@decaf-ts/utils 0.11.3 → 0.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/utils.cjs +2200 -2
  2. package/dist/utils.js +2216 -2
  3. package/lib/assets/slogans.cjs +1 -1
  4. package/lib/bin/build-scripts.cjs +1 -1
  5. package/lib/bin/tag-release.cjs +1 -1
  6. package/lib/cli/command.cjs +1 -1
  7. package/lib/cli/commands/build-scripts.cjs +1 -1
  8. package/lib/cli/commands/index.cjs +1 -1
  9. package/lib/cli/commands/tag-release.cjs +1 -1
  10. package/lib/cli/constants.cjs +1 -1
  11. package/lib/cli/index.cjs +1 -1
  12. package/lib/cli/types.cjs +1 -1
  13. package/lib/esm/assets/slogans.js +1 -1
  14. package/lib/esm/bin/build-scripts.js +1 -1
  15. package/lib/esm/bin/tag-release.js +1 -1
  16. package/lib/esm/cli/command.js +1 -1
  17. package/lib/esm/cli/commands/build-scripts.js +1 -1
  18. package/lib/esm/cli/commands/index.js +1 -1
  19. package/lib/esm/cli/commands/tag-release.js +1 -1
  20. package/lib/esm/cli/constants.js +1 -1
  21. package/lib/esm/cli/index.js +1 -1
  22. package/lib/esm/cli/types.js +1 -1
  23. package/lib/esm/index.js +1 -1
  24. package/lib/esm/input/index.js +1 -1
  25. package/lib/esm/input/input.js +1 -1
  26. package/lib/esm/input/types.js +1 -1
  27. package/lib/esm/output/common.js +1 -1
  28. package/lib/esm/output/index.js +1 -1
  29. package/lib/esm/tests/Consumer.js +1 -1
  30. package/lib/esm/tests/ProducerChildProcess.js +1 -1
  31. package/lib/esm/tests/TestReporter.js +1 -1
  32. package/lib/esm/tests/index.js +1 -1
  33. package/lib/esm/tests/utils.js +1 -1
  34. package/lib/esm/utils/constants.js +1 -1
  35. package/lib/esm/utils/fs.js +1 -1
  36. package/lib/esm/utils/http.js +1 -1
  37. package/lib/esm/utils/index.js +1 -1
  38. package/lib/esm/utils/md.js +1 -1
  39. package/lib/esm/utils/timeout.js +1 -1
  40. package/lib/esm/utils/types.js +1 -1
  41. package/lib/esm/utils/utils.js +1 -1
  42. package/lib/esm/writers/OutputWriter.js +1 -1
  43. package/lib/esm/writers/RegexpOutputWriter.js +1 -1
  44. package/lib/esm/writers/StandardOutputWriter.js +11 -4
  45. package/lib/esm/writers/index.js +1 -1
  46. package/lib/esm/writers/types.js +1 -1
  47. package/lib/index.cjs +1 -1
  48. package/lib/input/index.cjs +1 -1
  49. package/lib/input/input.cjs +1 -1
  50. package/lib/input/types.cjs +1 -1
  51. package/lib/output/common.cjs +1 -1
  52. package/lib/output/index.cjs +1 -1
  53. package/lib/tests/Consumer.cjs +1 -1
  54. package/lib/tests/ProducerChildProcess.cjs +1 -1
  55. package/lib/tests/TestReporter.cjs +1 -1
  56. package/lib/tests/index.cjs +1 -1
  57. package/lib/tests/utils.cjs +1 -1
  58. package/lib/utils/constants.cjs +1 -1
  59. package/lib/utils/fs.cjs +1 -1
  60. package/lib/utils/http.cjs +1 -1
  61. package/lib/utils/index.cjs +1 -1
  62. package/lib/utils/md.cjs +1 -1
  63. package/lib/utils/timeout.cjs +1 -1
  64. package/lib/utils/types.cjs +1 -1
  65. package/lib/utils/utils.cjs +1 -1
  66. package/lib/writers/OutputWriter.cjs +1 -1
  67. package/lib/writers/RegexpOutputWriter.cjs +1 -1
  68. package/lib/writers/StandardOutputWriter.cjs +11 -4
  69. package/lib/writers/index.cjs +1 -1
  70. package/lib/writers/types.cjs +1 -1
  71. package/package.json +3 -1
  72. package/dist/utils.cjs.map +0 -1
  73. package/dist/utils.js.map +0 -1
  74. package/lib/assets/slogans.js.map +0 -1
  75. package/lib/bin/build-scripts.js.map +0 -1
  76. package/lib/bin/tag-release.js.map +0 -1
  77. package/lib/cli/command.js.map +0 -1
  78. package/lib/cli/commands/build-scripts.js.map +0 -1
  79. package/lib/cli/commands/index.js.map +0 -1
  80. package/lib/cli/commands/tag-release.js.map +0 -1
  81. package/lib/cli/constants.js.map +0 -1
  82. package/lib/cli/index.js.map +0 -1
  83. package/lib/cli/types.js.map +0 -1
  84. package/lib/esm/assets/slogans.js.map +0 -1
  85. package/lib/esm/bin/build-scripts.js.map +0 -1
  86. package/lib/esm/bin/tag-release.js.map +0 -1
  87. package/lib/esm/cli/command.js.map +0 -1
  88. package/lib/esm/cli/commands/build-scripts.js.map +0 -1
  89. package/lib/esm/cli/commands/index.js.map +0 -1
  90. package/lib/esm/cli/commands/tag-release.js.map +0 -1
  91. package/lib/esm/cli/constants.js.map +0 -1
  92. package/lib/esm/cli/index.js.map +0 -1
  93. package/lib/esm/cli/types.js.map +0 -1
  94. package/lib/esm/index.js.map +0 -1
  95. package/lib/esm/input/index.js.map +0 -1
  96. package/lib/esm/input/input.js.map +0 -1
  97. package/lib/esm/input/types.js.map +0 -1
  98. package/lib/esm/output/common.js.map +0 -1
  99. package/lib/esm/output/index.js.map +0 -1
  100. package/lib/esm/tests/Consumer.js.map +0 -1
  101. package/lib/esm/tests/ProducerChildProcess.js.map +0 -1
  102. package/lib/esm/tests/TestReporter.js.map +0 -1
  103. package/lib/esm/tests/index.js.map +0 -1
  104. package/lib/esm/tests/utils.js.map +0 -1
  105. package/lib/esm/utils/constants.js.map +0 -1
  106. package/lib/esm/utils/fs.js.map +0 -1
  107. package/lib/esm/utils/http.js.map +0 -1
  108. package/lib/esm/utils/index.js.map +0 -1
  109. package/lib/esm/utils/md.js.map +0 -1
  110. package/lib/esm/utils/timeout.js.map +0 -1
  111. package/lib/esm/utils/types.js.map +0 -1
  112. package/lib/esm/utils/utils.js.map +0 -1
  113. package/lib/esm/writers/OutputWriter.js.map +0 -1
  114. package/lib/esm/writers/RegexpOutputWriter.js.map +0 -1
  115. package/lib/esm/writers/StandardOutputWriter.js.map +0 -1
  116. package/lib/esm/writers/index.js.map +0 -1
  117. package/lib/esm/writers/types.js.map +0 -1
  118. package/lib/index.js.map +0 -1
  119. package/lib/input/index.js.map +0 -1
  120. package/lib/input/input.js.map +0 -1
  121. package/lib/input/types.js.map +0 -1
  122. package/lib/output/common.js.map +0 -1
  123. package/lib/output/index.js.map +0 -1
  124. package/lib/tests/Consumer.js.map +0 -1
  125. package/lib/tests/ProducerChildProcess.js.map +0 -1
  126. package/lib/tests/TestReporter.js.map +0 -1
  127. package/lib/tests/index.js.map +0 -1
  128. package/lib/tests/utils.js.map +0 -1
  129. package/lib/utils/constants.js.map +0 -1
  130. package/lib/utils/fs.js.map +0 -1
  131. package/lib/utils/http.js.map +0 -1
  132. package/lib/utils/index.js.map +0 -1
  133. package/lib/utils/md.js.map +0 -1
  134. package/lib/utils/timeout.js.map +0 -1
  135. package/lib/utils/types.js.map +0 -1
  136. package/lib/utils/utils.js.map +0 -1
  137. package/lib/writers/OutputWriter.js.map +0 -1
  138. package/lib/writers/RegexpOutputWriter.js.map +0 -1
  139. package/lib/writers/StandardOutputWriter.js.map +0 -1
  140. package/lib/writers/index.js.map +0 -1
  141. package/lib/writers/types.js.map +0 -1
package/dist/utils.cjs CHANGED
@@ -1,2 +1,2200 @@
1
- var e,t;e=this,t=function(e,t,o,a,s,r,n,i,l,c,g,d,f,u,h,m,p){"use strict";function S(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function y(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(o=>{if("default"!==o){var a=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,a.get?a:{enumerable:!0,get:()=>e[o]})}}),t.default=e,Object.freeze(t)}var T=S(t),b=S(s),v=S(r),C=S(l),w=S(c),D=S(d),k=S(f),$=S(h),E=y(p);class I{static{this.logger=a.Logging.for(I)}constructor(e){this.type="text",this.name=e}setType(e){return I.logger.verbose("Setting type to: "+e),this.type=e,this}setMessage(e){return I.logger.verbose("Setting message to: "+e),this.message=e,this}setInitial(e){return I.logger.verbose("Setting initial value to: "+e),this.initial=e,this}setStyle(e){return I.logger.verbose("Setting style to: "+e),this.style=e,this}setFormat(e){return I.logger.verbose("Setting format function"),this.format=e,this}setValidate(e){return I.logger.verbose("Setting validate function"),this.validate=e,this}setOnState(e){return I.logger.verbose("Setting onState callback"),this.onState=e,this}setMin(e){return I.logger.verbose("Setting min value to: "+e),this.min=e,this}setMax(e){return I.logger.verbose("Setting max value to: "+e),this.max=e,this}setFloat(e){return I.logger.verbose("Setting float to: "+e),this.float=e,this}setRound(e){return I.logger.verbose("Setting round to: "+e),this.round=e,this}setInstructions(e){return I.logger.verbose("Setting instructions to: "+e),this.instructions=e,this}setIncrement(e){return I.logger.verbose("Setting increment to: "+e),this.increment=e,this}setSeparator(e){return I.logger.verbose("Setting separator to: "+e),this.separator=e,this}setActive(e){return I.logger.verbose("Setting active style to: "+e),this.active=e,this}setInactive(e){return I.logger.verbose("Setting inactive style to: "+e),this.inactive=e,this}setChoices(e){return I.logger.verbose("Setting choices: "+JSON.stringify(e)),this.choices=e,this}setHint(e){return I.logger.verbose("Setting hint to: "+e),this.hint=e,this}setWarn(e){return I.logger.verbose("Setting warn to: "+e),this.warn=e,this}setSuggest(e){return I.logger.verbose("Setting suggest function"),this.suggest=e,this}setLimit(e){return I.logger.verbose("Setting limit to: "+e),this.limit=e,this}setMask(e){return I.logger.verbose("Setting mask to: "+e),this.mask=e,this}setStdout(e){return I.logger.verbose("Setting stdout stream"),this.stdout=e,this}setStdin(e){return this.stdin=e,this}async ask(){return(await I.ask(this))[this.name]}static async ask(e){const t=I.logger.for(this.ask);let o;Array.isArray(e)||(e=[e]);try{t.verbose("Asking questions: "+e.map(e=>e.name).join(", ")),o=await T.default(e),t.verbose("Received answers: "+JSON.stringify(o,null,2))}catch(e){throw Error("Error while getting input: "+e)}return o}static async askNumber(e,t,o,a,s){I.logger.for(this.askNumber).verbose(`Asking number input: undefined, question: ${t}, min: ${o}, max: ${a}, initial: ${s}`);const r=new I(e).setMessage(t).setType("number");return"number"==typeof o&&r.setMin(o),"number"==typeof a&&r.setMax(a),"number"==typeof s&&r.setInitial(s),(await this.ask(r))[e]}static async askText(e,t,o=void 0,a){I.logger.for(this.askText).verbose(`Asking text input: undefined, question: ${t}, mask: ${o}, initial: ${a}`);const s=new I(e).setMessage(t);return o&&s.setMask(o),"string"==typeof a&&s.setInitial(a),(await this.ask(s))[e]}static async askConfirmation(e,t,o){I.logger.for(this.askConfirmation).verbose(`Asking confirmation input: undefined, question: ${t}, initial: ${o}`);const a=new I(e).setMessage(t).setType("confirm");return void 0!==o&&a.setInitial(o),(await this.ask(a))[e]}static async insist(e,t,o,a=1){const s=I.logger.for(this.insist);let r;s.verbose(`Insisting on input: ${e.name}, test: ${t.toString()}, defaultConfirmation: ${o}, limit: ${a}`);let n,i=0;try{do{r=(await I.ask(e))[e.name],t(r)?(n=await I.askConfirmation(e.name+"-confirm",`Is the ${e.type} correct?`,o),n||(r=void 0)):r=void 0}while(void 0===r&&a>1&&i++<a)}catch(e){throw s.error("Error while insisting: "+e),e}return void 0===r&&s.info("no selection..."),r}static async insistForText(e,t,o,a=void 0,s,r=!1,n=-1){I.logger.for(this.insistForText).verbose(`Insisting for text input: undefined, question: ${t}, test: ${o.toString()}, mask: ${a}, initial: ${s}, defaultConfirmation: ${r}, limit: ${n}`);const i=new I(e).setMessage(t);return a&&i.setMask(a),"string"==typeof s&&i.setInitial(s),await this.insist(i,o,r,n)}static async insistForNumber(e,t,o,a,s,r,n=!1,i=-1){I.logger.for(this.insistForNumber).verbose(`Insisting for number input: undefined, question: ${t}, test: ${o.toString()}, min: ${a}, max: ${s}, initial: ${r}, defaultConfirmation: ${n}, limit: ${i}`);const l=new I(e).setMessage(t).setType("number");return"number"==typeof a&&l.setMin(a),"number"==typeof s&&l.setMax(s),"number"==typeof r&&l.setInitial(r),await this.insist(l,o,n,i)}static parseArgs(e){const t=I.logger.for(this.parseArgs),a={args:process.argv.slice(2),options:e};t.debug("Parsing arguments: "+JSON.stringify(a,null,2));try{return o.parseArgs(a)}catch(o){throw t.debug(`Error while parsing arguments:\n${JSON.stringify(a,null,2)}\n | options\n${JSON.stringify(e,null,2)}\n | ${o}`),Error("Error while parsing arguments: "+o)}}}const F={verbose:{type:"boolean",short:"V",default:void 0},version:{type:"boolean",short:"v",default:void 0},help:{type:"boolean",short:"h",default:!1},logLevel:{type:"string",default:"info"},logStyle:{type:"boolean",default:!0},timestamp:{type:"boolean",default:!0},banner:{type:"boolean",default:!0}},A=Object.keys(F).reduce((e,t)=>(e[t]=F[t].default,e),{}),N="utf-8",j=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z])))/g;var x;e.SemVersion=void 0,(x=e.SemVersion||(e.SemVersion={})).PATCH="patch",x.MINOR="minor",x.MAJOR="major";const B="-no-ci";var M;e.Tokens=void 0,(M=e.Tokens||(e.Tokens={})).GIT=".token",M.NPM=".npmtoken",M.DOCKER=".dockertoken",M.CONFLUENCE=".confluence-token";const P="Aborted";class L{constructor(e,t,...o){this.cmd=e,this.lock=t,this.logger=a.Logging.for(this.cmd)}log(e,t){t=Buffer.isBuffer(t)?t.toString(N):t;const o="stderr"===e?i.style(t).red.text:t;this.logger.info(o)}data(e){this.log("stdout",e+"")}error(e){this.log("stderr",e+"")}errors(e){this.log("stderr","Error executing command exited : "+e)}exit(e,t){this.log("stdout","command exited code : "+(0===e?i.style(e.toString()).green.text:i.style(null===e?"null":e.toString()).red.text)),0===e?this.resolve(t.map(e=>e.trim()).join("\n")):this.reject(Error(t.length?t.join("\n"):e.toString()))}parseCommand(e){return e="string"==typeof e?e.split(" "):e,this.cmd=e.join(" "),[e[0],e.slice(1)]}resolve(e){this.log("stdout",`${this.cmd} executed successfully: ${i.style(e?"ran to completion":e).green}`),this.lock.resolve(e)}reject(e){e instanceof Error||(e=Error("number"==typeof e?"Exit code "+e:e)),this.log("stderr",`${this.cmd} failed to execute: ${i.style(e.message).red}`),this.lock.reject(e)}}function O(e,...t){let o,a;if(e instanceof AbortSignal?(a=new AbortController,o=[e,...t]):(a=e,o=t),a.signal.aborted)return a;const s=()=>a.abort();for(const e of o){if(e.aborted){a.abort();break}e.addEventListener("abort",s,{once:!0,signal:a.signal})}return a}function U(e,t,o,a,s){function r(t,a){const[r,i]=e.parseCommand(t);s.info("Running command: "+r),s.debug("with args: "+i.join(" "));const l=n.spawn(r,i,{...o,cwd:o.cwd||process.cwd(),env:Object.assign({},process.env,o.env,{PATH:process.env.PATH}),shell:o.shell||!1,signal:a.signal});return s.verbose("pid : "+l.pid),l}const i=t.match(/[<>$#]/g);if(i)throw Error(`Invalid command: ${t}. contains invalid characters: ${i}`);if(t.includes(" | ")){const e=t.split(" | "),o=[],s=Array(e.length);s[0]=a;for(let t=0;t<e.length;t++)0!==t&&(s[t]=O(s[t-1].signal)),o.push(r(e[t],s[t])),0!==t&&o[t-1].stdout.pipe(o[t].stdin);return o[e.length-1]}return r(t,a)}function R(e,t={},o=L,...s){const r=a.Logging.for(R),n=new AbortController,i={abort:n,command:e,logs:[],errs:[]},l=new Promise((a,l)=>{let c;try{c=new o(e,{resolve:a,reject:l},...s),i.cmd=U(c,e,t,n,r)}catch(t){return l(Error(`Error running command ${e}: ${t}`))}i.cmd.stdout.setEncoding("utf8"),i.cmd.stdout.on("data",e=>{e=e.toString(),i.logs.push(e),c.data(e)}),i.cmd.stderr.on("data",e=>{e=e.toString(),i.errs.push(e),c.error(e)}),i.cmd.once("error",e=>{c.exit(e.message,i.errs)}),i.cmd.once("exit",(e=0)=>{n.signal.aborted&&null===e&&(e=P),c.exit(e,0===e?i.logs:i.errs)})});return Object.assign(i,{promise:l,pipe:async t=>{const o=r.for("pipe");try{o.verbose(`Executing pipe function ${e}...`);const a=await l;return o.verbose(`Piping output to ${t.name}: ${a}`),t(a)}catch(e){throw o.error("Error piping command output: "+e),e}}}),i}const J=a.Logging.for("fs");function V(e,t,o){const s=J.for(V);if(!b.default.existsSync(e))throw Error(`File not found at path "${e}".`);let r=W(e);s.verbose(`Patching file "${e}"...`),s.debug("with value: "+JSON.stringify(t));try{r=((e,t,o="g",s)=>(Object.entries(t).forEach(([t,r])=>{const n=RegExp(a.escapeRegExp(t),o);e=e.replace(n,e=>(!s||s(e),r))}),e))(r,t,"g",o)}catch(e){throw Error("Error patching file: "+e)}K(e,r)}function W(e){const t=J.for(W);try{return t.verbose(`Reading file "${e}"...`),b.default.readFileSync(e,"utf8")}catch(o){throw t.verbose(`Error reading file "${e}": ${o}`),Error(`Error reading file "${e}": ${o}`)}}function K(e,t){const o=J.for(K);try{o.verbose(`Writing file "${e} with ${t.length} bytes...`),b.default.writeFileSync(e,t,"utf8")}catch(t){throw o.verbose(`Error writing file "${e}": ${t}`),Error(`Error writing file "${e}": ${t}`)}}function q(e,t){const o=J.for(q),a=[];try{return o.verbose(`Retrieving all files from "${e}"...`),b.default.readdirSync(e).forEach(t=>{const o=v.default.join(e,t),s=b.default.statSync(o);s.isFile()?a.push(o):s.isDirectory()&&a.push(...q(o))}),t?a.filter(t):a}catch(t){throw o.verbose(`Error retrieving files from "${e}": ${t}`),Error(`Error retrieving files from "${e}": ${t}`)}}async function _(e,t){const o=J.for(_);let a,s;try{a=b.default.statSync(e)}catch(t){throw o.verbose(`Source path "${e}" does not exist: ${t}`),Error(`Source path "${e}" does not exist: ${t}`)}try{s=b.default.statSync(t)}catch(e){}if(s)throw o.verbose(`Destination path "${t}" already exists`),Error(`Destination path "${t}" already exists`);try{o.verbose(`Renaming ${a.isFile()?"file":"directory"} "${e}" to "${t}...`),b.default.renameSync(e,t),o.verbose(`Successfully renamed to "${t}"`)}catch(s){throw o.verbose(`Error renaming ${a.isFile()?"file":"directory"} "${e}" to "${t}": ${s}`),Error(`Error renaming ${a.isFile()?"file":"directory"} "${e}" to "${t}": ${s}`)}}function G(e,t){const o=J.for(G);let a,s;try{a=b.default.statSync(e)}catch(t){throw o.verbose(`Source path "${e}" does not exist: ${t}`),Error(`Source path "${e}" does not exist: ${t}`)}try{s=b.default.statSync(t)}catch(e){a.isDirectory()&&(o.verbose(`Dest path "${t}" does not exist. creating`),b.default.mkdirSync(t,{recursive:!0}))}try{o.verbose(`Copying ${a.isFile()?"file":"directory"} "${e}" to "${t}...`),b.default.cpSync(e,t,{recursive:!0})}catch(s){throw o.verbose(`Error copying ${a.isFile()?"file":"directory"} "${e}" to "${t}: ${s}`),Error(`Error copying ${a.isFile()?"file":"directory"} "${e}" to "${t}: ${s}`)}}function X(e){const t=J.for(X);try{const o=b.default.statSync(e);o.isFile()?(t.verbose(`Deleting file "${e}...`),b.default.rmSync(e,{recursive:!0,force:!0})):o.isDirectory()&&b.default.rmSync(e,{recursive:!0,force:!0})}catch(o){throw t.verbose(`Error Deleting "${e}": ${o}`),Error(`Error Deleting "${e}": ${o}`)}}function z(e=process.cwd(),t){let o;try{o=JSON.parse(W(v.default.join(e,"package.json")))}catch(e){throw Error('Failed to retrieve package information" '+e)}if(t){if(!(t in o))throw Error(`Property "${t}" not found in package.json`);return o[t]}return o}function H(e=process.cwd()){return z(e,"version")}async function Y(e=process.cwd()){let t;try{t=JSON.parse(await R("npm ls --json",{cwd:e}).promise)}catch(e){throw Error("Failed to retrieve dependencies: "+e)}const o=(e,t)=>({name:e[0],version:e[1].version});return{prod:Object.entries(t.dependencies||{}).map(o),dev:Object.entries(t.devDependencies||{}).map(o),peer:Object.entries(t.peerDependencies||{}).map(o)}}async function Z(e){const t=J.for(Z),o=e.prod||[],a=e.dev||[],s=e.peer||[];o.length&&(t.info(`Installing dependencies ${o.join(", ")}...`),await R("npm install "+o.join(" "),{cwd:process.cwd()}).promise),a.length&&(t.info(`Installing devDependencies ${a.join(", ")}...`),await R("npm install --save-dev "+a.join(" "),{cwd:process.cwd()}).promise),s.length&&(t.info(`Installing peerDependencies ${s.join(", ")}...`),await R("npm install --save-peer "+s.join(" "),{cwd:process.cwd()}).promise)}async function Q(e){const t=J.for(Q);try{const o=b.default.readdirSync(e).map(t=>v.default.join(e,t)).filter(e=>{try{return b.default.statSync(e).isFile()&&(e.endsWith(".js")||e.endsWith(".cjs")||e.endsWith(".mjs"))}catch{return!1}});if(0===o.length)throw Error("No JS files found in directory "+e);let a=o[0],s=b.default.statSync(a).size;for(const e of o.slice(1)){const t=b.default.statSync(e).size;s>t&&(a=e,s=t)}t.verbose(`Selected smallest bundle: ${a} (${s} bytes)`);const r=b.default.readFileSync(a),n=C.default.gzipSync(r),i=Number((n.length/1024).toFixed(1));return t.verbose(`Gzipped size: ${n.length} bytes (${i} KB)`),i}catch(o){throw t.verbose(`Failed to compute gzipped size for ${e}: ${o}`),o}}function ee(e=v.default.join(process.cwd(),"node_modules")){const t=J.for(ee);try{if(!b.default.existsSync(e))return[];const o=b.default.readdirSync(e,{withFileTypes:!0}),a=[];for(const s of o)try{if(!s.isDirectory())continue;if(s.name.startsWith("."))continue;if(s.name.startsWith("@")){const o=v.default.join(e,s.name);try{const e=b.default.readdirSync(o,{withFileTypes:!0});for(const t of e)t.isDirectory()&&!t.name.startsWith(".")&&a.push(`${s.name}/${t.name}`)}catch(e){t.verbose(`Failed to read scope ${o}: ${e}`)}}else a.push(s.name)}catch(e){t.verbose(`Skipping entry ${s.name} due to error: ${e}`)}return a}catch(o){return t.verbose(`Failed to list node_modules packages at ${e}: ${o}`),[]}}const te=[{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That's Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"No caffeine, no chaos. Just clean code.",Tags:"Coffee-themed, Calm, Tech"},{Slogan:"Full flavor, no jitters. That\u2019s Decaf-TS.",Tags:"Coffee-themed, Cheerful"},{Slogan:"Chill fullstack. Powered by Decaf.",Tags:"Coffee-themed, Fun, Tech"},{Slogan:"Decaf-TS: Brewed for calm code.",Tags:"Coffee-themed, Branding"},{Slogan:"Smooth as your morning Decaf.",Tags:"Coffee-themed, Chill"},{Slogan:"All the kick, none of the crash.",Tags:"Coffee-themed, Energetic"},{Slogan:"Sip back and ship faster.",Tags:"Coffee-themed, Fun"},{Slogan:"Keep calm and code Decaf.",Tags:"Coffee-themed, Playful"},{Slogan:"Code without the caffeine shakes.",Tags:"Coffee-themed, Humorous"},{Slogan:"Your fullstack, decaffeinated.",Tags:"Coffee-themed, Technical"},{Slogan:"Decaf-TS: Where smart contracts meet smart interfaces.",Tags:"Blockchain, Smart Contracts, Tech"},{Slogan:"Ship dApps without the stress.",Tags:"Blockchain, Cheerful, Developer"},{Slogan:"No CRUD, no problem \u2014 Decaf your data.",Tags:"Data, No-CRUD, Chill"},{Slogan:"From DID to UI, without breaking a sweat.",Tags:"DID, SSI, UI, Calm"},{Slogan:"Decaf-TS: Your frontend already understands your smart contract.",Tags:"Smart Contracts, DX, Magic"},{Slogan:"Self-sovereign by design. Productive by default.",Tags:"SSI, Developer, Calm"},{Slogan:"Build once. Deploy everywhere. Decentralized and delightful.",Tags:"Blockchain, Multi-platform, Happy"},{Slogan:"Data that defines its own destiny.",Tags:"SSI, Data-driven, Empowerment"},{Slogan:"Goodbye CRUD, hello intent-based interfaces.",Tags:"No-CRUD, UI, Technical"},{Slogan:"The smoothest path from DID to done.",Tags:"DID, Workflow, Chill"},{Slogan:"Because your dApp deserves more than boilerplate.",Tags:"Blockchain, DevX, Efficiency"},{Slogan:"Own your data. Own your flow.",Tags:"SSI, Control, Ownership"},{Slogan:"Write logic like it belongs with the data \u2014 because it does.",Tags:"Data Logic, Developer, Smart"},{Slogan:"From smart contracts to smarter frontends.",Tags:"Smart Contracts, UI, DX"},{Slogan:"No caffeine. No CRUD. Just the future.",Tags:"No-CRUD, Coffee-themed, Futuristic"},{Slogan:"The future of web3 UX is Decaf.",Tags:"Blockchain, UX, Vision"},{Slogan:"Code with confidence. Govern with clarity.",Tags:"Blockchain, Governance, Calm"},{Slogan:"Interfaces that obey the data, not the other way around.",Tags:"UI, Data Logic, Self-aware"},{Slogan:"Brew business logic right into your bytes.",Tags:"Data Logic, Coffee-themed, Fun"},{Slogan:"DIDs done differently \u2014 and delightfully.",Tags:"DID, Self-Sovereign, Playful"},{Slogan:"Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",Tags:"Blockchain, Smart Contracts, Tech"},{Slogan:"Ship dApps without the stress.",Tags:"Blockchain, Cheerful, Developer"},{Slogan:"No boilerplate, no problem \u2014 Decaf-TS your data.",Tags:"Data, No-CRUD, Chill"},{Slogan:"From DID to UI, without breaking a sweat.",Tags:"DID, SSI, UI, Calm"},{Slogan:"Decaf-TS-TS: Your frontend already understands your blockchain contract.",Tags:"Smart Contracts, DX, Magic"},{Slogan:"Self-sovereign by design. Productive by default.",Tags:"SSI, Developer, Calm"},{Slogan:"Build once. Deploy everywhere. Decentralized and delightful.",Tags:"Blockchain, Multi-platform, Happy"},{Slogan:"Data that defines its own destiny.",Tags:"SSI, Data-driven, Empowerment"},{Slogan:"Goodbye boilerplate, hello intent-based interfaces.",Tags:"No-CRUD, UI, Technical"},{Slogan:"The smoothest path from DID to done.",Tags:"DID, Workflow, Chill"},{Slogan:"Because your dApp deserves more than boilerplate.",Tags:"Blockchain, DevX, Efficiency"},{Slogan:"Own your data. Own your flow.",Tags:"SSI, Control, Ownership"},{Slogan:"Write logic like it belongs with the data \u2014 because it does.",Tags:"Data Logic, Developer, Smart"},{Slogan:"From blockchain contracts to smarter frontends.",Tags:"Smart Contracts, UI, DX"},{Slogan:"No caffeine. No boilerplate. Just the future.",Tags:"No-CRUD, Coffee-themed, Futuristic"},{Slogan:"The future of web3 UX is Decaf-TS.",Tags:"Blockchain, UX, Vision"},{Slogan:"Code with confidence. Govern with clarity.",Tags:"Blockchain, Governance, Calm"},{Slogan:"Interfaces that obey the data, not the other way around.",Tags:"UI, Data Logic, Self-aware"},{Slogan:"Brew business logic right into your bytes.",Tags:"Data Logic, Coffee-themed, Fun"},{Slogan:"DIDs done differently \u2014 and delightfully.",Tags:"DID, Self-Sovereign, Playful"},{Slogan:"Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",Tags:"Blockchain, Smart Contracts, Tech"},{Slogan:"Ship dApps without the stress.",Tags:"Blockchain, Cheerful, Developer"},{Slogan:"No boilerplate, no problem \u2014 Decaf-TS your data.",Tags:"Data, No-CRUD, Chill"},{Slogan:"From DID to UI, without breaking a sweat.",Tags:"DID, SSI, UI, Calm"},{Slogan:"Decaf-TS-TS: Your frontend already understands your blockchain contract.",Tags:"Smart Contracts, DX, Magic"},{Slogan:"Self-sovereign by design. Productive by default.",Tags:"SSI, Developer, Calm"},{Slogan:"Build once. Deploy everywhere. Decentralized and delightful.",Tags:"Blockchain, Multi-platform, Happy"},{Slogan:"Data that defines its own destiny.",Tags:"SSI, Data-driven, Empowerment"},{Slogan:"Goodbye boilerplate, hello intent-based interfaces.",Tags:"No-CRUD, UI, Technical"},{Slogan:"The smoothest path from DID to done.",Tags:"DID, Workflow, Chill"},{Slogan:"Because your dApp deserves more than boilerplate.",Tags:"Blockchain, DevX, Efficiency"},{Slogan:"Own your data. Own your flow.",Tags:"SSI, Control, Ownership"},{Slogan:"Write logic like it belongs with the data \u2014 because it does.",Tags:"Data Logic, Developer, Smart"},{Slogan:"From blockchain contracts to smarter frontends.",Tags:"Smart Contracts, UI, DX"},{Slogan:"No caffeine. No boilerplate. Just the future.",Tags:"No-CRUD, Coffee-themed, Futuristic"},{Slogan:"The future of web3 UX is Decaf-TS.",Tags:"Blockchain, UX, Vision"},{Slogan:"Code with confidence. Govern with clarity.",Tags:"Blockchain, Governance, Calm"},{Slogan:"Interfaces that obey the data, not the other way around.",Tags:"UI, Data Logic, Self-aware"},{Slogan:"Brew business logic right into your bytes.",Tags:"Data Logic, Coffee-themed, Fun"},{Slogan:"DIDs done differently \u2014 and delightfully.",Tags:"DID, Self-Sovereign, Playful"},{Slogan:"Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",Tags:"Blockchain, Smart Contracts, Tech"},{Slogan:"Ship dApps without the stress.",Tags:"Blockchain, Cheerful, Developer"},{Slogan:"No boilerplate, no problem \u2014 Decaf-TS your data.",Tags:"Data, No-CRUD, Chill"},{Slogan:"From DID to UI, without breaking a sweat.",Tags:"DID, SSI, UI, Calm"},{Slogan:"Decaf-TS-TS: Your frontend already understands your blockchain contract.",Tags:"Smart Contracts, DX, Magic"},{Slogan:"Self-sovereign by design. Productive by default.",Tags:"SSI, Developer, Calm"},{Slogan:"Build once. Deploy everywhere. Decentralized and delightful.",Tags:"Blockchain, Multi-platform, Happy"},{Slogan:"Data that defines its own destiny.",Tags:"SSI, Data-driven, Empowerment"},{Slogan:"Goodbye boilerplate, hello intent-based interfaces.",Tags:"No-CRUD, UI, Technical"},{Slogan:"The smoothest path from DID to done.",Tags:"DID, Workflow, Chill"},{Slogan:"Because your dApp deserves more than boilerplate.",Tags:"Blockchain, DevX, Efficiency"},{Slogan:"Own your data. Own your flow.",Tags:"SSI, Control, Ownership"},{Slogan:"Write logic like it belongs with the data \u2014 because it does.",Tags:"Data Logic, Developer, Smart"},{Slogan:"From blockchain contracts to smarter frontends.",Tags:"Smart Contracts, UI, DX"},{Slogan:"No caffeine. No boilerplate. Just the future.",Tags:"No-CRUD, Coffee-themed, Futuristic"},{Slogan:"The future of web3 UX is Decaf-TS.",Tags:"Blockchain, UX, Vision"},{Slogan:"Code with confidence. Govern with clarity.",Tags:"Blockchain, Governance, Calm"},{Slogan:"Interfaces that obey the data, not the other way around.",Tags:"UI, Data Logic, Self-aware"},{Slogan:"Brew business logic right into your bytes.",Tags:"Data Logic, Coffee-themed, Fun"},{Slogan:"DIDs done differently \u2014 and delightfully.",Tags:"DID, Self-Sovereign, Playful"},{Slogan:"Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",Tags:"Blockchain, Smart Contracts, Tech"},{Slogan:"Ship dApps without the stress.",Tags:"Blockchain, Cheerful, Developer"},{Slogan:"No boilerplate, no problem \u2014 Decaf-TS your data.",Tags:"Data, No-CRUD, Chill"},{Slogan:"From DID to UI, without breaking a sweat.",Tags:"DID, SSI, UI, Calm"},{Slogan:"Decaf-TS-TS: Your frontend already understands your blockchain contract.",Tags:"Smart Contracts, DX, Magic"},{Slogan:"Self-sovereign by design. Productive by default.",Tags:"SSI, Developer, Calm"},{Slogan:"Build once. Deploy everywhere. Decentralized and delightful.",Tags:"Blockchain, Multi-platform, Happy"},{Slogan:"Data that defines its own destiny.",Tags:"SSI, Data-driven, Empowerment"},{Slogan:"Goodbye boilerplate, hello intent-based interfaces.",Tags:"No-CRUD, UI, Technical"},{Slogan:"The smoothest path from DID to done.",Tags:"DID, Workflow, Chill"},{Slogan:"Because your dApp deserves more than boilerplate.",Tags:"Blockchain, DevX, Efficiency"},{Slogan:"Own your data. Own your flow.",Tags:"SSI, Control, Ownership"},{Slogan:"Write logic like it belongs with the data \u2014 because it does.",Tags:"Data Logic, Developer, Smart"},{Slogan:"From blockchain contracts to smarter frontends.",Tags:"Smart Contracts, UI, DX"},{Slogan:"No caffeine. No boilerplate. Just the future.",Tags:"No-CRUD, Coffee-themed, Futuristic"},{Slogan:"The future of web3 UX is Decaf-TS.",Tags:"Blockchain, UX, Vision"},{Slogan:"Code with confidence. Govern with clarity.",Tags:"Blockchain, Governance, Calm"},{Slogan:"Interfaces that obey the data, not the other way around.",Tags:"UI, Data Logic, Self-aware"},{Slogan:"Brew business logic right into your bytes.",Tags:"Data Logic, Coffee-themed, Fun"},{Slogan:"DIDs done differently \u2014 and delightfully.",Tags:"DID, Self-Sovereign, Playful"}],oe=["\x1b[38;5;215m","\x1b[38;5;209m","\x1b[38;5;205m","\x1b[38;5;210m","\x1b[38;5;217m","\x1b[38;5;216m","\x1b[38;5;224m","\x1b[38;5;230m","\x1b[38;5;230m"];function ae(e){const t=se(),o="# \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \n# ( ( \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \n# ) ) \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \n# [=======] \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \n# `-----\xb4 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \n# \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \n# \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591\u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2593\u2592\u2591 \u2591\u2592\u2593\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2593\u2592\u2591 \n#".split("\n"),a=o.reduce((e,t)=>Math.max(e,t.length),0);o.push("# "+t.padStart(a-3)),o.forEach((t,o)=>{(e?e.info.bind(e):(()=>{}).bind())(i.style(t||"").raw(oe[o]).text)})}function se(e){try{return e=void 0===e?Math.floor(Math.random()*te.length):e,te[e].Slogan}catch(e){throw Error("Failed to retrieve slogans: "+e)}}class re extends a.LoggedClass{constructor(e,t={},o=[]){super(),this.name=e,this.inputs=t,this.requirements=o,re.log||Object.defineProperty(re,"log",{writable:!1,value:a.Logging.for(re.name)}),this.inputs=Object.assign({},F,t)}async checkRequirements(){const{prod:e,dev:t,peer:o}=await Y(),a=[],s=Array.from(new Set([...e,...t,...o]).values()).map(e=>e.name);for(const e of this.requirements)s.includes(e)||a.push(e);a.length}help(e){return this.log.info("This is help. I'm no use because I should have been overridden.")}async execute(){const e=I.parseArgs(this.inputs),t=a.LoggedEnvironment.accumulate(A).accumulate(e.values),{version:o,help:s,banner:r}=t;if(o)return H();if(s)return this.help(e);let n;r&&ae(this.log.for(ae,{timestamp:!1,style:!1,context:!1,logLevel:!1}));try{n=await this.run(t)}catch(e){throw e}return n}}class ne{static{this.log=a.Logging.for(ne)}static async downloadFile(e){return new Promise((t,o)=>{!function e(a){a=encodeURI(a),w.default.get(a,s=>{if(301===s.statusCode||307===s.statusCode)return e(s.headers.location);if(200!==s.statusCode)return ne.log.error(`Failed to fetch ${a} (status: ${s.statusCode})`),o(Error("Failed to fetch "+a));let r="";s.on("data",e=>{r+=e}),s.on("error",e=>{o(e)}),s.on("end",()=>{t(r)})})}(e)})}}function ie(e){return e?Array.isArray(e)?e.map(e=>(""+e).trim()).filter(Boolean):(""+e).split(",").map(e=>e.trim()).filter(Boolean):[]}function le(e){return e.replace(/^@/,"").split(/[/\-_.]+/).filter(Boolean).map((e,t)=>0===t?e.replace(/[^a-zA-Z0-9]/g,""):`${e.charAt(0).toUpperCase()}${e.slice(1)}`).join("")}function ce(){let e;try{e=z(process.cwd())}catch{e=void 0}try{if(!e||!(Object.keys(e.dependencies||{}).length>0||Object.keys(e.devDependencies||{}).length>0||Object.keys(e.peerDependencies||{}).length>0)){const t=v.default.resolve(__dirname,"../../..");try{e=z(t)}catch{}}}catch{}const t=Object.keys(e&&e.dependencies||{}),o=Object.keys(e&&e.peerDependencies||{}),a=Object.keys(e&&e.devDependencies||{});return Array.from(new Set([...t,...o,...a]))}const ge="##VERSION##",de="##PACKAGE##",fe="##PACKAGE_SIZE##";var ue,he;(e=>{e.CJS="commonjs",e.ESM="es2022"})(ue||(ue={})),(e=>{e.BUILD="build",e.BUNDLE="bundle",e.ALL="all"})(he||(he={}));const me={prod:{type:"boolean",default:!1},dev:{type:"boolean",default:!1},buildMode:{type:"string",default:he.ALL},includes:{type:"string",default:""},externals:{type:"string",default:""},docs:{type:"boolean",default:!1},commands:{type:"boolean",default:!1},banner:{type:"boolean",default:!1}},pe=(e=".cjs")=>{const t=Se.log.for(pe),o=new Map;return a=>s=>{const r=v.default.dirname(s.fileName);function n(a){const s=JSON.stringify([r,a]),n=o.get(s);if(null!=n)return n;let i,l=a;try{l=v.default.resolve(r,l+".ts")}catch(e){throw Error(`Failed to resolve path ${a}: ${e}`)}try{i=b.default.statSync(l)}catch(e){try{t.verbose(`Testing existence of path ${l} as a folder defaulting to index file`),i=b.default.statSync(l.replace(/\.ts$/gm,""))}catch(t){throw Error(`Failed to resolve path ${a}: ${e}, ${t}`)}}if(i.isDirectory()&&(l=l.replace(/\.ts$/gm,"/index.ts")),v.default.isAbsolute(l)){const t=(/\.tsx?$/.exec(v.default.basename(l))||[])[0]||void 0;l="./"+v.default.relative(r,v.default.resolve(v.default.dirname(l),v.default.basename(l,t)+e))}return o.set(s,l),l}return E.visitNode(s,function e(t){if((e=>!(!E.isImportDeclaration(e)&&!E.isExportDeclaration(e)||void 0===e.moduleSpecifier||!E.isStringLiteral(e.moduleSpecifier)||!e.moduleSpecifier.text.startsWith("./")&&!e.moduleSpecifier.text.startsWith("../")||""!==v.default.extname(e.moduleSpecifier.text)))(t)){if(E.isImportDeclaration(t)){const e=n(t.moduleSpecifier.text),o=a.factory.createStringLiteral(e);return a.factory.updateImportDeclaration(t,t.modifiers,t.importClause,o,void 0)}if(E.isExportDeclaration(t)){const e=n(t.moduleSpecifier.text),o=a.factory.createStringLiteral(e);return a.factory.updateExportDeclaration(t,t.modifiers,t.isTypeOnly,t.exportClause,o,void 0)}}return E.visitEachChild(t,e,a)})}};class Se extends re{constructor(){super("BuildScripts",Object.assign({},F,me)),this.replacements={};const e=z(),{name:t,version:o}=e;this.pkgName=t.includes("@")?t.split("/")[1]:t,this.pkgVersion=o,this.replacements[ge]=this.pkgVersion,this.replacements[de]=t}patchFiles(e){const t=this.log.for(this.patchFiles),{name:o,version:a}=z();t.info(`Patching ${o} ${a} module in ${e}...`),b.default.statSync(e).isDirectory()&&b.default.readdirSync(e,{withFileTypes:!0,recursive:!0}).filter(e=>e.isFile()).forEach(e=>V(v.default.join(e.parentPath,e.name),Object.entries(this.replacements).reduce((e,[o,a])=>{switch(o){case ge:t.debug("Found VERSION string to replace"),e[`VERSION = "${ge}";`]=`VERSION = "${a}";`;break;case de:t.debug("Found PACKAGE_NAME string to replace"),e[`PACKAGE_NAME = "${de}";`]=`PACKAGE_NAME = "${a}";`;break;default:e[o]=a}return e},{}))),t.verbose(`Module ${o} ${a} patched in ${e}...`)}reportDiagnostics(e,t){const o=this.formatDiagnostics(e);try{this.log[t](o)}catch(e){throw e}return o}formatDiagnostics(e){return e.map(e=>{let t="";if(e.file&&e.start){const{line:o,character:a}=e.file.getLineAndCharacterOfPosition(e.start);t+=`${e.file.fileName} (${o+1},${a+1})`}return t+=": "+E.flattenDiagnosticMessageText(e.messageText,"\n"),t}).join("\n")}readConfigFile(e){const t=b.default.readFileSync(e).toString(),o=E.parseConfigFileTextToJson(e,t),s=o.config;s||this.reportDiagnostics([o.error],a.LogLevel.error);const r=E.parseJsonConfigFileContent(s,E.sys,v.default.dirname(e));return r.errors.length>0&&this.reportDiagnostics(r.errors,a.LogLevel.error),r}evalDiagnostics(e){if(e&&e.length>0){const t=e.filter(e=>e.category===E.DiagnosticCategory.Error),o=e.filter(e=>e.category===E.DiagnosticCategory.Warning),s=e.filter(e=>e.category===E.DiagnosticCategory.Suggestion),r=e.filter(e=>e.category===E.DiagnosticCategory.Message);if(o.length&&this.reportDiagnostics(o,a.LogLevel.warn),t.length)throw this.reportDiagnostics(e,a.LogLevel.error),Error(`TypeScript reported ${e.length} diagnostic(s) during check; aborting.`);s.length&&this.reportDiagnostics(s,a.LogLevel.info),r.length&&this.reportDiagnostics(r,a.LogLevel.info)}}preCheckDiagnostics(e){const t=E.getPreEmitDiagnostics(e);this.evalDiagnostics(t)}async checkTsDiagnostics(e,t,o=!1){const a=this.log.for(this.checkTsDiagnostics);let s;try{s=this.readConfigFile("./tsconfig.json")}catch(e){throw Error("Failed to parse tsconfig.json: "+e)}o?(s.options.module=p.ModuleKind.AMD,s.options.outDir="dist",s.options.isolatedModules=!1,s.options.outFile=this.pkgName):(s.options.outDir="lib"+(t===ue.ESM?"/esm":""),s.options.module=t===ue.ESM?p.ModuleKind.ES2022:p.ModuleKind.CommonJS),s.options.inlineSourceMap=!1,s.options.inlineSources=!1,s.options.sourceMap=!0;const r=E.createProgram(s.fileNames,s.options);this.preCheckDiagnostics(r),a.verbose(`TypeScript checks passed (${o?"bundle":"normal"} mode).`)}async buildTs(e,t,o=!1){let a;this.log.for(this.buildTs).info(`Building ${this.pkgName} ${this.pkgVersion} module (${t}) in ${e?"dev":"prod"} mode...`);try{a=this.readConfigFile("./tsconfig.json")}catch(e){throw Error("Failed to parse tsconfig.json: "+e)}o?(a.options.module=p.ModuleKind.AMD,a.options.outDir="dist",a.options.isolatedModules=!1,a.options.outFile=this.pkgName):(a.options.outDir="lib"+(t===ue.ESM?"/esm":""),a.options.module=t===ue.ESM?p.ModuleKind.ES2022:p.ModuleKind.CommonJS),e?(a.options.inlineSourceMap=!0,a.options.inlineSources=!0,a.options.sourceMap=!1):(a.options.inlineSourceMap=!1,a.options.inlineSources=!1,a.options.sourceMap=!0);const s=E.createProgram(a.fileNames,a.options),r={};t===ue.CJS?r.before=[pe(".cjs")]:t===ue.ESM&&(r.before=[pe(".js")]);const n=s.emit(void 0,void 0,void 0,void 0,r),i=E.getPreEmitDiagnostics(s).concat(n.diagnostics);this.evalDiagnostics(i)}async build(e,t,o=!1){const a=this.log.for(this.build);if(await this.buildTs(e,t,o),a.verbose(`Module ${this.pkgName} ${this.pkgVersion} (${t}) built in ${e?"dev":"prod"} mode...`),t===ue.CJS&&!o){const e=q("lib",e=>e.endsWith(".js")&&!e.includes("/esm/"));for(const t of e){a.verbose(`Patching ${t}'s cjs imports...`);const e=t.replace(".js",".cjs");await _(t,e)}}}copyAssets(e){const t=this.log.for(this.copyAssets);let o=!1;try{o=b.default.statSync("./src/assets").isDirectory()}catch(e){return t.verbose("No assets found in ./src/assets to copy")}o&&G("./src/assets",`./${e===ue.CJS?"lib":"dist"}/assets`)}async bundle(e,t,o,a="src/index.ts",s=this.pkgName,r,n=["prompts","styled-string-builder","typed-object-accumulator","@decaf-ts/logging"]){await this.checkTsDiagnostics(t,e,!0);const i=e===ue.ESM,l=this.pkgName,c=this.log,d=Array.from(new Set([...ie(n)]));let f=ie(r);if(0===f.length){try{f=ee(v.default.join(process.cwd(),"node_modules"))}catch{}f&&0!==f.length||(f=ce())}const h=Array.from(new Set([...(()=>{try{return Array.isArray(m.builtinModules)?m.builtinModules:[]}catch{return["fs","path","process","child_process","util","https","http","os","stream","crypto","zlib","net","tls","url","querystring","assert","events","tty","dns","querystring"]}})(),...f])),p=!t||"inline",S=[D.default({compilerOptions:{module:"esnext",declaration:!1,outDir:o?"bin":"dist",sourceMap:!t,inlineSourceMap:!!t,inlineSources:!!t},include:["src/**/*.ts"],exclude:["node_modules","**/*.spec.ts"],tsconfig:"./tsconfig.json"}),$.default()];o&&S.push(k.default({include:[],exclude:f}),u.nodeResolve({resolveOnly:d}));try{const C=await import("@rollup/plugin-terser"),w=C&&C.terser||C.default||C,E={parse:{ecma:2020},compress:!1,mangle:!1,format:{comments:!1,beautify:!0}},I={parse:{ecma:2020},compress:{ecma:2020,passes:5,drop_console:!0,drop_debugger:!0,toplevel:!0,module:i,unsafe:!0,unsafe_arrows:!0,unsafe_comps:!0,collapse_vars:!0,reduce_funcs:!0,reduce_vars:!0},mangle:{toplevel:!0},format:{comments:!1,ascii_only:!0},toplevel:!0};S.push(w(t?E:I))}catch{}const y={input:a,plugins:S,external:h,onwarn:void 0,treeshake:!t},T={};h.forEach(e=>{T[e]=le(e)});const b=[{file:`${o?"bin/":"dist/"}${s||".bundle."+(t?"":"min")}${i?".js":".cjs"}`,format:o?"cjs":i?"esm":"umd",name:l,esModule:i,sourcemap:p,globals:T,exports:"auto"}];try{const F=await g.rollup(y);async function A(e){for(const t of b)await e.write(t)}c.verbose(F.watchFiles),await A(F)}catch(N){throw Error("Failed to bundle: "+N)}}async buildByEnv(e,t=he.ALL,o,a){try{X("lib")}catch(e){}try{X("dist")}catch(e){}b.default.mkdirSync("lib"),b.default.mkdirSync("dist"),[he.ALL,he.BUILD].includes(t)&&(await this.build(e,ue.ESM),await this.build(e,ue.CJS),this.patchFiles("lib")),[he.ALL,he.BUNDLE].includes(t)&&(await this.bundle(ue.ESM,e,!1,"src/index.ts",this.pkgName,a,o),await this.bundle(ue.CJS,e,!1,"src/index.ts",this.pkgName,a,o),this.patchFiles("dist")),this.copyAssets(ue.CJS),this.copyAssets(ue.ESM)}async buildDev(e=he.ALL,t,o){return this.buildByEnv(!0,e,t,o)}async buildProd(e=he.ALL,t,o){return this.buildByEnv(!1,e,t,o)}async buildDocs(){await R("npm install better-docs taffydb").promise,await R("npx markdown-include ./workdocs/readme-md.json").promise,await R("npx jsdoc -c ./workdocs/jsdocs.json -t ./node_modules/better-docs").promise,await R("npm remove better-docs taffydb").promise,[{src:"workdocs/assets",dest:"./docs/workdocs/assets"},{src:"workdocs/reports/coverage",dest:"./docs/workdocs/reports/coverage"},{src:"workdocs/reports/html",dest:"./docs/workdocs/reports/html"},{src:"workdocs/resources",dest:"./docs/workdocs/resources"},{src:"LICENSE.md",dest:"./docs/LICENSE.md"}].forEach(e=>{const{src:t,dest:o}=e;G(t,o)});try{const e=await Q(v.default.resolve(v.default.join(process.cwd(),"dist")));this.replacements[fe]=e+" KB"}catch{this.replacements[fe]="unknown"}try{V("./README.md",this.replacements)}catch(e){this.log.for(this.buildDocs).verbose("Failed to patch README.md: "+e)}}async run(e){const{dev:t,prod:o,docs:a,buildMode:s,includes:r,externals:n}=e;return t?await this.buildDev(s,r,n):o?await this.buildProd(s,r,n):a?await this.buildDocs():void 0}}const ye={ci:{type:"boolean",default:!0},message:{type:"string",short:"m"},tag:{type:"string",short:"t",default:void 0}};e.AbortCode=P,e.BuildScripts=Se,e.Command=re,e.DefaultCommandOptions=F,e.DefaultCommandValues=A,e.Encoding=N,e.HttpClient=ne,e.NoCIFLag=B,e.PACKAGE_NAME="##PACKAGE##",e.RegexpOutputWriter=class extends L{constructor(e,t,o,a="g"){super(e,t);try{this.regexp="string"==typeof o?RegExp(o,a):o}catch(e){throw Error("Invalid regular expression: "+e)}}test(e){let t;this.regexp.lastIndex=0;try{t=this.regexp.exec(e)}catch(e){return}return t}testAndResolve(e){const t=this.test(e);t&&this.resolve(t[0])}testAndReject(e){const t=this.test(e);t&&this.reject(t[0])}data(e){super.data(e),this.testAndResolve(e+"")}error(e){super.error(e),this.testAndReject(e+"")}},e.ReleaseScript=class extends re{constructor(){super("ReleaseScript",ye)}async prepareVersion(e){const t=this.log.for(this.prepareVersion);return(e=this.testVersion(e||""))||(t.verbose("No release message provided. Prompting for one:"),t.info("Listing latest git tags:"),await R("git tag --sort=-taggerdate | head -n 5").promise,await I.insistForText("tag","Enter the new tag number (accepts v*.*.*[-...])",e=>!!e.toString().match(/^v[0-9]+\.[0-9]+.[0-9]+(-[0-9a-zA-Z-]+)?$/)))}testVersion(t){const o=this.log.for(this.testVersion);switch(t=t.trim().toLowerCase()){case e.SemVersion.PATCH:case e.SemVersion.MINOR:case e.SemVersion.MAJOR:return o.verbose("Using provided SemVer update: "+t,1),t;default:return o.verbose("Testing provided version for SemVer compatibility: "+t,1),RegExp(j).test(t)?(o.verbose("version approved: "+t,1),t):void o.debug("Invalid version number: "+t)}}async prepareMessage(e){const t=this.log.for(this.prepareMessage);return e||(t.verbose("No release message provided. Prompting for one"),await I.insistForText("message","What should be the release message/ticket?",e=>!!e&&e.toString().length>5))}async run(e){let t;const{ci:o}=e;let{tag:a,message:s}=e;a=await this.prepareVersion(a),s=await this.prepareMessage(s),t=await R(`npm run prepare-release -- ${a} ${s}`,{cwd:process.cwd()}).promise,t=await R("git status --porcelain").promise,await t,t.logs.length&&await I.askConfirmation("git-changes","Do you want to push the changes to the remote repository?",!0)&&(await R("git add .").promise,await R(`git commit -m "${a} - ${s} - after release preparation${o?"":B}"`).promise),await R(`npm version "${a}" -m "${s}${o?"":B}"`).promise,await R("git push --follow-tags").promise,o||await R("NPM_TOKEN=$(cat .npmtoken) npm publish --access public").promise}},e.SemVersionRegex=j,e.SetupScriptKey="postinstall",e.StandardOutputWriter=L,e.UserInput=I,e.VERSION="##VERSION##",e.chainAbortController=O,e.copyFile=G,e.deletePath=X,e.getAllFiles=q,e.getDependencies=Y,e.getFileSizeZipped=Q,e.getPackage=z,e.getPackageDependencies=ce,e.getPackageVersion=H,e.getSlogan=se,e.installDependencies=Z,e.installIfNotAvailable=async(e,t)=>{if(!t){const e=await Y();t={prod:e.prod?.map(e=>e.name)||[],dev:e.dev?.map(e=>e.name)||[],peer:e.peer?.map(e=>e.name)||[]}}const{prod:o,dev:a,peer:s}=t,r=Array.from(new Set([...o||[],...a||[],...s||[]])),n=(e="string"==typeof e?[e]:e).filter(e=>!r.includes(e));return n.length&&await Z({dev:n}),t.dev=t.dev||[],t.dev.push(...n),t},e.listFolder=function e(t=process.cwd(),o){const a=J.for(e);try{return b.default.existsSync(t)?b.default.readdirSync(t,{withFileTypes:!0}).filter(e=>!o||o(e.name,e)).map(e=>e.name):[]}catch(e){return a.verbose(`Failed to list folder ${t}: ${e}`),[]}},e.listNodeModulesPackages=ee,e.lockify=e=>{let t=Promise.resolve();return(...o)=>{const a=t.then(()=>e(...o));return t=a.catch(()=>{}),a}},e.normalizeImport=async e=>e.then(e=>e.default||e),e.packageToGlobal=le,e.parseList=ie,e.patchFile=V,e.printBanner=ae,e.pushToGit=async function e(){const t=J.for(e),o=await R("git config user.name").promise,a=await R("git config user.email").promise;t.verbose(`cached git id: ${o}/${a}. changing to automation`),await R('git config user.email "automation@decaf.ts"').promise,await R('git config user.name "decaf"').promise,t.info("Pushing changes to git..."),await R("git add .").promise,await R('git commit -m "refs #1 - after repo setup"').promise,await R("git push").promise,await R(`git config user.email "${a}"`).promise,await R(`git config user.name "${o}"`).promise,t.verbose(`reverted to git id: ${o}/${a}`)},e.readFile=W,e.renameFile=_,e.runCommand=R,e.setPackageAttribute=(e,t,o=process.cwd())=>{const a=z(o);a[e]=t,K(v.default.join(o,"package.json"),JSON.stringify(a,null,2))},e.spawnCommand=U,e.updateDependencies=async function e(){const t=J.for(e);t.info("checking for updates..."),await R("npx npm-check-updates -u").promise,t.info("updating..."),await R("npx npm run do-install").promise},e.writeFile=K},"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("prompts"),require("util"),require("@decaf-ts/logging"),require("fs"),require("path"),require("child_process"),require("styled-string-builder"),require("zlib"),require("https"),require("rollup"),require("@rollup/plugin-typescript"),require("@rollup/plugin-commonjs"),require("@rollup/plugin-node-resolve"),require("@rollup/plugin-json"),require("module"),require("typescript")):"function"==typeof define&&define.amd?define(["exports","prompts","util","@decaf-ts/logging","fs","path","child_process","styled-string-builder","zlib","https","rollup","@rollup/plugin-typescript","@rollup/plugin-commonjs","@rollup/plugin-node-resolve","@rollup/plugin-json","module","typescript"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).utils={},e.prompts,e.util,e.decafTsLogging,e.fs,e.path,e.childProcess,e.styledStringBuilder,e.zlib,e.https,e.rollup,e.rollupPluginTypescript,e.rollupPluginCommonjs,e.rollupPluginNodeResolve,e.rollupPluginJson,e.module,e.typescript);
2
- //# sourceMappingURL=utils.cjs.map
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("prompts"), require("util"), require("@decaf-ts/logging"), require("fs"), require("path"), require("child_process"), require("styled-string-builder"), require("shell-quote"), require("zlib"), require("https"), require("rollup"), require("@rollup/plugin-typescript"), require("@rollup/plugin-commonjs"), require("@rollup/plugin-node-resolve"), require("@rollup/plugin-json"), require("module"), require("typescript")) : typeof define === "function" && define.amd ? define([ "exports", "prompts", "util", "@decaf-ts/logging", "fs", "path", "child_process", "styled-string-builder", "shell-quote", "zlib", "https", "rollup", "@rollup/plugin-typescript", "@rollup/plugin-commonjs", "@rollup/plugin-node-resolve", "@rollup/plugin-json", "module", "typescript" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
3
+ factory(global.utils = {}, global.prompts, global.util, global.decafTsLogging, global.fs, global.path, global.childProcess, global.styledStringBuilder, global.shellQuote, global.zlib, global.https, global.rollup, global.rollupPluginTypescript, global.rollupPluginCommonjs, global.rollupPluginNodeResolve, global.rollupPluginJson, global.module, global.typescript));
4
+ })(this, function(exports, prompts, util, logging, fs, path, child_process, styledStringBuilder, shellQuote, zlib, https, rollup, typescript, commonjs, pluginNodeResolve, json, module, ts) {
5
+ "use strict";
6
+ function _interopDefaultLegacy(e) {
7
+ return e && typeof e === "object" && "default" in e ? e : {
8
+ default: e
9
+ };
10
+ }
11
+ function _interopNamespace(e) {
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function(k) {
16
+ if (k !== "default") {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function() {
21
+ return e[k];
22
+ }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n["default"] = e;
28
+ return Object.freeze(n);
29
+ }
30
+ var prompts__default = _interopDefaultLegacy(prompts);
31
+ var fs__default = _interopDefaultLegacy(fs);
32
+ var path__default = _interopDefaultLegacy(path);
33
+ var zlib__default = _interopDefaultLegacy(zlib);
34
+ var https__default = _interopDefaultLegacy(https);
35
+ var typescript__default = _interopDefaultLegacy(typescript);
36
+ var commonjs__default = _interopDefaultLegacy(commonjs);
37
+ var json__default = _interopDefaultLegacy(json);
38
+ var ts__namespace = _interopNamespace(ts);
39
+ class UserInput {
40
+ static {
41
+ this.logger = logging.Logging.for(UserInput);
42
+ }
43
+ constructor(name) {
44
+ this.type = "text";
45
+ this.name = name;
46
+ }
47
+ setType(type) {
48
+ UserInput.logger.verbose(`Setting type to: ${type}`);
49
+ this.type = type;
50
+ return this;
51
+ }
52
+ setMessage(value) {
53
+ UserInput.logger.verbose(`Setting message to: ${value}`);
54
+ this.message = value;
55
+ return this;
56
+ }
57
+ setInitial(value) {
58
+ UserInput.logger.verbose(`Setting initial value to: ${value}`);
59
+ this.initial = value;
60
+ return this;
61
+ }
62
+ setStyle(value) {
63
+ UserInput.logger.verbose(`Setting style to: ${value}`);
64
+ this.style = value;
65
+ return this;
66
+ }
67
+ setFormat(value) {
68
+ UserInput.logger.verbose(`Setting format function`);
69
+ this.format = value;
70
+ return this;
71
+ }
72
+ setValidate(value) {
73
+ UserInput.logger.verbose(`Setting validate function`);
74
+ this.validate = value;
75
+ return this;
76
+ }
77
+ setOnState(value) {
78
+ UserInput.logger.verbose(`Setting onState callback`);
79
+ this.onState = value;
80
+ return this;
81
+ }
82
+ setMin(value) {
83
+ UserInput.logger.verbose(`Setting min value to: ${value}`);
84
+ this.min = value;
85
+ return this;
86
+ }
87
+ setMax(value) {
88
+ UserInput.logger.verbose(`Setting max value to: ${value}`);
89
+ this.max = value;
90
+ return this;
91
+ }
92
+ setFloat(value) {
93
+ UserInput.logger.verbose(`Setting float to: ${value}`);
94
+ this.float = value;
95
+ return this;
96
+ }
97
+ setRound(value) {
98
+ UserInput.logger.verbose(`Setting round to: ${value}`);
99
+ this.round = value;
100
+ return this;
101
+ }
102
+ setInstructions(value) {
103
+ UserInput.logger.verbose(`Setting instructions to: ${value}`);
104
+ this.instructions = value;
105
+ return this;
106
+ }
107
+ setIncrement(value) {
108
+ UserInput.logger.verbose(`Setting increment to: ${value}`);
109
+ this.increment = value;
110
+ return this;
111
+ }
112
+ setSeparator(value) {
113
+ UserInput.logger.verbose(`Setting separator to: ${value}`);
114
+ this.separator = value;
115
+ return this;
116
+ }
117
+ setActive(value) {
118
+ UserInput.logger.verbose(`Setting active style to: ${value}`);
119
+ this.active = value;
120
+ return this;
121
+ }
122
+ setInactive(value) {
123
+ UserInput.logger.verbose(`Setting inactive style to: ${value}`);
124
+ this.inactive = value;
125
+ return this;
126
+ }
127
+ setChoices(value) {
128
+ UserInput.logger.verbose(`Setting choices: ${JSON.stringify(value)}`);
129
+ this.choices = value;
130
+ return this;
131
+ }
132
+ setHint(value) {
133
+ UserInput.logger.verbose(`Setting hint to: ${value}`);
134
+ this.hint = value;
135
+ return this;
136
+ }
137
+ setWarn(value) {
138
+ UserInput.logger.verbose(`Setting warn to: ${value}`);
139
+ this.warn = value;
140
+ return this;
141
+ }
142
+ setSuggest(value) {
143
+ UserInput.logger.verbose(`Setting suggest function`);
144
+ this.suggest = value;
145
+ return this;
146
+ }
147
+ setLimit(value) {
148
+ UserInput.logger.verbose(`Setting limit to: ${value}`);
149
+ this.limit = value;
150
+ return this;
151
+ }
152
+ setMask(value) {
153
+ UserInput.logger.verbose(`Setting mask to: ${value}`);
154
+ this.mask = value;
155
+ return this;
156
+ }
157
+ setStdout(value) {
158
+ UserInput.logger.verbose(`Setting stdout stream`);
159
+ this.stdout = value;
160
+ return this;
161
+ }
162
+ setStdin(value) {
163
+ this.stdin = value;
164
+ return this;
165
+ }
166
+ async ask() {
167
+ return (await UserInput.ask(this))[this.name];
168
+ }
169
+ static async ask(question) {
170
+ const log = UserInput.logger.for(this.ask);
171
+ if (!Array.isArray(question)) {
172
+ question = [ question ];
173
+ }
174
+ let answers;
175
+ try {
176
+ log.verbose(`Asking questions: ${question.map(q => q.name).join(", ")}`);
177
+ answers = await prompts__default["default"](question);
178
+ log.verbose(`Received answers: ${JSON.stringify(answers, null, 2)}`);
179
+ } catch (error) {
180
+ throw new Error(`Error while getting input: ${error}`);
181
+ }
182
+ return answers;
183
+ }
184
+ static async askNumber(name, question, min, max, initial) {
185
+ const log = UserInput.logger.for(this.askNumber);
186
+ log.verbose(`Asking number input: undefined, question: ${question}, min: ${min}, max: ${max}, initial: ${initial}`);
187
+ const userInput = new UserInput(name).setMessage(question).setType("number");
188
+ if (typeof min === "number") userInput.setMin(min);
189
+ if (typeof max === "number") userInput.setMax(max);
190
+ if (typeof initial === "number") userInput.setInitial(initial);
191
+ return (await this.ask(userInput))[name];
192
+ }
193
+ static async askText(name, question, mask = undefined, initial) {
194
+ const log = UserInput.logger.for(this.askText);
195
+ log.verbose(`Asking text input: undefined, question: ${question}, mask: ${mask}, initial: ${initial}`);
196
+ const userInput = new UserInput(name).setMessage(question);
197
+ if (mask) userInput.setMask(mask);
198
+ if (typeof initial === "string") userInput.setInitial(initial);
199
+ return (await this.ask(userInput))[name];
200
+ }
201
+ static async askConfirmation(name, question, initial) {
202
+ const log = UserInput.logger.for(this.askConfirmation);
203
+ log.verbose(`Asking confirmation input: undefined, question: ${question}, initial: ${initial}`);
204
+ const userInput = new UserInput(name).setMessage(question).setType("confirm");
205
+ if (typeof initial !== "undefined") userInput.setInitial(initial);
206
+ return (await this.ask(userInput))[name];
207
+ }
208
+ static async insist(input, test, defaultConfirmation, limit = 1) {
209
+ const log = UserInput.logger.for(this.insist);
210
+ log.verbose(`Insisting on input: ${input.name}, test: ${test.toString()}, defaultConfirmation: ${defaultConfirmation}, limit: ${limit}`);
211
+ let result = undefined;
212
+ let count = 0;
213
+ let confirmation;
214
+ try {
215
+ do {
216
+ result = (await UserInput.ask(input))[input.name];
217
+ if (!test(result)) {
218
+ result = undefined;
219
+ continue;
220
+ }
221
+ confirmation = await UserInput.askConfirmation(`${input.name}-confirm`, `Is the ${input.type} correct?`, defaultConfirmation);
222
+ if (!confirmation) result = undefined;
223
+ } while (typeof result === "undefined" && limit > 1 && count++ < limit);
224
+ } catch (e) {
225
+ log.error(`Error while insisting: ${e}`);
226
+ throw e;
227
+ }
228
+ if (typeof result === "undefined") log.info("no selection...");
229
+ return result;
230
+ }
231
+ static async insistForText(name, question, test, mask = undefined, initial, defaultConfirmation = false, limit = -1) {
232
+ const log = UserInput.logger.for(this.insistForText);
233
+ log.verbose(`Insisting for text input: undefined, question: ${question}, test: ${test.toString()}, mask: ${mask}, initial: ${initial}, defaultConfirmation: ${defaultConfirmation}, limit: ${limit}`);
234
+ const userInput = new UserInput(name).setMessage(question);
235
+ if (mask) userInput.setMask(mask);
236
+ if (typeof initial === "string") userInput.setInitial(initial);
237
+ return await this.insist(userInput, test, defaultConfirmation, limit);
238
+ }
239
+ static async insistForNumber(name, question, test, min, max, initial, defaultConfirmation = false, limit = -1) {
240
+ const log = UserInput.logger.for(this.insistForNumber);
241
+ log.verbose(`Insisting for number input: undefined, question: ${question}, test: ${test.toString()}, min: ${min}, max: ${max}, initial: ${initial}, defaultConfirmation: ${defaultConfirmation}, limit: ${limit}`);
242
+ const userInput = new UserInput(name).setMessage(question).setType("number");
243
+ if (typeof min === "number") userInput.setMin(min);
244
+ if (typeof max === "number") userInput.setMax(max);
245
+ if (typeof initial === "number") userInput.setInitial(initial);
246
+ return await this.insist(userInput, test, defaultConfirmation, limit);
247
+ }
248
+ static parseArgs(options) {
249
+ const log = UserInput.logger.for(this.parseArgs);
250
+ const args = {
251
+ args: process.argv.slice(2),
252
+ options: options
253
+ };
254
+ log.debug(`Parsing arguments: ${JSON.stringify(args, null, 2)}`);
255
+ try {
256
+ return util.parseArgs(args);
257
+ } catch (error) {
258
+ log.debug(`Error while parsing arguments:\n${JSON.stringify(args, null, 2)}\n | options\n${JSON.stringify(options, null, 2)}\n | ${error}`);
259
+ throw new Error(`Error while parsing arguments: ${error}`);
260
+ }
261
+ }
262
+ }
263
+ const DefaultCommandOptions = {
264
+ verbose: {
265
+ type: "boolean",
266
+ short: "V",
267
+ default: undefined
268
+ },
269
+ version: {
270
+ type: "boolean",
271
+ short: "v",
272
+ default: undefined
273
+ },
274
+ help: {
275
+ type: "boolean",
276
+ short: "h",
277
+ default: false
278
+ },
279
+ logLevel: {
280
+ type: "string",
281
+ default: "info"
282
+ },
283
+ logStyle: {
284
+ type: "boolean",
285
+ default: true
286
+ },
287
+ timestamp: {
288
+ type: "boolean",
289
+ default: true
290
+ },
291
+ banner: {
292
+ type: "boolean",
293
+ default: true
294
+ }
295
+ };
296
+ const DefaultCommandValues = Object.keys(DefaultCommandOptions).reduce((acc, key) => {
297
+ acc[key] = DefaultCommandOptions[key].default;
298
+ return acc;
299
+ }, {});
300
+ const Encoding = "utf-8";
301
+ const SemVersionRegex = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z])))/g;
302
+ exports.SemVersion = void 0;
303
+ (function(SemVersion) {
304
+ SemVersion["PATCH"] = "patch";
305
+ SemVersion["MINOR"] = "minor";
306
+ SemVersion["MAJOR"] = "major";
307
+ })(exports.SemVersion || (exports.SemVersion = {}));
308
+ const NoCIFLag = "-no-ci";
309
+ const SetupScriptKey = "postinstall";
310
+ exports.Tokens = void 0;
311
+ (function(Tokens) {
312
+ Tokens["GIT"] = ".token";
313
+ Tokens["NPM"] = ".npmtoken";
314
+ Tokens["DOCKER"] = ".dockertoken";
315
+ Tokens["CONFLUENCE"] = ".confluence-token";
316
+ })(exports.Tokens || (exports.Tokens = {}));
317
+ const AbortCode = "Aborted";
318
+ class StandardOutputWriter {
319
+ constructor(cmd, lock, ...args) {
320
+ this.cmd = cmd;
321
+ this.lock = lock;
322
+ this.logger = logging.Logging.for(this.cmd);
323
+ }
324
+ log(type, data) {
325
+ data = Buffer.isBuffer(data) ? data.toString(Encoding) : data;
326
+ const log = type === "stderr" ? styledStringBuilder.style(data).red.text : data;
327
+ this.logger.info(log);
328
+ }
329
+ data(chunk) {
330
+ this.log("stdout", String(chunk));
331
+ }
332
+ error(chunk) {
333
+ this.log("stderr", String(chunk));
334
+ }
335
+ errors(err) {
336
+ this.log("stderr", `Error executing command exited : ${err}`);
337
+ }
338
+ exit(code, logs) {
339
+ this.log("stdout", `command exited code : ${code === 0 ? styledStringBuilder.style(code.toString()).green.text : styledStringBuilder.style(code === null ? "null" : code.toString()).red.text}`);
340
+ if (code === 0) {
341
+ this.resolve(logs.map(l => l.trim()).join("\n"));
342
+ } else {
343
+ this.reject(new Error(logs.length ? logs.join("\n") : code.toString()));
344
+ }
345
+ }
346
+ parseCommand(command) {
347
+ if (Array.isArray(command)) {
348
+ this.cmd = command.join(" ");
349
+ return [ command[0], command.slice(1) ];
350
+ }
351
+ const parts = shellQuote.parse(command).filter(p => typeof p === "string").map(String);
352
+ this.cmd = parts.join(" ");
353
+ return [ parts[0], parts.slice(1) ];
354
+ }
355
+ resolve(reason) {
356
+ this.log("stdout", `${this.cmd} executed successfully: ${styledStringBuilder.style(reason ? "ran to completion" : reason).green}`);
357
+ this.lock.resolve(reason);
358
+ }
359
+ reject(reason) {
360
+ if (!(reason instanceof Error)) {
361
+ reason = new Error(typeof reason === "number" ? `Exit code ${reason}` : reason);
362
+ }
363
+ this.log("stderr", `${this.cmd} failed to execute: ${styledStringBuilder.style(reason.message).red}`);
364
+ this.lock.reject(reason);
365
+ }
366
+ }
367
+ function lockify(f) {
368
+ let lock = Promise.resolve();
369
+ return (...params) => {
370
+ const result = lock.then(() => f(...params));
371
+ lock = result.catch(() => {});
372
+ return result;
373
+ };
374
+ }
375
+ function chainAbortController(argument0, ...remainder) {
376
+ let signals;
377
+ let controller;
378
+ if (argument0 instanceof AbortSignal) {
379
+ controller = new AbortController;
380
+ signals = [ argument0, ...remainder ];
381
+ } else {
382
+ controller = argument0;
383
+ signals = remainder;
384
+ }
385
+ if (controller.signal.aborted) {
386
+ return controller;
387
+ }
388
+ const handler = () => controller.abort();
389
+ for (const signal of signals) {
390
+ if (signal.aborted) {
391
+ controller.abort();
392
+ break;
393
+ }
394
+ signal.addEventListener("abort", handler, {
395
+ once: true,
396
+ signal: controller.signal
397
+ });
398
+ }
399
+ return controller;
400
+ }
401
+ function spawnCommand(output, command, opts, abort, logger) {
402
+ function spawnInner(command, controller) {
403
+ const [cmd, argz] = output.parseCommand(command);
404
+ logger.info(`Running command: ${cmd}`);
405
+ logger.debug(`with args: ${argz.join(" ")}`);
406
+ const childProcess = child_process.spawn(cmd, argz, {
407
+ ...opts,
408
+ cwd: opts.cwd || process.cwd(),
409
+ env: Object.assign({}, process.env, opts.env, {
410
+ PATH: process.env.PATH
411
+ }),
412
+ shell: opts.shell || false,
413
+ signal: controller.signal
414
+ });
415
+ logger.verbose(`pid : ${childProcess.pid}`);
416
+ return childProcess;
417
+ }
418
+ const m = command.match(/[<>$#]/g);
419
+ if (m) throw new Error(`Invalid command: ${command}. contains invalid characters: ${m}`);
420
+ if (command.includes(" | ")) {
421
+ const cmds = command.split(" | ");
422
+ const spawns = [];
423
+ const controllers = new Array(cmds.length);
424
+ controllers[0] = abort;
425
+ for (let i = 0; i < cmds.length; i++) {
426
+ if (i !== 0) controllers[i] = chainAbortController(controllers[i - 1].signal);
427
+ spawns.push(spawnInner(cmds[i], controllers[i]));
428
+ if (i === 0) continue;
429
+ spawns[i - 1].stdout.pipe(spawns[i].stdin);
430
+ }
431
+ return spawns[cmds.length - 1];
432
+ }
433
+ return spawnInner(command, abort);
434
+ }
435
+ function runCommand(command, opts = {}, outputConstructor = StandardOutputWriter, ...args) {
436
+ const logger = logging.Logging.for(runCommand);
437
+ const abort = new AbortController;
438
+ const result = {
439
+ abort: abort,
440
+ command: command,
441
+ logs: [],
442
+ errs: []
443
+ };
444
+ const lock = new Promise((resolve, reject) => {
445
+ let output;
446
+ try {
447
+ output = new outputConstructor(command, {
448
+ resolve: resolve,
449
+ reject: reject
450
+ }, ...args);
451
+ result.cmd = spawnCommand(output, command, opts, abort, logger);
452
+ } catch (e) {
453
+ return reject(new Error(`Error running command ${command}: ${e}`));
454
+ }
455
+ result.cmd.stdout.setEncoding("utf8");
456
+ result.cmd.stdout.on("data", chunk => {
457
+ chunk = chunk.toString();
458
+ result.logs.push(chunk);
459
+ output.data(chunk);
460
+ });
461
+ result.cmd.stderr.on("data", data => {
462
+ data = data.toString();
463
+ result.errs.push(data);
464
+ output.error(data);
465
+ });
466
+ result.cmd.once("error", err => {
467
+ output.exit(err.message, result.errs);
468
+ });
469
+ result.cmd.once("exit", (code = 0) => {
470
+ if (abort.signal.aborted && code === null) code = AbortCode;
471
+ output.exit(code, code === 0 ? result.logs : result.errs);
472
+ });
473
+ });
474
+ Object.assign(result, {
475
+ promise: lock,
476
+ pipe: async cb => {
477
+ const l = logger.for("pipe");
478
+ try {
479
+ l.verbose(`Executing pipe function ${command}...`);
480
+ const result = await lock;
481
+ l.verbose(`Piping output to ${cb.name}: ${result}`);
482
+ return cb(result);
483
+ } catch (e) {
484
+ l.error(`Error piping command output: ${e}`);
485
+ throw e;
486
+ }
487
+ }
488
+ });
489
+ return result;
490
+ }
491
+ const logger = logging.Logging.for("fs");
492
+ function patchString(input, values, flags = "g", filter) {
493
+ Object.entries(values).forEach(([key, val]) => {
494
+ const regexp = new RegExp(logging.escapeRegExp(key), flags);
495
+ input = input.replace(regexp, subStr => {
496
+ if (!filter || filter(subStr)) {
497
+ return val;
498
+ }
499
+ return val;
500
+ });
501
+ });
502
+ return input;
503
+ }
504
+ function patchFile(path, values, filter) {
505
+ const log = logger.for(patchFile);
506
+ if (!fs__default["default"].existsSync(path)) throw new Error(`File not found at path "${path}".`);
507
+ let content = readFile(path);
508
+ log.verbose(`Patching file "${path}"...`);
509
+ log.debug(`with value: ${JSON.stringify(values)}`);
510
+ try {
511
+ content = patchString(content, values, "g", filter);
512
+ } catch (error) {
513
+ throw new Error(`Error patching file: ${error}`);
514
+ }
515
+ writeFile(path, content);
516
+ }
517
+ function readFile(path) {
518
+ const log = logger.for(readFile);
519
+ try {
520
+ log.verbose(`Reading file "${path}"...`);
521
+ return fs__default["default"].readFileSync(path, "utf8");
522
+ } catch (error) {
523
+ log.verbose(`Error reading file "${path}": ${error}`);
524
+ throw new Error(`Error reading file "${path}": ${error}`);
525
+ }
526
+ }
527
+ function writeFile(path, data) {
528
+ const log = logger.for(writeFile);
529
+ try {
530
+ log.verbose(`Writing file "${path} with ${data.length} bytes...`);
531
+ fs__default["default"].writeFileSync(path, data, "utf8");
532
+ } catch (error) {
533
+ log.verbose(`Error writing file "${path}": ${error}`);
534
+ throw new Error(`Error writing file "${path}": ${error}`);
535
+ }
536
+ }
537
+ function getAllFiles(p, filter) {
538
+ const log = logger.for(getAllFiles);
539
+ const files = [];
540
+ try {
541
+ log.verbose(`Retrieving all files from "${p}"...`);
542
+ const entries = fs__default["default"].readdirSync(p);
543
+ entries.forEach(entry => {
544
+ const fullPath = path__default["default"].join(p, entry);
545
+ const stat = fs__default["default"].statSync(fullPath);
546
+ if (stat.isFile()) {
547
+ files.push(fullPath);
548
+ } else if (stat.isDirectory()) {
549
+ files.push(...getAllFiles(fullPath));
550
+ }
551
+ });
552
+ if (!filter) return files;
553
+ return files.filter(filter);
554
+ } catch (error) {
555
+ log.verbose(`Error retrieving files from "${p}": ${error}`);
556
+ throw new Error(`Error retrieving files from "${p}": ${error}`);
557
+ }
558
+ }
559
+ async function renameFile(source, dest) {
560
+ const log = logger.for(renameFile);
561
+ let descriptorSource, descriptorDest;
562
+ try {
563
+ descriptorSource = fs__default["default"].statSync(source);
564
+ } catch (error) {
565
+ log.verbose(`Source path "${source}" does not exist: ${error}`);
566
+ throw new Error(`Source path "${source}" does not exist: ${error}`);
567
+ }
568
+ try {
569
+ descriptorDest = fs__default["default"].statSync(dest);
570
+ } catch (e) {}
571
+ if (descriptorDest) {
572
+ log.verbose(`Destination path "${dest}" already exists`);
573
+ throw new Error(`Destination path "${dest}" already exists`);
574
+ }
575
+ try {
576
+ log.verbose(`Renaming ${descriptorSource.isFile() ? "file" : "directory"} "${source}" to "${dest}...`);
577
+ fs__default["default"].renameSync(source, dest);
578
+ log.verbose(`Successfully renamed to "${dest}"`);
579
+ } catch (error) {
580
+ log.verbose(`Error renaming ${descriptorSource.isFile() ? "file" : "directory"} "${source}" to "${dest}": ${error}`);
581
+ throw new Error(`Error renaming ${descriptorSource.isFile() ? "file" : "directory"} "${source}" to "${dest}": ${error}`);
582
+ }
583
+ }
584
+ function copyFile(source, dest) {
585
+ const log = logger.for(copyFile);
586
+ let descriptorSource, descriptorDest;
587
+ try {
588
+ descriptorSource = fs__default["default"].statSync(source);
589
+ } catch (error) {
590
+ log.verbose(`Source path "${source}" does not exist: ${error}`);
591
+ throw new Error(`Source path "${source}" does not exist: ${error}`);
592
+ }
593
+ try {
594
+ descriptorDest = fs__default["default"].statSync(dest);
595
+ } catch (error) {
596
+ if (descriptorSource.isDirectory()) {
597
+ log.verbose(`Dest path "${dest}" does not exist. creating`);
598
+ fs__default["default"].mkdirSync(dest, {
599
+ recursive: true
600
+ });
601
+ }
602
+ }
603
+ try {
604
+ log.verbose(`Copying ${descriptorSource.isFile() ? "file" : "directory"} "${source}" to "${dest}...`);
605
+ fs__default["default"].cpSync(source, dest, {
606
+ recursive: true
607
+ });
608
+ } catch (error) {
609
+ log.verbose(`Error copying ${descriptorSource.isFile() ? "file" : "directory"} "${source}" to "${dest}: ${error}`);
610
+ throw new Error(`Error copying ${descriptorSource.isFile() ? "file" : "directory"} "${source}" to "${dest}: ${error}`);
611
+ }
612
+ }
613
+ function deletePath(p) {
614
+ const log = logger.for(deletePath);
615
+ try {
616
+ const descriptor = fs__default["default"].statSync(p);
617
+ if (descriptor.isFile()) {
618
+ log.verbose(`Deleting file "${p}...`);
619
+ fs__default["default"].rmSync(p, {
620
+ recursive: true,
621
+ force: true
622
+ });
623
+ } else if (descriptor.isDirectory()) fs__default["default"].rmSync(p, {
624
+ recursive: true,
625
+ force: true
626
+ });
627
+ } catch (error) {
628
+ log.verbose(`Error Deleting "${p}": ${error}`);
629
+ throw new Error(`Error Deleting "${p}": ${error}`);
630
+ }
631
+ }
632
+ function getPackage(p = process.cwd(), property) {
633
+ let pkg;
634
+ try {
635
+ pkg = JSON.parse(readFile(path__default["default"].join(p, `package.json`)));
636
+ } catch (error) {
637
+ throw new Error(`Failed to retrieve package information" ${error}`);
638
+ }
639
+ if (property) {
640
+ if (!(property in pkg)) throw new Error(`Property "${property}" not found in package.json`);
641
+ return pkg[property];
642
+ }
643
+ return pkg;
644
+ }
645
+ function setPackageAttribute(attr, value, p = process.cwd()) {
646
+ const pkg = getPackage(p);
647
+ pkg[attr] = value;
648
+ writeFile(path__default["default"].join(p, `package.json`), JSON.stringify(pkg, null, 2));
649
+ }
650
+ function getPackageVersion(p = process.cwd()) {
651
+ return getPackage(p, "version");
652
+ }
653
+ async function getDependencies(path = process.cwd()) {
654
+ let pkg;
655
+ try {
656
+ pkg = JSON.parse(await runCommand(`npm ls --json`, {
657
+ cwd: path
658
+ }).promise);
659
+ } catch (e) {
660
+ throw new Error(`Failed to retrieve dependencies: ${e}`);
661
+ }
662
+ const mapper = (entry, index) => ({
663
+ name: entry[0],
664
+ version: entry[1].version
665
+ });
666
+ return {
667
+ prod: Object.entries(pkg.dependencies || {}).map(mapper),
668
+ dev: Object.entries(pkg.devDependencies || {}).map(mapper),
669
+ peer: Object.entries(pkg.peerDependencies || {}).map(mapper)
670
+ };
671
+ }
672
+ async function updateDependencies() {
673
+ const log = logger.for(updateDependencies);
674
+ log.info("checking for updates...");
675
+ await runCommand("npx npm-check-updates -u").promise;
676
+ log.info("updating...");
677
+ await runCommand("npx npm run do-install").promise;
678
+ }
679
+ async function installIfNotAvailable(deps, dependencies) {
680
+ if (!dependencies) {
681
+ const d = await getDependencies();
682
+ dependencies = {
683
+ prod: d.prod?.map(p => p.name) || [],
684
+ dev: d.dev?.map(d => d.name) || [],
685
+ peer: d.peer?.map(p => p.name) || []
686
+ };
687
+ }
688
+ const {prod: prod, dev: dev, peer: peer} = dependencies;
689
+ const installed = Array.from(new Set([ ...prod || [], ...dev || [], ...peer || [] ]));
690
+ deps = typeof deps === "string" ? [ deps ] : deps;
691
+ const toInstall = deps.filter(d => !installed.includes(d));
692
+ if (toInstall.length) await installDependencies({
693
+ dev: toInstall
694
+ });
695
+ dependencies.dev = dependencies.dev || [];
696
+ dependencies.dev.push(...toInstall);
697
+ return dependencies;
698
+ }
699
+ async function pushToGit() {
700
+ const log = logger.for(pushToGit);
701
+ const gitUser = await runCommand("git config user.name").promise;
702
+ const gitEmail = await runCommand("git config user.email").promise;
703
+ log.verbose(`cached git id: ${gitUser}/${gitEmail}. changing to automation`);
704
+ await runCommand('git config user.email "automation@decaf.ts"').promise;
705
+ await runCommand('git config user.name "decaf"').promise;
706
+ log.info("Pushing changes to git...");
707
+ await runCommand("git add .").promise;
708
+ await runCommand(`git commit -m "refs #1 - after repo setup"`).promise;
709
+ await runCommand("git push").promise;
710
+ await runCommand(`git config user.email "${gitEmail}"`).promise;
711
+ await runCommand(`git config user.name "${gitUser}"`).promise;
712
+ log.verbose(`reverted to git id: ${gitUser}/${gitEmail}`);
713
+ }
714
+ async function installDependencies(dependencies) {
715
+ const log = logger.for(installDependencies);
716
+ const prod = dependencies.prod || [];
717
+ const dev = dependencies.dev || [];
718
+ const peer = dependencies.peer || [];
719
+ if (prod.length) {
720
+ log.info(`Installing dependencies ${prod.join(", ")}...`);
721
+ await runCommand(`npm install ${prod.join(" ")}`, {
722
+ cwd: process.cwd()
723
+ }).promise;
724
+ }
725
+ if (dev.length) {
726
+ log.info(`Installing devDependencies ${dev.join(", ")}...`);
727
+ await runCommand(`npm install --save-dev ${dev.join(" ")}`, {
728
+ cwd: process.cwd()
729
+ }).promise;
730
+ }
731
+ if (peer.length) {
732
+ log.info(`Installing peerDependencies ${peer.join(", ")}...`);
733
+ await runCommand(`npm install --save-peer ${peer.join(" ")}`, {
734
+ cwd: process.cwd()
735
+ }).promise;
736
+ }
737
+ }
738
+ async function normalizeImport(importPromise) {
739
+ return importPromise.then(m => m.default || m);
740
+ }
741
+ async function getFileSizeZipped(dir) {
742
+ const log = logger.for(getFileSizeZipped);
743
+ try {
744
+ const entries = fs__default["default"].readdirSync(dir);
745
+ const candidates = entries.map(e => path__default["default"].join(dir, e)).filter(p => {
746
+ try {
747
+ const s = fs__default["default"].statSync(p);
748
+ return s.isFile() && (p.endsWith(".js") || p.endsWith(".cjs") || p.endsWith(".mjs"));
749
+ } catch {
750
+ return false;
751
+ }
752
+ });
753
+ if (candidates.length === 0) {
754
+ throw new Error(`No JS files found in directory ${dir}`);
755
+ }
756
+ let smallest = candidates[0];
757
+ let smallestSize = fs__default["default"].statSync(smallest).size;
758
+ for (const c of candidates.slice(1)) {
759
+ const s = fs__default["default"].statSync(c).size;
760
+ if (s < smallestSize) {
761
+ smallest = c;
762
+ smallestSize = s;
763
+ }
764
+ }
765
+ log.verbose(`Selected smallest bundle: ${smallest} (${smallestSize} bytes)`);
766
+ const buffer = fs__default["default"].readFileSync(smallest);
767
+ const gz = zlib__default["default"].gzipSync(buffer);
768
+ const sizeKb = Number((gz.length / 1024).toFixed(1));
769
+ log.verbose(`Gzipped size: ${gz.length} bytes (${sizeKb} KB)`);
770
+ return sizeKb;
771
+ } catch (e) {
772
+ log.verbose(`Failed to compute gzipped size for ${dir}: ${e}`);
773
+ throw e;
774
+ }
775
+ }
776
+ function listFolder(basePath = process.cwd(), filter) {
777
+ const log = logger.for(listFolder);
778
+ try {
779
+ if (!fs__default["default"].existsSync(basePath)) return [];
780
+ const entries = fs__default["default"].readdirSync(basePath, {
781
+ withFileTypes: true
782
+ });
783
+ const names = entries.filter(d => filter ? filter(d.name, d) : true).map(d => d.name);
784
+ return names;
785
+ } catch (e) {
786
+ log.verbose(`Failed to list folder ${basePath}: ${e}`);
787
+ return [];
788
+ }
789
+ }
790
+ function listNodeModulesPackages(basePath = path__default["default"].join(process.cwd(), "node_modules")) {
791
+ const log = logger.for(listNodeModulesPackages);
792
+ try {
793
+ if (!fs__default["default"].existsSync(basePath)) return [];
794
+ const entries = fs__default["default"].readdirSync(basePath, {
795
+ withFileTypes: true
796
+ });
797
+ const names = [];
798
+ for (const e of entries) {
799
+ try {
800
+ if (!e.isDirectory()) continue;
801
+ if (e.name.startsWith(".")) continue;
802
+ if (e.name.startsWith("@")) {
803
+ const scopePath = path__default["default"].join(basePath, e.name);
804
+ try {
805
+ const scoped = fs__default["default"].readdirSync(scopePath, {
806
+ withFileTypes: true
807
+ });
808
+ for (const s of scoped) {
809
+ if (s.isDirectory() && !s.name.startsWith(".")) {
810
+ names.push(`${e.name}/${s.name}`);
811
+ }
812
+ }
813
+ } catch (err) {
814
+ log.verbose(`Failed to read scope ${scopePath}: ${err}`);
815
+ }
816
+ } else {
817
+ names.push(e.name);
818
+ }
819
+ } catch (err) {
820
+ log.verbose(`Skipping entry ${e.name} due to error: ${err}`);
821
+ }
822
+ }
823
+ return names;
824
+ } catch (e) {
825
+ log.verbose(`Failed to list node_modules packages at ${basePath}: ${e}`);
826
+ return [];
827
+ }
828
+ }
829
+ const slogans = [ {
830
+ Slogan: "No caffeine, no chaos. Just clean code.",
831
+ Tags: "Coffee-themed, Calm, Tech"
832
+ }, {
833
+ Slogan: "Full flavor, no jitters. That's Decaf-TS.",
834
+ Tags: "Coffee-themed, Cheerful"
835
+ }, {
836
+ Slogan: "Chill fullstack. Powered by Decaf.",
837
+ Tags: "Coffee-themed, Fun, Tech"
838
+ }, {
839
+ Slogan: "Decaf-TS: Brewed for calm code.",
840
+ Tags: "Coffee-themed, Branding"
841
+ }, {
842
+ Slogan: "Smooth as your morning Decaf.",
843
+ Tags: "Coffee-themed, Chill"
844
+ }, {
845
+ Slogan: "All the kick, none of the crash.",
846
+ Tags: "Coffee-themed, Energetic"
847
+ }, {
848
+ Slogan: "Sip back and ship faster.",
849
+ Tags: "Coffee-themed, Fun"
850
+ }, {
851
+ Slogan: "Keep calm and code Decaf.",
852
+ Tags: "Coffee-themed, Playful"
853
+ }, {
854
+ Slogan: "Code without the caffeine shakes.",
855
+ Tags: "Coffee-themed, Humorous"
856
+ }, {
857
+ Slogan: "Your fullstack, decaffeinated.",
858
+ Tags: "Coffee-themed, Technical"
859
+ }, {
860
+ Slogan: "No caffeine, no chaos. Just clean code.",
861
+ Tags: "Coffee-themed, Calm, Tech"
862
+ }, {
863
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
864
+ Tags: "Coffee-themed, Cheerful"
865
+ }, {
866
+ Slogan: "Chill fullstack. Powered by Decaf.",
867
+ Tags: "Coffee-themed, Fun, Tech"
868
+ }, {
869
+ Slogan: "Decaf-TS: Brewed for calm code.",
870
+ Tags: "Coffee-themed, Branding"
871
+ }, {
872
+ Slogan: "Smooth as your morning Decaf.",
873
+ Tags: "Coffee-themed, Chill"
874
+ }, {
875
+ Slogan: "All the kick, none of the crash.",
876
+ Tags: "Coffee-themed, Energetic"
877
+ }, {
878
+ Slogan: "Sip back and ship faster.",
879
+ Tags: "Coffee-themed, Fun"
880
+ }, {
881
+ Slogan: "Keep calm and code Decaf.",
882
+ Tags: "Coffee-themed, Playful"
883
+ }, {
884
+ Slogan: "Code without the caffeine shakes.",
885
+ Tags: "Coffee-themed, Humorous"
886
+ }, {
887
+ Slogan: "Your fullstack, decaffeinated.",
888
+ Tags: "Coffee-themed, Technical"
889
+ }, {
890
+ Slogan: "No caffeine, no chaos. Just clean code.",
891
+ Tags: "Coffee-themed, Calm, Tech"
892
+ }, {
893
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
894
+ Tags: "Coffee-themed, Cheerful"
895
+ }, {
896
+ Slogan: "Chill fullstack. Powered by Decaf.",
897
+ Tags: "Coffee-themed, Fun, Tech"
898
+ }, {
899
+ Slogan: "Decaf-TS: Brewed for calm code.",
900
+ Tags: "Coffee-themed, Branding"
901
+ }, {
902
+ Slogan: "Smooth as your morning Decaf.",
903
+ Tags: "Coffee-themed, Chill"
904
+ }, {
905
+ Slogan: "All the kick, none of the crash.",
906
+ Tags: "Coffee-themed, Energetic"
907
+ }, {
908
+ Slogan: "Sip back and ship faster.",
909
+ Tags: "Coffee-themed, Fun"
910
+ }, {
911
+ Slogan: "Keep calm and code Decaf.",
912
+ Tags: "Coffee-themed, Playful"
913
+ }, {
914
+ Slogan: "Code without the caffeine shakes.",
915
+ Tags: "Coffee-themed, Humorous"
916
+ }, {
917
+ Slogan: "Your fullstack, decaffeinated.",
918
+ Tags: "Coffee-themed, Technical"
919
+ }, {
920
+ Slogan: "No caffeine, no chaos. Just clean code.",
921
+ Tags: "Coffee-themed, Calm, Tech"
922
+ }, {
923
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
924
+ Tags: "Coffee-themed, Cheerful"
925
+ }, {
926
+ Slogan: "Chill fullstack. Powered by Decaf.",
927
+ Tags: "Coffee-themed, Fun, Tech"
928
+ }, {
929
+ Slogan: "Decaf-TS: Brewed for calm code.",
930
+ Tags: "Coffee-themed, Branding"
931
+ }, {
932
+ Slogan: "Smooth as your morning Decaf.",
933
+ Tags: "Coffee-themed, Chill"
934
+ }, {
935
+ Slogan: "All the kick, none of the crash.",
936
+ Tags: "Coffee-themed, Energetic"
937
+ }, {
938
+ Slogan: "Sip back and ship faster.",
939
+ Tags: "Coffee-themed, Fun"
940
+ }, {
941
+ Slogan: "Keep calm and code Decaf.",
942
+ Tags: "Coffee-themed, Playful"
943
+ }, {
944
+ Slogan: "Code without the caffeine shakes.",
945
+ Tags: "Coffee-themed, Humorous"
946
+ }, {
947
+ Slogan: "Your fullstack, decaffeinated.",
948
+ Tags: "Coffee-themed, Technical"
949
+ }, {
950
+ Slogan: "No caffeine, no chaos. Just clean code.",
951
+ Tags: "Coffee-themed, Calm, Tech"
952
+ }, {
953
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
954
+ Tags: "Coffee-themed, Cheerful"
955
+ }, {
956
+ Slogan: "Chill fullstack. Powered by Decaf.",
957
+ Tags: "Coffee-themed, Fun, Tech"
958
+ }, {
959
+ Slogan: "Decaf-TS: Brewed for calm code.",
960
+ Tags: "Coffee-themed, Branding"
961
+ }, {
962
+ Slogan: "Smooth as your morning Decaf.",
963
+ Tags: "Coffee-themed, Chill"
964
+ }, {
965
+ Slogan: "All the kick, none of the crash.",
966
+ Tags: "Coffee-themed, Energetic"
967
+ }, {
968
+ Slogan: "Sip back and ship faster.",
969
+ Tags: "Coffee-themed, Fun"
970
+ }, {
971
+ Slogan: "Keep calm and code Decaf.",
972
+ Tags: "Coffee-themed, Playful"
973
+ }, {
974
+ Slogan: "Code without the caffeine shakes.",
975
+ Tags: "Coffee-themed, Humorous"
976
+ }, {
977
+ Slogan: "Your fullstack, decaffeinated.",
978
+ Tags: "Coffee-themed, Technical"
979
+ }, {
980
+ Slogan: "No caffeine, no chaos. Just clean code.",
981
+ Tags: "Coffee-themed, Calm, Tech"
982
+ }, {
983
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
984
+ Tags: "Coffee-themed, Cheerful"
985
+ }, {
986
+ Slogan: "Chill fullstack. Powered by Decaf.",
987
+ Tags: "Coffee-themed, Fun, Tech"
988
+ }, {
989
+ Slogan: "Decaf-TS: Brewed for calm code.",
990
+ Tags: "Coffee-themed, Branding"
991
+ }, {
992
+ Slogan: "Smooth as your morning Decaf.",
993
+ Tags: "Coffee-themed, Chill"
994
+ }, {
995
+ Slogan: "All the kick, none of the crash.",
996
+ Tags: "Coffee-themed, Energetic"
997
+ }, {
998
+ Slogan: "Sip back and ship faster.",
999
+ Tags: "Coffee-themed, Fun"
1000
+ }, {
1001
+ Slogan: "Keep calm and code Decaf.",
1002
+ Tags: "Coffee-themed, Playful"
1003
+ }, {
1004
+ Slogan: "Code without the caffeine shakes.",
1005
+ Tags: "Coffee-themed, Humorous"
1006
+ }, {
1007
+ Slogan: "Your fullstack, decaffeinated.",
1008
+ Tags: "Coffee-themed, Technical"
1009
+ }, {
1010
+ Slogan: "No caffeine, no chaos. Just clean code.",
1011
+ Tags: "Coffee-themed, Calm, Tech"
1012
+ }, {
1013
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
1014
+ Tags: "Coffee-themed, Cheerful"
1015
+ }, {
1016
+ Slogan: "Chill fullstack. Powered by Decaf.",
1017
+ Tags: "Coffee-themed, Fun, Tech"
1018
+ }, {
1019
+ Slogan: "Decaf-TS: Brewed for calm code.",
1020
+ Tags: "Coffee-themed, Branding"
1021
+ }, {
1022
+ Slogan: "Smooth as your morning Decaf.",
1023
+ Tags: "Coffee-themed, Chill"
1024
+ }, {
1025
+ Slogan: "All the kick, none of the crash.",
1026
+ Tags: "Coffee-themed, Energetic"
1027
+ }, {
1028
+ Slogan: "Sip back and ship faster.",
1029
+ Tags: "Coffee-themed, Fun"
1030
+ }, {
1031
+ Slogan: "Keep calm and code Decaf.",
1032
+ Tags: "Coffee-themed, Playful"
1033
+ }, {
1034
+ Slogan: "Code without the caffeine shakes.",
1035
+ Tags: "Coffee-themed, Humorous"
1036
+ }, {
1037
+ Slogan: "Your fullstack, decaffeinated.",
1038
+ Tags: "Coffee-themed, Technical"
1039
+ }, {
1040
+ Slogan: "No caffeine, no chaos. Just clean code.",
1041
+ Tags: "Coffee-themed, Calm, Tech"
1042
+ }, {
1043
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
1044
+ Tags: "Coffee-themed, Cheerful"
1045
+ }, {
1046
+ Slogan: "Chill fullstack. Powered by Decaf.",
1047
+ Tags: "Coffee-themed, Fun, Tech"
1048
+ }, {
1049
+ Slogan: "Decaf-TS: Brewed for calm code.",
1050
+ Tags: "Coffee-themed, Branding"
1051
+ }, {
1052
+ Slogan: "Smooth as your morning Decaf.",
1053
+ Tags: "Coffee-themed, Chill"
1054
+ }, {
1055
+ Slogan: "All the kick, none of the crash.",
1056
+ Tags: "Coffee-themed, Energetic"
1057
+ }, {
1058
+ Slogan: "Sip back and ship faster.",
1059
+ Tags: "Coffee-themed, Fun"
1060
+ }, {
1061
+ Slogan: "Keep calm and code Decaf.",
1062
+ Tags: "Coffee-themed, Playful"
1063
+ }, {
1064
+ Slogan: "Code without the caffeine shakes.",
1065
+ Tags: "Coffee-themed, Humorous"
1066
+ }, {
1067
+ Slogan: "Your fullstack, decaffeinated.",
1068
+ Tags: "Coffee-themed, Technical"
1069
+ }, {
1070
+ Slogan: "No caffeine, no chaos. Just clean code.",
1071
+ Tags: "Coffee-themed, Calm, Tech"
1072
+ }, {
1073
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
1074
+ Tags: "Coffee-themed, Cheerful"
1075
+ }, {
1076
+ Slogan: "Chill fullstack. Powered by Decaf.",
1077
+ Tags: "Coffee-themed, Fun, Tech"
1078
+ }, {
1079
+ Slogan: "Decaf-TS: Brewed for calm code.",
1080
+ Tags: "Coffee-themed, Branding"
1081
+ }, {
1082
+ Slogan: "Smooth as your morning Decaf.",
1083
+ Tags: "Coffee-themed, Chill"
1084
+ }, {
1085
+ Slogan: "All the kick, none of the crash.",
1086
+ Tags: "Coffee-themed, Energetic"
1087
+ }, {
1088
+ Slogan: "Sip back and ship faster.",
1089
+ Tags: "Coffee-themed, Fun"
1090
+ }, {
1091
+ Slogan: "Keep calm and code Decaf.",
1092
+ Tags: "Coffee-themed, Playful"
1093
+ }, {
1094
+ Slogan: "Code without the caffeine shakes.",
1095
+ Tags: "Coffee-themed, Humorous"
1096
+ }, {
1097
+ Slogan: "Your fullstack, decaffeinated.",
1098
+ Tags: "Coffee-themed, Technical"
1099
+ }, {
1100
+ Slogan: "No caffeine, no chaos. Just clean code.",
1101
+ Tags: "Coffee-themed, Calm, Tech"
1102
+ }, {
1103
+ Slogan: "Full flavor, no jitters. That’s Decaf-TS.",
1104
+ Tags: "Coffee-themed, Cheerful"
1105
+ }, {
1106
+ Slogan: "Chill fullstack. Powered by Decaf.",
1107
+ Tags: "Coffee-themed, Fun, Tech"
1108
+ }, {
1109
+ Slogan: "Decaf-TS: Brewed for calm code.",
1110
+ Tags: "Coffee-themed, Branding"
1111
+ }, {
1112
+ Slogan: "Smooth as your morning Decaf.",
1113
+ Tags: "Coffee-themed, Chill"
1114
+ }, {
1115
+ Slogan: "All the kick, none of the crash.",
1116
+ Tags: "Coffee-themed, Energetic"
1117
+ }, {
1118
+ Slogan: "Sip back and ship faster.",
1119
+ Tags: "Coffee-themed, Fun"
1120
+ }, {
1121
+ Slogan: "Keep calm and code Decaf.",
1122
+ Tags: "Coffee-themed, Playful"
1123
+ }, {
1124
+ Slogan: "Code without the caffeine shakes.",
1125
+ Tags: "Coffee-themed, Humorous"
1126
+ }, {
1127
+ Slogan: "Your fullstack, decaffeinated.",
1128
+ Tags: "Coffee-themed, Technical"
1129
+ }, {
1130
+ Slogan: "Decaf-TS: Where smart contracts meet smart interfaces.",
1131
+ Tags: "Blockchain, Smart Contracts, Tech"
1132
+ }, {
1133
+ Slogan: "Ship dApps without the stress.",
1134
+ Tags: "Blockchain, Cheerful, Developer"
1135
+ }, {
1136
+ Slogan: "No CRUD, no problem — Decaf your data.",
1137
+ Tags: "Data, No-CRUD, Chill"
1138
+ }, {
1139
+ Slogan: "From DID to UI, without breaking a sweat.",
1140
+ Tags: "DID, SSI, UI, Calm"
1141
+ }, {
1142
+ Slogan: "Decaf-TS: Your frontend already understands your smart contract.",
1143
+ Tags: "Smart Contracts, DX, Magic"
1144
+ }, {
1145
+ Slogan: "Self-sovereign by design. Productive by default.",
1146
+ Tags: "SSI, Developer, Calm"
1147
+ }, {
1148
+ Slogan: "Build once. Deploy everywhere. Decentralized and delightful.",
1149
+ Tags: "Blockchain, Multi-platform, Happy"
1150
+ }, {
1151
+ Slogan: "Data that defines its own destiny.",
1152
+ Tags: "SSI, Data-driven, Empowerment"
1153
+ }, {
1154
+ Slogan: "Goodbye CRUD, hello intent-based interfaces.",
1155
+ Tags: "No-CRUD, UI, Technical"
1156
+ }, {
1157
+ Slogan: "The smoothest path from DID to done.",
1158
+ Tags: "DID, Workflow, Chill"
1159
+ }, {
1160
+ Slogan: "Because your dApp deserves more than boilerplate.",
1161
+ Tags: "Blockchain, DevX, Efficiency"
1162
+ }, {
1163
+ Slogan: "Own your data. Own your flow.",
1164
+ Tags: "SSI, Control, Ownership"
1165
+ }, {
1166
+ Slogan: "Write logic like it belongs with the data — because it does.",
1167
+ Tags: "Data Logic, Developer, Smart"
1168
+ }, {
1169
+ Slogan: "From smart contracts to smarter frontends.",
1170
+ Tags: "Smart Contracts, UI, DX"
1171
+ }, {
1172
+ Slogan: "No caffeine. No CRUD. Just the future.",
1173
+ Tags: "No-CRUD, Coffee-themed, Futuristic"
1174
+ }, {
1175
+ Slogan: "The future of web3 UX is Decaf.",
1176
+ Tags: "Blockchain, UX, Vision"
1177
+ }, {
1178
+ Slogan: "Code with confidence. Govern with clarity.",
1179
+ Tags: "Blockchain, Governance, Calm"
1180
+ }, {
1181
+ Slogan: "Interfaces that obey the data, not the other way around.",
1182
+ Tags: "UI, Data Logic, Self-aware"
1183
+ }, {
1184
+ Slogan: "Brew business logic right into your bytes.",
1185
+ Tags: "Data Logic, Coffee-themed, Fun"
1186
+ }, {
1187
+ Slogan: "DIDs done differently — and delightfully.",
1188
+ Tags: "DID, Self-Sovereign, Playful"
1189
+ }, {
1190
+ Slogan: "Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",
1191
+ Tags: "Blockchain, Smart Contracts, Tech"
1192
+ }, {
1193
+ Slogan: "Ship dApps without the stress.",
1194
+ Tags: "Blockchain, Cheerful, Developer"
1195
+ }, {
1196
+ Slogan: "No boilerplate, no problem — Decaf-TS your data.",
1197
+ Tags: "Data, No-CRUD, Chill"
1198
+ }, {
1199
+ Slogan: "From DID to UI, without breaking a sweat.",
1200
+ Tags: "DID, SSI, UI, Calm"
1201
+ }, {
1202
+ Slogan: "Decaf-TS-TS: Your frontend already understands your blockchain contract.",
1203
+ Tags: "Smart Contracts, DX, Magic"
1204
+ }, {
1205
+ Slogan: "Self-sovereign by design. Productive by default.",
1206
+ Tags: "SSI, Developer, Calm"
1207
+ }, {
1208
+ Slogan: "Build once. Deploy everywhere. Decentralized and delightful.",
1209
+ Tags: "Blockchain, Multi-platform, Happy"
1210
+ }, {
1211
+ Slogan: "Data that defines its own destiny.",
1212
+ Tags: "SSI, Data-driven, Empowerment"
1213
+ }, {
1214
+ Slogan: "Goodbye boilerplate, hello intent-based interfaces.",
1215
+ Tags: "No-CRUD, UI, Technical"
1216
+ }, {
1217
+ Slogan: "The smoothest path from DID to done.",
1218
+ Tags: "DID, Workflow, Chill"
1219
+ }, {
1220
+ Slogan: "Because your dApp deserves more than boilerplate.",
1221
+ Tags: "Blockchain, DevX, Efficiency"
1222
+ }, {
1223
+ Slogan: "Own your data. Own your flow.",
1224
+ Tags: "SSI, Control, Ownership"
1225
+ }, {
1226
+ Slogan: "Write logic like it belongs with the data — because it does.",
1227
+ Tags: "Data Logic, Developer, Smart"
1228
+ }, {
1229
+ Slogan: "From blockchain contracts to smarter frontends.",
1230
+ Tags: "Smart Contracts, UI, DX"
1231
+ }, {
1232
+ Slogan: "No caffeine. No boilerplate. Just the future.",
1233
+ Tags: "No-CRUD, Coffee-themed, Futuristic"
1234
+ }, {
1235
+ Slogan: "The future of web3 UX is Decaf-TS.",
1236
+ Tags: "Blockchain, UX, Vision"
1237
+ }, {
1238
+ Slogan: "Code with confidence. Govern with clarity.",
1239
+ Tags: "Blockchain, Governance, Calm"
1240
+ }, {
1241
+ Slogan: "Interfaces that obey the data, not the other way around.",
1242
+ Tags: "UI, Data Logic, Self-aware"
1243
+ }, {
1244
+ Slogan: "Brew business logic right into your bytes.",
1245
+ Tags: "Data Logic, Coffee-themed, Fun"
1246
+ }, {
1247
+ Slogan: "DIDs done differently — and delightfully.",
1248
+ Tags: "DID, Self-Sovereign, Playful"
1249
+ }, {
1250
+ Slogan: "Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",
1251
+ Tags: "Blockchain, Smart Contracts, Tech"
1252
+ }, {
1253
+ Slogan: "Ship dApps without the stress.",
1254
+ Tags: "Blockchain, Cheerful, Developer"
1255
+ }, {
1256
+ Slogan: "No boilerplate, no problem — Decaf-TS your data.",
1257
+ Tags: "Data, No-CRUD, Chill"
1258
+ }, {
1259
+ Slogan: "From DID to UI, without breaking a sweat.",
1260
+ Tags: "DID, SSI, UI, Calm"
1261
+ }, {
1262
+ Slogan: "Decaf-TS-TS: Your frontend already understands your blockchain contract.",
1263
+ Tags: "Smart Contracts, DX, Magic"
1264
+ }, {
1265
+ Slogan: "Self-sovereign by design. Productive by default.",
1266
+ Tags: "SSI, Developer, Calm"
1267
+ }, {
1268
+ Slogan: "Build once. Deploy everywhere. Decentralized and delightful.",
1269
+ Tags: "Blockchain, Multi-platform, Happy"
1270
+ }, {
1271
+ Slogan: "Data that defines its own destiny.",
1272
+ Tags: "SSI, Data-driven, Empowerment"
1273
+ }, {
1274
+ Slogan: "Goodbye boilerplate, hello intent-based interfaces.",
1275
+ Tags: "No-CRUD, UI, Technical"
1276
+ }, {
1277
+ Slogan: "The smoothest path from DID to done.",
1278
+ Tags: "DID, Workflow, Chill"
1279
+ }, {
1280
+ Slogan: "Because your dApp deserves more than boilerplate.",
1281
+ Tags: "Blockchain, DevX, Efficiency"
1282
+ }, {
1283
+ Slogan: "Own your data. Own your flow.",
1284
+ Tags: "SSI, Control, Ownership"
1285
+ }, {
1286
+ Slogan: "Write logic like it belongs with the data — because it does.",
1287
+ Tags: "Data Logic, Developer, Smart"
1288
+ }, {
1289
+ Slogan: "From blockchain contracts to smarter frontends.",
1290
+ Tags: "Smart Contracts, UI, DX"
1291
+ }, {
1292
+ Slogan: "No caffeine. No boilerplate. Just the future.",
1293
+ Tags: "No-CRUD, Coffee-themed, Futuristic"
1294
+ }, {
1295
+ Slogan: "The future of web3 UX is Decaf-TS.",
1296
+ Tags: "Blockchain, UX, Vision"
1297
+ }, {
1298
+ Slogan: "Code with confidence. Govern with clarity.",
1299
+ Tags: "Blockchain, Governance, Calm"
1300
+ }, {
1301
+ Slogan: "Interfaces that obey the data, not the other way around.",
1302
+ Tags: "UI, Data Logic, Self-aware"
1303
+ }, {
1304
+ Slogan: "Brew business logic right into your bytes.",
1305
+ Tags: "Data Logic, Coffee-themed, Fun"
1306
+ }, {
1307
+ Slogan: "DIDs done differently — and delightfully.",
1308
+ Tags: "DID, Self-Sovereign, Playful"
1309
+ }, {
1310
+ Slogan: "Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",
1311
+ Tags: "Blockchain, Smart Contracts, Tech"
1312
+ }, {
1313
+ Slogan: "Ship dApps without the stress.",
1314
+ Tags: "Blockchain, Cheerful, Developer"
1315
+ }, {
1316
+ Slogan: "No boilerplate, no problem — Decaf-TS your data.",
1317
+ Tags: "Data, No-CRUD, Chill"
1318
+ }, {
1319
+ Slogan: "From DID to UI, without breaking a sweat.",
1320
+ Tags: "DID, SSI, UI, Calm"
1321
+ }, {
1322
+ Slogan: "Decaf-TS-TS: Your frontend already understands your blockchain contract.",
1323
+ Tags: "Smart Contracts, DX, Magic"
1324
+ }, {
1325
+ Slogan: "Self-sovereign by design. Productive by default.",
1326
+ Tags: "SSI, Developer, Calm"
1327
+ }, {
1328
+ Slogan: "Build once. Deploy everywhere. Decentralized and delightful.",
1329
+ Tags: "Blockchain, Multi-platform, Happy"
1330
+ }, {
1331
+ Slogan: "Data that defines its own destiny.",
1332
+ Tags: "SSI, Data-driven, Empowerment"
1333
+ }, {
1334
+ Slogan: "Goodbye boilerplate, hello intent-based interfaces.",
1335
+ Tags: "No-CRUD, UI, Technical"
1336
+ }, {
1337
+ Slogan: "The smoothest path from DID to done.",
1338
+ Tags: "DID, Workflow, Chill"
1339
+ }, {
1340
+ Slogan: "Because your dApp deserves more than boilerplate.",
1341
+ Tags: "Blockchain, DevX, Efficiency"
1342
+ }, {
1343
+ Slogan: "Own your data. Own your flow.",
1344
+ Tags: "SSI, Control, Ownership"
1345
+ }, {
1346
+ Slogan: "Write logic like it belongs with the data — because it does.",
1347
+ Tags: "Data Logic, Developer, Smart"
1348
+ }, {
1349
+ Slogan: "From blockchain contracts to smarter frontends.",
1350
+ Tags: "Smart Contracts, UI, DX"
1351
+ }, {
1352
+ Slogan: "No caffeine. No boilerplate. Just the future.",
1353
+ Tags: "No-CRUD, Coffee-themed, Futuristic"
1354
+ }, {
1355
+ Slogan: "The future of web3 UX is Decaf-TS.",
1356
+ Tags: "Blockchain, UX, Vision"
1357
+ }, {
1358
+ Slogan: "Code with confidence. Govern with clarity.",
1359
+ Tags: "Blockchain, Governance, Calm"
1360
+ }, {
1361
+ Slogan: "Interfaces that obey the data, not the other way around.",
1362
+ Tags: "UI, Data Logic, Self-aware"
1363
+ }, {
1364
+ Slogan: "Brew business logic right into your bytes.",
1365
+ Tags: "Data Logic, Coffee-themed, Fun"
1366
+ }, {
1367
+ Slogan: "DIDs done differently — and delightfully.",
1368
+ Tags: "DID, Self-Sovereign, Playful"
1369
+ }, {
1370
+ Slogan: "Decaf-TS-TS: Where blockchain contracts meet smart interfaces.",
1371
+ Tags: "Blockchain, Smart Contracts, Tech"
1372
+ }, {
1373
+ Slogan: "Ship dApps without the stress.",
1374
+ Tags: "Blockchain, Cheerful, Developer"
1375
+ }, {
1376
+ Slogan: "No boilerplate, no problem — Decaf-TS your data.",
1377
+ Tags: "Data, No-CRUD, Chill"
1378
+ }, {
1379
+ Slogan: "From DID to UI, without breaking a sweat.",
1380
+ Tags: "DID, SSI, UI, Calm"
1381
+ }, {
1382
+ Slogan: "Decaf-TS-TS: Your frontend already understands your blockchain contract.",
1383
+ Tags: "Smart Contracts, DX, Magic"
1384
+ }, {
1385
+ Slogan: "Self-sovereign by design. Productive by default.",
1386
+ Tags: "SSI, Developer, Calm"
1387
+ }, {
1388
+ Slogan: "Build once. Deploy everywhere. Decentralized and delightful.",
1389
+ Tags: "Blockchain, Multi-platform, Happy"
1390
+ }, {
1391
+ Slogan: "Data that defines its own destiny.",
1392
+ Tags: "SSI, Data-driven, Empowerment"
1393
+ }, {
1394
+ Slogan: "Goodbye boilerplate, hello intent-based interfaces.",
1395
+ Tags: "No-CRUD, UI, Technical"
1396
+ }, {
1397
+ Slogan: "The smoothest path from DID to done.",
1398
+ Tags: "DID, Workflow, Chill"
1399
+ }, {
1400
+ Slogan: "Because your dApp deserves more than boilerplate.",
1401
+ Tags: "Blockchain, DevX, Efficiency"
1402
+ }, {
1403
+ Slogan: "Own your data. Own your flow.",
1404
+ Tags: "SSI, Control, Ownership"
1405
+ }, {
1406
+ Slogan: "Write logic like it belongs with the data — because it does.",
1407
+ Tags: "Data Logic, Developer, Smart"
1408
+ }, {
1409
+ Slogan: "From blockchain contracts to smarter frontends.",
1410
+ Tags: "Smart Contracts, UI, DX"
1411
+ }, {
1412
+ Slogan: "No caffeine. No boilerplate. Just the future.",
1413
+ Tags: "No-CRUD, Coffee-themed, Futuristic"
1414
+ }, {
1415
+ Slogan: "The future of web3 UX is Decaf-TS.",
1416
+ Tags: "Blockchain, UX, Vision"
1417
+ }, {
1418
+ Slogan: "Code with confidence. Govern with clarity.",
1419
+ Tags: "Blockchain, Governance, Calm"
1420
+ }, {
1421
+ Slogan: "Interfaces that obey the data, not the other way around.",
1422
+ Tags: "UI, Data Logic, Self-aware"
1423
+ }, {
1424
+ Slogan: "Brew business logic right into your bytes.",
1425
+ Tags: "Data Logic, Coffee-themed, Fun"
1426
+ }, {
1427
+ Slogan: "DIDs done differently — and delightfully.",
1428
+ Tags: "DID, Self-Sovereign, Playful"
1429
+ } ];
1430
+ const colors = [ "", "", "", "", "", "", "", "", "" ];
1431
+ function printBanner(logger) {
1432
+ const message = getSlogan();
1433
+ const banner = `# ░▒▓███████▓▒░ ░▒▓████████▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░ ░▒▓████████▓▒░ ░▒▓████████▓▒░ ░▒▓███████▓▒░ \n# ( ( ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ \n# ) ) ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ \n# [=======] ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░ ░▒▓████████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░ ░▒▓██████▓▒░ \n# \`-----´ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ \n# ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ \n# ░▒▓███████▓▒░ ░▒▓████████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓███████▓▒░ \n#`.split("\n");
1434
+ const maxLength = banner.reduce((max, line) => Math.max(max, line.length), 0);
1435
+ banner.push(`# ${message.padStart(maxLength - 3)}`);
1436
+ banner.forEach((line, index) => {
1437
+ (logger ? logger.info.bind(logger) : console.log.bind(console))(styledStringBuilder.style(line || "").raw(colors[index]).text);
1438
+ });
1439
+ }
1440
+ function getSlogan(i) {
1441
+ try {
1442
+ i = typeof i === "undefined" ? Math.floor(Math.random() * slogans.length) : i;
1443
+ return slogans[i].Slogan;
1444
+ } catch (error) {
1445
+ throw new Error(`Failed to retrieve slogans: ${error}`);
1446
+ }
1447
+ }
1448
+ class Command extends logging.LoggedClass {
1449
+ constructor(name, inputs = {}, requirements = []) {
1450
+ super();
1451
+ this.name = name;
1452
+ this.inputs = inputs;
1453
+ this.requirements = requirements;
1454
+ if (!Command.log) {
1455
+ Object.defineProperty(Command, "log", {
1456
+ writable: false,
1457
+ value: logging.Logging.for(Command.name)
1458
+ });
1459
+ }
1460
+ this.inputs = Object.assign({}, DefaultCommandOptions, inputs);
1461
+ }
1462
+ async checkRequirements() {
1463
+ const {prod: prod, dev: dev, peer: peer} = await getDependencies();
1464
+ const missing = [];
1465
+ const fullList = Array.from(new Set([ ...prod, ...dev, ...peer ]).values()).map(d => d.name);
1466
+ for (const dep of this.requirements) if (!fullList.includes(dep)) missing.push(dep);
1467
+ if (!missing.length) return;
1468
+ }
1469
+ help(args) {
1470
+ return this.log.info(`This is help. I'm no use because I should have been overridden.`);
1471
+ }
1472
+ async execute() {
1473
+ const args = UserInput.parseArgs(this.inputs);
1474
+ const env = logging.LoggedEnvironment.accumulate(DefaultCommandValues).accumulate(args.values);
1475
+ const {version: version, help: help, banner: banner} = env;
1476
+ if (version) {
1477
+ return getPackageVersion();
1478
+ }
1479
+ if (help) {
1480
+ return this.help(args);
1481
+ }
1482
+ if (banner) printBanner(this.log.for(printBanner, {
1483
+ timestamp: false,
1484
+ style: false,
1485
+ context: false,
1486
+ logLevel: false
1487
+ }));
1488
+ let result;
1489
+ try {
1490
+ result = await this.run(env);
1491
+ } catch (e) {
1492
+ throw e;
1493
+ }
1494
+ return result;
1495
+ }
1496
+ }
1497
+ class HttpClient {
1498
+ static {
1499
+ this.log = logging.Logging.for(HttpClient);
1500
+ }
1501
+ static async downloadFile(url) {
1502
+ return new Promise((resolve, reject) => {
1503
+ function request(url) {
1504
+ url = encodeURI(url);
1505
+ https__default["default"].get(url, res => {
1506
+ if (res.statusCode === 301 || res.statusCode === 307) return request(res.headers.location);
1507
+ if (res.statusCode !== 200) {
1508
+ HttpClient.log.error(`Failed to fetch ${url} (status: ${res.statusCode})`);
1509
+ return reject(new Error(`Failed to fetch ${url}`));
1510
+ }
1511
+ let data = "";
1512
+ res.on("data", chunk => {
1513
+ data += chunk;
1514
+ });
1515
+ res.on("error", error => {
1516
+ reject(error);
1517
+ });
1518
+ res.on("end", () => {
1519
+ resolve(data);
1520
+ });
1521
+ });
1522
+ }
1523
+ request(url);
1524
+ });
1525
+ }
1526
+ }
1527
+ function parseList(input) {
1528
+ if (!input) return [];
1529
+ if (Array.isArray(input)) return input.map(i => `${i}`.trim()).filter(Boolean);
1530
+ return `${input}`.split(",").map(p => p.trim()).filter(Boolean);
1531
+ }
1532
+ function packageToGlobal(name) {
1533
+ const withoutScope = name.replace(/^@/, "");
1534
+ const parts = withoutScope.split(/[/\-_.]+/).filter(Boolean);
1535
+ return parts.map((p, i) => i === 0 ? p.replace(/[^a-zA-Z0-9]/g, "") : `${p.charAt(0).toUpperCase()}${p.slice(1)}`).join("");
1536
+ }
1537
+ function getPackageDependencies() {
1538
+ let pkg;
1539
+ try {
1540
+ pkg = getPackage(process.cwd());
1541
+ } catch {
1542
+ pkg = undefined;
1543
+ }
1544
+ try {
1545
+ const hasDeps = pkg && (Object.keys(pkg.dependencies || {}).length > 0 || Object.keys(pkg.devDependencies || {}).length > 0 || Object.keys(pkg.peerDependencies || {}).length > 0);
1546
+ if (!hasDeps) {
1547
+ const fallbackDir = path__default["default"].resolve(__dirname, "../../..");
1548
+ try {
1549
+ pkg = getPackage(fallbackDir);
1550
+ } catch {}
1551
+ }
1552
+ } catch {}
1553
+ const deps = Object.keys(pkg && pkg.dependencies || {});
1554
+ const peer = Object.keys(pkg && pkg.peerDependencies || {});
1555
+ const dev = Object.keys(pkg && pkg.devDependencies || {});
1556
+ return Array.from(new Set([ ...deps, ...peer, ...dev ]));
1557
+ }
1558
+ const VERSION_STRING = "##VERSION##";
1559
+ const PACKAGE_STRING = "##PACKAGE##";
1560
+ const PACKAGE_SIZE_STRING = "##PACKAGE_SIZE##";
1561
+ var Modes;
1562
+ (function(Modes) {
1563
+ Modes["CJS"] = "commonjs";
1564
+ Modes["ESM"] = "es2022";
1565
+ })(Modes || (Modes = {}));
1566
+ var BuildMode;
1567
+ (function(BuildMode) {
1568
+ BuildMode["BUILD"] = "build";
1569
+ BuildMode["BUNDLE"] = "bundle";
1570
+ BuildMode["ALL"] = "all";
1571
+ })(BuildMode || (BuildMode = {}));
1572
+ const options$1 = {
1573
+ prod: {
1574
+ type: "boolean",
1575
+ default: false
1576
+ },
1577
+ dev: {
1578
+ type: "boolean",
1579
+ default: false
1580
+ },
1581
+ buildMode: {
1582
+ type: "string",
1583
+ default: BuildMode.ALL
1584
+ },
1585
+ includes: {
1586
+ type: "string",
1587
+ default: ""
1588
+ },
1589
+ externals: {
1590
+ type: "string",
1591
+ default: ""
1592
+ },
1593
+ docs: {
1594
+ type: "boolean",
1595
+ default: false
1596
+ },
1597
+ commands: {
1598
+ type: "boolean",
1599
+ default: false
1600
+ },
1601
+ banner: {
1602
+ type: "boolean",
1603
+ default: false
1604
+ }
1605
+ };
1606
+ const cjs2Transformer = (ext = ".cjs") => {
1607
+ const log = BuildScripts.log.for(cjs2Transformer);
1608
+ const resolutionCache = new Map;
1609
+ return transformationContext => sourceFile => {
1610
+ const sourceDir = path__default["default"].dirname(sourceFile.fileName);
1611
+ function resolvePath(importPath) {
1612
+ const cacheKey = JSON.stringify([ sourceDir, importPath ]);
1613
+ const cachedValue = resolutionCache.get(cacheKey);
1614
+ if (cachedValue != null) return cachedValue;
1615
+ let resolvedPath = importPath;
1616
+ try {
1617
+ resolvedPath = path__default["default"].resolve(sourceDir, resolvedPath + ".ts");
1618
+ } catch (error) {
1619
+ throw new Error(`Failed to resolve path ${importPath}: ${error}`);
1620
+ }
1621
+ let stat;
1622
+ try {
1623
+ stat = fs__default["default"].statSync(resolvedPath);
1624
+ } catch (e) {
1625
+ try {
1626
+ log.verbose(`Testing existence of path ${resolvedPath} as a folder defaulting to index file`);
1627
+ stat = fs__default["default"].statSync(resolvedPath.replace(/\.ts$/gm, ""));
1628
+ } catch (e2) {
1629
+ throw new Error(`Failed to resolve path ${importPath}: ${e}, ${e2}`);
1630
+ }
1631
+ }
1632
+ if (stat.isDirectory()) resolvedPath = resolvedPath.replace(/\.ts$/gm, "/index.ts");
1633
+ if (path__default["default"].isAbsolute(resolvedPath)) {
1634
+ const extension = (/\.tsx?$/.exec(path__default["default"].basename(resolvedPath)) || [])[0] || void 0;
1635
+ resolvedPath = "./" + path__default["default"].relative(sourceDir, path__default["default"].resolve(path__default["default"].dirname(resolvedPath), path__default["default"].basename(resolvedPath, extension) + ext));
1636
+ }
1637
+ resolutionCache.set(cacheKey, resolvedPath);
1638
+ return resolvedPath;
1639
+ }
1640
+ function visitNode(node) {
1641
+ if (shouldMutateModuleSpecifier(node)) {
1642
+ if (ts__namespace.isImportDeclaration(node)) {
1643
+ const resolvedPath = resolvePath(node.moduleSpecifier.text);
1644
+ const newModuleSpecifier = transformationContext.factory.createStringLiteral(resolvedPath);
1645
+ return transformationContext.factory.updateImportDeclaration(node, node.modifiers, node.importClause, newModuleSpecifier, undefined);
1646
+ } else if (ts__namespace.isExportDeclaration(node)) {
1647
+ const resolvedPath = resolvePath(node.moduleSpecifier.text);
1648
+ const newModuleSpecifier = transformationContext.factory.createStringLiteral(resolvedPath);
1649
+ return transformationContext.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, newModuleSpecifier, undefined);
1650
+ }
1651
+ }
1652
+ return ts__namespace.visitEachChild(node, visitNode, transformationContext);
1653
+ }
1654
+ function shouldMutateModuleSpecifier(node) {
1655
+ if (!ts__namespace.isImportDeclaration(node) && !ts__namespace.isExportDeclaration(node)) return false;
1656
+ if (node.moduleSpecifier === undefined) return false;
1657
+ if (!ts__namespace.isStringLiteral(node.moduleSpecifier)) return false;
1658
+ if (!node.moduleSpecifier.text.startsWith("./") && !node.moduleSpecifier.text.startsWith("../")) return false;
1659
+ if (path__default["default"].extname(node.moduleSpecifier.text) !== "") return false;
1660
+ return true;
1661
+ }
1662
+ return ts__namespace.visitNode(sourceFile, visitNode);
1663
+ };
1664
+ };
1665
+ class BuildScripts extends Command {
1666
+ constructor() {
1667
+ super("BuildScripts", Object.assign({}, DefaultCommandOptions, options$1));
1668
+ this.replacements = {};
1669
+ const pkg = getPackage();
1670
+ const {name: name, version: version} = pkg;
1671
+ this.pkgName = name.includes("@") ? name.split("/")[1] : name;
1672
+ this.pkgVersion = version;
1673
+ this.replacements[VERSION_STRING] = this.pkgVersion;
1674
+ this.replacements[PACKAGE_STRING] = name;
1675
+ }
1676
+ patchFiles(p) {
1677
+ const log = this.log.for(this.patchFiles);
1678
+ const {name: name, version: version} = getPackage();
1679
+ log.info(`Patching ${name} ${version} module in ${p}...`);
1680
+ const stat = fs__default["default"].statSync(p);
1681
+ if (stat.isDirectory()) fs__default["default"].readdirSync(p, {
1682
+ withFileTypes: true,
1683
+ recursive: true
1684
+ }).filter(p => p.isFile()).forEach(file => patchFile(path__default["default"].join(file.parentPath, file.name), Object.entries(this.replacements).reduce((acc, [key, val]) => {
1685
+ switch (key) {
1686
+ case VERSION_STRING:
1687
+ log.debug("Found VERSION string to replace");
1688
+ acc[`VERSION = "${VERSION_STRING}";`] = `VERSION = "${val}";`;
1689
+ break;
1690
+
1691
+ case PACKAGE_STRING:
1692
+ log.debug("Found PACKAGE_NAME string to replace");
1693
+ acc[`PACKAGE_NAME = "${PACKAGE_STRING}";`] = `PACKAGE_NAME = "${val}";`;
1694
+ break;
1695
+
1696
+ default:
1697
+ acc[key] = val;
1698
+ }
1699
+ return acc;
1700
+ }, {})));
1701
+ log.verbose(`Module ${name} ${version} patched in ${p}...`);
1702
+ }
1703
+ reportDiagnostics(diagnostics, logLevel) {
1704
+ const msg = this.formatDiagnostics(diagnostics);
1705
+ try {
1706
+ this.log[logLevel](msg);
1707
+ } catch (e) {
1708
+ console.warn(`Failed to get logger for ${logLevel}`);
1709
+ throw e;
1710
+ }
1711
+ return msg;
1712
+ }
1713
+ formatDiagnostics(diagnostics) {
1714
+ return diagnostics.map(diagnostic => {
1715
+ let message = "";
1716
+ if (diagnostic.file && diagnostic.start) {
1717
+ const {line: line, character: character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
1718
+ message += `${diagnostic.file.fileName} (${line + 1},${character + 1})`;
1719
+ }
1720
+ message += ": " + ts__namespace.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
1721
+ return message;
1722
+ }).join("\n");
1723
+ }
1724
+ readConfigFile(configFileName) {
1725
+ const configFileText = fs__default["default"].readFileSync(configFileName).toString();
1726
+ const result = ts__namespace.parseConfigFileTextToJson(configFileName, configFileText);
1727
+ const configObject = result.config;
1728
+ if (!configObject) {
1729
+ this.reportDiagnostics([ result.error ], logging.LogLevel.error);
1730
+ }
1731
+ const configParseResult = ts__namespace.parseJsonConfigFileContent(configObject, ts__namespace.sys, path__default["default"].dirname(configFileName));
1732
+ if (configParseResult.errors.length > 0) this.reportDiagnostics(configParseResult.errors, logging.LogLevel.error);
1733
+ return configParseResult;
1734
+ }
1735
+ evalDiagnostics(diagnostics) {
1736
+ if (diagnostics && diagnostics.length > 0) {
1737
+ const errors = diagnostics.filter(d => d.category === ts__namespace.DiagnosticCategory.Error);
1738
+ const warnings = diagnostics.filter(d => d.category === ts__namespace.DiagnosticCategory.Warning);
1739
+ const suggestions = diagnostics.filter(d => d.category === ts__namespace.DiagnosticCategory.Suggestion);
1740
+ const messages = diagnostics.filter(d => d.category === ts__namespace.DiagnosticCategory.Message);
1741
+ if (warnings.length) this.reportDiagnostics(warnings, logging.LogLevel.warn);
1742
+ if (errors.length) {
1743
+ this.reportDiagnostics(diagnostics, logging.LogLevel.error);
1744
+ throw new Error(`TypeScript reported ${diagnostics.length} diagnostic(s) during check; aborting.`);
1745
+ }
1746
+ if (suggestions.length) this.reportDiagnostics(suggestions, logging.LogLevel.info);
1747
+ if (messages.length) this.reportDiagnostics(messages, logging.LogLevel.info);
1748
+ }
1749
+ }
1750
+ preCheckDiagnostics(program) {
1751
+ const diagnostics = ts__namespace.getPreEmitDiagnostics(program);
1752
+ this.evalDiagnostics(diagnostics);
1753
+ }
1754
+ async checkTsDiagnostics(isDev, mode, bundle = false) {
1755
+ const log = this.log.for(this.checkTsDiagnostics);
1756
+ let tsConfig;
1757
+ try {
1758
+ tsConfig = this.readConfigFile("./tsconfig.json");
1759
+ } catch (e) {
1760
+ throw new Error(`Failed to parse tsconfig.json: ${e}`);
1761
+ }
1762
+ if (bundle) {
1763
+ tsConfig.options.module = ts.ModuleKind.AMD;
1764
+ tsConfig.options.outDir = "dist";
1765
+ tsConfig.options.isolatedModules = false;
1766
+ tsConfig.options.outFile = this.pkgName;
1767
+ } else {
1768
+ tsConfig.options.outDir = `lib${mode === Modes.ESM ? "/esm" : ""}`;
1769
+ tsConfig.options.module = mode === Modes.ESM ? ts.ModuleKind.ES2022 : ts.ModuleKind.CommonJS;
1770
+ }
1771
+ tsConfig.options.inlineSourceMap = false;
1772
+ tsConfig.options.inlineSources = false;
1773
+ tsConfig.options.sourceMap = true;
1774
+ const program = ts__namespace.createProgram(tsConfig.fileNames, tsConfig.options);
1775
+ this.preCheckDiagnostics(program);
1776
+ log.verbose(`TypeScript checks passed (${bundle ? "bundle" : "normal"} mode).`);
1777
+ }
1778
+ async buildTs(isDev, mode, bundle = false) {
1779
+ const log = this.log.for(this.buildTs);
1780
+ log.info(`Building ${this.pkgName} ${this.pkgVersion} module (${mode}) in ${isDev ? "dev" : "prod"} mode...`);
1781
+ let tsConfig;
1782
+ try {
1783
+ tsConfig = this.readConfigFile("./tsconfig.json");
1784
+ } catch (e) {
1785
+ throw new Error(`Failed to parse tsconfig.json: ${e}`);
1786
+ }
1787
+ if (bundle) {
1788
+ tsConfig.options.module = ts.ModuleKind.AMD;
1789
+ tsConfig.options.outDir = "dist";
1790
+ tsConfig.options.isolatedModules = false;
1791
+ tsConfig.options.outFile = this.pkgName;
1792
+ } else {
1793
+ tsConfig.options.outDir = `lib${mode === Modes.ESM ? "/esm" : ""}`;
1794
+ tsConfig.options.module = mode === Modes.ESM ? ts.ModuleKind.ES2022 : ts.ModuleKind.CommonJS;
1795
+ }
1796
+ if (isDev) {
1797
+ tsConfig.options.inlineSourceMap = true;
1798
+ tsConfig.options.inlineSources = true;
1799
+ tsConfig.options.sourceMap = false;
1800
+ } else {
1801
+ tsConfig.options.inlineSourceMap = false;
1802
+ tsConfig.options.inlineSources = false;
1803
+ tsConfig.options.sourceMap = true;
1804
+ }
1805
+ const program = ts__namespace.createProgram(tsConfig.fileNames, tsConfig.options);
1806
+ const transformations = {};
1807
+ if (mode === Modes.CJS) {
1808
+ transformations.before = [ cjs2Transformer(".cjs") ];
1809
+ } else if (mode === Modes.ESM) {
1810
+ transformations.before = [ cjs2Transformer(".js") ];
1811
+ }
1812
+ const emitResult = program.emit(undefined, undefined, undefined, undefined, transformations);
1813
+ const allDiagnostics = ts__namespace.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
1814
+ this.evalDiagnostics(allDiagnostics);
1815
+ }
1816
+ async build(isDev, mode, bundle = false) {
1817
+ const log = this.log.for(this.build);
1818
+ await this.buildTs(isDev, mode, bundle);
1819
+ log.verbose(`Module ${this.pkgName} ${this.pkgVersion} (${mode}) built in ${isDev ? "dev" : "prod"} mode...`);
1820
+ if (mode === Modes.CJS && !bundle) {
1821
+ const files = getAllFiles("lib", file => file.endsWith(".js") && !file.includes("/esm/"));
1822
+ for (const file of files) {
1823
+ log.verbose(`Patching ${file}'s cjs imports...`);
1824
+ const f = file.replace(".js", ".cjs");
1825
+ await renameFile(file, f);
1826
+ }
1827
+ }
1828
+ }
1829
+ copyAssets(mode) {
1830
+ const log = this.log.for(this.copyAssets);
1831
+ let hasAssets = false;
1832
+ try {
1833
+ hasAssets = fs__default["default"].statSync("./src/assets").isDirectory();
1834
+ } catch (e) {
1835
+ return log.verbose(`No assets found in ./src/assets to copy`);
1836
+ }
1837
+ if (hasAssets) copyFile("./src/assets", `./${mode === Modes.CJS ? "lib" : "dist"}/assets`);
1838
+ }
1839
+ async bundle(mode, isDev, isLib, entryFile = "src/index.ts", nameOverride = this.pkgName, externalsArg, includeArg = [ "prompts", "styled-string-builder", "typed-object-accumulator", "@decaf-ts/logging" ]) {
1840
+ await this.checkTsDiagnostics(isDev, mode, true);
1841
+ const isEsm = mode === Modes.ESM;
1842
+ const pkgName = this.pkgName;
1843
+ const log = this.log;
1844
+ const include = Array.from(new Set([ ...parseList(includeArg) ]));
1845
+ let externalsList = parseList(externalsArg);
1846
+ if (externalsList.length === 0) {
1847
+ try {
1848
+ externalsList = listNodeModulesPackages(path__default["default"].join(process.cwd(), "node_modules"));
1849
+ } catch {}
1850
+ if (!externalsList || externalsList.length === 0) {
1851
+ externalsList = getPackageDependencies();
1852
+ }
1853
+ }
1854
+ const ext = Array.from(new Set([ ...function builtinList() {
1855
+ try {
1856
+ return Array.isArray(module.builtinModules) ? module.builtinModules : [];
1857
+ } catch {
1858
+ return [ "fs", "path", "process", "child_process", "util", "https", "http", "os", "stream", "crypto", "zlib", "net", "tls", "url", "querystring", "assert", "events", "tty", "dns", "querystring" ];
1859
+ }
1860
+ }(), ...externalsList ]));
1861
+ const rollupSourceMapOutput = isDev ? "inline" : true;
1862
+ const plugins = [ typescript__default["default"]({
1863
+ compilerOptions: {
1864
+ module: "esnext",
1865
+ declaration: false,
1866
+ outDir: isLib ? "bin" : "dist",
1867
+ sourceMap: isDev ? false : true,
1868
+ inlineSourceMap: isDev ? true : false,
1869
+ inlineSources: isDev ? true : false
1870
+ },
1871
+ include: [ "src/**/*.ts" ],
1872
+ exclude: [ "node_modules", "**/*.spec.ts" ],
1873
+ tsconfig: "./tsconfig.json"
1874
+ }), json__default["default"]() ];
1875
+ if (isLib) {
1876
+ plugins.push(commonjs__default["default"]({
1877
+ include: [],
1878
+ exclude: externalsList
1879
+ }), pluginNodeResolve.nodeResolve({
1880
+ resolveOnly: include
1881
+ }));
1882
+ }
1883
+ try {
1884
+ const terserMod = await import("@rollup/plugin-terser");
1885
+ const terserFn = terserMod && terserMod.terser || terserMod.default || terserMod;
1886
+ const terserOptionsDev = {
1887
+ parse: {
1888
+ ecma: 2020
1889
+ },
1890
+ compress: false,
1891
+ mangle: false,
1892
+ format: {
1893
+ comments: false,
1894
+ beautify: true
1895
+ }
1896
+ };
1897
+ const terserOptionsProd = {
1898
+ parse: {
1899
+ ecma: 2020
1900
+ },
1901
+ compress: {
1902
+ ecma: 2020,
1903
+ passes: 5,
1904
+ drop_console: true,
1905
+ drop_debugger: true,
1906
+ toplevel: true,
1907
+ module: isEsm,
1908
+ unsafe: true,
1909
+ unsafe_arrows: true,
1910
+ unsafe_comps: true,
1911
+ collapse_vars: true,
1912
+ reduce_funcs: true,
1913
+ reduce_vars: true
1914
+ },
1915
+ mangle: {
1916
+ toplevel: true
1917
+ },
1918
+ format: {
1919
+ comments: false,
1920
+ ascii_only: true
1921
+ },
1922
+ toplevel: true
1923
+ };
1924
+ plugins.push(terserFn(isDev ? terserOptionsDev : terserOptionsProd));
1925
+ } catch {}
1926
+ const input = {
1927
+ input: entryFile,
1928
+ plugins: plugins,
1929
+ external: ext,
1930
+ onwarn: undefined,
1931
+ treeshake: !isDev
1932
+ };
1933
+ const globals = {};
1934
+ ext.forEach(e => {
1935
+ globals[e] = packageToGlobal(e);
1936
+ });
1937
+ const outputs = [ {
1938
+ file: `${isLib ? "bin/" : "dist/"}${nameOverride ? nameOverride : `.bundle.${!isDev ? "min" : ""}`}${isEsm ? ".js" : ".cjs"}`,
1939
+ format: isLib ? "cjs" : isEsm ? "esm" : "umd",
1940
+ name: pkgName,
1941
+ esModule: isEsm,
1942
+ sourcemap: rollupSourceMapOutput,
1943
+ globals: globals,
1944
+ exports: "auto"
1945
+ } ];
1946
+ try {
1947
+ const bundle = await rollup.rollup(input);
1948
+ log.verbose(bundle.watchFiles);
1949
+ async function generateOutputs(bundle) {
1950
+ for (const outputOptions of outputs) {
1951
+ await bundle.write(outputOptions);
1952
+ }
1953
+ }
1954
+ await generateOutputs(bundle);
1955
+ } catch (e) {
1956
+ throw new Error(`Failed to bundle: ${e}`);
1957
+ }
1958
+ }
1959
+ async buildByEnv(isDev, mode = BuildMode.ALL, includesArg, externalsArg) {
1960
+ try {
1961
+ deletePath("lib");
1962
+ } catch (e) {}
1963
+ try {
1964
+ deletePath("dist");
1965
+ } catch (e) {}
1966
+ fs__default["default"].mkdirSync("lib");
1967
+ fs__default["default"].mkdirSync("dist");
1968
+ if ([ BuildMode.ALL, BuildMode.BUILD ].includes(mode)) {
1969
+ await this.build(isDev, Modes.ESM);
1970
+ await this.build(isDev, Modes.CJS);
1971
+ this.patchFiles("lib");
1972
+ }
1973
+ if ([ BuildMode.ALL, BuildMode.BUNDLE ].includes(mode)) {
1974
+ await this.bundle(Modes.ESM, isDev, false, "src/index.ts", this.pkgName, externalsArg, includesArg);
1975
+ await this.bundle(Modes.CJS, isDev, false, "src/index.ts", this.pkgName, externalsArg, includesArg);
1976
+ this.patchFiles("dist");
1977
+ }
1978
+ this.copyAssets(Modes.CJS);
1979
+ this.copyAssets(Modes.ESM);
1980
+ }
1981
+ async buildDev(mode = BuildMode.ALL, includesArg, externalsArg) {
1982
+ return this.buildByEnv(true, mode, includesArg, externalsArg);
1983
+ }
1984
+ async buildProd(mode = BuildMode.ALL, includesArg, externalsArg) {
1985
+ return this.buildByEnv(false, mode, includesArg, externalsArg);
1986
+ }
1987
+ async buildDocs() {
1988
+ await runCommand(`npm install better-docs taffydb`).promise;
1989
+ await runCommand(`npx markdown-include ./workdocs/readme-md.json`).promise;
1990
+ await runCommand(`npx jsdoc -c ./workdocs/jsdocs.json -t ./node_modules/better-docs`).promise;
1991
+ await runCommand(`npm remove better-docs taffydb`).promise;
1992
+ [ {
1993
+ src: "workdocs/assets",
1994
+ dest: "./docs/workdocs/assets"
1995
+ }, {
1996
+ src: "workdocs/reports/coverage",
1997
+ dest: "./docs/workdocs/reports/coverage"
1998
+ }, {
1999
+ src: "workdocs/reports/html",
2000
+ dest: "./docs/workdocs/reports/html"
2001
+ }, {
2002
+ src: "workdocs/resources",
2003
+ dest: "./docs/workdocs/resources"
2004
+ }, {
2005
+ src: "LICENSE.md",
2006
+ dest: "./docs/LICENSE.md"
2007
+ } ].forEach(f => {
2008
+ const {src: src, dest: dest} = f;
2009
+ copyFile(src, dest);
2010
+ });
2011
+ try {
2012
+ const sizeKb = await getFileSizeZipped(path__default["default"].resolve(path__default["default"].join(process.cwd(), "dist")));
2013
+ this.replacements[PACKAGE_SIZE_STRING] = `${sizeKb} KB`;
2014
+ } catch {
2015
+ this.replacements[PACKAGE_SIZE_STRING] = "unknown";
2016
+ }
2017
+ try {
2018
+ patchFile("./README.md", this.replacements);
2019
+ } catch (e) {
2020
+ const log = this.log.for(this.buildDocs);
2021
+ log.verbose(`Failed to patch README.md: ${e}`);
2022
+ }
2023
+ }
2024
+ async run(answers) {
2025
+ const {dev: dev, prod: prod, docs: docs, buildMode: buildMode, includes: includes, externals: externals} = answers;
2026
+ if (dev) {
2027
+ return await this.buildDev(buildMode, includes, externals);
2028
+ }
2029
+ if (prod) {
2030
+ return await this.buildProd(buildMode, includes, externals);
2031
+ }
2032
+ if (docs) {
2033
+ return await this.buildDocs();
2034
+ }
2035
+ }
2036
+ }
2037
+ const options = {
2038
+ ci: {
2039
+ type: "boolean",
2040
+ default: true
2041
+ },
2042
+ message: {
2043
+ type: "string",
2044
+ short: "m"
2045
+ },
2046
+ tag: {
2047
+ type: "string",
2048
+ short: "t",
2049
+ default: undefined
2050
+ }
2051
+ };
2052
+ class ReleaseScript extends Command {
2053
+ constructor() {
2054
+ super("ReleaseScript", options);
2055
+ }
2056
+ async prepareVersion(tag) {
2057
+ const log = this.log.for(this.prepareVersion);
2058
+ tag = this.testVersion(tag || "");
2059
+ if (!tag) {
2060
+ log.verbose("No release message provided. Prompting for one:");
2061
+ log.info(`Listing latest git tags:`);
2062
+ await runCommand("git tag --sort=-taggerdate | head -n 5").promise;
2063
+ return await UserInput.insistForText("tag", "Enter the new tag number (accepts v*.*.*[-...])", val => !!val.toString().match(/^v[0-9]+\.[0-9]+.[0-9]+(-[0-9a-zA-Z-]+)?$/));
2064
+ }
2065
+ return tag;
2066
+ }
2067
+ testVersion(version) {
2068
+ const log = this.log.for(this.testVersion);
2069
+ version = version.trim().toLowerCase();
2070
+ switch (version) {
2071
+ case exports.SemVersion.PATCH:
2072
+ case exports.SemVersion.MINOR:
2073
+ case exports.SemVersion.MAJOR:
2074
+ log.verbose(`Using provided SemVer update: ${version}`, 1);
2075
+ return version;
2076
+
2077
+ default:
2078
+ log.verbose(`Testing provided version for SemVer compatibility: ${version}`, 1);
2079
+ if (!new RegExp(SemVersionRegex).test(version)) {
2080
+ log.debug(`Invalid version number: ${version}`);
2081
+ return undefined;
2082
+ }
2083
+ log.verbose(`version approved: ${version}`, 1);
2084
+ return version;
2085
+ }
2086
+ }
2087
+ async prepareMessage(message) {
2088
+ const log = this.log.for(this.prepareMessage);
2089
+ if (!message) {
2090
+ log.verbose("No release message provided. Prompting for one");
2091
+ return await UserInput.insistForText("message", "What should be the release message/ticket?", val => !!val && val.toString().length > 5);
2092
+ }
2093
+ return message;
2094
+ }
2095
+ async run(args) {
2096
+ let result;
2097
+ const {ci: ci} = args;
2098
+ let {tag: tag, message: message} = args;
2099
+ tag = await this.prepareVersion(tag);
2100
+ message = await this.prepareMessage(message);
2101
+ result = await runCommand(`npm run prepare-release -- ${tag} ${message}`, {
2102
+ cwd: process.cwd()
2103
+ }).promise;
2104
+ result = await runCommand("git status --porcelain").promise;
2105
+ await result;
2106
+ if (result.logs.length && await UserInput.askConfirmation("git-changes", "Do you want to push the changes to the remote repository?", true)) {
2107
+ await runCommand("git add .").promise;
2108
+ await runCommand(`git commit -m "${tag} - ${message} - after release preparation${ci ? "" : NoCIFLag}"`).promise;
2109
+ }
2110
+ await runCommand(`npm version "${tag}" -m "${message}${ci ? "" : NoCIFLag}"`).promise;
2111
+ await runCommand("git push --follow-tags").promise;
2112
+ if (!ci) {
2113
+ await runCommand("NPM_TOKEN=$(cat .npmtoken) npm publish --access public").promise;
2114
+ }
2115
+ }
2116
+ }
2117
+ class RegexpOutputWriter extends StandardOutputWriter {
2118
+ constructor(cmd, lock, regexp, flags = "g") {
2119
+ super(cmd, lock);
2120
+ try {
2121
+ this.regexp = typeof regexp === "string" ? new RegExp(regexp, flags) : regexp;
2122
+ } catch (e) {
2123
+ throw new Error(`Invalid regular expression: ${e}`);
2124
+ }
2125
+ }
2126
+ test(data) {
2127
+ this.regexp.lastIndex = 0;
2128
+ let match;
2129
+ try {
2130
+ match = this.regexp.exec(data);
2131
+ } catch (e) {
2132
+ return console.debug(`Failed to parse chunk: ${data}\nError: ${e} `);
2133
+ }
2134
+ return match;
2135
+ }
2136
+ testAndResolve(data) {
2137
+ const match = this.test(data);
2138
+ if (match) this.resolve(match[0]);
2139
+ }
2140
+ testAndReject(data) {
2141
+ const match = this.test(data);
2142
+ if (match) this.reject(match[0]);
2143
+ }
2144
+ data(chunk) {
2145
+ super.data(chunk);
2146
+ this.testAndResolve(String(chunk));
2147
+ }
2148
+ error(chunk) {
2149
+ super.error(chunk);
2150
+ this.testAndReject(String(chunk));
2151
+ }
2152
+ }
2153
+ const VERSION = "0.11.3";
2154
+ const PACKAGE_NAME = "@decaf-ts/utils";
2155
+ exports.AbortCode = AbortCode;
2156
+ exports.BuildScripts = BuildScripts;
2157
+ exports.Command = Command;
2158
+ exports.DefaultCommandOptions = DefaultCommandOptions;
2159
+ exports.DefaultCommandValues = DefaultCommandValues;
2160
+ exports.Encoding = Encoding;
2161
+ exports.HttpClient = HttpClient;
2162
+ exports.NoCIFLag = NoCIFLag;
2163
+ exports.PACKAGE_NAME = PACKAGE_NAME;
2164
+ exports.RegexpOutputWriter = RegexpOutputWriter;
2165
+ exports.ReleaseScript = ReleaseScript;
2166
+ exports.SemVersionRegex = SemVersionRegex;
2167
+ exports.SetupScriptKey = SetupScriptKey;
2168
+ exports.StandardOutputWriter = StandardOutputWriter;
2169
+ exports.UserInput = UserInput;
2170
+ exports.VERSION = VERSION;
2171
+ exports.chainAbortController = chainAbortController;
2172
+ exports.copyFile = copyFile;
2173
+ exports.deletePath = deletePath;
2174
+ exports.getAllFiles = getAllFiles;
2175
+ exports.getDependencies = getDependencies;
2176
+ exports.getFileSizeZipped = getFileSizeZipped;
2177
+ exports.getPackage = getPackage;
2178
+ exports.getPackageDependencies = getPackageDependencies;
2179
+ exports.getPackageVersion = getPackageVersion;
2180
+ exports.getSlogan = getSlogan;
2181
+ exports.installDependencies = installDependencies;
2182
+ exports.installIfNotAvailable = installIfNotAvailable;
2183
+ exports.listFolder = listFolder;
2184
+ exports.listNodeModulesPackages = listNodeModulesPackages;
2185
+ exports.lockify = lockify;
2186
+ exports.normalizeImport = normalizeImport;
2187
+ exports.packageToGlobal = packageToGlobal;
2188
+ exports.parseList = parseList;
2189
+ exports.patchFile = patchFile;
2190
+ exports.printBanner = printBanner;
2191
+ exports.pushToGit = pushToGit;
2192
+ exports.readFile = readFile;
2193
+ exports.renameFile = renameFile;
2194
+ exports.runCommand = runCommand;
2195
+ exports.setPackageAttribute = setPackageAttribute;
2196
+ exports.spawnCommand = spawnCommand;
2197
+ exports.updateDependencies = updateDependencies;
2198
+ exports.writeFile = writeFile;
2199
+ });
2200
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuY2pzIiwic291cmNlcyI6WyIuLi9zcmMvaW5wdXQvaW5wdXQudHMiLCIuLi9zcmMvY2xpL2NvbnN0YW50cy50cyIsIi4uL3NyYy91dGlscy9jb25zdGFudHMudHMiLCIuLi9zcmMvd3JpdGVycy9TdGFuZGFyZE91dHB1dFdyaXRlci50cyIsIi4uL3NyYy91dGlscy91dGlscy50cyIsIi4uL3NyYy91dGlscy9mcy50cyIsIi4uL3NyYy9hc3NldHMvc2xvZ2Fucy50cyIsIi4uL3NyYy9vdXRwdXQvY29tbW9uLnRzIiwiLi4vc3JjL2NsaS9jb21tYW5kLnRzIiwiLi4vc3JjL3V0aWxzL2h0dHAudHMiLCIuLi9zcmMvY2xpL2NvbW1hbmRzL2J1aWxkLXNjcmlwdHMudHMiLCIuLi9zcmMvY2xpL2NvbW1hbmRzL3RhZy1yZWxlYXNlLnRzIiwiLi4vc3JjL3dyaXRlcnMvUmVnZXhwT3V0cHV0V3JpdGVyLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFuc3dlcnMsXG4gIENob2ljZSxcbiAgRmFsc3ksXG4gIEluaXRpYWxSZXR1cm5WYWx1ZSxcbiAgUHJldkNhbGxlcixcbiAgUHJvbXB0T2JqZWN0LFxuICBQcm9tcHRUeXBlLFxuICBWYWx1ZU9yRnVuYyxcbn0gZnJvbSBcInByb21wdHNcIjtcbmltcG9ydCBwcm9tcHRzIGZyb20gXCJwcm9tcHRzXCI7XG5pbXBvcnQgeyBwYXJzZUFyZ3MsIFBhcnNlQXJnc0NvbmZpZyB9IGZyb20gXCJ1dGlsXCI7XG5pbXBvcnQgeyBXcml0YWJsZSwgUmVhZGFibGUgfSBmcm9tIFwic3RyZWFtXCI7XG5pbXBvcnQgeyBQYXJzZUFyZ3NPcHRpb25zQ29uZmlnLCBQYXJzZUFyZ3NSZXN1bHQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIGEgdXNlciBpbnB1dCBwcm9tcHQgd2l0aCB2YXJpb3VzIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBzdW1tYXJ5IFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBmbGV4aWJsZSBpbnRlcmZhY2UgZm9yIGNyZWF0aW5nIGFuZCBtYW5hZ2luZyB1c2VyIGlucHV0IHByb21wdHMuXG4gKiBJdCBpbXBsZW1lbnRzIHRoZSBQcm9tcHRPYmplY3QgaW50ZXJmYWNlIGZyb20gdGhlICdwcm9tcHRzJyBsaWJyYXJ5IGFuZCBvZmZlcnMgbWV0aG9kcyB0byBzZXRcbiAqIHZhcmlvdXMgcHJvcGVydGllcyBvZiB0aGUgcHJvbXB0LiBUaGUgY2xhc3MgYWxzbyBpbmNsdWRlcyBzdGF0aWMgbWV0aG9kcyBmb3IgY29tbW9uIGlucHV0IHNjZW5hcmlvc1xuICogYW5kIGFyZ3VtZW50IHBhcnNpbmcuXG4gKlxuICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgcHJvbXB0IG5hbWUsIGV4dGVuZGluZyBzdHJpbmcuXG4gKlxuICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvbXB0LCB1c2VkIGFzIHRoZSBrZXkgaW4gdGhlIHJldHVybmVkIGFuc3dlcnMgb2JqZWN0LlxuICpcbiAqIEBjbGFzc1xuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFVzZXJJbnB1dCB9IGZyb20gJ0BkZWNhZi10cy91dGlscyc7XG4gKlxuICogLy8gQ3JlYXRlIGEgc2ltcGxlIHRleHQgaW5wdXRcbiAqIGNvbnN0IG5hbWVJbnB1dCA9IG5ldyBVc2VySW5wdXQoJ25hbWUnKVxuICogICAuc2V0TWVzc2FnZSgnV2hhdCBpcyB5b3VyIG5hbWU/JylcbiAqICAgLnNldEluaXRpYWwoJ1VzZXInKTtcbiAqXG4gKiAvLyBDcmVhdGUgYSBudW1iZXIgaW5wdXQgd2l0aCB2YWxpZGF0aW9uXG4gKiBjb25zdCBhZ2VJbnB1dCA9IG5ldyBVc2VySW5wdXQoJ2FnZScpXG4gKiAgIC5zZXRUeXBlKCdudW1iZXInKVxuICogICAuc2V0TWVzc2FnZSgnSG93IG9sZCBhcmUgeW91PycpXG4gKiAgIC5zZXRNaW4oMClcbiAqICAgLnNldE1heCgxMjApO1xuICpcbiAqIC8vIEFzayBmb3IgaW5wdXQgYW5kIHByb2Nlc3MgdGhlIHJlc3VsdHNcbiAqIGFzeW5jIGZ1bmN0aW9uIGdldFVzZXJJbmZvKCkge1xuICogICBjb25zdCBhbnN3ZXJzID0gYXdhaXQgVXNlcklucHV0LmFzayhbbmFtZUlucHV0LCBhZ2VJbnB1dF0pO1xuICogICBjb25zb2xlLmxvZyhgSGVsbG8gJHthbnN3ZXJzLm5hbWV9LCB5b3UgYXJlICR7YW5zd2Vycy5hZ2V9IHllYXJzIG9sZC5gKTtcbiAqIH1cbiAqXG4gKiBnZXRVc2VySW5mbygpO1xuICogYGBgXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgVXNlcklucHV0XG4gKiAgIHBhcnRpY2lwYW50IFByb21wdExpYnJhcnlcbiAqXG4gKiAgIENsaWVudC0+PlVzZXJJbnB1dDogbmV3IFVzZXJJbnB1dChuYW1lKVxuICogICBDbGllbnQtPj5Vc2VySW5wdXQ6IHNldE1lc3NhZ2UobWVzc2FnZSlcbiAqICAgQ2xpZW50LT4+VXNlcklucHV0OiBzZXRUeXBlKHR5cGUpXG4gKiAgIENsaWVudC0+PlVzZXJJbnB1dDogc2V0SW5pdGlhbChpbml0aWFsKVxuICogICBDbGllbnQtPj5Vc2VySW5wdXQ6IE90aGVyIGNvbmZpZ3VyYXRpb24gbWV0aG9kc1xuICpcbiAqICAgQ2xpZW50LT4+VXNlcklucHV0OiBhc2soKVxuICogICBVc2VySW5wdXQtPj5Qcm9tcHRMaWJyYXJ5OiBwcm9tcHRzKHF1ZXN0aW9uKVxuICogICBQcm9tcHRMaWJyYXJ5LT4+Q2xpZW50OiBEaXNwbGF5IHByb21wdFxuICogICBDbGllbnQtPj5Qcm9tcHRMaWJyYXJ5OiBVc2VyIHByb3ZpZGVzIGlucHV0XG4gKiAgIFByb21wdExpYnJhcnktPj5Vc2VySW5wdXQ6IFJldHVybiBhbnN3ZXJzXG4gKiAgIFVzZXJJbnB1dC0+PkNsaWVudDogUmV0dXJuIHByb2Nlc3NlZCBhbnN3ZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2VySW5wdXQ8UiBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gaW1wbGVtZW50cyBQcm9tcHRPYmplY3Q8Uj4ge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBsb2dnZXIgPSBMb2dnaW5nLmZvcihVc2VySW5wdXQpO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgdGhlIGlucHV0IG1ldGhvZCAoZS5nLiwgdGV4dCwgbnVtYmVyLCBjb25maXJtKS5cbiAgICovXG4gIHR5cGU6IFByb21wdFR5cGUgfCBGYWxzeSB8IFByZXZDYWxsZXI8UiwgUHJvbXB0VHlwZSB8IEZhbHN5PiA9IFwidGV4dFwiO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG5hbWUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgVXNlZCBhcyB0aGUga2V5IGluIHRoZSByZXR1cm5lZCBhbnN3ZXJzIG9iamVjdC5cbiAgICovXG4gIG5hbWU6IFZhbHVlT3JGdW5jPFI+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG1lc3NhZ2UgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKiBAc3VtbWFyeSBUaGUgcXVlc3Rpb24gb3IgaW5zdHJ1Y3Rpb24gcHJlc2VudGVkIHRvIHRoZSB1c2VyLlxuICAgKi9cbiAgbWVzc2FnZT86IFZhbHVlT3JGdW5jPHN0cmluZz4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBUaGUgZGVmYXVsdCB2YWx1ZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIuXG4gICAqL1xuICBpbml0aWFsPzpcbiAgICB8IEluaXRpYWxSZXR1cm5WYWx1ZVxuICAgIHwgUHJldkNhbGxlcjxSLCBJbml0aWFsUmV0dXJuVmFsdWUgfCBQcm9taXNlPEluaXRpYWxSZXR1cm5WYWx1ZT4+XG4gICAgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgc3R5bGUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyB0aGUgdmlzdWFsIHN0eWxlIG9mIHRoZSBwcm9tcHQuXG4gICAqL1xuICBzdHlsZT86IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGZvcm1hdCBmdW5jdGlvbiBmb3IgdGhlIGlucHV0LlxuICAgKiBAc3VtbWFyeSBBIGZ1bmN0aW9uIHRvIGZvcm1hdCB0aGUgdXNlcidzIGlucHV0IGJlZm9yZSBpdCdzIHJldHVybmVkLlxuICAgKi9cbiAgZm9ybWF0PzogUHJldkNhbGxlcjxSLCB2b2lkPiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSB2YWxpZGF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgaW5wdXQuXG4gICAqIEBzdW1tYXJ5IEEgZnVuY3Rpb24gdG8gdmFsaWRhdGUgdGhlIHVzZXIncyBpbnB1dC5cbiAgICovXG4gIHZhbGlkYXRlPzpcbiAgICB8IFByZXZDYWxsZXI8UiwgYm9vbGVhbiB8IHN0cmluZyB8IFByb21pc2U8Ym9vbGVhbiB8IHN0cmluZz4+XG4gICAgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgb25TdGF0ZSBjYWxsYmFjayBmdW5jdGlvbi5cbiAgICogQHN1bW1hcnkgQSBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIHByb21wdCBjaGFuZ2VzLlxuICAgKi9cbiAgb25TdGF0ZT86IFByZXZDYWxsZXI8Uiwgdm9pZD4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbWluaW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgVGhlIGxvd2VzdCBudW1iZXIgdGhlIHVzZXIgY2FuIGlucHV0LlxuICAgKi9cbiAgbWluPzogbnVtYmVyIHwgUHJldkNhbGxlcjxSLCBudW1iZXIgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbWF4aW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgVGhlIGhpZ2hlc3QgbnVtYmVyIHRoZSB1c2VyIGNhbiBpbnB1dC5cbiAgICovXG4gIG1heD86IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gV2hldGhlciB0byBhbGxvdyBmbG9hdCB2YWx1ZXMgZm9yIG51bWJlciBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IElmIHRydWUsIGFsbG93cyBkZWNpbWFsIG51bWJlcnMuXG4gICAqL1xuICBmbG9hdD86IGJvb2xlYW4gfCBQcmV2Q2FsbGVyPFIsIGJvb2xlYW4gfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIHJvdW5kIHRvIGZvciBmbG9hdCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgdGhlIHByZWNpc2lvbiBvZiBmbG9hdCBpbnB1dHMuXG4gICAqL1xuICByb3VuZD86IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5zdHJ1Y3Rpb25zIGZvciB0aGUgdXNlci5cbiAgICogQHN1bW1hcnkgQWRkaXRpb25hbCBndWlkYW5jZSBwcm92aWRlZCB0byB0aGUgdXNlci5cbiAgICovXG4gIGluc3RydWN0aW9ucz86IHN0cmluZyB8IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5jcmVtZW50IHZhbHVlIGZvciBudW1iZXIgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgc3RlcCBzaXplIHdoZW4gaW5jcmVhc2luZyBvciBkZWNyZWFzaW5nIHRoZSBudW1iZXIuXG4gICAqL1xuICBpbmNyZW1lbnQ/OiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBzZXBhcmF0b3IgZm9yIGxpc3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgY2hhcmFjdGVyIHVzZWQgdG8gc2VwYXJhdGUgbGlzdCBpdGVtcy5cbiAgICovXG4gIHNlcGFyYXRvcj86IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGFjdGl2ZSBvcHRpb24gc3R5bGUgZm9yIHNlbGVjdCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IFRoZSBzdHlsZSBhcHBsaWVkIHRvIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlxuICAgKi9cbiAgYWN0aXZlPzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgaW5hY3RpdmUgb3B0aW9uIHN0eWxlIGZvciBzZWxlY3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgc3R5bGUgYXBwbGllZCB0byBub24tc2VsZWN0ZWQgb3B0aW9ucy5cbiAgICovXG4gIGluYWN0aXZlPzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgYXZhaWxhYmxlIGNob2ljZXMgZm9yIHNlbGVjdCwgbXVsdGlzZWxlY3QsIG9yIGF1dG9jb21wbGV0ZSBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IEFuIGFycmF5IG9mIG9wdGlvbnMgdGhhdCB0aGUgdXNlciBjYW4gc2VsZWN0IGZyb20gaW4gY2hvaWNlLWJhc2VkIHByb21wdHMuXG4gICAqL1xuICBjaG9pY2VzPzogQ2hvaWNlW10gfCBQcmV2Q2FsbGVyPFIsIENob2ljZVtdIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGhpbnQgdGV4dCBmb3IgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQWRkaXRpb25hbCBpbmZvcm1hdGlvbiBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqL1xuICBoaW50Pzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgd2FybmluZyB0ZXh0IGZvciB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBBIHdhcm5pbmcgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqL1xuICB3YXJuPzogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQ7XG5cbiAgc3VnZ2VzdD86ICgoaW5wdXQ6IGFueSwgY2hvaWNlczogQ2hvaWNlW10pID0+IFByb21pc2U8YW55PikgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbGltaXQgZm9yIGxpc3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBUaGUgbWF4aW11bSBudW1iZXIgb2YgaXRlbXMgdGhhdCBjYW4gYmUgc2VsZWN0ZWQuXG4gICAqL1xuICBsaW1pdD86IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG1hc2sgZm9yIHBhc3N3b3JkIGlucHV0cy5cbiAgICogQHN1bW1hcnkgVGhlIGNoYXJhY3RlciB1c2VkIHRvIGhpZGUgdGhlIHVzZXIncyBpbnB1dC5cbiAgICovXG4gIG1hc2s/OiBzdHJpbmcgfCBQcmV2Q2FsbGVyPFIsIHN0cmluZyB8IEZhbHN5PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBzdGRvdXQgc3RyZWFtIGZvciB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBUaGUgb3V0cHV0IHN0cmVhbSB1c2VkIGJ5IHRoZSBwcm9tcHQuXG4gICAqL1xuICBzdGRvdXQ/OiBXcml0YWJsZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBzdGRpbiBzdHJlYW0gZm9yIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IFRoZSBpbnB1dCBzdHJlYW0gdXNlZCBieSB0aGUgcHJvbXB0LlxuICAgKi9cbiAgc3RkaW4/OiBSZWFkYWJsZSB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihuYW1lOiBWYWx1ZU9yRnVuYzxSPikge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIHR5cGUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgaW5wdXQgbWV0aG9kIGZvciB0aGUgcHJvbXB0LlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRUeXBlKHR5cGU6IFByb21wdFR5cGUgfCBGYWxzeSB8IFByZXZDYWxsZXI8UiwgUHJvbXB0VHlwZSB8IEZhbHN5Pik6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyB0eXBlIHRvOiAke3R5cGV9YCk7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbWVzc2FnZSBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBxdWVzdGlvbiBvciBpbnN0cnVjdGlvbiBwcmVzZW50ZWQgdG8gdGhlIHVzZXIuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldE1lc3NhZ2UodmFsdWU6IFZhbHVlT3JGdW5jPHN0cmluZz4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgbWVzc2FnZSB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLm1lc3NhZ2UgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBkZWZhdWx0IHZhbHVlIHByZXNlbnRlZCB0byB0aGUgdXNlci5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRJbml0aWFsKFxuICAgIHZhbHVlOlxuICAgICAgfCBJbml0aWFsUmV0dXJuVmFsdWVcbiAgICAgIHwgUHJldkNhbGxlcjxSLCBJbml0aWFsUmV0dXJuVmFsdWUgfCBQcm9taXNlPEluaXRpYWxSZXR1cm5WYWx1ZT4+XG4gICAgICB8IHVuZGVmaW5lZFxuICApOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgaW5pdGlhbCB2YWx1ZSB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmluaXRpYWwgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgc3R5bGUgb2YgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgdmlzdWFsIHN0eWxlIG9mIHRoZSBwcm9tcHQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBzdHlsZSB0byBiZSBhcHBsaWVkLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0U3R5bGUodmFsdWU6IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHN0eWxlIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuc3R5bGUgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgZm9ybWF0IGZ1bmN0aW9uIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0byBmb3JtYXQgdGhlIHVzZXIncyBpbnB1dCBiZWZvcmUgaXQncyByZXR1cm5lZC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGZvcm1hdCBmdW5jdGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldEZvcm1hdCh2YWx1ZTogUHJldkNhbGxlcjxSLCB2b2lkPiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBmb3JtYXQgZnVuY3Rpb25gKTtcbiAgICB0aGlzLmZvcm1hdCA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSB2YWxpZGF0aW9uIGZ1bmN0aW9uIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgdXNlcidzIGlucHV0LlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsaWRhdGlvbiBmdW5jdGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFZhbGlkYXRlKFxuICAgIHZhbHVlOlxuICAgICAgfCBQcmV2Q2FsbGVyPFIsIGJvb2xlYW4gfCBzdHJpbmcgfCBQcm9taXNlPGJvb2xlYW4gfCBzdHJpbmc+PlxuICAgICAgfCB1bmRlZmluZWRcbiAgKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHZhbGlkYXRlIGZ1bmN0aW9uYCk7XG4gICAgdGhpcy52YWxpZGF0ZSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBvblN0YXRlIGNhbGxiYWNrIG9mIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIHByb21wdCBjaGFuZ2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgb25TdGF0ZSBjYWxsYmFjayBmdW5jdGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldE9uU3RhdGUodmFsdWU6IFByZXZDYWxsZXI8Uiwgdm9pZD4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgb25TdGF0ZSBjYWxsYmFja2ApO1xuICAgIHRoaXMub25TdGF0ZSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBtaW5pbXVtIHZhbHVlIGZvciBudW1iZXIgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBsb3dlc3QgbnVtYmVyIHRoZSB1c2VyIGNhbiBpbnB1dC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIG1pbmltdW0gdmFsdWUuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRNaW4odmFsdWU6IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIG1pbiB2YWx1ZSB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLm1pbiA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBtYXhpbXVtIHZhbHVlIGZvciBudW1iZXIgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBoaWdoZXN0IG51bWJlciB0aGUgdXNlciBjYW4gaW5wdXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBtYXhpbXVtIHZhbHVlLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0TWF4KHZhbHVlOiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBtYXggdmFsdWUgdG86ICR7dmFsdWV9YCk7XG4gICAgdGhpcy5tYXggPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB3aGV0aGVyIHRvIGFsbG93IGZsb2F0IHZhbHVlcyBmb3IgbnVtYmVyIGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB3aGV0aGVyIGRlY2ltYWwgbnVtYmVycyBhcmUgYWxsb3dlZC5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gV2hldGhlciB0byBhbGxvdyBmbG9hdCB2YWx1ZXMuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRGbG9hdCh2YWx1ZTogYm9vbGVhbiB8IFByZXZDYWxsZXI8UiwgYm9vbGVhbiB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBmbG9hdCB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmZsb2F0ID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB0byByb3VuZCB0byBmb3IgZmxvYXQgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBwcmVjaXNpb24gb2YgZmxvYXQgaW5wdXRzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0Um91bmQodmFsdWU6IG51bWJlciB8IFByZXZDYWxsZXI8UiwgbnVtYmVyIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHJvdW5kIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMucm91bmQgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgaW5zdHJ1Y3Rpb25zIGZvciB0aGUgdXNlci5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyBhZGRpdGlvbmFsIGd1aWRhbmNlIHByb3ZpZGVkIHRvIHRoZSB1c2VyLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgaW5zdHJ1Y3Rpb25zLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0SW5zdHJ1Y3Rpb25zKHZhbHVlOiBzdHJpbmcgfCBib29sZWFuIHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIGluc3RydWN0aW9ucyB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmluc3RydWN0aW9ucyA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBpbmNyZW1lbnQgdmFsdWUgZm9yIG51bWJlciBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIHN0ZXAgc2l6ZSB3aGVuIGluY3JlYXNpbmcgb3IgZGVjcmVhc2luZyB0aGUgbnVtYmVyLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgaW5jcmVtZW50IHZhbHVlLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0SW5jcmVtZW50KFxuICAgIHZhbHVlOiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZFxuICApOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgaW5jcmVtZW50IHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuaW5jcmVtZW50ID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIHNlcGFyYXRvciBmb3IgbGlzdCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIGNoYXJhY3RlciB1c2VkIHRvIHNlcGFyYXRlIGxpc3QgaXRlbXMuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBzZXBhcmF0b3IgY2hhcmFjdGVyLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0U2VwYXJhdG9yKFxuICAgIHZhbHVlOiBzdHJpbmcgfCBQcmV2Q2FsbGVyPFIsIHN0cmluZyB8IEZhbHN5PiB8IHVuZGVmaW5lZFxuICApOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgc2VwYXJhdG9yIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuc2VwYXJhdG9yID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGFjdGl2ZSBvcHRpb24gc3R5bGUgZm9yIHNlbGVjdCBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIHN0eWxlIGFwcGxpZWQgdG8gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBvcHRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBhY3RpdmUgb3B0aW9uIHN0eWxlLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0QWN0aXZlKHZhbHVlOiBzdHJpbmcgfCBQcmV2Q2FsbGVyPFIsIHN0cmluZyB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBhY3RpdmUgc3R5bGUgdG86ICR7dmFsdWV9YCk7XG4gICAgdGhpcy5hY3RpdmUgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgaW5hY3RpdmUgb3B0aW9uIHN0eWxlIGZvciBzZWxlY3QgaW5wdXRzLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBzdHlsZSBhcHBsaWVkIHRvIG5vbi1zZWxlY3RlZCBvcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgaW5hY3RpdmUgb3B0aW9uIHN0eWxlLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0SW5hY3RpdmUodmFsdWU6IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIGluYWN0aXZlIHN0eWxlIHRvOiAke3ZhbHVlfWApO1xuICAgIHRoaXMuaW5hY3RpdmUgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgY2hvaWNlcyBmb3Igc2VsZWN0LCBtdWx0aXNlbGVjdCwgb3IgYXV0b2NvbXBsZXRlIGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgYXZhaWxhYmxlIG9wdGlvbnMgdGhhdCB0aGUgdXNlciBjYW4gc2VsZWN0IGZyb20gaW4gY2hvaWNlLWJhc2VkIHByb21wdHMuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBhcnJheSBvZiBjaG9pY2VzIG9yIGEgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHRoZSBjaG9pY2VzLlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0Q2hvaWNlcyhcbiAgICB2YWx1ZTogQ2hvaWNlW10gfCBQcmV2Q2FsbGVyPFIsIENob2ljZVtdIHwgRmFsc3k+IHwgdW5kZWZpbmVkXG4gICk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBjaG9pY2VzOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX1gKTtcbiAgICB0aGlzLmNob2ljZXMgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgaGludCB0ZXh0IGZvciB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgaGludCB0ZXh0LlxuICAgKiBAcmV0dXJucyBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0SGludCh2YWx1ZTogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgaGludCB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmhpbnQgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgd2FybmluZyB0ZXh0IGZvciB0aGUgcHJvbXB0LlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIGEgd2FybmluZyBtZXNzYWdlIGRpc3BsYXllZCB0byB0aGUgdXNlci5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIHdhcm5pbmcgdGV4dC5cbiAgICogQHJldHVybnMgVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFdhcm4odmFsdWU6IHN0cmluZyB8IFByZXZDYWxsZXI8Uiwgc3RyaW5nIHwgRmFsc3k+IHwgdW5kZWZpbmVkKTogdGhpcyB7XG4gICAgVXNlcklucHV0LmxvZ2dlci52ZXJib3NlKGBTZXR0aW5nIHdhcm4gdG86ICR7dmFsdWV9YCk7XG4gICAgdGhpcy53YXJuID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIHN1Z2dlc3Rpb24gZnVuY3Rpb24gZm9yIGF1dG9jb21wbGV0ZSBpbnB1dHMuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgYSBmdW5jdGlvbiB0aGF0IHByb3ZpZGVzIHN1Z2dlc3Rpb25zIGJhc2VkIG9uIHRoZSB1c2VyJ3MgaW5wdXQgYW5kIGF2YWlsYWJsZSBjaG9pY2VzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgLSBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgdGhlIGN1cnJlbnQgaW5wdXQgYW5kIGF2YWlsYWJsZSBjaG9pY2VzIGFuZCByZXR1cm5zIGEgUHJvbWlzZSByZXNvbHZpbmcgdG8gc3VnZ2VzdGlvbnMuXG4gICAqIEByZXR1cm5zIFRoaXMgVXNlcklucHV0IGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gICAqL1xuICBzZXRTdWdnZXN0KFxuICAgIHZhbHVlOiAoKGlucHV0OiBhbnksIGNob2ljZXM6IENob2ljZVtdKSA9PiBQcm9taXNlPGFueT4pIHwgdW5kZWZpbmVkXG4gICk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBzdWdnZXN0IGZ1bmN0aW9uYCk7XG4gICAgdGhpcy5zdWdnZXN0ID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGxpbWl0IGZvciBsaXN0IGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgaXRlbXMgdGhhdCBjYW4gYmUgc2VsZWN0ZWQgaW4gbGlzdC10eXBlIHByb21wdHMuXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHR5cGUgb2YgdGhlIHByb21wdCBuYW1lLCBleHRlbmRpbmcgc3RyaW5nLlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgbWF4aW11bSBudW1iZXIgb2YgaXRlbXMgdGhhdCBjYW4gYmUgc2VsZWN0ZWQsIG9yIGEgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHRoaXMgdmFsdWUuXG4gICAqIEByZXR1cm4gVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldExpbWl0KHZhbHVlOiBudW1iZXIgfCBQcmV2Q2FsbGVyPFIsIG51bWJlciB8IEZhbHN5PiB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIFVzZXJJbnB1dC5sb2dnZXIudmVyYm9zZShgU2V0dGluZyBsaW1pdCB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLmxpbWl0ID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIG1hc2sgZm9yIHBhc3N3b3JkIGlucHV0cy5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgY2hhcmFjdGVyIHVzZWQgdG8gaGlkZSB0aGUgdXNlcidzIGlucHV0IGluIHBhc3N3b3JkLXR5cGUgcHJvbXB0cy5cbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgcHJvbXB0IG5hbWUsIGV4dGVuZGluZyBzdHJpbmcuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBjaGFyYWN0ZXIgdXNlZCB0byBtYXNrIHRoZSBpbnB1dCwgb3IgYSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgdGhpcyB2YWx1ZS5cbiAgICogQHJldHVybiBUaGlzIFVzZXJJbnB1dCBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0TWFzayh2YWx1ZTogc3RyaW5nIHwgUHJldkNhbGxlcjxSLCBzdHJpbmcgfCBGYWxzeT4gfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgbWFzayB0bzogJHt2YWx1ZX1gKTtcbiAgICB0aGlzLm1hc2sgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgc3Rkb3V0IHN0cmVhbSBmb3IgdGhlIHByb21wdC5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgb3V0cHV0IHN0cmVhbSB1c2VkIGJ5IHRoZSBwcm9tcHQgZm9yIGRpc3BsYXlpbmcgbWVzc2FnZXMgYW5kIHJlc3VsdHMuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBXcml0YWJsZSBzdHJlYW0gdG8gYmUgdXNlZCBhcyBzdGRvdXQuXG4gICAqIEByZXR1cm4gVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFN0ZG91dCh2YWx1ZTogV3JpdGFibGUgfCB1bmRlZmluZWQpOiB0aGlzIHtcbiAgICBVc2VySW5wdXQubG9nZ2VyLnZlcmJvc2UoYFNldHRpbmcgc3Rkb3V0IHN0cmVhbWApO1xuICAgIHRoaXMuc3Rkb3V0ID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBzdGRpbiBzdHJlYW0gZm9yIHRoZSBwcm9tcHQuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIGlucHV0IHN0cmVhbSB1c2VkIGJ5IHRoZSBwcm9tcHQgZm9yIHJlY2VpdmluZyB1c2VyIGlucHV0LlxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgUmVhZGFibGUgc3RyZWFtIHRvIGJlIHVzZWQgYXMgc3RkaW4uXG4gICAqIEByZXR1cm4gVGhpcyBVc2VySW5wdXQgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldFN0ZGluKHZhbHVlOiBSZWFkYWJsZSB8IHVuZGVmaW5lZCk6IHRoaXMge1xuICAgIHRoaXMuc3RkaW4gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQXNrcyB0aGUgdXNlciBmb3IgaW5wdXQgYmFzZWQgb24gdGhlIGN1cnJlbnQgVXNlcklucHV0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBzdW1tYXJ5IFByb21wdHMgdGhlIHVzZXIgYW5kIHJldHVybnMgdGhlaXIgcmVzcG9uc2UgYXMgYSBzaW5nbGUgdmFsdWUuXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHR5cGUgb2YgdGhlIHByb21wdCBuYW1lLCBleHRlbmRpbmcgc3RyaW5nLlxuICAgKiBAcmV0dXJuIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSB1c2VyJ3MgYW5zd2VyLlxuICAgKi9cbiAgYXN5bmMgYXNrKCkge1xuICAgIHJldHVybiAoYXdhaXQgVXNlcklucHV0LmFzayh0aGlzKSlbdGhpcy5uYW1lIGFzIGtleW9mIEFuc3dlcnM8Uj5dO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBc2tzIHRoZSB1c2VyIG9uZSBvciBtb3JlIHF1ZXN0aW9ucyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgVXNlcklucHV0IGNvbmZpZ3VyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBQcm9tcHRzIHRoZSB1c2VyIHdpdGggb25lIG9yIG1vcmUgcXVlc3Rpb25zIGFuZCByZXR1cm5zIHRoZWlyIGFuc3dlcnMgYXMgYW4gb2JqZWN0LlxuICAgKiBAdGVtcGxhdGUgUiAtIFRoZSB0eXBlIG9mIHRoZSBwcm9tcHQgbmFtZSwgZXh0ZW5kaW5nIHN0cmluZy5cbiAgICogQHBhcmFtIHF1ZXN0aW9uIC0gQSBzaW5nbGUgVXNlcklucHV0IGluc3RhbmNlIG9yIGFuIGFycmF5IG9mIFVzZXJJbnB1dCBpbnN0YW5jZXMuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHVzZXIncyBhbnN3ZXJzLlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIFVzZXJcbiAgICogICBwYXJ0aWNpcGFudCBBIGFzIGFzayBtZXRob2RcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIHByb21wdHMgbGlicmFyeVxuICAgKiAgIEEtPj5QOiBDYWxsIHByb21wdHMgd2l0aCBxdWVzdGlvbihzKVxuICAgKiAgIFAtPj5VOiBEaXNwbGF5IHByb21wdChzKVxuICAgKiAgIFUtPj5QOiBQcm92aWRlIGlucHV0XG4gICAqICAgUC0+PkE6IFJldHVybiBhbnN3ZXJzXG4gICAqICAgQS0+PkE6IFByb2Nlc3MgYW5zd2Vyc1xuICAgKiAgIEEtLT4+Q2FsbGVyOiBSZXR1cm4gcHJvY2Vzc2VkIGFuc3dlcnNcbiAgICovXG4gIHN0YXRpYyBhc3luYyBhc2s8UiBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oXG4gICAgcXVlc3Rpb246IFVzZXJJbnB1dDxSPiB8IFVzZXJJbnB1dDxSPltdXG4gICkge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMuYXNrKTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocXVlc3Rpb24pKSB7XG4gICAgICBxdWVzdGlvbiA9IFtxdWVzdGlvbl07XG4gICAgfVxuICAgIGxldCBhbnN3ZXJzOiBBbnN3ZXJzPFI+O1xuICAgIHRyeSB7XG4gICAgICBsb2cudmVyYm9zZShcbiAgICAgICAgYEFza2luZyBxdWVzdGlvbnM6ICR7cXVlc3Rpb24ubWFwKChxKSA9PiBxLm5hbWUpLmpvaW4oXCIsIFwiKX1gXG4gICAgICApO1xuICAgICAgYW5zd2VycyA9IGF3YWl0IHByb21wdHMocXVlc3Rpb24pO1xuICAgICAgbG9nLnZlcmJvc2UoYFJlY2VpdmVkIGFuc3dlcnM6ICR7SlNPTi5zdHJpbmdpZnkoYW5zd2VycywgbnVsbCwgMil9YCk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3Igd2hpbGUgZ2V0dGluZyBpbnB1dDogJHtlcnJvcn1gKTtcbiAgICB9XG4gICAgcmV0dXJuIGFuc3dlcnM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFza3MgdGhlIHVzZXIgZm9yIGEgbnVtYmVyIGlucHV0LlxuICAgKiBAc3VtbWFyeSBQcm9tcHRzIHRoZSB1c2VyIHRvIGVudGVyIGEgbnVtYmVyLCB3aXRoIG9wdGlvbmFsIG1pbmltdW0sIG1heGltdW0sIGFuZCBpbml0aWFsIHZhbHVlcy5cbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvbXB0LCB1c2VkIGFzIHRoZSBrZXkgaW4gdGhlIHJldHVybmVkIGFuc3dlcnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBUaGUgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqIEBwYXJhbSBtaW4gLSBUaGUgbWluaW11bSBhbGxvd2VkIHZhbHVlIChvcHRpb25hbCkuXG4gICAqIEBwYXJhbSBtYXggLSBUaGUgbWF4aW11bSBhbGxvd2VkIHZhbHVlIChvcHRpb25hbCkuXG4gICAqIEBwYXJhbSBpbml0aWFsIC0gVGhlIGluaXRpYWwgdmFsdWUgcHJlc2VudGVkIHRvIHRoZSB1c2VyIChvcHRpb25hbCkuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIG51bWJlciBlbnRlcmVkIGJ5IHRoZSB1c2VyLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGFza051bWJlcihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgcXVlc3Rpb246IHN0cmluZyxcbiAgICBtaW4/OiBudW1iZXIsXG4gICAgbWF4PzogbnVtYmVyLFxuICAgIGluaXRpYWw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBsb2cgPSBVc2VySW5wdXQubG9nZ2VyLmZvcih0aGlzLmFza051bWJlcik7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgQXNraW5nIG51bWJlciBpbnB1dDogdW5kZWZpbmVkLCBxdWVzdGlvbjogJHtxdWVzdGlvbn0sIG1pbjogJHttaW59LCBtYXg6ICR7bWF4fSwgaW5pdGlhbDogJHtpbml0aWFsfWBcbiAgICApO1xuICAgIGNvbnN0IHVzZXJJbnB1dCA9IG5ldyBVc2VySW5wdXQobmFtZSlcbiAgICAgIC5zZXRNZXNzYWdlKHF1ZXN0aW9uKVxuICAgICAgLnNldFR5cGUoXCJudW1iZXJcIik7XG5cbiAgICBpZiAodHlwZW9mIG1pbiA9PT0gXCJudW1iZXJcIikgdXNlcklucHV0LnNldE1pbihtaW4pO1xuXG4gICAgaWYgKHR5cGVvZiBtYXggPT09IFwibnVtYmVyXCIpIHVzZXJJbnB1dC5zZXRNYXgobWF4KTtcblxuICAgIGlmICh0eXBlb2YgaW5pdGlhbCA9PT0gXCJudW1iZXJcIikgdXNlcklucHV0LnNldEluaXRpYWwoaW5pdGlhbCk7XG5cbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuYXNrKHVzZXJJbnB1dCkpW25hbWVdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBc2tzIHRoZSB1c2VyIGZvciBhIHRleHQgaW5wdXQuXG4gICAqIEBzdW1tYXJ5IFByb21wdHMgdGhlIHVzZXIgdG8gZW50ZXIgdGV4dCwgd2l0aCBvcHRpb25hbCBtYXNraW5nIGFuZCBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9tcHQsIHVzZWQgYXMgdGhlIGtleSBpbiB0aGUgcmV0dXJuZWQgYW5zd2VycyBvYmplY3QuXG4gICAqIEBwYXJhbSBxdWVzdGlvbiAtIFRoZSBtZXNzYWdlIGRpc3BsYXllZCB0byB0aGUgdXNlci5cbiAgICogQHBhcmFtIG1hc2sgLSBUaGUgY2hhcmFjdGVyIHVzZWQgdG8gbWFzayB0aGUgaW5wdXQgKG9wdGlvbmFsLCBmb3IgcGFzc3dvcmQtbGlrZSBpbnB1dHMpLlxuICAgKiBAcGFyYW0gaW5pdGlhbCAtIFRoZSBpbml0aWFsIHZhbHVlIHByZXNlbnRlZCB0byB0aGUgdXNlciAob3B0aW9uYWwpLlxuICAgKiBAcmV0dXJuIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSB0ZXh0IGVudGVyZWQgYnkgdGhlIHVzZXIuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgYXNrVGV4dChcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgcXVlc3Rpb246IHN0cmluZyxcbiAgICBtYXNrOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gICAgaW5pdGlhbD86IHN0cmluZ1xuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMuYXNrVGV4dCk7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgQXNraW5nIHRleHQgaW5wdXQ6IHVuZGVmaW5lZCwgcXVlc3Rpb246ICR7cXVlc3Rpb259LCBtYXNrOiAke21hc2t9LCBpbml0aWFsOiAke2luaXRpYWx9YFxuICAgICk7XG4gICAgY29uc3QgdXNlcklucHV0ID0gbmV3IFVzZXJJbnB1dChuYW1lKS5zZXRNZXNzYWdlKHF1ZXN0aW9uKTtcblxuICAgIGlmIChtYXNrKSB1c2VySW5wdXQuc2V0TWFzayhtYXNrKTtcbiAgICBpZiAodHlwZW9mIGluaXRpYWwgPT09IFwic3RyaW5nXCIpIHVzZXJJbnB1dC5zZXRJbml0aWFsKGluaXRpYWwpO1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5hc2sodXNlcklucHV0KSlbbmFtZV07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFza3MgdGhlIHVzZXIgZm9yIGEgY29uZmlybWF0aW9uICh5ZXMvbm8pLlxuICAgKiBAc3VtbWFyeSBQcm9tcHRzIHRoZSB1c2VyIHdpdGggYSB5ZXMvbm8gcXVlc3Rpb24gYW5kIHJldHVybnMgYSBib29sZWFuIHJlc3VsdC5cbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvbXB0LCB1c2VkIGFzIHRoZSBrZXkgaW4gdGhlIHJldHVybmVkIGFuc3dlcnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBUaGUgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqIEBwYXJhbSBpbml0aWFsIC0gVGhlIGluaXRpYWwgdmFsdWUgcHJlc2VudGVkIHRvIHRoZSB1c2VyIChvcHRpb25hbCkuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgdXNlcidzIGFuc3dlci5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBhc2tDb25maXJtYXRpb24oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHF1ZXN0aW9uOiBzdHJpbmcsXG4gICAgaW5pdGlhbD86IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgbG9nID0gVXNlcklucHV0LmxvZ2dlci5mb3IodGhpcy5hc2tDb25maXJtYXRpb24pO1xuICAgIGxvZy52ZXJib3NlKFxuICAgICAgYEFza2luZyBjb25maXJtYXRpb24gaW5wdXQ6IHVuZGVmaW5lZCwgcXVlc3Rpb246ICR7cXVlc3Rpb259LCBpbml0aWFsOiAke2luaXRpYWx9YFxuICAgICk7XG4gICAgY29uc3QgdXNlcklucHV0ID0gbmV3IFVzZXJJbnB1dChuYW1lKVxuICAgICAgLnNldE1lc3NhZ2UocXVlc3Rpb24pXG4gICAgICAuc2V0VHlwZShcImNvbmZpcm1cIik7XG5cbiAgICBpZiAodHlwZW9mIGluaXRpYWwgIT09IFwidW5kZWZpbmVkXCIpIHVzZXJJbnB1dC5zZXRJbml0aWFsKGluaXRpYWwpO1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5hc2sodXNlcklucHV0KSlbbmFtZV07XG4gIH1cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXBlYXRlZGx5IGFza3MgZm9yIGlucHV0IHVudGlsIGEgdmFsaWQgcmVzcG9uc2UgaXMgZ2l2ZW4gb3IgdGhlIGxpbWl0IGlzIHJlYWNoZWQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIGluc2lzdHMgb24gZ2V0dGluZyBhIHZhbGlkIGlucHV0IGZyb20gdGhlIHVzZXIsIGFsbG93aW5nIGZvciBhIHNwZWNpZmllZCBudW1iZXIgb2YgYXR0ZW1wdHMuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHR5cGUgb2YgdGhlIGV4cGVjdGVkIHJlc3VsdC5cbiAgICogQHBhcmFtIGlucHV0IC0gVGhlIFVzZXJJbnB1dCBpbnN0YW5jZSB0byB1c2UgZm9yIHByb21wdGluZy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihzdHJpbmcpOmJvb2xlYW59IHRlc3QgLSBWYWxpZGF0b3IgZnVuY3Rpb24gcmVjZWl2aW5nIHRoZSB1c2VyIGlucHV0IGFuZCByZXR1cm5pbmcgd2hldGhlciBpdCBpcyB2YWxpZC5cbiAgICogQHBhcmFtIGRlZmF1bHRDb25maXJtYXRpb24gLSBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGNvbmZpcm1hdGlvbiBwcm9tcHQgKHRydWUgZm9yIHllcywgZmFsc2UgZm9yIG5vKS5cbiAgICogQHBhcmFtIGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzIGFsbG93ZWQgKGRlZmF1bHQgaXMgMSkuXG4gICAqIEByZXR1cm4gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHZhbGlkIGlucHV0IG9yIHVuZGVmaW5lZCBpZiB0aGUgbGltaXQgaXMgcmVhY2hlZC5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gICAqICAgcGFydGljaXBhbnQgSSBhcyBpbnNpc3QgbWV0aG9kXG4gICAqICAgcGFydGljaXBhbnQgQSBhcyBhc2sgbWV0aG9kXG4gICAqICAgcGFydGljaXBhbnQgVCBhcyB0ZXN0IGZ1bmN0aW9uXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBhc2tDb25maXJtYXRpb24gbWV0aG9kXG4gICAqICAgbG9vcCBVbnRpbCB2YWxpZCBpbnB1dCBvciBsaW1pdCByZWFjaGVkXG4gICAqICAgICBJLT4+QTogQ2FsbCBhc2sgd2l0aCBpbnB1dFxuICAgKiAgICAgQS0+PlU6IFByb21wdCB1c2VyXG4gICAqICAgICBVLT4+QTogUHJvdmlkZSBpbnB1dFxuICAgKiAgICAgQS0+Pkk6IFJldHVybiByZXN1bHRcbiAgICogICAgIEktPj5UOiBUZXN0IHJlc3VsdFxuICAgKiAgICAgYWx0IFRlc3QgcGFzc2VzXG4gICAqICAgICAgIEktPj5DOiBBc2sgZm9yIGNvbmZpcm1hdGlvblxuICAgKiAgICAgICBDLT4+VTogQ29uZmlybSBpbnB1dFxuICAgKiAgICAgICBVLT4+QzogUHJvdmlkZSBjb25maXJtYXRpb25cbiAgICogICAgICAgQy0+Pkk6IFJldHVybiBjb25maXJtYXRpb25cbiAgICogICAgICAgYWx0IENvbmZpcm1lZFxuICAgKiAgICAgICAgIEktLT4+Q2FsbGVyOiBSZXR1cm4gdmFsaWQgcmVzdWx0XG4gICAqICAgICAgIGVsc2UgTm90IGNvbmZpcm1lZFxuICAgKiAgICAgICAgIEktPj5JOiBDb250aW51ZSBsb29wXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZSBUZXN0IGZhaWxzXG4gICAqICAgICAgIEktPj5JOiBDb250aW51ZSBsb29wXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICogICBJLS0+PkNhbGxlcjogUmV0dXJuIHVuZGVmaW5lZCBpZiBsaW1pdCByZWFjaGVkXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgaW5zaXN0PFI+KFxuICAgIGlucHV0OiBVc2VySW5wdXQsXG4gICAgdGVzdDogKHJlczogc3RyaW5nIHwgbnVtYmVyKSA9PiBib29sZWFuLFxuICAgIGRlZmF1bHRDb25maXJtYXRpb246IGJvb2xlYW4sXG4gICAgbGltaXQgPSAxXG4gICk6IFByb21pc2U8UiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGxvZyA9IFVzZXJJbnB1dC5sb2dnZXIuZm9yKHRoaXMuaW5zaXN0KTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBJbnNpc3Rpbmcgb24gaW5wdXQ6ICR7aW5wdXQubmFtZX0sIHRlc3Q6ICR7dGVzdC50b1N0cmluZygpfSwgZGVmYXVsdENvbmZpcm1hdGlvbjogJHtkZWZhdWx0Q29uZmlybWF0aW9ufSwgbGltaXQ6ICR7bGltaXR9YFxuICAgICk7XG4gICAgbGV0IHJlc3VsdDogc3RyaW5nIHwgbnVtYmVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGxldCBjb3VudCA9IDA7XG4gICAgbGV0IGNvbmZpcm1hdGlvbjogYm9vbGVhbjtcbiAgICB0cnkge1xuICAgICAgZG8ge1xuICAgICAgICByZXN1bHQgPSAoYXdhaXQgVXNlcklucHV0LmFzayhpbnB1dCkpW1xuICAgICAgICAgIGlucHV0Lm5hbWUgYXMga2V5b2YgQW5zd2VyczxzdHJpbmc+XG4gICAgICAgIF0gYXMgc3RyaW5nO1xuICAgICAgICBpZiAoIXRlc3QocmVzdWx0KSkge1xuICAgICAgICAgIHJlc3VsdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25maXJtYXRpb24gPSBhd2FpdCBVc2VySW5wdXQuYXNrQ29uZmlybWF0aW9uKFxuICAgICAgICAgIGAke2lucHV0Lm5hbWV9LWNvbmZpcm1gLFxuICAgICAgICAgIGBJcyB0aGUgJHtpbnB1dC50eXBlfSBjb3JyZWN0P2AsXG4gICAgICAgICAgZGVmYXVsdENvbmZpcm1hdGlvblxuICAgICAgICApO1xuICAgICAgICBpZiAoIWNvbmZpcm1hdGlvbikgcmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgICAgfSB3aGlsZSAodHlwZW9mIHJlc3VsdCA9PT0gXCJ1bmRlZmluZWRcIiAmJiBsaW1pdCA+IDEgJiYgY291bnQrKyA8IGxpbWl0KTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBsb2cuZXJyb3IoYEVycm9yIHdoaWxlIGluc2lzdGluZzogJHtlfWApO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gXCJ1bmRlZmluZWRcIikgbG9nLmluZm8oXCJubyBzZWxlY3Rpb24uLi5cIik7XG4gICAgcmV0dXJuIHJlc3VsdCBhcyBSIHwgdW5kZWZpbmVkO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVwZWF0ZWRseSBhc2tzIGZvciB0ZXh0IGlucHV0IHVudGlsIGEgdmFsaWQgcmVzcG9uc2UgaXMgZ2l2ZW4gb3IgdGhlIGxpbWl0IGlzIHJlYWNoZWQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIGluc2lzdHMgb24gZ2V0dGluZyBhIHZhbGlkIHRleHQgaW5wdXQgZnJvbSB0aGUgdXNlciwgYWxsb3dpbmcgZm9yIGEgc3BlY2lmaWVkIG51bWJlciBvZiBhdHRlbXB0cy5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvbXB0LCB1c2VkIGFzIHRoZSBrZXkgaW4gdGhlIHJldHVybmVkIGFuc3dlcnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBUaGUgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24obnVtYmVyKTpib29sZWFufSB0ZXN0IC0gVmFsaWRhdG9yIGZ1bmN0aW9uIHJlY2VpdmluZyB0aGUgdXNlciBpbnB1dCBhbmQgcmV0dXJuaW5nIHdoZXRoZXIgaXQgaXMgdmFsaWQuXG4gICAqIEBwYXJhbSBtYXNrIC0gVGhlIGNoYXJhY3RlciB1c2VkIHRvIG1hc2sgdGhlIGlucHV0IChvcHRpb25hbCwgZm9yIHBhc3N3b3JkLWxpa2UgaW5wdXRzKS5cbiAgICogQHBhcmFtIGluaXRpYWwgLSBUaGUgaW5pdGlhbCB2YWx1ZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIgKG9wdGlvbmFsKS5cbiAgICogQHBhcmFtIGRlZmF1bHRDb25maXJtYXRpb24gLSBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGNvbmZpcm1hdGlvbiBwcm9tcHQgKHRydWUgZm9yIHllcywgZmFsc2UgZm9yIG5vKS5cbiAgICogQHBhcmFtIGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzIGFsbG93ZWQgKGRlZmF1bHQgaXMgLTEsIG1lYW5pbmcgdW5saW1pdGVkKS5cbiAgICogQHJldHVybiBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgdmFsaWQgaW5wdXQgb3IgdW5kZWZpbmVkIGlmIHRoZSBsaW1pdCBpcyByZWFjaGVkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGluc2lzdEZvclRleHQoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHF1ZXN0aW9uOiBzdHJpbmcsXG4gICAgdGVzdDogKHJlczogc3RyaW5nKSA9PiBib29sZWFuLFxuICAgIG1hc2s6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbiAgICBpbml0aWFsPzogc3RyaW5nLFxuICAgIGRlZmF1bHRDb25maXJtYXRpb24gPSBmYWxzZSxcbiAgICBsaW1pdCA9IC0xXG4gICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgbG9nID0gVXNlcklucHV0LmxvZ2dlci5mb3IodGhpcy5pbnNpc3RGb3JUZXh0KTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBJbnNpc3RpbmcgZm9yIHRleHQgaW5wdXQ6IHVuZGVmaW5lZCwgcXVlc3Rpb246ICR7cXVlc3Rpb259LCB0ZXN0OiAke3Rlc3QudG9TdHJpbmcoKX0sIG1hc2s6ICR7bWFza30sIGluaXRpYWw6ICR7aW5pdGlhbH0sIGRlZmF1bHRDb25maXJtYXRpb246ICR7ZGVmYXVsdENvbmZpcm1hdGlvbn0sIGxpbWl0OiAke2xpbWl0fWBcbiAgICApO1xuICAgIGNvbnN0IHVzZXJJbnB1dCA9IG5ldyBVc2VySW5wdXQobmFtZSkuc2V0TWVzc2FnZShxdWVzdGlvbik7XG5cbiAgICBpZiAobWFzaykgdXNlcklucHV0LnNldE1hc2sobWFzayk7XG4gICAgaWYgKHR5cGVvZiBpbml0aWFsID09PSBcInN0cmluZ1wiKSB1c2VySW5wdXQuc2V0SW5pdGlhbChpbml0aWFsKTtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuaW5zaXN0KFxuICAgICAgdXNlcklucHV0LFxuICAgICAgdGVzdCBhcyAocmVzOiBzdHJpbmcgfCBudW1iZXIpID0+IGJvb2xlYW4sXG4gICAgICBkZWZhdWx0Q29uZmlybWF0aW9uLFxuICAgICAgbGltaXRcbiAgICApKSBhcyBzdHJpbmc7XG4gIH1cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXBlYXRlZGx5IGFza3MgZm9yIG51bWJlciBpbnB1dCB1bnRpbCBhIHZhbGlkIHJlc3BvbnNlIGlzIGdpdmVuIG9yIHRoZSBsaW1pdCBpcyByZWFjaGVkLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBpbnNpc3RzIG9uIGdldHRpbmcgYSB2YWxpZCBudW1iZXIgaW5wdXQgZnJvbSB0aGUgdXNlciwgYWxsb3dpbmcgZm9yIGEgc3BlY2lmaWVkIG51bWJlciBvZiBhdHRlbXB0cy5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvbXB0LCB1c2VkIGFzIHRoZSBrZXkgaW4gdGhlIHJldHVybmVkIGFuc3dlcnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBUaGUgbWVzc2FnZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuXG4gICAqIEBwYXJhbSB0ZXN0IC0gQSBmdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgdXNlcidzIGlucHV0LlxuICAgKiBAcGFyYW0gbWluIC0gVGhlIG1pbmltdW0gYWxsb3dlZCB2YWx1ZSAob3B0aW9uYWwpLlxuICAgKiBAcGFyYW0gbWF4IC0gVGhlIG1heGltdW0gYWxsb3dlZCB2YWx1ZSAob3B0aW9uYWwpLlxuICAgKiBAcGFyYW0gaW5pdGlhbCAtIFRoZSBpbml0aWFsIHZhbHVlIHByZXNlbnRlZCB0byB0aGUgdXNlciAob3B0aW9uYWwpLlxuICAgKiBAcGFyYW0gZGVmYXVsdENvbmZpcm1hdGlvbiAtIFRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUgY29uZmlybWF0aW9uIHByb21wdCAodHJ1ZSBmb3IgeWVzLCBmYWxzZSBmb3Igbm8pLlxuICAgKiBAcGFyYW0gbGltaXQgLSBUaGUgbWF4aW11bSBudW1iZXIgb2YgYXR0ZW1wdHMgYWxsb3dlZCAoZGVmYXVsdCBpcyAtMSwgbWVhbmluZyB1bmxpbWl0ZWQpLlxuICAgKiBAcmV0dXJuIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSB2YWxpZCBpbnB1dCBvciB1bmRlZmluZWQgaWYgdGhlIGxpbWl0IGlzIHJlYWNoZWQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgaW5zaXN0Rm9yTnVtYmVyKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBxdWVzdGlvbjogc3RyaW5nLFxuICAgIHRlc3Q6IChyZXM6IG51bWJlcikgPT4gYm9vbGVhbixcbiAgICBtaW4/OiBudW1iZXIsXG4gICAgbWF4PzogbnVtYmVyLFxuICAgIGluaXRpYWw/OiBudW1iZXIsXG4gICAgZGVmYXVsdENvbmZpcm1hdGlvbiA9IGZhbHNlLFxuICAgIGxpbWl0ID0gLTFcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBsb2cgPSBVc2VySW5wdXQubG9nZ2VyLmZvcih0aGlzLmluc2lzdEZvck51bWJlcik7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgSW5zaXN0aW5nIGZvciBudW1iZXIgaW5wdXQ6IHVuZGVmaW5lZCwgcXVlc3Rpb246ICR7cXVlc3Rpb259LCB0ZXN0OiAke3Rlc3QudG9TdHJpbmcoKX0sIG1pbjogJHttaW59LCBtYXg6ICR7bWF4fSwgaW5pdGlhbDogJHtpbml0aWFsfSwgZGVmYXVsdENvbmZpcm1hdGlvbjogJHtkZWZhdWx0Q29uZmlybWF0aW9ufSwgbGltaXQ6ICR7bGltaXR9YFxuICAgICk7XG4gICAgY29uc3QgdXNlcklucHV0ID0gbmV3IFVzZXJJbnB1dChuYW1lKVxuICAgICAgLnNldE1lc3NhZ2UocXVlc3Rpb24pXG4gICAgICAuc2V0VHlwZShcIm51bWJlclwiKTtcblxuICAgIGlmICh0eXBlb2YgbWluID09PSBcIm51bWJlclwiKSB1c2VySW5wdXQuc2V0TWluKG1pbik7XG5cbiAgICBpZiAodHlwZW9mIG1heCA9PT0gXCJudW1iZXJcIikgdXNlcklucHV0LnNldE1heChtYXgpO1xuXG4gICAgaWYgKHR5cGVvZiBpbml0aWFsID09PSBcIm51bWJlclwiKSB1c2VySW5wdXQuc2V0SW5pdGlhbChpbml0aWFsKTtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuaW5zaXN0KFxuICAgICAgdXNlcklucHV0LFxuICAgICAgdGVzdCBhcyAocmVzOiBzdHJpbmcgfCBudW1iZXIpID0+IGJvb2xlYW4sXG4gICAgICBkZWZhdWx0Q29uZmlybWF0aW9uLFxuICAgICAgbGltaXRcbiAgICApKSBhcyBudW1iZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBjb21tYW5kLWxpbmUgYXJndW1lbnRzIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBvcHRpb25zLlxuICAgKiBAc3VtbWFyeSBVc2VzIE5vZGUuanMncyB1dGlsLnBhcnNlQXJncyB0byBwYXJzZSBjb21tYW5kLWxpbmUgYXJndW1lbnRzIGFuZCByZXR1cm4gdGhlIHJlc3VsdC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHBhcnNpbmcgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJuIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwYXJzZWQgYXJndW1lbnRzLlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IFAgYXMgcGFyc2VBcmdzIG1ldGhvZFxuICAgKiAgIHBhcnRpY2lwYW50IFUgYXMgdXRpbC5wYXJzZUFyZ3NcbiAgICogICBDLT4+UDogQ2FsbCB3aXRoIG9wdGlvbnNcbiAgICogICBQLT4+UDogUHJlcGFyZSBhcmdzIG9iamVjdFxuICAgKiAgIFAtPj5VOiBDYWxsIHBhcnNlQXJncyB3aXRoIHByZXBhcmVkIGFyZ3NcbiAgICogICBVLT4+UDogUmV0dXJuIHBhcnNlZCByZXN1bHRcbiAgICogICBQLS0+PkM6IFJldHVybiBQYXJzZUFyZ3NSZXN1bHRcbiAgICovXG4gIHN0YXRpYyBwYXJzZUFyZ3Mob3B0aW9uczogUGFyc2VBcmdzT3B0aW9uc0NvbmZpZyk6IFBhcnNlQXJnc1Jlc3VsdCB7XG4gICAgY29uc3QgbG9nID0gVXNlcklucHV0LmxvZ2dlci5mb3IodGhpcy5wYXJzZUFyZ3MpO1xuICAgIGNvbnN0IGFyZ3M6IFBhcnNlQXJnc0NvbmZpZyA9IHtcbiAgICAgIGFyZ3M6IHByb2Nlc3MuYXJndi5zbGljZSgyKSxcbiAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgfTtcbiAgICBsb2cuZGVidWcoYFBhcnNpbmcgYXJndW1lbnRzOiAke0pTT04uc3RyaW5naWZ5KGFyZ3MsIG51bGwsIDIpfWApO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcGFyc2VBcmdzKGFyZ3MpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2cuZGVidWcoXG4gICAgICAgIGBFcnJvciB3aGlsZSBwYXJzaW5nIGFyZ3VtZW50czpcXG4ke0pTT04uc3RyaW5naWZ5KGFyZ3MsIG51bGwsIDIpfVxcbiB8IG9wdGlvbnNcXG4ke0pTT04uc3RyaW5naWZ5KG9wdGlvbnMsIG51bGwsIDIpfVxcbiB8ICR7ZXJyb3J9YFxuICAgICAgKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3Igd2hpbGUgcGFyc2luZyBhcmd1bWVudHM6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGNvbW1hbmQgb3B0aW9ucyBmb3IgQ0xJIGNvbW1hbmRzLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgc3RydWN0dXJlIGFuZCBkZWZhdWx0IHZhbHVlcyBmb3IgY29tbW9uIGNvbW1hbmQtbGluZSBvcHRpb25zIHVzZWQgYWNyb3NzIHZhcmlvdXMgQ0xJIGNvbW1hbmRzLlxuICogQGNvbnN0IERlZmF1bHRDb21tYW5kT3B0aW9uc1xuICogQHR5cGVkZWYge09iamVjdH0gRGVmYXVsdENvbW1hbmRPcHRpb25zXG4gKiBAcHJvcGVydHkge09iamVjdH0gdmVyYm9zZSAtIFZlcmJvc2l0eSBsZXZlbCBvcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdmVyYm9zZS50eXBlIC0gVGhlIHR5cGUgb2YgdGhlIHZlcmJvc2Ugb3B0aW9uIChudW1iZXIpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHZlcmJvc2Uuc2hvcnQgLSBUaGUgc2hvcnQgZmxhZyBmb3IgdGhlIHZlcmJvc2Ugb3B0aW9uIChWKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJib3NlLmRlZmF1bHQgLSBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdmVyYm9zaXR5ICgwKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB2ZXJzaW9uIC0gVmVyc2lvbiBkaXNwbGF5IG9wdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB2ZXJzaW9uLnR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgdmVyc2lvbiBvcHRpb24gKGJvb2xlYW4pLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHZlcnNpb24uc2hvcnQgLSBUaGUgc2hvcnQgZmxhZyBmb3IgdGhlIHZlcnNpb24gb3B0aW9uICh2KS5cbiAqIEBwcm9wZXJ0eSB7dW5kZWZpbmVkfSB2ZXJzaW9uLmRlZmF1bHQgLSBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdmVyc2lvbiBkaXNwbGF5ICh1bmRlZmluZWQpLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlbHAgLSBIZWxwIGRpc3BsYXkgb3B0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGhlbHAudHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBoZWxwIG9wdGlvbiAoYm9vbGVhbikuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaGVscC5zaG9ydCAtIFRoZSBzaG9ydCBmbGFnIGZvciB0aGUgaGVscCBvcHRpb24gKGgpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBoZWxwLmRlZmF1bHQgLSBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgaGVscCBkaXNwbGF5IChmYWxzZSkuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nTGV2ZWwgLSBMb2cgbGV2ZWwgb3B0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGxvZ0xldmVsLnR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgbG9nTGV2ZWwgb3B0aW9uIChzdHJpbmcpLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGxvZ0xldmVsLmRlZmF1bHQgLSBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgbG9nIGxldmVsIChcImluZm9cIikuXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nU3R5bGUgLSBMb2cgc3R5bGluZyBvcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbG9nU3R5bGUudHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBsb2dTdHlsZSBvcHRpb24gKGJvb2xlYW4pLlxuICogQHByb3BlcnR5IHtib29sZWFufSBsb2dTdHlsZS5kZWZhdWx0IC0gVGhlIGRlZmF1bHQgdmFsdWUgZm9yIGxvZyBzdHlsaW5nICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSB0aW1lc3RhbXAgLSBUaW1lc3RhbXAgZGlzcGxheSBvcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdGltZXN0YW1wLnR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgdGltZXN0YW1wIG9wdGlvbiAoYm9vbGVhbikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHRpbWVzdGFtcC5kZWZhdWx0IC0gVGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRpbWVzdGFtcCBkaXNwbGF5ICh0cnVlKS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBiYW5uZXIgLSBCYW5uZXIgZGlzcGxheSBvcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYmFubmVyLnR5cGUgLSBUaGUgdHlwZSBvZiB0aGUgYmFubmVyIG9wdGlvbiAoYm9vbGVhbikuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGJhbm5lci5kZWZhdWx0IC0gVGhlIGRlZmF1bHQgdmFsdWUgZm9yIGJhbm5lciBkaXNwbGF5IChmYWxzZSkuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0Q29tbWFuZE9wdGlvbnMgPSB7XG4gIHZlcmJvc2U6IHtcbiAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICBzaG9ydDogXCJWXCIsXG4gICAgZGVmYXVsdDogdW5kZWZpbmVkLFxuICB9LFxuICB2ZXJzaW9uOiB7XG4gICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgc2hvcnQ6IFwidlwiLFxuICAgIGRlZmF1bHQ6IHVuZGVmaW5lZCxcbiAgfSxcbiAgaGVscDoge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIHNob3J0OiBcImhcIixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgIGRlZmF1bHQ6IFwiaW5mb1wiLFxuICB9LFxuICBsb2dTdHlsZToge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG4gIHRpbWVzdGFtcDoge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG4gIGJhbm5lcjoge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIGRlZmF1bHQ6IHRydWUsXG4gIH0sXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGNvbW1hbmQgdmFsdWVzIGRlcml2ZWQgZnJvbSBEZWZhdWx0Q29tbWFuZE9wdGlvbnMuXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIHRoZSBkZWZhdWx0IHZhbHVlcyBvZiBhbGwgb3B0aW9ucyBkZWZpbmVkIGluIERlZmF1bHRDb21tYW5kT3B0aW9ucy5cbiAqIEBjb25zdCBEZWZhdWx0Q29tbWFuZFZhbHVlc1xuICogQHR5cGVkZWYge09iamVjdH0gRGVmYXVsdENvbW1hbmRWYWx1ZXNcbiAqIEBwcm9wZXJ0eSB7dW5rbm93bn0gW2tleTogc3RyaW5nXSAtIFRoZSBkZWZhdWx0IHZhbHVlIGZvciBlYWNoIG9wdGlvbiBpbiBEZWZhdWx0Q29tbWFuZE9wdGlvbnMuXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0Q29tbWFuZFZhbHVlczoge1xuICBbayBpbiBrZXlvZiB0eXBlb2YgRGVmYXVsdENvbW1hbmRPcHRpb25zXTogdW5rbm93bjtcbn0gPSBPYmplY3Qua2V5cyhEZWZhdWx0Q29tbWFuZE9wdGlvbnMpLnJlZHVjZShcbiAgKGFjYzogUmVjb3JkPGtleW9mIHR5cGVvZiBEZWZhdWx0Q29tbWFuZE9wdGlvbnMsIHVua25vd24+LCBrZXk6IHN0cmluZykgPT4ge1xuICAgIGFjY1trZXkgYXMga2V5b2YgdHlwZW9mIERlZmF1bHRDb21tYW5kT3B0aW9uc10gPVxuICAgICAgRGVmYXVsdENvbW1hbmRPcHRpb25zW2tleSBhcyBrZXlvZiB0eXBlb2YgRGVmYXVsdENvbW1hbmRPcHRpb25zXS5kZWZhdWx0O1xuICAgIHJldHVybiBhY2M7XG4gIH0sXG4gIHt9IGFzIFJlY29yZDxrZXlvZiB0eXBlb2YgRGVmYXVsdENvbW1hbmRWYWx1ZXMsIHVua25vd24+XG4pO1xuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCBlbmNvZGluZyBmb3IgdGV4dCBvcGVyYXRpb25zLlxuICogQHN1bW1hcnkgVGhlIHN0YW5kYXJkIFVURi04IGVuY29kaW5nIHVzZWQgZm9yIHRleHQgcHJvY2Vzc2luZy5cbiAqIEBjb25zdCB7c3RyaW5nfSBFbmNvZGluZ1xuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgY29uc3QgRW5jb2RpbmcgPSBcInV0Zi04XCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlZ3VsYXIgZXhwcmVzc2lvbiBmb3Igc2VtYW50aWMgdmVyc2lvbmluZy5cbiAqIEBzdW1tYXJ5IEEgcmVnZXggcGF0dGVybiB0byBtYXRjaCBhbmQgcGFyc2Ugc2VtYW50aWMgdmVyc2lvbiBzdHJpbmdzLlxuICogQGNvbnN0IHtSZWdFeHB9IFNlbVZlcnNpb25SZWdleFxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgY29uc3QgU2VtVmVyc2lvblJlZ2V4ID1cbiAgL14oXFxkKylcXC4oXFxkKylcXC4oXFxkKykoPzotKFswLTlBLVphLXotXSsoPzpcXC5bMC05QS1aYS16XSkpKS9nO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGZvciBzZW1hbnRpYyB2ZXJzaW9uIGNvbXBvbmVudHMuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSB0aHJlZSBsZXZlbHMgb2Ygc2VtYW50aWMgdmVyc2lvbmluZzogUEFUQ0gsIE1JTk9SLCBhbmQgTUFKT1IuXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZW51bSBTZW1WZXJzaW9uIHtcbiAgLyoqIFBhdGNoIHZlcnNpb24gZm9yIGJhY2t3YXJkcy1jb21wYXRpYmxlIGJ1ZyBmaXhlcy4gKi9cbiAgUEFUQ0ggPSBcInBhdGNoXCIsXG4gIC8qKiBNaW5vciB2ZXJzaW9uIGZvciBiYWNrd2FyZHMtY29tcGF0aWJsZSBuZXcgZmVhdHVyZXMuICovXG4gIE1JTk9SID0gXCJtaW5vclwiLFxuICAvKiogTWFqb3IgdmVyc2lvbiBmb3IgY2hhbmdlcyB0aGF0IGJyZWFrIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LiAqL1xuICBNQUpPUiA9IFwibWFqb3JcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRmxhZyB0byBpbmRpY2F0ZSBub24tQ0kgZW52aXJvbm1lbnQuXG4gKiBAc3VtbWFyeSBVc2VkIHRvIHNwZWNpZnkgdGhhdCBhIGNvbW1hbmQgc2hvdWxkIHJ1biBvdXRzaWRlIG9mIGEgQ29udGludW91cyBJbnRlZ3JhdGlvbiBlbnZpcm9ubWVudC5cbiAqIEBjb25zdCB7c3RyaW5nfSBOb0NJRkxhZ1xuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgY29uc3QgTm9DSUZMYWcgPSBcIi1uby1jaVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBLZXkgZm9yIHRoZSBzZXR1cCBzY3JpcHQgaW4gcGFja2FnZS5qc29uLlxuICogQHN1bW1hcnkgSWRlbnRpZmllcyB0aGUgc2NyaXB0IHRoYXQgcnVucyBhZnRlciBwYWNrYWdlIGluc3RhbGxhdGlvbi5cbiAqIEBjb25zdCB7c3RyaW5nfSBTZXR1cFNjcmlwdEtleVxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgY29uc3QgU2V0dXBTY3JpcHRLZXkgPSBcInBvc3RpbnN0YWxsXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVudW0gZm9yIHZhcmlvdXMgYXV0aGVudGljYXRpb24gdG9rZW5zLlxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgZmlsZSBuYW1lcyBmb3Igc3RvcmluZyBkaWZmZXJlbnQgdHlwZXMgb2YgYXV0aGVudGljYXRpb24gdG9rZW5zLlxuICogQGVudW0ge3N0cmluZ31cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGVudW0gVG9rZW5zIHtcbiAgLyoqIEdpdCBhdXRoZW50aWNhdGlvbiB0b2tlbiBmaWxlIG5hbWUuICovXG4gIEdJVCA9IFwiLnRva2VuXCIsXG4gIC8qKiBOUE0gYXV0aGVudGljYXRpb24gdG9rZW4gZmlsZSBuYW1lLiAqL1xuICBOUE0gPSBcIi5ucG10b2tlblwiLFxuICAvKiogRG9ja2VyIGF1dGhlbnRpY2F0aW9uIHRva2VuIGZpbGUgbmFtZS4gKi9cbiAgRE9DS0VSID0gXCIuZG9ja2VydG9rZW5cIixcbiAgLyoqIENvbmZsdWVuY2UgYXV0aGVudGljYXRpb24gdG9rZW4gZmlsZSBuYW1lLiAqL1xuICBDT05GTFVFTkNFID0gXCIuY29uZmx1ZW5jZS10b2tlblwiLFxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb2RlIHVzZWQgdG8gaW5kaWNhdGUgYW4gb3BlcmF0aW9uIHdhcyBhYm9ydGVkLlxuICogQHN1bW1hcnkgU3RhbmRhcmQgbWVzc2FnZSB1c2VkIHdoZW4gYSBwcm9jZXNzIGlzIG1hbnVhbGx5IHRlcm1pbmF0ZWQuXG4gKiBAY29uc3Qge3N0cmluZ30gQWJvcnRDb2RlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBjb25zdCBBYm9ydENvZGUgPSBcIkFib3J0ZWRcIjtcbiIsImltcG9ydCB7IEVuY29kaW5nIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgT3V0cHV0V3JpdGVyIH0gZnJvbSBcIi4vT3V0cHV0V3JpdGVyXCI7XG5pbXBvcnQgeyBQcm9taXNlRXhlY3V0b3IgfSBmcm9tIFwiLi4vdXRpbHMvdHlwZXNcIjtcbmltcG9ydCB7IE91dHB1dFR5cGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgc3R5bGUgfSBmcm9tIFwic3R5bGVkLXN0cmluZy1idWlsZGVyXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IHBhcnNlIH0gZnJvbSBcInNoZWxsLXF1b3RlXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgc3RhbmRhcmQgb3V0cHV0IHdyaXRlciBmb3IgaGFuZGxpbmcgY29tbWFuZCBleGVjdXRpb24gb3V0cHV0LlxuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBPdXRwdXRXcml0ZXIgaW50ZXJmYWNlIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvclxuICogaGFuZGxpbmcgdmFyaW91cyB0eXBlcyBvZiBvdXRwdXQgZnJvbSBjb21tYW5kIGV4ZWN1dGlvbiwgaW5jbHVkaW5nIHN0YW5kYXJkIG91dHB1dCxcbiAqIGVycm9yIG91dHB1dCwgYW5kIGV4aXQgY29kZXMuIEl0IGFsc28gaW5jbHVkZXMgdXRpbGl0eSBtZXRob2RzIGZvciBwYXJzaW5nIGNvbW1hbmRzXG4gKiBhbmQgcmVzb2x2aW5nIG9yIHJlamVjdGluZyBwcm9taXNlcyBiYXNlZCBvbiBleGVjdXRpb24gcmVzdWx0cy5cbiAqXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSB0eXBlIG9mIHRoZSByZXNvbHZlZCB2YWx1ZSwgZGVmYXVsdGluZyB0byBzdHJpbmcuXG4gKlxuICogQHBhcmFtIGNtZCAtIFRoZSBjb21tYW5kIHN0cmluZyB0byBiZSBleGVjdXRlZC5cbiAqIEBwYXJhbSBsb2NrIC0gQSBQcm9taXNlRXhlY3V0b3IgdG8gY29udHJvbCB0aGUgYXN5bmNocm9ub3VzIGZsb3cuXG4gKiBAcGFyYW0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzICh1bnVzZWQgaW4gdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24pLlxuICpcbiAqIEBjbGFzc1xuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFN0YW5kYXJkT3V0cHV0V3JpdGVyIH0gZnJvbSAnQGRlY2FmLXRzL3V0aWxzJztcbiAqIGltcG9ydCB7IFByb21pc2VFeGVjdXRvciB9IGZyb20gJ0BkZWNhZi10cy91dGlscyc7XG4gKlxuICogLy8gQ3JlYXRlIGEgcHJvbWlzZSBleGVjdXRvclxuICogY29uc3QgZXhlY3V0b3I6IFByb21pc2VFeGVjdXRvcjxzdHJpbmc+ID0ge1xuICogICByZXNvbHZlOiAodmFsdWUpID0+IGNvbnNvbGUubG9nKGBSZXNvbHZlZDogJHt2YWx1ZX1gKSxcbiAqICAgcmVqZWN0OiAoZXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoYFJlamVjdGVkOiAke2Vycm9yLm1lc3NhZ2V9YClcbiAqIH07XG4gKlxuICogLy8gQ3JlYXRlIGEgc3RhbmRhcmQgb3V0cHV0IHdyaXRlclxuICogY29uc3Qgd3JpdGVyID0gbmV3IFN0YW5kYXJkT3V0cHV0V3JpdGVyKCdscyAtbGEnLCBleGVjdXRvcik7XG4gKlxuICogLy8gVXNlIHRoZSB3cml0ZXIgdG8gaGFuZGxlIGNvbW1hbmQgb3V0cHV0XG4gKiB3cml0ZXIuZGF0YSgnRmlsZSBsaXN0IG91dHB1dC4uLicpO1xuICogd3JpdGVyLmV4aXQoMCwgWydDb21tYW5kIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseSddKTtcbiAqIGBgYFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFN0YW5kYXJkT3V0cHV0V3JpdGVyXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlclxuICogICBwYXJ0aWNpcGFudCBQcm9taXNlRXhlY3V0b3JcbiAqXG4gKiAgIENsaWVudC0+PlN0YW5kYXJkT3V0cHV0V3JpdGVyOiBuZXcgU3RhbmRhcmRPdXRwdXRXcml0ZXIoY21kLCBsb2NrKVxuICogICBTdGFuZGFyZE91dHB1dFdyaXRlci0+PkxvZ2dlcjogTG9nZ2luZy5mb3IoY21kKVxuICpcbiAqICAgQ2xpZW50LT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IGRhdGEoY2h1bmspXG4gKiAgIFN0YW5kYXJkT3V0cHV0V3JpdGVyLT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IGxvZyhcInN0ZG91dFwiLCBjaHVuaylcbiAqICAgU3RhbmRhcmRPdXRwdXRXcml0ZXItPj5Mb2dnZXI6IGxvZ2dlci5pbmZvKGxvZylcbiAqXG4gKiAgIENsaWVudC0+PlN0YW5kYXJkT3V0cHV0V3JpdGVyOiBlcnJvcihjaHVuaylcbiAqICAgU3RhbmRhcmRPdXRwdXRXcml0ZXItPj5TdGFuZGFyZE91dHB1dFdyaXRlcjogbG9nKFwic3RkZXJyXCIsIGNodW5rKVxuICogICBTdGFuZGFyZE91dHB1dFdyaXRlci0+PkxvZ2dlcjogbG9nZ2VyLmluZm8obG9nKVxuICpcbiAqICAgQ2xpZW50LT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IGV4aXQoY29kZSwgbG9ncylcbiAqICAgU3RhbmRhcmRPdXRwdXRXcml0ZXItPj5TdGFuZGFyZE91dHB1dFdyaXRlcjogbG9nKFwic3Rkb3V0XCIsIGV4aXRNZXNzYWdlKVxuICogICBhbHQgY29kZSA9PT0gMFxuICogICAgIFN0YW5kYXJkT3V0cHV0V3JpdGVyLT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IHJlc29sdmUobG9ncylcbiAqICAgICBTdGFuZGFyZE91dHB1dFdyaXRlci0+PlByb21pc2VFeGVjdXRvcjogbG9jay5yZXNvbHZlKHJlYXNvbilcbiAqICAgZWxzZSBjb2RlICE9PSAwXG4gKiAgICAgU3RhbmRhcmRPdXRwdXRXcml0ZXItPj5TdGFuZGFyZE91dHB1dFdyaXRlcjogcmVqZWN0KGVycm9yKVxuICogICAgIFN0YW5kYXJkT3V0cHV0V3JpdGVyLT4+UHJvbWlzZUV4ZWN1dG9yOiBsb2NrLnJlamVjdChyZWFzb24pXG4gKiAgIGVuZFxuICovXG5leHBvcnQgY2xhc3MgU3RhbmRhcmRPdXRwdXRXcml0ZXI8UiA9IHN0cmluZz4gaW1wbGVtZW50cyBPdXRwdXRXcml0ZXIge1xuICBwcm90ZWN0ZWQgbG9nZ2VyOiBMb2dnZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGNtZDogc3RyaW5nLFxuICAgIHByb3RlY3RlZCBsb2NrOiBQcm9taXNlRXhlY3V0b3I8Uj4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IHVua25vd25bXVxuICApIHtcbiAgICB0aGlzLmxvZ2dlciA9IExvZ2dpbmcuZm9yKHRoaXMuY21kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9ncyBvdXRwdXQgdG8gdGhlIGNvbnNvbGUuXG4gICAqIEBzdW1tYXJ5IEZvcm1hdHMgYW5kIGxvZ3MgdGhlIGdpdmVuIGRhdGEgd2l0aCBhIHRpbWVzdGFtcCBhbmQgdHlwZSBpbmRpY2F0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gVGhlIHR5cGUgb2Ygb3V0cHV0IChzdGRvdXQgb3Igc3RkZXJyKS5cbiAgICogQHBhcmFtIGRhdGEgLSBUaGUgZGF0YSB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgbG9nKHR5cGU6IE91dHB1dFR5cGUsIGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikge1xuICAgIGRhdGEgPSBCdWZmZXIuaXNCdWZmZXIoZGF0YSkgPyBkYXRhLnRvU3RyaW5nKEVuY29kaW5nKSA6IGRhdGE7XG4gICAgY29uc3QgbG9nID0gdHlwZSA9PT0gXCJzdGRlcnJcIiA/IHN0eWxlKGRhdGEpLnJlZC50ZXh0IDogZGF0YTtcbiAgICB0aGlzLmxvZ2dlci5pbmZvKGxvZyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgc3RhbmRhcmQgb3V0cHV0IGRhdGEuXG4gICAqIEBzdW1tYXJ5IExvZ3MgdGhlIGdpdmVuIGNodW5rIGFzIHN0YW5kYXJkIG91dHB1dC5cbiAgICpcbiAgICogQHBhcmFtIGNodW5rIC0gVGhlIGRhdGEgY2h1bmsgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgZGF0YShjaHVuazogYW55KSB7XG4gICAgdGhpcy5sb2coXCJzdGRvdXRcIiwgU3RyaW5nKGNodW5rKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgZXJyb3Igb3V0cHV0IGRhdGEuXG4gICAqIEBzdW1tYXJ5IExvZ3MgdGhlIGdpdmVuIGNodW5rIGFzIGVycm9yIG91dHB1dC5cbiAgICpcbiAgICogQHBhcmFtIGNodW5rIC0gVGhlIGVycm9yIGRhdGEgY2h1bmsgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgZXJyb3IoY2h1bms6IGFueSkge1xuICAgIHRoaXMubG9nKFwic3RkZXJyXCIsIFN0cmluZyhjaHVuaykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIGVycm9yIG9iamVjdHMuXG4gICAqIEBzdW1tYXJ5IExvZ3MgdGhlIGVycm9yIG1lc3NhZ2UgZnJvbSB0aGUgZ2l2ZW4gRXJyb3Igb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0gZXJyIC0gVGhlIEVycm9yIG9iamVjdCB0byBiZSBsb2dnZWQuXG4gICAqL1xuICBlcnJvcnMoZXJyOiBFcnJvcikge1xuICAgIHRoaXMubG9nKFwic3RkZXJyXCIsIGBFcnJvciBleGVjdXRpbmcgY29tbWFuZCBleGl0ZWQgOiAke2Vycn1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyB0aGUgZXhpdCBvZiBhIGNvbW1hbmQuXG4gICAqIEBzdW1tYXJ5IExvZ3MgdGhlIGV4aXQgY29kZSBhbmQgcmVzb2x2ZXMgb3IgcmVqZWN0cyB0aGUgcHJvbWlzZSBiYXNlZCBvbiB0aGUgY29kZS5cbiAgICpcbiAgICogQHBhcmFtIGNvZGUgLSBUaGUgZXhpdCBjb2RlIG9mIHRoZSBjb21tYW5kLlxuICAgKiBAcGFyYW0gbG9ncyAtIEFycmF5IG9mIGxvZyBtZXNzYWdlcyB0byBiZSBwcm9jZXNzZWQgYmVmb3JlIGV4aXRpbmcuXG4gICAqL1xuICBleGl0KGNvZGU6IG51bWJlciB8IHN0cmluZywgbG9nczogc3RyaW5nW10pIHtcbiAgICB0aGlzLmxvZyhcbiAgICAgIFwic3Rkb3V0XCIsXG4gICAgICBgY29tbWFuZCBleGl0ZWQgY29kZSA6ICR7Y29kZSA9PT0gMCA/IHN0eWxlKGNvZGUudG9TdHJpbmcoKSkuZ3JlZW4udGV4dCA6IHN0eWxlKGNvZGUgPT09IG51bGwgPyBcIm51bGxcIiA6IGNvZGUudG9TdHJpbmcoKSkucmVkLnRleHR9YFxuICAgICk7XG4gICAgaWYgKGNvZGUgPT09IDApIHtcbiAgICAgIHRoaXMucmVzb2x2ZShsb2dzLm1hcCgobCkgPT4gbC50cmltKCkpLmpvaW4oXCJcXG5cIikgYXMgUik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVqZWN0KG5ldyBFcnJvcihsb2dzLmxlbmd0aCA/IGxvZ3Muam9pbihcIlxcblwiKSA6IGNvZGUudG9TdHJpbmcoKSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGFyc2VzIGEgY29tbWFuZCBzdHJpbmcgb3IgYXJyYXkgaW50byBjb21wb25lbnRzLlxuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyB0aGUgY29tbWFuZCBpbnRvIGEgY29uc2lzdGVudCBmb3JtYXQgYW5kIHN0b3JlcyBpdCwgdGhlbiByZXR1cm5zIGl0IHNwbGl0IGludG8gY29tbWFuZCBhbmQgYXJndW1lbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gY29tbWFuZCAtIFRoZSBjb21tYW5kIGFzIGEgc3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3MuXG4gICAqIEByZXR1cm4gQSB0dXBsZSBjb250YWluaW5nIHRoZSBjb21tYW5kIGFuZCBpdHMgYXJndW1lbnRzIGFzIHNlcGFyYXRlIGVsZW1lbnRzLlxuICAgKi9cbiAgcGFyc2VDb21tYW5kKGNvbW1hbmQ6IHN0cmluZyB8IHN0cmluZ1tdKTogW3N0cmluZywgc3RyaW5nW11dIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjb21tYW5kKSkge1xuICAgICAgdGhpcy5jbWQgPSBjb21tYW5kLmpvaW4oXCIgXCIpO1xuICAgICAgcmV0dXJuIFtjb21tYW5kWzBdLCBjb21tYW5kLnNsaWNlKDEpXTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJ0cyA9IHBhcnNlKGNvbW1hbmQpXG4gICAgICAuZmlsdGVyKChwKSA9PiB0eXBlb2YgcCA9PT0gXCJzdHJpbmdcIilcbiAgICAgIC5tYXAoU3RyaW5nKTtcblxuICAgIHRoaXMuY21kID0gcGFydHMuam9pbihcIiBcIik7XG4gICAgcmV0dXJuIFtwYXJ0c1swXSwgcGFydHMuc2xpY2UoMSldO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXNvbHZlcyB0aGUgcHJvbWlzZSB3aXRoIGEgc3VjY2VzcyBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBMb2dzIGEgc3VjY2VzcyBtZXNzYWdlIGFuZCByZXNvbHZlcyB0aGUgcHJvbWlzZSB3aXRoIHRoZSBnaXZlbiByZWFzb24uXG4gICAqXG4gICAqIEBwYXJhbSByZWFzb24gLSBUaGUgcmVhc29uIGZvciByZXNvbHZpbmcgdGhlIHByb21pc2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVzb2x2ZShyZWFzb246IFIpIHtcbiAgICB0aGlzLmxvZyhcbiAgICAgIFwic3Rkb3V0XCIsXG4gICAgICBgJHt0aGlzLmNtZH0gZXhlY3V0ZWQgc3VjY2Vzc2Z1bGx5OiAke3N0eWxlKHJlYXNvbiA/IFwicmFuIHRvIGNvbXBsZXRpb25cIiA6IChyZWFzb24gYXMgc3RyaW5nKSkuZ3JlZW59YFxuICAgICk7XG4gICAgdGhpcy5sb2NrLnJlc29sdmUocmVhc29uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVqZWN0cyB0aGUgcHJvbWlzZSB3aXRoIGFuIGVycm9yIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IExvZ3MgYW4gZXJyb3IgbWVzc2FnZSBhbmQgcmVqZWN0cyB0aGUgcHJvbWlzZSB3aXRoIHRoZSBnaXZlbiByZWFzb24uXG4gICAqXG4gICAqIEBwYXJhbSByZWFzb24gLSBUaGUgcmVhc29uIGZvciByZWplY3RpbmcgdGhlIHByb21pc2UsIGVpdGhlciBhIG51bWJlciAoZXhpdCBjb2RlKSBvciBhIHN0cmluZy5cbiAgICovXG4gIHByb3RlY3RlZCByZWplY3QocmVhc29uOiBudW1iZXIgfCBzdHJpbmcgfCBFcnJvcikge1xuICAgIGlmICghKHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgcmVhc29uID0gbmV3IEVycm9yKFxuICAgICAgICB0eXBlb2YgcmVhc29uID09PSBcIm51bWJlclwiID8gYEV4aXQgY29kZSAke3JlYXNvbn1gIDogcmVhc29uXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmxvZyhcbiAgICAgIFwic3RkZXJyXCIsXG4gICAgICBgJHt0aGlzLmNtZH0gZmFpbGVkIHRvIGV4ZWN1dGU6ICR7c3R5bGUocmVhc29uLm1lc3NhZ2UpLnJlZH1gXG4gICAgKTtcbiAgICB0aGlzLmxvY2sucmVqZWN0KHJlYXNvbik7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIENoaWxkUHJvY2Vzc1dpdGhvdXROdWxsU3RyZWFtcyxcbiAgc3Bhd24sXG4gIFNwYXduT3B0aW9uc1dpdGhvdXRTdGRpbyxcbn0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IFN0YW5kYXJkT3V0cHV0V3JpdGVyIH0gZnJvbSBcIi4uL3dyaXRlcnMvU3RhbmRhcmRPdXRwdXRXcml0ZXJcIjtcbmltcG9ydCB7IENvbW1hbmRSZXN1bHQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgT3V0cHV0V3JpdGVyQ29uc3RydWN0b3IgfSBmcm9tIFwiLi4vd3JpdGVycy90eXBlc1wiO1xuaW1wb3J0IHsgQWJvcnRDb2RlIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGxvY2tlZCB2ZXJzaW9uIG9mIGEgZnVuY3Rpb24uXG4gKiBAc3VtbWFyeSBUaGlzIGhpZ2hlci1vcmRlciBmdW5jdGlvbiB0YWtlcyBhIGZ1bmN0aW9uIGFuZCByZXR1cm5zIGEgbmV3IGZ1bmN0aW9uIHRoYXQgZW5zdXJlc1xuICogc2VxdWVudGlhbCBleGVjdXRpb24gb2YgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uLCBldmVuIHdoZW4gY2FsbGVkIG11bHRpcGxlIHRpbWVzIGNvbmN1cnJlbnRseS5cbiAqIEl0IHVzZXMgYSBQcm9taXNlLWJhc2VkIGxvY2tpbmcgbWVjaGFuaXNtIHRvIHF1ZXVlIGZ1bmN0aW9uIGNhbGxzLlxuICpcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJldHVybiB0eXBlIG9mIHRoZSBpbnB1dCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0gZiAtIFRoZSBmdW5jdGlvbiB0byBiZSBsb2NrZWQuIEl0IGNhbiB0YWtlIGFueSBudW1iZXIgb2YgcGFyYW1ldGVycyBhbmQgcmV0dXJuIGEgdmFsdWUgb2YgdHlwZSBSLlxuICogQHJldHVybiBBIG5ldyBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lIHNpZ25hdHVyZSBhcyB0aGUgaW5wdXQgZnVuY3Rpb24sIGJ1dCB3aXRoIHNlcXVlbnRpYWwgZXhlY3V0aW9uIGd1YXJhbnRlZWQuXG4gKlxuICogQGZ1bmN0aW9uIGxvY2tpZnlcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBMb2NrZWRGdW5jdGlvblxuICogICBwYXJ0aWNpcGFudCBPcmlnaW5hbEZ1bmN0aW9uXG4gKiAgIENhbGxlci0+PkxvY2tlZEZ1bmN0aW9uOiBDYWxsIHdpdGggcGFyYW1zXG4gKiAgIExvY2tlZEZ1bmN0aW9uLT4+TG9ja2VkRnVuY3Rpb246IENoZWNrIGN1cnJlbnQgbG9ja1xuICogICBhbHQgTG9jayBpcyByZXNvbHZlZFxuICogICAgIExvY2tlZEZ1bmN0aW9uLT4+T3JpZ2luYWxGdW5jdGlvbjogRXhlY3V0ZSB3aXRoIHBhcmFtc1xuICogICAgIE9yaWdpbmFsRnVuY3Rpb24tLT4+TG9ja2VkRnVuY3Rpb246IFJldHVybiByZXN1bHRcbiAqICAgICBMb2NrZWRGdW5jdGlvbi0tPj5DYWxsZXI6IFJldHVybiByZXN1bHRcbiAqICAgZWxzZSBMb2NrIGlzIHBlbmRpbmdcbiAqICAgICBMb2NrZWRGdW5jdGlvbi0+PkxvY2tlZEZ1bmN0aW9uOiBRdWV1ZSBleGVjdXRpb25cbiAqICAgICBMb2NrZWRGdW5jdGlvbi0tPj5DYWxsZXI6IFJldHVybiBwcm9taXNlXG4gKiAgICAgTm90ZSBvdmVyIExvY2tlZEZ1bmN0aW9uOiBXYWl0IGZvciBwcmV2aW91cyBleGVjdXRpb25cbiAqICAgICBMb2NrZWRGdW5jdGlvbi0+Pk9yaWdpbmFsRnVuY3Rpb246IEV4ZWN1dGUgd2l0aCBwYXJhbXNcbiAqICAgICBPcmlnaW5hbEZ1bmN0aW9uLS0+PkxvY2tlZEZ1bmN0aW9uOiBSZXR1cm4gcmVzdWx0XG4gKiAgICAgTG9ja2VkRnVuY3Rpb24tLT4+Q2FsbGVyOiBSZXNvbHZlIHByb21pc2Ugd2l0aCByZXN1bHRcbiAqICAgZW5kXG4gKiAgIExvY2tlZEZ1bmN0aW9uLT4+TG9ja2VkRnVuY3Rpb246IFVwZGF0ZSBsb2NrXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbG9ja2lmeTxSPihmOiAoLi4ucGFyYW1zOiB1bmtub3duW10pID0+IFIpIHtcbiAgbGV0IGxvY2s6IFByb21pc2U8UiB8IHZvaWQ+ID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIHJldHVybiAoLi4ucGFyYW1zOiB1bmtub3duW10pID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBsb2NrLnRoZW4oKCkgPT4gZiguLi5wYXJhbXMpKTtcbiAgICBsb2NrID0gcmVzdWx0LmNhdGNoKCgpID0+IHt9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDaGFpbnMgbXVsdGlwbGUgYWJvcnQgc2lnbmFscyB0byBhIGNvbnRyb2xsZXIuXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgbWVjaGFuaXNtIHdoZXJlIG11bHRpcGxlIGFib3J0IHNpZ25hbHMgY2FuIHRyaWdnZXIgYSBzaW5nbGUgYWJvcnQgY29udHJvbGxlci5cbiAqIFRoaXMgaXMgdXNlZnVsIGZvciBjb29yZGluYXRpbmcgY2FuY2VsbGF0aW9uIGFjcm9zcyBtdWx0aXBsZSBhc3luY2hyb25vdXMgb3BlcmF0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0Fib3J0Q29udHJvbGxlcn0gY29udHJvbGxlciAtIFRoZSBhYm9ydCBjb250cm9sbGVyIHRvIGJlIHRyaWdnZXJlZCBieSBzaWduYWxzLlxuICogQHBhcmFtIHsuLi5BYm9ydFNpZ25hbH0gc2lnbmFscyAtIE9uZSBvciBtb3JlIGFib3J0IHNpZ25hbHMgdGhhdCBjYW4gdHJpZ2dlciB0aGUgY29udHJvbGxlci5cbiAqIEByZXR1cm4ge0Fib3J0Q29udHJvbGxlcn0gVGhlIGlucHV0IGNvbnRyb2xsZXIsIG5vdyBjb25uZWN0ZWQgdG8gdGhlIHNpZ25hbHMuXG4gKlxuICogQGZ1bmN0aW9uIGNoYWluQWJvcnRDb250cm9sbGVyXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2hhaW5BYm9ydENvbnRyb2xsZXIoXG4gIGNvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlcixcbiAgLi4uc2lnbmFsczogQWJvcnRTaWduYWxbXVxuKTogQWJvcnRDb250cm9sbGVyO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IGNvbnRyb2xsZXIgY2hhaW5lZCB0byBtdWx0aXBsZSBhYm9ydCBzaWduYWxzLlxuICogQHN1bW1hcnkgQ3JlYXRlcyBhIG5ldyBhYm9ydCBjb250cm9sbGVyIHRoYXQgd2lsbCBiZSB0cmlnZ2VyZWQgaWYgYW55IG9mIHRoZSBwcm92aWRlZCBzaWduYWxzIGFyZSBhYm9ydGVkLlxuICpcbiAqIEBwYXJhbSB7Li4uQWJvcnRTaWduYWx9IHNpZ25hbHMgLSBPbmUgb3IgbW9yZSBhYm9ydCBzaWduYWxzIHRoYXQgY2FuIHRyaWdnZXIgdGhlIG5ldyBjb250cm9sbGVyLlxuICogQHJldHVybiB7QWJvcnRDb250cm9sbGVyfSBBIG5ldyBhYm9ydCBjb250cm9sbGVyIGNvbm5lY3RlZCB0byB0aGUgc2lnbmFscy5cbiAqXG4gKiBAZnVuY3Rpb24gY2hhaW5BYm9ydENvbnRyb2xsZXJcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFpbkFib3J0Q29udHJvbGxlcihcbiAgLi4uc2lnbmFsczogQWJvcnRTaWduYWxbXVxuKTogQWJvcnRDb250cm9sbGVyO1xuXG5leHBvcnQgZnVuY3Rpb24gY2hhaW5BYm9ydENvbnRyb2xsZXIoXG4gIGFyZ3VtZW50MDogQWJvcnRDb250cm9sbGVyIHwgQWJvcnRTaWduYWwsXG4gIC4uLnJlbWFpbmRlcjogQWJvcnRTaWduYWxbXVxuKTogQWJvcnRDb250cm9sbGVyIHtcbiAgbGV0IHNpZ25hbHM6IEFib3J0U2lnbmFsW107XG4gIGxldCBjb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXI7XG5cbiAgLy8gbm9ybWFsaXplIGFyZ3NcbiAgaWYgKGFyZ3VtZW50MCBpbnN0YW5jZW9mIEFib3J0U2lnbmFsKSB7XG4gICAgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICBzaWduYWxzID0gW2FyZ3VtZW50MCwgLi4ucmVtYWluZGVyXTtcbiAgfSBlbHNlIHtcbiAgICBjb250cm9sbGVyID0gYXJndW1lbnQwO1xuICAgIHNpZ25hbHMgPSByZW1haW5kZXI7XG4gIH1cblxuICAvLyBpZiB0aGUgY29udHJvbGxlciBpcyBhbHJlYWR5IGFib3J0ZWQsIGV4aXQgZWFybHlcbiAgaWYgKGNvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHtcbiAgICByZXR1cm4gY29udHJvbGxlcjtcbiAgfVxuXG4gIGNvbnN0IGhhbmRsZXIgPSAoKSA9PiBjb250cm9sbGVyLmFib3J0KCk7XG5cbiAgZm9yIChjb25zdCBzaWduYWwgb2Ygc2lnbmFscykge1xuICAgIC8vIGNoZWNrIGJlZm9yZSBhZGRpbmchIChhbmQgYXNzdW1lIHRoZXJlIGlzIG5vIHBvc3NpYmxlIHdheSB0aGF0IHRoZSBzaWduYWwgY291bGRcbiAgICAvLyBhYm9ydCBiZXR3ZWVuIHRoZSBgaWZgIGNoZWNrIGFuZCBhZGRpbmcgdGhlIGV2ZW50IGxpc3RlbmVyKVxuICAgIGlmIChzaWduYWwuYWJvcnRlZCkge1xuICAgICAgY29udHJvbGxlci5hYm9ydCgpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgaGFuZGxlciwge1xuICAgICAgb25jZTogdHJ1ZSxcbiAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gY29udHJvbGxlcjtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU3Bhd25zIGEgY29tbWFuZCBhcyBhIGNoaWxkIHByb2Nlc3Mgd2l0aCBvdXRwdXQgaGFuZGxpbmcuXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgY2hpbGQgcHJvY2VzcyB0byBleGVjdXRlIGEgY29tbWFuZCB3aXRoIHN1cHBvcnQgZm9yIHBpcGluZyBtdWx0aXBsZSBjb21tYW5kcyxcbiAqIGN1c3RvbSBvdXRwdXQgaGFuZGxpbmcsIGFuZCBhYm9ydCBjb250cm9sLiBUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgdGhlIGxvdy1sZXZlbCBkZXRhaWxzIG9mXG4gKiBzcGF3bmluZyBwcm9jZXNzZXMgYW5kIGNvbm5lY3RpbmcgdGhlaXIgaW5wdXRzL291dHB1dHMgd2hlbiBwaXBpbmcgaXMgdXNlZC5cbiAqXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSB0eXBlIG9mIHRoZSBwcm9jZXNzZWQgb3V0cHV0LCBkZWZhdWx0aW5nIHRvIHN0cmluZy5cbiAqIEBwYXJhbSB7U3RhbmRhcmRPdXRwdXRXcml0ZXI8Uj59IG91dHB1dCAtIFRoZSBvdXRwdXQgd3JpdGVyIHRvIGhhbmRsZSBjb21tYW5kIG91dHB1dC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb21tYW5kIC0gVGhlIGNvbW1hbmQgdG8gZXhlY3V0ZSwgY2FuIGluY2x1ZGUgcGlwZSBvcGVyYXRvcnMuXG4gKiBAcGFyYW0ge1NwYXduT3B0aW9uc1dpdGhvdXRTdGRpb30gb3B0cyAtIE9wdGlvbnMgZm9yIHRoZSBzcGF3bmVkIHByb2Nlc3MuXG4gKiBAcGFyYW0ge0Fib3J0Q29udHJvbGxlcn0gYWJvcnQgLSBDb250cm9sbGVyIHRvIGFib3J0IHRoZSBjb21tYW5kIGV4ZWN1dGlvbi5cbiAqIEBwYXJhbSB7TG9nZ2VyfSBsb2dnZXIgLSBMb2dnZXIgZm9yIHJlY29yZGluZyBjb21tYW5kIGV4ZWN1dGlvbiBkZXRhaWxzLlxuICogQHJldHVybiB7Q2hpbGRQcm9jZXNzV2l0aG91dE51bGxTdHJlYW1zfSBUaGUgc3Bhd25lZCBjaGlsZCBwcm9jZXNzLlxuICpcbiAqIEBmdW5jdGlvbiBzcGF3bkNvbW1hbmRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcGF3bkNvbW1hbmQ8UiA9IHN0cmluZz4oXG4gIG91dHB1dDogU3RhbmRhcmRPdXRwdXRXcml0ZXI8Uj4sXG4gIGNvbW1hbmQ6IHN0cmluZyxcbiAgb3B0czogU3Bhd25PcHRpb25zV2l0aG91dFN0ZGlvLFxuICBhYm9ydDogQWJvcnRDb250cm9sbGVyLFxuICBsb2dnZXI6IExvZ2dlclxuKTogQ2hpbGRQcm9jZXNzV2l0aG91dE51bGxTdHJlYW1zIHtcbiAgZnVuY3Rpb24gc3Bhd25Jbm5lcihjb21tYW5kOiBzdHJpbmcsIGNvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlcikge1xuICAgIGNvbnN0IFtjbWQsIGFyZ3pdID0gb3V0cHV0LnBhcnNlQ29tbWFuZChjb21tYW5kKTtcbiAgICBsb2dnZXIuaW5mbyhgUnVubmluZyBjb21tYW5kOiAke2NtZH1gKTtcbiAgICBsb2dnZXIuZGVidWcoYHdpdGggYXJnczogJHthcmd6LmpvaW4oXCIgXCIpfWApO1xuICAgIGNvbnN0IGNoaWxkUHJvY2VzcyA9IHNwYXduKGNtZCwgYXJneiwge1xuICAgICAgLi4ub3B0cyxcbiAgICAgIGN3ZDogb3B0cy5jd2QgfHwgcHJvY2Vzcy5jd2QoKSxcbiAgICAgIGVudjogT2JqZWN0LmFzc2lnbih7fSwgcHJvY2Vzcy5lbnYsIG9wdHMuZW52LCB7IFBBVEg6IHByb2Nlc3MuZW52LlBBVEggfSksXG4gICAgICBzaGVsbDogb3B0cy5zaGVsbCB8fCBmYWxzZSxcbiAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgfSk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoYHBpZCA6ICR7Y2hpbGRQcm9jZXNzLnBpZH1gKTtcbiAgICByZXR1cm4gY2hpbGRQcm9jZXNzO1xuICB9XG5cbiAgY29uc3QgbSA9IGNvbW1hbmQubWF0Y2goL1s8PiQjXS9nKTtcbiAgaWYgKG0pXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEludmFsaWQgY29tbWFuZDogJHtjb21tYW5kfS4gY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzOiAke219YFxuICAgICk7XG4gIGlmIChjb21tYW5kLmluY2x1ZGVzKFwiIHwgXCIpKSB7XG4gICAgY29uc3QgY21kcyA9IGNvbW1hbmQuc3BsaXQoXCIgfCBcIik7XG4gICAgY29uc3Qgc3Bhd25zID0gW107XG4gICAgY29uc3QgY29udHJvbGxlcnMgPSBuZXcgQXJyYXkoY21kcy5sZW5ndGgpO1xuICAgIGNvbnRyb2xsZXJzWzBdID0gYWJvcnQ7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjbWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSAhPT0gMClcbiAgICAgICAgY29udHJvbGxlcnNbaV0gPSBjaGFpbkFib3J0Q29udHJvbGxlcihjb250cm9sbGVyc1tpIC0gMV0uc2lnbmFsKTtcbiAgICAgIHNwYXducy5wdXNoKHNwYXduSW5uZXIoY21kc1tpXSwgY29udHJvbGxlcnNbaV0pKTtcbiAgICAgIGlmIChpID09PSAwKSBjb250aW51ZTtcbiAgICAgIHNwYXduc1tpIC0gMV0uc3Rkb3V0LnBpcGUoc3Bhd25zW2ldLnN0ZGluKTtcbiAgICB9XG4gICAgcmV0dXJuIHNwYXduc1tjbWRzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgcmV0dXJuIHNwYXduSW5uZXIoY29tbWFuZCwgYWJvcnQpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyBhIGNvbW1hbmQgYXN5bmNocm9ub3VzbHkgd2l0aCBjdXN0b21pemFibGUgb3V0cHV0IGhhbmRsaW5nLlxuICogQHN1bW1hcnkgVGhpcyBmdW5jdGlvbiBydW5zIGEgc2hlbGwgY29tbWFuZCBhcyBhIGNoaWxkIHByb2Nlc3MsIHByb3ZpZGluZyBmaW5lLWdyYWluZWRcbiAqIGNvbnRyb2wgb3ZlciBpdHMgZXhlY3V0aW9uIGFuZCBvdXRwdXQgaGFuZGxpbmcuIEl0IHN1cHBvcnRzIGN1c3RvbSBvdXRwdXQgd3JpdGVycyxcbiAqIGFsbG93cyBmb3IgY29tbWFuZCBhYm9ydGlvbiwgYW5kIGNhcHR1cmVzIGJvdGggc3Rkb3V0IGFuZCBzdGRlcnIuXG4gKlxuICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgcmVzb2x2ZWQgdmFsdWUgZnJvbSB0aGUgY29tbWFuZCBleGVjdXRpb24uXG4gKlxuICogQHBhcmFtIGNvbW1hbmQgLSBUaGUgY29tbWFuZCB0byBydW4sIGVpdGhlciBhcyBhIHN0cmluZyBvciBhbiBhcnJheSBvZiBzdHJpbmdzLlxuICogQHBhcmFtIG9wdHMgLSBTcGF3biBvcHRpb25zIGZvciB0aGUgY2hpbGQgcHJvY2Vzcy4gRGVmYXVsdHMgdG8gYW4gZW1wdHkgb2JqZWN0LlxuICogQHBhcmFtIG91dHB1dENvbnN0cnVjdG9yIC0gQ29uc3RydWN0b3IgZm9yIHRoZSBvdXRwdXQgd3JpdGVyLiBEZWZhdWx0cyB0byBTdGFuZGFyZE91dHB1dFdyaXRlci5cbiAqIEBwYXJhbSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgb3V0cHV0IGNvbnN0cnVjdG9yLlxuICogQHJldHVybiB7Q29tbWFuZFJlc3VsdH0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGNvbW1hbmQgcmVzdWx0IG9mIHR5cGUgUi5cbiAqXG4gKiBAZnVuY3Rpb24gcnVuQ29tbWFuZFxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHJ1bkNvbW1hbmRcbiAqICAgcGFydGljaXBhbnQgT3V0cHV0V3JpdGVyXG4gKiAgIHBhcnRpY2lwYW50IENoaWxkUHJvY2Vzc1xuICogICBDYWxsZXItPj5ydW5Db21tYW5kOiBDYWxsIHdpdGggY29tbWFuZCBhbmQgb3B0aW9uc1xuICogICBydW5Db21tYW5kLT4+T3V0cHV0V3JpdGVyOiBDcmVhdGUgbmV3IGluc3RhbmNlXG4gKiAgIHJ1bkNvbW1hbmQtPj5PdXRwdXRXcml0ZXI6IFBhcnNlIGNvbW1hbmRcbiAqICAgcnVuQ29tbWFuZC0+PkNoaWxkUHJvY2VzczogU3Bhd24gcHJvY2Vzc1xuICogICBDaGlsZFByb2Nlc3MtLT4+cnVuQ29tbWFuZDogUmV0dXJuIHByb2Nlc3Mgb2JqZWN0XG4gKiAgIHJ1bkNvbW1hbmQtPj5DaGlsZFByb2Nlc3M6IFNldCB1cCBldmVudCBsaXN0ZW5lcnNcbiAqICAgbG9vcCBGb3IgZWFjaCBzdGRvdXQgZGF0YVxuICogICAgIENoaWxkUHJvY2Vzcy0+PnJ1bkNvbW1hbmQ6IEVtaXQgc3Rkb3V0IGRhdGFcbiAqICAgICBydW5Db21tYW5kLT4+T3V0cHV0V3JpdGVyOiBIYW5kbGUgc3Rkb3V0IGRhdGFcbiAqICAgZW5kXG4gKiAgIGxvb3AgRm9yIGVhY2ggc3RkZXJyIGRhdGFcbiAqICAgICBDaGlsZFByb2Nlc3MtPj5ydW5Db21tYW5kOiBFbWl0IHN0ZGVyciBkYXRhXG4gKiAgICAgcnVuQ29tbWFuZC0+Pk91dHB1dFdyaXRlcjogSGFuZGxlIHN0ZGVyciBkYXRhXG4gKiAgIGVuZFxuICogICBDaGlsZFByb2Nlc3MtPj5ydW5Db21tYW5kOiBFbWl0IGVycm9yIChpZiBhbnkpXG4gKiAgIHJ1bkNvbW1hbmQtPj5PdXRwdXRXcml0ZXI6IEhhbmRsZSBlcnJvclxuICogICBDaGlsZFByb2Nlc3MtPj5ydW5Db21tYW5kOiBFbWl0IGV4aXRcbiAqICAgcnVuQ29tbWFuZC0+Pk91dHB1dFdyaXRlcjogSGFuZGxlIGV4aXRcbiAqICAgT3V0cHV0V3JpdGVyLS0+PnJ1bkNvbW1hbmQ6IFJlc29sdmUgb3IgcmVqZWN0IHByb21pc2VcbiAqICAgcnVuQ29tbWFuZC0tPj5DYWxsZXI6IFJldHVybiBDb21tYW5kUmVzdWx0XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuQ29tbWFuZDxSID0gc3RyaW5nPihcbiAgY29tbWFuZDogc3RyaW5nLFxuICBvcHRzOiBTcGF3bk9wdGlvbnNXaXRob3V0U3RkaW8gPSB7fSxcbiAgb3V0cHV0Q29uc3RydWN0b3I6IE91dHB1dFdyaXRlckNvbnN0cnVjdG9yPFxuICAgIFIsXG4gICAgU3RhbmRhcmRPdXRwdXRXcml0ZXI8Uj4sXG4gICAgRXJyb3JcbiAgPiA9IFN0YW5kYXJkT3V0cHV0V3JpdGVyPFI+LFxuICAuLi5hcmdzOiB1bmtub3duW11cbik6IENvbW1hbmRSZXN1bHQ8Uj4ge1xuICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcihydW5Db21tYW5kKTtcbiAgY29uc3QgYWJvcnQgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgY29uc3QgcmVzdWx0OiBPbWl0PENvbW1hbmRSZXN1bHQsIFwicHJvbWlzZVwiIHwgXCJwaXBlXCI+ID0ge1xuICAgIGFib3J0OiBhYm9ydCxcbiAgICBjb21tYW5kOiBjb21tYW5kLFxuICAgIGxvZ3M6IFtdLFxuICAgIGVycnM6IFtdLFxuICB9O1xuXG4gIGNvbnN0IGxvY2sgPSBuZXcgUHJvbWlzZTxSPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgbGV0IG91dHB1dDtcbiAgICB0cnkge1xuICAgICAgb3V0cHV0ID0gbmV3IG91dHB1dENvbnN0cnVjdG9yKFxuICAgICAgICBjb21tYW5kLFxuICAgICAgICB7XG4gICAgICAgICAgcmVzb2x2ZSxcbiAgICAgICAgICByZWplY3QsXG4gICAgICAgIH0sXG4gICAgICAgIC4uLmFyZ3NcbiAgICAgICk7XG5cbiAgICAgIHJlc3VsdC5jbWQgPSBzcGF3bkNvbW1hbmQ8Uj4ob3V0cHV0LCBjb21tYW5kLCBvcHRzLCBhYm9ydCwgbG9nZ2VyKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcihgRXJyb3IgcnVubmluZyBjb21tYW5kICR7Y29tbWFuZH06ICR7ZX1gKSk7XG4gICAgfVxuXG4gICAgcmVzdWx0LmNtZC5zdGRvdXQuc2V0RW5jb2RpbmcoXCJ1dGY4XCIpO1xuXG4gICAgcmVzdWx0LmNtZC5zdGRvdXQub24oXCJkYXRhXCIsIChjaHVuazogYW55KSA9PiB7XG4gICAgICBjaHVuayA9IGNodW5rLnRvU3RyaW5nKCk7XG4gICAgICByZXN1bHQubG9ncy5wdXNoKGNodW5rKTtcbiAgICAgIG91dHB1dC5kYXRhKGNodW5rKTtcbiAgICB9KTtcblxuICAgIHJlc3VsdC5jbWQuc3RkZXJyLm9uKFwiZGF0YVwiLCAoZGF0YTogYW55KSA9PiB7XG4gICAgICBkYXRhID0gZGF0YS50b1N0cmluZygpO1xuICAgICAgcmVzdWx0LmVycnMucHVzaChkYXRhKTtcbiAgICAgIG91dHB1dC5lcnJvcihkYXRhKTtcbiAgICB9KTtcblxuICAgIHJlc3VsdC5jbWQub25jZShcImVycm9yXCIsIChlcnI6IEVycm9yKSA9PiB7XG4gICAgICBvdXRwdXQuZXhpdChlcnIubWVzc2FnZSwgcmVzdWx0LmVycnMpO1xuICAgIH0pO1xuXG4gICAgcmVzdWx0LmNtZC5vbmNlKFwiZXhpdFwiLCAoY29kZTogbnVtYmVyID0gMCkgPT4ge1xuICAgICAgaWYgKGFib3J0LnNpZ25hbC5hYm9ydGVkICYmIGNvZGUgPT09IG51bGwpIGNvZGUgPSBBYm9ydENvZGUgYXMgYW55O1xuICAgICAgb3V0cHV0LmV4aXQoY29kZSwgY29kZSA9PT0gMCA/IHJlc3VsdC5sb2dzIDogcmVzdWx0LmVycnMpO1xuICAgIH0pO1xuICB9KTtcblxuICBPYmplY3QuYXNzaWduKHJlc3VsdCwge1xuICAgIHByb21pc2U6IGxvY2ssXG4gICAgcGlwZTogYXN5bmMgPEU+KGNiOiAocjogUikgPT4gRSkgPT4ge1xuICAgICAgY29uc3QgbCA9IGxvZ2dlci5mb3IoXCJwaXBlXCIpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgbC52ZXJib3NlKGBFeGVjdXRpbmcgcGlwZSBmdW5jdGlvbiAke2NvbW1hbmR9Li4uYCk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogUiA9IGF3YWl0IGxvY2s7XG4gICAgICAgIGwudmVyYm9zZShgUGlwaW5nIG91dHB1dCB0byAke2NiLm5hbWV9OiAke3Jlc3VsdH1gKTtcbiAgICAgICAgcmV0dXJuIGNiKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGwuZXJyb3IoYEVycm9yIHBpcGluZyBjb21tYW5kIG91dHB1dDogJHtlfWApO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQgYXMgQ29tbWFuZFJlc3VsdDxSPjtcbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBydW5Db21tYW5kIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IERlcGVuZGVuY3lNYXAsIFNpbXBsZURlcGVuZGVuY3lNYXAgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgZXNjYXBlUmVnRXhwLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgemxpYiBmcm9tIFwiemxpYlwiO1xuXG5jb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcihcImZzXCIpO1xuXG5mdW5jdGlvbiBwYXRjaFN0cmluZyhcbiAgaW5wdXQ6IHN0cmluZyxcbiAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+LFxuICBmbGFnczogc3RyaW5nID0gXCJnXCIsXG4gIGZpbHRlcj86IChzdHI6IHN0cmluZykgPT4gYm9vbGVhblxuKTogc3RyaW5nIHtcbiAgT2JqZWN0LmVudHJpZXModmFsdWVzKS5mb3JFYWNoKChba2V5LCB2YWxdKSA9PiB7XG4gICAgY29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAoa2V5KSwgZmxhZ3MpO1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShyZWdleHAsIChzdWJTdHI6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKCFmaWx0ZXIgfHwgZmlsdGVyKHN1YlN0cikpIHtcbiAgICAgICAgcmV0dXJuIHZhbCBhcyBzdHJpbmc7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsIGFzIHN0cmluZztcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBpbnB1dDtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUGF0Y2hlcyBhIGZpbGUgd2l0aCBnaXZlbiB2YWx1ZXMuXG4gKiBAc3VtbWFyeSBSZWFkcyBhIGZpbGUsIGFwcGxpZXMgcGF0Y2hlcyB1c2luZyBUZXh0VXRpbHMsIGFuZCB3cml0ZXMgdGhlIHJlc3VsdCBiYWNrIHRvIHRoZSBmaWxlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGZpbGUgdG8gYmUgcGF0Y2hlZC5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPn0gdmFsdWVzIC0gVGhlIHZhbHVlcyB0byBwYXRjaCBpbnRvIHRoZSBmaWxlLlxuICogQHJldHVybiB7dm9pZH1cbiAqXG4gKiBAZnVuY3Rpb24gcGF0Y2hGaWxlXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcGF0Y2hGaWxlXG4gKiAgIHBhcnRpY2lwYW50IGZzXG4gKiAgIHBhcnRpY2lwYW50IHJlYWRGaWxlXG4gKiAgIHBhcnRpY2lwYW50IFRleHRVdGlsc1xuICogICBwYXJ0aWNpcGFudCB3cml0ZUZpbGVcbiAqICAgQ2FsbGVyLT4+cGF0Y2hGaWxlOiBDYWxsIHdpdGggcGF0aCBhbmQgdmFsdWVzXG4gKiAgIHBhdGNoRmlsZS0+PmZzOiBDaGVjayBpZiBmaWxlIGV4aXN0c1xuICogICBwYXRjaEZpbGUtPj5yZWFkRmlsZTogUmVhZCBmaWxlIGNvbnRlbnRcbiAqICAgcmVhZEZpbGUtPj5mczogUmVhZCBmaWxlXG4gKiAgIGZzLS0+PnJlYWRGaWxlOiBSZXR1cm4gZmlsZSBjb250ZW50XG4gKiAgIHJlYWRGaWxlLS0+PnBhdGNoRmlsZTogUmV0dXJuIGZpbGUgY29udGVudFxuICogICBwYXRjaEZpbGUtPj5UZXh0VXRpbHM6IFBhdGNoIHN0cmluZ1xuICogICBUZXh0VXRpbHMtLT4+cGF0Y2hGaWxlOiBSZXR1cm4gcGF0Y2hlZCBjb250ZW50XG4gKiAgIHBhdGNoRmlsZS0+PndyaXRlRmlsZTogV3JpdGUgcGF0Y2hlZCBjb250ZW50XG4gKiAgIHdyaXRlRmlsZS0+PmZzOiBXcml0ZSB0byBmaWxlXG4gKiAgIGZzLS0+PndyaXRlRmlsZTogRmlsZSB3cml0dGVuXG4gKiAgIHdyaXRlRmlsZS0tPj5wYXRjaEZpbGU6IEZpbGUgd3JpdHRlblxuICogICBwYXRjaEZpbGUtLT4+Q2FsbGVyOiBQYXRjaGluZyBjb21wbGV0ZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGNoRmlsZShcbiAgcGF0aDogc3RyaW5nLFxuICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4sXG4gIGZpbHRlcj86IChzdHI6IHN0cmluZykgPT4gYm9vbGVhblxuKSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IocGF0Y2hGaWxlKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHBhdGgpKVxuICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBub3QgZm91bmQgYXQgcGF0aCBcIiR7cGF0aH1cIi5gKTtcbiAgbGV0IGNvbnRlbnQgPSByZWFkRmlsZShwYXRoKTtcblxuICBsb2cudmVyYm9zZShgUGF0Y2hpbmcgZmlsZSBcIiR7cGF0aH1cIi4uLmApO1xuICBsb2cuZGVidWcoYHdpdGggdmFsdWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWVzKX1gKTtcbiAgdHJ5IHtcbiAgICBjb250ZW50ID0gcGF0Y2hTdHJpbmcoY29udGVudCwgdmFsdWVzLCBcImdcIiwgZmlsdGVyKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHBhdGNoaW5nIGZpbGU6ICR7ZXJyb3J9YCk7XG4gIH1cbiAgd3JpdGVGaWxlKHBhdGgsIGNvbnRlbnQpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIGZpbGUgYW5kIHJldHVybnMgaXRzIGNvbnRlbnQuXG4gKiBAc3VtbWFyeSBSZWFkcyB0aGUgY29udGVudCBvZiBhIGZpbGUgYXQgdGhlIHNwZWNpZmllZCBwYXRoIGFuZCByZXR1cm5zIGl0IGFzIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGZpbGUgdG8gYmUgcmVhZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNvbnRlbnQgb2YgdGhlIGZpbGUuXG4gKlxuICogQGZ1bmN0aW9uIHJlYWRGaWxlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZpbGUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihyZWFkRmlsZSk7XG4gIHRyeSB7XG4gICAgbG9nLnZlcmJvc2UoYFJlYWRpbmcgZmlsZSBcIiR7cGF0aH1cIi4uLmApO1xuICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMocGF0aCwgXCJ1dGY4XCIpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBFcnJvciByZWFkaW5nIGZpbGUgXCIke3BhdGh9XCI6ICR7ZXJyb3J9YCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciByZWFkaW5nIGZpbGUgXCIke3BhdGh9XCI6ICR7ZXJyb3J9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gV3JpdGVzIGRhdGEgdG8gYSBmaWxlLlxuICogQHN1bW1hcnkgV3JpdGVzIHRoZSBwcm92aWRlZCBkYXRhIHRvIGEgZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGguXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcGF0aCB0byB0aGUgZmlsZSB0byBiZSB3cml0dGVuLlxuICogQHBhcmFtIHtzdHJpbmcgfCBCdWZmZXJ9IGRhdGEgLSBUaGUgZGF0YSB0byBiZSB3cml0dGVuIHRvIHRoZSBmaWxlLlxuICogQHJldHVybiB7dm9pZH1cbiAqXG4gKiBAZnVuY3Rpb24gd3JpdGVGaWxlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVGaWxlKHBhdGg6IHN0cmluZywgZGF0YTogc3RyaW5nIHwgQnVmZmVyKTogdm9pZCB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3Iod3JpdGVGaWxlKTtcbiAgdHJ5IHtcbiAgICBsb2cudmVyYm9zZShgV3JpdGluZyBmaWxlIFwiJHtwYXRofSB3aXRoICR7ZGF0YS5sZW5ndGh9IGJ5dGVzLi4uYCk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLCBkYXRhLCBcInV0ZjhcIik7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nLnZlcmJvc2UoYEVycm9yIHdyaXRpbmcgZmlsZSBcIiR7cGF0aH1cIjogJHtlcnJvcn1gKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdyaXRpbmcgZmlsZSBcIiR7cGF0aH1cIjogJHtlcnJvcn1gKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYWxsIGZpbGVzIHJlY3Vyc2l2ZWx5IGZyb20gYSBkaXJlY3RvcnkuXG4gKiBAc3VtbWFyeSBUcmF2ZXJzZXMgdGhyb3VnaCBkaXJlY3RvcmllcyBhbmQgc3ViZGlyZWN0b3JpZXMgdG8gY29sbGVjdCBhbGwgZmlsZSBwYXRocy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcCAtIFRoZSBwYXRoIHRvIHN0YXJ0IHNlYXJjaGluZyBmcm9tLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gW2ZpbHRlcl0gLSBPcHRpb25hbCBmdW5jdGlvbiB0byBmaWx0ZXIgZmlsZXMgYnkgbmFtZSBvciBpbmRleC5cbiAqIEByZXR1cm4ge3N0cmluZ1tdfSBBcnJheSBvZiBmaWxlIHBhdGhzLlxuICpcbiAqIEBmdW5jdGlvbiBnZXRBbGxGaWxlc1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFsbEZpbGVzKFxuICBwOiBzdHJpbmcsXG4gIGZpbHRlcj86IChmOiBzdHJpbmcsIGk/OiBudW1iZXIpID0+IGJvb2xlYW5cbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihnZXRBbGxGaWxlcyk7XG4gIGNvbnN0IGZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHRyeSB7XG4gICAgbG9nLnZlcmJvc2UoYFJldHJpZXZpbmcgYWxsIGZpbGVzIGZyb20gXCIke3B9XCIuLi5gKTtcbiAgICBjb25zdCBlbnRyaWVzID0gZnMucmVhZGRpclN5bmMocCk7XG5cbiAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihwLCBlbnRyeSk7XG4gICAgICBjb25zdCBzdGF0ID0gZnMuc3RhdFN5bmMoZnVsbFBhdGgpO1xuXG4gICAgICBpZiAoc3RhdC5pc0ZpbGUoKSkge1xuICAgICAgICBmaWxlcy5wdXNoKGZ1bGxQYXRoKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGZpbGVzLnB1c2goLi4uZ2V0QWxsRmlsZXMoZnVsbFBhdGgpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoIWZpbHRlcikgcmV0dXJuIGZpbGVzO1xuICAgIHJldHVybiBmaWxlcy5maWx0ZXIoZmlsdGVyKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2cudmVyYm9zZShgRXJyb3IgcmV0cmlldmluZyBmaWxlcyBmcm9tIFwiJHtwfVwiOiAke2Vycm9yfWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgcmV0cmlldmluZyBmaWxlcyBmcm9tIFwiJHtwfVwiOiAke2Vycm9yfWApO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlbmFtZXMgYSBmaWxlIG9yIGRpcmVjdG9yeS5cbiAqIEBzdW1tYXJ5IE1vdmVzIGEgZmlsZSBvciBkaXJlY3RvcnkgZnJvbSB0aGUgc291cmNlIHBhdGggdG8gdGhlIGRlc3RpbmF0aW9uIHBhdGguXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIFRoZSBzb3VyY2UgcGF0aCBvZiB0aGUgZmlsZSBvciBkaXJlY3RvcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzdCAtIFRoZSBkZXN0aW5hdGlvbiBwYXRoIGZvciB0aGUgZmlsZSBvciBkaXJlY3RvcnkuXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSByZW5hbWUgb3BlcmF0aW9uIGlzIGNvbXBsZXRlLlxuICpcbiAqIEBmdW5jdGlvbiByZW5hbWVGaWxlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVuYW1lRmlsZShzb3VyY2U6IHN0cmluZywgZGVzdDogc3RyaW5nKSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IocmVuYW1lRmlsZSk7XG4gIGxldCBkZXNjcmlwdG9yU291cmNlLCBkZXNjcmlwdG9yRGVzdDtcblxuICB0cnkge1xuICAgIGRlc2NyaXB0b3JTb3VyY2UgPSBmcy5zdGF0U3luYyhzb3VyY2UpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBTb3VyY2UgcGF0aCBcIiR7c291cmNlfVwiIGRvZXMgbm90IGV4aXN0OiAke2Vycm9yfWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgU291cmNlIHBhdGggXCIke3NvdXJjZX1cIiBkb2VzIG5vdCBleGlzdDogJHtlcnJvcn1gKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgZGVzY3JpcHRvckRlc3QgPSBmcy5zdGF0U3luYyhkZXN0KTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAvLyBkbyBub3RoaW5nLiBpdHMgb2tcbiAgfVxuICBpZiAoZGVzY3JpcHRvckRlc3QpIHtcbiAgICBsb2cudmVyYm9zZShgRGVzdGluYXRpb24gcGF0aCBcIiR7ZGVzdH1cIiBhbHJlYWR5IGV4aXN0c2ApO1xuICAgIHRocm93IG5ldyBFcnJvcihgRGVzdGluYXRpb24gcGF0aCBcIiR7ZGVzdH1cIiBhbHJlYWR5IGV4aXN0c2ApO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBSZW5hbWluZyAke2Rlc2NyaXB0b3JTb3VyY2UuaXNGaWxlKCkgPyBcImZpbGVcIiA6IFwiZGlyZWN0b3J5XCJ9IFwiJHtzb3VyY2V9XCIgdG8gXCIke2Rlc3R9Li4uYFxuICAgICk7XG4gICAgZnMucmVuYW1lU3luYyhzb3VyY2UsIGRlc3QpO1xuICAgIGxvZy52ZXJib3NlKGBTdWNjZXNzZnVsbHkgcmVuYW1lZCB0byBcIiR7ZGVzdH1cImApO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKFxuICAgICAgYEVycm9yIHJlbmFtaW5nICR7ZGVzY3JpcHRvclNvdXJjZS5pc0ZpbGUoKSA/IFwiZmlsZVwiIDogXCJkaXJlY3RvcnlcIn0gXCIke3NvdXJjZX1cIiB0byBcIiR7ZGVzdH1cIjogJHtlcnJvcn1gXG4gICAgKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRXJyb3IgcmVuYW1pbmcgJHtkZXNjcmlwdG9yU291cmNlLmlzRmlsZSgpID8gXCJmaWxlXCIgOiBcImRpcmVjdG9yeVwifSBcIiR7c291cmNlfVwiIHRvIFwiJHtkZXN0fVwiOiAke2Vycm9yfWBcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvcGllcyBhIGZpbGUgb3IgZGlyZWN0b3J5LlxuICogQHN1bW1hcnkgQ3JlYXRlcyBhIGNvcHkgb2YgYSBmaWxlIG9yIGRpcmVjdG9yeSBmcm9tIHRoZSBzb3VyY2UgcGF0aCB0byB0aGUgZGVzdGluYXRpb24gcGF0aC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gVGhlIHNvdXJjZSBwYXRoIG9mIHRoZSBmaWxlIG9yIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXN0IC0gVGhlIGRlc3RpbmF0aW9uIHBhdGggZm9yIHRoZSBmaWxlIG9yIGRpcmVjdG9yeS5cbiAqIEByZXR1cm4ge3ZvaWR9XG4gKlxuICogQGZ1bmN0aW9uIGNvcHlGaWxlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29weUZpbGUoc291cmNlOiBzdHJpbmcsIGRlc3Q6IHN0cmluZykge1xuICBjb25zdCBsb2cgPSBsb2dnZXIuZm9yKGNvcHlGaWxlKTtcbiAgbGV0IGRlc2NyaXB0b3JTb3VyY2UsIGRlc2NyaXB0b3JEZXN0O1xuICB0cnkge1xuICAgIGRlc2NyaXB0b3JTb3VyY2UgPSBmcy5zdGF0U3luYyhzb3VyY2UpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBTb3VyY2UgcGF0aCBcIiR7c291cmNlfVwiIGRvZXMgbm90IGV4aXN0OiAke2Vycm9yfWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgU291cmNlIHBhdGggXCIke3NvdXJjZX1cIiBkb2VzIG5vdCBleGlzdDogJHtlcnJvcn1gKTtcbiAgfVxuICB0cnkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBkZXNjcmlwdG9yRGVzdCA9IGZzLnN0YXRTeW5jKGRlc3QpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBpZiAoZGVzY3JpcHRvclNvdXJjZS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBsb2cudmVyYm9zZShgRGVzdCBwYXRoIFwiJHtkZXN0fVwiIGRvZXMgbm90IGV4aXN0LiBjcmVhdGluZ2ApO1xuICAgICAgZnMubWtkaXJTeW5jKGRlc3QsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHRyeSB7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgQ29weWluZyAke2Rlc2NyaXB0b3JTb3VyY2UuaXNGaWxlKCkgPyBcImZpbGVcIiA6IFwiZGlyZWN0b3J5XCJ9IFwiJHtzb3VyY2V9XCIgdG8gXCIke2Rlc3R9Li4uYFxuICAgICk7XG4gICAgZnMuY3BTeW5jKHNvdXJjZSwgZGVzdCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nLnZlcmJvc2UoXG4gICAgICBgRXJyb3IgY29weWluZyAke2Rlc2NyaXB0b3JTb3VyY2UuaXNGaWxlKCkgPyBcImZpbGVcIiA6IFwiZGlyZWN0b3J5XCJ9IFwiJHtzb3VyY2V9XCIgdG8gXCIke2Rlc3R9OiAke2Vycm9yfWBcbiAgICApO1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBFcnJvciBjb3B5aW5nICR7ZGVzY3JpcHRvclNvdXJjZS5pc0ZpbGUoKSA/IFwiZmlsZVwiIDogXCJkaXJlY3RvcnlcIn0gXCIke3NvdXJjZX1cIiB0byBcIiR7ZGVzdH06ICR7ZXJyb3J9YFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBhIGZpbGUgb3IgZGlyZWN0b3J5LlxuICogQHN1bW1hcnkgUmVtb3ZlcyBhIGZpbGUgb3IgZGlyZWN0b3J5IGF0IHRoZSBzcGVjaWZpZWQgcGF0aCwgd2l0aCByZWN1cnNpdmUgYW5kIGZvcmNlIG9wdGlvbnMgZW5hYmxlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcCAtIFRoZSBwYXRoIHRvIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSB0byBkZWxldGUuXG4gKiBAcmV0dXJuIHt2b2lkfVxuICpcbiAqIEBmdW5jdGlvbiBkZWxldGVQYXRoXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlUGF0aChwOiBzdHJpbmcpIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihkZWxldGVQYXRoKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBkZXNjcmlwdG9yID0gZnMuc3RhdFN5bmMocCk7XG4gICAgaWYgKGRlc2NyaXB0b3IuaXNGaWxlKCkpIHtcbiAgICAgIGxvZy52ZXJib3NlKGBEZWxldGluZyBmaWxlIFwiJHtwfS4uLmApO1xuICAgICAgZnMucm1TeW5jKHAsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3IuaXNEaXJlY3RvcnkoKSlcbiAgICAgIGZzLnJtU3luYyhwLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nLnZlcmJvc2UoYEVycm9yIERlbGV0aW5nIFwiJHtwfVwiOiAke2Vycm9yfWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgRGVsZXRpbmcgXCIke3B9XCI6ICR7ZXJyb3J9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHBhY2thZ2UgaW5mb3JtYXRpb24gZnJvbSBwYWNrYWdlLmpzb24uXG4gKiBAc3VtbWFyeSBMb2FkcyBhbmQgcGFyc2VzIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBmcm9tIGEgc3BlY2lmaWVkIGRpcmVjdG9yeSBvciB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4gQ2FuIHJldHVybiB0aGUgZW50aXJlIHBhY2thZ2Ugb2JqZWN0IG9yIGEgc3BlY2lmaWMgcHJvcGVydHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3A9cHJvY2Vzcy5jd2QoKV0gLSBUaGUgZGlyZWN0b3J5IHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3Byb3BlcnR5XSAtIE9wdGlvbmFsLiBUaGUgc3BlY2lmaWMgcHJvcGVydHkgdG8gcmV0cmlldmUgZnJvbSBwYWNrYWdlLmpzb24uXG4gKiBAcmV0dXJuIHtvYmplY3QgfCBzdHJpbmd9IFRoZSBwYXJzZWQgY29udGVudHMgb2YgcGFja2FnZS5qc29uIG9yIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5LlxuICogQGZ1bmN0aW9uIGdldFBhY2thZ2VcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IGdldFBhY2thZ2VcbiAqICAgcGFydGljaXBhbnQgcmVhZEZpbGVcbiAqICAgcGFydGljaXBhbnQgSlNPTlxuICogICBDYWxsZXItPj5nZXRQYWNrYWdlOiBDYWxsIHdpdGggcGF0aCBhbmQgb3B0aW9uYWwgcHJvcGVydHlcbiAqICAgZ2V0UGFja2FnZS0+PnJlYWRGaWxlOiBSZWFkIHBhY2thZ2UuanNvblxuICogICByZWFkRmlsZS0tPj5nZXRQYWNrYWdlOiBSZXR1cm4gZmlsZSBjb250ZW50XG4gKiAgIGdldFBhY2thZ2UtPj5KU09OOiBQYXJzZSBmaWxlIGNvbnRlbnRcbiAqICAgSlNPTi0tPj5nZXRQYWNrYWdlOiBSZXR1cm4gcGFyc2VkIG9iamVjdFxuICogICBhbHQgcHJvcGVydHkgc3BlY2lmaWVkXG4gKiAgICAgZ2V0UGFja2FnZS0+PmdldFBhY2thZ2U6IENoZWNrIGlmIHByb3BlcnR5IGV4aXN0c1xuICogICAgIGFsdCBwcm9wZXJ0eSBleGlzdHNcbiAqICAgICAgIGdldFBhY2thZ2UtLT4+Q2FsbGVyOiBSZXR1cm4gcHJvcGVydHkgdmFsdWVcbiAqICAgICBlbHNlIHByb3BlcnR5IGRvZXNuJ3QgZXhpc3RcbiAqICAgICAgIGdldFBhY2thZ2UtLT4+Q2FsbGVyOiBUaHJvdyBFcnJvclxuICogICAgIGVuZFxuICogICBlbHNlIG5vIHByb3BlcnR5IHNwZWNpZmllZFxuICogICAgIGdldFBhY2thZ2UtLT4+Q2FsbGVyOiBSZXR1cm4gZW50aXJlIHBhY2thZ2Ugb2JqZWN0XG4gKiAgIGVuZFxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFja2FnZShcbiAgcDogc3RyaW5nID0gcHJvY2Vzcy5jd2QoKSxcbiAgcHJvcGVydHk/OiBzdHJpbmdcbik6IG9iamVjdCB8IHN0cmluZyB7XG4gIGxldCBwa2c6IGFueTtcbiAgdHJ5IHtcbiAgICBwa2cgPSBKU09OLnBhcnNlKHJlYWRGaWxlKHBhdGguam9pbihwLCBgcGFja2FnZS5qc29uYCkpKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byByZXRyaWV2ZSBwYWNrYWdlIGluZm9ybWF0aW9uXCIgJHtlcnJvcn1gKTtcbiAgfVxuXG4gIGlmIChwcm9wZXJ0eSkge1xuICAgIGlmICghKHByb3BlcnR5IGluIHBrZykpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb3BlcnR5IFwiJHtwcm9wZXJ0eX1cIiBub3QgZm91bmQgaW4gcGFja2FnZS5qc29uYCk7XG4gICAgcmV0dXJuIHBrZ1twcm9wZXJ0eV0gYXMgc3RyaW5nO1xuICB9XG4gIHJldHVybiBwa2c7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNldHMgYW4gYXR0cmlidXRlIGluIHRoZSBwYWNrYWdlLmpzb24gZmlsZS5cbiAqIEBzdW1tYXJ5IFVwZGF0ZXMgYSBzcGVjaWZpYyBhdHRyaWJ1dGUgaW4gdGhlIHBhY2thZ2UuanNvbiBmaWxlIHdpdGggdGhlIHByb3ZpZGVkIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIHRvIHNldCBpbiBwYWNrYWdlLmpzb24uXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlciB8IG9iamVjdH0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2V0IGZvciB0aGUgYXR0cmlidXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwPXByb2Nlc3MuY3dkKCldIC0gVGhlIGRpcmVjdG9yeSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkLlxuICogQHJldHVybiB7dm9pZH1cbiAqXG4gKiBAZnVuY3Rpb24gc2V0UGFja2FnZUF0dHJpYnV0ZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFBhY2thZ2VBdHRyaWJ1dGUoXG4gIGF0dHI6IHN0cmluZyxcbiAgdmFsdWU6IHN0cmluZyxcbiAgcDogc3RyaW5nID0gcHJvY2Vzcy5jd2QoKVxuKTogdm9pZCB7XG4gIGNvbnN0IHBrZyA9IGdldFBhY2thZ2UocCkgYXMgUmVjb3JkPHN0cmluZywgYW55PjtcbiAgcGtnW2F0dHJdID0gdmFsdWU7XG4gIHdyaXRlRmlsZShwYXRoLmpvaW4ocCwgYHBhY2thZ2UuanNvbmApLCBKU09OLnN0cmluZ2lmeShwa2csIG51bGwsIDIpKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uLlxuICogQHN1bW1hcnkgQSBjb252ZW5pZW5jZSBmdW5jdGlvbiB0aGF0IGNhbGxzIGdldFBhY2thZ2UgdG8gcmV0cmlldmUgdGhlIFwidmVyc2lvblwiIHByb3BlcnR5IGZyb20gcGFja2FnZS5qc29uLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwPXByb2Nlc3MuY3dkKCldIC0gVGhlIGRpcmVjdG9yeSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgdmVyc2lvbiBzdHJpbmcgZnJvbSBwYWNrYWdlLmpzb24uXG4gKiBAZnVuY3Rpb24gZ2V0UGFja2FnZVZlcnNpb25cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhY2thZ2VWZXJzaW9uKHAgPSBwcm9jZXNzLmN3ZCgpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldFBhY2thZ2UocCwgXCJ2ZXJzaW9uXCIpIGFzIHN0cmluZztcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFsbCBkZXBlbmRlbmNpZXMgZnJvbSB0aGUgcHJvamVjdC5cbiAqIEBzdW1tYXJ5IEV4ZWN1dGVzICducG0gbHMgLS1qc29uJyBjb21tYW5kIHRvIGdldCBhIGRldGFpbGVkIGxpc3Qgb2YgYWxsIGRlcGVuZGVuY2llcyAocHJvZHVjdGlvbiwgZGV2ZWxvcG1lbnQsIGFuZCBwZWVyKSBhbmQgdGhlaXIgdmVyc2lvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhdGg9cHJvY2Vzcy5jd2QoKV0gLSBUaGUgZGlyZWN0b3J5IHBhdGggb2YgdGhlIHByb2plY3QuXG4gKiBAcmV0dXJuIHtQcm9taXNlPHtwcm9kOiBBcnJheTx7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmd9PiwgZGV2OiBBcnJheTx7bmFtZTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmd9PiwgcGVlcjogQXJyYXk8e25hbWU6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nfT59Pn0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgYXJyYXlzIG9mIHByb2R1Y3Rpb24sIGRldmVsb3BtZW50LCBhbmQgcGVlciBkZXBlbmRlbmNpZXMuXG4gKiBAZnVuY3Rpb24gZ2V0RGVwZW5kZW5jaWVzXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCBnZXREZXBlbmRlbmNpZXNcbiAqICAgcGFydGljaXBhbnQgcnVuQ29tbWFuZFxuICogICBwYXJ0aWNpcGFudCBKU09OXG4gKiAgIENhbGxlci0+PmdldERlcGVuZGVuY2llczogQ2FsbCB3aXRoIG9wdGlvbmFsIHBhdGhcbiAqICAgZ2V0RGVwZW5kZW5jaWVzLT4+cnVuQ29tbWFuZDogRXhlY3V0ZSAnbnBtIGxzIC0tanNvbidcbiAqICAgcnVuQ29tbWFuZC0tPj5nZXREZXBlbmRlbmNpZXM6IFJldHVybiBjb21tYW5kIG91dHB1dFxuICogICBnZXREZXBlbmRlbmNpZXMtPj5KU09OOiBQYXJzZSBjb21tYW5kIG91dHB1dFxuICogICBKU09OLS0+PmdldERlcGVuZGVuY2llczogUmV0dXJuIHBhcnNlZCBvYmplY3RcbiAqICAgZ2V0RGVwZW5kZW5jaWVzLT4+Z2V0RGVwZW5kZW5jaWVzOiBQcm9jZXNzIGRlcGVuZGVuY2llc1xuICogICBnZXREZXBlbmRlbmNpZXMtLT4+Q2FsbGVyOiBSZXR1cm4gcHJvY2Vzc2VkIGRlcGVuZGVuY2llc1xuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RGVwZW5kZW5jaWVzKFxuICBwYXRoOiBzdHJpbmcgPSBwcm9jZXNzLmN3ZCgpXG4pOiBQcm9taXNlPERlcGVuZGVuY3lNYXA+IHtcbiAgbGV0IHBrZzogYW55O1xuXG4gIHRyeSB7XG4gICAgcGtnID0gSlNPTi5wYXJzZShhd2FpdCBydW5Db21tYW5kKGBucG0gbHMgLS1qc29uYCwgeyBjd2Q6IHBhdGggfSkucHJvbWlzZSk7XG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byByZXRyaWV2ZSBkZXBlbmRlbmNpZXM6ICR7ZX1gKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgY29uc3QgbWFwcGVyID0gKGVudHJ5OiBbc3RyaW5nLCB1bmtub3duXSwgaW5kZXg6IG51bWJlcikgPT4gKHtcbiAgICBuYW1lOiBlbnRyeVswXSxcbiAgICB2ZXJzaW9uOiAoZW50cnlbMV0gYXMgYW55KS52ZXJzaW9uLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIHByb2Q6IE9iamVjdC5lbnRyaWVzKHBrZy5kZXBlbmRlbmNpZXMgfHwge30pLm1hcChtYXBwZXIpLFxuICAgIGRldjogT2JqZWN0LmVudHJpZXMocGtnLmRldkRlcGVuZGVuY2llcyB8fCB7fSkubWFwKG1hcHBlciksXG4gICAgcGVlcjogT2JqZWN0LmVudHJpZXMocGtnLnBlZXJEZXBlbmRlbmNpZXMgfHwge30pLm1hcChtYXBwZXIpLFxuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHByb2plY3QgZGVwZW5kZW5jaWVzIHRvIHRoZWlyIGxhdGVzdCB2ZXJzaW9ucy5cbiAqIEBzdW1tYXJ5IFJ1bnMgbnBtLWNoZWNrLXVwZGF0ZXMgdG8gdXBkYXRlIHBhY2thZ2UuanNvbiBhbmQgdGhlbiBpbnN0YWxscyB0aGUgdXBkYXRlZCBkZXBlbmRlbmNpZXMuXG4gKlxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBkZXBlbmRlbmNpZXMgYXJlIHVwZGF0ZWQuXG4gKlxuICogQGZ1bmN0aW9uIHVwZGF0ZURlcGVuZGVuY2llc1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZURlcGVuZGVuY2llcygpIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcih1cGRhdGVEZXBlbmRlbmNpZXMpO1xuICBsb2cuaW5mbyhcImNoZWNraW5nIGZvciB1cGRhdGVzLi4uXCIpO1xuICBhd2FpdCBydW5Db21tYW5kKFwibnB4IG5wbS1jaGVjay11cGRhdGVzIC11XCIpLnByb21pc2U7XG4gIGxvZy5pbmZvKFwidXBkYXRpbmcuLi5cIik7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoXCJucHggbnBtIHJ1biBkby1pbnN0YWxsXCIpLnByb21pc2U7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEluc3RhbGxzIGRlcGVuZGVuY2llcyBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBhdmFpbGFibGUuXG4gKiBAc3VtbWFyeSBDaGVja3MgaWYgc3BlY2lmaWVkIGRlcGVuZGVuY2llcyBhcmUgaW5zdGFsbGVkIGFuZCBpbnN0YWxscyBhbnkgdGhhdCBhcmUgbWlzc2luZy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSBkZXBzIC0gVGhlIGRlcGVuZGVuY2llcyB0byBjaGVjayBhbmQgcG90ZW50aWFsbHkgaW5zdGFsbC5cbiAqIEBwYXJhbSB7U2ltcGxlRGVwZW5kZW5jeU1hcH0gW2RlcGVuZGVuY2llc10gLSBPcHRpb25hbCBtYXAgb2YgZXhpc3RpbmcgZGVwZW5kZW5jaWVzLlxuICogQHJldHVybiB7UHJvbWlzZTxTaW1wbGVEZXBlbmRlbmN5TWFwPn0gVXBkYXRlZCBtYXAgb2YgZGVwZW5kZW5jaWVzLlxuICpcbiAqIEBmdW5jdGlvbiBpbnN0YWxsSWZOb3RBdmFpbGFibGVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbnN0YWxsSWZOb3RBdmFpbGFibGUoXG4gIGRlcHM6IHN0cmluZ1tdIHwgc3RyaW5nLFxuICBkZXBlbmRlbmNpZXM/OiBTaW1wbGVEZXBlbmRlbmN5TWFwXG4pIHtcbiAgaWYgKCFkZXBlbmRlbmNpZXMpIHtcbiAgICBjb25zdCBkOiBEZXBlbmRlbmN5TWFwID0gYXdhaXQgZ2V0RGVwZW5kZW5jaWVzKCk7XG4gICAgZGVwZW5kZW5jaWVzID0ge1xuICAgICAgcHJvZDogZC5wcm9kPy5tYXAoKHApID0+IHAubmFtZSkgfHwgW10sXG4gICAgICBkZXY6IGQuZGV2Py5tYXAoKGQpID0+IGQubmFtZSkgfHwgW10sXG4gICAgICBwZWVyOiBkLnBlZXI/Lm1hcCgocCkgPT4gcC5uYW1lKSB8fCBbXSxcbiAgICB9O1xuICB9XG4gIGNvbnN0IHsgcHJvZCwgZGV2LCBwZWVyIH0gPSBkZXBlbmRlbmNpZXM7XG4gIGNvbnN0IGluc3RhbGxlZCA9IEFycmF5LmZyb20oXG4gICAgbmV3IFNldChbLi4uKHByb2QgfHwgW10pLCAuLi4oZGV2IHx8IFtdKSwgLi4uKHBlZXIgfHwgW10pXSlcbiAgKTtcbiAgZGVwcyA9IHR5cGVvZiBkZXBzID09PSBcInN0cmluZ1wiID8gW2RlcHNdIDogZGVwcztcbiAgY29uc3QgdG9JbnN0YWxsID0gZGVwcy5maWx0ZXIoKGQpID0+ICFpbnN0YWxsZWQuaW5jbHVkZXMoZCkpO1xuXG4gIGlmICh0b0luc3RhbGwubGVuZ3RoKSBhd2FpdCBpbnN0YWxsRGVwZW5kZW5jaWVzKHsgZGV2OiB0b0luc3RhbGwgfSk7XG4gIGRlcGVuZGVuY2llcy5kZXYgPSBkZXBlbmRlbmNpZXMuZGV2IHx8IFtdO1xuICBkZXBlbmRlbmNpZXMuZGV2LnB1c2goLi4udG9JbnN0YWxsKTtcbiAgcmV0dXJuIGRlcGVuZGVuY2llcztcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHVzaGVzIGNoYW5nZXMgdG8gR2l0IHJlcG9zaXRvcnkuXG4gKiBAc3VtbWFyeSBUZW1wb3JhcmlseSBjaGFuZ2VzIEdpdCB1c2VyIGNvbmZpZ3VyYXRpb24sIGNvbW1pdHMgYWxsIGNoYW5nZXMsIHB1c2hlcyB0byByZW1vdGUsIGFuZCByZXN0b3JlcyBvcmlnaW5hbCB1c2VyIGNvbmZpZ3VyYXRpb24uXG4gKlxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBjaGFuZ2VzIGFyZSBwdXNoZWQuXG4gKlxuICogQGZ1bmN0aW9uIHB1c2hUb0dpdFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1c2hUb0dpdCgpIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihwdXNoVG9HaXQpO1xuICBjb25zdCBnaXRVc2VyID0gYXdhaXQgcnVuQ29tbWFuZChcImdpdCBjb25maWcgdXNlci5uYW1lXCIpLnByb21pc2U7XG4gIGNvbnN0IGdpdEVtYWlsID0gYXdhaXQgcnVuQ29tbWFuZChcImdpdCBjb25maWcgdXNlci5lbWFpbFwiKS5wcm9taXNlO1xuICBsb2cudmVyYm9zZShgY2FjaGVkIGdpdCBpZDogJHtnaXRVc2VyfS8ke2dpdEVtYWlsfS4gY2hhbmdpbmcgdG8gYXV0b21hdGlvbmApO1xuICBhd2FpdCBydW5Db21tYW5kKCdnaXQgY29uZmlnIHVzZXIuZW1haWwgXCJhdXRvbWF0aW9uQGRlY2FmLnRzXCInKS5wcm9taXNlO1xuICBhd2FpdCBydW5Db21tYW5kKCdnaXQgY29uZmlnIHVzZXIubmFtZSBcImRlY2FmXCInKS5wcm9taXNlO1xuICBsb2cuaW5mbyhcIlB1c2hpbmcgY2hhbmdlcyB0byBnaXQuLi5cIik7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoXCJnaXQgYWRkIC5cIikucHJvbWlzZTtcbiAgYXdhaXQgcnVuQ29tbWFuZChgZ2l0IGNvbW1pdCAtbSBcInJlZnMgIzEgLSBhZnRlciByZXBvIHNldHVwXCJgKS5wcm9taXNlO1xuICBhd2FpdCBydW5Db21tYW5kKFwiZ2l0IHB1c2hcIikucHJvbWlzZTtcbiAgYXdhaXQgcnVuQ29tbWFuZChgZ2l0IGNvbmZpZyB1c2VyLmVtYWlsIFwiJHtnaXRFbWFpbH1cImApLnByb21pc2U7XG4gIGF3YWl0IHJ1bkNvbW1hbmQoYGdpdCBjb25maWcgdXNlci5uYW1lIFwiJHtnaXRVc2VyfVwiYCkucHJvbWlzZTtcbiAgbG9nLnZlcmJvc2UoYHJldmVydGVkIHRvIGdpdCBpZDogJHtnaXRVc2VyfS8ke2dpdEVtYWlsfWApO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBJbnN0YWxscyBwcm9qZWN0IGRlcGVuZGVuY2llcy5cbiAqIEBzdW1tYXJ5IEluc3RhbGxzIHByb2R1Y3Rpb24sIGRldmVsb3BtZW50LCBhbmQgcGVlciBkZXBlbmRlbmNpZXMgYXMgc3BlY2lmaWVkLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBkZXBlbmRlbmNpZXMgLSBPYmplY3QgY29udGFpbmluZyBhcnJheXMgb2YgZGVwZW5kZW5jaWVzIHRvIGluc3RhbGwuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbZGVwZW5kZW5jaWVzLnByb2RdIC0gUHJvZHVjdGlvbiBkZXBlbmRlbmNpZXMgdG8gaW5zdGFsbC5cbiAqIEBwYXJhbSB7c3RyaW5nW119IFtkZXBlbmRlbmNpZXMuZGV2XSAtIERldmVsb3BtZW50IGRlcGVuZGVuY2llcyB0byBpbnN0YWxsLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gW2RlcGVuZGVuY2llcy5wZWVyXSAtIFBlZXIgZGVwZW5kZW5jaWVzIHRvIGluc3RhbGwuXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBkZXBlbmRlbmNpZXMgYXJlIGluc3RhbGxlZC5cbiAqXG4gKiBAZnVuY3Rpb24gaW5zdGFsbERlcGVuZGVuY2llc1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluc3RhbGxEZXBlbmRlbmNpZXMoZGVwZW5kZW5jaWVzOiB7XG4gIHByb2Q/OiBzdHJpbmdbXTtcbiAgZGV2Pzogc3RyaW5nW107XG4gIHBlZXI/OiBzdHJpbmdbXTtcbn0pIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihpbnN0YWxsRGVwZW5kZW5jaWVzKTtcbiAgY29uc3QgcHJvZCA9IGRlcGVuZGVuY2llcy5wcm9kIHx8IFtdO1xuICBjb25zdCBkZXYgPSBkZXBlbmRlbmNpZXMuZGV2IHx8IFtdO1xuICBjb25zdCBwZWVyID0gZGVwZW5kZW5jaWVzLnBlZXIgfHwgW107XG4gIGlmIChwcm9kLmxlbmd0aCkge1xuICAgIGxvZy5pbmZvKGBJbnN0YWxsaW5nIGRlcGVuZGVuY2llcyAke3Byb2Quam9pbihcIiwgXCIpfS4uLmApO1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoYG5wbSBpbnN0YWxsICR7cHJvZC5qb2luKFwiIFwiKX1gLCB7IGN3ZDogcHJvY2Vzcy5jd2QoKSB9KVxuICAgICAgLnByb21pc2U7XG4gIH1cbiAgaWYgKGRldi5sZW5ndGgpIHtcbiAgICBsb2cuaW5mbyhgSW5zdGFsbGluZyBkZXZEZXBlbmRlbmNpZXMgJHtkZXYuam9pbihcIiwgXCIpfS4uLmApO1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoYG5wbSBpbnN0YWxsIC0tc2F2ZS1kZXYgJHtkZXYuam9pbihcIiBcIil9YCwge1xuICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIH0pLnByb21pc2U7XG4gIH1cbiAgaWYgKHBlZXIubGVuZ3RoKSB7XG4gICAgbG9nLmluZm8oYEluc3RhbGxpbmcgcGVlckRlcGVuZGVuY2llcyAke3BlZXIuam9pbihcIiwgXCIpfS4uLmApO1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoYG5wbSBpbnN0YWxsIC0tc2F2ZS1wZWVyICR7cGVlci5qb2luKFwiIFwiKX1gLCB7XG4gICAgICBjd2Q6IHByb2Nlc3MuY3dkKCksXG4gICAgfSkucHJvbWlzZTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIGltcG9ydHMgdG8gaGFuZGxlIGJvdGggQ29tbW9uSlMgYW5kIEVTTW9kdWxlIGZvcm1hdHMuXG4gKiBAc3VtbWFyeSBVdGlsaXR5IGZ1bmN0aW9uIHRvIGhhbmRsZSBtb2R1bGUgaW1wb3J0IGRpZmZlcmVuY2VzIGJldHdlZW4gZm9ybWF0cy5cbiAqXG4gKiBAdGVtcGxhdGUgVCAtIFR5cGUgb2YgdGhlIGltcG9ydGVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7UHJvbWlzZTxUPn0gaW1wb3J0UHJvbWlzZSAtIFByb21pc2UgcmV0dXJuZWQgYnkgZHluYW1pYyBpbXBvcnQuXG4gKiBAcmV0dXJuIHtQcm9taXNlPFQ+fSBOb3JtYWxpemVkIG1vZHVsZS5cbiAqXG4gKiBAZnVuY3Rpb24gbm9ybWFsaXplSW1wb3J0XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp1dGlsc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbm9ybWFsaXplSW1wb3J0PFQ+KFxuICBpbXBvcnRQcm9taXNlOiBQcm9taXNlPFQ+XG4pOiBQcm9taXNlPFQ+IHtcbiAgLy8gQ29tbW9uSlMncyBgbW9kdWxlLmV4cG9ydHNgIGlzIHdyYXBwZWQgYXMgYGRlZmF1bHRgIGluIEVTTW9kdWxlLlxuICByZXR1cm4gaW1wb3J0UHJvbWlzZS50aGVuKChtOiBhbnkpID0+IChtLmRlZmF1bHQgfHwgbSkgYXMgVCk7XG59XG5cbi8vIE5ldyBoZWxwZXI6IGNvbXB1dGUgZ3ppcHBlZCBzaXplIG9mIHNtYWxsZXN0IEpTIGZpbGUgaW4gYSBkaXJlY3RvcnlcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRGaWxlU2l6ZVppcHBlZChkaXI6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IoZ2V0RmlsZVNpemVaaXBwZWQpO1xuICB0cnkge1xuICAgIGNvbnN0IGVudHJpZXMgPSBmcy5yZWFkZGlyU3luYyhkaXIpO1xuICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBlbnRyaWVzXG4gICAgICAubWFwKChlKSA9PiBwYXRoLmpvaW4oZGlyLCBlKSlcbiAgICAgIC5maWx0ZXIoKHApID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBzID0gZnMuc3RhdFN5bmMocCk7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHMuaXNGaWxlKCkgJiZcbiAgICAgICAgICAgIChwLmVuZHNXaXRoKFwiLmpzXCIpIHx8IHAuZW5kc1dpdGgoXCIuY2pzXCIpIHx8IHAuZW5kc1dpdGgoXCIubWpzXCIpKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gSlMgZmlsZXMgZm91bmQgaW4gZGlyZWN0b3J5ICR7ZGlyfWApO1xuICAgIH1cblxuICAgIC8vIGNob29zZSB0aGUgc21hbGxlc3QgYnkgcmF3IGZpbGUgc2l6ZVxuICAgIGxldCBzbWFsbGVzdCA9IGNhbmRpZGF0ZXNbMF07XG4gICAgbGV0IHNtYWxsZXN0U2l6ZSA9IGZzLnN0YXRTeW5jKHNtYWxsZXN0KS5zaXplO1xuICAgIGZvciAoY29uc3QgYyBvZiBjYW5kaWRhdGVzLnNsaWNlKDEpKSB7XG4gICAgICBjb25zdCBzID0gZnMuc3RhdFN5bmMoYykuc2l6ZTtcbiAgICAgIGlmIChzIDwgc21hbGxlc3RTaXplKSB7XG4gICAgICAgIHNtYWxsZXN0ID0gYztcbiAgICAgICAgc21hbGxlc3RTaXplID0gcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBTZWxlY3RlZCBzbWFsbGVzdCBidW5kbGU6ICR7c21hbGxlc3R9ICgke3NtYWxsZXN0U2l6ZX0gYnl0ZXMpYFxuICAgICk7XG5cbiAgICBjb25zdCBidWZmZXIgPSBmcy5yZWFkRmlsZVN5bmMoc21hbGxlc3QpO1xuICAgIGNvbnN0IGd6ID0gemxpYi5nemlwU3luYyhidWZmZXIpO1xuICAgIGNvbnN0IHNpemVLYiA9IE51bWJlcigoZ3oubGVuZ3RoIC8gMTAyNCkudG9GaXhlZCgxKSk7XG4gICAgbG9nLnZlcmJvc2UoYEd6aXBwZWQgc2l6ZTogJHtnei5sZW5ndGh9IGJ5dGVzICgke3NpemVLYn0gS0IpYCk7XG4gICAgcmV0dXJuIHNpemVLYjtcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBGYWlsZWQgdG8gY29tcHV0ZSBnemlwcGVkIHNpemUgZm9yICR7ZGlyfTogJHtlfWApO1xuICAgIHRocm93IGUgYXMgRXJyb3I7XG4gIH1cbn1cblxuLy8gTmV3IGhlbHBlcjogbGlzdCBmb2xkZXIgZW50cmllcyAobmFtZXMpIHdpdGggb3B0aW9uYWwgZmlsdGVyXG5leHBvcnQgZnVuY3Rpb24gbGlzdEZvbGRlcihcbiAgYmFzZVBhdGg6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCksXG4gIGZpbHRlcj86IChuYW1lOiBzdHJpbmcsIGRpcmVudDogZnMuRGlyZW50KSA9PiBib29sZWFuXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IobGlzdEZvbGRlcik7XG4gIHRyeSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGJhc2VQYXRoKSkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGVudHJpZXMgPSBmcy5yZWFkZGlyU3luYyhiYXNlUGF0aCwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuICAgIGNvbnN0IG5hbWVzID0gZW50cmllc1xuICAgICAgLmZpbHRlcigoZCkgPT4gKGZpbHRlciA/IGZpbHRlcihkLm5hbWUsIGQpIDogdHJ1ZSkpXG4gICAgICAubWFwKChkKSA9PiBkLm5hbWUpO1xuICAgIHJldHVybiBuYW1lcztcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBGYWlsZWQgdG8gbGlzdCBmb2xkZXIgJHtiYXNlUGF0aH06ICR7ZX1gKTtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuLy8gTmV3IGhlbHBlcjogbGlzdCBub2RlX21vZHVsZXMgcGFja2FnZSBuYW1lcywgZXhwYW5kaW5nIHNjb3BlZCBwYWNrYWdlc1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3ROb2RlTW9kdWxlc1BhY2thZ2VzKFxuICBiYXNlUGF0aDogc3RyaW5nID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIFwibm9kZV9tb2R1bGVzXCIpXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3IobGlzdE5vZGVNb2R1bGVzUGFja2FnZXMpO1xuICB0cnkge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhiYXNlUGF0aCkpIHJldHVybiBbXTtcbiAgICBjb25zdCBlbnRyaWVzID0gZnMucmVhZGRpclN5bmMoYmFzZVBhdGgsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcbiAgICBjb25zdCBuYW1lczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZSBvZiBlbnRyaWVzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIWUuaXNEaXJlY3RvcnkoKSkgY29udGludWU7XG4gICAgICAgIC8vIGlnbm9yZSBoaWRkZW4gZm9sZGVyc1xuICAgICAgICBpZiAoZS5uYW1lLnN0YXJ0c1dpdGgoXCIuXCIpKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGUubmFtZS5zdGFydHNXaXRoKFwiQFwiKSkge1xuICAgICAgICAgIC8vIGEgc2NvcGUgZm9sZGVyOyBleHBhbmQgY29udGFpbmVkIHBhY2thZ2VzXG4gICAgICAgICAgY29uc3Qgc2NvcGVQYXRoID0gcGF0aC5qb2luKGJhc2VQYXRoLCBlLm5hbWUpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzY29wZWQgPSBmcy5yZWFkZGlyU3luYyhzY29wZVBhdGgsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcyBvZiBzY29wZWQpIHtcbiAgICAgICAgICAgICAgaWYgKHMuaXNEaXJlY3RvcnkoKSAmJiAhcy5uYW1lLnN0YXJ0c1dpdGgoXCIuXCIpKSB7XG4gICAgICAgICAgICAgICAgbmFtZXMucHVzaChgJHtlLm5hbWV9LyR7cy5uYW1lfWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBpZ25vcmUgc2NvcGUgcmVhZCBlcnJvcnNcbiAgICAgICAgICAgIGxvZy52ZXJib3NlKGBGYWlsZWQgdG8gcmVhZCBzY29wZSAke3Njb3BlUGF0aH06ICR7ZXJyfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lcy5wdXNoKGUubmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2cudmVyYm9zZShgU2tpcHBpbmcgZW50cnkgJHtlLm5hbWV9IGR1ZSB0byBlcnJvcjogJHtlcnJ9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuYW1lcztcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIGxvZy52ZXJib3NlKGBGYWlsZWQgdG8gbGlzdCBub2RlX21vZHVsZXMgcGFja2FnZXMgYXQgJHtiYXNlUGF0aH06ICR7ZX1gKTtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cbiIsIi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmluaXRpb24gb2YgYSBzbG9nYW4gaXRlbS5cbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBzaW5nbGUgc2xvZ2FuIGVudHJ5IHdpdGggdGV4dCBhbmQgdGFncy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNsb2dhbkl0ZW1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTbG9nYW4gLSBUaGUgc2xvZ2FuIHRleHQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVGFncyAtIENvbW1hLXNlcGFyYXRlZCB0YWdzIGRlc2NyaWJpbmcgdGhlIHNsb2dhbi5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBMaXN0IG9mIGF2YWlsYWJsZSBzbG9nYW5zIGZvciBiYW5uZXJzIGFuZCBtZXNzYWdlcy5cbiAqIEBzdW1tYXJ5IEltbXV0YWJsZSBhcnJheSBvZiBzbG9nYW4gZW50cmllcyB1c2VkIGJ5IHtAbGluayBnZXRTbG9nYW59IGFuZCBiYW5uZXIgcmVuZGVyaW5nLlxuICogQHR5cGUge1Nsb2dhbkl0ZW1bXX1cbiAqIEBjb25zdCBzbG9nYW5zXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBjb25zdCBzbG9nYW5zID0gW1xuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGNhZmZlaW5lLCBubyBjaGFvcy4gSnVzdCBjbGVhbiBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2FsbSwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZ1bGwgZmxhdm9yLCBubyBqaXR0ZXJzLiBUaGF0J3MgRGVjYWYtVFMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGVlcmZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNoaWxsIGZ1bGxzdGFjay4gUG93ZXJlZCBieSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1biwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRlY2FmLVRTOiBCcmV3ZWQgZm9yIGNhbG0gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEJyYW5kaW5nXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU21vb3RoIGFzIHlvdXIgbW9ybmluZyBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQWxsIHRoZSBraWNrLCBub25lIG9mIHRoZSBjcmFzaC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEVuZXJnZXRpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNpcCBiYWNrIGFuZCBzaGlwIGZhc3Rlci5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1blwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIktlZXAgY2FsbSBhbmQgY29kZSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFBsYXlmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDb2RlIHdpdGhvdXQgdGhlIGNhZmZlaW5lIHNoYWtlcy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEh1bW9yb3VzXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiWW91ciBmdWxsc3RhY2ssIGRlY2FmZmVpbmF0ZWQuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBUZWNobmljYWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJObyBjYWZmZWluZSwgbm8gY2hhb3MuIEp1c3QgY2xlYW4gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENhbG0sIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJGdWxsIGZsYXZvciwgbm8gaml0dGVycy4gVGhhdFxcdTIwMTlzIERlY2FmLVRTLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2hlZXJmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDaGlsbCBmdWxsc3RhY2suIFBvd2VyZWQgYnkgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBGdW4sIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEZWNhZi1UUzogQnJld2VkIGZvciBjYWxtIGNvZGUuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBCcmFuZGluZ1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNtb290aCBhcyB5b3VyIG1vcm5pbmcgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGlsbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkFsbCB0aGUga2ljaywgbm9uZSBvZiB0aGUgY3Jhc2guXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBFbmVyZ2V0aWNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTaXAgYmFjayBhbmQgc2hpcCBmYXN0ZXIuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBGdW5cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJLZWVwIGNhbG0gYW5kIGNvZGUgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBQbGF5ZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ29kZSB3aXRob3V0IHRoZSBjYWZmZWluZSBzaGFrZXMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBIdW1vcm91c1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIllvdXIgZnVsbHN0YWNrLCBkZWNhZmZlaW5hdGVkLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgVGVjaG5pY2FsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiTm8gY2FmZmVpbmUsIG5vIGNoYW9zLiBKdXN0IGNsZWFuIGNvZGUuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDYWxtLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRnVsbCBmbGF2b3IsIG5vIGppdHRlcnMuIFRoYXRcXHUyMDE5cyBEZWNhZi1UUy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoZWVyZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ2hpbGwgZnVsbHN0YWNrLiBQb3dlcmVkIGJ5IERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRnVuLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRGVjYWYtVFM6IEJyZXdlZCBmb3IgY2FsbSBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQnJhbmRpbmdcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTbW9vdGggYXMgeW91ciBtb3JuaW5nIERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJBbGwgdGhlIGtpY2ssIG5vbmUgb2YgdGhlIGNyYXNoLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRW5lcmdldGljXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU2lwIGJhY2sgYW5kIHNoaXAgZmFzdGVyLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRnVuXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiS2VlcCBjYWxtIGFuZCBjb2RlIERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgUGxheWZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNvZGUgd2l0aG91dCB0aGUgY2FmZmVpbmUgc2hha2VzLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgSHVtb3JvdXNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJZb3VyIGZ1bGxzdGFjaywgZGVjYWZmZWluYXRlZC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFRlY2huaWNhbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGNhZmZlaW5lLCBubyBjaGFvcy4gSnVzdCBjbGVhbiBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2FsbSwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZ1bGwgZmxhdm9yLCBubyBqaXR0ZXJzLiBUaGF0XFx1MjAxOXMgRGVjYWYtVFMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGVlcmZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNoaWxsIGZ1bGxzdGFjay4gUG93ZXJlZCBieSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1biwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRlY2FmLVRTOiBCcmV3ZWQgZm9yIGNhbG0gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEJyYW5kaW5nXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU21vb3RoIGFzIHlvdXIgbW9ybmluZyBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQWxsIHRoZSBraWNrLCBub25lIG9mIHRoZSBjcmFzaC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEVuZXJnZXRpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNpcCBiYWNrIGFuZCBzaGlwIGZhc3Rlci5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1blwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIktlZXAgY2FsbSBhbmQgY29kZSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFBsYXlmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDb2RlIHdpdGhvdXQgdGhlIGNhZmZlaW5lIHNoYWtlcy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEh1bW9yb3VzXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiWW91ciBmdWxsc3RhY2ssIGRlY2FmZmVpbmF0ZWQuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBUZWNobmljYWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJObyBjYWZmZWluZSwgbm8gY2hhb3MuIEp1c3QgY2xlYW4gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENhbG0sIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJGdWxsIGZsYXZvciwgbm8gaml0dGVycy4gVGhhdFxcdTIwMTlzIERlY2FmLVRTLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2hlZXJmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDaGlsbCBmdWxsc3RhY2suIFBvd2VyZWQgYnkgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBGdW4sIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEZWNhZi1UUzogQnJld2VkIGZvciBjYWxtIGNvZGUuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBCcmFuZGluZ1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNtb290aCBhcyB5b3VyIG1vcm5pbmcgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGlsbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkFsbCB0aGUga2ljaywgbm9uZSBvZiB0aGUgY3Jhc2guXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBFbmVyZ2V0aWNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTaXAgYmFjayBhbmQgc2hpcCBmYXN0ZXIuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBGdW5cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJLZWVwIGNhbG0gYW5kIGNvZGUgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBQbGF5ZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ29kZSB3aXRob3V0IHRoZSBjYWZmZWluZSBzaGFrZXMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBIdW1vcm91c1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIllvdXIgZnVsbHN0YWNrLCBkZWNhZmZlaW5hdGVkLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgVGVjaG5pY2FsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiTm8gY2FmZmVpbmUsIG5vIGNoYW9zLiBKdXN0IGNsZWFuIGNvZGUuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDYWxtLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRnVsbCBmbGF2b3IsIG5vIGppdHRlcnMuIFRoYXRcXHUyMDE5cyBEZWNhZi1UUy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoZWVyZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ2hpbGwgZnVsbHN0YWNrLiBQb3dlcmVkIGJ5IERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRnVuLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRGVjYWYtVFM6IEJyZXdlZCBmb3IgY2FsbSBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQnJhbmRpbmdcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTbW9vdGggYXMgeW91ciBtb3JuaW5nIERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJBbGwgdGhlIGtpY2ssIG5vbmUgb2YgdGhlIGNyYXNoLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRW5lcmdldGljXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU2lwIGJhY2sgYW5kIHNoaXAgZmFzdGVyLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRnVuXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiS2VlcCBjYWxtIGFuZCBjb2RlIERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgUGxheWZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNvZGUgd2l0aG91dCB0aGUgY2FmZmVpbmUgc2hha2VzLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgSHVtb3JvdXNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJZb3VyIGZ1bGxzdGFjaywgZGVjYWZmZWluYXRlZC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFRlY2huaWNhbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGNhZmZlaW5lLCBubyBjaGFvcy4gSnVzdCBjbGVhbiBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2FsbSwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZ1bGwgZmxhdm9yLCBubyBqaXR0ZXJzLiBUaGF0XFx1MjAxOXMgRGVjYWYtVFMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGVlcmZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNoaWxsIGZ1bGxzdGFjay4gUG93ZXJlZCBieSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1biwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRlY2FmLVRTOiBCcmV3ZWQgZm9yIGNhbG0gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEJyYW5kaW5nXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU21vb3RoIGFzIHlvdXIgbW9ybmluZyBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQWxsIHRoZSBraWNrLCBub25lIG9mIHRoZSBjcmFzaC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEVuZXJnZXRpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNpcCBiYWNrIGFuZCBzaGlwIGZhc3Rlci5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1blwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIktlZXAgY2FsbSBhbmQgY29kZSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFBsYXlmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDb2RlIHdpdGhvdXQgdGhlIGNhZmZlaW5lIHNoYWtlcy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEh1bW9yb3VzXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiWW91ciBmdWxsc3RhY2ssIGRlY2FmZmVpbmF0ZWQuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBUZWNobmljYWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJObyBjYWZmZWluZSwgbm8gY2hhb3MuIEp1c3QgY2xlYW4gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENhbG0sIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJGdWxsIGZsYXZvciwgbm8gaml0dGVycy4gVGhhdFxcdTIwMTlzIERlY2FmLVRTLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2hlZXJmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDaGlsbCBmdWxsc3RhY2suIFBvd2VyZWQgYnkgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBGdW4sIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEZWNhZi1UUzogQnJld2VkIGZvciBjYWxtIGNvZGUuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBCcmFuZGluZ1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNtb290aCBhcyB5b3VyIG1vcm5pbmcgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGlsbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkFsbCB0aGUga2ljaywgbm9uZSBvZiB0aGUgY3Jhc2guXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBFbmVyZ2V0aWNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTaXAgYmFjayBhbmQgc2hpcCBmYXN0ZXIuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBGdW5cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJLZWVwIGNhbG0gYW5kIGNvZGUgRGVjYWYuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBQbGF5ZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ29kZSB3aXRob3V0IHRoZSBjYWZmZWluZSBzaGFrZXMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBIdW1vcm91c1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIllvdXIgZnVsbHN0YWNrLCBkZWNhZmZlaW5hdGVkLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgVGVjaG5pY2FsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiTm8gY2FmZmVpbmUsIG5vIGNoYW9zLiBKdXN0IGNsZWFuIGNvZGUuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDYWxtLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRnVsbCBmbGF2b3IsIG5vIGppdHRlcnMuIFRoYXRcXHUyMDE5cyBEZWNhZi1UUy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoZWVyZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ2hpbGwgZnVsbHN0YWNrLiBQb3dlcmVkIGJ5IERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRnVuLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRGVjYWYtVFM6IEJyZXdlZCBmb3IgY2FsbSBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQnJhbmRpbmdcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTbW9vdGggYXMgeW91ciBtb3JuaW5nIERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJBbGwgdGhlIGtpY2ssIG5vbmUgb2YgdGhlIGNyYXNoLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRW5lcmdldGljXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU2lwIGJhY2sgYW5kIHNoaXAgZmFzdGVyLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgRnVuXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiS2VlcCBjYWxtIGFuZCBjb2RlIERlY2FmLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgUGxheWZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNvZGUgd2l0aG91dCB0aGUgY2FmZmVpbmUgc2hha2VzLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgSHVtb3JvdXNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJZb3VyIGZ1bGxzdGFjaywgZGVjYWZmZWluYXRlZC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFRlY2huaWNhbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGNhZmZlaW5lLCBubyBjaGFvcy4gSnVzdCBjbGVhbiBjb2RlLlwiLFxuICAgIFRhZ3M6IFwiQ29mZmVlLXRoZW1lZCwgQ2FsbSwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZ1bGwgZmxhdm9yLCBubyBqaXR0ZXJzLiBUaGF0XFx1MjAxOXMgRGVjYWYtVFMuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBDaGVlcmZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNoaWxsIGZ1bGxzdGFjay4gUG93ZXJlZCBieSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1biwgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRlY2FmLVRTOiBCcmV3ZWQgZm9yIGNhbG0gY29kZS5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEJyYW5kaW5nXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU21vb3RoIGFzIHlvdXIgbW9ybmluZyBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQWxsIHRoZSBraWNrLCBub25lIG9mIHRoZSBjcmFzaC5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEVuZXJnZXRpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNpcCBiYWNrIGFuZCBzaGlwIGZhc3Rlci5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEZ1blwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIktlZXAgY2FsbSBhbmQgY29kZSBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIFBsYXlmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDb2RlIHdpdGhvdXQgdGhlIGNhZmZlaW5lIHNoYWtlcy5cIixcbiAgICBUYWdzOiBcIkNvZmZlZS10aGVtZWQsIEh1bW9yb3VzXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiWW91ciBmdWxsc3RhY2ssIGRlY2FmZmVpbmF0ZWQuXCIsXG4gICAgVGFnczogXCJDb2ZmZWUtdGhlbWVkLCBUZWNobmljYWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEZWNhZi1UUzogV2hlcmUgc21hcnQgY29udHJhY3RzIG1lZXQgc21hcnQgaW50ZXJmYWNlcy5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIFNtYXJ0IENvbnRyYWN0cywgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNoaXAgZEFwcHMgd2l0aG91dCB0aGUgc3RyZXNzLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgQ2hlZXJmdWwsIERldmVsb3BlclwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIENSVUQsIG5vIHByb2JsZW0gXFx1MjAxNCBEZWNhZiB5b3VyIGRhdGEuXCIsXG4gICAgVGFnczogXCJEYXRhLCBOby1DUlVELCBDaGlsbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZyb20gRElEIHRvIFVJLCB3aXRob3V0IGJyZWFraW5nIGEgc3dlYXQuXCIsXG4gICAgVGFnczogXCJESUQsIFNTSSwgVUksIENhbG1cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEZWNhZi1UUzogWW91ciBmcm9udGVuZCBhbHJlYWR5IHVuZGVyc3RhbmRzIHlvdXIgc21hcnQgY29udHJhY3QuXCIsXG4gICAgVGFnczogXCJTbWFydCBDb250cmFjdHMsIERYLCBNYWdpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNlbGYtc292ZXJlaWduIGJ5IGRlc2lnbi4gUHJvZHVjdGl2ZSBieSBkZWZhdWx0LlwiLFxuICAgIFRhZ3M6IFwiU1NJLCBEZXZlbG9wZXIsIENhbG1cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJCdWlsZCBvbmNlLiBEZXBsb3kgZXZlcnl3aGVyZS4gRGVjZW50cmFsaXplZCBhbmQgZGVsaWdodGZ1bC5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIE11bHRpLXBsYXRmb3JtLCBIYXBweVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRhdGEgdGhhdCBkZWZpbmVzIGl0cyBvd24gZGVzdGlueS5cIixcbiAgICBUYWdzOiBcIlNTSSwgRGF0YS1kcml2ZW4sIEVtcG93ZXJtZW50XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiR29vZGJ5ZSBDUlVELCBoZWxsbyBpbnRlbnQtYmFzZWQgaW50ZXJmYWNlcy5cIixcbiAgICBUYWdzOiBcIk5vLUNSVUQsIFVJLCBUZWNobmljYWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJUaGUgc21vb3RoZXN0IHBhdGggZnJvbSBESUQgdG8gZG9uZS5cIixcbiAgICBUYWdzOiBcIkRJRCwgV29ya2Zsb3csIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQmVjYXVzZSB5b3VyIGRBcHAgZGVzZXJ2ZXMgbW9yZSB0aGFuIGJvaWxlcnBsYXRlLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgRGV2WCwgRWZmaWNpZW5jeVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk93biB5b3VyIGRhdGEuIE93biB5b3VyIGZsb3cuXCIsXG4gICAgVGFnczogXCJTU0ksIENvbnRyb2wsIE93bmVyc2hpcFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIldyaXRlIGxvZ2ljIGxpa2UgaXQgYmVsb25ncyB3aXRoIHRoZSBkYXRhIFxcdTIwMTQgYmVjYXVzZSBpdCBkb2VzLlwiLFxuICAgIFRhZ3M6IFwiRGF0YSBMb2dpYywgRGV2ZWxvcGVyLCBTbWFydFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZyb20gc21hcnQgY29udHJhY3RzIHRvIHNtYXJ0ZXIgZnJvbnRlbmRzLlwiLFxuICAgIFRhZ3M6IFwiU21hcnQgQ29udHJhY3RzLCBVSSwgRFhcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJObyBjYWZmZWluZS4gTm8gQ1JVRC4gSnVzdCB0aGUgZnV0dXJlLlwiLFxuICAgIFRhZ3M6IFwiTm8tQ1JVRCwgQ29mZmVlLXRoZW1lZCwgRnV0dXJpc3RpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlRoZSBmdXR1cmUgb2Ygd2ViMyBVWCBpcyBEZWNhZi5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIFVYLCBWaXNpb25cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDb2RlIHdpdGggY29uZmlkZW5jZS4gR292ZXJuIHdpdGggY2xhcml0eS5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIEdvdmVybmFuY2UsIENhbG1cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJJbnRlcmZhY2VzIHRoYXQgb2JleSB0aGUgZGF0YSwgbm90IHRoZSBvdGhlciB3YXkgYXJvdW5kLlwiLFxuICAgIFRhZ3M6IFwiVUksIERhdGEgTG9naWMsIFNlbGYtYXdhcmVcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJCcmV3IGJ1c2luZXNzIGxvZ2ljIHJpZ2h0IGludG8geW91ciBieXRlcy5cIixcbiAgICBUYWdzOiBcIkRhdGEgTG9naWMsIENvZmZlZS10aGVtZWQsIEZ1blwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRJRHMgZG9uZSBkaWZmZXJlbnRseSBcXHUyMDE0IGFuZCBkZWxpZ2h0ZnVsbHkuXCIsXG4gICAgVGFnczogXCJESUQsIFNlbGYtU292ZXJlaWduLCBQbGF5ZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRGVjYWYtVFMtVFM6IFdoZXJlIGJsb2NrY2hhaW4gY29udHJhY3RzIG1lZXQgc21hcnQgaW50ZXJmYWNlcy5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIFNtYXJ0IENvbnRyYWN0cywgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNoaXAgZEFwcHMgd2l0aG91dCB0aGUgc3RyZXNzLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgQ2hlZXJmdWwsIERldmVsb3BlclwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGJvaWxlcnBsYXRlLCBubyBwcm9ibGVtIFxcdTIwMTQgRGVjYWYtVFMgeW91ciBkYXRhLlwiLFxuICAgIFRhZ3M6IFwiRGF0YSwgTm8tQ1JVRCwgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJGcm9tIERJRCB0byBVSSwgd2l0aG91dCBicmVha2luZyBhIHN3ZWF0LlwiLFxuICAgIFRhZ3M6IFwiRElELCBTU0ksIFVJLCBDYWxtXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46XG4gICAgICBcIkRlY2FmLVRTLVRTOiBZb3VyIGZyb250ZW5kIGFscmVhZHkgdW5kZXJzdGFuZHMgeW91ciBibG9ja2NoYWluIGNvbnRyYWN0LlwiLFxuICAgIFRhZ3M6IFwiU21hcnQgQ29udHJhY3RzLCBEWCwgTWFnaWNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTZWxmLXNvdmVyZWlnbiBieSBkZXNpZ24uIFByb2R1Y3RpdmUgYnkgZGVmYXVsdC5cIixcbiAgICBUYWdzOiBcIlNTSSwgRGV2ZWxvcGVyLCBDYWxtXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQnVpbGQgb25jZS4gRGVwbG95IGV2ZXJ5d2hlcmUuIERlY2VudHJhbGl6ZWQgYW5kIGRlbGlnaHRmdWwuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBNdWx0aS1wbGF0Zm9ybSwgSGFwcHlcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEYXRhIHRoYXQgZGVmaW5lcyBpdHMgb3duIGRlc3RpbnkuXCIsXG4gICAgVGFnczogXCJTU0ksIERhdGEtZHJpdmVuLCBFbXBvd2VybWVudFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkdvb2RieWUgYm9pbGVycGxhdGUsIGhlbGxvIGludGVudC1iYXNlZCBpbnRlcmZhY2VzLlwiLFxuICAgIFRhZ3M6IFwiTm8tQ1JVRCwgVUksIFRlY2huaWNhbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlRoZSBzbW9vdGhlc3QgcGF0aCBmcm9tIERJRCB0byBkb25lLlwiLFxuICAgIFRhZ3M6IFwiRElELCBXb3JrZmxvdywgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJCZWNhdXNlIHlvdXIgZEFwcCBkZXNlcnZlcyBtb3JlIHRoYW4gYm9pbGVycGxhdGUuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBEZXZYLCBFZmZpY2llbmN5XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiT3duIHlvdXIgZGF0YS4gT3duIHlvdXIgZmxvdy5cIixcbiAgICBUYWdzOiBcIlNTSSwgQ29udHJvbCwgT3duZXJzaGlwXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiV3JpdGUgbG9naWMgbGlrZSBpdCBiZWxvbmdzIHdpdGggdGhlIGRhdGEgXFx1MjAxNCBiZWNhdXNlIGl0IGRvZXMuXCIsXG4gICAgVGFnczogXCJEYXRhIExvZ2ljLCBEZXZlbG9wZXIsIFNtYXJ0XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRnJvbSBibG9ja2NoYWluIGNvbnRyYWN0cyB0byBzbWFydGVyIGZyb250ZW5kcy5cIixcbiAgICBUYWdzOiBcIlNtYXJ0IENvbnRyYWN0cywgVUksIERYXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiTm8gY2FmZmVpbmUuIE5vIGJvaWxlcnBsYXRlLiBKdXN0IHRoZSBmdXR1cmUuXCIsXG4gICAgVGFnczogXCJOby1DUlVELCBDb2ZmZWUtdGhlbWVkLCBGdXR1cmlzdGljXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiVGhlIGZ1dHVyZSBvZiB3ZWIzIFVYIGlzIERlY2FmLVRTLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgVVgsIFZpc2lvblwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNvZGUgd2l0aCBjb25maWRlbmNlLiBHb3Zlcm4gd2l0aCBjbGFyaXR5LlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgR292ZXJuYW5jZSwgQ2FsbVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkludGVyZmFjZXMgdGhhdCBvYmV5IHRoZSBkYXRhLCBub3QgdGhlIG90aGVyIHdheSBhcm91bmQuXCIsXG4gICAgVGFnczogXCJVSSwgRGF0YSBMb2dpYywgU2VsZi1hd2FyZVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkJyZXcgYnVzaW5lc3MgbG9naWMgcmlnaHQgaW50byB5b3VyIGJ5dGVzLlwiLFxuICAgIFRhZ3M6IFwiRGF0YSBMb2dpYywgQ29mZmVlLXRoZW1lZCwgRnVuXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRElEcyBkb25lIGRpZmZlcmVudGx5IFxcdTIwMTQgYW5kIGRlbGlnaHRmdWxseS5cIixcbiAgICBUYWdzOiBcIkRJRCwgU2VsZi1Tb3ZlcmVpZ24sIFBsYXlmdWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEZWNhZi1UUy1UUzogV2hlcmUgYmxvY2tjaGFpbiBjb250cmFjdHMgbWVldCBzbWFydCBpbnRlcmZhY2VzLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgU21hcnQgQ29udHJhY3RzLCBUZWNoXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU2hpcCBkQXBwcyB3aXRob3V0IHRoZSBzdHJlc3MuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBDaGVlcmZ1bCwgRGV2ZWxvcGVyXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiTm8gYm9pbGVycGxhdGUsIG5vIHByb2JsZW0gXFx1MjAxNCBEZWNhZi1UUyB5b3VyIGRhdGEuXCIsXG4gICAgVGFnczogXCJEYXRhLCBOby1DUlVELCBDaGlsbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZyb20gRElEIHRvIFVJLCB3aXRob3V0IGJyZWFraW5nIGEgc3dlYXQuXCIsXG4gICAgVGFnczogXCJESUQsIFNTSSwgVUksIENhbG1cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjpcbiAgICAgIFwiRGVjYWYtVFMtVFM6IFlvdXIgZnJvbnRlbmQgYWxyZWFkeSB1bmRlcnN0YW5kcyB5b3VyIGJsb2NrY2hhaW4gY29udHJhY3QuXCIsXG4gICAgVGFnczogXCJTbWFydCBDb250cmFjdHMsIERYLCBNYWdpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNlbGYtc292ZXJlaWduIGJ5IGRlc2lnbi4gUHJvZHVjdGl2ZSBieSBkZWZhdWx0LlwiLFxuICAgIFRhZ3M6IFwiU1NJLCBEZXZlbG9wZXIsIENhbG1cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJCdWlsZCBvbmNlLiBEZXBsb3kgZXZlcnl3aGVyZS4gRGVjZW50cmFsaXplZCBhbmQgZGVsaWdodGZ1bC5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIE11bHRpLXBsYXRmb3JtLCBIYXBweVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRhdGEgdGhhdCBkZWZpbmVzIGl0cyBvd24gZGVzdGlueS5cIixcbiAgICBUYWdzOiBcIlNTSSwgRGF0YS1kcml2ZW4sIEVtcG93ZXJtZW50XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiR29vZGJ5ZSBib2lsZXJwbGF0ZSwgaGVsbG8gaW50ZW50LWJhc2VkIGludGVyZmFjZXMuXCIsXG4gICAgVGFnczogXCJOby1DUlVELCBVSSwgVGVjaG5pY2FsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiVGhlIHNtb290aGVzdCBwYXRoIGZyb20gRElEIHRvIGRvbmUuXCIsXG4gICAgVGFnczogXCJESUQsIFdvcmtmbG93LCBDaGlsbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkJlY2F1c2UgeW91ciBkQXBwIGRlc2VydmVzIG1vcmUgdGhhbiBib2lsZXJwbGF0ZS5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIERldlgsIEVmZmljaWVuY3lcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJPd24geW91ciBkYXRhLiBPd24geW91ciBmbG93LlwiLFxuICAgIFRhZ3M6IFwiU1NJLCBDb250cm9sLCBPd25lcnNoaXBcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJXcml0ZSBsb2dpYyBsaWtlIGl0IGJlbG9uZ3Mgd2l0aCB0aGUgZGF0YSBcXHUyMDE0IGJlY2F1c2UgaXQgZG9lcy5cIixcbiAgICBUYWdzOiBcIkRhdGEgTG9naWMsIERldmVsb3BlciwgU21hcnRcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJGcm9tIGJsb2NrY2hhaW4gY29udHJhY3RzIHRvIHNtYXJ0ZXIgZnJvbnRlbmRzLlwiLFxuICAgIFRhZ3M6IFwiU21hcnQgQ29udHJhY3RzLCBVSSwgRFhcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJObyBjYWZmZWluZS4gTm8gYm9pbGVycGxhdGUuIEp1c3QgdGhlIGZ1dHVyZS5cIixcbiAgICBUYWdzOiBcIk5vLUNSVUQsIENvZmZlZS10aGVtZWQsIEZ1dHVyaXN0aWNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJUaGUgZnV0dXJlIG9mIHdlYjMgVVggaXMgRGVjYWYtVFMuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBVWCwgVmlzaW9uXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQ29kZSB3aXRoIGNvbmZpZGVuY2UuIEdvdmVybiB3aXRoIGNsYXJpdHkuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBHb3Zlcm5hbmNlLCBDYWxtXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiSW50ZXJmYWNlcyB0aGF0IG9iZXkgdGhlIGRhdGEsIG5vdCB0aGUgb3RoZXIgd2F5IGFyb3VuZC5cIixcbiAgICBUYWdzOiBcIlVJLCBEYXRhIExvZ2ljLCBTZWxmLWF3YXJlXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQnJldyBidXNpbmVzcyBsb2dpYyByaWdodCBpbnRvIHlvdXIgYnl0ZXMuXCIsXG4gICAgVGFnczogXCJEYXRhIExvZ2ljLCBDb2ZmZWUtdGhlbWVkLCBGdW5cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJESURzIGRvbmUgZGlmZmVyZW50bHkgXFx1MjAxNCBhbmQgZGVsaWdodGZ1bGx5LlwiLFxuICAgIFRhZ3M6IFwiRElELCBTZWxmLVNvdmVyZWlnbiwgUGxheWZ1bFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRlY2FmLVRTLVRTOiBXaGVyZSBibG9ja2NoYWluIGNvbnRyYWN0cyBtZWV0IHNtYXJ0IGludGVyZmFjZXMuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBTbWFydCBDb250cmFjdHMsIFRlY2hcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTaGlwIGRBcHBzIHdpdGhvdXQgdGhlIHN0cmVzcy5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIENoZWVyZnVsLCBEZXZlbG9wZXJcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJObyBib2lsZXJwbGF0ZSwgbm8gcHJvYmxlbSBcXHUyMDE0IERlY2FmLVRTIHlvdXIgZGF0YS5cIixcbiAgICBUYWdzOiBcIkRhdGEsIE5vLUNSVUQsIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRnJvbSBESUQgdG8gVUksIHdpdGhvdXQgYnJlYWtpbmcgYSBzd2VhdC5cIixcbiAgICBUYWdzOiBcIkRJRCwgU1NJLCBVSSwgQ2FsbVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOlxuICAgICAgXCJEZWNhZi1UUy1UUzogWW91ciBmcm9udGVuZCBhbHJlYWR5IHVuZGVyc3RhbmRzIHlvdXIgYmxvY2tjaGFpbiBjb250cmFjdC5cIixcbiAgICBUYWdzOiBcIlNtYXJ0IENvbnRyYWN0cywgRFgsIE1hZ2ljXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiU2VsZi1zb3ZlcmVpZ24gYnkgZGVzaWduLiBQcm9kdWN0aXZlIGJ5IGRlZmF1bHQuXCIsXG4gICAgVGFnczogXCJTU0ksIERldmVsb3BlciwgQ2FsbVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkJ1aWxkIG9uY2UuIERlcGxveSBldmVyeXdoZXJlLiBEZWNlbnRyYWxpemVkIGFuZCBkZWxpZ2h0ZnVsLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgTXVsdGktcGxhdGZvcm0sIEhhcHB5XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRGF0YSB0aGF0IGRlZmluZXMgaXRzIG93biBkZXN0aW55LlwiLFxuICAgIFRhZ3M6IFwiU1NJLCBEYXRhLWRyaXZlbiwgRW1wb3dlcm1lbnRcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJHb29kYnllIGJvaWxlcnBsYXRlLCBoZWxsbyBpbnRlbnQtYmFzZWQgaW50ZXJmYWNlcy5cIixcbiAgICBUYWdzOiBcIk5vLUNSVUQsIFVJLCBUZWNobmljYWxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJUaGUgc21vb3RoZXN0IHBhdGggZnJvbSBESUQgdG8gZG9uZS5cIixcbiAgICBUYWdzOiBcIkRJRCwgV29ya2Zsb3csIENoaWxsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQmVjYXVzZSB5b3VyIGRBcHAgZGVzZXJ2ZXMgbW9yZSB0aGFuIGJvaWxlcnBsYXRlLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgRGV2WCwgRWZmaWNpZW5jeVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk93biB5b3VyIGRhdGEuIE93biB5b3VyIGZsb3cuXCIsXG4gICAgVGFnczogXCJTU0ksIENvbnRyb2wsIE93bmVyc2hpcFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIldyaXRlIGxvZ2ljIGxpa2UgaXQgYmVsb25ncyB3aXRoIHRoZSBkYXRhIFxcdTIwMTQgYmVjYXVzZSBpdCBkb2VzLlwiLFxuICAgIFRhZ3M6IFwiRGF0YSBMb2dpYywgRGV2ZWxvcGVyLCBTbWFydFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkZyb20gYmxvY2tjaGFpbiBjb250cmFjdHMgdG8gc21hcnRlciBmcm9udGVuZHMuXCIsXG4gICAgVGFnczogXCJTbWFydCBDb250cmFjdHMsIFVJLCBEWFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGNhZmZlaW5lLiBObyBib2lsZXJwbGF0ZS4gSnVzdCB0aGUgZnV0dXJlLlwiLFxuICAgIFRhZ3M6IFwiTm8tQ1JVRCwgQ29mZmVlLXRoZW1lZCwgRnV0dXJpc3RpY1wiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlRoZSBmdXR1cmUgb2Ygd2ViMyBVWCBpcyBEZWNhZi1UUy5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIFVYLCBWaXNpb25cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJDb2RlIHdpdGggY29uZmlkZW5jZS4gR292ZXJuIHdpdGggY2xhcml0eS5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIEdvdmVybmFuY2UsIENhbG1cIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJJbnRlcmZhY2VzIHRoYXQgb2JleSB0aGUgZGF0YSwgbm90IHRoZSBvdGhlciB3YXkgYXJvdW5kLlwiLFxuICAgIFRhZ3M6IFwiVUksIERhdGEgTG9naWMsIFNlbGYtYXdhcmVcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJCcmV3IGJ1c2luZXNzIGxvZ2ljIHJpZ2h0IGludG8geW91ciBieXRlcy5cIixcbiAgICBUYWdzOiBcIkRhdGEgTG9naWMsIENvZmZlZS10aGVtZWQsIEZ1blwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkRJRHMgZG9uZSBkaWZmZXJlbnRseSBcXHUyMDE0IGFuZCBkZWxpZ2h0ZnVsbHkuXCIsXG4gICAgVGFnczogXCJESUQsIFNlbGYtU292ZXJlaWduLCBQbGF5ZnVsXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRGVjYWYtVFMtVFM6IFdoZXJlIGJsb2NrY2hhaW4gY29udHJhY3RzIG1lZXQgc21hcnQgaW50ZXJmYWNlcy5cIixcbiAgICBUYWdzOiBcIkJsb2NrY2hhaW4sIFNtYXJ0IENvbnRyYWN0cywgVGVjaFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlNoaXAgZEFwcHMgd2l0aG91dCB0aGUgc3RyZXNzLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgQ2hlZXJmdWwsIERldmVsb3BlclwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIk5vIGJvaWxlcnBsYXRlLCBubyBwcm9ibGVtIFxcdTIwMTQgRGVjYWYtVFMgeW91ciBkYXRhLlwiLFxuICAgIFRhZ3M6IFwiRGF0YSwgTm8tQ1JVRCwgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJGcm9tIERJRCB0byBVSSwgd2l0aG91dCBicmVha2luZyBhIHN3ZWF0LlwiLFxuICAgIFRhZ3M6IFwiRElELCBTU0ksIFVJLCBDYWxtXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46XG4gICAgICBcIkRlY2FmLVRTLVRTOiBZb3VyIGZyb250ZW5kIGFscmVhZHkgdW5kZXJzdGFuZHMgeW91ciBibG9ja2NoYWluIGNvbnRyYWN0LlwiLFxuICAgIFRhZ3M6IFwiU21hcnQgQ29udHJhY3RzLCBEWCwgTWFnaWNcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJTZWxmLXNvdmVyZWlnbiBieSBkZXNpZ24uIFByb2R1Y3RpdmUgYnkgZGVmYXVsdC5cIixcbiAgICBUYWdzOiBcIlNTSSwgRGV2ZWxvcGVyLCBDYWxtXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiQnVpbGQgb25jZS4gRGVwbG95IGV2ZXJ5d2hlcmUuIERlY2VudHJhbGl6ZWQgYW5kIGRlbGlnaHRmdWwuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBNdWx0aS1wbGF0Zm9ybSwgSGFwcHlcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJEYXRhIHRoYXQgZGVmaW5lcyBpdHMgb3duIGRlc3RpbnkuXCIsXG4gICAgVGFnczogXCJTU0ksIERhdGEtZHJpdmVuLCBFbXBvd2VybWVudFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkdvb2RieWUgYm9pbGVycGxhdGUsIGhlbGxvIGludGVudC1iYXNlZCBpbnRlcmZhY2VzLlwiLFxuICAgIFRhZ3M6IFwiTm8tQ1JVRCwgVUksIFRlY2huaWNhbFwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIlRoZSBzbW9vdGhlc3QgcGF0aCBmcm9tIERJRCB0byBkb25lLlwiLFxuICAgIFRhZ3M6IFwiRElELCBXb3JrZmxvdywgQ2hpbGxcIixcbiAgfSxcbiAge1xuICAgIFNsb2dhbjogXCJCZWNhdXNlIHlvdXIgZEFwcCBkZXNlcnZlcyBtb3JlIHRoYW4gYm9pbGVycGxhdGUuXCIsXG4gICAgVGFnczogXCJCbG9ja2NoYWluLCBEZXZYLCBFZmZpY2llbmN5XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiT3duIHlvdXIgZGF0YS4gT3duIHlvdXIgZmxvdy5cIixcbiAgICBUYWdzOiBcIlNTSSwgQ29udHJvbCwgT3duZXJzaGlwXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiV3JpdGUgbG9naWMgbGlrZSBpdCBiZWxvbmdzIHdpdGggdGhlIGRhdGEgXFx1MjAxNCBiZWNhdXNlIGl0IGRvZXMuXCIsXG4gICAgVGFnczogXCJEYXRhIExvZ2ljLCBEZXZlbG9wZXIsIFNtYXJ0XCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRnJvbSBibG9ja2NoYWluIGNvbnRyYWN0cyB0byBzbWFydGVyIGZyb250ZW5kcy5cIixcbiAgICBUYWdzOiBcIlNtYXJ0IENvbnRyYWN0cywgVUksIERYXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiTm8gY2FmZmVpbmUuIE5vIGJvaWxlcnBsYXRlLiBKdXN0IHRoZSBmdXR1cmUuXCIsXG4gICAgVGFnczogXCJOby1DUlVELCBDb2ZmZWUtdGhlbWVkLCBGdXR1cmlzdGljXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiVGhlIGZ1dHVyZSBvZiB3ZWIzIFVYIGlzIERlY2FmLVRTLlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgVVgsIFZpc2lvblwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkNvZGUgd2l0aCBjb25maWRlbmNlLiBHb3Zlcm4gd2l0aCBjbGFyaXR5LlwiLFxuICAgIFRhZ3M6IFwiQmxvY2tjaGFpbiwgR292ZXJuYW5jZSwgQ2FsbVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkludGVyZmFjZXMgdGhhdCBvYmV5IHRoZSBkYXRhLCBub3QgdGhlIG90aGVyIHdheSBhcm91bmQuXCIsXG4gICAgVGFnczogXCJVSSwgRGF0YSBMb2dpYywgU2VsZi1hd2FyZVwiLFxuICB9LFxuICB7XG4gICAgU2xvZ2FuOiBcIkJyZXcgYnVzaW5lc3MgbG9naWMgcmlnaHQgaW50byB5b3VyIGJ5dGVzLlwiLFxuICAgIFRhZ3M6IFwiRGF0YSBMb2dpYywgQ29mZmVlLXRoZW1lZCwgRnVuXCIsXG4gIH0sXG4gIHtcbiAgICBTbG9nYW46IFwiRElEcyBkb25lIGRpZmZlcmVudGx5IFxcdTIwMTQgYW5kIGRlbGlnaHRmdWxseS5cIixcbiAgICBUYWdzOiBcIkRJRCwgU2VsZi1Tb3ZlcmVpZ24sIFBsYXlmdWxcIixcbiAgfSxcbl07XG4iLCJpbXBvcnQgeyBzbG9nYW5zIH0gZnJvbSBcIi4uL2Fzc2V0cy9zbG9nYW5zXCI7XG5pbXBvcnQgeyBzdHlsZSB9IGZyb20gXCJzdHlsZWQtc3RyaW5nLWJ1aWxkZXJcIjtcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBcnJheSBvZiBBTlNJIGNvbG9yIGNvZGVzIGZvciBiYW5uZXIgc3R5bGluZy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBzZXQgb2YgQU5TSSBjb2xvciBjb2RlcyB1c2VkIHRvIHN0eWxlIHRoZSBiYW5uZXIgdGV4dC5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuY29uc3QgY29sb3JzID0gW1xuICBcIlxceDFiWzM4OzU7MjE1bVwiLCAvLyBzb2Z0IG9yYW5nZVxuICBcIlxceDFiWzM4OzU7MjA5bVwiLCAvLyBjb3JhbFxuICBcIlxceDFiWzM4OzU7MjA1bVwiLCAvLyBwaW5rXG4gIFwiXFx4MWJbMzg7NTsyMTBtXCIsIC8vIHBlYWNoeVxuICBcIlxceDFiWzM4OzU7MjE3bVwiLCAvLyBzYWxtb25cbiAgXCJcXHgxYlszODs1OzIxNm1cIiwgLy8gbGlnaHQgY29yYWxcbiAgXCJcXHgxYlszODs1OzIyNG1cIiwgLy8gbGlnaHQgcGVhY2hcbiAgXCJcXHgxYlszODs1OzIzMG1cIiwgLy8gc29mdCBjcmVhbVxuICBcIlxceDFiWzM4OzU7MjMwbVwiLCAvLyBzb2Z0IGNyZWFtXG5dO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQcmludHMgYSBzdHlsZWQgYmFubmVyIHRvIHRoZSBjb25zb2xlLlxuICogQHN1bW1hcnkgR2VuZXJhdGVzIGFuZCBwcmludHMgYSBjb2xvcmZ1bCBBU0NJSSBhcnQgYmFubmVyIHdpdGggYSByYW5kb20gc2xvZ2FuLlxuICogQHBhcmFtIHtMb2dnZXJ9IFtsb2dnZXJdIC0gT3B0aW9uYWwgbG9nZ2VyIGZvciB2ZXJib3NlIG91dHB1dC5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqIEBmdW5jdGlvbiBwcmludEJhbm5lclxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBwcmludEJhbm5lclxuICogICBwYXJ0aWNpcGFudCBnZXRTbG9nYW5cbiAqICAgcGFydGljaXBhbnQgcGFkRW5kXG4gKiAgIHBhcnRpY2lwYW50IGNvbnNvbGVcbiAqICAgcHJpbnRCYW5uZXItPj5nZXRTbG9nYW46IENhbGwgZ2V0U2xvZ2FuKClcbiAqICAgZ2V0U2xvZ2FuLS0+PnByaW50QmFubmVyOiBSZXR1cm4gcmFuZG9tIHNsb2dhblxuICogICBwcmludEJhbm5lci0+PnByaW50QmFubmVyOiBDcmVhdGUgYmFubmVyIEFTQ0lJIGFydFxuICogICBwcmludEJhbm5lci0+PnByaW50QmFubmVyOiBTcGxpdCBiYW5uZXIgaW50byBsaW5lc1xuICogICBwcmludEJhbm5lci0+PnByaW50QmFubmVyOiBDYWxjdWxhdGUgbWF4IGxpbmUgbGVuZ3RoXG4gKiAgIHByaW50QmFubmVyLT4+cGFkRW5kOiBDYWxsIHBhZEVuZCB3aXRoIHNsb2dhblxuICogICBwYWRFbmQtLT4+cHJpbnRCYW5uZXI6IFJldHVybiBwYWRkZWQgc2xvZ2FuIGxpbmVcbiAqICAgbG9vcCBGb3IgZWFjaCBiYW5uZXIgbGluZVxuICogICAgIHByaW50QmFubmVyLT4+c3R5bGU6IENhbGwgc3R5bGUobGluZSlcbiAqICAgICBzdHlsZS0tPj5wcmludEJhbm5lcjogUmV0dXJuIHN0eWxlZCBsaW5lXG4gKiAgICAgcHJpbnRCYW5uZXItPj5jb25zb2xlOiBMb2cgc3R5bGVkIGxpbmVcbiAqICAgZW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmludEJhbm5lcihsb2dnZXI/OiBMb2dnZXIpIHtcbiAgY29uc3QgbWVzc2FnZSA9IGdldFNsb2dhbigpO1xuICBjb25zdCBiYW5uZXI6IHN0cmluZyB8IHN0cmluZ1tdID1cbiAgICBgIyAgICAgICAgICAgICAgICAg4paR4paS4paT4paI4paI4paI4paI4paI4paI4paI4paT4paS4paRICDilpHilpLilpPilojilojilojilojilojilojilojilojilpPilpLilpEgIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAgIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAg4paR4paS4paT4paI4paI4paI4paI4paI4paI4paI4paI4paT4paS4paRICAgICAgIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAg4paR4paS4paT4paI4paI4paI4paI4paI4paI4paI4paT4paS4paRIFxuIyAgICAgICggKCAgICAgICAg4paR4paS4paT4paI4paT4paS4paR4paR4paS4paT4paI4paT4paS4paRIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAgICAg4paR4paS4paT4paI4paT4paS4paR4paR4paS4paT4paI4paT4paS4paRIOKWkeKWkuKWk+KWiOKWk+KWkuKWkeKWkeKWkuKWk+KWiOKWk+KWkuKWkSDilpHilpLilpPilojilpPilpLilpEgICAgICAgICAgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAg4paR4paS4paT4paI4paT4paS4paRICAgICAgICBcbiMgICAgICAgKSApICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkeKWkeKWkuKWk+KWiOKWk+KWkuKWkSDilpHilpLilpPilojilpPilpLilpEgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAgICAg4paR4paS4paT4paI4paT4paS4paR4paR4paS4paT4paI4paT4paS4paRIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAgICAgICAgICAgICAg4paR4paS4paT4paI4paT4paS4paRICAgICDilpHilpLilpPilojilpPilpLilpEgICAgICAgIFxuIyAgICBbPT09PT09PV0gICAg4paR4paS4paT4paI4paT4paS4paR4paR4paS4paT4paI4paT4paS4paRIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAgICAg4paR4paS4paT4paI4paI4paI4paI4paI4paI4paI4paI4paT4paS4paRIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAgICAgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAgIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAgXG4jICAgICBcXGAtLS0tLcK0ICAgICDilpHilpLilpPilojilpPilpLilpHilpHilpLilpPilojilpPilpLilpEg4paR4paS4paT4paI4paT4paS4paRICAgICAgICDilpHilpLilpPilojilpPilpLilpEgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkeKWkeKWkuKWk+KWiOKWk+KWkuKWkSDilpHilpLilpPilojilpPilpLilpEgICAgICAgICAgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSAgICAgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkSBcbiMgICAgICAgICAgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkeKWkeKWkuKWk+KWiOKWk+KWkuKWkSDilpHilpLilpPilojilpPilpLilpEgICAgICAgIOKWkeKWkuKWk+KWiOKWk+KWkuKWkeKWkeKWkuKWk+KWiOKWk+KWkuKWkSDilpHilpLilpPilojilpPilpLilpHilpHilpLilpPilojilpPilpLilpEg4paR4paS4paT4paI4paT4paS4paRICAgICAgICAgICAgICAgICDilpHilpLilpPilojilpPilpLilpEgICAgICAgICAgICDilpHilpLilpPilojilpPilpLilpEgXG4jICAgICAgICAgICAgICAgICDilpHilpLilpPilojilojilojilojilojilojilojilpPilpLilpEgIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAg4paR4paS4paT4paI4paI4paI4paI4paI4paI4paT4paS4paRICDilpHilpLilpPilojilpPilpLilpHilpHilpLilpPilojilpPilpLilpEg4paR4paS4paT4paI4paT4paS4paRICAgICAgICAgICAgICAgICDilpHilpLilpPilojilpPilpLilpEgICAgIOKWkeKWkuKWk+KWiOKWiOKWiOKWiOKWiOKWiOKWiOKWk+KWkuKWkSAgXG4jYC5zcGxpdChcIlxcblwiKTtcbiAgY29uc3QgbWF4TGVuZ3RoID0gYmFubmVyLnJlZHVjZSgobWF4LCBsaW5lKSA9PiBNYXRoLm1heChtYXgsIGxpbmUubGVuZ3RoKSwgMCk7XG4gIGJhbm5lci5wdXNoKGAjICAke21lc3NhZ2UucGFkU3RhcnQobWF4TGVuZ3RoIC0gMyl9YCk7XG4gIGJhbm5lci5mb3JFYWNoKChsaW5lLCBpbmRleCkgPT4ge1xuICAgIChsb2dnZXIgPyBsb2dnZXIuaW5mby5iaW5kKGxvZ2dlcikgOiBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpKShcbiAgICAgIHN0eWxlKGxpbmUgfHwgXCJcIikucmF3KGNvbG9yc1tpbmRleF0pLnRleHRcbiAgICApO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgc2xvZ2FuIGZyb20gdGhlIHByZWRlZmluZWQgbGlzdC5cbiAqIEBzdW1tYXJ5IEZldGNoZXMgYSByYW5kb20gc2xvZ2FuIG9yIGEgc3BlY2lmaWMgb25lIGJ5IGluZGV4IGZyb20gdGhlIHNsb2dhbnMgbGlzdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbaV0gLSBPcHRpb25hbCBpbmRleCB0byByZXRyaWV2ZSBhIHNwZWNpZmljIHNsb2dhbi5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHNlbGVjdGVkIHNsb2dhbi5cbiAqIEBmdW5jdGlvbiBnZXRTbG9nYW5cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgZ2V0U2xvZ2FuXG4gKiAgIHBhcnRpY2lwYW50IE1hdGgucmFuZG9tXG4gKiAgIHBhcnRpY2lwYW50IHNsb2dhbnNcbiAqICAgYWx0IGkgaXMgdW5kZWZpbmVkXG4gKiAgICAgZ2V0U2xvZ2FuLT4+TWF0aC5yYW5kb206IEdlbmVyYXRlIHJhbmRvbSBpbmRleFxuICogICAgIE1hdGgucmFuZG9tLS0+PmdldFNsb2dhbjogUmV0dXJuIHJhbmRvbSBpbmRleFxuICogICBlbHNlIGkgaXMgZGVmaW5lZFxuICogICAgIE5vdGUgb3ZlciBnZXRTbG9nYW46IFVzZSBwcm92aWRlZCBpbmRleFxuICogICBlbmRcbiAqICAgZ2V0U2xvZ2FuLT4+c2xvZ2FuczogQWNjZXNzIHNsb2dhbiBhdCBpbmRleFxuICogICBzbG9nYW5zLS0+PmdldFNsb2dhbjogUmV0dXJuIHNsb2dhblxuICogICBhbHQgRXJyb3Igb2NjdXJzXG4gKiAgICAgZ2V0U2xvZ2FuLT4+Z2V0U2xvZ2FuOiBUaHJvdyBlcnJvclxuICogICBlbmRcbiAqICAgZ2V0U2xvZ2FuLS0+PkNhbGxlcjogUmV0dXJuIHNsb2dhblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2xvZ2FuKGk/OiBudW1iZXIpOiBzdHJpbmcge1xuICB0cnkge1xuICAgIGkgPVxuICAgICAgdHlwZW9mIGkgPT09IFwidW5kZWZpbmVkXCIgPyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBzbG9nYW5zLmxlbmd0aCkgOiBpO1xuICAgIHJldHVybiBzbG9nYW5zW2ldLlNsb2dhbjtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byByZXRyaWV2ZSBzbG9nYW5zOiAke2Vycm9yfWApO1xuICB9XG59XG4iLCJpbXBvcnQgeyBQYXJzZUFyZ3NSZXN1bHQgfSBmcm9tIFwiLi4vaW5wdXQvdHlwZXNcIjtcbmltcG9ydCB7IENvbW1hbmRPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFVzZXJJbnB1dCB9IGZyb20gXCIuLi9pbnB1dC9pbnB1dFwiO1xuaW1wb3J0IHsgRGVmYXVsdENvbW1hbmRPcHRpb25zLCBEZWZhdWx0Q29tbWFuZFZhbHVlcyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgZ2V0RGVwZW5kZW5jaWVzLCBnZXRQYWNrYWdlVmVyc2lvbiB9IGZyb20gXCIuLi91dGlscy9mc1wiO1xuaW1wb3J0IHsgcHJpbnRCYW5uZXIgfSBmcm9tIFwiLi4vb3V0cHV0L2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgTG9nZ2VkQ2xhc3MsXG4gIExvZ2dlZEVudmlyb25tZW50LFxuICBMb2dnZXIsXG4gIExvZ2dpbmcsXG4gIExvZ2dpbmdDb25maWcsXG59IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG4vKipcbiAqIEBjbGFzcyBDb21tYW5kXG4gKiBAYWJzdHJhY3RcbiAqIEB0ZW1wbGF0ZSBJIC0gVGhlIHR5cGUgb2YgaW5wdXQgb3B0aW9ucyBmb3IgdGhlIGNvbW1hbmQuXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXR1cm4gdHlwZSBvZiB0aGUgY29tbWFuZCBleGVjdXRpb24uXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKiBAZGVzY3JpcHRpb24gQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgY29tbWFuZCBpbXBsZW1lbnRhdGlvbi5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgc3RydWN0dXJlIGZvciBjcmVhdGluZyBjb21tYW5kLWxpbmUgaW50ZXJmYWNlIGNvbW1hbmRzIHdpdGggaW5wdXQgaGFuZGxpbmcsIGxvZ2dpbmcsIGFuZCBleGVjdXRpb24gZmxvdy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBjb21tYW5kLlxuICogQHBhcmFtIHtDb21tYW5kT3B0aW9uczxJPn0gW2lucHV0c10gLSBUaGUgaW5wdXQgb3B0aW9ucyBmb3IgdGhlIGNvbW1hbmQuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbcmVxdWlyZW1lbnRzXSAtIFRoZSBsaXN0IG9mIHJlcXVpcmVkIGRlcGVuZGVuY2llcyBmb3IgdGhlIGNvbW1hbmQuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDb21tYW5kPEksIFI+IGV4dGVuZHMgTG9nZ2VkQ2xhc3Mge1xuICAvKipcbiAgICogQHN0YXRpY1xuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIGxvZ2dlciBmb3IgdGhlIENvbW1hbmQgY2xhc3MuXG4gICAqIEB0eXBlIHtMb2dnZXJ9XG4gICAqL1xuICBzdGF0aWMgbG9nOiBMb2dnZXI7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBuYW1lOiBzdHJpbmcsXG4gICAgcHJvdGVjdGVkIGlucHV0czogQ29tbWFuZE9wdGlvbnM8ST4gPSB7fSBhcyB1bmtub3duIGFzIENvbW1hbmRPcHRpb25zPEk+LFxuICAgIHByb3RlY3RlZCByZXF1aXJlbWVudHM6IHN0cmluZ1tdID0gW11cbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAoIUNvbW1hbmQubG9nKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29tbWFuZCwgXCJsb2dcIiwge1xuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBMb2dnaW5nLmZvcihDb21tYW5kLm5hbWUpLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuaW5wdXRzID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHt9LFxuICAgICAgRGVmYXVsdENvbW1hbmRPcHRpb25zLFxuICAgICAgaW5wdXRzXG4gICAgKSBhcyBDb21tYW5kT3B0aW9uczxJPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBhc3luY1xuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGFsbCByZXF1aXJlZCBkZXBlbmRlbmNpZXMgYXJlIHByZXNlbnQuXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgbGlzdCBvZiBkZXBlbmRlbmNpZXMgYW5kIGNvbXBhcmVzIGl0IGFnYWluc3QgdGhlIHJlcXVpcmVkIGRlcGVuZGVuY2llcyBmb3IgdGhlIGNvbW1hbmQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjaGVjayBpcyBjb21wbGV0ZS5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ29tbWFuZFxuICAgKiAgIHBhcnRpY2lwYW50IGdldERlcGVuZGVuY2llc1xuICAgKiAgIHBhcnRpY2lwYW50IFNldFxuICAgKiAgIENvbW1hbmQtPj5nZXREZXBlbmRlbmNpZXM6IENhbGxcbiAgICogICBnZXREZXBlbmRlbmNpZXMtLT4+Q29tbWFuZDogUmV0dXJuIHtwcm9kLCBkZXYsIHBlZXJ9XG4gICAqICAgQ29tbWFuZC0+PlNldDogQ3JlYXRlIFNldCBmcm9tIHByb2QsIGRldiwgcGVlclxuICAgKiAgIFNldC0tPj5Db21tYW5kOiBSZXR1cm4gdW5pcXVlIGRlcGVuZGVuY2llc1xuICAgKiAgIENvbW1hbmQtPj5Db21tYW5kOiBDb21wYXJlIGFnYWluc3QgcmVxdWlyZW1lbnRzXG4gICAqICAgYWx0IE1pc3NpbmcgZGVwZW5kZW5jaWVzXG4gICAqICAgICBDb21tYW5kLT4+Q29tbWFuZDogQWRkIHRvIG1pc3NpbmcgbGlzdFxuICAgKiAgIGVuZFxuICAgKiAgIE5vdGUgb3ZlciBDb21tYW5kOiBJZiBtaXNzaW5nLmxlbmd0aCA+IDAsIGhhbmRsZSBtaXNzaW5nIGRlcGVuZGVuY2llc1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGNoZWNrUmVxdWlyZW1lbnRzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgcHJvZCwgZGV2LCBwZWVyIH0gPSBhd2FpdCBnZXREZXBlbmRlbmNpZXMoKTtcbiAgICBjb25zdCBtaXNzaW5nID0gW107XG4gICAgY29uc3QgZnVsbExpc3QgPSBBcnJheS5mcm9tKFxuICAgICAgbmV3IFNldChbLi4ucHJvZCwgLi4uZGV2LCAuLi5wZWVyXSkudmFsdWVzKClcbiAgICApLm1hcCgoZCkgPT4gZC5uYW1lKTtcbiAgICBmb3IgKGNvbnN0IGRlcCBvZiB0aGlzLnJlcXVpcmVtZW50cylcbiAgICAgIGlmICghZnVsbExpc3QuaW5jbHVkZXMoZGVwKSkgbWlzc2luZy5wdXNoKGRlcCk7XG5cbiAgICBpZiAoIW1pc3NpbmcubGVuZ3RoKSByZXR1cm47XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAZGVzY3JpcHRpb24gUHJvdmlkZXMgaGVscCBpbmZvcm1hdGlvbiBmb3IgdGhlIGNvbW1hbmQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuIGluIGRlcml2ZWQgY2xhc3NlcyB0byBwcm92aWRlIHNwZWNpZmljIGhlbHAgaW5mb3JtYXRpb24uXG4gICAqIEBwYXJhbSB7UGFyc2VBcmdzUmVzdWx0fSBhcmdzIC0gVGhlIHBhcnNlZCBjb21tYW5kLWxpbmUgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcHJvdGVjdGVkIGhlbHAoYXJnczogUGFyc2VBcmdzUmVzdWx0KTogdm9pZCB7XG4gICAgcmV0dXJuIHRoaXMubG9nLmluZm8oXG4gICAgICBgVGhpcyBpcyBoZWxwLiBJJ20gbm8gdXNlIGJlY2F1c2UgSSBzaG91bGQgaGF2ZSBiZWVuIG92ZXJyaWRkZW4uYFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAYWJzdHJhY3RcbiAgICogQGRlc2NyaXB0aW9uIFJ1bnMgdGhlIGNvbW1hbmQgd2l0aCB0aGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBzaG91bGQgYmUgaW1wbGVtZW50ZWQgaW4gZGVyaXZlZCBjbGFzc2VzIHRvIGRlZmluZSB0aGUgY29tbWFuZCdzIGJlaGF2aW9yLlxuICAgKiBAcGFyYW0ge1BhcnNlQXJnc1Jlc3VsdH0gYW5zd2VycyAtIFRoZSBwYXJzZWQgY29tbWFuZC1saW5lIGFyZ3VtZW50cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8UiB8IHN0cmluZyB8IHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBjb21tYW5kJ3MgcmVzdWx0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHJ1bjxSPihcbiAgICBhbnN3ZXJzOiBMb2dnaW5nQ29uZmlnICZcbiAgICAgIHR5cGVvZiBEZWZhdWx0Q29tbWFuZFZhbHVlcyAmIHsgW2sgaW4ga2V5b2YgSV06IHVua25vd24gfVxuICApOiBQcm9taXNlPFIgfCBzdHJpbmcgfCB2b2lkPjtcblxuICAvKipcbiAgICogQGFzeW5jXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyB0aGUgY29tbWFuZC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgb3ZlcmFsbCBleGVjdXRpb24gZmxvdyBvZiB0aGUgY29tbWFuZCwgaW5jbHVkaW5nIHBhcnNpbmcgYXJndW1lbnRzLFxuICAgKiBzZXR0aW5nIHVwIGxvZ2dpbmcsIGNoZWNraW5nIGZvciB2ZXJzaW9uIG9yIGhlbHAgcmVxdWVzdHMsIGFuZCBydW5uaW5nIHRoZSBjb21tYW5kLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSIHwgc3RyaW5nIHwgdm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGNvbW1hbmQncyByZXN1bHQuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENvbW1hbmRcbiAgICogICBwYXJ0aWNpcGFudCBVc2VySW5wdXRcbiAgICogICBwYXJ0aWNpcGFudCBMb2dnaW5nXG4gICAqICAgcGFydGljaXBhbnQgZ2V0UGFja2FnZVZlcnNpb25cbiAgICogICBwYXJ0aWNpcGFudCBwcmludEJhbm5lclxuICAgKiAgIENvbW1hbmQtPj5Vc2VySW5wdXQ6IHBhcnNlQXJncyhpbnB1dHMpXG4gICAqICAgVXNlcklucHV0LS0+PkNvbW1hbmQ6IFJldHVybiBQYXJzZUFyZ3NSZXN1bHRcbiAgICogICBDb21tYW5kLT4+Q29tbWFuZDogUHJvY2VzcyBvcHRpb25zXG4gICAqICAgQ29tbWFuZC0+PkxvZ2dpbmc6IHNldENvbmZpZyhvcHRpb25zKVxuICAgKiAgIGFsdCB2ZXJzaW9uIHJlcXVlc3RlZFxuICAgKiAgICAgQ29tbWFuZC0+PmdldFBhY2thZ2VWZXJzaW9uOiBDYWxsXG4gICAqICAgICBnZXRQYWNrYWdlVmVyc2lvbi0tPj5Db21tYW5kOiBSZXR1cm4gdmVyc2lvblxuICAgKiAgIGVsc2UgaGVscCByZXF1ZXN0ZWRcbiAgICogICAgIENvbW1hbmQtPj5Db21tYW5kOiBoZWxwKGFyZ3MpXG4gICAqICAgZWxzZSBiYW5uZXIgcmVxdWVzdGVkXG4gICAqICAgICBDb21tYW5kLT4+cHJpbnRCYW5uZXI6IENhbGxcbiAgICogICBlbmRcbiAgICogICBDb21tYW5kLT4+Q29tbWFuZDogcnVuKGFyZ3MpXG4gICAqICAgYWx0IGVycm9yIG9jY3Vyc1xuICAgKiAgICAgQ29tbWFuZC0+PkNvbW1hbmQ6IExvZyBlcnJvclxuICAgKiAgIGVuZFxuICAgKiAgIENvbW1hbmQtLT4+Q29tbWFuZDogUmV0dXJuIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZSgpOiBQcm9taXNlPFIgfCBzdHJpbmcgfCB2b2lkPiB7XG4gICAgY29uc3QgYXJnczogUGFyc2VBcmdzUmVzdWx0ID0gVXNlcklucHV0LnBhcnNlQXJncyh0aGlzLmlucHV0cyk7XG4gICAgY29uc3QgZW52ID0gTG9nZ2VkRW52aXJvbm1lbnQuYWNjdW11bGF0ZShEZWZhdWx0Q29tbWFuZFZhbHVlcykuYWNjdW11bGF0ZShcbiAgICAgIGFyZ3MudmFsdWVzXG4gICAgKTtcbiAgICBjb25zdCB7IHZlcnNpb24sIGhlbHAsIGJhbm5lciB9ID0gZW52O1xuXG4gICAgaWYgKHZlcnNpb24pIHtcbiAgICAgIHJldHVybiBnZXRQYWNrYWdlVmVyc2lvbigpO1xuICAgIH1cblxuICAgIGlmIChoZWxwKSB7XG4gICAgICByZXR1cm4gdGhpcy5oZWxwKGFyZ3MpO1xuICAgIH1cblxuICAgIGlmIChiYW5uZXIpXG4gICAgICBwcmludEJhbm5lcihcbiAgICAgICAgdGhpcy5sb2cuZm9yKHByaW50QmFubmVyLCB7XG4gICAgICAgICAgdGltZXN0YW1wOiBmYWxzZSxcbiAgICAgICAgICBzdHlsZTogZmFsc2UsXG4gICAgICAgICAgY29udGV4dDogZmFsc2UsXG4gICAgICAgICAgbG9nTGV2ZWw6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIGxldCByZXN1bHQ7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY2F0Y2hcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgdGhpcy5ydW4oZW52IGFzIGFueSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0IGFzIFI7XG4gIH1cbn1cbiIsIi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG5pbXBvcnQgaHR0cHMgZnJvbSBcImh0dHBzXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgc2ltcGxlIEhUVFAgY2xpZW50IGZvciBkb3dubG9hZGluZyBmaWxlcy5cbiAqIEBzdW1tYXJ5IFRoaXMgY2xhc3MgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSB0byBkb3dubG9hZCBmaWxlcyBmcm9tIEhUVFBTIFVSTHMuXG4gKiBJdCB1c2VzIE5vZGUuanMgYnVpbHQtaW4gaHR0cHMgbW9kdWxlIHRvIG1ha2UgcmVxdWVzdHMuXG4gKlxuICogQGNsYXNzIEh0dHBDbGllbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEh0dHBDbGllbnQge1xuICBwcm90ZWN0ZWQgc3RhdGljIGxvZyA9IExvZ2dpbmcuZm9yKEh0dHBDbGllbnQpO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERvd25sb2FkcyBhIGZpbGUgZnJvbSBhIGdpdmVuIFVSTC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2Qgc2VuZHMgYSBHRVQgcmVxdWVzdCB0byB0aGUgc3BlY2lmaWVkIFVSTCBhbmQgcmV0dXJucyB0aGUgcmVzcG9uc2UgYm9keSBhcyBhIHN0cmluZy5cbiAgICogSXQgaGFuZGxlcyBkaWZmZXJlbnQgc2NlbmFyaW9zIHN1Y2ggYXMgbm9uLTIwMCBzdGF0dXMgY29kZXMgYW5kIG5ldHdvcmsgZXJyb3JzLlxuICAgKlxuICAgKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCBvZiB0aGUgZmlsZSB0byBkb3dubG9hZC5cbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBmaWxlIGNvbnRlbnQgYXMgYSBzdHJpbmcuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IEh0dHBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBIVFRQU1xuICAgKiAgIHBhcnRpY2lwYW50IFNlcnZlclxuICAgKiAgIENsaWVudC0+Pkh0dHBDbGllbnQ6IGRvd25sb2FkRmlsZSh1cmwpXG4gICAqICAgSHR0cENsaWVudC0+PkhUVFBTOiBnZXQodXJsKVxuICAgKiAgIEhUVFBTLT4+U2VydmVyOiBHRVQgcmVxdWVzdFxuICAgKiAgIFNlcnZlci0tPj5IVFRQUzogUmVzcG9uc2VcbiAgICogICBIVFRQUy0tPj5IdHRwQ2xpZW50OiBSZXNwb25zZSBvYmplY3RcbiAgICogICBhbHQgU3RhdHVzIGNvZGUgaXMgMjAwXG4gICAqICAgICBsb29wIEZvciBlYWNoIGRhdGEgY2h1bmtcbiAgICogICAgICAgSFRUUFMtPj5IdHRwQ2xpZW50OiAnZGF0YScgZXZlbnRcbiAgICogICAgICAgSHR0cENsaWVudC0+Pkh0dHBDbGllbnQ6IEFjY3VtdWxhdGUgZGF0YVxuICAgKiAgICAgZW5kXG4gICAqICAgICBIVFRQUy0+Pkh0dHBDbGllbnQ6ICdlbmQnIGV2ZW50XG4gICAqICAgICBIdHRwQ2xpZW50LS0+PkNsaWVudDogUmVzb2x2ZSB3aXRoIGRhdGFcbiAgICogICBlbHNlIFN0YXR1cyBjb2RlIGlzIG5vdCAyMDBcbiAgICogICAgIEh0dHBDbGllbnQtLT4+Q2xpZW50OiBSZWplY3Qgd2l0aCBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGRvd25sb2FkRmlsZSh1cmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZnVuY3Rpb24gcmVxdWVzdCh1cmw6IHN0cmluZykge1xuICAgICAgICB1cmwgPSBlbmNvZGVVUkkodXJsKTtcbiAgICAgICAgaHR0cHMuZ2V0KHVybCwgKHJlcykgPT4ge1xuICAgICAgICAgIGlmIChyZXMuc3RhdHVzQ29kZSA9PT0gMzAxIHx8IHJlcy5zdGF0dXNDb2RlID09PSAzMDcpXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdChyZXMuaGVhZGVycy5sb2NhdGlvbiBhcyBzdHJpbmcpO1xuXG4gICAgICAgICAgaWYgKHJlcy5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgICAgIEh0dHBDbGllbnQubG9nLmVycm9yKFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIGZldGNoICR7dXJsfSAoc3RhdHVzOiAke3Jlcy5zdGF0dXNDb2RlfSlgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCAke3VybH1gKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxldCBkYXRhID0gXCJcIjtcbiAgICAgICAgICByZXMub24oXCJkYXRhXCIsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXMub24oXCJlcnJvclwiLCAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXMub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXF1ZXN0KHVybCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiLi4vY29tbWFuZFwiO1xuaW1wb3J0IHsgQ29tbWFuZE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IERlZmF1bHRDb21tYW5kT3B0aW9ucywgRGVmYXVsdENvbW1hbmRWYWx1ZXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBjb3B5RmlsZSxcbiAgZGVsZXRlUGF0aCxcbiAgZ2V0QWxsRmlsZXMsXG4gIGdldFBhY2thZ2UsXG4gIHBhdGNoRmlsZSxcbiAgcmVuYW1lRmlsZSxcbiAgcnVuQ29tbWFuZCxcbiAgZ2V0RmlsZVNpemVaaXBwZWQsXG4gIGxpc3ROb2RlTW9kdWxlc1BhY2thZ2VzLFxufSBmcm9tIFwiLi4vLi4vdXRpbHNcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBJbnB1dE9wdGlvbnMsIE91dHB1dE9wdGlvbnMsIHJvbGx1cCwgUm9sbHVwQnVpbGQgfSBmcm9tIFwicm9sbHVwXCI7XG5pbXBvcnQgdHlwZXNjcmlwdCBmcm9tIFwiQHJvbGx1cC9wbHVnaW4tdHlwZXNjcmlwdFwiO1xuaW1wb3J0IGNvbW1vbmpzIGZyb20gXCJAcm9sbHVwL3BsdWdpbi1jb21tb25qc1wiO1xuaW1wb3J0IHsgbm9kZVJlc29sdmUgfSBmcm9tIFwiQHJvbGx1cC9wbHVnaW4tbm9kZS1yZXNvbHZlXCI7XG5pbXBvcnQganNvbiBmcm9tIFwiQHJvbGx1cC9wbHVnaW4tanNvblwiO1xuaW1wb3J0IHsgYnVpbHRpbk1vZHVsZXMgfSBmcm9tIFwibW9kdWxlXCI7XG5pbXBvcnQgeyBMb2dnaW5nQ29uZmlnLCBMb2dMZXZlbCB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuXG4vLyBkZWNsYXJlIG9wdGlvbmFsIHRlcnNlciBtb2R1bGUgdG8gc2F0aXNmeSBUeXBlU2NyaXB0IHdoZW4gdHlwZXMgYXJlbid0IGluc3RhbGxlZFxuZGVjbGFyZSBtb2R1bGUgXCJAcm9sbHVwL3BsdWdpbi10ZXJzZXJcIjtcblxuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcbmltcG9ydCB7IERpYWdub3N0aWMsIEVtaXRSZXN1bHQsIE1vZHVsZUtpbmQsIFNvdXJjZUZpbGUgfSBmcm9tIFwidHlwZXNjcmlwdFwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VMaXN0KGlucHV0Pzogc3RyaW5nIHwgc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gIGlmICghaW5wdXQpIHJldHVybiBbXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpKVxuICAgIHJldHVybiBpbnB1dC5tYXAoKGkpID0+IGAke2l9YC50cmltKCkpLmZpbHRlcihCb29sZWFuKTtcbiAgcmV0dXJuIGAke2lucHV0fWBcbiAgICAuc3BsaXQoXCIsXCIpXG4gICAgLm1hcCgocCkgPT4gcC50cmltKCkpXG4gICAgLmZpbHRlcihCb29sZWFuKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhY2thZ2VUb0dsb2JhbChuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBSZW1vdmUgc2NvcGUgYW5kIHNwbGl0IGJ5IG5vbi1hbHBoYW51bWVyaWMgY2hhcnMsIHRoZW4gY2FtZWxDYXNlXG4gIGNvbnN0IHdpdGhvdXRTY29wZSA9IG5hbWUucmVwbGFjZSgvXkAvLCBcIlwiKTtcbiAgY29uc3QgcGFydHMgPSB3aXRob3V0U2NvcGUuc3BsaXQoL1svXFwtXy5dKy8pLmZpbHRlcihCb29sZWFuKTtcbiAgcmV0dXJuIHBhcnRzXG4gICAgLm1hcCgocCwgaSkgPT5cbiAgICAgIGkgPT09IDBcbiAgICAgICAgPyBwLnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCBcIlwiKVxuICAgICAgICA6IGAke3AuY2hhckF0KDApLnRvVXBwZXJDYXNlKCl9JHtwLnNsaWNlKDEpfWBcbiAgICApXG4gICAgLmpvaW4oXCJcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWNrYWdlRGVwZW5kZW5jaWVzKCk6IHN0cmluZ1tdIHtcbiAgLy8gVHJ5IHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IGZpcnN0XG4gIGxldCBwa2c6IGFueTtcbiAgdHJ5IHtcbiAgICBwa2cgPSBnZXRQYWNrYWdlKHByb2Nlc3MuY3dkKCkpIGFzIGFueTtcbiAgfSBjYXRjaCB7XG4gICAgcGtnID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gSWYgbm8gZGVwZW5kZW5jaWVzIGZvdW5kIGluIGN3ZCwgdHJ5IHRoZSBwYWNrYWdlIG5leHQgdG8gdGhpcyBzb3VyY2UgZmlsZSAoZmFsbGJhY2sgZm9yIHRlc3RzKVxuICB0cnkge1xuICAgIGNvbnN0IGhhc0RlcHMgPVxuICAgICAgcGtnICYmXG4gICAgICAoT2JqZWN0LmtleXMocGtnLmRlcGVuZGVuY2llcyB8fCB7fSkubGVuZ3RoID4gMCB8fFxuICAgICAgICBPYmplY3Qua2V5cyhwa2cuZGV2RGVwZW5kZW5jaWVzIHx8IHt9KS5sZW5ndGggPiAwIHx8XG4gICAgICAgIE9iamVjdC5rZXlzKHBrZy5wZWVyRGVwZW5kZW5jaWVzIHx8IHt9KS5sZW5ndGggPiAwKTtcbiAgICBpZiAoIWhhc0RlcHMpIHtcbiAgICAgIGNvbnN0IGZhbGxiYWNrRGlyID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCIuLi8uLi8uLlwiKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBrZyA9IGdldFBhY2thZ2UoZmFsbGJhY2tEaXIpIGFzIGFueTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBpZ25vcmUgYW5kIGtlZXAgcGtnIGFzLWlzXG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICAvLyBpZ25vcmVcbiAgfVxuXG4gIGNvbnN0IGRlcHMgPSBPYmplY3Qua2V5cygocGtnICYmIHBrZy5kZXBlbmRlbmNpZXMpIHx8IHt9KTtcbiAgY29uc3QgcGVlciA9IE9iamVjdC5rZXlzKChwa2cgJiYgcGtnLnBlZXJEZXBlbmRlbmNpZXMpIHx8IHt9KTtcbiAgY29uc3QgZGV2ID0gT2JqZWN0LmtleXMoKHBrZyAmJiBwa2cuZGV2RGVwZW5kZW5jaWVzKSB8fCB7fSk7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmRlcHMsIC4uLnBlZXIsIC4uLmRldl0pKTtcbn1cblxuY29uc3QgVkVSU0lPTl9TVFJJTkcgPSBcIiMjVkVSU0lPTiMjXCI7XG5jb25zdCBQQUNLQUdFX1NUUklORyA9IFwiIyNQQUNLQUdFIyNcIjtcbmNvbnN0IFBBQ0tBR0VfU0laRV9TVFJJTkcgPSBcIiMjUEFDS0FHRV9TSVpFIyNcIjtcblxuZW51bSBNb2RlcyB7XG4gIENKUyA9IFwiY29tbW9uanNcIixcbiAgRVNNID0gXCJlczIwMjJcIixcbn1cblxuZW51bSBCdWlsZE1vZGUge1xuICBCVUlMRCA9IFwiYnVpbGRcIixcbiAgQlVORExFID0gXCJidW5kbGVcIixcbiAgQUxMID0gXCJhbGxcIixcbn1cblxuY29uc3Qgb3B0aW9ucyA9IHtcbiAgcHJvZDoge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBkZXY6IHtcbiAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgYnVpbGRNb2RlOiB7XG4gICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICBkZWZhdWx0OiBCdWlsZE1vZGUuQUxMLFxuICB9LFxuICBpbmNsdWRlczoge1xuICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgZGVmYXVsdDogXCJcIixcbiAgfSxcbiAgZXh0ZXJuYWxzOiB7XG4gICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICBkZWZhdWx0OiBcIlwiLFxuICB9LFxuICBkb2NzOiB7XG4gICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGNvbW1hbmRzOiB7XG4gICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGJhbm5lcjoge1xuICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxufTtcblxuY29uc3QgY2pzMlRyYW5zZm9ybWVyID0gKGV4dCA9IFwiLmNqc1wiKSA9PiB7XG4gIGNvbnN0IGxvZyA9IEJ1aWxkU2NyaXB0cy5sb2cuZm9yKGNqczJUcmFuc2Zvcm1lcik7XG4gIGNvbnN0IHJlc29sdXRpb25DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbiAgcmV0dXJuICh0cmFuc2Zvcm1hdGlvbkNvbnRleHQ6IHRzLlRyYW5zZm9ybWF0aW9uQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoc291cmNlRmlsZTogdHMuU291cmNlRmlsZSkgPT4ge1xuICAgICAgY29uc3Qgc291cmNlRGlyID0gcGF0aC5kaXJuYW1lKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuXG4gICAgICBmdW5jdGlvbiByZXNvbHZlUGF0aChpbXBvcnRQYXRoOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgY2FjaGVLZXkgPSBKU09OLnN0cmluZ2lmeShbc291cmNlRGlyLCBpbXBvcnRQYXRoXSk7XG4gICAgICAgIGNvbnN0IGNhY2hlZFZhbHVlID0gcmVzb2x1dGlvbkNhY2hlLmdldChjYWNoZUtleSk7XG4gICAgICAgIGlmIChjYWNoZWRWYWx1ZSAhPSBudWxsKSByZXR1cm4gY2FjaGVkVmFsdWU7XG5cbiAgICAgICAgbGV0IHJlc29sdmVkUGF0aCA9IGltcG9ydFBhdGg7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcGF0aC5yZXNvbHZlKHNvdXJjZURpciwgcmVzb2x2ZWRQYXRoICsgXCIudHNcIik7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcmVzb2x2ZSBwYXRoICR7aW1wb3J0UGF0aH06ICR7ZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0YXQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgc3RhdCA9IGZzLnN0YXRTeW5jKHJlc29sdmVkUGF0aCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbG9nLnZlcmJvc2UoXG4gICAgICAgICAgICAgIGBUZXN0aW5nIGV4aXN0ZW5jZSBvZiBwYXRoICR7cmVzb2x2ZWRQYXRofSBhcyBhIGZvbGRlciBkZWZhdWx0aW5nIHRvIGluZGV4IGZpbGVgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc3RhdCA9IGZzLnN0YXRTeW5jKHJlc29sdmVkUGF0aC5yZXBsYWNlKC9cXC50cyQvZ20sIFwiXCIpKTtcbiAgICAgICAgICB9IGNhdGNoIChlMjogdW5rbm93bikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIHJlc29sdmUgcGF0aCAke2ltcG9ydFBhdGh9OiAke2V9LCAke2UyfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkpXG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZWRQYXRoLnJlcGxhY2UoL1xcLnRzJC9nbSwgXCIvaW5kZXgudHNcIik7XG5cbiAgICAgICAgaWYgKHBhdGguaXNBYnNvbHV0ZShyZXNvbHZlZFBhdGgpKSB7XG4gICAgICAgICAgY29uc3QgZXh0ZW5zaW9uID1cbiAgICAgICAgICAgICgvXFwudHN4PyQvLmV4ZWMocGF0aC5iYXNlbmFtZShyZXNvbHZlZFBhdGgpKSB8fCBbXSlbMF0gfHwgdm9pZCAwO1xuXG4gICAgICAgICAgcmVzb2x2ZWRQYXRoID1cbiAgICAgICAgICAgIFwiLi9cIiArXG4gICAgICAgICAgICBwYXRoLnJlbGF0aXZlKFxuICAgICAgICAgICAgICBzb3VyY2VEaXIsXG4gICAgICAgICAgICAgIHBhdGgucmVzb2x2ZShcbiAgICAgICAgICAgICAgICBwYXRoLmRpcm5hbWUocmVzb2x2ZWRQYXRoKSxcbiAgICAgICAgICAgICAgICBwYXRoLmJhc2VuYW1lKHJlc29sdmVkUGF0aCwgZXh0ZW5zaW9uKSArIGV4dFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzb2x1dGlvbkNhY2hlLnNldChjYWNoZUtleSwgcmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmVkUGF0aDtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gdmlzaXROb2RlKG5vZGU6IHRzLk5vZGUpOiB0cy5WaXNpdFJlc3VsdDx0cy5Ob2RlPiB7XG4gICAgICAgIGlmIChzaG91bGRNdXRhdGVNb2R1bGVTcGVjaWZpZXIobm9kZSkpIHtcbiAgICAgICAgICBpZiAodHMuaXNJbXBvcnREZWNsYXJhdGlvbihub2RlKSkge1xuICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWRQYXRoID0gcmVzb2x2ZVBhdGgobm9kZS5tb2R1bGVTcGVjaWZpZXIudGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuZXdNb2R1bGVTcGVjaWZpZXIgPVxuICAgICAgICAgICAgICB0cmFuc2Zvcm1hdGlvbkNvbnRleHQuZmFjdG9yeS5jcmVhdGVTdHJpbmdMaXRlcmFsKHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtYXRpb25Db250ZXh0LmZhY3RvcnkudXBkYXRlSW1wb3J0RGVjbGFyYXRpb24oXG4gICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgIG5vZGUubW9kaWZpZXJzLFxuICAgICAgICAgICAgICBub2RlLmltcG9ydENsYXVzZSxcbiAgICAgICAgICAgICAgbmV3TW9kdWxlU3BlY2lmaWVyLFxuICAgICAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0cy5pc0V4cG9ydERlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlZFBhdGggPSByZXNvbHZlUGF0aChub2RlLm1vZHVsZVNwZWNpZmllci50ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5ld01vZHVsZVNwZWNpZmllciA9XG4gICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uQ29udGV4dC5mYWN0b3J5LmNyZWF0ZVN0cmluZ0xpdGVyYWwocmVzb2x2ZWRQYXRoKTtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1hdGlvbkNvbnRleHQuZmFjdG9yeS51cGRhdGVFeHBvcnREZWNsYXJhdGlvbihcbiAgICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgICAgbm9kZS5tb2RpZmllcnMsXG4gICAgICAgICAgICAgIG5vZGUuaXNUeXBlT25seSxcbiAgICAgICAgICAgICAgbm9kZS5leHBvcnRDbGF1c2UsXG4gICAgICAgICAgICAgIG5ld01vZHVsZVNwZWNpZmllcixcbiAgICAgICAgICAgICAgdW5kZWZpbmVkXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cy52aXNpdEVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUsIHRyYW5zZm9ybWF0aW9uQ29udGV4dCk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNob3VsZE11dGF0ZU1vZHVsZVNwZWNpZmllcihub2RlOiB0cy5Ob2RlKTogbm9kZSBpcyAoXG4gICAgICAgIHwgdHMuSW1wb3J0RGVjbGFyYXRpb25cbiAgICAgICAgfCB0cy5FeHBvcnREZWNsYXJhdGlvblxuICAgICAgKSAmIHtcbiAgICAgICAgbW9kdWxlU3BlY2lmaWVyOiB0cy5TdHJpbmdMaXRlcmFsO1xuICAgICAgfSB7XG4gICAgICAgIGlmICghdHMuaXNJbXBvcnREZWNsYXJhdGlvbihub2RlKSAmJiAhdHMuaXNFeHBvcnREZWNsYXJhdGlvbihub2RlKSlcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgaWYgKG5vZGUubW9kdWxlU3BlY2lmaWVyID09PSB1bmRlZmluZWQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gb25seSB3aGVuIG1vZHVsZSBzcGVjaWZpZXIgaXMgdmFsaWRcbiAgICAgICAgaWYgKCF0cy5pc1N0cmluZ0xpdGVyYWwobm9kZS5tb2R1bGVTcGVjaWZpZXIpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIC8vIG9ubHkgd2hlbiBwYXRoIGlzIHJlbGF0aXZlXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhbm9kZS5tb2R1bGVTcGVjaWZpZXIudGV4dC5zdGFydHNXaXRoKFwiLi9cIikgJiZcbiAgICAgICAgICAhbm9kZS5tb2R1bGVTcGVjaWZpZXIudGV4dC5zdGFydHNXaXRoKFwiLi4vXCIpXG4gICAgICAgIClcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIC8vIG9ubHkgd2hlbiBtb2R1bGUgc3BlY2lmaWVyIGhhcyBubyBleHRlbnNpb25cbiAgICAgICAgaWYgKHBhdGguZXh0bmFtZShub2RlLm1vZHVsZVNwZWNpZmllci50ZXh0KSAhPT0gXCJcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRzLnZpc2l0Tm9kZShzb3VyY2VGaWxlLCB2aXNpdE5vZGUpIGFzIFNvdXJjZUZpbGU7XG4gICAgfTtcbiAgfTtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgY29tbWFuZC1saW5lIHNjcmlwdCBmb3IgYnVpbGRpbmcgYW5kIGJ1bmRsaW5nIFR5cGVTY3JpcHQgcHJvamVjdHMuXG4gKiBAc3VtbWFyeSBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSBidWlsZCBzY3JpcHQgdGhhdCBoYW5kbGVzIFR5cGVTY3JpcHQgY29tcGlsYXRpb24sXG4gKiBidW5kbGluZyB3aXRoIFJvbGx1cCwgYW5kIGRvY3VtZW50YXRpb24gZ2VuZXJhdGlvbi4gSXQgc3VwcG9ydHMgZGlmZmVyZW50IGJ1aWxkIG1vZGVzXG4gKiAoZGV2ZWxvcG1lbnQsIHByb2R1Y3Rpb24pLCBtb2R1bGUgZm9ybWF0cyAoQ0pTLCBFU00pLCBhbmQgY2FuIGJlIGV4dGVuZGVkIHdpdGggY3VzdG9tXG4gKiBjb25maWd1cmF0aW9ucy5cbiAqIEBjbGFzcyBCdWlsZFNjcmlwdHNcbiAqL1xuZXhwb3J0IGNsYXNzIEJ1aWxkU2NyaXB0cyBleHRlbmRzIENvbW1hbmQ8XG4gIENvbW1hbmRPcHRpb25zPHR5cGVvZiBvcHRpb25zPixcbiAgdm9pZFxuPiB7XG4gIHByaXZhdGUgcmVwbGFjZW1lbnRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgcGtnVmVyc2lvbjogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHBrZ05hbWU6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihcbiAgICAgIFwiQnVpbGRTY3JpcHRzXCIsXG4gICAgICBPYmplY3QuYXNzaWduKHt9LCBEZWZhdWx0Q29tbWFuZE9wdGlvbnMsIG9wdGlvbnMpIGFzIENvbW1hbmRPcHRpb25zPFxuICAgICAgICB0eXBlb2Ygb3B0aW9uc1xuICAgICAgPlxuICAgICk7XG4gICAgY29uc3QgcGtnID0gZ2V0UGFja2FnZSgpIGFzIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfTtcbiAgICBjb25zdCB7IG5hbWUsIHZlcnNpb24gfSA9IHBrZztcbiAgICB0aGlzLnBrZ05hbWUgPSBuYW1lLmluY2x1ZGVzKFwiQFwiKSA/IG5hbWUuc3BsaXQoXCIvXCIpWzFdIDogbmFtZTtcbiAgICB0aGlzLnBrZ1ZlcnNpb24gPSB2ZXJzaW9uO1xuICAgIHRoaXMucmVwbGFjZW1lbnRzW1ZFUlNJT05fU1RSSU5HXSA9IHRoaXMucGtnVmVyc2lvbjtcbiAgICB0aGlzLnJlcGxhY2VtZW50c1tQQUNLQUdFX1NUUklOR10gPSBuYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQYXRjaGVzIGZpbGVzIHdpdGggdmVyc2lvbiBhbmQgcGFja2FnZSBuYW1lLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCByZWFkcyBhbGwgZmlsZXMgaW4gYSBkaXJlY3RvcnksIGZpbmRzIHBsYWNlaG9sZGVycyBmb3IgdmVyc2lvblxuICAgKiBhbmQgcGFja2FnZSBuYW1lLCBhbmQgcmVwbGFjZXMgdGhlbSB3aXRoIHRoZSBhY3R1YWwgdmFsdWVzIGZyb20gcGFja2FnZS5qc29uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcCAtIFRoZSBwYXRoIHRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgZmlsZXMgdG8gcGF0Y2guXG4gICAqL1xuICBwYXRjaEZpbGVzKHA6IHN0cmluZykge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnBhdGNoRmlsZXMpO1xuICAgIGNvbnN0IHsgbmFtZSwgdmVyc2lvbiB9ID0gZ2V0UGFja2FnZSgpIGFzIGFueTtcbiAgICBsb2cuaW5mbyhgUGF0Y2hpbmcgJHtuYW1lfSAke3ZlcnNpb259IG1vZHVsZSBpbiAke3B9Li4uYCk7XG4gICAgY29uc3Qgc3RhdCA9IGZzLnN0YXRTeW5jKHApO1xuICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkpXG4gICAgICBmcy5yZWFkZGlyU3luYyhwLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICAgICAgICAuZmlsdGVyKChwKSA9PiBwLmlzRmlsZSgpKVxuICAgICAgICAuZm9yRWFjaCgoZmlsZSkgPT5cbiAgICAgICAgICBwYXRjaEZpbGUoXG4gICAgICAgICAgICBwYXRoLmpvaW4oZmlsZS5wYXJlbnRQYXRoLCBmaWxlLm5hbWUpLFxuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5yZXBsYWNlbWVudHMpLnJlZHVjZShcbiAgICAgICAgICAgICAgKGFjYzogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIFZFUlNJT05fU1RSSU5HOlxuICAgICAgICAgICAgICAgICAgICBsb2cuZGVidWcoXCJGb3VuZCBWRVJTSU9OIHN0cmluZyB0byByZXBsYWNlXCIpO1xuICAgICAgICAgICAgICAgICAgICBhY2NbYFZFUlNJT04gPSBcIiR7VkVSU0lPTl9TVFJJTkd9XCI7YF0gPVxuICAgICAgICAgICAgICAgICAgICAgIGBWRVJTSU9OID0gXCIke3ZhbH1cIjtgO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgUEFDS0FHRV9TVFJJTkc6XG4gICAgICAgICAgICAgICAgICAgIGxvZy5kZWJ1ZyhcIkZvdW5kIFBBQ0tBR0VfTkFNRSBzdHJpbmcgdG8gcmVwbGFjZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgYWNjW2BQQUNLQUdFX05BTUUgPSBcIiR7UEFDS0FHRV9TVFJJTkd9XCI7YF0gPVxuICAgICAgICAgICAgICAgICAgICAgIGBQQUNLQUdFX05BTUUgPSBcIiR7dmFsfVwiO2A7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgYWNjW2tleV0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHt9XG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgIGxvZy52ZXJib3NlKGBNb2R1bGUgJHtuYW1lfSAke3ZlcnNpb259IHBhdGNoZWQgaW4gJHtwfS4uLmApO1xuICB9XG5cbiAgcHJpdmF0ZSByZXBvcnREaWFnbm9zdGljcyhcbiAgICBkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdLFxuICAgIGxvZ0xldmVsOiBMb2dMZXZlbFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IG1zZyA9IHRoaXMuZm9ybWF0RGlhZ25vc3RpY3MoZGlhZ25vc3RpY3MpO1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvZ1tsb2dMZXZlbF0obXNnKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCB0byBnZXQgbG9nZ2VyIGZvciAke2xvZ0xldmVsfWApO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgcmV0dXJuIG1zZztcbiAgfVxuXG4gIC8vIEZvcm1hdCBkaWFnbm9zdGljcyBpbnRvIGEgc2luZ2xlIHN0cmluZyBmb3IgdGhyb3dpbmcgb3IgbG9nZ2luZ1xuICBwcml2YXRlIGZvcm1hdERpYWdub3N0aWNzKGRpYWdub3N0aWNzOiBEaWFnbm9zdGljW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBkaWFnbm9zdGljc1xuICAgICAgLm1hcCgoZGlhZ25vc3RpYykgPT4ge1xuICAgICAgICBsZXQgbWVzc2FnZSA9IFwiXCI7XG4gICAgICAgIGlmIChkaWFnbm9zdGljLmZpbGUgJiYgZGlhZ25vc3RpYy5zdGFydCkge1xuICAgICAgICAgIGNvbnN0IHsgbGluZSwgY2hhcmFjdGVyIH0gPVxuICAgICAgICAgICAgZGlhZ25vc3RpYy5maWxlLmdldExpbmVBbmRDaGFyYWN0ZXJPZlBvc2l0aW9uKGRpYWdub3N0aWMuc3RhcnQpO1xuICAgICAgICAgIG1lc3NhZ2UgKz0gYCR7ZGlhZ25vc3RpYy5maWxlLmZpbGVOYW1lfSAoJHtsaW5lICsgMX0sJHtjaGFyYWN0ZXIgKyAxfSlgO1xuICAgICAgICB9XG4gICAgICAgIG1lc3NhZ2UgKz1cbiAgICAgICAgICBcIjogXCIgKyB0cy5mbGF0dGVuRGlhZ25vc3RpY01lc3NhZ2VUZXh0KGRpYWdub3N0aWMubWVzc2FnZVRleHQsIFwiXFxuXCIpO1xuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgIH0pXG4gICAgICAuam9pbihcIlxcblwiKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZENvbmZpZ0ZpbGUoY29uZmlnRmlsZU5hbWU6IHN0cmluZykge1xuICAgIC8vIFJlYWQgY29uZmlnIGZpbGVcbiAgICBjb25zdCBjb25maWdGaWxlVGV4dCA9IGZzLnJlYWRGaWxlU3luYyhjb25maWdGaWxlTmFtZSkudG9TdHJpbmcoKTtcblxuICAgIC8vIFBhcnNlIEpTT04sIGFmdGVyIHJlbW92aW5nIGNvbW1lbnRzLiBKdXN0IGZhbmNpZXIgSlNPTi5wYXJzZVxuICAgIGNvbnN0IHJlc3VsdCA9IHRzLnBhcnNlQ29uZmlnRmlsZVRleHRUb0pzb24oY29uZmlnRmlsZU5hbWUsIGNvbmZpZ0ZpbGVUZXh0KTtcbiAgICBjb25zdCBjb25maWdPYmplY3QgPSByZXN1bHQuY29uZmlnO1xuICAgIGlmICghY29uZmlnT2JqZWN0KSB7XG4gICAgICB0aGlzLnJlcG9ydERpYWdub3N0aWNzKFtyZXN1bHQuZXJyb3IhXSwgTG9nTGV2ZWwuZXJyb3IpO1xuICAgIH1cblxuICAgIC8vIEV4dHJhY3QgY29uZmlnIGluZnJvbWF0aW9uXG4gICAgY29uc3QgY29uZmlnUGFyc2VSZXN1bHQgPSB0cy5wYXJzZUpzb25Db25maWdGaWxlQ29udGVudChcbiAgICAgIGNvbmZpZ09iamVjdCxcbiAgICAgIHRzLnN5cyxcbiAgICAgIHBhdGguZGlybmFtZShjb25maWdGaWxlTmFtZSlcbiAgICApO1xuICAgIGlmIChjb25maWdQYXJzZVJlc3VsdC5lcnJvcnMubGVuZ3RoID4gMClcbiAgICAgIHRoaXMucmVwb3J0RGlhZ25vc3RpY3MoY29uZmlnUGFyc2VSZXN1bHQuZXJyb3JzLCBMb2dMZXZlbC5lcnJvcik7XG5cbiAgICByZXR1cm4gY29uZmlnUGFyc2VSZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGV2YWxEaWFnbm9zdGljcyhkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdKSB7XG4gICAgaWYgKGRpYWdub3N0aWNzICYmIGRpYWdub3N0aWNzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGVycm9ycyA9IGRpYWdub3N0aWNzLmZpbHRlcihcbiAgICAgICAgKGQpID0+IGQuY2F0ZWdvcnkgPT09IHRzLkRpYWdub3N0aWNDYXRlZ29yeS5FcnJvclxuICAgICAgKTtcbiAgICAgIGNvbnN0IHdhcm5pbmdzID0gZGlhZ25vc3RpY3MuZmlsdGVyKFxuICAgICAgICAoZCkgPT4gZC5jYXRlZ29yeSA9PT0gdHMuRGlhZ25vc3RpY0NhdGVnb3J5Lldhcm5pbmdcbiAgICAgICk7XG4gICAgICBjb25zdCBzdWdnZXN0aW9ucyA9IGRpYWdub3N0aWNzLmZpbHRlcihcbiAgICAgICAgKGQpID0+IGQuY2F0ZWdvcnkgPT09IHRzLkRpYWdub3N0aWNDYXRlZ29yeS5TdWdnZXN0aW9uXG4gICAgICApO1xuICAgICAgY29uc3QgbWVzc2FnZXMgPSBkaWFnbm9zdGljcy5maWx0ZXIoXG4gICAgICAgIChkKSA9PiBkLmNhdGVnb3J5ID09PSB0cy5EaWFnbm9zdGljQ2F0ZWdvcnkuTWVzc2FnZVxuICAgICAgKTtcbiAgICAgIC8vIExvZyBkaWFnbm9zdGljcyB0byBjb25zb2xlXG5cbiAgICAgIGlmICh3YXJuaW5ncy5sZW5ndGgpIHRoaXMucmVwb3J0RGlhZ25vc3RpY3Mod2FybmluZ3MsIExvZ0xldmVsLndhcm4pO1xuICAgICAgaWYgKGVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5yZXBvcnREaWFnbm9zdGljcyhkaWFnbm9zdGljcyBhcyBEaWFnbm9zdGljW10sIExvZ0xldmVsLmVycm9yKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBUeXBlU2NyaXB0IHJlcG9ydGVkICR7ZGlhZ25vc3RpY3MubGVuZ3RofSBkaWFnbm9zdGljKHMpIGR1cmluZyBjaGVjazsgYWJvcnRpbmcuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHN1Z2dlc3Rpb25zLmxlbmd0aClcbiAgICAgICAgdGhpcy5yZXBvcnREaWFnbm9zdGljcyhzdWdnZXN0aW9ucywgTG9nTGV2ZWwuaW5mbyk7XG4gICAgICBpZiAobWVzc2FnZXMubGVuZ3RoKSB0aGlzLnJlcG9ydERpYWdub3N0aWNzKG1lc3NhZ2VzLCBMb2dMZXZlbC5pbmZvKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByZUNoZWNrRGlhZ25vc3RpY3MocHJvZ3JhbTogdHMuUHJvZ3JhbSkge1xuICAgIGNvbnN0IGRpYWdub3N0aWNzID0gdHMuZ2V0UHJlRW1pdERpYWdub3N0aWNzKHByb2dyYW0pO1xuICAgIHRoaXMuZXZhbERpYWdub3N0aWNzKGRpYWdub3N0aWNzIGFzIGFueSk7XG4gIH1cblxuICAvLyBDcmVhdGUgYSBUeXBlU2NyaXB0IHByb2dyYW0gZm9yIHRoZSBjdXJyZW50IHRzY29uZmlnIGFuZCBmYWlsIGlmIHRoZXJlIGFyZSBhbnkgZXJyb3IgZGlhZ25vc3RpY3MuXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tUc0RpYWdub3N0aWNzKFxuICAgIGlzRGV2OiBib29sZWFuLFxuICAgIG1vZGU6IE1vZGVzLFxuICAgIGJ1bmRsZSA9IGZhbHNlXG4gICkge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmNoZWNrVHNEaWFnbm9zdGljcyk7XG4gICAgbGV0IHRzQ29uZmlnO1xuICAgIHRyeSB7XG4gICAgICB0c0NvbmZpZyA9IHRoaXMucmVhZENvbmZpZ0ZpbGUoXCIuL3RzY29uZmlnLmpzb25cIik7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcGFyc2UgdHNjb25maWcuanNvbjogJHtlfWApO1xuICAgIH1cblxuICAgIGlmIChidW5kbGUpIHtcbiAgICAgIHRzQ29uZmlnLm9wdGlvbnMubW9kdWxlID0gTW9kdWxlS2luZC5BTUQ7XG4gICAgICB0c0NvbmZpZy5vcHRpb25zLm91dERpciA9IFwiZGlzdFwiO1xuICAgICAgdHNDb25maWcub3B0aW9ucy5pc29sYXRlZE1vZHVsZXMgPSBmYWxzZTtcbiAgICAgIHRzQ29uZmlnLm9wdGlvbnMub3V0RmlsZSA9IHRoaXMucGtnTmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHNDb25maWcub3B0aW9ucy5vdXREaXIgPSBgbGliJHttb2RlID09PSBNb2Rlcy5FU00gPyBcIi9lc21cIiA6IFwiXCJ9YDtcbiAgICAgIHRzQ29uZmlnLm9wdGlvbnMubW9kdWxlID1cbiAgICAgICAgbW9kZSA9PT0gTW9kZXMuRVNNID8gTW9kdWxlS2luZC5FUzIwMjIgOiBNb2R1bGVLaW5kLkNvbW1vbkpTO1xuICAgIH1cblxuICAgIC8vIEVuc3VyZSBUeXBlU2NyaXB0IGVtaXRzIGlubGluZSBzb3VyY2UgbWFwcyBmb3IgYm90aCBkZXYgYW5kIHByb2QgKGJ1bmRsZXJzIHdpbGwgY29udHJvbCBleHRlcm5hbCBtYXBzKVxuICAgIC8vIEtlZXAgY29tbWVudHMgaW4gVFMgZW1pdCBieSBkZWZhdWx0OyBidW5kbGluZy9taW5pZmljYXRpb24gd2lsbCBoYW5kbGUgcmVtb3ZhbCB3aGVyZSByZXF1ZXN0ZWQuXG4gICAgLy8gRW1pdCBleHRlcm5hbCBzb3VyY2UgbWFwcyBmcm9tIFR5cGVTY3JpcHQgc28gZWRpdG9ycy9kZWJ1Z2dlcnMgY2FuIGZpbmQgdGhlbS5cbiAgICAvLyBUdXJuIG9mZiBpbmxpbmUgbWFwcy9zb3VyY2VzIHNvIGJ1bmRsZXJzIChSb2xsdXApIGNhbiBjb250cm9sIHdoZXRoZXIgbWFwcyBhcmUgaW5saW5lZCBvciB3cml0dGVuIGV4dGVybmFsbHkuXG4gICAgdHNDb25maWcub3B0aW9ucy5pbmxpbmVTb3VyY2VNYXAgPSBmYWxzZTtcbiAgICB0c0NvbmZpZy5vcHRpb25zLmlubGluZVNvdXJjZXMgPSBmYWxzZTtcbiAgICB0c0NvbmZpZy5vcHRpb25zLnNvdXJjZU1hcCA9IHRydWU7XG5cbiAgICBjb25zdCBwcm9ncmFtID0gdHMuY3JlYXRlUHJvZ3JhbSh0c0NvbmZpZy5maWxlTmFtZXMsIHRzQ29uZmlnLm9wdGlvbnMpO1xuICAgIHRoaXMucHJlQ2hlY2tEaWFnbm9zdGljcyhwcm9ncmFtKTtcbiAgICBsb2cudmVyYm9zZShcbiAgICAgIGBUeXBlU2NyaXB0IGNoZWNrcyBwYXNzZWQgKCR7YnVuZGxlID8gXCJidW5kbGVcIiA6IFwibm9ybWFsXCJ9IG1vZGUpLmBcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBidWlsZFRzKGlzRGV2OiBib29sZWFuLCBtb2RlOiBNb2RlcywgYnVuZGxlID0gZmFsc2UpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5idWlsZFRzKTtcbiAgICBsb2cuaW5mbyhcbiAgICAgIGBCdWlsZGluZyAke3RoaXMucGtnTmFtZX0gJHt0aGlzLnBrZ1ZlcnNpb259IG1vZHVsZSAoJHttb2RlfSkgaW4gJHtpc0RldiA/IFwiZGV2XCIgOiBcInByb2RcIn0gbW9kZS4uLmBcbiAgICApO1xuICAgIGxldCB0c0NvbmZpZztcbiAgICB0cnkge1xuICAgICAgdHNDb25maWcgPSB0aGlzLnJlYWRDb25maWdGaWxlKFwiLi90c2NvbmZpZy5qc29uXCIpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHBhcnNlIHRzY29uZmlnLmpzb246ICR7ZX1gKTtcbiAgICB9XG5cbiAgICBpZiAoYnVuZGxlKSB7XG4gICAgICB0c0NvbmZpZy5vcHRpb25zLm1vZHVsZSA9IE1vZHVsZUtpbmQuQU1EO1xuICAgICAgdHNDb25maWcub3B0aW9ucy5vdXREaXIgPSBcImRpc3RcIjtcbiAgICAgIHRzQ29uZmlnLm9wdGlvbnMuaXNvbGF0ZWRNb2R1bGVzID0gZmFsc2U7XG4gICAgICB0c0NvbmZpZy5vcHRpb25zLm91dEZpbGUgPSB0aGlzLnBrZ05hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRzQ29uZmlnLm9wdGlvbnMub3V0RGlyID0gYGxpYiR7bW9kZSA9PT0gTW9kZXMuRVNNID8gXCIvZXNtXCIgOiBcIlwifWA7XG4gICAgICB0c0NvbmZpZy5vcHRpb25zLm1vZHVsZSA9XG4gICAgICAgIG1vZGUgPT09IE1vZGVzLkVTTSA/IE1vZHVsZUtpbmQuRVMyMDIyIDogTW9kdWxlS2luZC5Db21tb25KUztcbiAgICB9XG5cbiAgICAvLyBBbHdheXMgZW1pdCBpbmxpbmUgc291cmNlIG1hcHMgZnJvbSB0c2MgKGJ1bmRsZXIgd2lsbCBlbWl0IGV4dGVybmFsIG1hcHMgZm9yIHByb2R1Y3Rpb24gYnVuZGxlcykuXG4gICAgLy8gRm9yIGRldiBidWlsZHMgd2Ugd2FudCBUeXBlU2NyaXB0IHRvIGVtaXQgaW5saW5lIHNvdXJjZSBtYXBzIHNvIG5vIHNlcGFyYXRlIC5tYXAgZmlsZXMgYXJlIHByb2R1Y2VkLlxuICAgIC8vIEZvciBwcm9kdWN0aW9uIHdlIGVtaXQgZXh0ZXJuYWwgc291cmNlIG1hcHMgc28gdGhlIGJ1bmRsZXIgY2FuIGZ1cnRoZXIgdHJhbnNmb3JtIGFuZCBlbWl0IHRoZW0uXG4gICAgaWYgKGlzRGV2KSB7XG4gICAgICB0c0NvbmZpZy5vcHRpb25zLmlubGluZVNvdXJjZU1hcCA9IHRydWU7XG4gICAgICB0c0NvbmZpZy5vcHRpb25zLmlubGluZVNvdXJjZXMgPSB0cnVlO1xuICAgICAgdHNDb25maWcub3B0aW9ucy5zb3VyY2VNYXAgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHNDb25maWcub3B0aW9ucy5pbmxpbmVTb3VyY2VNYXAgPSBmYWxzZTtcbiAgICAgIHRzQ29uZmlnLm9wdGlvbnMuaW5saW5lU291cmNlcyA9IGZhbHNlO1xuICAgICAgdHNDb25maWcub3B0aW9ucy5zb3VyY2VNYXAgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIEZvciBwcm9kdWN0aW9uIGJ1aWxkcyB3ZSBzdGlsbCBrZWVwIFR5cGVTY3JpcHQgY29tbWVudHMgKHJlbW92ZUNvbW1lbnRzPWZhbHNlIGluIHRzY29uZmlnKVxuICAgIC8vIEJ1bmRsZXIvdGVyc2VyIHdpbGwgc3RyaXAgY29tbWVudHMgZm9yIHByb2R1Y3Rpb24gYnVuZGxlcyBhcyByZXF1ZXN0ZWQuXG5cbiAgICBjb25zdCBwcm9ncmFtID0gdHMuY3JlYXRlUHJvZ3JhbSh0c0NvbmZpZy5maWxlTmFtZXMsIHRzQ29uZmlnLm9wdGlvbnMpO1xuXG4gICAgY29uc3QgdHJhbnNmb3JtYXRpb25zOiB7IGJlZm9yZT86IGFueVtdIH0gPSB7fTtcbiAgICBpZiAobW9kZSA9PT0gTW9kZXMuQ0pTKSB7XG4gICAgICB0cmFuc2Zvcm1hdGlvbnMuYmVmb3JlID0gW2NqczJUcmFuc2Zvcm1lcihcIi5janNcIildO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gTW9kZXMuRVNNKSB7XG4gICAgICB0cmFuc2Zvcm1hdGlvbnMuYmVmb3JlID0gW2NqczJUcmFuc2Zvcm1lcihcIi5qc1wiKV07XG4gICAgfVxuXG4gICAgY29uc3QgZW1pdFJlc3VsdDogRW1pdFJlc3VsdCA9IHByb2dyYW0uZW1pdChcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRyYW5zZm9ybWF0aW9uc1xuICAgICk7XG5cbiAgICBjb25zdCBhbGxEaWFnbm9zdGljcyA9IHRzXG4gICAgICAuZ2V0UHJlRW1pdERpYWdub3N0aWNzKHByb2dyYW0pXG4gICAgICAuY29uY2F0KGVtaXRSZXN1bHQuZGlhZ25vc3RpY3MpO1xuXG4gICAgdGhpcy5ldmFsRGlhZ25vc3RpY3MoYWxsRGlhZ25vc3RpY3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBidWlsZChpc0RldjogYm9vbGVhbiwgbW9kZTogTW9kZXMsIGJ1bmRsZSA9IGZhbHNlKSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuYnVpbGQpO1xuICAgIGF3YWl0IHRoaXMuYnVpbGRUcyhpc0RldiwgbW9kZSwgYnVuZGxlKTtcblxuICAgIGxvZy52ZXJib3NlKFxuICAgICAgYE1vZHVsZSAke3RoaXMucGtnTmFtZX0gJHt0aGlzLnBrZ1ZlcnNpb259ICgke21vZGV9KSBidWlsdCBpbiAke2lzRGV2ID8gXCJkZXZcIiA6IFwicHJvZFwifSBtb2RlLi4uYFxuICAgICk7XG4gICAgaWYgKG1vZGUgPT09IE1vZGVzLkNKUyAmJiAhYnVuZGxlKSB7XG4gICAgICBjb25zdCBmaWxlcyA9IGdldEFsbEZpbGVzKFxuICAgICAgICBcImxpYlwiLFxuICAgICAgICAoZmlsZSkgPT4gZmlsZS5lbmRzV2l0aChcIi5qc1wiKSAmJiAhZmlsZS5pbmNsdWRlcyhcIi9lc20vXCIpXG4gICAgICApO1xuXG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgbG9nLnZlcmJvc2UoYFBhdGNoaW5nICR7ZmlsZX0ncyBjanMgaW1wb3J0cy4uLmApO1xuICAgICAgICBjb25zdCBmID0gZmlsZS5yZXBsYWNlKFwiLmpzXCIsIFwiLmNqc1wiKTtcbiAgICAgICAgYXdhaXQgcmVuYW1lRmlsZShmaWxlLCBmKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvcGllcyBhc3NldHMgdG8gdGhlIGJ1aWxkIG91dHB1dCBkaXJlY3RvcnkuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIGNoZWNrcyBmb3IgdGhlIGV4aXN0ZW5jZSBvZiBhbiAnYXNzZXRzJyBkaXJlY3RvcnkgaW4gdGhlIHNvdXJjZVxuICAgKiBhbmQgY29waWVzIGl0IHRvIHRoZSBhcHByb3ByaWF0ZSBidWlsZCBvdXRwdXQgZGlyZWN0b3J5IChsaWIgb3IgZGlzdCkuXG4gICAqIEBwYXJhbSB7TW9kZXN9IG1vZGUgLSBUaGUgYnVpbGQgbW9kZSAoQ0pTIG9yIEVTTSkuXG4gICAqL1xuICBjb3B5QXNzZXRzKG1vZGU6IE1vZGVzKSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuY29weUFzc2V0cyk7XG4gICAgbGV0IGhhc0Fzc2V0cyA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICBoYXNBc3NldHMgPSBmcy5zdGF0U3luYyhcIi4vc3JjL2Fzc2V0c1wiKS5pc0RpcmVjdG9yeSgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHJldHVybiBsb2cudmVyYm9zZShgTm8gYXNzZXRzIGZvdW5kIGluIC4vc3JjL2Fzc2V0cyB0byBjb3B5YCk7XG4gICAgfVxuICAgIGlmIChoYXNBc3NldHMpXG4gICAgICBjb3B5RmlsZShcbiAgICAgICAgXCIuL3NyYy9hc3NldHNcIixcbiAgICAgICAgYC4vJHttb2RlID09PSBNb2Rlcy5DSlMgPyBcImxpYlwiIDogXCJkaXN0XCJ9L2Fzc2V0c2BcbiAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEJ1bmRsZXMgdGhlIHByb2plY3QgdXNpbmcgUm9sbHVwLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBjb25maWd1cmVzIGFuZCBydW5zIFJvbGx1cCB0byBidW5kbGUgdGhlIHByb2plY3QuIEl0IGhhbmRsZXNcbiAgICogZGlmZmVyZW50IG1vZHVsZSBmb3JtYXRzLCBkZXZlbG9wbWVudCBhbmQgcHJvZHVjdGlvbiBidWlsZHMsIGFuZCBleHRlcm5hbCBkZXBlbmRlbmNpZXMuXG4gICAqIEBwYXJhbSB7TW9kZXN9IG1vZGUgLSBUaGUgbW9kdWxlIGZvcm1hdCAoQ0pTIG9yIEVTTSkuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNEZXYgLSBXaGV0aGVyIGl0J3MgYSBkZXZlbG9wbWVudCBidWlsZC5cbiAgICogQHBhcmFtIHtib29sZWFufSBpc0xpYiAtIFdoZXRoZXIgaXQncyBhIGxpYnJhcnkgYnVpbGQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZW50cnlGaWxlPVwic3JjL2luZGV4LnRzXCJdIC0gVGhlIGVudHJ5IGZpbGUgZm9yIHRoZSBidW5kbGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZU92ZXJyaWRlPXRoaXMucGtnTmFtZV0gLSBUaGUgbmFtZSBvZiB0aGUgb3V0cHV0IGJ1bmRsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IFtleHRlcm5hbHNBcmddIC0gQSBsaXN0IG9mIGV4dGVybmFsIGRlcGVuZGVuY2llcy5cbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IFtpbmNsdWRlQXJnXSAtIEEgbGlzdCBvZiBkZXBlbmRlbmNpZXMgdG8gaW5jbHVkZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBidW5kbGUoXG4gICAgbW9kZTogTW9kZXMsXG4gICAgaXNEZXY6IGJvb2xlYW4sXG4gICAgaXNMaWI6IGJvb2xlYW4sXG4gICAgZW50cnlGaWxlOiBzdHJpbmcgPSBcInNyYy9pbmRleC50c1wiLFxuICAgIG5hbWVPdmVycmlkZTogc3RyaW5nID0gdGhpcy5wa2dOYW1lLFxuICAgIGV4dGVybmFsc0FyZz86IHN0cmluZyB8IHN0cmluZ1tdLFxuICAgIGluY2x1ZGVBcmc6IHN0cmluZyB8IHN0cmluZ1tdID0gW1xuICAgICAgXCJwcm9tcHRzXCIsXG4gICAgICBcInN0eWxlZC1zdHJpbmctYnVpbGRlclwiLFxuICAgICAgXCJ0eXBlZC1vYmplY3QtYWNjdW11bGF0b3JcIixcbiAgICAgIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIixcbiAgICBdXG4gICkge1xuICAgIC8vIFJ1biBhIFR5cGVTY3JpcHQtb25seSBkaWFnbm9zdGljIGNoZWNrIGZvciB0aGUgYnVuZGxpbmcgY29uZmlndXJhdGlvbiBhbmQgZmFpbCBmYXN0IG9uIGFueSBlcnJvcnMuXG4gICAgYXdhaXQgdGhpcy5jaGVja1RzRGlhZ25vc3RpY3MoaXNEZXYsIG1vZGUsIHRydWUpO1xuICAgIGNvbnN0IGlzRXNtID0gbW9kZSA9PT0gTW9kZXMuRVNNO1xuICAgIGNvbnN0IHBrZ05hbWUgPSB0aGlzLnBrZ05hbWU7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2c7XG5cbiAgICAvLyBub3JtYWxpemUgaW5jbHVkZSBhbmQgZXh0ZXJuYWxzXG4gICAgY29uc3QgaW5jbHVkZSA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4ocGFyc2VMaXN0KGluY2x1ZGVBcmcpIGFzIHN0cmluZ1tdKV0pXG4gICAgKTtcbiAgICBsZXQgZXh0ZXJuYWxzTGlzdCA9IHBhcnNlTGlzdChleHRlcm5hbHNBcmcpO1xuICAgIGlmIChleHRlcm5hbHNMaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgLy8gaWYgbm8gZXh0ZXJuYWxzIHNwZWNpZmllZCwgbGlzdCB0b3AtbGV2ZWwgcGFja2FnZXMgaW4gbm9kZV9tb2R1bGVzIChleHBhbmQgc2NvcGVzKVxuICAgICAgdHJ5IHtcbiAgICAgICAgZXh0ZXJuYWxzTGlzdCA9IGxpc3ROb2RlTW9kdWxlc1BhY2thZ2VzKFxuICAgICAgICAgIHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBcIm5vZGVfbW9kdWxlc1wiKVxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGZhbGxiYWNrIHRvIHBhY2thZ2UuanNvbiBkZXBlbmRlbmNpZXMgaWYgbGlzdGluZyBmYWlscyBvciB5aWVsZHMgbm90aGluZ1xuICAgICAgfVxuICAgICAgaWYgKCFleHRlcm5hbHNMaXN0IHx8IGV4dGVybmFsc0xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGV4dGVybmFsc0xpc3QgPSBnZXRQYWNrYWdlRGVwZW5kZW5jaWVzKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZXh0ID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoW1xuICAgICAgICAvLyBidWlsdGlucyBhbmQgYWx3YXlzIGV4dGVybmFsIHJ1bnRpbWUgZGVwc1xuICAgICAgICAuLi4oZnVuY3Rpb24gYnVpbHRpbkxpc3QoKTogc3RyaW5nW10ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KGJ1aWx0aW5Nb2R1bGVzKSA/IGJ1aWx0aW5Nb2R1bGVzIDogW11cbiAgICAgICAgICAgICkgYXMgc3RyaW5nW107XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBmYWxsYmFjayB0byBhIHJlYXNvbmFibGUgc3Vic2V0IGlmIGBidWlsdGluTW9kdWxlc2AgaXMgdW5hdmFpbGFibGVcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgIFwiZnNcIixcbiAgICAgICAgICAgICAgXCJwYXRoXCIsXG4gICAgICAgICAgICAgIFwicHJvY2Vzc1wiLFxuICAgICAgICAgICAgICBcImNoaWxkX3Byb2Nlc3NcIixcbiAgICAgICAgICAgICAgXCJ1dGlsXCIsXG4gICAgICAgICAgICAgIFwiaHR0cHNcIixcbiAgICAgICAgICAgICAgXCJodHRwXCIsXG4gICAgICAgICAgICAgIFwib3NcIixcbiAgICAgICAgICAgICAgXCJzdHJlYW1cIixcbiAgICAgICAgICAgICAgXCJjcnlwdG9cIixcbiAgICAgICAgICAgICAgXCJ6bGliXCIsXG4gICAgICAgICAgICAgIFwibmV0XCIsXG4gICAgICAgICAgICAgIFwidGxzXCIsXG4gICAgICAgICAgICAgIFwidXJsXCIsXG4gICAgICAgICAgICAgIFwicXVlcnlzdHJpbmdcIixcbiAgICAgICAgICAgICAgXCJhc3NlcnRcIixcbiAgICAgICAgICAgICAgXCJldmVudHNcIixcbiAgICAgICAgICAgICAgXCJ0dHlcIixcbiAgICAgICAgICAgICAgXCJkbnNcIixcbiAgICAgICAgICAgICAgXCJxdWVyeXN0cmluZ1wiLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCksXG4gICAgICAgIC4uLmV4dGVybmFsc0xpc3QsXG4gICAgICBdKVxuICAgICk7XG5cbiAgICAvLyBGb3IgcGx1Z2luLXR5cGVzY3JpcHQgd2Ugd2FudCBpdCB0byBlbWl0IHNvdXJjZSBtYXBzIChub3QgaW5saW5lKSBzbyBSb2xsdXAgY2FuXG4gICAgLy8gZGVjaWRlIHdoZXRoZXIgdG8gaW5saW5lIG9yIGVtaXQgZXh0ZXJuYWwgZmlsZXMuIFRoZSBSb2xsdXAgb3V0cHV0LnNvdXJjZW1hcFxuICAgIC8vIGNvbnRyb2xzIGZpbmFsIG1hcCBwbGFjZW1lbnQuIERvIE5PVCBzZXQgYSBub24tc3RhbmRhcmQgYHNvdXJjZW1hcGAgZmllbGQgb25cbiAgICAvLyB0aGUgcm9sbHVwIGlucHV0IG9wdGlvbnMgKFJvbGx1cCB3aWxsIHJlamVjdCBpdCkuXG4gICAgY29uc3Qgcm9sbHVwU291cmNlTWFwT3V0cHV0OiBmYWxzZSB8IHRydWUgfCBcImlubGluZVwiIHwgXCJoaWRkZW5cIiA9IGlzRGV2XG4gICAgICA/IFwiaW5saW5lXCJcbiAgICAgIDogdHJ1ZTtcblxuICAgIGNvbnN0IHBsdWdpbnMgPSBbXG4gICAgICB0eXBlc2NyaXB0KHtcbiAgICAgICAgY29tcGlsZXJPcHRpb25zOiB7XG4gICAgICAgICAgbW9kdWxlOiBcImVzbmV4dFwiLFxuICAgICAgICAgIGRlY2xhcmF0aW9uOiBmYWxzZSxcbiAgICAgICAgICBvdXREaXI6IGlzTGliID8gXCJiaW5cIiA6IFwiZGlzdFwiLFxuICAgICAgICAgIC8vIEZvciBkZXYgYnVuZGxlcyBlbWl0IGlubGluZSBzb3VyY2UgbWFwcyAobm8gc2VwYXJhdGUgLm1hcCBmaWxlcykuXG4gICAgICAgICAgLy8gRm9yIHByb2QgYnVuZGxlcyBlbWl0IGV4dGVybmFsIG1hcHMgc28gUm9sbHVwIGNhbiB3cml0ZSB0aGVtIHRvIGRpc2suXG4gICAgICAgICAgc291cmNlTWFwOiBpc0RldiA/IGZhbHNlIDogdHJ1ZSxcbiAgICAgICAgICBpbmxpbmVTb3VyY2VNYXA6IGlzRGV2ID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgIGlubGluZVNvdXJjZXM6IGlzRGV2ID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBpbmNsdWRlOiBbXCJzcmMvKiovKi50c1wiXSxcbiAgICAgICAgZXhjbHVkZTogW1wibm9kZV9tb2R1bGVzXCIsIFwiKiovKi5zcGVjLnRzXCJdLFxuICAgICAgICB0c2NvbmZpZzogXCIuL3RzY29uZmlnLmpzb25cIixcbiAgICAgIH0pLFxuICAgICAganNvbigpLFxuICAgIF07XG5cbiAgICBpZiAoaXNMaWIpIHtcbiAgICAgIHBsdWdpbnMucHVzaChcbiAgICAgICAgY29tbW9uanMoe1xuICAgICAgICAgIGluY2x1ZGU6IFtdLFxuICAgICAgICAgIGV4Y2x1ZGU6IGV4dGVybmFsc0xpc3QsXG4gICAgICAgIH0pLFxuICAgICAgICBub2RlUmVzb2x2ZSh7XG4gICAgICAgICAgcmVzb2x2ZU9ubHk6IGluY2x1ZGUsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIHByb2R1Y3Rpb24gbWluaWZpY2F0aW9uOiBhZGQgdGVyc2VyIGxhc3Qgc28gaXQgc2VlcyBwcmlvciBzb3VyY2UgbWFwc1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0ZXJzZXJNb2Q6IGFueSA9IGF3YWl0IGltcG9ydChcIkByb2xsdXAvcGx1Z2luLXRlcnNlclwiKTtcbiAgICAgIGNvbnN0IHRlcnNlckZuID1cbiAgICAgICAgKHRlcnNlck1vZCAmJiB0ZXJzZXJNb2QudGVyc2VyKSB8fCB0ZXJzZXJNb2QuZGVmYXVsdCB8fCB0ZXJzZXJNb2Q7XG5cbiAgICAgIGNvbnN0IHRlcnNlck9wdGlvbnNEZXY6IGFueSA9IHtcbiAgICAgICAgcGFyc2U6IHsgZWNtYTogMjAyMCB9LFxuICAgICAgICBjb21wcmVzczogZmFsc2UsXG4gICAgICAgIG1hbmdsZTogZmFsc2UsXG4gICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgIGNvbW1lbnRzOiBmYWxzZSxcbiAgICAgICAgICBiZWF1dGlmeTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHRlcnNlck9wdGlvbnNQcm9kOiBhbnkgPSB7XG4gICAgICAgIHBhcnNlOiB7IGVjbWE6IDIwMjAgfSxcbiAgICAgICAgY29tcHJlc3M6IHtcbiAgICAgICAgICBlY21hOiAyMDIwLFxuICAgICAgICAgIHBhc3NlczogNSxcbiAgICAgICAgICBkcm9wX2NvbnNvbGU6IHRydWUsXG4gICAgICAgICAgZHJvcF9kZWJ1Z2dlcjogdHJ1ZSxcbiAgICAgICAgICB0b3BsZXZlbDogdHJ1ZSxcbiAgICAgICAgICBtb2R1bGU6IGlzRXNtLFxuICAgICAgICAgIHVuc2FmZTogdHJ1ZSxcbiAgICAgICAgICB1bnNhZmVfYXJyb3dzOiB0cnVlLFxuICAgICAgICAgIHVuc2FmZV9jb21wczogdHJ1ZSxcbiAgICAgICAgICBjb2xsYXBzZV92YXJzOiB0cnVlLFxuICAgICAgICAgIHJlZHVjZV9mdW5jczogdHJ1ZSxcbiAgICAgICAgICByZWR1Y2VfdmFyczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgbWFuZ2xlOiB7XG4gICAgICAgICAgdG9wbGV2ZWw6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgIGNvbW1lbnRzOiBmYWxzZSxcbiAgICAgICAgICBhc2NpaV9vbmx5OiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICB0b3BsZXZlbDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIHBsdWdpbnMucHVzaCh0ZXJzZXJGbihpc0RldiA/IHRlcnNlck9wdGlvbnNEZXYgOiB0ZXJzZXJPcHRpb25zUHJvZCkpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gaWYgdGVyc2VyIGlzbid0IGF2YWlsYWJsZSwgaWdub3JlXG4gICAgfVxuXG4gICAgY29uc3QgaW5wdXQ6IElucHV0T3B0aW9ucyA9IHtcbiAgICAgIGlucHV0OiBlbnRyeUZpbGUsXG4gICAgICBwbHVnaW5zOiBwbHVnaW5zLFxuICAgICAgZXh0ZXJuYWw6IGV4dCxcbiAgICAgIG9ud2FybjogdW5kZWZpbmVkLFxuICAgICAgLy8gZW5hYmxlIHRyZWUtc2hha2luZyBmb3IgcHJvZHVjdGlvbiBidW5kbGVzXG4gICAgICB0cmVlc2hha2U6ICFpc0RldixcbiAgICB9IGFzIGFueTtcblxuICAgIC8vIHByZXBhcmUgb3V0cHV0IGdsb2JhbHMgbWFwcGluZyBmb3IgZXh0ZXJuYWxzXG4gICAgY29uc3QgZ2xvYmFsczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIC8vIGluY2x1ZGUgYWxsIGV4dGVybmFscyBhbmQgYnVpbHRpbnMgKGV4dCkgc28gUm9sbHVwIHdvbid0IGd1ZXNzIG5hbWVzIGZvciBidWlsdGluc1xuICAgIGV4dC5mb3JFYWNoKChlKSA9PiB7XG4gICAgICBnbG9iYWxzW2VdID0gcGFja2FnZVRvR2xvYmFsKGUpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0cHV0czogT3V0cHV0T3B0aW9uc1tdID0gW1xuICAgICAge1xuICAgICAgICBmaWxlOiBgJHtpc0xpYiA/IFwiYmluL1wiIDogXCJkaXN0L1wifSR7bmFtZU92ZXJyaWRlID8gbmFtZU92ZXJyaWRlIDogYC5idW5kbGUuJHshaXNEZXYgPyBcIm1pblwiIDogXCJcIn1gfSR7aXNFc20gPyBcIi5qc1wiIDogXCIuY2pzXCJ9YCxcbiAgICAgICAgZm9ybWF0OiBpc0xpYiA/IFwiY2pzXCIgOiBpc0VzbSA/IFwiZXNtXCIgOiBcInVtZFwiLFxuICAgICAgICBuYW1lOiBwa2dOYW1lLFxuICAgICAgICBlc01vZHVsZTogaXNFc20sXG4gICAgICAgIC8vIG91dHB1dCBzb3VyY2VtYXA6IGlubGluZSBmb3IgZGV2LCBleHRlcm5hbCBmb3IgcHJvZFxuICAgICAgICBzb3VyY2VtYXA6IHJvbGx1cFNvdXJjZU1hcE91dHB1dCxcbiAgICAgICAgZ2xvYmFsczogZ2xvYmFscyxcbiAgICAgICAgZXhwb3J0czogXCJhdXRvXCIsXG4gICAgICB9LFxuICAgIF07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgYnVuZGxlID0gYXdhaXQgcm9sbHVwKGlucHV0IGFzIGFueSk7XG4gICAgICAvLyBvbmx5IGxvZyB3YXRjaEZpbGVzIGF0IHZlcmJvc2UgbGV2ZWwgdG8gYXZvaWQgbm9pc3kgY29uc29sZSBvdXRwdXRcbiAgICAgIGxvZy52ZXJib3NlKGJ1bmRsZS53YXRjaEZpbGVzKTtcbiAgICAgIGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlT3V0cHV0cyhidW5kbGU6IFJvbGx1cEJ1aWxkKSB7XG4gICAgICAgIGZvciAoY29uc3Qgb3V0cHV0T3B0aW9ucyBvZiBvdXRwdXRzKSB7XG4gICAgICAgICAgYXdhaXQgYnVuZGxlLndyaXRlKG91dHB1dE9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGdlbmVyYXRlT3V0cHV0cyhidW5kbGUpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGJ1bmRsZTogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYnVpbGRCeUVudihcbiAgICBpc0RldjogYm9vbGVhbixcbiAgICBtb2RlOiBCdWlsZE1vZGUgPSBCdWlsZE1vZGUuQUxMLFxuICAgIGluY2x1ZGVzQXJnPzogc3RyaW5nIHwgc3RyaW5nW10sXG4gICAgZXh0ZXJuYWxzQXJnPzogc3RyaW5nIHwgc3RyaW5nW11cbiAgKSB7XG4gICAgLy8gbm90ZTogaW5jbHVkZXMgYW5kIGV4dGVybmFscyB3aWxsIGJlIHBhc3NlZCB0aHJvdWdoIGZyb20gcnVuKCkgaW50byB0aGlzIG1ldGhvZCBieSBjYWxsZXJzXG4gICAgdHJ5IHtcbiAgICAgIGRlbGV0ZVBhdGgoXCJsaWJcIik7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgLy8gZG8gbm90aGluZ1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgZGVsZXRlUGF0aChcImRpc3RcIik7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgLy8gZG8gbm90aGluZ1xuICAgIH1cbiAgICBmcy5ta2RpclN5bmMoXCJsaWJcIik7XG4gICAgZnMubWtkaXJTeW5jKFwiZGlzdFwiKTtcblxuICAgIGlmIChbQnVpbGRNb2RlLkFMTCwgQnVpbGRNb2RlLkJVSUxEXS5pbmNsdWRlcyhtb2RlKSkge1xuICAgICAgYXdhaXQgdGhpcy5idWlsZChpc0RldiwgTW9kZXMuRVNNKTtcbiAgICAgIGF3YWl0IHRoaXMuYnVpbGQoaXNEZXYsIE1vZGVzLkNKUyk7XG4gICAgICB0aGlzLnBhdGNoRmlsZXMoXCJsaWJcIik7XG4gICAgfVxuXG4gICAgaWYgKFtCdWlsZE1vZGUuQUxMLCBCdWlsZE1vZGUuQlVORExFXS5pbmNsdWRlcyhtb2RlKSkge1xuICAgICAgYXdhaXQgdGhpcy5idW5kbGUoXG4gICAgICAgIE1vZGVzLkVTTSxcbiAgICAgICAgaXNEZXYsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBcInNyYy9pbmRleC50c1wiLFxuICAgICAgICB0aGlzLnBrZ05hbWUsXG4gICAgICAgIGV4dGVybmFsc0FyZyxcbiAgICAgICAgaW5jbHVkZXNBcmdcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmJ1bmRsZShcbiAgICAgICAgTW9kZXMuQ0pTLFxuICAgICAgICBpc0RldixcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIFwic3JjL2luZGV4LnRzXCIsXG4gICAgICAgIHRoaXMucGtnTmFtZSxcbiAgICAgICAgZXh0ZXJuYWxzQXJnLFxuICAgICAgICBpbmNsdWRlc0FyZ1xuICAgICAgKTtcbiAgICAgIHRoaXMucGF0Y2hGaWxlcyhcImRpc3RcIik7XG4gICAgfVxuXG4gICAgdGhpcy5jb3B5QXNzZXRzKE1vZGVzLkNKUyk7XG4gICAgdGhpcy5jb3B5QXNzZXRzKE1vZGVzLkVTTSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEJ1aWxkcyB0aGUgcHJvamVjdCBmb3IgZGV2ZWxvcG1lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIHJ1bnMgdGhlIGJ1aWxkIHByb2Nlc3Mgd2l0aCBkZXZlbG9wbWVudC1zcGVjaWZpYyBjb25maWd1cmF0aW9ucy5cbiAgICogQHBhcmFtIHtCdWlsZE1vZGV9IFttb2RlPUJ1aWxkTW9kZS5BTExdIC0gVGhlIGJ1aWxkIG1vZGUgKGJ1aWxkLCBidW5kbGUsIG9yIGFsbCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfHN0cmluZ1tdfSBbaW5jbHVkZXNBcmddIC0gQSBsaXN0IG9mIGRlcGVuZGVuY2llcyB0byBpbmNsdWRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xzdHJpbmdbXX0gW2V4dGVybmFsc0FyZ10gLSBBIGxpc3Qgb2YgZXh0ZXJuYWwgZGVwZW5kZW5jaWVzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGJ1aWxkRGV2KFxuICAgIG1vZGU6IEJ1aWxkTW9kZSA9IEJ1aWxkTW9kZS5BTEwsXG4gICAgaW5jbHVkZXNBcmc/OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICBleHRlcm5hbHNBcmc/OiBzdHJpbmcgfCBzdHJpbmdbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5idWlsZEJ5RW52KHRydWUsIG1vZGUsIGluY2x1ZGVzQXJnLCBleHRlcm5hbHNBcmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCdWlsZHMgdGhlIHByb2plY3QgZm9yIHByb2R1Y3Rpb24uXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIHJ1bnMgdGhlIGJ1aWxkIHByb2Nlc3Mgd2l0aCBwcm9kdWN0aW9uLXNwZWNpZmljIGNvbmZpZ3VyYXRpb25zLFxuICAgKiBpbmNsdWRpbmcgbWluaWZpY2F0aW9uIGFuZCBvdGhlciBvcHRpbWl6YXRpb25zLlxuICAgKiBAcGFyYW0ge0J1aWxkTW9kZX0gW21vZGU9QnVpbGRNb2RlLkFMTF0gLSBUaGUgYnVpbGQgbW9kZSAoYnVpbGQsIGJ1bmRsZSwgb3IgYWxsKS5cbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IFtpbmNsdWRlc0FyZ10gLSBBIGxpc3Qgb2YgZGVwZW5kZW5jaWVzIHRvIGluY2x1ZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfHN0cmluZ1tdfSBbZXh0ZXJuYWxzQXJnXSAtIEEgbGlzdCBvZiBleHRlcm5hbCBkZXBlbmRlbmNpZXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgYnVpbGRQcm9kKFxuICAgIG1vZGU6IEJ1aWxkTW9kZSA9IEJ1aWxkTW9kZS5BTEwsXG4gICAgaW5jbHVkZXNBcmc/OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICBleHRlcm5hbHNBcmc/OiBzdHJpbmcgfCBzdHJpbmdbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5idWlsZEJ5RW52KGZhbHNlLCBtb2RlLCBpbmNsdWRlc0FyZywgZXh0ZXJuYWxzQXJnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2VuZXJhdGVzIHRoZSBwcm9qZWN0IGRvY3VtZW50YXRpb24uXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIHVzZXMgSlNEb2MgYW5kIG90aGVyIHRvb2xzIHRvIGdlbmVyYXRlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIHByb2plY3QuXG4gICAqIEl0IGFsc28gcGF0Y2hlcyB0aGUgUkVBRE1FLm1kIGZpbGUgd2l0aCB2ZXJzaW9uIGFuZCBwYWNrYWdlIHNpemUgaW5mb3JtYXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgYnVpbGREb2NzKCkge1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoYG5wbSBpbnN0YWxsIGJldHRlci1kb2NzIHRhZmZ5ZGJgKS5wcm9taXNlO1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoYG5weCBtYXJrZG93bi1pbmNsdWRlIC4vd29ya2RvY3MvcmVhZG1lLW1kLmpzb25gKS5wcm9taXNlO1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoXG4gICAgICBgbnB4IGpzZG9jIC1jIC4vd29ya2RvY3MvanNkb2NzLmpzb24gLXQgLi9ub2RlX21vZHVsZXMvYmV0dGVyLWRvY3NgXG4gICAgKS5wcm9taXNlO1xuICAgIGF3YWl0IHJ1bkNvbW1hbmQoYG5wbSByZW1vdmUgYmV0dGVyLWRvY3MgdGFmZnlkYmApLnByb21pc2U7XG4gICAgW1xuICAgICAge1xuICAgICAgICBzcmM6IFwid29ya2RvY3MvYXNzZXRzXCIsXG4gICAgICAgIGRlc3Q6IFwiLi9kb2NzL3dvcmtkb2NzL2Fzc2V0c1wiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3JjOiBcIndvcmtkb2NzL3JlcG9ydHMvY292ZXJhZ2VcIixcbiAgICAgICAgZGVzdDogXCIuL2RvY3Mvd29ya2RvY3MvcmVwb3J0cy9jb3ZlcmFnZVwiLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3JjOiBcIndvcmtkb2NzL3JlcG9ydHMvaHRtbFwiLFxuICAgICAgICBkZXN0OiBcIi4vZG9jcy93b3JrZG9jcy9yZXBvcnRzL2h0bWxcIixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHNyYzogXCJ3b3JrZG9jcy9yZXNvdXJjZXNcIixcbiAgICAgICAgZGVzdDogXCIuL2RvY3Mvd29ya2RvY3MvcmVzb3VyY2VzXCIsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzcmM6IFwiTElDRU5TRS5tZFwiLFxuICAgICAgICBkZXN0OiBcIi4vZG9jcy9MSUNFTlNFLm1kXCIsXG4gICAgICB9LFxuICAgIF0uZm9yRWFjaCgoZikgPT4ge1xuICAgICAgY29uc3QgeyBzcmMsIGRlc3QgfSA9IGY7XG4gICAgICBjb3B5RmlsZShzcmMsIGRlc3QpO1xuICAgIH0pO1xuXG4gICAgLy8gcGF0Y2ggLi9SRUFETUUubWQgZmlsZSB0byByZXBsYWNlIHZlcnNpb24vcGFja2FnZS9wYWNrYWdlIHNpemUgc3RyaW5nc1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzaXplS2IgPSBhd2FpdCBnZXRGaWxlU2l6ZVppcHBlZChcbiAgICAgICAgcGF0aC5yZXNvbHZlKHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBcImRpc3RcIikpXG4gICAgICApO1xuICAgICAgdGhpcy5yZXBsYWNlbWVudHNbUEFDS0FHRV9TSVpFX1NUUklOR10gPSBgJHtzaXplS2J9IEtCYDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGlmIHdlIGNvdWxkbid0IGNvbXB1dGUgc2l6ZSwgbGVhdmUgcGxhY2Vob2xkZXIgb3Igc2V0IHRvIHVua25vd25cbiAgICAgIHRoaXMucmVwbGFjZW1lbnRzW1BBQ0tBR0VfU0laRV9TVFJJTkddID0gXCJ1bmtub3duXCI7XG4gICAgfVxuXG4gICAgLy8gUGF0Y2ggUkVBRE1FLm1kIGluIHByb2plY3Qgcm9vdFxuICAgIHRyeSB7XG4gICAgICBwYXRjaEZpbGUoXCIuL1JFQURNRS5tZFwiLCB0aGlzLnJlcGxhY2VtZW50cyk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuYnVpbGREb2NzIGFzIGFueSk7XG4gICAgICBsb2cudmVyYm9zZShgRmFpbGVkIHRvIHBhdGNoIFJFQURNRS5tZDogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBydW48Uj4oXG4gICAgYW5zd2VyczogTG9nZ2luZ0NvbmZpZyAmXG4gICAgICB0eXBlb2YgRGVmYXVsdENvbW1hbmRWYWx1ZXMgJiB7IFtrIGluIGtleW9mIHR5cGVvZiBvcHRpb25zXTogdW5rbm93biB9XG4gICk6IFByb21pc2U8c3RyaW5nIHwgdm9pZCB8IFI+IHtcbiAgICBjb25zdCB7IGRldiwgcHJvZCwgZG9jcywgYnVpbGRNb2RlLCBpbmNsdWRlcywgZXh0ZXJuYWxzIH0gPSBhbnN3ZXJzIGFzIGFueTtcbiAgICBpZiAoZGV2KSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5idWlsZERldihidWlsZE1vZGUgYXMgQnVpbGRNb2RlLCBpbmNsdWRlcywgZXh0ZXJuYWxzKTtcbiAgICB9XG4gICAgaWYgKHByb2QpIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmJ1aWxkUHJvZChidWlsZE1vZGUgYXMgQnVpbGRNb2RlLCBpbmNsdWRlcywgZXh0ZXJuYWxzKTtcbiAgICB9XG4gICAgaWYgKGRvY3MpIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmJ1aWxkRG9jcygpO1xuICAgIH1cbiAgfVxufVxuIiwiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmltcG9ydCB7IHJ1bkNvbW1hbmQgfSBmcm9tIFwiLi4vLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IE5vQ0lGTGFnLCBTZW1WZXJzaW9uLCBTZW1WZXJzaW9uUmVnZXggfSBmcm9tIFwiLi4vLi4vdXRpbHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBVc2VySW5wdXQgfSBmcm9tIFwiLi4vLi4vaW5wdXQvaW5wdXRcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiLi4vY29tbWFuZFwiO1xuaW1wb3J0IHsgRGVmYXVsdENvbW1hbmRWYWx1ZXMgfSBmcm9tIFwiLi4vaW5kZXhcIjtcbmltcG9ydCB7IExvZ2dpbmdDb25maWcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcblxuY29uc3Qgb3B0aW9ucyA9IHtcbiAgY2k6IHtcbiAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICBkZWZhdWx0OiB0cnVlLFxuICB9LFxuICBtZXNzYWdlOiB7XG4gICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICBzaG9ydDogXCJtXCIsXG4gIH0sXG4gIHRhZzoge1xuICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgc2hvcnQ6IFwidFwiLFxuICAgIGRlZmF1bHQ6IHVuZGVmaW5lZCxcbiAgfSxcbn07XG5cbi8qKlxuICogQGNsYXNzIFJlbGVhc2VTY3JpcHRcbiAqIEBleHRlbmRzIHtDb21tYW5kfVxuICogQGNhdmVnb3J5IHNjcmlwdHNcbiAqIEBkZXNjcmlwdGlvbiBBIGNvbW1hbmQtbGluZSBzY3JpcHQgZm9yIG1hbmFnaW5nIHJlbGVhc2VzIGFuZCB2ZXJzaW9uIHVwZGF0ZXMuXG4gKiBAc3VtbWFyeSBUaGlzIHNjcmlwdCBhdXRvbWF0ZXMgdGhlIHByb2Nlc3Mgb2YgY3JlYXRpbmcgYW5kIHB1c2hpbmcgbmV3IHJlbGVhc2VzLiBJdCBoYW5kbGVzIHZlcnNpb24gdXBkYXRlcyxcbiAqIGNvbW1pdCBtZXNzYWdlcywgYW5kIG9wdGlvbmFsbHkgcHVibGlzaGVzIHRvIE5QTS4gVGhlIHNjcmlwdCBzdXBwb3J0cyBzZW1hbnRpYyB2ZXJzaW9uaW5nIGFuZCBjYW4gd29yayBpbiBib3RoIENJIGFuZCBub24tQ0kgZW52aXJvbm1lbnRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgc2NyaXB0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9wdGlvbnMuY2kgLSBXaGV0aGVyIHRoZSBzY3JpcHQgaXMgcnVubmluZyBpbiBhIENJIGVudmlyb25tZW50IChkZWZhdWx0OiB0cnVlKVxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMubWVzc2FnZSAtIFRoZSByZWxlYXNlIG1lc3NhZ2UgKHNob3J0OiAnbScpXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy50YWcgLSBUaGUgdmVyc2lvbiB0YWcgdG8gdXNlIChzaG9ydDogJ3QnLCBkZWZhdWx0OiB1bmRlZmluZWQpXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWxlYXNlU2NyaXB0IGV4dGVuZHMgQ29tbWFuZDx0eXBlb2Ygb3B0aW9ucywgdm9pZD4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihcIlJlbGVhc2VTY3JpcHRcIiwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIHRoZSB2ZXJzaW9uIGZvciB0aGUgcmVsZWFzZS5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgdmFsaWRhdGVzIHRoZSBwcm92aWRlZCB0YWcgb3IgcHJvbXB0cyB0aGUgdXNlciBmb3IgYSBuZXcgb25lIGlmIG5vdCBwcm92aWRlZCBvciBpbnZhbGlkLlxuICAgKiBJdCBhbHNvIGRpc3BsYXlzIHRoZSBsYXRlc3QgZ2l0IHRhZ3MgZm9yIHJlZmVyZW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyAtIFRoZSB2ZXJzaW9uIHRhZyB0byBwcmVwYXJlXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IFRoZSBwcmVwYXJlZCB2ZXJzaW9uIHRhZ1xuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBSIGFzIFJlbGVhc2VTY3JpcHRcbiAgICogICBwYXJ0aWNpcGFudCBUIGFzIFRlc3RWZXJzaW9uXG4gICAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VySW5wdXRcbiAgICogICBwYXJ0aWNpcGFudCBHIGFzIEdpdFxuICAgKiAgIFItPj5UOiB0ZXN0VmVyc2lvbih0YWcpXG4gICAqICAgYWx0IHRhZyBpcyB2YWxpZFxuICAgKiAgICAgVC0tPj5SOiByZXR1cm4gdGFnXG4gICAqICAgZWxzZSB0YWcgaXMgaW52YWxpZCBvciBub3QgcHJvdmlkZWRcbiAgICogICAgIFItPj5HOiBMaXN0IGxhdGVzdCBnaXQgdGFnc1xuICAgKiAgICAgUi0+PlU6IFByb21wdCBmb3IgbmV3IHRhZ1xuICAgKiAgICAgVS0tPj5SOiByZXR1cm4gbmV3IHRhZ1xuICAgKiAgIGVuZFxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZVZlcnNpb24odGFnPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5wcmVwYXJlVmVyc2lvbik7XG4gICAgdGFnID0gdGhpcy50ZXN0VmVyc2lvbigodGFnIGFzIHN0cmluZykgfHwgXCJcIik7XG4gICAgaWYgKCF0YWcpIHtcbiAgICAgIGxvZy52ZXJib3NlKFwiTm8gcmVsZWFzZSBtZXNzYWdlIHByb3ZpZGVkLiBQcm9tcHRpbmcgZm9yIG9uZTpcIik7XG4gICAgICBsb2cuaW5mbyhgTGlzdGluZyBsYXRlc3QgZ2l0IHRhZ3M6YCk7XG4gICAgICBhd2FpdCBydW5Db21tYW5kKFwiZ2l0IHRhZyAtLXNvcnQ9LXRhZ2dlcmRhdGUgfCBoZWFkIC1uIDVcIikucHJvbWlzZTtcbiAgICAgIHJldHVybiBhd2FpdCBVc2VySW5wdXQuaW5zaXN0Rm9yVGV4dChcbiAgICAgICAgXCJ0YWdcIixcbiAgICAgICAgXCJFbnRlciB0aGUgbmV3IHRhZyBudW1iZXIgKGFjY2VwdHMgdiouKi4qWy0uLi5dKVwiLFxuICAgICAgICAodmFsKSA9PlxuICAgICAgICAgICEhdmFsLnRvU3RyaW5nKCkubWF0Y2goL152WzAtOV0rXFwuWzAtOV0rLlswLTldKygtWzAtOWEtekEtWi1dKyk/JC8pXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGFnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUZXN0cyBpZiB0aGUgcHJvdmlkZWQgdmVyc2lvbiBpcyB2YWxpZC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSB2ZXJzaW9uIGlzIGEgdmFsaWQgc2VtYW50aWMgdmVyc2lvbiBvciBhIHByZWRlZmluZWQgdXBkYXRlIHR5cGUgKFBBVENILCBNSU5PUiwgTUFKT1IpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvbiAtIFRoZSB2ZXJzaW9uIHRvIHRlc3RcbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gVGhlIHZhbGlkYXRlZCB2ZXJzaW9uIG9yIHVuZGVmaW5lZCBpZiBpbnZhbGlkXG4gICAqL1xuICB0ZXN0VmVyc2lvbih2ZXJzaW9uOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnRlc3RWZXJzaW9uKTtcbiAgICB2ZXJzaW9uID0gdmVyc2lvbi50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICBzd2l0Y2ggKHZlcnNpb24pIHtcbiAgICAgIGNhc2UgU2VtVmVyc2lvbi5QQVRDSDpcbiAgICAgIGNhc2UgU2VtVmVyc2lvbi5NSU5PUjpcbiAgICAgIGNhc2UgU2VtVmVyc2lvbi5NQUpPUjpcbiAgICAgICAgbG9nLnZlcmJvc2UoYFVzaW5nIHByb3ZpZGVkIFNlbVZlciB1cGRhdGU6ICR7dmVyc2lvbn1gLCAxKTtcbiAgICAgICAgcmV0dXJuIHZlcnNpb247XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBsb2cudmVyYm9zZShcbiAgICAgICAgICBgVGVzdGluZyBwcm92aWRlZCB2ZXJzaW9uIGZvciBTZW1WZXIgY29tcGF0aWJpbGl0eTogJHt2ZXJzaW9ufWAsXG4gICAgICAgICAgMVxuICAgICAgICApO1xuICAgICAgICBpZiAoIW5ldyBSZWdFeHAoU2VtVmVyc2lvblJlZ2V4KS50ZXN0KHZlcnNpb24pKSB7XG4gICAgICAgICAgbG9nLmRlYnVnKGBJbnZhbGlkIHZlcnNpb24gbnVtYmVyOiAke3ZlcnNpb259YCk7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBsb2cudmVyYm9zZShgdmVyc2lvbiBhcHByb3ZlZDogJHt2ZXJzaW9ufWAsIDEpO1xuICAgICAgICByZXR1cm4gdmVyc2lvbjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIHRoZSByZWxlYXNlIG1lc3NhZ2UuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIGVpdGhlciByZXR1cm5zIHRoZSBwcm92aWRlZCBtZXNzYWdlIG9yIHByb21wdHMgdGhlIHVzZXIgZm9yIGEgbmV3IG9uZSBpZiBub3QgcHJvdmlkZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gLSBUaGUgcmVsZWFzZSBtZXNzYWdlXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IFRoZSBwcmVwYXJlZCByZWxlYXNlIG1lc3NhZ2VcbiAgICovXG4gIGFzeW5jIHByZXBhcmVNZXNzYWdlKG1lc3NhZ2U/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5wcmVwYXJlTWVzc2FnZSk7XG4gICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICBsb2cudmVyYm9zZShcIk5vIHJlbGVhc2UgbWVzc2FnZSBwcm92aWRlZC4gUHJvbXB0aW5nIGZvciBvbmVcIik7XG4gICAgICByZXR1cm4gYXdhaXQgVXNlcklucHV0Lmluc2lzdEZvclRleHQoXG4gICAgICAgIFwibWVzc2FnZVwiLFxuICAgICAgICBcIldoYXQgc2hvdWxkIGJlIHRoZSByZWxlYXNlIG1lc3NhZ2UvdGlja2V0P1wiLFxuICAgICAgICAodmFsKSA9PiAhIXZhbCAmJiB2YWwudG9TdHJpbmcoKS5sZW5ndGggPiA1XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUnVucyB0aGUgcmVsZWFzZSBzY3JpcHQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIG9yY2hlc3RyYXRlcyB0aGUgZW50aXJlIHJlbGVhc2UgcHJvY2VzcywgaW5jbHVkaW5nIHZlcnNpb24gcHJlcGFyYXRpb24sIG1lc3NhZ2UgY3JlYXRpb24sXG4gICAqIGdpdCBvcGVyYXRpb25zLCBhbmQgbnBtIHB1Ymxpc2hpbmcgKGlmIG5vdCBpbiBDSSBlbnZpcm9ubWVudCkuXG4gICAqIEBwYXJhbSB7UGFyc2VBcmdzUmVzdWx0fSBhcmdzIC0gVGhlIHBhcnNlZCBjb21tYW5kLWxpbmUgYXJndW1lbnRzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBSIGFzIFJlbGVhc2VTY3JpcHRcbiAgICogICBwYXJ0aWNpcGFudCBWIGFzIFByZXBhcmVWZXJzaW9uXG4gICAqICAgcGFydGljaXBhbnQgTSBhcyBQcmVwYXJlTWVzc2FnZVxuICAgKiAgIHBhcnRpY2lwYW50IE4gYXMgTlBNXG4gICAqICAgcGFydGljaXBhbnQgRyBhcyBHaXRcbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIFVzZXJJbnB1dFxuICAgKiAgIFItPj5WOiBwcmVwYXJlVmVyc2lvbih0YWcpXG4gICAqICAgUi0+Pk06IHByZXBhcmVNZXNzYWdlKG1lc3NhZ2UpXG4gICAqICAgUi0+Pk46IFJ1biBwcmVwYXJlLXJlbGVhc2Ugc2NyaXB0XG4gICAqICAgUi0+Pkc6IENoZWNrIGdpdCBzdGF0dXNcbiAgICogICBhbHQgY2hhbmdlcyBleGlzdFxuICAgKiAgICAgUi0+PlU6IEFzayBmb3IgY29uZmlybWF0aW9uXG4gICAqICAgICBVLS0+PlI6IENvbmZpcm1cbiAgICogICAgIFItPj5HOiBBZGQgYW5kIGNvbW1pdCBjaGFuZ2VzXG4gICAqICAgZW5kXG4gICAqICAgUi0+Pk46IFVwZGF0ZSBucG0gdmVyc2lvblxuICAgKiAgIFItPj5HOiBQdXNoIGNoYW5nZXMgYW5kIHRhZ3NcbiAgICogICBhbHQgbm90IENJIGVudmlyb25tZW50XG4gICAqICAgICBSLT4+TjogUHVibGlzaCB0byBucG1cbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIHJ1bihcbiAgICBhcmdzOiBMb2dnaW5nQ29uZmlnICZcbiAgICAgIHR5cGVvZiBEZWZhdWx0Q29tbWFuZFZhbHVlcyAmIHsgW2sgaW4ga2V5b2YgdHlwZW9mIG9wdGlvbnNdOiB1bmtub3duIH1cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IHJlc3VsdDogYW55O1xuICAgIGNvbnN0IHsgY2kgfSA9IGFyZ3M7XG4gICAgbGV0IHsgdGFnLCBtZXNzYWdlIH0gPSBhcmdzO1xuICAgIHRhZyA9IGF3YWl0IHRoaXMucHJlcGFyZVZlcnNpb24odGFnIGFzIHN0cmluZyk7XG4gICAgbWVzc2FnZSA9IGF3YWl0IHRoaXMucHJlcGFyZU1lc3NhZ2UobWVzc2FnZSBhcyBzdHJpbmcpO1xuICAgIHJlc3VsdCA9IGF3YWl0IHJ1bkNvbW1hbmQoYG5wbSBydW4gcHJlcGFyZS1yZWxlYXNlIC0tICR7dGFnfSAke21lc3NhZ2V9YCwge1xuICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIH0pLnByb21pc2U7XG4gICAgcmVzdWx0ID0gYXdhaXQgcnVuQ29tbWFuZChcImdpdCBzdGF0dXMgLS1wb3JjZWxhaW5cIikucHJvbWlzZTtcbiAgICBhd2FpdCByZXN1bHQ7XG4gICAgaWYgKFxuICAgICAgcmVzdWx0LmxvZ3MubGVuZ3RoICYmXG4gICAgICAoYXdhaXQgVXNlcklucHV0LmFza0NvbmZpcm1hdGlvbihcbiAgICAgICAgXCJnaXQtY2hhbmdlc1wiLFxuICAgICAgICBcIkRvIHlvdSB3YW50IHRvIHB1c2ggdGhlIGNoYW5nZXMgdG8gdGhlIHJlbW90ZSByZXBvc2l0b3J5P1wiLFxuICAgICAgICB0cnVlXG4gICAgICApKVxuICAgICkge1xuICAgICAgYXdhaXQgcnVuQ29tbWFuZChcImdpdCBhZGQgLlwiKS5wcm9taXNlO1xuICAgICAgYXdhaXQgcnVuQ29tbWFuZChcbiAgICAgICAgYGdpdCBjb21taXQgLW0gXCIke3RhZ30gLSAke21lc3NhZ2V9IC0gYWZ0ZXIgcmVsZWFzZSBwcmVwYXJhdGlvbiR7Y2kgPyBcIlwiIDogTm9DSUZMYWd9XCJgXG4gICAgICApLnByb21pc2U7XG4gICAgfVxuICAgIGF3YWl0IHJ1bkNvbW1hbmQoXG4gICAgICBgbnBtIHZlcnNpb24gXCIke3RhZ31cIiAtbSBcIiR7bWVzc2FnZX0ke2NpID8gXCJcIiA6IE5vQ0lGTGFnfVwiYFxuICAgICkucHJvbWlzZTtcbiAgICBhd2FpdCBydW5Db21tYW5kKFwiZ2l0IHB1c2ggLS1mb2xsb3ctdGFnc1wiKS5wcm9taXNlO1xuICAgIGlmICghY2kpIHtcbiAgICAgIGF3YWl0IHJ1bkNvbW1hbmQoXCJOUE1fVE9LRU49JChjYXQgLm5wbXRva2VuKSBucG0gcHVibGlzaCAtLWFjY2VzcyBwdWJsaWNcIilcbiAgICAgICAgLnByb21pc2U7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBTdGFuZGFyZE91dHB1dFdyaXRlciB9IGZyb20gXCIuL1N0YW5kYXJkT3V0cHV0V3JpdGVyXCI7XG5pbXBvcnQgeyBQcm9taXNlRXhlY3V0b3IgfSBmcm9tIFwiLi4vdXRpbHMvdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBzcGVjaWFsaXplZCBvdXRwdXQgd3JpdGVyIHRoYXQgdXNlcyByZWd1bGFyIGV4cHJlc3Npb25zIHRvIHByb2Nlc3Mgb3V0cHV0LlxuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBleHRlbmRzIFN0YW5kYXJkT3V0cHV0V3JpdGVyIHRvIHByb3ZpZGUgcmVnZXgtYmFzZWQgb3V0cHV0IHByb2Nlc3NpbmcuXG4gKiBJdCBhbGxvd3MgZm9yIHBhdHRlcm4gbWF0Y2hpbmcgaW4gdGhlIG91dHB1dCBzdHJlYW0gYW5kIGNhbiB0cmlnZ2VyIHNwZWNpZmljIGFjdGlvbnNcbiAqIGJhc2VkIG9uIG1hdGNoZWQgcGF0dGVybnMuXG4gKlxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgcmVzb2x2ZWQgdmFsdWUsIGRlZmF1bHRpbmcgdG8gc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBjbWQgLSBUaGUgY29tbWFuZCBzdHJpbmcgdG8gYmUgZXhlY3V0ZWQuXG4gKiBAcGFyYW0gbG9jayAtIEEgUHJvbWlzZUV4ZWN1dG9yIHRvIGNvbnRyb2wgdGhlIGFzeW5jaHJvbm91cyBmbG93LlxuICogQHBhcmFtIHJlZ2V4cCAtIEEgc3RyaW5nIG9yIFJlZ0V4cCB0byBtYXRjaCBhZ2FpbnN0IHRoZSBvdXRwdXQuXG4gKiBAcGFyYW0gZmxhZ3MgLSBPcHRpb25hbCBmbGFncyBmb3IgdGhlIFJlZ0V4cCBjb25zdHJ1Y3RvciwgZGVmYXVsdHMgdG8gXCJnXCIuXG4gKlxuICogQGNsYXNzXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmVnZXhwT3V0cHV0V3JpdGVyIH0gZnJvbSAnQGRlY2FmLXRzL3V0aWxzJztcbiAqIGltcG9ydCB7IFByb21pc2VFeGVjdXRvciB9IGZyb20gJ0BkZWNhZi10cy91dGlscyc7XG4gKiBcbiAqIC8vIENyZWF0ZSBhIHByb21pc2UgZXhlY3V0b3JcbiAqIGNvbnN0IGV4ZWN1dG9yOiBQcm9taXNlRXhlY3V0b3I8c3RyaW5nLCBFcnJvcj4gPSB7XG4gKiAgIHJlc29sdmU6ICh2YWx1ZSkgPT4gY29uc29sZS5sb2coYFJlc29sdmVkOiAke3ZhbHVlfWApLFxuICogICByZWplY3Q6IChlcnJvcikgPT4gY29uc29sZS5lcnJvcihgUmVqZWN0ZWQ6ICR7ZXJyb3IubWVzc2FnZX1gKVxuICogfTtcbiAqIFxuICogLy8gQ3JlYXRlIGEgcmVnZXhwIG91dHB1dCB3cml0ZXIgdGhhdCBtYXRjaGVzIHZlcnNpb24gbnVtYmVyc1xuICogY29uc3Qgd3JpdGVyID0gbmV3IFJlZ2V4cE91dHB1dFdyaXRlcignbm9kZSAtLXZlcnNpb24nLCBleGVjdXRvciwgL3YoXFxkK1xcLlxcZCtcXC5cXGQrKS8pO1xuICogXG4gKiAvLyBVc2UgdGhlIHdyaXRlciB0byBoYW5kbGUgY29tbWFuZCBvdXRwdXRcbiAqIHdyaXRlci5kYXRhKCd2MTQuMTcuMCcpOyAgLy8gVGhpcyB3aWxsIGF1dG9tYXRpY2FsbHkgcmVzb2x2ZSB3aXRoIFwidjE0LjE3LjBcIlxuICogYGBgXG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgUmVnZXhwT3V0cHV0V3JpdGVyXG4gKiAgIHBhcnRpY2lwYW50IFN0YW5kYXJkT3V0cHV0V3JpdGVyXG4gKiAgIHBhcnRpY2lwYW50IExvZ2dlclxuICogICBcbiAqICAgQ2xpZW50LT4+UmVnZXhwT3V0cHV0V3JpdGVyOiBuZXcgUmVnZXhwT3V0cHV0V3JpdGVyKGNtZCwgbG9jaywgcmVnZXhwLCBmbGFncylcbiAqICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IHN1cGVyKGNtZCwgbG9jaylcbiAqICAgU3RhbmRhcmRPdXRwdXRXcml0ZXItPj5Mb2dnZXI6IExvZ2dpbmcuZm9yKGNtZClcbiAqICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+UmVnZXhwT3V0cHV0V3JpdGVyOiBjb21waWxlIHJlZ2V4cFxuICogICBcbiAqICAgQ2xpZW50LT4+UmVnZXhwT3V0cHV0V3JpdGVyOiBkYXRhKGNodW5rKVxuICogICBSZWdleHBPdXRwdXRXcml0ZXItPj5TdGFuZGFyZE91dHB1dFdyaXRlcjogc3VwZXIuZGF0YShjaHVuaylcbiAqICAgU3RhbmRhcmRPdXRwdXRXcml0ZXItPj5Mb2dnZXI6IGxvZ2dlci5pbmZvKGxvZylcbiAqICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+UmVnZXhwT3V0cHV0V3JpdGVyOiB0ZXN0QW5kUmVzb2x2ZShjaHVuaylcbiAqICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+UmVnZXhwT3V0cHV0V3JpdGVyOiB0ZXN0KGNodW5rKVxuICogICBhbHQgbWF0Y2ggZm91bmRcbiAqICAgICBSZWdleHBPdXRwdXRXcml0ZXItPj5SZWdleHBPdXRwdXRXcml0ZXI6IHJlc29sdmUobWF0Y2hbMF0pXG4gKiAgICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IHJlc29sdmUobWF0Y2hbMF0pXG4gKiAgIGVuZFxuICogICBcbiAqICAgQ2xpZW50LT4+UmVnZXhwT3V0cHV0V3JpdGVyOiBlcnJvcihjaHVuaylcbiAqICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IHN1cGVyLmVycm9yKGNodW5rKVxuICogICBTdGFuZGFyZE91dHB1dFdyaXRlci0+PkxvZ2dlcjogbG9nZ2VyLmluZm8obG9nKVxuICogICBSZWdleHBPdXRwdXRXcml0ZXItPj5SZWdleHBPdXRwdXRXcml0ZXI6IHRlc3RBbmRSZWplY3QoY2h1bmspXG4gKiAgIFJlZ2V4cE91dHB1dFdyaXRlci0+PlJlZ2V4cE91dHB1dFdyaXRlcjogdGVzdChjaHVuaylcbiAqICAgYWx0IG1hdGNoIGZvdW5kXG4gKiAgICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+UmVnZXhwT3V0cHV0V3JpdGVyOiByZWplY3QobWF0Y2hbMF0pXG4gKiAgICAgUmVnZXhwT3V0cHV0V3JpdGVyLT4+U3RhbmRhcmRPdXRwdXRXcml0ZXI6IHJlamVjdChtYXRjaFswXSlcbiAqICAgZW5kXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWdleHBPdXRwdXRXcml0ZXIgZXh0ZW5kcyBTdGFuZGFyZE91dHB1dFdyaXRlcjxzdHJpbmc+IHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgcmVndWxhciBleHByZXNzaW9uIHVzZWQgZm9yIG1hdGNoaW5nIG91dHB1dC5cbiAgICogQHN1bW1hcnkgVGhpcyByZWFkb25seSBwcm9wZXJ0eSBzdG9yZXMgdGhlIGNvbXBpbGVkIFJlZ0V4cCB1c2VkIGZvciBwYXR0ZXJuIG1hdGNoaW5nLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlZ2V4cDogUmVnRXhwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGNtZDogc3RyaW5nLFxuICAgIGxvY2s6IFByb21pc2VFeGVjdXRvcjxzdHJpbmcsIEVycm9yPixcbiAgICByZWdleHA6IHN0cmluZyB8IFJlZ0V4cCxcbiAgICBmbGFncyA9IFwiZ1wiXG4gICkge1xuICAgIHN1cGVyKGNtZCwgbG9jayk7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVnZXhwID1cbiAgICAgICAgdHlwZW9mIHJlZ2V4cCA9PT0gXCJzdHJpbmdcIiA/IG5ldyBSZWdFeHAocmVnZXhwLCBmbGFncykgOiByZWdleHA7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbjogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGVzdHMgdGhlIGlucHV0IGRhdGEgYWdhaW5zdCB0aGUgc3RvcmVkIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAgICogQHN1bW1hcnkgRXhlY3V0ZXMgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBvbiB0aGUgaW5wdXQgZGF0YSBhbmQgcmV0dXJucyB0aGUgbWF0Y2ggcmVzdWx0LlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBzdHJpbmcgdG8gdGVzdCBhZ2FpbnN0IHRoZSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgcmVndWxhciBleHByZXNzaW9uIGV4ZWN1dGlvbiwgb3IgdW5kZWZpbmVkIGlmIGFuIGVycm9yIG9jY3Vycy5cbiAgICovXG4gIHByaXZhdGUgdGVzdChkYXRhOiBzdHJpbmcpIHtcbiAgICB0aGlzLnJlZ2V4cC5sYXN0SW5kZXggPSAwO1xuICAgIGxldCBtYXRjaDtcbiAgICB0cnkge1xuICAgICAgbWF0Y2ggPSB0aGlzLnJlZ2V4cC5leGVjKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHJldHVybiBjb25zb2xlLmRlYnVnKGBGYWlsZWQgdG8gcGFyc2UgY2h1bms6ICR7ZGF0YX1cXG5FcnJvcjogJHtlfSBgKTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUZXN0cyB0aGUgZGF0YSBhbmQgcmVzb2x2ZXMgdGhlIHByb21pc2UgaWYgYSBtYXRjaCBpcyBmb3VuZC5cbiAgICogQHN1bW1hcnkgRXhlY3V0ZXMgdGhlIHRlc3QgbWV0aG9kIGFuZCByZXNvbHZlcyB0aGUgcHJvbWlzZSB3aXRoIHRoZSBmaXJzdCBtYXRjaCBncm91cCBpZiBzdWNjZXNzZnVsLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBzdHJpbmcgdG8gdGVzdCBhZ2FpbnN0IHRoZSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgdGVzdEFuZFJlc29sdmUoZGF0YTogc3RyaW5nKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLnRlc3QoZGF0YSk7XG4gICAgaWYgKG1hdGNoKSB0aGlzLnJlc29sdmUobWF0Y2hbMF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUZXN0cyB0aGUgZGF0YSBhbmQgcmVqZWN0cyB0aGUgcHJvbWlzZSBpZiBhIG1hdGNoIGlzIGZvdW5kLlxuICAgKiBAc3VtbWFyeSBFeGVjdXRlcyB0aGUgdGVzdCBtZXRob2QgYW5kIHJlamVjdHMgdGhlIHByb21pc2Ugd2l0aCB0aGUgZmlyc3QgbWF0Y2ggZ3JvdXAgaWYgc3VjY2Vzc2Z1bC5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBUaGUgc3RyaW5nIHRvIHRlc3QgYWdhaW5zdCB0aGUgcmVndWxhciBleHByZXNzaW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIHRlc3RBbmRSZWplY3QoZGF0YTogc3RyaW5nKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLnRlc3QoZGF0YSk7XG4gICAgaWYgKG1hdGNoKSB0aGlzLnJlamVjdChtYXRjaFswXSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByb2Nlc3NlcyBpbmNvbWluZyBkYXRhIGNodW5rcy5cbiAgICogQHN1bW1hcnkgQ2FsbHMgdGhlIHBhcmVudCBjbGFzcyBkYXRhIG1ldGhvZCBhbmQgdGhlbiB0ZXN0cyB0aGUgZGF0YSBmb3IgYSBtYXRjaCB0byBwb3RlbnRpYWxseSByZXNvbHZlIHRoZSBwcm9taXNlLlxuICAgKlxuICAgKiBAcGFyYW0gY2h1bmsgLSBUaGUgZGF0YSBjaHVuayB0byBwcm9jZXNzLlxuICAgKi9cbiAgb3ZlcnJpZGUgZGF0YShjaHVuazogYW55KSB7XG4gICAgc3VwZXIuZGF0YShjaHVuayk7XG4gICAgdGhpcy50ZXN0QW5kUmVzb2x2ZShTdHJpbmcoY2h1bmspKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJvY2Vzc2VzIGluY29taW5nIGVycm9yIGNodW5rcy5cbiAgICogQHN1bW1hcnkgQ2FsbHMgdGhlIHBhcmVudCBjbGFzcyBlcnJvciBtZXRob2QgYW5kIHRoZW4gdGVzdHMgdGhlIGRhdGEgZm9yIGEgbWF0Y2ggdG8gcG90ZW50aWFsbHkgcmVqZWN0IHRoZSBwcm9taXNlLlxuICAgKlxuICAgKiBAcGFyYW0gY2h1bmsgLSBUaGUgZXJyb3IgY2h1bmsgdG8gcHJvY2Vzcy5cbiAgICovXG4gIG92ZXJyaWRlIGVycm9yKGNodW5rOiBhbnkpIHtcbiAgICBzdXBlci5lcnJvcihjaHVuayk7XG4gICAgdGhpcy50ZXN0QW5kUmVqZWN0KFN0cmluZyhjaHVuaykpO1xuICB9XG59XG4iLCJleHBvcnQgKiBmcm9tIFwiLi9jbGlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2lucHV0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vdXRwdXRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi93cml0ZXJzXCI7XG5cbi8qKlxuICogQG1vZHVsZSB1dGlsc1xuICogQGRlc2NyaXB0aW9uIFV0aWxpdGllcyBhbmQgYnVpbGRpbmcgYmxvY2tzIGZvciBEZWNhZi1UUyBDTEkgYW5kIHNjcmlwdGluZy5cbiAqIEBzdW1tYXJ5IEFnZ3JlZ2F0ZXMgQ0xJIGNvbW1hbmQgaW5mcmFzdHJ1Y3R1cmUsIGlucHV0IGhlbHBlcnMsIG91dHB1dCB3cml0ZXJzLCBmaWxlc3lzdGVtL25ldHdvcmsgdXRpbGl0aWVzLFxuICogYW5kIHNoYXJlZCB0eXBlcy4gQ29uc3VtZXJzIHR5cGljYWxseSB1c2Uge0BsaW5rIENvbW1hbmR9LCB7QGxpbmsgVXNlcklucHV0fSwge0BsaW5rIFN0YW5kYXJkT3V0cHV0V3JpdGVyfSxcbiAqIHtAbGluayBwcmludEJhbm5lcn0sIGFuZCB1dGlsaXRpZXMgZnJvbSB7QGxpbmsgbW9kdWxlOnV0aWxzfHV0aWxzfS5cbiAqXG4gKiBUaGlzIGVudHJ5cG9pbnQgcmUtZXhwb3J0cyBzdWJwYWNrYWdlczpcbiAqIC0gQ0xJIGZyYW1ld29yayB1bmRlciBgLi9jbGlgIChjb21tYW5kIGJhc2UsIG9wdGlvbnMsIGJ1aWx0LWluIGNvbW1hbmRzKVxuICogLSBJbnB1dCBoZWxwZXJzIHVuZGVyIGAuL2lucHV0YCAocHJvbXB0aW5nIGFuZCBhcmcgcGFyc2luZylcbiAqIC0gT3V0cHV0IGhlbHBlcnMgdW5kZXIgYC4vb3V0cHV0YCAoYmFubmVyIGFuZCBzdHlsaW5nKVxuICogLSBHZW5lcmFsIHV0aWxpdGllcyB1bmRlciBgLi91dGlsc2AgKGZzLCBodHRwLCBleGVjLCB0eXBlcylcbiAqIC0gV3JpdGVycyB1bmRlciBgLi93cml0ZXJzYCAoc3Rkb3V0L3N0ZGVyciBwcm9jZXNzb3JzKVxuICpcbiAqIE5vdGU6IEluZGl2aWR1YWwgZXhwb3J0cyBhcmUgZG9jdW1lbnRlZCBpbiB0aGVpciBzb3VyY2UgZmlsZXMuXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSBtb2R1bGUuXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIHZlcnNpb24gZm9yIHRoZSBAZGVjYWYtdHMvdXRpbHMgcGFja2FnZS4gVGhlIGJ1aWxkIHJlcGxhY2VzXG4gKiB0aGUgcGxhY2Vob2xkZXIgd2l0aCB0aGUgYWN0dWFsIHZlcnNpb24gbnVtYmVyIGF0IHB1Ymxpc2ggdGltZS5cbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnV0aWxzXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIG1vZHVsZS5cbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgdmVyc2lvbiBmb3IgdGhlIEBkZWNhZi10cy91dGlscyBwYWNrYWdlLiBUaGUgYnVpbGQgcmVwbGFjZXNcbiAqIHRoZSBwbGFjZWhvbGRlciB3aXRoIHRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgYXQgcHVibGlzaCB0aW1lLlxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dXRpbHNcbiAqL1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9IFwiIyNQQUNLQUdFIyNcIjtcbiJdLCJuYW1lcyI6WyJVc2VySW5wdXQiLCJ0aGlzIiwibG9nZ2VyIiwiTG9nZ2luZyIsImZvciIsImNvbnN0cnVjdG9yIiwibmFtZSIsInR5cGUiLCJzZXRUeXBlIiwidmVyYm9zZSIsInNldE1lc3NhZ2UiLCJ2YWx1ZSIsIm1lc3NhZ2UiLCJzZXRJbml0aWFsIiwiaW5pdGlhbCIsInNldFN0eWxlIiwic3R5bGUiLCJzZXRGb3JtYXQiLCJmb3JtYXQiLCJzZXRWYWxpZGF0ZSIsInZhbGlkYXRlIiwic2V0T25TdGF0ZSIsIm9uU3RhdGUiLCJzZXRNaW4iLCJtaW4iLCJzZXRNYXgiLCJtYXgiLCJzZXRGbG9hdCIsImZsb2F0Iiwic2V0Um91bmQiLCJyb3VuZCIsInNldEluc3RydWN0aW9ucyIsImluc3RydWN0aW9ucyIsInNldEluY3JlbWVudCIsImluY3JlbWVudCIsInNldFNlcGFyYXRvciIsInNlcGFyYXRvciIsInNldEFjdGl2ZSIsImFjdGl2ZSIsInNldEluYWN0aXZlIiwiaW5hY3RpdmUiLCJzZXRDaG9pY2VzIiwiSlNPTiIsInN0cmluZ2lmeSIsImNob2ljZXMiLCJzZXRIaW50IiwiaGludCIsInNldFdhcm4iLCJ3YXJuIiwic2V0U3VnZ2VzdCIsInN1Z2dlc3QiLCJzZXRMaW1pdCIsImxpbWl0Iiwic2V0TWFzayIsIm1hc2siLCJzZXRTdGRvdXQiLCJzdGRvdXQiLCJzZXRTdGRpbiIsInN0ZGluIiwiYXNrIiwicXVlc3Rpb24iLCJsb2ciLCJBcnJheSIsImlzQXJyYXkiLCJhbnN3ZXJzIiwibWFwIiwicSIsImpvaW4iLCJwcm9tcHRzIiwiZXJyb3IiLCJFcnJvciIsImFza051bWJlciIsInVzZXJJbnB1dCIsImFza1RleHQiLCJ1bmRlZmluZWQiLCJhc2tDb25maXJtYXRpb24iLCJpbnNpc3QiLCJpbnB1dCIsInRlc3QiLCJkZWZhdWx0Q29uZmlybWF0aW9uIiwidG9TdHJpbmciLCJyZXN1bHQiLCJjb3VudCIsImNvbmZpcm1hdGlvbiIsImUiLCJpbmZvIiwiaW5zaXN0Rm9yVGV4dCIsImluc2lzdEZvck51bWJlciIsInBhcnNlQXJncyIsIm9wdGlvbnMiLCJhcmdzIiwicHJvY2VzcyIsImFyZ3YiLCJzbGljZSIsImRlYnVnIiwiRGVmYXVsdENvbW1hbmRPcHRpb25zIiwic2hvcnQiLCJkZWZhdWx0IiwidmVyc2lvbiIsImhlbHAiLCJsb2dMZXZlbCIsImxvZ1N0eWxlIiwidGltZXN0YW1wIiwiYmFubmVyIiwiRGVmYXVsdENvbW1hbmRWYWx1ZXMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYWNjIiwia2V5IiwiRW5jb2RpbmciLCJTZW1WZXJzaW9uUmVnZXgiLCJleHBvcnRzIiwiU2VtVmVyc2lvbiIsIk5vQ0lGTGFnIiwiU2V0dXBTY3JpcHRLZXkiLCJUb2tlbnMiLCJBYm9ydENvZGUiLCJTdGFuZGFyZE91dHB1dFdyaXRlciIsImNtZCIsImxvY2siLCJkYXRhIiwiQnVmZmVyIiwiaXNCdWZmZXIiLCJyZWQiLCJ0ZXh0IiwiY2h1bmsiLCJTdHJpbmciLCJlcnJvcnMiLCJlcnIiLCJleGl0IiwiY29kZSIsImxvZ3MiLCJncmVlbiIsInJlc29sdmUiLCJsIiwidHJpbSIsInJlamVjdCIsImxlbmd0aCIsInBhcnNlQ29tbWFuZCIsImNvbW1hbmQiLCJwYXJ0cyIsInBhcnNlIiwiZmlsdGVyIiwicCIsInJlYXNvbiIsImxvY2tpZnkiLCJmIiwiUHJvbWlzZSIsInBhcmFtcyIsInRoZW4iLCJjYXRjaCIsImNoYWluQWJvcnRDb250cm9sbGVyIiwiYXJndW1lbnQwIiwicmVtYWluZGVyIiwic2lnbmFscyIsImNvbnRyb2xsZXIiLCJBYm9ydFNpZ25hbCIsIkFib3J0Q29udHJvbGxlciIsInNpZ25hbCIsImFib3J0ZWQiLCJoYW5kbGVyIiwiYWJvcnQiLCJhZGRFdmVudExpc3RlbmVyIiwib25jZSIsInNwYXduQ29tbWFuZCIsIm91dHB1dCIsIm9wdHMiLCJzcGF3bklubmVyIiwiYXJneiIsImNoaWxkUHJvY2VzcyIsInNwYXduIiwiY3dkIiwiZW52IiwiYXNzaWduIiwiUEFUSCIsInNoZWxsIiwicGlkIiwibSIsIm1hdGNoIiwiaW5jbHVkZXMiLCJjbWRzIiwic3BsaXQiLCJzcGF3bnMiLCJjb250cm9sbGVycyIsImkiLCJwdXNoIiwicGlwZSIsInJ1bkNvbW1hbmQiLCJvdXRwdXRDb25zdHJ1Y3RvciIsImVycnMiLCJzZXRFbmNvZGluZyIsIm9uIiwic3RkZXJyIiwicHJvbWlzZSIsImFzeW5jIiwiY2IiLCJwYXRjaFN0cmluZyIsInZhbHVlcyIsImZsYWdzIiwiZW50cmllcyIsImZvckVhY2giLCJ2YWwiLCJyZWdleHAiLCJSZWdFeHAiLCJlc2NhcGVSZWdFeHAiLCJyZXBsYWNlIiwic3ViU3RyIiwicGF0Y2hGaWxlIiwicGF0aCIsImZzIiwiZXhpc3RzU3luYyIsImNvbnRlbnQiLCJyZWFkRmlsZSIsIndyaXRlRmlsZSIsInJlYWRGaWxlU3luYyIsIndyaXRlRmlsZVN5bmMiLCJnZXRBbGxGaWxlcyIsImZpbGVzIiwicmVhZGRpclN5bmMiLCJlbnRyeSIsImZ1bGxQYXRoIiwic3RhdCIsInN0YXRTeW5jIiwiaXNGaWxlIiwiaXNEaXJlY3RvcnkiLCJyZW5hbWVGaWxlIiwic291cmNlIiwiZGVzdCIsImRlc2NyaXB0b3JTb3VyY2UiLCJkZXNjcmlwdG9yRGVzdCIsInJlbmFtZVN5bmMiLCJjb3B5RmlsZSIsIm1rZGlyU3luYyIsInJlY3Vyc2l2ZSIsImNwU3luYyIsImRlbGV0ZVBhdGgiLCJkZXNjcmlwdG9yIiwicm1TeW5jIiwiZm9yY2UiLCJnZXRQYWNrYWdlIiwicHJvcGVydHkiLCJwa2ciLCJzZXRQYWNrYWdlQXR0cmlidXRlIiwiYXR0ciIsImdldFBhY2thZ2VWZXJzaW9uIiwiZ2V0RGVwZW5kZW5jaWVzIiwibWFwcGVyIiwiaW5kZXgiLCJwcm9kIiwiZGVwZW5kZW5jaWVzIiwiZGV2IiwiZGV2RGVwZW5kZW5jaWVzIiwicGVlciIsInBlZXJEZXBlbmRlbmNpZXMiLCJ1cGRhdGVEZXBlbmRlbmNpZXMiLCJpbnN0YWxsSWZOb3RBdmFpbGFibGUiLCJkZXBzIiwiZCIsImluc3RhbGxlZCIsImZyb20iLCJTZXQiLCJ0b0luc3RhbGwiLCJpbnN0YWxsRGVwZW5kZW5jaWVzIiwicHVzaFRvR2l0IiwiZ2l0VXNlciIsImdpdEVtYWlsIiwibm9ybWFsaXplSW1wb3J0IiwiaW1wb3J0UHJvbWlzZSIsImdldEZpbGVTaXplWmlwcGVkIiwiZGlyIiwiY2FuZGlkYXRlcyIsInMiLCJlbmRzV2l0aCIsInNtYWxsZXN0Iiwic21hbGxlc3RTaXplIiwic2l6ZSIsImMiLCJidWZmZXIiLCJneiIsInpsaWIiLCJnemlwU3luYyIsInNpemVLYiIsIk51bWJlciIsInRvRml4ZWQiLCJsaXN0Rm9sZGVyIiwiYmFzZVBhdGgiLCJ3aXRoRmlsZVR5cGVzIiwibmFtZXMiLCJsaXN0Tm9kZU1vZHVsZXNQYWNrYWdlcyIsInN0YXJ0c1dpdGgiLCJzY29wZVBhdGgiLCJzY29wZWQiLCJzbG9nYW5zIiwiU2xvZ2FuIiwiVGFncyIsImNvbG9ycyIsInByaW50QmFubmVyIiwiZ2V0U2xvZ2FuIiwibWF4TGVuZ3RoIiwibGluZSIsIk1hdGgiLCJwYWRTdGFydCIsImJpbmQiLCJjb25zb2xlIiwicmF3IiwiZmxvb3IiLCJyYW5kb20iLCJDb21tYW5kIiwiTG9nZ2VkQ2xhc3MiLCJpbnB1dHMiLCJyZXF1aXJlbWVudHMiLCJzdXBlciIsImRlZmluZVByb3BlcnR5Iiwid3JpdGFibGUiLCJjaGVja1JlcXVpcmVtZW50cyIsIm1pc3NpbmciLCJmdWxsTGlzdCIsImRlcCIsImV4ZWN1dGUiLCJMb2dnZWRFbnZpcm9ubWVudCIsImFjY3VtdWxhdGUiLCJjb250ZXh0IiwicnVuIiwiSHR0cENsaWVudCIsImRvd25sb2FkRmlsZSIsInVybCIsInJlcXVlc3QiLCJlbmNvZGVVUkkiLCJodHRwcyIsImdldCIsInJlcyIsInN0YXR1c0NvZGUiLCJoZWFkZXJzIiwibG9jYXRpb24iLCJwYXJzZUxpc3QiLCJCb29sZWFuIiwicGFja2FnZVRvR2xvYmFsIiwid2l0aG91dFNjb3BlIiwiY2hhckF0IiwidG9VcHBlckNhc2UiLCJnZXRQYWNrYWdlRGVwZW5kZW5jaWVzIiwiaGFzRGVwcyIsImZhbGxiYWNrRGlyIiwiX19kaXJuYW1lIiwiVkVSU0lPTl9TVFJJTkciLCJQQUNLQUdFX1NUUklORyIsIlBBQ0tBR0VfU0laRV9TVFJJTkciLCJNb2RlcyIsIkJ1aWxkTW9kZSIsImJ1aWxkTW9kZSIsIkFMTCIsImV4dGVybmFscyIsImRvY3MiLCJjb21tYW5kcyIsImNqczJUcmFuc2Zvcm1lciIsImV4dCIsIkJ1aWxkU2NyaXB0cyIsInJlc29sdXRpb25DYWNoZSIsIk1hcCIsInRyYW5zZm9ybWF0aW9uQ29udGV4dCIsInNvdXJjZUZpbGUiLCJzb3VyY2VEaXIiLCJkaXJuYW1lIiwiZmlsZU5hbWUiLCJyZXNvbHZlUGF0aCIsImltcG9ydFBhdGgiLCJjYWNoZUtleSIsImNhY2hlZFZhbHVlIiwicmVzb2x2ZWRQYXRoIiwiZTIiLCJpc0Fic29sdXRlIiwiZXh0ZW5zaW9uIiwiZXhlYyIsImJhc2VuYW1lIiwicmVsYXRpdmUiLCJzZXQiLCJ2aXNpdE5vZGUiLCJub2RlIiwic2hvdWxkTXV0YXRlTW9kdWxlU3BlY2lmaWVyIiwidHMiLCJpc0ltcG9ydERlY2xhcmF0aW9uIiwibW9kdWxlU3BlY2lmaWVyIiwibmV3TW9kdWxlU3BlY2lmaWVyIiwiZmFjdG9yeSIsImNyZWF0ZVN0cmluZ0xpdGVyYWwiLCJ1cGRhdGVJbXBvcnREZWNsYXJhdGlvbiIsIm1vZGlmaWVycyIsImltcG9ydENsYXVzZSIsImlzRXhwb3J0RGVjbGFyYXRpb24iLCJ1cGRhdGVFeHBvcnREZWNsYXJhdGlvbiIsImlzVHlwZU9ubHkiLCJleHBvcnRDbGF1c2UiLCJ2aXNpdEVhY2hDaGlsZCIsImlzU3RyaW5nTGl0ZXJhbCIsImV4dG5hbWUiLCJyZXBsYWNlbWVudHMiLCJwa2dOYW1lIiwicGtnVmVyc2lvbiIsInBhdGNoRmlsZXMiLCJmaWxlIiwicGFyZW50UGF0aCIsInJlcG9ydERpYWdub3N0aWNzIiwiZGlhZ25vc3RpY3MiLCJtc2ciLCJmb3JtYXREaWFnbm9zdGljcyIsImRpYWdub3N0aWMiLCJzdGFydCIsImNoYXJhY3RlciIsImdldExpbmVBbmRDaGFyYWN0ZXJPZlBvc2l0aW9uIiwiZmxhdHRlbkRpYWdub3N0aWNNZXNzYWdlVGV4dCIsIm1lc3NhZ2VUZXh0IiwicmVhZENvbmZpZ0ZpbGUiLCJjb25maWdGaWxlTmFtZSIsImNvbmZpZ0ZpbGVUZXh0IiwicGFyc2VDb25maWdGaWxlVGV4dFRvSnNvbiIsImNvbmZpZ09iamVjdCIsImNvbmZpZyIsIkxvZ0xldmVsIiwiY29uZmlnUGFyc2VSZXN1bHQiLCJwYXJzZUpzb25Db25maWdGaWxlQ29udGVudCIsInN5cyIsImV2YWxEaWFnbm9zdGljcyIsImNhdGVnb3J5IiwiRGlhZ25vc3RpY0NhdGVnb3J5Iiwid2FybmluZ3MiLCJXYXJuaW5nIiwic3VnZ2VzdGlvbnMiLCJTdWdnZXN0aW9uIiwibWVzc2FnZXMiLCJNZXNzYWdlIiwicHJlQ2hlY2tEaWFnbm9zdGljcyIsInByb2dyYW0iLCJnZXRQcmVFbWl0RGlhZ25vc3RpY3MiLCJjaGVja1RzRGlhZ25vc3RpY3MiLCJpc0RldiIsIm1vZGUiLCJidW5kbGUiLCJ0c0NvbmZpZyIsIm1vZHVsZSIsIk1vZHVsZUtpbmQiLCJBTUQiLCJvdXREaXIiLCJpc29sYXRlZE1vZHVsZXMiLCJvdXRGaWxlIiwiRVNNIiwiRVMyMDIyIiwiQ29tbW9uSlMiLCJpbmxpbmVTb3VyY2VNYXAiLCJpbmxpbmVTb3VyY2VzIiwic291cmNlTWFwIiwiY3JlYXRlUHJvZ3JhbSIsImZpbGVOYW1lcyIsImJ1aWxkVHMiLCJ0cmFuc2Zvcm1hdGlvbnMiLCJDSlMiLCJiZWZvcmUiLCJlbWl0UmVzdWx0IiwiZW1pdCIsImFsbERpYWdub3N0aWNzIiwiY29uY2F0IiwiYnVpbGQiLCJjb3B5QXNzZXRzIiwiaGFzQXNzZXRzIiwiaXNMaWIiLCJlbnRyeUZpbGUiLCJuYW1lT3ZlcnJpZGUiLCJleHRlcm5hbHNBcmciLCJpbmNsdWRlQXJnIiwiaXNFc20iLCJpbmNsdWRlIiwiZXh0ZXJuYWxzTGlzdCIsImJ1aWx0aW5MaXN0IiwiYnVpbHRpbk1vZHVsZXMiLCJyb2xsdXBTb3VyY2VNYXBPdXRwdXQiLCJwbHVnaW5zIiwidHlwZXNjcmlwdCIsImNvbXBpbGVyT3B0aW9ucyIsImRlY2xhcmF0aW9uIiwiZXhjbHVkZSIsInRzY29uZmlnIiwianNvbiIsImNvbW1vbmpzIiwibm9kZVJlc29sdmUiLCJyZXNvbHZlT25seSIsInRlcnNlck1vZCIsImltcG9ydCIsInRlcnNlckZuIiwidGVyc2VyIiwidGVyc2VyT3B0aW9uc0RldiIsImVjbWEiLCJjb21wcmVzcyIsIm1hbmdsZSIsImNvbW1lbnRzIiwiYmVhdXRpZnkiLCJ0ZXJzZXJPcHRpb25zUHJvZCIsInBhc3NlcyIsImRyb3BfY29uc29sZSIsImRyb3BfZGVidWdnZXIiLCJ0b3BsZXZlbCIsInVuc2FmZSIsInVuc2FmZV9hcnJvd3MiLCJ1bnNhZmVfY29tcHMiLCJjb2xsYXBzZV92YXJzIiwicmVkdWNlX2Z1bmNzIiwicmVkdWNlX3ZhcnMiLCJhc2NpaV9vbmx5IiwiZXh0ZXJuYWwiLCJvbndhcm4iLCJ0cmVlc2hha2UiLCJnbG9iYWxzIiwib3V0cHV0cyIsImVzTW9kdWxlIiwic291cmNlbWFwIiwicm9sbHVwIiwid2F0Y2hGaWxlcyIsImdlbmVyYXRlT3V0cHV0cyIsIm91dHB1dE9wdGlvbnMiLCJ3cml0ZSIsImJ1aWxkQnlFbnYiLCJpbmNsdWRlc0FyZyIsIkJVSUxEIiwiQlVORExFIiwiYnVpbGREZXYiLCJidWlsZFByb2QiLCJidWlsZERvY3MiLCJzcmMiLCJjaSIsInRhZyIsIlJlbGVhc2VTY3JpcHQiLCJwcmVwYXJlVmVyc2lvbiIsInRlc3RWZXJzaW9uIiwidG9Mb3dlckNhc2UiLCJQQVRDSCIsIk1JTk9SIiwiTUFKT1IiLCJwcmVwYXJlTWVzc2FnZSIsIlJlZ2V4cE91dHB1dFdyaXRlciIsImxhc3RJbmRleCIsInRlc3RBbmRSZXNvbHZlIiwidGVzdEFuZFJlamVjdCIsIlZFUlNJT04iLCJQQUNLQUdFX05BTUUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1VBd0VhQTs7WUFDYUMsS0FBTUMsU0FBR0MsUUFBQUEsUUFBUUMsSUFBSUo7QUFBVztRQXdKeEQsV0FBQUssQ0FBWUM7WUFuSlpMLEtBQUlNLE9BQTJEO1lBb0o3RE4sS0FBS0ssT0FBT0E7QUFDYjtRQVNELE9BQUFFLENB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QUNFQyxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUNFO1FBQ0ZDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUNFO1FBQ0ZDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUNFO1FBQ0ZDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUNFO1FBQ0ZDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07T0FFUjtRQUNFRCxRQUFRO1FBQ1JDLE1BQU07O0lDMXlCVixNQUFNQyxTQUFTLEVBQ2IsZUFDQSxlQUNBLGVBQ0EsZUFDQSxlQUNBLGVBQ0EsZUFDQSxlQUNBO0lBNEJJLFNBQVVDLFlBQVl2UztRQUMxQixNQUFNVSxVQUFVOFI7UUFDaEIsTUFBTW5NLFNBQ0osMDVCQU9EK0UsTUFBTTtRQUNQLE1BQU1xSCxZQUFZcE0sT0FBT0ksT0FBTyxDQUFDakYsS0FBS2tSLFNBQVNDLEtBQUtuUixJQUFJQSxLQUFLa1IsS0FBS2xLLFNBQVM7UUFDM0VuQyxPQUFPbUYsS0FBSyxNQUFNOUssUUFBUWtTLFNBQVNILFlBQVk7UUFDL0NwTSxPQUFPa0csUUFBUSxDQUFDbUcsTUFBTXBEO2FBQ25CdFAsU0FBU0EsT0FBT21GLEtBQUswTixLQUFLN1MsVUFBVThTLFFBQVFuUCxJQUFJa1AsS0FBS0MsVUFDcERoUywwQkFBTTRSLFFBQVEsSUFBSUssSUFBSVQsT0FBT2hELFFBQVEzSDs7QUFHM0M7SUEyQk0sU0FBVTZLLFVBQVVqSDtRQUN4QjtZQUNFQSxXQUNTQSxNQUFNLGNBQWNvSCxLQUFLSyxNQUFNTCxLQUFLTSxXQUFXZCxRQUFRM0osVUFBVStDO1lBQzFFLE9BQU80RyxRQUFRNUcsR0FBRzZHO0FBQ25CLFVBQUMsT0FBT2pPO1lBQ1AsTUFBTSxJQUFJQyxNQUFNLCtCQUErQkQ7QUFDaEQ7QUFDSDtJQ3hFTSxNQUFnQitPLGdCQUFzQkMsUUFBQUE7UUFRMUMsV0FBQWhULENBQ1lDLE1BQ0FnVCxTQUE0QixDQUFBLEdBQzVCQyxlQUF5QjtZQUVuQ0M7WUFKVXZULEtBQUlLLE9BQUpBO1lBQ0FMLEtBQU1xVCxTQUFOQTtZQUNBclQsS0FBWXNULGVBQVpBO1lBR1YsS0FBS0gsUUFBUXZQLEtBQUs7Z0JBQ2hCNEMsT0FBT2dOLGVBQWVMLFNBQVMsT0FBTztvQkFDcENNLFVBQVU7b0JBQ1YvUyxPQUFPUixRQUFPQSxRQUFDQyxJQUFJZ1QsUUFBUTlTOztBQUU5QjtZQUNETCxLQUFLcVQsU0FBUzdNLE9BQU9xRSxPQUNuQixDQUFBLEdBQ0EvRSx1QkFDQXVOO0FBRUg7UUF3QlMsdUJBQU1LO1lBQ2QsT0FBTWxFLE1BQUVBLE1BQUlFLEtBQUVBLEtBQUdFLE1BQUVBLGNBQWVQO1lBQ2xDLE1BQU1zRSxVQUFVO1lBQ2hCLE1BQU1DLFdBQVcvUCxNQUFNc00sS0FDckIsSUFBSUMsSUFBSSxLQUFJWixTQUFTRSxRQUFRRSxRQUFPdkQsVUFDcENySSxJQUFLaU0sS0FBTUEsRUFBRTVQO1lBQ2YsS0FBSyxNQUFNd1QsT0FBTzdULEtBQUtzVCxjQUNyQixLQUFLTSxTQUFTekksU0FBUzBJLE1BQU1GLFFBQVFsSSxLQUFLb0k7WUFFNUMsS0FBS0YsUUFBUWxMLFFBQVE7QUFDdEI7UUFVUyxJQUFBdkMsQ0FBS1Q7WUFDYixPQUFPekYsS0FBSzRELElBQUl3QixLQUNkO0FBRUg7UUErQ0QsYUFBTTBPO1lBQ0osTUFBTXJPLE9BQXdCMUYsVUFBVXdGLFVBQVV2RixLQUFLcVQ7WUFDdkQsTUFBTXpJLE1BQU1tSixRQUFpQkEsa0JBQUNDLFdBQVd6TixzQkFBc0J5TixXQUM3RHZPLEtBQUs0RztZQUVQLE9BQU1wRyxTQUFFQSxTQUFPQyxNQUFFQSxNQUFJSSxRQUFFQSxVQUFXc0U7WUFFbEMsSUFBSTNFLFNBQVM7Z0JBQ1gsT0FBT21KO0FBQ1I7WUFFRCxJQUFJbEosTUFBTTtnQkFDUixPQUFPbEcsS0FBS2tHLEtBQUtUO0FBQ2xCO1lBRUQsSUFBSWEsUUFDRmtNLFlBQ0V4UyxLQUFLNEQsSUFBSXpELElBQUlxUyxhQUFhO2dCQUN4Qm5NLFdBQVc7Z0JBQ1h0RixPQUFPO2dCQUNQa1QsU0FBUztnQkFDVDlOLFVBQVU7O1lBSWhCLElBQUluQjtZQUVKO2dCQUNFQSxlQUFlaEYsS0FBS2tVLElBQUl0SjtBQUN6QixjQUFDLE9BQU96RjtnQkFDUCxNQUFNQTtBQUNQO1lBRUQsT0FBT0g7QUFDUjs7VUMxS1VtUDs7WUFDTW5VLEtBQUE0RCxNQUFNMUQsUUFBQUEsUUFBUUMsSUFBSWdVO0FBQVk7UUErQi9DLHlCQUFhQyxDQUFhQztZQUN4QixPQUFPLElBQUlsTCxRQUFnQixDQUFDZCxTQUFTRztnQkFDbkMsU0FBUzhMLFFBQVFEO29CQUNmQSxNQUFNRSxVQUFVRjtvQkFDaEJHLGVBQUFBLFdBQU1DLElBQUlKLEtBQU1LO3dCQUNkLElBQUlBLElBQUlDLGVBQWUsT0FBT0QsSUFBSUMsZUFBZSxLQUMvQyxPQUFPTCxRQUFRSSxJQUFJRSxRQUFRQzt3QkFFN0IsSUFBSUgsSUFBSUMsZUFBZSxLQUFLOzRCQUMxQlIsV0FBV3ZRLElBQUlRLE1BQ2IsbUJBQW1CaVEsZ0JBQWdCSyxJQUFJQzs0QkFFekMsT0FBT25NLE9BQU8sSUFBSW5FLE1BQU0sbUJBQW1CZ1E7QUFDNUM7d0JBQ0QsSUFBSTdNLE9BQU87d0JBQ1hrTixJQUFJM0ksR0FBRyxRQUFTbEU7NEJBQ2RMLFFBQVFLOzt3QkFFVjZNLElBQUkzSSxHQUFHLFNBQVUzSDs0QkFDZm9FLE9BQU9wRTs7d0JBR1RzUSxJQUFJM0ksR0FBRyxPQUFPOzRCQUNaMUQsUUFBUWI7OztBQUdiO2dCQUNEOE0sUUFBUUQ7O0FBRVg7O0lDMUNHLFNBQVVTLFVBQVVsUTtRQUN4QixLQUFLQSxPQUFPLE9BQU87UUFDbkIsSUFBSWYsTUFBTUMsUUFBUWMsUUFDaEIsT0FBT0EsTUFBTVosSUFBS3dILEtBQU0sR0FBR0EsSUFBSWpELFFBQVFPLE9BQU9pTTtRQUNoRCxPQUFPLEdBQUduUSxRQUNQeUcsTUFBTSxLQUNOckgsSUFBSytFLEtBQU1BLEVBQUVSLFFBQ2JPLE9BQU9pTTtBQUNaO0lBRU0sU0FBVUMsZ0JBQWdCM1U7UUFFOUIsTUFBTTRVLGVBQWU1VSxLQUFLd00sUUFBUSxNQUFNO1FBQ3hDLE1BQU1qRSxRQUFRcU0sYUFBYTVKLE1BQU0sWUFBWXZDLE9BQU9pTTtRQUNwRCxPQUFPbk0sTUFDSjVFLElBQUksQ0FBQytFLEdBQUd5QyxNQUNQQSxNQUFNLElBQ0Z6QyxFQUFFOEQsUUFBUSxpQkFBaUIsTUFDM0IsR0FBRzlELEVBQUVtTSxPQUFPLEdBQUdDLGdCQUFnQnBNLEVBQUVuRCxNQUFNLE1BRTVDMUIsS0FBSztBQUNWO2FBRWdCa1I7UUFFZCxJQUFJbkc7UUFDSjtZQUNFQSxNQUFNRixXQUFXckosUUFBUWlGO0FBQzFCLFVBQUM7WUFDQXNFLE1BQU14SztBQUNQO1FBR0Q7WUFDRSxNQUFNNFEsVUFDSnBHLFFBQ0N6SSxPQUFPQyxLQUFLd0ksSUFBSVEsZ0JBQWdCLENBQUUsR0FBRWhILFNBQVMsS0FDNUNqQyxPQUFPQyxLQUFLd0ksSUFBSVUsbUJBQW1CLENBQUUsR0FBRWxILFNBQVMsS0FDaERqQyxPQUFPQyxLQUFLd0ksSUFBSVksb0JBQW9CLENBQUEsR0FBSXBILFNBQVM7WUFDckQsS0FBSzRNLFNBQVM7Z0JBQ1osTUFBTUMsY0FBY3RJLGNBQUksV0FBQzNFLFFBQVFrTixXQUFXO2dCQUM1QztvQkFDRXRHLE1BQU1GLFdBQVd1RztBQUNsQixrQkFBQyxPQUVEO0FBQ0Y7QUFDRixVQUFDLE9BRUQ7UUFFRCxNQUFNdEYsT0FBT3hKLE9BQU9DLEtBQU13SSxPQUFPQSxJQUFJUSxnQkFBaUIsQ0FBQTtRQUN0RCxNQUFNRyxPQUFPcEosT0FBT0MsS0FBTXdJLE9BQU9BLElBQUlZLG9CQUFxQixDQUFBO1FBQzFELE1BQU1ILE1BQU1sSixPQUFPQyxLQUFNd0ksT0FBT0EsSUFBSVUsbUJBQW9CLENBQUE7UUFDeEQsT0FBTzlMLE1BQU1zTSxLQUFLLElBQUlDLElBQUksS0FBSUosU0FBU0osU0FBU0Y7QUFDbEQ7SUFFQSxNQUFNOEYsaUJBQWlCO0lBQ3ZCLE1BQU1DLGlCQUFpQjtJQUN2QixNQUFNQyxzQkFBc0I7SUFFNUIsSUFBS0M7S0FBTCxTQUFLQTtRQUNIQSxNQUFBLFNBQUE7UUFDQUEsTUFBQSxTQUFBO0FBQ0QsTUFIRCxDQUFLQSxVQUFBQSxRQUdKLENBQUE7SUFFRCxJQUFLQztLQUFMLFNBQUtBO1FBQ0hBLFVBQUEsV0FBQTtRQUNBQSxVQUFBLFlBQUE7UUFDQUEsVUFBQSxTQUFBO0FBQ0QsTUFKRCxDQUFLQSxjQUFBQSxZQUlKLENBQUE7SUFFRCxNQUFNcFEsWUFBVTtRQUNkZ0ssTUFBTTtZQUNKbFAsTUFBTTtZQUNOMEYsU0FBUzs7UUFFWDBKLEtBQUs7WUFDSHBQLE1BQU07WUFDTjBGLFNBQVM7O1FBRVg2UCxXQUFXO1lBQ1R2VixNQUFNO1lBQ04wRixTQUFTNFAsVUFBVUU7O1FBRXJCM0ssVUFBVTtZQUNSN0ssTUFBTTtZQUNOMEYsU0FBUzs7UUFFWCtQLFdBQVc7WUFDVHpWLE1BQU07WUFDTjBGLFNBQVM7O1FBRVhnUSxNQUFNO1lBQ0oxVixNQUFNO1lBQ04wRixTQUFTOztRQUVYaVEsVUFBVTtZQUNSM1YsTUFBTTtZQUNOMEYsU0FBUzs7UUFFWE0sUUFBUTtZQUNOaEcsTUFBTTtZQUNOMEYsU0FBUzs7O0lBSWIsTUFBTWtRLGtCQUFrQixDQUFDQyxNQUFNO1FBQzdCLE1BQU12UyxNQUFNd1MsYUFBYXhTLElBQUl6RCxJQUFJK1Y7UUFDakMsTUFBTUcsa0JBQWtCLElBQUlDO1FBRTVCLE9BQVFDLHlCQUNFQztZQUNOLE1BQU1DLFlBQVl6SixjQUFJLFdBQUMwSixRQUFRRixXQUFXRztZQUUxQyxTQUFTQyxZQUFZQztnQkFDbkIsTUFBTUMsV0FBV3JVLEtBQUtDLFVBQVUsRUFBQytULFdBQVdJO2dCQUM1QyxNQUFNRSxjQUFjVixnQkFBZ0I1QixJQUFJcUM7Z0JBQ3hDLElBQUlDLGVBQWUsTUFBTSxPQUFPQTtnQkFFaEMsSUFBSUMsZUFBZUg7Z0JBQ25CO29CQUNFRyxlQUFlaEssY0FBSSxXQUFDM0UsUUFBUW9PLFdBQVdPLGVBQWU7QUFDdkQsa0JBQUMsT0FBTzVTO29CQUNQLE1BQU0sSUFBSUMsTUFBTSwwQkFBMEJ3UyxlQUFlelM7QUFDMUQ7Z0JBQ0QsSUFBSXlKO2dCQUNKO29CQUNFQSxPQUFPWixZQUFFLFdBQUNhLFNBQVNrSjtBQUNwQixrQkFBQyxPQUFPN1I7b0JBQ1A7d0JBQ0V2QixJQUFJcEQsUUFDRiw2QkFBNkJ3Vzt3QkFFL0JuSixPQUFPWixZQUFFLFdBQUNhLFNBQVNrSixhQUFhbkssUUFBUSxXQUFXO0FBQ3BELHNCQUFDLE9BQU9vSzt3QkFDUCxNQUFNLElBQUk1UyxNQUNSLDBCQUEwQndTLGVBQWUxUixNQUFNOFI7QUFFbEQ7QUFDRjtnQkFDRCxJQUFJcEosS0FBS0csZUFDUGdKLGVBQWVBLGFBQWFuSyxRQUFRLFdBQVc7Z0JBRWpELElBQUlHLGNBQUksV0FBQ2tLLFdBQVdGLGVBQWU7b0JBQ2pDLE1BQU1HLGFBQ0gsVUFBVUMsS0FBS3BLLGNBQUFBLFdBQUtxSyxTQUFTTCxrQkFBa0IsSUFBSSxXQUFXO29CQUVqRUEsZUFDRSxPQUNBaEssY0FBSSxXQUFDc0ssU0FDSGIsV0FDQXpKLGNBQUksV0FBQzNFLFFBQ0gyRSxjQUFJLFdBQUMwSixRQUFRTSxlQUNiaEssY0FBQUEsV0FBS3FLLFNBQVNMLGNBQWNHLGFBQWFoQjtBQUdoRDtnQkFFREUsZ0JBQWdCa0IsSUFBSVQsVUFBVUU7Z0JBQzlCLE9BQU9BO0FBQ1I7WUFFRCxTQUFTUSxVQUFVQztnQkFDakIsSUFBSUMsNEJBQTRCRCxPQUFPO29CQUNyQyxJQUFJRSxjQUFHQyxvQkFBb0JILE9BQU87d0JBQ2hDLE1BQU1ULGVBQWVKLFlBQVlhLEtBQUtJLGdCQUFnQmpRO3dCQUN0RCxNQUFNa1EscUJBQ0p2QixzQkFBc0J3QixRQUFRQyxvQkFBb0JoQjt3QkFDcEQsT0FBT1Qsc0JBQXNCd0IsUUFBUUUsd0JBQ25DUixNQUNBQSxLQUFLUyxXQUNMVCxLQUFLVSxjQUNMTCxvQkFDQXJUO0FBRUgsMkJBQU0sSUFBSWtULGNBQUdTLG9CQUFvQlgsT0FBTzt3QkFDdkMsTUFBTVQsZUFBZUosWUFBWWEsS0FBS0ksZ0JBQWdCalE7d0JBQ3RELE1BQU1rUSxxQkFDSnZCLHNCQUFzQndCLFFBQVFDLG9CQUFvQmhCO3dCQUNwRCxPQUFPVCxzQkFBc0J3QixRQUFRTSx3QkFDbkNaLE1BQ0FBLEtBQUtTLFdBQ0xULEtBQUthLFlBQ0xiLEtBQUtjLGNBQ0xULG9CQUNBclQ7QUFFSDtBQUNGO2dCQUVELE9BQU9rVCxjQUFHYSxlQUFlZixNQUFNRCxXQUFXakI7QUFDM0M7WUFFRCxTQUFTbUIsNEJBQTRCRDtnQkFNbkMsS0FBS0UsY0FBR0Msb0JBQW9CSCxVQUFVRSxjQUFHUyxvQkFBb0JYLE9BQzNELE9BQU87Z0JBRVQsSUFBSUEsS0FBS0ksb0JBQW9CcFQsV0FBVyxPQUFPO2dCQUUvQyxLQUFLa1QsY0FBR2MsZ0JBQWdCaEIsS0FBS0ksa0JBQWtCLE9BQU87Z0JBRXRELEtBQ0dKLEtBQUtJLGdCQUFnQmpRLEtBQUtxSyxXQUFXLFVBQ3JDd0YsS0FBS0ksZ0JBQWdCalEsS0FBS3FLLFdBQVcsUUFFdEMsT0FBTztnQkFFVCxJQUFJakYsY0FBQUEsV0FBSzBMLFFBQVFqQixLQUFLSSxnQkFBZ0JqUSxVQUFVLElBQUksT0FBTztnQkFDM0QsT0FBTztBQUNSO1lBRUQsT0FBTytQLGNBQUdILFVBQVVoQixZQUFZZ0I7OztJQWFoQyxNQUFPcEIscUJBQXFCakQ7UUFRaEMsV0FBQS9TO1lBQ0VtVCxNQUNFLGdCQUNBL00sT0FBT3FFLE9BQU8sQ0FBQSxHQUFJL0UsdUJBQXVCTjtZQVByQ3hGLEtBQVkyWSxlQUEyQjtZQVc3QyxNQUFNMUosTUFBTUY7WUFDWixPQUFNMU8sTUFBRUEsTUFBSTRGLFNBQUVBLFdBQVlnSjtZQUMxQmpQLEtBQUs0WSxVQUFVdlksS0FBSzhLLFNBQVMsT0FBTzlLLEtBQUtnTCxNQUFNLEtBQUssS0FBS2hMO1lBQ3pETCxLQUFLNlksYUFBYTVTO1lBQ2xCakcsS0FBSzJZLGFBQWFuRCxrQkFBa0J4VixLQUFLNlk7WUFDekM3WSxLQUFLMlksYUFBYWxELGtCQUFrQnBWO0FBQ3JDO1FBUUQsVUFBQXlZLENBQVcvUDtZQUNULE1BQU1uRixNQUFNNUQsS0FBSzRELElBQUl6RCxJQUFJSCxLQUFLOFk7WUFDOUIsT0FBTXpZLE1BQUVBLE1BQUk0RixTQUFFQSxXQUFZOEk7WUFDMUJuTCxJQUFJd0IsS0FBSyxZQUFZL0UsUUFBUTRGLHFCQUFxQjhDO1lBQ2xELE1BQU04RSxPQUFPWixZQUFBQSxXQUFHYSxTQUFTL0U7WUFDekIsSUFBSThFLEtBQUtHLGVBQ1BmLFlBQUUsV0FBQ1MsWUFBWTNFLEdBQUc7Z0JBQUUrSSxlQUFlO2dCQUFNckQsV0FBVztlQUNqRDNGLE9BQVFDLEtBQU1BLEVBQUVnRixVQUNoQnZCLFFBQVN1TSxRQUNSaE0sVUFDRUMsY0FBQUEsV0FBSzlJLEtBQUs2VSxLQUFLQyxZQUFZRCxLQUFLMVksT0FDaENtRyxPQUFPK0YsUUFBUXZNLEtBQUsyWSxjQUFjalMsT0FDaEMsQ0FBQ0MsTUFBMkJDLEtBQUs2RjtnQkFDL0IsUUFBUTdGO2tCQUNOLEtBQUs0TztvQkFDSDVSLElBQUlpQyxNQUFNO29CQUNWYyxJQUFJLGNBQWM2TyxzQkFDaEIsY0FBYy9JO29CQUNoQjs7a0JBQ0YsS0FBS2dKO29CQUNIN1IsSUFBSWlDLE1BQU07b0JBQ1ZjLElBQUksbUJBQW1COE8sc0JBQ3JCLG1CQUFtQmhKO29CQUNyQjs7a0JBQ0Y7b0JBQ0U5RixJQUFJQyxPQUFPNkY7O2dCQUVmLE9BQU85RjtlQUVULENBQUE7WUFJVi9DLElBQUlwRCxRQUFRLFVBQVVILFFBQVE0RixzQkFBc0I4QztBQUNyRDtRQUVPLGlCQUFBa1EsQ0FDTkMsYUFDQS9TO1lBRUEsTUFBTWdULE1BQU1uWixLQUFLb1osa0JBQWtCRjtZQUNuQztnQkFDRWxaLEtBQUs0RCxJQUFJdUMsVUFBVWdUO0FBQ3BCLGNBQUMsT0FBT2hVO2dCQUNQNE4sUUFBUWhRLEtBQUssNEJBQTRCb0Q7Z0JBQ3pDLE1BQU1oQjtBQUNQO1lBQ0QsT0FBT2dVO0FBQ1I7UUFHTyxpQkFBQUMsQ0FBa0JGO1lBQ3hCLE9BQU9BLFlBQ0psVixJQUFLcVY7Z0JBQ0osSUFBSTFZLFVBQVU7Z0JBQ2QsSUFBSTBZLFdBQVdOLFFBQVFNLFdBQVdDLE9BQU87b0JBQ3ZDLE9BQU0zRyxNQUFFQSxNQUFJNEcsV0FBRUEsYUFDWkYsV0FBV04sS0FBS1MsOEJBQThCSCxXQUFXQztvQkFDM0QzWSxXQUFXLEdBQUcwWSxXQUFXTixLQUFLcEMsYUFBYWhFLE9BQU8sS0FBSzRHLFlBQVk7QUFDcEU7Z0JBQ0Q1WSxXQUNFLE9BQU9nWCxjQUFHOEIsNkJBQTZCSixXQUFXSyxhQUFhO2dCQUNqRSxPQUFPL1k7ZUFFUnVELEtBQUs7QUFDVDtRQUVPLGNBQUF5VixDQUFlQztZQUVyQixNQUFNQyxpQkFBaUI1TSxZQUFBQSxXQUFHSyxhQUFhc00sZ0JBQWdCN1U7WUFHdkQsTUFBTUMsU0FBUzJTLGNBQUdtQywwQkFBMEJGLGdCQUFnQkM7WUFDNUQsTUFBTUUsZUFBZS9VLE9BQU9nVjtZQUM1QixLQUFLRCxjQUFjO2dCQUNqQi9aLEtBQUtpWixrQkFBa0IsRUFBQ2pVLE9BQU9aLFNBQVM2VixRQUFBQSxTQUFTN1Y7QUFDbEQ7WUFHRCxNQUFNOFYsb0JBQW9CdkMsY0FBR3dDLDJCQUMzQkosY0FDQXBDLGNBQUd5QyxLQUNIcE4seUJBQUswSixRQUFRa0Q7WUFFZixJQUFJTSxrQkFBa0JuUyxPQUFPVSxTQUFTLEdBQ3BDekksS0FBS2laLGtCQUFrQmlCLGtCQUFrQm5TLFFBQVFrUyxRQUFRQSxTQUFDN1Y7WUFFNUQsT0FBTzhWO0FBQ1I7UUFFTyxlQUFBRyxDQUFnQm5CO1lBQ3RCLElBQUlBLGVBQWVBLFlBQVl6USxTQUFTLEdBQUc7Z0JBQ3pDLE1BQU1WLFNBQVNtUixZQUFZcFEsT0FDeEJtSCxLQUFNQSxFQUFFcUssYUFBYTNDLGNBQUc0QyxtQkFBbUJsVztnQkFFOUMsTUFBTW1XLFdBQVd0QixZQUFZcFEsT0FDMUJtSCxLQUFNQSxFQUFFcUssYUFBYTNDLGNBQUc0QyxtQkFBbUJFO2dCQUU5QyxNQUFNQyxjQUFjeEIsWUFBWXBRLE9BQzdCbUgsS0FBTUEsRUFBRXFLLGFBQWEzQyxjQUFHNEMsbUJBQW1CSTtnQkFFOUMsTUFBTUMsV0FBVzFCLFlBQVlwUSxPQUMxQm1ILEtBQU1BLEVBQUVxSyxhQUFhM0MsY0FBRzRDLG1CQUFtQk07Z0JBSTlDLElBQUlMLFNBQVMvUixRQUFRekksS0FBS2laLGtCQUFrQnVCLFVBQVVQLFFBQVFBLFNBQUNsWDtnQkFDL0QsSUFBSWdGLE9BQU9VLFFBQVE7b0JBQ2pCekksS0FBS2laLGtCQUFrQkMsYUFBNkJlLFFBQVFBLFNBQUM3VjtvQkFDN0QsTUFBTSxJQUFJQyxNQUNSLHVCQUF1QjZVLFlBQVl6UTtBQUV0QztnQkFDRCxJQUFJaVMsWUFBWWpTLFFBQ2R6SSxLQUFLaVosa0JBQWtCeUIsYUFBYVQsUUFBUUEsU0FBQzdVO2dCQUMvQyxJQUFJd1YsU0FBU25TLFFBQVF6SSxLQUFLaVosa0JBQWtCMkIsVUFBVVgsUUFBUUEsU0FBQzdVO0FBQ2hFO0FBQ0Y7UUFFTyxtQkFBQTBWLENBQW9CQztZQUMxQixNQUFNN0IsY0FBY3ZCLGNBQUdxRCxzQkFBc0JEO1lBQzdDL2EsS0FBS3FhLGdCQUFnQm5CO0FBQ3RCO1FBR08sd0JBQU0rQixDQUNaQyxPQUNBQyxNQUNBQyxTQUFTO1lBRVQsTUFBTXhYLE1BQU01RCxLQUFLNEQsSUFBSXpELElBQUlILEtBQUtpYjtZQUM5QixJQUFJSTtZQUNKO2dCQUNFQSxXQUFXcmIsS0FBSzJaLGVBQWU7QUFDaEMsY0FBQyxPQUFPeFU7Z0JBQ1AsTUFBTSxJQUFJZCxNQUFNLGtDQUFrQ2M7QUFDbkQ7WUFFRCxJQUFJaVcsUUFBUTtnQkFDVkMsU0FBUzdWLFFBQVE4VixTQUFTQyxHQUFBQSxXQUFXQztnQkFDckNILFNBQVM3VixRQUFRaVcsU0FBUztnQkFDMUJKLFNBQVM3VixRQUFRa1csa0JBQWtCO2dCQUNuQ0wsU0FBUzdWLFFBQVFtVyxVQUFVM2IsS0FBSzRZO0FBQ2pDLG1CQUFNO2dCQUNMeUMsU0FBUzdWLFFBQVFpVyxTQUFTLE1BQU1OLFNBQVN4RixNQUFNaUcsTUFBTSxTQUFTO2dCQUM5RFAsU0FBUzdWLFFBQVE4VixTQUNmSCxTQUFTeEYsTUFBTWlHLE1BQU1MLEdBQVVBLFdBQUNNLFNBQVNOLEdBQVVBLFdBQUNPO0FBQ3ZEO1lBTURULFNBQVM3VixRQUFRdVcsa0JBQWtCO1lBQ25DVixTQUFTN1YsUUFBUXdXLGdCQUFnQjtZQUNqQ1gsU0FBUzdWLFFBQVF5VyxZQUFZO1lBRTdCLE1BQU1sQixVQUFVcEQsY0FBR3VFLGNBQWNiLFNBQVNjLFdBQVdkLFNBQVM3VjtZQUM5RHhGLEtBQUs4YSxvQkFBb0JDO1lBQ3pCblgsSUFBSXBELFFBQ0YsNkJBQTZCNGEsU0FBUyxXQUFXO0FBRXBEO1FBRU8sYUFBTWdCLENBQVFsQixPQUFnQkMsTUFBYUMsU0FBUztZQUMxRCxNQUFNeFgsTUFBTTVELEtBQUs0RCxJQUFJekQsSUFBSUgsS0FBS29jO1lBQzlCeFksSUFBSXdCLEtBQ0YsWUFBWXBGLEtBQUs0WSxXQUFXNVksS0FBSzZZLHNCQUFzQnNDLFlBQVlELFFBQVEsUUFBUTtZQUVyRixJQUFJRztZQUNKO2dCQUNFQSxXQUFXcmIsS0FBSzJaLGVBQWU7QUFDaEMsY0FBQyxPQUFPeFU7Z0JBQ1AsTUFBTSxJQUFJZCxNQUFNLGtDQUFrQ2M7QUFDbkQ7WUFFRCxJQUFJaVcsUUFBUTtnQkFDVkMsU0FBUzdWLFFBQVE4VixTQUFTQyxHQUFBQSxXQUFXQztnQkFDckNILFNBQVM3VixRQUFRaVcsU0FBUztnQkFDMUJKLFNBQVM3VixRQUFRa1csa0JBQWtCO2dCQUNuQ0wsU0FBUzdWLFFBQVFtVyxVQUFVM2IsS0FBSzRZO0FBQ2pDLG1CQUFNO2dCQUNMeUMsU0FBUzdWLFFBQVFpVyxTQUFTLE1BQU1OLFNBQVN4RixNQUFNaUcsTUFBTSxTQUFTO2dCQUM5RFAsU0FBUzdWLFFBQVE4VixTQUNmSCxTQUFTeEYsTUFBTWlHLE1BQU1MLEdBQVVBLFdBQUNNLFNBQVNOLEdBQVVBLFdBQUNPO0FBQ3ZEO1lBS0QsSUFBSVosT0FBTztnQkFDVEcsU0FBUzdWLFFBQVF1VyxrQkFBa0I7Z0JBQ25DVixTQUFTN1YsUUFBUXdXLGdCQUFnQjtnQkFDakNYLFNBQVM3VixRQUFReVcsWUFBWTtBQUM5QixtQkFBTTtnQkFDTFosU0FBUzdWLFFBQVF1VyxrQkFBa0I7Z0JBQ25DVixTQUFTN1YsUUFBUXdXLGdCQUFnQjtnQkFDakNYLFNBQVM3VixRQUFReVcsWUFBWTtBQUM5QjtZQUtELE1BQU1sQixVQUFVcEQsY0FBR3VFLGNBQWNiLFNBQVNjLFdBQVdkLFNBQVM3VjtZQUU5RCxNQUFNNlcsa0JBQXNDLENBQUE7WUFDNUMsSUFBSWxCLFNBQVN4RixNQUFNMkcsS0FBSztnQkFDdEJELGdCQUFnQkUsU0FBUyxFQUFDckcsZ0JBQWdCO0FBQzNDLG1CQUFNLElBQUlpRixTQUFTeEYsTUFBTWlHLEtBQUs7Z0JBQzdCUyxnQkFBZ0JFLFNBQVMsRUFBQ3JHLGdCQUFnQjtBQUMzQztZQUVELE1BQU1zRyxhQUF5QnpCLFFBQVEwQixLQUNyQ2hZLFdBQ0FBLFdBQ0FBLFdBQ0FBLFdBQ0E0WDtZQUdGLE1BQU1LLGlCQUFpQi9FLGNBQ3BCcUQsc0JBQXNCRCxTQUN0QjRCLE9BQU9ILFdBQVd0RDtZQUVyQmxaLEtBQUtxYSxnQkFBZ0JxQztBQUN0QjtRQUVPLFdBQU1FLENBQU0xQixPQUFnQkMsTUFBYUMsU0FBUztZQUN4RCxNQUFNeFgsTUFBTTVELEtBQUs0RCxJQUFJekQsSUFBSUgsS0FBSzRjO2tCQUN4QjVjLEtBQUtvYyxRQUFRbEIsT0FBT0MsTUFBTUM7WUFFaEN4WCxJQUFJcEQsUUFDRixVQUFVUixLQUFLNFksV0FBVzVZLEtBQUs2WSxlQUFlc0Msa0JBQWtCRCxRQUFRLFFBQVE7WUFFbEYsSUFBSUMsU0FBU3hGLE1BQU0yRyxRQUFRbEIsUUFBUTtnQkFDakMsTUFBTTNOLFFBQVFELFlBQ1osT0FDQ3VMLFFBQVNBLEtBQUsvSCxTQUFTLFdBQVcrSCxLQUFLNU4sU0FBUztnQkFHbkQsS0FBSyxNQUFNNE4sUUFBUXRMLE9BQU87b0JBQ3hCN0osSUFBSXBELFFBQVEsWUFBWXVZO29CQUN4QixNQUFNN1AsSUFBSTZQLEtBQUtsTSxRQUFRLE9BQU87MEJBQ3hCb0IsV0FBVzhLLE1BQU03UDtBQUN4QjtBQUNGO0FBQ0Y7UUFRRCxVQUFBMlQsQ0FBVzFCO1lBQ1QsTUFBTXZYLE1BQU01RCxLQUFLNEQsSUFBSXpELElBQUlILEtBQUs2YztZQUM5QixJQUFJQyxZQUFZO1lBQ2hCO2dCQUNFQSxZQUFZN1AsWUFBQUEsV0FBR2EsU0FBUyxnQkFBZ0JFO0FBRXpDLGNBQUMsT0FBTzdJO2dCQUNQLE9BQU92QixJQUFJcEQsUUFBUTtBQUNwQjtZQUNELElBQUlzYyxXQUNGdk8sU0FDRSxnQkFDQSxLQUFLNE0sU0FBU3hGLE1BQU0yRyxNQUFNLFFBQVE7QUFFdkM7UUFlRCxZQUFNbEIsQ0FDSkQsTUFDQUQsT0FDQTZCLE9BQ0FDLFlBQW9CLGdCQUNwQkMsZUFBdUJqZCxLQUFLNFksU0FDNUJzRSxjQUNBQyxhQUFnQyxFQUM5QixXQUNBLHlCQUNBLDRCQUNBO2tCQUlJbmQsS0FBS2liLG1CQUFtQkMsT0FBT0MsTUFBTTtZQUMzQyxNQUFNaUMsUUFBUWpDLFNBQVN4RixNQUFNaUc7WUFDN0IsTUFBTWhELFVBQVU1WSxLQUFLNFk7WUFDckIsTUFBTWhWLE1BQU01RCxLQUFLNEQ7WUFHakIsTUFBTXlaLFVBQVV4WixNQUFNc00sS0FDcEIsSUFBSUMsSUFBSSxLQUFLMEUsVUFBVXFJO1lBRXpCLElBQUlHLGdCQUFnQnhJLFVBQVVvSTtZQUM5QixJQUFJSSxjQUFjN1UsV0FBVyxHQUFHO2dCQUU5QjtvQkFDRTZVLGdCQUFnQnRMLHdCQUNkaEYsY0FBQUEsV0FBSzlJLEtBQUt3QixRQUFRaUYsT0FBTztBQUU1QixrQkFBQyxPQUVEO2dCQUNELEtBQUsyUyxpQkFBaUJBLGNBQWM3VSxXQUFXLEdBQUc7b0JBQ2hENlUsZ0JBQWdCbEk7QUFDakI7QUFDRjtZQUVELE1BQU1lLE1BQU10UyxNQUFNc00sS0FDaEIsSUFBSUMsSUFBSSxLQUVILFNBQVVtTjtnQkFDWDtvQkFDRSxPQUNFMVosTUFBTUMsUUFBUTBaLE9BQWNBLGtCQUFJQSxPQUFBQSxpQkFBaUI7QUFFcEQsa0JBQUM7b0JBRUEsT0FBTyxFQUNMLE1BQ0EsUUFDQSxXQUNBLGlCQUNBLFFBQ0EsU0FDQSxRQUNBLE1BQ0EsVUFDQSxVQUNBLFFBQ0EsT0FDQSxPQUNBLE9BQ0EsZUFDQSxVQUNBLFVBQ0EsT0FDQSxPQUNBO0FBRUg7QUFDRixhQTlCRSxPQStCQUY7WUFRUCxNQUFNRyx3QkFBNER2QyxRQUM5RCxXQUNBO1lBRUosTUFBTXdDLFVBQVUsRUFDZEMsK0JBQVc7Z0JBQ1RDLGlCQUFpQjtvQkFDZnRDLFFBQVE7b0JBQ1J1QyxhQUFhO29CQUNicEMsUUFBUXNCLFFBQVEsUUFBUTtvQkFHeEJkLFdBQVdmLFFBQVEsUUFBUTtvQkFDM0JhLGlCQUFpQmIsUUFBUSxPQUFPO29CQUNoQ2MsZUFBZWQsUUFBUSxPQUFPOztnQkFFaENtQyxTQUFTLEVBQUM7Z0JBQ1ZTLFNBQVMsRUFBQyxnQkFBZ0I7Z0JBQzFCQyxVQUFVO2dCQUVaQztZQUdGLElBQUlqQixPQUFPO2dCQUNUVyxRQUFRalMsS0FDTndTLDZCQUFTO29CQUNQWixTQUFTO29CQUNUUyxTQUFTUjtvQkFFWFksa0JBQUFBLFlBQVk7b0JBQ1ZDLGFBQWFkOztBQUdsQjtZQUdEO2dCQUNFLE1BQU1lLGtCQUF1QkMsT0FBTztnQkFDcEMsTUFBTUMsV0FDSEYsYUFBYUEsVUFBVUcsVUFBV0gsVUFBVXBZLFdBQVdvWTtnQkFFMUQsTUFBTUksbUJBQXdCO29CQUM1QjNWLE9BQU87d0JBQUU0VixNQUFNOztvQkFDZkMsVUFBVTtvQkFDVkMsUUFBUTtvQkFDUjFkLFFBQVE7d0JBQ04yZCxVQUFVO3dCQUNWQyxVQUFVOzs7Z0JBSWQsTUFBTUMsb0JBQXlCO29CQUM3QmpXLE9BQU87d0JBQUU0VixNQUFNOztvQkFDZkMsVUFBVTt3QkFDUkQsTUFBTTt3QkFDTk0sUUFBUTt3QkFDUkMsY0FBYzt3QkFDZEMsZUFBZTt3QkFDZkMsVUFBVTt3QkFDVjVELFFBQVE4Qjt3QkFDUitCLFFBQVE7d0JBQ1JDLGVBQWU7d0JBQ2ZDLGNBQWM7d0JBQ2RDLGVBQWU7d0JBQ2ZDLGNBQWM7d0JBQ2RDLGFBQWE7O29CQUVmYixRQUFRO3dCQUNOTyxVQUFVOztvQkFFWmplLFFBQVE7d0JBQ04yZCxVQUFVO3dCQUNWYSxZQUFZOztvQkFFZFAsVUFBVTs7Z0JBR1p4QixRQUFRalMsS0FBSzZTLFNBQVNwRCxRQUFRc0QsbUJBQW1CTTtBQUNsRCxjQUFDLE9BRUQ7WUFFRCxNQUFNbGEsUUFBc0I7Z0JBQzFCQSxPQUFPb1k7Z0JBQ1BVLFNBQVNBO2dCQUNUZ0MsVUFBVXZKO2dCQUNWd0osUUFBUWxiO2dCQUVSbWIsWUFBWTFFOztZQUlkLE1BQU0yRSxVQUFrQyxDQUFBO1lBRXhDMUosSUFBSTNKLFFBQVNySDtnQkFDWDBhLFFBQVExYSxLQUFLNlAsZ0JBQWdCN1A7O1lBRy9CLE1BQU0yYSxVQUEyQixFQUMvQjtnQkFDRS9HLE1BQU0sR0FBR2dFLFFBQVEsU0FBUyxVQUFVRSxlQUFlQSxlQUFlLFlBQVkvQixRQUFRLFFBQVEsT0FBT2tDLFFBQVEsUUFBUTtnQkFDckhuYyxRQUFROGIsUUFBUSxRQUFRSyxRQUFRLFFBQVE7Z0JBQ3hDL2MsTUFBTXVZO2dCQUNObUgsVUFBVTNDO2dCQUVWNEMsV0FBV3ZDO2dCQUNYb0MsU0FBU0E7Z0JBQ1Q5WSxTQUFTOztZQUliO2dCQUNFLE1BQU1xVSxlQUFlNkUsY0FBT3JiO2dCQUU1QmhCLElBQUlwRCxRQUFRNGEsT0FBTzhFO2dCQUNuQmhVLGVBQWVpVSxnQkFBZ0IvRTtvQkFDN0IsS0FBSyxNQUFNZ0YsaUJBQWlCTixTQUFTOzhCQUM3QjFFLE9BQU9pRixNQUFNRDtBQUNwQjtBQUNGO3NCQUVLRCxnQkFBZ0IvRTtBQUN2QixjQUFDLE9BQU9qVztnQkFDUCxNQUFNLElBQUlkLE1BQU0scUJBQXFCYztBQUN0QztBQUNGO1FBRU8sZ0JBQU1tYixDQUNacEYsT0FDQUMsT0FBa0J2RixVQUFVRSxLQUM1QnlLLGFBQ0FyRDtZQUdBO2dCQUNFdk8sV0FBVztBQUVaLGNBQUMsT0FBT3hKLElBRVI7WUFDRDtnQkFDRXdKLFdBQVc7QUFFWixjQUFDLE9BQU94SixJQUVSO1lBQ0Q4SCx1QkFBR3VCLFVBQVU7WUFDYnZCLHVCQUFHdUIsVUFBVTtZQUViLElBQUksRUFBQ29ILFVBQVVFLEtBQUtGLFVBQVU0SyxRQUFPclYsU0FBU2dRLE9BQU87c0JBQzdDbmIsS0FBSzRjLE1BQU0xQixPQUFPdkYsTUFBTWlHO3NCQUN4QjViLEtBQUs0YyxNQUFNMUIsT0FBT3ZGLE1BQU0yRztnQkFDOUJ0YyxLQUFLOFksV0FBVztBQUNqQjtZQUVELElBQUksRUFBQ2xELFVBQVVFLEtBQUtGLFVBQVU2SyxTQUFRdFYsU0FBU2dRLE9BQU87c0JBQzlDbmIsS0FBS29iLE9BQ1R6RixNQUFNaUcsS0FDTlYsT0FDQSxPQUNBLGdCQUNBbGIsS0FBSzRZLFNBQ0xzRSxjQUNBcUQ7c0JBRUl2Z0IsS0FBS29iLE9BQ1R6RixNQUFNMkcsS0FDTnBCLE9BQ0EsT0FDQSxnQkFDQWxiLEtBQUs0WSxTQUNMc0UsY0FDQXFEO2dCQUVGdmdCLEtBQUs4WSxXQUFXO0FBQ2pCO1lBRUQ5WSxLQUFLNmMsV0FBV2xILE1BQU0yRztZQUN0QnRjLEtBQUs2YyxXQUFXbEgsTUFBTWlHO0FBQ3ZCO1FBVUQsY0FBTThFLENBQ0p2RixPQUFrQnZGLFVBQVVFLEtBQzVCeUssYUFDQXJEO1lBRUEsT0FBT2xkLEtBQUtzZ0IsV0FBVyxNQUFNbkYsTUFBTW9GLGFBQWFyRDtBQUNqRDtRQVdELGVBQU15RCxDQUNKeEYsT0FBa0J2RixVQUFVRSxLQUM1QnlLLGFBQ0FyRDtZQUVBLE9BQU9sZCxLQUFLc2dCLFdBQVcsT0FBT25GLE1BQU1vRixhQUFhckQ7QUFDbEQ7UUFRRCxlQUFNMEQ7a0JBQ0VqVixXQUFXLG1DQUFtQ007a0JBQzlDTixXQUFXLGtEQUFrRE07a0JBQzdETixXQUNKLHFFQUNBTTtrQkFDSU4sV0FBVyxrQ0FBa0NNO1lBQ25ELEVBQ0U7Z0JBQ0U0VSxLQUFLO2dCQUNMMVMsTUFBTTtlQUVSO2dCQUNFMFMsS0FBSztnQkFDTDFTLE1BQU07ZUFFUjtnQkFDRTBTLEtBQUs7Z0JBQ0wxUyxNQUFNO2VBRVI7Z0JBQ0UwUyxLQUFLO2dCQUNMMVMsTUFBTTtlQUVSO2dCQUNFMFMsS0FBSztnQkFDTDFTLE1BQU07Z0JBRVIzQixRQUFTdEQ7Z0JBQ1QsT0FBTTJYLEtBQUVBLEtBQUcxUyxNQUFFQSxRQUFTakY7Z0JBQ3RCcUYsU0FBU3NTLEtBQUsxUzs7WUFJaEI7Z0JBQ0UsTUFBTXNELGVBQWViLGtCQUNuQjVELGNBQUFBLFdBQUszRSxRQUFRMkUsY0FBQUEsV0FBSzlJLEtBQUt3QixRQUFRaUYsT0FBTztnQkFFeEMzSyxLQUFLMlksYUFBYWpELHVCQUF1QixHQUFHakU7QUFDN0MsY0FBQztnQkFFQXpSLEtBQUsyWSxhQUFhakQsdUJBQXVCO0FBQzFDO1lBR0Q7Z0JBQ0UzSSxVQUFVLGVBQWUvTSxLQUFLMlk7QUFDL0IsY0FBQyxPQUFPeFQ7Z0JBQ1AsTUFBTXZCLE1BQU01RCxLQUFLNEQsSUFBSXpELElBQUlILEtBQUs0Z0I7Z0JBQzlCaGQsSUFBSXBELFFBQVEsOEJBQThCMkU7QUFDM0M7QUFDRjtRQUVTLFNBQU0rTyxDQUNkblE7WUFHQSxPQUFNMkwsS0FBRUEsS0FBR0YsTUFBRUEsTUFBSXdHLE1BQUVBLE1BQUlILFdBQUVBLFdBQVMxSyxVQUFFQSxVQUFRNEssV0FBRUEsYUFBY2hTO1lBQzVELElBQUkyTCxLQUFLO2dCQUNQLGFBQWExUCxLQUFLMGdCLFNBQVM3SyxXQUF3QjFLLFVBQVU0SztBQUM5RDtZQUNELElBQUl2RyxNQUFNO2dCQUNSLGFBQWF4UCxLQUFLMmdCLFVBQVU5SyxXQUF3QjFLLFVBQVU0SztBQUMvRDtZQUNELElBQUlDLE1BQU07Z0JBQ1IsYUFBYWhXLEtBQUs0Z0I7QUFDbkI7QUFDRjs7SUNwNkJILE1BQU1wYixVQUFVO1FBQ2RzYixJQUFJO1lBQ0Z4Z0IsTUFBTTtZQUNOMEYsU0FBUzs7UUFFWHJGLFNBQVM7WUFDUEwsTUFBTTtZQUNOeUYsT0FBTzs7UUFFVGdiLEtBQUs7WUFDSHpnQixNQUFNO1lBQ055RixPQUFPO1lBQ1BDLFNBQVN2Qjs7O0lBaUJQLE1BQU91YyxzQkFBc0I3TjtRQUNqQyxXQUFBL1M7WUFDRW1ULE1BQU0saUJBQWlCL047QUFDeEI7UUF3QkQsb0JBQU15YixDQUFlRjtZQUNuQixNQUFNbmQsTUFBTTVELEtBQUs0RCxJQUFJekQsSUFBSUgsS0FBS2loQjtZQUM5QkYsTUFBTS9nQixLQUFLa2hCLFlBQWFILE9BQWtCO1lBQzFDLEtBQUtBLEtBQUs7Z0JBQ1JuZCxJQUFJcEQsUUFBUTtnQkFDWm9ELElBQUl3QixLQUFLO3NCQUNIdUcsV0FBVywwQ0FBMENNO2dCQUMzRCxhQUFhbE0sVUFBVXNGLGNBQ3JCLE9BQ0EsbURBQ0NvSCxTQUNHQSxJQUFJMUgsV0FBV21HLE1BQU07QUFFNUI7WUFDRCxPQUFPNlY7QUFDUjtRQVFELFdBQUFHLENBQVlqYjtZQUNWLE1BQU1yQyxNQUFNNUQsS0FBSzRELElBQUl6RCxJQUFJSCxLQUFLa2hCO1lBQzlCamIsVUFBVUEsUUFBUXNDLE9BQU80WTtZQUN6QixRQUFRbGI7Y0FDTixLQUFLZSxRQUFBQSxXQUFXb2E7Y0FDaEIsS0FBS3BhLFFBQUFBLFdBQVdxYTtjQUNoQixLQUFLcmEsUUFBVUEsV0FBQ3NhO2dCQUNkMWQsSUFBSXBELFFBQVEsaUNBQWlDeUYsV0FBVztnQkFDeEQsT0FBT0E7O2NBQ1Q7Z0JBQ0VyQyxJQUFJcEQsUUFDRixzREFBc0R5RixXQUN0RDtnQkFFRixLQUFLLElBQUkwRyxPQUFPN0YsaUJBQWlCakMsS0FBS29CLFVBQVU7b0JBQzlDckMsSUFBSWlDLE1BQU0sMkJBQTJCSTtvQkFDckMsT0FBT3hCO0FBQ1I7Z0JBQ0RiLElBQUlwRCxRQUFRLHFCQUFxQnlGLFdBQVc7Z0JBQzVDLE9BQU9BOztBQUVaO1FBUUQsb0JBQU1zYixDQUFlNWdCO1lBQ25CLE1BQU1pRCxNQUFNNUQsS0FBSzRELElBQUl6RCxJQUFJSCxLQUFLdWhCO1lBQzlCLEtBQUs1Z0IsU0FBUztnQkFDWmlELElBQUlwRCxRQUFRO2dCQUNaLGFBQWFULFVBQVVzRixjQUNyQixXQUNBLDhDQUNDb0gsU0FBVUEsT0FBT0EsSUFBSTFILFdBQVcwRCxTQUFTO0FBRTdDO1lBQ0QsT0FBTzlIO0FBQ1I7UUFnQ0QsU0FBTXVULENBQ0p6TztZQUdBLElBQUlUO1lBQ0osT0FBTThiLElBQUVBLE1BQU9yYjtZQUNmLEtBQUlzYixLQUFFQSxLQUFHcGdCLFNBQUVBLFdBQVk4RTtZQUN2QnNiLFlBQVkvZ0IsS0FBS2loQixlQUFlRjtZQUNoQ3BnQixnQkFBZ0JYLEtBQUt1aEIsZUFBZTVnQjtZQUNwQ3FFLGVBQWUyRyxXQUFXLDhCQUE4Qm9WLE9BQU9wZ0IsV0FBVztnQkFDeEVnSyxLQUFLakYsUUFBUWlGO2VBQ1pzQjtZQUNIakgsZUFBZTJHLFdBQVcsMEJBQTBCTTtrQkFDOUNqSDtZQUNOLElBQ0VBLE9BQU9tRCxLQUFLTSxnQkFDTDFJLFVBQVUyRSxnQkFDZixlQUNBLDZEQUNBLE9BRUY7c0JBQ01pSCxXQUFXLGFBQWFNO3NCQUN4Qk4sV0FDSixrQkFBa0JvVixTQUFTcGdCLHNDQUFzQ21nQixLQUFLLEtBQUs3WixhQUMzRWdGO0FBQ0g7a0JBQ0tOLFdBQ0osZ0JBQWdCb1YsWUFBWXBnQixVQUFVbWdCLEtBQUssS0FBSzdaLGFBQ2hEZ0Y7a0JBQ0lOLFdBQVcsMEJBQTBCTTtZQUMzQyxLQUFLNlUsSUFBSTtzQkFDRG5WLFdBQVcsMERBQ2RNO0FBQ0o7QUFDRjs7SUMvSEcsTUFBT3VWLDJCQUEyQm5hO1FBT3RDLFdBQUFqSCxDQUNFa0gsS0FDQUMsTUFDQW1GLFFBQ0FKLFFBQVE7WUFFUmlILE1BQU1qTSxLQUFLQztZQUNYO2dCQUNFdkgsS0FBSzBNLGdCQUNJQSxXQUFXLFdBQVcsSUFBSUMsT0FBT0QsUUFBUUosU0FBU0k7QUFDNUQsY0FBQyxPQUFPdkg7Z0JBQ1AsTUFBTSxJQUFJZCxNQUFNLCtCQUErQmM7QUFDaEQ7QUFDRjtRQVNPLElBQUFOLENBQUsyQztZQUNYeEgsS0FBSzBNLE9BQU8rVSxZQUFZO1lBQ3hCLElBQUl2VztZQUNKO2dCQUNFQSxRQUFRbEwsS0FBSzBNLE9BQU8wSyxLQUFLNVA7QUFDMUIsY0FBQyxPQUFPckM7Z0JBQ1AsT0FBTzROLFFBQVFsTixNQUFNLDBCQUEwQjJCLGdCQUFnQnJDO0FBQ2hFO1lBQ0QsT0FBTytGO0FBQ1I7UUFRUyxjQUFBd1csQ0FBZWxhO1lBQ3ZCLE1BQU0wRCxRQUFRbEwsS0FBSzZFLEtBQUsyQztZQUN4QixJQUFJMEQsT0FBT2xMLEtBQUtxSSxRQUFRNkMsTUFBTTtBQUMvQjtRQVFTLGFBQUF5VyxDQUFjbmE7WUFDdEIsTUFBTTBELFFBQVFsTCxLQUFLNkUsS0FBSzJDO1lBQ3hCLElBQUkwRCxPQUFPbEwsS0FBS3dJLE9BQU8wQyxNQUFNO0FBQzlCO1FBUVEsSUFBQTFELENBQUtLO1lBQ1owTCxNQUFNL0wsS0FBS0s7WUFDWDdILEtBQUswaEIsZUFBZTVaLE9BQU9EO0FBQzVCO1FBUVEsS0FBQXpELENBQU15RDtZQUNiMEwsTUFBTW5QLE1BQU15RDtZQUNaN0gsS0FBSzJoQixjQUFjN1osT0FBT0Q7QUFDM0I7O0lDdkhVLE1BQUErWixVQUFVO0lBU2hCLE1BQU1DLGVBQWU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==