commit cd1a16ec87717b7828ce9fa79bad126e61ccdf53 parent 83191323b09c170de977585043fa899488c894c9 Author: Vincent Demeester <vincent@sbr.pm> Date: Mon, 27 Jun 2022 17:39:27 +0200 Migrate www to an external repository Signed-off-by: Vincent Demeester <vincent@sbr.pm> Diffstat:
372 files changed, 0 insertions(+), 34087 deletions(-)
diff --git a/.gitattributes b/.gitattributes @@ -1,11 +0,0 @@ -* annex.largefiles=largerthan=400kb -*.org annex.largefiles=nothing -*.yaml annex.largefiles=nothing -*.html annex.largefiles=nothing -*.js annex.largefiles=nothing -*.css annex.largefiles=nothing -*.log annex.largefiles=nothing -*.nix annex.largefiles=nothing -*.el annex.largefiles=nothing -*.go annex.largefiles=nothing -*.sh annex.largefiles=nothing diff --git a/www/Makefile b/www/Makefile @@ -1,7 +0,0 @@ -all: build - -build: - make -C vincent.demeester.fr clean build - -publish: - make -C vincent.demeester.fr clean publish diff --git a/www/README.org b/www/README.org @@ -1,5 +0,0 @@ -#+TITLE: www -#+SUBTITLE: my website(s) - -This publishes all my website, everywhere, anywhere. -Delegates to each one. diff --git a/www/dl.sbr.pm/.fancyindex/HEADER.md b/www/dl.sbr.pm/.fancyindex/HEADER.md @@ -1,4 +0,0 @@ -# Test of a HEADER.md file -## Test of a HEADER.md file -### Test of a HEADER.md file -#### Test of a HEADER.md file diff --git a/www/dl.sbr.pm/.fancyindex/addNginxFancyIndexForm.js b/www/dl.sbr.pm/.fancyindex/addNginxFancyIndexForm.js @@ -1,33 +0,0 @@ -// addNginxFancyIndexForm.js -// Add a small form to filter through the output of Nginx FancyIndex page -// © 2017, Lilian Besson (Naereen) and contributors, -// open-sourced under the MIT License, https://lbesson.mit-license.org/ -// hosted on GitHub, https://GitHub.com/Naereen/Nginx-Fancyindex-Theme -var form = document.createElement('form'); -var input = document.createElement('input'); - -input.name = 'filter'; -input.id = 'search'; -input.placeholder = 'Type to search...'; - -form.appendChild(input); - -document.querySelector('h1').after(form); - -var listItems = [].slice.call(document.querySelectorAll('#list tbody tr')); - -input.addEventListener('keyup', function () { - var i, - // Word sequence _matching_ to input. All, except last, words must be _complete_. - e = "(^|.*[^\\pL])" + this.value.trim().split(/\s+/).join("([^\\pL]|[^\\pL].*[^\\pL])") + ".*$", - n = RegExp(e, "i"); - listItems.forEach(function(item) { - item.removeAttribute('hidden'); - }); - listItems.filter(function(item) { - i = item.querySelector('td').textContent.replace(/\s+/g, " "); - return !n.test(i); - }).forEach(function(item) { - item.hidden = true; - }); -}); diff --git a/www/dl.sbr.pm/.fancyindex/footer.html b/www/dl.sbr.pm/.fancyindex/footer.html @@ -1,40 +0,0 @@ -<section id="raw_include_README_md"></section> -</main> -<footer> - <span class='copyright'> - Content and design by Vincent Demeester - (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) - </span> -</footer> -<script src="https://unpkg.com/xregexp/xregexp-all.js"></script> -<script type="text/javascript" src="/.fancyindex/addNginxFancyIndexForm.js"></script> -<script type="text/javascript" src="/.fancyindex/showdown.min.js"></script> -<script type="text/javascript" defer> - var converter = new showdown.Converter(); - $( "#raw_include_HEADER_md" ).load( "HEADER.md", function (){ - var elem = document.querySelector("#raw_include_HEADER_md"); - // strip leading whitespace so it isn't evaluated as code - var text = elem.innerHTML; - // console.log("text =", text); - text = text.replace(/\n[ ]*/g, '\n'); - // console.log("text =", text); - var html = converter.makeHtml(text); - // console.log("html =", html); - // here, have some HTML - elem.innerHTML = html; - }); - $( "#raw_include_README_md" ).load( "README.md", function (){ - var elem = document.querySelector("#raw_include_README_md"); - // strip leading whitespace so it isn't evaluated as code - var text = elem.innerHTML; - // console.log("text =", text); - text = text.replace(/\n[ ]*/g, '\n'); - // console.log("text =", text); - var html = converter.makeHtml(text); - // console.log("html =", html); - // here, have some HTML - elem.innerHTML = html; - }); -</script> -</body> -</html> diff --git a/www/dl.sbr.pm/.fancyindex/header.html b/www/dl.sbr.pm/.fancyindex/header.html @@ -1,25 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="IE=edge"> - <title>Directory</title> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="https://vincent.demeester.fr/css/new.css"> - <script type="text/javascript" src="/.fancyindex/jquery.min.js"></script> - </head> - <body> - <header id="top" class="status"> - <nav> - <img src="https://vincent.demeester.fr/images/favicon.ico" id="sitelogo"/> <a href='https://vincent.demeester.fr/'>home</a> / - <a href='https://vincent.demeester.fr/posts/'>posts</a> (<a href='https://vincent.demeester.fr/index.xml'>rss</a>) / - <a href='https://vincent.demeester.fr/articles/'>articles</a> / - <a href='https://vincent.demeester.fr/configurations/'>configurations</a> / - <a href='https://dl.sbr.pm/'>files</a> / - <a href='https://vincent.demeester.fr/about/'>about</a></li> - </nav> - </header> - <main id="content"> - <header id="raw_include_HEADER_md"> - </header> -<h1>Directory: diff --git a/www/dl.sbr.pm/.fancyindex/jquery.min.js b/www/dl.sbr.pm/.fancyindex/jquery.min.js @@ -1,5 +0,0 @@ -/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -/* Used on Lilian Besson's web pages ~ 2011-2014 */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length; -while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?o.queue(this[0],a):void 0===b?this:this.each(function(){var c=o.queue(this,a,b);o._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&o.dequeue(this,a)})},dequeue:function(a){return this.each(function(){o.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=o.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===o.css(a,"display")||!o.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=m.createDocumentFragment(),b=a.appendChild(m.createElement("div"));b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||m,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[o.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new o.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=m),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&o.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return o.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=o.extend(new o.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?o.event.trigger(e,null,b):o.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},o.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},o.Event=function(a,b){return this instanceof o.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.getPreventDefault&&a.getPreventDefault()?Z:$):this.type=a,b&&o.extend(this,b),this.timeStamp=a&&a.timeStamp||o.now(),void(this[o.expando]=!0)):new o.Event(a,b)},o.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z,this.stopPropagation()}},o.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){o.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!o.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.focusinBubbles||o.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){o.event.simulate(b,a.target,o.event.fix(a),!0)};o.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),o.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return o().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=o.guid++)),this.each(function(){o.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,o(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){o.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){o.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?o.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||o.contains(a.ownerDocument,a)||(g=o.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",e=m.documentElement,f=m.createElement("div"),g=m.createElement("div");g.style.backgroundClip="content-box",g.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===g.style.backgroundClip,f.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",f.appendChild(g);function h(){g.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",e.appendChild(f);var d=a.getComputedStyle(g,null);b="1%"!==d.top,c="4px"===d.width,e.removeChild(f)}a.getComputedStyle&&o.extend(l,{pixelPosition:function(){return h(),b},boxSizingReliable:function(){return null==c&&h(),c},reliableMarginRight:function(){var b,c=g.appendChild(m.createElement("div"));return c.style.cssText=g.style.cssText=d,c.style.marginRight=c.style.width="0",g.style.width="1px",e.appendChild(f),b=!parseFloat(a.getComputedStyle(c,null).marginRight),e.removeChild(f),g.innerHTML="",b}})}(),o.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:0,fontWeight:400},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=o.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=o.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=o.css(a,"border"+R[f]+"Width",!0,e))):(g+=o.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=o.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===o.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):f[g]||(e=S(d),(c&&"none"!==c||!e)&&L.set(d,"olddisplay",e?c:o.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}o.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=o.camelCase(b),i=a.style;return b=o.cssProps[h]||(o.cssProps[h]=Fb(i,h)),g=o.cssHooks[b]||o.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(o.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||o.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]="",i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=o.camelCase(b);return b=o.cssProps[h]||(o.cssProps[h]=Fb(a.style,h)),g=o.cssHooks[b]||o.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||o.isNumeric(f)?f||0:e):e}}),o.each(["height","width"],function(a,b){o.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&zb.test(o.css(a,"display"))?o.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===o.css(a,"boxSizing",!1,e),e):0)}}}),o.cssHooks.marginRight=yb(l.reliableMarginRight,function(a,b){return b?o.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),o.each({margin:"",padding:"",border:"Width"},function(a,b){o.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(o.cssHooks[a+b].set=Gb)}),o.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(o.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=o.css(a,b[g],!1,d);return f}return void 0!==c?o.style(a,b,c):o.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?o(this).show():o(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}o.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(o.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?o.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=o.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){o.fx.step[a.prop]?o.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[o.cssProps[a.prop]]||o.cssHooks[a.prop])?o.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},o.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},o.fx=Kb.prototype.init,o.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(o.cssNumber[a]?"":"px"),g=(o.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(o.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,o.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=o.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&S(a),p=L.get(a,"fxshow");c.queue||(h=o._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,k.always(function(){k.always(function(){h.unqueued--,o.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],j=o.css(a,"display"),"none"===j&&(j=tb(a.nodeName)),"inline"===j&&"none"===o.css(a,"float")&&(m.display="inline-block")),c.overflow&&(m.overflow="hidden",k.always(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(n?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;n=!0}l[d]=p&&p[d]||o.style(a,d)}if(!o.isEmptyObject(l)){p?"hidden"in p&&(n=p.hidden):p=L.access(a,"fxshow",{}),f&&(p.hidden=!n),n?o(a).show():k.done(function(){o(a).hide()}),k.done(function(){var b;L.remove(a,"fxshow");for(b in l)o.style(a,b,l[b])});for(d in l)g=Ub(n?p[d]:0,d,k),d in p||(p[d]=g.start,n&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=o.camelCase(c),e=b[d],f=a[c],o.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=o.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=o.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:o.extend({},b),opts:o.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=o.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return o.map(k,Ub,j),o.isFunction(j.opts.start)&&j.opts.start.call(a,j),o.fx.timer(o.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}o.Animation=o.extend(Xb,{tweener:function(a,b){o.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),o.speed=function(a,b,c){var d=a&&"object"==typeof a?o.extend({},a):{complete:c||!c&&b||o.isFunction(a)&&a,duration:a,easing:c&&b||b&&!o.isFunction(b)&&b};return d.duration=o.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in o.fx.speeds?o.fx.speeds[d.duration]:o.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){o.isFunction(d.old)&&d.old.call(this),d.queue&&o.dequeue(this,d.queue)},d},o.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=o.isEmptyObject(a),f=o.speed(b,c,d),g=function(){var b=Xb(this,o.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=o.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&o.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=o.timers,g=d?d.length:0;for(c.finish=!0,o.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),o.each(["toggle","show","hide"],function(a,b){var c=o.fn[b];o.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),o.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){o.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),o.timers=[],o.fx.tick=function(){var a,b=0,c=o.timers;for(Lb=o.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||o.fx.stop(),Lb=void 0},o.fx.timer=function(a){o.timers.push(a),a()?o.fx.start():o.timers.pop()},o.fx.interval=13,o.fx.start=function(){Mb||(Mb=setInterval(o.fx.tick,o.fx.interval))},o.fx.stop=function(){clearInterval(Mb),Mb=null},o.fx.speeds={slow:600,fast:200,_default:400},o.fn.delay=function(a,b){return a=o.fx?o.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=m.createElement("input"),b=m.createElement("select"),c=b.appendChild(m.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=m.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var Yb,Zb,$b=o.expr.attrHandle;o.fn.extend({attr:function(a,b){return J(this,o.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){o.removeAttr(this,a)})}}),o.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?o.prop(a,b,c):(1===f&&o.isXMLDoc(a)||(b=b.toLowerCase(),d=o.attrHooks[b]||(o.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=o.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void o.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=o.propFix[c]||c,o.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&o.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?o.removeAttr(a,c):a.setAttribute(c,c),c}},o.each(o.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||o.find.attr;$b[b]=function(a,b,d){var e,f; -return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;o.fn.extend({prop:function(a,b){return J(this,o.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[o.propFix[a]||a]})}}),o.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!o.isXMLDoc(a),f&&(b=o.propFix[b]||b,e=o.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),l.optSelected||(o.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),o.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){o.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;o.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=o.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?o.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(o.isFunction(a)?function(c){o(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=o(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;o.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=o.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,o(this).val()):a,null==e?e="":"number"==typeof e?e+="":o.isArray(e)&&(e=o.map(e,function(a){return null==a?"":a+""})),b=o.valHooks[this.type]||o.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=o.valHooks[e.type]||o.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),o.extend({valHooks:{select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&o.nodeName(c.parentNode,"optgroup"))){if(b=o(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=o.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=o.inArray(o(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),o.each(["radio","checkbox"],function(){o.valHooks[this]={set:function(a,b){return o.isArray(b)?a.checked=o.inArray(o(a).val(),b)>=0:void 0}},l.checkOn||(o.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),o.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){o.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),o.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=o.now(),dc=/\?/;o.parseJSON=function(a){return JSON.parse(a+"")},o.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&o.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=m.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(o.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,o.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=o.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&o.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}o.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":o.parseJSON,"text xml":o.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,o.ajaxSettings),b):tc(o.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=o.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?o(l):o.event,n=o.Deferred(),p=o.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(n.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=o.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=o.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===o.active++&&o.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(o.lastModified[d]&&v.setRequestHeader("If-Modified-Since",o.lastModified[d]),o.etag[d]&&v.setRequestHeader("If-None-Match",o.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(o.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(o.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?n.resolveWith(l,[r,x,v]):n.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--o.active||o.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return o.get(a,b,c,"json")},getScript:function(a,b){return o.get(a,void 0,b,"script")}}),o.each(["get","post"],function(a,b){o[b]=function(a,c,d,e){return o.isFunction(c)&&(e=e||d,d=c,c=void 0),o.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),o.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){o.fn[b]=function(a){return this.on(b,a)}}),o._evalUrl=function(a){return o.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},o.fn.extend({wrapAll:function(a){var b;return o.isFunction(a)?this.each(function(b){o(this).wrapAll(a.call(this,b))}):(this[0]&&(b=o(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(o.isFunction(a)?function(b){o(this).wrapInner(a.call(this,b))}:function(){var b=o(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=o.isFunction(a);return this.each(function(c){o(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){o.nodeName(this,"body")||o(this).replaceWith(this.childNodes)}).end()}}),o.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},o.expr.filters.visible=function(a){return!o.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(o.isArray(b))o.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==o.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}o.param=function(a,b){var c,d=[],e=function(a,b){b=o.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=o.ajaxSettings&&o.ajaxSettings.traditional),o.isArray(a)||a.jquery&&!o.isPlainObject(a))o.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},o.fn.extend({serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=o.prop(this,"elements");return a?o.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!o(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=o(this).val();return null==c?null:o.isArray(c)?o.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),o.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=o.ajaxSettings.xhr();a.ActiveXObject&&o(a).on("unload",function(){for(var a in Dc)Dc[a]()}),l.cors=!!Fc&&"withCredentials"in Fc,l.ajax=Fc=!!Fc,o.ajaxTransport(function(a){var b;return l.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort"),f.send(a.hasContent&&a.data||null)},abort:function(){b&&b()}}:void 0}),o.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return o.globalEval(a),a}}}),o.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),o.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=o("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),m.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;o.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||o.expando+"_"+cc++;return this[a]=!0,a}}),o.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=o.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||o.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&o.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),o.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||m;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=o.buildFragment([a],b,e),e&&e.length&&o(e).remove(),o.merge([],d.childNodes))};var Ic=o.fn.load;o.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h),a=a.slice(0,h)),o.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&o.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?o("<div>").append(o.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},o.expr.filters.animated=function(a){return o.grep(o.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return o.isWindow(a)?a:9===a.nodeType&&a.defaultView}o.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=o.css(a,"position"),l=o(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=o.css(a,"top"),i=o.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),o.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},o.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){o.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,o.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===o.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),o.nodeName(a[0],"html")||(d=a.offset()),d.top+=o.css(a[0],"borderTopWidth",!0),d.left+=o.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-o.css(c,"marginTop",!0),left:b.left-d.left-o.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!o.nodeName(a,"html")&&"static"===o.css(a,"position"))a=a.offsetParent;return a||Jc})}}),o.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;o.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),o.each(["top","left"],function(a,b){o.cssHooks[b]=yb(l.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?o(a).position()[b]+"px":c):void 0})}),o.each({Height:"height",Width:"width"},function(a,b){o.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){o.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return o.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?o.css(b,c,g):o.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),o.fn.size=function(){return this.length},o.fn.andSelf=o.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return o});var Lc=a.jQuery,Mc=a.$;return o.noConflict=function(b){return a.$===o&&(a.$=Mc),b&&a.jQuery===o&&(a.jQuery=Lc),o},typeof b===U&&(a.jQuery=a.$=o),o}); diff --git a/www/dl.sbr.pm/.fancyindex/new.css b/www/dl.sbr.pm/.fancyindex/new.css @@ -1,605 +0,0 @@ -:root { - ---font-sans: 'Ubuntu Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - ---font-mono: 'Ubuntu Mono', Consolas, monaco, 'Liberation Mono', 'Courier New', Courier, monospace; - ---tx-1: #000000; - ---tx-2: #1A1A1A; - ---tx-3: #666666; - ---tx-4: #999999; - ---bg-1: #FFFFFF; - ---bg-2: #F6F8FA; - ---bg-3: #E5E7EB; - ---lk-1: #0070F3; - ---lk-2: #0366D6; - ---lk-tx: #FFFFFF; - ---ac-1: #79FFE1; - ---ac-tx: #0C4047; - - --content-box-padding: 0.5rem; - --aside-width: 12.5rem; -} - -@media (prefers-color-scheme: dark) { - :root { - ---tx-1: #ffffff; - ---tx-2: #eeeeee; - ---tx-3: #cccccc; - ---tx-4: #aaaaaa; - ---bg-1: #000000; - ---bg-2: #111111; - ---bg-3: #222222; - ---lk-1: #3291FF; - ---lk-2: #0070F3; - ---lk-tx: #FFFFFF; - ---ac-1: #7928CA; - ---ac-tx: #FFFFFF; - } -} - -* { - /* Reset margins and padding */ - margin: 0; - padding: 0; -} - -address, -area, -article, -aside, -audio, -blockquote, -datalist, -details, -dl, -fieldset, -figure, -form, -input, -iframe, -img, -meter, -nav, -ol, -optgroup, -option, -output, -p, -pre, -progress, -ruby, -section, -table, -textarea, -ul, -video { - /* Margins for most elements */ - margin-bottom: 1rem; -} - -html,input,select,button { - /* Set body font family and some finicky elements */ - font-family: var(---font-sans); -} - -body { - /* Center body in page */ - margin: 0 auto; - max-width: 70rem; - padding: 2rem; - border-radius: 6px; - overflow-x: hidden; - word-break: break-word; - overflow-wrap: break-word; - background: var(---bg-1); - - /* Main body text */ - color: var(---tx-2); - font-size: 1.03rem; - line-height: 1.5; -} - -::selection { - /* Set background color for selected text */ - background: var(---ac-1); - color: var(---ac-tx); -} - -h1,h2,h3,h4,h5,h6 { - line-height: 1; - color: var(---tx-1); - padding-top: .875rem; -} - -h1, -h2, -h3 { - color: var(---tx-1); - padding-bottom: 2px; - margin-bottom: 8px; - border-bottom: 1px solid var(---bg-2); -} - -h4, -h5, -h6 { - margin-bottom: .3rem; -} - -h1 { - font-size: 2.25rem; -} - -h2 { - font-size: 1.85rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: 1rem; -} - -h6 { - font-size: .875rem; -} - -a { - color: var(---lk-1); -} - -a:hover { - color: var(---lk-2); -} - -abbr:hover { - /* Set the '?' cursor while hovering an abbreviation */ - cursor: help; -} - -blockquote { - padding: 1.5rem; - background: var(---bg-2); - border-left: 5px solid var(---bg-3); -} - -abbr { - cursor: help; -} - -blockquote *:last-child { - padding-bottom: 0; - margin-bottom: 0; -} - -header { - background: var(---bg-2); - border-bottom: 1px solid var(---bg-3); - padding: 1rem 1.5rem; - - /* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */ - - margin: -2rem calc(0px - (50vw - 50%)) 2rem; - - /* Shorthand for: - - margin-top: -2rem; - margin-bottom: 2rem; - - margin-left: calc(0px - (50vw - 50%)); - margin-right: calc(0px - (50vw - 50%)); */ - - padding-left: calc(50vw - 50%); - padding-right: calc(50vw - 50%); -} - -header img#sitelogo { - margin-bottom: 0; - margin-right: 1em; -} - -header h1, -header h2, -header h3 { - padding-bottom: 0; - border-bottom: 0; -} - -header > *:first-child { - margin-top: 0; - padding-top: 0; -} - -header > *:last-child { - margin-bottom: 0; -} - -main header { - background: var(---bg-3); -} - -a button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - font-size: 1rem; - display: inline-block; - padding: 6px 12px; - text-align: center; - text-decoration: none; - white-space: nowrap; - background: var(---lk-1); - color: var(---lk-tx); - border: 0; - border-radius: 4px; - box-sizing: border-box; - cursor: pointer; - color: var(---lk-tx); -} - -a button[disabled], -button[disabled], -input[type="submit"][disabled], -input[type="reset"][disabled], -input[type="button"][disabled] { - cursor: default; - opacity: .5; - - /* Set the [X] cursor while hovering a disabled link */ - cursor: not-allowed; -} - -.button:focus, -.button:hover, -button:focus, -button:hover, -input[type="submit"]:focus, -input[type="submit"]:hover, -input[type="reset"]:focus, -input[type="reset"]:hover, -input[type="button"]:focus, -input[type="button"]:hover { - background: var(---lk-2); -} - -code, -pre, -kbd, -samp { - /* Set the font family for monospaced elements */ - font-family: var(---font-mono); -} - -code, -samp, -kbd, -pre { - /* The main preformatted style. This is changed slightly across different cases. */ - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - padding: 3px 6px; -} - -kbd { - /* Makes the kbd element look like a keyboard key */ - border-bottom: 3px solid var(---bg-3); -} - -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; -} - -pre.src { - position: relative; -} -pre.src:before { - /*display: none;*/ - position: absolute; - background-color: var(---bg-3); - /*color: #f3f4f4;*/ - top: 0; - right: 0; - padding: 0.2rem 0.5rem; -} - -pre code { - /* When <code> is in a <pre>, reset it's formatting to blend in */ - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -code pre { - /* When <pre> is in a <code>, reset it's formatting to blend in */ - display: inline; - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -details { - /* Make the <details> look more "clickable" */ - padding: .6rem 1rem; - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -summary { - /* Makes the <summary> look more like a "clickable" link with the pointer cursor */ - cursor: pointer; - font-weight: bold; -} - -details[open] { - /* Adjust the <details> padding while open */ - padding-bottom: .75rem; -} - -details[open] summary { - /* Adjust the <details> padding while open */ - margin-bottom: 6px; -} - -details[open]>*:last-child { - /* Resets the bottom margin of the last element in the <details> while <details> is opened. This prevents double margins/paddings. */ - margin-bottom: 0; -} - -dt { - font-weight: bold; -} - -dd::before { - /* Add an arrow to data table definitions */ - content: '→ '; -} - -hr { - /* Reset the border of the <hr> separator, then set a better line */ - border: 0; - border-bottom: 1px solid var(---bg-3); - margin: 1rem auto; -} - -fieldset { - margin-top: 1rem; - padding: 2rem; - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -legend { - padding: auto .5rem; -} - -table { - /* border-collapse sets the table's elements to share borders, rather than floating as separate "boxes". */ - border-collapse: collapse; - width: 100% -} - -td, -th { - border: 1px solid var(---bg-3); - text-align: left; - padding: .5rem; -} - -th { - background: var(---bg-2); -} - -tr:nth-child(even) { - /* Set every other cell slightly darker. Improves readability. */ - background: var(---bg-2); -} - -table caption { - font-weight: bold; - margin-bottom: .5rem; -} - -textarea { - /* Don't let the <textarea> extend off the screen naturally or when dragged by the user */ - max-width: 100%; -} - -ol, -ul { - /* Replace the browser default padding */ - padding-left: 2rem; -} - -li { - margin-top: .4rem; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -mark { - padding: 3px 6px; - background: var(---ac-1); - color: var(---ac-tx); -} - -textarea, -select, -input { - padding: 6px 12px; - margin-bottom: .5rem; - background: var(---bg-2); - color: var(---tx-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; -} - -img { - max-width: 100%; -} - -aside { - --aside-offset: 1rem; - --aside-offset-lineheight: 1.5rem; - background-color: var(---bg-2); - padding: calc(var(--content-box-padding) * 0.5) calc(var(--content-box-padding) * 2); - padding-top: 1em; - margin-bottom: 0em; - float: right; - width: var(--aside-width); - font-size: 0.9rem; - line-height: 1.25rem; - border: 1px solid var(--bg-3); -} - -figure figcaption { - text-align: center; - color: var(---tx-2); - font-style: italic; - margin: 0 2rem; -} - -footer { - text-align: center; - color: var(---tx-4); -} - -footer a { - color: var(---tx-3); -} - -section img { - display: block; - margin-left: auto; - margin-right: auto; -} - -section img.shadow { - box-shadow: 0 28px 50px rgba(0,0,0,0.16); -} - -div.drawer:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 4.4rem; - width: 1px; - background-color: #555; -} - -div.drawer { - display: flex; - padding: 0; - margin: 1rem; - padding-top: 1rem; - position: relative; - color: #555; -} - -div.drawer h6 { - box-sizing: border-box; - font-style: italic; - flex: 0 0 5rem; - margin:0; - padding:0; - align-self: center; - text-align: right; - padding-right: 1.2rem; -} - -div.drawer.info:before { - background-color: #00529B; -} -div.drawer.info { - color: #00529B; -} - -div.drawer.note:before { - background-color: #9F6000; -} -div.drawer.note { - color: #9F6000; -} -div.drawer.tip:before { - background-color: #4F8A10; -} -div.drawer.tip { - color: #4F8A10; -} -div.drawer.warning:before { - background-color: #D8000C; -} -div.drawer.warning { - color: #D8000C; -} -div.drawer.results:before { - background-color: black; -} -div.drawer.results { - font-family:monospace,monospace; - font-family: var(---font-mono); - color: black; - width: 100% !important; -} -div.drawer.results p { - display: block; - unicode-bidi: embed; - white-space: pre; - margin-top: 0; -} -div.drawer.results pre { - background-color: inherit; - border: 0; -} -div.drawer.results pre.src:before { - background-color: #eee; - color: #555; -} - -.tag { - font-family:var(---font-mono); - font-size: 1rem; -} -.tag span { - padding:.3em; - float:right; - margin-right:.5em; - border:1px solid #bbb; - border-radius:3px; - background-clip:padding-box; - color:#333; - background-color:#eee; - line-height:1rem; -} - -.todo { - font-family: monospace; color: red; -} -.done { - font-family: monospace; color: green; -} -.priority { font-family: monospace; color: orange; } -.timestamp { color: #bebebe; } -.timestamp-kwd { color: #5f9ea0; } diff --git a/www/dl.sbr.pm/.fancyindex/showdown.min.js b/www/dl.sbr.pm/.fancyindex/showdown.min.js @@ -1,3 +0,0 @@ -/*! showdown v 1.8.6 - 22-12-2017 */ -(function(){function g(g){"use strict";var A={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",type:"string"},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',type:"boolean"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},rawHeaderId:{defaultValue:!1,describe:"Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,description:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,description:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,description:"Parses simple line breaks as <br> (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,description:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,description:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",description:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,description:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,description:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,description:"Support for HTML Tag escaping. ex: <div>foo</div>",type:"boolean"},emoji:{defaultValue:!1,description:"Enable emoji support. Ex: `this is a :smile: emoji`",type:"boolean"},underline:{defaultValue:!1,description:"Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`",type:"boolean"},completeHTMLDocument:{defaultValue:!1,description:"Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags",type:"boolean"},metadata:{defaultValue:!1,description:"Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).",type:"boolean"},splitAdjacentBlockquotes:{defaultValue:!1,description:"Split adjacent blockquote blocks",type:"boolean"}};if(!1===g)return JSON.parse(JSON.stringify(A));var C={};for(var I in A)A.hasOwnProperty(I)&&(C[I]=A[I].defaultValue);return C}function A(g,A){"use strict";var C=A?"Error in "+A+" extension->":"Error in unnamed extension",e={valid:!0,error:""};I.helper.isArray(g)||(g=[g]);for(var r=0;r<g.length;++r){var t=C+" sub-extension "+r+": ",a=g[r];if("object"!=typeof a)return e.valid=!1,e.error=t+"must be an object, but "+typeof a+" given",e;if(!I.helper.isString(a.type))return e.valid=!1,e.error=t+'property "type" must be a string, but '+typeof a.type+" given",e;var n=a.type=a.type.toLowerCase();if("language"===n&&(n=a.type="lang"),"html"===n&&(n=a.type="output"),"lang"!==n&&"output"!==n&&"listener"!==n)return e.valid=!1,e.error=t+"type "+n+' is not recognized. Valid values: "lang/language", "output/html" or "listener"',e;if("listener"===n){if(I.helper.isUndefined(a.listeners))return e.valid=!1,e.error=t+'. Extensions of type "listener" must have a property called "listeners"',e}else if(I.helper.isUndefined(a.filter)&&I.helper.isUndefined(a.regex))return e.valid=!1,e.error=t+n+' extensions must define either a "regex" property or a "filter" method',e;if(a.listeners){if("object"!=typeof a.listeners)return e.valid=!1,e.error=t+'"listeners" property must be an object but '+typeof a.listeners+" given",e;for(var o in a.listeners)if(a.listeners.hasOwnProperty(o)&&"function"!=typeof a.listeners[o])return e.valid=!1,e.error=t+'"listeners" property must be an hash of [event name]: [callback]. listeners.'+o+" must be a function but "+typeof a.listeners[o]+" given",e}if(a.filter){if("function"!=typeof a.filter)return e.valid=!1,e.error=t+'"filter" must be a function, but '+typeof a.filter+" given",e}else if(a.regex){if(I.helper.isString(a.regex)&&(a.regex=new RegExp(a.regex,"g")),!(a.regex instanceof RegExp))return e.valid=!1,e.error=t+'"regex" property must either be a string or a RegExp object, but '+typeof a.regex+" given",e;if(I.helper.isUndefined(a.replace))return e.valid=!1,e.error=t+'"regex" extensions must implement a replace string or function',e}}return e}function C(g,A){"use strict";return"¨E"+A.charCodeAt(0)+"E"}var I={},e={},r={},t=g(!0),a="vanilla",n={github:{omitExtraWLInCodeBlocks:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,disableForced4SpacesIndentedSublists:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghCompatibleHeaderId:!0,ghMentions:!0,backslashEscapesHTMLTags:!0,emoji:!0,splitAdjacentBlockquotes:!0},original:{noHeaderId:!0,ghCodeBlocks:!1},ghost:{omitExtraWLInCodeBlocks:!0,parseImgDimensions:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,smoothLivePreview:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghMentions:!1,encodeEmails:!0},vanilla:g(!0),allOn:function(){"use strict";var A=g(!0),C={};for(var I in A)A.hasOwnProperty(I)&&(C[I]=!0);return C}()};I.helper={},I.extensions={},I.setOption=function(g,A){"use strict";return t[g]=A,this},I.getOption=function(g){"use strict";return t[g]},I.getOptions=function(){"use strict";return t},I.resetOptions=function(){"use strict";t=g(!0)},I.setFlavor=function(g){"use strict";if(!n.hasOwnProperty(g))throw Error(g+" flavor was not found");I.resetOptions();var A=n[g];a=g;for(var C in A)A.hasOwnProperty(C)&&(t[C]=A[C])},I.getFlavor=function(){"use strict";return a},I.getFlavorOptions=function(g){"use strict";if(n.hasOwnProperty(g))return n[g]},I.getDefaultOptions=function(A){"use strict";return g(A)},I.subParser=function(g,A){"use strict";if(I.helper.isString(g)){if(void 0===A){if(e.hasOwnProperty(g))return e[g];throw Error("SubParser named "+g+" not registered!")}e[g]=A}},I.extension=function(g,C){"use strict";if(!I.helper.isString(g))throw Error("Extension 'name' must be a string");if(g=I.helper.stdExtName(g),I.helper.isUndefined(C)){if(!r.hasOwnProperty(g))throw Error("Extension named "+g+" is not registered!");return r[g]}"function"==typeof C&&(C=C()),I.helper.isArray(C)||(C=[C]);var e=A(C,g);if(!e.valid)throw Error(e.error);r[g]=C},I.getAllExtensions=function(){"use strict";return r},I.removeExtension=function(g){"use strict";delete r[g]},I.resetExtensions=function(){"use strict";r={}},I.validateExtension=function(g){"use strict";var C=A(g,null);return!!C.valid||(console.warn(C.error),!1)},I.hasOwnProperty("helper")||(I.helper={}),I.helper.isString=function(g){"use strict";return"string"==typeof g||g instanceof String},I.helper.isFunction=function(g){"use strict";return g&&"[object Function]"==={}.toString.call(g)},I.helper.isArray=function(g){"use strict";return Array.isArray(g)},I.helper.isUndefined=function(g){"use strict";return void 0===g},I.helper.forEach=function(g,A){"use strict";if(I.helper.isUndefined(g))throw new Error("obj param is required");if(I.helper.isUndefined(A))throw new Error("callback param is required");if(!I.helper.isFunction(A))throw new Error("callback param must be a function/closure");if("function"==typeof g.forEach)g.forEach(A);else if(I.helper.isArray(g))for(var C=0;C<g.length;C++)A(g[C],C,g);else{if("object"!=typeof g)throw new Error("obj does not seem to be an array or an iterable object");for(var e in g)g.hasOwnProperty(e)&&A(g[e],e,g)}},I.helper.stdExtName=function(g){"use strict";return g.replace(/[_?*+\/\\.^-]/g,"").replace(/\s/g,"").toLowerCase()},I.helper.escapeCharactersCallback=C,I.helper.escapeCharacters=function(g,A,I){"use strict";var e="(["+A.replace(/([\[\]\\])/g,"\\$1")+"])";I&&(e="\\\\"+e);var r=new RegExp(e,"g");return g=g.replace(r,C)};var o=function(g,A,C,I){"use strict";var e,r,t,a,n,o=I||"",s=o.indexOf("g")>-1,i=new RegExp(A+"|"+C,"g"+o.replace(/g/g,"")),l=new RegExp(A,o.replace(/g/g,"")),c=[];do{for(e=0;t=i.exec(g);)if(l.test(t[0]))e++||(a=(r=i.lastIndex)-t[0].length);else if(e&&!--e){n=t.index+t[0].length;var u={left:{start:a,end:r},match:{start:r,end:t.index},right:{start:t.index,end:n},wholeMatch:{start:a,end:n}};if(c.push(u),!s)return c}}while(e&&(i.lastIndex=r));return c};I.helper.matchRecursiveRegExp=function(g,A,C,I){"use strict";for(var e=o(g,A,C,I),r=[],t=0;t<e.length;++t)r.push([g.slice(e[t].wholeMatch.start,e[t].wholeMatch.end),g.slice(e[t].match.start,e[t].match.end),g.slice(e[t].left.start,e[t].left.end),g.slice(e[t].right.start,e[t].right.end)]);return r},I.helper.replaceRecursiveRegExp=function(g,A,C,e,r){"use strict";if(!I.helper.isFunction(A)){var t=A;A=function(){return t}}var a=o(g,C,e,r),n=g,s=a.length;if(s>0){var i=[];0!==a[0].wholeMatch.start&&i.push(g.slice(0,a[0].wholeMatch.start));for(var l=0;l<s;++l)i.push(A(g.slice(a[l].wholeMatch.start,a[l].wholeMatch.end),g.slice(a[l].match.start,a[l].match.end),g.slice(a[l].left.start,a[l].left.end),g.slice(a[l].right.start,a[l].right.end))),l<s-1&&i.push(g.slice(a[l].wholeMatch.end,a[l+1].wholeMatch.start));a[s-1].wholeMatch.end<g.length&&i.push(g.slice(a[s-1].wholeMatch.end)),n=i.join("")}return n},I.helper.regexIndexOf=function(g,A,C){"use strict";if(!I.helper.isString(g))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";if(A instanceof RegExp==!1)throw"InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp";var e=g.substring(C||0).search(A);return e>=0?e+(C||0):e},I.helper.splitAtIndex=function(g,A){"use strict";if(!I.helper.isString(g))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";return[g.substring(0,A),g.substring(A)]},I.helper.encodeEmailAddress=function(g){"use strict";var A=[function(g){return"&#"+g.charCodeAt(0)+";"},function(g){return"&#x"+g.charCodeAt(0).toString(16)+";"},function(g){return g}];return g=g.replace(/./g,function(g){if("@"===g)g=A[Math.floor(2*Math.random())](g);else{var C=Math.random();g=C>.9?A[2](g):C>.45?A[1](g):A[0](g)}return g})},"undefined"==typeof console&&(console={warn:function(g){"use strict";alert(g)},log:function(g){"use strict";alert(g)},error:function(g){"use strict";throw g}}),I.helper.regexes={asteriskDashAndColon:/([*_:~])/g},I.helper.emojis={"+1":"👍","-1":"👎",100:"💯",1234:"🔢","1st_place_medal":"🥇","2nd_place_medal":"🥈","3rd_place_medal":"🥉","8ball":"🎱",a:"🅰️",ab:"🆎",abc:"🔤",abcd:"🔡",accept:"🉑",aerial_tramway:"🚡",airplane:"✈️",alarm_clock:"⏰",alembic:"⚗️",alien:"👽",ambulance:"🚑",amphora:"🏺",anchor:"⚓️",angel:"👼",anger:"💢",angry:"😠",anguished:"😧",ant:"🐜",apple:"🍎",aquarius:"♒️",aries:"♈️",arrow_backward:"◀️",arrow_double_down:"⏬",arrow_double_up:"⏫",arrow_down:"⬇️",arrow_down_small:"🔽",arrow_forward:"▶️",arrow_heading_down:"⤵️",arrow_heading_up:"⤴️",arrow_left:"⬅️",arrow_lower_left:"↙️",arrow_lower_right:"↘️",arrow_right:"➡️",arrow_right_hook:"↪️",arrow_up:"⬆️",arrow_up_down:"↕️",arrow_up_small:"🔼",arrow_upper_left:"↖️",arrow_upper_right:"↗️",arrows_clockwise:"🔃",arrows_counterclockwise:"🔄",art:"🎨",articulated_lorry:"🚛",artificial_satellite:"🛰",astonished:"😲",athletic_shoe:"👟",atm:"🏧",atom_symbol:"⚛️",avocado:"🥑",b:"🅱️",baby:"👶",baby_bottle:"🍼",baby_chick:"🐤",baby_symbol:"🚼",back:"🔙",bacon:"🥓",badminton:"🏸",baggage_claim:"🛄",baguette_bread:"🥖",balance_scale:"⚖️",balloon:"🎈",ballot_box:"🗳",ballot_box_with_check:"☑️",bamboo:"🎍",banana:"🍌",bangbang:"‼️",bank:"🏦",bar_chart:"📊",barber:"💈",baseball:"⚾️",basketball:"🏀",basketball_man:"⛹️",basketball_woman:"⛹️‍♀️",bat:"🦇",bath:"🛀",bathtub:"🛁",battery:"🔋",beach_umbrella:"🏖",bear:"🐻",bed:"🛏",bee:"🐝",beer:"🍺",beers:"🍻",beetle:"🐞",beginner:"🔰",bell:"🔔",bellhop_bell:"🛎",bento:"🍱",biking_man:"🚴",bike:"🚲",biking_woman:"🚴‍♀️",bikini:"👙",biohazard:"☣️",bird:"🐦",birthday:"🎂",black_circle:"⚫️",black_flag:"🏴",black_heart:"🖤",black_joker:"🃏",black_large_square:"⬛️",black_medium_small_square:"◾️",black_medium_square:"◼️",black_nib:"✒️",black_small_square:"▪️",black_square_button:"🔲",blonde_man:"👱",blonde_woman:"👱‍♀️",blossom:"🌼",blowfish:"🐡",blue_book:"📘",blue_car:"🚙",blue_heart:"💙",blush:"😊",boar:"🐗",boat:"⛵️",bomb:"💣",book:"📖",bookmark:"🔖",bookmark_tabs:"📑",books:"📚",boom:"💥",boot:"👢",bouquet:"💐",bowing_man:"🙇",bow_and_arrow:"🏹",bowing_woman:"🙇‍♀️",bowling:"🎳",boxing_glove:"🥊",boy:"👦",bread:"🍞",bride_with_veil:"👰",bridge_at_night:"🌉",briefcase:"💼",broken_heart:"💔",bug:"🐛",building_construction:"🏗",bulb:"💡",bullettrain_front:"🚅",bullettrain_side:"🚄",burrito:"🌯",bus:"🚌",business_suit_levitating:"🕴",busstop:"🚏",bust_in_silhouette:"👤",busts_in_silhouette:"👥",butterfly:"🦋",cactus:"🌵",cake:"🍰",calendar:"📆",call_me_hand:"🤙",calling:"📲",camel:"🐫",camera:"📷",camera_flash:"📸",camping:"🏕",cancer:"♋️",candle:"🕯",candy:"🍬",canoe:"🛶",capital_abcd:"🔠",capricorn:"♑️",car:"🚗",card_file_box:"🗃",card_index:"📇",card_index_dividers:"🗂",carousel_horse:"🎠",carrot:"🥕",cat:"🐱",cat2:"🐈",cd:"💿",chains:"⛓",champagne:"🍾",chart:"💹",chart_with_downwards_trend:"📉",chart_with_upwards_trend:"📈",checkered_flag:"🏁",cheese:"🧀",cherries:"🍒",cherry_blossom:"🌸",chestnut:"🌰",chicken:"🐔",children_crossing:"🚸",chipmunk:"🐿",chocolate_bar:"🍫",christmas_tree:"🎄",church:"⛪️",cinema:"🎦",circus_tent:"🎪",city_sunrise:"🌇",city_sunset:"🌆",cityscape:"🏙",cl:"🆑",clamp:"🗜",clap:"👏",clapper:"🎬",classical_building:"🏛",clinking_glasses:"🥂",clipboard:"📋",clock1:"🕐",clock10:"🕙",clock1030:"🕥",clock11:"🕚",clock1130:"🕦",clock12:"🕛",clock1230:"🕧",clock130:"🕜",clock2:"🕑",clock230:"🕝",clock3:"🕒",clock330:"🕞",clock4:"🕓",clock430:"🕟",clock5:"🕔",clock530:"🕠",clock6:"🕕",clock630:"🕡",clock7:"🕖",clock730:"🕢",clock8:"🕗",clock830:"🕣",clock9:"🕘",clock930:"🕤",closed_book:"📕",closed_lock_with_key:"🔐",closed_umbrella:"🌂",cloud:"☁️",cloud_with_lightning:"🌩",cloud_with_lightning_and_rain:"⛈",cloud_with_rain:"🌧",cloud_with_snow:"🌨",clown_face:"🤡",clubs:"♣️",cocktail:"🍸",coffee:"☕️",coffin:"⚰️",cold_sweat:"😰",comet:"☄️",computer:"💻",computer_mouse:"🖱",confetti_ball:"🎊",confounded:"😖",confused:"😕",congratulations:"㊗️",construction:"🚧",construction_worker_man:"👷",construction_worker_woman:"👷‍♀️",control_knobs:"🎛",convenience_store:"🏪",cookie:"🍪",cool:"🆒",policeman:"👮",copyright:"©️",corn:"🌽",couch_and_lamp:"🛋",couple:"👫",couple_with_heart_woman_man:"💑",couple_with_heart_man_man:"👨‍❤️‍👨",couple_with_heart_woman_woman:"👩‍❤️‍👩",couplekiss_man_man:"👨‍❤️‍💋‍👨",couplekiss_man_woman:"💏",couplekiss_woman_woman:"👩‍❤️‍💋‍👩",cow:"🐮",cow2:"🐄",cowboy_hat_face:"🤠",crab:"🦀",crayon:"🖍",credit_card:"💳",crescent_moon:"🌙",cricket:"🏏",crocodile:"🐊",croissant:"🥐",crossed_fingers:"🤞",crossed_flags:"🎌",crossed_swords:"⚔️",crown:"👑",cry:"😢",crying_cat_face:"😿",crystal_ball:"🔮",cucumber:"🥒",cupid:"💘",curly_loop:"➰",currency_exchange:"💱",curry:"🍛",custard:"🍮",customs:"🛃",cyclone:"🌀",dagger:"🗡",dancer:"💃",dancing_women:"👯",dancing_men:"👯‍♂️",dango:"🍡",dark_sunglasses:"🕶",dart:"🎯",dash:"💨",date:"📅",deciduous_tree:"🌳",deer:"🦌",department_store:"🏬",derelict_house:"🏚",desert:"🏜",desert_island:"🏝",desktop_computer:"🖥",male_detective:"🕵️",diamond_shape_with_a_dot_inside:"💠",diamonds:"♦️",disappointed:"😞",disappointed_relieved:"😥",dizzy:"💫",dizzy_face:"😵",do_not_litter:"🚯",dog:"🐶",dog2:"🐕",dollar:"💵",dolls:"🎎",dolphin:"🐬",door:"🚪",doughnut:"🍩",dove:"🕊",dragon:"🐉",dragon_face:"🐲",dress:"👗",dromedary_camel:"🐪",drooling_face:"🤤",droplet:"💧",drum:"🥁",duck:"🦆",dvd:"📀","e-mail":"📧",eagle:"🦅",ear:"👂",ear_of_rice:"🌾",earth_africa:"🌍",earth_americas:"🌎",earth_asia:"🌏",egg:"🥚",eggplant:"🍆",eight_pointed_black_star:"✴️",eight_spoked_asterisk:"✳️",electric_plug:"🔌",elephant:"🐘",email:"✉️",end:"🔚",envelope_with_arrow:"📩",euro:"💶",european_castle:"🏰",european_post_office:"🏤",evergreen_tree:"🌲",exclamation:"❗️",expressionless:"😑",eye:"👁",eye_speech_bubble:"👁‍🗨",eyeglasses:"👓",eyes:"👀",face_with_head_bandage:"🤕",face_with_thermometer:"🤒",fist_oncoming:"👊",factory:"🏭",fallen_leaf:"🍂",family_man_woman_boy:"👪",family_man_boy:"👨‍👦",family_man_boy_boy:"👨‍👦‍👦",family_man_girl:"👨‍👧",family_man_girl_boy:"👨‍👧‍👦",family_man_girl_girl:"👨‍👧‍👧",family_man_man_boy:"👨‍👨‍👦",family_man_man_boy_boy:"👨‍👨‍👦‍👦",family_man_man_girl:"👨‍👨‍👧",family_man_man_girl_boy:"👨‍👨‍👧‍👦",family_man_man_girl_girl:"👨‍👨‍👧‍👧",family_man_woman_boy_boy:"👨‍👩‍👦‍👦",family_man_woman_girl:"👨‍👩‍👧",family_man_woman_girl_boy:"👨‍👩‍👧‍👦",family_man_woman_girl_girl:"👨‍👩‍👧‍👧",family_woman_boy:"👩‍👦",family_woman_boy_boy:"👩‍👦‍👦",family_woman_girl:"👩‍👧",family_woman_girl_boy:"👩‍👧‍👦",family_woman_girl_girl:"👩‍👧‍👧",family_woman_woman_boy:"👩‍👩‍👦",family_woman_woman_boy_boy:"👩‍👩‍👦‍👦",family_woman_woman_girl:"👩‍👩‍👧",family_woman_woman_girl_boy:"👩‍👩‍👧‍👦",family_woman_woman_girl_girl:"👩‍👩‍👧‍👧",fast_forward:"⏩",fax:"📠",fearful:"😨",feet:"🐾",female_detective:"🕵️‍♀️",ferris_wheel:"🎡",ferry:"⛴",field_hockey:"🏑",file_cabinet:"🗄",file_folder:"📁",film_projector:"📽",film_strip:"🎞",fire:"🔥",fire_engine:"🚒",fireworks:"🎆",first_quarter_moon:"🌓",first_quarter_moon_with_face:"🌛",fish:"🐟",fish_cake:"🍥",fishing_pole_and_fish:"🎣",fist_raised:"✊",fist_left:"🤛",fist_right:"🤜",flags:"🎏",flashlight:"🔦",fleur_de_lis:"⚜️",flight_arrival:"🛬",flight_departure:"🛫",floppy_disk:"💾",flower_playing_cards:"🎴",flushed:"😳",fog:"🌫",foggy:"🌁",football:"🏈",footprints:"👣",fork_and_knife:"🍴",fountain:"⛲️",fountain_pen:"🖋",four_leaf_clover:"🍀",fox_face:"🦊",framed_picture:"🖼",free:"🆓",fried_egg:"🍳",fried_shrimp:"🍤",fries:"🍟",frog:"🐸",frowning:"😦",frowning_face:"☹️",frowning_man:"🙍‍♂️",frowning_woman:"🙍",middle_finger:"🖕",fuelpump:"⛽️",full_moon:"🌕",full_moon_with_face:"🌝",funeral_urn:"⚱️",game_die:"🎲",gear:"⚙️",gem:"💎",gemini:"♊️",ghost:"👻",gift:"🎁",gift_heart:"💝",girl:"👧",globe_with_meridians:"🌐",goal_net:"🥅",goat:"🐐",golf:"⛳️",golfing_man:"🏌️",golfing_woman:"🏌️‍♀️",gorilla:"🦍",grapes:"🍇",green_apple:"🍏",green_book:"📗",green_heart:"💚",green_salad:"🥗",grey_exclamation:"❕",grey_question:"❔",grimacing:"😬",grin:"😁",grinning:"😀",guardsman:"💂",guardswoman:"💂‍♀️",guitar:"🎸",gun:"🔫",haircut_woman:"💇",haircut_man:"💇‍♂️",hamburger:"🍔",hammer:"🔨",hammer_and_pick:"⚒",hammer_and_wrench:"🛠",hamster:"🐹",hand:"✋",handbag:"👜",handshake:"🤝",hankey:"💩",hatched_chick:"🐥",hatching_chick:"🐣",headphones:"🎧",hear_no_evil:"🙉",heart:"❤️",heart_decoration:"💟",heart_eyes:"😍",heart_eyes_cat:"😻",heartbeat:"💓",heartpulse:"💗",hearts:"♥️",heavy_check_mark:"✔️",heavy_division_sign:"➗",heavy_dollar_sign:"💲",heavy_heart_exclamation:"❣️",heavy_minus_sign:"➖",heavy_multiplication_x:"✖️",heavy_plus_sign:"➕",helicopter:"🚁",herb:"🌿",hibiscus:"🌺",high_brightness:"🔆",high_heel:"👠",hocho:"🔪",hole:"🕳",honey_pot:"🍯",horse:"🐴",horse_racing:"🏇",hospital:"🏥",hot_pepper:"🌶",hotdog:"🌭",hotel:"🏨",hotsprings:"♨️",hourglass:"⌛️",hourglass_flowing_sand:"⏳",house:"🏠",house_with_garden:"🏡",houses:"🏘",hugs:"🤗",hushed:"😯",ice_cream:"🍨",ice_hockey:"🏒",ice_skate:"⛸",icecream:"🍦",id:"🆔",ideograph_advantage:"🉐",imp:"👿",inbox_tray:"📥",incoming_envelope:"📨",tipping_hand_woman:"💁",information_source:"ℹ️",innocent:"😇",interrobang:"⁉️",iphone:"📱",izakaya_lantern:"🏮",jack_o_lantern:"🎃",japan:"🗾",japanese_castle:"🏯",japanese_goblin:"👺",japanese_ogre:"👹",jeans:"👖",joy:"😂",joy_cat:"😹",joystick:"🕹",kaaba:"🕋",key:"🔑",keyboard:"⌨️",keycap_ten:"🔟",kick_scooter:"🛴",kimono:"👘",kiss:"💋",kissing:"😗",kissing_cat:"😽",kissing_closed_eyes:"😚",kissing_heart:"😘",kissing_smiling_eyes:"😙",kiwi_fruit:"🥝",koala:"🐨",koko:"🈁",label:"🏷",large_blue_circle:"🔵",large_blue_diamond:"🔷",large_orange_diamond:"🔶",last_quarter_moon:"🌗",last_quarter_moon_with_face:"🌜",latin_cross:"✝️",laughing:"😆",leaves:"🍃",ledger:"📒",left_luggage:"🛅",left_right_arrow:"↔️",leftwards_arrow_with_hook:"↩️",lemon:"🍋",leo:"♌️",leopard:"🐆",level_slider:"🎚",libra:"♎️",light_rail:"🚈",link:"🔗",lion:"🦁",lips:"👄",lipstick:"💄",lizard:"🦎",lock:"🔒",lock_with_ink_pen:"🔏",lollipop:"🍭",loop:"➿",loud_sound:"🔊",loudspeaker:"📢",love_hotel:"🏩",love_letter:"💌",low_brightness:"🔅",lying_face:"🤥",m:"Ⓜ️",mag:"🔍",mag_right:"🔎",mahjong:"🀄️",mailbox:"📫",mailbox_closed:"📪",mailbox_with_mail:"📬",mailbox_with_no_mail:"📭",man:"👨",man_artist:"👨‍🎨",man_astronaut:"👨‍🚀",man_cartwheeling:"🤸‍♂️",man_cook:"👨‍🍳",man_dancing:"🕺",man_facepalming:"🤦‍♂️",man_factory_worker:"👨‍🏭",man_farmer:"👨‍🌾",man_firefighter:"👨‍🚒",man_health_worker:"👨‍⚕️",man_in_tuxedo:"🤵",man_judge:"👨‍⚖️",man_juggling:"🤹‍♂️",man_mechanic:"👨‍🔧",man_office_worker:"👨‍💼",man_pilot:"👨‍✈️",man_playing_handball:"🤾‍♂️",man_playing_water_polo:"🤽‍♂️",man_scientist:"👨‍🔬",man_shrugging:"🤷‍♂️",man_singer:"👨‍🎤",man_student:"👨‍🎓",man_teacher:"👨‍🏫",man_technologist:"👨‍💻",man_with_gua_pi_mao:"👲",man_with_turban:"👳",tangerine:"🍊",mans_shoe:"👞",mantelpiece_clock:"🕰",maple_leaf:"🍁",martial_arts_uniform:"🥋",mask:"😷",massage_woman:"💆",massage_man:"💆‍♂️",meat_on_bone:"🍖",medal_military:"🎖",medal_sports:"🏅",mega:"📣",melon:"🍈",memo:"📝",men_wrestling:"🤼‍♂️",menorah:"🕎",mens:"🚹",metal:"🤘",metro:"🚇",microphone:"🎤",microscope:"🔬",milk_glass:"🥛",milky_way:"🌌",minibus:"🚐",minidisc:"💽",mobile_phone_off:"📴",money_mouth_face:"🤑",money_with_wings:"💸",moneybag:"💰",monkey:"🐒",monkey_face:"🐵",monorail:"🚝",moon:"🌔",mortar_board:"🎓",mosque:"🕌",motor_boat:"🛥",motor_scooter:"🛵",motorcycle:"🏍",motorway:"🛣",mount_fuji:"🗻",mountain:"⛰",mountain_biking_man:"🚵",mountain_biking_woman:"🚵‍♀️",mountain_cableway:"🚠",mountain_railway:"🚞",mountain_snow:"🏔",mouse:"🐭",mouse2:"🐁",movie_camera:"🎥",moyai:"🗿",mrs_claus:"🤶",muscle:"💪",mushroom:"🍄",musical_keyboard:"🎹",musical_note:"🎵",musical_score:"🎼",mute:"🔇",nail_care:"💅",name_badge:"📛",national_park:"🏞",nauseated_face:"🤢",necktie:"👔",negative_squared_cross_mark:"❎",nerd_face:"🤓",neutral_face:"😐",new:"🆕",new_moon:"🌑",new_moon_with_face:"🌚",newspaper:"📰",newspaper_roll:"🗞",next_track_button:"⏭",ng:"🆖",no_good_man:"🙅‍♂️",no_good_woman:"🙅",night_with_stars:"🌃",no_bell:"🔕",no_bicycles:"🚳",no_entry:"⛔️",no_entry_sign:"🚫",no_mobile_phones:"📵",no_mouth:"😶",no_pedestrians:"🚷",no_smoking:"🚭","non-potable_water":"🚱",nose:"👃",notebook:"📓",notebook_with_decorative_cover:"📔",notes:"🎶",nut_and_bolt:"🔩",o:"⭕️",o2:"🅾️",ocean:"🌊",octopus:"🐙",oden:"🍢",office:"🏢",oil_drum:"🛢",ok:"🆗",ok_hand:"👌",ok_man:"🙆‍♂️",ok_woman:"🙆",old_key:"🗝",older_man:"👴",older_woman:"👵",om:"🕉",on:"🔛",oncoming_automobile:"🚘",oncoming_bus:"🚍",oncoming_police_car:"🚔",oncoming_taxi:"🚖",open_file_folder:"📂",open_hands:"👐",open_mouth:"😮",open_umbrella:"☂️",ophiuchus:"⛎",orange_book:"📙",orthodox_cross:"☦️",outbox_tray:"📤",owl:"🦉",ox:"🐂",package:"📦",page_facing_up:"📄",page_with_curl:"📃",pager:"📟",paintbrush:"🖌",palm_tree:"🌴",pancakes:"🥞",panda_face:"🐼",paperclip:"📎",paperclips:"🖇",parasol_on_ground:"⛱",parking:"🅿️",part_alternation_mark:"〽️",partly_sunny:"⛅️",passenger_ship:"🛳",passport_control:"🛂",pause_button:"⏸",peace_symbol:"☮️",peach:"🍑",peanuts:"🥜",pear:"🍐",pen:"🖊",pencil2:"✏️",penguin:"🐧",pensive:"😔",performing_arts:"🎭",persevere:"😣",person_fencing:"🤺",pouting_woman:"🙎",phone:"☎️",pick:"⛏",pig:"🐷",pig2:"🐖",pig_nose:"🐽",pill:"💊",pineapple:"🍍",ping_pong:"🏓",pisces:"♓️",pizza:"🍕",place_of_worship:"🛐",plate_with_cutlery:"🍽",play_or_pause_button:"⏯",point_down:"👇",point_left:"👈",point_right:"👉",point_up:"☝️",point_up_2:"👆",police_car:"🚓",policewoman:"👮‍♀️",poodle:"🐩",popcorn:"🍿",post_office:"🏣",postal_horn:"📯",postbox:"📮",potable_water:"🚰",potato:"🥔",pouch:"👝",poultry_leg:"🍗",pound:"💷",rage:"😡",pouting_cat:"😾",pouting_man:"🙎‍♂️",pray:"🙏",prayer_beads:"📿",pregnant_woman:"🤰",previous_track_button:"⏮",prince:"🤴",princess:"👸",printer:"🖨",purple_heart:"💜",purse:"👛",pushpin:"📌",put_litter_in_its_place:"🚮",question:"❓",rabbit:"🐰",rabbit2:"🐇",racehorse:"🐎",racing_car:"🏎",radio:"📻",radio_button:"🔘",radioactive:"☢️",railway_car:"🚃",railway_track:"🛤",rainbow:"🌈",rainbow_flag:"🏳️‍🌈",raised_back_of_hand:"🤚",raised_hand_with_fingers_splayed:"🖐",raised_hands:"🙌",raising_hand_woman:"🙋",raising_hand_man:"🙋‍♂️",ram:"🐏",ramen:"🍜",rat:"🐀",record_button:"⏺",recycle:"♻️",red_circle:"🔴",registered:"®️",relaxed:"☺️",relieved:"😌",reminder_ribbon:"🎗",repeat:"🔁",repeat_one:"🔂",rescue_worker_helmet:"⛑",restroom:"🚻",revolving_hearts:"💞",rewind:"⏪",rhinoceros:"🦏",ribbon:"🎀",rice:"🍚",rice_ball:"🍙",rice_cracker:"🍘",rice_scene:"🎑",right_anger_bubble:"🗯",ring:"💍",robot:"🤖",rocket:"🚀",rofl:"🤣",roll_eyes:"🙄",roller_coaster:"🎢",rooster:"🐓",rose:"🌹",rosette:"🏵",rotating_light:"🚨",round_pushpin:"📍",rowing_man:"🚣",rowing_woman:"🚣‍♀️",rugby_football:"🏉",running_man:"🏃",running_shirt_with_sash:"🎽",running_woman:"🏃‍♀️",sa:"🈂️",sagittarius:"♐️",sake:"🍶",sandal:"👡",santa:"🎅",satellite:"📡",saxophone:"🎷",school:"🏫",school_satchel:"🎒",scissors:"✂️",scorpion:"🦂",scorpius:"♏️",scream:"😱",scream_cat:"🙀",scroll:"📜",seat:"💺",secret:"㊙️",see_no_evil:"🙈",seedling:"🌱",selfie:"🤳",shallow_pan_of_food:"🥘",shamrock:"☘️",shark:"🦈",shaved_ice:"🍧",sheep:"🐑",shell:"🐚",shield:"🛡",shinto_shrine:"⛩",ship:"🚢",shirt:"👕",shopping:"🛍",shopping_cart:"🛒",shower:"🚿",shrimp:"🦐",signal_strength:"📶",six_pointed_star:"🔯",ski:"🎿",skier:"⛷",skull:"💀",skull_and_crossbones:"☠️",sleeping:"😴",sleeping_bed:"🛌",sleepy:"😪",slightly_frowning_face:"🙁",slightly_smiling_face:"🙂",slot_machine:"🎰",small_airplane:"🛩",small_blue_diamond:"🔹",small_orange_diamond:"🔸",small_red_triangle:"🔺",small_red_triangle_down:"🔻",smile:"😄",smile_cat:"😸",smiley:"😃",smiley_cat:"😺",smiling_imp:"😈",smirk:"😏",smirk_cat:"😼",smoking:"🚬",snail:"🐌",snake:"🐍",sneezing_face:"🤧",snowboarder:"🏂",snowflake:"❄️",snowman:"⛄️",snowman_with_snow:"☃️",sob:"😭",soccer:"⚽️",soon:"🔜",sos:"🆘",sound:"🔉",space_invader:"👾",spades:"♠️",spaghetti:"🍝",sparkle:"❇️",sparkler:"🎇",sparkles:"✨",sparkling_heart:"💖",speak_no_evil:"🙊",speaker:"🔈",speaking_head:"🗣",speech_balloon:"💬",speedboat:"🚤",spider:"🕷",spider_web:"🕸",spiral_calendar:"🗓",spiral_notepad:"🗒",spoon:"🥄",squid:"🦑",stadium:"🏟",star:"⭐️",star2:"🌟",star_and_crescent:"☪️",star_of_david:"✡️",stars:"🌠",station:"🚉",statue_of_liberty:"🗽",steam_locomotive:"🚂",stew:"🍲",stop_button:"⏹",stop_sign:"🛑",stopwatch:"⏱",straight_ruler:"📏",strawberry:"🍓",stuck_out_tongue:"😛",stuck_out_tongue_closed_eyes:"😝",stuck_out_tongue_winking_eye:"😜",studio_microphone:"🎙",stuffed_flatbread:"🥙",sun_behind_large_cloud:"🌥",sun_behind_rain_cloud:"🌦",sun_behind_small_cloud:"🌤",sun_with_face:"🌞",sunflower:"🌻",sunglasses:"😎",sunny:"☀️",sunrise:"🌅",sunrise_over_mountains:"🌄",surfing_man:"🏄",surfing_woman:"🏄‍♀️",sushi:"🍣",suspension_railway:"🚟",sweat:"😓",sweat_drops:"💦",sweat_smile:"😅",sweet_potato:"🍠",swimming_man:"🏊",swimming_woman:"🏊‍♀️",symbols:"🔣",synagogue:"🕍",syringe:"💉",taco:"🌮",tada:"🎉",tanabata_tree:"🎋",taurus:"♉️",taxi:"🚕",tea:"🍵",telephone_receiver:"📞",telescope:"🔭",tennis:"🎾",tent:"⛺️",thermometer:"🌡",thinking:"🤔",thought_balloon:"💭",ticket:"🎫",tickets:"🎟",tiger:"🐯",tiger2:"🐅",timer_clock:"⏲",tipping_hand_man:"💁‍♂️",tired_face:"😫",tm:"™️",toilet:"🚽",tokyo_tower:"🗼",tomato:"🍅",tongue:"👅",top:"🔝",tophat:"🎩",tornado:"🌪",trackball:"🖲",tractor:"🚜",traffic_light:"🚥",train:"🚋",train2:"🚆",tram:"🚊",triangular_flag_on_post:"🚩",triangular_ruler:"📐",trident:"🔱",triumph:"😤",trolleybus:"🚎",trophy:"🏆",tropical_drink:"🍹",tropical_fish:"🐠",truck:"🚚",trumpet:"🎺",tulip:"🌷",tumbler_glass:"🥃",turkey:"🦃",turtle:"🐢",tv:"📺",twisted_rightwards_arrows:"🔀",two_hearts:"💕",two_men_holding_hands:"👬",two_women_holding_hands:"👭",u5272:"🈹",u5408:"🈴",u55b6:"🈺",u6307:"🈯️",u6708:"🈷️",u6709:"🈶",u6e80:"🈵",u7121:"🈚️",u7533:"🈸",u7981:"🈲",u7a7a:"🈳",umbrella:"☔️",unamused:"😒",underage:"🔞",unicorn:"🦄",unlock:"🔓",up:"🆙",upside_down_face:"🙃",v:"✌️",vertical_traffic_light:"🚦",vhs:"📼",vibration_mode:"📳",video_camera:"📹",video_game:"🎮",violin:"🎻",virgo:"♍️",volcano:"🌋",volleyball:"🏐",vs:"🆚",vulcan_salute:"🖖",walking_man:"🚶",walking_woman:"🚶‍♀️",waning_crescent_moon:"🌘",waning_gibbous_moon:"🌖",warning:"⚠️",wastebasket:"🗑",watch:"⌚️",water_buffalo:"🐃",watermelon:"🍉",wave:"👋",wavy_dash:"〰️",waxing_crescent_moon:"🌒",wc:"🚾",weary:"😩",wedding:"💒",weight_lifting_man:"🏋️",weight_lifting_woman:"🏋️‍♀️",whale:"🐳",whale2:"🐋",wheel_of_dharma:"☸️",wheelchair:"♿️",white_check_mark:"✅",white_circle:"⚪️",white_flag:"🏳️",white_flower:"💮",white_large_square:"⬜️",white_medium_small_square:"◽️",white_medium_square:"◻️",white_small_square:"▫️",white_square_button:"🔳",wilted_flower:"🥀",wind_chime:"🎐",wind_face:"🌬",wine_glass:"🍷",wink:"😉",wolf:"🐺",woman:"👩",woman_artist:"👩‍🎨",woman_astronaut:"👩‍🚀",woman_cartwheeling:"🤸‍♀️",woman_cook:"👩‍🍳",woman_facepalming:"🤦‍♀️",woman_factory_worker:"👩‍🏭",woman_farmer:"👩‍🌾",woman_firefighter:"👩‍🚒",woman_health_worker:"👩‍⚕️",woman_judge:"👩‍⚖️",woman_juggling:"🤹‍♀️",woman_mechanic:"👩‍🔧",woman_office_worker:"👩‍💼",woman_pilot:"👩‍✈️",woman_playing_handball:"🤾‍♀️",woman_playing_water_polo:"🤽‍♀️",woman_scientist:"👩‍🔬",woman_shrugging:"🤷‍♀️",woman_singer:"👩‍🎤",woman_student:"👩‍🎓",woman_teacher:"👩‍🏫",woman_technologist:"👩‍💻",woman_with_turban:"👳‍♀️",womans_clothes:"👚",womans_hat:"👒",women_wrestling:"🤼‍♀️",womens:"🚺",world_map:"🗺",worried:"😟",wrench:"🔧",writing_hand:"✍️",x:"❌",yellow_heart:"💛",yen:"💴",yin_yang:"☯️",yum:"😋",zap:"⚡️",zipper_mouth_face:"🤐",zzz:"💤",octocat:'<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAOwUlEQVR42uVbCVyO6RbPmn0sw9gZS0aZO4y5GTEUE2ObxjZjrbHEJVy3sWS5pkaWxjLEkCVDSbSgFLdESaWSLIVUSIi4kvb9f895vi/zbbR+yZ339/tbnu99n/ec/3Oe85xznufV0CjDBaAdwZqwnzCJ0FXjHV70/i8J5oQDhCFV8cJdq1atwqxZs+Ds7Iz4+HhqwgXCLELNKlK6G2Ej4e6lS5ewZcsWzJgxA+fOnWNZFqvzxT1v3boF/qcsBg0ahP3796OwsJAFWKYuIqjfPoS9cXFxWL58Obp06SInh5aWFr//jjoJWLlu3TolAorRuXNn7Ny5k4W4Spgj81xrgj5hLmED4RDhlNRygglBhADCSakpWxFMCHoETUJTwrYHDx7A1NT0je9nPHz4kN/fXl0EeI0aNeqtAjB69+4NPz8/FsSdlXvy5An8/f1hZ2cHCwsLGBsbY/To0cJy9PT0MGDAAAwePBhGRkbClNesWYODBw8iODgYOTk53M/d9evXo27duiW++8iRI3z/ZHURENOjR48ShSjGuHHjhHJ16tQp9TOKaNWqlZKpvw1MHluQOpSvk5eXh5YtW5ZbmarAvHnzmIBd6iCgXnZ2Npo1a1atCWAfwY5SHQTUKCoqQocOHao1AebmHBJgi7p8QBDP6epMwKFDvMDAWF0ELLS1ta3WBNy9e5cJMFIXAdvt7e2rNQHDhw9nAv5D+KKylV9y8+bNCi1pVYWZM2cyCfaVTcDdsqzH7xpBQRxcwqyylLdi5/K+KM/Q0dFhAqIri4Bn1T0AUgVpdmhYUeVHnD59+r1TnjF27Fgm4HhFCThoYmLyXhLQoEGD4mRKsyIE3OrZs+d7SQCDCyZcNSqv8k1evXoFTU3NUr+wzUcfYqRBf8yb/C2WzfoBFoTF08fBdMIITDD8CsP1+kL30x7Q6dYZH7drjfZ0f4fWLdG1Q1t81qMLBvTRwejB/TBl1BDMnzQGS2dMxKo5k7Fs9iSY/jAaBvR8Pc26pZaH02quLZSXgO6xsbGlelGnli1wZKcVMqN8gKcRwItrf+K/VB95doXaLwOJIVSzOU/+2Re5kV7IuuyJrIhTyLt6mmztLBBPNZLHoUAy9fE8UvJ8ikxfj8PwJPQErJeYlkquTZs2MQFLykuANgc/Jb2kn3Z3ZMaQUrmxwO1zyAo7gfRAJ6RfOIyMEFdkXj5F8BTK5lzxQv610yi8QcFatI8gQoCIK7x+hojwRnaE5H4JTiEj9Pjr/rJDqcZyn9b4ovu45LYbdWvXeqtsXMHiSlZ5CegRExPz1hd83PYj5POo0QinXyLFg48hnZTOiQ1Dzr1IZEaeQRoJn0HKZIR7lA2kfHrQUerXHTlx4ZL+rnjjFRGRGeYB5MUj2GnbW+XbuJFrp1heXgI6JCYmvvUFN1x3Aek3SWkapRAXMeJFGS8ge2Xfuog0toaykED3Mpk8+shOk+sv68Y50V9WuKewBKt5094o39atW/mRf5WXgIYZGRlo3Lixys4nj6A6Z1YMcqRCpwU4ouDlUyHk/QA/hNttR25Wlvh/ZthJUsil9ATQ/axkYbqEzDgfL0Ts/x35+aLyTES7IY36Q6w/+Q4/tP6wuUoZ9+7dy7ebVmQZjO/atavKzn32rAdeXkd6KCkXdAxZ13yFcLFnvPD73zrDVrsdTs6eggKSuSjjORHkUGoC0i86Iyc6QPQX7eqMnTodYNuzHU4vnosiaitMSUSavwMy6d3IvEUrzViVMrq5uXEX4ytCgL++vr5Sx7Vr1cIDX0dKkQJfj37Rs3jw1sBxkwlwGD4Ax3+ciN1faCHW76xQRFgAOcjSEMBkIe0x8nLzcez7kTg8Rh/uxuOxR/cTJISFSfq7eATpZCk8CAfXLVFJwIULXHnHoIoQYLtw4UKljps2aogXQcQuef/XAiMDKY+S4DhyEFwpDnCj9f+Afl8EbbWRTANaAdihlYoAMn8aZzyNuYODX/eD29TvRH/7v+qN8H27JdOAyWQfQQ74xPafVRLAPox9WUlK6hIGEgx4f00Kg2JcvHhRqeP6FIwknXemyen/2gLIIeC/CYk49M0AuE4xgtu0sThg8AUCN62TEuBdRgJo2Y+Kxh9D/k59SQiwH9QHobt3SAk4KSGA4oWjm1YqyVi8U6Soj4yOrHM/jTAyKVby/PnzIoNi8L+L4eXlpXoFcLcTgc1rAlISkJeXDxeK2A6P1hdTwI6mQPTJE+WbAlnJyE7PhNO3Q3BkrKGYWtxfHMkkmQLO0ilwA7+vXqAkn66urtBLUZ9iHfm30NBQaPAf165dA0d9vP2UlJSEp0+f4vHjx3j06JH4e+rUqUovcNmyGkiNEkLwklXsBG+ecMUOnfbYod1emG5uboFKJ8jPFVD0l0dBUHqoPDHpQeQEb0qc4FUHe3KAbYUT9JgzDbwOFL5MfN0fXkXhJ5PxSvLt2LFD1Ah5u4z1YJ14l4qnBe8v3rhxAzz4PAVG8nLHivIP0dHRiIiIQGRkpEgmrl69ClW1QBMjQ7LDW8hmU+RRI69ckJIkhL7jfRJBm62R+TJVYq6h0jhBRslsivqenT2MF/7OyI70VmkFhWnPJaS6OyPkt43IycqR9EfWlH7JDQUUTuNhCHR7Ke9YcRp/5coVoQPrcvnyZURFRYmBZlLS0kR8MVLD29sbnp6e8PHxQUBAgCgn8YO8E3z79m3BGKeVc+bMkXuBZt06SA12F/F5Go0gR4C8HBalPZMPXKL8lQKhPAqF+f97KXFyNx6HQsoPsshJ/kmAp2TKkJLISpXvjyxNhMYcDVLOEO+lPDi8B5mamipkZx1YF9YpJCRErAy+vr5CZ9ZdWABhDGEYYTBhAOFz3g4nfMJelNCbkNCpUye5F034mvxIPi1/FM+zQCw0k5B9O0iEr5kRXkqhMJOVf9NXIHjtT7hmaymSoBzKETimkAuFpaF1dkwI9RcmIYaXv3BJXoGCuyIgk5WpefPmKCgoYK46SmX/RKoL69Sfl0WuFEl1HlmWJXE5z6WmTZvKJxxmxkIQ3AuU5APk6NICj4hRT6eITTEEzqWk55HHPjz3cxJhNF5cxeNT9kj2cRDTQjEkzpDtjyyCic5l5fEA7uSHFEefR5pPsahrb2B9QkICFHeJ51HunkdLIg0VLY0BFKdLwllVHp4dHyvst3QuEiiju21vA/+VZkiluIKt4I3RIfWXQ4QgKUxkni47LJWUP3PmjHo2RxVI+CebmKJP6EiFDVurxUgmExe5PHlnPAkn8w4QqW62NCVmYopozid5H0CI9RKE21ggJeAYEeMnfitOnRn5XCfgeJ+VTosWQU8MOc6ZE0cqnUm4fv165SrPBVHCfMI4TowUfmOfsIcdJh92kBWmUcP6GDt8EDZbzIffH5tx3/ewSFjw5LKk0MEFEkZenDBjgew7Yiog5brkt+QrknvJmhIp4Apw/A1bVpjhG/0v5d7Vrl07bNu2TelUSqUoz8uI3Z49OEtBAy+TdP1CqKtwHzvQUxxgTJs2TeX5gdq1a0ObSmCjh+jB+NuvRamL1+3ls77HCip1rTSdJP5eNnMizKndjMLoH42G4bthX+FzHS3UVVEC69evH3799VeKMXJZrlWKclUGAZ5jxoxB02ZNsNlxH74aagBHZyex986HlVTczyGmI58h4CjL2toa48ePFxsUPEotWrQoc0GT0/C2bduiY8eO4ISMcxLeoOFYhS6qm2EpoZG65jmbv+dPSyRZlt5QfVjvtX19AOFNL+aDFNI4m0eFc9Ho5ORkaGtrl5kAVp6DMOk88efEjLe++ZhclZwHTJHEHbs4YOCmLj2645fdvwnTK42zoXtaEHwNDQ3LXdZm5yad3/2r+gQmDsRnIF5KAldX6zdsgG/GG8F44Vzcu3eP2y1K6GPr2rVrK1zbnz59Or/LoaoJCPZ4kCZsjw9GECL79OmDj9q2wb+320C3/5fgPQO6Vrzh+fpcDqxXr16lbHBwgkZXm6okYJr0ECMrX5vraiJ1lArEjrEnzWuOqemiYj9spGd2ee478XkiPsJakmJ83qA05/8qXNurJFLiunXrhpo1a6LxB02wyHIFZpovgOHwYfjZ0hK2lH5u2rwZ5suWYv5ycyUlmjRpgl69eimlrFy3kwuoyOvXr19frm3RokVMwPZ3TYC57E6xVq+e6KzVDSaL/oEp82Zh8IhhWLjGAp/p9oX5ujVKBNjY2MDV1VWuzd3dXaTesm2biUQuZ8u28elSPmKr8a4vdog8GnJpcT1N1KHUuBbt0jSgWuGbzJh3mVhh2TYHBwdxjFa2jVcZnvPVlQBOLXdZWlqW2ZFxNYYVlm07fPgwAgMD5dr4OD5HeHLFFxM+O42DGtXhIkFaMQlcUjIzM0P37t1Ro0YNpZPjPJcVK7SOjo5ybU5OTqIAo0gAh97VlgAZIj4l8Pn4WFaO64ocuXG6zJtDbMqySnC7IgF8uptLVrJtq1evFuWqak+A4j4i4TNpltiJ8LPiNFFFwNGjRyWFyfedAFUny/joekkEuLi4KK0CfykCeFnkiu1flgBeFtl3/D8SsMbKykpOifv37ysRcPz4cVHKUiSA8wwNdR9/VTMBSh9Y8S4Nf2qnSICiBbDzVCRg9uzZTMC+94kAv6FDh8opwRsVHPjItnl4eEDxHNLKlStFXV+2javQ/M1SpZe+1KA4L4G7WDG57fSm/OUbXiqG0ewAFYOeYcN4fwZhvLkp2y4tftrxcltdlf/w+fPn4qNGxTCYU2m6nrRu3VqunT/EoiuZvw6TTZHpyuNNmEaNGsndP3fu3OJAq1N1JOAHDmyKheVtNP4OkE2crULRAW7fvl20EyyLy24a8p+/7WISFixYIMLt4t82bNhQYjXqXREgPq3j74mlX3AmSL8E1eOPIBXnuVT5OsVZpuLnOMeOHeN7vifwiYhYzhC5IpwlOXj1QXWdBmy/XWU/X+UqMZfKBw4cKAobHPlJlZe9h6tOu+7cuSN2dg0MDMSSyZUpmXvaSD+crq/xvl0k9BTCRa7qEPq+5T4t6ffF52WVV+f1P6zyLG30bsU4AAAAAElFTkSuQmCC">',showdown:'<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAECtaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzA2NyA3OS4xNTc3NDcsIDIwMTUvMDMvMzAtMjM6NDA6NDIgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTctMTAtMjRUMTM6MzE6MzArMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOklDQ1Byb2ZpbGU+c1JHQiBJRUM2MTk2Ni0yLjE8L3Bob3Rvc2hvcDpJQ0NQcm9maWxlPgogICAgICAgICA8cGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgICAgIDxyZGY6QmFnPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHBob3Rvc2hvcDpMYXllck5hbWU+UyAtPC9waG90b3Nob3A6TGF5ZXJOYW1lPgogICAgICAgICAgICAgICAgICA8cGhvdG9zaG9wOkxheWVyVGV4dD5TIC08L3Bob3Rvc2hvcDpMYXllclRleHQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6N2NkMzQxNzctOWYyZi0yNDRiLWEyYjQtMzU1MzJkY2Y1MWJiPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6M2E1YzgxYmYtYjhiNy0xMWU3LTk0NDktYTQ2MzdlZjJkNjMzPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jcmVhdGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE3LTEwLTI0VDEzOjMxOjMwKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjdjZDM0MTc3LTlmMmYtMjQ0Yi1hMmI0LTM1NTMyZGNmNTFiYjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjYwQzVBRTY1RjY5Q0U0MTE5NDVBODU1RTNCQ0E3RUVCPC9zdFJlZjpkb2N1bWVudElEPgogICAgICAgICAgICA8c3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pse7bzcAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAA1JJREFUeNrsm1+OmlAUhz+aeS9dwZggJn1AnRUMO6jpBgZXULuC2hWUWUGZBTSxKyiuoA4mfUBMnB04K5g+9DihRBHlyh/lJLwIXLgf99xzzu9etZeXFy7Z3nDh1gBoAFy4XeVtQNO0zNcapmUDfUBPnFoBfhQGq6IBaHmjwD4Ahmk5wAD4kKG5J8CNwsAFaHe6DvA9cc0wCgOv8gDka3vA9RHNPgo0D7hNnJtGYWBXxgV2dH4MfMnRRA+Y1WIO2NJ5F/ikoKm3tYsChmkNFHW+fmHQMC1dfHaXPQP3wM1yMdc2B/AOGALTWobBmI1Shu0UGCwX83XyRBQGawHntTtdG5gUNfxVu4CTNqNv6/wWGL7kCc+1AmCYVisl3I2ydD4GYZUCs7IjoLXrxHIx9w9tLAqDCfBwDrXAY457x+cAoCfuwRGjYFUnAGk+PsjR7s8Dn1VeLWCYVlpDw+VivjVHSHt+u9PVJbzGzZXQWTkAkz0V31fATUaEsjVJlQBs4FeGcteLgzgbAALBA+4y3voAeJL8nA0AHfClnM1qm1HhnYUidCSE+KzvSSJUTwAxCOMcpfETMFYpfRUKIAbCFhC3OTJJJwqDWS0BxED0JZ4Pjix1P2+E0loCSMBwyK4S/xc1ojBwag8gMU84cvTKGgmlAYhngu1O9xAXuVE5J1QCQCz3bwHuHvdQui5QKQAxEO6eEKpsFCgTRSXkvdoxSlBMCxhJJbgrrbZRtHCiShN0pRB6PeQ3ckBw2K0oKXMBVYJIP+Nvh9qulFivGoBt1lLQxowT2ykBXCfnhZIglgYACWmqXQv+baioBYCeiCQHm+QEg1O7RhF7hO4OhSAhcJKSFU7qBGADwZeqMMuXn6TUBw8qlaMrirNb4LdhWlP+SWD+cjFfxTpuS2GUpik+o3jFSEkqbJiWn0P0OMSGqlWiOu0TvD+FRHZKAE+oW+cfRmEwqlsesJJEJs8y91QqP+9UL6lqEtz2gpuNEY5sm9sIHln2DRa2aFKGJtiXkZEMiWtgVvRKUSUFkSKt2S7fAGgAXLYpmQQXf36MUChTZdUa2u8/rkvPA6Tz30r4eH3ybcBS5gJ6SaNXb+aABkA1AMxKenclBZLW/He4cYEGwEXb3wEASelexk6LIIIAAAAASUVORK5CYII=">'},I.Converter=function(g){"use strict";function C(g,C){if(C=C||null,I.helper.isString(g)){if(g=I.helper.stdExtName(g),C=g,I.extensions[g])return console.warn("DEPRECATION WARNING: "+g+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"),void function(g,C){"function"==typeof g&&(g=g(new I.Converter));I.helper.isArray(g)||(g=[g]);var e=A(g,C);if(!e.valid)throw Error(e.error);for(var r=0;r<g.length;++r)switch(g[r].type){case"lang":s.push(g[r]);break;case"output":i.push(g[r]);break;default:throw Error("Extension loader error: Type unrecognized!!!")}}(I.extensions[g],g);if(I.helper.isUndefined(r[g]))throw Error('Extension "'+g+'" could not be loaded. It was either not found or is not a valid extension.');g=r[g]}"function"==typeof g&&(g=g()),I.helper.isArray(g)||(g=[g]);var t=A(g,C);if(!t.valid)throw Error(t.error);for(var a=0;a<g.length;++a){switch(g[a].type){case"lang":s.push(g[a]);break;case"output":i.push(g[a])}if(g[a].hasOwnProperty("listeners"))for(var n in g[a].listeners)g[a].listeners.hasOwnProperty(n)&&e(n,g[a].listeners[n])}}function e(g,A){if(!I.helper.isString(g))throw Error("Invalid argument in converter.listen() method: name must be a string, but "+typeof g+" given");if("function"!=typeof A)throw Error("Invalid argument in converter.listen() method: callback must be a function, but "+typeof A+" given");l.hasOwnProperty(g)||(l[g]=[]),l[g].push(A)}var o={},s=[],i=[],l={},c=a,u={parsed:{},raw:"",format:""};!function(){g=g||{};for(var A in t)t.hasOwnProperty(A)&&(o[A]=t[A]);if("object"!=typeof g)throw Error("Converter expects the passed parameter to be an object, but "+typeof g+" was passed instead.");for(var e in g)g.hasOwnProperty(e)&&(o[e]=g[e]);o.extensions&&I.helper.forEach(o.extensions,C)}(),this._dispatch=function(g,A,C,I){if(l.hasOwnProperty(g))for(var e=0;e<l[g].length;++e){var r=l[g][e](g,A,this,C,I);r&&void 0!==r&&(A=r)}return A},this.listen=function(g,A){return e(g,A),this},this.makeHtml=function(g){if(!g)return g;var A={gHtmlBlocks:[],gHtmlMdBlocks:[],gHtmlSpans:[],gUrls:{},gTitles:{},gDimensions:{},gListLevel:0,hashLinkCounts:{},langExtensions:s,outputModifiers:i,converter:this,ghCodeBlocks:[],metadata:{parsed:{},raw:"",format:""}};return g=g.replace(/¨/g,"¨T"),g=g.replace(/\$/g,"¨D"),g=g.replace(/\r\n/g,"\n"),g=g.replace(/\r/g,"\n"),g=g.replace(/\u00A0/g," "),o.smartIndentationFix&&(g=function(g){var A=g.match(/^\s*/)[0].length,C=new RegExp("^\\s{0,"+A+"}","gm");return g.replace(C,"")}(g)),g="\n\n"+g+"\n\n",g=I.subParser("detab")(g,o,A),g=g.replace(/^[ \t]+$/gm,""),I.helper.forEach(s,function(C){g=I.subParser("runExtension")(C,g,o,A)}),g=I.subParser("metadata")(g,o,A),g=I.subParser("hashPreCodeTags")(g,o,A),g=I.subParser("githubCodeBlocks")(g,o,A),g=I.subParser("hashHTMLBlocks")(g,o,A),g=I.subParser("hashCodeTags")(g,o,A),g=I.subParser("stripLinkDefinitions")(g,o,A),g=I.subParser("blockGamut")(g,o,A),g=I.subParser("unhashHTMLSpans")(g,o,A),g=I.subParser("unescapeSpecialChars")(g,o,A),g=g.replace(/¨D/g,"$$"),g=g.replace(/¨T/g,"¨"),g=I.subParser("completeHTMLDocument")(g,o,A),I.helper.forEach(i,function(C){g=I.subParser("runExtension")(C,g,o,A)}),u=A.metadata,g},this.setOption=function(g,A){o[g]=A},this.getOption=function(g){return o[g]},this.getOptions=function(){return o},this.addExtension=function(g,A){C(g,A=A||null)},this.useExtension=function(g){C(g)},this.setFlavor=function(g){if(!n.hasOwnProperty(g))throw Error(g+" flavor was not found");var A=n[g];c=g;for(var C in A)A.hasOwnProperty(C)&&(o[C]=A[C])},this.getFlavor=function(){return c},this.removeExtension=function(g){I.helper.isArray(g)||(g=[g]);for(var A=0;A<g.length;++A){for(var C=g[A],e=0;e<s.length;++e)s[e]===C&&s[e].splice(e,1);for(;0<i.length;++e)i[0]===C&&i[0].splice(e,1)}},this.getAllExtensions=function(){return{language:s,output:i}},this.getMetadata=function(g){return g?u.raw:u.parsed},this.getMetadataFormat=function(){return u.format},this._setMetadataPair=function(g,A){u.parsed[g]=A},this._setMetadataFormat=function(g){u.format=g},this._setMetadataRaw=function(g){u.raw=g}},I.subParser("anchors",function(g,A,C){"use strict";var e=function(g,e,r,t,a,n,o){if(I.helper.isUndefined(o)&&(o=""),r=r.toLowerCase(),g.search(/\(<?\s*>? ?(['"].*['"])?\)$/m)>-1)t="";else if(!t){if(r||(r=e.toLowerCase().replace(/ ?\n/g," ")),t="#"+r,I.helper.isUndefined(C.gUrls[r]))return g;t=C.gUrls[r],I.helper.isUndefined(C.gTitles[r])||(o=C.gTitles[r])}var s='<a href="'+(t=t.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"';return""!==o&&null!==o&&(s+=' title="'+(o=(o=o.replace(/"/g,""")).replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"'),A.openLinksInNewWindow&&!/^#/.test(t)&&(s+=' target="¨E95Eblank"'),s+=">"+e+"</a>"};return g=(g=C.converter._dispatch("anchors.before",g,A,C)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g,e),g=g.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,e),g=g.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,e),g=g.replace(/\[([^\[\]]+)]()()()()()/g,e),A.ghMentions&&(g=g.replace(/(^|\s)(\\)?(@([a-z\d\-]+))(?=[.!?;,[\]()]|\s|$)/gim,function(g,C,e,r,t){if("\\"===e)return C+r;if(!I.helper.isString(A.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");var a=A.ghMentionsLink.replace(/\{u}/g,t),n="";return A.openLinksInNewWindow&&(n=' target="¨E95Eblank"'),C+'<a href="'+a+'"'+n+">"+r+"</a>"})),g=C.converter._dispatch("anchors.after",g,A,C)});var s=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,i=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,l=/()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,c=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,u=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,d=function(g){"use strict";return function(A,C,e,r,t,a,n){var o=e=e.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback),s="",i="",l=C||"",c=n||"";return/^www\./i.test(e)&&(e=e.replace(/^www\./i,"http://www.")),g.excludeTrailingPunctuationFromURLs&&a&&(s=a),g.openLinksInNewWindow&&(i=' target="¨E95Eblank"'),l+'<a href="'+e+'"'+i+">"+o+"</a>"+s+c}},p=function(g,A){"use strict";return function(C,e,r){var t="mailto:";return e=e||"",r=I.subParser("unescapeSpecialChars")(r,g,A),g.encodeEmails?(t=I.helper.encodeEmailAddress(t+r),r=I.helper.encodeEmailAddress(r)):t+=r,e+'<a href="'+t+'">'+r+"</a>"}};I.subParser("autoLinks",function(g,A,C){"use strict";return g=C.converter._dispatch("autoLinks.before",g,A,C),g=g.replace(l,d(A)),g=g.replace(u,p(A,C)),g=C.converter._dispatch("autoLinks.after",g,A,C)}),I.subParser("simplifiedAutoLinks",function(g,A,C){"use strict";return A.simplifiedAutoLink?(g=C.converter._dispatch("simplifiedAutoLinks.before",g,A,C),g=A.excludeTrailingPunctuationFromURLs?g.replace(i,d(A)):g.replace(s,d(A)),g=g.replace(c,p(A,C)),g=C.converter._dispatch("simplifiedAutoLinks.after",g,A,C)):g}),I.subParser("blockGamut",function(g,A,C){"use strict";return g=C.converter._dispatch("blockGamut.before",g,A,C),g=I.subParser("blockQuotes")(g,A,C),g=I.subParser("headers")(g,A,C),g=I.subParser("horizontalRule")(g,A,C),g=I.subParser("lists")(g,A,C),g=I.subParser("codeBlocks")(g,A,C),g=I.subParser("tables")(g,A,C),g=I.subParser("hashHTMLBlocks")(g,A,C),g=I.subParser("paragraphs")(g,A,C),g=C.converter._dispatch("blockGamut.after",g,A,C)}),I.subParser("blockQuotes",function(g,A,C){"use strict";g=C.converter._dispatch("blockQuotes.before",g,A,C),g+="\n\n";var e=/(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;return A.splitAdjacentBlockquotes&&(e=/^ {0,3}>[\s\S]*?(?:\n\n)/gm),g=g.replace(e,function(g){return g=g.replace(/^[ \t]*>[ \t]?/gm,""),g=g.replace(/¨0/g,""),g=g.replace(/^[ \t]+$/gm,""),g=I.subParser("githubCodeBlocks")(g,A,C),g=I.subParser("blockGamut")(g,A,C),g=g.replace(/(^|\n)/g,"$1 "),g=g.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm,function(g,A){var C=A;return C=C.replace(/^ /gm,"¨0"),C=C.replace(/¨0/g,"")}),I.subParser("hashBlock")("<blockquote>\n"+g+"\n</blockquote>",A,C)}),g=C.converter._dispatch("blockQuotes.after",g,A,C)}),I.subParser("codeBlocks",function(g,A,C){"use strict";g=C.converter._dispatch("codeBlocks.before",g,A,C);return g=(g+="¨0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g,function(g,e,r){var t=e,a=r,n="\n";return t=I.subParser("outdent")(t,A,C),t=I.subParser("encodeCode")(t,A,C),t=I.subParser("detab")(t,A,C),t=t.replace(/^\n+/g,""),t=t.replace(/\n+$/g,""),A.omitExtraWLInCodeBlocks&&(n=""),t="<pre><code>"+t+n+"</code></pre>",I.subParser("hashBlock")(t,A,C)+a}),g=g.replace(/¨0/,""),g=C.converter._dispatch("codeBlocks.after",g,A,C)}),I.subParser("codeSpans",function(g,A,C){"use strict";return void 0===(g=C.converter._dispatch("codeSpans.before",g,A,C))&&(g=""),g=g.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(g,e,r,t){var a=t;return a=a.replace(/^([ \t]*)/g,""),a=a.replace(/[ \t]*$/g,""),a=I.subParser("encodeCode")(a,A,C),a=e+"<code>"+a+"</code>",a=I.subParser("hashHTMLSpans")(a,A,C)}),g=C.converter._dispatch("codeSpans.after",g,A,C)}),I.subParser("completeHTMLDocument",function(g,A,C){"use strict";if(!A.completeHTMLDocument)return g;g=C.converter._dispatch("completeHTMLDocument.before",g,A,C);var I="html",e="<!DOCTYPE HTML>\n",r="",t='<meta charset="utf-8">\n',a="",n="";void 0!==C.metadata.parsed.doctype&&(e="<!DOCTYPE "+C.metadata.parsed.doctype+">\n","html"!==(I=C.metadata.parsed.doctype.toString().toLowerCase())&&"html5"!==I||(t='<meta charset="utf-8">'));for(var o in C.metadata.parsed)if(C.metadata.parsed.hasOwnProperty(o))switch(o.toLowerCase()){case"doctype":break;case"title":r="<title>"+C.metadata.parsed.title+"</title>\n";break;case"charset":t="html"===I||"html5"===I?'<meta charset="'+C.metadata.parsed.charset+'">\n':'<meta name="charset" content="'+C.metadata.parsed.charset+'">\n';break;case"language":case"lang":a=' lang="'+C.metadata.parsed[o]+'"',n+='<meta name="'+o+'" content="'+C.metadata.parsed[o]+'">\n';break;default:n+='<meta name="'+o+'" content="'+C.metadata.parsed[o]+'">\n'}return g=e+"<html"+a+">\n<head>\n"+r+t+n+"</head>\n<body>\n"+g.trim()+"\n</body>\n</html>",g=C.converter._dispatch("completeHTMLDocument.after",g,A,C)}),I.subParser("detab",function(g,A,C){"use strict";return g=C.converter._dispatch("detab.before",g,A,C),g=g.replace(/\t(?=\t)/g," "),g=g.replace(/\t/g,"¨A¨B"),g=g.replace(/¨B(.+?)¨A/g,function(g,A){for(var C=A,I=4-C.length%4,e=0;e<I;e++)C+=" ";return C}),g=g.replace(/¨A/g," "),g=g.replace(/¨B/g,""),g=C.converter._dispatch("detab.after",g,A,C)}),I.subParser("ellipsis",function(g,A,C){"use strict";return g=C.converter._dispatch("ellipsis.before",g,A,C),g=g.replace(/\.\.\./g,"…"),g=C.converter._dispatch("ellipsis.after",g,A,C)}),I.subParser("emoji",function(g,A,C){"use strict";if(!A.emoji)return g;return g=(g=C.converter._dispatch("emoji.before",g,A,C)).replace(/:([\S]+?):/g,function(g,A){return I.helper.emojis.hasOwnProperty(A)?I.helper.emojis[A]:g}),g=C.converter._dispatch("emoji.after",g,A,C)}),I.subParser("encodeAmpsAndAngles",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeAmpsAndAngles.before",g,A,C),g=g.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&"),g=g.replace(/<(?![a-z\/?$!])/gi,"<"),g=g.replace(/</g,"<"),g=g.replace(/>/g,">"),g=C.converter._dispatch("encodeAmpsAndAngles.after",g,A,C)}),I.subParser("encodeBackslashEscapes",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeBackslashEscapes.before",g,A,C),g=g.replace(/\\(\\)/g,I.helper.escapeCharactersCallback),g=g.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("encodeBackslashEscapes.after",g,A,C)}),I.subParser("encodeCode",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeCode.before",g,A,C),g=g.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/([*_{}\[\]\\=~-])/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("encodeCode.after",g,A,C)}),I.subParser("escapeSpecialCharsWithinTagAttributes",function(g,A,C){"use strict";return g=(g=C.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",g,A,C)).replace(/<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,function(g){return g.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,I.helper.escapeCharactersCallback)}),g=g.replace(/<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi,function(g){return g.replace(/([\\`*_~=|])/g,I.helper.escapeCharactersCallback)}),g=C.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",g,A,C)}),I.subParser("githubCodeBlocks",function(g,A,C){"use strict";return A.ghCodeBlocks?(g=C.converter._dispatch("githubCodeBlocks.before",g,A,C),g+="¨0",g=g.replace(/(?:^|\n)(```+|~~~+)([^\s`~]*)\n([\s\S]*?)\n\1/g,function(g,e,r,t){var a=A.omitExtraWLInCodeBlocks?"":"\n";return t=I.subParser("encodeCode")(t,A,C),t=I.subParser("detab")(t,A,C),t=t.replace(/^\n+/g,""),t=t.replace(/\n+$/g,""),t="<pre><code"+(r?' class="'+r+" language-"+r+'"':"")+">"+t+a+"</code></pre>",t=I.subParser("hashBlock")(t,A,C),"\n\n¨G"+(C.ghCodeBlocks.push({text:g,codeblock:t})-1)+"G\n\n"}),g=g.replace(/¨0/,""),C.converter._dispatch("githubCodeBlocks.after",g,A,C)):g}),I.subParser("hashBlock",function(g,A,C){"use strict";return g=C.converter._dispatch("hashBlock.before",g,A,C),g=g.replace(/(^\n+|\n+$)/g,""),g="\n\n¨K"+(C.gHtmlBlocks.push(g)-1)+"K\n\n",g=C.converter._dispatch("hashBlock.after",g,A,C)}),I.subParser("hashCodeTags",function(g,A,C){"use strict";g=C.converter._dispatch("hashCodeTags.before",g,A,C);return g=I.helper.replaceRecursiveRegExp(g,function(g,e,r,t){var a=r+I.subParser("encodeCode")(e,A,C)+t;return"¨C"+(C.gHtmlSpans.push(a)-1)+"C"},"<code\\b[^>]*>","</code>","gim"),g=C.converter._dispatch("hashCodeTags.after",g,A,C)}),I.subParser("hashElement",function(g,A,C){"use strict";return function(g,A){var I=A;return I=I.replace(/\n\n/g,"\n"),I=I.replace(/^\n/,""),I=I.replace(/\n+$/g,""),I="\n\n¨K"+(C.gHtmlBlocks.push(I)-1)+"K\n\n"}}),I.subParser("hashHTMLBlocks",function(g,A,C){"use strict";g=C.converter._dispatch("hashHTMLBlocks.before",g,A,C);var e=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"],r=function(g,A,I,e){var r=g;return-1!==I.search(/\bmarkdown\b/)&&(r=I+C.converter.makeHtml(A)+e),"\n\n¨K"+(C.gHtmlBlocks.push(r)-1)+"K\n\n"};A.backslashEscapesHTMLTags&&(g=g.replace(/\\<(\/?[^>]+?)>/g,function(g,A){return"<"+A+">"}));for(var t=0;t<e.length;++t)for(var a,n=new RegExp("^ {0,3}(<"+e[t]+"\\b[^>]*>)","im"),o="<"+e[t]+"\\b[^>]*>",s="</"+e[t]+">";-1!==(a=I.helper.regexIndexOf(g,n));){var i=I.helper.splitAtIndex(g,a),l=I.helper.replaceRecursiveRegExp(i[1],r,o,s,"im");if(l===i[1])break;g=i[0].concat(l)}return g=g.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,I.subParser("hashElement")(g,A,C)),g=I.helper.replaceRecursiveRegExp(g,function(g){return"\n\n¨K"+(C.gHtmlBlocks.push(g)-1)+"K\n\n"},"^ {0,3}\x3c!--","--\x3e","gm"),g=g.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,I.subParser("hashElement")(g,A,C)),g=C.converter._dispatch("hashHTMLBlocks.after",g,A,C)}),I.subParser("hashHTMLSpans",function(g,A,C){"use strict";function I(g){return"¨C"+(C.gHtmlSpans.push(g)-1)+"C"}return g=C.converter._dispatch("hashHTMLSpans.before",g,A,C),g=g.replace(/<[^>]+?\/>/gi,function(g){return I(g)}),g=g.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,function(g){return I(g)}),g=g.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,function(g){return I(g)}),g=g.replace(/<[^>]+?>/gi,function(g){return I(g)}),g=C.converter._dispatch("hashHTMLSpans.after",g,A,C)}),I.subParser("unhashHTMLSpans",function(g,A,C){"use strict";g=C.converter._dispatch("unhashHTMLSpans.before",g,A,C);for(var I=0;I<C.gHtmlSpans.length;++I){for(var e=C.gHtmlSpans[I],r=0;/¨C(\d+)C/.test(e);){var t=RegExp.$1;if(e=e.replace("¨C"+t+"C",C.gHtmlSpans[t]),10===r){console.error("maximum nesting of 10 spans reached!!!");break}++r}g=g.replace("¨C"+I+"C",e)}return g=C.converter._dispatch("unhashHTMLSpans.after",g,A,C)}),I.subParser("hashPreCodeTags",function(g,A,C){"use strict";g=C.converter._dispatch("hashPreCodeTags.before",g,A,C);return g=I.helper.replaceRecursiveRegExp(g,function(g,e,r,t){var a=r+I.subParser("encodeCode")(e,A,C)+t;return"\n\n¨G"+(C.ghCodeBlocks.push({text:g,codeblock:a})-1)+"G\n\n"},"^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>","^ {0,3}</code>\\s*</pre>","gim"),g=C.converter._dispatch("hashPreCodeTags.after",g,A,C)}),I.subParser("headers",function(g,A,C){"use strict";function e(g){var e,r;if(A.customizedHeaderId){var t=g.match(/\{([^{]+?)}\s*$/);t&&t[1]&&(g=t[1])}return e=g,r=I.helper.isString(A.prefixHeaderId)?A.prefixHeaderId:!0===A.prefixHeaderId?"section-":"",A.rawPrefixHeaderId||(e=r+e),e=A.ghCompatibleHeaderId?e.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,"").toLowerCase():A.rawHeaderId?e.replace(/ /g,"-").replace(/&/g,"&").replace(/¨T/g,"¨").replace(/¨D/g,"$").replace(/["']/g,"-").toLowerCase():e.replace(/[^\w]/g,"").toLowerCase(),A.rawPrefixHeaderId&&(e=r+e),C.hashLinkCounts[e]?e=e+"-"+C.hashLinkCounts[e]++:C.hashLinkCounts[e]=1,e}g=C.converter._dispatch("headers.before",g,A,C);var r=isNaN(parseInt(A.headerLevelStart))?1:parseInt(A.headerLevelStart),t=A.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,a=A.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm;g=(g=g.replace(t,function(g,t){var a=I.subParser("spanGamut")(t,A,C),n=A.noHeaderId?"":' id="'+e(t)+'"',o="<h"+r+n+">"+a+"</h"+r+">";return I.subParser("hashBlock")(o,A,C)})).replace(a,function(g,t){var a=I.subParser("spanGamut")(t,A,C),n=A.noHeaderId?"":' id="'+e(t)+'"',o=r+1,s="<h"+o+n+">"+a+"</h"+o+">";return I.subParser("hashBlock")(s,A,C)});var n=A.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;return g=g.replace(n,function(g,t,a){var n=a;A.customizedHeaderId&&(n=a.replace(/\s?\{([^{]+?)}\s*$/,""));var o=I.subParser("spanGamut")(n,A,C),s=A.noHeaderId?"":' id="'+e(a)+'"',i=r-1+t.length,l="<h"+i+s+">"+o+"</h"+i+">";return I.subParser("hashBlock")(l,A,C)}),g=C.converter._dispatch("headers.after",g,A,C)}),I.subParser("horizontalRule",function(g,A,C){"use strict";g=C.converter._dispatch("horizontalRule.before",g,A,C);var e=I.subParser("hashBlock")("<hr />",A,C);return g=g.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,e),g=g.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,e),g=g.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,e),g=C.converter._dispatch("horizontalRule.after",g,A,C)}),I.subParser("images",function(g,A,C){"use strict";function e(g,A,e,r,t,a,n,o){var s=C.gUrls,i=C.gTitles,l=C.gDimensions;if(e=e.toLowerCase(),o||(o=""),g.search(/\(<?\s*>? ?(['"].*['"])?\)$/m)>-1)r="";else if(""===r||null===r){if(""!==e&&null!==e||(e=A.toLowerCase().replace(/ ?\n/g," ")),r="#"+e,I.helper.isUndefined(s[e]))return g;r=s[e],I.helper.isUndefined(i[e])||(o=i[e]),I.helper.isUndefined(l[e])||(t=l[e].width,a=l[e].height)}A=A.replace(/"/g,""").replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback);var c='<img src="'+(r=r.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'" alt="'+A+'"';return o&&(c+=' title="'+(o=o.replace(/"/g,""").replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"'),t&&a&&(c+=' width="'+(t="*"===t?"auto":t)+'"',c+=' height="'+(a="*"===a?"auto":a)+'"'),c+=" />"}return g=(g=C.converter._dispatch("images.before",g,A,C)).replace(/!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,e),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,function(g,A,C,I,r,t,a,n){return I=I.replace(/\s/g,""),e(g,A,C,I,r,t,0,n)}),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,e),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,e),g=g.replace(/!\[([^\[\]]+)]()()()()()/g,e),g=C.converter._dispatch("images.after",g,A,C)}),I.subParser("italicsAndBold",function(g,A,C){"use strict";function I(g,A,C){return A+g+C}return g=C.converter._dispatch("italicsAndBold.before",g,A,C),g=A.literalMidWordUnderscores?(g=(g=g.replace(/\b___(\S[\s\S]*)___\b/g,function(g,A){return I(A,"<strong><em>","</em></strong>")})).replace(/\b__(\S[\s\S]*)__\b/g,function(g,A){return I(A,"<strong>","</strong>")})).replace(/\b_(\S[\s\S]*?)_\b/g,function(g,A){return I(A,"<em>","</em>")}):(g=(g=g.replace(/___(\S[\s\S]*?)___/g,function(g,A){return/\S$/.test(A)?I(A,"<strong><em>","</em></strong>"):g})).replace(/__(\S[\s\S]*?)__/g,function(g,A){return/\S$/.test(A)?I(A,"<strong>","</strong>"):g})).replace(/_([^\s_][\s\S]*?)_/g,function(g,A){return/\S$/.test(A)?I(A,"<em>","</em>"):g}),g=A.literalMidWordAsterisks?(g=(g=g.replace(/([^*]|^)\B\*\*\*(\S[\s\S]+?)\*\*\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<strong><em>","</em></strong>")})).replace(/([^*]|^)\B\*\*(\S[\s\S]+?)\*\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<strong>","</strong>")})).replace(/([^*]|^)\B\*(\S[\s\S]+?)\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<em>","</em>")}):(g=(g=g.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,function(g,A){return/\S$/.test(A)?I(A,"<strong><em>","</em></strong>"):g})).replace(/\*\*(\S[\s\S]*?)\*\*/g,function(g,A){return/\S$/.test(A)?I(A,"<strong>","</strong>"):g})).replace(/\*([^\s*][\s\S]*?)\*/g,function(g,A){return/\S$/.test(A)?I(A,"<em>","</em>"):g}),g=C.converter._dispatch("italicsAndBold.after",g,A,C)}),I.subParser("lists",function(g,A,C){"use strict";function e(g,e){C.gListLevel++,g=g.replace(/\n{2,}$/,"\n");var r=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,t=/\n[ \t]*\n(?!¨0)/.test(g+="¨0");return A.disableForced4SpacesIndentedSublists&&(r=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),g=g.replace(r,function(g,e,r,a,n,o,s){s=s&&""!==s.trim();var i=I.subParser("outdent")(n,A,C),l="";return o&&A.tasklists&&(l=' class="task-list-item" style="list-style-type: none;"',i=i.replace(/^[ \t]*\[(x|X| )?]/m,function(){var g='<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';return s&&(g+=" checked"),g+=">"})),i=i.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g,function(g){return"¨A"+g}),e||i.search(/\n{2,}/)>-1?(i=I.subParser("githubCodeBlocks")(i,A,C),i=I.subParser("blockGamut")(i,A,C)):(i=(i=I.subParser("lists")(i,A,C)).replace(/\n$/,""),i=(i=I.subParser("hashHTMLBlocks")(i,A,C)).replace(/\n\n+/g,"\n\n"),i=t?I.subParser("paragraphs")(i,A,C):I.subParser("spanGamut")(i,A,C)),i=i.replace("¨A",""),i="<li"+l+">"+i+"</li>\n"}),g=g.replace(/¨0/g,""),C.gListLevel--,e&&(g=g.replace(/\s+$/,"")),g}function r(g,A){if("ol"===A){var C=g.match(/^ *(\d+)\./);if(C&&"1"!==C[1])return' start="'+C[1]+'"'}return""}function t(g,C,I){var t=A.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,a=A.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,n="ul"===C?t:a,o="";if(-1!==g.search(n))!function A(s){var i=s.search(n),l=r(g,C);-1!==i?(o+="\n\n<"+C+l+">\n"+e(s.slice(0,i),!!I)+"</"+C+">\n",n="ul"===(C="ul"===C?"ol":"ul")?t:a,A(s.slice(i))):o+="\n\n<"+C+l+">\n"+e(s,!!I)+"</"+C+">\n"}(g);else{var s=r(g,C);o="\n\n<"+C+s+">\n"+e(g,!!I)+"</"+C+">\n"}return o}return g=C.converter._dispatch("lists.before",g,A,C),g+="¨0",g=C.gListLevel?g.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(g,A,C){return t(A,C.search(/[*+-]/g)>-1?"ul":"ol",!0)}):g.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(g,A,C,I){return t(C,I.search(/[*+-]/g)>-1?"ul":"ol",!1)}),g=g.replace(/¨0/,""),g=C.converter._dispatch("lists.after",g,A,C)}),I.subParser("metadata",function(g,A,C){"use strict";function I(g){C.metadata.raw=g,(g=(g=g.replace(/&/g,"&").replace(/"/g,""")).replace(/\n {4}/g," ")).replace(/^([\S ]+): +([\s\S]+?)$/gm,function(g,A,I){return C.metadata.parsed[A]=I,""})}return A.metadata?(g=C.converter._dispatch("metadata.before",g,A,C),g=g.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/,function(g,A,C){return I(C),"¨M"}),g=g.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/,function(g,A,e){return A&&(C.metadata.format=A),I(e),"¨M"}),g=g.replace(/¨M/g,""),g=C.converter._dispatch("metadata.after",g,A,C)):g}),I.subParser("outdent",function(g,A,C){"use strict";return g=C.converter._dispatch("outdent.before",g,A,C),g=g.replace(/^(\t|[ ]{1,4})/gm,"¨0"),g=g.replace(/¨0/g,""),g=C.converter._dispatch("outdent.after",g,A,C)}),I.subParser("paragraphs",function(g,A,C){"use strict";for(var e=(g=(g=(g=C.converter._dispatch("paragraphs.before",g,A,C)).replace(/^\n+/g,"")).replace(/\n+$/g,"")).split(/\n{2,}/g),r=[],t=e.length,a=0;a<t;a++){var n=e[a];n.search(/¨(K|G)(\d+)\1/g)>=0?r.push(n):n.search(/\S/)>=0&&(n=(n=I.subParser("spanGamut")(n,A,C)).replace(/^([ \t]*)/g,"<p>"),n+="</p>",r.push(n))}for(t=r.length,a=0;a<t;a++){for(var o="",s=r[a],i=!1;/¨(K|G)(\d+)\1/.test(s);){var l=RegExp.$1,c=RegExp.$2;o=(o="K"===l?C.gHtmlBlocks[c]:i?I.subParser("encodeCode")(C.ghCodeBlocks[c].text,A,C):C.ghCodeBlocks[c].codeblock).replace(/\$/g,"$$$$"),s=s.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/,o),/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(s)&&(i=!0)}r[a]=s}return g=r.join("\n"),g=g.replace(/^\n+/g,""),g=g.replace(/\n+$/g,""),C.converter._dispatch("paragraphs.after",g,A,C)}),I.subParser("runExtension",function(g,A,C,I){"use strict";if(g.filter)A=g.filter(A,I.converter,C);else if(g.regex){var e=g.regex;e instanceof RegExp||(e=new RegExp(e,"g")),A=A.replace(e,g.replace)}return A}),I.subParser("spanGamut",function(g,A,C){"use strict";return g=C.converter._dispatch("spanGamut.before",g,A,C),g=I.subParser("codeSpans")(g,A,C),g=I.subParser("escapeSpecialCharsWithinTagAttributes")(g,A,C),g=I.subParser("encodeBackslashEscapes")(g,A,C),g=I.subParser("images")(g,A,C),g=I.subParser("anchors")(g,A,C),g=I.subParser("autoLinks")(g,A,C),g=I.subParser("simplifiedAutoLinks")(g,A,C),g=I.subParser("emoji")(g,A,C),g=I.subParser("underline")(g,A,C),g=I.subParser("italicsAndBold")(g,A,C),g=I.subParser("strikethrough")(g,A,C),g=I.subParser("ellipsis")(g,A,C),g=I.subParser("hashHTMLSpans")(g,A,C),g=I.subParser("encodeAmpsAndAngles")(g,A,C),A.simpleLineBreaks?/\n\n¨K/.test(g)||(g=g.replace(/\n+/g,"<br />\n")):g=g.replace(/ +\n/g,"<br />\n"),g=C.converter._dispatch("spanGamut.after",g,A,C)}),I.subParser("strikethrough",function(g,A,C){"use strict";return A.strikethrough&&(g=(g=C.converter._dispatch("strikethrough.before",g,A,C)).replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,function(g,e){return function(g){return A.simplifiedAutoLink&&(g=I.subParser("simplifiedAutoLinks")(g,A,C)),"<del>"+g+"</del>"}(e)}),g=C.converter._dispatch("strikethrough.after",g,A,C)),g}),I.subParser("stripLinkDefinitions",function(g,A,C){"use strict";var e=function(g,e,r,t,a,n,o){return e=e.toLowerCase(),r.match(/^data:.+?\/.+?;base64,/)?C.gUrls[e]=r.replace(/\s/g,""):C.gUrls[e]=I.subParser("encodeAmpsAndAngles")(r,A,C),n?n+o:(o&&(C.gTitles[e]=o.replace(/"|'/g,""")),A.parseImgDimensions&&t&&a&&(C.gDimensions[e]={width:t,height:a}),"")};return g=(g+="¨0").replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm,e),g=g.replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,e),g=g.replace(/¨0/,"")}),I.subParser("tables",function(g,A,C){"use strict";function e(g){return/^:[ \t]*--*$/.test(g)?' style="text-align:left;"':/^--*[ \t]*:[ \t]*$/.test(g)?' style="text-align:right;"':/^:[ \t]*--*[ \t]*:$/.test(g)?' style="text-align:center;"':""}function r(g,e){var r="";return g=g.trim(),(A.tablesHeaderId||A.tableHeaderId)&&(r=' id="'+g.replace(/ /g,"_").toLowerCase()+'"'),g=I.subParser("spanGamut")(g,A,C),"<th"+r+e+">"+g+"</th>\n"}function t(g,e){return"<td"+e+">"+I.subParser("spanGamut")(g,A,C)+"</td>\n"}function a(g){var a,n=g.split("\n");for(a=0;a<n.length;++a)/^ {0,3}\|/.test(n[a])&&(n[a]=n[a].replace(/^ {0,3}\|/,"")),/\|[ \t]*$/.test(n[a])&&(n[a]=n[a].replace(/\|[ \t]*$/,"")),n[a]=I.subParser("codeSpans")(n[a],A,C);var o=n[0].split("|").map(function(g){return g.trim()}),s=n[1].split("|").map(function(g){return g.trim()}),i=[],l=[],c=[],u=[];for(n.shift(),n.shift(),a=0;a<n.length;++a)""!==n[a].trim()&&i.push(n[a].split("|").map(function(g){return g.trim()}));if(o.length<s.length)return g;for(a=0;a<s.length;++a)c.push(e(s[a]));for(a=0;a<o.length;++a)I.helper.isUndefined(c[a])&&(c[a]=""),l.push(r(o[a],c[a]));for(a=0;a<i.length;++a){for(var d=[],p=0;p<l.length;++p)I.helper.isUndefined(i[a][p]),d.push(t(i[a][p],c[p]));u.push(d)}return function(g,A){for(var C="<table>\n<thead>\n<tr>\n",I=g.length,e=0;e<I;++e)C+=g[e];for(C+="</tr>\n</thead>\n<tbody>\n",e=0;e<A.length;++e){C+="<tr>\n";for(var r=0;r<I;++r)C+=A[e][r];C+="</tr>\n"}return C+="</tbody>\n</table>\n"}(l,u)}if(!A.tables)return g;return g=C.converter._dispatch("tables.before",g,A,C),g=g.replace(/\\(\|)/g,I.helper.escapeCharactersCallback),g=g.replace(/^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,a),g=g.replace(/^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm,a),g=C.converter._dispatch("tables.after",g,A,C)}),I.subParser("underline",function(g,A,C){"use strict";return A.underline?(g=C.converter._dispatch("underline.before",g,A,C),g=A.literalMidWordUnderscores?g.replace(/\b_?__(\S[\s\S]*)___?\b/g,function(g,A){return"<u>"+A+"</u>"}):g.replace(/_?__(\S[\s\S]*?)___?/g,function(g,A){return/\S$/.test(A)?"<u>"+A+"</u>":g}),g=g.replace(/(_)/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("underline.after",g,A,C)):g}),I.subParser("unescapeSpecialChars",function(g,A,C){"use strict";return g=C.converter._dispatch("unescapeSpecialChars.before",g,A,C),g=g.replace(/¨E(\d+)E/g,function(g,A){var C=parseInt(A);return String.fromCharCode(C)}),g=C.converter._dispatch("unescapeSpecialChars.after",g,A,C)});"function"==typeof define&&define.amd?define(function(){"use strict";return I}):"undefined"!=typeof module&&module.exports?module.exports=I:this.showdown=I}).call(this); -//# sourceMappingURL=showdown.min.js.map diff --git a/www/dl.sbr.pm/.fancyindex/styles.css b/www/dl.sbr.pm/.fancyindex/styles.css @@ -1,196 +0,0 @@ -/* styles.css - * Better styling for of Nginx FancyIndex page - * © 2015-17, Lilian Besson (Naereen) and contributors, - * open-sourced under the MIT License, https://lbesson.mit-license.org/ - * hosted on GitHub, https://GitHub.com/Naereen/Nginx-Fancyindex-Theme - */ - -* { - font-family: 'Verdana', sans-serif; - margin: 0; - padding: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - color: #61666c; - font-weight: 300; - font-size: 1em; - line-height: 2em; -} - -body { - margin: 0 auto; - padding-top: 20px; - max-width: 800px; -} - -thead { - font-weight: 200; - font-size: 1.2em; -} - -h1 { - font-weight: 200; - text-align: center; - font-size: 1.4em; - line-height: 3em; -} - -a { - color: #5f5f5f; - text-decoration: none; -} - a:hover { - color: #000; - } - a.clear, a.clear:link, a.clear:visited { - color: #666; - padding: 2px 0; - font-weight: 400; - font-size: 14px; - margin: 0 0 0 20px; - line-height: 14px; - display: inline-block; - border-bottom: transparent 1px solid; - vertical-align: -10px; - -webkit-transition: all 300ms ease-in; - -moz-transition: all 300ms ease-in; - -ms-transition: all 300ms ease-in; - -o-transition: all 300ms ease-in; - transition: all 300ms ease-in; - } - -input { - margin: 0 auto; - font-size: 100%; - vertical-align: middle; - *overflow: visible; - line-height: normal; - font-family: 'Open Sans', sans-serif; - font-size: 12px; - font-weight: 300; - line-height: 18px; - color: #555; - display: inline-block; - height: 20px; - padding: 4px 32px 4px 6px; - margin-bottom: 9px; - font-size: 14px; - line-height: 20px; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - width: 196px; - background-color: #fff; - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -webkit-transition: border linear .2s,box-shadow linear .2s; - -moz-transition: border linear .2s,box-shadow linear .2s; - -o-transition: border linear .2s,box-shadow linear .2s; - transition: border linear .2s,box-shadow linear .2s; -} - input:focus { - outline: 0; - border-color: rgba(0,0,0,0.8); - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - } - input::-moz-focus-inner { - padding: 0; - border: 0; - } - -#search { - display: block; - margin-left: auto; - margin-right: auto; - width: 250px; - margin-top: 20px; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; - -webkit-transition: all 300ms ease-in; - -moz-transition: all 300ms ease-in; - -ms-transition: all 300ms ease-in; - -o-transition: all 300ms ease-in; - transition: all 300ms ease-in; -} - -table { - border-collapse: collapse; - font-size: 0.9em; - max-width: 100%; - margin: 20px auto 0; -} - -tr { - outline: 0; - border: 0; -} - tr:hover td { - background: #f6f6f6; - } - tr td:first-of-type { - padding-left: 10px; - padding-right: 10px; - } - tr.parent a { - color: #9099A3; - } - -th { - - text-align: left; - font-size: .75em; - padding-right: 20px; -} - th + th { - width: 25%; - } - th + th + th + th { - width: 5%; - } - -td { - padding: 5px 0; - outline: 0; - border: 0; - border-bottom: 1px solid #edf1f5; - vertical-align: middle; - text-align: left; - -webkit-transition: background 300ms ease-in; - -moz-transition: background 300ms ease-in; - -ms-transition: background 300ms ease-in; - -o-transition: background 300ms ease-in; - transition: background 300ms ease-in; -} - td:last-child,th:last-child { - text-align: right; - padding-right: 0; - } - td a { - display: block; - } - -.parent a:hover { - color: #2a2a2a; -} - -footer { - font-size:12px; - text-align:center; -} -footer a { - text-decoration: underline; - color:#990012; -} - -img { max-width: 100%; } diff --git a/www/vincent.demeester.fr/.fancyindex/HEADER.md b/www/vincent.demeester.fr/.fancyindex/HEADER.md @@ -1,4 +0,0 @@ -# Test of a HEADER.md file -## Test of a HEADER.md file -### Test of a HEADER.md file -#### Test of a HEADER.md file diff --git a/www/vincent.demeester.fr/.fancyindex/addNginxFancyIndexForm.js b/www/vincent.demeester.fr/.fancyindex/addNginxFancyIndexForm.js @@ -1,33 +0,0 @@ -// addNginxFancyIndexForm.js -// Add a small form to filter through the output of Nginx FancyIndex page -// © 2017, Lilian Besson (Naereen) and contributors, -// open-sourced under the MIT License, https://lbesson.mit-license.org/ -// hosted on GitHub, https://GitHub.com/Naereen/Nginx-Fancyindex-Theme -var form = document.createElement('form'); -var input = document.createElement('input'); - -input.name = 'filter'; -input.id = 'search'; -input.placeholder = 'Type to search...'; - -form.appendChild(input); - -document.querySelector('h1').after(form); - -var listItems = [].slice.call(document.querySelectorAll('#list tbody tr')); - -input.addEventListener('keyup', function () { - var i, - // Word sequence _matching_ to input. All, except last, words must be _complete_. - e = "(^|.*[^\\pL])" + this.value.trim().split(/\s+/).join("([^\\pL]|[^\\pL].*[^\\pL])") + ".*$", - n = RegExp(e, "i"); - listItems.forEach(function(item) { - item.removeAttribute('hidden'); - }); - listItems.filter(function(item) { - i = item.querySelector('td').textContent.replace(/\s+/g, " "); - return !n.test(i); - }).forEach(function(item) { - item.hidden = true; - }); -}); diff --git a/www/vincent.demeester.fr/.fancyindex/footer.html b/www/vincent.demeester.fr/.fancyindex/footer.html @@ -1,40 +0,0 @@ -<section id="raw_include_README_md"></section> -</main> -<footer> - <span class='copyright'> - Content and design by Vincent Demeester - (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) - </span> -</footer> -<script src="https://unpkg.com/xregexp/xregexp-all.js"></script> -<script type="text/javascript" src="/.fancyindex/addNginxFancyIndexForm.js"></script> -<script type="text/javascript" src="/.fancyindex/showdown.min.js"></script> -<script type="text/javascript" defer> - var converter = new showdown.Converter(); - $( "#raw_include_HEADER_md" ).load( "HEADER.md", function (){ - var elem = document.querySelector("#raw_include_HEADER_md"); - // strip leading whitespace so it isn't evaluated as code - var text = elem.innerHTML; - // console.log("text =", text); - text = text.replace(/\n[ ]*/g, '\n'); - // console.log("text =", text); - var html = converter.makeHtml(text); - // console.log("html =", html); - // here, have some HTML - elem.innerHTML = html; - }); - $( "#raw_include_README_md" ).load( "README.md", function (){ - var elem = document.querySelector("#raw_include_README_md"); - // strip leading whitespace so it isn't evaluated as code - var text = elem.innerHTML; - // console.log("text =", text); - text = text.replace(/\n[ ]*/g, '\n'); - // console.log("text =", text); - var html = converter.makeHtml(text); - // console.log("html =", html); - // here, have some HTML - elem.innerHTML = html; - }); -</script> -</body> -</html> diff --git a/www/vincent.demeester.fr/.fancyindex/header.html b/www/vincent.demeester.fr/.fancyindex/header.html @@ -1,25 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="IE=edge"> - <title>Directory</title> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="https://vincent.demeester.fr/css/new.css"> - <script type="text/javascript" src="/.fancyindex/jquery.min.js"></script> - </head> - <body> - <header id="top" class="status"> - <nav> - <img src="https://vincent.demeester.fr/images/favicon.ico" id="sitelogo"/> <a href='https://vincent.demeester.fr/'>home</a> / - <a href='https://vincent.demeester.fr/posts/'>posts</a> (<a href='https://vincent.demeester.fr/index.xml'>rss</a>) / - <a href='https://vincent.demeester.fr/articles/'>articles</a> / - <a href='https://vincent.demeester.fr/configurations/'>configurations</a> / - <a href='https://dl.sbr.pm/'>files</a> / - <a href='https://vincent.demeester.fr/about/'>about</a></li> - </nav> - </header> - <main id="content"> - <header id="raw_include_HEADER_md"> - </header> -<h1>Directory: diff --git a/www/vincent.demeester.fr/.fancyindex/jquery.min.js b/www/vincent.demeester.fr/.fancyindex/jquery.min.js @@ -1,5 +0,0 @@ -/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -/* Used on Lilian Besson's web pages ~ 2011-2014 */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length; -while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?o.queue(this[0],a):void 0===b?this:this.each(function(){var c=o.queue(this,a,b);o._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&o.dequeue(this,a)})},dequeue:function(a){return this.each(function(){o.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=o.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===o.css(a,"display")||!o.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=m.createDocumentFragment(),b=a.appendChild(m.createElement("div"));b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||m,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[o.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new o.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=m),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&o.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return o.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=o.extend(new o.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?o.event.trigger(e,null,b):o.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},o.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},o.Event=function(a,b){return this instanceof o.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.getPreventDefault&&a.getPreventDefault()?Z:$):this.type=a,b&&o.extend(this,b),this.timeStamp=a&&a.timeStamp||o.now(),void(this[o.expando]=!0)):new o.Event(a,b)},o.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z,this.stopPropagation()}},o.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){o.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!o.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.focusinBubbles||o.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){o.event.simulate(b,a.target,o.event.fix(a),!0)};o.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),o.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return o().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=o.guid++)),this.each(function(){o.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,o(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){o.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){o.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?o.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||o.contains(a.ownerDocument,a)||(g=o.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",e=m.documentElement,f=m.createElement("div"),g=m.createElement("div");g.style.backgroundClip="content-box",g.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===g.style.backgroundClip,f.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",f.appendChild(g);function h(){g.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",e.appendChild(f);var d=a.getComputedStyle(g,null);b="1%"!==d.top,c="4px"===d.width,e.removeChild(f)}a.getComputedStyle&&o.extend(l,{pixelPosition:function(){return h(),b},boxSizingReliable:function(){return null==c&&h(),c},reliableMarginRight:function(){var b,c=g.appendChild(m.createElement("div"));return c.style.cssText=g.style.cssText=d,c.style.marginRight=c.style.width="0",g.style.width="1px",e.appendChild(f),b=!parseFloat(a.getComputedStyle(c,null).marginRight),e.removeChild(f),g.innerHTML="",b}})}(),o.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:0,fontWeight:400},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=o.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=o.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=o.css(a,"border"+R[f]+"Width",!0,e))):(g+=o.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=o.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===o.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):f[g]||(e=S(d),(c&&"none"!==c||!e)&&L.set(d,"olddisplay",e?c:o.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}o.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=o.camelCase(b),i=a.style;return b=o.cssProps[h]||(o.cssProps[h]=Fb(i,h)),g=o.cssHooks[b]||o.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(o.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||o.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]="",i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=o.camelCase(b);return b=o.cssProps[h]||(o.cssProps[h]=Fb(a.style,h)),g=o.cssHooks[b]||o.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||o.isNumeric(f)?f||0:e):e}}),o.each(["height","width"],function(a,b){o.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&zb.test(o.css(a,"display"))?o.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===o.css(a,"boxSizing",!1,e),e):0)}}}),o.cssHooks.marginRight=yb(l.reliableMarginRight,function(a,b){return b?o.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),o.each({margin:"",padding:"",border:"Width"},function(a,b){o.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(o.cssHooks[a+b].set=Gb)}),o.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(o.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=o.css(a,b[g],!1,d);return f}return void 0!==c?o.style(a,b,c):o.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?o(this).show():o(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}o.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(o.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?o.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=o.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){o.fx.step[a.prop]?o.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[o.cssProps[a.prop]]||o.cssHooks[a.prop])?o.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},o.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},o.fx=Kb.prototype.init,o.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(o.cssNumber[a]?"":"px"),g=(o.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(o.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,o.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=o.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&S(a),p=L.get(a,"fxshow");c.queue||(h=o._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,k.always(function(){k.always(function(){h.unqueued--,o.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],j=o.css(a,"display"),"none"===j&&(j=tb(a.nodeName)),"inline"===j&&"none"===o.css(a,"float")&&(m.display="inline-block")),c.overflow&&(m.overflow="hidden",k.always(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(n?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;n=!0}l[d]=p&&p[d]||o.style(a,d)}if(!o.isEmptyObject(l)){p?"hidden"in p&&(n=p.hidden):p=L.access(a,"fxshow",{}),f&&(p.hidden=!n),n?o(a).show():k.done(function(){o(a).hide()}),k.done(function(){var b;L.remove(a,"fxshow");for(b in l)o.style(a,b,l[b])});for(d in l)g=Ub(n?p[d]:0,d,k),d in p||(p[d]=g.start,n&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=o.camelCase(c),e=b[d],f=a[c],o.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=o.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=o.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:o.extend({},b),opts:o.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=o.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return o.map(k,Ub,j),o.isFunction(j.opts.start)&&j.opts.start.call(a,j),o.fx.timer(o.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}o.Animation=o.extend(Xb,{tweener:function(a,b){o.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),o.speed=function(a,b,c){var d=a&&"object"==typeof a?o.extend({},a):{complete:c||!c&&b||o.isFunction(a)&&a,duration:a,easing:c&&b||b&&!o.isFunction(b)&&b};return d.duration=o.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in o.fx.speeds?o.fx.speeds[d.duration]:o.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){o.isFunction(d.old)&&d.old.call(this),d.queue&&o.dequeue(this,d.queue)},d},o.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=o.isEmptyObject(a),f=o.speed(b,c,d),g=function(){var b=Xb(this,o.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=o.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&o.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=o.timers,g=d?d.length:0;for(c.finish=!0,o.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),o.each(["toggle","show","hide"],function(a,b){var c=o.fn[b];o.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),o.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){o.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),o.timers=[],o.fx.tick=function(){var a,b=0,c=o.timers;for(Lb=o.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||o.fx.stop(),Lb=void 0},o.fx.timer=function(a){o.timers.push(a),a()?o.fx.start():o.timers.pop()},o.fx.interval=13,o.fx.start=function(){Mb||(Mb=setInterval(o.fx.tick,o.fx.interval))},o.fx.stop=function(){clearInterval(Mb),Mb=null},o.fx.speeds={slow:600,fast:200,_default:400},o.fn.delay=function(a,b){return a=o.fx?o.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=m.createElement("input"),b=m.createElement("select"),c=b.appendChild(m.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=m.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var Yb,Zb,$b=o.expr.attrHandle;o.fn.extend({attr:function(a,b){return J(this,o.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){o.removeAttr(this,a)})}}),o.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?o.prop(a,b,c):(1===f&&o.isXMLDoc(a)||(b=b.toLowerCase(),d=o.attrHooks[b]||(o.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=o.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void o.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=o.propFix[c]||c,o.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&o.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?o.removeAttr(a,c):a.setAttribute(c,c),c}},o.each(o.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||o.find.attr;$b[b]=function(a,b,d){var e,f; -return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;o.fn.extend({prop:function(a,b){return J(this,o.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[o.propFix[a]||a]})}}),o.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!o.isXMLDoc(a),f&&(b=o.propFix[b]||b,e=o.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),l.optSelected||(o.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),o.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){o.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;o.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=o.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?o.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(o.isFunction(a)?function(c){o(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=o(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;o.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=o.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,o(this).val()):a,null==e?e="":"number"==typeof e?e+="":o.isArray(e)&&(e=o.map(e,function(a){return null==a?"":a+""})),b=o.valHooks[this.type]||o.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=o.valHooks[e.type]||o.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),o.extend({valHooks:{select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&o.nodeName(c.parentNode,"optgroup"))){if(b=o(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=o.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=o.inArray(o(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),o.each(["radio","checkbox"],function(){o.valHooks[this]={set:function(a,b){return o.isArray(b)?a.checked=o.inArray(o(a).val(),b)>=0:void 0}},l.checkOn||(o.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),o.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){o.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),o.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=o.now(),dc=/\?/;o.parseJSON=function(a){return JSON.parse(a+"")},o.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&o.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=m.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(o.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,o.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=o.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&o.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}o.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":o.parseJSON,"text xml":o.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,o.ajaxSettings),b):tc(o.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=o.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?o(l):o.event,n=o.Deferred(),p=o.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(n.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=o.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=o.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===o.active++&&o.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(o.lastModified[d]&&v.setRequestHeader("If-Modified-Since",o.lastModified[d]),o.etag[d]&&v.setRequestHeader("If-None-Match",o.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(o.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(o.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?n.resolveWith(l,[r,x,v]):n.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--o.active||o.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return o.get(a,b,c,"json")},getScript:function(a,b){return o.get(a,void 0,b,"script")}}),o.each(["get","post"],function(a,b){o[b]=function(a,c,d,e){return o.isFunction(c)&&(e=e||d,d=c,c=void 0),o.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),o.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){o.fn[b]=function(a){return this.on(b,a)}}),o._evalUrl=function(a){return o.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},o.fn.extend({wrapAll:function(a){var b;return o.isFunction(a)?this.each(function(b){o(this).wrapAll(a.call(this,b))}):(this[0]&&(b=o(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(o.isFunction(a)?function(b){o(this).wrapInner(a.call(this,b))}:function(){var b=o(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=o.isFunction(a);return this.each(function(c){o(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){o.nodeName(this,"body")||o(this).replaceWith(this.childNodes)}).end()}}),o.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},o.expr.filters.visible=function(a){return!o.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(o.isArray(b))o.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==o.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}o.param=function(a,b){var c,d=[],e=function(a,b){b=o.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=o.ajaxSettings&&o.ajaxSettings.traditional),o.isArray(a)||a.jquery&&!o.isPlainObject(a))o.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},o.fn.extend({serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=o.prop(this,"elements");return a?o.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!o(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=o(this).val();return null==c?null:o.isArray(c)?o.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),o.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=o.ajaxSettings.xhr();a.ActiveXObject&&o(a).on("unload",function(){for(var a in Dc)Dc[a]()}),l.cors=!!Fc&&"withCredentials"in Fc,l.ajax=Fc=!!Fc,o.ajaxTransport(function(a){var b;return l.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort"),f.send(a.hasContent&&a.data||null)},abort:function(){b&&b()}}:void 0}),o.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return o.globalEval(a),a}}}),o.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),o.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=o("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),m.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;o.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||o.expando+"_"+cc++;return this[a]=!0,a}}),o.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=o.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||o.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&o.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),o.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||m;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=o.buildFragment([a],b,e),e&&e.length&&o(e).remove(),o.merge([],d.childNodes))};var Ic=o.fn.load;o.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h),a=a.slice(0,h)),o.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&o.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?o("<div>").append(o.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},o.expr.filters.animated=function(a){return o.grep(o.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return o.isWindow(a)?a:9===a.nodeType&&a.defaultView}o.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=o.css(a,"position"),l=o(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=o.css(a,"top"),i=o.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),o.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},o.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){o.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,o.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===o.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),o.nodeName(a[0],"html")||(d=a.offset()),d.top+=o.css(a[0],"borderTopWidth",!0),d.left+=o.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-o.css(c,"marginTop",!0),left:b.left-d.left-o.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!o.nodeName(a,"html")&&"static"===o.css(a,"position"))a=a.offsetParent;return a||Jc})}}),o.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;o.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),o.each(["top","left"],function(a,b){o.cssHooks[b]=yb(l.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?o(a).position()[b]+"px":c):void 0})}),o.each({Height:"height",Width:"width"},function(a,b){o.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){o.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return o.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?o.css(b,c,g):o.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),o.fn.size=function(){return this.length},o.fn.andSelf=o.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return o});var Lc=a.jQuery,Mc=a.$;return o.noConflict=function(b){return a.$===o&&(a.$=Mc),b&&a.jQuery===o&&(a.jQuery=Lc),o},typeof b===U&&(a.jQuery=a.$=o),o}); diff --git a/www/vincent.demeester.fr/.fancyindex/new.css b/www/vincent.demeester.fr/.fancyindex/new.css @@ -1,605 +0,0 @@ -:root { - ---font-sans: 'Ubuntu Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - ---font-mono: 'Ubuntu Mono', Consolas, monaco, 'Liberation Mono', 'Courier New', Courier, monospace; - ---tx-1: #000000; - ---tx-2: #1A1A1A; - ---tx-3: #666666; - ---tx-4: #999999; - ---bg-1: #FFFFFF; - ---bg-2: #F6F8FA; - ---bg-3: #E5E7EB; - ---lk-1: #0070F3; - ---lk-2: #0366D6; - ---lk-tx: #FFFFFF; - ---ac-1: #79FFE1; - ---ac-tx: #0C4047; - - --content-box-padding: 0.5rem; - --aside-width: 12.5rem; -} - -@media (prefers-color-scheme: dark) { - :root { - ---tx-1: #ffffff; - ---tx-2: #eeeeee; - ---tx-3: #cccccc; - ---tx-4: #aaaaaa; - ---bg-1: #000000; - ---bg-2: #111111; - ---bg-3: #222222; - ---lk-1: #3291FF; - ---lk-2: #0070F3; - ---lk-tx: #FFFFFF; - ---ac-1: #7928CA; - ---ac-tx: #FFFFFF; - } -} - -* { - /* Reset margins and padding */ - margin: 0; - padding: 0; -} - -address, -area, -article, -aside, -audio, -blockquote, -datalist, -details, -dl, -fieldset, -figure, -form, -input, -iframe, -img, -meter, -nav, -ol, -optgroup, -option, -output, -p, -pre, -progress, -ruby, -section, -table, -textarea, -ul, -video { - /* Margins for most elements */ - margin-bottom: 1rem; -} - -html,input,select,button { - /* Set body font family and some finicky elements */ - font-family: var(---font-sans); -} - -body { - /* Center body in page */ - margin: 0 auto; - max-width: 70rem; - padding: 2rem; - border-radius: 6px; - overflow-x: hidden; - word-break: break-word; - overflow-wrap: break-word; - background: var(---bg-1); - - /* Main body text */ - color: var(---tx-2); - font-size: 1.03rem; - line-height: 1.5; -} - -::selection { - /* Set background color for selected text */ - background: var(---ac-1); - color: var(---ac-tx); -} - -h1,h2,h3,h4,h5,h6 { - line-height: 1; - color: var(---tx-1); - padding-top: .875rem; -} - -h1, -h2, -h3 { - color: var(---tx-1); - padding-bottom: 2px; - margin-bottom: 8px; - border-bottom: 1px solid var(---bg-2); -} - -h4, -h5, -h6 { - margin-bottom: .3rem; -} - -h1 { - font-size: 2.25rem; -} - -h2 { - font-size: 1.85rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: 1rem; -} - -h6 { - font-size: .875rem; -} - -a { - color: var(---lk-1); -} - -a:hover { - color: var(---lk-2); -} - -abbr:hover { - /* Set the '?' cursor while hovering an abbreviation */ - cursor: help; -} - -blockquote { - padding: 1.5rem; - background: var(---bg-2); - border-left: 5px solid var(---bg-3); -} - -abbr { - cursor: help; -} - -blockquote *:last-child { - padding-bottom: 0; - margin-bottom: 0; -} - -header { - background: var(---bg-2); - border-bottom: 1px solid var(---bg-3); - padding: 1rem 1.5rem; - - /* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */ - - margin: -2rem calc(0px - (50vw - 50%)) 2rem; - - /* Shorthand for: - - margin-top: -2rem; - margin-bottom: 2rem; - - margin-left: calc(0px - (50vw - 50%)); - margin-right: calc(0px - (50vw - 50%)); */ - - padding-left: calc(50vw - 50%); - padding-right: calc(50vw - 50%); -} - -header img#sitelogo { - margin-bottom: 0; - margin-right: 1em; -} - -header h1, -header h2, -header h3 { - padding-bottom: 0; - border-bottom: 0; -} - -header > *:first-child { - margin-top: 0; - padding-top: 0; -} - -header > *:last-child { - margin-bottom: 0; -} - -main header { - background: var(---bg-3); -} - -a button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - font-size: 1rem; - display: inline-block; - padding: 6px 12px; - text-align: center; - text-decoration: none; - white-space: nowrap; - background: var(---lk-1); - color: var(---lk-tx); - border: 0; - border-radius: 4px; - box-sizing: border-box; - cursor: pointer; - color: var(---lk-tx); -} - -a button[disabled], -button[disabled], -input[type="submit"][disabled], -input[type="reset"][disabled], -input[type="button"][disabled] { - cursor: default; - opacity: .5; - - /* Set the [X] cursor while hovering a disabled link */ - cursor: not-allowed; -} - -.button:focus, -.button:hover, -button:focus, -button:hover, -input[type="submit"]:focus, -input[type="submit"]:hover, -input[type="reset"]:focus, -input[type="reset"]:hover, -input[type="button"]:focus, -input[type="button"]:hover { - background: var(---lk-2); -} - -code, -pre, -kbd, -samp { - /* Set the font family for monospaced elements */ - font-family: var(---font-mono); -} - -code, -samp, -kbd, -pre { - /* The main preformatted style. This is changed slightly across different cases. */ - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - padding: 3px 6px; -} - -kbd { - /* Makes the kbd element look like a keyboard key */ - border-bottom: 3px solid var(---bg-3); -} - -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; -} - -pre.src { - position: relative; -} -pre.src:before { - /*display: none;*/ - position: absolute; - background-color: var(---bg-3); - /*color: #f3f4f4;*/ - top: 0; - right: 0; - padding: 0.2rem 0.5rem; -} - -pre code { - /* When <code> is in a <pre>, reset it's formatting to blend in */ - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -code pre { - /* When <pre> is in a <code>, reset it's formatting to blend in */ - display: inline; - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -details { - /* Make the <details> look more "clickable" */ - padding: .6rem 1rem; - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -summary { - /* Makes the <summary> look more like a "clickable" link with the pointer cursor */ - cursor: pointer; - font-weight: bold; -} - -details[open] { - /* Adjust the <details> padding while open */ - padding-bottom: .75rem; -} - -details[open] summary { - /* Adjust the <details> padding while open */ - margin-bottom: 6px; -} - -details[open]>*:last-child { - /* Resets the bottom margin of the last element in the <details> while <details> is opened. This prevents double margins/paddings. */ - margin-bottom: 0; -} - -dt { - font-weight: bold; -} - -dd::before { - /* Add an arrow to data table definitions */ - content: '→ '; -} - -hr { - /* Reset the border of the <hr> separator, then set a better line */ - border: 0; - border-bottom: 1px solid var(---bg-3); - margin: 1rem auto; -} - -fieldset { - margin-top: 1rem; - padding: 2rem; - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -legend { - padding: auto .5rem; -} - -table { - /* border-collapse sets the table's elements to share borders, rather than floating as separate "boxes". */ - border-collapse: collapse; - width: 100% -} - -td, -th { - border: 1px solid var(---bg-3); - text-align: left; - padding: .5rem; -} - -th { - background: var(---bg-2); -} - -tr:nth-child(even) { - /* Set every other cell slightly darker. Improves readability. */ - background: var(---bg-2); -} - -table caption { - font-weight: bold; - margin-bottom: .5rem; -} - -textarea { - /* Don't let the <textarea> extend off the screen naturally or when dragged by the user */ - max-width: 100%; -} - -ol, -ul { - /* Replace the browser default padding */ - padding-left: 2rem; -} - -li { - margin-top: .4rem; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -mark { - padding: 3px 6px; - background: var(---ac-1); - color: var(---ac-tx); -} - -textarea, -select, -input { - padding: 6px 12px; - margin-bottom: .5rem; - background: var(---bg-2); - color: var(---tx-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; -} - -img { - max-width: 100%; -} - -aside { - --aside-offset: 1rem; - --aside-offset-lineheight: 1.5rem; - background-color: var(---bg-2); - padding: calc(var(--content-box-padding) * 0.5) calc(var(--content-box-padding) * 2); - padding-top: 1em; - margin-bottom: 0em; - float: right; - width: var(--aside-width); - font-size: 0.9rem; - line-height: 1.25rem; - border: 1px solid var(--bg-3); -} - -figure figcaption { - text-align: center; - color: var(---tx-2); - font-style: italic; - margin: 0 2rem; -} - -footer { - text-align: center; - color: var(---tx-4); -} - -footer a { - color: var(---tx-3); -} - -section img { - display: block; - margin-left: auto; - margin-right: auto; -} - -section img.shadow { - box-shadow: 0 28px 50px rgba(0,0,0,0.16); -} - -div.drawer:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 4.4rem; - width: 1px; - background-color: #555; -} - -div.drawer { - display: flex; - padding: 0; - margin: 1rem; - padding-top: 1rem; - position: relative; - color: #555; -} - -div.drawer h6 { - box-sizing: border-box; - font-style: italic; - flex: 0 0 5rem; - margin:0; - padding:0; - align-self: center; - text-align: right; - padding-right: 1.2rem; -} - -div.drawer.info:before { - background-color: #00529B; -} -div.drawer.info { - color: #00529B; -} - -div.drawer.note:before { - background-color: #9F6000; -} -div.drawer.note { - color: #9F6000; -} -div.drawer.tip:before { - background-color: #4F8A10; -} -div.drawer.tip { - color: #4F8A10; -} -div.drawer.warning:before { - background-color: #D8000C; -} -div.drawer.warning { - color: #D8000C; -} -div.drawer.results:before { - background-color: black; -} -div.drawer.results { - font-family:monospace,monospace; - font-family: var(---font-mono); - color: black; - width: 100% !important; -} -div.drawer.results p { - display: block; - unicode-bidi: embed; - white-space: pre; - margin-top: 0; -} -div.drawer.results pre { - background-color: inherit; - border: 0; -} -div.drawer.results pre.src:before { - background-color: #eee; - color: #555; -} - -.tag { - font-family:var(---font-mono); - font-size: 1rem; -} -.tag span { - padding:.3em; - float:right; - margin-right:.5em; - border:1px solid #bbb; - border-radius:3px; - background-clip:padding-box; - color:#333; - background-color:#eee; - line-height:1rem; -} - -.todo { - font-family: monospace; color: red; -} -.done { - font-family: monospace; color: green; -} -.priority { font-family: monospace; color: orange; } -.timestamp { color: #bebebe; } -.timestamp-kwd { color: #5f9ea0; } diff --git a/www/vincent.demeester.fr/.fancyindex/showdown.min.js b/www/vincent.demeester.fr/.fancyindex/showdown.min.js @@ -1,3 +0,0 @@ -/*! showdown v 1.8.6 - 22-12-2017 */ -(function(){function g(g){"use strict";var A={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",type:"string"},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',type:"boolean"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},rawHeaderId:{defaultValue:!1,describe:"Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,description:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,description:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,description:"Parses simple line breaks as <br> (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,description:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,description:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",description:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,description:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,description:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,description:"Support for HTML Tag escaping. ex: <div>foo</div>",type:"boolean"},emoji:{defaultValue:!1,description:"Enable emoji support. Ex: `this is a :smile: emoji`",type:"boolean"},underline:{defaultValue:!1,description:"Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`",type:"boolean"},completeHTMLDocument:{defaultValue:!1,description:"Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags",type:"boolean"},metadata:{defaultValue:!1,description:"Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).",type:"boolean"},splitAdjacentBlockquotes:{defaultValue:!1,description:"Split adjacent blockquote blocks",type:"boolean"}};if(!1===g)return JSON.parse(JSON.stringify(A));var C={};for(var I in A)A.hasOwnProperty(I)&&(C[I]=A[I].defaultValue);return C}function A(g,A){"use strict";var C=A?"Error in "+A+" extension->":"Error in unnamed extension",e={valid:!0,error:""};I.helper.isArray(g)||(g=[g]);for(var r=0;r<g.length;++r){var t=C+" sub-extension "+r+": ",a=g[r];if("object"!=typeof a)return e.valid=!1,e.error=t+"must be an object, but "+typeof a+" given",e;if(!I.helper.isString(a.type))return e.valid=!1,e.error=t+'property "type" must be a string, but '+typeof a.type+" given",e;var n=a.type=a.type.toLowerCase();if("language"===n&&(n=a.type="lang"),"html"===n&&(n=a.type="output"),"lang"!==n&&"output"!==n&&"listener"!==n)return e.valid=!1,e.error=t+"type "+n+' is not recognized. Valid values: "lang/language", "output/html" or "listener"',e;if("listener"===n){if(I.helper.isUndefined(a.listeners))return e.valid=!1,e.error=t+'. Extensions of type "listener" must have a property called "listeners"',e}else if(I.helper.isUndefined(a.filter)&&I.helper.isUndefined(a.regex))return e.valid=!1,e.error=t+n+' extensions must define either a "regex" property or a "filter" method',e;if(a.listeners){if("object"!=typeof a.listeners)return e.valid=!1,e.error=t+'"listeners" property must be an object but '+typeof a.listeners+" given",e;for(var o in a.listeners)if(a.listeners.hasOwnProperty(o)&&"function"!=typeof a.listeners[o])return e.valid=!1,e.error=t+'"listeners" property must be an hash of [event name]: [callback]. listeners.'+o+" must be a function but "+typeof a.listeners[o]+" given",e}if(a.filter){if("function"!=typeof a.filter)return e.valid=!1,e.error=t+'"filter" must be a function, but '+typeof a.filter+" given",e}else if(a.regex){if(I.helper.isString(a.regex)&&(a.regex=new RegExp(a.regex,"g")),!(a.regex instanceof RegExp))return e.valid=!1,e.error=t+'"regex" property must either be a string or a RegExp object, but '+typeof a.regex+" given",e;if(I.helper.isUndefined(a.replace))return e.valid=!1,e.error=t+'"regex" extensions must implement a replace string or function',e}}return e}function C(g,A){"use strict";return"¨E"+A.charCodeAt(0)+"E"}var I={},e={},r={},t=g(!0),a="vanilla",n={github:{omitExtraWLInCodeBlocks:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,disableForced4SpacesIndentedSublists:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghCompatibleHeaderId:!0,ghMentions:!0,backslashEscapesHTMLTags:!0,emoji:!0,splitAdjacentBlockquotes:!0},original:{noHeaderId:!0,ghCodeBlocks:!1},ghost:{omitExtraWLInCodeBlocks:!0,parseImgDimensions:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,smoothLivePreview:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghMentions:!1,encodeEmails:!0},vanilla:g(!0),allOn:function(){"use strict";var A=g(!0),C={};for(var I in A)A.hasOwnProperty(I)&&(C[I]=!0);return C}()};I.helper={},I.extensions={},I.setOption=function(g,A){"use strict";return t[g]=A,this},I.getOption=function(g){"use strict";return t[g]},I.getOptions=function(){"use strict";return t},I.resetOptions=function(){"use strict";t=g(!0)},I.setFlavor=function(g){"use strict";if(!n.hasOwnProperty(g))throw Error(g+" flavor was not found");I.resetOptions();var A=n[g];a=g;for(var C in A)A.hasOwnProperty(C)&&(t[C]=A[C])},I.getFlavor=function(){"use strict";return a},I.getFlavorOptions=function(g){"use strict";if(n.hasOwnProperty(g))return n[g]},I.getDefaultOptions=function(A){"use strict";return g(A)},I.subParser=function(g,A){"use strict";if(I.helper.isString(g)){if(void 0===A){if(e.hasOwnProperty(g))return e[g];throw Error("SubParser named "+g+" not registered!")}e[g]=A}},I.extension=function(g,C){"use strict";if(!I.helper.isString(g))throw Error("Extension 'name' must be a string");if(g=I.helper.stdExtName(g),I.helper.isUndefined(C)){if(!r.hasOwnProperty(g))throw Error("Extension named "+g+" is not registered!");return r[g]}"function"==typeof C&&(C=C()),I.helper.isArray(C)||(C=[C]);var e=A(C,g);if(!e.valid)throw Error(e.error);r[g]=C},I.getAllExtensions=function(){"use strict";return r},I.removeExtension=function(g){"use strict";delete r[g]},I.resetExtensions=function(){"use strict";r={}},I.validateExtension=function(g){"use strict";var C=A(g,null);return!!C.valid||(console.warn(C.error),!1)},I.hasOwnProperty("helper")||(I.helper={}),I.helper.isString=function(g){"use strict";return"string"==typeof g||g instanceof String},I.helper.isFunction=function(g){"use strict";return g&&"[object Function]"==={}.toString.call(g)},I.helper.isArray=function(g){"use strict";return Array.isArray(g)},I.helper.isUndefined=function(g){"use strict";return void 0===g},I.helper.forEach=function(g,A){"use strict";if(I.helper.isUndefined(g))throw new Error("obj param is required");if(I.helper.isUndefined(A))throw new Error("callback param is required");if(!I.helper.isFunction(A))throw new Error("callback param must be a function/closure");if("function"==typeof g.forEach)g.forEach(A);else if(I.helper.isArray(g))for(var C=0;C<g.length;C++)A(g[C],C,g);else{if("object"!=typeof g)throw new Error("obj does not seem to be an array or an iterable object");for(var e in g)g.hasOwnProperty(e)&&A(g[e],e,g)}},I.helper.stdExtName=function(g){"use strict";return g.replace(/[_?*+\/\\.^-]/g,"").replace(/\s/g,"").toLowerCase()},I.helper.escapeCharactersCallback=C,I.helper.escapeCharacters=function(g,A,I){"use strict";var e="(["+A.replace(/([\[\]\\])/g,"\\$1")+"])";I&&(e="\\\\"+e);var r=new RegExp(e,"g");return g=g.replace(r,C)};var o=function(g,A,C,I){"use strict";var e,r,t,a,n,o=I||"",s=o.indexOf("g")>-1,i=new RegExp(A+"|"+C,"g"+o.replace(/g/g,"")),l=new RegExp(A,o.replace(/g/g,"")),c=[];do{for(e=0;t=i.exec(g);)if(l.test(t[0]))e++||(a=(r=i.lastIndex)-t[0].length);else if(e&&!--e){n=t.index+t[0].length;var u={left:{start:a,end:r},match:{start:r,end:t.index},right:{start:t.index,end:n},wholeMatch:{start:a,end:n}};if(c.push(u),!s)return c}}while(e&&(i.lastIndex=r));return c};I.helper.matchRecursiveRegExp=function(g,A,C,I){"use strict";for(var e=o(g,A,C,I),r=[],t=0;t<e.length;++t)r.push([g.slice(e[t].wholeMatch.start,e[t].wholeMatch.end),g.slice(e[t].match.start,e[t].match.end),g.slice(e[t].left.start,e[t].left.end),g.slice(e[t].right.start,e[t].right.end)]);return r},I.helper.replaceRecursiveRegExp=function(g,A,C,e,r){"use strict";if(!I.helper.isFunction(A)){var t=A;A=function(){return t}}var a=o(g,C,e,r),n=g,s=a.length;if(s>0){var i=[];0!==a[0].wholeMatch.start&&i.push(g.slice(0,a[0].wholeMatch.start));for(var l=0;l<s;++l)i.push(A(g.slice(a[l].wholeMatch.start,a[l].wholeMatch.end),g.slice(a[l].match.start,a[l].match.end),g.slice(a[l].left.start,a[l].left.end),g.slice(a[l].right.start,a[l].right.end))),l<s-1&&i.push(g.slice(a[l].wholeMatch.end,a[l+1].wholeMatch.start));a[s-1].wholeMatch.end<g.length&&i.push(g.slice(a[s-1].wholeMatch.end)),n=i.join("")}return n},I.helper.regexIndexOf=function(g,A,C){"use strict";if(!I.helper.isString(g))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";if(A instanceof RegExp==!1)throw"InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp";var e=g.substring(C||0).search(A);return e>=0?e+(C||0):e},I.helper.splitAtIndex=function(g,A){"use strict";if(!I.helper.isString(g))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";return[g.substring(0,A),g.substring(A)]},I.helper.encodeEmailAddress=function(g){"use strict";var A=[function(g){return"&#"+g.charCodeAt(0)+";"},function(g){return"&#x"+g.charCodeAt(0).toString(16)+";"},function(g){return g}];return g=g.replace(/./g,function(g){if("@"===g)g=A[Math.floor(2*Math.random())](g);else{var C=Math.random();g=C>.9?A[2](g):C>.45?A[1](g):A[0](g)}return g})},"undefined"==typeof console&&(console={warn:function(g){"use strict";alert(g)},log:function(g){"use strict";alert(g)},error:function(g){"use strict";throw g}}),I.helper.regexes={asteriskDashAndColon:/([*_:~])/g},I.helper.emojis={"+1":"👍","-1":"👎",100:"💯",1234:"🔢","1st_place_medal":"🥇","2nd_place_medal":"🥈","3rd_place_medal":"🥉","8ball":"🎱",a:"🅰️",ab:"🆎",abc:"🔤",abcd:"🔡",accept:"🉑",aerial_tramway:"🚡",airplane:"✈️",alarm_clock:"⏰",alembic:"⚗️",alien:"👽",ambulance:"🚑",amphora:"🏺",anchor:"⚓️",angel:"👼",anger:"💢",angry:"😠",anguished:"😧",ant:"🐜",apple:"🍎",aquarius:"♒️",aries:"♈️",arrow_backward:"◀️",arrow_double_down:"⏬",arrow_double_up:"⏫",arrow_down:"⬇️",arrow_down_small:"🔽",arrow_forward:"▶️",arrow_heading_down:"⤵️",arrow_heading_up:"⤴️",arrow_left:"⬅️",arrow_lower_left:"↙️",arrow_lower_right:"↘️",arrow_right:"➡️",arrow_right_hook:"↪️",arrow_up:"⬆️",arrow_up_down:"↕️",arrow_up_small:"🔼",arrow_upper_left:"↖️",arrow_upper_right:"↗️",arrows_clockwise:"🔃",arrows_counterclockwise:"🔄",art:"🎨",articulated_lorry:"🚛",artificial_satellite:"🛰",astonished:"😲",athletic_shoe:"👟",atm:"🏧",atom_symbol:"⚛️",avocado:"🥑",b:"🅱️",baby:"👶",baby_bottle:"🍼",baby_chick:"🐤",baby_symbol:"🚼",back:"🔙",bacon:"🥓",badminton:"🏸",baggage_claim:"🛄",baguette_bread:"🥖",balance_scale:"⚖️",balloon:"🎈",ballot_box:"🗳",ballot_box_with_check:"☑️",bamboo:"🎍",banana:"🍌",bangbang:"‼️",bank:"🏦",bar_chart:"📊",barber:"💈",baseball:"⚾️",basketball:"🏀",basketball_man:"⛹️",basketball_woman:"⛹️‍♀️",bat:"🦇",bath:"🛀",bathtub:"🛁",battery:"🔋",beach_umbrella:"🏖",bear:"🐻",bed:"🛏",bee:"🐝",beer:"🍺",beers:"🍻",beetle:"🐞",beginner:"🔰",bell:"🔔",bellhop_bell:"🛎",bento:"🍱",biking_man:"🚴",bike:"🚲",biking_woman:"🚴‍♀️",bikini:"👙",biohazard:"☣️",bird:"🐦",birthday:"🎂",black_circle:"⚫️",black_flag:"🏴",black_heart:"🖤",black_joker:"🃏",black_large_square:"⬛️",black_medium_small_square:"◾️",black_medium_square:"◼️",black_nib:"✒️",black_small_square:"▪️",black_square_button:"🔲",blonde_man:"👱",blonde_woman:"👱‍♀️",blossom:"🌼",blowfish:"🐡",blue_book:"📘",blue_car:"🚙",blue_heart:"💙",blush:"😊",boar:"🐗",boat:"⛵️",bomb:"💣",book:"📖",bookmark:"🔖",bookmark_tabs:"📑",books:"📚",boom:"💥",boot:"👢",bouquet:"💐",bowing_man:"🙇",bow_and_arrow:"🏹",bowing_woman:"🙇‍♀️",bowling:"🎳",boxing_glove:"🥊",boy:"👦",bread:"🍞",bride_with_veil:"👰",bridge_at_night:"🌉",briefcase:"💼",broken_heart:"💔",bug:"🐛",building_construction:"🏗",bulb:"💡",bullettrain_front:"🚅",bullettrain_side:"🚄",burrito:"🌯",bus:"🚌",business_suit_levitating:"🕴",busstop:"🚏",bust_in_silhouette:"👤",busts_in_silhouette:"👥",butterfly:"🦋",cactus:"🌵",cake:"🍰",calendar:"📆",call_me_hand:"🤙",calling:"📲",camel:"🐫",camera:"📷",camera_flash:"📸",camping:"🏕",cancer:"♋️",candle:"🕯",candy:"🍬",canoe:"🛶",capital_abcd:"🔠",capricorn:"♑️",car:"🚗",card_file_box:"🗃",card_index:"📇",card_index_dividers:"🗂",carousel_horse:"🎠",carrot:"🥕",cat:"🐱",cat2:"🐈",cd:"💿",chains:"⛓",champagne:"🍾",chart:"💹",chart_with_downwards_trend:"📉",chart_with_upwards_trend:"📈",checkered_flag:"🏁",cheese:"🧀",cherries:"🍒",cherry_blossom:"🌸",chestnut:"🌰",chicken:"🐔",children_crossing:"🚸",chipmunk:"🐿",chocolate_bar:"🍫",christmas_tree:"🎄",church:"⛪️",cinema:"🎦",circus_tent:"🎪",city_sunrise:"🌇",city_sunset:"🌆",cityscape:"🏙",cl:"🆑",clamp:"🗜",clap:"👏",clapper:"🎬",classical_building:"🏛",clinking_glasses:"🥂",clipboard:"📋",clock1:"🕐",clock10:"🕙",clock1030:"🕥",clock11:"🕚",clock1130:"🕦",clock12:"🕛",clock1230:"🕧",clock130:"🕜",clock2:"🕑",clock230:"🕝",clock3:"🕒",clock330:"🕞",clock4:"🕓",clock430:"🕟",clock5:"🕔",clock530:"🕠",clock6:"🕕",clock630:"🕡",clock7:"🕖",clock730:"🕢",clock8:"🕗",clock830:"🕣",clock9:"🕘",clock930:"🕤",closed_book:"📕",closed_lock_with_key:"🔐",closed_umbrella:"🌂",cloud:"☁️",cloud_with_lightning:"🌩",cloud_with_lightning_and_rain:"⛈",cloud_with_rain:"🌧",cloud_with_snow:"🌨",clown_face:"🤡",clubs:"♣️",cocktail:"🍸",coffee:"☕️",coffin:"⚰️",cold_sweat:"😰",comet:"☄️",computer:"💻",computer_mouse:"🖱",confetti_ball:"🎊",confounded:"😖",confused:"😕",congratulations:"㊗️",construction:"🚧",construction_worker_man:"👷",construction_worker_woman:"👷‍♀️",control_knobs:"🎛",convenience_store:"🏪",cookie:"🍪",cool:"🆒",policeman:"👮",copyright:"©️",corn:"🌽",couch_and_lamp:"🛋",couple:"👫",couple_with_heart_woman_man:"💑",couple_with_heart_man_man:"👨‍❤️‍👨",couple_with_heart_woman_woman:"👩‍❤️‍👩",couplekiss_man_man:"👨‍❤️‍💋‍👨",couplekiss_man_woman:"💏",couplekiss_woman_woman:"👩‍❤️‍💋‍👩",cow:"🐮",cow2:"🐄",cowboy_hat_face:"🤠",crab:"🦀",crayon:"🖍",credit_card:"💳",crescent_moon:"🌙",cricket:"🏏",crocodile:"🐊",croissant:"🥐",crossed_fingers:"🤞",crossed_flags:"🎌",crossed_swords:"⚔️",crown:"👑",cry:"😢",crying_cat_face:"😿",crystal_ball:"🔮",cucumber:"🥒",cupid:"💘",curly_loop:"➰",currency_exchange:"💱",curry:"🍛",custard:"🍮",customs:"🛃",cyclone:"🌀",dagger:"🗡",dancer:"💃",dancing_women:"👯",dancing_men:"👯‍♂️",dango:"🍡",dark_sunglasses:"🕶",dart:"🎯",dash:"💨",date:"📅",deciduous_tree:"🌳",deer:"🦌",department_store:"🏬",derelict_house:"🏚",desert:"🏜",desert_island:"🏝",desktop_computer:"🖥",male_detective:"🕵️",diamond_shape_with_a_dot_inside:"💠",diamonds:"♦️",disappointed:"😞",disappointed_relieved:"😥",dizzy:"💫",dizzy_face:"😵",do_not_litter:"🚯",dog:"🐶",dog2:"🐕",dollar:"💵",dolls:"🎎",dolphin:"🐬",door:"🚪",doughnut:"🍩",dove:"🕊",dragon:"🐉",dragon_face:"🐲",dress:"👗",dromedary_camel:"🐪",drooling_face:"🤤",droplet:"💧",drum:"🥁",duck:"🦆",dvd:"📀","e-mail":"📧",eagle:"🦅",ear:"👂",ear_of_rice:"🌾",earth_africa:"🌍",earth_americas:"🌎",earth_asia:"🌏",egg:"🥚",eggplant:"🍆",eight_pointed_black_star:"✴️",eight_spoked_asterisk:"✳️",electric_plug:"🔌",elephant:"🐘",email:"✉️",end:"🔚",envelope_with_arrow:"📩",euro:"💶",european_castle:"🏰",european_post_office:"🏤",evergreen_tree:"🌲",exclamation:"❗️",expressionless:"😑",eye:"👁",eye_speech_bubble:"👁‍🗨",eyeglasses:"👓",eyes:"👀",face_with_head_bandage:"🤕",face_with_thermometer:"🤒",fist_oncoming:"👊",factory:"🏭",fallen_leaf:"🍂",family_man_woman_boy:"👪",family_man_boy:"👨‍👦",family_man_boy_boy:"👨‍👦‍👦",family_man_girl:"👨‍👧",family_man_girl_boy:"👨‍👧‍👦",family_man_girl_girl:"👨‍👧‍👧",family_man_man_boy:"👨‍👨‍👦",family_man_man_boy_boy:"👨‍👨‍👦‍👦",family_man_man_girl:"👨‍👨‍👧",family_man_man_girl_boy:"👨‍👨‍👧‍👦",family_man_man_girl_girl:"👨‍👨‍👧‍👧",family_man_woman_boy_boy:"👨‍👩‍👦‍👦",family_man_woman_girl:"👨‍👩‍👧",family_man_woman_girl_boy:"👨‍👩‍👧‍👦",family_man_woman_girl_girl:"👨‍👩‍👧‍👧",family_woman_boy:"👩‍👦",family_woman_boy_boy:"👩‍👦‍👦",family_woman_girl:"👩‍👧",family_woman_girl_boy:"👩‍👧‍👦",family_woman_girl_girl:"👩‍👧‍👧",family_woman_woman_boy:"👩‍👩‍👦",family_woman_woman_boy_boy:"👩‍👩‍👦‍👦",family_woman_woman_girl:"👩‍👩‍👧",family_woman_woman_girl_boy:"👩‍👩‍👧‍👦",family_woman_woman_girl_girl:"👩‍👩‍👧‍👧",fast_forward:"⏩",fax:"📠",fearful:"😨",feet:"🐾",female_detective:"🕵️‍♀️",ferris_wheel:"🎡",ferry:"⛴",field_hockey:"🏑",file_cabinet:"🗄",file_folder:"📁",film_projector:"📽",film_strip:"🎞",fire:"🔥",fire_engine:"🚒",fireworks:"🎆",first_quarter_moon:"🌓",first_quarter_moon_with_face:"🌛",fish:"🐟",fish_cake:"🍥",fishing_pole_and_fish:"🎣",fist_raised:"✊",fist_left:"🤛",fist_right:"🤜",flags:"🎏",flashlight:"🔦",fleur_de_lis:"⚜️",flight_arrival:"🛬",flight_departure:"🛫",floppy_disk:"💾",flower_playing_cards:"🎴",flushed:"😳",fog:"🌫",foggy:"🌁",football:"🏈",footprints:"👣",fork_and_knife:"🍴",fountain:"⛲️",fountain_pen:"🖋",four_leaf_clover:"🍀",fox_face:"🦊",framed_picture:"🖼",free:"🆓",fried_egg:"🍳",fried_shrimp:"🍤",fries:"🍟",frog:"🐸",frowning:"😦",frowning_face:"☹️",frowning_man:"🙍‍♂️",frowning_woman:"🙍",middle_finger:"🖕",fuelpump:"⛽️",full_moon:"🌕",full_moon_with_face:"🌝",funeral_urn:"⚱️",game_die:"🎲",gear:"⚙️",gem:"💎",gemini:"♊️",ghost:"👻",gift:"🎁",gift_heart:"💝",girl:"👧",globe_with_meridians:"🌐",goal_net:"🥅",goat:"🐐",golf:"⛳️",golfing_man:"🏌️",golfing_woman:"🏌️‍♀️",gorilla:"🦍",grapes:"🍇",green_apple:"🍏",green_book:"📗",green_heart:"💚",green_salad:"🥗",grey_exclamation:"❕",grey_question:"❔",grimacing:"😬",grin:"😁",grinning:"😀",guardsman:"💂",guardswoman:"💂‍♀️",guitar:"🎸",gun:"🔫",haircut_woman:"💇",haircut_man:"💇‍♂️",hamburger:"🍔",hammer:"🔨",hammer_and_pick:"⚒",hammer_and_wrench:"🛠",hamster:"🐹",hand:"✋",handbag:"👜",handshake:"🤝",hankey:"💩",hatched_chick:"🐥",hatching_chick:"🐣",headphones:"🎧",hear_no_evil:"🙉",heart:"❤️",heart_decoration:"💟",heart_eyes:"😍",heart_eyes_cat:"😻",heartbeat:"💓",heartpulse:"💗",hearts:"♥️",heavy_check_mark:"✔️",heavy_division_sign:"➗",heavy_dollar_sign:"💲",heavy_heart_exclamation:"❣️",heavy_minus_sign:"➖",heavy_multiplication_x:"✖️",heavy_plus_sign:"➕",helicopter:"🚁",herb:"🌿",hibiscus:"🌺",high_brightness:"🔆",high_heel:"👠",hocho:"🔪",hole:"🕳",honey_pot:"🍯",horse:"🐴",horse_racing:"🏇",hospital:"🏥",hot_pepper:"🌶",hotdog:"🌭",hotel:"🏨",hotsprings:"♨️",hourglass:"⌛️",hourglass_flowing_sand:"⏳",house:"🏠",house_with_garden:"🏡",houses:"🏘",hugs:"🤗",hushed:"😯",ice_cream:"🍨",ice_hockey:"🏒",ice_skate:"⛸",icecream:"🍦",id:"🆔",ideograph_advantage:"🉐",imp:"👿",inbox_tray:"📥",incoming_envelope:"📨",tipping_hand_woman:"💁",information_source:"ℹ️",innocent:"😇",interrobang:"⁉️",iphone:"📱",izakaya_lantern:"🏮",jack_o_lantern:"🎃",japan:"🗾",japanese_castle:"🏯",japanese_goblin:"👺",japanese_ogre:"👹",jeans:"👖",joy:"😂",joy_cat:"😹",joystick:"🕹",kaaba:"🕋",key:"🔑",keyboard:"⌨️",keycap_ten:"🔟",kick_scooter:"🛴",kimono:"👘",kiss:"💋",kissing:"😗",kissing_cat:"😽",kissing_closed_eyes:"😚",kissing_heart:"😘",kissing_smiling_eyes:"😙",kiwi_fruit:"🥝",koala:"🐨",koko:"🈁",label:"🏷",large_blue_circle:"🔵",large_blue_diamond:"🔷",large_orange_diamond:"🔶",last_quarter_moon:"🌗",last_quarter_moon_with_face:"🌜",latin_cross:"✝️",laughing:"😆",leaves:"🍃",ledger:"📒",left_luggage:"🛅",left_right_arrow:"↔️",leftwards_arrow_with_hook:"↩️",lemon:"🍋",leo:"♌️",leopard:"🐆",level_slider:"🎚",libra:"♎️",light_rail:"🚈",link:"🔗",lion:"🦁",lips:"👄",lipstick:"💄",lizard:"🦎",lock:"🔒",lock_with_ink_pen:"🔏",lollipop:"🍭",loop:"➿",loud_sound:"🔊",loudspeaker:"📢",love_hotel:"🏩",love_letter:"💌",low_brightness:"🔅",lying_face:"🤥",m:"Ⓜ️",mag:"🔍",mag_right:"🔎",mahjong:"🀄️",mailbox:"📫",mailbox_closed:"📪",mailbox_with_mail:"📬",mailbox_with_no_mail:"📭",man:"👨",man_artist:"👨‍🎨",man_astronaut:"👨‍🚀",man_cartwheeling:"🤸‍♂️",man_cook:"👨‍🍳",man_dancing:"🕺",man_facepalming:"🤦‍♂️",man_factory_worker:"👨‍🏭",man_farmer:"👨‍🌾",man_firefighter:"👨‍🚒",man_health_worker:"👨‍⚕️",man_in_tuxedo:"🤵",man_judge:"👨‍⚖️",man_juggling:"🤹‍♂️",man_mechanic:"👨‍🔧",man_office_worker:"👨‍💼",man_pilot:"👨‍✈️",man_playing_handball:"🤾‍♂️",man_playing_water_polo:"🤽‍♂️",man_scientist:"👨‍🔬",man_shrugging:"🤷‍♂️",man_singer:"👨‍🎤",man_student:"👨‍🎓",man_teacher:"👨‍🏫",man_technologist:"👨‍💻",man_with_gua_pi_mao:"👲",man_with_turban:"👳",tangerine:"🍊",mans_shoe:"👞",mantelpiece_clock:"🕰",maple_leaf:"🍁",martial_arts_uniform:"🥋",mask:"😷",massage_woman:"💆",massage_man:"💆‍♂️",meat_on_bone:"🍖",medal_military:"🎖",medal_sports:"🏅",mega:"📣",melon:"🍈",memo:"📝",men_wrestling:"🤼‍♂️",menorah:"🕎",mens:"🚹",metal:"🤘",metro:"🚇",microphone:"🎤",microscope:"🔬",milk_glass:"🥛",milky_way:"🌌",minibus:"🚐",minidisc:"💽",mobile_phone_off:"📴",money_mouth_face:"🤑",money_with_wings:"💸",moneybag:"💰",monkey:"🐒",monkey_face:"🐵",monorail:"🚝",moon:"🌔",mortar_board:"🎓",mosque:"🕌",motor_boat:"🛥",motor_scooter:"🛵",motorcycle:"🏍",motorway:"🛣",mount_fuji:"🗻",mountain:"⛰",mountain_biking_man:"🚵",mountain_biking_woman:"🚵‍♀️",mountain_cableway:"🚠",mountain_railway:"🚞",mountain_snow:"🏔",mouse:"🐭",mouse2:"🐁",movie_camera:"🎥",moyai:"🗿",mrs_claus:"🤶",muscle:"💪",mushroom:"🍄",musical_keyboard:"🎹",musical_note:"🎵",musical_score:"🎼",mute:"🔇",nail_care:"💅",name_badge:"📛",national_park:"🏞",nauseated_face:"🤢",necktie:"👔",negative_squared_cross_mark:"❎",nerd_face:"🤓",neutral_face:"😐",new:"🆕",new_moon:"🌑",new_moon_with_face:"🌚",newspaper:"📰",newspaper_roll:"🗞",next_track_button:"⏭",ng:"🆖",no_good_man:"🙅‍♂️",no_good_woman:"🙅",night_with_stars:"🌃",no_bell:"🔕",no_bicycles:"🚳",no_entry:"⛔️",no_entry_sign:"🚫",no_mobile_phones:"📵",no_mouth:"😶",no_pedestrians:"🚷",no_smoking:"🚭","non-potable_water":"🚱",nose:"👃",notebook:"📓",notebook_with_decorative_cover:"📔",notes:"🎶",nut_and_bolt:"🔩",o:"⭕️",o2:"🅾️",ocean:"🌊",octopus:"🐙",oden:"🍢",office:"🏢",oil_drum:"🛢",ok:"🆗",ok_hand:"👌",ok_man:"🙆‍♂️",ok_woman:"🙆",old_key:"🗝",older_man:"👴",older_woman:"👵",om:"🕉",on:"🔛",oncoming_automobile:"🚘",oncoming_bus:"🚍",oncoming_police_car:"🚔",oncoming_taxi:"🚖",open_file_folder:"📂",open_hands:"👐",open_mouth:"😮",open_umbrella:"☂️",ophiuchus:"⛎",orange_book:"📙",orthodox_cross:"☦️",outbox_tray:"📤",owl:"🦉",ox:"🐂",package:"📦",page_facing_up:"📄",page_with_curl:"📃",pager:"📟",paintbrush:"🖌",palm_tree:"🌴",pancakes:"🥞",panda_face:"🐼",paperclip:"📎",paperclips:"🖇",parasol_on_ground:"⛱",parking:"🅿️",part_alternation_mark:"〽️",partly_sunny:"⛅️",passenger_ship:"🛳",passport_control:"🛂",pause_button:"⏸",peace_symbol:"☮️",peach:"🍑",peanuts:"🥜",pear:"🍐",pen:"🖊",pencil2:"✏️",penguin:"🐧",pensive:"😔",performing_arts:"🎭",persevere:"😣",person_fencing:"🤺",pouting_woman:"🙎",phone:"☎️",pick:"⛏",pig:"🐷",pig2:"🐖",pig_nose:"🐽",pill:"💊",pineapple:"🍍",ping_pong:"🏓",pisces:"♓️",pizza:"🍕",place_of_worship:"🛐",plate_with_cutlery:"🍽",play_or_pause_button:"⏯",point_down:"👇",point_left:"👈",point_right:"👉",point_up:"☝️",point_up_2:"👆",police_car:"🚓",policewoman:"👮‍♀️",poodle:"🐩",popcorn:"🍿",post_office:"🏣",postal_horn:"📯",postbox:"📮",potable_water:"🚰",potato:"🥔",pouch:"👝",poultry_leg:"🍗",pound:"💷",rage:"😡",pouting_cat:"😾",pouting_man:"🙎‍♂️",pray:"🙏",prayer_beads:"📿",pregnant_woman:"🤰",previous_track_button:"⏮",prince:"🤴",princess:"👸",printer:"🖨",purple_heart:"💜",purse:"👛",pushpin:"📌",put_litter_in_its_place:"🚮",question:"❓",rabbit:"🐰",rabbit2:"🐇",racehorse:"🐎",racing_car:"🏎",radio:"📻",radio_button:"🔘",radioactive:"☢️",railway_car:"🚃",railway_track:"🛤",rainbow:"🌈",rainbow_flag:"🏳️‍🌈",raised_back_of_hand:"🤚",raised_hand_with_fingers_splayed:"🖐",raised_hands:"🙌",raising_hand_woman:"🙋",raising_hand_man:"🙋‍♂️",ram:"🐏",ramen:"🍜",rat:"🐀",record_button:"⏺",recycle:"♻️",red_circle:"🔴",registered:"®️",relaxed:"☺️",relieved:"😌",reminder_ribbon:"🎗",repeat:"🔁",repeat_one:"🔂",rescue_worker_helmet:"⛑",restroom:"🚻",revolving_hearts:"💞",rewind:"⏪",rhinoceros:"🦏",ribbon:"🎀",rice:"🍚",rice_ball:"🍙",rice_cracker:"🍘",rice_scene:"🎑",right_anger_bubble:"🗯",ring:"💍",robot:"🤖",rocket:"🚀",rofl:"🤣",roll_eyes:"🙄",roller_coaster:"🎢",rooster:"🐓",rose:"🌹",rosette:"🏵",rotating_light:"🚨",round_pushpin:"📍",rowing_man:"🚣",rowing_woman:"🚣‍♀️",rugby_football:"🏉",running_man:"🏃",running_shirt_with_sash:"🎽",running_woman:"🏃‍♀️",sa:"🈂️",sagittarius:"♐️",sake:"🍶",sandal:"👡",santa:"🎅",satellite:"📡",saxophone:"🎷",school:"🏫",school_satchel:"🎒",scissors:"✂️",scorpion:"🦂",scorpius:"♏️",scream:"😱",scream_cat:"🙀",scroll:"📜",seat:"💺",secret:"㊙️",see_no_evil:"🙈",seedling:"🌱",selfie:"🤳",shallow_pan_of_food:"🥘",shamrock:"☘️",shark:"🦈",shaved_ice:"🍧",sheep:"🐑",shell:"🐚",shield:"🛡",shinto_shrine:"⛩",ship:"🚢",shirt:"👕",shopping:"🛍",shopping_cart:"🛒",shower:"🚿",shrimp:"🦐",signal_strength:"📶",six_pointed_star:"🔯",ski:"🎿",skier:"⛷",skull:"💀",skull_and_crossbones:"☠️",sleeping:"😴",sleeping_bed:"🛌",sleepy:"😪",slightly_frowning_face:"🙁",slightly_smiling_face:"🙂",slot_machine:"🎰",small_airplane:"🛩",small_blue_diamond:"🔹",small_orange_diamond:"🔸",small_red_triangle:"🔺",small_red_triangle_down:"🔻",smile:"😄",smile_cat:"😸",smiley:"😃",smiley_cat:"😺",smiling_imp:"😈",smirk:"😏",smirk_cat:"😼",smoking:"🚬",snail:"🐌",snake:"🐍",sneezing_face:"🤧",snowboarder:"🏂",snowflake:"❄️",snowman:"⛄️",snowman_with_snow:"☃️",sob:"😭",soccer:"⚽️",soon:"🔜",sos:"🆘",sound:"🔉",space_invader:"👾",spades:"♠️",spaghetti:"🍝",sparkle:"❇️",sparkler:"🎇",sparkles:"✨",sparkling_heart:"💖",speak_no_evil:"🙊",speaker:"🔈",speaking_head:"🗣",speech_balloon:"💬",speedboat:"🚤",spider:"🕷",spider_web:"🕸",spiral_calendar:"🗓",spiral_notepad:"🗒",spoon:"🥄",squid:"🦑",stadium:"🏟",star:"⭐️",star2:"🌟",star_and_crescent:"☪️",star_of_david:"✡️",stars:"🌠",station:"🚉",statue_of_liberty:"🗽",steam_locomotive:"🚂",stew:"🍲",stop_button:"⏹",stop_sign:"🛑",stopwatch:"⏱",straight_ruler:"📏",strawberry:"🍓",stuck_out_tongue:"😛",stuck_out_tongue_closed_eyes:"😝",stuck_out_tongue_winking_eye:"😜",studio_microphone:"🎙",stuffed_flatbread:"🥙",sun_behind_large_cloud:"🌥",sun_behind_rain_cloud:"🌦",sun_behind_small_cloud:"🌤",sun_with_face:"🌞",sunflower:"🌻",sunglasses:"😎",sunny:"☀️",sunrise:"🌅",sunrise_over_mountains:"🌄",surfing_man:"🏄",surfing_woman:"🏄‍♀️",sushi:"🍣",suspension_railway:"🚟",sweat:"😓",sweat_drops:"💦",sweat_smile:"😅",sweet_potato:"🍠",swimming_man:"🏊",swimming_woman:"🏊‍♀️",symbols:"🔣",synagogue:"🕍",syringe:"💉",taco:"🌮",tada:"🎉",tanabata_tree:"🎋",taurus:"♉️",taxi:"🚕",tea:"🍵",telephone_receiver:"📞",telescope:"🔭",tennis:"🎾",tent:"⛺️",thermometer:"🌡",thinking:"🤔",thought_balloon:"💭",ticket:"🎫",tickets:"🎟",tiger:"🐯",tiger2:"🐅",timer_clock:"⏲",tipping_hand_man:"💁‍♂️",tired_face:"😫",tm:"™️",toilet:"🚽",tokyo_tower:"🗼",tomato:"🍅",tongue:"👅",top:"🔝",tophat:"🎩",tornado:"🌪",trackball:"🖲",tractor:"🚜",traffic_light:"🚥",train:"🚋",train2:"🚆",tram:"🚊",triangular_flag_on_post:"🚩",triangular_ruler:"📐",trident:"🔱",triumph:"😤",trolleybus:"🚎",trophy:"🏆",tropical_drink:"🍹",tropical_fish:"🐠",truck:"🚚",trumpet:"🎺",tulip:"🌷",tumbler_glass:"🥃",turkey:"🦃",turtle:"🐢",tv:"📺",twisted_rightwards_arrows:"🔀",two_hearts:"💕",two_men_holding_hands:"👬",two_women_holding_hands:"👭",u5272:"🈹",u5408:"🈴",u55b6:"🈺",u6307:"🈯️",u6708:"🈷️",u6709:"🈶",u6e80:"🈵",u7121:"🈚️",u7533:"🈸",u7981:"🈲",u7a7a:"🈳",umbrella:"☔️",unamused:"😒",underage:"🔞",unicorn:"🦄",unlock:"🔓",up:"🆙",upside_down_face:"🙃",v:"✌️",vertical_traffic_light:"🚦",vhs:"📼",vibration_mode:"📳",video_camera:"📹",video_game:"🎮",violin:"🎻",virgo:"♍️",volcano:"🌋",volleyball:"🏐",vs:"🆚",vulcan_salute:"🖖",walking_man:"🚶",walking_woman:"🚶‍♀️",waning_crescent_moon:"🌘",waning_gibbous_moon:"🌖",warning:"⚠️",wastebasket:"🗑",watch:"⌚️",water_buffalo:"🐃",watermelon:"🍉",wave:"👋",wavy_dash:"〰️",waxing_crescent_moon:"🌒",wc:"🚾",weary:"😩",wedding:"💒",weight_lifting_man:"🏋️",weight_lifting_woman:"🏋️‍♀️",whale:"🐳",whale2:"🐋",wheel_of_dharma:"☸️",wheelchair:"♿️",white_check_mark:"✅",white_circle:"⚪️",white_flag:"🏳️",white_flower:"💮",white_large_square:"⬜️",white_medium_small_square:"◽️",white_medium_square:"◻️",white_small_square:"▫️",white_square_button:"🔳",wilted_flower:"🥀",wind_chime:"🎐",wind_face:"🌬",wine_glass:"🍷",wink:"😉",wolf:"🐺",woman:"👩",woman_artist:"👩‍🎨",woman_astronaut:"👩‍🚀",woman_cartwheeling:"🤸‍♀️",woman_cook:"👩‍🍳",woman_facepalming:"🤦‍♀️",woman_factory_worker:"👩‍🏭",woman_farmer:"👩‍🌾",woman_firefighter:"👩‍🚒",woman_health_worker:"👩‍⚕️",woman_judge:"👩‍⚖️",woman_juggling:"🤹‍♀️",woman_mechanic:"👩‍🔧",woman_office_worker:"👩‍💼",woman_pilot:"👩‍✈️",woman_playing_handball:"🤾‍♀️",woman_playing_water_polo:"🤽‍♀️",woman_scientist:"👩‍🔬",woman_shrugging:"🤷‍♀️",woman_singer:"👩‍🎤",woman_student:"👩‍🎓",woman_teacher:"👩‍🏫",woman_technologist:"👩‍💻",woman_with_turban:"👳‍♀️",womans_clothes:"👚",womans_hat:"👒",women_wrestling:"🤼‍♀️",womens:"🚺",world_map:"🗺",worried:"😟",wrench:"🔧",writing_hand:"✍️",x:"❌",yellow_heart:"💛",yen:"💴",yin_yang:"☯️",yum:"😋",zap:"⚡️",zipper_mouth_face:"🤐",zzz:"💤",octocat:'<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAOwUlEQVR42uVbCVyO6RbPmn0sw9gZS0aZO4y5GTEUE2ObxjZjrbHEJVy3sWS5pkaWxjLEkCVDSbSgFLdESaWSLIVUSIi4kvb9f895vi/zbbR+yZ339/tbnu99n/ec/3Oe85xznufV0CjDBaAdwZqwnzCJ0FXjHV70/i8J5oQDhCFV8cJdq1atwqxZs+Ds7Iz4+HhqwgXCLELNKlK6G2Ej4e6lS5ewZcsWzJgxA+fOnWNZFqvzxT1v3boF/qcsBg0ahP3796OwsJAFWKYuIqjfPoS9cXFxWL58Obp06SInh5aWFr//jjoJWLlu3TolAorRuXNn7Ny5k4W4Spgj81xrgj5hLmED4RDhlNRygglBhADCSakpWxFMCHoETUJTwrYHDx7A1NT0je9nPHz4kN/fXl0EeI0aNeqtAjB69+4NPz8/FsSdlXvy5An8/f1hZ2cHCwsLGBsbY/To0cJy9PT0MGDAAAwePBhGRkbClNesWYODBw8iODgYOTk53M/d9evXo27duiW++8iRI3z/ZHURENOjR48ShSjGuHHjhHJ16tQp9TOKaNWqlZKpvw1MHluQOpSvk5eXh5YtW5ZbmarAvHnzmIBd6iCgXnZ2Npo1a1atCWAfwY5SHQTUKCoqQocOHao1AebmHBJgi7p8QBDP6epMwKFDvMDAWF0ELLS1ta3WBNy9e5cJMFIXAdvt7e2rNQHDhw9nAv5D+KKylV9y8+bNCi1pVYWZM2cyCfaVTcDdsqzH7xpBQRxcwqyylLdi5/K+KM/Q0dFhAqIri4Bn1T0AUgVpdmhYUeVHnD59+r1TnjF27Fgm4HhFCThoYmLyXhLQoEGD4mRKsyIE3OrZs+d7SQCDCyZcNSqv8k1evXoFTU3NUr+wzUcfYqRBf8yb/C2WzfoBFoTF08fBdMIITDD8CsP1+kL30x7Q6dYZH7drjfZ0f4fWLdG1Q1t81qMLBvTRwejB/TBl1BDMnzQGS2dMxKo5k7Fs9iSY/jAaBvR8Pc26pZaH02quLZSXgO6xsbGlelGnli1wZKcVMqN8gKcRwItrf+K/VB95doXaLwOJIVSzOU/+2Re5kV7IuuyJrIhTyLt6mmztLBBPNZLHoUAy9fE8UvJ8ikxfj8PwJPQErJeYlkquTZs2MQFLykuANgc/Jb2kn3Z3ZMaQUrmxwO1zyAo7gfRAJ6RfOIyMEFdkXj5F8BTK5lzxQv610yi8QcFatI8gQoCIK7x+hojwRnaE5H4JTiEj9Pjr/rJDqcZyn9b4ovu45LYbdWvXeqtsXMHiSlZ5CegRExPz1hd83PYj5POo0QinXyLFg48hnZTOiQ1Dzr1IZEaeQRoJn0HKZIR7lA2kfHrQUerXHTlx4ZL+rnjjFRGRGeYB5MUj2GnbW+XbuJFrp1heXgI6JCYmvvUFN1x3Aek3SWkapRAXMeJFGS8ge2Xfuog0toaykED3Mpk8+shOk+sv68Y50V9WuKewBKt5094o39atW/mRf5WXgIYZGRlo3Lixys4nj6A6Z1YMcqRCpwU4ouDlUyHk/QA/hNttR25Wlvh/ZthJUsil9ATQ/axkYbqEzDgfL0Ts/x35+aLyTES7IY36Q6w/+Q4/tP6wuUoZ9+7dy7ebVmQZjO/atavKzn32rAdeXkd6KCkXdAxZ13yFcLFnvPD73zrDVrsdTs6eggKSuSjjORHkUGoC0i86Iyc6QPQX7eqMnTodYNuzHU4vnosiaitMSUSavwMy6d3IvEUrzViVMrq5uXEX4ytCgL++vr5Sx7Vr1cIDX0dKkQJfj37Rs3jw1sBxkwlwGD4Ax3+ciN1faCHW76xQRFgAOcjSEMBkIe0x8nLzcez7kTg8Rh/uxuOxR/cTJISFSfq7eATpZCk8CAfXLVFJwIULXHnHoIoQYLtw4UKljps2aogXQcQuef/XAiMDKY+S4DhyEFwpDnCj9f+Afl8EbbWRTANaAdihlYoAMn8aZzyNuYODX/eD29TvRH/7v+qN8H27JdOAyWQfQQ74xPafVRLAPox9WUlK6hIGEgx4f00Kg2JcvHhRqeP6FIwknXemyen/2gLIIeC/CYk49M0AuE4xgtu0sThg8AUCN62TEuBdRgJo2Y+Kxh9D/k59SQiwH9QHobt3SAk4KSGA4oWjm1YqyVi8U6Soj4yOrHM/jTAyKVby/PnzIoNi8L+L4eXlpXoFcLcTgc1rAlISkJeXDxeK2A6P1hdTwI6mQPTJE+WbAlnJyE7PhNO3Q3BkrKGYWtxfHMkkmQLO0ilwA7+vXqAkn66urtBLUZ9iHfm30NBQaPAf165dA0d9vP2UlJSEp0+f4vHjx3j06JH4e+rUqUovcNmyGkiNEkLwklXsBG+ecMUOnfbYod1emG5uboFKJ8jPFVD0l0dBUHqoPDHpQeQEb0qc4FUHe3KAbYUT9JgzDbwOFL5MfN0fXkXhJ5PxSvLt2LFD1Ah5u4z1YJ14l4qnBe8v3rhxAzz4PAVG8nLHivIP0dHRiIiIQGRkpEgmrl69ClW1QBMjQ7LDW8hmU+RRI69ckJIkhL7jfRJBm62R+TJVYq6h0jhBRslsivqenT2MF/7OyI70VmkFhWnPJaS6OyPkt43IycqR9EfWlH7JDQUUTuNhCHR7Ke9YcRp/5coVoQPrcvnyZURFRYmBZlLS0kR8MVLD29sbnp6e8PHxQUBAgCgn8YO8E3z79m3BGKeVc+bMkXuBZt06SA12F/F5Go0gR4C8HBalPZMPXKL8lQKhPAqF+f97KXFyNx6HQsoPsshJ/kmAp2TKkJLISpXvjyxNhMYcDVLOEO+lPDi8B5mamipkZx1YF9YpJCRErAy+vr5CZ9ZdWABhDGEYYTBhAOFz3g4nfMJelNCbkNCpUye5F034mvxIPi1/FM+zQCw0k5B9O0iEr5kRXkqhMJOVf9NXIHjtT7hmaymSoBzKETimkAuFpaF1dkwI9RcmIYaXv3BJXoGCuyIgk5WpefPmKCgoYK46SmX/RKoL69Sfl0WuFEl1HlmWJXE5z6WmTZvKJxxmxkIQ3AuU5APk6NICj4hRT6eITTEEzqWk55HHPjz3cxJhNF5cxeNT9kj2cRDTQjEkzpDtjyyCic5l5fEA7uSHFEefR5pPsahrb2B9QkICFHeJ51HunkdLIg0VLY0BFKdLwllVHp4dHyvst3QuEiiju21vA/+VZkiluIKt4I3RIfWXQ4QgKUxkni47LJWUP3PmjHo2RxVI+CebmKJP6EiFDVurxUgmExe5PHlnPAkn8w4QqW62NCVmYopozid5H0CI9RKE21ggJeAYEeMnfitOnRn5XCfgeJ+VTosWQU8MOc6ZE0cqnUm4fv165SrPBVHCfMI4TowUfmOfsIcdJh92kBWmUcP6GDt8EDZbzIffH5tx3/ewSFjw5LKk0MEFEkZenDBjgew7Yiog5brkt+QrknvJmhIp4Apw/A1bVpjhG/0v5d7Vrl07bNu2TelUSqUoz8uI3Z49OEtBAy+TdP1CqKtwHzvQUxxgTJs2TeX5gdq1a0ObSmCjh+jB+NuvRamL1+3ls77HCip1rTSdJP5eNnMizKndjMLoH42G4bthX+FzHS3UVVEC69evH3799VeKMXJZrlWKclUGAZ5jxoxB02ZNsNlxH74aagBHZyex986HlVTczyGmI58h4CjL2toa48ePFxsUPEotWrQoc0GT0/C2bduiY8eO4ISMcxLeoOFYhS6qm2EpoZG65jmbv+dPSyRZlt5QfVjvtX19AOFNL+aDFNI4m0eFc9Ho5ORkaGtrl5kAVp6DMOk88efEjLe++ZhclZwHTJHEHbs4YOCmLj2645fdvwnTK42zoXtaEHwNDQ3LXdZm5yad3/2r+gQmDsRnIF5KAldX6zdsgG/GG8F44Vzcu3eP2y1K6GPr2rVrK1zbnz59Or/LoaoJCPZ4kCZsjw9GECL79OmDj9q2wb+320C3/5fgPQO6Vrzh+fpcDqxXr16lbHBwgkZXm6okYJr0ECMrX5vraiJ1lArEjrEnzWuOqemiYj9spGd2ee478XkiPsJakmJ83qA05/8qXNurJFLiunXrhpo1a6LxB02wyHIFZpovgOHwYfjZ0hK2lH5u2rwZ5suWYv5ycyUlmjRpgl69eimlrFy3kwuoyOvXr19frm3RokVMwPZ3TYC57E6xVq+e6KzVDSaL/oEp82Zh8IhhWLjGAp/p9oX5ujVKBNjY2MDV1VWuzd3dXaTesm2biUQuZ8u28elSPmKr8a4vdog8GnJpcT1N1KHUuBbt0jSgWuGbzJh3mVhh2TYHBwdxjFa2jVcZnvPVlQBOLXdZWlqW2ZFxNYYVlm07fPgwAgMD5dr4OD5HeHLFFxM+O42DGtXhIkFaMQlcUjIzM0P37t1Ro0YNpZPjPJcVK7SOjo5ybU5OTqIAo0gAh97VlgAZIj4l8Pn4WFaO64ocuXG6zJtDbMqySnC7IgF8uptLVrJtq1evFuWqak+A4j4i4TNpltiJ8LPiNFFFwNGjRyWFyfedAFUny/joekkEuLi4KK0CfykCeFnkiu1flgBeFtl3/D8SsMbKykpOifv37ysRcPz4cVHKUiSA8wwNdR9/VTMBSh9Y8S4Nf2qnSICiBbDzVCRg9uzZTMC+94kAv6FDh8opwRsVHPjItnl4eEDxHNLKlStFXV+2javQ/M1SpZe+1KA4L4G7WDG57fSm/OUbXiqG0ewAFYOeYcN4fwZhvLkp2y4tftrxcltdlf/w+fPn4qNGxTCYU2m6nrRu3VqunT/EoiuZvw6TTZHpyuNNmEaNGsndP3fu3OJAq1N1JOAHDmyKheVtNP4OkE2crULRAW7fvl20EyyLy24a8p+/7WISFixYIMLt4t82bNhQYjXqXREgPq3j74mlX3AmSL8E1eOPIBXnuVT5OsVZpuLnOMeOHeN7vifwiYhYzhC5IpwlOXj1QXWdBmy/XWU/X+UqMZfKBw4cKAobHPlJlZe9h6tOu+7cuSN2dg0MDMSSyZUpmXvaSD+crq/xvl0k9BTCRa7qEPq+5T4t6ffF52WVV+f1P6zyLG30bsU4AAAAAElFTkSuQmCC">',showdown:'<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAECtaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzA2NyA3OS4xNTc3NDcsIDIwMTUvMDMvMzAtMjM6NDA6NDIgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTctMTAtMjRUMTM6MzE6MzArMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOklDQ1Byb2ZpbGU+c1JHQiBJRUM2MTk2Ni0yLjE8L3Bob3Rvc2hvcDpJQ0NQcm9maWxlPgogICAgICAgICA8cGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgICAgIDxyZGY6QmFnPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHBob3Rvc2hvcDpMYXllck5hbWU+UyAtPC9waG90b3Nob3A6TGF5ZXJOYW1lPgogICAgICAgICAgICAgICAgICA8cGhvdG9zaG9wOkxheWVyVGV4dD5TIC08L3Bob3Rvc2hvcDpMYXllclRleHQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6N2NkMzQxNzctOWYyZi0yNDRiLWEyYjQtMzU1MzJkY2Y1MWJiPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6M2E1YzgxYmYtYjhiNy0xMWU3LTk0NDktYTQ2MzdlZjJkNjMzPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jcmVhdGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE3LTEwLTI0VDEzOjMxOjMwKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjdjZDM0MTc3LTlmMmYtMjQ0Yi1hMmI0LTM1NTMyZGNmNTFiYjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjYwQzVBRTY1RjY5Q0U0MTE5NDVBODU1RTNCQ0E3RUVCPC9zdFJlZjpkb2N1bWVudElEPgogICAgICAgICAgICA8c3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pse7bzcAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAA1JJREFUeNrsm1+OmlAUhz+aeS9dwZggJn1AnRUMO6jpBgZXULuC2hWUWUGZBTSxKyiuoA4mfUBMnB04K5g+9DihRBHlyh/lJLwIXLgf99xzzu9etZeXFy7Z3nDh1gBoAFy4XeVtQNO0zNcapmUDfUBPnFoBfhQGq6IBaHmjwD4Ahmk5wAD4kKG5J8CNwsAFaHe6DvA9cc0wCgOv8gDka3vA9RHNPgo0D7hNnJtGYWBXxgV2dH4MfMnRRA+Y1WIO2NJ5F/ikoKm3tYsChmkNFHW+fmHQMC1dfHaXPQP3wM1yMdc2B/AOGALTWobBmI1Shu0UGCwX83XyRBQGawHntTtdG5gUNfxVu4CTNqNv6/wWGL7kCc+1AmCYVisl3I2ydD4GYZUCs7IjoLXrxHIx9w9tLAqDCfBwDrXAY457x+cAoCfuwRGjYFUnAGk+PsjR7s8Dn1VeLWCYVlpDw+VivjVHSHt+u9PVJbzGzZXQWTkAkz0V31fATUaEsjVJlQBs4FeGcteLgzgbAALBA+4y3voAeJL8nA0AHfClnM1qm1HhnYUidCSE+KzvSSJUTwAxCOMcpfETMFYpfRUKIAbCFhC3OTJJJwqDWS0BxED0JZ4Pjix1P2+E0loCSMBwyK4S/xc1ojBwag8gMU84cvTKGgmlAYhngu1O9xAXuVE5J1QCQCz3bwHuHvdQui5QKQAxEO6eEKpsFCgTRSXkvdoxSlBMCxhJJbgrrbZRtHCiShN0pRB6PeQ3ckBw2K0oKXMBVYJIP+Nvh9qulFivGoBt1lLQxowT2ykBXCfnhZIglgYACWmqXQv+baioBYCeiCQHm+QEg1O7RhF7hO4OhSAhcJKSFU7qBGADwZeqMMuXn6TUBw8qlaMrirNb4LdhWlP+SWD+cjFfxTpuS2GUpik+o3jFSEkqbJiWn0P0OMSGqlWiOu0TvD+FRHZKAE+oW+cfRmEwqlsesJJEJs8y91QqP+9UL6lqEtz2gpuNEY5sm9sIHln2DRa2aFKGJtiXkZEMiWtgVvRKUSUFkSKt2S7fAGgAXLYpmQQXf36MUChTZdUa2u8/rkvPA6Tz30r4eH3ybcBS5gJ6SaNXb+aABkA1AMxKenclBZLW/He4cYEGwEXb3wEASelexk6LIIIAAAAASUVORK5CYII=">'},I.Converter=function(g){"use strict";function C(g,C){if(C=C||null,I.helper.isString(g)){if(g=I.helper.stdExtName(g),C=g,I.extensions[g])return console.warn("DEPRECATION WARNING: "+g+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"),void function(g,C){"function"==typeof g&&(g=g(new I.Converter));I.helper.isArray(g)||(g=[g]);var e=A(g,C);if(!e.valid)throw Error(e.error);for(var r=0;r<g.length;++r)switch(g[r].type){case"lang":s.push(g[r]);break;case"output":i.push(g[r]);break;default:throw Error("Extension loader error: Type unrecognized!!!")}}(I.extensions[g],g);if(I.helper.isUndefined(r[g]))throw Error('Extension "'+g+'" could not be loaded. It was either not found or is not a valid extension.');g=r[g]}"function"==typeof g&&(g=g()),I.helper.isArray(g)||(g=[g]);var t=A(g,C);if(!t.valid)throw Error(t.error);for(var a=0;a<g.length;++a){switch(g[a].type){case"lang":s.push(g[a]);break;case"output":i.push(g[a])}if(g[a].hasOwnProperty("listeners"))for(var n in g[a].listeners)g[a].listeners.hasOwnProperty(n)&&e(n,g[a].listeners[n])}}function e(g,A){if(!I.helper.isString(g))throw Error("Invalid argument in converter.listen() method: name must be a string, but "+typeof g+" given");if("function"!=typeof A)throw Error("Invalid argument in converter.listen() method: callback must be a function, but "+typeof A+" given");l.hasOwnProperty(g)||(l[g]=[]),l[g].push(A)}var o={},s=[],i=[],l={},c=a,u={parsed:{},raw:"",format:""};!function(){g=g||{};for(var A in t)t.hasOwnProperty(A)&&(o[A]=t[A]);if("object"!=typeof g)throw Error("Converter expects the passed parameter to be an object, but "+typeof g+" was passed instead.");for(var e in g)g.hasOwnProperty(e)&&(o[e]=g[e]);o.extensions&&I.helper.forEach(o.extensions,C)}(),this._dispatch=function(g,A,C,I){if(l.hasOwnProperty(g))for(var e=0;e<l[g].length;++e){var r=l[g][e](g,A,this,C,I);r&&void 0!==r&&(A=r)}return A},this.listen=function(g,A){return e(g,A),this},this.makeHtml=function(g){if(!g)return g;var A={gHtmlBlocks:[],gHtmlMdBlocks:[],gHtmlSpans:[],gUrls:{},gTitles:{},gDimensions:{},gListLevel:0,hashLinkCounts:{},langExtensions:s,outputModifiers:i,converter:this,ghCodeBlocks:[],metadata:{parsed:{},raw:"",format:""}};return g=g.replace(/¨/g,"¨T"),g=g.replace(/\$/g,"¨D"),g=g.replace(/\r\n/g,"\n"),g=g.replace(/\r/g,"\n"),g=g.replace(/\u00A0/g," "),o.smartIndentationFix&&(g=function(g){var A=g.match(/^\s*/)[0].length,C=new RegExp("^\\s{0,"+A+"}","gm");return g.replace(C,"")}(g)),g="\n\n"+g+"\n\n",g=I.subParser("detab")(g,o,A),g=g.replace(/^[ \t]+$/gm,""),I.helper.forEach(s,function(C){g=I.subParser("runExtension")(C,g,o,A)}),g=I.subParser("metadata")(g,o,A),g=I.subParser("hashPreCodeTags")(g,o,A),g=I.subParser("githubCodeBlocks")(g,o,A),g=I.subParser("hashHTMLBlocks")(g,o,A),g=I.subParser("hashCodeTags")(g,o,A),g=I.subParser("stripLinkDefinitions")(g,o,A),g=I.subParser("blockGamut")(g,o,A),g=I.subParser("unhashHTMLSpans")(g,o,A),g=I.subParser("unescapeSpecialChars")(g,o,A),g=g.replace(/¨D/g,"$$"),g=g.replace(/¨T/g,"¨"),g=I.subParser("completeHTMLDocument")(g,o,A),I.helper.forEach(i,function(C){g=I.subParser("runExtension")(C,g,o,A)}),u=A.metadata,g},this.setOption=function(g,A){o[g]=A},this.getOption=function(g){return o[g]},this.getOptions=function(){return o},this.addExtension=function(g,A){C(g,A=A||null)},this.useExtension=function(g){C(g)},this.setFlavor=function(g){if(!n.hasOwnProperty(g))throw Error(g+" flavor was not found");var A=n[g];c=g;for(var C in A)A.hasOwnProperty(C)&&(o[C]=A[C])},this.getFlavor=function(){return c},this.removeExtension=function(g){I.helper.isArray(g)||(g=[g]);for(var A=0;A<g.length;++A){for(var C=g[A],e=0;e<s.length;++e)s[e]===C&&s[e].splice(e,1);for(;0<i.length;++e)i[0]===C&&i[0].splice(e,1)}},this.getAllExtensions=function(){return{language:s,output:i}},this.getMetadata=function(g){return g?u.raw:u.parsed},this.getMetadataFormat=function(){return u.format},this._setMetadataPair=function(g,A){u.parsed[g]=A},this._setMetadataFormat=function(g){u.format=g},this._setMetadataRaw=function(g){u.raw=g}},I.subParser("anchors",function(g,A,C){"use strict";var e=function(g,e,r,t,a,n,o){if(I.helper.isUndefined(o)&&(o=""),r=r.toLowerCase(),g.search(/\(<?\s*>? ?(['"].*['"])?\)$/m)>-1)t="";else if(!t){if(r||(r=e.toLowerCase().replace(/ ?\n/g," ")),t="#"+r,I.helper.isUndefined(C.gUrls[r]))return g;t=C.gUrls[r],I.helper.isUndefined(C.gTitles[r])||(o=C.gTitles[r])}var s='<a href="'+(t=t.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"';return""!==o&&null!==o&&(s+=' title="'+(o=(o=o.replace(/"/g,""")).replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"'),A.openLinksInNewWindow&&!/^#/.test(t)&&(s+=' target="¨E95Eblank"'),s+=">"+e+"</a>"};return g=(g=C.converter._dispatch("anchors.before",g,A,C)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g,e),g=g.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,e),g=g.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,e),g=g.replace(/\[([^\[\]]+)]()()()()()/g,e),A.ghMentions&&(g=g.replace(/(^|\s)(\\)?(@([a-z\d\-]+))(?=[.!?;,[\]()]|\s|$)/gim,function(g,C,e,r,t){if("\\"===e)return C+r;if(!I.helper.isString(A.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");var a=A.ghMentionsLink.replace(/\{u}/g,t),n="";return A.openLinksInNewWindow&&(n=' target="¨E95Eblank"'),C+'<a href="'+a+'"'+n+">"+r+"</a>"})),g=C.converter._dispatch("anchors.after",g,A,C)});var s=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,i=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,l=/()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,c=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,u=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,d=function(g){"use strict";return function(A,C,e,r,t,a,n){var o=e=e.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback),s="",i="",l=C||"",c=n||"";return/^www\./i.test(e)&&(e=e.replace(/^www\./i,"http://www.")),g.excludeTrailingPunctuationFromURLs&&a&&(s=a),g.openLinksInNewWindow&&(i=' target="¨E95Eblank"'),l+'<a href="'+e+'"'+i+">"+o+"</a>"+s+c}},p=function(g,A){"use strict";return function(C,e,r){var t="mailto:";return e=e||"",r=I.subParser("unescapeSpecialChars")(r,g,A),g.encodeEmails?(t=I.helper.encodeEmailAddress(t+r),r=I.helper.encodeEmailAddress(r)):t+=r,e+'<a href="'+t+'">'+r+"</a>"}};I.subParser("autoLinks",function(g,A,C){"use strict";return g=C.converter._dispatch("autoLinks.before",g,A,C),g=g.replace(l,d(A)),g=g.replace(u,p(A,C)),g=C.converter._dispatch("autoLinks.after",g,A,C)}),I.subParser("simplifiedAutoLinks",function(g,A,C){"use strict";return A.simplifiedAutoLink?(g=C.converter._dispatch("simplifiedAutoLinks.before",g,A,C),g=A.excludeTrailingPunctuationFromURLs?g.replace(i,d(A)):g.replace(s,d(A)),g=g.replace(c,p(A,C)),g=C.converter._dispatch("simplifiedAutoLinks.after",g,A,C)):g}),I.subParser("blockGamut",function(g,A,C){"use strict";return g=C.converter._dispatch("blockGamut.before",g,A,C),g=I.subParser("blockQuotes")(g,A,C),g=I.subParser("headers")(g,A,C),g=I.subParser("horizontalRule")(g,A,C),g=I.subParser("lists")(g,A,C),g=I.subParser("codeBlocks")(g,A,C),g=I.subParser("tables")(g,A,C),g=I.subParser("hashHTMLBlocks")(g,A,C),g=I.subParser("paragraphs")(g,A,C),g=C.converter._dispatch("blockGamut.after",g,A,C)}),I.subParser("blockQuotes",function(g,A,C){"use strict";g=C.converter._dispatch("blockQuotes.before",g,A,C),g+="\n\n";var e=/(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;return A.splitAdjacentBlockquotes&&(e=/^ {0,3}>[\s\S]*?(?:\n\n)/gm),g=g.replace(e,function(g){return g=g.replace(/^[ \t]*>[ \t]?/gm,""),g=g.replace(/¨0/g,""),g=g.replace(/^[ \t]+$/gm,""),g=I.subParser("githubCodeBlocks")(g,A,C),g=I.subParser("blockGamut")(g,A,C),g=g.replace(/(^|\n)/g,"$1 "),g=g.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm,function(g,A){var C=A;return C=C.replace(/^ /gm,"¨0"),C=C.replace(/¨0/g,"")}),I.subParser("hashBlock")("<blockquote>\n"+g+"\n</blockquote>",A,C)}),g=C.converter._dispatch("blockQuotes.after",g,A,C)}),I.subParser("codeBlocks",function(g,A,C){"use strict";g=C.converter._dispatch("codeBlocks.before",g,A,C);return g=(g+="¨0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g,function(g,e,r){var t=e,a=r,n="\n";return t=I.subParser("outdent")(t,A,C),t=I.subParser("encodeCode")(t,A,C),t=I.subParser("detab")(t,A,C),t=t.replace(/^\n+/g,""),t=t.replace(/\n+$/g,""),A.omitExtraWLInCodeBlocks&&(n=""),t="<pre><code>"+t+n+"</code></pre>",I.subParser("hashBlock")(t,A,C)+a}),g=g.replace(/¨0/,""),g=C.converter._dispatch("codeBlocks.after",g,A,C)}),I.subParser("codeSpans",function(g,A,C){"use strict";return void 0===(g=C.converter._dispatch("codeSpans.before",g,A,C))&&(g=""),g=g.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(g,e,r,t){var a=t;return a=a.replace(/^([ \t]*)/g,""),a=a.replace(/[ \t]*$/g,""),a=I.subParser("encodeCode")(a,A,C),a=e+"<code>"+a+"</code>",a=I.subParser("hashHTMLSpans")(a,A,C)}),g=C.converter._dispatch("codeSpans.after",g,A,C)}),I.subParser("completeHTMLDocument",function(g,A,C){"use strict";if(!A.completeHTMLDocument)return g;g=C.converter._dispatch("completeHTMLDocument.before",g,A,C);var I="html",e="<!DOCTYPE HTML>\n",r="",t='<meta charset="utf-8">\n',a="",n="";void 0!==C.metadata.parsed.doctype&&(e="<!DOCTYPE "+C.metadata.parsed.doctype+">\n","html"!==(I=C.metadata.parsed.doctype.toString().toLowerCase())&&"html5"!==I||(t='<meta charset="utf-8">'));for(var o in C.metadata.parsed)if(C.metadata.parsed.hasOwnProperty(o))switch(o.toLowerCase()){case"doctype":break;case"title":r="<title>"+C.metadata.parsed.title+"</title>\n";break;case"charset":t="html"===I||"html5"===I?'<meta charset="'+C.metadata.parsed.charset+'">\n':'<meta name="charset" content="'+C.metadata.parsed.charset+'">\n';break;case"language":case"lang":a=' lang="'+C.metadata.parsed[o]+'"',n+='<meta name="'+o+'" content="'+C.metadata.parsed[o]+'">\n';break;default:n+='<meta name="'+o+'" content="'+C.metadata.parsed[o]+'">\n'}return g=e+"<html"+a+">\n<head>\n"+r+t+n+"</head>\n<body>\n"+g.trim()+"\n</body>\n</html>",g=C.converter._dispatch("completeHTMLDocument.after",g,A,C)}),I.subParser("detab",function(g,A,C){"use strict";return g=C.converter._dispatch("detab.before",g,A,C),g=g.replace(/\t(?=\t)/g," "),g=g.replace(/\t/g,"¨A¨B"),g=g.replace(/¨B(.+?)¨A/g,function(g,A){for(var C=A,I=4-C.length%4,e=0;e<I;e++)C+=" ";return C}),g=g.replace(/¨A/g," "),g=g.replace(/¨B/g,""),g=C.converter._dispatch("detab.after",g,A,C)}),I.subParser("ellipsis",function(g,A,C){"use strict";return g=C.converter._dispatch("ellipsis.before",g,A,C),g=g.replace(/\.\.\./g,"…"),g=C.converter._dispatch("ellipsis.after",g,A,C)}),I.subParser("emoji",function(g,A,C){"use strict";if(!A.emoji)return g;return g=(g=C.converter._dispatch("emoji.before",g,A,C)).replace(/:([\S]+?):/g,function(g,A){return I.helper.emojis.hasOwnProperty(A)?I.helper.emojis[A]:g}),g=C.converter._dispatch("emoji.after",g,A,C)}),I.subParser("encodeAmpsAndAngles",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeAmpsAndAngles.before",g,A,C),g=g.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&"),g=g.replace(/<(?![a-z\/?$!])/gi,"<"),g=g.replace(/</g,"<"),g=g.replace(/>/g,">"),g=C.converter._dispatch("encodeAmpsAndAngles.after",g,A,C)}),I.subParser("encodeBackslashEscapes",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeBackslashEscapes.before",g,A,C),g=g.replace(/\\(\\)/g,I.helper.escapeCharactersCallback),g=g.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("encodeBackslashEscapes.after",g,A,C)}),I.subParser("encodeCode",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeCode.before",g,A,C),g=g.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/([*_{}\[\]\\=~-])/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("encodeCode.after",g,A,C)}),I.subParser("escapeSpecialCharsWithinTagAttributes",function(g,A,C){"use strict";return g=(g=C.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",g,A,C)).replace(/<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,function(g){return g.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,I.helper.escapeCharactersCallback)}),g=g.replace(/<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi,function(g){return g.replace(/([\\`*_~=|])/g,I.helper.escapeCharactersCallback)}),g=C.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",g,A,C)}),I.subParser("githubCodeBlocks",function(g,A,C){"use strict";return A.ghCodeBlocks?(g=C.converter._dispatch("githubCodeBlocks.before",g,A,C),g+="¨0",g=g.replace(/(?:^|\n)(```+|~~~+)([^\s`~]*)\n([\s\S]*?)\n\1/g,function(g,e,r,t){var a=A.omitExtraWLInCodeBlocks?"":"\n";return t=I.subParser("encodeCode")(t,A,C),t=I.subParser("detab")(t,A,C),t=t.replace(/^\n+/g,""),t=t.replace(/\n+$/g,""),t="<pre><code"+(r?' class="'+r+" language-"+r+'"':"")+">"+t+a+"</code></pre>",t=I.subParser("hashBlock")(t,A,C),"\n\n¨G"+(C.ghCodeBlocks.push({text:g,codeblock:t})-1)+"G\n\n"}),g=g.replace(/¨0/,""),C.converter._dispatch("githubCodeBlocks.after",g,A,C)):g}),I.subParser("hashBlock",function(g,A,C){"use strict";return g=C.converter._dispatch("hashBlock.before",g,A,C),g=g.replace(/(^\n+|\n+$)/g,""),g="\n\n¨K"+(C.gHtmlBlocks.push(g)-1)+"K\n\n",g=C.converter._dispatch("hashBlock.after",g,A,C)}),I.subParser("hashCodeTags",function(g,A,C){"use strict";g=C.converter._dispatch("hashCodeTags.before",g,A,C);return g=I.helper.replaceRecursiveRegExp(g,function(g,e,r,t){var a=r+I.subParser("encodeCode")(e,A,C)+t;return"¨C"+(C.gHtmlSpans.push(a)-1)+"C"},"<code\\b[^>]*>","</code>","gim"),g=C.converter._dispatch("hashCodeTags.after",g,A,C)}),I.subParser("hashElement",function(g,A,C){"use strict";return function(g,A){var I=A;return I=I.replace(/\n\n/g,"\n"),I=I.replace(/^\n/,""),I=I.replace(/\n+$/g,""),I="\n\n¨K"+(C.gHtmlBlocks.push(I)-1)+"K\n\n"}}),I.subParser("hashHTMLBlocks",function(g,A,C){"use strict";g=C.converter._dispatch("hashHTMLBlocks.before",g,A,C);var e=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"],r=function(g,A,I,e){var r=g;return-1!==I.search(/\bmarkdown\b/)&&(r=I+C.converter.makeHtml(A)+e),"\n\n¨K"+(C.gHtmlBlocks.push(r)-1)+"K\n\n"};A.backslashEscapesHTMLTags&&(g=g.replace(/\\<(\/?[^>]+?)>/g,function(g,A){return"<"+A+">"}));for(var t=0;t<e.length;++t)for(var a,n=new RegExp("^ {0,3}(<"+e[t]+"\\b[^>]*>)","im"),o="<"+e[t]+"\\b[^>]*>",s="</"+e[t]+">";-1!==(a=I.helper.regexIndexOf(g,n));){var i=I.helper.splitAtIndex(g,a),l=I.helper.replaceRecursiveRegExp(i[1],r,o,s,"im");if(l===i[1])break;g=i[0].concat(l)}return g=g.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,I.subParser("hashElement")(g,A,C)),g=I.helper.replaceRecursiveRegExp(g,function(g){return"\n\n¨K"+(C.gHtmlBlocks.push(g)-1)+"K\n\n"},"^ {0,3}\x3c!--","--\x3e","gm"),g=g.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,I.subParser("hashElement")(g,A,C)),g=C.converter._dispatch("hashHTMLBlocks.after",g,A,C)}),I.subParser("hashHTMLSpans",function(g,A,C){"use strict";function I(g){return"¨C"+(C.gHtmlSpans.push(g)-1)+"C"}return g=C.converter._dispatch("hashHTMLSpans.before",g,A,C),g=g.replace(/<[^>]+?\/>/gi,function(g){return I(g)}),g=g.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,function(g){return I(g)}),g=g.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,function(g){return I(g)}),g=g.replace(/<[^>]+?>/gi,function(g){return I(g)}),g=C.converter._dispatch("hashHTMLSpans.after",g,A,C)}),I.subParser("unhashHTMLSpans",function(g,A,C){"use strict";g=C.converter._dispatch("unhashHTMLSpans.before",g,A,C);for(var I=0;I<C.gHtmlSpans.length;++I){for(var e=C.gHtmlSpans[I],r=0;/¨C(\d+)C/.test(e);){var t=RegExp.$1;if(e=e.replace("¨C"+t+"C",C.gHtmlSpans[t]),10===r){console.error("maximum nesting of 10 spans reached!!!");break}++r}g=g.replace("¨C"+I+"C",e)}return g=C.converter._dispatch("unhashHTMLSpans.after",g,A,C)}),I.subParser("hashPreCodeTags",function(g,A,C){"use strict";g=C.converter._dispatch("hashPreCodeTags.before",g,A,C);return g=I.helper.replaceRecursiveRegExp(g,function(g,e,r,t){var a=r+I.subParser("encodeCode")(e,A,C)+t;return"\n\n¨G"+(C.ghCodeBlocks.push({text:g,codeblock:a})-1)+"G\n\n"},"^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>","^ {0,3}</code>\\s*</pre>","gim"),g=C.converter._dispatch("hashPreCodeTags.after",g,A,C)}),I.subParser("headers",function(g,A,C){"use strict";function e(g){var e,r;if(A.customizedHeaderId){var t=g.match(/\{([^{]+?)}\s*$/);t&&t[1]&&(g=t[1])}return e=g,r=I.helper.isString(A.prefixHeaderId)?A.prefixHeaderId:!0===A.prefixHeaderId?"section-":"",A.rawPrefixHeaderId||(e=r+e),e=A.ghCompatibleHeaderId?e.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,"").toLowerCase():A.rawHeaderId?e.replace(/ /g,"-").replace(/&/g,"&").replace(/¨T/g,"¨").replace(/¨D/g,"$").replace(/["']/g,"-").toLowerCase():e.replace(/[^\w]/g,"").toLowerCase(),A.rawPrefixHeaderId&&(e=r+e),C.hashLinkCounts[e]?e=e+"-"+C.hashLinkCounts[e]++:C.hashLinkCounts[e]=1,e}g=C.converter._dispatch("headers.before",g,A,C);var r=isNaN(parseInt(A.headerLevelStart))?1:parseInt(A.headerLevelStart),t=A.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,a=A.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm;g=(g=g.replace(t,function(g,t){var a=I.subParser("spanGamut")(t,A,C),n=A.noHeaderId?"":' id="'+e(t)+'"',o="<h"+r+n+">"+a+"</h"+r+">";return I.subParser("hashBlock")(o,A,C)})).replace(a,function(g,t){var a=I.subParser("spanGamut")(t,A,C),n=A.noHeaderId?"":' id="'+e(t)+'"',o=r+1,s="<h"+o+n+">"+a+"</h"+o+">";return I.subParser("hashBlock")(s,A,C)});var n=A.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;return g=g.replace(n,function(g,t,a){var n=a;A.customizedHeaderId&&(n=a.replace(/\s?\{([^{]+?)}\s*$/,""));var o=I.subParser("spanGamut")(n,A,C),s=A.noHeaderId?"":' id="'+e(a)+'"',i=r-1+t.length,l="<h"+i+s+">"+o+"</h"+i+">";return I.subParser("hashBlock")(l,A,C)}),g=C.converter._dispatch("headers.after",g,A,C)}),I.subParser("horizontalRule",function(g,A,C){"use strict";g=C.converter._dispatch("horizontalRule.before",g,A,C);var e=I.subParser("hashBlock")("<hr />",A,C);return g=g.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,e),g=g.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,e),g=g.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,e),g=C.converter._dispatch("horizontalRule.after",g,A,C)}),I.subParser("images",function(g,A,C){"use strict";function e(g,A,e,r,t,a,n,o){var s=C.gUrls,i=C.gTitles,l=C.gDimensions;if(e=e.toLowerCase(),o||(o=""),g.search(/\(<?\s*>? ?(['"].*['"])?\)$/m)>-1)r="";else if(""===r||null===r){if(""!==e&&null!==e||(e=A.toLowerCase().replace(/ ?\n/g," ")),r="#"+e,I.helper.isUndefined(s[e]))return g;r=s[e],I.helper.isUndefined(i[e])||(o=i[e]),I.helper.isUndefined(l[e])||(t=l[e].width,a=l[e].height)}A=A.replace(/"/g,""").replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback);var c='<img src="'+(r=r.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'" alt="'+A+'"';return o&&(c+=' title="'+(o=o.replace(/"/g,""").replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"'),t&&a&&(c+=' width="'+(t="*"===t?"auto":t)+'"',c+=' height="'+(a="*"===a?"auto":a)+'"'),c+=" />"}return g=(g=C.converter._dispatch("images.before",g,A,C)).replace(/!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,e),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,function(g,A,C,I,r,t,a,n){return I=I.replace(/\s/g,""),e(g,A,C,I,r,t,0,n)}),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,e),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,e),g=g.replace(/!\[([^\[\]]+)]()()()()()/g,e),g=C.converter._dispatch("images.after",g,A,C)}),I.subParser("italicsAndBold",function(g,A,C){"use strict";function I(g,A,C){return A+g+C}return g=C.converter._dispatch("italicsAndBold.before",g,A,C),g=A.literalMidWordUnderscores?(g=(g=g.replace(/\b___(\S[\s\S]*)___\b/g,function(g,A){return I(A,"<strong><em>","</em></strong>")})).replace(/\b__(\S[\s\S]*)__\b/g,function(g,A){return I(A,"<strong>","</strong>")})).replace(/\b_(\S[\s\S]*?)_\b/g,function(g,A){return I(A,"<em>","</em>")}):(g=(g=g.replace(/___(\S[\s\S]*?)___/g,function(g,A){return/\S$/.test(A)?I(A,"<strong><em>","</em></strong>"):g})).replace(/__(\S[\s\S]*?)__/g,function(g,A){return/\S$/.test(A)?I(A,"<strong>","</strong>"):g})).replace(/_([^\s_][\s\S]*?)_/g,function(g,A){return/\S$/.test(A)?I(A,"<em>","</em>"):g}),g=A.literalMidWordAsterisks?(g=(g=g.replace(/([^*]|^)\B\*\*\*(\S[\s\S]+?)\*\*\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<strong><em>","</em></strong>")})).replace(/([^*]|^)\B\*\*(\S[\s\S]+?)\*\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<strong>","</strong>")})).replace(/([^*]|^)\B\*(\S[\s\S]+?)\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<em>","</em>")}):(g=(g=g.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,function(g,A){return/\S$/.test(A)?I(A,"<strong><em>","</em></strong>"):g})).replace(/\*\*(\S[\s\S]*?)\*\*/g,function(g,A){return/\S$/.test(A)?I(A,"<strong>","</strong>"):g})).replace(/\*([^\s*][\s\S]*?)\*/g,function(g,A){return/\S$/.test(A)?I(A,"<em>","</em>"):g}),g=C.converter._dispatch("italicsAndBold.after",g,A,C)}),I.subParser("lists",function(g,A,C){"use strict";function e(g,e){C.gListLevel++,g=g.replace(/\n{2,}$/,"\n");var r=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,t=/\n[ \t]*\n(?!¨0)/.test(g+="¨0");return A.disableForced4SpacesIndentedSublists&&(r=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),g=g.replace(r,function(g,e,r,a,n,o,s){s=s&&""!==s.trim();var i=I.subParser("outdent")(n,A,C),l="";return o&&A.tasklists&&(l=' class="task-list-item" style="list-style-type: none;"',i=i.replace(/^[ \t]*\[(x|X| )?]/m,function(){var g='<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';return s&&(g+=" checked"),g+=">"})),i=i.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g,function(g){return"¨A"+g}),e||i.search(/\n{2,}/)>-1?(i=I.subParser("githubCodeBlocks")(i,A,C),i=I.subParser("blockGamut")(i,A,C)):(i=(i=I.subParser("lists")(i,A,C)).replace(/\n$/,""),i=(i=I.subParser("hashHTMLBlocks")(i,A,C)).replace(/\n\n+/g,"\n\n"),i=t?I.subParser("paragraphs")(i,A,C):I.subParser("spanGamut")(i,A,C)),i=i.replace("¨A",""),i="<li"+l+">"+i+"</li>\n"}),g=g.replace(/¨0/g,""),C.gListLevel--,e&&(g=g.replace(/\s+$/,"")),g}function r(g,A){if("ol"===A){var C=g.match(/^ *(\d+)\./);if(C&&"1"!==C[1])return' start="'+C[1]+'"'}return""}function t(g,C,I){var t=A.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,a=A.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,n="ul"===C?t:a,o="";if(-1!==g.search(n))!function A(s){var i=s.search(n),l=r(g,C);-1!==i?(o+="\n\n<"+C+l+">\n"+e(s.slice(0,i),!!I)+"</"+C+">\n",n="ul"===(C="ul"===C?"ol":"ul")?t:a,A(s.slice(i))):o+="\n\n<"+C+l+">\n"+e(s,!!I)+"</"+C+">\n"}(g);else{var s=r(g,C);o="\n\n<"+C+s+">\n"+e(g,!!I)+"</"+C+">\n"}return o}return g=C.converter._dispatch("lists.before",g,A,C),g+="¨0",g=C.gListLevel?g.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(g,A,C){return t(A,C.search(/[*+-]/g)>-1?"ul":"ol",!0)}):g.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(g,A,C,I){return t(C,I.search(/[*+-]/g)>-1?"ul":"ol",!1)}),g=g.replace(/¨0/,""),g=C.converter._dispatch("lists.after",g,A,C)}),I.subParser("metadata",function(g,A,C){"use strict";function I(g){C.metadata.raw=g,(g=(g=g.replace(/&/g,"&").replace(/"/g,""")).replace(/\n {4}/g," ")).replace(/^([\S ]+): +([\s\S]+?)$/gm,function(g,A,I){return C.metadata.parsed[A]=I,""})}return A.metadata?(g=C.converter._dispatch("metadata.before",g,A,C),g=g.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/,function(g,A,C){return I(C),"¨M"}),g=g.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/,function(g,A,e){return A&&(C.metadata.format=A),I(e),"¨M"}),g=g.replace(/¨M/g,""),g=C.converter._dispatch("metadata.after",g,A,C)):g}),I.subParser("outdent",function(g,A,C){"use strict";return g=C.converter._dispatch("outdent.before",g,A,C),g=g.replace(/^(\t|[ ]{1,4})/gm,"¨0"),g=g.replace(/¨0/g,""),g=C.converter._dispatch("outdent.after",g,A,C)}),I.subParser("paragraphs",function(g,A,C){"use strict";for(var e=(g=(g=(g=C.converter._dispatch("paragraphs.before",g,A,C)).replace(/^\n+/g,"")).replace(/\n+$/g,"")).split(/\n{2,}/g),r=[],t=e.length,a=0;a<t;a++){var n=e[a];n.search(/¨(K|G)(\d+)\1/g)>=0?r.push(n):n.search(/\S/)>=0&&(n=(n=I.subParser("spanGamut")(n,A,C)).replace(/^([ \t]*)/g,"<p>"),n+="</p>",r.push(n))}for(t=r.length,a=0;a<t;a++){for(var o="",s=r[a],i=!1;/¨(K|G)(\d+)\1/.test(s);){var l=RegExp.$1,c=RegExp.$2;o=(o="K"===l?C.gHtmlBlocks[c]:i?I.subParser("encodeCode")(C.ghCodeBlocks[c].text,A,C):C.ghCodeBlocks[c].codeblock).replace(/\$/g,"$$$$"),s=s.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/,o),/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(s)&&(i=!0)}r[a]=s}return g=r.join("\n"),g=g.replace(/^\n+/g,""),g=g.replace(/\n+$/g,""),C.converter._dispatch("paragraphs.after",g,A,C)}),I.subParser("runExtension",function(g,A,C,I){"use strict";if(g.filter)A=g.filter(A,I.converter,C);else if(g.regex){var e=g.regex;e instanceof RegExp||(e=new RegExp(e,"g")),A=A.replace(e,g.replace)}return A}),I.subParser("spanGamut",function(g,A,C){"use strict";return g=C.converter._dispatch("spanGamut.before",g,A,C),g=I.subParser("codeSpans")(g,A,C),g=I.subParser("escapeSpecialCharsWithinTagAttributes")(g,A,C),g=I.subParser("encodeBackslashEscapes")(g,A,C),g=I.subParser("images")(g,A,C),g=I.subParser("anchors")(g,A,C),g=I.subParser("autoLinks")(g,A,C),g=I.subParser("simplifiedAutoLinks")(g,A,C),g=I.subParser("emoji")(g,A,C),g=I.subParser("underline")(g,A,C),g=I.subParser("italicsAndBold")(g,A,C),g=I.subParser("strikethrough")(g,A,C),g=I.subParser("ellipsis")(g,A,C),g=I.subParser("hashHTMLSpans")(g,A,C),g=I.subParser("encodeAmpsAndAngles")(g,A,C),A.simpleLineBreaks?/\n\n¨K/.test(g)||(g=g.replace(/\n+/g,"<br />\n")):g=g.replace(/ +\n/g,"<br />\n"),g=C.converter._dispatch("spanGamut.after",g,A,C)}),I.subParser("strikethrough",function(g,A,C){"use strict";return A.strikethrough&&(g=(g=C.converter._dispatch("strikethrough.before",g,A,C)).replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,function(g,e){return function(g){return A.simplifiedAutoLink&&(g=I.subParser("simplifiedAutoLinks")(g,A,C)),"<del>"+g+"</del>"}(e)}),g=C.converter._dispatch("strikethrough.after",g,A,C)),g}),I.subParser("stripLinkDefinitions",function(g,A,C){"use strict";var e=function(g,e,r,t,a,n,o){return e=e.toLowerCase(),r.match(/^data:.+?\/.+?;base64,/)?C.gUrls[e]=r.replace(/\s/g,""):C.gUrls[e]=I.subParser("encodeAmpsAndAngles")(r,A,C),n?n+o:(o&&(C.gTitles[e]=o.replace(/"|'/g,""")),A.parseImgDimensions&&t&&a&&(C.gDimensions[e]={width:t,height:a}),"")};return g=(g+="¨0").replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm,e),g=g.replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,e),g=g.replace(/¨0/,"")}),I.subParser("tables",function(g,A,C){"use strict";function e(g){return/^:[ \t]*--*$/.test(g)?' style="text-align:left;"':/^--*[ \t]*:[ \t]*$/.test(g)?' style="text-align:right;"':/^:[ \t]*--*[ \t]*:$/.test(g)?' style="text-align:center;"':""}function r(g,e){var r="";return g=g.trim(),(A.tablesHeaderId||A.tableHeaderId)&&(r=' id="'+g.replace(/ /g,"_").toLowerCase()+'"'),g=I.subParser("spanGamut")(g,A,C),"<th"+r+e+">"+g+"</th>\n"}function t(g,e){return"<td"+e+">"+I.subParser("spanGamut")(g,A,C)+"</td>\n"}function a(g){var a,n=g.split("\n");for(a=0;a<n.length;++a)/^ {0,3}\|/.test(n[a])&&(n[a]=n[a].replace(/^ {0,3}\|/,"")),/\|[ \t]*$/.test(n[a])&&(n[a]=n[a].replace(/\|[ \t]*$/,"")),n[a]=I.subParser("codeSpans")(n[a],A,C);var o=n[0].split("|").map(function(g){return g.trim()}),s=n[1].split("|").map(function(g){return g.trim()}),i=[],l=[],c=[],u=[];for(n.shift(),n.shift(),a=0;a<n.length;++a)""!==n[a].trim()&&i.push(n[a].split("|").map(function(g){return g.trim()}));if(o.length<s.length)return g;for(a=0;a<s.length;++a)c.push(e(s[a]));for(a=0;a<o.length;++a)I.helper.isUndefined(c[a])&&(c[a]=""),l.push(r(o[a],c[a]));for(a=0;a<i.length;++a){for(var d=[],p=0;p<l.length;++p)I.helper.isUndefined(i[a][p]),d.push(t(i[a][p],c[p]));u.push(d)}return function(g,A){for(var C="<table>\n<thead>\n<tr>\n",I=g.length,e=0;e<I;++e)C+=g[e];for(C+="</tr>\n</thead>\n<tbody>\n",e=0;e<A.length;++e){C+="<tr>\n";for(var r=0;r<I;++r)C+=A[e][r];C+="</tr>\n"}return C+="</tbody>\n</table>\n"}(l,u)}if(!A.tables)return g;return g=C.converter._dispatch("tables.before",g,A,C),g=g.replace(/\\(\|)/g,I.helper.escapeCharactersCallback),g=g.replace(/^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,a),g=g.replace(/^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm,a),g=C.converter._dispatch("tables.after",g,A,C)}),I.subParser("underline",function(g,A,C){"use strict";return A.underline?(g=C.converter._dispatch("underline.before",g,A,C),g=A.literalMidWordUnderscores?g.replace(/\b_?__(\S[\s\S]*)___?\b/g,function(g,A){return"<u>"+A+"</u>"}):g.replace(/_?__(\S[\s\S]*?)___?/g,function(g,A){return/\S$/.test(A)?"<u>"+A+"</u>":g}),g=g.replace(/(_)/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("underline.after",g,A,C)):g}),I.subParser("unescapeSpecialChars",function(g,A,C){"use strict";return g=C.converter._dispatch("unescapeSpecialChars.before",g,A,C),g=g.replace(/¨E(\d+)E/g,function(g,A){var C=parseInt(A);return String.fromCharCode(C)}),g=C.converter._dispatch("unescapeSpecialChars.after",g,A,C)});"function"==typeof define&&define.amd?define(function(){"use strict";return I}):"undefined"!=typeof module&&module.exports?module.exports=I:this.showdown=I}).call(this); -//# sourceMappingURL=showdown.min.js.map diff --git a/www/vincent.demeester.fr/.fancyindex/styles.css b/www/vincent.demeester.fr/.fancyindex/styles.css @@ -1,196 +0,0 @@ -/* styles.css - * Better styling for of Nginx FancyIndex page - * © 2015-17, Lilian Besson (Naereen) and contributors, - * open-sourced under the MIT License, https://lbesson.mit-license.org/ - * hosted on GitHub, https://GitHub.com/Naereen/Nginx-Fancyindex-Theme - */ - -* { - font-family: 'Verdana', sans-serif; - margin: 0; - padding: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - color: #61666c; - font-weight: 300; - font-size: 1em; - line-height: 2em; -} - -body { - margin: 0 auto; - padding-top: 20px; - max-width: 800px; -} - -thead { - font-weight: 200; - font-size: 1.2em; -} - -h1 { - font-weight: 200; - text-align: center; - font-size: 1.4em; - line-height: 3em; -} - -a { - color: #5f5f5f; - text-decoration: none; -} - a:hover { - color: #000; - } - a.clear, a.clear:link, a.clear:visited { - color: #666; - padding: 2px 0; - font-weight: 400; - font-size: 14px; - margin: 0 0 0 20px; - line-height: 14px; - display: inline-block; - border-bottom: transparent 1px solid; - vertical-align: -10px; - -webkit-transition: all 300ms ease-in; - -moz-transition: all 300ms ease-in; - -ms-transition: all 300ms ease-in; - -o-transition: all 300ms ease-in; - transition: all 300ms ease-in; - } - -input { - margin: 0 auto; - font-size: 100%; - vertical-align: middle; - *overflow: visible; - line-height: normal; - font-family: 'Open Sans', sans-serif; - font-size: 12px; - font-weight: 300; - line-height: 18px; - color: #555; - display: inline-block; - height: 20px; - padding: 4px 32px 4px 6px; - margin-bottom: 9px; - font-size: 14px; - line-height: 20px; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - width: 196px; - background-color: #fff; - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -webkit-transition: border linear .2s,box-shadow linear .2s; - -moz-transition: border linear .2s,box-shadow linear .2s; - -o-transition: border linear .2s,box-shadow linear .2s; - transition: border linear .2s,box-shadow linear .2s; -} - input:focus { - outline: 0; - border-color: rgba(0,0,0,0.8); - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - } - input::-moz-focus-inner { - padding: 0; - border: 0; - } - -#search { - display: block; - margin-left: auto; - margin-right: auto; - width: 250px; - margin-top: 20px; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; - -webkit-transition: all 300ms ease-in; - -moz-transition: all 300ms ease-in; - -ms-transition: all 300ms ease-in; - -o-transition: all 300ms ease-in; - transition: all 300ms ease-in; -} - -table { - border-collapse: collapse; - font-size: 0.9em; - max-width: 100%; - margin: 20px auto 0; -} - -tr { - outline: 0; - border: 0; -} - tr:hover td { - background: #f6f6f6; - } - tr td:first-of-type { - padding-left: 10px; - padding-right: 10px; - } - tr.parent a { - color: #9099A3; - } - -th { - - text-align: left; - font-size: .75em; - padding-right: 20px; -} - th + th { - width: 25%; - } - th + th + th + th { - width: 5%; - } - -td { - padding: 5px 0; - outline: 0; - border: 0; - border-bottom: 1px solid #edf1f5; - vertical-align: middle; - text-align: left; - -webkit-transition: background 300ms ease-in; - -moz-transition: background 300ms ease-in; - -ms-transition: background 300ms ease-in; - -o-transition: background 300ms ease-in; - transition: background 300ms ease-in; -} - td:last-child,th:last-child { - text-align: right; - padding-right: 0; - } - td a { - display: block; - } - -.parent a:hover { - color: #2a2a2a; -} - -footer { - font-size:12px; - text-align:center; -} -footer a { - text-decoration: underline; - color:#990012; -} - -img { max-width: 100%; } diff --git a/www/vincent.demeester.fr/.gitignore b/www/vincent.demeester.fr/.gitignore @@ -1,2 +0,0 @@ -public/* -content/posts/index.org- \ No newline at end of file diff --git a/www/vincent.demeester.fr/Makefile b/www/vincent.demeester.fr/Makefile @@ -1,118 +0,0 @@ -# /Make/ it happen -# :PROPERTIES: -# :header-args: :tangle /etc/nixos/www/vincent.demeester.fr/Makefile -# :header-args+: :comments org -# :ID: 6191455e-95bc-4abc-a5f5-a62606ab2ea7 -# :END: -# -# In order to publish this website, I am using [[file:make.org][make]]. In a nutshell, I am going to define a -# few target to get the content from my notes, export org files into html and copy more or -# less everything to the =public= folder. I will also define a clean and a publish target. -# -# The first part of my =Makefile= will be to define some constants that I want to use later -# on. Those are mainly to easily change where to look for the notes or where the emacs -# configuration is. - - -EMACS = -ifndef EMACS -EMACS = "emacs" -endif - -DOTEMACS = -ifndef DOTEMACS -DOTEMACS = "~/.config/emacs" -endif - -PUBLISH = -ifndef PUBLISH -PUBLISH = vincent.demeester.fr -endif - -NOTES = ~/desktop/org/notes - - - -# The default target will be name =build=. - - -all: build - -# Building =public/= and publishing it -# :PROPERTIES: -# :ID: 853f3d6b-f385-4091-9f9e-b04d17794e5c -# :END: -# -# To build the website, we will be using [[file:emacs.org][Emacs]] in batch mode, with some shared library *and* -# the actual [[id:631ced7a-f3f7-4a77-81a8-4a1884a6c4d4][publish]] script. - - -.PHONY: build -build: lib/publish.el lib/publish-common.el build-articles - @echo "Publishing... with current Emacs configurations." - ${EMACS} --debug-init --batch --directory $(DOTEMACS)/lisp/ --directory $(DOTEMACS)/lisp/vorg/ \ - --load lib/publish-common.el --load lib/publish.el \ - --funcall publish - -.PHONY: build-articles -build-articles: $(NOTES) - rsync -arv --delete --copy-links --exclude='*.private.org' --exclude='*.db' $(NOTES)/ content/legacy/articles/ - -$(NOTES): - $(error $(NOTES) doesn't exists…) - - - -# The =publish= target is gonna be really simple: I just need to copy the content to -# =~/desktop/sites= on the current machine, and the rest is automated. - - -#rsync -a --progress --copy-links --delete public/assets/.fancyindex/ ~/desktop/sites/dl.sbr.pm/.fancyindex/ -#rsync -a --progress --copy-links --delete public/ ~/desktop/sites/${PUBLISH}/ -.PHONY: publish -publish: build - rsync -ave ssh --progress --copy-links --delete public/assets/.fancyindex/ kerkouane.vpn:/var/www/dl.sbr.pm/.fancyindex/ - rsync -ave ssh --progress --copy-links --delete public/ kerkouane.vpn:/var/www/${PUBLISH}/ - -# Local server -# :PROPERTIES: -# :ID: 0e26a52e-5f66-42c6-934d-b45cfc9745b2 -# :END: -# -# Let's use =miniserve= (using [[file:nix.org][Nix]] with =nix-shell=) to serve the static website locally to -# validate my changes. - - -.PHONY: serve -serve: - nix-shell -p miniserve --command "miniserve --port=8181 --index=index.html public/" - -# Final nits of the =Makefile= -# :PROPERTIES: -# :ID: 5bec22c8-491b-4e03-855a-4b5f859473cf -# :END: -# -# One of the final step is to install the git hooks if any. I tend to have this target in all my -# personal =Makefile= at least. Let's also define a =pre-commit= target that will hold -# anything we need to do at =pre-commit=. - - -.PHONY: install-hooks -install-hooks: - if [ -e .git ]; then nix-shell -p git --run 'git config core.hooksPath .githooks'; fi - -.PHONY: pre-commit -pre-commit: README.md - - - -# And the final target is the =clean= one. This will remove any compile emacs-lisp file -# (=*.elc=), the =public= folder, and some org-mode metadata. - - -.PHONY: clean -clean: - @echo "Cleaning up.." - @-rm -rvf *.elc - @-rm -rvf public - #@-rm -rv ~/.org-timestamps/* diff --git a/www/vincent.demeester.fr/README.org b/www/vincent.demeester.fr/README.org @@ -1,26 +0,0 @@ -#+TITLE: vincent.demeester.fr - -This is my website source code and content. Here lives /or should live/ all that matters and -is required to run and publish my website, anywhere. - -- It is statically published and can be build and browsed locally -- It is as simple, and reproductible as possible - + as little dependency as possible, most likely only =emacs= (if that's not too much already). - + using ~nix~ to make sure it is reproductible -- It is /temporal/, meaning if I change the style, theme, … the previous pages are still - using the one at their time. - -* Structure - -This repository holds the source of the website. The actual generated website is build, in -a reproducible manner, package and deployed. It can also be served locally, with tools -like =miniserve= or even without. - -- =content= holds the content, so =org= files or =html= files, … -- =public= holds the generated content. - -* Links - -- [[https://github.com/NixOS/nixos-homepage/blob/master/flake.nix][nixos homepage flake]] -- [[https://git.sr.ht/~aasg/haunted-blog][aasg's most experimental weblog – haunted edition]] — using flake - + [[https://sr.ht/~aasg/snowweb/][SnowWeb – a webserver for Nix flakes]] diff --git a/www/vincent.demeester.fr/assets/.fancyindex/HEADER.md b/www/vincent.demeester.fr/assets/.fancyindex/HEADER.md @@ -1,4 +0,0 @@ -# Test of a HEADER.md file -## Test of a HEADER.md file -### Test of a HEADER.md file -#### Test of a HEADER.md file diff --git a/www/vincent.demeester.fr/assets/.fancyindex/addNginxFancyIndexForm.js b/www/vincent.demeester.fr/assets/.fancyindex/addNginxFancyIndexForm.js @@ -1,33 +0,0 @@ -// addNginxFancyIndexForm.js -// Add a small form to filter through the output of Nginx FancyIndex page -// © 2017, Lilian Besson (Naereen) and contributors, -// open-sourced under the MIT License, https://lbesson.mit-license.org/ -// hosted on GitHub, https://GitHub.com/Naereen/Nginx-Fancyindex-Theme -var form = document.createElement('form'); -var input = document.createElement('input'); - -input.name = 'filter'; -input.id = 'search'; -input.placeholder = 'Type to search...'; - -form.appendChild(input); - -document.querySelector('h1').after(form); - -var listItems = [].slice.call(document.querySelectorAll('#list tbody tr')); - -input.addEventListener('keyup', function () { - var i, - // Word sequence _matching_ to input. All, except last, words must be _complete_. - e = "(^|.*[^\\pL])" + this.value.trim().split(/\s+/).join("([^\\pL]|[^\\pL].*[^\\pL])") + ".*$", - n = RegExp(e, "i"); - listItems.forEach(function(item) { - item.removeAttribute('hidden'); - }); - listItems.filter(function(item) { - i = item.querySelector('td').textContent.replace(/\s+/g, " "); - return !n.test(i); - }).forEach(function(item) { - item.hidden = true; - }); -}); diff --git a/www/vincent.demeester.fr/assets/.fancyindex/footer.html b/www/vincent.demeester.fr/assets/.fancyindex/footer.html @@ -1,40 +0,0 @@ -<section id="raw_include_README_md"></section> -</main> -<footer> - <span class='copyright'> - Content and design by Vincent Demeester - (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) - </span> -</footer> -<script src="https://unpkg.com/xregexp/xregexp-all.js"></script> -<script type="text/javascript" src="/.fancyindex/addNginxFancyIndexForm.js"></script> -<script type="text/javascript" src="/.fancyindex/showdown.min.js"></script> -<script type="text/javascript" defer> - var converter = new showdown.Converter(); - $( "#raw_include_HEADER_md" ).load( "HEADER.md", function (){ - var elem = document.querySelector("#raw_include_HEADER_md"); - // strip leading whitespace so it isn't evaluated as code - var text = elem.innerHTML; - // console.log("text =", text); - text = text.replace(/\n[ ]*/g, '\n'); - // console.log("text =", text); - var html = converter.makeHtml(text); - // console.log("html =", html); - // here, have some HTML - elem.innerHTML = html; - }); - $( "#raw_include_README_md" ).load( "README.md", function (){ - var elem = document.querySelector("#raw_include_README_md"); - // strip leading whitespace so it isn't evaluated as code - var text = elem.innerHTML; - // console.log("text =", text); - text = text.replace(/\n[ ]*/g, '\n'); - // console.log("text =", text); - var html = converter.makeHtml(text); - // console.log("html =", html); - // here, have some HTML - elem.innerHTML = html; - }); -</script> -</body> -</html> diff --git a/www/vincent.demeester.fr/assets/.fancyindex/header.html b/www/vincent.demeester.fr/assets/.fancyindex/header.html @@ -1,25 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <meta http-equiv="x-ua-compatible" content="IE=edge"> - <title>Directory</title> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="https://vincent.demeester.fr/css/new.css"> - <script type="text/javascript" src="/.fancyindex/jquery.min.js"></script> - </head> - <body> - <header id="top" class="status"> - <nav> - <img src="https://vincent.demeester.fr/images/favicon.ico" id="sitelogo"/> <a href='https://vincent.demeester.fr/'>home</a> / - <a href='https://vincent.demeester.fr/posts/'>posts</a> (<a href='https://vincent.demeester.fr/index.xml'>rss</a>) / - <a href='https://vincent.demeester.fr/articles/'>articles</a> / - <a href='https://vincent.demeester.fr/configurations/'>configurations</a> / - <a href='https://dl.sbr.pm/'>files</a> / - <a href='https://vincent.demeester.fr/about/'>about</a></li> - </nav> - </header> - <main id="content"> - <header id="raw_include_HEADER_md"> - </header> -<h1>Directory: diff --git a/www/vincent.demeester.fr/assets/.fancyindex/jquery.min.js b/www/vincent.demeester.fr/assets/.fancyindex/jquery.min.js @@ -1,5 +0,0 @@ -/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -/* Used on Lilian Besson's web pages ~ 2011-2014 */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length; -while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?o.queue(this[0],a):void 0===b?this:this.each(function(){var c=o.queue(this,a,b);o._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&o.dequeue(this,a)})},dequeue:function(a){return this.each(function(){o.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=o.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===o.css(a,"display")||!o.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=m.createDocumentFragment(),b=a.appendChild(m.createElement("div"));b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||m,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[o.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new o.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=m),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&o.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return o.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=o.extend(new o.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?o.event.trigger(e,null,b):o.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},o.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},o.Event=function(a,b){return this instanceof o.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.getPreventDefault&&a.getPreventDefault()?Z:$):this.type=a,b&&o.extend(this,b),this.timeStamp=a&&a.timeStamp||o.now(),void(this[o.expando]=!0)):new o.Event(a,b)},o.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z,this.stopPropagation()}},o.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){o.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!o.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.focusinBubbles||o.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){o.event.simulate(b,a.target,o.event.fix(a),!0)};o.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),o.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return o().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=o.guid++)),this.each(function(){o.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,o(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){o.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){o.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?o.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||o.contains(a.ownerDocument,a)||(g=o.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",e=m.documentElement,f=m.createElement("div"),g=m.createElement("div");g.style.backgroundClip="content-box",g.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===g.style.backgroundClip,f.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",f.appendChild(g);function h(){g.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",e.appendChild(f);var d=a.getComputedStyle(g,null);b="1%"!==d.top,c="4px"===d.width,e.removeChild(f)}a.getComputedStyle&&o.extend(l,{pixelPosition:function(){return h(),b},boxSizingReliable:function(){return null==c&&h(),c},reliableMarginRight:function(){var b,c=g.appendChild(m.createElement("div"));return c.style.cssText=g.style.cssText=d,c.style.marginRight=c.style.width="0",g.style.width="1px",e.appendChild(f),b=!parseFloat(a.getComputedStyle(c,null).marginRight),e.removeChild(f),g.innerHTML="",b}})}(),o.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:0,fontWeight:400},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=o.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=o.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=o.css(a,"border"+R[f]+"Width",!0,e))):(g+=o.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=o.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===o.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):f[g]||(e=S(d),(c&&"none"!==c||!e)&&L.set(d,"olddisplay",e?c:o.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}o.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=o.camelCase(b),i=a.style;return b=o.cssProps[h]||(o.cssProps[h]=Fb(i,h)),g=o.cssHooks[b]||o.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(o.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||o.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]="",i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=o.camelCase(b);return b=o.cssProps[h]||(o.cssProps[h]=Fb(a.style,h)),g=o.cssHooks[b]||o.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||o.isNumeric(f)?f||0:e):e}}),o.each(["height","width"],function(a,b){o.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&zb.test(o.css(a,"display"))?o.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===o.css(a,"boxSizing",!1,e),e):0)}}}),o.cssHooks.marginRight=yb(l.reliableMarginRight,function(a,b){return b?o.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),o.each({margin:"",padding:"",border:"Width"},function(a,b){o.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(o.cssHooks[a+b].set=Gb)}),o.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(o.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=o.css(a,b[g],!1,d);return f}return void 0!==c?o.style(a,b,c):o.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?o(this).show():o(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}o.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(o.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?o.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=o.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){o.fx.step[a.prop]?o.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[o.cssProps[a.prop]]||o.cssHooks[a.prop])?o.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},o.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},o.fx=Kb.prototype.init,o.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(o.cssNumber[a]?"":"px"),g=(o.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(o.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,o.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=o.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&S(a),p=L.get(a,"fxshow");c.queue||(h=o._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,k.always(function(){k.always(function(){h.unqueued--,o.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],j=o.css(a,"display"),"none"===j&&(j=tb(a.nodeName)),"inline"===j&&"none"===o.css(a,"float")&&(m.display="inline-block")),c.overflow&&(m.overflow="hidden",k.always(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(n?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;n=!0}l[d]=p&&p[d]||o.style(a,d)}if(!o.isEmptyObject(l)){p?"hidden"in p&&(n=p.hidden):p=L.access(a,"fxshow",{}),f&&(p.hidden=!n),n?o(a).show():k.done(function(){o(a).hide()}),k.done(function(){var b;L.remove(a,"fxshow");for(b in l)o.style(a,b,l[b])});for(d in l)g=Ub(n?p[d]:0,d,k),d in p||(p[d]=g.start,n&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=o.camelCase(c),e=b[d],f=a[c],o.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=o.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=o.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:o.extend({},b),opts:o.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=o.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return o.map(k,Ub,j),o.isFunction(j.opts.start)&&j.opts.start.call(a,j),o.fx.timer(o.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}o.Animation=o.extend(Xb,{tweener:function(a,b){o.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),o.speed=function(a,b,c){var d=a&&"object"==typeof a?o.extend({},a):{complete:c||!c&&b||o.isFunction(a)&&a,duration:a,easing:c&&b||b&&!o.isFunction(b)&&b};return d.duration=o.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in o.fx.speeds?o.fx.speeds[d.duration]:o.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){o.isFunction(d.old)&&d.old.call(this),d.queue&&o.dequeue(this,d.queue)},d},o.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=o.isEmptyObject(a),f=o.speed(b,c,d),g=function(){var b=Xb(this,o.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=o.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&o.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=o.timers,g=d?d.length:0;for(c.finish=!0,o.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),o.each(["toggle","show","hide"],function(a,b){var c=o.fn[b];o.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),o.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){o.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),o.timers=[],o.fx.tick=function(){var a,b=0,c=o.timers;for(Lb=o.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||o.fx.stop(),Lb=void 0},o.fx.timer=function(a){o.timers.push(a),a()?o.fx.start():o.timers.pop()},o.fx.interval=13,o.fx.start=function(){Mb||(Mb=setInterval(o.fx.tick,o.fx.interval))},o.fx.stop=function(){clearInterval(Mb),Mb=null},o.fx.speeds={slow:600,fast:200,_default:400},o.fn.delay=function(a,b){return a=o.fx?o.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=m.createElement("input"),b=m.createElement("select"),c=b.appendChild(m.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=m.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var Yb,Zb,$b=o.expr.attrHandle;o.fn.extend({attr:function(a,b){return J(this,o.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){o.removeAttr(this,a)})}}),o.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?o.prop(a,b,c):(1===f&&o.isXMLDoc(a)||(b=b.toLowerCase(),d=o.attrHooks[b]||(o.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=o.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void o.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=o.propFix[c]||c,o.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&o.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?o.removeAttr(a,c):a.setAttribute(c,c),c}},o.each(o.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||o.find.attr;$b[b]=function(a,b,d){var e,f; -return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;o.fn.extend({prop:function(a,b){return J(this,o.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[o.propFix[a]||a]})}}),o.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!o.isXMLDoc(a),f&&(b=o.propFix[b]||b,e=o.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),l.optSelected||(o.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),o.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){o.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;o.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=o.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?o.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(o.isFunction(a)?function(c){o(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=o(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;o.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=o.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,o(this).val()):a,null==e?e="":"number"==typeof e?e+="":o.isArray(e)&&(e=o.map(e,function(a){return null==a?"":a+""})),b=o.valHooks[this.type]||o.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=o.valHooks[e.type]||o.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),o.extend({valHooks:{select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&o.nodeName(c.parentNode,"optgroup"))){if(b=o(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=o.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=o.inArray(o(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),o.each(["radio","checkbox"],function(){o.valHooks[this]={set:function(a,b){return o.isArray(b)?a.checked=o.inArray(o(a).val(),b)>=0:void 0}},l.checkOn||(o.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),o.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){o.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),o.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=o.now(),dc=/\?/;o.parseJSON=function(a){return JSON.parse(a+"")},o.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&o.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=m.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(o.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,o.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=o.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&o.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}o.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":o.parseJSON,"text xml":o.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,o.ajaxSettings),b):tc(o.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=o.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?o(l):o.event,n=o.Deferred(),p=o.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(n.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=o.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=o.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===o.active++&&o.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(o.lastModified[d]&&v.setRequestHeader("If-Modified-Since",o.lastModified[d]),o.etag[d]&&v.setRequestHeader("If-None-Match",o.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(o.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(o.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?n.resolveWith(l,[r,x,v]):n.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--o.active||o.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return o.get(a,b,c,"json")},getScript:function(a,b){return o.get(a,void 0,b,"script")}}),o.each(["get","post"],function(a,b){o[b]=function(a,c,d,e){return o.isFunction(c)&&(e=e||d,d=c,c=void 0),o.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),o.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){o.fn[b]=function(a){return this.on(b,a)}}),o._evalUrl=function(a){return o.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},o.fn.extend({wrapAll:function(a){var b;return o.isFunction(a)?this.each(function(b){o(this).wrapAll(a.call(this,b))}):(this[0]&&(b=o(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(o.isFunction(a)?function(b){o(this).wrapInner(a.call(this,b))}:function(){var b=o(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=o.isFunction(a);return this.each(function(c){o(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){o.nodeName(this,"body")||o(this).replaceWith(this.childNodes)}).end()}}),o.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},o.expr.filters.visible=function(a){return!o.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(o.isArray(b))o.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==o.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}o.param=function(a,b){var c,d=[],e=function(a,b){b=o.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=o.ajaxSettings&&o.ajaxSettings.traditional),o.isArray(a)||a.jquery&&!o.isPlainObject(a))o.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},o.fn.extend({serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=o.prop(this,"elements");return a?o.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!o(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=o(this).val();return null==c?null:o.isArray(c)?o.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),o.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=o.ajaxSettings.xhr();a.ActiveXObject&&o(a).on("unload",function(){for(var a in Dc)Dc[a]()}),l.cors=!!Fc&&"withCredentials"in Fc,l.ajax=Fc=!!Fc,o.ajaxTransport(function(a){var b;return l.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort"),f.send(a.hasContent&&a.data||null)},abort:function(){b&&b()}}:void 0}),o.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return o.globalEval(a),a}}}),o.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),o.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=o("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),m.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;o.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||o.expando+"_"+cc++;return this[a]=!0,a}}),o.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=o.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||o.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&o.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),o.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||m;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=o.buildFragment([a],b,e),e&&e.length&&o(e).remove(),o.merge([],d.childNodes))};var Ic=o.fn.load;o.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h),a=a.slice(0,h)),o.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&o.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?o("<div>").append(o.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},o.expr.filters.animated=function(a){return o.grep(o.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return o.isWindow(a)?a:9===a.nodeType&&a.defaultView}o.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=o.css(a,"position"),l=o(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=o.css(a,"top"),i=o.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),o.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},o.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){o.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,o.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===o.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),o.nodeName(a[0],"html")||(d=a.offset()),d.top+=o.css(a[0],"borderTopWidth",!0),d.left+=o.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-o.css(c,"marginTop",!0),left:b.left-d.left-o.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!o.nodeName(a,"html")&&"static"===o.css(a,"position"))a=a.offsetParent;return a||Jc})}}),o.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;o.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),o.each(["top","left"],function(a,b){o.cssHooks[b]=yb(l.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?o(a).position()[b]+"px":c):void 0})}),o.each({Height:"height",Width:"width"},function(a,b){o.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){o.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return o.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?o.css(b,c,g):o.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),o.fn.size=function(){return this.length},o.fn.andSelf=o.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return o});var Lc=a.jQuery,Mc=a.$;return o.noConflict=function(b){return a.$===o&&(a.$=Mc),b&&a.jQuery===o&&(a.jQuery=Lc),o},typeof b===U&&(a.jQuery=a.$=o),o}); diff --git a/www/vincent.demeester.fr/assets/.fancyindex/new.css b/www/vincent.demeester.fr/assets/.fancyindex/new.css @@ -1,605 +0,0 @@ -:root { - ---font-sans: 'Ubuntu Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - ---font-mono: 'Ubuntu Mono', Consolas, monaco, 'Liberation Mono', 'Courier New', Courier, monospace; - ---tx-1: #000000; - ---tx-2: #1A1A1A; - ---tx-3: #666666; - ---tx-4: #999999; - ---bg-1: #FFFFFF; - ---bg-2: #F6F8FA; - ---bg-3: #E5E7EB; - ---lk-1: #0070F3; - ---lk-2: #0366D6; - ---lk-tx: #FFFFFF; - ---ac-1: #79FFE1; - ---ac-tx: #0C4047; - - --content-box-padding: 0.5rem; - --aside-width: 12.5rem; -} - -@media (prefers-color-scheme: dark) { - :root { - ---tx-1: #ffffff; - ---tx-2: #eeeeee; - ---tx-3: #cccccc; - ---tx-4: #aaaaaa; - ---bg-1: #000000; - ---bg-2: #111111; - ---bg-3: #222222; - ---lk-1: #3291FF; - ---lk-2: #0070F3; - ---lk-tx: #FFFFFF; - ---ac-1: #7928CA; - ---ac-tx: #FFFFFF; - } -} - -* { - /* Reset margins and padding */ - margin: 0; - padding: 0; -} - -address, -area, -article, -aside, -audio, -blockquote, -datalist, -details, -dl, -fieldset, -figure, -form, -input, -iframe, -img, -meter, -nav, -ol, -optgroup, -option, -output, -p, -pre, -progress, -ruby, -section, -table, -textarea, -ul, -video { - /* Margins for most elements */ - margin-bottom: 1rem; -} - -html,input,select,button { - /* Set body font family and some finicky elements */ - font-family: var(---font-sans); -} - -body { - /* Center body in page */ - margin: 0 auto; - max-width: 70rem; - padding: 2rem; - border-radius: 6px; - overflow-x: hidden; - word-break: break-word; - overflow-wrap: break-word; - background: var(---bg-1); - - /* Main body text */ - color: var(---tx-2); - font-size: 1.03rem; - line-height: 1.5; -} - -::selection { - /* Set background color for selected text */ - background: var(---ac-1); - color: var(---ac-tx); -} - -h1,h2,h3,h4,h5,h6 { - line-height: 1; - color: var(---tx-1); - padding-top: .875rem; -} - -h1, -h2, -h3 { - color: var(---tx-1); - padding-bottom: 2px; - margin-bottom: 8px; - border-bottom: 1px solid var(---bg-2); -} - -h4, -h5, -h6 { - margin-bottom: .3rem; -} - -h1 { - font-size: 2.25rem; -} - -h2 { - font-size: 1.85rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: 1rem; -} - -h6 { - font-size: .875rem; -} - -a { - color: var(---lk-1); -} - -a:hover { - color: var(---lk-2); -} - -abbr:hover { - /* Set the '?' cursor while hovering an abbreviation */ - cursor: help; -} - -blockquote { - padding: 1.5rem; - background: var(---bg-2); - border-left: 5px solid var(---bg-3); -} - -abbr { - cursor: help; -} - -blockquote *:last-child { - padding-bottom: 0; - margin-bottom: 0; -} - -header { - background: var(---bg-2); - border-bottom: 1px solid var(---bg-3); - padding: 1rem 1.5rem; - - /* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */ - - margin: -2rem calc(0px - (50vw - 50%)) 2rem; - - /* Shorthand for: - - margin-top: -2rem; - margin-bottom: 2rem; - - margin-left: calc(0px - (50vw - 50%)); - margin-right: calc(0px - (50vw - 50%)); */ - - padding-left: calc(50vw - 50%); - padding-right: calc(50vw - 50%); -} - -header img#sitelogo { - margin-bottom: 0; - margin-right: 1em; -} - -header h1, -header h2, -header h3 { - padding-bottom: 0; - border-bottom: 0; -} - -header > *:first-child { - margin-top: 0; - padding-top: 0; -} - -header > *:last-child { - margin-bottom: 0; -} - -main header { - background: var(---bg-3); -} - -a button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - font-size: 1rem; - display: inline-block; - padding: 6px 12px; - text-align: center; - text-decoration: none; - white-space: nowrap; - background: var(---lk-1); - color: var(---lk-tx); - border: 0; - border-radius: 4px; - box-sizing: border-box; - cursor: pointer; - color: var(---lk-tx); -} - -a button[disabled], -button[disabled], -input[type="submit"][disabled], -input[type="reset"][disabled], -input[type="button"][disabled] { - cursor: default; - opacity: .5; - - /* Set the [X] cursor while hovering a disabled link */ - cursor: not-allowed; -} - -.button:focus, -.button:hover, -button:focus, -button:hover, -input[type="submit"]:focus, -input[type="submit"]:hover, -input[type="reset"]:focus, -input[type="reset"]:hover, -input[type="button"]:focus, -input[type="button"]:hover { - background: var(---lk-2); -} - -code, -pre, -kbd, -samp { - /* Set the font family for monospaced elements */ - font-family: var(---font-mono); -} - -code, -samp, -kbd, -pre { - /* The main preformatted style. This is changed slightly across different cases. */ - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - padding: 3px 6px; -} - -kbd { - /* Makes the kbd element look like a keyboard key */ - border-bottom: 3px solid var(---bg-3); -} - -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; -} - -pre.src { - position: relative; -} -pre.src:before { - /*display: none;*/ - position: absolute; - background-color: var(---bg-3); - /*color: #f3f4f4;*/ - top: 0; - right: 0; - padding: 0.2rem 0.5rem; -} - -pre code { - /* When <code> is in a <pre>, reset it's formatting to blend in */ - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -code pre { - /* When <pre> is in a <code>, reset it's formatting to blend in */ - display: inline; - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -details { - /* Make the <details> look more "clickable" */ - padding: .6rem 1rem; - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -summary { - /* Makes the <summary> look more like a "clickable" link with the pointer cursor */ - cursor: pointer; - font-weight: bold; -} - -details[open] { - /* Adjust the <details> padding while open */ - padding-bottom: .75rem; -} - -details[open] summary { - /* Adjust the <details> padding while open */ - margin-bottom: 6px; -} - -details[open]>*:last-child { - /* Resets the bottom margin of the last element in the <details> while <details> is opened. This prevents double margins/paddings. */ - margin-bottom: 0; -} - -dt { - font-weight: bold; -} - -dd::before { - /* Add an arrow to data table definitions */ - content: '→ '; -} - -hr { - /* Reset the border of the <hr> separator, then set a better line */ - border: 0; - border-bottom: 1px solid var(---bg-3); - margin: 1rem auto; -} - -fieldset { - margin-top: 1rem; - padding: 2rem; - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -legend { - padding: auto .5rem; -} - -table { - /* border-collapse sets the table's elements to share borders, rather than floating as separate "boxes". */ - border-collapse: collapse; - width: 100% -} - -td, -th { - border: 1px solid var(---bg-3); - text-align: left; - padding: .5rem; -} - -th { - background: var(---bg-2); -} - -tr:nth-child(even) { - /* Set every other cell slightly darker. Improves readability. */ - background: var(---bg-2); -} - -table caption { - font-weight: bold; - margin-bottom: .5rem; -} - -textarea { - /* Don't let the <textarea> extend off the screen naturally or when dragged by the user */ - max-width: 100%; -} - -ol, -ul { - /* Replace the browser default padding */ - padding-left: 2rem; -} - -li { - margin-top: .4rem; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -mark { - padding: 3px 6px; - background: var(---ac-1); - color: var(---ac-tx); -} - -textarea, -select, -input { - padding: 6px 12px; - margin-bottom: .5rem; - background: var(---bg-2); - color: var(---tx-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; -} - -img { - max-width: 100%; -} - -aside { - --aside-offset: 1rem; - --aside-offset-lineheight: 1.5rem; - background-color: var(---bg-2); - padding: calc(var(--content-box-padding) * 0.5) calc(var(--content-box-padding) * 2); - padding-top: 1em; - margin-bottom: 0em; - float: right; - width: var(--aside-width); - font-size: 0.9rem; - line-height: 1.25rem; - border: 1px solid var(--bg-3); -} - -figure figcaption { - text-align: center; - color: var(---tx-2); - font-style: italic; - margin: 0 2rem; -} - -footer { - text-align: center; - color: var(---tx-4); -} - -footer a { - color: var(---tx-3); -} - -section img { - display: block; - margin-left: auto; - margin-right: auto; -} - -section img.shadow { - box-shadow: 0 28px 50px rgba(0,0,0,0.16); -} - -div.drawer:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 4.4rem; - width: 1px; - background-color: #555; -} - -div.drawer { - display: flex; - padding: 0; - margin: 1rem; - padding-top: 1rem; - position: relative; - color: #555; -} - -div.drawer h6 { - box-sizing: border-box; - font-style: italic; - flex: 0 0 5rem; - margin:0; - padding:0; - align-self: center; - text-align: right; - padding-right: 1.2rem; -} - -div.drawer.info:before { - background-color: #00529B; -} -div.drawer.info { - color: #00529B; -} - -div.drawer.note:before { - background-color: #9F6000; -} -div.drawer.note { - color: #9F6000; -} -div.drawer.tip:before { - background-color: #4F8A10; -} -div.drawer.tip { - color: #4F8A10; -} -div.drawer.warning:before { - background-color: #D8000C; -} -div.drawer.warning { - color: #D8000C; -} -div.drawer.results:before { - background-color: black; -} -div.drawer.results { - font-family:monospace,monospace; - font-family: var(---font-mono); - color: black; - width: 100% !important; -} -div.drawer.results p { - display: block; - unicode-bidi: embed; - white-space: pre; - margin-top: 0; -} -div.drawer.results pre { - background-color: inherit; - border: 0; -} -div.drawer.results pre.src:before { - background-color: #eee; - color: #555; -} - -.tag { - font-family:var(---font-mono); - font-size: 1rem; -} -.tag span { - padding:.3em; - float:right; - margin-right:.5em; - border:1px solid #bbb; - border-radius:3px; - background-clip:padding-box; - color:#333; - background-color:#eee; - line-height:1rem; -} - -.todo { - font-family: monospace; color: red; -} -.done { - font-family: monospace; color: green; -} -.priority { font-family: monospace; color: orange; } -.timestamp { color: #bebebe; } -.timestamp-kwd { color: #5f9ea0; } diff --git a/www/vincent.demeester.fr/assets/.fancyindex/showdown.min.js b/www/vincent.demeester.fr/assets/.fancyindex/showdown.min.js @@ -1,3 +0,0 @@ -/*! showdown v 1.8.6 - 22-12-2017 */ -(function(){function g(g){"use strict";var A={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",type:"string"},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',type:"boolean"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},rawHeaderId:{defaultValue:!1,describe:"Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,description:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,description:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,description:"Parses simple line breaks as <br> (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,description:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,description:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",description:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,description:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,description:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,description:"Support for HTML Tag escaping. ex: <div>foo</div>",type:"boolean"},emoji:{defaultValue:!1,description:"Enable emoji support. Ex: `this is a :smile: emoji`",type:"boolean"},underline:{defaultValue:!1,description:"Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`",type:"boolean"},completeHTMLDocument:{defaultValue:!1,description:"Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags",type:"boolean"},metadata:{defaultValue:!1,description:"Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).",type:"boolean"},splitAdjacentBlockquotes:{defaultValue:!1,description:"Split adjacent blockquote blocks",type:"boolean"}};if(!1===g)return JSON.parse(JSON.stringify(A));var C={};for(var I in A)A.hasOwnProperty(I)&&(C[I]=A[I].defaultValue);return C}function A(g,A){"use strict";var C=A?"Error in "+A+" extension->":"Error in unnamed extension",e={valid:!0,error:""};I.helper.isArray(g)||(g=[g]);for(var r=0;r<g.length;++r){var t=C+" sub-extension "+r+": ",a=g[r];if("object"!=typeof a)return e.valid=!1,e.error=t+"must be an object, but "+typeof a+" given",e;if(!I.helper.isString(a.type))return e.valid=!1,e.error=t+'property "type" must be a string, but '+typeof a.type+" given",e;var n=a.type=a.type.toLowerCase();if("language"===n&&(n=a.type="lang"),"html"===n&&(n=a.type="output"),"lang"!==n&&"output"!==n&&"listener"!==n)return e.valid=!1,e.error=t+"type "+n+' is not recognized. Valid values: "lang/language", "output/html" or "listener"',e;if("listener"===n){if(I.helper.isUndefined(a.listeners))return e.valid=!1,e.error=t+'. Extensions of type "listener" must have a property called "listeners"',e}else if(I.helper.isUndefined(a.filter)&&I.helper.isUndefined(a.regex))return e.valid=!1,e.error=t+n+' extensions must define either a "regex" property or a "filter" method',e;if(a.listeners){if("object"!=typeof a.listeners)return e.valid=!1,e.error=t+'"listeners" property must be an object but '+typeof a.listeners+" given",e;for(var o in a.listeners)if(a.listeners.hasOwnProperty(o)&&"function"!=typeof a.listeners[o])return e.valid=!1,e.error=t+'"listeners" property must be an hash of [event name]: [callback]. listeners.'+o+" must be a function but "+typeof a.listeners[o]+" given",e}if(a.filter){if("function"!=typeof a.filter)return e.valid=!1,e.error=t+'"filter" must be a function, but '+typeof a.filter+" given",e}else if(a.regex){if(I.helper.isString(a.regex)&&(a.regex=new RegExp(a.regex,"g")),!(a.regex instanceof RegExp))return e.valid=!1,e.error=t+'"regex" property must either be a string or a RegExp object, but '+typeof a.regex+" given",e;if(I.helper.isUndefined(a.replace))return e.valid=!1,e.error=t+'"regex" extensions must implement a replace string or function',e}}return e}function C(g,A){"use strict";return"¨E"+A.charCodeAt(0)+"E"}var I={},e={},r={},t=g(!0),a="vanilla",n={github:{omitExtraWLInCodeBlocks:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,disableForced4SpacesIndentedSublists:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghCompatibleHeaderId:!0,ghMentions:!0,backslashEscapesHTMLTags:!0,emoji:!0,splitAdjacentBlockquotes:!0},original:{noHeaderId:!0,ghCodeBlocks:!1},ghost:{omitExtraWLInCodeBlocks:!0,parseImgDimensions:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,smoothLivePreview:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghMentions:!1,encodeEmails:!0},vanilla:g(!0),allOn:function(){"use strict";var A=g(!0),C={};for(var I in A)A.hasOwnProperty(I)&&(C[I]=!0);return C}()};I.helper={},I.extensions={},I.setOption=function(g,A){"use strict";return t[g]=A,this},I.getOption=function(g){"use strict";return t[g]},I.getOptions=function(){"use strict";return t},I.resetOptions=function(){"use strict";t=g(!0)},I.setFlavor=function(g){"use strict";if(!n.hasOwnProperty(g))throw Error(g+" flavor was not found");I.resetOptions();var A=n[g];a=g;for(var C in A)A.hasOwnProperty(C)&&(t[C]=A[C])},I.getFlavor=function(){"use strict";return a},I.getFlavorOptions=function(g){"use strict";if(n.hasOwnProperty(g))return n[g]},I.getDefaultOptions=function(A){"use strict";return g(A)},I.subParser=function(g,A){"use strict";if(I.helper.isString(g)){if(void 0===A){if(e.hasOwnProperty(g))return e[g];throw Error("SubParser named "+g+" not registered!")}e[g]=A}},I.extension=function(g,C){"use strict";if(!I.helper.isString(g))throw Error("Extension 'name' must be a string");if(g=I.helper.stdExtName(g),I.helper.isUndefined(C)){if(!r.hasOwnProperty(g))throw Error("Extension named "+g+" is not registered!");return r[g]}"function"==typeof C&&(C=C()),I.helper.isArray(C)||(C=[C]);var e=A(C,g);if(!e.valid)throw Error(e.error);r[g]=C},I.getAllExtensions=function(){"use strict";return r},I.removeExtension=function(g){"use strict";delete r[g]},I.resetExtensions=function(){"use strict";r={}},I.validateExtension=function(g){"use strict";var C=A(g,null);return!!C.valid||(console.warn(C.error),!1)},I.hasOwnProperty("helper")||(I.helper={}),I.helper.isString=function(g){"use strict";return"string"==typeof g||g instanceof String},I.helper.isFunction=function(g){"use strict";return g&&"[object Function]"==={}.toString.call(g)},I.helper.isArray=function(g){"use strict";return Array.isArray(g)},I.helper.isUndefined=function(g){"use strict";return void 0===g},I.helper.forEach=function(g,A){"use strict";if(I.helper.isUndefined(g))throw new Error("obj param is required");if(I.helper.isUndefined(A))throw new Error("callback param is required");if(!I.helper.isFunction(A))throw new Error("callback param must be a function/closure");if("function"==typeof g.forEach)g.forEach(A);else if(I.helper.isArray(g))for(var C=0;C<g.length;C++)A(g[C],C,g);else{if("object"!=typeof g)throw new Error("obj does not seem to be an array or an iterable object");for(var e in g)g.hasOwnProperty(e)&&A(g[e],e,g)}},I.helper.stdExtName=function(g){"use strict";return g.replace(/[_?*+\/\\.^-]/g,"").replace(/\s/g,"").toLowerCase()},I.helper.escapeCharactersCallback=C,I.helper.escapeCharacters=function(g,A,I){"use strict";var e="(["+A.replace(/([\[\]\\])/g,"\\$1")+"])";I&&(e="\\\\"+e);var r=new RegExp(e,"g");return g=g.replace(r,C)};var o=function(g,A,C,I){"use strict";var e,r,t,a,n,o=I||"",s=o.indexOf("g")>-1,i=new RegExp(A+"|"+C,"g"+o.replace(/g/g,"")),l=new RegExp(A,o.replace(/g/g,"")),c=[];do{for(e=0;t=i.exec(g);)if(l.test(t[0]))e++||(a=(r=i.lastIndex)-t[0].length);else if(e&&!--e){n=t.index+t[0].length;var u={left:{start:a,end:r},match:{start:r,end:t.index},right:{start:t.index,end:n},wholeMatch:{start:a,end:n}};if(c.push(u),!s)return c}}while(e&&(i.lastIndex=r));return c};I.helper.matchRecursiveRegExp=function(g,A,C,I){"use strict";for(var e=o(g,A,C,I),r=[],t=0;t<e.length;++t)r.push([g.slice(e[t].wholeMatch.start,e[t].wholeMatch.end),g.slice(e[t].match.start,e[t].match.end),g.slice(e[t].left.start,e[t].left.end),g.slice(e[t].right.start,e[t].right.end)]);return r},I.helper.replaceRecursiveRegExp=function(g,A,C,e,r){"use strict";if(!I.helper.isFunction(A)){var t=A;A=function(){return t}}var a=o(g,C,e,r),n=g,s=a.length;if(s>0){var i=[];0!==a[0].wholeMatch.start&&i.push(g.slice(0,a[0].wholeMatch.start));for(var l=0;l<s;++l)i.push(A(g.slice(a[l].wholeMatch.start,a[l].wholeMatch.end),g.slice(a[l].match.start,a[l].match.end),g.slice(a[l].left.start,a[l].left.end),g.slice(a[l].right.start,a[l].right.end))),l<s-1&&i.push(g.slice(a[l].wholeMatch.end,a[l+1].wholeMatch.start));a[s-1].wholeMatch.end<g.length&&i.push(g.slice(a[s-1].wholeMatch.end)),n=i.join("")}return n},I.helper.regexIndexOf=function(g,A,C){"use strict";if(!I.helper.isString(g))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";if(A instanceof RegExp==!1)throw"InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp";var e=g.substring(C||0).search(A);return e>=0?e+(C||0):e},I.helper.splitAtIndex=function(g,A){"use strict";if(!I.helper.isString(g))throw"InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";return[g.substring(0,A),g.substring(A)]},I.helper.encodeEmailAddress=function(g){"use strict";var A=[function(g){return"&#"+g.charCodeAt(0)+";"},function(g){return"&#x"+g.charCodeAt(0).toString(16)+";"},function(g){return g}];return g=g.replace(/./g,function(g){if("@"===g)g=A[Math.floor(2*Math.random())](g);else{var C=Math.random();g=C>.9?A[2](g):C>.45?A[1](g):A[0](g)}return g})},"undefined"==typeof console&&(console={warn:function(g){"use strict";alert(g)},log:function(g){"use strict";alert(g)},error:function(g){"use strict";throw g}}),I.helper.regexes={asteriskDashAndColon:/([*_:~])/g},I.helper.emojis={"+1":"👍","-1":"👎",100:"💯",1234:"🔢","1st_place_medal":"🥇","2nd_place_medal":"🥈","3rd_place_medal":"🥉","8ball":"🎱",a:"🅰️",ab:"🆎",abc:"🔤",abcd:"🔡",accept:"🉑",aerial_tramway:"🚡",airplane:"✈️",alarm_clock:"⏰",alembic:"⚗️",alien:"👽",ambulance:"🚑",amphora:"🏺",anchor:"⚓️",angel:"👼",anger:"💢",angry:"😠",anguished:"😧",ant:"🐜",apple:"🍎",aquarius:"♒️",aries:"♈️",arrow_backward:"◀️",arrow_double_down:"⏬",arrow_double_up:"⏫",arrow_down:"⬇️",arrow_down_small:"🔽",arrow_forward:"▶️",arrow_heading_down:"⤵️",arrow_heading_up:"⤴️",arrow_left:"⬅️",arrow_lower_left:"↙️",arrow_lower_right:"↘️",arrow_right:"➡️",arrow_right_hook:"↪️",arrow_up:"⬆️",arrow_up_down:"↕️",arrow_up_small:"🔼",arrow_upper_left:"↖️",arrow_upper_right:"↗️",arrows_clockwise:"🔃",arrows_counterclockwise:"🔄",art:"🎨",articulated_lorry:"🚛",artificial_satellite:"🛰",astonished:"😲",athletic_shoe:"👟",atm:"🏧",atom_symbol:"⚛️",avocado:"🥑",b:"🅱️",baby:"👶",baby_bottle:"🍼",baby_chick:"🐤",baby_symbol:"🚼",back:"🔙",bacon:"🥓",badminton:"🏸",baggage_claim:"🛄",baguette_bread:"🥖",balance_scale:"⚖️",balloon:"🎈",ballot_box:"🗳",ballot_box_with_check:"☑️",bamboo:"🎍",banana:"🍌",bangbang:"‼️",bank:"🏦",bar_chart:"📊",barber:"💈",baseball:"⚾️",basketball:"🏀",basketball_man:"⛹️",basketball_woman:"⛹️‍♀️",bat:"🦇",bath:"🛀",bathtub:"🛁",battery:"🔋",beach_umbrella:"🏖",bear:"🐻",bed:"🛏",bee:"🐝",beer:"🍺",beers:"🍻",beetle:"🐞",beginner:"🔰",bell:"🔔",bellhop_bell:"🛎",bento:"🍱",biking_man:"🚴",bike:"🚲",biking_woman:"🚴‍♀️",bikini:"👙",biohazard:"☣️",bird:"🐦",birthday:"🎂",black_circle:"⚫️",black_flag:"🏴",black_heart:"🖤",black_joker:"🃏",black_large_square:"⬛️",black_medium_small_square:"◾️",black_medium_square:"◼️",black_nib:"✒️",black_small_square:"▪️",black_square_button:"🔲",blonde_man:"👱",blonde_woman:"👱‍♀️",blossom:"🌼",blowfish:"🐡",blue_book:"📘",blue_car:"🚙",blue_heart:"💙",blush:"😊",boar:"🐗",boat:"⛵️",bomb:"💣",book:"📖",bookmark:"🔖",bookmark_tabs:"📑",books:"📚",boom:"💥",boot:"👢",bouquet:"💐",bowing_man:"🙇",bow_and_arrow:"🏹",bowing_woman:"🙇‍♀️",bowling:"🎳",boxing_glove:"🥊",boy:"👦",bread:"🍞",bride_with_veil:"👰",bridge_at_night:"🌉",briefcase:"💼",broken_heart:"💔",bug:"🐛",building_construction:"🏗",bulb:"💡",bullettrain_front:"🚅",bullettrain_side:"🚄",burrito:"🌯",bus:"🚌",business_suit_levitating:"🕴",busstop:"🚏",bust_in_silhouette:"👤",busts_in_silhouette:"👥",butterfly:"🦋",cactus:"🌵",cake:"🍰",calendar:"📆",call_me_hand:"🤙",calling:"📲",camel:"🐫",camera:"📷",camera_flash:"📸",camping:"🏕",cancer:"♋️",candle:"🕯",candy:"🍬",canoe:"🛶",capital_abcd:"🔠",capricorn:"♑️",car:"🚗",card_file_box:"🗃",card_index:"📇",card_index_dividers:"🗂",carousel_horse:"🎠",carrot:"🥕",cat:"🐱",cat2:"🐈",cd:"💿",chains:"⛓",champagne:"🍾",chart:"💹",chart_with_downwards_trend:"📉",chart_with_upwards_trend:"📈",checkered_flag:"🏁",cheese:"🧀",cherries:"🍒",cherry_blossom:"🌸",chestnut:"🌰",chicken:"🐔",children_crossing:"🚸",chipmunk:"🐿",chocolate_bar:"🍫",christmas_tree:"🎄",church:"⛪️",cinema:"🎦",circus_tent:"🎪",city_sunrise:"🌇",city_sunset:"🌆",cityscape:"🏙",cl:"🆑",clamp:"🗜",clap:"👏",clapper:"🎬",classical_building:"🏛",clinking_glasses:"🥂",clipboard:"📋",clock1:"🕐",clock10:"🕙",clock1030:"🕥",clock11:"🕚",clock1130:"🕦",clock12:"🕛",clock1230:"🕧",clock130:"🕜",clock2:"🕑",clock230:"🕝",clock3:"🕒",clock330:"🕞",clock4:"🕓",clock430:"🕟",clock5:"🕔",clock530:"🕠",clock6:"🕕",clock630:"🕡",clock7:"🕖",clock730:"🕢",clock8:"🕗",clock830:"🕣",clock9:"🕘",clock930:"🕤",closed_book:"📕",closed_lock_with_key:"🔐",closed_umbrella:"🌂",cloud:"☁️",cloud_with_lightning:"🌩",cloud_with_lightning_and_rain:"⛈",cloud_with_rain:"🌧",cloud_with_snow:"🌨",clown_face:"🤡",clubs:"♣️",cocktail:"🍸",coffee:"☕️",coffin:"⚰️",cold_sweat:"😰",comet:"☄️",computer:"💻",computer_mouse:"🖱",confetti_ball:"🎊",confounded:"😖",confused:"😕",congratulations:"㊗️",construction:"🚧",construction_worker_man:"👷",construction_worker_woman:"👷‍♀️",control_knobs:"🎛",convenience_store:"🏪",cookie:"🍪",cool:"🆒",policeman:"👮",copyright:"©️",corn:"🌽",couch_and_lamp:"🛋",couple:"👫",couple_with_heart_woman_man:"💑",couple_with_heart_man_man:"👨‍❤️‍👨",couple_with_heart_woman_woman:"👩‍❤️‍👩",couplekiss_man_man:"👨‍❤️‍💋‍👨",couplekiss_man_woman:"💏",couplekiss_woman_woman:"👩‍❤️‍💋‍👩",cow:"🐮",cow2:"🐄",cowboy_hat_face:"🤠",crab:"🦀",crayon:"🖍",credit_card:"💳",crescent_moon:"🌙",cricket:"🏏",crocodile:"🐊",croissant:"🥐",crossed_fingers:"🤞",crossed_flags:"🎌",crossed_swords:"⚔️",crown:"👑",cry:"😢",crying_cat_face:"😿",crystal_ball:"🔮",cucumber:"🥒",cupid:"💘",curly_loop:"➰",currency_exchange:"💱",curry:"🍛",custard:"🍮",customs:"🛃",cyclone:"🌀",dagger:"🗡",dancer:"💃",dancing_women:"👯",dancing_men:"👯‍♂️",dango:"🍡",dark_sunglasses:"🕶",dart:"🎯",dash:"💨",date:"📅",deciduous_tree:"🌳",deer:"🦌",department_store:"🏬",derelict_house:"🏚",desert:"🏜",desert_island:"🏝",desktop_computer:"🖥",male_detective:"🕵️",diamond_shape_with_a_dot_inside:"💠",diamonds:"♦️",disappointed:"😞",disappointed_relieved:"😥",dizzy:"💫",dizzy_face:"😵",do_not_litter:"🚯",dog:"🐶",dog2:"🐕",dollar:"💵",dolls:"🎎",dolphin:"🐬",door:"🚪",doughnut:"🍩",dove:"🕊",dragon:"🐉",dragon_face:"🐲",dress:"👗",dromedary_camel:"🐪",drooling_face:"🤤",droplet:"💧",drum:"🥁",duck:"🦆",dvd:"📀","e-mail":"📧",eagle:"🦅",ear:"👂",ear_of_rice:"🌾",earth_africa:"🌍",earth_americas:"🌎",earth_asia:"🌏",egg:"🥚",eggplant:"🍆",eight_pointed_black_star:"✴️",eight_spoked_asterisk:"✳️",electric_plug:"🔌",elephant:"🐘",email:"✉️",end:"🔚",envelope_with_arrow:"📩",euro:"💶",european_castle:"🏰",european_post_office:"🏤",evergreen_tree:"🌲",exclamation:"❗️",expressionless:"😑",eye:"👁",eye_speech_bubble:"👁‍🗨",eyeglasses:"👓",eyes:"👀",face_with_head_bandage:"🤕",face_with_thermometer:"🤒",fist_oncoming:"👊",factory:"🏭",fallen_leaf:"🍂",family_man_woman_boy:"👪",family_man_boy:"👨‍👦",family_man_boy_boy:"👨‍👦‍👦",family_man_girl:"👨‍👧",family_man_girl_boy:"👨‍👧‍👦",family_man_girl_girl:"👨‍👧‍👧",family_man_man_boy:"👨‍👨‍👦",family_man_man_boy_boy:"👨‍👨‍👦‍👦",family_man_man_girl:"👨‍👨‍👧",family_man_man_girl_boy:"👨‍👨‍👧‍👦",family_man_man_girl_girl:"👨‍👨‍👧‍👧",family_man_woman_boy_boy:"👨‍👩‍👦‍👦",family_man_woman_girl:"👨‍👩‍👧",family_man_woman_girl_boy:"👨‍👩‍👧‍👦",family_man_woman_girl_girl:"👨‍👩‍👧‍👧",family_woman_boy:"👩‍👦",family_woman_boy_boy:"👩‍👦‍👦",family_woman_girl:"👩‍👧",family_woman_girl_boy:"👩‍👧‍👦",family_woman_girl_girl:"👩‍👧‍👧",family_woman_woman_boy:"👩‍👩‍👦",family_woman_woman_boy_boy:"👩‍👩‍👦‍👦",family_woman_woman_girl:"👩‍👩‍👧",family_woman_woman_girl_boy:"👩‍👩‍👧‍👦",family_woman_woman_girl_girl:"👩‍👩‍👧‍👧",fast_forward:"⏩",fax:"📠",fearful:"😨",feet:"🐾",female_detective:"🕵️‍♀️",ferris_wheel:"🎡",ferry:"⛴",field_hockey:"🏑",file_cabinet:"🗄",file_folder:"📁",film_projector:"📽",film_strip:"🎞",fire:"🔥",fire_engine:"🚒",fireworks:"🎆",first_quarter_moon:"🌓",first_quarter_moon_with_face:"🌛",fish:"🐟",fish_cake:"🍥",fishing_pole_and_fish:"🎣",fist_raised:"✊",fist_left:"🤛",fist_right:"🤜",flags:"🎏",flashlight:"🔦",fleur_de_lis:"⚜️",flight_arrival:"🛬",flight_departure:"🛫",floppy_disk:"💾",flower_playing_cards:"🎴",flushed:"😳",fog:"🌫",foggy:"🌁",football:"🏈",footprints:"👣",fork_and_knife:"🍴",fountain:"⛲️",fountain_pen:"🖋",four_leaf_clover:"🍀",fox_face:"🦊",framed_picture:"🖼",free:"🆓",fried_egg:"🍳",fried_shrimp:"🍤",fries:"🍟",frog:"🐸",frowning:"😦",frowning_face:"☹️",frowning_man:"🙍‍♂️",frowning_woman:"🙍",middle_finger:"🖕",fuelpump:"⛽️",full_moon:"🌕",full_moon_with_face:"🌝",funeral_urn:"⚱️",game_die:"🎲",gear:"⚙️",gem:"💎",gemini:"♊️",ghost:"👻",gift:"🎁",gift_heart:"💝",girl:"👧",globe_with_meridians:"🌐",goal_net:"🥅",goat:"🐐",golf:"⛳️",golfing_man:"🏌️",golfing_woman:"🏌️‍♀️",gorilla:"🦍",grapes:"🍇",green_apple:"🍏",green_book:"📗",green_heart:"💚",green_salad:"🥗",grey_exclamation:"❕",grey_question:"❔",grimacing:"😬",grin:"😁",grinning:"😀",guardsman:"💂",guardswoman:"💂‍♀️",guitar:"🎸",gun:"🔫",haircut_woman:"💇",haircut_man:"💇‍♂️",hamburger:"🍔",hammer:"🔨",hammer_and_pick:"⚒",hammer_and_wrench:"🛠",hamster:"🐹",hand:"✋",handbag:"👜",handshake:"🤝",hankey:"💩",hatched_chick:"🐥",hatching_chick:"🐣",headphones:"🎧",hear_no_evil:"🙉",heart:"❤️",heart_decoration:"💟",heart_eyes:"😍",heart_eyes_cat:"😻",heartbeat:"💓",heartpulse:"💗",hearts:"♥️",heavy_check_mark:"✔️",heavy_division_sign:"➗",heavy_dollar_sign:"💲",heavy_heart_exclamation:"❣️",heavy_minus_sign:"➖",heavy_multiplication_x:"✖️",heavy_plus_sign:"➕",helicopter:"🚁",herb:"🌿",hibiscus:"🌺",high_brightness:"🔆",high_heel:"👠",hocho:"🔪",hole:"🕳",honey_pot:"🍯",horse:"🐴",horse_racing:"🏇",hospital:"🏥",hot_pepper:"🌶",hotdog:"🌭",hotel:"🏨",hotsprings:"♨️",hourglass:"⌛️",hourglass_flowing_sand:"⏳",house:"🏠",house_with_garden:"🏡",houses:"🏘",hugs:"🤗",hushed:"😯",ice_cream:"🍨",ice_hockey:"🏒",ice_skate:"⛸",icecream:"🍦",id:"🆔",ideograph_advantage:"🉐",imp:"👿",inbox_tray:"📥",incoming_envelope:"📨",tipping_hand_woman:"💁",information_source:"ℹ️",innocent:"😇",interrobang:"⁉️",iphone:"📱",izakaya_lantern:"🏮",jack_o_lantern:"🎃",japan:"🗾",japanese_castle:"🏯",japanese_goblin:"👺",japanese_ogre:"👹",jeans:"👖",joy:"😂",joy_cat:"😹",joystick:"🕹",kaaba:"🕋",key:"🔑",keyboard:"⌨️",keycap_ten:"🔟",kick_scooter:"🛴",kimono:"👘",kiss:"💋",kissing:"😗",kissing_cat:"😽",kissing_closed_eyes:"😚",kissing_heart:"😘",kissing_smiling_eyes:"😙",kiwi_fruit:"🥝",koala:"🐨",koko:"🈁",label:"🏷",large_blue_circle:"🔵",large_blue_diamond:"🔷",large_orange_diamond:"🔶",last_quarter_moon:"🌗",last_quarter_moon_with_face:"🌜",latin_cross:"✝️",laughing:"😆",leaves:"🍃",ledger:"📒",left_luggage:"🛅",left_right_arrow:"↔️",leftwards_arrow_with_hook:"↩️",lemon:"🍋",leo:"♌️",leopard:"🐆",level_slider:"🎚",libra:"♎️",light_rail:"🚈",link:"🔗",lion:"🦁",lips:"👄",lipstick:"💄",lizard:"🦎",lock:"🔒",lock_with_ink_pen:"🔏",lollipop:"🍭",loop:"➿",loud_sound:"🔊",loudspeaker:"📢",love_hotel:"🏩",love_letter:"💌",low_brightness:"🔅",lying_face:"🤥",m:"Ⓜ️",mag:"🔍",mag_right:"🔎",mahjong:"🀄️",mailbox:"📫",mailbox_closed:"📪",mailbox_with_mail:"📬",mailbox_with_no_mail:"📭",man:"👨",man_artist:"👨‍🎨",man_astronaut:"👨‍🚀",man_cartwheeling:"🤸‍♂️",man_cook:"👨‍🍳",man_dancing:"🕺",man_facepalming:"🤦‍♂️",man_factory_worker:"👨‍🏭",man_farmer:"👨‍🌾",man_firefighter:"👨‍🚒",man_health_worker:"👨‍⚕️",man_in_tuxedo:"🤵",man_judge:"👨‍⚖️",man_juggling:"🤹‍♂️",man_mechanic:"👨‍🔧",man_office_worker:"👨‍💼",man_pilot:"👨‍✈️",man_playing_handball:"🤾‍♂️",man_playing_water_polo:"🤽‍♂️",man_scientist:"👨‍🔬",man_shrugging:"🤷‍♂️",man_singer:"👨‍🎤",man_student:"👨‍🎓",man_teacher:"👨‍🏫",man_technologist:"👨‍💻",man_with_gua_pi_mao:"👲",man_with_turban:"👳",tangerine:"🍊",mans_shoe:"👞",mantelpiece_clock:"🕰",maple_leaf:"🍁",martial_arts_uniform:"🥋",mask:"😷",massage_woman:"💆",massage_man:"💆‍♂️",meat_on_bone:"🍖",medal_military:"🎖",medal_sports:"🏅",mega:"📣",melon:"🍈",memo:"📝",men_wrestling:"🤼‍♂️",menorah:"🕎",mens:"🚹",metal:"🤘",metro:"🚇",microphone:"🎤",microscope:"🔬",milk_glass:"🥛",milky_way:"🌌",minibus:"🚐",minidisc:"💽",mobile_phone_off:"📴",money_mouth_face:"🤑",money_with_wings:"💸",moneybag:"💰",monkey:"🐒",monkey_face:"🐵",monorail:"🚝",moon:"🌔",mortar_board:"🎓",mosque:"🕌",motor_boat:"🛥",motor_scooter:"🛵",motorcycle:"🏍",motorway:"🛣",mount_fuji:"🗻",mountain:"⛰",mountain_biking_man:"🚵",mountain_biking_woman:"🚵‍♀️",mountain_cableway:"🚠",mountain_railway:"🚞",mountain_snow:"🏔",mouse:"🐭",mouse2:"🐁",movie_camera:"🎥",moyai:"🗿",mrs_claus:"🤶",muscle:"💪",mushroom:"🍄",musical_keyboard:"🎹",musical_note:"🎵",musical_score:"🎼",mute:"🔇",nail_care:"💅",name_badge:"📛",national_park:"🏞",nauseated_face:"🤢",necktie:"👔",negative_squared_cross_mark:"❎",nerd_face:"🤓",neutral_face:"😐",new:"🆕",new_moon:"🌑",new_moon_with_face:"🌚",newspaper:"📰",newspaper_roll:"🗞",next_track_button:"⏭",ng:"🆖",no_good_man:"🙅‍♂️",no_good_woman:"🙅",night_with_stars:"🌃",no_bell:"🔕",no_bicycles:"🚳",no_entry:"⛔️",no_entry_sign:"🚫",no_mobile_phones:"📵",no_mouth:"😶",no_pedestrians:"🚷",no_smoking:"🚭","non-potable_water":"🚱",nose:"👃",notebook:"📓",notebook_with_decorative_cover:"📔",notes:"🎶",nut_and_bolt:"🔩",o:"⭕️",o2:"🅾️",ocean:"🌊",octopus:"🐙",oden:"🍢",office:"🏢",oil_drum:"🛢",ok:"🆗",ok_hand:"👌",ok_man:"🙆‍♂️",ok_woman:"🙆",old_key:"🗝",older_man:"👴",older_woman:"👵",om:"🕉",on:"🔛",oncoming_automobile:"🚘",oncoming_bus:"🚍",oncoming_police_car:"🚔",oncoming_taxi:"🚖",open_file_folder:"📂",open_hands:"👐",open_mouth:"😮",open_umbrella:"☂️",ophiuchus:"⛎",orange_book:"📙",orthodox_cross:"☦️",outbox_tray:"📤",owl:"🦉",ox:"🐂",package:"📦",page_facing_up:"📄",page_with_curl:"📃",pager:"📟",paintbrush:"🖌",palm_tree:"🌴",pancakes:"🥞",panda_face:"🐼",paperclip:"📎",paperclips:"🖇",parasol_on_ground:"⛱",parking:"🅿️",part_alternation_mark:"〽️",partly_sunny:"⛅️",passenger_ship:"🛳",passport_control:"🛂",pause_button:"⏸",peace_symbol:"☮️",peach:"🍑",peanuts:"🥜",pear:"🍐",pen:"🖊",pencil2:"✏️",penguin:"🐧",pensive:"😔",performing_arts:"🎭",persevere:"😣",person_fencing:"🤺",pouting_woman:"🙎",phone:"☎️",pick:"⛏",pig:"🐷",pig2:"🐖",pig_nose:"🐽",pill:"💊",pineapple:"🍍",ping_pong:"🏓",pisces:"♓️",pizza:"🍕",place_of_worship:"🛐",plate_with_cutlery:"🍽",play_or_pause_button:"⏯",point_down:"👇",point_left:"👈",point_right:"👉",point_up:"☝️",point_up_2:"👆",police_car:"🚓",policewoman:"👮‍♀️",poodle:"🐩",popcorn:"🍿",post_office:"🏣",postal_horn:"📯",postbox:"📮",potable_water:"🚰",potato:"🥔",pouch:"👝",poultry_leg:"🍗",pound:"💷",rage:"😡",pouting_cat:"😾",pouting_man:"🙎‍♂️",pray:"🙏",prayer_beads:"📿",pregnant_woman:"🤰",previous_track_button:"⏮",prince:"🤴",princess:"👸",printer:"🖨",purple_heart:"💜",purse:"👛",pushpin:"📌",put_litter_in_its_place:"🚮",question:"❓",rabbit:"🐰",rabbit2:"🐇",racehorse:"🐎",racing_car:"🏎",radio:"📻",radio_button:"🔘",radioactive:"☢️",railway_car:"🚃",railway_track:"🛤",rainbow:"🌈",rainbow_flag:"🏳️‍🌈",raised_back_of_hand:"🤚",raised_hand_with_fingers_splayed:"🖐",raised_hands:"🙌",raising_hand_woman:"🙋",raising_hand_man:"🙋‍♂️",ram:"🐏",ramen:"🍜",rat:"🐀",record_button:"⏺",recycle:"♻️",red_circle:"🔴",registered:"®️",relaxed:"☺️",relieved:"😌",reminder_ribbon:"🎗",repeat:"🔁",repeat_one:"🔂",rescue_worker_helmet:"⛑",restroom:"🚻",revolving_hearts:"💞",rewind:"⏪",rhinoceros:"🦏",ribbon:"🎀",rice:"🍚",rice_ball:"🍙",rice_cracker:"🍘",rice_scene:"🎑",right_anger_bubble:"🗯",ring:"💍",robot:"🤖",rocket:"🚀",rofl:"🤣",roll_eyes:"🙄",roller_coaster:"🎢",rooster:"🐓",rose:"🌹",rosette:"🏵",rotating_light:"🚨",round_pushpin:"📍",rowing_man:"🚣",rowing_woman:"🚣‍♀️",rugby_football:"🏉",running_man:"🏃",running_shirt_with_sash:"🎽",running_woman:"🏃‍♀️",sa:"🈂️",sagittarius:"♐️",sake:"🍶",sandal:"👡",santa:"🎅",satellite:"📡",saxophone:"🎷",school:"🏫",school_satchel:"🎒",scissors:"✂️",scorpion:"🦂",scorpius:"♏️",scream:"😱",scream_cat:"🙀",scroll:"📜",seat:"💺",secret:"㊙️",see_no_evil:"🙈",seedling:"🌱",selfie:"🤳",shallow_pan_of_food:"🥘",shamrock:"☘️",shark:"🦈",shaved_ice:"🍧",sheep:"🐑",shell:"🐚",shield:"🛡",shinto_shrine:"⛩",ship:"🚢",shirt:"👕",shopping:"🛍",shopping_cart:"🛒",shower:"🚿",shrimp:"🦐",signal_strength:"📶",six_pointed_star:"🔯",ski:"🎿",skier:"⛷",skull:"💀",skull_and_crossbones:"☠️",sleeping:"😴",sleeping_bed:"🛌",sleepy:"😪",slightly_frowning_face:"🙁",slightly_smiling_face:"🙂",slot_machine:"🎰",small_airplane:"🛩",small_blue_diamond:"🔹",small_orange_diamond:"🔸",small_red_triangle:"🔺",small_red_triangle_down:"🔻",smile:"😄",smile_cat:"😸",smiley:"😃",smiley_cat:"😺",smiling_imp:"😈",smirk:"😏",smirk_cat:"😼",smoking:"🚬",snail:"🐌",snake:"🐍",sneezing_face:"🤧",snowboarder:"🏂",snowflake:"❄️",snowman:"⛄️",snowman_with_snow:"☃️",sob:"😭",soccer:"⚽️",soon:"🔜",sos:"🆘",sound:"🔉",space_invader:"👾",spades:"♠️",spaghetti:"🍝",sparkle:"❇️",sparkler:"🎇",sparkles:"✨",sparkling_heart:"💖",speak_no_evil:"🙊",speaker:"🔈",speaking_head:"🗣",speech_balloon:"💬",speedboat:"🚤",spider:"🕷",spider_web:"🕸",spiral_calendar:"🗓",spiral_notepad:"🗒",spoon:"🥄",squid:"🦑",stadium:"🏟",star:"⭐️",star2:"🌟",star_and_crescent:"☪️",star_of_david:"✡️",stars:"🌠",station:"🚉",statue_of_liberty:"🗽",steam_locomotive:"🚂",stew:"🍲",stop_button:"⏹",stop_sign:"🛑",stopwatch:"⏱",straight_ruler:"📏",strawberry:"🍓",stuck_out_tongue:"😛",stuck_out_tongue_closed_eyes:"😝",stuck_out_tongue_winking_eye:"😜",studio_microphone:"🎙",stuffed_flatbread:"🥙",sun_behind_large_cloud:"🌥",sun_behind_rain_cloud:"🌦",sun_behind_small_cloud:"🌤",sun_with_face:"🌞",sunflower:"🌻",sunglasses:"😎",sunny:"☀️",sunrise:"🌅",sunrise_over_mountains:"🌄",surfing_man:"🏄",surfing_woman:"🏄‍♀️",sushi:"🍣",suspension_railway:"🚟",sweat:"😓",sweat_drops:"💦",sweat_smile:"😅",sweet_potato:"🍠",swimming_man:"🏊",swimming_woman:"🏊‍♀️",symbols:"🔣",synagogue:"🕍",syringe:"💉",taco:"🌮",tada:"🎉",tanabata_tree:"🎋",taurus:"♉️",taxi:"🚕",tea:"🍵",telephone_receiver:"📞",telescope:"🔭",tennis:"🎾",tent:"⛺️",thermometer:"🌡",thinking:"🤔",thought_balloon:"💭",ticket:"🎫",tickets:"🎟",tiger:"🐯",tiger2:"🐅",timer_clock:"⏲",tipping_hand_man:"💁‍♂️",tired_face:"😫",tm:"™️",toilet:"🚽",tokyo_tower:"🗼",tomato:"🍅",tongue:"👅",top:"🔝",tophat:"🎩",tornado:"🌪",trackball:"🖲",tractor:"🚜",traffic_light:"🚥",train:"🚋",train2:"🚆",tram:"🚊",triangular_flag_on_post:"🚩",triangular_ruler:"📐",trident:"🔱",triumph:"😤",trolleybus:"🚎",trophy:"🏆",tropical_drink:"🍹",tropical_fish:"🐠",truck:"🚚",trumpet:"🎺",tulip:"🌷",tumbler_glass:"🥃",turkey:"🦃",turtle:"🐢",tv:"📺",twisted_rightwards_arrows:"🔀",two_hearts:"💕",two_men_holding_hands:"👬",two_women_holding_hands:"👭",u5272:"🈹",u5408:"🈴",u55b6:"🈺",u6307:"🈯️",u6708:"🈷️",u6709:"🈶",u6e80:"🈵",u7121:"🈚️",u7533:"🈸",u7981:"🈲",u7a7a:"🈳",umbrella:"☔️",unamused:"😒",underage:"🔞",unicorn:"🦄",unlock:"🔓",up:"🆙",upside_down_face:"🙃",v:"✌️",vertical_traffic_light:"🚦",vhs:"📼",vibration_mode:"📳",video_camera:"📹",video_game:"🎮",violin:"🎻",virgo:"♍️",volcano:"🌋",volleyball:"🏐",vs:"🆚",vulcan_salute:"🖖",walking_man:"🚶",walking_woman:"🚶‍♀️",waning_crescent_moon:"🌘",waning_gibbous_moon:"🌖",warning:"⚠️",wastebasket:"🗑",watch:"⌚️",water_buffalo:"🐃",watermelon:"🍉",wave:"👋",wavy_dash:"〰️",waxing_crescent_moon:"🌒",wc:"🚾",weary:"😩",wedding:"💒",weight_lifting_man:"🏋️",weight_lifting_woman:"🏋️‍♀️",whale:"🐳",whale2:"🐋",wheel_of_dharma:"☸️",wheelchair:"♿️",white_check_mark:"✅",white_circle:"⚪️",white_flag:"🏳️",white_flower:"💮",white_large_square:"⬜️",white_medium_small_square:"◽️",white_medium_square:"◻️",white_small_square:"▫️",white_square_button:"🔳",wilted_flower:"🥀",wind_chime:"🎐",wind_face:"🌬",wine_glass:"🍷",wink:"😉",wolf:"🐺",woman:"👩",woman_artist:"👩‍🎨",woman_astronaut:"👩‍🚀",woman_cartwheeling:"🤸‍♀️",woman_cook:"👩‍🍳",woman_facepalming:"🤦‍♀️",woman_factory_worker:"👩‍🏭",woman_farmer:"👩‍🌾",woman_firefighter:"👩‍🚒",woman_health_worker:"👩‍⚕️",woman_judge:"👩‍⚖️",woman_juggling:"🤹‍♀️",woman_mechanic:"👩‍🔧",woman_office_worker:"👩‍💼",woman_pilot:"👩‍✈️",woman_playing_handball:"🤾‍♀️",woman_playing_water_polo:"🤽‍♀️",woman_scientist:"👩‍🔬",woman_shrugging:"🤷‍♀️",woman_singer:"👩‍🎤",woman_student:"👩‍🎓",woman_teacher:"👩‍🏫",woman_technologist:"👩‍💻",woman_with_turban:"👳‍♀️",womans_clothes:"👚",womans_hat:"👒",women_wrestling:"🤼‍♀️",womens:"🚺",world_map:"🗺",worried:"😟",wrench:"🔧",writing_hand:"✍️",x:"❌",yellow_heart:"💛",yen:"💴",yin_yang:"☯️",yum:"😋",zap:"⚡️",zipper_mouth_face:"🤐",zzz:"💤",octocat:'<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAOwUlEQVR42uVbCVyO6RbPmn0sw9gZS0aZO4y5GTEUE2ObxjZjrbHEJVy3sWS5pkaWxjLEkCVDSbSgFLdESaWSLIVUSIi4kvb9f895vi/zbbR+yZ339/tbnu99n/ec/3Oe85xznufV0CjDBaAdwZqwnzCJ0FXjHV70/i8J5oQDhCFV8cJdq1atwqxZs+Ds7Iz4+HhqwgXCLELNKlK6G2Ej4e6lS5ewZcsWzJgxA+fOnWNZFqvzxT1v3boF/qcsBg0ahP3796OwsJAFWKYuIqjfPoS9cXFxWL58Obp06SInh5aWFr//jjoJWLlu3TolAorRuXNn7Ny5k4W4Spgj81xrgj5hLmED4RDhlNRygglBhADCSakpWxFMCHoETUJTwrYHDx7A1NT0je9nPHz4kN/fXl0EeI0aNeqtAjB69+4NPz8/FsSdlXvy5An8/f1hZ2cHCwsLGBsbY/To0cJy9PT0MGDAAAwePBhGRkbClNesWYODBw8iODgYOTk53M/d9evXo27duiW++8iRI3z/ZHURENOjR48ShSjGuHHjhHJ16tQp9TOKaNWqlZKpvw1MHluQOpSvk5eXh5YtW5ZbmarAvHnzmIBd6iCgXnZ2Npo1a1atCWAfwY5SHQTUKCoqQocOHao1AebmHBJgi7p8QBDP6epMwKFDvMDAWF0ELLS1ta3WBNy9e5cJMFIXAdvt7e2rNQHDhw9nAv5D+KKylV9y8+bNCi1pVYWZM2cyCfaVTcDdsqzH7xpBQRxcwqyylLdi5/K+KM/Q0dFhAqIri4Bn1T0AUgVpdmhYUeVHnD59+r1TnjF27Fgm4HhFCThoYmLyXhLQoEGD4mRKsyIE3OrZs+d7SQCDCyZcNSqv8k1evXoFTU3NUr+wzUcfYqRBf8yb/C2WzfoBFoTF08fBdMIITDD8CsP1+kL30x7Q6dYZH7drjfZ0f4fWLdG1Q1t81qMLBvTRwejB/TBl1BDMnzQGS2dMxKo5k7Fs9iSY/jAaBvR8Pc26pZaH02quLZSXgO6xsbGlelGnli1wZKcVMqN8gKcRwItrf+K/VB95doXaLwOJIVSzOU/+2Re5kV7IuuyJrIhTyLt6mmztLBBPNZLHoUAy9fE8UvJ8ikxfj8PwJPQErJeYlkquTZs2MQFLykuANgc/Jb2kn3Z3ZMaQUrmxwO1zyAo7gfRAJ6RfOIyMEFdkXj5F8BTK5lzxQv610yi8QcFatI8gQoCIK7x+hojwRnaE5H4JTiEj9Pjr/rJDqcZyn9b4ovu45LYbdWvXeqtsXMHiSlZ5CegRExPz1hd83PYj5POo0QinXyLFg48hnZTOiQ1Dzr1IZEaeQRoJn0HKZIR7lA2kfHrQUerXHTlx4ZL+rnjjFRGRGeYB5MUj2GnbW+XbuJFrp1heXgI6JCYmvvUFN1x3Aek3SWkapRAXMeJFGS8ge2Xfuog0toaykED3Mpk8+shOk+sv68Y50V9WuKewBKt5094o39atW/mRf5WXgIYZGRlo3Lixys4nj6A6Z1YMcqRCpwU4ouDlUyHk/QA/hNttR25Wlvh/ZthJUsil9ATQ/axkYbqEzDgfL0Ts/x35+aLyTES7IY36Q6w/+Q4/tP6wuUoZ9+7dy7ebVmQZjO/atavKzn32rAdeXkd6KCkXdAxZ13yFcLFnvPD73zrDVrsdTs6eggKSuSjjORHkUGoC0i86Iyc6QPQX7eqMnTodYNuzHU4vnosiaitMSUSavwMy6d3IvEUrzViVMrq5uXEX4ytCgL++vr5Sx7Vr1cIDX0dKkQJfj37Rs3jw1sBxkwlwGD4Ax3+ciN1faCHW76xQRFgAOcjSEMBkIe0x8nLzcez7kTg8Rh/uxuOxR/cTJISFSfq7eATpZCk8CAfXLVFJwIULXHnHoIoQYLtw4UKljps2aogXQcQuef/XAiMDKY+S4DhyEFwpDnCj9f+Afl8EbbWRTANaAdihlYoAMn8aZzyNuYODX/eD29TvRH/7v+qN8H27JdOAyWQfQQ74xPafVRLAPox9WUlK6hIGEgx4f00Kg2JcvHhRqeP6FIwknXemyen/2gLIIeC/CYk49M0AuE4xgtu0sThg8AUCN62TEuBdRgJo2Y+Kxh9D/k59SQiwH9QHobt3SAk4KSGA4oWjm1YqyVi8U6Soj4yOrHM/jTAyKVby/PnzIoNi8L+L4eXlpXoFcLcTgc1rAlISkJeXDxeK2A6P1hdTwI6mQPTJE+WbAlnJyE7PhNO3Q3BkrKGYWtxfHMkkmQLO0ilwA7+vXqAkn66urtBLUZ9iHfm30NBQaPAf165dA0d9vP2UlJSEp0+f4vHjx3j06JH4e+rUqUovcNmyGkiNEkLwklXsBG+ecMUOnfbYod1emG5uboFKJ8jPFVD0l0dBUHqoPDHpQeQEb0qc4FUHe3KAbYUT9JgzDbwOFL5MfN0fXkXhJ5PxSvLt2LFD1Ah5u4z1YJ14l4qnBe8v3rhxAzz4PAVG8nLHivIP0dHRiIiIQGRkpEgmrl69ClW1QBMjQ7LDW8hmU+RRI69ckJIkhL7jfRJBm62R+TJVYq6h0jhBRslsivqenT2MF/7OyI70VmkFhWnPJaS6OyPkt43IycqR9EfWlH7JDQUUTuNhCHR7Ke9YcRp/5coVoQPrcvnyZURFRYmBZlLS0kR8MVLD29sbnp6e8PHxQUBAgCgn8YO8E3z79m3BGKeVc+bMkXuBZt06SA12F/F5Go0gR4C8HBalPZMPXKL8lQKhPAqF+f97KXFyNx6HQsoPsshJ/kmAp2TKkJLISpXvjyxNhMYcDVLOEO+lPDi8B5mamipkZx1YF9YpJCRErAy+vr5CZ9ZdWABhDGEYYTBhAOFz3g4nfMJelNCbkNCpUye5F034mvxIPi1/FM+zQCw0k5B9O0iEr5kRXkqhMJOVf9NXIHjtT7hmaymSoBzKETimkAuFpaF1dkwI9RcmIYaXv3BJXoGCuyIgk5WpefPmKCgoYK46SmX/RKoL69Sfl0WuFEl1HlmWJXE5z6WmTZvKJxxmxkIQ3AuU5APk6NICj4hRT6eITTEEzqWk55HHPjz3cxJhNF5cxeNT9kj2cRDTQjEkzpDtjyyCic5l5fEA7uSHFEefR5pPsahrb2B9QkICFHeJ51HunkdLIg0VLY0BFKdLwllVHp4dHyvst3QuEiiju21vA/+VZkiluIKt4I3RIfWXQ4QgKUxkni47LJWUP3PmjHo2RxVI+CebmKJP6EiFDVurxUgmExe5PHlnPAkn8w4QqW62NCVmYopozid5H0CI9RKE21ggJeAYEeMnfitOnRn5XCfgeJ+VTosWQU8MOc6ZE0cqnUm4fv165SrPBVHCfMI4TowUfmOfsIcdJh92kBWmUcP6GDt8EDZbzIffH5tx3/ewSFjw5LKk0MEFEkZenDBjgew7Yiog5brkt+QrknvJmhIp4Apw/A1bVpjhG/0v5d7Vrl07bNu2TelUSqUoz8uI3Z49OEtBAy+TdP1CqKtwHzvQUxxgTJs2TeX5gdq1a0ObSmCjh+jB+NuvRamL1+3ls77HCip1rTSdJP5eNnMizKndjMLoH42G4bthX+FzHS3UVVEC69evH3799VeKMXJZrlWKclUGAZ5jxoxB02ZNsNlxH74aagBHZyex986HlVTczyGmI58h4CjL2toa48ePFxsUPEotWrQoc0GT0/C2bduiY8eO4ISMcxLeoOFYhS6qm2EpoZG65jmbv+dPSyRZlt5QfVjvtX19AOFNL+aDFNI4m0eFc9Ho5ORkaGtrl5kAVp6DMOk88efEjLe++ZhclZwHTJHEHbs4YOCmLj2645fdvwnTK42zoXtaEHwNDQ3LXdZm5yad3/2r+gQmDsRnIF5KAldX6zdsgG/GG8F44Vzcu3eP2y1K6GPr2rVrK1zbnz59Or/LoaoJCPZ4kCZsjw9GECL79OmDj9q2wb+320C3/5fgPQO6Vrzh+fpcDqxXr16lbHBwgkZXm6okYJr0ECMrX5vraiJ1lArEjrEnzWuOqemiYj9spGd2ee478XkiPsJakmJ83qA05/8qXNurJFLiunXrhpo1a6LxB02wyHIFZpovgOHwYfjZ0hK2lH5u2rwZ5suWYv5ycyUlmjRpgl69eimlrFy3kwuoyOvXr19frm3RokVMwPZ3TYC57E6xVq+e6KzVDSaL/oEp82Zh8IhhWLjGAp/p9oX5ujVKBNjY2MDV1VWuzd3dXaTesm2biUQuZ8u28elSPmKr8a4vdog8GnJpcT1N1KHUuBbt0jSgWuGbzJh3mVhh2TYHBwdxjFa2jVcZnvPVlQBOLXdZWlqW2ZFxNYYVlm07fPgwAgMD5dr4OD5HeHLFFxM+O42DGtXhIkFaMQlcUjIzM0P37t1Ro0YNpZPjPJcVK7SOjo5ybU5OTqIAo0gAh97VlgAZIj4l8Pn4WFaO64ocuXG6zJtDbMqySnC7IgF8uptLVrJtq1evFuWqak+A4j4i4TNpltiJ8LPiNFFFwNGjRyWFyfedAFUny/joekkEuLi4KK0CfykCeFnkiu1flgBeFtl3/D8SsMbKykpOifv37ysRcPz4cVHKUiSA8wwNdR9/VTMBSh9Y8S4Nf2qnSICiBbDzVCRg9uzZTMC+94kAv6FDh8opwRsVHPjItnl4eEDxHNLKlStFXV+2javQ/M1SpZe+1KA4L4G7WDG57fSm/OUbXiqG0ewAFYOeYcN4fwZhvLkp2y4tftrxcltdlf/w+fPn4qNGxTCYU2m6nrRu3VqunT/EoiuZvw6TTZHpyuNNmEaNGsndP3fu3OJAq1N1JOAHDmyKheVtNP4OkE2crULRAW7fvl20EyyLy24a8p+/7WISFixYIMLt4t82bNhQYjXqXREgPq3j74mlX3AmSL8E1eOPIBXnuVT5OsVZpuLnOMeOHeN7vifwiYhYzhC5IpwlOXj1QXWdBmy/XWU/X+UqMZfKBw4cKAobHPlJlZe9h6tOu+7cuSN2dg0MDMSSyZUpmXvaSD+crq/xvl0k9BTCRa7qEPq+5T4t6ffF52WVV+f1P6zyLG30bsU4AAAAAElFTkSuQmCC">',showdown:'<img width="20" height="20" align="absmiddle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAECtaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzA2NyA3OS4xNTc3NDcsIDIwMTUvMDMvMzAtMjM6NDA6NDIgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTctMTAtMjRUMTM6MzE6MzArMDE6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOklDQ1Byb2ZpbGU+c1JHQiBJRUM2MTk2Ni0yLjE8L3Bob3Rvc2hvcDpJQ0NQcm9maWxlPgogICAgICAgICA8cGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgICAgIDxyZGY6QmFnPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHBob3Rvc2hvcDpMYXllck5hbWU+UyAtPC9waG90b3Nob3A6TGF5ZXJOYW1lPgogICAgICAgICAgICAgICAgICA8cGhvdG9zaG9wOkxheWVyVGV4dD5TIC08L3Bob3Rvc2hvcDpMYXllclRleHQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6N2NkMzQxNzctOWYyZi0yNDRiLWEyYjQtMzU1MzJkY2Y1MWJiPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6M2E1YzgxYmYtYjhiNy0xMWU3LTk0NDktYTQ2MzdlZjJkNjMzPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jcmVhdGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDEtMTVUMjE6MDE6MTlaPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE3LTEwLTI0VDEzOjMxOjMwKzAxOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5jb252ZXJ0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+ZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL3BuZzwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjdjZDM0MTc3LTlmMmYtMjQ0Yi1hMmI0LTM1NTMyZGNmNTFiYjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNy0xMC0yNFQxMzozMTozMCswMTowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6ODZjNjBkMGQtOGY0Yy01ZTRlLWEwMjQtODI4ZWQyNTIwZDc3PC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjYwQzVBRTY1RjY5Q0U0MTE5NDVBODU1RTNCQ0E3RUVCPC9zdFJlZjpkb2N1bWVudElEPgogICAgICAgICAgICA8c3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjBDNUFFNjVGNjlDRTQxMTk0NUE4NTVFM0JDQTdFRUI8L3N0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjQ8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pse7bzcAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAA1JJREFUeNrsm1+OmlAUhz+aeS9dwZggJn1AnRUMO6jpBgZXULuC2hWUWUGZBTSxKyiuoA4mfUBMnB04K5g+9DihRBHlyh/lJLwIXLgf99xzzu9etZeXFy7Z3nDh1gBoAFy4XeVtQNO0zNcapmUDfUBPnFoBfhQGq6IBaHmjwD4Ahmk5wAD4kKG5J8CNwsAFaHe6DvA9cc0wCgOv8gDka3vA9RHNPgo0D7hNnJtGYWBXxgV2dH4MfMnRRA+Y1WIO2NJ5F/ikoKm3tYsChmkNFHW+fmHQMC1dfHaXPQP3wM1yMdc2B/AOGALTWobBmI1Shu0UGCwX83XyRBQGawHntTtdG5gUNfxVu4CTNqNv6/wWGL7kCc+1AmCYVisl3I2ydD4GYZUCs7IjoLXrxHIx9w9tLAqDCfBwDrXAY457x+cAoCfuwRGjYFUnAGk+PsjR7s8Dn1VeLWCYVlpDw+VivjVHSHt+u9PVJbzGzZXQWTkAkz0V31fATUaEsjVJlQBs4FeGcteLgzgbAALBA+4y3voAeJL8nA0AHfClnM1qm1HhnYUidCSE+KzvSSJUTwAxCOMcpfETMFYpfRUKIAbCFhC3OTJJJwqDWS0BxED0JZ4Pjix1P2+E0loCSMBwyK4S/xc1ojBwag8gMU84cvTKGgmlAYhngu1O9xAXuVE5J1QCQCz3bwHuHvdQui5QKQAxEO6eEKpsFCgTRSXkvdoxSlBMCxhJJbgrrbZRtHCiShN0pRB6PeQ3ckBw2K0oKXMBVYJIP+Nvh9qulFivGoBt1lLQxowT2ykBXCfnhZIglgYACWmqXQv+baioBYCeiCQHm+QEg1O7RhF7hO4OhSAhcJKSFU7qBGADwZeqMMuXn6TUBw8qlaMrirNb4LdhWlP+SWD+cjFfxTpuS2GUpik+o3jFSEkqbJiWn0P0OMSGqlWiOu0TvD+FRHZKAE+oW+cfRmEwqlsesJJEJs8y91QqP+9UL6lqEtz2gpuNEY5sm9sIHln2DRa2aFKGJtiXkZEMiWtgVvRKUSUFkSKt2S7fAGgAXLYpmQQXf36MUChTZdUa2u8/rkvPA6Tz30r4eH3ybcBS5gJ6SaNXb+aABkA1AMxKenclBZLW/He4cYEGwEXb3wEASelexk6LIIIAAAAASUVORK5CYII=">'},I.Converter=function(g){"use strict";function C(g,C){if(C=C||null,I.helper.isString(g)){if(g=I.helper.stdExtName(g),C=g,I.extensions[g])return console.warn("DEPRECATION WARNING: "+g+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"),void function(g,C){"function"==typeof g&&(g=g(new I.Converter));I.helper.isArray(g)||(g=[g]);var e=A(g,C);if(!e.valid)throw Error(e.error);for(var r=0;r<g.length;++r)switch(g[r].type){case"lang":s.push(g[r]);break;case"output":i.push(g[r]);break;default:throw Error("Extension loader error: Type unrecognized!!!")}}(I.extensions[g],g);if(I.helper.isUndefined(r[g]))throw Error('Extension "'+g+'" could not be loaded. It was either not found or is not a valid extension.');g=r[g]}"function"==typeof g&&(g=g()),I.helper.isArray(g)||(g=[g]);var t=A(g,C);if(!t.valid)throw Error(t.error);for(var a=0;a<g.length;++a){switch(g[a].type){case"lang":s.push(g[a]);break;case"output":i.push(g[a])}if(g[a].hasOwnProperty("listeners"))for(var n in g[a].listeners)g[a].listeners.hasOwnProperty(n)&&e(n,g[a].listeners[n])}}function e(g,A){if(!I.helper.isString(g))throw Error("Invalid argument in converter.listen() method: name must be a string, but "+typeof g+" given");if("function"!=typeof A)throw Error("Invalid argument in converter.listen() method: callback must be a function, but "+typeof A+" given");l.hasOwnProperty(g)||(l[g]=[]),l[g].push(A)}var o={},s=[],i=[],l={},c=a,u={parsed:{},raw:"",format:""};!function(){g=g||{};for(var A in t)t.hasOwnProperty(A)&&(o[A]=t[A]);if("object"!=typeof g)throw Error("Converter expects the passed parameter to be an object, but "+typeof g+" was passed instead.");for(var e in g)g.hasOwnProperty(e)&&(o[e]=g[e]);o.extensions&&I.helper.forEach(o.extensions,C)}(),this._dispatch=function(g,A,C,I){if(l.hasOwnProperty(g))for(var e=0;e<l[g].length;++e){var r=l[g][e](g,A,this,C,I);r&&void 0!==r&&(A=r)}return A},this.listen=function(g,A){return e(g,A),this},this.makeHtml=function(g){if(!g)return g;var A={gHtmlBlocks:[],gHtmlMdBlocks:[],gHtmlSpans:[],gUrls:{},gTitles:{},gDimensions:{},gListLevel:0,hashLinkCounts:{},langExtensions:s,outputModifiers:i,converter:this,ghCodeBlocks:[],metadata:{parsed:{},raw:"",format:""}};return g=g.replace(/¨/g,"¨T"),g=g.replace(/\$/g,"¨D"),g=g.replace(/\r\n/g,"\n"),g=g.replace(/\r/g,"\n"),g=g.replace(/\u00A0/g," "),o.smartIndentationFix&&(g=function(g){var A=g.match(/^\s*/)[0].length,C=new RegExp("^\\s{0,"+A+"}","gm");return g.replace(C,"")}(g)),g="\n\n"+g+"\n\n",g=I.subParser("detab")(g,o,A),g=g.replace(/^[ \t]+$/gm,""),I.helper.forEach(s,function(C){g=I.subParser("runExtension")(C,g,o,A)}),g=I.subParser("metadata")(g,o,A),g=I.subParser("hashPreCodeTags")(g,o,A),g=I.subParser("githubCodeBlocks")(g,o,A),g=I.subParser("hashHTMLBlocks")(g,o,A),g=I.subParser("hashCodeTags")(g,o,A),g=I.subParser("stripLinkDefinitions")(g,o,A),g=I.subParser("blockGamut")(g,o,A),g=I.subParser("unhashHTMLSpans")(g,o,A),g=I.subParser("unescapeSpecialChars")(g,o,A),g=g.replace(/¨D/g,"$$"),g=g.replace(/¨T/g,"¨"),g=I.subParser("completeHTMLDocument")(g,o,A),I.helper.forEach(i,function(C){g=I.subParser("runExtension")(C,g,o,A)}),u=A.metadata,g},this.setOption=function(g,A){o[g]=A},this.getOption=function(g){return o[g]},this.getOptions=function(){return o},this.addExtension=function(g,A){C(g,A=A||null)},this.useExtension=function(g){C(g)},this.setFlavor=function(g){if(!n.hasOwnProperty(g))throw Error(g+" flavor was not found");var A=n[g];c=g;for(var C in A)A.hasOwnProperty(C)&&(o[C]=A[C])},this.getFlavor=function(){return c},this.removeExtension=function(g){I.helper.isArray(g)||(g=[g]);for(var A=0;A<g.length;++A){for(var C=g[A],e=0;e<s.length;++e)s[e]===C&&s[e].splice(e,1);for(;0<i.length;++e)i[0]===C&&i[0].splice(e,1)}},this.getAllExtensions=function(){return{language:s,output:i}},this.getMetadata=function(g){return g?u.raw:u.parsed},this.getMetadataFormat=function(){return u.format},this._setMetadataPair=function(g,A){u.parsed[g]=A},this._setMetadataFormat=function(g){u.format=g},this._setMetadataRaw=function(g){u.raw=g}},I.subParser("anchors",function(g,A,C){"use strict";var e=function(g,e,r,t,a,n,o){if(I.helper.isUndefined(o)&&(o=""),r=r.toLowerCase(),g.search(/\(<?\s*>? ?(['"].*['"])?\)$/m)>-1)t="";else if(!t){if(r||(r=e.toLowerCase().replace(/ ?\n/g," ")),t="#"+r,I.helper.isUndefined(C.gUrls[r]))return g;t=C.gUrls[r],I.helper.isUndefined(C.gTitles[r])||(o=C.gTitles[r])}var s='<a href="'+(t=t.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"';return""!==o&&null!==o&&(s+=' title="'+(o=(o=o.replace(/"/g,""")).replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"'),A.openLinksInNewWindow&&!/^#/.test(t)&&(s+=' target="¨E95Eblank"'),s+=">"+e+"</a>"};return g=(g=C.converter._dispatch("anchors.before",g,A,C)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g,e),g=g.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,e),g=g.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,e),g=g.replace(/\[([^\[\]]+)]()()()()()/g,e),A.ghMentions&&(g=g.replace(/(^|\s)(\\)?(@([a-z\d\-]+))(?=[.!?;,[\]()]|\s|$)/gim,function(g,C,e,r,t){if("\\"===e)return C+r;if(!I.helper.isString(A.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");var a=A.ghMentionsLink.replace(/\{u}/g,t),n="";return A.openLinksInNewWindow&&(n=' target="¨E95Eblank"'),C+'<a href="'+a+'"'+n+">"+r+"</a>"})),g=C.converter._dispatch("anchors.after",g,A,C)});var s=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,i=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,l=/()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,c=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,u=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,d=function(g){"use strict";return function(A,C,e,r,t,a,n){var o=e=e.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback),s="",i="",l=C||"",c=n||"";return/^www\./i.test(e)&&(e=e.replace(/^www\./i,"http://www.")),g.excludeTrailingPunctuationFromURLs&&a&&(s=a),g.openLinksInNewWindow&&(i=' target="¨E95Eblank"'),l+'<a href="'+e+'"'+i+">"+o+"</a>"+s+c}},p=function(g,A){"use strict";return function(C,e,r){var t="mailto:";return e=e||"",r=I.subParser("unescapeSpecialChars")(r,g,A),g.encodeEmails?(t=I.helper.encodeEmailAddress(t+r),r=I.helper.encodeEmailAddress(r)):t+=r,e+'<a href="'+t+'">'+r+"</a>"}};I.subParser("autoLinks",function(g,A,C){"use strict";return g=C.converter._dispatch("autoLinks.before",g,A,C),g=g.replace(l,d(A)),g=g.replace(u,p(A,C)),g=C.converter._dispatch("autoLinks.after",g,A,C)}),I.subParser("simplifiedAutoLinks",function(g,A,C){"use strict";return A.simplifiedAutoLink?(g=C.converter._dispatch("simplifiedAutoLinks.before",g,A,C),g=A.excludeTrailingPunctuationFromURLs?g.replace(i,d(A)):g.replace(s,d(A)),g=g.replace(c,p(A,C)),g=C.converter._dispatch("simplifiedAutoLinks.after",g,A,C)):g}),I.subParser("blockGamut",function(g,A,C){"use strict";return g=C.converter._dispatch("blockGamut.before",g,A,C),g=I.subParser("blockQuotes")(g,A,C),g=I.subParser("headers")(g,A,C),g=I.subParser("horizontalRule")(g,A,C),g=I.subParser("lists")(g,A,C),g=I.subParser("codeBlocks")(g,A,C),g=I.subParser("tables")(g,A,C),g=I.subParser("hashHTMLBlocks")(g,A,C),g=I.subParser("paragraphs")(g,A,C),g=C.converter._dispatch("blockGamut.after",g,A,C)}),I.subParser("blockQuotes",function(g,A,C){"use strict";g=C.converter._dispatch("blockQuotes.before",g,A,C),g+="\n\n";var e=/(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;return A.splitAdjacentBlockquotes&&(e=/^ {0,3}>[\s\S]*?(?:\n\n)/gm),g=g.replace(e,function(g){return g=g.replace(/^[ \t]*>[ \t]?/gm,""),g=g.replace(/¨0/g,""),g=g.replace(/^[ \t]+$/gm,""),g=I.subParser("githubCodeBlocks")(g,A,C),g=I.subParser("blockGamut")(g,A,C),g=g.replace(/(^|\n)/g,"$1 "),g=g.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm,function(g,A){var C=A;return C=C.replace(/^ /gm,"¨0"),C=C.replace(/¨0/g,"")}),I.subParser("hashBlock")("<blockquote>\n"+g+"\n</blockquote>",A,C)}),g=C.converter._dispatch("blockQuotes.after",g,A,C)}),I.subParser("codeBlocks",function(g,A,C){"use strict";g=C.converter._dispatch("codeBlocks.before",g,A,C);return g=(g+="¨0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g,function(g,e,r){var t=e,a=r,n="\n";return t=I.subParser("outdent")(t,A,C),t=I.subParser("encodeCode")(t,A,C),t=I.subParser("detab")(t,A,C),t=t.replace(/^\n+/g,""),t=t.replace(/\n+$/g,""),A.omitExtraWLInCodeBlocks&&(n=""),t="<pre><code>"+t+n+"</code></pre>",I.subParser("hashBlock")(t,A,C)+a}),g=g.replace(/¨0/,""),g=C.converter._dispatch("codeBlocks.after",g,A,C)}),I.subParser("codeSpans",function(g,A,C){"use strict";return void 0===(g=C.converter._dispatch("codeSpans.before",g,A,C))&&(g=""),g=g.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(g,e,r,t){var a=t;return a=a.replace(/^([ \t]*)/g,""),a=a.replace(/[ \t]*$/g,""),a=I.subParser("encodeCode")(a,A,C),a=e+"<code>"+a+"</code>",a=I.subParser("hashHTMLSpans")(a,A,C)}),g=C.converter._dispatch("codeSpans.after",g,A,C)}),I.subParser("completeHTMLDocument",function(g,A,C){"use strict";if(!A.completeHTMLDocument)return g;g=C.converter._dispatch("completeHTMLDocument.before",g,A,C);var I="html",e="<!DOCTYPE HTML>\n",r="",t='<meta charset="utf-8">\n',a="",n="";void 0!==C.metadata.parsed.doctype&&(e="<!DOCTYPE "+C.metadata.parsed.doctype+">\n","html"!==(I=C.metadata.parsed.doctype.toString().toLowerCase())&&"html5"!==I||(t='<meta charset="utf-8">'));for(var o in C.metadata.parsed)if(C.metadata.parsed.hasOwnProperty(o))switch(o.toLowerCase()){case"doctype":break;case"title":r="<title>"+C.metadata.parsed.title+"</title>\n";break;case"charset":t="html"===I||"html5"===I?'<meta charset="'+C.metadata.parsed.charset+'">\n':'<meta name="charset" content="'+C.metadata.parsed.charset+'">\n';break;case"language":case"lang":a=' lang="'+C.metadata.parsed[o]+'"',n+='<meta name="'+o+'" content="'+C.metadata.parsed[o]+'">\n';break;default:n+='<meta name="'+o+'" content="'+C.metadata.parsed[o]+'">\n'}return g=e+"<html"+a+">\n<head>\n"+r+t+n+"</head>\n<body>\n"+g.trim()+"\n</body>\n</html>",g=C.converter._dispatch("completeHTMLDocument.after",g,A,C)}),I.subParser("detab",function(g,A,C){"use strict";return g=C.converter._dispatch("detab.before",g,A,C),g=g.replace(/\t(?=\t)/g," "),g=g.replace(/\t/g,"¨A¨B"),g=g.replace(/¨B(.+?)¨A/g,function(g,A){for(var C=A,I=4-C.length%4,e=0;e<I;e++)C+=" ";return C}),g=g.replace(/¨A/g," "),g=g.replace(/¨B/g,""),g=C.converter._dispatch("detab.after",g,A,C)}),I.subParser("ellipsis",function(g,A,C){"use strict";return g=C.converter._dispatch("ellipsis.before",g,A,C),g=g.replace(/\.\.\./g,"…"),g=C.converter._dispatch("ellipsis.after",g,A,C)}),I.subParser("emoji",function(g,A,C){"use strict";if(!A.emoji)return g;return g=(g=C.converter._dispatch("emoji.before",g,A,C)).replace(/:([\S]+?):/g,function(g,A){return I.helper.emojis.hasOwnProperty(A)?I.helper.emojis[A]:g}),g=C.converter._dispatch("emoji.after",g,A,C)}),I.subParser("encodeAmpsAndAngles",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeAmpsAndAngles.before",g,A,C),g=g.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&"),g=g.replace(/<(?![a-z\/?$!])/gi,"<"),g=g.replace(/</g,"<"),g=g.replace(/>/g,">"),g=C.converter._dispatch("encodeAmpsAndAngles.after",g,A,C)}),I.subParser("encodeBackslashEscapes",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeBackslashEscapes.before",g,A,C),g=g.replace(/\\(\\)/g,I.helper.escapeCharactersCallback),g=g.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("encodeBackslashEscapes.after",g,A,C)}),I.subParser("encodeCode",function(g,A,C){"use strict";return g=C.converter._dispatch("encodeCode.before",g,A,C),g=g.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/([*_{}\[\]\\=~-])/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("encodeCode.after",g,A,C)}),I.subParser("escapeSpecialCharsWithinTagAttributes",function(g,A,C){"use strict";return g=(g=C.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",g,A,C)).replace(/<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,function(g){return g.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,I.helper.escapeCharactersCallback)}),g=g.replace(/<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi,function(g){return g.replace(/([\\`*_~=|])/g,I.helper.escapeCharactersCallback)}),g=C.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",g,A,C)}),I.subParser("githubCodeBlocks",function(g,A,C){"use strict";return A.ghCodeBlocks?(g=C.converter._dispatch("githubCodeBlocks.before",g,A,C),g+="¨0",g=g.replace(/(?:^|\n)(```+|~~~+)([^\s`~]*)\n([\s\S]*?)\n\1/g,function(g,e,r,t){var a=A.omitExtraWLInCodeBlocks?"":"\n";return t=I.subParser("encodeCode")(t,A,C),t=I.subParser("detab")(t,A,C),t=t.replace(/^\n+/g,""),t=t.replace(/\n+$/g,""),t="<pre><code"+(r?' class="'+r+" language-"+r+'"':"")+">"+t+a+"</code></pre>",t=I.subParser("hashBlock")(t,A,C),"\n\n¨G"+(C.ghCodeBlocks.push({text:g,codeblock:t})-1)+"G\n\n"}),g=g.replace(/¨0/,""),C.converter._dispatch("githubCodeBlocks.after",g,A,C)):g}),I.subParser("hashBlock",function(g,A,C){"use strict";return g=C.converter._dispatch("hashBlock.before",g,A,C),g=g.replace(/(^\n+|\n+$)/g,""),g="\n\n¨K"+(C.gHtmlBlocks.push(g)-1)+"K\n\n",g=C.converter._dispatch("hashBlock.after",g,A,C)}),I.subParser("hashCodeTags",function(g,A,C){"use strict";g=C.converter._dispatch("hashCodeTags.before",g,A,C);return g=I.helper.replaceRecursiveRegExp(g,function(g,e,r,t){var a=r+I.subParser("encodeCode")(e,A,C)+t;return"¨C"+(C.gHtmlSpans.push(a)-1)+"C"},"<code\\b[^>]*>","</code>","gim"),g=C.converter._dispatch("hashCodeTags.after",g,A,C)}),I.subParser("hashElement",function(g,A,C){"use strict";return function(g,A){var I=A;return I=I.replace(/\n\n/g,"\n"),I=I.replace(/^\n/,""),I=I.replace(/\n+$/g,""),I="\n\n¨K"+(C.gHtmlBlocks.push(I)-1)+"K\n\n"}}),I.subParser("hashHTMLBlocks",function(g,A,C){"use strict";g=C.converter._dispatch("hashHTMLBlocks.before",g,A,C);var e=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"],r=function(g,A,I,e){var r=g;return-1!==I.search(/\bmarkdown\b/)&&(r=I+C.converter.makeHtml(A)+e),"\n\n¨K"+(C.gHtmlBlocks.push(r)-1)+"K\n\n"};A.backslashEscapesHTMLTags&&(g=g.replace(/\\<(\/?[^>]+?)>/g,function(g,A){return"<"+A+">"}));for(var t=0;t<e.length;++t)for(var a,n=new RegExp("^ {0,3}(<"+e[t]+"\\b[^>]*>)","im"),o="<"+e[t]+"\\b[^>]*>",s="</"+e[t]+">";-1!==(a=I.helper.regexIndexOf(g,n));){var i=I.helper.splitAtIndex(g,a),l=I.helper.replaceRecursiveRegExp(i[1],r,o,s,"im");if(l===i[1])break;g=i[0].concat(l)}return g=g.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,I.subParser("hashElement")(g,A,C)),g=I.helper.replaceRecursiveRegExp(g,function(g){return"\n\n¨K"+(C.gHtmlBlocks.push(g)-1)+"K\n\n"},"^ {0,3}\x3c!--","--\x3e","gm"),g=g.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,I.subParser("hashElement")(g,A,C)),g=C.converter._dispatch("hashHTMLBlocks.after",g,A,C)}),I.subParser("hashHTMLSpans",function(g,A,C){"use strict";function I(g){return"¨C"+(C.gHtmlSpans.push(g)-1)+"C"}return g=C.converter._dispatch("hashHTMLSpans.before",g,A,C),g=g.replace(/<[^>]+?\/>/gi,function(g){return I(g)}),g=g.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,function(g){return I(g)}),g=g.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,function(g){return I(g)}),g=g.replace(/<[^>]+?>/gi,function(g){return I(g)}),g=C.converter._dispatch("hashHTMLSpans.after",g,A,C)}),I.subParser("unhashHTMLSpans",function(g,A,C){"use strict";g=C.converter._dispatch("unhashHTMLSpans.before",g,A,C);for(var I=0;I<C.gHtmlSpans.length;++I){for(var e=C.gHtmlSpans[I],r=0;/¨C(\d+)C/.test(e);){var t=RegExp.$1;if(e=e.replace("¨C"+t+"C",C.gHtmlSpans[t]),10===r){console.error("maximum nesting of 10 spans reached!!!");break}++r}g=g.replace("¨C"+I+"C",e)}return g=C.converter._dispatch("unhashHTMLSpans.after",g,A,C)}),I.subParser("hashPreCodeTags",function(g,A,C){"use strict";g=C.converter._dispatch("hashPreCodeTags.before",g,A,C);return g=I.helper.replaceRecursiveRegExp(g,function(g,e,r,t){var a=r+I.subParser("encodeCode")(e,A,C)+t;return"\n\n¨G"+(C.ghCodeBlocks.push({text:g,codeblock:a})-1)+"G\n\n"},"^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>","^ {0,3}</code>\\s*</pre>","gim"),g=C.converter._dispatch("hashPreCodeTags.after",g,A,C)}),I.subParser("headers",function(g,A,C){"use strict";function e(g){var e,r;if(A.customizedHeaderId){var t=g.match(/\{([^{]+?)}\s*$/);t&&t[1]&&(g=t[1])}return e=g,r=I.helper.isString(A.prefixHeaderId)?A.prefixHeaderId:!0===A.prefixHeaderId?"section-":"",A.rawPrefixHeaderId||(e=r+e),e=A.ghCompatibleHeaderId?e.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,"").toLowerCase():A.rawHeaderId?e.replace(/ /g,"-").replace(/&/g,"&").replace(/¨T/g,"¨").replace(/¨D/g,"$").replace(/["']/g,"-").toLowerCase():e.replace(/[^\w]/g,"").toLowerCase(),A.rawPrefixHeaderId&&(e=r+e),C.hashLinkCounts[e]?e=e+"-"+C.hashLinkCounts[e]++:C.hashLinkCounts[e]=1,e}g=C.converter._dispatch("headers.before",g,A,C);var r=isNaN(parseInt(A.headerLevelStart))?1:parseInt(A.headerLevelStart),t=A.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,a=A.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm;g=(g=g.replace(t,function(g,t){var a=I.subParser("spanGamut")(t,A,C),n=A.noHeaderId?"":' id="'+e(t)+'"',o="<h"+r+n+">"+a+"</h"+r+">";return I.subParser("hashBlock")(o,A,C)})).replace(a,function(g,t){var a=I.subParser("spanGamut")(t,A,C),n=A.noHeaderId?"":' id="'+e(t)+'"',o=r+1,s="<h"+o+n+">"+a+"</h"+o+">";return I.subParser("hashBlock")(s,A,C)});var n=A.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;return g=g.replace(n,function(g,t,a){var n=a;A.customizedHeaderId&&(n=a.replace(/\s?\{([^{]+?)}\s*$/,""));var o=I.subParser("spanGamut")(n,A,C),s=A.noHeaderId?"":' id="'+e(a)+'"',i=r-1+t.length,l="<h"+i+s+">"+o+"</h"+i+">";return I.subParser("hashBlock")(l,A,C)}),g=C.converter._dispatch("headers.after",g,A,C)}),I.subParser("horizontalRule",function(g,A,C){"use strict";g=C.converter._dispatch("horizontalRule.before",g,A,C);var e=I.subParser("hashBlock")("<hr />",A,C);return g=g.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,e),g=g.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,e),g=g.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,e),g=C.converter._dispatch("horizontalRule.after",g,A,C)}),I.subParser("images",function(g,A,C){"use strict";function e(g,A,e,r,t,a,n,o){var s=C.gUrls,i=C.gTitles,l=C.gDimensions;if(e=e.toLowerCase(),o||(o=""),g.search(/\(<?\s*>? ?(['"].*['"])?\)$/m)>-1)r="";else if(""===r||null===r){if(""!==e&&null!==e||(e=A.toLowerCase().replace(/ ?\n/g," ")),r="#"+e,I.helper.isUndefined(s[e]))return g;r=s[e],I.helper.isUndefined(i[e])||(o=i[e]),I.helper.isUndefined(l[e])||(t=l[e].width,a=l[e].height)}A=A.replace(/"/g,""").replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback);var c='<img src="'+(r=r.replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'" alt="'+A+'"';return o&&(c+=' title="'+(o=o.replace(/"/g,""").replace(I.helper.regexes.asteriskDashAndColon,I.helper.escapeCharactersCallback))+'"'),t&&a&&(c+=' width="'+(t="*"===t?"auto":t)+'"',c+=' height="'+(a="*"===a?"auto":a)+'"'),c+=" />"}return g=(g=C.converter._dispatch("images.before",g,A,C)).replace(/!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,e),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,function(g,A,C,I,r,t,a,n){return I=I.replace(/\s/g,""),e(g,A,C,I,r,t,0,n)}),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,e),g=g.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,e),g=g.replace(/!\[([^\[\]]+)]()()()()()/g,e),g=C.converter._dispatch("images.after",g,A,C)}),I.subParser("italicsAndBold",function(g,A,C){"use strict";function I(g,A,C){return A+g+C}return g=C.converter._dispatch("italicsAndBold.before",g,A,C),g=A.literalMidWordUnderscores?(g=(g=g.replace(/\b___(\S[\s\S]*)___\b/g,function(g,A){return I(A,"<strong><em>","</em></strong>")})).replace(/\b__(\S[\s\S]*)__\b/g,function(g,A){return I(A,"<strong>","</strong>")})).replace(/\b_(\S[\s\S]*?)_\b/g,function(g,A){return I(A,"<em>","</em>")}):(g=(g=g.replace(/___(\S[\s\S]*?)___/g,function(g,A){return/\S$/.test(A)?I(A,"<strong><em>","</em></strong>"):g})).replace(/__(\S[\s\S]*?)__/g,function(g,A){return/\S$/.test(A)?I(A,"<strong>","</strong>"):g})).replace(/_([^\s_][\s\S]*?)_/g,function(g,A){return/\S$/.test(A)?I(A,"<em>","</em>"):g}),g=A.literalMidWordAsterisks?(g=(g=g.replace(/([^*]|^)\B\*\*\*(\S[\s\S]+?)\*\*\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<strong><em>","</em></strong>")})).replace(/([^*]|^)\B\*\*(\S[\s\S]+?)\*\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<strong>","</strong>")})).replace(/([^*]|^)\B\*(\S[\s\S]+?)\*\B(?!\*)/g,function(g,A,C){return I(C,A+"<em>","</em>")}):(g=(g=g.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,function(g,A){return/\S$/.test(A)?I(A,"<strong><em>","</em></strong>"):g})).replace(/\*\*(\S[\s\S]*?)\*\*/g,function(g,A){return/\S$/.test(A)?I(A,"<strong>","</strong>"):g})).replace(/\*([^\s*][\s\S]*?)\*/g,function(g,A){return/\S$/.test(A)?I(A,"<em>","</em>"):g}),g=C.converter._dispatch("italicsAndBold.after",g,A,C)}),I.subParser("lists",function(g,A,C){"use strict";function e(g,e){C.gListLevel++,g=g.replace(/\n{2,}$/,"\n");var r=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,t=/\n[ \t]*\n(?!¨0)/.test(g+="¨0");return A.disableForced4SpacesIndentedSublists&&(r=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),g=g.replace(r,function(g,e,r,a,n,o,s){s=s&&""!==s.trim();var i=I.subParser("outdent")(n,A,C),l="";return o&&A.tasklists&&(l=' class="task-list-item" style="list-style-type: none;"',i=i.replace(/^[ \t]*\[(x|X| )?]/m,function(){var g='<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';return s&&(g+=" checked"),g+=">"})),i=i.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g,function(g){return"¨A"+g}),e||i.search(/\n{2,}/)>-1?(i=I.subParser("githubCodeBlocks")(i,A,C),i=I.subParser("blockGamut")(i,A,C)):(i=(i=I.subParser("lists")(i,A,C)).replace(/\n$/,""),i=(i=I.subParser("hashHTMLBlocks")(i,A,C)).replace(/\n\n+/g,"\n\n"),i=t?I.subParser("paragraphs")(i,A,C):I.subParser("spanGamut")(i,A,C)),i=i.replace("¨A",""),i="<li"+l+">"+i+"</li>\n"}),g=g.replace(/¨0/g,""),C.gListLevel--,e&&(g=g.replace(/\s+$/,"")),g}function r(g,A){if("ol"===A){var C=g.match(/^ *(\d+)\./);if(C&&"1"!==C[1])return' start="'+C[1]+'"'}return""}function t(g,C,I){var t=A.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,a=A.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,n="ul"===C?t:a,o="";if(-1!==g.search(n))!function A(s){var i=s.search(n),l=r(g,C);-1!==i?(o+="\n\n<"+C+l+">\n"+e(s.slice(0,i),!!I)+"</"+C+">\n",n="ul"===(C="ul"===C?"ol":"ul")?t:a,A(s.slice(i))):o+="\n\n<"+C+l+">\n"+e(s,!!I)+"</"+C+">\n"}(g);else{var s=r(g,C);o="\n\n<"+C+s+">\n"+e(g,!!I)+"</"+C+">\n"}return o}return g=C.converter._dispatch("lists.before",g,A,C),g+="¨0",g=C.gListLevel?g.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(g,A,C){return t(A,C.search(/[*+-]/g)>-1?"ul":"ol",!0)}):g.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(g,A,C,I){return t(C,I.search(/[*+-]/g)>-1?"ul":"ol",!1)}),g=g.replace(/¨0/,""),g=C.converter._dispatch("lists.after",g,A,C)}),I.subParser("metadata",function(g,A,C){"use strict";function I(g){C.metadata.raw=g,(g=(g=g.replace(/&/g,"&").replace(/"/g,""")).replace(/\n {4}/g," ")).replace(/^([\S ]+): +([\s\S]+?)$/gm,function(g,A,I){return C.metadata.parsed[A]=I,""})}return A.metadata?(g=C.converter._dispatch("metadata.before",g,A,C),g=g.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/,function(g,A,C){return I(C),"¨M"}),g=g.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/,function(g,A,e){return A&&(C.metadata.format=A),I(e),"¨M"}),g=g.replace(/¨M/g,""),g=C.converter._dispatch("metadata.after",g,A,C)):g}),I.subParser("outdent",function(g,A,C){"use strict";return g=C.converter._dispatch("outdent.before",g,A,C),g=g.replace(/^(\t|[ ]{1,4})/gm,"¨0"),g=g.replace(/¨0/g,""),g=C.converter._dispatch("outdent.after",g,A,C)}),I.subParser("paragraphs",function(g,A,C){"use strict";for(var e=(g=(g=(g=C.converter._dispatch("paragraphs.before",g,A,C)).replace(/^\n+/g,"")).replace(/\n+$/g,"")).split(/\n{2,}/g),r=[],t=e.length,a=0;a<t;a++){var n=e[a];n.search(/¨(K|G)(\d+)\1/g)>=0?r.push(n):n.search(/\S/)>=0&&(n=(n=I.subParser("spanGamut")(n,A,C)).replace(/^([ \t]*)/g,"<p>"),n+="</p>",r.push(n))}for(t=r.length,a=0;a<t;a++){for(var o="",s=r[a],i=!1;/¨(K|G)(\d+)\1/.test(s);){var l=RegExp.$1,c=RegExp.$2;o=(o="K"===l?C.gHtmlBlocks[c]:i?I.subParser("encodeCode")(C.ghCodeBlocks[c].text,A,C):C.ghCodeBlocks[c].codeblock).replace(/\$/g,"$$$$"),s=s.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/,o),/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(s)&&(i=!0)}r[a]=s}return g=r.join("\n"),g=g.replace(/^\n+/g,""),g=g.replace(/\n+$/g,""),C.converter._dispatch("paragraphs.after",g,A,C)}),I.subParser("runExtension",function(g,A,C,I){"use strict";if(g.filter)A=g.filter(A,I.converter,C);else if(g.regex){var e=g.regex;e instanceof RegExp||(e=new RegExp(e,"g")),A=A.replace(e,g.replace)}return A}),I.subParser("spanGamut",function(g,A,C){"use strict";return g=C.converter._dispatch("spanGamut.before",g,A,C),g=I.subParser("codeSpans")(g,A,C),g=I.subParser("escapeSpecialCharsWithinTagAttributes")(g,A,C),g=I.subParser("encodeBackslashEscapes")(g,A,C),g=I.subParser("images")(g,A,C),g=I.subParser("anchors")(g,A,C),g=I.subParser("autoLinks")(g,A,C),g=I.subParser("simplifiedAutoLinks")(g,A,C),g=I.subParser("emoji")(g,A,C),g=I.subParser("underline")(g,A,C),g=I.subParser("italicsAndBold")(g,A,C),g=I.subParser("strikethrough")(g,A,C),g=I.subParser("ellipsis")(g,A,C),g=I.subParser("hashHTMLSpans")(g,A,C),g=I.subParser("encodeAmpsAndAngles")(g,A,C),A.simpleLineBreaks?/\n\n¨K/.test(g)||(g=g.replace(/\n+/g,"<br />\n")):g=g.replace(/ +\n/g,"<br />\n"),g=C.converter._dispatch("spanGamut.after",g,A,C)}),I.subParser("strikethrough",function(g,A,C){"use strict";return A.strikethrough&&(g=(g=C.converter._dispatch("strikethrough.before",g,A,C)).replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,function(g,e){return function(g){return A.simplifiedAutoLink&&(g=I.subParser("simplifiedAutoLinks")(g,A,C)),"<del>"+g+"</del>"}(e)}),g=C.converter._dispatch("strikethrough.after",g,A,C)),g}),I.subParser("stripLinkDefinitions",function(g,A,C){"use strict";var e=function(g,e,r,t,a,n,o){return e=e.toLowerCase(),r.match(/^data:.+?\/.+?;base64,/)?C.gUrls[e]=r.replace(/\s/g,""):C.gUrls[e]=I.subParser("encodeAmpsAndAngles")(r,A,C),n?n+o:(o&&(C.gTitles[e]=o.replace(/"|'/g,""")),A.parseImgDimensions&&t&&a&&(C.gDimensions[e]={width:t,height:a}),"")};return g=(g+="¨0").replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm,e),g=g.replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,e),g=g.replace(/¨0/,"")}),I.subParser("tables",function(g,A,C){"use strict";function e(g){return/^:[ \t]*--*$/.test(g)?' style="text-align:left;"':/^--*[ \t]*:[ \t]*$/.test(g)?' style="text-align:right;"':/^:[ \t]*--*[ \t]*:$/.test(g)?' style="text-align:center;"':""}function r(g,e){var r="";return g=g.trim(),(A.tablesHeaderId||A.tableHeaderId)&&(r=' id="'+g.replace(/ /g,"_").toLowerCase()+'"'),g=I.subParser("spanGamut")(g,A,C),"<th"+r+e+">"+g+"</th>\n"}function t(g,e){return"<td"+e+">"+I.subParser("spanGamut")(g,A,C)+"</td>\n"}function a(g){var a,n=g.split("\n");for(a=0;a<n.length;++a)/^ {0,3}\|/.test(n[a])&&(n[a]=n[a].replace(/^ {0,3}\|/,"")),/\|[ \t]*$/.test(n[a])&&(n[a]=n[a].replace(/\|[ \t]*$/,"")),n[a]=I.subParser("codeSpans")(n[a],A,C);var o=n[0].split("|").map(function(g){return g.trim()}),s=n[1].split("|").map(function(g){return g.trim()}),i=[],l=[],c=[],u=[];for(n.shift(),n.shift(),a=0;a<n.length;++a)""!==n[a].trim()&&i.push(n[a].split("|").map(function(g){return g.trim()}));if(o.length<s.length)return g;for(a=0;a<s.length;++a)c.push(e(s[a]));for(a=0;a<o.length;++a)I.helper.isUndefined(c[a])&&(c[a]=""),l.push(r(o[a],c[a]));for(a=0;a<i.length;++a){for(var d=[],p=0;p<l.length;++p)I.helper.isUndefined(i[a][p]),d.push(t(i[a][p],c[p]));u.push(d)}return function(g,A){for(var C="<table>\n<thead>\n<tr>\n",I=g.length,e=0;e<I;++e)C+=g[e];for(C+="</tr>\n</thead>\n<tbody>\n",e=0;e<A.length;++e){C+="<tr>\n";for(var r=0;r<I;++r)C+=A[e][r];C+="</tr>\n"}return C+="</tbody>\n</table>\n"}(l,u)}if(!A.tables)return g;return g=C.converter._dispatch("tables.before",g,A,C),g=g.replace(/\\(\|)/g,I.helper.escapeCharactersCallback),g=g.replace(/^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,a),g=g.replace(/^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm,a),g=C.converter._dispatch("tables.after",g,A,C)}),I.subParser("underline",function(g,A,C){"use strict";return A.underline?(g=C.converter._dispatch("underline.before",g,A,C),g=A.literalMidWordUnderscores?g.replace(/\b_?__(\S[\s\S]*)___?\b/g,function(g,A){return"<u>"+A+"</u>"}):g.replace(/_?__(\S[\s\S]*?)___?/g,function(g,A){return/\S$/.test(A)?"<u>"+A+"</u>":g}),g=g.replace(/(_)/g,I.helper.escapeCharactersCallback),g=C.converter._dispatch("underline.after",g,A,C)):g}),I.subParser("unescapeSpecialChars",function(g,A,C){"use strict";return g=C.converter._dispatch("unescapeSpecialChars.before",g,A,C),g=g.replace(/¨E(\d+)E/g,function(g,A){var C=parseInt(A);return String.fromCharCode(C)}),g=C.converter._dispatch("unescapeSpecialChars.after",g,A,C)});"function"==typeof define&&define.amd?define(function(){"use strict";return I}):"undefined"!=typeof module&&module.exports?module.exports=I:this.showdown=I}).call(this); -//# sourceMappingURL=showdown.min.js.map diff --git a/www/vincent.demeester.fr/assets/.fancyindex/styles.css b/www/vincent.demeester.fr/assets/.fancyindex/styles.css @@ -1,196 +0,0 @@ -/* styles.css - * Better styling for of Nginx FancyIndex page - * © 2015-17, Lilian Besson (Naereen) and contributors, - * open-sourced under the MIT License, https://lbesson.mit-license.org/ - * hosted on GitHub, https://GitHub.com/Naereen/Nginx-Fancyindex-Theme - */ - -* { - font-family: 'Verdana', sans-serif; - margin: 0; - padding: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html { - color: #61666c; - font-weight: 300; - font-size: 1em; - line-height: 2em; -} - -body { - margin: 0 auto; - padding-top: 20px; - max-width: 800px; -} - -thead { - font-weight: 200; - font-size: 1.2em; -} - -h1 { - font-weight: 200; - text-align: center; - font-size: 1.4em; - line-height: 3em; -} - -a { - color: #5f5f5f; - text-decoration: none; -} - a:hover { - color: #000; - } - a.clear, a.clear:link, a.clear:visited { - color: #666; - padding: 2px 0; - font-weight: 400; - font-size: 14px; - margin: 0 0 0 20px; - line-height: 14px; - display: inline-block; - border-bottom: transparent 1px solid; - vertical-align: -10px; - -webkit-transition: all 300ms ease-in; - -moz-transition: all 300ms ease-in; - -ms-transition: all 300ms ease-in; - -o-transition: all 300ms ease-in; - transition: all 300ms ease-in; - } - -input { - margin: 0 auto; - font-size: 100%; - vertical-align: middle; - *overflow: visible; - line-height: normal; - font-family: 'Open Sans', sans-serif; - font-size: 12px; - font-weight: 300; - line-height: 18px; - color: #555; - display: inline-block; - height: 20px; - padding: 4px 32px 4px 6px; - margin-bottom: 9px; - font-size: 14px; - line-height: 20px; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - width: 196px; - background-color: #fff; - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -webkit-transition: border linear .2s,box-shadow linear .2s; - -moz-transition: border linear .2s,box-shadow linear .2s; - -o-transition: border linear .2s,box-shadow linear .2s; - transition: border linear .2s,box-shadow linear .2s; -} - input:focus { - outline: 0; - border-color: rgba(0,0,0,0.8); - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(0,0,0,0.6); - } - input::-moz-focus-inner { - padding: 0; - border: 0; - } - -#search { - display: block; - margin-left: auto; - margin-right: auto; - width: 250px; - margin-top: 20px; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; - -webkit-transition: all 300ms ease-in; - -moz-transition: all 300ms ease-in; - -ms-transition: all 300ms ease-in; - -o-transition: all 300ms ease-in; - transition: all 300ms ease-in; -} - -table { - border-collapse: collapse; - font-size: 0.9em; - max-width: 100%; - margin: 20px auto 0; -} - -tr { - outline: 0; - border: 0; -} - tr:hover td { - background: #f6f6f6; - } - tr td:first-of-type { - padding-left: 10px; - padding-right: 10px; - } - tr.parent a { - color: #9099A3; - } - -th { - - text-align: left; - font-size: .75em; - padding-right: 20px; -} - th + th { - width: 25%; - } - th + th + th + th { - width: 5%; - } - -td { - padding: 5px 0; - outline: 0; - border: 0; - border-bottom: 1px solid #edf1f5; - vertical-align: middle; - text-align: left; - -webkit-transition: background 300ms ease-in; - -moz-transition: background 300ms ease-in; - -ms-transition: background 300ms ease-in; - -o-transition: background 300ms ease-in; - transition: background 300ms ease-in; -} - td:last-child,th:last-child { - text-align: right; - padding-right: 0; - } - td a { - display: block; - } - -.parent a:hover { - color: #2a2a2a; -} - -footer { - font-size:12px; - text-align:center; -} -footer a { - text-decoration: underline; - color:#990012; -} - -img { max-width: 100%; } diff --git a/www/vincent.demeester.fr/content/2022/digital-garden.org b/www/vincent.demeester.fr/content/2022/digital-garden.org @@ -1,45 +0,0 @@ -#+title: A Digital Garden you say… -#+subtitle: Let's try to describe what this "website" is about ✍️. -#+date: <2022-06-24 Fri> -#+filetags: #home -#+SETUPFILE: ../../templates/2022.org - -As I said in [[file:random.org]["Random thoughts after 2 years"]], I've been inspired by [[https://joelhooks.com/digital-garden][Joel's digital garden]] -article. This article aims to provide a bit of how I intend to maintain this space from -now on. - -This space is inspired by [[https://www.la-grange.net/][a]] [[https://larlet.fr/david/][lot]] [[https://joelhooks.com/][of]] [[https://tomcritchlow.com/][other]] spaces, but adapted to my vision. I think I've -always struggled with the blog approach. I sometimes want to publish things that are not -related to time. That can be true no matter when you read it. The opposite is true as -well. - -I really like the way Joel speaks about it. - -#+begin_quote -While not everybody has or works in a dirt garden, we all share a -familiarity with the idea of what a garden is. - -A garden is usually a place where things grow. - -Gardens can be very personal and full of whimsy or a garden can be a -source of food and substance. - -We gather and work together in community gardens to share the labor as -well as the rewards of a collective effort. - -It's a comparison that you can take very far. From "planting seeds" -and "pulling weeds" to tending mutiple gardens that each serve an -individual need or desired outcome. - -Like with real gardens, our digital gardens are a constant ebb and -flow towards entropy. - -Weeds take over. Left untended the Earth will reclaim what belongs to -it. - -The same is true for our digital gardens here on the internet. -#+end_quote - -There is quite some things I still did not figure out: -- I am not sure how to handle =rss= yet. It is slightly easier for a time-based approach - such as a "blog". diff --git a/www/vincent.demeester.fr/content/2022/random.org b/www/vincent.demeester.fr/content/2022/random.org @@ -1,39 +0,0 @@ -#+title: Random thoughts after 2 years -#+SUBTITLE: Re-organizing my writing workflow and website -#+date: <2022-05-05 Thu> -#+filetags: #home -#+SETUPFILE: ../../templates/2022.org - -* Introduction - -It has been a while since I wrote something here, and I think the reason for that is… -writing is not really central to my day-to-day "flow". For example, I do write /a lot/ as -I do journaling. But writing a blog post or an article is longer, and usually, it is -happening in my =org= folders. - -I am currently trying to re-organize a bit the website and my publishing workflow to -reduce as much as possible the "noise" between when and what I write and when and where it -is published. I think I've been inspired by [[https://joelhooks.com/digital-garden][Joel's digital garden]] article. - -#+begin_quote -For as long as I've been writing words on the internet, I've connected the words that I create in a paginated chronological format. This is the "traditional" blog style website. A linear newest-first sorted chronologically oriented list of posts. - -I'm convinced that paginated posted sorted chronologically fuckin' sucks. - -What makes a garden is interesting. It's personal. Things are organized and orderly, but with a touch of chaos around the edges. - -Just like plants in the garden I've got posts that are in various stages of growth and nurturing. Some might wither and die, and others (like this one you are reading) will flourish and provide a source of continued for the gardener and folks in community that visit 👋 - -Chronologically sorted pages of posts aren't how people actually use the internet. -#+end_quote - -I am also going to re-design a little bit (as little as possible really) to be even more -aligned with my current "thoughts". And there, I am taking inspiration from [[https://www.la-grange.net/][La Grange]] from -[[https://www.la-grange.net/karl/][Karl Dubost]]. Karl keeps the "design" (or style or whatever) of its page as they are / were -when he is published the content. This means, a page written 10 years ago, will be -rendered the same (/with devil in details if the browser changed something or course/), 10 -years ago or now. And, /for some reason/, this is *really* appealing to me. I am slowing -and incrementally trying to achieve that. Also, /note/ that the redesign is very subtle -as, the more I am looking at the current theme, the more most of it seems good enough for me. - -I am also making sure I keep an [[file:../sandbox.org][sandbox]] page always {{{mark(up-to-date)}}}. diff --git a/www/vincent.demeester.fr/content/about.org b/www/vincent.demeester.fr/content/about.org @@ -1,27 +0,0 @@ -#+TITLE: About me -#+SETUPFILE: ../../templates/2022.org - -I develop mainly in Go, a little bit of Java, a tiny bit of Python ; I'm learning Haskell -and LISP with Clojure (and also Emacs Lisp). The more I learn about about Functionnal -languages and their way of thinking, the more I feel enlighten. I'm using Emacs as my main -editor and IntelliJ IDEA for Java-related stuff. I'm a GNU/Linux user, mainly NixOS -GNU/Linux. I no longer use or need Microsoft® Windows® but I'm, sometimes, using Mac OS X -at work (but I don't really like OS X and Apple in general). I'm a FSFE fellow since 2010 -(and previously a FSF fellow), Framasoft and La Quadrature du Net supporter/donator. I -also try to support various free software, like Mediagoblin. - -* Contact - -- Email :: vinSPAMcentAT@demSPAMeesterDOT.fr -- GnuPG :: [[https://vincent.demeester.fr/about/VincentDemeester.asc][5860 2A88]] -- Instant messaging :: - - vdemeester@jabber.fsfe.org - - vdemeester@irc.freenode.net #fsfe #docker #docker-compose #docker-dev ##openweb -- Socials :: - + [[https://twitter.com/vdemeest][@vdemeest]] on Twitter - + [[https://github.com/vdemeester][@vdemeester]] on GitHub - + [[https://gitlab.com/vdemeester][@vdemeester]] on Gitlab - -* Talks - -- TODO :: TBD diff --git a/www/vincent.demeester.fr/content/images/2012/velo_casse.jpg b/www/vincent.demeester.fr/content/images/2012/velo_casse.jpg Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/2016/firefox-place-awesomebar-example.png b/www/vincent.demeester.fr/content/images/2016/firefox-place-awesomebar-example.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/2016/firefox-place-bookmark-toolbar.png b/www/vincent.demeester.fr/content/images/2016/firefox-place-bookmark-toolbar.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/2016/firefox-place-most-visited-today.png b/www/vincent.demeester.fr/content/images/2016/firefox-place-most-visited-today.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/2019/01/desk1.jpg b/www/vincent.demeester.fr/content/images/2019/01/desk1.jpg Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/2020-04-15-16-12-54.png b/www/vincent.demeester.fr/content/images/2020-04-15-16-12-54.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/bg.png b/www/vincent.demeester.fr/content/images/bg.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/bg_blue.png b/www/vincent.demeester.fr/content/images/bg_blue.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/bg_gray.png b/www/vincent.demeester.fr/content/images/bg_gray.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/bg_green.png b/www/vincent.demeester.fr/content/images/bg_green.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/bg_red.png b/www/vincent.demeester.fr/content/images/bg_red.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/bg_yellow.png b/www/vincent.demeester.fr/content/images/bg_yellow.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-blue.png b/www/vincent.demeester.fr/content/images/button-blue.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-green.png b/www/vincent.demeester.fr/content/images/button-green.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-light-blue.png b/www/vincent.demeester.fr/content/images/button-light-blue.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-orange.png b/www/vincent.demeester.fr/content/images/button-orange.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-red.png b/www/vincent.demeester.fr/content/images/button-red.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-white.png b/www/vincent.demeester.fr/content/images/button-white.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/button-yellow.png b/www/vincent.demeester.fr/content/images/button-yellow.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/comments.png b/www/vincent.demeester.fr/content/images/comments.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/emacs/2020-02-29-13-46-08.png b/www/vincent.demeester.fr/content/images/emacs/2020-02-29-13-46-08.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/emacs/2020-02-29-14-41-59.png b/www/vincent.demeester.fr/content/images/emacs/2020-02-29-14-41-59.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/emacs/2020-03-03-21-57-41.png b/www/vincent.demeester.fr/content/images/emacs/2020-03-03-21-57-41.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/emacs/2020-03-03-21-59-22.png b/www/vincent.demeester.fr/content/images/emacs/2020-03-03-21-59-22.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/email.png b/www/vincent.demeester.fr/content/images/email.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/favicon.ico b/www/vincent.demeester.fr/content/images/favicon.ico Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/favicon.png b/www/vincent.demeester.fr/content/images/favicon.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/fsfe.blogs.png b/www/vincent.demeester.fr/content/images/fsfe.blogs.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/github.png b/www/vincent.demeester.fr/content/images/github.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/identi.png b/www/vincent.demeester.fr/content/images/identi.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/imessage.png b/www/vincent.demeester.fr/content/images/imessage.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/key.png b/www/vincent.demeester.fr/content/images/key.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/lastfm.png b/www/vincent.demeester.fr/content/images/lastfm.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/linkedin.png b/www/vincent.demeester.fr/content/images/linkedin.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/logo.shortbrain.png b/www/vincent.demeester.fr/content/images/logo.shortbrain.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/sandbox/long-img.png b/www/vincent.demeester.fr/content/images/sandbox/long-img.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/sandbox/pic-demo.png b/www/vincent.demeester.fr/content/images/sandbox/pic-demo.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/sandbox/some_filename.png b/www/vincent.demeester.fr/content/images/sandbox/some_filename.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/sbr-big.png b/www/vincent.demeester.fr/content/images/sbr-big.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/sbr-medium.png b/www/vincent.demeester.fr/content/images/sbr-medium.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/sbr-small.png b/www/vincent.demeester.fr/content/images/sbr-small.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/social-rss.png b/www/vincent.demeester.fr/content/images/social-rss.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/stackoverflow.png b/www/vincent.demeester.fr/content/images/stackoverflow.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/star.png b/www/vincent.demeester.fr/content/images/star.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/user_gray.png b/www/vincent.demeester.fr/content/images/user_gray.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/images/www-inspirations/Screenshot_2020-03-22 Zettelkasten.png b/www/vincent.demeester.fr/content/images/www-inspirations/Screenshot_2020-03-22 Zettelkasten.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/index.org b/www/vincent.demeester.fr/content/index.org @@ -1,33 +0,0 @@ -#+TITLE: Hi, I'm Vincent Demeester -#+FILETAGS: home index -#+LINK: monorepo https://git.sr.ht/~vdemeester/home -#+SETUPFILE: ../templates/2022.org - -#+BEGIN_EXPORT html -<p>I'm a <em>french</em> developer 🐻, Gopher 🐹, sysadmin 🐺, <abbr title="who does all kinds of work"> factotum</abbr> 🦁, <span class="fan"><abbr title="as in free speek">free</abbr>-software <abbr title="You could say Evangelist">fan</abbr></span> 👼 and unicode lover 🐸. I'm working at <a href="https://www.redhat.com">Red Hat</a> 🎩 as a principal software engineer, previously at <a href="https://www.docker.com">Docker</a> 🐳 and <a href="http://www.zenika.com/">Zenika</a> 🐯. I am a maintainer of the <a href="https://docker.com">docker project (<a href="https://github.com/moby/moby"><code>moby/moby</code></a>, <a href="https://github.com/docker/cli"><code>docker/cli</code></a>, …), the <a href="https://github.com/tektoncd">TektonCD</a> project (<code>tektoncd/*</code>) and a tiny bit of <a href="https://github.com/NixOS/nixpkgs">NixOS</a>.</p> -#+END_EXPORT - -This is my personal space on the /World Wide Web/. It is meant to be simple, /modest/ and -*persistent* — by persistent, it means that I am trying to not breaking URIs. The list -below is a "selection" of some content. If you are looking for an "index" of all pages -(almost), there is a [[file:sitemap.org][sitemap]]. - -- [[file:2022/digital-garden.org][A Digital Garden]] -- [[file:2022/random.org][Random thoughts after 2 years]] -- [[file:sandbox.org][Sandbox]], where I try the /design/ of the website. - -See also some [[http:/docs/sitemap.html][documentation]] publish from my [[monorepo][mono-repo]]. - -I did /archive/ part of the website. The URI stay the same, so it shouldn't be a problem. -For shortcuts, here are the old [[https://vincent.demeester.fr/posts/][posts]] and [[https://vincent.demeester.fr/articles/][articles]]. - -#+BEGIN_EXPORT html -<small class='opinions'>Opinions stated here are my own and do not express the views of my employer, spouse, children, pets, neighbors, secret crushes, favorite authors, or anyone else who is not me. And maybe not even me, depending on how old this is.</small><br/> -<small class='engine'> - Powered by <a href='https://www.gnu.org/software/emacs/'>Gnu Emacs</a> and <a href='https://orgmode.org'>orgmode</a> -</small> -#+END_EXPORT - -#+BEGIN_COMMENT -{{{title}}} -#+END_COMMENT diff --git a/www/vincent.demeester.fr/content/legacy/about/index.org b/www/vincent.demeester.fr/content/legacy/about/index.org @@ -1,27 +0,0 @@ -#+TITLE: About me -#+SETUPFILE: ../../templates/2022.org - -I develop mainly in Go, a little bit of Java, a tiny bit of Python ; I'm learning Haskell -and LISP with Clojure (and also Emacs Lisp). The more I learn about about Functionnal -languages and their way of thinking, the more I feel enlighten. I'm using Emacs as my main -editor and IntelliJ IDEA for Java-related stuff. I'm a GNU/Linux user, mainly NixOS -GNU/Linux. I no longer use or need Microsoft® Windows® but I'm, sometimes, using Mac OS X -at work (but I don't really like OS X and Apple in general). I'm a FSFE fellow since 2010 -(and previously a FSF fellow), Framasoft and La Quadrature du Net supporter/donator. I -also try to support various free software, like Mediagoblin. - -* Contact - -- Email :: vinSPAMcentAT@demSPAMeesterDOT.fr -- GnuPG :: [[https://vincent.demeester.fr/about/VincentDemeester.asc][5860 2A88]] -- Instant messaging :: - - vdemeester@jabber.fsfe.org - - vdemeester@irc.freenode.net #fsfe #docker #docker-compose #docker-dev ##openweb -- Socials :: - + [[https://twitter.com/vdemeest][@vdemeest]] on Twitter - + [[https://github.com/vdemeester][@vdemeester]] on GitHub - + [[https://gitlab.com/vdemeester][@vdemeester]] on Gitlab - -* Talks - -- TODO :: TBD diff --git a/www/vincent.demeester.fr/content/legacy/articles/.setup.org b/www/vincent.demeester.fr/content/legacy/articles/.setup.org @@ -1,4 +0,0 @@ -#+AUTHOR: Vincent Demeester -#+KEYWORDS: article -#+OPTIONS: toc:nil d:(not "LOGBOOK") -#+EXCLUDE_TAGS: noexport diff --git a/www/vincent.demeester.fr/content/legacy/articles/2021-10.private.html b/www/vincent.demeester.fr/content/legacy/articles/2021-10.private.html @@ -1,317 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> -<head> -<!-- 2021-10-19 Tue 14:36 --> -<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> -<meta name="viewport" content="width=device-width, initial-scale=1" /> -<title>2021-10 Journal</title> -<meta name="generator" content="Org mode" /> -<meta name="author" content="Vincent Demeester" /> -<style type="text/css"> - <!--/*--><![CDATA[/*><!--*/ - .title { text-align: center; - margin-bottom: .2em; } - .subtitle { text-align: center; - font-size: medium; - font-weight: bold; - margin-top:0; } - .todo { font-family: monospace; color: red; } - .done { font-family: monospace; color: green; } - .priority { font-family: monospace; color: orange; } - .tag { background-color: #eee; font-family: monospace; - padding: 2px; font-size: 80%; font-weight: normal; } - .timestamp { color: #bebebe; } - .timestamp-kwd { color: #5f9ea0; } - .org-right { margin-left: auto; margin-right: 0px; text-align: right; } - .org-left { margin-left: 0px; margin-right: auto; text-align: left; } - .org-center { margin-left: auto; margin-right: auto; text-align: center; } - .underline { text-decoration: underline; } - #postamble p, #preamble p { font-size: 90%; margin: .2em; } - p.verse { margin-left: 3%; } - pre { - border: 1px solid #ccc; - box-shadow: 3px 3px 3px #eee; - padding: 8pt; - font-family: monospace; - overflow: auto; - margin: 1.2em; - } - pre.src { - position: relative; - overflow: auto; - padding-top: 1.2em; - } - pre.src:before { - display: none; - position: absolute; - background-color: white; - top: -10px; - right: 10px; - padding: 3px; - border: 1px solid black; - } - pre.src:hover:before { display: inline; margin-top: 14px;} - /* Languages per Org manual */ - pre.src-asymptote:before { content: 'Asymptote'; } - pre.src-awk:before { content: 'Awk'; } - pre.src-C:before { content: 'C'; } - /* pre.src-C++ doesn't work in CSS */ - pre.src-clojure:before { content: 'Clojure'; } - pre.src-css:before { content: 'CSS'; } - pre.src-D:before { content: 'D'; } - pre.src-ditaa:before { content: 'ditaa'; } - pre.src-dot:before { content: 'Graphviz'; } - pre.src-calc:before { content: 'Emacs Calc'; } - pre.src-emacs-lisp:before { content: 'Emacs Lisp'; } - pre.src-fortran:before { content: 'Fortran'; } - pre.src-gnuplot:before { content: 'gnuplot'; } - pre.src-haskell:before { content: 'Haskell'; } - pre.src-hledger:before { content: 'hledger'; } - pre.src-java:before { content: 'Java'; } - pre.src-js:before { content: 'Javascript'; } - pre.src-latex:before { content: 'LaTeX'; } - pre.src-ledger:before { content: 'Ledger'; } - pre.src-lisp:before { content: 'Lisp'; } - pre.src-lilypond:before { content: 'Lilypond'; } - pre.src-lua:before { content: 'Lua'; } - pre.src-matlab:before { content: 'MATLAB'; } - pre.src-mscgen:before { content: 'Mscgen'; } - pre.src-ocaml:before { content: 'Objective Caml'; } - pre.src-octave:before { content: 'Octave'; } - pre.src-org:before { content: 'Org mode'; } - pre.src-oz:before { content: 'OZ'; } - pre.src-plantuml:before { content: 'Plantuml'; } - pre.src-processing:before { content: 'Processing.js'; } - pre.src-python:before { content: 'Python'; } - pre.src-R:before { content: 'R'; } - pre.src-ruby:before { content: 'Ruby'; } - pre.src-sass:before { content: 'Sass'; } - pre.src-scheme:before { content: 'Scheme'; } - pre.src-screen:before { content: 'Gnu Screen'; } - pre.src-sed:before { content: 'Sed'; } - pre.src-sh:before { content: 'shell'; } - pre.src-sql:before { content: 'SQL'; } - pre.src-sqlite:before { content: 'SQLite'; } - /* additional languages in org.el's org-babel-load-languages alist */ - pre.src-forth:before { content: 'Forth'; } - pre.src-io:before { content: 'IO'; } - pre.src-J:before { content: 'J'; } - pre.src-makefile:before { content: 'Makefile'; } - pre.src-maxima:before { content: 'Maxima'; } - pre.src-perl:before { content: 'Perl'; } - pre.src-picolisp:before { content: 'Pico Lisp'; } - pre.src-scala:before { content: 'Scala'; } - pre.src-shell:before { content: 'Shell Script'; } - pre.src-ebnf2ps:before { content: 'ebfn2ps'; } - /* additional language identifiers per "defun org-babel-execute" - in ob-*.el */ - pre.src-cpp:before { content: 'C++'; } - pre.src-abc:before { content: 'ABC'; } - pre.src-coq:before { content: 'Coq'; } - pre.src-groovy:before { content: 'Groovy'; } - /* additional language identifiers from org-babel-shell-names in - ob-shell.el: ob-shell is the only babel language using a lambda to put - the execution function name together. */ - pre.src-bash:before { content: 'bash'; } - pre.src-csh:before { content: 'csh'; } - pre.src-ash:before { content: 'ash'; } - pre.src-dash:before { content: 'dash'; } - pre.src-ksh:before { content: 'ksh'; } - pre.src-mksh:before { content: 'mksh'; } - pre.src-posh:before { content: 'posh'; } - /* Additional Emacs modes also supported by the LaTeX listings package */ - pre.src-ada:before { content: 'Ada'; } - pre.src-asm:before { content: 'Assembler'; } - pre.src-caml:before { content: 'Caml'; } - pre.src-delphi:before { content: 'Delphi'; } - pre.src-html:before { content: 'HTML'; } - pre.src-idl:before { content: 'IDL'; } - pre.src-mercury:before { content: 'Mercury'; } - pre.src-metapost:before { content: 'MetaPost'; } - pre.src-modula-2:before { content: 'Modula-2'; } - pre.src-pascal:before { content: 'Pascal'; } - pre.src-ps:before { content: 'PostScript'; } - pre.src-prolog:before { content: 'Prolog'; } - pre.src-simula:before { content: 'Simula'; } - pre.src-tcl:before { content: 'tcl'; } - pre.src-tex:before { content: 'TeX'; } - pre.src-plain-tex:before { content: 'Plain TeX'; } - pre.src-verilog:before { content: 'Verilog'; } - pre.src-vhdl:before { content: 'VHDL'; } - pre.src-xml:before { content: 'XML'; } - pre.src-nxml:before { content: 'XML'; } - /* add a generic configuration mode; LaTeX export needs an additional - (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */ - pre.src-conf:before { content: 'Configuration File'; } - - table { border-collapse:collapse; } - caption.t-above { caption-side: top; } - caption.t-bottom { caption-side: bottom; } - td, th { vertical-align:top; } - th.org-right { text-align: center; } - th.org-left { text-align: center; } - th.org-center { text-align: center; } - td.org-right { text-align: right; } - td.org-left { text-align: left; } - td.org-center { text-align: center; } - dt { font-weight: bold; } - .footpara { display: inline; } - .footdef { margin-bottom: 1em; } - .figure { padding: 1em; } - .figure p { text-align: center; } - .equation-container { - display: table; - text-align: center; - width: 100%; - } - .equation { - vertical-align: middle; - } - .equation-label { - display: table-cell; - text-align: right; - vertical-align: middle; - } - .inlinetask { - padding: 10px; - border: 2px solid gray; - margin: 10px; - background: #ffffcc; - } - #org-div-home-and-up - { text-align: right; font-size: 70%; white-space: nowrap; } - textarea { overflow-x: auto; } - .linenr { font-size: smaller } - .code-highlighted { background-color: #ffff00; } - .org-info-js_info-navigation { border-style: none; } - #org-info-js_console-label - { font-size: 10px; font-weight: bold; white-space: nowrap; } - .org-info-js_search-highlight - { background-color: #ffff00; color: #000000; font-weight: bold; } - .org-svg { width: 90%; } - /*]]>*/--> -</style> -<script type="text/javascript"> -// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later -<!--/*--><![CDATA[/*><!--*/ - function CodeHighlightOn(elem, id) - { - var target = document.getElementById(id); - if(null != target) { - elem.classList.add("code-highlighted"); - target.classList.add("code-highlighted"); - } - } - function CodeHighlightOff(elem, id) - { - var target = document.getElementById(id); - if(null != target) { - elem.classList.remove("code-highlighted"); - target.classList.remove("code-highlighted"); - } - } - /*]]>*///--> -// @license-end -</script> -</head> -<body> -<div id="content"> -<h1 class="title">2021-10 Journal</h1> -<dl class="org-dl"> -<dt>AppStudio organization across teams</dt><dd>The way AppStudio is organize is relatively to <b>very</b> inefficient. Trying to organize a -bunch of small team — that have, for most of them, an actual product to deliver. The F2F -showed that. AppStudio initial scope is relatively small and it could be handle way more -efficiently by one <i>execution</i> team that design AppStudio based on it's need, and work on -product (and with product teams) to achieve their goal. The amount of meetings and -discussion added by this "cross-team" effort is enormous (and most likely tiring to a -lot of folks, including me). And even like that, we have the feeling that there is not -enough communication between teams (e.g., on what is the responsibilities and boundaries -of each service — and assumption that we make). This also creates sources of contentions -that would be not happening if AppStudio team was one <i>execution</i> team.</dd> - -<dt>Build Service / Tekton Service</dt><dd><p> -For some reason, we brought OSBS and CPaaS team in the AppStudio loop. For some reason, -we <i>sold</i> them that AppStudio would fit their bill. But if we look at the requirements of -each, they are very different. AppStudio has the smallest amount of requirements and -somehow should encapsulate all the others ? As said above, it seems to me that the -current vision of AppStudio is very very close to a Digital Ocean Apps made by Red -Hat. This, in my opinion, has nothing to do with a lot of requirement OSBS and other -have. It doesn't even tie AppStudio to KCP. -</p> - -<p> -Siamak tried to clarify a bit this in <a href="https://docs.google.com/presentation/d/1Y4555ByKNnc-IqudjpimeHCwO-q8XPMpYkbGVk9glmk/edit#slide=id.gf4c3d0aa3b_0_17">Managed Tekton Service</a>, by proposing a Tekton -Service (Tekton API served by something — kcp is impl. detail here) and AppStudio, OSBS, -CPaaS, RHODS, and whatever-comes-next, to build build on top. In a simple term, all -those services (internal or external) would build on top of the Tekton API. Benifiting -from each others at different possible levels (Tasks, …). This got "changed" again, for -being confusing — which is getting me confused. What is wrong with all building on top -of Tekton ? Do we feel Tekton abstraction is not at the right level ? Do we think the -abstraction that will be at AppStudio Build Service level will be the right one and more -importantly, will "fit them all" ? (note: if so, then why do we consider Tekton API in -the picture at all, is one question we can ask ourselves). Most importantly what are the -reason we <b>absolutely</b> want to use the exact same system for all ? If it's to be able to -say "we use the same tools as what we are selling", isn't the tekton api (+ tasks, … ) -level, openshift, etc., good enough already ? -</p> - -<p> -Most of the time (to not say <b>all the time</b>), duplication is better than the wrong -abstraction. I'd rather have a few things duplicated between OSBS, CPaaS, Appstudio, … -to start with, gather information on what are those duplication, and do something about -it, than trying to resolve all of the problems with one abstraction that has a high -chance of not getting it right anyway. -</p> - -<p> -It also seems the experience and "service" vision, long-term (kcp, …), is disconnected -from the first(s) milestone(s) of AppStudio. What do we want to achieve for Red Hat Summit -and after ? Is our goal to present something that is usable by customer even if it -doesn't do anything like the long-term vision (aka not based on kcp, …) ? Or is the goal -to show that KCP vision applies and work. If it's the 2nd, then, AppStudio should not -only go at the KCP vision pace but also actually participating to it, working towards it -and not focus on providing an AppStudio experience independently of it. KCP seems to be -at a relative experimental state, and, thus, if we consider AppStudio as a <i>capability</i> on -top of KCP, AppStudio itself should be consider in an experimental state too (and -organizationally wise it would change how we do things). -</p></dd> - -<dt>Decision mechansims and "unilateral changes"</dt><dd><p> -I have some relative concerns around how is AppStudio Build Service being discussed and -who is talking about what, and when. Decision, and discussion should be taken with all -representative as part of it (Siamak, Guillaume, …) and it feels like sometimes some -decision or changes are don unilaterally. A good example of this is the recent changes -<a href="https://docs.google.com/presentation/d/1Y4555ByKNnc-IqudjpimeHCwO-q8XPMpYkbGVk9glmk/edit#slide=id.gf4c3d0aa3b_0_17">Managed Tekton Service</a> slidedeck, without any prior discussion, and without actually -sharing with the rest of the stakeholders what is confusing about the current setup -(note that it had been shared with all the folks and we didn't have that "it's confusing -feedback"). This creates some confusion around who are the representative of the Build -Service team, and the Pipeline team for example. From my point of view, anyone who is -not part of the execution teams, is not a representative of those teams and it feels -really weird to me that potential discussion and decision are taken by individuals that -are not part of the "execution" (organizing the work, reviewing, committing to do -something, …). -</p> - -<p> -From my perspective (and the team perspective), I would assume (and am assuming) that -anything that is not shared to the rest of the team and not written somewhere (and -accepted/agreed by the stakholder of the project) is not decided yet and can be -discussed, changed or discarded. -</p> - -<p> -All of this causes frustration and not only for me, and it causes enough frustration for -me to have to write this and get it out of my brain. I am of course available to discuss -those thoughts more, either by mail or on a call with you all. -</p></dd> -</dl> -</div> -<div id="postamble" class="status"> -<p class="author">Author: Vincent Demeester</p> -<p class="date">Created: 2021-10-19 Tue 14:36</p> -<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p> -</div> -</body> -</html> diff --git a/www/vincent.demeester.fr/content/legacy/articles/Makefile b/www/vincent.demeester.fr/content/legacy/articles/Makefile @@ -1,8 +0,0 @@ -all: tangle - -org_files = $(patsubst %.org, %.org.tangle, $(wildcard *.org))) - -tangle: $(org_files) - -%.org.tangle: %.org - emacs --batch --eval "(progn (require 'ob-tangle) (org-babel-tangle-file \"$<\"))" diff --git a/www/vincent.demeester.fr/content/legacy/articles/a_philosophy_of_project_governance_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/a_philosophy_of_project_governance_drew_devault_s_blog.org @@ -1,26 +0,0 @@ -#+title: A philosophy of project governance | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2020/01/17/Effective-project-governance.html - -I’ve been in the maintainer role for dozens of projects for a while now, and have -moderated my fair share of conflicts. I’ve also been on the other side, many times, as a -minor contributor watching or participating in conflict within other projects. Over the -years, I’ve developed an approach to project governance which I believe is lightweight, -effective, and inclusive. - -I hold the following axioms to be true: - -- Computer projects are organized by humans, creating a social system. -- Social systems are fundamentally different from computer systems. -- Objective rules cannot be programmed into a social system. - -And the following is true of individuals within those systems: - -- Project leadership is in a position to do anything they want. -- Project leadership will ultimately do whatever they want, even if they have to come up - with an interpretation of the rules which justifies it. -- Individual contributors who have a dissonant world-view from project leadership will - never be welcome under those leaders. - -Any effective project governance model has to acknowledge these truths. To this end, the -simplest effective project governance model is a BDFL, which scales a lot further than -people might expect. diff --git a/www/vincent.demeester.fr/content/legacy/articles/add_a_contrib_directory_to_your_projects_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/add_a_contrib_directory_to_your_projects_drew_devault_s_blog.org @@ -1,11 +0,0 @@ -#+title: Add a “contrib” directory to your projects | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2020/06/06/Add-a-contrib-directory.html - -The contrib directory is used as an unorganized (or, at best, lightly organized) bin of -various useful things contributed by the community around the software, but which is not -necessarily a good candidate for being a proper part of the software. Things in contrib -should not be wired into your build system, shouldn’t be part of your automated testing, -shouldn’t be included in your documentation, and should not be installed with your -packages. contrib entries are not supported by the maintainers, and are given only a light -code review at the most. There is no guarantee whatsoever of workitude or maintenance for -anything found in contrib. diff --git a/www/vincent.demeester.fr/content/legacy/articles/apis.org b/www/vincent.demeester.fr/content/legacy/articles/apis.org @@ -1,3 +0,0 @@ -#+TITLE: APIs - -* Links diff --git a/www/vincent.demeester.fr/content/legacy/articles/architect.org b/www/vincent.demeester.fr/content/legacy/articles/architect.org @@ -1,8 +0,0 @@ - -#+TITLE: Architect - -Primary responsibilities -- Provides holistic view of the entire portfolio of products -- Develops architectural and design principles to improve performance and scalability of product -- Works with Product Manager in planning and execution of new product releases -- Assist technical team with issues needing technical expertise or complex systems knowledge diff --git a/www/vincent.demeester.fr/content/legacy/articles/bash.org b/www/vincent.demeester.fr/content/legacy/articles/bash.org @@ -1,31 +0,0 @@ - -#+TITLE: bash - -* Links :#link: -** [[https://ashishb.net/all/the-first-two-statements-of-your-bash-script-should-be/][The first two statements of your BASH script should be…]] :shell:bash: -[2020-04-15 Wed 17:22] - -#+begin_src bash -#!/usr/bin/env bash -set -euo pipefail -#+end_src - -** [[https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/][Safer bash scripts with 'set -euxo pipefail' · vaneyckt.io]] :bash: -[2019-06-21 Fri 18:11] - -Almost the same as above 🙃. - -** [[https://citizen428.net/blog/bash-error-handling-with-trap/][Bash Error Handling with Trap - citizen428.net]] -[2020-05-28 Thu 15:52] - -Traps in Bash are used for executing a command or series of commands -upon catching a signal. - -** [[https://zwischenzugs.com/2019/04/03/eight-obscure-bash-options-you-might-want-to-know-about/][Eight Obscure Bash Options You Might Want to Know About – zwischenzugs]] -[2019-06-07 Fri 14:49] - -** [[https://danpker.com/posts/2020/faster-bash-startup/][Faster Bash Startup · Daniel Parker]] -[2020-11-23 Mon 10:23] - -** [[https://work.lisk.in/2020/11/20/even-faster-bash-startup.html][Even faster bash startup — Tomáš Janoušek, Blog]] -[2020-11-23 Mon 10:23] diff --git a/www/vincent.demeester.fr/content/legacy/articles/blog.org b/www/vincent.demeester.fr/content/legacy/articles/blog.org @@ -1,8 +0,0 @@ -#+TITLE: Blog - -* Links -** [[https://robertheaton.com/2018/12/06/a-blogging-style-guide/][A blogging style guide | Robert Heaton]] -[2020-06-23 Tue 17:04] - -** [[https://robertheaton.com/a-blogging-style-guide-vol-2/][A blogging style guide vol. 2 | Robert Heaton]] -[2020-06-23 Tue 17:04] diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_a_practical_approach_to_large_scale_agile_development.org b/www/vincent.demeester.fr/content/legacy/articles/book_a_practical_approach_to_large_scale_agile_development.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: A Practical Approach to Large-Scale Agile Development diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_a_practical_guide_to_distributed_scrum.org b/www/vincent.demeester.fr/content/legacy/articles/book_a_practical_guide_to_distributed_scrum.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: A Practical Guide to Distributed Scrum diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_accelerate.org b/www/vincent.demeester.fr/content/legacy/articles/book_accelerate.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Accelerate diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_debugging_teams.org b/www/vincent.demeester.fr/content/legacy/articles/book_debugging_teams.org @@ -1,5 +0,0 @@ - -#+TITLE: Book: Debugging Teams - -I am reading this in complement (and before), [[file:book_a_practical_guide_to_distributed_scrum.org][A Practical Guide to Distributed Scrum]], -[[file:book_kanban_workbook.org][Kanban Workbook]], [[file:book_sprint.org][Sprint]] and other teams and [[file:remote_team.org][remote teams]] related resources. diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_kanban_workbook.org b/www/vincent.demeester.fr/content/legacy/articles/book_kanban_workbook.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Kanban Workbook diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_living_documentation.org b/www/vincent.demeester.fr/content/legacy/articles/book_living_documentation.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Living Documentation diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_make_time.org b/www/vincent.demeester.fr/content/legacy/articles/book_make_time.org @@ -1,4 +0,0 @@ - -#+TITLE: Book: Make time - -* TODO Add notes from icloud notes diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_managing_humans.org b/www/vincent.demeester.fr/content/legacy/articles/book_managing_humans.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Managing Humans diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_sleep_smarter.org b/www/vincent.demeester.fr/content/legacy/articles/book_sleep_smarter.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Sleep Smarter diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_sprint.org b/www/vincent.demeester.fr/content/legacy/articles/book_sprint.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Sprint diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_checklist_manifesto.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_checklist_manifesto.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: The Checklist Manifesto diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_flinch.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_flinch.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: The Flinch diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_holloway_guide_to_equity_compensation.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_holloway_guide_to_equity_compensation.org @@ -1,3 +0,0 @@ -#+TITLE: Book: The Holloway Guide to Equity Compensation - -[[https://www.holloway.com/g/equity-compensation][Book content]] diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_holloway_guide_to_remote_work.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_holloway_guide_to_remote_work.org @@ -1,3 +0,0 @@ -#+TITLE: Book: The Holloway Guide to Remote Work - -[[https://www.holloway.com/g/remote-work][Book content]]. diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_manager_s_path.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_manager_s_path.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: The Manager's Path diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_now_habit.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_now_habit.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: The Now habit diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_the_ultimate_guide_to_remote_work.org b/www/vincent.demeester.fr/content/legacy/articles/book_the_ultimate_guide_to_remote_work.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: The Ultimate Guide To Remote Work diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_time_management.org b/www/vincent.demeester.fr/content/legacy/articles/book_time_management.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Time Management diff --git a/www/vincent.demeester.fr/content/legacy/articles/book_work_clean.org b/www/vincent.demeester.fr/content/legacy/articles/book_work_clean.org @@ -1,2 +0,0 @@ - -#+TITLE: Book: Work Clean diff --git a/www/vincent.demeester.fr/content/legacy/articles/building_interactive_ssh_applications_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/building_interactive_ssh_applications_drew_devault_s_blog.org @@ -1,7 +0,0 @@ -#+title: Building interactive SSH applications | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2019/09/02/Interactive-SSH-programs.html - -After the announcement of shell access for builds.sr.ht jobs, a few people sent me some -questions, wondering how this sort of thing is done. Writing interactive SSH applications -is actually pretty easy, but it does require some knowledge of the pieces involved and a -little bit of general Unix literacy. diff --git a/www/vincent.demeester.fr/content/legacy/articles/clojure.org b/www/vincent.demeester.fr/content/legacy/articles/clojure.org @@ -1,6 +0,0 @@ -#+TITLE: Clojure - -* Links :#link: - -** [[https://simongray.github.io/essays/spread.html][Clojure: the Lisp that wants to spread]] -[2020-03-29 Sun 16:54] diff --git a/www/vincent.demeester.fr/content/legacy/articles/config_configurations.org b/www/vincent.demeester.fr/content/legacy/articles/config_configurations.org @@ -1,38 +0,0 @@ -#+TITLE: Configurations -#+ROAM_ALIAS: "configurations" -#+LINK: monorepo https://git.sr.ht/~vdemeester/home - -This set of pages and articles are describing and discussing my configurations. By -configurations I mean the [[https://dotfiles.github.io/][dotfiles]] for miscellaneous software and operating systems (like -[[https://nixos.org][=NixOS=]], or [[https://www.gnu.org/software/emacs/][GNU Emacs]]). This documents comes from my [[monorepo][monorepo]] for my personal tools and -infrastructure. I'm trying to use [[https://nixos.org/nix/][Nix]] as much as possible for those configuration, using -[[https://nixos.org][=NixOS=]] and [[https://rycee.gitlab.io/home-manager/][=home-manager=]]. But it is not limited to this. The goal of my [[monorepo][monorepo]] is: - -- Centralized (sometimes /literate/) configurations -- Shareable nix modules (e.g. =zsh= configuration on =nixos= and using =home-manager=) -- One repository to rule all my configurations, for all my machines. -- Reproductible and testable configurations - -On idea is also to try to do something like "[[https://willschenk.com/articles/2020/leveraging_disposability_for_exploration/][Leveraging disposability for exploration]]", -aka "how to play around without leaving a mess". I'll try my best to make everything -reproducible and easily testable without making /a mess/. Nix/NixOS should help with that… - -One of the goal of these pages is to do something similar to "[[http://doc.rix.si/cce/cce.html][Complete Computing -Environment]]". Alongside with [[file:emacs.org][my emacs system]] this should be a group of litterate -configurations that are /tangled/ in my [[monorepo][monorepo]]. - -* Setup - -My [[monorepo][monorepo]] can be used on multiple system — [[https://nixos.org][=NixOS=]] and [[https://fedoraproject.org/][Fedora]] mainly, but it should work -on anything that can run [[https://nixos.org/nix][Nix]] is available, and where [[https://rycee.gitlab.io/home-manager/][=home-manager=]] works. - -- [[file:install/nixos.org][How to install on NixOS]] explains how to setup and use the [[monorepo][monorepo]] when installing NixOS -- [[file:install/fedora.org][How to install on Fedora]] explains how to setup and use the [[monorepo][monorepo]] when installing on - Fedora (after the installation) - -* Tools - -- [[file:emacs.org][Emacs]] setup -- [[file:config_email_configuration.org][Email]] setup - -* To-dos diff --git a/www/vincent.demeester.fr/content/legacy/articles/config_email_configuration.org b/www/vincent.demeester.fr/content/legacy/articles/config_email_configuration.org @@ -1,439 +0,0 @@ -#+TITLE: config: Email configuration -#+SUBTITLE: A very opiniated mail setup -#+ROAM_ALIAS: "email" - -#+BEGIN_abstract -This article presents my opinionated email setup, client side. By opinionated I mean that -it requires quite some stuff (like =nixpkgs=) and is cli/emacs/… oriented. -#+END_abstract - -I used to read my mails only through the web interface of my mail provider (GMail for the -most part), or through my phone. As I'm trying to use my phone less, at least for work, -and as I wanted to not have a gmail tab always opened on my browser, I decided to -configure an email client on my laptops/desktops. - -#+TOC: headlines 2 - -So far, I ended up using the following tools: - -- [[http://isync.sourceforge.net/mbsync.html][~mbsync~]] to sync mails between server and laptop/desktop. -- [[https://marlam.de/msmtp/][~msmtp~]] to send mails. -- [[https://notmuchmail.org/][~notmuch~]] to index, and tag mails. -- [[https://www.gnu.org/software/emacs/][~emacs~]] with [[https://www.gnu.org/software/emacs/manual/html_node/gnus/][~gnus~]] and [[https://notmuchmail.org/notmuch-emacs/][~notmuch~]] for reading/sending mails. - -Something a bit special here is that I also use [[https://github.com/rycee/home-manager][~home-manager~]]… and [[https://github.com/rycee/home-manager][~home-manager~]] has -modules for those tools, so we are going to use thoses. - -*This needs to be updated and rewritten*. - -* Module -:PROPERTIES: -:CUSTOM_ID: h:db00a56e-c928-47d4-a784-3b2d2600759c -:ID: a609cdab-c681-47db-b89e-16ceb67dee39 -:END: - -Let's start by defining the module, the usual Nix way. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix - # Generated from an org file 💃 - # See : https://sbr.pm/technical/configurations/mails.html - { config, lib, pkgs, ... }: - - with lib; - let - cfg = config.profiles.mails; - in - { -#+end_src - -Let's now define options. As of now, except ~enable~ (to activate or not the module) I -don't have any options in mind. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -options = { - profiles.mails = { - enable = mkEnableOption "Enable mails configuration"; - sync = mkEnableOption "Enable sync mail service"; - frequency = mkOption { - default = "*:0/30"; - description = "Frequency at which the mail should be checked"; - type = types.str; - }; - }; -}; -#+end_src - -Finally, create the configuration. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -config = mkIf cfg.enable (mkMerge [ - { -#+end_src - -* Base settings -:PROPERTIES: -:CUSTOM_ID: h:e492a4cf-41e5-4091-9fc3-1294bef31875 -:END: - -** Accounts -:PROPERTIES: -:CUSTOM_ID: h:ddef34cf-07c6-4ae1-abc9-129440ded5e2 -:ID: c310252d-2576-445b-a130-14f5700806bf -:END: - -The next step is to actually define the accounts we want use and where we want to store -email, amongst other need. - -- We want to store mails in ~desktop/mails/{account}~. -- We don't want to input password each and every time so we're using an encrypted file - ([[https://www.gnupg.org/gph/en/manual/x110.html][symmetric encryption using GnuPG]] with a passphrase file). -- We're gonna enable diverse modules on each account - + ~mbsync~ to sync the mail with some setupts (like specific rules for GMail specific - folders) - + ~notmuch~ for email indexing - + ~msmtp~ to send a mail, using the account's smtp server - + ~astroid~ for a GUI - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -accounts.email = { - maildirBasePath = "desktop/mails"; - accounts = { - "redhat" = { - address = "vdemeest@redhat.com"; - userName = "vdemeest@redhat.com"; - realName = "Vincent Demeester"; - passwordCommand = "${pkgs.gnupg}/bin/gpg -q --for-your-eyes-only --no-tty --exit-on-status-write-error --batch --passphrase-file ${config.home.homeDirectory}/sync/rh.pass -d ${config.home.homeDirectory}/desktop/documents/rh.pass.gpg"; - imap.host = "imap.gmail.com"; - smtp.host = "smtp.gmail.com"; - mbsync = { - enable = true; - create = "both"; - expunge = "both"; - patterns = ["*" "![Gmail]*" "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail"]; - extraConfig = { - channel = { - Sync = "All"; - }; - account = { - Timeout = 120; - PipelineDepth = 1; - }; - }; - }; - notmuch.enable = cfg.sync; - astroid.enable = cfg.sync; - msmtp.enable = true; - }; - "perso" = { - address = "vinc.demeester@gmail.com"; - userName = "vinc.demeester@gmail.com"; - realName = "Vincent Demeester"; - passwordCommand = "${pkgs.gnupg}/bin/gpg -q --for-your-eyes-only --no-tty --exit-on-status-write-error --batch --passphrase-file ${config.home.homeDirectory}/sync/perso.pass -d ${config.home.homeDirectory}/desktop/documents/perso.pass.gpg"; - imap.host = "imap.gmail.com"; - smtp.host = "smtp.gmail.com"; - mbsync = { - enable = true; - create = "both"; - expunge = "both"; - patterns = ["*" "![Gmail]*" "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail"]; - extraConfig = { - channel = { - Sync = "All"; - }; - account = { - Timeout = 120; - PipelineDepth = 1; - }; - }; - }; - notmuch.enable = cfg.sync; - astroid.enable = cfg.sync; - msmtp.enable = true; - }; - "prv" = { - primary = true; - address = "vincent@demeester.fr"; - userName = "vincent@demeester.fr"; - realName = "Vincent Demeester"; - passwordCommand = "${pkgs.gnupg}/bin/gpg -q --for-your-eyes-only --no-tty --exit-on-status-write-error --batch --passphrase-file ${config.home.homeDirectory}/sync/prv.pass -d ${config.home.homeDirectory}/desktop/documents/prv.pass.gpg"; - imap.host = "mail.gandi.net"; - smtp.host = "mail.gandi.net"; - mbsync = { - enable = true; - create = "both"; - expunge = "both"; - patterns = ["*"]; - extraConfig = { - channel = { - Sync = "All"; - }; - account = { - Timeout = 120; - PipelineDepth = 1; - }; - }; - }; - notmuch.enable = cfg.sync; - astroid.enable = cfg.sync; - msmtp.enable = true; - }; - }; -}; -#+end_src - -To create the pasword files: -- create =~/desktop/documents/{account}.pass.gpg= file, you need to create a - =~/desktop/documents/prv.pass= file with the actual password. -- create =~/sync/{account}.pass= with a passphrase (long, complex, whatever…) -- encrypt =~/desktop/documents/{account}.pass.gpg= with the following command - - #+begin_src bash - gpg --batch --yes --symmetric --passphrase-file ~/sync/{account}.pass --encrypt {account.pass} - #+end_src - -- remove =~/desktop/documents/{account}.pass= - - -** ~msmtp~ wrapper -:PROPERTIES: -:CUSTOM_ID: h:cc9d0707-d775-49ef-884d-ae65174fb259 -:ID: afd568fd-e4b8-484a-9e60-b5f13b4c4c2f -:END: - -As I have multiple accounts, I need to be able to send mails from those multiple accounts -too. For this we will use ~msmtp~. We will ~$HOME/.nix-profile/bin/msmtp~ to make sure it -uses ~--read-envolep-from~. This means it will look at what ~FROM~ header is set in the -e-mail and use the correct account accordingly. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -home.file."bin/msmtp" = { - text = '' - #!${pkgs.stdenv.shell} - ${pkgs.libnotify}/bin/notify-send "Sending mail ✉️" - ${pkgs.msmtp}/bin/msmtp --read-envelope-from $@ - ''; - executable = true; -}; -#+end_src - -We also want to make sure we enable ~msmtp~. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -programs.msmtp.enable = true; -#+end_src - -And that should be all for the base settings, so let's close that part - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -} -#+end_src - - -* Syncing -:PROPERTIES: -:CUSTOM_ID: h:47e38880-580e-4335-a504-b3c9c580ec91 -:ID: fd8dbe4d-145f-42e7-993e-cbf34c0f4092 -:END: - -I may not want to sync and index mails on all computers. In practice, I only do that on -one computer and I sync these mails with the others. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -(mkIf cfg.sync { -#+end_src - -** Service -:PROPERTIES: -:CUSTOM_ID: h:2b822f1b-cd0a-430d-8942-3ad21a4bcaa1 -:ID: d2b173c8-bfa0-4f4f-8cb5-a81bf24e441f -:END: - -Now that all the configuration are defined (and generated once we run [[https://github.com/rycee/home-manager][~home-manager~]]), -we're going to enable the ~mbsync~ service to synchronize email at the given frequency. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -services.mbsync = { - enable = true; - preExec = "${config.xdg.configHome}/mbsync/preExec"; - postExec = "${config.xdg.configHome}/mbsync/postExec"; - frequency = cfg.frequency; -}; -#+end_src - -We also setup ~preExec~ and ~postExec~ hooks on the service to be able to run commands -before and after actually running ~mbsync~. - -- ~preExec~ has two main purpose : - - + Create the accounts mail folder — this is *only* useful for the first run ever, but it - is required. - + Move mails on the right folders - - from Inbox to elsewhere (All mails, …) - - (in the future) to the right folders (from the tags) - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -xdg.configFile."mbsync/preExec" = { - text = '' - #!${pkgs.stdenv.shell} - - export NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc - export NMBGIT=${config.xdg.dataHome}/notmuch/nmbug - - ${pkgs.coreutils}/bin/mkdir -p ${config.home.homeDirectory}/desktop/mails/redhat ${config.home.homeDirectory}/desktop/mails/perso - ${pkgs.afew}/bin/afew -C ${config.xdg.configHome}/notmuch/notmuchrc -m -v - ''; - executable = true; -}; -#+end_src - -- ~postExec~ will index the new emails in the ~notmuch~ database and tag mail accordingly - (to their folders and other rules in place). - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -xdg.configFile."mbsync/postExec" = { - text = '' - #!${pkgs.stdenv.shell} - - export NOTMUCH_CONFIG=${config.xdg.configHome}/notmuch/notmuchrc - export NMBGIT=${config.xdg.dataHome}/notmuch/nmbug - - ${pkgs.notmuch}/bin/notmuch new - ${pkgs.afew}/bin/afew -C ${config.xdg.configHome}/notmuch/notmuchrc --tag --new -v - # Remove inbox (lower-case) - ${pkgs.notmuch}/bin/notmuch tag -inbox -- tag:inbox - # Remove Inbox tagged message that are not in an Inbox - ${pkgs.notmuch}/bin/notmuch tag -Inbox -- not folder:redhat/Inbox and not folder:perso/Inbox and tag:Inbox - ${pkgs.libnotify}/bin/notify-send "Mails synced 📬" - ''; - executable = true; -}; -#+end_src - -Finally, let's define custom commands to simplify my mail usage. Those should be nix -package in the near future — as of now, it is a bit ugly as I'm creating binaries inside -~$HOME/bin~ instead of relying of Nix. - -- ~msync~ is an helper to run quickly ~mbsync~ systemd service from anywhere - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -home.file."bin/msync" = { - text = '' - #!${pkgs.stdenv.shell} - ${pkgs.libnotify}/bin/notify-send "Syncing mails 📫️" - systemctl --user start mbsync - ''; - executable = true; -}; -#+end_src - - -** Programs -:PROPERTIES: -:CUSTOM_ID: h:8e918ee0-4ef7-4f98-b170-dcfea20c6443 -:ID: 189f9dcd-9a41-49cf-ad9d-fa02e410a259 -:END: - -Additionally we can enable some programs and customize their behavior. Let's enable -~programs.mbsync~, which has for effect to put ~mbsync~ binary in ~PATH~ so that the user -(us) can call it. Same goes for ~programs.msmtp~ and ~programs.notmuch~. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -programs.mbsync.enable = true; -programs.notmuch.enable = true; -#+end_src - -*** Afew -:PROPERTIES: -:CUSTOM_ID: h:74f4160b-d34a-490e-b56a-ad3d0e5f966c -:ID: 5bffb703-a8f1-4252-beca-f650b069e8aa -:END: - -[[https://github.com/afewmail/afew][~afew~]] is "an initial tagging script for notmuch mail". We're going to define some extra -configuration to enable some filters and ~MailMover~ rules. - -Note: This should go away at some point as these rules are not dynamic enough for my usage. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -programs.afew = { - enable = true; - extraConfig = '' - [SpamFilter] - [KillThreadsFilter] - [ListMailsFilter] - [ArchiveSentMailsFilter] - [FolderNameFilter] - maildir_separator = / - - [MailMover] - folders = perso/Inbox redhat/Inbox - rename = true - - perso/Inbox = 'NOT tag:Inbox':"perso/[Gmail]/All Mail" - redhat/Inbox = 'NOT tag:Inbox':"redhat/[Gmail]/All Mail" - ''; -}; -#+end_src - -*** Astroid -:PROPERTIES: -:CUSTOM_ID: h:2d4558d2-0596-4c80-bab0-f259385375b1 -:ID: 1330d141-2f0d-4b02-ad40-1016e089d9dc -:END: - -[[https://github.com/astroidmail/astroid/][~astroid~]] is a "graphical threads-with-tags style, lightweight and fast, e-mail client for -Notmuch". My main e-mail client is ~emacs~ with the ~notmuch~ mode, but sometimes I want a -GUI, mainly to see wanky HTML mails that would not render correctly some times. - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -programs.astroid = { - enable = true; - externalEditor = "emacsclient -c"; - extraConfig = { - startup.queries.inbox = "tag:Inbox"; - startup.queries.inbox_perso = "folder:perso/Inbox"; - startup.queries.inbox_redhat = "folder:redhat/Inbox"; - }; -}; -#+end_src - -And that's all for the sync part, so let's close it - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -}) -#+end_src - -* Close the module -:PROPERTIES: -:CUSTOM_ID: h:7672fedf-2afa-4eb1-a9f2-38a6aada5f5f -:ID: 92526d27-5da0-4b6a-be86-7b5e0986c136 -:END: - -#+begin_src nix :tangle ~/src/home/users/modules/profiles/mails.nix -]); -} -#+end_src - - -* References -:PROPERTIES: -:CUSTOM_ID: h:7012be97-2b81-44e9-b9bb-8c4147e3d561 -:END: - -- [[https://copyninja.info/blog/email_setup.html][My personal Email setup - Notmuch, mbsync, postfix and dovecot]] -- [[https://anarc.at/blog/2016-05-12-email-setup/][Notmuch, offlineimap and Sieve setup - anarcat]] -- [[https://github.com/kzar/davemail]] -- [[https://martinralbrecht.wordpress.com/2016/05/30/handling-email-with-emacs/][Handling Email with Emacs – malb::blog]] -- [[https://kirang.in/post/emacs-as-email-client-with-offlineimap-and-mu4e-on-osx/][Emacs as email client with offlineimap and mu4e on OS X]] -- [[http://cachestocaches.com/2017/3/complete-guide-email-emacs-using-mu-and-/][A Complete Guide to Email in Emacs using Mu and Mu4e]] -- [[https://notmuchmail.org/emacstips/#index24h2][emacstips]] -- [[https://kkatsuyuki.github.io/notmuch-conf/][notmuch + emacs + offlineimap configuration procedure]] -- [[https://wiki.archlinux.org/index.php/Isync][isync - ArchWiki]] -- [[https://superuser.com/questions/437027/emacs-and-multiple-smtp-servers][email - Emacs and Multiple SMTP servers - Super User]] -- [[https://notanumber.io/2016-10-03/better-email-with-mu4e/][Better Email with mu4e | NaN]] -- [[https://wwwtech.de/articles/2016/jul/my-personal-mail-setup][My personal mail setup]] -- [[https://foobacca.co.uk/blog/2013/04/initial-tagging-and-afew/][initial tagging and afew - Foobacca]] -- [[https://martinralbrecht.wordpress.com/2016/05/30/handling-email-with-emacs/][Handling Email with Emacs – malb::blog]] -- [[http://deferred.io/2016/01/18/how-i-email.html][How I email, 2016 edition]] -- [[https://bostonenginerd.com/posts/notmuch-of-a-mail-setup-part-2-notmuch-and-emacs/][Notmuch of mail a setup Part 2 - notmuch and Emacs | Assorted Nerdery]] -- [[http://www.johnborwick.com/2019/02/09/notmuch-gmailieer.html][Checking email with gmailieer + notmuch + Emacs | John’s Blog]] -- [[https://blog.einval.eu/2019/06/one-year-with-notmuch.html][One year with Notmuch]] diff --git a/www/vincent.demeester.fr/content/legacy/articles/containers.org b/www/vincent.demeester.fr/content/legacy/articles/containers.org @@ -1,46 +0,0 @@ -#+TITLE: Containers - -From the [[file:docker.org][Docker]] [[https://www.docker.com/resources/what-container][website]] : - -#+begin_quote -A container is a standard unit of software that packages up code and all its dependencies -so the application runs quickly and reliably from one computing environment to another. A -Docker container image is a lightweight, standalone, executable package of software that -includes everything needed to run an application: code, runtime, system tools, system -libraries and settings. -#+end_quote - -[[file:docker.org][Docker]] made the use of [[file:linux.org][Linux]] containers easy, and bootstrap the [[file:open_container_initiative.org][Open Container Initiative]] -to ensure we have standards. - -* Runtimes - -There is a bunch of runtimes: -- [[file:runc.org][runc]] from [[file:open_container_initiative.org][OCI]] (simplest, default runtime) -- [[file:docker.org][docker]] from [[file:docker.org][Docker Inc.]] -- [[file:containerd.org][containerd]] under the [[file:moby_project.org][Moby Project]] -- [[file:cri_o.org][cri-o]] from [[file:red_hat.org][Red Hat]] - -* Specs - -- [[file:opencontainers_runtime_spec_oci_runtime_specification.org][opencontainers/runtime-spec: OCI Runtime Specification]] -- [[file:opencontainers_image_spec_oci_image_format.org][opencontainers/image-spec: OCI Image Format]] -- [[file:opencontainers_distribution_spec_oci_distribution_specification.org][opencontainers/distribution-spec: OCI Distribution Specification]] -- [[file:opencontainers_artifacts_oci_artifacts.org][opencontainers/artifacts: OCI Artifacts]] -* Links :#link: -** TODO [[https://kontain.me/][Kontain.me]] -[2020-06-06 Sat 16:26] -** TODO [[https://ericchiang.github.io/post/containers-from-scratch/][Containers from Scratch | posts]] -[2020-12-04 Fri 07:51] -** TODO [[https://containers.gitbook.io/build-containers-the-hard-way/][Build Containers the Hard Way (WIP) - Build Containers the Hard Way]] -[2020-12-04 Fri 07:51] - -** TODO [[https://ericchiang.github.io/post/user-namespaces/][User Namespaces | posts]] -[2020-12-04 Fri 08:09] - -** TODO [[https://ericchiang.github.io/post/privileged-containers/][Privileged Containers Aren't Containers | posts]] -[2020-12-04 Fri 08:09] -** TODO [[https://github.com/slp/krunvm][slp/krunvm: Manage lightweight VMs created from OCI images]] -[2021-01-29 Fri 10:17] -** TODO [[https://ntietz.com/tech-blog/drawbacks-of-developing-in-containers/][Drawbacks of developing in containers | nicholas@web]] -[2021-03-19 Fri 16:55] diff --git a/www/vincent.demeester.fr/content/legacy/articles/continuous_deployment.org b/www/vincent.demeester.fr/content/legacy/articles/continuous_deployment.org @@ -1,3 +0,0 @@ - -#+TITLE: continuous deployment -#+ROAM_ALIAS: "CD" diff --git a/www/vincent.demeester.fr/content/legacy/articles/continuous_integration.org b/www/vincent.demeester.fr/content/legacy/articles/continuous_integration.org @@ -1,3 +0,0 @@ - -#+TITLE: continuous integration -#+ROAM_ALIAS: "CI" diff --git a/www/vincent.demeester.fr/content/legacy/articles/css.org b/www/vincent.demeester.fr/content/legacy/articles/css.org @@ -1,8 +0,0 @@ -#+TITLE: Cascading Style Sheets - -* Links -** TODO [[https://css-tricks.com/snippets/css/complete-guide-grid/][A Complete Guide to Grid | CSS-Tricks]] -[2020-03-22 Sun 13:58] - -** TODO [[https://joshwcomeau.com/css/full-bleed/][CSS Grid full-bleed layout tutorial · Josh W Comeau]] -[2020-10-07 Wed 12:29] diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/david/2020/02/14/index.html b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/david/2020/02/14/index.html @@ -1,158 +0,0 @@ -<!doctype html><!-- This is a valid HTML5 document. --> -<!-- Screen readers, SEO, extensions and so on. --> -<html lang="fr"> -<!-- Has to be within the first 1024 bytes, hence before the <title> - See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> -<meta charset="utf-8"> -<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> -<!-- The viewport meta is quite crowded and we are responsible for that. - See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> -<meta name="viewport" content="width=device-width,initial-scale=1"> -<!-- Required to make a valid HTML5 document. --> -<title>Espoirs — David Larlet</title> -<!-- Generated from https://realfavicongenerator.net/ such a mess. --> -<link rel="apple-touch-icon" sizes="180x180" href="https://larlet.fr/static/david/icons2/apple-touch-icon.png"> -<link rel="icon" type="image/png" sizes="32x32" href="https://larlet.fr/static/david/icons2/favicon-32x32.png"> -<link rel="icon" type="image/png" sizes="16x16" href="https://larlet.fr/static/david/icons2/favicon-16x16.png"> -<link rel="manifest" href="https://larlet.fr/static/david/icons2/site.webmanifest"> -<link rel="mask-icon" href="https://larlet.fr/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> -<link rel="shortcut icon" href="../../../../static/david/icons2/favicon.ico"> -<meta name="msapplication-TileColor" content="#f0f0ea"> -<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> -<meta name="theme-color" content="#f0f0ea"> -<!-- Thank you Florens! --> -<link rel="stylesheet" href="../../../../static/david/css/style_2020-01-24.css"> -<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> -<link rel="preload" href="../../../../static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" crossorigin> -<link rel="preload" href="../../../../static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" crossorigin> -<link rel="preload" href="../../../../static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" crossorigin> - -<body class="remarkdown h1-underline h2-underline hr-center ul-star pre-tick"> - -<article> -<h1>Espoirs</h1> -<nav> - <p class="center"> - <a rel="prev" href="https://larlet.fr/david/2020/02/07/" title="Publication précédente : GAFAM+">←</a> • - <a href="https://larlet.fr/david/2020/" title="Liste des publications récentes">↑</a> - - </p> -</nav> -<hr> - -<p><em>Quelques pistes pour un monde qui (me) serait meilleur.</em></p> -<h2 id="ambivalence">Ambivalence <a href="index.html#ambivalence" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>Comme l’a montré Gramsci, les crises sont toujours des moments ambivalents pour le capitalisme. D’un côté, elles représentent un risque pour la survie du système. Mais, de l’autre, elles sont aussi des occasions de générer de nouvelles opportunités de profits. La crise environnementale n’échappe pas à cette ambivalence. L’ouragan Katrina a par exemple détruit des volumes colossaux de capital. Mais il a aussi permis l’expulsion et la rentabilisation de quartiers jusque-là populaires et donc peu rentables, ainsi que la privatisation massive des services publics, notamment les écoles. Il en va de même du tsunami de 2004 en Asie, qui a conduit à l’enclosure de nombreuses régions côtières et suscité l’installation de chaînes internationales d’hôtellerie et de restauration.</p> -<p><cite><em><a href="https://larlet.fr/david/2020/12/21/#la-nature-est-un-champ-de-bataille">La nature est un champ de bataille</a></em>, Razmig Keucheyan</cite></p> -</blockquote> -<p>Après avoir dépeint un <a href="https://larlet.fr/david/2020/02/07/">univers numérique</a> relativement triste, j’aimerais rappeler que des technologies sont porteuses d’espoirs. Le choix dépend de nous, de nos usages, de ce que l’on promeut à nos proches, des possibilités que l’on est capable de montrer.</p> -<h2 id="neutral-data">Neutral data <a href="index.html#neutral-data" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>“‘The map is not the territory ... but another version of reality,’ Wreckert said, quoting semanticist Alfred Korzybski, one of William S. Burroughs’ biggest influences. “Data is always translated to what they might be presented. The images, lists, graphs, and maps that represent those data are all interpretations, and there is no such thing as neutral data. Data is always collected for a specific purpose, by a combination of people, technology, money, commerce, and government.”</p> -<p><cite><em><a href="https://www.vice.com/en_us/article/9393w7/this-man-created-traffic-jams-on-google-maps-using-a-red-wagon-full-of-phones">How to Fake a Traffic Jam on Google Maps</a></em> (<a href="https://larlet.fr/david/cache/2020/42b02cc81a7fface539dfb3397f0a464/">cache</a>)</cite></p> -</blockquote> -<p>Rien n’est neutre mais tout est relativement <em>hackable</em>. Le manque de résilience d’un système fortement couplé a cette défaillance qu’il suffit d’un petit grain de sable pour que la machine ne sache quoi en faire.</p> -<p>J’imagine un <em>business</em> qui créerait un faux embouteillage le matin pour faire passer plus rapidement les personnes à l’origine de celui-ci par ce même endroit. Puis un concurrent qui rendrait inopérant le raccourci. Quitte à marcher sur la tête, autant que ça soit avec du fun !</p> -<h2 id="rss">RSS <a href="index.html#rss" title="Ancre vers cette partie">#</a></h2><p>J’ai posé la <a href="https://mastodon.social/@dav/103524352995568684">question suivante sur Mastodon</a> :</p> -<blockquote> -<p>Si vous n’utilisez pas de lecteur de flux RSS, pourquoi ?</p> -</blockquote> -<p>Et j’ai eu pas mal de réponses que je souhaite consigner ici, si vous voulez connaître les auteur·ice·s, il·le·s sont lié·e·s sur la page originale.</p> -<blockquote> -<p>j’utilisais miniflux, mais j’ai arrêté, trop de flux, je n’arrivais pas à tout lire, je trouvais que je tombais en pleine FOMO :p</p> -</blockquote> -<blockquote> -<p>j’en utilisais vers 2010 puis j’ai progressivement arrêté, Twitter et la gestion des listes fait le taff pour moi. Sinon j’ai l’impression d’avoir une boîte mail à devoir vider et je prends pas plaisir à lire les derniers articles</p> -</blockquote> -<blockquote> -<p>Parce que j’ai trop de trucs à suivre, et du coup j’en perd. -Et heureusement, sinon je ne ferais que ça ^^. -Donc ne pas utiliser de flux RSS est une technique de tri simple et efficace...</p> -<p>Une professionnelle m’a assuré que je n’étais pas cliniquement dangereux pour les autres.</p> -</blockquote> -<blockquote> -<p>Je peux répondre à la place de mon collègue avec qui j’en parlais il y a peu : "Parce que les réseaux sociaux me fournissent toute l’actu que je veux"</p> -<p>Ignorance, quand tu nous tiens</p> -</blockquote> -<blockquote> -<p>j’ai l’impression que je vais devoir bidouiller un truc perso pour en profiter. je me trompe sûrement mais je ne connais pas les services qui permettent d’utiliser le rss. Et comme de toutes façons j’ai pas le temps de lire ce que je suis déjà, je ne cherche pas plus loin que ça.</p> -</blockquote> -<blockquote> -<p>J’avais arrêté au profit de twitter (sélection de compte suivi) -J’ai récemment remis en place FreshRSS car je trouve qu’il y a trop de bruit parasites sur TW. -Et j’ai arrêté les flux RSS généralistes qui polluent trop pour me concentrer sur quelques flux intéressant : l’idée étant de ne pas être submergé d’articles -Ensuite je survole régulièrement et je marque "comme lu" (sans les lire) ceux qui ne m’intéressent pas; je lis ceux qui m’intéressent quand j’ai le temps; j’en enregistre certain dans Wallabag/Shaarli pour ne pas les perdre</p> -</blockquote> -<blockquote> -<p>J’ai toujours utilisé les flux RSS, mais mon usage s’est intensifié dans le cadre de ma dégafamisation. On croise les doigts que les flux RSS des chaînes Youtube restent en place :)</p> -</blockquote> -<blockquote> -<p>Je m’en sers, mais ça demande un peu de discipline : t’as tendances à ajouter tout et n’importe quoi jusqu’à le rendre illisible/inutilisable. Je comprends que ça puisse décourager ou fatiguer certains/certaines : ça demande un peu de rigueur !</p> -</blockquote> -<blockquote> -<p>J’utilise mais probablement mal. Principalement probablement par méconnaissance des outils. Je ne trouve pas notamment de clients qui me satisfasse pleinement que ce soit sur Debian ou Android. Mais j’utilise de plus en plus oui !</p> -</blockquote> -<p>Merci pour toutes ces réponses, ça me donne du grain à moudre pour un <em>vapoware</em> qui a au moins 15 ans.</p> -<h2 id="confuse-trackers">Confuse trackers <a href="index.html#confuse-trackers" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>Each time she refreshed the Explore tab, it was a completely different topic, none of which she was interested in. That's because Mosley wasn't the only person using this account -- it belonged to a group of her friends, at least five of whom could be on at any given time. Maybe they couldn't hide their data footprints, but they could at least leave hundreds behind to confuse trackers.</p> -<p>These teenagers are relying on a sophisticated network of trusted Instagram users to post content from multiple different devices, from multiple different locations.</p> -<p>If you wanted to confuse Instagram, here's how.</p> -<p><cite><em><a href="https://www.cnet.com/news/teens-have-figured-out-how-to-mess-with-instagrams-tracking-algorithm/">Teens have figured out how to mess with Instagram's tracking algorithm</a></em> (<a href="https://larlet.fr/david/cache/2020/dd11327ac0ac5bf42163e3a6315012b8/">cache</a>)</cite></p> -</blockquote> -<p>C’est une somme de petits actes de résistance qui donnent de l’espoir, en particulier venant des jeunes générations. Je suis encore trop dans l’exclusion élitiste (ne pas aller sur Facebook) et pas assez dans le <em>hack</em> collectif (y aller et participer au bruit alternatif pour se protéger… et protéger les autres ?).</p> -<p><em>Note: le contenu de l’article est plein de liens avec des attributs du type <code>data-link-tracker-options="{&quot;action&quot;:&quot;inline-annotation|Mobile Apps|CNET_CAT_TOPIC|450&quot;}"</code>, c’est assez succulent vu le contenu…</em></p> -<h2 id="ecologie-sociale">Écologie sociale <a href="index.html#ecologie-sociale" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>Dans mon esprit, écologie a toujours signifié écologie sociale : la conviction que l’idée même de dominer la nature découle de la domination de l’humain par l’humain, que ces soit des femmes par les hommes, des jeunes par leurs aînés, d’un groupe ethnique par un autre, de la société par l’État, de l’individu par la bureaucratie, aussi bien que d’une classe économique par une autre ou d’un peuple colonisé par une puissance coloniale.</p> -<p>[…]</p> -<p>Aussi longtemps que persistera la hiérarchie, aussi longtemps que la domination imposera un système d’organisation élitiste à l’humanité, le projet de dominer la nature se perpétuera et conduira inévitablement notre planète vers l’extinction écologique.</p> -<p><cite><em>Lettre ouverte au mouvement écologiste</em>, février 1980, extrait de <em><a href="https://larlet.fr/david/2020/12/21/#pouvoir-de-detruire-pouvoir-de-creer">Pouvoir de détruire, pouvoir de créer</a></em>, Murray Bookchin</cite></p> -</blockquote> -<p>Ce que je trouve intéressant dans cette réflexion, c’est qu’il existe de très nombreuses formes de luttes qui permettraient d’aboutir (?) à un résultat proche et enthousiasmant. Chacun·e peut avoir son propre cheval de bataille plus ou moins léger s’ils finissent par converger, voire s’émuler. En ayant l’esprit souple, on peut potentiellement imaginer être sur plusieurs chevaux à la fois. Ou séquentiellement.</p> -<p>Quel cirque.</p> -<h2 id="alternumerisme">Alternumérisme <a href="index.html#alternumerisme" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>Il me semble que nous pouvons peut-être encore être pour l’alternumérisme. Mais ce qui tenait de l’affirmation devient chaque jour un peu plus une interrogation, tant ce que nous prônons, finalement n’arrive pas à devenir autre chose qu’un instrument, un argument même pour permettre aux excès du numérisme de devenir toujours plus excessifs.</p> -<p><cite><em><a href="http://www.internetactu.net/2020/02/13/de-lalternumerisme-dautres-numeriques-sont-ils-possibles/">De l’alternumérisme : d’autres numériques sont-ils possibles ?</a></em> (<a href="https://larlet.fr/david/cache/2020/ad8fd9818243ad950a794021d3dc794c/">cache</a>)</cite></p> -</blockquote> -<p><em>Pour un autre numérique.</em></p> -<p>J’aime ce double sens. À quel point est-ce qu’un autre numérique passe par une dé-numérisation de l’autre ? Ne plus communiquer par un biais numérique, ne plus partager des photos par un biais numérique, ne plus transmettre une émotion par un émoji, ne plus être informé que par des personnes physiquement proches.</p> -<p>Je doute que ce soit <em>via</em> le numérique que l’on réussira à inventer un autre numérique.</p> -<p>🤖</p> -<h2 id="sagesse">Sagesse <a href="index.html#sagesse" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>Il n’est pas nécessaire de faire un effort pour penser d’une manière particulière. Votre pensée ne devrait pas être partiale. Nous pensons simplement avec notre esprit intégral, et voyons sans un effort les choses telles qu’elles sont. Simplement voir, et être prêt à voir les choses avec notre esprit intégral, c’est cela la pratique de zazen. Si nous sommes prêts à penser, nous n’avons pas besoin de faire un effort pour penser. C’est ce qu’on appelle la conscience présente. La conscience présente est en même temps la sagesse. Par sagesse, nous n’entendons pas une faculté ou une philosophie particulières. Avoir l’esprit prêt, cette qualité est la sagesse. Divers enseignements et philosophies, diverses formes d’études et de recherche, pourraient donc être la sagesse. Mais nous ne devrions pas nous attacher à une sagesse particulière, telle celle enseignée par Bouddha. La sagesse n’est pas quelque chose qui s’apprend. La sagesse viendra de votre conscience présente. Il s’agit donc d’être prêt à voir, et d’être prêt à penser. C’est ce qu’on appelle la vacuité de votre esprit. La vacuité n’est autre que la pratique de zazen.</p> -<p><cite><em><a href="https://larlet.fr/david/2020/12/21/#esprit-zen-esprit-neuf">Esprit zen, esprit neuf</a></em>, Shunryu Suzuki</cite></p> -</blockquote> -<p>Et si l’espoir était une pratique ? Un petit feu à alimenter régulièrement pour réchauffer notre cœur. Et pour éclairer les sourires des autres.</p> -<p><em>Une même flamme peut se partager à l’infini.</em></p> -<p>(Il y a des chances de finir sur un tas de cendres par contre.)</p> -<h2 id="empathie">Empathie <a href="index.html#empathie" title="Ancre vers cette partie">#</a></h2><blockquote> -<p>— Tu vois si tu m’expliques ça me permet d’avoir de l’empathie pour toi.<br /> -— C’est quoi l’empathie ?<br /> -— C’est essayer de ressentir ce que ressentent les autres.<br /> -<em>[Lâche un gros pet.]</em><br /> -— Mais c’est pour t’aider papa !</p> -</blockquote> -<p>:facepalm:</p> - -<nav> - <p class="center"> - <a rel="prev" href="https://larlet.fr/david/2020/02/07/" title="Publication précédente : GAFAM+">←</a> • - <a href="https://larlet.fr/david/2020/" title="Liste des publications récentes">↑</a> - - </p> -</nav> -</article> - - -<hr> - -<footer> - <p> - <a href="https://larlet.fr/david/" title="Aller à l’accueil">🏠</a> • - <a href="https://larlet.fr/david/log/" title="Accès au flux RSS">🤖</a> • - <a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> • - <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> • - <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr> - </p> -</footer> -<script src="../../../../static/david/js/instantpage-3.0.0.min.js" type="module" defer></script> -</body> -</html>- \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/FiraCode-Retina.woff b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/FiraCode-Retina.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/FiraCode-Retina.woff2 b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/FiraCode-Retina.woff2 Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_bold.woff b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_bold.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_bold.woff2 b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_bold.woff2 Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_italic.woff b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_italic.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_italic.woff2 b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_italic.woff2 Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_regular.woff b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_regular.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_regular.woff2 b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/fonts/triplicate_t4_poly_regular.woff2 Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/style_2020-01-24.css b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/css/style_2020-01-24.css @@ -1,548 +0,0 @@ -/*! ReMarkdown 3.0.0 (MIT) https://fvsch.github.io/remarkdown/ */ -/* - Included: all styles - Defaults: hn-reset hn-hash ul-hyphen ol-decimal quote-gt em-star strong-star a-bracket code-tick pre-indent hr-star -*/ -.remarkdown { - line-height: 1.5; - font-family: monospace, monospace; -} - -.remarkdown pre, -.remarkdown code, -.remarkdown kbd, -.remarkdown samp { - font-family: inherit; -} - -.remarkdown h1 { - font-size: inherit; - font-weight: inherit; - margin-top: 2.25em; - margin-bottom: 1.5em; -} - -.remarkdown h2 { - font-size: inherit; - font-weight: inherit; - margin-top: 2.25em; - margin-bottom: 1.5em; -} - -.remarkdown h3, -.remarkdown h4, -.remarkdown h5, -.remarkdown h6 { - font-size: inherit; - font-weight: inherit; - margin-top: 1.5em; - margin-bottom: 1.5em; -} - -.remarkdown h1::before { - content: "# "; -} - -.remarkdown h2::before { - content: "## "; -} - -.remarkdown h3::before { - content: "### "; -} - -.remarkdown h4::before { - content: "#### "; -} - -.remarkdown h5::before { - content: "##### "; -} - -.remarkdown h6::before { - content: "###### "; -} - -.remarkdown.h1-underline h1, -.remarkdown.h2-underline h2 { - display: table; - overflow: hidden; - position: relative; - padding-bottom: 1.5em; -} - -.remarkdown.h1-underline h1::before, -.remarkdown.h2-underline h2::before { - content: none; -} - -.remarkdown.h1-underline h1::after, -.remarkdown.h2-underline h2::after { - position: absolute; - bottom: 0; - left: 0; - height: 1.5em; - width: 100%; - overflow: hidden; - word-break: break-all; - cursor: default; -} - -.remarkdown.h1-underline h1::after { - content: "========================================================================================================================"; -} - -.remarkdown.h2-underline h2::after { - content: "------------------------------------------------------------------------------------------------------------------------"; -} - -.remarkdown p { - margin-top: 1.5em; - margin-bottom: 1.5em; -} - -.remarkdown figure { - margin: 1.5em 0 1.5em; -} - -hr { - height: 1.5em; - line-height: 1.5em; - margin: 1.5em 0 1.5em; - border: none; - color: inherit; -} - -.remarkdown.hr-center hr { - text-align: center; -} - -.remarkdown hr::before { - content: "* * * *"; -} - -.remarkdown.hr-hyphen hr::before { - content: "-------"; -} - -.remarkdown ul { - margin: 1.5em 0ch 1.5em 4ch; - padding: 0; -} - -.remarkdown li ul { - margin-top: 0; - margin-bottom: 0; -} - -.remarkdown.ul-plus ul { - list-style: none; -} - -.remarkdown.ul-plus ul > li::before { - float: left; - width: 1ch; - margin-left: -4ch; - margin-right: 1ch; - content: "+"; -} - -.remarkdown.ul-star ul { - list-style: none; -} - -.remarkdown.ul-star ul > li::before { - float: left; - width: 1ch; - margin-left: -4ch; - margin-right: 1ch; - content: "*"; -} - -.remarkdown ul { - list-style: none; -} - -.remarkdown ul > li::before { - float: left; - width: 1ch; - margin-left: -4ch; - margin-right: 1ch; - content: "-"; -} - -.remarkdown ol { - margin: 1.5em 0ch 1.5em 4ch; - padding: 0; -} - -.remarkdown li ol { - margin-top: 0; - margin-bottom: 0; -} - -.remarkdown ol { - list-style: none; - counter-reset: rmd-ol; -} - -.remarkdown ol > li { - counter-increment: rmd-ol; -} - -.remarkdown ol > li::before { - float: left; - margin-left: -4ch; - margin-right: 1ch; - min-width: 2ch; - content: counter(rmd-ol) "."; -} - -.remarkdown.ol-zero ol { - list-style: none; -} - -.remarkdown.ol-zero ol > li::before { - float: left; - margin-left: -4ch; - margin-right: 1ch; - min-width: 2ch; - content: "0."; -} - -.remarkdown.ol-alpha ol { - list-style: none; - counter-reset: rmd-ol; -} - -.remarkdown.ol-alpha ol > li { - counter-increment: rmd-ol; -} - -.remarkdown.ol-alpha ol > li::before { - float: left; - margin-left: -4ch; - margin-right: 1ch; - min-width: 2ch; - content: counter(rmd-ol, lower-alpha) "."; -} - -.remarkdown a::before { - content: "["; -} - -.remarkdown a::after { - content: "]"; -} - -.remarkdown.a-showurl a[href]::before { - content: "["; -} - -.remarkdown.a-showurl a[href]::after { - content: "](" attr(href) ")"; - word-break: break-all; -} - -.remarkdown em, -.remarkdown strong { - font-style: normal; - font-weight: normal; -} - -.remarkdown em::before, -.remarkdown em::after { - content: "*"; -} - -.remarkdown.em-underscore em::before, -.remarkdown.em-underscore em::after { - content: "_"; -} - -.remarkdown strong::before, -.remarkdown strong::after { - content: "**"; -} - -.remarkdown.strong-underscore strong::before, -.remarkdown.strong-underscore strong::after { - content: "__"; -} - -.remarkdown code::before, -.remarkdown code::after { - content: "`"; -} - -.remarkdown pre code::before, -.remarkdown pre code::after { - display: none; -} - -.remarkdown pre { - margin-top: 1.5em; - margin-bottom: 1.5em; - tab-size: 4; -} - -.remarkdown pre { - margin-left: 4ch; - margin-right: 0ch; -} - -.remarkdown.pre-tick pre::before, -.remarkdown.pre-tick pre::after, -.remarkdown.pre-tilde pre::before, -.remarkdown.pre-tilde pre::after, -.remarkdown.pre-tilde-full pre::before, -.remarkdown.pre-tilde-full pre::after { - display: block; - width: 100%; - height: 1.5em; - cursor: default; -} - -.remarkdown.pre-tick pre::before, -.remarkdown.pre-tick pre::after { - content: "```"; - position: relative; - top: 0.25em; -} - -.remarkdown.pre-tilde pre::before, -.remarkdown.pre-tilde pre::after { - content: "~~~"; - overflow: hidden; - word-break: break-all; -} - -.remarkdown.pre-tilde-full pre::before, -.remarkdown.pre-tilde-full pre::after { - content: "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; - overflow: hidden; - word-break: break-all; -} - -.remarkdown blockquote { - margin: 1.5em 2ch 1.5em 2ch; - padding: 0; -} - -.remarkdown blockquote { - position: relative; -} - -.remarkdown blockquote::before { - position: absolute; - top: 0; - left: -2ch; - bottom: 0; - width: 1ch; - overflow: hidden; - white-space: pre; - content: ">\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a"; - cursor: default; -} - -.remarkdown.del-gfm del { - text-decoration: none; -} - -.remarkdown.del-gfm del::before, -.remarkdown.del-gfm del::after { - content: "~~"; -} - -.remarkdown.table-marker table { - margin-top: 1.5em; - margin-bottom: 1.5em; - border-collapse: collapse; -} - -.remarkdown.table-marker tr > * { - min-width: 3ch; - position: relative; - padding: 0; - text-align: inherit; - vertical-align: top; - font-weight: normal; - border: none; -} - -.remarkdown.table-marker tr > * + * { - padding-left: 3ch; -} - -.remarkdown.table-marker tr:first-child > th:not([scope="row"]) { - padding-bottom: 1.5em; -} - -.remarkdown.table-marker tr:first-child > th:not([scope="row"])::after { - content: "--------------------------------------------------------------------------------------------------------------"; - position: absolute; - bottom: 0; - left: 0; - right: 0; - overflow: hidden; - word-break: break-all; - height: 1.5em; -} - -.remarkdown.table-marker tr:first-child > * + th:not([scope="row"])::after { - left: 3ch; -} - -.remarkdown.table-marker tr > * + *::before { - content: "|\a|\a|\a|\a|\a|\a|\a|\a|\a|\a"; - position: absolute; - overflow: hidden; - left: 1ch; - top: 0; - bottom: 0; - white-space: pre; -} - - -/* Custom*/ -@font-face { - font-family: 'triplicate_t4p'; - src: url('fonts/triplicate_t4_poly_regular.woff2') format('woff2'), - url('fonts/triplicate_t4_poly_regular.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: 'triplicate_t4p'; - src: url('fonts/triplicate_t4_poly_bold.woff2') format('woff2'), - url('fonts/triplicate_t4_poly_bold.woff') format('woff'); - font-weight: bold; - font-style: normal; - font-display: swap; -} -@font-face { - font-family: 'triplicate_t4p'; - src: url('fonts/triplicate_t4_poly_italic.woff2') format('woff2'), - url('fonts/triplicate_t4_poly_italic.woff') format('woff'); - font-weight: normal; - font-style: italic; - font-display: swap; -} -@font-face { - font-family: 'firacode_retina'; - src: url('fonts/FiraCode-Retina.woff2') format('woff2'), - url('fonts/FiraCode-Retina.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - -.remarkdown { - font-family: 'triplicate_t4p', Menlo, Monaco, 'DejaVu Sans Mono', Consolas, monospace; - margin: 0 auto; - padding: 0 1.5ch; - max-width: 58ch; - background-color: #f0f0ea; - color: #07486c; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; -} -.remarkdown code, -.remarkdown pre { - font-family: 'firacode_retina', Courier, "Courier New", monospace; -} -/* Font-sizes and line-heights. */ -.remarkdown { - font-size: .9rem; - line-height: 1.3; -} -@media (min-width: 20em) { - .remarkdown { - font-size: 1.05rem; - line-height: 1.45; - } -} -@media (min-width: 60em) { - .remarkdown { - font-size: 1.25rem; - line-height: 1.5; - } -} -/* Keep regular style for strong/em. */ -.remarkdown strong { - font-weight: bold; -} -.remarkdown em { - font-style: italic; -} -/* Reset indentation, need room for code. */ -.remarkdown pre { - margin-left: 0; -} -/* Soften the Markdown-like markers. */ -.remarkdown ::before, -.remarkdown ::after { - opacity: .6; - color: SteelBlue; -} -/* Set link colors close to defaults but softer. */ -a { - color: RoyalBlue; - text-decoration-skip-ink: auto; - text-decoration-thickness: 0.05em; - text-underline-offset: 0.1em; - text-decoration: none; -} -a:visited { - color: RebeccaPurple; -} -a:focus, -a:active, -a:hover, -a:visited:hover { - color: white; - background-color: RoyalBlue; - text-decoration: underline; -} -/* I could not resist. Probably bad. */ -h1 { - margin-left: auto; - margin-right: auto; -} -.center, -footer { - text-align: center; - margin-bottom: 1.5rem; -} -footer { - margin-bottom: 3rem; -} -/* Images */ -figure { - text-align: center; -} -img { - max-width: 512px; - width: 100%; - padding: 1px; - border: 1px solid SteelBlue; -} -/* Surprisingly not browsers default. */ -summary { - cursor: pointer; -} -/* Consistency with abbreviations style. */ -abbr[title] { - cursor: help; - border-bottom: none; - text-decoration: none; -} -abbr[title]::after { - content: " (" attr(title) ")"; - cursor: default; -} -footer abbr[title]::after { - content: none; -} - diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/icons2/favicon.ico b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/icons2/favicon.ico Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/js/instantpage-3.0.0.min.js b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/larlet.fr/static/david/js/instantpage-3.0.0.min.js @@ -1,2 +0,0 @@ -/*! instant.page v3.0.0 - (C) 2019 Alexandre Dieulot - https://instant.page/license */ -let t,e;const n=new Set,o=document.createElement("link"),s=o.relList&&o.relList.supports&&o.relList.supports("prefetch")&&window.IntersectionObserver&&"isIntersecting"in IntersectionObserverEntry.prototype,i="instantAllowQueryString"in document.body.dataset,r="instantAllowExternalLinks"in document.body.dataset,a="instantWhitelist"in document.body.dataset;let c=65,d=!1,l=!1,u=!1;if("instantIntensity"in document.body.dataset){const t=document.body.dataset.instantIntensity;if("mousedown"==t.substr(0,"mousedown".length))d=!0,"mousedown-only"==t&&(l=!0);else if("viewport"==t.substr(0,"viewport".length))navigator.connection&&(navigator.connection.saveData||navigator.connection.effectiveType.includes("2g"))||("viewport"==t?document.documentElement.clientWidth*document.documentElement.clientHeight<45e4&&(u=!0):"viewport-all"==t&&(u=!0));else{const e=parseInt(t);isNaN(e)||(c=e)}}if(s){const n={capture:!0,passive:!0};if(l||document.addEventListener("touchstart",function(t){e=performance.now();const n=t.target.closest("a");if(!f(n))return;h(n.href)},n),d?document.addEventListener("mousedown",function(t){const e=t.target.closest("a");if(!f(e))return;h(e.href)},n):document.addEventListener("mouseover",function(n){if(performance.now()-e<1100)return;const o=n.target.closest("a");if(!f(o))return;o.addEventListener("mouseout",m,{passive:!0}),t=setTimeout(()=>{h(o.href),t=void 0},c)},n),u){let t;(t=window.requestIdleCallback?t=>{requestIdleCallback(t,{timeout:1500})}:t=>{t()})(()=>{const t=new IntersectionObserver(e=>{e.forEach(e=>{if(e.isIntersecting){const n=e.target;t.unobserve(n),h(n.href)}})});document.querySelectorAll("a").forEach(e=>{f(e)&&t.observe(e)})})}}function m(e){e.relatedTarget&&e.target.closest("a")==e.relatedTarget.closest("a")||t&&(clearTimeout(t),t=void 0)}function f(t){if(t&&t.href&&(!a||"instant"in t.dataset)&&(r||t.origin==location.origin||"instant"in t.dataset)&&["http:","https:"].includes(t.protocol)&&("http:"!=t.protocol||"https:"!=location.protocol)&&(i||!t.search||"instant"in t.dataset)&&!(t.hash&&t.pathname+t.search==location.pathname+location.search||"noInstant"in t.dataset))return!0}function h(t){if(n.has(t))return;const e=document.createElement("link");e.rel="prefetch",e.href=t,document.head.appendChild(e),n.add(t)} diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/org-board-7af3b3f4-a1f0-4adf-80f5-833d55ca7f86.log b/www/vincent.demeester.fr/content/legacy/articles/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17_19_57_0100/org-board-7af3b3f4-a1f0-4adf-80f5-833d55ca7f86.log @@ -1 +0,0 @@ -/run/current-system/sw/bin/wget --directory-prefix=/home/vincent/desktop/org/personal/data/7a/f3b3f4-a1f0-4adf-80f5-833d55ca7f86/2020-02-14T17:19:57+0100// "-e robots=off" --page-requisites --adjust-extension --convert-links https://larlet.fr/david/2020/02/14/- \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/89/96fae4-8792-4fcb-a18c-f625d63881e0/elbank-ynab.html b/www/vincent.demeester.fr/content/legacy/articles/data/89/96fae4-8792-4fcb-a18c-f625d63881e0/elbank-ynab.html @@ -1,330 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <title>Using Ledger for YNAB-like envelope budgeting</title> - <meta name="description" content="Bye bye Elbank"> - - <link rel="shortcut icon" type="image/png" href="/favicon.png"/> - <link href="https://fonts.googleapis.com/css?family=Fira+Mono|Gentium+Book+Basic|Lato" rel="stylesheet"> - <link rel="stylesheet" href="/assets/main.css"> - <link rel="stylesheet" href="/css/cafe.css"> - <link rel="canonical" href="https://emacs.cafe/ledger/emacs/ynab/budgeting/2018/06/12/elbank-ynab.html"> - <link rel="alternate" type="application/rss+xml" title="Emacs café" href="/feed.xml"> - - -</head> - - - <body> - - <header class="site-header" role="banner"> - - <div class="wrapper"> - - - <a class="site-title" href="/"><img src="/img/emacscafe.png"/>Emacs café</a> - - - <nav class="site-nav"> - <input type="checkbox" id="nav-trigger" class="nav-trigger" /> - <label for="nav-trigger"> - <span class="menu-icon"> - <svg viewBox="0 0 18 15" width="18px" height="15px"> - <path fill="#424242" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/> - <path fill="#424242" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/> - <path fill="#424242" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/> - </svg> - </span> - </label> - - <div class="trigger"> - - - - <a class="page-link" href="/about/">About Emacs café</a> - - - - - - - - - - - - </div> - </nav> - - </div> -</header> - - - <main class="page-content" aria-label="Content"> - <div class="wrapper"> - <article class="post" itemscope itemtype="http://schema.org/BlogPosting"> - - <header class="post-header"> - <h1 class="post-title" itemprop="name headline">Using Ledger for YNAB-like envelope budgeting</h1> - <p class="post-meta"> - <time datetime="2018-06-12T21:20:00+02:00" itemprop="datePublished"> - - Jun 12, 2018 - </time> - - • <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Nicolas Petton</span></span> - </p> - </header> - - <div class="post-content" itemprop="articleBody"> - <h1 id="bye-bye-elbank">Bye bye Elbank</h1> - -<p>I have to start this post with this: I will not be actively maintaining -<a href="https://github.com/NicolasPetton/elbank">Elbank</a> anymore, simply because I -switched back to <a href="https://www.ledger-cli.org/">Ledger</a>. If someone wants to -take over, please contact me!</p> - -<p>The main reason for switching is budgeting. While Elbank was a cool experiment, -it is not an accounting software, and inherently lacks support for powerful -budgeting.</p> - -<p>When I started working on Elbank as a replacement for Ledger, I was looking for -a reporting tool within Emacs that would fetch bank transactions automatically, -so I wouldn’t have to enter transactions by hand (this is a seriously tedious -task, and I grew tired of doing it after roughly two years, and finally gave up).</p> - -<p>Since then, I learned about ledger-autosync and boobank, which I use to sync my -bank statements with Ledger (more about that in another post).</p> - -<h1 id="ynabs-way-of-budgeting">YNAB’s way of budgeting</h1> - -<p>I only came across <a href="https://ynab.com">YNAB</a> recently. While I won’t use their -software (being a non-free web application, and, you know… there’s no <code class="highlighter-rouge">M-x -ynab</code>), I think that the principles behind it are really appealing for personal -budgeting. I encourage you to <a href="https://www.youneedabudget.com/method/">read more about -it</a> (or grab a <a href="https://www.youneedabudget.com/book-order-now/">copy of the -book</a>, it’s great), but here’s -the idea.</p> - -<ol> - <li> - <p><strong>Budget every euro</strong>: Quite simple once you get it. Every single Euro you have -should be in a budget envelope. You should assign a job to every Euro you -earn (that’s called -<a href="https://en.wikipedia.org/wiki/Zero-based_budgeting">zero-based</a>, <a href="https://en.wikipedia.org/wiki/Envelope_system">envelope -system</a>).</p> - </li> - <li> - <p><strong>Embrace your true expenses</strong>: Plan for larger and less frequent expenses, so -when a yearly bill arrives, or your car breaks down, you’ll be covered.</p> - </li> - <li> - <p><strong>Roll with the punches</strong>: Address overspending as it happens by taking money -overspent from another envelope. As long as you keep budgeting, you’re -succeeding.</p> - </li> - <li> - <p><strong>Age your money</strong>: Spend less than you earn, so your money stays in the bank -account longer. As you do that, the age of your money will grow, and once -you reach the goal of spending money that is at least one month old, you -won’t worry about that next bill.</p> - </li> -</ol> - -<h1 id="implementation-in-ledger">Implementation in Ledger</h1> - -<p>I assume that you are familiar with Ledger, but if not I recommend reading its -great -<a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Introduction-to-Ledger">introduction</a> -and <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Ledger-Tutorial">tutorial</a>.</p> - -<p>The implementation in Ledger uses plain double-entry accounting. I took most of -it from -<a href="http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/">Sacha</a>, with -some minor differences.</p> - -<h2 id="budgeting-new-money">Budgeting new money</h2> - -<p>After each income transaction, I budget the new money:</p> - -<div class="highlighter-rouge"><pre class="highlight"><code>2018-06-12 Employer - Assets:Bank:Checking 1600.00 EUR - Income:Salary -1600.00 EUR - -2018-06-12 Budget - [Assets:Budget:Food] 400.00 EUR - [Assets:Budget:Rent] 600.00 EUR - [Assets:Budget:Utilities] 600.00 EUR - [Equity:Budget] -1600.00 EUR -</code></pre> -</div> - -<p>Did you notice the square brackets around the accounts of the budget -transaction? It’s a feature Ledger calls <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Virtual-postings">virtual -postings</a>. These -postings are not considered real, and won’t be present in any report that uses -the <code class="highlighter-rouge">--real</code> flag. This is exactly what we want, since it’s a budget allocation -and not a “real” transaction. Therefore we’ll use the <code class="highlighter-rouge">--real</code> flag for all -reports except for our budget report.</p> - -<h2 id="automatically-crediting-budget-accounts-when-spending-money">Automatically crediting budget accounts when spending money</h2> - -<p>Next, we need to credit the budget accounts each time we spend money. Ledger -has another neat feature called <a href="https://www.ledger-cli.org/3.0/doc/ledger3.html#Automated-Transactions">automated -transactions</a> -for this:</p> - -<div class="highlighter-rouge"><pre class="highlight"><code>= /Expenses/ - [Assets:Budget:Unbudgeted] -1.0 - [Equity:Budget] 1.0 - -= /Expenses:Food/ - [Assets:Budget:Food] -1.0 - [Assets:Budget:Unbudgeted] 1.0 - -= /Expenses:Rent/ - [Assets:Budget:Rent] -1.0 - [Assets:Budget:Unbudgeted] 1.0 - -= /Expenses:Utilities/ - [Assets:Budget:Utilities] -1.0 - [Assets:Budget:Unbudgeted] 1.0 -</code></pre> -</div> - -<p>Every expense is taken out of the <code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> account by default.</p> - -<p>This forces me to budget properly, as <code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> should always -be 0 (if it is not the case I immediately know that there is something wrong -going on).</p> - -<p>All other automatic transactions take money out of the -<code class="highlighter-rouge">Assets:Budget:Unbudgeted</code> account instead of <code class="highlighter-rouge">Equity:Budget</code> account.</p> - -<h2 id="a-budget-report">A Budget report</h2> - -<p>This is the final piece of the puzzle. Here’s the budget report command:</p> - -<div class="highlighter-rouge"><pre class="highlight"><code>ledger --empty -S -T -f ledger.dat bal ^assets:budget -</code></pre> -</div> - -<p>If we have the following transactions:</p> - -<div class="highlighter-rouge"><pre class="highlight"><code>2018/06/12 Groceries store - Expenses:Food 123.00 EUR - Assets:Bank:Checking - -2018/06/12 Landlord - Expenses:Rent 600.00 EUR - Assets:Bank:Checking - -2018/06/12 Internet provider - Expenses:Utilities:Internet 40.00 EUR - Assets:Bank:Checking -</code></pre> -</div> - -<p>Here’s what the report looks like:</p> - -<div class="highlighter-rouge"><pre class="highlight"><code> 837.00 EUR Assets:Budget - 560.00 EUR Utilities - 277.00 EUR Food - 0 Rent - 0 Unbudgeted --------------------- - 837.00 EUR -</code></pre> -</div> - -<h1 id="conclusion">Conclusion</h1> - -<p>Ledger is amazingly powerful, and provides a great framework for YNAB-like -budgeting. In a future post I’ll explain how I automatically import my bank -transactions using a mix of <code class="highlighter-rouge">ledger-autosync</code> and <code class="highlighter-rouge">weboob</code>.</p> - - </div> - - - - -<div id="disqus_thread"></div> -<script> - /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ - var disqus_shortname = 'emacs-cafe'; - - /* * * DON'T EDIT BELOW THIS LINE * * */ - (function() { - var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; - dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; - (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); - })(); -</script> -<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript> - - - -</article> - - </div> - </main> - - <footer class="site-footer"> - - <div class="wrapper"> - - <h2 class="footer-heading">Emacs café</h2> - - <div class="footer-col-wrapper"> - <div class="footer-col footer-col-1"> - <ul class="contact-list"> - <li> - - Emacs café - - </li> - - <li><a href="mailto:nicolas@petton.fr">nicolas@petton.fr</a></li> - - </ul> - </div> - - <div class="footer-col footer-col-2"> - <ul class="social-media-list"> - - <li> - <a href="https://github.com/NicolasPetton"><span class="icon icon--github"><svg viewBox="0 0 16 16" width="16px" height="16px"><path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/></svg> -</span><span class="username">NicolasPetton</span></a> - - </li> - - - - <li> - <a href="https://twitter.com/NicolasPetton"><span class="icon icon--twitter"><svg viewBox="0 0 16 16" width="16px" height="16px"><path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/></svg> -</span><span class="username">NicolasPetton</span></a> - - </li> - - </ul> - </div> - - <div class="footer-col footer-col-3"> - <p>A blog about Emacs, mostly focused on JavaScript development, by Nicolas Petton. -</p> - </div> - </div> - - </div> - -</footer> - - - </body> - -</html> diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/org-board-ac212115-e0c6-448c-9344-17c10aeb9694.log b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/org-board-ac212115-e0c6-448c-9344-17c10aeb9694.log @@ -1 +0,0 @@ -/run/current-system/sw/bin/wget --directory-prefix=/home/vincent/desktop/org/personal/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17:45:26+0100// "-e robots=off" --page-requisites --adjust-extension --convert-links https://writequit.org/articles/emacs-org-mode-generate-ids.html- \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/articles/emacs-org-mode-generate-ids.html b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/articles/emacs-org-mode-generate-ids.html @@ -1,458 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> -<head> -<!-- 2017-07-24 Mon 16:42 --> -<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> -<meta name="viewport" content="width=device-width, initial-scale=1" /> -<title>Emacs Org-mode: Use good header ids!</title> -<meta name="generator" content="Org mode" /> -<meta name="author" content="Lee Hinman" /> -<link rel="stylesheet" href="../css/tufte.css" type="text/css" /> -<link rel="stylesheet" href="../css/tufte.css" type="text/css" /> -<script type="text/javascript"> -/* -@licstart The following is the entire license notice for the -JavaScript code in this tag. - -Copyright (C) 2012-2017 Free Software Foundation, Inc. - -The JavaScript code in this tag is free software: you can -redistribute it and/or modify it under the terms of the GNU -General Public License (GNU GPL) as published by the Free Software -Foundation, either version 3 of the License, or (at your option) -any later version. The code is distributed WITHOUT ANY WARRANTY; -without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. - -As additional permission under GNU GPL version 3 section 7, you -may distribute non-source (e.g., minimized or compacted) forms of -that code without the copy of the GNU GPL normally required by -section 4, provided you include this license notice and a URL -through which recipients can access the Corresponding Source. - - -@licend The above is the entire license notice -for the JavaScript code in this tag. -*/ -<!--/*--><![CDATA[/*><!--*/ - function CodeHighlightOn(elem, id) - { - var target = document.getElementById(id); - if(null != target) { - elem.cacheClassElem = elem.className; - elem.cacheClassTarget = target.className; - target.className = "code-highlighted"; - elem.className = "code-highlighted"; - } - } - function CodeHighlightOff(elem, id) - { - var target = document.getElementById(id); - if(elem.cacheClassElem) - elem.className = elem.cacheClassElem; - if(elem.cacheClassTarget) - target.className = elem.cacheClassTarget; - } -/*]]>*///--> -</script> -</head> -<body> -<div id="content"> -<h1 class="title">Emacs Org-mode: Use good header ids!</h1> -<div id="table-of-contents"> -<h2>Table of Contents</h2> -<div id="text-table-of-contents"> -<ul> -<li><a href="emacs-org-mode-generate-ids.html#header-intro">Introduction</a></li> -<li><a href="emacs-org-mode-generate-ids.html#the-problem">The Problem - anchors are not consistent</a></li> -<li><a href="emacs-org-mode-generate-ids.html#the-solution">The Solution - use custom ids in headline properties</a></li> -<li><a href="emacs-org-mode-generate-ids.html#automating-id-creation">Automating adding the CUSTOM_ID</a></li> -<li><a href="emacs-org-mode-generate-ids.html#update-2016-09-07">Update 2016-09-07</a></li> -<li><a href="emacs-org-mode-generate-ids.html#h-cf29e5e7-b456-4842-a3f7-e9185897ac3b">Update 2017-07-24</a></li> -</ul> -</div> -</div> -<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"> - - -<colgroup> -<col class="org-left" /> - -<col class="org-left" /> -</colgroup> -<tbody> -<tr> -<td class="org-left"><b>Author</b></td> -<td class="org-left">Lee Hinman (lee@writequit.org)</td> -</tr> - -<tr> -<td class="org-left"><b>Date</b></td> -<td class="org-left">2017-07-24 16:42:01</td> -</tr> -</tbody> -</table> - -<div id="outline-container-org3980e17" class="outline-2"> -<h2 id="header-intro"><a id="org3980e17"></a>Introduction</h2> -<div class="outline-text-2" id="text-header-intro"> -<p> -I frequently write many articles in org-mode, some private, some public. <a href="http://writequit.org">Most</a> <a href="http://writequit.org/org/es/">of</a> -<a href="http://writequit.org/articles/getting-started-with-git-annex.html">the</a> <a href="http://writequit.org/articles/literate-es-scripts.html">public</a> <a href="http://writequit.org/denver-emacs/">ones</a> eventually end up published on my site as HTML documents, to be -shared with co-workers or anyone who happens to be browsing my site. Recently, -however, I've noticed that many org documents that are exported to HTML are -using a concerning method of anchoring links to different headlines. -</p> -</div> -</div> - -<div id="outline-container-orgdfc1c09" class="outline-2"> -<h2 id="the-problem"><a id="orgdfc1c09"></a>The Problem - anchors are not consistent</h2> -<div class="outline-text-2" id="text-the-problem"> -<p> -Let's take an <code>example.org</code> document, the simplest example of a an org-mode -buffer with just a few headlines: -</p> - -<pre class="code"><code><span style="color: #0066BB; font-weight: bold;">* Headline 1</span> -This is some text - -<span style="color: #0066BB; font-weight: bold;">* Headline 2</span> -This is heading number two - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 1</span> - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 2</span> - -<span style="color: #0066BB; font-weight: bold;">* Headline 3</span> -In conclusion, this is an example -</code></pre> - -<p> -Now, if you invoke <code>C-c C-e</code> to bring up the export options and export this -document to HTML, you'll end up with a document that looks something like this: -</p> - - -<div class="figure"> -<p><img src="images/org-export1.png" alt="org-export1.png" /> -</p> -</div> - -<p> -Currently this is at the <code>file:///home/hinmanm/example.html</code> url. In the table -of contents, if you click on the <code>Headline 2</code> heading, you are then taken to the -<code>file:///home/hinmanm/example.html#sec-2</code> and jump to that location on the page -(imagine the page is longer so you would jump to the location). -</p> - -<p> -The issue with this is when we edit our <code>example.org</code> file to add a headline -somewhere in the middle, in this case, adding a "Newly added headline" in -between "Headline 1" and "Headline 2". -</p> - -<pre class="code"><code><span style="color: #0066BB; font-weight: bold;">* Headline 1</span> -This is some text - -<span style="color: #0066BB; font-weight: bold;">* Newly added headline</span> -Wait, I've decided that this information is really important! - -<span style="color: #0066BB; font-weight: bold;">* Headline 2</span> -This is heading number two - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 1</span> - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 2</span> - -<span style="color: #0066BB; font-weight: bold;">* Headline 3</span> -In conclusion, this is an example -</code></pre> - -<p> -If this is again exported to HTML, we get: -</p> - - -<div class="figure"> -<p><img src="images/org-export2.png" alt="org-export2.png" /> -</p> -</div> - -<p> -But wait! Notice that the previously visited HTML anchor <code>#sec-2</code> now points to -the "Newly added headline" headline, instead of "Headline 2" like it used to! -This is a problem for any public HTML document where someone may keep a link to -a sub heading, or send the heading to another person. As the number of headlines -increases, the chance of inserting a headline and messing up the anchors -increases. So, how can you handle this? -</p> -</div> -</div> - -<div id="outline-container-org2ce7f6c" class="outline-2"> -<h2 id="the-solution"><a id="org2ce7f6c"></a>The Solution - use custom ids in headline properties</h2> -<div class="outline-text-2" id="text-the-solution"> -<p> -Org-mode has property drawers for properties that apply to headlines, and we can -assign a custom ID to a headline by setting the <code>CUSTOM_ID</code> property, so if we -do that to the "Headline 2" heading, you can see: -</p> - -<pre class="code"><code><span style="color: #0066BB; font-weight: bold;">* Headline 1</span> -This is some text - -<span style="color: #0066BB; font-weight: bold;">* Newly added headline</span> -Wait, I've decided that this information is really important! - -<span style="color: #0066BB; font-weight: bold;">* Headline 2</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> my-headline-2 -<span style="color: #90a4be;">:END:</span> -This is heading number two - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 1</span> - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 2</span> - -<span style="color: #0066BB; font-weight: bold;">* Headline 3</span> -In conclusion, this is an example -</code></pre> - -<p> -When this org document is exported to HTML, instead of using <code>#sec-2</code> as the -anchor, the value of the <code>CUSTOM_ID</code> will be used instead. This means the full -link will be <code>file:///home/hinmanm/example.html#my-headline-2</code>, no matter how -many headings you insert before or after the heading. You can also give the -anchor a much more human-friendly name instead of a section number. -</p> -</div> -</div> - -<div id="outline-container-org7321176" class="outline-2"> -<h2 id="automating-id-creation"><a id="org7321176"></a>Automating adding the CUSTOM_ID</h2> -<div class="outline-text-2" id="text-automating-id-creation"> -<p> -Fantastic! You may say, the only issue is that now I have to go through and -manually add these custom ids! Well, fear not, because there is some elisp that -can do this easily for you: -</p> - -<p> -First, you'll need to require the <code>org-id</code> library, which has some helpers for -this. You may also want to use your <code>CUSTOM_ID</code> for links also: -</p> - -<pre class="code"><code><span style="color: #7f7f7f;">(</span><span style="color: #008800;">require</span> <span style="color: #008800;">'</span><span style="color: #003366;">org-id</span><span style="color: #7f7f7f;">)</span> -<span style="color: #7f7f7f;">(</span><span style="color: #008800;">setq</span> org-id-link-to-org-use-id <span style="color: #008800;">'</span><span style="color: #003366;">create-if-interactive-and-no-custom-id</span><span style="color: #7f7f7f;">)</span> -</code></pre> - -<p> -Then we can define our own version of <code>org-custom-id-get</code> that calls -<code>org-id-new</code> and creates a new property if one doesn't already exist<label for="1" class="margin-toggle sidenote-number"></label><input type="checkbox" id="1" class="margin-toggle"/><span class="sidenote"> -In case you were wondering what the "h" is for, the ids that <code>org-id-new</code> -generates by default are actually invalid XHTML anchors (because they start with -a number instead of a character), so this changes them to start with "h". -</span>. -</p> - -<pre class="code"><code><span style="color: #7f7f7f;">(</span><span style="color: #008800;">defun</span> <span style="color: #0066BB;">eos/org-custom-id-get</span> <span style="color: #7f7f7f;">(</span><span style="color: #333399;">&optional</span> pom create prefix<span style="color: #7f7f7f;">)</span> - <span style="color: #206070;">"Get the CUSTOM_ID property of the entry at point-or-marker POM.</span> -<span style="color: #206070;"> If POM is nil, refer to the entry at point. If the entry does</span> -<span style="color: #206070;"> not have an CUSTOM_ID, the function returns nil. However, when</span> -<span style="color: #206070;"> CREATE is non nil, create a CUSTOM_ID if none is present</span> -<span style="color: #206070;"> already. PREFIX will be passed through to `</span><span style="color: #003366;">org-id-new</span><span style="color: #206070;">'. In any</span> -<span style="color: #206070;"> case, the CUSTOM_ID of the entry is returned."</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">interactive</span><span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">org-with-point-at</span> pom - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">let</span> <span style="color: #7f7f7f;">((</span>id <span style="color: #7f7f7f;">(</span>org-entry-get nil <span style="background-color: #fff0f0;">"CUSTOM_ID"</span><span style="color: #7f7f7f;">)))</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">cond</span> - <span style="color: #7f7f7f;">((</span><span style="color: #008800;">and</span> id <span style="color: #7f7f7f;">(</span>stringp id<span style="color: #7f7f7f;">)</span> <span style="color: #7f7f7f;">(</span>string-match <span style="background-color: #fff0f0;">"</span><span style="color: #000000; background-color: #fff0f0; font-weight: bold;">\</span><span style="color: #000000; background-color: #fff0f0; font-weight: bold;">\</span><span style="background-color: #fff0f0;">S-"</span> id<span style="color: #7f7f7f;">))</span> - id<span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>create - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">setq</span> id <span style="color: #7f7f7f;">(</span>org-id-new <span style="color: #7f7f7f;">(</span>concat prefix <span style="background-color: #fff0f0;">"h"</span><span style="color: #7f7f7f;">)))</span> - <span style="color: #7f7f7f;">(</span>org-entry-put pom <span style="background-color: #fff0f0;">"CUSTOM_ID"</span> id<span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>org-id-add-location id <span style="color: #7f7f7f;">(</span>buffer-file-name <span style="color: #7f7f7f;">(</span>buffer-base-buffer<span style="color: #7f7f7f;">)))</span> - id<span style="color: #7f7f7f;">)))))</span> -</code></pre> - -<p> -And add a helper function that's interactive to add custom ids to <b>all</b> -headlines in the buffer if they don't already have one. -</p> - -<pre class="code"><code><span style="color: #7f7f7f;">(</span><span style="color: #008800;">defun</span> <span style="color: #0066BB;">eos/org-add-ids-to-headlines-in-file</span> <span style="color: #7f7f7f;">()</span> - <span style="color: #206070;">"Add CUSTOM_ID properties to all headlines in the</span> -<span style="color: #206070;"> current file which do not already have one."</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">interactive</span><span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>org-map-entries <span style="color: #7f7f7f;">(</span><span style="color: #008800;">lambda</span> <span style="color: #7f7f7f;">()</span> <span style="color: #7f7f7f;">(</span>eos/org-custom-id-get <span style="color: #7f7f7f;">(</span>point<span style="color: #7f7f7f;">)</span> <span style="color: #008800;">'</span><span style="color: #003366;">create</span><span style="color: #7f7f7f;">))))</span> -</code></pre> - -<p> -Now to add headlines, you can hit <code>M-x eos/org-add-ids-to-headlines-in-file</code> and -you'll get something like this! -</p> - -<pre class="code"><code><span style="color: #0066BB; font-weight: bold;">* Headline 1</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> h:7d66adcc-5e24-4f49-9923-4816bc30a7cb -<span style="color: #90a4be;">:END:</span> -This is some text - -<span style="color: #0066BB; font-weight: bold;">* Newly added headline</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> h:7c38f8ef-0c8c-4f17-a7da-7ed7d5eedeff -<span style="color: #90a4be;">:END:</span> -Wait, I've decided that this information is really important! - -<span style="color: #0066BB; font-weight: bold;">* Headline 2</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> my-headline-2 -<span style="color: #90a4be;">:END:</span> -This is heading number two - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 1</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> h:2c29be2d-be83-46d3-bee8-bcbe75e4160b -<span style="color: #90a4be;">:END:</span> - -<span style="color: #f9f9f9;">*</span><span style="color: #996633; font-weight: bold;">* Sub heading 2</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> h:e148d5ed-8e55-4e26-bd5a-c414ed06fa5a -<span style="color: #90a4be;">:END:</span> - -<span style="color: #0066BB; font-weight: bold;">* Headline 3</span> -<span style="color: #90a4be;">:PROPERTIES:</span> -<span style="color: #90a4be;">:CUSTOM_ID:</span> h:a1b44d60-488a-4aae-8ae4-6b98d5dbef7e -<span style="color: #90a4be;">:END:</span> -In conclusion, this is an example -</code></pre> - -<p> -(It looks better when the <code>:PROPERTIES:</code> drawers are collapsed of course). If -you decide you want to add a nicer-looking CUSTOM_ID instead of the UUID, you -can hit <code>C-c C-x p</code> and be prompted to change the property. -</p> - -<p> -Finally, if you so desire, here is an optional helper if you want to add a -<code>CUSTOM_ID</code> to headlines created when you use an org-capture template: -</p> - -<pre class="code"><code><span style="color: #888888;">;; </span><span style="color: #888888;">automatically add ids to captured headlines</span> -<span style="color: #7f7f7f;">(</span>add-hook <span style="color: #008800;">'</span><span style="color: #003366;">org-capture-prepare-finalize-hook</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">lambda</span> <span style="color: #7f7f7f;">()</span> <span style="color: #7f7f7f;">(</span>eos/org-custom-id-get <span style="color: #7f7f7f;">(</span>point<span style="color: #7f7f7f;">)</span> <span style="color: #008800;">'</span><span style="color: #003366;">create</span><span style="color: #7f7f7f;">)))</span> -</code></pre> - -<p> -Now go forth and make anchor links that don't break! -</p> -</div> -</div> -<div id="outline-container-orga56defc" class="outline-2"> -<h2 id="update-2016-09-07"><a id="orga56defc"></a>Update 2016-09-07</h2> -<div class="outline-text-2" id="text-update-2016-09-07"> -<p> -I've updated the <code>eos/org-add-ids-to-headlines-in-file</code> method to check for the -string <code>#+OPTIONS: auto-id:t</code> in the file somewhere (usually at the top) and -automatically add ids when the file is saved. The new version looks like: -</p> - -<pre class="code"><code><span style="color: #7f7f7f;">(</span><span style="color: #008800;">defun</span> <span style="color: #0066BB;">eos/org-add-ids-to-headlines-in-file</span> <span style="color: #7f7f7f;">()</span> - <span style="color: #206070;">"Add CUSTOM_ID properties to all headlines in the current</span> -<span style="color: #206070;"> file which do not already have one. Only adds ids if the</span> -<span style="color: #206070;"> `</span><span style="color: #003366;">auto-id</span><span style="color: #206070;">' option is set to `t' in the file somewhere. ie,</span> -<span style="color: #206070;"> #+OPTIONS: auto-id:t"</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">interactive</span><span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">save-excursion</span> - <span style="color: #7f7f7f;">(</span>widen<span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>goto-char <span style="color: #7f7f7f;">(</span>point-min<span style="color: #7f7f7f;">))</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">when</span> <span style="color: #7f7f7f;">(</span>re-search-forward <span style="background-color: #fff0f0;">"^#</span><span style="color: #000000; background-color: #fff0f0; font-weight: bold;">\</span><span style="color: #000000; background-color: #fff0f0; font-weight: bold;">\</span><span style="background-color: #fff0f0;">+OPTIONS:.*auto-id:t"</span> <span style="color: #7f7f7f;">(</span>point-max<span style="color: #7f7f7f;">)</span> t<span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>org-map-entries <span style="color: #7f7f7f;">(</span><span style="color: #008800;">lambda</span> <span style="color: #7f7f7f;">()</span> <span style="color: #7f7f7f;">(</span>eos/org-custom-id-get <span style="color: #7f7f7f;">(</span>point<span style="color: #7f7f7f;">)</span> <span style="color: #008800;">'</span><span style="color: #003366;">create</span><span style="color: #7f7f7f;">))))))</span> -</code></pre> - -<p> -And then it's automatically<label for="2" class="margin-toggle sidenote-number"></label><input type="checkbox" id="2" class="margin-toggle"/><span class="sidenote">Running it automatically is up to you, I find -it easy to leave the hook in and add the option when I am intending to publish -the HTML publicly somewhere</span> run with: -</p> - -<pre class="code"><code><span style="color: #888888;">;; </span><span style="color: #888888;">automatically add ids to saved org-mode headlines</span> -<span style="color: #7f7f7f;">(</span>add-hook <span style="color: #008800;">'</span><span style="color: #003366;">org-mode-hook</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">lambda</span> <span style="color: #7f7f7f;">()</span> - <span style="color: #7f7f7f;">(</span>add-hook <span style="color: #008800;">'</span><span style="color: #003366;">before-save-hook</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">lambda</span> <span style="color: #7f7f7f;">()</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">when</span> <span style="color: #7f7f7f;">(</span><span style="color: #008800;">and</span> <span style="color: #7f7f7f;">(</span>eq major-mode <span style="color: #008800;">'</span><span style="color: #003366;">org-mode</span><span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>eq buffer-read-only nil<span style="color: #7f7f7f;">))</span> - <span style="color: #7f7f7f;">(</span>eos/org-add-ids-to-headlines-in-file<span style="color: #7f7f7f;">))))))</span> -</code></pre> -</div> -</div> - -<div id="outline-container-orgf72fa3d" class="outline-2"> -<h2 id="h-cf29e5e7-b456-4842-a3f7-e9185897ac3b"><a id="orgf72fa3d"></a>Update 2017-07-24</h2> -<div class="outline-text-2" id="text-h-cf29e5e7-b456-4842-a3f7-e9185897ac3b"> -<p> -I got a nice email from a fellow who mentioned that an id like <code>h:1234</code> breaks jquery trying to -select that particular heading. So in order to fix that, do the following: -</p> - -<pre class="code"><code><span style="color: #7f7f7f;">(</span><span style="color: #008800;">defun</span> <span style="color: #0066BB;">org-id-new</span> <span style="color: #7f7f7f;">(</span><span style="color: #333399;">&optional</span> prefix<span style="color: #7f7f7f;">)</span> - <span style="color: #206070;">"Create a new globally unique ID.</span> - -<span style="color: #206070;">An ID consists of two parts separated by a colon:</span> -<span style="color: #206070;">- a prefix</span> -<span style="color: #206070;">- a unique part that will be created according to `</span><span style="color: #003366;">org-id-method</span><span style="color: #206070;">'.</span> - -<span style="color: #206070;">PREFIX can specify the prefix, the default is given by the variable</span> -<span style="color: #206070;">`</span><span style="color: #003366;">org-id-prefix</span><span style="color: #206070;">'. However, if PREFIX is the symbol `</span><span style="color: #003366;">none</span><span style="color: #206070;">', don't use any</span> -<span style="color: #206070;">prefix even if `</span><span style="color: #003366;">org-id-prefix</span><span style="color: #206070;">' specifies one.</span> - -<span style="color: #206070;">So a typical ID could look like </span><span style="color: #000000; font-weight: bold;">\</span><span style="color: #000000; font-weight: bold;">"</span><span style="color: #206070;">Org-4nd91V40HI</span><span style="color: #000000; font-weight: bold;">\</span><span style="color: #000000; font-weight: bold;">"</span><span style="color: #206070;">."</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">let*</span> <span style="color: #7f7f7f;">((</span>prefix <span style="color: #7f7f7f;">(</span><span style="color: #008800;">if</span> <span style="color: #7f7f7f;">(</span>eq prefix <span style="color: #008800;">'</span><span style="color: #003366;">none</span><span style="color: #7f7f7f;">)</span> - <span style="background-color: #fff0f0;">""</span> - <span style="color: #7f7f7f;">(</span>concat <span style="color: #7f7f7f;">(</span><span style="color: #008800;">or</span> prefix org-id-prefix<span style="color: #7f7f7f;">)</span> <span style="background-color: #fff0f0;">"-"</span><span style="color: #7f7f7f;">)))</span> - unique<span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">if</span> <span style="color: #7f7f7f;">(</span>equal prefix <span style="background-color: #fff0f0;">"-"</span><span style="color: #7f7f7f;">)</span> <span style="color: #7f7f7f;">(</span><span style="color: #008800;">setq</span> prefix <span style="background-color: #fff0f0;">""</span><span style="color: #7f7f7f;">))</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">cond</span> - <span style="color: #7f7f7f;">((</span>memq org-id-method <span style="color: #008800;">'</span><span style="color: #7f7f7f;">(</span>uuidgen uuid<span style="color: #7f7f7f;">))</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">setq</span> unique <span style="color: #7f7f7f;">(</span>org-trim <span style="color: #7f7f7f;">(</span>shell-command-to-string org-id-uuid-program<span style="color: #7f7f7f;">)))</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">unless</span> <span style="color: #7f7f7f;">(</span>org-uuidgen-p unique<span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">setq</span> unique <span style="color: #7f7f7f;">(</span>org-id-uuid<span style="color: #7f7f7f;">))))</span> - <span style="color: #7f7f7f;">((</span>eq org-id-method <span style="color: #008800;">'</span><span style="color: #003366;">org</span><span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">let*</span> <span style="color: #7f7f7f;">((</span>etime <span style="color: #7f7f7f;">(</span>org-reverse-string <span style="color: #7f7f7f;">(</span>org-id-time-to-b36<span style="color: #7f7f7f;">)))</span> - <span style="color: #7f7f7f;">(</span>postfix <span style="color: #7f7f7f;">(</span><span style="color: #008800;">if</span> org-id-include-domain - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">progn</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">require</span> <span style="color: #008800;">'</span><span style="color: #003366;">message</span><span style="color: #7f7f7f;">)</span> - <span style="color: #7f7f7f;">(</span>concat <span style="background-color: #fff0f0;">"@"</span> <span style="color: #7f7f7f;">(</span>message-make-fqdn<span style="color: #7f7f7f;">))))))</span> - <span style="color: #7f7f7f;">(</span><span style="color: #008800;">setq</span> unique <span style="color: #7f7f7f;">(</span>concat etime postfix<span style="color: #7f7f7f;">))))</span> - <span style="color: #7f7f7f;">(</span>t <span style="color: #7f7f7f;">(</span><span style="color: #ff0000; font-weight: bold;">error</span> <span style="background-color: #fff0f0;">"Invalid `</span><span style="color: #003366; background-color: #fff0f0;">org-id-method</span><span style="background-color: #fff0f0;">'"</span><span style="color: #7f7f7f;">)))</span> - <span style="color: #7f7f7f;">(</span>concat prefix unique<span style="color: #7f7f7f;">)))</span> -</code></pre> - -<p> -This changes the header delimiter from <code>:</code> to <code>-</code> so <code>h-1234</code> is generated instead. -</p> -</div> -</div> -<!-- Footnotes --><!-- -<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara"><p class="footpara"> -In case you were wondering what the "h" is for, the ids that <code>org-id-new</code> -generates by default are actually invalid XHTML anchors (because they start with -a number instead of a character), so this changes them to start with "h". -</p></div></div> - -<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup> <div class="footpara">Running it automatically is up to you, I find -it easy to leave the hook in and add the option when I am intending to publish -the HTML publicly somewhere</div></div> - - --></div> -<div id="postamble" class="status"> -<p class="author">Author: Lee Hinman</p> -<p class="date">Created: 2017-07-24 Mon 16:42</p> -<p class="validation"></p> -</div> -</body> -</html> diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/articles/images/org-export1.png b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/articles/images/org-export1.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/articles/images/org-export2.png b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/articles/images/org-export2.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.svg b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.svg @@ -1,243 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata></metadata> -<defs> -<font id="etbemboboldlf" horiz-adv-x="1001" > -<font-face units-per-em="2048" ascent="1638" descent="-410" /> -<missing-glyph horiz-adv-x="501" /> -<glyph horiz-adv-x="2048" /> -<glyph horiz-adv-x="2048" /> -<glyph unicode="
" horiz-adv-x="681" /> -<glyph unicode=" " horiz-adv-x="501" /> -<glyph unicode="	" horiz-adv-x="501" /> -<glyph unicode=" " horiz-adv-x="501" /> -<glyph unicode="!" horiz-adv-x="557" d="M164 1305q-2 33 0 53t21.5 37.5t56.5 17.5h73q45 0 64.5 -12t19.5 -37t-2 -59l-69 -926q-12 -25 -43 -30t-52 30zM166 96q0 49 32.5 81t82.5 32q47 0 81.5 -32t34.5 -81t-33.5 -81.5t-83 -32.5t-82 32.5t-32.5 81.5z" /> -<glyph unicode=""" horiz-adv-x="870" d="M129 1229q0 152 123 151q61 0 97 -38.5t36 -102.5q0 -31 -8 -88q-4 -31 -17 -88l-55 -299q-23 -33 -60.5 -22.5t-43.5 49.5l-49 274q-23 121 -23 164zM487 1219q0 162 134 161q59 0 94 -38.5t35 -102.5q0 -65 -23 -178l-57 -295q-16 -39 -57.5 -32t-47.5 34l-51 291 q-2 8 -14.5 67.5t-12.5 92.5z" /> -<glyph unicode="#" horiz-adv-x="1431" d="M63 416q2 14 11 63q0 51 65 51h162q14 0 18.5 2.5t6.5 16.5l65 307q0 6 -26 6h-189q-35 0 -54.5 10.5t-17.5 40.5q-2 12 0 25.5t6.5 29t6.5 23.5q4 39 63 43q127 4 236 0q12 0 14 10l76 355q10 49 38.5 55t69.5 -6q41 -4 52.5 -16.5t3.5 -53.5l-66 -319q-2 -8 4 -16.5 t13 -8.5q47 2 174 0t172 0q16 0 18 19q53 258 68 321q6 29 9 39t17.5 22.5t40.5 14.5l47 4q39 2 50.5 -20.5t5.5 -71.5q0 -2 -68 -322q2 -4 27 -6q27 -4 66.5 -3t68.5 -1q49 0 47 -47q-2 -16 -16 -84q-6 -33 -68 -37h-143q-10 0 -16.5 -4t-7.5 -7t-3 -16.5t-2 -15.5 l-59 -278q0 -10 30 -11q80 -2 181 0q43 0 53 -4q35 -10 24 -53l-12 -59q-6 -35 -23.5 -44.5t-52.5 -11.5q-106 -4 -200 0h-21.5t-11.5 -7t-5 -9t-3 -18l-68 -320q-10 -63 -66 -63h-59q-59 0 -45 94q4 27 13.5 67.5t24.5 106t28 123.5q4 27 -19 26q-205 8 -342 0 q-18 -2 -22 -28l-68 -324q-2 -14 -6 -24.5t-10.5 -16.5t-11.5 -10t-15 -6t-16.5 -3t-20.5 -2t-20 -1q-74 -4 -74 51q0 6 3 17.5t3 15.5l66 317q2 8 -1 11t-16 3h-139q-23 0 -34 2t-20.5 15.5t-9.5 40.5zM494 541q0 -4 10 -6l12 -3q125 6 332 0q29 -2 33 19l61 289 q2 12 -6.5 17t-20.5 5q-184 4 -325 0q-25 0 -27 -4q0 -2 -4 -16z" /> -<glyph unicode="$" horiz-adv-x="980" d="M63 223q0 39 30 70t69 31q41 0 64.5 -24t43 -80t23.5 -64q6 -14 24 -33q0 2 2 6v4v469q-2 4 -6 8q-123 92 -157 140q-57 74 -58 172q0 94 57.5 168.5t153.5 111.5q10 4 10 23v92q8 27 62 31q31 -6 43 -35v-66l2 -18q39 4 82 0q6 0 6 20v62q4 25 43 35h27q16 0 25 -9.5 t11.5 -27t3.5 -30.5t-1 -31.5t-2 -20.5q0 -20 14 -25q94 -31 154.5 -82t60.5 -112q0 -39 -26.5 -67t-65.5 -28q-20 0 -36.5 6.5t-32 20.5t-23 24.5t-21.5 32t-20 29.5q-2 0 -4 4v-330q0 -23 4 -26q82 -51 132 -90t96 -114t46 -159q0 -115 -74.5 -204t-199.5 -130 q-4 -2 -4 -16q0 -86 2 -141q0 -39 -43 -39h-33q-16 2 -26.5 16.5t-8.5 30.5l2 117q0 16 -14 12q-20 -2 -62 2q-6 2 -9 -3t-3 -17q0 -86 4 -111q4 -35 -29 -47h-57q-31 10 -25 45v27v114q0 14 -14 19q-125 43 -176 96q-66 70 -66 141zM270 991q0 -55 39 -96q8 4 8 16l2 150 l-2 24q-47 -37 -47 -94zM424 520l2 -436q0 -18 8 -18q8 -2 41 -4.5t39 4.5v16v387q0 18 -6 18q-12 8 -35 23t-37 25q0 6 -8 0q-4 -4 -4 -15zM424 825q0 -16 6 -22l4 -6q4 -5 76 -52q4 8 4 13v334q0 23 -4 24q-55 12 -86 6v-6v-291zM618 406q2 -4 3 -7v-268q0 -23 4 -22 q4 0 8 2q78 53 78 155q0 82 -88 146q-6 2 -5 -6z" /> -<glyph unicode="%" horiz-adv-x="1425" d="M76 928q0 135 90 224t219 89t222 -86t91 -221t-92 -224t-219 -89q-125 0 -218 88t-93 219zM238 932q0 -100 40.5 -152.5t108.5 -52.5q70 0 111 52t41 155q0 100 -42 150.5t-116 50.5q-66 0 -104.5 -52.5t-38.5 -150.5zM246 -68l786 1352q33 39 72 21l24 -11 q37 -12 19 -61l-782 -1344q-20 -41 -76 -28q-74 18 -43 71zM705 219q0 135 90 224t219 89t222 -87t91 -220q-2 -135 -92 -224t-219 -89q-125 0 -218 88t-93 219zM866 223q0 -98 41 -150.5t109 -52.5q70 0 110.5 52.5t40.5 152.5q1 203 -157 203q-63 0 -103.5 -52t-40.5 -153 z" /> -<glyph unicode="&" horiz-adv-x="1562" d="M72 336q0 164 131 274q59 51 207 117q8 8 4 12q-123 119 -123 254q0 123 90 198t231 75q127 0 214 -64.5t87 -169.5q0 -147 -192 -258q-16 -10 -2 -20q55 -43 139 -123q84 -78 141 -160q8 -14 21 0q61 80 119 164q63 98 92 180q4 20 0 21q-4 2 -13.5 3t-13.5 1 q-14 2 -38.5 4t-30.5 2q-35 16 -23 69q6 27 39 27h8q182 -4 350 2q16 4 30.5 -6t16.5 -29v-26q0 -37 -47 -41q-6 0 -44 -3t-61.5 -9.5t-37.5 -20.5q-23 -23 -74 -113q-14 -27 -33.5 -65.5t-23.5 -44.5q-63 -111 -150 -209q-12 -16 -8 -23q14 -20 36 -59t30 -51 q51 -94 78.5 -121t60.5 -27q47 0 156 74q20 4 40.5 -14.5t22.5 -41t-14 -34.5q-152 -119 -281 -119q-27 0 -50 3t-44.5 12.5t-36 15.5t-32 24.5t-26.5 25.5t-25.5 32.5t-20.5 33t-21.5 39t-21.5 37.5l-13 9q-238 -231 -464 -232q-158 0 -268.5 108.5t-110.5 266.5zM315 360 q0 -104 60.5 -165.5t159.5 -61.5q76 0 162.5 39t152.5 104q18 19 6 27q-143 215 -346 350q-2 2 -14 -8q-98 -72 -139.5 -138.5t-41.5 -146.5zM494 1044q0 -109 116 -204q6 -6 17 0q92 63 92 176q0 68 -33 105.5t-88 37.5q-104 0 -104 -115z" /> -<glyph unicode="'" horiz-adv-x="378" d="M72 1221q0 160 116 159q59 0 91 -38.5t32 -102.5q0 -37 -10 -92q-10 -57 -27.5 -173t-27.5 -173q-2 -23 -16.5 -41.5t-43.5 -16.5q-8 0 -15 2.5t-11 3.5t-7 4t-5.5 5t-3.5 7t-2 9t-2 11.5t-1 11.5l-45 266q-23 145 -22 158z" /> -<glyph unicode="(" horiz-adv-x="667" d="M143 492q0 252 106.5 499.5t285.5 446.5q45 37 86 -7.5t14 -87.5q-61 -70 -125 -184.5t-104 -222.5q-74 -201 -74 -444q0 -193 41 -344.5t137 -325.5q55 -102 127 -187q23 -53 -57 -92q-31 -14 -66 21q-168 193 -269.5 437.5t-101.5 490.5z" /> -<glyph unicode=")" horiz-adv-x="647" d="M16.5 1381q1.5 30 24.5 49q25 18 51.5 16t44.5 -21q172 -195 271.5 -437.5t99.5 -491.5q0 -256 -104.5 -506t-284.5 -443q-41 -33 -88 2t-13 93q141 162 232 407q74 201 74 447q0 190 -41 341.5t-140 327.5q-61 113 -110 168q-18 18 -16.5 48z" /> -<glyph unicode="*" horiz-adv-x="1093" d="M152 735q0 39 17 62.5t36.5 32t60.5 18.5q70 14 211 70q8 6 0 10q-49 25 -102 39q-23 8 -59.5 16t-51.5 12q-57 14 -84.5 37t-27.5 76q0 27 23.5 57.5t76.5 30.5q12 0 24.5 -4t20.5 -8t20.5 -14.5t17.5 -15.5t16 -18.5t16 -17.5q76 -86 145 -129q6 4 6 6q-4 90 -26 156 q-29 100 -29 125q0 39 24.5 69.5t69.5 30.5t69.5 -30.5t24.5 -69.5q0 -29 -8 -60.5t-20.5 -69.5t-16.5 -59q-18 -88 -8 -94q2 -2 10 -2q78 51 140 127q68 78 116 78q53 0 75 -30.5t22 -57.5q0 -41 -26 -67.5t-51.5 -36t-77.5 -21.5t-65 -16q-109 -31 -104 -47q2 -12 102 -46 q16 -4 66.5 -15t77 -19.5t52.5 -36t26 -68.5q0 -33 -25 -59.5t-64 -26.5q-27 0 -51 12.5t-35.5 22.5t-35 40t-29.5 36q-47 57 -115 96q-8 0 -8 -8q4 -102 29 -168q14 -43 16 -51q10 -20 10 -60q0 -43 -26.5 -73.5t-69.5 -30.5t-69.5 30.5t-26.5 73.5q0 35 28 111 q25 66 27 166q0 8 -2 10v2q-78 -47 -143 -129q-23 -29 -35 -41t-38 -25.5t-56 -13.5q-39 0 -64.5 28t-25.5 58z" /> -<glyph unicode="+" horiz-adv-x="1429" d="M135 664v57q0 27 2 36t13.5 15t39.5 6h416q23 0 23 23v397q0 39 2 45q6 27 45 27h80q29 0 39 -14.5t10 -49.5v-409q4 -4 9 -9.5t9 -7.5t13 -2h405q35 0 45 -12t10 -43v-59q0 -27 -11 -40.5t-22 -15.5t-36 -2h-402q-8 0 -14 -8t-6 -18v-416q0 -39 -11.5 -48.5t-50.5 -9.5 h-65q-33 2 -41 14.5t-8 43.5v432q0 10 -21 10h-420q-33 0 -43 11.5t-10 46.5z" /> -<glyph unicode="," horiz-adv-x="514" d="M133 53q0 49 36 82t87 33q63 0 100 -46t37 -120q0 -178 -178 -260q-51 -23 -65 -4l-15 14q-4 12 4 28.5t17 20.5q106 61 112 131q2 2 0 8.5t-4 6.5q-53 -12 -92 20.5t-39 85.5z" /> -<glyph unicode="-" horiz-adv-x="890" d="M82 446v58q0 23 20.5 33t38.5 10h629q20 0 35.5 -13.5t13.5 -29.5l-4 -53q-8 -33 -41 -37q-309 -4 -651 0q-29 0 -41 32z" /> -<glyph unicode="." horiz-adv-x="444" d="M129 80q0 49 34 77.5t87 28.5q51 0 84 -28.5t33 -75.5q0 -45 -33 -76t-84 -31t-86 30t-35 75z" /> -<glyph unicode="/" horiz-adv-x="980" d="M71.5 -16.5q-16.5 20.5 2.5 55.5q115 219 338 652t338 652q23 43 68.5 47.5t86.5 -8.5q29 -4 36 -30.5t-11 -55.5l-672 -1290q-14 -27 -27.5 -37t-22.5 -11t-42 -1t-47 2q-31 4 -47.5 24.5z" /> -<glyph unicode="0" d="M59 636.5q0 276.5 126 475.5t316.5 199t316.5 -199t126 -475.5t-126 -475t-316.5 -198.5t-316.5 198.5t-126 475zM276 637q0 -219 35 -371q23 -96 73 -143t117.5 -47t119 54t69.5 136q37 156 37 371q0 211 -37 371q-20 96 -70.5 143t-117.5 47q-145 0 -191 -190 q-35 -139 -35 -371z" /> -<glyph unicode="1" d="M168 971q0 25 18 41q59 41 197 168q53 49 90 90q18 33 57 41h31q37 0 47 -11.5t15 -48.5l2 -1038v-23q0 -70 55 -71h76q18 0 28.5 -11.5t11.5 -19.5t5 -31v-12q-1 -57 -60 -53q-162 10 -440 2q-41 -6 -57 26q-4 29 -2 48q4 18 9 27t18.5 15.5t39.5 6.5q10 0 28.5 1 t33.5 1q49 2 49 86l2 803q-2 25 -6 24q-2 2 -6 -2q-78 -53 -170 -98q-31 -14 -58 14z" /> -<glyph unicode="2" d="M66 27q-4 37 18 67q98 113 252 275l56 56t58.5 59.5t51.5 56.5t51 63.5t39.5 63.5t35 72.5t18.5 74.5t9 86q0 104 -48 165.5t-138 61.5q-86 0 -159.5 -61t-108.5 -166q-12 -39 -60 -39q-29 0 -37 16.5t-6 32.5q27 182 143.5 291t286.5 109q168 0 264.5 -107.5 t96.5 -273.5q0 -55 -23.5 -113.5t-44 -89.5t-63.5 -86q-55 -72 -122 -142.5t-163 -164.5t-133 -133q-12 -12 12 -17h6q31 2 135.5 1t135.5 -1q113 2 135 15q41 20 55 98q6 29 35 35h43q14 0 20.5 -10.5t6.5 -16.5t-2 -24q-13 -105 -33 -234q-12 -55 -66 -55h-682 q-37 0 -50 6t-25 29z" /> -<glyph unicode="3" d="M74 139q0 39 29.5 70t68.5 31q10 0 21.5 -2t23.5 -7.5t19.5 -9.5t20.5 -13t18.5 -13.5t19.5 -15.5t16 -13q57 -47 89 -61.5t71 -14.5q94 0 159.5 90t65.5 228q0 109 -43 172t-112 63q-59 0 -97 -27q-16 -12 -40.5 -10t-38.5 21q-27 39 10 71q98 74 160 136q82 84 81 159 q0 61 -44 104.5t-109 43.5q-59 0 -120.5 -44t-104.5 -122q-20 -35 -68 -19q-49 23 -31 66q59 133 164 211t227.5 78t207.5 -72t85 -182q0 -141 -127 -240q-12 -10 4 -16q102 -33 165 -128t63 -216q0 -197 -157 -345.5t-365 -148.5q-125 0 -228.5 48t-103.5 128z" /> -<glyph unicode="4" d="M66 399v39q264 416 569 834q2 4 8 12t8 10l7.5 7.5t9.5 6.5t12 2t18 1h37q39 0 39 -54v-28v-670q0 -37 23 -37h118h20.5t13.5 -4t13.5 -12t8.5 -23q2 -49 0 -106q-7 -23 -27 -27q-4 -2 -14 -2h-123q-27 -2 -27 -18q0 -289 -2 -326q0 -39 -49 -41q-12 2 -96 2 q-61 -4 -62 45v314q0 6 -4 11t-8 6t-10 3l-4 2q-231 -2 -424 0q-33 0 -44 10.5t-11 42.5zM276 541q-16 -27 3 -27h270q23 8 22 18q0 63 1 211t1 215q0 25 -14 7q-201 -272 -283 -424z" /> -<glyph unicode="5" d="M102 119q0 41 30 70.5t71 29.5q23 0 43 -6t40.5 -21.5t33 -25.5t36 -32.5t29.5 -29.5q27 -23 64 -22q86 0 147 85t61 212q0 125 -63.5 198.5t-169.5 73.5q-76 0 -168 -55q-31 -16 -55 -2q-29 23 -27 63l41 562q2 35 39 51t74 14l282 -4h64q18 2 30.5 16.5t26.5 14.5h37 q39 0 31 -62l-17 -114q-2 -4 -6 -14.5t-5 -12.5t-5 -8t-7 -7t-10.5 -4.5t-15.5 -4.5t-20 -3l-359 6q-20 -4 -22 -18l-15 -221q1 -18 19 -12q51 16 123 16q178 0 299 -124t121 -304q0 -195 -135.5 -328t-340.5 -133q-123 0 -212 40t-89 116z" /> -<glyph unicode="6" d="M86 508q0 279 172 490.5t479 306.5q49 12 66 -19l10 -14q10 -18 0 -38t-29 -28q-182 -80 -282.5 -182t-141.5 -252q-2 -12 0.5 -17t8.5 -3q63 39 180 39q158 0 262 -116t104 -280q0 -178 -114.5 -305t-286.5 -127q-197 0 -312.5 153.5t-115.5 391.5zM307 467 q0 -197 56.5 -298t154.5 -101q176 0 176 307q0 147 -47 223t-127 76q-70 0 -190 -92q-23 -16 -23 -115z" /> -<glyph unicode="7" d="M57 1014l11 180q2 27 32.5 56.5t61.5 27.5q209 -10 641 0q29 0 52.5 -18.5t21.5 -49.5l-3 -32l-460 -1174q-18 -41 -70 -41q-12 0 -78 10q-29 4 -38 29t1 45l443 1024q2 2 0 4t-7.5 4t-11.5 2q-94 -4 -381 -4h-75q-8 0 -17 -4q-8 -6 -11 -33.5t-16.5 -49t-46.5 -21.5 q-23 0 -37 13t-12 32z" /> -<glyph unicode="8" horiz-adv-x="999" d="M102 322q0 182 211 305q8 4 11 6q12 8 2 18q-193 119 -193 305q0 145 110.5 248t262 103t251 -90.5t99.5 -225.5q0 -178 -164 -278q-12 -6 4 -19q227 -131 228 -336q0 -164 -123 -279.5t-291 -115.5q-178 0 -293 102.5t-115 256.5zM301 324q0 -111 61.5 -182.5 t149.5 -71.5q90 0 151.5 66.5t61.5 166.5q0 84 -49 137q-61 61 -191 131q-25 12 -41 0q-143 -96 -143 -247zM313 1014q0 -86 61.5 -139.5t172.5 -104.5q23 -8 37 6q86 74 86 213q0 98 -44 154.5t-122 56.5q-82 0 -136.5 -53t-54.5 -133z" /> -<glyph unicode="9" d="M80 879q0 176 122 301t294 125q199 0 315.5 -149.5t116.5 -387.5q0 -276 -168 -487t-469 -308q-57 -18 -86 27q-27 41 16 66q2 0 6 2q219 94 334 233q74 92 105 207q2 12 -1.5 18t-13.5 2q-72 -45 -188 -45q-162 0 -272.5 116t-110.5 280zM297 899q0 -141 54.5 -220 t137.5 -79q39 0 93.5 25.5t85.5 54.5q37 37 37 127q0 197 -56.5 295t-156.5 98q-88 0 -141.5 -76.5t-53.5 -224.5z" /> -<glyph unicode=":" horiz-adv-x="526" d="M152 100.5q0 49.5 31.5 80t80.5 30.5t81 -30.5t32 -80.5q0 -51 -33 -82.5t-80 -31.5t-79.5 32.5t-32.5 82zM152 700q0 51 31.5 83t80.5 32t81 -31.5t32 -83.5q0 -47 -33 -78.5t-80 -31.5t-79.5 31.5t-32.5 78.5z" /> -<glyph unicode=";" horiz-adv-x="471" d="M125 74q0 51 36 85t85 34q63 0 104 -50.5t41 -124.5q0 -94 -57.5 -174t-151.5 -118q-33 -14 -50 24.5t15 54.5q117 76 117 158q0 4 -14 2q-2 0 -10.5 -1t-12.5 -1q-43 0 -72.5 33t-29.5 78zM127 696q0 51 33 83t82 32t82.5 -31.5t33.5 -83.5q0 -49 -33.5 -81.5 t-82.5 -32.5t-82 32.5t-33 81.5z" /> -<glyph unicode="<" horiz-adv-x="1429" d="M133 670q-8 25 0 53q0 39 37 55q700 303 1049 436q49 18 65 -5t16 -74v-31q0 -20 -19 -38.5t-38 -27.5q-676 -279 -831 -340q-4 0 -5 -3t3 -5q424 -182 850 -346q41 -16 40 -65v-43q0 -37 -20.5 -57.5t-69.5 -4.5q-358 129 -1042 438q-35 16 -35 58z" /> -<glyph unicode="=" horiz-adv-x="1429" d="M129 442v62q0 53 55 53h23q129 -2 1036 -2q14 0 25.5 -3t18.5 -11.5t10 -14.5t4.5 -19t1.5 -20.5t-1.5 -24t-1.5 -20.5q-2 -45 -14 -53t-43 -8h-1038q-76 0 -76 61zM137 893l4 76q10 41 64 41q33 0 459 1t573 5q27 0 42 -13.5t18 -29t3 -39.5q0 -4 1.5 -18.5t1.5 -22.5 q0 -37 -23 -49q-10 -4 -51 -4h-1030q-31 -4 -42.5 9t-19.5 44z" /> -<glyph unicode=">" horiz-adv-x="1429" d="M131 279q0 47 41 65q633 252 850 346q6 4 -4 10q-350 147 -830 338q-43 18 -49 33q-6 12 -6 37v35q0 45 20.5 66.5t59.5 4.5q518 -209 1038 -432q47 -20 47 -57q6 -33 2 -55q0 -25 -11 -38.5t-44 -27.5q-340 -152 -1022 -428q-51 -20 -70.5 1.5t-19.5 58.5q0 8 -1 22 t-1 21z" /> -<glyph unicode="?" horiz-adv-x="741" d="M76 1241q0 68 59.5 99.5t151.5 31.5q170 0 279.5 -113.5t109.5 -289.5q0 -203 -156 -314q-68 -45 -145 -73q-43 -14 -56.5 -28.5t-13.5 -35.5q0 -45 80 -139q8 -12 0 -29.5t-20 -23.5q-18 -6 -45 1t-37 21q-111 129 -111 236q0 76 40 125t96.5 71.5t111.5 44t95 64.5 t40 110q0 70 -45 108t-131 38q-29 0 -79 -7.5t-75 -7.5q-66 0 -107.5 28t-41.5 83zM197 96q0 51 35.5 84t86.5 33q53 0 88 -33t35 -84t-35 -85t-88 -34q-51 0 -86.5 34t-35.5 85z" /> -<glyph unicode="@" horiz-adv-x="1966" d="M223 567q0 360 247 610t599 250q287 0 471 -161.5t184 -431.5q0 -256 -153.5 -453t-362.5 -197q-162 0 -161 152q0 12 -1.5 13t-9.5 -7q-150 -158 -278 -158q-82 0 -135.5 69t-53.5 163q0 119 54.5 250t150.5 229q141 145 281 145q92 0 141 -61v-2q16 37 30.5 48t55.5 13 h24.5h35h22.5q43 0 43 -45q-8 -29 -55 -194.5t-70 -239.5l-37 -127q-8 -27 -12 -70q-2 -55 33 -55q37 0 90 32t96 81q68 82 110 190.5t42 216.5q0 215 -149.5 353.5t-379.5 138.5q-291 0 -496.5 -224.5t-205.5 -549.5q0 -279 187.5 -457t449.5 -178q457 0 651 430 q10 23 20.5 31t36.5 8q2 0 10.5 -1t12.5 -1q43 -12 26 -58q-84 -246 -290.5 -390t-470.5 -144q-334 0 -558.5 223t-224.5 559zM770 440q0 -41 20.5 -65.5t45.5 -24.5q90 0 200 146q113 147 113 346q0 43 -25.5 69.5t-60.5 26.5q-55 0 -117 -68q-74 -88 -125 -217t-51 -213z " /> -<glyph unicode="A" horiz-adv-x="1456" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 27.5t39 15.5h68h26q59 0 80 -30q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40q-8 -15 -27 -15h-5 q-128 6 -280 6q-121 0 -258 -4q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -33 87 -33q16 0 34 1q25 4 43 0q12 -2 22.5 -20.5 t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5q-167 3 -275.5 3t-158.5 -3h-27q-39 6 -39 61.5zM563 729q-1 -2 -1 -4q0 -4 6 -6q10 -2 24 -2q49 1 93.5 1t84.5 -1q8 0 16 7q6 6 5 10l-97 286q-2 8 -7 10q-2 1 -4.5 1t-4.5 -1q-4 -2 -6 -4q-20 -61 -62.5 -175t-46.5 -122z" /> -<glyph unicode="B" horiz-adv-x="1343" d="M36 48q5 52 27 61q43 6 56 2q111 0 136.5 28.5t25.5 145.5v757q0 131 -29 160q-20 20 -119 21h-47q-24 0 -24 50q0 58 22 60q172 18 594 19q127 0 185.5 -11.5t135.5 -46.5q88 -39 140.5 -112.5t52.5 -161.5q0 -80 -46 -147.5t-122 -106.5q-16 -8 2 -16 q113 -53 178.5 -140.5t65.5 -193.5q0 -143 -95.5 -260t-234.5 -144q-106 -21 -226 -21q-24 0 -48 1q-158 3 -307 3t-289 -3q-35 4 -35 45q0 5 1 11zM528 371q0 -104 11 -156q8 -49 51 -72.5t141 -23.5q121 0 198 82t77 202q0 78 -38 144.5t-104 105.5q-35 20 -79 31 q-45 10 -69 12q-12 1 -33 1t-51 -1q-60 -2 -77 -2q-27 -8 -27 -39v-284zM528 825q0 -18 29 -18q15 0 61 -1h39.5h26.5q20 1 61 4t61.5 10t49.5 22.5t43 36t24.5 53.5t10.5 76q0 118 -80 186q-60 50 -148 58q-35 3 -67 3q-49 0 -92 -8q-18 -8 -19 -26v-396z" /> -<glyph unicode="C" horiz-adv-x="1560" d="M98 649q0 315 215 514t553 199q25 0 46.5 -1t44 -4t37 -4t39 -7.5t34.5 -8.5t36.5 -11t36 -11t42 -13.5t43.5 -15.5q41 -14 57 0q12 10 45 7t37 -21q21 -87 21 -157q0 -14 -1 -28q0 -2 -1 -62t1 -60q-8 -33 -46 -41.5t-56 18.5q-104 301 -403 301q-233 0 -368.5 -147.5 t-135.5 -403.5q0 -264 149.5 -434t382.5 -170q178 0 314 123q41 37 61.5 62.5t54.5 88.5q10 18 39 24q28 7 50 -4q17 -9 17 -26q0 -5 -1 -10q-54 -176 -152 -336q-39 8 -57 8q-57 0 -150 -28q-90 -29 -239 -29q-326 0 -536 194.5t-210 493.5z" /> -<glyph unicode="D" horiz-adv-x="1583" d="M20 76q10 28 35 37q12 2 44 3t48.5 4t35 16.5t26.5 37.5q8 23 8 113v755q0 129 -16 152q-20 29 -131 29h-19q-28 0 -28 45q0 54 22 61l18 4q401 16 596 17q199 0 331 -34t245 -112q254 -180 254 -497q0 -229 -143.5 -418t-370.5 -252q-154 -43 -404 -43l-483 -2 q-46 0 -62 28q-10 17 -10 33q0 12 4 23zM463 223q0 -68 22.5 -90t110.5 -22q293 0 460 136t167 429q0 143 -52.5 261.5t-144.5 188.5q-63 49 -130 73t-183 36q-64 6 -133 6q-42 0 -86 -2q-10 -2 -20.5 -11t-10.5 -18v-987z" /> -<glyph unicode="E" horiz-adv-x="1267" d="M37 58q8 54 41 57q14 2 88 2q78 2 102.5 30.5t24.5 139.5v753q0 106 -23.5 142.5t-111.5 36.5h-8.5h-9.5h-8t-8 1t-7 2t-7.5 2t-7.5 3t-7 5t-6 7t-5 10q-5 9 -5 20q0 18 13 42q10 20 53 20q328 2 551.5 2t343.5 -2q53 0 60 -39q8 -66 11 -118t4 -96t3 -60 q-2 -18 -29.5 -25.5t-50.5 0.5q-29 4 -28 39q-18 115 -48 139.5t-145 26.5q-109 4 -179 4q-46 0 -75 -2q-8 0 -17 -8t-9 -18v-398q0 -20 26 -20h211q109 0 130.5 16t35.5 115q4 14 25.5 21t45 -3t29.5 -41q2 -45 2 -111.5t-1 -142t-1 -102.5q0 -31 -25.5 -42t-50 -4 t-28.5 25q-14 92 -36.5 110.5t-131.5 18.5l-199 2q-33 0 -32 -30v-314q0 -63 2 -84q2 -29 12 -38q16 -16 125 -17h145q109 0 142.5 7.5t54.5 33.5q45 49 69 152q6 29 37 37q8 1 15 1q45 0 55 -22q5 -10 5 -34.5t-5 -63.5q-2 -23 -11 -90.5t-16 -112.5q-6 -47 -100 -47 q-225 2 -428 2q-303 0 -555 -4l-10 2q-38 7 -38 46q0 8 1 16z" /> -<glyph unicode="F" horiz-adv-x="1112" d="M76 1283q2 48 37 48h6q215 2 430 2l430 -2q20 0 36.5 -18.5t16.5 -38.5l-6 -227q-23 -15 -50 -15q-14 0 -30 4q-23 4 -22 35q-6 80 -39 101.5t-160 21.5h-211q-37 0 -41 -23l-2 -358q0 -12 5 -18.5t9 -8.5t15.5 -4t13.5 -2q26 -2 80.5 -2t136.5 2q106 0 129 12.5t29 73.5 q4 33 50 38q5 1 10 1q36 0 40 -33v-358q-4 -23 -48 -31q-7 -1 -14 -1q-31 0 -36 32q-8 90 -34 110q-24 18 -115 17h-19q-53 -2 -107 -2t-108 2q-12 -2 -23.5 -11t-11.5 -18v-395q0 -70 23.5 -90.5t103.5 -20.5h23q32 -4 32 -56q0 -23 -10 -39.5t-27 -16.5q-124 3 -250 3 t-253 -3h-3q-35 0 -35 48q0 55 29 60q80 4 102.5 24.5t22.5 90.5v893q0 68 -24.5 88.5t-100.5 24.5q-31 7 -31 53q1 3 1 7z" /> -<glyph unicode="G" horiz-adv-x="1562" d="M102 643q0 152 64.5 290t175.5 243q109 100 226.5 145t279.5 45q133 0 338 -61q35 -10 57 -11q14 0 27 13q8 12 35.5 12t33.5 -14q10 -16 13 -151q2 -49 2 -91q0 -71 -4 -119q-2 -39 -47 -39h-5q-49 2 -55 33q-66 315 -364 315q-240 0 -375 -159.5t-135 -440.5 q0 -258 134 -416.5t353 -158.5q115 0 252 61q12 4 12 45v201q0 70 -25.5 90.5t-109.5 22.5l-78 2q-10 0 -20 10t-15.5 25.5t-5.5 32t10.5 28.5t30.5 14q68 -2 172.5 -2t225 1t159.5 1h3q39 0 39 -42q0 -7 -1 -15q-10 -41 -12 -43q-16 -12 -41 -8q-63 -8 -77.5 -26.5 t-16.5 -88.5q-2 -53 -2 -109t2 -116q0 -57 -29 -74q-109 -53 -260 -90t-278 -37q-301 0 -495 193.5t-194 488.5z" /> -<glyph unicode="H" horiz-adv-x="1613" d="M42 79q9 32 42 34h12h14.5h12.5q63 4 83.5 22.5t20.5 81.5v893q0 66 -20.5 88.5t-81.5 26.5h-12q-23 2 -29 28.5t5 52t28 25.5q128 -6 248.5 -6t234.5 6q10 2 35 -12q12 -12 12 -39q0 -12 -2 -27q-6 -23 -45 -26q-78 0 -105.5 -26.5t-27.5 -90.5v-342q0 -31 25 -31h299 q150 -1 229 -1t86 1q39 10 39 35v338q0 51 -25.5 77.5t-55.5 32t-79 7.5h-16q-27 4 -34 32.5t1 47.5q16 30 53 30h2q22 1 52 1q77 0 210.5 -4t201.5 -4q27 0 44 1q27 0 43.5 -23.5t10 -51t-34.5 -33.5q-6 -2 -19 -2q-57 -6 -85 -28t-30 -83q-2 -135 -2 -307t1 -352.5 t1 -233.5q0 -57 29 -79.5t105 -22.5q70 0 71 -54q2 -45 -35 -63q-8 -4 -16 -4h-573q-41 0 -47 33q-8 25 3 55.5t42 30.5h49q76 0 104.5 21.5t28.5 82.5v371q-2 14 -37 14h-190.5h-230.5h-200q-2 0 -6 -3t-9 -10t-5 -16v-356q0 -68 22.5 -87t100.5 -19h18q27 2 41.5 -25 t4 -57.5t-43.5 -34.5h-514q-41 0 -51 26q-7 15 -7 32q0 13 4 27z" /> -<glyph unicode="I" horiz-adv-x="743" d="M92 45q0 55 31 61q8 2 27 3q63 8 81.5 27.5t20.5 80.5l2 70v753l-2 70q-2 72 -17.5 89.5t-84.5 25.5q-16 0 -29 6q-21 13 -21 41q0 8 2 17q8 42 41 44h13q173 -2 285.5 -2t164.5 2q49 0 53 -41q4 -24 -6 -47q-12 -20 -51 -20q-80 -2 -97.5 -28t-17.5 -157v-823 q0 -72 27 -92q12 -8 104 -14q30 0 42 -27q7 -15 6 -31q0 -15 -4 -29q-10 -32 -35 -32q-123 4 -245.5 4t-244.5 -4q-20 0 -32.5 15.5t-12.5 37.5z" /> -<glyph unicode="J" horiz-adv-x="663" d="M-195 -446q0 45 32 79.5t77 34.5q14 0 29.5 -6t23.5 -12t24.5 -19.5t20.5 -17.5q43 -33 47 -35q25 -12 59 -1t52 38q29 43 38 120t9 288v962q0 82 -2 123q-2 72 -25.5 92.5t-103.5 20.5q-6 -2 -18.5 1t-14.5 3q-33 2 -33 57q0 20 12 36q12 13 32 13h6q25 0 43 -2 q25 0 183 2q78 1 149 1t135 -1q45 -2 45 -45q0 -51 -27 -57q-13 -6 -31 -6q-12 -2 -35 -2q-80 -6 -79 -113v-954q0 -141 -35 -299t-101 -258q-121 -188 -297 -189q-90 0 -152.5 39t-62.5 107z" /> -<glyph unicode="K" horiz-adv-x="1515" d="M32 61q5 37 40 50q16 4 47 0q66 0 98.5 23.5t32.5 82.5v893q0 70 -25.5 92.5t-107.5 22.5h-41q-31 2 -39 35.5t4 48.5q8 26 44 26h3q205 -5 353 -5q111 0 190 3q49 0 49 -53q0 -55 -57 -55q-84 0 -109 -22.5t-25 -92.5v-403q0 -8 7 -9q27 10 63 43q92 78 208 232.5 t116 224.5q0 14 -11.5 17.5t-72.5 9.5l-37 4q-25 20 -25 49q0 14 6 31q10 29 48 22q146 -4 271 -4t230 4q31 0 44.5 -26.5t0 -53t-44.5 -22.5q-98 -2 -155.5 -25.5t-102.5 -85.5q-12 -16 -59 -90q-117 -176 -238 -317l-4 -4q23 -14 94 -80q57 -55 114.5 -121t128.5 -155 t106 -128q61 -74 106 -93t137 -19q35 0 47 -23q9 -12 9 -31q-1 -10 -3 -22q-8 -35 -42 -41q-36 3 -148 3q-149 0 -434 -5q-33 8 -43 24q-12 25 -3 55.5t40 30.5q20 2 35.5 4.5t37 9.5t21.5 19t-12 33q-8 10 -46 59t-50.5 63.5t-46 56.5t-53 62.5t-50.5 52.5t-60.5 55.5 t-60.5 45.5q-29 20 -59 27q-8 0 -9 -45v-328q0 -61 27 -84.5t107 -23.5q45 0 57 -25q9 -20 9 -38t-9 -34q-8 -20 -47 -20q-125 5 -259 5t-276 -5h-12q-31 0 -43 16q-12 12 -12 37q0 7 1 16z" /> -<glyph unicode="L" horiz-adv-x="1218" d="M34 80q7 33 34 35h12h14q127 0 142 65q4 45 4 115v815q0 70 -25 90.5t-109 22.5h-24q-27 2 -33 38.5t4 51.5q16 27 51 20q84 -2 193 -2q163 0 379 4q41 0 49 -32q5 -18 5 -33q0 -47 -50 -51q-41 -4 -66 -5q-92 -4 -114.5 -17t-22.5 -67v-909q0 -49 27.5 -67.5t85.5 -18.5 h170q115 0 155.5 18.5t108.5 106.5l74 96q22 8 38 8t27 -8q13 -6 17 -18q4 -10 3 -17q0 -8 -3 -14q-86 -205 -125 -268q-35 -47 -82 -47q-260 4 -555 5h-108q-194 0 -222 -3h-7q-33 0 -44 33q-6 12 -6 28q0 11 3 25z" /> -<glyph unicode="M" horiz-adv-x="1929" d="M45 25q-5 13 -5 26q0 15 7 29q14 27 45 24q12 -1 23 -1q53 1 75 17q28 20 35 77q4 41 6 92q6 92 21.5 271t24 322.5t8.5 272.5q0 45 -28 54.5t-63.5 10.5t-46.5 23q-10 25 -4 51q7 39 43 39h7q71 -4 157 -4q57 0 121 2q53 0 68 -33l419 -938q6 -6 11.5 -0.5t13.5 21.5 l403 915q20 35 70 35q68 -2 137.5 -2t139.5 2q27 0 40 -25.5t4.5 -53t-34.5 -29.5q-6 -2 -37 -4t-45 -7q-31 -10 -31 -53q0 -25 4 -82l56 -784q8 -131 31.5 -159t101.5 -28q12 0 21 -2t15.5 -4t10.5 -7t6 -9t3 -12.5t1 -12.5v-15v-15q-6 -35 -51 -35q-74 5 -229 5 q-117 0 -279 -3q-51 0 -55 31q-4 14 0 45q2 14 19.5 24t35.5 10q41 0 67.5 8.5t41 14.5t20.5 31.5t7 36t-2 52.5t-3 56q-4 109 -41 674q-2 23 -16 -12q-2 -7 -4 -11l-414 -946q-8 -23 -50 -23q-1 1 -2 1q-44 0 -53 22l-430 951l-14 24l-43 -690q-4 -78 -4 -98 q0 -47 22.5 -66.5t98.5 -26.5q41 0 51 -32q3 -15 3 -28q0 -38 -32 -46q-4 -2 -11 -3t-11 -1q-116 5 -232 5l-174 -3q-4 0 -12 1t-12 2t-10.5 4t-10.5 8t-6 14z" /> -<glyph unicode="N" horiz-adv-x="1708" d="M66 79q12 30 51 30q131 0 131 94v991q-45 27 -148 31q-12 0 -20 17.5t-8 37.5q0 49 53 53q37 3 96 3q31 0 65 -1q106 -2 128 -2q39 0 65 -30l797 -895h-2q27 -31 26 -2v636q0 133 -18 152q-12 12 -45 18q-16 2 -53 4.5t-56 4.5q-25 0 -36 28.5t-0.5 56t38.5 27.5 q62 -3 162 -3q133 0 332 5q29 0 35 -59q2 -51 -49 -51q-109 -4 -127.5 -22.5t-18.5 -127.5v-1046q0 -43 -58 -49q-13 -1 -23 -2q-38 0 -50 18q-178 201 -468 527.5t-429 484.5q-4 2 -10 8q-8 -6 -10 -15v-704q0 -98 10 -129q8 -23 25.5 -35t30 -14t44 -2h37.5q51 -4 60 -27 q15 -22 5 -60q-9 -36 -44 -36h-4q-140 3 -247 3q-143 0 -227 -5q-27 -2 -40 28q-7 15 -7 30q1 14 7 29z" /> -<glyph unicode="O" horiz-adv-x="1693" d="M92 639q0 313 214 520t544 207q324 0 532.5 -190.5t208.5 -481.5q0 -311 -213 -522t-532 -211q-324 0 -539 194.5t-215 483.5zM360 692q0 -264 146.5 -438t374.5 -174q236 0 339 152.5t103 400.5q0 274 -146 445t-384 171q-195 0 -314 -152.5t-119 -404.5z" /> -<glyph unicode="P" horiz-adv-x="1181" d="M41 1276q0 53 35 55q162 18 463 19q168 0 272 -27q137 -35 220 -134t83 -231q0 -197 -141 -310t-383 -113q-45 0 -88 6q-4 2 -6 -2t-2 -19v-303q0 -59 20 -83q19 -22 66 -21h8q10 0 35.5 2t40.5 2q51 -2 65 -25q10 -18 8 -47q-2 -23 -14 -40q-11 -15 -29 -15h-4 q-148 6 -303 6q-124 0 -252 -4q-39 0 -55 22q-10 18 -8 37q2 49 13 56.5t67 7.5q70 0 84 9t14 52v914q0 94 -13.5 117.5t-58.5 23.5q-8 0 -31.5 -3t-37 -3t-30 3t-26.5 15t-12 33zM494 680q0 -29 22 -35q31 -6 62 -6q139 0 208.5 85t69.5 239q0 183 -125 249q-67 34 -157 34 q-28 0 -58 -3q-23 -2 -22 -31v-532z" /> -<glyph unicode="Q" horiz-adv-x="1683" d="M78 639q0 309 218 518t548 209q324 0 526.5 -191.5t202.5 -486.5q0 -231 -133 -416.5t-355 -269.5q-8 0 0 -4q100 -47 248 -170q92 -78 154.5 -106.5t154.5 -30.5q26 -8 26 -28q0 -15 -13 -36q-25 -45 -56 -51q-59 -12 -106 -12q-223 0 -494 225q-35 29 -78.5 68 t-60.5 51q-25 18 -96 47q-307 27 -496.5 217t-189.5 467zM346 686q0 -266 149.5 -443t376.5 -177q135 0 236.5 88t146.5 213t45 262q0 279 -138 448.5t-374 169.5q-201 0 -321.5 -153.5t-120.5 -407.5z" /> -<glyph unicode="R" horiz-adv-x="1425" d="M30 74q10 28 42 32q6 2 22 3h19q80 0 103.5 22.5t23.5 85.5v70v755q0 82 -2 109q-2 37 -17 51q-16 23 -149 25q-36 0 -36 49q0 44 30 57q168 16 505 17q102 0 194.5 -18.5t178.5 -60.5t136 -123t50 -194q0 -109 -55 -203t-147 -147q-8 -4 4 -26q33 -49 69.5 -104.5 t81.5 -123t70 -104.5q49 -72 123 -127q39 -33 104 -45q28 -22 28 -48q0 -18 -13 -38q-18 -13 -45 -17q-14 -2 -43 -2q-205 0 -318 129q-68 76 -174 240q-18 29 -47 84t-41 76q-14 37 -29 34q-78 -6 -156 -6h-38q-8 2 -13.5 -9t-5.5 -15q0 -182 2 -285q4 -66 28 -85t99 -19 q25 6 52.5 1t38.5 -34q3 -17 3 -31q0 -55 -51 -55q-37 0 -165 2q-85 1 -158 1h-70q-102 -1 -168 -5l-33 2q-19 0 -31 26q-6 15 -7 30q1 12 5 24zM485 659q0 -6 4.5 -12t8.5 -8l4 -2q44 -2 78 -2q68 0 94 8q90 31 141 114t51 185q0 150 -68.5 226.5t-246.5 76.5 q-66 0 -66 -24v-562z" /> -<glyph unicode="S" horiz-adv-x="1050" d="M104 339q0 15 18 23q20 10 45.5 8.5t35.5 -12.5q31 -92 61.5 -139t81.5 -82q76 -53 154 -53q104 0 164.5 57.5t60.5 145.5q0 33 -9 62.5t-30.5 57t-39 48t-52.5 47t-52.5 39t-58.5 39t-51 32.5q-72 47 -117 83t-98 89.5t-79.5 116t-26.5 133.5q0 145 106.5 238.5 t271.5 93.5q63 0 175 -35q49 -16 65 -16q8 0 10 6l13 8q20 8 51 4q14 2 21 -7t10 -26q31 -236 32 -258q-2 -33 -24.5 -40t-44 2.5t-25.5 17.5q-92 229 -264 229q-84 0 -128 -43t-44 -114q0 -117 239 -277q10 -8 17 -12q88 -59 130 -90t109.5 -93.5t97 -130t29.5 -145.5 q0 -168 -123.5 -276.5t-316.5 -108.5q-68 0 -213 43q-43 12 -53 12q-4 0 -16 -16q-20 -14 -52 -9t-37 34q-43 261 -43 314z" /> -<glyph unicode="T" horiz-adv-x="1394" d="M92 1354q23 25 53 25q3 -1 5 -1q34 -2 43 -24q8 -20 92 -21q205 -2 413 -2t418 2q66 0 76 2q14 4 20 19q9 21 44 21q13 0 30 -3q25 -4 29 -37l31 -331v-5q0 -19 -14 -28q-16 -10 -34 -10q-51 0 -59 47q-25 119 -48.5 151.5t-68.5 32.5h-270q-27 0 -27 -51v-854v-70 q0 -55 23.5 -77.5t105.5 -22.5h58q35 0 47 -34t2 -58q-12 -31 -53 -31q-100 4 -233 4q-166 0 -382 -6q-35 0 -45 28q-5 16 -5 32t5 32q10 16 17.5 19t25.5 8h23.5h29h27.5q35 0 53.5 4t36 29.5t17.5 72.5v70v310v385v165q0 45 -35 45h-217h-41q-47 0 -73 -38t-52 -175 q-19 -12 -42 -12q-11 0 -24 3q-35 9 -35 33q0 89 33 351z" /> -<glyph unicode="U" horiz-adv-x="1669" d="M41 1258q-4 12 -4 22q0 19 12 33q14 18 45 18h514q39 0 50.5 -26.5t-1 -54t-30.5 -27.5h-19q-84 0 -107.5 -20.5t-25.5 -92.5q0 -16 -1 -45t-1 -43v-387q0 -115 18.5 -201t61.5 -156.5t123 -107.5t194 -37q281 0 367 223q31 80 31 267v360q0 160 -28 199t-136 43 q-31 8 -37 24q-7 14 -7 29.5t7 32.5q10 20 37 20q110 2 233 2t258 -2q39 0 39 -51q0 -45 -37 -53q-109 -4 -138 -43t-29 -193v-366q0 -129 -6.5 -196t-47.5 -156t-123 -160q-92 -82 -187 -117t-243 -35q-408 0 -551 309q-31 70 -39 128.5t-8 207.5v518q0 29 -4 47.5t-8 28.5 t-19.5 15.5t-23.5 6.5t-39 1h-47q-33 3 -43 35z" /> -<glyph unicode="V" horiz-adv-x="1558" d="M41 1247q-5 13 -5 25q0 15 7 28q8 31 53 31q137 -4 270.5 -4t262.5 4q51 0 61 -14q14 -19 14 -39q0 -13 -6 -27q-6 -16 -39 -32q-109 -8 -129 -13q-35 -7 -35 -44q0 -17 7 -40q12 -29 18 -45l301 -737q4 -8 11.5 -13t11.5 3l280 729q27 66 29 98v7q0 45 -47 57 q-20 4 -92 4q-31 0 -45 24q-9 17 -9 32q0 17 11 34q12 17 38 17q5 0 11 -1q58 -4 173 -4t288 4h4q42 0 41 -44q0 -54 -37 -58q-78 0 -115 -36t-86 -159l-405 -1032q-6 -14 -22.5 -31.5t-33.5 -19.5q-13 -2 -29 -2q-24 0 -55 4q-31 6 -45 45l-434 1067q-29 72 -57.5 105.5 t-52 40t-72.5 8.5q-31 6 -41 28z" /> -<glyph unicode="W" horiz-adv-x="2224" d="M26 1284q6 47 50 47q315 0 499 2q41 0 50 -26q6 -31 -4 -60q-8 -20 -41 -20q-51 0 -64.5 -8.5t-13.5 -26.5q0 -29 37 -119l309 -760h-2q16 -23 26 6l162 392q12 31 4 57l-143 332q-37 88 -64.5 106.5t-134.5 22.5q-27 4 -27 59q0 45 29 45h2q184 -4 393 -4t441 4 q18 2 43 -10q18 -12 17 -48t-19 -46q-8 -4 -29 -4q-92 -2 -121.5 -22.5t-64.5 -104.5l-100 -242q-8 -18 0 -39l219 -518q10 -29 20 0l307 793q28 72 28 101q0 9 -3 15q-12 20 -100 23q-27 4 -33 30.5t8 50t37 21.5q51 -4 137 -4q108 0 270 6q18 0 30.5 -15t14.5 -36 q0 -55 -45 -55q-82 0 -115.5 -26.5t-74.5 -137.5l-410 -1055q-16 -39 -39 -43q-36 -5 -64 -5q-57 0 -75 22q-2 4 -6 14t-6 12l-213 500q-14 33 -29 -4l-205 -494q-16 -41 -51 -49q-20 -5 -43 -5q-30 0 -65 9q-29 10 -43 49l-406 1018q-53 135 -82 158q-10 10 -30.5 15t-34 6 t-40 2.5t-30.5 1.5q-27 0 -41 8q-22 10 -22 44q0 7 1 15zM1098 1222q-2 -1 -2 -7q0 -7 2 -19q2 -8 15 -42t27.5 -68.5t16.5 -41.5q6 -14 11.5 -14t11.5 14q20 45 57 154q1 5 1 9q0 18 -28 20h-84q-24 -2 -28 -5z" /> -<glyph unicode="X" horiz-adv-x="1607" d="M45 51q0 16 11.5 33.5t29.5 19.5q82 6 126 26t85 73q27 33 362 452q6 12 7.5 15.5t-5 11.5t-6.5 10l-280 355q-88 117 -129 139q-39 25 -150 26q-12 0 -29.5 11.5t-21.5 25.5q-4 20 -4 34.5t4 23.5q10 27 45 27q6 0 12 -1q132 -6 263 -6q153 0 303 8q41 0 53 -28 q6 -6 4 -33t-14 -39q-25 -8 -41 -8l-86 -4q-25 -2 -11 -33q10 -27 45 -70l197 -258q2 -2 8 1t11 7l4 4q178 233 219 293q20 31 14 43.5t-43 12.5q-68 0 -80 10q-16 14 -17 44t15 42q12 12 37 12q432 0 473 2q31 -4 41 -30.5t-2 -51t-39 -24.5q-113 -6 -183.5 -61.5 t-164.5 -176.5l-184 -241q-10 -12 0 -25q35 -39 82 -97.5t92 -116.5t84 -110.5t65.5 -87.5t26.5 -37q10 -12 30.5 -40.5t26.5 -36t22.5 -25.5t26 -23.5t27.5 -16.5t36.5 -15t44 -9.5t58.5 -9.5q37 -4 37 -53q0 -16 -10 -33.5t-33 -15.5q-82 2 -278.5 2t-266.5 -4 q-4 -1 -9 -1q-24 0 -36 21q-12 23 -4 54.5t29 31.5h26q70 0 70 19q-2 27 -55 98l-230 307q-14 20 -20 20.5t-18 -16.5q-4 -6 -7 -8l-260 -321q-41 -51 -41 -70q0 -10 11 -16q20 -12 88 -13h18q27 0 39 -26.5t2 -53t-37 -26.5q-217 4 -345 4q-85 0 -130 -2q-18 -2 -29.5 17.5 t-11.5 37.5z" /> -<glyph unicode="Y" horiz-adv-x="1490" d="M23 1253q-2 8 -2 17.5t2 19.5q9 42 37 42q4 0 8 -1q194 -3 329 -3t211 3q23 0 37 -26.5t4 -54t-47 -27.5q-59 0 -74 -2q-31 -6 -18 -41q10 -25 47 -82l254 -383q6 -10 7 -12.5t6 -5.5t10.5 2.5t11.5 15.5l217 358q55 92 55 121q0 18 -15.5 24.5t-72.5 6.5h-24 q-14 6 -23.5 32.5t0.5 50.5q9 23 40 23h5q86 -3 195 -3t241 3q41 0 41 -51q0 -53 -39 -53q-31 -2 -56.5 -8.5t-48 -21.5t-35.5 -24.5t-33.5 -37t-26.5 -36.5t-27.5 -46t-26.5 -43l-297 -494v-299q0 -57 30 -77.5t91 -24.5q53 0 64 -6q20 -10 20 -62q0 -55 -45 -55 q-236 4 -388 4q-101 0 -165 -2q-39 0 -53 26q-10 29 -2 60q8 20 22.5 29.5t25.5 9.5t34.5 -1t34.5 -1q45 2 63.5 26.5t22.5 75.5q5 81 5 158q0 58 -3 115l-367 563q-70 109 -109.5 137.5t-123.5 32.5q-41 0 -49 28z" /> -<glyph unicode="Z" horiz-adv-x="1443" d="M63 53q4 25 15 39l835 1084q2 2 3.5 7t1.5 9v2h-414q-145 0 -180 -28.5t-52 -166.5l-2 -10q-2 -10 -27.5 -14t-51 4t-25.5 29q0 201 10 286q8 27 64 37h958q51 0 62 -20q12 -18 12 -36.5t-12 -37.5l-848 -1090q-4 -4 2 -6t18 -3t19.5 -1h13.5h471q154 0 201 53.5 t63 210.5q2 12 3 16.5t7.5 9.5t20.5 5h49q35 0 35 -26q-6 -174 -29 -369q-4 -18 -33.5 -29.5t-48.5 -11.5q-61 0 -287.5 -1t-351.5 -1q-98 0 -201.5 1t-169 1h-69.5q-25 0 -45 14q-17 11 -18 34q0 4 1 9z" /> -<glyph unicode="[" horiz-adv-x="690" d="M203 -408v1758q0 35 13 47t48 16q10 4 129 1t129 -3q45 0 45 -27v-41q0 -29 -35 -32q-113 -10 -120 -15q-14 -10 -15 -43v-1566q0 -31 12.5 -37t71.5 -10l54 -5q33 -2 32 -43v-32q0 -8 -3 -13.5t-10 -7.5t-12 -2t-15.5 -1t-14.5 -1q-127 -8 -250 -4q-59 4 -59 61z" /> -<glyph unicode="\" horiz-adv-x="980" d="M74 1321q-14 29 4 44t51 15h64q25 0 34 -1t19 -10t20 -30l635 -1292q33 -70 -33 -76l-84 -10q-27 -2 -40 8.5t-25 34.5z" /> -<glyph unicode="]" horiz-adv-x="702" d="M55 -397q0 20 29 28q10 2 35.5 4.5t30.5 2.5q29 2 41 4t23 13t11 34q6 1174 0 1568q-2 20 -5 29.5t-10 13t-28 5.5l-92 6q-35 4 -35 30v37q0 35 33 35h23q20 0 75.5 1t100.5 1t71 -2q35 -2 48.5 -19.5t13.5 -54.5v-1747q0 -57 -64 -61q-174 -6 -260 0q-41 4 -41 39v33z " /> -<glyph unicode="^" horiz-adv-x="1005" d="M49 766q238 408 416 674q6 16 22 16h39q16 0 27 -16q266 -428 414 -682q16 -37 3 -52.5t-40 -17.5q-41 -8 -66.5 -3t-48.5 42q-123 215 -291 477q-18 27 -37 0q-90 -139 -294 -485q-23 -35 -72 -35q-55 6 -60 8q-43 16 -12 74z" /> -<glyph unicode="_" horiz-adv-x="1071" d="M-8 -385q0 2 2 8t6 7t11 3t20 2q256 -2 1016 -2q37 0 36 -32v-43v-4q0 -27 -18 -29h-41h-985q-12 0 -20.5 1t-13.5 3t-8 3t-4 6t-1 7v10.5v12.5v37v10z" /> -<glyph unicode="`" horiz-adv-x="712" d="M138.5 1325.5q19.5 20.5 41.5 20.5l148 2q39 0 55 -25q51 -129 96 -305q2 -35 -32 -41t-52 12q-92 117 -256 289q-20 27 -0.5 47.5z" /> -<glyph unicode="a" horiz-adv-x="862" d="M47 172q0 160 227 219q63 16 183 70q10 10 10 18l-2 125q-2 156 -111 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -31 8 -51q-16 -18 -67 -43t-70 -31t-33 -6q-41 0 -41 55q0 78 134 183q111 84 200 84q68 0 135.5 -34t104.5 -87q27 -37 33 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q33 0 70 31q14 10 33 10q29 -4 35 -32q2 -10 2 -19q0 -16 -7 -29q-139 -123 -229 -123q-94 1 -119 99v-2q-72 -55 -114.5 -76t-102.5 -21q-92 0 -153.5 55.5t-61.5 141.5zM244 197q0 -37 24.5 -61.5t63.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12q-3 4 -6 4 h-2q-29 -14 -115 -51q-94 -35 -94 -100z" /> -<glyph unicode="b" horiz-adv-x="1011" d="M12 1354q0 39 27 47l244 82q15 4 26 4q39 0 39 -53v-639q0 -21 2 -25q2 2 22.5 16.5t27 18.5t26.5 17.5t30.5 18.5t29 15t30.5 15.5t28.5 11.5t31 8t28.5 2q145 0 245.5 -124t100.5 -294q0 -215 -135 -360.5t-344 -145.5q-106 0 -283 39q-31 10 -34 55q3 248 3 532.5 t-3 604.5q0 20 -1 44t-1 28q0 14 -27 18q-14 2 -86 17q-27 8 -27 47zM348 453q0 -182 14 -236q12 -55 55.5 -87t104.5 -32q100 0 164 85t64 229q0 145 -64 232t-158 87q-57 0 -172 -82q-6 -4 -6 -47q-2 -39 -2 -149z" /> -<glyph unicode="c" horiz-adv-x="888" d="M51 397q0 203 147.5 345.5t354.5 142.5q102 0 180 -38t78 -108q0 -39 -26.5 -66.5t-65.5 -27.5q-61 0 -139 76q-49 47 -99 47q-88 0 -156.5 -95t-68.5 -231q0 -143 70.5 -229t179.5 -86q135 0 215 115q13 36 44 36q8 0 17 -2q25 -12 33 -38q2 -9 2 -17q0 -18 -12 -31 q-139 -215 -369 -215q-168 0 -276.5 121t-108.5 301z" /> -<glyph unicode="d" horiz-adv-x="1067" d="M39 401q0 207 136 349.5t337 142.5q68 0 158 -27q4 -2 6 0t3 7.5t1 10.5t-1 11t-1 8q2 63 2 205.5t-2 177.5q0 14 -4 17q-12 6 -109 14q-31 4 -35 45v8q0 40 37 47q162 53 250 84q16 7 28 7q11 0 19 -8q14 -15 15 -40v-1206q0 -68 4 -80t28 -12q14 0 60 18q25 8 39 3 t22 -33q4 -11 4 -23q0 -8 -2 -18q-4 -23 -18 -29q-115 -55 -266 -100q-11 -3 -20 -3q-24 -1 -36 21q-16 27 -16 58v7q0 8 -4 13.5t-10 1.5q-164 -109 -269 -109q-150 0 -253 127t-103 305zM246 463q0 -147 65.5 -239.5t157.5 -92.5q82 0 199 78q8 8 8 29v395 q-96 135 -209 135q-98 0 -159.5 -82t-61.5 -223z" /> -<glyph unicode="e" horiz-adv-x="874" d="M43 414q0 199 123 332t309 133q219 0 305 -185q33 -66 56 -94q7 -14 7 -28q0 -12 -5 -24q-10 -26 -45 -28q-75 -3 -206 -3t-317 3q-29 0 -28 -57q0 -143 77.5 -235.5t194.5 -92.5q129 0 231 119q20 23 52 16q20 -4 32.5 -28.5t-0.5 -44.5q-203 -227 -395 -228 q-168 0 -279.5 130t-111.5 315zM266 631q4 -6 27 -6h276q11 0 19 4q6 3 6 8q0 139 -164 139q-106 0 -164 -145z" /> -<glyph unicode="f" horiz-adv-x="663" d="M41 731q-6 20 -6 35q0 29 20 43q129 37 135 53q2 6 3 21q0 8 1 29.5t1 39.5q6 123 36.5 203t110.5 168q154 166 330 166q59 0 130.5 -25.5t104.5 -72.5q8 -14 8 -35q0 -28 -43 -94q-20 -33 -50 -33q-27 0 -62 28q-88 74 -178 74q-53 0 -96.5 -31.5t-63.5 -85.5 q-27 -75 -27 -176v-14l2 -129q0 -27 13 -27h139q41 0 47 -20l4 -8l14 -101q-4 -23 -13 -30t-34 -7l-166 3q-4 0 -4 -25v-404q0 -123 17 -145q10 -14 45 -19q24 -4 46 -4h21q31 3 54 1q41 -2 45 -62q0 -18 -11.5 -35.5t-27.5 -17.5q-152 5 -278 5t-224 -5h-4q-15 0 -24 16 q-11 17 -11 37q0 14 6 31q13 26 52 26h3q57 0 70.5 28t13.5 151v393v14q0 12 -12 19h-94q-37 0 -43 22z" /> -<glyph unicode="g" horiz-adv-x="995" d="M47 -272q0 84 41 132t123 99q6 4 8 9t-2 7q-133 55 -133 160q0 8 2 16.5t6 15.5t8 12t12.5 12.5t13.5 11.5t15.5 9t14.5 8t14 8t12 8q39 20 58 32l-4 13q-137 88 -138 247q0 150 104.5 250.5t254.5 100.5q137 0 221 -84h6q43 0 178 22q33 4 47.5 -3t16.5 -38 q6 -106 6 -108q-10 -43 -41 -43q-10 0 -52 5t-55 5q-8 2 -8 -14q10 -33 10 -76q0 -143 -102 -233.5t-256 -90.5q-43 0 -76 8q-6 -8 -14 -15t-18.5 -15.5t-16.5 -12.5q-26 -22 -26 -35q0 -12 20 -18q51 -14 203 -14q55 0 83.5 -1t83 -6.5t86 -14.5t72.5 -27.5t62.5 -44 t38 -66.5t16.5 -92q0 -162 -164 -270.5t-387 -108.5q-119 0 -231.5 65.5t-112.5 174.5zM240 -219q-2 -61 74.5 -105.5t187.5 -44.5q94 0 184 60t90 123q0 57 -41 84.5t-160 35.5q-45 4 -114.5 4.5t-104.5 2.5q-8 -10 -27.5 -27.5t-25.5 -26.5q-63 -63 -63 -106zM291 569 q0 -113 46 -175t111.5 -62t106.5 51t41 149q0 106 -48 172t-116 66q-59 0 -100 -55.5t-41 -145.5z" /> -<glyph unicode="h" horiz-adv-x="1077" d="M28 1358q0 37 27 47q115 47 260 88q13 4 24 4q42 0 42 -59v-602q0 -2 1 -7.5t2 -12.5t4 -11t5 -2q139 88 269 88q186 0 233 -156q29 -84 29 -227q0 -59 -6.5 -179t-6.5 -182q0 -27 15.5 -31.5t87.5 -4.5q31 0 39 -13.5t12 -46.5v-7q1 -16 -7 -30q-10 -18 -26 -18 q-75 -1 -161 -1h-89q-137 1 -176 1q-45 0 -55 53q0 57 41 57h10q63 0 78.5 12.5t21.5 59.5q14 121 15 271q0 127 -10.5 176t-36.5 77q-41 45 -107 46q-20 0 -37.5 -3.5t-37 -12.5t-28.5 -13t-34 -19.5t-31 -19.5q-14 -8 -14 -68v-413q2 -68 15.5 -81.5t68.5 -13.5 q47 0 51 -36v-11.5v-13.5v-10q0 -40 -35 -40q-5 0 -10 1q-26 1 -75.5 1t-124 -1t-126 -1t-79.5 1h-2q-19 0 -33 31q-8 16 -8 32q0 17 10 33q4 8 33 14q4 0 13 1t13 1q55 4 68.5 30t13.5 147v911l-2 74q0 27 -31 32q-12 2 -38.5 5.5t-41.5 5.5q-33 2 -33 47z" /> -<glyph unicode="i" horiz-adv-x="559" d="M37 45v10q0 45 35 47q98 8 110 31q8 12 11 45v90v357q0 66 -7 77l-30 11q-39 8 -80 22q-25 10 -25 43t19 45q147 55 243 86q18 6 32 6q46 0 46 -69v-578q0 -74 2 -100q2 -43 11.5 -51t60.5 -8q4 0 8 1q43 0 49 -42v-37q0 -37 -42 -37h-9q-47 3 -145 3t-248 -3 q-31 0 -41 51zM145 1237q0 51 35 85t86 34q53 0 87 -34t34 -87q0 -49 -36 -81t-87 -32q-53 0 -86 33t-33 82z" /> -<glyph unicode="j" horiz-adv-x="512" d="M-223 -362q0 47 25.5 86.5t66.5 39.5t98 -67q45 -55 99 -55q51 0 77.5 47t26.5 170v125v643q0 63 -7 74.5t-52 21.5q-12 4 -34 8t-26 6q-27 10 -24.5 46t20.5 44q94 41 250 93q37 14 53.5 -9.5t16.5 -50.5v-801q0 -137 -7 -198.5t-34 -124.5q-27 -68 -86 -133 q-94 -102 -248 -103q-90 0 -152.5 37t-62.5 101zM117 1217q0 49 35.5 82.5t87.5 33.5q53 0 86.5 -33.5t33.5 -82.5q0 -51 -34.5 -85t-85.5 -34q-53 0 -88 33.5t-35 85.5z" /> -<glyph unicode="k" horiz-adv-x="1060" d="M18 1362q2 20 27 31q76 27 238 86q17 6 30 6q42 0 41 -62v-805q4 -31 8 -30l211 153q25 16 31 23q10 10 -10 14h-6h-35q-47 6 -47 49v7q4 47 49 47q53 -1 112 -1q118 0 259 3q23 0 33 -17.5t10 -36.5q0 -16 -10.5 -35.5t-22.5 -19.5q-119 -2 -236 -88q-80 -61 -200 -143 q-4 -10 0 -15q301 -307 362 -366q35 -37 57.5 -49.5t65.5 -12.5h25q22 -10 28 -36q2 -9 2 -18q0 -16 -7 -30q-11 -22 -29 -22q-89 5 -197.5 5t-235.5 -5q-23 0 -30 16q-8 14 -9 51q0 23 11.5 31t40.5 8q27 0 35 5.5t1.5 15.5t-28.5 33l-223 237q-10 10 -13.5 7t0.5 -17h-2 q0 -115 2 -182q0 -59 4 -72q10 -25 48 -25h53q31 0 31 -55q0 -53 -33 -53q-148 3 -247.5 3t-152.5 -3q-23 0 -30 16q-10 20 -10 40q0 16 6 32q12 23 49 22q59 0 70.5 25t11.5 154v878q0 49 -2 74q0 31 -9.5 39t-44.5 16q-2 0 -22.5 5t-26.5 5q-34 8 -34 46q0 8 1 16z" /> -<glyph unicode="l" horiz-adv-x="550" d="M35 27q-3 10 -3 21q0 12 3 24q6 24 24 30q6 2 15 2h14h12q55 0 70 16q16 18 16 93v1038q0 23 -14 25l-98 18q-29 6 -31 42t27 46q150 57 264 93q6 1 10 1q19 0 30 -12q13 -16 13 -53v-1196q0 -80 10.5 -95.5t67.5 -15.5q51 0 57 -28v-29q0 -51 -39 -51q-148 2 -249 2 t-156 -2q-10 0 -25.5 8t-17.5 23z" /> -<glyph unicode="m" horiz-adv-x="1669" d="M25 51q2 25 10 37q6 6 24 10q20 4 33 4q55 2 69.5 29t14.5 148v278v56.5v40t-1 23.5t-1 13v4q-8 12 -65 21l-48 6q-31 4 -31 36q0 15 7 36q4 14 18 20q78 37 269 86q9 2 16 2q41 0 41 -57v-80q0 -14 12 -6q180 121 309 121q156 0 209 -142q0 -2 9 2q66 47 101.5 69.5 t99 46.5t120.5 24q150 0 209 -129q31 -74 31 -281q0 -53 -4 -155.5t-4 -153.5q0 -37 16 -45.5t94 -8.5q39 0 51 -8q16 -10 16 -45q0 -9 -1 -20q0 -39 -39 -39q-56 2 -168 2t-279 -2q-27 0 -37 16q-6 8 -8 33t6 39q2 4 6.5 8t6.5 5t7 2t7 1h9h11q57 0 74 14.5t21 67.5 q6 80 6 273q0 180 -25.5 233t-93.5 53q-63 0 -223 -104v-440q0 -63 15.5 -80t72.5 -17q43 0 47 -49q0 -55 -39 -55q-171 3 -300 3q-65 0 -120 -1q-25 0 -36 25.5t0.5 52t41.5 26.5h15q68 0 84 26t16 153v317q0 70 -30.5 106.5t-82.5 36.5q-78 0 -233 -104v-440 q0 -66 15.5 -81.5t80.5 -15.5q2 0 33 -4q14 -2 14 -65q-6 -35 -32 -35q-98 4 -203 4t-219 -4q-31 0 -39 18q-6 11 -6 29v10z" /> -<glyph unicode="n" horiz-adv-x="1062" d="M33 45q0 25 2 33q14 20 35 20h10q59 0 76.5 29t17.5 154v268q0 131 -6 149q-6 8 -64 19l-41 8q-31 8 -26.5 47t24.5 47q84 27 177 64q47 16 63 20q16 3 28 3q17 0 27 -7q16 -12 17 -49v-86q0 -14 2 -16.5t12 4.5q188 127 293 127q244 0 244 -373q0 -59 -8.5 -177 t-8.5 -177q0 -33 12.5 -41.5t61.5 -8.5q33 10 55 -14q8 -10 8 -35v-10q-2 -33 -22 -43q-8 -4 -31 -4q-49 0 -187 1h-83q-73 0 -109 -1q-31 -2 -40 7t-11 36q0 63 35 63h12q59 4 78 21.5t25 69.5q12 113 12 342q0 196 -124 196h-1q-80 0 -225 -104v-432q0 -66 15 -79.5 t85 -13.5q31 0 37 -36q0 -41 -6 -54q-6 -14 -41 -18q-30 1 -78.5 1t-116.5 -1q-46 -1 -83 -1q-74 0 -113 3q-29 2 -35 16q-4 8 -4 33z" /> -<glyph unicode="o" horiz-adv-x="1028" d="M41 426q0 195 136 325t337 130q203 0 341 -131.5t138 -325.5q0 -190 -137 -322.5t-336 -132.5q-203 0 -341 132t-138 325zM262 485q0 -172 84 -286.5t199 -114.5q92 0 156.5 88t64.5 221q0 162 -83 268.5t-198 106.5q-94 0 -158.5 -80t-64.5 -203z" /> -<glyph unicode="p" horiz-adv-x="1036" d="M20 -475q10 16 41 16q70 0 88.5 31t18.5 170v825v47q0 27 -5 34t-30 14q-12 4 -35.5 12t-34.5 10q-27 6 -30.5 38t12.5 46q2 4 8 10l228 137q18 14 44 14q6 0 13 -1q33 -4 33 -47v-107q0 -26 12 -18q163 114 264 114h2q137 0 237.5 -127t100.5 -290q0 -197 -140 -345.5 t-327 -148.5q-55 0 -133 23q-6 2 -11 -3.5t-5 -17.5v-219q0 -100 8 -138t26.5 -47.5t69.5 -9.5h29q45 0 55 -30q4 -12 4 -34t-6 -34q-12 -20 -47 -20q-47 2 -449 2q-29 0 -41 18q-12 17 -12 36t12 40zM371 184q102 -96 204 -96q86 0 145.5 84t59.5 213q0 145 -66.5 234.5 t-164.5 89.5q-70 0 -172 -80q-6 -6 -6 -21v-424z" /> -<glyph unicode="q" horiz-adv-x="1038" d="M59 391q0 203 132.5 342t326.5 139q94 0 221 -65q6 -4 13 -8q6 -4 14 6q2 4 4 6q39 47 47 55q7 8 31 8h10q33 -2 47 -24q-16 -57 -16 -152v-88v-864q0 -135 16.5 -168t67.5 -33h20q29 0 36 -37q2 -11 2 -21q0 -23 -11 -42q-6 -12 -43 -12q-113 4 -224 4t-221 -4 q-59 0 -59 51q0 20 1 26.5t7 17.5t23 17q14 2 84 2q68 0 84 29t16 170v289q-4 29 -6 29.5t-8 -3.5q-135 -104 -256 -104q-156 0 -257.5 125t-101.5 309zM256 446q0 -150 72.5 -246t177.5 -96q78 0 178 84q6 12 6 52q0 283 -4 338q-2 31 -14 63q-18 55 -66.5 89t-109.5 34 q-109 0 -174.5 -83t-65.5 -235z" /> -<glyph unicode="r" horiz-adv-x="743" d="M45 47q0 20 2 29.5t12.5 16.5t32.5 7q57 0 74.5 28t17.5 151v352q0 29 -6 33q-12 6 -47 18t-49 18q-25 12 -29 21q-2 4 -2 10v29q0 31 29 41q33 16 62.5 27.5t80.5 27.5t92 33q14 5 25 5q14 0 24 -8q18 -14 17 -38q2 -29 2 -117q2 2 16.5 39t26.5 58.5t27 29.5 q29 14 58.5 15t50 -5t53 -17t53.5 -15l18 -7q34 -11 34 -35q0 -7 -3 -14q-19 -55 -66 -141q-45 4 -94 29q-41 20 -61 20q-49 0 -109 -108v-287q0 -18 1 -45t1 -53q4 -68 16.5 -80.5t77.5 -12.5h43q35 0 40 -43t-15 -59q-8 -6 -27 -6q-47 0 -135 2t-160.5 2t-138.5 -4h-6 q-24 0 -31 14q-8 16 -8 39z" /> -<glyph unicode="s" horiz-adv-x="669" d="M68 633q0 115 84 186.5t206 71.5q82 0 187 -43q7 -74 7 -136q0 -42 -3 -79q-2 -10 -17.5 -20.5t-31.5 -10.5q-43 0 -45 27q-29 147 -127 147q-39 0 -63.5 -23.5t-24.5 -58.5q0 -29 26.5 -60.5t52 -50t73.5 -48t54 -33.5q168 -117 168 -254q0 -111 -84.5 -189.5 t-199.5 -78.5q-72 0 -125 22l-12 4q-2 -2 -11 -20q-30 -12 -45 -12q-3 0 -6 1q-37 8 -39 39q-12 156 -16 224q-2 20 18.5 30.5t48.5 5.5q23 -8 29 -34q37 -158 152 -158q43 0 72.5 30.5t29.5 73.5q0 70 -109 148q-10 8 -54 36.5t-60.5 41t-49 42t-47 52t-26.5 56.5t-12 71z " /> -<glyph unicode="t" horiz-adv-x="659" d="M41 797q10 18 27 24q98 49 170 246q6 31 51 31q43 0 43 -34l-3 -108q0 -45 3 -75q0 -2 4 -3t8 -2.5t6 -1.5h199q20 0 36.5 -14t8.5 -43q-8 -37 -21 -69q-14 -27 -51 -27l-170 4q-20 0 -20 -33v-319q0 -150 22.5 -195t77.5 -45q51 0 100 92q14 25 40 22t40 -18 q11 -14 11 -32q0 -12 -5 -27q-85 -193 -249 -193q-104 0 -169 76t-65 193v80v368q0 25 -10 27q-23 2 -72 8q-16 27 -16 48q0 11 4 20z" /> -<glyph unicode="u" horiz-adv-x="1093" d="M44 780q-4 9 -4 19.5t4 20.5q7 22 34 28q25 6 110.5 30.5t126.5 32.5q29 6 43.5 -12t14.5 -39v-481q0 -152 30.5 -197t118.5 -45q82 0 203 92q0 2 2 7.5t3 9.5t1 8v336v45q0 102 -49 113q-20 4 -58 10t-57 8q-23 12 -22.5 48t28.5 42q227 49 295 57h8q55 0 56 -51v-626 v-62q0 -18 11 -24.5t19.5 -4.5t28.5 7q6 2 20.5 6t20.5 6q27 4 39 -20q8 -15 8 -31q0 -9 -3 -19q-7 -28 -29 -33q-117 -50 -230 -73q-18 -4 -32 -4q-51 0 -52 51q0 2 -1 12t-2 28.5t-1 28.5q0 18 -18 5q-59 -41 -92 -62.5t-91.5 -44t-111.5 -22.5q-125 0 -186.5 77.5 t-61.5 212.5v416q0 27 -5 36t-24 15q-14 4 -40.5 11.5t-39.5 11.5q-8 2 -15 20z" /> -<glyph unicode="v" horiz-adv-x="1048" d="M14 792q-2 8 -2 14q0 20 13 36q6 16 20 16q6 1 36 1q45 0 142 -2q69 -1 124 -1q73 0 120 2q14 0 23.5 -16.5t9.5 -35t-10.5 -34.5t-26.5 -16h-19q-53 0 -65 -4t-12 -17q0 -18 79.5 -207.5t110.5 -257.5q4 -10 8 -12t6 3t7 15q6 14 75.5 179.5t98.5 226.5q6 25 -0.5 40 t-34 22.5t-44 9.5t-30.5 2q-27 0 -33 18q-12 29 -2 62q6 22 29 22h2q81 -2 170 -2t186 2q37 0 37 -51q-4 -45 -31 -49q-55 -6 -81.5 -38t-79.5 -155l-246 -551q-18 -33 -35 -34q-7 -1 -21 -1h-16q-28 1 -37 5q-16 6 -32 39l-260 583q-10 23 -22.5 51.5t-16.5 36.5t-8.5 15.5 t-9.5 13.5t-8 10t-10 7t-10.5 5.5t-12.5 3.5t-12 2t-15.5 3t-16.5 2q-31 6 -37 36z" /> -<glyph unicode="w" horiz-adv-x="1574" d="M18 788q-2 10 -2 18q0 20 9 32q12 18 38 14q332 0 375 2q31 0 41 -33q8 -16 1 -40.5t-29 -26.5q-78 -2 -78 -24.5t178 -455.5q10 -25 22 0l154 357q-35 70 -55 90q-31 29 -74 29q-12 2 -26.5 2t-24.5 16t-10 33q-2 18 6 35.5t24 17.5q194 -5 297 -5q77 0 103 3l12 2h7 q38 0 43 -42q1 -8 1 -15q0 -34 -20 -45q-92 -2 -92 -29q0 -20 28 -88l154 -356q8 -25 18 2q35 80 74 176q82 193 88 227q6 29 -5 44t-26.5 18.5t-46.5 5.5h-47q-20 6 -21 54t29 48q72 -2 158.5 -2t187.5 2q4 1 8 1q23 1 31 -21q6 -14 6 -28q0 -12 -4 -24q-8 -28 -26 -30 q-68 -4 -88 -31q-10 -14 -39 -84q-117 -272 -264 -635q-6 -16 -37 -20q-27 -4 -52 2q-33 2 -45 28l-194 463q-12 25 -21 6q-43 -88 -115.5 -262t-88.5 -211q-10 -27 -33 -31q-12 -4 -28.5 -4t-35.5 4q-23 6 -37 37l-245 586q-45 104 -67.5 126t-90.5 26q-19 2 -25 36z" /> -<glyph unicode="x" horiz-adv-x="1097" d="M18 43q0 51 37 51q68 2 105 23.5t114 111.5l154 172q10 12 -2 27l-143 188q-72 92 -105 115t-112 25q-23 6 -22 53q1 45 33 45h3q53 -3 149.5 -3t237.5 3h8q29 0 37 -23.5t-1 -48t-24 -24.5h-18q-43 0 -45 -10q0 -6 4 -13q20 -33 69.5 -97.5t67.5 -82.5q4 -6 25 14 q117 117 117 162q0 8 -3.5 12.5t-19.5 8.5t-47 4q-4 0 -9 1t-7.5 1t-5.5 2t-6 6t-7 12q-4 10 -4 47q5 30 31 30q5 0 10 -1q148 -2 242.5 -2t134.5 2q4 1 9 1q24 0 36 -21q12 -20 4 -49t-41 -29h-13q-70 0 -107 -20q-40 -22 -101 -91l-78 -82l-76 -84q-6 -8 -2 -12 q41 -49 74 -92t50 -65.5t28 -35.5l71 -92q39 -49 73 -65.5t97 -20.5q31 -4 31 -57q0 -16 -1 -22.5t-10.5 -13.5t-29.5 -7q-89 2 -172 2q-125 0 -237 -4q-41 0 -41 49t36 49h17q49 0 49 10q0 6 -9 19.5t-22.5 28t-15.5 18.5l-111 147q-12 18 -18 13q-2 -2 -50 -54.5 t-82 -93.5t-34 -53q0 -16 15.5 -23.5t68.5 -11.5h16q35 -4 35 -51q0 -25 -9 -37q-8 -10 -23 -10h-5q-73 5 -187 5q-86 0 -194 -3q-16 0 -24 7t-10.5 13.5t-4.5 26.5z" /> -<glyph unicode="y" horiz-adv-x="1005" d="M20 786q-5 12 -5 24t5 24q11 24 43 24h27h336q35 0 45 -23.5t1 -49t-28 -29.5q-43 0 -61 -6q-10 -2 -14 -9.5t-3 -18.5t4 -18.5t9 -20.5t6 -15q29 -61 55.5 -127t57 -150t49.5 -129q8 -20 22 17l101 272q47 121 47 156q0 29 -17.5 39t-83.5 10q-18 12 -22 52t29 48h20 q61 0 155.5 1t145.5 1q35 0 46 -30q5 -14 5 -26q0 -15 -8 -28q-6 -12 -26 -18q-53 -4 -87 -47t-92 -197l-243 -664q-43 -115 -84 -213q-33 -72 -76 -127q-39 -49 -117 -49q-45 0 -81 36t-36 81q0 70 117 105q27 6 50.5 20t39 25.5t29.5 37t21.5 37t16.5 47t11 45t10.5 50.5 t8.5 47l-246 592q-51 125 -72.5 147.5t-85.5 28.5q-16 4 -25 28z" /> -<glyph unicode="z" horiz-adv-x="839" d="M22 28q-2 10 -3 18q0 19 12 32l10 10l461 617q12 16 0 16q-43 0 -126 -3t-128 -3q-33 0 -49.5 -26.5t-44.5 -141.5q-6 -10 -21 -17h-4q-16 0 -26.5 1t-25 4.5t-20.5 11.5t-4 20q0 6 2 11q31 195 56 294q4 23 14 25q2 2 6 2q15 8 37 8q7 0 14 -1q31 -3 31 -23.5t10 -25.5 t53 -5q250 4 370 5q40 0 65 -1q4 0 20.5 1t22.5 0t17 -5t20 -14q5 -17 5 -32q0 -22 -12 -36q-137 -176 -454 -623q-6 -10 -3 -12t17 -2q52 -1 120.5 -1t153.5 1q39 2 50.5 17.5t50.5 105.5q4 6 6 12t4 7t12 4q13 2 25 2q27 0 43 -13q9 -9 9 -19q0 -6 -3 -11l-80 -213 q-10 -18 -43 -29h-649q-13 0 -21 32z" /> -<glyph unicode="{" horiz-adv-x="1026" d="M205 455q-6 16 0 34q2 27 28 35q94 18 145.5 69.5t51.5 113.5q0 39 -22 145q-23 90 -23 172q0 164 112.5 285t288.5 147q29 0 37 -26q4 -14 4 -58q-2 -10 -8 -14t-16 -5t-12 -1q-199 -43 -199 -211q0 -55 18 -146q23 -117 23 -180q0 -145 -117 -258q-53 -53 -115 -84 q-6 0 2 -4q229 -123 230 -340q0 -66 -21 -178q-18 -84 -18 -144q0 -160 201 -217q27 -4 34 -26q8 -26 -2 -53q-10 -20 -21 -22.5t-22 1.5q-176 29 -286.5 148.5t-110.5 281.5q0 68 23 164q23 117 22 149q0 68 -51 117t-152 70q-20 8 -24 35z" /> -<glyph unicode="|" horiz-adv-x="1093" d="M473 31v1659q0 27 2 40t14.5 22t34.5 9q37 -8 58 -4q16 0 26 -2t14.5 -8t5.5 -10t0 -18.5t-1 -18.5v-836q0 -752 -2 -844v-8q0 -23 -1 -32t-10.5 -17t-29.5 -8q-27 4 -60 0q-51 0 -51 76z" /> -<glyph unicode="}" horiz-adv-x="1026" d="M207 -463q0 2 1 10.5t1 12.5q8 31 31 34q201 43 200 209q0 55 -21.5 163t-21.5 163q0 141 117 258q55 55 117 86q2 0 -2 4q-231 123 -232 338q0 51 20.5 158.5t20.5 163.5q0 123 -116 180q-12 6 -40 18.5t-40 18.5q-25 12 -31 22t-4 33q0 18 11 33.5t30 13.5 q176 -29 287.5 -148.5t111.5 -281.5q0 -53 -23.5 -156.5t-23.5 -156.5q0 -63 47 -111.5t137 -71.5q43 -12 43 -53q0 -51 -41 -59q-88 -18 -136 -67.5t-48 -110.5q0 -53 23.5 -158t23.5 -160q0 -158 -105.5 -276.5t-273.5 -151.5q-31 -6 -50 3t-13 40z" /> -<glyph unicode="~" horiz-adv-x="1161" d="M39 537q8 135 95 224t214 89q117 0 285 -86q160 -82 231 -82q59 0 93 28.5t42.5 62.5t22.5 60.5t41 24.5l22 -2q18 -2 33 -13.5t12 -29.5q-10 -137 -94 -228t-209 -91q-119 0 -299 88l-51 25.5t-64.5 30.5t-56 19.5t-59.5 10.5q-57 0 -99 -38t-51 -106q-4 -29 -31.5 -36 t-52 8.5t-24.5 40.5z" /> -<glyph unicode="¡" horiz-adv-x="557" d="M158 758q0 51 34.5 86t88 35t86 -34t32.5 -87t-32.5 -85t-86 -32t-88 32t-34.5 85zM164 -406l69 924q10 25 46 25t47 -25l73 -926q6 -53 -11.5 -77.5t-74.5 -24.5h-59q-61 0 -77.5 25.5t-12.5 78.5z" /> -<glyph unicode="¢" horiz-adv-x="915" d="M88 389q0 211 147.5 358.5t356.5 147.5q6 0 16 -1t15 -1q14 0 18 14l86 226q10 20 17.5 25t25.5 3q10 0 31.5 -9t25.5 -13q12 -12 2 -41l-88 -221q-2 -4 2 -9q113 -45 113 -127q0 -41 -27.5 -67.5t-70.5 -26.5q-45 0 -88 37q-2 2 -4 -6q-2 -2 -2 -4l-215 -537 q-10 -31 98 -31q68 0 116 31t103 99q10 12 19.5 16t17.5 2t17 -7t20 -11q37 -23 2 -70q-143 -211 -369 -211q-43 0 -88 10q-2 0 -12 -20q-86 -227 -109 -279q-16 -35 -23.5 -41t-23.5 -2q-4 0 -16.5 5t-22.5 7q-35 6 -16 56l119 299q6 14 -2 18q-88 57 -139.5 159.5 t-51.5 221.5zM289 434q0 -131 65 -221q8 -18 13 -2l213 534q2 16 -7 21q-18 8 -49 8q-90 0 -162.5 -98t-72.5 -242z" /> -<glyph unicode="£" horiz-adv-x="1630" d="M20 -395q0 63 78 136t176 116q59 109 105 225q8 23 10 29l2 2h-233h-17q-8 0 -24 4q-29 12 -13 67q8 45 60 45h270q23 57 72 194.5t77.5 213.5t78 184.5t100.5 194.5q246 416 555 416q109 0 195.5 -51.5t86.5 -133.5q0 -41 -29.5 -68.5t-72.5 -27.5q-51 0 -102 51 q-12 8 -29 29q-61 61 -129 61q-76 0 -145 -88q-78 -106 -162 -315q-176 -438 -275 -651l-6 -11l2 2h2q49 0 144.5 1t144.5 1q51 0 39 -55q-8 -37 -22.5 -52t-51.5 -15l-313 4q-45 -89 -111 -183q59 16 138 17q160 0 337 -133q102 -74 132 -90q68 -39 129 -39 q66 0 109.5 37.5t43.5 84.5q0 27 -28.5 78.5t-28.5 81.5q0 45 29.5 75t74.5 30q59 0 93 -51.5t34 -120.5q0 -150 -131 -265.5t-293 -115.5q-125 0 -225 65q-31 20 -109.5 86t-144 105t-125.5 39q-57 0 -143 -39q-57 -111 -128 -182.5t-136 -71.5q-35 0 -63 23.5t-28 60.5z " /> -<glyph unicode="¥" horiz-adv-x="1071" d="M-14 1405q-2 20 11 28.5t30 8.5q231 -8 432 2q43 2 43 -37q0 -8 2 -25.5t0 -27.5v2q-2 -18 -29 -27q-98 0 -98 -29q0 -4 16 -47l53 -127q2 -6 33 -6h226q14 0 18 10q63 154 63 170q0 25 -55 29q-4 0 -15 1t-16.5 3t-13.5 5t-11 9.5t-3 16.5v33q0 39 35 39q39 0 109.5 -2 t123.5 -1t109 5q18 2 30.5 -8.5t12.5 -22.5v-37q0 -41 -39 -41q-49 0 -77 -23.5t-65 -111.5q-27 -51 -30 -74h6h151q16 0 24.5 -10t8.5 -15v-24v-41q0 -20 -1 -27.5t-8 -15.5t-24 -8h-207q-10 0 -14 -8l-55 -123q-4 -4 -1 -8t7 -4l276 4q27 -8 27 -47v-50q0 -49 -43 -49 l-297 2q-41 0 -47 -18l-29 -62v-344q0 -117 18.5 -141.5t84.5 -24.5h22q51 0 51 -45v-28q0 -20 -8 -29.5t-18 -11.5t-29 0q-250 14 -487 0q-18 -2 -32.5 9t-12.5 34q0 4 1 18.5t3 20.5t6 15t13 13t24 4h16q78 0 95.5 24t17.5 142v324l-43 92q-4 8 -23 8h-309q-37 0 -37 54 v47q0 27 7.5 35t33.5 8q197 -4 221 -4h43l-53 127q-6 16 -12 16h-209q-18 0 -24.5 9t-6.5 38v47q0 27 7.5 37t29.5 10h143q4 4 4.5 11.5t-7 23.5t-10.5 25.5t-7 15.5q-37 74 -64 100q-16 18 -36.5 25.5t-36 7.5t-27.5 8.5t-16 26.5q-6 12 -2 41zM512 973l66 -168q4 -18 10 0 l65 166q0 8 -8 8h-127q-6 0 -6 -6z" /> -<glyph unicode="¦" horiz-adv-x="1093" d="M473 -45v803h154v-803h-154zM473 956v805h154v-805h-154z" /> -<glyph unicode="§" horiz-adv-x="1005" d="M98 872q0 227 146.5 393.5t351.5 166.5q43 0 106.5 -14.5t126 -56.5t62.5 -99q0 -43 -33 -76t-76 -33q-45 0 -102 53q-4 4 -9 8.5t-10.5 10.5t-7.5 8q-61 70 -118 70q-66 0 -112 -41t-46 -99q0 -16 7 -39.5t22.5 -52.5t29 -52.5t36 -57t34.5 -51t34.5 -49.5t26.5 -36 q166 -236 229.5 -348t94.5 -227q23 -88 22 -201q0 -215 -149 -374.5t-352 -159.5q-104 0 -194.5 46t-90.5 120q0 39 28.5 73.5t71.5 34.5q12 0 22.5 -2t20 -8t15.5 -9t16 -14.5t13 -14.5t14.5 -16.5t13.5 -15.5q63 -70 137 -69q61 0 109.5 42t48.5 89q0 76 -113 233 q-199 276 -305 467q-121 211 -121 401zM266 1055q-76 -211 56 -465q55 -111 184 -301.5t178 -278.5q47 -86 61 -123q23 59 23 142q0 223 -150 450q-33 49 -113.5 170t-121.5 189q-25 37 -72 117.5t-45 99.5z" /> -<glyph unicode="¨" horiz-adv-x="712" d="M49 1108q0 51 38 87t95 36q55 0 93 -36t38 -87q0 -53 -36.5 -88t-94 -35t-95.5 35t-38 88zM401 1108q0 51 38 87t93 36q57 0 94.5 -36t37.5 -87t-37.5 -87t-94.5 -36q-55 0 -93 36t-38 87z" /> -<glyph unicode="©" horiz-adv-x="1630" d="M72 713q0 305 220 522t527 217t527.5 -216t220.5 -523q0 -305 -220.5 -522.5t-527.5 -217.5t-527 217.5t-220 522.5zM203 713q0 -254 181 -434.5t435 -180.5t435.5 180.5t181.5 434.5q0 256 -180.5 435t-436.5 179t-436 -179t-180 -435zM336 715q0 203 146.5 337 t361.5 134q76 0 184 -37q16 -6 27 -6q6 0 22 43h53q35 0 41 -39q0 -6 7.5 -101.5t9.5 -138.5q2 0 0 -10v-8q-4 -31 -27 -31h-39q-25 0 -35 23q-2 4 -4 13t-4 13q-68 174 -248 174q-125 0 -199.5 -89t-74.5 -249q0 -176 75 -267t210 -91q92 0 146 29.5t124 107.5 q6 8 13.5 12.5t17.5 1t13 -4.5t15 -7l15 -8q37 -20 8 -57q-149 -195 -385 -195q-201 0 -337 129t-136 322z" /> -<glyph unicode="ª" horiz-adv-x="557" d="M37 954q0 102 156 138q66 16 114 38v78q0 80 -63 80q-16 0 -37 -16q-14 -14 -10 -31q0 -2 2 -5t3 -8t3 -11l-117 -52q-25 -12 -33 13q-10 29 -10 36q0 53 92 117q70 49 135 49q98 0 144.5 -47t46.5 -147v-158v-53q0 -31 4 -31q10 0 53 27q18 12 30.5 -7.5t14.5 -39.5 q4 -12 -10 -27q-98 -74 -149 -74q-53 0 -76 39q-9 10 -15 6q-61 -45 -129 -45q-63 0 -106 36t-43 95zM186 965q0 -39 45 -39q18 0 47 20.5t29 32.5v63h-4q-4 -2 -12 -4t-17 -6q-59 -23 -73.5 -36t-14.5 -31z" /> -<glyph unicode="«" horiz-adv-x="759" d="M68 446q-23 31 8 68l280 346l9 10q6 8 16 9h53q43 0 29 -29l-195 -375l187 -364q23 -45 -19 -45h-45q-20 0 -39 24zM352 453q-16 23 13 63l213 303l8 15q6 10 26 10h47q35 0 21 -37l-125 -332l123 -332q14 -45 -23 -45h-51q-10 0 -24 23z" /> -<glyph unicode="¬" horiz-adv-x="1429" d="M135 848v170h1165v-645h-176v475h-989z" /> -<glyph unicode="­" horiz-adv-x="890" d="M82 446v58q0 23 20.5 33t38.5 10h629q20 0 35.5 -13.5t13.5 -29.5l-4 -53q-8 -33 -41 -37q-309 -4 -651 0q-29 0 -41 32z" /> -<glyph unicode="®" horiz-adv-x="1630" d="M53 713q0 313 221.5 534t536.5 221q313 0 535.5 -221t222.5 -534q0 -311 -222.5 -532.5t-535.5 -221.5q-315 0 -536.5 221t-221.5 533zM182 713q0 -260 184.5 -443.5t444.5 -183.5q262 0 446.5 183.5t184.5 443.5t-184.5 443t-446.5 183q-260 0 -444.5 -183t-184.5 -443z M399 297v31q0 35 35 34q43 2 55.5 18.5t12.5 82.5v508q0 70 -8.5 84t-42.5 16q-39 0 -39 37v27q0 33 49 32q84 -6 356 0q139 0 229.5 -67.5t90.5 -179.5q0 -160 -179 -228q-16 -6 -17 -9t9 -17l170 -232q31 -43 48.5 -56t43.5 -16q31 -4 31 -24v-29q0 -45 -55 -45 q-74 4 -133 0q-39 0 -56 23l-272 370h-10q-12 0 -12 -4v-20v-172v-72q0 -14 11 -18t35.5 -5t34.5 -4q4 0 10.5 -1t9.5 -2t7 -3t5 -7t1 -11v-47q0 -27 -41 -27q-184 12 -338 0q-41 0 -41 33zM705 793q0 -31 14 -31q98 2 148.5 42t50.5 103q0 66 -46 110t-118 44q-31 0 -49 -6 v-262z" /> -<glyph unicode="¯" horiz-adv-x="714" d="M14 1071v72q0 35 58 35h18h557q27 0 39 -8.5t12 -34.5v-70q0 -41 -57 -41h-578q-23 0 -34 8t-13 16.5t-2 22.5z" /> -<glyph unicode="°" horiz-adv-x="849" d="M88 1053q0 139 98.5 236t239.5 97t240.5 -97t99.5 -236q0 -137 -99.5 -234.5t-240.5 -97.5t-239.5 97t-98.5 235zM238 1053q0 -76 55 -130.5t133 -54.5t134 54.5t56 130.5q0 78 -56 132t-134 54t-133 -54.5t-55 -131.5z" /> -<glyph unicode="±" horiz-adv-x="1429" d="M135 846v74q0 33 17.5 42t58.5 9h391q27 0 27 33v370q0 6 -1 13.5t-1 11.5q0 68 49 67h74q29 0 42 -14t13 -51v-404q4 -27 35 -26h397q63 0 63 -56v-61q0 -27 -11 -40t-23 -15t-35 -2h-381q-16 0 -30.5 -8.5t-14.5 -16.5v-405q0 -39 -9.5 -50.5t-45.5 -11.5h-64 q-37 2 -47 15.5t-10 46.5v401q0 29 -25 29h-405q-27 0 -36 1t-18.5 12t-9.5 36zM137 33v53q0 20 3 32.5t17.5 23t41.5 8.5h303.5h433h303.5q61 -2 61 -62v-51q0 -43 -12 -53.5t-51 -10.5q-651 4 -1024 -2q-33 0 -45 2t-21.5 15.5t-9.5 44.5z" /> -<glyph unicode="²" horiz-adv-x="614" d="M8 653v35q51 63 168 162q61 49 88 71.5t67 76t40 98.5q0 37 -30 62.5t-73 25.5q-98 0 -139 -115q-8 -16 -57 -16t-52 28q10 111 88 176.5t191 65.5q109 0 184.5 -59.5t75.5 -153.5q0 -47 -14.5 -85t-55 -75t-57 -49t-76.5 -53q-53 -33 -114 -86h151q55 0 62 4 q8 8 11 28.5t10 33t30 12.5h43q35 0 35 -35q-16 -125 -21 -146q-8 -43 -57 -43h-457q-23 0 -32 7.5t-9 29.5z" /> -<glyph unicode="³" horiz-adv-x="614" d="M18 713q0 35 26 56.5t58 21.5q37 0 91.5 -39t82.5 -39q45 0 81 39t36 96q0 41 -22.5 67.5t-51.5 26.5q-31 0 -57 -22q-53 -29 -84 18q-8 16 -3 36.5t20 31.5q70 43 105.5 79.5t35.5 57.5q0 18 -17.5 32.5t-46.5 14.5q-72 0 -120 -88q-35 -41 -74 -13.5t-31 56.5 q84 178 264 178q78 0 136.5 -40t58.5 -109q0 -66 -57 -117q127 -49 126 -183q0 -113 -104 -192.5t-235 -79.5q-78 0 -148 28.5t-70 82.5z" /> -<glyph unicode="´" horiz-adv-x="714" d="M231 1014l97 303q16 37 55 37h168q20 2 36.5 -7.5t12.5 -31.5q0 -13 -20 -33l-263 -303q-14 -20 -55 -10t-31 45z" /> -<glyph unicode="¶" horiz-adv-x="1011" d="M-25 928q0 199 130.5 310.5t357.5 113.5q442 0 477 2q33 2 46 -8.5t13 -40.5v-48q0 -23 -11 -33t-18.5 -11t-25.5 -1h-53q-12 0 -19.5 -11t-7.5 -23v-1635q0 -31 -10 -39t-45 -8h-35q-55 0 -55 45l2 1637q0 31 -21 30h-79q-16 0 -17 -26l2 -1647q0 -41 -53 -41h-45 q-31 0 -41 11.5t-10 37.5v936q0 29 -17 29q-307 6 -415 213q-49 90 -50 207z" /> -<glyph unicode="·" horiz-adv-x="526" d="M141 702.5q0 45.5 37 80t86 34.5q51 0 86 -33.5t35 -81.5q0 -45 -36 -79.5t-85 -34.5t-86 34.5t-37 80z" /> -<glyph unicode="¸" horiz-adv-x="714" d="M203 -252l166 272h100l-63 -114q57 -12 94 -59.5t37 -108.5q0 -82 -58.5 -139.5t-142.5 -57.5q-18 0 -37.5 2t-45.5 10.5t-30 21.5t6 38q0 2 3.5 7t5.5 7q8 12 20 15.5t31.5 -0.5t25.5 -4q31 0 52.5 20t21.5 47q0 49 -33 49q-18 0 -110 -45q-23 -12 -42.5 -3t-0.5 42z " /> -<glyph unicode="¹" horiz-adv-x="614" d="M93 1100.5q-17 29.5 3 52.5q137 84 197 154q6 10 62.5 4t56.5 -23v-551v-12q0 -4 8 -4q4 0 23.5 -2t27.5 0q4 0 11 -1t10.5 -2t8.5 -3t8 -4t5 -7.5t2 -11.5q2 -6 2 -26q0 -18 -10.5 -35t-24.5 -17q-158 6 -311 0q-16 0 -26.5 17.5t-10.5 34.5q0 47 33 51l57 6q18 2 19 14 v381q-43 -23 -101 -43q-33 -2 -50 27.5z" /> -<glyph unicode="º" horiz-adv-x="737" d="M49 1102q0 121 92 199.5t227.5 78.5t227.5 -78.5t92 -199.5q0 -119 -92 -199t-223 -80q-137 0 -230.5 79t-93.5 200zM215 1139q0 -96 52 -160t122 -64q57 0 96 44.5t39 113.5q0 92 -53 154.5t-121 62.5q-57 0 -96 -42t-39 -109z" /> -<glyph unicode="»" horiz-adv-x="759" d="M80 141l127 330l-123 332q-8 14 -3 29.5t23 15.5h46h6q12 0 26 -23l226 -329q16 -23 -11 -64l-213 -305q-2 -4 -6 -10t-5 -7t-5 -4.5t-8 -3.5h-10h-48q-37 0 -22 39zM299 96l195 377l-187 363q-23 45 19 45h45q20 0 39 -25l284 -356q10 -20 6 -38t-16 -30l-278 -346 q-16 -18 -33 -18h-47q-41 0 -27 28z" /> -<glyph unicode="¼" horiz-adv-x="1464" d="M93 1093.5q-17 28.5 3 55.5q145 88 207 160q6 10 64.5 3t58.5 -24v-569q0 -16 10 -17h32t32 -2q37 -10 37 -57q0 -20 -10.5 -36.5t-24.5 -16.5q-166 6 -326 0q-39 0 -39 55q6 49 35 51l64 4q10 0 12 2.5t2 14.5v393q-16 -8 -51 -22.5t-54 -22.5q-35 0 -52 28.5zM184 -41 q-6 29 6 43l953 1327l4 10q12 12 31 13h6h84q18 0 25 -20.5t-7 -43.5l-954 -1333q-16 -25 -45 -25h-66q-31 0 -37 29zM786 211v37l365 461q43 12 74 6q14 -2 26.5 -14.5t10.5 -30.5v-357l16 -8h63q49 0 50 -47q0 -55 -7 -68q-10 -23 -32 -22h-78q-12 -4 -12 -25l2 -133 q0 -18 -2 -26.5t-11.5 -14.5t-27.5 -6h-47q-48 0 -56 2q-25 2 -35 35v141q-2 27 -10 27h-239q-49 0 -50 43zM983 305h88q12 0 14 12l2 111q0 18 -10 4z" /> -<glyph unicode="½" horiz-adv-x="1464" d="M93 1098.5q-17 29.5 3 54.5q133 80 197 156q6 8 62.5 2t56.5 -23v-559v-12q0 -4 8 -4q4 0 23.5 -2t27.5 0q4 0 11 -1t10.5 -2t8.5 -3.5t8 -4.5t5 -7t2 -11q2 -6 2 -27q0 -18 -10.5 -35.5t-24.5 -17.5q-158 6 -311 0q-16 0 -26.5 17.5t-10.5 35.5q0 16 9.5 33t23.5 19 l57 6q18 2 19 14v387q-31 -18 -101 -43q-33 -2 -50 27.5zM182 -40q-8 17 2 32l959 1339q10 12 16 16.5t15.5 5.5t17.5 3q2 0 13.5 -2t21.5 -3t23.5 -4.5t22.5 -8.5t15 -12t6 -16.5t-8 -21.5l-954 -1333q-27 -37 -47 -33q-4 2 -11 2l-57 13q-27 6 -35 23zM850 23v36 q55 68 168 164q2 2 24.5 20.5t29.5 24.5t27.5 23.5t30 28t25.5 28t23.5 30.5t16.5 30.5t13 33t4 31.5q0 37 -29.5 62.5t-74.5 25.5q-96 0 -137 -115q-8 -16 -58.5 -16t-50.5 29q10 113 88 179.5t191 66.5q106 0 183 -60.5t77 -157.5q0 -47 -15.5 -86t-53.5 -75.5t-58.5 -51 t-75.5 -53.5q-47 -31 -117 -86h154q55 0 61 2q4 4 12.5 40t39.5 36h43q35 0 34 -35q-18 -131 -20 -147q-10 -43 -57 -43h-457q-23 0 -32 6t-9 29z" /> -<glyph unicode="¾" horiz-adv-x="1464" d="M25 690q0 35 26.5 57.5t61.5 22.5q39 0 92 -40t84 -40q47 0 84 40t37 97q0 43 -24 71t-54 28q-29 0 -58 -21q-39 -27 -61 -2q-39 33 -22.5 65.5t51 54t70.5 52.5t36 58q0 18 -17.5 32.5t-47.5 14.5q-74 0 -121 -93q-20 -20 -70.5 -2.5t-34.5 52.5q37 86 109 134t158 48 q80 0 141 -42t61 -114q0 -66 -59 -119q127 -51 127 -190q0 -115 -104.5 -197t-239.5 -82q-82 0 -153.5 29t-71.5 86zM181 -26.5q1 6.5 2 8.5t3 8l2 6l7 12l948 1323q29 41 67 25l43 -19q49 -23 27 -57l-948 -1325q-10 -14 -19.5 -22.5t-24 -9.5t-18.5 -1t-26.5 6t-26.5 9 q-10 4 -17 8t-11.5 9t-6.5 9t-1 10.5zM776 211v37l365 461q43 12 73 6q14 -2 26.5 -14.5t10.5 -30.5v-357l17 -8h63q49 0 49 -47q0 -55 -6 -68q-10 -23 -33 -22h-77q-12 -4 -13 -25l2 -133q0 -18 -2 -26.5t-11 -14.5t-28 -6h-47q-47 0 -55 2q-25 2 -35 35v141q-2 27 -10 27 h-240q-49 0 -49 43zM973 305h88q12 0 14 12l2 111q0 18 -10 4z" /> -<glyph unicode="¿" horiz-adv-x="759" d="M72 -106q0 207 149 311q51 39 146 74q43 16 56 30.5t13 34.5q0 43 -71 127q-35 39 10 61q18 10 47 4t41 -24q106 -131 106 -233q0 -82 -40 -129.5t-132 -81.5q-127 -49 -170 -92.5t-43 -113t45 -109.5t131 -40q29 0 79 7.5t75 7.5q152 0 152 -107q0 -68 -59.5 -99.5 t-151.5 -31.5q-170 0 -276.5 112.5t-106.5 291.5zM291 758q0 53 38 89t93 36t93 -35t38 -90.5t-38 -91t-93 -35.5t-93 35.5t-38 91.5z" /> -<glyph unicode="À" horiz-adv-x="1452" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 27.5t39 15.5h68h26q59 0 80 -30q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40t-32 -15q-231 10 -538 2 q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -39 121 -32q25 4 43 0q12 -2 22.5 -20.5t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5 q-334 6 -434 0h-27q-39 6 -39 61.5zM496 1810q-20 29 0 51.5t45 22.5l153 2q45 0 58 -28q47 -123 104 -332q0 -39 -37 -45t-53 14q-123 158 -270 315zM563 729q-4 -8 5.5 -10t23.5 -2q98 2 178 0q8 0 15.5 7t5.5 13q-45 121 -97 283q-2 8 -7 10t-9 0t-6 -4 q-20 -61 -62.5 -175t-46.5 -122z" /> -<glyph unicode="Á" horiz-adv-x="1452" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 27.5t39 15.5h68h26q59 0 80 -30q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40t-32 -15q-231 10 -538 2 q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -39 121 -32q25 4 43 0q12 -2 22.5 -20.5t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5 q-334 6 -434 0h-27q-39 6 -39 61.5zM563 729q-4 -8 5.5 -10t23.5 -2q98 2 178 0q8 0 15.5 7t5.5 13q-45 121 -97 283q-2 8 -7 10t-9 0t-6 -4q-20 -61 -62.5 -175t-46.5 -122zM598 1542l100 328q12 41 58 41q33 0 90 2t78 0q33 -2 48 -12.5t11 -30.5q-4 -19 -8 -23l-289 -344 q-10 -12 -34.5 -13t-43 13.5t-10.5 38.5z" /> -<glyph unicode="Â" horiz-adv-x="1452" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 27.5t39 15.5h68h26q59 0 80 -30q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40t-32 -15q-231 10 -538 2 q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -39 121 -32q25 4 43 0q12 -2 22.5 -20.5t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5 q-334 6 -434 0h-27q-39 6 -39 61.5zM408 1491l180 311q8 18 39 31q14 2 75.5 3t81.5 -1q37 -2 52 -31l178 -303q22 -47 -17 -57t-59 8l-231 197l-218 -197q-18 -12 -40.5 -11t-37 16.5t-3.5 33.5zM563 729q-4 -8 5.5 -10t23.5 -2q98 2 178 0q8 0 15.5 7t5.5 13 q-45 121 -97 283q-2 8 -7 10t-9 0t-6 -4q-20 -61 -62.5 -175t-46.5 -122z" /> -<glyph unicode="Ã" horiz-adv-x="1452" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 27.5t39 15.5h68h26q59 0 80 -30q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40t-32 -15q-231 10 -538 2 q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -39 121 -32q25 4 43 0q12 -2 22.5 -20.5t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5 q-334 6 -434 0h-27q-39 6 -39 61.5zM367 1540q6 137 60 214t157 77q86 0 209 -84q74 -49 106 -49q25 0 35 21.5t11 48t15.5 49t43.5 24.5q43 0 45 -29q4 -14 4 -30q0 -113 -60.5 -191t-158.5 -78q-88 0 -205 82q-82 55 -107 56q-18 0 -29.5 -14.5t-23.5 -61.5q0 -8 -3 -20.5 t-3 -18.5q-12 -25 -50 -30t-46 34zM563 729q-4 -8 5.5 -10t23.5 -2q98 2 178 0q8 0 15.5 7t5.5 13q-45 121 -97 283q-2 8 -7 10t-9 0t-6 -4q-20 -61 -62.5 -175t-46.5 -122z" /> -<glyph unicode="Ä" horiz-adv-x="1452" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 27.5t39 15.5h68h26q59 0 80 -30q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40t-32 -15q-231 10 -538 2 q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -39 121 -32q25 4 43 0q12 -2 22.5 -20.5t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5 q-334 6 -434 0h-27q-39 6 -39 61.5zM406 1622q0 57 40.5 99t100 42t102.5 -42t43 -99q0 -59 -43 -100t-102.5 -41t-100 41t-40.5 100zM563 729q-4 -8 5.5 -10t23.5 -2q98 2 178 0q8 0 15.5 7t5.5 13q-45 121 -97 283q-2 8 -7 10t-9 0t-6 -4q-20 -61 -62.5 -175t-46.5 -122z M762 1622q0 59 42 100t101 41q61 0 102.5 -41t41.5 -100t-41.5 -100t-102.5 -41q-59 0 -101 41t-42 100z" /> -<glyph unicode="Å" horiz-adv-x="1452" d="M16 55.5q0 55.5 41 55.5q72 0 91.5 12t46.5 76q14 29 32 82l377 1007l-12 45q-4 14 10 25.5t39 15.5h68h26q59 0 80 -28q94 -248 186.5 -490t131 -344t59.5 -152q20 -53 57 -155q23 -66 43.5 -83.5t79.5 -17.5h14q39 0 39 -57q0 -23 -9 -40t-32 -15q-231 10 -538 2 q-27 -2 -36 15.5t-9 45.5q0 55 63 56q20 0 47 1t37 1q43 2 54.5 18t-3.5 55q-25 63 -68.5 181t-68.5 182q-6 12 -33 12h-307q-12 0 -30 -22q-41 -115 -125 -342q-10 -20 -11 -56q0 -39 121 -32q25 4 43 0q12 -2 22.5 -20.5t10.5 -41.5q-2 -20 -14.5 -36.5t-22.5 -16.5 q-334 6 -434 0h-27q-39 6 -39 61.5zM489 1702q0 90 64.5 154.5t157.5 64.5q90 0 153.5 -64.5t63.5 -154.5t-63.5 -154.5t-153.5 -64.5q-92 0 -157 64.5t-65 154.5zM563 729q-4 -8 5.5 -10t23.5 -2q98 2 178 0q8 0 15.5 7t5.5 13q-45 121 -97 283q-2 8 -7 10t-9 0t-6 -4 q-20 -61 -62.5 -175t-46.5 -122zM623 1702q0 -35 25.5 -60.5t62.5 -25.5q35 0 59.5 24.5t24.5 61.5t-24.5 62.5t-59.5 25.5q-37 0 -62.5 -25.5t-25.5 -62.5z" /> -<glyph unicode="Æ" horiz-adv-x="1873" d="M-125 51q-4 27 10.5 36t40.5 11q61 6 100.5 40t102.5 138l541 885q25 39 24.5 55.5t-13.5 21.5t-71 5q-23 0 -37 9.5t-12 29.5l2 29q6 37 49 37q143 -4 543.5 -1t474.5 1q23 0 46.5 -12.5t25.5 -30.5q0 -6 18 -267q0 -8 -2 -12q0 -27 -30 -27h-31q-18 0 -29.5 12.5 t-14.5 21.5t-7 32q-20 90 -41 116.5t-54 26.5h-57h-311q-37 0 -37 -14v-401q0 -8 8 -19.5t23 -11.5l227 4q90 0 110.5 14.5t38.5 98.5q8 39 46 39h26q39 0 39 -52q0 -311 2 -356q4 -49 -35 -49q-18 -6 -39 -2q-33 0 -36 41q-12 88 -35 106.5t-113 16.5l-244 -5 q-18 0 -18 -38v-324q0 -88 21.5 -106.5t107.5 -18.5q45 -4 209 0q96 2 125.5 11.5t54.5 41.5q49 63 68 146q4 14 6 20t10 10.5t25 4.5h26q45 0 41 -60q-1 -47 -26 -258q-4 -55 -80 -55h-1047q-51 0 -51 43v31q0 25 39 34q16 4 84.5 5t105.5 25t39 87l2 72v200q0 14 -26 15 h-371q-14 0 -23 -15l-163 -264q-43 -72 -43 -94q0 -35 108 -35q23 0 33 -11t11 -19.5t3 -32.5q2 -45 -45 -45h-426q-27 -2 -36 15t-13 48zM551 664q-4 -8 1 -13.5t11 -5.5h271q10 0 21 11.5t11 21.5v479q0 18 -12 4q-131 -203 -303 -497z" /> -<glyph unicode="Ç" horiz-adv-x="1560" d="M98 649q0 315 213 514t551 199q72 0 135.5 -11.5t94 -21.5t129.5 -45q39 -12 57 2q12 10 45 7t37 -21q25 -104 20 -185v-122q-8 -35 -46 -43.5t-56 18.5q-104 303 -404 303q-233 0 -368 -149.5t-135 -405.5q0 -264 149.5 -434t382.5 -170q178 0 314 123q41 37 61 62.5 t55 90.5q10 18 39 23.5t50.5 -5.5t15.5 -36q-25 -80 -81.5 -210t-70.5 -128q-39 10 -57 10q-59 0 -150 -28q-82 -25 -180 -29q-18 0 -25 -14l-32 -58q-2 -4 22 -16q47 -18 77 -62.5t30 -101.5q0 -86 -67.5 -163t-149.5 -77q-47 0 -76 11q-51 20 -35 51q8 16 12 22 q8 12 20.5 13.5t31 -5t26.5 -6.5q29 0 61.5 41t32.5 72q0 25 -13 43.5t-30 18.5q-35 0 -106 -37q-25 -8 -33 12q-10 20 8 49l115 187q10 23 -6 22q-295 25 -479.5 216.5t-184.5 473.5z" /> -<glyph unicode="È" horiz-adv-x="1267" d="M37 57.5q8 53.5 41 57.5q14 2 88 2q78 2 102.5 30.5t24.5 139.5v753q0 106 -23.5 142.5t-111.5 36.5h-8.5h-9.5h-8t-8 1t-7 2t-7.5 2t-7.5 3t-7 5t-6 7t-5 10q-14 23 8 62q10 20 53 20q655 4 895 0q53 0 60 -39q8 -66 11 -118t4 -96t3 -60q-2 -18 -29.5 -25.5t-50.5 0.5 q-29 4 -28 39q-18 115 -48 139.5t-145 26.5q-182 6 -254 2q-8 0 -17 -8t-9 -18v-398q0 -20 26 -20h211q109 0 130.5 16t35.5 115q4 14 25.5 21t45 -3t29.5 -41q2 -45 2 -111.5t-1 -142t-1 -102.5q0 -31 -25.5 -42t-50 -4t-28.5 25q-14 92 -36.5 110.5t-131.5 18.5l-199 2 q-33 0 -32 -30v-314q0 -63 2 -84q2 -29 12 -38q16 -16 125 -17h145q109 0 142.5 7.5t54.5 33.5q45 49 69 152q6 29 37 37q59 4 70 -21q10 -20 0 -98q-2 -23 -11 -90.5t-16 -112.5q-6 -47 -100 -47q-563 4 -983 -2l-10 2q-45 8 -37 61.5zM408.5 1818.5q21.5 24.5 46.5 24.5 l155 2q39 0 58 -28q68 -188 100 -332q0 -41 -38 -45t-50 14q-104 137 -270 315q-23 25 -1.5 49.5z" /> -<glyph unicode="É" horiz-adv-x="1267" d="M37 57.5q8 53.5 41 57.5q14 2 88 2q78 2 102.5 30.5t24.5 139.5v753q0 106 -23.5 142.5t-111.5 36.5h-8.5h-9.5h-8t-8 1t-7 2t-7.5 2t-7.5 3t-7 5t-6 7t-5 10q-14 23 8 62q10 20 53 20q655 4 895 0q53 0 60 -39q8 -66 11 -118t4 -96t3 -60q-2 -18 -29.5 -25.5t-50.5 0.5 q-29 4 -28 39q-18 115 -48 139.5t-145 26.5q-182 6 -254 2q-8 0 -17 -8t-9 -18v-398q0 -20 26 -20h211q109 0 130.5 16t35.5 115q4 14 25.5 21t45 -3t29.5 -41q2 -45 2 -111.5t-1 -142t-1 -102.5q0 -31 -25.5 -42t-50 -4t-28.5 25q-14 92 -36.5 110.5t-131.5 18.5l-199 2 q-33 0 -32 -30v-314q0 -63 2 -84q2 -29 12 -38q16 -16 125 -17h145q109 0 142.5 7.5t54.5 33.5q45 49 69 152q6 29 37 37q59 4 70 -21q10 -20 0 -98q-2 -23 -11 -90.5t-16 -112.5q-6 -47 -100 -47q-563 4 -983 -2l-10 2q-45 8 -37 61.5zM500 1489l98 328q12 41 55 41l174 2 q20 0 36 -11.5t14 -36.5q-2 -2 -4.5 -8t-4.5 -10l-290 -344q-16 -23 -52.5 -11.5t-25.5 50.5z" /> -<glyph unicode="Ê" horiz-adv-x="1267" d="M37 57.5q8 53.5 41 57.5q14 2 88 2q78 2 102.5 30.5t24.5 139.5v753q0 106 -23.5 142.5t-111.5 36.5h-8.5h-9.5h-8t-8 1t-7 2t-7.5 2t-7.5 3t-7 5t-6 7t-5 10q-14 23 8 62q10 20 53 20q655 4 895 0q53 0 60 -39q8 -66 11 -118t4 -96t3 -60q-2 -18 -29.5 -25.5t-50.5 0.5 q-29 4 -28 39q-18 115 -48 139.5t-145 26.5q-182 6 -254 2q-8 0 -17 -8t-9 -18v-398q0 -20 26 -20h211q109 0 130.5 16t35.5 115q4 14 25.5 21t45 -3t29.5 -41q2 -45 2 -111.5t-1 -142t-1 -102.5q0 -31 -25.5 -42t-50 -4t-28.5 25q-14 92 -36.5 110.5t-131.5 18.5l-199 2 q-33 0 -32 -30v-314q0 -63 2 -84q2 -29 12 -38q16 -16 125 -17h145q109 0 142.5 7.5t54.5 33.5q45 49 69 152q6 29 37 37q59 4 70 -21q10 -20 0 -98q-2 -23 -11 -90.5t-16 -112.5q-6 -47 -100 -47q-563 4 -983 -2l-10 2q-45 8 -37 61.5zM342 1518l176 311q8 18 39 31 q14 2 75.5 3t82.5 -1q35 -2 51 -31l176 -303q10 -12 8 -32t-22 -26q-39 -10 -60 9l-231 196l-217 -196q-18 -12 -40 -11.5t-36 16t-2 34.5z" /> -<glyph unicode="Ë" horiz-adv-x="1267" d="M37 57.5q8 53.5 41 57.5q14 2 88 2q78 2 102.5 30.5t24.5 139.5v753q0 106 -23.5 142.5t-111.5 36.5h-8.5h-9.5h-8t-8 1t-7 2t-7.5 2t-7.5 3t-7 5t-6 7t-5 10q-14 23 8 62q10 20 53 20q655 4 895 0q53 0 60 -39q8 -66 11 -118t4 -96t3 -60q-2 -18 -29.5 -25.5t-50.5 0.5 q-29 4 -28 39q-18 115 -48 139.5t-145 26.5q-182 6 -254 2q-8 0 -17 -8t-9 -18v-398q0 -20 26 -20h211q109 0 130.5 16t35.5 115q4 14 25.5 21t45 -3t29.5 -41q2 -45 2 -111.5t-1 -142t-1 -102.5q0 -31 -25.5 -42t-50 -4t-28.5 25q-14 92 -36.5 110.5t-131.5 18.5l-199 2 q-33 0 -32 -30v-314q0 -63 2 -84q2 -29 12 -38q16 -16 125 -17h145q109 0 142.5 7.5t54.5 33.5q45 49 69 152q6 29 37 37q59 4 70 -21q10 -20 0 -98q-2 -23 -11 -90.5t-16 -112.5q-6 -47 -100 -47q-563 4 -983 -2l-10 2q-45 8 -37 61.5zM332 1593q0 55 39 95.5t96 40.5 t97 -40t40 -96q0 -57 -41 -96t-96 -39t-95 39t-40 96zM670 1593.5q0 55.5 40 95.5t95 40q57 0 97 -40t40 -95.5t-40 -95.5t-97 -40q-55 0 -95 40t-40 95.5z" /> -<glyph unicode="Ì" horiz-adv-x="743" d="M96 45q0 18 10.5 37.5t26.5 21.5q84 8 100.5 24.5t18.5 90.5l2 70v760l-2 69q-2 72 -18.5 92.5t-88.5 28.5q-18 2 -29.5 13.5t-13.5 26.5t2.5 30.5t15.5 24.5t25 9q379 -4 461 0q49 4 53 -40q2 -20 -6 -42t-22 -24q-4 0 -13.5 -1t-15.5 -1q-80 -2 -97.5 -28.5 t-17.5 -157.5v-830q0 -78 29 -94q18 -12 64.5 -14t58.5 -7q27 -16 23.5 -64t-33.5 -46q-246 8 -488 0q-20 0 -32.5 14.5t-12.5 36.5zM136.5 1820.5q19.5 22.5 43.5 22.5l152 2q39 0 57 -28q61 -172 98 -332q2 -37 -33 -44t-53 13q-139 178 -264 315q-20 29 -0.5 51.5z" /> -<glyph unicode="Í" horiz-adv-x="743" d="M96 45q0 18 10.5 37.5t26.5 21.5q84 8 100.5 24.5t18.5 90.5l2 70v760l-2 69q-2 74 -18.5 93.5t-88.5 27.5q-18 2 -29.5 13.5t-13.5 26.5t2.5 30.5t15.5 26t25 10.5q68 -2 131.5 -4.5t93 -3.5t88 0t148.5 5q49 4 53 -38q2 -23 -6 -44.5t-22 -23.5q-4 0 -13.5 -1t-15.5 -1 q-80 -2 -97.5 -28.5t-17.5 -157.5v-830q0 -78 29 -94q18 -12 64.5 -14t58.5 -7q27 -16 23.5 -64t-33.5 -46q-246 8 -488 0q-20 0 -32.5 14.5t-12.5 36.5zM231 1501l97 330q20 39 57 39q31 0 71 1t56 2t43 -1q90 -8 31 -80l-267 -330q-16 -23 -57 -11.5t-31 50.5z" /> -<glyph unicode="Î" horiz-adv-x="741" d="M78 1501l174 311q12 18 39 31q14 2 74.5 3t80.5 -1q35 -2 50 -30l174 -304q22 -47 -15 -57q-39 -10 -59 8l-227 197l-213 -197q-16 -12 -39 -11t-36 16.5t-3 33.5zM94 45q0 16 12.5 36.5t26.5 22.5q84 8 100.5 24.5t18.5 90.5l2 70v760l-2 69q-2 72 -18.5 91.5 t-88.5 27.5q-31 4 -41 30.5t2.5 51t36.5 24.5q80 0 158 -3t135.5 -3t171.5 6q37 2 48.5 -23.5t1 -53t-24.5 -31.5q-6 0 -16.5 -1t-12.5 -1q-80 0 -99.5 -26.5t-19.5 -157.5v-830q0 -74 31 -94q18 -12 64.5 -14t58.5 -7q33 -20 28 -66t-36 -44q-246 8 -490 0 q-20 0 -33.5 14.5t-13.5 36.5z" /> -<glyph unicode="Ï" horiz-adv-x="743" d="M55 1593q0 57 41 99.5t98.5 42.5t98.5 -41t41 -100.5t-40 -100.5t-99 -41q-57 0 -98.5 41t-41.5 100zM96 45q0 18 10.5 37.5t26.5 21.5q84 8 100.5 24.5t18.5 90.5l2 70v758l-2 69q-2 74 -18.5 93.5t-86.5 27.5q-31 2 -41 28.5t2.5 51t36.5 24.5q381 -4 463 0 q49 4 54 -41q4 -20 -5.5 -41.5t-23.5 -23.5q-6 0 -14.5 -1t-14.5 -1q-80 -2 -98.5 -28.5t-18.5 -157.5v-828q0 -76 29 -94q18 -12 65.5 -14t59.5 -7q27 -16 24 -64t-34 -46q-246 8 -490 0q-20 0 -32.5 14.5t-12.5 36.5zM406 1593.5q0 59.5 40.5 100.5t98.5 41q59 0 100 -41 t41 -100.5t-41 -100.5t-100 -41q-57 0 -98 41t-41 100.5z" /> -<glyph unicode="Ð" horiz-adv-x="1628" d="M12 655v70q2 2 0 13.5t11.5 24.5t39.5 13h154q6 0 13.5 12.5t7.5 24.5v242q0 133 -22.5 157.5t-133.5 24.5q-51 0 -51 57q0 49 49 60l166 6q152 6 459 6q203 0 341 -34t248 -113q125 -90 196 -221.5t71 -284.5q0 -231 -152 -422.5t-381 -257.5q-104 -31 -168.5 -37 t-271.5 -6q-438 0 -512 -2q-16 -2 -31.5 8t-15.5 31q0 45 6 55q8 12 16 18t13.5 7.5t18.5 0t19 -1.5q84 0 107.5 19.5t26.5 89.5q2 59 2 369q0 20 -21 20l-172 -2q-33 4 -33 53zM477 217q0 -86 19.5 -103.5t124.5 -17.5q145 0 212.5 9.5t135.5 41.5q143 66 229 210.5 t86 322.5q0 145 -54.5 268t-146.5 195q-63 47 -133.5 70.5t-189.5 35.5q-119 10 -191 11q-6 0 -28.5 2t-34.5 0q-29 -4 -29 -29v-424q0 -25 10.5 -29t51.5 -6q27 0 84 1t107 2t52 1q55 0 56 -57v-76q-6 -27 -15.5 -33t-38.5 -6l-288 -2q-18 0 -19 -29v-358z" /> -<glyph unicode="Ñ" horiz-adv-x="1708" d="M65.5 79q12.5 30 51.5 30q131 0 131 94v991q-45 27 -148 31q-12 0 -20 17.5t-8 37.5q0 49 53 53q55 4 160.5 2t128.5 -2q39 0 65 -30l797 -895h-2q27 -31 26 -2v636q0 133 -18 152q-12 12 -45 18q-16 2 -53 4.5t-56 4.5q-25 0 -36 28.5t-0.5 56t38.5 27.5q145 -6 494 2 q29 0 35 -59q2 -51 -49 -51q-109 -4 -127.5 -22.5t-18.5 -127.5v-1046q0 -43 -58 -49.5t-73 16.5q-178 201 -468 527.5t-429 484.5q-4 2 -10 8q-8 -6 -10 -15v-704q0 -98 10 -129q8 -23 25.5 -35t30 -14t44 -2h37.5q51 -4 60 -27q14 -23 4.5 -60.5t-47.5 -35.5 q-326 6 -474 -2q-27 -2 -40 27.5t-0.5 59.5zM485 1507q6 137 60.5 214t156.5 77q86 0 209 -84q74 -49 107 -49q25 0 36 21.5t12 48t14.5 49t41.5 24.5q43 0 47 -28q4 -14 5 -31q0 -113 -62 -190.5t-160 -77.5q-88 0 -204 82q-78 53 -107 53q-18 0 -30.5 -13.5t-22.5 -60.5 q0 -2 -6 -39q-12 -25 -50 -30t-47 34z" /> -<glyph unicode="Ò" horiz-adv-x="1693" d="M92 641q0 315 214 522t544 207q324 0 532.5 -191.5t208.5 -482.5q0 -311 -213 -523t-532 -212q-324 0 -539 195.5t-215 484.5zM360 694q0 -266 146.5 -439t374.5 -173q236 0 339 152.5t103 402.5q0 274 -146 445t-384 171q-195 0 -314 -153.5t-119 -405.5zM659 1790 q-20 29 0.5 51.5t45.5 22.5l147 2q45 0 57 -29q51 -135 103 -332q0 -27 -16.5 -37t-36 -4.5t-29.5 15.5q-102 133 -271 311z" /> -<glyph unicode="Ó" horiz-adv-x="1693" d="M92 643q0 313 214 520t544 207q324 0 532.5 -191.5t208.5 -482.5q0 -311 -213 -523t-532 -212q-324 0 -539 195.5t-215 486.5zM360 694q0 -266 146.5 -439t374.5 -173q236 0 339 152.5t103 402.5q0 274 -146 445t-384 171q-195 0 -314 -153.5t-119 -405.5zM748 1483 l98 327q12 41 55 41q33 0 90.5 2t77.5 0q35 -2 49.5 -12t9.5 -31q0 -12 -6 -22l-297 -340q-16 -23 -53 -13.5t-24 48.5z" /> -<glyph unicode="Ô" horiz-adv-x="1693" d="M92 641q0 315 214 522t544 207q324 0 532.5 -191.5t208.5 -482.5q0 -311 -213 -523t-532 -212q-324 0 -539 195.5t-215 484.5zM360 694q0 -266 146.5 -439t374.5 -173q236 0 339 152.5t103 402.5q0 274 -146 445t-384 171q-195 0 -314 -153.5t-119 -405.5zM575 1481 l179 311q10 18 41 31q14 2 75.5 3t81.5 -1q35 -2 52 -31l176 -303q26 -47 -15 -57q-39 -12 -59 8l-232 196l-219 -196q-18 -12 -39.5 -11t-36 16t-4.5 34z" /> -<glyph unicode="Õ" horiz-adv-x="1693" d="M92 641q0 315 214 522t544 207q324 0 532.5 -191.5t208.5 -482.5q0 -311 -213 -523t-532 -212q-324 0 -539 195.5t-215 484.5zM360 694q0 -266 146.5 -439t374.5 -173q236 0 339 152.5t103 400.5q0 274 -146 445t-384 171q-195 0 -314 -152.5t-119 -404.5zM506 1489 q6 129 60.5 202.5t154.5 73.5q86 0 207 -79q74 -47 104 -48q25 0 36 20.5t12 46.5t14.5 47.5t42.5 21.5q12 2 27.5 -4.5t17.5 -22.5q4 -14 4 -29q0 -109 -60.5 -183.5t-156.5 -74.5q-86 0 -203 76q-82 55 -104 55q-18 0 -29.5 -12t-24.5 -57q0 -6 -1 -12.5t-3 -13.5t-2 -11 q-12 -23 -49 -28t-47 32z" /> -<glyph unicode="Ö" horiz-adv-x="1693" d="M92 641q0 315 214 522t544 207q324 0 532.5 -191.5t208.5 -482.5q0 -311 -213 -523t-532 -212q-324 0 -539 195.5t-215 484.5zM360 694q0 -266 146.5 -439t374.5 -173q236 0 339 152.5t103 400.5q0 274 -146 445t-384 171q-195 0 -314 -152.5t-119 -404.5zM526 1604 q0 57 42 99t101.5 42t101.5 -41t42 -100.5t-42 -100.5t-101.5 -41t-101.5 41t-42 101zM885 1603.5q0 59.5 42 100.5t101 41t101 -41t42 -100.5t-42 -100.5t-101 -41t-101 41t-42 100.5z" /> -<glyph unicode="×" horiz-adv-x="1431" d="M200 269q-3 24 19 48q117 111 363 357q16 14 2 28l-353 351q-14 12 -22 24.5t-8 23.5v19t9 19.5t13 16.5t18.5 18.5t18.5 17.5q55 27 82 0q166 -156 365 -365q12 -12 19 -11t26 18q162 147 331 340q14 16 46 25t49 -3q4 -2 25.5 -20.5t27.5 -25.5t15 -23.5t4 -31 t-21 -30.5q-25 -25 -175.5 -174.5t-197.5 -190.5q-12 -10 -2 -20l365 -356q14 -12 21 -23.5t6 -23t0 -17.5t-11 -18.5t-14 -14.5t-21 -16l-18 -14q-49 -39 -88 -2l-344 344q-29 27 -60 -7q-109 -117 -336 -331q-10 -10 -20 -15.5t-18.5 -8.5t-18.5 0t-15.5 5t-16.5 10.5 t-15 11.5t-16.5 14t-14.5 13q-16 14 -19 38z" /> -<glyph unicode="Ø" horiz-adv-x="1769" d="M92 649q0 313 230.5 524t566.5 211q248 0 442 -116q8 -4 27 16l112 139q33 27 66 4l16 -12q37 -29 -6 -76l-100 -114q-20 -20 -12 -29q233 -203 233 -498q0 -313 -227 -528t-557 -215q-229 0 -430 108q-16 8 -41 -16l-144 -168q-29 -25 -42 -23.5t-40 19.5q-39 35 -8 70 l146 161q20 27 10 35q-242 203 -242 508zM362 702q0 -238 115 -395q10 -10 14.5 -7t20.5 22q397 475 670 770q31 31 20 38q-150 136 -373 136q-203 0 -335 -156t-132 -408zM573 205q0 -6 2 -8q150 -125 345 -125q236 0 362 182q113 162 117 383t-105 385q-9 19 -34 -10 q-160 -182 -678 -779q-6 -6 -7.5 -14t-1.5 -14z" /> -<glyph unicode="Ù" horiz-adv-x="1669" d="M41 1287q-10 50 35 54q41 2 230.5 2t316.5 -2q27 0 35 -26.5t-3.5 -53t-33.5 -26.5h-19q-82 0 -106.5 -22.5t-26.5 -94.5q0 -16 -1 -45t-1 -43v-389q0 -240 90 -373t313 -133q285 0 369 225q31 80 31 269v362q0 162 -28 201t-136 41l-14 6q-25 6 -28 54t32 48 q225 4 499 0q39 0 39 -51q0 -45 -37 -53q-109 -4 -138 -43t-29 -195v-368q0 -131 -6.5 -198.5t-47.5 -157t-123 -160.5q-94 -82 -188 -118t-242 -36q-403 0 -547 313q-31 70 -39 128.5t-8 207.5v520q0 72 -22.5 88.5t-130.5 16.5q-25 2 -35 52zM620 1780q19 22 46 22l155 2 q41 0 58 -28q55 -143 102 -332q0 -29 -19.5 -39t-40 -6t-28.5 14q-113 145 -272 316q-20 29 -1 51z" /> -<glyph unicode="Ú" horiz-adv-x="1669" d="M41 1287q-10 50 35 54q41 2 230.5 2t316.5 -2q27 0 35 -26.5t-3.5 -53t-33.5 -26.5h-19q-82 0 -106.5 -22.5t-26.5 -94.5q0 -14 -1 -42.5t-1 -45.5v-389q0 -240 90 -373t313 -133q285 0 369 225q31 80 31 269v362q0 162 -28 201t-136 43l-14 4q-25 6 -28 54t32 48 q225 4 499 0q39 0 39 -51q0 -45 -37 -53q-109 -4 -138 -43t-29 -195v-368q0 -131 -6.5 -198.5t-47.5 -157t-123 -160.5q-94 -82 -188 -118t-242 -36q-403 0 -547 313q-31 70 -39 128.5t-8 207.5v520q0 72 -22.5 88.5t-130.5 16.5q-25 2 -35 52zM715 1442l98 327q12 41 57 41 l179 2q27 0 42 -14t7 -39l-2 -2l-295 -354q-16 -23 -57.5 -11.5t-28.5 50.5z" /> -<glyph unicode="Û" horiz-adv-x="1669" d="M40 1312.5q5 26.5 36 28.5q41 2 230.5 2t316.5 -2q27 0 35 -26.5t-3.5 -53t-33.5 -26.5h-19q-82 0 -106.5 -22.5t-26.5 -94.5q0 -16 -1 -45t-1 -43v-389q0 -240 90 -373t313 -133q285 0 369 225q31 80 31 269v362q0 162 -28 201t-136 41l-14 4q-25 8 -28 56t32 48 q225 4 499 0q39 0 39 -51q0 -45 -37 -53q-109 -4 -138 -44t-29 -194v-368q0 -131 -6.5 -198.5t-47.5 -157t-123 -160.5q-94 -82 -188 -118t-242 -36q-403 0 -547 313q-31 70 -39 128.5t-8 207.5v520q0 70 -22.5 86.5t-130.5 18.5q-14 0 -27.5 25.5t-8.5 52zM545 1511 l178 304q8 18 39 30q14 2 71.5 3t79.5 -1q33 -2 50 -30l186 -295q10 -12 8 -33t-22 -25q-39 -8 -62 9l-231 196l-217 -196q-18 -12 -41 -11.5t-37.5 16t-1.5 33.5z" /> -<glyph unicode="Ü" horiz-adv-x="1669" d="M41 1285q-10 50 35 54q41 4 230.5 4t316.5 -4q27 0 35 -26.5t-3.5 -53t-33.5 -26.5h-19q-80 0 -102.5 -21.5t-24.5 -95.5q0 -14 -1 -43t-1 -45v-389q0 -240 87 -372t310 -132q283 0 369 223q31 82 31 269v362q0 162 -28 201t-136 41l-14 6q-25 6 -28 54t32 48 q225 4 499 0q39 0 39 -51q0 -45 -37 -53q-109 -4 -138 -43t-29 -195v-368q0 -129 -6.5 -196.5t-47.5 -157t-123 -160.5q-94 -82 -188 -118t-242 -36q-408 0 -551 311q-31 70 -39 129.5t-8 208.5v518q0 74 -20.5 89.5t-128.5 15.5q-25 2 -35 52zM485 1587.5q0 59.5 42 100.5 t101.5 41t101.5 -42t42 -100q0 -59 -42 -100t-101.5 -41t-101.5 41t-42 100.5zM944 1587.5q0 57.5 43 99.5t102.5 42t100.5 -41t41 -100.5t-41 -100.5t-100.5 -41t-102.5 42t-43 99.5z" /> -<glyph unicode="Ý" horiz-adv-x="1490" d="M23 1257q-4 18 0 39q10 43 45 41q389 -6 540 0q23 0 37 -27.5t4 -54t-47 -26.5q-96 0 -96 -19q0 -14 4 -26q10 -25 47 -82l264 -397q2 -4 7.5 -3.5t9.5 5t8 10.5l217 360q55 94 55 121q0 18 -15.5 25.5t-72.5 7.5h-24q-10 4 -18.5 21.5t-10.5 37t11 33.5t40 14 q131 -8 436 0q41 0 41 -51q0 -53 -39 -55q-27 -2 -50 -8t-40.5 -12.5t-37 -24t-30 -26.5t-26.5 -33.5t-22.5 -34t-24.5 -40t-23 -38.5l-297 -494v-103.5v-123v-76.5q0 -57 30 -77.5t91 -22.5h16.5t15.5 1t16.5 -1t15.5 -6q20 -12 20 -64q0 -55 -45 -55q-393 6 -553 2 q-39 0 -53 26q-10 29 -2 60q8 20 22.5 29.5t25.5 9.5t34.5 -1t34.5 -1q45 2 63.5 26.5t22.5 75.5q8 143 2 275l-367 565q-70 111 -109.5 139.5t-123.5 30.5q-41 0 -49 28zM647 1499l98 330q20 39 58 39l178 2q29 0 42 -14t5 -41l-293 -355q-18 -23 -58 -11.5t-30 50.5z" /> -<glyph unicode="Þ" horiz-adv-x="1206" d="M37 1290v19q0 41 41 41q358 -6 508 -2q51 4 51 -39v-23q0 -37 -23 -41q-6 -2 -18 -2q-98 0 -113 -20q-10 -16 -10 -97q0 -4 6 -10t13 -6q227 0 350 -31q135 -35 219 -135t84 -239q0 -197 -144.5 -309.5t-388.5 -112.5q-82 0 -125 6q-8 2 -11 -2.5t-3 -14.5v-51 q0 -74 25.5 -98.5t107.5 -24.5h4h12.5h14.5h16.5h14.5q43 -2 43 -39q2 -20 0 -32.5t-14.5 -23.5t-39.5 -11q-295 8 -544 -2q-39 0 -45 18q-4 8 -2 23v16t2 21q6 29 57 28q61 0 81.5 16.5t20.5 71.5v92v832q0 94 -10 119q-8 10 -31 12q-16 6 -63 5t-64 3q-23 4 -22 43z M473 422q0 -10 2 -16.5t4 -8.5l2 -2q37 -6 74 -6q147 0 237.5 90t90.5 238q0 191 -123 254q-102 53 -260 35q-27 0 -27 -15v-569z" /> -<glyph unicode="ß" horiz-adv-x="1116" d="M29 41q0 18 1 27.5t11 19.5t31 10q70 6 78 17q10 14 10 90v78v505q0 236 20.5 333.5t87.5 183.5q115 152 320 151q162 0 274.5 -97t112.5 -243q0 -109 -57.5 -176.5t-167.5 -136.5q-14 -12 8 -21q131 -51 207.5 -153.5t76.5 -239.5q0 -193 -111.5 -308.5t-273.5 -115.5 q-53 0 -91 25.5t-38 72.5q0 37 23.5 64t58.5 27q29 0 78 -29q45 -18 47 -19q14 0 31.5 26t32 87.5t14.5 142.5q0 315 -190 357q-39 8 -101 8q-31 0 -47 14q-6 8 -6 50q0 20 7 25t34 9q125 16 190.5 88t65.5 187q0 113 -55.5 178t-145.5 65q-92 0 -141 -77q-53 -82 -53 -254 v-129v-600v-90q0 -63 11 -77t71 -14q23 -4 29.5 -6t13 -12t6.5 -31q0 -37 -2 -43q-18 -23 -39 -18q-213 8 -385 0q-29 -2 -38 12t-9 37z" /> -<glyph unicode="à" horiz-adv-x="862" d="M47 172q0 160 227 219q59 14 181 70q12 8 12 18l-2 125q-2 156 -113 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -29 10 -51q-16 -18 -67 -43t-70 -31q-74 -25 -74 49q0 78 134 183q111 84 200 84q68 0 134.5 -34t105.5 -87q25 -37 31 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q31 0 72 31q14 10 33 10q18 -2 27.5 -17.5t8 -31.5t-7.5 -31q-135 -123 -227 -122.5t-121 98.5v-2q-70 -55 -112.5 -76t-102.5 -21q-94 0 -154.5 54.5t-60.5 142.5zM205.5 1321.5q21.5 24.5 48.5 24.5l152 2q43 0 55 -29q66 -168 102 -330q0 -29 -19.5 -39 t-39 -5t-29.5 13q-106 143 -268 314q-23 25 -1.5 49.5zM242 197q0 -37 25.5 -61.5t64.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12t-8 4q-39 -18 -117 -51q-94 -37 -94 -100z" /> -<glyph unicode="á" horiz-adv-x="862" d="M47 172q0 160 227 219q59 14 181 70q12 8 12 18l-2 125q-2 156 -113 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -29 10 -51q-16 -18 -67 -43t-70 -31q-74 -25 -74 49q0 78 134 183q111 84 200 84q68 0 134.5 -34t105.5 -87q25 -37 31 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q31 0 72 31q14 10 33 10q18 -2 27.5 -17.5t8 -31.5t-7.5 -31q-135 -123 -227 -122.5t-121 98.5v-2q-70 -55 -112.5 -76t-102.5 -21q-94 0 -154.5 54.5t-60.5 142.5zM242 197q0 -37 25.5 -61.5t64.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12t-8 4 q-39 -18 -117 -51q-94 -37 -94 -100zM301 987l96 326q12 41 58 41h176q20 0 35.5 -10.5t13.5 -34.5l-2 -2q-4 -12 -6 -15l-285 -342q-16 -23 -57 -12.5t-29 49.5z" /> -<glyph unicode="â" horiz-adv-x="862" d="M47 172q0 160 227 219q59 14 181 70q12 8 12 18l-2 125q-2 156 -113 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -29 10 -51q-16 -18 -67 -43t-70 -31q-74 -25 -74 49q0 78 134 183q111 84 200 84q68 0 134.5 -34t105.5 -87q25 -37 31 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q31 0 72 31q14 10 33 10q18 -2 27.5 -17.5t8 -31.5t-7.5 -31q-135 -123 -227 -122.5t-121 98.5v-2q-70 -55 -112.5 -76t-102.5 -21q-94 0 -154.5 54.5t-60.5 142.5zM104 1001l181 297q12 16 39 29q12 2 62 3t73 -1q33 -2 49 -29l178 -290q19 -44 -16 -54 q-37 -10 -58 9l-221 186l-207 -186q-16 -12 -38.5 -11.5t-37 15t-4.5 32.5zM242 197q0 -37 25.5 -61.5t64.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12t-8 4q-39 -18 -117 -51q-94 -37 -94 -100z" /> -<glyph unicode="ã" horiz-adv-x="862" d="M47 172q0 160 227 219q59 14 181 70q12 8 12 18l-2 125q-2 156 -113 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -29 10 -51q-16 -18 -67 -43t-70 -31q-74 -25 -74 49q0 78 134 183q111 84 200 84q68 0 134.5 -34t105.5 -87q25 -37 31 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q31 0 72 31q14 10 33 10q18 -2 27.5 -17.5t8 -31.5t-7.5 -31q-135 -123 -227 -122.5t-121 98.5v-2q-70 -55 -112.5 -76t-102.5 -21q-94 0 -154.5 54.5t-60.5 142.5zM86 969q14 274 215 274q86 0 207 -78q72 -47 104 -47q25 0 36 20.5t12.5 45t13.5 46t41 23.5 q43 0 47 -28q4 -12 4 -27q0 -109 -60.5 -183.5t-156.5 -74.5q-86 0 -205 78q-80 53 -104 53q-18 0 -29.5 -13.5t-22.5 -56.5q0 -6 -4 -18t-4 -18q-12 -23 -49 -27t-45 31zM242 197q0 -37 25.5 -61.5t64.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12t-8 4q-39 -18 -117 -51 q-94 -37 -94 -100z" /> -<glyph unicode="ä" horiz-adv-x="862" d="M47 172q0 160 227 219q59 14 181 70q12 8 12 18l-2 125q-2 156 -113 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -29 10 -51q-16 -18 -67 -43t-70 -31q-74 -25 -74 49q0 78 134 183q111 84 200 84q68 0 134.5 -34t105.5 -87q25 -37 31 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q31 0 72 31q14 10 33 10q18 -2 27.5 -17.5t8 -31.5t-7.5 -31q-135 -123 -227 -122.5t-121 98.5v-2q-70 -55 -112.5 -76t-102.5 -21q-94 0 -154.5 54.5t-60.5 142.5zM129 1092q0 53 40 93t95 40t95 -40t40 -93q0 -57 -40 -96.5t-95 -39.5t-95 39t-40 97z M242 197q0 -37 25.5 -61.5t64.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12t-8 4q-39 -18 -117 -51q-94 -37 -94 -100zM465 1092q0 53 40 93t95 40t95 -39t40 -94.5t-39 -95.5t-96 -40q-55 0 -95 39t-40 97z" /> -<glyph unicode="å" horiz-adv-x="862" d="M47 172q0 160 227 219q59 14 181 70q12 8 12 18l-2 125q-2 156 -113 156q-27 0 -59.5 -23.5t-32.5 -44.5q0 -29 10 -51q-16 -18 -67 -43t-70 -31q-74 -25 -74 49q0 78 134 183q111 84 200 84q68 0 134.5 -34t105.5 -87q25 -37 31 -67.5t6 -125.5v-356q0 -35 3 -51.5 t7 -20.5t12 -4q31 0 72 31q14 10 33 10q18 -2 27.5 -17.5t8 -31.5t-7.5 -31q-135 -123 -227 -122.5t-121 98.5v-2q-70 -55 -112.5 -76t-102.5 -21q-94 0 -154.5 54.5t-60.5 142.5zM188 1175.5q0 90.5 64.5 154t157.5 63.5q90 0 153.5 -63.5t63.5 -154t-63.5 -155 t-153.5 -64.5q-92 0 -157 64.5t-65 155zM242 197q0 -37 25.5 -61.5t64.5 -24.5q25 0 73 30.5t60 55.5v135q0 6 -4 12t-8 4q-39 -18 -117 -51q-94 -37 -94 -100zM322 1176q0 -37 25.5 -63t62.5 -26q35 0 59.5 26t24.5 63q0 35 -24.5 60.5t-59.5 25.5q-37 0 -62.5 -26 t-25.5 -60z" /> -<glyph unicode="æ" horiz-adv-x="1339" d="M63 164q0 96 61.5 146t217.5 89q94 23 170 70v119q0 168 -121 168q-45 0 -74.5 -22.5t-29.5 -47.5q0 -6 1 -21.5t1 -21.5t-6.5 -16.5t-20.5 -16.5l-110 -49q-35 -18 -52.5 -7t-17.5 67q0 78 141 184q104 78 203 78q135 0 227 -99q6 -4 11 0q113 102 274 103 q127 0 196.5 -60.5t122.5 -183.5q10 -18 37 -45v-37q0 -29 -14 -37t-47 -8h-483q-35 0 -35 -22q0 -131 22 -199q23 -70 88.5 -116t139.5 -46q59 0 103 23.5t108 87.5q33 37 59 10l25 -21q31 -25 -3 -61q-186 -207 -368 -207q-176 0 -285 144q-10 10 -18 4q-66 -66 -148 -107 t-153 -41q-92 0 -157 56.5t-65 142.5zM266 190q0 -86 90 -86q70 0 156 80v115q0 25 -2 36t-12 5q-63 -27 -103 -39q-80 -27 -104.5 -49.5t-24.5 -61.5zM733 639q-4 -18 17 -18h276q18 0 14 14q-18 70 -58 106.5t-89 36.5q-117 0 -160 -139z" /> -<glyph unicode="ç" horiz-adv-x="888" d="M51 391q0 207 147.5 350.5t356.5 143.5q100 0 179 -39t79 -109q0 -39 -26.5 -66.5t-65.5 -27.5q-59 0 -139 74q-51 51 -99 51q-88 0 -157.5 -98.5t-69.5 -235.5q0 -145 71.5 -234t180.5 -89q131 0 215 122q25 41 61 33q25 -14 33 -39q6 -20 -10 -47q-117 -180 -291 -213 l-31 -57q-2 -2 -6 -4q61 -14 103.5 -63.5t42.5 -114.5q0 -84 -64.5 -145.5t-150.5 -61.5q-49 0 -93 14q-16 6 -21 25.5t3 38.5l4 4q2 4 4 6q12 27 66 16q6 -2 16 -2q33 0 59.5 21.5t26.5 50.5q0 45 -43 52t-96 -36q-16 -16 -44 -0.5t-11 43.5l120 201q6 8 -2 8 q-154 12 -251 133t-97 295z" /> -<glyph unicode="è" horiz-adv-x="874" d="M43 418q0 199 123 333t309 134q215 0 305 -185q31 -66 56 -96q12 -25 2 -51.5t-47 -28.5q-147 -6 -523 0q-27 0 -26 -57q0 -145 77.5 -237.5t194.5 -92.5q129 0 231 119q20 25 50 16q23 -4 34 -27.5t-2 -45.5q-201 -229 -393 -230q-168 0 -279.5 131t-111.5 318z M252 1272q-20 29 0 51.5t45 22.5l152 2q45 0 57 -29q53 -147 100 -330q0 -39 -36 -44t-52 13q-113 147 -266 314zM266 637q6 -8 25 -8h276l25 2q-43 151 -162 151q-111 0 -164 -145z" /> -<glyph unicode="é" horiz-adv-x="874" d="M43 418q0 201 123 334t309 133q215 0 305 -185q37 -72 56 -96q12 -25 2 -51.5t-47 -28.5q-147 -6 -523 0q-27 0 -26 -57q0 -145 77.5 -237.5t194.5 -92.5q129 0 231 119q20 25 50 16q23 -4 34 -27.5t-2 -45.5q-201 -229 -393 -230q-168 0 -279.5 131t-111.5 318zM266 637 q6 -8 25 -8h276l25 2q-43 151 -162 151q-111 0 -164 -145zM344 987l98 326q12 41 56 41h176q23 0 38 -9.5t11 -31.5q0 -15 -8 -21l-285 -342q-16 -23 -56 -12.5t-30 49.5z" /> -<glyph unicode="ê" horiz-adv-x="874" d="M43 418q0 199 123 333t309 134q215 0 305 -185q33 -70 56 -96q12 -25 2 -51.5t-47 -28.5q-147 -6 -523 0q-27 0 -26 -57q0 -145 77.5 -237.5t194.5 -92.5q129 0 231 119q20 25 50 16q23 -4 34 -27.5t-2 -45.5q-201 -229 -393 -230q-168 0 -279.5 131t-111.5 318z M184 1001l181 297q12 16 38 29q12 2 62.5 3t73.5 -1q33 -2 49 -29l178 -290q19 -44 -16 -54q-37 -10 -58 9l-221 186l-207 -186q-16 -12 -38.5 -11.5t-37 15t-4.5 32.5zM266 635q6 -8 25 -6h276l25 2q-43 151 -162 151q-111 0 -164 -147z" /> -<glyph unicode="ë" horiz-adv-x="874" d="M43 418q0 199 123 333t309 134q215 0 305 -187q35 -72 56 -94q23 -78 -45 -80q-147 -6 -523 0q-27 0 -26 -57q0 -145 77.5 -237.5t194.5 -92.5q129 0 231 119q20 25 50 16q23 -4 34 -27.5t-2 -45.5q-201 -229 -393 -230q-168 0 -279.5 130t-111.5 319zM172 1092 q0 53 40 93t97 40q55 0 95 -40t40 -93q0 -57 -40 -96.5t-95 -39.5q-57 0 -97 39t-40 97zM266 635q6 -8 25 -6h276l25 2q-43 151 -162 151q-111 0 -164 -147zM508 1092q0 53 40 93t95 40q57 0 96 -39t39 -94.5t-39 -95.5t-96 -40q-55 0 -95 39t-40 97z" /> -<glyph unicode="ì" horiz-adv-x="559" d="M39 45q-4 55 35 57q96 8 110 31q8 14 9 45v23.5v34v32.5v357q0 70 -5 77q-2 2 -8 4.5t-13 4.5t-9 2q-43 8 -82 22q-25 10 -24 43t20 45q111 43 241 86q78 25 78 -69v-572q0 -74 2 -102q2 -43 13.5 -50t60.5 -7q51 4 57 -41v-37q0 -41 -51 -37q-96 6 -395 0 q-14 0 -25.5 16.5t-13.5 34.5zM62.5 1323.5q19.5 22.5 43.5 22.5l148 2q39 0 55 -27q57 -154 97 -317q0 -39 -37 -42t-47 13q-74 98 -259 301q-20 25 -0.5 47.5z" /> -<glyph unicode="í" horiz-adv-x="559" d="M39 45q-4 55 35 57q96 8 110 31q8 14 9 45v23.5v34v32.5v357q0 70 -5 77q-2 2 -8 4.5t-13 4.5t-9 2q-43 8 -82 22q-25 10 -24 43t20 45q111 43 241 86q78 25 78 -69v-572q0 -74 2 -102q2 -43 13.5 -50t60.5 -7q51 4 57 -41v-37q0 -41 -51 -37q-96 6 -395 0 q-14 0 -25.5 16.5t-13.5 34.5zM160 1022l94 313q12 39 55 39h172q18 0 33.5 -8t13.5 -31q0 -12 -8 -20l-276 -330q-14 -23 -54 -12.5t-30 49.5z" /> -<glyph unicode="î" horiz-adv-x="559" d="M2 1083l180 297q12 16 39 29q12 2 62.5 3t72.5 -1q33 -2 50 -29l178 -290q18 -44 -17 -54q-37 -10 -57 9l-221 186l-207 -186q-16 -12 -39 -11.5t-37 15t-4 32.5zM39 45q-4 55 35 57q96 8 110 31q8 14 9 45v23.5v34v32.5v357q0 70 -5 77q-2 2 -8 4.5t-13 4.5t-9 2 q-43 8 -82 22q-25 10 -24 43t20 45q129 49 241 84q78 25 78 -67v-572q0 -74 2 -102q2 -43 13.5 -50t60.5 -7q51 4 57 -41q0 -2 -1 -17.5t-1 -19.5h2q0 -41 -51 -37q-96 6 -395 0q-14 0 -25.5 16.5t-13.5 34.5z" /> -<glyph unicode="ï" horiz-adv-x="559" d="M-35 1161q0 53 41 92t98 39q59 0 100.5 -37.5t41.5 -93t-42 -93.5t-99.5 -38t-98.5 38t-41 93zM39 43q-2 20 6 38.5t29 20.5q96 8 110 31q8 14 9 45v23.5v34v32.5v355q0 72 -5 79q-2 2 -8 4.5t-13 4.5t-9 2q-43 8 -82 22q-25 10 -24 43t20 45q174 61 241 84q78 25 78 -67 v-572q0 -74 2 -102q2 -43 13.5 -50t60.5 -7q51 4 57 -41v-37q0 -41 -51 -37q-96 6 -395 0q-14 0 -25.5 16.5t-13.5 32.5zM315 1161.5q0 55.5 42 93t99.5 37.5t98.5 -39t41 -92t-41 -92t-98.5 -39t-99.5 38t-42 93.5z" /> -<glyph unicode="ð" horiz-adv-x="1116" d="M84 436q0 199 136 335t335 136q70 0 129 -20l8 -2q0 14 -47 90q-43 61 -108 121q-23 23 -56 6l-256 -133q-39 -12 -59 26q-23 49 22 74l220 115q8 4 0 8q-58 34 -132 59q-18 6 -33.5 24.5t-0.5 41.5l14 26q27 43 76 31q158 -47 250 -98l180 88q51 14 72 -23 q29 -49 -78 -102q-4 -2 -6 -2q-47 -20 -52 -23q-14 -10 0 -18q61 -45 122 -118.5t102 -145.5q119 -209 118 -440q0 -274 -153 -408q-135 -119 -322 -119q-211 0 -346 133t-135 338zM299 504q0 -182 86 -304t205 -122q100 0 166.5 81t66.5 212q0 184 -86 303t-209 119 q-94 0 -161.5 -82t-67.5 -207z" /> -<glyph unicode="ñ" horiz-adv-x="1062" d="M33 45q0 25 2 33q14 20 35 20h10q59 0 76.5 29t17.5 154v268q0 131 -6 149q-6 8 -64 19l-41 8q-31 8 -26.5 47t24.5 47q84 27 177 64q47 16 63 20q39 8 55.5 -4t16.5 -49v-86q0 -14 2 -16.5t12 4.5q188 127 293 127q244 0 244 -373q0 -59 -8.5 -177t-8.5 -177 q0 -33 12.5 -41.5t61.5 -8.5q33 10 55 -14q10 -12 8 -45t-22 -43q-8 -4 -31 -4q-49 0 -187 1t-192 -1q-31 -2 -40 7t-11 36q0 63 35 63h12q59 4 78 21.5t25 69.5q12 113 12 342q0 197 -125 196q-80 0 -225 -104v-432q0 -66 15 -79.5t85 -13.5q31 0 37 -36q0 -41 -6 -54 q-6 -14 -41 -18q-59 2 -195.5 0t-195.5 2q-29 2 -35 16q-4 8 -4 33zM182 1028q6 135 60.5 212t156.5 77q86 0 209 -82q74 -51 107 -51q25 0 35 21.5t11 48t15.5 49t42.5 24.5q43 0 45 -29q4 -14 4 -30q0 -113 -60.5 -190t-158.5 -77q-88 0 -205 82q-78 53 -106 54 q-18 0 -29.5 -13.5t-23.5 -62.5q0 -6 -3 -18.5t-3 -20.5q-12 -23 -50.5 -28t-46.5 34z" /> -<glyph unicode="ò" horiz-adv-x="1024" d="M41 430q0 199 135 332t336 133q203 0 341 -134t136 -333q-2 -193 -138 -326t-333 -133q-203 0 -340 132t-137 329zM258 496q0 -176 85 -294t200 -118q94 0 159.5 83t65.5 214q0 166 -86 283.5t-199 117.5q-94 0 -159.5 -80.5t-65.5 -205.5zM327.5 1341.5 q22.5 24.5 45.5 24.5l155 2q39 0 58 -27q53 -141 98 -329q4 -41 -34 -46t-52 13q-129 166 -270 313q-23 25 -0.5 49.5z" /> -<glyph unicode="ó" horiz-adv-x="1024" d="M41 432q0 199 135 331t336 132q203 0 341 -133t136 -332q-2 -195 -137 -328t-334 -133q-203 0 -340 132t-137 331zM258 496q0 -176 85 -294t200 -118q94 0 159.5 83t65.5 214q0 166 -86 283.5t-199 117.5q-94 0 -159.5 -80.5t-65.5 -205.5zM428 1028l98 328q20 39 56 39 h178q23 0 38 -10.5t11 -30.5q0 -2 -2 -6v-5v-2l-291 -352q-20 -20 -59 -10t-29 49z" /> -<glyph unicode="ô" horiz-adv-x="1024" d="M41 428q0 199 134 329t337 130t341 -132t136 -329q-2 -193 -137 -325t-334 -132q-203 0 -340 132t-137 327zM223 1020l180 297q12 16 39 29q12 2 62.5 3t73.5 -1q33 -2 49 -29l178 -291q20 -45 -17 -53q-37 -10 -57 8l-221 186l-207 -186q-16 -12 -38.5 -11t-37 15 t-4.5 33zM258 489q0 -172 85 -288.5t200 -116.5q94 0 159.5 82t65.5 213q0 164 -86 279.5t-199 115.5q-94 0 -159.5 -80t-65.5 -205z" /> -<glyph unicode="õ" horiz-adv-x="1024" d="M41 428q0 197 135 328t336 131q203 0 341 -133t136 -328q-2 -193 -137 -325t-334 -132q-203 0 -340 132t-137 327zM188 991q14 274 215 275q86 0 207 -78q72 -47 105 -47q25 0 36 20.5t12 45t13 46t41 23.5q43 0 47 -27q4 -14 4 -28q0 -109 -60.5 -183.5t-156.5 -74.5 q-86 0 -205 77q-80 53 -104 54q-18 0 -29.5 -13.5t-21.5 -56.5q0 -6 -4 -18.5t-4 -18.5q-12 -23 -49 -27t-46 31zM258 489q0 -172 85 -288.5t200 -116.5q94 0 159.5 81t65.5 212q0 166 -86 281.5t-199 115.5q-94 0 -159.5 -80t-65.5 -205z" /> -<glyph unicode="ö" horiz-adv-x="1024" d="M41 430q0 199 135 331t336 132q203 0 341 -134t136 -331q-2 -195 -137 -327t-334 -132q-203 0 -340 132t-137 329zM215 1092q0 53 40 93t95.5 40t95 -40t39.5 -93q0 -57 -39.5 -96.5t-95 -39.5t-95.5 39t-40 97zM258 494q0 -174 85 -292t200 -118q94 0 159.5 83t65.5 214 q0 164 -86 280.5t-199 116.5q-94 0 -159.5 -80t-65.5 -204zM551 1092q0 53 40 93t95 40q57 0 97 -39t40 -94.5t-40 -95.5t-97 -40q-55 0 -95 39t-40 97z" /> -<glyph unicode="÷" horiz-adv-x="1431" d="M141 651v70q0 57 70 57h1026h23.5t14.5 -3t9 -5t3 -11t2 -18.5t0 -30t3 -40.5q2 -37 -12 -49.5t-49 -12.5h-1018q-72 0 -72 43zM608 283q0 45 32 74.5t77 29.5t75.5 -29.5t30.5 -74.5q0 -43 -30.5 -74t-75.5 -31q-43 0 -76 31t-33 74zM608 1116q2 41 35 68.5t74 27.5 q43 0 74.5 -29.5t31.5 -72.5t-31.5 -73.5t-74.5 -30.5q-45 0 -77 32.5t-32 77.5z" /> -<glyph unicode="ø" horiz-adv-x="1116" d="M82 420q0 201 138 334t343 133q137 0 256 -70q16 -8 23 0l4 4l84 94q25 31 53 3q8 -8 27 -29q16 -20 -9 -49q-6 -6 -10 -11q-27 -29 -65 -75q-10 -13 4 -27q115 -131 114 -303q0 -197 -137 -329t-338 -132q-147 0 -272 78q-2 0 -4 -2l-109 -133q-33 -29 -61 0l-21 16 q-27 20 4 60q61 72 97 108q12 14 0 27q-121 127 -121 303zM307 483q0 -113 37 -200q10 -16 23 -4l344 389q8 12 -2 22q-78 84 -174.5 84t-162 -81t-65.5 -210zM418 178q-6 -10 4 -20q74 -80 170 -80t163.5 83t67.5 214q0 100 -41 190q-6 20 -16 8z" /> -<glyph unicode="ù" horiz-adv-x="1093" d="M44 780.5q-7 18.5 0 40t34 27.5q25 6 110.5 30.5t126.5 32.5q29 6 43.5 -12t14.5 -39v-481q0 -152 30.5 -197t118.5 -45q82 0 203 92q0 2 2 7.5t3 9.5t1 8v336v45q0 102 -49 113q-20 4 -58 10t-57 8q-23 12 -22.5 48t28.5 42q227 49 295 57q63 4 64 -51v-626v-62 q0 -18 11 -24.5t19.5 -4.5t28.5 7q6 2 20.5 6t20.5 6q27 4 39 -19.5t5 -51t-29 -32.5q-117 -50 -230 -73q-82 -18 -84 47q0 2 -1 12t-2 28.5t-1 28.5q0 18 -18 5q-59 -41 -92 -62.5t-91.5 -44t-111.5 -22.5q-125 0 -186.5 77.5t-61.5 212.5v416q0 27 -5 36t-24 15 q-14 4 -40.5 11.5t-39.5 11.5q-8 2 -15 20.5zM330.5 1382.5q21.5 24.5 46.5 24.5l153 2q41 0 58 -27q59 -156 100 -329q2 -41 -36 -46t-50 13q-98 129 -270 313q-23 25 -1.5 49.5z" /> -<glyph unicode="ú" horiz-adv-x="1093" d="M44 780.5q-7 18.5 0 40t34 27.5q25 6 110.5 30.5t126.5 32.5q29 6 43.5 -12t14.5 -39v-481q0 -152 30.5 -197t118.5 -45q82 0 203 92q0 2 2 7.5t3 9.5t1 8v336v45q0 102 -49 113q-20 4 -58 10t-57 8q-23 12 -22.5 48t28.5 42q227 49 295 57q63 4 64 -51v-626v-62 q0 -18 11 -24.5t19.5 -4.5t28.5 7q6 2 20.5 6t20.5 6q27 4 39 -19.5t5 -51t-29 -32.5q-117 -50 -230 -73q-82 -18 -84 47q0 2 -1 12t-2 28.5t-1 28.5q0 18 -18 5q-59 -41 -92 -62.5t-91.5 -44t-111.5 -22.5q-125 0 -186.5 77.5t-61.5 212.5v416q0 27 -5 36t-24 15 q-14 4 -40.5 11.5t-39.5 11.5q-8 2 -15 20.5zM424 1049l98 327q20 39 58 39h178q23 0 38 -10t11 -31v-6l-2 -4v-2l-293 -350q-18 -23 -59 -12.5t-29 49.5z" /> -<glyph unicode="û" horiz-adv-x="1093" d="M44 780.5q-7 18.5 0 40t34 27.5q25 6 110.5 30.5t126.5 32.5q29 6 43.5 -12t14.5 -39v-481q0 -152 30.5 -197t118.5 -45q82 0 203 92q0 2 2 7.5t3 9.5t1 8v336v45q0 102 -49 113q-20 4 -58 10t-57 8q-23 12 -22.5 48t28.5 42q227 49 295 57q63 4 64 -51v-626v-62 q0 -18 11 -24.5t19.5 -4.5t28.5 7q6 2 20.5 6t20.5 6q27 4 39 -19.5t5 -51t-29 -32.5q-117 -50 -230 -73q-82 -18 -84 47q0 2 -1 12t-2 28.5t-1 28.5q0 18 -18 5q-59 -41 -92 -62.5t-91.5 -44t-111.5 -22.5q-125 0 -186.5 77.5t-61.5 212.5v416q0 27 -5 36t-24 15 q-14 4 -40.5 11.5t-39.5 11.5q-8 2 -15 20.5zM236 1061l180 297q12 16 39 28q12 2 62 3.5t73 -0.5q33 -2 49 -29l178 -291q21 -45 -16 -53q-37 -10 -58 8l-221 186l-207 -186q-16 -12 -38.5 -11t-37 15t-3.5 33z" /> -<glyph unicode="ü" horiz-adv-x="1093" d="M44 780.5q-7 18.5 0 40t34 27.5q25 6 110.5 30.5t126.5 32.5q29 6 43.5 -12t14.5 -39v-481q0 -152 30.5 -197t118.5 -45q82 0 203 92q0 2 2 7.5t3 9.5t1 8v336v45q0 102 -49 113q-20 4 -58 10t-57 8q-23 12 -22.5 48t28.5 42q227 49 295 57q63 4 64 -51v-626v-62 q0 -18 11 -24.5t19.5 -4.5t28.5 7q6 2 20.5 6t20.5 6q27 4 39 -19.5t5 -51t-29 -32.5q-117 -50 -230 -73q-82 -18 -84 47q0 2 -1 12t-2 28.5t-1 28.5q0 18 -18 5q-59 -41 -92 -62.5t-91.5 -44t-111.5 -22.5q-125 0 -186.5 77.5t-61.5 212.5v416q0 27 -5 36t-24 15 q-14 4 -40.5 11.5t-39.5 11.5q-8 2 -15 20.5zM256 1153q0 53 40 93t95 40q57 0 97 -40t40 -93q0 -57 -40 -96t-97 -39q-55 0 -95 39t-40 96zM592 1153q0 53 40 93t97 40t96 -39t39 -94t-39 -95t-96 -40t-97 39t-40 96z" /> -<glyph unicode="ý" horiz-adv-x="1003" d="M19.5 786.5q-9.5 24.5 1 48t42.5 23.5h25h338q35 0 45 -23.5t1 -49t-28 -29.5q-43 0 -61 -6q-35 -10 2 -82q27 -61 53.5 -127t58 -150t50.5 -129q8 -20 22 17l101 272q47 121 47 156q0 29 -17.5 39t-83.5 10q-20 10 -23 51t30 49h20q61 0 154.5 1t146.5 1q35 0 45 -30.5 t-2 -53.5q-6 -14 -29 -18q-51 -4 -84.5 -47t-91.5 -197l-243 -664q-49 -133 -86 -213q-31 -70 -74 -127q-43 -49 -117 -49q-45 0 -82 36t-37 81q0 70 119 105q25 6 45.5 15t35.5 25.5t27.5 26.5t22.5 36t16.5 36t13.5 43t8 40t8 45t7 42l-243 592q-51 125 -72.5 147.5 t-85.5 28.5q-16 4 -25.5 28.5zM385 1047l98 329q20 39 58 39h178q23 0 38 -11t11 -32q-2 -2 -2 -8l-2 -2l-291 -354q-18 -23 -59 -11.5t-29 50.5z" /> -<glyph unicode="þ" horiz-adv-x="1071" d="M4 -463q2 33 10.5 45t42.5 15q33 0 55.5 9t34 19t16.5 34t5 37t-1 46t-1 45v1307v53q0 25 -6 32t-31 13q-10 2 -27.5 7t-26.5 8t-19.5 10.5t-14.5 17.5t-4 41q-2 20 16 33l13 6l219 135q35 23 60.5 10.5t25.5 -61.5v-570q0 -39 6 -38q4 0 10 4q176 119 272 118 q139 0 240.5 -129t101.5 -297q0 -201 -141 -350t-334 -149q-72 0 -141 22q-6 2 -10 -3t-4 -15v-205q0 -131 19.5 -164t88.5 -29q53 4 68.5 -6t17.5 -61q2 -25 -11 -34t-42 -9q-319 6 -459 0q-29 -2 -40 12.5t-9 40.5zM371 213q106 -96 213 -96q88 0 150.5 81t62.5 212 q0 145 -71 240t-169 95q-86 0 -186 -86v-446z" /> -<glyph unicode="ÿ" horiz-adv-x="1011" d="M19.5 786.5q-9.5 24.5 1 48t42.5 23.5h25h338q35 0 45 -23.5t1 -49t-28 -29.5q-43 0 -61 -6q-35 -10 2 -82q27 -61 53.5 -127t58 -150t50.5 -129q8 -20 22 17l101 272q47 121 47 156q0 29 -17.5 39t-83.5 10q-20 10 -23 51t30 49h20q61 0 154.5 1t146.5 1q35 0 45 -30.5 t-2 -53.5q-6 -14 -29 -18q-51 -4 -84.5 -47t-91.5 -197l-243 -664q-49 -133 -86 -213q-31 -70 -74 -127q-43 -49 -117 -49q-45 0 -82 36t-37 81q0 70 119 105q25 6 45.5 15t35.5 25.5t27.5 26.5t22.5 36t16.5 36t13.5 43t8 40t8 45t7 42l-243 592q-51 125 -72.5 147.5 t-85.5 28.5q-16 4 -25.5 28.5zM207 1143q0 57 42 99t101.5 42t100.5 -42t41 -99q0 -59 -41 -100.5t-100.5 -41.5t-101.5 41t-42 101zM563 1142.5q0 57.5 42 99.5t100 42q59 0 101 -41t42 -100.5t-42 -100.5t-101 -41q-57 0 -99.5 42t-42.5 99.5z" /> -<glyph unicode="Œ" horiz-adv-x="2121" d="M100 657q0 203 111 375t293 258q145 70 352 70q76 0 227 -8q100 -6 113 -6q6 0 39 1t72 1h581q31 0 45.5 -11.5t16.5 -42.5q4 -23 8 -127t2 -147q0 -18 -35 -19h-37q-18 2 -28 37l-11 39q-23 94 -43 112.5t-96 18.5h-324q-43 0 -43 -22v-402q0 -23 37 -22h236 q92 0 115 18q16 18 28 103q0 6 3 15t13.5 17.5t24.5 8.5h29q20 0 26.5 -9.5t10.5 -31.5q-2 -51 -1 -190.5t1 -180.5q0 -51 -29 -51h-37q-41 0 -41 47q-8 78 -28.5 96.5t-96.5 18.5h-272q-18 0 -19 -50v-409q0 -10 11.5 -21.5t23.5 -11.5h289q115 0 148.5 8t60.5 41 q55 66 66 146q4 35 43 34h22q37 0 37 -53q-2 -72 -29 -260q-4 -27 -19.5 -39t-28.5 -14t-38 -2q-121 0 -356.5 1t-358.5 1q-70 0 -205 -9.5t-202 -9.5q-291 0 -499 199t-208 483zM367 698q0 -260 139 -432t340 -172q102 0 174 53q47 37 60.5 90.5t13.5 231.5v563 q0 111 -62.5 163t-202.5 52q-217 0 -339.5 -143t-122.5 -406z" /> -<glyph unicode="œ" horiz-adv-x="1587" d="M86 420q0 190 140.5 326.5t338.5 136.5q190 0 301 -129q0 -4 6 6q123 123 297 123q231 0 314 -203q20 -51 57 -84v-39q0 -41 -47 -41h-481q-37 0 -37 -22q4 -162 77.5 -267.5t170.5 -105.5q80 0 219 131q31 31 55 0q25 -25 27 -31q8 -20 -15 -43q-76 -86 -174 -149 q-102 -63 -205 -64q-149 0 -243 129q-121 -129 -318 -129q-205 0 -344 130t-139 325zM307 477q0 -162 87 -278.5t194 -116.5q86 0 138 73.5t52 217.5q0 182 -73 290.5t-177 108.5q-90 0 -155.5 -83t-65.5 -212zM991 639q-4 -18 19 -18h250q20 0 20 4q-8 74 -48 116.5 t-93 42.5q-113 0 -148 -145z" /> -<glyph unicode="Ÿ" horiz-adv-x="1490" d="M23 1253q-4 16 0 37q10 47 45 41q389 -6 540 0q23 0 37 -26.5t4 -54t-47 -27.5q-59 0 -74 -2q-31 -6 -18 -41q10 -25 47 -82l254 -383q6 -10 7 -12.5t6 -5.5t10.5 2.5t11.5 15.5l217 358q55 92 55 121q0 18 -15.5 24.5t-72.5 6.5h-24q-14 6 -23.5 32.5t0.5 51t45 22.5 q172 -6 436 0q41 0 41 -51q0 -53 -39 -53q-31 -2 -56.5 -8.5t-48 -21.5t-35.5 -24.5t-33.5 -37t-26.5 -36.5t-27.5 -46t-26.5 -43l-297 -494v-299q0 -57 30 -77.5t91 -24.5q53 0 64 -6q20 -10 20 -62q0 -55 -45 -55q-393 6 -553 2q-39 0 -53 26q-10 29 -2 60q8 20 22.5 29.5 t25.5 9.5t34.5 -1t34.5 -1q45 2 63.5 26.5t22.5 75.5q8 141 2 273l-367 563q-70 109 -109.5 137.5t-123.5 32.5q-41 0 -49 28zM483 1587q0 57 42 99.5t101.5 42.5t101.5 -41t42 -100.5t-42 -100.5t-101.5 -41t-101.5 41t-42 100zM842 1587.5q0 59.5 42 100.5t101 41t100 -41 t41 -100.5t-41 -100.5t-100 -41t-101 41t-42 100.5z" /> -<glyph unicode="ˆ" horiz-adv-x="714" d="M59 1012l177 284q10 16 38 29q14 2 74 3t82 -1q33 -2 49 -29l174 -278q19 -41 -16 -51q-35 -8 -57 8l-228 178l-213 -178q-29 -25 -67 -2q-27 14 -13 37z" /> -<glyph unicode="˜" horiz-adv-x="714" d="M18 983q14 262 215 262q80 0 207 -76q72 -45 105 -45q25 0 36 19.5t12 43t13 44t41 22.5q43 0 47 -26q4 -12 4 -27q0 -102 -60.5 -173t-156.5 -71q-86 0 -205 72q-84 53 -104 53q-18 0 -29.5 -12t-21.5 -55q0 -6 -3 -17.5t-5 -17.5q-4 -27 -46 -30t-49 34z" /> -<glyph unicode=" " horiz-adv-x="960" /> -<glyph unicode=" " horiz-adv-x="1921" /> -<glyph unicode=" " horiz-adv-x="960" /> -<glyph unicode=" " horiz-adv-x="1921" /> -<glyph unicode=" " horiz-adv-x="640" /> -<glyph unicode=" " horiz-adv-x="480" /> -<glyph unicode=" " horiz-adv-x="320" /> -<glyph unicode=" " horiz-adv-x="320" /> -<glyph unicode=" " horiz-adv-x="240" /> -<glyph unicode=" " horiz-adv-x="384" /> -<glyph unicode=" " horiz-adv-x="106" /> -<glyph unicode="‐" horiz-adv-x="890" d="M82 446v58q0 23 20.5 33t38.5 10h629q20 0 35.5 -13.5t13.5 -29.5l-4 -53q-8 -33 -41 -37q-309 -4 -651 0q-29 0 -41 32z" /> -<glyph unicode="‑" horiz-adv-x="890" d="M82 446v58q0 23 20.5 33t38.5 10h629q20 0 35.5 -13.5t13.5 -29.5l-4 -53q-8 -33 -41 -37q-309 -4 -651 0q-29 0 -41 32z" /> -<glyph unicode="‒" horiz-adv-x="890" d="M82 446v58q0 23 20.5 33t38.5 10h629q20 0 35.5 -13.5t13.5 -29.5l-4 -53q-8 -33 -41 -37q-309 -4 -651 0q-29 0 -41 32z" /> -<glyph unicode="–" horiz-adv-x="1249" d="M74 471v22.5t2 22.5q4 35 37 39q504 -4 1026 0q41 0 41 -37v-55q-6 -29 -47 -29q-512 4 -1022 0q-16 0 -26.5 11.5t-10.5 25.5z" /> -<glyph unicode="—" horiz-adv-x="1751" d="M166 446q2 16 2 58q4 35 57 35q639 -4 1297 0q39 -8 45 -21q8 -16 2 -86q-14 -20 -49 -20q-391 -4 -1301 0q-53 0 -53 34z" /> -<glyph unicode="‘" horiz-adv-x="557" d="M135 1116q0 98 66.5 180t173.5 121q20 8 38.5 -5t17.5 -37.5t-25 -43.5q-131 -74 -132 -164q0 -8 21 -2q6 2 20 2q49 0 80 -33.5t31 -82.5q0 -53 -38 -89t-91 -36q-72 0 -117 56t-45 134z" /> -<glyph unicode="’" horiz-adv-x="557" d="M135 1296q0 53 38 89t93 36q72 0 115 -53t43 -133q0 -90 -56.5 -169t-150.5 -124q-57 -27 -78 16q-14 37 17 58q133 80 133 162v8v2q-29 -8 -43 -8q-49 0 -80 33.5t-31 82.5z" /> -<glyph unicode="‚" horiz-adv-x="526" d="M127 49q0 49 37 83t88 34q68 0 108.5 -52.5t40.5 -125.5q0 -92 -59 -170t-158 -117q-37 -14 -49 33q-4 33 12 41l9 6q111 66 114 158q1 6 -22 0h-17q-45 0 -74.5 31.5t-29.5 78.5z" /> -<glyph unicode="“" horiz-adv-x="1028" d="M154 1110q0 94 64.5 176t170.5 123q29 12 51.5 -3t21.5 -37.5t-20 -37.5q-139 -78 -139 -164q0 -4 12 -4q25 4 33 4q49 0 83 -33.5t34 -82.5q0 -53 -41 -89t-96 -36q-76 0 -125 53t-49 131zM600 1110q0 94 64.5 176t171.5 123q45 16 65 -6q10 -14 10 -37t-22 -35 q-139 -74 -139 -164q0 -6 12 -6q4 0 15 3t18 3q51 0 83.5 -33.5t32.5 -82.5q0 -53 -40 -89t-97 -36q-76 0 -125 54t-49 130z" /> -<glyph unicode="”" horiz-adv-x="1026" d="M168 1296q0 51 37 86t88 35q68 0 108.5 -53t40.5 -127q0 -92 -59 -171t-158 -118q-37 -12 -49 33q-4 35 12 41l9 6q111 68 114 158q1 6 -22 0h-17q-45 0 -74.5 32.5t-29.5 77.5zM608 1290q0 51 37 86t88 35q68 0 109 -54t41 -128q0 -92 -59.5 -170t-157.5 -117 q-37 -14 -50 33q-4 33 13 41l8 6q111 66 115 158q0 6 -23 0h-16q-45 0 -75 31.5t-30 78.5z" /> -<glyph unicode="„" horiz-adv-x="968" d="M147 49q0 49 37 83t88 34q68 0 109 -52.5t41 -125.5q0 -92 -59.5 -170t-157.5 -117q-37 -14 -49 33q-4 33 12 41l8 6q111 66 115 158q0 6 -23 0h-16q-45 0 -75 31.5t-30 78.5zM569 49q0 49 37 83t88 34q68 0 110 -52.5t42 -125.5q0 -92 -60.5 -170t-158.5 -117 q-33 -14 -49 33q-4 31 12 41l10 6q111 66 113 158q0 6 -23 0h-14q-45 0 -76 31.5t-31 78.5z" /> -<glyph unicode="•" horiz-adv-x="759" d="M143 671.5q0 96.5 69 164t169 67.5t168.5 -67.5t68.5 -164t-68.5 -164t-168.5 -67.5t-169 67.5t-69 164z" /> -<glyph unicode="…" horiz-adv-x="2215" d="M256 86q0 53 39 87t98.5 34t95 -37t35.5 -90q0 -49 -36 -82t-95 -33q-61 0 -99 34t-38 87zM987 78q0 55 37 91t96.5 36t97 -37t37.5 -90q0 -51 -37 -82t-96 -31q-61 0 -98 31t-37 82zM1712 86q0 53 35 87t94.5 34t96 -37t36.5 -90q0 -51 -35 -83t-96 -32q-59 0 -95 35 t-36 86z" /> -<glyph unicode=" " horiz-adv-x="384" /> -<glyph unicode="‹" horiz-adv-x="1802" d="M44 16.5q-11 26.5 0 54t42 29.5h20q70 0 86.5 16.5t16.5 88.5v481q0 4 -5 9t-7 5h-88q-49 0 -62 29q-10 39 4 66q4 12 35 18q88 18 125 39q8 102 12 139t23.5 97.5t55.5 102.5t101 101q72 66 174.5 109t221.5 42t200 -67q29 -33 56 -14q78 55 168 88t192.5 26.5 t173.5 -67.5q41 -31 41 -80q0 -31 -48 -70.5t-81 -39.5q-27 0 -55.5 27.5t-71.5 55t-106 27.5q-76 0 -142.5 -55t-85.5 -133q-12 -53 -12 -236q0 -27 14 -31q92 -8 351 3q86 2 172 32q27 8 46 -17.5t19 -51.5v-643q0 -63 13.5 -78t64.5 -15q43 8 55.5 -18.5t2 -58 t-24.5 -35.5q-193 6 -428 0q-16 0 -26.5 17.5t-10.5 35.5q0 16 2 28.5t15.5 22.5t37.5 8q57 0 72.5 11.5t17.5 62.5v105v307q0 68 -18.5 98.5t-73.5 32.5q-2 0 -132 2t-146 0q-16 -4 -21 -21l-2 -419q0 -125 12 -148q14 -31 90 -31h39q25 0 37.5 -10t14.5 -20.5t2 -28.5 t-10.5 -35.5t-22.5 -17.5q-242 4 -483 -2q-39 0 -39 51q0 45 34 59h19q70 0 81 22.5t11 156.5v399q-4 31 -16 33q-70 4 -192 4t-167 -6q-10 0 -12 -25q0 -51 -1 -151.5t-1 -184.5t2 -155q2 -57 17.5 -72t78.5 -15q45 0 68 -4q37 -14 29.5 -64t-37.5 -48q-256 10 -502 0 q-25 0 -36 26.5zM426 887q0 -6 6 -15.5t12 -9.5q164 -10 353 4q20 0 20 80q6 154 57 246q0 6 -8 16q-8 12 -20 21q-74 66 -182 65q-76 0 -141.5 -54t-84.5 -132q-12 -57 -12 -221z" /> -<glyph unicode="›" horiz-adv-x="1761" d="M43 22.5q-8 34.5 8 59.5q6 12 27 16q12 4 33.5 4h27.5q43 2 57.5 18.5t14.5 84.5v471q0 4 -10.5 14t-14.5 10h-73q-49 0 -64 29q-4 45 6 66q4 6 33 18q84 16 123 41q14 172 35 238q33 88 160 200q74 66 173 110t213.5 43t194.5 -69q25 -20 27 -18q119 100 264 100 q20 0 63 -5t66 -5q43 0 80 43q29 14 63.5 6t34.5 -37v-1265q0 -8 -1 -26.5t0 -26t4 -18.5t13.5 -15.5t26.5 -4.5q10 -2 29.5 -2h25.5q27 -4 37 -28q8 -29 0 -56q-8 -24 -28 -26h-19q-182 8 -407 0q-31 0 -39 26q-8 29 0 48q8 25 24 32q10 4 35 3t39 1q37 2 44 28t7 153 l2 407q0 29 -30 29q-264 6 -318 0q-16 -2 -22 -31v-493q0 -66 15 -82.5t79 -16.5q10 2 31 -2q31 -6 28.5 -55t-35.5 -47q-127 4 -432 0q-20 0 -30.5 24.5t-2 51t34.5 28.5q66 8 76 17q18 12 19 69q2 23 2 101v387q0 39 -35 39q-199 -4 -297 0q-10 0 -20.5 -11.5t-12.5 -27.5 v-389q0 -131 6 -146q8 -18 22.5 -27.5t32 -8.5t35.5 1q37 0 68 -6q31 -12 31 -59t-37 -45q-262 10 -510 0q-25 -2 -33 32.5zM428 879q0 -4 10.5 -10.5t16.5 -6.5q72 -4 309 0q27 0 29 8q2 4 2 11q10 162 67 284q10 23 -2 39q-2 2 -5 6t-8 8.5t-11 10.5q-43 43 -79 55t-93 12 q-76 0 -140.5 -54t-83.5 -132q-12 -57 -12 -231zM1008 891q0 -12 5 -15.5t25 -3.5h301q37 0 37 19v366q-102 66 -182 66q-61 0 -111 -66q-74 -104 -75 -366z" /> -<glyph unicode=" " horiz-adv-x="480" /> -<glyph unicode="€" d="M-6 485v25q0 47 33 47h94v68q0 49 2 73h-96q-23 0 -28 11.5t-5 40.5v24q0 47 33 47h110q41 219 159 354.5t269 135.5q82 0 185 -56q33 -18 45 0q8 10 34.5 7.5t28.5 -19.5q12 -135 12 -276q0 -35 -35.5 -42t-46.5 19q-47 254 -227 254q-190 0 -219 -377h346q33 0 33 -47 v-24q0 -51 -33 -52h-350v-34q0 -72 2 -107h348q33 0 33 -47v-25q0 -51 -33 -51h-336q23 -168 81.5 -262t150.5 -94q164 0 231 231q4 18 27.5 23.5t43 -6t15.5 -33.5q-18 -119 -80 -305q-23 8 -30 8q-39 0 -109 -16.5t-131 -16.5q-154 0 -266.5 124t-149.5 347h-108 q-33 0 -33 51z" /> -<glyph unicode="™" horiz-adv-x="2099" d="M25 1239l18 145q4 31 18.5 41.5t44.5 10.5q319 -8 680 0q37 2 54.5 -9.5t21.5 -50.5l17 -145v-19q2 -20 -3.5 -29t-13.5 -10.5t-31 -1.5h-49q-12 86 -46 114t-124 28h-10h-12t-10.5 -1t-8.5 -6.5t-2 -11.5v-526q0 -70 11 -82q12 -12 57 -16q23 -4 27 -6q16 -6 14 -49.5 t-35 -45.5h-25q-45 2 -108.5 2t-132 -1t-86.5 -1q-35 -2 -49.5 8.5t-14.5 40.5q0 16 1 22.5t7.5 15t20.5 12.5h12q43 6 52.5 20t9.5 78v530q0 16 -45 17q-86 0 -119 -28t-47 -114h-53q-33 0 -40.5 11.5t-0.5 56.5zM885 600v21q0 41 49 47q47 2 57 15t10 83v463q0 74 -9 89 t-56 15q-33 0 -45 19q-6 18 -6 37q0 47 49 47q162 -6 264 -2q35 2 55 -39l228 -467q4 -8 8 -12.5t6 -4.5h2l227 482q18 43 50 43h247q61 0 62 -50q0 -47 -31 -51q-8 -2 -22 -2q-41 -2 -50.5 -16t-9.5 -86v-463q0 -66 9.5 -81t54.5 -17q6 -2 16 -2q33 0 33 -54q0 -45 -53 -45 q-27 0 -105 1t-142.5 1t-103.5 -2q-72 -4 -71 39v31q0 31 39 31h18q45 4 56.5 18t11.5 78v336q0 10 -9 0q0 -2 -2 -4l-235 -494q-16 -35 -45 -35h-29q-20 0 -27 13l-6 14l-235 489q-8 20 -10 19.5t-2 -12.5v-324q0 -70 10 -85t53 -15h31q39 0 39 -31q0 -61 -27 -72h-22 q-43 14 -269 4q-63 -10 -63 31z" /> -<glyph unicode="◼" horiz-adv-x="849" d="M0 0v850h850v-850h-850z" /> -<glyph unicode="fi" horiz-adv-x="1144" d="M74 20q-20 47 24 70l49 8q41 4 48.5 24.5t7.5 123.5v413q0 12 -1 18.5t-4 9.5t-6.5 4t-11.5 1l-71 6q-20 10 -27.5 37t14.5 47q10 8 38 16.5t48.5 17.5t20.5 24q0 195 63 344q43 104 146.5 192t261.5 88q106 0 188 -51t82 -127q0 -51 -35 -77.5t-69 -26.5q-47 0 -74 41 q-37 63 -83 91.5t-81 28.5q-201 0 -201 -452q0 -35 5 -45q6 -12 28 -12q160 -6 342 4q57 2 109 10q51 20 73 -19q-8 -156 -8 -254v-329q0 -102 8.5 -123t49.5 -25l41 -6q35 -6 32 -47t-32 -53q-66 4 -195 4q-158 0 -178 -2q-33 0 -43 31q-16 57 41 69q4 0 13 2t13 2 q41 4 45 21q6 18 7 127v344q0 74 -10.5 89t-61.5 17q-131 4 -256 0q-14 -2 -18.5 -7t-4.5 -30v-413q0 -102 7.5 -124t46.5 -24l61 -6q37 -6 29 -49t-33 -51q-129 6 -215 6q-88 0 -172 -6q-39 -4 -51 28z" /> -<glyph unicode="fl" horiz-adv-x="1103" d="M40 47q-1 27 7 35q16 16 41 16q57 4 72 21q16 23 16 166v413q0 16 -16 21h-88q-23 0 -27 14q-14 29 -2 58q8 25 29 28l84 35q20 12 20 14q14 281 162 441q141 158 313 157q23 0 65 -5t62 -5q45 0 78 43q29 12 59.5 7t34.5 -23v-1278q0 -66 12.5 -84.5t65.5 -18.5 q8 2 35 -6q23 -4 25 -54t-33 -48h-408h-8q-37 0 -43 18q-16 39 2 72q8 14 41 14q82 0 94 22.5t12 162.5v403q0 14 -9 25.5t-17 11.5q-109 2 -301 -2q-8 0 -13.5 -1t-10.5 -9.5t-9 -24.5v-489q0 -66 15.5 -82.5t78.5 -16.5q14 4 27 -2q27 -4 28 -50t-26 -52h-14q-14 0 -93 2 t-161 2t-150 -4q-29 -2 -41 14q-8 12 -9 39zM385 895q0 -20 25 -21q55 -2 114.5 -2t120 1t82.5 1q14 0 18 37v349q-102 66 -176 65q-68 0 -112 -65q-70 -98 -72 -365z" /> -<glyph unicode="ffi" horiz-adv-x="1802" d="M44 16.5q-11 26.5 0 54t42 29.5h20q70 0 86.5 16.5t16.5 88.5v481q0 4 -5 9t-7 5h-88q-49 0 -62 29q-10 39 4 66q4 2 35 18q88 18 125 39q8 102 12 139t23.5 97.5t55.5 102.5t101 101q72 66 174.5 109t221.5 42t200 -67q29 -33 56 -14q78 55 168 88t192.5 26.5 t173.5 -67.5q41 -31 41 -80q0 -31 -48 -70.5t-81 -39.5q-27 0 -55.5 27.5t-71.5 55t-106 27.5q-76 0 -142.5 -55t-85.5 -133q-12 -53 -12 -236q0 -27 14 -31q92 -8 351 3q86 2 172 32q27 8 46 -17.5t19 -51.5v-643q0 -63 13.5 -78t64.5 -15q43 8 55.5 -18.5t2 -58 t-24.5 -35.5q-193 6 -428 0q-16 0 -26.5 17.5t-10.5 35.5q0 16 2 28.5t15.5 22.5t37.5 8q57 0 72.5 11.5t17.5 62.5v105v307q0 68 -18.5 98.5t-73.5 32.5q-2 0 -132 2t-146 0q-16 -4 -21 -21l-2 -419q0 -125 12 -148q14 -31 90 -31h39q25 0 37.5 -10t14.5 -20.5t2 -28.5 t-10.5 -35.5t-22.5 -17.5q-242 4 -483 -2q-39 0 -39 51q0 45 34 59h19q70 0 81 22.5t11 156.5v399q-4 31 -16 33q-70 4 -192 4t-167 -6q-10 0 -12 -25q0 -51 -1 -151.5t-1 -184.5t2 -155q2 -57 17.5 -72t78.5 -15q45 0 68 -4q37 -14 29.5 -64t-37.5 -48q-256 10 -502 0 q-25 0 -36 26.5zM426 887q0 -25 8 -25q174 -12 371 4q6 0 9 7.5t4 18.5t1 20.5t-1 20.5t-1 13q6 154 57 246q0 6 -8 16q-8 12 -20 21q-74 66 -182 65q-76 0 -141.5 -54t-84.5 -132q-12 -57 -12 -221z" /> -<glyph unicode="ffl" horiz-adv-x="1761" d="M40 63.5q9 26.5 38 34.5q12 4 33.5 4h27.5q43 2 57.5 19.5t14.5 83.5v485q0 10 -6 10h-92q-49 0 -64 29q-4 45 6 66q4 6 33 18q84 16 123 41q14 172 35 238q33 88 160 200q74 66 173 110t213.5 43t194.5 -69l12 -10q12 -10 15 -8q119 100 264 100q20 0 63 -5t66 -5 q43 0 80 43q29 14 63.5 6t34.5 -37v-1265q0 -70 6 -80q6 -8 24.5 -10.5t36 -1.5t31.5 -1q27 -4 37 -28q8 -29 0 -56q-8 -24 -28 -26h-19q-182 8 -407 0q-35 0 -43 26q-8 29 0 48q8 23 22.5 29.5t43 5.5t36.5 1q37 2 44 29t7 152l2 407q0 29 -16 29q-276 6 -332 0 q-16 -2 -22 -31v-493q0 -66 15 -82.5t79 -16.5q10 2 31 -2q31 -6 28.5 -55t-35.5 -47q-127 4 -432 0q-20 0 -30.5 24.5t-2 51t34.5 28.5q66 8 76 17q18 12 19 69q2 23 2 101v387q0 35 -9 37q-4 2 -10 2q-219 -6 -328 0q-16 0 -18 -19v-409q0 -131 6 -146q0 -2 4 -6l4 -6 l4 -6q4 -8 13 -13q20 -4 65 -4q18 4 68 -6q31 -12 31 -59t-37 -45q-262 10 -510 0q-23 0 -34 23.5t-2 50zM428 879q0 -16 12 -17q76 -4 324 0q27 0 29 8q2 4 2 11q10 162 67 284q10 23 -2 39q-2 2 -5 6t-8 8.5t-11 10.5q-43 43 -79 55t-93 12q-76 0 -140.5 -54t-83.5 -132 q-12 -57 -12 -231zM1008 891q0 -12 5 -15.5t25 -3.5h316q23 0 22 19v366q-102 66 -182 66q-61 0 -111 -66q-74 -104 -75 -366z" /> -</font> -</defs></svg> - \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.svg b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.svg @@ -1,244 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata></metadata> -<defs> -<font id="etbembodisplayitalic" horiz-adv-x="1390" > -<font-face units-per-em="2048" ascent="1638" descent="-410" /> -<missing-glyph horiz-adv-x="520" /> -<glyph horiz-adv-x="2048" /> -<glyph horiz-adv-x="2048" /> -<glyph unicode="
" horiz-adv-x="681" /> -<glyph unicode=" " horiz-adv-x="520" /> -<glyph unicode="	" horiz-adv-x="520" /> -<glyph unicode=" " horiz-adv-x="520" /> -<glyph unicode="!" horiz-adv-x="608" d="M178 72q0 10 2 16q6 49 34 80t69 31q37 0 60.5 -28t23.5 -73q0 -53 -30 -90t-73 -37q-39 0 -62.5 28t-23.5 73zM303 362l123 916q8 55 18.5 66.5t55.5 11.5h43q39 0 53 -7t14 -32q0 -14 -6 -37l-254 -918q-6 -12 -18.5 -15t-20.5 2t-8 13z" /> -<glyph unicode=""" horiz-adv-x="868" d="M344 745l33 310q18 176 52 238.5t114 62.5q35 0 57.5 -21.5t22.5 -56.5q0 -29 -15 -66q-6 -18 -71 -159l-140 -308h-53zM717 745l31 306l10 104q10 92 52 146.5t105 54.5q37 0 58.5 -20.5t21.5 -55.5q0 -53 -80 -229l-141 -306h-57z" /> -<glyph unicode="#" horiz-adv-x="1392" d="M90 373v116h232l81 394h-313v116h338l88 426h113l-88 -426h438l88 426h113l-88 -426h206v-116h-229l-82 -394h311v-116h-333l-84 -424h-117l90 424h-442l-84 -424h-115l86 424h-209zM434 492h443l79 391h-440z" /> -<glyph unicode="$" horiz-adv-x="966" d="M141 217q0 43 23.5 69.5t60.5 26.5q31 0 51.5 -22.5t20.5 -54.5q0 -12 -4 -41t-4 -43q0 -61 55 -105l109 524q8 39 -9 60q-125 131 -125 287q0 127 72 214t199 109l22 119q4 16 31 16q25 0 19 -18l-19 -94q-2 -8 4 -12.5t15 -4.5q37 0 53 -2q27 0 28 19l19 96q0 16 24 16 q10 0 17.5 -5t5.5 -13l-18 -98q-4 -25 18 -33q76 -27 119 -83t43 -136q0 -111 -70 -111q-31 0 -48 22.5t-17 57.5q0 25 12 78q0 2 1 10t1 12q0 53 -55 88q-12 8 -18.5 4t-10.5 -24l-107 -524q184 -176 185 -332q0 -127 -80 -211t-217 -105q-23 -4 -29 -34l-22 -119 q-4 -14 -29 -15q-10 0 -15.5 4.5t-2.5 10.5l22 121q0 25 -18 26q-25 0 -54 4q-12 -2 -24 -22l-31 -131q-6 -14 -29 -11q-8 2 -13 5.5t-3 9.5l33 166q-86 33 -138.5 94t-52.5 135zM395 59q0 -6 1 -13t1 -9t1 -5t4.5 -4t9.5 -3q37 -6 63 -7q6 0 8 4.5t5.5 13.5t7.5 15l82 400 q6 33 -9 49q-6 6 -15 16t-17.5 18.5t-16.5 14.5q-16 8 -28 -25zM430 973q0 -70 41 -139q25 -41 31 -15l67 324q4 23 1 28t-23 -4q-117 -66 -117 -194zM535 743q12 -14 34.5 -34.5t32.5 -32.5q18 -14 23 6l96 473q8 37 -14 39q-31 2 -62 0q-16 0 -22 -23zM545 46q0 -3 1 -8 t3 -7t6 0q70 25 112 82t42 131q0 84 -72 178q-14 14 -21 -6l-71 -353v-6v-11z" /> -<glyph unicode="%" horiz-adv-x="1497" d="M225 950q29 152 130.5 257.5t217.5 105.5q121 0 179.5 -107.5t29.5 -259.5q-29 -154 -129 -258t-217 -104q-121 0 -180 106.5t-31 259.5zM367 946q-59 -305 75 -305q140 0 197 309q59 305 -72 305q-139 0 -200 -309zM391.5 -30.5q-6.5 12.5 3.5 30.5q508 774 690 1047 q51 78 164 245q20 27 39 25l51 -4q14 -8 12 -19.5t-10 -17.5l-856 -1296q-18 -25 -41 -25h-28q-18 2 -24.5 14.5zM983 403q29 152 130 257.5t218 105.5q119 0 178.5 -107.5t30.5 -261.5q-29 -152 -129 -257t-217 -105q-121 0 -180.5 107.5t-30.5 260.5zM1124 397 q-59 -303 76 -303q140 0 197 309q59 305 -72 306q-139 0 -201 -312z" /> -<glyph unicode="&" horiz-adv-x="1474" d="M188 383q0 129 92.5 230.5t239.5 140.5q31 8 31 20q0 6 -6 8q-184 70 -185 226q0 150 139.5 250t340.5 100q68 0 144.5 -16.5t147 -66.5t70.5 -124q0 -29 -21.5 -49.5t-50.5 -20.5q-53 0 -81 76q-2 6 -5.5 20.5t-5.5 20.5q-25 98 -184 98q-141 0 -229 -86t-88 -229 q0 -82 39.5 -135t99.5 -53q6 0 23.5 2t31.5 2t29.5 -2t25 -11.5t9.5 -23.5q0 -20 -11.5 -30.5t-31 -12.5t-38 -1t-42 4t-31.5 3q-113 0 -187.5 -85t-74.5 -214q0 -172 113.5 -274.5t306.5 -102.5q164 0 319.5 103.5t155.5 263.5q0 84 -53.5 134t-149.5 50 q-63 0 -110.5 -17.5t-47.5 -37.5q0 -12 15 -27q31 -31 33 -59q2 -53 -46 -62q-49 -10 -75 41q-8 18 -11 39q-6 63 68 141q47 47 109.5 66.5t173.5 19.5q33 0 99.5 -2t98.5 -2q55 0 89 14.5t34 35.5q0 12 -17.5 33.5t-19.5 39.5q0 51 58 51q29 0 44 -19t15 -48 q0 -88 -80 -143.5t-219 -65.5q-37 0 -33 -10l6 -6q82 -70 82 -166q0 -139 -102 -247t-237.5 -157t-266.5 -49t-250 41t-206 140.5t-87 240.5z" /> -<glyph unicode="'" horiz-adv-x="456" d="M322 791l22 251q4 61 10 95t22.5 95.5t51.5 92.5t86 31t69.5 -33t7.5 -88t-32.5 -111.5t-56.5 -122.5l-117 -225q-16 -29 -29 -31q-4 -2 -12 -2q-23 0 -22 48z" /> -<glyph unicode="(" horiz-adv-x="626" d="M205 248q0 588 581 1165q23 21 33 2.5t-8 -39.5q-313 -379 -436 -854q-125 -483 45 -966q12 -37 -8 -45q-20 -10 -35 24q-172 377 -172 713z" /> -<glyph unicode=")" horiz-adv-x="585" d="M-82 -481q-10 18 16 53q147 172 244 354q117 231 184 488q119 463 -47 970q-8 29 9 39q18 10 36 -26q172 -379 172 -711q0 -397 -270 -795q-137 -201 -303 -362q-29 -29 -41 -10z" /> -<glyph unicode="*" horiz-adv-x="1140" d="M197 770q0 49 23.5 67.5t78.5 30.5q66 12 115 29q57 16 118 53q35 14 5 31q-68 35 -125 51q-25 8 -115 31q-53 14 -76.5 33.5t-23.5 64.5q0 12 6 27.5t25.5 31t50.5 15.5q37 0 77 -45q4 -4 12.5 -14.5t14.5 -16.5q74 -88 166 -145q16 -10 21 -6t5 24q-6 113 -28 182 q-27 88 -27 125q0 33 19.5 58.5t56.5 25.5t57.5 -25.5t20.5 -58.5q0 -29 -29 -125q-27 -92 -29 -182q-2 -25 7.5 -25.5t25.5 11.5q88 55 162 141q16 20 27 31q37 45 75 45q45 0 63.5 -25.5t18.5 -48.5q0 -45 -23.5 -64.5t-76.5 -33.5q-113 -31 -115 -31q-55 -16 -121 -49 q-14 -8 -17 -12t1 -8.5t16 -12.5q63 -37 121 -53q49 -16 115 -29q55 -12 77.5 -30.5t22.5 -67.5q0 -27 -20.5 -49.5t-50.5 -22.5q-51 0 -90 45q-14 14 -27 33q-72 90 -162 146q-27 14 -27 -11q2 -129 29 -204q2 -8 7 -18.5t8.5 -17.5t5.5 -16q8 -33 8 -59q0 -39 -21.5 -64.5 t-58.5 -25.5t-58.5 25.5t-21.5 64.5q0 33 10 59q2 8 9.5 25.5t9.5 26.5q27 63 28 198q0 31 -24 17q-86 -51 -162 -146q-33 -41 -53 -55q-27 -23 -64 -23q-33 0 -53 22.5t-20 49.5z" /> -<glyph unicode="+" d="M141 623v118h492v504h119v-504h495v-118h-495v-500h-119v500h-492z" /> -<glyph unicode="," horiz-adv-x="526" d="M110 -345q-6 17 11 30q4 2 44 32.5t51 43t37 39t35 52t9 54.5q0 37 -33 90q-33 61 -33 84q0 41 29 71.5t64 30.5q45 0 73.5 -43t28.5 -104q0 -221 -285 -389q-25 -8 -31 9z" /> -<glyph unicode="-" horiz-adv-x="679" d="M123 382q-4 5 0 40q0 12 8 41q8 23 16 24q8 2 27 2h428q10 0 14.5 -1t8.5 -7t0 -18q-4 -37 -13 -68q-8 -23 -26 -18h-426q-33 0 -37 5z" /> -<glyph unicode="." horiz-adv-x="499" d="M158 86q4 47 33.5 79t68.5 32t61.5 -28t22.5 -71q0 -53 -28.5 -90t-73.5 -37q-47 0 -68.5 34t-15.5 81z" /> -<glyph unicode="/" horiz-adv-x="714" d="M-14 -78q133 246 331.5 651.5t307.5 647.5q0 2 6 11t9 12t9 10.5t15.5 9.5t19.5 0l51 -7q12 -2 19.5 -14t-0.5 -41q-420 -850 -625 -1292q-35 -43 -57 -41l-56 4q-47 6 -30 49z" /> -<glyph unicode="0" horiz-adv-x="884" d="M123 330q0 141 76.5 274t216 229.5t223.5 96.5q76 0 140.5 -105.5t64.5 -234.5q0 -209 -117 -363q-113 -152 -283 -227q-76 -33 -120 -33q-74 0 -137.5 111.5t-63.5 251.5zM279 324q0 -111 41.5 -186t99.5 -75q104 0 187 150.5t83 347.5q0 113 -47 189.5t-113 76.5 q-98 0 -174.5 -152.5t-76.5 -350.5z" /> -<glyph unicode="1" horiz-adv-x="778" d="M147 18q4 23 19 27q92 4 143 25q31 12 43 80l123 624q2 16 -1 20.5t-11 0.5l-8 -4l-142 -64q-8 2 -10 21q0 27 16 32l263 150q16 12 43 12q10 0 20 -10.5t8 -18.5l-145 -737q-12 -57 -12 -74q0 -29 28.5 -40t118.5 -17q8 0 9 -12.5t-4 -23.5t-15 -11q-342 4 -475 0 q-14 0 -11 20z" /> -<glyph unicode="2" horiz-adv-x="847" d="M69 15.5q1 15.5 7 27.5q84 94 137 154q59 61 200.5 181t202.5 189q61 72 62 154q0 57 -39 87t-94 30q-53 0 -105.5 -29t-81 -56.5t-73.5 -78.5q-14 -14 -29.5 2t-7.5 33q182 223 366 223q98 0 161 -66.5t63 -152.5q0 -70 -44 -132.5t-90.5 -95t-132.5 -84.5 q-207 -127 -344 -258q-10 -10 13 -12q8 -2 20 -2h301q92 0 123 55q37 66 39 70q10 25 39 14q16 -4 12 -16q-61 -135 -98 -234q-14 -20 -43 -20q-266 4 -555 0q-10 2 -9 17.5z" /> -<glyph unicode="3" horiz-adv-x="874" d="M-2 -293q0 29 14.5 52.5t40.5 23.5q25 0 107 -41q61 -33 114 -33q123 0 237 136.5t114 324.5q0 88 -40 144.5t-108 56.5q-53 0 -115 -27q-31 -12 -34 12q0 29 20 37q348 156 348 326q0 51 -33.5 84t-82.5 33q-127 0 -299 -174q-10 -10 -29 3t-6 29q211 231 407 232 q72 0 119 -22.5t63.5 -57.5t21.5 -54.5t5 -37.5q0 -88 -82 -163t-180 -120q-6 -2 -8 -7t1 -8t7 -3q68 -16 121 -66q68 -68 67 -151q0 -164 -110.5 -309.5t-260 -224.5t-280.5 -79q-139 0 -139 84z" /> -<glyph unicode="4" horiz-adv-x="917" d="M131 90q0 63 12 78q422 520 648 741l30 2q14 2 21.5 -6t5.5 -22q-80 -399 -137 -676q-2 -20 8 -23h139q12 0 20.5 -15t2.5 -42q-8 -53 -31 -55h-125q-35 0 -47 -25l-82 -395q-2 -16 -15.5 -24.5t-25.5 -4.5h-72q-18 0 -29.5 6t-7.5 25l80 399q2 6 -2 11.5t-9 6.5t-9 1 h-352q-23 0 -23 18zM256 211q-8 -12 12 -18h252q29 0 31 14q98 385 125 493h2q-197 -190 -422 -489z" /> -<glyph unicode="5" horiz-adv-x="884" d="M23 -276q0 29 24.5 64.5t54.5 35.5q23 0 103 -35q61 -27 94 -27q127 0 220 117t93 271q0 82 -43 145t-103 94t-102 45.5t-63 16.5q-31 2 -34 13t5 30q18 68 47 189.5t37 156.5q2 12 5.5 21t6.5 15.5t5 11.5t8 8l8 4t12.5 2t13.5 1h17h21h2q258 -8 276 8q8 6 21 45 q4 8 22.5 9t18.5 -11q-39 -133 -52 -180q-8 -25 -32 -24q-35 0 -139.5 4t-159.5 4q-16 0 -21 -15q-23 -88 -33 -147q-2 -4 4.5 -9t20.5 -7q166 -27 266 -119q96 -84 96 -238q0 -182 -153 -352q-80 -86 -190.5 -154.5t-223.5 -68.5q-47 0 -100 16.5t-53 59.5z" /> -<glyph unicode="6" horiz-adv-x="948" d="M176 432q0 371 330 690q76 72 148.5 122t143 76t105.5 34t92 18q21 0 23 -14q4 -10 -3 -20.5t-18 -12.5q-205 -57 -368.5 -220t-245.5 -425q-4 -12 4 -10q14 4 33 24q45 57 98 108.5t111.5 84.5t83.5 33q59 0 119.5 -89.5t60.5 -212.5q0 -225 -151.5 -430.5 t-297.5 -205.5q-121 0 -194.5 139t-73.5 311zM340 389q0 -137 53 -224t127 -87q88 0 154.5 135t66.5 313q0 111 -35.5 191t-80.5 80q-59 0 -176 -135q-72 -86 -90.5 -139.5t-18.5 -133.5z" /> -<glyph unicode="7" horiz-adv-x="837" d="M102 -311.5q4 14.5 8.5 26t10.5 19.5l600 1009q6 20 -39 21q-49 -2 -180 3t-178 -3q-37 -4 -48.5 -18.5t-25.5 -57.5l-41 -121q-4 -12 -27 -8q-12 4 -13 8t1 15l70 280q8 31 16 37t41 8q74 8 227.5 2t171.5 -6q37 0 111 6q53 4 53 -14v-18q-12 -35 -49 -101l-563 -1034 q-33 -59 -45.5 -73.5t-30.5 -14.5h-45q-16 0 -22.5 10t-2.5 24.5z" /> -<glyph unicode="8" horiz-adv-x="948" d="M117 297q0 182 315 375q20 12 6 26q-121 131 -121 228q0 117 158 231q35 25 109.5 62.5t120.5 37.5q88 0 152.5 -75.5t64.5 -141.5q0 -141 -277 -309q-12 -8 0 -20q154 -143 154 -303q0 -172 -153.5 -302.5t-274.5 -130.5q-90 0 -178 121q-76 104 -76 201zM250 352 q0 -86 69.5 -196.5t126.5 -110.5q53 0 145.5 80t92.5 205q0 166 -199 319q-236 -152 -235 -297zM444 995q0 -100 152 -241q57 39 91 65.5t69 76.5t35 99q0 66 -66 125.5t-111 59.5q-43 0 -106.5 -52.5t-63.5 -132.5z" /> -<glyph unicode="9" horiz-adv-x="1011" d="M76 -410q0 12 14 23q236 84 370 216t218 349q10 37 8 39t-10 -8q-29 -35 -65 -73t-109.5 -85t-139.5 -47q-80 0 -132 78t-52 207q0 133 49 258t119 206t144.5 130t130.5 49q123 0 201.5 -141.5t78.5 -319.5q0 -158 -76.5 -332t-212.5 -307q-125 -121 -284 -192 q-76 -35 -222 -74q-27 -6 -30 24zM328 385q0 -109 33.5 -188.5t87.5 -79.5q27 0 70.5 24.5t94 70.5t85 129t34.5 183q0 137 -55 222t-123 85q-90 0 -158.5 -123.5t-68.5 -322.5z" /> -<glyph unicode=":" horiz-adv-x="608" d="M231 88q4 49 35 80t72 31q39 0 61.5 -28t22.5 -73q0 -53 -28.5 -90t-74 -37t-69 36t-19.5 81zM362 760q18 111 107 110q37 0 60.5 -28.5t23.5 -73.5q0 -53 -29.5 -89t-72.5 -36t-67 35t-22 82z" /> -<glyph unicode=";" horiz-adv-x="608" d="M106 -360q-12 23 21 49q164 106 164 217q0 33 -31 90q-33 57 -33 100t27 73t65 30q45 0 75 -43t30 -109q0 -240 -289 -412q-18 -10 -29 5zM352 750q0 47 30 83.5t77 36.5q37 0 61.5 -30.5t24.5 -75.5q0 -53 -31 -87t-76 -34q-37 0 -61.5 31t-24.5 76z" /> -<glyph unicode="<" d="M143 633v104l1104 475v-131l-942 -397l942 -397v-131z" /> -<glyph unicode="=" d="M143 385v121h1104v-121h-1104zM143 868v121h1104v-121h-1104z" /> -<glyph unicode=">" d="M143 156v131l944 395l-944 397v133l1104 -477v-104z" /> -<glyph unicode="?" horiz-adv-x="825" d="M193 86q4 49 32.5 81t67.5 32t62.5 -28t23.5 -73q0 -55 -30 -91t-75 -36q-82 0 -81 115zM313 346q16 248 103 363q16 20 41.5 41.5t46 34t55.5 33t49 28.5q125 78 125 184q0 70 -51 117t-129 47q-31 0 -88 -16.5t-84 -16.5q-25 0 -41 23.5t-16 58.5q0 49 55 81t137 32 q131 0 213 -91.5t82 -238.5q0 -203 -109 -307q-33 -31 -153 -96q-94 -49 -131 -121q-37 -70 -58 -156q-2 -8 -14 -14t-22.5 -2t-10.5 16z" /> -<glyph unicode="@" horiz-adv-x="1910" d="M205 461q0 426 278.5 711.5t687.5 285.5q328 0 529 -188.5t201 -505.5q0 -303 -165 -519t-399 -216q-160 0 -159 147q0 39 8 98q4 23 -6 21q-6 -2 -19 -16q-63 -82 -125 -138q-125 -113 -237 -112q-82 0 -135.5 70.5t-53.5 174.5q0 131 72 286t186 276q164 168 308 168 q111 0 157 -97q6 -12 10.5 -14t7.5 2t7 11t6 9q16 47 55 60l84 16q35 -4 27 -57q-2 -4 -20.5 -59.5t-41 -125t-48 -158.5t-43 -171t-26 -152.5t5 -113.5t50.5 -43q55 0 125 42t123 107q82 100 129 239.5t47 282.5q0 276 -181.5 444.5t-469.5 168.5q-367 0 -619 -275.5 t-252 -685.5q0 -360 220.5 -579.5t570.5 -219.5q281 0 490.5 137.5t324.5 409.5q16 16 33 17q9 -2 34 -27q-94 -291 -333.5 -449.5t-552.5 -158.5q-387 0 -639 251t-252 646zM780 305q0 -59 33 -101t80 -42q119 0 266 198q66 88 105 207q45 144 45 232q0 66 -35 106.5 t-88 40.5q-86 0 -166 -96q-96 -113 -168 -275.5t-72 -269.5z" /> -<glyph unicode="A" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q19 6 43 6q19 0 39 -4q25 -6 25 -35l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q21 -3 21 -24q0 -5 -1 -11q-2 -22 -23 -22h-5q-123 5 -267.5 5t-310.5 -5q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35 t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-114 4 -237 4t-255 -4q-15 0 -15 16q0 4 1 8zM656 674q8 -10 30 -10l291 2q39 -1 39 28v424q0 18 -6 24q-4 4 -9 5q-1 0 -5 -1 q-8 -3 -15 -11l-324 -441q-4 -5 -4 -10q-1 -5 3 -10z" /> -<glyph unicode="B" horiz-adv-x="1323" d="M37 10q-3 7 -3 13q0 8 5 16q8 14 24 14q43 0 64 2q66 8 96.5 50t52.5 151l173 809q10 45 12 61.5t3 52t-10.5 51t-38 29t-69.5 13.5q-10 2 -25.5 1t-21.5 -1q-18 0 -16 26q4 25 22 25h578q197 0 307 -75t110 -210q0 -109 -79.5 -188.5t-216.5 -106.5q-8 -2 -7.5 -9 t7.5 -9q121 -43 190.5 -131t69.5 -201q0 -185 -150 -293q-148 -106 -404 -106h-10q-173 2 -333.5 2t-307.5 -2q-16 0 -22 16zM457 207q0 -84 40 -116t165 -32q168 0 258 62q145 102 145 297q0 139 -99.5 220t-273.5 81h-108q-8 0 -18.5 -6t-10.5 -13l-88 -415 q-10 -55 -10 -78zM580 811q-2 -12 7 -20.5t21 -8.5h97q184 0 274 52q131 76 131 221q0 139 -106 184q-66 27 -203 27h-96q-25 0 -37 -23z" /> -<glyph unicode="C" horiz-adv-x="1458" d="M59 567q0 219 128 400.5t350.5 286t488.5 104.5q240 0 447 -90q19 -11 19 -37q0 -10 -3 -23q-4 -14 -80 -266q-4 -14 -17.5 -16t-22.5 6t-7 18q4 27 4 51q0 289 -354 289q-311 0 -532.5 -213t-221.5 -522q0 -242 123 -383t342 -141q328 0 545 311q4 8 18 9t23.5 -6 t5.5 -19q-61 -156 -107 -322q-2 -8 -15 -8t-24 8q-33 10 -61 10q-33 0 -125 -18q-162 -33 -270 -33q-276 0 -465 164t-189 440z" /> -<glyph unicode="D" horiz-adv-x="1624" d="M4 10q-2 6 -3 11q0 10 6 20q9 16 28 18l67 7q74 2 100.5 35.5t53.5 154.5l176 831q10 43 11 73t-6 49.5t-19 30.5t-38 16.5t-50.5 6.5t-67.5 1h-16q-27 0 -17 30q8 29 31 29h608q330 0 529.5 -162t199.5 -428q1 -311 -247 -526q-245 -213 -602 -213h-7h-714q-17 0 -23 16 zM434 231q-9 -43 -9 -73q0 -48 23 -66q37 -28 168 -29q186 0 308 39q205 66 336 244t131 397q0 141 -54.5 247t-150.5 164t-214 85q-97 22 -207 22q-25 0 -50 -1q-2 0 -15.5 -1.5t-17.5 -2.5t-13.5 -3t-14.5 -8t-9 -16z" /> -<glyph unicode="E" horiz-adv-x="1355" d="M35 59q12 2 35.5 1t31.5 -1q74 6 104 40t50 132l180 859q12 57 13 88q0 90 -136 90h-53q-23 2 -18 28q6 27 39 27h1046q29 0 39 -9q7 -6 7 -23q0 -7 -1 -15q-23 -125 -53 -246q2 -6 -4 -9t-17 -3q-12 0 -17 5t-6 10t1 16.5t2 17.5q0 102 -54.5 147.5t-179.5 45.5h-344 q-45 0 -51 -29l-104 -498q-2 -14 8 -20t33 -6h336q92 0 139 28.5t86 110.5q4 14 31 8q18 -2 12 -16q-37 -150 -76 -371q-2 -12 -20 -14q-27 -4 -27 47q0 80 -45 108.5t-174 28.5h-281q-41 0 -47 -29l-88 -409q-4 -20 -5 -37t4 -29t9 -22.5t16.5 -17.5t20.5 -12t25.5 -8 t28 -5t31 -3.5t30.5 -1.5h33h8h143q186 0 303 84q55 39 81 64t67 78q6 10 17 12t18.5 -2t7.5 -12q-12 -29 -32.5 -94.5t-37 -117.5t-22.5 -61q-18 -18 -82 -18q-303 4 -570.5 4t-498.5 -4q-9 0 -17 10q-6 8 -6 16q0 38 31 37z" /> -<glyph unicode="F" horiz-adv-x="1124" d="M18 10q-1 4 -2 9q0 10 6 20q8 14 21 12h23q84 0 120.5 36t59.5 144l182 859q12 57 12 84q0 90 -133 90h-35q-20 0 -14 28q6 31 32 31h3q203 -2 428 -2t471 2q16 0 28 -2q13 -1 23 -11q7 -7 7 -18q0 -4 -1 -10l-53 -252q0 -8 -25 -12q-8 0 -13 3t-6 9t-1 12.5t1 14.5t1 10 q0 111 -44 153t-159 42h-250q-37 0 -47 -29q-4 2 -33.5 -121t-56.5 -246l-26 -123q-8 -37 28 -36h70.5h122h90.5q78 2 120 31.5t85 109.5q2 6 16 12t25.5 0t5.5 -31q-57 -201 -78 -364q-2 -12 -13.5 -16.5t-22.5 0t-11 12.5q0 104 -33 140t-123 36h-278q-25 0 -31 -29 l-80 -379q-9 -46 -9 -79q-1 -37 11 -57q22 -38 129 -38q23 6 42.5 -1t17.5 -29q-4 -27 -29 -29q-132 2 -271 2t-286 -2q-13 0 -17 14z" /> -<glyph unicode="G" horiz-adv-x="1529" d="M125 582q0 328 246.5 551t629.5 223q217 0 478 -94q16 -4 22 -43l8 -248q4 -18 -19.5 -21.5t-27.5 8.5q-41 162 -160.5 249t-308.5 87q-297 0 -482 -212t-185 -527q0 -530 518 -530q94 0 178 22.5t119 56.5q29 27 49 110t20 136q0 51 -24.5 66.5t-98.5 23.5l-18 2 q-14 2 -15 15.5t7 26t16 12.5q137 -4 258 -4t228 4q11 -2 11 -18q0 -4 -1 -10q-4 -26 -17 -28h-26q-45 -6 -72.5 -16t-45 -36t-23 -39t-14.5 -62t-13 -66q-14 -37 -14 -67q0 -14 3 -27q9 -41 74 -43q10 -2 9.5 -21.5t-17.5 -23.5q-293 -76 -579 -76q-188 0 -347 68.5 t-262.5 212t-103.5 338.5z" /> -<glyph unicode="H" horiz-adv-x="1583" d="M-31 23q4 29 21 28h41q92 0 134 42t68 163l177 836q14 63 14 90q0 88 -127 88h-68q-18 6 -14 22q0 31 25 31q140 -6 285 -6t294 6q16 0 23.5 -7t5.5 -18q-2 -8 -4 -14t-5 -9t-8.5 -4t-9.5 -1h-13h-15q-98 0 -138.5 -35t-62.5 -145l-72 -347q-6 -12 2 -23t21 -11h653 q12 0 23.5 10t13.5 20l74 353q11 58 11 95t-31 61q-32 24 -101 24q-39 0 -41 12q-2 6 -2 14q0 25 24 25q165 -7 300 -7t241 7q17 0 17 -18q0 -5 -1 -11q-6 -16 -22 -22h-53q-72 -6 -106 -48t-58 -161l-176 -834q-13 -40 -13 -73q0 -29 10 -52q22 -49 113 -55q2 0 26.5 1 t35 -4t10.5 -21q0 -20 -33 -29q-140 6 -280.5 6t-280.5 -6q-16 0 -22.5 6t-4.5 18q4 25 31 29q14 2 37 2h33q70 8 101.5 46t51.5 134l74 353q2 10 2 18q0 29 -29 29h-643q-31 0 -36 -27l-80 -375q-9 -45 -9 -78q0 -38 12 -60q22 -40 120 -40h10q2 0 15 1t19.5 0t14.5 -3 t12 -9t2 -17q-5 -27 -25 -27h-5q-216 3 -361.5 3t-220.5 -3q-27 0 -27 21v6z" /> -<glyph unicode="I" horiz-adv-x="729" d="M47 27q8 25 33 24h10q92 0 127 37q37 39 59 143l183 861q15 47 15 81q0 28 -10 47q-22 42 -124 48h-24.5t-19.5 8t-1 24q6 23 33 23q129 -6 262.5 -6t271.5 6q14 0 14 -13q0 -7 -4 -18q-10 -31 -36 -22q-100 -6 -135 -38t-58 -142l-182 -861q-9 -43 -9 -75q0 -47 20 -70 q32 -37 138 -37h11q25 0 20 -29q-8 -18 -25 -22q-190 5 -328.5 5t-226.5 -5q-17 0 -17 16q0 6 3 15z" /> -<glyph unicode="J" horiz-adv-x="692" d="M-362 -530q0 39 30 79q23 31 72 31q14 0 30.5 -5t35 -13t28.5 -13q69 -22 111 -22h4q141 0 201 133q23 55 38 139l244 1293q10 57 10 92q0 26 -6 39q-18 43 -96 47h-34.5t-35.5 2q-20 0 -18 22q4 29 27 29q124 -7 262 -7t290 7q19 0 19 -18q0 -5 -2 -13q-6 -16 -17.5 -22 t-39.5 -4h-27q-70 -8 -99.5 -44t-48.5 -132l-213 -1121q-29 -150 -72.5 -234.5t-135.5 -160.5q-195 -162 -412 -162q-145 0 -145 58z" /> -<glyph unicode="K" horiz-adv-x="1454" d="M18 20q6 18 15.5 23.5t34 4.5t26.5 -1q76 8 109 45t55 137l184 861q12 53 13 90q0 90 -125 90h-15q-14 -2 -10 22q2 29 27 29q144 -5 274 -5t248 5q25 0 14 -31q-8 -20 -24 -20h-23q-96 -2 -135 -37t-61 -146l-76 -362q-4 -14 3 -19.5t28 7.5q68 47 276.5 199.5 t329.5 234.5q59 41 59 74q0 27 -18.5 38t-67.5 11q-10 0 -14 1t-7 6t1 17q4 27 22 27q80 -4 199.5 -4t279.5 4q17 -1 19 -11q1 -3 1 -5q0 -8 -5 -17q-6 -12 -13 -14q-12 -2 -16 -4l-84 -17q-156 -29 -375 -194q-246 -182 -405 -305q-23 -16 -6 -39l428 -535 q59 -76 118.5 -103.5t139.5 -27.5h14q10 0 11 -14.5t-6 -27.5t-17 -13q-70 4 -146.5 4t-158.5 -4q-27 0 -43 22l-500 625l-59 -37q-16 -12 -21 -33l-72 -344q-16 -47 -16 -83q0 -31 12 -52q25 -47 144 -47q16 2 27.5 -4t9.5 -21q-4 -20 -25 -26q-144 4 -283 4t-272 -4 q-24 5 -24 20q0 3 1 6z" /> -<glyph unicode="L" horiz-adv-x="1234" d="M33 4q-2 7 -2 13q0 11 7 21q11 14 23 15h20.5t18.5 2q76 4 113 48t59 157l174 832q14 64 14 99q0 37 -31 57q-32 22 -103 22q-4 0 -16.5 -1t-15.5 -1t-11.5 3t-6 10t2.5 19q8 23 18 23q142 -8 284 -8t283 8q23 0 17 -31q-2 -6 -5.5 -10t-5.5 -7t-9 -4t-9 -1h-12h-9 q-96 0 -136 -35t-62 -145l-178 -840q-12 -36 -12 -67q1 -27 9 -51q20 -52 101 -54h211q180 2 287 61q92 51 180 160q11 14 31 9q16 -4 15 -17q0 -4 -1 -8q-16 -35 -46 -124t-42 -122q-14 -41 -53 -41q-23 0 -539 3q-221 1 -350 1q-172 0 -180 -2q-10 -2 -17 -2q-15 0 -16 8z " /> -<glyph unicode="M" horiz-adv-x="1808" d="M-12 23q6 23 22 22q106 14 162 82q41 49 98 244l205 702q20 49 20 88q1 27 -9 51q-22 56 -126 58q-43 0 -61 4q-12 6 -5 28.5t25 18.5q84 -2 159 -2q112 0 204 4q6 1 11 1q28 0 28 -19l143 -1020q4 -16 11.5 -23.5t17.5 4.5l684 1041q10 16 39 16q100 -3 179 -3t136 3 q25 0 27 -10q1 -3 1 -6q0 -9 -4 -21q-5 -16 -18 -14h-14q-96 0 -137 -36t-64 -146l-182 -861q-15 -43 -15 -79q-1 -28 9 -51q22 -52 123 -52h6q14 0 19.5 -1t12.5 -7t-1 -21q-2 -10 -10.5 -17t-16.5 -5q-72 4 -205.5 4t-328.5 -4q-20 -2 -15 29q6 25 21 24q55 0 82 4 q59 10 88.5 49t48.5 129l188 869q4 16 2 23t-9 2t-15 -17l-701 -1106q-22 -12 -49 -12h-8q-32 2 -35 14l-151 1094q-4 37 -17 14q-4 -6 -6 -12l-244 -836q-12 -41 -12 -86q0 -63 36 -95t114 -38q14 0 6 -25q-2 -25 -17 -24q-132 5 -242 5t-198 -5q-13 0 -13 17q0 5 1 10z " /> -<glyph unicode="N" horiz-adv-x="1615" d="M25 25q6 23 22 20q102 14 146.5 62.5t68.5 171.5l187 923q-14 18 -30 30.5t-37.5 18.5t-33.5 9.5t-42 6.5t-40 5q-18 4 -14 28q2 23 22 23q45 -2 105 -2t135 2q55 0 66 -16l671 -1035q27 -39 39 0l166 783q10 48 10 84q0 51 -20 80q-35 49 -160 57q-10 0 -10 24 q4 23 20 23q132 -3 246 -3t211 3h3q12 0 12 -9q0 -7 -7 -20q-8 -16 -18 -16q-96 -14 -145.5 -64.5t-71.5 -158.5l-228 -1078q-2 -8 -28 -9h-4q-22 0 -31 9l-703 1100q-23 29 -30 -8l-152 -780q-8 -46 -8 -83q0 -50 16 -83q28 -57 138 -72q20 0 25 -5t3 -23q-4 -27 -18 -27 q-140 5 -256 5t-209 -5q-18 -2 -18 16q0 6 2 13z" /> -<glyph unicode="O" horiz-adv-x="1677" d="M180 588q0 313 237.5 540.5t565.5 227.5q268 0 443.5 -179.5t175.5 -443.5q0 -319 -237 -544.5t-572 -225.5q-268 0 -440.5 178t-172.5 447zM373 537q0 -238 110.5 -373t309.5 -137h5q257 0 433 220q178 222 178 550q-1 223 -115 360q-113 135 -303 135h-6 q-236 0 -381 -155q-106 -113 -168.5 -275t-62.5 -325z" /> -<glyph unicode="P" horiz-adv-x="1155" d="M-39 20q6 27 19 27q94 4 134 45t66 164l174 823q8 51 14 93q1 5 0 11q0 35 -32 58q-37 27 -123 27q-23 4 -18 28q4 29 32 29q61 -2 453 -2q152 0 233.5 -18.5t151.5 -67.5q141 -101 141 -281q0 -147 -101 -265t-259 -154q-117 -27 -208 -27q-55 0 -101 10 q-18 8 -13.5 27.5t21.5 17.5q29 -4 58 -4q86 0 164 32q105 42 167 134q80 119 80 258q0 94 -41 161.5t-111 90.5q-63 20 -254 20q-33 0 -41 -32l-209 -996q-8 -40 -8 -71q0 -42 16 -67q28 -42 132 -42q41 0 43 -12q2 -6 -4 -21q-8 -20 -21 -20q-158 7 -293 7t-248 -7 q-15 0 -15 16q0 4 1 8z" /> -<glyph unicode="Q" horiz-adv-x="1634" d="M127 588q0 311 238.5 539.5t572.5 228.5q289 0 472 -177.5t183 -445.5q0 -276 -170 -488t-452 -268q-29 -6 -13 -20q23 -14 54 -35q285 -199 360 -219q48 -12 90 -12q61 0 111 24q10 8 20.5 1t13.5 -18q1 -5 1 -9q0 -5 -2 -8q-111 -94 -248 -95q-78 0 -177.5 41t-168 86 t-177 122t-145.5 102q-47 39 -65 40q-215 45 -356.5 220.5t-141.5 390.5zM330 535q0 -233 125 -372.5t338 -139.5q268 0 433 220t165 552q0 225 -117 363t-318 138q-227 0 -387 -159q-111 -113 -175 -275t-64 -327z" /> -<glyph unicode="R" horiz-adv-x="1277" d="M2 27q8 25 23 22h16q104 0 145 35t66 147l184 861q8 40 8 70q0 38 -12 62q-22 44 -119 44q-16 0 -24 1t-16.5 8t-6.5 19q4 29 35 29q47 -2 541 -2q180 -2 290.5 -91t110.5 -237q0 -143 -102.5 -245.5t-276.5 -139.5q-20 -4 -10 -20q23 -33 47 -82q53 -121 96 -207 q63 -125 168 -207q80 -63 178 -63q13 0 13 -14q0 -20 -10 -25q-43 -16 -72 -17q-160 0 -255 40t-173 161q-18 31 -34.5 68t-35 85t-26.5 70q-45 106 -80 176q-76 -6 -135 -6q-25 0 -33 -30l-64 -310q-9 -43 -9 -75q1 -41 15 -65q26 -42 134 -42q29 0 37 -6t-1 -31 q-4 -14 -30 -14q-170 6 -313 6t-259 -6q-13 -1 -13 13q0 7 3 18zM526 651q-2 -6 8.5 -13t22.5 -7q133 0 188 16q51 12 132 62q78 45 128 137q45 84 45 174v18q-5 100 -79 160q-76 61 -273 62q-20 0 -34.5 -12.5t-16.5 -24.5z" /> -<glyph unicode="S" horiz-adv-x="1058" d="M31 116q-1 10 -1 16t1 9l65 260q2 12 14.5 16.5t22.5 -0.5t8 -18q0 -14 -1 -27.5t-1 -19.5q0 -156 90 -241.5t263 -85.5q150 0 233.5 66.5t83.5 176.5q0 80 -56.5 150.5t-136 128t-160.5 118t-137.5 144.5t-56.5 182q0 145 116 245.5t294 100.5q47 0 131 -20.5t125 -20.5 q37 0 65 29q6 14 31 10q10 -2 16 -5q4 -2 4 -5v-2q-25 -131 -47 -348q0 -12 -24.5 -12t-24.5 12q0 301 -276 301q-123 0 -192.5 -56.5t-69.5 -148.5q0 -88 74.5 -170t198.5 -169t163 -126q119 -119 119 -262q0 -170 -131.5 -275.5t-350.5 -105.5t-444 129q-6 4 -8 24z" /> -<glyph unicode="T" horiz-adv-x="1290" d="M147 1038q59 225 74 342q4 10 25 11q18 0 20 -11q29 -35 55.5 -46t88.5 -11h817q111 0 150.5 10t80.5 49q6 10 25 11q8 -1 15 -5q5 -4 5 -6l-71 -350q-4 -14 -26 -14t-24 14q0 63 -2 90q-8 51 -18 72q-29 59 -139 59h-265q-27 -4 -34 -32l-209 -992q-10 -48 -10 -81 t10 -51q20 -36 100 -42q23 -2 84 -2q18 0 14 -26q-4 -31 -24 -31q-148 4 -299.5 4t-306.5 -4q-23 0 -11 31q8 27 27 26q45 0 66 2q80 4 110.5 39t52.5 137l213 979q8 43 -26 43h-195q-154 0 -213 -47q-37 -29 -58.5 -65.5t-55.5 -112.5q-6 -18 -29 -14q-19 6 -19 17q0 3 2 7 z" /> -<glyph unicode="U" horiz-adv-x="1515" d="M121 1303q8 27 29 22q128 -6 264 -6t280 6q12 0 19.5 -8t5.5 -19q0 -33 -37 -28h-22q-86 0 -118 -29q-36 -33 -61 -151l-116 -545q-25 -117 -25 -203q0 -145 102.5 -231t284.5 -86q236 0 352.5 124.5t159.5 354.5l104 555q9 44 9 78q0 58 -25 88q-39 47 -164 47 q-14 0 -10 28q4 12 9 19.5t12 5.5q147 -3 251 -3q139 0 203 5h2q17 0 17 -31q-6 -29 -29 -24q-96 -12 -137 -53t-66 -175l-104 -561q-29 -154 -92 -260q-158 -260 -527 -260q-178 0 -290.5 50t-182.5 157q-57 88 -61 188q-1 13 -1 26q0 86 23 169l113 528q10 55 12 97v6 q1 38 -29 62q-32 26 -102 26h-35q-8 0 -14 10q-5 8 -5 16q0 2 1 5z" /> -<glyph unicode="V" horiz-adv-x="1308" d="M111 1280q-1 7 -1 14q0 19 13 29q4 2 8 2q169 -4 302 -4t229 4q16 0 8 -29q-6 -27 -25 -26q-6 0 -40 1t-48 -3q-94 -16 -104 -176l-52 -861q-2 -27 4.5 -30.5t26.5 18.5l713 840q82 94 82 143q0 29 -16.5 44.5t-31 17.5t-46.5 4q-27 4 -37 6q-18 0 -19 26q4 25 23 25 q105 -3 207.5 -3t203.5 3q7 -1 11 -13l2 -8q0 -8 -4 -17q-6 -13 -19 -13q-63 -20 -113.5 -62.5t-123.5 -128.5l-961 -1116q-8 -12 -51 -12q-14 0 -24.5 10t-10.5 25l55 1102q1 16 1 31q-1 68 -23 104q-28 43 -117 43h-10q-8 -2 -12 10z" /> -<glyph unicode="W" horiz-adv-x="1826" d="M94 1303q4 22 23 22h2q114 -4 236 -4t253 4h3q9 0 13 -7q6 -9 3 -22q-2 -8 -9.5 -17t-13.5 -9q-102 -12 -131 -45t-41 -150l-84 -809q-4 -27 1 -33t26 17l645 827v76q0 72 -27.5 92.5t-126.5 24.5q-10 0 -12 13t3 27.5t13 14.5q123 -4 251 -4t261 4q10 0 10.5 -13.5 t-7 -27.5t-13.5 -14q-113 -12 -136.5 -36t-31.5 -132l-59 -836q-2 -25 4 -30t22 18l572 811q60 84 60 134q0 46 -52 63q-29 8 -88 8q-8 0 -14.5 9t-3.5 19q6 27 24 27q142 -3 242.5 -3t159.5 3q12 0 12 -10q0 -6 -4 -15q-4 -27 -19 -26q-51 -12 -97 -51t-108 -125 l-794 -1104q-18 -25 -43 -25q-37 0 -41 2q-25 10 -25 19l66 930q0 37 -21 16l-737 -946q-20 -20 -31 -21q-16 -4 -29 -4q-9 0 -16 2q-23 10 -22 21l94 1122q2 14 2 39q0 70 -19.5 92.5t-56.5 24.5q-43 0 -69 6q-20 0 -20 20q0 5 1 11z" /> -<glyph unicode="X" horiz-adv-x="1441" d="M-25 18q4 27 17 27q123 16 154.5 32.5t119.5 104.5l477 477q12 20 9 41l-252 463q-35 63 -83 85t-157 26q-10 0 -10 29q6 20 22 20q131 -3 272.5 -3t293.5 3q23 0 18.5 -24.5t-16.5 -24.5q-88 -2 -119 -13.5t-31 -46.5q0 -20 29 -73l158 -314q10 -12 13 -11t19 13 l283 293q53 53 53 88q0 33 -31.5 47.5t-117.5 16.5q-20 -2 -13 26q6 23 19 23q140 -4 263 -4t228 4q8 0 12.5 -1t6.5 -4t2 -4v-9q-4 -27 -21 -27q-98 -12 -171.5 -50t-153.5 -120l-332 -342q-16 -12 -6 -33l280 -518q55 -102 96.5 -132t139.5 -44q8 -2 8 -12.5t-6 -20.5 t-10 -10q-135 4 -264 4t-252 -4h-4q-29 0 -23 29q2 6 7 13t11 5q41 2 63.5 4t46.5 9t31 19.5t4 34t-20 54.5l-223 420q-25 37 -43 16l-364 -367q-68 -69 -75 -109q-1 -6 -1 -12q0 -32 32 -46q38 -18 121 -23q6 -2 6.5 -14.5t-5 -22.5t-11.5 -10q-229 4 -355 4q-84 0 -124 -2 q-14 -2 -18 4q-3 4 -4 10q0 3 1 6z" /> -<glyph unicode="Y" horiz-adv-x="1308" d="M211 1300q4 23 22 23q97 -5 207 -5t232 5q23 -4 14 -25q-4 -25 -12 -24q-70 -6 -92 -14q-22 -9 -22 -40q0 -30 30 -98l209 -477q6 -16 8 -18t24 18l377 438q80 92 80 125q0 59 -127 66q-8 4 -8 15t7 23q6 11 15 11h3q104 -5 194 -5t168 5q8 0 16 -4q5 -3 5 -9 q0 -17 -13 -30q-68 -27 -102.5 -50.5t-93.5 -94.5l-521 -598l-63 -308q-9 -45 -9 -77q0 -40 13 -60q24 -35 120 -35h11q49 0 58 -2q14 -2 5.5 -30.5t-16.5 -28.5q-146 4 -300 4t-318 -4q-8 4 -8 16.5t7 27.5t17 15q129 6 164 29q47 33 72 147l65 308l-258 587 q-37 86 -69.5 115t-90.5 33q-21 0 -21 16q0 5 1 10z" /> -<glyph unicode="Z" horiz-adv-x="1406" d="M4 43q152 147 1196 1186q16 20 12 23t-24 3h-397q-158 0 -250 -66.5t-152 -223.5q-2 -6 -27 -11q-25 0 -24 13q4 16 26.5 96t38 140.5t19.5 94.5q6 25 41 25q164 -3 411.5 -3t579.5 3h7q23 0 29 -11q3 -6 3 -15q0 -10 -4 -23q-356 -342 -1198 -1184q-10 -10 -11 -14t4 -6 t19 -4h539q102 0 164.5 20t117.5 68q78 70 166 217q18 14 33 10q16 -6 10 -25q-20 -59 -90 -321q-8 -39 -47 -39q-289 4 -586.5 4t-603.5 -4q-7 4 -7 19q0 23 5 28z" /> -<glyph unicode="[" horiz-adv-x="628" d="M121 -467l371 1862h397l-10 -45h-191q-41 0 -57.5 -15.5t-26.5 -60.5l-321 -1618q-6 -25 -7 -39q0 -41 103 -41h147l-8 -43h-397z" /> -<glyph unicode="\" horiz-adv-x="456" d="M152 1356h139l182 -1389h-139z" /> -<glyph unicode="]" horiz-adv-x="628" d="M-84 -467l8 45h193q41 0 59.5 16.5t26.5 61.5l321 1616q4 29 4 41q0 39 -104 39h-145l8 43h399l-373 -1862h-397z" /> -<glyph unicode="^" horiz-adv-x="888" d="M111 684l444 750h33l438 -750h-104l-353 600l-354 -600h-104z" /> -<glyph unicode="_" horiz-adv-x="1042" d="M-18 -428l2 10l4 10q0 37 41 37q989 0 1001 2q25 -6 29 -18q6 -12 2 -21.5t-4 -23.5q-12 -25 -29 -23h-1018q-12 -2 -21 5.5t-7 21.5z" /> -<glyph unicode="`" horiz-adv-x="694" d="M349 1339.5q5 6.5 16 6.5h151q20 0 25 -7v-2q2 -2 2 -4l98 -311q2 -4 -1 -7t-11 -3q-16 0 -25 8l-252 299q-8 14 -3 20.5z" /> -<glyph unicode="a" horiz-adv-x="851" d="M76 199q0 158 108.5 325.5t274.5 263.5q145 84 332 89q10 0 12 -19l-121 -612l-4 -19q-4 -18 -8 -36.5t-6 -38t2 -30.5t14 -9q27 4 84 69q12 14 27 29q16 16 24 -6q2 -7 2 -14q0 -11 -6 -21q-82 -90 -104 -113q-86 -82 -125 -82q-62 0 -62 100v13q2 57 21 137 q4 18 -3.5 19.5t-19.5 -13.5q-246 -256 -315 -256q-51 0 -89 68t-38 156zM213 242q0 -63 19.5 -105.5t43.5 -42.5q29 0 285 242l80 395q5 8 5 15q0 4 -1 6q-2 9 -12 8h-4q-125 -14 -221 -80q-88 -59 -141.5 -180t-53.5 -258z" /> -<glyph unicode="b" horiz-adv-x="849" d="M139 293q10 55 90 470t131 636q6 23 -10 22.5t-78 -35.5q-29 -12 -31.5 8.5t13.5 28.5l178 105q43 26 63 26q7 0 11 -2q12 -6 12 -31q0 -13 -4 -32l-176 -875q-4 -20 2 -23t16 7q4 4 31 34t44.5 49t49 53t55 55.5t51 45t50 35t39.5 11.5q26 -1 55 -52q51 -87 57 -205 q1 -18 1 -35q0 -99 -31 -193q-37 -110 -98.5 -207t-149.5 -155.5t-180 -58.5q-139 -1 -178 91q-23 55 -23 126q0 47 10 101zM276 291q-14 -73 -14 -125q0 -137 96 -137q84 0 155 100t103.5 216t32.5 196q0 96 -19.5 155.5t-47.5 59.5q-41 0 -140 -107q-29 -31 -110 -127 q-12 -14 -15 -24q0 -6 -2 -15z" /> -<glyph unicode="c" horiz-adv-x="614" d="M72 201q0 125 56 278.5t168 276.5t241 123q49 0 79.5 -21.5t30.5 -60.5q0 -31 -16.5 -51.5t-42.5 -20.5q-37 0 -101 37q-33 16 -55 16q-70 0 -129 -145q-14 -35 -27.5 -79t-33.5 -112q-19 -68 -25 -128q-4 -40 -4 -78q0 -18 1 -38q3 -56 31.5 -89t80.5 -33q98 0 204 127 q2 6 13.5 4t15.5 -8q20 -14 14 -33q-76 -88 -162.5 -139.5t-156.5 -51.5q-82 0 -132 62.5t-50 163.5z" /> -<glyph unicode="d" horiz-adv-x="921" d="M100 233q0 164 86 325t230 265q62 47 124 55l18 2q53 0 104 -44q8 -10 16 3t12 33l101 517q6 31 -2.5 33.5t-30.5 -11.5q-18 -8 -52 -29.5t-53 -29.5q-18 -12 -24 14q-4 31 14 37l219 121q34 19 53 19q26 0 26 -34q0 -11 -3 -26l-252 -1327q-10 -47 6 -47q31 0 119 124 q6 10 20 0q18 -18 9 -34q-59 -92 -136 -158t-122 -66q-47 0 -47 68q0 45 17 119t19 98q4 35 -12 10q-2 -4 -6 -10q-2 -2 -2 -4q-100 -127 -190.5 -204t-137.5 -77q-55 0 -89 73t-34 185zM258 129q18 -43 47 -43q35 0 115 82t174 215l59 307q-45 123 -129 123 q-78 0 -164 -147q-120 -207 -120 -417q0 -77 18 -120z" /> -<glyph unicode="e" horiz-adv-x="745" d="M78 270q0 233 143.5 423t321.5 190q80 0 126 -40t46 -110q0 -150 -180 -241q-55 -31 -158 -62q-29 -8 -69 -19.5t-54 -15.5q-23 -10 -23 -24q-10 -49 -10 -109q0 -92 45 -146q43 -51 109 -50h8q90 2 233 114q18 16 27 -6q12 -23 -2 -43q-88 -76 -184.5 -116t-167.5 -40 q-88 0 -149.5 85t-61.5 210zM258 481q0 -8 7 -11q3 -1 7 -1q8 0 19 4q113 27 192 66q115 59 123 170q1 6 1 12q-1 39 -23 67q-24 30 -66 29h-6q-109 -4 -164 -102q-47 -88 -49 -94q-41 -92 -41 -140z" /> -<glyph unicode="f" horiz-adv-x="579" d="M-365 -449q9 59 69 59q7 0 15 -1q20 -2 54 -31l9 -9t8 -9t8 -9.5t9.5 -8.5t9.5 -7t10 -7t10 -5t12.5 -5t12.5 -2t13 -1q45 0 90 33.5t72 84.5q23 43 47 158q23 98 49 242q18 94 123 715q6 27 -10 26h-109q-6 -2 -8 5t0 16q4 29 18 28q55 8 72 13q8 2 26.5 8t28.5 8 q35 184 70 289q57 172 133 262q120 149 277 149h2q61 0 108 -34q45 -32 45 -74q0 -63 -70 -63q-9 0 -18 1q-29 4 -72.5 45t-89.5 41q-66 0 -114 -75q-49 -74 -94 -326l-35 -197q0 -14 14 -16h129q14 0 6 -39q-14 -41 -28 -41h-125q-8 -2 -17 -14l-92 -533 q-20 -127 -36.5 -198.5t-51.5 -184t-90 -194.5t-131 -137q-100 -74 -203 -74q-66 0 -115 36q-42 31 -42 65q0 5 1 11z" /> -<glyph unicode="g" horiz-adv-x="815" d="M-170 -383q0 72 123 154q92 63 250 147q-20 32 -20 63q0 61 77 115q14 8 0 17q-72 43 -113 119.5t-41 166.5q0 94 65 202t167 192q106 88 217 88h14q39 -2 128 -10.5t108 -8.5q20 0 24 -61q0 -27 -5 -41.5t-17 -9.5l-86 10q-8 2 -12 -2t-2 -10q37 -98 36 -179 q0 -86 -37.5 -170t-101.5 -139q-102 -88 -246 -154q-75 -35 -75 -66q0 -24 30.5 -53.5t112.5 -84.5q141 -94 196.5 -151.5t55.5 -104.5q0 -92 -129 -150.5t-324 -58.5q-172 0 -283.5 50t-111.5 130zM-41 -362q0 -68 75 -113t193 -45q145 0 235.5 34t90.5 85q0 35 -68 82 q-139 102 -245 196q-10 6 -23 0q-137 -78 -197.5 -132t-60.5 -107zM250 381q0 -86 38 -146.5t89 -60.5q63 0 127 92q92 133 92 330q0 98 -34 157.5t-87 59.5q-66 0 -120 -85t-79.5 -182t-25.5 -165z" /> -<glyph unicode="h" horiz-adv-x="935" d="M106 29l267 1347q8 37 -6.5 37t-106.5 -51q-14 -12 -20 10q-8 27 4 33l207 119q39 22 59 22h2q12 0 19.5 -5t8.5 -9t0 -17.5t-1 -15.5l-199 -995q-4 -23 -1 -26t15 16q272 383 410 383q84 0 83 -116q0 -57 -20 -143l-120 -471q-16 -51 6 -51q29 0 161 148q8 6 16.5 -1 t10.5 -19q1 -6 1 -10t-1 -7q-74 -98 -154.5 -165t-125.5 -67q-33 0 -47 27q-13 24 -13 58v10q2 41 7 68.5t12 51.5l108 426q20 72 20 112q0 48 -30 48q-39 0 -163 -154.5t-208 -275.5q-55 -270 -57 -278q-2 -6 -4 -22.5t-4 -24t-7.5 -17.5t-14.5 -14t-23 -4h-78 q-18 -1 -18 18q0 10 5 25z" /> -<glyph unicode="i" horiz-adv-x="522" d="M113 641q-4 9 -4 16q0 9 6 17q172 205 256 205q44 0 44 -60q0 -27 -9 -65l-121 -594q-8 -47 -2 -51q4 -4 16 -5q25 0 125 119q12 20 27 -4q14 -29 4 -39q-47 -61 -128 -132t-134 -71q-60 1 -60 87q0 31 8 73l109 520q0 2 3 11.5t4 18.5t2 19.5t0 16.5t-7 8h-3 q-17 0 -59 -45q-51 -55 -53 -57q-10 -14 -24 12zM348 1206q10 49 37 81t57 32q50 -2 50 -74q0 -18 -3 -41q-8 -55 -34.5 -91t-61.5 -36q-54 0 -54 65q0 27 9 64z" /> -<glyph unicode="j" horiz-adv-x="501" d="M-297 -451q4 31 21.5 47.5t48.5 12.5q33 -4 59 -39l39 -45q29 -21 54 -21q32 0 57 34q45 59 77 183q10 37 20.5 88.5t14.5 67.5l189 799q10 35 -9 41q-1 1 -3 1q-13 0 -54 -38q-12 -12 -29.5 -30.5t-19.5 -20.5q-10 -8 -20.5 -2t-12.5 16t4 16q76 96 143.5 149.5 t108.5 53.5q48 0 48 -68q0 -38 -15 -96l-166 -692q-57 -246 -166 -393q-121 -170 -264 -170q-59 0 -94 35q-31 31 -31 64v7zM383 1208q20 115 94 117h4q47 0 55 -46q3 -17 3 -33q0 -27 -9 -48q-20 -117 -94 -117q-58 2 -58 76q0 22 5 51z" /> -<glyph unicode="k" horiz-adv-x="940" d="M109 2q0 4 2 11t2 10l274 1368q6 27 0 28.5t-33 -14.5q-12 -6 -34.5 -19.5l-32.5 -19.5q-12 -12 -23 14q-14 27 6 33l207 121q28 21 49 21q4 -1 8 -1q24 -4 13 -55l-187 -903q-6 -27 -5 -29t26 19q315 293 418 293q49 0 86 -53.5t41 -123.5q1 -12 1 -23q1 -123 -99 -191 q-98 -67 -302 -67q-22 0 -45 1q80 -84 107 -123l47 -70q41 -59 86 -96q39 -32 69 -32q5 0 9 1q25 23 86 91q10 10 19 3.5t15.5 -19.5t2.5 -19q-88 -113 -170 -178q-49 0 -82 24q-98 66 -191 215q-84 131 -135 184q-18 18 -25 -22l-69 -361q-6 -31 -13.5 -35.5t-27.5 -4.5 q-57 0 -84 2q-6 0 -10 3t-5 8t-1 9zM336 472q2 -3 6 -6t4 -5q25 0 73 1h30q27 0 45 -1h16q71 0 137 16q164 39 164 203q0 39 -24.5 67.5t-59.5 28.5q-41 0 -155.5 -87t-235.5 -212q-1 -1 -1 -2t1 -3z" /> -<glyph unicode="l" horiz-adv-x="524" d="M139 152l244 1224q8 39 -12 39q-10 0 -113 -57q-29 -8 -35 12q-8 27 13 31l198 117q27 16 43.5 23t36.5 10h6q16 0 22 -14q3 -8 3 -20q0 -14 -4 -34l-271 -1358q-12 -53 11 -53q37 0 147 125q2 4 11.5 5t15.5 -5q12 -8 2 -33q-162 -190 -254 -191q-73 0 -73 99q0 34 9 80 z" /> -<glyph unicode="m" horiz-adv-x="1380" d="M96 621q63 98 153.5 177t129.5 79q38 0 38 -50q0 -14 -3 -32l-62 -308q-4 -18 2 -18q2 0 6 8q276 399 420 400q29 0 45.5 -26t16.5 -69q0 -35 -4 -72.5t-9.5 -62t-14.5 -68.5t-13 -67q-10 -55 6 -31q4 6 34.5 54.5t54.5 82t64.5 86t77.5 86t82 58t86 24.5q60 0 60 -91 q0 -36 -9 -85l-114 -561q-2 -9 -2 -14q0 -13 9 -13q10 0 30 17q29 23 41 41q33 37 61 74q19 22 33 4q5 -9 5 -18q0 -11 -7 -21q-72 -100 -149 -165t-117 -65q-54 0 -54 69q0 23 6 54q61 301 121 617q8 35 4 45t-22 10q-39 0 -142.5 -143.5t-158.5 -237.5q-41 -70 -60 -153 l-43 -216q-10 -43 -32 -43h-80q-23 0 -27 12.5t2 28.5l137 695q14 55 -10 55q-55 0 -162.5 -140.5t-173.5 -246.5q-31 -51 -63 -209q-4 -18 -13.5 -73.5t-15.5 -84.5q-4 -20 -11 -27t-28 -7q-10 0 -33.5 -1.5t-33.5 -1.5q-41 0 -33 41l131 662q10 41 -4 41q-10 0 -45 -36 t-49 -56q-18 -25 -23 -29q-6 -6 -16.5 -7t-16.5 5q-4 4 -4 11q0 5 2 12z" /> -<glyph unicode="n" horiz-adv-x="960" d="M100 582q-6 12 -6 22.5t6 18.5q190 256 260 256h2q36 -1 36 -57q0 -20 -5 -48q-37 -195 -63 -315l-2 -21q2 2 12 15q10 12 61.5 81.5t89 115.5t92 105.5t103.5 91.5t90 32q86 0 86 -127q0 -59 -16 -125l-123 -473q-13 -44 -12 -65q0 -17 8 -19h2q19 0 92 80q51 59 78 92 q19 20 29 10q4 -6 7 -10t3 -9.5v-7.5t-3 -7t-4 -7t-6.5 -9t-7.5 -9q-74 -100 -149.5 -159t-124.5 -59q-66 0 -66 80q0 33 11 80l133 533q9 35 9 57q0 41 -30 41q-14 0 -33.5 -12.5t-44 -35t-48 -48t-53.5 -61.5t-52.5 -65.5t-50 -67.5t-44 -60.5t-38 -52t-25.5 -35.5 l-63 -312q-4 -27 -12.5 -33t-32.5 -6h-58q-36 0 -36 24q0 7 3 17l132 658q0 27 -7 26q-4 0 -8 -2q-10 -6 -47 -53t-51 -67q-4 -4 -12.5 -3t-10.5 5z" /> -<glyph unicode="o" horiz-adv-x="815" d="M78 317.5q0 131.5 73.5 256t206.5 214.5q131 90 213 91q72 0 133.5 -97.5t61.5 -220.5q0 -195 -113 -342q-47 -61 -121.5 -120.5t-148.5 -90.5q-72 -33 -115 -33q-70 0 -130 105.5t-60 237zM223 309q0 -102 41 -175t96 -73q102 0 183.5 144t81.5 330q0 109 -46.5 181 t-111.5 72q-96 0 -170 -144t-74 -335z" /> -<glyph unicode="p" horiz-adv-x="911" d="M-129 -522q4 6 47 12q41 6 66.5 16.5t39 35t18.5 42t13 58.5q35 178 205 991l2 8q2 8 3 14.5t3 16.5t2 18v15.5t-1 11.5t-5 4q-27 0 -84 -66q-18 -20 -43.5 -52t-27.5 -34q-8 -12 -24.5 4.5t-2.5 36.5q76 113 166 191t135 78q39 0 39 -64q0 -59 -27 -197q-8 -45 -2 -45 q2 2 13 19q2 4 4 6t40.5 59.5t57 79t56.5 63.5t72 59.5t69 17.5q70 0 106.5 -100.5t36.5 -211.5q0 -102 -47 -218t-123 -208t-184 -137q-63 -26 -126 -26q-46 0 -92 14q-6 2 -9 -5.5t-3 -13.5q-57 -252 -74 -333q-7 -39 -7 -66q0 -43 17 -58q29 -24 150 -28q14 0 8 -27 q-5 -20 -22 -20h-4q-112 5 -226.5 5t-232.5 -5q-9 2 -9 13q0 14 7 26zM293 102q0 -31 12 -39q42 -28 72 -28h2q127 0 228.5 159.5t101.5 362.5q0 90 -22.5 148.5t-57.5 58.5q-33 0 -125 -121q-72 -94 -144 -207z" /> -<glyph unicode="q" horiz-adv-x="872" d="M106 217q0 197 170 395q221 266 519 267q41 -1 41 -35q0 -7 -2 -15l-234 -1136q-23 -119 -22 -133q0 -18 4 -30.5t14 -21t18.5 -12.5t25.5 -6t25.5 -2h29h26.5q10 2 14 -5t2 -20q-3 -25 -20 -25q-4 0 -8 1q-122 3 -236.5 3t-220.5 -3q-12 2 -12 15.5t9 24.5t19 9 q104 10 134 30.5t44 92.5q27 133 121 579q14 51 4 54q-2 0 -6 -4q-63 -78 -169.5 -171.5t-162.5 -93.5q-51 0 -89 74t-38 168zM248 250q0 -158 69 -158q29 0 91.5 56.5t193.5 199.5l74 381q1 5 1 10q0 19 -15 19q-145 -8 -234 -80q-82 -66 -131 -184.5t-49 -243.5z" /> -<glyph unicode="r" horiz-adv-x="661" d="M80 606q-7 9 -7 18q0 10 9 19q188 233 246 234q39 0 43 -60v-7q0 -24 -9 -85q-12 -86 -32 -184q-10 -59 -21 -95q-12 -48 -12 -60q0 -4 2 -3q4 0 18 43q164 451 306 451q69 0 75 -68q1 -10 0 -19q0 -49 -18 -75q-15 -21 -40 -21q-12 0 -26 4l-36 13q-82 -12 -160 -166 q-20 -41 -101 -250q-18 -45 -29.5 -88t-24.5 -105.5t-19 -89.5q-8 -37 -45 -37h-56q-33 0 -24 48l108 643q8 55 -14 55q-12 0 -50 -44t-50 -63q-23 -23 -33 -8z" /> -<glyph unicode="s" horiz-adv-x="655" d="M29 76q6 62 54 68q8 1 16 1q38 0 69 -26q6 -4 27.5 -17.5t32 -19.5t28.5 -14.5t34.5 -12.5t33.5 -4q47 0 78.5 31t31.5 76q0 27 -10 55.5t-32.5 61t-37 51t-47.5 55.5t-37 43q-78 93 -78 173q0 84 91 179q102 102 204 103q53 0 103.5 -47.5t50.5 -96.5q0 -29 -17.5 -50 t-43.5 -21q-35 0 -58 43q-59 100 -104 100q-43 0 -84 -47t-41 -92q0 -20 9 -44t28.5 -50.5t35 -45t40 -46t30.5 -36.5q90 -104 90 -200q0 -123 -91 -197t-242 -74q-78 0 -124 27q-41 24 -41 63q0 6 1 11z" /> -<glyph unicode="t" horiz-adv-x="577" d="M121 61q0 72 43 250q18 78 102 416q0 2 2 8q10 39 -14 39h-78q-18 0 -21 14.5t11 20.5q109 55 178.5 130t142.5 194q5 8 15 13q6 3 12 3q3 0 6 -1q8 -3 8 -18q-92 -223 -98 -258q-2 -8 5 -12t18 -2h131q11 0 11 -19q0 -10 -3 -24q-4 -18 -10.5 -30.5t-16.5 -10.5h-135 q-18 -6 -18 -8l-4 -10l-142 -621q-6 -22 -6 -37q0 -26 19 -26q47 0 194 155q14 16 29 -10q10 -20 0 -31q-195 -211 -305 -211q-35 0 -55.5 22.5t-20.5 63.5z" /> -<glyph unicode="u" horiz-adv-x="997" d="M129 614q-1 4 -1 7q0 7 3 12q41 61 126 151t130 90q46 0 46 -66q0 -32 -11 -79l-100 -504q-6 -33 -8.5 -53t1.5 -38.5t23.5 -13.5t54.5 36q74 68 179.5 223.5t134.5 247.5q18 55 45 221q6 33 45 33q27 -2 63 0q33 0 33 -34q0 -8 -2 -18l-129 -659q-3 -15 -3 -24 q0 -17 9 -17q7 0 18 8q14 10 35 33q55 59 76 86q10 16 25 -4q7 -11 7 -21q0 -4 -1 -8q-78 -98 -161 -173t-116 -75q-43 0 -43 64q0 133 66 381q6 23 -2 20q-8 -2 -21 -22q-125 -193 -241.5 -318t-182.5 -125q-61 0 -61 110q0 56 16 142l92 463q8 37 0 37q-12 0 -29.5 -15.5 t-30.5 -32.5t-30.5 -41t-21.5 -28q-10 -12 -20.5 -10t-12.5 14z" /> -<glyph unicode="v" horiz-adv-x="831" d="M80 610q-2 5 -2 8q0 7 4 13q176 246 262 246q47 0 47 -74q0 -41 -14 -127l-80 -494q0 -2 -3 -17t-3 -27.5t-1 -27t4 -22.5t13 -8q66 0 163 125t166 274.5t69 220.5q0 27 -25 41q-27 14 -27 39q0 33 37 66t70 33q41 0 67.5 -37t26.5 -94q0 -106 -121 -294t-274.5 -333.5 t-237.5 -145.5q-57 0 -57 125q0 67 16 170l62 379q6 44 6 66t-6 22q-25 0 -129 -137q-8 -10 -18.5 -6t-14.5 16z" /> -<glyph unicode="w" horiz-adv-x="1249" d="M72 623q31 45 69.5 94t100 105.5t98.5 56.5q43 0 43 -85q0 -40 -10 -100l-74 -499q-4 -35 -3 -59q0 -52 17 -52q49 0 176 158.5t187 261.5l51 334q4 37 43 36q23 2 49 3q38 0 38 -30q0 -5 -1 -11l-100 -652q0 -2 -3 -17t-3 -27.5t-1 -27t4 -22.5t13 -8q53 0 144 110.5 t164 259t73 240.5q0 29 -23 51q-25 18 -24 39q0 41 29.5 68t70.5 27q39 0 64.5 -35t25.5 -86q0 -141 -157.5 -366.5t-298.5 -338.5q-27 -20 -58 -39q-30 -18 -70 -32q-16 -6 -31 -7q-20 1 -35 13q-26 20 -26 77q0 76 17 164q4 20 8 43t6 40.5t4 33.5q4 23 2 23q-4 0 -26 -37 q-70 -113 -192 -233t-206 -120q-68 0 -68 108q0 15 1 32q4 59 12 114q49 317 68 471q4 23 -1.5 26t-21.5 -11q-31 -25 -113 -131q-12 -14 -32 3q-10 9 -9 17q0 9 9 17z" /> -<glyph unicode="x" horiz-adv-x="1032" d="M92 227q18 47 33 47q10 -2 14 -30q10 -63 17 -80q12 -29 32.5 -36t47 5t49 27.5t50 44t39 42t25.5 29.5l88 111q6 16 2 29l-100 252q-23 55 -37 75.5t-35 20.5q-27 0 -54 -32t-85 -128q-14 -27 -32.5 -12.5t-6.5 37.5q84 143 133.5 196.5t100.5 53.5q45 0 73.5 -35 t65.5 -129l68 -178q6 -10 14 -5t18 19q150 207 211 268q39 39 89 53q17 5 31 4q31 0 55 -18q36 -26 36 -92q0 -33 -18 -98q-6 -23 -13.5 -27t-12.5 4t-9 23q-16 84 -86 84q-76 0 -168 -129l-102 -144q-14 -16 -7 -33l78 -208q29 -76 47.5 -104t38.5 -28q53 2 119 142 q12 29 29 12q12 -8 12 -41q-66 -147 -115 -195.5t-104 -48.5q-43 0 -62.5 27t-60.5 127l-76 190q-8 18 -24 -2l-74 -90q-207 -252 -311 -252q-64 0 -64 78q0 62 41 174z" /> -<glyph unicode="y" horiz-adv-x="894" d="M-42 -538q3 24 26 24q92 4 114.5 13t46.5 59q113 227 160 356q61 170 66 225q5 69 5 140q0 134 -18 271q-26 210 -82 210q-35 0 -102 -94q-6 -8 -18.5 -25.5t-18.5 -26.5q-12 -16 -28 7q-12 18 -3 34q150 221 230 222q90 0 123 -273q23 -187 23 -335q0 -67 -5 -126 q-2 -23 1 -27.5t8.5 1.5t15.5 22q257 433 257 561q0 7 -1 13q-2 8 -17 39q-12 25 -12 36q0 37 25.5 64t60.5 27q39 0 63.5 -31t24.5 -80q0 -72 -72 -205q-33 -57 -178 -270q-115 -166 -151 -246q-35 -78 -97.5 -230.5t-95.5 -226.5q-24 -49 -24 -72q0 -8 3 -13 q11 -19 97 -19h13t12.5 -2t9.5 -8t0 -15q-8 -26 -28 -26h-1q-113 6 -230 6q-95 0 -192 -4q-12 0 -12 17q0 3 1 8z" /> -<glyph unicode="z" horiz-adv-x="999" d="M35 14q0 53 67 144q129 170 521 377q119 61 174 98q61 39 88 65q20 20 14 23.5t-25 -8.5q-102 -49 -192 -49q-60 0 -115 22q-25 10 -69.5 33.5t-82.5 38t-75 14.5q-41 0 -67.5 -21.5t-75.5 -84.5q-4 -8 -17.5 -6t-19.5 10t2 20q139 184 274 184q82 0 197 -67 q6 -4 26.5 -15.5t28.5 -15.5t26.5 -13t30 -12t27.5 -6.5t33 -2.5q100 0 119 83q6 27 6 29q10 16 37 16q34 0 34 -39q0 -94 -128 -211.5t-238 -175.5q-31 -16 -114 -56t-128 -64q-135 -72 -205 -136q-14 -14 -10 -18q4 -2 19 6q78 39 151 39q84 0 195 -63q109 -63 159 -64 q90 0 160 107q12 16 25.5 1.5t5.5 -26.5q-59 -88 -131 -140.5t-131 -52.5q-16 0 -33.5 4.5t-31 8.5t-34 15t-28.5 16.5t-30.5 19.5t-27.5 16q-131 78 -219 78q-63 0 -82.5 -20.5t-19.5 -57.5q0 -45 -4 -55q-10 -27 -51 -27q-35 0 -35 39z" /> -<glyph unicode="{" horiz-adv-x="825" d="M129 457v22q0 12 14 15q96 23 153.5 80t57.5 128q0 55 -24.5 160t-24.5 160q0 158 109.5 273.5t281.5 136.5q20 2 21 -19q0 -27 -21 -33q-113 -20 -173 -83.5t-60 -157.5q0 -55 20.5 -164t20.5 -162q0 -135 -109 -244q-59 -59 -131 -90q-33 -14 4 -26q236 -117 236 -332 q0 -55 -20.5 -163t-20.5 -163q0 -186 231 -246q14 -4 18.5 -16t-0.5 -22.5t-16 -10.5q-172 23 -280.5 138.5t-108.5 271.5q0 53 23.5 156.5t23.5 156.5q0 76 -52 131.5t-150 79.5q-23 6 -23 23z" /> -<glyph unicode="|" horiz-adv-x="1062" d="M471 -39v1770h119v-1770h-119z" /> -<glyph unicode="}" horiz-adv-x="825" d="M103.5 -463q7.5 14 25.5 14q113 20 173 84t60 156q0 57 -20 166t-20 164q0 133 108 241q53 53 109 82q29 12 31.5 19.5t-19.5 19.5q-231 123 -232 330q0 31 21 158q23 117 22 164q0 186 -231 249q-16 8 -20.5 19.5t3 21t15.5 9.5q172 -25 280.5 -139.5t108.5 -270.5 q0 -53 -23.5 -157.5t-23.5 -157.5q0 -82 59.5 -139.5t167.5 -77.5q12 -6 16.5 -26t-14.5 -26q-106 -18 -166.5 -76.5t-60.5 -134.5h-2q0 -53 24.5 -157.5t24.5 -159.5q0 -158 -109.5 -274.5t-281.5 -137.5q-16 -2 -24.5 10.5t-1 26.5z" /> -<glyph unicode="~" horiz-adv-x="1128" d="M188 502q2 135 81 228t190 93q59 0 116.5 -20.5t161.5 -79.5q139 -80 211 -80t118 45t54 129q6 18 30 17t26 -17q-4 -137 -79 -228t-184 -91q-102 0 -299 106q-143 80 -204 80q-70 0 -117 -50t-53 -132q-8 -12 -29 -12.5t-23 12.5z" /> -<glyph unicode="¡" horiz-adv-x="608" d="M123 -420l252 912q8 20 22 20h11q18 -9 16 -29l-121 -903q-6 -45 -20.5 -61.5t-55.5 -16.5h-43q-47 0 -60 16.5t-1 61.5zM360 756q4 49 34 81.5t69 32.5q37 0 60.5 -28.5t23.5 -73.5q0 -53 -30 -89t-75 -36t-66.5 35t-15.5 78z" /> -<glyph unicode="¢" horiz-adv-x="565" d="M86 195q0 180 98.5 374.5t229.5 268.5q14 8 20 43l76 417q2 20 20 19l11 -4q18 -4 16 -19l-74 -403q-6 -27 23 -21q12 2 35 2q113 0 112 -84q0 -31 -15 -51t-42 -20q-37 0 -100 37q-35 18 -41 -15l-119 -643q-4 -18 3 -24t23 -2q82 12 170 118q10 14 19 7l16 -13 q12 -10 2 -20q-115 -139 -231 -180q-25 -8 -27 -29l-73 -410q-6 -29 -27 -24l-10 2q-8 0 -12.5 4t-2.5 18l74 400q4 25 -18 28q-72 10 -114 69.5t-42 154.5zM227 217q0 -78 37 -119q10 -8 18.5 -2t10.5 19l110 608q5 19 3 25q-8 10 -21 0q-20 -18 -35 -48q-49 -80 -86 -228 t-37 -255z" /> -<glyph unicode="£" horiz-adv-x="1519" d="M98 -444q0 55 71 115.5t163 86.5q70 92 135 234q41 90 57 131h-278l12 61h289l14 37q131 344 268 621q141 283 277 436q137 156 305 156q78 0 130 -36t52 -89q0 -31 -21.5 -52.5t-53.5 -21.5q-12 0 -23.5 4t-18 7t-16.5 13.5t-13 14.5t-13.5 18.5t-12.5 16.5 q-33 45 -86 45q-94 0 -174 -121q-66 -102 -192 -402q-129 -303 -213 -483q-47 -102 -82 -164h342l-12 -61h-363q-70 -127 -137 -232q-27 -41 -84 -112q63 14 129 14q104 0 171.5 -21.5t186.5 -90.5q139 -84 232 -84q66 0 110.5 43t44.5 104q0 29 -14 61l-31 62 q-10 25 -10 45q0 29 19.5 51.5t46.5 22.5q41 0 66.5 -39t25.5 -101q0 -137 -100.5 -239.5t-233.5 -102.5q-127 0 -254 72q-20 12 -109 66q-141 88 -284 88h-33q-156 -227 -229 -228q-23 0 -39.5 15.5t-16.5 38.5z" /> -<glyph unicode="¤" d="M203 266l131 133q-59 88 -77.5 145.5t-18.5 145.5t19 143.5t77 137.5l-131 129l82 84l131 -131q76 61 130 79.5t148 18.5t149.5 -18.5t133.5 -79.5l127 131l80 -84l-127 -129q59 -84 77.5 -141.5t18.5 -151.5t-19.5 -149.5t-76.5 -131.5l127 -131l-80 -82l-127 131 q-82 -61 -137.5 -80.5t-147.5 -19.5q-94 0 -147 19.5t-129 80.5l-131 -131zM354 684q0 -145 98.5 -247.5t239.5 -102.5q143 0 243.5 101.5t100.5 246.5t-99 247.5t-239 102.5q-143 0 -243.5 -101.5t-100.5 -246.5z" /> -<glyph unicode="¥" horiz-adv-x="1042" d="M39 721l14 49q6 14 33 14h68.5h139.5h124q35 0 41 5.5t0 27.5l-45 170q-6 27 -37 31h-15h-219q-10 -2 -15 5t-3 15l2 4q0 4 2 8.5t2 8.5q6 16 8 24q4 10 19 13h37l155 2q27 0 28 10t-13 51q-33 102 -56.5 140t-66.5 53q-4 0 -8.5 2t-8.5 2t-8 4q-4 0 -4 12l4 25q0 2 1 7 t3 7t23 2q242 -6 415 0q23 0 23 -12l-8 -31q-4 -12 -19 -12q-72 0 -102.5 -20.5t-30.5 -67.5q0 -51 27 -123q12 -47 49 -49q156 -8 272 0q29 0 41 20q47 72 64 99q41 63 41 87.5t-23.5 37t-91.5 16.5q-10 0 -13 2t-1 10l6 29q4 12 31 12q59 2 167.5 -2t188.5 4q12 2 19.5 -5 t3.5 -17l-21 -31q-92 -14 -137 -60q-20 -20 -53 -69q-57 -82 -80 -113q-10 -20 26 -20h13h145q14 0 2 -33l-10 -35q-8 -18 -29 -14q-18 2 -194 2q-31 0 -45 -27q-80 -119 -121 -172q-18 -25 2 -35q8 -2 28 -2q16 0 61.5 -1t70.5 -1q90 -4 110 0q8 0 14.5 -2t9.5 -6t4 -8 t0 -11.5t-2 -11.5t-4 -11t-3 -9q-8 -25 -31 -25q-37 6 -305 2q-53 0 -74 -51l-105 -360q-35 -115 -34 -158q0 -41 26.5 -55.5t116.5 -20.5q18 0 16 -10l-12 -37q-8 -14 -35 -14q-190 10 -487 0q-14 0 -14 16l8 31q2 14 26 14q10 0 23.5 1t21 2t13.5 1q14 0 28 6 q45 23 62.5 52.5t52.5 156.5l119 400q-10 29 -41 26h-395q-14 2 -20.5 3t-9.5 6.5t-1 13.5zM598 981l51 -199q2 -10 6 -15t11 -3q4 4 20 27q61 78 131 196q10 20 4 25.5t-37 5.5h-153q-25 0 -32 -6t-1 -31z" /> -<glyph unicode="¦" horiz-adv-x="1062" d="M471 -39v756h119v-756h-119zM471 975v756h119v-756h-119z" /> -<glyph unicode="§" horiz-adv-x="997" d="M-80 -393q0 25 21 61q27 39 53 39q33 0 92 -41q74 -49 100.5 -60.5t63.5 -11.5q92 0 156.5 92.5t64.5 225.5q0 84 -22.5 156.5t-94.5 222.5q-119 248 -118 411q0 154 82.5 315t220.5 271q180 145 376 146q80 0 139.5 -29t59.5 -72q0 -41 -22.5 -73.5t-53.5 -32.5 q-37 0 -92 43q-57 43 -90 57t-76 14q-74 0 -123 -71.5t-49 -182.5q0 -164 113 -430q78 -182 99.5 -261t21.5 -175q0 -172 -101.5 -332.5t-279.5 -273.5t-344 -113q-84 0 -140.5 29t-56.5 76zM336 727q0 -172 84 -344l65 -135q74 -152 74 -297q0 -92 -43 -199 q227 195 227 457q0 150 -102 383q-59 137 -76 184q-47 127 -47 262q0 61 23 148q-205 -244 -205 -459z" /> -<glyph unicode="¨" horiz-adv-x="694" d="M225 1098q0 45 31 76.5t76 31.5q43 0 73.5 -31.5t30.5 -76.5q0 -43 -31.5 -75t-72.5 -32q-45 0 -76 32t-31 75zM567 1100q0 45 32 76.5t77 31.5q43 0 73.5 -31.5t30.5 -76.5t-30.5 -77t-73.5 -32q-45 0 -77 32t-32 77z" /> -<glyph unicode="©" horiz-adv-x="1583" d="M199 700.5q0 305.5 214 522.5t517 217t518 -217t215 -522.5t-215 -522.5t-518 -217t-517 217t-214 522.5zM276 700.5q0 -274.5 190.5 -467t463 -192.5t464 192.5t191.5 467t-191.5 467t-464 192.5t-463 -192.5t-190.5 -467zM453 694q0 209 148.5 347.5t369.5 138.5 q76 0 192 -39q25 -8 35 -8q14 0 23.5 9t21.5 38h29q23 0 24 -19l19 -241q8 -45 -17 -46h-24q-8 0 -13.5 6.5t-7.5 17.5t-4 15q-80 205 -291 205q-150 0 -242.5 -106.5t-92.5 -288.5q0 -199 93 -307.5t253 -108.5q190 0 303 152q16 20 35 12l12 -8q20 -15 8 -31 q-152 -205 -393 -205q-205 0 -343 134.5t-138 332.5z" /> -<glyph unicode="ª" horiz-adv-x="542" d="M205 950q0 94 70.5 194.5t177.5 158.5q96 53 192 53h37l-82 -377q-10 -57 -10 -68q0 -12 8 -12t47 35q6 6 17.5 18.5t15.5 16.5v-41q-2 -4 -8 -8l-2 -2q-4 -4 -4 -7q-90 -94 -129 -94q-18 0 -30.5 17.5t-12.5 44.5q0 37 18 110q-172 -172 -221 -172q-33 0 -58.5 41 t-25.5 92zM297 975q0 -37 11 -61.5t28 -24.5q12 0 53 33q6 6 46 41.5t73 62.5l12 10l53 248q-96 -8 -147 -43q-57 -37 -93 -110.5t-36 -155.5z" /> -<glyph unicode="«" horiz-adv-x="913" d="M195 467l403 395h51l-301 -397l127 -393h-55zM547 467l325 348h56l-226 -350l58 -342h-53z" /> -<glyph unicode="¬" d="M141 877v120h1106v-624h-117v504h-989z" /> -<glyph unicode="­" horiz-adv-x="679" d="M123 382q-4 5 0 40q0 12 8 41q8 23 16 24q8 2 27 2h428q10 0 14.5 -1t8.5 -7t0 -18q-4 -37 -13 -68q-8 -23 -26 -18h-426q-33 0 -37 5z" /> -<glyph unicode="®" horiz-adv-x="1583" d="M160 704.5q0 309.5 217 528.5t522 219t523 -219t218 -528.5t-218 -527.5t-523 -218t-522 218t-217 527.5zM240 705q0 -276 192.5 -471t467 -195t468 195t193.5 471q0 279 -193.5 473t-468 194t-467 -194.5t-192.5 -472.5zM487 264v25q0 12 21 12q57 2 71.5 25.5 t14.5 109.5v547q0 86 -12.5 108.5t-65.5 24.5q-16 0 -16 14v19q0 23 24 18q182 -4 381 0q139 2 227.5 -64.5t88.5 -174.5q0 -166 -201 -232q-23 -6 -6 -30l192 -277q35 -49 58.5 -67.5t58.5 -20.5q4 0 7 -3t3 -7v-9.5t-1 -10.5t-1 -7q0 -10 -3 -12t-13 -2h-4q-61 4 -154 0 q-23 -4 -37 10l-295 412h-41q-25 0 -24 -41v-197v-76q0 -55 112 -57q8 0 9 -14v-25q0 -16 -21 -12q-193 8 -352 0q-4 -2 -12.5 2t-8.5 12zM760 756q0 -23 22 -23q123 0 189.5 48t66.5 134q0 82 -56 136.5t-144 54.5q-37 0 -78 -14v-336z" /> -<glyph unicode="¯" horiz-adv-x="694" d="M193 1108l22 78q2 6 4 14q2 10 5 12t18 2h10h539q48 0 36 -45l-18 -69q-12 -33 -37 -27h-545q-43 0 -34 35z" /> -<glyph unicode="°" horiz-adv-x="825" d="M268 1036q0 133 93.5 227.5t222.5 94.5q131 0 223 -94.5t92 -227.5t-92 -227t-223 -94q-129 0 -222.5 94t-93.5 227zM360 1036q0 -94 66 -159.5t158 -65.5t156.5 65.5t64.5 159.5t-64.5 161t-156.5 67t-158 -67t-66 -161z" /> -<glyph unicode="±" d="M141 -45v121h1106v-121h-1106zM141 793v118h492v504h119v-504h495v-118h-495v-504h-119v504h-492z" /> -<glyph unicode="²" horiz-adv-x="651" d="M170 657.5q0 16.5 23 34.5q6 6 64 55.5t80.5 70t75 67.5t80 76.5t58.5 66.5t47 66q25 45 30 87t-21.5 73.5t-86.5 31.5q-109 0 -166 -110q-12 -25 -43 -25q-25 0 -14 31q27 82 91.5 127t154.5 45q94 0 154.5 -46t60.5 -118q0 -117 -211 -275q-2 -2 -168 -133 q-57 -47 -8 -47h176q63 0 74 45q2 20 28 21q14 0 18.5 -1t8.5 -8.5t-2 -21.5l-23 -106q-4 -27 -65 -21q-20 0 -100 1t-153 1t-122 -2q-41 -2 -41 14.5z" /> -<glyph unicode="³" horiz-adv-x="651" d="M186 684q0 20 17.5 33.5t40.5 13.5q14 0 56 -19.5t73 -19.5q78 0 137 82q57 74 57 154q0 45 -24.5 71.5t-63.5 26.5q-20 0 -80 -29q-27 -12 -37 13q4 23 29 41q123 61 167 100t44 78q0 29 -20.5 47t-53.5 18q-53 0 -110 -57q-16 -14 -20.5 -16t-22.5 6q-20 16 0 39 q76 90 188 90q72 0 119 -33t47 -84q0 -78 -117 -131q-12 -6 -11 -14.5t11 -12.5q86 -29 86 -123q0 -98 -85 -186t-214 -127q-35 -16 -124 -14t-89 53z" /> -<glyph unicode="´" horiz-adv-x="694" d="M408 1030q78 248 86 297q8 20 38 21q90 4 134 0q16 4 24 -4.5t-2 -24.5q-59 -82 -250 -297q-6 -6 -14 -7t-13 3t-3 12z" /> -<glyph unicode="¶" horiz-adv-x="933" d="M-18 928q0 186 122.5 290.5t339.5 104.5h490q16 0 16 -27q0 -41 -20 -36h-86q-29 -4 -29 -31v-1706q0 -25 -37 -21q-27 2 -35 6.5t-10 20.5v1690q0 41 -35 41h-110q-31 0 -35 -33v-1706q-2 -18 -45 -19q-39 0 -39 23v964q0 27 -7 35t-30 8q-305 6 -403 199 q-47 90 -47 197z" /> -<glyph unicode="·" horiz-adv-x="608" d="M270 602q0 45 32 77t75 32q45 0 76.5 -32t31.5 -77t-31.5 -77.5t-76.5 -32.5q-43 0 -75 32.5t-32 77.5z" /> -<glyph unicode="¸" horiz-adv-x="694" d="M80 -379q0 14 14 19q25 -2 43 -2q88 0 135 31.5t47 90.5q0 68 -86 76q-18 2 -12 23l68 133h43l-23 -45q53 -8 84 -47.5t31 -96.5q0 -98 -76 -153.5t-207 -55.5q-16 0 -45 3q-23 12 -16 24z" /> -<glyph unicode="¹" horiz-adv-x="651" d="M295 644q-6 5 0 18q6 18 13 20t44 2q51 0 64 57l98 430q2 23 -7 27t-18 -4q-76 -45 -147 -70q-14 -4 -19.5 -1t-0.5 14l8 34q154 55 256 164q23 23 32 21h35q25 0 17 -37l-133 -576q-8 -35 7 -46t54 -13q12 0 19.5 -5t5.5 -17q-8 -25 -29 -25q-168 4 -264 2 q-18 -2 -23.5 -1t-11.5 6z" /> -<glyph unicode="º" horiz-adv-x="542" d="M229 1020q0 172 185 285q78 51 135 51q53 0 90 -56.5t37 -134.5q0 -106 -65.5 -193t-182.5 -136q-43 -18 -74 -19q-49 0 -87 61.5t-38 141.5zM326 1016q0 -61 26.5 -103.5t63.5 -42.5q63 0 115.5 85t52.5 196q0 63 -30 107.5t-73 44.5q-59 0 -107 -87.5t-48 -199.5z" /> -<glyph unicode="»" horiz-adv-x="913" d="M190 119l230 350l-62 342h54l161 -344l-327 -348h-56zM469 72l303 397l-125 393h53l226 -395l-404 -395h-53z" /> -<glyph unicode="¼" horiz-adv-x="1714" d="M295 644q-6 5 0 18q6 18 13 20t44 2q51 0 64 57l98 430q2 23 -7 27t-18 -4q-76 -45 -147 -70q-14 -4 -19.5 -1t-0.5 14l8 34q154 55 256 164q23 23 32 21h35q25 0 17 -37l-133 -576q-8 -35 7 -46t54 -13q12 0 19.5 -5t5.5 -17q-8 -25 -29 -25q-168 4 -264 2 q-18 -2 -23.5 -1t-11.5 6zM322 -18l1237 1384q18 27 30.5 32t34.5 -5q36 -9 18 -50l-1263 -1413q-25 -8 -47 9q-33 10 -10 43zM1128 223q-10 20 23 51l420 412q18 16 43 21h20q23 0 13 -48l-82 -344q-6 -27 12 -34h70q16 0 16 -25l-12 -53h-92q-25 -16 -31 -39l-33 -148 q-6 -33 -20 -34q-4 -2 -11 -2l-71 2q-29 0 -21 32l37 154q6 27 -12 35h-226q-35 0 -38 8q-2 4 -5 12zM1262 305q-14 -23 4 -24h149q23 0 29 30l39 176q4 18 -2 22.5t-21 -7.5z" /> -<glyph unicode="½" horiz-adv-x="1714" d="M295 644q-6 5 0 18q6 18 13 20t44 2q51 0 64 57l98 430q2 23 -7 27t-18 -4q-76 -45 -147 -70q-14 -4 -19.5 -1t-0.5 14l8 34q154 55 256 164q23 23 32 21h35q25 0 17 -37l-133 -576q-8 -35 7 -46t54 -13q12 0 19.5 -5t5.5 -17q-8 -25 -29 -25q-168 4 -264 2 q-18 -2 -23.5 -1t-11.5 6zM322 -18l1237 1384q18 27 30.5 32t34.5 -5q36 -9 18 -50l-1263 -1413q-25 -8 -47 9q-33 10 -10 43zM1120 10v19q12 10 64.5 54t82 69.5t82 72.5t85 81t65.5 73t49 70q25 45 30 87t-21.5 72.5t-86.5 30.5q-106 0 -163 -109q-8 -16 -15.5 -20 t-27.5 -4q-25 0 -15 29q27 82 90.5 127t153.5 45q96 0 155.5 -45t59.5 -117q0 -106 -209 -266q-33 -25 -92 -74t-82 -68q-45 -43 -4 -47h176q66 0 74 43q2 23 28 23q14 0 18.5 -1t8.5 -8.5t-2 -23.5l-20 -105q-4 -25 -68 -22q-98 6 -373 0q-35 -2 -43 14z" /> -<glyph unicode="¾" horiz-adv-x="1714" d="M186 684q0 20 17.5 33.5t40.5 13.5q14 0 56 -19.5t73 -19.5q78 0 137 82q57 74 57 154q0 45 -24.5 71.5t-63.5 26.5q-20 0 -80 -29q-27 -12 -37 13q4 23 29 41q123 61 167 100t44 78q0 29 -20.5 47t-53.5 18q-53 0 -110 -57q-16 -14 -20.5 -16t-22.5 6q-20 16 0 39 q76 90 188 90q72 0 119 -33t47 -84q0 -78 -117 -131q-12 -6 -11 -14.5t11 -12.5q86 -29 86 -123q0 -98 -85 -186t-214 -127q-35 -16 -124 -14t-89 53zM322 -18l1237 1384q18 27 30.5 32t34.5 -5q36 -9 18 -50l-1263 -1413q-25 -8 -47 9q-33 10 -10 43zM1128 223 q-10 20 23 51l420 412q18 16 43 21h20q23 0 13 -48l-82 -344q-6 -27 12 -34h70q16 0 16 -25l-12 -53h-92q-25 -16 -31 -39l-33 -148q-6 -33 -20 -34q-4 -2 -11 -2l-71 2q-29 0 -21 32l37 154q6 27 -12 35h-226q-35 0 -38 8q-2 4 -5 12zM1262 305q-14 -23 4 -24h149 q23 0 29 30l39 176q4 18 -2 22.5t-21 -7.5z" /> -<glyph unicode="¿" horiz-adv-x="825" d="M106 -168q0 205 109 307q47 45 123 82q78 39 108.5 64.5t55.5 70.5q33 57 49 136q6 20 18 22h21q12 0 10 -33q-25 -240 -94 -331q-29 -39 -141 -103q-98 -55 -139.5 -105.5t-41.5 -113.5q0 -70 51.5 -117t129.5 -47q53 0 127 25q27 8 45 8q27 0 42 -23.5t15 -58.5 q0 -49 -55.5 -81t-135.5 -32q-131 0 -214 92.5t-83 237.5zM539 756q4 49 33.5 81.5t70.5 32.5q39 0 61.5 -28.5t22.5 -73.5q0 -53 -29.5 -89t-74.5 -36q-47 0 -66.5 37t-17.5 76z" /> -<glyph unicode="À" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q39 12 82 0q25 -4 25 -33l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q26 -4 20 -35q-2 -23 -28 -22q-207 10 -578 0q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403 q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-229 8 -492 0q-18 0 -14 24zM656.5 674q7.5 -10 29.5 -10l291 2q39 -1 39 28v424q0 27 -13.5 29t-21.5 -12l-324 -441q-8 -10 -0.5 -20zM932 1786.5q6 7.5 18 7.5h152 q20 0 24 -6v-2l2 -4l99 -312q2 -4 -2 -7t-13 -3q-16 0 -22 8l-252 299q-12 12 -6 19.5z" /> -<glyph unicode="Á" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q39 12 82 0q25 -4 25 -33l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q26 -4 20 -35q-2 -23 -28 -22q-207 10 -578 0q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403 q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-229 8 -492 0q-18 0 -14 24zM656.5 674q7.5 -10 29.5 -10l291 2q39 -1 39 28v424q0 27 -13.5 29t-21.5 -12l-324 -441q-8 -10 -0.5 -20zM1096 1479q78 250 86 297q8 20 39 20 q90 4 133 0q14 2 23 -5.5t-1 -23.5q-27 -37 -70.5 -90t-106 -123.5t-73.5 -83.5q-6 -6 -14 -7t-13 3t-3 13z" /> -<glyph unicode="Â" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q39 12 82 0q25 -4 25 -33l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q26 -4 20 -35q-2 -23 -28 -22q-207 10 -578 0q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403 q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-229 8 -492 0q-18 0 -14 24zM656.5 674q7.5 -10 29.5 -10l291 2q39 -1 39 28v424q0 27 -13.5 29t-21.5 -12l-324 -441q-8 -10 -0.5 -20zM848 1427q-12 2 0 15l299 301 q16 18 45 18q12 2 48 0t42 -2q31 -2 37 -30l70 -281q4 -20 -11 -21h-12l-162 195q-10 12 -26 2l-306 -197h-24z" /> -<glyph unicode="Ã" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q39 12 82 0q25 -4 25 -33l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q26 -4 20 -35q-2 -23 -28 -22q-207 10 -578 0q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403 q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-229 8 -492 0q-18 0 -14 24zM656.5 674q7.5 -10 29.5 -10l291 2q39 -1 39 28v424q0 27 -13.5 29t-21.5 -12l-324 -441q-8 -10 -0.5 -20zM825 1503q23 248 193 248 q70 0 181.5 -71.5t146.5 -71.5q70 0 90 121q2 20 22 20q19 0 19 -27q0 -106 -54.5 -177.5t-136.5 -71.5q-76 0 -185.5 71.5t-142.5 71.5q-39 0 -58 -26.5t-34 -98.5q-2 -16 -24 -16q-18 0 -17 28z" /> -<glyph unicode="Ä" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q39 12 82 0q25 -4 25 -33l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q26 -4 20 -35q-2 -23 -28 -22q-207 10 -578 0q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403 q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-229 8 -492 0q-18 0 -14 24zM656.5 674q7.5 -10 29.5 -10l291 2q39 -1 39 28v424q0 27 -13.5 29t-21.5 -12l-324 -441q-8 -10 -0.5 -20zM893 1546q0 45 30.5 77t75.5 32 q43 0 74 -32t31 -77q0 -43 -32 -75.5t-73 -32.5q-43 0 -74.5 32.5t-31.5 75.5zM1235 1548q0 45 31.5 77t74.5 32q45 0 76 -32t31 -77t-31 -77.5t-76 -32.5q-43 0 -74.5 32.5t-31.5 77.5z" /> -<glyph unicode="Å" horiz-adv-x="1419" d="M-86 20q2 27 29 27q82 16 131 51t129 140l852 1108q4 10 22 14q39 12 82 0q25 -4 25 -33l12 -1163q0 -59 25.5 -82t70.5 -29h58h14q26 -4 20 -35q-2 -23 -28 -22q-207 10 -578 0q-10 0 -14 12t1 25.5t19 13.5q135 0 182.5 35t47.5 133l-2 334q0 6 -10.5 14t-18.5 8h-403 q-14 0 -29 -14l-256 -340q-39 -51 -39 -86q0 -76 117 -80h53q12 0 16 -13t-3 -27.5t-19 -14.5q-229 8 -492 0q-18 0 -14 24zM656.5 674q7.5 -10 29.5 -10l291 2q39 -1 39 28v424q0 27 -13.5 29t-21.5 -12l-324 -441q-8 -10 -0.5 -20zM963 1620q0 82 58 141.5t138 59.5 q82 0 138.5 -58.5t56.5 -142.5t-56.5 -141.5t-138.5 -57.5q-80 0 -138 58.5t-58 140.5zM1038 1620q0 -51 35 -87t86 -36t87 36t36 87t-36 88t-87 37t-86 -36t-35 -89z" /> -<glyph unicode="Æ" horiz-adv-x="1976" d="M-53 20q6 18 18 23q90 8 158 68q57 47 108 112q8 12 46 59.5t69 86.5l649 827q20 27 21 39q0 16 -25.5 24.5t-105.5 14.5q-16 2 -18.5 8t3.5 18q10 25 31 27q508 -8 1045 -4q27 0 36 -6.5t9 -26.5q-16 -123 -49 -258q-16 -8 -21 -8q-14 -2 -25 8l-2 27q-10 113 -55 158 t-158 45h-364q-23 -4 -29 -33l-98 -502q-2 -14 7 -20.5t24 -6.5h376q141 0 193 127q4 8 8 13.5t6 5.5h11h8q16 -4 12 -27q-41 -131 -66 -332q-4 -27 -26 -26h-12q-8 2 -10.5 7t-0.5 15l2 9q0 86 -42 116.5t-164 30.5h-318q-20 -2 -31 -27l-84 -417q-4 -25 -4 -39 q0 -55 40 -77t149 -22h135q174 0 311 93q49 33 77 61.5t64 83.5h29q14 0 4 -31l-84 -239q-10 -29 -45 -29q-561 8 -1036 0q-27 0 -21 27q6 20 31 20q88 4 126 43t59 145l51 267q4 14 -1 19t-24 5h-371q-29 0 -51 -24l-200 -258q-66 -86 -66 -125t25.5 -53.5t109.5 -18.5 q16 -10 12 -20l-2 -5q-2 -4 -5 -7t-6 -7t-9 -6t-12 -2q-305 8 -414 0q-8 6 -8 24zM607 596q1 -8 5 -10t9 -2h340q20 0 32 32l121 611q0 27 -16 12l-482 -623q-10 -12 -9 -20z" /> -<glyph unicode="Ç" horiz-adv-x="1458" d="M59 567q0 219 128 400.5t350.5 286t488.5 104.5q242 0 447 -92q27 -12 16 -58q-4 -14 -80 -266q-4 -14 -17.5 -16t-22.5 6t-7 18q4 27 4 51q0 289 -354 289q-311 0 -532.5 -213t-221.5 -522q0 -242 123 -383t342 -141q328 0 545 311q4 8 18 9t23.5 -6t5.5 -19 q-61 -156 -107 -322q-2 -8 -15 -8t-24 8q-33 10 -61 10q-33 0 -125 -18q-158 -33 -266 -33l-17 -35q53 -8 84 -48t31 -95q0 -98 -75.5 -153.5t-207.5 -55.5q-16 0 -45 2q-23 12 -16 25q0 14 14 18q25 -2 43 -2q88 0 135.5 32t47.5 91q0 68 -86 76q-18 2 -13 22l62 125 q-264 10 -439.5 173t-175.5 429z" /> -<glyph unicode="È" horiz-adv-x="1355" d="M4 27q8 33 31 32q12 2 35.5 1t31.5 -1q74 6 104 40t50 132l180 859q12 57 13 88q0 90 -136 90h-53q-23 2 -18 28q6 27 39 27h1046q29 0 39 -9t6 -38q-23 -125 -53 -246q2 -6 -4 -9t-17 -3q-12 0 -17 5t-6 10t1 16.5t2 17.5q0 102 -54.5 147.5t-179.5 45.5h-344 q-45 0 -51 -29l-104 -498q-2 -14 8 -20t33 -6h336q92 0 139 28.5t86 110.5q4 14 31 8q18 -2 12 -16q-25 -98 -78 -371q0 -10 -16 -14q-20 -4 -27 24q-2 10 -2 23q0 80 -45 108.5t-174 28.5h-281q-43 0 -49 -29l-86 -409q-10 -23 -4 -40.5t5 -31.5t13.5 -23.5t19.5 -16.5 t25.5 -11t29.5 -7t33 -4.5t35 -1.5h36h8h143q186 0 303 84q55 39 81 64t67 78q6 10 17 12t18.5 -2t7.5 -12q-12 -29 -32.5 -94.5t-37 -117.5t-22.5 -61q-18 -18 -82 -18q-606 8 -1071 0q-8 0 -15.5 10t-5.5 21zM732 1787.5q5 6.5 16 6.5h151q20 0 25 -6q0 -2 2 -6l98 -312 q2 -4 -2 -7t-12 -3q-14 0 -23 8l-252 299q-8 14 -3 20.5z" /> -<glyph unicode="É" horiz-adv-x="1355" d="M4 27q8 33 31 32q12 2 35.5 1t31.5 -1q74 6 104 40t50 132l180 859q12 57 13 88q0 90 -136 90h-53q-23 2 -18 28q6 27 39 27h1046q29 0 39 -9t6 -38q-23 -125 -53 -246q2 -6 -4 -9t-17 -3q-12 0 -17 5t-6 10t1 16.5t2 17.5q0 102 -54.5 147.5t-179.5 45.5h-344 q-45 0 -51 -29l-104 -498q-2 -14 8 -20t33 -6h336q92 0 139 28.5t86 110.5q4 14 31 8q18 -2 12 -16q-25 -98 -78 -371q0 -10 -16 -14q-20 -4 -27 24q-2 10 -2 23q0 80 -45 108.5t-174 28.5h-281q-43 0 -49 -29l-86 -409q-10 -23 -4 -40.5t5 -31.5t13.5 -23.5t19.5 -16.5 t25.5 -11t29.5 -7t33 -4.5t35 -1.5h36h8h143q186 0 303 84q55 39 81 64t67 78q6 10 17 12t18.5 -2t7.5 -12q-12 -29 -32.5 -94.5t-37 -117.5t-22.5 -61q-18 -18 -82 -18q-606 8 -1071 0q-8 0 -15.5 10t-5.5 21zM872 1479q78 250 86 297q8 20 39 20q90 4 133 0 q14 2 23.5 -5.5t-0.5 -23.5q-27 -37 -71 -90t-106.5 -123.5t-72.5 -83.5q-6 -6 -14 -7t-13.5 3t-3.5 13z" /> -<glyph unicode="Ê" horiz-adv-x="1355" d="M4 27q8 33 31 32q12 2 35.5 1t31.5 -1q74 6 104 40t50 132l180 859q12 57 13 88q0 90 -136 90h-53q-23 2 -18 28q6 27 39 27h1046q29 0 39 -9t6 -38q-23 -125 -53 -246q2 -6 -4 -9t-17 -3q-12 0 -17 5t-6 10t1 16.5t2 17.5q0 102 -54.5 147.5t-179.5 45.5h-344 q-45 0 -51 -29l-104 -498q-2 -14 8 -20t33 -6h336q92 0 139 28.5t86 110.5q4 14 31 8q18 -2 12 -16q-25 -98 -78 -371q0 -10 -16 -14q-20 -4 -27 24q-2 10 -2 23q0 80 -45 108.5t-174 28.5h-281q-43 0 -49 -29l-86 -409q-10 -23 -4 -40.5t5 -31.5t13.5 -23.5t19.5 -16.5 t25.5 -11t29.5 -7t33 -4.5t35 -1.5h36h8h143q186 0 303 84q55 39 81 64t67 78q6 10 17 12t18.5 -2t7.5 -12q-12 -29 -32.5 -94.5t-37 -117.5t-22.5 -61q-18 -18 -82 -18q-606 8 -1071 0q-8 0 -15.5 10t-5.5 21zM586 1427q-12 2 0 15l299 301q16 18 45 18q12 2 48 0t42 -2 q31 -2 37 -30l69 -281q4 -20 -10 -21h-12l-162 195q-10 12 -27 2l-305 -197h-24z" /> -<glyph unicode="Ë" horiz-adv-x="1355" d="M4 27q8 33 31 32q12 2 35.5 1t31.5 -1q74 6 104 40t50 132l180 859q12 57 13 88q0 90 -136 90h-53q-23 2 -18 28q6 27 39 27h1046q29 0 39 -9t6 -38q-23 -125 -53 -246q2 -6 -4 -9t-17 -3q-12 0 -17 5t-6 10t1 16.5t2 17.5q0 102 -54.5 147.5t-179.5 45.5h-344 q-45 0 -51 -29l-104 -498q-2 -14 8 -20t33 -6h336q92 0 139 28.5t86 110.5q4 14 31 8q18 -2 12 -16q-25 -98 -78 -371q0 -10 -16 -14q-20 -4 -27 24q-2 10 -2 23q0 80 -45 108.5t-174 28.5h-281q-43 0 -49 -29l-86 -409q-10 -23 -4 -40.5t5 -31.5t13.5 -23.5t19.5 -16.5 t25.5 -11t29.5 -7t33 -4.5t35 -1.5h36h8h143q186 0 303 84q55 39 81 64t67 78q6 10 17 12t18.5 -2t7.5 -12q-12 -29 -32.5 -94.5t-37 -117.5t-22.5 -61q-18 -18 -82 -18q-606 8 -1071 0q-8 0 -15.5 10t-5.5 21zM649 1546q0 45 31 77t76 32q43 0 73.5 -32t30.5 -77 q0 -43 -31.5 -75.5t-72.5 -32.5q-43 0 -75 32.5t-32 75.5zM991 1548q0 45 32 77t77 32q43 0 73.5 -32t30.5 -77t-30.5 -77.5t-73.5 -32.5q-45 0 -77 32.5t-32 77.5z" /> -<glyph unicode="Ì" horiz-adv-x="729" d="M47 27q8 25 33 24q100 -2 137 37t59 143l183 861q27 86 5 128t-124 48q-25 -2 -39 3t-6 27q6 25 33 25q258 -12 534 0q22 0 10 -33q-10 -29 -36 -20q-100 -6 -135 -38t-58 -142l-182 -861q-23 -106 11 -145t149 -37q27 0 18 -29q-4 -18 -23 -22q-379 10 -555 0 q-23 0 -14 31zM417 1787.5q5 6.5 15 6.5h152q23 0 24 -6l2 -2q0 -4 2 -4l99 -312q0 -10 -15 -10q-16 0 -22 8l-254 299q-8 14 -3 20.5z" /> -<glyph unicode="Í" horiz-adv-x="729" d="M47 27q8 25 33 24q100 -2 137 37t59 143l183 861q27 86 5 128t-124 48q-25 -2 -39 3t-6 27q6 25 33 25q258 -12 534 0q22 0 10 -33q-10 -29 -36 -20q-100 -6 -135 -38t-58 -142l-182 -861q-23 -106 11 -145t149 -37q27 0 18 -29q-4 -18 -23 -22q-379 10 -555 0 q-23 0 -14 31zM559 1479q6 23 27.5 92t38 125.5t20.5 79.5q8 20 39 20q86 6 133 0q14 2 22.5 -5.5t-1.5 -23.5q-51 -74 -250 -297q-6 -6 -14.5 -7t-12.5 3t-2 13z" /> -<glyph unicode="Î" horiz-adv-x="729" d="M47 27q8 25 33 24q100 -2 137 37t59 143l183 861q27 86 5 128t-124 48q-25 -2 -39 3t-6 27q6 25 33 25q258 -12 534 0q22 0 10 -33q-10 -29 -36 -20q-100 -6 -135 -38t-58 -142l-182 -861q-23 -106 11 -145t149 -37q27 0 18 -29q-4 -18 -23 -22q-379 10 -555 0 q-23 0 -14 31zM338 1430q-12 2 0 14l299 301q16 18 45 18q12 2 48 0t42 -2q31 -2 37 -30l70 -281q4 -20 -11 -20h-12l-162 194q-10 12 -26 2l-306 -196h-24z" /> -<glyph unicode="Ï" horiz-adv-x="729" d="M47 27q8 25 33 24q100 -2 137 37t59 143l183 861q27 86 5 128t-124 48q-25 -2 -39 3t-6 27q6 25 33 25q258 -12 534 0q22 0 10 -33q-10 -29 -36 -20q-100 -6 -135 -38t-58 -142l-182 -861q-23 -106 11 -145t149 -37q27 0 18 -29q-4 -18 -23 -22q-379 10 -555 0 q-23 0 -14 31zM377 1546q0 47 29.5 78t74.5 31q43 0 74 -32t31 -77q0 -43 -31 -75.5t-74 -32.5t-73.5 32.5t-30.5 75.5zM719 1548q0 45 30.5 77t75.5 32t75 -31t30 -78q0 -45 -31 -77.5t-74 -32.5q-45 0 -75.5 32.5t-30.5 77.5z" /> -<glyph unicode="Ð" horiz-adv-x="1583" d="M63 12l7 27q6 14 20 14h6q98 0 132 35t59 168l59 305q0 41 -37 41h-149q-16 -4 -26.5 5t-8.5 28q14 45 12 65q6 20 53 21h166q16 6 27 24l70 347q12 68 12 90q0 94 -127 94h-41q-18 0 -18 12l6 23q6 12 20 12q106 4 606 0q307 -2 487.5 -162t180.5 -428 q0 -313 -224.5 -527t-559.5 -212l-703 2q-14 0 -22.5 4t-6.5 12zM449 174q0 -68 47 -93.5t176 -25.5q305 0 507.5 188.5t202.5 499.5q0 141 -48 245t-135 162t-194.5 86t-238.5 28h-61q-39 0 -54 -45l-90 -453q-8 -45 29 -45q223 6 264 0q12 2 18.5 -6t1.5 -29l-10 -53 q-12 -31 -35 -31h-254q-18 0 -35.5 -11t-19.5 -30l-65 -334q-6 -25 -6 -53z" /> -<glyph unicode="Ñ" horiz-adv-x="1615" d="M25 25q6 23 22 20q102 14 146.5 62.5t68.5 171.5l187 923q-14 18 -30 30.5t-37.5 18.5t-33.5 9.5t-42 6.5t-40 5q-18 4 -14 26q2 25 22 25q90 -4 240 0q55 0 66 -16l671 -1035q27 -39 39 0l166 783q25 115 -10 164t-160 57q-10 0 -10 22q2 25 20 25q185 -8 457 0 q25 2 8 -29q-8 -16 -18 -16q-96 -14 -145.5 -64.5t-71.5 -158.5l-228 -1078q-2 -8 -27.5 -9t-35.5 9l-703 1100q-23 29 -30 -8l-152 -780q-20 -111 7.5 -167t138.5 -71q20 0 25 -5t3 -23q-4 -27 -18 -27q-279 10 -465 0q-23 -2 -16 29zM731 1440q23 248 193 248 q70 0 181.5 -72t145.5 -72q70 0 90 121q2 20 23 21q18 0 18 -27q0 -106 -54 -178t-136 -72q-76 0 -185.5 71.5t-142.5 71.5q-39 0 -58.5 -26.5t-33.5 -98.5q-2 -16 -24 -16q-18 0 -17 29z" /> -<glyph unicode="Ò" horiz-adv-x="1677" d="M180 588q0 313 237.5 540.5t565.5 227.5q268 0 443.5 -179.5t175.5 -443.5q0 -319 -237 -544.5t-572 -225.5q-268 0 -440.5 178t-172.5 447zM373 537q0 -238 110.5 -373t309.5 -137q260 -2 438 220t178 550q0 223 -114.5 360t-309.5 135q-236 0 -381 -155 q-106 -113 -168.5 -275t-62.5 -325zM886 1787.5q5 6.5 15 6.5h154q18 0 22 -6q0 -2 2 -2l2 -4l99 -312q2 -4 -2 -7t-13 -3q-16 0 -22 8l-254 299q-8 14 -3 20.5z" /> -<glyph unicode="Ó" horiz-adv-x="1677" d="M180 588q0 313 237.5 540.5t565.5 227.5q268 0 443.5 -179.5t175.5 -443.5q0 -319 -237 -544.5t-572 -225.5q-268 0 -440.5 178t-172.5 447zM373 537q0 -238 110.5 -373t309.5 -137q260 -2 438 220t178 550q0 223 -114.5 360t-309.5 135q-236 0 -381 -155 q-106 -113 -168.5 -275t-62.5 -325zM967 1479q6 23 27.5 92t38 125.5t20.5 79.5q8 20 39 20q88 6 133 0q14 2 23 -5.5t-1 -23.5q-53 -72 -252 -297q-6 -6 -14 -7t-12 3t-2 13z" /> -<glyph unicode="Ô" horiz-adv-x="1677" d="M180 588q0 313 237.5 540.5t565.5 227.5q268 0 443.5 -179.5t175.5 -443.5q0 -319 -237 -544.5t-572 -225.5q-268 0 -440.5 178t-172.5 447zM373 537q0 -238 110.5 -373t309.5 -137q260 -2 438 220t178 550q0 223 -114.5 360t-309.5 135q-236 0 -381 -155 q-106 -113 -168.5 -275t-62.5 -325zM768 1432q-12 2 0 14l299 301q16 18 45 18q12 2 48 0t42 -2q31 -2 37 -30l70 -281q4 -20 -11 -20h-12l-162 194q-10 12 -26 2l-305 -196h-25z" /> -<glyph unicode="Õ" horiz-adv-x="1677" d="M180 588q0 313 237.5 540.5t565.5 227.5q268 0 443.5 -179.5t175.5 -443.5q0 -319 -237 -544.5t-572 -225.5q-268 0 -440.5 178t-172.5 447zM373 537q0 -238 110.5 -373t309.5 -137q260 -2 438 220t178 550q0 223 -114.5 360t-309.5 135q-236 0 -381 -155 q-106 -113 -168.5 -275t-62.5 -325zM700 1503q23 248 193 248q70 0 181.5 -71.5t146.5 -71.5q70 0 90 121q2 20 22 20q19 0 19 -27q0 -106 -54.5 -177.5t-136.5 -71.5q-76 0 -185.5 71.5t-141.5 71.5q-39 0 -58.5 -26.5t-34.5 -98.5q-2 -16 -24 -16q-18 0 -17 28z" /> -<glyph unicode="Ö" horiz-adv-x="1677" d="M180 588q0 313 237.5 540.5t565.5 227.5q268 0 443.5 -179.5t175.5 -443.5q0 -319 -237 -544.5t-572 -225.5q-268 0 -440.5 178t-172.5 447zM373 537q0 -238 110.5 -373t309.5 -137q260 -2 438 220t178 550q0 223 -114.5 360t-309.5 135q-236 0 -381 -155 q-106 -113 -168.5 -275t-62.5 -325zM784 1546q0 47 30 78t75 31q43 0 73.5 -32t30.5 -77q0 -43 -30.5 -75.5t-73.5 -32.5t-74 32.5t-31 75.5zM1126 1548q0 45 31 77t76 32t74.5 -31t29.5 -78q0 -45 -30.5 -77.5t-73.5 -32.5q-45 0 -76 32.5t-31 77.5z" /> -<glyph unicode="×" horiz-adv-x="1392" d="M190 254l422 428l-422 432l82 86l424 -434l424 434l82 -86l-424 -432l420 -428l-82 -84l-418 428l-424 -428z" /> -<glyph unicode="Ø" horiz-adv-x="1650" d="M225 588q0 309 236.5 538.5t556.5 229.5q203 0 360 -103q10 -6 25 13l119 135q8 6 30.5 -8.5t16.5 -26.5l-117 -137q-14 -16 -4 -27q215 -178 215 -467q0 -322 -235.5 -547t-571.5 -225q-207 0 -367 113q-20 14 -36 -6l-152 -176q-12 -12 -25.5 -8.5t-21.5 17t-2 19.5 l149 174q25 31 11 45q-186 188 -187 447zM418 541q0 -178 69 -305q12 -25 35 0l793 923q12 20 -10 41q-117 96 -277 96q-233 0 -383 -159q-104 -109 -165.5 -272t-61.5 -324zM551 182q-18 -18 4 -39q121 -121 303 -120q260 0 437.5 223t177.5 549q0 182 -80 307 q-23 35 -41 14z" /> -<glyph unicode="Ù" horiz-adv-x="1515" d="M121 1303q6 23 29 22q256 -12 544 0q10 0 18.5 -8t6.5 -19q0 -33 -37 -28q-104 4 -140 -29t-61 -151l-116 -545q-25 -117 -25 -203q0 -145 102.5 -231t284.5 -86q236 0 352.5 124.5t159.5 354.5l104 555q23 119 -16 166t-164 47q-14 0 -10 28q4 12 9 19.5t12 5.5 q342 -6 454 2q23 2 17 -31q-4 -29 -27 -24q-96 -12 -137 -53t-66 -175l-104 -561q-29 -154 -92 -260q-158 -260 -527 -260q-178 0 -290.5 50t-182.5 157q-57 88 -61 187.5t22 195.5l113 528q10 55 12 97.5t-29.5 68t-101.5 25.5h-35q-8 0 -14 10t-4 21zM742.5 1787.5 q5.5 6.5 15.5 6.5h151q20 0 25 -6v-2l2 -4l98 -312q2 -4 -2 -7t-12 -3q-14 0 -23 8l-252 299q-8 14 -2.5 20.5z" /> -<glyph unicode="Ú" horiz-adv-x="1515" d="M121 1303q6 23 29 22q256 -12 544 0q10 0 18.5 -8t6.5 -19q0 -33 -37 -28q-104 4 -140 -29t-61 -151l-116 -545q-25 -117 -25 -203q0 -145 102.5 -231t284.5 -86q236 0 352.5 124.5t159.5 354.5l104 555q23 119 -16 166t-164 47q-14 0 -10 28q4 12 9 19.5t12 5.5 q342 -6 454 2q23 2 17 -31q-4 -29 -27 -24q-96 -12 -137 -53t-66 -175l-104 -561q-29 -154 -92 -260q-158 -260 -527 -260q-178 0 -290.5 50t-182.5 157q-57 88 -61 187.5t22 195.5l113 528q10 55 12 97.5t-29.5 68t-101.5 25.5h-35q-8 0 -14 10t-4 21zM961 1479 q78 250 86 297q8 20 38 20q90 4 134 0q14 2 23 -5.5t-1 -23.5q-27 -37 -71 -90t-106.5 -123.5t-72.5 -83.5q-6 -6 -14 -7t-13.5 3t-2.5 13z" /> -<glyph unicode="Û" horiz-adv-x="1515" d="M121 1303q6 23 29 22q256 -12 544 0q10 0 18.5 -8t6.5 -19q0 -33 -37 -28q-104 4 -140 -29t-61 -151l-116 -545q-25 -117 -25 -203q0 -145 102.5 -231t284.5 -86q236 0 352.5 124.5t159.5 354.5l104 555q23 119 -16 166t-164 47q-14 0 -10 28q4 12 9 19.5t12 5.5 q342 -6 454 2q23 2 17 -31q-4 -29 -27 -24q-96 -12 -137 -53t-66 -175l-104 -561q-29 -154 -92 -260q-158 -260 -527 -260q-178 0 -290.5 50t-182.5 157q-57 88 -61 187.5t22 195.5l113 528q10 55 12 97.5t-29.5 68t-101.5 25.5h-35q-8 0 -14 10t-4 21zM688 1438q-12 2 0 14 l297 301q16 16 47 16q23 4 90 -2q29 0 37 -28l70 -281q4 -20 -12 -20h-13l-160 194q-12 12 -26 2l-305 -196h-25z" /> -<glyph unicode="Ü" horiz-adv-x="1515" d="M121 1303q6 23 29 22q256 -12 544 0q10 0 18.5 -8t6.5 -19q0 -33 -37 -28q-104 4 -140 -29t-61 -151l-116 -545q-25 -117 -25 -203q0 -145 102.5 -231t284.5 -86q236 0 352.5 124.5t159.5 354.5l104 555q23 119 -16 166t-164 47q-14 0 -10 28q4 12 9 19.5t12 5.5 q342 -6 454 2q23 2 17 -31q-4 -29 -27 -24q-96 -12 -137 -53t-66 -175l-104 -561q-29 -154 -92 -260q-158 -260 -527 -260q-178 0 -290.5 50t-182.5 157q-57 88 -61 187.5t22 195.5l113 528q10 55 12 97.5t-29.5 68t-101.5 25.5h-35q-8 0 -14 10t-4 21zM696 1546q0 45 31 77 t76 32q43 0 73.5 -32t30.5 -77q0 -43 -31.5 -75.5t-72.5 -32.5q-43 0 -75 32.5t-32 75.5zM1038 1548q0 45 32 77t75 32q45 0 75.5 -32t30.5 -77t-30.5 -77.5t-75.5 -32.5q-43 0 -75 32.5t-32 77.5z" /> -<glyph unicode="Ý" horiz-adv-x="1308" d="M211 1300q4 23 22 23q195 -10 439 0q20 -6 14 -25q-4 -25 -12 -24q-70 -6 -91.5 -14.5t-22.5 -38t30 -99.5l209 -477q6 -16 8 -18t24 18l377 438q80 92 80 125q0 59 -127 66q-8 4 -8 15t7 23.5t18 10.5q205 -10 362 0q8 0 15.5 -4t5.5 -12q-4 -18 -13 -27 q-68 -27 -102.5 -50.5t-93.5 -94.5l-521 -598l-63 -308q-20 -100 4.5 -137t130.5 -35q49 0 58 -2q14 -2 5.5 -30.5t-16.5 -28.5q-291 8 -618 0q-8 4 -8 16.5t7 27.5t17 15q129 6 164 29q47 33 72 147l65 308l-258 587q-37 86 -69.5 115t-92.5 33q-25 0 -18 26zM872 1479 q78 250 86 297q8 20 39 20q90 4 133 0q14 2 23.5 -5.5t-0.5 -23.5q-27 -37 -71 -90t-106.5 -123.5t-72.5 -83.5q-6 -6 -14 -7t-13.5 3t-3.5 13z" /> -<glyph unicode="Þ" horiz-adv-x="1173" d="M96 27q2 12 3 16t5.5 7t7.5 2t13 0t22 3q61 10 91 52.5t53 148.5l166 836q12 68 12 90q0 94 -127 94q-29 0 -25 31q6 27 41 22q25 0 104 -1t167 -1t180 2q16 4 22.5 -7t-0.5 -24q-2 -14 -18 -20q-78 -6 -118 -44t-60 -120q-6 -25 4 -36t23.5 -12t50.5 -1h18 q143 0 220 -17.5t143 -66.5q135 -105 135 -283q0 -115 -47 -201.5t-126 -139t-174.5 -78t-199.5 -25.5q-2 0 -24.5 -1t-33 0t-26.5 4t-21.5 11t-3.5 21q4 18 10.5 21t26 -1t33.5 -4q221 0 328 166q74 113 73 256q0 94 -37.5 162.5t-103.5 91.5q-61 23 -231 23q-49 0 -64 -31 l-149 -744q-18 -96 6 -136t127 -40q25 0 29 -6t0 -20q0 -2 -2.5 -10.5t-3.5 -10.5l-3 -6t-6 -5t-11 -2t-17 -1q-285 8 -465 0q-25 0 -17 35z" /> -<glyph unicode="ß" horiz-adv-x="913" d="M-389 -383q0 27 19.5 44t45.5 17q39 0 101 -47q63 -53 106 -53q39 0 78 33t64 86q47 109 79 301l109 623q51 299 96 423q41 119 113 213q59 78 145 126.5t168 48.5q100 0 169 -74.5t69 -183.5q0 -88 -51.5 -167t-137.5 -124q-53 -29 -98 -41q-10 -2 -15 -8.5t-2 -11.5 t13 -9q182 -94 182 -311q0 -236 -172 -414q-113 -117 -231 -117q-51 0 -84 22.5t-33 61.5q0 27 17.5 44.5t39.5 17.5q37 0 91 -58q23 -23 43 -22q76 0 129 123t53 301q0 184 -94 278q-31 31 -72 54q-23 16 -21 32q2 18 25 21q90 18 147 63q133 106 134 291q0 80 -40 130 t-102 50q-59 0 -118.5 -46t-92.5 -117q-59 -127 -114 -451l-80 -461q-57 -330 -148 -516q-53 -109 -131 -190q-96 -96 -213 -97q-76 0 -131 33t-55 82z" /> -<glyph unicode="à" horiz-adv-x="851" d="M76 199q0 158 108.5 325.5t274.5 263.5q145 84 332 89q10 0 12 -19l-121 -612l-4 -19q-4 -18 -8 -36.5t-6 -38t2 -30.5t14 -9q27 4 84 69q12 14 27 29q16 16 24 -6q6 -19 -4 -35q-82 -90 -104 -113q-86 -82 -125 -82q-66 0 -62 113q2 57 21 137q4 18 -3.5 19.5 t-19.5 -13.5q-246 -256 -315 -256q-51 0 -89 68t-38 156zM213 242q0 -63 19.5 -105.5t43.5 -42.5q29 0 285 242l80 395q6 10 4 20.5t-16 8.5q-125 -14 -221 -80q-88 -59 -141.5 -180t-53.5 -258zM424 1338.5q6 7.5 18 7.5h152q20 0 22 -7q2 0 2 -2t3 -4l98 -311q2 -4 -2 -7 t-12 -3q-16 0 -23 8l-252 299q-12 12 -6 19.5z" /> -<glyph unicode="á" horiz-adv-x="851" d="M76 199q0 158 108.5 325.5t274.5 263.5q145 84 332 89q10 0 12 -19l-121 -612l-4 -19q-4 -18 -8 -36.5t-6 -38t2 -30.5t14 -9q27 4 84 69q12 14 27 29q16 16 24 -6q6 -19 -4 -35q-82 -90 -104 -113q-86 -82 -125 -82q-66 0 -62 113q2 57 21 137q4 18 -3.5 19.5 t-19.5 -13.5q-246 -256 -315 -256q-51 0 -89 68t-38 156zM213 242q0 -63 19.5 -105.5t43.5 -42.5q29 0 285 242l80 395q6 10 4 20.5t-16 8.5q-125 -14 -221 -80q-88 -59 -141.5 -180t-53.5 -258zM485 1030q78 250 86 297q8 20 39 21q88 6 133 0q14 2 23.5 -5.5t-0.5 -23.5 q-27 -37 -71 -89t-107.5 -126t-71.5 -82q-6 -6 -14 -7t-13.5 3t-3.5 12z" /> -<glyph unicode="â" horiz-adv-x="851" d="M76 199q0 158 108.5 325.5t274.5 263.5q145 84 332 89q10 0 12 -19l-121 -612l-4 -19q-4 -18 -8 -36.5t-6 -38t2 -30.5t14 -9q27 4 84 69q12 14 27 29q16 16 24 -6q6 -19 -4 -35q-82 -90 -104 -113q-86 -82 -125 -82q-66 0 -62 113q2 57 21 137q4 18 -3.5 19.5 t-19.5 -13.5q-246 -256 -315 -256q-51 0 -89 68t-38 156zM213 242q0 -63 19.5 -105.5t43.5 -42.5q29 0 285 242l80 395q6 10 4 20.5t-16 8.5q-125 -14 -221 -80q-88 -59 -141.5 -180t-53.5 -258zM373 979q-12 2 0 14l299 301q16 18 45 19q12 2 48 0t42 -2q31 -2 37 -31 l69 -281q4 -20 -10 -20h-12l-162 195q-10 12 -27 2l-305 -197h-24z" /> -<glyph unicode="ã" horiz-adv-x="851" d="M76 199q0 158 108.5 325.5t274.5 263.5q145 84 332 89q10 0 12 -19l-121 -612l-4 -19q-4 -18 -8 -36.5t-6 -38t2 -30.5t14 -9q27 4 84 69q12 14 27 29q16 16 24 -6q6 -19 -4 -35q-82 -90 -104 -113q-86 -82 -125 -82q-66 0 -62 113q2 57 21 137q4 18 -3.5 19.5 t-19.5 -13.5q-246 -256 -315 -256q-51 0 -89 68t-38 156zM213 242q0 -63 19.5 -105.5t43.5 -42.5q29 0 285 242l80 395q6 10 4 20.5t-16 8.5q-125 -14 -221 -80q-88 -59 -141.5 -180t-53.5 -258zM289 1034q23 248 192 248q70 0 181.5 -71.5t146.5 -71.5q70 0 90 121 q2 20 23 20q18 0 18 -27q0 -106 -54.5 -177.5t-135.5 -71.5q-76 0 -185.5 71.5t-142.5 71.5q-39 0 -58.5 -26.5t-33.5 -98.5q-2 -16 -25 -16q-18 0 -16 28z" /> -<glyph unicode="ä" horiz-adv-x="851" d="M76 199q0 158 107.5 324.5t273.5 262.5q141 82 329 86q10 0 13 -18l-121 -610q-18 -88 -19 -109q0 -27 17 -26q25 0 84 67q16 16 24 29q10 20 23 -2q18 -25 0 -33q-4 -4 -22.5 -24.5t-32 -35t-34 -37t-37.5 -38t-36.5 -29.5t-36 -22.5t-28.5 -8.5q-68 0 -64 113 q0 12 12 92q2 10 5.5 25.5t5.5 26t4 16.5l-6 2q4 2 4 4h-9l3 -2h-3l-2 -2q-252 -274 -329 -275q-51 0 -88 68t-37 156zM209 242q0 -66 19.5 -110t45.5 -44q18 0 142 111q82 74 143 135q20 92 86 420q-2 6 -10 6q-129 -12 -229 -80q-90 -61 -143.5 -181t-53.5 -257zM303 1098 q0 45 31 76.5t76 31.5q43 0 74.5 -31.5t31.5 -76.5t-31.5 -77t-74.5 -32q-45 0 -76 32t-31 77zM643 1100q0 45 32 76.5t77 31.5t75.5 -31.5t30.5 -76.5q0 -47 -30.5 -79t-75.5 -32t-77 33t-32 78z" /> -<glyph unicode="å" horiz-adv-x="851" d="M76 199q0 158 108.5 325.5t274.5 263.5q145 84 332 89q10 0 12 -19l-121 -612l-4 -19q-4 -18 -8 -36.5t-6 -38t2 -30.5t14 -9q27 4 84 69q12 14 27 29q16 16 24 -6q6 -19 -4 -35q-82 -90 -104 -113q-86 -82 -125 -82q-66 0 -62 113q2 57 21 137q4 18 -3.5 19.5 t-19.5 -13.5q-246 -256 -315 -256q-51 0 -89 68t-38 156zM213 242q0 -63 19.5 -105.5t43.5 -42.5q29 0 285 242l80 395q6 10 4 20.5t-16 8.5q-125 -14 -221 -80q-88 -59 -141.5 -180t-53.5 -258zM420 1145q0 82 58.5 141.5t137.5 59.5q82 0 138.5 -58.5t56.5 -142.5 t-56.5 -141.5t-138.5 -57.5q-80 0 -138 58.5t-58 140.5zM496 1145q0 -51 34.5 -87t86 -36t87 36t35.5 87t-35.5 88t-87 37t-86 -36t-34.5 -89z" /> -<glyph unicode="æ" horiz-adv-x="1193" d="M76 209q0 254 221 456.5t498 202.5q29 0 18 -32l-14 -66q-2 -16 3 -15t13 9q117 106 234 106q76 0 125 -41.5t49 -107.5q0 -70 -54.5 -131.5t-150.5 -104.5q-137 -61 -266 -96q-18 -2 -23 -24q-12 -63 -12 -115q0 -86 42 -140.5t105 -54.5q76 0 236 105q14 0 22 -8 q6 -12 2 -25q-223 -156 -356 -156q-82 0 -138.5 75t-56.5 179q0 25 -24 2q-104 -98 -156 -141q-135 -113 -178 -113q-27 0 -53 25q-86 68 -86 211zM213 264q0 -82 21.5 -130t52.5 -48q63 0 295 233l84 416q4 16 1 23.5t-22 5.5q-119 -18 -203 -68q-106 -63 -167.5 -179 t-61.5 -253zM750 465q-4 -18 5 -22.5t21 -0.5q37 12 70 25q98 35 164 82q41 29 66.5 76t25.5 92t-25.5 72.5t-66.5 27.5q-170 0 -260 -352z" /> -<glyph unicode="ç" horiz-adv-x="614" d="M40 -384q-1 3 3 13q0 8 12 9q102 -4 157.5 31.5t55.5 99.5q0 66 -88 75q-10 10 -4 23l41 84q6 10 4 20.5t-10 12.5q-63 16 -100 75.5t-37 145.5q0 123 56 276.5t168 275.5t241 122q49 0 79.5 -22.5t30.5 -59.5q0 -33 -17.5 -54.5t-43.5 -21.5q-33 0 -99 37q-39 20 -55 20 q-68 0 -125 -145q-23 -59 -44 -138t-38.5 -179.5t7 -168t94.5 -67.5q96 0 200 127q12 23 37 -6q16 -18 10 -33q-150 -174 -299 -188h-16q-4 -2 -12 -13l-6 -10q-6 -10 1 -17.5t17 -7.5q35 -6 64.5 -40.5t29.5 -84.5q0 -80 -75.5 -140t-225.5 -56q-12 2 -13 5z" /> -<glyph unicode="è" horiz-adv-x="745" d="M78 270q0 233 143.5 423t321.5 190q80 0 126 -40t46 -110q0 -150 -180 -241q-55 -31 -158 -62q-31 -10 -73 -21.5t-52 -13.5q-20 -8 -21 -24q-10 -49 -10 -109q0 -92 45 -145.5t117 -50.5q90 2 233 114q18 16 27 -6q12 -25 -4 -43q-88 -76 -183.5 -116t-166.5 -40 q-88 0 -149.5 85t-61.5 210zM258 485q-2 -12 7 -15t26 3q113 27 192 66q115 59 123 170q4 47 -21.5 78.5t-72.5 29.5q-109 -4 -164 -102q-47 -88 -49 -94q-23 -51 -41 -136zM321 1339.5q5 6.5 15 6.5h151q20 0 25 -7q0 -2 4 -6l96 -311q2 -4 -1 -7t-11 -3q-16 0 -22 8 l-254 299q-8 14 -3 20.5z" /> -<glyph unicode="é" horiz-adv-x="745" d="M78 270q0 233 143.5 423t321.5 190q80 0 126 -40t46 -110q0 -150 -180 -241q-55 -31 -158 -62q-31 -10 -73 -21.5t-52 -13.5q-20 -8 -21 -24q-10 -49 -10 -109q0 -92 45 -145.5t117 -50.5q90 2 233 114q18 16 27 -6q12 -25 -4 -43q-88 -76 -183.5 -116t-166.5 -40 q-88 0 -149.5 85t-61.5 210zM258 485q-2 -12 7 -15t26 3q113 27 192 66q115 59 123 170q4 47 -21.5 78.5t-72.5 29.5q-109 -4 -164 -102q-47 -88 -49 -94q-23 -51 -41 -136zM420 1030q8 25 28.5 92.5t38 125t21.5 79.5q8 20 37 21q90 4 135 0q14 2 22 -5.5t-2 -23.5 q-59 -82 -249 -297q-6 -6 -14.5 -7t-13.5 3t-3 12z" /> -<glyph unicode="ê" horiz-adv-x="745" d="M78 270q0 233 143.5 423t321.5 190q80 0 126 -40t46 -110q0 -150 -180 -241q-55 -31 -158 -62q-31 -10 -73 -21.5t-52 -13.5q-20 -8 -21 -24q-10 -49 -10 -109q0 -92 45 -145.5t117 -50.5q90 2 233 114q18 16 27 -6q12 -25 -4 -43q-88 -76 -183.5 -116t-166.5 -40 q-88 0 -149.5 85t-61.5 210zM256 979q-12 2 0 14l299 301q16 18 45 19q12 2 48 0t42 -2q31 -2 37 -31l70 -281q4 -20 -11 -20h-12l-162 195q-10 12 -26 2l-305 -197h-25zM258 485q-2 -12 7 -15t26 3q113 27 192 66q115 59 123 170q4 47 -21.5 78.5t-72.5 29.5 q-109 -4 -164 -102q-47 -88 -49 -94q-23 -51 -41 -136z" /> -<glyph unicode="ë" horiz-adv-x="745" d="M78 270q0 233 143.5 423t321.5 190q80 0 126 -40t46 -110q0 -150 -180 -241q-55 -31 -158 -62q-31 -10 -73 -21.5t-52 -13.5q-20 -8 -21 -24q-10 -49 -10 -109q0 -92 45 -145.5t117 -50.5q90 2 233 114q18 16 27 -6q12 -25 -4 -43q-88 -76 -183.5 -116t-166.5 -40 q-88 0 -149.5 85t-61.5 210zM252 1098q0 43 29.5 72.5t70.5 29.5t71 -29.5t30 -72.5q0 -41 -30 -72t-71 -31t-70.5 31t-29.5 72zM258 485q-2 -12 7 -15t26 3q113 27 192 66q115 59 123 170q4 47 -21.5 78.5t-72.5 29.5q-109 -4 -164 -102q-47 -88 -49 -94q-23 -51 -41 -136z M578 1100q0 43 29.5 72.5t72.5 29.5q41 0 69.5 -29.5t28.5 -72.5t-28.5 -74t-69.5 -31q-43 0 -72.5 31t-29.5 74z" /> -<glyph unicode="ì" horiz-adv-x="522" d="M107.5 646q-1.5 11 3.5 18q186 207 253.5 206.5t38.5 -125.5l-118 -591q-12 -63 8 -64q16 0 61 49t70 82q6 8 17.5 4t16.5 -13t-1 -19q-57 -74 -129 -140q-88 -82 -133 -82q-84 0 -52 160l105 531q0 2 3 11t5 18t3 20.5t-1 17.5t-8 6q-14 0 -34.5 -20.5t-44.5 -49 t-36 -36.5q-10 -8 -18 -1t-9.5 18zM122 1339.5q5 6.5 15 6.5h152q20 0 24 -7l2 -2v-4l99 -311q2 -4 -1 -7t-12 -3q-16 0 -24 8l-252 299q-8 14 -3 20.5z" /> -<glyph unicode="í" horiz-adv-x="522" d="M107.5 646q-1.5 11 3.5 18q186 207 253.5 206.5t38.5 -125.5l-118 -591q-12 -63 8 -64q16 0 61 49t70 82q6 8 17.5 4t16.5 -13t-1 -19q-57 -74 -129 -140q-88 -82 -133 -82q-84 0 -52 160l105 531q0 2 3 11t5 18t3 20.5t-1 17.5t-8 6q-14 0 -34.5 -20.5t-44.5 -49 t-36 -36.5q-10 -8 -18 -1t-9.5 18zM313 1030q78 248 86 297q8 20 39 21q90 4 133 0q16 4 24.5 -4.5t-1.5 -24.5q-59 -82 -250 -297q-6 -6 -14 -7t-13.5 3t-3.5 12z" /> -<glyph unicode="î" horiz-adv-x="522" d="M80 979q-12 2 0 14l299 301q16 18 45 19q12 2 48 0t42 -2q31 -2 37 -31l70 -281q4 -20 -11 -20h-12l-162 195q-10 12 -26 2l-306 -197h-24zM107.5 646q-1.5 11 3.5 18q186 207 253.5 206.5t38.5 -125.5l-118 -591q-12 -63 8 -64q16 0 61 49t70 82q6 8 17.5 4t16.5 -13 t-1 -19q-57 -74 -129 -140q-88 -82 -133 -82q-84 0 -52 160l105 531q0 2 3 11t5 18t3 20.5t-1 17.5t-8 6q-14 0 -34.5 -20.5t-44.5 -49t-36 -36.5q-10 -8 -18 -1t-9.5 18z" /> -<glyph unicode="ï" horiz-adv-x="522" d="M107.5 646q-1.5 11 3.5 18q186 207 253.5 206.5t38.5 -125.5l-118 -591q-12 -63 8 -64q16 0 61 49t70 82q6 8 17.5 4t16.5 -13t-1 -19q-57 -74 -129 -140q-88 -82 -133 -82q-84 0 -52 160l105 531q0 2 3 11t5 18t3 20.5t-1 17.5t-8 6q-14 0 -34.5 -20.5t-44.5 -49 t-36 -36.5q-10 -8 -18 -1t-9.5 18zM111 1098q0 45 30.5 76.5t75.5 31.5q43 0 74 -31.5t31 -76.5q0 -43 -32 -75t-73 -32q-45 0 -75.5 32t-30.5 75zM453 1100q0 45 31.5 76.5t76.5 31.5q43 0 74 -31.5t31 -76.5t-31 -77t-74 -32q-45 0 -76.5 32t-31.5 77z" /> -<glyph unicode="ð" horiz-adv-x="868" d="M94 305q0 291 283 481q127 86 215 86q25 0 47 -12q6 -2 11 8.5t5 18.5q-10 113 -45 194q-4 6 -15 11.5t-17 3.5l-191 -62q-8 -2 -13 1t-7 5l-2 4l-5 15q0 10 13 18l178 53q25 12 12 37q-25 43 -47 65.5t-84 67.5q-16 8 -12 29l8 14q12 16 37 9q113 -47 199 -158 q12 -20 41 -14l131 43q20 8 24 -11l6 -24l-139 -47q-25 -6 -10 -31q74 -129 80 -323.5t-44.5 -375t-174 -309.5t-287.5 -129q-82 0 -139.5 97.5t-57.5 234.5zM238 313q0 -113 39.5 -184.5t99.5 -71.5q104 0 184 144.5t80 337.5q0 102 -46 174.5t-108 72.5q-96 0 -172.5 -144 t-76.5 -329z" /> -<glyph unicode="ñ" horiz-adv-x="960" d="M100 582q-12 25 0 41q193 260 262 256q51 -2 31 -105q-37 -195 -63 -315q-4 -14 0 -14.5t22 22.5q8 10 60.5 80.5t87.5 114t87 100.5t100 87t87 30q88 0 88 -127q0 -59 -16 -125l-123 -473q-23 -80 -4 -84q16 -6 94 80q51 59 78 92q19 20 29 10q4 -6 7 -10t3 -9.5v-7.5 t-3 -7t-4 -7t-6.5 -9t-7.5 -9q-72 -100 -148.5 -159t-125.5 -59q-94 0 -55 160l133 533q25 98 -21 98q-14 0 -33.5 -12.5t-44 -35t-48 -48t-53.5 -61.5t-52.5 -65.5t-50 -67.5t-44 -60.5t-38 -52t-25.5 -35.5l-63 -312q-4 -27 -12.5 -33t-32.5 -6h-58q-47 0 -33 41l132 658 q0 27 -7 26q-4 0 -8 -2q-10 -6 -47 -53t-51 -67q-4 -4 -12.5 -3t-10.5 5zM260 975q66 266 258 266q80 0 182 -84q70 -59 115 -59q37 0 62.5 30.5t56.5 114.5q2 8 24 8q12 0 15 -6q2 -6 2 -16q-2 -4 -2 -10q-23 -111 -91.5 -173.5t-158.5 -62.5q-84 0 -180 82q-76 63 -115 63 q-59 0 -111 -112q0 -4 -2 -6l-2 -9l-2 -8q-4 -8 -6 -14q-10 -10 -29 -14q-16 0 -16 10z" /> -<glyph unicode="ò" horiz-adv-x="815" d="M78 317.5q0 131.5 73.5 256t206.5 214.5q131 90 213 91q72 0 133.5 -97.5t61.5 -220.5q0 -195 -113 -342q-47 -61 -121.5 -120.5t-148.5 -90.5q-72 -33 -115 -33q-70 0 -130 105.5t-60 237zM223 309q0 -102 41 -175t96 -73q102 0 183.5 144t81.5 330q0 109 -46.5 181 t-111.5 72q-96 0 -170 -144t-74 -335zM373 1338.5q6 7.5 18 7.5h152q18 0 22 -7l2 -2q2 -2 2 -4l99 -311q2 -4 -2 -7t-13 -3q-16 0 -22 8l-252 299q-12 12 -6 19.5z" /> -<glyph unicode="ó" horiz-adv-x="815" d="M78 317.5q0 131.5 73.5 256t206.5 214.5q131 90 213 91q72 0 133.5 -97.5t61.5 -220.5q0 -195 -113 -342q-47 -61 -121.5 -120.5t-148.5 -90.5q-72 -33 -115 -33q-70 0 -130 105.5t-60 237zM223 309q0 -102 41 -175t96 -73q102 0 183.5 144t81.5 330q0 109 -46.5 181 t-111.5 72q-96 0 -170 -144t-74 -335zM475 1030q78 250 86 297q8 20 39 21q86 4 133 0q14 2 23.5 -5.5t-0.5 -23.5q-49 -70 -252 -297q-4 -6 -12.5 -7t-13.5 3t-3 12z" /> -<glyph unicode="ô" horiz-adv-x="815" d="M78 317.5q0 131.5 73.5 256t206.5 214.5q131 90 213 91q72 0 133.5 -97.5t61.5 -220.5q0 -195 -113 -342q-47 -61 -121.5 -120.5t-148.5 -90.5q-72 -33 -115 -33q-70 0 -130 105.5t-60 237zM223 309q0 -102 41 -175t96 -73q102 0 183.5 144t81.5 330q0 109 -46.5 181 t-111.5 72q-96 0 -170 -144t-74 -335zM287 979q-12 2 0 14l299 301q16 18 45 19q12 2 48 0t42 -2q31 -2 37 -31l69 -281q4 -20 -10 -20h-12l-162 195q-10 12 -27 2l-305 -197h-24z" /> -<glyph unicode="õ" horiz-adv-x="815" d="M78 317.5q0 131.5 73.5 256t206.5 214.5q131 90 213 91q72 0 133.5 -97.5t61.5 -220.5q0 -195 -113 -342q-47 -61 -121.5 -120.5t-148.5 -90.5q-72 -33 -115 -33q-70 0 -130 105.5t-60 237zM223 309q0 -102 41 -175t96 -73q102 0 183.5 144t81.5 330q0 109 -46.5 181 t-111.5 72q-96 0 -170 -144t-74 -335zM240 1034q23 248 192 248q70 0 181.5 -71.5t146.5 -71.5q70 0 90 121q2 20 22 20q19 0 19 -27q0 -106 -54.5 -177.5t-136.5 -71.5q-76 0 -185 71.5t-142 71.5q-39 0 -58.5 -26.5t-33.5 -98.5q-2 -16 -25 -16q-18 0 -16 28z" /> -<glyph unicode="ö" horiz-adv-x="815" d="M78 317.5q0 131.5 73.5 256t206.5 214.5q131 90 213 91q72 0 133.5 -97.5t61.5 -220.5q0 -195 -113 -342q-47 -61 -121.5 -120.5t-148.5 -90.5q-72 -33 -115 -33q-70 0 -130 105.5t-60 237zM223 309q0 -102 41 -175t96 -73q102 0 183.5 144t81.5 330q0 109 -46.5 181 t-111.5 72q-96 0 -170 -144t-74 -335zM293 1098q0 45 30.5 76.5t73.5 31.5t75 -31.5t32 -76.5q0 -43 -32 -75t-75 -32t-73.5 32t-30.5 75zM635 1100q0 45 31.5 76.5t74.5 31.5q45 0 76 -31.5t31 -76.5t-31 -77t-76 -32q-43 0 -74.5 32t-31.5 77z" /> -<glyph unicode="÷" horiz-adv-x="1392" d="M143 625v116h1106v-116h-1106zM614 260q0 33 22.5 55.5t57.5 22.5q33 0 54.5 -22.5t21.5 -55.5t-21.5 -55.5t-54 -22.5t-56.5 22.5t-24 55.5zM614 1118q0 31 25 51.5t55.5 20.5t53 -21.5t22.5 -54.5t-22.5 -56.5t-53.5 -23.5q-35 0 -58.5 24.5t-21.5 59.5z" /> -<glyph unicode="ø" horiz-adv-x="825" d="M61 14l60 72q14 16 4 45q-31 84 -31 176q0 207 162 375q72 78 169 133t161 55q57 0 121 -75q8 -12 30 10l49 59q10 10 21 0l6 -8q10 -14 -2 -29l-53 -63q-20 -20 -10 -43q31 -68 30 -166q0 -195 -110 -340q-47 -61 -122 -120.5t-149 -90.5q-72 -33 -112 -33 q-63 0 -113 74q-14 16 -31 -2l-51 -59q-16 -16 -24 -2q-16 18 -5 32zM238 311q0 -33 2 -47q2 -18 6 -22t8 -1t14 15l330 387q16 21 6 39q-45 98 -123 98q-94 0 -168.5 -142t-74.5 -327zM266 156q43 -100 109 -101q102 0 182 143.5t80 327.5q0 35 -4 58q-6 31 -33 -2 l-326 -383q-18 -20 -8 -43z" /> -<glyph unicode="ù" horiz-adv-x="997" d="M129 613.5q-2 11.5 2 19.5q41 61 126 151t130 90q68 0 35 -145l-100 -504q-6 -33 -8.5 -53t1.5 -38.5t23.5 -13.5t54.5 36q74 68 179.5 223.5t134.5 247.5q18 55 45 221q6 33 45 33q27 -2 63 0q41 0 31 -52l-129 -659q-12 -59 24 -33q14 10 35 33q55 59 76 86 q10 16 25 -4q10 -15 6 -29q-78 -98 -161 -173t-116 -75q-43 0 -43 64q0 133 66 381q6 20 0 20q-8 0 -25 -22q-123 -193 -239.5 -318t-182.5 -125q-92 0 -45 252l92 463q8 37 0 37q-12 0 -29.5 -15.5t-30.5 -32.5t-30.5 -41t-21.5 -28q-10 -12 -20.5 -10t-12.5 13.5z M409 1339.5q5 6.5 15 6.5h151q23 0 25 -7q2 0 2 -2t2 -4l96 -311q2 -4 -1 -7t-11 -3q-16 0 -22 8l-254 299q-8 14 -3 20.5z" /> -<glyph unicode="ú" horiz-adv-x="997" d="M129 613.5q-2 11.5 2 19.5q41 61 126 151t130 90q68 0 35 -145l-100 -504q-6 -33 -8.5 -53t1.5 -38.5t23.5 -13.5t54.5 36q74 68 179.5 223.5t134.5 247.5q18 55 45 221q6 33 45 33q27 -2 63 0q41 0 31 -52l-129 -659q-12 -59 24 -33q14 10 35 33q55 59 76 86 q10 16 25 -4q10 -15 6 -29q-78 -98 -161 -173t-116 -75q-43 0 -43 64q0 133 66 381q6 20 0 20q-8 0 -25 -22q-123 -193 -239.5 -318t-182.5 -125q-92 0 -45 252l92 463q8 37 0 37q-12 0 -29.5 -15.5t-30.5 -32.5t-30.5 -41t-21.5 -28q-10 -12 -20.5 -10t-12.5 13.5z M549 1030q8 25 28.5 92.5t38 125t21.5 79.5q8 20 37 21q90 4 135 0q14 2 22 -5.5t-2 -23.5q-59 -82 -249 -297q-6 -6 -14.5 -7t-13.5 3t-3 12z" /> -<glyph unicode="û" horiz-adv-x="997" d="M129 613.5q-2 11.5 2 19.5q41 61 126 151t130 90q68 0 35 -145l-100 -504q-6 -33 -8.5 -53t1.5 -38.5t23.5 -13.5t54.5 36q74 68 179.5 223.5t134.5 247.5q18 55 45 221q6 33 45 33q27 -2 63 0q41 0 31 -52l-129 -659q-12 -59 24 -33q14 10 35 33q55 59 76 86 q10 16 25 -4q10 -15 6 -29q-78 -98 -161 -173t-116 -75q-43 0 -43 64q0 133 66 381q6 20 0 20q-8 0 -25 -22q-123 -193 -239.5 -318t-182.5 -125q-92 0 -45 252l92 463q8 37 0 37q-12 0 -29.5 -15.5t-30.5 -32.5t-30.5 -41t-21.5 -28q-10 -12 -20.5 -10t-12.5 13.5zM340 979 q-12 2 0 14l299 301q16 18 45 19q12 2 48 0t42 -2q31 -2 37 -31l70 -281q4 -20 -11 -20h-12l-162 195q-10 12 -26 2l-305 -197h-25z" /> -<glyph unicode="ü" horiz-adv-x="997" d="M129 613.5q-2 11.5 2 19.5q41 61 126 151t130 90q68 0 35 -145l-100 -504q-6 -33 -8.5 -53t1.5 -38.5t23.5 -13.5t54.5 36q74 68 179.5 223.5t134.5 247.5q18 55 45 221q6 33 45 33q27 -2 63 0q41 0 31 -52l-129 -659q-12 -59 24 -33q14 10 35 33q55 59 76 86 q10 16 25 -4q10 -15 6 -29q-78 -98 -161 -173t-116 -75q-43 0 -43 64q0 133 66 381q6 20 0 20q-8 0 -25 -22q-123 -193 -239.5 -318t-182.5 -125q-92 0 -45 252l92 463q8 37 0 37q-12 0 -29.5 -15.5t-30.5 -32.5t-30.5 -41t-21.5 -28q-10 -12 -20.5 -10t-12.5 13.5z M369 1098q0 47 29.5 77.5t74.5 30.5q43 0 74 -31.5t31 -76.5q0 -43 -31 -75t-74 -32t-73.5 32t-30.5 75zM709 1100q0 45 31.5 76.5t76.5 31.5t75 -30.5t30 -77.5q0 -45 -30 -77t-75 -32t-76.5 32t-31.5 77z" /> -<glyph unicode="ý" horiz-adv-x="894" d="M-42 -538.5q3 24.5 26 24.5q92 4 114.5 13t46.5 59q113 227 160 356q61 170 66 225q14 201 -12.5 411t-82.5 210q-35 0 -102 -94q-6 -8 -18.5 -25.5t-18.5 -26.5q-12 -16 -28 7q-12 18 -3 34q150 221 230 222q90 0 123 -272.5t18 -461.5q-2 -23 1 -27.5t8.5 1.5t15.5 22 q270 455 256 574q-2 8 -17 39q-12 25 -12 36q0 37 25.5 64t60.5 27q39 0 63.5 -31t24.5 -80q0 -72 -72 -205q-33 -57 -178 -270q-115 -166 -151 -246q-35 -78 -97.5 -230.5t-95.5 -226.5q-33 -66 -21.5 -85t97.5 -19h13t12.5 -2t9.5 -8t0 -15q-8 -27 -29 -26q-203 10 -422 2 q-14 0 -11 24.5zM518 1030q78 250 86 297q8 20 39 21q90 4 133 0q14 2 23.5 -5.5t-0.5 -23.5q-27 -37 -71 -89t-107.5 -126t-71.5 -82q-6 -6 -14.5 -7t-13.5 3t-3 12z" /> -<glyph unicode="þ" horiz-adv-x="913" d="M-139 -471q10 23 45 25q78 4 116.5 38.5t55.5 122.5q2 14 295 1483q12 61 -4 62q-8 0 -21.5 -7.5t-27 -17.5t-26.5 -23.5t-22.5 -23.5t-17.5 -21l-8 -8q-23 -25 -39 -8q-18 18 8 51q80 98 161 165t118 67q57 0 24 -191l-125 -625q-6 -31 10 -30q4 0 11 8q68 86 165 179 t158 93q47 0 82 -65.5t48.5 -132t13.5 -111.5q0 -225 -155 -406.5t-347 -181.5q-41 0 -80 9q-31 10 -39 -31l-37 -193q-4 -16 -11 -53t-9 -47t-2 -34.5t8 -31t24.5 -17.5t43 -15t65.5 -7q27 0 20 -24q-4 -18 -12 -24.5t-28 -4.5q-252 8 -441 0q-10 -2 -17 6.5t-3 24.5z M299 135q-10 -57 14 -74q45 -31 101 -30q127 0 227 158.5t100 361.5q0 88 -24.5 144.5t-61.5 56.5q-35 0 -119.5 -90.5t-177.5 -225.5z" /> -<glyph unicode="ÿ" horiz-adv-x="894" d="M-42 -538.5q3 24.5 26 24.5q92 4 114.5 13t46.5 59q113 227 160 356q61 170 66 225q14 201 -12.5 411t-82.5 210q-35 0 -102 -94q-6 -8 -18.5 -25.5t-18.5 -26.5q-12 -16 -28 7q-12 18 -3 34q150 221 230 222q90 0 123 -272.5t18 -461.5q-2 -23 1 -27.5t8.5 1.5t15.5 22 q270 455 256 574q-2 8 -17 39q-12 25 -12 36q0 37 25.5 64t60.5 27q39 0 63.5 -31t24.5 -80q0 -72 -72 -205q-33 -57 -178 -270q-115 -166 -151 -246q-35 -78 -97.5 -230.5t-95.5 -226.5q-33 -66 -21.5 -85t97.5 -19h13t12.5 -2t9.5 -8t0 -15q-8 -27 -29 -26q-203 10 -422 2 q-14 0 -11 24.5zM350 1098q0 43 30 72.5t71 29.5t70.5 -29.5t29.5 -72.5q0 -41 -29.5 -72t-70.5 -31t-71 31t-30 72zM676 1100q0 43 29.5 72.5t70.5 29.5q43 0 72 -29.5t29 -72.5t-29 -74t-72 -31q-41 0 -70.5 31t-29.5 74z" /> -<glyph unicode="Œ" horiz-adv-x="2148" d="M190 584q0 246 151 445.5t386 262.5q150 41 346 41q61 0 92 -2l174 -6h797q25 1 21 -22q-4 -41 -14.5 -92.5t-25 -107.5t-16.5 -69q-6 -6 -19.5 -6t-19.5 6v25q0 111 -50 157t-171 46h-301q-45 0 -63 -31l-105 -516q-2 -16 37 -17h101.5h141h105.5q156 4 199 140 q16 12 45 0q-6 -47 -19.5 -116t-31 -148.5t-23.5 -106.5q-4 -10 -24.5 -9t-22.5 11q2 6 2 18q0 88 -41 119t-164 31h-293q-8 -2 -19 -13.5t-13 -19.5l-82 -409q-8 -23 -4 -40.5t4 -31.5t12 -24.5t18.5 -17.5t24.5 -11t28.5 -7.5t32 -4.5t35 -1h35.5h35q92 0 139 3t116 23.5 t130 63.5q86 57 137 138q4 4 27 10q6 0 12 -3t4 -9q-12 -41 -96 -246q-6 -14 -12 -24.5t-13.5 -13.5t-10.5 -4t-12 0t-14 1h-821q-12 0 -127 -4q-111 -4 -145 -4q-279 0 -447 162.5t-168 433.5zM379 547q0 -233 118.5 -366.5t325.5 -133.5q106 0 183 41q49 27 75.5 81 t51.5 177l139 696q10 47 10 82q0 150 -250 150q-279 0 -465 -221q-188 -221 -188 -506z" /> -<glyph unicode="œ" horiz-adv-x="1189" d="M68 281q0 317 282 514q109 74 191 73q117 0 168 -172q6 -25 28 4q121 168 297 168q82 0 130 -41.5t48 -111.5q0 -129 -180 -219q-141 -70 -297 -111q-8 -2 -10 -2t-7 -4t-7 -12.5t-4 -22.5q-4 -31 -5 -84q0 -209 158 -209q100 0 244 111q12 12 20 -6q8 -23 -2 -33 q-195 -152 -348 -152q-127 0 -184 156q-14 37 -35 12q-55 -57 -117 -98q-113 -72 -184 -72q-76 0 -131 93.5t-55 218.5zM207 342q0 -283 153 -283q88 0 161 150t73 336q0 106 -38 174.5t-93 68.5q-100 0 -178 -131t-78 -315zM728 440.5q5 -8.5 24 -4.5q166 45 255 117 t89 158q0 47 -30 76.5t-75 29.5q-182 0 -262 -348q-6 -20 -1 -28.5z" /> -<glyph unicode="Ÿ" horiz-adv-x="1308" d="M211 1300q4 23 22 23q195 -10 439 0q20 -6 14 -25q-4 -25 -12 -24q-70 -6 -91.5 -14.5t-22.5 -38t30 -99.5l209 -477q6 -16 8 -18t24 18l377 438q80 92 80 125q0 59 -127 66q-8 4 -8 15t7 23.5t18 10.5q205 -10 362 0q8 0 15.5 -4t5.5 -12q-4 -18 -13 -27 q-68 -27 -102.5 -50.5t-93.5 -94.5l-521 -598l-63 -308q-20 -100 4.5 -137t130.5 -35q49 0 58 -2q14 -2 5.5 -30.5t-16.5 -28.5q-291 8 -618 0q-8 4 -8 16.5t7 27.5t17 15q129 6 164 29q47 33 72 147l65 308l-258 587q-37 86 -69.5 115t-92.5 33q-25 0 -18 26zM690 1546 q0 45 31 77t76 32q43 0 73.5 -32t30.5 -77q0 -43 -31.5 -75.5t-72.5 -32.5q-43 0 -75 32.5t-32 75.5zM1032 1548q0 45 32 77t77 32q43 0 73.5 -32t30.5 -77t-30.5 -77.5t-73.5 -32.5q-45 0 -77 32.5t-32 77.5z" /> -<glyph unicode="ˆ" horiz-adv-x="694" d="M201 979q-12 2 0 14l299 301q16 18 45 19q12 2 48 0t42 -2q31 -2 37 -31l69 -281q4 -20 -10 -20h-12l-162 195q-10 12 -27 2l-305 -197h-24z" /> -<glyph unicode="˜" horiz-adv-x="694" d="M176 1034q23 248 193 248q70 0 181.5 -71.5t145.5 -71.5q70 0 90 121q2 20 23 20q18 0 18 -27q0 -106 -54 -177.5t-136 -71.5q-76 0 -185.5 71.5t-142.5 71.5q-39 0 -58.5 -26.5t-33.5 -98.5q-2 -16 -24 -16q-18 0 -17 28z" /> -<glyph unicode=" " horiz-adv-x="910" /> -<glyph unicode=" " horiz-adv-x="1821" /> -<glyph unicode=" " horiz-adv-x="910" /> -<glyph unicode=" " horiz-adv-x="1821" /> -<glyph unicode=" " horiz-adv-x="607" /> -<glyph unicode=" " horiz-adv-x="455" /> -<glyph unicode=" " horiz-adv-x="303" /> -<glyph unicode=" " horiz-adv-x="303" /> -<glyph unicode=" " horiz-adv-x="227" /> -<glyph unicode=" " horiz-adv-x="364" /> -<glyph unicode=" " horiz-adv-x="101" /> -<glyph unicode="‐" horiz-adv-x="679" d="M123 382q-4 5 0 40q0 12 8 41q8 23 16 24q8 2 27 2h428q10 0 14.5 -1t8.5 -7t0 -18q-4 -37 -13 -68q-8 -23 -26 -18h-426q-33 0 -37 5z" /> -<glyph unicode="‑" horiz-adv-x="679" d="M123 382q-4 5 0 40q0 12 8 41q8 23 16 24q8 2 27 2h428q10 0 14.5 -1t8.5 -7t0 -18q-4 -37 -13 -68q-8 -23 -26 -18h-426q-33 0 -37 5z" /> -<glyph unicode="‒" horiz-adv-x="679" d="M123 382q-4 5 0 40q0 12 8 41q8 23 16 24q8 2 27 2h428q10 0 14.5 -1t8.5 -7t0 -18q-4 -37 -13 -68q-8 -23 -26 -18h-426q-33 0 -37 5z" /> -<glyph unicode="–" horiz-adv-x="1263" d="M121 408l6 61q0 18 25 23h970q12 0 20.5 -9.5t8.5 -17.5l-6 -66q-2 -18 -33 -18h-971q-25 0 -20 27z" /> -<glyph unicode="—" horiz-adv-x="1683" d="M180 401q0 12 3 25.5t3 22.5q0 39 35 38h1278q27 -8 31 -18q8 -4 2 -33.5t-6 -38.5q-12 -25 -29 -22h-1284q-12 -2 -23.5 5t-9.5 21z" /> -<glyph unicode="‘" horiz-adv-x="608" d="M395 952q0 115 79 218.5t220 175.5q25 6 33 -17q6 -18 -14 -24q-98 -66 -139.5 -117t-41.5 -109q0 -43 27 -86q31 -47 31 -90q0 -41 -23.5 -69.5t-60.5 -28.5q-47 0 -79 42t-32 105z" /> -<glyph unicode="’" horiz-adv-x="559" d="M257 799.5q1 13.5 11 21.5q100 66 141.5 117t41.5 109q0 43 -27 83q-31 47 -31 93q0 41 23.5 68.5t60.5 27.5q47 0 80 -39.5t33 -105.5q0 -113 -80 -218.5t-219 -177.5q-14 -8 -24.5 0t-9.5 21.5z" /> -<glyph unicode="‚" horiz-adv-x="608" d="M139 -338q2 14 8 19q100 68 141.5 120t41.5 111q0 41 -29 88q-33 51 -33 94q0 45 24.5 74t63.5 29q51 0 82 -43t31 -111q0 -233 -299 -408q-6 -4 -29 11q-4 2 -2 16z" /> -<glyph unicode="“" horiz-adv-x="1042" d="M426 952q0 115 79 218.5t218 175.5q15 3 25 -7q12 -23 -5 -34q-98 -66 -139 -117t-41 -109q0 -43 27 -86q31 -51 31 -90q0 -41 -24 -69.5t-60 -28.5q-49 0 -80 42t-31 105zM838 952q0 115 77.5 219.5t217.5 174.5q16 10 26 -13q4 -8 3 -17t-7 -11q-4 -4 -24.5 -19.5 t-26.5 -19.5t-24.5 -18.5t-25.5 -21.5l-21.5 -21.5t-20.5 -22.5t-15.5 -22.5t-13.5 -26t-7 -25.5t-3 -29q0 -39 28 -86q31 -51 31 -90q0 -41 -24.5 -69.5t-59.5 -28.5q-49 0 -79.5 42t-30.5 105z" /> -<glyph unicode="”" horiz-adv-x="1042" d="M331 816.5q-9 19.5 7 29.5q98 66 139 117t41 110q0 39 -26 82q-31 51 -31 92q0 43 23.5 71t60.5 28q49 0 78.5 -42t29.5 -108q0 -115 -78.5 -218.5t-216.5 -172.5q-18 -8 -27 11.5zM736 817.5q-11 22.5 14 28.5q98 66 139 117t41 110q0 43 -27 84q-31 49 -31 90 q0 43 24 71t60 28q47 0 77 -42t30 -108q0 -113 -77 -216t-216 -175q-23 -10 -34 12.5z" /> -<glyph unicode="„" horiz-adv-x="1042" d="M83 -332q1 10 7 13q100 68 141 120t41 111q0 41 -28 88q-33 49 -33 94t24.5 74t63.5 29q49 0 80 -43t31 -111q0 -119 -79 -225.5t-222 -182.5q-6 -2 -15.5 3.5t-7.5 15.5q-4 4 -3 14zM506 -352q-10 20 6 33q100 68 141 120t41 111q0 41 -28 88q-31 51 -31 94 q0 45 24.5 74t61.5 29q49 0 81 -44t32 -110q0 -119 -80 -225.5t-224 -182.5q-4 -2 -14 3.5t-10 9.5z" /> -<glyph unicode="•" horiz-adv-x="737" d="M233 664q0 109 76 185.5t182.5 76.5t183.5 -76.5t77 -185.5q0 -111 -76 -188t-184 -77q-106 0 -182.5 77t-76.5 188z" /> -<glyph unicode="…" horiz-adv-x="2082" d="M256 86q6 49 34.5 80t67.5 31t61.5 -28t22.5 -71q0 -55 -29.5 -91t-74.5 -36q-47 0 -67.5 33t-14.5 82zM948 86q6 49 35 80t70 31q86 0 86 -111q0 -53 -30 -84t-75 -31q-53 0 -71.5 37t-14.5 78zM1638 88q4 49 35 79t72 30q39 0 62.5 -28t23.5 -71q0 -53 -29.5 -90 t-75.5 -37q-47 0 -69.5 36t-18.5 81z" /> -<glyph unicode=" " horiz-adv-x="364" /> -<glyph unicode="‹" horiz-adv-x="1495" d="M-356 -446q4 29 19 43t28.5 16t38.5 0q10 0 21 -7t17.5 -13.5t17.5 -18.5t15 -16q43 -39 80 -39q43 0 87 32.5t69 81.5q27 55 49 158q8 37 23.5 120t23.5 122q25 127 119 684q2 16 -4 29.5t-23 11.5l-86 6q-6 -2 -10 3t-4 17q4 25 20 35q96 8 125 27q51 240 68 284 q59 166 135 261q55 66 140 105.5t159 39.5q111 0 146 -82q29 -66 -15 -104q-27 -23 -67 -19q-31 2 -79 58.5t-91 56.5q-31 0 -68 -18.5t-55 -49.5q-49 -80 -90 -323l-29 -166q-2 -16 15.5 -27.5t35.5 -11.5h77.5h123h72.5q26 0 36 4q31 10 39 61q16 121 51 220 q55 164 132 260q55 70 134 108.5t152 38.5q61 0 114.5 -38t51.5 -85q-6 -96 -100 -76q-29 8 -72 59.5t-88 49.5q-29 0 -64.5 -19.5t-56.5 -50.5q-51 -82 -92 -323l-27 -156q-4 -18 5.5 -34.5t23.5 -18.5q82 -4 166 0q76 0 117 6q29 2 78 16q49 8 49 -8l-125 -743 q0 -4 -1 -12.5t-1 -12.5q0 -20 18 -20q43 0 142 125q8 10 19 7t18.5 -16.5t5.5 -27.5q-152 -195 -267 -195q-102 0 -76 152q12 78 33 188.5t36 201.5t30 181q12 66 -35 66q-150 4 -215 2q-20 0 -35 -10q-2 -2 -14 -27l-90 -498q-25 -139 -38.5 -200.5t-49 -180t-89 -198.5 t-128.5 -135q-100 -74 -203 -74q-63 0 -113.5 37t-42.5 77q12 68 86 60q10 0 21.5 -7t18.5 -13.5t19.5 -17.5t16.5 -15q39 -39 76 -39q45 0 89 32.5t68 81.5q27 53 58 195q27 141 37 205q18 92 114 659q4 23 -9 45.5t-36 22.5q-66 4 -123 4h-143q-70 -8 -78 -55l-86 -486 q-55 -313 -110 -444q-72 -180 -193 -268q-100 -74 -203 -74q-66 0 -115 37t-40 80z" /> -<glyph unicode="›" horiz-adv-x="1509" d="M-358 -446q6 29 21 43t28.5 16t38.5 0q12 0 24.5 -8t30.5 -27l18 -18q39 -39 78 -39q43 0 87 32.5t68.5 80t47.5 157.5q8 37 23.5 120t23.5 122q25 127 119 684q2 16 -4 29.5t-21 11.5l-86 6q-14 -4 -14 14q-2 29 20 41q94 8 125 25q39 203 68 286q59 170 135 259 q55 68 140 107.5t159 39.5q111 0 148 -82q29 -66 -15 -106q-27 -25 -69 -19q-31 2 -80 58.5t-90 56.5q-31 0 -67 -18.5t-56 -49.5q-49 -80 -90 -323l-29 -166q-2 -16 15.5 -26.5t35.5 -10.5h55h74h47h68q76 0 86 45q27 137 59 235q57 172 133 261q45 55 113 96t144.5 52 t144.5 -30q23 -10 39 -2q12 4 49 29q12 14 24.5 14t16.5 -16l-240 -1391q-8 -53 17 -53q43 0 135 115q8 10 23.5 5t21.5 -18.5t0 -25.5q-154 -197 -268 -197q-72 0 -78 78q-4 45 12 133l96 522q6 12 1 36t-23 26q-76 2 -169 0t-102 -2q-33 -8 -39 -45l-84 -494 q-20 -125 -36.5 -197.5t-50 -184t-89 -193.5t-129.5 -137q-100 -74 -202 -74q-66 0 -116 37t-42 80q4 29 20.5 43t29.5 16t38 0q10 0 21.5 -6t18.5 -12.5t19.5 -18.5t16.5 -16q39 -39 76 -39q43 0 87 31.5t68 80.5q25 47 47 158q25 121 47 242q25 125 119 684q6 35 -18 41 q-33 2 -35 2h-25q-23 0 -58.5 -1t-72.5 -1h-67.5h-42.5q-56 -4 -64 -49l-86 -486q-20 -115 -28.5 -156.5t-36 -148t-54 -164t-75 -128t-109.5 -115.5q-100 -74 -203 -74q-66 0 -116 37t-41 80zM950 899q-4 -14 1 -32.5t16 -18.5h76.5h105.5h84q45 0 51 41l84 444 q-55 98 -144 116.5t-157 -73.5q-49 -80 -90 -323z" /> -<glyph unicode=" " horiz-adv-x="455" /> -<glyph unicode="€" horiz-adv-x="948" d="M14 481q0 18 12.5 38t28.5 20h119q0 66 14 151h-98q-29 0 -29 23q0 18 12.5 37.5t28.5 19.5h105q51 190 211 337.5t346 147.5t315 -84q20 -14 11 -55q-16 -68 -48 -237q-2 -12 -28 -13q-25 0 -25 35q0 299 -213 299q-137 0 -236.5 -117.5t-140.5 -312.5h412q29 0 29 -22 q0 -18 -12.5 -38t-28.5 -20h-414q-10 -74 -12 -151h391q29 0 29 -23q0 -18 -12.5 -37.5t-28.5 -19.5h-379q2 -186 55 -314.5t166 -128.5q104 0 191 68t139 201q8 25 30 24q29 0 23 -28q-25 -92 -59 -285q-18 8 -70 8q-20 0 -114.5 -20.5t-172.5 -20.5q-166 0 -269.5 120 t-115.5 376h-133q-29 0 -29 22z" /> -<glyph unicode="™" horiz-adv-x="2039" d="M18.5 1187q-2.5 5 1.5 38l17 151q2 20 9 25.5t32 5.5q315 -8 674 0q31 2 40 -5t11 -36l16 -147q4 -18 2 -27.5t-24 -9.5h-27q-14 84 -54 114.5t-136 30.5h-19.5h-17.5t-12.5 -2t-11.5 -6t-5 -13.5t-2 -21.5v-545q0 -76 15.5 -98.5t70.5 -28.5h14h4q4 -2 5 -28v-17 q0 -6 -3 -6q-4 -4 -32 -4q-129 4 -326 0q-29 0 -34 4t-5 25v16q0 8 8 10h13q55 8 68.5 29t13.5 96v551q0 14 -3.5 23.5t-11.5 12.5t-13 4t-20.5 0t-21.5 -1q-92 0 -131 -30.5t-55 -114.5h-31q-16 0 -18.5 5zM874 588q0 20 25 24q59 2 74.5 24.5t15.5 100.5v482 q0 84 -14 106.5t-74 24.5q-18 2 -22.5 6t-4.5 20v8q0 16 4.5 19.5t18.5 3.5q164 -6 266 -2q16 2 25 -16l248 -519q8 -14 21 -9t20 18l233 510q12 18 37 18h231q16 0 21.5 -1t11.5 -7t6 -21q0 -20 -4 -23t-26 -5q-53 -2 -67.5 -26t-14.5 -103v-482q0 -80 13 -100.5t71 -26.5 q25 -2 26 -8q2 -2 2 -20q0 -16 -6 -21.5t-24 -5.5h-351q-29 -2 -36 3t-7 26q0 12 3 17t5.5 7t12.5 2h14q57 6 71.5 30t14.5 95v430q0 18 -8 19q-4 0 -8 -10l-273 -601q-10 -18 -24 -18h-21q-8 0 -18 21l-272 585q-14 14 -17 -20v-404q0 -84 15.5 -105.5t70.5 -21.5h31 q18 0 18 -26q0 -29 -26 -29h-21q-143 6 -252 0q-27 -2 -31 2t-4 29z" /> -<glyph unicode="◼" horiz-adv-x="880" d="M0 0v881h881v-881h-881z" /> -<glyph unicode="fi" horiz-adv-x="1032" d="M-305 -451q6 29 20.5 42.5t27.5 15.5t35.5 0t53.5 -33l10 -10l11.5 -11.5l10.5 -10.5t12 -10t12.5 -7t14.5 -6t15 -4t16 -2q45 0 90.5 33.5t69.5 82.5q18 37 47 160q4 18 49 240q25 125 123 714q2 6 -3 14.5t-11 8.5h-104q-8 -2 -10.5 7t-0.5 20q4 18 19 24q98 8 129 27 q29 174 67 286q59 170 136 261q55 66 141 105.5t160 39.5q111 0 145 -80q27 -63 -16 -102q-25 -23 -66 -19q-10 2 -19.5 6.5t-19.5 12.5t-15 13t-16.5 18.5t-13.5 15.5q-47 51 -88 49q-31 0 -68.5 -18.5t-58.5 -49.5q-47 -74 -92 -325l-35 -193q-4 -20 16 -20q98 -4 191 0 q23 0 49.5 1t41.5 1t28 2q14 2 38.5 8t41.5 8q4 0 12 2t13 3t10.5 2t8.5 -1t3 -6l-129 -745q-6 -53 16 -53q45 0 148 131q8 8 18 6t17 -14.5t3 -24.5q-150 -193 -266 -193q-96 0 -71 148q31 184 104 610q6 39 -12 39q-143 4 -277 0q-6 0 -11 -2t-6 -4t-4 -10.5t-5 -10.5 l-91 -518q-20 -127 -36.5 -198.5t-51 -184t-89 -193.5t-130.5 -136q-100 -74 -203 -74q-66 0 -114.5 35.5t-40.5 76.5z" /> -<glyph unicode="fl" horiz-adv-x="997" d="M-350 -451q6 29 20.5 42.5t28.5 15.5t37 0q20 -2 51 -33l10 -10l11.5 -11.5l10.5 -10.5t12 -10t12 -7t14.5 -6t15.5 -4t16 -2q45 0 90.5 33.5t69.5 82.5q23 43 49 160q8 35 23.5 116t23.5 124q27 137 123 712q2 2 0 8.5t-8 11.5t-14 5h-105q-18 0 -14 22q4 23 25 25 q57 6 135 31q39 203 67 286q55 166 135 261q49 59 121 100t154 49t149 -43q18 6 72 41q12 14 21.5 13t11.5 -13l-246 -1419q-6 -49 19 -49q39 0 147 133q6 6 18.5 1t18.5 -16.5t0 -21.5q-152 -195 -266 -195q-68 0 -76 76q-4 37 14 131l105 561q0 27 -21 27h-297 q-10 0 -19 -7t-9 -22l-91 -514q-25 -135 -39 -199.5t-48.5 -181t-89 -196.5t-130.5 -135q-100 -74 -203 -74q-66 0 -114.5 35.5t-40.5 76.5zM430 874q-2 -8 3 -18t20 -10q137 -4 297 0q20 0 26 20l90 469q-57 102 -149 122t-160 -75q-49 -74 -94 -325z" /> -<glyph unicode="ffi" horiz-adv-x="1495" d="M-356 -446q4 29 19 43t28.5 16t38.5 0q10 0 21 -7t17.5 -13.5t17.5 -18.5t15 -16q43 -39 80 -39q43 0 87 32.5t69 81.5q27 55 49 158q8 37 23.5 120t23.5 122q25 127 119 684q2 16 -4 29.5t-23 11.5l-86 6q-6 -2 -10 3t-4 17q4 25 20 35q96 8 125 27q51 240 68 284 q59 166 135 261q55 66 140 105.5t159 39.5q111 0 146 -82q29 -66 -15 -104q-27 -23 -67 -19q-31 2 -79 58.5t-91 56.5q-31 0 -68 -18.5t-55 -49.5q-49 -80 -90 -323l-29 -166q-2 -16 15.5 -27.5t35.5 -11.5h77.5h123h72.5q26 0 36 4q31 10 39 61q16 121 51 220 q55 164 132 260q55 70 134 108.5t152 38.5q61 0 114.5 -38t51.5 -85q-6 -96 -100 -76q-29 8 -72 59.5t-88 49.5q-29 0 -64.5 -19.5t-56.5 -50.5q-51 -82 -92 -323l-27 -156q-4 -18 5.5 -34.5t23.5 -18.5q82 -4 166 0q76 0 117 6q29 2 78 16q49 8 49 -8l-125 -743 q0 -4 -1 -12.5t-1 -12.5q0 -20 18 -20q43 0 142 125q8 10 19 7t18.5 -16.5t5.5 -27.5q-152 -195 -267 -195q-102 0 -76 152q12 78 33 188.5t36 201.5t30 181q12 66 -35 66q-150 4 -215 2q-20 0 -35 -10q-2 -2 -14 -27l-90 -498q-25 -139 -38.5 -200.5t-49 -180t-89 -198.5 t-128.5 -135q-100 -74 -203 -74q-63 0 -113.5 37t-42.5 77q12 68 86 60q10 0 21.5 -7t18.5 -13.5t19.5 -17.5t16.5 -15q39 -39 76 -39q45 0 89 32.5t68 81.5q27 53 58 195q27 141 37 205q18 92 114 659q4 23 -9 45.5t-36 22.5q-66 4 -123 4h-143q-70 -8 -78 -55l-86 -486 q-55 -313 -110 -444q-72 -180 -193 -268q-100 -74 -203 -74q-66 0 -115 37t-40 80z" /> -<glyph unicode="ffl" horiz-adv-x="1509" d="M-358 -446q6 29 21 43t28.5 16t38.5 0q12 0 24.5 -8t30.5 -27l18 -18q39 -39 78 -39q43 0 87 32.5t68.5 80t47.5 157.5q8 37 23.5 120t23.5 122q25 127 119 684q2 16 -4 29.5t-21 11.5l-86 6q-14 -4 -14 14q-2 29 20 41q94 8 125 25q39 203 68 286q59 170 135 259 q55 68 140 107.5t159 39.5q111 0 148 -82q29 -66 -15 -106q-27 -25 -69 -19q-31 2 -80 58.5t-90 56.5q-31 0 -67 -18.5t-56 -49.5q-49 -80 -90 -323l-29 -166q-2 -16 15.5 -26.5t35.5 -10.5h55h74h47h68q76 0 86 45q27 137 59 235q57 172 133 261q45 55 113 96t144.5 52 t144.5 -30q23 -10 39 -2q12 4 49 29q12 14 24.5 14t16.5 -16l-240 -1391q-8 -53 17 -53q43 0 135 115q8 10 23.5 5t21.5 -18.5t0 -25.5q-154 -197 -268 -197q-72 0 -78 78q-4 45 12 133l96 522q6 12 1 36t-23 26q-76 2 -169 0t-102 -2q-33 -8 -39 -45l-84 -494 q-20 -125 -36.5 -197.5t-50 -184t-89 -193.5t-129.5 -137q-100 -74 -202 -74q-66 0 -116 37t-42 80q4 29 20.5 43t29.5 16t38 0q10 0 21.5 -6t18.5 -12.5t19.5 -18.5t16.5 -16q39 -39 76 -39q43 0 87 31.5t68 80.5q25 47 47 158q25 121 47 242q25 125 119 684q6 35 -18 41 q-33 2 -35 2h-25q-23 0 -58.5 -1t-72.5 -1h-67.5h-42.5q-56 -4 -64 -49l-86 -486q-20 -115 -28.5 -156.5t-36 -148t-54 -164t-75 -128t-109.5 -115.5q-100 -74 -203 -74q-66 0 -116 37t-41 80zM950 899q-4 -14 1 -32.5t16 -18.5h76.5h105.5h84q45 0 51 41l84 444 q-55 98 -144 116.5t-157 -73.5q-49 -80 -90 -323z" /> -</font> -</defs></svg> - \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.svg b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.svg @@ -1,244 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata></metadata> -<defs> -<font id="etbemboromanlf" horiz-adv-x="1001" > -<font-face units-per-em="2048" ascent="1638" descent="-410" /> -<missing-glyph horiz-adv-x="501" /> -<glyph horiz-adv-x="2048" /> -<glyph horiz-adv-x="2048" /> -<glyph unicode="
" horiz-adv-x="681" /> -<glyph unicode=" " horiz-adv-x="501" /> -<glyph unicode="	" horiz-adv-x="501" /> -<glyph unicode=" " horiz-adv-x="501" /> -<glyph unicode="!" horiz-adv-x="557" d="M168 78q0 49 31.5 78.5t81 29.5t82 -29.5t32.5 -78.5q0 -47 -32.5 -78t-82 -31t-81 31t-31.5 78zM173 1367q-1 19 15.5 32.5t49.5 13.5l67 -2q59 -2 72.5 -17.5t9.5 -68.5l-78 -950q-6 -14 -26.5 -16.5t-30.5 16.5l-78 950q0 23 -1 42z" /> -<glyph unicode=""" horiz-adv-x="870" d="M135 1241q0 139 111 139q53 0 84.5 -35t31.5 -94q0 -31 -8 -92q-4 -31 -16 -92l-59 -315q-10 -14 -33 -13q-12 0 -23.5 10.5t-13.5 26.5l-51 293q-23 127 -23 172zM510 1229q0 152 117 151q53 0 84.5 -35t31.5 -94q0 -70 -22 -186l-59 -313q-6 -16 -23 -19 q-14 -4 -30.5 3t-16.5 16l-55 311q-27 143 -27 166z" /> -<glyph unicode="#" horiz-adv-x="1431" d="M94 408q-6 31 0 63q0 33 45 33h154q25 0 34 6t13 31l66 315q4 31 -25 33h-68.5h-96.5h-71q-31 0 -42 7t-9 26q-4 27 4 75q0 23 43 25q145 4 269 0q20 -2 26 3t10 26l76 364q4 16 7 25.5t11.5 12.5t13.5 2t24.5 -3t31.5 -4q35 -2 39 -8t-2 -37l-69 -348q-4 -12 3 -22.5 t21 -10.5q45 4 186.5 1t184.5 -1q23 2 29 8t10 29q53 264 67 330q0 4 2 14t3 13t4.5 10.5t5.5 9.5t7 6t12 6t15 2l50 4q25 2 33 -14.5t1 -38.5l-71 -346q-6 -33 24 -33q55 -6 138 0h11h10h8t7 -2t5.5 -5t3.5 -9.5v-14.5q2 -8 -5 -76q0 -27 -47 -26h-44.5h-61.5h-45 q-8 0 -14.5 -1t-10.5 -2t-8 -5t-6 -6.5t-4 -10.5t-3 -10t-3 -12.5t-2 -14.5l-60 -286q-8 -37 31 -37q98 -4 225 0q16 0 29.5 1t21 -7.5t7.5 -28.5l-5 -61q0 -10 -3 -16.5t-5 -10.5t-10 -6t-11 -2t-14.5 -1t-13.5 -1q-121 -4 -231 0q-31 0 -40 -4.5t-12.5 -20.5t-11.5 -27 l-67 -331q-4 -27 -13.5 -37t-33.5 -10h-60q-37 0 -26 53l67 323q8 27 2 39.5t-31 14.5q-190 8 -342 0q-37 -2 -45 -7.5t-16 -39.5l-68 -334q-2 -12 -7 -21.5t-8 -14.5t-12 -7l-13.5 -3t-19.5 -1h-22l-32 -2q-10 0 -15.5 3t-6.5 11t0 14t4 17.5t3 15.5l68 328q6 25 1 33 t-32 8h-129q-20 0 -26.5 1t-11.5 9t-5 27zM467 526.5q2 -6.5 4 -7.5t7 -5t7 -8q193 8 365 0q47 0 55 37l62 297q6 33 1 41t-28 8q-199 4 -354 0q-37 -2 -43 -12q-4 -8 -8 -27l-66 -309q-4 -8 -2 -14.5z" /> -<glyph unicode="$" horiz-adv-x="980" d="M74 213q0 33 23.5 57.5t56.5 24.5q53 0 88 -88q4 -12 11 -32.5t10 -28t10.5 -21.5t18.5 -24.5t27 -22.5q16 0 17 28v502q-6 14 -14 21q-121 92 -156 135q-57 72 -57 168q0 92 60 165.5t159 106.5q8 0 8 19v110q4 10 18 13l23 2q16 -4 24 -19v-86q2 -2 4.5 -7t5.5 -8 t11 -3q51 4 100 0q4 -2 9.5 7t5.5 15v82q2 10 24 17h25q18 0 18 -23l-2 -96q0 -12 10 -23q102 -31 164 -80t62 -104q0 -33 -20.5 -54.5t-51.5 -21.5q-49 0 -94 68q-31 47 -54 71l-16 -8v-373q6 -37 12 -43q84 -53 134.5 -92t95.5 -109.5t45 -152.5q0 -115 -75 -202 t-202 -123q-10 0 -10 -19q0 -104 2 -162q0 -18 -22 -18h-31q-20 4 -16 24l2 140q0 20 -19 20q-43 -6 -96 2q-4 0 -11.5 -5t-7.5 -15l3 -131q0 -4 1 -10.5t1 -9.5t-3.5 -8t-9.5 -7h-51q-12 4 -8 22v9v153q-2 16 -12 21q-135 43 -189 98q-61 66 -61 129zM244 1004 q0 -78 75 -144q10 -8 17 14v5v241q2 2 0 9.5t-8 5.5q-84 -45 -84 -131zM401 51q4 -18 13 -18q63 -14 112 -4q11 0 11 20v418q0 10 -7.5 23.5t-11.5 15.5l-61 39q-20 12 -39 24q-8 4 -12.5 -3t-4.5 -25v-490zM401 819q0 -20 9 -28q12 -10 110 -74q17 8 17 20v391q0 20 -11 21 q-63 18 -110 10q-14 -2 -15 -29v-311zM602 76q0 -6 4 -10.5t7 -5.5t5 1q121 66 121 197q0 100 -98 166l-25 16q-6 4 -11 -4t-3 -16v-344z" /> -<glyph unicode="%" horiz-adv-x="1425" d="M90 938q0 131 84 216t205 85q123 0 209 -83t84 -212q-2 -131 -85 -216t-206 -85q-119 0 -205 85t-86 210zM207 942q0 -111 47 -171t127 -60q82 0 129 61.5t47 172t-48 170t-134 59.5q-78 0 -123 -61.5t-45 -170.5zM258 -98l801 1390q18 25 45 15l24 -11q19 -5 7 -34 l-797 -1383q-6 -12 -12 -16q-4 -2 -41 -2q-49 0 -27 41zM731 209q0 131 84 216t205 85q123 0 209 -83t84 -212q-2 -131 -85 -216t-206 -85q-119 0 -205 84t-86 211zM848 213q0 -111 47 -171t127 -60q82 0 129 61t47 172t-48 170t-134 59q-78 0 -123 -61t-45 -170z" /> -<glyph unicode="&" horiz-adv-x="1562" d="M86 328q0 162 121 266q53 47 207 119q35 23 24 30q-131 125 -131 263q0 117 83 188.5t218 71.5q123 0 204 -61.5t81 -157.5q0 -147 -211 -265q-6 -4 -5 -12t5 -12q68 -51 162 -142q88 -86 157 -188q8 -14 27 10q78 98 133 187q47 72 75 134t28 83q0 14 -22.5 20t-57.5 9 t-37 3q-8 4 -10 20.5t2 25.5q2 12 24 12q135 -6 359 2q20 4 24 -16v-27q0 -16 -28 -21q-10 -2 -40 -4t-45.5 -4t-37 -10t-35.5 -21q-29 -29 -80 -122q-14 -29 -34.5 -68t-22.5 -45q-63 -117 -164 -229q-10 -10 -2 -23q37 -61 71 -123q55 -100 87 -132t75 -32q53 0 166 78 q14 4 28.5 -22.5t0.5 -32.5q-147 -119 -273 -119q-86 0 -136 39t-109 147q-10 20 -27 50q-12 23 -31 4q-240 -240 -465 -240q-152 0 -255 105.5t-103 261.5zM285 352q0 -117 67.5 -188.5t177.5 -71.5q84 0 183.5 49t169.5 125q10 10 0 27q-72 111 -174 217 q-113 113 -193 166q-14 10 -41 -8q-190 -143 -190 -316zM467 1059q0 -131 145 -246q127 80 127 217q0 78 -40 123t-105 45q-59 0 -93 -37t-34 -102z" /> -<glyph unicode="'" horiz-adv-x="378" d="M78 1231q0 150 110 149q53 0 85 -35t32 -94q0 -39 -10 -94q-12 -66 -16 -90l-50 -281q-4 -20 -13 -32.5t-28 -10.5q-23 2 -27.5 6.5t-6.5 20.5q-2 8 -2 12l-50 285q-25 127 -24 164z" /> -<glyph unicode="(" horiz-adv-x="667" d="M162 492q0 256 105.5 505.5t287.5 446.5q31 23 61.5 -7t12.5 -61q-143 -160 -244 -422q-78 -205 -78 -462q0 -201 43 -359t146 -338q61 -104 133 -190q16 -33 -49 -64q-20 -10 -43 17q-172 190 -273.5 438t-101.5 496z" /> -<glyph unicode=")" horiz-adv-x="647" d="M25 -391q147 164 245 422q78 205 78 465q0 199 -43 356.5t-147 339.5q-57 102 -119 174q-12 12 -11 32.5t17 35.5q37 31 70 -2q176 -193 275 -437.5t99 -498.5q0 -260 -104 -511t-287 -444q-33 -25 -65.5 3t-7.5 65z" /> -<glyph unicode="*" horiz-adv-x="1093" d="M158 727q0 49 23.5 68.5t80.5 31.5q4 2 46 11.5t67 17.5q57 16 119 53q25 14 4 25q-66 35 -123 51q-20 6 -41 11t-42.5 10.5t-31.5 7.5q-55 16 -78.5 35.5t-23.5 66.5q0 23 19.5 49.5t66.5 26.5q10 0 18 -2t17.5 -8t15.5 -10.5t15 -13.5t13.5 -13t13.5 -15.5t11 -13.5 q74 -88 164 -143q23 -12 23 14q-4 96 -29 180q-29 96 -29 125q0 35 21.5 61.5t58.5 26.5t58.5 -26.5t21.5 -61.5q0 -37 -27 -125q-27 -92 -28 -180q0 -25 26 -12q92 59 158 141q66 76 106 76q47 0 65.5 -25.5t18.5 -50.5q0 -68 -79 -96q-25 -8 -72 -18.5t-64 -16.5 q-47 -14 -120 -49q-12 -6 -14.5 -9t-0.5 -6t17 -12q76 -41 116 -53q16 -6 65.5 -15.5t74.5 -17.5q77 -26 77 -96q0 -27 -21.5 -50.5t-53.5 -23.5q-39 0 -63.5 19.5t-53.5 58.5q-72 90 -160 143q-20 10 -20 -8q2 -123 28 -202q14 -35 19 -54q8 -18 8 -57t-22.5 -65.5 t-59.5 -26.5t-59.5 26.5t-22.5 65.5q0 29 8 57q12 33 21 54q27 80 28 198q0 25 -20 12q-84 -49 -160 -143q-23 -29 -33 -40t-33.5 -24.5t-52.5 -13.5q-33 0 -54 23.5t-21 50.5z" /> -<glyph unicode="+" horiz-adv-x="1429" d="M145 662v55v13v11t1 7.5t3.5 6.5t6.5 3t10 2h14h438q20 0 25.5 5t5.5 23v408q0 6 -1 14.5t-1 12.5q0 47 29 47h80q18 0 23 -7.5t5 -37.5v-445q-4 -20 21 -20h442q27 0 35 -7.5t8 -27.5v-63q0 -27 -9 -32t-40 -5h-426h-12h-9t-5.5 -2t-4.5 -7.5v-13.5v-442q0 -31 -6 -36 t-37 -5q-29 -8 -61 0q-8 0 -13 1t-9.5 3t-5.5 3t-2 6t-1 7v9.5v11.5v438q0 27 -28 27h-433q-27 0 -35 6t-8 31z" /> -<glyph unicode="," horiz-adv-x="514" d="M143 63q0 45 33 75t78 30q61 0 98 -44t37 -116q0 -88 -52 -168t-136 -119q-29 -14 -41 -2q-2 2 -5 7.5t-5 7.5q-10 31 6 35q137 82 137 178q0 20 -8 22q-6 4 -27 -2q-47 -10 -81 18.5t-34 77.5z" /> -<glyph unicode="-" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="." horiz-adv-x="419" d="M133 80q0 53 35 86t90 33q53 0 86 -32t33 -85q0 -51 -33 -85t-86 -34t-89 33t-36 84z" /> -<glyph unicode="/" horiz-adv-x="980" d="M76 -14.5q0 10.5 6 24.5q119 225 348 670.5t346 673.5q20 33 35 32l102 -4q8 0 14.5 -7t5.5 -20.5t-11 -27.5l-691 -1331q-20 -41 -45 -39h-15h-21.5t-24.5 1t-23.5 4t-17.5 8t-8 15.5z" /> -<glyph unicode="0" d="M70 636.5q0 278.5 124.5 476.5t307 198t307.5 -198t125 -476.5t-125 -476t-307.5 -197.5t-307 197.5t-124.5 476zM250 637q0 -240 35 -387q49 -213 217 -213q80 0 137 61.5t78 151.5q39 172 39 387q0 211 -39 387q-23 104 -79 158.5t-136 54.5q-164 0 -217 -213 q-35 -145 -35 -387z" /> -<glyph unicode="1" d="M178 987q0 18 8 25q109 76 207 170q66 59 96 96q16 27 46 33h24q16 0 28.5 -13.5t14.5 -27.5l2 -1092v-24q0 -39 12.5 -56.5t57.5 -19.5h82q29 0 35 -41q0 -49 -39 -45q-168 10 -459 2q-29 -4 -37 12q-4 27 -2 37q16 35 49 35q72 0 76 2q41 2 51 23.5t10 66.5l2 866 q-4 16 -17 27.5t-24 3.5q-76 -55 -180 -106q-16 -8 -33 8z" /> -<glyph unicode="2" d="M78 29q0 8 4 15t10 15.5t8 10.5q96 113 248 268q8 8 52 53t55.5 57.5t49.5 53.5t50 59.5t40 57t38 67.5t24.5 67t19.5 76.5t5 79.5q0 115 -55.5 185.5t-157.5 70.5q-96 0 -177 -67.5t-120 -182.5q-8 -25 -41 -24q-29 0 -22 27q27 180 141.5 286.5t277.5 106.5 q162 0 253 -104.5t91 -268.5q0 -125 -124 -285q-59 -78 -131 -153.5t-168.5 -169.5t-141.5 -142q-8 -8 -9 -15t12.5 -15t43.5 -11q154 8 277 0q115 -6 157.5 16.5t59.5 106.5q6 27 35 33l10 -4q16 0 16 -30.5t-30 -237.5q-4 -16 -26 -27.5t-44 -11.5q-45 0 -172 4t-254 4 t-248 -8q-43 0 -55 20z" /> -<glyph unicode="3" d="M84 123q0 33 23.5 57.5t56.5 24.5q41 0 129 -72q61 -51 97 -66.5t81 -15.5q109 0 182.5 100.5t73.5 247.5q0 117 -51 192t-133 75q-66 0 -113 -33q-10 -8 -26.5 -6t-24.5 12q-16 23 6 45q98 72 166 141q92 94 92 181q0 72 -52 122t-128 50q-68 0 -136.5 -49.5 t-115.5 -133.5q-8 -18 -43 -8q-31 12 -18 39q57 133 159.5 209t220.5 76q117 0 197 -67.5t80 -172.5q0 -131 -133 -242q-14 -14 -12 -24t12 -12q106 -23 169.5 -118t63.5 -224q0 -195 -149.5 -341.5t-354.5 -146.5q-125 0 -222 46t-97 114z" /> -<glyph unicode="4" d="M76 391v35q252 403 579 854q23 31 60 31h6q43 -12 35 -62v-719q0 -18 28 -36l140 4q2 0 9 -1t9 -2t6 -4.5t7.5 -9.5t5.5 -14q6 -8 1.5 -40t-4.5 -34q-4 -23 -30 -26l-140 -7q-4 0 -9 -1t-14 -12t-9 -30q8 -213 4 -307q0 -45 -39 -47q-33 6 -86 2q-41 0 -41 47 q-6 193 0 301q-2 18 -6 27.5t-8.5 12.5t-14.5 5q-168 -12 -454 0q-35 2 -35 33zM231 518q-4 -8 6.5 -17t32.5 -12q96 -8 291 0q31 8 33 39q8 203 0 457q-4 29 -9 35t-20 -2q-88 -119 -194.5 -279.5t-139.5 -220.5z" /> -<glyph unicode="5" d="M113 102q0 33 23.5 57.5t58.5 24.5q25 0 51 -13t41.5 -25.5t45 -40t36.5 -33.5q35 -29 77 -29q102 0 170 95t68 232.5t-70.5 220.5t-191.5 83q-94 0 -176 -56q-29 -16 -41 -8q-20 14 -19 47l43 578q4 49 93 49l292 -4h30h27t19 1t19.5 6t13.5 11q10 12 27 13h22 q18 -12 14 -39l-16 -115q-8 -20 -20.5 -28.5t-49.5 -10.5l-352 6q-35 -10 -43 -37l-14 -256q-2 -14 8 -18t23 2q61 23 137 23q174 0 289.5 -121t115.5 -299q0 -193 -130 -324t-333 -131q-123 0 -205.5 38t-82.5 101z" /> -<glyph unicode="6" d="M100 504q0 281 171 493.5t479 307.5q33 10 43 -9l10 -14q12 -25 -19 -37q-197 -88 -303 -200.5t-149 -280.5q-4 -18 7 -30.5t23 -4.5q66 45 189 45q154 0 252 -112.5t98 -274.5q0 -176 -110.5 -300t-276.5 -124q-190 0 -302 150.5t-112 390.5zM281 461q0 -207 61 -320.5 t176 -113.5q98 0 150.5 88t52.5 252q0 156 -52.5 242.5t-148.5 86.5q-80 0 -209 -98q-25 -18 -28 -63q-2 -23 -2 -74z" /> -<glyph unicode="7" d="M68 1026l10 186q2 20 27.5 44t46.5 22q305 -10 661 0q23 0 39 -13.5t14 -31.5l-4 -31l-479 -1208q-14 -37 -51 -31l-68 10q-39 6 -20 47l454 1057q6 12 -7 27.5t-34 13.5q-98 -4 -391 -4q-96 2 -108 -10q-16 -12 -29 -86q-4 -16 -32.5 -16.5t-28.5 24.5z" /> -<glyph unicode="8" horiz-adv-x="950" d="M82 311q0 178 201 297q20 12 29.5 27.5t-3.5 26.5q-201 117 -200 305q0 141 106.5 240.5t253.5 99.5t241.5 -86t94.5 -217q0 -180 -168 -277q-14 -12 -7 -25.5t23 -23.5q217 -129 217 -328q0 -162 -115.5 -274.5t-281.5 -112.5q-160 0 -275.5 102.5t-115.5 245.5z M236 313q0 -123 69.5 -203.5t169.5 -80.5q102 0 172 75.5t70 188.5q0 98 -58 156q-57 61 -200 139q-39 20 -66 0q-158 -106 -157 -275zM250 1026q0 -53 21.5 -96t62.5 -76t76.5 -53.5t91.5 -44.5q33 -14 61 8q96 83 96 237q0 109 -51 175.5t-141 66.5q-92 0 -154.5 -62.5 t-62.5 -154.5z" /> -<glyph unicode="9" d="M80 887q0 174 116.5 296t284.5 122q193 0 304.5 -148.5t111.5 -388.5q0 -279 -165 -488.5t-468 -306.5q-41 -12 -63 17q-20 23 14 39q231 100 350 247q86 106 115 238q4 18 -1 30.5t-14.5 12.5t-15.5 -2q-78 -55 -203 -55q-154 0 -260 112.5t-106 274.5zM258 907 q0 -154 59.5 -241.5t157.5 -87.5q80 0 197 88q39 31 43 73q2 23 2 74q0 207 -61.5 317.5t-178.5 110.5q-100 0 -159.5 -87t-59.5 -247z" /> -<glyph unicode=":" horiz-adv-x="526" d="M156 84q0 45 30.5 73.5t77.5 28.5t78 -28.5t31 -73.5t-31 -74.5t-78 -29.5t-77.5 29.5t-30.5 74.5zM156 717q0 47 30.5 75.5t77.5 28.5t78 -28.5t31 -75.5q0 -45 -31 -74t-78 -29t-77.5 29t-30.5 74z" /> -<glyph unicode=";" horiz-adv-x="471" d="M129 74q0 45 34 75.5t81 30.5q63 0 105 -47t42 -121q0 -96 -64.5 -182t-164.5 -125q-16 -6 -27.5 20.5t6.5 34.5q145 88 146 191q0 29 -15 29q-8 0 -24.5 -3.5t-24.5 -3.5q-39 0 -66.5 30t-27.5 71zM131 713q0 45 31 74.5t78 29.5t78.5 -28.5t31.5 -75.5q0 -45 -31.5 -74 t-78.5 -29t-78 29t-31 74z" /> -<glyph unicode="<" horiz-adv-x="1429" d="M143 672q-6 18 0 51q0 29 25 39q707 313 1069 455q35 14 44 -4.5t9 -59.5v-33q0 -27 -45 -47q-705 -299 -866 -362q-41 -16 4 -35q418 -184 879 -367q29 -12 28 -47v-45q0 -66 -63 -43q-344 127 -1061 455q-23 10 -23 43z" /> -<glyph unicode="=" horiz-adv-x="1429" d="M139 428v49q0 49 58 49q174 -4 1056 -4q39 0 39 -37l-2 -55q-2 -29 -10 -37t-43 -8h-1042q-31 0 -43.5 8t-12.5 35zM145 983q6 25 43 25q33 0 466 1t585 5q31 0 41 -18.5t10 -47.5q0 -4 1 -17.5t1 -21.5q0 -14 -1 -21t-9 -11.5t-14 -4.5h-29h-1034q-47 -6 -58 39z" /> -<glyph unicode=">" horiz-adv-x="1429" d="M141 262q0 35 29 47q553 221 866 361q18 8 26.5 19t-9.5 22q-324 139 -867 362q-37 14 -41 25q-2 8 -2 26v37q0 41 13.5 53.5t38.5 2.5q481 -199 1058 -451q35 -16 35 -43q6 -33 2 -51q0 -18 -7 -27.5t-36 -23.5q-387 -174 -1042 -447q-61 -27 -62 43q0 8 -1 23.5 t-1 21.5z" /> -<glyph unicode="?" horiz-adv-x="741" d="M86 1260q0 113 197 112q168 0 273.5 -110.5t105.5 -284.5q0 -203 -148 -303q-59 -41 -147 -74q-86 -29 -86 -86q0 -53 88 -158q2 -4 -2.5 -11t-10.5 -9q-12 -4 -32.5 1t-28.5 15q-109 129 -109 230q0 74 38 117.5t128 78.5q135 49 183.5 99.5t48.5 132.5t-53.5 127 t-151.5 45q-31 0 -82 -7.5t-78 -7.5q-133 0 -133 93zM197 78q0 49 34.5 80.5t85.5 31.5q53 0 87 -30.5t34 -81.5q0 -49 -33.5 -81t-87.5 -32q-51 0 -85.5 32t-34.5 81z" /> -<glyph unicode="@" horiz-adv-x="1966" d="M246 565q0 362 238.5 612t584.5 250q281 0 460 -168.5t179 -439.5q0 -254 -148.5 -439t-349.5 -185q-141 0 -141 133q0 39 2 63q4 20 -10 8q-6 -8 -10 -14q-29 -35 -90 -92q-109 -98 -207 -98q-72 0 -118 62t-46 153q0 113 60.5 242.5t158.5 232.5q139 143 264 143 q94 0 135 -72q12 -20 25 13q0 4 2 11t3 10t2 8.5t3 7.5t4 5t4 5t6.5 4t8.5 3t10 2t12 1q18 2 86 2q20 0 21 -22q0 -2 -56.5 -181.5t-88 -297t-36.5 -169.5q-4 -80 56 -79q45 0 102.5 34.5t102.5 87.5q72 88 115.5 203t43.5 230q0 229 -158.5 377.5t-398.5 148.5 q-305 0 -518 -236.5t-213 -580.5q0 -301 185.5 -487.5t478.5 -186.5q231 0 406 115.5t274 339.5q8 18 14 22t25 4q4 0 10 -1t10 -1q16 -4 10 -29q-84 -244 -287.5 -384t-465.5 -140q-328 0 -544 217t-216 553zM745 436q0 -49 26 -81.5t63 -32.5q98 0 221 163q53 72 86 170 q39 123 39 193q0 53 -28 86t-71 33q-68 0 -135 -78q-80 -96 -140.5 -231.5t-60.5 -221.5z" /> -<glyph unicode="A" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17q2 -8 2 -17t-2 -17q-5 -18 -17 -18 q-131 6 -286 6q-124 0 -263 -4q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 28q7 11 7 27q0 22 -13 55q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-54 -3 -134 -3t-185 3q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355 q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0q14 -2 14 -39q-4 -35 -14 -35q-171 3 -282 3t-162 -3h-23q-22 4 -22 33q0 12 4 28zM535 727q-1 -2 -1 -4q0 -15 25 -27q64 -2 126.5 -2t121.5 2q10 0 15 10q3 6 3 12q0 5 -2 9q-68 188 -125 373q-4 10 -13 13q-2 1 -4 1 q-6 0 -9 -8q-39 -127 -137 -379z" /> -<glyph unicode="B" horiz-adv-x="1343" d="M43 27.5q0 33.5 14 38.5q39 6 49 2q133 0 164 31.5t31 172.5v783q0 150 -26.5 179.5t-151.5 29.5h-47q-16 0 -14.5 33.5t14.5 35.5l18 2q154 16 584 17q127 0 184.5 -11.5t134.5 -46.5q82 -39 130.5 -109.5t48.5 -154.5q0 -88 -53.5 -157.5t-143.5 -102.5q-16 -6 4 -16 l41 -21q231 -112 231 -325q0 -141 -90 -255t-223 -141q-109 -21 -228 -21q-24 0 -48 1q-162 3 -314 3t-293 -3q-16 2 -16 35.5zM500 360q0 -109 10 -163q23 -121 223 -121q133 0 218 92t85 227q0 86 -42 160t-115 117q-31 18 -63 29.5t-70 14.5q-36 3 -60 4h-30h-42 q-48 -1 -69 -1q-45 -8 -45 -39v-320zM500 829q0 -14 6 -24t11 -13.5t7 -3.5q14 0 62 -2h42h30q26 1 66 4t71.5 10t58.5 19q109 45 109 199q0 131 -91 209q-66 53 -165 63q-41 4 -79 4q-53 0 -100 -8q-29 -6 -28 -33v-424z" /> -<glyph unicode="C" horiz-adv-x="1560" d="M115 649q0 315 208.5 514t544.5 199q147 0 336 -70q39 -15 65 -15q22 0 36 11q8 6 27.5 6t21.5 -8q21 -87 21 -157q0 -14 -1 -27q0 -18 -2 -60q-1 -21 -1 -37.5t1 -27.5q-4 -18 -28.5 -23.5t-32.5 7.5q-53 154 -163 239.5t-267 85.5q-248 0 -393.5 -161.5t-145.5 -432.5 q0 -279 160 -463t407 -184q182 0 334 135q41 37 62.5 65.5t60.5 98.5q4 18 43 14q25 -4 23 -16q-49 -170 -144 -328q-27 6 -47 6q-61 0 -160 -30q-88 -29 -235 -29q-324 0 -527.5 194.5t-203.5 493.5z" /> -<glyph unicode="D" horiz-adv-x="1583" d="M25 1296q2 30 16 33l14 4q406 16 602 17q201 0 332 -34t240 -112q248 -178 248 -495q0 -231 -140.5 -420t-363.5 -252q-150 -43 -404 -43l-491 -2q-39 0 -45 18q-7 17 -7 29q0 22 23 31q14 2 41 3t35 1q18 2 32.5 6t26 9t19.5 16.5t13 17.5t9 22.5t6 22.5t3.5 26.5 t1.5 25.5v27.5v26.5v781q0 137 -26 174t-151 37h-18q-16 0 -16 25v5zM434 209q0 -80 32 -114t128 -34q305 0 483 151t178 464q0 152 -56 279.5t-155 203.5q-68 53 -138 78t-191 37q-68 6 -143 6q-45 0 -93 -2q-45 -4 -45 -43v-1026z" /> -<glyph unicode="E" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q335 2 563.5 2t350.5 -2q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23 q-20 125 -57 156.5t-164 33.5q-118 4 -193 4q-50 0 -81 -2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q2 -40 2 -106q0 -99 -4 -258q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 128t-149 24 l-235 2q-29 -8 -29 -33v-344q0 -119 21.5 -142.5t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-3 8 -3 18q0 9 2 19z" /> -<glyph unicode="F" horiz-adv-x="1112" d="M82 26q2 32 18 35q88 4 117 32t29 110v921q0 82 -32 111t-116 33q-4 2 -8 9t-4 16.5t1 18.5t6 15q4 4 9 5q2 0 4 -1h883q12 0 23.5 -12.5t9.5 -22.5l-6 -225q-12 -7 -27 -7t-35 7q-4 104 -43 133t-182 29h-248q-27 0 -35 -33l-2 -401q0 -12 10.5 -23.5t18.5 -13.5 q39 -2 83 -2t97.5 1t81.5 1q115 2 145.5 18.5t39.5 89.5q2 20 26 25q31 4 33 -16v-367q-4 -12 -29.5 -12t-27.5 12q-10 100 -43 126q-31 24 -135 24h-17q-58 -2 -117 -2t-118 2q-45 -4 -46 -41v-418q0 -82 32 -111t122 -29h21q16 -4 16 -36q0 -15 -4 -25q-3 -9 -10 -8h-2 q-171 2 -300 2t-217 -2q-23 0 -23 26q1 3 1 6z" /> -<glyph unicode="G" horiz-adv-x="1562" d="M117 639q0 152 61.5 293t171.5 244q106 100 222 145t276 45q131 0 338 -61q45 -12 63 -13q25 0 41 17q16 4 47 0q7 -2 7 -90.5t-7 -264.5q-2 -18 -32.5 -19t-32.5 15q-68 342 -391 342q-254 0 -397.5 -171t-143.5 -468q0 -274 141.5 -444t374.5 -170q125 0 266 63 q25 10 25 68q0 14 -1 60t-1 85t2 62q0 82 -33 107.5t-125 29.5l-80 2q-10 0 -16 17.5t-2 35t18 19.5q101 -3 243 -3t323 3q22 0 22 -21q0 -6 -2 -14q-2 -12 -8 -23.5t-12 -9.5q-74 -2 -100.5 -32.5t-28.5 -108.5q-2 -55 -2 -114t2 -120q0 -47 -19 -55q-106 -55 -257.5 -92 t-278.5 -37q-297 0 -485.5 191.5t-188.5 486.5z" /> -<glyph unicode="H" horiz-adv-x="1613" d="M53 8q-5 15 -5 27q0 20 15 31q10 2 52 2q72 4 98.5 32.5t26.5 102.5v921q0 80 -30 109t-110 33q-8 4 -11 20.5t1 30.5t14 14q131 -6 254.5 -6t239.5 6q8 0 20 -8q10 -10 3 -45q-2 -10 -25 -12q-88 0 -122 -33t-34 -109v-374q0 -10 9.5 -20.5t27.5 -10.5q134 -3 292.5 -3 t340.5 3q16 0 38.5 10t22.5 23v372q0 76 -33.5 109t-123.5 33h-41q-20 4 -20 26q0 11 5 27q8 18 37 18q22 1 53 1q77 0 212.5 -4t204.5 -4q28 0 44 1q20 2 28.5 -19.5t-1.5 -37.5q-4 -10 -29 -10q-76 -6 -104.5 -36t-30.5 -104q-4 -139 -4 -316t2 -364.5t2 -240.5 q0 -74 34 -104.5t122 -30.5q39 -1 45 -17q4 -9 4 -18t-3 -19q-7 -20 -26 -20h-581q-25 0 -27 18q-6 18 1 36t24 18h49q84 0 120.5 30.5t36.5 106.5v383q-4 37 -38 37q-144 -6 -308.5 -6t-347.5 6q-10 0 -23.5 -14.5t-13.5 -37.5v-368q0 -80 30 -107.5t116 -27.5h10h10 q14 2 22.5 -15.5t2.5 -37t-25 -21.5h-520q-27 0 -33 14z" /> -<glyph unicode="I" horiz-adv-x="743" d="M106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-26 3 -26 27q0 10 4 24q6 14 28 14q8 0 205 -5q66 -2 117 -2q103 0 149 7h3q29 0 30 -22q6 -43 -10 -43q-4 0 -13.5 -2t-15.5 -2q-94 -2 -117.5 -36t-23.5 -175v-850 q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2q12 -8 14 -26q1 -5 1 -9q0 -13 -4 -23q-5 -14 -13 -14q-127 4 -254 4l-254 -4q-25 0 -25 31z" /> -<glyph unicode="J" horiz-adv-x="663" d="M-184 -465q0 39 26.5 67.5t63.5 28.5q14 0 28.5 -7t36 -25.5t23.5 -20.5q43 -33 51 -37q19 -8 40 -8q18 0 37 7q40 14 64 46q33 49 43.5 130t10.5 298q0 1024 -2 1110q-2 84 -35 114t-123 30q-8 -2 -25 -2q-16 2 -19 22.5t5 32.5q6 10 31 10q89 -5 216.5 -5t293.5 5 q22 0 28 -12q4 -9 4 -22v-9q-2 -18 -12 -20h-22q-86 -6 -114 -35t-28 -109v-974q0 -145 -28 -273q-37 -180 -107 -287q-119 -182 -289 -182q-88 0 -143 36t-55 91z" /> -<glyph unicode="K" horiz-adv-x="1515" d="M41 38q4 26 27 34q12 4 38 0q90 0 124 30.5t34 100.5v921q0 82 -32.5 111t-125.5 29h-40q-14 2 -19.5 23.5t2.5 33.5q4 14 29 14q209 -5 359 -5q113 0 192 3q29 0 28 -33q0 -37 -36 -36q-92 0 -125 -29t-33 -111v-430q2 -25 35 -14q39 14 73 47q94 84 215 246t121 241 q0 27 -20.5 35t-95.5 17l-21 2q-25 18 -6 53q4 14 24 10q148 -4 277 -4t238 4q29 2 24 -33q-4 -29 -24 -28q-147 -2 -209 -47q-18 -12 -39 -36t-32 -40.5t-34.5 -52t-27.5 -41.5q-70 -109 -230 -314q-25 -29 -35 -37q39 -16 117 -92q59 -57 116.5 -122.5t131.5 -161 t104 -131.5q68 -80 117 -103.5t145 -23.5q23 -1 29 -13q8 -11 8 -26q0 -5 -1 -9q-3 -22 -23 -26q-37 3 -150 3q-151 0 -438 -5q-23 4 -27 12q-6 12 -3 32.5t18 22.5q80 0 105.5 12.5t25.5 34.5q0 25 -27 60q-14 18 -56 71.5t-60.5 77t-56.5 68.5t-65.5 72.5t-64.5 61.5 t-74 61q-35 25 -71 30q-20 2 -26.5 -5t-6.5 -28v-372q0 -74 33.5 -105.5t124.5 -31.5q33 0 38 -15q12 -27 0 -51q-4 -8 -28 -8q-127 5 -263 5t-280 -5q-33 0 -39 8q-9 9 -9 26q0 6 1 12z" /> -<glyph unicode="L" horiz-adv-x="1218" d="M45 42q4 20 16 24q2 0 8.5 2t8.5 2h8q150 0 164 67q4 45 4 146v841q0 82 -33 112t-125 30h-24q-14 2 -16.5 24.5t5.5 32.5q8 16 31 10q87 -2 198 -2q167 0 388 4q25 0 29 -18q4 -13 4 -24q0 -30 -31 -31q-41 -4 -66 -5q-117 -4 -139 -18t-22 -94v-938q0 -63 26.5 -87 t89.5 -24h193q121 0 168 20.5t119 116.5l71 95q29 10 43 0q11 -6 11 -15q0 -5 -3 -10q-80 -190 -131 -272q-27 -39 -63 -39q-357 6 -596 6q-191 0 -305 -4q-25 -4 -29 18q-4 6 -4 15q0 7 2 15z" /> -<glyph unicode="M" horiz-adv-x="1929" d="M57 49q8 16 25 14h19q40 1 66 7q32 8 47 38.5t19.5 54t8.5 85.5q2 16 2 26q6 96 21.5 281.5t23.5 334t8 281.5q0 47 -22.5 63.5t-90.5 22.5q-28 3 -28 33q0 8 2 17q5 27 30 27q4 0 9 -1q71 -4 154 -4q55 0 114 2q39 0 49 -20l438 -998q6 -12 19.5 0.5t19.5 24.5l420 969 q14 25 51 24q72 -2 139 -2t130 2h9h8t5 -2t5 -5l3 -9q6 -49 -10 -51l-22 -2q-74 -6 -93.5 -24.5t-19.5 -61.5q0 -18 3 -49t3 -37l55 -811q10 -147 35 -179t121 -32q33 0 37 -23v-35q-2 -16 -31 -16q-70 -2 -168 -2q-148 0 -362 4q-14 0 -19 14q-4 18 0 39q0 16 35 17 q111 0 139 43q20 32 20 102q0 26 -3 57q-29 494 -49 795q0 16 -17 -2q-6 -6 -8 -14l-451 -1049q-2 -10 -31.5 -10t-33.5 10l-463 1046q-6 14 -18 13q-6 -2 -7 -8l-47 -764q-4 -82 -4 -103q0 -59 30 -84.5t114 -34.5q23 0 26 -18q8 -29 -4 -41q-2 -2 -24 -8q-81 -2 -187.5 -2 t-238.5 2q-19 4 -19 22q0 13 8 31z" /> -<glyph unicode="N" horiz-adv-x="1708" d="M70 18q-1 8 -1 14q0 16 7 23q10 14 30 15q158 0 158 118v1035q-55 41 -166 43q-8 -2 -12 9t-4 25q0 33 33 33q85 -2 158 -2t135 2q29 0 49 -24l837 -959q12 -18 31 12q4 8 4 17v676q0 88 -4 123.5t-22 52.5q-18 18 -58 24q-33 4 -112 9q-12 0 -18.5 18t-1.5 34.5t20 16.5 q64 -3 166 -3q135 0 337 5q13 0 13 -39v-9q-1 -13 -5 -16q-6 -5 -24 -5q-119 -4 -144.5 -31t-25.5 -145v-1082q0 -27 -36 -31q-8 -1 -14 -1q-23 0 -28 12q-4 4 -72.5 81.5t-192.5 218t-224 255.5l-475 540q-6 4 -11.5 0t-8.5 -15t-3 -28v-755q0 -104 12 -140q20 -66 99 -71 q14 -2 34.5 0t43 -2t26.5 -13q10 -18 5 -41.5t-30 -23.5q-143 3 -253 3q-146 0 -232 -5q-16 -2 -20 26z" /> -<glyph unicode="O" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z " /> -<glyph unicode="P" horiz-adv-x="1181" d="M51 1296q0 35 17 35q147 18 471 19q168 0 272 -27q133 -35 211 -132t78 -224q0 -193 -135.5 -304.5t-374.5 -111.5q-37 0 -103 10q-6 0 -10 -7t-6 -17.5t-4 -20.5v-313q-1 -81 31 -105q29 -22 112 -22h15h71q16 -4 22 -26q5 -22 -2 -42q-6 -18 -19 -18h-3q-151 6 -310 6 q-127 0 -259 -4q-29 0 -37 12q-6 12 -6 27q2 45 61 45q76 0 100.5 14t24.5 70v944q0 100 -20 134q-18 32 -72 32h-6l-102 -2q-6 -2 -10.5 7t-6.5 21zM467 659q0 -27 29 -34q43 -8 79 -9q154 0 231 95.5t77 261.5q0 203 -140 276q-75 40 -178 40q-37 0 -78 -5q-20 -2 -20 -47 v-578z" /> -<glyph unicode="Q" horiz-adv-x="1683" d="M92 643q0 309 213 516t539 207q319 0 514.5 -189.5t195.5 -482.5q0 -240 -139 -429t-368 -265q-6 -2 -8.5 -7t5.5 -11q115 -45 281 -187q96 -82 163 -112.5t163 -34.5q8 -2 8 -9q0 -12 -25 -38q-16 -16 -28 -21q-59 -12 -105 -12q-221 0 -485 225q-131 109 -144 119 q-33 25 -104 51q-305 27 -490.5 215.5t-185.5 464.5zM313 692q0 -281 158 -469t401 -188q145 0 254 94t158 227.5t49 276.5q0 293 -148.5 476t-398.5 183q-213 0 -343 -167t-130 -433z" /> -<glyph unicode="R" horiz-adv-x="1425" d="M41 10q-4 8 -4 19t4 24q6 16 61 17q92 0 124 25.5t32 107.5v71v781q0 150 -26.5 179.5t-170.5 31.5q-8 0 -14 13t-3 30.5t17 23.5l21 2q133 14 487 15q178 0 263.5 -28t166.5 -101q113 -102 113 -256q0 -113 -56.5 -208t-148.5 -143q-18 -6 -4 -26q14 -25 55 -93.5 t66 -103.5l115 -172q33 -49 55.5 -72.5t73.5 -64.5q47 -37 110 -49q20 -14 20 -31q0 -10 -7 -20l-13 -9q-10 0 -30.5 -2t-30.5 -2q-121 0 -186.5 33t-116.5 92q-68 80 -174 246q-39 63 -82 143q-2 4 -8.5 15.5t-11.5 18.5t-11 16.5t-14 13.5t-17 4q-65 -8 -131 -8l-65 2 q-41 0 -41 -25q0 -211 2 -317q2 -82 31.5 -107.5t121.5 -25.5q4 0 14.5 2t17.5 2t15.5 -1t14.5 -5.5t8 -12.5q6 -27 2 -45q-2 -6 -13 -11t-16 -5h-63q-137 0 -526 -4q-20 6 -27 20zM459 655q0 -41 20 -41q51 -3 90 -3q75 0 111 12q100 35 155.5 124.5t55.5 202.5 q0 162 -75 249t-267 87q-90 0 -90 -39v-592z" /> -<glyph unicode="S" horiz-adv-x="1050" d="M115 328q0 10 12 14t27.5 3t19.5 -7q31 -94 63.5 -145.5t90.5 -90.5q86 -59 172 -59q117 0 187.5 65.5t70.5 165.5q0 29 -5 54.5t-20.5 52.5t-27 45t-39 44t-40 38t-48 36.5t-45 32t-48.5 33t-43 27.5q-74 49 -117.5 83t-97 86t-78 111.5t-24.5 129.5q0 141 100.5 230 t263.5 89q66 0 170 -35q57 -18 76 -18q12 0 33 18q27 8 47 0q12 -31 39 -278q-2 -20 -26.5 -20.5t-28.5 9.5q-98 250 -291 250q-96 0 -149.5 -51t-53.5 -135q0 -100 117 -203q49 -45 154.5 -116.5t176 -124t129 -140.5t58.5 -186q0 -164 -116.5 -269.5t-305.5 -105.5 q-68 0 -213 43q-51 14 -61 14q-16 0 -31 -22q-23 -10 -53 0q-25 84 -45 332z" /> -<glyph unicode="T" horiz-adv-x="1394" d="M70 1014q8 168 32 352q14 12 32 12h5q21 -2 25 -12q16 -35 115 -35q148 3 359 3t484 -3q18 -1 33 -1q45 0 59 5q18 6 27 31q6 10 28.5 8t33.5 -8l32 -354q0 -4 -1 -8.5t-4 -6.5t-6 -3t-7 -2t-8 -1q-12 0 -19.5 1t-11.5 7.5t-5 9.5t-3 13q-25 127 -54.5 169t-85.5 42h-299 q-10 0 -19 -13.5t-9 -23.5v-273v-376v-273v-71q0 -80 31.5 -103.5t123.5 -23.5h60q18 0 29 -27q6 -18 0 -39q-6 -16 -33 -16q-102 4 -237 4q-169 0 -390 -6q-20 0 -25 14q-8 25 0 49q8 12 25 17h80q80 0 107.5 26.5t27.5 104.5v71v280v370v280q0 10 -16.5 19.5t-30.5 9.5 h-236h-43q-57 0 -87.5 -46t-57.5 -186q-10 -6 -24.5 -7t-25.5 4.5t-11 15.5z" /> -<glyph unicode="U" horiz-adv-x="1669" d="M48 1314q3 16 18 17q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q32 83 32 272v11v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q114 2 240 2t266 -2q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v535q0 82 -30 103.5t-146 23.5 q-10 0 -16 16q-4 10 -3 21q0 5 1 11z" /> -<glyph unicode="V" horiz-adv-x="1558" d="M49 1274q-3 9 -3 17q0 12 5 24q4 16 35 16q138 -4 272 -4t265 4q41 0 45 -6q16 -20 4 -45q-2 -10 -25 -20q-106 -4 -150 -18.5t-44 -47.5q0 -20 34 -111l318 -788q2 -4 7 -10t13.5 -13.5t16.5 -3.5t14 21l299 776q29 76 29 123q0 41 -35 60.5t-131 19.5h-17 q-12 4 -16 23.5t2 31.5q4 8 29 8q120 -4 239 -4t238 4q14 0 18 -6q7 -9 7 -21q0 -6 -1 -12q-4 -20 -18 -22q-88 -2 -130 -43t-93 -172l-412 -1065q-4 -10 -17 -24.5t-22 -14.5q-14 -3 -30 -3q-21 0 -43 5q-18 0 -31 33l-440 1099q-47 119 -79 144.5t-128 27.5q-18 4 -25 17z " /> -<glyph unicode="W" horiz-adv-x="2224" d="M35 1317q2 14 39 14q132 8 272 8q120 0 246 -6q16 0 13 -31.5t-13 -35.5h-19q-68 0 -85 -11.5t-17 -46.5q0 -33 39 -129l324 -813q2 -8 9 -15t17 -3t21 28l182 449q8 18 -2 47l-146 350q-39 96 -72.5 119t-148.5 27q-14 4 -16 34.5t18 30.5q83 2 300.5 2t568.5 -2 q23 0 19.5 -31.5t-15.5 -35.5q-113 -2 -150 -25.5t-76 -120.5l-102 -250q-10 -33 0 -57l236 -563q4 -8 11 -10t16 7t16 25l313 826q32 90 32 127q1 13 -3 19q-14 24 -123 28q-12 2 -14.5 18.5t5 30.5t17.5 12q63 -3 148 -3q114 0 268 5h1q17 0 21 -32q0 -33 -24 -33 q-90 0 -129 -33t-84 -152l-422 -1105q-6 -16 -66 -16q-2 0 -4 -1q-55 0 -63 12l-244 584q-2 8 -7 12t-12.5 0t-15.5 -22l-233 -574q-7 -16 -57 -16h-12q-60 2 -69 23l-417 1073q-39 102 -67 141t-62.5 50t-122.5 14q-20 0 -31 6q-14 7 -14 24q0 12 6 27zM1069 1239 q0 -12 14 -55q4 -8 78 -178q2 -4 4 -4q3 0 9 6q8 10 12 20l53 129q27 64 27 80q0 29 -56 29q-24 -3 -46 -3t-40 3q-55 0 -55 -27z" /> -<glyph unicode="X" horiz-adv-x="1607" d="M55 1274q-2 8 -2 17q1 11 5 23q8 20 32 19q137 -6 270 -6q155 0 306 8q29 0 34 -16q8 -18 -1 -35.5t-31 -17.5q-86 -2 -113 -10.5t-27 -28.5q0 -10 8.5 -25.5t17.5 -28t22.5 -30t17.5 -21.5l211 -282q16 -23 41 12q207 274 237 319q23 34 23 56q0 38 -70 39h-49 q-31 0 -38 20.5t5 32.5q8 12 35 12q112 -4 218 -4q133 0 257 6q16 -2 22.5 -19.5t0.5 -32.5t-21 -15q-123 -6 -199.5 -67.5t-170.5 -186.5l-199 -264q-6 -10 2 -29l361 -471q88 -115 116 -135q53 -39 178 -54q19 -1 19 -34q0 -29 -21 -29q-69 3 -179 3q-147 0 -367 -5 q-29 0 -35 10q-6 14 -3 34.5t15 20.5h21q109 0 108 43q-2 27 -65 113l-261 354q-6 4 -19 0t-22 -14l-286 -358q-49 -66 -49 -95q0 -43 125 -43h18q14 0 20.5 -16t2 -32.5t-18.5 -16.5q-221 4 -351 4q-86 0 -132 -2q-18 0 -18.5 35t20.5 35q88 6 139 27.5t96 80.5 q6 8 20.5 27.5t30 39t31.5 40.5l297 376q4 4 6 15.5t-2 15.5l-299 385q-96 125 -142 152.5t-167 29.5q-27 0 -31 19z" /> -<glyph unicode="Y" horiz-adv-x="1490" d="M32 1278q-1 7 -1 13q0 8 2 16q2 12 8 19q5 5 11 5h3q197 -3 335 -3t216 3q8 0 17.5 -16.5t4.5 -31.5t-28 -15q-127 0 -127 -41q0 -29 64 -127l274 -422q8 -10 26.5 -1t28.5 28l219 370q66 109 66 137q0 31 -23.5 42.5t-93.5 11.5h-20q-18 8 -16 38q1 27 19 27h3 q89 -3 203.5 -3t253.5 3q18 0 18 -31q0 -35 -18 -34q-104 -6 -170 -74q-31 -33 -107 -160l-303 -514v-107.5v-128v-79.5q0 -59 25.5 -92t89.5 -41q8 0 32.5 1t34.5 -3q25 -6 25 -41t-25 -35q-244 4 -401 4q-105 0 -172 -2q-16 0 -22.5 21.5t-0.5 37.5q8 20 43 21q10 2 31 0 t25 -2q109 6 114 131q6 86 6 166q0 64 -4 125l-374 585q-72 113 -120 147t-143 38q-25 0 -29 14z" /> -<glyph unicode="Z" horiz-adv-x="1443" d="M74 31q0 14 10 30l877 1143q10 14 -4.5 21.5t-26.5 7.5h-438q-156 0 -197 -34t-59 -185q0 -6 -12.5 -8t-27 3t-18.5 15q0 201 10 287q4 14 45 20h975q33 0 46.5 -15.5t-3.5 -47.5l-868 -1123q-8 -8 -11 -17t10 -19.5t50 -10.5h520q156 0 212.5 58.5t72.5 218.5l2 20 q4 6 20.5 10.5t30 2t13.5 -8.5q-8 -211 -27 -379q-4 -24 -58 -24h-4q-63 0 -293.5 -1t-357.5 -1q-438 0 -448 2q-10 0 -19.5 2t-16.5 11q-5 7 -5 16v6z" /> -<glyph unicode="[" horiz-adv-x="690" d="M213 -428q-12 895 0 1788q0 29 9 40t36 13q63 6 262 0q37 0 37 -14v-31q0 -16 -16 -16q-123 -10 -140 -19q-25 -14 -24 -61q-8 -834 0 -1604q0 -41 16.5 -52t91.5 -17l50 -5q14 -2 18 -5t4 -17v-23q0 -18 -39 -18q-86 -6 -258 0q-47 4 -47 41z" /> -<glyph unicode="\" horiz-adv-x="980" d="M82 1350q-16 31 59 30h43h12.5h10.5t7 -1t7 -2t5 -5t6.5 -9t7.5 -13l653 -1332q20 -43 -16 -47l-86 -10q-27 -4 -41 27q-2 4 -5 6z" /> -<glyph unicode="]" horiz-adv-x="702" d="M66 -428q0 16 10 22.5t35 4.5h26q74 6 91.5 17t17.5 54q8 772 0 1606q0 47 -25 59q-12 6 -84 13l-55 4q-16 0 -16 16v31q0 14 24 14h12h263q27 -2 36 -12t9 -41q14 -1022 0 -1788q0 -37 -48 -41q-172 -6 -258 0q-39 0 -38 18v23z" /> -<glyph unicode="^" horiz-adv-x="1005" d="M46 710.5q1 10.5 11 26.5q227 408 428 719h45q256 -418 428 -727q23 -37 -20 -41l-41 -4q-35 -4 -55 35q-152 270 -314 528q-23 37 -41 6q-113 -174 -321 -542q-14 -27 -53 -27q-4 0 -21.5 1t-24 3t-14.5 7t-7 15.5z" /> -<glyph unicode="_" horiz-adv-x="1071" d="M-20 -383q0 8 6 12t21.5 5t30.5 0t40.5 -2t46.5 -1h805q4 0 34.5 1t53 1h39.5q41 0 41 -24v-60q0 -20 -21 -24h-43h-977q-78 0 -77 37v55z" /> -<glyph unicode="`" horiz-adv-x="712" d="M143 1307q-10 10 0.5 24.5t28.5 14.5l158 2q29 0 39 -17q59 -156 100 -334q2 -18 -18.5 -22t-32.5 8q-109 141 -275 324z" /> -<glyph unicode="a" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q20 -4 20 -24q0 -11 -6 -27q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM241.5 106.5q32.5 -32.5 80.5 -32.5q33 0 91 37.5t70 70.5v170 v8.5t-2 10.5t-6 6t-10 -2q-47 -23 -146 -64q-110 -45 -110 -124q0 -48 32.5 -80.5z" /> -<glyph unicode="b" horiz-adv-x="1005" d="M16 1371.5q0 23.5 15 27.5l250 84q12 4 20.5 4t12.5 -4q8 -8 5 -35q-3 -110 -3 -281t3 -403q2 -16 6.5 -22.5t14.5 -0.5q4 4 23.5 17.5t27.5 19.5t27.5 19.5t31 19.5t30 16.5t32.5 16.5t30.5 11t32 8t29.5 3q137 0 232.5 -120.5t95.5 -288.5q0 -213 -130 -353.5 t-335 -140.5q-104 0 -281 39q-16 6 -20 37q3 254 3 546.5t-3 622.5q0 20 -1 45t-1 29q-2 33 -45 39q-14 2 -44 7t-44.5 9.5t-14.5 28zM317 444q0 -180 17 -247q16 -63 65.5 -102.5t120.5 -39.5q115 0 186.5 96.5t71.5 252t-71.5 254t-180.5 98.5q-66 0 -207 -103 q0 -4 -1 -78.5t-1 -130.5z" /> -<glyph unicode="c" horiz-adv-x="864" d="M51 395q0 205 144.5 347.5t351.5 142.5q100 0 172 -37t72 -94q0 -33 -21.5 -54.5t-52.5 -21.5q-53 0 -127 72q-57 57 -117 57q-102 0 -180 -108.5t-78 -256.5q0 -158 80 -257t203 -99q147 0 241 137q10 31 35 25q6 -2 8 -4t4.5 -6.5t4.5 -8.5q7 -5 7 -14q0 -10 -10 -25 q-137 -215 -362 -215q-162 0 -268.5 119t-106.5 301z" /> -<glyph unicode="d" horiz-adv-x="1050" d="M47 391q0 205 132 344t329 139q72 0 170 -32q8 -2 15 7t7 30q3 70 3 176.5t-3 249.5q-10 29 -16 32q-12 8 -30.5 10.5t-44 3.5t-36.5 3q-20 4 -22 14q-4 20 -2 29q4 16 20 18q143 45 258 88q8 3 13 3q8 0 14 -6q8 -11 8 -34v-1226q0 -82 10.5 -99.5t45.5 -17.5q8 0 45 12 q2 0 11 3t14 4t12.5 1t12.5 -4t7 -12q5 -16 5 -26q0 -16 -11 -21q-137 -68 -277 -103q-14 -6 -23 0.5t-12.5 19.5t-3.5 25.5t2 26.5v17q0 14 -6 25t-16 5q-184 -127 -289 -127q-143 0 -242.5 124t-99.5 298zM211 455q0 -158 72.5 -263.5t181.5 -105.5q88 0 213 84 q16 8 20 47v420q-109 156 -235 156q-113 0 -182.5 -93.5t-69.5 -244.5z" /> -<glyph unicode="e" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q211 0 295 -181l16 -34q20 -39 41 -66q3 -9 3 -21q0 -5 -1 -11q-2 -18 -28 -19q-79 -3 -216 -3t-333 3q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t219 -103.5q143 0 254 131q10 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142 q-115 -88 -242 -88q-162 0 -270.5 129t-108.5 316zM225 627q-1 -5 11 -9q14 -6 22 -6h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-199 0 -199 -188z" /> -<glyph unicode="f" horiz-adv-x="657" d="M35 756.5q0 27.5 10 34.5q94 20 154 55q0 8 4 110q6 125 35.5 204t109.5 165q150 164 322 164q57 0 125.5 -24.5t97.5 -67.5q6 -9 6 -23q0 -20 -41 -86q-14 -20 -29.5 -22t-24.5 3t-30 21q-98 80 -196 80q-63 0 -115.5 -37t-73.5 -98q-29 -79 -29 -189v-14l2 -141 q0 -41 31 -41h152q25 0 28 -19l15 -92q-4 -16 -25 -16l-174 2q-10 0 -18.5 -9t-8.5 -18v-436q0 -143 20 -168q18 -24 107 -24h15h69q23 -2 27 -43q0 -33 -18 -33q-156 5 -285 5t-231 -5q-16 0 -17 33q0 16 4 22q6 14 37 14q72 0 90.5 38t18.5 169v426q-6 29 -25 33h-129 q-10 0 -10 27.5z" /> -<glyph unicode="g" horiz-adv-x="989" d="M55 -287q0 70 31 115t94 86q8 6 16.5 11t17.5 10.5t15 9.5q10 8 14.5 19t-3.5 16q-143 51 -144 151q0 41 86 88q43 25 78 45q23 10 10 19q-161 81 -161 252q0 147 99 245.5t245 98.5q137 0 217 -86h16q41 0 186 22q23 4 30 -1t9 -28q7 -60 7 -92v-8q-4 -27 -21 -27 q-27 0 -127 15q-4 2 -13 -5t-7 -12q18 -45 18 -102q0 -137 -98.5 -224t-247.5 -87q-41 0 -84 12q-4 -6 -57 -53q-39 -33 -39 -53q0 -14 8 -24.5t68.5 -22t177.5 -11.5q229 -4 323 -47q105 -47 105 -188q0 -156 -159 -262.5t-380 -106.5q-115 0 -222.5 63.5t-107.5 161.5z M205 -231q-2 -78 87 -127.5t206 -49.5q102 0 203.5 66.5t101.5 142.5q0 72 -50.5 106t-177.5 44q-49 4 -123.5 4t-113.5 2q-4 -8 -27 -31q-106 -106 -106 -157zM260 582q0 -123 52.5 -195t131.5 -72q78 0 125 61t47 167q0 117 -54 192.5t-134 75.5q-72 0 -120 -65.5 t-48 -163.5z" /> -<glyph unicode="h" horiz-adv-x="1077" d="M41 57q2 2 43 11q70 4 88 38.5t18 163.5v936l-2 78q0 45 -51 53q-14 2 -41.5 5.5t-42.5 5.5q-12 2 -14 26.5t14 30.5q92 37 262 86q6 2 11 2q10 0 16 -6q10 -10 10 -41v-631q0 -14 7.5 -29.5t17.5 -9.5q82 51 143.5 74.5t143.5 23.5q172 0 217 -145q23 -68 26 -227 q0 -49 -4 -139.5t-4 -96.5q-4 -90 -4 -135q0 -39 23.5 -50t105.5 -11q20 0 24.5 -8t6.5 -33q1 -6 1 -11q0 -22 -14 -22q-75 -1 -163 -1h-91q-141 1 -182 1q-33 0 -33 35q-4 33 17 32h12q72 0 96.5 19.5t30.5 77.5q14 123 14 280q0 135 -11 188.5t-42 88.5q-49 53 -127 53 q-39 0 -78 -13.5t-56 -22.5t-67 -40q-10 -6 -10 -22v-490q0 -78 21.5 -98.5t89.5 -20.5q29 0 31 -16q0 -18 2 -27q0 -12 -8 -20q-6 -6 -13 -6h-4q-26 1 -77.5 1t-128 -1t-129.5 -1t-83 1h-2q-7 0 -12 10t-5 24q0 19 7 29z" /> -<glyph unicode="i" horiz-adv-x="544" d="M41 27q-1 6 -1 11q0 24 17 25l27 3q88 6 104.5 32.5t16.5 157.5v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5q217 80 248 86q11 4 20 4q33 0 34 -53v-590q0 -78 2 -106q2 -55 19 -67.5t83 -12.5q10 4 22.5 -4.5t14.5 -18.5q0 -2 -1 -9t-1 -11 q0 -33 -29 -33q-138 3 -242 3t-174 -3q-14 0 -18 33zM147 1255q0 45 32 76t79 31q49 0 82 -30t33 -77q0 -45 -35 -74.5t-82 -29.5q-49 0 -79 29.5t-30 74.5z" /> -<glyph unicode="j" horiz-adv-x="505" d="M-219 -381q0 43 21.5 76t52.5 33q33 0 84 -62q56 -65 118 -65h2q68 0 99.5 57t31.5 188v127v658q0 66 -3 81t-17 23q-18 10 -57 17q-12 4 -35 8t-29 6q-8 4 -8 25.5t8 25.5q115 49 254 94q23 8 34 -6t11 -35v-819q0 -135 -7 -197.5t-34 -125.5q-31 -72 -84 -129 q-90 -98 -241 -99q-88 0 -144.5 34t-56.5 85zM127 1235q0 45 33 74.5t80 29.5q49 0 79.5 -29.5t30.5 -74.5t-31.5 -76t-78.5 -31q-49 0 -81 31t-32 76z" /> -<glyph unicode="k" horiz-adv-x="1060" d="M31 1367q0 24 12 28q59 14 131 43.5t109 40.5q9 2 16 2q29 0 29 -37l2 -873q0 -31 41 -6l217 158q53 39 53 49q0 25 -92 25q-25 12 -23 37q2 16 7.5 22t21.5 6q54 -1 114 -1q121 0 267 3q20 0 20 -33q0 -35 -12 -34q-133 -2 -252 -95q-143 -106 -217 -157q-14 -14 8 -37 q246 -254 371 -379q41 -41 66.5 -55.5t74.5 -14.5h21q10 -4 13 -20q1 -7 1 -13q0 -10 -2 -18q-4 -14 -12 -14q-92 5 -203 5t-242 -5q-16 0 -16 35q0 20 5 25t26 5q71 0 71 28q0 13 -47 65l-264 280q-12 8 -14 -12q-2 -8 -2 -21v-145q0 -143 14 -168t96 -25h25q16 0 16 -34 q0 -15 -4 -25q-3 -9 -10 -8h-2q-110 2 -214.5 2t-203.5 -2q-14 0 -14 33q-2 23 3 29.5t27 6.5q74 0 89.5 32t15.5 175v904q0 70 -2 108q-2 31 -70 45q-6 2 -11 3l-10 2t-10.5 2t-8.5 2l-6 2t-5 1h-2q-12 4 -12 28z" /> -<glyph unicode="l" horiz-adv-x="536" d="M37 12q-4 13 -4 23q0 20 16 28h23q80 0 102.5 26t22.5 110v1077q0 31 -33 37q-18 4 -52 10t-51 8q-12 4 -14 27.5t14 30.5q137 35 271 86h3q10 1 17 -13q8 -16 8 -30v-1231q0 -92 16.5 -115t90.5 -23q37 0 39 -12v-7v-10v-7q0 -33 -25 -33q-56 -2 -115 -2q-60 0 -120 2 q-81 3 -136 3q-28 0 -49 -1q-4 0 -13 5t-11 11z" /> -<glyph unicode="m" horiz-adv-x="1662" d="M35 8q-3 8 -3 16q0 12 5 25q6 14 45 14q68 4 88 40t20 167v293q0 145 -6 154q-10 23 -84 33l-47 6q-12 2 -10 26.5t10 28.5q88 41 269 88q5 1 9 1q10 0 15 -7q6 -10 6 -31v-121q2 -20 27 -2q199 139 321 140q70 0 122 -40t75 -110q4 -14 23 0q72 51 105.5 72.5t100 49.5 t121.5 28q135 0 189 -123q30 -70 30 -274v-13q0 -55 -4 -161.5t-4 -162.5q0 -49 24.5 -63t112.5 -14q6 2 19.5 1t19.5 -6q9 -4 9 -23q0 -6 -1 -15q0 -13 -6 -23q-5 -9 -11 -8h-3q-58 2 -171.5 2t-283.5 -2q-20 0 -26 12q-6 10 -4 31.5t18 21.5h21q66 0 88 20.5t28 86.5 q10 139 11 287q0 190 -31 255.5t-115 65.5q-76 0 -250 -119v-473q0 -76 22.5 -99.5t90.5 -23.5q16 0 21.5 -6t7.5 -24q0 -12 -6.5 -23.5t-14.5 -11.5q-154 4 -276 4q-82 0 -150 -2q-18 0 -20 27.5t16 35.5q4 2 27 2q80 0 101.5 35t21.5 174v334q0 80 -37 125t-101 45 q-82 0 -258 -119v-473q0 -78 22.5 -100.5t100.5 -22.5q14 4 19 0q14 -4 14 -36q-2 -11 -8 -21q-5 -9 -11 -8h-2q-100 4 -208.5 4t-225.5 -4q-14 0 -18 14z" /> -<glyph unicode="n" horiz-adv-x="1056" d="M33 40q4 20 18 19h12q72 0 94.5 39t22.5 174v281q0 150 -8 166q-8 18 -80 33l-41 8q-10 2 -10 26.5t10 28.5q33 6 119 43t123 45q10 2 17 2q30 0 30 -37v-112q0 -6 7 -18.5t15 -6.5q96 68 170 105q86 41 144 41q227 0 227 -369q0 -61 -8 -184t-8 -187q0 -47 16.5 -60.5 t85.5 -13.5q18 12 33 -6q6 -11 6 -25q0 -8 -2 -18q-2 -12 -6 -15t-19 -3h-6q-43 0 -193 1h-89q-77 0 -107 -1q-20 0 -25.5 6t-7.5 27q0 35 17 34h14q68 6 93.5 29t31.5 86q12 119 12 361q0 227 -149 227q-96 0 -252 -121v-463q0 -78 22.5 -98.5t102.5 -20.5q14 0 18 -34 q0 -33 -28 -35q-24 1 -72.5 1t-122.5 -1q-49 -1 -87 -1q-77 0 -110 3q-25 0 -28 10q-4 8 -4 19q0 7 2 15z" /> -<glyph unicode="o" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132q133 -130 133 -321v-6q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228z" /> -<glyph unicode="p" horiz-adv-x="1030" d="M13 -522q3 22 20 22h18q86 0 108.5 40t22.5 190v848v49q0 39 -9 49t-44 20q-12 4 -35.5 12.5t-36 10.5t-13.5 19.5t5 23.5q2 4 12 14l226 142q22 14 35 14q20 0 20 -31v-127q0 -41 16 -39q2 0 4 2q184 131 291 131q129 0 224.5 -122.5t95.5 -284.5q0 -195 -135.5 -339.5 t-317.5 -144.5q-61 0 -153 29q-12 4 -18.5 -1t-6.5 -32v-243q0 -147 23.5 -185.5t109.5 -38.5h29q31 0 37 -16q8 -29 -2 -47q-6 -12 -27 -12q-46 2 -121 2q-57 0 -131 -1q-103 -2 -158 -2q-36 0 -51 1q-27 0 -33 10t-6 25q0 5 1 12zM342 174q117 -111 236 -111 q102 0 168.5 90.5t66.5 227.5q0 156 -75.5 260t-186.5 104q-86 0 -197 -88q-12 -12 -12 -36v-447z" /> -<glyph unicode="q" horiz-adv-x="1032" d="M63 399q0 199 129.5 336t317.5 137q117 0 233 -59q23 -12 31 4q29 33 55 53q10 6 27 8h3q14 0 22 -10q-14 -55 -15 -153v-90v-891q0 -143 21.5 -188.5t89.5 -45.5h20q14 0 17 -20q2 -7 2 -12q0 -13 -6 -23q-4 -10 -11 -12h-18q-115 4 -229.5 4t-227.5 -4q-39 0 -39 30 q0 33 17 41q14 2 80 2q84 0 106.5 39t22.5 189v327h2q0 2 -1 7.5t-3 14.5t-6.5 13t-8.5 0q-147 -123 -286 -123q-150 0 -247.5 122t-97.5 304zM221 455q0 -160 80 -266.5t197 -106.5q92 0 200 92q9 8 15 37l-2 235q-2 166 -19 218q-23 61 -79 101t-126 40 q-123 0 -194.5 -93.5t-71.5 -256.5z" /> -<glyph unicode="r" horiz-adv-x="716" d="M41 29v17t3 9t8 6h16q74 0 97 38t23 171v394q-6 27 -20 30l-86 33q-31 12 -35 25v6v16q0 18 16 23q25 12 121 45q74 25 123 49q9 4 16 4t11 -3q10 -7 10 -26v-73t2 -70q0 -8 3 -12t5 -3t4 1q61 133 93 149q26 14 60 14q54 0 130 -34q6 -2 18.5 -6t16.5 -5q19 -3 19 -17 q0 -3 -1 -7q-16 -49 -59 -129q-27 2 -76 26q-45 23 -74 23q-68 0 -137 -131q0 -356 2 -410q2 -78 23.5 -98.5t99.5 -20.5h45q14 0 20.5 -27.5t-8.5 -39.5q-2 -2 -28 -2q-164 3 -273 3t-163 -3h-5q-11 0 -15 7q-4 9 -5 28z" /> -<glyph unicode="s" horiz-adv-x="643" d="M70 641q0 111 77.5 180.5t198.5 69.5q78 0 172 -39q6 -82 6 -143q0 -37 -2 -66q0 -10 -28 -10q-12 0 -20.5 3t-6.5 7q-14 82 -55 127t-99 45q-49 0 -80.5 -30.5t-31.5 -77.5q0 -72 123 -162q20 -14 62 -42t72.5 -51.5t55.5 -50.5q70 -76 70 -170q0 -106 -79 -178.5 t-190 -72.5q-53 0 -102 14q-2 0 -17.5 6t-23.5 8q-16 0 -27 -26q-24 -7 -31 -7h-1q-18 2 -21 21q-18 144 -18 219v14q-2 12 10 15.5t31 1.5q10 -4 14 -21q43 -184 180 -184q55 0 94 39t39 92q0 20 -5 39.5t-19.5 39t-23.5 32t-33.5 31t-33 25.5t-37 26.5t-32.5 21.5 q-57 39 -92 67.5t-65.5 79t-30.5 107.5z" /> -<glyph unicode="t" horiz-adv-x="653" d="M43 799q4 8 16 14q117 59 189 260q0 7 13 13q8 3 16 4q5 0 9 -2q12 -4 13 -15q-3 -60 -3 -105.5t3 -74.5q2 -8 10 -17.5t15 -9.5h227q35 0 24 -32q-4 -33 -18 -68q-10 -16 -33 -16l-194 4q-8 0 -18.5 -8.5t-12.5 -16.5v-362q0 -158 28.5 -214.5t102.5 -56.5q66 0 123 109 q2 10 20.5 9t26.5 -11q6 -7 6 -18q0 -9 -4 -21q-84 -186 -240 -187q-96 0 -157.5 72t-61.5 184v84v410q0 18 -12 23h-41q-16 0 -41 6q-9 15 -9 28q0 8 3 15z" /> -<glyph unicode="u" horiz-adv-x="1093" d="M40 820v6q0 16 13 20q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 57 -62 65q-14 4 -26.5 5t-18.5 4q-2 0 -67 10q-12 8 -10.5 28.5t14.5 24.5q209 47 293 55h8 q33 0 33 -32v-652v-63q0 -51 49 -51q17 0 39 6q4 2 13 4t16 4l14 4q12 3 17 -13q3 -9 3 -18q0 -8 -2 -16q-4 -18 -16 -19q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v434q0 35 -8 51.5 t-37 24.5q-14 4 -40.5 11.5t-41.5 11.5q-10 3 -13 25z" /> -<glyph unicode="v" horiz-adv-x="1019" d="M8 826q2 30 20 32q7 1 39 1q46 0 144 -2q70 -1 126 -1q74 0 122 2q12 0 12 -33q0 -31 -16 -30h-19q-47 0 -72.5 -7.5t-29.5 -14.5t-4 -19q0 -14 43 -121t104.5 -250t61.5 -145q2 -2 6 -10.5t7 -11.5t7 -6t8 1t8 14q133 324 197 459q9 19 9 35q1 31 -35 48q-54 26 -119 28 q-8 6 -8.5 34.5t16.5 28.5q83 -2 174 -2t190 2q9 0 13 -16q2 -8 2 -16q0 -7 -1 -14q-3 -15 -9 -15q-66 -8 -96.5 -46t-88.5 -169l-250 -578q-12 -23 -28 -24q-12 -3 -24 -3q-16 0 -32 5q-10 4 -20 30l-266 613q-45 106 -62 127q-27 29 -117 43q-12 2 -12 25v6z" /> -<glyph unicode="w" horiz-adv-x="1542" d="M4 814q-1 7 -1 12q0 11 3 16q4 14 29 10q20 0 76.5 -2t128 -2t166.5 4h10q20 2 24 -16q6 -12 3 -27.5t-15 -15.5q-104 -4 -104 -48q0 -25 88 -247q45 -115 110 -271q4 -10 13.5 -18t17.5 2l184 432v-2q-45 90 -65 111q-33 33 -90 36q-6 0 -18.5 1.5t-20.5 1.5 q-14 0 -15 30q-4 33 11 33q198 -5 305 -5q80 0 110 3q33 4 39 -14q4 -12 2 -27.5t-6 -19.5q-108 -2 -108 -53q0 -28 30 -101l172 -416q6 -10 16.5 -2t14.5 19q166 387 178 454q3 15 3 28q-1 30 -17 44q-24 20 -74 24q-39 0 -59 3q-10 4 -12.5 33.5t16.5 29.5q75 -2 164 -2 t192 2h3q12 0 16 -14q4 -10 4 -20q0 -6 -1 -11q-3 -16 -11 -18q-82 -8 -105 -41q-10 -16 -43 -95q-45 -111 -262 -651q-6 -16 -10 -20t-25 -7q-25 -5 -34 -5q-3 0 -5 1q-14 2 -20 17l-4 10l-222 535q-6 12 -20 -15l-219 -516q-6 -25 -27 -27q-4 -2 -12 -2h-23q-14 0 -18 2 q-12 2 -18 15l-5 10l-249 616q-45 115 -73 141.5t-106 31.5q-10 3 -12 23z" /> -<glyph unicode="x" horiz-adv-x="1069" d="M14 25q0 31 17 30q74 2 114.5 28t124.5 122l183 207l-170 227q-74 100 -114 126t-126 30q-12 5 -11 33q1 27 18 26h3q54 -3 153.5 -3t244.5 3q20 0 22 -4q6 -8 7 -20.5t-2 -22.5t-7 -10h-18q-70 0 -70 -24.5t74 -121.5q55 -74 80 -98q12 -16 20 -17t25 17q45 45 80 90 q55 66 55 105q0 23 -18.5 34t-71.5 13h-8.5h-6.5t-5 3t-5 7q-6 16 -2 37q2 13 17 13q4 0 8 -1q154 -2 251 -2t138 2h4q13 0 20 -10q8 -20 2 -37q-4 -12 -30 -12q-90 -6 -131 -28t-107 -95l-78 -86l-96 -111q117 -150 165 -212t83 -105q43 -55 81 -76t103 -25q17 -10 17 -37 q0 -10 -5.5 -18t-13.5 -6q-92 2 -177 2q-129 0 -245 -4q-18 0 -18 29.5t18 29.5h19q71 0 71 32q0 11 -9 26.5t-24.5 34t-19.5 22.5l-117 156q-31 39 -47 20q-4 -6 -30.5 -33.5t-49 -53.5t-48 -56.5t-41 -54t-15.5 -33.5q0 -27 23.5 -40.5t87.5 -19.5h16q10 0 14 -16.5 t0 -30.5q-4 -12 -12 -12h-2q-103 4 -223 4q-80 0 -168 -2q-12 0 -17 29z" /> -<glyph unicode="y" horiz-adv-x="999" d="M18 840q6 23 41 18h35q78 0 314 4q35 0 38 -16q4 -14 0 -30.5t-12 -18.5q-66 -2 -86 -14.5t-20 -37.5q0 -23 22 -71q43 -94 189 -459q6 -14 28 21q4 4 4 6l123 313q20 51 31 84q18 55 18 84q0 41 -24.5 56.5t-100.5 17.5q-10 6 -11 31.5t18 27.5h16q98 6 178 6 q64 0 117 -4q35 0 39 -18q1 -4 1 -8q0 -9 -3 -20q-4 -15 -10 -15q-63 -8 -101.5 -56.5t-99.5 -210.5l-254 -684q-72 -184 -86 -219q-31 -74 -74 -125q-33 -43 -94 -43q-39 0 -67.5 28t-28.5 64q0 63 102 89q63 16 105.5 72.5t78.5 176.5l29 95l-260 618q-55 133 -82 161 t-100 34q-6 2 -11 16q-3 10 -3 19q0 4 1 8z" /> -<glyph unicode="z" horiz-adv-x="839" d="M31 35q2 6 8 13t8 11l498 678q4 12 -15 19q-17 1 -39 1q-44 0 -109 -3q-97 -4 -138 -4q-43 0 -65.5 -33t-53.5 -158q-4 -10 -20.5 -12t-26.5 4q-16 6 -12 29q51 281 61 325q4 6 30.5 6t26.5 -8q0 -35 14 -45q12 -8 56 -8h18q267 4 396 4h71q35 0 43 -8q8 -33 -4 -47 q-287 -375 -502 -688q-2 -6 7.5 -11.5t17.5 -3.5q68 -6 145 -6t164 6q51 2 75 28t60 112l9 10q8 20 41 12q15 -3 15 -12q0 -2 -1 -4l-84 -230q-6 -12 -23 -16q-167 -4 -331.5 -4t-327.5 4q-13 0 -13 25q0 6 1 14z" /> -<glyph unicode="{" horiz-adv-x="1026" d="M215 459q-6 14 0 26q0 14 14 19q102 20 161 77.5t59 131.5q0 49 -25 153q-23 90 -23 170q0 158 112 276t286 144q12 0 14 -10q8 -29 4 -33q0 -2 -2 -2q-2 -2 -2 -4q-4 -10 -18 -14q-109 -25 -165.5 -86.5t-56.5 -151.5q0 -59 19 -151q23 -117 22 -181q0 -141 -112 -248 q-63 -59 -127 -88q-33 -12 -2 -28q242 -121 241 -338q0 -82 -20 -176q-18 -90 -19 -152q0 -180 226 -244q10 0 16 -10l2 -2q8 -21 0 -39q-6 -10 -20 -8q-176 27 -286 143.5t-110 274.5q0 63 23 164q25 109 25 155q0 78 -58.5 134.5t-167.5 78.5q-10 4 -10 19z" /> -<glyph unicode="|" horiz-adv-x="1093" d="M483 10v1700q0 29 10.5 40t36.5 11q37 -8 60 -4q12 0 18 -1t8 -6t2 -9t-1 -15.5t-1 -19.5v-842q0 -793 -2 -864q0 -45 -45 -45q-23 4 -51 0q-23 0 -29 13.5t-6 41.5z" /> -<glyph unicode="}" horiz-adv-x="1026" d="M217 -485q0 2 1 10t1 12q4 14 14 17q109 23 167.5 85t58.5 150q0 57 -21.5 165.5t-21.5 166.5q0 139 114 250q59 59 127 88q12 6 11.5 15t-13.5 15q-240 121 -239 334q0 53 20.5 163t20.5 165q0 180 -215 242q-8 2 -17.5 12t-7.5 22q0 31 16 29q176 -27 287 -143.5 t111 -274.5q0 -55 -24.5 -159.5t-24.5 -159.5q0 -74 53 -129t153 -80q29 -8 29 -33q0 -35 -24 -39q-98 -23 -153.5 -78t-55.5 -127q0 -55 24.5 -161.5t24.5 -161.5q0 -154 -105.5 -269.5t-271.5 -146.5q-14 -4 -27.5 2t-11.5 19z" /> -<glyph unicode="~" horiz-adv-x="1161" d="M49 518q6 143 90 237.5t205 94.5q106 0 279 -94q2 0 24.5 -13.5t26.5 -15.5t25.5 -13.5t29.5 -14.5t26.5 -11t30 -11t26.5 -8t29.5 -6t28.5 -1q145 0 177 169q4 27 24 27l23 -2q12 -2 20 -9t6 -13q-10 -147 -91 -243.5t-198 -96.5q-115 0 -294 96q-6 4 -52.5 28.5t-69 35 t-59.5 22.5t-65 12q-68 0 -116 -48t-58 -130q-4 -27 -31 -23q-10 2 -17.5 4.5t-13.5 9.5t-6 17z" /> -<glyph unicode="¡" horiz-adv-x="557" d="M162 776q0 47 33.5 80t85 33t85 -32t33.5 -81q0 -51 -33.5 -84t-85 -33t-85 33t-33.5 84zM176 -426l76 948q4 10 27.5 10t27.5 -10l82 -950q4 -47 -8 -64.5t-64 -17.5h-65q-53 0 -66.5 17.5t-9.5 66.5z" /> -<glyph unicode="¢" horiz-adv-x="915" d="M98 389q0 207 145.5 352.5t352.5 145.5q10 0 59 -4l101 262q8 14 26 12q2 0 10.5 -1t11.5 -1t8 -2t7 -5t2 -8t-2 -14l-100 -256q127 -38 127 -118q0 -33 -22.5 -54.5t-57.5 -21.5q-37 0 -76 33q-25 25 -35 -2l-227 -570q-12 -35 34 -48t87 -13q76 0 130 34.5t114 106.5 q12 16 26 8l21 -12q16 -10 -4 -41q-143 -209 -363 -209q-41 0 -86 10q-23 6 -33 -20q-94 -256 -116 -299q-12 -27 -33 -25l-31 6q-12 2 -6 19l4 8l123 309q10 31 -10 43q-84 55 -135.5 156.5t-51.5 218.5zM262 436q0 -162 90 -268q12 -16 25 10l237 600q-37 29 -88 29 q-106 0 -185 -108.5t-79 -262.5z" /> -<glyph unicode="£" horiz-adv-x="1630" d="M31 -416q0 57 76.5 129t175.5 113q61 109 110 240l13 32q4 8 -2.5 18.5t-18.5 10.5h-238q-29 0 -30 2q-12 4 -6 25q0 4 2 10q2 12 3 17t5 11.5t12 8.5t21 2h290q18 49 70.5 193.5t83.5 221.5q94 244 186 400q242 414 541 414q104 0 184 -48t80 -118q0 -33 -23.5 -55.5 t-58.5 -22.5q-43 0 -90 47q-14 12 -26 27q-72 72 -148 71q-94 0 -168 -100q-80 -104 -168 -328q-195 -481 -278 -663q-16 -37 10 -39h8l271 2h26q25 0 19 -27l-7 -26q-4 -29 -47 -29l-338 4q-76 -154 -153 -254q88 41 200 41q92 0 168 -35t162 -98q80 -61 135 -92 q74 -43 142 -43q74 0 126 43t52 104q0 33 -33 90q-27 45 -27 72q0 37 25 61.5t59 24.5q47 0 78 -44t31 -110q0 -143 -126 -255.5t-284 -112.5q-119 0 -217 63q-31 20 -92 70q-6 6 -42 34.5t-54 43.5q-121 90 -207 90q-63 0 -156 -43l-6 -4q-55 -113 -124.5 -182.5 t-127.5 -69.5q-29 0 -49 18.5t-20 44.5z" /> -<glyph unicode="¤" horiz-adv-x="1429" d="M207 272l133 134q-57 88 -75.5 145t-18.5 149q0 90 18.5 146.5t75.5 134.5l-133 133l92 96l135 -135q74 59 131.5 79t151.5 20q96 0 152.5 -19.5t136.5 -79.5l129 135l94 -96l-131 -133q57 -82 76.5 -140.5t19.5 -152.5q0 -96 -19.5 -152.5t-76.5 -129.5l131 -134 l-94 -94l-129 133q-82 -59 -138.5 -78.5t-153 -19.5t-151.5 19.5t-129 78.5l-135 -133zM379 694.5q0 -143.5 98 -245t238 -101.5q143 0 243.5 100.5t100.5 244t-99.5 244.5t-238.5 101q-141 0 -241.5 -100t-100.5 -243.5z" /> -<glyph unicode="¥" horiz-adv-x="1071" d="M-6 1409q0 4 2 8v6q-2 18 18 19q238 -8 445 2q23 0 22 -29q6 -16 0 -24q0 -18 -10 -21h-6q-113 -8 -113 -53q0 -10 19 -55l53 -132q8 -20 53 -20h232q29 0 39 25l45 110q20 53 20 74q0 43 -76 49q-43 8 -43 27v22q0 18 17 19h8q193 -8 342 2q20 2 20 -25v-24v-9v-2 q-2 -2 -2 -4q-4 -4 -16 -4q-57 0 -90 -29.5t-74 -123.5l-37 -87q-4 -8 7.5 -14t25.5 -6h154q31 0 30 -29v-41q0 -33 -30 -32h-211q-27 0 -35 -21l-64 -139q-6 -12 5.5 -21.5t27.5 -9.5l281 4q27 -8 26 -26v-52q0 -29 -41 -28l-303 2q-29 0 -41 -2q-14 0 -20 -13l-37 -84 v-360q0 -127 23.5 -161t101.5 -34h22q31 0 31 -26v-25q0 -16 -5 -19t-28 -1q-258 14 -499 0q-12 0 -20.5 6t-6.5 14l2 27q2 23 27 22h18q90 0 112.5 32t22.5 165v338l-45 100q-8 20 -28 21h-15h-315q-37 0 -37 33v49q0 23 41 22l252 -4q20 0 32.5 6t6.5 25l-56 131 q-12 29 -32 29h-213q-31 0 -31 28v47q0 18 5 22.5t20 4.5h157q10 0 21.5 8t7.5 17l-39 92q-33 82 -65.5 110.5t-90.5 32.5q-14 0 -16 21q-4 4 -4 18zM485 985l84 -205q4 -12 13.5 -12t17.5 16l80 199q8 25 -12 25h-166q-27 0 -17 -23z" /> -<glyph unicode="¦" horiz-adv-x="1093" d="M483 -45v778h133v-778h-133zM483 981v780h133v-780h-133z" /> -<glyph unicode="§" horiz-adv-x="1005" d="M109 881q0 225 145 388t344 163q45 0 107.5 -15.5t119 -52.5t56.5 -84q0 -35 -28 -62.5t-62 -27.5q-41 0 -91 49q-4 4 -9 8t-10 10.5t-7 8.5q-74 78 -139 77q-76 0 -129.5 -48t-53.5 -115q0 -18 7.5 -44t22.5 -55.5t29.5 -55.5t38 -60.5t37 -54t37 -51.5t27.5 -38 q170 -242 234.5 -355.5t95.5 -225.5q22 -88 22 -201q0 -211 -147.5 -367.5t-345.5 -156.5q-104 0 -188.5 43t-84.5 104q0 33 24.5 61.5t57.5 28.5q12 0 22.5 -4t18.5 -8t18.5 -13.5t14.5 -14.5t15 -17t14 -17q74 -80 157 -79q70 0 126.5 48t56.5 107q0 88 -119 252 q-207 287 -314 475q-121 213 -120 400zM246 1090q-88 -231 51 -508q57 -111 189 -305.5t184 -286.5q53 -96 67 -137q6 -16 17 -11q12 6 18 23q25 63 25 153q0 172 -74 330q-39 76 -82 144q-47 70 -98 147q-76 111 -146 219q-96 147 -123 232q-10 25 -16 22q-6 -4 -12 -22z " /> -<glyph unicode="¨" horiz-adv-x="712" d="M53 1108q0 51 36 87t87 36t87 -36t36 -87t-36 -87t-87 -36t-87 36t-36 87zM416 1108q0 51 35.5 87t87 36t88.5 -36t37 -87t-37 -87t-88.5 -36t-87 36t-35.5 87z" /> -<glyph unicode="©" horiz-adv-x="1630" d="M86 713q0 305 215 522t518 217t518 -216t215 -523q0 -305 -215 -522.5t-518 -217.5t-518 217.5t-215 522.5zM172 713q0 -270 189.5 -462t457.5 -192t457.5 192t189.5 462q0 272 -189.5 462.5t-457.5 190.5t-457.5 -190.5t-189.5 -462.5zM340 707q0 209 149.5 348 t370.5 139q76 0 191 -39q25 -8 34 -8q14 0 21.5 8t19.5 39h41q18 0 21 -23l18 -239v-35q0 -14 -14 -14h-33q-12 0 -16 12q-2 2 -4 12.5t-6 16.5q-76 201 -285 200q-143 0 -229.5 -103t-86.5 -284q0 -199 85 -305t241 -106q184 0 299 149q16 20 29 12l31 -16q16 -9 0 -29 q-152 -203 -394 -202q-205 0 -344 134t-139 333z" /> -<glyph unicode="ª" horiz-adv-x="557" d="M47 942q0 94 146 127q76 18 139 51v97q0 104 -90 104q-29 0 -56 -21q-16 -18 -16 -28l8 -33l-112 -51q-10 29 -11 35q0 45 88 108q66 49 127 49q94 0 135 -44t41 -144v-170v-57q0 -55 27 -56q20 0 70 33l14 -39q-96 -80 -147 -80q-61 0 -74 70q-4 -2 -8 -6t-9 -6 q-74 -57 -137 -58q-59 0 -97 33t-38 86zM160 956q0 -29 19.5 -47t47.5 -18q27 0 66 27.5t39 50.5v100q-39 -16 -66 -27q-72 -29 -89 -44t-17 -42z" /> -<glyph unicode="«" horiz-adv-x="759" d="M63 471l320 410h63l-206 -410v2l206 -405h-63zM362 471l256 375h58l-137 -375l139 -367h-60z" /> -<glyph unicode="¬" horiz-adv-x="1429" d="M145 881v137h1145v-645h-135v508h-1010z" /> -<glyph unicode="­" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="®" horiz-adv-x="1630" d="M63 713q0 313 219.5 534t528.5 221t528.5 -221t219.5 -534q0 -311 -219.5 -532.5t-528.5 -221.5t-528.5 221t-219.5 533zM152 712.5q0 -276.5 192.5 -471t466.5 -194.5t468 194.5t194 471t-194 471t-468 194.5t-466.5 -194.5t-192.5 -471zM393 266v29q0 16 25 16 q55 2 69.5 23.5t14.5 107.5v549q0 86 -12.5 106.5t-63.5 24.5q-20 0 -20 19v18q0 16 2 19q4 4 26 4q41 -2 110.5 -2t156.5 1t116 1q141 2 230.5 -66.5t89.5 -179.5q0 -166 -203 -236q-20 -4 -6 -24l194 -279q35 -49 57.5 -66.5t57.5 -19.5q12 0 12 -4v-8v-10v-21 q0 -18 -24 -18q-92 4 -166 0q-18 0 -29 14l-297 412h-39q-20 0 -20 -37v-199v-78q0 -49 108 -51q14 0 15 -20v-23v-12q0 -6 -9 -6h-16q-195 10 -354 0q-25 0 -25 16zM674 764q0 -12 3 -16.5t17 -4.5q121 0 186.5 48.5t65.5 132.5q0 82 -55 135t-141 53q-37 0 -76 -12v-336z " /> -<glyph unicode="¯" horiz-adv-x="714" d="M18 1063v92q0 23 43 23h21h575q23 0 32 -6.5t9 -26.5v-90q0 -31 -47 -31h-598q-35 0 -35 39z" /> -<glyph unicode="°" horiz-adv-x="849" d="M98 1053q0 139 95.5 236t232.5 97t233.5 -97t96.5 -236q0 -137 -96.5 -234.5t-233.5 -97.5t-232.5 97t-95.5 235zM209 1053q0 -90 63.5 -154.5t153.5 -64.5t154.5 64.5t64.5 154.5q0 92 -64.5 156.5t-154.5 64.5t-153.5 -64.5t-63.5 -156.5z" /> -<glyph unicode="±" horiz-adv-x="1429" d="M145 -2v45q0 27 6.5 36t32.5 7q53 -4 425 -4t640 4q25 0 33 -8t8 -33v-53q0 -31 -20 -37q-12 -6 -49 -6q-233 -2 -1020 -2q-39 0 -49 10q-2 4 -7 16v25zM145 836v55v20q0 8 2 13q6 8 33 8h438q20 0 25.5 5t5.5 24v407q0 6 -1 14.5t-1 12.5q0 47 29 47h80q18 0 23 -7.5 t5 -37.5v-443q-4 -23 21 -22h442q29 0 36 -7t7 -28v-63q0 -27 -9 -32t-40 -5h-426h-16q-6 0 -8 -2q-6 -4 -7 -21v-442q0 -31 -6 -36t-37 -5q-35 -10 -61 0q-25 0 -31 10l-2 6v6t1 8.5t1 10.5v438q0 16 -6 21.5t-22 5.5h-433q-27 0 -35 6t-8 33z" /> -<glyph unicode="²" horiz-adv-x="614" d="M18 633v31q53 63 168 161q2 2 28 22.5t32 27t29.5 27t31.5 31.5t26.5 30.5t26 34t17.5 33t14 36.5t4 37q0 47 -36.5 81t-92 34t-99.5 -36t-65 -100q-4 -10 -37.5 -9t-33.5 13q10 109 84.5 172.5t183.5 63.5q104 0 177 -57.5t73 -147.5q0 -18 -4 -37.5t-8.5 -34t-15.5 -31 t-16 -26.5t-23.5 -26.5t-23.5 -22.5t-27.5 -22.5t-27 -19.5t-30 -20.5t-27.5 -19.5q-74 -49 -151 -119q-6 -4 4 -8q12 -4 22 -4h176q66 0 78 8q6 6 12 19q0 4 4.5 18t6.5 27q2 10 24 10h15q36 0 36 -12q-27 -166 -28 -166h2q-6 -14 -33 -15h-475q-20 0 -21 17z" /> -<glyph unicode="³" horiz-adv-x="614" d="M4 698q0 25 19.5 42.5t46.5 17.5q12 0 27.5 -6.5t24.5 -11.5t26.5 -17t21.5 -14q45 -33 82 -33q55 0 99 49t44 117q0 51 -30.5 86t-69.5 35q-35 0 -72 -27q-35 -20 -55 12q-4 8 -1 22.5t11 18.5q156 100 156 164q0 29 -25.5 50.5t-62.5 21.5q-86 0 -144 -103 q-20 -27 -47.5 -9.5t-21.5 36.5q39 82 105.5 128t148.5 46q76 0 129 -38t53 -99q0 -68 -68 -119q-14 -12 2 -18q63 -20 100.5 -67.5t37.5 -113.5q0 -109 -101.5 -187.5t-230.5 -78.5q-78 0 -141.5 26.5t-63.5 69.5z" /> -<glyph unicode="´" horiz-adv-x="714" d="M242 991l100 336q14 27 39 27h180q12 2 21.5 -3.5t7.5 -15.5v-6l-2 -4l-293 -352q-10 -12 -34.5 -8t-18.5 26z" /> -<glyph unicode="¶" horiz-adv-x="960" d="M-18 940q0 193 127 301.5t350 110.5q453 0 489.5 2t36.5 -29v-37q0 -25 -35 -24h-78q-27 0 -26 -37v-1704q0 -23 -5 -28t-30 -5h-33q-35 0 -35 31l2 1706q0 33 -36 33h-105q-27 0 -26 -29l2 -1716q0 -25 -33 -25h-43q-20 0 -25.5 6t-5.5 27v979q0 31 -37 30 q-160 2 -257 53.5t-150 151.5q-47 88 -47 203z" /> -<glyph unicode="·" horiz-adv-x="526" d="M156 575.5q0 45.5 31.5 78t76.5 32.5t77 -32t32 -79q0 -45 -32 -77.5t-77 -32.5t-76.5 32.5t-31.5 78z" /> -<glyph unicode="¸" horiz-adv-x="714" d="M211 -266l170 286h57l-57 -106q-4 -8 -4 -12q2 -2 6 -3t6 -1q59 -8 98 -54.5t39 -109.5q0 -80 -56 -136.5t-136 -56.5q-47 0 -86 15q-23 8 -8 30q6 12 8 15q4 12 18 8q31 -6 45 -6q43 0 73 28.5t30 67.5q0 74 -58 74q-29 0 -129 -52q-8 -4 -15 -0.5t-1 13.5z" /> -<glyph unicode="¹" horiz-adv-x="614" d="M100 1149q141 84 209 166q4 6 45 6t41 -12v-586q0 -23 4 -29q4 -8 25 -10q23 0 33 2q18 0 26.5 -1t16.5 -11.5t8 -28.5q0 -33 -14 -33q-166 6 -330 0q-16 0 -16.5 33t16.5 33l59 6q25 4 32 10t7 27l-2 426q-2 12 -4 14q-23 -14 -63 -35q-29 -12 -62 -24 q-20 -2 -30.5 16.5t-0.5 30.5z" /> -<glyph unicode="º" horiz-adv-x="737" d="M63 1102q0 119 87.5 198.5t218.5 79.5t220 -79.5t89 -198.5t-89 -199t-216 -80q-133 0 -221.5 80t-88.5 199zM188 1141q0 -111 59.5 -186.5t141.5 -75.5q70 0 116 54t46 138q0 106 -60.5 181t-140.5 75q-70 0 -116 -52t-46 -134z" /> -<glyph unicode="»" horiz-adv-x="759" d="M86 104l137 367l-137 375h61l252 -375l-252 -367h-61zM315 68l207 405v-2l-207 410h64l321 -410l-321 -403h-64z" /> -<glyph unicode="¼" horiz-adv-x="1464" d="M100 1149q145 88 211 166q4 6 46 6t42 -12v-588q0 -23 5.5 -30t25.5 -9h31q27 2 39 -5t12 -34q0 -33 -14 -33q-170 6 -332 0q-18 0 -19 33q4 33 17 33l63 4q23 2 29 9t6 30v426q-2 14 -4 14q-31 -20 -63 -33q-41 -16 -64 -26q-20 0 -30.5 18.5t-0.5 30.5zM194.5 -55.5 q-4.5 14.5 4.5 24.5l968 1370l4 9q4 4 13 4h8h84q4 0 6 -4.5t1 -11.5t-5 -15l-971 -1374q-10 -16 -28 -17h-66q-14 0 -18.5 14.5zM856 188v5v4v32l363 463q35 10 59 4q20 -4 18 -24v-389q0 -10 23 -11h80q25 0 24 -34v-17q0 -4 1 -10t1 -8t-1 -7.5t-3 -7.5q-4 -12 -26 -12 h-76q-18 -4 -23 -16v-168q0 -27 -16 -27h-49q-33 0 -43 4q-27 4 -29 17l2 172q-4 14 -24 18h-252q-29 0 -29 12zM1004 289q-10 -16 8 -17h125q24 1 24 11v172q0 16 -2 24q0 12 -8 4z" /> -<glyph unicode="½" horiz-adv-x="1464" d="M100 1149q145 88 211 166q4 4 29 6t43 -2q16 -2 16 -33v-565q0 -23 6.5 -31t26.5 -10h31q18 2 26.5 0t15.5 -10.5t7 -26.5q4 -33 -14 -33q-170 6 -332 0q-18 0 -19 33q4 33 17 33l80 4q18 2 18 39v405q0 8 -1 14.5t-6 11.5t-15 1q-12 -8 -45 -25q-41 -16 -64 -26 q-20 0 -30.5 18.5t-0.5 30.5zM189 -50q1 7 4 9l974 1380q8 12 21 13h12h70q8 0 11 -9.5t-3 -21.5l-971 -1374q-8 -14 -26 -17h-15h-55q-10 0 -16.5 6.5t-5.5 13.5zM872 2v31q55 66 170 162q127 106 164 161q43 59 43 117q0 49 -35.5 83t-91.5 34q-119 0 -164 -135 q-4 -10 -37.5 -10.5t-33.5 12.5q10 109 85 173t183 64q104 0 177 -58t73 -149q0 -25 -6 -47t-12.5 -38.5t-22.5 -37t-25.5 -30.5t-33 -29.5t-31.5 -26t-37 -27t-35 -24.5q-72 -47 -151 -116q-10 -6 4 -11q12 -4 22 -4h176q66 0 78 8q6 6 12 21q8 33 11 43q2 12 24 12h15 q37 0 37 -14q-27 -166 -29 -166h2q-6 -14 -33 -14h-475q-23 0 -23 16z" /> -<glyph unicode="¾" horiz-adv-x="1464" d="M35 692q0 25 20.5 42.5t46.5 17.5q29 0 101 -52q43 -31 80 -30q55 0 99 48t44 116q0 53 -29.5 87.5t-70.5 34.5q-35 0 -72 -26q-20 -20 -35 -4q-10 10 -18 26q-10 20 8 31q156 98 156 164q0 31 -25 51.5t-64 20.5q-88 0 -141 -105q-8 -10 -43 0t-26 29q35 82 102.5 128 t148.5 46q76 0 130.5 -38t54.5 -99q0 -63 -68 -121q-18 -12 2 -17q135 -43 135 -182q0 -106 -100 -185t-229 -79q-78 0 -142.5 26.5t-64.5 69.5zM194.5 -55.5q-4.5 14.5 2.5 18.5l970 1376q8 12 47 13h43q12 0 17.5 -14.5t-2.5 -24.5l-965 -1366q-14 -18 -39 -19l-55 2 q-14 0 -18.5 14.5zM799 197v2v2v28l362 463q33 10 58 4q23 -4 20 -24v-389q0 -10 21 -11h81q16 0 23 -16q6 -15 6 -33q0 -47 -18 -47h-92q-16 -4 -21 -16l2 -168q-6 -27 -20 -27h-52q-35 0 -47 4q-18 2 -20 17l2 172q-6 16 -25 18h-252q-10 0 -20 6t-8 15zM944 278.5 q2 -6.5 8 -6.5h131q21 1 21 11v192q0 12 -2 14q-4 2 -8 -6l-148 -194q-4 -4 -2 -10.5z" /> -<glyph unicode="¿" horiz-adv-x="759" d="M82 -115q0 201 145 303q53 37 148 72q86 33 86 88q0 33 -14.5 59.5t-65.5 86.5q-18 20 4 30q14 6 34.5 2t29.5 -16q106 -131 106 -229q0 -74 -38 -118t-126 -79q-137 -51 -186 -100.5t-49 -131t53 -129t151 -47.5q31 0 82.5 7.5t77.5 7.5q135 0 135 -88q0 -113 -196 -113 q-168 0 -272.5 109.5t-104.5 285.5zM303 776q0 47 35 80t86 33t86 -32t35 -81q0 -51 -35 -84t-86 -33q-53 0 -87 33t-34 84z" /> -<glyph unicode="À" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM510 1763q-10 10 1 24.5t30 14.5l155 2q31 0 39 -16q54 -139 103 -334q0 -18 -20.5 -22.5t-33.5 8.5q-109 141 -274 323zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373 q-4 10 -13 13t-13 -7q-39 -127 -137 -379z" /> -<glyph unicode="Á" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373q-4 10 -13 13t-13 -7q-39 -127 -137 -379zM608 1448l103 336q6 27 37 26l180 2q8 0 15 -2t11 -6t2 -12q0 -8 -2 -10l-292 -352 q-10 -12 -35 -8.5t-19 26.5z" /> -<glyph unicode="Â" horiz-adv-x="1456" d="M29 55q2 12 20 13q90 0 117 30q18 20 43 78q2 6 31 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h8q92 0 105 -20q106 -281 191 -505t132 -349t60 -160q41 -106 59 -160q27 -74 53.5 -97.5t93.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -547 2 q-18 0 -25 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h96q61 2 78 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-106 -6 -319 0q-8 0 -15.5 -4.5t-10.5 -7.5t-9 -12t-8 -11q-45 -145 -129 -355q-18 -45 -18 -69q0 -27 26.5 -40t91.5 -15q8 0 35 2t39 0 q14 -2 14 -39q-4 -35 -14 -35q-342 6 -444 0h-23q-31 6 -18 61zM434 1442l182 319q8 12 27 21q12 2 72.5 3t81.5 -1q27 -2 34 -21l181 -311q14 -25 -2 -27q-29 -8 -41 5l-250 212l-236 -212q-18 -16 -43 -3q-10 6 -6 15zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5 t1 21.5q-68 188 -125 373q-2 10 -12 13t-14 -7q-39 -127 -137 -379z" /> -<glyph unicode="Ã" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM373 1434q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182.5t-146 -71.5q-82 0 -198 80q-84 59 -121 60q-31 0 -47.5 -20.5 t-28.5 -76.5q0 -4 -2 -15t-4 -21q-6 -14 -28.5 -16.5t-26.5 16.5zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373q-4 10 -13 13t-13 -7q-39 -127 -137 -379z" /> -<glyph unicode="Ä" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM422 1564.5q0 51.5 36 87.5t87 36t88 -36t37 -87.5t-37 -87t-88 -35.5t-87 35.5t-36 87zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373q-4 10 -13 13t-13 -7q-39 -127 -137 -379z M784 1564.5q0 51.5 36 87.5t87 36q53 0 89 -36t36 -87.5t-35.5 -87t-89.5 -35.5q-51 0 -87 35.5t-36 87z" /> -<glyph unicode="Å" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM504 1624q0 88 61.5 149.5t149.5 61.5q84 0 145.5 -61.5t61.5 -149.5t-61.5 -149.5t-145.5 -61.5q-88 0 -149.5 61.5t-61.5 149.5zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373 q-4 10 -13 13t-13 -7q-39 -127 -137 -379zM600 1624q0 -47 34 -81t81 -34q45 0 77.5 34t32.5 81t-32.5 81t-77.5 34q-47 0 -81 -34t-34 -81z" /> -<glyph unicode="Æ" horiz-adv-x="1873" d="M-115 48q4 9 33 11q68 8 112 46t109 147l510 852q53 88 58 98q8 14 8 33q0 29 -19.5 39t-87.5 10q-16 0 -23 3t-5 13l2 29q4 18 26 19q145 -4 550 -1t480 1q51 0 52 -25q2 -41 9 -138.5t9 -125.5v-19q0 -8 -10 -8h-31q-6 0 -11 3t-8 10.5t-5.5 11.5t-4.5 13t-2 11 q-20 96 -45.5 131t-70.5 35h-58h-323q-51 0 -52 -37v-434q0 -33 46 -33l237 5q37 0 78 4q31 2 47 14q31 23 47 115q6 23 23 22h10h12h6q18 0 19 -31q0 -322 2 -368q2 -29 -17 -29q-16 -6 -34 -2q-16 0 -19 25q-12 100 -40.5 123.5t-129.5 21.5l-248 -4q-39 0 -39 -53v-342 q0 -104 27 -128t125 -24q45 -4 213 0q100 4 134 14.5t65 49.5q47 61 69 149q0 2 1 7t3 7v5q0 4 2 4q0 6 17 6h26q21 0 21 -39q-2 -47 -27 -266q-2 -37 -59 -37h-1059q-33 0 -31 22v21q0 29 48 28l63 -2q160 -6 162 142l2 73v207q0 37 -29 37h-395q-27 0 -41 -24l-166 -273 q-47 -78 -47 -108q0 -57 131 -58q25 0 25 -18l2 -29q2 -12 -4.5 -17t-20.5 -5q-33 0 -129 2t-176 2t-127 -4q-20 0 -23 24q-8 27 -4 36zM516 651q-8 -10 1 -19t32 -9h305q35 0 35 55v516q0 33 -12 43q-6 4 -15 -8q-143 -219 -346 -578z" /> -<glyph unicode="Ç" horiz-adv-x="1560" d="M115 649q0 315 208.5 514t544.5 199q147 0 336 -70q72 -27 101 -4q8 6 27.5 6t21.5 -8q25 -104 20 -184q0 -18 -2 -60.5t0 -64.5q-4 -18 -28.5 -23.5t-32.5 7.5q-53 154 -163 239.5t-267 85.5q-248 0 -393.5 -161.5t-145.5 -432.5q0 -279 160 -463t407 -184 q182 0 334 135q41 37 62.5 65.5t60.5 98.5q4 18 43 14q25 -4 23 -16q-49 -170 -144 -328q-27 6 -47 6q-61 0 -160 -30q-94 -29 -227 -29l-53 -98q-4 -8 -4 -13q2 -2 6 -3t6 -1q59 -8 98 -54t39 -109q0 -80 -56 -136.5t-136 -56.5q-47 0 -86 14q-23 8 -9 31q6 12 9 14 q4 12 18 9q31 -6 45 -7q43 0 73 29t30 68q0 74 -58 73q-29 0 -129 -51q-8 -4 -15 -1t-1 14l166 280q-305 14 -493.5 205.5t-188.5 480.5z" /> -<glyph unicode="È" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM422 1763q-8 10 2 24.5t29 14.5l157 2q29 0 39 -16q66 -184 101 -334q0 -18 -20.5 -22.5 t-31.5 8.5q-115 152 -276 323z" /> -<glyph unicode="É" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM522 1448l101 336q6 27 36 26l183 2q8 0 14 -2t10 -6t4 -12q0 -2 -1 -5t-3 -5l-293 -352 q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Ê" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM348 1442l180 319q8 12 27 21q12 2 72.5 3t81.5 -1q27 -2 34 -21l181 -311q14 -25 -2 -27 q-29 -8 -41 5l-250 212l-236 -212q-18 -16 -43 -3q-8 6 -4 15z" /> -<glyph unicode="Ë" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM348 1565q0 47 34 81.5t83 34.5q47 0 82 -34.5t35 -81.5q0 -49 -34 -83t-83 -34t-83 34 t-34 83zM692 1565q0 47 35 81.5t82 34.5q51 0 85 -33.5t34 -82.5t-34 -83t-85 -34q-47 0 -82 35t-35 82z" /> -<glyph unicode="Ì" horiz-adv-x="743" d="M106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-37 4 -22 51q6 14 28 14q8 0 205 -5t266 5q31 1 33 -22q6 -43 -10 -45q-4 0 -13.5 -1t-15.5 -1q-94 -2 -117.5 -36t-23.5 -175v-850q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2 q12 -8 14 -25.5t-3 -32t-13 -14.5q-254 8 -508 0q-25 0 -25 31zM143 1763q-10 10 0.5 24.5t28.5 14.5l158 2q29 0 39 -16q59 -156 100 -334q2 -18 -18.5 -22.5t-32.5 8.5q-109 141 -275 323z" /> -<glyph unicode="Í" horiz-adv-x="743" d="M106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-37 4 -22 51q6 14 28 14q10 0 206 -5t265 5q31 1 33 -22q6 -43 -10 -45q-4 0 -13.5 -1t-15.5 -1q-94 -2 -117.5 -36t-23.5 -175v-850q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2 q12 -8 14 -25.5t-3 -32t-13 -14.5q-254 8 -508 0q-25 0 -25 31zM242 1448l100 336q14 27 39 26l180 2q8 0 15.5 -2t11.5 -6t2 -12v-6l-2 -4l-293 -352q-10 -12 -34.5 -8.5t-18.5 26.5z" /> -<glyph unicode="Î" horiz-adv-x="741" d="M68 1442l180 319q8 12 26 21q12 2 73 3t81 -1q27 -2 35 -21l180 -311q14 -25 -2 -27q-29 -8 -41 5l-250 212l-235 -212q-18 -16 -43 -3q-8 6 -4 15zM104 25q0 12 6.5 25t12.5 13q96 8 118.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-106.5 35q-37 4 -22 51 q6 14 28 14q8 0 205 -5t268 5q31 1 33 -22q6 -41 -10 -45q-6 0 -15.5 -1t-13.5 -1q-94 -2 -118.5 -37t-24.5 -174v-850q0 -80 29.5 -106.5t111.5 -28.5q23 0 31 -2q12 -8 15 -25.5t-2 -32t-13 -14.5q-256 8 -508 0q-27 0 -27 31z" /> -<glyph unicode="Ï" horiz-adv-x="743" d="M55 1564.5q0 51.5 36 87.5t87 36t87 -36t36 -87.5t-36 -87t-87 -35.5t-87 35.5t-36 87zM106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-37 4 -22 51q6 14 28 14q8 0 205 -5t266 5q31 1 33 -22q6 -43 -10 -45q-4 0 -13.5 -1 t-15.5 -1q-94 -2 -117.5 -36t-23.5 -175v-850q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2q12 -8 14 -25.5t-3 -32t-13 -14.5q-254 8 -508 0q-25 0 -25 31zM418 1564.5q0 51.5 35.5 87.5t87.5 36q53 0 89 -36t36 -87.5t-36 -87t-89 -35.5q-51 0 -87 35.5t-36 87z" /> -<glyph unicode="Ð" horiz-adv-x="1628" d="M0 635v72q0 31 39 30h162q16 0 22 6q14 6 15 33v291q0 150 -28 179.5t-153 29.5q-31 0 -30 37q0 35 30 41l168 6q154 6 463 6q203 0 340 -34t246 -113q248 -182 248 -504q0 -233 -143.5 -426t-366.5 -256q-104 -31 -169 -37t-272 -6q-449 0 -522 -2q-8 -2 -16 4t-8 14 q0 41 4 47q8 16 16 17h6h6q2 0 9.5 -1t11.5 -1q92 0 123.5 25.5t34.5 107.5q2 20 2 43.5v42.5v284q0 31 -37 31l-174 -2q-27 4 -27 35zM436 193q0 -100 22.5 -120t145.5 -20q143 0 216 11.5t147 46.5q152 70 241.5 225.5t89.5 343.5q0 156 -56 286t-155 208 q-119 92 -339 114q-111 12 -195 12q-59 0 -86 -2q-31 -12 -31 -47v-479q0 -35 39 -35l293 2q45 0 45 -37v-61q-10 -37 -43 -37l-297 -2q-37 0 -37 -39v-370z" /> -<glyph unicode="Ñ" horiz-adv-x="1708" d="M70 17.5q-4 27.5 6 37.5q10 14 30 15q158 0 158 118v1035q-55 41 -166 43q-8 -2 -12 9t-4 25q0 33 33 33q170 -4 293 0q29 0 49 -24l837 -959q12 -18 31 12q4 8 4 17v676q0 61 -1 87.5t-7 51.5t-18 37q-18 18 -58 24q-33 4 -112 9q-12 0 -18.5 18t-1.5 34.5t20 16.5 q150 -6 503 2q4 0 7.5 -8t4.5 -18.5t1 -12.5q2 -20 -4.5 -25t-24.5 -5q-119 -4 -144.5 -31t-25.5 -145v-1082q0 -27 -36 -31t-42 11q-14 14 -489 555l-475 540q-6 4 -11.5 0t-8.5 -15t-3 -28v-755q0 -104 12 -140q20 -66 99 -71q14 -2 34.5 0t43 -2t26.5 -13q10 -18 5 -41.5 t-30 -23.5q-334 6 -485 -2q-16 -2 -20 25.5zM553 1434q12 276 201 276q82 0 200 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182.5t-145 -71.5q-82 0 -199 80q-84 59 -121 60q-31 0 -47 -20.5t-29 -76.5q0 -4 -2 -15 t-4 -21q-6 -14 -28.5 -16.5t-26.5 16.5z" /> -<glyph unicode="Ò" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M666 1763q-10 10 1 24.5t29 14.5l156 2q31 0 39 -16q53 -139 102 -334q0 -18 -20.5 -22.5t-32.5 8.5q-109 141 -274 323z" /> -<glyph unicode="Ó" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M766 1448l100 336q6 27 37 26l180 2q8 0 15.5 -2t11.5 -6t2 -12q0 -8 -2 -10l-293 -352q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Ô" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t531.5 207q319 0 523 -190.5t204 -481.5q0 -311 -208 -522t-523 -211q-319 0 -527 194.5t-208 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M590 1442l182 319q8 12 27 21q12 2 72.5 3t80.5 -1q23 -2 35 -21l178 -311q14 -25 0 -27q-33 -8 -41 5l-250 212l-235 -212q-18 -16 -43 -3q-10 6 -6 15z" /> -<glyph unicode="Õ" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M502 1434q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182.5t-146 -71.5q-82 0 -198 80q-84 59 -121 60q-31 0 -47.5 -20.5t-28.5 -76.5q0 -4 -2 -15t-4 -21q-6 -14 -28.5 -16.5t-26.5 16.5z " /> -<glyph unicode="Ö" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M543 1564.5q0 51.5 36.5 87.5t88 36t87.5 -36t36 -87.5t-36 -87t-87.5 -35.5t-88 35.5t-36.5 87zM907 1564.5q0 51.5 36 87.5t87 36t88 -36t37 -87.5t-37 -87t-88 -35.5t-87 35.5t-36 87z" /> -<glyph unicode="×" horiz-adv-x="1431" d="M223 227q-33 29 0 60l371 370q31 31 2 62l-360 364q-43 43 -13 72l43 43q27 27 53 0q158 -152 371 -379q23 -20 36 -19t40 23q137 127 342 357q10 14 34.5 20t31.5 0l53 -47q27 -27 -2 -57q-33 -31 -182.5 -183.5t-196.5 -195.5q-33 -25 -4 -53l372 -371q39 -39 9 -64 l-45 -36q-35 -29 -60 -5l-352 359q-43 47 -92 -6q-100 -111 -342 -344q-37 -37 -74 -2z" /> -<glyph unicode="Ø" horiz-adv-x="1771" d="M108.5 649.5q0.5 311.5 225.5 522t557 210.5q246 0 438 -116q20 -12 43 12l125 152q16 16 37 2l16 -13q20 -14 -8 -47l-121 -137q-16 -18 9 -41q225 -195 225 -494q0 -315 -222.5 -529t-547.5 -214q-227 0 -426 109q-35 18 -60 -11l-153 -182q-23 -27 -39 -12l-6 4 q-8 6 -9.5 8t-6.5 6t-5 7t-1 7.5t1 9.5t6 9l160 178q10 12 10 26.5t-6 20.5q-242 201 -241.5 512.5zM332 700q0 -240 123 -415q27 -37 53 -6q414 506 711 831q31 26 4 49q-162 150 -392 150q-217 0 -358 -171t-141 -438zM553 225q-23 -29 6 -57q162 -137 363 -137 q252 0 391 202q119 169 119 402q0 250 -123 428q-16 23 -41 -6q-98 -113 -367.5 -427.5t-347.5 -404.5z" /> -<glyph unicode="Ù" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM633 1763q-8 10 2 24.5t29 14.5l157 2q29 0 39 -16q60 -156 101 -334q0 -18 -20.5 -22.5t-31.5 8.5q-115 152 -276 323z" /> -<glyph unicode="Ú" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM733 1448l101 336q6 27 36 26l183 2q8 0 14 -2t10 -6t4 -12v-6l-2 -4l-295 -352q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Û" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM559 1442l180 319q8 12 27 21q12 2 72.5 3t83.5 -1q25 -2 32 -21l181 -311q14 -25 -2 -27q-29 -8 -41 5l-250 212l-236 -212q-16 -16 -41 -3q-10 6 -6 15z" /> -<glyph unicode="Ü" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM543 1564.5q0 51.5 36.5 87.5t88 36t87.5 -36t36 -87.5t-36 -87t-87.5 -35.5t-88 35.5t-36.5 87zM905 1564.5q0 51.5 37 87.5t88 36t87 -36t36 -87.5t-36 -87t-87 -35.5t-88 35.5t-37 87z" /> -<glyph unicode="Ý" horiz-adv-x="1490" d="M33 1278q-4 12 0 29q4 25 22 24q395 -6 551 0q8 0 17.5 -16.5t4.5 -31.5t-28 -15q-129 0 -129 -41q0 -25 66 -127l274 -422q8 -10 26.5 -1t28.5 28l219 370q66 109 66 137q0 31 -23.5 42.5t-93.5 11.5h-20q-18 8 -16.5 36.5t22.5 28.5q178 -6 457 0q18 0 18 -31 q0 -35 -18 -34q-104 -6 -170 -74q-31 -33 -107 -160l-303 -514v-107.5v-128v-79.5q0 -59 25.5 -92t89.5 -41q8 0 32.5 1t34.5 -3q25 -6 25 -41t-25 -35q-406 6 -573 2q-16 0 -22.5 21.5t-0.5 37.5q8 20 43 21q10 2 31 0t25 -2q109 6 114 131q10 154 2 291l-374 585 q-72 113 -120 147t-143 38q-25 0 -28 14zM643 1448l100 336q14 27 37 26l183 2q8 0 14 -2t10 -6t4 -12v-6l-2 -4l-295 -352q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Þ" horiz-adv-x="1206" d="M39 1311v18q0 20 29 21q401 -8 518 -2q31 0 30 -19v-22q0 -23 -8 -23q-2 -2 -12 -2h-21q-66 -4 -87 -10t-29 -21q-14 -23 -15 -71v-45q0 -14 12.5 -27.5t28.5 -11.5h66q164 0 291 -31q90 -23 162 -80q131 -104 131 -278q0 -195 -140.5 -308.5t-382.5 -113.5 q-84 0 -147 10q-12 2 -16.5 -6t-4.5 -19v-69q0 -84 34 -113t128 -29h43q43 -4 43 -20q4 -47 -33 -47q-303 8 -557 -2q-18 0 -26 4t-6 20q4 23 10 31q6 10 35 10q96 0 116 33q14 23 15 70v100v858q0 115 -15 139q-10 18 -45 23q-6 2 -24 2q-35 2 -47 4h-13h-28q-14 0 -19 2 q-16 4 -16 25zM444 408q0 -43 27 -50q39 -6 84 -6q160 0 259 99.5t99 261.5q0 98 -36.5 171.5t-102.5 108.5q-82 43 -211 43q-39 0 -74 -4q-45 -12 -45 -37v-587z" /> -<glyph unicode="ß" horiz-adv-x="1116" d="M39 23q0 23 3 27.5t21 6.5q80 4 96.5 24.5t16.5 108.5v80v521q0 238 20.5 335t86.5 183q117 147 307 147q156 0 262 -95t106 -235q0 -104 -67.5 -189t-188.5 -138q-10 -4 -12 -7.5t1 -5.5t14 -4q117 -33 208 -120q115 -113 115 -279q0 -168 -109.5 -293t-259.5 -125 q-47 0 -77.5 21.5t-30.5 58.5q0 29 17.5 50.5t43.5 21.5q23 0 70 -29q47 -20 57 -20q41 0 73 79.5t32 204.5q0 342 -211 387q-51 10 -107 11q-20 0 -28 8q-4 6 -4 24q0 14 3 18.5t19 6.5q135 18 207 96t72 205q0 125 -63.5 200.5t-166.5 75.5q-109 0 -166 -90t-57 -274v-133 v-617v-92q0 -78 17.5 -96.5t89.5 -18.5q20 -4 26 -10t6 -30q0 -16 -2 -23q-6 -10 -18 -8q-217 8 -398 0q-14 -2 -19 5t-5 26z" /> -<glyph unicode="à" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23 q-47 -23 -146 -64q-111 -45 -110 -125zM211 1307q-8 10 2 24.5t29 14.5l157 2q29 0 37 -17q64 -170 103 -334q0 -18 -20.5 -22t-31.5 8q-115 152 -276 324z" /> -<glyph unicode="á" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23 q-47 -23 -146 -64q-111 -45 -110 -125zM311 991l101 336q6 27 37 27h182q8 0 14 -1t10 -5.5t4 -12.5q0 -2 -1 -5t-3 -5l-293 -352q-10 -12 -33.5 -8t-17.5 26z" /> -<glyph unicode="â" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM104 985l183 320q8 12 26 20q12 2 72.5 3t81.5 -1q23 -2 35 -20l180 -312 q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -7 14zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125z" /> -<glyph unicode="ã" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM74 967q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5 t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57.5 -182t-145.5 -71q-82 0 -198 79q-84 59 -121 60q-31 0 -47.5 -20.5t-28.5 -75.5q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5t-26.5 16.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170 q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125z" /> -<glyph unicode="ä" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM135 1108q0 47 35 82t84 35q47 0 82 -35t35 -82q0 -49 -34 -83t-83 -34t-84 34 t-35 83zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125zM481 1108q0 47 35 82t82 35q49 0 84 -35t35 -82t-35 -82t-84 -35q-47 0 -82 34t-35 83z" /> -<glyph unicode="å" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM190 1182q0 88 61.5 149.5t149.5 61.5q84 0 145.5 -61.5t61.5 -149.5 t-61.5 -149.5t-145.5 -61.5q-88 0 -149.5 61.5t-61.5 149.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125zM287 1182q0 -47 33.5 -81t80.5 -34q45 0 78 34t33 81t-33 80.5t-78 33.5q-47 0 -80.5 -33.5 t-33.5 -80.5z" /> -<glyph unicode="æ" horiz-adv-x="1339" d="M76 152q0 90 55 134t211 85q96 23 188 82v143q0 197 -145 197q-51 0 -89 -29t-38 -66q0 -6 2 -16t2 -16.5t-3 -14.5t-13 -12l-113 -51q-20 -10 -30.5 4t-10.5 37q0 72 135 176q104 78 195 78q135 0 223 -105q12 -14 31 6q115 102 266 103q109 0 175.5 -49.5t119.5 -165.5 q4 -10 12 -27q8 -20 35 -47v-31q0 -25 -41 -24h-502q-51 0 -51 -45q0 -139 27 -215q27 -80 98.5 -132.5t155.5 -52.5q66 0 116 28t113 95q8 8 21.5 9t19.5 -5l14 -16q14 -12 -4 -35q-82 -94 -170 -149q-94 -59 -188 -60q-176 0 -285 156q-12 20 -30 2q-66 -70 -149 -114 t-153 -44q-86 0 -143 53.5t-57 133.5zM238 180q0 -53 30.5 -85t81.5 -32q82 1 180 97v190q0 29 -20 19q-66 -33 -127 -54q-86 -29 -115.5 -57.5t-29.5 -77.5zM702 629q-4 -20 41 -21h5h305q10 0 16 8.5t4 16.5q-18 86 -66.5 135t-109.5 49q-150 0 -195 -188z" /> -<glyph unicode="ç" horiz-adv-x="864" d="M51 395q0 205 144.5 347.5t351.5 142.5q100 0 172 -37t72 -94q0 -33 -21.5 -54.5t-52.5 -21.5q-53 0 -127 72q-57 57 -117 57q-102 0 -180 -108.5t-78 -256.5q0 -158 80 -257t203 -99q147 0 241 137q12 31 35 25q6 -2 8 -4t4.5 -6.5t4.5 -8.5q16 -12 -3 -39 q-121 -184 -296 -210l-37 -68q-18 -33 -4 -35q59 -8 99 -54t40 -110q0 -80 -57.5 -136t-135.5 -56q-47 0 -88 14q-6 2 -9 11.5t1 19.5q2 2 8 14q4 8 16.5 8t29 -3t20.5 -3q43 0 71.5 28t28.5 66q0 70 -57.5 74t-110.5 -43q-6 -6 -18.5 2t-5.5 21l131 217q6 8 3 18t-14 10 q-156 8 -254 126t-98 294z" /> -<glyph unicode="è" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-139 0 -199 -186zM256 1307q-10 10 1 24.5t30 14.5l155 2q31 0 39 -17q54 -139 103 -334q0 -18 -20.5 -22t-33.5 8q-109 141 -274 324z" /> -<glyph unicode="é" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-139 0 -199 -186zM356 991l101 336q6 27 37 27h180q10 0 16 -1t10 -5.5t2 -12.5q0 -8 -2 -10l-292 -352q-10 -12 -34 -8t-18 26z" /> -<glyph unicode="ê" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM162 985l182 320q8 12 27 20q12 2 72.5 3t80.5 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -6 14zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131 t-116 47q-139 0 -199 -186z" /> -<glyph unicode="ë" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM180 1108q0 47 35 82t84 35q47 0 82 -35t35 -82q0 -49 -34 -83t-83 -34t-84 34t-35 83zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-139 0 -199 -186zM526 1108q0 47 35 82t82 35q49 0 83 -34 t34 -83t-34 -83t-83 -34q-47 0 -82 34t-35 83z" /> -<glyph unicode="ì" horiz-adv-x="536" d="M-14 1307q-10 10 0 24.5t28 14.5l158 2q29 0 39 -17q59 -156 100 -334q2 -18 -18.5 -22t-32.5 8q-109 141 -274 324zM41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5l261 90q41 14 41 -29v-614 q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23z" /> -<glyph unicode="í" horiz-adv-x="536" d="M41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5l261 90q41 14 41 -29v-614q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23zM158 991l100 336 q12 27 39 27h180q12 2 21.5 -3.5t7.5 -15.5q0 -2 -2 -6v-4l-293 -352q-10 -12 -34.5 -8t-18.5 26z" /> -<glyph unicode="î" horiz-adv-x="536" d="M-23 985l183 320q8 12 26 20q12 2 72.5 3t81.5 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -7 14zM41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5 t8.5 27.5l261 90q41 14 41 -29v-614q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23z" /> -<glyph unicode="ï" horiz-adv-x="536" d="M-27 1108q0 51 36 87t87 36t87 -36t36 -87t-36 -87t-87 -36t-87 36t-36 87zM41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5l261 90q41 14 41 -29v-614q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23 q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23zM336 1108q0 51 36 87t87 36t88 -36t37 -87t-37 -87t-88 -36t-87 36t-36 87z" /> -<glyph unicode="ð" horiz-adv-x="1116" d="M94 430q0 197 133 330t328 133q70 0 125 -21q20 -6 31.5 4.5t-0.5 38.5q-20 45 -45 80q-43 66 -115 129q-12 12 -37 16.5t-45 -5.5l-260 -138q-20 -4 -33 19q-14 33 14 47l224 117q14 6 16 21.5t-14 25.5q-51 33 -140 63q-8 0 -20 10.5t-4 24.5l16 29q18 31 51 20 q152 -41 263 -104l192 96q35 10 47 -14q16 -25 -14 -41l-115 -62q-47 -25 -4 -55q59 -45 121 -119q63 -76 102 -145q119 -212 119 -445q0 -274 -149 -403q-129 -117 -316 -117q-205 0 -338 131t-133 334zM270 498q0 -193 94.5 -326t225.5 -133q115 0 188.5 90t73.5 231 q0 197 -93 327t-231 130q-109 0 -183.5 -91t-74.5 -228z" /> -<glyph unicode="ñ" horiz-adv-x="1056" d="M33 39.5q4 19.5 18 19.5h12q72 0 94.5 39t22.5 174v281q0 150 -8 166q-8 18 -80 33l-41 8q-10 2 -10 26.5t10 28.5q33 6 119 43t123 45q47 12 47 -35v-112q0 -6 7 -18.5t15 -6.5q96 68 170 105q86 41 144 41q227 0 227 -369q0 -61 -8 -184t-8 -187q0 -47 16.5 -60.5 t85.5 -13.5q18 12 33 -6q10 -18 4 -43q-2 -12 -6 -15t-19 -3h-6q-43 0 -193.5 1t-195.5 -1q-20 0 -25.5 6t-7.5 27q0 35 17 34h14q68 6 93.5 29t31.5 86q12 119 12 361q0 227 -149 227q-96 0 -252 -121v-463q0 -78 22.5 -98.5t102.5 -20.5q14 0 18 -34q0 -33 -28 -35 q-47 2 -194.5 0t-197.5 2q-25 0 -28 10q-6 14 -2 33.5zM195 967q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52 27.5t30 107.5q0 12 26 12q25 4 25 -12q4 -13 4 -27q0 -111 -57.5 -182t-145.5 -71q-86 0 -198 79q-86 59 -121 60q-31 0 -47.5 -20.5t-28.5 -75.5 q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5t-26.5 16.5z" /> -<glyph unicode="ò" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228zM342 1307 q-8 10 2 24.5t29 14.5l157 2q29 0 39 -17q60 -156 101 -334q2 -18 -19.5 -22t-32.5 8q-115 152 -276 324z" /> -<glyph unicode="ó" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228zM442 991l101 336 q14 27 37 27h182q8 0 14 -1t11.5 -5.5t3.5 -12.5v-6l-3 -4l-292 -352q-12 -12 -36 -8t-18 26z" /> -<glyph unicode="ô" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM209 985l182 320q8 12 27 20q12 2 72.5 3t80.5 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-249 213l-236 -213q-18 -16 -43 -2 q-10 6 -6 14zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228z" /> -<glyph unicode="õ" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM170 967q12 276 201 276q82 0 200 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182t-145 -71 q-82 0 -199 79q-84 59 -121 60q-31 0 -47 -20.5t-29 -75.5q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5t-26.5 16.5zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228z" /> -<glyph unicode="ö" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228zM225 1108q0 47 35 82 t82 35t82 -35t35 -82q0 -49 -34 -83t-83 -34t-83 34t-34 83zM569 1108q0 47 35 82t82 35q51 0 85 -35t34 -82t-34 -82t-85 -35q-47 0 -82 34t-35 83z" /> -<glyph unicode="÷" horiz-adv-x="1431" d="M152 672v51q0 37 63 37h979h37q20 0 29 -2q27 -6 28 -31l4 -59q2 -27 -16.5 -34t-46.5 -7h-1012q-18 0 -41.5 14t-23.5 31zM629 266q0 37 25.5 61.5t62.5 24.5t61.5 -24.5t24.5 -61.5t-24.5 -62.5t-61.5 -25.5q-35 0 -61.5 25.5t-26.5 62.5zM629 1133q0 35 26.5 57 t61.5 22t60.5 -24.5t25.5 -59.5q0 -37 -25.5 -62.5t-60.5 -25.5q-37 0 -63.5 27t-24.5 66z" /> -<glyph unicode="ø" horiz-adv-x="1116" d="M94 422q0 199 134 331t335 132q145 0 273 -82q4 -2 14 3t12 9l92 109q12 12 25 0q20 -16 20 -19q14 -14 -14 -43q-18 -20 -78 -92q-14 -14 -4 -25q129 -131 129 -321q0 -195 -134 -327t-329 -132q-143 0 -268 78q-16 10 -31 -6l-110 -137q-16 -16 -33 0l-23 18 q-10 8 7 31l108 125q16 20 6 30q-131 129 -131 318zM279 487.5q0 -141.5 53 -249.5q2 -6 13 -5.5t17 9.5l377 434q12 14 0 29q-88 106 -204 106q-111 0 -183.5 -91t-72.5 -232.5zM389 147q88 -106 203 -106q111 0 185.5 94.5t74.5 237.5q0 123 -57 237q-8 20 -21 8 l-385 -446q-12 -12 0 -25z" /> -<glyph unicode="ù" horiz-adv-x="1093" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM322 1307q-8 10 2 24.5t28 14.5l158 2q29 0 39 -17q59 -156 100 -334q2 -18 -19.5 -22t-31.5 8q-115 152 -276 324z" /> -<glyph unicode="ú" horiz-adv-x="1093" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM442 991l101 336q14 27 37 27h182q8 0 14 -1t11.5 -5.5t3.5 -12.5v-6l-3 -4l-292 -352q-12 -12 -36 -8t-18 26z" /> -<glyph unicode="û" horiz-adv-x="1093" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM215 985l182 320q8 12 27 20q12 2 72.5 3t81.5 -1q23 -2 34 -20l181 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-236 -213q-18 -16 -43 -2q-10 6 -6 14z" /> -<glyph unicode="ü" horiz-adv-x="1093" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM250 1108q0 47 34.5 82t82.5 35q49 0 83.5 -35t34.5 -82q0 -49 -34.5 -83t-84 -34t-83 34t-33.5 83zM594 1108q0 47 35 82t84 35t82.5 -35t33.5 -82t-33.5 -82t-82.5 -35t-84 34t-35 83z" /> -<glyph unicode="ý" horiz-adv-x="999" d="M18 840q6 23 41 18q35 -2 349 4q33 0 38 -16q4 -14 0 -30.5t-12 -18.5q-66 -2 -86 -14.5t-20 -37.5q0 -23 22 -71q25 -51 189 -459q6 -14 28 21q4 4 4 6l123 313q20 51 31 84q18 55 18 84q0 39 -25.5 55.5t-99.5 18.5q-10 6 -11 31.5t18 27.5h16q176 10 295 2 q35 0 39 -18q2 -12 -2 -27.5t-10 -15.5q-63 -8 -101.5 -56.5t-99.5 -210.5l-254 -684q-72 -184 -86 -219q-31 -74 -74 -125q-33 -43 -94 -43q-39 0 -67.5 28t-28.5 64q0 63 102 89q63 16 105.5 72.5t78.5 176.5l29 95l-262 618q-57 133 -82 161t-98 34q-6 2 -10.5 16 t-2.5 27zM387 991l100 336q12 27 37 27h183q8 0 14 -1t11 -5.5t3 -12.5q0 -2 -2 -6v-4l-293 -352q-12 -12 -35.5 -8t-17.5 26z" /> -<glyph unicode="þ" horiz-adv-x="1071" d="M6 -494l2 33q0 12 7.5 15.5t22.5 1.5t17 -2q53 2 75 14t32 56t10 149v1335v53q0 37 -8 47.5t-45 20.5l-58 16q-23 6 -22 43q0 16 8 21q2 2 10 6l224 137q31 12 44 6t13 -39v-581q0 -27 6 -50q8 -25 21 -12q180 125 290 125q131 0 229.5 -125t98.5 -289q0 -197 -139 -343 t-326 -146q-74 0 -160 29q-12 4 -16 -9.5t-4 -35.5v-209q0 -139 24.5 -182.5t108.5 -36.5l31 2q18 2 24 -3.5t9 -23.5q6 -23 1.5 -35t-32.5 -10q-326 6 -469 0q-29 0 -29 22zM338 199q117 -111 240 -111q102 0 170.5 90.5t68.5 229.5q0 156 -77.5 260t-188.5 104 q-98 0 -213 -98v-475z" /> -<glyph unicode="ÿ" horiz-adv-x="999" d="M18 840q6 23 41 18q35 -2 349 4q33 0 38 -16q4 -14 0 -30.5t-12 -18.5q-66 -2 -86 -14.5t-20 -37.5q0 -23 22 -71q25 -51 189 -459q6 -14 28 21q4 4 4 6l123 313q20 51 31 84q18 55 18 84q0 39 -25.5 55.5t-99.5 18.5q-10 6 -11 31.5t18 27.5h16q176 10 295 2 q35 0 39 -18q2 -12 -2 -27.5t-10 -15.5q-63 -8 -101.5 -56.5t-99.5 -210.5l-254 -684q-72 -184 -86 -219q-31 -74 -74 -125q-33 -43 -94 -43q-39 0 -67.5 28t-28.5 64q0 63 102 89q63 16 105.5 72.5t78.5 176.5l29 95l-262 618q-57 133 -82 161t-98 34q-6 2 -10.5 16 t-2.5 27zM199 1108q0 51 36.5 87t88 36t87 -36t35.5 -87t-35.5 -87t-87 -36t-88 36t-36.5 87zM563 1108q0 51 36 87t87 36t88 -36t37 -87t-37 -87t-88 -36t-87 36t-36 87z" /> -<glyph unicode="Œ" horiz-adv-x="2121" d="M123 657q0 205 103.5 376t279.5 257q141 70 348 70q76 0 227 -8q104 -6 117 -6q6 0 39 1t72 1h589q23 0 31 -6.5t10 -30.5q16 -168 15 -252q0 -25 -19 -25q-6 0 -14 -1t-11 -1t-7.5 1t-7.5 6t-5 16l-10 41q-27 102 -52.5 126.5t-109.5 24.5h-358q-10 0 -24.5 -9 t-14.5 -21v-449q0 -25 59 -25h242q104 0 131 25q23 25 35 119q4 23 20 22h29q14 0 16 -16v-6q4 -109 0 -367q0 -45 -16 -45h-29q-16 0 -20 31q-8 88 -36 112.5t-112 24.5h-282q-16 0 -26.5 -11t-10.5 -24v-481q0 -10 19.5 -22.5t33.5 -12.5h299q119 0 158 10.5t72 49.5 q43 55 67 147q2 6 3 13t2 10.5t5.5 5.5t14.5 2h22q19 0 17 -33q0 -59 -29 -266q-4 -27 -18.5 -33t-47.5 -6q-125 0 -362.5 1t-359.5 1q-70 0 -208.5 -9.5t-205.5 -9.5q-285 0 -482.5 199t-197.5 483zM332 698q0 -274 148.5 -460.5t363.5 -186.5q115 0 192 60 q53 41 68.5 103.5t15.5 248.5v581q0 242 -293 242q-233 0 -364 -155.5t-131 -432.5z" /> -<glyph unicode="œ" horiz-adv-x="1587" d="M98 428q0 190 134.5 322.5t328.5 132.5q184 0 289 -127q16 -18 39 4q121 123 287 123q221 0 297 -199q25 -59 57 -90v-31q0 -20 -27 -20h-493q-57 0 -58 -31q0 -180 82 -305t195 -125q90 0 237 147q4 4 9.5 6.5t8.5 2.5t7 -3.5t6 -5.5t6 -7t6 -7q14 -14 -4 -35 q-74 -82 -174 -151q-98 -63 -196 -64q-143 0 -236 133q-12 12 -22 0q-119 -133 -312 -133q-199 0 -333 133t-134 330zM279 479q0 -176 93 -307t212 -131q100 0 157.5 86t57.5 244q0 197 -78 318.5t-197 121.5q-102 0 -173.5 -94t-71.5 -238zM965 629q0 -6 7 -11.5t18 -7.5 t22 -2h270q31 0 27 29q-8 82 -54.5 134t-111.5 52q-143 0 -178 -194z" /> -<glyph unicode="Ÿ" horiz-adv-x="1490" d="M33 1278q-4 12 0 29q4 25 22 24q395 -6 551 0q8 0 17.5 -16.5t4.5 -31.5t-28 -15q-129 0 -129 -41q0 -25 66 -127l274 -422q8 -10 26.5 -1t28.5 28l219 370q66 109 66 137q0 31 -23.5 42.5t-93.5 11.5h-20q-18 8 -16.5 36.5t22.5 28.5q178 -6 457 0q18 0 18 -31 q0 -35 -18 -34q-104 -6 -170 -74q-31 -33 -107 -160l-303 -514v-107.5v-128v-79.5q0 -59 25.5 -92t89.5 -41q8 0 32.5 1t34.5 -3q25 -6 25 -41t-25 -35q-406 6 -573 2q-16 0 -22.5 21.5t-0.5 37.5q8 20 43 21q10 2 31 0t25 -2q109 6 114 131q10 154 2 291l-374 585 q-72 113 -120 147t-143 38q-25 0 -28 14zM453 1564.5q0 51.5 36.5 87.5t88 36t87 -36t35.5 -87.5t-35.5 -87t-87 -35.5t-88 35.5t-36.5 87zM817 1564.5q0 51.5 36 87.5t87 36t87 -36t36 -87.5t-36 -87t-87 -35.5t-87 35.5t-36 87z" /> -<glyph unicode="ˆ" horiz-adv-x="714" d="M68 985l182 320q8 12 26 20q12 2 73 3t81 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -6 14z" /> -<glyph unicode="˜" horiz-adv-x="714" d="M29 967q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 26 12q25 4 25 -12q4 -13 4 -27q0 -111 -57.5 -182t-145.5 -71q-82 0 -198 79q-84 59 -121 60q-31 0 -47.5 -20.5t-28.5 -75.5q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5 t-26.5 16.5z" /> -<glyph unicode=" " horiz-adv-x="917" /> -<glyph unicode=" " horiz-adv-x="1835" /> -<glyph unicode=" " horiz-adv-x="917" /> -<glyph unicode=" " horiz-adv-x="1835" /> -<glyph unicode=" " horiz-adv-x="611" /> -<glyph unicode=" " horiz-adv-x="458" /> -<glyph unicode=" " horiz-adv-x="305" /> -<glyph unicode=" " horiz-adv-x="305" /> -<glyph unicode=" " horiz-adv-x="229" /> -<glyph unicode=" " horiz-adv-x="367" /> -<glyph unicode=" " horiz-adv-x="101" /> -<glyph unicode="‐" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="‑" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="‒" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="–" horiz-adv-x="1249" d="M78 461l2 71q4 18 24 23q377 12 1043 0q12 0 20.5 -9t8.5 -18v-75q-2 -18 -33 -19q-573 6 -1045 0q-6 0 -13 9.5t-7 17.5z" /> -<glyph unicode="—" horiz-adv-x="1751" d="M170 496q0 12 11.5 25.5t33.5 13.5q680 12 1313 0q33 -11 35 -23q8 -2 2 -37t-6 -41q-12 -25 -29 -22q-745 10 -1323 0q-12 -2 -23.5 5t-9.5 21q0 8 -3 24.5t-1 33.5z" /> -<glyph unicode="‘" horiz-adv-x="557" d="M141 1112q0 100 66.5 185t177.5 126q12 4 23.5 -6t11.5 -24.5t-17 -28.5q-152 -86 -151 -197q0 -31 20 -30q2 0 4.5 1t4.5 1l12 2q16 4 24 4q43 0 71 -31t28 -74q0 -49 -34 -81.5t-83 -32.5q-68 0 -113 54t-45 132z" /> -<glyph unicode="’" horiz-adv-x="557" d="M145 1307q0 49 35 81.5t84 32.5q68 0 112 -51t44 -129q0 -92 -60.5 -176t-156.5 -131q-33 -16 -45 -2q-29 33 0 51q154 90 153 195q0 16 -4 25t-18 7q-29 -8 -45 -8q-43 0 -71 30t-28 75z" /> -<glyph unicode="‚" horiz-adv-x="526" d="M137 59q0 45 33 76t80 31q61 0 101 -49t40 -123q0 -94 -61.5 -175t-161.5 -120q-14 -6 -23 20q-4 31 5 33q143 88 143 187q0 29 -14 28h-7q-4 0 -14 -2t-14 -4h-15q-39 0 -65.5 28.5t-26.5 69.5z" /> -<glyph unicode="“" horiz-adv-x="1028" d="M164 1104q0 96 63.5 182t165.5 131q27 10 37 -8q20 -35 -2 -45q-154 -90 -154 -197q0 -31 21 -30l4 2h6l10 2q16 4 27 4q43 0 70.5 -31t27.5 -74q0 -49 -34.5 -81.5t-83.5 -32.5q-68 0 -113 51t-45 127zM625 1104q0 96 63.5 182t165.5 131q29 10 41 -6q18 -33 -6 -47 q-154 -86 -154 -197q0 -31 21 -30q6 0 22.5 4t24.5 4q43 0 70.5 -31t27.5 -74q0 -49 -35 -81.5t-84 -32.5q-68 0 -112.5 51t-44.5 127z" /> -<glyph unicode="”" horiz-adv-x="1026" d="M158 1307q0 49 34.5 81.5t86.5 32.5q68 0 112.5 -51t44.5 -129q0 -92 -62.5 -177t-162.5 -132q-33 -10 -45 4q-23 31 2 47q158 84 158 195q0 35 -17 34q-6 0 -24 -6q-20 -4 -29 -4q-41 0 -69.5 30t-28.5 75zM616.5 959.5q-0.5 15.5 12.5 23.5q158 84 157 195q0 20 -5 27 t-15 5q-8 0 -10 -2q-4 0 -17.5 -3t-21.5 -3q-41 0 -70 30t-29 75q0 49 35 81.5t86 32.5q68 0 113 -51t45 -129q0 -92 -61.5 -178t-161.5 -131q-37 -16 -47 0q-10 12 -10.5 27.5z" /> -<glyph unicode="„" horiz-adv-x="968" d="M147 59q0 45 34 76t81 31q63 0 104.5 -49t41.5 -123q0 -94 -62.5 -174t-165.5 -121q-14 -4 -26.5 20.5t6.5 32.5q147 88 147 187q0 29 -16 28q-4 0 -11.5 -1t-11.5 -1q-16 -4 -26 -4q-39 0 -67 28.5t-28 69.5zM582 59q0 45 33.5 76t80.5 31q63 0 104.5 -49t41.5 -123 q0 -94 -62.5 -175t-165.5 -120q-8 -4 -16 8t-8 25.5t4 19.5q147 86 147 187q0 29 -14 28h-2h-6l-17 -2q-16 -4 -26 -4q-39 0 -66.5 28.5t-27.5 69.5z" /> -<glyph unicode="•" horiz-adv-x="759" d="M113 672q0 113 77.5 192.5t190.5 79.5t192.5 -80t79.5 -192.5t-79.5 -192.5t-192.5 -80t-190.5 79t-77.5 194z" /> -<glyph unicode="…" horiz-adv-x="2162" d="M258 86q0 49 35 79t90 30q53 0 87 -32t34 -83q0 -49 -34 -82t-87 -33t-89 35t-36 86zM971 78q0 51 33.5 83t89.5 32q53 0 86.5 -32t33.5 -83t-32.5 -82t-85.5 -31q-55 0 -90 32t-35 81zM1675 86q0 51 34 80t89 29q53 0 87 -32t34 -83t-33 -83t-86 -32t-89 36t-36 85z" /> -<glyph unicode=" " horiz-adv-x="367" /> -<glyph unicode="‹" horiz-adv-x="1802" d="M40 37.5q5 17.5 23 21.5h23q80 0 105.5 25t25.5 104v496q0 12 -13.5 24.5t-21.5 12.5h-88q-37 0 -41 14q-4 10 -4 25.5t4 21.5q6 4 21 11q2 2 4 2q94 18 141 49q6 82 12 141q12 80 23 109q31 88 154 198q72 66 171 109t212.5 42t189.5 -65q41 -45 84 -16q76 55 165 87 t185 26.5t166 -62.5q31 -27 31 -49.5t-40 -60t-63 -37.5q-20 0 -49 28q-49 43 -90 58.5t-102 15.5q-84 0 -158 -62.5t-94 -148.5q-14 -70 -15 -248q0 -49 25 -51q90 -12 377 0q82 2 178 35q16 6 26.5 -12.5t10.5 -36.5v-664q0 -78 20.5 -97.5t83.5 -19.5q16 4 29 0 q12 -2 11 -34.5t-11 -36.5q-193 6 -438 0q-14 0 -15 33q0 16 2.5 23t9.5 12.5t21 2.5q88 0 106.5 30t18.5 177v316q0 154 -125 155q-199 6 -287 2q-14 -2 -26 -15t-14 -23l-3 -435q0 -131 18.5 -169t108.5 -38h41q23 0 28 -8t5 -30q0 -33 -12 -33q-246 4 -492 -2 q-16 0 -16 30q0 33 16 39h17q47 0 65.5 2t33.5 25t17.5 60.5t2.5 119.5v412q-12 51 -33 53q-72 4 -203 4t-176 -6q-29 -4 -33 -45v-508q2 -68 26.5 -89t98.5 -21q51 0 61 -3q12 -4 15.5 -23.5t-1.5 -34.5t-14 -15q-301 10 -518 0q-10 0 -16 15t-1 32.5zM389 891 q0 -41 27 -43q229 -10 389 0q16 2 23.5 14t8.5 25.5t1 36v28.5q6 154 55 242q10 23 -33 66q-82 74 -205 73q-84 0 -158.5 -61.5t-93.5 -147.5q-14 -59 -14 -233z" /> -<glyph unicode="›" horiz-adv-x="1761" d="M48 4q-5 14 0 30.5t24 20.5q6 4 29.5 3t29.5 -1q59 2 76.5 28t17.5 103v500q0 33 -26 33h-97q-37 0 -43 14q-6 37 2 47q2 2 23 13q92 16 141 49q6 82 13 141q6 53 22 109q31 88 154 198q74 66 170 108t205.5 42t185.5 -64q37 -35 55 -18q111 96 254 96q23 0 66 -5t63 -5 q55 0 94 49q61 23 62 -14v-1303q0 -76 13 -96.5t71 -22.5q2 0 14 1t18.5 0t14.5 -5t10 -12q8 -19 0 -39q-4 -14 -18 -12h-9h-428q-12 0 -16 20.5t2 32.5q4 10 21.5 12t41 1t29.5 -1q49 6 60.5 42t11.5 171l2 418q0 51 -37 51q-262 10 -362 0q-10 -2 -25 -49v-512 q0 -76 24.5 -99.5t100.5 -23.5q10 4 22 0q16 -2 16.5 -32.5t-16.5 -30.5q-129 4 -438 0q-10 0 -15 18.5t-1 30.5q4 10 13 14t18.5 2t17.5 0q53 4 72 29q14 18 17 47t3 137v398q0 39 -7 49t-34 12h-102.5h-138h-105.5q-16 0 -23.5 -7t-11.5 -32v-422q0 -109 3 -135.5 t16 -44.5q12 -20 32.5 -26.5t75.5 -6.5q29 6 60 0q12 -4 15 -20.5t-2 -30.5t-13 -14q-264 10 -519 0q-10 0 -15 14zM395 883q0 -37 23 -39q111 -4 348 0q29 0 40 6t13 33q11 163 68 286q16 37 -6 62q-6 8 -27 29q-78 74 -192 73q-84 0 -159 -61.5t-93 -147.5 q-14 -59 -15 -241zM983 895q0 -23 10.5 -31t40.5 -10h326q45 0 45 41v389q-115 78 -207 78q-76 0 -133 -78q-80 -109 -82 -389z" /> -<glyph unicode=" " horiz-adv-x="458" /> -<glyph unicode="€" d="M8 506v47q0 20 23 20h121v50q0 68 2 98h-111q-25 0 -25 24v50q0 20 23 20h123q35 238 150.5 367t267.5 129q90 0 186 -58q35 -20 51 -4q12 12 28.5 15.5t28 -2t11.5 -15.5q8 -156 8 -297q0 -12 -17.5 -19t-35 -6t-19.5 9q-27 145 -89 224t-146 79q-221 0 -252 -422h373 q23 0 22 -20v-50q0 -25 -24 -24h-375v-55q0 -63 2 -93h362q23 0 23 -20v-47q0 -25 -25 -25h-354q20 -217 88 -329.5t174 -112.5q102 0 178 123q20 37 60 157q2 16 47 15q33 0 31 -17q-29 -174 -74 -315q-16 4 -35 4q-39 0 -102.5 -21.5t-124.5 -21.5q-154 0 -274 138.5 t-148 379.5h-127q-25 0 -25 25z" /> -<glyph unicode="™" horiz-adv-x="2099" d="M34 1209.5q-3 7.5 1 39.5l18 152q2 23 10.5 29t32.5 6q324 -8 688 0q31 2 41.5 -5.5t12.5 -37.5l16 -152q0 -4 1 -11t1 -9q0 -10 -2 -13q-2 -6 -25 -6h-30q-12 86 -52 117t-139 31h-33q-16 0 -20 -4q-12 -4 -12 -37v-553q0 -76 14 -98.5t72 -26.5h12q6 0 6 -2q6 -2 6 -33 v-14q-4 -8 -4 -9q-4 -6 -35 -4q-143 6 -331 0q-31 0 -37 4.5t-6 26.5v16q2 10 10 13q8 0 14 2q55 8 67.5 27.5t12.5 95.5v557q0 33 -12 37q-4 2 -21 2h-35q-92 0 -132 -31t-54 -117h-35q-18 0 -21 7.5zM905 580v22q0 27 29 27q59 2 73.5 24.5t14.5 100.5v487 q0 86 -13.5 107.5t-72.5 23.5q-23 0 -29 8l-2 4v7v18q0 18 5 22.5t22 4.5q201 -6 268 -2q23 0 31 -19l250 -524q10 -18 16 -21q6 -4 10 7l258 559h267q23 0 30 -4q10 -6 11 -27q0 -23 -4.5 -27t-10.5 -4q-4 -2 -18 -2q-53 -2 -67.5 -25.5t-14.5 -103.5v-487 q0 -78 13.5 -99.5t70.5 -25.5q8 -2 18 -2q6 0 8 -2q5 -4 5 -31q0 -16 -6.5 -21.5t-26.5 -5.5q-27 0 -106 1t-144.5 1t-103.5 -2q-33 -2 -41.5 3.5t-8.5 27.5v21q0 10 9 10h8h22q55 4 70.5 27.5t15.5 95.5v436q-2 14 -6 16q-4 -4 -6 -10l-289 -627h-49l-285 617 q-12 6 -14 -23v-407q0 -84 15.5 -105.5t70.5 -21.5h31q12 0 14 -2q4 -4 4 -9q0 -2 -1 -8t-1 -10q0 -33 -8 -35h-14q-12 4 -23 4q-186 4 -256 0q-10 -2 -24.5 -2t-14.5 13z" /> -<glyph unicode="◼" horiz-adv-x="849" d="M0 0v850h850v-850h-850z" /> -<glyph unicode="fi" horiz-adv-x="1138" d="M82 8q-12 31 12 43l47 6q53 8 63.5 35t10.5 139v426q0 53 -41 56l-70 6q-12 6 -15 22.5t9 24.5q6 6 38 16.5t50 20.5q29 14 29 41q0 195 64 344q43 102 143 189t254 87q104 0 180 -48t76 -113q0 -43 -29 -64.5t-57 -21.5q-37 0 -55 30q-41 70 -92.5 102.5t-96.5 32.5 q-229 0 -229 -489q0 -33 1 -43t13 -23.5t39 -13.5q133 -4 242 0q176 4 239 18q39 12 49 -4q-8 -147 -8 -256v-340q0 -113 11.5 -139t64.5 -35l43 -6q16 -2 15 -26.5t-17 -32.5q-61 4 -195 4h-172q-2 0 -10 -1t-10 0t-6 4t-6 11q-12 41 41 45q6 2 10 2q53 8 64.5 35t11.5 139 v355q0 90 -16.5 108.5t-84.5 20.5q-137 4 -276 0q-25 -2 -34 -13.5t-9 -48.5v-422q0 -113 11 -141.5t62 -32.5l66 -6q18 -2 15 -28.5t-19 -30.5q-127 6 -217 6q-92 0 -178 -6q-25 0 -31 16z" /> -<glyph unicode="fl" horiz-adv-x="1103" d="M49 4q-10 20 0 43q4 10 29 10q72 6 90 31q14 18 17 48t3 136v430q0 33 -32 37h-95q-6 0 -10 17q-4 18 0 28q4 16 17 17l106 45q14 10 14 24q18 287 160 441q137 154 305 153q23 0 66 -5t63 -5q55 0 95 49q55 20 61 -2v-1321q0 -82 15.5 -102.5t88.5 -20.5q10 4 27 0 q8 -2 11 -19.5t-1 -31.5q-2 -12 -14 -12h-8q-201 8 -420 0h-8q-14 0 -19 12q-6 14 -2 31.5t17 19.5h16q39 0 55.5 1t36 8.5t24.5 17.5t11 39t7 59.5t1 89.5v437q0 35 -39 34q-279 6 -360 -2q-18 0 -23 -22v-539q0 -76 24.5 -99.5t100.5 -23.5q12 4 21 0q14 -2 16 -31.5 t-12 -31.5h-6h-6q-27 0 -115 2t-167 2t-132 -4q-20 -4 -29 10zM354 877q0 -8 4 -12.5t7.5 -5.5t13.5 -2t12 -1q57 -2 123 -2t132.5 1t88.5 1q35 0 41 45v385q-115 78 -207 78q-76 0 -133 -78q-82 -115 -82 -409z" /> -<glyph unicode="ffi" horiz-adv-x="1802" d="M40 37.5q5 17.5 23 21.5h23q80 0 105.5 25t25.5 104v496q0 12 -13.5 24.5t-21.5 12.5h-88q-37 0 -41 14q-4 10 -4 25.5t4 21.5q6 4 21 11q2 2 4 2q94 18 141 49q6 82 12 141q12 80 23 109q31 88 154 198q72 66 171 109t212.5 42t189.5 -65q41 -45 84 -16q76 55 165 87 t185 26.5t166 -62.5q31 -27 31 -49.5t-40 -60t-63 -37.5q-20 0 -49 28q-49 43 -90 58.5t-102 15.5q-84 0 -158 -62.5t-94 -148.5q-14 -70 -15 -248q0 -49 25 -51q90 -12 377 0q82 2 178 35q16 6 26.5 -12.5t10.5 -36.5v-664q0 -78 20.5 -97.5t83.5 -19.5q16 4 29 0 q12 -2 11 -34.5t-11 -36.5q-193 6 -438 0q-14 0 -15 33q0 16 2.5 23t9.5 12.5t21 2.5q88 0 106.5 30t18.5 177v316q0 154 -125 155q-199 6 -287 2q-14 -2 -26 -15t-14 -23l-3 -435q0 -131 18.5 -169t108.5 -38h41q23 0 28 -8t5 -30q0 -33 -12 -33q-246 4 -492 -2 q-16 0 -16 30q0 33 16 39h17q47 0 65.5 2t33.5 25t17.5 60.5t2.5 119.5v412q-12 51 -33 53q-72 4 -203 4t-176 -6q-29 -4 -33 -45v-508q2 -68 26.5 -89t98.5 -21q51 0 61 -3q12 -4 15.5 -23.5t-1.5 -34.5t-14 -15q-301 10 -518 0q-10 0 -16 15t-1 32.5zM389 891 q0 -41 27 -43q229 -10 389 0q16 2 23.5 14t8.5 25.5t1 36v28.5q6 154 55 242q10 23 -33 66q-82 74 -205 73q-84 0 -158.5 -61.5t-93.5 -147.5q-14 -59 -14 -233z" /> -<glyph unicode="ffl" horiz-adv-x="1761" d="M48 4q-5 14 0 30.5t24 20.5q6 4 29.5 3t29.5 -1q59 2 76.5 28t17.5 103v500q0 33 -26 33h-97q-37 0 -43 14q-6 37 2 47q2 2 23 13q92 16 141 49q6 82 13 141q6 53 22 109q31 88 154 198q74 66 170 108t205.5 42t185.5 -64q37 -35 55 -18q111 96 254 96q23 0 66 -5t63 -5 q55 0 94 49q61 23 62 -14v-1303q0 -76 13 -96.5t71 -22.5q2 0 14 1t18.5 0t14.5 -5t10 -12q8 -19 0 -39q-4 -14 -18 -12h-9h-428q-12 0 -16 20.5t2 32.5q4 10 21.5 12t41 1t29.5 -1q49 6 60.5 42t11.5 171l2 418q0 51 -37 51q-262 10 -362 0q-10 -2 -25 -49v-512 q0 -76 24.5 -99.5t100.5 -23.5q10 4 22 0q16 -2 16.5 -32.5t-16.5 -30.5q-129 4 -438 0q-10 0 -15 18.5t-1 30.5q4 10 13 14t18.5 2t17.5 0q53 4 72 29q14 18 17 47t3 137v398q0 39 -7 49t-34 12h-102.5h-138h-105.5q-16 0 -23.5 -7t-11.5 -32v-422q0 -109 3 -135.5 t16 -44.5q12 -20 32.5 -26.5t75.5 -6.5q29 6 60 0q12 -4 15 -20.5t-2 -30.5t-13 -14q-264 10 -519 0q-10 0 -15 14zM395 883q0 -37 23 -39q111 -4 348 0q29 0 40 6t13 33q11 163 68 286q16 37 -6 62q-6 8 -27 29q-78 74 -192 73q-84 0 -159 -61.5t-93 -147.5 q-14 -59 -15 -241zM983 895q0 -23 10.5 -31t40.5 -10h326q45 0 45 41v389q-115 78 -207 78q-76 0 -133 -78q-80 -109 -82 -389z" /> -</font> -</defs></svg> - \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.ttf b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.ttf Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.woff b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-line-figures/et-book-roman-line-figures.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.svg b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.svg @@ -1,244 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata></metadata> -<defs> -<font id="etbemboromanosf" horiz-adv-x="1093" > -<font-face units-per-em="2048" ascent="1638" descent="-410" /> -<missing-glyph horiz-adv-x="501" /> -<glyph horiz-adv-x="2048" /> -<glyph horiz-adv-x="2048" /> -<glyph unicode="
" horiz-adv-x="681" /> -<glyph unicode=" " horiz-adv-x="501" /> -<glyph unicode="	" horiz-adv-x="501" /> -<glyph unicode=" " horiz-adv-x="501" /> -<glyph unicode="!" horiz-adv-x="557" d="M168 78q0 49 31.5 78.5t81 29.5t82 -29.5t32.5 -78.5q0 -47 -32.5 -78t-82 -31t-81 31t-31.5 78zM173 1367q-1 19 15.5 32.5t49.5 13.5l67 -2q59 -2 72.5 -17.5t9.5 -68.5l-78 -950q-6 -14 -26.5 -16.5t-30.5 16.5l-78 950q0 23 -1 42z" /> -<glyph unicode=""" horiz-adv-x="870" d="M135 1241q0 139 111 139q53 0 84.5 -35t31.5 -94q0 -31 -8 -92q-4 -31 -16 -92l-59 -315q-10 -14 -33 -13q-12 0 -23.5 10.5t-13.5 26.5l-51 293q-23 127 -23 172zM510 1229q0 152 117 151q53 0 84.5 -35t31.5 -94q0 -70 -22 -186l-59 -313q-6 -16 -23 -19 q-14 -4 -30.5 3t-16.5 16l-55 311q-27 143 -27 166z" /> -<glyph unicode="#" horiz-adv-x="1431" d="M94 408q-6 31 0 63q0 33 45 33h154q25 0 34 6t13 31l66 315q4 31 -25 33h-68.5h-96.5h-71q-31 0 -42 7t-9 26q-4 27 4 75q0 23 43 25q145 4 269 0q20 -2 26 3t10 26l76 364q4 16 7 25.5t11.5 12.5t13.5 2t24.5 -3t31.5 -4q35 -2 39 -8t-2 -37l-69 -348q-4 -12 3 -22.5 t21 -10.5q45 4 186.5 1t184.5 -1q23 2 29 8t10 29q53 264 67 330q0 4 2 14t3 13t4.5 10.5t5.5 9.5t7 6t12 6t15 2l50 4q25 2 33 -14.5t1 -38.5l-71 -346q-6 -33 24 -33q55 -6 138 0h11h10h8t7 -2t5.5 -5t3.5 -9.5v-14.5q2 -8 -5 -76q0 -27 -47 -26h-44.5h-61.5h-45 q-8 0 -14.5 -1t-10.5 -2t-8 -5t-6 -6.5t-4 -10.5t-3 -10t-3 -12.5t-2 -14.5l-60 -286q-8 -37 31 -37q98 -4 225 0q16 0 29.5 1t21 -7.5t7.5 -28.5l-5 -61q0 -10 -3 -16.5t-5 -10.5t-10 -6t-11 -2t-14.5 -1t-13.5 -1q-121 -4 -231 0q-31 0 -40 -4.5t-12.5 -20.5t-11.5 -27 l-67 -331q-4 -27 -13.5 -37t-33.5 -10h-60q-37 0 -26 53l67 323q8 27 2 39.5t-31 14.5q-190 8 -342 0q-37 -2 -45 -7.5t-16 -39.5l-68 -334q-2 -12 -7 -21.5t-8 -14.5t-12 -7l-13.5 -3t-19.5 -1h-22l-32 -2q-10 0 -15.5 3t-6.5 11t0 14t4 17.5t3 15.5l68 328q6 25 1 33 t-32 8h-129q-20 0 -26.5 1t-11.5 9t-5 27zM467 526.5q2 -6.5 4 -7.5t7 -5t7 -8q193 8 365 0q47 0 55 37l62 297q6 33 1 41t-28 8q-199 4 -354 0q-37 -2 -43 -12q-4 -8 -8 -27l-66 -309q-4 -8 -2 -14.5z" /> -<glyph unicode="$" horiz-adv-x="980" d="M74 213q0 33 23.5 57.5t56.5 24.5q53 0 88 -88q4 -12 11 -32.5t10 -28t10.5 -21.5t18.5 -24.5t27 -22.5q16 0 17 28v502q-6 14 -14 21q-121 92 -156 135q-57 72 -57 168q0 92 60 165.5t159 106.5q8 0 8 19v110q4 10 18 13l23 2q16 -4 24 -19v-86q2 -2 4.5 -7t5.5 -8 t11 -3q51 4 100 0q4 -2 9.5 7t5.5 15v82q2 10 24 17h25q18 0 18 -23l-2 -96q0 -12 10 -23q102 -31 164 -80t62 -104q0 -33 -20.5 -54.5t-51.5 -21.5q-49 0 -94 68q-31 47 -54 71l-16 -8v-373q6 -37 12 -43q84 -53 134.5 -92t95.5 -109.5t45 -152.5q0 -115 -75 -202 t-202 -123q-10 0 -10 -19q0 -104 2 -162q0 -18 -22 -18h-31q-20 4 -16 24l2 140q0 20 -19 20q-43 -6 -96 2q-4 0 -11.5 -5t-7.5 -15l3 -131q0 -4 1 -10.5t1 -9.5t-3.5 -8t-9.5 -7h-51q-12 4 -8 22v9v153q-2 16 -12 21q-135 43 -189 98q-61 66 -61 129zM244 1004 q0 -78 75 -144q10 -8 17 14v5v241q2 2 0 9.5t-8 5.5q-84 -45 -84 -131zM401 51q4 -18 13 -18q63 -14 112 -4q11 0 11 20v418q0 10 -7.5 23.5t-11.5 15.5l-61 39q-20 12 -39 24q-8 4 -12.5 -3t-4.5 -25v-490zM401 819q0 -20 9 -28q12 -10 110 -74q17 8 17 20v391q0 20 -11 21 q-63 18 -110 10q-14 -2 -15 -29v-311zM602 76q0 -6 4 -10.5t7 -5.5t5 1q121 66 121 197q0 100 -98 166l-25 16q-6 4 -11 -4t-3 -16v-344z" /> -<glyph unicode="%" horiz-adv-x="1425" d="M90 938q0 131 84 216t205 85q123 0 209 -83t84 -212q-2 -131 -85 -216t-206 -85q-119 0 -205 85t-86 210zM207 942q0 -111 47 -171t127 -60q82 0 129 61.5t47 172t-48 170t-134 59.5q-78 0 -123 -61.5t-45 -170.5zM258 -98l801 1390q18 25 45 15l24 -11q19 -5 7 -34 l-797 -1383q-6 -12 -12 -16q-4 -2 -41 -2q-49 0 -27 41zM731 209q0 131 84 216t205 85q123 0 209 -83t84 -212q-2 -131 -85 -216t-206 -85q-119 0 -205 84t-86 211zM848 213q0 -111 47 -171t127 -60q82 0 129 61t47 172t-48 170t-134 59q-78 0 -123 -61t-45 -170z" /> -<glyph unicode="&" horiz-adv-x="1562" d="M86 328q0 162 121 266q53 47 207 119q35 23 24 30q-131 125 -131 263q0 117 83 188.5t218 71.5q123 0 204 -61.5t81 -157.5q0 -147 -211 -265q-6 -4 -5 -12t5 -12q68 -51 162 -142q88 -86 157 -188q8 -14 27 10q78 98 133 187q47 72 75 134t28 83q0 14 -22.5 20t-57.5 9 t-37 3q-8 4 -10 20.5t2 25.5q2 12 24 12q135 -6 359 2q20 4 24 -16v-27q0 -16 -28 -21q-10 -2 -40 -4t-45.5 -4t-37 -10t-35.5 -21q-29 -29 -80 -122q-14 -29 -34.5 -68t-22.5 -45q-63 -117 -164 -229q-10 -10 -2 -23q37 -61 71 -123q55 -100 87 -132t75 -32q53 0 166 78 q14 4 28.5 -22.5t0.5 -32.5q-147 -119 -273 -119q-86 0 -136 39t-109 147q-10 20 -27 50q-12 23 -31 4q-240 -240 -465 -240q-152 0 -255 105.5t-103 261.5zM285 352q0 -117 67.5 -188.5t177.5 -71.5q84 0 183.5 49t169.5 125q10 10 0 27q-72 111 -174 217 q-113 113 -193 166q-14 10 -41 -8q-190 -143 -190 -316zM467 1059q0 -131 145 -246q127 80 127 217q0 78 -40 123t-105 45q-59 0 -93 -37t-34 -102z" /> -<glyph unicode="'" horiz-adv-x="378" d="M78 1231q0 150 110 149q53 0 85 -35t32 -94q0 -39 -10 -94q-12 -66 -16 -90l-50 -281q-4 -20 -13 -32.5t-28 -10.5q-23 2 -27.5 6.5t-6.5 20.5q-2 8 -2 12l-50 285q-25 127 -24 164z" /> -<glyph unicode="(" horiz-adv-x="667" d="M162 492q0 256 105.5 505.5t287.5 446.5q31 23 61.5 -7t12.5 -61q-143 -160 -244 -422q-78 -205 -78 -462q0 -201 43 -359t146 -338q61 -104 133 -190q16 -33 -49 -64q-20 -10 -43 17q-172 190 -273.5 438t-101.5 496z" /> -<glyph unicode=")" horiz-adv-x="647" d="M25 -391q147 164 245 422q78 205 78 465q0 199 -43 356.5t-147 339.5q-57 102 -119 174q-12 12 -11 32.5t17 35.5q37 31 70 -2q176 -193 275 -437.5t99 -498.5q0 -260 -104 -511t-287 -444q-33 -25 -65.5 3t-7.5 65z" /> -<glyph unicode="*" d="M158 727q0 49 23.5 68.5t80.5 31.5q4 2 46 11.5t67 17.5q57 16 119 53q25 14 4 25q-66 35 -123 51q-20 6 -41 11t-42.5 10.5t-31.5 7.5q-55 16 -78.5 35.5t-23.5 66.5q0 23 19.5 49.5t66.5 26.5q10 0 18 -2t17.5 -8t15.5 -10.5t15 -13.5t13.5 -13t13.5 -15.5t11 -13.5 q74 -88 164 -143q23 -12 23 14q-4 96 -29 180q-29 96 -29 125q0 35 21.5 61.5t58.5 26.5t58.5 -26.5t21.5 -61.5q0 -37 -27 -125q-27 -92 -28 -180q0 -25 26 -12q92 59 158 141q66 76 106 76q47 0 65.5 -25.5t18.5 -50.5q0 -68 -79 -96q-25 -8 -72 -18.5t-64 -16.5 q-47 -14 -120 -49q-12 -6 -14.5 -9t-0.5 -6t17 -12q76 -41 116 -53q16 -6 65.5 -15.5t74.5 -17.5q77 -26 77 -96q0 -27 -21.5 -50.5t-53.5 -23.5q-39 0 -63.5 19.5t-53.5 58.5q-72 90 -160 143q-20 10 -20 -8q2 -123 28 -202q14 -35 19 -54q8 -18 8 -57t-22.5 -65.5 t-59.5 -26.5t-59.5 26.5t-22.5 65.5q0 29 8 57q12 33 21 54q27 80 28 198q0 25 -20 12q-84 -49 -160 -143q-23 -29 -33 -40t-33.5 -24.5t-52.5 -13.5q-33 0 -54 23.5t-21 50.5z" /> -<glyph unicode="+" horiz-adv-x="1429" d="M145 662v55v13v11t1 7.5t3.5 6.5t6.5 3t10 2h14h438q20 0 25.5 5t5.5 23v408q0 6 -1 14.5t-1 12.5q0 47 29 47h80q18 0 23 -7.5t5 -37.5v-445q-4 -20 21 -20h442q27 0 35 -7.5t8 -27.5v-63q0 -27 -9 -32t-40 -5h-426h-12h-9t-5.5 -2t-4.5 -7.5v-13.5v-442q0 -31 -6 -36 t-37 -5q-29 -8 -61 0q-8 0 -13 1t-9.5 3t-5.5 3t-2 6t-1 7v9.5v11.5v438q0 27 -28 27h-433q-27 0 -35 6t-8 31z" /> -<glyph unicode="," horiz-adv-x="514" d="M143 63q0 45 33 75t78 30q61 0 98 -44t37 -116q0 -88 -52 -168t-136 -119q-29 -14 -41 -2q-2 2 -5 7.5t-5 7.5q-10 31 6 35q137 82 137 178q0 20 -8 22q-6 4 -27 -2q-47 -10 -81 18.5t-34 77.5z" /> -<glyph unicode="-" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="." horiz-adv-x="417" d="M133 80q0 53 35 86t90 33q53 0 86 -32t33 -85q0 -51 -33 -85t-86 -34t-89 33t-36 84z" /> -<glyph unicode="/" horiz-adv-x="980" d="M76 -14.5q0 10.5 6 24.5q119 225 348 670.5t346 673.5q20 33 35 32l102 -4q8 0 14.5 -7t5.5 -20.5t-11 -27.5l-691 -1331q-20 -41 -45 -39h-15h-21.5t-24.5 1t-23.5 4t-17.5 8t-8 15.5z" /> -<glyph unicode="0" horiz-adv-x="1001" d="M82 440q0 215 121 353.5t309 138.5q190 0 311 -136.5t121 -349.5q0 -209 -121 -342t-313 -133q-186 0 -307 133.5t-121 335.5zM227 452.5q0 -178.5 76 -279.5t207 -101q135 0 213 100.5t78 278.5q0 184 -77 284.5t-216 100.5q-129 0 -205 -102.5t-76 -281z" /> -<glyph unicode="1" horiz-adv-x="790" d="M111 641q18 12 45.5 29.5t42.5 27.5q143 100 221 207q10 8 47 8t41 -16v-721q0 -70 16 -84q10 -6 35 -10q6 -2 57 -6h33t33 -2q18 -4 18 -43t-20 -39q-365 4 -504 0q-12 -2 -17 15.5t-2 38t13 26.5q18 8 37 4q51 0 59 2q29 0 45 8q43 20 43 84v475q-2 4 -2 16.5t-2 18.5 q-2 18 -12 12q-31 -23 -82 -49q-23 -12 -60.5 -29.5t-56.5 -25.5q-14 -8 -26.5 18.5t-1.5 34.5z" /> -<glyph unicode="2" horiz-adv-x="1001" d="M66 19.5q0 21.5 8 29.5q229 158 375 287q174 154 174 276q0 88 -56.5 143.5t-144.5 55.5q-115 0 -238 -113q-8 -8 -31.5 3.5t-13.5 33.5q94 106 177 151.5t186 45.5q117 0 199.5 -69.5t82.5 -170.5q0 -76 -42 -152.5t-122.5 -151.5t-136 -119t-143.5 -105q-6 -6 0 -14 q4 -8 18 -9q281 0 336 2q41 2 56.5 10.5t31.5 36.5q31 55 60 129q12 12 35 9q10 -2 17 -7.5t5 -13.5l-70 -287q-6 -29 -55 -28h-18h-678q-12 6 -12 27.5z" /> -<glyph unicode="3" horiz-adv-x="892" d="M123 -252q0 47 41 66.5t78 -2.5q6 -4 17 -13.5t17 -13.5q82 -61 136 -61q57 0 97 67.5t40 175.5q0 178 -84 250q-66 59 -176 29q-20 -6 -26.5 20.5t5.5 32.5q256 158 256 340q0 76 -36.5 120t-100.5 44q-96 0 -194 -113q-8 -6 -18.5 -4t-19 14.5t-3.5 26.5 q51 100 127.5 155.5t166.5 55.5q100 0 166 -71.5t66 -178.5q0 -156 -164 -278q-8 -4 -11 -11.5t7 -11.5q45 -6 84 -37q111 -94 111 -274q0 -188 -112 -314.5t-280 -126.5q-190 0 -190 113z" /> -<glyph unicode="4" horiz-adv-x="1001" d="M54.5 21.5q-3.5 19.5 4.5 33.5l572 865q16 20 43 16q20 -8 20 -21v-759q4 -25 29 -35l168 4q4 0 16.5 -1t18.5 -5t8 -16t2 -78q0 -10 -14.5 -19.5t-20.5 -7.5l-178 2q-6 0 -17.5 -9t-11.5 -18q6 -133 0 -299q0 -39 -32 -39h-105q-10 -2 -19.5 11.5t-9.5 23.5 q-8 188 -2 291q-6 41 -20 39q-176 -10 -440 0q-8 2 -11.5 21.5zM208 131.5q3 -10.5 13 -10.5q125 -4 268 0h11q14 2 24 14q2 4 4 6q-6 324 0 449q6 16 -6 28q-4 4 -8 -2l-303 -464q-6 -10 -3 -20.5z" /> -<glyph unicode="5" horiz-adv-x="919" d="M111 -279q0 33 21.5 56.5t51.5 23.5q23 0 54 -12q117 -41 151 -41q86 0 150.5 80t64.5 190q0 78 -38 154t-107.5 140.5t-129 108.5t-141.5 95q-18 12 0 41q150 207 291 361q12 14 29 12l233 -27q39 -4 35 -35q-4 -18 -29.5 -55t-37.5 -49q-14 -14 -35 -14l-193 24 q-25 2 -37 -14l-79 -98q-23 -29 -19 -37t21 -19q98 -61 192 -149q186 -176 186 -373q0 -213 -206 -346q-156 -100 -320 -100q-49 0 -78.5 22.5t-29.5 60.5z" /> -<glyph unicode="6" horiz-adv-x="1028" d="M98 451q0 154 66.5 290t179.5 234t240 167.5t270 114.5q37 10 54.5 -5t-3.5 -44q-176 -78 -292.5 -165t-215.5 -226q-6 -10 0 -16t15 -4q41 10 55 10q16 2 55 2q178 0 291 -113t113 -293q0 -184 -116 -308t-288 -124q-182 0 -303 136.5t-121 343.5zM276 403 q0 -174 65 -273t175 -99q88 0 148 59q86 86 86 281q0 184 -67 283.5t-187 99.5q-61 0 -152 -41q-41 -100 -54.5 -162t-13.5 -148z" /> -<glyph unicode="7" horiz-adv-x="1001" d="M86 561l41 309q14 35 63 35q332 12 662 0q37 0 45 -16v-33q-293 -762 -504 -1194q-10 -27 -31 -24l-63 2q-14 2 -23.5 13t-3.5 25l471 1059q4 10 -11 14.5t-30 4.5q-90 -6 -423 0q-43 2 -68 -18.5t-41 -88.5l-27 -102q-4 -6 -18 -6t-26.5 5t-12.5 15z" /> -<glyph unicode="8" horiz-adv-x="950" d="M145 285q0 106 54.5 176.5t158.5 136.5q27 14 9 31q-186 141 -187 329q0 131 90 215t232 84q135 0 223 -79.5t88 -204.5q0 -88 -43 -153.5t-147 -133.5q-16 -12 -2 -22q125 -102 174 -182.5t49 -182.5q0 -141 -101.5 -234.5t-253.5 -93.5q-147 0 -245.5 88t-98.5 226z M281 289q0 -119 61 -187.5t162 -68.5q86 0 143.5 54t57.5 136q0 94 -60.5 173t-210.5 182q-86 -53 -119.5 -117t-33.5 -172zM307 1030q0 -147 248 -319q59 33 84 69q47 78 47 176q0 113 -53 179.5t-141 66.5q-82 0 -133.5 -48t-51.5 -124z" /> -<glyph unicode="9" horiz-adv-x="1044" d="M98 502q0 184 116 308t290 124q186 0 304 -138.5t118 -349.5q0 -172 -61.5 -311t-172 -234.5t-243 -159t-293.5 -101.5q-20 -4 -33.5 9t-13.5 31.5t16 24.5q393 141 526 373q20 47 -18 37q-82 -20 -137 -21q-168 0 -283 118t-115 290zM276 532q0 -182 67 -282t185 -100 q72 0 148 36q29 14 41 54q33 127 33 266q0 174 -64.5 274.5t-173.5 100.5q-80 0 -139 -50q-96 -76 -97 -299z" /> -<glyph unicode=":" horiz-adv-x="526" d="M156 84q0 45 30.5 73.5t77.5 28.5t78 -28.5t31 -73.5t-31 -74.5t-78 -29.5t-77.5 29.5t-30.5 74.5zM156 717q0 47 30.5 75.5t77.5 28.5t78 -28.5t31 -75.5q0 -45 -31 -74t-78 -29t-77.5 29t-30.5 74z" /> -<glyph unicode=";" horiz-adv-x="471" d="M129 74q0 45 34 75.5t81 30.5q63 0 105 -47t42 -121q0 -96 -64.5 -182t-164.5 -125q-16 -6 -27.5 20.5t6.5 34.5q145 88 146 191q0 29 -15 29q-8 0 -24.5 -3.5t-24.5 -3.5q-39 0 -66.5 30t-27.5 71zM131 713q0 45 31 74.5t78 29.5t78.5 -28.5t31.5 -75.5q0 -45 -31.5 -74 t-78.5 -29t-78 29t-31 74z" /> -<glyph unicode="<" horiz-adv-x="1429" d="M143 672q-6 18 0 51q0 29 25 39q707 313 1069 455q35 14 44 -4.5t9 -59.5v-33q0 -27 -45 -47q-705 -299 -866 -362q-41 -16 4 -35q418 -184 879 -367q29 -12 28 -47v-45q0 -66 -63 -43q-344 127 -1061 455q-23 10 -23 43z" /> -<glyph unicode="=" horiz-adv-x="1429" d="M139 428v49q0 49 58 49q174 -4 1056 -4q39 0 39 -37l-2 -55q-2 -29 -10 -37t-43 -8h-1042q-31 0 -43.5 8t-12.5 35zM145 983q6 25 43 25q33 0 466 1t585 5q31 0 41 -18.5t10 -47.5q0 -4 1 -17.5t1 -21.5q0 -14 -1 -21t-9 -11.5t-14 -4.5h-29h-1034q-47 -6 -58 39z" /> -<glyph unicode=">" horiz-adv-x="1429" d="M141 262q0 35 29 47q553 221 866 361q18 8 26.5 19t-9.5 22q-324 139 -867 362q-37 14 -41 25q-2 8 -2 26v37q0 41 13.5 53.5t38.5 2.5q481 -199 1058 -451q35 -16 35 -43q6 -33 2 -51q0 -18 -7 -27.5t-36 -23.5q-387 -174 -1042 -447q-61 -27 -62 43q0 8 -1 23.5 t-1 21.5z" /> -<glyph unicode="?" horiz-adv-x="741" d="M86 1260q0 113 197 112q168 0 273.5 -110.5t105.5 -284.5q0 -203 -148 -303q-59 -41 -147 -74q-86 -29 -86 -86q0 -53 88 -158q2 -4 -2.5 -11t-10.5 -9q-12 -4 -32.5 1t-28.5 15q-109 129 -109 230q0 74 38 117.5t128 78.5q135 49 183.5 99.5t48.5 132.5t-53.5 127 t-151.5 45q-31 0 -82 -7.5t-78 -7.5q-133 0 -133 93zM197 78q0 49 34.5 80.5t85.5 31.5q53 0 87 -30.5t34 -81.5q0 -49 -33.5 -81t-87.5 -32q-51 0 -85.5 32t-34.5 81z" /> -<glyph unicode="@" horiz-adv-x="1966" d="M246 565q0 362 238.5 612t584.5 250q281 0 460 -168.5t179 -439.5q0 -254 -148.5 -439t-349.5 -185q-141 0 -141 133q0 39 2 63q4 20 -10 8q-6 -8 -10 -14q-29 -35 -90 -92q-109 -98 -207 -98q-72 0 -118 62t-46 153q0 113 60.5 242.5t158.5 232.5q139 143 264 143 q94 0 135 -72q12 -20 25 13q0 4 2 11t3 10t2 8.5t3 7.5t4 5t4 5t6.5 4t8.5 3t10 2t12 1q18 2 86 2q20 0 21 -22q0 -2 -56.5 -181.5t-88 -297t-36.5 -169.5q-4 -80 56 -79q45 0 102.5 34.5t102.5 87.5q72 88 115.5 203t43.5 230q0 229 -158.5 377.5t-398.5 148.5 q-305 0 -518 -236.5t-213 -580.5q0 -301 185.5 -487.5t478.5 -186.5q231 0 406 115.5t274 339.5q8 18 14 22t25 4q4 0 10 -1t10 -1q16 -4 10 -29q-84 -244 -287.5 -384t-465.5 -140q-328 0 -544 217t-216 553zM745 436q0 -49 26 -81.5t63 -32.5q98 0 221 163q53 72 86 170 q39 123 39 193q0 53 -28 86t-71 33q-68 0 -135 -78q-80 -96 -140.5 -231.5t-60.5 -221.5z" /> -<glyph unicode="A" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17q2 -8 2 -17t-2 -17q-5 -18 -17 -18 q-131 6 -286 6q-124 0 -263 -4q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 28q7 11 7 27q0 22 -13 55q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-53 -3 -131 -3t-182 3q-23 0 -49 -35q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55 q14 0 36 2t40 0q14 -2 14 -39q-4 -35 -14 -35q-171 3 -282 3t-162 -3h-23q-22 4 -22 33q0 12 4 28zM535 727q-1 -2 -1 -4q0 -15 25 -27q64 -2 126.5 -2t121.5 2q10 0 15 10q3 6 3 12q0 5 -2 9q-68 188 -125 373q-4 10 -13 13q-2 1 -4 1q-6 0 -9 -8q-39 -127 -137 -379z" /> -<glyph unicode="B" horiz-adv-x="1343" d="M43 27.5q0 33.5 14 38.5q39 6 49 2q133 0 164 31.5t31 172.5v783q0 150 -26.5 179.5t-151.5 29.5h-47q-16 0 -14.5 33.5t14.5 35.5l18 2q154 16 584 17q127 0 184.5 -11.5t134.5 -46.5q82 -39 130.5 -109.5t48.5 -154.5q0 -88 -53.5 -157.5t-143.5 -102.5q-16 -6 4 -16 l41 -21q231 -112 231 -325q0 -141 -90 -255t-223 -141q-109 -21 -228 -21q-24 0 -48 1q-162 3 -314 3t-293 -3q-16 2 -16 35.5zM500 360q0 -109 10 -163q23 -121 223 -121q133 0 218 92t85 227q0 86 -42 160t-115 117q-31 18 -63 29.5t-70 14.5q-36 3 -60 4h-30h-42 q-48 -1 -69 -1q-45 -8 -45 -43v-316zM500 829q0 -14 6 -24t11 -13.5t7 -3.5q14 0 62 -2h42h30q26 1 66 4t71.5 10t58.5 19q109 45 109 199q0 131 -91 209q-66 53 -165 63q-41 4 -79 4q-53 0 -100 -8q-8 -2 -18 -14t-10 -25v-418z" /> -<glyph unicode="C" horiz-adv-x="1560" d="M115 649q0 315 208.5 514t544.5 199q147 0 336 -70q39 -15 65 -15q22 0 36 11q8 6 27.5 6t21.5 -8q21 -87 21 -157q0 -14 -1 -27q0 -18 -2 -60q-1 -21 -1 -37.5t1 -27.5q-4 -18 -28.5 -23.5t-32.5 7.5q-53 154 -163 239.5t-267 85.5q-248 0 -393.5 -161.5t-145.5 -432.5 q0 -279 160 -463t407 -184q182 0 334 135q41 37 62.5 65.5t60.5 98.5q4 18 43 14q25 -4 23 -16q-49 -170 -144 -328q-27 6 -47 6q-61 0 -160 -30q-88 -29 -235 -29q-324 0 -527.5 194.5t-203.5 493.5z" /> -<glyph unicode="D" horiz-adv-x="1583" d="M25 1296q2 30 16 33l14 4q406 16 602 17q201 0 332 -34t240 -112q248 -178 248 -495q0 -231 -140.5 -420t-363.5 -252q-150 -43 -404 -43l-491 -2q-39 0 -45 18q-7 17 -7 29q0 22 23 31q14 2 41 3t35 1q18 2 32.5 6t26 9t19.5 16.5t13 17.5t9 22.5t6 22.5t3.5 26.5 t1.5 25.5v27.5v26.5v781q0 137 -26 174t-151 37h-18q-16 0 -16 25v5zM434 209q0 -80 32 -114t128 -34q305 0 483 151t178 464q0 152 -56 279.5t-155 203.5q-68 53 -138 78t-191 37q-68 6 -143 6q-45 0 -93 -2q-45 -4 -45 -47v-1022z" /> -<glyph unicode="E" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q335 2 563.5 2t350.5 -2q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23 q-20 125 -57 156.5t-164 33.5q-118 4 -193 4q-50 0 -81 -2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q2 -40 2 -106q0 -99 -4 -258q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 128t-149 24 l-235 2q-29 -8 -29 -33v-344q0 -119 21.5 -142.5t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-3 8 -3 18q0 9 2 19z" /> -<glyph unicode="F" horiz-adv-x="1112" d="M82 26q2 32 18 35q88 4 117 32t29 110v921q0 82 -32 111t-116 33q-4 2 -8 9t-4 16.5t1 18.5t6 15q4 4 9 5q2 0 4 -1h883q12 0 23.5 -12.5t9.5 -22.5l-6 -225q-12 -7 -27 -7t-35 7q-4 104 -43 133t-182 29h-248q-27 0 -35 -33l-2 -401q0 -12 10.5 -23.5t18.5 -13.5 q39 -2 83 -2t97.5 1t81.5 1q115 2 145.5 18.5t39.5 89.5q2 20 26 25q31 4 33 -16v-367q-4 -12 -29.5 -12t-27.5 12q-10 100 -43 126q-31 24 -135 24h-17q-58 -2 -117 -2t-118 2q-45 -4 -46 -41v-418q0 -82 32 -111t122 -29h21q16 -4 16 -36q0 -15 -4 -25q-3 -9 -10 -8h-2 q-171 2 -300 2t-217 -2q-23 0 -23 26q1 3 1 6z" /> -<glyph unicode="G" horiz-adv-x="1562" d="M117 639q0 152 61.5 293t171.5 244q106 100 222 145t276 45q131 0 338 -61q45 -12 63 -13q25 0 41 17q16 4 47 0q7 -2 7 -90.5t-7 -264.5q-2 -18 -32.5 -19t-32.5 15q-68 342 -391 342q-254 0 -397.5 -171t-143.5 -468q0 -274 141.5 -444t374.5 -170q125 0 266 63 q25 10 25 68q0 14 -1 60t-1 85t2 62q0 82 -33 107.5t-125 29.5l-80 2q-10 0 -16 17.5t-2 35t18 19.5q101 -3 243 -3t323 3q22 0 22 -21q0 -6 -2 -14q-2 -12 -8 -23.5t-12 -9.5q-74 -2 -100.5 -32.5t-28.5 -108.5q-2 -55 -2 -114t2 -120q0 -47 -19 -55q-106 -55 -257.5 -92 t-278.5 -37q-297 0 -485.5 191.5t-188.5 486.5z" /> -<glyph unicode="H" horiz-adv-x="1613" d="M53 8q-5 15 -5 27q0 20 15 31q10 2 52 2q72 4 98.5 32.5t26.5 102.5v921q0 80 -30 109t-110 33q-8 4 -11 20.5t1 30.5t14 14q131 -6 254.5 -6t239.5 6q8 0 20 -8q10 -10 3 -45q-2 -10 -25 -12q-88 0 -122 -33t-34 -109v-374q0 -10 9.5 -20.5t27.5 -10.5q134 -3 292.5 -3 t340.5 3q16 0 38.5 10t22.5 23v372q0 76 -33.5 109t-123.5 33h-41q-20 4 -20 26q0 11 5 27q8 18 37 18q22 1 53 1q77 0 212.5 -4t204.5 -4q28 0 44 1q20 2 28.5 -19.5t-1.5 -37.5q-4 -10 -29 -10q-76 -6 -104.5 -36t-30.5 -104q-4 -139 -4 -316t2 -364.5t2 -240.5 q0 -74 34 -104.5t122 -30.5q39 -1 45 -17q4 -9 4 -18t-3 -19q-7 -20 -26 -20h-581q-25 0 -27 18q-6 18 1 36t24 18h49q84 0 120.5 30.5t36.5 106.5v383q-4 37 -38 37q-144 -6 -308.5 -6t-347.5 6q-10 0 -23.5 -14.5t-13.5 -37.5v-368q0 -80 30 -107.5t116 -27.5h10h10 q14 2 22.5 -15.5t2.5 -37t-25 -21.5h-520q-27 0 -33 14z" /> -<glyph unicode="I" horiz-adv-x="743" d="M106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-26 3 -26 27q0 10 4 24q6 14 28 14q8 0 205 -5q66 -2 117 -2q103 0 149 7h3q29 0 30 -22q6 -43 -10 -43q-4 0 -13.5 -2t-15.5 -2q-94 -2 -117.5 -36t-23.5 -175v-850 q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2q12 -8 14 -26q1 -5 1 -9q0 -13 -4 -23q-5 -14 -13 -14q-127 4 -254 4l-254 -4q-25 0 -25 31z" /> -<glyph unicode="J" horiz-adv-x="663" d="M-184 -465q0 39 26.5 67.5t63.5 28.5q14 0 28.5 -7t36 -25.5t23.5 -20.5q43 -33 51 -37q19 -8 40 -8q18 0 37 7q40 14 64 46q33 49 43.5 130t10.5 298q0 1024 -2 1110q-2 84 -35 112t-123 28q-4 -2 -13.5 0t-11.5 2q-16 2 -19 22.5t5 32.5q6 10 31 10q89 -5 216.5 -5 t293.5 5q22 0 28 -12q4 -9 4 -22v-9q-2 -18 -12 -20q-4 -2 -22 -2q-86 -6 -114 -34t-28 -108v-974q0 -145 -28 -273q-37 -180 -107 -287q-119 -182 -289 -182q-88 0 -143 36t-55 91z" /> -<glyph unicode="K" horiz-adv-x="1515" d="M41 38q4 26 27 34q12 4 38 0q90 0 124 30.5t34 100.5v921q0 82 -32.5 111t-125.5 29h-40q-14 2 -19.5 23.5t2.5 33.5q4 14 29 14q209 -5 359 -5q113 0 192 3q29 0 28 -33q0 -37 -36 -36q-92 0 -125 -29t-33 -111v-430q2 -25 35 -14q39 14 73 47q94 84 215 246t121 241 q0 27 -20.5 35t-95.5 17l-21 2q-25 18 -6 53q4 14 24 10q148 -4 277 -4t238 4q29 2 24 -33q-4 -29 -24 -28q-147 -2 -209 -47q-18 -12 -39 -36t-32 -40.5t-34.5 -52t-27.5 -41.5q-70 -109 -230 -314q-25 -29 -35 -37q39 -16 117 -92q59 -57 116.5 -122.5t131.5 -161 t104 -131.5q68 -80 117 -103.5t145 -23.5q23 -1 29 -13q8 -11 8 -26q0 -5 -1 -9q-3 -22 -23 -26q-37 3 -150 3q-151 0 -438 -5q-23 4 -27 12q-6 12 -3 32.5t18 22.5q80 0 105.5 12.5t25.5 34.5q0 25 -27 60q-14 18 -56 71.5t-60.5 77t-56.5 68.5t-65.5 72.5t-64.5 61.5 t-74 61q-35 25 -71 30q-20 2 -26.5 -5t-6.5 -28v-372q0 -74 33.5 -105.5t124.5 -31.5q33 0 38 -15q12 -27 0 -51q-4 -8 -28 -8q-127 5 -263 5t-280 -5q-33 0 -39 8q-9 9 -9 26q0 6 1 12z" /> -<glyph unicode="L" horiz-adv-x="1218" d="M45 42q4 20 16 24q2 0 8.5 2t8.5 2h8q150 0 164 67q4 45 4 146v841q0 82 -33 112t-125 30h-24q-14 2 -16.5 24.5t5.5 32.5q8 16 31 10q87 -2 198 -2q167 0 388 4q25 0 29 -18q4 -13 4 -24q0 -30 -31 -31q-41 -4 -66 -5q-117 -4 -139 -18t-22 -94v-938q0 -63 26.5 -87 t89.5 -24h193q121 0 168 20.5t119 116.5l71 95q29 10 43 0q11 -6 11 -15q0 -5 -3 -10q-80 -190 -131 -272q-27 -39 -63 -39q-357 6 -596 6q-191 0 -305 -4q-25 -4 -29 18q-4 6 -4 15q0 7 2 15z" /> -<glyph unicode="M" horiz-adv-x="1929" d="M57 49q8 16 25 14h19q40 1 66 7q32 8 47 38.5t19.5 54t8.5 85.5q2 16 2 26q6 96 21.5 281.5t23.5 334t8 281.5q0 47 -22.5 63.5t-90.5 22.5q-28 3 -28 33q0 8 2 17q5 27 30 27q4 0 9 -1q71 -4 154 -4q55 0 114 2q39 0 49 -20l438 -998q6 -12 19.5 0.5t19.5 24.5l420 969 q14 25 51 24q72 -2 139 -2t130 2h9h8t5 -2t5 -5l3 -9q6 -49 -10 -51l-22 -2q-74 -6 -93.5 -24.5t-19.5 -61.5q0 -18 3 -49t3 -37l55 -811q10 -147 35 -179t121 -32q33 0 37 -23v-35q-2 -16 -31 -16q-70 -2 -168 -2q-148 0 -362 4q-14 0 -19 14q-4 18 0 39q0 16 35 17 q111 0 139 43q20 32 20 102q0 26 -3 57q-29 494 -49 795q0 16 -17 -2q-6 -6 -8 -14l-451 -1049q-2 -10 -31.5 -10t-33.5 10l-463 1046q-6 14 -18 13q-6 -2 -7 -8l-47 -764q-4 -82 -4 -103q0 -59 30 -84.5t114 -34.5q23 0 26 -18q8 -29 -4 -41q-2 -2 -24 -8q-81 -2 -187.5 -2 t-238.5 2q-19 4 -19 22q0 13 8 31z" /> -<glyph unicode="N" horiz-adv-x="1708" d="M70 18q-1 8 -1 14q0 16 7 23q10 14 30 15q158 0 158 118v1035q-55 41 -166 43q-8 -2 -12 9t-4 25q0 33 33 33q85 -2 158 -2t135 2q29 0 49 -24l837 -959q12 -18 31 12q4 8 4 17v676q0 88 -4 123.5t-22 52.5q-18 18 -58 24q-33 4 -112 9q-12 0 -18.5 18t-1.5 34.5t20 16.5 q64 -3 166 -3q135 0 337 5q13 0 13 -39v-9q-1 -13 -5 -16q-6 -5 -24 -5q-119 -4 -144.5 -31t-25.5 -145v-1082q0 -27 -36 -31q-8 -1 -14 -1q-23 0 -28 12q-4 4 -72.5 81.5t-192.5 218t-224 255.5l-475 540q-6 4 -11.5 0t-8.5 -15t-3 -28v-755q0 -104 12 -140q20 -66 99 -71 q14 -2 34.5 0t43 -2t26.5 -13q10 -18 5 -41.5t-30 -23.5q-143 3 -253 3q-146 0 -232 -5q-16 -2 -20 26z" /> -<glyph unicode="O" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z " /> -<glyph unicode="P" horiz-adv-x="1181" d="M51 1296q0 35 17 35q147 18 471 19q168 0 272 -27q133 -35 211 -132t78 -224q0 -193 -135.5 -304.5t-374.5 -111.5q-37 0 -103 10q-6 0 -10 -7t-6 -17.5t-4 -20.5v-313q-1 -81 31 -105q29 -22 112 -22h15h71q16 -4 22 -26q5 -22 -2 -42q-6 -18 -19 -18h-3q-151 6 -310 6 q-127 0 -259 -4q-29 0 -37 12q-6 12 -6 27q2 45 61 45q76 0 100.5 14t24.5 70v944q0 100 -20 134q-18 32 -72 32h-6l-102 -2q-6 -2 -10.5 7t-6.5 21zM467 659q0 -27 29 -34q43 -8 79 -9q154 0 231 95.5t77 261.5q0 203 -140 276q-75 40 -178 40q-37 0 -78 -5q-20 -2 -20 -47 v-578z" /> -<glyph unicode="Q" horiz-adv-x="1683" d="M92 643q0 309 213 516t539 207q319 0 514.5 -189.5t195.5 -482.5q0 -240 -139 -429t-368 -265q-6 -2 -8.5 -7t5.5 -11q115 -45 281 -187q96 -82 163 -112.5t163 -34.5q8 -2 8 -9q0 -12 -25 -38q-16 -16 -28 -21q-59 -12 -105 -12q-221 0 -485 225q-131 109 -144 119 q-33 25 -104 51q-305 27 -490.5 215.5t-185.5 464.5zM313 692q0 -281 158 -469t401 -188q145 0 254 94t158 227.5t49 276.5q0 293 -148.5 476t-398.5 183q-213 0 -343 -167t-130 -433z" /> -<glyph unicode="R" horiz-adv-x="1425" d="M41 10q-4 8 -4 19t4 24q6 16 61 17q92 0 124 25.5t32 107.5v71v781q0 150 -26.5 179.5t-170.5 31.5q-8 0 -14 13t-3 30.5t17 23.5l21 2q133 14 487 15q178 0 263.5 -28t166.5 -101q113 -102 113 -256q0 -113 -56.5 -208t-148.5 -143q-18 -6 -4 -26q14 -25 55 -93.5 t66 -103.5l115 -172q33 -49 55.5 -72.5t73.5 -64.5q47 -37 110 -49q20 -14 20 -31q0 -10 -7 -20l-13 -9q-10 0 -30.5 -2t-30.5 -2q-121 0 -186.5 33t-116.5 92q-68 80 -174 246q-39 63 -82 143q-2 4 -8.5 15.5t-11.5 18.5t-11 16.5t-14 13.5t-17 4q-106 -13 -168 -13 q-15 0 -28 1q-14 0 -27.5 -10.5t-13.5 -22.5q0 -197 2 -303q2 -82 31.5 -107.5t121.5 -25.5q4 0 14.5 2t17.5 2t15.5 -1t14.5 -5.5t8 -12.5q6 -27 2 -45q-2 -6 -13 -11t-16 -5h-63q-137 0 -526 -4q-20 6 -27 20zM459 655q0 -41 20 -41q51 -3 90 -3q75 0 111 12 q100 35 155.5 124.5t55.5 202.5q0 162 -75 249t-267 87q-90 0 -90 -47v-584z" /> -<glyph unicode="S" horiz-adv-x="1050" d="M115 328q0 10 12 14t27.5 3t19.5 -7q31 -94 63.5 -145.5t90.5 -90.5q86 -59 172 -59q117 0 187.5 65.5t70.5 165.5q0 29 -5 54.5t-20.5 52.5t-27 45t-39 44t-40 38t-48 36.5t-45 32t-48.5 33t-43 27.5q-74 49 -117.5 83t-97 86t-78 111.5t-24.5 129.5q0 141 100.5 230 t263.5 89q66 0 170 -35q57 -18 76 -18q12 0 33 18q27 8 47 0q12 -31 39 -278q-2 -20 -26.5 -20.5t-28.5 9.5q-98 250 -291 250q-96 0 -149.5 -51t-53.5 -135q0 -100 117 -203q49 -45 154.5 -116.5t176 -124t129 -140.5t58.5 -186q0 -164 -116.5 -269.5t-305.5 -105.5 q-68 0 -213 43q-51 14 -61 14q-16 0 -31 -22q-23 -10 -53 0q-25 84 -45 332z" /> -<glyph unicode="T" horiz-adv-x="1394" d="M70 1014q8 168 32 352q14 12 32 12h5q21 -2 25 -12q16 -35 115 -35q148 3 359 3t484 -3q18 -1 33 -1q45 0 59 5q18 6 27 31q6 10 28.5 8t33.5 -8l32 -354q0 -4 -1 -8.5t-4 -6.5t-6 -3t-7 -2t-8 -1q-12 0 -19.5 1t-11.5 7.5t-5 9.5t-3 13q-25 127 -54.5 169t-85.5 42h-299 q-10 0 -19 -13.5t-9 -23.5v-273v-376v-273v-71q0 -80 31.5 -103.5t123.5 -23.5h60q18 0 29 -27q6 -18 0 -39q-6 -16 -33 -16q-102 4 -237 4q-169 0 -390 -6q-20 0 -25 14q-8 25 0 49q8 14 27 19q66 0 78 -2q78 0 106.5 31.5t28.5 113.5v57v926q0 10 -16.5 21.5t-30.5 11.5 h-236h-43q-57 0 -87.5 -46t-57.5 -186q-10 -6 -24.5 -7t-25.5 4.5t-11 15.5z" /> -<glyph unicode="U" horiz-adv-x="1669" d="M48 1314q3 16 18 17q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q32 83 32 272v11v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q114 2 240 2t266 -2q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v535q0 82 -30 103.5t-146 23.5 q-10 0 -16 16q-4 10 -3 21q0 5 1 11z" /> -<glyph unicode="V" horiz-adv-x="1558" d="M49 1274q-3 9 -3 17q0 12 5 24q4 16 35 16q138 -4 272 -4t265 4q41 0 45 -6q16 -20 4 -45q-2 -10 -25 -20q-106 -4 -150 -18.5t-44 -47.5q0 -20 34 -111l318 -788q2 -4 7 -10t13.5 -13.5t16.5 -3.5t14 21l299 776q29 76 29 123q0 41 -35 60.5t-131 19.5h-17 q-12 4 -16 23.5t2 31.5q4 8 29 8q120 -4 239 -4t238 4q14 0 18 -6q7 -9 7 -21q0 -6 -1 -12q-4 -20 -18 -22q-88 -2 -130 -43t-93 -172l-412 -1065q-4 -10 -17 -24.5t-22 -14.5q-14 -3 -30 -3q-21 0 -43 5q-18 0 -31 33l-440 1099q-47 119 -79 144.5t-128 27.5q-18 4 -25 17z " /> -<glyph unicode="W" horiz-adv-x="2224" d="M35 1317q2 14 39 14q132 8 272 8q120 0 246 -6q16 0 13 -31.5t-13 -35.5h-19q-68 0 -85 -11.5t-17 -46.5q0 -33 39 -129l324 -813q2 -8 9 -15t17 -3t21 28l182 449q8 18 -2 47l-146 350q-39 96 -72.5 119t-148.5 27q-14 4 -16 34.5t18 30.5q83 2 300.5 2t568.5 -2 q23 0 19.5 -31.5t-15.5 -35.5q-113 -2 -150 -25.5t-76 -120.5l-102 -250q-10 -33 0 -57l236 -563q4 -8 11 -10t16 7t16 25l313 826q32 90 32 127q1 13 -3 19q-14 24 -123 28q-12 2 -14.5 18.5t5 30.5t17.5 12q63 -3 148 -3q114 0 268 5h1q17 0 21 -32q0 -33 -24 -33 q-90 0 -129 -33t-84 -152l-422 -1105q-6 -16 -66 -16q-2 0 -4 -1q-55 0 -63 12l-244 584q-2 8 -7 12t-12.5 0t-15.5 -22l-233 -574q-7 -16 -57 -16h-12q-60 2 -69 23l-417 1073q-39 102 -67 141t-62.5 50t-122.5 14q-20 0 -31 6q-14 7 -14 24q0 12 6 27zM1069 1239 q0 -12 14 -55q4 -8 78 -178q2 -4 4 -4q3 0 9 6q8 10 12 20l53 129q27 64 27 80q0 29 -56 29q-24 -3 -46 -3t-40 3q-55 0 -55 -27z" /> -<glyph unicode="X" horiz-adv-x="1607" d="M55 1274q-2 8 -2 17q1 11 5 23q8 20 32 19q137 -6 270 -6q155 0 306 8q29 0 34 -16q8 -18 -1 -35.5t-31 -17.5q-86 -2 -113 -10.5t-27 -28.5q0 -10 8.5 -25.5t17.5 -28t22.5 -30t17.5 -21.5l211 -282q16 -23 41 12q207 274 237 319q23 34 23 56q0 38 -70 39h-49 q-31 0 -38 20.5t5 32.5q8 12 35 12q112 -4 218 -4q133 0 257 6q16 -2 22.5 -19.5t0.5 -32.5t-21 -15q-123 -6 -199.5 -67.5t-170.5 -186.5l-199 -264q-6 -10 2 -29l361 -471q88 -115 116 -135q53 -39 178 -54q19 -1 19 -34q0 -29 -21 -29q-69 3 -179 3q-147 0 -367 -5 q-29 0 -35 10q-6 14 -3 34.5t15 20.5h21q109 0 108 43q-2 27 -65 113l-261 354q-6 4 -19 0t-22 -14l-286 -358q-49 -66 -49 -95q0 -43 125 -43h18q14 0 20.5 -16t2 -32.5t-18.5 -16.5q-221 4 -351 4q-86 0 -132 -2q-18 0 -18.5 35t20.5 35q88 6 139 27.5t96 80.5 q6 8 20.5 27.5t30 39t31.5 40.5l297 376q4 4 6 15.5t-2 15.5l-299 385q-96 125 -142 152.5t-167 29.5q-27 0 -31 19z" /> -<glyph unicode="Y" horiz-adv-x="1490" d="M32 1278q-1 7 -1 13q0 8 2 16q2 12 8 19q5 5 11 5h3q197 -3 335 -3t216 3q8 0 17.5 -16.5t4.5 -31.5t-28 -15q-127 0 -127 -41q0 -29 64 -127l274 -422q8 -10 26.5 -1t28.5 28l219 370q66 109 66 137q0 31 -23.5 42.5t-93.5 11.5h-20q-18 8 -16 38q1 27 19 27h3 q89 -3 203.5 -3t253.5 3q18 0 18 -31q0 -35 -18 -34q-104 -6 -170 -74q-31 -33 -107 -160l-303 -514v-107.5v-128v-79.5q0 -59 25.5 -92t89.5 -41q8 0 32.5 1t34.5 -3q25 -6 25 -41t-25 -35q-244 4 -401 4q-105 0 -172 -2q-16 0 -22.5 21.5t-0.5 37.5q8 20 43 21q10 2 31 0 t25 -2q109 6 114 131q6 86 6 166q0 64 -4 125l-374 585q-72 113 -120 147t-143 38q-25 0 -29 14z" /> -<glyph unicode="Z" horiz-adv-x="1443" d="M74 31q0 14 10 30l877 1143q10 14 -4.5 21.5t-26.5 7.5h-438q-156 0 -197 -34t-59 -185q0 -6 -12.5 -8t-27 3t-18.5 15q0 201 10 287q4 14 45 20h975q33 0 46.5 -15.5t-3.5 -47.5l-868 -1123q-8 -8 -11 -17t10 -19.5t50 -10.5h520q156 0 212.5 58.5t72.5 218.5l2 20 q4 6 20.5 10.5t30 2t13.5 -8.5q-8 -211 -27 -379q-4 -24 -58 -24h-4q-63 0 -293.5 -1t-357.5 -1q-438 0 -448 2q-10 0 -19.5 2t-16.5 11q-5 7 -5 16v6z" /> -<glyph unicode="[" horiz-adv-x="690" d="M213 -428q-12 895 0 1788q0 29 9 40t36 13q63 6 262 0q37 0 37 -14v-31q0 -16 -16 -16q-123 -10 -140 -19q-25 -14 -24 -61q-8 -834 0 -1604q0 -41 16.5 -52t91.5 -17l50 -5q14 -2 18 -5t4 -17v-23q0 -18 -39 -18q-86 -6 -258 0q-47 4 -47 41z" /> -<glyph unicode="\" horiz-adv-x="980" d="M82 1350q-16 31 59 30h43h12.5h10.5t7 -1t7 -2t5 -5t6.5 -9t7.5 -13l653 -1332q20 -43 -16 -47l-86 -10q-27 -4 -41 27q-2 4 -5 6z" /> -<glyph unicode="]" horiz-adv-x="702" d="M66 -428q0 16 10 22.5t35 4.5h26q74 6 91.5 17t17.5 54q8 772 0 1606q0 47 -25 59q-12 6 -84 13l-55 4q-16 0 -16 16v31q0 14 24 14h12h263q27 -2 36 -12t9 -41q14 -1022 0 -1788q0 -37 -48 -41q-172 -6 -258 0q-39 0 -38 18v23z" /> -<glyph unicode="^" horiz-adv-x="1005" d="M46 710.5q1 10.5 11 26.5q227 408 428 719h45q256 -418 428 -727q23 -37 -20 -41l-41 -4q-35 -4 -55 35q-152 270 -314 528q-23 37 -41 6q-113 -174 -321 -542q-14 -27 -53 -27q-4 0 -21.5 1t-24 3t-14.5 7t-7 15.5z" /> -<glyph unicode="_" horiz-adv-x="1071" d="M-20 -383q0 8 6 12t21.5 5t30.5 0t40.5 -2t46.5 -1h805q4 0 34.5 1t53 1h39.5q41 0 41 -24v-60q0 -20 -21 -24h-43h-977q-78 0 -77 37v55z" /> -<glyph unicode="`" horiz-adv-x="712" d="M143 1307q-10 10 0.5 24.5t28.5 14.5l158 2q29 0 39 -17q59 -156 100 -334q2 -18 -18.5 -22t-32.5 8q-109 141 -275 324z" /> -<glyph unicode="a" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q20 -4 20 -24q0 -11 -6 -27q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM241.5 106.5q32.5 -32.5 80.5 -32.5q33 0 91 37.5t70 70.5v152v11 t-2 15.5t-6 14.5q-2 2 -4.5 2t-5.5 -2q-47 -23 -146 -64q-110 -45 -110 -124q0 -48 32.5 -80.5z" /> -<glyph unicode="b" horiz-adv-x="1005" d="M16 1371.5q0 23.5 15 27.5l250 84q12 4 20.5 4t12.5 -4q8 -8 5 -35q-3 -106 -3 -271t3 -389q6 -47 17 -49q2 0 4 2q4 4 23.5 17.5t27.5 19.5t27.5 19.5t31 19.5t30 16.5t32.5 16.5t30.5 11t32 8t29.5 3q137 0 232.5 -120.5t95.5 -288.5q0 -213 -130 -353.5t-335 -140.5 q-104 0 -281 39q-16 6 -20 37q3 254 3 546.5t-3 622.5q0 20 -1 45t-1 29q-2 33 -45 39q-14 2 -44 7t-44.5 9.5t-14.5 28zM317 444q0 -180 17 -247q16 -63 65.5 -102.5t120.5 -39.5q115 0 186.5 96.5t71.5 252t-71.5 254t-180.5 98.5q-66 0 -207 -103q0 -4 -1 -78.5 t-1 -130.5z" /> -<glyph unicode="c" horiz-adv-x="864" d="M51 395q0 205 144.5 347.5t351.5 142.5q100 0 172 -37t72 -94q0 -33 -21.5 -54.5t-52.5 -21.5q-53 0 -127 72q-57 57 -117 57q-102 0 -180 -108.5t-78 -256.5q0 -158 80 -257t203 -99q147 0 241 137q10 31 35 25q6 -2 8 -4t4.5 -6.5t4.5 -8.5q7 -5 7 -14q0 -10 -10 -25 q-137 -215 -362 -215q-162 0 -268.5 119t-106.5 301z" /> -<glyph unicode="d" horiz-adv-x="1050" d="M47 391q0 205 132 344t329 139q72 0 170 -32q8 -2 15 14t7 37q3 68 3 170.5t-3 241.5q-10 29 -16 32q-12 8 -30.5 10.5t-44 3.5t-36.5 3q-20 4 -22 14q-4 20 -2 29q4 16 20 18q143 45 258 88q8 3 13 3q8 0 14 -6q8 -11 8 -34v-1226q0 -82 10.5 -99.5t45.5 -17.5 q8 0 45 12q2 0 11 3t14 4t12.5 1t12.5 -4t7 -12q5 -16 5 -26q0 -16 -11 -21q-137 -68 -277 -103q-14 -6 -23 0.5t-12.5 19.5t-3.5 25.5t2 26.5v17q0 14 -6 25t-16 5q-184 -127 -289 -127q-143 0 -242.5 124t-99.5 298zM211 455q0 -158 72.5 -263.5t181.5 -105.5q88 0 213 84 q16 8 20 47v420q-109 156 -235 156q-113 0 -182.5 -93.5t-69.5 -244.5z" /> -<glyph unicode="e" horiz-adv-x="876" d="M53 414q0 201 120 333t300 132q207 0 295 -181l16 -34q12 -31 41 -66q3 -9 3 -21q0 -5 -1 -11q-2 -18 -28 -19q-79 -3 -216 -3t-333 3q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t219 -103.5q143 0 254 131q10 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142 q-115 -88 -242 -88q-162 0 -270.5 129t-108.5 316zM229 627q-1 -5 11 -9q14 -6 22 -6h307q16 0 33.5 6.5t15.5 18.5q-23 84 -73.5 131t-116.5 47q-199 0 -199 -188z" /> -<glyph unicode="f" horiz-adv-x="657" d="M35 756.5q0 27.5 10 34.5q94 20 154 55q0 8 4 110q6 125 35.5 204t109.5 165q150 164 322 164q57 0 125.5 -24.5t97.5 -67.5q6 -9 6 -23q0 -20 -41 -86q-14 -20 -29.5 -22t-24.5 3t-30 21q-98 80 -196 80q-63 0 -115.5 -37t-73.5 -98q-29 -79 -29 -189v-14l2 -141 q0 -41 31 -41h152q25 0 28 -19l15 -92q-4 -16 -25 -16l-174 2q-10 0 -18.5 -9t-8.5 -18v-436q0 -143 20 -168q18 -24 107 -24h15h69q23 -2 27 -43q0 -33 -18 -33q-156 5 -285 5t-231 -5q-16 0 -17 33q0 16 4 22q6 14 37 14q72 0 90.5 38t18.5 169v426q-6 29 -25 33h-129 q-10 0 -10 27.5z" /> -<glyph unicode="g" horiz-adv-x="989" d="M55 -287q0 70 31 115t94 86q8 6 16.5 11t17.5 10.5t15 9.5q10 8 14.5 19t-3.5 16q-143 51 -144 151q0 41 86 88q14 8 34 19.5t30 17.5l8 6q10 6 15 12.5t1 8.5q-161 81 -161 252q0 147 99 245.5t245 98.5q137 0 217 -86h16q41 0 186 22q23 4 30 -1t9 -28q7 -60 7 -92v-8 q-4 -27 -21 -27q-27 0 -127 15q-4 2 -13 -5t-7 -12q18 -45 18 -102q0 -137 -98.5 -224t-247.5 -87q-41 0 -84 12q-4 -6 -57 -53q-39 -33 -39 -53q0 -14 8 -24.5t68.5 -22t177.5 -11.5q229 -4 323 -47q105 -47 105 -188q0 -156 -159 -262.5t-380 -106.5q-115 0 -222.5 63.5 t-107.5 161.5zM205 -231q-2 -78 87 -127.5t206 -49.5q102 0 203.5 66.5t101.5 142.5q0 72 -50.5 106t-177.5 44q-49 4 -123.5 4t-113.5 2q-4 -8 -27 -31q-106 -106 -106 -157zM260 582q0 -123 52.5 -195t131.5 -72q78 0 125 61t47 167q0 117 -54 192.5t-134 75.5 q-72 0 -120 -65.5t-48 -163.5z" /> -<glyph unicode="h" horiz-adv-x="1077" d="M41 57q2 2 43 11q70 4 88 38.5t18 163.5v936l-2 78q0 45 -51 53q-14 2 -41.5 5.5t-42.5 5.5q-12 2 -14 26.5t14 30.5q92 37 262 86q6 2 11 2q10 0 16 -6q10 -10 10 -41v-631q0 -14 7.5 -29.5t17.5 -9.5q82 51 143.5 74.5t143.5 23.5q172 0 217 -145q23 -68 26 -227 q0 -49 -4 -139.5t-4 -96.5q-4 -90 -4 -135q0 -39 23.5 -50t105.5 -11q20 0 24.5 -8t6.5 -33q1 -6 1 -11q0 -22 -14 -22q-75 -1 -163 -1h-91q-141 1 -182 1q-33 0 -33 35q-4 33 17 32h12q72 0 96.5 19.5t30.5 77.5q14 123 14 280q0 135 -11 188.5t-42 88.5q-49 53 -127 53 q-39 0 -78 -13.5t-56 -22.5t-67 -40q-10 -6 -10 -22v-490q0 -78 21.5 -98.5t89.5 -20.5q29 0 31 -16q0 -18 2 -27q0 -12 -8 -20q-6 -6 -13 -6h-4q-26 1 -77.5 1t-128 -1t-129.5 -1t-83 1h-2q-7 0 -12 10t-5 24q0 19 7 29z" /> -<glyph unicode="i" horiz-adv-x="544" d="M41 12v9.5v8.5v11q0 11 8 17q10 8 23 10q10 2 21 0t22 0q63 8 76.5 36.5t13.5 151.5v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5q16 6 74 28.5t104 39t72 22.5q23 10 34 0t14.5 -21.5t3.5 -31.5v-590q0 -78 2 -106q2 -55 19 -67.5t83 -12.5 q10 4 22.5 -4.5t14.5 -18.5q0 -2 -1 -9t-1 -11q0 -33 -29 -33q-136 3 -238.5 3t-170.5 -3q-18 0 -23 16zM152 1255q0 45 30.5 76t75.5 31q49 0 80 -30t31 -77q0 -45 -33 -74.5t-80 -29.5t-75.5 29.5t-28.5 74.5z" /> -<glyph unicode="j" horiz-adv-x="505" d="M-219 -381q0 43 21.5 76t52.5 33q33 0 84 -62q56 -65 118 -65h2q68 0 99.5 57t31.5 188v127v658q0 66 -3 81t-17 23q-18 10 -57 17q-12 4 -35 8t-29 6q-8 4 -8 25.5t8 25.5q115 49 254 94q23 8 34 -6t11 -35v-819q0 -135 -7 -197.5t-34 -125.5q-31 -72 -84 -129 q-90 -98 -241 -99q-88 0 -144.5 34t-56.5 85zM127 1235q0 45 33 74.5t80 29.5q49 0 79.5 -29.5t30.5 -74.5t-31.5 -76t-78.5 -31q-49 0 -81 31t-32 76z" /> -<glyph unicode="k" horiz-adv-x="1060" d="M31 1367q0 24 12 28q59 14 131 43.5t109 40.5q9 2 16 2q29 0 29 -37l2 -873q0 -31 41 -6l217 158q53 39 53 49q0 25 -92 25q-25 12 -23 37q2 16 7.5 22t21.5 6q54 -1 114 -1q121 0 267 3q20 0 20 -33q0 -35 -12 -34q-133 -2 -252 -95q-143 -106 -217 -157q-14 -14 8 -37 q246 -254 371 -379q41 -41 66.5 -55.5t74.5 -14.5h21q10 -4 13 -20q1 -7 1 -13q0 -10 -2 -18q-4 -14 -12 -14q-92 5 -203 5t-242 -5q-16 0 -16 35q0 20 5 25t26 5q71 0 71 28q0 13 -47 65l-264 280q-12 8 -14 -12q-2 -8 -2 -21v-145q0 -143 14 -168t96 -25h25q16 0 16 -34 q0 -15 -4 -25q-3 -9 -10 -8h-2q-110 2 -214.5 2t-203.5 -2q-14 0 -14 33q-2 23 3 29.5t27 6.5q74 0 89.5 32t15.5 175v904q0 70 -2 108q-2 31 -70 45q-6 2 -11 3l-10 2t-10.5 2t-8.5 2l-6 2t-5 1h-2q-12 4 -12 28z" /> -<glyph unicode="l" horiz-adv-x="536" d="M37 12q-4 13 -4 23q0 20 16 28h23q80 0 102.5 26t22.5 110v1077q0 31 -33 37q-18 4 -52 10t-51 8q-12 4 -14 27.5t14 30.5q137 35 271 86h3q10 1 17 -13q8 -16 8 -30v-1231q0 -92 16.5 -115t90.5 -23q37 0 39 -12v-7v-10v-7q0 -33 -25 -33q-56 -2 -115 -2q-60 0 -120 2 q-81 3 -136 3q-28 0 -49 -1q-4 0 -13 5t-11 11z" /> -<glyph unicode="m" horiz-adv-x="1662" d="M35 8q-3 8 -3 16q0 12 5 25q6 14 45 14q68 4 88 40t20 167v293q0 145 -6 154q-10 23 -84 33l-47 6q-12 2 -10 26.5t10 28.5q88 41 269 88q5 1 9 1q10 0 15 -7q6 -10 6 -31v-121q2 -20 27 -2q199 139 321 140q70 0 122 -40t75 -110q4 -14 23 0q72 51 105.5 72.5t100 49.5 t121.5 28q135 0 189 -123q30 -70 30 -274v-13q0 -55 -4 -161.5t-4 -162.5q0 -49 24.5 -63t112.5 -14q6 2 19.5 1t19.5 -6q9 -4 9 -23q0 -6 -1 -15q0 -13 -6 -23q-5 -9 -11 -8h-3q-58 2 -171.5 2t-283.5 -2q-20 0 -26 12q-6 10 -4 31.5t18 21.5h21q66 0 88 20.5t28 86.5 q10 139 11 287q0 190 -31 255.5t-115 65.5q-76 0 -250 -119v-473q0 -76 22.5 -99.5t90.5 -23.5q16 0 21.5 -6t7.5 -24q0 -12 -6.5 -23.5t-14.5 -11.5q-154 4 -276 4q-82 0 -150 -2q-18 0 -20 27.5t16 35.5q4 2 27 2q80 0 101.5 35t21.5 174v334q0 80 -37 125t-101 45 q-82 0 -258 -119v-473q0 -78 22.5 -100.5t100.5 -22.5q14 4 19 0q14 -4 14 -36q-2 -11 -8 -21q-5 -9 -11 -8h-2q-100 4 -208.5 4t-225.5 -4q-14 0 -18 14z" /> -<glyph unicode="n" horiz-adv-x="1056" d="M33 40q4 20 18 19h12q72 0 94.5 39t22.5 174v281q0 150 -8 166q-8 18 -80 33l-41 8q-10 2 -10 26.5t10 28.5q33 6 119 43t123 45q10 2 17 2q30 0 30 -37v-112q0 -6 7 -18.5t15 -6.5q96 68 170 105q86 41 144 41q227 0 227 -369q0 -61 -8 -184t-8 -187q0 -47 16.5 -60.5 t85.5 -13.5q18 12 33 -6q6 -11 6 -25q0 -8 -2 -18q-2 -12 -6 -15t-19 -3h-6q-43 0 -193 1h-89q-77 0 -107 -1q-20 0 -25.5 6t-7.5 27q0 35 17 34h14q68 6 93.5 29t31.5 86q12 119 12 361q0 227 -149 227q-96 0 -252 -121v-463q0 -78 22.5 -98.5t102.5 -20.5q14 0 18 -34 q0 -33 -28 -35q-24 1 -72.5 1t-122.5 -1q-49 -1 -87 -1q-77 0 -110 3q-25 0 -28 10q-4 8 -4 19q0 7 2 15z" /> -<glyph unicode="o" horiz-adv-x="1030" d="M51 424q0 197 132 327t329 130q199 0 334 -132q133 -130 133 -321v-6q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM229 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228z" /> -<glyph unicode="p" horiz-adv-x="1030" d="M13 -522q3 22 20 22h18q86 0 108.5 40t22.5 190v848v49q0 39 -9 49t-44 20q-12 4 -35.5 12.5t-36 10.5t-13.5 19.5t5 23.5q2 4 12 14l226 142q22 14 35 14q20 0 20 -31v-127q0 -41 16 -39q2 0 4 2q184 131 291 131q129 0 224.5 -122.5t95.5 -284.5q0 -195 -135.5 -339.5 t-317.5 -144.5q-61 0 -153 29q-12 4 -18.5 -1t-6.5 -32v-243q0 -147 23.5 -185.5t109.5 -38.5h29q31 0 37 -16q8 -29 -2 -47q-6 -12 -27 -12q-46 2 -121 2q-57 0 -131 -1q-103 -2 -158 -2q-36 0 -51 1q-27 0 -33 10t-6 25q0 5 1 12zM342 174q117 -111 236 -111 q102 0 168.5 90.5t66.5 227.5q0 156 -75.5 260t-186.5 104q-86 0 -197 -88q-12 -12 -12 -36v-447z" /> -<glyph unicode="q" horiz-adv-x="1032" d="M63 399q0 199 129.5 336t317.5 137q117 0 233 -59q23 -12 31 4q29 33 55 53q10 6 27 8h3q14 0 22 -10q-14 -55 -15 -153v-90v-891q0 -143 21.5 -188.5t89.5 -45.5h20q14 0 17 -20q2 -7 2 -12q0 -13 -6 -23q-4 -10 -11 -12h-18q-115 4 -229.5 4t-227.5 -4q-39 0 -39 30 q0 33 17 41q14 2 80 2q84 0 106.5 39t22.5 189v327h2q0 2 -1 7.5t-3 14.5t-6.5 13t-8.5 0q-147 -123 -286 -123q-150 0 -247.5 122t-97.5 304zM221 455q0 -160 80 -266.5t197 -106.5q92 0 200 92q9 8 15 37l-2 235q-2 166 -19 218q-23 61 -79 101t-126 40 q-123 0 -194.5 -93.5t-71.5 -256.5z" /> -<glyph unicode="r" horiz-adv-x="716" d="M41 29v17t3 9t8 6h16q74 0 97 38t23 171v394q-6 27 -20 30l-86 33q-31 12 -35 25v6v16q0 18 16 23q25 12 121 45q74 25 123 49q9 4 16 4t11 -3q10 -7 10 -26v-73t2 -70q0 -8 3 -12t5 -3t4 1q61 133 93 149q26 14 60 14q54 0 130 -34q6 -2 18.5 -6t16.5 -5q19 -3 19 -17 q0 -3 -1 -7q-16 -49 -59 -129q-27 2 -76 26q-45 23 -74 23q-68 0 -137 -131q0 -356 2 -410q2 -78 23.5 -98.5t99.5 -20.5h45q14 0 20.5 -27.5t-8.5 -39.5q-2 -2 -28 -2q-164 3 -273 3t-163 -3h-5q-11 0 -15 7q-4 9 -5 28z" /> -<glyph unicode="s" horiz-adv-x="643" d="M70 641q0 111 77.5 180.5t198.5 69.5q78 0 172 -39q6 -82 6 -143q0 -37 -2 -66q0 -10 -28 -10q-12 0 -20.5 3t-6.5 7q-14 82 -55 127t-99 45q-49 0 -80.5 -30.5t-31.5 -77.5q0 -72 123 -162q20 -14 62 -42t72.5 -51.5t55.5 -50.5q70 -76 70 -170q0 -106 -79 -178.5 t-190 -72.5q-53 0 -102 14q-2 0 -17.5 6t-23.5 8q-16 0 -27 -26q-24 -7 -31 -7h-1q-18 2 -21 21q-18 144 -18 219v14q-2 12 10 15.5t31 1.5q10 -4 14 -21q43 -184 180 -184q55 0 94 39t39 92q0 20 -5 39.5t-19.5 39t-23.5 32t-33.5 31t-33 25.5t-37 26.5t-32.5 21.5 q-57 39 -92 67.5t-65.5 79t-30.5 107.5z" /> -<glyph unicode="t" horiz-adv-x="653" d="M43 799q4 8 16 14q117 59 189 260q0 7 13 13q8 3 16 4q5 0 9 -2q12 -4 13 -15q-3 -60 -3 -105.5t3 -74.5q2 -8 10 -17.5t15 -9.5h227q35 0 24 -32q-4 -33 -18 -68q-10 -16 -33 -16l-194 4q-8 0 -18.5 -8.5t-12.5 -16.5v-362q0 -158 28.5 -214.5t102.5 -56.5q66 0 123 109 q2 10 20.5 9t26.5 -11q6 -7 6 -18q0 -9 -4 -21q-84 -186 -240 -187q-96 0 -157.5 72t-61.5 184v84v410q0 18 -12 23h-41q-16 0 -41 6q-9 15 -9 28q0 8 3 15z" /> -<glyph unicode="u" d="M40 820v6q0 16 13 20q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 57 -62 65q-14 4 -26.5 5t-18.5 4q-2 0 -67 10q-12 8 -10.5 28.5t14.5 24.5q209 47 293 55h8 q33 0 33 -32v-652v-63q0 -51 49 -51q17 0 39 6q4 2 13 4t16 4l14 4q12 3 17 -13q3 -9 3 -18q0 -8 -2 -16q-4 -18 -16 -19q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v434q0 35 -8 51.5 t-37 24.5q-14 4 -40.5 11.5t-41.5 11.5q-10 3 -13 25z" /> -<glyph unicode="v" horiz-adv-x="1019" d="M8 826q2 30 20 32q7 1 39 1q46 0 144 -2q70 -1 126 -1q74 0 122 2q12 0 12 -33q0 -31 -16 -30h-19q-47 0 -72.5 -7.5t-29.5 -14.5t-4 -19q0 -14 43 -121t104.5 -250t61.5 -145q2 -2 6 -10.5t7 -11.5t7 -6t8 1t8 14q133 324 197 459q9 19 9 35q1 31 -35 48q-54 26 -119 28 q-8 6 -8.5 34.5t16.5 28.5q83 -2 174 -2t190 2q9 0 13 -16q2 -8 2 -16q0 -7 -1 -14q-3 -15 -9 -15q-66 -8 -96.5 -46t-88.5 -169l-250 -578q-12 -23 -28 -24q-12 -3 -24 -3q-16 0 -32 5q-10 4 -20 30l-266 613q-45 106 -62 127q-27 29 -117 43q-12 2 -12 25v6z" /> -<glyph unicode="w" horiz-adv-x="1542" d="M4 814q-1 7 -1 12q0 11 3 16q4 14 29 10q20 0 76.5 -2t128 -2t166.5 4h10q20 2 24 -16q6 -12 3 -27.5t-15 -15.5q-104 -4 -104 -48q0 -25 88 -247q45 -115 110 -271q4 -10 13.5 -18t17.5 2l184 432v-2q-45 90 -65 111q-33 33 -90 36q-6 0 -18.5 1.5t-20.5 1.5 q-14 0 -15 30q-4 33 11 33q198 -5 305 -5q80 0 110 3q33 4 39 -14q4 -12 2 -27.5t-6 -19.5q-108 -2 -108 -53q0 -28 30 -101l172 -416q6 -10 16.5 -2t14.5 19q166 387 178 454q3 15 3 28q-1 30 -17 44q-24 20 -74 24q-39 0 -59 3q-10 4 -12.5 33.5t16.5 29.5q75 -2 164 -2 t192 2h3q12 0 16 -14q4 -10 4 -20q0 -6 -1 -11q-3 -16 -11 -18q-82 -8 -105 -41q-10 -16 -43 -95q-45 -111 -262 -651q-6 -16 -10 -20t-25 -7q-25 -5 -34 -5q-3 0 -5 1q-14 2 -20 17l-4 10l-222 535q-6 12 -20 -15l-219 -516q-6 -25 -27 -27q-4 -2 -12 -2h-23q-14 0 -18 2 q-12 2 -18 15l-5 10l-249 616q-45 115 -73 141.5t-106 31.5q-10 3 -12 23z" /> -<glyph unicode="x" horiz-adv-x="1069" d="M14 25q0 31 17 30q74 2 114.5 28t124.5 122l183 207l-170 227q-74 100 -114 126t-126 30q-12 5 -11 33q1 27 18 26h3q54 -3 153.5 -3t244.5 3q20 0 22 -4q6 -8 7 -20.5t-2 -22.5t-7 -10h-18q-70 0 -70 -24.5t74 -121.5q55 -74 80 -98q12 -16 20 -17t25 17q45 45 80 90 q55 66 55 105q0 23 -18.5 34t-71.5 13h-8.5h-6.5t-5 3t-5 7q-6 16 -2 37q2 13 17 13q4 0 8 -1q154 -2 251 -2t138 2h4q13 0 20 -10q8 -20 2 -37q-4 -12 -30 -12q-90 -6 -131 -28t-107 -95l-78 -86l-96 -111q117 -150 165 -212t83 -105q43 -55 81 -76t103 -25q17 -10 17 -37 q0 -10 -5.5 -18t-13.5 -6q-92 2 -177 2q-129 0 -245 -4q-18 0 -18 29.5t18 29.5h19q71 0 71 32q0 11 -9 26.5t-24.5 34t-19.5 22.5l-117 156q-31 39 -47 20q-4 -6 -30.5 -33.5t-49 -53.5t-48 -56.5t-41 -54t-15.5 -33.5q0 -27 23.5 -40.5t87.5 -19.5h16q10 0 14 -16.5 t0 -30.5q-4 -12 -12 -12h-2q-103 4 -223 4q-80 0 -168 -2q-12 0 -17 29z" /> -<glyph unicode="y" horiz-adv-x="999" d="M18 840q6 23 41 18h35q78 0 314 4q35 0 38 -16q4 -14 0 -30.5t-12 -18.5q-66 -2 -86 -14.5t-20 -37.5q0 -23 22 -71q43 -94 189 -459q6 -14 28 21q4 4 4 6l123 313q20 51 31 84q18 55 18 84q0 41 -24.5 56.5t-100.5 17.5q-10 6 -11 31.5t18 27.5h16q98 6 178 6 q64 0 117 -4q35 0 39 -18q1 -4 1 -8q0 -9 -3 -20q-4 -15 -10 -15q-63 -8 -101.5 -56.5t-99.5 -210.5l-254 -684q-72 -184 -86 -219q-31 -74 -74 -125q-33 -43 -94 -43q-39 0 -67.5 28t-28.5 64q0 63 102 89q63 16 105.5 72.5t78.5 176.5l29 95l-260 618q-55 133 -82 161 t-100 34q-6 2 -11 16q-3 10 -3 19q0 4 1 8z" /> -<glyph unicode="z" horiz-adv-x="839" d="M31 35q2 6 8 13t8 11l498 678q4 12 -15 19q-17 1 -39 1q-44 0 -109 -3q-97 -4 -138 -4q-43 0 -65.5 -33t-53.5 -158q-4 -10 -20.5 -12t-26.5 4q-16 6 -12 29q51 281 61 325q4 6 30.5 6t26.5 -8q0 -35 14 -45q12 -8 56 -8h18q267 4 396 4h71q35 0 43 -8q8 -33 -4 -47 q-287 -375 -502 -688q-2 -6 7.5 -11.5t17.5 -3.5q68 -6 145 -6t164 6q51 2 75 28t60 112l9 10q8 20 41 12q15 -3 15 -12q0 -2 -1 -4l-84 -230q-6 -12 -23 -16q-167 -4 -331.5 -4t-327.5 4q-13 0 -13 25q0 6 1 14z" /> -<glyph unicode="{" horiz-adv-x="1026" d="M215 459q-6 14 0 26q0 14 14 19q102 20 161 77.5t59 131.5q0 49 -25 153q-23 90 -23 170q0 158 112 276t286 144q12 0 14 -10q8 -29 4 -33q0 -2 -2 -2q-2 -2 -2 -4q-4 -10 -18 -14q-109 -25 -165.5 -86.5t-56.5 -151.5q0 -59 19 -151q23 -117 22 -181q0 -141 -112 -248 q-63 -59 -127 -88q-33 -12 -2 -28q242 -121 241 -338q0 -82 -20 -176q-18 -90 -19 -152q0 -180 226 -244q10 0 16 -10l2 -2q8 -21 0 -39q-6 -10 -20 -8q-176 27 -286 143.5t-110 274.5q0 63 23 164q25 109 25 155q0 78 -58.5 134.5t-167.5 78.5q-10 4 -10 19z" /> -<glyph unicode="|" d="M483 10v1700q0 29 10.5 40t36.5 11q37 -8 60 -4q12 0 18 -1t8 -6t2 -9t-1 -15.5t-1 -19.5v-842q0 -793 -2 -864q0 -45 -45 -45q-23 4 -51 0q-23 0 -29 13.5t-6 41.5z" /> -<glyph unicode="}" horiz-adv-x="1026" d="M217 -485q0 2 1 10t1 12q4 14 14 17q109 23 167.5 85t58.5 150q0 57 -21.5 165.5t-21.5 166.5q0 139 114 250q59 59 127 88q12 6 11.5 15t-13.5 15q-240 121 -239 334q0 53 20.5 163t20.5 165q0 180 -215 242q-8 2 -17.5 12t-7.5 22q0 31 16 29q176 -27 287 -143.5 t111 -274.5q0 -55 -24.5 -159.5t-24.5 -159.5q0 -74 53 -129t153 -80q29 -8 29 -33q0 -35 -24 -39q-98 -23 -153.5 -78t-55.5 -127q0 -55 24.5 -161.5t24.5 -161.5q0 -154 -105.5 -269.5t-271.5 -146.5q-14 -4 -27.5 2t-11.5 19z" /> -<glyph unicode="~" horiz-adv-x="1161" d="M49 518q6 143 90 237.5t205 94.5q106 0 279 -94q2 0 24.5 -13.5t26.5 -15.5t25.5 -13.5t29.5 -14.5t26.5 -11t30 -11t26.5 -8t29.5 -6t28.5 -1q145 0 177 169q4 27 24 27l23 -2q12 -2 20 -9t6 -13q-10 -147 -91 -243.5t-198 -96.5q-115 0 -294 96q-6 4 -52.5 28.5t-69 35 t-59.5 22.5t-65 12q-68 0 -116 -48t-58 -130q-4 -27 -31 -23q-10 2 -17.5 4.5t-13.5 9.5t-6 17z" /> -<glyph unicode="¡" horiz-adv-x="557" d="M162 776q0 47 33.5 80t85 33t85 -32t33.5 -81q0 -51 -33.5 -84t-85 -33t-85 33t-33.5 84zM176 -426l76 948q4 10 27.5 10t27.5 -10l82 -950q4 -47 -8 -64.5t-64 -17.5h-65q-53 0 -66.5 17.5t-9.5 66.5z" /> -<glyph unicode="¢" horiz-adv-x="915" d="M98 389q0 207 145.5 352.5t352.5 145.5q10 0 59 -4l101 262q8 14 26 12q2 0 10.5 -1t11.5 -1t8 -2t7 -5t2 -8t-2 -14l-100 -256q127 -38 127 -118q0 -33 -22.5 -54.5t-57.5 -21.5q-37 0 -76 33q-25 25 -35 -2l-227 -570q-12 -35 34 -48t87 -13q76 0 130 34.5t114 106.5 q12 16 26 8l21 -12q16 -10 -4 -41q-143 -209 -363 -209q-41 0 -86 10q-23 6 -33 -20q-94 -256 -116 -299q-12 -27 -33 -25l-31 6q-12 2 -6 19l4 8l123 309q10 31 -10 43q-84 55 -135.5 156.5t-51.5 218.5zM262 436q0 -162 90 -268q12 -16 25 10l237 600q-37 29 -88 29 q-106 0 -185 -108.5t-79 -262.5z" /> -<glyph unicode="£" horiz-adv-x="1630" d="M31 -416q0 57 76.5 129t175.5 113q61 109 110 240l13 32q4 8 -2.5 18.5t-18.5 10.5h-238q-29 0 -30 2q-12 4 -6 25q0 4 2 10q2 12 3 17t5 11.5t12 8.5t21 2h290q18 49 70.5 193.5t83.5 221.5q94 244 186 400q242 414 541 414q104 0 184 -48t80 -118q0 -33 -23.5 -55.5 t-58.5 -22.5q-43 0 -90 47q-14 12 -26 27q-72 72 -148 71q-94 0 -168 -100q-80 -104 -168 -328q-195 -481 -278 -663q-16 -37 10 -39h8l271 2h26q25 0 19 -27l-7 -26q-4 -29 -47 -29l-338 4q-76 -154 -153 -254q88 41 200 41q92 0 168 -35t162 -98q80 -61 135 -92 q74 -43 142 -43q74 0 126 43t52 104q0 33 -33 90q-27 45 -27 72q0 37 25 61.5t59 24.5q47 0 78 -44t31 -110q0 -143 -126 -255.5t-284 -112.5q-119 0 -217 63q-31 20 -92 70q-6 6 -42 34.5t-54 43.5q-121 90 -207 90q-63 0 -156 -43l-6 -4q-55 -113 -124.5 -182.5 t-127.5 -69.5q-29 0 -49 18.5t-20 44.5z" /> -<glyph unicode="¤" horiz-adv-x="1429" d="M207 272l133 134q-57 88 -75.5 145t-18.5 149q0 90 18.5 146.5t75.5 134.5l-133 133l92 96l135 -135q74 59 131.5 79t151.5 20q96 0 152.5 -19.5t136.5 -79.5l129 135l94 -96l-131 -133q57 -82 76.5 -140.5t19.5 -152.5q0 -96 -19.5 -152.5t-76.5 -129.5l131 -134 l-94 -94l-129 133q-82 -59 -138.5 -78.5t-153 -19.5t-151.5 19.5t-129 78.5l-135 -133zM379 694.5q0 -143.5 98 -245t238 -101.5q143 0 243.5 100.5t100.5 244t-99.5 244.5t-238.5 101q-141 0 -241.5 -100t-100.5 -243.5z" /> -<glyph unicode="¥" horiz-adv-x="1071" d="M-6 1409q0 4 2 8v6q-2 18 18 19q238 -8 445 2q23 0 22 -29q6 -16 0 -24q0 -18 -10 -21h-6q-113 -8 -113 -53q0 -10 19 -55l53 -132q8 -20 53 -20h232q29 0 39 25l45 110q20 53 20 74q0 43 -76 49q-43 8 -43 27v22q0 18 23 19h8q188 -8 336 2q20 2 20 -25v-24v-9 q0 -10 -18 -10q-57 0 -90 -29.5t-74 -123.5l-37 -87q-10 -20 33 -20h154q31 0 30 -29v-41q0 -33 -30 -32h-211q-27 0 -35 -21l-64 -139q-6 -12 5.5 -21.5t27.5 -9.5l281 4q27 -8 26 -26v-52q0 -29 -41 -28l-303 2q-29 0 -41 -2q-14 0 -20 -13l-37 -84v-360q0 -127 23.5 -161 t101.5 -34h22q31 0 31 -26v-25q0 -16 -5 -19t-28 -1q-258 14 -499 0q-12 0 -20.5 6t-6.5 14l2 27q2 23 27 22h18q90 0 112.5 32t22.5 165v338l-45 100q-8 20 -28 21h-15h-315q-37 0 -37 33v49q0 23 41 22l252 -4q20 0 32.5 6t6.5 25l-56 131q-12 29 -32 29h-213 q-31 0 -31 28v47q0 27 35 27h147q10 0 21.5 8t7.5 17l-39 92q-33 82 -65.5 110.5t-90.5 32.5q-14 0 -16 21q-4 4 -4 18zM485 985l84 -205q4 -12 13.5 -12t17.5 16l80 199q8 25 -12 25h-166q-27 0 -17 -23z" /> -<glyph unicode="¦" d="M483 -45v778h133v-778h-133zM483 981v780h133v-780h-133z" /> -<glyph unicode="§" horiz-adv-x="1005" d="M109 881q0 225 145 388t344 163q45 0 107.5 -15.5t119 -52.5t56.5 -84q0 -35 -28 -62.5t-62 -27.5q-41 0 -91 49q-4 4 -9 8t-10 10.5t-7 8.5q-74 78 -139 77q-76 0 -129.5 -48t-53.5 -115q0 -18 7.5 -44t22.5 -55.5t29.5 -55.5t38 -60.5t37 -54t37 -51.5t27.5 -38 q170 -242 234.5 -355.5t95.5 -225.5q22 -88 22 -201q0 -211 -147.5 -367.5t-345.5 -156.5q-104 0 -188.5 43t-84.5 104q0 33 24.5 61.5t57.5 28.5q12 0 22.5 -4t18.5 -8t18.5 -13.5t14.5 -14.5t15 -17t14 -17q74 -80 157 -79q70 0 126.5 48t56.5 107q0 88 -119 252 q-207 287 -314 475q-121 213 -120 400zM246 1090q-88 -231 51 -508q57 -111 189 -305.5t184 -286.5q53 -96 67 -137q6 -16 17 -11q12 6 18 23q25 63 25 153q0 172 -74 330q-39 76 -82 144q-47 70 -98 147q-76 111 -146 219q-96 147 -123 232q-10 25 -16 22q-6 -4 -12 -22z " /> -<glyph unicode="¨" horiz-adv-x="712" d="M53 1108q0 51 36 87t87 36t87 -36t36 -87t-36 -87t-87 -36t-87 36t-36 87zM416 1108q0 51 35.5 87t87 36t88.5 -36t37 -87t-37 -87t-88.5 -36t-87 36t-35.5 87z" /> -<glyph unicode="©" horiz-adv-x="1630" d="M86 713q0 305 215 522t518 217t518 -216t215 -523q0 -305 -215 -522.5t-518 -217.5t-518 217.5t-215 522.5zM172 713q0 -270 189.5 -462t457.5 -192t457.5 192t189.5 462q0 272 -189.5 462.5t-457.5 190.5t-457.5 -190.5t-189.5 -462.5zM340 707q0 209 149.5 348 t370.5 139q76 0 191 -39q25 -8 34 -8q14 0 21.5 8t19.5 39h41q18 0 21 -23l18 -239v-35q0 -14 -14 -14h-33q-12 0 -16 12q-2 2 -4 12.5t-6 16.5q-76 201 -285 200q-143 0 -229.5 -103t-86.5 -284q0 -199 85 -305t241 -106q184 0 299 149q16 20 29 12l31 -16q16 -9 0 -29 q-152 -203 -394 -202q-205 0 -344 134t-139 333z" /> -<glyph unicode="ª" horiz-adv-x="557" d="M47 942q0 94 146 127q76 18 139 51v97q0 104 -90 104q-29 0 -56 -21q-16 -18 -16 -28l8 -33l-112 -51q-10 29 -11 35q0 45 88 108q66 49 127 49q94 0 135 -44t41 -144v-170v-57q0 -55 27 -56q20 0 70 33l14 -39q-96 -80 -147 -80q-61 0 -74 70q-4 -2 -8 -6t-9 -6 q-74 -57 -137 -58q-59 0 -97 33t-38 86zM160 956q0 -29 19.5 -47t47.5 -18q27 0 66 27.5t39 50.5v100q-39 -16 -66 -27q-72 -29 -89 -44t-17 -42z" /> -<glyph unicode="«" horiz-adv-x="759" d="M63 471l320 410h63l-206 -410v2l206 -405h-63zM362 471l256 375h58l-137 -375l139 -367h-60z" /> -<glyph unicode="¬" horiz-adv-x="1429" d="M145 881v137h1145v-645h-135v508h-1010z" /> -<glyph unicode="­" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="®" horiz-adv-x="1630" d="M63 713q0 313 219.5 534t528.5 221t528.5 -221t219.5 -534q0 -311 -219.5 -532.5t-528.5 -221.5t-528.5 221t-219.5 533zM152 712.5q0 -276.5 192.5 -471t466.5 -194.5t468 194.5t194 471t-194 471t-468 194.5t-466.5 -194.5t-192.5 -471zM393 266v29q0 16 25 16 q55 2 69.5 23.5t14.5 107.5v549q0 86 -12.5 106.5t-63.5 24.5q-20 0 -20 19v18q0 16 2 19q4 4 26 4q41 -2 110.5 -2t156.5 1t116 1q141 2 230.5 -66.5t89.5 -179.5q0 -166 -203 -236q-20 -4 -6 -24l194 -279q35 -49 57.5 -66.5t57.5 -19.5q12 0 12 -4v-8v-10v-21 q0 -18 -24 -18q-92 4 -166 0q-18 0 -29 14l-297 412h-39q-20 0 -20 -37v-199v-78q0 -49 108 -51q14 0 15 -20v-23v-12q0 -6 -9 -6h-16q-195 10 -354 0q-25 0 -25 16zM674 764q0 -12 3 -16.5t17 -4.5q121 0 186.5 48.5t65.5 132.5q0 82 -55 135t-141 53q-37 0 -76 -12v-336z " /> -<glyph unicode="¯" horiz-adv-x="714" d="M18 1063v92q0 23 43 23h21h575q23 0 32 -6.5t9 -26.5v-90q0 -31 -47 -31h-598q-35 0 -35 39z" /> -<glyph unicode="°" horiz-adv-x="849" d="M98 1053q0 139 95.5 236t232.5 97t233.5 -97t96.5 -236q0 -137 -96.5 -234.5t-233.5 -97.5t-232.5 97t-95.5 235zM209 1053q0 -90 63.5 -154.5t153.5 -64.5t154.5 64.5t64.5 154.5q0 92 -64.5 156.5t-154.5 64.5t-153.5 -64.5t-63.5 -156.5z" /> -<glyph unicode="±" horiz-adv-x="1429" d="M145 -2v45q0 27 6.5 36t32.5 7q53 -4 425 -4t640 4q25 0 33 -8t8 -33v-53q0 -31 -20 -37q-12 -6 -49 -6q-233 -2 -1020 -2q-39 0 -49 10q-2 4 -7 16v25zM145 836v55v20q0 8 2 13q6 8 33 8h438q20 0 25.5 5t5.5 24v407q0 6 -1 14.5t-1 12.5q0 47 29 47h80q18 0 23 -7.5 t5 -37.5v-443q-4 -23 21 -22h442q29 0 36 -7t7 -28v-63q0 -27 -9 -32t-40 -5h-426h-16q-6 0 -8 -2q-6 -4 -7 -21v-442q0 -31 -6 -36t-37 -5q-35 -10 -61 0q-25 0 -31 10l-2 6v6t1 8.5t1 10.5v438q0 16 -6 21.5t-22 5.5h-433q-27 0 -35 6t-8 33z" /> -<glyph unicode="²" horiz-adv-x="614" d="M18 633v31q53 63 168 161q2 2 28 22.5t32 27t29.5 27t31.5 31.5t26.5 30.5t26 34t17.5 33t14 36.5t4 37q0 47 -36.5 81t-92 34t-99.5 -36t-65 -100q-4 -10 -37.5 -9t-33.5 13q10 109 84.5 172.5t183.5 63.5q104 0 177 -57.5t73 -147.5q0 -18 -4 -37.5t-8.5 -34t-15.5 -31 t-16 -26.5t-23.5 -26.5t-23.5 -22.5t-27.5 -22.5t-27 -19.5t-30 -20.5t-27.5 -19.5q-74 -49 -151 -119q-6 -4 4 -8q12 -4 22 -4h176q66 0 78 8q6 6 12 19q0 4 4.5 18t6.5 27q2 10 24 10h15q36 0 36 -12q-27 -166 -28 -166h2q-6 -14 -33 -15h-475q-20 0 -21 17z" /> -<glyph unicode="³" horiz-adv-x="614" d="M4 698q0 25 19.5 42.5t46.5 17.5q12 0 27.5 -6.5t24.5 -11.5t26.5 -17t21.5 -14q45 -33 82 -33q55 0 99 49t44 117q0 51 -30.5 86t-69.5 35q-35 0 -72 -27q-35 -20 -55 12q-4 8 -1 22.5t11 18.5q156 100 156 164q0 29 -25.5 50.5t-62.5 21.5q-86 0 -144 -103 q-20 -27 -47.5 -9.5t-21.5 36.5q39 82 105.5 128t148.5 46q76 0 129 -38t53 -99q0 -68 -68 -119q-14 -12 2 -18q63 -20 100.5 -67.5t37.5 -113.5q0 -109 -101.5 -187.5t-230.5 -78.5q-78 0 -141.5 26.5t-63.5 69.5z" /> -<glyph unicode="´" horiz-adv-x="714" d="M242 991l100 336q14 27 39 27h180q12 2 21.5 -3.5t7.5 -15.5v-6l-2 -4l-293 -352q-10 -12 -34.5 -8t-18.5 26z" /> -<glyph unicode="¶" horiz-adv-x="960" d="M-18 940q0 193 127 301.5t350 110.5q453 0 489.5 2t36.5 -29v-37q0 -25 -35 -24h-78q-27 0 -26 -37v-1704q0 -23 -5 -28t-30 -5h-33q-35 0 -35 31l2 1706q0 33 -36 33h-105q-27 0 -26 -29l2 -1716q0 -25 -33 -25h-43q-20 0 -25.5 6t-5.5 27v979q0 31 -37 30 q-160 2 -257 53.5t-150 151.5q-47 88 -47 203z" /> -<glyph unicode="·" horiz-adv-x="526" d="M156 575.5q0 45.5 31.5 78t76.5 32.5t77 -32t32 -79q0 -45 -32 -77.5t-77 -32.5t-76.5 32.5t-31.5 78z" /> -<glyph unicode="¸" horiz-adv-x="714" d="M211 -266l170 286h57l-57 -106q-4 -8 -4 -12q2 -2 6 -3t6 -1q59 -8 98 -54.5t39 -109.5q0 -80 -56 -136.5t-136 -56.5q-47 0 -86 15q-23 8 -8 30q6 12 8 15q4 12 18 8q31 -6 45 -6q43 0 73 28.5t30 67.5q0 74 -58 74q-29 0 -129 -52q-8 -4 -15 -0.5t-1 13.5z" /> -<glyph unicode="¹" horiz-adv-x="614" d="M100 1149q141 84 209 166q4 6 45 6t41 -12v-586q0 -23 4 -29q4 -8 25 -10q23 0 33 2q18 0 26.5 -1t16.5 -11.5t8 -28.5q0 -33 -14 -33q-166 6 -330 0q-16 0 -16.5 33t16.5 33l59 6q25 4 32 10t7 27l-2 426q-2 12 -4 14q-23 -14 -63 -35q-29 -12 -62 -24 q-20 -2 -30.5 16.5t-0.5 30.5z" /> -<glyph unicode="º" horiz-adv-x="737" d="M63 1102q0 119 87.5 198.5t218.5 79.5t220 -79.5t89 -198.5t-89 -199t-216 -80q-133 0 -221.5 80t-88.5 199zM188 1141q0 -111 59.5 -186.5t141.5 -75.5q70 0 116 54t46 138q0 106 -60.5 181t-140.5 75q-70 0 -116 -52t-46 -134z" /> -<glyph unicode="»" horiz-adv-x="759" d="M86 104l137 367l-137 375h61l252 -375l-252 -367h-61zM315 68l207 405v-2l-207 410h64l321 -410l-321 -403h-64z" /> -<glyph unicode="¼" horiz-adv-x="1464" d="M100 1149q145 88 211 166q4 6 46 6t42 -12v-588q0 -23 5.5 -30t25.5 -9h31q27 2 39 -5t12 -34q0 -33 -14 -33q-170 6 -332 0q-18 0 -19 33q4 33 17 33l63 4q23 2 29 9t6 30v426q-2 14 -4 14q-31 -20 -63 -33q-41 -16 -64 -26q-20 0 -30.5 18.5t-0.5 30.5zM194.5 -55.5 q-4.5 14.5 4.5 24.5l968 1370l4 9q4 4 13 4h8h84q4 0 6 -4.5t1 -11.5t-5 -15l-971 -1374q-10 -16 -28 -17h-66q-14 0 -18.5 14.5zM856 188v5v4v32l363 463q35 10 59 4q20 -4 18 -24v-389q0 -10 23 -11h80q25 0 24 -34v-17q0 -4 1 -10t1 -8t-1 -7.5t-3 -7.5q-4 -12 -26 -12 h-76q-18 -4 -23 -16v-168q0 -27 -16 -27h-49q-33 0 -43 4q-27 4 -29 17l2 172q-4 14 -24 18h-252q-29 0 -29 12zM1004 289q-10 -16 8 -17h125q24 1 24 11v172q0 16 -2 24q0 12 -8 4z" /> -<glyph unicode="½" horiz-adv-x="1464" d="M100 1149q145 88 211 166q4 4 29 6t43 -2q16 -2 16 -33v-565q0 -23 6.5 -31t26.5 -10h31q18 2 26.5 0t15.5 -10.5t7 -26.5q4 -33 -14 -33q-170 6 -332 0q-18 0 -19 33q4 33 17 33l80 4q18 2 18 39v405q0 8 -1 14.5t-6 11.5t-15 1q-12 -8 -45 -25q-41 -16 -64 -26 q-20 0 -30.5 18.5t-0.5 30.5zM189 -50q1 7 4 9l974 1380q8 12 21 13h12h70q8 0 11 -9.5t-3 -21.5l-971 -1374q-8 -14 -26 -17h-15h-55q-10 0 -16.5 6.5t-5.5 13.5zM872 2v31q55 66 170 162q127 106 164 161q43 59 43 117q0 49 -35.5 83t-91.5 34q-119 0 -164 -135 q-4 -10 -37.5 -10.5t-33.5 12.5q10 109 85 173t183 64q104 0 177 -58t73 -149q0 -25 -6 -47t-12.5 -38.5t-22.5 -37t-25.5 -30.5t-33 -29.5t-31.5 -26t-37 -27t-35 -24.5q-72 -47 -151 -116q-10 -6 4 -11q12 -4 22 -4h176q66 0 78 8q6 6 12 21q8 33 11 43q2 12 24 12h15 q37 0 37 -14q-27 -166 -29 -166h2q-6 -14 -33 -14h-475q-23 0 -23 16z" /> -<glyph unicode="¾" horiz-adv-x="1464" d="M35 692q0 25 20.5 42.5t46.5 17.5q29 0 101 -52q43 -31 80 -30q55 0 99 48t44 116q0 53 -29.5 87.5t-70.5 34.5q-35 0 -72 -26q-20 -20 -35 -4q-10 10 -18 26q-10 20 8 31q156 98 156 164q0 31 -25 51.5t-64 20.5q-88 0 -141 -105q-8 -10 -43 0t-26 29q35 82 102.5 128 t148.5 46q76 0 130.5 -38t54.5 -99q0 -63 -68 -121q-18 -12 2 -17q135 -43 135 -182q0 -106 -100 -185t-229 -79q-78 0 -142.5 26.5t-64.5 69.5zM194.5 -55.5q-4.5 14.5 2.5 18.5l970 1376q8 12 47 13h43q12 0 17.5 -14.5t-2.5 -24.5l-965 -1366q-14 -18 -39 -19l-55 2 q-14 0 -18.5 14.5zM799 197v2v2v28l362 463q33 10 58 4q23 -4 20 -24v-389q0 -10 21 -11h81q16 0 23 -16q6 -15 6 -33q0 -47 -18 -47h-92q-16 -4 -21 -16l2 -168q-6 -27 -20 -27h-52q-35 0 -47 4q-18 2 -20 17l2 172q-6 16 -25 18h-252q-10 0 -20 6t-8 15zM944 278.5 q2 -6.5 8 -6.5h131q21 1 21 11v192q0 12 -2 14q-4 2 -8 -6l-148 -194q-4 -4 -2 -10.5z" /> -<glyph unicode="¿" horiz-adv-x="759" d="M82 -115q0 201 145 303q53 37 148 72q86 33 86 88q0 33 -14.5 59.5t-65.5 86.5q-18 20 4 30q14 6 34.5 2t29.5 -16q106 -131 106 -229q0 -74 -38 -118t-126 -79q-137 -51 -186 -100.5t-49 -131t53 -129t151 -47.5q31 0 82.5 7.5t77.5 7.5q135 0 135 -88q0 -113 -196 -113 q-168 0 -272.5 109.5t-104.5 285.5zM303 776q0 47 35 80t86 33t86 -32t35 -81q0 -51 -35 -84t-86 -33q-53 0 -87 33t-34 84z" /> -<glyph unicode="À" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM510 1763q-10 10 1 24.5t30 14.5l155 2q31 0 39 -16q54 -139 103 -334q0 -18 -20.5 -22.5t-33.5 8.5q-109 141 -274 323zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373 q-4 10 -13 13t-13 -7q-39 -127 -137 -379z" /> -<glyph unicode="Á" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373q-4 10 -13 13t-13 -7q-39 -127 -137 -379zM608 1448l103 336q6 27 37 26l180 2q8 0 15 -2t11 -6t2 -12q0 -8 -2 -10l-292 -352 q-10 -12 -35 -8.5t-19 26.5z" /> -<glyph unicode="Â" horiz-adv-x="1456" d="M29 55q2 12 20 13q90 0 117 30q18 20 43 78q2 6 31 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h8q92 0 105 -20q106 -281 191 -505t132 -349t60 -160q41 -106 59 -160q27 -74 53.5 -97.5t93.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -547 2 q-18 0 -25 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h96q61 2 78 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-106 -6 -319 0q-8 0 -15.5 -4.5t-10.5 -7.5t-9 -12t-8 -11q-45 -145 -129 -355q-18 -45 -18 -69q0 -27 26.5 -40t91.5 -15q8 0 35 2t39 0 q14 -2 14 -39q-4 -35 -14 -35q-342 6 -444 0h-23q-31 6 -18 61zM434 1442l182 319q8 12 27 21q12 2 72.5 3t81.5 -1q27 -2 34 -21l181 -311q14 -25 -2 -27q-29 -8 -41 5l-250 212l-236 -212q-18 -16 -43 -3q-10 6 -6 15zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5 t1 21.5q-68 188 -125 373q-2 10 -12 13t-14 -7q-39 -127 -137 -379z" /> -<glyph unicode="Ã" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM373 1434q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182.5t-146 -71.5q-82 0 -198 80q-84 59 -121 60q-31 0 -47.5 -20.5 t-28.5 -76.5q0 -4 -2 -15t-4 -21q-6 -14 -28.5 -16.5t-26.5 16.5zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373q-4 10 -13 13t-13 -7q-39 -127 -137 -379z" /> -<glyph unicode="Ä" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM422 1564.5q0 51.5 36 87.5t87 36t88 -36t37 -87.5t-37 -87t-88 -35.5t-87 35.5t-36 87zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373q-4 10 -13 13t-13 -7q-39 -127 -137 -379z M784 1564.5q0 51.5 36 87.5t87 36q53 0 89 -36t36 -87.5t-35.5 -87t-89.5 -35.5q-51 0 -87 35.5t-36 87z" /> -<glyph unicode="Å" horiz-adv-x="1456" d="M29 55q2 12 18 13q92 0 119 30q14 16 41 78q25 61 33 84l385 1047l-15 53q-2 4 1 7t9.5 5t13.5 3t16 1h15.5h14.5h6q92 0 107 -20q106 -281 191 -505t132 -349t60 -160q20 -53 57 -160q27 -74 54.5 -97.5t94.5 -23.5h15q12 0 17 -17t0 -34.5t-17 -17.5q-236 10 -549 2 q-16 0 -23 16q-2 6 -2 25q0 20 8.5 26.5t28.5 6.5h94q63 2 80 27.5t-6 82.5q-25 66 -70 187.5t-69 187.5q-4 12 -23.5 20.5t-34.5 6.5q-109 -6 -319 0q-10 0 -16.5 -4.5t-10.5 -7.5t-9 -11t-7 -12q-53 -174 -131 -355q-16 -39 -16 -69q0 -53 116 -55q14 0 36 2t40 0 q14 -2 14 -39q-4 -35 -16 -35q-340 6 -442 0h-23q-31 6 -18 61zM504 1624q0 88 61.5 149.5t149.5 61.5q84 0 145.5 -61.5t61.5 -149.5t-61.5 -149.5t-145.5 -61.5q-88 0 -149.5 61.5t-61.5 149.5zM535 727q-4 -18 24 -31q129 -4 248 0q10 0 15 9.5t1 21.5q-68 188 -125 373 q-4 10 -13 13t-13 -7q-39 -127 -137 -379zM600 1624q0 -47 34 -81t81 -34q45 0 77.5 34t32.5 81t-32.5 81t-77.5 34q-47 0 -81 -34t-34 -81z" /> -<glyph unicode="Æ" horiz-adv-x="1873" d="M-115 48q4 9 33 11q68 8 112 46t109 147l510 852q53 88 58 98q8 14 8 33q0 29 -19.5 39t-87.5 10q-16 0 -23 3t-5 13l2 29q4 18 26 19q145 -4 550 -1t480 1q51 0 52 -25q2 -41 9 -138.5t9 -125.5v-19q0 -8 -10 -8h-31q-6 0 -11 3t-8 10.5t-5.5 11.5t-4.5 13t-2 11 q-20 96 -45.5 131t-70.5 35h-58h-323q-51 0 -52 -37v-434q0 -33 46 -33l237 5q37 0 78 4q31 2 47 14q31 23 47 115q6 23 23 22h10h12h6q18 0 19 -31q0 -322 2 -368q2 -29 -17 -29q-16 -6 -34 -2q-16 0 -19 25q-12 100 -40.5 123.5t-129.5 21.5l-248 -4q-39 0 -39 -53v-342 q0 -104 27 -128t125 -24q45 -4 213 0q100 4 134 14.5t65 49.5q47 61 69 149q0 2 1 7t3 7v5q0 4 2 4q0 6 17 6h26q21 0 21 -39q-2 -47 -27 -266q-2 -37 -59 -37h-1059q-33 0 -31 22v21q0 29 48 28l63 -2q160 -6 162 142l2 73v207q0 37 -29 37h-395q-27 0 -41 -24l-166 -273 q-47 -78 -47 -108q0 -57 131 -58q25 0 25 -18l2 -29q2 -12 -4.5 -17t-20.5 -5q-33 0 -129 2t-176 2t-127 -4q-20 0 -23 24q-8 27 -4 36zM516 651q-8 -10 1 -19t32 -9h305q35 0 35 55v516q0 33 -12 43q-6 4 -15 -8q-143 -219 -346 -578z" /> -<glyph unicode="Ç" horiz-adv-x="1560" d="M115 649q0 315 208.5 514t544.5 199q147 0 336 -70q72 -27 101 -4q8 6 27.5 6t21.5 -8q25 -104 20 -184q0 -18 -2 -60.5t0 -64.5q-4 -18 -28.5 -23.5t-32.5 7.5q-53 154 -163 239.5t-267 85.5q-248 0 -393.5 -161.5t-145.5 -432.5q0 -279 160 -463t407 -184 q182 0 334 135q41 37 62.5 65.5t60.5 98.5q4 18 43 14q25 -4 23 -16q-49 -170 -144 -328q-27 6 -47 6q-61 0 -160 -30q-94 -29 -227 -29l-53 -98q-4 -8 -4 -13q2 -2 6 -3t6 -1q59 -8 98 -54t39 -109q0 -80 -56 -136.5t-136 -56.5q-47 0 -86 14q-23 8 -9 31q6 12 9 14 q4 12 18 9q31 -6 45 -7q43 0 73 29t30 68q0 74 -58 73q-29 0 -129 -51q-8 -4 -15 -1t-1 14l166 280q-305 14 -493.5 205.5t-188.5 480.5z" /> -<glyph unicode="È" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM422 1763q-8 10 2 24.5t29 14.5l157 2q29 0 39 -16q66 -184 101 -334q0 -18 -20.5 -22.5 t-31.5 8.5q-115 152 -276 323z" /> -<glyph unicode="É" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM522 1448l101 336q6 27 36 26l183 2q8 0 14 -2t10 -6t4 -12q0 -2 -1 -5t-3 -5l-293 -352 q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Ê" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM348 1442l180 319q8 12 27 21q12 2 72.5 3t81.5 -1q27 -2 34 -21l181 -311q14 -25 -2 -27 q-29 -8 -41 5l-250 212l-236 -212q-18 -16 -43 -3q-8 6 -4 15z" /> -<glyph unicode="Ë" horiz-adv-x="1267" d="M50 45q5 23 19.5 25t88.5 2q100 4 125.5 37.5t25.5 164.5v779q0 131 -25.5 169t-133.5 38h-9.5h-9.5h-9t-8 1t-7.5 3t-8.5 6t-6 8q-6 12 8 43q6 10 35 10q670 4 914 0q39 0 38 -20q8 -66 11.5 -121t4.5 -99t3 -61q-4 -20 -49 -6q-14 2 -15 23q-20 125 -57 156.5 t-164 33.5q-197 6 -274 2q-12 0 -25.5 -16.5t-13.5 -28.5v-414q0 -16 9 -29.5t20 -13.5h241q121 0 147.5 20.5t41.5 131.5q4 14 45 10q10 -2 16 -31q4 -100 -2 -364q0 -27 -25 -29q-35 -4 -36 10q-16 106 -44 129t-149 23h-235q-29 -4 -29 -31v-344q0 -119 21.5 -142.5 t132.5 -23.5h163q115 0 155 9.5t67 39.5q49 59 75 166q4 18 21 23q37 4 43 -8q0 -66 -6 -124.5t-13.5 -112.5t-9.5 -64q-4 -29 -82 -29q-729 0 -999 -2q-20 4 -25 14q-6 14 -1 37zM348 1565q0 47 34 81.5t83 34.5q47 0 82 -34.5t35 -81.5q0 -49 -34 -83t-83 -34t-83 34 t-34 83zM692 1565q0 47 35 81.5t82 34.5q51 0 85 -33.5t34 -82.5t-34 -83t-85 -34q-47 0 -82 35t-35 82z" /> -<glyph unicode="Ì" horiz-adv-x="743" d="M106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-37 4 -22 51q6 14 28 14q8 0 205 -5t266 5q31 1 33 -22q6 -43 -10 -45q-4 0 -13.5 -1t-15.5 -1q-94 -2 -117.5 -36t-23.5 -175v-850q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2 q12 -8 14 -25.5t-3 -32t-13 -14.5q-254 8 -508 0q-25 0 -25 31zM143 1763q-10 10 0.5 24.5t28.5 14.5l158 2q29 0 39 -16q59 -156 100 -334q2 -18 -18.5 -22.5t-32.5 8.5q-109 141 -275 323z" /> -<glyph unicode="Í" horiz-adv-x="743" d="M106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-37 4 -22 51q6 14 28 14q10 0 206 -5t265 5q31 1 33 -22q6 -43 -10 -45q-4 0 -13.5 -1t-15.5 -1q-94 -2 -117.5 -36t-23.5 -175v-850q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2 q12 -8 14 -25.5t-3 -32t-13 -14.5q-254 8 -508 0q-25 0 -25 31zM242 1448l100 336q14 27 39 26l180 2q8 0 15.5 -2t11.5 -6t2 -12v-6l-2 -4l-293 -352q-10 -12 -34.5 -8.5t-18.5 26.5z" /> -<glyph unicode="Î" horiz-adv-x="741" d="M68 1442l180 319q8 12 26 21q12 2 73 3t81 -1q27 -2 35 -21l180 -311q14 -25 -2 -27q-29 -8 -41 5l-250 212l-235 -212q-18 -16 -43 -3q-8 6 -4 15zM104 25q0 12 6.5 25t12.5 13q96 8 118.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-106.5 35q-37 4 -22 51 q6 14 28 14q8 0 205 -5t268 5q31 1 33 -22q6 -41 -10 -45q-6 0 -15.5 -1t-13.5 -1q-94 -2 -118.5 -37t-24.5 -174v-850q0 -80 29.5 -106.5t111.5 -28.5q23 0 31 -2q12 -8 15 -25.5t-2 -32t-13 -14.5q-256 8 -508 0q-27 0 -27 31z" /> -<glyph unicode="Ï" horiz-adv-x="743" d="M55 1564.5q0 51.5 36 87.5t87 36t87 -36t36 -87.5t-36 -87t-87 -35.5t-87 35.5t-36 87zM106 25q0 39 19 38q94 8 116.5 32t26.5 108l2 71v779l-2 71q-2 82 -24.5 109t-104.5 35q-37 4 -22 51q6 14 28 14q8 0 205 -5t266 5q31 1 33 -22q6 -43 -10 -45q-4 0 -13.5 -1 t-15.5 -1q-94 -2 -117.5 -36t-23.5 -175v-850q0 -80 28.5 -106.5t112.5 -28.5q23 0 31 -2q12 -8 14 -25.5t-3 -32t-13 -14.5q-254 8 -508 0q-25 0 -25 31zM418 1564.5q0 51.5 35.5 87.5t87.5 36q53 0 89 -36t36 -87.5t-36 -87t-89 -35.5q-51 0 -87 35.5t-36 87z" /> -<glyph unicode="Ð" horiz-adv-x="1628" d="M0 635v72q0 31 39 30h162q16 0 22 6q14 6 15 33v291q0 150 -28 179.5t-153 29.5q-31 0 -30 37q0 35 30 41l168 6q154 6 463 6q203 0 340 -34t246 -113q248 -182 248 -504q0 -233 -143.5 -426t-366.5 -256q-104 -31 -169 -37t-272 -6q-449 0 -522 -2q-8 -2 -16 4t-8 14 q0 41 4 47q8 16 16 17h6h6q2 0 9.5 -1t11.5 -1q92 0 123.5 25.5t34.5 107.5q2 20 2 43.5v42.5v284q0 31 -37 31l-174 -2q-27 4 -27 35zM436 193q0 -100 22.5 -120t145.5 -20q143 0 216 11.5t147 46.5q152 70 241.5 225.5t89.5 343.5q0 156 -56 286t-155 208 q-119 92 -339 114q-111 12 -195 12q-59 0 -86 -2q-31 -12 -31 -47v-479q0 -35 39 -35l293 2q45 0 45 -37v-61q-10 -37 -43 -37l-297 -2q-37 0 -37 -39v-370z" /> -<glyph unicode="Ñ" horiz-adv-x="1708" d="M70 17.5q-4 27.5 6 37.5q10 14 30 15q158 0 158 118v1035q-55 41 -166 43q-8 -2 -12 9t-4 25q0 33 33 33q170 -4 293 0q29 0 49 -24l837 -959q12 -18 31 12q4 8 4 17v676q0 61 -1 87.5t-7 51.5t-18 37q-18 18 -58 24q-33 4 -112 9q-12 0 -18.5 18t-1.5 34.5t20 16.5 q150 -6 503 2q4 0 7.5 -8t4.5 -18.5t1 -12.5q2 -20 -4.5 -25t-24.5 -5q-119 -4 -144.5 -31t-25.5 -145v-1082q0 -27 -36 -31t-42 11q-14 14 -489 555l-475 540q-6 4 -11.5 0t-8.5 -15t-3 -28v-755q0 -104 12 -140q20 -66 99 -71q14 -2 34.5 0t43 -2t26.5 -13q10 -18 5 -41.5 t-30 -23.5q-334 6 -485 -2q-16 -2 -20 25.5zM553 1434q12 276 201 276q82 0 200 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182.5t-145 -71.5q-82 0 -199 80q-84 59 -121 60q-31 0 -47 -20.5t-29 -76.5q0 -4 -2 -15 t-4 -21q-6 -14 -28.5 -16.5t-26.5 16.5z" /> -<glyph unicode="Ò" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M666 1763q-10 10 1 24.5t29 14.5l156 2q31 0 39 -16q53 -139 102 -334q0 -18 -20.5 -22.5t-32.5 8.5q-109 141 -274 323z" /> -<glyph unicode="Ó" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M766 1448l100 336q6 27 37 26l180 2q8 0 15.5 -2t11.5 -6t2 -12q0 -8 -2 -10l-293 -352q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Ô" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t531.5 207q319 0 523 -190.5t204 -481.5q0 -311 -208 -522t-523 -211q-319 0 -527 194.5t-208 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M590 1442l182 319q8 12 27 21q12 2 72.5 3t80.5 -1q23 -2 35 -21l178 -311q14 -25 0 -27q-33 -8 -41 5l-250 212l-235 -212q-18 -16 -43 -3q-10 6 -6 15z" /> -<glyph unicode="Õ" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M502 1434q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182.5t-146 -71.5q-82 0 -198 80q-84 59 -121 60q-31 0 -47.5 -20.5t-28.5 -76.5q0 -4 -2 -15t-4 -21q-6 -14 -28.5 -16.5t-26.5 16.5z " /> -<glyph unicode="Ö" horiz-adv-x="1693" d="M109 639q0 313 207.5 520t533.5 207q319 0 522 -190.5t203 -481.5q0 -311 -208 -522t-521 -211q-319 0 -528 194.5t-209 483.5zM330 692q0 -281 155.5 -468t395.5 -187q131 0 225 48t147.5 134t77 188.5t23.5 225.5q0 289 -155 474t-406 185q-211 0 -337 -167t-126 -433z M543 1564.5q0 51.5 36.5 87.5t88 36t87.5 -36t36 -87.5t-36 -87t-87.5 -35.5t-88 35.5t-36.5 87zM907 1564.5q0 51.5 36 87.5t87 36t88 -36t37 -87.5t-37 -87t-88 -35.5t-87 35.5t-36 87z" /> -<glyph unicode="×" horiz-adv-x="1431" d="M223 227q-33 29 0 60l371 370q31 31 2 62l-360 364q-43 43 -13 72l43 43q27 27 53 0q158 -152 371 -379q23 -20 36 -19t40 23q137 127 342 357q10 14 34.5 20t31.5 0l53 -47q27 -27 -2 -57q-33 -31 -182.5 -183.5t-196.5 -195.5q-33 -25 -4 -53l372 -371q39 -39 9 -64 l-45 -36q-35 -29 -60 -5l-352 359q-43 47 -92 -6q-100 -111 -342 -344q-37 -37 -74 -2z" /> -<glyph unicode="Ø" horiz-adv-x="1742" d="M102 649.5q0 311.5 225.5 522t557.5 210.5q246 0 438 -116q20 -12 43 12l125 152q16 16 37 2l16 -13q20 -14 -8 -47l-121 -137q-16 -18 8 -41q226 -195 226 -494q0 -315 -222.5 -529t-547.5 -214q-227 0 -426 109q-35 18 -60 -11l-153 -182q-23 -27 -39 -12l-8 4 q-6 6 -7.5 8t-6.5 6t-5 7t-1 7.5t1 9.5t6 9l160 178q12 12 12 26.5t-8 20.5q-242 201 -242 512.5zM326 700q0 -240 123 -415q27 -37 53 -6q414 506 710 831q32 26 5 49q-162 150 -392 150q-217 0 -358 -171t-141 -438zM547 225q-23 -29 6 -57q162 -137 362 -137 q252 0 392 202q118 169 118 402q0 250 -122 428q-16 23 -41 -6q-98 -113 -367.5 -427.5t-347.5 -404.5z" /> -<glyph unicode="Ù" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM633 1763q-8 10 2 24.5t29 14.5l157 2q29 0 39 -16q60 -156 101 -334q0 -18 -20.5 -22.5t-31.5 8.5q-115 152 -276 323z" /> -<glyph unicode="Ú" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM733 1448l101 336q6 27 36 26l183 2q8 0 14 -2t10 -6t4 -12v-6l-2 -4l-295 -352q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Û" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM559 1442l180 319q8 12 27 21q12 2 72.5 3t83.5 -1q25 -2 32 -21l181 -311q14 -25 -2 -27q-29 -8 -41 5l-250 212l-236 -212q-16 -16 -41 -3q-10 6 -6 15z" /> -<glyph unicode="Ü" horiz-adv-x="1669" d="M48 1314.5q3 16.5 18 16.5q43 4 234.5 4t317.5 -4q12 0 16.5 -17.5t-0.5 -33.5t-16 -14h-20q-90 0 -121 -29t-35 -113q0 -14 -1 -44.5t-1 -45.5v-399q0 -250 96.5 -394.5t333.5 -144.5q305 0 396 244q33 86 32 283v370q0 172 -32.5 220.5t-151.5 50.5l-14 4 q-16 0 -19.5 31.5t19.5 31.5q227 4 506 0q18 0 18 -30.5t-18 -32.5q-119 -4 -154 -52.5t-35 -214.5v-376q0 -100 -3 -152.5t-18.5 -124.5t-52 -127t-98.5 -108q-92 -82 -184 -117t-238 -35q-393 0 -534 307q-31 70 -39 128.5t-8 207.5v533q0 84 -30 105.5t-146 23.5 q-10 0 -15.5 16t-2.5 32.5zM543 1564.5q0 51.5 36.5 87.5t88 36t87.5 -36t36 -87.5t-36 -87t-87.5 -35.5t-88 35.5t-36.5 87zM905 1564.5q0 51.5 37 87.5t88 36t87 -36t36 -87.5t-36 -87t-87 -35.5t-88 35.5t-37 87z" /> -<glyph unicode="Ý" horiz-adv-x="1517" d="M33 1278q-4 12 0 29q4 25 22 24q395 -6 551 0q8 0 17.5 -16.5t4.5 -31.5t-28 -15q-129 0 -129 -41q0 -25 66 -127l274 -422q8 -10 26.5 -1t28.5 28l219 370q66 109 66 137q0 31 -23.5 42.5t-93.5 11.5h-20q-18 8 -16.5 36.5t22.5 28.5q178 -6 457 0q18 0 18 -31 q0 -35 -18 -34q-104 -6 -170 -74q-31 -33 -107 -160l-303 -514v-107.5v-128v-79.5q0 -59 25.5 -92t89.5 -41q8 0 32.5 1t34.5 -3q25 -6 25 -41t-25 -35q-406 6 -573 2q-16 0 -22.5 21.5t-0.5 37.5q8 20 43 21q10 2 31 0t25 -2q109 6 114 131q10 154 2 291l-374 585 q-72 113 -120 147t-143 38q-25 0 -28 14zM643 1448l100 336q14 27 37 26l183 2q8 0 14 -2t10 -6t4 -12v-6l-2 -4l-295 -352q-10 -12 -33.5 -8.5t-17.5 26.5z" /> -<glyph unicode="Þ" horiz-adv-x="1206" d="M39 1311v18q0 20 29 21q401 -8 518 -2q31 0 30 -19v-22q0 -23 -8 -23q-2 -2 -12 -2h-21q-66 -4 -87 -10t-29 -21q-14 -23 -15 -71v-45q0 -14 12.5 -27.5t28.5 -11.5h66q164 0 291 -31q90 -23 162 -80q131 -104 131 -278q0 -195 -140.5 -308.5t-382.5 -113.5 q-84 0 -147 10q-12 2 -16.5 -6t-4.5 -19v-69q0 -84 34 -113t128 -29h43q43 -4 43 -20q4 -47 -33 -47q-303 8 -557 -2q-18 0 -26 4t-6 20q4 23 10 31q6 10 35 10q96 0 116 33q14 23 15 70v100v858q0 115 -15 139q-10 18 -45 23q-6 2 -24 2q-35 2 -47 4h-13h-28q-14 0 -19 2 q-16 4 -16 25zM444 408q0 -43 27 -50q39 -6 84 -6q160 0 259 99.5t99 261.5q0 98 -36.5 171.5t-102.5 108.5q-82 43 -211 43q-39 0 -74 -4q-45 -12 -45 -37v-587z" /> -<glyph unicode="ß" horiz-adv-x="1116" d="M39 23q0 23 3 27.5t21 6.5q80 4 96.5 24.5t16.5 108.5v80v521q0 238 20.5 335t86.5 183q117 147 307 147q156 0 262 -95t106 -235q0 -104 -67.5 -189t-188.5 -138q-10 -4 -12 -7.5t1 -5.5t14 -4q117 -33 208 -120q115 -113 115 -279q0 -168 -109.5 -293t-259.5 -125 q-47 0 -77.5 21.5t-30.5 58.5q0 29 17.5 50.5t43.5 21.5q23 0 70 -29q47 -20 57 -20q41 0 73 79.5t32 204.5q0 342 -211 387q-51 10 -107 11q-20 0 -28 8q-4 6 -4 24q0 14 3 18.5t19 6.5q135 18 207 96t72 205q0 125 -63.5 200.5t-166.5 75.5q-109 0 -166 -90t-57 -274v-133 v-617v-92q0 -78 17.5 -96.5t89.5 -18.5q20 -4 26 -10t6 -30q0 -16 -2 -23q-6 -10 -18 -8q-217 8 -398 0q-14 -2 -19 5t-5 26z" /> -<glyph unicode="à" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23 q-47 -23 -146 -64q-111 -45 -110 -125zM211 1307q-8 10 2 24.5t29 14.5l157 2q29 0 37 -17q64 -170 103 -334q0 -18 -20.5 -22t-31.5 8q-115 152 -276 324z" /> -<glyph unicode="á" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23 q-47 -23 -146 -64q-111 -45 -110 -125zM311 991l101 336q6 27 37 27h182q8 0 14 -1t10 -5.5t4 -12.5q0 -2 -1 -5t-3 -5l-293 -352q-10 -12 -33.5 -8t-17.5 26z" /> -<glyph unicode="â" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM104 985l183 320q8 12 26 20q12 2 72.5 3t81.5 -1q23 -2 35 -20l180 -312 q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -7 14zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125z" /> -<glyph unicode="ã" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM74 967q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5 t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57.5 -182t-145.5 -71q-82 0 -198 79q-84 59 -121 60q-31 0 -47.5 -20.5t-28.5 -75.5q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5t-26.5 16.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170 q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125z" /> -<glyph unicode="ä" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM135 1108q0 47 35 82t84 35q47 0 82 -35t35 -82q0 -49 -34 -83t-83 -34t-84 34 t-35 83zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125zM481 1108q0 47 35 82t82 35q49 0 84 -35t35 -82t-35 -82t-84 -35q-47 0 -82 34t-35 83z" /> -<glyph unicode="å" horiz-adv-x="847" d="M51 160q0 152 217 209q82 23 195 75q23 14 22 37l-2 131q-4 184 -139 185q-35 0 -76 -30t-41 -62q0 -35 6 -50q-10 -10 -58 -33.5t-64 -27.5q-27 -10 -37.5 -4t-10.5 35q0 76 130 174q104 84 192 84q66 0 130.5 -33t98.5 -84q25 -33 30 -62.5t5 -128.5v-372 q0 -61 10.5 -81t35 -20t36.5 7q25 8 49 30q10 6 19 6q30 -6 14 -51q-135 -119 -217 -119q-88 0 -107 107q-6 6 -8 6t-12 -8l-10 -8q-66 -57 -109 -77t-100 -20q-88 0 -143.5 51.5t-55.5 133.5zM190 1182q0 88 61.5 149.5t149.5 61.5q84 0 145.5 -61.5t61.5 -149.5 t-61.5 -149.5t-145.5 -61.5q-88 0 -149.5 61.5t-61.5 149.5zM209 186q0 -47 32.5 -79.5t80.5 -32.5q33 0 91 37.5t70 70.5v170q0 31 -18 23q-47 -23 -146 -64q-111 -45 -110 -125zM287 1182q0 -47 33.5 -81t80.5 -34q45 0 78 34t33 81t-33 80.5t-78 33.5q-47 0 -80.5 -33.5 t-33.5 -80.5z" /> -<glyph unicode="æ" horiz-adv-x="1339" d="M76 152q0 90 55 134t211 85q96 23 188 82v143q0 197 -145 197q-51 0 -89 -29t-38 -66q0 -6 2 -16t2 -16.5t-3 -14.5t-13 -12l-113 -51q-20 -10 -30.5 4t-10.5 37q0 72 135 176q104 78 195 78q135 0 223 -105q12 -14 31 6q115 102 266 103q109 0 175.5 -49.5t119.5 -165.5 q4 -10 12 -27q8 -20 35 -47v-31q0 -25 -41 -24h-502q-51 0 -51 -45q0 -139 27 -215q27 -80 98.5 -132.5t155.5 -52.5q66 0 116 28t113 95q8 8 21.5 9t19.5 -5l14 -16q14 -12 -4 -35q-82 -94 -170 -149q-94 -59 -188 -60q-176 0 -285 156q-12 20 -30 2q-66 -70 -149 -114 t-153 -44q-86 0 -143 53.5t-57 133.5zM238 180q0 -53 30.5 -85t81.5 -32q82 1 180 97v190q0 29 -20 19q-66 -33 -127 -54q-86 -29 -115.5 -57.5t-29.5 -77.5zM702 629q-4 -20 41 -21h5h305q10 0 16 8.5t4 16.5q-18 86 -66.5 135t-109.5 49q-150 0 -195 -188z" /> -<glyph unicode="ç" horiz-adv-x="864" d="M51 395q0 205 144.5 347.5t351.5 142.5q100 0 172 -37t72 -94q0 -33 -21.5 -54.5t-52.5 -21.5q-53 0 -127 72q-57 57 -117 57q-102 0 -180 -108.5t-78 -256.5q0 -158 80 -257t203 -99q147 0 241 137q12 31 35 25q6 -2 8 -4t4.5 -6.5t4.5 -8.5q16 -12 -3 -39 q-121 -184 -296 -210l-37 -68q-18 -33 -4 -35q59 -8 99 -54t40 -110q0 -80 -57.5 -136t-135.5 -56q-47 0 -88 14q-6 2 -9 11.5t1 19.5q2 2 8 14q4 8 16.5 8t29 -3t20.5 -3q43 0 71.5 28t28.5 66q0 70 -57.5 74t-110.5 -43q-6 -6 -18.5 2t-5.5 21l131 217q6 8 3 18t-14 10 q-156 8 -254 126t-98 294z" /> -<glyph unicode="è" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-139 0 -199 -186zM256 1307q-10 10 1 24.5t30 14.5l155 2q31 0 39 -17q54 -139 103 -334q0 -18 -20.5 -22t-33.5 8q-109 141 -274 324z" /> -<glyph unicode="é" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-139 0 -199 -186zM356 991l101 336q6 27 37 27h180q10 0 16 -1t10 -5.5t2 -12.5q0 -8 -2 -10l-292 -352q-10 -12 -34 -8t-18 26z" /> -<glyph unicode="ê" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM162 985l182 320q8 12 27 20q12 2 72.5 3t80.5 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -6 14zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131 t-116 47q-139 0 -199 -186z" /> -<glyph unicode="ë" horiz-adv-x="868" d="M49 414q0 201 120 333t300 132q223 0 295 -181l14 -34q27 -45 43 -66q4 -15 0 -33q0 -18 -26 -18q-158 -6 -549 0q-37 0 -39 -21q-4 -23 -4 -61q0 -158 88 -261.5t217 -103.5q145 0 256 131q14 14 31 11q12 -4 19 -18.5t1 -24.5q-68 -80 -145 -142q-115 -88 -242 -88 q-162 0 -270.5 129t-108.5 316zM180 1108q0 47 35 82t84 35q47 0 82 -35t35 -82q0 -49 -34 -83t-83 -34t-84 34t-35 83zM225 629q-2 -6 11.5 -11.5t21.5 -5.5h307q16 0 33.5 6.5t15.5 18.5q-23 84 -74 131t-116 47q-139 0 -199 -186zM526 1108q0 47 35 82t82 35q49 0 83 -34 t34 -83t-34 -83t-83 -34q-47 0 -82 34t-35 83z" /> -<glyph unicode="ì" horiz-adv-x="536" d="M-14 1307q-10 10 0 24.5t28 14.5l158 2q29 0 39 -17q59 -156 100 -334q2 -18 -18.5 -22t-32.5 8q-109 141 -274 324zM41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5l261 90q41 14 41 -29v-614 q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23z" /> -<glyph unicode="í" horiz-adv-x="536" d="M41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5l261 90q41 14 41 -29v-614q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23zM158 991l100 336 q12 27 39 27h180q12 2 21.5 -3.5t7.5 -15.5q0 -2 -2 -6v-4l-293 -352q-10 -12 -34.5 -8t-18.5 26z" /> -<glyph unicode="î" horiz-adv-x="536" d="M-23 985l183 320q8 12 26 20q12 2 72.5 3t81.5 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-235 -213q-18 -16 -43 -2q-10 6 -7 14zM41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5 t8.5 27.5l261 90q41 14 41 -29v-614q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23z" /> -<glyph unicode="ï" horiz-adv-x="536" d="M-27 1108q0 51 36 87t87 36t87 -36t36 -87t-36 -87t-87 -36t-87 36t-36 87zM41 27q-4 35 14 34h27q88 0 105.5 30t17.5 165v367q0 76 -8.5 90t-46.5 22q-47 10 -84 23q-10 2 -11.5 23.5t8.5 27.5l261 90q41 14 41 -29v-614q0 -78 2 -106q2 -57 20.5 -73t81.5 -16h23 q16 -3 12 -34q0 -31 -12 -31q-186 4 -433 0q-6 -2 -11 8t-7 23zM336 1108q0 51 36 87t87 36t88 -36t37 -87t-37 -87t-88 -36t-87 36t-36 87z" /> -<glyph unicode="ð" horiz-adv-x="1116" d="M94 430q0 197 133 330t328 133q70 0 125 -21q20 -6 31.5 4.5t-0.5 38.5q-20 45 -45 80q-43 66 -115 129q-12 12 -37 16.5t-45 -5.5l-260 -138q-20 -4 -33 19q-14 33 14 47l224 117q14 6 16 21.5t-14 25.5q-51 33 -140 63q-8 0 -20 10.5t-4 24.5l16 29q18 31 51 20 q152 -41 263 -104l192 96q35 10 47 -14q16 -25 -14 -41l-115 -62q-47 -25 -4 -55q59 -45 121 -119q63 -76 102 -145q119 -212 119 -445q0 -274 -149 -403q-129 -117 -316 -117q-205 0 -338 131t-133 334zM270 498q0 -193 94.5 -326t225.5 -133q115 0 188.5 90t73.5 231 q0 197 -93 327t-231 130q-109 0 -183.5 -91t-74.5 -228z" /> -<glyph unicode="ñ" horiz-adv-x="1056" d="M33 39.5q4 19.5 18 19.5h12q72 0 94.5 39t22.5 174v281q0 150 -8 166q-8 18 -80 33l-41 8q-10 2 -10 26.5t10 28.5q33 6 119 43t123 45q47 12 47 -35v-112q0 -6 7 -18.5t15 -6.5q96 68 170 105q86 41 144 41q227 0 227 -369q0 -61 -8 -184t-8 -187q0 -47 16.5 -60.5 t85.5 -13.5q18 12 33 -6q10 -18 4 -43q-2 -12 -6 -15t-19 -3h-6q-43 0 -193.5 1t-195.5 -1q-20 0 -25.5 6t-7.5 27q0 35 17 34h14q68 6 93.5 29t31.5 86q12 119 12 361q0 227 -149 227q-96 0 -252 -121v-463q0 -78 22.5 -98.5t102.5 -20.5q14 0 18 -34q0 -33 -28 -35 q-47 2 -194.5 0t-197.5 2q-25 0 -28 10q-6 14 -2 33.5zM195 967q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52 27.5t30 107.5q0 12 26 12q25 4 25 -12q4 -13 4 -27q0 -111 -57.5 -182t-145.5 -71q-86 0 -198 79q-86 59 -121 60q-31 0 -47.5 -20.5t-28.5 -75.5 q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5t-26.5 16.5z" /> -<glyph unicode="ò" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228zM342 1307 q-8 10 2 24.5t29 14.5l157 2q29 0 39 -17q60 -156 101 -334q2 -18 -19.5 -22t-32.5 8q-115 152 -276 324z" /> -<glyph unicode="ó" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228zM442 991l101 336 q14 27 37 27h182q8 0 14 -1t11.5 -5.5t3.5 -12.5v-6l-3 -4l-292 -352q-12 -12 -36 -8t-18 26z" /> -<glyph unicode="ô" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM209 985l182 320q8 12 27 20q12 2 72.5 3t80.5 -1q23 -2 35 -20l180 -312q10 -25 -2 -26q-29 -8 -41 4l-249 213l-236 -213q-18 -16 -43 -2 q-10 6 -6 14zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228z" /> -<glyph unicode="õ" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM170 967q12 276 201 276q82 0 200 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 27 12q25 4 24 -12q4 -13 4 -27q0 -111 -57 -182t-145 -71 q-82 0 -199 79q-84 59 -121 60q-31 0 -47 -20.5t-29 -75.5q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5t-26.5 16.5zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228z" /> -<glyph unicode="ö" horiz-adv-x="1013" d="M47 424q0 197 132 327t329 130q199 0 334 -132t133 -327q0 -190 -133 -321.5t-328 -131.5q-199 0 -333 130t-134 325zM225 489q0 -186 92.5 -315t221.5 -129q109 0 181.5 92.5t72.5 235.5q0 178 -93.5 306t-220.5 128q-109 0 -181.5 -90t-72.5 -228zM225 1108q0 47 35 82 t82 35t82 -35t35 -82q0 -49 -34 -83t-83 -34t-83 34t-34 83zM569 1108q0 47 35 82t82 35q51 0 85 -35t34 -82t-34 -82t-85 -35q-47 0 -82 34t-35 83z" /> -<glyph unicode="÷" horiz-adv-x="1431" d="M152 672v51q0 37 63 37h979h37q20 0 29 -2q27 -6 28 -31l4 -59q2 -27 -16.5 -34t-46.5 -7h-1012q-18 0 -41.5 14t-23.5 31zM629 266q0 37 25.5 61.5t62.5 24.5t61.5 -24.5t24.5 -61.5t-24.5 -62.5t-61.5 -25.5q-35 0 -61.5 25.5t-26.5 62.5zM629 1133q0 35 26.5 57 t61.5 22t60.5 -24.5t25.5 -59.5q0 -37 -25.5 -62.5t-60.5 -25.5q-37 0 -63.5 27t-24.5 66z" /> -<glyph unicode="ø" horiz-adv-x="1116" d="M94 422q0 199 134 331t335 132q145 0 273 -82q4 -2 14 3t12 9l92 109q12 12 25 0q20 -16 20 -19q14 -14 -14 -43q-18 -20 -78 -92q-14 -14 -4 -25q129 -131 129 -321q0 -195 -134 -327t-329 -132q-143 0 -268 78q-16 10 -31 -6l-110 -137q-16 -16 -33 0l-23 18 q-10 8 7 31l108 125q16 20 6 30q-131 129 -131 318zM279 487.5q0 -141.5 53 -249.5q2 -6 13 -5.5t17 9.5l377 434q12 14 0 29q-88 106 -204 106q-111 0 -183.5 -91t-72.5 -232.5zM389 147q88 -106 203 -106q111 0 185.5 94.5t74.5 237.5q0 123 -57 237q-8 20 -21 8 l-385 -446q-12 -12 0 -25z" /> -<glyph unicode="ù" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM322 1307q-8 10 2 24.5t28 14.5l158 2q29 0 39 -17q59 -156 100 -334q2 -18 -19.5 -22t-31.5 8q-115 152 -276 324z" /> -<glyph unicode="ú" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM442 991l101 336q14 27 37 27h182q8 0 14 -1t11.5 -5.5t3.5 -12.5v-6l-3 -4l-292 -352q-12 -12 -36 -8t-18 26z" /> -<glyph unicode="û" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM215 985l182 320q8 12 27 20q12 2 72.5 3t81.5 -1q23 -2 34 -20l181 -312q10 -25 -2 -26q-29 -8 -41 4l-250 213l-236 -213q-18 -16 -43 -2q-10 6 -6 14z" /> -<glyph unicode="ü" d="M40 819.5q-3 22.5 13 26.5q20 4 117.5 28.5t138.5 32.5q16 2 24.5 -10t8.5 -29v-491q0 -164 38 -220.5t142 -56.5q100 0 230 103l2 6q2 6 4 15t2 18v354q0 92 -6 121q-14 55 -62 63q-10 2 -19 4t-14.5 3t-11.5 4q-2 0 -67 10q-12 6 -10.5 27.5t14.5 25.5q209 47 293 55 q41 4 41 -32v-652v-63q0 -68 88 -45l43 12q12 2 17 -13.5t1 -33t-16 -19.5q-113 -49 -234 -73q-23 -8 -39 -3t-18 31l-4 80q0 8 -4 22.5t-11 8.5q-68 -49 -104.5 -73.5t-101 -50t-123.5 -25.5q-231 0 -232 282v432q0 35 -8 51.5t-37 24.5q-16 6 -47 14.5t-35 10.5 q-10 2 -13 24.5zM250 1108q0 47 34.5 82t82.5 35q49 0 83.5 -35t34.5 -82q0 -49 -34.5 -83t-84 -34t-83 34t-33.5 83zM594 1108q0 47 35 82t84 35t82.5 -35t33.5 -82t-33.5 -82t-82.5 -35t-84 34t-35 83z" /> -<glyph unicode="ý" horiz-adv-x="1005" d="M18 840q6 23 41 18q35 -2 349 4q33 0 38 -16q4 -14 0 -30.5t-12 -18.5q-66 -2 -86 -14.5t-20 -37.5q0 -23 22 -71q25 -51 189 -459q6 -14 28 21q4 4 4 6l123 313q20 51 31 84q18 55 18 84q0 39 -25.5 55.5t-99.5 18.5q-10 6 -11 31.5t18 27.5h16q176 10 295 2 q35 0 39 -18q2 -12 -2 -27.5t-10 -15.5q-63 -8 -101.5 -56.5t-99.5 -210.5l-254 -684q-72 -184 -86 -219q-31 -74 -74 -125q-33 -43 -94 -43q-39 0 -67.5 28t-28.5 64q0 63 102 89q63 16 105.5 72.5t78.5 176.5l29 95l-262 618q-57 133 -82 161t-98 34q-6 2 -10.5 16 t-2.5 27zM387 991l100 336q12 27 37 27h183q8 0 14 -1t11 -5.5t3 -12.5q0 -2 -2 -6v-4l-293 -352q-12 -12 -35.5 -8t-17.5 26z" /> -<glyph unicode="þ" horiz-adv-x="1071" d="M6 -494l2 33q0 12 7.5 15.5t22.5 1.5t17 -2q53 2 75 14t32 56t10 149v1335v53q0 37 -8 47.5t-45 20.5l-58 16q-23 6 -22 43q0 16 8 21q2 2 10 6l224 137q31 12 44 6t13 -39v-581q0 -27 6 -50q8 -25 21 -12q180 125 290 125q131 0 229.5 -125t98.5 -289q0 -197 -139 -343 t-326 -146q-74 0 -160 29q-12 4 -16 -9.5t-4 -35.5v-209q0 -139 24.5 -182.5t108.5 -36.5l31 2q18 2 24 -3.5t9 -23.5q6 -23 1.5 -35t-32.5 -10q-326 6 -469 0q-29 0 -29 22zM338 199q117 -111 240 -111q102 0 170.5 90.5t68.5 229.5q0 156 -77.5 260t-188.5 104 q-98 0 -213 -98v-475z" /> -<glyph unicode="ÿ" horiz-adv-x="999" d="M18 840q6 23 41 18q35 -2 349 4q33 0 38 -16q4 -14 0 -30.5t-12 -18.5q-66 -2 -86 -14.5t-20 -37.5q0 -23 22 -71q25 -51 189 -459q6 -14 28 21q4 4 4 6l123 313q20 51 31 84q18 55 18 84q0 39 -25.5 55.5t-99.5 18.5q-10 6 -11 31.5t18 27.5h16q176 10 295 2 q35 0 39 -18q2 -12 -2 -27.5t-10 -15.5q-63 -8 -101.5 -56.5t-99.5 -210.5l-254 -684q-72 -184 -86 -219q-31 -74 -74 -125q-33 -43 -94 -43q-39 0 -67.5 28t-28.5 64q0 63 102 89q63 16 105.5 72.5t78.5 176.5l29 95l-262 618q-57 133 -82 161t-98 34q-6 2 -10.5 16 t-2.5 27zM199 1108q0 51 36.5 87t88 36t87 -36t35.5 -87t-35.5 -87t-87 -36t-88 36t-36.5 87zM563 1108q0 51 36 87t87 36t88 -36t37 -87t-37 -87t-88 -36t-87 36t-36 87z" /> -<glyph unicode="Œ" horiz-adv-x="2121" d="M123 657q0 205 103.5 376t279.5 257q141 70 348 70q76 0 227 -8q104 -6 117 -6q6 0 39 1t72 1h589q23 0 31 -6.5t10 -30.5q16 -168 15 -252q0 -25 -19 -25q-6 0 -14 -1t-11 -1t-7.5 1t-7.5 6t-5 16l-10 41q-27 102 -52.5 126.5t-109.5 24.5h-358q-10 0 -24.5 -9 t-14.5 -21v-449q0 -25 59 -25h242q104 0 131 25q23 25 35 119q4 23 20 22h29q14 0 16 -16v-6q4 -109 0 -367q0 -45 -16 -45h-29q-16 0 -20 31q-8 88 -36 112.5t-112 24.5h-282q-16 0 -26.5 -11t-10.5 -24v-481q0 -10 19.5 -22.5t33.5 -12.5h299q119 0 158 10.5t72 49.5 q43 55 67 147q2 6 3 13t2 10.5t5.5 5.5t14.5 2h22q19 0 17 -33q0 -59 -29 -266q-4 -27 -18.5 -33t-47.5 -6q-125 0 -362.5 1t-359.5 1q-70 0 -208.5 -9.5t-205.5 -9.5q-285 0 -482.5 199t-197.5 483zM332 698q0 -274 148.5 -460.5t363.5 -186.5q115 0 192 60 q53 41 68.5 103.5t15.5 248.5v581q0 242 -293 242q-233 0 -364 -155.5t-131 -432.5z" /> -<glyph unicode="œ" horiz-adv-x="1587" d="M98 428q0 190 134.5 322.5t328.5 132.5q184 0 289 -127q16 -18 39 4q121 123 287 123q221 0 297 -199q25 -59 57 -90v-31q0 -20 -27 -20h-493q-57 0 -58 -31q0 -180 82 -305t195 -125q90 0 237 147q4 4 9.5 6.5t8.5 2.5t7 -3.5t6 -5.5t6 -7t6 -7q14 -14 -4 -35 q-74 -82 -174 -151q-98 -63 -196 -64q-143 0 -236 133q-12 12 -22 0q-119 -133 -312 -133q-199 0 -333 133t-134 330zM279 479q0 -176 93 -307t212 -131q100 0 157.5 86t57.5 244q0 197 -78 318.5t-197 121.5q-102 0 -173.5 -94t-71.5 -238zM965 629q0 -6 7 -11.5t18 -7.5 t22 -2h270q31 0 27 29q-8 82 -54.5 134t-111.5 52q-143 0 -178 -194z" /> -<glyph unicode="Ÿ" horiz-adv-x="1490" d="M33 1278q-4 12 0 29q4 25 22 24q395 -6 551 0q8 0 17.5 -16.5t4.5 -31.5t-28 -15q-129 0 -129 -41q0 -25 66 -127l274 -422q8 -10 26.5 -1t28.5 28l219 370q66 109 66 137q0 31 -23.5 42.5t-93.5 11.5h-20q-18 8 -16.5 36.5t22.5 28.5q178 -6 457 0q18 0 18 -31 q0 -35 -18 -34q-104 -6 -170 -74q-31 -33 -107 -160l-303 -514v-107.5v-128v-79.5q0 -59 25.5 -92t89.5 -41q8 0 32.5 1t34.5 -3q25 -6 25 -41t-25 -35q-406 6 -573 2q-16 0 -22.5 21.5t-0.5 37.5q8 20 43 21q10 2 31 0t25 -2q109 6 114 131q10 154 2 291l-374 585 q-72 113 -120 147t-143 38q-25 0 -28 14zM453 1564.5q0 51.5 36.5 87.5t88 36t87 -36t35.5 -87.5t-35.5 -87t-87 -35.5t-88 35.5t-36.5 87zM817 1564.5q0 51.5 36 87.5t87 36t87 -36t36 -87.5t-36 -87t-87 -35.5t-87 35.5t-36 87z" /> -<glyph unicode="ˆ" horiz-adv-x="714" d="M70 985l182 320q8 12 27 20q12 2 69.5 3t77.5 -1q23 -2 35 -20l180 -312q6 -16 -2 -26q-20 -16 -41 4l-246 213l-233 -213q-25 -23 -45 -4q-8 8 -4 16z" /> -<glyph unicode="˜" horiz-adv-x="714" d="M29 967q12 276 200 276q82 0 201 -82q82 -55 121 -55q35 0 52.5 27.5t29.5 107.5q0 12 26 12q25 4 25 -12q4 -13 4 -27q0 -111 -57.5 -182t-145.5 -71q-82 0 -198 79q-84 59 -121 60q-31 0 -47.5 -20.5t-28.5 -75.5q0 -4 -2 -15.5t-4 -21.5q-6 -14 -28.5 -16.5 t-26.5 16.5z" /> -<glyph unicode=" " horiz-adv-x="917" /> -<glyph unicode=" " horiz-adv-x="1835" /> -<glyph unicode=" " horiz-adv-x="917" /> -<glyph unicode=" " horiz-adv-x="1835" /> -<glyph unicode=" " horiz-adv-x="611" /> -<glyph unicode=" " horiz-adv-x="458" /> -<glyph unicode=" " horiz-adv-x="305" /> -<glyph unicode=" " horiz-adv-x="305" /> -<glyph unicode=" " horiz-adv-x="229" /> -<glyph unicode=" " horiz-adv-x="367" /> -<glyph unicode=" " horiz-adv-x="101" /> -<glyph unicode="‐" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="‑" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="‒" horiz-adv-x="890" d="M90 432v82q0 16 13.5 25.5t25.5 9.5q68 -2 303.5 1t349.5 -1q10 0 19.5 -11.5t9.5 -21.5l-4 -80q-6 -25 -35 -28q-158 4 -357.5 1t-303.5 -1q-14 0 -21 24z" /> -<glyph unicode="–" horiz-adv-x="1247" d="M78 461l2 71q4 18 24 23q377 12 1043 0q12 0 20.5 -9t8.5 -18v-75q-2 -18 -33 -19q-573 6 -1045 0q-6 0 -13 9.5t-7 17.5z" /> -<glyph unicode="—" horiz-adv-x="1751" d="M170 496q0 12 11.5 25.5t33.5 13.5q680 12 1313 0q33 -11 35 -23q8 -2 2 -37t-6 -41q-12 -25 -29 -22q-745 10 -1323 0q-12 -2 -23.5 5t-9.5 21q0 8 -3 24.5t-1 33.5z" /> -<glyph unicode="‘" horiz-adv-x="557" d="M141 1112q0 100 66.5 185t177.5 126q12 4 23.5 -6t11.5 -24.5t-17 -28.5q-152 -86 -151 -197q0 -31 20 -30q6 0 20.5 5t22.5 5q43 0 72 -32t29 -75q0 -49 -34 -81.5t-83 -32.5q-68 0 -113 54t-45 132z" /> -<glyph unicode="’" horiz-adv-x="557" d="M145 1307q0 49 35 81.5t84 32.5q68 0 112 -51t44 -129q0 -92 -60.5 -176t-156.5 -131q-33 -16 -45 -2q-29 33 0 51q154 90 153 195q0 16 -4 25t-18 7q-29 -8 -45 -8q-43 0 -71 30t-28 75z" /> -<glyph unicode="‚" horiz-adv-x="526" d="M137 59q0 45 33 76t80 31q61 0 101 -49t40 -123q0 -94 -61.5 -175t-161.5 -120q-14 -6 -23 20q-4 31 5 33q143 88 143 187q0 29 -14 28h-7q-4 0 -14 -2t-14 -4h-15q-39 0 -65.5 28.5t-26.5 69.5z" /> -<glyph unicode="“" horiz-adv-x="1028" d="M164 1104q0 96 63.5 182t165.5 131q27 10 37 -8q20 -35 -2 -45q-154 -90 -154 -197q0 -31 21 -30l4 2h6l10 2q16 4 27 4q43 0 70.5 -31t27.5 -74q0 -49 -34.5 -81.5t-83.5 -32.5q-68 0 -113 51t-45 127zM625 1104q0 96 63.5 182t165.5 131q29 10 41 -6q18 -33 -6 -47 q-154 -86 -154 -197q0 -31 21 -30q6 0 22.5 4t24.5 4q43 0 70.5 -31t27.5 -74q0 -49 -35 -81.5t-84 -32.5q-68 0 -112.5 51t-44.5 127z" /> -<glyph unicode="”" horiz-adv-x="1026" d="M158 1307q0 49 34.5 81.5t86.5 32.5q68 0 112.5 -51t44.5 -129q0 -92 -62.5 -177t-162.5 -132q-33 -10 -45 4q-23 31 2 47q158 84 158 195q0 35 -17 34q-6 0 -24 -6q-20 -4 -29 -4q-41 0 -69.5 30t-28.5 75zM616.5 959.5q-0.5 15.5 12.5 23.5q158 84 157 195q0 20 -5 27 t-15 5q-8 0 -10 -2q-4 0 -17.5 -3t-21.5 -3q-41 0 -70 30t-29 75q0 49 35 81.5t86 32.5q68 0 113 -51t45 -129q0 -92 -61.5 -178t-161.5 -131q-37 -16 -47 0q-10 12 -10.5 27.5z" /> -<glyph unicode="„" horiz-adv-x="968" d="M147 59q0 45 34 76t81 31q63 0 104.5 -49t41.5 -123q0 -94 -62.5 -174t-165.5 -121q-14 -4 -26.5 20.5t6.5 32.5q147 88 147 187q0 29 -16 28q-4 0 -11.5 -1t-11.5 -1q-16 -4 -26 -4q-39 0 -67 28.5t-28 69.5zM582 59q0 45 33.5 76t80.5 31q63 0 104.5 -49t41.5 -123 q0 -94 -62.5 -175t-165.5 -120q-8 -4 -16 8t-8 25.5t4 19.5q147 86 147 187q0 29 -14 28h-2h-6l-17 -2q-16 -4 -26 -4q-39 0 -66.5 28.5t-27.5 69.5z" /> -<glyph unicode="•" horiz-adv-x="759" d="M113 672q0 113 77.5 192.5t190.5 79.5t192.5 -80t79.5 -192.5t-79.5 -192.5t-192.5 -80t-190.5 79t-77.5 194z" /> -<glyph unicode="…" horiz-adv-x="2162" d="M258 86q0 49 35 79t90 30q53 0 87 -32t34 -83q0 -49 -34 -82t-87 -33t-89 35t-36 86zM971 78q0 51 33.5 83t89.5 32q53 0 86.5 -32t33.5 -83t-32.5 -82t-85.5 -31q-55 0 -90 32t-35 81zM1675 86q0 51 34 80t89 29q53 0 87 -32t34 -83t-33 -83t-86 -32t-89 36t-36 85z" /> -<glyph unicode=" " horiz-adv-x="367" /> -<glyph unicode="‹" horiz-adv-x="1802" d="M40 37.5q5 17.5 23 21.5h23q80 0 105.5 25t25.5 104v496q0 12 -13.5 24.5t-21.5 12.5h-88q-37 0 -41 14q-4 10 -4 25.5t4 21.5q6 4 21 11q2 2 4 2q94 18 141 49q6 82 12 141q12 80 23 109q31 88 154 198q72 66 171 109t212.5 42t189.5 -65q41 -45 84 -16q76 55 165 87 t185 26.5t166 -62.5q31 -27 31 -49.5t-40 -60t-63 -37.5q-20 0 -49 28q-49 43 -90 58.5t-102 15.5q-84 0 -158 -62.5t-94 -148.5q-14 -70 -15 -248q0 -49 25 -51q90 -12 377 0q82 2 178 35q16 6 26.5 -12.5t10.5 -36.5v-664q0 -78 20.5 -97.5t83.5 -19.5q16 4 29 0 q12 -2 11 -34.5t-11 -36.5q-193 6 -438 0q-14 0 -15 33q0 16 2.5 23t9.5 12.5t21 2.5q88 0 106.5 30t18.5 177v316q0 154 -125 155q-199 6 -287 2q-14 -2 -26 -15t-14 -23l-3 -435q0 -131 18.5 -169t108.5 -38h41q23 0 28 -8t5 -30q0 -33 -12 -33q-246 4 -492 -2 q-16 0 -16 30q0 33 16 39h17q47 0 65.5 2t33.5 25t17.5 60.5t2.5 119.5v412q-12 51 -33 53q-72 4 -203 4t-176 -6q-29 -4 -33 -45v-508q2 -68 26.5 -89t98.5 -21q51 0 61 -3q12 -4 15.5 -23.5t-1.5 -34.5t-14 -15q-301 10 -518 0q-10 0 -16 15t-1 32.5zM389 891 q0 -41 27 -43q229 -10 389 0q16 2 23.5 14t8.5 25.5t1 36v28.5q6 154 55 242q10 23 -33 66q-82 74 -205 73q-84 0 -158.5 -61.5t-93.5 -147.5q-14 -59 -14 -233z" /> -<glyph unicode="›" horiz-adv-x="1761" d="M48 4q-5 14 0 30.5t24 20.5q6 4 29.5 3t29.5 -1q59 2 76.5 28t17.5 103v500q0 33 -26 33h-97q-37 0 -43 14q-6 37 2 47q2 2 23 13q92 16 141 49q6 82 13 141q6 53 22 109q31 88 154 198q74 66 170 108t205.5 42t185.5 -64q37 -35 55 -18q111 96 254 96q23 0 66 -5t63 -5 q55 0 94 49q61 23 62 -14v-1303q0 -76 13 -96.5t71 -22.5q2 0 14 1t18.5 0t14.5 -5t10 -12q8 -19 0 -39q-4 -14 -18 -12h-9h-428q-12 0 -16 20.5t2 32.5q4 10 21.5 12t41 1t29.5 -1q49 6 60.5 42t11.5 171l2 418q0 51 -37 51q-262 10 -362 0q-10 -2 -25 -49v-512 q0 -76 24.5 -99.5t100.5 -23.5q10 4 22 0q16 -2 16.5 -32.5t-16.5 -30.5q-129 4 -438 0q-10 0 -15 18.5t-1 30.5q4 10 13 14t18.5 2t17.5 0q53 4 72 29q14 18 17 47t3 137v398q0 39 -7 49t-34 12h-102.5h-138h-105.5q-16 0 -23.5 -7t-11.5 -32v-422q0 -109 3 -135.5 t16 -44.5q12 -20 32.5 -26.5t75.5 -6.5q29 6 60 0q12 -4 15 -20.5t-2 -30.5t-13 -14q-264 10 -519 0q-10 0 -15 14zM395 883q0 -37 23 -39q111 -4 348 0q29 0 40 6t13 33q11 163 68 286q16 37 -6 62q-6 8 -27 29q-78 74 -192 73q-84 0 -159 -61.5t-93 -147.5 q-14 -59 -15 -241zM983 895q0 -23 10.5 -31t40.5 -10h326q45 0 45 41v389q-115 78 -207 78q-76 0 -133 -78q-80 -109 -82 -389z" /> -<glyph unicode=" " horiz-adv-x="458" /> -<glyph unicode="€" horiz-adv-x="1001" d="M8 506v47q0 20 23 20h121v50q0 68 2 98h-111q-25 0 -25 24v50q0 20 23 20h123q35 238 150.5 367t267.5 129q90 0 186 -58q35 -20 51 -4q12 12 28.5 15.5t28 -2t11.5 -15.5q8 -156 8 -297q0 -12 -17.5 -19t-35 -6t-19.5 9q-27 145 -89 224t-146 79q-221 0 -252 -422h373 q23 0 22 -20v-50q0 -25 -24 -24h-375v-55q0 -63 2 -93h362q23 0 23 -20v-47q0 -25 -25 -25h-354q20 -217 88 -329.5t174 -112.5q102 0 178 123q20 37 60 157q2 16 47 15q33 0 31 -17q-29 -174 -74 -315q-16 4 -35 4q-39 0 -102.5 -21.5t-124.5 -21.5q-154 0 -274 138.5 t-148 379.5h-127q-25 0 -25 25z" /> -<glyph unicode="™" horiz-adv-x="2099" d="M34 1209.5q-3 7.5 1 39.5l18 152q2 23 10.5 29t32.5 6q324 -8 688 0q31 2 41.5 -5.5t12.5 -37.5l16 -152q0 -4 1 -11t1 -9q0 -10 -2 -13q-2 -6 -25 -6h-30q-12 86 -52 117t-139 31h-33q-16 0 -20 -4q-12 -4 -12 -37v-553q0 -76 14 -98.5t72 -26.5h12q6 0 6 -2q6 -2 6 -33 v-14q-4 -8 -4 -9q-4 -6 -35 -4q-143 6 -331 0q-31 0 -37 4.5t-6 26.5v16q2 10 10 13q8 0 14 2q55 8 67.5 27.5t12.5 95.5v557q0 33 -12 37q-4 2 -21 2h-35q-92 0 -132 -31t-54 -117h-35q-18 0 -21 7.5zM905 580v22q0 27 29 27q59 2 73.5 24.5t14.5 100.5v487 q0 86 -13.5 107.5t-72.5 23.5q-23 0 -29 8l-2 4v7v18q0 18 5 22.5t22 4.5q201 -6 268 -2q23 0 31 -19l250 -524q10 -18 16 -21q6 -4 10 7l258 559h267q23 0 30 -4q10 -6 11 -27q0 -23 -4.5 -27t-10.5 -4q-4 -2 -18 -2q-53 -2 -67.5 -25.5t-14.5 -103.5v-487 q0 -78 13.5 -99.5t70.5 -25.5q8 -2 18 -2q6 0 8 -2q5 -4 5 -31q0 -16 -6.5 -21.5t-26.5 -5.5q-27 0 -106 1t-144.5 1t-103.5 -2q-33 -2 -41.5 3.5t-8.5 27.5v21q0 10 9 10h8h22q55 4 70.5 27.5t15.5 95.5v436q-2 14 -6 16q-4 -4 -6 -10l-289 -627h-49l-285 617 q-12 6 -14 -23v-407q0 -84 15.5 -105.5t70.5 -21.5h31q12 0 14 -2q4 -4 4 -9q0 -2 -1 -8t-1 -10q0 -33 -8 -35h-14q-12 4 -23 4q-186 4 -256 0q-10 -2 -24.5 -2t-14.5 13z" /> -<glyph unicode="◼" horiz-adv-x="849" d="M0 0v850h850v-850h-850z" /> -<glyph unicode="fi" horiz-adv-x="1136" d="M82 8q-12 31 12 43l47 6q53 8 63.5 35t10.5 139v426q0 53 -41 56l-70 6q-12 6 -15 22.5t9 24.5q6 6 38 16.5t50 20.5q29 14 29 41q0 195 64 344q43 102 143 189t254 87q104 0 180 -48t76 -113q0 -43 -29 -64.5t-57 -21.5q-37 0 -55 30q-41 70 -92.5 102.5t-96.5 32.5 q-229 0 -229 -489q0 -33 1 -44t13 -25.5t39 -14.5q117 -4 211 0q154 4 240 22q39 12 49 -4q-8 -147 -8 -256v-340q0 -113 11 -139t64 -35l43 -6q16 -2 15.5 -26.5t-17.5 -32.5q-61 4 -194 4h-172q-2 0 -10.5 -1t-10.5 0t-6 4t-6 11q-12 41 41 45q6 2 10 2q53 8 64.5 35 t11.5 139v355q0 90 -16.5 110.5t-83.5 22.5q-123 4 -246 0q-25 -2 -34 -13.5t-9 -48.5v-426q0 -113 11 -141.5t62 -32.5l66 -6q18 -2 15 -28.5t-19 -30.5q-127 6 -217 6q-92 0 -178 -6q-25 0 -31 16z" /> -<glyph unicode="fl" horiz-adv-x="1103" d="M49 4q-10 20 0 43q4 10 29 10q72 6 90 31q14 18 17 48t3 136v430q0 33 -32 37h-95q-6 0 -10 17q-4 18 0 28q4 16 17 17l106 45q14 10 14 24q18 287 160 441q137 154 305 153q23 0 66 -5t63 -5q55 0 95 49q55 20 61 -2v-1321q0 -82 15.5 -102.5t88.5 -20.5q10 4 27 0 q8 -2 11 -19.5t-1 -31.5q-2 -12 -14 -12h-8q-201 8 -420 0h-8q-14 0 -19 12q-6 14 -2 31.5t17 19.5h16q39 0 55.5 1t36 8.5t24.5 17.5t11 39t7 59.5t1 89.5v437q0 35 -39 34q-279 6 -360 -2q-18 0 -23 -22v-539q0 -76 24.5 -99.5t100.5 -23.5q12 4 21 0q14 -2 16 -31.5 t-12 -31.5h-6h-6q-27 0 -115 2t-167 2t-132 -4q-20 -4 -29 10zM354 877q0 -8 4 -12.5t7.5 -5.5t13.5 -2t12 -1q57 -2 123 -2t132.5 1t88.5 1q35 0 41 45v385q-115 78 -207 78q-76 0 -133 -78q-82 -115 -82 -409z" /> -<glyph unicode="ffi" horiz-adv-x="1802" d="M40 37.5q5 17.5 23 21.5h23q80 0 105.5 25t25.5 104v496q0 12 -13.5 24.5t-21.5 12.5h-88q-37 0 -41 14q-4 10 -4 25.5t4 21.5q6 4 21 11q2 2 4 2q94 18 141 49q6 82 12 141q12 80 23 109q31 88 154 198q72 66 171 109t212.5 42t189.5 -65q41 -45 84 -16q76 55 165 87 t185 26.5t166 -62.5q31 -27 31 -49.5t-40 -60t-63 -37.5q-20 0 -49 28q-49 43 -90 58.5t-102 15.5q-84 0 -158 -62.5t-94 -148.5q-14 -70 -15 -248q0 -49 25 -51q90 -12 377 0q82 2 178 35q16 6 26.5 -12.5t10.5 -36.5v-664q0 -78 20.5 -97.5t83.5 -19.5q16 4 29 0 q12 -2 11 -34.5t-11 -36.5q-193 6 -438 0q-14 0 -15 33q0 16 2.5 23t9.5 12.5t21 2.5q88 0 106.5 30t18.5 177v316q0 154 -125 155q-199 6 -287 2q-14 -2 -26 -15t-14 -23l-3 -435q0 -131 18.5 -169t108.5 -38h41q23 0 28 -8t5 -30q0 -33 -12 -33q-246 4 -492 -2 q-16 0 -16 30q0 33 16 39h17q47 0 65.5 2t33.5 25t17.5 60.5t2.5 119.5v412q-12 51 -33 53q-72 4 -203 4t-176 -6q-29 -4 -33 -45v-508q2 -68 26.5 -89t98.5 -21q51 0 61 -3q12 -4 15.5 -23.5t-1.5 -34.5t-14 -15q-301 10 -518 0q-10 0 -16 15t-1 32.5zM389 891 q0 -41 27 -43q229 -10 389 0q16 2 23.5 14t8.5 25.5t1 36v28.5q6 154 55 242q10 23 -33 66q-82 74 -205 73q-84 0 -158.5 -61.5t-93.5 -147.5q-14 -59 -14 -233z" /> -<glyph unicode="ffl" horiz-adv-x="1761" d="M48 4q-5 14 0 30.5t24 20.5q6 4 29.5 3t29.5 -1q59 2 76.5 28t17.5 103v500q0 33 -26 33h-97q-37 0 -43 14q-6 37 2 47q2 2 23 13q92 16 141 49q6 82 13 141q6 53 22 109q31 88 154 198q74 66 170 108t205.5 42t185.5 -64q37 -35 55 -18q111 96 254 96q23 0 66 -5t63 -5 q55 0 94 49q61 23 62 -14v-1303q0 -76 13 -96.5t71 -22.5q2 0 14 1t18.5 0t14.5 -5t10 -12q8 -19 0 -39q-4 -14 -18 -12h-9h-428q-12 0 -16 20.5t2 32.5q4 10 21.5 12t41 1t29.5 -1q49 6 60.5 42t11.5 171l2 418q0 51 -37 51q-262 10 -362 0q-10 -2 -25 -49v-512 q0 -76 24.5 -99.5t100.5 -23.5q10 4 22 0q16 -2 16.5 -32.5t-16.5 -30.5q-129 4 -438 0q-10 0 -15 18.5t-1 30.5q4 10 13 14t18.5 2t17.5 0q53 4 72 29q14 18 17 47t3 137v398q0 39 -7 49t-34 12h-102.5h-138h-105.5q-16 0 -23.5 -7t-11.5 -32v-422q0 -109 3 -135.5 t16 -44.5q12 -20 32.5 -26.5t75.5 -6.5q29 6 60 0q12 -4 15 -20.5t-2 -30.5t-13 -14q-264 10 -519 0q-10 0 -15 14zM395 883q0 -37 23 -39q111 -4 348 0q29 0 40 6t13 33q11 163 68 286q16 37 -6 62q-6 8 -27 29q-78 74 -192 73q-84 0 -159 -61.5t-93 -147.5 q-14 -59 -15 -241zM983 895q0 -23 10.5 -31t40.5 -10h326q45 0 45 41v389q-115 78 -207 78q-76 0 -133 -78q-80 -109 -82 -389z" /> -</font> -</defs></svg> - \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/tufte.css b/www/vincent.demeester.fr/content/legacy/articles/data/ac/212115-e0c6-448c-9344-17c10aeb9694/2020-02-14T17_45_26_0100/writequit.org/css/tufte.css @@ -1,257 +0,0 @@ -/* Import ET Book styles - adapted from https://github.com/edwardtufte/et-book/blob/gh-pages/et-book.css */ - -@charset "UTF-8"; - -@font-face { font-family: "et-book"; - src: url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot"); - src: url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot%3F") format("embedded-opentype"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.woff") format("woff"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.ttf") format("truetype"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.svg") format("svg"); - font-weight: normal; - font-style: normal; } - -@font-face { font-family: "et-book"; - src: url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot"); - src: url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot%3F") format("embedded-opentype"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff") format("woff"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf") format("truetype"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.svg") format("svg"); - font-weight: normal; - font-style: italic; } - -@font-face { font-family: "et-book"; - src: url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot"); - src: url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot%3F") format("embedded-opentype"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff") format("woff"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf") format("truetype"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.svg") format("svg"); - font-weight: bold; - font-style: normal; } - -@font-face { font-family: "et-book-roman-old-style"; - src: url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot"); - src: url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot%3F") format("embedded-opentype"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff") format("woff"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf") format("truetype"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.svg") format("svg"); - font-weight: normal; - font-style: normal; } - -/* Tufte CSS styles */ -html { font-size: 15px; } - -body { width: 87.5%; - margin-left: auto; - margin-right: auto; - padding-left: 12.5%; - font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif; - background-color: #fffff8; - color: #111; - max-width: 1400px; - counter-reset: sidenote-counter; } - -h1 { font-weight: 400; - margin-top: 4rem; - margin-bottom: 1.5rem; - font-size: 3.2rem; - line-height: 1; } - -h2 { font-style: italic; - font-weight: 400; - margin-top: 2.1rem; - margin-bottom: 0; - font-size: 2.2rem; - line-height: 1; } - -h3 { font-style: italic; - font-weight: 400; - font-size: 1.7rem; - margin-top: 2rem; - margin-bottom: 0; - line-height: 1; } - -p.subtitle { font-style: italic; - margin-top: 1rem; - margin-bottom: 1rem; - font-size: 1.8rem; - display: block; - line-height: 1; } - -.numeral { font-family: et-book-roman-old-style; } - -.danger { color: red; } - -article { position: relative; - padding: 5rem 0rem; } - -section { padding-top: 1rem; - padding-bottom: 1rem; } - -p, ol, ul { font-size: 1.4rem; } - -p { line-height: 2rem; - margin-top: 1.4rem; - margin-bottom: 1.4rem; - padding-right: 0; - vertical-align: baseline; } - -/* Chapter Epigraphs */ -div.epigraph { margin: 5em 0; } - -div.epigraph > blockquote { margin-top: 3em; - margin-bottom: 3em; } - -div.epigraph > blockquote, div.epigraph > blockquote > p { font-style: italic; } - -div.epigraph > blockquote > footer { font-style: normal; } - -div.epigraph > blockquote > footer > cite { font-style: italic; } -/* end chapter epigraphs styles */ - -blockquote { font-size: 1.4rem; } - -blockquote p { width: 55%; - margin-right: 40px; } - -blockquote footer { width: 55%; - font-size: 1.1rem; - text-align: right; } - -section>ol, section>ul { width: 45%; - -webkit-padding-start: 5%; - -webkit-padding-end: 5%; } - -li { padding: 0.5rem 0; } - -figure { padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; - max-width: 55%; - -webkit-margin-start: 0; - -webkit-margin-end: 0; - margin: 0 0 3em 0; } - -figcaption { float: right; - clear: right; - margin-right: -48%; - margin-top: 0; - margin-bottom: 0; - font-size: 1.1rem; - line-height: 1.6; - vertical-align: baseline; - position: relative; - max-width: 40%; } - -figure.fullwidth figcaption { margin-right: 24%; } - -/* Links: replicate underline that clears descenders */ -a:link, a:visited { color: inherit; } - -a:link { text-decoration: none; - background: -webkit-linear-gradient(#fffff8, #fffff8), -webkit-linear-gradient(#fffff8, #fffff8), -webkit-linear-gradient(#333, #333); - background: linear-gradient(#fffff8, #fffff8), linear-gradient(#fffff8, #fffff8), linear-gradient(#333, #333); - -webkit-background-size: 0.05em 1px, 0.05em 1px, 1px 1px; - -moz-background-size: 0.05em 1px, 0.05em 1px, 1px 1px; - background-size: 0.05em 1px, 0.05em 1px, 1px 1px; - background-repeat: no-repeat, no-repeat, repeat-x; - text-shadow: 0.03em 0 #fffff8, -0.03em 0 #fffff8, 0 0.03em #fffff8, 0 -0.03em #fffff8, 0.06em 0 #fffff8, -0.06em 0 #fffff8, 0.09em 0 #fffff8, -0.09em 0 #fffff8, 0.12em 0 #fffff8, -0.12em 0 #fffff8, 0.15em 0 #fffff8, -0.15em 0 #fffff8; - background-position: 0% 93%, 100% 93%, 0% 93%; } - -@media screen and (-webkit-min-device-pixel-ratio: 0) { a:link { background-position-y: 87%, 87%, 87%; } } - -a:link::selection { text-shadow: 0.03em 0 #b4d5fe, -0.03em 0 #b4d5fe, 0 0.03em #b4d5fe, 0 -0.03em #b4d5fe, 0.06em 0 #b4d5fe, -0.06em 0 #b4d5fe, 0.09em 0 #b4d5fe, -0.09em 0 #b4d5fe, 0.12em 0 #b4d5fe, -0.12em 0 #b4d5fe, 0.15em 0 #b4d5fe, -0.15em 0 #b4d5fe; - background: #b4d5fe; } - -a:link::-moz-selection { text-shadow: 0.03em 0 #b4d5fe, -0.03em 0 #b4d5fe, 0 0.03em #b4d5fe, 0 -0.03em #b4d5fe, 0.06em 0 #b4d5fe, -0.06em 0 #b4d5fe, 0.09em 0 #b4d5fe, -0.09em 0 #b4d5fe, 0.12em 0 #b4d5fe, -0.12em 0 #b4d5fe, 0.15em 0 #b4d5fe, -0.15em 0 #b4d5fe; - background: #b4d5fe; } - -/* Sidenotes, margin notes, figures, captions */ -img { max-width: 100%; } - -.sidenote, .marginnote { float: right; - clear: right; - margin-right: -60%; - width: 50%; - margin-top: 0; - margin-bottom: 0; - font-size: 1.1rem; - line-height: 1.3; - vertical-align: baseline; - position: relative; } - -.sidenote-number { counter-increment: sidenote-counter; } - -.sidenote-number:after, .sidenote:before { content: counter(sidenote-counter) " "; - font-family: et-book-roman-old-style; - position: relative; - vertical-align: baseline; } - -.sidenote-number:after { content: counter(sidenote-counter); - font-size: 1rem; - top: -0.5rem; - left: 0.1rem; } - -.sidenote:before { content: counter(sidenote-counter) " "; - top: -0.5rem; } - -blockquote .sidenote, blockquote .marginnote { margin-right: -82%; - min-width: 59%; - text-align: left; } - -p, footer, table { width: 55%; } - -div.fullwidth, table.fullwidth { width: 100%; } - -div.table-wrapper { overflow-x: auto; - font-family: "Trebuchet MS", "Gill Sans", "Gill Sans MT", sans-serif; } - -.sans { font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif; - letter-spacing: .03em; } - -code { font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 1.0rem; - line-height: 1.42; } - -.sans > code { font-size: 1.2rem; } - -h1 > code, h2 > code, h3 > code { font-size: 0.80em; } - -.marginnote > code, .sidenote > code { font-size: 1rem; } - -pre.code { font-size: 0.9rem; - width: 52.5%; - margin-left: 2.5%; - overflow-x: auto; } - -pre.code.fullwidth { width: 90%; } - -.fullwidth { max-width: 90%; - clear:both; } - -span.newthought { font-variant: small-caps; - font-size: 1.2em; } - -input.margin-toggle { display: none; } - -label.sidenote-number { display: inline; } - -label.margin-toggle:not(.sidenote-number) { display: none; } - -@media (max-width: 760px) { body { width: 84%; - padding-left: 8%; - padding-right: 8%; } - p, footer { width: 100%; } - pre.code { width: 97%; } - ul { width: 85%; } - figure { max-width: 90%; } - figcaption, figure.fullwidth figcaption { margin-right: 0%; - max-width: none; } - blockquote { margin-left: 1.5em; - margin-right: 0em; } - blockquote p, blockquote footer { width: 100%; } - label.margin-toggle:not(.sidenote-number) { display: inline; } - .sidenote, .marginnote { display: none; } - .margin-toggle:checked + .sidenote, - .margin-toggle:checked + .marginnote { display: block; - float: left; - left: 1rem; - clear: both; - width: 95%; - margin: 1rem 2.5%; - vertical-align: baseline; - position: relative; } - label { cursor: pointer; } - div.table-wrapper, table { width: 85%; } - img { width: 100%; } }- \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/b9/059b7e-29c0-4e7f-a1c1-901d812109bf/architecture.png b/www/vincent.demeester.fr/content/legacy/articles/data/b9/059b7e-29c0-4e7f-a1c1-901d812109bf/architecture.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/data/d4/868e4e-61bc-4904-b683-f165569f8baf/lifecycle.png b/www/vincent.demeester.fr/content/legacy/articles/data/d4/868e4e-61bc-4904-b683-f165569f8baf/lifecycle.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/development-machines.org b/www/vincent.demeester.fr/content/legacy/articles/development-machines.org @@ -1,434 +0,0 @@ -#+TITLE: Development machines made easy -#+SUBTITLE: From lazyness to awesomeness -#+SETUPFILE: .setup.org - - -#+begin_abstract -Let's dig into how I manage creating and managing development machines. The Why and the -How. -#+end_abstract - -#+TOC: headlines 1 - -For work, I sometimes need to create and use /development/ machines to hack on a specific -case. There is multiple reason I would need to create those machines instead of working -directly on my laptop or desktop. Let's look at those, and how I try to automate the hell -out of it (because I am *really lazy*). - -* Use case -:PROPERTIES: -:CUSTOM_ID: h:f7b73025-0a31-4001-a08d-a5646d6e7be1 -:END: - -Let's look into some use-case that are useful to me - -- Create and/or test packages for a specific distribution — most likely RPM-based (Fedora, - RHEL, …) and Debian-based (Ubuntu, Debian, …). -- From scratch machine, - - to make sure some documentation are complete for people to start - hacking on a project, and using a tool. - - to make demo, recording or something 👼 -- Cluster machines for Kubernetes or Openshift. - -Some requirements and _nice-to-have_: - -- Automate provisioning of these machines. -- Use virtual machine for most case (~libvirt~, ~qemu+kvm~). -- Auto updates of the "provisioning" - -Targeted system are, _for now_ : - -- Fedora, RHEL -- Debian, Ubuntu -- NixOS - -* Base images -:PROPERTIES: -:CUSTOM_ID: h:302d6250-fe7f-42a9-9c1c-0cbfcedf8e62 -:END: - -I initially wanted to use ~packer~ and it has its uses. I mainly need to build images for -virtual machines, and it's even simpler than that, ~qemu~ based virtual machine (using -~libvirt~). For those cases, there is simpler solution: - -- For ~nixos~, a tool seems to be designed for that purpose : [[https://github.com/nix-community/nixos-generators][~nixos-generators~]] -- For ~fedora~, ~ubuntu~ and all, if targeting ~libvirt~, there is a really nice tool : - [[http://libguestfs.org/virt-builder.1.html][~virt-builder~]] from [[http://libguestfs.org/][libguestfs]]. - -#+TOC: headlines 2 local - -** TODO ~virt-builder~ -:PROPERTIES: -:CUSTOM_ID: h:86b2f8d4-a8c7-4b6f-a788-e7a5a681a3d5 -:END: - -** TODO NixOS ~nixos-generators~ -:PROPERTIES: -:CUSTOM_ID: h:5d22d10b-657d-4ca2-a614-577b60d0023e -:END: - -* TODO Provisionning -:PROPERTIES: -:CUSTOM_ID: h:dc187bf7-25a3-4bdd-a021-54ca4b59cf65 -:END: -:LOGBOOK: -- Rescheduled from "[2019-11-07 Thu]" on [2019-11-07 Thu 17:49] -- Rescheduled from "[2019-11-01 Fri]" on [2019-11-04 Mon 09:32] -- Rescheduled from "[2019-10-24 Thu]" on [2019-10-25 Fri 10:07] -- Rescheduled from "[2019-10-18 Fri]" on [2019-10-18 Fri 17:23] -- Rescheduled from "[2019-10-17 Thu]" on [2019-10-17 Thu 18:48] -- Rescheduled from "[2019-10-16 Wed]" on [2019-10-16 Wed 17:04] -- Rescheduled from "[2019-10-14 Mon]" on [2019-10-14 Mon 09:28] -- Rescheduled from "[2019-10-11 Fri]" on [2019-10-11 Fri 20:41] -- Rescheduled from "[2019-10-10 Thu]" on [2019-10-10 Thu 18:22] -CLOCK: [2019-10-10 Thu 15:30]--[2019-10-10 Thu 16:54] => 1:24 -CLOCK: [2019-10-10 Thu 14:18]--[2019-10-10 Thu 22:38] => 8:20 -- Rescheduled from "[2019-10-09 Wed]" on [2019-10-09 Wed 18:35] -- Rescheduled from "[2019-10-08 Tue]" on [2019-10-09 Wed 15:02] -- Rescheduled from "[2019-10-04 Fri]" on [2019-10-06 Sun 14:57] -- Rescheduled from "[2019-10-03 Thu]" on [2019-10-03 Thu 09:58] -- Rescheduled from "[2019-09-30 Mon]" on [2019-10-02 Wed 14:26] -- Rescheduled from "[2019-09-27 Fri]" on [2019-09-27 Fri 11:19] -- Rescheduled from "[2019-09-25 Wed]" on [2019-09-25 Wed 17:23] -- Rescheduled from "[2019-09-17 Tue]" on [2019-09-20 Fri 14:11] -- Rescheduled from "[2019-09-13 Fri]" on [2019-09-13 Fri 16:20] -- Rescheduled from "[2019-09-11 Wed]" on [2019-09-11 Wed 19:19] -- Rescheduled from "[2019-09-10 Tue]" on [2019-09-10 Tue 17:56] -- Rescheduled from "[2019-09-06 Fri]" on [2019-09-06 Fri 16:50] -- Rescheduled from "[2019-09-04 Wed]" on [2019-09-05 Thu 17:34] -CLOCK: [2019-09-04 Wed 10:00]--[2019-09-04 Wed 11:00] => 1:00 -:END: - -Now that we have base images, we can start to play around, most likely with ~ansible~ to -easily and quickly provision setups based on those. Those setups can includes : - -- development environment - + Nix-based (aka Nixos or Nixpkgs on other machines) - + /Native/-based (aka no Nix), Fedora -- multiple node testing environment - -** TODO Development machine -:PROPERTIES: -:CUSTOM_ID: h:b1ad53f3-6ac7-44e1-8fc0-326ef785ec46 -:END: - -There is currently only one, my /main/ development machine, to hack on containers and -orchestration tooling, using mainly go. - -- It doesn't need to be a "workstation", can be a server, I just need a headless - fedora on which I can install stuff and run services. -- It needs to be able to run ~minikube~ or ~crc~, so nested virtualization is required. -- It needs to require the less effort to reset/recreate. -- It needs to have the same IP on the network, always (meaning same MAC address) -- It needs to be "updatable" using provisionning (aka I change the provisionning part, I - apply and go !) - -*** TODO Create the virtal machine -:PROPERTIES: -:CUSTOM_ID: h:bc7d4e4c-76e9-4fc6-9ce6-999f250c4d4c -:END: - -I want to re-use a disk for ~/home~ (or at least ~$HOME/src~) so that I can just re-attach -it later on. We are assuming we have a base image working here, see [[*~virt-builder~][~virt-builder~]]. - -#+begin_src bash -virsh --connect=qemu+tcp://wakasu.home:16509/system list -#+end_src - -#+RESULTS: -| Id | Name | State | -| ---------------------------- | | | -| 2 | fedora-dev | running | - - -*** TODO Base system -:PROPERTIES: -:CUSTOM_ID: h:af99c176-b991-433e-8070-17b38a8fb82a -:END: - -- zsh -- bash -- exa -- htop -- ssh/shhd - -*** TODO Virtualization tooling -:PROPERTIES: -:CUSTOM_ID: h:6cbfd75a-6dbd-4b6b-8b63-c7c92db04e77 -:END: - -- nested virt => @virtualization, libvirt-devel - -*** TODO Containers tooling -:PROPERTIES: -:CUSTOM_ID: h:8a9a0d74-00d4-458f-a481-1620de380a4f -:END: - -- podman-docker -- buildah -- skopeo - -- ko -- kubectl -- google-cloud-sdk - -*** TODO Developers tooling -:PROPERTIES: -:CUSTOM_ID: h:cbbb7ea9-a553-4029-b755-d3d2f6894ced -:END: - -*** TODO Nix setup ? -:PROPERTIES: -:CUSTOM_ID: h:27836d1b-e7f9-4274-b3ca-37909e72daaa -:END: - -** TODO Kubernetes cluster -:PROPERTIES: -:CUSTOM_ID: h:77a3cff7-20d4-416b-bb1d-b772196b1f3e -:END: - -* References -:PROPERTIES: -:CUSTOM_ID: h:9c4d79c4-726c-424c-8d27-3f819532d1ae -:END: - -- https://github.com/SkypLabs/packer-debian -- https://github.com/SkypLabs/packer-centos -- https://github.com/idi-ops/packer-fedora -- https://github.com/rustic/fedora29-minimal -- https://github.com/terusus/packer-ansible-arch -- https://github.com/jogleasonjr/packer-arch -- https://github.com/karolistamutis/packer-archlinux -- https://developer.fedoraproject.org/tools/virt-builder/about.html -- https://computingforgeeks.com/virsh-commands-cheatsheet/ -- https://help.ubuntu.com/community/KVM/Virsh - -* Archives -:PROPERTIES: -:CUSTOM_ID: h:1f6e052f-3df2-415c-a7a1-e1eb9ae3f6c0 -:END: -** Packer -:PROPERTIES: -:CUSTOM_ID: h:62c6b7b1-0ab4-4ab6-9dad-edd9e2d7c54e -:END: -Let's use [[https://packer.io/][~packer~]] with qemu for those cases — and let's create a repository where we're -gonna write the development machine recipes : [[https://github.com/vdemeester/machines][~vdemeester/machines~]]. - -#+TOC: headlines 2 local - -*** NixOS recipes -:PROPERTIES: -:CUSTOM_ID: h:edba86e1-0aa2-43a7-832b-60bfd5bf3727 -:ID: f76c12a3-c9da-4cf8-bdbf-ab74865c3e0e -:END: - -The initial source of packer recipes comes from [[https://github.com/nix-community/nixbox][~nix-community/nixbox~]], but I'm -/tailoring/ them to my needs - -#+begin_src json - { - "builders": [ - { - "boot_wait": "40s", - "boot_command": [ - "echo http://{{ .HTTPIP }}:{{ .HTTPPort}} > .packer_http<enter>", - "mkdir -m 0700 .ssh<enter>", - "curl $(cat .packer_http)/install_rsa.pub > .ssh/authorized_keys<enter>", - "systemctl start sshd<enter>" - ], - "http_directory": "scripts", - "iso_checksum_type": "sha256", - "shutdown_command": "shutdown -h now", - "ssh_private_key_file": "./scripts/install_rsa", - "ssh_port": 22, - "ssh_username": "root", - "type": "qemu", - "iso_url": "https://d3g5gsiof5omrk.cloudfront.net/nixos/18.09/nixos-18.09.1799.b9fa31cea0e/nixos-minimal-18.09.1799.b9fa31cea0e-x86_64-linux.iso", - "iso_checksum": "cc7c399c5fe4672383fe54cb1d648854a0d6732765fe1a61bb38b3fe3b7c6d2f", - "disk_interface": "virtio-scsi", - "qemuargs": [ - [ - "-m", - "1024" - ] - ] - } - ], - "provisioners": [ - { - "type": "shell", - "script": "./scripts/install.sh" - } - ] - } -#+end_src - -Let's look at the provisioning script. We don't want to create a full specific -configuration for these images as we will use ~ansible~ for the final provisioning. - -- ~scripts/install.sh~ - - #+begin_src bash - #!/bin/sh -e - - packer_http=$(cat .packer_http) - - # Partition disk - cat <<FDISK | fdisk /dev/sda - n - - - - - a - w - - FDISK - - # Create filesystem - mkfs.ext4 -j -L nixos /dev/sda1 - - # Mount filesystem - mount LABEL=nixos /mnt - - # Setup system - nixos-generate-config --root /mnt - - curl -sf "$packer_http/machine.nix" > /mnt/etc/nixos/machine.nix - curl -sf "$packer_http/builders/$PACKER_BUILDER_TYPE.nix" > /mnt/etc/nixos/hardware-builder.nix - curl -sf "$packer_http/configuration.nix" > /mnt/etc/nixos/configuration.nix - curl -sf "$packer_http/custom-configuration.nix" > /mnt/etc/nixos/custom-configuration.nix - - ### Install ### - nixos-install - - ### Cleanup ### - curl "$packer_http/postinstall.sh" | nixos-install - #+end_src -- ~scripts/postinstall.sh~ - #+begin_src bash - #!/bin/sh - - # Make sure we are totally up to date - nix-channel --add https://nixos.org/channels/nixos-18.09 nixos - nix-channel --update - nixos-rebuild switch --upgrade - - # Cleanup any previous generations and delete old packages that can be - # pruned. - - for x in $(seq 0 2) ; do - nix-env --delete-generations old - nix-collect-garbage -d - done - - - # Remove install ssh key - rm -rf /root/.ssh /root/.packer_http - - # Zero out the disk (for better compression) - dd if=/dev/zero of=/EMPTY bs=1M - rm -rf /EMPTY - #+end_src -- ~scripts/machine.nix~ - #+begin_src nix - # This file is overwritten by the vagrant-nixos plugin - { config, pkgs, ... }: - { - networking.hostName = "nixos-machine"; - } - #+end_src -- ~scripts/configuration.nix~ - #+begin_src nix - { config, pkgs, ... }: - - { - imports = - [ # Include the results of the hardware scan. - ./hardware-configuration.nix - ./hardware-builder.nix - ./machine.nix - ./custom-configuration.nix - ]; - - # Use the GRUB 2 boot loader. - boot.loader.grub.enable = true; - boot.loader.grub.version = 2; - boot.loader.grub.device = "/dev/sda"; - - # remove the fsck that runs at startup. It will always fail to run, stopping - # your boot until you press *. - boot.initrd.checkJournalingFS = false; - - # Services to enable: - - # Enable the OpenSSH daemon. - services.openssh.enable = true; - - # Enable DBus - services.dbus.enable = true; - - # Replace nptd by timesyncd - services.timesyncd.enable = true; - - # Packages for Vagrant - environment.systemPackages = with pkgs; [ - iputils - ]; - - # Creates a "vincent" users with password-less sudo access - users = { - extraGroups = [ { name = "vincent"; } ]; - extraUsers = [ - # Try to avoid ask password - { name = "root"; password = "vincent"; } - { - description = "Vincent User"; - name = "vincent"; - group = "vincent"; - extraGroups = [ "users" "wheel" ]; - password = "vincent"; - home = "/home/vincent"; - createHome = true; - useDefaultShell = true; - openssh.authorizedKeys.keys = [ - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDO1sx5h44xnK/k0ODnQ3aQR8+nr7HC7u94fS3OhwQ6AvjqDGLnI6EP4sr4Yh2eXf8lHX+lkg8iZ6Z+y9dVnnzwveZfqbfOyh6t8Hg+M1nl26rwdYv+guU8khvh+Kzl9Vdb5dexf/hWQ/LcWvsuPO+tBmqajNTLYbGinqrMm3Bw2jJS/+DitgoT8hiuSTU1smY1CGzggHEdsx4+oDMuDMvRYwOBBHrUF00lZLx3zB3nGl1VFYD2St3vzlmzoZNrW7Rx8TRg02BTVAwd4qPHOMz8Kg+JmDhVig9yeqHo4FCwXxQ8+jk54Cd2el6TjfaA5HD2+e4FYLP6bMSLIabLTfLP vincent@wakasu" - ]; - } - ]; - }; - - security.sudo.configFile = - '' - Defaults:root,%wheel env_keep+=LOCALE_ARCHIVE - Defaults:root,%wheel env_keep+=NIX_PATH - Defaults:root,%wheel env_keep+=TERMINFO_DIRS - Defaults env_keep+=SSH_AUTH_SOCK - Defaults lecture = never - root ALL=(ALL) SETENV: ALL - %wheel ALL=(ALL) NOPASSWD: ALL, SETENV: ALL - ''; - - } - #+end_src -- ~scripts/custom-configuration.nix~ - #+begin_src nix - { config, pkgs, ... }: - - { - # Place here any custom configuration specific to your organisation (locale, ...) - # if you want it to be part of the packer base image to be used with vagrant. - } - #+end_src -- ~scripts/builders/qemu.nix~ - #+begin_src nix - { modulesPath, ... }: - { - imports = [ - "${toString modulesPath}/profiles/qemu-guest.nix" - ]; - } - #+end_src - - -And to build this image, a simple ~packer build nixos.json~ is required. diff --git a/www/vincent.demeester.fr/content/legacy/articles/documentation.org b/www/vincent.demeester.fr/content/legacy/articles/documentation.org @@ -1,64 +0,0 @@ -#+TITLE: Documentation -#+FILETAGS: language programming documentation -#+SETUPFILE: .setup.org - -* Documentation :docs:#link: - -** [[https://documentation.divio.com/][Documentation System]] -[2021-10-15 Fri 17:27] - -#+begin_quote -The Grand Unified Theory of Documentation -— David Laing - -There is a secret that needs to be understood in order to write good software -documentation: there isn’t one thing called documentation, there are four. - -They are: tutorials, how-to guides, technical reference and explanation. They represent -four different purposes or functions, and require four different approaches to their -creation. Understanding the implications of this will help improve most documentation - -often immensely. -#+end_quote - -This is a set of resources around how setup a system to document your software/product -correctly. And there is *four* distinctive type of documentation (different style of writing): - -- Tutorials — /learning-oriented/ - Usually the most important to "get-in", and usually not very well done. -- How-to Guides — /problem-oriented/ - Series of step required to solve a real-world problem. -- Explanation — /understanding-oriented/ -- References — /information-oriented/ - -#+NAME: Overview -[[./images/documentation/overview.png]] - -Given how wide is this set of pages, I might link several sub-entries here. - -[[https://www.youtube.com/watch?v=t4vKPhjcMZg][What nobody tells you about documentation]] is the video from the author(s) of this set of pages. - -** [[https://8thlight.com/blog/martin-gaston/2019/10/22/tips-for-technical-writing.html][Tips for Technical Writing | 8th Light]] -[2019-10-28 Mon 08:21] - -#+begin_quote -Do you struggle to write blog posts? Developing your craft when it comes to writing can be -as intimidating as the buggiest code. - -Refining your writing will be another fascinating challenge on your path to mastery. At -its best, writing can be very satisfying. While it might feel daunting now, in time it -could become something you take real pleasure in. - -Yet it can sure feel difficult and daunting to establish yourself in this space. What -should you write about? How should you get started? How often should you publish your -work? Where? When? - -It's a lot to take in. - -This post contains some advice to anyone aspiring to technical writing on the web. Also -included are some creative writing exercises to help develop your thinking. -#+end_quote - -One very interesting part of this article is the template part of it: -- Beginning :: /What are you going to tell me/ -- Middle :: /The telling/ -- End :: /What did you tell me/ diff --git a/www/vincent.demeester.fr/content/legacy/articles/dogfooding.org b/www/vincent.demeester.fr/content/legacy/articles/dogfooding.org @@ -1,9 +0,0 @@ - -#+TITLE: dogfooding -#+ROAM_ALIAS: "Dogfooding" - -Usually, "dogfooding" means /eat your own food/. In the software engineer world, it -usually means /using what your are building/. It is, of course, easier to achieve if you -are a developer and are building tools for developers 😛. - -I am trying to apply that for my work, aka [[file:openshift.org][OpenShift]], [[file:openshift_pipeline.org][OpenShift Pipeline]] and [[file:tekton.org][Tekton]]. diff --git a/www/vincent.demeester.fr/content/legacy/articles/emacs.old.org b/www/vincent.demeester.fr/content/legacy/articles/emacs.old.org @@ -1,1105 +0,0 @@ -#+title: My Emacs System -#+SUBTITLE: A attempt to document my emacs setup 🙃 -#+ROAM_ALIAS: "emacs" "Emacs" "GNU/Emacs" "gnu/emacs" - -Emacs is the best editor possible, at least for me, especially with the killer [[file:org_mode.org][org-mode]] -module. - -I do all in a lot in Emacs: -- task and calendar management using [[file:org_mode.org][org-mode]]. -- mail using [[file:gnus.org][gnus]]. -- programming in different languages ([[file:elisp.org][elisp]], [[file:go.org][go]], [[file:bash.org][bash]], …) -- interactive shell using either [[file:eshell.org][eshell]] or [[file:vterm.org][vterm]]. - -This is my attempt to document my Emacs setup, inspired by [[https://writequit.org/eos/eos.html][The Emacs Operating System -(EOS)]] or [[http://doc.rix.si/cce/cce.html][Complete Computing Environment]] and other litterate configurations, see -[[id:575a424a-8121-40d9-85bd-ac4975818a8d][Inspirations]]. In a gist, this is the litterate version of the [[file:config_configurations.org][configurations]] available in -my [[https://git.sr.ht/~vdemeester/home][monorepo]]. - -#+TOC: headlines 1 - -* What is this - -The present document, referred to in the source code version as =emacs.org=, contains the -bulk of my configurations for GNU Emacs. It is designed using principles of "literate -programming": a combination of ordinary language and inline code blocks. Emacs knows how -to parse this file properly so as to evaluate only the elisp ("Emacs Lisp") included -herein. The rest is for humans to make sense of my additions and their underlying -rationale. - -#+BEGIN_QUOTE -Literate programming allows us to be more expressive and deliberate. Not only we can use -typography to its maximum potential, but can also employ techniques such as internal links -between sections. This makes the end product much better for end users, than a terse -script. -#+END_QUOTE - -I switched back and forth on using =org-mode= and literate programming, so why re-using -it. First, I think I went for it the wrong way the first time. I copied part of the -configuration from elsewhere, sometimes without really needing what I was copying. for -some reason I think this is a common pattern when configuring Emacs. You start by using a -distribution (Doom Emacs, Spacemacs, …) or by copying configuration from all over the -place. Slowly but surely you realize this was a mistake as you didn't learn anything, so -you *reboot* your configuration. - - -* Why using GNU/Emacs ? - -This is a question I thought I needed to answer, or at least, document why I am choosing -GNU/Emacs as my primary editor. [[https://protesilaos.com/][Protesilaos Stavrou]] has a [[https://protesilaos.com/codelog/2019-12-20-vlog-switch-emacs/][video]] about it, really -interesting. - -There is a lot of reasons but for me, the following are the main ones: -- *Open Source*: this is a "of course", but my editor _has to be_ open-sourced. This seems - to be the norm these days anyway (and for a long time, with =vim=). -- *Lightweight*: the editor should be relatively lightweight. I don't want a full browser - loaded to edit files, and I want to be able to run it in a terminal, on a server. =vim= - can do that (and sometimes, =vim= or =vi= is enough 👼). -- *Extensible*: to be honest, this is the most important reason. I want to be able to - extend my editor as much as possible. - -GNU/Emacs checks all the boxes for me. Even though GNU/Emacs is probably not as -lightweight as =vim=, it is definitely lightweight compared to all the Electron-based -editors (vscode, …). It is of course open-source, and since ages (almost as old as I am -😅). And best of all, GNU/Emacs is extensible as you couldn't dream of. Emacs is a lisp -interpreter, and it is designed to be extended in order to meet the user's -needs. /Extensibility/ is the quintessential Emacs quality. You can modify any piece of -elisp /in real time/. - -I'm also a huge fan of /text-based/ software, a.k.a. do whatever you can using text : -reading mails, news, organizing notes and todos, all can be done in text. And GNU/Emacs -shines at this. For emails and news, you've got Gnus built-in, for notes and todos, the -wonderful =org-mode= is the best thing on earth (seriously, this is the *one* mode that -made me switch from =vim=). - -* Assumptions - -I'll make a few assumption in the following document (that may or may not be true): - -- [[https://nixos.org/nix/][~nix~]] is available, either from [[https://nixos.org][NixOS]] or via an install of nix. I'll try my best to - support non-nix environment, but it's definitely not my current focus. - + As I am making the assumption that ~nix~ is available, I am also making the assumption - that all the library required are already present (in my [[https://github.com/vdemeester/home][~home~]], there is a file - called [[https://github.com/vdemeester/home/blob/master/modules/profiles/emacs.nix][~emacs.nix~]] that encapsulate those dependencies). This is why, by default - *use-package* doesn't use the =ensure= option in 99% of the configuration. -- Any function I wrote is going to be prefixed by ~vde/~ so that it doesn't conflicts with - function that would have been defined elsewhere. -- Any function imported from another configuration, without any change, should be kept as - is and/or prefixed by an unique id. I'll try to make sure to link to the configuration - too. -* Keybinding -:PROPERTIES: -:ID: 5f74193a-03ed-4336-8746-fb1d514a5484 -:END: - -As it is detailed in each part of this configuration, I am trying to setup keybinding in a -/mnemonics/ way so it's easy to remember (and use). This is what [[https://www.spacemacs.org/][spacemacs]] does with evil -keybindings (aka vim-like keybindings). I am staying with the /standard/ emacs keybinding -as much as possible (as there is already some mnemonics in there). - -There are countless jokes and comics on Emacs’s seemingly ridiculous keybindings. Good -laughs indeed, but at the end of day, it’s not incomprehensible. It has well-defined -conventions listed at [[https://www.gnu.org/software/emacs/manual/html%5Fnode/elisp/Key-Binding-Conventions.html][Emacs Key Bindings Convention]]. In summary, the general rules are: - -+ =C-x= reserved for Emacs native essential keybindings: buffer, window, frame, file, directory, etc… -+ =C-c= reserved for user and major mode: - - =C-c letter= reserved for user. =<F5>=-=<F9>= reserved for user. - - =C-c C-letter= reserved for major mode. -+ Don’t rebind =C-g=, =C-h= and =ESC=. - -To give a small example, most of my personal =org-mode= keybinding will start with =C-c -o=, as it is reserved for user, and =o= is for =org-mode=. For version control, it's gonna -be =C-c v=, for projects it's gonna be =C-c p=, etc… - -| prefix | "mode" | -|---------+-------------------------------------| -| <F1> | | -| <F2> | | -| <F3> | /built-in/ Register macro(s) | -| <F4> | /built-in/ Plays macro(s) | -| <F5> | =revert-buffer= | -| <F6> | | -| <F7> | | -| <F8> | | -| <F9> | | -| <F10> | | -| <F11> | | -| <F12> | | -| =C-c b= | Bookmarks (=bookmark-plus=) | -| =C-c h= | Help (=helpful=, …) | -| =C-c n= | Navigation (=avy=, …) | -| =C-c o= | Org mode | -| =C-c p= | Projects (=projectile=, …) | -| =C-c v= | Version control (=vc=, =magit=, …) | -| =C-c w= | Window management (=ace-window=, …) | -| =C-x p= | Bookmarks (=bookmark-plus=, …) | - -This table is not complete and I don't intend to keep it complete here. Instead, there -should be a table like this on each configuration file to describe what this config brings -as keybinding. - -See also: -- https://karl-voit.at/2018/07/08/emacs-key-bindings/ -- https://www.masteringemacs.org/article/mastering-key-bindings-emacs -- http://www.wilfred.me.uk/blog/2018/01/06/the-emacs-guru-guide-to-key-bindings/ -* COPYING - -Copyright (c) 2013-2020 Vincent Demeester <vincent@sbr.pm> - -This file is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at -your option) any later version. - -This file is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this file. If not, see <http://www.gnu.org/licenses/>. -* Base settings -:PROPERTIES: -:header-args: :tangle ~/src/home/tools/emacs/init.el -:header-args+: :comments org -:END: - -This section contains configurations that are needed prior to the setup of everything -else. Anything that needs to be configured first should be in there, this includes the -~init.el~ and ~early-init.el~ files content. - -** Early initialization -:PROPERTIES: -:header-args: :tangle ~/src/home/tools/emacs/early-init.el -:header-args+: :comments org -:ID: 317fc8fd-1220-423d-8a45-497f951014ee -:END: - -Starting with Emacs 27, an =early-init.el= file can be used to do early configuration -and optimization. - -#+begin_quote -Emacs can now be configured using an early init file. The file is called ~early-init.el~, -in ~user-emacs-directory~. It is loaded very early in the startup process: before -graphical elements such as the tool bar are initialized, and before the package manager is -initialized. The primary purpose is to allow customizing how the package system is -initialized given that initialization now happens before loading the regular init file -(see below). - -We recommend against putting any customizations in this file that don't need to be set up -before initializing installed add-on packages, because the early init file is read too -early into the startup process, and some important parts of the Emacs session, such as -'window-system' and other GUI features, are not yet set up, which could make some -customization fail to work. -#+end_quote - -We can use this to our advantage and optimize the initial loading of emacs. - -- Before Emacs 27, the init file was responsible for initializing the package manager by - calling `package-initialize'. Emacs 27 changed the default behavior: It now calls - `package-initialize' before loading the init file. - - #+begin_src emacs-lisp - (setq package-enable-at-startup nil) - #+end_src - -- Let's inhibit resizing the frame at early stage. - - #+begin_src emacs-lisp - (setq frame-inhibit-implied-resize t) - #+end_src - -- I never use the /menu-bar/, or the /tool-bar/ or even the /scroll-bar/, so we can safely - disable those very very early. - - #+begin_src emacs-lisp - (menu-bar-mode -1) - (tool-bar-mode -1) - (scroll-bar-mode -1) - (horizontal-scroll-bar-mode -1) - #+end_src - -- Finally we can try to avoid garbage collection at startup. The garbage collector can - easily double startup time, so we suppress it at startup by turning up ~gc-cons-threshold~ - (and perhaps ~gc-cons-percentage~) temporarily. - - #+begin_src emacs-lisp - (setq gc-cons-threshold 402653184 - gc-cons-percentage 0.6) - #+end_src - -- Another small optimization concerns on =file-name-handler-alist= : on every .el and .elc - file loaded during start up, it has to runs those regexps against the filename ; setting - it to ~nil~ and after initialization finished put the value back make the initialization - process quicker. - - #+begin_src emacs-lisp - (defvar file-name-handler-alist-original file-name-handler-alist) - (setq file-name-handler-alist nil) - #+end_src - - However, it is important to reset it eventually. Not doing so will cause garbage - collection freezes during long-term interactive use. Conversely, a ~gc-cons-threshold~ - that is too small will cause stuttering. This will be done at the end. - -- It's also possible to put the theme *and* the font in =early-init.el= to speed the - start. - - #+begin_src emacs-lisp - (defvar contrib/after-load-theme-hook nil - "Hook run after a color theme is loaded using `load-theme'.") - - (defun contrib/run-after-load-theme-hook (&rest _) - "Run `contrib/after-load-theme-hook'." - (run-hooks 'contrib/after-load-theme-hook)) - - (advice-add #'load-theme :after #'contrib/run-after-load-theme-hook) - (require 'modus-operandi-theme) - - (defun vde/modus-operandi () - "Enable some Modus Operandi variables and load the theme. - This is used internally by `vde/modus-themes-toggle'." - (setq modus-operandi-theme-slanted-constructs t - modus-operandi-theme-bold-constructs t - modus-operandi-theme-subtle-diffs t - modus-operandi-theme-rainbow-headings t - modus-operandi-theme-section-headings nil - modus-operandi-theme-scale-headings nil - modus-operandi-theme-fringes 'subtle ; {nil,'subtle,'intense} - modus-operandi-theme-mode-line '3d ; {nil,'3d,'moody} - modus-operandi-theme-3d-modeline t - modus-operandi-theme-faint-syntax nil - modus-operandi-theme-intense-hl-line t - modus-operandi-theme-intense-paren-match t - modus-operandi-theme-prompts 'subtle ; {nil,'subtle,'intense} - modus-operandi-theme-completions 'opinionated ; {nil,'moderate,'opinionated} - modus-operandi-theme-diffs 'desaturated ; {nil,'desaturated,'fg-only} - modus-operandi-theme-org-blocks 'greyscale ; {nil,'greyscale,'rainbow} - modus-operandi-theme-variable-pitch-headings nil - modus-operandi-theme-rainbow-headings t - modus-operandi-theme-section-headings nil - modus-operandi-theme-scale-headings t - modus-operandi-theme-scale-1 1.05 - modus-operandi-theme-scale-2 1.1 - modus-operandi-theme-scale-3 1.15 - modus-operandi-theme-scale-4 1.2) - (load-theme 'modus-operandi t)) - - (defun vde/modus-operandi-custom () - "Customize modus-operandi theme" - (if (member 'modus-operandi custom-enabled-themes) - (modus-operandi-theme-with-color-variables ; this macro allows us to access the colour palette - (custom-theme-set-faces - 'modus-operandi - `(whitespace-tab ((,class (:background "#ffffff" :foreground "#cccccc")))) - `(whitespace-space ((,class (:background "#ffffff" :foreground "#cccccc")))) - `(whitespace-hspace ((,class (:background "#ffffff" :foreground "#cccccc")))) - `(whitespace-newline ((,class (:background "#ffffff" :foreground "#cccccc")))) - `(whitespace-indentation ((,class (:background "#ffffff" :foreground "#cccccc")))) - )))) - - (add-hook 'contrib/after-load-theme-hook 'vde/modus-operandi-custom) - (vde/modus-operandi) - - (defconst font-height 130 - "Default font-height to use.") - (defconst font-family-mono "Ubuntu Mono" - "Default monospace font-family to use.") - (defconst font-family-sans "Ubuntu Sans" - "Default sans font-family to use.") - ;; Middle/Near East: שלום, السّلام عليكم - (when (member "Noto Sans Arabic" (font-family-list)) - (set-fontset-font t 'arabic "Noto Sans Arabic")) - (when (member "Noto Sans Hebrew" (font-family-list)) - (set-fontset-font t 'arabic "Noto Sans Hebrew")) - ;; Africa: ሠላም - (when (member "Noto Sans Ethiopic" (font-family-list)) - (set-fontset-font t 'ethiopic "Noto Sans Ethiopic")) - - ;; If font-family-mono or font-family-sans are not available, use the default Emacs face - (when (member font-family-mono (font-family-list)) - (set-face-attribute 'default nil - :family font-family-mono - :height font-height) - (set-face-attribute 'fixed-pitch nil - :family font-family-mono)) - (when (member font-family-sans (font-family-list)) - (set-face-attribute 'variable-pitch nil - :family font-family-sans - :weight 'regular)) - - ;; Ignore X resources; its settings would be redundant with the other settings - ;; in this file and can conflict with later config (particularly where the - ;; cursor color is concerned). - (advice-add #'x-apply-session-resources :override #'ignore) - #+end_src - -- Reseting garbage collection and file-name-handler values. - - #+begin_src emacs-lisp - (add-hook 'after-init-hook - `(lambda () - (setq gc-cons-threshold 67108864 ; 64mb - gc-cons-percentage 0.1 - file-name-handler-alist file-name-handler-alist-original) - (garbage-collect)) t) - #+end_src - -** Initialization -:PROPERTIES: -:ID: a8fe7fee-d339-4854-9b75-c627adce788a -:END: - -I am using the [[https://archive.casouri.cat/note/2020/painless-transition-to-portable-dumper/index.html][portable dump]] feature (/to speed things up/) *but* I want to also start -without =pdump=, so I need to take both cases into account. - -#+begin_src emacs-lisp -(defvar sbr-dumped nil - "non-nil when a dump file is loaded (because dump.el sets this variable).") - -(defmacro sbr-if-dump (then &rest else) - "Evaluate IF if running with a dump file, else evaluate ELSE." - (declare (indent 1)) - `(if sbr-dumped - ,then - ,@else)) - -(sbr-if-dump - (progn - (global-font-lock-mode) - (transient-mark-mode) - (setq load-path sbr-dumped-load-path)) - ;; add load-path’s and load autoload files - (package-initialize)) -#+end_src - -First thing first, let's define a =emacs-start-time= constant to be able to compute the -time Emacs took to start. - -#+begin_src emacs-lisp -(defconst emacs-start-time (current-time)) -#+end_src - -My configuration do not support Emacs version lower than 26. - -#+begin_src emacs-lisp -(let ((minver 26)) - (unless (>= emacs-major-version minver) - (error "Your Emacs is too old -- this configuration requires v%s or higher" minver))) -#+end_src - -One thing though, I am currently not necessarily running Emacs 27, so I am going to need -to have the same configuration in ~init.el~ for a little bit of time. - -/Note: the lowest emacs version I wanna support is 26 (as of today, might evolve)/ - -#+begin_src emacs-lisp -;; load early-init.el before Emacs 27.0 -(unless (>= emacs-major-version 27) - (message "Early init: Emacs Version < 27.0") - (load (expand-file-name "early-init.el" user-emacs-directory))) -#+end_src - -We also want our configuration to be working the same on any computer, this means we want -to define every option by ourselves, not relying on default files (~default.el~) that -would be set by our distribution. This is where =inhibit-default-init= comes into play, -setting it to non-nil inhibit loading the ~default~ library. - -We also want to inhibit some initial default start messages and screen. The default screen -will be as bare as possible. - -#+begin_src emacs-lisp -(setq inhibit-default-init t) ; Disable the site default settings - -(setq inhibit-startup-message t - inhibit-startup-screen t) -#+end_src - -Let's also use =y= or =n= instead of =yes= and =no= when exiting Emacs. - -#+begin_src emacs-lisp -(setq confirm-kill-emacs #'y-or-n-p) -#+end_src - -One last piece to the puzzle is the default mode. Setting it to fundamental-mode means we -won't load any /heavy/ mode at startup (like =org-mode=). We also want this scratch buffer -to be empty, so let's set it as well - -#+begin_src emacs-lisp -(setq initial-major-mode 'fundamental-mode - initial-scratch-message nil) -#+end_src - -** Unicode all the way -:PROPERTIES: -:ID: e98f57c6-565a-4919-8ecb-f12e939dab03 -:END: - -By default, all my systems are configured and support =utf-8=, so let's just make it a -default in Emacs ; and handle special case on demand. - -#+begin_src emacs-lisp -(prefer-coding-system 'utf-8) -(set-default-coding-systems 'utf-8) -(set-language-environment 'utf-8) -(set-selection-coding-system 'utf-8) -(set-terminal-coding-system 'utf-8) -#+end_src - -** Package management with =use-package= -:PROPERTIES: -:ID: d2d75dfe-5085-4655-a81f-b6033f273f6f -:END: - -=use-package= is a tool that streamlines the configuration of packages. It handles -everything from assigning key bindings, setting the value of customisation options, -writing hooks, declaring a package as a dependency for another, and so on. - -#+begin_quote -The =use-package= macro allows you to isolate package configuration in your =.emacs= file -in a way that is both performance-oriented and, well, tidy. I created it because I have -over 80 packages that I use in Emacs, and things were getting difficult to manage. Yet -with this utility my total load time is around 2 seconds, with no loss of functionality! -#+end_quote - -With =use-package= we can improve the start-up performance of Emacs in a few fairly simple -ways. Whenever a command is bound to a key it is configured to be loaded only once -invoked. Otherwise we can specify which functions should be autoloaded by means of the -=:commands= keyword. - -We need to setup the emacs package system and install =use-package= if not present -already. - -#+begin_src emacs-lisp -(require 'package) - -(setq package-archives - '(("melpa" . "http://melpa.org/packages/") - ("org" . "https://orgmode.org/elpa/") - ("gnu" . "https://elpa.gnu.org/packages/"))) - -(setq package-archive-priorities - '(("melpa" . 3) - ("org" . 2) - ("gnu" . 1))) - -(require 'tls) - -;; From https://github.com/hlissner/doom-emacs/blob/5dacbb7cb1c6ac246a9ccd15e6c4290def67757c/core/core-packages.el#L102 -(setq gnutls-verify-error (not (getenv "INSECURE")) ; you shouldn't use this - tls-checktrust gnutls-verify-error - tls-program (list "gnutls-cli --x509cafile %t -p %p %h" - ;; compatibility fallbacks - "gnutls-cli -p %p %h" - "openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof")) - -;; Initialise the packages, avoiding a re-initialisation. -(unless (bound-and-true-p package--initialized) - (setq package-enable-at-startup nil) - (package-initialize)) - -(setq load-prefer-newer t) ; Always load newer compiled files -(setq ad-redefinition-action 'accept) ; Silence advice redefinition warnings - -;; Init `delight' -(unless (package-installed-p 'delight) - (package-refresh-contents) - (package-install 'delight)) - -;; Configure `use-package' prior to loading it. -(eval-and-compile - (setq use-package-always-ensure nil) - (setq use-package-always-defer nil) - (setq use-package-always-demand nil) - (setq use-package-expand-minimally nil) - (setq use-package-enable-imenu-support t)) - -(unless (package-installed-p 'use-package) - (package-refresh-contents) - (package-install 'use-package)) - -(eval-when-compile - (require 'use-package)) -#+end_src -** Early environment setup -:PROPERTIES: -:ID: de0aad38-4742-4601-9fe6-c659ddc76bcb -:END: - -I want to *force* ==SSH_AUTH_SOCK= in Emacs to use my gpg-agent. - -#+begin_src emacs-lisp -(setenv "SSH_AUTH_SOCK" "/run/user/1000/gnupg/S.gpg-agent.ssh") -#+end_src - -** =custom.el= -:PROPERTIES: -:ID: afd8123e-1461-4f65-a9b7-c8195f1054c8 -:END: - -When you install a package or use the various customisation interfaces to tweak things to -your liking, Emacs will append a piece of elisp to your init file. I prefer to have that -stored in a separate file. - -#+begin_src emacs-lisp -(defconst vde/custom-file (locate-user-emacs-file "custom.el") - "File used to store settings from Customization UI.") - -(use-package cus-edit - :config - (setq - custom-file vde/custom-file - custom-buffer-done-kill nil ; Kill when existing - custom-buffer-verbose-help nil ; Remove redundant help text - custom-unlispify-tag-names nil ; Show me the real variable name - custom-unlispify-menu-entries nil) - (unless (file-exists-p custom-file) - (write-region "" nil custom-file)) - - (load vde/custom-file 'no-error 'no-message)) -#+end_src - -** Remove built-in =org-mode= -:PROPERTIES: -:ID: b2b2ac61-2ce6-4a86-b67c-88592bc0f111 -:END: - -I want to make sure I am using the installed version of =orgmode= (from my org -configuration) instead of the built-in one. To do that safely, let's remove the built-in -version out of the load path. - -#+begin_src emacs-lisp -(require 'cl-seq) -(setq load-path - (cl-remove-if - (lambda (x) - (string-match-p "org$" x)) - load-path)) -#+end_src - -** Loading configuration files -:PROPERTIES: -:ID: ca8dd6f8-47c1-40bd-932b-baf3fb9e6407 -:END: - -This =org-mode= document /tangles/ into several files in different folders : -- ~config~ for my configuration -- ~lisp~ for imported code or library I've written and not yet published - -I used to load them by hand in the ~init.el~ file, which is very cumbersome, so let's try -to automatically load them. I want to first load the file in the ~lisp~ folder as they are -potentially used by my configuration (in ~config~). - -Let's define some functions that would do the job. - -#+begin_src emacs-lisp -(defun vde/el-load-dir (dir) - "Load el files from the given folder" - (let ((files (directory-files dir nil "\.el$"))) - (while files - (load-file (concat dir (pop files)))))) - -(defun vde/short-hostname () - "Return hostname in short (aka wakasu.local -> wakasu)" - (string-match "[0-9A-Za-z-]+" system-name) - (substring system-name (match-beginning 0) (match-end 0))) -#+end_src - -Let's define some constants early, based on the system, and the environment, to be able to -use those later on to skip some package or change some configuration accordingly. - -#+begin_src emacs-lisp -(defconst *sys/gui* - (display-graphic-p) - "Are we running on a GUI Emacs ?") -(defconst *sys/linux* - (eq system-type 'gnu/linux) - "Are we running on a GNU/Linux system?") -(defconst *sys/mac* - (eq system-type 'darwin) - "Are we running on a Mac system?") -(defconst *sys/root* - (string-equal "root" (getenv "USER")) - "Are you a ROOT user?") -(defconst *nix* - (executable-find "nix") - "Do we have nix? (aka are we running in NixOS or a system using nixpkgs)") -(defconst *rg* - (executable-find "rg") - "Do we have ripgrep?") -(defconst *gcc* - (executable-find "gcc") - "Do we have gcc?") -(defconst *git* - (executable-find "git") - "Do we have git?") - -(defvar *sys/full* - (member (vde/short-hostname) '("wakasu" "naruhodo")) ; "naruhodo" <- put naruhodo back in - "Is it a full system ?") -(defvar *sys/light* - (not *sys/full*) - "Is it a light system ?") -#+end_src - -Now, in order to load ~lisp~ and ~config~ files, it's just a matter of calling this -function with the right argument. - -#+begin_src emacs-lisp -(add-to-list 'load-path (concat user-emacs-directory "lisp/")) -(add-to-list 'load-path (concat user-emacs-directory "lisp/vorg")) -(require 'init-func) -(vde/el-load-dir (concat user-emacs-directory "/config/")) -#+end_src - -Finally, I want to be able to load files for a specific machine, in case I need it (not -entirely sure why yet but…) - -#+begin_src emacs-lisp -(if (file-exists-p (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el"))) - (load-file (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el")))) -#+end_src - -** Counting the time of loading -:PROPERTIES: -:ID: 2c7541e4-ed3c-497a-b078-732d18e82759 -:END: - -#+begin_src emacs-lisp -(let ((elapsed (float-time (time-subtract (current-time) - emacs-start-time)))) - (message "Loading %s...done (%.3fs)" load-file-name elapsed)) - -(add-hook 'after-init-hook - `(lambda () - (let ((elapsed - (float-time - (time-subtract (current-time) emacs-start-time)))) - (message "Loading %s...done (%.3fs) [after-init]" - ,load-file-name elapsed))) t) -#+end_src -* Configurations -:PROPERTIES: -:ID: 9bccfc88-2f6d-4437-8ce6-4ca8dd28e970 -:END: - -As seen above, I split my configurations in a =config= folder. Each of those configuration -has its own documentation, on its own page. Ideally, each module is optional and can be -skipped if not desired. In practice though, I load all of them, because this is my -config. I haven't really tried loading them all individually to make sure I don't have -links between them. - -- Core System - + [[file:emacs_keep_it_clean.org][keep emacs clean]] - + [[file:emacs_appearance.org][appearance]] - + editing - + navigation - + buffer and windows - + files (with dired) -- Version control -- [[file:emacs_projects.org][Projects]] -- Programming - + emacs-lisp - + go - + nix -- Writing -- Task management - + [[file:my_organizational_workflow.org][Org-mode and agenda]] aka "My Organization Workflow" -- Communications - + [[file:config_email_configuration.org][Email configuration]], notably using [[file:gnus.org][Gnus]] and [[file:notmuch.org][notmuch]]. -* Nix(eries) -:PROPERTIES: -:header-args: :tangle ~/src/home/users/vincent/dev/emacs.nix -:END: - -I am using [[file:nixos.org][NixOS]] and [[file:nix.org][Nix]], thus I do have a nix specific setup for Emacs. - -** Scripts -:PROPERTIES: -:ID: 2ae616a0-a300-4cd5-8856-ff251082bb8d -:END: - -I have a few scripts and desktop files that I want to get installed in my environment. - -*** capture -The first one is a capture command that starts a new frame using the =org= daemon so that -I can quickly capture something from anywhere. - -#+name: script-capture -#+begin_src nix :tangle no -capture = pkgs.writeScriptBin "capture" '' - #!${pkgs.stdenv.shell} - emacsclient -s /run/user/1000/emacs/org -n -F '((name . "capture") (width . 150) (height . 90))' -e '(org-capture)' -''; -#+end_src - -*** emacsclient helpers - -=ec= will start an emacs "window" frame from the emacs org server. - -#+name: script-ec -#+begin_src nix :tangle no -ec = pkgs.writeScriptBin "ec" '' - #!${pkgs.stdenv.shell} - emacsclient -s /run/user/1000/emacs/org --create-frame $@ -''; -#+end_src - -=ec= will start an emacs termimal frame from the emacs org server. - -#+name: script-et -#+begin_src nix :tangle no -et = pkgs.writeScriptBin "et" '' - #!${pkgs.stdenv.shell} - emacsclient -s /run/user/1000/emacs/org --tty $@ -''; -#+end_src - -*** portable dump command - -=e= starts emacs using the portable dump. - -#+name: script-e -#+begin_src nix :tangle no -e = pkgs.writeScriptBin "e" '' - #!${pkgs.stdenv.shell} - emacs --dump-file=~/.config/emacs/emacs.pdmp $@ -''; -#+end_src - -** Desktop files -:PROPERTIES: -:ID: 022aa37e-3f12-4a33-9f94-5a866ca6e481 -:END: - -- =org-protocol.desktop=: this register the org protocol in xdg. - #+begin_src conf :tangle ~/src/home/users/vincent/dev/emacs/org-protocol.desktop - [Desktop Entry] - Name=org-protocol - Exec=emacsclient -s /run/user/1000/emacs/org -n %u - Type=Application - Terminal=false - Categories=System; - MimeType=x-scheme-handler/org-protocol; - #+end_src -- =ec.desktop=: this starts a new frame on the =org= daemon. - #+begin_src conf :tangle ~/src/home/users/vincent/dev/emacs/ec.desktop - [Desktop Entry] - Name=Emacs (client) - Exec=ec - Type=Application - Terminal=false - Categories=System; - Icon=emacs; - #+end_src -- =capture.desktop=: this runs the =capture= script above - #+begin_src conf :tangle ~/src/home/users/vincent/dev/emacs/capture.desktop - [Desktop Entry] - Name=Emacs capture - Exec=capture - Type=Application - Terminal=false - Categories=System; - Icon=emacs; - #+end_src - -And then, we need to link those up : - -#+name: desktop-files -#+begin_src nix :tangle no -home.file.".local/share/applications/org-protocol.desktop".source = ./emacs/org-protocol.desktop; -home.file.".local/share/applications/ec.desktop".source = ./emacs/ec.desktop; -home.file.".local/share/applications/capture.desktop".source = ./emacs/capture.desktop; -#+end_src - -** Home packages - -We need to install a few packages: -- =ditaa= and =graphiz= are there for org-mode and org-babel -- =pandoc= is for when I when to migrate a document from markdown to org-mode or the opposite -- =sqlite= is for packages like =forge= -- =zip= is… always useful -- =capture= is the script defined abovoe. - -#+name: packages -#+begin_src nix :tangle no -home.packages = with pkgs; [ - ditaa - graphviz - pandoc - sqlite - zip - # See if I can hide this under an option - capture - e - ec - et -]; -#+end_src - -** =programs.emacs= -:PROPERTIES: -:ID: d0e07ae1-425f-4a87-834a-45da3c908711 -:END: - -=home-manager= comes with a modules named =programs.emacs=, so we are going to use it - -#+name: programs.emacs -#+begin_src nix :tangle no -programs.emacs = { - enable = true; - package = pkgs.my.emacs; - extraPackages = myExtraPackages; -}; -#+end_src - -#+name: myExtraPackages -#+begin_src nix :tangle no -myExtraPackages = epkgs: with epkgs; [ - ace-window - aggressive-indent - async - avy - bbdb - beginend - color-identifiers-mode - company - company-emoji - company-go - dash - delight - diredfl - dired-collapse - dired-git-info - dired-narrow - dired-quick-sort - dired-rsync - dired-subtree - dockerfile-mode - dumb-jump - easy-kill - edit-indirect - envrc - esh-autosuggest - eshell-prompt-extras - esup - expand-region - flimenu - flycheck - flycheck-golangci-lint - git-annex - git-commit - gitattributes-mode - gitconfig-mode - github-review - gitignore-mode - go-mode - go-stacktracer - gotest - goto-last-change - hardhat - helpful - highlight - highlight-indentation - highlight-numbers - ibuffer-vc - icomplete-vertical - iedit - json-mode - magit - magit-annex - magit-popup - magit-todos - markdown-mode - minions - modus-operandi-theme - moody - mwim - nix-buffer - nix-mode - nixpkgs-fmt - no-littering - ob-async - ob-go - ob-http - olivetti - orderless - org-capture-pop-frame - org-gcal - org-journal - org-plus-contrib - org-ql - org-ref - org-roam - org-super-agenda - org-superstar - org-tree-slide - org-web-tools - orgit - ox-pandoc - pandoc-mode - pdf-tools - pkgs.bookmark-plus - pkgs.dired-plus - projectile - python-mode - rainbow-delimiters - rainbow-mode - rg - ripgrep - scratch - shr-tag-pre-highlight - smartparens - symbol-overlay - trashed - try - undo-tree - use-package - visual-fill-column - visual-regexp - vterm - web-mode - wgrep - whole-line-or-region - with-editor - xterm-color - yaml-mode -]; -#+end_src - -** Emacs /server/ - -#+name: emacs-server -#+begin_src nix :tangle no -services.emacs-server = { - enable = true; - package = pkgs.my.emacs; - name = "org"; - shell = pkgs.zsh + "/bin/zsh -i -c"; - # FIXME do this in the derivation :) - # extraOptions = "--dump-file=${config.home.homeDirectory}/.config/emacs/emacs.pdmp"; -}; -#+end_src - -** Commands and sessions variables - -Let's define some useful /commands/ that can be used - -Let's define some - -** Legacy -:PROPERTIES: -:END: - -#+name: legacy -#+begin_src nix :tangle no -home.sessionVariables = { - EDITOR = "et"; - ALTERNATE_EDITOR = "et"; -}; -#+end_src - -** Configuration layout -:PROPERTIES: -:ID: 72cc55fc-4c47-4425-9d0c-2b309068ccb9 -:END: - -Here we define the =emacs.nix= file that gets generated by the source blocks in our Org -document. This is the file that actually gets loaded on startup. The placeholders in -angled brackets correspond to the ~NAME~ directives above the ~SRC~ blocks throughout this -document. - -#+begin_src nix :noweb no-export :exports code -# Note: this file is autogenerated from an org-mode file. -{ config, lib, pkgs, ... }: - -with lib; -let - <<script-capture>> - <<script-e>> - <<script-et>> - <<script-ec>> - <<myExtraPackages>> -in -{ - <<desktop-files>> - <<packages>> - <<programs.emacs>> - <<emacs-server>> - <<legacy>> -} -#+end_src -* Inspirations -:PROPERTIES: -:ID: 575a424a-8121-40d9-85bd-ac4975818a8d -:END: - -This is inspired by a crazy amount of configurations (litterate or note): - -- [[https://protesilaos.com/dotemacs/][Protesilaos Stravou's dotemacs]] -- [[https://tecosaur.github.io/emacs-config/config.html][Doom Emacs Configuration]] from [[https://github.com/tecosaur][tecosaur]] -- [[https://gitlab.com/ndw/dotfiles][https://gitlab.com/ndw/dotfiles]] -- [[https://github.com/MatthewZMD/.emacs.d][https://github.com/MatthewZMD/.emacs.d]] -- [[https://github.com/alhassy/emacs.d][https://github.com/alhassy/emacs.d]] -- [[https://github.com/chmouel/emacs-config][https://github.com/chmouel/emacs-config]] -- [[https://github.com/seagle0128/.emacs.d][https://github.com/seagle0128/.emacs.d]] -- [[https://github.com/hlissner/doom-emacs][https://github.com/hlissner/doom-emacs]] -- [[http://doc.norang.ca/org-mode.html][http://doc.norang.ca/org-mode.html]] - -And also: - -- [[https://sriramkswamy.github.io/dotemacs/][Emacs configuration file]] -- [[https://blog.d46.us/advanced-emacs-startup/][Advanced Techniques for Reducing Emacs Startup Time]] -- [[https://www.bartuka.com/posts/emacs-config/index.html][@bartuka: emacs.d]] -- [[http://www.howardism.org/Technical/Emacs/getting-boxes-done.html][Getting Boxes Done]] -- [[https://idiocy.org/emacs-fonts-and-fontsets.html][Emacs, fonts and fontsets]] -- [[https://spin.atomicobject.com/2016/05/27/write-emacs-package/][A Simple Guide to Writing & Publishing Emacs Packages]] -- [[https://alphapapa.github.io/emacs-package-dev-handbook/][The Emacs Package Developer's Handbook]] -- [[https://tecosaur.github.io/emacs-config/config.html][Doom Emacs Configuration]] - - -* Links - -Here is a compilation of /random/ articles around GNU/Emacs that I found interesting to -share. I may add comment on those too. -** TODO [[https://aliquote.org/post/minimalist-emacs/][Minimalist Emacs - aliquot]] -[2020-09-17 Thu 17:55] - -** [[https://github.com/kensanata/ggg#gmail-gnus-gpg-guide-gggg][kensanata/ggg: Gmail, Gnus and GPG]] -[2020-07-08 Wed 07:37] -** [[https://www.greghendershott.com/2017/02/emacs-themes.html][Emacs Themes]] -[2020-06-02 Tue 18:07] -** [[https://degruchy.org/2020/05/26/binding-emacs/][Binding Emacs – Verily]] -[2020-06-02 Tue 18:04] -** [[https://mihaiolteanu.me/eshell-toggle/][How to create and jump to eshell buffers with a single command]] -[2020-05-29 Fri 15:05] -** TODO [[https://www.reddit.com/r/emacs/comments/fk7p49/piping_stdout_to_emacs/][Piping stdout to Emacs : emacs]] :emacs: -[2020-03-24 Tue 07:54] - -** TODO [[https://explog.in/notes/poet.html][Making Poet, an Emacs theme]] :emacs: -[2020-03-25 Wed 16:58] - -** TODO [[https://willschenk.com/articles/2020/tramp_tricks/][Emacs Tramp tricks]] :emacs: -[2020-03-08 Sun 16:44] -** TODO [[https://azzamsa.com/n/scripts-el/][Useful Emacs Lisp Scripts 🌱 · AZZAMSA]] -[2020-06-18 Thu 18:41] -** TODO [[https://emacsredux.com/blog/2020/06/10/comment-commands-redux/][Comment Commands Redux | Emacs Redux]] :emacs: -[2020-06-23 Tue 17:45] -** TODO [[https://github.com/MatthewZMD/.emacs.d][MatthewZMD/.emacs.d: M-EMACS, a full-feature GNU Emacs configuration distribution]] -[2020-06-29 Mon 11:35] -** TODO [[https://writequit.org/eos/eos.html][The Emacs Operating System (EOS)]] -[2020-07-02 Thu 18:20] -** TODO [[https://justin.abrah.ms/dotfiles/emacs.html][My Emacs Configuration]] -[2020-07-15 Wed 12:29] -** TODO [[https://jakemccrary.com/blog/2020/11/14/speeding-up-magit/][Speeding up magit - Jake McCrary]] -[2020-11-17 Tue 18:09] -** TODO [[https://tech.toryanderson.com/2020/11/13/migrating-to-a-custom-file-less-setup/][Migrating to a custom-file-less setup | Tech.ToryAnderson.com]] -[2020-11-19 Thu 11:00] - -** TODO [[https://www.philnewton.net/blog/leanpub-with-emacs/][Writing a Leanpub book with Emacs - philnewton.net]] -[2020-11-19 Thu 11:11] -** TODO [[https://en.liujiacai.net/2020/11/29/why-emacs/][What you need to know before try Emacs - KeepCoding]] -[2020-12-01 Tue 08:02] - -** TODO [[https://github.com/rougier/nano-emacs][rougier/nano-emacs: GNU Emacs / N Λ N O - Emacs made simple]] -[2020-12-01 Tue 08:12] diff --git a/www/vincent.demeester.fr/content/legacy/articles/emacs.org b/www/vincent.demeester.fr/content/legacy/articles/emacs.org @@ -1,81 +0,0 @@ -#+title: My Emacs System -#+SUBTITLE: A attempt to document my emacs setup 🙃 -#+ROAM_ALIAS: "emacs" "Emacs" "GNU/Emacs" "gnu/emacs" - -Emacs is the best editor possible, at least for me, especially with the killer [[file:org_mode.org][org-mode]] -module. - -I do all in a lot in Emacs: -- task and calendar management using [[file:org_mode.org][org-mode]]. -- mail using [[file:gnus.org][gnus]]. -- programming in different languages ([[file:elisp.org][elisp]], [[file:go.org][go]], [[file:bash.org][bash]], …) -- interactive shell using either [[file:eshell.org][eshell]] or [[file:vterm.org][vterm]]. - -[[file:emacs.old.org][Here is my old attempt]] to document my Emacs setup, inspired by [[https://writequit.org/eos/eos.html][The Emacs Operating System -(EOS)]] or [[http://doc.rix.si/cce/cce.html][Complete Computing Environment]] and other litterate configurations.In a gist, this -is the litterate version of the [[file:config_configurations.org][configurations]] available in my [[https://git.sr.ht/~vdemeester/home][monorepo]]. In the end, I -don't have time to properly maintain this, and I prefer to do code and document it well. - -* Links - -Here is a compilation of /random/ articles around GNU/Emacs that I found interesting to -share. I may add comment on those too. -** [[https://aliquote.org/post/minimalist-emacs/][Minimalist Emacs - aliquot]] -[2020-09-17 Thu 17:55] - -** [[https://github.com/kensanata/ggg#gmail-gnus-gpg-guide-gggg][kensanata/ggg: Gmail, Gnus and GPG]] -[2020-07-08 Wed 07:37] -** [[https://www.greghendershott.com/2017/02/emacs-themes.html][Emacs Themes]] -[2020-06-02 Tue 18:07] -** [[https://degruchy.org/2020/05/26/binding-emacs/][Binding Emacs – Verily]] -[2020-06-02 Tue 18:04] -** [[https://mihaiolteanu.me/eshell-toggle/][How to create and jump to eshell buffers with a single command]] -[2020-05-29 Fri 15:05] -** TODO [[https://www.reddit.com/r/emacs/comments/fk7p49/piping_stdout_to_emacs/][Piping stdout to Emacs : emacs]] :emacs: -[2020-03-24 Tue 07:54] - -** TODO [[https://explog.in/notes/poet.html][Making Poet, an Emacs theme]] :emacs: -[2020-03-25 Wed 16:58] - -** TODO [[https://willschenk.com/articles/2020/tramp_tricks/][Emacs Tramp tricks]] :emacs: -[2020-03-08 Sun 16:44] -** TODO [[https://azzamsa.com/n/scripts-el/][Useful Emacs Lisp Scripts 🌱 · AZZAMSA]] -[2020-06-18 Thu 18:41] -** TODO [[https://emacsredux.com/blog/2020/06/10/comment-commands-redux/][Comment Commands Redux | Emacs Redux]] :emacs: -[2020-06-23 Tue 17:45] -** TODO [[https://github.com/MatthewZMD/.emacs.d][MatthewZMD/.emacs.d: M-EMACS, a full-feature GNU Emacs configuration distribution]] -[2020-06-29 Mon 11:35] -** TODO [[https://writequit.org/eos/eos.html][The Emacs Operating System (EOS)]] -[2020-07-02 Thu 18:20] -** TODO [[https://justin.abrah.ms/dotfiles/emacs.html][My Emacs Configuration]] -[2020-07-15 Wed 12:29] -** TODO [[https://jakemccrary.com/blog/2020/11/14/speeding-up-magit/][Speeding up magit - Jake McCrary]] -[2020-11-17 Tue 18:09] -** TODO [[https://tech.toryanderson.com/2020/11/13/migrating-to-a-custom-file-less-setup/][Migrating to a custom-file-less setup | Tech.ToryAnderson.com]] -[2020-11-19 Thu 11:00] - -** TODO [[https://www.philnewton.net/blog/leanpub-with-emacs/][Writing a Leanpub book with Emacs - philnewton.net]] -[2020-11-19 Thu 11:11] -** TODO [[https://en.liujiacai.net/2020/11/29/why-emacs/][What you need to know before try Emacs - KeepCoding]] -[2020-12-01 Tue 08:02] - -** TODO [[https://github.com/rougier/nano-emacs][rougier/nano-emacs: GNU Emacs / N Λ N O - Emacs made simple]] -[2020-12-01 Tue 08:12] -** TODO [[https://emacsredux.com/blog/2018/11/09/an-easy-kill/][An easy-kill | Emacs Redux]] -[2020-12-10 Thu 11:19] -** TODO [[https://jherrlin.github.io/posts/emacs-orgmode-source-code-blocks2/][Emacs Orgmode Source Code Blocks 2 | jherrlin]] -[2020-12-17 Thu 16:04] -** TODO [[https://blog.sumtypeofway.com/posts/emacs-config.html][adventures in uncertainty: My Emacs Configuration (Or, Emacs is Agar for Brain Worms)]] -[2020-09-23 Wed 12:23] - -Fixing Emacs’s defaults is a nontrivial problem. We’ll start with UI concerns. -** TODO [[https://blog.aaronbieber.com/2016/09/24/an-agenda-for-life-with-org-mode.html][An Agenda for Life With Org Mode - The Chronicle]] -[2020-09-24 Thu 18:52] - -(org-agenda-skip-if nil '(scheduled deadline)) -** TODO [[https://www.rousette.org.uk/archives/advising-emacs/][BSAG » Advising Emacs]] -[2020-09-15 Tue 16:59] -** TODO [[https://blog.tastytea.de/posts/editing-remote-files-with-emacs-comfortably/][Editing remote files with Emacs, comfortably | tastyteablog]] -[2020-08-21 Fri 15:56] -** TODO [[https://www.labri.fr/perso/nrougier/GTD/index.html][Get Things Done with Emacs]] -[2020-09-19 Sat 00:35] diff --git a/www/vincent.demeester.fr/content/legacy/articles/emacs_appearance.org b/www/vincent.demeester.fr/content/legacy/articles/emacs_appearance.org @@ -1,45 +0,0 @@ -#+TITLE: emacs: appearance - -* Typeface suitability test - -#+begin_example -()[]{}<>«»‹› -6bB8& -0ODdoaoOQGC -I1tilIJL| -!¡ij -5$§Ss -7ZzZ2 -9gqpG6 -hnmMN -uvvwWuuw -x×X -.,·°% -¡!¿? -:; -`''"‘’“” -—-~≈=≠+*_ -…⋯ -... - -Sample character set -Check for monospacing and Greek glyphs - -ABCDEFGHIJKLMNOPQRSTUVWXYZ -abcdefghijklmnopqrstuvwxyz -0123456789 -~!@#$%^&*+ -`'"‘’“”.,;:… -()[]{}—-_=|<>/\ -ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ -αβγδεζηθικλμνξοπρστυφχψω -#+end_example - - -* References -- [[https://github.com/rougier/elegant-emacs][rougier/elegant-emacs: A very minimal but elegant emacs (I think)]] - Some interesting ideas here. -- [[https://protesilaos.com/codelog/2020-07-17-emacs-mixed-fonts-org/][Emacs: configuring mixed fonts in Org mode | Protesilaos Stavrou]] -- [[https://protesilaos.com/codelog/2020-07-18-emacs-concept-org-tweaked-focus/][Emacs proof-of-concept: tweaked focused writing for Org | Protesilaos Stavrou]] -- [[https://aliquote.org/post/monochrome-color-scheme/][Monochrome color scheme - aliquot]] -[2020-09-07 Mon 11:49] diff --git a/www/vincent.demeester.fr/content/legacy/articles/emacs_keep_it_clean.org b/www/vincent.demeester.fr/content/legacy/articles/emacs_keep_it_clean.org @@ -1,100 +0,0 @@ -#+TITLE: emacs: keep it clean -#+PROPERTY: header-args :tangle ~/src/home/tools/emacs/config/00-clean.el - -I want to keep the =~/.emacs.d= folder as clean as possible. The [[https://github.com/emacscollective/no-littering][no-littering]] project -helps wit that. - -#+begin_quote -The default paths used to store configuration files and persistent data are not consistent -across Emacs packages. This isn't just a problem with third-party packages but even with -built-in packages. - -Some packages put these files directly in user-emacs-directory or $HOME or in a -subdirectory of either of the two or elsewhere. Furthermore sometimes file names are used -that don't provide any insight into what package might have created them. - -This package sets out to fix this by changing the values of path variables to put -configuration files in no-littering-etc-directory (defaulting to ~/.emacs.d/etc/) and -persistent data files in no-littering-var-directory (defaulting to ~/.emacs.d/var/), and -by using descriptive file names and subdirectories when appropriate. This is similar to a -color-theme; a "path-theme" if you will. -#+end_quote - -Let's configure it *and* make sure we load it as soon as possible (hence the -=config/00-clean.el=). - -As I am loading =recentf= during this cleanup part, I need to setup recentf before 😅. In -a gist: - -- I keep about 200 items. -- I don't want the /auto-cleanup/ of recentf items to happen when the mode is loaded (a.k.a. - at startup). It is configured to run after 360s of idle time. -- I don't really want to show the Nth number of the items. -- I don't want recentf to save remote, =su= and =sudo= items (=ssh:=, =sudo:=, …) - -#+begin_src emacs-lisp -;;; 00-clean.el --- -*- lexical-binding: t; -*- -;;; Commentary: -;;; no-littering and recentf configurations -;;; Note: this file is autogenerated from an org-mode file. -;;; Code: -(use-package recentf - :config - (setq recentf-max-saved-items 200 - recentf-auto-cleanup 360 - recentf-show-file-shortcuts-flag nil) - (recentf-mode 1) - (add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:") - ;; Magic advice to rename entries in recentf when moving files in - ;; dired. - (defun rjs/recentf-rename-notify (oldname newname &rest args) - (if (file-directory-p newname) - (rjs/recentf-rename-directory oldname newname) - (rjs/recentf-rename-file oldname newname))) - - (defun rjs/recentf-rename-file (oldname newname) - (setq recentf-list - (mapcar (lambda (name) - (if (string-equal name oldname) - newname - oldname)) - recentf-list)) - recentf-cleanup) - - (defun rjs/recentf-rename-directory (oldname newname) - ;; oldname, newname and all entries of recentf-list should already - ;; be absolute and normalised so I think this can just test whether - ;; oldname is a prefix of the element. - (setq recentf-list - (mapcar (lambda (name) - (if (string-prefix-p oldname name) - (concat newname (substring name (length oldname))) - name)) - recentf-list)) - recentf-cleanup) - - (advice-add 'dired-rename-file :after #'rjs/recentf-rename-notify)) - -(use-package no-littering ; Keep .emacs.d clean - :config - (require 'recentf) - (add-to-list 'recentf-exclude no-littering-var-directory) - (add-to-list 'recentf-exclude no-littering-etc-directory) - - ;; Move this in its own thing - (setq - create-lockfiles nil - delete-old-versions t - kept-new-versions 6 - kept-old-versions 2 - version-control t) - - (setq - backup-directory-alist - `((".*" . ,(no-littering-expand-var-file-name "backup/"))) - auto-save-file-name-transforms - `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))) - -(provide '00-clean) -;;; 00-clean.el ends here -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/emacs_lisp.org b/www/vincent.demeester.fr/content/legacy/articles/emacs_lisp.org @@ -1 +0,0 @@ -#+TITLE: Emacs Lisp diff --git a/www/vincent.demeester.fr/content/legacy/articles/emacs_projects.org b/www/vincent.demeester.fr/content/legacy/articles/emacs_projects.org @@ -1,364 +0,0 @@ -#+TITLE: emacs: Managing projects -#+ROAM_ALIAS: "emacs: projects" - -Working on *project* a key part of my workflow when using [[file:emacs.org][GNU/Emacs]]. Almost everything I -work on can be part of a project. It might be simpler to give examples: -[[https://github.com/tektoncd/pipeline][=tektoncd/pipeline=]] checked out is a project, my =~/desktop/org= is another project. There -is only a handful of buffer in Emacs that I do not consider of any project, one example is -the [[file:org_mode.org][org-mode]] agenda. - -In a *project*, I want to be able to: - -- List *all* files in that project - + /optionally/ spiking the files from =.gitignore= -- Search in all *project* files - + using =ripgrep= or something else - + possibly to a search and replace -- Run commands on the project _root_ folder - + could be a compilation, some tests, some random commands -- Manage the version control (using =magit=) - + adding files, switch branches, … -- Switch between project buffers - -Emacs 27.1 ships with a =project= library that has some useful function. But prior to this, -the [[https://github.com/bbatsov/projectile][=projectile=]] project has been the way to go for managing projects in -[[file:emacs.org][GNU/Emacs]]. [[https://github.com/bbatsov/projectile][=projectile=]] is also quite extensible and integrates relatively well with a -bunch of other libraries. - -The /mnemonics/ key for the *project* is =C-c p=, and thus, any project command will start with -that prefix. - - -#+TOC: headlines 3 - -* Projectile - -Let's configure =projectile= using =use-package=. - -#+name: projectile -#+begin_src emacs-lisp :noweb no-export :exports code :tangle no -(use-package projectile - :commands - (projectile-ack - projectile-ag - projectile-compile-project - projectile-configure-project - projectile-package-project - projectile-install-project - projectile-test-project - projectile-run-project - projectile-dired - projectile-find-dir - projectile-find-file - projectile-find-file-dwim - projectile-find-file-in-directory - projectile-find-tag - projectile-test-project - projectile-grep - projectile-invalidate-cache - projectile-kill-buffers - projectile-multi-occur - projectile-project-p - projectile-project-root - projectile-recentf - projectile-regenerate-tags - projectile-replace - projectile-replace-regexp - projectile-run-async-shell-command-in-root - projectile-run-shell-command-in-root - projectile-switch-project - projectile-switch-to-buffer - projectile-vc - projectile-commander) - :bind-keymap ("C-c p" . projectile-command-map) - :config - <<projectile-completion>> - <<projectile-variables>> - <<projectile-compilation>> - <<projectile-known-projects>> - <<projectile-commander-methods>> - <<projectile-custom-types>> - (projectile-mode)) -#+end_src - -First thing first, let's tell =projectile= to use the default completion system instead of -=ivy=, or =helm=, or … - -#+name: projectile-completion -#+begin_src emacs-lisp :tangle no -(setq-default projectile-completion-system 'default) -#+end_src - -Let's also configure some =projectile= behavior. - -- The default action when switch to a project should be the =commander=, as it allows to do - different actions. This is done by setting =projectile-command= to - =project-switch-project-action=. -- When switching to tests (=C-c p t=), if there is no test files, create one. This is done - by setting =projectile-create-missing-test-files=. - -#+name: projectile-variables -#+begin_src emacs-lisp :tangle no -(setq-default projectile-switch-project-action #'projectile-commander - projectile-create-missing-test-files t) -#+end_src - -In order to make sure we can have a /living/ compilation per project, we need to modify the -buffer name to include the project name. This is easily do-able by writing a function for -=compilation-buffer-name-function=. - -#+name: projectile-compilation -#+begin_src emacs-lisp :tangle no -(setq-default compilation-buffer-name-function (lambda (mode) (concat "*" (downcase mode) ": " (projectile-project-name) "*"))) -#+end_src - -Do not track known projects automatically, instead call projectile-add-known-project -Remove dead projects when Emacs is idle - -#+name: projectile-known-projects -#+begin_src emacs-lisp :tangle no -(setq-default projectile-track-known-projects-automatically nil) -(run-with-idle-timer 10 nil #'projectile-cleanup-known-projects) -#+end_src - -#+name: projectile-commander-methods -#+begin_src emacs-lisp :tangle no -(def-projectile-commander-method ?s - "Open a *shell* buffer for the project" - (projectile-run-eshell nil)) -(def-projectile-commander-method ?c - "Run `compile' in the project" - (projectile-compile-project nil)) -#+end_src - -** Custom project types - - [[https://github.com/bbatsov/projectile][=projectile=]] allows to add custom project type, in addition to the built-in project -types. See [[https://projectile.readthedocs.io/en/latest/projects/][Projects - Projectile: The Project Interaction Library for Emacs]] for a little -bit more detail. It should be possible to configure the =configure=, =compile=, =package=, -=install= and =test= commands. One a the hope of this section is to be able to define highly -customized project types so that doing =C-p u= on, let's say, =tektoncd/pipeline= does the -right thing by default. - -An example of custom project type is the following. - -#+begin_src emacs-lisp :tangle no :noweb no -;; Ruby + RSpec -(projectile-register-project-type 'ruby-rspec '("Gemfile" "lib" "spec") - :project-file "Gemfile" - :compile "bundle exec rake" - :src-dir "lib/" - :test "bundle exec rspec" - :test-dir "spec/" - :test-suffix "_spec") -#+end_src - -One nice aspect of =:compile= (and some others) is that it can take a symbolic reference to -a function, which means, you can define dynamic behavior. Based on the doc this works for -=:compile=, =:configure=, =:compilation-dir= and =:run= (but /my hope is it would work for =:test= -and that a =:package= and an =:install= would exist/). - -*** TODO =ko= -:PROPERTIES: -:header-args: :noweb-ref projectile-custom-types :tangle no -:END: - -First thing first, what makes a =ko= project. In most cases, a =.ko.yaml= will be present (at -the root folder of the project). Let's also define a function do detect if a it's a =ko= -project that uses the /standard/ =config= folder for yamls. - -#+begin_src emacs-lisp -(defun projectile-ko-project-p () - "Check if a project contains a .ko.yaml file." - (projectile-verify-file ".ko.yaml")) -(defun projectile-ko-with-config-project-p () - "Check if a project is a ko project and has a config/ folder full of yaml" - (and (projectile-ko-project-p) - (projectile-verify-file-wildcard "config/*.yaml"))) -#+end_src - -Let's register the =ko= project (with config). Long-term, the idea is to make different -function for =ko= and =ko-with-config= projects. - -#+begin_src emacs-lisp -(projectile-register-project-type 'ko-with-config #'projectile-ko-with-config-project-p - :project-file ".ko.yaml" ; might not be required - :configure 'projectile-ko-configure-command - :compile 'projectile-ko-compile-command - :test 'projectile-ko-test-command - :run 'projectile-ko-run-command - :package 'projectile-ko-package-command - :install 'projectile-ko-install-command) -#+end_src - - -Let's now dig a little bit more into the configure, compile, test, run, package and -install commands. As we can pass it a function, we can define behaviour depending on the -current opened buffer, etc. One assumption that we can make is that a =ko= project is also a -=go= project. - -- configure :: configure stands for =./configure= scripts usually. Let's see what it could - be for ~ko~ project. Most likely related to file generations. - + default to =./hack/update-codegen.sh= if it is present. - #+begin_src emacs-lisp - (defun projectile-ko-configure-command () - "define a configure command for a ko project, depending on the opened file" - (cond - ((projectile-file-exists-p "hack/update-codegen.sh") "./hack/update-codegen.sh"))) - #+end_src -- compile :: compile might be slightly different depending on the current major mode we - are in, and maybe also depending on the folder. - - + default to =go build -v ./...= - + =go= file (=go-mode=) - - default to build the current package - - if it is a test file, tests the current package - - #+begin_src emacs-lisp - (defun projectile-ko-compile-command () - "define a compile command for a ko project, depending on the openend file " - (cond - ((eq major-mode 'go-mode) (projectile-ko-compile-command-go)) - ((eq major-mode 'yaml-mode) "yamllint .") - (t "go build -v ./...") - )) - - (defun projectile-ko-compile-command-go () - "compile command for a ko project if in a go file" - (let* ((current-file (buffer-file-name (current-buffer))) - (relative-current-file (file-relative-name current-file (projectile-project-root))) - (relative-current-folder (file-name-directory relative-current-file))) - (message relative-current-file) - (cond - ((string-suffix-p "_test.go" relative-current-file) (format "go test -c -v ./%s" relative-current-folder)) - (t (format "go build -v ./%s" relative-current-folder))))) - #+end_src -- test :: test might be slightly different depending on the current major mode we are in, - and might depend on the folder. - - + default to =go test -v ./...= - + =go= file (=go-mode=) - - default to run tests on the current package - - if it is a test file, tests the current file (like =go-test-current-file= or - =gotest-ui-current-file=) - - #+begin_src emacs-lisp - (defun projectile-ko-test-command () - "define a test command for a ko project, depending on the openend file" - (cond - ((eq major-mode 'go-mode) (projectile-ko-test-command-go)) - (t "go test -v ./..."))) - - (defun projectile-ko-test-command-go () - "test command for a ko project if in a go file" - (let* ((current-file (buffer-file-name (current-buffer))) - (relative-current-file (file-relative-name current-file (projectile-project-root))) - (relative-current-folder (file-name-directory relative-current-file))) - (cond - ((string-suffix-p "_test.go" relative-current-file) (projectile-ko-command-go-test relative-current-file)) - (t (format "go test -v ./%s" relative-current-folder))))) - - (defun projectile-ko-command-go-test (current-file) - "get the command for a go test" - (cond - ((gotest-module-available-p) (projectile-ko-command-go-test-gotest current-file)) - (t (format "go test -v ./%s" current-file)))) - - (defun projectile-ko-command-go-test-gotest (current-file) - "get the command for a go test with gotest module enabled" - (message default-directory) - (let ((data (go-test--get-current-file-testing-data))) - (format "go test -run='%s' -v ./%s" data (file-name-directory current-file)))) - - (defun gotest-module-available-p () - "is go-test module available" - (fboundp 'go-test--get-current-file-data)) - #+end_src -- run :: run is usually about running the project binary or something. - #+begin_src emacs-lisp - (defun projectile-ko-run-command () - "define a run command for a ko project, depending on the openend file " - (cond - ((eq major-mode 'go-mode) (projectile-ko-run-command-go)) - ;; nothing by default ? - )) - - (defun projectile-ko-run-command-go () - "test command for a ko project if in a go file" - (let* ((current-file (buffer-file-name (current-buffer))) - (relative-current-file (file-relative-name current-file (projectile-project-root))) - (relative-current-folder (file-name-directory relative-current-file))) - (cond - ((string-prefix-p "cmd/" relative-current-file) (format "go run ./%s" relative-current-folder))))) - #+end_src -- package :: package is usually about generating a package, for a maven project this would - be =mvn package=, for a project with a =Dockerfile=, this could be build the image(s). For a - =ko= project this is about building and pushing the images that are going to be - deployed. This is achieved by doing a =ko resolve=. - #+begin_src emacs-lisp - (defun projectile-ko-package-command () - "define a package command for a ko project, depending on the openend file " - (cond - ((eq major-mode 'go-mode) (projectile-ko-package-command-go)) - (t "ko resolve --push=false --oci-layout-path=/tmp/oci -f config") - )) - - (defun projectile-ko-package-command-go () - "package command for a ko project if in a go file" - (let* ((current-file (buffer-file-name (current-buffer))) - (relative-current-file (file-relative-name current-file (projectile-project-root))) - (relative-current-folder (file-name-directory relative-current-file))) - (cond - ((string-prefix-p "cmd/" relative-current-file) (format "ko publish --push=false ./%s" relative-current-folder))))) - #+end_src -- install :: install is about installing the project artifact somewhere (usually =make install=) - #+begin_src emacs-lisp - (defun projectile-ko-install-command () - "define a install command for a ko project, depending on the openend file " - "ko apply -f config/") - #+end_src - -*** TODO Others - -- Detect project type - + ~.ko.yaml~ => run is ~ko apply -f …~ - + is there a ~Makefile~ ? - + ~tkn~ and ~tekton~ file - + =home= detection: ~systems~, ~users~, ~ci.nix~, ~shell.nix~, - ~hosts.nix~, ~systems.nix~ - - if in =pkgs=, run =nix-build pkgs -A …=, and try to detect the file derivations - - if in =tools/emacs= (elisp), tangle files from =~/desktop/org/notes= - - detect =hostname= and act based on it: - + =naruhodo=: ~make home-switch~, … - + =wakasu=: ~make switch~, … - + Could also detect using =nixos-version= -- Hook projectile run/compile/test to multi-compile - Group things together, so that I can either choose from a list of different compile - options *or* run my command - -[[https://github.com/asok/projectile-rails][asok/projectile-rails: Emacs Rails mode based on projectile]] is also quite interesting. - -* Configuration layout -:PROPERTIES: -:header-args: :tangle ~/src/home/tools/emacs/config/config-projects.el -:ID: 6401532f-d10a-4d38-a38f-b08f48501d3d -:END: - -Here we define the =config-projects.el= file that gets generated by the source blocks in our Org -document. This is the file that actually gets loaded on startup. The placeholders in -angled brackets correspond to the ~NAME~ directives above the ~SRC~ blocks throughout this -document. - -#+begin_src emacs-lisp :noweb no-export :exports code -;;; config-projects.el --- -*- lexical-binding: t; -*- -;;; Commentary: -;;; Project related configuration. -;;; This is mainly using projectile now, but built-in projects module seems promising for long-term. -;;; Note: this file is autogenerated from an org-mode file. -;;; Code: - -<<projectile>> - -(provide 'config-projects) -;;; config-projects.el ends here -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/email.org b/www/vincent.demeester.fr/content/legacy/articles/email.org @@ -1,24 +0,0 @@ - -#+TITLE: email -#+ROAM_ALIAS: "mail" "e-mail" "Email" "Mail" - -* [[https://www.paritybit.ca/blog/why-email-is-the-best-discussion-platform][Why Email is the Best Discussion Platform - paritybit.ca]] -[2020-06-08 Mon 10:35] - -* TODO [[https://useplaintext.email/][Use plaintext email]] -[2020-03-03 Tue 22:42] - -* TODO [[https://poolp.org/posts/2019-12-15/decentralised-smtp-is-for-the-greater-good/][Decentralised SMTP is for the greater good - poolp.org]] -[2020-03-03 Tue 22:06] - -* TODO [[https://kevq.uk/email-is-not-broken/][Email Is Not Broken - Kev Quirk]] -[2020-07-01 Wed 11:08] - -* TODO [[https://write.privacytools.io/freddy/my-take-on-email][My Take on Email — Freddy's Ramblings]] -[2020-07-03 Fri 09:08] - -* TODO [[https://www.artemix.org/blog/backing-up-e-mails-from-an-imap-server][Backing up e-mails from an IMAP server - Artemis]] -[2020-11-05 Thu 10:48] -* Self hosting -** [[https://codedharma.com/posts/openbsd_email_1/][Setting Up Your Own Email Server With OpenBSD | Code Dharma]] -[2020-06-08 Mon 10:23] diff --git a/www/vincent.demeester.fr/content/legacy/articles/empathy_online.org b/www/vincent.demeester.fr/content/legacy/articles/empathy_online.org @@ -1,2 +0,0 @@ -#+title: Empathy Online -#+roam_key: https://thoughtbot.com/blog/empathy-online diff --git a/www/vincent.demeester.fr/content/legacy/articles/eshell.org b/www/vincent.demeester.fr/content/legacy/articles/eshell.org @@ -1,12 +0,0 @@ - -#+TITLE: eshell - -* Links -** TODO [[https://masteringemacs.org/article/complete-guide-mastering-eshell][Mastering Eshell - Mastering Emacs]] -[2020-04-09 Thu 14:54] - -** TODO [[https://www.reddit.com/r/emacs/comments/ft84xy/run_shell_command_in_new_vterm/][Run shell command in new vterm : emacs]] :vterm:shell: -:PROPERTIES: -:ID: 6f42bb20-51fd-4ed0-8bdb-5d423d517320 -:END: -[2020-04-09 Thu 17:45] diff --git a/www/vincent.demeester.fr/content/legacy/articles/fedora-silverblue.org b/www/vincent.demeester.fr/content/legacy/articles/fedora-silverblue.org @@ -1,10 +0,0 @@ -#+TITLE: Fedora silverblue -#+SUBTITLE: A NixOS-like fedora based on rpm-ostree -#+SETUPFILE: .setup.org -#+FILETAGS: fedora linux silverblue - -#+begin_abstract -Let's dig into Fedora Silverblue, how it works, gotchas and usage -#+end_abstract - -#+TOC: headlines 1 diff --git a/www/vincent.demeester.fr/content/legacy/articles/fedora.org b/www/vincent.demeester.fr/content/legacy/articles/fedora.org @@ -1,22 +0,0 @@ -#+TITLE: Fedora -#+FILETAGS: fedora linux -#+SETUPFILE: .setup.org - -- [[file:fedora-silverblue.org][Fedora silverblue]] - -* Packaging -:PROPERTIES: -:CUSTOM_ID: h:8b03b38c-c116-4ee2-874f-f2a301ac3715 -:END: - -- [[https://fedoraproject.org/wiki/Join_the_package_collection_maintainers][Join the package collection maintainers]] - -** Golang -:PROPERTIES: -:CUSTOM_ID: h:f8173b2d-a3b9-4108-8bc5-847898aaf7ea -:END: - -- [[https://eclipseo.fedorapeople.org/guidelines/packaging-guidelines/Golang/][Golang Packaging Guidelines]] -- [[https://fedoraproject.org/wiki/More_Go_packaging][More Go packaging]] -- [[https://fedoraproject.org/wiki/PackagingDrafts/Go][PackagingDrafts/Go]] -- [[https://github.com/gofed/gofed][~gofed~]] is a tool set aimed at automation of packaging of golang projects (in fedora) diff --git a/www/vincent.demeester.fr/content/legacy/articles/feeds.org b/www/vincent.demeester.fr/content/legacy/articles/feeds.org @@ -1,232 +0,0 @@ -#+TITLE: My Feeds - -* Feeds :elfeed: -** Blogs :blog: - -*** https://major.io/posts/index.xml - -*** https://christine.website/blog.rss - -*** https://sidhartharya.me/posts/index.xml - -*** https://fzakaria.com/feed.xml - -*** https://francis.begyn.be/blog.rss - -*** http://www.willghatch.net/blog/feeds/all.rss.xml - -*** https://ag91.github.io/rss.xml :emacs: - -*** https://danyspin97.org/blog/index.xml - -*** https://sachachua.com/blog/category/emacs/feed/ :emacs: - -*** https://mgdm.net/atom.xml - -*** https://xenodium.com/rss.xml - -*** http://blog.dijit.sh/feed - -*** https://willschenk.com/feed.xml - -*** https://vincent.bernat.ch/en/blog/atom.xml - -*** https://cookie.engineer/weblog/feed.xml - -*** https://adamj.eu/tech/atom.xml - -*** https://aliquote.org/index.xml - -*** https://irreal.org/blog/?feed=rss2 :emacs: - -*** https://yitang.uk/atom.xml - -*** https://jcs.org/rss :openbsd: - -*** https://www.charlieharrington.com/rss.xml - -*** https://occasionallycogent.com/feed.xml - -*** https://jao.io/blog/rss.xml - -*** https://waylonwalker.com/rss.xml - -*** https://blog.sulami.xyz/atom.xml - -*** https://utcc.utoronto.ca/~cks/space/blog/?atom - -*** https://blog.vivekhaldar.com/rss - -*** https://chrisman.github.io/rss.xml - -*** https://ambrevar.xyz/atom.xml - -*** https://emacsredux.com/atom.xml :emacs: - -*** https://pablo.tools/atom.xml - -*** http://feeds.feedburner.com/collabfund - -*** https://opguides.info/posts/index.xml - -*** https://www.alexblackie.com/feed.xml - -*** https://tsdh.org/rss.xml - -*** https://nullprogram.com/feed/ - -*** https://blog.jim-nielsen.com/feed.xml - -*** https://medium.com/feed/@threkk - -*** https://aduros.com/index.xml - -*** https://weekly.nixos.org/feeds/all.rss.xml :weekly:nixos: - -*** https://martinfowler.com/feed.atom - -*** https://ianthehenry.com/feed.xml - -*** https://www.joshwcomeau.com/rss.xml :css: - -*** https://martinfowler.com/feed.atom - -*** https://abhinavsarkar.net/feed.atom - -*** https://notes.abhinavsarkar.net/feed.atom :notes: - -*** https://マリウス.com/index.xml - -*** https://fasterthanli.me/index.xml - -*** https://8thlight.com/blog/feed/atom.xml - -*** https://rauljordan.com/feed.xml - -*** https://vfoley.xyz/index.xml - -*** https://batsov.com/atom.xml - -*** https://blog.royalsloth.eu/posts/index.xml - -*** https://dindi.garjola.net/rss.xml - -*** https://karthinks.com/index.xml :emacs: - -*** https://hachibu.net/posts/index.xml - -*** https://erikwinter.nl/index.xml - -*** https://blog.sumtypeofway.com/atom.xml - -*** https://www.inkandswitch.com/index.xml - -*** https://www.unixsheikh.com/feed.rss - -*** https://brooker.co.za/blog/rss.xml - -*** https://duan.ca/feed.xml - -*** https://thume.ca/atom.xml - -*** https://elis.nu/blog/rss.xml - -*** https://protesilaos.com/codelog.xml - -*** https://codeinthehole.com/index.xml - -*** https://cprss.s3.amazonaws.com/golangweekly.com.xml :weekly:go: - -*** https://shivjm.blog/feed.xml - -*** https://helpdeskheadesk.net/index.xml - -*** https://lepisma.xyz/log/atom.xml - -*** https://lepisma.xyz/journal/atom.xml - -*** https://lepisma.xyz/atom.xml - -*** https://adventurist.me/feed.xml - -*** https://danluu.com/atom.xml - -*** https://danielmangum.com/posts/index.xml - -*** https://mazzo.li/rss.xml - -*** https://apenwarr.ca/log/rss.php - -*** https://zerokspot.com/feeds - -*** https://lazybear.io/index.xml - -*** https://shen.hong.io/rss/ :phylosophy: - -*** https://www.la-grange.net/feed - -*** https://larlet.fr/david/log/ - -*** https://t-ravis.com/index.xml - -*** https://evanhahn.com/blog/index.xml - -*** https://sookocheff.com/index.xml - -*** https://n.survol.fr/feed - -*** https://www.standblog.org/blog/feed/rss2 - -*** https://www.quaternum.net/atom.xml - -*** https://www.arthurperret.fr/feed.xml - -*** https://taoofmac.com/feed - -*** https://jeffbowman.writeas.com/feed/ - -*** https://seirdy.one/atom.xml - -*** https://blog.einval.eu/index.xml - -*** https://gregorymignard.com/posts/index.xml - -*** https://jeremyjanin.com/posts/index.xml - -*** https://sylvaindurand.org/rss.xml - -*** https://fev.al/feed.xml - -*** https://tomcritchlow.com/feed - -** Journals :journal: - -** News :news: - -*** https://lobste.rs/rss :lobsters: - -** Reddit :reddit: - -*** https://www.reddit.com/r/emacs.rss?sort=new :emacs: - -*** https://www.reddit.com/r/NixOS.rss?sort=new :nixos: - - -** Youtube :video:youtube: - -Example of RSS link for youtube: -https://www.youtube.com/feeds/videos.xml?channel_id=UCe5excZqMeG1CIW-YhMTCEQ - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UCAiiOTio8Yu69c3XnR7nQBQ][System Crafters]] :lang:en:emacs: - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UCJ24N4O0bP7LGLBDvye7oCA][Matt D'avella]] :lang:en:productivity:minimalism: - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UCJNItGjNhUx3Zz6W4OCVfHA][Passion Rénovation]] :rénovation:lang:fr: - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UC0uTPqBCFIpZxlz_Lv1tk_g][Protesilaos Stavrou]] :emacs: - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UCtqICqGbPSbTN09K1_7VZ3Q][DirtyBiology]] :biology: - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UCs_azWRsdYDhKonquMlAMfQ][The Unlazy Way]] :productivity: - -*** [[https://www.youtube.com/feeds/videos.xml?channel_id=UCe5excZqMeG1CIW-YhMTCEQ][Emacs Elements]] :emacs: diff --git a/www/vincent.demeester.fr/content/legacy/articles/firefox.org b/www/vincent.demeester.fr/content/legacy/articles/firefox.org @@ -1,7 +0,0 @@ -#+TITLE: Firefox - -* Links -** TODO [[https://ungleich.ch/en-us/cms/blog/2019/09/10/turn-off-doh-firefox/][ungleich blog - Turn off DoH, Firefox. Now.]] -[2019-09-16 Mon 09:49] -** TODO [[http://calpaterson.com/mozilla.html][Firefox usage is down 85% despite Mozilla's top exec pay going up 400%]] -[2020-09-23 Wed 10:58] diff --git a/www/vincent.demeester.fr/content/legacy/articles/fish.org b/www/vincent.demeester.fr/content/legacy/articles/fish.org @@ -1,81 +0,0 @@ -#+TITLE: Fish shell notes -#+FILETAGS: :fish:shell:configuration: -#+setupfile: .setup.org - -I recently (2017) switch to [[https://fishshell.com/][fish]] shell as my interactive shell. There -is a few reason for it: - -- the defaults are really good and there is a little to configure to - achieve what I was trying to do with zsh, -- the autosuggestion feature is quite cool (I even went to reproduce - that in =eshell=), -- the syntax highlighting feature is also killer as it easier to see - problems in the command-line before hitting enter, -- it auto-generates completion from parsing man pages =<3= - - #+BEGIN_SRC sh - $ fish_update_completions - Parsing man pages and writing completions to /home/vincent/.local/share/fish/generated_completions/ - 1793 / 1793 : zramctl.8.gz - #+END_SRC - -At the begining, I used [[https://github.com/oh-my-fish/oh-my-fish][oh-my-fish]] as a simple way in. - -#+BEGIN_QUOTE -Oh My Fish provides core infrastructure to allow you to install -packages which extend or modify the look of your shell. It's fast, -extensible and easy to use. -#+END_QUOTE - -[[https://github.com/oh-my-fish/oh-my-fish][oh-my-fish]] is pretty cool but I tend to use only a few plugin and I -almost have more hand-written configuration files for fish than what -oh-my-fish gives me. So I'm now using [[https://fishshell.com/][fish]] shell /bare-naked/ with my -own configurations. - -According to the [[https://fishshell.com/docs/current/index.html#initialization][documentation]], fish will load files from the -following folder (in order): - -- Configuration shipped with fish, which should not be edited, in - =$__fish_datadir/config.fish= (usually =/usr/share/fish/config.fish=). -- System-wide configuration files, where administrators can include - initialization that should be run for all users on the system - - similar to =/etc/profile= for POSIX-style shells - in - =$__fish_sysconfdir= (usually =/etc/fish/config.fish=); -- Configuration snippets in files ending in =.fish=, in the directories: - - =$XDG_CONFIG_HOME/fish/conf.d= (by default, =~/.config/fish/conf.d/=) - - =$__fish_sysconfdir/conf.d= (by default, =/etc/fish/conf.d=) - - =/usr/share/fish/vendor_conf.d= (set at compile time; by default, - =$__fish_datadir/conf.d=) - If there are multiple files with the same name in these directories, - only the first will be executed. They are executed in order of their - filename, sorted (like globs) in a natural order (i.e. "01" sorts - before "2"). -- User initialization, usually in =~/.config/fish/config.fish= - (controlled by the =XDG_CONFIG_HOME= environment variable). - -Fish will also automatically loads functions from the following folder -(in order): - -- A directory for end-users to keep their own functions, usually - =~/.config/fish/functions= (controlled by the =XDG_CONFIG_HOME= - environment variable). -- A directory for systems administrators to install functions for all - users on the system, usually =/etc/fish/functions=. -- A directory for third-party software vendors to ship their own - functions for their software, usually - =/usr/share/fish/vendor_functions.d=. -- The functions shipped with fish, usually installed in - =/usr/share/fish/functions=. - -#+begin_quote -An autoloaded function becomes available automatically to all -running shells. If the function definition is changed, all running -shells will automatically reload the altered version. Startup time and -memory usage is improved, etc. -#+end_quote - -I'm also using [[https://nixos.org/][nixos]] which have some specificities but we'll see that -later. One specificity though about my setup is the, I may want some -fish function/helper to be available for all users on a server (when -using nixos) or only a user (mainly, when using nixpkgs without nixos, -on Mac OSX or another linux or on Windows with WSL). diff --git a/www/vincent.demeester.fr/content/legacy/articles/generics_aren_t_ready_for_go_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/generics_aren_t_ready_for_go_drew_devault_s_blog.org @@ -1,11 +0,0 @@ -#+title: Generics aren’t ready for Go | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2019/02/18/Generics-arent-ready-for-Go.html - -Have you ever seen someone write something to the effect of “I would use Go, but I need -generics”? Perhaps we can infer from this that many of the people who are pining after -generics in Go are not, in fact, Go users. Many of them are users of another programming -language that does have generics, and they feel that generics are a good fit for this -language, and therefore a good fit for any language. The inertia of “what I’m used to” -comes to a violent stop when they try to use Go. People affected by this frustration -interpret it as a problem with Go, that Go is missing some crucial feature - such as -generics. But this lack of features is itself a feature, not a bug. diff --git a/www/vincent.demeester.fr/content/legacy/articles/getting_boxes_done.org b/www/vincent.demeester.fr/content/legacy/articles/getting_boxes_done.org @@ -1,2 +0,0 @@ -#+title: Getting Boxes Done -#+roam_key: http://www.howardism.org/Technical/Emacs/getting-boxes-done.html diff --git a/www/vincent.demeester.fr/content/legacy/articles/getting_boxes_done_the_code.org b/www/vincent.demeester.fr/content/legacy/articles/getting_boxes_done_the_code.org @@ -1,2 +0,0 @@ -#+title: Getting Boxes Done, the Code -#+roam_key: http://www.howardism.org/Technical/Emacs/getting-more-boxes-done.html diff --git a/www/vincent.demeester.fr/content/legacy/articles/getting_started_with_qemu_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/getting_started_with_qemu_drew_devault_s_blog.org @@ -1,2 +0,0 @@ -#+title: Getting started with qemu | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2018/09/10/Getting-started-with-qemu.html diff --git a/www/vincent.demeester.fr/content/legacy/articles/git.org b/www/vincent.demeester.fr/content/legacy/articles/git.org @@ -1,46 +0,0 @@ -#+TITLE: Git -#+FILETAGS: git -#+SETUPFILE: .setup.org -#+ROAM_ALIAS: "git" - -[[file:git_annex.org][git-annex]] -[[file:gitops.org][gitops]] - -* Links - -** TODO [[https://spacekookie.de/blog/collaborating-with-git-send-email/][Collaborating with git-send-email]] :git: -[2020-03-03 Tue 22:41] - -=git-send-mail= can be used as an alternative to pull requests ([[file:github.org][GitHub]]) or merge requests -([[file:gitlab.org][Gitlab]]). In a gist, =git= helps you generating an [[file:email.org][email]], and also provides helper to -consume patches from mails. - -** TODO [[https://git-rebase.io/][Learn to change history with git rebase!]] :git: -[2019-05-18 Sat 12:55] -** TODO [[https://git-send-email.io/#step-1][Learn to use email with git!]] :git: -[2019-04-05 Fri 08:38] - -** TODO [[https://www.smashingmagazine.com/make-life-easier-when-using-git/][How To Make Life Easier When Using Git — Smashing Magazine]] -[2020-03-28 Sat 16:57] - -** TODO [[https://thoughtbot.com/blog/confirm-your-changes-at-the-end-of-a-git-rebase][Confirm your changes at the end of a git rebase]] -[2020-04-28 Tue 15:56] - -** TODO [[https://martinfowler.com/articles/branching-patterns.html][Patterns for Managing Source Code Branches]] :#read:git: -[2020-04-29 Wed 17:35] -** TODO [[https://encore.dev/blog/git-clone-grpc][Git clone over gRPC • Encore]] -[2020-05-13 Wed 12:38] -** TODO [[https://thoughtbot.com/blog/powerful-git-macros-for-automating-everyday-workflows][Powerful Git Macros For Automating Everyday Workflows]] :git: -[2020-05-14 Thu 16:14] - -git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative $@..$(git rev-parse --abbrev-ref HEAD) - -** TODO [[https://dangitgit.com/][Dangit, Git!?!]] -[2020-05-19 Tue 17:38] -** TODO [[https://jemma.dev/blog/git-stash][Git stash doesn’t have to be scary | Jemma Issroff]] -[2020-12-04 Fri 10:24] - -** TODO [[https://github.blog/2020-12-17-commits-are-snapshots-not-diffs/][Commits are snapshots, not diffs - The GitHub Blog]] -[2020-12-21 Mon 10:09] -** TODO [[https://tech.lightspeedhq.com/when-pushing-is-not-enough-a-git-story/][When Pushing is Not Enough, A Git Story]] -[2021-02-03 Wed 23:38] diff --git a/www/vincent.demeester.fr/content/legacy/articles/git_annex.org b/www/vincent.demeester.fr/content/legacy/articles/git_annex.org @@ -1,7 +0,0 @@ - -#+TITLE: git-annex -#+ROAM_ALIAS: "Git Annex" "git annex" - -* Links -** [[https://writequit.org/org/git-annex.html][Git-annex notes and configuration]] -[2020-06-18 Thu 18:28] diff --git a/www/vincent.demeester.fr/content/legacy/articles/git_sr_ht.org b/www/vincent.demeester.fr/content/legacy/articles/git_sr_ht.org @@ -1,2 +0,0 @@ - -#+TITLE: git.sr.ht diff --git a/www/vincent.demeester.fr/content/legacy/articles/github.org b/www/vincent.demeester.fr/content/legacy/articles/github.org @@ -1,2 +0,0 @@ -#+TITLE: GitHub -#+ROAM_ALIAS: "Github" "github" diff --git a/www/vincent.demeester.fr/content/legacy/articles/gitlab.org b/www/vincent.demeester.fr/content/legacy/articles/gitlab.org @@ -1,7 +0,0 @@ -#+TITLE: Gitlab - -* [[https://about.gitlab.com/blog/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/][How to automatically create a new MR on GitLab with GitLab CI | GitLab]] -[2022-05-03 Tue 14:23] - -* [[https://haseebmajid.dev/blog/gitlab-auto-mr-with-gitlab][How to auto create MRs in Gitlab | Haseeb Majid's Blog]] -[2022-05-03 Tue 14:23] diff --git a/www/vincent.demeester.fr/content/legacy/articles/gitops.org b/www/vincent.demeester.fr/content/legacy/articles/gitops.org @@ -1,89 +0,0 @@ -#+TITLE: GitOps -#+FILETAGS: git gitops ci cd devops -#+SETUPFILE: .setup.org - -* What is GitOps? - -GitOps is an app dev and operations methodology that leverages - -- an entire system that is described declaratively -- code that is version controlled and -- software agents that reconcile and ensure correctness (along with alerts, etc). - -GitOps is a paradigm, not a specific tool or technology. GitOps applies to everything and brings business value. - -Maya Kaczorowski adds that when you have everything “as code” with GitOps, you can make -your code as automated and error-free as possible. With GitOps, you push a change to code -that’s reviewed, and then you use automation to do the hard stuff of deploying, -monitoring, etc. You also have a pipeline where devs only need to focus on developing -their apps, and any operations or security control can be automatically verified or -enforced as part of that pipeline. Teams have a clear separation of responsibilities. - -** The 4 Principles of GitOps - -1. The entire system is described *declaratively* -2. The canonical desired system is *versioned* in git -3. Approved changes can be *automatically applied* to the system -4. *Software agents* ensure correctness and alert (diffs & actions) - -Most importantly, these are principles, *not technologies*. You can apply the principles -across many of your existing technologies without replacing them. - -Also, *GitOps* is not constrained to Git. You can use whatever support version control. - -** What is GitOps for Security? - -It provides - -1. Immutable infrastructure -2. Single source of truth -3. Dev velocity - -** Transparency and Collaboration - -1. *Reversibility*: You can do rollbacks, and lower mean time to resolving config-based - outages with version controlling. -2. *Audit trails*: You can track the history of a repo, … - -This also helps to reduce the risk of relying on a single employee. - -** What can you GitOps? - -You can GitOps not just apps, but infrastructure, things that go onto DNS and identity -providers, Chaos experiments and Kubernetes Clusters, and more. You can GitOps all the -things! - -* GitOps tools - -- [[https://www.ansible.com/][Ansible]] -- [[https://argoproj.github.io/argo-cd/][ArgoCD]] -- [[https://www.runatlantis.io/][Atlantis]] -- [[https://www.chef.io/][Chef]] -- [[https://draft.sh/][Draft]] -- [[https://eksctl.io/][eksctl]] -- [[https://fluxcd.io/][FluxCD]] -- [[https://flagger.app/][Flagger]] -- [[https://git-scm.com/][Git]] -- [[https://gitkube.sh/][GitKube]] -- [[https://toolkit.fluxcd.io/][GitOps Toolkit]] -- [[https://helm.sh/][Helm]] -- [[https://medium.com/keikoproj/keiko-running-kubernetes-at-scale-1178491c1440][Keiko]] -- [[https://kubernetes.io/][Kubernetes]] -- [[https://kustomize.io/][Kustomize]] -- [[https://www.jenkins.io/][Jenkins]] -- [[https://jenkins-x.io/][Jenkins X]] -- [[https://www.pulumi.com/][Pulumi]] -- [[https://puppet.com/][Puppet]] -- [[http://salt.io/][Salt]] -- [[https://skaffold.dev/][Skaffold]] -- [[https://www.terraform.io/][Terraform]] - -One day, [[file:tekton.org][Tekton]] components could be in that list - -* References -- [[https://gitops-community.github.io/kit/#need-help-or-want-updates][GitOps Conversation Kit (beta) | GitOps Community]] - -* Links - -** TODO [[https://zwischenzugs.com/2020/11/30/gitops-decisions/][GitOps Decisions – zwischenzugs]] -[2020-12-02 Wed 10:57] diff --git a/www/vincent.demeester.fr/content/legacy/articles/gnupg.org b/www/vincent.demeester.fr/content/legacy/articles/gnupg.org @@ -1,6 +0,0 @@ - -#+TITLE: gnupg -#+ROAM_ALIAS: "GnuPG" "gpg" - -* TODO [[https://metacode.biz/openpgp/proofs][Decentralized proofs]] -[2020-05-09 Sat 13:11] diff --git a/www/vincent.demeester.fr/content/legacy/articles/gnus.org b/www/vincent.demeester.fr/content/legacy/articles/gnus.org @@ -1,13 +0,0 @@ - -#+TITLE: Gnus -#+SUBTITLE: a flexible message reader running under GNU Emacs. - -#+begin_quote -The main Gnus goal is to provide the user with an efficient and extensible interface -towards dealing with large numbers of messages, no matter the form they may have or -wherever they may come from. -#+end_quote - -* Links -** TODO [[https://gist.github.com/zeroed/df307e7f52845a6502700a50f4a12082][Practical guide to use Gnus with Gmail]] -[2020-03-13 Fri 16:31] diff --git a/www/vincent.demeester.fr/content/legacy/articles/go.org b/www/vincent.demeester.fr/content/legacy/articles/go.org @@ -1,137 +0,0 @@ -#+TITLE: Go -#+SUBTITLE: an open source programming language that makes it easy to build simple, reliable, and efficient software. -#+ROAM_ALIAS: "golang" "go" - - -* Design docs - -Here is a list of interesting design docs around Go. - -** Generics - -- [[file:generics_aren_t_ready_for_go_drew_devault_s_blog.org][Generics aren’t ready for Go | Drew DeVault’s Blog]] -- [[https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md][Type Parameters - Draft Design]] - + [[https://rakyll.org/generics-proposal/][Few things on generics]] Rakyll's take on the design - -* Links - -** [[https://rakyll.org/inlined-defers/][Inlined defers in Go · Go, the unwritten parts]] :go: -[2020-06-08 Mon 10:43] - -** [[https://0x46.net/thoughts/2018/12/29/go-libraries/][Stop writing broken Go libraries]] -[2020-05-04 Mon 20:33] - -** [[https://www.arp242.net/go-last-resort.html][Go’s features of last resort]] -[2019-11-27 Wed 14:54] - -** [[https://www.bartfokker.nl/posts/decorators/][Clean code using decorators :: Programming blog — Programming blog]] - -** [[https://dave.cheney.net/practical-go/presentations/qcon-china.html][Practical Go: Real world advice for writing maintainable Go programs]] - -** [[https://github.com/undefinedlabs/go-integration/blob/master/example/example_test.go][go-integration/example_test.go at master · undefinedlabs/go-integration]] :test: -[2019-11-27 Wed 15:56] - -An example of transparent integration with containers on tests. - -** [[https://www.manifold.co/blog/how-go-interfaces-can-facilitate-switching-external-services-619cc478e20a][How Go interfaces can facilitate switching external services - Manifold]] -[2019-03-27 Wed 18:18] - -** [[https://www.alexedwards.net/blog/an-overview-of-go-tooling][An Overview of Go's Tooling - Alex Edwards]] :tools: -[2019-04-17 Wed 14:17] -** [[https://peter.bourgon.org/blog/2019/04/24/go-naming-tips.html][Peter Bourgon · Go naming tips]] -[2019-04-24 Wed 16:17] - -** [[https://npf.io/2019/06/do-or-do-not/][Do or Do Not · npf.io]] -[2019-06-21 Fri 18:16] - -** [[https://kristoff.it/blog/why-go-and-not-rust/][Why Go and not Rust? | Loris Cro's Personal Blog]] :rust: -[2019-09-17 Tue 11:38] -** [[https://philpearl.github.io/post/bad_go_slice_of_pointers/?utm_campaign=The%2520Go%2520Gazette&utm_medium=email&utm_source=Revue%2520newsletter][Bad Go: slices of pointers · Phil Pearl's Blog]] -[2019-09-17 Tue 10:40] - -** [[https://divan.dev/posts/gopath/][I still ❤️ you, GOPATH · divan's blog]] :go: -[2019-10-01 Tue 17:55] -** [[https://blog.golang.org/publishing-go-modules][Publishing Go Modules - The Go Blog]] :modules: -[2019-11-05 Tue 15:02] -** TODO [[https://rakhim.org/2019/12/summary-of-concurrency-is-not-parallellism-a-talk-by-rob-pike/][Summary of Concurrency Is Not Parallellism, a talk by Rob Pike - Rakhim.org]] -[2019-12-23 Mon 17:21] -** TODO [[https://pace.dev/blog/2020/02/13/batching-operations-in-go-by-mat-ryer][Batching operations in Go by Mat Ryer - PACE.]] -[2020-03-19 Thu 21:05] - -** TODO [[https://pace.dev/blog/2020/02/12/why-you-shouldnt-use-func-main-in-golang-by-mat-ryer][Why you shouldn't use func main in Go by Mat Ryer - PACE.]] -[2020-03-19 Thu 21:05] - - -** TODO [[https://www.arp242.net/static-go.html][Statically compiling Go programs]] :compile:go: -[2020-04-14 Tue 15:13] -** TODO [[https://pace.dev/blog/2020/02/03/context-aware-ioreader-for-golang-by-mat-ryer.html][Context-aware io.Reader for Go by Mat Ryer + David Hernandez - PACE.]] -[2020-04-01 Wed 17:28] -** TODO [[https://blog.sbstp.ca/go-quirks/][sbstp's blog — go quirks]] -[2020-03-29 Sun 11:48] -** TODO [[https://github.com/stretchr/testify/pull/933/files][Avoid calling Helper() on the happy path by bboreham · Pull Request #933 · stretchr/testify]] :go: -[2020-04-27 Mon 15:23] - -We should do the same for gotestyourself - -** TODO [[https://github.com/go-noisegate/noisegate][go-noisegate/noisegate: Noise Gate: Golang test runner to get faster test results]] :go: -[2020-05-05 Tue 10:57] - -*** [[https://github.com/go-noisegate/go-noisegate.el][go-noisegate/go-noisegate.el: Emacs plugin for Noise Gate]] :emacs: -[2020-05-05 Tue 10:57] - -** TODO [[https://orndorffgrant.com/framework-agnostic-go-handlers/][Framework Agnostic HTTP Endpoint Go Handlers]] :go: -[2020-05-25 Mon 11:07] - -** TODO [[https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md][Type Parameters - Draft Design]] :go:#read: -[2020-06-17 Wed 16:47] - -** TODO [[https://rauljordan.com/2020/07/06/why-go-error-handling-is-awesome.html][Why Go’s Error Handling is Awesome | rauljordan]] -[2020-07-09 Thu 18:37] - -** TODO [[https://rauljordan.com/2020/05/25/immutability-patterns-in-go.html][Immutability Patterns in Go | rauljordan]] -[2020-07-09 Thu 18:37] - -** TODO [[https://rauljordan.com/2019/09/23/how-to-write-an-event-feed-library.html][Writing an One-to-Many Event Feed Library in Go | rauljordan]] -[2020-07-09 Thu 18:37] - -** TODO [[https://bencane.com/stories/2020/07/06/how-i-structure-go-packages/#/eof-bio][How I Structure Go Packages]] -[2020-07-17 Fri 07:23] - -** TODO [[https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride][I want off Mr. Golang's Wild Ride - fasterthanli.me]] -[2020-07-01 Wed 19:08] - -** TODO [[https://christine.website/blog/within-go-repo-layout-2020-09-07][The Within Go Repo Layout - Christine Dodrill]] -[2020-09-08 Tue 07:24] - -Go repository layout is a very different thing compared to other languages. There's a lot of conflicting opinions and little firm guidance to help steer people along a path to more maintainable code. This is a collection of guidelines that help to facilitate understandable and idiomatic Go. -** TODO [[https://johnsogg.github.io/emacs-golang][Set up Emacs for Golang from scratch - December 2016 · jnl]] :go: -[2020-04-09 Thu 17:44] - -Do the same in 2020 (with go modules), without lsp for now -Add this to notes (go language) - -** TODO [[https://github.com/quii/learn-go-with-tests][quii/learn-go-with-tests: Learn Go with test-driven development]] -[2020-11-16 Mon 09:46] - -** TODO [[https://fasterthanli.me/articles/abstracting-away-correctness][Abstracting away correctness - fasterthanli.me]] -[2020-06-30 Tue 19:50] - -** TODO [[https://blog.questionable.services/article/guide-logging-middleware-go/][A Guide To Writing Logging Middleware in Go · questionable services]] -[2020-10-06 Tue 17:18] - -** TODO [[https://www.arp242.net/read-stdin.html][Better UX when reading from stdin]] -[2019-12-12 Thu 18:03] - - -** TODO [[https://www.alexedwards.net/blog/which-go-router-should-i-use][Which Go router should I use? (with flowchart) – Alex Edwards]] -:PROPERTIES: -:CREATED:[2021-10-05 Tue 16:01] -:END: - -** TODO [[https://christine.website/blog/gonads-2022-04-24][Crimes with Go Generics - Xe]] -[2022-05-05 Thu 22:05] - -** Misc -- https://peter.bourgon.org/go-for-industrial-programming/#testing -- https://www.bartfokker.nl/posts/decorators/ -- http://technosophos.com/2018/07/04/be-nice-and-write-stable-code.html diff --git a/www/vincent.demeester.fr/content/legacy/articles/haskell.org b/www/vincent.demeester.fr/content/legacy/articles/haskell.org @@ -1,26 +0,0 @@ -#+TITLE: haskell -#+FILETAGS: haskell language programming -#+SETUPFILE: .setup.org - -* Links -** TODO [[https://williamyaoh.com/posts/2019-11-24-design-and-testing-articles.html][A list of Haskell articles on good design, good testing | William Yao]] :haskell: -[2019-11-29 Fri 19:53] - -** TODO [[https://lexi-lambda.github.io/blog/2016/10/03/using-types-to-unit-test-in-haskell/][Using types to unit-test in Haskell]] :haskell: -[2019-11-29 Fri 19:55] - -** TODO [[https://wickstrom.tech/programming/2019/11/17/time-travelling-and-fixing-bugs-with-property-based-testing.html][Time Travelling and Fixing Bugs with Property-Based Testing | Oskar Wickström]] -[2019-11-29 Fri 19:56] - -** TODO [[https://lexi-lambda.github.io/blog/2017/06/29/unit-testing-effectful-haskell-with-monad-mock/][Unit testing effectful Haskell with monad-mock]] :haskell: -[2019-11-29 Fri 19:56] - -** TODO [[https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/][Parse, don’t validate]] -[2019-11-29 Fri 19:58] -** TODO [[http://dev.stephendiehl.com/hask/][What I Wish I Knew When Learning Haskell 2.5 ( Stephen Diehl )]] -[2020-02-17 Mon 19:19] - -** TODO [[https://abhinavsarkar.net/posts/twt-notes-1/][Notes for 'Thinking with Types: Type-level Programming in Haskell', Chapters 1–5 | abhinavsarkar.net]] -[2020-03-19 Thu 08:35] -** TODO [[https://www.poberezkin.com/posts/2021-04-21-what-i-wish-somebody-told-me-when-i-was-learning-Haskell.html][Evgeny Poberezkin - What I wish somebody told me when I was learning Haskell]] -[2021-04-23 Fri 06:57] diff --git a/www/vincent.demeester.fr/content/legacy/articles/how_i_decide_between_many_programming_languages_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/how_i_decide_between_many_programming_languages_drew_devault_s_blog.org @@ -1,9 +0,0 @@ -#+title: How I decide between many programming languages | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2019/09/08/Enough-to-decide.html - -I have a few old standards in my toolbelt that I find myself calling upon most often, but -I try to learn enough about many programming languages to reason about whether or not -they’re suitable to any use-case I’m thinking about. The best way is to learn by doing, -so getting a general impression of the utility of many languages helps equip you with the -knowledge of whether or not they’d be useful for a particular problem even if you don’t -know them yet. diff --git a/www/vincent.demeester.fr/content/legacy/articles/how_to_drive_upstream_project.org b/www/vincent.demeester.fr/content/legacy/articles/how_to_drive_upstream_project.org @@ -1,7 +0,0 @@ - -#+TITLE: How to drive upstream project - -* TODO Track upstream work - -- How to track upstream work in your downstream issue tracker -- How to converge the needs/requirements diff --git a/www/vincent.demeester.fr/content/legacy/articles/images/sandbox/long-img.png b/www/vincent.demeester.fr/content/legacy/articles/images/sandbox/long-img.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/images/sandbox/pic-demo.png b/www/vincent.demeester.fr/content/legacy/articles/images/sandbox/pic-demo.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/images/sandbox/some_filename.png b/www/vincent.demeester.fr/content/legacy/articles/images/sandbox/some_filename.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/images/tekton/canary-pipeline.png b/www/vincent.demeester.fr/content/legacy/articles/images/tekton/canary-pipeline.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/images/tekton/tekton-horizontal-color.png b/www/vincent.demeester.fr/content/legacy/articles/images/tekton/tekton-horizontal-color.png Binary files differ. diff --git a/www/vincent.demeester.fr/content/legacy/articles/index.org b/www/vincent.demeester.fr/content/legacy/articles/index.org @@ -1,30 +0,0 @@ -#+TITLE: Articles -#+FILETAGS: #home article knowledge -#+SETUPFILE: .setup.org - -This set of articles is my knowledge base. This is managed using [[file:org_mode.org][Org Mode]] and specifically -[[file:org_roam.org][org-roam]]. This content is kept up-to-date across time (compared to posts). - -The following part of this page tries to present an organization to all my -articles ; but there is a [[file:sitemap.org][sitemap]] if you want to see all the content. -/The sitemap is gonna be a little bit hard to navigate without a filtering mechanism./ - -- [[file:kubernetes.org][Kubernetes]] and [[file:openshift.org][OpenShift]] - + [[file:knative.org][Knative]] - + [[file:tekton.org][Tekton]] - - [[file:tekton_dev.org][Tekton development environment]] - - [[file:tekton-usage.org][Tektoncd usage and examples]] -- [[file:linux.org][Linux]] - + [[file:fedora.org][Fedora]] - + [[file:nixos.org][NixOS]] - + Misc - - [[file:yubikey.org][Yubikey setup on Linux]] -- [[file:programming.org][Programming]] - + [[file:bash.org][bash]] - + [[file:elisp.org][elisp]] - + [[file:go.org][golang]] - + [[file:haskell.org][haskell]] - + [[file:development-machines.org][Development machines made easy]] -- Miscellaneous - + [[file:sandbox.org][Emacs org-mode sandbox]] - + [[file:fish.org][Fish shell notes]] diff --git a/www/vincent.demeester.fr/content/legacy/articles/individual_contributors.org b/www/vincent.demeester.fr/content/legacy/articles/individual_contributors.org @@ -1,13 +0,0 @@ - -#+TITLE: Individual Contributors - -Primary responsibilities -- Participate in sprint planning calls -- Groom product backlog - refine, estimate backlog items -- Self-assign user stories -- Write code and tests -- Write documentation -- Triage bugs -- Fix bugs -- Participate in code reviews -- Participate in sprint review and sprint retrospective diff --git a/www/vincent.demeester.fr/content/legacy/articles/infrastructure.org b/www/vincent.demeester.fr/content/legacy/articles/infrastructure.org @@ -1,118 +0,0 @@ - -#+TITLE: Infrastructure -#+ROAM_ALIAS: "Personal infrastructure" "Infrastructure" - -This should cover links and idea around my infrastructure (and infrastructure in -general). Their implementation should be /mostly/ be covered on the [[file:config_configurations.org][configurations]] part, -as it all lives in my [[https://git.sr.ht/~vdemeester/home][monorepo]]. - -I treat my local machine as *pet* but anything that is remote should -be considered as cattle. This mainly means *it's a matter of -minutes/hours to setup back those machines* (limiting factor here -would be network and compute time). Everything should be reproductible -as much as possible *and* tested if possible. It is also true for my *pet* machines -though, they should be quick to re-setup if need be (from backups, …). - -#+TOC: headlines 1 - -* Needs and requirements - -What are my needs and what are my requirements… Writing (and thinking) about them should -help me decide what to do in terms of /Personal infrastructure/. Also, take into account -my current "hardware" before taking decision (as "this would be perfect, but does the -current hardware do the job"). - -One thing to note though, in /Personal infrastructure/ I also have some elements that are -related to work. I am a developer, and I work mainly on [[file:openshift.org][OpenShift]] and [[file:kubernetes.org][Kubernetes]], and thus -I need ways to create temporary cluster on my network. - -Let's split the _needs_ into several parts: - -- Work :: - + OpenShift cluster(s) for development and testing purpose - - [[file:openshift_on_vm_bare_metal.org][OpenShift on VM Bare metal]] - - [[file:crc.org][OpenShift locally (CRC)]] - + Kubernetes cluster(s) for development and testing purpose - - [[file:kind.org][kind]] for developement (one-node, locally or multiple node, remotely) - - [[file:microk8s.org][microk8s]] for /remote/ development (multiple node) - - [[file:kubernetes_on_nixos.org][kubernetes on nixos]] for a "long-term" cluster running -- Personnal :: - + Basics: - - Backup and network data access (NAS) - - Secure Remote access to data and machines wherever they are (VPN) - - Sync between systems (some folders like documents, …) - + Extras: - - Automation system à-là-ifttt - - Async download system - - Notifications/Report system (todo deadlines, work report mail, …) - - Health tracking system (fitbit, … sync) - - Media library system - - Music sync system (=music= <-> spotify if possible – i.e playlists, downloads) - - Same for Movies, TV Shows, … - - Private/public source repository (if not using [[file:github.org][github]], [[file:gitlab.org][gitlab]], [[file:git_sr_ht.org][git.sr.ht]], …) - - Cache system (for build, system updates, …) - - Sharing system (publish securely to a group of ppl) - - Messaging bouncer (irc, …) — get history, keep connected - + Bonus: - - Personal libraries depot (ex =lib.tools=) - - Continous integration - -The Basics *need* to be taken care of in priority, and _always working_. As in kanban, if -those are not working, it's *top priority* to fix them. - -The Extras are nice to have but not required, so decide what to do for them depending on -the time you have. This also means, if those are down for a reason, it's possible to not -get them back up. And the /Bonus/ are really if you're bored or have time to kill -(i.e. never). - -Also, something for my future self : don't tie personal infrastructure together. What I -mean by that is : use the right things (tools, hardware, …) that do the job, even if it's -not the one you work on at work. - -* Systems - -I am going to list the different system I've got, being /bare-metal/ (aka laptop, -workstation, nuc, …), in the _cloud_ or VMs. Those are the _pet_ systems, aka the ones -that are significant. I won't list all the _cattle_ VMs I've got. - -#+TOC: headlines 1 local - -** naruhodo - -Thinkpad t480s - -** wakasu - -Thinkpad P50 - -** okinawa - -** sakhalin - -** honshu - -** kerkouane :remote: - -** honshu - -macbook pro 13 - -** hokkaido - -Dell - -** sapporo - -* Triage - -** Softwares and tools - -- [[file:email.org][email]]s -- [[file:ipfs.org][ipfs]] -- [[https://www.paritybit.ca/blog/setting-up-a-status-page][Setting Up a Status Page - paritybit.ca]] - -** Links -*** TODO [[https://jkcfg.github.io/#/][jk]] :configuration:infra: -[2020-01-03 Fri 17:02] -*** TODO [[https://ferd.ca/a-pipeline-made-of-airbags.html][A Pipeline Made of Airbags]] -[2020-09-25 Fri 11:46] diff --git a/www/vincent.demeester.fr/content/legacy/articles/internet_of_things.org b/www/vincent.demeester.fr/content/legacy/articles/internet_of_things.org @@ -1,7 +0,0 @@ -#+TITLE: Internet of Things - -* Links -** TODO [#C] [[https://vas3k.com/blog/dumbass_home/?ref=sn][Dumbass Home 2.0 :: Internet of Things. How to Automate Your Flat Today :: vas3k.com]] -[2020-03-08 Sun 16:34] - -Put this somewhere into notes diff --git a/www/vincent.demeester.fr/content/legacy/articles/ipfs.org b/www/vincent.demeester.fr/content/legacy/articles/ipfs.org @@ -1,17 +0,0 @@ - -#+TITLE: ipfs - -[[https://ipfs.io/][IPFS]] is peer-to-peer hypermedia protocol designed to make the web faster, safer, and more -open. - -* What is =ipfs= ? - -- [[https://hackernoon.com/understanding-ipfs-in-depth-1-5-a-beginner-to-advanced-guide-e937675a8c8a][Understanding IPFS in Depth(1/6): A Beginner to Advanced Guide]] -- [[https://medium.com/towardsblockchain/understanding-ipfs-in-depth-2-6-what-is-interplanetary-linked-data-ipld-c8c01551517b][Understanding IPFS in Depth(2/6): What is InterPlanetary Linked Data(IPLD)?]] -- [[https://medium.com/textileio/tutorial-series-setting-up-an-ipfs-peer-4056e6c69612][Tutorial Series: Setting up an IPFS peer]] - -* Links -** [[https://elais.codes/deploying-this-site-with-ipfs-and-scheme.html][Deploying This Site with IPFS and Scheme - Elais Codes]] -[2020-06-08 Mon 10:38] -** [[https://github.com/ipfs-shipyard/ipfs-deploy][ipfs-shipyard/ipfs-deploy: Zero-Config CLI to Deploy Static Websites to IPFS]] -[2020-06-08 Mon 10:40] diff --git a/www/vincent.demeester.fr/content/legacy/articles/keyboard.org b/www/vincent.demeester.fr/content/legacy/articles/keyboard.org @@ -1,13 +0,0 @@ -#+TITLE: Keyboards -#+FILETAGS: keyboard moonlander ergodox - -* Links - -** [[https://github.com/optozorax/moonlander][optozorax/moonlander: My keymap for moonlander keyboard]] -[2021-08-04 Wed 20:07] - -** [[https://github.com/lee-dohm/keyboard-firmware][lee-dohm/keyboard-firmware: Firmware that I use for my various mechanical keyboards]] -[2021-08-04 Wed 20:09] - -** [[https://configure.zsa.io/moonlander/layouts/vKAxL/latest/0][Oryx: The ZSA Keyboard Configurator]] -[2021-08-11 Wed 09:45] diff --git a/www/vincent.demeester.fr/content/legacy/articles/kind.org b/www/vincent.demeester.fr/content/legacy/articles/kind.org @@ -1,60 +0,0 @@ - -#+TITLE: kind - -[[https://kind.sigs.k8s.io/][=kind=]] runs [[file:kubernetes.org][Kubernetes]] in [[file:docker.org][Docker]] containers, and maybe more in the future. - -* Multi-node setup - -I am using the following configuration to be able to run a =kind= cluster on one of my local -server and target it from my laptop. - -:note: -wakasu.home IP is =192.168.1.77= -:end: - -#+begin_src yaml :tangle /ssh:wakasu.home:/home/vincent/var/kind/wakasu.kind.yaml -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -networking: - apiServerAddress: "192.168.1.77" - apiServerPort: 8443 -containerdConfigPatches: -- |- - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"] - endpoint = ["http://sakhalin.home:5000"] -nodes: -- role: control-plane - kubeadmConfigPatches: - - | - kind: InitConfiguration - nodeRegistration: - kubeletExtraArgs: - node-labels: "ingress-ready=true" - extraPortMappings: - - containerPort: 80 - hostPort: 80 - protocol: TCP - - containerPort: 443 - hostPort: 443 - protocol: TCP -- role: worker -- role: worker -#+end_src - -Then, to provision this and get the configuration file, it's a matter of 2 commands. - -#+begin_src shell -ssh wakasu.home kind create cluster --config ~/var/kind/wakasu.kind.yaml --name wakasu -ssh wakasu.home kind get kubeconfig --name wakasu > ~/.kube/config.wakasu.kind -cat <<EOF | kubectl --kubeconfig=$HOME/.kube/config.wakasu.kind apply -f - -apiVersion: v1 -kind: ConfigMap -metadata: - name: local-registry-hosting - namespace: kube-public -data: - localRegistryHosting.v1: | - host: "localhost:5000" - help: "https://kind.sigs.k8s.io/docs/user/local-registry/" -EOF -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/knative.org b/www/vincent.demeester.fr/content/legacy/articles/knative.org @@ -1,54 +0,0 @@ - -#+TITLE: Knative -#+FILETAGS: knative kubernetes - -[[https://knative.dev][Knative]] is a [[file:kubernetes.org][kubernetes]]-based platform to deploy and manage modern [[file:serverless.org][serverless]] workloads. - -* Command lines -:PROPERTIES: -:CUSTOM_ID: h:25a70ace-92ba-4de5-ac86-d2e8801bd5c8 -:END: -- live cli updating https://github.com/gosuri/uilive -- live progress barse https://github.com/gosuri/uiprogress -- for a cool prompt (kubeprompt) https://github.com/c-bata/go-prompt -- progress bars :https://github.com/vbauerster/mpb -- questions during CLI https://github.com/AlecAivazis/survey - -* Check version of knative -:PROPERTIES: -:CUSTOM_ID: h:934f08e2-1009-469d-8ab3-f18e3da7067a -:END: - -#+BEGIN_SRC sh -kubectl describe deploy controller --namespace knative-serving -# […] -... -Pod Template: - Labels: app=controller - Annotations: sidecar.istio.io/inject=false - Service Account: controller - Containers: - controller: - # Link to container used for Knative install - Image: gcr.io/knative-releases/github.com/knative/serving/cmd/controller@sha256:59abc8765d4396a3fc7cac27a932a9cc151ee66343fa5338fb7146b607c6e306 -... -# […] -#+END_SRC - -Copy the full gcr.io link to the container and paste it into your browser. If you are -already signed in to a Google account, you'll be taken to the Google Container Registry -page for that container in the Google Cloud Platform console. If you aren't already signed -in, you'll need to sign in a to a Google account before you can view the container -details. - -* Community -:PROPERTIES: -:CUSTOM_ID: h:ecea89b9-d163-4128-ac11-7cf06ea4582e -:END: - -- https://github.com/knative/docs/blob/master/community/ROLES.md -- https://github.com/knative/docs/blob/master/community/VALUES.md -- https://github.com/knative/docs/blob/master/community/CONTRIBUTING.md -* Links -** [[https://www.arthurkoziel.com/running-knative-with-istio-in-kind/][Running Knative with Istio in a Kind Cluster]] :kubernetes:knative: -[2020-05-04 Mon 13:32] diff --git a/www/vincent.demeester.fr/content/legacy/articles/kubernetes.org b/www/vincent.demeester.fr/content/legacy/articles/kubernetes.org @@ -1,62 +0,0 @@ - -#+TITLE: Kubernetes - -- [[file:knative.org][Knative]] notes - -* Provisioning - -There is a bunch of ways to provision Kubernetes, but you need to take few elements into -account: -- is it a "throwable" cluster, for development or tests purposes -- is it a local cluster (not exposed to the public) -- is it a production grade cluster (exposed to the public) - -For the /throwable/ case, there is a bunch of possibilities, from running VMs to running -kubernetes in containers. - -- [[file:kubernix.org][kubernix]] for [[file:nixos.org][NixOS]] specific. -- [[file:minikube.org][minikube]] -- [[file:kind.org][kind]] -- [[file:microk8s.org][microk8s]] - -For the local cluster part, you can rely on [[https://github.com/kelseyhightower/kubernetes-the-hard-way/][/the hard way/]] or on tools from the community, -depending on your system. - -- I am trying to use [[file:nixos.org][NixOS]] for this : [[file:kubernetes_on_nixos.org][Kubernetes on NixOS]]. -- In parallel, I'm gonna setup k8s using [[file:microk8s.org][microk8s]] on VMs too, so that I can test with a - Ubuntu host. - -For the production grade cluster, /well/, I am not there yet, but best advice, use GKE or -[[file:openshift.org][OpenShift]]. - -* Configuration - -** Extract configuration context to its own file - -#+begin_src shell -kubectl config view --minify --flatten \ - --context=put-the-context-here > ~/.kube/config.context -#+end_src - -* Links - -** TODO [[http://boringis.cool/][boring is cool | advocacy site for boring technology]] -** TODO [[https://ahmet.im/blog/mastering-kubeconfig/][Mastering the KUBECONFIG file]] -** TODO [[https://christine.website/blog/drone-kubernetes-cd-2020-07-10][Continuous Deployment to Kubernetes with Gitea and Drone - Christine Dodrill]] -[2020-07-11 Sat 14:30] - -** TODO [[https://medium.com/flant-com/kubectl-commands-and-tips-7b33de0c5476][Ready-to-use commands and tips for kubectl | by Flant staff | Flant | Aug, 2020 | Medium]] -[2020-09-10 Thu 13:24] -** TODO [[https://blog.dave.tf/post/new-kubernetes/][A better Kubernetes, from the ground up · blog.dave.tf]] -[2020-11-30 Mon 19:05] -** TODO [[https://aporcupine.com/2020/03/pi4-kubernetes-cluster/][🤖 Setting Up a Raspberry Pi 4 Kubernetes Cluster | A_Porcupine - A Blog about technology and other such geekery!]] -[2020-12-09 Wed 16:34] - -** TODO [[https://dbafromthecold.com/2020/11/30/building-a-raspberry-pi-cluster-to-run-azure-sql-edge-on-kubernetes/][Building a Raspberry Pi cluster to run Azure SQL Edge on Kubernetes | DBA From The Cold]] -[2020-12-09 Wed 16:45] - -** TODO [[https://dbafromthecold.com/2020/12/03/updating-my-kubernetes-raspberry-pi-cluster-to-containerd/][Updating my Kubernetes Raspberry Pi Cluster to containerd | DBA From The Cold]] -[2020-12-09 Wed 16:47] - -** TODO [[https://geektechstuff.com/2020/11/18/kubernetes-cluster-on-raspberry-pi/][Kubernetes Cluster On Raspberry Pi – Geek Tech Stuff]] -[2020-12-09 Wed 16:47] diff --git a/www/vincent.demeester.fr/content/legacy/articles/kubernetes_on_nixos.org b/www/vincent.demeester.fr/content/legacy/articles/kubernetes_on_nixos.org @@ -1,39 +0,0 @@ -#+TITLE: Kubernetes on NixOS - -This document will serve to document the way I setup my own little personal kubernetes -cluster on NixOS. I am using virtual machines for this (as of today) because it is simpler -to use, and as for [[file:microk8s.org][microk8s]] document, I rely on the fact that my network setup is capable -of assigning a predefined IP to a given mac address. - -* Why Kubernetes at home ? - -The first question that can come to mind is "why the hell do you want to setup a -kubernetes cluster at home" ? And… that's a valid question. - -I work daily on Kubernetes and OpenShift, and on a CI/CD tooling that I want to be as -useful as possible. If I don't use it myself, what the hell am I doing right ? That's the -main reason why setuping a Kubernetes (and of course [[https://tekton.dev][Tekton]] on it) — gaining operational -knowledge, find the gap and enhancements, … - -* Bootstrap the cluster - -How big should the cluster be ? 3 nodes or 5 nodes ? -Let's start with 3, and figure the rest out. - -We need to do the following to boostrap the cluster: -- Configure the network to allocate a set of IP for a set a MAC address -- Create VMs images (=qcow2=) with NixOS and the base system on -- Create VMs on a remote server libvirt -- /Hopefully/ enjoy, and =ssh= onto them in need be - -Ideally, the image we build is using the configuration, this means we should, in theory, -use =nixos-generate= targeting our /node/ configuration, and it should be the exact same thing -used for =morph=. - -Once the images are created, we need to copy them to the right host and from there, create -the virtual machine. Ideally, we do this automatically, command-line, … - - -* References -** [[https://nixos.wiki/wiki/Kubernetes][Kubernetes - NixOS Wiki]] -[2020-06-11 Thu 15:25] diff --git a/www/vincent.demeester.fr/content/legacy/articles/kubernix.org b/www/vincent.demeester.fr/content/legacy/articles/kubernix.org @@ -1,2 +0,0 @@ - -#+TITLE: kubernix diff --git a/www/vincent.demeester.fr/content/legacy/articles/leadership.org b/www/vincent.demeester.fr/content/legacy/articles/leadership.org @@ -1,2 +0,0 @@ - -#+TITLE: Leadership diff --git a/www/vincent.demeester.fr/content/legacy/articles/libvirt.org b/www/vincent.demeester.fr/content/legacy/articles/libvirt.org @@ -1,38 +0,0 @@ -#+TITLE: libvirt -#+FILETAGS: libvirt kvm qemu -#+SETUPFILE: .setup.org - -* Remote setup with NixOS -:PROPERTIES: -:CUSTOM_ID: h:348103fa-e9a6-49b0-a7f8-7b212d647940 -:END: - -Usually, you connect to =libvirt= using =qmeu:///system= or =qemu+ssh://…=. This works in -most case but sometimes you want to expose libvirt on tcp (with or without TLS). One such -example is for [[https://github.com/openshift/installer/][=openshift/installer=]]. - -#+begin_src nix - boot.kernel.sysctl = { "net.ipv4.ip_forward" = 1 ; }; - virtualisation.libvirtd = { - extraConfig = '' - listen_tls = 0 - listen_tcp = 1 - auth_tcp="none" - tcp_port = "16509" - ''; - extraOptions = [ "--listen" ] - }; - networking.firewall.allowedTCPPorts = [ 16509 ]; -#+end_src - -For =openshift= purpose we may want dns entry like =echo -server=/tt.testing/192.168.126.1 | sudo tee /etc/NetworkManager/dnsmasq.d/openshift.conf=. - -** Sources -:PROPERTIES: -:CUSTOM_ID: h:6b85c514-d810-4441-89f1-133158f17761 -:END: -- [[https://github.com/openshift/installer/blob/master/docs/dev/libvirt-howto.md][=openshift/installer= libvirt HOWTO]] -- [[https://libvirt.org/remote.html][libvirt: Remote support]] -- [[https://libvirt.org/auth.html][libvirt: Connection authentication]] -- [[https://libvirt.org/remote.html][libvirt: Remote support]] diff --git a/www/vincent.demeester.fr/content/legacy/articles/linux.org b/www/vincent.demeester.fr/content/legacy/articles/linux.org @@ -1,22 +0,0 @@ - -#+TITLE: Linux -#+ROAM_ALIAS: "linux" - -* Desktop - -** TODO [[https://matklad.github.io/2019/06/20/linux-desktop-tips.html][Linux Desktop Tips]] :tips:linux: -[2020-04-14 Tue 16:16] -** TODO [[https://soc.me/standards/defending-home][Standards: Defending $HOME]] :dotfiles:home:xdg: -[2020-04-06 Mon 12:04] - -** TODO [[https://prefet.ch/code/winvm-old/tree/winvm.sh][winvm.sh - winvm-old - Unmaintained script to start a Windows VM with GPU passthrough.]] -[2020-04-09 Thu 17:34] - -** TODO [[https://martinheinz.dev/blog/22][Saving Your Linux Machine from Certain Death]] :infra: -[2020-05-03 Sun 14:48] - -** TODO [[https://xn--gckvb8fzb.com/linux-on-the-desktop-part-one][マリウス . Linux on the Desktop: Part One]] -[2021-09-27 Mon 12:12] - -** TODO [[https://xn--gckvb8fzb.com/linux-on-the-desktop-part-two/][マリウス . Linux on the Desktop: Part Two]] -[2021-09-27 Mon 12:12] diff --git a/www/vincent.demeester.fr/content/legacy/articles/lisp.org b/www/vincent.demeester.fr/content/legacy/articles/lisp.org @@ -1,13 +0,0 @@ -#+TITLE: Lisp - -* Sub languages - -- Common Lisp -- [[file:emacs_lisp.org][Emacs Lisp]] -- [[file:clojure.org][Clojure]] - -* Links -** TODO [[https://joshbradley.me/understanding-the-power-of-lisp/][Understanding the Power of LISP]] :lisp: -[2020-04-09 Thu 17:35] -** TODO [[https://stopa.io/post/265][An Intuition for Lisp Syntax]] -[2020-10-26 Mon 10:56] diff --git a/www/vincent.demeester.fr/content/legacy/articles/mac.org b/www/vincent.demeester.fr/content/legacy/articles/mac.org @@ -1,5 +0,0 @@ -#+TITLE: Mac (OSX) - -* Links -** TODO [[http://karolis.koncevicius.lt/posts/cleaning_home_on_macos/][Cleaning home on macos]] -[2020-09-17 Thu 08:36] diff --git a/www/vincent.demeester.fr/content/legacy/articles/make.org b/www/vincent.demeester.fr/content/legacy/articles/make.org @@ -1,5 +0,0 @@ -#+TITLE: make - -* Links -** TODO [[https://endler.dev/2017/makefiles/][Afraid of Makefiles? Don't be! | Matthias Endler]] -[2020-08-20 Thu 16:30] diff --git a/www/vincent.demeester.fr/content/legacy/articles/meta_meta.org b/www/vincent.demeester.fr/content/legacy/articles/meta_meta.org @@ -1,2 +0,0 @@ -#+TITLE: Meta -#+ROAM_ALIAS: "meta" diff --git a/www/vincent.demeester.fr/content/legacy/articles/meta_publishing_this_website.org b/www/vincent.demeester.fr/content/legacy/articles/meta_publishing_this_website.org @@ -1,610 +0,0 @@ -#+TITLE: meta: publishing this website -#+ROAM_ALIAS: "publishing this website" - -This is a *always up-to-date* version of my initial [[https://vincent.demeester.fr/posts/2020-03-22-org-mode-website.html][post]] about publishing this website -using [[file:org_mode.org][org-mode]]. This uses the [[https://orgmode.org/manual/Extracting-Source-Code.html][tangle]] feature of =org-mode= and will span from the -=Makefile= of the [[https://git.sr.ht/~vdemeester/www][repository]] to any [[file:elisp.org][emacs-lisp]] code required. - -This is part of the [[file:meta_meta.org][Meta]] entry. - -#+TOC: headlines 3 - -* Parts of the website - -Let's look at the different part of the website and for each where I do get the -information I want to publish. - -- =/= :: this is just a file (=index.org=) that I maintain manually. -- =/posts= :: this is what we call /blog/ these days : short to medium article that are valid - at a point of time, as may contain /deprecated/ content, or content that do not reflect - my views at a later point in time. -- =/articles= :: medium to long article about a topic. Those should be up-to-date or - explicitly mark as deprecated or invalid. This is my *ready for the public* knowledge - database, a bit like [[https://braindump.jethro.dev/][Jethro's Braindump]]. It is managed using [[file:org_roam.org][org-roam]] and I just need to - get the latests somewhere to publish it. -- =/configurations= :: medium to long article about my configurations. Those are base - sources for my ~home~ /configuration/ mono-repository, and usually follow literate - programming principles. The are managed using [[file:org_roam.org][org-roam]] with the =config:= prefix. -- =/files= :: a dump of random files, it is actually on another domain name, completely - unmanaged by this. -- =/about= :: an about page about the author of the website (aka [[https://vincent.demeester.fr][me]]), linking external - contributions (GitHub/Gitlab/… profiles, Talks, …). - -In a nutshell, the folder hierarchy is something like : - -#+begin_src shell :tangle no -src/www -|-- about # the about folder (with one index.org) -|-- articles # <- comes from ~/desktop/org/notes~ -|-- css # the css -|-- images # the images -|-- index.org # the index 🎉 -|-- posts # the posts (format YYYY-MM-DD-{title}.org) -`-- public # the output that get deployed later on -#+end_src - -* Publishing - -** /Make/ it happen -:PROPERTIES: -:header-args: :tangle /etc/nixos/www/vincent.demeester.fr/Makefile -:header-args+: :comments org -:ID: 6191455e-95bc-4abc-a5f5-a62606ab2ea7 -:END: - -In order to publish this website, I am using [[file:make.org][make]]. In a nutshell, I am going to define a -few target to get the content from my notes, export org files into html and copy more or -less everything to the =public= folder. I will also define a clean and a publish target. - -The first part of my =Makefile= will be to define some constants that I want to use later -on. Those are mainly to easily change where to look for the notes or where the emacs -configuration is. - -#+begin_src makefile -EMACS = -ifndef EMACS -EMACS = "emacs" -endif - -DOTEMACS = -ifndef DOTEMACS -DOTEMACS = "~/.config/emacs" -endif - -PUBLISH = -ifndef PUBLISH -PUBLISH = vincent.demeester.fr -endif - -NOTES = ~/desktop/org/notes -#+end_src - -The default target will be name =build=. - -#+begin_src makefile -all: build -#+end_src - -*** Building =public/= and publishing it -:PROPERTIES: -:ID: 853f3d6b-f385-4091-9f9e-b04d17794e5c -:END: - -To build the website, we will be using [[file:emacs.org][Emacs]] in batch mode, with some shared library *and* -the actual [[id:631ced7a-f3f7-4a77-81a8-4a1884a6c4d4][publish]] script. - -#+begin_src makefile -.PHONY: build -build: publish.el publish-common.el build-articles - @echo "Publishing... with current Emacs configurations." - ${EMACS} --debug-init --batch --directory $(DOTEMACS)/lisp/ --directory $(DOTEMACS)/lisp/vorg/ \ - --load publish-common.el --load publish.el \ - --funcall org-publish-all - -.PHONY: build-articles -build-articles: $(NOTES) - rsync -arv --delete --copy-links --exclude='*.private.org' --exclude='*.db' $(NOTES)/ articles/ - -$(NOTES): - $(error $(NOTES) doesn't exists…) -#+end_src - -The =publish= target is gonna be really simple: I just need to copy the content to -=~/desktop/sites= on the current machine, and the rest is automated. - -#+begin_src makefile -#rsync -a --progress --copy-links --delete public/assets/.fancyindex/ ~/desktop/sites/dl.sbr.pm/.fancyindex/ -#rsync -a --progress --copy-links --delete public/ ~/desktop/sites/${PUBLISH}/ -.PHONY: publish -publish: build - rsync -ave ssh --progress --copy-links --delete public/assets/.fancyindex/ kerkouane.vpn:/var/www/dl.sbr.pm/.fancyindex/ - rsync -ave ssh --progress --copy-links --delete public/ kerkouane.vpn:/var/www/${PUBLISH}/ -#+end_src - -*** Local server -:PROPERTIES: -:ID: 0e26a52e-5f66-42c6-934d-b45cfc9745b2 -:END: - -Let's use =miniserve= (using [[file:nix.org][Nix]] with =nix-shell=) to serve the static website locally to -validate my changes. - -#+begin_src makefile -.PHONY: serve -serve: - nix-shell -p miniserve --command "miniserve --port=8181 --index=index.html public/" -#+end_src - -*** Final nits of the =Makefile= -:PROPERTIES: -:ID: 5bec22c8-491b-4e03-855a-4b5f859473cf -:END: - -One of the final step is to install the git hooks if any. I tend to have this target in all my -personal =Makefile= at least. Let's also define a =pre-commit= target that will hold -anything we need to do at =pre-commit=. - -#+begin_src makefile -.PHONY: install-hooks -install-hooks: - if [ -e .git ]; then nix-shell -p git --run 'git config core.hooksPath .githooks'; fi - -.PHONY: pre-commit -pre-commit: README.md -#+end_src - -And the final target is the =clean= one. This will remove any compile emacs-lisp file -(=*.elc=), the =public= folder, and some org-mode metadata. - -#+begin_src makefile -.PHONY: clean -clean: - @echo "Cleaning up.." - @-rm -rvf *.elc - @-rm -rvf public - @-rm -rv ~/.org-timestamps/* -#+end_src - -** The /publish/ scrits -:PROPERTIES: -:ID: 631ced7a-f3f7-4a77-81a8-4a1884a6c4d4 -:END: - -I've imported the script directly in here, I'll slowly split this and document it. - -*** =publish.el= -:PROPERTIES: -:header-args: :tangle /etc/nixos/www/vincent.demeester.fr/publish.el -:ID: bef868db-17f0-4a67-9c64-6dcf64ad6de1 -:END: - -#+begin_src emacs-lisp -;;; publish.el --- Publish www project -*- lexical-binding: t; -*- -;; Author: Vincent Demeester <vincent@sbr.pm> - -;;; Commentary: -;; This script will convert the org-mode files in this directory into -;; html. - -;;; Code: -(require 'package) -(require 'publish-common) - -(setq org-publish-project-alist - `(("posts" - :base-directory "posts" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/posts" - :exclude ,(regexp-opt '("README.org" "draft")) - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "index.org" - :sitemap-title "Posts" - :sitemap-format-entry sbr/org-sitemap-format-entry - :sitemap-style list - :sitemap-sort-files anti-chronologically - :sitemap-function sbr/org-publish-sitemap - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("posts-rss" - :base-directory "posts" - :base-extension "org" - :recursive t - :html-link-home "https://vincent.demeester.fr/" - :rss-link-home "https://vincent.demeester.fr/posts/" - :html-link-use-abs-url t - :rss-extension "xml" - :publishing-directory "./public" - :publishing-function (sbr/org-rss-publish-to-rss) - :section-number nil - :exclude ".*" - :include ("index.org")) - ("articles" - :base-directory "articles" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/articles" - :exclude ,(regexp-opt '("README.org" "draft")) - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "sitemap.org" - :sitemap-title "Articles" - :sitemap-style tree - :sitemap-sort-files anti-chronologically - ;;:sitemap-format-entry sbr/org-sitemap-format-entry - ;;:sitemap-function sbr/org-publish-sitemap - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("articles-assets" - :exclude ,(regexp-opt '("*.org")) - :base-directory "articles" - :base-extension ,site-attachments - :publishing-directory "./public/articles" - :publishing-function org-publish-attachment - :recursive t) - ("about" - :base-directory "about" - :base-extension "org" - :exclude ,(regexp-opt '("README.org" "draft")) - :index-filename "index.org" - :recursive nil - :with-footnotes t - :with-toc nil - :with-drawers t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/about" - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("index" - :base-directory "" - :base-extension "org" - :exclude ,(regexp-opt '("README.org" "draft")) - :index-filename "index.org" - :recursive nil - :with-footnotes t - :with-toc nil - :with-drawers t - :with-title nil - :publishing-function org-html-publish-to-html - :publishing-directory "./public" - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("css" - :base-directory "./css" - :base-extension ,site-attachments - :recursive t - :publishing-directory "./public/css" - :publishing-function org-publish-attachment - :recursive t) - ("images" - :base-directory "./images" - :base-extension ,site-attachments - :publishing-directory "./public/images" - :publishing-function org-publish-attachment - :recursive t) - ("assets" - :base-directory "./assets" - :base-extension ,site-attachments - :publishing-directory "./public/assets" - :publishing-function org-publish-attachment - :recursive t) - ("legacy" - :base-directory "./legacy" - :base-extension ,site-attachments - :publishing-directory "./public/" - :publishing-function org-publish-attachment - :recursive t) - ("all" :components ("posts" "about" "index" "articles" "articles-assets" "css" "images" "assets" "legacy" "posts-rss")))) - -(provide 'publish) -;;; publish.el ends here -#+end_src - -*** =publish-common.el= -:PROPERTIES: -:header-args: :tangle /etc/nixos/www/vincent.demeester.fr/publish-common.el -:ID: bcedf3bd-49ec-4602-b916-daea6695af1e -:END: - -#+begin_src emacs-lisp -;;; publish-common.el --- Commons code for www publishing projects -*- lexical-binding: t; -*- -;; Author: Vincent Demeester <vincent@sbr.pm> - -;;; Commentary: -;; -;;; Code: -;; load org -(require 'org) -(require 'dash) -;; load org export functions -(require 'ox-publish) -(require 'ox-rss) -(require 'ox-html) -;; load org link functions -(require 'ol-man) -(require 'ol-git-link) -;; Those are mine -(require 'ol-github) -(require 'ol-gitlab) -(require 'org-attach) -;; load additional libraries -(require 'go-mode) -(require 'css-mode) -(require 'yaml-mode) -(require 'nix-mode) - -(require 's) - -(setq org-export-use-babel nil) -(setq org-link-abbrev-alist '(("att" . org-attach-expand-link))) - -;; setting to nil, avoids "Author: x" at the bottom -(setq org-export-with-section-numbers nil - org-export-with-smart-quotes t - org-export-with-toc nil) - -(defvar sbr-date-format "%b %d, %Y") - -(setq org-html-divs '((preamble "header" "top") - (content "main" "content") - (postamble "footer" "postamble")) - org-html-container-element "section" - org-html-metadata-timestamp-format sbr-date-format - org-html-checkbox-type 'unicode - org-html-html5-fancy t - org-html-doctype "html5" - org-html-htmlize-output-type 'css - org-html-htmlize-font-prefix "org-" - org-src-fontify-natively t - org-html-coding-system 'utf-8-unix) - -(defun sbr/org-export-format-drawer (name content) - "HTML export of drawer with NAME and CONTENT. -name is the name of the drawer, that will be used as class. -content is the content of the drawer" - (format "<div class='drawer %s'>\n<h6>%s</h6>\n%s</div>" - (downcase name) - (capitalize name) - content)) -(setq org-html-format-drawer-function 'sbr/org-export-format-drawer) - -(defun read-file (filePath) - "Return FILEPATH's file content." - (with-temp-buffer - (insert-file-contents filePath) - (buffer-string))) - -(defvar sbr-website-html-head - "<link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> -<meta name='viewport' content='width=device-width, initial-scale=1'> -<link rel='stylesheet' href='/css/new.css' type='text/css'/> -<link rel='stylesheet' href='/css/syntax.css' type='text/css'/> -<link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' />") - -(defun sbr-website-html-preamble (plist) - "PLIST: An entry." - ;; Skip adding subtitle to the post if :KEYWORDS don't have 'post' has a - ;; keyword - (when (string-match-p "post" (format "%s" (plist-get plist :keywords))) - (plist-put plist - :subtitle (format "Published on %s by %s." - (org-export-get-date plist sbr-date-format) - (car (plist-get plist :author))))) - - ;; Below content will be added anyways - "<nav> -<img src=\"/images/favicon.ico\" id=\"sitelogo\"/> <a href='/'>home</a> / -<a href='/posts/'>posts</a> (<a href='/index.xml'>rss</a>) / -<a href='/articles/'>articles</a> / -<a href='https://dl.sbr.pm/'>files</a> / -<a href='/about/'>about</a></li> -</nav>") - -(defvar sbr-website-html-postamble - "<footer> - <span class='questions'>Questions, comments ? Please use my <a href=\"https://lists.sr.ht/~vdemeester/public-inbox\">public inbox</a> by sending a plain-text email to <a href=\"mailto:~vdemeester/public-inbox@lists.sr.ht\">~vdemeester/public-inbox@lists.sr.ht</a>.</span> - <span class='opinions'>Opinions stated here are my own and do not express the views of my employer, spouse, children, pets, neighbors, secret crushes, favorite authors, or anyone else who is not me. And maybe not even me, depending on how old this is.</span> - <span class='copyright'> - Content and design by Vincent Demeester - (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) - </span><br /> - <span class='engine'> - Powered by <a href='https://www.gnu.org/software/emacs/'>Gnu Emacs</a> and <a href='https://orgmode.org'>orgmode</a> - </span> -</footer>") -(defvar site-attachments - (regexp-opt '("jpg" "jpeg" "gif" "png" "svg" - "ico" "cur" "css" "js" "woff" "html" "pdf" "otf")) - "File types that are published as static files.") - -(defun sbr/org-sitemap-format-entry (entry style project) - "Format posts with author and published data in the index page. - -ENTRY: file-name -STYLE: -PROJECT: `posts in this case." - (cond ((not (directory-name-p entry)) - (format "%s — [[file:%s][%s]] - :PROPERTIES: - :PUBDATE: [%s] - :END:" - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)) - entry - (org-publish-find-title entry project) - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)))) - ((eq style 'tree) (file-name-nondirectory (directory-file-name entry))) - (t entry))) - -(defun sbr/org-publish-sitemap (title list) - "" - (concat "#+TITLE: " title "\n\n" - (org-list-to-subtree list))) - -(defun sbr/org-get-first-paragraph (file) - "Get string content of first paragraph of file." - (ignore-errors - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (show-all) - (let ((first-begin (progn - (org-forward-heading-same-level 1) - (next-line) - (point))) - (first-end (progn - (org-next-visible-heading 1) - (point)))) - (buffer-substring first-begin first-end))))) - -(defun sbr/org-rss-publish-to-rss (plist filename pub-dir) - "Prepare rss.org file before exporting." - (let* ((postsdir (plist-get plist :base-directory))) - (with-current-buffer (find-file filename) - (erase-buffer) - (insert "#+TITLE: Posts\n") - (insert "#+AUTHOR: Vincent Demeester\n") - (insert "#+OPTIONS: toc:nil\n") - (let* ((files-all - (reverse (directory-files "." nil - "[0-9-]+.*\\.org$"))) - (files (seq-subseq files-all 0 (min (length files-all) 30)))) - (message (format "foo: %s" filename)) - (dolist (post files) - (let* ((post-file post) - (post-title (org-publish-find-title post-file plist)) - (preview-str (sbr/org-get-first-paragraph post-file)) - (date (replace-regexp-in-string - "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)-.*" - "\\1" post))) - (insert (concat "* [[file:" postsdir "/" post "][" post-title "]]\n\n")) - (org-set-property "ID" post) - (org-set-property "RSS_TITLE" post-title) - ;; ox-rss prepends html-link-home to permalink - (org-set-property "RSS_PERMALINK" - (concat postsdir "/" - (file-name-sans-extension post) - ".html")) - (org-set-property - "PUBDATE" - (format-time-string - "<%Y-%m-%d %a %H:%M>" - (org-time-string-to-time - (replace-regexp-in-string - "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)-.*" - "\\1" post)))) - (insert preview-str) - (newline 1) - (insert (concat "[[file:" postsdir "/" post "][(Read more)]]\n\n")))) - (save-buffer)))) - (let ((user-mail-address "t") - (org-export-with-broken-links t) - (org-rss-use-entry-url-as-guid nil)) - (org-rss-publish-to-rss plist filename pub-dir))) - -(advice-add #'org-export-get-reference :override #'unpackaged/org-export-get-reference) - -(defun unpackaged/org-export-get-reference (datum info) - "Like `org-export-get-reference', except uses heading titles instead of random numbers." - (let ((cache (plist-get info :internal-references))) - (or (car (rassq datum cache)) - (let* ((crossrefs (plist-get info :crossrefs)) - (cells (org-export-search-cells datum)) - ;; Preserve any pre-existing association between - ;; a search cell and a reference, i.e., when some - ;; previously published document referenced a location - ;; within current file (see - ;; `org-publish-resolve-external-link'). - ;; - ;; However, there is no guarantee that search cells are - ;; unique, e.g., there might be duplicate custom ID or - ;; two headings with the same title in the file. - ;; - ;; As a consequence, before re-using any reference to - ;; an element or object, we check that it doesn't refer - ;; to a previous element or object. - (new (or (cl-some - (lambda (cell) - (let ((stored (cdr (assoc cell crossrefs)))) - (when stored - (let ((old (org-export-format-reference stored))) - (and (not (assoc old cache)) stored))))) - cells) - (when (org-element-property :raw-value datum) - ;; Heading with a title - (unpackaged/org-export-new-title-reference datum cache)) - ;; NOTE: This probably breaks some Org Export - ;; feature, but if it does what I need, fine. - (org-export-format-reference - (org-export-new-reference cache)))) - (reference-string new)) - ;; Cache contains both data already associated to - ;; a reference and in-use internal references, so as to make - ;; unique references. - (dolist (cell cells) (push (cons cell new) cache)) - ;; Retain a direct association between reference string and - ;; DATUM since (1) not every object or element can be given - ;; a search cell (2) it permits quick lookup. - (push (cons reference-string datum) cache) - (plist-put info :internal-references cache) - reference-string)))) - -(defun unpackaged/org-export-new-title-reference (datum cache) - "Return new reference for DATUM that is unique in CACHE." - (cl-macrolet ((inc-suffixf (place) - `(progn - (string-match (rx bos - (minimal-match (group (1+ anything))) - (optional "--" (group (1+ digit))) - eos) - ,place) - ;; HACK: `s1' instead of a gensym. - (-let* (((s1 suffix) (list (match-string 1 ,place) - (match-string 2 ,place))) - (suffix (if suffix - (string-to-number suffix) - 0))) - (setf ,place (format "%s--%s" s1 (cl-incf suffix))))))) - (let* ((title (org-element-property :raw-value datum)) - (ref (url-hexify-string (substring-no-properties title))) - (parent (org-element-property :parent datum))) - (while (--any (equal ref (car it)) - cache) - ;; Title not unique: make it so. - (if parent - ;; Append ancestor title. - (setf title (concat (org-element-property :raw-value parent) - "--" title) - ref (url-hexify-string (substring-no-properties title)) - parent (org-element-property :parent parent)) - ;; No more ancestors: add and increment a number. - (inc-suffixf ref))) - ref))) - -(provide 'publish-common) -;;; publish-common.el ends here -#+end_src - -#+begin_src bash -# -*- mode: org; eval: (add-hook 'after-save-hook (lambda () (org-babel-tangle)) nil t) -*- -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/minikube.org b/www/vincent.demeester.fr/content/legacy/articles/minikube.org @@ -1,57 +0,0 @@ - -#+TITLE: minikube -#+ROAM_ALIAS: "Minikube" - -* Alternative container runtimes -:PROPERTIES: -:CUSTOM_ID: h:ac96a1df-968e-4cac-b8fe-60b7bf747917 -:END: -#+BEGIN_SRC sh -minikube start \ - --network-plugin=cni \ - --container-runtime=containerd \ - --bootstrapper=kubeadm -# or … -minikube start \ - --network-plugin=cni \ - --extra-config=kubelet.container-runtime=remote \ - --extra-config=kubelet.container-runtime-endpoint=unix:///run/containerd/containerd.sock \ - --extra-config=kubelet.image-service-endpoint=unix:///run/containerd/containerd.sock \ - --bootstrapper=kubeadm -#+END_SRC - -#+BEGIN_SRC sh -minikube start \ - --network-plugin=cni \ - --container-runtime=cri-o \ - --bootstrapper=kubeadm -# or … -minikube start \ - --network-plugin=cni \ - --extra-config=kubelet.container-runtime=remote \ - --extra-config=kubelet.container-runtime-endpoint=/var/run/crio.sock \ - --extra-config=kubelet.image-service-endpoint=/var/run/crio.sock \ - --bootstrapper=kubeadm -#+END_SRC - -* Cache some images -:PROPERTIES: -:CUSTOM_ID: h:84b224cb-6da0-48b3-a4f7-ea3cfd0d62ec -:END: - -Depending on your workflow with =minikube=, you may re-create a VM from time to time (or -quite a lot). In this case, you may want to speed the process up a bit. - -First, you need a recent =minikube= version, a.k.a. =v0.29.0= at least — adding image to -cache with =v0.28.1= is bugged and doesn't work. - -Then, it's pretty simple and it works even if a minikube VM doesn't work — in that case -images will be loaded when doing a =minikube start=. - -#+BEGIN_SRC sh - minikube cache add docker.io/library/ubuntu:18.04 - # […] - minikube cache add docker.io/prom/statsd-export:v0.6.0 -#+END_SRC - -There is some shortcomings still, as _for now_, it's not possible to download digest image. diff --git a/www/vincent.demeester.fr/content/legacy/articles/moby_project.org b/www/vincent.demeester.fr/content/legacy/articles/moby_project.org @@ -1,3 +0,0 @@ - -#+TITLE: Moby Project -#+ROAM_ALIAS: "Moby" "moby" diff --git a/www/vincent.demeester.fr/content/legacy/articles/my_organizational_workflow.org b/www/vincent.demeester.fr/content/legacy/articles/my_organizational_workflow.org @@ -1,1120 +0,0 @@ -#+TITLE: My Organizational Workflow -#+SUBTITLE: How I use org-mode and other tools to streamline my life -#+ROAM_ALIAS: "getting org done" "config: getting org done" - -This is an up-to-date document on my [[file:org_mode.org][org-mode]] workflow. This is inspired by "[[http://cachestocaches.com/2020/3/my-organized-life/][A Guide to My -Organizational Workflow: How to Streamline Your Life]]" and other articles like [[http://www.howardism.org/Technical/Emacs/getting-boxes-done.html][Getting -Boxes Done]], [[http://www.howardism.org/Technical/Emacs/getting-more-boxes-done.html][Getting Boxes Done, the Code]], [[http://www.howardism.org/Technical/Emacs/getting-even-more-boxes-done.html][Refiling Trees to Files]]. In a gist this is about -how I take notes and how I keep track on what I work on and what I need to work on. - -This is part of [[file:emacs.org][My Emacs System]]. - -#+TOC: headlines 2 - -* Introduction - -I am not sure exactly when, but overtime, my life grew in complexity, and I decide along -the way to use [[file:org_mode.org][org-mode]] to help me with that. Even though [[file:org_mode.org][org-mode]] could be considered as -an implementation detail of my workflow, it's really hard to separate from it. I'll try my -best to describe the workflow without mentionning [[file:org_mode.org][org-mode]] and from there, we'll see how -my setup does it. - -Many of the ideas presented here derive from the [[https://gettingthingsdone.com/what-is-gtd/][Getting Things Done]] methodology, but -adapted and expanded to meet my personal needs. With that workflow, I am trying to spint -my time more wisely and focus on what's important to me. This is not a silver bullet -though, and is an always in progress work. -* Goals - -I really liked the goal list from "[[http://cachestocaches.com/2020/3/my-organized-life/][A Guide to My -Organizational Workflow: How to Streamline Your Life]]", so I kinda took *heavy* inspiration -from it. - -In order to determine how effective an organizational system is, it is important to have -clearly enumerated aims: what is the system being designed to enable? Your goals may be -different, but my system is structured to prioritize the following: - -- Ensure that I never miss a task, /meeting/, or deadline (/note: the meeting part is - tricky/); -- Manage tasks that I need to work on; -- Manage tasks that I share with and have assigned to others (/when I depend on it/); -- Keep a permanent record of my work and research, and in a way that can be easily shared - with others if necessary; -- Collect my thoughts, writings, and half-baked ideas; -- Ensure that my local progress—on a daily or monthly basis—is in service of my long-term - goals (this is kinda hard to do); -- Finally: ensure I enjoy my life and make time for fun and friends! My system is meant to - organize, not confine. - -#+begin_quote -One key idea to keep in mind as well is that an organizational system should be -flexible. Life is complicated and unexpected items—both good and bad—can appear at a -moment's notice. While it may not be immediately clear where a new task or project -belongs, one should always have the ability to add new files or lists to which the new -items can be added. Additionally, I do occasionally discover a file or project will -outgrow the way I decided to structure it at its inception. My tools support fast and easy -refactoring when necessary so that I can restructure a project to reflect my updated -understanding of the problems it was intended to solve. The greater the effort required to -reorganize when necessary, the less frequently it will happen and the effectiveness of the -organizational system will decline. The tools I will describe later on work well for me, -but you should find those tools that work best for you. -#+end_quote - -The above is the reason why I am using [[file:org_mode.org][org-mode]] : it's plain text, it's flexible — you can -add data (properties, tags, …), you can define your behavior (using =emacs-lisp= code). -* My workflow - -As described earlier, my workflow is loosely based on some concept from the [[https://gettingthingsdone.com/what-is-gtd/][Getting Things -Done]] methodology, but adapted and expanded to meet my personal needs. One of the core -principles of the /Getting Things Done/ methodology, is that "the mind is for thinking, -not remembering". Everything that may need to be accomplished—or that you might someday -want to accomplish—should be written down. - -I also really like the /boxes/ comparison from [[http://www.howardism.org/Technical/Emacs/getting-boxes-done.html][Getting Boxes Done]]. - -#+begin_quote -On my workbench is a box. Actually, a few boxes. Each uncompleted project goes into a box… -no lost screws. Sure unpacking and packing between each session is a hassle, but since the -best projects take a few weekends, boxes are required. - -Non-workbench-oriented projects go into mental boxes, and I’m thinking of my self -organization in terms of boxes. Thoughts don’t go into physical boxes, but in my world, -they live in text files. […] -#+end_quote - -My usual workflow for solving a problem involves breaking up a high-level objective into -increasingly smaller goals until I can make progress towards accomplishing it. [[file:org_mode.org][org-mode]] -allows me to collect my tasks and projects when needed and build the lists. As I work, I -log my progress, my thoughts, where I get stuck, temporary images or figures, intermediate -results, how to reproduce my work, and so on. Note taking is a critical part of my -thinking process, so notes and their parent tasks should coexist. - -If we talk in files now, this looks like the following: - -- archive :: this is where I archive my project and notes if they don't make sense - anymore. -- notes :: this is my /notes boxes/, where I keep my journal entry (monthly files), - private and public notes (the one published [[https://vincent.demeester.fr/articles/][here]]). -- projects :: this is my /project boxes/, where I keep a set of files containing tasks I - need to do for specific projects (related to my work, or personal). Each file represent - a project and should be /archived/ at some point, except a bunch of special ones - (=inbox=, =incubate=, =next=, …) - + =inbox= is where I capture ideas, task and links that I need to review later. - + =incubate= is where ideas (captured previously in inbox) are going while /waiting/ for - being picked up. - + =next= is where I put small task that can be quickly done, like a doing a quick - backup, etc. My /wish/ is to have the least amount of tasks in =next=. -* Implementation - -** Constants and registers -:PROPERTIES: -:header-args: :noweb-ref constants-and-registers :tangle no -:END: - -Let's dig into the files and folders I'll use across the rest of my configuration. - -#+begin_src emacs-lisp -(defconst org-directory "~/desktop/org/" - "org-mode directory, where most of the org-mode file lives") -(defconst org-projects-dir (expand-file-name "projects" org-directory) - "Primary tasks directory.") -(defconst org-notes-dir (expand-file-name "notes" org-directory) - "Directory of shareable, technical notes.") -(defconst org-archive-dir (expand-file-name "archive" org-directory) - "Directory of shareable, technical notes.") -(defconst org-completed-dir (expand-file-name "projects" org-archive-dir) - "Directory of completed project files.") -(defconst org-inbox-file (expand-file-name "inbox.org" org-projects-dir) - "New stuff collected in this file.") -(defconst org-next-file (expand-file-name "next.org" org-projects-dir) - "Todo *next* collected in this file.") -(defconst org-incubate-file (expand-file-name "incubate.org" org-projects-dir) - "Ideas simmering on back burner.") -(defconst org-babel-library-file (expand-file-name "org_library_of_babel.org" org-notes-dir) - "Org babel library.") -#+end_src - -I'm also using [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html][registers]] to quickly access some files, mainly the =inbox= file, the -=incubate= file and the =next= file. - -#+begin_src emacs-lisp -(set-register ?i `(file . ,org-inbox-file)) -(set-register ?I `(file . ,org-incubate-file)) -(set-register ?n `(file . ,org-next-file)) -#+end_src - -** TODO Main configuration - -#+name: main -#+begin_src emacs-lisp -(use-package org - :ensure org-plus-contrib ;; load from the package instead of internal - :mode (("\\.org$" . org-mode) - ("\\.org.draft$" . org-mode)) - :commands (org-agenda org-capture) - :bind (("C-c o l" . org-store-link) - ("C-c o r r" . org-refile) - ("C-c o a a" . org-agenda) - ("C-c o a r" . my/reload-org-agenda-files) - ("C-c o s" . org-sort) - ("<f12>" . org-agenda) - ("C-c o c" . org-capture) - ;; Skeletons - ("C-c o i p" . vde/org-project) - ("C-c o i n" . vde/org-www-post)) - :config - (define-skeleton vde/org-project - "new org-mode project" - nil - > "#+TITLE: " (skeleton-read "Title: ") \n - > "#+FILETAGS: " (skeleton-read "Tags: ") \n - > _ \n - > "#+BEGIN: clocktable :scope file :maxlevel 2 :emphasize nil :link t" \n - > "#+END:" \n - > _ \n) - (define-skeleton vde/org-www-post - "new www post" - nil - > "#+title: " (skeleton-read "Title: ") \n - > "#+date: " (format-time-string "<%Y-%M-%d %a>") \n - > "#+filetags: " (skeleton-read "Tags: ") \n - > "#+setupfile: ../templates/post.org" \n - > _ \n - > "* Introduction" - ) - ;; Org Babel configurations - (when (file-exists-p org-babel-library-file) - (org-babel-lob-ingest org-babel-library-file)) - (defun my/org-agenda-files () - `(,org-projects-dir - "~/src/home/tasks.org" - "~/src/www/tasks.org")) - (defun my/reload-org-agenda-files () - (interactive) - (setq org-agenda-files (my/org-agenda-files))) - (setq org-agenda-files (my/org-agenda-files) - org-agenda-file-regexp "^[a-zA-Z0-9-_]+.org$" - org-use-speed-commands t - org-special-ctrl-a/e t - org-special-ctrl-k t - org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "STARTED(s)" "|" "DONE(d!)" "CANCELED(c@/!)") - (sequence "WAITING(w@/!)" "SOMEDAY(s)" "|" "CANCELED(c@/!)") - (sequence "IDEA(i)" "|" "CANCELED(c@/!)")) - org-todo-state-tags-triggers '(("CANCELLED" ("CANCELLED" . t)) - ("WAITING" ("WAITING" . t)) - (done ("WAITING")) - ("TODO" ("WAITING") ("CANCELLED")) - ("NEXT" ("WAITING") ("CANCELLED")) - ("DONE" ("WAITING") ("CANCELLED"))) - org-use-tag-inheritance t - org-tag-alist '(("linux") ("nixos") ("emacs") ("org") - ("openshift") ("redhat") ("tektoncd") ("kubernetes") ("knative" ) ("docker") - ("docs") ("code") ("review") - (:startgroup . nil) - ("#home" . ?h) ("#work" . ?w) ("#errand" . ?e) ("#health" . ?l) - (:endgroup . nil) - (:startgroup . nil) - ("#link" . ?i) ("#read" . ?r) ("#project" . ?p) - (:endgroup . nil)) - org-log-done 'time - org-log-redeadline 'time - org-log-reschedule 'time - org-log-into-drawer t - org-enforce-todo-dependencies t - org-refile-targets (append '((org-inbox-file :level . 0)) - (->> - (directory-files org-projects-dir nil ".org") - (--remove (s-starts-with? "." it)) - (--map (format "%s/%s" org-projects-dir it)) - (--map `(,it :level . 1)))) - org-refile-use-outline-path 'file - org-refile-allow-creating-parent-nodes 'confirm - org-outline-path-complete-in-steps nil - org-columns-default-format "%80ITEM(Task) %TODO %3PRIORITY %10Effort(Effort){:} %10CLOCKSUM" - org-fontify-whole-heading-line t - org-pretty-entities t - org-ellipsis " ⤵" - org-archive-location (concat org-completed-dir "/%s::datetree/") - org-use-property-inheritance t - org-priority 67 - org-priority-faces '((?A . "#ff2600") - (?B . "#ff5900") - (?C . "#ff9200") - (?D . "#747474")) - org-global-properties (quote (("EFFORT_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00") - ("STYLE_ALL" . "habit"))) - org-blank-before-new-entry '((heading . t) - (plain-list-item . nil)) - org-insert-heading-respect-content t - org-yank-adjusted-subtrees t - org-image-actual-width nil - org-startup-with-inline-images nil - org-list-demote-modify-bullet '(("+" . "-") ("-" . "+")) - org-catch-invisible-edits 'error - ;; Put theses into a minor mode - org-indent-indentation-per-level 1 - org-cycle-separator-lines 1 - org-adapt-indentation nil - org-hide-leading-stars t - org-hide-emphasis-markers t) - (setcar (nthcdr 4 org-emphasis-regexp-components) 10) - :hook (org-mode . vde/org-mode-hook)) - -(defun vde/org-mode-hook () - "Org-mode hook" - (setq show-trailing-whitespace t) - (when (not (eq major-mode 'org-agenda-mode)) - (setq fill-column 90) - (auto-revert-mode) - (auto-fill-mode) - (org-indent-mode) - (set (make-local-variable 'company-backends) - '(company-emoji company-capf company-files company-dabbrev)) - (company-mode 1) - (add-hook 'before-save-hook #'save-and-update-includes nil 'make-it-local))) -#+end_src - -** TODO Agenda -:PROPERTIES: -:header-args: :noweb-ref agenda :tangle no -:END: - -#+begin_src emacs-lisp -(use-package org-agenda - :after org - :commands (org-agenda) - :bind (("C-c o a a" . org-agenda) - ("<f12>" . org-agenda) - ("C-c o r a" . org-agenda-refile)) - :config - (use-package org-super-agenda - :config (org-super-agenda-mode)) - (setq org-agenda-span 'day - org-agenda-start-on-weekday 1 - org-agenda-include-diary t - org-agenda-window-setup 'current-window - org-agenda-skip-scheduled-if-done nil - org-agenda-compact-blocks t - org-agenda-sticky t - org-super-agenda-header-separator "" - org-agenda-custom-commands - `(("w" "Agenda" - ((agenda "") - (tags-todo "-goals-incubate-inbox+TODO=\"STARTED\"" - ((org-agenda-overriding-header "Ongoing"))) - (tags-todo "-goals-incubate-inbox+TODO=\"NEXT\"" - ((org-agenda-overriding-header "Next")))) - ((org-super-agenda-groups - '((:name "Important" :priority "A") - (:name "Scheduled" :time-grid t) - (:habit t)))) - (org-agenda-list))))) -#+end_src - -#+begin_src emacs-lisp -(use-package org-gcal - :after (org) - :commands (org-gcal-fetch) - :config - (require 'netrc) - (setq-default org-gcal-remove-cancelled-events t) - (defun get-authinfo (host port) - (let* ((netrc (netrc-parse (expand-file-name "~/.authinfo.gpg"))) - (hostentry (netrc-machine netrc host port port))) - (when hostentry (netrc-get hostentry "password")))) - - (setq org-gcal-client-id "959564825992-kvc7ofe9640cpc8ibgjqqgpi15e89nkn.apps.googleusercontent.com" - org-gcal-client-secret (get-authinfo "gcal.api" "9999") - org-gcal-file-alist '(("vdemeest@redhat.com" . "~/desktop/org/projects/schedule.org")))) -#+end_src - -** TODO Habits - -#+name: habits -#+begin_src emacs-lisp -(use-package org-habit - :after (org) - :config - (setq org-habit-show-habits-only-for-today nil - org-habit-graph-column 80)) -#+end_src - -** TODO Capture - -#+name: capture -#+begin_src emacs-lisp -(use-package org-capture - :after org - :commands (org-capture) - :config - - (add-to-list 'org-capture-templates - `("l" "Link" entry - (file ,org-inbox-file) - "* %a\n%U\n%?\n%i" - :empty-lines 1)) - - (add-to-list 'org-capture-templates - `("t" "Tasks")) - (add-to-list 'org-capture-templates - `("tt" "New task" entry - (file ,org-inbox-file) - "* %?\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n\nFrom: %a" - :empty-lines 1)) - (add-to-list 'org-capture-templates - `("tr" "PR Review" entry - (file ,org-inbox-file) - "* TODO review gh:%^{issue} :review:\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n%?\nFrom: %a" - :empty-lines 1)) - - ;; (add-to-list 'org-capture-templates - ;; `("m" "Meeting notes" entry - ;; (file+datetree ,org-meeting-notes-file) - ;; (file ,(concat user-emacs-directory "/etc/orgmode/meeting-notes.org")))) - - (add-to-list 'org-capture-templates - `("w" "Writing")) - :bind (("C-c o c" . org-capture))) - - -(use-package org-capture-pop-frame - :after org) -#+end_src - -*** TODO Templates -:PROPERTIES: -:ID: 063de768-f5df-4216-9239-201406441bae -:END: - -#+begin_src org :tangle ~/src/home/tools/emacs/etc/orgmode/meeting-notes.org -,* %^{meeting} - -- Actions :: - ,#+BEGIN: columnview :id local :match "/TODO|DONE" :format "%ITEM(What) %TAGS(Who) %DEADLINE(When) %TODO(State)" - | What | Who | When | State | - |-------------------------------------+------------+------+-------| - ,#+END: -- Decisions :: - ,#+BEGIN: columnview :id local :match "Decision" :format "%ITEM(Decisions)" - | Decisions | - |-----------| - ,#+END: - -,** Present at meeting - - [ ] -,** Agenda -- %? -,** Notes -- Use =:Decision:= tag for decision -- Use entry with =TODO= (or =DONE=) for actions -#+end_src - -#+begin_src org :tangle ~/src/home/tools/emacs/etc/orgmode/weekly.org -,** %(format-time-string org-journal-time-format) weekly review :weekly:review: -%U - -- [ ] review [[file:../projects/inbox.org][~inbox.org~]] - Clean the file by either - - refiling it to ~incubate.org~ - - removing it / archiving it -- [ ] review [[file:../projects/incubate.org][~incubate.org~]] - - Is something worth becoming a project - - Is something not worth thinking about anymore ? -- [ ] empty mail inbox (and create task if needed) - - [ ] work - - [ ] perso -- [ ] Review next week ~F12 n w f~ -- [ ] review ~org-mode~ workflow - - *what works, what doesn't ?* - - *is there task / stuck projects ?* - - *enhancement possible ?* -- [ ] export previous agenda (somewhere) -#+end_src - -*** TODO Protocol - -#+name: protocol -#+begin_src emacs-lisp -(use-package org-protocol - :after org) -#+end_src - -** TODO Clocking - -#+name: clock -#+begin_src emacs-lisp -(use-package org-clock - :after org - :commands (org-clock-in org-clock-out org-clock-goto) - :config - ;; Setup hooks for clock persistance - (org-clock-persistence-insinuate) - (setq org-clock-clocked-in-display nil - ;; Show lot of clocking history so it's easy to pick items off the C-F11 list - org-clock-history-length 23 - ;; Change tasks to STARTED when clocking in - org-clock-in-switch-to-state 'vde/clock-in-to-started - ;; Clock out when moving task to a done state - org-clock-out-when-done t - ;; Save the running clock and all clock history when exiting Emacs, load it on startup - org-clock-persist t) - (use-package find-lisp) - (defun vde/is-project-p () - "Any task with a todo keyword subtask" - (save-restriction - (widen) - (let ((has-subtask) - (subtree-end (save-excursion (org-end-of-subtree t))) - (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) - (save-excursion - (forward-line 1) - (while (and (not has-subtask) - (< (point) subtree-end) - (re-search-forward "^\*+ " subtree-end t)) - (when (member (org-get-todo-state) org-todo-keywords-1) - (setq has-subtask t)))) - (and is-a-task has-subtask)))) - - (defun vde/is-project-subtree-p () - "Any task with a todo keyword that is in a project subtree. -Callers of this function already widen the buffer view." - (let ((task (save-excursion (org-back-to-heading 'invisible-ok) - (point)))) - (save-excursion - (vde/find-project-task) - (if (equal (point) task) - nil - t)))) - - (defun vde/find-project-task () - "Move point to the parent (project) task if any" - (save-restriction - (widen) - (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point)))) - (while (org-up-heading-safe) - (when (member (nth 2 (org-heading-components)) org-todo-keywords-1) - (setq parent-task (point)))) - (goto-char parent-task) - parent-task))) - - (defun vde/is-task-p () - "Any task with a todo keyword and no subtask" - (save-restriction - (widen) - (let ((has-subtask) - (subtree-end (save-excursion (org-end-of-subtree t))) - (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) - (save-excursion - (forward-line 1) - (while (and (not has-subtask) - (< (point) subtree-end) - (re-search-forward "^\*+ " subtree-end t)) - (when (member (org-get-todo-state) org-todo-keywords-1) - (setq has-subtask t)))) - (and is-a-task (not has-subtask))))) - - (defun vde/is-subproject-p () - "Any task which is a subtask of another project" - (let ((is-subproject) - (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) - (save-excursion - (while (and (not is-subproject) (org-up-heading-safe)) - (when (member (nth 2 (org-heading-components)) org-todo-keywords-1) - (setq is-subproject t)))) - (and is-a-task is-subproject))) - - (defun vde/clock-in-to-started (kw) - "Switch a task from TODO to STARTED when clocking in. -Skips capture tasks, projects, and subprojects. -Switch projects and subprojects from STARTED back to TODO" - (when (not (and (boundp 'org-capture-mode) org-capture-mode)) - (cond - ((and (member (org-get-todo-state) (list "TODO")) - (vde/is-task-p)) - "STARTED") - ((and (member (org-get-todo-state) (list "STARTED")) - (vde/is-project-p)) - "TODO")))) - :bind (("<f11>" . org-clock-goto))) -#+end_src - -** TODO Notes taking -:PROPERTIES: -:header-args: :noweb-ref notes :tangle no -:END: - -#+begin_src emacs-lisp -(use-package org-roam - :commands (org-roam org-roam-build-cache) - ;; :hook - ;; (after-init . org-roam-mode) - :bind (("C-c o n" . org-roam-mode) - :map org-roam-mode-map - (("C-c n l" . org-roam) - ("C-c n f" . org-roam-find-file) - ("C-c n g" . org-roam-show-graph) - ("C-c n b" . org-roam-switch-to-buffer)) - :map org-mode-map - (("C-c n i" . org-roam-insert))) - :custom - (org-roam-directory org-notes-dir) - :custom-face - (org-roam-link ((t (:inherit org-link :foreground "#C991E1")))) - :config - (require 'org-roam-protocol) - ;; (defun jethro/conditional-hugo-enable () - ;; (save-excursion - ;; (if (cdr (assoc "SETUPFILE" (org-roam--extract-global-props '("SETUPFILE")))) - ;; (org-hugo-auto-export-mode +1) - ;; (org-hugo-auto-export-mode -1)))) - ;; - ;; (with-eval-after-load 'org - ;; (defun my/org-roam--backlinks-list (file) - ;; (if (org-roam--org-roam-file-p file) - ;; (--reduce-from - ;; (concat acc (format "- [[file:%s][%s]]\n" - ;; (file-relative-name (car it) org-roam-directory) - ;; (org-roam--get-title-or-slug (car it)))) - ;; "" (org-roam-sql [:select [file-from] - ;; :from file-links - ;; :where (= file-to $s1) - ;; :and file-from :not :like $s2] file "%private%")) - ;; "")) - ;; (defun my/org-export-preprocessor (_backend) - ;; (let ((links (my/org-roam--backlinks-list (buffer-file-name)))) - ;; (unless (string= links "") - ;; (save-excursion - ;; (goto-char (point-max)) - ;; (insert (concat "\n* Backlinks\n" links)))))) - ;; (add-hook 'org-export-before-processing-hook 'my/org-export-preprocessor)) - (setq org-roam-capture-ref-templates - '(("r" "ref" plain #'org-roam-capture--get-point "" - :file-name "${slug}" - :head "#+title: ${title}\n#+roam_key: ${ref}\n\n${body}" - :unnarrowed t))) - (setq org-roam-capture-templates - '(("d" "default" plain (function org-roam--capture-get-point) - "%?" - :file-name "${slug}" -,#+TITLE: ${title}\n" - :unnarrowed t) - ("p" "private" plain (function org-roam--capture-get-point) - "%?" - :file-name "${slug}.private" - :head "#+TITLE: ${title}\n" - :unnarrowed t)))) -#+end_src - -*** TODO Rebuild configurations files - -Most of my configuration files are store in my [[https://git.sr.ht/~vdemeester/home][~home~ monorepo]]. That said, most of those -are actually automatically generated from litterate =org-mode= files coming from my notes. - -I want to be able to update those all in one go. Even better, I would like to make sure I -update those before killing emacs. - -#+begin_src emacs-lisp -(use-package org - :defer 2 - :config - (defun vde/tangle-all-notes () - "Produce files from my notes folder. -This function will attempt to tangle all org files from `org-notes-dir'. The -assumption is that those will generate configuration file (in `~/src/home'), -and thus keeping the configuration source up-to-date" - (mapc (lambda (x) (org-babel-tangle-file x)) - (ignore-errors - (directory-files-recursively org-notes-dir "\.org$"))))) -#+end_src - -** TODO Journaling -:PROPERTIES: -:header-args: :noweb-ref journaling :tangle no -:END: - -#+begin_src emacs-lisp -(use-package org-journal - :commands (org-journal-new-entry org-capture) - :after (org-capture) - :bind - (("C-c n j" . org-journal-new-entry) - ("C-c o j" . org-journal-new-entry)) - :init - (defun org-journal-find-location () - "Open today's journal, but inhibiting inserting the heading, leaving that to the template." - (org-journal-new-entry t) - ;; position pont on the journal's top-level heading so that org-capture will add the new entry as a child. - (goto-char (point-max))) - (add-to-list 'org-capture-templates - `("j" "Journal")) - (add-to-list 'org-capture-templates - `("jj" "Journal entry" entry (function org-journal-find-location) - "** %(format-time-string org-journal-time-format)%^{Title}\n%i%?" - :empty-lines 1 :clock-in t :clock-resume t)) - (add-to-list 'org-capture-templates - `("je" "Weekly review" entry (function org-journal-find-location) - (file ,(expand-file-name "etc/orgmode/weekly.org" user-emacs-directory)) - :empty-lines 1 :clock-in t :clock-resume t)) - :custom - (org-journal-date-prefix "* ") - (org-journal-file-header "#+TITLE: %Y-v%m Journal\n\n") - (org-journal-file-format "%Y-%m.private.org") - (org-journal-file-type 'monthly) - (org-journal-dir org-notes-dir) - (org-journal-date-format "%A, %d %B %Y") - (org-journal-enable-agenda-integration nil)) -#+end_src - -** TODO Litterate programming - -Although not really in my "organization" workflow, this is related to [[file:org_mode.org][org-mode]] so this -leaves here for now. - -#+name: src -#+begin_src emacs-lisp -(use-package org-src - :after (org) - :config - (setq org-src-fontify-natively t - org-src-tab-acts-natively t - org-src-window-setup 'current-window - org-edit-src-content-indentation 0)) -#+end_src - -*** TODO Links -:PROPERTIES: -:header-args: :noweb-ref links :tangle no -:END: - -#+begin_src emacs-lisp -;; my personal -(use-package ol-github - :after (org)) -(use-package ol-gitlab - :after (org)) -(use-package ol-ripgrep - :after (org)) -(use-package ol-rg - :disabled - :after (org)) -(use-package ol-grep - :after (org)) - -;; built-in org-mode -(use-package ol-eshell - :after (org)) -(use-package ol-git-link - :defer 2 - :after (org)) -(use-package ol-gnus - :defer 2 - :after (org)) -(use-package ol-irc - :defer 2 - :after (org)) -(use-package ol-info - :defer 2 - :after (org)) -(use-package ol-man - :defer 2 - :after (org)) -(use-package ol-notmuch - :defer 2 - :after (org)) -#+end_src - -#+begin_src emacs-lisp -(use-package orgit - :after org) -#+end_src - -*** TODO Babel -:PROPERTIES: -:header-args: :noweb-ref babel :tangle no -:END: - -#+begin_src emacs-lisp -(use-package ob-async - :after org - :commands (ob-async-org-babel-execute-src-block)) -(use-package ob-css - :after org - :commands (org-babel-execute:css)) -(use-package ob-dot - :after org - :commands (org-babel-execute:dot)) -(use-package ob-ditaa - :after org - :commands (org-babel-execute:ditaa) - :config - (setq org-ditaa-jar-path "/home/vincent/.nix-profile/lib/ditaa.jar")) -(use-package ob-emacs-lisp - :after org - :commands (org-babel-execute:emacs-lisp org-babel-execute:elisp)) -(use-package ob-go - :after org - :commands (org-babel-execute:go)) -(use-package ob-gnuplot - :after org - :commands (org-babel-execute:gnuplot)) -(use-package ob-http - :after org - :commands (org-babel-execute:http)) -(use-package ob-js - :after org - :commands (org-babel-execute:js)) -(use-package ob-latex - :after org - :commands (org-babel-execute:latex)) -(use-package ob-python - :after org - :commands (org-babel-execute:python)) -(use-package ob-shell - :after org - :commands (org-babel-execute:ash - org-babel-execute:bash - org-babel-execute:csh - org-babel-execute:dash - org-babel-execute:fish - org-babel-execute:ksh - org-babel-execute:mksh - org-babel-execute:posh - org-babel-execute:sh - org-babel-execute:shell - org-babel-execute:zsh)) -(use-package ob-doc-makefile - :after org - :commands (org-babel-execute:makefile)) -#+end_src - -** TODO Diary - -#+name: diary -#+begin_src emacs-lisp -(use-package diary-lib - :after (org) - :config - (setq diary-entry-marker "diary") - (setq diary-show-holidays-flag t) - (setq diary-header-line-flag nil) - (setq diary-mail-days 3) - (setq diary-number-of-entries 3) - (setq diary-comment-start ";") - (setq diary-comment-end "") - (setq diary-date-forms - '((day "/" month "[^/0-9]") - (day "/" month "/" year "[^0-9]") - (day " *" monthname " *" year "[^0-9]") - (monthname " *" day "[^,0-9]") - (monthname " *" day ", *" year "[^0-9]") - (year "[-/]" month "[-/]" day "[^0-9]") - (dayname "\\W")))) -#+end_src - -** TODO Miscellaneous -:PROPERTIES: -:header-args: :noweb-ref misc :tangle no -:END: - -#+begin_src emacs-lisp -(use-package org-id - :after org - :commands contrib/org-id-headlines - :config - (setq org-id-link-to-org-use-id - 'create-if-interactive-and-no-custom-id) - - (defun contrib/org-get-id (&optional pom create prefix) - "Get the CUSTOM_ID property of the entry at point-or-marker -POM. If POM is nil, refer to the entry at point. If the entry -does not have an CUSTOM_ID, the function returns nil. However, -when CREATE is non nil, create a CUSTOM_ID if none is present -already. PREFIX will be passed through to `org-id-new'. In any -case, the CUSTOM_ID of the entry is returned." - (org-with-point-at pom - (let ((id (org-entry-get nil "CUSTOM_ID"))) - (cond - ((and id (stringp id) (string-match "\\S-" id)) - id) - (create - (setq id (org-id-new (concat prefix "h"))) - (org-entry-put pom "CUSTOM_ID" id) - (org-id-add-location id (buffer-file-name (buffer-base-buffer))) - id))))) - - (defun contrib/org-id-headlines () - "Add CUSTOM_ID properties to all headlines in the current -file which do not already have one." - (interactive) - (org-map-entries - (funcall 'contrib/org-get-id (point) 'create)))) -#+end_src - -#+begin_src emacs-lisp -(use-package org-crypt - :after (org) - :config - (org-crypt-use-before-save-magic) - (setq org-tags-exclude-from-inheritance '("crypt"))) -#+end_src - -#+begin_src emacs-lisp -(use-package org-tempo - :after (org)) -#+end_src - -#+begin_src emacs-lisp -(use-package org-attach - :after org - :config - (setq org-link-abbrev-alist '(("att" . org-attach-expand-link)))) -#+end_src - -#+begin_src emacs-lisp -(use-package ox-publish - :after org - :commands (org-publish org-publish-all org-publish-project org-publish-current-project org-publish-current-file) - :config - (setq org-html-coding-system 'utf-8-unix)) -#+end_src -* Triage - -#+begin_src -# -*- mode: org; eval: (add-hook 'after-save-hook (lambda () (org-babel-tangle)) nil t) -*- -#+end_src - -- Remove slack from phone (or personal tablets) - With working remote, it's even more important to draw the line - -- Have timeboxed « slacking off » session - by slacking off, I mean twitter, reddit, … - -- Take a medium to long walk during the day - Better in the middle, by medium to long I mean at least an hour walk - -- It's ok to set smaller pomodoro from time to time, 25 is the "longest" limit, not the - lowest one - -- Apply it as much as you can (i.e. not interruption) - -- Pomodoro technique -- https://thelifelifebalance.com/pros-and-cons-of-pomodoro/ - -- Phone / tablet - - Remove most apps - - Remove most notifications - - Grayscale most of the time - -** TODO ~org-mode~ Workflow -:LOGBOOK: -CLOCK: [2020-02-24 Mon 17:48]--[2020-02-24 Mon 19:07] => 1:19 -:END: - -This goes into =emacs.org=. - -Ideas: -- filter org file(s) with a tags & co - - use case: ~journal.org~ with weekly-review only, worklog only, … - - subject (go, emacs, …) to build article or gather thoughts, idea, reviews, … -- Heavy usage of =org-protocol= to list reviews done, and more quickly capture content - from the browser - -The rest is deprecated 😅 -:deprecated: -Let's try to think about "TODOs" management in the light of =todoist= *and* =org-mode=. -Reasons to use =todoist= are : - -- write task/todo items on-the-go on any devices — this is way harder with =org-mode=. -- list and mark task/todo as done from anywhere -- share some list with others (mainly @houbeb) -- have some nice stats - -Reasons to use =org-mode= are : - -- integrated with my editor, agenda, notes, mail, … -- easily customizable (dashboard, agenda, search, filters, org-links, …) -- all text, data are own by me, replicated -- clock possibility (related to work, so adding some context to it) - -One idea is to be able to synchronize =org-mode= and =todoist= - -- only part of the =org-mode= todo list (i.e. a =todoist.org= file) -- mainly (and at first) used =todoist -> org-mode= -- syncing two ways the means adding a new element that doesn't have the required - properties in the =todoist.org= file -:end: - -*** TODO Do some writeup about org-mode usage and workflow - -A bit à-la-howardisms -- [[http://www.howardism.org/Technical/Emacs/getting-boxes-done.html][Getting Boxes Done]] -- [[http://www.howardism.org/Technical/Emacs/getting-more-boxes-done.html][Getting Boxes Done, the Code]] -- [[http://www.howardism.org/Technical/Emacs/getting-even-more-boxes-done.html][Refiling Trees to Files]] - -*** TODO Add a reviewing org-protocol capture template -:PROPERTIES: -:CREATED:[2020-04-16 Thu 10:57] -:END: - -That way I track more easily the long review by just using a bookmark. - -*** TODO Better worklog entries - -- Substree in a datetime tree (see if it is possible) -- In a separate journal ? - -*** TODO [#B] Fix meetings notes -:PROPERTIES: -:CREATED:[2020-04-02 Thu 17:41] -:END: - -1. Capture template doesn't work -2. Can we make Actions and Decision per "tree" ? (if not, meeting notes might be one file - for each meeting) -3. Ideas - - New tree - - Better template - - Stay in the capture while it's happening - -From: [[file:~/desktop/org/projects/meetings.org::*Decisions][Decisions]] -*** TODO [#A] quick writing org-mode template -:LOGBOOK: -CLOCK: [2020-04-01 Wed 19:15]--[2020-04-01 Wed 19:45] => 0:30 -:END: -:PROPERTIES: -:CREATED:[2019-12-20 Fri 10:09] -:END: - -- +blog post (in ~src/github.com/vdemeester/blog~)+ -- +technical post (in ~desktop/org/technical~)+ - -- Meeting notes :: =meetings.org= in =~/desktop/org/projects= - See [[https://egli.dev/posts/using-org-mode-for-meeting-minutes/][Using org-mode for meeting minutes • egli.dev]] for inspiration -- Better notes :: Make it easier to take notes - See [[file:~/desktop/org/projects/inbox.org::*[[https://dpitt.me/blog/2020/03/zettelkasten/\][dpitt.me :: Using Emacs's org-mode As Your Zettelkästen]\]][dpitt.me :: Using Emacs's org-mode As Your Zettelkästen]] -- =src/www= :: - + articles - + posts -- =src/home/docs= :: - + for new docs ? - -- Read [[https://orgmode.org/manual/Template-elements.html#Template-elements][Template elements (The Org Manual)]] -- rg:org-capture-template:/mnt/synodine/volumeUSB2/usbshare/src/github.com/vdemeester/configs - + [[git:/mnt/synodine/volumeUSB2/usbshare/src/github.com/vdemeester/configs/howardabrams.spacemacs.d/layers/ha-org/packages.el::master@{2020-04-02}::342][git:/mnt/synodine/volumeUSB2/usbshare/src/github.com/vdemeester/configs/howardabrams.spacemacs.d/layers/ha-org/packages.el::master@{2020-04-02}::342]] - -^^ some of those could be /normal/ template instead of =org-mode= capture templates - -*** TODO org-protocol support for more templates - -- reviews, task, … -- https://github.com/abo-abo/orca - -** TODO [#A] =org-mode= entry ordering - -- By TODO keyword, then priority -- Bind it to sthg (else than =^=) -** Legacy - -#+name: legacy -#+begin_src emacs-lisp :tangle no -(use-package org - :defer t - :config - - (defvar org-capture-templates (list)) - (setq org-protocol-default-template-key "l") - - ;; images - (setq org-image-actual-width nil - org-startup-with-inline-images nil) - - ;; Tasks (-> inbox) - - ;; Journal - - (add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" ":END:")) - (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" "#\\+END_SRC")) - (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_EXAMPLE" "#\\+END_EXAMPLE")) - - ;; org-links - ;; from http://endlessparentheses.com/use-org-mode-links-for-absolutely-anything.html - (org-link-set-parameters "tag" - :follow #'endless/follow-tag-link) - (defun endless/follow-tag-link (tag) - "Display a list of TODO headlines with tag TAG. -With prefix argument, also display headlines without a TODO keyword." - (org-tags-view (null current-prefix-arg) tag)) - - (org-link-set-parameters - "org" - :complete (lambda () (+org-link-read-file "org" org-directory)) - :follow (lambda (link) (find-file (expand-file-name link org-directory))) - :face (lambda (link) - (if (file-exists-p (expand-file-name link org-directory)) - 'org-link - 'error))) - (defun +org-link-read-file (key dir) - (let ((file (read-file-name (format "%s: " (capitalize key)) dir))) - (format "%s:%s" - key - (file-relative-name file dir)))) - ) -#+end_src - -** Foobar - -#+name: foo -#+begin_src emacs-lisp :tangle no -(message "foo") -#+end_src - -#+name: bar -#+begin_src emacs-lisp :tangle no -(message "bar") -#+end_src - -#+name: foobar -#+begin_src emacs-lisp :noweb no-export :exports code :tangle no -;; Yo - -<<foo>> -<<bar>> -#+end_src -* Configuration layout -:PROPERTIES: -:header-args: :tangle ~/src/home/tools/emacs/config/config-org.el -:ID: 04f8683e-a5df-4803-a01e-dbbefd256554 -:END: - -Here we define the =config-org= file that gets generated by the source blocks in our Org -document. This is the file that actually gets loaded on startup. The placeholders in -angled brackets correspond to the ~NAME~ directives above the ~SRC~ blocks throughout this -document. - -#+begin_src emacs-lisp :noweb no-export :exports code -;;; config-org.el --- -*- lexical-binding: t; -*- -;;; Commentary: -;;; Configuration of orgmode. -;;; Code: - -(use-package s) - -<<constants-and-registers>> -<<main>> -<<agenda>> -<<capture>> -<<protocol>> -<<clock>> -<<habits>> -<<src>> -<<links>> -<<babel>> -<<notes>> -<<journaling>> -<<misc>> -<<diary>> - -<<legacy>> - -(provide 'config-org) -;;; config-org.el ends here -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/my_personal_journey_from_mit_to_gpl_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/my_personal_journey_from_mit_to_gpl_drew_devault_s_blog.org @@ -1,7 +0,0 @@ -#+title: My personal journey from MIT to GPL | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2019/06/13/My-journey-from-MIT-to-GPL.html - -As I got started writing open source software, I generally preferred the MIT license. I -actually made fun of the “copyleft” GPL licenses, on the grounds that they are less -free. I still hold this opinion today: the GPL license is less free than the MIT license - -but today, I believe this in a good way. diff --git a/www/vincent.demeester.fr/content/legacy/articles/nginx.org b/www/vincent.demeester.fr/content/legacy/articles/nginx.org @@ -1,2 +0,0 @@ - -#+TITLE: nginx diff --git a/www/vincent.demeester.fr/content/legacy/articles/nix.org b/www/vincent.demeester.fr/content/legacy/articles/nix.org @@ -1,64 +0,0 @@ -#+SETUPFILE: .setup.org -#+TITLE: Nix - -[[https://nixos.org/][Nix]] is a powerful package manager for Linux and other Unix systems that makes package -management reliable and reproducible. Share your development and build environments across -different machines. - -[[file:nixos.org][NixOS]] is a Linux distribution with a unique approach to package and configuration -management. Built on top of the Nix package manager, it is completely declarative, makes -upgrading systems reliable, and has many other [[https://nixos.org/features.html][advantages]]. - -* Links -** [[https://stephank.nl/p/2020-06-01-a-nix-primer-by-a-newcomer.html][A Nix terminology primer by a newcomer]] :nixos:docs: -[2020-06-05 Fri 23:06] - -** [[https://github.com/t184256/nix-on-droid][t184256/nix-on-droid: Nix-enabled environment for your Android device.]] -[2020-06-18 Thu 11:51] -** TODO [[https://www.tweag.io/posts/2020-05-25-flakes.html][Tweag I/O - Nix Flakes, Part 1: An introduction and tutorial]] -[2020-05-26 Tue 09:14] - -https://github.com/edolstra/dwarffs - -** TODO [[https://nixos.wiki/wiki/Binary_Cache][Binary Cache - NixOS Wiki]] -[2020-05-26 Tue 10:24] -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/inspecting-values-with-repl.md][nix-shorts/inspecting-values-with-repl.md at master · justinwoo/nix-shorts]] :nixos: -[2020-06-21 Sun 21:08] - -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/install-packages-from-files.md][nix-shorts/install-packages-from-files.md at master · justinwoo/nix-shorts]] -[2020-06-21 Sun 21:08] - -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/install-things-to-nix-profile.md][nix-shorts/install-things-to-nix-profile.md at master · justinwoo/nix-shorts]] -[2020-06-21 Sun 21:09] - -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/install-things-to-nix-profile.md][nix-shorts/install-things-to-nix-profile.md at master · justinwoo/nix-shorts]] -[2020-06-21 Sun 21:10] - -readlink -f ~/.nix-profile - -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/pinning-to-a-specific-nixpkgs-revision.md][nix-shorts/pinning-to-a-specific-nixpkgs-revision.md at master · justinwoo/nix-shorts]] -[2020-06-21 Sun 21:10] - -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/working-with-nix-shells.md][nix-shorts/working-with-nix-shells.md at master · justinwoo/nix-shorts]] -[2020-06-21 Sun 21:10] - -** TODO [[https://github.com/justinwoo/nix-shorts/blob/master/posts/your-first-derivation.md][nix-shorts/your-first-derivation.md at master · justinwoo/nix-shorts]] -[2020-06-21 Sun 21:11] -** TODO [[https://nixos.mayflower.consulting/blog/2020/01/20/structured-attrs/][__structuredAttrs in Nix]] -[2020-06-23 Tue 18:07] -** TODO [[https://gvolpe.github.io/blog/github-actions-nix-cachix-dhall/][Github actions powered by Nix Shell & Cachix • gvolpe's blog]] -[2020-06-29 Mon 17:51] - -** TODO [[https://nix.dev/][Welcome to nix.dev — nix.dev documentation]] -[2020-06-29 Mon 17:51] - -** TODO [[https://ghedam.at/15490/so-tell-me-about-nix][So, tell me about Nix]] -[2020-06-29 Mon 17:53] -** TODO [[https://blog.sulami.xyz/posts/nix-for-developers/][Lightning Introduction to Nix for Developers - sulami's blog]] -[2020-11-30 Mon 11:21] -** TODO [[https://ariya.io/2016/06/isolated-development-environment-using-nix][Isolated Development Environment using Nix · ariya.io]] -[2020-12-03 Thu 15:45] -** TODO [[https://github.com/mlvzk/manix][mlvzk/manix: A fast CLI documentation searcher for Nix.]] -[2020-12-17 Thu 16:04] -** TODO [[https://rgoswami.me/posts/ccon-tut-nix/][A Tutorial Introduction to Nix :: Rohit Goswami — Reflections]] -[2020-08-19 Wed 10:02] diff --git a/www/vincent.demeester.fr/content/legacy/articles/nixos-overlays.org b/www/vincent.demeester.fr/content/legacy/articles/nixos-overlays.org @@ -1,41 +0,0 @@ -#+TITLE: NixOS overlay notes -#+FILETAGS: :nixos:overlay:configuration: -#+SETUPFILE: .setup.org - -[[https://nixos.org][NixOS]] has a concept of =overlays= since a while ([[https://nixos.org/nix-dev/2016-December/022386.html][around 2016]]). The -official manual has a chapter on it : [[https://nixos.org/nixpkgs/manual/#chap-overlays][Overlays]]. - -#+BEGIN_QUOTE -Overlays are used to add layers in the fix-point used by Nixpkgs to -compose the set of all packages. -#+END_QUOTE - -There is two distinct element to overlays: - -- How to define overlays ? -- Where =nix= (and NixOS) looks for it ? - -* Define an overlay -:PROPERTIES: -:CUSTOM_ID: h:56de4f99-53be-49fd-b969-a419d8e9273f -:END: - -According to the documentation, « Overlays are Nix functions which -accept two arguments, conventionally called self and super, and return -a set of packages ». The documentation gives an example : - -#+BEGIN_SRC nix -self: super: - -{ - boost = super.boost.override { - python = self.python3; - }; - rr = super.callPackage ./pkgs/rr { - stdenv = self.stdenv_32bit; - }; -} -#+END_SRC - -I used to have a personal channels on github : [[https://github.com/vdemeester/sbrpkgs/][sbrpkgs]]. Let's convert -this repository to an overlay by updating the =default.nix= file. diff --git a/www/vincent.demeester.fr/content/legacy/articles/nixos.org b/www/vincent.demeester.fr/content/legacy/articles/nixos.org @@ -1,156 +0,0 @@ - -#+TITLE: NixOS - -[[https://nixos.org/][NixOS]] is a Linux distribution with a unique approach to package and configuration -management. Built on top of the [[file:nix.org][Nix]] package manager, it is completely declarative, makes -upgrading systems reliable, and has many other [[https://nixos.org/features.html][advantages]]. - -Most of my [[file:infrastructure.org][infrastructure]] is on NixOS. - -- [[file:nixos-overlays.org][NixOS overlay notes]] - -* Nix builder - -* Links - -** [[https://github.com/nix-community/impermanence][nix-community/impermanence: Modules to help you handle persistent state on systems with ephemeral root storage [maintainer=@talyz]]] :nixos: -[2020-06-07 Sun 14:05] - -=impermanence= provides modules to setup your system with ephemeral root storage 🙃 - - -** [[https://spacekookie.de/blog/ocitools-in-nixos/][ociTools in NixOS]] -[2019-10-28 Mon 21:38] -** TODO [[http://notes.neeasade.net/adhoc-executable-patching-on-nix.html][adhoc executable patching on nixos]] -[2020-11-26 Thu 12:17] -** TODO [[http://davedellacosta.com/posts/2019-03-29-why-nixos-is-hard-and-how-to-fix.html][davedellacosta.com - 2019-03-29-why-nixos-is-hard-and-how-to-fix]] :nixpkgs:nixos: -[2019-04-17 Wed 18:19] - -** TODO https://elvishjerricco.github.io/2018/06/24/secure-declarative-key-management.html (Secure, Declarative Key Management with NixOps, Pass, and nix-plugins) :nixos: - :PROPERTIES: - :END: -** TODO [[https://blog.hercules-ci.com/nix/2019/05/15/nix-gitignore/][gitignore for Nix – Hercules Labs blog]] :nixpkgs: -[2019-06-07 Fri 14:47] - -** TODO [[https://gist.github.com/adisbladis/187204cb772800489ee3dac4acdd9947][Use podman within a nix-shell]] :nixos:podman:containers: -[2019-12-10 Tue 18:52] -** TODO [[https://nixos.mayflower.consulting/blog/2019/11/27/windows-vm-storage/][Windows-on-NixOS, part 1: Migrating bare-metal to a VM]] :nixos: -[2020-01-17 Fri 18:19] - -** TODO [[http://blog.patapon.info/nixos-local-vm/][Dejà vu - Updating NixOS local VMs]] :nixos: -[2020-01-17 Fri 18:19] - -** TODO [[http://blog.patapon.info/nix-run-direnv/][Dejà vu - Direnv with nix run]] :nixos: -[2020-01-17 Fri 18:19] - -** TODO [[https://myme.no/posts/2020-01-26-nixos-for-development.html][myme.no - NixOS: For developers]] -[2020-01-30 Thu 18:28] - -** TODO [[https://github.com/fghibellini/nix-haskell-monorepo][fghibellini/nix-haskell-monorepo: Pragmatic tutorial on how to use nix with a haskell monorepo]] -[2020-01-30 Thu 18:33] - -** TODO [[https://christine.website/blog/i-was-wrong-about-nix-2020-02-10][I was Wrong about Nix - Christine Dodrill]] -[2020-02-12 Wed 12:38] - -** TODO [[https://www.srid.ca/2012301.html][Lightweight Linux VMs on NixOS - Sridhar Ratnakumar]] -[2020-03-27 Fri 18:15] -** TODO [[https://blog.ysndr.de/posts/internals/2020-04-10-built-with-nix/][Building a reproducible blog with Nix]] -[2020-04-28 Tue 19:20] - -** TODO [[https://christine.website/blog/nixos-desktop-flow-2020-04-25][My NixOS Desktop Flow - Christine Dodrill]] -[2020-05-07 Thu 16:45] -** TODO [[https://github.com/tazjin/nix-1p][tazjin/nix-1p: A (more or less) one page introduction to Nix, the language.]] :nixpkgs:nixos: -[2020-05-15 Fri 10:46] -** TODO [[https://brianmckenna.org/blog/running_binaries_on_nixos][Running Unpatched Binaries on NixOS - BAM Weblog]] -:PROPERTIES: -:CREATED:[2019-03-02 Sat 11:29] -:END: -** TODO [[https://thomashartmann.dev/blog/nix-override-packages-with-overlays/][thomashartmann.dev::Nix: override packages with overlays]] -[2020-03-02 Mon 15:11] - -** TODO [[https://christine.website/blog/how-i-start-nix-2020-03-08][How I Start: Nix - Christine Dodrill]] -[2020-03-09 Mon 10:25] - -Super guide to nix in a project with niv 💓 - -** TODO [[https://nixery.dev/][Nixery]] -[2019-10-09 Wed 15:07] - -nixery.dev/shell/git/htop -** TODO [[https://rycwo.xyz/2018/07/29/nixos-series-dual-boot][Diving Into NixOS (Part 1): Dual-Booting On A New Laptop]] - -** TODO [[https://github.com/tweag/rfcs/blob/flakes/rfcs/0049-flakes.md][rfcs/0049-flakes.md at flakes · tweag/rfcs]] -[2020-05-06 Wed 05:44] - -**** TODO [[https://github.com/NixOS/nixpkgs/pull/84125][nix-daemon.nix: Add option nix.registry by edolstra · Pull Request #84125 · NixOS/nixpkgs]] :nixos: -[2020-05-06 Wed 09:01] - -**** TODO [[https://github.com/NixOS/nixpkgs/pull/68897][Flake support by edolstra · Pull Request #68897 · NixOS/nixpkgs]] :nixos: -[2020-05-06 Wed 09:01] - - - -** TODO [[http://www.haskellforall.com/2020/11/how-to-use-nixos-for-lightweight.html?m=1][Haskell for all: How to use NixOS for lightweight integration tests]] -[2020-11-30 Mon 14:32] -** TODO [[https://rbf.dev/blog/2020/05/custom-nixos-build-for-raspberry-pis/][NixOS on a Raspberry Pi: creating a custom SD image with OpenSSH out of the box | Roberto Frenna]] :nixos: -[2020-05-28 Thu 15:53] - -** TODO [[https://blog.qtp2t.club/posts/2020-06-20-nix-nixos-thoughts/][Nix(OS) Thoughts]] -[2020-06-22 Mon 16:49] - -** TODO [[https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html][Encypted Btrfs Root with Opt-in State on NixOS]] -[2020-06-29 Mon 17:44] - -** TODO [[https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/][NixOS ❄: tmpfs as root]] -[2020-06-29 Mon 17:46] - -** TODO [[https://elis.nu/blog/2020/06/nixos-tmpfs-as-home/][NixOS ❄: tmpfs as home]] -[2020-06-29 Mon 17:46] - -** TODO [[https://github.com/ryantm/home-manager-template][ryantm/home-manager-template: A quick-start template for using home-manager in a more reproducible way.]] -[2020-06-29 Mon 17:49] - -** TODO [[https://github.com/grahamc/netboot.nix/][grahamc/netboot.nix: Create full netboot images in 15 seconds.]] -[2020-06-29 Mon 17:52] - -** TODO [[https://notes.neeasade.net/adhoc-executable-patching-on-nix.html][adhoc executable patching on nixos]] -[2020-07-14 Tue 18:45] - -** TODO [[https://foo-dogsquared.github.io/blog/posts/moving-into-nixos/][Moving into NixOS | Gabriel Arazas]] -[2020-11-16 Mon 19:17] - -** TODO [[https://fzakaria.com/2020/11/17/on-demand-linked-libraries-for-nix.html][On-demand linked libraries for Nix | Farid Zakaria’s Blog]] -[2020-11-19 Thu 17:44] - -** TODO [[https://rycwo.xyz/2019/02/07/nixos-series-configuring-xinit][Diving Into NixOS (Part 3): Lightweight Startup With xinit]] -[2020-11-19 Thu 17:47] - -** TODO [[https://fzakaria.com/2020/08/11/caching-your-nix-shell.html][caching your nix-shell | Farid Zakaria’s Blog]] -[2020-12-17 Thu 16:04] -** TODO [[https://hands-on.cloud/why-you-should-never-ever-use-nixos/][Why you should never ever use NixOS]] -[2021-01-26 Tue 18:32] -** TODO [[https://sgt.hootr.club/molten-matter/nix-distributed-builds/][Offloading NixOS builds to a faster machine]] -[2021-01-26 Tue 18:34] -** TODO [[https://serokell.io/blog/deploy-rs][Our New Nix Deployment Tool: deploy-rs]] -[2021-01-26 Tue 18:49] - -** TODO [[https://terinstock.com/post/2021/01/Setting-up-a-git-server-on-NixOS/][Setting up a git server on NixOS]] -[2021-01-28 Thu 10:48] -** TODO [[https://nixos.mayflower.consulting/blog/2021/01/28/nextcloud-stateversion/][Safe service upgrades using system.stateVersion]] -[2021-01-29 Fri 10:34] - -** TODO [[https://tech.channable.com/posts/2021-04-09-nix-is-the-ultimate-devops-toolkit.html][Channable - Nix is the ultimate DevOps toolkit]] -[2021-04-12 Mon 12:32] - -** TODO [[https://christine.website/blog/my-wireguard-setup-2021-02-06][My Automagic NixOS Wireguard Setup - Christine Dodrill]] -[2021-04-12 Mon 12:38] - -** TODO [[https://fzakaria.com/2021/08/05/the-search-for-a-minimal-nix-shell-continued-mkshellminimal.html][The search for a minimal nix-shell continued; mkShellMinimal | Farid Zakaria’s Blog]] -[2021-08-06 Fri 10:23] - -** TODO [[https://github.com/Mic92/sops-nix][Mic92/sops-nix: Atomic secret provisioning for NixOS based on sops]] -[2021-08-06 Fri 15:35] -** TODO [[https://catgirl.ai/log/nixos-experience/][Eight Months of NixOS | gay robot noises]] -[2020-11-03 Tue 11:04] -** TODO [[https://hoverbear.org/blog/configurable-nix-packages/][Configurable Nix packages]] -[2022-06-10 Fri 22:28] diff --git a/www/vincent.demeester.fr/content/legacy/articles/notmuch.org b/www/vincent.demeester.fr/content/legacy/articles/notmuch.org @@ -1 +0,0 @@ -#+TITLE: notmuch diff --git a/www/vincent.demeester.fr/content/legacy/articles/ocp-bootstrap.xml b/www/vincent.demeester.fr/content/legacy/articles/ocp-bootstrap.xml @@ -1,63 +0,0 @@ -<domain type="kvm"> - <name>ocp4-bootstrap</name> - <uuid>08b76da0-046c-4472-85e4-071b24e43a9f</uuid> - <memory>8388608</memory> - <currentMemory>8388608</currentMemory> - <vcpu>4</vcpu> - <os> - <type arch="x86_64" machine="pc-i440fx-4.2">hvm</type> - <boot dev="hd"/> - <bootmenu enable="yes"/> - </os> - <features> - <acpi/> - <apic/> - <vmport state="off"/> - </features> - <cpu mode="host-model"/> - <clock offset="utc"> - <timer name="rtc" tickpolicy="catchup"/> - <timer name="pit" tickpolicy="delay"/> - <timer name="hpet" present="no"/> - </clock> - <pm> - <suspend-to-mem enabled="no"/> - <suspend-to-disk enabled="no"/> - </pm> - <devices> - <emulator>/run/libvirt/nix-emulators/qemu-system-x86_64</emulator> - <disk type="file" device="disk"> - <driver name="qemu" type="qcow2"/> - <source file="/var/lib/libvirt/images/ocp-bootstrap.qcow2"/> - <target dev="vda" bus="virtio"/> - </disk> - <controller type="usb" index="0" model="ich9-ehci1"/> - <controller type="usb" index="0" model="ich9-uhci1"> - <master startport="0"/> - </controller> - <controller type="usb" index="0" model="ich9-uhci2"> - <master startport="2"/> - </controller> - <controller type="usb" index="0" model="ich9-uhci3"> - <master startport="4"/> - </controller> - <interface type="network"> - <source network="default"/> - <mac address="52:54:00:74:76:12"/> - <model type="e1000"/> - </interface> - <console type="pty"/> - <channel type="spicevmc"> - <target type="virtio" name="com.redhat.spice.0"/> - </channel> - <input type="tablet" bus="usb"/> - <graphics type="spice" port="-1" tlsPort="-1" autoport="yes"/> - <sound model="ich6"/> - <video> - <model type="qxl"/> - </video> - <redirdev bus="usb" type="spicevmc"/> - <redirdev bus="usb" type="spicevmc"/> - </devices> -</domain> - diff --git a/www/vincent.demeester.fr/content/legacy/articles/open_container_initiative.org b/www/vincent.demeester.fr/content/legacy/articles/open_container_initiative.org @@ -1,12 +0,0 @@ - -#+TITLE: Open Container Initiative -#+ROAM_ALIAS: "OCI" - -From the [[https://opencontainers.org/][website]]: - -#+begin_quote -The Open Container Initiative is an open governance structure for the express purpose of -creating open industry standards around container formats and runtimes. -#+end_quote - -The most important part is on the [[file:github.org][GitHub]] organization though : [[https://github.com/opencontainers][opencontainers]]. diff --git a/www/vincent.demeester.fr/content/legacy/articles/openbsd.org b/www/vincent.demeester.fr/content/legacy/articles/openbsd.org @@ -1,3 +0,0 @@ -#+TITLE: openbsd -* TODO [[https://eradman.com/posts/openbsd-workstation.html][An OpenBSD Workstation]] -[2020-05-18 Mon 18:32] diff --git a/www/vincent.demeester.fr/content/legacy/articles/opencontainers_artifacts_oci_artifacts.org b/www/vincent.demeester.fr/content/legacy/articles/opencontainers_artifacts_oci_artifacts.org @@ -1,2 +0,0 @@ -#+title: opencontainers/artifacts: OCI Artifacts -#+roam_key: https://github.com/opencontainers/artifacts diff --git a/www/vincent.demeester.fr/content/legacy/articles/opencontainers_distribution_spec_oci_distribution_specification.org b/www/vincent.demeester.fr/content/legacy/articles/opencontainers_distribution_spec_oci_distribution_specification.org @@ -1,2 +0,0 @@ -#+title: opencontainers/distribution-spec: OCI Distribution Specification -#+roam_key: https://github.com/opencontainers/distribution-spec diff --git a/www/vincent.demeester.fr/content/legacy/articles/opencontainers_image_spec_oci_image_format.org b/www/vincent.demeester.fr/content/legacy/articles/opencontainers_image_spec_oci_image_format.org @@ -1,2 +0,0 @@ -#+title: opencontainers/image-spec: OCI Image Format -#+roam_key: https://github.com/opencontainers/image-spec diff --git a/www/vincent.demeester.fr/content/legacy/articles/opencontainers_runtime_spec_oci_runtime_specification.org b/www/vincent.demeester.fr/content/legacy/articles/opencontainers_runtime_spec_oci_runtime_specification.org @@ -1,2 +0,0 @@ -#+title: opencontainers/runtime-spec: OCI Runtime Specification -#+roam_key: https://github.com/opencontainers/runtime-spec diff --git a/www/vincent.demeester.fr/content/legacy/articles/opendatahub_opendatahub.org b/www/vincent.demeester.fr/content/legacy/articles/opendatahub_opendatahub.org @@ -1,2 +0,0 @@ -#+title: OpenDataHub · OpenDataHub -#+roam_key: https://opendatahub.io/ diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift-commons.org b/www/vincent.demeester.fr/content/legacy/articles/openshift-commons.org @@ -1,658 +0,0 @@ -#+TITLE: OpenShift Commons -#+SUBTITLE: Support for OpenShift Commons calls & demos -#+FILETAGS: kubernetes openshift -#+SETUPFILE: .setup.org - -#+TOC: headlines 1 - -* Openshift Pipelines -:PROPERTIES: -:CUSTOM_ID: h:a5228f76-91f1-4e30-93a9-fe704230a561 -:END: - -OpenShift Pipelines is a cloud-native, continuous integration and delivery (CI/CD) -solution for building pipelines using [Tekton](https://tekton.dev). Tekton is a flexible, -Kubernetes-native, open-source CI/CD framework that enables automating deployments across -multiple platforms (Kubernetes, serverless, VMs, etc) by abstracting away the underlying -details. - -OpenShift Pipelines features: -- Standard CI/CD pipeline definition based on Tekton -- Build images with Kubernetes tools such as S2I, Buildah, Buildpacks, Kaniko, etc -- Deploy applications to multiple platforms such as Kubernetes, serverless and VMs -- Easy to extend and integrate with existing tools -- Scale pipelines on-demand -- Portable across any Kubernetes platform -- Designed for microservices and decentralized teams -- Integrated with the OpenShift Developer Console - -** Prerequisite -:PROPERTIES: -:CUSTOM_ID: h:509fe8c1-2619-496f-b109-dfd67c0e47a1 -:END: - -You need an OpenShift 4 cluster in order to complete this tutorial. If you don't have an -existing cluster, go to http://try.openshift.com and register for free in order to get an -OpenShift 4 cluster up and running on AWS within minutes. - -You will also use the Tekton CLI (~tkn~) through out this tutorial. Download the Tekton -CLI and copy it to a location on your ~PATH~. - -** Concepts -:PROPERTIES: -:CUSTOM_ID: h:d958ae3b-de56-4b7c-9355-988579b57389 -:END: - -Tekton defines a number of [[https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/][Kubernetes custom resources]] as building blocks in order to -standardize pipeline concepts and provide a terminology that is consistent across CI/CD -solutions. These custom resources (CR) are an extension of Kubernetes that let users -create and interact with these objects using ~kubectl~ and other Kubernetes tools. - -The custom resources needed to define a pipeline are: -- ~Task~: a reusable, loosely coupled number of steps that perform a specific task (e.g., building a container image) -- ~Pipeline~: the definition of the pipeline and the ~Task~s that it should perform -- ~PipelineResource~: inputs (e.g., git repository) and outputs (e.g., image registry) to and out of a pipeline or task -- ~TaskRun~: the result of running an instance of task -- ~PipelineRun~: the result of running an instance of pipeline, which includes a number of ~TaskRun~s - -** Deploy sample application -:PROPERTIES: -:CUSTOM_ID: h:d1d116fb-34e7-43d1-bf1b-2a4a8c3bcb65 -:END: -*** Create the project -:PROPERTIES: -:CUSTOM_ID: h:b7952df1-d635-4276-8186-b1c209aea268 -:END: - -We are creating a project, ~openshift-comons~. Building container images using build tools -such as S2I, Buildah, Kaniko, etc require privileged access to the cluster. OpenShift -default security settings do not allow privileged containers unless specifically -configured. Create a service account for running pipelines and enable it to run privileged -pods for building images. - -#+begin_src bash - oc new-project pipeline-demo - oc create serviceaccount pipeline - oc adm policy add-scc-to-user privileged -z pipeline - oc adm policy add-role-to-user edit -z pipeline -#+end_src - -*** The application -:PROPERTIES: -:CUSTOM_ID: h:070d48bb-7bfd-4cff-b709-60a825f0cab4 -:END: - -We will use the [[https://github.com/spring-projects/spring-petclinic][Spring PetClinic]] sample application during this tutorial, which is a -simple Spring Boot application. - -#+begin_src yaml :tangle openshift-commons/app.yaml - --- - apiVersion: image.openshift.io/v1 - kind: ImageStream - metadata: - labels: - app: spring-petclinic - name: spring-petclinic - --- - apiVersion: apps.openshift.io/v1 - kind: DeploymentConfig - metadata: - labels: - app: spring-petclinic - name: spring-petclinic - spec: - replicas: 1 - revisionHistoryLimit: 10 - selector: - app: spring-petclinic - deploymentconfig: spring-petclinic - strategy: - activeDeadlineSeconds: 21600 - resources: {} - rollingParams: - intervalSeconds: 1 - maxSurge: 25% - maxUnavailable: 25% - timeoutSeconds: 600 - updatePeriodSeconds: 1 - type: Rolling - template: - metadata: - labels: - app: spring-petclinic - deploymentconfig: spring-petclinic - spec: - containers: - - image: spring-petclinic:latest - imagePullPolicy: Always - livenessProbe: - failureThreshold: 3 - httpGet: - path: / - port: 8080 - scheme: HTTP - initialDelaySeconds: 45 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - name: spring-petclinic - ports: - - containerPort: 8080 - protocol: TCP - - containerPort: 8443 - protocol: TCP - - containerPort: 8778 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: / - port: 8080 - scheme: HTTP - initialDelaySeconds: 45 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 5 - resources: {} - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - dnsPolicy: ClusterFirst - restartPolicy: Always - schedulerName: default-scheduler - securityContext: {} - terminationGracePeriodSeconds: 30 - test: false - triggers: - - imageChangeParams: - containerNames: - - spring-petclinic - from: - kind: ImageStreamTag - name: spring-petclinic:latest - namespace: pipeline-demo - type: ImageChange - --- - apiVersion: v1 - kind: Service - metadata: - labels: - app: spring-petclinic - name: spring-petclinic - spec: - ports: - - name: 8080-tcp - port: 8080 - protocol: TCP - targetPort: 8080 - - name: 8443-tcp - port: 8443 - protocol: TCP - targetPort: 8443 - - name: 8778-tcp - port: 8778 - protocol: TCP - targetPort: 8778 - selector: - app: spring-petclinic - deploymentconfig: spring-petclinic - sessionAffinity: None - type: ClusterIP - --- - apiVersion: route.openshift.io/v1 - kind: Route - metadata: - labels: - app: spring-petclinic - name: spring-petclinic - spec: - port: - targetPort: 8080-tcp - to: - kind: Service - name: spring-petclinic - weight: 100 -#+end_src - -*** The tasks -:PROPERTIES: -:CUSTOM_ID: h:9abbbf9d-553a-40a6-b9b1-bee2fc250f4e -:END: - -- ~openshift-client~ from the [[https://github.com/tektoncd/catalog/][upstream catalog]] (see [[https://raw.githubusercontent.com/tektoncd/catalog/658c021e86ce45c9396031a98df32ee50d2dc19e/openshift-client/openshift-client-task.yaml][here]]) - #+begin_src yaml :tangle openshift-commons/task-openshift-client.yaml - apiVersion: tekton.dev/v1alpha1 - kind: Task - metadata: - name: openshift-client - spec: - inputs: - params: - - name: ARGS - description: The OpenShift CLI arguments to run - default: help - steps: - - name: oc - image: quay.io/openshift-pipeline/openshift-cli:0.5.0 - command: ["/usr/local/bin/oc"] - args: - - "${inputs.params.ARGS}" - #+end_src - -- ~s2i-java~ from our [[https://github.com/openshift/pipelines-catalog/][downstream catalog]] (see [[https://raw.githubusercontent.com/openshift/pipelines-catalog/master/s2i-java-8/s2i-java-8-task.yaml][here]]) - #+begin_src yaml :tangle openshift-commons/task-s2i-java-8.yaml - apiVersion: tekton.dev/v1alpha1 - kind: Task - metadata: - name: s2i-java-8 - spec: - inputs: - resources: - - name: source - type: git - params: - - name: PATH_CONTEXT - description: The location of the path to run s2i from. - default: . - - name: TLSVERIFY - description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) - default: "true" - outputs: - resources: - - name: image - type: image - steps: - - name: generate - image: quay.io/openshift-pipeline/s2i - workingdir: /workspace/source - command: ['s2i', 'build', '${inputs.params.PATH_CONTEXT}', 'registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift', '--image-scripts-url', 'image:///usr/local/s2i', '--as-dockerfile', '/gen-source/Dockerfile.gen'] - volumeMounts: - - name: gen-source - mountPath: /gen-source - - name: build - image: quay.io/buildah/stable - workingdir: /gen-source - command: ['buildah', 'bud', '--tls-verify=${inputs.params.TLSVERIFY}', '--layers', '-f', '/gen-source/Dockerfile.gen', '-t', '${outputs.resources.image.url}', '.'] - volumeMounts: - - name: varlibcontainers - mountPath: /var/lib/containers - - name: gen-source - mountPath: /gen-source - securityContext: - privileged: true - - name: push - image: quay.io/buildah/stable - command: ['buildah', 'push', '--tls-verify=${inputs.params.TLSVERIFY}', '${outputs.resources.image.url}', 'docker://${outputs.resources.image.url}'] - volumeMounts: - - name: varlibcontainers - mountPath: /var/lib/containers - securityContext: - privileged: true - volumes: - - name: varlibcontainers - emptyDir: {} - - name: gen-source - emptyDir: {} - #+end_src - -*** The pipeline -:PROPERTIES: -:CUSTOM_ID: h:6d4e1c61-9ae8-46f9-8917-e4a99ae59d2b -:END: - -A pipeline defines a number of tasks that should be executed and how they interact with -each other via their inputs and outputs. - -Here is the YAML file that represents the above pipeline: - -#+begin_src yaml :tangle openshift-commons/pipeline-petclinic-deploy.yaml - apiVersion: tekton.dev/v1alpha1 - kind: Pipeline - metadata: - name: petclinic-deploy-pipeline - spec: - resources: - - name: app-git - type: git - - name: app-image - type: image - tasks: - - name: build - taskRef: - name: s2i-java-8 - params: - - name: TLSVERIFY - value: "false" - resources: - inputs: - - name: source - resource: app-git - outputs: - - name: image - resource: app-image - - name: deploy - taskRef: - name: openshift-client - runAfter: - - build - params: - - name: ARGS - value: "rollout latest spring-petclinic" -#+end_src - - This pipeline performs the following: - 1. Clones the source code of the application from a Git repository (~app-git~ resource) - 3. Builds the container image using the ~s2i-java-8~ task that generates a Dockerfile for the application and uses [[https://buildah.io/][Buildah]] to build the image - 4. The application image is pushed to an image registry (~app-image~ resource) - 5. The new application image is deployed on OpenShift using the ~openshift-cli~ - - You might have noticed that there are no references to the PetClinic Git repository and - its image in the registry. That's because ~Pipeline~s in Tekton are designed to be - generic and re-usable across environments and stages through the application's - lifecycle. ~Pipeline~s abstract away the specifics of the Git source repository and image - to be produced as ~resource~s. When triggering a pipeline, you can provide different Git - repositories and image registries to be used during pipeline execution. Be patient! You - will do that in a little bit in the next section. - -*** The resources -:PROPERTIES: -:CUSTOM_ID: h:3f4a9686-427f-455d-9fd3-aa3741bf089d -:END: - -Now that the pipeline is created, you can trigger it to execute the tasks specified in the -pipeline. Triggering pipelines is an area that is under development and in the next -release it will be possible to be done via the OpenShift web console and Tekton CLI. In -this tutorial, you will trigger the pipeline through creating the Kubernetes objects (the -hard way!) in order to learn the mechanics of triggering. - -First, you should create a number of ~PipelineResource~s that contain the specifics of the -Git repository and image registry to be used in the pipeline during execution. Expectedly, -these are also reusable across multiple pipelines. - -#+begin_src yaml :tangle openshift-commons/resources.yaml - --- - apiVersion: tekton.dev/v1alpha1 - kind: PipelineResource - metadata: - name: petclinic-image - spec: - type: image - params: - - name: url - value: image-registry.openshift-image-registry.svc:5000/pipeline-demo/spring-petclinic - --- - apiVersion: tekton.dev/v1alpha1 - kind: PipelineResource - metadata: - name: petclinic-git - spec: - type: git - params: - - name: url - value: https://github.com/spring-projects/spring-petclinic -#+end_src - -*** Run the pipeline -:PROPERTIES: -:CUSTOM_ID: h:c3372a6a-f189-4029-a5ba-a40193dd42bd -:END: - -A ~PipelineRun~ is how you can start a pipeline and tie it to the Git and image resources -that should be used for this specific invocation. You can start the pipeline using the -CLI: - -#+begin_src bash - tkn pipeline start petclinic-deploy-pipeline \ - -r app-git=petclinic-git \ - -r app-image=petclinic-image \ - -s pipeline -#+end_src - -*** ~tkn~ features -:PROPERTIES: -:CUSTOM_ID: h:d33b093d-e6f0-4601-a9e6-0a669a4dcc2c -:END: - -#+begin_src bash - tkn pipeline logs -f - tkn pipeline start petclinic-deploy-pipeline --last - - tkn resource list - tkn task list - tkn taskrun list - tkn pipeline list - tkn pipelinerun list - - # same with logs, descibe, … -#+end_src - -** Additionnals Tasks and Pipeline -:PROPERTIES: -:CUSTOM_ID: h:dc6a9055-eefc-4029-97c1-aab98f2147a0 -:END: -*** Tasks -:PROPERTIES: -:CUSTOM_ID: h:b5add1e6-379f-4442-87b9-d8800ef38481 -:END: -#+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: Task - metadata: - name: golangci-lint - spec: - inputs: - params: - - name: package - description: base package (and its children) under validation - - name: flags - description: flags to use for the test command - default: --verbose - - name: version - default: golangci-lint version to use - default: "v1.17.1" - - name: GOOS - description: "running operating system target" - default: linux - - name: GOARCH - description: "running architecture target" - default: amd64 - - name: GO111MODULE - description: "value of module support" - default: auto - resources: - - name: source - type: git - targetPath: src/${inputs.params.package} - steps: - - name: lint - image: golangci/golangci-lint:${inputs.params.version} - workingdir: /workspace/src/${inputs.params.package} - command: - - /bin/bash - args: - - -c - - "golangci-lint run ${inputs.params.flags}" - env: - - name: GOPATH - value: /workspace - - name: GOOS - value: "${inputs.params.GOOS}" - - name: GOARCH - value: "${inputs.params.GOARCH}" - - name: GO111MODULE - value: "${inputs.params.GO111MODULE}" - --- - apiVersion: tekton.dev/v1alpha1 - kind: Task - metadata: - name: golang-test - spec: - inputs: - params: - - name: package - description: package (and its children) under test - - name: packages - description: "packages to test (default: ./...)" - default: "./..." - - name: version - description: golang version to use for tests - default: "1.12" - - name: flags - description: flags to use for the test command - default: -race -cover -v - - name: GOOS - description: "running program's operating system target" - default: linux - - name: GOARCH - description: "running program's architecture target" - default: amd64 - - name: GO111MODULE - description: "value of module support" - default: auto - resources: - - name: source - type: git - targetPath: src/${inputs.params.package} - steps: - - name: unit-test - image: golang:${inputs.params.version} - workingdir: /workspace/src/${inputs.params.package} - command: - - /bin/bash - args: - - -c - - "go test ${inputs.params.flags} ${inputs.params.packages}" - env: - - name: GOPATH - value: /workspace - - name: GOOS - value: "${inputs.params.GOOS}" - - name: GOARCH - value: "${inputs.params.GOARCH}" - - name: GO111MODULE - value: "${inputs.params.GO111MODULE}" - --- - apiVersion: tekton.dev/v1alpha1 - kind: Task - metadata: - name: golang-build - spec: - inputs: - params: - - name: package - description: base package to build in - - name: packages - description: "packages to build (default: ./cmd/...)" - default: "./cmd/..." - - name: version - description: golang version to use for builds - default: "1.12" - - name: flags - description: flags to use for the test command - default: -v - - name: GOOS - description: "running program's operating system target" - default: linux - - name: GOARCH - description: "running program's architecture target" - default: amd64 - - name: GO111MODULE - description: "value of module support" - default: auto - resources: - - name: source - type: git - targetPath: src/${inputs.params.package} - steps: - - name: build - image: golang:${inputs.params.version} - workingdir: /workspace/src/${inputs.params.package} - command: - - /bin/bash - args: - - -c - - "go build ${inputs.params.flags} ${inputs.params.packages}" - env: - - name: GOPATH - value: /workspace - - name: GOOS - value: "${inputs.params.GOOS}" - - name: GOARCH - value: "${inputs.params.GOARCH}" - - name: GO111MODULE - value: "${inputs.params.GO111MODULE}" -#+end_src - -*** Pipelines -:PROPERTIES: -:CUSTOM_ID: h:d29b2a8c-c139-49ec-9d1c-8c40ffd7983e -:END: - -#+begin_src yaml - --- - apiVersion: tekton.dev/v1alpha1 - kind: Pipeline - metadata: - name: cli-build-pipeline - spec: - params: - - name: package - description: package to release - default: github.com/tektoncd/cli - resources: - - name: source-repo - type: git - tasks: - - name: lint - taskRef: - name: golangci-lint - params: - - name: package - value: ${params.package} - - name: flags - value: -v - resources: - inputs: - - name: source - resource: source-repo - - name: unit-tests - runAfter: [lint] - taskRef: - name: golang-test - params: - - name: package - value: ${params.package} - resources: - inputs: - - name: source - resource: source-repo - - name: build - runAfter: [lint] - taskRef: - name: golang-build - params: - - name: package - value: ${params.package} - resources: - inputs: - - name: source - resource: source-repo -#+end_src - -*** Resources -:PROPERTIES: -:CUSTOM_ID: h:04951c0d-64e7-43b7-aac4-37a383ad18e5 -:END: - -#+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: PipelineResource - metadata: - name: tektoncd-cli-git - spec: - type: git - params: - - name: revision - value: master - - name: url - value: https://github.com/tektoncd/cli -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/app.yaml b/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/app.yaml @@ -1,125 +0,0 @@ ---- -apiVersion: image.openshift.io/v1 -kind: ImageStream -metadata: - labels: - app: spring-petclinic - name: spring-petclinic ---- -apiVersion: apps.openshift.io/v1 -kind: DeploymentConfig -metadata: - labels: - app: spring-petclinic - name: spring-petclinic -spec: - replicas: 1 - revisionHistoryLimit: 10 - selector: - app: spring-petclinic - deploymentconfig: spring-petclinic - strategy: - activeDeadlineSeconds: 21600 - resources: {} - rollingParams: - intervalSeconds: 1 - maxSurge: 25% - maxUnavailable: 25% - timeoutSeconds: 600 - updatePeriodSeconds: 1 - type: Rolling - template: - metadata: - labels: - app: spring-petclinic - deploymentconfig: spring-petclinic - spec: - containers: - - image: spring-petclinic:latest - imagePullPolicy: Always - livenessProbe: - failureThreshold: 3 - httpGet: - path: / - port: 8080 - scheme: HTTP - initialDelaySeconds: 45 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - name: spring-petclinic - ports: - - containerPort: 8080 - protocol: TCP - - containerPort: 8443 - protocol: TCP - - containerPort: 8778 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: / - port: 8080 - scheme: HTTP - initialDelaySeconds: 45 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 5 - resources: {} - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - dnsPolicy: ClusterFirst - restartPolicy: Always - schedulerName: default-scheduler - securityContext: {} - terminationGracePeriodSeconds: 30 - test: false - triggers: - - imageChangeParams: - containerNames: - - spring-petclinic - from: - kind: ImageStreamTag - name: spring-petclinic:latest - namespace: pipeline-demo - type: ImageChange ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: spring-petclinic - name: spring-petclinic -spec: - ports: - - name: 8080-tcp - port: 8080 - protocol: TCP - targetPort: 8080 - - name: 8443-tcp - port: 8443 - protocol: TCP - targetPort: 8443 - - name: 8778-tcp - port: 8778 - protocol: TCP - targetPort: 8778 - selector: - app: spring-petclinic - deploymentconfig: spring-petclinic - sessionAffinity: None - type: ClusterIP ---- -apiVersion: route.openshift.io/v1 -kind: Route -metadata: - labels: - app: spring-petclinic - name: spring-petclinic -spec: - port: - targetPort: 8080-tcp - to: - kind: Service - name: spring-petclinic - weight: 100 diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/pipeline-petclinic-deploy.yaml b/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/pipeline-petclinic-deploy.yaml @@ -1,32 +0,0 @@ -apiVersion: tekton.dev/v1alpha1 -kind: Pipeline -metadata: - name: petclinic-deploy-pipeline -spec: - resources: - - name: app-git - type: git - - name: app-image - type: image - tasks: - - name: build - taskRef: - name: s2i-java-8 - params: - - name: TLSVERIFY - value: "false" - resources: - inputs: - - name: source - resource: app-git - outputs: - - name: image - resource: app-image - - name: deploy - taskRef: - name: openshift-client - runAfter: - - build - params: - - name: ARGS - value: "rollout latest spring-petclinic" diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/resources.yaml b/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/resources.yaml @@ -1,20 +0,0 @@ ---- -apiVersion: tekton.dev/v1alpha1 -kind: PipelineResource -metadata: - name: petclinic-image -spec: - type: image - params: - - name: url - value: image-registry.openshift-image-registry.svc:5000/pipeline-demo/spring-petclinic ---- -apiVersion: tekton.dev/v1alpha1 -kind: PipelineResource -metadata: - name: petclinic-git -spec: - type: git - params: - - name: url - value: https://github.com/spring-projects/spring-petclinic diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/task-openshift-client.yaml b/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/task-openshift-client.yaml @@ -1,16 +0,0 @@ -apiVersion: tekton.dev/v1alpha1 -kind: Task -metadata: - name: openshift-client -spec: - inputs: - params: - - name: ARGS - description: The OpenShift CLI arguments to run - default: help - steps: - - name: oc - image: quay.io/openshift-pipeline/openshift-cli:0.5.0 - command: ["/usr/local/bin/oc"] - args: - - "${inputs.params.ARGS}" diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/task-s2i-java-8.yaml b/www/vincent.demeester.fr/content/legacy/articles/openshift-commons/task-s2i-java-8.yaml @@ -1,52 +0,0 @@ -apiVersion: tekton.dev/v1alpha1 -kind: Task -metadata: - name: s2i-java-8 -spec: - inputs: - resources: - - name: source - type: git - params: - - name: PATH_CONTEXT - description: The location of the path to run s2i from. - default: . - - name: TLSVERIFY - description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) - default: "true" - outputs: - resources: - - name: image - type: image - steps: - - name: generate - image: quay.io/openshift-pipeline/s2i - workingdir: /workspace/source - command: ['s2i', 'build', '${inputs.params.PATH_CONTEXT}', 'registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift', '--image-scripts-url', 'image:///usr/local/s2i', '--as-dockerfile', '/gen-source/Dockerfile.gen'] - volumeMounts: - - name: gen-source - mountPath: /gen-source - - name: build - image: quay.io/buildah/stable - workingdir: /gen-source - command: ['buildah', 'bud', '--tls-verify=${inputs.params.TLSVERIFY}', '--layers', '-f', '/gen-source/Dockerfile.gen', '-t', '${outputs.resources.image.url}', '.'] - volumeMounts: - - name: varlibcontainers - mountPath: /var/lib/containers - - name: gen-source - mountPath: /gen-source - securityContext: - privileged: true - - name: push - image: quay.io/buildah/stable - command: ['buildah', 'push', '--tls-verify=${inputs.params.TLSVERIFY}', '${outputs.resources.image.url}', 'docker://${outputs.resources.image.url}'] - volumeMounts: - - name: varlibcontainers - mountPath: /var/lib/containers - securityContext: - privileged: true - volumes: - - name: varlibcontainers - emptyDir: {} - - name: gen-source - emptyDir: {} diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift.org b/www/vincent.demeester.fr/content/legacy/articles/openshift.org @@ -1,119 +0,0 @@ - -#+TITLE: OpenShift - -It is primarily built by [[file:red_hat.org][Red Hat]]. - -* Projects around OpenShift - -- [[file:openshift_pipeline.org][OpenShift Pipeline]] - -* Provisioning - -One of my goal is to have a local OpenShift cluster that I use daily — I really like the -idea of [[file:dogfooding.org][dogfooding]]. There is multiple ways to provision OpenShift, but as we are going to -run it locally (because it costs less 🙃), we are going to try to using =libvirt= and the -[[https://github.com/openshift/installer/][installer]] /or/ on bare metal. Note that we can use the /bare metal/ setup on libvirt -virtual machines that are managed outside of the OpenShift scope using the [[https://github.com/openshift/installer/blob/master/docs/user/metal/install_upi.md][User Provided -Infrastructure]]. Let's try this : [[file:openshift_on_vm_bare_metal.org][OpenShift on VM Bare metal]]. - -For OpenShift, I'll stick with [[file:red_hat.org][Red Hat]] usual setup, aka using CentOS or RHEL 😉. - -* Identity providers - -#+begin_quote -For users to interact with OpenShift Container Platform, they must first authenticate to -the cluster. The authentication layer identifies the user associated with requests to the -OpenShift Container Platform API. The authorization layer then uses information about the -requesting user to determine if the request is allowed. - -[…] - -The OpenShift Container Platform master includes a built-in OAuth server. Developers and -administrators obtain OAuth access tokens to authenticate themselves to the API. -#+end_quote - -Identity providers are the way to create user in an OpenShift cluster. There is a bunch -that exists, but we will only look at the following. - -#+TOC: headlines 1 local - -** HTPasswd - -*** create - -#+begin_quote -Configure the htpasswd identity provider to validate user names and passwords against a -flat file generated using htpasswd. -#+end_quote - -- Create or update your flat file with a user name and hashed password: - #+begin_src bash - $ htpasswd -c -B -b </path/to/users.htpasswd> <user_name> <password> - #+end_src - -- Create the htpasswd secret - #+begin_src bash - $ oc create secret generic htpass-secret --from-file=htpasswd=</path/to/users.htpasswd> -n openshift-config - #+end_src - -- Create an HTPasswd CR - #+begin_src yaml - apiVersion: config.openshift.io/v1 - kind: OAuth - metadata: - name: cluster - spec: - identityProviders: - - name: my_htpasswd_provider - mappingMethod: claim - type: HTPasswd - htpasswd: - fileData: - name: htpass-secret - #+end_src - -*** update - -In order to update the users of an htpasswd identity provider: - -- Get the secret content - #+begin_src bash - $ oc get secret htpass-secret -ojsonpath={.data.htpasswd} -n openshift-config | base64 -d > users.htpasswd - #+end_src -- Add or remove a user - #+begin_src bash - # Add - $ htpasswd -bB users.htpasswd <username> <password> - # Remove - $ htpasswd -D users.htpasswd <username> - #+end_src -- Replace the =htpass-secret= - #+begin_src bash - $ oc create secret generic htpass-secret --from-file=htpasswd=users.htpasswd --dry-run -o yaml -n openshift-config | oc replace -f - - #+end_src -- /note:/ If you removed one or more users, you must additionally remove existing resources - for each user. - #+begin_src bash - # Delete the user - $ oc delete user <username> - # Delete the user identity - $ oc delete identity my_htpasswd_provider:<username> - #+end_src - -** GitHub - -#+begin_quote -Configure a github identity provider to validate user names and passwords against GitHub -or GitHub Enterprise’s OAuth authentication server. -#+end_quote - -See [[https://docs.openshift.com/container-platform/4.5/authentication/identity_providers/configuring-github-identity-provider.html][Configuring a GitHub or GitHub Enterprise identity provider - Configuring identity providers | Authentication and authorization | OpenShift Container Platform 4.5]]. - -** GitLab - -#+begin_quote -Configure a gitlab identity provider to use GitLab.com or any other GitLab instance as an -identity provider. -#+end_quote - -See [[https://docs.openshift.com/container-platform/4.5/authentication/identity_providers/configuring-gitlab-identity-provider.html#configuring-gitlab-identity-provider][Configuring a GitLab identity provider - Configuring identity providers | Authentication and authorization | OpenShift Container Platform 4.5]]. diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift_on_vm_bare_metal.org b/www/vincent.demeester.fr/content/legacy/articles/openshift_on_vm_bare_metal.org @@ -1,211 +0,0 @@ - -#+TITLE: OpenShift on VM Bare metal - -Let's try to install OpenShift 4 on bare metal, where bare metal is virtual machine -managed outside of OpenShift reach. We are trying to follow the [[https://docs.openshift.com/container-platform/4.4/installing/installing_bare_metal/installing-bare-metal.html][OpenShift Install on Bare -metal]] official documentation as much as possible. - -#+TOC: headlines 2 - -* Prerequisites - - -In my [[file:infrastructure.org][infrastructure]] I do have at my disposal 2 machines that both have libvirt (qemu+kvm) -enabled (with nested virtualization support even 😝). - -- okinawa: 8 cores, 32GiB memory -- wakasu: 8 cores, 64GiB memory - -Because we are going to install the machine /bare metal/ on virtual machine, some -assumptions are made (see [[file:infrastructure.org][Infrastructure]] on those). - -- VMs are created using a pre-defined Mac address, and the DHCP server on the network - assign them a static IP (based on the mac address). -- This allows to create _ahead_ of time DNS entries on the network so that the bootstrap - and the cluster can find its own by domain name. - -My /home/ network is using =home= as domain name tld. So VMs will be =vm1.home=, … and for -the ocp cluster, /aliased/ with =ocp.home=. We will have 3 master and 5 workers 🙃. The -DNS entry looks more or less like - -#+begin_src text -;; Load balancer -vm0.home. IN A 192.168.1.120 -api.ocp.home. IN A 192.168.1.120 -api-int.ocp.home. IN A 192.168.1.120 -,*.apps.ocp.home. IN A 192.168.1.120 - -;; Masters -vm1.home. IN A 192.168.1.121 -master1.ocp.home. IN A 192.168.1.121 -vm2.home. IN A 192.168.1.122 -master2.ocp.home. IN A 192.168.1.122 -vm3.home. IN A 192.168.1.123 -master3.ocp.home. IN A 192.168.1.123 - -;; Workers -vm4.home. IN A 192.168.1.124 -worker1.ocp.home. IN A 192.168.1.124 -vm5.home. IN A 192.168.1.125 -worker2.ocp.home. IN A 192.168.1.125 -vm6.home. IN A 192.168.1.126 -worker3.ocp.home. IN A 192.168.1.126 -vm7.home. IN A 192.168.1.127 -worker4.ocp.home. IN A 192.168.1.127 -vm8.home. IN A 192.168.1.128 -worker5.ocp.home. IN A 192.168.1.128 - -;; Bootstrap machine -vm9.home. IN A 192.168.1.129 -bootstrap.ocp.home. IN A 192.168.1.129 - -;; etcd records -etcd-0.ocp.home. IN A 192.168.1.121 -etcd-1.ocp.home. IN A 192.168.1.122 -etcd-2.ocp.home. IN A 192.168.1.123 -_etcd-server-ssl._tcp.ocp.home. IN SRV 0 10 2380 etcd-0.ocp.home. -_etcd-server-ssl._tcp.ocp.home. IN SRV 0 10 2380 etcd-1.ocp.home. -_etcd-server-ssl._tcp.ocp.home. IN SRV 0 10 2380 etcd-2.ocp.haome. -#+end_src - -As you can see, aside from the 3 masters and the 5 workers, we will have a load-balancer -VM as documented in the official documentation. - -For reference, VMs Mac address compared to their IP. - -| MAC address | IP | Name | -| 52:54:00:dd:a3:20 | 192.168.1.120 | VM0 | -| 52:54:00:dd:a3:21 | 192.168.1.121 | VM1 | -| 52:54:00:dd:a3:22 | 192.168.1.122 | VM2 | -| 52:54:00:dd:a3:23 | 192.168.1.123 | VM3 | -| 52:54:00:dd:a3:24 | 192.168.1.124 | VM4 | -| 52:54:00:dd:a3:25 | 192.168.1.125 | VM5 | -| 52:54:00:dd:a3:26 | 192.168.1.126 | VM6 | -| 52:54:00:dd:a3:27 | 192.168.1.127 | VM7 | -| 52:54:00:dd:a3:28 | 192.168.1.128 | VM8 | -| 52:54:00:dd:a3:29 | 192.168.1.129 | VM9 | - -Although I am tempted to use [[https://github.com/RedHatOfficial/ocp4-helpernode][ocp4-helpernode]], I am going to try to do as much as I can -with my bare hands ✋. -* Provisionning Machines - -We will need to provision some machines, using =virsh=, =virt-install= or whatever works -the best to be honest. This is also gonna be *heavily* based on -[[https://github.com/RedHatOfficial/ocp4-helpernode/blob/master/docs/quickstart-static.md][ocp4-helpernode/quickstart-static.md]]. - -** Bootstraper - -For the bootstrap VM (=vm9=), we can go with any system but, let's follow closely the -quistart and use Centos EL8. The boostraper machine will be on =wakasu= so we will need to -target the libvirt daemon from there. - -#+begin_src shell -export QEMU_URI=qemu+ssh://vincent@wakasu.home/system -virt-install --connect=${QEMU_URI} \ - --name="ocp4-bootstrap" --vcpus=4 --ram=8192 \ - --disk path=/var/lib/libvirt/images/ocp-bootstrap.qcow2,bus=virtio,size=120 \ - --boot menu=on --print-xml > ocp4-bootstrap.xml -virsh --connect=${QEMU_URI} \ - define --file ocp4-bootstrap.xml -#+end_src - -#+RESULTS: - -** Load balancer - -** Master and worker nodes - -Let's group machines between wakasu and okinawa. There will be 2 masters on wakasu and one -on okinawa, 3 workers on wakasu, and 2 on okinawa. - -- =wakasu= - #+begin_src bash :dir ~/var/ocp4 :results raw - export QEMU_URI=qemu+ssh://vincent@wakasu.home/system - virt-install --connect=${QEMU_URI} \ - --name="ocp4-master1" --vcpus=4 --ram=12288 \ - --disk path=/var/lib/libvirt/images/ocp4-master1.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:21 \ - --boot menu=on --print-xml > ocp4-wakasu-master1.xml - virt-install --connect=${QEMU_URI} \ - --name="ocp4-master2" --vcpus=4 --ram=12288 \ - --disk path=/var/lib/libvirt/images/ocp4-master2.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:22 \ - --boot menu=on --print-xml > ocp4-wakasu-master2.xml - virt-install --connect=${QEMU_URI} \ - --name="ocp4-worker1" --vcpus=4 --ram=8192 \ - --disk path=/var/lib/libvirt/images/ocp4-worker1.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:24 \ - --boot menu=on --print-xml > ocp4-wakasu-worker1.xml - virt-install --connect=${QEMU_URI} \ - --name="ocp4-worker2" --vcpus=4 --ram=8192 \ - --disk path=/var/lib/libvirt/images/ocp4-worker2.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:25 \ - --boot menu=on --print-xml > ocp4-wakasu-worker2.xml - virt-install --connect=${QEMU_URI} \ - --name="ocp4-worker3" --vcpus=4 --ram=8192 \ - --disk path=/var/lib/libvirt/images/ocp4-worker3.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:26 \ - --boot menu=on --print-xml > ocp4-wakasu-worker3.xml - for f in ocp4-wakasu-*.xml; do - virsh --connect=${QEMU_URI} define \ - --file $f - done - #+end_src - - #+RESULTS: - Domain ocp4-master1 defined from ocp4-wakasu-master1.xml - - Domain ocp4-master2 defined from ocp4-wakasu-master2.xml - - Domain ocp4-worker1 defined from ocp4-wakasu-worker1.xml - - Domain ocp4-worker2 defined from ocp4-wakasu-worker2.xml - - Domain ocp4-worker3 defined from ocp4-wakasu-worker3.xml - - - -- =okinawa= - #+begin_src bash :dir ~/var/ocp4 :result raw - export QEMU_URI=qemu+ssh://vincent@okinawa.home/system - virt-install --connect=${QEMU_URI} \ - --name="ocp4-master3" --vcpus=4 --ram=12288 \ - --disk path=/var/lib/libvirt/images/ocp4-master3.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:23 \ - --boot menu=on --print-xml > ocp4-okinawa-master1.xml - virt-install --connect=${QEMU_URI} \ - --name="ocp4-worker4" --vcpus=4 --ram=8192 \ - --disk path=/var/lib/libvirt/images/ocp4-worker4.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:27 \ - --boot menu=on --print-xml > ocp4-okinawa-worker1.xml - virt-install --connect=${QEMU_URI} \ - --name="ocp4-worker5" --vcpus=4 --ram=8192 \ - --disk path=/var/lib/libvirt/images/ocp4-worker5.qcow2,bus=virtio,size=120 \ - --os-variant rhel8.0 \ - --network bridge=br1,mac.address=52:54:00:dd:a3:28 \ - --boot menu=on --print-xml > ocp4-okinawa-worker2.xml - for f in ocp4-okinawa-*.xml; do - virsh --connect=${QEMU_URI} define \ - --file $f - done - - #+end_src - - #+RESULTS: - | Domain | ocp4-master3 | defined | from | ocp4-okinawa-master1.xml | - | Domain | ocp4-worker4 | defined | from | ocp4-okinawa-worker1.xml | - | Domain | ocp4-worker5 | defined | from | ocp4-okinawa-worker2.xml | - - -* Links - -- [[https://github.com/RedHatOfficial/ocp4-helpernode][ocp4-helpernode]] -- [[https://www.openshift.com/blog/openshift-4-bare-metal-install-quickstart][OpenShift 4 Bare metal quickstart]] blog post -- [[https://docs.openshift.com/container-platform/4.4/installing/installing_bare_metal/installing-bare-metal.html][OpenShift Install on Bare metal]] official doc diff --git a/www/vincent.demeester.fr/content/legacy/articles/openshift_pipeline.org b/www/vincent.demeester.fr/content/legacy/articles/openshift_pipeline.org @@ -1,9 +0,0 @@ - -#+TITLE: OpenShift Pipeline - -OpenShift Pipeline is [[file:tekton.org][Tekton]] version optimized for [[file:openshift.org][OpenShift]]. It enables you to write -[[file:continuous_integration.org][CI]]/[[file:continuous_deployment.org][CD]] pipelines on [[file:openshift.org][OpenShift]], built by [[file:red_hat.org][Red Hat]]. The *mission* of OpenShift Pipeline is : - -#+begin_quote -to provide the best user experience for building cloud-native CI/CD pipelines on OpenShift -#+end_quote diff --git a/www/vincent.demeester.fr/content/legacy/articles/org_library_of_babel.org b/www/vincent.demeester.fr/content/legacy/articles/org_library_of_babel.org @@ -1,38 +0,0 @@ -#+TITLE: Library of Babel (org-mode) -#+ALIAS: "library of babel" - -This is my [[file:org_mode.org][org-mode]] [[https://orgmode.org/manual/Library-of-Babel.html][Library of Babel]]. - -* File I/O - -** Reading and writing files - -Read the contents of the file at =file=. The =:results vector= and -=:results scalar= header arguments can be used to read the contents of -file as either a table or a string. - -#+name: read -#+begin_src emacs-lisp :var file="" :var format="" - (if (string= format "csv") - (with-temp-buffer - (org-table-import (expand-file-name file) nil) - (org-table-to-lisp)) - (with-temp-buffer - (insert-file-contents (expand-file-name file)) - (buffer-string))) -#+end_src - -Write =data= to a file at =file=. If =data= is a list, then write it -as a table in traditional Org-mode table syntax. - -#+name: write -#+begin_src emacs-lisp :var data="" :var file="" :var ext='() - (flet ((echo (r) (if (stringp r) r (format "%S" r)))) - (with-temp-file file - (case (and (listp data) - (or ext (intern (file-name-extension file)))) - ('tsv (insert (orgtbl-to-tsv data '(:fmt echo)))) - ('csv (insert (orgtbl-to-csv data '(:fmt echo)))) - (t (org-babel-insert-result data))))) - nil -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/articles/org_mode.org b/www/vincent.demeester.fr/content/legacy/articles/org_mode.org @@ -1,100 +0,0 @@ -#+title: org-mode -#+ROAM_ALIAS: "Org" "Org Mode" "OrgMode" - -[[https://orgmode.org][Orgmode]] is the most awesome mode [[file:emacs.org][Emacs]] has. It is a *beast* to master, and the *best -advice* one can get is : /dig in slowly/, use it for tracking your todos or as an outline -and forget about all the super powerful feature it has. Once you are used to the basic -usage, slowly document yourself (using the awesome documentation directly from [[file:emacs.org][Emacs]]) and -enhance your workflow. - -* Workflow - -I've wanted to write about my =org-mode= workflow for a while. I started on my [[https://git.sr.ht/~vdemeester/home/tree/master/docs/emacs.org][monorepo]] -but it's far from complete and the format doesn't really fit the /prose/ I wanted to put -in. I've recently read "[[http://cachestocaches.com/2020/3/my-organized-life/][A Guide to My Organizational Workflow: How to Streamline Your -Life]]" and well, it gave me the will to document it, so here it is : [[file:my_organizational_workflow.org][My Organizational Workflow]]. - -* Babel and the library - -#+begin_quote -The “Library of Babel” is a collection of code blocks. Like a function library, these code -blocks can be called from other Org files. -#+end_quote - -I recently discovered the [[https://orgmode.org/manual/Library-of-Babel.html][Library of Babel]] concept (from [[http://howardism.org/Technical/Emacs/literate-devops.html][Literate DevOps]]), and here is [[file:org_library_of_babel.org][mine]]. - - -* Publishing - -[[https://orgmode.org][Orgmode]] has [[https://orgmode.org/manual/Exporting.html][export]] and [[https://orgmode.org/manual/Publishing.html][publishing]] features. It is very powerful. As a matter of face, I am -using org-mode to [[https://vincent.demeester.fr/posts/2020-03-22-org-mode-website.html][publish this website]], from the [[https://vincent.demeester.fr][index]] to the [[https://vincent.demeester.fr/posts/][posts]], [[https://vincent.demeester.fr/articles/][articles]], … And as a -matter of fact, there is even a page about it : [[file:meta_publishing_this_website.org][publishing this website]]. -* Triage -** TODO https://jingsi.space/post/2017/04/30/org-protocol/ (org-protocol) :org: - :PROPERTIES: - :END: - -** TODO [[https://www.labri.fr/perso/nrougier/GTD/index.html][Get Things Done with Emacs]] -[2020-09-14 Mon 10:59] - -** TODO [[https://karl-voit.at/folder-hierarchy/][My Folder Hierarchy]] -[2020-03-18 Wed 18:19] - -Think about this in the context of Linux only *and* with =dired=. - -- Why :: Archive by date easily, find files easily -- What :: from download (or elsewhere) to =~/desktop/archive=, the rest is only links (or - virtual fs) -- How :: Scripts, links or a fuse filesystem - -*** TODO [[https://karl-voit.at/2020/01/25/avoid-complex-folder-hierarchies/][Don't Do Complex Folder Hierarchies - They Don't Work and This Is Why and What to Do Instead]] -[2020-03-18 Wed 18:19] -** TODO [[http://www.howardism.org/Technical/Emacs/orgmode-wordprocessor.html][Org as a Word Processor]] :org: -[2020-04-01 Wed 18:51] -** TODO [[https://yiming.dev/blog/2018/03/02/my-org-refile-workflow/][My org-refile workflow - Yiming Chen]] :emacs:org: -[2020-05-19 Tue 12:35] -** TODO [[https://writequit.org/articles/emacs-org-mode-generate-ids.html][Emacs Org-mode: Use good header ids!]] :emacs:org: -:PROPERTIES: -:ID: 5af4e0ed-4a2a-4fb3-8d09-91f6499f5ad0 -:END: -[2019-02-02 Sat 17:14] -** TODO [[https://yiufung.net/post/org-mode-hidden-gems-pt1/][Org-mode Hidden Gems - 01 Document Structure]] :emacs:org: -[2019-05-12 Sun 18:43] - -** TODO [[https://yiufung.net/post/org-mode-hidden-gems-pt2/][Org-mode Hidden Gems - 02 Tables]] :emacs:org: -[2019-05-12 Sun 18:43] -** TODO [[https://acidwords.com/posts/2019-12-04-handle-chromium-and-firefox-sessions-with-org-mode.html][#:acid 'words: Handle Chromium & Firefox sessions with org-mode]] -[2019-12-09 Mon 13:48] -** TODO [[https://blog.jethro.dev/posts/org_mode_workflow_preview/][Org-mode Workflow: A Preview - Jethro Kuan]] -[2019-12-27 Fri 11:20] -** TODO [[https://karl-voit.at/2016/12/23/my-org-region-to-property/][UOMF: Easy Entering Values for Org Mode Properties]] :emacs:org: -[2020-01-17 Fri 18:10] - -** TODO [[https://karl-voit.at/2020/01/01/appendorgheading/][UOMF: Logging With Emacs Org Mode]] :emacs:org: -[2020-01-17 Fri 18:10] - -** TODO [[https://mullikine.github.io/posts/custom-org-links/][Custom Org Links // Bodacious Blog]] :emacs:org: -[2020-01-17 Fri 18:11] -** TODO [[https://bzg.fr/en/some-emacs-org-mode-features-you-may-not-know.html/][Org-mode features You May Not Know · Bastien Guerry - Liberté, informatique, choucroute.]] :emacs:org: -[2020-02-08 Sat 16:49] -** TODO [[https://github.com/blaa/orgassist][blaa/orgassist: orgassist is a bot - which handles your appointments, tasks and notes. A remote control for your org-mode directory.]] :emacs:org: -[2020-02-18 Tue 09:47] -** TODO [[https://egli.dev/posts/using-org-mode-for-meeting-minutes/][Using org-mode for meeting minutes • egli.dev]] :emacs:org: -[2020-03-26 Thu 10:38] -** TODO [[https://rgoswami.me/posts/org-note-workflow/][An Orgmode Note Workflow :: Rohit Goswami — Reflections]] :emacs:org: -[2020-05-11 Mon 15:23] - -** TODO [[https://www.baty.net/2018/tracking-my-time-with-org-mode/][Tracking my Time with Org-mode - Jack Baty's weblog]] :emacs:org: -[2020-05-12 Tue 12:28] - -** TODO [[http://cachestocaches.com/2020/3/my-organized-life/][A Guide to My Organizational Workflow: How to Streamline Your Life]] :emacs:org: -[2020-05-14 Thu 15:20] - -** TODO [[https://karl-voit.at/2020/05/03/current-org-files/][UOMF: My Current Org Mode Files and Heading Structure]] :emacs:org: -[2020-05-19 Tue 16:35] -** TODO [[https://jherrlin.github.io/posts/emacs-orgmode-tables/][Emacs Org mode tables | jherrlin]] -[2020-06-26 Fri 18:17] -** TODO [[http://www.howardism.org/Technical/Emacs/getting-boxes-done.html][Getting Boxes Done]] -[2020-06-26 Fri 18:26] -** TODO [[https://blog.aaronbieber.com/2016/11/23/creating-org-mode-structure-templates.html][Creating Org Mode Structure Templates - The Chronicle]] -[2020-09-24 Thu 18:52] diff --git a/www/vincent.demeester.fr/content/legacy/articles/org_roam.org b/www/vincent.demeester.fr/content/legacy/articles/org_roam.org @@ -1,41 +0,0 @@ -#+title: org-roam - -[[https://org-roam.readthedocs.io/][org-roam]] is [[https://roamresearch.com/][roam]] adapted for [[file:org_mode.org][org-mode]] in [[file:emacs.org][emacs]] of course. - -I am trying to use this one as my main knowledge database, with the idea of being able to -publish this at some point. This would, /long-term/, replace the [[https://vincent.demeester.fr/articles/][articles]] part of my -website. - -- [[file:appendix_roam_protocol_org_roam.org][Appendix: Roam Protocol - Org-roam]] -- [[file:roam_research_why_i_love_it_and_how_i_use_it_nat_eliason.org][Roam Research: Why I Love It and How I Use It - Nat Eliason]] - -* Links -** TODO [[https://org-roam.readthedocs.io/en/develop/][Org-Roam: Roam + Org-Mode = ♥]] :emacs:org: -[2020-02-25 Tue 09:56] - - -** TODO [[https://blog.jethro.dev/posts/how_to_take_smart_notes_org/][How To Take Smart Notes With Org-mode · Jethro Kuan]] -[2020-03-04 Wed 18:57] - -** TODO [[https://www.nateliason.com/blog/smart-notes][How to Take Smart Notes: A Step-by-Step Guide - Nat Eliason]] -[2020-03-04 Wed 18:59] - -** TODO [[https://www.nateliason.com/blog/roam][Roam Research: Why I Love It and How I Use It - Nat Eliason]] -[2020-03-04 Wed 19:00] -** TODO [[https://www.ianjones.us/blog/2020-05-05-doom-emacs/][🧠 Own Your Second Brain: Set Up org-roam on Your Own Machine]] :emacs:org: -[2020-05-19 Tue 12:33] -** TODO [[https://dpitt.me/blog/2020/03/zettelkasten/][dpitt.me :: Using Emacs's org-mode As Your Zettelkästen]] :emacs:org: -[2020-04-15 Wed 08:47] -** TODO [[http://www.dansheffler.com/blog/2015-05-05-the-zettelkasten-method/][The Zettelkasten Method]] :zettelkasten: -[2020-01-21 Tue 18:58] - -** TODO [[https://clerestory.netlify.com/zk/][Zettelkästen? | Clerestory]] :zettelkasten: -[2020-01-21 Tue 18:58] - -** TODO [[https://www.lesswrong.com/posts/NfdHG6oHBJ8Qxc26s/the-zettelkasten-method-1][The Zettelkasten Method - LessWrong 2.0]] :zettelkasten: -[2020-01-21 Tue 18:58] -** TODO [[https://www.nateliason.com/blog/roam][Roam Research: Why I Love It and How I Use It - Nat Eliason]] -[2020-06-19 Fri 22:10] - -** TODO [[https://www.reddit.com/r/RoamResearch/comments/eho7de/building_a_second_brain_in_roamand_why_you_might/][Building a Second Brain in Roam...And Why You Might Want To : RoamResearch]] -[2020-06-19 Fri 22:10] diff --git a/www/vincent.demeester.fr/content/legacy/articles/personal_knowledge_base.org b/www/vincent.demeester.fr/content/legacy/articles/personal_knowledge_base.org @@ -1,19 +0,0 @@ - -#+TITLE: Personal knowledge base -#+ROAM_ALIAS: "personal knowledge base" "pkb" - -A personal knowledge base is an electronic tool used to express, capture, and later -retrieve the personal knowledge of an individual. It differs from a traditional database -in that it contains subjective material particular to the owner, that others may not agree -with nor care about (From [[https://en.wikipedia.org/wiki/Personal_knowledge_base][Wikipedia]]). - -* Links - -** [[https://beepb00p.xyz/myinfra-roam.html][Extending my personal infrastructure with a data source | beepb00p]] -[2020-06-11 Thu 16:30] - -I have a frustration around the fact that our personal data is scattered, siloed and -incredibly hard to use for any purposes, not anticipated by the original developers. - -** [[https://tkainrad.dev/posts/managing-my-personal-knowledge-base/][Managing my personal knowledge base · tkainrad]] -[2020-06-12 Fri 18:20] diff --git a/www/vincent.demeester.fr/content/legacy/articles/preseed.cfg b/www/vincent.demeester.fr/content/legacy/articles/preseed.cfg @@ -1,77 +0,0 @@ -### Localization -# Locale sets language and country. -d-i debian-installer/locale string en_US -# Keyboard selection. -d-i keyboard-configuration/layoutcode string fr -d-i keyboard-configuration/modelcode string bepo -d-i keyboard-configuration/variantcode string - -### Network configuration -# netcfg will choose an interface that has link if possible. This makes it -# skip displaying a list if there is more than one interface. -d-i netcfg/choose_interface select auto -# Any hostname and domain names assigned from dhcp take precedence over -# values set here. However, setting the values still prevents the questions -# from being shown, even if values come from dhcp. -d-i netcfg/get_hostname string ubnt1 -d-i netcfg/get_domain string home -# Disable that annoying WEP key dialog. -d-i netcfg/wireless_wep string - -### Mirror settings -d-i mirror/country string manual -d-i mirror/http/hostname string us.archive.ubuntu.com -d-i mirror/http/directory string /ubuntu -d-i mirror/http/proxy string - -### Partitioning -# Encrypt your home directory? -d-i user-setup/encrypt-home boolean false -# Alternatively, you can specify a disk to partition. The device name -# can be given in either devfs or traditional non-devfs format. -d-i partman-auto/disk string /dev/vda -# In addition, you'll need to specify the method to use. -# The presently available methods are: "regular", "lvm" and "crypto" -d-i partman-auto/method string regular -# You can choose from any of the predefined partitioning recipes. -d-i partman-auto/choose_recipe select atomic -# This makes partman automatically partition without confirmation, provided -# that you told it what to do using one of the methods above. -d-i partman-partitioning/confirm_write_new_label boolean true -d-i partman/choose_partition select finish -d-i partman/confirm boolean true -d-i partman/confirm_nooverwrite boolean true - -### Clock and time zone setup -# Controls whether or not the hardware clock is set to UTC. -d-i clock-setup/utc boolean true -# You may set this to any valid setting for $TZ; see the contents of -# /usr/share/zoneinfo/ for valid values. -d-i time/zone string Europe/Paris - -### Account setup -# Skip creation of a root account (normal user account will be able to -# use sudo). -d-i passwd/root-login boolean false - -# To create a normal user account. -d-i passwd/user-fullname string Vincent -d-i passwd/username string vincent -# Normal user's password, either in clear text -# or encrypted using an MD5 hash. -d-i passwd/user-password-crypted password 4d01b93c7d1fd8a8e6200e7e045d73ea - -# This is fairly safe to set, it makes grub install automatically to the MBR -# if no other operating system is detected on the machine. -d-i grub-installer/only_debian boolean true - -### Package selection -d-i tasksel/first multiselect standard -# Individual additional packages to install -d-i pkgsel/include string openssh-server - -### Finishing up the first stage install -# Avoid that last message about the install being complete. -d-i finish-install/reboot_in_progress note -# How do you want to manage upgrades on this system? -d-i pkgsel/update-policy select none diff --git a/www/vincent.demeester.fr/content/legacy/articles/programming.org b/www/vincent.demeester.fr/content/legacy/articles/programming.org @@ -1,220 +0,0 @@ -#+TITLE: Programming -#+SETUPFILE: .setup.org - -* Languages -:PROPERTIES: -:ID: 46a1380a-fce0-4d4c-bc09-4468cd4f6f58 -:END: - -- [[file:go.org][Go]] -- [[file:python.org][Python]] -- [[file:lisp.org][Lisp]] - + [[file:clojure.org][Clojure]] - + [[file:emacs_lisp.org][Emacs Lisp]] -- [[file:rust.org][Rust]] - -* Four principles of software engineering -:PROPERTIES: -:CREATED: [2020-10-12 Mon 10:48] -:END: - -#+begin_quote -Software should be robust. It should be designed to accommodate all -known edge cases. In practice, this means predicting and handling all -known error cases, enumerating and addressing all classes of user -inputs, reasoning about and planning for the performance -characteristics of your program, and so on. - -Software should be reliable. It should be expected to work for an -extended length of time under design conditions without failures. -Ideally, it should work outside of design conditions up to some -threshold. - -Software should also be stable. It should not change in incompatible -or unexpected ways; if it works today it should also work tomorrow. If -it has to change, a plan shall be written. Stakeholders (including -users!) should be given advance notice and should be involved in the -planning stage. - -Finally, software should be simple. Only as many moving parts should -be included as necessary to meet the other three goals. All software -has bugs, but complicated software (1) has more bugs and (2) is more -difficult to diagnose and fix. Note that designing a simple solution -is usually more difficult than designing a complex solution. - -This (short) article is based on a Mastodon post I wrote a few weeks -ago. - -From: [[https://drewdevault.com/2020/10/09/Four-principles-of-software-engineering.html][Four principles of software engineering]] -#+end_quote - -* Programming is terrible - -[[https://programmingisterrible.com/][programming is terrible]] — lessons learned from a life wasted — is a very interesting -website. I've tried to extract a few links from it with my comments in here. - -- [[https://programmingisterrible.com/post/110922879293/stop-blowhard-syndrome][Stop Blowhard Syndrome — programming is terrible]] - Yes, Yes, Yes ! -- [[https://programmingisterrible.com/post/102153932958/how-i-write-software][How I write software — programming is terrible]] - Write boring code ! - - #+BEGIN_QUOTE - My favourite property of good code is boredom. Dull statements one after another, no - surprises, no tricks, no special cases, and absolutely no meta-programming. Boring code is - the easiest to debug, to verify, and to explain. - - Boring code usually doesn’t use global state, has very precise effects, and isn’t strongly - tied to the project it lives in. Boring features like single assignment, where each - variable only holds one object, and not relying on changing the world around it. Boring - code will only do what its asked of it and does not rely on implicit behaviours. - #+END_QUOTE - -- [[https://programmingisterrible.com/post/116698171738/nothing-is-more-indicative-of-a-bullshit-job-than][Nothing is more indicative of a bullshit job than... — programming is terrible]] -- [[https://programmingisterrible.com/post/39420736223/bisecting-programmers][What makes good and what makes bad programmers? — programming is terrible]] - Some thoughs about good/bad programmers — and really, is there good/bad ? -- [[https://programmingisterrible.com/post/173883533613/code-to-debug][Write code that's easy to delete, and easy to... — programming is terrible]] -- [[https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to][Write code that is easy to delete, not easy to... — programming is terrible]] -- [[https://programmingisterrible.com/post/173883533613/code-to-debug][Write code that's easy to delete, and easy to... — programming is terrible]] -- [[https://programmingisterrible.com/post/110292532528/modules-network-microservices][modules + network = microservices — programming is terrible]] -- [[https://programmingisterrible.com/post/162346490883/how-do-you-cut-a-monolith-in-half][How do you cut a monolith in half? — programming is terrible]] - Some thoughts one cutting monolith in several pieces -- [[https://programmingisterrible.com/post/188942142748/scaling-in-the-presence-of-errorsdont-ignore][Scaling in the presence of errors—don’t ignore... — programming is terrible]] - -* Code reviews - -Code review is one extremely powerful tool in a software developer team’s arsenal, yet -it’s often neglected or used in a way that leads to toxic behavior, causing more harm than -good. - -The primary purpose of code review is to make sure that the overall code health of your -project code base is improving over time. All of the tools and processes of code review -are designed to this end. - -An list of code-review article and tools aronud code revîew : [[https://github.com/joho/awesome-code-review][awesome-code-review]]. - -** TODO [[https://dev.to/rfornal/better-code-review-practices-15nb][Better Code Review Practices - DEV Community 👩💻👨💻]] -[2020-01-28 Tue 18:58] - -** TODO [[https://medium.com/palantir/code-review-best-practices-19e02780015f][Code Review Best Practices - Palantir Blog - Medium]] -[2020-01-28 Tue 18:58] - -** TODO [[https://codingsans.com/blog/code-review][Code Review: Create The Culture, Learn The Best Practices | Coding Sans]] -[2020-01-28 Tue 18:58] - -** TODO [[https://google.github.io/eng-practices/review/developer/][The CL author’s guide to getting through code review | eng-practices]] -[2019-10-07 Mon 10:43] - -** TODO [[https://google.github.io/eng-practices/review/reviewer/][How to do a code review | eng-practices]] -[2019-10-07 Mon 10:44] - -** TODO [[https://blog.jez.io/cli-code-review/][Code Review from the Command Line - Bits, Bytes, and Words]] -[2020-09-23 Wed 13:02] - -** TODO [[https://benjamincongdon.me/blog/2021/10/17/Features-of-Excellent-Code-Review-Tools/][Features of Excellent Code Review Tools | Ben Congdon]] -[2021-10-29 Fri 18:03] - -* Pair programming :pair: - -** TODO [[https://martinfowler.com/articles/on-pair-programming.html][On Pair Programming]] -[2020-02-12 Wed 09:21] - -** TODO [[https://chelseatroy.com/2017/04/01/advanced-pair-programming-pairing-remotely/][Advanced Pair Programming: Pairing Remotely – Chelsea Troy]] -[2020-04-21 Tue 18:26] - -** TODO [[https://chelseatroy.com/2017/04/04/advanced-pair-programming-enabling-your-pair/][Advanced Pair Programming: Enabling Your Pair – Chelsea Troy]] -[2020-04-21 Tue 18:26] - -** TODO [[https://chelseatroy.com/2017/04/06/advanced-pair-programming-learning-from-your-pair/][Advanced Pair Programming: Learning From Your Pair – Chelsea Troy]] -[2020-04-21 Tue 18:26] - -** TODO [[https://chelseatroy.com/2016/01/30/remote-pair-programming-best-practices/][Remote Pair Programming: Best Practices – Chelsea Troy]] -[2020-04-21 Tue 18:27] - -** TODO [[https://geshan.com.np/blog/2020/06/pair-programming-benefits-for-your-team/][5 pair programming benefits you should know about]] -[2020-06-23 Tue 17:49] - -* Misc. - -** TODO [[http://karolis.koncevicius.lt/posts/porn_zen_and_vimrc/][Porn, Zen, and .vimrc]] -[2020-09-17 Thu 08:36] - -Could be on it's own entry on editors -** TODO [[https://solovyov.net/blog/2020/higher-order-functions/][Higher-order functions are like inheritance]] -[2020-09-18 Fri 11:29] - - -** TODO [[https://www.arp242.net/comments.html][Good comments are to the point and flow well]] -[2019-12-12 Thu 18:03] -** [[https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction][The Wrong Abstraction — Sandi Metz]] - - A really interesting article about a really good point : sometimes duplication is better - than the wrong abstraction ! - -** [[https://blog.nelhage.com/post/reflections-on-performance/][Reflections on software performance - Made of Bugs]] -[2020-06-06 Sat 12:36] - - -** TODO [[https://medium.com/@johnclarke_82232/mono-or-multi-repo-6c3674142dfc][Mono- or Multi-repo?. One big repo, or lots of smaller repos… | by John Clarke | Medium]] -[2020-08-17 Mon 16:33] - -** TODO [[https://medium.com/@mattklein123/monorepos-please-dont-e9a279be011b][Monorepos: Please don’t!. Here we are at the beginning of 2019… | by Matt Klein | Medium]] -[2020-08-17 Mon 16:33] - -** TODO [[https://understandlegacycode.com/blog/key-points-of-working-effectively-with-legacy-code/][The key points of Working Effectively with Legacy Code — Understand Legacy Code]] -[2020-02-26 Wed 12:20] - -** TODO [[https://trineo.com/blog/2020/01/constraint-driven-development][Constraint Driven Development | Trineo]] -[2020-03-29 Sun 06:15] -** TODO [[https://jameshfisher.com/2014/05/11/your-syntax-highlighter-is-wrong/][Your syntax highlighter is wrong]] -[2019-12-12 Thu 13:35] -** TODO [[https://www.benkuhn.net/syntax][Syntax highlighting is backwards | benkuhn.net]] -[2020-03-02 Mon 17:02] -** TODO [[https://lukeplant.me.uk/blog/posts/why-im-leaving-elm/][Why I’m leaving Elm - lukeplant.me.uk]] -:PROPERTIES: -:ID: 6d0ed84f-6ae3-4f49-90cd-ef19b2d85fc9 -:END: -[2020-04-09 Thu 19:48] -** TODO [[https://andreyorst.gitlab.io/posts/2020-04-29-text-editors/][Text Editors – Andrey Orst]] -[2020-05-14 Thu 12:31] -** TODO [[https://codewithoutrules.com/2020/04/20/productivity-skills/][The secret skills of productive programmers]] -[2020-05-15 Fri 14:33] - -** TODO [[https://codewithoutrules.com/2020/05/14/prepare-losing-job/][How to prepare for losing your programming job]] -[2020-05-15 Fri 14:33] -** TODO [[https://icyphox.sh/blog/simplicity-security/][Simplicity (mostly) guarantees security]] -[2020-05-16 Sat 15:17] -** TODO [[http://themediocreprogrammer.com/build/html/the_mediocre_programmer.html][The Mediocre Programmer]] :#read: -[2020-05-25 Mon 11:10] -** TODO [[https://michaelfeathers.silvrback.com/functional-code-is-honest-code][Michael Feathers - Functional Code is Honest Code]] -[2020-06-23 Tue 17:39] - -** TODO [[https://michaelfeathers.silvrback.com/testing-warranties][Michael Feathers - Testing Warranties]] -[2020-06-23 Tue 17:39] -** TODO [[https://qntm.org/clean][It's probably time to stop recommending Clean Code @ Things Of Interest]] -[2020-06-29 Mon 17:01] -** TODO [[https://tomgamon.com/posts/2020-08-25-dont-marry-your-design/][Don't marry your design after the first date - Tom Gamon]] -[2020-08-26 Wed 16:14] -** TODO [[https://phaazon.net/blog/editors-in-2020][My thoughts about editors in 2020 – phaazon.net]] -[2020-09-07 Mon 10:28] - -Because I think the speed doesn’t matter when programming, I think the most important part to remember here is the comfort: the wrists don’t move and my fingers fly around the keyboard, whatever the speed. -** TODO [[https://noelwelsh.com/posts/2020-07-05-what-and-why-fp.html][Noel Welsh: What Functional Programming Is, What it Isn't, and Why it Matters]] -[2020-09-07 Mon 16:07] -** TODO [[https://josephg.com/blog/3-tribes/][3 tribes of programming]] -[2020-09-23 Wed 12:12] -** TODO [[https://jfmengels.net/safe-dead-code-removal/?lobsters][Safe dead code removal in a pure functional language | jfmengels' blog]] -[2021-01-29 Fri 10:28] - -** TODO [[https://www.unixsheikh.com/articles/code-navigation-design-patterns-and-too-many-functions.html][Code Navigation, Design Patterns, and Too Many Functions]] -[2020-10-27 Tue 16:21] -** TODO [[http://brooker.co.za/blog/2020/06/23/code.html][Code Only Says What it Does - Marc's Blog]] -[2020-10-27 Tue 16:22] -** TODO [[https://joshwcomeau.com/accessibility/hands-free-coding/][Coding with voice dictation using Talon Voice · Josh W Comeau]] -[2020-10-22 Thu 10:50] -** TODO [[https://thereader.mitpress.mit.edu/habits-of-expert-software-designers/][Eight Habits of Expert Software Designers: An Illustrated Guide | The MIT Press Reader]] -[2019-10-10 Thu 14:38] - -** TODO [[https://www.inkandswitch.com/end-user-programming.html][End-user programming]] :inkandswitch: -[2020-02-08 Sat 18:02] -** TODO [[https://8thlight.com/blog/javier-garc%25C3%25ADa/2019/10/29/functional-lessons.html][Functional lessons learnt | 8th Light]] -[2019-11-06 Wed 09:29] diff --git a/www/vincent.demeester.fr/content/legacy/articles/python.org b/www/vincent.demeester.fr/content/legacy/articles/python.org @@ -1,8 +0,0 @@ -#+TITLE: Python - -* Links -** TODO [[https://martinheinz.dev/blog/14][Ultimate Setup for your next Python project]] :python: -[2020-03-29 Sun 16:59] - -** TODO [[https://martinheinz.dev/blog/17][Automating every aspect of your python project]] :docker:python: -[2020-04-02 Thu 17:24] diff --git a/www/vincent.demeester.fr/content/legacy/articles/red_hat.org b/www/vincent.demeester.fr/content/legacy/articles/red_hat.org @@ -1,2 +0,0 @@ -#+TITLE: Red Hat -#+ROAM_ALIAS: "RedHat" diff --git a/www/vincent.demeester.fr/content/legacy/articles/refiling_trees_to_files.org b/www/vincent.demeester.fr/content/legacy/articles/refiling_trees_to_files.org @@ -1,2 +0,0 @@ -#+title: Refiling Trees to Files -#+roam_key: http://www.howardism.org/Technical/Emacs/getting-even-more-boxes-done.html diff --git a/www/vincent.demeester.fr/content/legacy/articles/remote-development.org b/www/vincent.demeester.fr/content/legacy/articles/remote-development.org @@ -1,32 +0,0 @@ -#+TITLE: Remote developement -#+SUBTITLE: Thoughts, documents and resources around remote developement -#+FILETAGS: #work remote developement emacs -#+SETUPFILE: .setup.org - - -/Note: This is more or less taking over [[file:development-machines.org][Development machines made easy.]]/ - -* TODO Goals - -* TODO Emacs - -- Tramp aka local edit, remote execution -- ssh + emacs in terminal aka remote edit, remote execution - -** TODO Challenges - -- Tramp + direnv doesn't work - + Actually it does with a little bit of "magic" - =C-x p c= followed by =eval "$(direnv export bash)" && go build -v ./...= and it just - works, it needs automation though. -- "Slowness" - -Ideas: -- Use remote-tailored commands (write elisp) -- ko nix aware to be able to delegate to builder - - -* TODO Alternatives - -- VSCode -- Vim diff --git a/www/vincent.demeester.fr/content/legacy/articles/remote.org b/www/vincent.demeester.fr/content/legacy/articles/remote.org @@ -1,28 +0,0 @@ -#+TITLE: Remote work -#+SUBTITLE: Thoughts, documents, links and other resource around remote work, its challenges and benefits. -#+FILETAGS: #work remote -#+SETUPFILE: .setup.org -#+ROAM_ALIAS: "Remote" "Remote work" - -Remote work can be hard, especially when it comes to communication, decision taking and -meetings. It is even harder if you work in a team with different timezones. This is more -about invidual remote work, whereas [[file:remote_team.org][remote team]] is more about the team organization. - -* Links - -** TODO [[https://www.bearer.sh/blog/how-to-make-remote-a-success][How to Make Remote a Success | Bearer blog]] :remote: -[2019-12-20 Fri 13:17] - -** TODO [[https://www.joshwcomeau.com/posts/remote-work/][My experience as a remote worker - Josh Comeau's Blog]] :remote: -[2019-12-20 Fri 13:18] - - -** TODO [[https://jezenthomas.com/how-i-work-from-anywhere-in-the-world/][How I Work From Anywhere in the World]] :remote: -[2020-02-07 Fri 17:32] -** TODO [[https://henrikwarne.com/2020/06/09/working-from-home-cons-and-pros/][Working From Home – Cons and Pros | Henrik Warne's blog]] -[2020-06-23 Tue 18:09] -** TODO [[https://snir.dev/blog/remote-async-communication/][Written communication is remote work super power - Snir David Blog]] -[2020-06-24 Wed 10:36] - -** TODO [[https://wickstrom.tech/general/2020/03/13/my-experience-in-working-remotely.html][My Experiences in Working Remotely | Oskar Wickström]] -[2020-05-19 Tue 16:14] diff --git a/www/vincent.demeester.fr/content/legacy/articles/remote_team.org b/www/vincent.demeester.fr/content/legacy/articles/remote_team.org @@ -1,40 +0,0 @@ - -#+TITLE: Remote Team -#+SUBTITLE: How to build successful remote teams (or at least trying to) -#+ROAM_ALIAS: "remote team" - -* Links - -** TODO [[https://www.bearer.sh/blog/how-to-make-remote-a-success][How to Make Remote a Success | Bearer blog]] :remote: -[2019-12-20 Fri 13:17] - -** TODO [[https://doist.com/blog/asynchronous-communication/][Asynchronous Communication: What It Is & Why You Should Care About It]] -[2020-06-18 Thu 18:03] - -** TODO [[https://www.helpscout.com/blog/asynchronous-communication-remote-teams/][What Remote Companies Can Teach About Asynchronous Communication]] -[2020-06-18 Thu 18:04] - -** TODO [[https://zapier.com/learn/remote-work/how-build-culture-remote-team/][How to build culture in a remote team - The ultimate guide to remote work | Zapier]] -[2020-06-18 Thu 18:04] - -remote team - -** TODO [[https://zapier.com/learn/remote-work/how-manage-remote-team/][How to Manage a Remote Team - The ultimate guide to remote work | Zapier]] -[2020-06-18 Thu 18:04] - -** TODO [[https://qz.com/work/1853725/why-asynchronous-communication-works-for-teams/][Why asynchronous communication works for teams — Quartz at Work]] -[2020-06-18 Thu 18:04] - -** TODO [[https://twist.com/remote-work-guides/remote-team-communication][The Art of Async: The Remote Guide to Team Communication | Twist]] -[2020-06-18 Thu 18:04] - -** TODO [[https://doist.com/blog/remote-team-communication-tools/][The Pyramid of Remote Team Communication Tools]] -[2020-06-18 Thu 18:04] -** TODO [[https://increment.com/teams/a-guide-to-distributed-teams/][A guide to distributed teams – Increment: Teams]] -[2020-12-03 Thu 15:15] -** TODO [[https://barehands.substack.com/p/how-to-take-meeting-notes][How to take meeting notes - Beyond Bare Hands]] -[2020-12-03 Thu 15:16] -** TODO [[https://ewintr.nl/articles/2020/a-better-way-to-do-standups/][A Better Way to do Standups]] -[2021-10-15 Fri 16:12] -** TODO [[http://www.alfredo.motta.name/agile-or-waterfall-a-risk-management-perspective/][Agile or Waterfall; a risk management perspective – Alfredo Motta]] -[2020-06-23 Tue 18:08] diff --git a/www/vincent.demeester.fr/content/legacy/articles/roam_research_why_i_love_it_and_how_i_use_it_nat_eliason.org b/www/vincent.demeester.fr/content/legacy/articles/roam_research_why_i_love_it_and_how_i_use_it_nat_eliason.org @@ -1,4 +0,0 @@ -#+title: Roam Research: Why I Love It and How I Use It - Nat Eliason -#+roam_key: https://www.nateliason.com/blog/roam - -I’ve been deeply interested in personal knowledge management for almost 10 years now. diff --git a/www/vincent.demeester.fr/content/legacy/articles/rpi.org b/www/vincent.demeester.fr/content/legacy/articles/rpi.org @@ -1,8 +0,0 @@ -#+TITLE: Raspberry PI - -* NixOS - -- https://rbf.dev/blog/2020/05/custom-nixos-build-for-raspberry-pis/#building-on-nixos-using-nixos-generators -- https://github.com/Robertof/nixos-docker-sd-image-builder -- https://gist.github.com/chrisanthropic/2e6d3645f20da8fd4c1f122113f89c06 -- https://github.com/zupo/nix diff --git a/www/vincent.demeester.fr/content/legacy/articles/runc.org b/www/vincent.demeester.fr/content/legacy/articles/runc.org @@ -1,2 +0,0 @@ - -#+TITLE: runc diff --git a/www/vincent.demeester.fr/content/legacy/articles/rust.org b/www/vincent.demeester.fr/content/legacy/articles/rust.org @@ -1,13 +0,0 @@ -#+TITLE: Rust - -* Links -** TODO [[https://duan.ca/2020/05/07/nix-rust-development/][Naive NixOS Rust Development]] :nixos: -[2020-05-28 Thu 15:56] -** TODO [[https://endler.dev/2020/rust-compile-times/][Tips for Faster Rust Compile Times | Matthias Endler]] -[2020-06-22 Mon 16:48] -** TODO [[http://www.sheshbabu.com/posts/rust-module-system/][Clear explanation of Rust’s module system]] -[2020-07-20 Mon 11:16] -** TODO [[https://joeprevite.com/rust-lang-ecosystem][Understanding the Rust Ecosystem]] -[2020-06-23 Tue 18:06] -** TODO [[http://www.sheshbabu.com/posts/rust-error-handling/][Beginner's guide to Error Handling in Rust]] -[2020-08-20 Thu 16:33] diff --git a/www/vincent.demeester.fr/content/legacy/articles/sandbox.org b/www/vincent.demeester.fr/content/legacy/articles/sandbox.org @@ -1,451 +0,0 @@ -#+TITLE: Emacs org-mode sandbox -#+SUBTITLE: A Clean and Comfort Stylesheet -#+SETUPFILE: .setup.org - -#+BEGIN_abstract - -This article serves as a complete demonstration for my [[file:notes.css][org.css]], a simple and -clean stylesheet for org-exported HTML file. You may switch between the default -style provided by Emacs Org mode, i.e., styles specified in the variable -=org-html-style-default= and my customized stylesheet using the button at the -top left corner. - -#+END_abstract - -#+TOC: headlines 2 - -Hello ~world~ vs =world= 🙃 - -* Demo -:PROPERTIES: -:CUSTOM_ID: sec:demo -:END: -<2015-11-09 Mon 14:41> - -#+BEGIN_QUOTE - -[[http://orgmode.org/][Org mode]] is for keeping notes, maintaining TODO lists, planning projects, -and authoring documents with a fast and effective /plain-text/ system -cite:dominik2003-org. - -#+END_QUOTE - - -We use [[https://en.wikipedia.org/wiki/Lorem_ipsum][Lorem ipsum]] text to demonstrate all elements you would expect to see in -the org-exported HTML pages. Note however that the =.title=, =.subtitle= and -=#postamble= element are not included in this section. - -** TODO Title with TODO - -** DONE Title with DONE - -Some inactive timestamps - -[2019-02-20 Wed 12:03] With time ! - -Let's write some stuff between the two ! - -[2019-02-20 Wed] Without time - -** [#A] Title with Priority - -** Title with Tag :tag0:tag1: - -** Miscellaneous - -#+TOC: headlines 2 local - -*** Table - -#+CAPTION: Table Caption -| \(N\) | \(N^2\) | \(N^3\) | \(N^4\) | \(\sqrt n\) | \(\sqrt[4]N\) | -|-------+---------+---------+---------+-----------+-----------------| -| 1 | 1 | 1 | 1 | 1 | 1 | -| 2 | 4 | 8 | 16 | 1.4142 | 1.1892 | -| 3 | 9 | 27 | 81 | 1.7321 | 1.3161 | -|-------+---------+---------+---------+-----------+-----------------| -#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt(($1))) - -*** List - -**** The ordered list - -1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. -2. Donec et massa sit amet ligula maximus feugiat. -3. Morbi consequat orci et tincidunt sagittis. - -**** Unordered list - -- Aliquam non metus nec elit pellentesque scelerisque. -- In accumsan nunc ac orci varius hendrerit. -- Suspendisse non eros eu nisi finibus maximus. - -**** Unordered checked list [1/3] - -- [X] Aliquam non metus nec elit pellentesque scelerisque. -- [ ] In accumsan nunc ac orci varius hendrerit. -- [ ] Suspendisse non eros eu nisi finibus maximus. - -**** Definition list - -#+BEGIN_aside -This is a side note. If collection is a string, item must also be a string, and is -compared using =strings.Contains()=. If collection is a Map, contains will succeed if item -is a key in the map. -#+END_aside - -- Lorem ipsum :: dolor sit amet, consectetur adipiscing elit. Mauris laoreet - sollicitudin venenatis. Duis sed consequat dolor. -- Etiam feugiat :: pharetra sapien et semper. Nunc ornare lacus sit amet massa - auctor, vitae aliquam eros interdum. Mauris arcu ante, imperdiet vel purus - ac, bibendum faucibus diam. Ut blandit nec mi at ultricies. Donec eget - mattis nisl. In sed nibh felis. Cras quis convallis orci. -- Sed aliquam :: odio sed faucibus aliquam, arcu augue elementum justo, ut - vulputate ligula sem in augue. Maecenas ante felis, pellentesque auctor - semper non, eleifend quis ante. Fusce enim orci, suscipit ac dapibus et, - fermentum eu tortor. Duis in facilisis ante, quis faucibus dolor. Etiam - maximus lorem quis accumsan vehicula. - -**** Drawers - -Still outside the drawer - -:generic: -This is inside the drawer. -:END: - -And an update 😉 - -:update: -This is an update :) -:END: - -After the drawer. - -:Note: -This is a note -:END: -:Info: -This is an info -:END: -:Tip: -This is a tip -:END: -:Warning: -This is a warning -:END: -*** Picture - -#+CAPTION: Demo Picture with Caption -#+ATTR_HTML: :class shadow -[[file:./images/sandbox/pic-demo.png]] - -And a really wide picture. - -#+CAPTION: A really long picture -#+ATTR_HTML: :width 100% -[[file:./images/sandbox/long-img.png]] - -*** Math - -\begin{align} -\mathcal{F}(a) &= \frac{1}{2\pi i}\oint_\gamma \frac{f(z)}{z - a}\,dz\\ -\int_D (\nabla\cdot \mathcal{F})\,dV &=\int_{\partial D}\mathcal{F}\cdot n\, dS -\end{align} - -* Org-mode links :emacs: - -** TODO Host dependent link - -- grep:foo:~/src/github.com/vdemeester -- rg:foo:~/src/github.com/vdemeester - -** Github links - -- gh:vdemeester/ape -- [[gh:knative/build-pipeline#123][A super PR here]] -- gh:knative/build-pipeline#123 - -** ~man~ - -- [[man:tmux][tmux]] -- [[man:git][git]] - -- [[man:git-commit][Manpage for git-commit]] -- [[https://orgmode.org/manual/store_002dlink-protocol.html][The Org Manual: store-link protocol]] - -** Others - -- tag:foo - -- [[git:~/src/github.com/vdemeester/ape/README.md::v0.2.0]] - -* Org-babel - -** ~emacs-lisp~ - -#+begin_src emacs-lisp :exports both :results value drawer -(message "foo is bar") -#+end_src - -#+RESULTS: -:results: -foo is bar -:end: - -** ~go~ - -#+begin_src go :imports '("fmt") :exports both :results value drawer - fmt.Println("Hello, 世界") -#+end_src - -#+RESULTS: -:results: -Hello, 世界 -:end: - -** ~http~ - -#+BEGIN_SRC http :pretty -POST http://httpbin.org/post -Content-Type: application/json - -{ - "key": "value" -} -#+END_SRC - -#+RESULTS: -:results: -{ - "url": "http://httpbin.org/post", - "json": { - "key": "value" - }, - "headers": { - "User-Agent": "curl/7.35.0", - "Host": "httpbin.org", - "Content-Type": "application/json", - "Content-Length": "18", - "Accept": "*/*" - }, - "form": {}, - "files": {}, - "data": "{ \"key\": \"value\"}", - "args": {} -} -:end: - -** ~rust~ - -#+begin_src rust :exports both :results value drawer - fn main() { - let greetings = ["Hello", "Hola", "Bonjour", - "Ciao", "こんにちは", "안녕하세요", - "Cześć", "Olá", "Здравствуйте", - "chào bạn", "您好"]; - - for (num, greeting) in greetings.iter().enumerate() { - print!("{} : ", greeting); - match num { - 0 => println!("This code is editable and runnable!"), - 1 => println!("Este código es editable y ejecutable!"), - 2 => println!("Ce code est modifiable et exécutable!"), - 3 => println!("Questo codice è modificabile ed eseguibile!"), - 4 => println!("このコードは編集して実行出来ます!"), - 5 => println!("여기에서 코드를 수정하고 실행할 수 있습니다!"), - 6 => println!("Ten kod można edytować oraz uruchomić!"), - 7 => println!("Esse código é editável e executável!"), - 8 => println!("Этот код можно отредактировать и запустить!"), - 9 => println!("Bạn có thể edit và run code trực tiếp!"), - 10 => println!("这段代码是可以编辑并且能够运行的!"), - _ => {}, - } - } - } -#+end_src - -#+RESULTS: -:results: -Hello : This code is editable and runnable! -Hola : Este código es editable y ejecutable! -Bonjour : Ce code est modifiable et exécutable! -Ciao : Questo codice è modificabile ed eseguibile! -こんにちは : このコードは編集して実行出来ます! -안녕하세요 : 여기에서 코드를 수정하고 실행할 수 있습니다! -Cześć : Ten kod można edytować oraz uruchomić! -Olá : Esse código é editável e executável! -Здравствуйте : Этот код можно отредактировать и запустить! -chào bạn : Bạn có thể edit và run code trực tiếp! -您好 : 这段代码是可以编辑并且能够运行的! -:end: - -** ~typescript~ - -*** Execute with node.js - -#+BEGIN_SRC typescript :exports both :results value drawer -module Greeting { - export class Hello { - constructor(private text : string) { - } - say() :void{ - console.log(this.text); - } - } -} - -var hello : Greeting.Hello = new Greeting.Hello("Hello, World!"); -hello.say(); -#+END_src - -#+RESULTS: -:results: -Hello, World! -:end: - -*** Transpile - -You can see transpile results by specifying ":wrap SRC js" header argument. - -#+Begin_SRC typescript :exports both :wrap SRC js :results value drawer -module Greeting { - export class Hello { - constructor(private text : string) { - } - say() :void{ - consonle.log(this.text); - } - } -} - -var hello : Greeting.Hello = new Greeting.Hello("Hello, World!"); -hello.say(); -#+END_SRC - -#+RESULTS: -:results: -#+BEGIN_SRC js -var Greeting; -(function (Greeting) { - var Hello = (function () { - function Hello(text) { - this.text = text; - } - Hello.prototype.say = function () { - console.log(this.text); - }; - return Hello; - })(); - Greeting.Hello = Hello; -})(Greeting || (Greeting = {})); -var hello = new Greeting.Hello("Hello, World!"); -hello.say(); -#+END_SRC -:end: - -** Ditaa - -Let's try something with ~ditaa~ - -#+begin_src ditaa :file ./images/sandbox/some_filename.png - +-----------+ +---------+ - | PLC | | | - | Network +<------>+ PLC +<---=---------+ - | cRED | | c707 | | - +-----------+ +----+----+ | - ^ | - | | - | +----------------|-----------------+ - | | | | - v v v v - +----------+ +----+--+--+ +-------+---+ +-----+-----+ Windows clients - | | | | | | | | +----+ +----+ - | Database +<----->+ Shared +<---->+ Executive +<-=-->+ Operator +<---->|cYEL| . . .|cYEL| - | c707 | | Memory | | c707 | | Server | | | | | - +--+----+--+ |{d} cGRE | +------+----+ | c707 | +----+ +----+ - ^ ^ +----------+ ^ +-------+---+ - | | | - | +--------=--------------------------+ - v - +--------+--------+ - | | - | Millwide System | -------- Data --------- - | cBLU | --=----- Signals ---=-- - +-----------------+ -#+end_src - -#+RESULTS: -[[file:./images/sandbox/some_filename.png]] - - -** Graphviz - -** References and labels ! - -foo is bar - -#+BEGIN_SRC emacs-lisp -l "<ref:%s>" -(save-excursion ;; <ref:foo> - (message "this is baz") - (goto-char (point-min)) ;; <ref:bar> -#+END_SRC - -In line [[(foo)]] we remember the current position. [[(bar)][Line (bar)]] jumps to -point-min. - -#+BEGIN_SRC emacs-lisp -n -r -(save-excursion (ref:sc) - (message "this is sparta") - (goto-char (point-min)) (ref:jump) -#+END_SRC - -In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]] jumps to point-min. - - -* Counsel - -/this is italic/ -_this should be underlined_ - -* Known Issues -:PROPERTIES: -:CUSTOM_ID: sec:known-issues -:END: - -The citation exporter, =ox-bibtex=, does NOT work seamlessly. As of =Org-mode -8.3.2=, I have the following issues. - -** +Dangling Element+ :solved: -:PROPERTIES: -:CUSTOM_ID: sec:dangling-element -:END: - -The lisp function =insert-file-contents= used in =ox-bibtex= does not move point -and insertion-marker to the end of inserted text (I'm not sure it is a bug or an -intention). The result is that the citation is a dangling table not included in -the bibliography div. - -The expected result is - -#+BEGIN_SRC html -<div id="bibliography"> - <h2>Bibliography</h2> - <table> - <!-- Citation content goes here --> - </table> -</div> -#+END_SRC - -But we got - -#+BEGIN_SRC html -<div id="bibliography"> - <h2>Bibliography</h2> -</div> -<table> -<!-- Citation content goes here --> -</table> -#+END_SRC - -Unless a patch is submitted, we may need to manually adjust this weird result. diff --git a/www/vincent.demeester.fr/content/legacy/articles/serverless.org b/www/vincent.demeester.fr/content/legacy/articles/serverless.org @@ -1,8 +0,0 @@ -#+TITLE: serverless - -* Links - -** TODO [[https://martinfowler.com/articles/serverless.html][Serverless Architectures]] -[2020-02-12 Wed 09:22] -** TODO [[https://blog.vtemian.com/post/serverless-hosting-platform/][Building a serverless hosting platform]] -[2020-05-18 Mon 19:51] diff --git a/www/vincent.demeester.fr/content/legacy/articles/simple_correct_fast_in_that_order_drew_devault_s_blog.org b/www/vincent.demeester.fr/content/legacy/articles/simple_correct_fast_in_that_order_drew_devault_s_blog.org @@ -1,2 +0,0 @@ -#+title: Simple, correct, fast: in that order | Drew DeVault’s Blog -#+roam_key: https://drewdevault.com/2018/07/09/Simple-correct-fast.html diff --git a/www/vincent.demeester.fr/content/legacy/articles/sitemap.org b/www/vincent.demeester.fr/content/legacy/articles/sitemap.org @@ -1,144 +0,0 @@ -#+TITLE: Articles - -- [[file:feeds.org][My Feeds]] -- [[file:nixos.org][NixOS]] -- [[file:go.org][Go]] -- [[file:github.org][GitHub]] -- [[file:gitlab.org][Gitlab]] -- [[file:meta_publishing_this_website.org][meta: publishing this website]] -- [[file:emacs.org][My Emacs System]] -- [[file:documentation.org][Documentation]] -- [[file:remote-development.org][Remote developement]] -- [[file:bash.org][bash]] -- [[file:development-machines.org][Development machines made easy]] -- [[file:blog.org][Blog]] -- [[file:programming.org][Programming]] -- [[file:linux.org][Linux]] -- [[file:firefox.org][Firefox]] -- [[file:gnupg.org][gnupg]] -- [[file:css.org][Cascading Style Sheets]] -- [[file:org_mode.org][org-mode]] -- [[file:mac.org][Mac (OSX)]] -- [[file:typography.org][Typography]] -- [[file:testing.org][Testing]] -- [[file:rust.org][Rust]] -- [[file:email.org][email]] -- [[file:nix.org][Nix]] -- [[file:infrastructure.org][Infrastructure]] -- [[file:openbsd.org][openbsd]] -- [[file:lisp.org][Lisp]] -- [[file:remote_team.org][Remote Team]] -- [[file:make.org][make]] -- [[file:apis.org][APIs]] -- [[file:book_the_holloway_guide_to_remote_work.org][Book: The Holloway Guide to Remote Work]] -- [[file:tekton-pipeline-without-pipeline-resources.org][Tekton Pipeline : another world without PipelineResources]] -- [[file:tekton-usage.org][Tektoncd usage and examples]] -- [[file:tekton-effective.org][Efficient Pipeline with Tekton]] -- [[file:kubernetes_on_nixos.org][Kubernetes on NixOS]] -- [[file:keyboard.org][Keyboards]] -- [[file:haskell.org][haskell]] -- [[file:tekton.org][Tekton]] -- [[file:containers.org][Containers]] -- [[file:git.org][Git]] -- [[file:org_library_of_babel.org][Library of Babel (org-mode)]] -- [[file:tekton-migrating-from-jenkins.org][Migrating from Jenkins to Tekton]] -- [[file:rpi.org][Raspberry PI]] -- [[file:kubernetes.org][Kubernetes]] -- [[file:gitops.org][GitOps]] -- [[file:emacs.old.org][My Emacs System]] -- [[file:config_configurations.org][Configurations]] -- [[file:clojure.org][Clojure]] -- [[file:remote.org][Remote work]] -- [[file:red_hat.org][Red Hat]] -- [[file:book_the_manager_s_path.org][Book: The Manager's Path]] -- [[file:book_debugging_teams.org][Book: Debugging Teams]] -- [[file:gnus.org][Gnus]] -- [[file:ubuntu.org][Ubuntu]] -- [[file:openshift_on_vm_bare_metal.org][OpenShift on VM Bare metal]] -- [[file:knative.org][Knative]] -- [[file:book_the_checklist_manifesto.org][Book: The Checklist Manifesto]] -- [[file:continuous_integration.org][continuous integration]] -- [[file:moby_project.org][Moby Project]] -- [[file:individual_contributors.org][Individual Contributors]] -- [[file:runc.org][runc]] -- [[file:git_sr_ht.org][git.sr.ht]] -- [[file:book_managing_humans.org][Book: Managing Humans]] -- [[file:architect.org][Architect]] -- [[file:leadership.org][Leadership]] -- [[file:book_a_practical_approach_to_large_scale_agile_development.org][Book: A Practical Approach to Large-Scale Agile Development]] -- [[file:book_the_now_habit.org][Book: The Now habit]] -- [[file:book_work_clean.org][Book: Work Clean]] -- [[file:kubernix.org][kubernix]] -- [[file:book_the_flinch.org][Book: The Flinch]] -- [[file:open_container_initiative.org][Open Container Initiative]] -- [[file:book_sprint.org][Book: Sprint]] -- [[file:how_to_drive_upstream_project.org][How to drive upstream project]] -- [[file:book_living_documentation.org][Book: Living Documentation]] -- [[file:continuous_deployment.org][continuous deployment]] -- [[file:vterm.org][vterm]] -- [[file:book_accelerate.org][Book: Accelerate]] -- [[file:yoga.org][Yoga]] -- [[file:team_lead.org][Team Lead]] -- [[file:book_time_management.org][Book: Time Management]] -- [[file:tekton_dev.org][Tekton development environment]] -- [[file:openshift.org][OpenShift]] -- [[file:openshift_pipeline.org][OpenShift Pipeline]] -- [[file:eshell.org][eshell]] -- [[file:ipfs.org][ipfs]] -- [[file:personal_knowledge_base.org][Personal knowledge base]] -- [[file:nginx.org][nginx]] -- [[file:book_kanban_workbook.org][Book: Kanban Workbook]] -- [[file:git_annex.org][git-annex]] -- [[file:minikube.org][minikube]] -- [[file:book_the_ultimate_guide_to_remote_work.org][Book: The Ultimate Guide To Remote Work]] -- [[file:kind.org][kind]] -- [[file:book_a_practical_guide_to_distributed_scrum.org][Book: A Practical Guide to Distributed Scrum]] -- [[file:book_make_time.org][Book: Make time]] -- [[file:dogfooding.org][dogfooding]] -- [[file:book_sleep_smarter.org][Book: Sleep Smarter]] -- [[file:writing_technical_book.org][Writing a Technical Book]] -- [[file:config_email_configuration.org][config: Email configuration]] -- [[file:internet_of_things.org][Internet of Things]] -- [[file:my_organizational_workflow.org][My Organizational Workflow]] -- [[file:ssh.org][ssh]] -- [[file:meta_meta.org][Meta]] -- [[file:serverless.org][serverless]] -- [[file:python.org][Python]] -- [[file:emacs_appearance.org][emacs: appearance]] -- [[file:notmuch.org][notmuch]] -- [[file:emacs_projects.org][emacs: Managing projects]] -- [[file:emacs_lisp.org][Emacs Lisp]] -- [[file:emacs_keep_it_clean.org][emacs: keep it clean]] -- [[file:zsh.org][zsh]] -- [[file:book_the_holloway_guide_to_equity_compensation.org][Book: The Holloway Guide to Equity Compensation]] -- [[file:sandbox.org][Emacs org-mode sandbox]] -- [[file:org_roam.org][org-roam]] -- [[file:index.org][Articles]] -- [[file:refiling_trees_to_files.org][Refiling Trees to Files]] -- [[file:getting_boxes_done_the_code.org][Getting Boxes Done, the Code]] -- [[file:getting_boxes_done.org][Getting Boxes Done]] -- [[file:fish.org][Fish shell notes]] -- [[file:virtualization.org][Virtualization]] -- [[file:fedora-silverblue.org][Fedora silverblue]] -- [[file:wireguard.org][Wireguard]] -- [[file:yubikey.org][Yubikey setup on Linux]] -- [[file:openshift-commons.org][OpenShift Commons]] -- [[file:fedora.org][Fedora]] -- [[file:libvirt.org][libvirt]] -- [[file:nixos-overlays.org][NixOS overlay notes]] -- [[file:talks.org][Talks]] -- [[file:opendatahub_opendatahub.org][OpenDataHub · OpenDataHub]] -- [[file:empathy_online.org][Empathy Online]] -- [[file:generics_aren_t_ready_for_go_drew_devault_s_blog.org][Generics aren’t ready for Go | Drew DeVault’s Blog]] -- [[file:roam_research_why_i_love_it_and_how_i_use_it_nat_eliason.org][Roam Research: Why I Love It and How I Use It - Nat Eliason]] -- [[file:my_personal_journey_from_mit_to_gpl_drew_devault_s_blog.org][My personal journey from MIT to GPL | Drew DeVault’s Blog]] -- [[file:building_interactive_ssh_applications_drew_devault_s_blog.org][Building interactive SSH applications | Drew DeVault’s Blog]] -- [[file:how_i_decide_between_many_programming_languages_drew_devault_s_blog.org][How I decide between many programming languages | Drew DeVault’s Blog]] -- [[file:a_philosophy_of_project_governance_drew_devault_s_blog.org][A philosophy of project governance | Drew DeVault’s Blog]] -- [[file:add_a_contrib_directory_to_your_projects_drew_devault_s_blog.org][Add a “contrib” directory to your projects | Drew DeVault’s Blog]] -- [[file:opencontainers_artifacts_oci_artifacts.org][opencontainers/artifacts: OCI Artifacts]] -- [[file:opencontainers_distribution_spec_oci_distribution_specification.org][opencontainers/distribution-spec: OCI Distribution Specification]] -- [[file:opencontainers_image_spec_oci_image_format.org][opencontainers/image-spec: OCI Image Format]] -- [[file:opencontainers_runtime_spec_oci_runtime_specification.org][opencontainers/runtime-spec: OCI Runtime Specification]] -- [[file:simple_correct_fast_in_that_order_drew_devault_s_blog.org][Simple, correct, fast: in that order | Drew DeVault’s Blog]] -- [[file:getting_started_with_qemu_drew_devault_s_blog.org][Getting started with qemu | Drew DeVault’s Blog]]- \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/legacy/articles/ssh.org b/www/vincent.demeester.fr/content/legacy/articles/ssh.org @@ -1,12 +0,0 @@ -#+TITLE: ssh - -* Links -** TODO [[https://www.ibm.com/developerworks/aix/library/au-sshlocks/index.html?cmp=dw&cpb=dwaix&ct=dwgra-3SSHlocks&cr=lnxw06&ccy=us][Three locks for your SSH door]] -** TODO [[https://buttondown.email/cryptography-dispatches/archive/cryptography-dispatches-openssh-82-just-works/][Cryptography Dispatches: OpenSSH 8.2 Just Works with U2F/FIDO2 Security Keys • Buttondown]] -[2020-04-28 Tue 01:03] -** TODO [[https://blog.jakuba.net/ssh-tunnel---local-remote-and-dynamic-port-forwarding/][SSH Tunnel - Local, Remote and Dynamic Port Forwarding | Jakub Arnold Blog]] :ssh: -[2020-05-07 Thu 15:12] -** TODO [[https://smallstep.com/blog/ssh-agent-explained/][SSH Agent Explained]] :ssh: -[2020-05-21 Thu 13:07] -** TODO [[https://smallstep.com/blog/ssh-emergency-access/][SSH Emergency Access]] -[2020-07-02 Thu 07:39] diff --git a/www/vincent.demeester.fr/content/legacy/articles/talks.org b/www/vincent.demeester.fr/content/legacy/articles/talks.org @@ -1,11 +0,0 @@ -#+TITLE: Talks -#+FILETAGS: :talk: - -* Resources to write a conference proposal :ATTACH: -:PROPERTIES: -:Attachments: The_Decker_Grid.pdf -:CUSTOM_ID: h:10dc9268-476a-4e22-8220-d476e5c3d638 -:END: - -- [[https://dave.cheney.net/2017/02/12/how-to-write-a-successful-conference-proposal][How to write a successful conference proposal | Dave Cheney]] -- [[https://www.deconstructconf.com/blog/how-to-prepare-a-talk][How to Prepare a Talk – Deconstruct]] diff --git a/www/vincent.demeester.fr/content/legacy/articles/team_lead.org b/www/vincent.demeester.fr/content/legacy/articles/team_lead.org @@ -1,16 +0,0 @@ - -#+TITLE: Team Lead - -* Role at Red Hat (devtools) - -Primary responsibilities -- Serves as Agile Coach and Process Authority for the Scrum team -- Acts as Scrum Master - Run sprint planning calls, reviews and retrospectives -- Work with Product Owner - + Translate features into user stories - + Set and prioritize the team backlog by feature + release schedule priority - + Periodically groom the team backlog per changing conditions -- Provide architectural guidance on user story implementations -- Participate in code reviews -- Triage team bugs -- Individual contributor tasks diff --git a/www/vincent.demeester.fr/content/legacy/articles/tekton-effective.org b/www/vincent.demeester.fr/content/legacy/articles/tekton-effective.org @@ -1,36 +0,0 @@ -#+TITLE: Efficient Pipeline with Tekton -#+SUBTITLE: Diving into the cat's project best practices 🐱 -#+FILETAGS: tektoncd kubernetes ci cd pipeline - -#+begin_abstract -Let's dig into how I to write efficient pipeline with Tekton, following best-practices -#+end_abstract - -#+TOC: headlines 1 - -* TODO Plan - -Open question: should it a set of article ? (like a small book :D) - -* What is Tektoncd ? -:PROPERTIES: -:CUSTOM_ID: h:df5e2667-14ba-44d1-9ea5-789fcd64a202 -:END: - -#+NAME: fig:tektoncd-logo -#+ATTR_ORG: :width 400/600 -#+ATTR_HTML: :width 400/600px -[[file:images/tekton/tekton-horizontal-color.png]] - -#+begin_quote -The Tekton Pipelines project provides Kubernetes-style resources for declaring CI/CD-style pipelines. -#+end_quote - -* TODO Without PipelineResource - -* TODO Use of parameters - -* TODO Ways to pass information from A to B - -* TODO When to use =podTemplate= -* TODO When to use =stepTemplate= diff --git a/www/vincent.demeester.fr/content/legacy/articles/tekton-migrating-from-jenkins.org b/www/vincent.demeester.fr/content/legacy/articles/tekton-migrating-from-jenkins.org @@ -1,2 +0,0 @@ -#+title: Migrating from Jenkins to Tekton -#+filetags: guide tekton jenkins diff --git a/www/vincent.demeester.fr/content/legacy/articles/tekton-pipeline-without-pipeline-resources.org b/www/vincent.demeester.fr/content/legacy/articles/tekton-pipeline-without-pipeline-resources.org @@ -1,1802 +0,0 @@ -#+TITLE: Tekton Pipeline : another world without PipelineResources -#+FILETAGS: tekton #work pipeline pipelineresources -#+CATEGORY: tektoncd - -This document is a refreshed version of [[https://docs.google.com/document/d/1u6qO7CPtDnTOZMYFQ5ARysSOy8lfFeVw83C_5BxAKsw/edit#heading=h.yc5nzf2ze0dr][A world without PipelineResource]] (only accessible -if you are a member of the tekton community) as of =tekton/pipeline= =v0.17.x=. - -* TODO Goal(s) - - -** PipelineResources "problems" -*** PipelineResources extra(s) - -Related issue is [[https://github.com/tektoncd/pipeline/issues/3518][#3518]], but there might be others. It is not currently possible to pass -extra certificates to a =PipelineResource= generated container, making, for example a -self-signed =https= git clone from using =PipelineResource= impossible. This may apply to -additional "extra" that we would want to apply to =PipelineResource= that we can apply to -=Task= (additional volumes, …). -* TODO Examples -:LOGBOOK: -CLOCK: [2020-11-10 Tue 16:25]--[2020-11-10 Tue 17:30] => 1:05 -CLOCK: [2020-11-02 Mon 15:37]--[2020-11-09 Mon 16:57] => 169:20 -CLOCK: [2020-10-30 Fri 15:10]--[2020-10-30 Fri 16:58] => 1:48 -:END: - -The examples in the document are based on the "User stories" list of [[https://docs.google.com/document/d/1h9n0Lod0OiJ_sP2HK8Ms7N04aee5LW8xfz5yMGCFMIs/edit?ts=5f96a3e8#][Tekton Pipeline v1 -API]] document. - -We are going to use the [[https://github.com/tektoncd/catalog][catalog]] task as much as we can. We are also going to use tekton -bundle, that will be available starting from =v0.18.0=. - -** DONE Prerequisite -CLOSED: [2020-11-02 Mon 15:36] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-02 Mon 15:36] -:END: - -Let's bundle some base tasks into a tekton bundle to "ease" of use. - -- =git= - - #+begin_src bash :dir /home/vincent/src/github.com/tektoncd/catalog :result raw - tkn-oci push docker.io/vdemeester/tekton-base-git:v0.1 task/git-clone/0.2/git-clone.yaml task/git-cli/0.1/git-cli.yaml task/git-rebase/0.1/git-rebase.yaml - #+end_src - - -Let's also create a /generic/ PVC for getting source code, … - -#+begin_src yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: testpvc -spec: - accessModes: [ ReadWriteMany ] - storageClassName: standard - resources: - requests: - storage: 1Gi -#+end_src - -** DONE Standard Go Pipeline -CLOSED: [2020-11-02 Mon 15:34] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-02 Mon 15:34] -:END: - -A simple go pipeline is doing the following: -- *linting* using =golangci-lint= - [[https://raw.githubusercontent.com/tektoncd/catalog/master/task/golangci-lint/0.1/golangci-lint.yaml][golangci-lint]] -- *build* using =go build= - [[https://raw.githubusercontent.com/tektoncd/catalog/master/task/golang-build/0.1/golang-build.yaml][golang-build]] -- *testing* using =go test= - [[https://raw.githubusercontent.com/tektoncd/catalog/master/task/golang-test/0.1/golang-test.yaml][golang-test]] - -#+begin_src bash :dir /home/vincent/src/github.com/tektoncd/catalog :result raw -tkn-oci push docker.io/vdemeester/tekton-golang:v0.1 task/golangci-lint/0.1/golangci-lint.yaml task/golang-build/0.1/golang-build.yaml task/golang-test/0.1/golang-test.yaml -#+end_src - -#+begin_src yaml ---- -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: std-golang -spec: - params: - - name: package -#- name: url -# default: https://$(params.package) # that doesn't work - - name: revision - default: "" - workspaces: - - name: ws - tasks: - - name: fetch-repository - taskRef: - name: git-clone - bundle: docker.io/vdemeester/tekton-base-git:v0.1 - workspaces: - - name: output - workspace: ws - params: - - name: url - value: https://$(params.package) - - name: build - taskRef: - name: golang-build - bundle: docker.io/vdemeester/tekton-golang:v0.1 - runAfter: [ fetch-repository ] - params: - - name: package - value: $(params.package) - workspaces: - - name: source - workspace: ws - - name: lint - taskRef: - name: golangci-lint - bundle: docker.io/vdemeester/tekton-golang:v0.1 - runAfter: [ fetch-repository ] - params: - - name: package - value: $(params.package) - workspaces: - - name: source - workspace: ws - - name: test - taskRef: - name: golang-test - bundle: docker.io/vdemeester/tekton-golang:v0.1 - runAfter: [ build, lint ] - params: - - name: package - value: $(params.package) - workspaces: - - name: source - workspace: ws -#+end_src - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - generateName: run-std-go- -spec: - pipelineRef: - name: std-golang - params: - - name: package - value: github.com/tektoncd/pipeline - workspaces: - - name: ws - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteMany - resources: - requests: - storage: 1Gi -#+end_src - -Note: -- =bundle= is duplicated a lot (default bundle would reduce verbosity). -- =params= and =workspaces= are duplicated in there. - /Maybe we could be able to specify workspace to be available for all tasks/ - -** DONE Standard Java Pipeline(s) -CLOSED: [2020-11-02 Mon 17:23] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-02 Mon 17:23] -:END: - -#+begin_src bash :dir /home/vincent/src/github.com/tektoncd/catalog :result raw -tkn-oci push docker.io/vdemeester/tekton-java:v0.1 task/maven/0.2/maven.yaml task/jib-gradle/0.1/jib-gradle.yaml task/jib-maven/0.1/jib-maven.yaml -#+end_src - -*** DONE Prerequisite -CLOSED: [2020-11-02 Mon 16:27] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-02 Mon 16:27] -:END: - -Let's have a =nexus= server running… - -#+begin_src yaml ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: nexus - app.kubernetes.io/instance: nexus - app.kubernetes.io/name: nexus - app.kubernetes.io/part-of: nexus - name: nexus -spec: - replicas: 1 - selector: - matchLabels: - app: nexus - template: - metadata: - labels: - app: nexus - spec: - containers: - - name: nexus - image: docker.io/sonatype/nexus3:3.16.2 - env: - - name: CONTEXT_PATH - value: / - imagePullPolicy: IfNotPresent - ports: - - containerPort: 8081 - protocol: TCP - livenessProbe: - exec: - command: - - echo - - ok - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 3 - httpGet: - path: / - port: 8081 - scheme: HTTP - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - resources: - limits: - memory: 4Gi - cpu: 2 - requests: - memory: 512Mi - cpu: 200m - terminationMessagePath: /dev/termination-log - volumeMounts: - - mountPath: /nexus-data - name: nexus-data - volumes: - - name: nexus-data - persistentVolumeClaim: - claimName: nexus-pv ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: nexus - name: nexus -spec: - ports: - - name: 8081-tcp - port: 8081 - protocol: TCP - targetPort: 8081 - selector: - app: nexus - sessionAffinity: None - type: ClusterIP -# --- -# apiVersion: v1 -# kind: Route -# metadata: -# labels: -# app: nexus -# name: nexus -# spec: -# port: -# targetPort: 8081-tcp -# to: -# kind: Service -# name: nexus -# weight: 100 ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - labels: - app: nexus - name: nexus-pv -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi -#+end_src - -… a maven-repo PVC - -#+begin_src yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: maven-repo-pvc -spec: - resources: - requests: - storage: 5Gi - volumeMode: Filesystem - accessModes: - - ReadWriteMany -#+end_src - -and a maven settings configmap - -#+begin_src yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: custom-maven-settings -data: - settings.xml: | - <?xml version="1.0" encoding="UTF-8"?> - <settings> - <servers> - <server> - <id>nexus</id> - <username>admin</username> - <password>admin123</password> - </server> - </servers> - <mirrors> - <mirror> - <id>nexus</id> - <name>nexus</name> - <url>http://nexus:8081/repository/maven-public/</url> - <mirrorOf>*</mirrorOf> - </mirror> - </mirrors> - </settings> -#+end_src - -*** DONE Maven -CLOSED: [2020-11-02 Mon 16:40] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-02 Mon 16:40] -:END: - -A simple =maven= project pipeline that build, run test, packages and publish artifacts -(jars) to a maven repository. /Note: it uses a maven cache (=.m2=)/. - -The pipeline… - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: std-maven -spec: - params: - - name: url - - name: revision - default: "" - workspaces: - - name: ws - - name: local-maven-repo - - name: maven-settings - optional: true - tasks: - - name: fetch-repository - taskRef: - name: git-clone - bundle: docker.io/vdemeester/tekton-base-git:v0.1 - workspaces: - - name: output - workspace: ws - params: - - name: url - value: $(params.url) - - name: unit-tests - taskRef: - bundle: docker.io/vdemeester/tekton-java:v0.1 - name: maven - runAfter: - - fetch-repository - workspaces: - - name: source - workspace: ws - - name: maven-repo - workspace: local-maven-repo - - name: maven-settings - workspace: maven-settings - params: - - name: GOALS - value: ["package"] - - name: release-app - taskRef: - bundle: docker.io/vdemeester/tekton-java:v0.1 - name: maven - runAfter: - - unit-tests - workspaces: - - name: source - workspace: ws - - name: maven-repo - workspace: local-maven-repo - - name: maven-settings - workspace: maven-settings - params: - - name: GOALS - value: - - deploy - - -DskipTests=true - - -DaltDeploymentRepository=nexus::default::http://nexus:8081/repository/maven-releases/ - - -DaltSnapshotDeploymentRepository=nexus::default::http://nexus:8081/repository/maven-snapshots/ -#+end_src - -… and the pipeline run - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - generateName: run-std-maven- -spec: - pipelineRef: - name: std-maven - params: - - name: url - value: https://github.com/spring-projects/spring-petclinic - workspaces: - - name: maven-settings - configMap: - name: custom-maven-settings - items: - - key: settings.xml - path: settings.xml - - name: local-maven-repo - persistentVolumeClaim: - claimName: maven-repo-pvc - - name: ws - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteMany - resources: - requests: - storage: 1Gi -#+end_src - -Notes: -- Need =affinity-assistant= to be disabled (as of today) -- =params= and =workspaces= are duplicated in there. - /Maybe we could be able to specify workspace to be available for all tasks/ - -*** DONE Gradle -CLOSED: [2020-11-02 Mon 16:56] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-02 Mon 16:56] -:END: - -A simple =gradle= project pipeline that build, run test, packages and publish artifacts -(jars) to a maven repository. /Note: it uses a maven cache (=.m2=)/. This is the same as above -but using =gradle= instead of =maven=. - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: std-gradle -spec: - params: - - name: url - - name: revision - default: "" - workspaces: - - name: ws - - name: local-maven-repo - - name: maven-settings - optional: true - tasks: - - name: fetch-repository - taskRef: - name: git-clone - bundle: docker.io/vdemeester/tekton-base-git:v0.1 - workspaces: - - name: output - workspace: ws - params: - - name: url - value: $(params.url) - - name: unit-tests - taskRef: - bundle: docker.io/vdemeester/tekton-java:v0.1 - name: gradle - runAfter: - - fetch-repository - workspaces: - - name: source - workspace: ws - - name: maven-repo - workspace: local-maven-repo - - name: maven-settings - workspace: maven-settings - params: - - name: GOALS - value: ["build"] - # - name: release-app - # taskRef: - # bundle: docker.io/vdemeester/tekton-java:v0.1 - # name: gradle - # runAfter: - # - unit-tests - # workspaces: - # - name: source - # workspace: ws - # - name: maven-repo - # workspace: local-maven-repo - # - name: maven-settings - # workspace: maven-settings - # params: - # - name: GOALS - # value: - # - upload - # - -DskipTests=true - # - -DaltDeploymentRepository=nexus::default::http://nexus:8081/repository/maven-releases/ - # - -DaltSnapshotDeploymentRepository=nexus::default::http://nexus:8081/repository/maven-snapshots/q -#+end_src - -and the run… - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - generateName: run-std-gradle- -spec: - pipelineRef: - name: std-gradle - params: - - name: url - value: https://github.com/spring-petclinic/spring-petclinic-kotlin - workspaces: - - name: maven-settings - configMap: - name: custom-maven-settings - items: - - key: settings.xml - path: settings.xml - - name: local-maven-repo - persistentVolumeClaim: - claimName: maven-repo-pvc - - name: ws - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteMany - resources: - requests: - storage: 1Gi -#+end_src - -** DONE A source-to-image Pipeline -CLOSED: [2020-11-10 Tue 17:04] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-10 Tue 17:04] -:END: - -A pipeline that takes a repository with a =Dockerfile=, builds and pushes an image from it, -and deploy it to kubernetes (using deployment/services). - -Let's first setup a registry - -#+begin_src shell -TMD=$(mktemp -d) - -# Generate SSL Certificate -openssl req -newkey rsa:4096 -nodes -sha256 -keyout "${TMD}"/ca.key -x509 -days 365 \ - -out "${TMD}"/ca.crt -subj "/C=FR/ST=IDF/L=Paris/O=Tekton/OU=Catalog/CN=registry" - -# Create a configmap from these certs -kubectl create -n "${tns}" configmap sslcert \ - --from-file=ca.crt="${TMD}"/ca.crt --from-file=ca.key="${TMD}"/ca.key -#+end_src - -#+RESULTS: - -#+begin_src yaml ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: registry -spec: - selector: - matchLabels: - run: registry - replicas: 1 - template: - metadata: - labels: - run: registry - spec: - containers: - - name: registry - image: docker.io/registry:2 - ports: - - containerPort: 5000 - volumeMounts: - - name: sslcert - mountPath: /certs - env: - - name: REGISTRY_HTTP_TLS_CERTIFICATE - value: "/certs/ca.crt" - - name: REGISTRY_HTTP_TLS_KEY - value: "/certs/ca.key" - - name: REGISTRY_HTTP_SECRET - value: "tekton" - volumes: - - name: sslcert - configMap: - defaultMode: 420 - items: - - key: ca.crt - path: ca.crt - - key: ca.key - path: ca.key - name: sslcert ---- -apiVersion: v1 -kind: Service -metadata: - name: registry -spec: - ports: - - port: 5000 - selector: - run: registry -#+end_src - -*** DONE buildah -CLOSED: [2020-11-09 Mon 16:57] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-09 Mon 16:57] -:END: - -#+begin_src yaml ---- -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: std-source-to-image-buildah -spec: - params: - - name: url - - name: revision - default: "" - - name: image - default: "localhost:5000/foo" - - name: pushimage - default: "localhost:5000/foo" - workspaces: - - name: ws - - name: sslcertdir - optional: true - tasks: - - name: fetch-repository - taskRef: - name: git-clone - #bundle: docker.io/vdemeester/tekton-base-git:v0.1 - workspaces: - - name: output - workspace: ws - params: - - name: url - value: $(params.url) - - name: build-and-push - taskRef: - name: buildah - #bundle: docker.io/vdemeester/tekton-builders:v0.1 - runAfter: [ fetch-repository ] - params: - - name: IMAGE - value: $(params.pushimage) - - name: TLSVERIFY - value: "false" - workspaces: - - name: source - workspace: ws - # - name: sslcertdir - # workspace: sslcertdir - - name: deploy - runAfter: [ build-and-push ] - params: - - name: reference - value: $(params.image)@$(tasks.build-and-push.results.IMAGE_DIGEST) - taskSpec: - params: - - name: reference - steps: - - image: gcr.io/cloud-builders/kubectl@sha256:8ab94be8b2b4f3d117f02d868b39540fddd225447abf4014f7ba4765cb39f753 - script: | - cat <<EOF | kubectl apply -f - - apiVersion: apps/v1 - kind: Deployment - metadata: - name: foo-app - spec: - selector: - matchLabels: - run: foo-app - replicas: 1 - template: - metadata: - labels: - run: foo-app - spec: - containers: - - name: foo - image: $(params.reference) -#+end_src - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - generateName: run-std-source-to-image-buildah- -spec: - pipelineRef: - name: std-source-to-image-buildah - params: - - name: url - value: https://github.com/lvthillo/python-flask-docker - - name: pushimage - value: sakhalin.home:5000/foo - workspaces: - - name: ws - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi -#+end_src - -Notes: -- =deploy= may need it's own task definition in the catalog. =kubectl-deploy-pod= is one but - didn't work properly -- rest is smooth - -*** DONE s2i (no =Dockerfile=) -CLOSED: [2020-11-10 Tue 16:59] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-10 Tue 16:59] -:END: - -#+begin_src yaml ---- -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: std-source-to-image-s2i -spec: - params: - - name: url - - name: revision - default: "" - - name: image - default: "localhost:5000/foo" - - name: pushimage - default: "localhost:5000/foo" - workspaces: - - name: ws - - name: sslcertdir - optional: true - tasks: - - name: fetch-repository - taskRef: - name: git-clone - #bundle: docker.io/vdemeester/tekton-base-git:v0.1 - workspaces: - - name: output - workspace: ws - params: - - name: url - value: $(params.url) - - name: build-and-push - taskRef: - name: s2i - #bundle: docker.io/vdemeester/tekton-builders:v0.1 - runAfter: [ fetch-repository ] - params: - - name: BUILDER_IMAGE - value: docker.io/fabric8/s2i-java:latest-java11 - - name: S2I_EXTRA_ARGS - value: "--image-scripts-url=image:///usr/local/s2i" - - name: IMAGE - value: $(params.pushimage) - - name: TLSVERIFY - value: "false" - workspaces: - - name: source - workspace: ws - # - name: sslcertdir - # workspace: sslcertdir - - name: deploy - runAfter: [ build-and-push ] - params: - - name: reference - value: $(params.image)@$(tasks.build-and-push.results.IMAGE_DIGEST) - taskSpec: - params: - - name: reference - steps: - - image: gcr.io/cloud-builders/kubectl@sha256:8ab94be8b2b4f3d117f02d868b39540fddd225447abf4014f7ba4765cb39f753 - script: | - cat <<EOF | kubectl apply -f - - apiVersion: apps/v1 - kind: Deployment - metadata: - name: foo-app - spec: - selector: - matchLabels: - run: foo-app - replicas: 1 - template: - metadata: - labels: - run: foo-app - spec: - containers: - - name: foo - image: $(params.reference) -#+end_src - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - generateName: run-std-source-to-image-s2i- -spec: - pipelineRef: - name: std-source-to-image-s2i - params: - - name: url - value: https://github.com/siamaksade/spring-petclinic - - name: pushimage - value: sakhalin.home:5000/foo - workspaces: - - name: ws - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi -#+end_src - -Notes: -- =s2i= shares a lot with =buildah= or any =Dockerfile= build tool. - This may *show* the need to compose tasks from other tasks. Here we do =s2i … - --as-dockerfile= and then we just need to build the =Dockerfile=. This could be 2 separate - tasks but it would make the pipeline less efficient. - -** DONE A source-to-image "knative" Pipeline -CLOSED: [2020-11-10 Tue 17:02] -:LOGBOOK: -- State "DONE" from "TODO" [2020-11-10 Tue 17:02] -:END: - -A pipeline that takes a repository with a =Dockerfile=, builds and pushes an image from it, -and deploy it to kubernetes using knative services. - -#+begin_src yaml ---- -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: std-source-to-image-buildah-kn -spec: - params: - - name: url - - name: revision - default: "" - - name: image - default: "localhost:5000/foo" - - name: pushimage - default: "localhost:5000/foo" - workspaces: - - name: ws - - name: sslcertdir - optional: true - tasks: - - name: fetch-repository - taskRef: - name: git-clone - #bundle: docker.io/vdemeester/tekton-base-git:v0.1 - workspaces: - - name: output - workspace: ws - params: - - name: url - value: $(params.url) - - name: build-and-push - taskRef: - name: buildah - #bundle: docker.io/vdemeester/tekton-builders:v0.1 - runAfter: [ fetch-repository ] - params: - - name: IMAGE - value: $(params.pushimage) - - name: TLSVERIFY - value: "false" - workspaces: - - name: source - workspace: ws - # - name: sslcertdir - # workspace: sslcertdir - - name: kn-deploy - runAfter: [ build-and-push ] - taskref: - name: kn - params: - - name: ARGS - value: - - "service" - - "create" - - "hello" - - "--force" - - "--image=$(params.image)@$(tasks.build-and-push.results.IMAGE_DIGEST)" -#+end_src - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - generateName: run-std-source-to-image-buildah-kn- -spec: - pipelineRef: - name: std-source-to-image-buildah-kn - params: - - name: url - value: https://github.com/lvthillo/python-flask-docker - - name: pushimage - value: sakhalin.home:5000/foo - serviceAccountName: kn-deployer-account - workspaces: - - name: ws - volumeClaimTemplate: - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi -#+end_src - - -** TODO A canary deployment pipeline (not from sources) - - - -** TODO A canary deployment pipeline (iter8) - -This is taken from [[https://github.com/iter8-tools/canary-tekton-example][iter8 canary tekton example]]. - -[[./images/tekton/canary-pipeline.png]] - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: identify-baseline-task -spec: - description: | - Identify the baseline deployment in a cluster namespace. - params: - - name: UID - type: string - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - - name: NAMESPACE - type: string - default: default - description: The cluster namespace in which to search for the baseline. - - name: EXPERIMENT_TEMPLATE - type: string - default: "experiment" - description: Name of template that should be used for the experiment. - workspaces: - - name: source - results: - - name: baseline - description: Name of the baseline deployment. - steps: - - name: update-experiment - workingDir: $(workspaces.source.path)/$(params.UID) - image: kalantar/yq-kubernetes - script: | - #!/usr/bin/env bash - # Uncomment to debug - set -x - - # Identify baseline deployment for an experiment - # This is heuristic; prefers to look at stable DestinationRule - # But if this isn't defined will select first deployment that satisfies - # the service selector (service from Experiment) - - NAMESPACE=$(params.NAMESPACE) - SERVICE=$(yq read $(params.EXPERIMENT_TEMPLATE) spec.service.name) - ROUTER=$(yq read $(params.EXPERIMENT_TEMPLATE) spec.networking.id) - - if [[ -z ${ROUTER} ]] || [[ "${ROUTER}" == "null" ]]; then - ROUTER="${SERVICE}.${NAMESPACE}.svc.cluster.local" - fi - - echo "SERVICE=${SERVICE}" - echo " ROUTER=${ROUTER}" - - SUBSET= - NUM_VS=$(kubectl --namespace ${NAMESPACE} get vs --selector=iter8-tools/router=${ROUTER} --output json | jq '.items | length') - echo "NUM_VS=${NUM_VS}" - if (( ${NUM_VS} > 0 )); then - SUBSET=$(kubectl --namespace ${NAMESPACE} get vs --selector=iter8-tools/router=${ROUTER} --output json | jq -r '.items[0].spec.http[0].route[] | select(has("weight")) | select(.weight == 100) | .destination.subset') - echo "SUBSET=$SUBSET" - fi - - DEPLOY_SELECTOR="" - if [[ -n ${SUBSET} ]]; then - NUM_DR=$(kubectl --namespace ${NAMESPACE} get dr --selector=iter8-tools/router=${ROUTER} --output json | jq '.items | length') - echo "NUM_DR=${NUM_DR}" - if (( ${NUM_DR} > 0 )); then - DEPLOY_SELECTOR=$(kubectl --namespace ${NAMESPACE} get dr --selector=iter8-tools/router=${ROUTER} --output json | jq -r --arg SUBSET "$SUBSET" '.items[0].spec.subsets[] | select(.name == $SUBSET) | .labels | to_entries[] | "\(.key)=\(.value)"' | paste -sd',' -) - fi - fi - echo "DEPLOY_SELECTOR=${DEPLOY_SELECTOR}" - - if [ -z "${DEPLOY_SELECTOR}" ]; then - # No stable DestinationRule found so find the deployment(s) implementing $SERVICE - DEPLOY_SELECTOR=$(kubectl --namespace ${NAMESPACE} get service ${SERVICE} --output json | jq -r '.spec.selector | to_entries[] | "\(.key)=\(.value)"' | paste -sd',' -) - fi - echo "DEPLOY_SELECTOR=$DEPLOY_SELECTOR" - - NUM_DEPLOY=$(kubectl --namespace ${NAMESPACE} get deployment --selector=${DEPLOY_SELECTOR} --output json | jq '.items | length') - echo " NUM_DEPLOY=${NUM_DEPLOY}" - BASELINE_DEPLOYMENT_NAME= - if (( ${NUM_DEPLOY} > 0 )); then - BASELINE_DEPLOYMENT_NAME=$(kubectl --namespace ${NAMESPACE} get deployment --selector=${DEPLOY_SELECTOR} --output jsonpath='{.items[0].metadata.name}') - fi - echo -n "${BASELINE_DEPLOYMENT_NAME}" | tee $(results.baseline.path) ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: define-experiment-task -spec: - description: | - Define an iter8 canary Experiment from a template. - workspaces: - - name: source - description: Consisting of kubernetes manifest templates (ie, the Experiment) - params: - - name: UID - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - - name: EXPERIMENT_TEMPLATE - type: string - default: "experiment.yaml" - description: An experiment resource that can be modified. - - name: NAME - type: string - default: "" - description: The name of the experiment resource to create - - name: BASELINE - type: string - default: "" - description: The name of the baseline resource - - name: CANDIDATE - type: string - default: "" - description: The name of the candidate (canary) resource - results: - - name: experiment - description: Path to experiment (in workspace ) - steps: - - name: update-experiment - image: kalantar/yq-kubernetes - workingDir: $(workspaces.source.path)/$(params.UID) - script: | - #!/usr/bin/env bash - - OUTPUT="experiment-$(params.UID).yaml" - - if [ -f "$(params.EXPERIMENT_TEMPLATE)" ]; then - cp "$(params.EXPERIMENT_TEMPLATE)" "${OUTPUT}" - else - curl -s -o "${OUTPUT}" "$(params.EXPERIMENT_TEMPLATE)" - fi - - if [ ! -f "${OUTPUT}" ]; then - echo "Can not read template: $(params.EXPERIMENT_TEMPLATE)" - exit 1 - fi - - # Update experiment template - if [ "" != "$(params.NAME)" ]; then - yq write --inplace "${OUTPUT}" metadata.name "$(params.NAME)" - fi - if [ "" != "$(params.BASELINE)" ]; then - yq write --inplace "${OUTPUT}" spec.service.baseline "$(params.BASELINE)" - fi - if [ "" != "$(params.CANDIDATE)" ]; then - yq write --inplace "${OUTPUT}" spec.service.candidates[0] "$(params.CANDIDATE)" - fi - - cat "${OUTPUT}" - echo -n $(params.UID)/${OUTPUT} | tee $(results.experiment.path) ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: apply-manifest-task -spec: - description: | - Create an iter8 canary Experiment from a template. - workspaces: - - name: manifest-dir - description: Consisting of kubernetes manifests (ie, the Experiment) - params: - - name: MANIFEST - type: string - default: "manifest.yaml" - description: The name of the file containing the kubernetes manifest to apply - - name: TARGET_NAMESPACE - type: string - default: "default" - description: The namespace in which the manifest should be applied - steps: - - name: apply-manifest - image: kalantar/yq-kubernetes - workingDir: $(workspaces.manifest-dir.path) - script: | - #!/usr/bin/env bash - - # Create experiment in cluster - kubectl --namespace $(params.TARGET_NAMESPACE) apply --filename "$(params.MANIFEST)" ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: define-canary-task -spec: - description: | - Create YAML file needed to deploy the canary version of the application. - Relies on kustomize and assumes a patch file template (PATCH_FILE) containing the keyword - "VERSION" that can be replaced with the canary verion. - params: - - name: UID - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - - name: image-repository - description: Docker image repository - default: "" - - name: image-tag - description: tag of image to deploy - default: latest - - name: PATCH_FILE - default: kustomize/patch.yaml - workspaces: - - name: source - results: - - name: deployment-file - description: Path to file (in workspace ) - - steps: - - name: modify-patch - image: alpine - workingDir: $(workspaces.source.path)/$(params.UID) - script: | - #!/usr/bin/env sh - - IMAGE_TAG=$(params.image-tag) - PATCH_FILE=$(params.PATCH_FILE) - IMAGE=$(params.image-repository):$(params.image-tag) - - sed -i -e "s#iter8/reviews:istio-VERSION#${IMAGE}#" ${PATCH_FILE} - sed -i -e "s#VERSION#${IMAGE_TAG}#g" ${PATCH_FILE} - cat ${PATCH_FILE} - - echo -n "deploy-$(params.UID).yaml" | tee $(results.deployment-file.path) - - - name: generate-deployment - image: smartive/kustomize - workingDir: $(workspaces.source.path)/$(params.UID) - command: [ "kustomize" ] - args: [ "build", "kustomize", "-o", "deploy-$(params.UID).yaml" ] - - - name: log-deployment - image: alpine - workingDir: $(workspaces.source.path)/$(params.UID) - command: [ "cat" ] - args: [ "deploy-$(params.UID).yaml" ] ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: wait-completion-task -spec: - description: | - Wait until EXPERIMENT is completed; - that is, condition ExperimentCompleted is true. - params: - - name: EXPERIMENT - default: "experiment" - description: Name of iter8 experiment - - name: NAMESPACE - default: default - description: Namespace in which the iter8 experiment is defined. - - name: TIMEOUT - default: "1h" - description: Amount of time to wait for experiment to complete. - steps: - - name: wait - image: kalantar/yq-kubectl - script: | - #!/usr/bin/env sh - set -x - - kubectl --namespace $(params.NAMESPACE) wait \ - --for=condition=ExperimentCompleted \ - experiments.iter8.tools $(params.EXPERIMENT) \ - --timeout=$(params.TIMEOUT) ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: cleanup-task -spec: - workspaces: - - name: workspace - params: - - name: UID - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - steps: - - name: clean-workspace - image: alpine - script: | - #!/usr/bin/env sh - set -x - - rm -rf $(workspaces.workspace.path)/$(params.UID) ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: identify-endpoint-task -spec: - description: | - Identify URL of application to be used buy load generator. - params: - - name: istio-namespace - default: istio-system - description: Namespace where Istio is installed. - - name: application-query - default: "" - description: Application endpoint. - results: - - name: application-url - description: The URL that can be used to apply load to the application. - steps: - - name: determine-server - image: kalantar/yq-kubernetes - script: | - #!/usr/bin/env sh - - # Determine the IP - # Try loadbalancer on istio-ingressgateway - IP=$(kubectl --namespace $(params.istio-namespace) get service istio-ingressgateway --output jsonpath='{.status.loadBalancer.ingress[0].ip}') - # If not, try an external IP for a node - echo "IP=${IP}" - if [ -z "${IP}" ]; then - IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type == "ExternalIP")].address}') - fi - echo "IP=${IP}" - # If not, try an internal IP for a node (minikube) - if [ -z "${IP}" ]; then - IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type == "InternalIP")].address}') - fi - echo "IP=${IP}" - - # Determine the port - PORT=$(kubectl --namespace $(params.istio-namespace) get service istio-ingressgateway --output jsonpath="{.spec.ports[?(@.port==80)].nodePort}") - echo "PORT=${PORT}" - - HOST="${IP}:${PORT}" - echo "HOST=$HOST" - - echo -n "http://${HOST}/$(params.application-query)" | tee $(results.application-url.path) ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: generate-load-task -spec: - description: | - Generate load by sending queries to URL every INTERVAL seconds. - Load generation continues as long as the file terminate is not present. - params: - - name: UID - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - - name: URL - default: "http://localhost:8080" - description: URL that should be used to generate load. - - name: HOST - default: "" - description: Value to be added in Host header. - - name: terminate - default: ".terminate" - description: Name of file that, if present, triggers termination of load generation. - - name: INTERVAL - default: "0.1" - description: Interval (s) between generated requests. - workspaces: - - name: scratch - steps: - - name: generate-load - image: kalantar/yq-kubernetes - workingDir: $(workspaces.scratch.path) - script: | - #!/usr/bin/env bash - - # Remove terminatation file if it exists (it should not) - rm -f $(params.UID)/$(params.terminate) || true - - echo "param HOST=$(params.HOST)" - echo "param URL=$(params.URL)" - - if [ "$(params.HOST)" == "" ]; then - HOST= - elif [ "$(params.HOST)" == "\*" ]; then - HOST= - else - HOST=$(params.HOST) - fi - echo "computed HOST=$HOST" - - # Optionally use a Host header in requests - if [ -z ${HOST} ]; then - echo "curl -o /dev/null -s -w \"%{http_code}\\n\" $(params.URL)" - else - echo "curl -H \"Host: ${HOST}\" -o /dev/null -s -w \"%{http_code}\\n\" $(params.URL)" - fi - - # Generate load until the file terminate is created. - REQUESTS=0 - ERRORS=0 - while [ 1 ]; do - if [ -f $(params.UID)/$(params.terminate) ]; then - echo "Terminating load; ${REQUESTS} requests sent; ${ERRORS} had errors." - break - fi - sleep $(params.INTERVAL) - OUT= - if [ -z ${HOST} ]; then - OUT=$(curl -o /dev/null -s -w "%{http_code}\n" $(params.URL)) - else - OUT=$(curl -H "Host: ${HOST}" -o /dev/null -s -w "%{http_code}\n" $(params.URL)) - fi - if [ "${OUT}" != "200" ]; then ((ERRORS++)); echo "Not OK: ${OUT}"; fi - ((REQUESTS++)) - done ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: stop-load-task -spec: - description: | - Trigger the termination of experiment load. - params: - - name: UID - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - - name: terminate - default: ".terminate" - description: Name of file that, if present, triggers termination of load generation. - workspaces: - - name: scratch - steps: - - name: wait - image: alpine - workingDir: $(workspaces.scratch.path) - script: | - #!/usr/bin/env sh - - # To avoid conflicts, use a run specific subdirectory - mkdir -p $(params.UID) - touch $(params.UID)/$(params.terminate) ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: queue-request-task -spec: - description: | - Place self at the end of a queue and wait until we are at the top. - params: - - name: UID - default: "uid" - description: | - Unique identifier used to assocaite load with an experiment. - Suitable values might be the experiment name of the task/pipeline run name/uid. - - name: lock-dir - default: ".lock" - description: Name of directory to use to acquire mutex. - - name: queue - default: ".queue" - description: Name of the file containing execution queue. - - name: wait-time - default: "20" - description: Sleep time between attempts to aquire the lock. - workspaces: - - name: scratch - steps: - - name: queue - image: alpine - workingDir: $(workspaces.scratch.path) - script: | - #!/usr/bin/env sh - - while [ "$(params.UID)" != "$(tail -n 1 $(params.queue))" ]; do - if mkdir "$(params.lock-dir)"; then - echo "queuing $(params.UID)" - echo $(params.UID) >> $(params.queue) - rm -rf "$(params.lock-dir)" - else - sleep $(params.wait-time) - fi - done - - name: wait-head - image: alpine - workingDir: $(workspaces.scratch.path) - script: | - #!/usr/bin/env sh - - while [ "$(params.UID)" != "$(head -n 1 $(params.queue))" ]; do - sleep $(params.wait-time) - done - echo "$(params.UID) proceeding" ---- -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: dequeue-request-task -spec: - description: | - Remove entry from top of queue. - params: - - name: queue - default: ".queue" - description: Name of the file containing execution queue. - workspaces: - - name: scratch - steps: - - name: dequeue - image: alpine - workingDir: $(workspaces.scratch.path) - script: | - #!/usr/bin/env sh - - tail -n +2 $(params.queue) > /tmp/$$; mv /tmp/$$ $(params.queue) -#+end_src - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: Pipeline -metadata: - name: canary-rollout-iter8 -spec: - workspaces: - - name: source - - name: experiment-dir - params: - - name: application-source - type: string - description: URL of source git repository. - default: "" - - name: application-namespace - type: string - description: Target namespace for application. - - name: application-query - type: string - description: Service query for load generation. - default: "" - - name: application-image - type: string - description: Docker image repository for image to deploy. - - name: HOST - type: string - description: Value that should be sent in Host header in test queries - default: "" - - - name: experiment - type: string - description: Name of experiment to create. - default: "experiment" - - name: experiment-template - type: string - description: Template for experiment to create. - - - name: terminate - type: string - default: ".terminate" - description: Name of file that, if present, triggers termination of load generation. - - tasks: - - name: initialize-request - taskRef: - name: queue-request-task - workspaces: - - name: scratch - workspace: experiment-dir - params: - - name: UID - value: $(context.pipelineRun.uid) - - - name: clone-source - taskRef: - name: git-clone - runAfter: - - initialize-request - workspaces: - - name: output - workspace: source - params: - - name: url - value: $(params.application-source) - - name: revision - value: master - - name: deleteExisting - value: "true" - - name: subdirectory - value: $(context.pipelineRun.uid) - - - name: build-and-push-image - taskRef: - name: kaniko - runAfter: - - clone-source - timeout: "15m" - workspaces: - - name: source - workspace: source - params: - - name: DOCKERFILE - value: ./$(context.pipelineRun.uid)/Dockerfile - - name: CONTEXT - value: ./$(context.pipelineRun.uid) - - name: IMAGE - value: $(params.application-image):$(tasks.clone-source.results.commit) - - name: EXTRA_ARGS - value: "--skip-tls-verify" - - - name: identify-baseline - taskRef: - name: identify-baseline-task - runAfter: - - clone-source - workspaces: - - name: source - workspace: source - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: NAMESPACE - value: $(params.application-namespace) - - name: EXPERIMENT_TEMPLATE - value: $(params.experiment-template) - - - name: define-experiment - taskRef: - name: define-experiment-task - runAfter: - - clone-source - - identify-baseline - workspaces: - - name: source - workspace: source - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: EXPERIMENT_TEMPLATE - value: $(params.experiment-template) - - name: NAME - value: $(context.pipelineRun.uid) - - name: BASELINE - value: $(tasks.identify-baseline.results.baseline) - - name: CANDIDATE - value: reviews-$(tasks.clone-source.results.commit) - - - name: create-experiment - taskRef: - name: apply-manifest-task - runAfter: - - define-experiment - workspaces: - - name: manifest-dir - workspace: source - params: - - name: TARGET_NAMESPACE - value: $(params.application-namespace) - - name: MANIFEST - value: $(tasks.define-experiment.results.experiment) - - - name: define-canary - taskRef: - name: define-canary-task - runAfter: - - clone-source - workspaces: - - name: source - workspace: source - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: image-repository - value: $(params.application-image) - - name: image-tag - value: $(tasks.clone-source.results.commit) - - - name: deploy-canary - taskRef: - name: apply-manifest-task - runAfter: - - create-experiment - - build-and-push-image - - define-canary - workspaces: - - name: manifest-dir - workspace: source - params: - - name: TARGET_NAMESPACE - value: $(params.application-namespace) - - name: MANIFEST - value: $(context.pipelineRun.uid)/$(tasks.define-canary.results.deployment-file) - - - name: identify-endpoint - taskRef: - name: identify-endpoint-task - runAfter: - - initialize-request - params: - - name: application-query - value: $(params.application-query) - - - name: generate-load - taskRef: - name: generate-load-task - runAfter: - - create-experiment - - identify-endpoint - workspaces: - - name: scratch - workspace: experiment-dir - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: URL - value: $(tasks.identify-endpoint.results.application-url) - - name: HOST - value: $(params.HOST) - - name: terminate - value: $(params.terminate) - - - name: wait-completion - taskRef: - name: wait-completion-task - runAfter: - - deploy-canary - params: - - name: EXPERIMENT - value: $(context.pipelineRun.uid) - - name: NAMESPACE - value: $(params.application-namespace) - - - name: stop-load-generation - runAfter: - - wait-completion - taskRef: - name: stop-load-task - workspaces: - - name: scratch - workspace: experiment-dir - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: terminate - value: $(params.terminate) - - finally: - - name: cleanup-scratch-workspace - taskRef: - name: cleanup-task - workspaces: - - name: workspace - workspace: experiment-dir - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: cleanup-source-workspace - taskRef: - name: cleanup-task - workspaces: - - name: workspace - workspace: source - params: - - name: UID - value: $(context.pipelineRun.uid) - - name: complete-request - taskRef: - name: dequeue-request-task - workspaces: - - name: scratch - workspace: experiment-dir -#+end_src - -#+begin_src yaml -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - name: canary-rollout -spec: - pipelineRef: - name: canary-rollout-iter8 - serviceAccountName: default - workspaces: - - name: source - persistentVolumeClaim: - claimName: source-storage - - name: experiment-dir - persistentVolumeClaim: - claimName: experiment-storage - params: - - name: application-source - value: https://github.com/kalantar/reviews - - name: application-namespace - value: bookinfo-iter8 - - name: application-image - value: kalantar/reviews - - name: application-query - value: productpage - - - name: HOST - value: "bookinfo.example.com" - - - name: experiment-template - value: iter8/experiment.yaml -#+end_src - -** TODO A canary "knative" deployment pipeline - -** TODO A "matrix" build pipeline - -** TODO =tektoncd/pipeline= project pipeline - -** TODO Netlify flow - -- Build and deploy a wip - -* TODO Issues - -** No support for one-shot task with =git-clone= - -PipelineResource brought /pre/ steps that would help running one task on top of a -GitResource for example. Let's say you have a repository with a =Dockerfile=. All you want -is to build your =Dockerfile= in your CI. Without =PipelineResource= you are /stuck/ to use a -=Pipeline=. - -* TODO Advantage - -* TODO Next steps - -* TODO References - -- https://github.com/redhat-gpte-devopsautomation/app-dev-openshift-pipeline -- https://gist.github.com/markito/9ef0329bce51a454e7ce5a0ed18a1eb1 -- https://github.com/iter8-tools/canary-tekton-example -- https://github.com/ibm/ibm-garage-tekton-tasks diff --git a/www/vincent.demeester.fr/content/legacy/articles/tekton-usage.org b/www/vincent.demeester.fr/content/legacy/articles/tekton-usage.org @@ -1,385 +0,0 @@ -#+TITLE: Tektoncd usage and examples -#+SUBTITLE: Playing with the cat's project 🐱 -#+FILETAGS: tektoncd kubernetes ci cd pipeline -#+SETUPFILE: .setup.org - -#+begin_abstract -Let's dig into some use case and examples of ~tektoncd/pipeline~. From secrets and -services accounts to real-life example, let's document ~pipeline~ usage, tips and tricks. -#+end_abstract - -#+TOC: headlines 2 - -* What is Tektoncd ? -:PROPERTIES: -:CUSTOM_ID: h:7b3bca36-78c1-44b4-96fe-b26332e195ed -:END: - -#+NAME: fig:tektoncd-logo -#+ATTR_ORG: :width 400/600 -#+ATTR_HTML: :width 400/600px -[[file:images/tekton/tekton-horizontal-color.png]] - -#+begin_quote -The Tekton Pipelines project provides Kubernetes-style resources for declaring CI/CD-style pipelines. -#+end_quote - -- Started as an experiment from [[https://github.com/knative][Knative]] to define more advance build use cases that - [[https://github.com/knative/build/][~knative/build~]] was able to. -- Is now it's own project and GitHub organization. - -* Secrets -:PROPERTIES: -:CUSTOM_ID: h:dc6c7476-6df0-467b-a2fb-1512d300ef4c -:END: - -Most of the time, you're gonna need to access private resources like git repositories, -image registries, ssh server and clusters. We'll dig into each of them but the gist is always the -same : - -- Create secrets that holds the credentials -- Create service accounts that uses those secrets -- Attach those service accounts to the ~PipelineRun~/~TaskRun~ - -:note: -Those are working *exactly* the same as ~knative/build~. The docs are [[https://github.com/knative/docs/blob/master/docs/build/auth.md][here]]. -:END: - - -** Git credentials -:PROPERTIES: -:CUSTOM_ID: h:8eb369c9-1987-4119-9b24-d3b1204dab15 -:END: - -*** Using ssh -:PROPERTIES: -:CUSTOM_ID: h:c08a3856-f230-4c0d-a8ee-2f5ee8c85313 -:END: - -#+begin_src yaml - apiVersion: v1 - kind: Secret - metadata: - name: ssh-key - annotations: - tekton.dev/git-0: github.com - tekton.dev/git-1: gitlab.com - tekton.dev/git-2: sr.ht - type: kubernetes.io/ssh-auth - data: - # cat ~/.id_rs | base64 -w 0 - ssh-privatekey: <base64 encoded> - # This is non-standard, but its use is encouraged to make this more secure. - # ssh-keyscan github.com | base64 -w 0 - known_hosts: <base64 encoded> -#+end_src - -*** Using basic authentication -:PROPERTIES: -:CUSTOM_ID: h:e54bf2cb-7ac1-449e-b7cb-25a036248b83 -:END: - -#+begin_src yaml - apiVersion: v1 - kind: Secret - metadata: - name: basic-user-pass - annotations: - tekton.dev/git-0: https://github.com - tekton.dev/git-1: https://gitlab.com - tekton.dev/git-0: https://sr.ht - type: kubernetes.io/basic-auth - stringData: - username: <username> - password: <password> -#+end_src - - -** Registry credentials -:PROPERTIES: -:CUSTOM_ID: h:f590bf9c-464d-4d31-a176-b7c9b7b9e168 -:END: - -*** Using basic authentication -:PROPERTIES: -:CUSTOM_ID: h:2813551c-f51a-4873-8d1d-7608d67e9711 -:END: - -#+begin_src yaml - apiVersion: v1 - kind: Secret - metadata: - name: basic-user-pass - annotations: - tekton.dev/docker-0: https://index.docker.io - tekton.dev/docker-1: https://gcr.io - type: kubernetes.io/basic-auth - stringData: - username: <username> - password: <password> -#+end_src - -*** Using kubernetes secret types -:PROPERTIES: -:CUSTOM_ID: h:b81a4552-743f-4c5d-80be-c1a896ba7ec7 -:END: - -There is two secret specific secret types related to docker authentication, or more -accurately to docker configuration files (that holds auth). - -- ~kubernetes.io/dockerconfigjson~ (~$HOME/.docker/config.json~) -- ~kubernetes.io/dockercfg~ (~$HOME/.dockercfg~) - -#+begin_src bash - kubectl create secret generic regcred \ - --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ - --type=kubernetes.io/dockerconfigjson - # kubectl create secret generic regcred --from-file=.dockerconfigjson=$HOME/.docker/config.json --type=kubernetes.io/dockerconfigjson -#+end_src - -#+begin_src yaml - apiVersion: v1 - data: - .dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0= - kind: Secret - metadata: - ... - name: regcred - ... - type: kubernetes.io/dockerconfigjson -#+end_src - -Kubernetes documentation : [[https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/][Pull an Image from a Private Registry - Kubernetes]] - -* Service account -:PROPERTIES: -:CUSTOM_ID: h:b0f52c83-e465-4733-9ba8-51d4c915fb25 -:END: - -#+begin_src yaml - apiVersion: v1 - kind: ServiceAccount - metadata: - name: build-bot - secrets: - - name: regcred - - name: ssh-key -#+end_src - - -* Using ~kaniko~ -:PROPERTIES: -:CUSTOM_ID: h:d81a3f84-c608-4345-8cf0-44c8ed15ea2a -:END: - -** Volume for ~kaniko~'s cache -:PROPERTIES: -:CUSTOM_ID: h:8c8cd49e-5dda-47cf-a3d8-caff9a1bf833 -:END: - -#+begin_src yaml - kind: PersistentVolumeClaim - apiVersion: v1 - metadata: - name: kaniko-cache-pvc - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi -#+end_src - - -** Resources -:PROPERTIES: -:CUSTOM_ID: h:7da25768-794e-48c1-b92a-603e1c0572b2 -:END: - -- the ~git~ repository - #+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: PipelineResource - metadata: - name: private-go-hello - spec: - type: git - params: - - name: revision - value: master - - name: url - value: git@github.com:vdemeester/go-hello.git - #+end_src - -- the ~image~ (s) - #+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: PipelineResource - metadata: - name: hello-image-res - spec: - type: image - params: - - name: url - description: The target URL - value: docker.io/vdemeester/go-hello - --- - apiVersion: tekton.dev/v1alpha1 - kind: PipelineResource - metadata: - name: bye-image-res - spec: - type: image - params: - - name: url - description: The target URL - value: quay.io/rhdevelopers/vdemeest-go-bye - #+end_src - -** ~Task~ -:PROPERTIES: -:CUSTOM_ID: h:4d50a5ad-2748-4f28-b545-6bf1e6872463 -:END: - -#+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: Task - metadata: - name: kaniko-build-push - spec: - inputs: - resources: - - name: src - type: git - params: - - name: pathToDockerFile - description: The path to the dockerfile to build (relative to the context) - default: Dockerfile - - name: pathToContext - description: - The path to the build context, used by Kaniko - within the workspace - (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts). - The git clone directory is set by the GIT init container which setup - the git input resource - see https://github.com/knative/build-pipeline/blob/master/pkg/reconciler/v1alpha1/taskrun/resources/pod.go#L107 - default: . - outputs: - resources: - - name: builtImage - type: image - steps: - - name: build-and-push - image: gcr.io/kaniko-project/executor:debug - command: ["/kaniko/executor"] - args: - - --dockerfile=${inputs.params.pathToDockerFile} - - --destination=${outputs.resources.builtImage.url} - - --context=/workspace/src/${inputs.params.pathToContext} - volumeMounts: - - name: kaniko-cache - mountPath: /cache - volumes: - - name: kaniko-cache - persistentVolumeClaim: - claimName: kaniko-cache-pvc -#+end_src - -** ~Pipeline~ -:PROPERTIES: -:CUSTOM_ID: h:f00592b2-a81b-43c4-a4fa-36959f515553 -:END: - -#+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: Pipeline - metadata: - name: kaniko - spec: - resources: - - name: src - type: git - - name: hello-image - type: image - - name: bye-image - type: image - tasks: - - name: go-hello-image - taskRef: - name: kaniko-build-push - params: - - name: pathToContext - value: hello - resources: - inputs: - - name: src - resource: src - outputs: - - name: builtImage - resource: hello-image - - name: go-bye-image - taskRef: - name: kaniko-build-push - params: - - name: pathToContext - value: bye - resources: - inputs: - - name: src - resource: src - outputs: - - name: builtImage - resource: bye-image -#+end_src - - -** ~PipelineRun~ -:PROPERTIES: -:CUSTOM_ID: h:9caacd24-1667-4268-9716-d967cab7c6f1 -:END: - -#+begin_src yaml - apiVersion: tekton.dev/v1alpha1 - kind: PipelineRun - metadata: - name: kaniko-run - spec: - pipelineRef: - name: kaniko - trigger: - type: manual - serviceAccount: build-bot - resources: - - name: src - resourceRef: - name: private-go-hello - - name: hello-image - resourceRef: - name: hello-image-res - - name: bye-image - resourceRef: - name: bye-image-res -#+end_src - -* TODO Deploy to a cluster -:PROPERTIES: -:CUSTOM_ID: h:eadc5b7a-797b-4da4-a543-3116612dfb4a -:END: - -** TODO Same one, on another cluster -:PROPERTIES: -:CUSTOM_ID: h:90600634-74c2-4e04-b25c-b6665baac4d5 -:END: - -** TODO Another one, thanks to cluster resources -:PROPERTIES: -:CUSTOM_ID: h:7aaedc77-4319-4223-9790-31353447ad48 -:END: - -* TODO Using ~buildah~ -:PROPERTIES: -:CUSTOM_ID: h:6fc85dd7-034c-4170-9b69-b84df9c976eb -:END: - -* TODO Using ~helm~ -:PROPERTIES: -:CUSTOM_ID: h:6c165f41-d642-480c-b841-541a89f95875 -:END: diff --git a/www/vincent.demeester.fr/content/legacy/articles/tekton.org b/www/vincent.demeester.fr/content/legacy/articles/tekton.org @@ -1,112 +0,0 @@ -#+TITLE: Tekton - -* What is Tektoncd ? -:LOGBOOK: -CLOCK: [2020-06-12 Fri 17:57]--[2020-06-12 Fri 19:57] => 2:00 -:END: - -#+NAME: fig:tektoncd-logo -#+ATTR_ORG: :width 400/600 -#+ATTR_HTML: :width 400/600px -[[file:./images/tekton/tekton-horizontal-color.png]] - -#+begin_quote -The Tekton Pipelines project provides [[file:kubernetes.org][Kubernetes]]-style resources for declaring [[file:continuous_integration.org][CI]]/[[file:continuous_deployment.org][CD]]-style pipelines. -#+end_quote - -- Started as an experiment from [[file:knative.org][knative]] to define more advance build use cases that - [[https://github.com/knative/build/][~knative/build~]] was able to. -- Is now it's own [[https://tekton.dev][project]] and [[https://github.com/tetkon][GitHub organization]]. - -It can be deployed in [[file:openshift.org][OpenShift]] either using the upstream releases or with [[file:openshift_pipeline.org][OpenShift -Pipeline]]. - -As it is running in [[file:kubernetes.org][Kubernetes]], everything runs into [[file:containers.org][containers]]. - -* TODO Guides - -** TODO [[file:tekton-migrating-from-jenkins.org][Migrating from Jenkins to Tekton]] - -The gist of this guide is to help you migrate from Jenkins (using =Jenkinsfile=, or not) to -Tekton pipelines. - -** TODO Efficient Tekton Pipelines - -* Contributing - -- [[file:tekton_dev.org][Tekton development environment]] is a good /getting started/ article. -- [[https://github.com/tektoncd/community/blob/master/teps/README.md][Tekton Enhancement proposals (TEPs)]] are a good way to see what and how are the features - discuss in the tekton community. - -** Design Docs - -Let's list some interesting design docs I worked on (or reviewed). - -- [[https://docs.google.com/document/d/10nQSeIse7Ld4fLg4lhfgUmNKtewfaFNET3zlMdRnBuQ/edit#heading=h.nz0qjg4cmzp0][Tekton Custom Tasks]] - -** TEPs : Tekton Enhancement Proposals - -[2020-06-17 Wed] TEP, or Tekton Enhancement Proposal is a new process to to propose, -communicate and coordinate on new efforts for the Tekton project. You can read the full -details of the project in [[https://github.com/tektoncd/community/blob/master/teps/0001-tekton-enhancement-proposal-process.md][TEP-1]]. - -#+begin_quote -A standardized development process for Tekton is proposed in order to - -- provide a common structure and clear checkpoints for proposing changes to Tekton -- ensure that the motivation for a change is clear -- allow for the enumeration stability milestones and stability graduation criteria -- persist project information in a Version Control System (VCS) for future Tekton users - and contributors -- support the creation of high value user facing information such as: - + motivation for impactful user facing changes - + an overall project development roadmap -- ensure community participants are successfully able to drive changes to completion - across one or more releases while stakeholders are adequately represented throughout the - process - -*This process is supported by a unit of work called a Tekton Enhancement Proposal (TEP)*. A -TEP attempts to combine aspects of the following: - -- feature, and effort tracking document -- a product requirements document -- design document - -into one file which is created incrementally in collaboration with one or more [[https://github.com/tektoncd/community/blob/master/working-groups.md][Working -Groups (WGs)]]. - -This process does not block authors from doing early design docs using any means. It does -not block authors from sharing those design docs with the community (during Working -groups, on Slack, GitHub, …. - -This process acts as a requirement when a design docs is ready to be implemented or -integrated in the tektoncd projects. In other words, a change that impact other tektoncd -projects or users cannot be merged if there is no TEP associated with it. - -This TEP process is related to - - the generation of an architectural roadmap - the fact that the what constitutes a feature is still undefined - issue management - the difference between an accepted design and a proposal - the organization of design proposals - -This proposal attempts to place these concerns within a general framework. -#+end_quote - -The TEPs should be publish at https://teps.tekton.dev at some point. -* Links -** TODO [[https://lewo.abesis.fr/posts/2019-09-30-tekton-pipelines-the-nix-way.html][Lewo - Tekton Pipelines - the Nix way]] -[2019-10-09 Wed 17:05] -** TODO [[https://mustafaakin.dev/posts/2020-04-26-using-jsonnet-to-generate-dynamic-tekton-pipelines-in-kubernetes/][Using Jsonnet to Generate Dynamic Tekton Pipelines in Kubernetes · Mustafa Akın]] :kubernetes:tetkon: -[2020-04-28 Tue 00:41] -** TODO [[https://www.blokje5.dev/posts/compliance-in-cicd/][Building in compliance in your CI/CD pipeline with conftest · blokje5.dev]] -[2020-06-23 Tue 18:07] -** TODO [[https://technologists.dev/posts/tekton-jx-pipelines/][Jenkins X Orchestration: More than Tekton on Steroids :: CloudBees Technologists]] :tekton:jenkins:x: -[2020-05-12 Tue 10:36] - -Read and gather feedback in issues from there maybe ? -** TODO [[https://martinheinz.dev/blog/45][Cloud Native CI/CD with Tekton — Laying The Foundation]] -[2021-03-18 Thu 11:21] -** TODO [[https://martinheinz.dev/blog/47?utm_source=rss&utm_medium=referral&utm_campaign=blog_post_47][Martin Heinz | Cloud Native CI/CD with Tekton - Building Custom Tasks]] -[2021-04-16 Fri 07:01] diff --git a/www/vincent.demeester.fr/content/legacy/articles/tekton_dev.org b/www/vincent.demeester.fr/content/legacy/articles/tekton_dev.org @@ -1,266 +0,0 @@ - -#+TITLE: Tekton development environment - -* Basic development environment setup -:PROPERTIES: -:CUSTOM_ID: h:07626b12-f046-4671-87cd-858ebde959b9 -:END: - -** Requirements -:PROPERTIES: -:CUSTOM_ID: h:29af1f1c-bb22-4f51-96b2-a217279e5b04 -:END: - -- ~go~ : installation depends on your operating system -- ~ko~ : ~go get -u github.com/google/go-containerregistry/cmd/ko~ -- ~kubernetes~ - + ~minikube~ - + ~minishift~ - + … - -** ~Minikube~ -:PROPERTIES: -:CUSTOM_ID: h:8a457dfb-5144-4bd2-bc16-4a18d7bb54f6 -:END: - -#+BEGIN_SRC bash -$ minikube profile tektoncd -$ minikube config set kubernetes-version "v1.13.2" -$ minikube config set memory "8192" -$ minikube config set cpus "4" -# linux-only with libvirt, qemu-kvm -$ minikube config set vm-driver "kvm2" -$ minikube start -✅ minikube profile was successfully set to tektoncd -⚠️ These changes will take effect upon a minikube delete and then a minikube start -⚠️ These changes will take effect upon a minikube delete and then a minikube start -⚠️ These changes will take effect upon a minikube delete and then a minikube start -😄 minikube v0.35.0 on linux (amd64) -🔥 Creating kvm2 VM (CPUs=4, Memory=8192MB, Disk=20000MB) ... -📶 "tektoncd" IP address is 192.168.39.241 -🐳 Configuring Docker as the container runtime ... -✨ Preparing Kubernetes environment ... -🚜 Pulling images required by Kubernetes v1.13.2 ... -🚀 Launching Kubernetes v1.13.2 using kubeadm ... -⌛ Waiting for pods: apiserver proxy etcd scheduler controller addon-manager dns -🔑 Configuring cluster permissions ... -🤔 Verifying component health ..... -💗 kubectl is now configured to use "tektoncd" -🏄 Done! Thank you for using minikube! -#+END_SRC - -** ~Minishift~ -:PROPERTIES: -:CUSTOM_ID: h:b6e6a6cd-6130-4d8a-828e-41e609f66c19 -:END: - -#+BEGIN_SRC bash -$ minishift profile set tektoncd -$ minishift config set openshift-version "v3.11.0" -$ minishift config set memory "8192" -$ minishift config set cpus "4" -$ minishift config set image-caching "true" -$ minishift addons enable admin-user -$ minishift addons enable anyuid -$ minishift start --- Starting profile 'tektoncd' --- Check if deprecated options are used ... OK --- Checking if https://github.com is reachable ... OK --- Checking if requested OpenShift version 'v3.11.0' is valid ... OK --- Checking if requested OpenShift version 'v3.11.0' is supported ... OK --- Checking if requested hypervisor 'kvm' is supported on this platform ... OK --- Checking if KVM driver is installed ... -# […] --- Starting the OpenShift cluster using 'kvm' hypervisor ... --- Minishift VM will be configured with ... - Memory: 8 GB - vCPUs : 4 - Disk size: 20 GB -# […] - -- Starting OpenShift cluster ........... - -Creating initial project "myproject" ... -Server Information ... -OpenShift server started. - -The server is accessible via web console at: - https://192.168.42.95:8443/console - -You are logged in as: - User: developer - Password: <any value> - -To login as administrator: - oc login -u system:admin - - --- Applying addon 'admin-user':.. --- Applying addon 'anyuid':. -# […] -#+END_SRC - -** Environments -:PROPERTIES: -:CUSTOM_ID: h:4ca1bd38-6613-4b44-a276-f40680d89310 -:END: - -We need to configure ~ko~ (using ~KO_DOCKER_REPO~) so that it can deploy the working copy -code into our development cluster. - -- ~minikube~ (or ~minishift~) with ~docker~ as container runtime - 1. Make sure your local ~docker~ command-line points to the VM daemon - #+BEGIN_SRC bash - eval $(minikube docker-env) - # eval $(minishift docker-env) # for minishift - #+END_SRC - 2. Use ~ko.local~ as ~KO_DOCKER_REPO~ — it's a special case handled by ~ko~ - #+BEGIN_SRC bash - export KO_DOCKER_REPO=ko.local - #+END_SRC -- for any cluster using another runtime (or a remote cluster), you need to use a registry - that will be accessible from the cluster (~gcr.io~ or your own – the docker hub doesn't - work with ~ko~). - -** Deploy ~tektoncd/pipeline~ -:PROPERTIES: -:CUSTOM_ID: h:f8a6a774-f886-492c-a268-2d896cf0918d -:END: - -1. ~tektoncd/pipeline~ needs to sit on the right place in your ~GOPATH~ - - #+BEGIN_SRC bash - $ echo $GOPATH - /home/vincent - $ pwd - /home/vincent/src/github.com/tektoncd/pipeline - #+END_SRC - -2. Deploy 💃 - - #+BEGIN_SRC bash - $ ko apply -f ./config - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/webhook - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/gsutil - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/controller - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/nop - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/creds-init - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/git-init - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/kubeconfigwriter - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/bash - 2019/03/13 10:49:22 Building github.com/tektoncd/pipeline/cmd/entrypoint - namespace/tekton-pipelines created - clusterrole.rbac.authorization.k8s.io/tekton-pipelines-admin created - serviceaccount/tekton-pipelines-controller created - clusterrolebinding.rbac.authorization.k8s.io/tekton-pipelines-controller-admin created - 2019/03/13 10:49:23 Using base index.docker.io/library/busybox:latest for github.com/tektoncd/pipeline/cmd/entrypoint - 2019/03/13 10:49:23 Using base gcr.io/distroless/static:latest for github.com/tektoncd/pipeline/cmd/nop - # […] - deployment.apps/tekton-pipelines-controller created - deployment.apps/tekton-pipelines-webhook created - #+END_SRC - -3. Enjoy 🔥 - - #+BEGIN_SRC bash - $ kubectl get all -n tekton-pipelines - NAME READY STATUS RESTARTS AGE - pod/tekton-pipelines-controller-5875857cf5-k9njx 1/1 Running 0 3m18s - pod/tekton-pipelines-webhook-54785c88f4-jbkqr 1/1 Running 0 3m18s - - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - service/tekton-pipelines-controller ClusterIP 10.104.145.40 <none> 9090/TCP 4m31s - service/tekton-pipelines-webhook ClusterIP 10.97.9.56 <none> 443/TCP 4m31s - - NAME READY UP-TO-DATE AVAILABLE AGE - deployment.apps/tekton-pipelines-controller 1/1 1 1 3m18s - deployment.apps/tekton-pipelines-webhook 1/1 1 1 3m18s - - NAME DESIRED CURRENT READY AGE - replicaset.apps/tekton-pipelines-controller-5875857cf5 1 1 1 3m18s - replicaset.apps/tekton-pipelines-webhook-54785c88f4 1 1 1 3m18s - #+END_SRC - -** An example -:PROPERTIES: -:CUSTOM_ID: h:99cb715a-3807-414e-9b73-2d60bacbe583 -:END: - -Let's validate it works by running a simple example - -#+BEGIN_SRC yaml -apiVersion: tekton.dev/v1alpha1 -kind: Task -metadata: - name: build-simple -spec: - steps: - - name: build-simple - image: docker.io/library/busybox - command: - - /bin/sh - args: - - -c - - "echo hello world" ---- -apiVersion: tekton.dev/v1alpha1 -kind: TaskRun -metadata: - name: build-simple -spec: - taskRef: - name: build-simple - trigger: - type: manual -#+END_SRC - -#+BEGIN_SRC bash -$ kubectl apply -f ./test.yaml -task.tekton.dev/build-simple created -taskrun.tekton.dev/build-simple created -#+END_SRC - -Let's now look at what's in our namespace - -#+BEGIN_SRC bash -$ kubectl get all -NAME READY STATUS RESTARTS AGE -pod/build-simple-pod-ada879 0/2 Completed 0 10s - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26m - -NAME AGE -task.tekton.dev/build-simple 10s - -NAME AGE -taskrun.tekton.dev/build-simple 10s -#+END_SRC -* Development workflow -:PROPERTIES: -:CUSTOM_ID: h:89f26869-04b1-402f-af3a-77946dec25b2 -:END: - -When you're working on ~pipeline~, usually you want : - -1. make sure it compiles : ~go build -v ./..~ -2. Running unit tests : ~go test ./...~ (bonus use [[https://github.com/vdemeester/ram][~ram~]] for continuous testing) -3. End-to-end tests : ~go test -tags e2e ./...~ (or simply using `./test/` package) - - *Make sure you re-deploy before running the e2e tests* using ~ko apply -f ./config~, - otherwise you're testing the wrong code. - -* Code walkthrough -:PROPERTIES: -:CUSTOM_ID: h:0964e161-7ddd-40f9-a224-207e68b941fe -:END: - -Let's look into ~tektoncd/pipeline~ sources - -- Go packages - + ~cmd~ - + ~pkg~ - - ~apis~ : api types - - ~client~ : generated client - - ~reconcilier~ : core of the pipeline controller -- Tests -- CI related files diff --git a/www/vincent.demeester.fr/content/legacy/articles/test.resource.yaml b/www/vincent.demeester.fr/content/legacy/articles/test.resource.yaml @@ -1,57 +0,0 @@ -apiVersion: tekton.dev/v1alpha1 -kind: PipelineResource -metadata: - name: skaffold-git -spec: - type: git - params: - - name: revision - value: master - - name: url - value: https://github.com/GoogleContainerTools/skaffold ---- -#Builds an image via kaniko and pushes it to registry. -apiVersion: tekton.dev/v1alpha1 -kind: Task -metadata: - name: build-simple -spec: - inputs: - resources: - - name: workspace - type: git - params: - - name: pathToDockerFile - description: The path to the dockerfile to build - default: /workspace/workspace/Dockerfile - - name: pathToContext - description: The build context used by Kaniko (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts) - default: /workspace/workspace - steps: - - name: build-simple - image: docker.io/library/busybox - command: - - /bin/sh - args: - - -c - - "ls -l ${pathToDockerFile} ${pathToContext}" ---- -apiVersion: tekton.dev/v1alpha1 -kind: TaskRun -metadata: - name: build-simple -spec: - taskRef: - name: build-simple - trigger: - type: manual - inputs: - resources: - - name: workspace - resourceRef: - name: skaffold-git - params: - - name: pathToDockerFile - value: Dockerfile - - name: pathToContext - value: /workspace/workspace/examples/microservices/leeroy-web diff --git a/www/vincent.demeester.fr/content/legacy/articles/test.yaml b/www/vincent.demeester.fr/content/legacy/articles/test.yaml @@ -1,30 +0,0 @@ -apiVersion: tekton.dev/v1alpha1 -kind: TaskRun -metadata: - name: build-simple -spec: - taskSpec: - steps: - - name: echo - image: docker.io/library/busybox - command: - - /bin/sh - args: - - -c - - "echo echo" - - name: exit - image: docker.io/library/busybox - command: - - /bin/sh - args: - - -c - - "exit 1" - - name: echo-again - image: docker.io/library/busybox - command: - - /bin/sh - args: - - -c - - "sleep 30s" - trigger: - type: manual diff --git a/www/vincent.demeester.fr/content/legacy/articles/testing.org b/www/vincent.demeester.fr/content/legacy/articles/testing.org @@ -1,51 +0,0 @@ -#+TITLE: Testing -#+FILETAGS: language programming testing -#+SETUPFILE: .setup.org - -* Links - -** TODO [[https://ahuth.github.io/content/articles/what-are-unit-tests-for.html][What are Unit Tests For?]] -[2020-06-11 Thu 10:49] -** TODO [[https://mike-bland.com/2012/08/10/call-me-ishmael.html][Call me Ishmael]] - -Interesting article about testing at google. Read the following also: -- https://mike-bland.com/2012/08/16/oop-revisited.html -- https://mike-bland.com/2012/09/11/practice-of-testing.html -- https://mike-bland.com/2012/09/13/process.html -- https://mike-bland.com/2012/10/01/tools.html - -** TODO [[https://dave.cheney.net/2019/05/14/why-bother-writing-tests-at-all][Why bother writing tests at all? | Dave Cheney]] -[2019-05-18 Sat 12:49] - -** TODO [[https://medium.com/scopedev/testing-in-the-cloud-native-era-41f63a0e101b][Testing in the Cloud Native Era - Scope - Medium]] -[2019-11-06 Wed 19:21] - -** TODO [[https://www.hillelwayne.com/post/contract-examples/][Finding Property Tests • Hillel Wayne]] :haskell: -[2019-11-29 Fri 19:55] - -** TODO [[https://8thlight.com/blog/rani-zilpelwar/2019/12/10/write-flexible-and-clear-unit-tests.html][How to Write Flexible and Clear Unit Tests | 8th Light]] -[2019-12-12 Thu 13:41] -** TODO [[https://www.arp242.net/testing.html][Testing isn’t everything]] -[2019-12-12 Thu 18:03] - -** TODO [[https://madeintandem.com/blog/five-factor-testing/][Five Factor Testing | Tandem]] -[2020-02-08 Sat 16:49] - -** TODO [[http://calpaterson.com/against-database-teardown.html][The argument against clearing the database between tests]] :database:test: -[2020-04-28 Tue 00:41] - -** TODO [[https://www.dein.fr/2019-09-06-test-coverage-only-matters-if-at-100-percent.html][Test coverage only matters if it's at 100% | dein.fr]] :testing: -[2020-05-19 Tue 16:29] -** TODO [[https://www.innoq.com/en/blog/why-you-should-write-automated-tests/][Why You Should Write Automated Tests – INNOQ]] -[2020-08-27 Thu 12:57] - -** TODO [[https://lukeplant.me.uk/blog/posts/test-smarter-not-harder/][Test smarter, not harder - lukeplant.me.uk]] -[2020-09-11 Fri 10:51] - -For many religions, the more painful an activity, and the more you do it, the more meritorious it is — and it may even atone for past misdeeds. If you take that mindset with you into writing tests, you will do a rather bad job. -** TODO [[https://blog.auxon.io/2021/02/01/effective-property-based-testing/][Effective Property-Based Testing | Blog – Auxon Corporation]] -[2021-02-03 Wed 10:51] -** TODO [[https://www.innoq.com/en/blog/anatomy-of-a-good-test/][Anatomy of a Good Test – INNOQ]] -[2020-09-25 Fri 11:50] -** TODO [[https://gregberge.com/blog/testing-hooks][Better tests with "Testing Hooks" pattern]] -[2020-07-01 Wed 19:01] diff --git a/www/vincent.demeester.fr/content/legacy/articles/typography.org b/www/vincent.demeester.fr/content/legacy/articles/typography.org @@ -1,5 +0,0 @@ -#+TITLE: Typography - -* Links -** TODO [[https://practicaltypography.com/][Butterick’s Practical Typography]] -[2020-01-21 Tue 18:47] diff --git a/www/vincent.demeester.fr/content/legacy/articles/ubuntu.org b/www/vincent.demeester.fr/content/legacy/articles/ubuntu.org @@ -1,2 +0,0 @@ - -#+TITLE: Ubuntu diff --git a/www/vincent.demeester.fr/content/legacy/articles/virtualization.org b/www/vincent.demeester.fr/content/legacy/articles/virtualization.org @@ -1,11 +0,0 @@ -#+TITLE: Virtualization -#+FILETAGS: virtualization -#+SETUPFILE: .setup.org - -* Links -** TODO [[https://drewdevault.com/2018/09/10/Getting-started-with-qemu.html][Getting started with qemu | Drew DeVault’s Blog]] -** TODO [[https://nixos.mayflower.consulting/blog/2017/03/10/from-vagrant-to-nixops/][From Vagrant to NixOps]] :nixos: -** TODO [[https://nixos.mayflower.consulting/blog/2018/09/11/custom-images/][Building Customised NixOS Images]] :nixos: - -** [[https://nixos.wiki/wiki/Virtualization_in_NixOS][Virtualization in NixOS - NixOS Wiki]] -[2020-06-11 Thu 15:25] diff --git a/www/vincent.demeester.fr/content/legacy/articles/vterm.org b/www/vincent.demeester.fr/content/legacy/articles/vterm.org @@ -1,2 +0,0 @@ - -#+TITLE: vterm diff --git a/www/vincent.demeester.fr/content/legacy/articles/wireguard.org b/www/vincent.demeester.fr/content/legacy/articles/wireguard.org @@ -1,6 +0,0 @@ -#+TITLE: Wireguard -#+FILETAGS: linux wireguard vpn -#+SETUPFILE: .setup.org - -* Links -** TODO [[https://reflexivereflection.com/posts/2018-12-18-wireguard-vpn-with-network-namespace-on-nixos.html][Reflexive Reflection - Wireguard vpn with network namespace on NixOS]] :nixos: diff --git a/www/vincent.demeester.fr/content/legacy/articles/writing_technical_book.org b/www/vincent.demeester.fr/content/legacy/articles/writing_technical_book.org @@ -1,26 +0,0 @@ -#+TITLE: Writing a Technical Book -#+FILETAGS: book writing technical - -* Links -** TODO [[https://www.electronicdesign.com/blogs/article/21802756/10-tips-for-writing-your-first-technical-book][10 Tips for Writing Your First Technical Book | Electronic Design]] -[2020-11-20 Fri 11:21] - -** TODO [[https://www.freecodecamp.org/news/how-to-write-your-first-technical-book/][How to Write Your First Technical Book: Tools, Techniques, and Resources for First-time Developer Authors]] -[2020-11-20 Fri 11:21] - -** TODO [[https://www.freecodecamp.org/news/how-to-write-your-first-technical-book/][How to Write Your First Technical Book: Tools, Techniques, and Resources for First-time Developer Authors]] -[2020-11-20 Fri 11:21] - -** TODO [[https://paulcunningham.me/writing-technical-books/][Writing Technical Books - A Guide to Getting Started]] -[2020-11-20 Fri 11:22] - -** TODO [[https://manuel.bernhardt.io/2016/07/15/the-reality-of-writing-a-technical-book/][The reality of writing a technical book - manuel bernhardt]] -[2020-11-20 Fri 11:22] - -** TODO [[https://www.adamtornhill.com/articles/writingbook/writingtechbook.htm][Writing a Technical Book]] -[2020-11-20 Fri 11:22] -** TODO [[https://www.quora.com/What-is-it-like-to-write-for-Packt][What is it like to write for Packt? - Quora]] -[2020-11-20 Fri 12:07] - -** TODO [[https://medium.com/@brenn.a.hill/how-to-write-a-technical-book-a8e15e694c59][Lessons From Writing a Technical Book | by Brenn | Medium]] -[2020-11-20 Fri 12:07] diff --git a/www/vincent.demeester.fr/content/legacy/articles/yoga.org b/www/vincent.demeester.fr/content/legacy/articles/yoga.org @@ -1,3 +0,0 @@ - -#+TITLE: Yoga -#+ROAM_ALIAS: "yoga" diff --git a/www/vincent.demeester.fr/content/legacy/articles/yubikey.org b/www/vincent.demeester.fr/content/legacy/articles/yubikey.org @@ -1,113 +0,0 @@ -#+TITLE: Yubikey setup on Linux -#+SUBTITLE: Trying to use yubikey to its full potential on Linux -#+FILETAGS: yubikey linux -#+SETUPFILE: .setup.org - -A YubiKey is a hardware authentication device that can be used for various one-time -password (OTP) and authentication methods. This article explains how I setup my yubikey -and operating system (most likely only different GNU/Linux distribution) for it. - -The goal is to use the yubikey for: -- GnuPG subkeys for signing and encrypting -- Main SSH key (using ~gpg-agent~, …) -- Dual authentication using OTP (time-based, event-based) - -The yubikey manual[fn:1] (at least the version that seem to refer the yubikey neo I have) -is the base read but there is plenty of useful article on the subject. This is also based -on my usage of the yubikey, so it might vary from your usage. - -* TODO GnuPG -:PROPERTIES: -:CUSTOM_ID: h:168c7019-2c6b-4872-84d2-7535a3a38f91 -:END: - -Some assumptions are made in this section: - -- You know a tiny bit of GnuPG and the ~gpg~ command (at least the basics) -- You have a backup of your GnuPG configuration (usually ~$HOME/.gnupg~) — just in case 👼 -- You have an existing GnuPG key (private/public) - -We are going to use GnuPG subkeys (for security, as we won't have the /master/ key -anywhere on the machines, only offline). If you are interested in how it works and how to -configure it, here is a [[https://blog.tinned-software.net/create-gnupg-key-with-sub-keys-to-sign-encrypt-authenticate/][guide]]. The following is a mere /rip-off/ of the yubikey developer -article : [[https://developers.yubico.com/PGP/Importing_keys.html][Importing keys]]. - -Let's first see if our gpg version supports our yubikey. - -#+begin_src shell -$ gpg-connect-agent --hex "scd apdu 00 f1 00 00" /bye -D[0000] 01 00 05 90 00 ..... -OK -#+end_src - -We need to have our secret key on the machine we are using to setup the yubikey. Once the -setup is done, we will reset the ~.gnupg~ so that the machine doesn't have the main key -(or even the subkey for that matter). - -#+begin_src shell - $ gpg --list-secret-keys - # […] - -------------------------------- - sec rsa2048 2013-05-19 [SC] - 8C4E8DDA04C18C6B503BD2DBB7E7CF1C634256FA - uid [ultimate] Vincent Demeester (vdemeester) <vincent@demeester.fr> - uid [ultimate] Vincent Demeester <vincent@sbr.pm> - uid [ultimate] Vincent Demeester <vdemeest@redhat.com> - uid [ultimate] [jpeg image of size 4711] - ssb> rsa2048 2013-05-19 [E] - ssb rsa4096 2019-04-07 [S] [expires: 2022-04-06] - ssb> rsa2048 2019-07-02 [S] - ssb> rsa2048 2019-07-02 [A] -#+end_src - - - -* TODO SSH -:PROPERTIES: -:CUSTOM_ID: h:55406d2f-0f1f-4ef7-9ec1-634d9fcaaedc -:END: - -We are using a GnuPG key as ssh key, and we are storing this into the yubikey (in the -~Authentication Key~ slot). - -* TODO Dual authentication -:PROPERTIES: -:CUSTOM_ID: h:f3ecbc48-0c51-4dcd-b075-0575b06fff7b -:END: - -* TODO Some more automation -:PROPERTIES: -:CUSTOM_ID: h:8398bd8f-12ca-4167-84ae-6c9a63aa41e6 -:END: - -* References -:PROPERTIES: -:CUSTOM_ID: h:ec8f52e7-9b54-42da-95f8-ff5c44445118 -:END: - -- https://fedoraproject.org/wiki/Using_Yubikeys_with_Fedora -- https://fedoraproject.org/wiki/Infrastructure/Yubikey -- https://fedoramagazine.org/using-the-yubikey4-with-fedora/ -- https://developers.yubico.com/PGP/Importing_keys.html -- https://developers.yubico.com/ -- https://github.com/fedora-infra/ssh-gpg-smartcard-config/ - + https://github.com/fedora-infra/ssh-gpg-smartcard-config/blob/master/Linux.md -- https://www.gnupg.org/gph/en/manual/x110.html -- https://github.com/cornelinux/yubikey-luks -- https://rzetterberg.github.io/yubikey-gpg-nixos.html -- https://github.com/drduh/YubiKey-Guide -- https://blog.tinned-software.net/create-gnupg-key-with-sub-keys-to-sign-encrypt-authenticate/ -- https://nixos.wiki/wiki/Yubikey_based_Full_Disk_Encryption_(FDE)_on_NixOS -- https://suchsecurity.com/gpg-and-ssh-with-yubikey-on-windows.html -- https://codingnest.com/how-to-use-gpg-with-yubikey-wsl/ -- https://metebalci.com/blog/using-u2f-at-linux-login/ -- https://0day.work/locking-the-screen-when-removing-a-yubikey/ -- https://gist.github.com/jhass/070207e9d22b314d9992 -- https://wiki.realmofespionage.xyz/distros:fedora_workstation_gnome - -* Footnotes -:PROPERTIES: -:CUSTOM_ID: h:75eb511c-1d78-40ba-8a4a-4a1111f40d82 -:END: - -[fn:1] https://www.yubico.com/wp-content/uploads/2015/03/YubiKeyManual_v3.4.pdf diff --git a/www/vincent.demeester.fr/content/legacy/articles/zsh.org b/www/vincent.demeester.fr/content/legacy/articles/zsh.org @@ -1,6 +0,0 @@ -#+TITLE: zsh - -* Links - -** TODO [[https://ebzzry.io/en/zsh-tips-4/][Zsh Tips 4: General Helpers]] :zsh: -[2020-04-16 Thu 19:00] diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-05-07-reinit-and-jekyll.org b/www/vincent.demeester.fr/content/legacy/posts/2012-05-07-reinit-and-jekyll.org @@ -1,61 +0,0 @@ -#+title: Reinit and Jekyll -#+date: <2012-05-07 Mon> -#+filetags: website jekyll -#+setupfile: ../templates/post.org - -* Introduction - -Two weeks ago, my /online/ personal server has been attacked and, -somehow, died. I'm in the process of re-installation of it but I'm going -to hardened a bit the security on it. Anyway, this crash meant that -every piece of site I maintain has been down. That's why I moved this -/identity site/ on the github pages, using a CNAME ; That way I can -crash as much as I want my server(s), this page should still be up for a -while. - -And I'm switching on Jekyll for this website as It is supported by -Github page, easy to use and easy to deploy elsewhere (if one day I want -to move from Github). - -The rest of the post is going to be used as a /sandbox/ post to test the -site styles. - -#+BEGIN_QUOTE - This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, - consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. - Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. - - Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse - id sem consectetuer libero luctus adipiscing. -#+END_QUOTE - -** Highlight - :PROPERTIES: - :CUSTOM_ID: highlight - :ID: 6e1687a1-6898-4fe1-ac56-53b6e1e1f310 - :END: - -#+begin_src ruby -def foo puts 'foo' end -#+end_src - -Some bash script... - -#+begin_src bash -#!/bin/bash -update_gems() { - echo "Update gems for all versions ? (y/N)" - read UPDATE_GEMS - test -z "${UPDATE_GEMS}" && UPDATE_GEMS="n" - - if test "${UPDATE_GEMS}" = "y"; then - for version in =ls --color=never $HOME/.rbenv/versions=; do - echo "Updating ${version%/}" - RBENV_VERSION="${version%/}" rbenv exec gem update - RBENV_VERSION="${version%/}" rbenv exec gem install bundler - done - fi -} - -update_gems -#+end_src diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-05-07-reinit-and-jekyll/index.html b/www/vincent.demeester.fr/content/legacy/posts/2012-05-07-reinit-and-jekyll/index.html @@ -1,161 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2012-05-07-reinit-and-jekyll/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Reinit and Jekyll</h1><a href='https://vincent.demeester.fr/posts/2012-05-07-reinit-and-jekyll/'></a> - <address class="signature"> - <span class="date">Mon, 7 May, 2012</span> - <span class="words">(300 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#me">me</a></li> - - - - - - <li class="tag tag-intro"><a href="/tags/#intro">intro<span>1</span></a></li> - - - <li class="tag tag-jekyll"><a href="/tags/#jekyll">jekyll<span>4</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Two weeks ago, my <em>online</em> personal server has been attacked and, somehow, died. I’m in the process -of re-installation of it but I’m going to hardened a bit the security on it. Anyway, this crash meant -that every piece of site I maintain has been down. That’s why I moved this <em>identity site</em> on the -github pages, using a CNAME ; That way I can crash as much as I want my server(s), this page should -still be up for a while.</p> - -<p>And I’m switching on Jekyll for this website as It is supported by Github page, easy to use and easy -to deploy elsewhere (if one day I want to move from Github).</p> - -<p>The rest of the post is going to be used as a <em>sandbox</em> post to test the site styles.</p> - -<blockquote> -<p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, -consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. -Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p> - -<p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse -id sem consectetuer libero luctus adipiscing.</p> -</blockquote> - -<h2 id="highlight">Highlight</h2> - -<div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span> - <span class="nb">puts</span> <span class="s1">'foo'</span> -<span class="k">end</span></code></pre></div> - -<p>Some bash script…</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="cp">#!/bin/bash -</span><span class="cp"></span>update_gems<span class="o">()</span> <span class="o">{</span> - <span class="nb">echo</span> <span class="s2">"Update gems for all versions ? (y/N)"</span> - <span class="nb">read</span> UPDATE_GEMS - <span class="nb">test</span> -z <span class="s2">"</span><span class="si">${</span><span class="nv">UPDATE_GEMS</span><span class="si">}</span><span class="s2">"</span> <span class="o">&&</span> <span class="nv">UPDATE_GEMS</span><span class="o">=</span><span class="s2">"n"</span> - <span class="k">if</span> <span class="nb">test</span> <span class="s2">"</span><span class="si">${</span><span class="nv">UPDATE_GEMS</span><span class="si">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"y"</span><span class="p">;</span> <span class="k">then</span> - <span class="k">for</span> version in <span class="sb">`</span>ls --color<span class="o">=</span>never <span class="nv">$HOME</span>/.rbenv/versions<span class="sb">`</span><span class="p">;</span> <span class="k">do</span> - <span class="nb">echo</span> <span class="s2">"Updating </span><span class="si">${</span><span class="nv">version</span><span class="p">%/</span><span class="si">}</span><span class="s2">"</span> - <span class="nv">RBENV_VERSION</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">version</span><span class="p">%/</span><span class="si">}</span><span class="s2">"</span> rbenv <span class="nb">exec</span> gem update - <span class="nv">RBENV_VERSION</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">version</span><span class="p">%/</span><span class="si">}</span><span class="s2">"</span> rbenv <span class="nb">exec</span> gem install bundler - <span class="k">done</span> - <span class="k">fi</span> -<span class="o">}</span> - -update_gems</code></pre></div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2012-05-08-gitolite-quick-and-dirty-mirror/" title="Gitolite quick and dirty mirror">← Previous post</a> - - - - <a class="paging-link next" href="/about/" title="About">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror.org b/www/vincent.demeester.fr/content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror.org @@ -1,126 +0,0 @@ -#+title: Gitolite quick and dirty mirror -#+date: <2012-05-08 Tue> -#+filetags: gitolite git linux mirror github -#+setupfile: ../templates/post.org - -* Introduction - -I'm running a gitolite _instance_ on my personal server to manage my repositories -(personnal, private or public) ; and I am quickly going to share with you how I setup a -_quick and dirty_ mirror feature. - -First, I am using **gitolite 3**. The mirroring we are going to setup is not the -_supported_ [[http://sitaramc.github.com/gitolite/mirroring.html][mirroring *built-in*]]. We are going to implement a simplier way to set mirror -thing : - -1. Write a custom gitolite command ; the idea is to be able to write ~git-config~ stuff. -2. Write a hook that take a specific ~git-config~ (let say ~mirror.url~) and do a simple - mirroring. - -* Gitolite commands - -Gitolite 3 has been rewritten to be more flexible : [[http://sitaramc.github.com/gitolite/g3why.html][Why a completely new version]]. The -rewrite made it really easy to extend gitolite. +I've fork [[https://github.com/vdemeester/gitolite][gitolite]] on github+ I've -created a [[http://github.com/vdemeester/vdemeester-gitolite-local-code][repository git]] to easily add commands to my gitolite instance via _local -code_. The gitolite command I wrote is a quick and dirty script in shell to add ~git -config~. The source should speek for itself ; It _should_ include some way to check if the -given config is not already present in the ~gitolite-admin~ configuration file — and so -might be rewritten in ~Perl~. - -The command is ~write-git-config~ because a ~git-config~ command already exists -in the built-in commands. - -#+begin_src bash -#!/bin/sh - -# Usage: ssh git@host write-git-config <repo> <key> <value> -# -# Set git-config value for user-created ("wild") repo. - -die() { echo "$@" >&2; exit 1; } -usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } -[ -z "$1" ] && [ -z "$2" ] && [ -z "$3" ] && usage -[ "$1" = "-h" ] && usage -[ -z "$GL_USER" ] && die GL_USER not set - -# ---------------------------------------------------------------------- -repo=$1; shift -key=$1; shift -value=$1; shift - -# this shell script takes arguments that are completely under the user's -# control, so make sure you quote those suckers! - -if gitolite query-rc -q WRITER_CAN_UPDATE_DESC -then - gitolite access -q "$repo" $GL_USER W any || die You are not authorised -else - gitolite creator "$repo" $GL_USER || die You are not authorised -fi - -# if it passes, $repo is a valid repo name so it is known to contain only sane -# characters. This is because 'gitolite creator' return true only if there -# *is* a repo of that name and it has a gl-creator file that contains the same -# text as $GL_USER. - -configfile=`gitolite query-rc GL_REPO_BASE`/"$repo".git/config - -git config --file "$configfile" "$key" "$value" -#+end_src - -* Gitolite hooks - -The next step is to write a quick ~post-receive~ hook that check if there is a -certain ~git-config~ entry and run ~git push --mirror~. The file is in -~$HOME/.gitolite/hooks/common/post-receive~ ; you could add a better system to -hooks (to be able to add "dynamic" hooks, …). - -#+begin_src bash - -#!/bin/sh - -# Simple gitolite mirroring - -# flush STDIN coming from git, because gitolite's own post-receive.mirrorpush -# script does the same thing -[ -t 0 ] || cat >/dev/null - -[ -z "$GL_REPO" ] && die GL_REPO not set - -target=`git config --get mirror.url` -[ -z "$target" ] && exit 0 - -# Support a REPO variable for wildcard mirrors -gl_repo_escaped=$(echo $GL_REPO | sed 's/\//\\\//g') -target=$(echo $target | sed -e "s/REPO/$gl_repo_escaped/g") - -# Do the mirror push -git push --mirror $target -#+end_src - -The next, and final step is to run `gitolite compile` to update links to hooks -for every repositories. - -* For real - -And finaly, this is the final step you'll do. - -#+begin_src bash -$ ssh git@host write-git-config vincent/vcsh-home mirror.url git@github.com:vdemeester/vcsh-home.git -$ git push -Counting objects: 5, done. -Delta compression using up to 2 threads. -Compressing objects: 100% (3/3), done. -Writing objects: 100% (3/3), 294 bytes, done. -Total 3 (delta 2), reused 0 (delta 0) -remote: To git@github.com:vdemeester/vcsh-home.git -remote: 65681a8..701c990 master -> master -To git@host:vincent/vcsh-home.git - 65681a8..701c990 master -> master -#+end_src - - -And that should be it ! - -_Update 2012/10/04_ : Moved from gitolite fork to _gitolite local code_ -repository. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror/index.html b/www/vincent.demeester.fr/content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror/index.html @@ -1,243 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2012-05-08-gitolite-quick-and-dirty-mirror/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Gitolite quick and dirty mirror</h1><a href='https://vincent.demeester.fr/posts/2012-05-08-gitolite-quick-and-dirty-mirror/'></a> - <address class="signature"> - <span class="date">Tue, 8 May, 2012</span> - <span class="words">(700 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-gitolite"><a href="/tags/#gitolite">gitolite<span>1</span></a></li> - - - <li class="tag tag-git"><a href="/tags/#git">git<span>3</span></a></li> - - - <li class="tag tag-linux"><a href="/tags/#linux">linux<span>4</span></a></li> - - - <li class="tag tag-mirror"><a href="/tags/#mirror">mirror<span>1</span></a></li> - - - <li class="tag tag-github"><a href="/tags/#github">github<span>2</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>I’m running a gitolite <em>instance</em> on my personal server to manage my repositories -(personnal, private or public) ; and I am quickly going to share with you how I -setup a <em>quick and dirty</em> mirror feature.</p> - -<p>First, I am using <strong>gitolite 3</strong>. The mirroring we are going to setup is not the -<em>supported</em> <a href="http://sitaramc.github.com/gitolite/mirroring.html">mirroring <strong>built-in</strong></a>. -We are going to implement a simplier way to set mirror thing :</p> - -<ol> -<li>Write a custom gitolite command ; the idea is to be able to write <code>git-config</code> -stuff.</li> -<li>Write a hook that take a specific <code>git-config</code> (let say <code>mirror.url</code>) and do -a simple mirroring.</li> -</ol> - -<h1 id="gitolite-commands">Gitolite commands</h1> - -<p>Gitolite 3 has been rewritten to be more flexible : <a href="http://sitaramc.github.com/gitolite/g3why.html">Why a completely new version</a>. -The rewrite made it really easy to extend gitolite. <del>I’ve fork <a href="https://github.com/vdemeester/gitolite">gitolite</a> on github</del> -I’ve created a <a href="http://github.com/vdemeester/vdemeester-gitolite-local-code">repository git</a> -to easily add commands to my gitolite instance via <em>local code</em>. The gitolite command I wrote is -a quick and dirty script in shell to add <code>git config</code>. The source should speek -for itself ; It <em>should</em> include some way to check if the given config is not -already present in the <code>gitolite-admin</code> configuration file — and so might be -rewritten in <code>Perl</code>.</p> - -<p>The command is <code>write-git-config</code> because a <code>git-config</code> command already exists -in the built-in commands.</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="cp">#!/bin/sh -</span><span class="cp"></span> -<span class="c1"># Usage: ssh git@host write-git-config <repo> <key> <value></span> -# -<span class="c1"># Set git-config value for user-created ("wild") repo.</span> - -die<span class="o">()</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span> ><span class="p">&</span><span class="m">2</span><span class="p">;</span> <span class="nb">exit</span> <span class="m">1</span><span class="p">;</span> <span class="o">}</span> -usage<span class="o">()</span> <span class="o">{</span> perl -lne <span class="s1">'print substr($_, 2) if /^# Usage/../^$/'</span> < <span class="nv">$0</span><span class="p">;</span> <span class="nb">exit</span> <span class="m">1</span><span class="p">;</span> <span class="o">}</span> -<span class="o">[</span> -z <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">[</span> -z <span class="s2">"</span><span class="nv">$2</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">[</span> -z <span class="s2">"</span><span class="nv">$3</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> usage -<span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"-h"</span> <span class="o">]</span> <span class="o">&&</span> usage -<span class="o">[</span> -z <span class="s2">"</span><span class="nv">$GL_USER</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> die GL_USER not <span class="nb">set</span> - -<span class="c1"># ----------------------------------------------------------------------</span> -<span class="nv">repo</span><span class="o">=</span><span class="nv">$1</span><span class="p">;</span> <span class="nb">shift</span> -<span class="nv">key</span><span class="o">=</span><span class="nv">$1</span><span class="p">;</span> <span class="nb">shift</span> -<span class="nv">value</span><span class="o">=</span><span class="nv">$1</span><span class="p">;</span> <span class="nb">shift</span> - -<span class="c1"># this shell script takes arguments that are completely under the user's</span> -<span class="c1"># control, so make sure you quote those suckers!</span> - -<span class="k">if</span> gitolite query-rc -q WRITER_CAN_UPDATE_DESC -<span class="k">then</span> - gitolite access -q <span class="s2">"</span><span class="nv">$repo</span><span class="s2">"</span> <span class="nv">$GL_USER</span> W any <span class="o">||</span> die You are not authorised -<span class="k">else</span> - gitolite creator <span class="s2">"</span><span class="nv">$repo</span><span class="s2">"</span> <span class="nv">$GL_USER</span> <span class="o">||</span> die You are not authorised -<span class="k">fi</span> - -<span class="c1"># if it passes, $repo is a valid repo name so it is known to contain only sane</span> -<span class="c1"># characters. This is because 'gitolite creator' return true only if there</span> -<span class="c1"># *is* a repo of that name and it has a gl-creator file that contains the same</span> -<span class="c1"># text as $GL_USER.</span> - -<span class="nv">configfile</span><span class="o">=</span><span class="sb">`</span>gitolite query-rc GL_REPO_BASE<span class="sb">`</span>/<span class="s2">"</span><span class="nv">$repo</span><span class="s2">"</span>.git/config - -git config --file <span class="s2">"</span><span class="nv">$configfile</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$key</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$value</span><span class="s2">"</span></code></pre></div> - -<h1 id="gitolite-hooks">Gitolite hooks</h1> - -<p>The next step is to write a quick <code>post-receive</code> hook that check if there is a -certain <code>git-config</code> entry and run <code>git push --mirror</code>. The file is in -<code>$HOME/.gitolite/hooks/common/post-receive</code> ; you could add a better system to -hooks (to be able to add “dynamic” hooks, …).</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="cp">#!/bin/sh -</span><span class="cp"></span> -<span class="c1"># Simple gitolite mirroring</span> - -<span class="c1"># flush STDIN coming from git, because gitolite's own post-receive.mirrorpush</span> -<span class="c1"># script does the same thing</span> -<span class="o">[</span> -t <span class="m">0</span> <span class="o">]</span> <span class="o">||</span> cat >/dev/null - -<span class="o">[</span> -z <span class="s2">"</span><span class="nv">$GL_REPO</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> die GL_REPO not <span class="nb">set</span> - -<span class="nv">target</span><span class="o">=</span><span class="sb">`</span>git config --get mirror.url<span class="sb">`</span> -<span class="o">[</span> -z <span class="s2">"</span><span class="nv">$target</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="nb">exit</span> <span class="m">0</span> - -<span class="c1"># Support a REPO variable for wildcard mirrors</span> -<span class="nv">gl_repo_escaped</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="nv">$GL_REPO</span> <span class="p">|</span> sed <span class="s1">'s/\//\\\//g'</span><span class="k">)</span> -<span class="nv">target</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="nv">$target</span> <span class="p">|</span> sed -e <span class="s2">"s/REPO/</span><span class="nv">$gl_repo_escaped</span><span class="s2">/g"</span><span class="k">)</span> - -<span class="c1"># Do the mirror push</span> -git push --mirror <span class="nv">$target</span></code></pre></div> - -<p>The next, and final step is to run <code>gitolite compile</code> to update links to hooks -for every repositories.</p> - -<h1 id="for-real">For real</h1> - -<p>And finaly, this is the final step you’ll do.</p> - -<pre><code>$ ssh git@host write-git-config vincent/vcsh-home mirror.url git@github.com:vdemeester/vcsh-home.git -$ git push -Counting objects: 5, done. -Delta compression using up to 2 threads. -Compressing objects: 100% (3/3), done. -Writing objects: 100% (3/3), 294 bytes, done. -Total 3 (delta 2), reused 0 (delta 0) -remote: To git@github.com:vdemeester/vcsh-home.git -remote: 65681a8..701c990 master -> master -To git@host:vincent/vcsh-home.git - 65681a8..701c990 master -> master -</code></pre> - -<p>And that should be it !</p> - -<p><strong>Update 2012/10/04</strong> : Moved from gitolite fork to <em>gitolite local code</em> -repository.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2012-05-13-jekyll-foreman-guard-bundler/" title="Jekyll Forman Guard Bundler">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2012-05-07-reinit-and-jekyll/" title="Reinit and Jekyll">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler.org b/www/vincent.demeester.fr/content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler.org @@ -1,90 +0,0 @@ -#+title: Jekyll Forman Guard Bundler -#+date: <2012-05-13 Sun> -#+filetags: jekyll ruby bundler guard foreman -#+setupfile: ../templates/post.org - -* Introduction - -This post is a quick "How did I setup my Jekyll environnement ?". We are -going all the tools that are quite awesome in Ruby. - -* Goal - :PROPERTIES: - :CUSTOM_ID: goal - :END: - -The goal is simple : - -1. I want to be able to install any dependent - [[http://rubygems.org][Gem]] with a /on-liner/ command -2. I want to be able to run a /Jekyll server/ that auto updates. - -We are going to play with : [[http://gembundler.com/][Bundler]], -[[https://github.com/guard/guard][Guard]] and -[[https://github.com/ddollar/foreman][foreman]]. - -* Bundler - :PROPERTIES: - :CUSTOM_ID: bundler - :END: - -Bundler let us run =bundle install= to get all Ruby Gems we will need ; -It use a file name =Gemfile=. The gems we need are simple : =jekyll=, -=guard= and some Guard extensions. - -#+begin_src ruby -source "http://rubygems.org" - -gem 'jekyll' -gem 'guard' -gem 'guard-jekyll2' -gem 'guard-shell' -gem 'guard-bundler' -#+end_src - -* Guard - :PROPERTIES: - :CUSTOM_ID: guard - :END: - -#+BEGIN_QUOTE - Guard is a command line tool to easily handle events on file system - modifications. -#+END_QUOTE - -Guard will be watching file we told him and run action in consequence ; -The file is name =Guardfile=. - -#+begin_src ruby -guard 'jekyll2' do - watch %r{.*} -end - -guard :bundler do - watch('Gemfile') -end -# vim:filetype=ruby -#+end_src - -* Foreman - :PROPERTIES: - :CUSTOM_ID: foreman - :END: - -Finally, foreman will let us declare our processes and will handle the -start, forward the output and handle the shutdown. It can then export -its configuration into more /production-ready/ file (=init=, =upstard=, -...) ; It uses a file named =Procfile=. - -We will tell foreman to run : - -- The jekyll build-in server : =jekyll --server= -- Guard, to handle file changes /in background/. - -#+begin_src bash -web: bundle exec jekyll --server -guard: bundle exec guard -#+end_src - -And that's all folk. Now, you just need to run foreman in the -Jekyll-powered directory and edit your files. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler/index.html b/www/vincent.demeester.fr/content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler/index.html @@ -1,194 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2012-05-13-jekyll-foreman-guard-bundler/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Jekyll Forman Guard Bundler</h1><a href='https://vincent.demeester.fr/posts/2012-05-13-jekyll-foreman-guard-bundler/'></a> - <address class="signature"> - <span class="date">Sun, 13 May, 2012</span> - <span class="words">(300 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-jekyll"><a href="/tags/#jekyll">jekyll<span>4</span></a></li> - - - <li class="tag tag-ruby"><a href="/tags/#ruby">ruby<span>1</span></a></li> - - - <li class="tag tag-bundler"><a href="/tags/#bundler">bundler<span>1</span></a></li> - - - <li class="tag tag-guard"><a href="/tags/#guard">guard<span>1</span></a></li> - - - <li class="tag tag-foreman"><a href="/tags/#foreman">foreman<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>This post is a quick “How did I setup my Jekyll environnement ?”. We are going -all the tools that are quite awesome in Ruby.</p> - -<h1 id="goal">Goal</h1> - -<p>The goal is simple :</p> - -<ol> -<li>I want to be able to install any dependent <a href="http://rubygems.org">Gem</a> with a -<em>on-liner</em> command</li> -<li>I want to be able to run a <em>Jekyll server</em> that auto updates.</li> -</ol> - -<p>We are going to play with : <a href="http://gembundler.com/">Bundler</a>, -<a href="https://github.com/guard/guard">Guard</a> and <a href="https://github.com/ddollar/foreman">foreman</a>.</p> - -<h2 id="bundler">Bundler</h2> - -<p>Bundler let us run <code>bundle install</code> to get all Ruby Gems we will need ; It use -a file name <code>Gemfile</code>. The gems we need are simple : <code>jekyll</code>, <code>guard</code> and some -Guard extensions.</p> - -<div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby"><span class="n">source</span> <span class="s2">"http://rubygems.org"</span> - -<span class="n">gem</span> <span class="s1">'jekyll'</span> -<span class="n">gem</span> <span class="s1">'guard'</span> -<span class="n">gem</span> <span class="s1">'guard-jekyll2'</span> -<span class="n">gem</span> <span class="s1">'guard-shell'</span> -<span class="n">gem</span> <span class="s1">'guard-bundler'</span></code></pre></div> - -<h2 id="guard">Guard</h2> - -<blockquote> -<p>Guard is a command line tool to easily handle events on file system modifications.</p> -</blockquote> - -<p>Guard will be watching file we told him and run action in consequence ; The file -is name <code>Guardfile</code>.</p> - -<div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby"><span class="n">guard</span> <span class="s1">'jekyll2'</span> <span class="k">do</span> - <span class="n">watch</span> <span class="sr">%r{.*}</span> -<span class="k">end</span> - -<span class="n">guard</span> <span class="ss">:bundler</span> <span class="k">do</span> - <span class="n">watch</span><span class="p">(</span><span class="s1">'Gemfile'</span><span class="p">)</span> -<span class="k">end</span> -<span class="c1"># vim:filetype=ruby</span></code></pre></div> - -<h2 id="foreman">Foreman</h2> - -<p>Finally, foreman will let us declare our processes and will handle the start, -forward the output and handle the shutdown. It can then export its configuration -into more <em>production-ready</em> file (<code>init</code>, <code>upstard</code>, …) ; It uses a file named -<code>Procfile</code>.</p> - -<p>We will tell foreman to run :</p> - -<ul> -<li>The jekyll build-in server : <code>jekyll --server</code></li> -<li>Guard, to handle file changes <em>in background</em>.</li> -</ul> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">web: bundle <span class="nb">exec</span> jekyll --server -guard: bundle <span class="nb">exec</span> guard</code></pre></div> - -<p>And that’s all folk. Now, you just need to run foreman in the Jekyll-powered -directory and edit your files.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2012-07-21-news/" title="News">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2012-05-08-gitolite-quick-and-dirty-mirror/" title="Gitolite quick and dirty mirror">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-07-21-news/index.html b/www/vincent.demeester.fr/content/legacy/posts/2012-07-21-news/index.html @@ -1,166 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2012-07-21-news/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">News</h1><a href='https://vincent.demeester.fr/posts/2012-07-21-news/'></a> - <address class="signature"> - <span class="date">Sat, 21 July, 2012</span> - <span class="words">(300 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#me">me</a></li> - - - - - - <li class="tag tag-news"><a href="/tags/#news">news<span>1</span></a></li> - - - <li class="tag tag-cyclisme"><a href="/tags/#cyclisme">cyclisme<span>1</span></a></li> - - - <li class="tag tag-vaadin"><a href="/tags/#vaadin">vaadin<span>1</span></a></li> - - - <li class="tag tag-java"><a href="/tags/#java">java<span>4</span></a></li> - - <br/> - - </ul> - </header> - - - - <p>Je suis resté assez longtemps silencieux, à cause du boulot entre autre. Je -vais donc remédier un peu à ça en publiant un petit post <em>news</em> :-).</p> - -<ul> -<li>Je suis fan de cyclisme. Mon vélo de course est ma seconde paire de jambes. -Enfin, le mot juste serait plutôt était. Il y a quelques semaines, en -rentrant du boulot, j’ai sentis un grosse vibration, puis plus moyen de -tourner les pédales. Intrigué, j’ai jeté un coup d’œil au vélo, et <em>oh rage -oh désespoir</em> j’ai découvert que la <em>fourche arrière</em> du vélo c’était tout -simplement fendue.</li> -</ul> - -<p><img src="/images/2012/velo_casse.jpg" alt="Fourche arrière du vélo" title="Fourche arrière du vélo" /></p> - -<p>Il ne me restait plus que mes yeux pour pleurer et mes jambes pour faire les - 7kms qui restait à effectuer jusqu’à mon appartement.</p> - -<p>Bien entendu ce n’est que matériel mais ce vélo avait une grande importance - sentimentale : il avait mon âge et appartenait à mon père quand j’étais - petit.</p> - -<p>Maintenant il ne reste plus qu’à sortir la carte bleue pour m’en procurer un - nouveau…</p> - -<ul> -<li><p>Je suis actuellement en vacances pour deux petites semaines (ouf !). Cela me -permet, entre autre, de me réentrainer à monter des cols (vu que je suis -dans les Alpes) ; parce qu’à Bordeaux, c’est assez difficile d’en trouver. -Par contre il me reste beaucoup de boulot pour retrouver ma forme d’il -y a une dizaine d’année et de monter facilement le <em>Grand Colombier</em> !</p></li> - -<li><p>Je joue pas mal avec <a href="http://vaadin.com">Vaadin</a> en ce moment, -principalement pour le boulot. J’annonce donc deux petits projets en cours :</p> - -<ol> -<li><a href="http://vdemeester.github.com/vaadin-container-utils">vaadin-container-utils</a></li> -<li>librarie utilitaire pour la création de Container vaadin.</li> -<li><a href="http://vdemeester.github.com/vaadin-composite-layout">vaadin-composite-layout</a></li> -<li>un composant vaadin hautement flexible (mais je suis mauvais pour les -noms).</li> -</ol></li> -</ul> - -<p>Et “c’est tout pour le moment”.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2012-07-23-maven-release-gitflow/" title="Maven Release Gitflow">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2012-05-13-jekyll-foreman-guard-bundler/" title="Jekyll Forman Guard Bundler">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-07-23-maven-release-gitflow.org b/www/vincent.demeester.fr/content/legacy/posts/2012-07-23-maven-release-gitflow.org @@ -1,99 +0,0 @@ -#+title: Maven Release Gitflow -#+date: <2012-07-23 Mon> -#+filetags: maven java git gitflow release -#+setupfile: ../templates/post.org - -* Introduction - -I like a lot the [[http://nvie.com/posts/a-successful-git-branching-model/][gitflow]] way of managing project. When working on maven project, there is -few great plugins that helps to get the work done. One of them is [[http://maven.apache.org/plugins/maven-release-plugin][maven-release-plugin]]. - -Inspired on this [[https://gist.github.com/1043970][gist]], I've come -with a cool way of doing things (let say we want to release a 0.1 -version of an artifact) : - -* Prepare the pom.xml. - :PROPERTIES: - :CUSTOM_ID: prepare-the-pom.xml. - :END: - -It needs =<scm>= entries, =<distributionManagement>= entries (to know -where to deploy the release artifact) and few options for the -maven-release-plugin : - -{{< highlight xml >}} -#+begin_src xml -<project> - - <!-- […] --> - <build> - <plugins> - <!-- […] --> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-release-plugin</artifactId> - <version>2.3.2</version> - <configuration> - <tagNameFormat>v@{project.version}</tagNameFormat> - <pushChanges>false</pushChanges> - <localCheckout>true</localCheckout> - </configuration> - </plugin> - <!-- […] --> - </plugins> - </build> - <!-- […] --> - -</project> -#+end_src - -Few explanation here : - -- =tagNameFormat= is here to change the default tag name (which is - =${project.artifactId}-${project.version}=) to a better one. -- =pushChanges= set to =false= tells maven-release-plugin not to push - changes (this will become useful) -- =localCheckout= set to =true= tells maven-release-plugin to clone from - local repository (not distant). This is especially useful here because - we didn't push anything (so not setting this option would result in a - failure). - -* The real stuff - :PROPERTIES: - :CUSTOM_ID: the-real-stuff - :END: - -First create a release branch from develop. - -#+begin_src bash -$ git checkout -b release/v0.1 develop -#+end_src - -Then run the maven release stuff. - -#+begin_src bash -$ mvn release:prepare # change the pom, commit and tag version, and - # re-change pom (by incrementing SNAPSHOT version) -$ mvn release:perform # get the tagged version, compile and deploy -#+end_src - -And the real fun begins. - -#+begin_src bash -$ git checkout develop # get back to the develop branch -$ git merge --no-ff release/v0.1 # merge the version back into develop -$ git checkout master # go to the master branch -$ git merge --no-ff release/v0.1~1 # merge the version back into master but - # the tagged version instead of the release/v0.1 HEAD -$ git branch -D release/v0.1 # Removing the release branch -$ git push --all && git push --tags # Finally push everything -#+end_src - -The real magic here is the =git merge --no-ff release/v0.1~1= which will -merge into master the commit before the HEAD of the branch -=release/v0.1=. - -The next step would be to create a helper script that automates this and -verify that the =pom.xml= has the right configuration options. - -*Edit 17:58* : You can take a look [[https://github.com/vdemeester/java-config/blob/master/bin/mvn-release-flow][here]] diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-07-23-maven-release-gitflow/index.html b/www/vincent.demeester.fr/content/legacy/posts/2012-07-23-maven-release-gitflow/index.html @@ -1,204 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2012-07-23-maven-release-gitflow/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Maven Release Gitflow</h1><a href='https://vincent.demeester.fr/posts/2012-07-23-maven-release-gitflow/'></a> - <address class="signature"> - <span class="date">Mon, 23 July, 2012</span> - <span class="words">(400 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-maven"><a href="/tags/#maven">maven<span>2</span></a></li> - - - <li class="tag tag-java"><a href="/tags/#java">java<span>4</span></a></li> - - - <li class="tag tag-git"><a href="/tags/#git">git<span>3</span></a></li> - - - <li class="tag tag-gitflow"><a href="/tags/#gitflow">gitflow<span>1</span></a></li> - - - <li class="tag tag-release"><a href="/tags/#release">release<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>I like a lot the <a href="http://nvie.com/posts/a-successful-git-branching-model/">gitflow</a> way of managing project. -When working on maven project, there is few great plugins that helps to get -the work done. One of them is <a href="http://maven.apache.org/plugins/maven-release-plugin">maven-release-plugin</a>.</p> - -<p>Inspired on this <a href="https://gist.github.com/1043970">gist</a>, I’ve come with -a cool way of doing things (let say we want to release a 0.1 version of an -artifact) :</p> - -<h1 id="prepare-the-pom-xml">Prepare the pom.xml.</h1> - -<p>It needs <code><scm></code> entries, <code><distributionManagement></code> entries -(to know where to deploy the release artifact) and few options for the -maven-release-plugin :</p> - -<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt"><project></span> - - <span class="c"><!-- […] --></span> - <span class="nt"><build></span> - <span class="nt"><plugins></span> - <span class="c"><!-- […] --></span> - <span class="nt"><plugin></span> - <span class="nt"><groupId></span>org.apache.maven.plugins<span class="nt"></groupId></span> - <span class="nt"><artifactId></span>maven-release-plugin<span class="nt"></artifactId></span> - <span class="nt"><version></span>2.3.2<span class="nt"></version></span> - <span class="nt"><configuration></span> - <span class="nt"><tagNameFormat></span>v@{project.version}<span class="nt"></tagNameFormat></span> - <span class="nt"><pushChanges></span>false<span class="nt"></pushChanges></span> - <span class="nt"><localCheckout></span>true<span class="nt"></localCheckout></span> - <span class="nt"></configuration></span> - <span class="nt"></plugin></span> - <span class="c"><!-- […] --></span> - <span class="nt"></plugins></span> - <span class="nt"></build></span> - <span class="c"><!-- […] --></span> - -<span class="nt"></project></span></code></pre></div> - -<p>Few explanation here :</p> - -<ul> -<li><code>tagNameFormat</code> is here to change the default tag name (which is <code>${project.artifactId}-${project.version}</code>) to a better one.</li> -<li><code>pushChanges</code> set to <code>false</code> tells maven-release-plugin not to push -changes (this will become useful)</li> -<li><code>localCheckout</code> set to <code>true</code> tells maven-release-plugin to clone from -local repository (not distant). This is especially useful here because we -didn’t push anything (so not setting this option would result in a failure).</li> -</ul> - -<h1 id="the-real-stuff">The real stuff</h1> - -<p>First create a release branch from develop.</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">$ git checkout -b release/v0.1 develop</code></pre></div> - -<p>Then run the maven release stuff.</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">$ mvn release:prepare <span class="c1"># change the pom, commit and tag version, and</span> - <span class="c1"># re-change pom (by incrementing SNAPSHOT version)</span> -$ mvn release:perform <span class="c1"># get the tagged version, compile and deploy</span></code></pre></div> - -<p>And the real fun begins.</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">$ git checkout develop <span class="c1"># get back to the develop branch</span> -$ git merge --no-ff release/v0.1 <span class="c1"># merge the version back into develop</span> -$ git checkout master <span class="c1"># go to the master branch</span> -$ git merge --no-ff release/v0.1~1 <span class="c1"># merge the version back into master but</span> - <span class="c1"># the tagged version instead of the release/v0.1 HEAD</span> -$ git branch -D release/v0.1 <span class="c1"># Removing the release branch</span> -$ git push --all <span class="o">&&</span> git push --tags <span class="c1"># Finally push everything</span></code></pre></div> - -<p>The real magic here is the <code>git merge --no-ff release/v0.1~1</code> which will -merge into master the commit before the HEAD of the branch <code>release/v0.1</code>.</p> - -<p>The next step would be to create a helper script that automates this and -verify that the <code>pom.xml</code> has the right configuration options.</p> - -<p><strong>Edit 17:58</strong> : You can take a look <a href="https://github.com/vdemeester/java-config/blob/master/bin/mvn-release-flow">here</a></p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2012-12-16-gollum-comme-wiki-personnel/" title="Gollum Comme Wiki Personnel">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2012-07-21-news/" title="News">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel.org b/www/vincent.demeester.fr/content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel.org @@ -1,84 +0,0 @@ -#+title: Gollum comme Wiki personnel -#+date: <2012-12-16 Sun> -#+filetags: wiki golum github personnel -#+setupfile: ../templates/post.org - -* Introduction - -Il y a environ 4 mois j'ai eu un accident de vélo ; un traumatisme -crânien, des brulures sur la face, quelques points de sutures, un doigt -cassé et une hernie discale m'ont cloué (et me clou encore) plus que -d'habitude sur ma chaise de bureau. Le bon côté des choses, c'est que -cela m'a permit de me poser et de réfléchir une bonne façon d'être -efficace et organiser, au travail et à la maison :-). - -Une des principales /action/ que j'ai pris est d'utiliser un wiki local -et synchronisé sur /tout/ mes PCs. Le /format/ wiki est assez adapté à -une prise de note et à la création de contenu plus complet (comme des -[[http://shortbrain.org][articles]] ou de la documentation pour des -projets en cours). Les conditions étaient les suivantes : - -- Facilité de mise en place. -- Pas de base de données. -- /Merging/ facile ([[http://git-scm.com][git]] /rules my world/). -- [[http://daringfireball.net/projects/markdown/][Markdown]] comme - syntaxe, car utilisé à peu près partout (blogs, articles, READMEs, - documentations). -- Éditable à partir d'une interface web ou de mon éditeur favoris. - -L'outil qui remplit presque toutes ces conditions s'appelle -[[https://github.com/github/gollum][gollum]]. C'est un moteur wiki, -écris en ruby, qui se base sur un repository -[[http://git-scm.com][git]]. Il est développer par l'équipe de -[[http://github.com][Github]] et c'est celui qui est utilisé par les -pages wiki là-bas. Il permet d'utiliser à peu près n'importe quel -syntaxe (dont -[[https://github.com/github/github-flavored-markdown][github-markdown]] -qui est assez proche de celle de -[[http://johnmacfarlane.net/pandoc][pandoc]]). Par ailleurs, comme il se -base sur [[http://git-scm.com][git]], les points /"pas de base de -données"/, /"merging facile"/ et /"éditable également à partir de mon -éditeur favoris"/ sont toutes remplies. - -Avec [[https://github.com/github/gollum][Gollum]] vous avez un wiki -markdown décentralisé, éditable via une interface web ou via votre -éditeur favoris. - -* Mise en place - :PROPERTIES: - :CUSTOM_ID: mise-en-place - :END: - -La mise en place est relativement simple ; après tout dépend du besoin -que vous avez. L'installation se fait par [[file:rubygems.org][RubyGem]] -ou en clonant le repository. - -{{< highlight bash >}} # Installation de gollum et du format markdown de -github $ gem install gollum gitub-markdown {{< /highlight >}} - -Si vous n'utilisez pas [[https://github.com/sstephenson/rbenv][rbenv]] -ou [[https://rvm.io/][rvm]] il est probable qu'il faille lancer la -commande en root ou utiliser sudo. - -Ensuite, il suffit de lancer -[[https://github.com/github/gollum][Gollum]] dans un dossier qui est un -repository git ; le tour est joué - -{{< highlight bash >}} # J'ulitise ~/desktop/wiki pour mon wiki $ cd -~/desktop/wiki && gollum {{< /highlight >}} - -L'idée finale est d'automatiser deux choses : - -1. Le démarrage de gollum -2. La synchronisation du repository avec les différents autres /remotes/ - -Suivant le système d'exploitation et/ou la distribution utilisées, il y -a énormément de possibilité d'effectuer cette automatisation. Dans mon -cas, j'ai une [[http://debian.org][Debian]] assez light, avec surtout -plein de scripts. Je démarre donc -[[https://github.com/github/gollum][Gollum]] au démarrage de ma session -grâce à une script qui est lancé dans la foulée du gestionnaire de -fenêtre. La synchronisation se fait grâce à une tâche planifiée /cron/ -qui est "distribué" sur chacune de mes machines. - -/C'est tout pour le moment/ ;-). diff --git a/www/vincent.demeester.fr/content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel/index.html b/www/vincent.demeester.fr/content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel/index.html @@ -1,164 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2012-12-16-gollum-comme-wiki-personnel/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Gollum Comme Wiki Personnel</h1><a href='https://vincent.demeester.fr/posts/2012-12-16-gollum-comme-wiki-personnel/'></a> - <address class="signature"> - <span class="date">Sun, 16 December, 2012</span> - <span class="words">(500 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#me">me</a></li> - - - - - - <li class="tag tag-wiki"><a href="/tags/#wiki">wiki<span>1</span></a></li> - - - <li class="tag tag-gollum"><a href="/tags/#gollum">gollum<span>1</span></a></li> - - - <li class="tag tag-github"><a href="/tags/#github">github<span>2</span></a></li> - - - <li class="tag tag-personnel"><a href="/tags/#personnel">personnel<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Il y a environ 4 mois j’ai eu un accident de vélo ; un traumatisme crânien, des brulures sur la face, quelques points de sutures, un doigt cassé et une hernie discale m’ont cloué (et me clou encore) plus que d’habitude sur ma chaise de bureau. Le bon côté des choses, c’est que cela m’a permit de me poser et de réfléchir une bonne façon d’être efficace et organiser, au travail et à la maison :-).</p> - -<p>Une des principales <em>action</em> que j’ai pris est d’utiliser un wiki local et synchronisé sur <em>tout</em> mes PCs. Le <em>format</em> wiki est assez adapté à une prise de note et à la création de contenu plus complet (comme des <a href="http://shortbrain.org">articles</a> ou de la documentation pour des projets en cours). Les conditions étaient les suivantes :</p> - -<ul> -<li>Facilité de mise en place.</li> -<li>Pas de base de données.</li> -<li><em>Merging</em> facile (<a href="http://git-scm.com">git</a> <em>rules my world</em>).</li> -<li><a href="http://daringfireball.net/projects/markdown/">Markdown</a> comme syntaxe, car utilisé à peu près partout (blogs, articles, READMEs, documentations).</li> -<li>Éditable à partir d’une interface web ou de mon éditeur favoris.</li> -</ul> - -<p>L’outil qui remplit presque toutes ces conditions s’appelle <a href="https://github.com/github/gollum">gollum</a>. C’est un moteur wiki, écris en ruby, qui se base sur un repository <a href="http://git-scm.com">git</a>. Il est développer par l’équipe de <a href="http://github.com">Github</a> et c’est celui qui est utilisé par les pages wiki là-bas. Il permet d’utiliser à peu près n’importe quel syntaxe (dont <a href="https://github.com/github/github-flavored-markdown">github-markdown</a> qui est assez proche de celle de <a href="http://johnmacfarlane.net/pandoc">pandoc</a>). Par ailleurs, comme il se base sur <a href="http://git-scm.com">git</a>, les points <em>“pas de base de données”</em>, <em>“merging facile”</em> et <em>“éditable également à partir de mon éditeur favoris”</em> sont toutes remplies.</p> - -<p>Avec <a href="https://github.com/github/gollum">Gollum</a> vous avez un wiki markdown décentralisé, éditable via une interface web ou via votre éditeur favoris.</p> - -<h2 id="mise-en-place">Mise en place</h2> - -<p>La mise en place est relativement simple ; après tout dépend du besoin que vous avez. L’installation se fait par <a href="rubygems.org">RubyGem</a> ou en clonant le repository.</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># Installation de gollum et du format markdown de github</span> -$ gem install gollum gitub-markdown</code></pre></div> - -<p>Si vous n’utilisez pas <a href="https://github.com/sstephenson/rbenv">rbenv</a> ou <a href="https://rvm.io/">rvm</a> il est probable qu’il faille lancer la commande en root ou utiliser sudo.</p> - -<p>Ensuite, il suffit de lancer <a href="https://github.com/github/gollum">Gollum</a> dans un dossier qui est un repository git ; le tour est joué</p> - -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># J'ulitise ~/desktop/wiki pour mon wiki</span> -$ <span class="nb">cd</span> ~/desktop/wiki <span class="o">&&</span> gollum</code></pre></div> - -<p>L’idée finale est d’automatiser deux choses :</p> - -<ol> -<li>Le démarrage de gollum</li> -<li>La synchronisation du repository avec les différents autres <em>remotes</em></li> -</ol> - -<p>Suivant le système d’exploitation et/ou la distribution utilisées, il y a énormément de possibilité d’effectuer cette automatisation. Dans mon cas, j’ai une <a href="http://debian.org">Debian</a> assez light, avec surtout plein de scripts. Je démarre donc <a href="https://github.com/github/gollum">Gollum</a> au démarrage de ma session grâce à une script qui est lancé dans la foulée du gestionnaire de fenêtre. La synchronisation se fait grâce à une tâche planifiée <em>cron</em> qui est “distribué” sur chacune de mes machines.</p> - -<p><em>C’est tout pour le moment</em> ;-).</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2013-09-08-maven-tmpfs/" title="Maven Tmpfs">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2012-07-23-maven-release-gitflow/" title="Maven Release Gitflow">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2013-09-08-maven-tmpfs.org b/www/vincent.demeester.fr/content/legacy/posts/2013-09-08-maven-tmpfs.org @@ -1,158 +0,0 @@ -#+title: Maven Tmpfs -#+date: <2013-09-08 Sun> -#+filetags: maven tmpfs ssd -#+setupfile: ../templates/post.org - -* Introduction - -Je suis un utilisateur convaincu de [[http://maven.apache.org/][maven]], malgré ces défauts, le -moto *"Convention over configuration"* me va vraiment bien. Que ce soit -au boulot ou à la maison, j'ai plus d'ordinateurs équipés de ssd (ou de -mémoire flash) que de disque traditionnel (mécanique ?). Pour augmenter -un peu la durée de vie de ces disques SSD, j'ai cherché à savoir comment -/déporter/ le /build/ de maven (qui, pour rappel, se passe dans le -dossier =target/=) hors du SSD ; ici ce sera dans le dossier =/tmp/= qui -est monté en mémoire (merci =tmpfs=), mais on peut imaginer déporter ça -sur un autre disque, etc.. Après quelques recherches j'ai trouvés -quelques inspirations. - -#+BEGIN_QUOTE - *Limitations* - - Dans la solution présentée ci-dessous les principales limitations sont - les suivantes (que j'essaierais de diminuer au fil du temp ;P) : - - 1. Il est nécessaire de modifier le pom.xml du projet ; cela ne - s'appliquera donc pas à tous les projets maven sans modification du - pom.xml. - 2. Cela ne fonctionne que sur une plateforme qui support les liens - symboliques (Linux, Mac OS X, et autre UNIX). - 3. Cela ne fonctionne qu'avec Java 7 ou plus. - 4. Si vous utilisez m2e, il va gentillement gueuler et c'est moche ; pour résoudre le - problème, il faut faire un tour vers [[http://wiki.eclipse.org/M2E_plugin_execution_not_covered][M2E plugin execution not covered]]. -#+END_QUOTE - -Pour [[http://maven.apache.org/][maven]], le dossier =target/= vient de la propriété -=project.build.directory=. Dans la théorie, il suffirait de modifier -(dans =$HOME/.m2/settings.xml=) cette propriété et le tour serait jouer. -Malheuresement ce n'est pas possible, =project.build.directory= est une -propriété interne et n'est, à priori, pas modifiable. - -Notre souhait est le suivant : - -1. Le build doit se faire dans =/tmp/m2/=, ce qui pour un projet se - traduit par =/tmp/m2/${groupId}:${artifactId}=. -2. Le dossier =target/= dans les sources est un lien symbolique vers le - dossier dans =/tmp/m2/= -3. On passe par un *profile* qui n'est *pas actif* par défaut (pour ne - pas faire chier le monde) mais *activable via une propriété* (maven - nous permet de le faire et c'est cool =^_^=). La propriété utilisée - sera =external.build.root=. - -Le code ci-dessous est repris directement de mon inspiration[fn:1]. Il -s'occupe de créer le dossier =${groupId}:${artifactId}= dans -=external.build.root= et de faire le lien dans le dossier courant. - -#+begin_src xml -<project> - <!-- […] --> - <profiles> - <profile> - <id>external-build-dir</id> - <activation> - <activeByDefault>false</activeByDefault> - <property> - <name>external.build.root</name> - </property> - </activation> - <build> - <plugins> - <plugin> - <groupId>com.alexecollins.maven.plugin</groupId> - <artifactId>script-maven-plugin</artifactId> - <version>1.0.0</version> - <executions> - <execution> - <id>prep-work-tree</id> - <goals> - <goal>execute</goal> - </goals> - <phase>initialize</phase> - <configuration> - <script> - import java.nio.file.* - def dir = - "${external.build.root}/${project.groupId}:${project.artifactId}" - println "using Maven dir ${dir}" - def dirPath = Paths.get(dir) - if (!Files.exists(dirPath)) { - Files.createDirectories(dirPath) - } - def target = Paths.get("${project.build.directory}") - if (!Files.exists(target)) { - Files.createSymbolicLink(target, dirPath) - }</script> - </configuration> - </execution> - <execution> - <id>drop-symlink</id> - <goals> - <goal>execute</goal> - </goals> - <phase>clean</phase> - <configuration> - <script> - import java.nio.file.* - def target = Paths.get("${project.build.directory}") - if (Files.isSymbolicLink(target)) { - Files.delete(target) - } - </script> - </configuration> - </execution> - </executions> - <dependencies> - <dependency> - <groupId>org.codehaus.groovy</groupId> - <artifactId>groovy</artifactId> - <version>1.8.6</version> - </dependency> - </dependencies> - <configuration> - <language>groovy</language> - </configuration> - </plugin> - </plugins> - </build> - </profile> - </profiles> - <!-- […] --> -</project> -#+end_src - -Ainsi, il suffit ensuite d'avoir quelques choses du genre dans son -=$HOME/.m2/settings.xml= pour que les builds qui ont ce profil se -/build/ dans =/tmp/m2/=. On peut aussi ne rien avoir dans -=$HOME/.m2/settings.xml= et utilise =-Dexternal.build.root=/tmp/m2/= -avec la commande =mvn=. - -#+begin_src xml -<settings> - <!-- […] --> - <profiles> - <profile> - <id>build-in-ramfs</id> - <properties> - <external.build.root>/tmp/m2/</external.build.root> - </properties> - </profile> - </profiles> - <activeProfiles> - <activeProfile>build-in-ramfs</activeProfile> - </activeProfiles> - <!-- […] --> -</settings> -#+end_src - - -[fn:1] [[http://elehack.net/writings/programming/maven-target-in-tmpfs][PuttingMaven build directories out-of-tree]] par [[http://elehack.net/][Michal Ekstrand]] diff --git a/www/vincent.demeester.fr/content/legacy/posts/2013-09-08-maven-tmpfs/index.html b/www/vincent.demeester.fr/content/legacy/posts/2013-09-08-maven-tmpfs/index.html @@ -1,274 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2013-09-08-maven-tmpfs/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Maven Tmpfs</h1><a href='https://vincent.demeester.fr/posts/2013-09-08-maven-tmpfs/'></a> - <address class="signature"> - <span class="date">Sun, 8 September, 2013</span> - <span class="words">(600 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-maven"><a href="/tags/#maven">maven<span>2</span></a></li> - - - <li class="tag tag-tmpfs"><a href="/tags/#tmpfs">tmpfs<span>1</span></a></li> - - - <li class="tag tag-ssd"><a href="/tags/#ssd">ssd<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - <p>Je suis un utilisateur convaincu de [maven](), malgré ces défauts, le moto -<strong>“Convention over configuration”</strong> me va vraiment bien. Que ce soit au boulot ou -à la maison, j’ai plus d’ordinateurs équipés de ssd (ou de mémoire flash) que de -disque traditionnel (mécanique ?). Pour augmenter un peu la durée de vie de -ces disques SSD, j’ai cherché à savoir comment <em>déporter</em> le <em>build</em> de maven -(qui, pour rappel, se passe dans le dossier <code>target/</code>) hors du SSD ; ici ce -sera dans le dossier <code>/tmp/</code> qui est monté en mémoire (merci <code>tmpfs</code>), -mais on peut imaginer déporter ça sur un autre disque, etc.. Après quelques -recherches j’ai trouvés quelques inspirations.</p> - -<blockquote> -<p><strong>Limitations</strong></p> - -<p>Dans la solution présentée ci-dessous les principales limitations sont -les suivantes (que j’essaierais de diminuer au fil du temp ;P) :</p> - -<ol> -<li>Il est nécessaire de modifier le pom.xml du projet ; cela ne s’appliquera -donc pas à tous les projets maven sans modification du pom.xml.</li> -<li>Cela ne fonctionne que sur une plateforme qui support les liens -symboliques (Linux, Mac OS X, et autre UNIX).</li> -<li>Cela ne fonctionne qu’avec Java 7 ou plus.</li> -<li>Si vous utilisez m2e, il va gentillement gueuler et c’est moche ; pour -résoudre le problème, il faut faire un tour vers <a href="http://wiki.eclipse.org/M2E_plugin_execution_not_covered">M2E plugin execution -not covered</a>.</li> -</ol> -</blockquote> - -<p>Pour [maven](), le dossier <code>target/</code> vient de la propriété -<code>project.build.directory</code>. Dans la théorie, il suffirait de modifier (dans -<code>$HOME/.m2/settings.xml</code>) cette propriété et le tour serait jouer. -Malheuresement ce n’est pas possible, <code>project.build.directory</code> est une -propriété interne et n’est, à priori, pas modifiable.</p> - -<p>Notre souhait est le suivant :</p> - -<ol> -<li>Le build doit se faire dans <code>/tmp/m2/</code>, ce qui pour un projet se traduit -par <code>/tmp/m2/${groupId}:${artifactId}</code>.</li> -<li>Le dossier <code>target/</code> dans les sources est un lien symbolique vers le -dossier dans <code>/tmp/m2/</code></li> -<li>On passe par un <strong>profile</strong> qui n’est <strong>pas actif</strong> par défaut (pour ne pas -faire chier le monde) mais <strong>activable via une propriété</strong> (maven nous permet -de le faire et c’est cool <code>^_^</code>). La propriété utilisée sera -<code>external.build.root</code>.</li> -</ol> - -<p>Le code ci-dessous est repris directement de mon inspiration<sup class="footnote-ref" id="fnref:inspiration"><a href="#fn:inspiration">1</a></sup>. Il -s’occupe de créer le dossier <code>${groupId}:${artifactId}</code> dans -<code>external.build.root</code> et de faire le lien dans le dossier courant.</p> - -<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt"><project></span> - <span class="c"><!-- […] --></span> - <span class="nt"><profiles></span> - <span class="nt"><profile></span> - <span class="nt"><id></span>external-build-dir<span class="nt"></id></span> - <span class="nt"><activation></span> - <span class="nt"><activeByDefault></span>false<span class="nt"></activeByDefault></span> - <span class="nt"><property></span> - <span class="nt"><name></span>external.build.root<span class="nt"></name></span> - <span class="nt"></property></span> - <span class="nt"></activation></span> - <span class="nt"><build></span> - <span class="nt"><plugins></span> - <span class="nt"><plugin></span> - <span class="nt"><groupId></span>com.alexecollins.maven.plugin<span class="nt"></groupId></span> - <span class="nt"><artifactId></span>script-maven-plugin<span class="nt"></artifactId></span> - <span class="nt"><version></span>1.0.0<span class="nt"></version></span> - <span class="nt"><executions></span> - <span class="nt"><execution></span> - <span class="nt"><id></span>prep-work-tree<span class="nt"></id></span> - <span class="nt"><goals></span> - <span class="nt"><goal></span>execute<span class="nt"></goal></span> - <span class="nt"></goals></span> - <span class="nt"><phase></span>initialize<span class="nt"></phase></span> - <span class="nt"><configuration></span> - <span class="nt"><script></span> - import java.nio.file.* - def dir = - "${external.build.root}/${project.groupId}:${project.artifactId}" - println "using Maven dir ${dir}" - def dirPath = Paths.get(dir) - if (!Files.exists(dirPath)) { - Files.createDirectories(dirPath) - } - def target = Paths.get("${project.build.directory}") - if (!Files.exists(target)) { - Files.createSymbolicLink(target, dirPath) - }<span class="nt"></script></span> - <span class="nt"></configuration></span> - <span class="nt"></execution></span> - <span class="nt"><execution></span> - <span class="nt"><id></span>drop-symlink<span class="nt"></id></span> - <span class="nt"><goals></span> - <span class="nt"><goal></span>execute<span class="nt"></goal></span> - <span class="nt"></goals></span> - <span class="nt"><phase></span>clean<span class="nt"></phase></span> - <span class="nt"><configuration></span> - <span class="nt"><script></span> - import java.nio.file.* - def target = Paths.get("${project.build.directory}") - if (Files.isSymbolicLink(target)) { - Files.delete(target) - } - <span class="nt"></script></span> - <span class="nt"></configuration></span> - <span class="nt"></execution></span> - <span class="nt"></executions></span> - <span class="nt"><dependencies></span> - <span class="nt"><dependency></span> - <span class="nt"><groupId></span>org.codehaus.groovy<span class="nt"></groupId></span> - <span class="nt"><artifactId></span>groovy<span class="nt"></artifactId></span> - <span class="nt"><version></span>1.8.6<span class="nt"></version></span> - <span class="nt"></dependency></span> - <span class="nt"></dependencies></span> - <span class="nt"><configuration></span> - <span class="nt"><language></span>groovy<span class="nt"></language></span> - <span class="nt"></configuration></span> - <span class="nt"></plugin></span> - <span class="nt"></plugins></span> - <span class="nt"></build></span> - <span class="nt"></profile></span> - <span class="nt"></profiles></span> - <span class="c"><!-- […] --></span> -<span class="nt"></project></span></code></pre></div> - -<p>Ainsi, il suffit ensuite d’avoir quelques choses du genre dans son -<code>$HOME/.m2/settings.xml</code> pour que les builds qui ont ce profil se <em>build</em> -dans <code>/tmp/m2/</code>. On peut aussi ne rien avoir dans <code>$HOME/.m2/settings.xml</code> -et utilise <code>-Dexternal.build.root=/tmp/m2/</code> avec la commande <code>mvn</code>.</p> - -<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt"><settings></span> - <span class="c"><!-- […] --></span> - <span class="nt"><profiles></span> - <span class="nt"><profile></span> - <span class="nt"><id></span>build-in-ramfs<span class="nt"></id></span> - <span class="nt"><properties></span> - <span class="nt"><external.build.root></span>/tmp/m2/<span class="nt"></external.build.root></span> - <span class="nt"></properties></span> - <span class="nt"></profile></span> - <span class="nt"></profiles></span> - <span class="nt"><activeProfiles></span> - <span class="nt"><activeProfile></span>build-in-ramfs<span class="nt"></activeProfile></span> - <span class="nt"></activeProfiles></span> - <span class="c"><!-- […] --></span> -<span class="nt"></settings></span></code></pre></div> -<div class="footnotes"> - -<hr /> - -<ol> -<li id="fn:inspiration"><a href="http://elehack.net/writings/programming/maven-target-in-tmpfs">Putting Maven build directories out-of-tree</a> par <a href="http://elehack.net/">Michal Ekstrand</a> - <a class="footnote-return" href="#fnref:inspiration"><sup>[return]</sup></a></li> -</ol> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2013-10-12-podcasts/" title="Podcasts">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2012-12-16-gollum-comme-wiki-personnel/" title="Gollum Comme Wiki Personnel">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2013-10-12-podcasts.org b/www/vincent.demeester.fr/content/legacy/posts/2013-10-12-podcasts.org @@ -1,91 +0,0 @@ -#+TITLE: Podcasts -#+date: <2013-10-12 Sat> -#+filetags: music podcast -#+setupfile: ../templates/post.org - -* Introduction - -#+BEGIN_QUOTE - Voici un petit billet présentant les différents podcast que j'écoute - plus ou moins régulièrement. -#+END_QUOTE - -J'écoute énormément de musique et de podcast ; je passe beaucoup de -temps avec des écouteurs sur la tête ou la chaine hifi en route. Les -podcasts ont une grande place. Voici une liste plus ou moins bien triés -de ceux auxquels je suis souscrit et/ou que j'écoute en ce moment. Je -tiendrais peut-être ce post à jour ou en créerait un nouveau sinon :-). - -* Geek & co - :PROPERTIES: - :CUSTOM_ID: geek-co - :END: - -Je suis un developpeur, un geek et convaincu des logiciels libres, les -podcasts qui suivent reflète assez cette partie là de mon identité. - -- [[http://www.captainweb.net/][L'apéro de Captain (fr)]] : dans le - genre geeky, déjanté et sauvage, en français, on ne fait pas mieux. - Pas vraiment safe for work, et pas tout à fait "libriste" comme - j'aime, les tranches de rires sont garanties ; même si parfois on est - un peu verreux d'avoir écouter jusqu'à la fin et le bien nommé - "wazzuf". -- [[http://www.agencetousgeeks.com/][Agence Tous Geeks (fr)]] : fils - caché de l'apéro du captain, on y retrouve des amis (et membres de ce - dernier), mais c'est un peu plus calme. -- [[http://bazingcast.com/about/][Bazingcast (fr)]] : podcast geek, plus - posé que les deux précédents mais avec des débats, des trolls et tout - ce que l'on peut attendre de geeks. -- [[http://www.captainposix.net/][Parole de Tux (fr-be)]] : podcast - venant de nos voisin belge, pas trop long et plutôt sympa ; et si - comme moi vous adorez l'accent belge, c'est le top. -- [[http://faif.us/][Free as in Freedom (en)]] : podcast parlant de - logiciel libre principalement côté license, truc légal, etc.. en - anglais, faut parfois s'accrocher. -- [[http://episodes.gitminutes.com/][Git Minutes (en)]] : podcast à - propos de Git et des outils de son écosystème (vcsh, etc..). - -* Radio - :PROPERTIES: - :CUSTOM_ID: radio - :END: - -J'aime bien la radio, bien plus que la télévision (que j'allume si peu -qu'à chaque fois la box se met à jour =;-p=). - -- [[http://www.franceinter.fr/emission-laura-leishman-project][France - Inter - LLP (Laura leishman Project)]] -- [[http://radiofrance-podcast.net/podcast09/rss_12265.xml][Le Mouv' - - Laura Leishman Project]] -- [[http://www.franceinter.fr/emission-interception][France Inter - - Interception]] -- [[http://www.la-bas.org/][France Inter - là-bas si j'y suis]] -- [[http://www.franceculture.fr/podcast/4689840][France Culture - - Pixel]] -- [[http://www.franceculture.fr/podcast/4685228][France Culture - Place - de la toile]] -- [[http://www.franceculture.fr/podcast/4689418][France Culture - - Philippe Meyer]] -- [[http://radiofrance-podcast.net/podcast09/rss_12582.xml][Le Mouv' - - Glitch (sur le Mouv')]] -- [[http://radiofrance-podcast.net/podcast09/rss_12691.xml][Le Mouv' - - Code Source]] -- [[http://radiofrance-podcast.net/podcast09/rss_12190.xml][Le Mouv' - - Suivez le geek]] -- [[http://www.divergence-fm.org/-http-www-divergence-fm-org-ecrire-exec-rubrique-id_rubrique-61-.html][Divergence - Numerique]] - -* Musique - :PROPERTIES: - :CUSTOM_ID: musique - :END: - -Les podcast suivant sont purement musique, tous musique techno ou trance -(que j'aime bien). - -- [[http://podcasts.flaix.fr/corstencountdown][Ferry Corsten - Corsten - Countdown]] -- [[http://www.galexmusic.com/podcast/gareth.xml][Gareth Emery Podcast]] -- [[http://feedproxy.feedburner.com/Tiestos_club_life][Tiesto Club - Life]] -- [[http://oakenfold.libsyn.com/rss][Oakenfold Perfecto Podcast]] diff --git a/www/vincent.demeester.fr/content/legacy/posts/2013-10-12-podcasts/index.html b/www/vincent.demeester.fr/content/legacy/posts/2013-10-12-podcasts/index.html @@ -1,177 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2013-10-12-podcasts/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr" class="gray"> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Podcasts</h1><a href='https://vincent.demeester.fr/posts/2013-10-12-podcasts/'></a> - <address class="signature"> - <span class="date">Sat, 12 October, 2013</span> - <span class="words">(400 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#me">me</a></li> - - - - - - <li class="tag tag-music"><a href="/tags/#music">music<span>1</span></a></li> - - - <li class="tag tag-podcast"><a href="/tags/#podcast">podcast<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<blockquote> -<p>Voici un petit billet présentant les différents podcast que j’écoute plus ou -moins régulièrement.</p> -</blockquote> - -<p>J’écoute énormément de musique et de podcast ; je passe beaucoup de temps avec -des écouteurs sur la tête ou la chaine hifi en route. Les podcasts ont une grande -place. Voici une liste plus ou moins bien triés de ceux auxquels je suis -souscrit et/ou que j’écoute en ce moment. Je tiendrais peut-être ce post -à jour ou en créerait un nouveau sinon :-).</p> - -<h2 id="geek-co">Geek & co</h2> - -<p>Je suis un developpeur, un geek et convaincu des logiciels libres, les -podcasts qui suivent reflète assez cette partie là de mon identité.</p> - -<ul> -<li><a href="http://www.captainweb.net/">L’apéro de Captain (fr)</a> : dans le genre geeky, déjanté et sauvage, en français, on ne fait pas mieux. Pas vraiment safe for work, et pas tout à fait “libriste” comme j’aime, les tranches de rires sont garanties ; même si parfois on est un peu verreux d’avoir écouter jusqu’à la fin et le bien nommé “wazzuf”.</li> -<li><a href="http://www.agencetousgeeks.com/">Agence Tous Geeks (fr)</a> : fils caché de l’apéro du captain, on y retrouve des amis (et membres de ce dernier), mais c’est un peu plus calme.</li> -<li><a href="http://bazingcast.com/about/">Bazingcast (fr)</a> : podcast geek, plus posé que les deux précédents mais avec -des débats, des trolls et tout ce que l’on peut attendre de geeks.</li> -<li><a href="http://www.captainposix.net/">Parole de Tux (fr-be)</a> : podcast venant de nos voisin belge, pas trop long et plutôt sympa ; et si comme moi vous adorez l’accent belge, c’est le top.</li> -<li><a href="http://faif.us/">Free as in Freedom (en)</a> : podcast parlant de logiciel -libre principalement côté license, truc légal, etc.. en anglais, faut -parfois s’accrocher.</li> -<li><a href="http://episodes.gitminutes.com/">Git Minutes (en)</a> : podcast à propos de -Git et des outils de son écosystème (vcsh, etc..).</li> -</ul> - -<h2 id="radio">Radio</h2> - -<p>J’aime bien la radio, bien plus que la télévision (que j’allume si peu qu’à -chaque fois la box se met à jour <code>;-p</code>).</p> - -<ul> -<li><a href="http://www.franceinter.fr/emission-laura-leishman-project">France Inter - LLP (Laura leishman Project)</a></li> -<li><a href="http://radiofrance-podcast.net/podcast09/rss_12265.xml">Le Mouv’ - Laura Leishman Project</a></li> -<li><a href="http://www.franceinter.fr/emission-interception">France Inter - Interception</a></li> -<li><a href="http://www.la-bas.org/">France Inter - là-bas si j’y suis</a></li> -<li><a href="http://www.franceculture.fr/podcast/4689840">France Culture - Pixel</a></li> -<li><a href="http://www.franceculture.fr/podcast/4685228">France Culture - Place de la toile</a></li> -<li><a href="http://www.franceculture.fr/podcast/4689418">France Culture - Philippe Meyer</a></li> -<li><a href="http://radiofrance-podcast.net/podcast09/rss_12582.xml">Le Mouv’ - Glitch (sur le Mouv’)</a></li> -<li><a href="http://radiofrance-podcast.net/podcast09/rss_12691.xml">Le Mouv’ - Code Source</a></li> -<li><a href="http://radiofrance-podcast.net/podcast09/rss_12190.xml">Le Mouv’ - Suivez le geek</a></li> -<li><a href="http://www.divergence-fm.org/-http-www-divergence-fm-org-ecrire-exec-rubrique-id_rubrique-61-.html">Divergence Numerique</a></li> -</ul> - -<h2 id="musique">Musique</h2> - -<p>Les podcast suivant sont purement musique, tous musique <em>techno</em> ou -trance (que j’aime bien).</p> - -<ul> -<li><a href="http://podcasts.flaix.fr/corstencountdown">Ferry Corsten - Corsten Countdown</a></li> -<li><a href="http://www.galexmusic.com/podcast/gareth.xml">Gareth Emery Podcast</a></li> -<li><a href="http://feedproxy.feedburner.com/Tiestos_club_life">Tiesto Club Life</a></li> -<li><a href="http://oakenfold.libsyn.com/rss">Oakenfold Perfecto Podcast</a></li> -</ul> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2014-03-24-redesign-et-r%C3%A9solutions/" title="Redesign Et Résolutions">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2013-09-08-maven-tmpfs/" title="Maven Tmpfs">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2014-03-24-redesign-et-résolutions.org b/www/vincent.demeester.fr/content/legacy/posts/2014-03-24-redesign-et-résolutions.org @@ -1,76 +0,0 @@ -#+title: Redesign et Résolutions -#+date: <2014-03-24 Mon> -#+filetags: jekyll design images redesign -#+setupfile: ../templates/post.org - -* Introduction - -Un /tout petit/ post pour parler rapidement, entre autre, du redesign de -[[http://vincent.demeester.fr][vincent.demeester.fr]] et de mes -résolutions. - -* Redesign - :PROPERTIES: - :CUSTOM_ID: redesign - :END: - -Les raisons de ce redesign sont assez simple : je change d'employeur et -de ville (retour sur Paris =\o/=). Cela fait pas mal de changement, et -en voulant mettre à jour la page d'accueil (ce que je n'ai toujours pas -fait =;-P=), j'avais envie de /déménager/ le site en quelques sortes. - -Pour l'inspiration c'est assez facile à trouver, regarder -[[http://medium.com][medium]], le site de -[[http://www.viksit.com/][Viksit Gaur]] ou encore celui de -[[http://silent-strength.com/][Michael]] (coucou =:-P=). J'adore ce -genre de site, assez épuré mais avec une partie fixe (à gauche ou à -droite) et avec des images changeantes. - -Les images en fond de l'espace de gauche peuvent changer d'une page à -l'autre. Je suis en train de m'amuser un peu avec -[[http://jekyllrb.com][Jekyll]]. Il faut que je trouve un moyen -d'optimiser un peu les images que j'utilise parce que là je joue un peu -le bourrin. - -* Résolutions - :PROPERTIES: - :CUSTOM_ID: résolutions - :END: - -Nouvelle année, nouveau boulot, implique nouvelles résolutions. Il y a -deux aspects à ces /résolutions/ : sur un plan -informatique/geek/travail/organisation, et sur un plan purement -/physique/. - -Mon retour sur Paris devrait me permettre de participer à un peu plus -d'évènements, notamment du côté des Java User Group, mais aussi FSFE, et -j'en passe. Je compte également continué à jouer le /factotum/ en me -gardant un peu de temps au niveau personnel pour travailler sur des -aspects /geek/ que je n'aurais peut-être pas l'occasion de pratiquer au -travail. Au niveau de mes /points d'entrées/ sur le web, je compte -remettre un peu en route la partie blog de ce site et tourner -shortbrain.org (ou autre) en un site plus "documentation" en me basant -sur mes notes (powered by [[http://org-mode.org][org-mode]]). Je me suis -également remis à [[https://www.gnu.org/software/emacs/][Gnu Emacs]] et -/oh god/ qu'est-ce que c'est bon =:-D=. - -Au niveau phyisque, dans la continuité de la fin 2012, l'année 2013 a -probablement été la pire de ma vie. Les problèmes de dos c'est pas -facile tous les jours.. En février, j'avais peur de ne jamais remonter -sur un vélo ; en Mai je remontais pour la première fois sur le vélo, en -Septembre je faisais 40km par semaine et en décembre j'étais presque -capable de faire 30km en une journée. Mème si l'année 2014 a mal -commencé (je me suis felé un côte en Janvier), mes objectifs pour cette -année et les futurs sont nettement plus positif. Le -[[http://fitbit.com][fitbit]] que j'ai acquis en Février me permet -d'avoir un objectif de marche (certes assez modeste) de 10000 pas et -8,05 km par jour. Je compte bien me fixer d'autre objectifs : monter la -barre plus haut (15000 voir plus), faire 50km de vélo sur une journée. - -Les objectifs physiques à très long termes sont également assez simples -: retrouver ma forme physique et ne plus être géné à cause du dos. En -gros c'est : être capable de faire 120km de vélo et monter des cols (Col -du Sapenay, Mont Revard) et à long terme, faire des courses de footing -(i.e. 10km, Paris-Versaille, Semi-marathon, marathon :D). - -Sur ce, je vais retourner à mes cartons :-P. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2014-03-24-redesign-et-résolutions/index.html b/www/vincent.demeester.fr/content/legacy/posts/2014-03-24-redesign-et-résolutions/index.html @@ -1,166 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2014-03-24-redesign-et-r%C3%A9solutions/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Redesign Et Résolutions</h1><a href='https://vincent.demeester.fr/posts/2014-03-24-redesign-et-r%C3%A9solutions/'></a> - <address class="signature"> - <span class="date">Mon, 24 March, 2014</span> - <span class="words">(600 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#me">me</a></li> - - - - - - <li class="tag tag-jekyll"><a href="/tags/#jekyll">jekyll<span>4</span></a></li> - - - <li class="tag tag-design"><a href="/tags/#design">design<span>1</span></a></li> - - - <li class="tag tag-images"><a href="/tags/#images">images<span>1</span></a></li> - - - <li class="tag tag-redesign"><a href="/tags/#redesign">redesign<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Un <em>tout petit</em> post pour parler rapidement, entre autre, du redesign de <a href="http://vincent.demeester.fr">vincent.demeester.fr</a> et de mes résolutions.</p> - -<h2 id="redesign">Redesign</h2> - -<p>Les raisons de ce redesign sont assez simple : je change d’employeur et de ville (retour sur Paris <code>\o/</code>). -Cela fait pas mal de changement, et en voulant mettre à jour la page d’accueil (ce que je n’ai toujours pas -fait <code>;-P</code>), j’avais envie de <em>déménager</em> le site en quelques sortes.</p> - -<p>Pour l’inspiration c’est assez facile à trouver, regarder <a href="http://medium.com">medium</a>, le site de -<a href="http://www.viksit.com/">Viksit Gaur</a> ou encore celui de <a href="http://silent-strength.com/">Michael</a> (coucou <code>:-P</code>). -J’adore ce genre de site, assez épuré mais avec une partie fixe (à gauche ou à droite) et avec des images changeantes.</p> - -<p>Les images en fond de l’espace de gauche peuvent changer d’une page à l’autre. Je suis en train de m’amuser un peu -avec <a href="http://jekyllrb.com">Jekyll</a>. Il faut que je trouve un moyen d’optimiser un peu les images que j’utilise -parce que là je joue un peu le bourrin.</p> - -<h2 id="résolutions">Résolutions</h2> - -<p>Nouvelle année, nouveau boulot, implique nouvelles résolutions. Il y a deux aspects à ces <em>résolutions</em> : sur un plan -informatique/geek/travail/organisation, et sur un plan purement <em>physique</em>.</p> - -<p>Mon retour sur Paris devrait me permettre de participer à un peu plus d’évènements, notamment du côté des Java User Group, mais -aussi FSFE, et j’en passe. Je compte également continué à jouer le <em>factotum</em> en me gardant un peu de temps au niveau -personnel pour travailler sur des aspects <em>geek</em> que je n’aurais peut-être pas l’occasion de pratiquer au travail. -Au niveau de mes <em>points d’entrées</em> sur le web, je compte remettre un peu en route la partie blog de ce site et -tourner shortbrain.org (ou autre) en un site plus “documentation” en me basant sur mes notes (powered by <a href="http://org-mode.org">org-mode</a>). -Je me suis également remis à <a href="https://www.gnu.org/software/emacs/">Gnu Emacs</a> et <em>oh god</em> qu’est-ce que c’est bon <code>:-D</code>.</p> - -<p>Au niveau phyisque, dans la continuité de la fin 2012, l’année 2013 a probablement été la pire de ma vie. Les -problèmes de dos c’est pas facile tous les jours.. En février, j’avais peur de ne jamais remonter sur un vélo ; en Mai -je remontais pour la première fois sur le vélo, en Septembre je faisais 40km par semaine et en décembre j’étais -presque capable de faire 30km en une journée. Mème si l’année 2014 a mal commencé (je me suis felé un côte en Janvier), -mes objectifs pour cette année et les futurs sont nettement plus positif. Le <a href="http://fitbit.com">fitbit</a> que j’ai -acquis en Février me permet d’avoir un objectif de marche (certes assez modeste) de 10000 pas et 8,05 km par jour. -Je compte bien me fixer d’autre objectifs : monter la barre plus haut (15000 voir plus), faire 50km de vélo -sur une journée.</p> - -<p>Les objectifs physiques à très long termes sont également assez simples : retrouver ma forme physique et ne plus être -géné à cause du dos. En gros c’est : être capable de faire 120km de vélo et monter des cols (Col du Sapenay, Mont Revard) -et à long terme, faire des courses de footing (i.e. 10km, Paris-Versaille, Semi-marathon, marathon :D).</p> - -<p>Sur ce, je vais retourner à mes cartons :-P.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2014-10-27-docker-1.3-ecosystem/" title="Docker 1.3 et son écosystème">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2013-10-12-podcasts/" title="Podcasts">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2014-10-27-docker-1.3-ecosystem/index.html b/www/vincent.demeester.fr/content/legacy/posts/2014-10-27-docker-1.3-ecosystem/index.html @@ -1,383 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2014-10-27-docker-1.3-ecosystem/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Docker 1.3 et son écosystème</h1><a href='https://vincent.demeester.fr/posts/2014-10-27-docker-1.3-ecosystem/'></a> - <address class="signature"> - <span class="date">Mon, 27 October, 2014</span> - <span class="words">(1700 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#zenika">zenika</a></li> - - - - - - <li class="tag tag-docker"><a href="/tags/#docker">docker<span>3</span></a></li> - - - <li class="tag tag-fig"><a href="/tags/#fig">fig<span>1</span></a></li> - - - <li class="tag tag-hub"><a href="/tags/#hub">hub<span>1</span></a></li> - - - <li class="tag tag-boot2docker"><a href="/tags/#boot2docker">boot2docker<span>1</span></a></li> - - - <li class="tag tag-container"><a href="/tags/#container">container<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - -<div class="notice">Cet article est disponible sur le <a href="http://blog.zenika.com/">Blog de Zenika</a> à l'adresse suivante : <a href="http://blog.zenika.com/index.php?post/2014/10/27/Docker-1-3-et-son-ecosysteme">http://blog.zenika.com/index.php?post/2014/10/27/Docker-1-3-et-son-ecosysteme</a>. Cet publication me sert de mirroir / sauvegarde.</div> - -<p>Le <strong>16 octobre dernier</strong>, <ins>Docker est passé en version 1.3</ins>. C'est une -bonne occasion de faire un point sur ce qu'apportent les mises à jour -qui sont sorties depuis la 1.0. Nous allons également en profiter pour -regarder les news <strong>importantes</strong> de l'écosystème Docker.</p> - - -<p><img src="/public/Billet_0511/docker_container_engine_logo.png" alt="Docker" title="Docker" /></p> - - -<p>Rappel très rapide, <strong>Docker est une plate-forme ouverte à destination des développeurs et administrateurs systèmes visant à faciliter la construction et le déploiement d'applications distribuées</strong>. De manière -moins marketing, l'idée derrière Docker est d'<strong>automatiser</strong> le <strong>déploiement</strong> d'environnements sous forme de <strong>conteneurs légers</strong>, portables et auto-suffisants ; les conteneurs permettant d'isoler -l'exécution des applications dans des contextes d'exécution. Pour ce -faire, Docker, écris en <a href="http://golang.org/">Go</a>, reprend les bases de <strong>LXC</strong>, utilise les fonctionnalités -du <strong>noyau Linux</strong> (CGroups, Namespaces, …) et se base <em>initialement</em> sur un -système de fichier "en oignons" AUFS ; D'autres backend sont supportés -également comme BTRFS ou <em>devicemapper</em> (LVM).</p> - - -<p>Depuis le 9 juin 2014 et la release de la version 1.0 "production-read", l'équipe derrière Docker n'a pas chomé et 3 -nouvelles mises à jour sont sorties depuis ; à savoir que les -<em>releases</em> de Docker se font à un rythme pré-défini, "à-la" Linux, -tout ce qui est prêt et testé est intégré à la release qui -suit. Voyons, de façon non-exhaustive, quelles sont les princiales -améliorations apportées par ces différentes versions.</p> - -<h4>Hub : Images officielles et language stack</h4> - - -<p>Le <strong>Hub</strong>, tel qu'il a été nommé après la sortie de Docker 1.0 est <strong>un dépôt des images Docker</strong> de tout-un-chacun qui souhaite les partager.</p> - - -<p>Au début de l'été, Docker Inc. a annoncé l'apparition des <strong>dépots officiels</strong>. L'idée est d'estampiller des images Docker comme officielles, -c'est à dire vérifiées et garanties comme étant issues et supportées par -les mainteneurs des projets. De nombreuses images officielles existent -déjà pour les principaux projets open-source, comme Ubuntu, MongoDB, -etc. Toute communauté open-source ou même tout éditeur logiciel peut -entrer en contact avec l'équipe Docker pour voir son/ses images -estampillées "officielles", après validation. Cette étiquette vient se -rajouter à l'étiquette "<em>automated build repository</em>", précédement -appelée <em>verified</em> (ce qui prétait à confusion) qui donne la garantie -à l'utilisateur que l'image a été construite de manière automatique -par l'infrastructure de Docker Inc. Il est également à noter que la version -1.3.0 de Docker apporte la vérification de la provenance et de -l'intégrité des images officielles via signature électronique ; même si -pour l'instant c'est en <em>work-in-progress</em>.</p> - - -<p>Un autre ajout récent au Docker Hub, datant de fin septembre, vaut le -détour : les l<strong>anguage stack</strong>, des images de bases <em>pre-construites</em> avec tous les outils nécessaires pour faire tourner une application dans un langage donné. Un développeur souhaitant rapidement construire -un conteneur avec, par exemple, une application Clojure, n'a plus -besoin de <em>réinventer la roue</em> (i.e. partir d'une image de base, installer -le JDK, installer lein, etc.). Il lui suffit de partir d'une des -<em>language stack</em>, ici clojure.</p> - -<pre class="bash code bash" style="font-family:inherit">FROM clojure -COPY . <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>app -WORKDIR <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>src<span style="color: #000000; font-weight: bold;">/</span>app -CMD <span style="color: #7a0874; font-weight: bold;">[</span><span style="color: #ff0000;">"lein"</span>, <span style="color: #ff0000;">"run"</span><span style="color: #7a0874; font-weight: bold;">]</span></pre> - - -<h4>Restart policies (1.2.0)</h4> - - -<p>Docker 1.2 a apporté une option en plus à la commande <code>run</code> : -<code>--restart</code>. Il permet de définir une <strong>politique de redémarrage</strong> dans -le cas où le conteneurs viendrait à mourrir, que ce soit de manière -normale (code de retour à 0) ou inattendue (<em>failure</em>, code de retour -différent de 0). Trois options sont disponibles pour l'instant :</p> - -<ul> -<li><strong>no</strong> : pas de redémarrage, fonctionnement par défaut.</li> -<li><strong>on-failure</strong>: redémarrage automatique si le conteneur s'est terminé de façon anormale. Il est possible d'ajouter un nombre maximum de redémarrage ; avec <code>--restart=on-failure:3</code> docker essaiera de redémarrer 3 fois avant d'abandonner.</li> -<li><strong>always</strong> : redémarrage automatique, tout le temps, erreurs ou pas.</li> -</ul> - -<h4>Injection de processus (1.3.0)</h4> - - -<p>La possibilité de voir ce qui se passe dans le container, et par -conséquent de s'en servir pour debugger, s'est averé longtemps -complexe. Dans les <em>premiers jours</em> de Docker, l'installation d'un -démon ssh était une solution commune. Cependant, celà complexifiait la -création d'un conteneur ; en effet, Docker est fait pour lancer et isoler -une seule commande, l'ajout d'un démon sshd imposait alors de mettre -en place une solution du type <em>init</em> comme supervisord, runit, ou -autres. Un article de Jérôme Petazonni, employé Docker Inc, -a mis les choses au point : -<strong><a href="http://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/">If you run SSHD in your Docker containers, you're doing it wrong!</a></strong>, -littéralement "<em>Si vous faites tourner SSHD dans vos container Docker, vous vous trompez</em>". Jérôme avait créé à l'époque un outil, -<a href="https://github.com/jpetazzo/nsenter">nsenter</a>, qui était (et est toujours) installable en passant par un container, histoire de montrer -un peu de magie.</p> - - -<p>La version 1.3 de Docker intègre un nouvelle commande, <code>exec</code> qui -n'est autre que nsenter, en mieux, directement intégré à Docker, plus -besoin de passer par un outil externe. <strong>Il devient donc possible d'executer n'importe quelle process à l'intérieur donc container, qui est en cours d'exécution</strong>. Ainsi un simple <code>docker exec -it ubuntu_bash bash</code> et -nous voici dans une session bash à l'intérieur du conteneur. Bien -entendu, comme pour nsenter, cela ne change pas l'idée derrière Docker -qui est "une application par conteneur" ; la commande <code>exec</code> est -surtout présente pour répondre à des problématiques de <em>debug</em> et de -<em>developpement</em>.</p> - - -<h4>Cycle de vie d’un container (1.3.0)</h4> - - -<p>Une autre nouvelle commande arrive avec la version 1.3.0 de Docker, -c'est <code>create</code>. Beaucoup d'utilisateur ont demandé d'être capable -de séparer la création initiale de conteneur et son lancement ; -auparavant il n'existait que la commande <code>run</code> qui faisait les deux -d'un coup.</p> - -<pre class="bash code bash" style="font-family:inherit">$ docker create <span style="color: #660033;">-t</span> <span style="color: #660033;">-i</span> fedora <span style="color: #c20cb9; font-weight: bold;">bash</span> -6d8af538ec541dd581ebc2a24153a28329acb5268abe5ef868c1f1a261221752 -$ docker start <span style="color: #660033;">-a</span> <span style="color: #660033;">-i</span> 6d8af538ec5 -bash-<span style="color: #000000;">4.2</span><span style="color: #666666; font-style: italic;">#</span></pre> - - -<h4>Options de sécurité (1.3.0)</h4> - - -<p>Les utilisateurs de SELinux ou AppArmor vont être content, la commande -<code>--security-opt</code>, arrivée avec la version 1.3.0, permet les <em>labels</em> -et <em>profiles</em> de ces derniers, ce qui donne quelque chose comme :</p> - -<pre class="bash code bash" style="font-family:inherit">docker run <span style="color: #660033;">--security-opt</span> label:<span style="color: #7a0874; font-weight: bold;">type</span>:svirt_apache <span style="color: #660033;">-i</span> <span style="color: #660033;">-t</span> centos <span style="color: #c20cb9; font-weight: bold;">bash</span></pre> - - -<p>L'avantage principal de cette nouvelle commande, c'est, sur -les systèmes qui sont configurés avec SELinux ou AppArmor, de pouvoir -donner des privilèges de manière plus fine qu'avec l'option -<code>--privileged</code> (qui donne tout) et ainsi diminuer les risques -potentiels.</p> - - -<h4>Boot2docker</h4> - - -<p>Docker s'appuyant sur des fonctionnalitées de noyau Linux, son usage -est <em>limité</em> à un système hôte avec un noyau Linux. Le projet -boot2docker vise à enlever cette barrière en <strong>permettant d'avoir la commande docker sous Mac OS X et Windows</strong>. Il s'agit ni plus ni moins -d'une machine virtuelle VirtualBox légère, basée sur la distribution -Tiny Core Linux, pour avoir un <em>overhead</em> le plus faible possible. -L'utilisation de boot2docker n'est pas encore totalement transparente, -principalement pour la gestion des ports ou encore du montage des -volumes du Host (OS X ou Windows) dans le conteneur Docker. La version -1.3 de docker, et la version correspondante de boot2docker, permettent -maintenant aux utiliseurs de Mac OS X de monter leur dossier <em>hôtes</em> -dans le conteneur.</p> - - -<h4>Fig 1.0</h4> - - -<p><a href="http://www.fig.sh/">Fig</a> est un outil de développement basé sur Docker, écrit en Python. L'idée est de -définir son environnement via un fichier YAML, que ce soit pour le -code sur lequel nous travaillons mais également les services externes -desquels notre application dépend (Base de données, ''Message -queue'', etc.).</p> - - -<p>Nous avons donc, par exemple, un <code>Dockerfile</code> :</p> - -<pre class="bash code bash" style="font-family:inherit">FROM clojure:lein-2.5.0 -ADD . <span style="color: #000000; font-weight: bold;">/</span>code -WORKDIR <span style="color: #000000; font-weight: bold;">/</span>code -RUN lein run</pre> - - - -<p>Et un <code>fig.yml</code> :</p> - -<pre>[yaml] -web: - build: . - command: lein run - links: - - db - ports: - - "8000:8000" -db: - image: postgres -</pre> - - -<p>Enfin un petit <code>fig up</code> et c'est gagné, nous obtenons notre base de données -relationnelle qui tourne, notre appli qui a été construite et qui -tourne aussi, et qui est lié à notre conteneur db. Il existe bien d'autres -commandes (<code>start</code>, <code>stop</code>, <code>destroy</code>, etc.).</p> - - -<p>Fig était initialement développé par <a href="https://www.orchardup.com/">Orchard</a>, qui a été acquis cette -année par Docker Inc. Ce 17 octobre, l'équipe Docker a donc fait un release 1.0 de -Fig en ajoutant le support à docker 1.3 et à boot2docker. Un certain nombre de commandes et de -nouvelles fonctionnalitées ont étés ajoutées, notament :</p> - -<ul> -<li><code>fig port</code>, qui liste les ports par service,</li> -<li><code>fig pull</code>, qui récupère la dernière version d'un service,</li> -<li><code>fig restart</code>, qui redémarre les conteneurs (<code>stop</code> et <code>start</code>)</li> -<li>le support de <code>.dockerignore</code></li> -<li>le support de connection en TLS au daemon Docker</li> -<li>et pas mal d'autres options.</li> -</ul> - -<p>Mais l'annonce principale accompagnant cette version est que <strong>Fig ne recevra plus de mise à jour majeure à partir de cette version 1.0</strong> -puisque l'équipe Docker travaille pour <strong>intégrer les fonctionnalités</strong> -que Fig apporte, <strong>directement dans Docker</strong> ; ce qui est une -excellente nouvelle.</p> - - -<h4>Partenariat avec Microsoft</h4> - - -<p>Cela transpirait ces derniers mois, dans les différentes conférences -et meetups, Microsoft s'intéressait de très prêt à Docker. C'est -maintenant officiel, <strong>Docker Inc et Microsoft sont partenaires</strong>. Le -partenariat couvre pour l'instant les sujets suivants :</p> - -<ul> -<li>Ajouter le support de windows comme hôte Docker.</li> -<li>Pour Microsoft, supporter les API <em>open-orchestration</em> de Docker.</li> -<li>Intégration de Docker dans Microsoft Azure.</li> -<li>Collaboration étroite sur les applications qui ont besoin de plusieurs conteneur (i.e. ce que Fig fait de mieux), et le support d'application qui sont composés de conteneurs Linux et Windows.</li> -</ul> - -<p>Le but <em>ultime</em> de Docker quand il a été distribué de façon libre -était : "__Construire le 'bouton' qui permet à toutes applications -d'être construites et déployées sur n'importe quel serveur, n'importe -où.__" (C'est nettement plus classe en anglais : “''To build the ‘button’ -that enables any application to be built and deployed on any server, -anywhere.''”). Ce partenariat est donc une nouvelle marche en direction -de ce dernier.</p> - - -<h4>Conclusion</h4> - - -<p>Un an et demi après la première <em>release</em> publique de Docker et près -de 5 mois après la version 1.0, Docker et sa communauté avancent -toujours aussi vite. Comme Solomon Hykes (CTO et co-fondateur de dotCould) -avait dit lors de la dockerCon 14 : "<strong>la valeur réelle de docker n'est pas la technologie, mais le fait que les gens se mettent d'accord sur quelque chose</strong>" ; Docker Inc. pousse principalement dans le sens de la -standardisation. Le développement de -<a href="https://github.com/docker/libcontainer">libcontainer</a>, -<a href="https://github.com/docker/libchan">libchan</a> et -<a href="https://github.com/docker/libswarm">libswarm</a> sont des projets qui -vont dans ce sens. La communautée est toute aussi <em>bouillante</em> d'idées -et chaque jour voit de nouveau projet plus intéressant les uns que les -autres.</p> - - -<p>Enfin la <strong><a href="http://europe.dockercon.com/">dockerCon Europe</a>, les 4 et 5 décembre 2014</strong> viendra couronner une année très riche du côté de Docker et -de son écosystème. Rendez-vous mi-décembre pour faire un petit retour - sur la première conférence européenne Docker ;-).</> - - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2015-05-01-orgmode-et-jekyll/" title="Orgmode et Jekyll">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2014-03-24-redesign-et-r%C3%A9solutions/" title="Redesign Et Résolutions">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2015-05-01-orgmode-et-jekyll/index.html b/www/vincent.demeester.fr/content/legacy/posts/2015-05-01-orgmode-et-jekyll/index.html @@ -1,260 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2015-05-01-orgmode-et-jekyll/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Orgmode et Jekyll</h1><a href='https://vincent.demeester.fr/posts/2015-05-01-orgmode-et-jekyll/'></a> - <address class="signature"> - <span class="date">Fri, 1 May, 2015</span> - <span class="words">(900 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-jekyll"><a href="/tags/#jekyll">jekyll<span>4</span></a></li> - - - <li class="tag tag-blog"><a href="/tags/#blog">blog<span>2</span></a></li> - - - <li class="tag tag-emacs"><a href="/tags/#emacs">emacs<span>2</span></a></li> - - - <li class="tag tag-orgmode"><a href="/tags/#orgmode">orgmode<span>2</span></a></li> - - - <li class="tag tag-html"><a href="/tags/#html">html<span>2</span></a></li> - - <br/> - - </ul> - </header> - - - - <div id="outline-container-sec-1" class="outline-2"> -<h2 id="sec-1">Un peu plus d'un an..</h2> -<div class="outline-text-2" id="text-1"> -<p> -.. que je n'ai rien posté ici. Le temps passe bien vite, mais c'est plutôt une bonne chose. Je crois que quelque chose me manquait pour poster ici plus souvent. -</p> - -<blockquote> -<p> -Au niveau de mes points d'entrées sur le web, je compte remettre un peu en route la partie blog de ce site et tourner shortbrain.org (ou autre) en un site plus "documentation" en me basant sur mes notes (powered by org-mode). <b>Je me suis également remis à Gnu Emacs et oh god qu'est-ce que c'est bon</b> :-D. -</p> -</blockquote> - -<p> -C'est ce que j'écrivais il y a un an, et effectivement c'est toujours aussi bon <code>;-D</code>. J'ai commencé à utiliser <code>org-mode</code> de manière assez intensive, pour mettre en place mon <i>personal kanban</i> mais également pour prendre mes notes. Et plus je l'utilise, plus j'ai du mal m'en passer et à aller dans mon dossier hébergeant ce site pour y écrire en Markdown. Il me fallait donc trouver une astuce pour convertir certaines notes en post pour Jekyll. C'est maintenant chose faite (après 6 mois dans ma TODO-list…), et voici comment je m'en sors. -</p> - -<p> -L'idée générale est assez simple : -</p> - -<ol class="org-ol"> -<li>Utiliser un dossier particulier pour les notes destiné à ce blog -</li> -<li>Exporter, au format html, ces notes dans le bon dossier (<code>_posts</code>) -</li> -<li>… et c'est tout en fait :) — c'était pas <i>ben</i> compliqué ! -</li> -</ol> -</div> -</div> - -<div id="outline-container-sec-2" class="outline-2"> -<h2 id="sec-2">Les fichiers org</h2> -<div class="outline-text-2" id="text-2"> -<p> -Tous mes fichiers <code>org-mode</code> sont dans un ensemble de dossiers bien particulier — cela n'a pas grand chose d'important à faire ici, mais ça permet de suivre la configuration qui suit. Il s'agit du dossier <code>~/desktop/org/</code>, et de ces fils : <code>todos</code> pour ce que je dois faire et <code>notes</code> pour ma prise de note. Dans <code>notes</code> on trouve donc des dossiers et en particulier un qui se nomme <code>vdf</code> (pour Vincent.Demeester.Fr). -</p> - -<p> -La seule différence que les fichiers <code>.org</code> ont dans ce dossier par rapport aux autres, c'est le début du fichier. En effet, <a href="http://jekyllrb.com/">Jekyll</a> a besoin d'une entête en <code>YAML</code> pour le layout, les tags, la catégorie et plein d'autres trucs. Le fichier <code>org</code> de ce billet ressemble à ça par example : -</p> - -<pre class="example"> -#+BEGIN_HTML ---- -layout: post -category: developement -tags: jekyll blog emacs orgmode html -lang: fr ---- -#+END_HTML -* Un peu plus d'un an.. - -.. que je n'ai rien posté ici. Le temps passe bien vite, mais c'est plutôt une bonne chose. Je crois que quelque chose me manquait pour poster ici. - -[…] -</pre> - -<p> -Les utilisateurs de Jekyll reconnaitront les <code>---</code> et le format du header. <code>#+BEGIN_HTML</code> et <code>#+END_HTML</code> sont là pour dire à <code>org-mode</code> d'exporter un bloc en HTML sans l'interpréter — c'est une façon de mettre du HTML dans un document <code>org</code> si on peut pas faire ce qu'on veut avec le <i>markup</i>. Ici ça nous permet d'exporter tel quel le header de <a href="http://jekyllrb.com/">Jekyll</a> en haut du HTML généré, pratique ! -</p> -</div> -</div> - -<div id="outline-container-sec-3" class="outline-2"> -<h2 id="sec-3">Configuration de org-mode</h2> -<div class="outline-text-2" id="text-3"> -<p> -Il reste maintenant à configurer le <i>projet de publication</i> (publishing project) dans Emacs. Je vais mettre ici juste la partie intéressante, donc pour plus d'information sur comment publier des fichiers org-mode avec Emacs, c'est par <a href="http://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html">ici</a> pour un tutoriel (j'adore <a href="http://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html">worg</a> soit dit en passant :P). -</p> - -<p> -L'idée c'est de définir un projet avec plusieurs <i>components</i>, un pour les fichiers <code>org</code>, un pour les fichiers <code>css</code> et un pour les <i>assets</i> (images, vidéos, …). On souhaite également ne pas générer de table des matières (TOC) et ne génerer que le <i>body</i> (pas de <code><head></code>, …). Et ça se présente comme suit. -</p> - -<div class="org-src-container"> - -<pre class="src src-emacs-lisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">Variables</span> -<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-keyword">setq</span> <span class="org-rainbow-identifiers-identifier-9">vdf-base-directory</span> <span class="org-string">"~/desktop/org/notes/vdf/"</span> - <span class="org-rainbow-identifiers-identifier-11">vdf-site-directory</span> <span class="org-string">"~/src/github/vdemeester/vdemeester.github.com"</span> - <span class="org-rainbow-identifiers-identifier-4">vdf-publishing-directory</span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-identifiers-identifier-15">expand-file-name</span> <span class="org-string">"_posts"</span> <span class="org-rainbow-identifiers-identifier-11">vdf-site-directory</span><span class="org-rainbow-delimiters-depth-2">)</span> - <span class="org-rainbow-identifiers-identifier-2">vdf-css-publishing-directory</span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-identifiers-identifier-15">expand-file-name</span> <span class="org-string">"css"</span> <span class="org-rainbow-identifiers-identifier-11">vdf-site-directory</span><span class="org-rainbow-delimiters-depth-2">)</span> - <span class="org-rainbow-identifiers-identifier-15">vdf-assets-publishing-directory</span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-identifiers-identifier-15">expand-file-name</span> <span class="org-string">"assets"</span> <span class="org-rainbow-identifiers-identifier-11">vdf-site-directory</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> - -<span class="org-comment-delimiter">;; </span><span class="org-comment">Project</span> -<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-keyword">setq</span> <span class="org-rainbow-identifiers-identifier-12">org-publish-project-alist</span> - `<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span><span class="org-string">"vdf-notes"</span> - <span class="org-builtin">:base-directory</span> ,<span class="org-rainbow-identifiers-identifier-9">vdf-base-directory</span> - <span class="org-builtin">:base-extension</span> <span class="org-string">"org"</span> - <span class="org-builtin">:publishing-directory</span> ,<span class="org-rainbow-identifiers-identifier-4">vdf-publishing-directory</span> - <span class="org-builtin">:exclude</span> <span class="org-string">"FIXME"</span> - <span class="org-builtin">:section-numbers</span> <span class="org-rainbow-identifiers-identifier-2">nil</span> - <span class="org-builtin">:with-toc</span> <span class="org-rainbow-identifiers-identifier-2">nil</span> - <span class="org-builtin">:with-drawers</span> <span class="org-rainbow-identifiers-identifier-8">t</span> - <span class="org-builtin">:htmlized-source</span> <span class="org-rainbow-identifiers-identifier-8">t</span> - <span class="org-builtin">:publishing-function</span> <span class="org-rainbow-identifiers-identifier-7">org-html-publish-to-html</span> - <span class="org-builtin">:headline-levels</span> <span class="org-rainbow-identifiers-identifier-8">4</span> - <span class="org-builtin">:body-only</span> <span class="org-rainbow-identifiers-identifier-8">t</span><span class="org-rainbow-delimiters-depth-3">)</span> - <span class="org-rainbow-delimiters-depth-3">(</span><span class="org-string">"vdf-static-css"</span> - <span class="org-builtin">:base-directory</span> ,<span class="org-rainbow-identifiers-identifier-9">vdf-base-directory</span> - <span class="org-builtin">:base-extension</span> <span class="org-string">"css"</span> - <span class="org-builtin">:publishing-directory</span> ,<span class="org-rainbow-identifiers-identifier-2">vdf-css-publishing-directory</span> - <span class="org-builtin">:recursive</span> <span class="org-rainbow-identifiers-identifier-8">t</span> - <span class="org-builtin">:publishing-function</span> <span class="org-rainbow-identifiers-identifier-5">org-publish-attachment</span> - <span class="org-rainbow-delimiters-depth-3">)</span> - <span class="org-rainbow-delimiters-depth-3">(</span><span class="org-string">"vdf-static-assets"</span> - <span class="org-builtin">:base-directory</span> ,<span class="org-rainbow-identifiers-identifier-9">vdf-base-directory</span> - <span class="org-builtin">:base-extension</span> <span class="org-string">"png</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">|</span></span><span class="org-string">jpg</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">|</span></span><span class="org-string">gif</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">|</span></span><span class="org-string">pdf</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">|</span></span><span class="org-string">mp3</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">|</span></span><span class="org-string">ogg"</span> - <span class="org-builtin">:publishing-directory</span> ,<span class="org-rainbow-identifiers-identifier-15">vdf-assets-publishing-directory</span> - <span class="org-builtin">:recursive</span> <span class="org-rainbow-identifiers-identifier-8">t</span> - <span class="org-builtin">:publishing-function</span> <span class="org-rainbow-identifiers-identifier-5">org-publish-attachment</span> - <span class="org-rainbow-delimiters-depth-3">)</span> - <span class="org-rainbow-delimiters-depth-3">(</span><span class="org-string">"vdf"</span> <span class="org-builtin">:components</span> <span class="org-rainbow-delimiters-depth-4">(</span><span class="org-string">"vdf-notes"</span> <span class="org-string">"vdf-static-css"</span> <span class="org-string">"vdf-static-assets"</span><span class="org-rainbow-delimiters-depth-4">)</span><span class="org-rainbow-delimiters-depth-3">)</span> - <span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> -</pre> -</div> - -<p> -J'utilise des variables, c'est pas indispensable mais c'est plus pratique. Il y a trois <i>components</i>, chacun définit les fichiers qu'il traite grâce à <code>:base-extension</code>. Intéressons-nous surtout à <code>vdf-notes</code> puisque c'est celui qui nous sort les fichiers <code>HTML</code> à partir des fichiers <code>org</code>. On se passe de table des matières grâce à <code>:with-toc nil</code>, on ne génère que le <i>body</i> grâce à <code>:body-only t</code> et on évite les numéros de sections avec <code>:section-numbers nil</code>. Le bonus vient avec <code>:htmlized-source t</code> puisque du coup, les parties sources (entre <code>#+BEGIN_SRC</code> et <code>#+END_SRC</code>) sont exportés avec les mêmes couleurs que j'ai dans ma configuration Emacs (avec les <a href="https://github.com/vdemeester/emacs-config#raindow-identifiers">rainbow-identifiers</a>, voir ce post <a href="https://medium.com/@evnbr/coding-in-color-3a6db2743a1e">là</a> également). -</p> - -<p> -Il ne reste plus qu'à publier le projet quand on le souhaite avec <code>org-publish</code> — je vous laisse lire la documentation pour savoir comment on fait. -</p> - -<p> -Et c'est tout bon. Un petit <code>bundle exec jekyll serve --watch</code> pour voir le rendu — et quand on est content on commit. Et c'est la fête <code>\o/</code>. -</p> - -<p> -C'est tout pour le moment, la fréquence des billets de ce blog devrait s'incrémenter un peu maintenant. -</p> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2015-05-09-migration-to-hugo/" title="Migration vers hugo">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2014-10-27-docker-1.3-ecosystem/" title="Docker 1.3 et son écosystème">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2015-05-09-migration-to-hugo/index.html b/www/vincent.demeester.fr/content/legacy/posts/2015-05-09-migration-to-hugo/index.html @@ -1,229 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2015-05-09-migration-to-hugo/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Migration vers hugo</h1><a href='https://vincent.demeester.fr/posts/2015-05-09-migration-to-hugo/'></a> - <address class="signature"> - <span class="date">Sat, 9 May, 2015</span> - <span class="words">(500 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-hugo"><a href="/tags/#hugo">hugo<span>1</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-blog"><a href="/tags/#blog">blog<span>2</span></a></li> - - - <li class="tag tag-emacs"><a href="/tags/#emacs">emacs<span>2</span></a></li> - - - <li class="tag tag-orgmode"><a href="/tags/#orgmode">orgmode<span>2</span></a></li> - - - <li class="tag tag-html"><a href="/tags/#html">html<span>2</span></a></li> - - <br/> - - </ul> - </header> - - - - <p> -Et voilà, une semaine après m'être remis en route sur ce blog, je fais -déjà une migration <code>>_<</code>. Je me suis rendu compte que <a href="http://jekyllrb.com/">Jekyll</a> -m'énervait un peu, et comme je suis à fond dans <a href="http://golang.org/">go</a> en ce moment, j'ai -regardé du côté des générateurs de sites static et <a href="http://gohugo.io/">Hugo</a> a clairement -retenu mon attention. -</p> - -<div id="outline-container-sec-1" class="outline-2"> -<h2 id="sec-1">Pourquoi Hugo ?</h2> -<div class="outline-text-2" id="text-1"> -<blockquote> -<p> -<b>Make the Web Fun Again</b> -</p> - -<p> -Introducing Hugo, a new idea around making website creation simple again. Hugo flexibly works with many formats and is ideal for blogs, docs, portfolios and much more. Hugo’s speed fosters creativity and makes building a website fun again. -</p> -</blockquote> - -<p> -Presque tout est dit dans cette citation. -</p> - -<ul class="org-ul"> -<li>Hugo est rapide. -</li> -<li>Le système de content est un régale. -</li> -<li>L'organisation d'un <i>projet hugo</i> est simple : -<ul class="org-ul"> -<li><code>content</code> pour le contenu, avec ce qu'on veut dedans, -</li> -<li><code>static</code> pour le contenu statique (<code>css</code>, <code>javascript</code>, <code>images</code>, …), -</li> -<li><code>layouts</code> pour les templates (super facile de mettre des templates différents en fonction des contenus, voir <a href="http://gohugo.io/templates/content/">ici</a>), -</li> -<li><code>themes</code> pour les themes applicables (qui définissent eux même <code>layouts</code> et <code>static</code>. -</li> -</ul> -</li> -<li>Le système de template est <a href="http://gohugo.io/templates/go-templates/">puissant</a> et un vrai régale. -</li> -<li>Le mode <code>server</code> a la possiblité de surveiller les fichiers(avec le <i>flag</i> <code>-w</code>, et implémente <a href="http://gohugo.io/extras/livereload/">LiveReload</a> ce qui est un petit bonus non négligeable. -</li> -</ul> -</div> -</div> - -<div id="outline-container-sec-2" class="outline-2"> -<h2 id="sec-2">Ce qui changes</h2> -<div class="outline-text-2" id="text-2"> -<p> -Le principale changement est sur le/les repository utilisés. Avant tout était dans <a href="https://github.com/vdemeester/vdemeester.github.com">vdemeester.github.com</a>, puisque c'est github qui générait le résultat final avec Jekyll. Ce n'est maintenant plus le cas : <a href="https://github.com/vdemeester/blog">blog</a> héberge les sources du blog (les fichiers content en Markdown ou <i>HTML-from-orgmode</i> ainsi que les templates et la configuration <a href="http://gohugo.io/">Hugo</a> — <a href="https://github.com/vdemeester/vdemeester.github.com">vdemeester.github.com</a> héberge désormais le résultat. -</p> - -<p> -J'en ai profité également pour faire quelques ajustements graphique, principalement sur les tags qui ont maintenant, parfois, des couleurs différentes. -</p> -</div> -</div> - -<div id="outline-container-sec-3" class="outline-2"> -<h2 id="sec-3">Intégration avec Emacs & orgmode</h2> -<div class="outline-text-2" id="text-3"> -<p> -Il me manque encore quelques petits <i>trucs</i> pour rendre ça automatique, mais dans l'idée, voilà le workflow que j'utilise quand je publie un article (comme maintenant) : -</p> - -<ol class="org-ol"> -<li>Démarre <code>hugo server -w</code> dans mon repository <code>blog</code>. -</li> -<li>Je créer mon fichier <code>org</code> au bon endroit (soit <code>$HOME/desktop/org/notes/vdf/monfichier.org</code>). Par rapport au <a href="http://vincent.demeester.fr/posts/2015-05-01-orgmode-et-jekyll/">billet précédent</a>, le header de mes fichiers <code>org</code> change un peu : - -<pre class="example"> -#+begin_html -+++ -title="Migration vers hugo" -date="2015-05-09" -categories=["developement"] -tags=["hugo","golang","blog","emacs","orgmode","html"] -lang="fr" -+++ -#+end_html - -Et voilà, une semaine après m'être remis en route sur ce blog, je fais déjà une migration =>_<=. Je me suis rendu compte que [[http://jekyllrb.com/][Jekyll]] m'énervait un peu, et comme je suis à fond dans [[http://golang.org/][go]] en ce moment, j'ai regardé du côté des générateurs de sites static et [[http://gohugo.io/][Hugo]] a clairement retenu mon attention. -</pre> -</li> - -<li>J'exécute <code>org-publish-current-project</code> (qu'il faut que je <i>bind</i> pour éviter de me le taper à la main..) -</li> -<li>Et je regarde le résultat dans mon navigateur (merci encore <a href="http://gohugo.io/extras/livereload/">LiveReload</a>). -</li> -</ol> - -<p> -Pour me simplifier la vie, il me resterais à démarrer et arrêter facilement <code>hugo server -w</code> dans le bon dossier directement depuis emacs (un peu à-la <code>compile</code>), <i>binder</i> <code>org-publish-current-project</code> et un petit script final qui copie le rendu de <code>blog</code> vers <code>vincent.demeester.fr</code> et qui commit (le tout appellable depuis Emacs <code>;-P</code>). -</p> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2015-06-01-docker-1.6-ecosystem/" title="Docker 1.6 et son écosystème">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2015-05-01-orgmode-et-jekyll/" title="Orgmode et Jekyll">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2015-06-01-docker-1.6-ecosystem/index.html b/www/vincent.demeester.fr/content/legacy/posts/2015-06-01-docker-1.6-ecosystem/index.html @@ -1,610 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2015-06-01-docker-1.6-ecosystem/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Docker 1.6 et son écosystème</h1><a href='https://vincent.demeester.fr/posts/2015-06-01-docker-1.6-ecosystem/'></a> - <address class="signature"> - <span class="date">Mon, 1 June, 2015</span> - <span class="words">(3100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#zenika">zenika</a></li> - - - - - - <li class="tag tag-docker"><a href="/tags/#docker">docker<span>3</span></a></li> - - - <li class="tag tag-compose"><a href="/tags/#compose">compose<span>1</span></a></li> - - - <li class="tag tag-swarm"><a href="/tags/#swarm">swarm<span>1</span></a></li> - - - <li class="tag tag-machine"><a href="/tags/#machine">machine<span>1</span></a></li> - - - <li class="tag tag-cluster"><a href="/tags/#cluster">cluster<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - -<div class="notice">Cet article est disponible sur le <a href="http://blog.zenika.com/">Blog de Zenika</a> à l'adresse suivante : <a href="http://blog.zenika.com/index.php?post/2015/06/01/Docker-1-6-et-son-ecosysteme">http://blog.zenika.com/index.php?post/2015/06/01/Docker-1-6-et-son-ecosysteme</a>. Cet publication me sert de mirroir / sauvegarde.</div> - -<div id="outline-container-sec-1" class="outline-2"> -<h2 id="sec-1">Introduction</h2> -<div class="outline-text-2" id="text-1"> -<p> -Le 28 octobre dernier, nous avions parlé de la sortie de Docker 1.3, des évolutions entre la version 1 et cette dernière et de son écosystème. Je vous proposes de remettre ça, bientôt 6 mois après, avec un peu le même plan : les principales nouveautés entre la version 1.3 et 1.6 (et il y en a <code>;-)</code>), l'évolution de l'écosystème qui gravite autour et un peu de <i>social</i> avec les meetups et évènements qui se sont passés depuis. -</p> - - -<div class="figure"> -<p><img src="./img/docker-16/docker_container_engine_logo.png" alt="docker_container_engine_logo.png" /> -</p> -</div> - -<p> -Rappel <i>ultra</i> rapide, <b>Docker est une plate-forme ouverte à destination des développeurs et administrateurs systèmes visant à faciliter la construction et le déploiement d'applications distribuées</b>. De manière moins marketing, l'idée derrière Docker est d'automatiser le déploiement d'environnements sous forme de conteneurs légers, portables et auto-suffisants ; les conteneurs permettant d'isoler l'exécution des applications dans des contextes d'exécution. Pour ce -faire, Docker, écrit en Go, reprend les bases de LXC, utilise les fonctionnalités du noyau Linux (CGroups, Namespaces, …) et se base initialement sur un système de fichier "en oignons" AUFS ; D'autres backends sont supportés également comme BTRFS ou devicemapper (LVM). -</p> -</div> -</div> - -<div id="outline-container-sec-2" class="outline-2"> -<h2 id="sec-2">Ovelay filesystem storage driver (1.4.0)</h2> -<div class="outline-text-2" id="text-2"> -<p> -La release 1.4.0 de Docker (et la 1.3.3 en parallèle) a surtout été une gigantesque <i>bugfix party</i>, histoire de rendre les fonctionnalités arrivées auparavant plus stable — la release note se trouve <a href="https://github.com/docker/docker/blob/master/CHANGELOG.md#140-2014-12-11">ici</a>. -</p> - -<p> -La principale nouveautée de cette version est l'apparation d'un nouveau <i>storage driver</i>, il s'agit d'<b>OverlayFs</b>. Il s'agit d'un mécanisme de montage permettant de superposer dans un répertoire le contenu de plusieurs autres répertoires. -</p> - -<p> -Initialement Docker est basé <b><a href="http://en.wikipedia.org/wiki/Aufs">Aufs</a></b> qui fait, pour simplifier, la même chose. Le problème avec aufs est qu'il n'est pas intégré dans le noyau Linux (i.e. dans les sources officielles), contrairement à OverlayFS qui a fait son apparition avec le noyau <a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=e9be9d5e76e34872f0c37d72e25bc27fe9e2c54c">3.18</a>. Il était donc nécessaire de disposer d'un noyau patché ; Le noyau Linux de Debian et de sess dérivés (Ubuntu, etc.) ont ce <i>patchset</i> aufs de base mais ce n'est pas le cas de toutes les distributions. L'idée de cette intégration est assez simple : supporter le maximum de distributions en se basant sur une <i>feature</i> du noyau. C'est donc bien évidemment le <i>driver</i> d'avenir pour Docker ; attention cependant, la peinture est encore un peu fraîche <code>;-P</code>. -</p> -</div> -</div> - -<div id="outline-container-sec-3" class="outline-2"> -<h2 id="sec-3">Support d'IPv6 (1.5.0)</h2> -<div class="outline-text-2" id="text-3"> -<p> -Les adresses IPv4 commencent a se faire <a href="http://en.wikipedia.org/wiki/IPv4_address_exhaustion">rare</a>, il est donc important que Docker supporte IPv6. C'est désormais le cas avec la version 1.5.0, même si ce n'est pas activé par défaut. Pour activer le support de l'IPv6 (en plus de l'IPv4), il faut ajouter le <i>flag</i> <code>--ipv6</code> au daemon. Docker va donc mettre en place le <i>bridge</i> <code>docker0</code> avec en plus un IPv6 en mode local, avec l'adresse <code>fe80::1</code>. -</p> - -<p> -Par défaut les containers qui seront créés n'auront qu'une adresse locale. Pour avoir une adresse IPv6 routable à votre conteneur, il est nécessaire de lui préciser un <i>sous-réseau</i> (subnet) dans lequel il va piocher son adresse. Cela se fait grâce à l'argument <code>--fixed-cidr-v6</code>. -</p> - - -<div class="org-src-container"> - -<pre class="src src-sh"><span style="color: #783778;">docker</span> <span style="color: #43783f;">-d</span> <span style="color: #374478;">--ipv6</span> <span style="color: #78683f;">--fixed-cidr-v6</span>=<span style="color: #008000;">"2001:db8:1::/64"</span> -</pre> -</div> - -<p> -Comme je ne suis pas un pro de l'IPv6, pour plus d'information, et si l'anglais ne vous fait pas peur, c'est dans la <a href="https://docs.docker.com/articles/networking/#ipv6">documentation "networking"</a> de Docker. -</p> -</div> -</div> - -<div id="outline-container-sec-4" class="outline-2"> -<h2 id="sec-4">Conteneurs en lecture seule (1.5.0)</h2> -<div class="outline-text-2" id="text-4"> -<p> -Une autre fonctionnalité assez sympathique qui est arrivé avec cette version 1.5.0 est les conteneurs en lecture seule — c'est Michael Crosby qui s'est occupé d'<a href="https://github.com/docker/docker/pull/10093">implémenter ça</a>. L'intérêt des conteneurs en lecture seule est de permettre de <b>contrôler où l'application</b> à l'intérieur de votre conteneur <b>peut écrire ou modifier des fichiers</b>. En combinant ceci avec les volumes, vous pouvez vous assurez des emplacements dans lesquels votre conteneur va persister des états ou données (le/les volumes), puisqu'il ne sera pas possible d'écrire ailleurs de toute façon. -</p> - -<p> -Pour activer cette fonctionnalité, c'est l'argument <code>--read-only</code>. -</p> - -<div class="org-src-container"> - -<pre class="src src-sh"><span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #43783f;">--read-only</span> <span style="color: #5e7837;">-v</span> <span style="color: #5e7837;">/volume/writable</span> <span style="color: #3f7178;">busybox</span> <span style="color: #783778;">touch</span> <span style="color: #5e7837;">/volume/writable</span> -</pre> -</div> - -<p> -Une autre utilisation des conteneurs en lecture seule est que cela donne la possibilité de faire du debug <i>post-mortem</i> d'un conteneur (en production par exemple). Cela nous permet de redémarrer un conteneur qui aurait planté, en lecture seule avec le système de fichier dans l'état du crash. -</p> -</div> -</div> - -<div id="outline-container-sec-5" class="outline-2"> -<h2 id="sec-5">Les labels pour le « daemon », les images et les conteneurs (1.6.0)</h2> -<div class="outline-text-2" id="text-5"> -<blockquote> -<p> -One Meta Data to Rule Them All -</p> -</blockquote> - -<p> -Une des deux fonctionnalités très attendue de la récente version 1.6.0 sont les labels. En un mot, et pour le faire « à-la » <i>le seigneur des anneaux</i>, les labels peuvent se résumer en "<b>Une metadata pour les gouverner tous</b>" (ça le fait vachement mieux en anglais en fait). -</p> - -<p> -Les labels s'appliquent sur le <i>daemon</i>, les images et les conteneurs. C'est un peu un mélange entre des tags et des variables d'environnements puisque il s'agit d'un couple <b>clé/valeur</b>. -</p> - -<p> -L'ajout de label sur le <i>daemon</i> se fait grâce à l'argument — roulement de tambour — <code>--label</code> (<code>\o/</code>). La principale utilité pour l'instant est son utilisation conjointe avec Swarm dont nous parlerons un peu plus bas ; mais en deux mots, cela permet de filtrer les <i>engines</i> sur lesquels on va <i>taper</i>. -</p> - -<div class="org-src-container"> - -<pre class="src src-sh"><span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Souvent, c'est dans DOCKER_OPTS du fichier /etc/default/docker</span> -<span style="color: #783778;">docker</span> <span style="color: #43783f;">-d</span> <span style="color: #784437;">-H</span> <span style="color: #4f5c7e;">unix://var/run/docker.sock</span> <span style="color: #7a4f7e;">--label</span> <span style="color: #BA36A5;">storage</span>=<span style="color: #5e7837;">ssd</span> <span style="color: #7a4f7e;">--label</span> <span style="color: #BA36A5;">type</span>=<span style="color: #5e7837;">laptop</span> -</pre> -</div> - -<p> -L'ajout d'un label sur une image se fait dans le fichier <code>Dockerfile</code>, et l'ajout d'un label sur un conteneur, grâce à l'argument <code>--label</code> pour rester cohérent. Construisons une image inutile mais en lui appliquant un label : -</p> - -<div class="org-src-container"> - -<pre class="src src-sh"><span style="color: #37785e;">FROM</span> <span style="color: #3f7178;">busybox</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Support du multi-line pour LABEL</span> -<span style="color: #783778;">LABEL</span> <span style="color: #BA36A5;">vendor</span>=<span style="color: #78683f;">zenika</span> <span style="color: #008000;">\</span> - <span style="color: #784437;">com.zenika.lang</span>=<span style="color: #374478;">golang</span> <span style="color: #008000;">\</span> - <span style="color: #78683f;">com.zenika.version</span>=<span style="color: #43783f;">0.1</span> -<span style="color: #7a4f7e;">CMD</span> [<span style="color: #008000;">"echo"</span><span style="color: #7e544f;">,</span> <span style="color: #008000;">"zenika"</span>] -</pre> -</div> - -<p> -Nous allons maintenant construire cette image et lancer un conteneur à partir de cette dernière avec un autre label. -</p> - -<div class="org-src-container"> - -<pre class="src src-sh">$ <span style="color: #783778;">docker</span> <span style="color: #7e544f;">build</span> <span style="color: #7a4f7e;">-t</span> <span style="color: #4f7e67;">zenikaapp</span> <span style="color: #374478;">.</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…]</span> -$ <span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #4f5c7e;">--name</span> <span style="color: #783f5a;">test</span> <span style="color: #7a4f7e;">--label</span> <span style="color: #783f5a;">com.zenika.foo</span>=<span style="color: #784437;">bar</span> <span style="color: #4f7e67;">zenikaapp</span> -<span style="color: #78683f;">zenika</span> -</pre> -</div> - -<p> -L'idée c'est que maintenant, lorsque l'on va regarder la liste d'images ou de conteneurs à disposition sur notre <i>engine</i>, nous allons pouvoir <b>filtrer</b> par label, comme suit : -</p> - -<div class="org-src-container"> - -<pre class="src src-sh">$ <span style="color: #783778;">docker</span> <span style="color: #707e4f;">images</span> <span style="color: #4f5c7e;">--filter</span> <span style="color: #008000;">"label=vendor=zenika"</span> <span style="color: #4f5c7e;">--filter</span> <span style="color: #008000;">"label=com.zenika.lang=golang"</span> -<span style="color: #784437;">REPOSITORY</span> <span style="color: #3f7178;">TAG</span> <span style="color: #707e4f;">IMAGE</span> <span style="color: #707e4f;">ID</span> <span style="color: #7e544f;">CREATED</span> <span style="color: #784437;">VIRTUAL</span> <span style="color: #4f7e67;">SIZE</span> -<span style="color: #4f7e67;">zenikaapp</span> <span style="color: #7a4f7e;">latest</span> <span style="color: #784437;">66ffda023118</span> <span style="color: #5e7837;">43</span> <span style="color: #7e544f;">seconds</span> <span style="color: #43783f;">ago</span> <span style="color: #783778;">2.433</span> <span style="color: #7e544f;">MB</span> -$ <span style="color: #783778;">docker</span> <span style="color: #43783f;">ps</span> <span style="color: #784437;">-a</span> <span style="color: #4f5c7e;">--filter</span> <span style="color: #008000;">"label=com.zenika.foo=bar"</span> -<span style="color: #374478;">CONTAINER</span> <span style="color: #707e4f;">ID</span> <span style="color: #707e4f;">IMAGE</span> <span style="color: #78683f;">COMMAND</span> <span style="color: #7e544f;">CREATED</span> [<span style="color: #374478;">…</span>] <span style="color: #707e4f;">NAMES</span> -<span style="color: #513f78;">37e9a37caf57</span> <span style="color: #513f78;">zenikaapp:latest</span> <span style="color: #008000;">"echo zenika"</span> <span style="color: #43783f;">About</span> <span style="color: #78683f;">a</span> <span style="color: #37785e;">minute</span> <span style="color: #43783f;">ago</span> [<span style="color: #374478;">…</span>] <span style="color: #783f5a;">test</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">On peut également regarder les labels avec inspect</span> -$ <span style="color: #783778;">docker</span> <span style="color: #374478;">inspect</span> <span style="color: #3f7178;">-f</span> <span style="color: #008000;">"{{json .ContainerConfig.Labels }}"</span> <span style="color: #783f5a;">zenikaap</span> -{<span style="color: #008000;">"com.zenika.lang"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"golang"</span><span style="color: #7e544f;">,</span><span style="color: #008000;">"com.zenika.version"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"0.1"</span><span style="color: #7e544f;">,</span><span style="color: #008000;">"vendor"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"zenika"</span>} -$ <span style="color: #783778;">docker</span> <span style="color: #374478;">inspect</span> <span style="color: #3f7178;">-f</span> <span style="color: #008000;">"{{json .Config.Labels }}"</span> <span style="color: #783f5a;">test</span> -{<span style="color: #008000;">"com.zenika.foo"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"bar"</span><span style="color: #7e544f;">,</span><span style="color: #008000;">"com.zenika.lang"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"golang"</span><span style="color: #7e544f;">,</span><span style="color: #008000;">"com.zenika.version"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"0.1"</span><span style="color: #7e544f;">,</span><span style="color: #008000;">"vendor"</span><span style="color: #707e4f;">:</span><span style="color: #008000;">"zenika"</span>} -</pre> -</div> - -<p> -On peut imaginer beaucoup d'usage de ces labels. Par example, avec <a href="http://rancher.com">Rancher</a>, ils sont utilisés pour faciliter la configuration du load-balancer (<a href="http://rancher.com/docker-labels/">ici</a>) — ils utilisent un label <code>io.rancher.service.provides</code> qui permettra à ce dernier de trouver automatiquement ces petits. Je vous laisse imaginer vos propres <i>use-cases</i>. -</p> - -<p> -Il y a une partie de la documentation qui parle exclusivement des labels, avec une petite partie sur les <i>best-practice</i> de nommage des labels, c'est <a href="https://docs.docker.com/userguide/labels-custom-metadata/">ici</a>. -</p> -</div> -</div> - -<div id="outline-container-sec-6" class="outline-2"> -<h2 id="sec-6">Logging drivers \o/ (1.6.0)</h2> -<div class="outline-text-2" id="text-6"> -<p> -Un <i>gros reproche</i> qui était fait à Docker était sa gestion très <b>simpliste</b> des logs des conteneurs. Plusieurs critiques étaient faites : -</p> - -<ol class="org-ol"> -<li>Tout faire sortir sur <code>stdout</code> et <code>stderr</code> n'est pas vraiment une habitude de nos jours, surtout dans des langages comme Java où l'utilisation de <i>logger</i> (Log4j, Slf4j, …) est très répandue. Cela rend le portage vers docker de certaines applications un peu plus fastidieux. -</li> -<li>Il n'y avait aucun mécanisme de <i>rotation</i> de logs — et comme en plus le dossier dans lequel les logs étaient écris est un peu enfoui dans <code>/var/lib/docker</code>, cela pouvait poser quelques problème si des conteneurs étaient un peu trop bavards.. -</li> -<li>La solution utilisée pour sauvegarder ces logs et pourquoi pas les centraliser (avec ELK par exemple), était d'utiliser un volume, souvent partagé entre applications, et de démarrer un conteneur pour gérer cette analyse, centralisation, …. Non seulement ce n'est pas très optimal, mais cela nécessitait de configurer chaque application (donc chaque conteneur) — et <code>docker logs</code> perdait tout son intérêt. -</li> -</ol> - -<p> -Avec la version 1.6.0, les <i>logging driver</i> permettent une gestion des logs un peu plus optimale, ou au moins plus flexible. Il est donc maintenant possible de préciser le <i>logging driver</i> à utiliser. Ils en existent 3 pour l'instant : -</p> - -<ol class="org-ol"> -<li><code>json-file</code> correspond au comportement par défaut de Docker avant la 1.6 et reste la valeur par défaut -</li> -<li><code>syslog</code> qui permet de connecter les logs de nos conteneurs dans notre vénérable syslog (ou en tout cas quelqu'un qui parl le syslog). -</li> -<li><code>none</code> qui est le magicien puisqu'il nous permet de faire taire complètement un conteneur <code>o/</code>. -</li> -</ol> - -<p> -Il est possible de définir le logging driver à deux endroits : -</p> - -<ol class="org-ol"> -<li>sur le <b>daemon</b> pour la valeur par défaut de tous les conteneurs. -</li> -</ol> - -<div class="org-src-container"> - -<pre class="src src-sh">$ <span style="color: #783778;">docker</span> <span style="color: #43783f;">-d</span> <span style="color: #5e7837;">--log-driver</span>=<span style="color: #008000;">"json-file"</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Pour faire taire les conteneurs par défaut</span> -$ <span style="color: #783778;">docker</span> <span style="color: #43783f;">-d</span> <span style="color: #5e7837;">--log-driver</span>=<span style="color: #008000;">"none"</span> -</pre> -</div> - -<ol class="org-ol"> -<li>en option de la command <b>run</b> (ou de la commande <b>create</b>). -</li> -</ol> - -<div class="org-src-container"> - -<pre class="src src-sh">$ <span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #5e7837;">--log-driver</span>=<span style="color: #3f7178;">syslog</span> <span style="color: #3f7178;">ubuntu</span> <span style="color: #008000;">\</span> - <span style="color: #37785e;">/bin/bash</span> <span style="color: #784437;">-c</span> <span style="color: #008000;">'while true; do echo "Hello"; sleep1; done'</span> -$ <span style="color: #707e4f;">tail</span> <span style="color: #3f7178;">-f</span> <span style="color: #784437;">/var/log/syslog</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…]</span> -<span style="color: #374478;">May</span> <span style="color: #3f7178;">28</span> <span style="color: #3f7178;">17:39:01</span> <span style="color: #7e544f;">dev1</span> <span style="color: #783778;">docker</span>[<span style="color: #5e7837;">116314</span>]<span style="color: #707e4f;">:</span> <span style="color: #513f78;">0e5b67244c00:</span> <span style="color: #4f7e67;">Hello</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…]</span> -</pre> -</div> - -<p> -Une option <code>--log-opts</code> est également présente pour passer des options additionnelles au driver si celui-ci les supporte. Notons également qu'un driver pour <code>systemd</code> devrait arriver avec la version 1.7. -</p> - -<p> -La pull-request ayant permis d'intégrer cette fonctionnalité se trouve <a href="https://github.com/docker/docker/pull/10568">ici</a>. -</p> -</div> -</div> - -<div id="outline-container-sec-7" class="outline-2"> -<h2 id="sec-7">Client Windows natif (1.6.0)</h2> -<div class="outline-text-2" id="text-7"> -<p> -Enfin, on s'en doutait un peu après l'annonce du partenariat entre Docker Microsoft, ça bosse beaucoup pour porter Docker vers Windows. La première étape était de fournir un client natif pour Windows. C'est chose faite avec cette version 1.6. Maintenant beaucoup de travail est effectué pour rendre le <i>engine</i> plus portable, il n'y a qu'à suivre un peu les pull-request avec un tag <code>os/windows</code> ou encore cette très récente pull-request avec un titre plutôt évocateur : « <a href="https://github.com/docker/docker/pull/13554">Windows: The real Windows exec driver is here</a> ». -</p> -</div> -</div> - -<div id="outline-container-sec-8" class="outline-2"> -<h2 id="sec-8">Divers</h2> -<div class="outline-text-2" id="text-8"> -<p> -Il y a pas mal d'autres options qui sont arrivées depuis la version 1.3.0, nous allons en parcourir certaines rapidement — parce que sinon cet article va faire 100 pages ;-p : -</p> - -<ul class="org-ul"> -<li><b>Stats</b> (1.5.0) : une commande <code>stats</code> (et donc une API derrière) permet de récupérer quelques statistiques par conteneur, c'est simple pour l'instant. -</li> -<li>Depuis la version 1.5.0 il est possible de spécifier le ficher Dockerfile grâce à l'option <code>-f</code> de la commande build — jusqu'à maintenant docker regardait uniquement le dossier spécifié et cherchait le fichier <code>Dockerfile</code>. Cela permet donc, par exemple, d'avoir plusieurs <code>Dockerfile</code> dans un dossier. -</li> -</ul> - -<div class="org-src-container"> - -<pre class="src src-sh">$ <span style="color: #783778;">docker</span> <span style="color: #7e544f;">build</span> <span style="color: #7a4f7e;">-t</span> <span style="color: #5e7837;">monimage</span> <span style="color: #3f7178;">-f</span> <span style="color: #43783f;">backend.Dockerfile</span> <span style="color: #374478;">.</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…] Build the backend</span> -$ <span style="color: #783778;">docker</span> <span style="color: #7e544f;">build</span> <span style="color: #7a4f7e;">-t</span> <span style="color: #5e7837;">monimage</span> <span style="color: #3f7178;">-f</span> <span style="color: #4f7e67;">frontend.Dockerfile</span> <span style="color: #374478;">.</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…] Build the frontend</span> -</pre> -</div> - -<ul class="org-ul"> -<li>Le <i>registry</i> voit son API passer en V2, principalement pour améliorer les transferts. L'implémentation officielle a été réécrite en Go (à la place de Python) et se nomme maintenant <a href="https://github.com/docker/distribution">distribution</a>. -</li> -<li>La commande <code>commit est dotée, depuis la version 1.6.0, d'une option =--change</code> qui permet d'appliquer une instruction supportée par les <code>Dockerfile</code> — voir <a href="https://docs.docker.com/reference/commandline/cli/#commit">ici</a>. -</li> -<li>Docker a publié un petit document « <a href="https://github.com/docker/docker/blob/master/image/spec/v1.md">Docker Image Specification</a> » qui a pour but de définir le format des images utilisées par Docker, permettant à d'autres notamment des potentiels conccurents, d'implémenter des images qui seraient compatible. -</li> -</ul> -</div> -</div> - -<div id="outline-container-sec-9" class="outline-2"> -<h2 id="sec-9">À venir</h2> -<div class="outline-text-2" id="text-9"> -<p> -L'une des principales nouveautés qui devrait arriver avec la version 1.7 de Docker, c'est l'intégration d'une <b>nouvelle stack réseau</b> avec l'intégration du projet <a href="https://github.com/docker/libnetwork">libnetwork</a>, si tout se passe bien. On pourra noter également de nouveaux <i>logging driver</i>, avec notamment un <code>rollover</code> driver ou encore le <code>systemd</code> driver. On peut noter également l'arrivée d'un <i>filesystem driver</i> pour ZFS (voici la <a href="https://github.com/docker/docker/pull/9411">pull-request</a>). Le Docker Birthday étant passé par là, beaucoup de corrections de bugs, de nouvelles petites fonctionnalités, une meilleure couverture de code par les tests unitaires (<code>o/</code>). -</p> - -<p> -La RC1 est disponible depuis le 28 mai, <a href="https://github.com/docker/docker/releases/tag/v1.7.0-rc1">ici</a> et la <a href="https://github.com/docker/docker/pull/13528">pull-request</a> associée, donc à vos tests ! -</p> -</div> -</div> - -<div id="outline-container-sec-10" class="outline-2"> -<h2 id="sec-10">Écosystème</h2> -<div class="outline-text-2" id="text-10"> -<p> -Trois projets « Docker » sont apparus depuis le dernier article : Compose, Swarm et Machine. Présentons les très rapidement. -</p> -</div> - -<div id="outline-container-sec-10-1" class="outline-3"> -<h3 id="sec-10-1">Compose</h3> -<div class="outline-text-3" id="text-10-1"> -<p> -Compose est le nouveau nom de Fig. Fig était développé par Orchard qui a été racheté par Docker. Pour rappel, l'idée est de définir son environnement via un fichier YAML, que ce soit pour le code sur lequel nous travaillons mais également les services externes desquels notre application dépend (Base de données, ''Message queue'', etc.). -</p> - -<div class="org-src-container"> - -<pre class="src src-yaml"><span style="color: #BA36A5;">web</span>: - <span style="color: #BA36A5;">build</span>: . - <span style="color: #BA36A5;">command</span>: lein run - <span style="color: #BA36A5;">links</span>: - - db - <span style="color: #BA36A5;">ports</span>: - - <span style="color: #008000;">"8000:8000"</span> -<span style="color: #BA36A5;">db</span>: - <span style="color: #BA36A5;">image</span>: postgres -</pre> -</div> - -<p> -Compose est en version 1.2 — depuis la version 1.0, la majorité des modifications sont des corrections de bugs et des ajouts pour suivre les modifications et nouvelles fonctionnalités de Docker (<code>env-file</code>, <code>dns_search</code>, <code>add_host</code>, <code>restart</code>, <code>volumes_from</code>, <code>net</code>, …). La commande est maintenant <code>docker-compose</code> à la place de <code>fig</code> et le fichier <code>docker-compose.yml</code> à la place de <code>fig.yml</code> — pour des raisons de rétro-compatibilité, Compose continue de lire les <code>fig.yml</code>. -</p> -</div> -</div> - -<div id="outline-container-sec-10-2" class="outline-3"> -<h3 id="sec-10-2">Swarm & Machine</h3> -<div class="outline-text-3" id="text-10-2"> -<p> -Deux nouveaux projets ont fait leur apparition dans l'escarcelle de Docker Inc. : Swarm et Machine. Swarm est le <i>clustering</i> à moyenne échelle vu par Docker. Machine permet de provisionner Docker sur différents providers : amazon aws, google compute engine, azure, Virtualbox pour ne citer qu'eux — mais beaucoup d'autres sont déjà supportés. -</p> - -<p> -Voilà ce que Jérôme Petazzoni dit à propos de Swarm : -</p> - -<blockquote> -<p> -Un système de cluster utilisant l’API Docker et compatible avec tous les outils de l’écosystème maison. On peut utiliser les commandes classiques Docker pour piloter le cluster -</p> -</blockquote> - -<p> -L'idée principale de Swarm est <b>Je veux parler à mon cluster Docker de la même façon que je parle avec mon daemon Docker</b>. Cela se traduit assez simplement par : <b>Swarm expose la même API que docker</b>. C'est une idée simple et terriblement puissante puisque cela veut dire que je peux administrer mon cluster avec les mêmes commandes que j'utilise quand je travaille en local. Swarm a pour but de piloter des clusters d'une taille relativement petite (moins de 1000 machines). Pour les clusters de plus grande taille, il existe de très bonnes solutions, comme <a href="http://mesos.apache.org/">Mesos</a>, et ce n'est pas le but de Docker Inc. de venir les concurrencer, bien au contraire. -</p> - -<p> -Pour faire simple, swarm c'est un <b>manager</b> et des <b>agents</b> (un par engine) — les agents s'enregistrent auprès du master par le biais d'un <i>service discovery</i>. Swarm dispose d'un petit service de discovery mais qui n'est là que pour <i>la démo</i> ; il est possible et conseillé de le connecter à des solutions existantes, pour l'instant <a href="https://github.com/hashicorp/consul">consul</a> et <a href="https://github.com/coreos/etcd">etcd</a>. -</p> - -<p> -Un bout de code vaut mieux qu'un long discours, voici comment <i>bootstraper</i> un cluster Swarm, avec l'aide de Machine pour être <i>funky</i>. -</p> - -<div class="org-src-container"> - -<pre class="src src-sh"><span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">On crée un cluster simple avec son id</span> -$ <span style="color: #7a4f7e;">swarm</span> <span style="color: #783f5a;">create</span> -<span style="color: #3f7178;">50862dcedd53c2f584adfb00e85bac4b</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">On démarre des agents</span> -$ <span style="color: #43783f;">docker-machine</span> <span style="color: #783f5a;">create</span> <span style="color: #43783f;">-d</span> <span style="color: #374478;">azure</span> <span style="color: #4f5c7e;">--swarm</span> <span style="color: #4f5c7e;">--swarm-discovery</span> <span style="color: #4f7e67;">token://50862dcedd53c2f584adfb00e85bac4b</span> <span style="color: #43783f;">node1</span> -<span style="color: #3f7178;">INFO</span>[<span style="color: #7a4f7e;">0000</span>] <span style="color: #5e7837;">Creating</span> <span style="color: #513f78;">SSH</span> <span style="color: #5e7837;">key...</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…]</span> -$ <span style="color: #43783f;">docker-machine</span> <span style="color: #783f5a;">create</span> <span style="color: #43783f;">-d</span> <span style="color: #7e544f;">digitalocean</span> <span style="color: #4f5c7e;">--swarm</span> <span style="color: #4f5c7e;">--swarm-discovery</span> <span style="color: #4f7e67;">token://50862dcedd53c2f584adfb00e85bac4b</span> <span style="color: #783f5a;">node2</span> -<span style="color: #3f7178;">INFO</span>[<span style="color: #7a4f7e;">0000</span>] <span style="color: #5e7837;">Creating</span> <span style="color: #513f78;">SSH</span> <span style="color: #5e7837;">key...</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">[…]</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">On démarre le master</span> -$ <span style="color: #43783f;">docker-machine</span> <span style="color: #783f5a;">create</span> <span style="color: #43783f;">-d</span> <span style="color: #78683f;">virtualbox</span> <span style="color: #4f5c7e;">--swarm</span> <span style="color: #707e4f;">--swarm-master</span> <span style="color: #4f5c7e;">--swarm-discovery</span> <span style="color: #4f7e67;">token://50862dcedd53c2f584adfb00e85bac4b</span> <span style="color: #374478;">manager</span> -</pre> -</div> - -<p> -Maintenant que l'on dispose d'un petit cluster, en pointant dessus (merci Machine) on va pouvoir lancer des commandes docker. -</p> - -<div class="org-src-container"> - -<pre class="src src-sh">$ $(<span style="color: #43783f;">docker-machine</span> <span style="color: #7a4f7e;">env</span> <span style="color: #4f5c7e;">--swarm</span> <span style="color: #374478;">manager</span>) -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Le bon vieux info</span> -$ <span style="color: #783778;">docker</span> <span style="color: #784437;">info</span> -<span style="color: #3f7178;">Containers:</span> <span style="color: #4f5c7e;">4</span> -<span style="color: #4f5c7e;">Nodes:</span> <span style="color: #7e544f;">3</span> - <span style="color: #374478;">manager:</span> <span style="color: #7e544f;">192.168.99.103:2376</span> - <span style="color: #78683f;">└</span> <span style="color: #3f7178;">Containers:</span> <span style="color: #513f78;">2</span> - <span style="color: #78683f;">└</span> <span style="color: #4f7e67;">Reserved</span> <span style="color: #4f5c7e;">CPUs:</span> <span style="color: #784437;">0</span> <span style="color: #783778;">/</span> <span style="color: #4f5c7e;">4</span> - <span style="color: #78683f;">└</span> <span style="color: #4f7e67;">Reserved</span> <span style="color: #7a4f7e;">Memory:</span> <span style="color: #784437;">0</span> <span style="color: #4f7e67;">B</span> <span style="color: #783778;">/</span> <span style="color: #707e4f;">999.9</span> <span style="color: #783f5a;">MiB</span> - <span style="color: #78683f;">node1:</span> <span style="color: #513f78;">45.55.160.223:2376</span> - <span style="color: #78683f;">└</span> <span style="color: #3f7178;">Containers:</span> <span style="color: #78683f;">1</span> - <span style="color: #78683f;">└</span> <span style="color: #4f7e67;">Reserved</span> <span style="color: #4f5c7e;">CPUs:</span> <span style="color: #784437;">0</span> <span style="color: #783778;">/</span> <span style="color: #78683f;">1</span> - <span style="color: #78683f;">└</span> <span style="color: #4f7e67;">Reserved</span> <span style="color: #7a4f7e;">Memory:</span> <span style="color: #784437;">0</span> <span style="color: #4f7e67;">B</span> <span style="color: #783778;">/</span> <span style="color: #4f7e67;">490</span> <span style="color: #783f5a;">MiB</span> - <span style="color: #513f78;">node2:</span> <span style="color: #707e4f;">swarm-nwde2.cloudapp.net:2376</span> - <span style="color: #78683f;">└</span> <span style="color: #3f7178;">Containers:</span> <span style="color: #78683f;">1</span> - <span style="color: #78683f;">└</span> <span style="color: #4f7e67;">Reserved</span> <span style="color: #4f5c7e;">CPUs:</span> <span style="color: #784437;">0</span> <span style="color: #783778;">/</span> <span style="color: #78683f;">1</span> - <span style="color: #78683f;">└</span> <span style="color: #4f7e67;">Reserved</span> <span style="color: #7a4f7e;">Memory:</span> <span style="color: #784437;">0</span> <span style="color: #4f7e67;">B</span> <span style="color: #783778;">/</span> <span style="color: #7e544f;">1.639</span> <span style="color: #3f7178;">GiB</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">On démarre des nginx</span> -$ <span style="color: #4f7e67;">for</span> <span style="color: #7a4f7e;">i</span><span style="color: #0000FF;"> in</span> <span style="color: #FF1493;">`seq 1 3`</span>; <span style="color: #0000FF;">do</span> <span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #43783f;">-d</span> <span style="color: #783f5a;">-p</span> <span style="color: #7a4f7e;">80:80</span> <span style="color: #783778;">nginx</span>; <span style="color: #0000FF;">done</span> -$ <span style="color: #783778;">docker</span> <span style="color: #43783f;">ps</span> -<span style="color: #374478;">CONTAINER</span> <span style="color: #707e4f;">ID</span> <span style="color: #707e4f;">IMAGE</span> <span style="color: #78683f;">COMMAND</span> <span style="color: #78683f;">...</span> <span style="color: #3f7178;">PORTS</span> <span style="color: #707e4f;">NAMES</span> -<span style="color: #374478;">9bff07d8ee18</span> <span style="color: #78683f;">nginx:1.7</span> <span style="color: #008000;">"nginx -g 'daemon of ... 443/tcp, 104.210.33.180:80->80/tcp node1/loving_torvalds</span> -<span style="color: #008000;">457ed59c9bb3 nginx:1.7 "</span><span style="color: #783778;">nginx</span> <span style="color: #78683f;">-g</span> <span style="color: #008000;">'daemon of ... 443/tcp, 45.55.160.223:80->80/tcp node2/drunk_swartz</span> -<span style="color: #008000;">6013be18cdbc nginx:1.7 "nginx -g '</span><span style="color: #3f7178;">daemon</span> <span style="color: #5e7837;">of</span> <span style="color: #78683f;">...</span> <span style="color: #784437;">443/tcp,</span> <span style="color: #4f7e67;">192.168.99.103:80-</span>><span style="color: #5e7837;">80/tcp</span> <span style="color: #707e4f;">manager/condescending_galileo</span> -</pre> -</div> - -<p> -On voit qu'on a démarré nginx sur les 3 nœuds. Swarm a quelques stratégies pour démarrer un conteneur sur un nœud ou l'autre : -</p> - -<ul class="org-ul"> -<li><code>spread</code> va éparpiller les conteneurs pour que chaque nœud en ait le moins possible (répartis). -</li> -<li><code>binpack</code> va faire l'inverse (tout sur le même nœud jusqu'à ce que ses ressources soient épuisés). -</li> -<li><code>random</code> qui fait <i>au pif</i>. -</li> -</ul> - -<p> -Il est également possible de mettre des contraintes lors du lancement d'un conteneur, en utilisant le flag <code>-e</code> de <code>docker run</code> (<code>-e</code> = variables d'environnement). -</p> - - -<div class="org-src-container"> - -<pre class="src src-sh"><span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Démarrer postgres sur un host qui a le label storage=ssd</span> -$ <span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #43783f;">-d</span> <span style="color: #707e4f;">-e</span> <span style="color: #4f5c7e;">constraint:</span><span style="color: #4f5c7e;">storage</span>==<span style="color: #5e7837;">ssd</span> <span style="color: #4f5c7e;">--name</span> <span style="color: #4f7e67;">postgres</span> <span style="color: #4f7e67;">postgres</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Démarrer redis à coté du conteneur dont le nom est postgres</span> -$ <span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #43783f;">-d</span> <span style="color: #707e4f;">-e</span> <span style="color: #4f5c7e;">affinity:</span><span style="color: #4f5c7e;">container</span>==<span style="color: #4f7e67;">postgres</span> <span style="color: #4f5c7e;">--name</span> <span style="color: #7e544f;">redis</span> <span style="color: #7e544f;">redis</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">Démarer backend où tu veux, mais comme les links sont des contraintes</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">implicites il démarrera sur le même host que postgres ET redis</span> -<span style="color: #8D8D84;"># </span><span style="color: #8D8D84; font-style: italic;">(ou ne démarrera pas ces derniers ne sont pas au même endroit)</span> -$ <span style="color: #783778;">docker</span> <span style="color: #513f78;">run</span> <span style="color: #43783f;">-d</span> <span style="color: #374478;">--link</span> <span style="color: #3f7178;">redis:redis</span> <span style="color: #374478;">--link</span> <span style="color: #784437;">postgres:db</span> <span style="color: #4f5c7e;">--name</span> <span style="color: #78683f;">backend</span> <span style="color: #78683f;">backend</span> -</pre> -</div> - -<p> -On pourrait faire un article dédié à Swarm (ce qui sera probablement le cas dans un avenir assez proche) donc je vous laisse le découvrir via <a href="https://github.com/docker/swarm/">github</a>. -</p> -</div> -</div> -</div> - -<div id="outline-container-sec-11" class="outline-2"> -<h2 id="sec-11">Levées de fonds et acquisitons</h2> -<div class="outline-text-2" id="text-11"> -<p> -Docker est sur toutes les lèvres en ce moment. Il est donc normal que cela attire également des capitaux. Le 14 avril dernier, Docker annonçait une nouvelle levée de fonds de <b>95 millions</b> de dollars. Après celle de <i>40 millions</i> en Septembre 2014, on peut se dire que Docker Inc. a de beaux jours à venir. -</p> - -<p> -Docker Inc. « mange » aussi quelques startups, puisque après Orchard, qui éditait fig (devenu docker-compose), ils ont fait l'acquisition de <a href="http://socketplane.io/">Socketplane</a> et <a href="https://kitematic.com/">Kitematic</a>. Kitematic est un outil <i>desktop</i> qui permet de facilement utiliser Docker sous Mac OS X, une belle application, un peu « clickodrome » <code>;-P</code>. <a href="http://socketplane.io/">Socketplane</a> est une solution réseau qui connectait Open vSwitch avec Docker — nulle doute que la récente libnetwork vient de là. -</p> -</div> -</div> - -<div id="outline-container-sec-12" class="outline-2"> -<h2 id="sec-12">Évènements</h2> -<div class="outline-text-2" id="text-12"> -<p> -Nous allons finir avec une liste non-exhaustive et un peu orientée des évènements <i>marquants</i> qui se sont passés ces derniers mois : -</p> - -<ul class="org-ul"> -<li>Le <a href="https://blog.docker.com/2014/11/docker-tour-de-france/">Docker Tour de France</a>, avec notament un <a href="http://www.meetup.com/Docker-Paris/events/218767688/">hackathon</a> organisé à l'<a href="http://www.epitech.eu/paris/ecole-informatique-paris.aspx">Epitech</a>, où notre <a href="https://twitter.com/mariolet">Mario Loriedo</a> national a bootstrapé son projet Sublime-docker avec <a href="https://github.com/mjbright">Mike Bright</a> et à du coup gagné sa place à la DockerCon de 2015. -</li> -<li>Les <a href="http://blog.zenika.com/index.php?post/2015/02/19/NightClazz-Docker-Avance">Nightclazz</a> <a href="http://zenika.github.io/NC-Docker-Decouverte/">découverte</a> et <a href="http://zenika.github.io/NC-Docker-Avance/#/">avancée</a> hébergé par Zenika, présenté par Mario Loriedo et moi-même ;-). -</li> -<li>La DockerCon Europe. -</li> -<li>Le <a href="http://docker.party/">Docker Birthday</a>, gigantesque <i>Open-source-athon</i> tout autour du monde — une véritable réussite, tant au niveau de l'organisation (des évènements, la préparation en amont des <i>issues</i>, etc.) que de ce qu'il en est <a href="https://blog.docker.com/2015/05/dockers-2nd-birthday-by-the-numbers/">ressorti</a>. -</li> -</ul> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2015-07-31-config-managment-intro/" title="Gestion de configuration : introduction">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2015-05-09-migration-to-hugo/" title="Migration vers hugo">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2015-07-31-config-managment-intro/index.html b/www/vincent.demeester.fr/content/legacy/posts/2015-07-31-config-managment-intro/index.html @@ -1,387 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2015-07-31-config-managment-intro/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Gestion de configuration : introduction</h1><a href='https://vincent.demeester.fr/posts/2015-07-31-config-managment-intro/'></a> - <address class="signature"> - <span class="date">Fri, 31 July, 2015</span> - <span class="words">(1300 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#configurations">configurations</a></li> - - - - - - <li class="tag tag-git"><a href="/tags/#git">git<span>3</span></a></li> - - - <li class="tag tag-myrepos"><a href="/tags/#myrepos">myrepos<span>1</span></a></li> - - - <li class="tag tag-mr"><a href="/tags/#mr">mr<span>1</span></a></li> - - - <li class="tag tag-vcsh"><a href="/tags/#vcsh">vcsh<span>1</span></a></li> - - - <li class="tag tag-linux"><a href="/tags/#linux">linux<span>4</span></a></li> - - - <li class="tag tag-posix"><a href="/tags/#posix">posix<span>1</span></a></li> - - - <li class="tag tag-shell"><a href="/tags/#shell">shell<span>2</span></a></li> - - - <li class="tag tag-sharing"><a href="/tags/#sharing">sharing<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - <p> -Cela doit faire au moins 2 ans que je souhaite partager la façon dont -je gère mes configurations (en anglais <i>dotfiles</i>). Comme j'ai -longtemps repoussé l'échéance, probablement de peur d'avoir un roman à -écrire, je vais en faire une série de petits billets de blog dont -celui-ci est l'introduction. Nous y aborderons donc mon besoin, et mes -choix. -</p> - -<div id="outline-container-sec-1" class="outline-2"> -<h2 id="sec-1">Besoin(s)</h2> -<div class="outline-text-2" id="text-1"> -<p> -En bon <b>geek</b> que je suis, je suis fan des <i>dotfiles</i>. Les <i>dotfiles</i> -— fichiers de configurations — sont de petits fichiers, habituellement -dans notre dossier personnel (votre <i>$HOME</i>), qui nous permettent de -paramétrer et personnaliser nos outils de tous les jours. C'est -principalement vrai pour des outils en ligne de commande — et ça tombe -bien, j'adore — mais pas uniquement limité à ces derniers. -</p> - -<p> -Je vais faire un très petit aparté sur le pourquoi de cette -personnalisation : -</p> - -<ul class="org-ul"> -<li>C'est <b>fun</b> à faire et c'est relativement important de mon point de vue. -</li> -<li>C'est <b>éducatif</b> ou formateur ; on lit les documentations de nos -outils, leurs fonctionnalités un peu cachées. On va souvent découvrir -un peu la philosophie dans laquelle l'outil a été créé. C'est en -mettant les <i>mains dans le cambouis</i> et en <i>foutant un gros bordel</i> -que j'ai le plus appris (ça va du <i>langage</i> shell et d'autres -langages de scripts, de POSIX, au noyau linux ou encore au LISP avec -GNU/Emacs). -</li> -<li>Cela fait <b>gagner du temps</b> et de manière non négligeable. Je suis -né <span class="underline">courageux mais terriblement fainéant</span> (et oui c'est possible -<code>:-P</code>), j'aime pas trop me répéter quand ça devient un peu compliqué -/ chiant (e.g. <code>docker run monimage args</code> ça va, <code>docker run</code> avec -<code>-v /tmp:/tmp -v /var/run/docker.socket:/var/run/docker.socket […]</code> -et <code>run monimage arg1 arg2 arg3 […]</code> moins déjà). -</li> -</ul> - -<p> -Mais revenons à nos moutons et faisons une petite liste de mes besoins, un -peu en vrac : -</p> - -<ul class="org-ul"> -<li>J'ai plusieurs ordinateurs (laptop/desktop/serveurs) et je souhaite -avoir mes configurations <b>synchronisées</b> entre ceux-ci — et ce de -manière simple, c'est à dire <i>une commande à exécuter</i>. -</li> -<li>C'est lié au point précédent mais, je ne <i>peux pas vivre</i> sans -outil de gestion de version, comme <b>git</b>. Il me faut donc un outil -ou ensemble d'outil qui sache utiliser des outils de gestion de -version <i>du marché</i>. - - -<div class="figure"> -<p><img src="./img/git-all-the-thing.jpg" alt="git-all-the-thing.jpg" /> -</p> -</div> -</li> - -<li>En fonction de mes ordinateurs, mes besoins de configuration -changent. Il me faut donc un outil <b>flexible</b> qui me permette de dire -par exemple : sur ce PC j'ai un serveur <code>Xorg</code> donc j'ai besoin de -mes configuration xorg, de celle de mon <i>window manager</i>, etc. — et -inversement sur ce serveur j'ai besoin de python et haskell mais pas -de xorg.. -</li> -<li>Je ne souhaites pas avoir à faire des liens symboliques, ou de -scripts d'installation. Je trouves que ça rends les choses plus -compliquées. Du coup il faut que je puisse avoir <b>plusieurs <i>dépôts -de configuration</i></b> (repository) qui pointent au même endroit, sans -que ce soit le bordel. -</li> -<li>Le <b>partage</b> est important pour moi. Il en découle deux choses : -<ol class="org-ol"> -<li>Il faut que je puisse documenter un peu mon repository, avec un -bon vieux <code>README</code> ; sans que chaque <code>README</code> se marche dessus. -</li> -<li>Il y a quelques <b>informations</b> qui sont <b>personnelles</b>, comme par -exemple les clés ssh. Il me faut donc être capable d'avoir des -<i>dépôts publiques</i> et des <i>dépôts privés</i>. C'est grandement facilité -par l'aspect <i>flexibilité</i> <code>:-)</code>. -</li> -</ol> -</li> -<li>Un bonus que je souhaite, est de pouvoir disposer de <b>hooks</b>, un peu -à la manière de git (voir <a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">ici</a>). L'idée est de pouvoir <b>générer</b> un -fichier de configuration à partir d'un ensemble de fichiers qui -viendraient de différents dépôts. Le meilleur exemple que je peux -donner c'est <code>~/.ssh/config</code> dans lequel je vais y mettre des bouts -publiques que je souhaites partager (comme le <code>Host *</code> avec des -trucs cool comme <code>ControlPersist</code>, on en parlera plus tard) et des -bouts privés (mes hosts privés, avec mes configurations de -<i>rebonds</i>, etc..). -</li> -</ul> - -<p> -Cette liste a mis un certain temps à se former dans ma tête, mais une -fois qu'elle était formée, j'ai pu assez facilement faire des choix. -</p> -</div> -</div> - -<div id="outline-container-sec-2" class="outline-2"> -<h2 id="sec-2">Choix</h2> -<div class="outline-text-2" id="text-2"> -<p> -Deux outils et un peu d'organisation permettent de répondre à mes -besoins. Les deux outils sont <code>vcsh</code> et <code>myrepos</code> (anciennement appelé -<code>mr</code>), fait par respectivement Richard Hartmann et Joey Hess (tout -deux assez impliqué dans la communauté Debian). -</p> -</div> - -<div id="outline-container-sec-2-1" class="outline-3"> -<h3 id="sec-2-1">vcsh</h3> -<div class="outline-text-3" id="text-2-1"> -<p> -En un mot, <a href="https://github.com/RichiH/vcsh">vcsh</a> permet de maintenir plusieurs <i>repository</i> <a href="http://git-scm.com/">git</a> dans -un seul dossier. Par défaut tous les <i>repository</i> git maintenus par -<code>vcsh</code> pointent vers le dossier <code>$HOME</code>, mais il est possible -d'utiliser un autre dossier. -</p> - -<p> -L'idée est de pouvoir disposer de plusieurs repository par <i>famille -d'application</i>, par exemple <code>vim</code>, <code>ssh</code>, <code>emacs</code>, <code>zsh</code>, etc. Cela -permet ainsi d'avoir différents ensemble de configurations sur -différentes machines et pour différents utilisateurs. Cela apporte -une très grande flexibilité et facilite le partage de configuration -(au sein d'une entreprise ou d'un projet par exemple) tout en -laissant la place à la définition de configuration(s) -personnalisé(s). -</p> - -<p> -En bonus, <code>vcsh</code> supporte un système de hook, permettant d'exécuter -des commandes à différents moments du <i>workflow</i> — c'est la seule -partie qui manquant à <code>vcsh</code> de mon point de vue alors j'y ai -apporté ma petit pierre. -</p> - -<p> -<code>vcsh</code> est la clé de voûte de ma gestion de configuration. Sans le -travail formidable de <a href="http://richardhartmann.de/">Richard Hartmann</a>, je ne sais pas comment je -ferais.. -</p> -</div> -</div> - -<div id="outline-container-sec-2-2" class="outline-3"> -<h3 id="sec-2-2">myrepos</h3> -<div class="outline-text-3" id="text-2-2"> -<p> -En un mot, <a href="https://myrepos.branchable.com/">myrepos</a> est un outil permettant de <i>gérer</i> plusieurs -repository (git, subversion, mercurial, …) avec une seule -commande : <code>mr</code>. C'est simple et efficace : -</p> - -<ul class="org-ul"> -<li><code>mr u</code> (ou <code>mr update</code>) pour récupérer les dernières modifications (<code>git pull</code>, -<code>svn up</code>, …). -</li> -<li><code>mr -d $HOME/.config u</code> pour récupérer les dernières modifications -des repository qui sont dans <code>$HOME/.config</code>. -</li> -<li><code>mr -j 6 u</code> pour paralléliser la récupération (ici 6 jobs en parallèle). -</li> -<li><code>mr p</code> pour pousser des modifications (<code>git push</code>, …). -</li> -<li><code>mr run</code> pour lancer un commande (j'utilise ça tous les jours). -</li> -</ul> - -<p> -Il est également possible de personnaliser les commandes à lancer lors -d'un <i>update</i> ou autre (toutes les commandes), et même en définir des -nouvelles. Cela se présente comme suit : -</p> - - -<div class="org-src-container"> - -<pre class="src src-conf">[<span class="org-type">foo</span>] -<span class="org-variable-name">checkout</span> = git@github.com:joeyh/foo.git -<span class="org-variable-name">update</span> = git pull --rebase - -[<span class="org-type">bar</span>] -<span class="org-comment-delimiter"># </span><span class="org-comment">This repository has an upstream, which I've forked;</span> -<span class="org-comment-delimiter"># </span><span class="org-comment">set up a remote on checkout.</span> -<span class="org-variable-name">checkout</span> = - git clone git@github.com:joeyh/bar.git - cd bar - git remote add upstream git@github.com:barbar/bar.git -<span class="org-comment-delimiter"># </span><span class="org-comment">make `mr zap` integrate from upstream</span> -<span class="org-variable-name">zap</span> = - git pull upstream - git merge upstream/master - git push origin master - -[<span class="org-type">mystuff</span>] -<span class="org-variable-name">checkout</span> = git@github.com:joeyh/foo.git -<span class="org-comment-delimiter"># </span><span class="org-comment">Skip if the current user is not joey</span> -<span class="org-variable-name">skip</span> = test `whoami` != joey - -[<span class="org-type">DEFAULT</span>] -<span class="org-comment-delimiter"># </span><span class="org-comment">Teach mr how to `mr gc` in git repos.</span> -<span class="org-variable-name">git_gc</span> = git gc <span class="org-string">"$@"</span> -</pre> -</div> - -<p> -Une autre fonctionnalité qui m'est totalement indispensable est ce -qu'on appel les <code>fixup(s)</code>. Il est en effet possible d'exécuter une ou -plusieurs commandes (shell) après un <code>update</code> (ou via la commande -<code>fixup</code>). C'est grâce à ce système la que je génère mes fichiers de -configuration en provenance de plusieurs repository (comme -<code>$HOME/.ssh/config</code> ou encore <code>$HOME/.gitconfig</code>). -</p> - -<p> -<code>myrepos</code> est l'exemple de l'outil simple et efficace qui fait une -chose et le fait très bien, et dont je n'arrive pas à me passer -<code>:-D</code>. Je l'utilise également dans plein d'autres cas, comme par -exemple pour mettre à jour mes <i>forks</i> de projets open-source. -</p> -</div> -</div> -</div> - -<div id="outline-container-sec-3" class="outline-2"> -<h2 id="sec-3">Conclusion</h2> -<div class="outline-text-2" id="text-3"> -<p> -Et voilà, c'est tout pour cette introduction <code>;-)</code>. La prochaine -partie se penchera sur la <b>structure</b> que j'utilise ainsi que le -repository principal qui est <a href="https://github.com/vdemeester/vcsh-home"><b>vcsh-home</b></a>. Dans les parties suivantes -on parlera des autres repository et donc des configurations -spécifiques pour les différents outils (comme <a href="https://github.com/vdemeester/sh-config">sh-config</a>, -<a href="https://github.com/vdemeester/emacs-config">emacs-config</a> ou encore <a href="https://github.com/vdemeester/go-config">go-config</a>). On parlera aussi probablement de -<code>git-annex</code> dans le futur. -</p> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2016-09-18-firefox-places-and-bookmarks/" title="Firefox hidden feature — places in bookmarks">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2015-06-01-docker-1.6-ecosystem/" title="Docker 1.6 et son écosystème">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2016-09-18-firefox-places-and-bookmarks/index.html b/www/vincent.demeester.fr/content/legacy/posts/2016-09-18-firefox-places-and-bookmarks/index.html @@ -1,332 +0,0 @@ -<!DOCTYPE html> - -<html lang="fr"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2016-09-18-firefox-places-and-bookmarks/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="fr"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Firefox hidden feature — places in bookmarks</h1><a href='https://vincent.demeester.fr/posts/2016-09-18-firefox-places-and-bookmarks/'></a> - <address class="signature"> - <span class="date">Mon, 19 September, 2016</span> - <span class="words">(1100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#configurations">configurations</a></li> - - - - - - <li class="tag tag-firefox"><a href="/tags/#firefox">firefox<span>1</span></a></li> - - - <li class="tag tag-place"><a href="/tags/#place">place<span>1</span></a></li> - - - <li class="tag tag-bookmark"><a href="/tags/#bookmark">bookmark<span>1</span></a></li> - - - <li class="tag tag-hidden"><a href="/tags/#hidden">hidden<span>1</span></a></li> - - - <li class="tag tag-tips"><a href="/tags/#tips">tips<span>2</span></a></li> - - <br/> - - </ul> - </header> - - - - <p> -Je réalise que j'utilise Firefox depuis bien plus de 10 ans maintenant -(on doit être à minimum 15 ans en fait…). Et je me souviens d'un temps -où je souhaitais rendre mes <i>bookmarks</i> (marque-pages 👼) -dynamique. Après tout ils existent de base dans Firefox (e.g. <code>Most -visited</code>), il doit donc être possible d'en faire soit même. -</p> - -<p> -Il fut un temps où c'était facile à mettre en place — ouvrir la -gestion des marques pages, chercher quelque chose et <i>cliquer</i> sur le -bouton <code>save</code> pour sauvegarder cette recherche en tant de bookmark -dynamique. -</p> - -<p> -<span class="underline">Note</span>: comme j'avais grave lutté à l'époque, et que j'ai encore lutté -cette fois ci, cet article va me servir de pense-bête pour le futur. -</p> - -<div id="outline-container-sec-1" class="outline-2"> -<h2 id="sec-1">Places</h2> -<div class="outline-text-2" id="text-1"> -<p> -C'est le petit nom que possède cette fonctionnalité dans le cœur de -Firefox. C'est un nom relativement commun, du coup ça n'aide pas trop -la recherche d'information… Le meilleur endroit pour se documenter -reste alors le <a href="https://developer.mozilla.org">Mozilla Developer Network</a>… -</p> - -<p> -Et ce qu'on peut lire sur cette <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places">page</a> c'est : -</p> - -<blockquote> -<p> -Places is the bookmarks and history management system introduced in -Firefox 3. It offers increased flexibility and complex querying to -make handling the places the user goes easier and more -convenient. It also includes new features including favicon storage -and the ability to annotate pages with arbitrary information. -</p> -</blockquote> - -<p> -C'est donc un mécanisme interne qui permet d'annoter des pages -(bookmarks, history, …) et surtout un <i>requêtage</i> plus complexe et -flexible que le système précédent. On peut noter également que c'est -arrivé en version 3, et qu'à la date du jour, la version courante de -Firefox est la 48. En espérant donc que ce soit toujours le système en -place (<i>spoiler alert: ça a l'air d'être le cas</i>). -</p> - - -<div class="figure"> -<p><img src="/images/2016/firefox-place-awesomebar-example.png" alt="firefox-place-awesomebar-example.png" /> -</p> -<p><span class="figure-number">Figure 1:</span> An example of places usage in the awesome bar</p> -</div> - -<p> -Les petits <i>encarts</i> en noir ci-dessus sont un exemple de ces -<i>places</i>. Ici il s'agit des <b>tags</b> qui ont étés apposer sur les -bookmarks ; on voit d'ailleurs que ce sont des bookmarks puisqu'ils -ont une petite étoile à côté du joli petit <code>favicon</code>. Firefox a pris -les termes que j'ai écrit dans la barre d'url et à faire une recherche -dans les <i>places</i> suivant différents critères (l'url, les tags pour -les bookmarks, …). -</p> -</div> -</div> - -<div id="outline-container-sec-2" class="outline-2"> -<h2 id="sec-2">Places dans les bookmarks</h2> -<div class="outline-text-2" id="text-2"> -<p> -L'idée est d'utiliser cette fonctionnalité pour faire des bookmarks -dynamique. Pour poser un peu de contexte, j'utilise surtout la -bookmark toolbar pour accéder à des pages dont j'ai besoin (au hasard, -le webmail du boulot, une page précise d'issues sur github, des pages -de guide/référence/manuel sur des outils que j'utilise…) et également -en mode <i>read that later</i>. -</p> - - -<div class="figure"> -<p><img src="/images/2016/firefox-place-bookmark-toolbar.png" alt="firefox-place-bookmark-toolbar.png" /> -</p> -<p><span class="figure-number">Figure 2:</span> Ma <i>bookmark</i> toolbar</p> -</div> - -<p> -Par exemple, dans mon dossier <code>inbox</code>, il y a plusieurs sous-dossiers -(en fait des dossiers dynamique, mais j'y reviendrais plus tard), -genre <code>docker</code>, <code>nix</code>, <code>golang</code>, <code>java</code>, etc. Tout ce qui <i>traîne</i> -dans <code>inbox</code> est à lire ou à trier (<code>inbox</code> se réfère un peu à ce que -l'on peut voir avec GTD). Chaque sous dossier était une sorte de -<i>filtre</i> par projet, langage ou /whatever/… -</p> - -<p> -Nous allons donc ruser un peu et utiliser les <i>places</i> dans nos -bookmarks pour en faire des dossiers dynamique, à l'instar de <code>Most -Visited</code>. Pour se faire, il faut déjà trouver un peu de documentation -sur l'utilisation de ces fameuses <i>places</i> au sein de bookmarks — et -ça pèche un peu… Toujours sur le <a href="https://developer.mozilla.org">Mozilla Developer Network</a>, une page -<i>un peu caché</i> nous révèle quelques informations : <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places/Places_query_URIs">Places query URIs</a>. -</p> - -<blockquote> -<p> -You can use a <code>place</code> URI as a bookmark. For example, if you right-click -on the toolbar and choose "New Bookmark," you can enter a place URI -there to create a new query on your toolbar that, when clicked, will -reveal a popup containing the results of the query. -</p> -</blockquote> - -<p> -Victoire <code>\o/</code>, il <i>suffit</i> de créer un bookmark avec comme <code>URI</code> -une <code>place:…</code> URI et c'est gagné. Ainsi, un bookmark avec comme <code>URI</code> -<code>place:terms=nixos</code> me retournera un dossier dynamique qui contiens -tous les liens (<i>history</i>, <i>bookmarks</i>, …) qui contiennent le mot -<code>nixos</code> — en gros l'équivalent de ce que nous aurions si nous tapions -<code>nixos</code> dans la <i>awesomebar</i>. -</p> - -<p> -Si l'on regarde d'un peu plus près <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places/Places_query_URIs">Places query URIs</a>, il y a une -longue liste de paramètres possible. Il y en a pour presque tous les -goûts : le temps (utile pour afficher l'historique, mais pas trop), -les visites, le type de <i>place</i> (<i>bookmark</i>, <i>history</i>, …), le -domaine de l'élément, le dossier dans lequel il se trouve, l'<code>URI</code>, -les tags… j'en passe et des meilleurs. -</p> - -<p> -Si par exemple, je souhaite n'afficher que les pages visités -aujourd'hui, triés par nombre de visites et limités à 10 résultats, je -peux mettre comme <code>URI</code> : -</p> - -<div class="org-src-container"> - -<pre class="src src-http">place:queryType=0&sort=8&maxResults=10&beginTimeRef=1&beginTime=0 -</pre> -</div> - -<p> -Et on obtiens ça : -</p> - - -<div class="figure"> -<p><img src="/images/2016/firefox-place-most-visited-today.png" alt="firefox-place-most-visited-today.png" /> -</p> -</div> - -<p> -Mais revenons à nos moutons, moi ce que je souhaite, c'est faire des -dossiers dynamique par <code>tag</code>, i.e. les tags que l'on peut setter -lorsqu'on ajoute un bookmark. Et ça tombe bien, un des paramètres -s'appelle <code>tag</code> et fait exactement ça. Je souhaite également pouvoir -faire des <code>ET</code> sur mes tags — par exemple, dans mon dossier -<code>inbox/nixos</code> je veux tous les bookmarks qui sont taggués <code>inbox</code> <b>et</b> -<code>nixos</code>. Et c'est simple, il suffit de lui donner les deux. -</p> - -<div class="org-src-container"> - -<pre class="src src-http">place:tag=inbox&tag=nixos -</pre> -</div> -</div> -</div> - -<div id="outline-container-sec-3" class="outline-2"> -<h2 id="sec-3">Rétrospective</h2> -<div class="outline-text-2" id="text-3"> -<p> -Voilà, vous avez maintenant tout ce qu'il faut pour faire des dossiers -dynamiques dans vos bookmarks Firefox et vous organiser au mieux ( -<i>ou pas</i>). Quelques points à noter : -</p> - -<ul class="org-ul"> -<li>L'icône du dossier dynamique — ou même la fonctionnalité à -proprement parler= n'apparaît pas de suite. Il faut parfois -redémarrez Firefox pour profiter du nouveau dossier dynamique. -</li> -<li>Une fois que le bookmark est vu comme un dossier dynamique, il n'est -plus possible d'éditer l'<code>URI</code>. Si vous voulez en changer un, il -faut tout bonnement le recréer. -</li> -<li>Bien que ce soit une fonctionnalité que je trouve géniale, il y a -peu de <i>presse</i> sur le sujet et à mon grand étonnement, aucun plugin -pour gérer ça plus proprement. Est-ce le signe qu'un jour ce ne sera -plus supporter, je n'en ai aucune idée. -</li> -<li>Un point très positif si vous utilisez Firefox Sync : ça marche bien -(pas vraiment étonnant en fait), ces dossiers se synchronise comme -le reste et seront donc à disponible quelque soit l'appareil sur lequel -vous utilisez firefox <code>\o/</code>. -</li> -</ul> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2017-01-01-go-testing-functionnal-builders/" title="Golang testing — functional arguments for wonderful builders">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2015-07-31-config-managment-intro/" title="Gestion de configuration : introduction">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2017-01-01-go-testing-functionnal-builders/index.html b/www/vincent.demeester.fr/content/legacy/posts/2017-01-01-go-testing-functionnal-builders/index.html @@ -1,585 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2017-01-01-go-testing-functionnal-builders/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="en"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — functional arguments for wonderful builders</h1><a href='https://vincent.demeester.fr/posts/2017-01-01-go-testing-functionnal-builders/'></a> - <address class="signature"> - <span class="date">Sun, 1 January, 2017</span> - <span class="words">(1600 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-builder"><a href="/tags/#builder">builder<span>1</span></a></li> - - - <li class="tag tag-functionnal"><a href="/tags/#functionnal">functionnal<span>2</span></a></li> - - - <li class="tag tag-java"><a href="/tags/#java">java<span>4</span></a></li> - - - <li class="tag tag-featured"><a href="/tags/#featured">featured<span>2</span></a></li> - - <br/> - - </ul> - </header> - - - - <blockquote> -<p> -Programming is not easy; even the best programmers are incapable of -writing programs that work exactly as intended every time. Therefore -an important part of the software development process is -testing. Writing tests for our code is a good way to ensure quality -and improve reliability. -</p> -</blockquote> - -<p> -Go programs, when properly implemented, are fairly simple to test -programatically. The <code>testing</code> built-in library and the features of -the language itself offer plenty of ways to write good tests. As this -is a subject I particularly like, I'm gonna write a bunch of articles -about it, that, <i>hopefully</i> do not get old or boring. -</p> - -<p> -I'm not going to start by introducing how <code>testing</code> works, it's -already widely described in <a href="https://golang.org/pkg/testing/">the <code>testing</code> godoc</a>, <a href="https://blog.golang.org/examples">some</a> <a href="https://www.golang-book.com/books/intro/12">articles</a> and -<a href="https://jonathanmh.com/golang-unit-testing-for-absolute-beginners/">blogs</a>. I'm going to jump ahead on a more advanced techinque to write -tests, the <code>builders</code> for tests. -</p> - -<p> -One of the most important characteristic of a <b>unit test</b> (and any -type of test really) is <b>readability</b>. This means it should be <i>easy -to read</i> but most importantly it should <b>clearly show the intent of -the test</b>. The setup (and cleanup) of the tests should be as small as -possible to avoid the noise. And as we are going to see below, <code>go</code> -makes it pretty easy to do so. -</p> - -<div id="outline-container-org1afcfe7" class="outline-2"> -<h2 id="org1afcfe7">Builders in tests</h2> -<div class="outline-text-2" id="text-org1afcfe7"> -<p> -Sometimes, your need to create data structure for your test that -might take a lot of line and introduce noise. In <code>golang</code> we don't -have method overload or even <i>constructors</i> as some other language -have. This means most of the time, we end up building our data using -directly the struct expression, as below. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-rainbow-identifiers-identifier-5">node</span> := &<span class="org-type">Node</span>{ - <span class="org-constant">Name</span>: <span class="org-string">"carthage"</span>, - <span class="org-constant">Hostname</span>: <span class="org-string">"carthage.sbr.pm"</span>, - <span class="org-constant">Platform</span>: <span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x86_64"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"linux"</span>, - }, -} -</pre> -</div> - -<p> -Let's imagine we have a <code>Validate</code> function that make sure the -specified <code>Node</code> is supported on our structure. We would write some -tests that ensure that. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">TestValidateLinuxIsSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(&<span class="org-type">Node</span>{ - <span class="org-constant">Name</span>: <span class="org-string">"carthage"</span>, - <span class="org-constant">Hostname</span>: <span class="org-string">"carthage.sbr.pm"</span>, - <span class="org-constant">Platform</span>: &<span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x86_64"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"linux"</span>, - }, - }) - <span class="org-keyword">if</span> !<span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"linux should be supported, it was not"</span>) - } -} - -<span class="org-keyword">func</span> <span class="org-function-name">TestValidateDarwinIsNotSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(&<span class="org-type">Node</span>{ - <span class="org-constant">Name</span>: <span class="org-string">"babylon"</span>, - <span class="org-constant">Hostname</span>: <span class="org-string">"babylon.sbr.pm"</span>, - <span class="org-constant">Platform</span>: &<span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x86_64"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"darwin"</span>, - }, - }) - <span class="org-keyword">if</span> <span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"darwin should not be supported, it was"</span>) - } -} -</pre> -</div> - -<p> -This is quickly hard to read, there is too much noise on that -test. We setup a whole <code>Node</code> struct, but the only thing we really -intend to test is the <code>Platform.OS</code> part. The rest is just required -fields for the function to correctly compile and run. -</p> - -<p> -This is where test builders (and builders in general) comes into -play. In <a href="http://www.growing-object-oriented-software.com/">Growing Object-Oriented Software Guided by Tests</a>, the -Chapter 22 "Constructing Complex Test Data" is exactly about that -and guide us through the why and the how of these builders. The -examples in the book are in <code>java</code> and uses wisely the -object-oriented nature of the language. Here is an example from the -book. -</p> - -<div class="org-src-container"> -<pre class="src src-java"><span class="org-comment-delimiter">// </span><span class="org-comment">I just want an order from a customer that has no post code</span> -<span class="org-type">Order</span> <span class="org-variable-name">order</span> = <span class="org-rainbow-identifiers-identifier-12">anOrder</span>() - .<span class="org-rainbow-identifiers-identifier-7">from</span>(<span class="org-rainbow-identifiers-identifier-13">aCustomer</span>().<span class="org-rainbow-identifiers-identifier-11">with</span>(<span class="org-rainbow-identifiers-identifier-13">anAddress</span>().<span class="org-rainbow-identifiers-identifier-3">withNotPostCode</span>())) - .<span class="org-rainbow-identifiers-identifier-10">build</span>() -</pre> -</div> - -<p> -These builders helps <b>keep tests expressive</b>, as it's pretty obvious -when reading it, what we want to test. They remove the <b>visual -noise</b> you have when building an object (or a <code>struct{}</code> in Go) and -allows you to put sane default. They also make <b>tests resilient to -change</b>. If the structure changes, only the builder has to be -updated, not the tests depending on it. They also make default case -really simple to write, and special cases not much more complicated. -</p> -</div> -</div> - -<div id="outline-container-orgff90129" class="outline-2"> -<h2 id="orgff90129">Builder in Go</h2> -<div class="outline-text-2" id="text-orgff90129"> -<p> -The naive way to create builders in <code>go</code> could be to create a -<code>builder</code> struct that have methods to construct the final struct and -a <code>build</code> method. Let's see how it looks. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">ANode</span>() *<span class="org-type">NodeBuilder</span> { - <span class="org-keyword">return</span> &<span class="org-type">NodeBuilder</span>{ - <span class="org-constant">node</span>: &<span class="org-type">Node</span>{ - <span class="org-constant">Name</span>: <span class="org-string">"node"</span>, - <span class="org-comment-delimiter">// </span><span class="org-comment">Other defaults</span> - }, - } -} - -<span class="org-keyword">type</span> <span class="org-type">NodeBuilder</span> <span class="org-keyword">struct</span> { - <span class="org-rainbow-identifiers-identifier-5">node</span> *<span class="org-rainbow-identifiers-identifier-12">Node</span> -} - -<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-1">b</span> *<span class="org-type">NodeBuilder</span>) <span class="org-function-name">Build</span>() *<span class="org-type">Node</span> { - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-1">b</span>.<span class="org-rainbow-identifiers-identifier-5">node</span> -} - -<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-1">b</span> *<span class="org-type">NodeBuilder</span>) <span class="org-function-name">Hostname</span>(<span class="org-rainbow-identifiers-identifier-3">hostname</span> <span class="org-type">string</span>) *<span class="org-type">NodeBuilder</span> { - <span class="org-rainbow-identifiers-identifier-1">b</span>.<span class="org-rainbow-identifiers-identifier-5">node</span>.<span class="org-rainbow-identifiers-identifier-10">Hostname</span> = <span class="org-rainbow-identifiers-identifier-3">hostname</span> - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-1">b</span> -} - -<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-1">b</span> *<span class="org-type">NodeBuilder</span>) <span class="org-function-name">Name</span>(<span class="org-rainbow-identifiers-identifier-3">name</span> <span class="org-type">string</span>) *<span class="org-type">NodeBuilder</span> { - <span class="org-rainbow-identifiers-identifier-1">b</span>.<span class="org-rainbow-identifiers-identifier-5">node</span>.<span class="org-rainbow-identifiers-identifier-8">Name</span> = <span class="org-rainbow-identifiers-identifier-3">name</span> - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-1">b</span> -} - -<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-1">b</span> *<span class="org-type">NodeBuilder</span>) <span class="org-function-name">Platform</span>(<span class="org-rainbow-identifiers-identifier-14">platform</span> *<span class="org-type">Platform</span>) *<span class="org-type">NodeBuilder</span> { - <span class="org-rainbow-identifiers-identifier-1">b</span>.<span class="org-rainbow-identifiers-identifier-5">node</span>.<span class="org-rainbow-identifiers-identifier-4">Platform</span> = <span class="org-rainbow-identifiers-identifier-14">platform</span> - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-1">b</span> -} -</pre> -</div> - -<p> -This looks decent, and using it is pretty straightforward. At least -it make building the <code>struct</code> more expressive, less noisy and -resilient to change. We can update the previous test as follow. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">TestValidateLinuxIsSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(<span class="org-function-name">ANode</span>().<span class="org-function-name">Platform</span>(&<span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x86_64"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"linux"</span>, - }).<span class="org-function-name">Build</span>()) - <span class="org-keyword">if</span> !<span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"linux should be supported, it was not"</span>) - } -} - -<span class="org-keyword">func</span> <span class="org-function-name">TestValidateDarwinIsNotSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(<span class="org-function-name">ANode</span>().<span class="org-function-name">Platform</span>(&<span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x86_64"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"darwin"</span>, - }).<span class="org-function-name">Build</span>()) - <span class="org-keyword">if</span> <span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"darwin should not be supported, it was"</span>) - } -} -</pre> -</div> - -<p> -There is room for improvement : -</p> - -<ul class="org-ul"> -<li>There is still some noise, mainly <code>build()</code> and the platform -<code>struct</code>, as it still shows too much.</li> -<li>It's not that extensible yet. If you want to update the <code>Node</code> a -certain way that the builder is not written for, you have to -update the builder.</li> -<li>The <code>NodeBuilder</code> struct feels a little empty, it's just there to -hold on the <code>Node</code> being constructed until it is <code>build</code>.</li> -</ul> - -<p> -One improvement we could make is to have a <code>Platform</code> builder, even -if it's a small struct here. Let's do that in the same way we did -with <code>Node</code>. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">APlatform</span>() *<span class="org-type">PlatformBuilder</span> { - <span class="org-keyword">return</span> &<span class="org-type">PlatformBuilder</span>{ - <span class="org-constant">platform</span>: &<span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x64_86"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"linux"</span>, - }, - } -} - -<span class="org-keyword">type</span> <span class="org-type">PlatformBuilder</span> <span class="org-keyword">struct</span>{ - <span class="org-rainbow-identifiers-identifier-14">platform</span> *<span class="org-rainbow-identifiers-identifier-4">Platform</span> -} - -<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-1">b</span> *<span class="org-type">PlatformBuilder</span>) <span class="org-function-name">Build</span>() *<span class="org-type">Platform</span> { - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-1">b</span>.<span class="org-rainbow-identifiers-identifier-14">platform</span> -} - -<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-1">b</span> *<span class="org-type">PlatformBuilder</span>) <span class="org-function-name">OS</span>(<span class="org-rainbow-identifiers-identifier-2">os</span> <span class="org-type">string</span>) *<span class="org-type">PlatformBuilder</span> { - <span class="org-rainbow-identifiers-identifier-1">b</span>.<span class="org-rainbow-identifiers-identifier-14">platform</span>.<span class="org-rainbow-identifiers-identifier-12">OS</span> = <span class="org-rainbow-identifiers-identifier-2">os</span> - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-1">b</span> -} -</pre> -</div> - -<p> -And our tests becomes 🐻. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">TestValidateLinuxIsSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(<span class="org-function-name">ANode</span>().<span class="org-function-name">Platform</span>( - <span class="org-function-name">APlatform</span>().<span class="org-function-name">OS</span>(<span class="org-string">"linux"</span>).<span class="org-function-name">Build</span>() - ).<span class="org-function-name">Build</span>()) - <span class="org-keyword">if</span> !<span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"linux should be supported, it was not"</span>) - } -} - -<span class="org-keyword">func</span> <span class="org-function-name">TestValidateDarwinIsNotSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(<span class="org-function-name">ANode</span>().<span class="org-function-name">Platform</span>( - <span class="org-function-name">APlatform</span>().<span class="org-function-name">OS</span>(<span class="org-string">"darwin"</span>).<span class="org-function-name">Build</span>() - ).<span class="org-function-name">Build</span>()) - <span class="org-keyword">if</span> <span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"darwin should not be supported, it was"</span>) - } -} -</pre> -</div> - -<p> -It does not really improve the visual noise as there is now quite a -few duplication : several <code>build</code>, <code>APlatform</code> inside <code>Platform</code>, … -It is a small improvement on readability but not that much compared -to the previous one. This is were the Go language features comes -into play. -</p> -</div> -</div> - -<div id="outline-container-org28e3042" class="outline-2"> -<h2 id="org28e3042">Functional arguments to the rescue</h2> -<div class="outline-text-2" id="text-org28e3042"> -<p> -Go has two interesting feature that are going to be useful here. -</p> - -<p> -First, a function in Go is a type on its own and thus is considered -a <i>first class citizen</i>. It means it's possible to pass a function -as argument, or define a variable that holds it. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">ApplyTo</span>(<span class="org-rainbow-identifiers-identifier-8">s</span> <span class="org-type">string</span>, <span class="org-rainbow-identifiers-identifier-12">fn</span> <span class="org-keyword">func</span>(<span class="org-type">string</span>) <span class="org-type">string</span>) <span class="org-type">string</span> { - <span class="org-keyword">return</span> <span class="org-function-name">fn</span>(<span class="org-rainbow-identifiers-identifier-8">s</span>) -} - -<span class="org-keyword">func</span> <span class="org-function-name">world</span>(<span class="org-rainbow-identifiers-identifier-8">s</span> <span class="org-type">string</span>) <span class="org-type">string</span> { - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-9">fmt</span>.<span class="org-function-name">Sprintf</span>(<span class="org-string">"%s, world!"</span>, <span class="org-rainbow-identifiers-identifier-8">s</span>) -} - -<span class="org-comment-delimiter">// </span><span class="org-comment">Usage</span> -<span class="org-rainbow-identifiers-identifier-1">a</span> := <span class="org-function-name">ApplyTo</span>(<span class="org-string">"hello"</span>, <span class="org-rainbow-identifiers-identifier-9">world</span>) -<span class="org-comment-delimiter">// </span><span class="org-comment">a == "hello, world!"</span> -</pre> -</div> - -<p> -The second feature that comes into play here, is the possiblity to -have <i>variadic</i> functions. A variadic function is a function that -takes a variable number of arguments (from <code>0</code> to any number of -argument). -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">Print</span>(<span class="org-rainbow-identifiers-identifier-9">strs</span> ...<span class="org-type">string</span>) <span class="org-type">string</span> { - <span class="org-keyword">for</span> <span class="org-rainbow-identifiers-identifier-8">_</span>, <span class="org-rainbow-identifiers-identifier-8">s</span> := <span class="org-keyword">range</span> <span class="org-rainbow-identifiers-identifier-9">strs</span> { - <span class="org-rainbow-identifiers-identifier-9">fmt</span>.<span class="org-function-name">Println</span>(<span class="org-rainbow-identifiers-identifier-8">s</span>) - } -} -</pre> -</div> - -<p> -As we are going to see below, combining these two feature makes our -builders pretty easy to write and to use with simple case, while -staying very customizable, even outside of the builder. This is -really well described in a talk from Dave Cheney : <a href="https://www.youtube.com/watch?v=24lFtGHWxAQ&index=15&list=PLMW8Xq7bXrG58Qk-9QSy2HRh2WVeIrs7e">Functional -options for friendly APIs</a> (<a href="https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis">transcription</a>). -</p> - -<p> -Let's apply that to our new builders. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">ANode</span>(<span class="org-rainbow-identifiers-identifier-2">nodeBuilders</span> ...<span class="org-keyword">func</span>(*<span class="org-type">Node</span>)) *<span class="org-type">Node</span> { - <span class="org-rainbow-identifiers-identifier-5">node</span> := &<span class="org-type">Node</span>{ - <span class="org-constant">Name</span>: <span class="org-string">"node"</span>, - <span class="org-comment-delimiter">// </span><span class="org-comment">Other defaults</span> - } - - <span class="org-keyword">for</span> <span class="org-rainbow-identifiers-identifier-8">_</span>, <span class="org-rainbow-identifiers-identifier-10">build</span> := <span class="org-keyword">range</span> <span class="org-rainbow-identifiers-identifier-2">nodeBuilders</span> { - <span class="org-function-name">build</span>(<span class="org-rainbow-identifiers-identifier-5">node</span>) - } - - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-5">node</span> -} - -<span class="org-keyword">func</span> <span class="org-function-name">APlatform</span>(<span class="org-rainbow-identifiers-identifier-8">platformBuilders</span> ...<span class="org-keyword">func</span>(*<span class="org-type">Platform</span>)) *<span class="org-type">Platform</span> { - <span class="org-rainbow-identifiers-identifier-14">platform</span> := &<span class="org-type">Platform</span>{ - <span class="org-constant">Architecture</span>: <span class="org-string">"x64_86"</span>, - <span class="org-constant">OS</span>: <span class="org-string">"linux"</span>, - } - - <span class="org-keyword">for</span> <span class="org-rainbow-identifiers-identifier-8">_</span>, <span class="org-rainbow-identifiers-identifier-10">build</span> := <span class="org-keyword">range</span> <span class="org-rainbow-identifiers-identifier-8">platformBuilders</span> { - <span class="org-function-name">build</span>(<span class="org-rainbow-identifiers-identifier-14">platform</span>) - } - - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-14">platform</span> -} -</pre> -</div> - -<p> -And that is it for the actual builder code. It is <b>small</b> and -simple, there is <b>no more <code>NodeBuilder</code></b> struct, and this is highly -extensible. Let's see how to use it. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-comment-delimiter">// </span><span class="org-comment">a default node</span> -<span class="org-rainbow-identifiers-identifier-2">node1</span> := <span class="org-function-name">ANode</span>() -<span class="org-comment-delimiter">// </span><span class="org-comment">a node with a specific Hostname</span> -<span class="org-rainbow-identifiers-identifier-5">node2</span> := <span class="org-function-name">ANode</span>(<span class="org-keyword">func</span>(<span class="org-rainbow-identifiers-identifier-15">n</span> *<span class="org-type">Node</span>) { - <span class="org-rainbow-identifiers-identifier-15">n</span>.<span class="org-rainbow-identifiers-identifier-10">Hostname</span> = <span class="org-string">"custom-hostname"</span> -}) -<span class="org-comment-delimiter">// </span><span class="org-comment">a node with a specific name and platform</span> -<span class="org-rainbow-identifiers-identifier-8">node3</span> := <span class="org-function-name">ANode</span>(<span class="org-keyword">func</span>(<span class="org-rainbow-identifiers-identifier-15">n</span> *<span class="org-type">Node</span>) { - <span class="org-rainbow-identifiers-identifier-15">n</span>.<span class="org-rainbow-identifiers-identifier-8">Name</span> = <span class="org-string">"custom-name"</span> -}, <span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-15">n</span> *<span class="org-type">Node</span>) { - <span class="org-rainbow-identifiers-identifier-15">n</span>.<span class="org-rainbow-identifiers-identifier-4">Platform</span> = <span class="org-function-name">APlatform</span>(<span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-10">p</span> *<span class="org-type">Platform</span>) { - <span class="org-rainbow-identifiers-identifier-10">p</span>.<span class="org-rainbow-identifiers-identifier-12">OS</span> = <span class="org-string">"darwin"</span> - }) -}) -</pre> -</div> - -<p> -The last step is to define some <i>function builder</i> for common or -widely used customization, to make this <b>expressive</b>. And let -complex, <i>one-time</i> function builder in the end of the user. Now our -tests looks like. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">TestValidateLinuxIsSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(<span class="org-function-name">ANode</span>(<span class="org-function-name">WithAPlatform</span>(<span class="org-rainbow-identifiers-identifier-2">Linux</span>))) - <span class="org-keyword">if</span> !<span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"linux should be supported, it was not"</span>) - } -} - -<span class="org-keyword">func</span> <span class="org-function-name">TestValidateDarwinIsNotSupported</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-6">valid</span> := <span class="org-function-name">Validate</span>(<span class="org-function-name">ANode</span>(<span class="org-function-name">WithAPlatform</span>(<span class="org-rainbow-identifiers-identifier-15">Darwin</span>))) - <span class="org-keyword">if</span> <span class="org-rainbow-identifiers-identifier-6">valid</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-string">"darwin should not be supported, it was"</span>) - } -} - -<span class="org-comment-delimiter">// </span><span class="org-comment">Function builders</span> -<span class="org-keyword">func</span> <span class="org-function-name">WithAPlatform</span>(<span class="org-rainbow-identifiers-identifier-4">builders</span> ...<span class="org-keyword">func</span>(*<span class="org-type">Platform</span>)) <span class="org-keyword">func</span> (<span class="org-rainbow-identifiers-identifier-15">n</span> *<span class="org-type">Node</span>) { - <span class="org-keyword">return</span> <span class="org-keyword">func</span>(<span class="org-rainbow-identifiers-identifier-15">n</span> *<span class="org-type">Node</span>) { - <span class="org-rainbow-identifiers-identifier-15">n</span>.<span class="org-rainbow-identifiers-identifier-4">Platform</span> = <span class="org-function-name">Platform</span>(<span class="org-rainbow-identifiers-identifier-4">builders</span>...) - } -} - -<span class="org-keyword">func</span> <span class="org-function-name">Linux</span>(<span class="org-rainbow-identifiers-identifier-10">p</span> *<span class="org-type">Platform</span>) { - <span class="org-rainbow-identifiers-identifier-10">p</span>.<span class="org-rainbow-identifiers-identifier-12">OS</span> = <span class="org-string">"linux"</span> -} - -<span class="org-keyword">func</span> <span class="org-function-name">Darwin</span>(<span class="org-rainbow-identifiers-identifier-10">p</span> *<span class="org-type">Platform</span>) { - <span class="org-rainbow-identifiers-identifier-10">p</span>.<span class="org-rainbow-identifiers-identifier-12">OS</span> = <span class="org-string">"darwin"</span> -} -</pre> -</div> - -<p> -The intent is now clear. It's readable and still resilient to -change. The code <code>Node(WithPlatform(Linux))</code> is easy to understand -for a human. It makes what are the <i>tested</i> characteristics of -<code>struct</code> pretty clear. It's easy to combine multiple builders as the -<code>WithPlatform</code> function shows 👼. It's also easy to create a -<i>function builder</i>, even in a different package (as long as the ways -to modify the struct are exported) and complex or <i>on-off</i> builder -can be embedded in the function call (<code>Node(func(n *Node) { // … - })</code>). -</p> - -<p> -In summary, using these types of builder have several advantages : -</p> - -<ul class="org-ul"> -<li>tests are <b>easy to read</b>, and reduce the visual noise</li> -<li>tests are <b>resilient to change</b></li> -<li>builders are <b>easy to compose</b> and very extensible</li> -<li>builders could even be <b>shared</b> with production code as there is -nothing tied to <code>testing</code>.</li> -</ul> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2017-04-22-golang-testing-golden-file/" title="Golang testing — golden file">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2016-09-18-firefox-places-and-bookmarks/" title="Firefox hidden feature — places in bookmarks">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2017-04-22-golang-testing-golden-file/index.html b/www/vincent.demeester.fr/content/legacy/posts/2017-04-22-golang-testing-golden-file/index.html @@ -1,359 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2017-04-22-golang-testing-golden-file/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang="en"/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — golden file</h1><a href='https://vincent.demeester.fr/posts/2017-04-22-golang-testing-golden-file/'></a> - <address class="signature"> - <span class="date">Sat, 22 April, 2017</span> - <span class="words">(900 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golden"><a href="/tags/#golden">golden<span>1</span></a></li> - - - <li class="tag tag-file"><a href="/tags/#file">file<span>1</span></a></li> - - - <li class="tag tag-functionnal"><a href="/tags/#functionnal">functionnal<span>2</span></a></li> - - - <li class="tag tag-java"><a href="/tags/#java">java<span>4</span></a></li> - - <br/> - - </ul> - </header> - - - - <p> -Tests are all about <b>maintainability</b> and <b>readability</b>. You want the -least visual noise possible and it should not be a hassle to -maintain. When testing functions that output a long of string, in case -of a command line output testing, readability and maintainance tend to -be tricky to achieve. -</p> - - -<div id="outline-container-org2f1fc39" class="outline-2"> -<h2 id="org2f1fc39">The problem</h2> -<div class="outline-text-2" id="text-org2f1fc39"> -<p> -As an example let's say we want to test out the output of a command -that displays a list as a table. The output would look like the -following: -</p> - -<div class="org-src-container"> -<pre class="src src-sh"><span class="org-rainbow-identifiers-identifier-3">ID:</span> <span class="org-rainbow-identifiers-identifier-15">nodeID</span> -<span class="org-rainbow-identifiers-identifier-4">Name:</span> <span class="org-rainbow-identifiers-identifier-8">defaultNodeName</span> -<span class="org-rainbow-identifiers-identifier-10">Hostname:</span> <span class="org-rainbow-identifiers-identifier-6">defaultNodeHostname</span> -<span class="org-rainbow-identifiers-identifier-4">Joined</span> <span class="org-rainbow-identifiers-identifier-1">at:</span> <span class="org-rainbow-identifiers-identifier-11">2009-11-10</span> <span class="org-rainbow-identifiers-identifier-11">23:00:00</span> <span class="org-rainbow-identifiers-identifier-13">+0000</span> <span class="org-rainbow-identifiers-identifier-15">utc</span> -<span class="org-rainbow-identifiers-identifier-3">Status:</span> - <span class="org-rainbow-identifiers-identifier-4">State:</span> <span class="org-rainbow-identifiers-identifier-10">Ready</span> - <span class="org-rainbow-identifiers-identifier-11">Availability:</span> <span class="org-rainbow-identifiers-identifier-8">Active</span> - <span class="org-rainbow-identifiers-identifier-11">Address:</span> <span class="org-rainbow-identifiers-identifier-13">127.0.0.1</span> -<span class="org-rainbow-identifiers-identifier-9">Manager</span> <span class="org-rainbow-identifiers-identifier-3">Status:</span> - <span class="org-rainbow-identifiers-identifier-11">Address:</span> <span class="org-rainbow-identifiers-identifier-13">127.0.0.1</span> - <span class="org-rainbow-identifiers-identifier-3">Raft</span> <span class="org-rainbow-identifiers-identifier-3">Status:</span> <span class="org-rainbow-identifiers-identifier-8">Reachable</span> - <span class="org-rainbow-identifiers-identifier-8">Leader:</span> <span class="org-rainbow-identifiers-identifier-15">No</span> -<span class="org-rainbow-identifiers-identifier-3">Platform:</span> - <span class="org-rainbow-identifiers-identifier-15">Operating</span> <span class="org-rainbow-identifiers-identifier-13">System:</span> <span class="org-rainbow-identifiers-identifier-12">linux</span> - <span class="org-rainbow-identifiers-identifier-10">Architecture:</span> <span class="org-rainbow-identifiers-identifier-2">x86_64</span> -<span class="org-rainbow-identifiers-identifier-8">Resources:</span> - <span class="org-rainbow-identifiers-identifier-8">CPUs:</span> <span class="org-rainbow-identifiers-identifier-12">0</span> - <span class="org-rainbow-identifiers-identifier-9">Memory:</span> <span class="org-rainbow-identifiers-identifier-15">20</span> <span class="org-rainbow-identifiers-identifier-5">MiB</span> -<span class="org-rainbow-identifiers-identifier-14">Plugins:</span> - <span class="org-rainbow-identifiers-identifier-5">Network:</span> <span class="org-rainbow-identifiers-identifier-3">bridge,</span> <span class="org-rainbow-identifiers-identifier-12">overlay</span> - <span class="org-rainbow-identifiers-identifier-9">Volume:</span> <span class="org-rainbow-identifiers-identifier-12">local</span> -<span class="org-rainbow-identifiers-identifier-10">Engine</span> <span class="org-rainbow-identifiers-identifier-14">Version:</span> <span class="org-rainbow-identifiers-identifier-15">1.13.0</span> -<span class="org-rainbow-identifiers-identifier-10">Engine</span> <span class="org-rainbow-identifiers-identifier-12">Labels:</span> - <span class="org-rainbow-identifiers-identifier-11">-</span> <span class="org-variable-name">engine</span> = <span class="org-rainbow-identifiers-identifier-12">label</span> -</pre> -</div> - -<p> -Let's see how we would test that output, naively. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">TestNodeInspectPretty</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-14">expected</span> := <span class="org-string">```</span> -<span class="org-string">ID: nodeID</span> -<span class="org-string">Name: defaultNodeName</span> -<span class="org-string">Hostname: defaultNodeHostname</span> -<span class="org-string">Joined at: 2009-11-10 23:00:00 +0000 utc</span> -<span class="org-string">Status:</span> -<span class="org-string"> State: Ready</span> -<span class="org-string"> Availability: Active</span> -<span class="org-string"> Address: 127.0.0.1</span> -<span class="org-string">Manager Status:</span> -<span class="org-string"> Address: 127.0.0.1</span> -<span class="org-string"> Raft Status: Reachable</span> -<span class="org-string"> Leader: No</span> -<span class="org-string">Platform:</span> -<span class="org-string"> Operating System: linux</span> -<span class="org-string"> Architecture: x86_64</span> -<span class="org-string">Resources:</span> -<span class="org-string"> CPUs: 0</span> -<span class="org-string"> Memory: 20 MiB</span> -<span class="org-string">Plugins:</span> -<span class="org-string"> Network: bridge, overlay</span> -<span class="org-string"> Volume: local</span> -<span class="org-string">Engine Version: 1.13.0</span> -<span class="org-string">Engine Labels:</span> -<span class="org-string"> - engine = label</span> -<span class="org-string">```</span> - <span class="org-rainbow-identifiers-identifier-3">buf</span> := <span class="org-builtin">new</span>(<span class="org-type">bytes.Buffer</span>) - <span class="org-rainbow-identifiers-identifier-3">cmd</span> := <span class="org-function-name">newInspectCommand</span>( - <span class="org-rainbow-identifiers-identifier-5">test</span>.<span class="org-function-name">NewFakeCli</span>(&<span class="org-type">fakeClient</span>{ - <span class="org-constant">nodeInspectFunc</span>: <span class="org-keyword">func</span>() (<span class="org-type">swarm.Node</span>, []<span class="org-type">byte</span>, <span class="org-type">error</span>) { - <span class="org-keyword">return</span> *<span class="org-function-name">Node</span>(<span class="org-function-name">Manager</span>()), []<span class="org-type">byte</span>{}, <span class="org-constant">nil</span> - }, - }, <span class="org-rainbow-identifiers-identifier-3">buf</span>)) - <span class="org-rainbow-identifiers-identifier-3">cmd</span>.<span class="org-function-name">SetArgs</span>([]<span class="org-type">string</span>{<span class="org-string">"nodeID"</span>}) - <span class="org-rainbow-identifiers-identifier-3">cmd</span>.<span class="org-function-name">Flags</span>().<span class="org-function-name">Set</span>(<span class="org-string">"pretty"</span>, <span class="org-string">"true"</span>) - <span class="org-rainbow-identifiers-identifier-11">assert</span>.<span class="org-function-name">NilError</span>(<span class="org-rainbow-identifiers-identifier-8">t</span>, <span class="org-rainbow-identifiers-identifier-3">cmd</span>.<span class="org-function-name">Execute</span>()) - <span class="org-rainbow-identifiers-identifier-15">actual</span> := <span class="org-rainbow-identifiers-identifier-3">buf</span>.<span class="org-function-name">String</span>() - <span class="org-rainbow-identifiers-identifier-11">assert</span>.<span class="org-function-name">EqualNormalizedString</span>(<span class="org-rainbow-identifiers-identifier-8">t</span>, <span class="org-rainbow-identifiers-identifier-11">assert</span>.<span class="org-rainbow-identifiers-identifier-2">RemoveSpace</span>, <span class="org-rainbow-identifiers-identifier-15">actual</span>, <span class="org-function-name">string</span>(<span class="org-rainbow-identifiers-identifier-14">expected</span>)) -} -</pre> -</div> - -<p> -This might look ok as is, but a few problem are present: -</p> - -<ul class="org-ul"> -<li>The output is quite large and adds some noise to the test</li> -<li><p> -Lot's of value in the <code>expected</code> string comes from default values -of our <code>Node</code> builder. -</p> - -<p> -This means any time we change our builder default values, we would -need to update this test, <i>painful</i>. -</p></li> -<li>If the output changes for a good reason (add a field, fix a typo, -…), this test has to be updated too.</li> -</ul> -</div> -</div> - -<div id="outline-container-org0519f3e" class="outline-2"> -<h2 id="org0519f3e">Golden files to the rescue</h2> -<div class="outline-text-2" id="text-org0519f3e"> -<p> -First, let's get back at what is our test about and what we actually -want to test. -</p> - -<ul class="org-ul"> -<li>We want to ensure, the output of the function does not change by -mistake (i.e. change that wasn't supposed to change the output)</li> -<li>We want to have an update version of the output if that was the -purpose of our change. And we want this update to be the least -painful possible.</li> -<li>We don't really care about the final outputs as long as it stays -the same for the same inputs (i.e. we don't test for any number of -space, or that word are valid English, or …).</li> -</ul> - -<p> -This is where the concept of <b>golden file</b> is useful. In a -nutshell, a golden file is a file where we store the output and that -will be used by the test as the expected output. This file should be -updated any time the output changes for good reason. That's that -simple 👼. -</p> - -<p> -Once again, the way go <code>testing</code> works, introducing and using golden -files in our tests is pretty straightforward and easy to use. -</p> - -<p> -Let's write a small <i>golden file helper</i> so that our test has no -visual noise, in a <code>golden</code> package. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">var</span> <span class="org-rainbow-identifiers-identifier-3">update</span> = <span class="org-rainbow-identifiers-identifier-15">flag</span>.<span class="org-function-name">Bool</span>(<span class="org-string">"test.update"</span>, <span class="org-constant">false</span>, <span class="org-string">"update golden file"</span>) - -<span class="org-comment-delimiter">// </span><span class="org-comment">Get returns the golden file content. If the `test.update` is specified, it updates the</span> -<span class="org-comment-delimiter">// </span><span class="org-comment">file with the current output and returns it.</span> -<span class="org-keyword">func</span> <span class="org-function-name">Get</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>, <span class="org-rainbow-identifiers-identifier-15">actual</span> []<span class="org-type">byte</span>, <span class="org-rainbow-identifiers-identifier-5">filename</span> <span class="org-type">string</span>) []<span class="org-type">byte</span> { - <span class="org-rainbow-identifiers-identifier-1">golden</span> := <span class="org-rainbow-identifiers-identifier-9">filepath</span>.<span class="org-function-name">Join</span>(<span class="org-string">"testdata"</span>, <span class="org-rainbow-identifiers-identifier-5">filename</span>) - <span class="org-keyword">if</span> *<span class="org-rainbow-identifiers-identifier-3">update</span> { - <span class="org-keyword">if</span> <span class="org-rainbow-identifiers-identifier-10">err</span> := <span class="org-rainbow-identifiers-identifier-1">ioutil</span>.<span class="org-function-name">WriteFile</span>(<span class="org-rainbow-identifiers-identifier-1">golden</span>, <span class="org-rainbow-identifiers-identifier-15">actual</span>, <span class="org-rainbow-identifiers-identifier-4">0644</span>); <span class="org-rainbow-identifiers-identifier-10">err</span> != <span class="org-constant">nil</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-rainbow-identifiers-identifier-10">err</span>) - } - } - <span class="org-rainbow-identifiers-identifier-14">expected</span>, <span class="org-rainbow-identifiers-identifier-10">err</span> := <span class="org-rainbow-identifiers-identifier-1">ioutil</span>.<span class="org-function-name">ReadFile</span>(<span class="org-rainbow-identifiers-identifier-1">golden</span>) - <span class="org-keyword">if</span> <span class="org-rainbow-identifiers-identifier-10">err</span> != <span class="org-constant">nil</span> { - <span class="org-rainbow-identifiers-identifier-8">t</span>.<span class="org-function-name">Fatal</span>(<span class="org-rainbow-identifiers-identifier-10">err</span>) - } - <span class="org-keyword">return</span> <span class="org-rainbow-identifiers-identifier-14">expected</span> -} -</pre> -</div> - -<ul class="org-ul"> -<li>We define a <i>global</i> flag, <code>-test.update</code> that will <i>enhance</i> the -<code>go test</code> command with it (as soon as we import this <code>golden</code> package).</li> -<li><p> -We define a <code>golden.Get</code> function that takes the current output -and the path of the golden file. It also takes <code>testing.T</code> so any -failure happening here (like reading file, …) will make the test -fail (one less thing to write in the test calling this function). -</p> - -<p> -If the flag is present when running the test, it will update the -file with the actual content. -</p></li> -</ul> - -<p> -The initial test becomes. -</p> - -<div class="org-src-container"> -<pre class="src src-go"><span class="org-keyword">func</span> <span class="org-function-name">TestNodeInspectPretty</span>(<span class="org-rainbow-identifiers-identifier-8">t</span> *<span class="org-type">testing.T</span>) { - <span class="org-rainbow-identifiers-identifier-3">buf</span> := <span class="org-builtin">new</span>(<span class="org-type">bytes.Buffer</span>) - <span class="org-rainbow-identifiers-identifier-3">cmd</span> := <span class="org-function-name">newInspectCommand</span>( - <span class="org-rainbow-identifiers-identifier-5">test</span>.<span class="org-function-name">NewFakeCli</span>(&<span class="org-type">fakeClient</span>{ - <span class="org-constant">nodeInspectFunc</span>: <span class="org-keyword">func</span>() (<span class="org-type">swarm.Node</span>, []<span class="org-type">byte</span>, <span class="org-type">error</span>) { - <span class="org-keyword">return</span> *<span class="org-function-name">Node</span>(<span class="org-function-name">Manager</span>()), []<span class="org-type">byte</span>{}, <span class="org-constant">nil</span> - }, - }, <span class="org-rainbow-identifiers-identifier-3">buf</span>)) - <span class="org-rainbow-identifiers-identifier-3">cmd</span>.<span class="org-function-name">SetArgs</span>([]<span class="org-type">string</span>{<span class="org-string">"nodeID"</span>}) - <span class="org-rainbow-identifiers-identifier-3">cmd</span>.<span class="org-function-name">Flags</span>().<span class="org-function-name">Set</span>(<span class="org-string">"pretty"</span>, <span class="org-string">"true"</span>) - <span class="org-rainbow-identifiers-identifier-11">assert</span>.<span class="org-function-name">NilError</span>(<span class="org-rainbow-identifiers-identifier-8">t</span>, <span class="org-rainbow-identifiers-identifier-3">cmd</span>.<span class="org-function-name">Execute</span>()) - <span class="org-rainbow-identifiers-identifier-15">actual</span> := <span class="org-rainbow-identifiers-identifier-3">buf</span>.<span class="org-function-name">String</span>() - <span class="org-rainbow-identifiers-identifier-14">expected</span> := <span class="org-rainbow-identifiers-identifier-1">golden</span>.<span class="org-function-name">Get</span>(<span class="org-rainbow-identifiers-identifier-8">t</span>, []<span class="org-function-name">byte</span>(<span class="org-rainbow-identifiers-identifier-15">actual</span>), <span class="org-string">"myfile.golden"</span>) - <span class="org-rainbow-identifiers-identifier-11">assert</span>.<span class="org-function-name">EqualNormalizedString</span>(<span class="org-rainbow-identifiers-identifier-8">t</span>, <span class="org-rainbow-identifiers-identifier-11">assert</span>.<span class="org-rainbow-identifiers-identifier-2">RemoveSpace</span>, <span class="org-rainbow-identifiers-identifier-15">actual</span>, <span class="org-function-name">string</span>(<span class="org-rainbow-identifiers-identifier-14">expected</span>)) -} -</pre> -</div> - -<p> -If we change the output, the workflow becomes the following : -</p> - -<ul class="org-ul"> -<li>run <code>go test</code> and make sure it's failing,</li> -<li>Validate that the current output is correct,</li> -<li>run <code>go test -test.update</code> to update the golden file(s),</li> -<li>re-run <code>go test</code> to make sure it's now green,</li> -<li>you are done 👼.</li> -</ul> - -<p> -With this simple trick, our test now <b>contains less noise</b> and is -way more <b>maintainable</b> (you just have a command to run to update -the expected content). -</p> -</div> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-07-28-gotest-tools-intro/" title="Golang testing — gotest.tools introduction">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2017-01-01-go-testing-functionnal-builders/" title="Golang testing — functional arguments for wonderful builders">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-07-28-gotest-tools-intro.org b/www/vincent.demeester.fr/content/legacy/posts/2018-07-28-gotest-tools-intro.org @@ -1,45 +0,0 @@ -#+TITLE: Golang testing — gotest.tools introduction -#+date: <2018-07-28 Sat> -#+filetags: feature go testing -#+setupfile: ../templates/post.org - -* Introduction - -I already wrote 2 previous posts about golang and testing. It's something I care deeply -about and I wanted to continue writing about it. It took me a bit more time than I -thought, but getting back to it. Since the [[http://vincent.demeester.fr/posts/2017-04-22-golang-testing-golden-file/][last post]], Daniel Nephin and I worked (but -mainly Daniel 🤗) on bootstrapping a testing helper library. - -Let me introduce it to you this library : [[https://gotest.tools][=gotest.tools=]]. As described in the [[https://godoc.org/gotest.tools][godoc]] package comment, =gotest.tools= is a -collection of packages to augment =testing= and support common patterns. It's an enhanced and growing version of the -initial helpers we (the docker/moby maintainers) wrote initially in [[https://github.com/docker/docker][=docker/docker=]] repository. We are using in quite some -project here at [[https://github.com][Docker]]. - -There is a bunch of packages that will all have their own post (linked here when available) : - -- [[file:2018-08-16-gotest-tools-assertions.org][=assert=]] (with =assert/cmp= and =assert/opt=) that provides assertions for comparing expected values to actual values. -- =env= that provides functions to test code that read environment variable or the current working directory. -- [[file:2018-09-14-gotest-tools-fs.org][=fs=]] that provides tools for creating temporary files, and testing the contents and structure of a directory. -- [[file:2018-09-06-gotest-tools-golden.org][=golden=]] that provides tools for comparing large multi-line strings. -- [[file:2018-09-18-gotest-tools-icmd.org][=icmd=]] that executes binaries and provides convenient assertions for testing the results. -- [[file:2019-03-23-gotest-tools-poll.org][=poll=]] that provides tools for testing asynchronous code. -- [[file:2018-09-01-gotest-tools-skip.org][=skip=]] that provides functions for skipping a test and printing the source code of the condition used to skip the test. - -There is also experimental package, using the =x= notation (as the golang team uses, for example with =golang.org/x/sync=) : - -- =x/subtest= that provides a =TestContext= to subtests which handles cleanup and provides a =testing.TB= and =context.Context=. - -There is already some good =testing= helpers in the Go ecosystem : [[https://github.com/stretchr/testify][=testify=]], [[http://labix.org/gocheck][=gocheck=]], [[https://github.com/onsi/ginkgo][=ginkgo=]] and a lot more — so -why create a new one ? There is multiple reason for it, most of them can be seen in the following [[https://github.com/gotestyourself/gotest.tools/issues/49#issuecomment-362436026][GitHub issue]]. - -[[https://github.com/dnephin/][Daniel]] also wrote a very useful converter if your code base is currently using =testify= : =gty-migrate-from-testify=. - -#+BEGIN_SRC sh -$ go get -u gotest.tools/assert/cmd/gty-migrate-from-testify -# […] -$ go list \ - -f '{{.ImportPath}} {{if .XTestGoFiles}}{{"\n"}}{{.ImportPath}}_test{{end}}' \ - ./... | xargs gty-migrate-from-testify -#+END_SRC - -In the next post, let's dig into the assertion part of the library, package =assert= 👼. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-07-28-gotest-tools-intro/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-07-28-gotest-tools-intro/index.html @@ -1,154 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-07-28-gotest-tools-intro/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools introduction</h1><a href='https://vincent.demeester.fr/posts/2018-07-28-gotest-tools-intro/'></a> - <address class="signature"> - <span class="date">Sat, 28 July, 2018</span> - <span class="words">(400 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-featured"><a href="/tags/#featured">featured<span>2</span></a></li> - - <br/> - - </ul> - </header> - - I already wrote 2 previous posts about golang and testing. It’s something I care deeply about and I wanted to continue - writing about it. It took me a bit more time than I thought, but getting back to it. Since the <a href="http://vincent.demeester.fr/posts/2017-04-22-golang-testing-golden-file/">last post</a>, Daniel Nephin - and I worked (but mainly Daniel 🤗) on bootstrapping a testing helper library. - - <p>Let me introduce it to you this library : <a href="https://gotest.tools"><code>gotest.tools</code></a>. As described in the <a href="https://godoc.org/gotest.tools">godoc</a> package comment, <code>gotest.tools</code> is a -collection of packages to augment <code>testing</code> and support common patterns. It’s an enhanced and growing version of the -initial helpers we (the docker/moby maintainers) wrote initially in <a href="https://github.com/docker/docker"><code>docker/docker</code></a> repository. We are using in quite some -project here at <a href="https://github.com">Docker</a>.</p> - -<p>There is a bunch of packages that will all have their own post (linked here when available) :</p> - -<ul> -<li><a href="/posts/2018-08-16-gotest-tools-assertions/"><code>assert</code></a> (with <code>assert/cmp</code> and <code>assert/opt</code>) that provides assertions for comparing expected values to actual values.</li> -<li><code>env</code> that provides functions to test code that read environment variable or the current working directory.</li> -<li><a href="/posts/2018-09-14-gotest-tools-fs/"><code>fs</code></a> that provides tools for creating temporary files, and testing the contents and structure of a directory.</li> -<li><a href="/posts/2018-09-06-gotest-tools-golden/"><code>golden</code></a> that provides tools for comparing large multi-line strings.</li> -<li><a href="/posts/2018-09-18-gotest-tools-icmd/"><code>icmd</code></a> that executes binaries and provides convenient assertions for testing the results.</li> -<li><code>poll</code> that provides tools for testing asynchronous code.</li> -<li><a href="/posts/2018-09-01-gotest-tools-skip/"><code>skip</code></a> that provides functions for skipping a test and printing the source code of the condition used to skip the test.</li> -</ul> - -<p>There is also experimental package, using the <code>x</code> notation (as the golang team uses, for example with <code>golang.org/x/sync</code>) :</p> - -<ul> -<li><code>x/subtest</code> that provides a <code>TestContext</code> to subtests which handles cleanup and provides a <code>testing.TB</code> and <code>context.Context</code>.</li> -</ul> - -<p>There is already some good <code>testing</code> helpers in the Go ecosystem : <a href="https://github.com/stretchr/testify"><code>testify</code></a>, <a href="http://labix.org/gocheck"><code>gocheck</code></a>, <a href="https://github.com/onsi/ginkgo"><code>ginkgo</code></a> and a lot more — so -why create a new one ? There is multiple reason for it, most of them can be seen in the following <a href="https://github.com/gotestyourself/gotest.tools/issues/49#issuecomment-362436026">GitHub issue</a>.</p> - -<p><a href="https://github.com/dnephin/">Daniel</a> also wrote a very useful converter if your code base is currently using <code>testify</code> : <code>gty-migrate-from-testify</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">$ go get -u gotest.tools/assert/cmd/gty-migrate-from-testify -<span class="c1"># […]</span> -$ go list <span class="se">\ -</span><span class="se"></span> -f <span class="s1">'{{.ImportPath}} {{if .XTestGoFiles}}{{"\n"}}{{.ImportPath}}_test{{end}}'</span> <span class="se">\ -</span><span class="se"></span> ./... <span class="p">|</span> xargs gty-migrate-from-testify</code></pre></div> -<p>In the next post, let’s dig into the assertion part of the library, package <code>assert</code> 👼.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-08-16-gotest-tools-assertions/" title="Golang testing — gotest.tools assertions">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2017-04-22-golang-testing-golden-file/" title="Golang testing — golden file">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-08-16-gotest-tools-assertions.org b/www/vincent.demeester.fr/content/legacy/posts/2018-08-16-gotest-tools-assertions.org @@ -1,340 +0,0 @@ -#+title: Golang testing — gotest.tools assertions -#+date: <2018-08-16 Thu> -#+filetags: go testing assert -#+setupfile: ../templates/post.org - -#+TOC: headlines 2 - -* Introduction - -Let's take a closer look at [[https://gotest.tools][=gotest.tools=]] assertions packages. This is mainly about =assert=, =assert/cmp= and -=assert/opt=. - -#+BEGIN_QUOTE -Package assert provides assertions for comparing expected values to actual values. When assertion fails a helpful error -message is printed. -#+END_QUOTE - -There is two main functions (=Assert= and =Check=) and some helpers (like =NilError=, …). They all take a =*testing.T= as -a first argument, pretty common across testing Go libraries. Let's dive into those ! - -* =Assert= and =Check= - -Both those functions accept a =Comparison= (we'll check what it is later on) and fail the test when that comparison -fails. The one difference is that =Assert= will end the test execution at immediately whereas =Check= will fail the test -and proceed with the rest of the test case. This is similar to =FailNow= and =Fail= from the standard library -=testing=. Both have their use cases. - -We'll Use =Assert= for the rest of the section but any example here would work with =Check= too. When we said -=Comparison= above, it's mainly the [[https://godoc.org/gotest.tools/assert#BoolOrComparison][BoolOrComparison]] interface — it can either be a boolean expression, or a -[[https://godoc.org/gotest.tools/assert/cmp#Comparison][cmp.Comparison]] type. =Assert= and =Check= code will be /smart/ enough to detect which one it is. - -#+BEGIN_SRC go - assert.Assert(t, ok) - assert.Assert(t, err != nil) - assert.Assert(t, foo.IsBar()) -#+END_SRC - -So far not anything extra-ordinary. Let's first look at some more /helper/ functions in the =assert= package and quickly -dive a bit deeper with =Comparison=. - -* More =assert= helpers - -The additional helper functions are the following - -- =Equal= uses the ==== operator to assert two values are equal. -- =DeepEqual= uses =google/go-cmp= to assert two values are equal (it's /close/ to =reflect.DeepEqual= but not - quite). We'll detail a bit more the /options/ part of this function with =cmp.DeepEqual=. -- =Error= fails if the error is =nil= *or* the error message is not the expected one. -- =ErrorContains= fails if the error is =nil= *or* the error message does not contain the expected substring. -- =ErrorType= fails if the error is =nil= *or* the error type is not the expected type. -- =NilError= fails if the error is not =nil=. - -All those helper functions have a equivalent function in the =cmp= package that returns a =Comparison=. I, personally, -prefer to use =assert.Check= or =assert.Assert= in combination with =cmp.Comparison= as it allows me to write all my -assertions the same way, with built-ins comparison or with my own — i.e. =assert.Assert(t, is.Equal(…), "message"= or -=assert.Assert(t, stackIsUp(c, time…), "another message")=. - -* =cmp.Comparison= - -This is where it get really interesting, =gotest.tools= tries to make it as easy as possible for you to create -appropriate comparison — making you test readable as much as possible. - -Let's look a bit at the =cmp.Comparison= type. - -#+BEGIN_SRC go -type Comparison func() Result -#+END_SRC - -It's just a function that returns a =cmp.Result=, so let's look at =cmp.Result= definition. - -#+BEGIN_SRC go -type Result interface { - Success() bool -} -#+END_SRC - -Result is an =interface=, thus any /struct/ that provide a function =Success= that returns a =bool= can be used as a -comparison result, making it really easy to use in your code. There is also existing type of result to make it even -quicker to write your own comparison. - -- =ResultSuccess= is a constant which is returned to indicate success. -- =ResultFailure= and =ResultFailureTemplate= return a failed Result with a failure message. -- =ResultFromError= returns =ResultSuccess= if =err= is nil. Otherwise =ResultFailure= is returned with the error - message as the failure message. It works a bit like the =errors.Wrap= function of the [[https://github.com/pkg/errors][=github.com/pkgs/errors=]] - package. - -The =cmp= package comes with a few defined comparison that, we think, should cover a high number of use-cases. Let's -look at them. - -** Equality with =Equal= and =DeepEqual= - -#+BEGIN_QUOTE -Equal uses the == operator to assert two values are equal and fails the test if they are not equal. - -If the comparison fails Equal will use the variable names for x and y as part of the failure message to identify the -actual and expected values. - -If either x or y are a multi-line string the failure message will include a unified diff of the two values. If the -values only differ by whitespace the unified diff will be augmented by replacing whitespace characters with visible -characters to identify the whitespace difference. -#+END_QUOTE - -On the other hand… - -#+BEGIN_QUOTE -DeepEqual uses google/go-cmp (http://bit.do/go-cmp) to assert two values are equal and fails the test if they are not -equal. - -Package https://godoc.org/gotest.tools/assert/opt provides some additional commonly used Options. -#+END_QUOTE - -Using one or the other is as simple as : if you wrote your =if= with ==== then use =Equal=, otherwise use =DeepEqual=. -=DeepEqual= (and usually =reflect.DeepEqual=) is used when you want to compare anything more complex than primitive -types. One advantage of using =cmp.DeepEqual= over =reflect.DeepEqual= (in an if), is that you get a well crafted -message that shows the diff between the expected and the actual structs compared – and you can pass options to it. - -#+BEGIN_SRC go -assert.Assert(t, cmp.DeepEqual([]string{"a", "b"}, []string{"b", "a"})) -// Will print something like -// --- result -// +++ exp -// {[]string}[0]: -// -: "a" -// +: "b" -// {[]string}[1]: -// -: "b" -// +: "a" -foo := &someType(a: "with", b: "value") -bar := &someType(a: "with", b: "value") -// the following will succeed as foo and bar are _DeepEqual_ -assert.Assert(t, cmp.DeepEqual(foo, bar)) -#+END_SRC - -When using =DeepEqual=, you may end up with really weird behavior(s). You may want to ignore some fields, or consider -=nil= slice or map the same as empty ones ; or more common, your /struct/ contains some unexported fields that you -cannot use when comparing (as they are not exported 😓). In those case, you can use =go-cmp= options. - -Some existing one are : -- [[https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#EquateEmpty][=EquateEmpty=]] returns a Comparer option that determines all maps and slices with a length of zero to be equal, - regardless of whether they are nil. -- [[https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#IgnoreFields][=IgnoreFields=]] returns an Option that ignores exported fields of the given names on a single struct type. The struct - type is specified by passing in a value of that type. -- [[https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#IgnoreUnexported][=IgnoreUnexported=]] returns an Option that only ignores the immediate unexported fields of a struct, including anonymous - fields of unexported types. -- [[https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#SortSlices][=SortSlices=]] returns a Transformer option that sorts all =[]V= -- … and [[https://godoc.org/github.com/google/go-cmp/cmp/cmpopts][more]] 👼 - -=gotest.tools= also defines some *and* you can define yours ! As an example, =gotest.tools= defines =TimeWithThreshold= -and =DurationWithThreshold= that allows to not fails if the time (or duration) is not exactly the same but in the -specified threshold we specified. Here is the code for =DurationWithThreshold= for inspiration. - -#+BEGIN_SRC go -// DurationWithThreshold returns a gocmp.Comparer for comparing time.Duration. The -// Comparer returns true if the difference between the two Duration values is -// within the threshold and neither value is zero. -func DurationWithThreshold(threshold time.Duration) gocmp.Option { - return gocmp.Comparer(cmpDuration(threshold)) -} - -func cmpDuration(threshold time.Duration) func(x, y time.Duration) bool { - return func(x, y time.Duration) bool { - if x == 0 || y == 0 { - return false - } - delta := x - y - return delta <= threshold && delta >= -threshold - } -} -#+END_SRC - -Another good example for those options is when you want to skip some field. In [[https://github.com/docker/docker][=docker/docker=]] we want to be able to -easily check for equality between two service specs, but those might have different =CreatedAt= and =UpdatedAt= values -that we usually don't care about – what we want is to make sure it happens in the past 20 seconds. You can easily define -an option for that. - -#+BEGIN_SRC go - func cmpServiceOpts() cmp.Option { - const threshold = 20 * time.Second - - // Apply withinThreshold only for the following fields - metaTimeFields := func(path cmp.Path)bool { - switch path.String() { - case "Meta.CreatedAt", "Meta.UpdatedAt": - return true - } - return false - } - // have a 20s threshold for the time value that will be passed - withinThreshold := cmp.Comparer(func(x, y time.Time) bool { - delta := x.Sub(y) - return delta < threshold && delta > -threshold - }) - - return cmp.FilterPath(metaTimeFields, withinThreshold) - } -#+END_SRC - -I recommend you look at the [[https://godoc.org/gotest.tools/assert/opt][gotest.tools/assert/opt]] documentation to see which one are defined and how to use them. - -** Errors with =Error=, =ErrorContains= and =ErrorType= - -Checking for errors is *very common* in Go, having =Comparison= function for it was a requirement. - -- =Error= fails if the error is =nil= *or* the error message is not the expected one. -- =ErrorContains= fails if the error is =nil= *or* the error message does not contain the expected substring. -- =ErrorType= fails if the error is =nil= *or* the error type is not the expected type. - -Let's first look at the most used : =Error= and =ErrorContains=. - -#+BEGIN_SRC go - var err error - // will fail with : expected an error, got nil - assert.Check(t, cmp.Error(err, "message in a bottle")) - err = errors.Wrap(errors.New("other"), "wrapped") - // will fail with : expected error "other", got "wrapped: other" - assert.Check(t, cmp.Error(err, "other")) - // will succeed - assert.Check(t, cmp.ErrorContains(err, "other")) -#+END_SRC - -As you can see =ErrorContains= is especially useful when working with /wrapped/ errors. -Now let's look at =ErrorType=. - -#+BEGIN_SRC go - var err error - // will fail with : error is nil, not StubError - assert.Check(t, cmp.ErrorType(err, StubError{})) - - err := StubError{"foo"} - // will succeed - assert.Check(t, cmp.ErrorType(err, StubError{})) - - // Note that it also work with a function returning an error - func foo() error {} - assert.Check(t, cmp.ErrorType(foo, StubError{})) -#+END_SRC - -** Bonus with =Panics= - -Sometimes, a code is supposed to /panic/, see [[https://golang.org/doc/effective_go.html#panic][Effective Go (#Panic)]] for more information. And thus, you may want to make -sure you're code panics in such cases. It's always a bit tricky to test a code that panic as you have to use a deferred -function to recover the panic — but then if the panic doesn't happen how do you fail the test ? - -This is where =Panics= comes handy. - -#+BEGIN_SRC go - func foo(shouldPanic bool) { - if shouldPanic { - panic("booooooooooh") - } - // don't worry, be happy - } - // will fail with : did not panic - assert.Check(t, cmp.Panics(foo(false))) - // will succeed - assert.Check(t, cmp.Panics(foo(true))) -#+END_SRC - -** Miscellaneous with =Contains=, =Len= and =Nil= - -Those last three /built-in/ =Comparison= are pretty straightforward. - -- =Contains= succeeds if item is in collection. Collection may be a string, map, slice, or array. - - If collection is a string, item must also be a string, and is compared using =strings.Contains()=. If collection is a - Map, contains will succeed if item is a key in the map. If collection is a slice or array, item is compared to each - item in the sequence using ==reflect.DeepEqual()==. -- =Len= succeeds if the sequence has the expected length. -- =Nil= succeeds if obj is a nil interface, pointer, or function. - -#+BEGIN_SRC go - // Contains works on string, map, slice or arrays - assert.Check(t, cmp.Contains("foobar", "foo")) - assert.Check(t, cmp.Contains([]string{"a", "b", "c"}, "b")) - assert.Check(t, cmp.Contains(map[string]int{"a": 1, "b": 2, "c": 4}, "b")) - - // Len also works on string, map, slice or arrays - assert.Check(t, cmp.Len("foobar", 6)) - assert.Check(t, cmp.Len([]string{"a", "b", "c"}, 3)) - assert.Check(t, cmp.Len(map[string]int{"a": 1, "b": 2, "c": 4}, 3)) - - // Nil - var foo *MyStruc - assert.Check(t, cmp.Nil(foo)) - assert.Check(t, cmp.Nil(bar())) -#+END_SRC - -But let's not waste more time and let's see how to write our own =Comparison= ! - -** Write your own =Comparison= - -One of the main aspect of =gotest.tools/assert= is to make it easy for developer to write as less boilerplate code as -possible while writing tests. Writing your own =Comparison= allows you to write a well named function that will be easy -to read and that can be re-used across your tests. - -Let's look back at the =cmp.Comparison= and =cmp.Result= types. - -#+BEGIN_SRC go -type Comparison func() Result - -type Result interface { - Success() bool -} -#+END_SRC - -A =Comparison= for =assert.Check= or =assert.Check= is a function that return a =Result=, it's pretty straightforward to -implement, especially with =cmp.ResultSuccess= and =cmp.ResultFailure(…)= (as seen previously). - -#+BEGIN_SRC go - func regexPattern(value string, pattern string) cmp.Comparison { - return func() cmp.Result { - re := regexp.MustCompile(pattern) - if re.MatchString(value) { - return cmp.ResultSuccess - } - return cmp.ResultFailure( - fmt.Sprintf("%q did not match pattern %q", value, pattern)) - } - } - - // To use it - assert.Check(t, regexPattern("12345.34", `\d+.\d\d`)) -#+END_SRC - -As you can see, it's pretty easy to implement, and you can do quite a lot in there easily. If a function call returns an -error inside of your =Comparison= function, you can use =cmp.ResultFromError= for example. Having something like -=assert.Check(t, isMyServerUp(":8080"))= is way more readable than a 30-line of code to check it. - -* Conclusion… - -… and that's a wrap. We only looked at the =assert= package of [[https://gotest.tools][=gotest.tools=]] so far, but it's already quite a bit to process. - -We've seen : -- the main functions provided by this package : =assert.Assert= and =assert.Check= -- some helper functions like =assert.NilError=, … -- the =assert/cmp=, and =assert/opt= sub-package that allows you to write more custom =Comparison= - -Next time, we'll look at the =skip= package, that is a really simple wrapper on top of =testing.Skip= function. - -** diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-08-16-gotest-tools-assertions/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-08-16-gotest-tools-assertions/index.html @@ -1,443 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-08-16-gotest-tools-assertions/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools assertions</h1><a href='https://vincent.demeester.fr/posts/2018-08-16-gotest-tools-assertions/'></a> - <address class="signature"> - <span class="date">Thu, 16 August, 2018</span> - <span class="words">(2000 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-assert"><a href="/tags/#assert">assert<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>Faster way to send the same command to each and every <em>pane</em> in your - tmux <em>session</em>.</p> - -<p>Let’s take a closer look at <a href="https://gotest.tools"><code>gotest.tools</code></a> assertions packages. This is mainly about <code>assert</code>, <code>assert/cmp</code> and - <code>assert/opt</code>.</p> - -<blockquote> -<p>Package assert provides assertions for comparing expected values to actual values. When assertion fails a helpful error -message is printed.</p> -</blockquote> - -<p>There is two main functions (<code>Assert</code> and <code>Check</code>) and some helpers (like <code>NilError</code>, …). They all take a <code>*testing.T</code> as - a first argument, pretty common across testing Go libraries. Let’s dive into those !</p> - - - - -<div class="ox-hugo-toc toc"> -<div></div> - -<div class="heading">Table of Contents</div> - -<ul> -<li><a href="#assert-and-check"><code>Assert</code> and <code>Check</code></a></li> -<li><a href="#more-assert-helpers">More <code>assert</code> helpers</a></li> -<li><a href="#cmp-dot-comparison"><code>cmp.Comparison</code></a> - -<ul> -<li><a href="#equality-with-equal-and-deepequal">Equality with <code>Equal</code> and <code>DeepEqual</code></a></li> -<li><a href="#errors-with-error-errorcontains-and-errortype">Errors with <code>Error</code>, <code>ErrorContains</code> and <code>ErrorType</code></a></li> -<li><a href="#bonus-with-panics">Bonus with <code>Panics</code></a></li> -<li><a href="#miscellaneous-with-contains-len-and-nil">Miscellaneous with <code>Contains</code>, <code>Len</code> and <code>Nil</code></a></li> -<li><a href="#write-your-own-comparison">Write your own <code>Comparison</code></a></li> -</ul></li> -<li><a href="#conclusion">Conclusion…</a></li> -</ul> - -<p></div> -<!--endtoc--></p> - -<h2 id="assert-and-check"><code>Assert</code> and <code>Check</code></h2> - -<p>Both those functions accept a <code>Comparison</code> (we’ll check what it is later on) and fail the test when that comparison -fails. The one difference is that <code>Assert</code> will end the test execution at immediately whereas <code>Check</code> will fail the test -and proceed with the rest of the test case. This is similar to <code>FailNow</code> and <code>Fail</code> from the standard library -<code>testing</code>. Both have their use cases.</p> - -<p>We’ll Use <code>Assert</code> for the rest of the section but any example here would work with <code>Check</code> too. When we said -<code>Comparison</code> above, it’s mainly the <a href="https://godoc.org/gotest.tools/assert#BoolOrComparison">BoolOrComparison</a> interface — it can either be a boolean expression, or a -<a href="https://godoc.org/gotest.tools/assert/cmp#Comparison">cmp.Comparison</a> type. <code>Assert</code> and <code>Check</code> code will be <em>smart</em> enough to detect which one it is.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">ok</span><span class="p">)</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span><span class="p">)</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">foo</span><span class="p">.</span><span class="nf">IsBar</span><span class="p">())</span></code></pre></div> -<p>So far not anything extra-ordinary. Let’s first look at some more <em>helper</em> functions in the <code>assert</code> package and quickly -dive a bit deeper with <code>Comparison</code>.</p> - -<h2 id="more-assert-helpers">More <code>assert</code> helpers</h2> - -<p>The additional helper functions are the following</p> - -<ul> -<li><code>Equal</code> uses the <code>==</code> operator to assert two values are equal.</li> -<li><code>DeepEqual</code> uses <code>google/go-cmp</code> to assert two values are equal (it’s <em>close</em> to <code>reflect.DeepEqual</code> but not -quite). We’ll detail a bit more the <em>options</em> part of this function with <code>cmp.DeepEqual</code>.</li> -<li><code>Error</code> fails if the error is <code>nil</code> <strong>or</strong> the error message is not the expected one.</li> -<li><code>ErrorContains</code> fails if the error is <code>nil</code> <strong>or</strong> the error message does not contain the expected substring.</li> -<li><code>ErrorType</code> fails if the error is <code>nil</code> <strong>or</strong> the error type is not the expected type.</li> -<li><code>NilError</code> fails if the error is not <code>nil</code>.</li> -</ul> - -<p>All those helper functions have a equivalent function in the <code>cmp</code> package that returns a <code>Comparison</code>. I, personally, -prefer to use <code>assert.Check</code> or <code>assert.Assert</code> in combination with <code>cmp.Comparison</code> as it allows me to write all my -assertions the same way, with built-ins comparison or with my own — i.e. <code>assert.Assert(t, is.Equal(…), "message"</code> or -<code>assert.Assert(t, stackIsUp(c, time…), "another message")</code>.</p> - -<h2 id="cmp-dot-comparison"><code>cmp.Comparison</code></h2> - -<p>This is where it get really interesting, <code>gotest.tools</code> tries to make it as easy as possible for you to create -appropriate comparison — making you test readable as much as possible.</p> - -<p>Let’s look a bit at the <code>cmp.Comparison</code> type.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Comparison</span> <span class="kd">func</span><span class="p">()</span> <span class="nx">Result</span></code></pre></div> -<p>It’s just a function that returns a <code>cmp.Result</code>, so let’s look at <code>cmp.Result</code> definition.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Result</span> <span class="kd">interface</span> <span class="p">{</span> - <span class="nf">Success</span><span class="p">()</span> <span class="kt">bool</span> -<span class="p">}</span></code></pre></div> -<p>Result is an <code>interface</code>, thus any <em>struct</em> that provide a function <code>Success</code> that returns a <code>bool</code> can be used as a -comparison result, making it really easy to use in your code. There is also existing type of result to make it even -quicker to write your own comparison.</p> - -<ul> -<li><code>ResultSuccess</code> is a constant which is returned to indicate success.</li> -<li><code>ResultFailure</code> and <code>ResultFailureTemplate</code> return a failed Result with a failure message.</li> -<li><code>ResultFromError</code> returns <code>ResultSuccess</code> if <code>err</code> is nil. Otherwise <code>ResultFailure</code> is returned with the error -message as the failure message. It works a bit like the <code>errors.Wrap</code> function of the <a href="https://github.com/pkg/errors"><code>github.com/pkgs/errors</code></a> -package.</li> -</ul> - -<p>The <code>cmp</code> package comes with a few defined comparison that, we think, should cover a high number of use-cases. Let’s -look at them.</p> - -<h3 id="equality-with-equal-and-deepequal">Equality with <code>Equal</code> and <code>DeepEqual</code></h3> - -<blockquote> -<p>Equal uses the == operator to assert two values are equal and fails the test if they are not equal.</p> - -<p>If the comparison fails Equal will use the variable names for x and y as part of the failure message to identify the -actual and expected values.</p> - -<p>If either x or y are a multi-line string the failure message will include a unified diff of the two values. If the -values only differ by whitespace the unified diff will be augmented by replacing whitespace characters with visible -characters to identify the whitespace difference.</p> -</blockquote> - -<p>On the other hand…</p> - -<blockquote> -<p>DeepEqual uses google/go-cmp (<a href="http://bit.do/go-cmp">http://bit.do/go-cmp</a>) to assert two values are equal and fails the test if they are not -equal.</p> - -<p>Package <a href="https://godoc.org/gotest.tools/assert/opt">https://godoc.org/gotest.tools/assert/opt</a> provides some additional commonly used Options.</p> -</blockquote> - -<p>Using one or the other is as simple as : if you wrote your <code>if</code> with <code>==</code> then use <code>Equal</code>, otherwise use <code>DeepEqual</code>. -<code>DeepEqual</code> (and usually <code>reflect.DeepEqual</code>) is used when you want to compare anything more complex than primitive -types. One advantage of using <code>cmp.DeepEqual</code> over <code>reflect.DeepEqual</code> (in an if), is that you get a well crafted -message that shows the diff between the expected and the actual structs compared – and you can pass options to it.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">DeepEqual</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"a"</span><span class="p">,</span> <span class="s">"b"</span><span class="p">},</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"b"</span><span class="p">,</span> <span class="s">"a"</span><span class="p">}))</span> -<span class="c1">// Will print something like -</span><span class="c1">// --- result -</span><span class="c1">// +++ exp -</span><span class="c1">// {[]string}[0]: -</span><span class="c1">// -: "a" -</span><span class="c1">// +: "b" -</span><span class="c1">// {[]string}[1]: -</span><span class="c1">// -: "b" -</span><span class="c1">// +: "a" -</span><span class="c1"></span><span class="nx">foo</span> <span class="o">:=</span> <span class="o">&</span><span class="nf">someType</span><span class="p">(</span><span class="nx">a</span><span class="p">:</span> <span class="s">"with"</span><span class="p">,</span> <span class="nx">b</span><span class="p">:</span> <span class="s">"value"</span><span class="p">)</span> -<span class="nx">bar</span> <span class="o">:=</span> <span class="o">&</span><span class="nf">someType</span><span class="p">(</span><span class="nx">a</span><span class="p">:</span> <span class="s">"with"</span><span class="p">,</span> <span class="nx">b</span><span class="p">:</span> <span class="s">"value"</span><span class="p">)</span> -<span class="c1">// the following will succeed as foo and bar are _DeepEqual_ -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">DeepEqual</span><span class="p">(</span><span class="nx">foo</span><span class="p">,</span> <span class="nx">bar</span><span class="p">))</span></code></pre></div> -<p>When using <code>DeepEqual</code>, you may end up with really weird behavior(s). You may want to ignore some fields, or consider -<code>nil</code> slice or map the same as empty ones ; or more common, your <em>struct</em> contains some unexported fields that you -cannot use when comparing (as they are not exported 😓). In those case, you can use <code>go-cmp</code> options.</p> - -<p>Some existing one are :</p> - -<ul> -<li><a href="https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#EquateEmpty"><code>EquateEmpty</code></a> returns a Comparer option that determines all maps and slices with a length of zero to be equal, -regardless of whether they are nil.</li> -<li><a href="https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#IgnoreFields"><code>IgnoreFields</code></a> returns an Option that ignores exported fields of the given names on a single struct type. The struct -type is specified by passing in a value of that type.</li> -<li><a href="https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#IgnoreUnexported"><code>IgnoreUnexported</code></a> returns an Option that only ignores the immediate unexported fields of a struct, including anonymous -fields of unexported types.</li> -<li><a href="https://godoc.org/github.com/google/go-cmp/cmp/cmpopts#SortSlices"><code>SortSlices</code></a> returns a Transformer option that sorts all <code>[]V</code></li> -<li>… and <a href="https://godoc.org/github.com/google/go-cmp/cmp/cmpopts">more</a> 👼</li> -</ul> - -<p><code>gotest.tools</code> also defines some <strong>and</strong> you can define yours ! As an example, <code>gotest.tools</code> defines <code>TimeWithThreshold</code> -and <code>DurationWithThreshold</code> that allows to not fails if the time (or duration) is not exactly the same but in the -specified threshold we specified. Here is the code for <code>DurationWithThreshold</code> for inspiration.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="c1">// DurationWithThreshold returns a gocmp.Comparer for comparing time.Duration. The -</span><span class="c1">// Comparer returns true if the difference between the two Duration values is -</span><span class="c1">// within the threshold and neither value is zero. -</span><span class="c1"></span><span class="kd">func</span> <span class="nf">DurationWithThreshold</span><span class="p">(</span><span class="nx">threshold</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">)</span> <span class="nx">gocmp</span><span class="p">.</span><span class="nx">Option</span> <span class="p">{</span> - <span class="k">return</span> <span class="nx">gocmp</span><span class="p">.</span><span class="nf">Comparer</span><span class="p">(</span><span class="nf">cmpDuration</span><span class="p">(</span><span class="nx">threshold</span><span class="p">))</span> -<span class="p">}</span> - -<span class="kd">func</span> <span class="nf">cmpDuration</span><span class="p">(</span><span class="nx">threshold</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">)</span> <span class="kd">func</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">)</span> <span class="kt">bool</span> <span class="p">{</span> - <span class="k">return</span> <span class="kd">func</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">)</span> <span class="kt">bool</span> <span class="p">{</span> - <span class="k">if</span> <span class="nx">x</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">y</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">{</span> - <span class="k">return</span> <span class="kc">false</span> - <span class="p">}</span> - <span class="nx">delta</span> <span class="o">:=</span> <span class="nx">x</span> <span class="o">-</span> <span class="nx">y</span> - <span class="k">return</span> <span class="nx">delta</span> <span class="o"><=</span> <span class="nx">threshold</span> <span class="o">&&</span> <span class="nx">delta</span> <span class="o">>=</span> <span class="o">-</span><span class="nx">threshold</span> - <span class="p">}</span> -<span class="p">}</span></code></pre></div> -<p>Another good example for those options is when you want to skip some field. In <a href="https://github.com/docker/docker"><code>docker/docker</code></a> we want to be able to -easily check for equality between two service specs, but those might have different <code>CreatedAt</code> and <code>UpdatedAt</code> values -that we usually don’t care about – what we want is to make sure it happens in the past 20 seconds. You can easily define -an option for that.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">cmpServiceOpts</span><span class="p">()</span> <span class="nx">cmp</span><span class="p">.</span><span class="nx">Option</span> <span class="p">{</span> - <span class="kd">const</span> <span class="nx">threshold</span> <span class="p">=</span> <span class="mi">20</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Second</span> - - <span class="c1">// Apply withinThreshold only for the following fields -</span><span class="c1"></span> <span class="nx">metaTimeFields</span> <span class="o">:=</span> <span class="kd">func</span><span class="p">(</span><span class="nx">path</span> <span class="nx">cmp</span><span class="p">.</span><span class="nx">Path</span><span class="p">)</span><span class="kt">bool</span> <span class="p">{</span> - <span class="k">switch</span> <span class="nx">path</span><span class="p">.</span><span class="nf">String</span><span class="p">()</span> <span class="p">{</span> - <span class="k">case</span> <span class="s">"Meta.CreatedAt"</span><span class="p">,</span> <span class="s">"Meta.UpdatedAt"</span><span class="p">:</span> - <span class="k">return</span> <span class="kc">true</span> - <span class="p">}</span> - <span class="k">return</span> <span class="kc">false</span> - <span class="p">}</span> - <span class="c1">// have a 20s threshold for the time value that will be passed -</span><span class="c1"></span> <span class="nx">withinThreshold</span> <span class="o">:=</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Comparer</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="p">)</span> <span class="kt">bool</span> <span class="p">{</span> - <span class="nx">delta</span> <span class="o">:=</span> <span class="nx">x</span><span class="p">.</span><span class="nf">Sub</span><span class="p">(</span><span class="nx">y</span><span class="p">)</span> - <span class="k">return</span> <span class="nx">delta</span> <span class="p"><</span> <span class="nx">threshold</span> <span class="o">&&</span> <span class="nx">delta</span> <span class="p">></span> <span class="o">-</span><span class="nx">threshold</span> - <span class="p">})</span> - - <span class="k">return</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">FilterPath</span><span class="p">(</span><span class="nx">metaTimeFields</span><span class="p">,</span> <span class="nx">withinThreshold</span><span class="p">)</span> -<span class="p">}</span></code></pre></div> -<p>I recommend you look at the <a href="https://godoc.org/gotest.tools/assert/opt">gotest.tools/assert/opt</a> documentation to see which one are defined and how to use them.</p> - -<h3 id="errors-with-error-errorcontains-and-errortype">Errors with <code>Error</code>, <code>ErrorContains</code> and <code>ErrorType</code></h3> - -<p>Checking for errors is <strong>very common</strong> in Go, having <code>Comparison</code> function for it was a requirement.</p> - -<ul> -<li><code>Error</code> fails if the error is <code>nil</code> <strong>or</strong> the error message is not the expected one.</li> -<li><code>ErrorContains</code> fails if the error is <code>nil</code> <strong>or</strong> the error message does not contain the expected substring.</li> -<li><code>ErrorType</code> fails if the error is <code>nil</code> <strong>or</strong> the error type is not the expected type.</li> -</ul> - -<p>Let’s first look at the most used : <code>Error</code> and <code>ErrorContains</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">var</span> <span class="nx">err</span> <span class="kt">error</span> -<span class="c1">// will fail with : expected an error, got nil -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Error</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="s">"message in a bottle"</span><span class="p">))</span> -<span class="nx">err</span> <span class="p">=</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">Wrap</span><span class="p">(</span><span class="nx">errors</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">"other"</span><span class="p">),</span> <span class="s">"wrapped"</span><span class="p">)</span> -<span class="c1">// will fail with : expected error "other", got "wrapped: other" -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Error</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="s">"other"</span><span class="p">))</span> -<span class="c1">// will succeed -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">ErrorContains</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="s">"other"</span><span class="p">))</span></code></pre></div> -<p>As you can see <code>ErrorContains</code> is especially useful when working with <em>wrapped</em> errors. -Now let’s look at <code>ErrorType</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">var</span> <span class="nx">err</span> <span class="kt">error</span> -<span class="c1">// will fail with : error is nil, not StubError -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">ErrorType</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">StubError</span><span class="p">{}))</span> - -<span class="nx">err</span> <span class="o">:=</span> <span class="nx">StubError</span><span class="p">{</span><span class="s">"foo"</span><span class="p">}</span> -<span class="c1">// will succeed -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">ErrorType</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">StubError</span><span class="p">{}))</span> - -<span class="c1">// Note that it also work with a function returning an error -</span><span class="c1"></span><span class="kd">func</span> <span class="nf">foo</span><span class="p">()</span> <span class="kt">error</span> <span class="p">{}</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">ErrorType</span><span class="p">(</span><span class="nx">foo</span><span class="p">,</span> <span class="nx">StubError</span><span class="p">{}))</span></code></pre></div> -<h3 id="bonus-with-panics">Bonus with <code>Panics</code></h3> - -<p>Sometimes, a code is supposed to <em>panic</em>, see <a href="https://golang.org/doc/effective%5Fgo.html#panic">Effective Go (#Panic)</a> for more information. And thus, you may want to make -sure you’re code panics in such cases. It’s always a bit tricky to test a code that panic as you have to use a deferred -function to recover the panic — but then if the panic doesn’t happen how do you fail the test ?</p> - -<p>This is where <code>Panics</code> comes handy.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">foo</span><span class="p">(</span><span class="nx">shouldPanic</span> <span class="kt">bool</span><span class="p">)</span> <span class="p">{</span> - <span class="k">if</span> <span class="nx">shouldPanic</span> <span class="p">{</span> - <span class="nb">panic</span><span class="p">(</span><span class="s">"booooooooooh"</span><span class="p">)</span> - <span class="p">}</span> - <span class="c1">// don't worry, be happy -</span><span class="c1"></span><span class="p">}</span> -<span class="c1">// will fail with : did not panic -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Panics</span><span class="p">(</span><span class="nf">foo</span><span class="p">(</span><span class="kc">false</span><span class="p">)))</span> -<span class="c1">// will succeed -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Panics</span><span class="p">(</span><span class="nf">foo</span><span class="p">(</span><span class="kc">true</span><span class="p">)))</span></code></pre></div> -<h3 id="miscellaneous-with-contains-len-and-nil">Miscellaneous with <code>Contains</code>, <code>Len</code> and <code>Nil</code></h3> - -<p>Those last three <em>built-in</em> <code>Comparison</code> are pretty straightforward.</p> - -<ul> -<li><p><code>Contains</code> succeeds if item is in collection. Collection may be a string, map, slice, or array.</p> - -<p>If collection is a string, item must also be a string, and is compared using <code>strings.Contains()</code>. If collection is a -Map, contains will succeed if item is a key in the map. If collection is a slice or array, item is compared to each -item in the sequence using <code>=reflect.DeepEqual()=</code>.</p></li> - -<li><p><code>Len</code> succeeds if the sequence has the expected length.</p></li> - -<li><p><code>Nil</code> succeeds if obj is a nil interface, pointer, or function.</p></li> -</ul> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="c1">// Contains works on string, map, slice or arrays -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Contains</span><span class="p">(</span><span class="s">"foobar"</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">))</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Contains</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"a"</span><span class="p">,</span> <span class="s">"b"</span><span class="p">,</span> <span class="s">"c"</span><span class="p">},</span> <span class="s">"b"</span><span class="p">))</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Contains</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">"a"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s">"b"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s">"c"</span><span class="p">:</span> <span class="mi">4</span><span class="p">},</span> <span class="s">"b"</span><span class="p">))</span> - -<span class="c1">// Len also works on string, map, slice or arrays -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Len</span><span class="p">(</span><span class="s">"foobar"</span><span class="p">,</span> <span class="mi">6</span><span class="p">))</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Len</span><span class="p">([]</span><span class="kt">string</span><span class="p">{</span><span class="s">"a"</span><span class="p">,</span> <span class="s">"b"</span><span class="p">,</span> <span class="s">"c"</span><span class="p">},</span> <span class="mi">3</span><span class="p">))</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Len</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">"a"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s">"b"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s">"c"</span><span class="p">:</span> <span class="mi">4</span><span class="p">},</span> <span class="mi">3</span><span class="p">))</span> - -<span class="c1">// Nil -</span><span class="c1"></span><span class="kd">var</span> <span class="nx">foo</span> <span class="o">*</span><span class="nx">MyStruc</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Nil</span><span class="p">(</span><span class="nx">foo</span><span class="p">))</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">Nil</span><span class="p">(</span><span class="nf">bar</span><span class="p">()))</span></code></pre></div> -<p>But let’s not waste more time and let’s see how to write our own <code>Comparison</code> !</p> - -<h3 id="write-your-own-comparison">Write your own <code>Comparison</code></h3> - -<p>One of the main aspect of <code>gotest.tools/assert</code> is to make it easy for developer to write as less boilerplate code as -possible while writing tests. Writing your own <code>Comparison</code> allows you to write a well named function that will be easy -to read and that can be re-used across your tests.</p> - -<p>Let’s look back at the <code>cmp.Comparison</code> and <code>cmp.Result</code> types.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Comparison</span> <span class="kd">func</span><span class="p">()</span> <span class="nx">Result</span> - -<span class="kd">type</span> <span class="nx">Result</span> <span class="kd">interface</span> <span class="p">{</span> - <span class="nf">Success</span><span class="p">()</span> <span class="kt">bool</span> -<span class="p">}</span></code></pre></div> -<p>A <code>Comparison</code> for <code>assert.Check</code> or <code>assert.Check</code> is a function that return a <code>Result</code>, it’s pretty straightforward to -implement, especially with <code>cmp.ResultSuccess</code> and <code>cmp.ResultFailure(…)</code> (as seen previously).</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">regexPattern</span><span class="p">(</span><span class="nx">value</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">pattern</span> <span class="kt">string</span><span class="p">)</span> <span class="nx">cmp</span><span class="p">.</span><span class="nx">Comparison</span> <span class="p">{</span> - <span class="k">return</span> <span class="kd">func</span><span class="p">()</span> <span class="nx">cmp</span><span class="p">.</span><span class="nx">Result</span> <span class="p">{</span> - <span class="nx">re</span> <span class="o">:=</span> <span class="nx">regexp</span><span class="p">.</span><span class="nf">MustCompile</span><span class="p">(</span><span class="nx">pattern</span><span class="p">)</span> - <span class="k">if</span> <span class="nx">re</span><span class="p">.</span><span class="nf">MatchString</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span> - <span class="k">return</span> <span class="nx">cmp</span><span class="p">.</span><span class="nx">ResultSuccess</span> - <span class="p">}</span> - <span class="k">return</span> <span class="nx">cmp</span><span class="p">.</span><span class="nf">ResultFailure</span><span class="p">(</span> - <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"%q did not match pattern %q"</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">pattern</span><span class="p">))</span> - <span class="p">}</span> -<span class="p">}</span> - -<span class="c1">// To use it -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nf">regexPattern</span><span class="p">(</span><span class="s">"12345.34"</span><span class="p">,</span> <span class="s">`\d+.\d\d`</span><span class="p">))</span></code></pre></div> -<p>As you can see, it’s pretty easy to implement, and you can do quite a lot in there easily. If a function call returns an -error inside of your <code>Comparison</code> function, you can use <code>cmp.ResultFromError</code> for example. Having something like -<code>assert.Check(t, isMyServerUp(":8080"))</code> is way more readable than a 30-line of code to check it.</p> - -<h2 id="conclusion">Conclusion…</h2> - -<p>… and that’s a wrap. We only looked at the <code>assert</code> package of <a href="https://gotest.tools"><code>gotest.tools</code></a> so far, but it’s already quite a bit to process.</p> - -<p>We’ve seen :</p> - -<ul> -<li>the main functions provided by this package : <code>assert.Assert</code> and <code>assert.Check</code></li> -<li>some helper functions like <code>assert.NilError</code>, …</li> -<li>the <code>assert/cmp</code>, and <code>assert/opt</code> sub-package that allows you to write more custom <code>Comparison</code></li> -</ul> - -<p>Next time, we’ll look at the <code>skip</code> package, that is a really simple wrapper on top of <code>testing.Skip</code> function.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-09-01-gotest-tools-skip/" title="Golang testing — gotest.tools skip">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-07-28-gotest-tools-intro/" title="Golang testing — gotest.tools introduction">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-01-gotest-tools-skip.org b/www/vincent.demeester.fr/content/legacy/posts/2018-09-01-gotest-tools-skip.org @@ -1,59 +0,0 @@ -#+title: Golang testing — gotest.tools skip -#+date: <2018-09-01 Sat> -#+filetags: go testing skip -#+setupfile: ../templates/post.org - -* Introduction - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =skip= package. This is a -really simple one so this should be quick. - -#+BEGIN_QUOTE -=skip= provides functions for skipping a test and printing the source code of the -condition used to skip the test. -#+END_QUOTE - -The package consists of only one function : =If=. The idea comes mainly from -[[https://github.com/docker/docker][=docker/docker=]] integration test suite, where we wanted to skip some test (or test suites) -given different context. By context I mean things like the system we are running on -(=Windows=, =Linux=, …) or the capabilities of the running kernel or node (is =apparmor= -available or not on the current machine). - -This =If= method takes a =testing.T= pointer and either a boolean, a function that -returns a boolean, *or* an expression. - -#+BEGIN_SRC go - // boolean - // --- SKIP: TestName (0.00s) - // skip.go:19: MissingFeature - var MissingFeature bool - skip.If(t, MissingFeature) - - // function - // --- SKIP: TestName (0.00s) - // skip.go:19: !IsExperimentalDaemon(dockerClient): daemon is not experimental - skip.If(t, IsExperimentalDaemon(dockerClient), "daemon is not experimental") - - // expression - // --- SKIP: TestName (0.00s) - // skip.go:19: apiVersion < version("v1.24") - skip.If(t, apiVersion < version("v1.24")) -#+END_SRC - -There is few elements to note though : - -- This package (as other parts of the =gotest.tools= packages), will try to look at source - files to display the expression used (same goes for =assert=). This is usually not a - problem because you run tests where the source code is. *However*, in the cases you - generate a test binary to be executed later (à-la =kubernetes= or other projects), this - can display a weird error message if the sources are not available… You shouldn't be - worried too much about it, but it's better if you know :) -- The main reason to use =skip.If= is mainly for new contributors to get in quickly, - *reducing potential friction of them running the tests on their environment*. The more - the tests are written in a way they explicitely declare their requirements (and skipped - if the environment does not meet those), the easier it makes contributors run your - tests. *But*, this also means, you should try to measure the skipped tests on your - continuous integration system to make sure you run all of them eventually… otherwise - it's dead code. /But more on that in later posts 😉/. - -That's all for today folks, told you that was going to be quick. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-01-gotest-tools-skip/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-09-01-gotest-tools-skip/index.html @@ -1,169 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-09-01-gotest-tools-skip/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools skip</h1><a href='https://vincent.demeester.fr/posts/2018-09-01-gotest-tools-skip/'></a> - <address class="signature"> - <span class="date">Sat, 1 September, 2018</span> - <span class="words">(400 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-skip"><a href="/tags/#skip">skip<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - <p>Let’s continue the <a href="https://gotest.tools"><code>gotest.tools</code></a> serie, this time with the <code>skip</code> package. This is a -really simple one so this should be quick.</p> - -<blockquote> -<p><code>skip</code> provides functions for skipping a test and printing the source code of the -condition used to skip the test.</p> -</blockquote> - -<p>The package consists of only one function : <code>If</code>. The idea comes mainly from -<a href="https://github.com/docker/docker"><code>docker/docker</code></a> integration test suite, where we wanted to skip some test (or test suites) -given different context. By context I mean things like the system we are running on -(<code>Windows</code>, <code>Linux</code>, …) or the capabilities of the running kernel or node (is <code>apparmor</code> -available or not on the current machine).</p> - -<p>This <code>If</code> method takes a <code>testing.T</code> pointer and either a boolean, a function that -returns a boolean, <strong>or</strong> an expression.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="c1">// boolean -</span><span class="c1">// --- SKIP: TestName (0.00s) -</span><span class="c1">// skip.go:19: MissingFeature -</span><span class="c1"></span><span class="kd">var</span> <span class="nx">MissingFeature</span> <span class="kt">bool</span> -<span class="nx">skip</span><span class="p">.</span><span class="nf">If</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">MissingFeature</span><span class="p">)</span> - -<span class="c1">// function -</span><span class="c1">// --- SKIP: TestName (0.00s) -</span><span class="c1">// skip.go:19: !IsExperimentalDaemon(dockerClient): daemon is not experimental -</span><span class="c1"></span><span class="nx">skip</span><span class="p">.</span><span class="nf">If</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nf">IsExperimentalDaemon</span><span class="p">(</span><span class="nx">dockerClient</span><span class="p">),</span> <span class="s">"daemon is not experimental"</span><span class="p">)</span> - -<span class="c1">// expression -</span><span class="c1">// --- SKIP: TestName (0.00s) -</span><span class="c1">// skip.go:19: apiVersion < version("v1.24") -</span><span class="c1"></span><span class="nx">skip</span><span class="p">.</span><span class="nf">If</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">apiVersion</span> <span class="p"><</span> <span class="nf">version</span><span class="p">(</span><span class="s">"v1.24"</span><span class="p">))</span></code></pre></div> -<p>There is few elements to note though :</p> - -<ul> -<li>This package (as other parts of the <code>gotest.tools</code> packages), will try to look at source -files to display the expression used (same goes for <code>assert</code>). This is usually not a -problem because you run tests where the source code is. <strong>However</strong>, in the cases you -generate a test binary to be executed later (à-la <code>kubernetes</code> or other projects), this -can display a weird error message if the sources are not available… You shouldn’t be -worried too much about it, but it’s better if you know :)</li> -<li>The main reason to use <code>skip.If</code> is mainly for new contributors to get in quickly, -<strong>reducing potential friction of them running the tests on their environment</strong>. The more -the tests are written in a way they explicitely declare their requirements (and skipped -if the environment does not meet those), the easier it makes contributors run your -tests. <strong>But</strong>, this also means, you should try to measure the skipped tests on your -continuous integration system to make sure you run all of them eventually… otherwise -it’s dead code. <em>But more on that in later posts 😉</em>.</li> -</ul> - -<p>That’s all for today folks, told you that was going to be quick.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-09-06-gotest-tools-golden/" title="Golang testing — gotest.tools golden">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-08-16-gotest-tools-assertions/" title="Golang testing — gotest.tools assertions">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-06-gotest-tools-golden.org b/www/vincent.demeester.fr/content/legacy/posts/2018-09-06-gotest-tools-golden.org @@ -1,75 +0,0 @@ -#+TITLE: Golang testing — gotest.tools golden -#+date: <2018-09-06 Thu> -#+filetags: go testing golden -#+setupfile: ../templates/post.org - -#+TOC: headlines 2 - -* Introduction -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =golden= package. This is a -[[/posts/2017-04-22-golang-testing-golden-file/][/quick follow-up/ on a previous =golden= post]], but focused on the =gotest.tools= -implementation. I'm gonna be quicker, please read that one if =golden= files is a new -concept for you. - -#+BEGIN_QUOTE -Package =golden= provides tools for comparing large mutli-line strings. - -Golden files are files in the =./testdata/= sub-directory of the package under test. -#+END_QUOTE - -In the previous article, we described the problem, and how to fix it by writing a small -helper. Well, that small helper is in =gotest.tools/golden= now, and it has a tiny bit -more features. - -One of the difference between the =gotest.tools= implementation and the previous post is -the flag name. In =gotest.tools/golden=, the flag is =-test.update-golden= (was just -=-test.update= before). Just as before, if the =-test.update-golden= flag is set then the -actual content is written to the golden file, before reading it and comparing. - -There is two ways to use the =golden= package: -- on it's own, using =golden.Assert= or =golden.AssertBytes= -- as a =cmp.Comparison=, with =golden.String= or =golden.Bytes= - -* =Assert= and =AssertBytes= - -Using =Assert= functions should be straightforward. Both =Assert= function compares the -actual content to the expected content in the golden file and returns whether the -assertion was successful (true) or not (false). - -- =Assert= uses string. Note that this one *removes carriage return* before comparing to - depend as less as possible of the system (=\n= vs =\r\n= 😅) -- =AssertBytes= uses raw data (in the form of =[]byte=) - -#+BEGIN_SRC go - golden.Assert(t, "foo", "foo-content.golden") - // Could also be used to check some binary format - golden.AssertBytes(t, []byte("foo"), "foo-content.golden") -#+END_SRC - -* =Bytes= and =String= - -As written in a [[/posts/2018-08-16-gotest-tools-assertions/][previous post (about the =assert= package)]], I prefer to use =cmp.Comparison=. - -#+BEGIN_QUOTE -All those helper functions have a equivalent function in the =cmp= package that returns a -=Comparison=. I, personally, prefer to use =assert.Check= or =assert.Assert= in -combination with =cmp.Comparison= as it allows me to write all my assertions the same way, -with built-ins comparison or with my own — i.e. =assert.Assert(t, is.Equal(…), "message"= -or =assert.Assert(t, stackIsUp(c, time…), "another message")=. -#+END_QUOTE - -The =golden= package gives us that too, in the form of =Bytes= and =String=. Using the -=assert.Check= or =assert.Assert= functions with those is equivalent to their /helper/ -counter-part =golden.Assert= and =golden.AssertBytes=. - -#+BEGIN_SRC go - assert.Assert(t, golden.String("foo", "foo-content.golden")) - // Could also be used to check some binary format - assert.Assert(t, golden.Bytes([]byte("foo"), "foo-content.golden")) -#+END_SRC - -* Conclusion… - -… that's a wrap. As for [[/posts/2018-09-01-gotest-tools-skip/][=skip=]], this is a small package, so the post was going to be -quick. =golden= package just solve a specific problem (read [[/posts/2017--04-22-golang-testing-golden-file/][Golang testing — golden file]]) -in a simple way. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-06-gotest-tools-golden/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-09-06-gotest-tools-golden/index.html @@ -1,182 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-09-06-gotest-tools-golden/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools golden</h1><a href='https://vincent.demeester.fr/posts/2018-09-06-gotest-tools-golden/'></a> - <address class="signature"> - <span class="date">Thu, 6 September, 2018</span> - <span class="words">(500 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Let’s continue the <a href="https://gotest.tools"><code>gotest.tools</code></a> serie, this time with the <code>golden</code> package. This is a -<a href="/posts/2017-04-22-golang-testing-golden-file/"><em>quick follow-up</em> on a previous <code>golden</code> post</a>, but focused on the <code>gotest.tools</code> -implementation. I’m gonna be quicker, please read that one if <code>golden</code> files is a new -concept for you.</p> - -<blockquote> -<p>Package <code>golden</code> provides tools for comparing large mutli-line strings.</p> - -<p>Golden files are files in the <code>./testdata/</code> sub-directory of the package under test.</p> -</blockquote> - -<p>In the previous article, we described the problem, and how to fix it by writing a small -helper. Well, that small helper is in <code>gotest.tools/golden</code> now, and it has a tiny bit -more features.</p> - -<p>One of the difference between the <code>gotest.tools</code> implementation and the previous post is -the flag name. In <code>gotest.tools/golden</code>, the flag is <code>-test.update-golden</code> (was just -<code>-test.update</code> before). Just as before, if the <code>-test.update-golden</code> flag is set then the -actual content is written to the golden file, before reading it and comparing.</p> - -<p>There is two ways to use the <code>golden</code> package:</p> - -<ul> -<li>on it’s own, using <code>golden.Assert</code> or <code>golden.AssertBytes</code></li> -<li>as a <code>cmp.Comparison</code>, with <code>golden.String</code> or <code>golden.Bytes</code></li> -</ul> - -<h2 id="assert-and-assertbytes"><code>Assert</code> and <code>AssertBytes</code></h2> - -<p>Using <code>Assert</code> functions should be straightforward. Both <code>Assert</code> function compares the -actual content to the expected content in the golden file and returns whether the -assertion was successful (true) or not (false).</p> - -<ul> -<li><code>Assert</code> uses string. Note that this one <strong>removes carriage return</strong> before comparing to -depend as less as possible of the system (<code>\n</code> vs <code>\r\n</code> 😅)</li> -<li><code>AssertBytes</code> uses raw data (in the form of <code>[]byte</code>)</li> -</ul> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">golden</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">,</span> <span class="s">"foo-content.golden"</span><span class="p">)</span> -<span class="c1">// Could also be used to check some binary format -</span><span class="c1"></span><span class="nx">golden</span><span class="p">.</span><span class="nf">AssertBytes</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="p">[]</span><span class="nb">byte</span><span class="p">(</span><span class="s">"foo"</span><span class="p">),</span> <span class="s">"foo-content.golden"</span><span class="p">)</span></code></pre></div> -<h2 id="bytes-and-string"><code>Bytes</code> and <code>String</code></h2> - -<p>As written in a <a href="/posts/2018-08-16-gotest-tools-assertions/">previous post (about the <code>assert</code> package)</a>, I prefer to use <code>cmp.Comparison</code>.</p> - -<blockquote> -<p>All those helper functions have a equivalent function in the <code>cmp</code> package that returns a -<code>Comparison</code>. I, personally, prefer to use <code>assert.Check</code> or <code>assert.Assert</code> in -combination with <code>cmp.Comparison</code> as it allows me to write all my assertions the same way, -with built-ins comparison or with my own — i.e. <code>assert.Assert(t, is.Equal(…), "message"</code> -or <code>assert.Assert(t, stackIsUp(c, time…), "another message")</code>.</p> -</blockquote> - -<p>The <code>golden</code> package gives us that too, in the form of <code>Bytes</code> and <code>String</code>. Using the -<code>assert.Check</code> or <code>assert.Assert</code> functions with those is equivalent to their <em>helper</em> -counter-part <code>golden.Assert</code> and <code>golden.AssertBytes</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">golden</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"foo"</span><span class="p">,</span> <span class="s">"foo-content.golden"</span><span class="p">))</span> -<span class="c1">// Could also be used to check some binary format -</span><span class="c1"></span><span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">golden</span><span class="p">.</span><span class="nf">Bytes</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="s">"foo"</span><span class="p">),</span> <span class="s">"foo-content.golden"</span><span class="p">))</span></code></pre></div> -<h2 id="conclusion">Conclusion…</h2> - -<p>… that’s a wrap. As for <a href="/posts/2018-09-01-gotest-tools-skip/"><code>skip</code></a>, this is a small package, so the post was going to be -quick. <code>golden</code> package just solve a specific problem (read <a href="/posts/2017-04-22-golang-testing-golden-file/">Golang testing — golden file</a>) -in a simple way.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-09-14-gotest-tools-fs/" title="Golang testing — gotest.tools fs">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-09-01-gotest-tools-skip/" title="Golang testing — gotest.tools skip">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-14-gotest-tools-fs.org b/www/vincent.demeester.fr/content/legacy/posts/2018-09-14-gotest-tools-fs.org @@ -1,187 +0,0 @@ -#+TITLE: Golang testing — gotest.tools fs -#+date: <2018-09-14 Fri> -#+filetags: go testing fs -#+setupfile: ../templates/post.org - -#+TOC: headlines 2 - -* Introduction - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =fs= package. - -#+BEGIN_QUOTE -Package fs provides tools for creating temporary files, and testing the contents and structure of a directory. -#+END_QUOTE - -This package is heavily using functional arguments (as we saw in [[/posts/2017-01-01-go-testing-functionnal-builders/][functional arguments for -wonderful builders]]). Functional arguments is, in a nutshell, a combinaison of two Go -features : /variadic/ functions (=...= operation in a function signature) and the fact -that =func= are /first class citizen/. This looks more or less like that. - -#+BEGIN_SRC go - type Config struct {} - - func MyFn(ops ...func(*Config)) *Config { - c := &Config{} // with default values - for _, op := range ops { - op(c) - } - return c - } - - // Calling it - conf := MyFn(withFoo, withBar("baz")) -#+END_SRC - -The =fs= package has too *main* purpose : - -1. create folders and files required for testing in a simple manner -2. compare two folders structure (and content) - -* Create folder structures - -Sometimes, you need to create folder structures (and files) in tests. Doing =i/o= work -takes time so try to limit the number of tests that needs to do that, especially in unit -tests. Doing it in tests adds a bit of boilerplate that could be avoid. As stated [[/posts/2017-01-01-go-testing-functionnal-builders/][before]] : - -#+BEGIN_QUOTE -One of the most important characteristic of a unit test (and any type of test really) is -*readability*. This means it should be easy to read but most importantly it should *clearly -show the intent* of the test. The setup (and cleanup) of the tests should be as small as -possible to avoid the noise. -#+END_QUOTE - -In a test you usually end up using =ioutil= function to create what you need. This looks -somewhat like the following. - -#+BEGIN_SRC go - path, err := ioutil.TempDir("", "bar") - if err != nil { // or using `assert.Assert` - t.Fatal(err) - } - if err := os.Mkdir(filepath.Join(path, "foo"), os.FileMode(0755)); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(filepath.Join(path, "foo", "bar"), []byte("content"), os.FileMode(0777)); err != nil { - t.Fatal(err) - } - defer os.RemoveAll(path) // to clean up at the end of the test -#+END_SRC - -The =fs= package intends to help reduce the noise and comes with a bunch function to create -folder structure : - -- two main function =NewFile= and =NewDir= -- a bunch of /operators/ : =WithFile=, =WithDir=, … - -#+BEGIN_SRC go - func NewDir(t assert.TestingT, prefix string, ops ...PathOp) *Dir { - // … - } - - func NewFile(t assert.TestingT, prefix string, ops ...PathOp) *File { - // … - } -#+END_SRC - -The =With*= function are all satisfying the =PathOp= interface, making =NewFile= and -=NewDir= extremely composable. Let's first see how our above example would look like using -the =fs= package, and then, we'll look a bit more at the main =PathOp= function… - -#+BEGIN_SRC go - dir := fs.NewDir(t, "bar", fs.WithDir("foo", - fs.WithFile("bar", fs.WithContent("content"), fs.WithMode(os.FileMode(0777))), - )) - defer dir.Remove() -#+END_SRC - -It's clean and simple to read. The intent is well described and there is not that much of -noise. =fs= functions tends to have /sane/ and /safe/ defaults value (for =os.FileMode= -for example). Let's list the main, useful, =PathOp= provided by =gotest.tools/fs=. - -- =WithDir= creates a sub-directory in the directory at path. -- =WithFile= creates a file in the directory at path with content. -- =WithSymlink= creates a symlink in the directory which links to target. Target must be a - path relative to the directory. -- =WithHardlink= creates a link in the directory which links to target. Target must be a - path relative to the directory. -- =WithContent= and =WWithBytes= write content to a file at Path (from a =string= or a - =[]byte= slice). -- =WithMode= sets the file mode on the directory or file at path. -- =WithTimestamps= sets the access and modification times of the file system object at - path. -- =FromDir= copies the directory tree from the source path into the new Dir. This is - pretty useful when you have a huge folder structure already present in you =testdata= - folder or elsewhere. -- =AsUser= changes ownership of the file system object at Path. - -Also, note that =PathOp= being an function type, you can provide your own implementation -for specific use-cases. Your function just has to satisfy =PathOp= signature. - -#+BEGIN_SRC go - type PathOp func(path Path) error -#+END_SRC - -* Compare folder structures - -Sometimes, the code you're testing is creating a folder structure, and you would like to -be able to tests that, with the given arguments, it creates the specified structure. =fs= -allows you to do that too. - -The package provides a =Equal= function, which returns a =Comparison=, that the [[/posts/2018-08-16-gotest-tools-assertions/][=assert=]] -package understand. It works by comparing a =Manifest= type provided by the test and a -=Manifest= representation of the specified folder. - -#+BEGIN_QUOTE - Equal compares a directory to the expected structured described by a manifest and returns - success if they match. If they do not match the failure message will contain all the - differences between the directory structure and the expected structure defined by the - Manifest. -#+END_QUOTE - -A =Manifest= stores the expected structure and properties of files and directories in a -file-system. You can create a =Manifest= using either the functions =Expected= or -=ManifestFromDir=. - -We're going to focus on the =Expected= function, as =ManifestFromDir= does pretty much -what you would expected : it takes the specified path, and returns a =Manifest= that -represent this folder. - -#+BEGIN_SRC go - func Expected(t assert.TestingT, ops ...PathOp) Manifest -#+END_SRC - -=Expected= is close to =NewDir= function : it takes the same =PathOp= functional -arguments. This makes creating a =Manifest= straightforward, as it's working the same. Any -function that satisfy =PathOp= can be used for =Manifest= the exact same way you're using -them on =fs.NewDir=. - -There is a few additional functions that are only useful with =Manifest= : - -- =MatchAnyFileContent= updates a Manifest so that the file at path may contain any content. -- =MatchAnyFileMode= updates a Manifest so that the resource at path will match any file mode. -- =MatchContentIgnoreCarriageReturn= ignores cariage return discrepancies. -- =MatchExtraFiles= updates a Manifest to allow a directory to contain unspecified files. - -#+BEGIN_SRC go - path := operationWhichCreatesFiles() - expected := fs.Expected(t, - fs.WithFile("one", "", - fs.WithBytes(golden.Get(t, "one.golden")), - fs.WithMode(0600)), - fs.WithDir("data", - fs.WithFile("config", "", fs.MatchAnyFileContent)), - ) - - assert.Assert(t, fs.Equal(path, expected)) -#+END_SRC - -The following example compares the result of =operationWhichCreatesFiles= to the expected -=Manifest=. As you can see it also integrates well with other part of the =gotest.tools= -library, with the [[/posts/2018-09-06-gotest-tools-golden/][=golden= package]] in this example. - -* Conclusion… - -… that's a wrap. In my opinion, this is one the most useful package provided by -=gotest.tools= after =assert=. It allows to create simple or complex folder structure -without the noise that usually comes with it. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-14-gotest-tools-fs/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-09-14-gotest-tools-fs/index.html @@ -1,279 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-09-14-gotest-tools-fs/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools fs</h1><a href='https://vincent.demeester.fr/posts/2018-09-14-gotest-tools-fs/'></a> - <address class="signature"> - <span class="date">Fri, 14 September, 2018</span> - <span class="words">(1100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-filesystem"><a href="/tags/#filesystem">filesystem<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Let’s continue the <a href="https://gotest.tools"><code>gotest.tools</code></a> serie, this time with the <code>fs</code> package.</p> - -<blockquote> -<p>Package fs provides tools for creating temporary files, and testing the contents and structure of a directory.</p> -</blockquote> - -<p>This package is heavily using functional arguments (as we saw in <a href="/posts/2017-01-01-go-testing-functionnal-builders/">functional arguments for -wonderful builders</a>). Functional arguments is, in a nutshell, a combinaison of two Go -features : <em>variadic</em> functions (<code>...</code> operation in a function signature) and the fact -that <code>func</code> are <em>first class citizen</em>. This looks more or less like that.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Config</span> <span class="kd">struct</span> <span class="p">{}</span> - -<span class="kd">func</span> <span class="nf">MyFn</span><span class="p">(</span><span class="nx">ops</span> <span class="o">...</span><span class="kd">func</span><span class="p">(</span><span class="o">*</span><span class="nx">Config</span><span class="p">))</span> <span class="o">*</span><span class="nx">Config</span> <span class="p">{</span> - <span class="nx">c</span> <span class="o">:=</span> <span class="o">&</span><span class="nx">Config</span><span class="p">{}</span> <span class="c1">// with default values -</span><span class="c1"></span> <span class="k">for</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">op</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">ops</span> <span class="p">{</span> - <span class="nf">op</span><span class="p">(</span><span class="nx">c</span><span class="p">)</span> - <span class="p">}</span> - <span class="k">return</span> <span class="nx">c</span> -<span class="p">}</span> - -<span class="c1">// Calling it -</span><span class="c1"></span><span class="nx">conf</span> <span class="o">:=</span> <span class="nf">MyFn</span><span class="p">(</span><span class="nx">withFoo</span><span class="p">,</span> <span class="nf">withBar</span><span class="p">(</span><span class="s">"baz"</span><span class="p">))</span></code></pre></div> -<p>The <code>fs</code> package has too <strong>main</strong> purpose :</p> - -<ol> -<li>create folders and files required for testing in a simple manner</li> -<li>compare two folders structure (and content)</li> -</ol> - -<h2 id="create-folder-structures">Create folder structures</h2> - -<p>Sometimes, you need to create folder structures (and files) in tests. Doing <code>i/o</code> work -takes time so try to limit the number of tests that needs to do that, especially in unit -tests. Doing it in tests adds a bit of boilerplate that could be avoid. As stated <a href="/posts/2017-01-01-go-testing-functionnal-builders/">before</a> :</p> - -<blockquote> -<p>One of the most important characteristic of a unit test (and any type of test really) is -<strong>readability</strong>. This means it should be easy to read but most importantly it should <strong>clearly -show the intent</strong> of the test. The setup (and cleanup) of the tests should be as small as -possible to avoid the noise.</p> -</blockquote> - -<p>In a test you usually end up using <code>ioutil</code> function to create what you need. This looks -somewhat like the following.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">path</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nf">TempDir</span><span class="p">(</span><span class="s">""</span><span class="p">,</span> <span class="s">"bar"</span><span class="p">)</span> -<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> <span class="c1">// or using `assert.Assert` -</span><span class="c1"></span> <span class="nx">t</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> -<span class="p">}</span> -<span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">Mkdir</span><span class="p">(</span><span class="nx">filepath</span><span class="p">.</span><span class="nf">Join</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">),</span> <span class="nx">os</span><span class="p">.</span><span class="nf">FileMode</span><span class="p">(</span><span class="mo">0755</span><span class="p">));</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> - <span class="nx">t</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> -<span class="p">}</span> -<span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nf">WriteFile</span><span class="p">(</span><span class="nx">filepath</span><span class="p">.</span><span class="nf">Join</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">,</span> <span class="s">"bar"</span><span class="p">),</span> <span class="p">[]</span><span class="nb">byte</span><span class="p">(</span><span class="s">"content"</span><span class="p">),</span> <span class="nx">os</span><span class="p">.</span><span class="nf">FileMode</span><span class="p">(</span><span class="mo">0777</span><span class="p">));</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> - <span class="nx">t</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> -<span class="p">}</span> -<span class="k">defer</span> <span class="nx">os</span><span class="p">.</span><span class="nf">RemoveAll</span><span class="p">(</span><span class="nx">path</span><span class="p">)</span> <span class="o">//</span> <span class="nx">to</span> <span class="nx">clean</span> <span class="nx">up</span> <span class="nx">at</span> <span class="nx">the</span> <span class="nx">end</span> <span class="nx">of</span> <span class="nx">the</span> <span class="nx">test</span></code></pre></div> -<p>The <code>fs</code> package intends to help reduce the noise and comes with a bunch function to create -folder structure :</p> - -<ul> -<li>two main function <code>NewFile</code> and <code>NewDir</code></li> -<li>a bunch of <em>operators</em> : <code>WithFile</code>, <code>WithDir</code>, …</li> -</ul> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">NewDir</span><span class="p">(</span><span class="nx">t</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">TestingT</span><span class="p">,</span> <span class="nx">prefix</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">ops</span> <span class="o">...</span><span class="nx">PathOp</span><span class="p">)</span> <span class="o">*</span><span class="nx">Dir</span> <span class="p">{</span> - <span class="c1">// … -</span><span class="c1"></span><span class="p">}</span> - -<span class="kd">func</span> <span class="nf">NewFile</span><span class="p">(</span><span class="nx">t</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">TestingT</span><span class="p">,</span> <span class="nx">prefix</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">ops</span> <span class="o">...</span><span class="nx">PathOp</span><span class="p">)</span> <span class="o">*</span><span class="nx">File</span> <span class="p">{</span> - <span class="c1">// … -</span><span class="c1"></span><span class="p">}</span></code></pre></div> -<p>The <code>With*</code> function are all satisfying the <code>PathOp</code> interface, making <code>NewFile</code> and -<code>NewDir</code> extremely composable. Let’s first see how our above example would look like using -the <code>fs</code> package, and then, we’ll look a bit more at the main <code>PathOp</code> function…</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">dir</span> <span class="o">:=</span> <span class="nx">fs</span><span class="p">.</span><span class="nf">NewDir</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="s">"bar"</span><span class="p">,</span> <span class="nx">fs</span><span class="p">.</span><span class="nf">WithDir</span><span class="p">(</span><span class="s">"foo"</span><span class="p">,</span> - <span class="nx">fs</span><span class="p">.</span><span class="nf">WithFile</span><span class="p">(</span><span class="s">"bar"</span><span class="p">,</span> <span class="nx">fs</span><span class="p">.</span><span class="nf">WithContent</span><span class="p">(</span><span class="s">"content"</span><span class="p">),</span> <span class="nx">fs</span><span class="p">.</span><span class="nf">WithMode</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nf">FileMode</span><span class="p">(</span><span class="mo">0777</span><span class="p">))),</span> -<span class="p">))</span> -<span class="k">defer</span> <span class="nx">dir</span><span class="p">.</span><span class="nf">Remove</span><span class="p">()</span></code></pre></div> -<p>It’s clean and simple to read. The intent is well described and there is not that much of -noise. <code>fs</code> functions tends to have <em>sane</em> and <em>safe</em> defaults value (for <code>os.FileMode</code> -for example). Let’s list the main, useful, <code>PathOp</code> provided by <code>gotest.tools/fs</code>.</p> - -<ul> -<li><code>WithDir</code> creates a sub-directory in the directory at path.</li> -<li><code>WithFile</code> creates a file in the directory at path with content.</li> -<li><code>WithSymlink</code> creates a symlink in the directory which links to target. Target must be a -path relative to the directory.</li> -<li><code>WithHardlink</code> creates a link in the directory which links to target. Target must be a -path relative to the directory.</li> -<li><code>WithContent</code> and <code>WWithBytes</code> write content to a file at Path (from a <code>string</code> or a -<code>[]byte</code> slice).</li> -<li><code>WithMode</code> sets the file mode on the directory or file at path.</li> -<li><code>WithTimestamps</code> sets the access and modification times of the file system object at -path.</li> -<li><code>FromDir</code> copies the directory tree from the source path into the new Dir. This is -pretty useful when you have a huge folder structure already present in you <code>testdata</code> -folder or elsewhere.</li> -<li><code>AsUser</code> changes ownership of the file system object at Path.</li> -</ul> - -<p>Also, note that <code>PathOp</code> being an function type, you can provide your own implementation -for specific use-cases. Your function just has to satisfy <code>PathOp</code> signature.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">PathOp</span> <span class="kd">func</span><span class="p">(</span><span class="nx">path</span> <span class="nx">Path</span><span class="p">)</span> <span class="kt">error</span></code></pre></div> -<h2 id="compare-folder-structures">Compare folder structures</h2> - -<p>Sometimes, the code you’re testing is creating a folder structure, and you would like to -be able to tests that, with the given arguments, it creates the specified structure. <code>fs</code> -allows you to do that too.</p> - -<p>The package provides a <code>Equal</code> function, which returns a <code>Comparison</code>, that the <a href="/posts/2018-08-16-gotest-tools-assertions/"><code>assert</code></a> -package understand. It works by comparing a <code>Manifest</code> type provided by the test and a -<code>Manifest</code> representation of the specified folder.</p> - -<blockquote> -<p>Equal compares a directory to the expected structured described by a manifest and returns -success if they match. If they do not match the failure message will contain all the -differences between the directory structure and the expected structure defined by the -Manifest.</p> -</blockquote> - -<p>A <code>Manifest</code> stores the expected structure and properties of files and directories in a -file-system. You can create a <code>Manifest</code> using either the functions <code>Expected</code> or -<code>ManifestFromDir</code>.</p> - -<p>We’re going to focus on the <code>Expected</code> function, as <code>ManifestFromDir</code> does pretty much -what you would expected : it takes the specified path, and returns a <code>Manifest</code> that -represent this folder.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">Expected</span><span class="p">(</span><span class="nx">t</span> <span class="nx">assert</span><span class="p">.</span><span class="nx">TestingT</span><span class="p">,</span> <span class="nx">ops</span> <span class="o">...</span><span class="nx">PathOp</span><span class="p">)</span> <span class="nx">Manifest</span></code></pre></div> -<p><code>Expected</code> is close to <code>NewDir</code> function : it takes the same <code>PathOp</code> functional -arguments. This makes creating a <code>Manifest</code> straightforward, as it’s working the same. Any -function that satisfy <code>PathOp</code> can be used for <code>Manifest</code> the exact same way you’re using -them on <code>fs.NewDir</code>.</p> - -<p>There is a few additional functions that are only useful with <code>Manifest</code> :</p> - -<ul> -<li><code>MatchAnyFileContent</code> updates a Manifest so that the file at path may contain any content.</li> -<li><code>MatchAnyFileMode</code> updates a Manifest so that the resource at path will match any file mode.</li> -<li><code>MatchContentIgnoreCarriageReturn</code> ignores cariage return discrepancies.</li> -<li><code>MatchExtraFiles</code> updates a Manifest to allow a directory to contain unspecified files.</li> -</ul> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">path</span> <span class="o">:=</span> <span class="nf">operationWhichCreatesFiles</span><span class="p">()</span> -<span class="nx">expected</span> <span class="o">:=</span> <span class="nx">fs</span><span class="p">.</span><span class="nf">Expected</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> - <span class="nx">fs</span><span class="p">.</span><span class="nf">WithFile</span><span class="p">(</span><span class="s">"one"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> - <span class="nx">fs</span><span class="p">.</span><span class="nf">WithBytes</span><span class="p">(</span><span class="nx">golden</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="s">"one.golden"</span><span class="p">)),</span> - <span class="nx">fs</span><span class="p">.</span><span class="nf">WithMode</span><span class="p">(</span><span class="mo">0600</span><span class="p">)),</span> - <span class="nx">fs</span><span class="p">.</span><span class="nf">WithDir</span><span class="p">(</span><span class="s">"data"</span><span class="p">,</span> - <span class="nx">fs</span><span class="p">.</span><span class="nf">WithFile</span><span class="p">(</span><span class="s">"config"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">MatchAnyFileContent</span><span class="p">)),</span> -<span class="p">)</span> - -<span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">fs</span><span class="p">.</span><span class="nf">Equal</span><span class="p">(</span><span class="nx">path</span><span class="p">,</span> <span class="nx">expected</span><span class="p">))</span></code></pre></div> -<p>The following example compares the result of <code>operationWhichCreatesFiles</code> to the expected -<code>Manifest</code>. As you can see it also integrates well with other part of the <code>gotest.tools</code> -library, with the <a href="/posts/2018-09-06-gotest-tools-golden/"><code>golden</code> package</a> in this example.</p> - -<h2 id="conclusion">Conclusion…</h2> - -<p>… that’s a wrap. In my opinion, this is one the most useful package provided by -<code>gotest.tools</code> after <code>assert</code>. It allows to create simple or complex folder structure -without the noise that usually comes with it.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-09-18-gotest-tools-icmd/" title="Golang testing — gotest.tools icmd">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-09-06-gotest-tools-golden/" title="Golang testing — gotest.tools golden">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-18-gotest-tools-icmd.org b/www/vincent.demeester.fr/content/legacy/posts/2018-09-18-gotest-tools-icmd.org @@ -1,209 +0,0 @@ -#+TITLE: Golang testing — gotest.tools icmd -#+date: <2018-09-18 Tue> -#+filetags: go testing cmd -#+setupfile: ../templates/post.org - -#+TOC: headlines 2 - -* Introduction -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =icmd= package. - -#+BEGIN_QUOTE -Package icmd executes binaries and provides convenient assertions for testing the results. -#+END_QUOTE - -After file-system operations (seen in [[/posts/2018-09-14-gotest-tools-fs/][=fs=]]), another common use-case in tests is to -*execute a command*. The reasons can be you're testing the =cli= you're currently writing -or you need to setup something using a command line. A classic execution in a test might -lookup like the following. - -#+BEGIN_SRC go - cmd := exec.Command("echo", "foo") - cmd.Stout = &stdout - cmd.Env = env - if err := cmd.Run(); err != nil { - t.Fatal(err) - } - if string(stdout) != "foo" { - t.Fatalf("expected: foo, got %s", string(stdout)) - } -#+END_SRC - -The package =icmd= is there to ease your pain (as usual 😉) — we used /the name =icmd=/ -instead of =cmd= because it's a pretty common identifier in Go source code, thus would be -really easy to /shadow/ — and have some really weird problems going on. - -The usual =icmd= workflow is the following: - -1. Describe the command you want to execute using : type =Cmd=, function =Command= and - =CmdOp= operators. -2. Run it using : function =RunCmd= or =RunCommand= (that does 1. for you). You can also - use =StartCmd= and =WaitOnCmd= if you want more control on the execution workflow. -3. Check the result using the =Assert=, =Equal= or =Compare= methods attached to the - =Result= struct that the command execution return. - -* Create and run a command - -Let's first dig how to create commands. In this part, the assumption here is that the -command is successful, so we'll have =.Assert(t, icmd.Success)= for now — we'll learn more -about =Assert= in the next section 👼. - -The simplest way to create and run a command is using =RunCommand=, it has the same -signature as =os/exec.Command=. A simple command execution goes as below. - -#+BEGIN_SRC go - icmd.RunCommand("echo", "foo").Assert(t, icmd.Sucess) -#+END_SRC - -Sometimes, you need to customize the command a bit more, like adding some environment -variable. In those case, you are going to use =RunCmd=, it takes a =Cmd= and operators. -Let's look at those functions. - -#+BEGIN_SRC go - func RunCmd(cmd Cmd, cmdOperators ...CmdOp) *Result - - func Command(command string, args ...string) Cmd - - type Cmd struct { - Command []string - Timeout time.Duration - Stdin io.Reader - Stdout io.Writer - Dir string - Env []string - } -#+END_SRC - -As we've seen [[/posts/2017-01-01-go-testing-functionnal-builders/][multiple]] [[/posts/2018-08-16-gotest-tools-assertions/][times]] [[/posts/2018-09-14-gotest-tools-fs/][before]], it uses the /powerful/ functional arguments. At the -time I wrote this post, the =icmd= package doesn't contains too much =CmdOp= [fn:1], so I'll -propose two version for each example : one with =CmdOpt= present in [[https://github.com/gotestyourself/gotest.tools/pull/122][this PR]] and one -without them. - -#+BEGIN_SRC go - // With - icmd.RunCmd(icmd.Command("sh", "-c", "echo $FOO"), - icmd.WithEnv("FOO=bar", "BAR=baz"), icmd.Dir("/tmp"), - icmd.WithTimeout(10*time.Second), - ).Assert(t, icmd.Success) - - // Without - icmd.RunCmd(icmd.Cmd{ - Command: []string{"sh", "-c", "echo $FOO"}, - Env: []string{"FOO=bar", "BAR=baz"}, - Dir: "/tmp", - Timeout: 10*time.Second, - }).Assert(t, icmd.Success) -#+END_SRC - -As usual, the intent is clear, it's simple to read and composable (with =CmdOp='s). - -[fn:1] The =icmd= package is one of the oldest =gotest.tools= package, that comes from the -[[https://github.com/docker/docker][=docker/docker=]] initially. We introduced these =CmdOp= but implementations were in -=docker/docker= at first and we never really updated them. - -* Assertions - -Let's dig into the assertion part of =icmd=. Running a command returns a struct -=Result=. It has the following methods : - -- =Assert= compares the Result against the Expected struct, and fails the test if any of - the expectations are not met. -- =Compare= compares the result to Expected and return an error if they do not match. -- =Equal= compares the result to Expected. If the result doesn't match expected - returns a formatted failure message with the command, stdout, stderr, exit code, and any - failed expectations. It returns an =assert.Comparison= struct, that can be used by other - =gotest.tools=. -- =Combined= returns the stdout and stderr combined into a single string. -- =Stderr= returns the stderr of the process as a string. -- =Stdout= returns the stdout of the process as a string. - -When you have a result, you, most likely want to do two things : - -- /assert/ that the command succeed or failed with some specific values (exit code, - stderr, stdout) -- use the output — most likely =stdout= but maybe =stderr= — in the rest of the test. - -As seen above, /asserting/ the command result is using the =Expected= struct. - -#+BEGIN_SRC go - type Expected struct { - ExitCode int // the exit code the command returned - Timeout bool // did it timeout ? - Error string // error returned by the execution (os/exe) - Out string // content of stdout - Err string // content of stderr - } -#+END_SRC - -=Success= is a constant that defines a success — it's an exit code of =0=, didn't timeout, -no error. There is also the =None= constant, that should be used for =Out= or =Err=, to -specify that we don't want any content for those standard outputs. - -#+BEGIN_SRC go - icmd.RunCmd(icmd.Command("cat", "/does/not/exist")).Assert(t, icmd.Expected{ - ExitCode: 1, - Err: "cat: /does/not/exist: No such file or directory", - }) - - // In case of success, we may want to do something with the result - result := icmd.RunCommand("cat", "/does/exist") - result.Assert(t, icmd.Success) - // Read the output line by line - scanner := bufio.NewScanner(strings.NewReader(result.Stdout())) - for scanner.Scan() { - // Do something with it - } -#+END_SRC - -If the =Result= doesn't map the =Expected=, a test failure will happen with a useful -message that will contains the executed command and what differs between the result and -the expectation. - -#+BEGIN_SRC go - result := icmd.RunCommand(…) - result.Assert(t, icmd.Expected{ - ExitCode: 101, - Out: "Something else", - Err: None, - }) - // Command: binary arg1 - // ExitCode: 99 (timeout) - // Error: exit code 99 - // Stdout: the output - // Stderr: the stderr - // - // Failures: - // ExitCode was 99 expected 101 - // Expected command to finish, but it hit the timeout - // Expected stdout to contain "Something else" - // Expected stderr to contain "[NOTHING]" - … -#+END_SRC - -Finally, we listed =Equal= above, that returns a =Comparison= struct. This means we can -use it easily with the =assert= package. As written in a [[/posts/2018-08-16-gotest-tools-assertions/][previous post (about the =assert= -package)]], I tend prefer to use =cmp.Comparison=. Let's convert the above examples using -=assert=. - -#+BEGIN_SRC go - result := icmd.RunCmd(icmd.Command("cat", "/does/not/exist")) - assert.Check(t, result.Equal(icmd.Expected{ - ExitCode: 1, - Err: "cat: /does/not/exist: No such file or directory", - })) - - // In case of success, we may want to do something with the result - result := icmd.RunCommand("cat", "/does/exist") - assert.Assert(t, result.Equal(icmd.Success)) - // Read the output line by line - scanner := bufio.NewScanner(strings.NewReader(result.Stdout())) - for scanner.Scan() { - // Do something with it - } -#+END_SRC - -* Conclusion… - -… that's a wrap. The =icmd= package allows to easily run command and describe what result -are expected of the execution, with the least noise possible. We *use this package heavily* -on several =docker/*= projects (the engine, the cli)… diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-09-18-gotest-tools-icmd/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-09-18-gotest-tools-icmd/index.html @@ -1,304 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-09-18-gotest-tools-icmd/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools icmd</h1><a href='https://vincent.demeester.fr/posts/2018-09-18-gotest-tools-icmd/'></a> - <address class="signature"> - <span class="date">Tue, 18 September, 2018</span> - <span class="words">(1100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-exec"><a href="/tags/#exec">exec<span>1</span></a></li> - - - <li class="tag tag-command"><a href="/tags/#command">command<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Let’s continue the <a href="https://gotest.tools"><code>gotest.tools</code></a> serie, this time with the <code>icmd</code> package.</p> - -<blockquote> -<p>Package icmd executes binaries and provides convenient assertions for testing the results.</p> -</blockquote> - -<p>After file-system operations (seen in <a href="/posts/2018-09-14-gotest-tools-fs/"><code>fs</code></a>), another common use-case in tests is to -<strong>execute a command</strong>. The reasons can be you’re testing the <code>cli</code> you’re currently writing -or you need to setup something using a command line. A classic execution in a test might -lookup like the following.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">cmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"echo"</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">)</span> -<span class="nx">cmd</span><span class="p">.</span><span class="nx">Stout</span> <span class="p">=</span> <span class="o">&</span><span class="nx">stdout</span> -<span class="nx">cmd</span><span class="p">.</span><span class="nx">Env</span> <span class="p">=</span> <span class="nx">env</span> -<span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">cmd</span><span class="p">.</span><span class="nf">Run</span><span class="p">();</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> - <span class="nx">t</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> -<span class="p">}</span> -<span class="k">if</span> <span class="nb">string</span><span class="p">(</span><span class="nx">stdout</span><span class="p">)</span> <span class="o">!=</span> <span class="s">"foo"</span> <span class="p">{</span> - <span class="nx">t</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">"expected: foo, got %s"</span><span class="p">,</span> <span class="nb">string</span><span class="p">(</span><span class="nx">stdout</span><span class="p">))</span> -<span class="p">}</span></code></pre></div> -<p>The package <code>icmd</code> is there to ease your pain (as usual 😉) — we used <em>the name <code>icmd</code></em> -instead of <code>cmd</code> because it’s a pretty common identifier in Go source code, thus would be -really easy to <em>shadow</em> — and have some really weird problems going on.</p> - -<p>The usual <code>icmd</code> workflow is the following:</p> - -<ol> -<li>Describe the command you want to execute using : type <code>Cmd</code>, function <code>Command</code> and -<code>CmdOp</code> operators.</li> -<li>Run it using : function <code>RunCmd</code> or <code>RunCommand</code> (that does 1. for you). You can also -use <code>StartCmd</code> and <code>WaitOnCmd</code> if you want more control on the execution workflow.</li> -<li>Check the result using the <code>Assert</code>, <code>Equal</code> or <code>Compare</code> methods attached to the -<code>Result</code> struct that the command execution return.</li> -</ol> - -<h2 id="create-and-run-a-command">Create and run a command</h2> - -<p>Let’s first dig how to create commands. In this part, the assumption here is that the -command is successful, so we’ll have <code>.Assert(t, icmd.Success)</code> for now — we’ll learn more -about <code>Assert</code> in the next section 👼.</p> - -<p>The simplest way to create and run a command is using <code>RunCommand</code>, it has the same -signature as <code>os/exec.Command</code>. A simple command execution goes as below.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCommand</span><span class="p">(</span><span class="s">"echo"</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">).</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">icmd</span><span class="p">.</span><span class="nx">Sucess</span><span class="p">)</span></code></pre></div> -<p>Sometimes, you need to customize the command a bit more, like adding some environment -variable. In those case, you are going to use <code>RunCmd</code>, it takes a <code>Cmd</code> and operators. -Let’s look at those functions.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">RunCmd</span><span class="p">(</span><span class="nx">cmd</span> <span class="nx">Cmd</span><span class="p">,</span> <span class="nx">cmdOperators</span> <span class="o">...</span><span class="nx">CmdOp</span><span class="p">)</span> <span class="o">*</span><span class="nx">Result</span> - -<span class="kd">func</span> <span class="nf">Command</span><span class="p">(</span><span class="nx">command</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">args</span> <span class="o">...</span><span class="kt">string</span><span class="p">)</span> <span class="nx">Cmd</span> - -<span class="kd">type</span> <span class="nx">Cmd</span> <span class="kd">struct</span> <span class="p">{</span> - <span class="nx">Command</span> <span class="p">[]</span><span class="kt">string</span> - <span class="nx">Timeout</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span> - <span class="nx">Stdin</span> <span class="nx">io</span><span class="p">.</span><span class="nx">Reader</span> - <span class="nx">Stdout</span> <span class="nx">io</span><span class="p">.</span><span class="nx">Writer</span> - <span class="nx">Dir</span> <span class="kt">string</span> - <span class="nx">Env</span> <span class="p">[]</span><span class="kt">string</span> -<span class="p">}</span></code></pre></div> -<p>As we’ve seen <a href="/posts/2017-01-01-go-testing-functionnal-builders/">multiple</a> <a href="/posts/2018-08-16-gotest-tools-assertions/">times</a> <a href="/posts/2018-09-14-gotest-tools-fs/">before</a>, it uses the <em>powerful</em> functional arguments. At the -time I wrote this post, the <code>icmd</code> package doesn’t contains too much <code>CmdOp</code> <sup class="footnote-ref" id="fnref:fn-1"><a href="#fn:fn-1">1</a></sup>, so I’ll -propose two version for each example : one with <code>CmdOpt</code> present in <a href="https://github.com/gotestyourself/gotest.tools/pull/122">this PR</a> and one -without them.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="c1">// With -</span><span class="c1"></span><span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCmd</span><span class="p">(</span><span class="nx">icmd</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"sh"</span><span class="p">,</span> <span class="s">"-c"</span><span class="p">,</span> <span class="s">"echo $FOO"</span><span class="p">),</span> - <span class="nx">icmd</span><span class="p">.</span><span class="nf">WithEnv</span><span class="p">(</span><span class="s">"FOO=bar"</span><span class="p">,</span> <span class="s">"BAR=baz"</span><span class="p">),</span> <span class="nx">icmd</span><span class="p">.</span><span class="nf">Dir</span><span class="p">(</span><span class="s">"/tmp"</span><span class="p">),</span> - <span class="nx">icmd</span><span class="p">.</span><span class="nf">WithTimeout</span><span class="p">(</span><span class="mi">10</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">),</span> -<span class="p">).</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">icmd</span><span class="p">.</span><span class="nx">Success</span><span class="p">)</span> - -<span class="c1">// Without -</span><span class="c1"></span><span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCmd</span><span class="p">(</span><span class="nx">icmd</span><span class="p">.</span><span class="nx">Cmd</span><span class="p">{</span> - <span class="nx">Command</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"sh"</span><span class="p">,</span> <span class="s">"-c"</span><span class="p">,</span> <span class="s">"echo $FOO"</span><span class="p">},</span> - <span class="nx">Env</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"FOO=bar"</span><span class="p">,</span> <span class="s">"BAR=baz"</span><span class="p">},</span> - <span class="nx">Dir</span><span class="p">:</span> <span class="s">"/tmp"</span><span class="p">,</span> - <span class="nx">Timeout</span><span class="p">:</span> <span class="mi">10</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">,</span> -<span class="p">}).</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">icmd</span><span class="p">.</span><span class="nx">Success</span><span class="p">)</span></code></pre></div> -<p>As usual, the intent is clear, it’s simple to read and composable (with <code>CmdOp</code>’s).</p> - -<h2 id="assertions">Assertions</h2> - -<p>Let’s dig into the assertion part of <code>icmd</code>. Running a command returns a struct -<code>Result</code>. It has the following methods :</p> - -<ul> -<li><code>Assert</code> compares the Result against the Expected struct, and fails the test if any of -the expectations are not met.</li> -<li><code>Compare</code> compares the result to Expected and return an error if they do not match.</li> -<li><code>Equal</code> compares the result to Expected. If the result doesn’t match expected -returns a formatted failure message with the command, stdout, stderr, exit code, and any -failed expectations. It returns an <code>assert.Comparison</code> struct, that can be used by other -<code>gotest.tools</code>.</li> -<li><code>Combined</code> returns the stdout and stderr combined into a single string.</li> -<li><code>Stderr</code> returns the stderr of the process as a string.</li> -<li><code>Stdout</code> returns the stdout of the process as a string.</li> -</ul> - -<p>When you have a result, you, most likely want to do two things :</p> - -<ul> -<li><em>assert</em> that the command succeed or failed with some specific values (exit code, -stderr, stdout)</li> -<li>use the output — most likely <code>stdout</code> but maybe <code>stderr</code> — in the rest of the test.</li> -</ul> - -<p>As seen above, <em>asserting</em> the command result is using the <code>Expected</code> struct.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Expected</span> <span class="kd">struct</span> <span class="p">{</span> - <span class="nx">ExitCode</span> <span class="kt">int</span> <span class="c1">// the exit code the command returned -</span><span class="c1"></span> <span class="nx">Timeout</span> <span class="kt">bool</span> <span class="c1">// did it timeout ? -</span><span class="c1"></span> <span class="nx">Error</span> <span class="kt">string</span> <span class="c1">// error returned by the execution (os/exe) -</span><span class="c1"></span> <span class="nx">Out</span> <span class="kt">string</span> <span class="c1">// content of stdout -</span><span class="c1"></span> <span class="nx">Err</span> <span class="kt">string</span> <span class="c1">// content of stderr -</span><span class="c1"></span><span class="p">}</span></code></pre></div> -<p><code>Success</code> is a constant that defines a success — it’s an exit code of <code>0</code>, didn’t timeout, -no error. There is also the <code>None</code> constant, that should be used for <code>Out</code> or <code>Err</code>, to -specify that we don’t want any content for those standard outputs.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCmd</span><span class="p">(</span><span class="nx">icmd</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"cat"</span><span class="p">,</span> <span class="s">"/does/not/exist"</span><span class="p">)).</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">icmd</span><span class="p">.</span><span class="nx">Expected</span><span class="p">{</span> - <span class="nx">ExitCode</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> - <span class="nx">Err</span><span class="p">:</span> <span class="s">"cat: /does/not/exist: No such file or directory"</span><span class="p">,</span> -<span class="p">})</span> - -<span class="c1">// In case of success, we may want to do something with the result -</span><span class="c1"></span><span class="nx">result</span> <span class="o">:=</span> <span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCommand</span><span class="p">(</span><span class="s">"cat"</span><span class="p">,</span> <span class="s">"/does/exist"</span><span class="p">)</span> -<span class="nx">result</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">icmd</span><span class="p">.</span><span class="nx">Success</span><span class="p">)</span> -<span class="c1">// Read the output line by line -</span><span class="c1"></span><span class="nx">scanner</span> <span class="o">:=</span> <span class="nx">bufio</span><span class="p">.</span><span class="nf">NewScanner</span><span class="p">(</span><span class="nx">strings</span><span class="p">.</span><span class="nf">NewReader</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nf">Stdout</span><span class="p">()))</span> -<span class="k">for</span> <span class="nx">scanner</span><span class="p">.</span><span class="nf">Scan</span><span class="p">()</span> <span class="p">{</span> - <span class="c1">// Do something with it -</span><span class="c1"></span><span class="p">}</span></code></pre></div> -<p>If the <code>Result</code> doesn’t map the <code>Expected</code>, a test failure will happen with a useful -message that will contains the executed command and what differs between the result and -the expectation.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">result</span> <span class="o">:=</span> <span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCommand</span><span class="p">(</span><span class="err">…</span><span class="p">)</span> -<span class="nx">result</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">icmd</span><span class="p">.</span><span class="nx">Expected</span><span class="p">{</span> - <span class="nx">ExitCode</span><span class="p">:</span> <span class="mi">101</span><span class="p">,</span> - <span class="nx">Out</span><span class="p">:</span> <span class="s">"Something else"</span><span class="p">,</span> - <span class="nx">Err</span><span class="p">:</span> <span class="nx">None</span><span class="p">,</span> -<span class="p">})</span> -<span class="c1">// Command: binary arg1 -</span><span class="c1">// ExitCode: 99 (timeout) -</span><span class="c1">// Error: exit code 99 -</span><span class="c1">// Stdout: the output -</span><span class="c1">// Stderr: the stderr -</span><span class="c1">// -</span><span class="c1">// Failures: -</span><span class="c1">// ExitCode was 99 expected 101 -</span><span class="c1">// Expected command to finish, but it hit the timeout -</span><span class="c1">// Expected stdout to contain "Something else" -</span><span class="c1">// Expected stderr to contain "[NOTHING]" -</span><span class="c1"></span><span class="err">…</span></code></pre></div> -<p>Finally, we listed <code>Equal</code> above, that returns a <code>Comparison</code> struct. This means we can -use it easily with the <code>assert</code> package. As written in a <a href="/posts/2018-08-16-gotest-tools-assertions/">previous post (about the <code>assert</code> -package)</a>, I tend prefer to use <code>cmp.Comparison</code>. Let’s convert the above examples using -<code>assert</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">result</span> <span class="o">:=</span> <span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCmd</span><span class="p">(</span><span class="nx">icmd</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"cat"</span><span class="p">,</span> <span class="s">"/does/not/exist"</span><span class="p">))</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Check</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">result</span><span class="p">.</span><span class="nf">Equal</span><span class="p">(</span><span class="nx">icmd</span><span class="p">.</span><span class="nx">Expected</span><span class="p">{</span> - <span class="nx">ExitCode</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> - <span class="nx">Err</span><span class="p">:</span> <span class="s">"cat: /does/not/exist: No such file or directory"</span><span class="p">,</span> -<span class="p">}))</span> - -<span class="c1">// In case of success, we may want to do something with the result -</span><span class="c1"></span><span class="nx">result</span> <span class="o">:=</span> <span class="nx">icmd</span><span class="p">.</span><span class="nf">RunCommand</span><span class="p">(</span><span class="s">"cat"</span><span class="p">,</span> <span class="s">"/does/exist"</span><span class="p">)</span> -<span class="nx">assert</span><span class="p">.</span><span class="nf">Assert</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">result</span><span class="p">.</span><span class="nf">Equal</span><span class="p">(</span><span class="nx">icmd</span><span class="p">.</span><span class="nx">Success</span><span class="p">))</span> -<span class="c1">// Read the output line by line -</span><span class="c1"></span><span class="nx">scanner</span> <span class="o">:=</span> <span class="nx">bufio</span><span class="p">.</span><span class="nf">NewScanner</span><span class="p">(</span><span class="nx">strings</span><span class="p">.</span><span class="nf">NewReader</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nf">Stdout</span><span class="p">()))</span> -<span class="k">for</span> <span class="nx">scanner</span><span class="p">.</span><span class="nf">Scan</span><span class="p">()</span> <span class="p">{</span> - <span class="c1">// Do something with it -</span><span class="c1"></span><span class="p">}</span></code></pre></div> -<h2 id="conclusion">Conclusion…</h2> - -<p>… that’s a wrap. The <code>icmd</code> package allows to easily run command and describe what result -are expected of the execution, with the least noise possible. We <strong>use this package heavily</strong> -on several <code>docker/*</code> projects (the engine, the cli)…</p> -<div class="footnotes"> - -<hr /> - -<ol> -<li id="fn:fn-1">The <code>icmd</code> package is one of the oldest <code>gotest.tools</code> package, that comes from the <a href="https://github.com/docker/docker"><code>docker/docker</code></a> initially. We introduced these <code>CmdOp</code> but implementations were in <code>docker/docker</code> at first and we never really updated them. - <a class="footnote-return" href="#fnref:fn-1"><sup>[return]</sup></a></li> -</ol> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2018-12-16-link/" title="Go testing style guide">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-09-14-gotest-tools-fs/" title="Golang testing — gotest.tools fs">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2018-12-16-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2018-12-16-link/index.html @@ -1,115 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2018-12-16-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Go testing style guide</h1><a href='https://vincent.demeester.fr/posts/2018-12-16-link/'></a> - <address class="signature"> - <span class="date">Sun, 16 December, 2018</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - <br/> - - </ul> - </header> - - <p>A small (opiniated) style guide for Writing Go tests.</p> - <p>🔗 <a href="https://arp242.net/weblog/go-testing-style.html" class="link">https://arp242.net/weblog/go-testing-style.html</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-01-10-link/" title="log.Fatal vs log.Panic · Iskander Sharipov technical blog">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-09-18-gotest-tools-icmd/" title="Golang testing — gotest.tools icmd">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-01-10-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-01-10-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-01-10-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">log.Fatal vs log.Panic · Iskander Sharipov technical blog</h1><a href='https://vincent.demeester.fr/posts/2019-01-10-link/'></a> - <address class="signature"> - <span class="date">Thu, 10 January, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-log"><a href="/tags/#log">log<span>1</span></a></li> - - - <li class="tag tag-panic"><a href="/tags/#panic">panic<span>1</span></a></li> - - - <li class="tag tag-fatal"><a href="/tags/#fatal">fatal<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>Why you should prefer to use log.Panic instead of log.Fatal in go code</p> - <p>🔗 <a href="https://quasilyte.github.io/blog/post/log-fatal-vs-log-panic/" class="link">https://quasilyte.github.io/blog/post/log-fatal-vs-log-panic/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-01-20-2018-year-review/" title="2018 year review">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2018-12-16-link/" title="Go testing style guide">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-01-20-2018-year-review.org b/www/vincent.demeester.fr/content/legacy/posts/2019-01-20-2018-year-review.org @@ -1,151 +0,0 @@ -#+title: 2018 year review -#+date: <2019-01-20 Sun> -#+filetags: review - -* Introduction - -Here is my review of 2018, the first of its kind, hopefully not the last 👼. I saw -some[fn:1] /2018[fn:2] reviews/[fn:3] articles[fn:4] in my Feedly feed and I thought it -would be a good idea to write my own too. - -I'll try in the next year — maybe month if I ever want to do monthly reviews — to automate -some of it ; using the beloved =org-mode=. - -[fn:1] [[https://punchagan.muse-amuse.in/blog/2018-in-review/][2018 in Review - Noetic Nought]] -[fn:2] [[https://medium.com/@buster/42-dig-deeper-e2278d1fe015][42 — Dig deeper – Buster Benson – Medium]] -[fn:3] [[https://jvns.ca/blog/2018/12/23/2018--year-in-review/][2018: Year in review - Julia Evans]] -[fn:4] [[https://writing.natwelch.com/post/685][Nat? Nat. Nat! | #685 2018 Year in Review]] - -* Work - -The big change this year is : I changed job 👼. I went from Docker Inc. to Red Hat. I -needed a change and 5 month in, I think it was the *best choice I made in my life* so far -💃. I'm doing open-source for a living and best part, I am working remotely (more on that -later). - -Before that, at Docker Inc., I continued the work I started years before, -a.k.a. maintaining the Moby project and the docker engine, among other Docker project -(both open-source and closed-source). I also helped the work on the compose side, from the -root of =docker/compose-on-kubernetes= (before it got open-sourced), to the =docker/app= -experiments. - -At Red Hat, I started to work upstream in the Kubernetes community, mainly on the Knative -projects. I also work on the Openshift Cloud Function project (and thus team), and those -fellows are awesome ! Digging more into Openshift, and other part of the Red Hat portfolio -is a really good learning experience, and it's just the start ! - -As stated above, I am now working home, full-time. I could work from home from time to -time when I was at Docker inc, but working home full-time is another kind of beast. So far -it is really good, some adjustments were needed but it's for the best. Here is a small -take on "working from home": - -- It's easy to have *no distraction*, thus having *really productive* piece of time -- It's also *really easy to work long day or really long period of time*. It's especially - true if, like me, you work on a distributed team (across multiple timezones). - - I ended up using the Pomodoro technique to make sure I move at least few times a day - - I try to make sure I don't make an habits of checking out work code, email and other - material after a certain hour in the evening. It's ok to do it sometimes, but for your - sanity, you need some rest time. -- It's easy to adapt your day to circumstance. If you got to run errands in the middle of - the day, it's no big deal. You can take the time back later on. -- It's so good to have *no* commmute time. That said I end up /walking or taking the bike/ - early morning to clear my head before work 😝. - -* Personal - -Health wise, it's a mix of good and bad year. The first half was really good, the second -way less. End of august, I felt something weird in the right knee, and well, turns out my -internal meniscus is in a real bad shape. Just as before joining Docker, I'm gonna need a -surgery, on the right knee that time. It's gonna affect 2019 (the first half, I'm not -gonna be able to move around much but.. meh, it's life). - -Now that I work from home, I'm really glad I got a standing desk at the end of 2017. I -tend to work standing most of the time -- except when my knee hurts (and most likely for -few months after the surgery 😅). I invested on a ultrawide screen, to get the same -experience I had at Docker. And oh boy those screens are good ! - -I also try to clean my desk and it's "neighboorhood". As I get older, I want less messy -stuuf (desk, flat, ...). I'm leaning towards having less stuff, being commputer related or -not. It's not minimalism, but it feel good to have less stuff, but stuff that you actually -use. I still have trouble throwing old computer away, mainly because I fell they can be -useful in some way. - -[[/images/2019/01/desk1.jpg]] - -This year I migrate all of my "infrastructure" computer to NixOS. I learned a lot of Nix, -reworked my configuration multiple time to end up with a [[https://github.com/vdemeester/nixos-configuration.git][system configuration repository]] -that uses modules, and a [[https://github.com/vdemeester/home.git][/home configuration repository/]] (for user configuration). The -[[https://github.com/vdemeester/home.git][home]] repository uses [[https://github.com/rycee/home-manager.git][=home-manager=]] and thus doesn't make any assumption of running on top -of NixOS. This allows me to have an /easy to get/ setup on any system that =nixpkgs= -supports (any Linux distribution, Mac OSX, Windows Subsystem Linux). The current -configuration is not yet optimal but I'm pretty happy about what I got : - -- Custom DNS server @home to make it easier to target local hosts. -- Local proxies and mirrors for docker images, nixpkgs binary package and go modules to - eat less bandwidth. -- Easy to setup VPN using [[https://www.wireguard.com/][WireGuard]]. -- File replication using =syncthing= and automatic backup on my local NAS. -- Automatic system upgrade, thanks to NixOS. I'll probably write an article about that - later on this year. - -I started to use =todoist= in 2017, and boy, oh boy, it helped me quite a lot ! I'm using -it daily to organize my work and quickly get idea, and /todos/ out of my head. The main -problem with it is it's not integrated with another tool I'm using daily : Emacs and -=org-mode=. =org-mode= is a fantastic piece of software and is, on its own, the main -reason for me to invest time in Emacs. I'm taking note in =org-mode=, I write my daily -standup notes in there too. I end up going back and forth between =org-mode= and =todoist= -for those daily standup. I am lazy, I want to automate that. And the best way to do it, is -to also use =org-mode= for task management. I'm in a /transition/ mode right now, but my -goal for 2019 is to use todoist to take quick note/todo(s) on the move (aka on the phone) -and use =org-mode= for the rest. - - -* Reading & Writing - -I used to like reading, but the past years, I didn't really read that much, except some -technical books. 2018 in, that respect, is not an exception, I didn't read too much. Worse -than that, I started some book and stopped at some point, for no apparent reason ; and -now, I need to start back from the beginning, which, well, is not helping me want to read -them again. - -I'm trying two thing to counter that and consume more books for the years to come. - -1. I now have a reading list on my =org-mode= files, where I track which one I read and - when I read them ; and maybe notes too. I have a lot of book on my kindle, that only - wait for one thing, being read.. -2. I subscribed to [[https://www.audible.fr][Audible]] 👼. Working from home, I tend to take a long break after lunch, - where I'm going for a walk, for around an hour. I can't read while walking but I - definitely can listen - that make audio books perfect for these moments. I also - alternate between audio books and non-musical podcasts. - -On the writing side, 2017 was a slow year in terms of writing (only 2 posts), 2018 was a -bit better, 6 posts -- it's a bit cheating, as it was mainly between changing jobs, and -on a series I still need to finish. I'm hoping to write more this year, hence the goals -I've set to myself below. - -* 2019 Goals - -- *Get back on my feet after knee surgery (exercices, …)* 🏃 -- *Read at least one book per month (be audible, ebook or paper)* 📖 -- *Giving at least a talk (on Knative, containers, nixos, ..)* 🙊 - - I didn't give too much talk in 2018 (at least less than 2017). I'm gonna try to get back - at it this year. The surgery won't help but it's just few months. - -- *At least 1 video per month* 📹 - - I want to start recording some video, as I feel it's an easier medium than writing and, - well, I wanna try ! - -- *At least 1 post per month* ✍️ -- *Enhance my emacs skills (aka don't be afraid of the lisp)* ⌨️ - - I'm using Emacs for almost anything that doesn't happen in a web browser. But I still - feel like a newbie. I want to learn more, to write more lisp that help me being even - more lazier (aka achieve more doing less 😝) - -- *Enhance my Nix(OS) skills* 🐧 -- *Learn / master a new language* 🎽 - - I'm working with Go 90% of my time. I want to master and learn more language. On my list - are Emacs Lisp, Rust, Typescript and Haskell. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-01-20-2018-year-review/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-01-20-2018-year-review/index.html @@ -1,284 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-01-20-2018-year-review/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">2018 year review</h1><a href='https://vincent.demeester.fr/posts/2019-01-20-2018-year-review/'></a> - <address class="signature"> - <span class="date">Sun, 20 January, 2019</span> - <span class="words">(1500 Words)</span> - </address> - <ul class="tag_box inline"> - - - - - - <li class="tag tag-review"><a href="/tags/#review">review<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Here is my review of 2018, the first of its kind, hopefully not the last 👼. I saw -some<sup class="footnote-ref" id="fnref:fn-1"><a href="#fn:fn-1">1</a></sup> <em>2018<sup class="footnote-ref" id="fnref:fn-2"><a href="#fn:fn-2">2</a></sup> reviews</em><sup class="footnote-ref" id="fnref:fn-3"><a href="#fn:fn-3">3</a></sup> articles<sup class="footnote-ref" id="fnref:fn-4"><a href="#fn:fn-4">4</a></sup> in my Feedly feed and I thought it -would be a good idea to write my own too.</p> - -<p>I’ll try in the next year — maybe month if I ever want to do monthly reviews — to automate -some of it ; using the beloved <code>org-mode</code>.</p> - -<h2 id="work">Work</h2> - -<p>The big change this year is : I changed job 👼. I went from Docker Inc. to Red Hat. I -needed a change and 5 month in, I think it was the <strong>best choice I made in my life</strong> so far -💃. I’m doing open-source for a living and best part, I am working remotely (more on that -later).</p> - -<p>Before that, at Docker Inc., I continued the work I started years before, -a.k.a. maintaining the Moby project and the docker engine, among other Docker project -(both open-source and closed-source). I also helped the work on the compose side, from the -root of <code>docker/compose-on-kubernetes</code> (before it got open-sourced), to the <code>docker/app</code> -experiments.</p> - -<p>At Red Hat, I started to work upstream in the Kubernetes community, mainly on the Knative -projects. I also work on the Openshift Cloud Function project (and thus team), and those -fellows are awesome ! Digging more into Openshift, and other part of the Red Hat portfolio -is a really good learning experience, and it’s just the start !</p> - -<p>As stated above, I am now working home, full-time. I could work from home from time to -time when I was at Docker inc, but working home full-time is another kind of beast. So far -it is really good, some adjustments were needed but it’s for the best. Here is a small -take on “working from home”:</p> - -<ul> -<li>It’s easy to have <strong>no distraction</strong>, thus having <strong>really productive</strong> piece of time</li> -<li>It’s also <strong>really easy to work long day or really long period of time</strong>. It’s especially -true if, like me, you work on a distributed team (across multiple timezones). - -<ul> -<li>I ended up using the Pomodoro technique to make sure I move at least few times a day</li> -<li>I try to make sure I don’t make an habits of checking out work code, email and other -material after a certain hour in the evening. It’s ok to do it sometimes, but for your -sanity, you need some rest time.</li> -</ul></li> -<li>It’s easy to adapt your day to circumstance. If you got to run errands in the middle of -the day, it’s no big deal. You can take the time back later on.</li> -<li>It’s so good to have <strong>no</strong> commmute time. That said I end up <em>walking or taking the bike</em> -early morning to clear my head before work 😝.</li> -</ul> - -<h2 id="personal">Personal</h2> - -<p>Health wise, it’s a mix of good and bad year. The first half was really good, the second -way less. End of august, I felt something weird in the right knee, and well, turns out my -internal meniscus is in a real bad shape. Just as before joining Docker, I’m gonna need a -surgery, on the right knee that time. It’s gonna affect 2019 (the first half, I’m not -gonna be able to move around much but.. meh, it’s life).</p> - -<p>Now that I work from home, I’m really glad I got a standing desk at the end of 2017. I -tend to work standing most of the time – except when my knee hurts (and most likely for -few months after the surgery 😅). I invested on a ultrawide screen, to get the same -experience I had at Docker. And oh boy those screens are good !</p> - -<p>I also try to clean my desk and it’s “neighboorhood”. As I get older, I want less messy -stuuf (desk, flat, …). I’m leaning towards having less stuff, being commputer related or -not. It’s not minimalism, but it feel good to have less stuff, but stuff that you actually -use. I still have trouble throwing old computer away, mainly because I fell they can be -useful in some way.</p> - -<figure> - <img src="/images/2019/01/desk1.jpg"/> -</figure> - - -<p>This year I migrate all of my “infrastructure” computer to NixOS. I learned a lot of Nix, -reworked my configuration multiple time to end up with a <a href="https://github.com/vdemeester/nixos-configuration.git">system configuration repository</a> -that uses modules, and a <a href="https://github.com/vdemeester/home.git"><em>home configuration repository</em></a> (for user configuration). The -<a href="https://github.com/vdemeester/home.git">home</a> repository uses <a href="https://github.com/rycee/home-manager.git"><code>home-manager</code></a> and thus doesn’t make any assumption of running on top -of NixOS. This allows me to have an <em>easy to get</em> setup on any system that <code>nixpkgs</code> -supports (any Linux distribution, Mac OSX, Windows Subsystem Linux). The current -configuration is not yet optimal but I’m pretty happy about what I got :</p> - -<ul> -<li>Custom DNS server @home to make it easier to target local hosts.</li> -<li>Local proxies and mirrors for docker images, nixpkgs binary package and go modules to -eat less bandwidth.</li> -<li>Easy to setup VPN using <a href="https://www.wireguard.com/">WireGuard</a>.</li> -<li>File replication using <code>syncthing</code> and automatic backup on my local NAS.</li> -<li>Automatic system upgrade, thanks to NixOS. I’ll probably write an article about that -later on this year.</li> -</ul> - -<p>I started to use <code>todoist</code> in 2017, and boy, oh boy, it helped me quite a lot ! I’m using -it daily to organize my work and quickly get idea, and <em>todos</em> out of my head. The main -problem with it is it’s not integrated with another tool I’m using daily : Emacs and -<code>org-mode</code>. <code>org-mode</code> is a fantastic piece of software and is, on its own, the main -reason for me to invest time in Emacs. I’m taking note in <code>org-mode</code>, I write my daily -standup notes in there too. I end up going back and forth between <code>org-mode</code> and <code>todoist</code> -for those daily standup. I am lazy, I want to automate that. And the best way to do it, is -to also use <code>org-mode</code> for task management. I’m in a <em>transition</em> mode right now, but my -goal for 2019 is to use todoist to take quick note/todo(s) on the move (aka on the phone) -and use <code>org-mode</code> for the rest.</p> - -<h2 id="reading-and-writing">Reading & Writing</h2> - -<p>I used to like reading, but the past years, I didn’t really read that much, except some -technical books. 2018 in, that respect, is not an exception, I didn’t read too much. Worse -than that, I started some book and stopped at some point, for no apparent reason ; and -now, I need to start back from the beginning, which, well, is not helping me want to read -them again.</p> - -<p>I’m trying two thing to counter that and consume more books for the years to come.</p> - -<ol> -<li>I now have a reading list on my <code>org-mode</code> files, where I track which one I read and -when I read them ; and maybe notes too. I have a lot of book on my kindle, that only -wait for one thing, being read..</li> -<li>I subscribed to <a href="https://www.audible.fr">Audible</a> 👼. Working from home, I tend to take a long break after lunch, -where I’m going for a walk, for around an hour. I can’t read while walking but I -definitely can listen - that make audio books perfect for these moments. I also -alternate between audio books and non-musical podcasts.</li> -</ol> - -<p>On the writing side, 2017 was a slow year in terms of writing (only 2 posts), 2018 was a -bit better, 6 posts – it’s a bit cheating, as it was mainly between changing jobs, and -on a series I still need to finish. I’m hoping to write more this year, hence the goals -I’ve set to myself below.</p> - -<h2 id="2019-goals">2019 Goals</h2> - -<ul> -<li><strong>Get back on my feet after knee surgery (exercices, …)</strong> 🏃</li> -<li><strong>Read at least one book per month (be audible, ebook or paper)</strong> 📖</li> - -<li><p><strong>Giving at least a talk (on Knative, containers, nixos, ..)</strong> 🙊</p> - -<p>I didn’t give too much talk in 2018 (at least less than 2017). I’m gonna try to get back -at it this year. The surgery won’t help but it’s just few months.</p></li> - -<li><p><strong>At least 1 video per month</strong> 📹</p> - -<p>I want to start recording some video, as I feel it’s an easier medium than writing and, -well, I wanna try !</p></li> - -<li><p><strong>At least 1 post per month</strong> ✍️</p></li> - -<li><p><strong>Enhance my emacs skills (aka don’t be afraid of the lisp)</strong> ⌨️</p> - -<p>I’m using Emacs for almost anything that doesn’t happen in a web browser. But I still -feel like a newbie. I want to learn more, to write more lisp that help me being even -more lazier (aka achieve more doing less 😝)</p></li> - -<li><p><strong>Enhance my Nix(OS) skills</strong> 🐧</p></li> - -<li><p><strong>Learn / master a new language</strong> 🎽</p> - -<p>I’m working with Go 90% of my time. I want to master and learn more language. On my list -are Emacs Lisp, Rust, Typescript and Haskell.</p></li> -</ul> -<div class="footnotes"> - -<hr /> - -<ol> -<li id="fn:fn-1"><a href="https://punchagan.muse-amuse.in/blog/2018-in-review/">2018 in Review - Noetic Nought</a> - <a class="footnote-return" href="#fnref:fn-1"><sup>[return]</sup></a></li> -<li id="fn:fn-2"><a href="https://medium.com/@buster/42-dig-deeper-e2278d1fe015">42 — Dig deeper – Buster Benson – Medium</a> - <a class="footnote-return" href="#fnref:fn-2"><sup>[return]</sup></a></li> -<li id="fn:fn-3"><a href="https://jvns.ca/blog/2018/12/23/2018--year-in-review/">2018: Year in review - Julia Evans</a> - <a class="footnote-return" href="#fnref:fn-3"><sup>[return]</sup></a></li> -<li id="fn:fn-4"><a href="https://writing.natwelch.com/post/685">Nat? Nat. Nat! | #685 2018 Year in Review</a> - <a class="footnote-return" href="#fnref:fn-4"><sup>[return]</sup></a></li> -</ol> -</div> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-01-26-nix-run-alias/" title="nix run aliases">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-01-10-link/" title="log.Fatal vs log.Panic · Iskander Sharipov technical blog">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-01-26-nix-run-alias.org b/www/vincent.demeester.fr/content/legacy/posts/2019-01-26-nix-run-alias.org @@ -1,200 +0,0 @@ -#+title: Nix run aliases -#+date: <2019-01-26 Sat> -#+filetags: nixos fish alias nix shell home manager - -* Introduction - -I use [[https://nixos.org/][=NixOS=]] each and every day, everywhere. One really cool feature of =nix= is -=nix-shell= and more recently (with =nix= >= =2.0.0=), =nix run=. - -#+begin_src man -Usage: nix run <FLAGS>... <INSTALLABLES>... - -Summary: run a shell in which the specified packages are available. - -Flags: - --arg <NAME> <EXPR> argument to be passed to Nix functions - --argstr <NAME> <STRING> string-valued argument to be passed to Nix functions - -c, --command <COMMAND> <ARGS> command and arguments to be executed; defaults to 'bash' - -f, --file <FILE> evaluate FILE rather than the default - -i, --ignore-environment clear the entire environment (except those specified with --keep) - -I, --include <PATH> add a path to the list of locations used to look up <...> file names - -k, --keep <NAME> keep specified environment variable - -u, --unset <NAME> unset specified environment variable - -Examples: - - To start a shell providing GNU Hello from NixOS 17.03: - $ nix run -f channel:nixos-17.03 hello - - To start a shell providing youtube-dl from your 'nixpkgs' channel: - $ nix run nixpkgs.youtube-dl - - To run GNU Hello: - $ nix run nixpkgs.hello -c hello --greeting 'Hi everybody!' - - To run GNU Hello in a chroot store: - $ nix run --store ~/my-nix nixpkgs.hello -c hello - -Note: this program is EXPERIMENTAL and subject to change. -#+end_src - -As you can see from the =-h= summary, it makes it really easy to run a shell or a command -with some packages that are not in your main configuration. It will download the -package(s) if there are not available in the Nix store (=/nix/store/=). - -A few month ago I decided it would be a perfect use-case for command I do not run -often. My idea was, let's define =aliases= (in the shell) that would make a simple command -call, like =ncdu=, become =nix run nixpkgs.ncdu -c ndcu=. My /shell of choice/ is [[https://fishshell.com/][fish]], so -I decided to dig into the /language/ in order to implement that. - -The use case is the following : -- When I type =foo=, I want the command =foo= in package =bar= to be executed. -- I want to be able to pin a channel for the package — I'm using [[https://matthewbauer.us/][Matthew Bauer]] [[https://matthewbauer.us/blog/channel-changing.html][Channel - Changing with Nix]] setup for pin-pointing a given channel. - -* Fish aliases experimentation - -I had a feeling the built-in =alias= would not work so I ended up trying to define a -/dynamic/ function that would be the name of the command. That's the beauty of the shell, -everything is a command, even function appears as commands. If you define a function -=foo()=, you will be able to run =foo= in your shell, *and* it will take precedence over -the =foo= executable file that would be in your =PATH=. - -I ended up with two main helper function that would create those /alias/ function. - -#+begin_src fish - function _nix_run_package - set -l s $argv[1] - set -l package (string split ":" $s) - switch (count $package) - case 1 - _nix_run $s $s $argv[2] $argv[3] - case 2 - _nix_run $package[1] $package[2] $argv[2] $argv[3] - end - end - - function _nix_run - set -l c $argv[1] - set -l p $argv[2] - set -l channel $argv[3] - set -l channelsfile $argv[4] - function $c --inherit-variable c --inherit-variable p --inherit-variable channel --inherit-variable channelsfile - set -l cmd nix run - if test -n "$channelsfile" - set cmd $cmd -f $channelsfile - end - eval $cmd $channel.$p -c $c $argv - end - end -#+end_src - -In a nutshell, =_nix_run= is the function that create the alias function. There is so -condition in there depending on whether we gave it a channel or not. So, a call like -=_nix_run foo bar unstable channels.nix= would, in the end generate a function =foo= with -the following call : =nix run -f channels.nix unstable.bar -c foo=. - -The other function, =_nix_run_package= is there to make me write less when I define those -aliases — aka if the command and the package share the same name, I don't want to write it -twice. So, a call like =_nix_run_package foo nixpkgs= would result in a =_nix_run foo foo -nixpkgs=, whereas a call like =_nix_run_package foo:bar unstable channels.nix= would -result in a =_nix_run foo bar unstable channels.nix=. - -An example is gonna be better than the above paragraphs. This is what I used to have in my -fish configuration. - -#+begin_src fish - function _def_nix_run_aliases - set -l stable mr sshfs ncdu wakeonlan:python36Packages.wakeonlan lspci:pciutils lsusb:usbutils beet:beets gotop virt-manager:virtmanager pandoc nix-prefetch-git:nix-prefetch-scripts nix-prefetch-hg:nix-prefetch-scripts - set -l unstable op:_1password update-desktop-database:desktop-file-utils lgogdownloader - for s in $stable - _nix_run_package $s nixpkgs - end - for s in $unstable - _nix_run_package $s unstable ~/.config/nixpkgs/channels.nix - end - end - # Call the function to create the aliases - _def_nix_run_aliases -#+end_src - -This works like a charm, and for a while, I was happy. But I soon realized something : I'm -not always on my shell — like, I tend to spend more and more time in =eshell=. This also -doesn't work with graphic tools like [[https://github.com/DaveDavenport/rofi][=rofi=]]. I needed actual command, so that external -tools would benefit from that. I ended up writing a small tool, [[https://github.com/vdemeester/nr][=nr=]] that integrates -nicely with =nix= and [[https://github.com/rycee/home-manager][=home-manager=]]. - -* A proper tool : =nr= - -The gist for this tool is simple : -- create an executable script that will call =nix run ...= instead of the command -- as for the above fish script, support different channels -- make sure we don't have conflicts — if the command already exists, then don't create the - command - -The =nr= tool would have to be able to manage multiple /profile/, which really stands for -multiple file. The main reason is really about how I manage my configuration ; To make it -simple, depending on the computer my configurations are setup, I may not have =go=, thus I -don't want any =go=-related aliases for a computer that doesn't have =go= (using =go= here -but you can replace with anything). - -#+begin_src fish -$ nr default -> nr generate default -> virtmanager already exists -$ nr git -> nr generate git -#+end_src - -=nr= generates a bash script that does the =nr run …= and mark it as executable. =nr= -needs to be able to clean files it has generated (in case we removed it from -aliases). Thus, I went for a really naive comment in the script. When generating a new set -of commands, =nr= will first remove previously generated script for this profile, and for -that, it uses the comment. Let's look at what a generated script looks like, for the -default profile. - -#+begin_src bash -#!/usr/bin/env bash -# Generated by nr default -nix run nixpkgs.nix-prefetch-scripts -c nix-prefetch-git $@ -#+end_src - -The format used in =nr= is =json=. I'm not a /huge fan/ of =json= but it really was the -best format to use for this tool. The reason to use =json= are simple : - -- Go has =encoding/json= built-in, so it's really easy to =Marshall= and =Unmarshall= - structure. - #+begin_src go - type alias struct { - Command string `json:"cmd"` - Package string `json:"pkg"` - Channel string `json:"chan"` - } - #+end_src -- Nix also has built-in support for =json= : =builtins.toJSON= will marshall a /struct/ - into a json file. - -Finally, to avoid conflicts at /build time/ (=home-manager switch=) I couldn't use/define -a nix package, but to execute command(s) at the end of the build. One way to achieve it is -to use =file.?.onChange= script, which is executed after [[https://github.com/rycee/home-manager][=home-manager=]] has updated the -environment, *if* the file has changed. That means it's possible to check for executable -files in =~/.nix-profile/bin/= for defined aliases and create those that are not there, -with =nr=. My configuration then looks like the following. - -#+BEGIN_SRC nix - xdg.configFile."nr/default" = { - text = builtins.toJSON [ - {cmd = "ncdu";} {cmd = "sshfs";} {cmd = "gotop";} {cmd = "pandoc";} - {cmd = "wakeonlan"; pkg = "python36Packages.wakeonlan";} - {cmd = "beet"; pkg = "beets";} - {cmd = "virt-manager"; pkg = "virtmanager";} - {cmd = "nix-prefetch-git"; pkg = "nix-prefetch-scripts";} - {cmd = "nix-prefetch-hg"; pkg = "nix-prefetch-scripts";} - ]; - onChange = "${pkgs.nur.repos.vdemeester.nr}/bin/nr default"; - }; -#+END_SRC - -And there you are, now, each time I update my environment (=home-manager switch=), =nr= -will regenerate my =nix run= aliases. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-01-26-nix-run-alias/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-01-26-nix-run-alias/index.html @@ -1,308 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-01-26-nix-run-alias/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">nix run aliases</h1><a href='https://vincent.demeester.fr/posts/2019-01-26-nix-run-alias/'></a> - <address class="signature"> - <span class="date">Sat, 26 January, 2019</span> - <span class="words">(1300 Words)</span> - </address> - <ul class="tag_box inline"> - - - - - - <li class="tag tag-nixos"><a href="/tags/#nixos">nixos<span>1</span></a></li> - - - <li class="tag tag-fish"><a href="/tags/#fish">fish<span>1</span></a></li> - - - <li class="tag tag-alias"><a href="/tags/#alias">alias<span>1</span></a></li> - - - <li class="tag tag-nix"><a href="/tags/#nix">nix<span>3</span></a></li> - - - <li class="tag tag-shell"><a href="/tags/#shell">shell<span>2</span></a></li> - - - <li class="tag tag-home"><a href="/tags/#home">home<span>1</span></a></li> - - - <li class="tag tag-manager"><a href="/tags/#manager">manager<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>I use <a href="https://nixos.org/"><code>NixOS</code></a> each and every day, everywhere. One really cool feature of <code>nix</code> is -<code>nix-shell</code> and more recently (with <code>nix</code> >= <code>2.0.0</code>), <code>nix run</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-man" data-lang="man">Usage: nix run <FLAGS>... <INSTALLABLES>... - -Summary: run a shell in which the specified packages are available. - -Flags: - --arg <NAME> <EXPR> argument to be passed to Nix functions - --argstr <NAME> <STRING> string-valued argument to be passed to Nix functions - -c, --command <COMMAND> <ARGS> command and arguments to be executed; defaults to 'bash' - -f, --file <FILE> evaluate FILE rather than the default - -i, --ignore-environment clear the entire environment (except those specified with --keep) - -I, --include <PATH> add a path to the list of locations used to look up <...> file names - -k, --keep <NAME> keep specified environment variable - -u, --unset <NAME> unset specified environment variable - -Examples: - - To start a shell providing GNU Hello from NixOS 17.03: - $ nix run -f channel:nixos-17.03 hello - - To start a shell providing youtube-dl from your 'nixpkgs' channel: - $ nix run nixpkgs.youtube-dl - - To run GNU Hello: - $ nix run nixpkgs.hello -c hello --greeting 'Hi everybody!' - - To run GNU Hello in a chroot store: - $ nix run --store ~/my-nix nixpkgs.hello -c hello - -Note: this program is EXPERIMENTAL and subject to change.</code></pre></div> -<p>As you can see from the <code>-h</code> summary, it makes it really easy to run a shell or a command -with some packages that are not in your main configuration. It will download the -package(s) if there are not available in the Nix store (<code>/nix/store/</code>).</p> - -<p>A few month ago I decided it would be a perfect use-case for command I do not run -often. My idea was, let’s define <code>aliases</code> (in the shell) that would make a simple command -call, like <code>ncdu</code>, become <code>nix run nixpkgs.ncdu -c ndcu</code>. My <em>shell of choice</em> is <a href="https://fishshell.com/">fish</a>, so -I decided to dig into the <em>language</em> in order to implement that.</p> - -<p>The use case is the following :</p> - -<ul> -<li>When I type <code>foo</code>, I want the command <code>foo</code> in package <code>bar</code> to be executed.</li> -<li>I want to be able to pin a channel for the package — I’m using <a href="https://matthewbauer.us/">Matthew Bauer</a> <a href="https://matthewbauer.us/blog/channel-changing.html">Channel -Changing with Nix</a> setup for pin-pointing a given channel.</li> -</ul> - -<h2 id="fish-aliases-experimentation">Fish aliases experimentation</h2> - -<p>I had a feeling the built-in <code>alias</code> would not work so I ended up trying to define a -<em>dynamic</em> function that would be the name of the command. That’s the beauty of the shell, -everything is a command, even function appears as commands. If you define a function -<code>foo()</code>, you will be able to run <code>foo</code> in your shell, <strong>and</strong> it will take precedence over -the <code>foo</code> executable file that would be in your <code>PATH</code>.</p> - -<p>I ended up with two main helper function that would create those <em>alias</em> function.</p> -<div class="highlight"><pre class="chroma"><code class="language-fish" data-lang="fish"><span class="k">function</span> _nix_run_package - <span class="k">set</span> -l s <span class="nv">$argv</span><span class="o">[</span>1<span class="o">]</span> - <span class="k">set</span> -l package <span class="o">(</span>string split <span class="s2">":"</span> <span class="nv">$s</span><span class="o">)</span> - <span class="k">switch</span> <span class="o">(</span><span class="k">count</span> <span class="nv">$package</span><span class="o">)</span> - <span class="k">case</span> 1 - _nix_run <span class="nv">$s</span> <span class="nv">$s</span> <span class="nv">$argv</span><span class="o">[</span>2<span class="o">]</span> <span class="nv">$argv</span><span class="o">[</span>3<span class="o">]</span> - <span class="k">case</span> 2 - _nix_run <span class="nv">$package</span><span class="o">[</span>1<span class="o">]</span> <span class="nv">$package</span><span class="o">[</span>2<span class="o">]</span> <span class="nv">$argv</span><span class="o">[</span>2<span class="o">]</span> <span class="nv">$argv</span><span class="o">[</span>3<span class="o">]</span> - <span class="k">end</span> -<span class="k">end</span> - -<span class="k">function</span> _nix_run - <span class="k">set</span> -l c <span class="nv">$argv</span><span class="o">[</span>1<span class="o">]</span> - <span class="k">set</span> -l p <span class="nv">$argv</span><span class="o">[</span>2<span class="o">]</span> - <span class="k">set</span> -l channel <span class="nv">$argv</span><span class="o">[</span>3<span class="o">]</span> - <span class="k">set</span> -l channelsfile <span class="nv">$argv</span><span class="o">[</span>4<span class="o">]</span> - <span class="k">function</span> <span class="nv">$c</span> --inherit-variable c --inherit-variable p --inherit-variable channel --inherit-variable channelsfile - <span class="k">set</span> -l cmd nix run - <span class="k">if</span> <span class="k">test</span> -n <span class="s2">"</span><span class="nv">$channelsfile</span><span class="s2">"</span> - <span class="k">set</span> cmd <span class="nv">$cmd</span> -f <span class="nv">$channelsfile</span> - <span class="k">end</span> - <span class="nb">eval</span> <span class="nv">$cmd</span> <span class="nv">$channel</span>.<span class="nv">$p</span> -c <span class="nv">$c</span> <span class="nv">$argv</span> - <span class="k">end</span> -<span class="k">end</span></code></pre></div> -<p>In a nutshell, <code>_nix_run</code> is the function that create the alias function. There is so -condition in there depending on whether we gave it a channel or not. So, a call like -<code>_nix_run foo bar unstable channels.nix</code> would, in the end generate a function <code>foo</code> with -the following call : <code>nix run -f channels.nix unstable.bar -c foo</code>.</p> - -<p>The other function, <code>_nix_run_package</code> is there to make me write less when I define those -aliases — aka if the command and the package share the same name, I don’t want to write it -twice. So, a call like <code>_nix_run_package foo nixpkgs</code> would result in a <code>_nix_run foo foo -nixpkgs</code>, whereas a call like <code>_nix_run_package foo:bar unstable channels.nix</code> would -result in a <code>_nix_run foo bar unstable channels.nix</code>.</p> - -<p>An example is gonna be better than the above paragraphs. This is what I used to have in my -fish configuration.</p> -<div class="highlight"><pre class="chroma"><code class="language-fish" data-lang="fish"><span class="k">function</span> _def_nix_run_aliases - <span class="k">set</span> -l stable mr sshfs ncdu wakeonlan:python36Packages.wakeonlan lspci:pciutils lsusb:usbutils beet:beets gotop virt-manager:virtmanager pandoc nix-prefetch-git:nix-prefetch-scripts nix-prefetch-hg:nix-prefetch-scripts - <span class="k">set</span> -l unstable op:_1password update-desktop-database:desktop-file-utils lgogdownloader - <span class="k">for</span> s <span class="k">in</span> <span class="nv">$stable</span> - _nix_run_package <span class="nv">$s</span> nixpkgs - <span class="k">end</span> - <span class="k">for</span> s <span class="k">in</span> <span class="nv">$unstable</span> - _nix_run_package <span class="nv">$s</span> unstable ~/.config/nixpkgs/channels.nix - <span class="k">end</span> -<span class="k">end</span> -<span class="c"># Call the function to create the aliases -</span><span class="c"></span>_def_nix_run_aliases</code></pre></div> -<p>This works like a charm, and for a while, I was happy. But I soon realized something : I’m -not always on my shell — like, I tend to spend more and more time in <code>eshell</code>. This also -doesn’t work with graphic tools like <a href="https://github.com/DaveDavenport/rofi"><code>rofi</code></a>. I needed actual command, so that external -tools would benefit from that. I ended up writing a small tool, <a href="https://github.com/vdemeester/nr"><code>nr</code></a> that integrates -nicely with <code>nix</code> and <a href="https://github.com/rycee/home-manager"><code>home-manager</code></a>.</p> - -<h2 id="a-proper-tool-nr">A proper tool : <code>nr</code></h2> - -<p>The gist for this tool is simple :</p> - -<ul> -<li>create an executable script that will call <code>nix run ...</code> instead of the command</li> -<li>as for the above fish script, support different channels</li> -<li>make sure we don’t have conflicts — if the command already exists, then don’t create the -command</li> -</ul> - -<p>The <code>nr</code> tool would have to be able to manage multiple <em>profile</em>, which really stands for -multiple file. The main reason is really about how I manage my configuration ; To make it -simple, depending on the computer my configurations are setup, I may not have <code>go</code>, thus I -don’t want any <code>go</code>-related aliases for a computer that doesn’t have <code>go</code> (using <code>go</code> here -but you can replace with anything).</p> -<div class="highlight"><pre class="chroma"><code class="language-fish" data-lang="fish"><span class="nv">$ </span>nr default -<span class="o">></span> nr generate default -<span class="o">></span> virtmanager already exists -<span class="nv">$ </span>nr git -<span class="o">></span> nr generate git</code></pre></div> -<p><code>nr</code> generates a bash script that does the <code>nr run …</code> and mark it as executable. <code>nr</code> -needs to be able to clean files it has generated (in case we removed it from -aliases). Thus, I went for a really naive comment in the script. When generating a new set -of commands, <code>nr</code> will first remove previously generated script for this profile, and for -that, it uses the comment. Let’s look at what a generated script looks like, for the -default profile.</p> -<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="cp">#!/usr/bin/env bash -</span><span class="cp"></span><span class="c1"># Generated by nr default</span> -nix run nixpkgs.nix-prefetch-scripts -c nix-prefetch-git <span class="nv">$@</span></code></pre></div> -<p>The format used in <code>nr</code> is <code>json</code>. I’m not a <em>huge fan</em> of <code>json</code> but it really was the -best format to use for this tool. The reason to use <code>json</code> are simple :</p> - -<ul> -<li><p>Go has <code>encoding/json</code> built-in, so it’s really easy to <code>Marshall</code> and <code>Unmarshall</code> -structure.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">alias</span> <span class="kd">struct</span> <span class="p">{</span> - <span class="nx">Command</span> <span class="kt">string</span> <span class="s">`json:"cmd"`</span> - <span class="nx">Package</span> <span class="kt">string</span> <span class="s">`json:"pkg"`</span> - <span class="nx">Channel</span> <span class="kt">string</span> <span class="s">`json:"chan"`</span> -<span class="p">}</span></code></pre></div></li> - -<li><p>Nix also has built-in support for <code>json</code> : <code>builtins.toJSON</code> will marshall a <em>struct</em> -into a json file.</p></li> -</ul> - -<p>Finally, to avoid conflicts at <em>build time</em> (<code>home-manager switch</code>) I couldn’t use/define -a nix package, but to execute command(s) at the end of the build. One way to achieve it is -to use <code>file.?.onChange</code> script, which is executed after <a href="https://github.com/rycee/home-manager"><code>home-manager</code></a> has updated the -environment, <strong>if</strong> the file has changed. That means it’s possible to check for executable -files in <code>~/.nix-profile/bin/</code> for defined aliases and create those that are not there, -with <code>nr</code>. My configuration then looks like the following.</p> -<div class="highlight"><pre class="chroma"><code class="language-nix" data-lang="nix"><span class="n">xdg</span><span class="o">.</span><span class="n">configFile</span><span class="o">.</span><span class="s2">"nr/default"</span> <span class="err">=</span> <span class="p">{</span> - <span class="n">text</span> <span class="o">=</span> <span class="nb">builtins</span><span class="o">.</span><span class="n">toJSON</span> <span class="p">[</span> - <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"ncdu"</span><span class="p">;}</span> <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"sshfs"</span><span class="p">;}</span> <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"gotop"</span><span class="p">;}</span> <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"pandoc"</span><span class="p">;}</span> - <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"wakeonlan"</span><span class="p">;</span> <span class="n">pkg</span> <span class="o">=</span> <span class="s2">"python36Packages.wakeonlan"</span><span class="p">;}</span> - <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"beet"</span><span class="p">;</span> <span class="n">pkg</span> <span class="o">=</span> <span class="s2">"beets"</span><span class="p">;}</span> - <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"virt-manager"</span><span class="p">;</span> <span class="n">pkg</span> <span class="o">=</span> <span class="s2">"virtmanager"</span><span class="p">;}</span> - <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"nix-prefetch-git"</span><span class="p">;</span> <span class="n">pkg</span> <span class="o">=</span> <span class="s2">"nix-prefetch-scripts"</span><span class="p">;}</span> - <span class="p">{</span><span class="n">cmd</span> <span class="o">=</span> <span class="s2">"nix-prefetch-hg"</span><span class="p">;</span> <span class="n">pkg</span> <span class="o">=</span> <span class="s2">"nix-prefetch-scripts"</span><span class="p">;}</span> - <span class="p">];</span> - <span class="n">onChange</span> <span class="o">=</span> <span class="s2">"</span><span class="si">${</span><span class="n">pkgs</span><span class="o">.</span><span class="n">nur</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">vdemeester</span><span class="o">.</span><span class="n">nr</span><span class="si">}</span><span class="s2">/bin/nr default"</span><span class="p">;</span> -<span class="p">};</span></code></pre></div> -<p>And there you are, now, each time I update my environment (<code>home-manager switch</code>), <code>nr</code> -will regenerate my <code>nix run</code> aliases.</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-01-27-link/" title="Self-care tips for new developers">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-01-20-2018-year-review/" title="2018 year review">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-01-27-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-01-27-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-01-27-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Self-care tips for new developers</h1><a href='https://vincent.demeester.fr/posts/2019-01-27-link/'></a> - <address class="signature"> - <span class="date">Sun, 27 January, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-productivity"><a href="/tags/#productivity">productivity<span>1</span></a></li> - - - <li class="tag tag-health"><a href="/tags/#health">health<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>Tips for developers to take care of themselves to work better (but less too 👼)</p> - <p>🔗 <a href="https://punchagan.muse-amuse.in/blog/self-care-tips-for-new-developers/" class="link">https://punchagan.muse-amuse.in/blog/self-care-tips-for-new-developers/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-02-15-link/" title="$ docker build -f Mockerfile.yaml .">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-01-26-nix-run-alias/" title="nix run aliases">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-02-15-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-02-15-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-02-15-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">$ docker build -f Mockerfile.yaml .</h1><a href='https://vincent.demeester.fr/posts/2019-02-15-link/'></a> - <address class="signature"> - <span class="date">Fri, 15 February, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-docker"><a href="/tags/#docker">docker<span>3</span></a></li> - - - <li class="tag tag-buildkit"><a href="/tags/#buildkit">buildkit<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>how to write your own Dockerfile syntax that works out of the box with any existing Docker installation. </p> - <p>🔗 <a href="https://matt-rickard.com/building-a-new-dockerfile-frontend/" class="link">https://matt-rickard.com/building-a-new-dockerfile-frontend/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-02-25-link/" title="Go Interfaces - fREW Schmidt's Foolish Manifesto">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-01-27-link/" title="Self-care tips for new developers">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-02-25-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-02-25-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-02-25-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Go Interfaces - fREW Schmidt's Foolish Manifesto</h1><a href='https://vincent.demeester.fr/posts/2019-02-25-link/'></a> - <address class="signature"> - <span class="date">Mon, 25 February, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-go"><a href="/tags/#go">go<span>5</span></a></li> - - - <li class="tag tag-interfaces"><a href="/tags/#interfaces">interfaces<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>I did some work recently that depended on Go interfaces and I found it both straightforward and elegant.</p> - <p>🔗 <a href="https://blog.afoolishmanifesto.com/posts/go-interfaces/" class="link">https://blog.afoolishmanifesto.com/posts/go-interfaces/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-12-link/" title="Go2 Contracts Go Too Far · npf.io">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-02-15-link/" title="$ docker build -f Mockerfile.yaml .">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-12-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-12-link/index.html @@ -1,124 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-12-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Go2 Contracts Go Too Far · npf.io</h1><a href='https://vincent.demeester.fr/posts/2019-03-12-link/'></a> - <address class="signature"> - <span class="date">Tue, 12 March, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-go"><a href="/tags/#go">go<span>5</span></a></li> - - - <li class="tag tag-contracts"><a href="/tags/#contracts">contracts<span>1</span></a></li> - - - <li class="tag tag-go2"><a href="/tags/#go2">go2<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>A take at the Go 2 contracts proposal and why it might not really do good</p> - <p>🔗 <a href="https://npf.io/2018/09/go2-contracts-go-too-far/" class="link">https://npf.io/2018/09/go2-contracts-go-too-far/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-23-gotest-tools-poll/" title="Golang testing — gotest.tools poll">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-02-25-link/" title="Go Interfaces - fREW Schmidt's Foolish Manifesto">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-23-gotest-tools-poll.org b/www/vincent.demeester.fr/content/legacy/posts/2019-03-23-gotest-tools-poll.org @@ -1,136 +0,0 @@ -#+TITLE: Golang testing — gotest.tools poll -#+date: <2019-03-23 Sat> -#+filetags: go testing poll - -#+TOC: headlines 2 - -* Introduction -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =poll= package. - -#+BEGIN_QUOTE -Package poll provides tools for testing asynchronous code. -#+END_QUOTE - -When you write test, you may test a piece of code that work asynchronously, where the -state you're expecting is gonna take a bit of time to be achieved. This is especially true -when you work on networking or file-system code. And this happens a lot when you write -integration (or end-to-end) test, less for unit-tests. - -The package =poll= is trying to tackle those use cases. We'll first take a look at the -main function, =WaitOn=, then how to write a ~Check~, using the ~Result~ type. - -* ~WaitOn~ - -Let's look into the main ~poll~ function : `WaitOn`. - -#+begin_quote - WaitOn a condition or until a timeout. Poll by calling check and exit when check returns - a done Result. To fail a test and exit polling with an error return a error result. -#+end_quote - -In a gist, ~WaitOn~ will run a /condition/ function until it either times out or -succeed. It wait for a given time/delay between each run. - -#+begin_src go - func WaitOn(t TestingT, check Check, pollOps ...SettingOp) { - // […] - } -#+end_src - -As any /testing helper/ function, the first argument is ~*testing.T~ (or, in this case, -any thing that look like it, thanks to the ~TestingT~ interace). The two other arguments -are way more interesting : - -- The ~Check~ is the condition that will run multiple times until it either timeout, or succeed. -- The ~SettingOp(s)~ which are options to configure the function, things like the timeout, - or the /delay/ between each run. - -The settings are pretty straightforward : - -- ~WithDelay~ : sets the delay to wait between polls. The default delay is 100ms. -- ~WithTimeout~ : sets the timeout. The default timeout is 10s. - -There is existing ~Check~ for common case: - -- ~Connection~ : try to open a connection to the address on the named network. - - #+begin_src go - poll.WaitOn(t, poll.Connection("tcp", "foo.bar:55555"), poll.WithTimeout("5s")) - #+end_src - -- ~FileExists~ : looks on filesystem and check that path exists. - - #+begin_src go - poll.WaitOn(t, poll.FileExists("/should/be/created"), poll.WithDelay("1s")) - #+end_src - - -* ~Check~ and ~Result~ - -~Connection~ and ~FileExists~ are the only two /built-in/ ~Check~ provided by -~gotest.tools~. They are useful, but as usual, where ~gotest.tools~ shines is -extensiblity. It is really easy to define your own ~Check~. - -#+begin_src go - type Check func(t LogT) Result -#+end_src - -A ~Check~ is, thus, only a function that takes ~LogT~ — which is anything that can log -something, like ~*testing.T~ — and return a ~Result~. Let's look at this intersting -~Result~ type. - -#+begin_src go - type Result interface { - // Error indicates that the check failed and polling should stop, and the - // the has failed - Error() error - // Done indicates that polling should stop, and the test should proceed - Done() bool - // Message provides the most recent state when polling has not completed - Message() string - } -#+end_src - -Although it's an interface, the ~poll~ package defines built-in ~Result~ so that it's easy -to write ~Check~ without having to define you ~Result~ type. - -- ~Continue~ returns a Result that indicates to WaitOn that it should continue - polling. The message text will be used as the failure message if the timeout is reached. -- ~Success~ returns a Result where Done() returns true, which indicates to WaitOn that it - should stop polling and exit without an error. -- ~Error~ returns a Result that indicates to WaitOn that it should fail the test and stop - polling. - -The basic just to write a ~Check~ is then : - -- if the state is not there yet, return ~Continue~, -- if there is an error, unrelated to validating the state, return an ~Error~, -- if the state is there, return ~Success~. - -Let's look at an example taken from the ~moby/moby~ source code. - -#+begin_src go - poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) - - func IsInState(ctx context.Context, client client.APIClient, containerID string, state ...string) func(log poll.LogT) poll.Result { - return func(log poll.LogT) poll.Result { - inspect, err := client.ContainerInspect(ctx, containerID) - if err != nil { - return poll.Error(err) - } - for _, v := range state { - if inspect.State.Status == v { - return poll.Success() - } - } - return poll.Continue("waiting for container to be one of (%s), currently %s", strings.Join(state, ", "), inspect.State.Status) - } - } -#+end_src - - -* Conclusion - -… that's a wrap. The =poll= package allows to easily wait for a condition to happen in a -given time-frame — with sane defaults. As for most of the ~gotest.tools~ package, we use -this package heavily in =docker/*= projects too… diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-23-gotest-tools-poll/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-23-gotest-tools-poll/index.html @@ -1,236 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-23-gotest-tools-poll/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Golang testing — gotest.tools poll</h1><a href='https://vincent.demeester.fr/posts/2019-03-23-gotest-tools-poll/'></a> - <address class="signature"> - <span class="date">Sat, 23 March, 2019</span> - <span class="words">(700 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#developement">developement</a></li> - - - - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-golang"><a href="/tags/#golang">golang<span>12</span></a></li> - - - <li class="tag tag-poll"><a href="/tags/#poll">poll<span>1</span></a></li> - - <br/> - - </ul> - </header> - - - - - -<p>Let’s continue the <a href="https://gotest.tools"><code>gotest.tools</code></a> serie, this time with the <code>poll</code> package.</p> - -<blockquote> -<p>Package poll provides tools for testing asynchronous code.</p> -</blockquote> - -<p>When you write test, you may test a piece of code that work asynchronously, where the -state you’re expecting is gonna take a bit of time to be achieved. This is especially true -when you work on networking or file-system code. And this happens a lot when you write -integration (or end-to-end) test, less for unit-tests.</p> - -<p>The package <code>poll</code> is trying to tackle those use cases. We’ll first take a look at the -main function, <code>WaitOn</code>, then how to write a <code>Check</code>, using the <code>Result</code> type.</p> - -<h2 id="waiton"><code>WaitOn</code></h2> - -<p>Let’s look into the main <code>poll</code> function : `WaitOn`.</p> - -<blockquote> -<p>WaitOn a condition or until a timeout. Poll by calling check and exit when check returns -a done Result. To fail a test and exit polling with an error return a error result.</p> -</blockquote> - -<p>In a gist, <code>WaitOn</code> will run a <em>condition</em> function until it either times out or -succeed. It wait for a given time/delay between each run.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">WaitOn</span><span class="p">(</span><span class="nx">t</span> <span class="nx">TestingT</span><span class="p">,</span> <span class="nx">check</span> <span class="nx">Check</span><span class="p">,</span> <span class="nx">pollOps</span> <span class="o">...</span><span class="nx">SettingOp</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// […] -</span><span class="c1"></span><span class="p">}</span></code></pre></div> -<p>As any <em>testing helper</em> function, the first argument is <code>*testing.T</code> (or, in this case, -any thing that look like it, thanks to the <code>TestingT</code> interace). The two other arguments -are way more interesting :</p> - -<ul> -<li>The <code>Check</code> is the condition that will run multiple times until it either timeout, or succeed.</li> -<li>The <code>SettingOp(s)</code> which are options to configure the function, things like the timeout, -or the <em>delay</em> between each run.</li> -</ul> - -<p>The settings are pretty straightforward :</p> - -<ul> -<li><code>WithDelay</code> : sets the delay to wait between polls. The default delay is 100ms.</li> -<li><code>WithTimeout</code> : sets the timeout. The default timeout is 10s.</li> -</ul> - -<p>There is existing <code>Check</code> for common case:</p> - -<ul> -<li><p><code>Connection</code> : try to open a connection to the address on the named network.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">poll</span><span class="p">.</span><span class="nf">WaitOn</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">Connection</span><span class="p">(</span><span class="s">"tcp"</span><span class="p">,</span> <span class="s">"foo.bar:55555"</span><span class="p">),</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">WithTimeout</span><span class="p">(</span><span class="s">"5s"</span><span class="p">))</span></code></pre></div></li> - -<li><p><code>FileExists</code> : looks on filesystem and check that path exists.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">poll</span><span class="p">.</span><span class="nf">WaitOn</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">FileExists</span><span class="p">(</span><span class="s">"/should/be/created"</span><span class="p">),</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">WithDelay</span><span class="p">(</span><span class="s">"1s"</span><span class="p">))</span></code></pre></div></li> -</ul> - -<h2 id="check-and-result"><code>Check</code> and <code>Result</code></h2> - -<p><code>Connection</code> and <code>FileExists</code> are the only two <em>built-in</em> <code>Check</code> provided by -<code>gotest.tools</code>. They are useful, but as usual, where <code>gotest.tools</code> shines is -extensiblity. It is really easy to define your own <code>Check</code>.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Check</span> <span class="kd">func</span><span class="p">(</span><span class="nx">t</span> <span class="nx">LogT</span><span class="p">)</span> <span class="nx">Result</span></code></pre></div> -<p>A <code>Check</code> is, thus, only a function that takes <code>LogT</code> — which is anything that can log -something, like <code>*testing.T</code> — and return a <code>Result</code>. Let’s look at this intersting -<code>Result</code> type.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">type</span> <span class="nx">Result</span> <span class="kd">interface</span> <span class="p">{</span> - <span class="c1">// Error indicates that the check failed and polling should stop, and the -</span><span class="c1"></span> <span class="c1">// the has failed -</span><span class="c1"></span> <span class="nf">Error</span><span class="p">()</span> <span class="kt">error</span> - <span class="c1">// Done indicates that polling should stop, and the test should proceed -</span><span class="c1"></span> <span class="nf">Done</span><span class="p">()</span> <span class="kt">bool</span> - <span class="c1">// Message provides the most recent state when polling has not completed -</span><span class="c1"></span> <span class="nf">Message</span><span class="p">()</span> <span class="kt">string</span> -<span class="p">}</span></code></pre></div> -<p>Although it’s an interface, the <code>poll</code> package defines built-in <code>Result</code> so that it’s easy -to write <code>Check</code> without having to define you <code>Result</code> type.</p> - -<ul> -<li><code>Continue</code> returns a Result that indicates to WaitOn that it should continue -polling. The message text will be used as the failure message if the timeout is reached.</li> -<li><code>Success</code> returns a Result where Done() returns true, which indicates to WaitOn that it -should stop polling and exit without an error.</li> -<li><code>Error</code> returns a Result that indicates to WaitOn that it should fail the test and stop -polling.</li> -</ul> - -<p>The basic just to write a <code>Check</code> is then :</p> - -<ul> -<li>if the state is not there yet, return <code>Continue</code>,</li> -<li>if there is an error, unrelated to validating the state, return an <code>Error</code>,</li> -<li>if the state is there, return <code>Success</code>.</li> -</ul> - -<p>Let’s look at an example taken from the <code>moby/moby</code> source code.</p> -<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="nx">poll</span><span class="p">.</span><span class="nf">WaitOn</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="nx">container</span><span class="p">.</span><span class="nf">IsInState</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">client</span><span class="p">,</span> <span class="nx">cID</span><span class="p">,</span> <span class="s">"running"</span><span class="p">),</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">WithDelay</span><span class="p">(</span><span class="mi">100</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">))</span> - -<span class="kd">func</span> <span class="nf">IsInState</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span> <span class="nx">client</span> <span class="nx">client</span><span class="p">.</span><span class="nx">APIClient</span><span class="p">,</span> <span class="nx">containerID</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">state</span> <span class="o">...</span><span class="kt">string</span><span class="p">)</span> <span class="kd">func</span><span class="p">(</span><span class="nx">log</span> <span class="nx">poll</span><span class="p">.</span><span class="nx">LogT</span><span class="p">)</span> <span class="nx">poll</span><span class="p">.</span><span class="nx">Result</span> <span class="p">{</span> - <span class="k">return</span> <span class="kd">func</span><span class="p">(</span><span class="nx">log</span> <span class="nx">poll</span><span class="p">.</span><span class="nx">LogT</span><span class="p">)</span> <span class="nx">poll</span><span class="p">.</span><span class="nx">Result</span> <span class="p">{</span> - <span class="nx">inspect</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">client</span><span class="p">.</span><span class="nf">ContainerInspect</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">containerID</span><span class="p">)</span> - <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> - <span class="k">return</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">Error</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> - <span class="p">}</span> - <span class="k">for</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">v</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">state</span> <span class="p">{</span> - <span class="k">if</span> <span class="nx">inspect</span><span class="p">.</span><span class="nx">State</span><span class="p">.</span><span class="nx">Status</span> <span class="o">==</span> <span class="nx">v</span> <span class="p">{</span> - <span class="k">return</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">Success</span><span class="p">()</span> - <span class="p">}</span> - <span class="p">}</span> - <span class="k">return</span> <span class="nx">poll</span><span class="p">.</span><span class="nf">Continue</span><span class="p">(</span><span class="s">"waiting for container to be one of (%s), currently %s"</span><span class="p">,</span> <span class="nx">strings</span><span class="p">.</span><span class="nf">Join</span><span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="s">", "</span><span class="p">),</span> <span class="nx">inspect</span><span class="p">.</span><span class="nx">State</span><span class="p">.</span><span class="nx">Status</span><span class="p">)</span> - <span class="p">}</span> -<span class="p">}</span></code></pre></div> -<h2 id="conclusion">Conclusion</h2> - -<p>… that’s a wrap. The <code>poll</code> package allows to easily wait for a condition to happen in a -given time-frame — with sane defaults. As for most of the <code>gotest.tools</code> package, we use -this package heavily in <code>docker/*</code> projects too…</p> - - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-24-link/" title="Building Blocks – I.A.">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-12-link/" title="Go2 Contracts Go Too Far · npf.io">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-24-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-24-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-24-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Building Blocks – I.A.</h1><a href='https://vincent.demeester.fr/posts/2019-03-24-link/'></a> - <address class="signature"> - <span class="date">Sun, 24 March, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-functional"><a href="/tags/#functional">functional<span>1</span></a></li> - - - <li class="tag tag-programming"><a href="/tags/#programming">programming<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>A visual approach to the topic of purely-typed functional programming.</p> - <p>🔗 <a href="https://icidasset.com/writings/building-blocks/" class="link">https://icidasset.com/writings/building-blocks/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-26-link/" title="Handle and Check - Let's Not · npf.io">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-23-gotest-tools-poll/" title="Golang testing — gotest.tools poll">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-26-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-26-link/index.html @@ -1,127 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-26-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Handle and Check - Let's Not · npf.io</h1><a href='https://vincent.demeester.fr/posts/2019-03-26-link/'></a> - <address class="signature"> - <span class="date">Tue, 26 March, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-go"><a href="/tags/#go">go<span>5</span></a></li> - - - <li class="tag tag-proposal"><a href="/tags/#proposal">proposal<span>1</span></a></li> - - - <li class="tag tag-handle"><a href="/tags/#handle">handle<span>1</span></a></li> - - - <li class="tag tag-check"><a href="/tags/#check">check<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>Opinion (that I share) on the check/handle error proposal for Go 2</p> - <p>🔗 <a href="https://npf.io/2018/09/check-and-handle/" class="link">https://npf.io/2018/09/check-and-handle/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-27-link/" title="Nicolas Mattia - The 5 Raisons d'Être of Testing">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-24-link/" title="Building Blocks – I.A.">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-27-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-27-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-27-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Nicolas Mattia - The 5 Raisons d'Être of Testing</h1><a href='https://vincent.demeester.fr/posts/2019-03-27-link/'></a> - <address class="signature"> - <span class="date">Wed, 27 March, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-testing"><a href="/tags/#testing">testing<span>11</span></a></li> - - - <li class="tag tag-craftmanship"><a href="/tags/#craftmanship">craftmanship<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>The author describes five of the reason why he thinks tests are important — and I do agree !</p> - <p>🔗 <a href="https://nmattia.com/posts/2019-01-22-the-5-raisons-detre-of-testing.html" class="link">https://nmattia.com/posts/2019-01-22-the-5-raisons-detre-of-testing.html</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-28-link/" title="Nix: A Reproducible Setup for Linux and macOS">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-26-link/" title="Handle and Check - Let's Not · npf.io">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-28-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-28-link/index.html @@ -1,130 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-28-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Nix: A Reproducible Setup for Linux and macOS</h1><a href='https://vincent.demeester.fr/posts/2019-03-28-link/'></a> - <address class="signature"> - <span class="date">Thu, 28 March, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-linux"><a href="/tags/#linux">linux<span>4</span></a></li> - - - <li class="tag tag-macos"><a href="/tags/#macos">macos<span>1</span></a></li> - - - <li class="tag tag-nix"><a href="/tags/#nix">nix<span>3</span></a></li> - - - <li class="tag tag-reproductible"><a href="/tags/#reproductible">reproductible<span>2</span></a></li> - - - <li class="tag tag-nixpkgs"><a href="/tags/#nixpkgs">nixpkgs<span>2</span></a></li> - - <br/> - - </ul> - </header> - - <p>This post describes how I set up a reproducible development environment in a few seconds on any Linux distribution (and potentially macOS as well).</p> - <p>🔗 <a href="https://nmattia.com/posts/2018-03-21-nix-reproducible-setup-linux-macos.html" class="link">https://nmattia.com/posts/2018-03-21-nix-reproducible-setup-linux-macos.html</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-03-31-link/" title="Six Years With a Distraction-Free iPhone">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-27-link/" title="Nicolas Mattia - The 5 Raisons d'Être of Testing">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-03-31-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-03-31-link/index.html @@ -1,121 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-03-31-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Six Years With a Distraction-Free iPhone</h1><a href='https://vincent.demeester.fr/posts/2019-03-31-link/'></a> - <address class="signature"> - <span class="date">Sun, 31 March, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#productivity">productivity</a></li> - - - - - - <li class="tag tag-iphone"><a href="/tags/#iphone">iphone<span>1</span></a></li> - - - <li class="tag tag-distration"><a href="/tags/#distration">distration<span>1</span></a></li> - - - <li class="tag tag-mobile"><a href="/tags/#mobile">mobile<span>1</span></a></li> - - - <li class="tag tag-free"><a href="/tags/#free">free<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>A very interesting medium story on why and how to try your own low-stress experiment. I went and did a few of what the author did, and it feels good ! Really !</p> - <p>🔗 <a href="https://medium.com/s/story/six-years-with-a-distraction-free-iphone-8cf5eb4f97e3" class="link">https://medium.com/s/story/six-years-with-a-distraction-free-iphone-8cf5eb4f97e3</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-04-18-link/" title="Easy Peasy Nix Versions">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-28-link/" title="Nix: A Reproducible Setup for Linux and macOS">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-04-18-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-04-18-link/index.html @@ -1,127 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-04-18-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Easy Peasy Nix Versions</h1><a href='https://vincent.demeester.fr/posts/2019-04-18-link/'></a> - <address class="signature"> - <span class="date">Thu, 18 April, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-linux"><a href="/tags/#linux">linux<span>4</span></a></li> - - - <li class="tag tag-nix"><a href="/tags/#nix">nix<span>3</span></a></li> - - - <li class="tag tag-reproductible"><a href="/tags/#reproductible">reproductible<span>2</span></a></li> - - - <li class="tag tag-nixpkgs"><a href="/tags/#nixpkgs">nixpkgs<span>2</span></a></li> - - <br/> - - </ul> - </header> - - <p>This is a convention for using third-party packages in Nix. It has a simple directory structure, makes using the packages straightforward and automatizes updates.</p> - <p>🔗 <a href="https://www.nmattia.com/posts/2019-01-15-easy-peasy-nix-versions.html" class="link">https://www.nmattia.com/posts/2019-01-15-easy-peasy-nix-versions.html</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-04-19-link/" title="Stop writing broken Go libraries">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-03-31-link/" title="Six Years With a Distraction-Free iPhone">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-04-19-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-04-19-link/index.html @@ -1,127 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-04-19-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Stop writing broken Go libraries</h1><a href='https://vincent.demeester.fr/posts/2019-04-19-link/'></a> - <address class="signature"> - <span class="date">Fri, 19 April, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-go"><a href="/tags/#go">go<span>5</span></a></li> - - - <li class="tag tag-libraries"><a href="/tags/#libraries">libraries<span>1</span></a></li> - - - <li class="tag tag-broken"><a href="/tags/#broken">broken<span>1</span></a></li> - - - <li class="tag tag-tips"><a href="/tags/#tips">tips<span>2</span></a></li> - - <br/> - - </ul> - </header> - - <p>Every single one of those libraries had some fundamental problems that made it unusable in any real world applications. Furthermore every single one of those libraries was written in a way which made fixing the issues impossible without altering the existing library APIs in a non backwards compatibile way. As the same problems unfortunately plague many other Go libraries I attempted to list most of the sins commited by their authors below.</p> - <p>🔗 <a href="https://0x46.net/thoughts/2018/12/29/go-libraries/" class="link">https://0x46.net/thoughts/2018/12/29/go-libraries/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-04-23-link/" title="Trimming the fat from a Golang binary">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-04-18-link/" title="Easy Peasy Nix Versions">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-04-23-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-04-23-link/index.html @@ -1,124 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-04-23-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">Trimming the fat from a Golang binary</h1><a href='https://vincent.demeester.fr/posts/2019-04-23-link/'></a> - <address class="signature"> - <span class="date">Tue, 23 April, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-go"><a href="/tags/#go">go<span>5</span></a></li> - - - <li class="tag tag-binary"><a href="/tags/#binary">binary<span>1</span></a></li> - - - <li class="tag tag-size"><a href="/tags/#size">size<span>1</span></a></li> - - <br/> - - </ul> - </header> - - <p>Some tips and tricks to reduce the size of a golang binary</p> - <p>🔗 <a href="https://boyter.org/posts/trimming-golang-binary-fat/" class="link">https://boyter.org/posts/trimming-golang-binary-fat/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-05-11-link/" title="As We May Kube*">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-04-19-link/" title="Stop writing broken Go libraries">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-05-11-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-05-11-link/index.html @@ -1,127 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-05-11-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">As We May Kube*</h1><a href='https://vincent.demeester.fr/posts/2019-05-11-link/'></a> - <address class="signature"> - <span class="date">Sat, 11 May, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-orchestration"><a href="/tags/#orchestration">orchestration<span>2</span></a></li> - - - <li class="tag tag-kubernetes"><a href="/tags/#kubernetes">kubernetes<span>2</span></a></li> - - - <li class="tag tag-kube"><a href="/tags/#kube">kube<span>2</span></a></li> - - - <li class="tag tag-k8s"><a href="/tags/#k8s">k8s<span>2</span></a></li> - - <br/> - - </ul> - </header> - - <p>We use different programming languages and development environments to write apps. Each language comes with a different flow and also we typically go through different phases, from prototyping to integration-level activities to incrementally adding features or fixing bugs once the app is in production. Now, the expectation of a developer coming from a “traditional” environment to Kubernetes is in general that their natural and well-known workflow changes as little as possible. This article reviews where we stand in Kubernetes-land concerning developing apps and where we may be heading.</p> - <p>🔗 <a href="https://itnext.io/as-we-may-kube-293b30c0a365" class="link">https://itnext.io/as-we-may-kube-293b30c0a365</a></p> - - </article> - <hr /> - <div class="prev-next"> - - <a class="paging-link prev" href="/posts/2019-06-28-link/" title="boring is cool | advocacy site for boring technology">← Previous post</a> - - - - <a class="paging-link next" href="/posts/2019-04-23-link/" title="Trimming the fat from a Golang binary">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2019-06-28-link/index.html b/www/vincent.demeester.fr/content/legacy/posts/2019-06-28-link/index.html @@ -1,125 +0,0 @@ -<!DOCTYPE html> - -<html lang="en"> - - <head> - <meta charset="utf-8"> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - - <link rel="start" href="https://vincent.demeester.fr" /> - - <title>Vincent Demeester</title> - <link rel="canonical" href="https://vincent.demeester.fr/posts/2019-06-28-link/"> - <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" /> - - <link rel="openid.server" href="https://indieauth.com/openid" /> - <link rel="openid.delegate" href="http://vincent.demeester.fr/" /> - <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> - - <link rel="stylesheet" href="/css/screen.css" type="text/css" /> - <link rel="stylesheet" href="/css/sbrain.css" type="text/css" /> - <link rel="stylesheet" href="/css/syntax.css" type="text/css" /> - - </head> - - <body lang=""/> - - - - - - -<div id="main-container"> - <div id="page"> - <article class="post"> - <header> - <h1 class="emphnext">boring is cool | advocacy site for boring technology</h1><a href='https://vincent.demeester.fr/posts/2019-06-28-link/'></a> - <address class="signature"> - <span class="date">Fri, 28 June, 2019</span> - <span class="words">(100 Words)</span> - </address> - <ul class="tag_box inline"> - - <li class="category"><a href="/categories/#development">development</a></li> - - - - - - <li class="tag tag-development"><a href="/tags/#development">development<span>13</span></a></li> - - - <li class="tag tag-software"><a href="/tags/#software">software<span>13</span></a></li> - - - <li class="tag tag-orchestration"><a href="/tags/#orchestration">orchestration<span>2</span></a></li> - - - <li class="tag tag-kubernetes"><a href="/tags/#kubernetes">kubernetes<span>2</span></a></li> - - - <li class="tag tag-kube"><a href="/tags/#kube">kube<span>2</span></a></li> - - - <li class="tag tag-k8s"><a href="/tags/#k8s">k8s<span>2</span></a></li> - - <br/> - - </ul> - </header> - - <p>« Here, I share some thoughts and considerations around using cloud native technologies, including Kubernetes, observability tools such as Prometheus, service meshes, and serverless offerings. »</p> - <p>🔗 <a href="http://boringis.cool/" class="link">http://boringis.cool/</a></p> - - </article> - <hr /> - <div class="prev-next"> - - - - <a class="paging-link next" href="/posts/2019-05-11-link/" title="As We May Kube*">Next post →</a> - - </div> - - </div> -</div> - -<footer> - <nav> - - <a href="/">home</a> - <span class="text-muted"> | </span> - - <a href="/about">about</a> - <span class="text-muted"> | </span> - - <a href="/archive">archive</a> - <span class="text-muted"> | </span> - - <a href="/categories">categories</a> - <span class="text-muted"> | </span> - - <a href="/tags">tags</a> - <span class="text-muted"> | </span> - - <a href="https://twitter.com/vdemeest">twitter</a> - <span class="text-muted"> | </span> - - <a href="https://github.com/vdemeester">github</a> - <span class="text-muted"> | </span> - - <a href="https://vincent.demeester.fr/index.xml">rss</a> - </nav> - <br/> - <address> - <span class="copyright"> - Content and design by Vincent Demeester - (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>) - </span><br /> - <span class="engine"> - Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a> - </span> - </address> -</footer> -</body> - diff --git a/www/vincent.demeester.fr/content/legacy/posts/2020-02-22-digital-minimalism.org b/www/vincent.demeester.fr/content/legacy/posts/2020-02-22-digital-minimalism.org @@ -1,130 +0,0 @@ -#+title: On digital minimalism, Linux, NixOS and Emacs -#+date: <2020-02-22 Sat> -#+filetags: minimalism digital emacs linux nixos -#+setupfile: ../templates/post.org/ - -* Introduction - -I've been reading and listening about Minimalism and Digital Minimalism for a little while -now. I've watch some [[https://www.youtube.com/channel/UCJ24N4O0bP7LGLBDvye7oCA][Matt D'Avella]] youtube video (and documentary), read [[https://www.goodreads.com/book/show/40672036-digital-minimalism][Digital -Minimalism]] from [[https://www.goodreads.com/author/show/147891.Cal_Newport][Cal Newport]], and read a bunch of [[Links][articles and blog posts]]. - -I wouldn't say I am a minimalist, neither am I a digital minimalist *but* it is something -that is a bit appealing and I feel I am slowly taking inspiration from those. I've started -reducing to a minimun what my /smart/-phone does, I've reduced the number of /gadgets/ -I've add over time. But in this posts, I am going to focus on my systems and tools — this -means Linux distributions, Emacs and other tools. - -* A little bit of history (or context) - -I've been using GNU/Linux for ages now. It has been around 22 years now that I discovered -Red Hat[fn:1] Linux, 5.2 at the time. I've use it as my primary operating system almost -ever sync. During that time, I've tried so many distribution: from [[https://en.wikipedia.org/wiki/Mandriva_Linux][Mandrake]] (later -Mandriva), to [[https://www.debian.org/][Debian]] (3.0 -> 9.0 on some servers) and [[https://www.ubuntu.com][Ubuntu]] (on the first ever public -release), with a long time on [[https://gentoo.org/][Gentoo]] and later [[https://www.archlinux.org/][Archlinux]]. I've used Gnome, KDE, wmii, -XMonad, awesome-vm. I've used bash, zsh, fish, switching from one to another multiple -times. I've used Emacs, vim, IntelliJ, Eclipse, VSCode… My gentoo/archlinux days made me -try and /use/ a lot of tools (screen, tmux, …) and customization. - -I had the habit to customize everything, down to the theme and icons I use. There was a -time where I would patch and re-package some GTK themes and icons set. *I had to -customize everything*, that was my learning experience. I would often break things and -have to re-install the system — and *it was fun* 😎. - -But the more I /grew/, the more I worked for different companies, the less time I had to -do this. I was also learning a lot about tests, reproducibility at that time. My /will/ to -customization and /instability/ slowly faded, I wanted to be able to focus on what -mattered, and not loose time on silly things that I would break soon after making it. - -* Minimalism and Digital Mininalism - -Let's try to define really quick what is minimalism and digital minimalism about.Digital -minimalism is Minimalism in the digital world, and [[https://www.theminimalists.com/minimalism/][minimalism]] can be seen as [[https://jamesstuber.com/minimalism-as-a-framework/][a Framework -for Decision Making]]. - -#+begin_quote -Every decision we make is constrained by limited resources. Money, materials, energy. Even -the richest man in the world is limited by time, and has to make decisions accordingly. - -Here are some factors that make minimalism well suited for decision making: - -- Practicing minimalism helps develop an improved ability to discern what’s important and - what’s not -- It becomes easier to let go of ‘sort of important’ things -- What you choose to keep is a reflection of your values -#+end_quote - -In a gist, Digital Minimalism is about making conscious choice of what you use and what -you do in the digital world, a world of abundance (information, software, …). - -Let's take two examples: our desktops and our phones. - -On desktop, digital minimalism can be something like the follow blog post : [[http://neugierig.org/software/blog/2014/07/anti-dashboard-manifesto.html][Tech Notes: -The Anti-Dashboard Manifesto]]. - -#+begin_quote -Now take that reasoning further: It's not useful to reserve a portion of my screen for -displaying which applications are running, as the things that are running are visible and -the things that aren't visible can be found when necessary. There's no need for an icon -displaying wifi status; if I'm connected it's uninteresting and if I'm not connected I'll -surely discover it if I attempt to use the internet. - -I took this reasoning to its conclusion. I run my computers with the screen blank except -for the apps I run, and the apps I run I configure to display a minimal amount of -information. I think of this as being anti-dashboard: against the cognitive clutter of -extraneous information. My computer is not a cockpit and I am at my best when I'm only -thinking about the single task at hand. -#+end_quote - -This is taking things a little bit too far for me *but* it does resonate with me, and as -you'll see in the following articles (and on my configuration), I share some of Evan's -belief. By default, my desktop do only show a background (be an image or a color) and -anything related to time, battery and other status is a keybinding away (the =Win= key). - -And on the phone: [[https://robertheaton.com/2020/03/18/yourself-happier-iphone-worse/][How to make yourself happier by making your iPhone worse | Robert Heaton]] -— which I followed almost word for word, but this isn't the subject of this post. - -* Emacs, Nix, NixOS, =home-manager= and other tools - -How a GNU/Linux distribution like NixOS comes into this. First, let's see what I want : - -- A system that is tailored to my needs, that makes me efficient. -- A system that is customizable, to answer the previous item. I want to be able to modify - the default behavior if it doesn't suit me. -- A system that is reproductible and easy to replicate. If I change my hardware, or if I - need to re-install my system for /any reason/. -- A way to share configuration on my infra. This is probably the developer speaking, but I - want to write something once and re-use it several times. -- A developer environment that is reproductible, on-demand and /safe/. -- Use defaults of the software I use as much as possible. This one is tricky to achiev for - several reasons: - + I am used to customize everything (/easy to fix/) - + I use a custom keyboard layout ([[https://bepo.fr][bepo]]), so if I go with default keybinding, I will have - the wrong /muscle memory/ (and they could be not optimized either) -- Hackable tools that I can manipulate as I want. -- Use the right tool at the right time, trying not to reinvent the wheel. - -As it turns out Nix and NixOS are giving all the components required for my /almost/ ideal -setup. - -If you complete that with a /not really minimalist/ editor, called [[https://www.gnu.org/software/emacs/][GNU Emacs]], you've got a -pretty composable system without leaving Emacs. I'll dig more into my Emacs configuration -and my NixOS setup in different posts — and on the [[https://vincent.demeester.fr/configurations/][=configurations=]] pages — but my take -lately is to try to do with what is available (as built-in, in Emacs for example). After -reading the docs, if it's not sufficient, I may look for an external module or tool. - -* Conclusion - -This was a weird post that mixes up tooling, minimalism and thoughts. It's definitely not -what I initially envisioned. But I'm hoping it introduce a bit my take on things. - -* Links - -- [[http://neugierig.org/software/blog/2014/07/anti-dashboard-manifesto.html][Tech Notes: The Anti-Dashboard Manifesto]] -- [[https://blog.zdsmith.com/posts/digital-minimalism-for-the-working-hacker.html][Subset Park: Digital Minimalism for the Working Hacker]] -- [[https://jamesstuber.com/minimalism-as-a-framework/][Minimalism as a Framework for Decision Making | JamesStuber.com]] -- [[https://robertheaton.com/2020/03/18/yourself-happier-iphone-worse/][How to make yourself happier by making your iPhone worse | Robert Heaton]] - -* Footnotes - -[fn:1] And I now work for Red Hat Inc., what a journey 😝 diff --git a/www/vincent.demeester.fr/content/legacy/posts/2020-03-22-org-mode-website.org b/www/vincent.demeester.fr/content/legacy/posts/2020-03-22-org-mode-website.org @@ -1,562 +0,0 @@ -#+title: Migrating to an org-mode website -#+date: <2020-03-22 Sun> -#+filetags: orgmode website emacs -#+setupfile: ../templates/post.org - -* Introduction -:PROPERTIES: -:ID: 24a765bd-a0ed-42cf-b96c-db667f7d37e2 -:END: - -This is a story… a story of me changing the way I code and publish my website. In the -past, I've switch from [[https://vincent.demeester.fr/posts/2012-05-07-reinit-and-jekyll/][Jekyll]] to [[https://vincent.demeester.fr/posts/2015-05-01-orgmode-et-jekyll/]["=orgmode= and Jekyll"]] to [[https://vincent.demeester.fr/posts/2015-05-09-migration-to-hugo/][Hugo]] (sorry those are written -in french). The past year, I've written and documented myself a little bit about -[[https://www.theminimalists.com/minimalism/][minimalism]] and [[https://www.goodreads.com/book/show/40672036-digital-minimalism][digital minimalism]]. Although I don't see myself as a minimalist, it helped -me realize some issues I had. - -I also realized if I want to write more, I need to lower the barrier between writing and -publishing my content ; /if I want it to be published, of course/. This /post/ is about -what I'm putting in place for this, with a premise : I spend my life in [[https://www.gnu.org/software/emacs/][Emacs]] and thus in -[[https://orgmode.org/][=orgmode=]]. And [[https://orgmode.org/][=orgmode=]] is feature-full and has this badass feature : =org-publish=. - -To build and publish this website, we will /try/ to rely on a reproducible setup, meaning -[[https://www.gnu.org/software/emacs/][Emacs]] and [[https://orgmode.org/][=orgmode=]] of course, [[https://www.gnu.org/software/make/][GNU Make]] of course *but* most importantly, [[https://nixos.org/nix/][Nix]] (in the near -future 👼). - -:update: -There is now an article about it, that uses literate programming: [[../articles/meta_publishing_this_website.org][publishing this -website]]. The content of the post might no be up-to-date at some point. -:end: - - -* Requirements -:PROPERTIES: -:ID: 09991f8e-4257-443c-a3a3-40f449df4597 -:END: - -Let's list the requirements I feel I have for my website: - -- Full control over the URL of the published posts. :: - This is a golden rule of the web: should I change the publishing system, I want to be - able to stick to the same URLs or else all external references would be broken. This is - a big no-no and in my opinion it makes most blogging systems unacceptable. -- Top-notch Org support. :: - I believe generators like Jekyll and Hugo only have partial Org support. You end up - requiring some conversion tooling to get the job done. -- Simple publishing pipeline. :: - I want the generation process to be as simple as possible. This is important for - maintenance. Should I someday switch host, I want to be sure that I can set up the same - pipeline. -- Full control over the publishing system. :: - I want maximum control over the generation process. I don’t want to be restricted by a - non-Turing-complete configuration file or a dumb programming language. -- Ease of use. :: - The process as a whole must be as immediate and friction-less as possible, or else I - take the risk of feeling too lazy to publish new posts and update the content. -- Hackability. :: - Last but not least, and this probably supersedes all other requirements: The system must - be hackable. Lisp-based systems are prime contenders in that area. - -* DONE Organizing -CLOSED: [2020-03-21 Sat 17:57] -:PROPERTIES: -:ID: 78251967-c48a-476d-bc39-c748fc412927 -:END: -:LOGBOOK: -- State "DONE" from "TODO" [2020-03-21 Sat 17:57] -:END: - -Let's describe what I do want to publish here: - -- Posts :: this is what we call /blog/ these days : short to medium article that are valid - at a point of time, as may contain /deprecated/ content, or content that do not reflect - my views at a later point in time. -- Articles :: medium to long article about a topic. Those should be up-to-date or - explicitly mark as deprecated or invalid. /In a ideal world this is my *ready for the - public* knowledge database, a bit like [[https://braindump.jethro.dev/][Jethro's Braindump]]/. -- Configurations :: medium to long article about my configurations. Those are base on my - ~home~ /configuration/ mono-repository, and usually follow literate programming - principles. -- About :: an about page about the author of the website (aka [[https://vincent.demeester.fr][me]]), linking external - contributions (GitHub/Gitlab/… profiles, Talks, …). - -* DONE Publishing -CLOSED: [2020-03-25 Wed 15:54] -:PROPERTIES: -:ID: da542763-78b9-46c0-bcf7-d8d2a2b18677 -:END: -:LOGBOOK: -- State "DONE" from "TODO" [2020-03-25 Wed 15:54] -:END: - -As said above, the goal is to publish everything using only [[https://www.gnu.org/software/emacs/][Emacs]] and [[https://orgmode.org/][=orgmode=]] (with the -help of some standard GNU tools). - -The [[file:~/src/sbr/publish.el][~publish.el~]] file is where all the magic happens: - -- I want to generate something that is ~html5~ (almost?). The /preamble/, /content/ and - /postamble/ ~div~ can be customized using ~org-html-div~. Same goes for the /container/ - element that is used for "wrapping top level sections", it is customized using - ~org-html-container-helement~ (we want ~<section>~). There is a few additional variable - that I might document one day 😛. - - #+begin_src emacs-lisp - (setq org-export-use-babel nil) - (setq org-link-abbrev-alist '(("att" . org-attach-expand-link))) - - ;; setting to nil, avoids "Author: x" at the bottom - (setq org-export-with-section-numbers nil - org-export-with-smart-quotes t - org-export-with-toc nil) - - (defvar sbr-date-format "%b %d, %Y") - - (setq org-html-divs '((preamble "header" "top") - (content "main" "content") - (postamble "footer" "postamble")) - org-html-container-element "section" - org-html-metadata-timestamp-format sbr-date-format - org-html-checkbox-type 'unicode - org-html-html5-fancy t - org-html-doctype "html5" - org-html-htmlize-output-type 'css - org-html-htmlize-font-prefix "org-" - org-src-fontify-natively t - org-html-coding-system 'utf-8-unix) - #+end_src - -- Part of the ~<head>~, preamble and postamble are customized for the website. - + ~head~ :: - #+begin_src emacs-lisp - (defvar sbr-website-html-head - "<link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> - <meta name='viewport' content='width=device-width, initial-scale=1'> - <link rel='stylesheet' href='/css/new.css' type='text/css'/> - <link rel='stylesheet' href='/css/syntax.css' type='text/css'/> - <link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' />") - #+end_src - + premable :: - #+begin_src emacs-lisp - (defun sbr-website-html-preamble (plist) - "PLIST: An entry." - ;; Skip adding subtitle to the post if :KEYWORDS don't have 'post' has a - ;; keyword - (when (string-match-p "post" (format "%s" (plist-get plist :keywords))) - (plist-put plist - :subtitle (format "Published on %s by %s." - (org-export-get-date plist sbr-date-format) - (car (plist-get plist :author))))) - - ;; Below content will be added anyways - "<nav> - <img src=\"/images/favicon.ico\" id=\"sitelogo\"/> <a href='/'>home</a> / - <a href='/posts/'>posts</a> (<a href='/index.xml'>rss</a>) / - <a href='/articles/'>articles</a> / - <a href='/configurations/'>configurations</a> / - <a href='https://dl.sbr.pm/'>files</a> / - <a href='/about/'>about</a></li> - </nav>") - #+end_src - + postamble :: - #+begin_src emacs-lisp - (defvar sbr-website-html-postamble - "<footer> - <span class='questions'>Questions, comments ? Please use my <a href=\"https://lists.sr.ht/~vdemeester/public-inbox\">public inbox</a> by sending a plain-text email to <a href=\"mailto:~vdemeester/public-inbox@lists.sr.ht\">~vdemeester/public-inbox@lists.sr.ht</a>.</span> - <span class='opinions'>Opinions stated here are my own and do not express the views of my employer, spouse, children, pets, neighbors, secret crushes, favorite authors, or anyone else who is not me. And maybe not even me, depending on how old this is.</span> - <span class='copyright'> - Content and design by Vincent Demeester - (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) - </span><br /> - <span class='engine'> - Powered by <a href='https://www.gnu.org/software/emacs/'>Gnu Emacs</a> and <a href='https://orgmode.org'>orgmode</a> - </span> - </footer>") - #+end_src -- =orgmode= is able to generate a site-map. This is what we are going to use to generate - the index files for ~posts/~ and ~articles~ mainly. - #+begin_src emacs-lisp - (defun sbr/org-sitemap-format-entry (entry style project) - "Format posts with author and published data in the index page. - - ENTRY: file-name - STYLE: - PROJECT: `posts in this case." - (cond ((not (directory-name-p entry)) - (format "%s — [[file:%s][%s]] - :PROPERTIES: - :PUBDATE: [%s] - :END:" - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)) - entry - (org-publish-find-title entry project) - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)))) - ((eq style 'tree) (file-name-nondirectory (directory-file-name entry))) - (t entry))) - - (defun sbr/org-publish-sitemap (title list) - "" - (concat "#+TITLE: " title "\n\n" - (org-list-to-subtree list))) - #+end_src -- =orgmode= is able to generate a rss, with =ox-rss=. This is what we are going to use to - generate the rss files for ~posts~ and ~articles~. This is _heavily_ customized. - #+begin_src emacs-lisp - (defun sbr/org-get-first-paragraph (file) - "Get string content of first paragraph of file." - (ignore-errors - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (show-all) - (let ((first-begin (progn - (org-forward-heading-same-level 1) - (next-line) - (point))) - (first-end (progn - (org-next-visible-heading 1) - (point)))) - (buffer-substring first-begin first-end))))) - - (defun sbr/org-rss-publish-to-rss (plist filename pub-dir) - "Prepare rss.org file before exporting." - (let* ((postsdir (plist-get plist :base-directory))) - (with-current-buffer (find-file filename) - (erase-buffer) - (insert "#+TITLE: Posts\n") - (insert "#+AUTHOR: Vincent Demeester\n") - (insert "#+OPTIONS: toc:nil\n") - (let* ((files-all - (reverse (directory-files "." nil - "[0-9-]+.*\\.org$"))) - (files (subseq files-all 0 (min (length files-all) 30)))) - (message (format "foo: %s" filename)) - (dolist (post files) - (let* ((post-file post) - (post-title (org-publish-find-title post-file plist)) - (preview-str (sbr/org-get-first-paragraph post-file)) - (date (replace-regexp-in-string - "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)-.*" - "\\1" post))) - (insert (concat "* [[file:" postsdir "/" post "][" post-title "]]\n\n")) - (org-set-property "ID" post) - (org-set-property "RSS_TITLE" post-title) - ;; ox-rss prepends html-link-home to permalink - (org-set-property "RSS_PERMALINK" - (concat postsdir "/" - (file-name-sans-extension post) - ".html")) - (org-set-property - "PUBDATE" - (format-time-string - "<%Y-%m-%d %a %H:%M>" - (org-time-string-to-time - (replace-regexp-in-string - "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)-.*" - "\\1" post)))) - (insert preview-str) - (newline 1) - (insert (concat "[[file:" postsdir "/" post "][(Read more)]]\n\n")))) - (save-buffer)))) - (let ((user-mail-address "t") - (org-export-with-broken-links t) - (org-rss-use-entry-url-as-guid nil)) - (org-rss-publish-to-rss plist filename pub-dir))) - #+end_src -- Finally let's set the ~org-publish-project-alist~ to publish our projects - #+begin_src emacs-lisp - (setq org-publish-project-alist - `(("posts" - :base-directory "posts" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/posts" - :exclude ,(regexp-opt '("README.org" "draft")) - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "index.org" - :sitemap-title "Posts" - :sitemap-format-entry sbr/org-sitemap-format-entry - :sitemap-style list - :sitemap-sort-files anti-chronologically - :sitemap-function sbr/org-publish-sitemap - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("posts-rss" - :base-directory "posts" - :base-extension "org" - :recursive t - :html-link-home "https://vincent.demeester.fr/" - :rss-link-home "https://vincent.demeester.fr/posts/" - :html-link-use-abs-url t - :rss-extension "xml" - :publishing-directory "./public" - :publishing-function (sbr/org-rss-publish-to-rss) - :section-number nil - :exclude ".*" - :include ("index.org")) - ("articles" - :base-directory "articles" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/articles" - :exclude ,(regexp-opt '("README.org" "draft")) - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "sitemap.org" - :sitemap-title "Articles" - :sitemap-style tree - :sitemap-sort-files anti-chronologically - ;;:sitemap-format-entry sbr/org-sitemap-format-entry - ;;:sitemap-function sbr/org-publish-sitemap - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("articles-assets" - :exclude ,(regexp-opt '("*.org")) - :base-directory "articles" - :base-extension ,site-attachments - :publishing-directory "./public/articles" - :publishing-function org-publish-attachment - :recursive t) - ("about" - :base-directory "about" - :base-extension "org" - :exclude ,(regexp-opt '("README.org" "draft")) - :index-filename "index.org" - :recursive nil - :with-footnotes t - :with-toc nil - :with-drawers t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/about" - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("index" - :base-directory "" - :base-extension "org" - :exclude ,(regexp-opt '("README.org" "draft")) - :index-filename "index.org" - :recursive nil - :with-footnotes t - :with-toc nil - :with-drawers t - :with-title nil - :publishing-function org-html-publish-to-html - :publishing-directory "./public" - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("css" - :base-directory "./css" - :base-extension ,site-attachments - :recursive t - :publishing-directory "./public/css" - :publishing-function org-publish-attachment - :recursive t) - ("images" - :base-directory "./images" - :base-extension ,site-attachments - :publishing-directory "./public/images" - :publishing-function org-publish-attachment - :recursive t) - ("assets" - :base-directory "./assets" - :base-extension ,site-attachments - :publishing-directory "./public/assets" - :publishing-function org-publish-attachment - :recursive t) - ("legacy" - :base-directory "./legacy" - :base-extension ,site-attachments - :publishing-directory "./public/" - :publishing-function org-publish-attachment - :recursive t) - ("all" :components ("posts" "about" "index" "articles" "articles-assets" "css" "images" "assets" "legacy" "posts-rss")))) - #+end_src - -Here are some /inspiration/ I took for this publishing code: - -- [[https://thibaultmarin.github.io/blog/posts/2016-11-13-Personal_website_in_org.html][Personal website in org]] -- [[https://vicarie.in/posts/blogging-with-org.html][Blogging with Org publishing]] -- [[https://ambrevar.xyz/blog-architecture/][A blog in pure Org/Lisp]] -- [[https://zngguvnf.org/2017-07-13--blogging-with-org-static-blog.html][Blogging with org-static-blog]] -- [[https://bastibe.de/2013-11-13-blogging-with-emacs.html][Blogging with Emacs]] -- [[https://gjhenrique.com/meta.html][Blogging with org-mode and Gitlab Pages]] - - -* DONE Styling -CLOSED: [2020-03-23 Mon 19:02] -:PROPERTIES: -:ID: 052e297f-01b2-41d3-9689-cd2946b56cfb -:END: -:LOGBOOK: -- State "DONE" from "STARTED" [2020-03-23 Mon 19:02] -:END: - -The style of the website has be as simple as possible, and also really light. This means: -- use default system font as much as possible -- have a small stylesheet, rely on the default as much as we can - -In addition, I want support for: -- side notes -- code syntax highlight -- table of content - -The inspiration for this website, in term of style are the following: -- [[https://vincent.demeester.fr/posts/2018-08-16-gotest-tools-assertions/][Vincent Demeester]] -- [[https://braindump.jethro.dev/zettels/zettelkasten/][Jethro's Braindump]] -- [[https://hamberg.no/gtd/][GTD in 15 minutes – A Pragmatic Guide to Getting Things Done]] -- [[https://www.inkandswitch.com/local-first.html][Local-first software: You own your data, in spite of the cloud]] -- [[https://archive.casouri.cat/note/2018/blog-in-org-mode-revisited/index.html][Blog in Org Mode, Revisited]] -- [[https://kind.sigs.k8s.io/][kind]] -- [[http://willcrichton.net/notes/idioms-of-dynamic-languages/][Idioms of Dynamic Languages | Will Crichton]] -- [[https://peter.bourgon.org/blog/2019/09/11/programming-with-errors.html][Peter Bourgon · Programming with errors]] -- [[https://johv.dk/blog/bare-metal-assembly-tutorial.html][Getting started with bare-metal assembly — Jonas Hvid]] - -To be able to define the style a bit, let's try some things below. From this point on, -this is random content just to try my style out. 👼 - -There is more in [[../articles/sandbox.org][the sandbox]]. - ------- - -#+begin_abstract -Let's dig into how I setup my development environment when working on ~tektoncd/pipeline~ -#+end_abstract - -#+TOC: headlines 2 - -** sub-heading 1 - -Checking for errors is *very common* in Go, having =Comparison= function for it was a requirement. - -#+BEGIN_aside -This is a side note. If collection is a string, item must also be a string, and is -compared using =strings.Contains()=. If collection is a Map, contains will succeed if item -is a key in the map. -#+END_aside - -- =Error= fails if the error is =nil= *or* the error message is not the expected one. -- =ErrorContains= fails if the error is =nil= *or* the error message does not contain the expected substring. -- =ErrorType= fails if the error is =nil= *or* the error type is not the expected type. - -Let's first look at the most used : =Error= and =ErrorContains=. -When you're working on ~pipeline~, usually you want : - -1. make sure it compiles : ~go build -v ./..~ -2. Running unit tests : ~go test ./...~ (bonus use [[https://github.com/vdemeester/ram][~ram~]] for continuous testing) -3. End-to-end tests : ~go test -tags e2e ./...~ (or simply using `./test/` package) - - *Make sure you re-deploy before running the e2e tests* using ~ko apply -f ./config~, - otherwise you're testing the wrong code. - -#+BEGIN_SRC go - var err error - // will fail with : expected an error, got nil - assert.Check(t, cmp.Error(err, "message in a bottle")) - err = errors.Wrap(errors.New("other"), "wrapped") - // will fail with : expected error "other", got "wrapped: other" - assert.Check(t, cmp.Error(err, "other")) - // will succeed - assert.Check(t, cmp.ErrorContains(err, "other")) -#+END_SRC - -#+CAPTION: This is the caption for the next figure link (or table) -#+NAME: fig:SED-HR4049 -#+ATTR_ORG: :width 400/600 -#+ATTR_HTML: :width 100% -[[../images/emacs/2020-02-29-13-46-08.png]] - -If this is the case, then what makes dynamic languages feel easy? Can we take what we learn in answering this question and improve the ergonomics of our static languages? For example, in 2018, I don’t think there’s as strong an argument for “you don’t have to write out the types,” since modern type inference eliminates most of the keystrokes required (even though many major languages still lack such facilities). Plus, saving a few keystrokes does not seem like a critical bottleneck in the programming process. - -#+NAME: fig:tektoncd-logo -[[../images/emacs/2020-02-29-14-41-59.png]] - - -** sub-heading 2 - -Some content from my other org-mode files. - -#+begin_description -I already wrote 2 previous posts about golang and testing. It's something I care deeply about and I wanted to continue -writing about it. It took me a bit more time than I thought, but getting back to it. Since the [[http://vincent.demeester.fr/posts/2017-04-22-golang-testing-golden-file/][last post]], Daniel -Nephin -and I worked (but mainly Daniel 🤗) on bootstrapping a testing helper library. -#+end_description - -#+BEGIN_QUOTE -Package assert provides assertions for comparing expected values to actual values. When -assertion fails a helpful error message is printed. -#+END_QUOTE - -There is already some good =testing= helpers in the Go ecosystem : [[https://github.com/stretchr/testify][=testify=]], [[http://labix.org/gocheck][=gocheck=]], -[[https://github.com/onsi/ginkgo][=ginkgo=]] and a lot more — so why create a new one ? There is multiple reason for it, most -of them can be seen in the following [[https://github.com/gotestyourself/gotest.tools/issues/49#issuecomment-362436026][GitHub issue]]. - -[[https://github.com/dnephin/][Daniel]] also wrote a very useful [fn:1]converter if your code base is currently using =testify= : -=gty-migrate-from-testify=. - -#+BEGIN_SRC sh -$ go get -u gotest.tools/assert/cmd/gty-migrate-from-testify -# […] -$ go list \ - -f '{{.ImportPath}} {{if .XTestGoFiles}}{{"\n"}}{{.ImportPath}}_test{{end}}' \ - ./... | xargs gty-migrate-from-testify -#+END_SRC - -We'll Use =Assert= for the rest of the section but any example here would work with -=Check= too. When we said =Comparison= above, it's mainly the [[https://godoc.org/gotest.tools/assert#BoolOrComparison][BoolOrComparison]] interface — -it can either be a boolean expression, or a [[https://godoc.org/gotest.tools/assert/cmp#Comparison][cmp.Comparison]] type. =Assert= and =Check= code -will be /smart/ enough to detect which one it is. - -#+BEGIN_SRC go - assert.Assert(t, ok) - assert.Assert(t, err != nil) - assert.Assert(t, foo.IsBar()) -#+END_SRC - - -* What's next ? -:PROPERTIES: -:ID: 678bf6cb-68e7-4fc9-af50-23d283293ab1 -:END: - -One thing is to import old blog posts from [[https://vincent.demeester.fr][vincent.demeester.fr]]. This is easily done with -[[https://pandoc.org/][Pandoc]] and a small bash loop — and some manual adjusting later on 😛. - -#+begin_src bash -for post in ~/src/github.com/vdemeester/blog/content/posts/*.md; do - pandoc -f markdown -t org -o posts/$(basename -s .md ${post}).org ${post} -done -#+end_src - - -What is still /to do/ after this initial take. - -- [ ] List =FILETAGS= for taximony -- [ ] Maybe use [[https://css-tricks.com/snippets/css/complete-guide-grid/][css grid]] for the UI - -* Footnotes -:PROPERTIES: -:ID: 220a0cce-39c3-4b5f-aaa0-66e3a2450f04 -:END: - -[fn:1] foo is bar, bar is baz diff --git a/www/vincent.demeester.fr/content/legacy/posts/2020-04-15-emacs-bankruptcy-is-fun.org b/www/vincent.demeester.fr/content/legacy/posts/2020-04-15-emacs-bankruptcy-is-fun.org @@ -1,108 +0,0 @@ -#+title: Emacs bankruptcy is fun -#+date: <2020-04-15 Wed> -#+filetags: emacs configuration optimization -#+setupfile: ../templates/post.org - -* Introduction - -Since go 1.14 go released, I've had a broken =go-mode= setup on my Emacs. I was using -=lsp-mode= and =gopls= and well, the update broke everything. I initally try to fix it but -I made it worse. At the same time, I started to get fed up with some performance issue of -my configuration and how slow my Emacs starts, about 6s. - -I, thus, declared my third Emacs bankruptcy, =:disabled= everything and slowly started -from scratch, with the following goal: - -- Have it start quick, as less than a second, not too much more than =emacs -Q= would -- Disable anything that I don't use often initially -- Try to use as much built-in as possible (example: using =icomplete= instead of - =ivy=/=counsel=) - -* Do I really need this feature - -Following [[https://protesilaos.com/][Protesilaos Stavrou]]'s emacs videos (and [[https://protesilaos.com/dotemacs/][=dotemacs=]]) for a while now, I have a -tendency to try to use built-in feature as much as possible. The most obvious example is -using =icomplete= instead of =ivy=/=counsel=. - -When I started my /bankruptcy/, I disabled every single customization I had, either using -=:disabled= when using =use-package= *or* the =(when nil)= /hack/. I then started Emacs -and acted on what was missing : - -1. Do I really miss it ? An example would be, at least initially, the completion in a =go= - file. I do miss it, but I miss it *way less* than having Emacs lagging because of - =lsp-mode= and showing me wrong completion. -2. Is there a built-in option to what I previously used ? Here, the =icomplete= example - fits well, or =isearch= instead of =swiper=. -3. Do I need it at startup or /on-demand/ ? - -* Looking into what takes time - -In "Advanced Techniques for Reducing Emacs Startup Time"[fn:1], I discovered the [[https://github.com/jschaf/esup][=esup=]] -emacs library. In a gist, this is a profiler for Emacs. It starts a new Emacs instance and -look at the loading time. - -#+CAPTION: esup "result" view -[[../images/2020-04-15-16-12-54.png]] - -Then, you can do a simple loop: - -- Run =esup= -- Look at the top result -- Fix it (lazy load, removing the feature, …) -- Re-iterate - -* Loading on-demand - -Once you have the setup to know what takes time and what not, it's time to look into how -to load the most thing on demand. - -For this, [[https://github.com/jwiegley/use-package][=use-package=]] is amazing, it tremendously help autoloading modules on-demand. If -you are not using =use-package=, usually you are using =require=, which loads the -underlying source file (all of it). - -With =use-package=, there is multiple ways to load on demand: - -- =:commands= to add callable that will trigger loading the package -- =:bind=, =:bind*=, =:bind-keymap= and =:bind-keymap*= to bind key sequences to the - global keymap or a specific keymap. -- =:mode= and =:interpreter= establish a deferred binding with the =auto-mode-alist= and - =interpreter-mode-alist=. -- =:hook= allows adding functions onto the package hook -- =:defer= is the most generic one, all the previous keyword imply =:defer=. You can - specify a number of second of idle to load the package. - -#+BEGIN_aside -In a gist for =org-babel=, use =use-package ob-python= and never call =org-babel-do-languages=. -#+END_aside -Once this is done, you are left with edge cases, like =org-babel-do-languages=. Those are -to be handle case by case. The good thing about those cases is that you'll learn what -those function do and this will give you an even better understanding of what is -happening. - -Doing this exercise also forces you to make you see if you really use that feature or -not. I ended up removing entire feature from my configuration because they were taking -quite some time to load, and was used almost never. Instead I am forcing myself to learn -more what I can do with the built-in features first. - -* Conclusion - -All in all, this /bankruptcy/ was the most fun I had to do. I consider myself still in the -process but the base is there. - -1. I learned a lot ! -2. My Emacs starts in 0.6s against previously in 5s — =emacs -q= starts in about 0.3s so - there is still a little bit of room for improvement. -3. I discovered / re-discovered a lot of built-in feature -4. I started documenting my configuration, see [[../configurations/emacs.org][here]]. - -🎉 - -:update: -Well, I've look into the /portable dump/ feature of Emacs, thanks to [[https://archive.casouri.cat/note/2020/painless-transition-to-portable-dumper/index.html][Painless Transition -to Portable Dumper]]. And I am now down to =0.091s= for the startup. There is a few gotchas -with /portable dump/, I'll try to write about it later. -:end: - -* Footnotes - -[fn:1]: [[https://blog.d46.us/advanced-emacs-startup/][Advanced Techniques for Reducing Emacs Startup Time]] diff --git a/www/vincent.demeester.fr/content/legacy/posts/2020-06-21-website-update.org b/www/vincent.demeester.fr/content/legacy/posts/2020-06-21-website-update.org @@ -1,16 +0,0 @@ -#+title: website update -#+date: <2020-06-08 Mon> -#+filetags: website css new simple -#+setupfile: ../templates/post.org - -* Introduction - -A really small article to talk about small updates on the website (/well, maybe not that -small/). In a gist: a new css and articles changes. - -- Updating the style of the website to something really similar to [[https://newcss.net/][new.css]]. It is way - simpler and /pleasing/ (at least for me). -- My [[../articles][=/articles=]] are now exporting from my [[../articles/personal_knowledge_base.org][personal knowledge base]], powered by - [[../articles/org_roam.org][=org-roam=]]. -- A new [[https://dl.sbr.pm/][=/files=]] part is available, where I share some random file. See for example the - [[https://dl.sbr.pm/wallpapers/dynamics/][dynamic wallpaper]] part. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2020-07-08-june-status-update.org b/www/vincent.demeester.fr/content/legacy/posts/2020-07-08-june-status-update.org @@ -1,109 +0,0 @@ -#+title: Status update, June 2020 -#+date: <2020-07-08 Wed> -#+filetags: status update -#+setupfile: ../templates/post.org - -* Introduction - -Time for the first new monthly status update! I do like those updates from [[https://drewdevault.com/2020/06/15/Status-update.html][Drew DeVault]] -and [[https://emersion.fr/blog/2020/status-update-19/][Simon Ser]], so I figured, why not trying myself 🙃. I am not sure where to start and -where to end, but I guess I'll figure things out as I go. - -* Tekton & OpenShift Pipelines - -As you know, /or may not/, I am working on the [[https://github.com/tektoncd/][TektonCD]] project and also on our [[https://redhat.com][RedHat]] -product [[https://www.openshift.com/learn/topics/pipelines][OpenShift Pipelines]]. As far as the month of June went : - -- We release [[https://github.com/tektoncd/pipeline/releases/tag/v0.13.0][v0.13.0]] "Bobtail Bishop" and a bunch of fixes ([[https://github.com/tektoncd/pipeline/releases/tag/v0.13.2][v0.13.2]]) - + It's the second release after the =v1beta1= bump, and we start to stabilise things. - + [[https://github.com/tektoncd/pipeline/releases/tag/v0.14.0][v0.14.0]] will (and actually is already) a more feature-packed release because there is - now the =finally= field support and cloud-events opt-in. -- But the *most important* contributions I tried to make during that month is the TEP - process. *TEP* stands for *Tekton Enhancement proposals*. - - #+begin_src markdown - # Tekton Enhancement Proposals (TEPs) - - A Tekton Enhancement Proposal (TEP) is a way to propose, communicate - and coordinate on new efforts for the Tekton project. You can read - the full details of the project in - [TEP-1](https://github.com/tektoncd/community/blob/master/teps/0001-tekton-enhancement-proposal-process.md). - - ## What is a TEP - - A standardized development process for Tekton is proposed in order to - - - provide a common structure and clear checkpoints for proposing - changes to Tekton - - ensure that the motivation for a change is clear - - allow for the enumeration stability milestones and stability - graduation criteria - - persist project information in a Version Control System (VCS) for - future Tekton users and contributors - - support the creation of _high value user facing_ information such - as: - - an overall project development roadmap - - motivation for impactful user facing changes - - ensure community participants are successfully able to drive changes - to completion across one or more releases while stakeholders are - adequately represented throughout the process - - This process is supported by a unit of work called a Tekton - Enhancement Proposal (TEP). A TEP attempts to combine aspects of the - following: - - - feature, and effort tracking document - - a product requirements document - - design document - - into one file which is created incrementally in collaboration with one - or more [Working - Groups](https://github.com/tektoncd/community/blob/master/working-groups.md) - (WGs). - - This process does not block authors from doing early design docs using - any means. It does not block authors from sharing those design docs - with the community (during Working groups, on Slack, GitHub, …. - - ,**This process acts as a requirement when a design docs is ready to be - implemented or integrated in the `tektoncd` projects**. In other words, - a change that impact other `tektoncd` projects or users cannot be - merged if there is no `TEP` associated with it. - - This TEP process is related to - - the generation of an architectural roadmap - - the fact that the what constitutes a feature is still undefined - - issue management - - the difference between an accepted design and a proposal - - the organization of design proposals - - This proposal attempts to place these concerns within a general - framework. - - - See [TEP-1](https://github.com/tektoncd/community/blob/master/teps/0001-tekton-enhancement-proposal-process.md) for more details. - #+end_src - -* =home=, Nixos and the rest of thing - -I did some big changes in my [[https://git.sr.ht/~vdemeester/home][=home=]] repository, it's still much a work-in-progress but it -is in a way better state than before. - -- It is more reproductible. All dependencies are managed by [[https://github.com/nmattia/niv][niv]] and all machines are using - a pinned version of channels from there. That way I can test the configuration (on the - CI) and cache the packages for all channels that my machines uses. I also can decide - when I want to upgrade a particular channel (nixos, unstable, …). -- I am slowly experimenting on simplifying things more and more. This is a bit related to - the [[file:2020-02-22-digital-minimalism.org][previous post]]. I am trying to use Gnome3 everywhere. Well configured, managed by - NixOS, it's enough for my test and reduce the configuration cruft I need to do. - -An ongoing work is my knowledge base and how it is published as part of this website : -[[https://vincent.demeester.fr/articles/][articles]]. I am trying to make all those publishable (for the one that do not hold any -secret). I'll document this a bit more at some point but… -- Configurations are now part of that knowledge base, the =docs= folder of [[https://git.sr.ht/~vdemeester/home][=home=]] is going - away. -- I am trying to use litterate configuration as much as possible. So slowly, the content - from [[https://git.sr.ht/~vdemeester/home][=home=]] will be a tangled version of my knowledge base. At least that is the goal as - of today. - -And I feel that's all /for June/. diff --git a/www/vincent.demeester.fr/content/legacy/posts/2020-12-01-nixify-www.draft b/www/vincent.demeester.fr/content/legacy/posts/2020-12-01-nixify-www.draft @@ -1,8 +0,0 @@ -#+title: Nixifying this website -#+date: <2020-12-01 Fri> -#+filetags: website nix -#+setupfile: ../templates/post.org - -* Introduction - -… diff --git a/www/vincent.demeester.fr/content/legacy/posts/diving-into-nix.org.draft b/www/vincent.demeester.fr/content/legacy/posts/diving-into-nix.org.draft @@ -1,8 +0,0 @@ -#+TITLE: Diving into Nix(OS) — introduction -#+SUBTITLE: Series about nixos -#+SETUPFILE: ../templates/post.org - -* TODO Introduction - -This will be the start of a serie of blog post around Nix, Nixpkgs and NixOS. The goal is -to present the pros and cons of Nix and how it benefits to use it in different use cases. diff --git a/www/vincent.demeester.fr/content/legacy/posts/index.org b/www/vincent.demeester.fr/content/legacy/posts/index.org @@ -1,813 +0,0 @@ -#+TITLE: Posts -#+AUTHOR: Vincent Demeester -#+OPTIONS: toc:nil -* [[file:content/legacy/posts/2020-07-08-june-status-update.org][Status update, June 2020]] -:PROPERTIES: -:ID: 2020-07-08-june-status-update.org -:RSS_TITLE: Status update, June 2020 -:RSS_PERMALINK: content/legacy/posts/2020-07-08-june-status-update.html -:PUBDATE: <2020-07-08 Wed 00:00> -:END: - - -Time for the first new monthly status update! I do like those updates from [[https://drewdevault.com/2020/06/15/Status-update.html][Drew DeVault]] -and [[https://emersion.fr/blog/2020/status-update-19/][Simon Ser]], so I figured, why not trying myself 🙃. I am not sure where to start and -where to end, but I guess I'll figure things out as I go. - - -[[file:content/legacy/posts/2020-07-08-june-status-update.org][(Read more)]] - -* [[file:content/legacy/posts/2020-06-21-website-update.org][website update]] -:PROPERTIES: -:ID: 2020-06-21-website-update.org -:RSS_TITLE: website update -:RSS_PERMALINK: content/legacy/posts/2020-06-21-website-update.html -:PUBDATE: <2020-06-21 Sun 00:00> -:END: - - -A really small article to talk about small updates on the website (/well, maybe not that -small/). In a gist: a new css and articles changes. - -- Updating the style of the website to something really similar to [[https://newcss.net/][new.css]]. It is way - simpler and /pleasing/ (at least for me). -- My [[../articles][=/articles=]] are now exporting from my [[../articles/personal_knowledge_base.org][personal knowledge base]], powered by - [[../articles/org_roam.org][=org-roam=]]. -- A new [[https://dl.sbr.pm/][=/files=]] part is available, where I share some random file. See for example the - [[https://dl.sbr.pm/wallpapers/dynamics/][dynamic wallpaper]] part. - -[[file:content/legacy/posts/2020-06-21-website-update.org][(Read more)]] - -* [[file:content/legacy/posts/2020-04-15-emacs-bankruptcy-is-fun.org][Emacs bankruptcy is fun]] -:PROPERTIES: -:ID: 2020-04-15-emacs-bankruptcy-is-fun.org -:RSS_TITLE: Emacs bankruptcy is fun -:RSS_PERMALINK: content/legacy/posts/2020-04-15-emacs-bankruptcy-is-fun.html -:PUBDATE: <2020-04-15 Wed 00:00> -:END: - - -Since go 1.14 go released, I've had a broken =go-mode= setup on my Emacs. I was using -=lsp-mode= and =gopls= and well, the update broke everything. I initally try to fix it but -I made it worse. At the same time, I started to get fed up with some performance issue of -my configuration and how slow my Emacs starts, about 6s. - -I, thus, declared my third Emacs bankruptcy, =:disabled= everything and slowly started -from scratch, with the following goal: - -- Have it start quick, as less than a second, not too much more than =emacs -Q= would -- Disable anything that I don't use often initially -- Try to use as much built-in as possible (example: using =icomplete= instead of - =ivy=/=counsel=) - - -[[file:content/legacy/posts/2020-04-15-emacs-bankruptcy-is-fun.org][(Read more)]] - -* [[file:content/legacy/posts/2020-03-22-org-mode-website.org][Migrating to an org-mode website]] -:PROPERTIES: -:ID: 2020-03-22-org-mode-website.org -:RSS_TITLE: Migrating to an org-mode website -:RSS_PERMALINK: content/legacy/posts/2020-03-22-org-mode-website.html -:PUBDATE: <2020-03-22 Sun 00:00> -:END: - -:PROPERTIES: -:ID: 24a765bd-a0ed-42cf-b96c-db667f7d37e2 -:END: - -This is a story… a story of me changing the way I code and publish my website. In the -past, I've switch from [[https://vincent.demeester.fr/posts/2012-05-07-reinit-and-jekyll/][Jekyll]] to [[https://vincent.demeester.fr/posts/2015-05-01-orgmode-et-jekyll/]["=orgmode= and Jekyll"]] to [[https://vincent.demeester.fr/posts/2015-05-09-migration-to-hugo/][Hugo]] (sorry those are written -in french). The past year, I've written and documented myself a little bit about -[[https://www.theminimalists.com/minimalism/][minimalism]] and [[https://www.goodreads.com/book/show/40672036-digital-minimalism][digital minimalism]]. Although I don't see myself as a minimalist, it helped -me realize some issues I had. - -I also realized if I want to write more, I need to lower the barrier between writing and -publishing my content ; /if I want it to be published, of course/. This /post/ is about -what I'm putting in place for this, with a premise : I spend my life in [[https://www.gnu.org/software/emacs/][Emacs]] and thus in -[[https://orgmode.org/][=orgmode=]]. And [[https://orgmode.org/][=orgmode=]] is feature-full and has this badass feature : =org-publish=. - -To build and publish this website, we will /try/ to rely on a reproducible setup, meaning -[[https://www.gnu.org/software/emacs/][Emacs]] and [[https://orgmode.org/][=orgmode=]] of course, [[https://www.gnu.org/software/make/][GNU Make]] of course *but* most importantly, [[https://nixos.org/nix/][Nix]] (in the near -future 👼). - -:update: -There is now an article about it, that uses literate programming: [[../articles/meta_publishing_this_website.org][publishing this -website]]. The content of the post might no be up-to-date at some point. -:end: - - - -[[file:content/legacy/posts/2020-03-22-org-mode-website.org][(Read more)]] - -* [[file:content/legacy/posts/2020-02-22-digital-minimalism.org][On digital minimalism, Linux, NixOS and Emacs]] -:PROPERTIES: -:ID: 2020-02-22-digital-minimalism.org -:RSS_TITLE: On digital minimalism, Linux, NixOS and Emacs -:RSS_PERMALINK: content/legacy/posts/2020-02-22-digital-minimalism.html -:PUBDATE: <2020-02-22 Sat 00:00> -:END: - - -I've been reading and listening about Minimalism and Digital Minimalism for a little while -now. I've watch some [[https://www.youtube.com/channel/UCJ24N4O0bP7LGLBDvye7oCA][Matt D'Avella]] youtube video (and documentary), read [[https://www.goodreads.com/book/show/40672036-digital-minimalism][Digital -Minimalism]] from [[https://www.goodreads.com/author/show/147891.Cal_Newport][Cal Newport]], and read a bunch of [[Links][articles and blog posts]]. - -I wouldn't say I am a minimalist, neither am I a digital minimalist *but* it is something -that is a bit appealing and I feel I am slowly taking inspiration from those. I've started -reducing to a minimun what my /smart/-phone does, I've reduced the number of /gadgets/ -I've add over time. But in this posts, I am going to focus on my systems and tools — this -means Linux distributions, Emacs and other tools. - - -[[file:content/legacy/posts/2020-02-22-digital-minimalism.org][(Read more)]] - -* [[file:content/legacy/posts/2019-03-23-gotest-tools-poll.org][Golang testing — gotest.tools poll]] -:PROPERTIES: -:ID: 2019-03-23-gotest-tools-poll.org -:RSS_TITLE: Golang testing — gotest.tools poll -:RSS_PERMALINK: content/legacy/posts/2019-03-23-gotest-tools-poll.html -:PUBDATE: <2019-03-23 Sat 00:00> -:END: - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =poll= package. - -#+BEGIN_QUOTE -Package poll provides tools for testing asynchronous code. -#+END_QUOTE - -When you write test, you may test a piece of code that work asynchronously, where the -state you're expecting is gonna take a bit of time to be achieved. This is especially true -when you work on networking or file-system code. And this happens a lot when you write -integration (or end-to-end) test, less for unit-tests. - -The package =poll= is trying to tackle those use cases. We'll first take a look at the -main function, =WaitOn=, then how to write a ~Check~, using the ~Result~ type. - - -[[file:content/legacy/posts/2019-03-23-gotest-tools-poll.org][(Read more)]] - -* [[file:content/legacy/posts/2019-01-26-nix-run-alias.org][Nix run aliases]] -:PROPERTIES: -:ID: 2019-01-26-nix-run-alias.org -:RSS_TITLE: Nix run aliases -:RSS_PERMALINK: content/legacy/posts/2019-01-26-nix-run-alias.html -:PUBDATE: <2019-01-26 Sat 00:00> -:END: - - -I use [[https://nixos.org/][=NixOS=]] each and every day, everywhere. One really cool feature of =nix= is -=nix-shell= and more recently (with =nix= >= =2.0.0=), =nix run=. - -#+begin_src man -Usage: nix run <FLAGS>... <INSTALLABLES>... - -Summary: run a shell in which the specified packages are available. - -Flags: - --arg <NAME> <EXPR> argument to be passed to Nix functions - --argstr <NAME> <STRING> string-valued argument to be passed to Nix functions - -c, --command <COMMAND> <ARGS> command and arguments to be executed; defaults to 'bash' - -f, --file <FILE> evaluate FILE rather than the default - -i, --ignore-environment clear the entire environment (except those specified with --keep) - -I, --include <PATH> add a path to the list of locations used to look up <...> file names - -k, --keep <NAME> keep specified environment variable - -u, --unset <NAME> unset specified environment variable - -Examples: - - To start a shell providing GNU Hello from NixOS 17.03: - $ nix run -f channel:nixos-17.03 hello - - To start a shell providing youtube-dl from your 'nixpkgs' channel: - $ nix run nixpkgs.youtube-dl - - To run GNU Hello: - $ nix run nixpkgs.hello -c hello --greeting 'Hi everybody!' - - To run GNU Hello in a chroot store: - $ nix run --store ~/my-nix nixpkgs.hello -c hello - -Note: this program is EXPERIMENTAL and subject to change. -#+end_src - -As you can see from the =-h= summary, it makes it really easy to run a shell or a command -with some packages that are not in your main configuration. It will download the -package(s) if there are not available in the Nix store (=/nix/store/=). - -A few month ago I decided it would be a perfect use-case for command I do not run -often. My idea was, let's define =aliases= (in the shell) that would make a simple command -call, like =ncdu=, become =nix run nixpkgs.ncdu -c ndcu=. My /shell of choice/ is [[https://fishshell.com/][fish]], so -I decided to dig into the /language/ in order to implement that. - -The use case is the following : -- When I type =foo=, I want the command =foo= in package =bar= to be executed. -- I want to be able to pin a channel for the package — I'm using [[https://matthewbauer.us/][Matthew Bauer]] [[https://matthewbauer.us/blog/channel-changing.html][Channel - Changing with Nix]] setup for pin-pointing a given channel. - - -[[file:content/legacy/posts/2019-01-26-nix-run-alias.org][(Read more)]] - -* [[file:content/legacy/posts/2019-01-20-2018-year-review.org][2018 year review]] -:PROPERTIES: -:ID: 2019-01-20-2018-year-review.org -:RSS_TITLE: 2018 year review -:RSS_PERMALINK: content/legacy/posts/2019-01-20-2018-year-review.html -:PUBDATE: <2019-01-20 Sun 00:00> -:END: - - -Here is my review of 2018, the first of its kind, hopefully not the last 👼. I saw -some[fn:1] /2018[fn:2] reviews/[fn:3] articles[fn:4] in my Feedly feed and I thought it -would be a good idea to write my own too. - -I'll try in the next year — maybe month if I ever want to do monthly reviews — to automate -some of it ; using the beloved =org-mode=. - -[fn:1] [[https://punchagan.muse-amuse.in/blog/2018-in-review/][2018 in Review - Noetic Nought]] -[fn:2] [[https://medium.com/@buster/42-dig-deeper-e2278d1fe015][42 — Dig deeper – Buster Benson – Medium]] -[fn:3] [[https://jvns.ca/blog/2018/12/23/2018--year-in-review/][2018: Year in review - Julia Evans]] -[fn:4] [[https://writing.natwelch.com/post/685][Nat? Nat. Nat! | #685 2018 Year in Review]] - - -[[file:content/legacy/posts/2019-01-20-2018-year-review.org][(Read more)]] - -* [[file:content/legacy/posts/2018-09-18-gotest-tools-icmd.org][Golang testing — gotest.tools icmd]] -:PROPERTIES: -:ID: 2018-09-18-gotest-tools-icmd.org -:RSS_TITLE: Golang testing — gotest.tools icmd -:RSS_PERMALINK: content/legacy/posts/2018-09-18-gotest-tools-icmd.html -:PUBDATE: <2018-09-18 Tue 00:00> -:END: - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =icmd= package. - -#+BEGIN_QUOTE -Package icmd executes binaries and provides convenient assertions for testing the results. -#+END_QUOTE - -After file-system operations (seen in [[/posts/2018-09-14-gotest-tools-fs/][=fs=]]), another common use-case in tests is to - -[[file:content/legacy/posts/2018-09-18-gotest-tools-icmd.org][(Read more)]] - -* [[file:content/legacy/posts/2018-09-14-gotest-tools-fs.org][Golang testing — gotest.tools fs]] -:PROPERTIES: -:ID: 2018-09-14-gotest-tools-fs.org -:RSS_TITLE: Golang testing — gotest.tools fs -:RSS_PERMALINK: content/legacy/posts/2018-09-14-gotest-tools-fs.html -:PUBDATE: <2018-09-14 Fri 00:00> -:END: - - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =fs= package. - -#+BEGIN_QUOTE -Package fs provides tools for creating temporary files, and testing the contents and structure of a directory. -#+END_QUOTE - -This package is heavily using functional arguments (as we saw in [[/posts/2017-01-01-go-testing-functionnal-builders/][functional arguments for -wonderful builders]]). Functional arguments is, in a nutshell, a combinaison of two Go -features : /variadic/ functions (=...= operation in a function signature) and the fact -that =func= are /first class citizen/. This looks more or less like that. - -#+BEGIN_SRC go - type Config struct {} - - func MyFn(ops ...func(*Config)) *Config { - c := &Config{} // with default values - for _, op := range ops { - op(c) - } - return c - } - - // Calling it - conf := MyFn(withFoo, withBar("baz")) -#+END_SRC - -The =fs= package has too *main* purpose : - -1. create folders and files required for testing in a simple manner -2. compare two folders structure (and content) - - -[[file:content/legacy/posts/2018-09-14-gotest-tools-fs.org][(Read more)]] - -* [[file:content/legacy/posts/2018-09-06-gotest-tools-golden.org][Golang testing — gotest.tools golden]] -:PROPERTIES: -:ID: 2018-09-06-gotest-tools-golden.org -:RSS_TITLE: Golang testing — gotest.tools golden -:RSS_PERMALINK: content/legacy/posts/2018-09-06-gotest-tools-golden.html -:PUBDATE: <2018-09-06 Thu 00:00> -:END: - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =golden= package. This is a -[[/posts/2017-04-22-golang-testing-golden-file/][/quick follow-up/ on a previous =golden= post]], but focused on the =gotest.tools= -implementation. I'm gonna be quicker, please read that one if =golden= files is a new -concept for you. - -#+BEGIN_QUOTE -Package =golden= provides tools for comparing large mutli-line strings. - -Golden files are files in the =./testdata/= sub-directory of the package under test. -#+END_QUOTE - -In the previous article, we described the problem, and how to fix it by writing a small -helper. Well, that small helper is in =gotest.tools/golden= now, and it has a tiny bit -more features. - -One of the difference between the =gotest.tools= implementation and the previous post is -the flag name. In =gotest.tools/golden=, the flag is =-test.update-golden= (was just -=-test.update= before). Just as before, if the =-test.update-golden= flag is set then the -actual content is written to the golden file, before reading it and comparing. - -There is two ways to use the =golden= package: -- on it's own, using =golden.Assert= or =golden.AssertBytes= -- as a =cmp.Comparison=, with =golden.String= or =golden.Bytes= - - -[[file:content/legacy/posts/2018-09-06-gotest-tools-golden.org][(Read more)]] - -* [[file:content/legacy/posts/2018-09-01-gotest-tools-skip.org][Golang testing — gotest.tools skip]] -:PROPERTIES: -:ID: 2018-09-01-gotest-tools-skip.org -:RSS_TITLE: Golang testing — gotest.tools skip -:RSS_PERMALINK: content/legacy/posts/2018-09-01-gotest-tools-skip.html -:PUBDATE: <2018-09-01 Sat 00:00> -:END: - - -Let's continue the [[https://gotest.tools][=gotest.tools=]] serie, this time with the =skip= package. This is a -really simple one so this should be quick. - -#+BEGIN_QUOTE -=skip= provides functions for skipping a test and printing the source code of the -condition used to skip the test. -#+END_QUOTE - -The package consists of only one function : =If=. The idea comes mainly from -[[https://github.com/docker/docker][=docker/docker=]] integration test suite, where we wanted to skip some test (or test suites) -given different context. By context I mean things like the system we are running on -(=Windows=, =Linux=, …) or the capabilities of the running kernel or node (is =apparmor= -available or not on the current machine). - -This =If= method takes a =testing.T= pointer and either a boolean, a function that -returns a boolean, *or* an expression. - -#+BEGIN_SRC go - // boolean - // --- SKIP: TestName (0.00s) - // skip.go:19: MissingFeature - var MissingFeature bool - skip.If(t, MissingFeature) - - // function - // --- SKIP: TestName (0.00s) - // skip.go:19: !IsExperimentalDaemon(dockerClient): daemon is not experimental - skip.If(t, IsExperimentalDaemon(dockerClient), "daemon is not experimental") - - // expression - // --- SKIP: TestName (0.00s) - // skip.go:19: apiVersion < version("v1.24") - skip.If(t, apiVersion < version("v1.24")) -#+END_SRC - -There is few elements to note though : - -- This package (as other parts of the =gotest.tools= packages), will try to look at source - files to display the expression used (same goes for =assert=). This is usually not a - problem because you run tests where the source code is. *However*, in the cases you - generate a test binary to be executed later (à-la =kubernetes= or other projects), this - can display a weird error message if the sources are not available… You shouldn't be - worried too much about it, but it's better if you know :) -- The main reason to use =skip.If= is mainly for new contributors to get in quickly, - *reducing potential friction of them running the tests on their environment*. The more - the tests are written in a way they explicitely declare their requirements (and skipped - if the environment does not meet those), the easier it makes contributors run your - tests. *But*, this also means, you should try to measure the skipped tests on your - continuous integration system to make sure you run all of them eventually… otherwise - it's dead code. /But more on that in later posts 😉/. - -That's all for today folks, told you that was going to be quick. - -[[file:content/legacy/posts/2018-09-01-gotest-tools-skip.org][(Read more)]] - -* [[file:content/legacy/posts/2018-08-16-gotest-tools-assertions.org][Golang testing — gotest.tools assertions]] -:PROPERTIES: -:ID: 2018-08-16-gotest-tools-assertions.org -:RSS_TITLE: Golang testing — gotest.tools assertions -:RSS_PERMALINK: content/legacy/posts/2018-08-16-gotest-tools-assertions.html -:PUBDATE: <2018-08-16 Thu 00:00> -:END: - - -Let's take a closer look at [[https://gotest.tools][=gotest.tools=]] assertions packages. This is mainly about =assert=, =assert/cmp= and -=assert/opt=. - -#+BEGIN_QUOTE -Package assert provides assertions for comparing expected values to actual values. When assertion fails a helpful error -message is printed. -#+END_QUOTE - -There is two main functions (=Assert= and =Check=) and some helpers (like =NilError=, …). They all take a =*testing.T= as -a first argument, pretty common across testing Go libraries. Let's dive into those ! - - -[[file:content/legacy/posts/2018-08-16-gotest-tools-assertions.org][(Read more)]] - -* [[file:content/legacy/posts/2018-07-28-gotest-tools-intro.org][Golang testing — gotest.tools introduction]] -:PROPERTIES: -:ID: 2018-07-28-gotest-tools-intro.org -:RSS_TITLE: Golang testing — gotest.tools introduction -:RSS_PERMALINK: content/legacy/posts/2018-07-28-gotest-tools-intro.html -:PUBDATE: <2018-07-28 Sat 00:00> -:END: - - -I already wrote 2 previous posts about golang and testing. It's something I care deeply -about and I wanted to continue writing about it. It took me a bit more time than I -thought, but getting back to it. Since the [[http://vincent.demeester.fr/posts/2017-04-22-golang-testing-golden-file/][last post]], Daniel Nephin and I worked (but -mainly Daniel 🤗) on bootstrapping a testing helper library. - -Let me introduce it to you this library : [[https://gotest.tools][=gotest.tools=]]. As described in the [[https://godoc.org/gotest.tools][godoc]] package comment, =gotest.tools= is a -collection of packages to augment =testing= and support common patterns. It's an enhanced and growing version of the -initial helpers we (the docker/moby maintainers) wrote initially in [[https://github.com/docker/docker][=docker/docker=]] repository. We are using in quite some -project here at [[https://github.com][Docker]]. - -There is a bunch of packages that will all have their own post (linked here when available) : - -- [[file:2018-08-16-gotest-tools-assertions.org][=assert=]] (with =assert/cmp= and =assert/opt=) that provides assertions for comparing expected values to actual values. -- =env= that provides functions to test code that read environment variable or the current working directory. -- [[file:2018-09-14-gotest-tools-fs.org][=fs=]] that provides tools for creating temporary files, and testing the contents and structure of a directory. -- [[file:2018-09-06-gotest-tools-golden.org][=golden=]] that provides tools for comparing large multi-line strings. -- [[file:2018-09-18-gotest-tools-icmd.org][=icmd=]] that executes binaries and provides convenient assertions for testing the results. -- [[file:2019-03-23-gotest-tools-poll.org][=poll=]] that provides tools for testing asynchronous code. -- [[file:2018-09-01-gotest-tools-skip.org][=skip=]] that provides functions for skipping a test and printing the source code of the condition used to skip the test. - -There is also experimental package, using the =x= notation (as the golang team uses, for example with =golang.org/x/sync=) : - -- =x/subtest= that provides a =TestContext= to subtests which handles cleanup and provides a =testing.TB= and =context.Context=. - -There is already some good =testing= helpers in the Go ecosystem : [[https://github.com/stretchr/testify][=testify=]], [[http://labix.org/gocheck][=gocheck=]], [[https://github.com/onsi/ginkgo][=ginkgo=]] and a lot more — so -why create a new one ? There is multiple reason for it, most of them can be seen in the following [[https://github.com/gotestyourself/gotest.tools/issues/49#issuecomment-362436026][GitHub issue]]. - -[[https://github.com/dnephin/][Daniel]] also wrote a very useful converter if your code base is currently using =testify= : =gty-migrate-from-testify=. - -#+BEGIN_SRC sh -$ go get -u gotest.tools/assert/cmd/gty-migrate-from-testify -# […] -$ go list \ - -f '{{.ImportPath}} {{if .XTestGoFiles}}{{"\n"}}{{.ImportPath}}_test{{end}}' \ - ./... | xargs gty-migrate-from-testify -#+END_SRC - -In the next post, let's dig into the assertion part of the library, package =assert= 👼. - -[[file:content/legacy/posts/2018-07-28-gotest-tools-intro.org][(Read more)]] - -* [[file:content/legacy/posts/2014-03-24-redesign-et-résolutions.org][Redesign et Résolutions]] -:PROPERTIES: -:ID: 2014-03-24-redesign-et-résolutions.org -:RSS_TITLE: Redesign et Résolutions -:RSS_PERMALINK: content/legacy/posts/2014-03-24-redesign-et-résolutions.html -:PUBDATE: <2014-03-24 Mon 00:00> -:END: - - -Un /tout petit/ post pour parler rapidement, entre autre, du redesign de -[[http://vincent.demeester.fr][vincent.demeester.fr]] et de mes -résolutions. - - -[[file:content/legacy/posts/2014-03-24-redesign-et-résolutions.org][(Read more)]] - -* [[file:content/legacy/posts/2013-10-12-podcasts.org][Podcasts]] -:PROPERTIES: -:ID: 2013-10-12-podcasts.org -:RSS_TITLE: Podcasts -:RSS_PERMALINK: content/legacy/posts/2013-10-12-podcasts.html -:PUBDATE: <2013-10-12 Sat 00:00> -:END: - - -#+BEGIN_QUOTE - Voici un petit billet présentant les différents podcast que j'écoute - plus ou moins régulièrement. -#+END_QUOTE - -J'écoute énormément de musique et de podcast ; je passe beaucoup de -temps avec des écouteurs sur la tête ou la chaine hifi en route. Les -podcasts ont une grande place. Voici une liste plus ou moins bien triés -de ceux auxquels je suis souscrit et/ou que j'écoute en ce moment. Je -tiendrais peut-être ce post à jour ou en créerait un nouveau sinon :-). - - -[[file:content/legacy/posts/2013-10-12-podcasts.org][(Read more)]] - -* [[file:content/legacy/posts/2013-09-08-maven-tmpfs.org][Maven Tmpfs]] -:PROPERTIES: -:ID: 2013-09-08-maven-tmpfs.org -:RSS_TITLE: Maven Tmpfs -:RSS_PERMALINK: content/legacy/posts/2013-09-08-maven-tmpfs.html -:PUBDATE: <2013-09-08 Sun 00:00> -:END: - - -Je suis un utilisateur convaincu de [[http://maven.apache.org/][maven]], malgré ces défauts, le -moto *"Convention over configuration"* me va vraiment bien. Que ce soit -au boulot ou à la maison, j'ai plus d'ordinateurs équipés de ssd (ou de -mémoire flash) que de disque traditionnel (mécanique ?). Pour augmenter -un peu la durée de vie de ces disques SSD, j'ai cherché à savoir comment -/déporter/ le /build/ de maven (qui, pour rappel, se passe dans le -dossier =target/=) hors du SSD ; ici ce sera dans le dossier =/tmp/= qui -est monté en mémoire (merci =tmpfs=), mais on peut imaginer déporter ça -sur un autre disque, etc.. Après quelques recherches j'ai trouvés -quelques inspirations. - -#+BEGIN_QUOTE - *Limitations* - - Dans la solution présentée ci-dessous les principales limitations sont - les suivantes (que j'essaierais de diminuer au fil du temp ;P) : - - 1. Il est nécessaire de modifier le pom.xml du projet ; cela ne - s'appliquera donc pas à tous les projets maven sans modification du - pom.xml. - 2. Cela ne fonctionne que sur une plateforme qui support les liens - symboliques (Linux, Mac OS X, et autre UNIX). - 3. Cela ne fonctionne qu'avec Java 7 ou plus. - 4. Si vous utilisez m2e, il va gentillement gueuler et c'est moche ; pour résoudre le - problème, il faut faire un tour vers [[http://wiki.eclipse.org/M2E_plugin_execution_not_covered][M2E plugin execution not covered]]. -#+END_QUOTE - -Pour [[http://maven.apache.org/][maven]], le dossier =target/= vient de la propriété -=project.build.directory=. Dans la théorie, il suffirait de modifier -(dans =$HOME/.m2/settings.xml=) cette propriété et le tour serait jouer. -Malheuresement ce n'est pas possible, =project.build.directory= est une -propriété interne et n'est, à priori, pas modifiable. - -Notre souhait est le suivant : - -1. Le build doit se faire dans =/tmp/m2/=, ce qui pour un projet se - traduit par =/tmp/m2/${groupId}:${artifactId}=. -2. Le dossier =target/= dans les sources est un lien symbolique vers le - dossier dans =/tmp/m2/= -3. On passe par un *profile* qui n'est *pas actif* par défaut (pour ne - pas faire chier le monde) mais *activable via une propriété* (maven - nous permet de le faire et c'est cool =^_^=). La propriété utilisée - sera =external.build.root=. - -Le code ci-dessous est repris directement de mon inspiration[fn:1]. Il -s'occupe de créer le dossier =${groupId}:${artifactId}= dans -=external.build.root= et de faire le lien dans le dossier courant. - -#+begin_src xml -<project> - <!-- […] --> - <profiles> - <profile> - <id>external-build-dir</id> - <activation> - <activeByDefault>false</activeByDefault> - <property> - <name>external.build.root</name> - </property> - </activation> - <build> - <plugins> - <plugin> - <groupId>com.alexecollins.maven.plugin</groupId> - <artifactId>script-maven-plugin</artifactId> - <version>1.0.0</version> - <executions> - <execution> - <id>prep-work-tree</id> - <goals> - <goal>execute</goal> - </goals> - <phase>initialize</phase> - <configuration> - <script> - import java.nio.file.* - def dir = - "${external.build.root}/${project.groupId}:${project.artifactId}" - println "using Maven dir ${dir}" - def dirPath = Paths.get(dir) - if (!Files.exists(dirPath)) { - Files.createDirectories(dirPath) - } - def target = Paths.get("${project.build.directory}") - if (!Files.exists(target)) { - Files.createSymbolicLink(target, dirPath) - }</script> - </configuration> - </execution> - <execution> - <id>drop-symlink</id> - <goals> - <goal>execute</goal> - </goals> - <phase>clean</phase> - <configuration> - <script> - import java.nio.file.* - def target = Paths.get("${project.build.directory}") - if (Files.isSymbolicLink(target)) { - Files.delete(target) - } - </script> - </configuration> - </execution> - </executions> - <dependencies> - <dependency> - <groupId>org.codehaus.groovy</groupId> - <artifactId>groovy</artifactId> - <version>1.8.6</version> - </dependency> - </dependencies> - <configuration> - <language>groovy</language> - </configuration> - </plugin> - </plugins> - </build> - </profile> - </profiles> - <!-- […] --> -</project> -#+end_src - -Ainsi, il suffit ensuite d'avoir quelques choses du genre dans son -=$HOME/.m2/settings.xml= pour que les builds qui ont ce profil se -/build/ dans =/tmp/m2/=. On peut aussi ne rien avoir dans -=$HOME/.m2/settings.xml= et utilise =-Dexternal.build.root=/tmp/m2/= -avec la commande =mvn=. - -#+begin_src xml -<settings> - <!-- […] --> - <profiles> - <profile> - <id>build-in-ramfs</id> - <properties> - <external.build.root>/tmp/m2/</external.build.root> - </properties> - </profile> - </profiles> - <activeProfiles> - <activeProfile>build-in-ramfs</activeProfile> - </activeProfiles> - <!-- […] --> -</settings> -#+end_src - - -[fn:1] [[http://elehack.net/writings/programming/maven-target-in-tmpfs][PuttingMaven build directories out-of-tree]] par [[http://elehack.net/][Michal Ekstrand]] - -[[file:content/legacy/posts/2013-09-08-maven-tmpfs.org][(Read more)]] - -* [[file:content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel.org][Gollum comme Wiki personnel]] -:PROPERTIES: -:ID: 2012-12-16-gollum-comme-wiki-personnel.org -:RSS_TITLE: Gollum comme Wiki personnel -:RSS_PERMALINK: content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel.html -:PUBDATE: <2012-12-16 Sun 00:00> -:END: - - -Il y a environ 4 mois j'ai eu un accident de vélo ; un traumatisme -crânien, des brulures sur la face, quelques points de sutures, un doigt -cassé et une hernie discale m'ont cloué (et me clou encore) plus que -d'habitude sur ma chaise de bureau. Le bon côté des choses, c'est que -cela m'a permit de me poser et de réfléchir une bonne façon d'être -efficace et organiser, au travail et à la maison :-). - -Une des principales /action/ que j'ai pris est d'utiliser un wiki local -et synchronisé sur /tout/ mes PCs. Le /format/ wiki est assez adapté à -une prise de note et à la création de contenu plus complet (comme des -[[http://shortbrain.org][articles]] ou de la documentation pour des -projets en cours). Les conditions étaient les suivantes : - -- Facilité de mise en place. -- Pas de base de données. -- /Merging/ facile ([[http://git-scm.com][git]] /rules my world/). -- [[http://daringfireball.net/projects/markdown/][Markdown]] comme - syntaxe, car utilisé à peu près partout (blogs, articles, READMEs, - documentations). -- Éditable à partir d'une interface web ou de mon éditeur favoris. - -L'outil qui remplit presque toutes ces conditions s'appelle -[[https://github.com/github/gollum][gollum]]. C'est un moteur wiki, -écris en ruby, qui se base sur un repository -[[http://git-scm.com][git]]. Il est développer par l'équipe de -[[http://github.com][Github]] et c'est celui qui est utilisé par les -pages wiki là-bas. Il permet d'utiliser à peu près n'importe quel -syntaxe (dont -[[https://github.com/github/github-flavored-markdown][github-markdown]] -qui est assez proche de celle de -[[http://johnmacfarlane.net/pandoc][pandoc]]). Par ailleurs, comme il se -base sur [[http://git-scm.com][git]], les points /"pas de base de -données"/, /"merging facile"/ et /"éditable également à partir de mon -éditeur favoris"/ sont toutes remplies. - -Avec [[https://github.com/github/gollum][Gollum]] vous avez un wiki -markdown décentralisé, éditable via une interface web ou via votre -éditeur favoris. - - -[[file:content/legacy/posts/2012-12-16-gollum-comme-wiki-personnel.org][(Read more)]] - -* [[file:content/legacy/posts/2012-07-23-maven-release-gitflow.org][Maven Release Gitflow]] -:PROPERTIES: -:ID: 2012-07-23-maven-release-gitflow.org -:RSS_TITLE: Maven Release Gitflow -:RSS_PERMALINK: content/legacy/posts/2012-07-23-maven-release-gitflow.html -:PUBDATE: <2012-07-23 Mon 00:00> -:END: - - -I like a lot the [[http://nvie.com/posts/a-successful-git-branching-model/][gitflow]] way of managing project. When working on maven project, there is -few great plugins that helps to get the work done. One of them is [[http://maven.apache.org/plugins/maven-release-plugin][maven-release-plugin]]. - -Inspired on this [[https://gist.github.com/1043970][gist]], I've come -with a cool way of doing things (let say we want to release a 0.1 -version of an artifact) : - - -[[file:content/legacy/posts/2012-07-23-maven-release-gitflow.org][(Read more)]] - -* [[file:content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler.org][Jekyll Forman Guard Bundler]] -:PROPERTIES: -:ID: 2012-05-13-jekyll-foreman-guard-bundler.org -:RSS_TITLE: Jekyll Forman Guard Bundler -:RSS_PERMALINK: content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler.html -:PUBDATE: <2012-05-13 Sun 00:00> -:END: - - -This post is a quick "How did I setup my Jekyll environnement ?". We are -going all the tools that are quite awesome in Ruby. - - -[[file:content/legacy/posts/2012-05-13-jekyll-foreman-guard-bundler.org][(Read more)]] - -* [[file:content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror.org][Gitolite quick and dirty mirror]] -:PROPERTIES: -:ID: 2012-05-08-gitolite-quick-and-dirty-mirror.org -:RSS_TITLE: Gitolite quick and dirty mirror -:RSS_PERMALINK: content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror.html -:PUBDATE: <2012-05-08 Tue 00:00> -:END: - - -I'm running a gitolite _instance_ on my personal server to manage my repositories -(personnal, private or public) ; and I am quickly going to share with you how I setup a -_quick and dirty_ mirror feature. - -First, I am using **gitolite 3**. The mirroring we are going to setup is not the -_supported_ [[http://sitaramc.github.com/gitolite/mirroring.html][mirroring *built-in*]]. We are going to implement a simplier way to set mirror -thing : - -1. Write a custom gitolite command ; the idea is to be able to write ~git-config~ stuff. -2. Write a hook that take a specific ~git-config~ (let say ~mirror.url~) and do a simple - mirroring. - - -[[file:content/legacy/posts/2012-05-08-gitolite-quick-and-dirty-mirror.org][(Read more)]] - -* [[file:content/legacy/posts/2012-05-07-reinit-and-jekyll.org][Reinit and Jekyll]] -:PROPERTIES: -:ID: 2012-05-07-reinit-and-jekyll.org -:RSS_TITLE: Reinit and Jekyll -:RSS_PERMALINK: content/legacy/posts/2012-05-07-reinit-and-jekyll.html -:PUBDATE: <2012-05-07 Mon 00:00> -:END: - - -Two weeks ago, my /online/ personal server has been attacked and, -somehow, died. I'm in the process of re-installation of it but I'm going -to hardened a bit the security on it. Anyway, this crash meant that -every piece of site I maintain has been down. That's why I moved this -/identity site/ on the github pages, using a CNAME ; That way I can -crash as much as I want my server(s), this page should still be up for a -while. - -And I'm switching on Jekyll for this website as It is supported by -Github page, easy to use and easy to deploy elsewhere (if one day I want -to move from Github). - -The rest of the post is going to be used as a /sandbox/ post to test the -site styles. - -#+BEGIN_QUOTE - This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, - consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. - Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. - - Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse - id sem consectetuer libero luctus adipiscing. -#+END_QUOTE - - -[[file:content/legacy/posts/2012-05-07-reinit-and-jekyll.org][(Read more)]] - diff --git a/www/vincent.demeester.fr/content/legacy/posts/quick-kubernetes-provisionning.org.draft b/www/vincent.demeester.fr/content/legacy/posts/quick-kubernetes-provisionning.org.draft @@ -1,5 +0,0 @@ -#+TITLE: Quickly provision Kubernetes -#+SUBTITLE: Experiment with different tools to see what is the most efficient way to provision a multi-node kubernetes cluster -#+SETUPFILE: ../templates/post.org - -* TODO Introduction diff --git a/www/vincent.demeester.fr/content/linux/luks-key-sdcard.org b/www/vincent.demeester.fr/content/linux/luks-key-sdcard.org @@ -1,112 +0,0 @@ -#+title: Automatically unlock an luks encrypted partiiton with an SDCard -#+subtitle: … or a USB card. -#+date: <2022-06-23 Thu> -#+filetages: #home nixos cryptsetup -#+SETUPFILE: ../../templates/2022.org - -I am booting my work laptop (NixOS on a Thinkpad) from a LUKS-encrypted volume. I also do -have another "laptop" (used as a build/server) that is LUKS-encrypted. So far, I've been -using a passphrase I type on boot. It's more than fine for my laptop, but it means it's a -bit trickier for my other machine. I need to remove from its slot below my desk, type it -and re-put it in the slot. This mean it's a bit harder to do upgrade and reboot without -any input from me. - -For convenience, I want an SD card's LUKS volume to unlock and mount when the machine -boots, rather than me needing to unlock and mount it each time. - -There is a bunch of articles about this, like [[https://possiblelossofprecision.net/?p=300][this one]]. Or slightly related [[https://kyau.net/wiki/ArchLinux:LUKS][these]] [[https://neilzone.co.uk/2021/07/auto-unlocking-a-luks-volume-on-an-sd-card-on-boot-with-debian-11-bullseye][ones]]. I -am using NixOS however, and it is actually making things relatively straightforward. The -closer article to what I was looking for is [[https://medium.com/@geis/using-a-raw-usb-device-to-unlock-a-luks-volume-on-nixos-193406ee7474][this one]] as well as the [[https://nixos.wiki/wiki/Full_Disk_Encryption][NixOS wiki entry]] on -full disk encryption. - -The idea is relatively simple : we are going to use a key file (hidden or not in a -partition) to unlock a luks encrypted — with a fallback on passphrase (in case the medium -is not there). There is 3 main steps : -- creating the key file and storing it somewhere -- add the key to a slot in the luks encrypted partition -- configuring NixOS to use it - -* Creating a keyfile and storing it - -Creating a key file is very simple. If we are to use a file, we can just do the following: - -#+begin_src bash -$ dd if=/dev/urandom of=hdd.key bs=4096 count=1 -#+end_src - -I have two key to generate, one for =aomi= and one for =naruhodo= - -#+begin_src bash -$ dd if=/dev/random of=naruhodo.key.bin bs=1 count=4096 -4096+0 records in -4096+0 records out -4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00947718 s, 432 kB/s - -$ dd if=/dev/random of=aomi.key.bin bs=1 count=4096 -4096+0 records in -4096+0 records out -4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00985101 s, 416 kB/s -#+end_src - -What we are going to do here is, to hide the key inside a sdcard or a usb stick. The idea -is to use the first or the last few blocks to hide the key. - -#+begin_src bash -# This writes the aomi key to the "head" of sda (a sdcard) -$ sudo dd if=sync/aomi.key.bin of=/dev/sda bs=1 count=4096 -# This writes the naruhodo key to the "tail" of sdb (a usb card) -# The offset has to be computed from the usb key size -$ sudo dd if=sync/naruhodo.key.bin of=/dev/sdb bs=1 count=4096 seek=30992883712 -#+end_src - -* Add the key to a slot - -This is probably the easiest step of all, this is just about running the following. - -#+begin_src bash -$ cryptsetup luksAddKey $LUKS_DEVICE $KEY -#+end_src - -The only /trick/ to it is : you have to do this "offline", a.k.a. when the partition in -locked (and thus not mounted, …). Either you do this when you are installing the operating -system (and it's straightforward), or you need to boot your laptop/desktop with a livecd -(that also then has access to the key). - -* NixOS configuration - -This is where NixOS helps greatly, we have just a few things to write, and NixOS will make -sure all is correctly setup (the initramfs, …). - -#+begin_src nix -# For aomi, without offset -boot.initrd.luks.devices = { - root = { - device = "/dev/disk/by-uuid/{UUID}"; - preLVM = true; - allowDiscards = true; - keyFile = "/dev/disk/by-id/{DISKID}"; - keyFileSize = 4096; - fallbackToPassword = true; - }; -}; -# For narudoho, with offset -boot.initrd.luks.devices = { - root = { - device = "/dev/disk/by-uuid/{UUID}"; - preLVM = true; - allowDiscards = true; - keyFile = "/dev/disk/by-id/{DISKID}"; - keyFileOffset = 30992883712; - keyFileSize = 4096; - fallbackToPassword = true; - }; -}; -#+end_src - -Now, we are a =nixos-rebuild= away from being able to boot a NixOS on a encrypted file -system, without having to type the password *if we have the correct medium* inserted in -the machine. - -/Of course, this means that the "unlock" medium becomes precious and important *not to* -loose. If you go on vacation for example, you should definitely remove any of those medium -and hide them (or bring them with you)./ diff --git a/www/vincent.demeester.fr/content/linux/nixos.org b/www/vincent.demeester.fr/content/linux/nixos.org @@ -1,8 +0,0 @@ -#+title: NixOS -#+subtitle: A reproductible, declarative and reliable Linux operating system. - -[[https://nixos.org/][NixOS]] is a Linux distribution with a unique approach to package and configuration -management. Built on top of the [[file:nix.org][Nix]] package manager, it is completely declarative, makes -upgrading systems reliable, and has many other [[https://nixos.org/features.html][advantages]]. - -Most of my infrastructure is on NixOS. diff --git a/www/vincent.demeester.fr/content/sandbox.org b/www/vincent.demeester.fr/content/sandbox.org @@ -1,457 +0,0 @@ -#+TITLE: Emacs org-mode sandbox -#+SUBTITLE: A Clean and Comfort Stylesheet -#+SETUPFILE: ../templates/2022.org - -#+BEGIN_abstract - -This article serves as a complete demonstration for my [[file:notes.css][org.css]], a simple and -clean stylesheet for org-exported HTML file. You may switch between the default -style provided by Emacs Org mode, i.e., styles specified in the variable -=org-html-style-default= and my customized stylesheet using the button at the -top left corner. - -#+END_abstract - -#+TOC: headlines 2 - -Hello ~world~ vs =world= 🙃 - -* Demo -:PROPERTIES: -:CUSTOM_ID: sec:demo -:END: -<2015-11-09 Mon 14:41> - -#+BEGIN_QUOTE - -[[http://orgmode.org/][Org mode]] is for keeping notes, maintaining TODO lists, planning projects, -and authoring documents with a fast and effective /plain-text/ system -cite:dominik2003-org. - -#+END_QUOTE - - -We use [[https://en.wikipedia.org/wiki/Lorem_ipsum][Lorem ipsum]] text to demonstrate all elements you would expect to see in -the org-exported HTML pages. Note however that the =.title=, =.subtitle= and -=#postamble= element are not included in this section. - -** TODO Title with TODO -SCHEDULED: <2022-05-07 Sat> - -** DONE Title with DONE -DEADLINE: <2022-05-07 Sat> - -Some inactive timestamps - -[2019-02-20 Wed 12:03] With time ! - -Let's write some stuff between the two ! - -[2019-02-20 Wed] Without time - -Maybe also some *active* timestamps - -<2022-05-07 Sat> Without time as well - -** [#A] Title with Priority - -** Title with Tag :tag0:tag1: - -** Miscellaneous - -#+TOC: headlines 2 local - -*** Table - -#+CAPTION: Table Caption -| \(N\) | \(N^2\) | \(N^3\) | \(N^4\) | \(\sqrt n\) | \(\sqrt[4]N\) | -|-------+---------+---------+---------+-----------+-----------------| -| 1 | 1 | 1 | 1 | 1 | 1 | -| 2 | 4 | 8 | 16 | 1.4142 | 1.1892 | -| 3 | 9 | 27 | 81 | 1.7321 | 1.3161 | -|-------+---------+---------+---------+-----------+-----------------| -#+TBLFM: $2=$1^2::$3=$1^3::$4=$1^4::$5=sqrt($1)::$6=sqrt(sqrt(($1))) - -*** List - -**** The ordered list - -1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. -2. Donec et massa sit amet ligula maximus feugiat. -3. Morbi consequat orci et tincidunt sagittis. - -**** Unordered list - -- Aliquam non metus nec elit pellentesque scelerisque. -- In accumsan nunc ac orci varius hendrerit. -- Suspendisse non eros eu nisi finibus maximus. - -**** Unordered checked list [1/3] - -- [X] Aliquam non metus nec elit pellentesque scelerisque. -- [ ] In accumsan nunc ac orci varius hendrerit. -- [ ] Suspendisse non eros eu nisi finibus maximus. - -**** Definition list - -#+BEGIN_aside -This is a side note. If collection is a string, item must also be a string, and is -compared using =strings.Contains()=. If collection is a Map, contains will succeed if item -is a key in the map. -#+END_aside - -- Lorem ipsum :: dolor sit amet, consectetur adipiscing elit. Mauris laoreet - sollicitudin venenatis. Duis sed consequat dolor. -- Etiam feugiat :: pharetra sapien et semper. Nunc ornare lacus sit amet massa - auctor, vitae aliquam eros interdum. Mauris arcu ante, imperdiet vel purus - ac, bibendum faucibus diam. Ut blandit nec mi at ultricies. Donec eget - mattis nisl. In sed nibh felis. Cras quis convallis orci. -- Sed aliquam :: odio sed faucibus aliquam, arcu augue elementum justo, ut - vulputate ligula sem in augue. Maecenas ante felis, pellentesque auctor - semper non, eleifend quis ante. Fusce enim orci, suscipit ac dapibus et, - fermentum eu tortor. Duis in facilisis ante, quis faucibus dolor. Etiam - maximus lorem quis accumsan vehicula. - -**** Drawers - -Still outside the drawer - -:generic: -This is inside the drawer. -:END: - -And an update 😉 - -:update: -This is an update :) -:END: - -After the drawer. - -:Note: -This is a note -:END: -:Info: -This is an info -:END: -:Tip: -This is a tip -:END: -:Warning: -This is a warning -:END: -*** Picture - -#+CAPTION: Demo Picture with Caption -#+ATTR_HTML: :class shadow -[[file:./images/sandbox/pic-demo.png]] - -And a really wide picture. - -#+CAPTION: A really long picture -#+ATTR_HTML: :width 100% -[[file:./images/sandbox/long-img.png]] - -*** Math - -\begin{align} -\mathcal{F}(a) &= \frac{1}{2\pi i}\oint_\gamma \frac{f(z)}{z - a}\,dz\\ -\int_D (\nabla\cdot \mathcal{F})\,dV &=\int_{\partial D}\mathcal{F}\cdot n\, dS -\end{align} - -* Org-mode links :emacs: - -** TODO Host dependent link - -- grep:foo:~/src/github.com/vdemeester -- rg:foo:~/src/github.com/vdemeester - -** Github links - -- gh:vdemeester/ape -- [[gh:knative/build-pipeline#123][A super PR here]] -- gh:knative/build-pipeline#123 - -** ~man~ - -- [[man:tmux][tmux]] -- [[man:git][git]] - -- [[man:git-commit][Manpage for git-commit]] -- [[https://orgmode.org/manual/store_002dlink-protocol.html][The Org Manual: store-link protocol]] - -** Others - -- tag:foo - -- [[git:~/src/github.com/vdemeester/ape/README.md::v0.2.0]] - -* Org-babel - -** ~emacs-lisp~ - -#+begin_src emacs-lisp :exports both :results value drawer -(message "foo is bar") -#+end_src - -#+RESULTS: -:results: -foo is bar -:end: - -** ~go~ - -#+begin_src go :imports '("fmt") :exports both :results value drawer - fmt.Println("Hello, 世界") -#+end_src - -#+RESULTS: -:results: -Hello, 世界 -:end: - -** ~http~ - -#+BEGIN_SRC http :pretty -POST http://httpbin.org/post -Content-Type: application/json - -{ - "key": "value" -} -#+END_SRC - -#+RESULTS: -:results: -{ - "url": "http://httpbin.org/post", - "json": { - "key": "value" - }, - "headers": { - "User-Agent": "curl/7.35.0", - "Host": "httpbin.org", - "Content-Type": "application/json", - "Content-Length": "18", - "Accept": "*/*" - }, - "form": {}, - "files": {}, - "data": "{ \"key\": \"value\"}", - "args": {} -} -:end: - -** ~rust~ - -#+begin_src rust :exports both :results value drawer - fn main() { - let greetings = ["Hello", "Hola", "Bonjour", - "Ciao", "こんにちは", "안녕하세요", - "Cześć", "Olá", "Здравствуйте", - "chào bạn", "您好"]; - - for (num, greeting) in greetings.iter().enumerate() { - print!("{} : ", greeting); - match num { - 0 => println!("This code is editable and runnable!"), - 1 => println!("Este código es editable y ejecutable!"), - 2 => println!("Ce code est modifiable et exécutable!"), - 3 => println!("Questo codice è modificabile ed eseguibile!"), - 4 => println!("このコードは編集して実行出来ます!"), - 5 => println!("여기에서 코드를 수정하고 실행할 수 있습니다!"), - 6 => println!("Ten kod można edytować oraz uruchomić!"), - 7 => println!("Esse código é editável e executável!"), - 8 => println!("Этот код можно отредактировать и запустить!"), - 9 => println!("Bạn có thể edit và run code trực tiếp!"), - 10 => println!("这段代码是可以编辑并且能够运行的!"), - _ => {}, - } - } - } -#+end_src - -#+RESULTS: -:results: -Hello : This code is editable and runnable! -Hola : Este código es editable y ejecutable! -Bonjour : Ce code est modifiable et exécutable! -Ciao : Questo codice è modificabile ed eseguibile! -こんにちは : このコードは編集して実行出来ます! -안녕하세요 : 여기에서 코드를 수정하고 실행할 수 있습니다! -Cześć : Ten kod można edytować oraz uruchomić! -Olá : Esse código é editável e executável! -Здравствуйте : Этот код можно отредактировать и запустить! -chào bạn : Bạn có thể edit và run code trực tiếp! -您好 : 这段代码是可以编辑并且能够运行的! -:end: - -** ~typescript~ - -*** Execute with node.js - -#+BEGIN_SRC typescript :exports both :results value drawer -module Greeting { - export class Hello { - constructor(private text : string) { - } - say() :void{ - console.log(this.text); - } - } -} - -var hello : Greeting.Hello = new Greeting.Hello("Hello, World!"); -hello.say(); -#+END_src - -#+RESULTS: -:results: -Hello, World! -:end: - -*** Transpile - -You can see transpile results by specifying ":wrap SRC js" header argument. - -#+Begin_SRC typescript :exports both :wrap SRC js :results value drawer -module Greeting { - export class Hello { - constructor(private text : string) { - } - say() :void{ - consonle.log(this.text); - } - } -} - -var hello : Greeting.Hello = new Greeting.Hello("Hello, World!"); -hello.say(); -#+END_SRC - -#+RESULTS: -:results: -#+BEGIN_SRC js -var Greeting; -(function (Greeting) { - var Hello = (function () { - function Hello(text) { - this.text = text; - } - Hello.prototype.say = function () { - console.log(this.text); - }; - return Hello; - })(); - Greeting.Hello = Hello; -})(Greeting || (Greeting = {})); -var hello = new Greeting.Hello("Hello, World!"); -hello.say(); -#+END_SRC -:end: - -** Ditaa - -Let's try something with ~ditaa~ - -#+begin_src ditaa :file ./images/sandbox/some_filename.png - +-----------+ +---------+ - | PLC | | | - | Network +<------>+ PLC +<---=---------+ - | cRED | | c707 | | - +-----------+ +----+----+ | - ^ | - | | - | +----------------|-----------------+ - | | | | - v v v v - +----------+ +----+--+--+ +-------+---+ +-----+-----+ Windows clients - | | | | | | | | +----+ +----+ - | Database +<----->+ Shared +<---->+ Executive +<-=-->+ Operator +<---->|cYEL| . . .|cYEL| - | c707 | | Memory | | c707 | | Server | | | | | - +--+----+--+ |{d} cGRE | +------+----+ | c707 | +----+ +----+ - ^ ^ +----------+ ^ +-------+---+ - | | | - | +--------=--------------------------+ - v - +--------+--------+ - | | - | Millwide System | -------- Data --------- - | cBLU | --=----- Signals ---=-- - +-----------------+ -#+end_src - -#+RESULTS: -[[file:./images/sandbox/some_filename.png]] - - -** Graphviz - -** References and labels ! - -foo is bar - -#+BEGIN_SRC emacs-lisp -l "<ref:%s>" -(save-excursion ;; <ref:foo> - (message "this is baz") - (goto-char (point-min)) ;; <ref:bar> -#+END_SRC - -In line [[(foo)]] we remember the current position. [[(bar)][Line (bar)]] jumps to -point-min. - -#+BEGIN_SRC emacs-lisp -n -r -(save-excursion (ref:sc) - (message "this is sparta") - (goto-char (point-min)) (ref:jump) -#+END_SRC - -In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]] jumps to point-min. - - -* Counsel - -/this is italic/ -_this should be underlined_ - -* Known Issues -:PROPERTIES: -:CUSTOM_ID: sec:known-issues -:END: - -The citation exporter, =ox-bibtex=, does NOT work seamlessly. As of =Org-mode -8.3.2=, I have the following issues. - -** +Dangling Element+ :solved: -:PROPERTIES: -:CUSTOM_ID: sec:dangling-element -:END: - -The lisp function =insert-file-contents= used in =ox-bibtex= does not move point -and insertion-marker to the end of inserted text (I'm not sure it is a bug or an -intention). The result is that the citation is a dangling table not included in -the bibliography div. - -The expected result is - -#+BEGIN_SRC html -<div id="bibliography"> - <h2>Bibliography</h2> - <table> - <!-- Citation content goes here --> - </table> -</div> -#+END_SRC - -But we got - -#+BEGIN_SRC html -<div id="bibliography"> - <h2>Bibliography</h2> -</div> -<table> -<!-- Citation content goes here --> -</table> -#+END_SRC - -Unless a patch is submitted, we may need to manually adjust this weird result. diff --git a/www/vincent.demeester.fr/content/sitemap.org b/www/vincent.demeester.fr/content/sitemap.org @@ -1,13 +0,0 @@ -#+TITLE: Sitemap - -- [[file:index.org][Hi, I'm Vincent Demeester]] -- [[file:sandbox.org][Emacs org-mode sandbox]] -- [[file:about.org][About me]] -- linux - - [[file:linux/nixos.org][NixOS]] - - [[file:linux/luks-key-sdcard.org][Automatically unlock an luks encrypted partiiton with an SDCard]] -- tekton - - [[file:tekton/index.org][Tekton]] -- 2022 - - [[file:2022/digital-garden.org][A Digital Garden you say…]] - - [[file:2022/random.org][Random thoughts after 2 years]]- \ No newline at end of file diff --git a/www/vincent.demeester.fr/content/tekton/index.org b/www/vincent.demeester.fr/content/tekton/index.org @@ -1,5 +0,0 @@ -#+title: Tekton -#+subtitle: Cloud Native CI/CD -#+SETUPFILE: ../../templates/tekton.org - -Foo is bar diff --git a/www/vincent.demeester.fr/css/2022.css b/www/vincent.demeester.fr/css/2022.css @@ -1,611 +0,0 @@ -/* - 2022.css is based on new.css (see https://newcss.net/) - with very small personal adjustements. -*/ -:root { - ---font-sans: sans-serif; - ---font-mono: monospace; - ---tx-1: #000000; - ---tx-2: #1A1A1A; - ---tx-3: #666666; - ---tx-4: #999999; - ---bg-1: #FFFFFF; - ---bg-2: #F6F8FA; - ---bg-3: #E5E7EB; - ---lk-1: #0070F3; - ---lk-2: #0366D6; - ---lk-tx: #FFFFFF; - ---ac-1: #79FFE1; - ---ac-tx: #0C4047; - - --content-box-padding: 0.5rem; - --aside-width: 12.5rem; -} - -@media (prefers-color-scheme: dark) { - :root { - ---tx-1: #ffffff; - ---tx-2: #eeeeee; - ---tx-3: #cccccc; - ---tx-4: #aaaaaa; - ---bg-1: #000000; - ---bg-2: #111111; - ---bg-3: #222222; - ---lk-1: #3291FF; - ---lk-2: #0070F3; - ---lk-tx: #FFFFFF; - ---ac-1: #7928CA; - ---ac-tx: #FFFFFF; - } -} - -* { - /* Reset margins and padding */ - margin: 0; - padding: 0; -} - -address, -area, -article, -aside, -audio, -blockquote, -datalist, -details, -dl, -fieldset, -figure, -form, -input, -iframe, -img, -meter, -nav, -ol, -optgroup, -option, -output, -p, -pre, -progress, -ruby, -section, -table, -textarea, -ul, -video { - /* Margins for most elements */ - margin-bottom: 1rem; -} - -html,input,select,button { - /* Set body font family and some finicky elements */ - font-family: var(---font-sans); -} - -body { - /* Center body in page */ - margin: 0 auto; - max-width: 70rem; - padding: 2rem; - border-radius: 6px; - overflow-x: hidden; - word-break: break-word; - overflow-wrap: break-word; - background: var(---bg-1); - - /* Main body text */ - color: var(---tx-2); - font-size: 1.03rem; - line-height: 1.5; -} - -::selection { - /* Set background color for selected text */ - background: var(---ac-1); - color: var(---ac-tx); -} - -h1,h2,h3,h4,h5,h6 { - line-height: 1; - color: var(---tx-1); - padding-top: .875rem; -} - -h1, -h2, -h3 { - color: var(---tx-1); - padding-bottom: 2px; - margin-bottom: 8px; - border-bottom: 1px solid var(---bg-2); -} - -h4, -h5, -h6 { - margin-bottom: .3rem; -} - -h1 { - font-size: 2.25rem; -} - -h2 { - font-size: 1.85rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: 1rem; -} - -h6 { - font-size: .875rem; -} - -a { - color: var(---lk-1); -} - -a:hover { - color: var(---lk-2); -} - -abbr:hover { - /* Set the '?' cursor while hovering an abbreviation */ - cursor: help; -} - -blockquote { - padding: 1.5rem; - background: var(---bg-2); - border-left: 5px solid var(---bg-3); -} - -abbr { - cursor: help; -} - -blockquote *:last-child { - padding-bottom: 0; - margin-bottom: 0; -} - -header { - background: var(---bg-2); - border-bottom: 1px solid var(---bg-3); - padding: 1rem 1.5rem; - - /* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */ - - margin: -2rem calc(0px - (50vw - 50%)) 2rem; - - /* Shorthand for: - - margin-top: -2rem; - margin-bottom: 2rem; - - margin-left: calc(0px - (50vw - 50%)); - margin-right: calc(0px - (50vw - 50%)); */ - - padding-left: calc(50vw - 50%); - padding-right: calc(50vw - 50%); -} - -header img#sitelogo { - margin-bottom: 0; - margin-right: 1em; -} - -header h1, -header h2, -header h3 { - padding-bottom: 0; - border-bottom: 0; -} - -header > *:first-child { - margin-top: 0; - padding-top: 0; -} - -header > *:last-child { - margin-bottom: 0; -} - -a button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - font-size: 1rem; - display: inline-block; - padding: 6px 12px; - text-align: center; - text-decoration: none; - white-space: nowrap; - background: var(---lk-1); - color: var(---lk-tx); - border: 0; - border-radius: 4px; - box-sizing: border-box; - cursor: pointer; - color: var(---lk-tx); -} - -a button[disabled], -button[disabled], -input[type="submit"][disabled], -input[type="reset"][disabled], -input[type="button"][disabled] { - cursor: default; - opacity: .5; - - /* Set the [X] cursor while hovering a disabled link */ - cursor: not-allowed; -} - -.button:focus, -.button:hover, -button:focus, -button:hover, -input[type="submit"]:focus, -input[type="submit"]:hover, -input[type="reset"]:focus, -input[type="reset"]:hover, -input[type="button"]:focus, -input[type="button"]:hover { - background: var(---lk-2); -} - -code, -pre, -kbd, -samp { - /* Set the font family for monospaced elements */ - font-family: var(---font-mono); -} - -code, -samp, -kbd, -pre { - /* The main preformatted style. This is changed slightly across different cases. */ - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - padding: 3px 6px; -} - -kbd { - /* Makes the kbd element look like a keyboard key */ - border-bottom: 3px solid var(---bg-3); -} - -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; -} - -pre.src { - position: relative; -} -pre.src:before { - /*display: none;*/ - position: absolute; - background-color: var(---bg-3); - /*color: #f3f4f4;*/ - top: 0; - right: 0; - padding: 0.2rem 0.5rem; -} - -pre code { - /* When <code> is in a <pre>, reset it's formatting to blend in */ - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -code pre { - /* When <pre> is in a <code>, reset it's formatting to blend in */ - display: inline; - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -details { - /* Make the <details> look more "clickable" */ - padding: .6rem 1rem; - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -summary { - /* Makes the <summary> look more like a "clickable" link with the pointer cursor */ - cursor: pointer; - font-weight: bold; -} - -details[open] { - /* Adjust the <details> padding while open */ - padding-bottom: .75rem; -} - -details[open] summary { - /* Adjust the <details> padding while open */ - margin-bottom: 6px; -} - -details[open]>*:last-child { - /* Resets the bottom margin of the last element in the <details> while <details> is opened. This prevents double margins/paddings. */ - margin-bottom: 0; -} - -dt { - font-weight: bold; -} - -dd::before { - /* Add an arrow to data table definitions */ - content: '→ '; -} - -hr { - /* Reset the border of the <hr> separator, then set a better line */ - border: 0; - border-bottom: 1px solid var(---bg-3); - margin: 1rem auto; -} - -fieldset { - margin-top: 1rem; - padding: 2rem; - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -legend { - padding: auto .5rem; -} - -table { - /* border-collapse sets the table's elements to share borders, rather than floating as separate "boxes". */ - border-collapse: collapse; - width: 100% -} - -td, -th { - border: 1px solid var(---bg-3); - text-align: left; - padding: .5rem; -} - -th { - background: var(---bg-2); -} - -tr:nth-child(even) { - /* Set every other cell slightly darker. Improves readability. */ - background: var(---bg-2); -} - -table caption { - font-weight: bold; - margin-bottom: .5rem; -} - -textarea { - /* Don't let the <textarea> extend off the screen naturally or when dragged by the user */ - max-width: 100%; -} - -ol, -ul { - /* Replace the browser default padding */ - padding-left: 2rem; -} - -li { - margin-top: .4rem; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -mark { - padding: 3px 6px; - background: var(---ac-1); - color: var(---ac-tx); -} - -textarea, -select, -input { - padding: 6px 12px; - margin-bottom: .5rem; - background: var(---bg-2); - color: var(---tx-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; -} - -img { - max-width: 100%; -} - -aside { - --aside-offset: 1rem; - --aside-offset-lineheight: 1.5rem; - background-color: var(---bg-2); - padding: calc(var(--content-box-padding) * 0.5) calc(var(--content-box-padding) * 2); - padding-top: 1em; - margin-bottom: 0em; - float: right; - width: var(--aside-width); - font-size: 0.9rem; - line-height: 1.25rem; - border: 1px solid var(--bg-3); -} - -aside code { - background: var(---bg-3); - border: 1px solid var(---bg-4); -} - -figure figcaption { - text-align: center; - color: var(---tx-2); - font-style: italic; - margin: 0 2rem; -} - -footer { - text-align: center; - color: var(---tx-4); -} - -footer a { - color: var(---tx-3); -} - -section img { - display: block; - margin-left: auto; - margin-right: auto; -} - -section img.shadow { - box-shadow: 0 28px 50px rgba(0,0,0,0.16); -} - -div.drawer:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 4.4rem; - width: 1px; - background-color: #555; -} - -div.drawer { - display: flex; - padding: 0; - margin: 1rem; - padding-top: 1rem; - position: relative; - color: #555; -} - -div.drawer h6 { - box-sizing: border-box; - font-style: italic; - flex: 0 0 5rem; - margin:0; - padding:0; - align-self: center; - text-align: right; - padding-right: 1.2rem; -} - -div.drawer.info:before { - background-color: #00529B; -} -div.drawer.info { - color: #00529B; -} - -div.drawer.note:before { - background-color: #9F6000; -} -div.drawer.note { - color: #9F6000; -} -div.drawer.tip:before { - background-color: #4F8A10; -} -div.drawer.tip { - color: #4F8A10; -} -div.drawer.warning:before { - background-color: #D8000C; -} -div.drawer.warning { - color: #D8000C; -} -div.drawer.results:before { - background-color: black; -} -div.drawer.results { - font-family:monospace,monospace; - font-family: var(---font-mono); - color: black; - width: 100% !important; -} -div.drawer.results p { - display: block; - unicode-bidi: embed; - white-space: pre; - margin-top: 0; -} -div.drawer.results pre { - background-color: inherit; - border: 0; -} -div.drawer.results pre.src:before { - background-color: #eee; - color: #555; -} - -.tag { - font-family:var(---font-mono); - font-size: 1rem; -} -.tag span { - padding:.3em; - float:right; - margin-right:.5em; - border:1px solid #bbb; - border-radius:3px; - background-clip:padding-box; - color:#333; - background-color:#eee; - line-height:1rem; -} - -.todo { - font-family: monospace; color: red; -} -.done { - font-family: monospace; color: green; -} -.priority { font-family: monospace; color: orange; } -.timestamp { color: #bebebe; } -.timestamp-kwd { color: #5f9ea0; } -.underline { text-decoration: underline; } diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-Black.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-Black.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-Bold.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-Bold.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-BoldItalic.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-BoldItalic.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-HeavyItalic.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-HeavyItalic.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-Italic.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-Italic.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-Light.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-Light.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-LightItalic.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-LightItalic.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/fonts/Merriweather-Regular.otf b/www/vincent.demeester.fr/css/fonts/Merriweather-Regular.otf Binary files differ. diff --git a/www/vincent.demeester.fr/css/new.css b/www/vincent.demeester.fr/css/new.css @@ -1,605 +0,0 @@ -:root { - ---font-sans: sans-serif; - ---font-mono: monospace; - ---tx-1: #000000; - ---tx-2: #1A1A1A; - ---tx-3: #666666; - ---tx-4: #999999; - ---bg-1: #FFFFFF; - ---bg-2: #F6F8FA; - ---bg-3: #E5E7EB; - ---lk-1: #0070F3; - ---lk-2: #0366D6; - ---lk-tx: #FFFFFF; - ---ac-1: #79FFE1; - ---ac-tx: #0C4047; - - --content-box-padding: 0.5rem; - --aside-width: 12.5rem; -} - -@media (prefers-color-scheme: dark) { - :root { - ---tx-1: #ffffff; - ---tx-2: #eeeeee; - ---tx-3: #cccccc; - ---tx-4: #aaaaaa; - ---bg-1: #000000; - ---bg-2: #111111; - ---bg-3: #222222; - ---lk-1: #3291FF; - ---lk-2: #0070F3; - ---lk-tx: #FFFFFF; - ---ac-1: #7928CA; - ---ac-tx: #FFFFFF; - } -} - -* { - /* Reset margins and padding */ - margin: 0; - padding: 0; -} - -address, -area, -article, -aside, -audio, -blockquote, -datalist, -details, -dl, -fieldset, -figure, -form, -input, -iframe, -img, -meter, -nav, -ol, -optgroup, -option, -output, -p, -pre, -progress, -ruby, -section, -table, -textarea, -ul, -video { - /* Margins for most elements */ - margin-bottom: 1rem; -} - -html,input,select,button { - /* Set body font family and some finicky elements */ - font-family: var(---font-sans); -} - -body { - /* Center body in page */ - margin: 0 auto; - max-width: 70rem; - padding: 2rem; - border-radius: 6px; - overflow-x: hidden; - word-break: break-word; - overflow-wrap: break-word; - background: var(---bg-1); - - /* Main body text */ - color: var(---tx-2); - font-size: 1.03rem; - line-height: 1.5; -} - -::selection { - /* Set background color for selected text */ - background: var(---ac-1); - color: var(---ac-tx); -} - -h1,h2,h3,h4,h5,h6 { - line-height: 1; - color: var(---tx-1); - padding-top: .875rem; -} - -h1, -h2, -h3 { - color: var(---tx-1); - padding-bottom: 2px; - margin-bottom: 8px; - border-bottom: 1px solid var(---bg-2); -} - -h4, -h5, -h6 { - margin-bottom: .3rem; -} - -h1 { - font-size: 2.25rem; -} - -h2 { - font-size: 1.85rem; -} - -h3 { - font-size: 1.55rem; -} - -h4 { - font-size: 1.25rem; -} - -h5 { - font-size: 1rem; -} - -h6 { - font-size: .875rem; -} - -a { - color: var(---lk-1); -} - -a:hover { - color: var(---lk-2); -} - -abbr:hover { - /* Set the '?' cursor while hovering an abbreviation */ - cursor: help; -} - -blockquote { - padding: 1.5rem; - background: var(---bg-2); - border-left: 5px solid var(---bg-3); -} - -abbr { - cursor: help; -} - -blockquote *:last-child { - padding-bottom: 0; - margin-bottom: 0; -} - -header { - background: var(---bg-2); - border-bottom: 1px solid var(---bg-3); - padding: 1rem 1.5rem; - - /* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */ - - margin: -2rem calc(0px - (50vw - 50%)) 2rem; - - /* Shorthand for: - - margin-top: -2rem; - margin-bottom: 2rem; - - margin-left: calc(0px - (50vw - 50%)); - margin-right: calc(0px - (50vw - 50%)); */ - - padding-left: calc(50vw - 50%); - padding-right: calc(50vw - 50%); -} - -header img#sitelogo { - margin-bottom: 0; - margin-right: 1em; -} - -header h1, -header h2, -header h3 { - padding-bottom: 0; - border-bottom: 0; -} - -header > *:first-child { - margin-top: 0; - padding-top: 0; -} - -header > *:last-child { - margin-bottom: 0; -} - -main header { - background: var(---bg-3); -} - -a button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - font-size: 1rem; - display: inline-block; - padding: 6px 12px; - text-align: center; - text-decoration: none; - white-space: nowrap; - background: var(---lk-1); - color: var(---lk-tx); - border: 0; - border-radius: 4px; - box-sizing: border-box; - cursor: pointer; - color: var(---lk-tx); -} - -a button[disabled], -button[disabled], -input[type="submit"][disabled], -input[type="reset"][disabled], -input[type="button"][disabled] { - cursor: default; - opacity: .5; - - /* Set the [X] cursor while hovering a disabled link */ - cursor: not-allowed; -} - -.button:focus, -.button:hover, -button:focus, -button:hover, -input[type="submit"]:focus, -input[type="submit"]:hover, -input[type="reset"]:focus, -input[type="reset"]:hover, -input[type="button"]:focus, -input[type="button"]:hover { - background: var(---lk-2); -} - -code, -pre, -kbd, -samp { - /* Set the font family for monospaced elements */ - font-family: var(---font-mono); -} - -code, -samp, -kbd, -pre { - /* The main preformatted style. This is changed slightly across different cases. */ - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - padding: 3px 6px; -} - -kbd { - /* Makes the kbd element look like a keyboard key */ - border-bottom: 3px solid var(---bg-3); -} - -pre { - padding: 1rem 1.4rem; - max-width: 100%; - overflow: auto; -} - -pre.src { - position: relative; -} -pre.src:before { - /*display: none;*/ - position: absolute; - background-color: var(---bg-3); - /*color: #f3f4f4;*/ - top: 0; - right: 0; - padding: 0.2rem 0.5rem; -} - -pre code { - /* When <code> is in a <pre>, reset it's formatting to blend in */ - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -code pre { - /* When <pre> is in a <code>, reset it's formatting to blend in */ - display: inline; - background: inherit; - font-size: inherit; - color: inherit; - border: 0; - padding: 0; - margin: 0; -} - -details { - /* Make the <details> look more "clickable" */ - padding: .6rem 1rem; - background: var(---bg-2); - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -summary { - /* Makes the <summary> look more like a "clickable" link with the pointer cursor */ - cursor: pointer; - font-weight: bold; -} - -details[open] { - /* Adjust the <details> padding while open */ - padding-bottom: .75rem; -} - -details[open] summary { - /* Adjust the <details> padding while open */ - margin-bottom: 6px; -} - -details[open]>*:last-child { - /* Resets the bottom margin of the last element in the <details> while <details> is opened. This prevents double margins/paddings. */ - margin-bottom: 0; -} - -dt { - font-weight: bold; -} - -dd::before { - /* Add an arrow to data table definitions */ - content: '→ '; -} - -hr { - /* Reset the border of the <hr> separator, then set a better line */ - border: 0; - border-bottom: 1px solid var(---bg-3); - margin: 1rem auto; -} - -fieldset { - margin-top: 1rem; - padding: 2rem; - border: 1px solid var(---bg-3); - border-radius: 4px; -} - -legend { - padding: auto .5rem; -} - -table { - /* border-collapse sets the table's elements to share borders, rather than floating as separate "boxes". */ - border-collapse: collapse; - width: 100% -} - -td, -th { - border: 1px solid var(---bg-3); - text-align: left; - padding: .5rem; -} - -th { - background: var(---bg-2); -} - -tr:nth-child(even) { - /* Set every other cell slightly darker. Improves readability. */ - background: var(---bg-2); -} - -table caption { - font-weight: bold; - margin-bottom: .5rem; -} - -textarea { - /* Don't let the <textarea> extend off the screen naturally or when dragged by the user */ - max-width: 100%; -} - -ol, -ul { - /* Replace the browser default padding */ - padding-left: 2rem; -} - -li { - margin-top: .4rem; -} - -ul ul, -ol ul, -ul ol, -ol ol { - margin-bottom: 0; -} - -mark { - padding: 3px 6px; - background: var(---ac-1); - color: var(---ac-tx); -} - -textarea, -select, -input { - padding: 6px 12px; - margin-bottom: .5rem; - background: var(---bg-2); - color: var(---tx-2); - border: 1px solid var(---bg-3); - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; -} - -img { - max-width: 100%; -} - -aside { - --aside-offset: 1rem; - --aside-offset-lineheight: 1.5rem; - background-color: var(---bg-2); - padding: calc(var(--content-box-padding) * 0.5) calc(var(--content-box-padding) * 2); - padding-top: 1em; - margin-bottom: 0em; - float: right; - width: var(--aside-width); - font-size: 0.9rem; - line-height: 1.25rem; - border: 1px solid var(--bg-3); -} - -figure figcaption { - text-align: center; - color: var(---tx-2); - font-style: italic; - margin: 0 2rem; -} - -footer { - text-align: center; - color: var(---tx-4); -} - -footer a { - color: var(---tx-3); -} - -section img { - display: block; - margin-left: auto; - margin-right: auto; -} - -section img.shadow { - box-shadow: 0 28px 50px rgba(0,0,0,0.16); -} - -div.drawer:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 4.4rem; - width: 1px; - background-color: #555; -} - -div.drawer { - display: flex; - padding: 0; - margin: 1rem; - padding-top: 1rem; - position: relative; - color: #555; -} - -div.drawer h6 { - box-sizing: border-box; - font-style: italic; - flex: 0 0 5rem; - margin:0; - padding:0; - align-self: center; - text-align: right; - padding-right: 1.2rem; -} - -div.drawer.info:before { - background-color: #00529B; -} -div.drawer.info { - color: #00529B; -} - -div.drawer.note:before { - background-color: #9F6000; -} -div.drawer.note { - color: #9F6000; -} -div.drawer.tip:before { - background-color: #4F8A10; -} -div.drawer.tip { - color: #4F8A10; -} -div.drawer.warning:before { - background-color: #D8000C; -} -div.drawer.warning { - color: #D8000C; -} -div.drawer.results:before { - background-color: black; -} -div.drawer.results { - font-family:monospace,monospace; - font-family: var(---font-mono); - color: black; - width: 100% !important; -} -div.drawer.results p { - display: block; - unicode-bidi: embed; - white-space: pre; - margin-top: 0; -} -div.drawer.results pre { - background-color: inherit; - border: 0; -} -div.drawer.results pre.src:before { - background-color: #eee; - color: #555; -} - -.tag { - font-family:var(---font-mono); - font-size: 1rem; -} -.tag span { - padding:.3em; - float:right; - margin-right:.5em; - border:1px solid #bbb; - border-radius:3px; - background-clip:padding-box; - color:#333; - background-color:#eee; - line-height:1rem; -} - -.todo { - font-family: monospace; color: red; -} -.done { - font-family: monospace; color: green; -} -.priority { font-family: monospace; color: orange; } -.timestamp { color: #bebebe; } -.timestamp-kwd { color: #5f9ea0; } diff --git a/www/vincent.demeester.fr/css/site.css b/www/vincent.demeester.fr/css/site.css @@ -1,353 +0,0 @@ -@font-face { - font-family: "Merriweather"; - src: url("/css/fonts/Merriweather-Regular.otf") format("opentype"); -} -@font-face { - font-family: "Merriweather"; - font-weight: bold; - src: url("/css/fonts/Merriweather-Bold.otf") format("opentype"); -} -@font-face { - font-family: "Merriweather"; - font-weight: bold; - font-style: italic; - src: url("/css/fonts/Merriweather-BoldItalic.otf") format("opentype"); -} -@font-face { - font-family: "Merriweather"; - font-style: italic; - src: url("/css/fonts/Merriweather-Italic.otf") format("opentype"); -} -@font-face { - font-family: "Merriweather"; - font-weight: lighter; - font-style: italic; - src: url("/css/fonts/Merriweather-LightItalic.otf") format("opentype"); -} -@font-face { - font-family: "Merriweather"; - font-weight: lighter; - src: url("/css/fonts/Merriweather-Light.otf") format("opentype"); -} - -html{ - margin: 1rem 2rem; - font-size: 106.25%; - --body-vertical-margin: 1rem; - --body-horizontal-margin: 1rem; - --content-box-padding: 0.5rem; - --font-main: Georgia, sans-serif; - --font-mono: 'Ubuntu Mono','Fira Code','Deja Vu Sans Mono','Bitstream Vera Sans Mono','Source Code Pro','Courier New',monospace; - --font-quote: "Fresco", Georgia, serif; - --font-sans: Avenir Next, Avenir, system-ui, sans-serif; - --font-header: 'Merriweather','Linux Libertine','Georgia','Times',serif; - --figure-offset: 0; - --figcaption-padding: 0; - --aside-width: 12.5rem; - --column-gap: 2rem; - --padding: 1rem; -} - -body { - font-family: var(--font-main); - max-width: 70rem; - min-width: 30rem; - line-height: 1.4rem; - margin: 0 auto; -} - -p { - word-wrap: break-word; -} -body > header{ - margin-bottom: 4em; -} - -body > header nav { - float:right; -} - -body > header nav ul li { - display: inline-block; - list-style: none; - padding: 0 0.5rem; -} - -main { - font-size: 1.1rem; - font-family: var(--font-sans); -} - -div.index h1 { - font-family: "Merriweather", "Linux Libertine", "Georgia", "Times", serif; - font-size: 2rem; - line-height: 2rem; - font-weight: bolder; -} - -div.index h2 { - font-family: "Merriweather", "Linux Libertine", "Georgia", "Times", serif; - font-size: 1.5rem; - line-height: 2rem; -} - -nav#table-of-contents { - background: #f2f2f2; - padding: 0.2rem 1rem; - font-size: 90%; -} - -nav#table-of-contents h2 { - font-family: var(--font-sans); - font-weight: bold; - font-style: italic; -} - -nav#table-of-contents li { - list-style-type: square; -} - -nav#table-of-contents li a { - color: black; -} -nav#table-of-contents li a:hover { - color: #33f; - background-color: inherit; -} - -code { - background-color: #f3f4f4; - font-family: var(--font-mono); - padding: 0.1rem 0.3rem; - border: 1px solid #e1e1e1; - border-radius: 4px; -} - -blockquote code { - background-color: #999; - border-color: #666; - color: white; -} - -pre { - background-color: #f3f4f4; - font-family: var(--font-mono); - white-space: pre-wrap; - overflow: auto; - overflow-x: auto; - margin: 1.25rem calc(-1 * var(--content-box-padding)); - padding: var(--content-box-padding); - border: 1px solid #999; -} - -pre.src { - position: relative; -} - -pre.src:before { - /*display: none;*/ - position: absolute; - background-color: #999; - color: #f3f4f4; - top: 0; - right: 0; - padding: 0.2rem 0.5rem; -} - -aside { - --aside-offset: 1rem; - --aside-offset-lineheight: 1.5rem; - background-color: #f8f8f8; - padding: calc(var(--content-box-padding) * 0.5) calc(var(--content-box-padding) * 2); - float: right; - width: var(--aside-width); - font-size: 0.9rem; - line-height: 1.25rem; - border: 1px solid #ccc; -} - -a { text-decoration: none; color: #339; } -a:hover { color: #33f; background-color: #f6f6f6; } - -blockquote { - font-family: var(--font-quote); - text-rendering: optimizeLegibility; - line-height: 1.4; - font-style: italic; - background-color: #e0e0e0; - border-radius: 0.5em; - width: 90%; - margin: 1em auto; - padding: 0.2rem 1.2rem; -} - -h1, h2, h3, h4 { - font-family: var(--font-header); -} -main header h1 { - font-size: 300%; - line-height: 3.8rem; -} - -figure figcaption { - text-align: center; - color: #666; - font-style: italic; - margin: 0 2rem; -} - -footer { - text-align: center; - color: #999; -} - -footer a { - color: #666; -} - -section img { - display: block; - margin-left: auto; - margin-right: auto; -} - - -section img.shadow { - box-shadow: 0 28px 50px rgba(0,0,0,0.16); -} - -table { - margin:1em auto; - border-top:2px solid; - border-collapse:collapse -} -table,thead { - border-bottom:2px solid -} -table td+td,table th+th { - border-left:1px solid gray -} -table tr { - border-top:1px solid #d3d3d3 -} -td,th { - padding:.3em .6em; - vertical-align:middle -} - -.title { text-align: center; - margin-bottom: 1.5rem; } -.subtitle { - text-align: center; - font-size: medium; - font-weight: bold; - margin-top:0; - color: #999; -} - -div.drawer:before { - content: ""; - position: absolute; - top: 0; - bottom: 0; - left: 6.4rem; - width: 1px; - background-color: #555; -} - -div.drawer { - display: flex; - padding: 0; - margin: 1rem; - margin-left: -7rem; - position: relative; - color: #555; -} - -div.drawer h6 { - box-sizing: border-box; - font-style: italic; - flex: 0 0 7rem; - margin:0; - padding:0; - align-self: center; - text-align: right; - padding-right: 1.2rem; -} - -div.drawer.info:before { - background-color: #00529B; -} -div.drawer.info { - color: #00529B; -} - -div.drawer.note:before { - background-color: #9F6000; -} -div.drawer.note { - color: #9F6000; -} -div.drawer.tip:before { - background-color: #4F8A10; -} -div.drawer.tip { - color: #4F8A10; -} -div.drawer.warning:before { - background-color: #D8000C; -} -div.drawer.warning { - color: #D8000C; -} -div.drawer.results:before { - background-color: black; -} -div.drawer.results { - font-family:monospace,monospace; - font-family: var(--font-mono); - color: black; - width: 100% !important; -} -div.drawer.results p { - display: block; - unicode-bidi: embed; - white-space: pre; - margin-top: 0; -} -div.drawer.results pre { - background-color: inherit; - border: 0; -} -div.drawer.results pre.src:before { - background-color: #eee; - color: #555; -} - -.tag { - font-family:var(--font-mono); - font-size: 1rem; -} -.tag span { - padding:.3em; - float:right; - margin-right:.5em; - border:1px solid #bbb; - border-radius:3px; - background-clip:padding-box; - color:#333; - background-color:#eee; - line-height:1rem; -} - -.todo { font-family: monospace; color: red; } -.done { font-family: monospace; color: green; } -.priority { font-family: monospace; color: orange; } -.timestamp { color: #bebebe; } -.timestamp-kwd { color: #5f9ea0; } -.org-right { margin-left: auto; margin-right: 0px; text-align: right; } -.org-left { margin-left: 0px; margin-right: auto; text-align: left; } -.org-center { margin-left: auto; margin-right: auto; text-align: center; } -.underline { text-decoration: underline; } -#postamble p, #preamble p { font-size: 90%; margin: .2em; } -p.verse { margin-left: 3%; } diff --git a/www/vincent.demeester.fr/css/syntax.css b/www/vincent.demeester.fr/css/syntax.css @@ -1,280 +0,0 @@ -pre.src:hover:before { display: inline;} -/* Languages per Org manual */ -pre.src-asymptote:before { content: 'Asymptote'; } -pre.src-awk:before { content: 'Awk'; } -pre.src-C:before { content: 'C'; } -/* pre.src-C++ doesn't work in CSS */ -pre.src-clojure:before { content: 'Clojure'; } -pre.src-css:before { content: 'CSS'; } -pre.src-D:before { content: 'D'; } -pre.src-ditaa:before { content: 'ditaa'; } -pre.src-dot:before { content: 'Graphviz'; } -pre.src-calc:before { content: 'Emacs Calc'; } -pre.src-emacs-lisp:before { content: 'Emacs Lisp'; } -pre.src-fortran:before { content: 'Fortran'; } -pre.src-gnuplot:before { content: 'gnuplot'; } -pre.src-haskell:before { content: 'Haskell'; } -pre.src-hledger:before { content: 'hledger'; } -pre.src-java:before { content: 'Java'; } -pre.src-js:before { content: 'Javascript'; } -pre.src-latex:before { content: 'LaTeX'; } -pre.src-ledger:before { content: 'Ledger'; } -pre.src-lisp:before { content: 'Lisp'; } -pre.src-lilypond:before { content: 'Lilypond'; } -pre.src-lua:before { content: 'Lua'; } -pre.src-matlab:before { content: 'MATLAB'; } -pre.src-mscgen:before { content: 'Mscgen'; } -pre.src-ocaml:before { content: 'Objective Caml'; } -pre.src-octave:before { content: 'Octave'; } -pre.src-org:before { content: 'Org mode'; } -pre.src-oz:before { content: 'OZ'; } -pre.src-plantuml:before { content: 'Plantuml'; } -pre.src-processing:before { content: 'Processing.js'; } -pre.src-python:before { content: 'Python'; } -pre.src-R:before { content: 'R'; } -pre.src-ruby:before { content: 'Ruby'; } -pre.src-sass:before { content: 'Sass'; } -pre.src-scheme:before { content: 'Scheme'; } -pre.src-screen:before { content: 'Gnu Screen'; } -pre.src-sed:before { content: 'Sed'; } -pre.src-sh:before { content: 'shell'; } -pre.src-sql:before { content: 'SQL'; } -pre.src-sqlite:before { content: 'SQLite'; } -/* additional languages in org.el's org-babel-load-languages alist */ -pre.src-forth:before { content: 'Forth'; } -pre.src-io:before { content: 'IO'; } -pre.src-J:before { content: 'J'; } -pre.src-makefile:before { content: 'Makefile'; } -pre.src-maxima:before { content: 'Maxima'; } -pre.src-perl:before { content: 'Perl'; } -pre.src-picolisp:before { content: 'Pico Lisp'; } -pre.src-scala:before { content: 'Scala'; } -pre.src-shell:before { content: 'Shell Script'; } -pre.src-ebnf2ps:before { content: 'ebfn2ps'; } -/* additional language identifiers per \"defun org-babel-execute\" - in ob-*.el */ -pre.src-cpp:before { content: 'C++'; } -pre.src-abc:before { content: 'ABC'; } -pre.src-coq:before { content: 'Coq'; } -pre.src-groovy:before { content: 'Groovy'; } -/* additional language identifiers from org-babel-shell-names in - ob-shell.el: ob-shell is the only babel language using a lambda to put - the execution function name together. */ -pre.src-go:before { content: 'go'; } -pre.src-bash:before { content: 'bash'; } -pre.src-csh:before { content: 'csh'; } -pre.src-ash:before { content: 'ash'; } -pre.src-dash:before { content: 'dash'; } -pre.src-ksh:before { content: 'ksh'; } -pre.src-mksh:before { content: 'mksh'; } -pre.src-posh:before { content: 'posh'; } -/* Additional Emacs modes also supported by the LaTeX listings package */ -pre.src-ada:before { content: 'Ada'; } -pre.src-asm:before { content: 'Assembler'; } -pre.src-caml:before { content: 'Caml'; } -pre.src-delphi:before { content: 'Delphi'; } -pre.src-html:before { content: 'HTML'; } -pre.src-idl:before { content: 'IDL'; } -pre.src-mercury:before { content: 'Mercury'; } -pre.src-metapost:before { content: 'MetaPost'; } -pre.src-modula-2:before { content: 'Modula-2'; } -pre.src-pascal:before { content: 'Pascal'; } -pre.src-ps:before { content: 'PostScript'; } -pre.src-prolog:before { content: 'Prolog'; } -pre.src-simula:before { content: 'Simula'; } -pre.src-tcl:before { content: 'tcl'; } -pre.src-tex:before { content: 'TeX'; } -pre.src-plain-tex:before { content: 'Plain TeX'; } -pre.src-verilog:before { content: 'Verilog'; } -pre.src-vhdl:before { content: 'VHDL'; } -pre.src-xml:before { content: 'XML'; } -pre.src-nxml:before { content: 'XML'; } -pre.src-yaml:before { content: 'YAML'; } -pre.src-toml:before { content: 'TOML'; } -/* add a generic configuration mode; LaTeX export needs an additional - (add-to-list 'org-latex-listings-langs '(conf \" \")) in .emacs */ -pre.src-conf:before { content: 'Configuration File'; } - -table { border-collapse:collapse; } -caption.t-above { caption-side: top; } -caption.t-bottom { caption-side: bottom; } -td, th { vertical-align:top; } -th.org-right { text-align: center; } -th.org-left { text-align: center; } -th.org-center { text-align: center; } -td.org-right { text-align: right; } -td.org-left { text-align: left; } -td.org-center { text-align: center; } -dt { font-weight: bold; } -.footpara { display: inline; } -.footdef { margin-bottom: 1em; } -.figure { padding: 1em; } -.figure p { text-align: center; } -.inlinetask { - padding: 10px; - border: 2px solid gray; - margin: 10px; - background: #ffffcc; -} -#org-div-home-and-up - { text-align: right; font-size: 70%; white-space: nowrap; } -textarea { overflow-x: auto; } -.linenr { font-size: smaller } -.code-highlighted { background-color: #ffff00; } -.org-info-js_info-navigation { border-style: none; } -#org-info-js_console-label - { font-size: 10px; font-weight: bold; white-space: nowrap; } -.org-info-js_search-highlight - { background-color: #ffff00; color: #000000; font-weight: bold; } -.org-svg { width: 90%; } - -/****************************** - * Syntax highlighting - *** - * Source: https://github.com/fniessen/org-html-themes/blob/master/styles/bigblow/css/htmlize.css - ******************************/ -.org-bold { /* bold */ font-weight: bold; } -.org-bold-italic { /* bold-italic */ font-weight: bold; font-style: italic; } -.org-buffer-menu-buffer { /* buffer-menu-buffer */ font-weight: bold; } -.org-builtin { /* font-lock-builtin-face */ color: #7a378b; } -.org-button { /* button */ text-decoration: underline; } -.org-calendar-today { /* calendar-today */ text-decoration: underline; } -.org-change-log-acknowledgement { /* change-log-acknowledgement */ color: #b22222; } -.org-change-log-conditionals { /* change-log-conditionals */ color: #a0522d; } -.org-change-log-date { /* change-log-date */ color: #8b2252; } -.org-change-log-email { /* change-log-email */ color: #a0522d; } -.org-change-log-file { /* change-log-file */ color: #0000ff; } -.org-change-log-function { /* change-log-function */ color: #a0522d; } -.org-change-log-list { /* change-log-list */ color: #a020f0; } -.org-change-log-name { /* change-log-name */ color: #008b8b; } -.org-comint-highlight-input { /* comint-highlight-input */ font-weight: bold; } -.org-comint-highlight-prompt { /* comint-highlight-prompt */ color: #00008b; } -.org-comment { /* font-lock-comment-face */ color: #b22222; } -.org-comment-delimiter { /* font-lock-comment-delimiter-face */ color: #b22222; } -.org-completions-annotations { /* completions-annotations */ font-style: italic; } -.org-completions-common-part { /* completions-common-part */ color: #000000; background-color: #ffffff; } -.org-completions-first-difference { /* completions-first-difference */ font-weight: bold; } -.org-constant { /* font-lock-constant-face */ color: #008b8b; } -.org-diary { /* diary */ color: #ff0000; } -.org-diff-context { /* diff-context */ color: #7f7f7f; } -.org-diff-file-header { /* diff-file-header */ background-color: #b3b3b3; font-weight: bold; } -.org-diff-function { /* diff-function */ background-color: #cccccc; } -.org-diff-header { /* diff-header */ background-color: #cccccc; } -.org-diff-hunk-header { /* diff-hunk-header */ background-color: #cccccc; } -.org-diff-index { /* diff-index */ background-color: #b3b3b3; font-weight: bold; } -.org-diff-nonexistent { /* diff-nonexistent */ background-color: #b3b3b3; font-weight: bold; } -.org-diff-refine-change { /* diff-refine-change */ background-color: #d9d9d9; } -.org-dired-directory { /* dired-directory */ color: #0000ff; } -.org-dired-flagged { /* dired-flagged */ color: #ff0000; font-weight: bold; } -.org-dired-header { /* dired-header */ color: #228b22; } -.org-dired-ignored { /* dired-ignored */ color: #7f7f7f; } -.org-dired-mark { /* dired-mark */ color: #008b8b; } -.org-dired-marked { /* dired-marked */ color: #ff0000; font-weight: bold; } -.org-dired-perm-write { /* dired-perm-write */ color: #b22222; } -.org-dired-symlink { /* dired-symlink */ color: #a020f0; } -.org-dired-warning { /* dired-warning */ color: #ff0000; font-weight: bold; } -.org-doc { /* font-lock-doc-face */ color: #8b2252; } -.org-escape-glyph { /* escape-glyph */ color: #a52a2a; } -.org-file-name-shadow { /* file-name-shadow */ color: #7f7f7f; } -.org-flyspell-duplicate { /* flyspell-duplicate */ color: #cdad00; font-weight: bold; text-decoration: underline; } -.org-flyspell-incorrect { /* flyspell-incorrect */ color: #ff4500; font-weight: bold; text-decoration: underline; } -.org-fringe { /* fringe */ background-color: #f2f2f2; } -.org-function-name { /* font-lock-function-name-face */ color: #0000ff; } -.org-header-line { /* header-line */ color: #333333; background-color: #e5e5e5; } -.org-help-argument-name { /* help-argument-name */ font-style: italic; } -.org-highlight { /* highlight */ background-color: #b4eeb4; } -.org-holiday { /* holiday */ background-color: #ffc0cb; } -.org-isearch { /* isearch */ color: #b0e2ff; background-color: #cd00cd; } -.org-isearch-fail { /* isearch-fail */ background-color: #ffc1c1; } -.org-italic { /* italic */ font-style: italic; } -.org-keyword { /* font-lock-keyword-face */ color: #a020f0; } -.org-lazy-highlight { /* lazy-highlight */ background-color: #afeeee; } -.org-link { /* link */ color: #0000ff; text-decoration: underline; } -.org-link-visited { /* link-visited */ color: #8b008b; text-decoration: underline; } -.org-log-edit-header { /* log-edit-header */ color: #a020f0; } -.org-log-edit-summary { /* log-edit-summary */ color: #0000ff; } -.org-log-edit-unknown-header { /* log-edit-unknown-header */ color: #b22222; } -.org-match { /* match */ background-color: #ffff00; } -.org-next-error { /* next-error */ background-color: #eedc82; } -.org-nobreak-space { /* nobreak-space */ color: #a52a2a; text-decoration: underline; } -.org-org-archived { /* org-archived */ color: #7f7f7f; } -.org-org-block { /* org-block */ color: #7f7f7f; } -.org-org-block-begin-line { /* org-block-begin-line */ color: #b22222; } -.org-org-block-end-line { /* org-block-end-line */ color: #b22222; } -.org-org-checkbox { /* org-checkbox */ font-weight: bold; } -.org-org-checkbox-statistics-done { /* org-checkbox-statistics-done */ color: #228b22; font-weight: bold; } -.org-org-checkbox-statistics-todo { /* org-checkbox-statistics-todo */ color: #ff0000; font-weight: bold; } -.org-org-clock-overlay { /* org-clock-overlay */ background-color: #ffff00; } -.org-org-code { /* org-code */ color: #7f7f7f; } -.org-org-column { /* org-column */ background-color: #e5e5e5; } -.org-org-column-title { /* org-column-title */ background-color: #e5e5e5; font-weight: bold; text-decoration: underline; } -.org-org-date { /* org-date */ color: #a020f0; text-decoration: underline; } -.org-org-document-info { /* org-document-info */ color: #191970; } -.org-org-document-info-keyword { /* org-document-info-keyword */ color: #7f7f7f; } -.org-org-document-title { /* org-document-title */ color: #191970; font-size: 144%; font-weight: bold; } -.org-org-done { /* org-done */ color: #228b22; font-weight: bold; } -.org-org-drawer { /* org-drawer */ color: #0000ff; } -.org-org-ellipsis { /* org-ellipsis */ color: #b8860b; text-decoration: underline; } -.org-org-footnote { /* org-footnote */ color: #a020f0; text-decoration: underline; } -.org-org-formula { /* org-formula */ color: #b22222; } -.org-org-headline-done { /* org-headline-done */ color: #bc8f8f; } -.org-org-hide { /* org-hide */ color: #ffffff; } -.org-org-latex-and-export-specials { /* org-latex-and-export-specials */ color: #8b4513; } -.org-org-level-1 { /* org-level-1 */ color: #0000ff; } -.org-org-level-2 { /* org-level-2 */ color: #a0522d; } -.org-org-level-3 { /* org-level-3 */ color: #a020f0; } -.org-org-level-4 { /* org-level-4 */ color: #b22222; } -.org-org-level-5 { /* org-level-5 */ color: #228b22; } -.org-org-level-6 { /* org-level-6 */ color: #008b8b; } -.org-org-level-7 { /* org-level-7 */ color: #7a378b; } -.org-org-level-8 { /* org-level-8 */ color: #8b2252; } -.org-org-link { /* org-link */ color: #0000ff; text-decoration: underline; } -.org-org-meta-line { /* org-meta-line */ color: #b22222; } -.org-org-mode-line-clock { /* org-mode-line-clock */ color: #000000; background-color: #bfbfbf; } -.org-org-mode-line-clock-overrun { /* org-mode-line-clock-overrun */ color: #000000; background-color: #ff0000; } -.org-org-quote { /* org-quote */ color: #7f7f7f; } -.org-org-scheduled { /* org-scheduled */ color: #006400; } -.org-org-scheduled-previously { /* org-scheduled-previously */ color: #b22222; } -.org-org-scheduled-today { /* org-scheduled-today */ color: #006400; } -.org-org-sexp-date { /* org-sexp-date */ color: #a020f0; } -.org-org-special-keyword { /* org-special-keyword */ color: #a020f0; } -.org-org-table { /* org-table */ color: #0000ff; } -.org-org-tag { /* org-tag */ font-weight: bold; } -.org-org-target { /* org-target */ text-decoration: underline; } -.org-org-time-grid { /* org-time-grid */ color: #b8860b; } -.org-org-todo { /* org-todo */ color: #ff0000; font-weight: bold; } -.org-org-upcoming-deadline { /* org-upcoming-deadline */ color: #b22222; } -.org-org-verbatim { /* org-verbatim */ color: #7f7f7f; } -.org-org-verse { /* org-verse */ color: #7f7f7f; } -.org-org-warning { /* org-warning */ color: #ff0000; font-weight: bold; } -.org-outline-1 { /* outline-1 */ color: #0000ff; } -.org-outline-2 { /* outline-2 */ color: #a0522d; } -.org-outline-3 { /* outline-3 */ color: #a020f0; } -.org-outline-4 { /* outline-4 */ color: #b22222; } -.org-outline-5 { /* outline-5 */ color: #228b22; } -.org-outline-6 { /* outline-6 */ color: #008b8b; } -.org-outline-7 { /* outline-7 */ color: #7a378b; } -.org-outline-8 { /* outline-8 */ color: #8b2252; } -.org-preprocessor { /* font-lock-preprocessor-face */ color: #7a378b; } -.org-query-replace { /* query-replace */ color: #b0e2ff; background-color: #cd00cd; } -.org-regexp-grouping-backslash { /* font-lock-regexp-grouping-backslash */ font-weight: bold; } -.org-regexp-grouping-construct { /* font-lock-regexp-grouping-construct */ font-weight: bold; } -.org-region { /* region */ background-color: #eedc82; } -.org-secondary-selection { /* secondary-selection */ background-color: #ffff00; } -.org-shadow { /* shadow */ color: #7f7f7f; } -.org-show-paren-match { /* show-paren-match */ background-color: #40e0d0; } -.org-show-paren-mismatch { /* show-paren-mismatch */ color: #ffffff; background-color: #a020f0; } -.org-string { /* font-lock-string-face */ color: #8b2252; } -.org-tool-bar { /* tool-bar */ color: #000000; background-color: #bfbfbf; } -.org-tooltip { /* tooltip */ color: #000000; background-color: #ffffe0; } -.org-trailing-whitespace { /* trailing-whitespace */ background-color: #ff0000; } -.org-type { /* font-lock-type-face */ color: #228b22; } -.org-underline { /* underline */ text-decoration: underline; } -.org-variable-name { /* font-lock-variable-name-face */ color: #a0522d; } -.org-warning { /* font-lock-warning-face */ color: #ff0000; font-weight: bold; } -.org-widget-button { /* widget-button */ font-weight: bold; } -.org-widget-button-pressed { /* widget-button-pressed */ color: #ff0000; } -.org-widget-documentation { /* widget-documentation */ color: #006400; } -.org-widget-field { /* widget-field */ background-color: #d9d9d9; } -.org-widget-inactive { /* widget-inactive */ color: #7f7f7f; } -.org-widget-single-line-field { /* widget-single-line-field */ background-color: #d9d9d9; } diff --git a/www/vincent.demeester.fr/css/tekton.css b/www/vincent.demeester.fr/css/tekton.css @@ -1,3 +0,0 @@ -header { - background: #ed6a5a; -} diff --git a/www/vincent.demeester.fr/default.nix b/www/vincent.demeester.fr/default.nix @@ -1,6 +0,0 @@ -{ stdenv }: - -stdenv.mkDerivation { - name = "vincent.demeester.fr"; - src = ./.; -} diff --git a/www/vincent.demeester.fr/lib/publish-common.el b/www/vincent.demeester.fr/lib/publish-common.el @@ -1,294 +0,0 @@ -;;; publish-common.el --- Commons code for www publishing projects -*- lexical-binding: t; -*- -;; Author: Vincent Demeester <vincent@sbr.pm> - -;;; Commentary: -;; -;;; Code: -;; load org -(require 'org) -(require 'dash) -;; load org export functions -(require 'ox-publish) -(require 'ox-rss) -(require 'ox-html) -;; load org link functions -(require 'ol-man) -(require 'ol-git-link) -;; Those are mine -(require 'ol-github) -(require 'ol-gitlab) -(require 'org-attach) -;; load additional libraries -(require 'go-mode) -(require 'css-mode) -(require 'yaml-mode) -(require 'nix-mode) - -(require 's) - -(setq org-export-use-babel nil) -(setq org-link-abbrev-alist '(("att" . org-attach-expand-link))) - -;; setting to nil, avoids "Author: x" at the bottom -(setq org-export-with-section-numbers nil - org-export-with-smart-quotes t - org-export-with-toc nil) - -(defvar sbr-date-format "%b %d, %Y") - -(setq org-html-divs '((preamble "header" "top") - (content "main" "content") - (postamble "footer" "postamble")) - org-html-container-element "section" - org-html-metadata-timestamp-format sbr-date-format - org-html-checkbox-type 'unicode - org-html-html5-fancy t - org-html-doctype "html5" - org-html-htmlize-output-type 'css - org-html-htmlize-font-prefix "org-" - org-src-fontify-natively t - org-html-coding-system 'utf-8-unix) - -(defun sbr/org-export-format-drawer (name content) - "HTML export of drawer with NAME and CONTENT. -name is the name of the drawer, that will be used as class. -content is the content of the drawer" - (format "<div class='drawer %s'>\n<h6>%s</h6>\n%s</div>" - (downcase name) - (capitalize name) - content)) -(setq org-html-format-drawer-function 'sbr/org-export-format-drawer) - -(defun read-file (filePath) - "Return FILEPATH's file content." - (with-temp-buffer - (insert-file-contents filePath) - (buffer-string))) - -(defvar sbr-website-html-head - "<link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> -<meta name='viewport' content='width=device-width, initial-scale=1'> -<link rel='stylesheet' href='/css/2022.css' type='text/css'/> -<link rel='stylesheet' href='/css/syntax.css' type='text/css'/> -<link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' />") - -(defvar legacy-sbr-website-html-head - "<link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> -<meta name='viewport' content='width=device-width, initial-scale=1'> -<link rel='stylesheet' href='/css/new.css' type='text/css'/> -<link rel='stylesheet' href='/css/syntax.css' type='text/css'/> -<link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' />") - -(defun islegacy (file) - "Returns t if FILE is in the legacy folder" - (string-prefix-p "www/vincent.demeester.fr/content/legacy" - (file-relative-name file - (expand-file-name (locate-dominating-file default-directory ".git"))))) - -(defun sbr-website-html-preamble (plist) - "PLIST: An entry." - (cond ((islegacy (plist-get plist :input-file)) - ;; Legacy handling - ;; Skip adding subtitle to the post if :KEYWORDS don't have 'post' has a - ;; keyword - (when (string-match-p "post" (format "%s" (plist-get plist :keywords))) - (plist-put plist - :subtitle (format "Published on %s by %s." - (org-export-get-date plist sbr-date-format) - (car (plist-get plist :author))))) - (format "<nav style=\"background: yellow;\">This part of the website is \"archived\", it means it is \"stuck in time\" and won't be updated/up-to-date</nav> -<nav> -<img src=\"/images/favicon.ico\" id=\"sitelogo\"/> <a href='/'>home</a> / -<a href='/posts/'>posts</a> (<a href='/index.xml'>rss</a>) / -<a href='/articles/'>articles</a> / -<a href='https://dl.sbr.pm/'>files</a> / -<a href='/about/'>about</a></li> -</nav>") - ) - (t nil)) - ) - -(defvar sbr-website-html-postamble - "<footer> - <small><a href=\"/\" rel=\"history\">Index</a> • <a href=\"/sitemap.html\">Sitemap</a> • <a href=\"https://dl.sbr.pm/\">Files</a></small><br/> - <small class='questions'>Questions, comments ? Please use my <a href=\"https://lists.sr.ht/~vdemeester/public-inbox\">public inbox</a> by sending a plain-text email to <a href=\"mailto:~vdemeester/public-inbox@lists.sr.ht\">~vdemeester/public-inbox@lists.sr.ht</a>.</small><br/> - <small class='copyright'> - Content and design by Vincent Demeester - (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) - </small><br /> -</footer>") - -;; TODO: Move in about / colophon - -(defvar site-attachments - (regexp-opt '("jpg" "jpeg" "gif" "png" "svg" - "ico" "cur" "css" "js" "woff" "html" "pdf" "otf")) - "File types that are published as static files.") - -(defun sbr/org-sitemap-format-entry (entry style project) - "Format posts with author and published data in the index page. - -ENTRY: file-name -STYLE: -PROJECT: `posts in this case." - (cond ((not (directory-name-p entry)) - (format "%s — [[file:%s][%s]] - :PROPERTIES: - :PUBDATE: [%s] - :END:" - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)) - entry - (org-publish-find-title entry project) - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)))) - ((eq style 'tree) (file-name-nondirectory (directory-file-name entry))) - (t entry))) - -(defun sbr/org-publish-sitemap (title list) - "" - (concat "#+TITLE: " title "\n\n" - (org-list-to-subtree list))) - -(defun sbr/org-get-first-paragraph (file) - "Get string content of first paragraph of file." - (ignore-errors - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (show-all) - (let ((first-begin (progn - (org-forward-heading-same-level 1) - (next-line) - (point))) - (first-end (progn - (org-next-visible-heading 1) - (point)))) - (buffer-substring first-begin first-end))))) - -(defun sbr/org-rss-publish-to-rss (plist filename pub-dir) - "Prepare rss.org file before exporting." - (let* ((postsdir (plist-get plist :base-directory))) - (with-current-buffer (find-file filename) - (erase-buffer) - (insert "#+TITLE: Posts\n") - (insert "#+AUTHOR: Vincent Demeester\n") - (insert "#+OPTIONS: toc:nil\n") - (let* ((files-all - (reverse (directory-files "." nil - "[0-9-]+.*\\.org$"))) - (files (seq-subseq files-all 0 (min (length files-all) 30)))) - (message (format "foo: %s" filename)) - (dolist (post files) - (let* ((post-file post) - (post-title (org-publish-find-title post-file plist)) - (preview-str (sbr/org-get-first-paragraph post-file)) - (date (replace-regexp-in-string - "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)-.*" - "\\1" post))) - (insert (concat "* [[file:" postsdir "/" post "][" post-title "]]\n\n")) - (org-set-property "ID" post) - (org-set-property "RSS_TITLE" post-title) - ;; ox-rss prepends html-link-home to permalink - (org-set-property "RSS_PERMALINK" - (concat postsdir "/" - (file-name-sans-extension post) - ".html")) - (org-set-property - "PUBDATE" - (format-time-string - "<%Y-%m-%d %a %H:%M>" - (org-time-string-to-time - (replace-regexp-in-string - "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)-.*" - "\\1" post)))) - (insert preview-str) - (newline 1) - (insert (concat "[[file:" postsdir "/" post "][(Read more)]]\n\n")))) - (save-buffer)))) - (let ((user-mail-address "t") - (org-export-with-broken-links t) - (org-rss-use-entry-url-as-guid nil)) - (org-rss-publish-to-rss plist filename pub-dir))) - -(advice-add #'org-export-get-reference :override #'unpackaged/org-export-get-reference) - -(defun unpackaged/org-export-get-reference (datum info) - "Like `org-export-get-reference', except uses heading titles instead of random numbers." - (let ((cache (plist-get info :internal-references))) - (or (car (rassq datum cache)) - (let* ((crossrefs (plist-get info :crossrefs)) - (cells (org-export-search-cells datum)) - ;; Preserve any pre-existing association between - ;; a search cell and a reference, i.e., when some - ;; previously published document referenced a location - ;; within current file (see - ;; `org-publish-resolve-external-link'). - ;; - ;; However, there is no guarantee that search cells are - ;; unique, e.g., there might be duplicate custom ID or - ;; two headings with the same title in the file. - ;; - ;; As a consequence, before re-using any reference to - ;; an element or object, we check that it doesn't refer - ;; to a previous element or object. - (new (or (cl-some - (lambda (cell) - (let ((stored (cdr (assoc cell crossrefs)))) - (when stored - (let ((old (org-export-format-reference stored))) - (and (not (assoc old cache)) stored))))) - cells) - (when (org-element-property :raw-value datum) - ;; Heading with a title - (unpackaged/org-export-new-title-reference datum cache)) - ;; NOTE: This probably breaks some Org Export - ;; feature, but if it does what I need, fine. - (org-export-format-reference - (org-export-new-reference cache)))) - (reference-string new)) - ;; Cache contains both data already associated to - ;; a reference and in-use internal references, so as to make - ;; unique references. - (dolist (cell cells) (push (cons cell new) cache)) - ;; Retain a direct association between reference string and - ;; DATUM since (1) not every object or element can be given - ;; a search cell (2) it permits quick lookup. - (push (cons reference-string datum) cache) - (plist-put info :internal-references cache) - reference-string)))) - -(defun unpackaged/org-export-new-title-reference (datum cache) - "Return new reference for DATUM that is unique in CACHE." - (cl-macrolet ((inc-suffixf (place) - `(progn - (string-match (rx bos - (minimal-match (group (1+ anything))) - (optional "--" (group (1+ digit))) - eos) - ,place) - ;; HACK: `s1' instead of a gensym. - (-let* (((s1 suffix) (list (match-string 1 ,place) - (match-string 2 ,place))) - (suffix (if suffix - (string-to-number suffix) - 0))) - (setf ,place (format "%s--%s" s1 (cl-incf suffix))))))) - (let* ((title (org-element-property :raw-value datum)) - (ref (url-hexify-string (substring-no-properties title))) - (parent (org-element-property :parent datum))) - (while (--any (equal ref (car it)) - cache) - ;; Title not unique: make it so. - (if parent - ;; Append ancestor title. - (setf title (concat (org-element-property :raw-value parent) - "--" title) - ref (url-hexify-string (substring-no-properties title)) - parent (org-element-property :parent parent)) - ;; No more ancestors: add and increment a number. - (inc-suffixf ref))) - ref))) - -(provide 'publish-common) -;;; publish-common.el ends here diff --git a/www/vincent.demeester.fr/lib/publish.el b/www/vincent.demeester.fr/lib/publish.el @@ -1,173 +0,0 @@ -;;; publish.el --- Publish www project -*- lexical-binding: t; -*- -;; Author: Vincent Demeester <vincent@sbr.pm> - -;;; Commentary: -;; This script will convert the org-mode files in this directory into -;; html. - -;;; Code: -(require 'package) -(require 'publish-common) - -(setq org-publish-project-alist - `(("content" - :base-directory "content" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public" - :exclude ,(regexp-opt '("README.org" "draft" "legacy" "articles")) - :index-filename "index.org" - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :with-timestamps t - :sitemap-filename "sitemap.org" - :sitemap-title "Sitemap" - ;; :sitemap-format-entry sbr/org-sitemap-format-entry - :sitemap-style tree - :sitemap-sort-files anti-chronologically - :html-head-include-default-style nil - :html-head-include-scripts nil - ;; :sitemap-function sbr/org-publish-sitemap - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble - ) - ("docs" - :base-directory "../../docs" - :base-extension "org" - :publishing-function org-html-publish-to-html - :publishing-directory "./public/docs/" - :exclude ,(regexp-opt '("README.org" "draft" "private.org")) - :index-filename "index.org" - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "sitemap.org" - :sitemap-title "Docs sitemap" - :sitemap-style tree - :sitemap-sort-files anti-chronologically - :html-head-include-default-style nil - :html-head-include-scripts nil - :html-head ,sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ;; TODO: add rss for content, from https://writepermission.com/org-blogging-rss-feed.html - ("css" - :base-directory "./css" - :base-extension ,site-attachments - :recursive t - :publishing-directory "./public/css" - :publishing-function org-publish-attachment - :recursive t) - ("images" - :base-directory "./content/images" - :base-extension ,site-attachments - :publishing-directory "./public/images" - :publishing-function org-publish-attachment - :recursive t) - ("assets" - :base-directory "./assets" - :base-extension ,site-attachments - :publishing-directory "./public/assets" - :publishing-function org-publish-attachment - :recursive t) - ;; legacy - ("posts" - :base-directory "content/legacy/posts" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/posts" - :exclude ,(regexp-opt '("README.org" "draft")) - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "index.org" - :sitemap-title "Posts" - :sitemap-format-entry sbr/org-sitemap-format-entry - :sitemap-style list - :sitemap-sort-files anti-chronologically - :sitemap-function sbr/org-publish-sitemap - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,legacy-sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("posts-rss" - :base-directory "content/legacy/posts" - :base-extension "org" - :recursive t - :html-link-home "https://vincent.demeester.fr/" - :rss-link-home "https://vincent.demeester.fr/posts/" - :html-link-use-abs-url t - :rss-extension "xml" - :publishing-directory "./public" - :publishing-function (sbr/org-rss-publish-to-rss) - :section-number nil - :exclude ".*" - :include ("index.org")) - ("articles" - :base-directory "content/legacy/articles" - :base-extension "org" - :recursive t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/articles" - :exclude ,(regexp-opt '("README.org" "draft")) - :auto-sitemap t - :with-footnotes t - :with-toc nil - :with-drawers t - :sitemap-filename "sitemap.org" - :sitemap-title "Articles" - :sitemap-style tree - :sitemap-sort-files anti-chronologically - ;;:sitemap-format-entry sbr/org-sitemap-format-entry - ;;:sitemap-function sbr/org-publish-sitemap - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,legacy-sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("articles-assets" - :exclude ,(regexp-opt '("*.org")) - :base-directory "content/legacy/articles" - :base-extension ,site-attachments - :publishing-directory "./public/articles" - :publishing-function org-publish-attachment - :recursive t) - ("about" - :base-directory "content/legacy/about" - :base-extension "org" - :exclude ,(regexp-opt '("README.org" "draft")) - :index-filename "index.org" - :recursive nil - :with-footnotes t - :with-toc nil - :with-drawers t - :publishing-function org-html-publish-to-html - :publishing-directory "./public/about" - :html-head-include-scripts nil - :html-head-include-default-style nil - :html-head ,legacy-sbr-website-html-head - :html-preamble sbr-website-html-preamble - :html-postamble ,sbr-website-html-postamble) - ("legacy" - :base-directory "./content/legacy" - :base-extension ,site-attachments - :publishing-directory "./public/" - :publishing-function org-publish-attachment - :recursive t) - ("all" :components ("content" "docs" "posts" "articles" "articles-assets" "css" "images" "assets" "legacy" "posts-rss")))) - -(defun publish () - "Build vincent.demeester.fr website" - (delete-directory (expand-file-name "~/.org-timestamps") t) - (org-publish-all)) - -(provide 'publish) -;;; publish.el ends here diff --git a/www/vincent.demeester.fr/tasks.org b/www/vincent.demeester.fr/tasks.org @@ -1,96 +0,0 @@ -#+TITLE: tasks - -* TODO Make all in legacy as static - -Once I settle with this setup, I should make all in legacy as html.. that way I can -rewrite =emacs-lisp= without any trouble. - -There is a trick to it though… - -* TODO Set =<mark>= with orgmode - -- https://emacs.stackexchange.com/questions/36496/how-to-mark-code-fragments-in-org-export -- https://emacs.stackexchange.com/questions/12814/extending-org-mode-with-more-markups - -* TODO Should the publish/export code be in =src/home= - -A nice side effect would be that it can be used directly from emacs (no need to call =make= -from emacs). Otherwise, [[https://tecosaur.github.io/emacs-config/config.html#nicer-generated-heading][this]] will need to be adapted. - -* TODO nixify publishing - -See https://github.com/etu/etu.github.io/ - -* TODO [[https://abhinavsarkar.net/about/][About Me | abhinavsarkar.net]] - -[2020-05-07 Thu 16:25] - -Good automation setup. - -* TODO Simplify home again -[2020-06-11 Thu 10:49] - -Like [[https://ahuth.github.io/][Andrew Huth]] -- Subtitle is "Hi, …" -- List of /featured/ content (posts) -- Little explanation for articles -- List of some projects (docker, tekton, …) - -* TODO Add support for org-roam in publish - -- [ ] On reference, add the link -- [ ] Add a reference /aside/ or entry for references on the page - -* TODO New blog post capture template/snippet - -- Ask for date -- Ask for title -- Put in the right place - -Use skeleton, … -* TODO Have a "series" page ? -:PROPERTIES: -:CREATED:[2020-06-28 Sun 14:05] -:END: - -For series of article or posts ? - - -From: [[git:~/src/home/README.org::master@{2020-06-28}::1][git:~/src/home/README.org::master@{2020-06-28}::1]] -* DONE Simplify the home -CLOSED: [2020-06-06 Sat 15:50] -:LOGBOOK: -- State "DONE" from "TODO" [2020-06-06 Sat 15:50] -:END: -[2020-04-30 Thu 12:55] - -to sthg like [[https://filippo.io/][Filippo Valsorda]] -also https://duan.ca/articles/ - -Also look at http://git.foldling.org/ and -https://emacsninja.com/posts/farewell-github.html for a ~git.sbr.pm~ -(with gitlab.com/vdemeester header as header) - -https://www.garron.blog/en/ -https://yarmo.eu/ - -Could take https://newcss.net/ and go with it :D [[https://newcss.net/][new.css]] -Base on top of new.css but: -- a bit larger -- remove some nonsense -- support main > header -- add customs (org related) - -* DONE Article listing instead of sitemap -CLOSED: [2020-05-17 Sun 13:48] -:LOGBOOK: -- State "DONE" from "TODO" [2020-05-17 Sun 13:48] -:END: - -Manual listing of articles, linking to the sitemap (like ~configuration~) - -* DONE Add support for small screen like iPhone -CLOSED: [2020-06-06 Sat 15:50] -:LOGBOOK: -- State "DONE" from "TODO" [2020-06-06 Sat 15:50] -:END: diff --git a/www/vincent.demeester.fr/templates/2022.org b/www/vincent.demeester.fr/templates/2022.org @@ -1,9 +0,0 @@ -#+AUTHOR: Vincent Demeester -#+KEYWORDS: post -#+OPTIONS: toc:nil pri:nil todo:nil d:(not "LOGBOOK") -#+EXCLUDE_TAGS: noexport -#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="/css/2022.css" /> -#+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="/css/syntax.css" /> -#+HTML_HEAD_EXTRA: <link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> -#+HTML_HEAD_EXTRA: <meta name='viewport' content='width=device-width, initial-scale=1'> -#+MACRO: mark @@html:<mark>$1</mark>@@ diff --git a/www/vincent.demeester.fr/templates/articles.org b/www/vincent.demeester.fr/templates/articles.org @@ -1,4 +0,0 @@ -#+AUTHOR: Vincent Demeester -#+KEYWORDS: article -#+OPTIONS: toc:nil d:(not "LOGBOOK") -#+EXCLUDE_TAGS: noexport diff --git a/www/vincent.demeester.fr/templates/post.org b/www/vincent.demeester.fr/templates/post.org @@ -1,4 +0,0 @@ -#+AUTHOR: Vincent Demeester -#+KEYWORDS: post -#+OPTIONS: toc:nil pri:nil todo:nil d:(not "LOGBOOK") -#+EXCLUDE_TAGS: noexport diff --git a/www/vincent.demeester.fr/templates/tekton.org b/www/vincent.demeester.fr/templates/tekton.org @@ -1,10 +0,0 @@ -#+AUTHOR: Vincent Demeester -#+KEYWORDS: article -#+OPTIONS: toc:nil pri:nil todo:nil d:(not "LOGBOOK") -#+EXCLUDE_TAGS: noexport -#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="/css/2022.css" /> -#+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="/css/syntax.css" /> -#+HTML_HEAD_EXTRA: <link rel="stylesheet" type="text/css" href="/css/tekton.css" /> -#+HTML_HEAD_EXTRA: <link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> -#+HTML_HEAD_EXTRA: <meta name='viewport' content='width=device-width, initial-scale=1'> -#+MACRO: mark @@html:<mark>$1</mark>@@