diff --git a/.gitignore b/.gitignore index c16476440..3b23e01d4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ docs/_site powershell.log zones/ *.env +node_modules diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..e3f90c4b0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +tabWidth: 4 +singleQuote: true +trailingComma: es5 diff --git a/docs/adding-new-rtypes.md b/docs/adding-new-rtypes.md index 63a65fc9d..61ff934b1 100644 --- a/docs/adding-new-rtypes.md +++ b/docs/adding-new-rtypes.md @@ -60,7 +60,12 @@ is the Javascript file that defines `dnsconfig.js`'s functions like `A()` and `MX()`. Look at the definition of A, MX and CAA for good examples to use as a base. -Please add the function alphabetically with the others. +Please add the function alphabetically with the others. Also, please run +[prettier](https://github.com/prettier/prettier) on the file to ensure +your code conforms to our coding standard: + + npm install prettier + node_modules/.bin/prettier --write pkg/js/helpers.js ## Step 3: Search for `#rtype_variations` diff --git a/pkg/js/helpers.js b/pkg/js/helpers.js index 4bcf49c45..f5e7fced2 100644 --- a/pkg/js/helpers.js +++ b/pkg/js/helpers.js @@ -1,143 +1,153 @@ -"use strict"; +'use strict'; var conf = { registrars: [], dns_providers: [], - domains: [] + domains: [], }; var defaultArgs = []; -function initialize(){ +function initialize() { conf = { registrars: [], dns_providers: [], - domains: [] + domains: [], }; defaultArgs = []; } -function NewRegistrar(name,type,meta) { +function NewRegistrar(name, type, meta) { if (type) { - type == "MANUAL"; + type == 'MANUAL'; } - var reg = {name: name, type: type, meta: meta}; + var reg = { name: name, type: type, meta: meta }; conf.registrars.push(reg); return name; } function NewDnsProvider(name, type, meta) { - if ((typeof meta === 'object') && ('ip_conversions' in meta)) { - meta.ip_conversions = format_tt(meta.ip_conversions) + if (typeof meta === 'object' && 'ip_conversions' in meta) { + meta.ip_conversions = format_tt(meta.ip_conversions); } - var dsp = {name: name, type: type, meta: meta}; + var dsp = { name: name, type: type, meta: meta }; conf.dns_providers.push(dsp); return name; } -function newDomain(name,registrar) { - return {name: name, registrar: registrar, meta:{}, records:[], dnsProviders: {}, defaultTTL: 0, nameservers:[]}; +function newDomain(name, registrar) { + return { + name: name, + registrar: registrar, + meta: {}, + records: [], + dnsProviders: {}, + defaultTTL: 0, + nameservers: [], + }; } function processDargs(m, domain) { - // for each modifier, if it is a... - // function: call it with domain - // array: process recursively - // object: merge it into metadata - if (_.isFunction(m)) { - m(domain); - } else if (_.isArray(m)) { - for (var j in m) { - processDargs(m[j], domain) - } - } else if (_.isObject(m)) { - _.extend(domain.meta,m); - } else { - throw "WARNING: domain modifier type unsupported: "+ typeof m + " Domain: "+ domain.name; + // for each modifier, if it is a... + // function: call it with domain + // array: process recursively + // object: merge it into metadata + if (_.isFunction(m)) { + m(domain); + } else if (_.isArray(m)) { + for (var j in m) { + processDargs(m[j], domain); } + } else if (_.isObject(m)) { + _.extend(domain.meta, m); + } else { + throw 'WARNING: domain modifier type unsupported: ' + + typeof m + + ' Domain: ' + + domain.name; + } } // D(name,registrar): Create a DNS Domain. Use the parameters as records and mods. -function D(name,registrar) { - var domain = newDomain(name,registrar); - for (var i = 0; i< defaultArgs.length; i++){ - processDargs(defaultArgs[i],domain) - } - for (var i = 2; i 1) { // run validator if supplied - if(!argDefinition[1](value)){ - throw type + " record " + argDefinition[0] + " argument validation failed"; + if (!argDefinition[1](value)) { + throw type + + ' record ' + + argDefinition[0] + + ' argument validation failed'; } } parsedArgs[argDefinition[0]] = value; @@ -393,7 +403,7 @@ function recordBuilder(type, opts){ modifiers.push(arguments[i]); } - return function(d){ + return function(d) { var record = { type: type, meta: {}, @@ -412,30 +422,41 @@ function recordBuilder(type, opts){ /** * @deprecated */ -function addRecord(d,type,name,target,mods) { +function addRecord(d, type, name, target, mods) { // if target is number, assume ip address. convert it. if (_.isNumber(target)) { target = num2dot(target); } - var rec = {type: type, name: name, target: target, ttl:d.defaultTTL, priority: 0, meta:{}}; + var rec = { + type: type, + name: name, + target: target, + ttl: d.defaultTTL, + priority: 0, + meta: {}, + }; // for each modifier, decide based on type: // - Function: call is with the record as the argument // - Object: merge it into the metadata // - Number: IF MX record assume it is priority if (mods) { - for (var i = 0; i< mods.length; i++) { - var m = mods[i] + for (var i = 0; i < mods.length; i++) { + var m = mods[i]; if (_.isFunction(m)) { m(rec); } else if (_.isObject(m)) { - //convert transforms to strings - if (m.transform && _.isArray(m.transform)){ - m.transform = format_tt(m.transform) - } - _.extend(rec.meta,m); - _.extend(rec.meta,m); + //convert transforms to strings + if (m.transform && _.isArray(m.transform)) { + m.transform = format_tt(m.transform); + } + _.extend(rec.meta, m); + _.extend(rec.meta, m); } else { - console.log("WARNING: Modifier type unsupported:", typeof m, "(Skipping!)"); + console.log( + 'WARNING: Modifier type unsupported:', + typeof m, + '(Skipping!)' + ); } } } @@ -445,69 +466,66 @@ function addRecord(d,type,name,target,mods) { //ip conversion functions from http://stackoverflow.com/a/8105740/121660 // via http://javascript.about.com/library/blipconvert.htm -function IP(dot) -{ +function IP(dot) { var d = dot.split('.'); - return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]); + // prettier-ignore + return ((((((+d[0]) * 256) + (+d[1])) * 256) + (+d[2])) * 256) + (+d[3]); } -function num2dot(num) -{ - if(num === undefined){ - return ""; +function num2dot(num) { + if (num === undefined) { + return ''; } - if (_.isString(num)){ - return num + if (_.isString(num)) { + return num; } - var d = num%256; - for (var i = 3; i > 0; i--) - { - num = Math.floor(num/256); - d = num%256 + '.' + d; + var d = num % 256; + for (var i = 3; i > 0; i--) { + num = Math.floor(num / 256); + d = num % 256 + '.' + d; } return d; } - // Cloudflare aliases: // Meta settings for individual records. -var CF_PROXY_OFF = {'cloudflare_proxy': 'off'}; // Proxy disabled. -var CF_PROXY_ON = {'cloudflare_proxy': 'on'}; // Proxy enabled. -var CF_PROXY_FULL = {'cloudflare_proxy': 'full'}; // Proxy+Railgun enabled. +var CF_PROXY_OFF = { cloudflare_proxy: 'off' }; // Proxy disabled. +var CF_PROXY_ON = { cloudflare_proxy: 'on' }; // Proxy enabled. +var CF_PROXY_FULL = { cloudflare_proxy: 'full' }; // Proxy+Railgun enabled. // Per-domain meta settings: // Proxy default off for entire domain (the default): -var CF_PROXY_DEFAULT_OFF = {'cloudflare_proxy_default': 'off'}; +var CF_PROXY_DEFAULT_OFF = { cloudflare_proxy_default: 'off' }; // Proxy default on for entire domain: -var CF_PROXY_DEFAULT_ON = {'cloudflare_proxy_default': 'on'}; +var CF_PROXY_DEFAULT_ON = { cloudflare_proxy_default: 'on' }; // CUSTOM, PROVIDER SPECIFIC RECORD TYPES -function _validateCloudFlareRedirect(value){ - if(!_.isString(value)){ +function _validateCloudFlareRedirect(value) { + if (!_.isString(value)) { return false; } - return value.indexOf(",") === -1; + return value.indexOf(',') === -1; } -var CF_REDIRECT = recordBuilder("CF_REDIRECT", { +var CF_REDIRECT = recordBuilder('CF_REDIRECT', { args: [ - ["source", _validateCloudFlareRedirect], - ["destination", _validateCloudFlareRedirect], + ['source', _validateCloudFlareRedirect], + ['destination', _validateCloudFlareRedirect], ], - transform: function(record, args, modifiers){ - record.name = "@"; - record.target = args.source + "," + args.destination; + transform: function(record, args, modifiers) { + record.name = '@'; + record.target = args.source + ',' + args.destination; }, }); -var CF_TEMP_REDIRECT = recordBuilder("CF_TEMP_REDIRECT", { +var CF_TEMP_REDIRECT = recordBuilder('CF_TEMP_REDIRECT', { args: [ - ["source", _validateCloudFlareRedirect], - ["destination", _validateCloudFlareRedirect], + ['source', _validateCloudFlareRedirect], + ['destination', _validateCloudFlareRedirect], ], - transform: function(record, args, modifiers){ - record.name = "@"; - record.target = args.source + "," + args.destination; + transform: function(record, args, modifiers) { + record.name = '@'; + record.target = args.source + ',' + args.destination; }, }); diff --git a/pkg/js/static.go b/pkg/js/static.go index 6146b968d..a9916b07b 100644 --- a/pkg/js/static.go +++ b/pkg/js/static.go @@ -190,75 +190,75 @@ var _escData = map[string]*_escFile{ "/helpers.js": { local: "pkg/js/helpers.js", - size: 14087, + size: 14682, modtime: 0, compressed: ` -H4sIAAAAAAAA/+w6a3PbOJLf9St6WHcj0mYo2Zl4t6Rob7R+bLnOr5KVXLZ0OhcsQhISitQBoDy+nPLb -r/AiAT7sZGv29svmgyMCjUa/0N1otJczDIxTsuDesNPZIQqLLF3CCL52AAAoXhHGKaJsALN5KMfilD1s -abYjMXaGsw0iqRzo7DWuGC9RnvAxXTEYwWw+7HSWebrgJEuBpIQTlJD/wX6gNnN2btv9BQqqVIjv/VAR -VyNkb5Fyg58mZis/RRsc8uctDjeYo0CTQ5bgi8GgIE98wWgE3vX45sP4ylMb7eVfwTvFK8GMQDcAiVQu -Gci/IQjkA/lXkyi4j0qOo23O1j7Fq2CoNcFzmkpENeLPUnanxeGXO6k9LAbAlyxkSzkBo9EIutnjZ7zg -3QB+/hn8Ltk+LLJ0hykjWcq6QFKFI7CUIgYiFxBGsMzoBvEHzv2G+aAimphtf1w0jtKVdGK2fU06KX46 -kyahBFPINygMXC50aCmABuVPTdXXvZheZDRmg9k8FJZ4VxqimNWWNp1eDaAfSowMUyGJwWy+d4nb0myB -GTtDdMX8TaiN1xZ2ryckCxgt1rDJYrIkmIZCl4QDYYCiKHJgNeYBLFCSCKAnwtcarw2IKEXPA0OAYCmn -jOxw8mxDKeMQqqArLLdMeSYFESOOCkhxNh4iwi707v7GMRhjN75mb1jM7AEnDBfrx4KohsVCAr6wm8/S -IOu4XTnOPs8LUTqA+7aNbyWfDTs/RPg3jtNYkx4J1sNNnQN7FV/T7Am8/xhPbi5v/jLQlBTaU34jT1m+ -3WaU43gA3iGYcwmH4IEyWDmu91V2XfKx73R6PTir2vQATilGHAOCs5t7jSeCDwwDX2PYIoo2mGPKADFj -xoDSWBDHotIua4g1g/LsKnZG7SdLEVoojcAI+kMg720nHCU4XfH1EMjhYVBIz9GjBT0j89BS6L6+wbHY -ANFVvsEpd7FbyhHQGxhBATgj81KsLaex9F3KDakAox2QBtH6OL8Yf7ia3oN2UwwQMMwhWxrWy52BZ4C2 -2+RZ/kgSWOY8p9jEr0jgOxenXh5knpXIn0iSwCLBiAJKn2FL8Y5kOYMdSnLMxIa2JvUqE2LrcbBZV6+K -0talFIUt08DEQiWX6fTK3wUDuMdc2uF0eiW3VFaq7NCiWYFbcVcc0XtOSbryd0FgqRNGMndJV9PsLKdI -+p5dYAdi7d4Nbp/aPNCI8wRGsLPILahoQFwegg3iizUWItxF8rff+y//P+PDwJ+xzTp+Sp/n/xb8S0+T -IngoVowgzZPE4kL5i508+YRBmnFAQpkkhljvrYnxLMbylHAYgce86haz47mFXcOVc3YohpHwCQxfprxY -fTQPCjZzEaU95g2OQvA23uCkH4K39gZvT/p9TcbMi705jCCP1nAAx7+Y0Sc9GsMB/MEMptbg274ZfbZH -T95p0g5GkM8E9XMnwu/MWSvCrGNa5pwZE5Njyg1ah8Je+/exs9g5K1GZFLSZ2wZ9wafj8UWCVr48ycHX -ZgOWpyWwc2R5fBYILRO0gv8dKUcwNNmvEtfpePxwOrmcXp6Or0SUIJwsUCKGQSyTyboNI02mpOjo/ft+ -MOwoyVvJpmcSshu0wV4I/QAESMpOszyVjq8PG4xSBnGWdjmI20ZGdVaFlQOzMqTIXiwOgkGvkYjlKEls -VdYyX708MGo1Ka9BK7PePI3xkqQ47lqSLCDgzdGP6NZKAWeCBmHNGpfrB8eKRLI1OeS1zglYFEWB1MEY -RnruzzlJBFfdcVdIXiwfj78Hw3jchGQ8LvFcXY7v9TUH0RXmLyAToA3YxLBBd2qo4mgVSttrx3faRNvp -eNwNpUhFrLg9u/V5QjbBAC45sHWWJzE8YkApYEozKk6q3MU4y76wqKPjP6pEWATvAcwK/cy6grZuCOXh -tm6Lsy5Hq/ZJuU/TtP6PU5QycfMZVA9oKAkJi6yP1U+soEvlIqyS35VHmqOVAeFoVYNQ6jMQ9rlX9Jnd -b/LNI6YNRNqepu5MWNWbhJ29UfrN+Pr8+2xIgjZoXQwbG7qbTr4P2d10Ukd1N50YRPeTjwrRlpKMEv4c -PmGyWvNQ5NqvYr+ffKxjv5981Ob549ZlqNAQSg8OhCKvfV7Q3T6rGPqHWSijO8OhgTPfTbCKVwOpvhpx -ZrSAEr9fsXv1VTNRFQ5yhlY4BIYTvOCZuMaLPIekK1VqWGDKyZIsEMfSAqZX9w0eSoz+zTYgKWhXoaGs -HcKm+AdNAXo9hxVIMRZXPvAUuFdcSP7/jIYnDEmZGCj50QhmZGMgzXcjsC0ms8Ae+9usaPpp+n2eafpp -2mA4n6bGM11/qjim1xBef6rju/70d3RF/2BnsvltS/ESU5wu8Kve5HXdFSniYo0XX8Q91Ze/mKE1xmwR -lMk/KqsS8F4tMt/Vy5ovl1oZYkOtw0FQKXPI/X5SEDMyl1uLW3PgFp/KvQ49eFOcVPAOyWFxVVxklOIF -lwUkL7BKRGAlnjffme7dNOR6N0WiJwL2/fnk47kTqwOrEl0BAA0BzVeZSh5t3wNkRcGtD0tUA/3/Pmi4 -QpUl6MJQHzh6THTNXhxmsf9slmRPAzgKYU1W6wEch5Dipz8jhgfwdh6Cmv7FTL+T05d3AziZzxUaWQX1 -juAbHMM3eAvfhvALfIN38A3gG5yIG7mQZkJSrKosHdtERsJA4D1UiGwqtEj4LYyqsEXZSgBI6mAEZBvJ -n2XNQX46ZmeVWdVkxeQMrodog7YKJCz0RYKvpsyeb47jjPsk2AfR54ykvhfaxocThpsRm5Vq92HNXi2m -hEYKtsSHw5gYeIE1OV1nTuMs2BPfvxuDGrnFoqSinUmaPQnz0PPFntsoyZ6CsD4sDLIc19R3LAErZy3/ -SuPTb0jZk+YBvoEXCDYEDZpVBajnh+CZYubl9d3tZPownYxv7i9uJ9fqUCWy+KGssKyQCmaq8HVPUoV4 -IZTV9uo6kUrt645xnjSFtt8xdHV/7b4ShxRd9ciGOdI8lWe4O3dezVQcq7Id1DeUFUsFzZNaunL3YfKX -c9/yyWpAu9o4+neMtx/SL2n2lIrtUcKwiRG3D7XFxVjLek5ztfzgoAMH8GuMtxSLXDruwEGvxLPCvAg2 -ktOQcUS57eY2WdxakZbAQ1mUbq1HyxcMU4iW0bRewREwQ4veiRSpepB5VFYq2ZDvJPBVlfz2at6CbYLJ -tpxFcuf5rD+HsYnVwnRseCOSkbvkaA63WzGOElX6RTyjL60rjAnMo1v5oOC8MZjqOhwYSU3RFwwtxh8A -YuX6CMbpc3kw1MvDI7ZwiQ0JjuERLzOKga8JK85XZNVvNjlHXD1CrcgOpzZZraIRzBizaWCzpItnErPC -6Vqe64LUnU9g14dc/JTxQBdomf91rwBCy7aq/gleTbfBTqit8XnYKVPJH3BJlWfJXk8zplSyRjtsiQMl -FKP42SinulLgNqoElOpHXnnirAdCXR91Fr+ayYNVSFde2Lfy86ZH4ZofNeHOXudu0PDk2oyqdjUoMJQR -2dKHY28NOmnVRi37h/clcJu/Mv+074NRuURmdzXA+iN7FjdKFJQ3NC8FwxpAy+P3C+h6PVDdHLy0Wnns -lPtjjYvkk1QWW67q55/Beua3p1p31sxYSJxWEwdHnVNwlG3/Kx72rRAtVdwur2YC9Wv/+WRyOxmACY3O -Y7/XgLLdHuV/gTaA6pUpcN+y5eNdrB9zv+6HzmTpEHTnlZnUt13nfRfel/HI3HorHAucxbIrwsQRK9eI -hLpMpDneBE0HVHIjZmf9eeVM6jy7G0K3ogMlYhmFD8Ezno/i/84JxQw8OKzRLgHLOOgLGJf2Q/CCCG7T -5BmcSRvBE6YYWK7caEWLihc7ty9+ytOSJMKpFmiLySZnUaW+0Vlo8Z8Jv0xkbLPE7/QxGGj1StLW7WBZ -QonTcP8nOGo6kSLu5GmZoQgERj4NDsv/yUE+O5rrp80G22hXtFaPhac/d/Rr6JE1AESSmq7ghRMn/pXH -aFbdSCTp1gtIu6aL09as6QYVw/ua1TUqvgwlbX0WFarqdZa6JWnZjhqUbHXi1eZUZ97XfX2G82TgPHS7 -IPtKRKtneA1xdlhfUnj7ArxUnrvUWRtHutvJdFU2hEYtNjVnCdZ5SX/looPiWF0U/Fi1kNplN3H9MMrt -9cTZ0akKYSLtecQ0BMRYvsFAtgIVxYxFReQlPCoKIFaC1ZBb1ZIpJ4+yO1QXwgLs1sv2klsoVexoGEx5 -VnY66v5ILa/mxsUYL0iM4RExHINI5sXWBv5NkeSb9kWm2hfL5F5cT8SX82ohl942tioKWKddUcKa59DL -C7j+VGJWkpfqMIwVArd1B80VX3kDfcWBb1SeJ85uY9L8cgclSKtvTodfbWUExf4P5nGS99YUzk7gWhLR -tszNWlpfWM/Z7Hyt3oX5/VCtudwiS1mW4CjJVn7Zu3nd2rTphUXPZgief/+FbLckXf0UeNUdG8t/dYfk -NjJTvNCtO2QLZSd14dQZLGm2gTXn20GvxzhafMl2mC6T7ClaZJse6v3xqP/uD7/0e0fHRycn/U6vBzuC -zILPaIfYgpItj9BjlnO5JiGPFNHn3mNCttpMojXflN7t8s6PMx50rGZQGEGc8YhtE8L9btR1ufDlv8N4 -1p8HB8fvToJD8XE0D6yvY+frrYhpTv+2qabmG7MxWYov2chT9PE4RTu5t+c05FfauwS2+pI031Q8ZKyc -6L8evztpqEu9FVH8T/L4v3mjzNjqJhIkwjXi62iZZBkVe/YEn6V5WNjhELpRFw4hbug8iqVIZNtFkuXx -MkEUA0oIYpgN1OMi5rLVlItTLIkkaUx2JM5RYhp9I9WNcfFwN7n99NeH24sL4fy7iwLlw5Zmvz13B9DN -lsvufihp7PXgTgxDTBh6THBcRXPTjiU1SCw0OG3CcvHh6qoVzzJPEoXJYDmcIJKs8rTEJmYwfWN6rW1x -DDolD7o7MFsuVXRKOSl6bsG3GgiDgUug7qNtldqDXldKr2HXtL5p2zbNUnV2EdJVRvHhfnp7HcLd5Pbj -5dn5BO7vzk8vLy5PYXJ+ejs5g+lf787vrTP1oBNmLM3pQuCf4JhQETjsjiCRwds9kdXc3SSaKDGPM47Z -SviIpDH+7XYpH1DkmX1zJM1Z8z05P7ucnJ/W3849a9JrfSnwWJbTBfbCl5iy3wm8GDNOUnlb+K5Vv+MD -gver98oDguJG3G5Cfe1hkUWwW+7XEpyeX9+9LEYH4p+ybJDl/wUAAP//wSZNvQc3AAA= +H4sIAAAAAAAA/+w7a3PbOJLf/St6UndDyVYo2Zlkt+Rob7V+bLnOr5KVnLd0OhcsQhISvg4A5fHllN9+ +hRcJkKDlSd3Ofll9SEiw0d3obnQ3Gu2gYBgYp2TBg+O9vQ2isMjSJYzg2x4AAMUrwjhFlA1hNu/JsShl +DznNNiTCznCWIJLqga1GFuElKmI+pisGI5jNj/f2lkW64CRLgaSEExST/8Gdribn0G6j/wIPDT7EwPZY +8ddgZWsxc42fJoZWJ0UJ7gF/znEPEsyRYY8soSNGuxaH4h1GIwiuxtefxpeBIraV/woJULwSKwKBcwgV +5qGFfyj/NYwKIYTVwsO8YOsOxavusVYJL2gqMTWWcJqyWy2VnYvIlorqSDCfPX7BCx7Azz9DQPKHRZZu +MGUkS1kAJHXmi594D104GMEyowniD5x3PN+7dcFELP8RwTiaV7KJWL5LNil+OpV2ocVSirdbGrqcWS3R +YqtpjcPqsecIZQjftjb8IqNR03RvK8u1wbWFTqeXQxj0HE4YphvH0rfu+nKaLTBjp4iuWCfp6U1gFtfv +C90ARos1JFlElgTTnjAEwoEwQGEYlnAa4xAWKI4FwBPha43PACFK0fPQEBXLLCgjGxw/GwhlT0J9dIUl +mZRnUkIR4qi0w4eQsHNNsZN0HRPr6DVouwEcM1xOGgsOajPEEjvCsr5Ik7U/iZ8rotmXeSml4xJu66N1 +I9dSI/YQ4l85TiPNZSiW1oPE5dbyEmuaPUHwH+PJ9cX1X4eacqkM5UWKlBV5nlGOoyEEcOCwb7ZsbTgA +ZdfNCZoxtRfU4rZ7e/0+nKo9UG2BIZxQjDgGBKfXdxphCJ8YBr7GkCOKEswxZYCYsWlAaSTYZ2FlhKdt +m0tud7Xi0QtbUbFZqpHACAbHQOCj7bvDGKcrvj4GcnBgK8RRrwU/I3VFb5tkjhQZRFdFglPeSkTAJzCq +AGdkfuxnIfFSVS5MRSjtvAyQVs7Z+fjT5fQOtI9jgIBhDtnSCKEiDjwDlOfxs3yIY1gWvKDYRMBQ4DsT +e15uZZ5VyJ9IHMMixogCSp8hp3hDsoLBBsUFZoKgrVY9q4zSzUjapredArUVK8VhS7br2u10etnZdIdw +h7m0y+n0UhJVVqvs0mJbgVtBT+zlO05JuupsnL28gZHMgdLVNDstKJLeaOPoTYcHg7xD7fk05DyGEWyO +fa7Zg9naFgniizUWctyE8rnT/6/Of0YH3c6MJevoKX2e/1v3X/qaGbGMcsYI0iKOuw0vs4EDCIRfTzMO +SOiURBBp6podJ00pUsJhBAELGlRmR3ObgIasPjpBHUbCVzB8kfJy/qHRolhsIQM+G8JhD5IhfBj0YD2E +dx8GAxPii1kQBXMYQRGuYR+OfimHn/RwBPvwh3I0tUbfDcrhZ3v4w3vNAeyPoJiJNcyddGFTbr4yADuG +ZjaeMTg5ppyktUvsuX8nq4ucrRNW+UKr8SXoKz4Zj89jtOrIzV3LdyqDltvHsWq1oRYILWO0gv8dKe9g +k+n34WQ8fjiZXEwvTsaXIo4QThYoFsMgpslDgA0jrafi6RA+foRB91iJ38pe35gc7xol+E0PBl0BkbKT +rEilNxxAglHKIMrSgIM4xmRUxxKsvJqVN4X2ZLEtDHaNRExHcWyrs5FJ6+meNNoglpl0kUZ4SVIcBbYw +SxB4e/hbNGzlijPBhjBrjaumiLFik+Q9rbkrnVuwMAy7Ug9jGOlvfylILFYWjAMt+/F4/BoM47EPyXhc +4bm8GN8pRBzRFeYvIBOgHmxi2KA7MVxxtOpJ+2vHd+Lj7WQ8DnpVGjy9Ob3p8Jgk3SFccGDrrIgjeMSA +UsCUZlToVdIxDnQg7Orw6I8qQxahfQizWSCYCnpQ7e55D2YBR6vmoETnDusknlOUMnFqGtY3Yk9S6pUJ +IvPsTMGCykWYleW5W5ejlQHhaNWAUCoyEPb+Vgwa8tdF8oiph0vHpzS9Bqu7jd7e1mj2enx19jpDkaAe +1YphYyi308nrkN1OJ01Ut9OJQXQ3+awQ5ZRklPDn3hMmqzXvicR8J/a7yecm9rvJ59IGtQGV8vJakvXV +cKEhlCIcCMVe+3fBd/tXtSAf/d/HRhndmCUaOPPug1WLNZDqzYszoyWUeN5h+eqtYaPK8RcMrXAPGI7x +gme0p9Ifkq5UnWKBKSdLskAcSxOYXt55/JAY/WEjkBy069Bw1g5hc/wbbQH6fWcpkGIsjn/wRoG/KZP8 +39FqeMyQFIqBki9eMCMcA2nevcC2nMwEe+zHzGh6P32db5reTz2Wcz81vunqvuaadiG8um/iu7r/Ozqj +f7Q7SX7NKV5iitMF3ulPdiuvTAcXa7z4Kk6pHfnEDLMRZgs7I0RVhQI+qlnmvXlQE5NbSxL6BO2gaByf +BcmfFMiMzCV1cW6ul74qcvJo+LbcshDAARD7vLjIKMULLstNQaMwpnPN61dmeNee9O66zO1E+L47m3w+ +cyJ31ypo1wBAQ7QcYWq5s53+y9JCrdQscQ31/7Dtes9PVUm7NNwHjh5jbJVWp4KL2SzOnuTBdk1W6yEc +9SDFT39BDA/hnUgD5edfzOf38vPF7RA+zOcGkayRvjmE73AE3+EdfD+GX+A7vIfvAN/hw5vyHB2TFO8q +vdT4famiRXIY1eGdwpYAkuzCCEgeysdjxwjlUN3s3GKtAqnDiJ9B/RAmKFdwvUqtxDfF0n9aJEdRxjvE +quOWZtsNv2Qk7QS9oPa1UaGtM2PQKrZrk/eaT1pGQuOllMRLQ05icKekJFCLrDSJUlri/R8qL82QJTHJ +/utkJjzTCGYlV3kYZ0/dHlgDYst0y/2kd45lnnI76Guy7EmvAL5D0PVVUxS0BjqGoCy9Xlzd3kymD9PJ ++Pru/GZypbZ8LAszalOUJV3p3erwTV9Xh6gH3lnQIBHII6Mio545j914+/8ZSYM/BzvComKlGWgxR5r9 +ymnIqlvlMlVYra+w2yQoq6cKmseN9On20+SvZx0rLqiB0t1H4b9jnH9Kv6bZUyoYQDHDRqnXNw+N+eVY +KwpOC41hf38P9uHPEc4pFil+tAf7/QrVCvMy7HWU1BlHlDsl3ixqddYSuKyVt8Z5edFi6uNOadwybAFk +Mz2R0lVXS4/KJOVa5H0OfFO1x636bsH6YLKcs1CSns8Gcxib9EFYkQ1v5DJypxzO4SYX4yhW5WjEM/rS +vNKuwNwOVncdzvWHqfrDvhHVFH3F0LIRuoCYdScB4/S52iTqUuQRW7gEQYIjeMTLjGLga8LKvRZa9aOk +4Iiry7IV2eDUZqtVNGIxxnY8y6z44pnErHC65uf6G3UeFdiN7YhnGSp0qZh1vm0VRM+yrp1FLZnTC79T +JbA/5nxAJToKUgl8jTbYWiyKKUbRsxF9fabAbRQFKNX3zHJPWdeUugLrTN55ggArDitP27HOBd5gXHeY +JmbZ814ZRnceSUoMVRy19OFYk0cnrdrwpY4lcJs7Mj/t3WBUTZF5YwOwedefRV6JgnJ25jrCk6H47+Zf +QNfvg2pD4ZXVyk2lnBvzTpJXYFlkOaKffwar8cD+1EpZL8ZC4vTIODiaKwVH2fav7D2wYrFUcbu8/Azq +roSzyeRmMgQT/pymhMCDst0e5X9dbQD181n92CHvCiN9i/xt6x43Ko+g28bMR33Kdq6V4WMVbjynbYOz +nHZJmNhj5ZzGEmVqXWXUHDe6ScxPL1KAzAZzX0bdRK5TbKjn2EodMh4fNGYFxmtS/N8FoZg1Gj5AO3xb +DF5EVQTt+HC4YvIg6IZwk8bPXgYaqvEx8IQpBlYoF1+zMCVQu/JQPsqdHMfC4Zdkyo8+R1aXhteRacs4 +FTGDyKhqWYZzDDbQ6n6orQsEKiOtcBpp/AkOfZYkYmKRVrmRQGDk43WmPznYZ4dzfbvbZqYvmlalGG1i +PsWan0t4MH8RX1ln0iuTJRVE4obW4QW/In6Vr5jVGRBnDuuKCVptpnQpfpvxGMtrOljAuiZr72GpcfVi +6QrKzlGpjJFHpVafZONbsw2xnMXjodM24IJsa4G7maZ60onj5pQyqJXglfbcqc7cKNStZabh1ZMBaLmp +b5ZknbvwHUc2FEXqtNOJTHusXRGUHDKrvEeWpkZImMjwHjHtAWKsSDCQXKCjmLGwTDIIV1fFtVzSk0Y2 +8kYnZbRbiBeOFfi072tXdUuc1ni7HZhaudOA6lqUFra/pzTCCxJheEQMRyCOM4JVA/+2POaY7lKmukur +4404oIk3505JTr3xdpQKWKerVMKa6+qLc7i6rzArlUk9mnWWmrKVDu158c5Ikqhk2B8SXmh3LWUtDN9/ +aHixH9X8+v3fluzKtbemua9IcpO29PbF5LaZ2NpJba2b9jeCtaa8iyxlWYzDOFt1vGup+nOvWhtzg6Zf +Bas91/816Nx9JXlO0tVP3aABsaNSutUlqrp7dHveKV7omhfJoeq7L2MMgyXNElhzng/7fcbR4mu2wXQZ +Z0/hIkv6qP/Hw8H7P/wy6B8eHX74MNjr92FDkJnwBW0QW1CS8xA9ZgWXc2LySBF97j/GJNdmF655Uvna +i9tOlDnFMBHPooyHLI8J7wShyYH7fcgp5pxg+pas0oxie3Ed+TuIZoN5F/bh6P2HLhyAGDicd2sjR42R +d/Nu7a8BTKW6SOzLu7RIZA9X2cLl1k0lJ4HTOVlr8BP4PHPSImn88YPy+vCvgk9PXfCd8Dh/ko7n7Vun +kUzwCFeIr8NlnGVUMt2Xq62syMEOBxCEARxA5KkZRmUfX5wV0TJGFAOKCWKYDdWVM+ayAZkL7yF5JGlE +NiQqUGx6wUPVpXP+cDu5uf/bw835uezzXJQoH3Ka/fo8hCBbLgPYHgtt34ohiAhDjzGO6iiuWzGkLgKc ++uaff7q8bMOwLOLYwXEwQSReFWmFS3zB9K1p0rdFMNyreNdtodlyqUJhyknZfQ0dq3O0O3TZ0x3VrZJ6 +0PMqiXmopk2ibWT80rSpSKkqQ/h0N7256sHt5ObzxenZBO5uz04uzi9OYHJ2cjM5henfbs/urM30oHN7 +LE3oXOCf4IhQEaOc9jB5brHbYRsnFpMWqwJ+w1jlhJCkEf71ZinvqOR2fXsojVgvfXJ2ejE5O/E0Ulgf +X+iAYFlBF7IK2r4up+UhwoyTVJ5tXjXr972+UcsRPqAnfIC60qk4di9btAinZ1e3L8vRgfinMH3C/L8A +AAD//4nEKeNaOQAA `, },