UNPKG

text-to-map

Version:

Text To Map usiluje o lepší, strojově zpracovatelné využití částí vyhlášek s výčtem ulic a dalších lokací. Jde o rozšiřitelnou sadu konceptů a nástrojů, které zajistí hladký převod výčtu ulic a jejich rozsahů v lidsky srozumitelném jazyce do strojově zpra

168 lines 19.5 kB
import { createToken, Lexer } from "chevrotain"; let nameWasMatched = false; export const resetTokenState = () => { nameWasMatched = false; }; export const prepareLine = (text) => { return text .replace(/([IVXLCDM]+) - ([IVXLCDM]+)/, "$1-$2") .replace(/;/g, ",") .replace(/,$/, ""); }; // this function prevents numbers that make part of the street name to be matched before the // street/municipality part name is completely matched const tokenBlockerFactory = (pattern) => { const stickyPattern = new RegExp(pattern, "y"); return (text, startOffset) => { if (nameWasMatched) { stickyPattern.lastIndex = startOffset; return stickyPattern.exec(text); } else { return null; } }; }; const interruptPatterns = [ "lichá", "sudá", "č.", "od", "do", "pouze", "všechna", "bez", "vyjma", "mimo", "s výjimkou", "kromě", ]; // this pattern allows a single space or a single hyphen (without an adjacent space) between words const streetNamePattern = /[^ -]+([ -]?[^ -]+)*/; // same but with a prefix of municipality part const municipalityPartNamePattern = /část (obce|města) [^ -]+([ -]?[^ -]+)*/; export const nameMatcherFactory = (pattern) => { return (text, startOffset) => { if (nameWasMatched || startOffset > 0) { return null; } else { const result = pattern.exec(text); if (result !== null) { nameWasMatched = true; const firstIndex = interruptPatterns.reduce((currentMin, pattern) => { const index = text.search(new RegExp(` ${pattern}( |$)`)); return index >= 0 ? Math.min(index, currentMin) : currentMin; }, Infinity); if (firstIndex < Infinity) { return [result[0].substring(0, firstIndex).trim()]; } } return result; } }; }; export const streetNameMatcher = nameMatcherFactory(streetNamePattern); const MainSeparator = createToken({ name: "MainSeparator", pattern: / - / }); const From = createToken({ name: "From", pattern: /od/ }); const To = createToken({ name: "To", pattern: /do/ }); const AndAbove = createToken({ name: "AndAbove", pattern: / (a )?(výše?|vyšší)/, }); const AndBelow = createToken({ name: "AndBelow", pattern: / a (níže?|nižší)/, }); const Separator = createToken({ name: "Separator", pattern: /,| a /, longer_alt: [AndAbove, AndBelow], }); const DescriptiveType = createToken({ name: "CPType", pattern: /(pouze |všechna )?č. ?p./, }); const AllType = createToken({ name: "AllType", pattern: /(pouze |všechna )?(č(\.|ísla)( ?o\.)?|lichá i sudá)/, longer_alt: DescriptiveType, }); const OddType = createToken({ name: "OddType", pattern: /(pouze |všechna )?(lich([áé]|ých)( č(\.|ísla))?( ?o\.)?|č(\.|ísla)( ?o\.)? lich[áé])/, longer_alt: AllType, }); const EvenType = createToken({ name: "EvenType", pattern: /(pouze |všechna )?(sud([áé]|ých)( č(\.|ísla))?( ?o\.)?|č(\.|ísla)( ?o\.)? sud[áé])/, }); const Without = createToken({ name: "Without", pattern: /bez|vyjma|mimo|s výjimkou|kromě/, }); const MunicipalityPartName = createToken({ name: "MunicipalityPartName", pattern: nameMatcherFactory(municipalityPartNamePattern), }); const StreetName = createToken({ name: "StreetName", pattern: nameMatcherFactory(streetNamePattern), }); const Number = createToken({ name: "Number", pattern: tokenBlockerFactory(/\d+[a-zA-Z]?/), }); const Hyphen = createToken({ name: "Hyphen", pattern: /-|až/ }); const Slash = createToken({ name: "Hyphen", pattern: /\// }); const Space = createToken({ name: "Space", pattern: / +/, longer_alt: [MainSeparator, Separator], group: Lexer.SKIPPED, }); // const Colon = createToken({ // name: "Colon", // pattern: /:/, // group: Lexer.SKIPPED, // }); const smdTokens = [ MainSeparator, Separator, OddType, EvenType, DescriptiveType, AllType, Number, From, To, AndAbove, AndBelow, Without, Hyphen, Slash, Space, // Colon, MunicipalityPartName, StreetName, ]; MainSeparator.LABEL = "' - '"; Separator.LABEL = "','"; Hyphen.LABEL = "'-'"; Slash.LABEL = "'/'"; From.LABEL = "'od'"; To.LABEL = "'do'"; AndAbove.LABEL = "'a výše'"; AndBelow.LABEL = "'a níže'"; Space.LABEL = "' '"; OddType.LABEL = "'lichá č.'"; EvenType.LABEL = "'sudá č.'"; DescriptiveType.LABEL = "'č. p.'"; AllType.LABEL = "'č.'"; Without.LABEL = "'bez'"; const tokenVocabulary = {}; smdTokens.forEach((tokenType) => { tokenVocabulary[tokenType.name] = tokenType; }); export { MainSeparator, Separator, OddType, EvenType, DescriptiveType, AllType, Number, From, To, AndAbove, AndBelow, Without, Hyphen, Slash, Space, StreetName, MunicipalityPartName, smdTokens, tokenVocabulary, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tZGVmaW5pdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdHJlZXQtbWFya2Rvd24vdG9rZW4tZGVmaW5pdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBbUIsTUFBTSxZQUFZLENBQUM7QUFFakUsSUFBSSxjQUFjLEdBQUcsS0FBSyxDQUFDO0FBRTNCLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxHQUFTLEVBQUU7SUFDeEMsY0FBYyxHQUFHLEtBQUssQ0FBQztBQUN6QixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRTtJQUMxQyxPQUFPLElBQUk7U0FDUixPQUFPLENBQUMsNkJBQTZCLEVBQUUsT0FBTyxDQUFDO1NBQy9DLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO1NBQ2xCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDdkIsQ0FBQyxDQUFDO0FBRUYsNEZBQTRGO0FBQzVGLHNEQUFzRDtBQUN0RCxNQUFNLG1CQUFtQixHQUFHLENBQzFCLE9BQWUsRUFDa0QsRUFBRTtJQUNuRSxNQUFNLGFBQWEsR0FBRyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDL0MsT0FBTyxDQUFDLElBQVksRUFBRSxXQUFtQixFQUEwQixFQUFFO1FBQ25FLElBQUksY0FBYyxFQUFFO1lBQ2xCLGFBQWEsQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDO1lBQ3RDLE9BQU8sYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNqQzthQUFNO1lBQ0wsT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0saUJBQWlCLEdBQUc7SUFDeEIsT0FBTztJQUNQLE1BQU07SUFDTixJQUFJO0lB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OUIsZUFBZSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUM7QUFDOUMsQ0FBQyxDQUFDLENBQUM7QUFFSCxPQUFPLEVBQ0wsYUFBYSxFQUNiLFNBQVMsRUFDVCxPQUFPLEVBQ1AsUUFBUSxFQUNSLGVBQWUsRUFDZixPQUFPLEVBQ1AsTUFBTSxFQUNOLElBQUksRUFDSixFQUFFLEVBQ0YsUUFBUSxFQUNSLFFBQVEsRUFDUixPQUFPLEVBQ1AsTUFBTSxFQUNOLEtBQUssRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUNWLG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsZUFBZSxHQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlVG9rZW4sIExleGVyLCBUb2tlblZvY2FidWxhcnkgfSBmcm9tIFwiY2hldnJvdGFpblwiO1xyXG5cclxubGV0IG5hbWVXYXNNYXRjaGVkID0gZmFsc2U7XHJcblxyXG5leHBvcnQgY29uc3QgcmVzZXRUb2tlblN0YXRlID0gKCk6IHZvaWQgPT4ge1xyXG4gIG5hbWVXYXNNYXRjaGVkID0gZmFsc2U7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgcHJlcGFyZUxpbmUgPSAodGV4dDogc3RyaW5nKSA9PiB7XHJcbiAgcmV0dXJuIHRleHRcclxuICAgIC5yZXBsYWNlKC8oW0lWWExDRE1dKykgLSAoW0lWWExDRE1dKykvLCBcIiQxLSQyXCIpXHJcbiAgICAucmVwbGFjZSgvOy9nLCBcIixcIilcclxuICAgIC5yZXBsYWNlKC8sJC8sIFwiXCIpO1xyXG59O1xyXG5cclxuLy8gdGhpcyBmdW5jdGlvbiBwcmV2ZW50cyBudW1iZXJzIHRoYXQgbWFrZSBwYXJ0IG9mIHRoZSBzdHJlZXQgbmFtZSB0byBiZSBtYXRjaGVkIGJlZm9yZSB0aGVcclxuLy8gc3RyZWV0L211bmljaXBhbGl0eSBwYXJ0IG5hbWUgaXMgY29tcGxldGVseSBtYXRjaGVkXHJcbmNvbnN0IHRva2VuQmxvY2tlckZhY3RvcnkgPSAoXHJcbiAgcGF0dGVybjogUmVnRXhwXHJcbik6ICgodGV4dDogc3RyaW5nLCBzdGFydE9mZnNldDogbnVtYmVyKSA9PiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsKSA9PiB7XHJcbiAgY29uc3Qgc3RpY2t5UGF0dGVybiA9IG5ldyBSZWdFeHAocGF0dGVybiwgXCJ5XCIpO1xyXG4gIHJldHVybiAodGV4dDogc3RyaW5nLCBzdGFydE9mZnNldDogbnVtYmVyKTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbCA9PiB7XHJcbiAgICBpZiAobmFtZVdhc01hdGNoZWQpIHtcclxuICAgICAgc3RpY2t5UGF0dGVybi5sYXN0SW5kZXggPSBzdGFydE9mZnNldDtcclxuICAgICAgcmV0dXJuIHN0aWNreVBhdHRlcm4uZXhlYyh0ZXh0KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gIH07XHJcbn07XHJcblxyXG5jb25zdCBpbnRlcnJ1cHRQYXR0ZXJucyA9IFtcclxuICBcImxpY2jDoVwiLFxyXG4gIFwic3Vkw6FcIixcclxuICBcIsSNLlwiLFxyXG4gIFwib2RcIixcclxuICBcImRvXCIsXHJcbiAgXCJwb3V6ZVwiLFxyXG4gIFwidsWhZWNobmFcIixcclxuICBcImJlelwiLFxyXG4gIFwidnlqbWFcIixcclxuICBcIm1pbW9cIixcclxuICBcInMgdsO9amlta291XCIsXHJcbiAgXCJrcm9txJtcIixcclxuXTtcclxuLy8gdGhpcyBwYXR0ZXJuIGFsbG93cyBhIHNpbmdsZSBzcGFjZSBvciBhIHNpbmdsZSBoeXBoZW4gKHdpdGhvdXQgYW4gYWRqYWNlbnQgc3BhY2UpIGJldHdlZW4gd29yZHNcclxuY29uc3Qgc3RyZWV0TmFtZVBhdHRlcm4gPSAvW14gLV0rKFsgLV0/W14gLV0rKSovO1xyXG5cclxuLy8gc2FtZSBidXQgd2l0aCBhIHByZWZpeCBvZiBtdW5pY2lwYWxpdHkgcGFydFxyXG5jb25zdCBtdW5pY2lwYWxpdHlQYXJ0TmFtZVBhdHRlcm4gPSAvxI3DoXN0IChvYmNlfG3Em3N0YSkgW14gLV0rKFsgLV0/W14gLV0rKSovO1xyXG5cclxuZXhwb3J0IGNvbnN0IG5hbWVNYXRjaGVyRmFjdG9yeSA9IChwYXR0ZXJuOiBSZWdFeHApID0+IHtcclxuICByZXR1cm4gKFxyXG4gICAgdGV4dDogc3RyaW5nLFxyXG4gICAgc3RhcnRPZmZzZXQ6IG51bWJlclxyXG4gICk6IFJlZ0V4cEV4ZWNBcnJheSB8IFtzdHJpbmddIHwgbnVsbCA9PiB7XHJcbiAgICBpZiAobmFtZVdhc01hdGNoZWQgfHwgc3RhcnRPZmZzZXQgPiAwKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gcGF0dGVybi5leGVjKHRleHQpO1xyXG4gICAgICBpZiAocmVzdWx0ICE9PSBudWxsKSB7XHJcbiAgICAgICAgbmFtZVdhc01hdGNoZWQgPSB0cnVlO1xyXG4gICAgICAgIGNvbnN0IGZpcnN0SW5kZXggPSBpbnRlcnJ1cHRQYXR0ZXJucy5yZWR1Y2UoXHJcbiAgICAgICAgICAoY3VycmVudE1pbjogbnVtYmVyLCBwYXR0ZXJuOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0ZXh0LnNlYXJjaChuZXcgUmVnRXhwKGAgJHtwYXR0ZXJufSggfCQpYCkpO1xyXG4gICAgICAgICAgICByZXR1cm4gaW5kZXggPj0gMCA/IE1hdGgubWluKGluZGV4LCBjdXJyZW50TWluKSA6IGN1cnJlbnRNaW47XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgSW5maW5pdHlcclxuICAgICAgICApO1xyXG4gICAgICAgIGlmIChmaXJzdEluZGV4IDwgSW5maW5pdHkpIHtcclxuICAgICAgICAgIHJldHVybiBbcmVzdWx0WzBdLnN1YnN0cmluZygwLCBmaXJzdEluZGV4KS50cmltKCldO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG4gIH07XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3Qgc3RyZWV0TmFtZU1hdGNoZXIgPSBuYW1lTWF0Y2hlckZhY3Rvcnkoc3RyZWV0TmFtZVBhdHRlcm4pO1xyXG5cclxuY29uc3QgTWFpblNlcGFyYXRvciA9IGNyZWF0ZVRva2VuKHsgbmFtZTogXCJNYWluU2VwYXJhdG9yXCIsIHBhdHRlcm46IC8gLSAvIH0pO1xyXG5jb25zdCBGcm9tID0gY3JlYXRlVG9rZW4oeyBuYW1lOiBcIkZyb21cIiwgcGF0dGVybjogL29kLyB9KTtcclxuY29uc3QgVG8gPSBjcmVhdGVUb2tlbih7IG5hbWU6IFwiVG9cIiwgcGF0dGVybjogL2RvLyB9KTtcclxuY29uc3QgQW5kQWJvdmUgPSBjcmVhdGVUb2tlbih7XHJcbiAgbmFtZTogXCJBbmRBYm92ZVwiLFxyXG4gIHBhdHRlcm46IC8gKGEgKT8odsO9xaFlP3x2ecWhxaHDrSkvLFxyXG59KTtcclxuY29uc3QgQW5kQmVsb3cgPSBjcmVhdGVUb2tlbih7XHJcbiAgbmFtZTogXCJBbmRCZWxvd1wiLFxyXG4gIHBhdHRlcm46IC8gYSAobsOtxb5lP3xuacW+xaHDrSkvLFxyXG59KTtcclxuY29uc3QgU2VwYXJhdG9yID0gY3JlYXRlVG9rZW4oe1xyXG4gIG5hbWU6IFwiU2VwYXJhdG9yXCIsXHJcbiAgcGF0dGVybjogLyx8IGEgLyxcclxuICBsb25nZXJfYWx0OiBbQW5kQWJvdmUsIEFuZEJlbG93XSxcclxufSk7XHJcbmNvbnN0IERlc2NyaXB0aXZlVHlwZSA9IGNyZWF0ZVRva2VuKHtcclxuICBuYW1lOiBcIkNQVHlwZVwiLFxyXG4gIHBhdHRlcm46IC8ocG91emUgfHbFoWVjaG5hICk/xI0uID9wLi8sXHJcbn0pO1xyXG5jb25zdCBBbGxUeXBlID0gY3JlYXRlVG9rZW4oe1xyXG4gIG5hbWU6IFwiQWxsVHlwZVwiLFxyXG4gIHBhdHRlcm46IC8ocG91emUgfHbFoWVjaG5hICk/KMSNKFxcLnzDrXNsYSkoID9vXFwuKT98bGljaMOhIGkgc3Vkw6EpLyxcclxuICBsb25nZXJfYWx0OiBEZXNjcmlwdGl2ZVR5cGUsXHJcbn0pO1xyXG5jb25zdCBPZGRUeXBlID0gY3JlYXRlVG9rZW4oe1xyXG4gIG5hbWU6IFwiT2RkVHlwZVwiLFxyXG4gIHBhdHRlcm46XHJcbiAgICAvKHBvdXplIHx2xaFlY2huYSApPyhsaWNoKFvDocOpXXzDvWNoKSggxI0oXFwufMOtc2xhKSk/KCA/b1xcLik/fMSNKFxcLnzDrXNsYSkoID9vXFwuKT8gbGljaFvDocOpXSkvLFxyXG4gIGxvbmdlcl9hbHQ6IEFsbFR5cGUsXHJcbn0pO1xyXG5jb25zdCBFdmVuVHlwZSA9IGNyZWF0ZVRva2VuKHtcclxuICBuYW1lOiBcIkV2ZW5UeXBlXCIsXHJcbiAgcGF0dGVybjpcclxuICAgIC8ocG91emUgfHbFoWVjaG5hICk/KHN1ZChbw6HDqV18w71jaCkoIMSNKFxcLnzDrXNsYSkpPyggP29cXC4pP3zEjShcXC58w61zbGEpKCA/b1xcLik/IHN1ZFvDocOpXSkvLFxyXG59KTtcclxuY29uc3QgV2l0aG91dCA9IGNyZWF0ZVRva2VuKHtcclxuICBuYW1lOiBcIldpdGhvdXRcIixcclxuICBwYXR0ZXJuOiAvYmV6fHZ5am1hfG1pbW98cyB2w71qaW1rb3V8a3JvbcSbLyxcclxufSk7XHJcbmNvbnN0IE11bmljaXBhbGl0eVBhcnROYW1lID0gY3JlYXRlVG9rZW4oe1xyXG4gIG5hbWU6IFwiTXVuaWNpcGFsaXR5UGFydE5hbWVcIixcclxuICBwYXR0ZXJuOiBuYW1lTWF0Y2hlckZhY3RvcnkobXVuaWNpcGFsaXR5UGFydE5hbWVQYXR0ZXJuKSxcclxufSk7XHJcbmNvbnN0IFN0cmVldE5hbWUgPSBjcmVhdGVUb2tlbih7XHJcbiAgbmFtZTogXCJTdHJlZXROYW1lXCIsXHJcbiAgcGF0dGVybjogbmFtZU1hdGNoZXJGYWN0b3J5KHN0cmVldE5hbWVQYXR0ZXJuKSxcclxufSk7XHJcblxyXG5jb25zdCBOdW1iZXIgPSBjcmVhdGVUb2tlbih7XHJcbiAgbmFtZTogXCJOdW1iZXJcIixcclxuICBwYXR0ZXJuOiB0b2tlbkJsb2NrZXJGYWN0b3J5KC9cXGQrW2EtekEtWl0/LyksXHJcbn0pO1xyXG5jb25zdCBIeXBoZW4gPSBjcmVhdGVUb2tlbih7IG5hbWU6IFwiSHlwaGVuXCIsIHBhdHRlcm46IC8tfGHFvi8gfSk7XHJcbmNvbnN0IFNsYXNoID0gY3JlYXRlVG9rZW4oeyBuYW1lOiBcIkh5cGhlblwiLCBwYXR0ZXJuOiAvXFwvLyB9KTtcclxuY29uc3QgU3BhY2UgPSBjcmVhdGVUb2tlbih7XHJcbiAgbmFtZTogXCJTcGFjZVwiLFxyXG4gIHBhdHRlcm46IC8gKy8sXHJcbiAgbG9uZ2VyX2FsdDogW01haW5TZXBhcmF0b3IsIFNlcGFyYXRvcl0sXHJcbiAgZ3JvdXA6IExleGVyLlNLSVBQRUQsXHJcbn0pO1xyXG4vLyBjb25zdCBDb2xvbiA9IGNyZWF0ZVRva2VuKHtcclxuLy8gICBuYW1lOiBcIkNvbG9uXCIsXHJcbi8vICAgcGF0dGVybjogLzovLFxyXG4vLyAgIGdyb3VwOiBMZXhlci5TS0lQUEVELFxyXG4vLyB9KTtcclxuXHJcbmNvbnN0IHNtZFRva2VucyA9IFtcclxuICBNYWluU2VwYXJhdG9yLFxyXG4gIFNlcGFyYXRvcixcclxuICBPZGRUeXBlLFxyXG4gIEV2ZW5UeXBlLFxyXG4gIERlc2NyaXB0aXZlVHlwZSxcclxuICBBbGxUeXBlLFxyXG4gIE51bWJlcixcclxuICBGcm9tLFxyXG4gIFRvLFxyXG4gIEFuZEFib3ZlLFxyXG4gIEFuZEJlbG93LFxyXG4gIFdpdGhvdXQsXHJcbiAgSHlwaGVuLFxyXG4gIFNsYXNoLFxyXG4gIFNwYWNlLFxyXG4gIC8vIENvbG9uLFxyXG4gIE11bmljaXBhbGl0eVBhcnROYW1lLFxyXG4gIFN0cmVldE5hbWUsXHJcbl07XHJcblxyXG5NYWluU2VwYXJhdG9yLkxBQkVMID0gXCInIC0gJ1wiO1xyXG5TZXBhcmF0b3IuTEFCRUwgPSBcIicsJ1wiO1xyXG5IeXBoZW4uTEFCRUwgPSBcIictJ1wiO1xyXG5TbGFzaC5MQUJFTCA9IFwiJy8nXCI7XHJcbkZyb20uTEFCRUwgPSBcIidvZCdcIjtcclxuVG8uTEFCRUwgPSBcIidkbydcIjtcclxuQW5kQWJvdmUuTEFCRUwgPSBcIidhIHbDvcWhZSdcIjtcclxuQW5kQmVsb3cuTEFCRUwgPSBcIidhIG7DrcW+ZSdcIjtcclxuU3BhY2UuTEFCRUwgPSBcIicgJ1wiO1xyXG5PZGRUeXBlLkxBQkVMID0gXCInbGljaMOhIMSNLidcIjtcclxuRXZlblR5cGUuTEFCRUwgPSBcIidzdWTDoSDEjS4nXCI7XHJcbkRlc2NyaXB0aXZlVHlwZS5MQUJFTCA9IFwiJ8SNLiBwLidcIjtcclxuQWxsVHlwZS5MQUJFTCA9IFwiJ8SNLidcIjtcclxuV2l0aG91dC5MQUJFTCA9IFwiJ2JleidcIjtcclxuXHJcbmNvbnN0IHRva2VuVm9jYWJ1bGFyeTogVG9rZW5Wb2NhYnVsYXJ5ID0ge307XHJcblxyXG5zbWRUb2tlbnMuZm9yRWFjaCgodG9rZW5UeXBlKSA9PiB7XHJcbiAgdG9rZW5Wb2NhYnVsYXJ5W3Rva2VuVHlwZS5uYW1lXSA9IHRva2VuVHlwZTtcclxufSk7XHJcblxyXG5leHBvcnQge1xyXG4gIE1haW5TZXBhcmF0b3IsXHJcbiAgU2VwYXJhdG9yLFxyXG4gIE9kZFR5cGUsXHJcbiAgRXZlblR5cGUsXHJcbiAgRGVzY3JpcHRpdmVUeXBlLFxyXG4gIEFsbFR5cGUsXHJcbiAgTnVtYmVyLFxyXG4gIEZyb20sXHJcbiAgVG8sXHJcbiAgQW5kQWJvdmUsXHJcbiAgQW5kQmVsb3csXHJcbiAgV2l0aG91dCxcclxuICBIeXBoZW4sXHJcbiAgU2xhc2gsXHJcbiAgU3BhY2UsXHJcbiAgU3RyZWV0TmFtZSxcclxuICBNdW5pY2lwYWxpdHlQYXJ0TmFtZSxcclxuICBzbWRUb2tlbnMsXHJcbiAgdG9rZW5Wb2NhYnVsYXJ5LFxyXG59O1xyXG4iXX0=