UNPKG

wisp

Version:

Homoiconic JS with clojure syntax, s-expressions & macros

155 lines (154 loc) 28.9 kB
{ var _ns_ = { id: 'wisp.backend.javascript.writer', doc: 'Compiler backend for for writing JS output' }; var wisp_ast = require('./../../ast'); var name = wisp_ast.name; var namespace = wisp_ast.namespace; var symbol = wisp_ast.symbol; var isSymbol = wisp_ast.isSymbol; var isKeyword = wisp_ast.isKeyword; var wisp_sequence = require('./../../sequence'); var list = wisp_sequence.list; var first = wisp_sequence.first; var second = wisp_sequence.second; var third = wisp_sequence.third; var rest = wisp_sequence.rest; var isList = wisp_sequence.isList; var vec = wisp_sequence.vec; var map = wisp_sequence.map; var count = wisp_sequence.count; var last = wisp_sequence.last; var reduce = wisp_sequence.reduce; var isEmpty = wisp_sequence.isEmpty; var wisp_runtime = require('./../../runtime'); var isTrue = wisp_runtime.isTrue; var isNil = wisp_runtime.isNil; var isString = wisp_runtime.isString; var isNumber = wisp_runtime.isNumber; var isVector = wisp_runtime.isVector; var isDictionary = wisp_runtime.isDictionary; var isBoolean = wisp_runtime.isBoolean; var isRePattern = wisp_runtime.isRePattern; var reFind = wisp_runtime.reFind; var dec = wisp_runtime.dec; var subs = wisp_runtime.subs; var isEqual = wisp_runtime.isEqual; var wisp_string = require('./../../string'); var replace = wisp_string.replace; var join = wisp_string.join; var split = wisp_string.split; var upperCase = wisp_string.upperCase; } var writeReference = exports.writeReference = function writeReference(form) { 'Translates references from clojure convention to JS:\n\n **macros** __macros__\n list->vector listToVector\n set! set\n foo_bar foo_bar\n number? isNumber\n create-server createServer'; return function () { var idø1 = name(form); idø1 = idø1 === '*' ? 'multiply' : idø1 === '/' ? 'divide' : idø1 === '+' ? 'sum' : idø1 === '-' ? 'subtract' : idø1 === '=' ? 'equal?' : idø1 === '==' ? 'strict-equal?' : idø1 === '<=' ? 'not-greater-than' : idø1 === '>=' ? 'not-less-than' : idø1 === '>' ? 'greater-than' : idø1 === '<' ? 'less-than' : idø1 === '->' ? 'thread-first' : 'else' ? idø1 : void 0; idø1 = join('_', split(idø1, '*')); idø1 = join('-to-', split(idø1, '->')); idø1 = join(split(idø1, '!')); idø1 = join('$', split(idø1, '%')); idø1 = join('-plus-', split(idø1, '+')); idø1 = join('-and-', split(idø1, '&')); idø1 = last(idø1) === '?' ? '' + 'is-' + subs(idø1, 0, dec(count(idø1))) : idø1; idø1 = reduce(function (result, key) { return '' + result + (!isEmpty(result) && !isEmpty(key) ? '' + upperCase((key || 0)[0]) + subs(key, 1) : key); }, '', split(idø1, '-')); return idø1; }.call(this); }; var writeKeywordReference = exports.writeKeywordReference = function writeKeywordReference(form) { return '' + '"' + name(form) + '"'; }; var writeKeyword = exports.writeKeyword = function writeKeyword(form) { return '' + '"' + '\uA789' + name(form) + '"'; }; var writeSymbol = exports.writeSymbol = function writeSymbol(form) { return write(list(symbol(void 0, 'symbol'), namespace(form), name(form))); }; var writeNil = exports.writeNil = function writeNil(form) { return 'void(0)'; }; var writeNumber = exports.writeNumber = function writeNumber(form) { return form; }; var writeBoolean = exports.writeBoolean = function writeBoolean(form) { return isTrue(form) ? 'true' : 'false'; }; var writeString = exports.writeString = function writeString(form) { form = replace(form, RegExp('\\\\', 'g'), '\\\\'); form = replace(form, RegExp('\n', 'g'), '\\n'); form = replace(form, RegExp('\r', 'g'), '\\r'); form = replace(form, RegExp('\t', 'g'), '\\t'); form = replace(form, RegExp('"', 'g'), '\\"'); return '' + '"' + form + '"'; }; var writeTemplate = exports.writeTemplate = function writeTemplate() { var form = Array.prototype.slice.call(arguments, 0); return function () { var indentPatternø1 = /\n *$/; var lineBreakPatterø1 = RegExp('\n', 'g'); var getIndentationø1 = function (code) { return reFind(indentPatternø1, code) || '\n'; }; return function loop() { var recur = loop; var codeø1 = ''; var partsø1 = split(first(form), '~{}'); var valuesø1 = rest(form); do { recur = count(partsø1) > 1 ? (loop[0] = '' + codeø1 + first(partsø1) + replace('' + '' + first(valuesø1), lineBreakPatterø1, getIndentationø1(first(partsø1))), loop[1] = rest(partsø1), loop[2] = rest(valuesø1), loop) : '' + codeø1 + first(partsø1); } while (codeø1 = loop[0], partsø1 = loop[1], valuesø1 = loop[2], recur === loop); return recur; }.call(this); }.call(this); }; var writeGroup = exports.writeGroup = function writeGroup() { var forms = Array.prototype.slice.call(arguments, 0); return join(', ', forms); }; var writeInvoke = exports.writeInvoke = function writeInvoke(callee) { var params = Array.prototype.slice.call(arguments, 1); return writeTemplate('~{}(~{})', callee, writeGroup.apply(void 0, params)); }; var writeError = exports.writeError = function writeError(message) { return function () { return (function () { throw Error(message); })(); }; }; var writeVector = exports.writeVector = writeError('Vectors are not supported'); var writeDictionary = exports.writeDictionary = writeError('Dictionaries are not supported'); var escapePattern = function escapePattern(pattern) { pattern = join('/', split(pattern, '\\/')); pattern = join('\\/', split(pattern, '/')); return pattern; }; var writeRePattern = exports.writeRePattern = function writeRePattern(form) { return function () { var flagsø1 = '' + (form.multiline ? 'm' : '') + (form.ignoreCase ? 'i' : '') + (form.sticky ? 'y' : ''); var patternø1 = form.source; return '' + '/' + escapePattern(patternø1) + '/' + flagsø1; }.call(this); }; var compileComment = exports.compileComment = function compileComment(form) { return compileTemplate(list('//~{}\n', first(form))); }; var writeDef = exports.writeDef = function writeDef(form) { return function () { var idø1 = first(form); var isExportø1 = (meta(form) || {} || 0)['top'] && !(meta(idø1) || {} || 0)['private']; var attributeø1 = symbol(namespace(idø1), '' + '-' + name(idø1)); return isExportø1 ? compileTemplate(list('var ~{};\n~{}', compile(cons(symbol(void 0, 'set!'), form)), compile(list.apply(void 0, [symbol(void 0, 'set!')].concat([list.apply(void 0, [symbol(void 0, '.')].concat([symbol(void 0, 'exports')], [attributeø1]))], [idø1]))))) : compileTemplate(list('var ~{}', compile(cons(symbol(void 0, 'set!'), form)))); }.call(this); }; var isWriteInstance = exports.isWriteInstance = function isWriteInstance(form) { return writeTemplate('~{} instanceof ~{}', write(second(form)), write(first(form))); }; var write = exports.write = function write(form) { return isNil(form) ? writeNil(form) : isSymbol(form) ? writeReference(form) : isKeyword(form) ? writeKeywordReference(form) : isString(form) ? writeString(form) : isNumber(form) ? writeNumber(form) : isBoolean(form) ? writeBoolean(form) : isRePattern(form) ? writePattern(form) : isVector(form) ? writeVector(form) : isDictionary(form) ? writeDictionary() : isList(form) ? writeInvoke.apply(void 0, map(write, vec(form))) : 'else' ? writeError('Unsupported form') : void 0; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFub255bW91cy53aXNwIl0sIm5hbWVzIjpbIl9uc18iLCJpZCIsImRvYyIsIm5hbWUiLCJuYW1lc3BhY2UiLCJzeW1ib2wiLCJpc1N5bWJvbCIsImlzS2V5d29yZCIsImxpc3QiLCJmaXJzdCIsInNlY29uZCIsInRoaXJkIiwicmVzdCIsImlzTGlzdCIsInZlYyIsIm1hcCIsImNvdW50IiwibGFzdCIsInJlZHVjZSIsImlzRW1wdHkiLCJpc1RydWUiLCJpc05pbCIsImlzU3RyaW5nIiwiaXNOdW1iZXIiLCJpc1ZlY3RvciIsImlzRGljdGlvbmFyeSIsImlzQm9vbGVhbiIsImlzUmVQYXR0ZXJuIiwicmVGaW5kIiwiZGVjIiwic3VicyIsImlzRXF1YWwiLCJyZXBsYWNlIiwiam9pbiIsInNwbGl0IiwidXBwZXJDYXNlIiwid3JpdGVSZWZlcmVuY2UiLCJleHBvcnRzIiwiZm9ybSIsImlkw7gxIiwicmVzdWx0Iiwia2V5Iiwid3JpdGVLZXl3b3JkUmVmZXJlbmNlIiwid3JpdGVLZXl3b3JkIiwid3JpdGVTeW1ib2wiLCJ3cml0ZSIsIndyaXRlTmlsIiwid3JpdGVOdW1iZXIiLCJ3cml0ZUJvb2xlYW4iLCJ3cml0ZVN0cmluZyIsIlJlZ0V4cCIsIndyaXRlVGVtcGxhdGUiLCJpbmRlbnRQYXR0ZXJuw7gxIiwibGluZUJyZWFrUGF0dGVyw7gxIiwiZ2V0SW5kZW50YXRpb27DuDEiLCJjb2RlIiwiY29kZcO4MSIsInBhcnRzw7gxIiwidmFsdWVzw7gxIiwid3JpdGVHcm91cCIsImZvcm1zIiwid3JpdGVJbnZva2UiLCJjYWxsZWUiLCJwYXJhbXMiLCJ3cml0ZUVycm9yIiwibWVzc2FnZSIsIkVycm9yIiwid3JpdGVWZWN0b3IiLCJ3cml0ZURpY3Rpb25hcnkiLCJlc2NhcGVQYXR0ZXJuIiwicGF0dGVybiIsIndyaXRlUmVQYXR0ZXJuIiwiZmxhZ3PDuDEiLCJtdWx0aWxpbmUiLCJpZ25vcmVDYXNlIiwic3RpY2t5IiwicGF0dGVybsO4MSIsInNvdXJjZSIsImNvbXBpbGVDb21tZW50IiwiY29tcGlsZVRlbXBsYXRlIiwid3JpdGVEZWYiLCJpc0V4cG9ydMO4MSIsIm1ldGEiLCJhdHRyaWJ1dGXDuDEiLCJjb21waWxlIiwiY29ucyIsImlzV3JpdGVJbnN0YW5jZSIsIndyaXRlUGF0dGVybiJdLCJtYXBwaW5ncyI6IjtJQUFBLElBQUNBLEksR0FBRDtBQUFBLFlBQUFDLEUsRUFBSSxnQ0FBSjtBQUFBLFlBQUFDLEcsRUFDRSw0Q0FERjtBQUFBLFU7O1FBRThCQyxJQUFBLEcsU0FBQUEsSTtRQUFLQyxTQUFBLEcsU0FBQUEsUztRQUFVQyxNQUFBLEcsU0FBQUEsTTtRQUFPQyxRQUFBLEcsU0FBQUEsUTtRQUFRQyxTQUFBLEcsU0FBQUEsUzs7UUFDekJDLElBQUEsRyxjQUFBQSxJO1FBQUtDLEtBQUEsRyxjQUFBQSxLO1FBQU1DLE1BQUEsRyxjQUFBQSxNO1FBQU9DLEtBQUEsRyxjQUFBQSxLO1FBQU1DLElBQUEsRyxjQUFBQSxJO1FBQUtDLE1BQUEsRyxjQUFBQSxNO1FBQzdCQyxHQUFBLEcsY0FBQUEsRztRQUFJQyxHQUFBLEcsY0FBQUEsRztRQUFJQyxLQUFBLEcsY0FBQUEsSztRQUFNQyxJQUFBLEcsY0FBQUEsSTtRQUFLQyxNQUFBLEcsY0FBQUEsTTtRQUFPQyxPQUFBLEcsY0FBQUEsTzs7UUFDM0JDLE1BQUEsRyxhQUFBQSxNO1FBQU1DLEtBQUEsRyxhQUFBQSxLO1FBQUtDLFFBQUEsRyxhQUFBQSxRO1FBQVFDLFFBQUEsRyxhQUFBQSxRO1FBQVFDLFFBQUEsRyxhQUFBQSxRO1FBQzNCQyxZQUFBLEcsYUFBQUEsWTtRQUFZQyxTQUFBLEcsYUFBQUEsUztRQUFTQyxXQUFBLEcsYUFBQUEsVztRQUNyQkMsTUFBQSxHLGFBQUFBLE07UUFBUUMsR0FBQSxHLGFBQUFBLEc7UUFBSUMsSUFBQSxHLGFBQUFBLEk7UUFBS0MsT0FBQSxHLGFBQUFBLE87O1FBQ2xCQyxPQUFBLEcsWUFBQUEsTztRQUFRQyxJQUFBLEcsWUFBQUEsSTtRQUFLQyxLQUFBLEcsWUFBQUEsSztR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TUEsS0FBTixDQUVHUCxJQUZILEVBR0U7QUFBQSxlQUNFakIsS0FBRCxDQUFNaUIsSUFBTixDQURELEdBQ2NRLFFBQUQsQ0FBV1IsSUFBWCxDQURiLEdBRUVoQyxRQUFELENBQVNnQyxJQUFULEMsR0FBZ0JGLGNBQUQsQ0FBaUJFLElBQWpCLEMsR0FDZC9CLFNBQUQsQ0FBVStCLElBQVYsQyxHQUFpQkkscUJBQUQsQ0FBeUJKLElBQXpCLEMsR0FDZmhCLFFBQUQsQ0FBU2dCLElBQVQsQyxHQUFnQlcsV0FBRCxDQUFjWCxJQUFkLEMsR0FDZGYsUUFBRCxDQUFTZSxJQUFULEMsR0FBZ0JTLFdBQUQsQ0FBY1QsSUFBZCxDLEdBQ2RaLFNBQUQsQ0FBVVksSUFBVixDLEdBQWlCVSxZQUFELENBQWVWLElBQWYsQyxHQUNmWCxXQUFELENBQWFXLElBQWIsQyxHQUFvQmlELFlBQUQsQ0FBZWpELElBQWYsQyxHQUNsQmQsUUFBRCxDQUFTYyxJQUFULEMsR0FBZ0I2QixXQUFELENBQWM3QixJQUFkLEMsR0FDZGIsWUFBRCxDQUFhYSxJQUFiLEMsR0FBb0I4QixlQUFELEUsR0FDbEJ2RCxNQUFELENBQU95QixJQUFQLEMsR0FBb0J1QixXLE1BQVAsQyxNQUFBLEVBQXFCOUMsR0FBRCxDQUFLOEIsS0FBTCxFQUFZL0IsR0FBRCxDQUFLd0IsSUFBTCxDQUFYLENBQXBCLEMsWUFDTjBCLFVBQUQsQ0FBYSxrQkFBYixDLFNBWFA7QUFBQSxLQUhGIiwic291cmNlc0NvbnRlbnQiOlsiKG5zIHdpc3AuYmFja2VuZC5qYXZhc2NyaXB0LndyaXRlclxuICBcIkNvbXBpbGVyIGJhY2tlbmQgZm9yIGZvciB3cml0aW5nIEpTIG91dHB1dFwiXG4gICg6cmVxdWlyZSBbd2lzcC5hc3QgOnJlZmVyIFtuYW1lIG5hbWVzcGFjZSBzeW1ib2wgc3ltYm9sPyBrZXl3b3JkP11dXG4gICAgICAgICAgICBbd2lzcC5zZXF1ZW5jZSA6cmVmZXIgW2xpc3QgZmlyc3Qgc2Vjb25kIHRoaXJkIHJlc3QgbGlzdD9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjIG1hcCBjb3VudCBsYXN0IHJlZHVjZSBlbXB0eT9dXVxuICAgICAgICAgICAgW3dpc3AucnVudGltZSA6cmVmZXIgW3RydWU/IG5pbD8gc3RyaW5nPyBudW1iZXI/IHZlY3Rvcj9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWN0aW9uYXJ5PyBib29sZWFuPyByZS1wYXR0ZXJuP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlLWZpbmQgZGVjIHN1YnMgPV1dXG4gICAgICAgICAgICBbd2lzcC5zdHJpbmcgOnJlZmVyIFtyZXBsYWNlIGpvaW4gc3BsaXQgdXBwZXItY2FzZV1dKSlcblxuOzsgQWN0dWFsIGNvZGVcblxuKGRlZm4gd3JpdGUtcmVmZXJlbmNlXG4gIFtmb3JtXVxuICBcIlRyYW5zbGF0ZXMgcmVmZXJlbmNlcyBmcm9tIGNsb2p1cmUgY29udmVudGlvbiB0byBKUzpcblxuICAqKm1hY3JvcyoqICAgICAgX19tYWNyb3NfX1xuICBsaXN0LT52ZWN0b3IgICAgbGlzdFRvVmVjdG9yXG4gIHNldCEgICAgICAgICAgICBzZXRcbiAgZm9vX2JhciAgICAgICAgIGZvb19iYXJcbiAgbnVtYmVyPyAgICAgICAgIGlzTnVtYmVyXG4gIGNyZWF0ZS1zZXJ2ZXIgICBjcmVhdGVTZXJ2ZXJcIlxuICAobGV0IFtpZCAobmFtZSBmb3JtKV1cbiAgICAoc2V0ISBpZCAoY29uZCAoaWRlbnRpY2FsPyBpZCAgXCIqXCIpIFwibXVsdGlwbHlcIlxuICAgICAgICAgICAgICAgICAgIChpZGVudGljYWw/IGlkIFwiL1wiKSBcImRpdmlkZVwiXG4gICAgICAgICAgICAgICAgICAgKGlkZW50aWNhbD8gaWQgXCIrXCIpIFwic3VtXCJcbiAgICAgICAgICAgICAgICAgICAoaWRlbnRpY2FsPyBpZCBcIi1cIikgXCJzdWJ0cmFjdFwiXG4gICAgICAgICAgICAgICAgICAgKGlkZW50aWNhbD8gaWQgXCI9XCIpIFwiZXF1YWw/XCJcbiAgICAgICAgICAgICAgICAgICAoaWRlbnRpY2FsPyBpZCBcIj09XCIpIFwic3RyaWN0LWVxdWFsP1wiXG4gICAgICAgICAgICAgICAgICAgKGlkZW50aWNhbD8gaWQgXCI8PVwiKSBcIm5vdC1ncmVhdGVyLXRoYW5cIlxuICAgICAgICAgICAgICAgICAgIChpZGVudGljYWw/IGlkIFwiPj1cIikgXCJub3QtbGVzcy10aGFuXCJcbiAgICAgICAgICAgICAgICAgICAoaWRlbnRpY2FsPyBpZCBcIj5cIikgXCJncmVhdGVyLXRoYW5cIlxuICAgICAgICAgICAgICAgICAgIChpZGVudGljYWw/IGlkIFwiPFwiKSBcImxlc3MtdGhhblwiXG4gICAgICAgICAgICAgICAgICAgKGlkZW50aWNhbD8gaWQgXCItPlwiKSBcInRocmVhZC1maXJzdFwiXG4gICAgICAgICAgICAgICAgICAgOmVsc2UgaWQpKVxuICAgIDs7ICoqbWFjcm9zKiogLT4gIF9fbWFjcm9zX19cbiAgICAoc2V0ISBpZCAoam9pbiBcIl9cIiAoc3BsaXQgaWQgXCIqXCIpKSlcbiAgICA7OyBsaXN0LT52ZWN0b3IgLT4gIGxpc3RUb1ZlY3RvclxuICAgIChzZXQhIGlkIChqb2luIFwiLXRvLVwiIChzcGxpdCBpZCBcIi0+XCIpKSlcbiAgICA7OyBzZXQhIC0+ICBzZXRcbiAgICAoc2V0ISBpZCAoam9pbiAoc3BsaXQgaWQgXCIhXCIpKSlcbiAgICAoc2V0ISBpZCAoam9pbiBcIiRcIiAoc3BsaXQgaWQgXCIlXCIpKSlcbiAgICA7OyBmb289IC0+IGZvb0VxdWFsXG4gICAgOyhzZXQhIGlkIChqb2luIFwiLWVxdWFsLVwiIChzcGxpdCBpZCBcIj1cIikpXG4gICAgOzsgZm9vK2JhciAtPiBmb29QbHVzQmFyXG4gICAgKHNldCEgaWQgKGpvaW4gXCItcGx1cy1cIiAoc3BsaXQgaWQgXCIrXCIpKSlcbiAgICAoc2V0ISBpZCAoam9pbiBcIi1hbmQtXCIgKHNwbGl0IGlkIFwiJlwiKSkpXG4gICAgOzsgbnVtYmVyPyAtPiBpc051bWJlclxuICAgIChzZXQhIGlkIChpZiAoaWRlbnRpY2FsPyAobGFzdCBpZCkgXCI/XCIpXG4gICAgICAgICAgICAgICAoc3RyIFwiaXMtXCIgKHN1YnMgaWQgMCAoZGVjIChjb3VudCBpZCkpKSlcbiAgICAgICAgICAgICAgIGlkKSlcbiAgICA7OyBjcmVhdGUtc2VydmVyIC0+IGNyZWF0ZVNlcnZlclxuICAgIChzZXQhIGlkIChyZWR1Y2VcbiAgICAgICAgICAgICAgKGZuIFtyZXN1bHQga2V5XVxuICAgICAgICAgICAgICAgIChzdHIgcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAoaWYgKGFuZCAobm90IChlbXB0eT8gcmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChub3QgKGVtcHR5PyBrZXkpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgKHN0ciAodXBwZXItY2FzZSAoZ2V0IGtleSAwKSkgKHN1YnMga2V5IDEpKVxuICAgICAgICAgICAgICAgICAgICAgICBrZXkpKSlcbiAgICAgICAgICAgICAgXCJcIlxuICAgICAgICAgICAgICAoc3BsaXQgaWQgXCItXCIpKSlcbiAgICBpZCkpXG5cbihkZWZuIHdyaXRlLWtleXdvcmQtcmVmZXJlbmNlXG4gIFtmb3JtXVxuICAoc3RyIFwiXFxcIlwiIChuYW1lIGZvcm0pIFwiXFxcIlwiKSlcblxuKGRlZm4gd3JpdGUta2V5d29yZCBbZm9ybV0gKHN0ciBcIlxcXCJcIiBcIlxcdUE3ODlcIiAobmFtZSBmb3JtKSBcIlxcXCJcIikpXG5cbihkZWZuIHdyaXRlLXN5bWJvbCBbZm9ybV1cbiAgKHdyaXRlIChsaXN0ICdzeW1ib2wgKG5hbWVzcGFjZSBmb3JtKSAobmFtZSBmb3JtKSkpKVxuXG4oZGVmbiB3cml0ZS1uaWwgW2Zvcm1dIFwidm9pZCgwKVwiKVxuXG4oZGVmbiB3cml0ZS1udW1iZXIgW2Zvcm1dIGZvcm0pXG5cbihkZWZuIHdyaXRlLWJvb2xlYW4gW2Zvcm1dIChpZiAodHJ1ZT8gZm9ybSkgXCJ0cnVlXCIgXCJmYWxzZVwiKSlcblxuKGRlZm4gd3JpdGUtc3RyaW5nXG4gIFtmb3JtXVxuICAoc2V0ISBmb3JtIChyZXBsYWNlIGZvcm0gKFJlZ0V4cCBcIlxcXFxcXFxcXCIgXCJnXCIpIFwiXFxcXFxcXFxcIikpXG4gIChzZXQhIGZvcm0gKHJlcGxhY2UgZm9ybSAoUmVnRXhwIFwiXFxuXCIgXCJnXCIpIFwiXFxcXG5cIikpXG4gIChzZXQhIGZvcm0gKHJlcGxhY2UgZm9ybSAoUmVnRXhwIFwiXFxyXCIgXCJnXCIpIFwiXFxcXHJcIikpXG4gIChzZXQhIGZvcm0gKHJlcGxhY2UgZm9ybSAoUmVnRXhwIFwiXFx0XCIgXCJnXCIpIFwiXFxcXHRcIikpXG4gIChzZXQhIGZvcm0gKHJlcGxhY2UgZm9ybSAoUmVnRXhwIFwiXFxcIlwiIFwiZ1wiKSBcIlxcXFxcXFwiXCIpKVxuICAoc3RyIFwiXFxcIlwiIGZvcm0gXCJcXFwiXCIpKVxuXG4oZGVmbiB3cml0ZS10ZW1wbGF0ZVxuICBcIkNvbXBpbGVzIGdpdmVuIHRlbXBsYXRlXCJcbiAgWyYgZm9ybV1cbiAgKGxldCBbaW5kZW50LXBhdHRlcm4gI1wiXFxuICokXCJcbiAgICAgICAgbGluZS1icmVhay1wYXR0ZXIgKFJlZ0V4cCBcIlxcblwiIFwiZ1wiKVxuICAgICAgICBnZXQtaW5kZW50YXRpb24gKGZuIFtjb2RlXSAob3IgKHJlLWZpbmQgaW5kZW50LXBhdHRlcm4gY29kZSkgXCJcXG5cIikpXVxuICAgIChsb29wIFtjb2RlIFwiXCJcbiAgICAgICAgICAgcGFydHMgKHNwbGl0IChmaXJzdCBmb3JtKSBcIn57fVwiKVxuICAgICAgICAgICB2YWx1ZXMgKHJlc3QgZm9ybSldXG4gICAgICAoaWYgKD4gKGNvdW50IHBhcnRzKSAxKVxuICAgICAgICAocmVjdXJcbiAgICAgICAgIChzdHJcbiAgICAgICAgICBjb2RlXG4gICAgICAgICAgKGZpcnN0IHBhcnRzKVxuICAgICAgICAgIChyZXBsYWNlIChzdHIgXCJcIiAoZmlyc3QgdmFsdWVzKSlcbiAgICAgICAgICAgICAgICAgICAgbGluZS1icmVhay1wYXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgKGdldC1pbmRlbnRhdGlvbiAoZmlyc3QgcGFydHMpKSkpXG4gICAgICAgICAocmVzdCBwYXJ0cylcbiAgICAgICAgIChyZXN0IHZhbHVlcykpXG4gICAgICAgICAoc3RyIGNvZGUgKGZpcnN0IHBhcnRzKSkpKSkpXG5cblxuKGRlZm4gd3JpdGUtZ3JvdXBcbiAgWyYgZm9ybXNdXG4gIChqb2luIFwiLCBcIiBmb3JtcykpXG5cbihkZWZuIHdyaXRlLWludm9rZVxuICBbY2FsbGVlICYgcGFyYW1zXVxuICAod3JpdGUtdGVtcGxhdGUgXCJ+e30ofnt9KVwiIGNhbGxlZSAoYXBwbHkgd3JpdGUtZ3JvdXAgcGFyYW1zKSkpXG5cbihkZWZuIHdyaXRlLWVycm9yXG4gIFttZXNzYWdlXVxuICAoZm4gW10gKHRocm93IChFcnJvciBtZXNzYWdlKSkpKVxuXG4oZGVmIHdyaXRlLXZlY3RvciAod3JpdGUtZXJyb3IgXCJWZWN0b3JzIGFyZSBub3Qgc3VwcG9ydGVkXCIpKVxuKGRlZiB3cml0ZS1kaWN0aW9uYXJ5ICh3cml0ZS1lcnJvciBcIkRpY3Rpb25hcmllcyBhcmUgbm90IHN1cHBvcnRlZFwiKSlcblxuKGRlZm4tIGVzY2FwZS1wYXR0ZXJuIFtwYXR0ZXJuXVxuICAoc2V0ISBwYXR0ZXJuIChqb2luIFwiL1wiIChzcGxpdCBwYXR0ZXJuIFwiXFxcXC9cIikpKVxuICAoc2V0ISBwYXR0ZXJuIChqb2luIFwiXFxcXC9cIiAoc3BsaXQgcGF0dGVybiBcIi9cIikpKVxuICBwYXR0ZXJuKVxuXG4oZGVmbiB3cml0ZS1yZS1wYXR0ZXJuXG4gIFtmb3JtXVxuICAobGV0IFtmbGFncyAoc3RyIChpZiBmb3JtLm11bHRpbGluZSBcIm1cIiBcIlwiKVxuICAgICAgICAgICAgICAgICAgIChpZiBmb3JtLmlnbm9yZUNhc2UgXCJpXCIgXCJcIilcbiAgICAgICAgICAgICAgICAgICAoaWYgZm9ybS5zdGlja3kgXCJ5XCIgXCJcIikpXG4gICAgICAgIHBhdHRlcm4gZm9ybS5zb3VyY2VdXG4gICAgKHN0ciBcXC8gKGVzY2FwZS1wYXR0ZXJuIHBhdHRlcm4pIFxcLyBmbGFncykpKVxuXG5cbihkZWZuIGNvbXBpbGUtY29tbWVudFxuICBbZm9ybV1cbiAgKGNvbXBpbGUtdGVtcGxhdGUgKGxpc3QgXCIvL357fVxcblwiIChmaXJzdCBmb3JtKSkpKVxuXG4oZGVmbiB3cml0ZS1kZWZcbiAgXCJDcmVhdGVzIGFuZCBpbnRlcm5zIG9yIGxvY2F0ZXMgYSBnbG9iYWwgdmFyIHdpdGggdGhlIG5hbWUgb2Ygc3ltYm9sXG4gIGFuZCBhIG5hbWVzcGFjZSBvZiB0aGUgdmFsdWUgb2YgdGhlIGN1cnJlbnQgbmFtZXNwYWNlICgqbnMqKS4gSWYgaW5pdFxuICBpcyBzdXBwbGllZCwgaXQgaXMgZXZhbHVhdGVkLCBhbmQgdGhlIHJvb3QgYmluZGluZyBvZiB0aGUgdmFyIGlzIHNldFxuICB0byB0aGUgcmVzdWx0aW5nIHZhbHVlLiBJZiBpbml0IGlzIG5vdCBzdXBwbGllZCwgdGhlIHJvb3QgYmluZGluZyBvZlxuICB0aGUgdmFyIGlzIHVuYWZmZWN0ZWQuIGRlZiBhbHdheXMgYXBwbGllcyB0byB0aGUgcm9vdCBiaW5kaW5nLCBldmVuIGlmXG4gIHRoZSB2YXIgaXMgdGhyZWFkLWJvdW5kIGF0IHRoZSBwb2ludCB3aGVyZSBkZWYgaXMgY2FsbGVkLiBkZWYgeWllbGRzXG4gIHRoZSB2YXIgaXRzZWxmIChub3QgaXRzIHZhbHVlKS5cIlxuICBbZm9ybV1cbiAgKGxldCBbaWQgKGZpcnN0IGZvcm0pXG4gICAgICAgIGV4cG9ydD8gKGFuZCAoOnRvcCAob3IgKG1ldGEgZm9ybSkge30pKVxuICAgICAgICAgICAgICAgICAgICAgKG5vdCAoOnByaXZhdGUgKG9yIChtZXRhIGlkKSB7fSkpKSlcbiAgICAgICAgYXR0cmlidXRlIChzeW1ib2wgKG5hbWVzcGFjZSBpZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0ciBcIi1cIiAobmFtZSBpZCkpKV1cbiAgICAoaWYgZXhwb3J0P1xuICAgICAgKGNvbXBpbGUtdGVtcGxhdGUgKGxpc3QgXCJ2YXIgfnt9O1xcbn57fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbXBpbGUgKGNvbnMgJ3NldCEgZm9ybSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbXBpbGUgYChzZXQhICguIGV4cG9ydHMgfmF0dHJpYnV0ZSkgfmlkKSkpKVxuICAgICAgKGNvbXBpbGUtdGVtcGxhdGUgKGxpc3QgXCJ2YXIgfnt9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb21waWxlIChjb25zICdzZXQhIGZvcm0pKSkpKSkpXG5cblxuKGRlZm4gd3JpdGUtaW5zdGFuY2U/XG4gIFwiRXZhbHVhdGVzIHggYW5kIHRlc3RzIGlmIGl0IGlzIGFuIGluc3RhbmNlIG9mIHRoZSBjbGFzc1xuICBjLiBSZXR1cm5zIHRydWUgb3IgZmFsc2VcIlxuICBbZm9ybV1cbiAgKHdyaXRlLXRlbXBsYXRlIFwifnt9IGluc3RhbmNlb2Ygfnt9XCJcbiAgICAgICAgICAgICAgICAgICh3cml0ZSAoc2Vjb25kIGZvcm0pKVxuICAgICAgICAgICAgICAgICAgKHdyaXRlIChmaXJzdCBmb3JtKSkpKVxuKGRlZm4gd3JpdGVcbiAgXCJjb21waWxlcyBnaXZlbiBmb3JtXCJcbiAgW2Zvcm1dXG4gIChjb25kXG4gICAobmlsPyBmb3JtKSAod3JpdGUtbmlsIGZvcm0pXG4gICAoc3ltYm9sPyBmb3JtKSAod3JpdGUtcmVmZXJlbmNlIGZvcm0pXG4gICAoa2V5d29yZD8gZm9ybSkgKHdyaXRlLWtleXdvcmQtcmVmZXJlbmNlIGZvcm0pXG4gICAoc3RyaW5nPyBmb3JtKSAod3JpdGUtc3RyaW5nIGZvcm0pXG4gICAobnVtYmVyPyBmb3JtKSAod3JpdGUtbnVtYmVyIGZvcm0pXG4gICAoYm9vbGVhbj8gZm9ybSkgKHdyaXRlLWJvb2xlYW4gZm9ybSlcbiAgIChyZS1wYXR0ZXJuPyBmb3JtKSAod3JpdGUtcGF0dGVybiBmb3JtKVxuICAgKHZlY3Rvcj8gZm9ybSkgKHdyaXRlLXZlY3RvciBmb3JtKVxuICAgKGRpY3Rpb25hcnk/IGZvcm0pICh3cml0ZS1kaWN0aW9uYXJ5KVxuICAgKGxpc3Q/IGZvcm0pIChhcHBseSB3cml0ZS1pbnZva2UgKG1hcCB3cml0ZSAodmVjIGZvcm0pKSlcbiAgIDplbHNlICh3cml0ZS1lcnJvciBcIlVuc3VwcG9ydGVkIGZvcm1cIikpKVxuIl19