@decaf-ts/mcp-server 0.4.2 → 0.4.6
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.
- package/LICENSE.md +31 -0
- package/dist/mcp-server.cjs +2 -2360
- package/dist/mcp-server.cjs.map +1 -0
- package/dist/mcp-server.js +2 -0
- package/dist/mcp-server.js.map +1 -0
- package/lib/bin/cli.cjs +7 -35
- package/lib/bin/cli.js.map +1 -0
- package/lib/builders/builder.cjs +91 -0
- package/lib/builders/builder.d.ts +25 -0
- package/lib/builders/builder.js.map +1 -0
- package/lib/{mcp/resources → builders}/index.cjs +5 -2
- package/lib/builders/index.d.ts +4 -0
- package/lib/builders/index.js.map +1 -0
- package/lib/builders/prompt-builder.cjs +76 -0
- package/lib/builders/prompt-builder.d.ts +12 -0
- package/lib/builders/prompt-builder.js.map +1 -0
- package/lib/builders/resource-builder.cjs +83 -0
- package/lib/builders/resource-builder.d.ts +14 -0
- package/lib/builders/resource-builder.js.map +1 -0
- package/lib/builders/tool-builder.cjs +104 -0
- package/lib/builders/tool-builder.d.ts +16 -0
- package/lib/builders/tool-builder.js.map +1 -0
- package/lib/constants.cjs +28 -30
- package/lib/constants.d.ts +19 -24
- package/lib/constants.js.map +1 -0
- package/lib/environment.cjs +32 -0
- package/lib/environment.d.ts +71 -0
- package/lib/environment.js.map +1 -0
- package/lib/esm/bin/cli.js +7 -35
- package/lib/esm/bin/cli.js.map +1 -0
- package/lib/esm/builders/builder.d.ts +25 -0
- package/lib/esm/builders/builder.js +86 -0
- package/lib/esm/builders/builder.js.map +1 -0
- package/lib/esm/builders/index.d.ts +4 -0
- package/lib/esm/builders/index.js +5 -0
- package/lib/esm/builders/index.js.map +1 -0
- package/lib/esm/builders/prompt-builder.d.ts +12 -0
- package/lib/esm/builders/prompt-builder.js +72 -0
- package/lib/esm/builders/prompt-builder.js.map +1 -0
- package/lib/esm/builders/resource-builder.d.ts +14 -0
- package/lib/esm/builders/resource-builder.js +79 -0
- package/lib/esm/builders/resource-builder.js.map +1 -0
- package/lib/esm/builders/tool-builder.d.ts +16 -0
- package/lib/esm/builders/tool-builder.js +100 -0
- package/lib/esm/builders/tool-builder.js.map +1 -0
- package/lib/esm/constants.d.ts +19 -24
- package/lib/esm/constants.js +27 -29
- package/lib/esm/constants.js.map +1 -0
- package/lib/esm/environment.d.ts +71 -0
- package/lib/esm/environment.js +29 -0
- package/lib/esm/environment.js.map +1 -0
- package/lib/esm/index.d.ts +3 -10
- package/lib/esm/index.js +4 -11
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/mcp-server.d.ts +10 -0
- package/lib/esm/mcp-server.js +189 -0
- package/lib/esm/mcp-server.js.map +1 -0
- package/lib/esm/modules/template-module/index.d.ts +6 -0
- package/lib/esm/modules/template-module/index.js +4 -0
- package/lib/esm/modules/template-module/index.js.map +1 -0
- package/lib/esm/prompts/code/constants.d.ts +1 -0
- package/lib/esm/prompts/code/constants.js +2 -0
- package/lib/esm/prompts/code/constants.js.map +1 -0
- package/lib/esm/prompts/code/design-patterns/builder.d.ts +2 -0
- package/lib/esm/prompts/code/design-patterns/builder.js +118 -0
- package/lib/esm/prompts/code/design-patterns/builder.js.map +1 -0
- package/lib/esm/prompts/code/design-patterns/constants.d.ts +1 -0
- package/lib/esm/prompts/code/design-patterns/constants.js +3 -0
- package/lib/esm/prompts/code/design-patterns/constants.js.map +1 -0
- package/lib/esm/prompts/example-prompt/index.d.ts +2 -0
- package/lib/esm/prompts/example-prompt/index.js +18 -0
- package/lib/esm/prompts/example-prompt/index.js.map +1 -0
- package/lib/esm/prompts/index.d.ts +2 -0
- package/lib/esm/prompts/index.js +26 -0
- package/lib/esm/prompts/index.js.map +1 -0
- package/lib/esm/prompts/interactive-jsdoc/index.d.ts +2 -0
- package/lib/esm/prompts/interactive-jsdoc/index.js +18 -0
- package/lib/esm/prompts/interactive-jsdoc/index.js.map +1 -0
- package/lib/esm/prompts/jsdocs/class-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/class-prompt.js +52 -0
- package/lib/esm/prompts/jsdocs/class-prompt.js.map +1 -0
- package/lib/esm/prompts/jsdocs/const-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/const-prompt.js +24 -0
- package/lib/esm/prompts/jsdocs/const-prompt.js.map +1 -0
- package/lib/esm/prompts/jsdocs/constants.d.ts +4 -0
- package/lib/esm/prompts/jsdocs/constants.js +46 -0
- package/lib/esm/prompts/jsdocs/constants.js.map +1 -0
- package/lib/esm/prompts/jsdocs/decorator-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/decorator-prompt.js +42 -0
- package/lib/esm/prompts/jsdocs/decorator-prompt.js.map +1 -0
- package/lib/esm/prompts/jsdocs/enum-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/enum-prompt.js +24 -0
- package/lib/esm/prompts/jsdocs/enum-prompt.js.map +1 -0
- package/lib/esm/prompts/jsdocs/function-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/function-prompt.js +43 -0
- package/lib/esm/prompts/jsdocs/function-prompt.js.map +1 -0
- package/lib/esm/prompts/jsdocs/interface-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/interface-prompt.js +24 -0
- package/lib/esm/prompts/jsdocs/interface-prompt.js.map +1 -0
- package/lib/esm/prompts/jsdocs/types-prompt.d.ts +2 -0
- package/lib/esm/prompts/jsdocs/types-prompt.js +24 -0
- package/lib/esm/prompts/jsdocs/types-prompt.js.map +1 -0
- package/lib/esm/resources/example-resource/index.d.ts +2 -0
- package/lib/esm/resources/example-resource/index.js +19 -0
- package/lib/esm/resources/example-resource/index.js.map +1 -0
- package/lib/esm/resources/index.d.ts +2 -0
- package/lib/esm/resources/index.js +4 -0
- package/lib/esm/resources/index.js.map +1 -0
- package/lib/esm/resources/repo-metadata/index.d.ts +2 -0
- package/lib/esm/resources/repo-metadata/index.js +25 -0
- package/lib/esm/resources/repo-metadata/index.js.map +1 -0
- package/lib/esm/tools/ast/ts-ast-tool.d.ts +2 -0
- package/lib/esm/tools/ast/ts-ast-tool.js +67 -0
- package/lib/esm/tools/ast/ts-ast-tool.js.map +1 -0
- package/lib/esm/tools/ast/types.d.ts +105 -0
- package/lib/esm/tools/ast/types.js +33 -0
- package/lib/esm/tools/ast/types.js.map +1 -0
- package/lib/esm/tools/ast/utils.d.ts +5 -0
- package/lib/esm/tools/ast/utils.js +58 -0
- package/lib/esm/tools/ast/utils.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/apply.d.ts +6 -0
- package/lib/esm/tools/ast-jsdoc-tools/apply.js +29 -0
- package/lib/esm/tools/ast-jsdoc-tools/apply.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/cli.js +33 -0
- package/lib/esm/tools/ast-jsdoc-tools/cli.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/enumerator.d.ts +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/enumerator.js +25 -0
- package/lib/esm/tools/ast-jsdoc-tools/enumerator.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/fileRunner.d.ts +11 -0
- package/lib/esm/tools/ast-jsdoc-tools/fileRunner.js +29 -0
- package/lib/esm/tools/ast-jsdoc-tools/fileRunner.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/formatter.d.ts +6 -0
- package/lib/esm/tools/ast-jsdoc-tools/formatter.js +18 -0
- package/lib/esm/tools/ast-jsdoc-tools/formatter.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/generator.d.ts +12 -0
- package/lib/esm/tools/ast-jsdoc-tools/generator.js +55 -0
- package/lib/esm/tools/ast-jsdoc-tools/generator.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/index.d.ts +7 -0
- package/lib/esm/tools/ast-jsdoc-tools/index.js +29 -0
- package/lib/esm/tools/ast-jsdoc-tools/index.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/interactive.d.ts +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/interactive.js +7 -0
- package/lib/esm/tools/ast-jsdoc-tools/interactive.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/parser.d.ts +13 -0
- package/lib/esm/tools/ast-jsdoc-tools/parser.js +71 -0
- package/lib/esm/tools/ast-jsdoc-tools/parser.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/patch.d.ts +2 -0
- package/lib/esm/tools/ast-jsdoc-tools/patch.js +23 -0
- package/lib/esm/tools/ast-jsdoc-tools/patch.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/prompts/loader.d.ts +10 -0
- package/lib/esm/tools/ast-jsdoc-tools/prompts/loader.js +26 -0
- package/lib/esm/tools/ast-jsdoc-tools/prompts/loader.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/repoRunner.d.ts +16 -0
- package/lib/esm/tools/ast-jsdoc-tools/repoRunner.js +61 -0
- package/lib/esm/tools/ast-jsdoc-tools/repoRunner.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/tools/jsdoc-generator.d.ts +5 -0
- package/lib/esm/tools/ast-jsdoc-tools/tools/jsdoc-generator.js +78 -0
- package/lib/esm/tools/ast-jsdoc-tools/tools/jsdoc-generator.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/conflict-detector.d.ts +5 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/conflict-detector.js +30 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/conflict-detector.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/context-schema.d.ts +7 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/context-schema.js +29 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/context-schema.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/heuristics.d.ts +2 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/heuristics.js +31 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/heuristics.js.map +1 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/ts-project.d.ts +12 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/ts-project.js +21 -0
- package/lib/esm/tools/ast-jsdoc-tools/utils/ts-project.js.map +1 -0
- package/lib/esm/tools/example-tool/index.d.ts +2 -0
- package/lib/esm/tools/example-tool/index.js +29 -0
- package/lib/esm/tools/example-tool/index.js.map +1 -0
- package/lib/esm/tools/file-summarizer/index.d.ts +2 -0
- package/lib/esm/tools/file-summarizer/index.js +29 -0
- package/lib/esm/tools/file-summarizer/index.js.map +1 -0
- package/lib/esm/tools/index.d.ts +2 -0
- package/lib/esm/tools/index.js +6 -0
- package/lib/esm/tools/index.js.map +1 -0
- package/lib/esm/tools/jsdoc/ts-jsdoc-element-tool.d.ts +2 -0
- package/lib/esm/tools/jsdoc/ts-jsdoc-element-tool.js +84 -0
- package/lib/esm/tools/jsdoc/ts-jsdoc-element-tool.js.map +1 -0
- package/lib/esm/tools/jsdoc/utils.d.ts +5 -0
- package/lib/esm/tools/jsdoc/utils.js +53 -0
- package/lib/esm/tools/jsdoc/utils.js.map +1 -0
- package/lib/esm/tools/testing/ts-jest-list-tests.d.ts +2 -0
- package/lib/esm/tools/testing/ts-jest-list-tests.js +53 -0
- package/lib/esm/tools/testing/ts-jest-list-tests.js.map +1 -0
- package/lib/esm/types.d.ts +56 -47
- package/lib/esm/types.js +1 -1
- package/lib/esm/types.js.map +1 -0
- package/lib/esm/utils/banner.d.ts +3 -0
- package/lib/esm/utils/banner.js +107 -0
- package/lib/esm/utils/banner.js.map +1 -0
- package/lib/esm/version.d.ts +2 -0
- package/lib/esm/version.js +5 -0
- package/lib/esm/version.js.map +1 -0
- package/lib/index.cjs +4 -11
- package/lib/index.d.ts +3 -10
- package/lib/index.js.map +1 -0
- package/lib/mcp-server.cjs +226 -0
- package/lib/mcp-server.d.ts +10 -0
- package/lib/mcp-server.js.map +1 -0
- package/lib/modules/template-module/index.cjs +7 -0
- package/lib/modules/template-module/index.d.ts +6 -0
- package/lib/modules/template-module/index.js.map +1 -0
- package/lib/prompts/code/constants.cjs +5 -0
- package/lib/prompts/code/constants.d.ts +1 -0
- package/lib/prompts/code/constants.js.map +1 -0
- package/lib/prompts/code/design-patterns/builder.cjs +121 -0
- package/lib/prompts/code/design-patterns/builder.d.ts +2 -0
- package/lib/prompts/code/design-patterns/builder.js.map +1 -0
- package/lib/prompts/code/design-patterns/constants.cjs +6 -0
- package/lib/prompts/code/design-patterns/constants.d.ts +1 -0
- package/lib/prompts/code/design-patterns/constants.js.map +1 -0
- package/lib/prompts/example-prompt/index.cjs +21 -0
- package/lib/prompts/example-prompt/index.d.ts +2 -0
- package/lib/prompts/example-prompt/index.js.map +1 -0
- package/lib/prompts/index.cjs +29 -0
- package/lib/prompts/index.d.ts +2 -0
- package/lib/prompts/index.js.map +1 -0
- package/lib/prompts/interactive-jsdoc/index.cjs +21 -0
- package/lib/prompts/interactive-jsdoc/index.d.ts +2 -0
- package/lib/prompts/interactive-jsdoc/index.js.map +1 -0
- package/lib/prompts/jsdocs/class-prompt.cjs +55 -0
- package/lib/prompts/jsdocs/class-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/class-prompt.js.map +1 -0
- package/lib/prompts/jsdocs/const-prompt.cjs +27 -0
- package/lib/prompts/jsdocs/const-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/const-prompt.js.map +1 -0
- package/lib/prompts/jsdocs/constants.cjs +49 -0
- package/lib/prompts/jsdocs/constants.d.ts +4 -0
- package/lib/prompts/jsdocs/constants.js.map +1 -0
- package/lib/prompts/jsdocs/decorator-prompt.cjs +45 -0
- package/lib/prompts/jsdocs/decorator-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/decorator-prompt.js.map +1 -0
- package/lib/prompts/jsdocs/enum-prompt.cjs +27 -0
- package/lib/prompts/jsdocs/enum-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/enum-prompt.js.map +1 -0
- package/lib/prompts/jsdocs/function-prompt.cjs +46 -0
- package/lib/prompts/jsdocs/function-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/function-prompt.js.map +1 -0
- package/lib/prompts/jsdocs/interface-prompt.cjs +27 -0
- package/lib/prompts/jsdocs/interface-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/interface-prompt.js.map +1 -0
- package/lib/prompts/jsdocs/types-prompt.cjs +27 -0
- package/lib/prompts/jsdocs/types-prompt.d.ts +2 -0
- package/lib/prompts/jsdocs/types-prompt.js.map +1 -0
- package/lib/resources/example-resource/index.cjs +22 -0
- package/lib/resources/example-resource/index.d.ts +2 -0
- package/lib/resources/example-resource/index.js.map +1 -0
- package/lib/resources/index.cjs +7 -0
- package/lib/resources/index.d.ts +2 -0
- package/lib/resources/index.js.map +1 -0
- package/lib/resources/repo-metadata/index.cjs +28 -0
- package/lib/resources/repo-metadata/index.d.ts +2 -0
- package/lib/resources/repo-metadata/index.js.map +1 -0
- package/lib/tools/ast/ts-ast-tool.cjs +70 -0
- package/lib/tools/ast/ts-ast-tool.d.ts +2 -0
- package/lib/tools/ast/ts-ast-tool.js.map +1 -0
- package/lib/tools/ast/types.cjs +36 -0
- package/lib/tools/ast/types.d.ts +105 -0
- package/lib/tools/ast/types.js.map +1 -0
- package/lib/tools/ast/utils.cjs +65 -0
- package/lib/tools/ast/utils.d.ts +5 -0
- package/lib/tools/ast/utils.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/apply.cjs +36 -0
- package/lib/tools/ast-jsdoc-tools/apply.d.ts +6 -0
- package/lib/tools/ast-jsdoc-tools/apply.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/cli.cjs +38 -0
- package/lib/tools/ast-jsdoc-tools/cli.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/enumerator.cjs +31 -0
- package/lib/tools/ast-jsdoc-tools/enumerator.d.ts +1 -0
- package/lib/tools/ast-jsdoc-tools/enumerator.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/fileRunner.cjs +35 -0
- package/lib/tools/ast-jsdoc-tools/fileRunner.d.ts +11 -0
- package/lib/tools/ast-jsdoc-tools/fileRunner.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/formatter.cjs +21 -0
- package/lib/tools/ast-jsdoc-tools/formatter.d.ts +6 -0
- package/lib/tools/ast-jsdoc-tools/formatter.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/generator.cjs +58 -0
- package/lib/tools/ast-jsdoc-tools/generator.d.ts +12 -0
- package/lib/tools/ast-jsdoc-tools/generator.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/index.cjs +33 -0
- package/lib/tools/ast-jsdoc-tools/index.d.ts +7 -0
- package/lib/tools/ast-jsdoc-tools/index.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/interactive.cjs +10 -0
- package/lib/tools/ast-jsdoc-tools/interactive.d.ts +1 -0
- package/lib/tools/ast-jsdoc-tools/interactive.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/parser.cjs +77 -0
- package/lib/tools/ast-jsdoc-tools/parser.d.ts +13 -0
- package/lib/tools/ast-jsdoc-tools/parser.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/patch.cjs +29 -0
- package/lib/tools/ast-jsdoc-tools/patch.d.ts +2 -0
- package/lib/tools/ast-jsdoc-tools/patch.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/prompts/loader.cjs +32 -0
- package/lib/tools/ast-jsdoc-tools/prompts/loader.d.ts +10 -0
- package/lib/tools/ast-jsdoc-tools/prompts/loader.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/repoRunner.cjs +67 -0
- package/lib/tools/ast-jsdoc-tools/repoRunner.d.ts +16 -0
- package/lib/tools/ast-jsdoc-tools/repoRunner.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/tools/jsdoc-generator.cjs +81 -0
- package/lib/tools/ast-jsdoc-tools/tools/jsdoc-generator.d.ts +5 -0
- package/lib/tools/ast-jsdoc-tools/tools/jsdoc-generator.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/utils/conflict-detector.cjs +33 -0
- package/lib/tools/ast-jsdoc-tools/utils/conflict-detector.d.ts +5 -0
- package/lib/tools/ast-jsdoc-tools/utils/conflict-detector.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/utils/context-schema.cjs +32 -0
- package/lib/tools/ast-jsdoc-tools/utils/context-schema.d.ts +7 -0
- package/lib/tools/ast-jsdoc-tools/utils/context-schema.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/utils/heuristics.cjs +34 -0
- package/lib/tools/ast-jsdoc-tools/utils/heuristics.d.ts +2 -0
- package/lib/tools/ast-jsdoc-tools/utils/heuristics.js.map +1 -0
- package/lib/tools/ast-jsdoc-tools/utils/ts-project.cjs +57 -0
- package/lib/tools/ast-jsdoc-tools/utils/ts-project.d.ts +12 -0
- package/lib/tools/ast-jsdoc-tools/utils/ts-project.js.map +1 -0
- package/lib/tools/example-tool/index.cjs +32 -0
- package/lib/tools/example-tool/index.d.ts +2 -0
- package/lib/tools/example-tool/index.js.map +1 -0
- package/lib/tools/file-summarizer/index.cjs +32 -0
- package/lib/tools/file-summarizer/index.d.ts +2 -0
- package/lib/tools/file-summarizer/index.js.map +1 -0
- package/lib/tools/index.cjs +9 -0
- package/lib/tools/index.d.ts +2 -0
- package/lib/tools/index.js.map +1 -0
- package/lib/tools/jsdoc/ts-jsdoc-element-tool.cjs +87 -0
- package/lib/tools/jsdoc/ts-jsdoc-element-tool.d.ts +2 -0
- package/lib/tools/jsdoc/ts-jsdoc-element-tool.js.map +1 -0
- package/lib/tools/jsdoc/utils.cjs +60 -0
- package/lib/tools/jsdoc/utils.d.ts +5 -0
- package/lib/tools/jsdoc/utils.js.map +1 -0
- package/lib/tools/testing/ts-jest-list-tests.cjs +56 -0
- package/lib/tools/testing/ts-jest-list-tests.d.ts +2 -0
- package/lib/tools/testing/ts-jest-list-tests.js.map +1 -0
- package/lib/types.cjs +1 -1
- package/lib/types.d.ts +56 -47
- package/lib/types.js.map +1 -0
- package/lib/utils/banner.cjs +114 -0
- package/lib/utils/banner.d.ts +3 -0
- package/lib/utils/banner.js.map +1 -0
- package/lib/version.cjs +8 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.js.map +1 -0
- package/package.json +14 -63
- package/dist/mcp-server.esm.cjs +0 -2314
- package/lib/McpWrapper.cjs +0 -233
- package/lib/McpWrapper.d.ts +0 -89
- package/lib/bin/validate-modules.cjs +0 -24
- package/lib/esm/McpWrapper.d.ts +0 -89
- package/lib/esm/McpWrapper.js +0 -196
- package/lib/esm/bin/validate-modules.js +0 -22
- package/lib/esm/mcp/aggregateModules.d.ts +0 -26
- package/lib/esm/mcp/aggregateModules.js +0 -185
- package/lib/esm/mcp/code.d.ts +0 -23
- package/lib/esm/mcp/code.js +0 -70
- package/lib/esm/mcp/decorator-tools.d.ts +0 -118
- package/lib/esm/mcp/decorator-tools.js +0 -237
- package/lib/esm/mcp/fastmcp-wiring.d.ts +0 -14
- package/lib/esm/mcp/fastmcp-wiring.js +0 -56
- package/lib/esm/mcp/index.d.ts +0 -9
- package/lib/esm/mcp/index.js +0 -29
- package/lib/esm/mcp/mcp-module.d.ts +0 -11
- package/lib/esm/mcp/mcp-module.js +0 -31
- package/lib/esm/mcp/moduleRegistry.d.ts +0 -14
- package/lib/esm/mcp/moduleRegistry.js +0 -47
- package/lib/esm/mcp/prompts/index.d.ts +0 -4
- package/lib/esm/mcp/prompts/index.js +0 -7
- package/lib/esm/mcp/prompts/prompts.d.ts +0 -22
- package/lib/esm/mcp/prompts/prompts.js +0 -203
- package/lib/esm/mcp/resources/index.d.ts +0 -1
- package/lib/esm/mcp/resources/index.js +0 -2
- package/lib/esm/mcp/resources/resources.d.ts +0 -2
- package/lib/esm/mcp/resources/resources.js +0 -69
- package/lib/esm/mcp/schemas.d.ts +0 -53
- package/lib/esm/mcp/schemas.js +0 -97
- package/lib/esm/mcp/templates/codex-templates.d.ts +0 -3
- package/lib/esm/mcp/templates/codex-templates.js +0 -33
- package/lib/esm/mcp/templates/index.d.ts +0 -71
- package/lib/esm/mcp/templates/index.js +0 -66
- package/lib/esm/mcp/templates/resource-templates.d.ts +0 -3
- package/lib/esm/mcp/templates/resource-templates.js +0 -60
- package/lib/esm/mcp/templates/workspace-templates.d.ts +0 -3
- package/lib/esm/mcp/templates/workspace-templates.js +0 -66
- package/lib/esm/mcp/tools/codex-tools.d.ts +0 -5
- package/lib/esm/mcp/tools/codex-tools.js +0 -244
- package/lib/esm/mcp/tools/generateMcpModule.d.ts +0 -9
- package/lib/esm/mcp/tools/generateMcpModule.js +0 -133
- package/lib/esm/mcp/tools/index.d.ts +0 -219
- package/lib/esm/mcp/tools/index.js +0 -27
- package/lib/esm/mcp/tools/tools.d.ts +0 -10
- package/lib/esm/mcp/tools/tools.js +0 -275
- package/lib/esm/mcp/types.d.ts +0 -66
- package/lib/esm/mcp/types.js +0 -2
- package/lib/esm/mcp/utils.d.ts +0 -3
- package/lib/esm/mcp/utils.js +0 -46
- package/lib/esm/mcp/validation/index.d.ts +0 -13
- package/lib/esm/mcp/validation/index.js +0 -116
- package/lib/esm/mcp/validation/scaffoldModule.d.ts +0 -9
- package/lib/esm/mcp/validation/scaffoldModule.js +0 -88
- package/lib/esm/mcp/workspace.d.ts +0 -9
- package/lib/esm/mcp/workspace.js +0 -73
- package/lib/esm/metadata.d.ts +0 -9
- package/lib/esm/metadata.js +0 -22
- package/lib/esm/modules/_template/index.d.ts +0 -32
- package/lib/esm/modules/_template/index.js +0 -16
- package/lib/esm/modules/_template/prompts/index.d.ts +0 -6
- package/lib/esm/modules/_template/prompts/index.js +0 -9
- package/lib/esm/modules/_template/resources/index.d.ts +0 -6
- package/lib/esm/modules/_template/resources/index.js +0 -9
- package/lib/esm/modules/_template/templates/index.d.ts +0 -7
- package/lib/esm/modules/_template/templates/index.js +0 -10
- package/lib/esm/modules/_template/tools/index.d.ts +0 -6
- package/lib/esm/modules/_template/tools/index.js +0 -15
- package/lib/esm/modules/decoration/index.d.ts +0 -46
- package/lib/esm/modules/decoration/index.js +0 -10
- package/lib/esm/modules/decoration/prompts/index.d.ts +0 -1
- package/lib/esm/modules/decoration/prompts/index.js +0 -2
- package/lib/esm/modules/decoration/resources/index.d.ts +0 -7
- package/lib/esm/modules/decoration/resources/index.js +0 -10
- package/lib/esm/modules/decoration/templates/index.d.ts +0 -6
- package/lib/esm/modules/decoration/templates/index.js +0 -9
- package/lib/esm/modules/decoration/tools/index.d.ts +0 -26
- package/lib/esm/modules/decoration/tools/index.js +0 -7
- package/lib/esm/modules/index.d.ts +0 -2
- package/lib/esm/modules/index.js +0 -17
- package/lib/esm/modules/mcp/decoration-assist.d.ts +0 -4
- package/lib/esm/modules/mcp/decoration-assist.js +0 -6
- package/lib/esm/modules/mcp/index.d.ts +0 -6
- package/lib/esm/modules/mcp/index.js +0 -16
- package/lib/esm/modules/mcp/prompts/index.d.ts +0 -2
- package/lib/esm/modules/mcp/prompts/index.js +0 -9
- package/lib/esm/modules/mcp/resources/index.d.ts +0 -2
- package/lib/esm/modules/mcp/resources/index.js +0 -24
- package/lib/esm/modules/mcp/templates/index.d.ts +0 -2
- package/lib/esm/modules/mcp/templates/index.js +0 -28
- package/lib/esm/modules/mcp/tools/index.d.ts +0 -6
- package/lib/esm/modules/mcp/tools/index.js +0 -15
- package/lib/esm/utils/modulePaths.d.ts +0 -6
- package/lib/esm/utils/modulePaths.js +0 -33
- package/lib/esm/utils/moduleValidator.d.ts +0 -14
- package/lib/esm/utils/moduleValidator.js +0 -176
- package/lib/esm/utils.d.ts +0 -61
- package/lib/esm/utils.js +0 -86
- package/lib/mcp/aggregateModules.cjs +0 -225
- package/lib/mcp/aggregateModules.d.ts +0 -26
- package/lib/mcp/code.cjs +0 -81
- package/lib/mcp/code.d.ts +0 -23
- package/lib/mcp/decorator-tools.cjs +0 -243
- package/lib/mcp/decorator-tools.d.ts +0 -118
- package/lib/mcp/fastmcp-wiring.cjs +0 -59
- package/lib/mcp/fastmcp-wiring.d.ts +0 -14
- package/lib/mcp/index.cjs +0 -57
- package/lib/mcp/index.d.ts +0 -9
- package/lib/mcp/mcp-module.cjs +0 -46
- package/lib/mcp/mcp-module.d.ts +0 -11
- package/lib/mcp/moduleRegistry.cjs +0 -52
- package/lib/mcp/moduleRegistry.d.ts +0 -14
- package/lib/mcp/prompts/index.cjs +0 -25
- package/lib/mcp/prompts/index.d.ts +0 -4
- package/lib/mcp/prompts/prompts.cjs +0 -217
- package/lib/mcp/prompts/prompts.d.ts +0 -22
- package/lib/mcp/resources/index.d.ts +0 -1
- package/lib/mcp/resources/resources.cjs +0 -72
- package/lib/mcp/resources/resources.d.ts +0 -2
- package/lib/mcp/schemas.cjs +0 -100
- package/lib/mcp/schemas.d.ts +0 -53
- package/lib/mcp/templates/codex-templates.cjs +0 -40
- package/lib/mcp/templates/codex-templates.d.ts +0 -3
- package/lib/mcp/templates/index.cjs +0 -76
- package/lib/mcp/templates/index.d.ts +0 -71
- package/lib/mcp/templates/resource-templates.cjs +0 -67
- package/lib/mcp/templates/resource-templates.d.ts +0 -3
- package/lib/mcp/templates/workspace-templates.cjs +0 -70
- package/lib/mcp/templates/workspace-templates.d.ts +0 -3
- package/lib/mcp/tools/codex-tools.cjs +0 -250
- package/lib/mcp/tools/codex-tools.d.ts +0 -5
- package/lib/mcp/tools/generateMcpModule.cjs +0 -139
- package/lib/mcp/tools/generateMcpModule.d.ts +0 -9
- package/lib/mcp/tools/index.cjs +0 -30
- package/lib/mcp/tools/index.d.ts +0 -219
- package/lib/mcp/tools/tools.cjs +0 -317
- package/lib/mcp/tools/tools.d.ts +0 -10
- package/lib/mcp/types.cjs +0 -3
- package/lib/mcp/types.d.ts +0 -66
- package/lib/mcp/utils.cjs +0 -54
- package/lib/mcp/utils.d.ts +0 -3
- package/lib/mcp/validation/index.cjs +0 -123
- package/lib/mcp/validation/index.d.ts +0 -13
- package/lib/mcp/validation/scaffoldModule.cjs +0 -94
- package/lib/mcp/validation/scaffoldModule.d.ts +0 -9
- package/lib/mcp/workspace.cjs +0 -119
- package/lib/mcp/workspace.d.ts +0 -9
- package/lib/metadata.cjs +0 -25
- package/lib/metadata.d.ts +0 -9
- package/lib/modules/_template/index.cjs +0 -23
- package/lib/modules/_template/index.d.ts +0 -32
- package/lib/modules/_template/prompts/index.cjs +0 -12
- package/lib/modules/_template/prompts/index.d.ts +0 -6
- package/lib/modules/_template/resources/index.cjs +0 -12
- package/lib/modules/_template/resources/index.d.ts +0 -6
- package/lib/modules/_template/templates/index.cjs +0 -13
- package/lib/modules/_template/templates/index.d.ts +0 -7
- package/lib/modules/_template/tools/index.cjs +0 -18
- package/lib/modules/_template/tools/index.d.ts +0 -6
- package/lib/modules/decoration/index.cjs +0 -17
- package/lib/modules/decoration/index.d.ts +0 -46
- package/lib/modules/decoration/prompts/index.cjs +0 -5
- package/lib/modules/decoration/prompts/index.d.ts +0 -1
- package/lib/modules/decoration/resources/index.cjs +0 -13
- package/lib/modules/decoration/resources/index.d.ts +0 -7
- package/lib/modules/decoration/templates/index.cjs +0 -12
- package/lib/modules/decoration/templates/index.d.ts +0 -6
- package/lib/modules/decoration/tools/index.cjs +0 -10
- package/lib/modules/decoration/tools/index.d.ts +0 -26
- package/lib/modules/index.cjs +0 -20
- package/lib/modules/index.d.ts +0 -2
- package/lib/modules/mcp/decoration-assist.cjs +0 -13
- package/lib/modules/mcp/decoration-assist.d.ts +0 -4
- package/lib/modules/mcp/index.cjs +0 -23
- package/lib/modules/mcp/index.d.ts +0 -6
- package/lib/modules/mcp/prompts/index.cjs +0 -12
- package/lib/modules/mcp/prompts/index.d.ts +0 -2
- package/lib/modules/mcp/resources/index.cjs +0 -27
- package/lib/modules/mcp/resources/index.d.ts +0 -2
- package/lib/modules/mcp/templates/index.cjs +0 -31
- package/lib/modules/mcp/templates/index.d.ts +0 -2
- package/lib/modules/mcp/tools/index.cjs +0 -18
- package/lib/modules/mcp/tools/index.d.ts +0 -6
- package/lib/utils/modulePaths.cjs +0 -43
- package/lib/utils/modulePaths.d.ts +0 -6
- package/lib/utils/moduleValidator.cjs +0 -184
- package/lib/utils/moduleValidator.d.ts +0 -14
- package/lib/utils.cjs +0 -129
- package/lib/utils.d.ts +0 -61
- /package/lib/{bin/validate-modules.d.ts → esm/tools/ast-jsdoc-tools/cli.d.ts} +0 -0
- /package/lib/{esm/bin/validate-modules.d.ts → tools/ast-jsdoc-tools/cli.d.ts} +0 -0
package/dist/mcp-server.cjs
CHANGED
|
@@ -1,2360 +1,2 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'fs', 'path', 'child_process', 'zod', 'diff', '@decaf-ts/decoration', 'url', 'node:fs', 'node:path', 'fastmcp', '@decaf-ts/logging'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["mcp-server"] = {}, global.fs, global.path, global.child_process, global.zod, global.diff, global.decoration, global.url, global.fs$1, global.path$1, global.fastmcp, global.logging));
|
|
5
|
-
})(this, (function (exports, fs, path, child_process, zod, diff, decoration, url, fs$1, path$1, fastmcp, logging) { 'use strict';
|
|
6
|
-
|
|
7
|
-
function _interopNamespaceDefault(e) {
|
|
8
|
-
var n = Object.create(null);
|
|
9
|
-
if (e) {
|
|
10
|
-
Object.keys(e).forEach(function (k) {
|
|
11
|
-
if (k !== 'default') {
|
|
12
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () { return e[k]; }
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
n.default = e;
|
|
21
|
-
return Object.freeze(n);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
25
|
-
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @description The filename that identifies Decaf CLI modules
|
|
29
|
-
* @summary The standard filename for CLI module files where each library must export a single CliModule function
|
|
30
|
-
*
|
|
31
|
-
* @const MCP_FILE_NAME
|
|
32
|
-
* @memberOf module:MCP
|
|
33
|
-
*/
|
|
34
|
-
const MCP_FILE_NAME = "mcp-module";
|
|
35
|
-
const WORKSPACE_ROOT_ENV = "MCP_WORKSPACE_ROOT";
|
|
36
|
-
const PROMPT_DIRECTORIES = [".code/prompts", ".codex/prompts"];
|
|
37
|
-
const DEFAULT_PROMPT_NAME = "doc";
|
|
38
|
-
const CLIENT_INTEGRATIONS = [
|
|
39
|
-
{
|
|
40
|
-
id: "vscode",
|
|
41
|
-
display: "Visual Studio Code",
|
|
42
|
-
instructions: "When interacting from Visual Studio Code, prefer the vscode://workspace/{path} resource template to fetch file contents and use the apply-code-change tool to commit edits with previewable diffs.",
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
id: "cursor",
|
|
46
|
-
display: "Cursor",
|
|
47
|
-
instructions: "Cursor clients can retrieve and update files through the cursor://workspace/{path} resource template. Always validate patches in dryRun mode before applying permanent changes.",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "copilot",
|
|
51
|
-
display: "GitHub Copilot",
|
|
52
|
-
instructions: "Use the copilot://workspace/{path} resource template to stream file content into Copilot chat sessions. Prefer returning unified diffs to maintain alignment with Copilot's diff visualization.",
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
let workspaceRoot = initializeWorkspaceRoot();
|
|
57
|
-
let userErrorCtor;
|
|
58
|
-
class WorkspaceError extends Error {
|
|
59
|
-
constructor(message) {
|
|
60
|
-
super(message);
|
|
61
|
-
this.name = "WorkspaceError";
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function initializeWorkspaceRoot() {
|
|
65
|
-
const configured = process.env[WORKSPACE_ROOT_ENV];
|
|
66
|
-
if (configured && configured.trim().length > 0) {
|
|
67
|
-
return path.resolve(configured.trim());
|
|
68
|
-
}
|
|
69
|
-
return process.cwd();
|
|
70
|
-
}
|
|
71
|
-
async function getUserErrorCtor() {
|
|
72
|
-
if (!userErrorCtor) {
|
|
73
|
-
try {
|
|
74
|
-
const mod = await import('fastmcp');
|
|
75
|
-
userErrorCtor = mod
|
|
76
|
-
.UserError;
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
userErrorCtor = class MCPUserError extends Error {
|
|
80
|
-
constructor(message) {
|
|
81
|
-
super(message);
|
|
82
|
-
this.name = "MCPUserError";
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return userErrorCtor;
|
|
88
|
-
}
|
|
89
|
-
async function throwUserError(message) {
|
|
90
|
-
const Ctor = await getUserErrorCtor();
|
|
91
|
-
throw new Ctor(message);
|
|
92
|
-
}
|
|
93
|
-
function setWorkspaceRoot(root) {
|
|
94
|
-
workspaceRoot = path.resolve(root);
|
|
95
|
-
}
|
|
96
|
-
function getWorkspaceRoot() {
|
|
97
|
-
return workspaceRoot;
|
|
98
|
-
}
|
|
99
|
-
function resolveInWorkspace(root, targetPath) {
|
|
100
|
-
const resolved = path.isAbsolute(targetPath)
|
|
101
|
-
? path.normalize(targetPath)
|
|
102
|
-
: path.resolve(root, targetPath);
|
|
103
|
-
const relative = path.relative(root, resolved);
|
|
104
|
-
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
105
|
-
throw new WorkspaceError(`Path ${targetPath} escapes the workspace root at ${root}`);
|
|
106
|
-
}
|
|
107
|
-
return resolved;
|
|
108
|
-
}
|
|
109
|
-
async function readWorkspaceFile(root, target) {
|
|
110
|
-
try {
|
|
111
|
-
const absolute = resolveInWorkspace(root, target);
|
|
112
|
-
return fs.readFileSync(absolute, "utf8");
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
if (error instanceof WorkspaceError) {
|
|
116
|
-
await throwUserError(error.message);
|
|
117
|
-
}
|
|
118
|
-
/* istanbul ignore next */
|
|
119
|
-
throw error;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
function __resetWorkspaceRoot(root) {
|
|
123
|
-
setWorkspaceRoot(root);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const prompts = [];
|
|
127
|
-
// Read registered module packages from a runtime global set by modules/index
|
|
128
|
-
// This avoids importing moduleRegistry at module-eval time which creates circular imports.
|
|
129
|
-
function getRegisteredModulePackages() {
|
|
130
|
-
return globalThis.__DECAF_MODULE_PACKAGES__ ?? [];
|
|
131
|
-
}
|
|
132
|
-
const OBJECT_PROMPT_DEPENDENCIES = {
|
|
133
|
-
module: ["doc", "module"],
|
|
134
|
-
file: ["doc", "file"],
|
|
135
|
-
class: ["doc", "class"],
|
|
136
|
-
function: ["doc", "function"],
|
|
137
|
-
interface: ["doc", "interface"],
|
|
138
|
-
decorator: ["doc", "decorator"],
|
|
139
|
-
constant: ["doc", "constant"],
|
|
140
|
-
"bulk-docs": ["bulk-docs"],
|
|
141
|
-
"bulk-tests": ["bulk-tests"],
|
|
142
|
-
"update-readme": ["update-readme"],
|
|
143
|
-
"repo-setup": ["repo-setup"],
|
|
144
|
-
"release-notes": ["release-notes"],
|
|
145
|
-
"mcp-module": ["mcp-module"],
|
|
146
|
-
};
|
|
147
|
-
function getObjectPromptDependencies() {
|
|
148
|
-
return OBJECT_PROMPT_DEPENDENCIES;
|
|
149
|
-
}
|
|
150
|
-
function buildDocPrompts() {
|
|
151
|
-
const root = getWorkspaceRoot();
|
|
152
|
-
const fileBasedPrompts = discoverDocPrompts(root).map((prompt) => ({
|
|
153
|
-
name: `doc/${prompt.name}`,
|
|
154
|
-
description: prompt.description,
|
|
155
|
-
load: async () => prompt.content,
|
|
156
|
-
}));
|
|
157
|
-
const integrationPrompts = CLIENT_INTEGRATIONS.map((integration) => ({
|
|
158
|
-
name: `integration/${integration.id}`,
|
|
159
|
-
description: `${integration.display} integration guidance`,
|
|
160
|
-
load: async () => `You are coordinating with ${integration.display}. ${integration.instructions}\n\nTools available:\n- document-code\n- apply-code-change\n\nEnsure responses include actionable steps for the client.`,
|
|
161
|
-
}));
|
|
162
|
-
return [...fileBasedPrompts, ...integrationPrompts];
|
|
163
|
-
}
|
|
164
|
-
function summarizePromptContent(prompt, headingPrefix) {
|
|
165
|
-
return [`## ${headingPrefix}`, "", prompt.content.trim()].join("\n");
|
|
166
|
-
}
|
|
167
|
-
function buildObjectPrompts() {
|
|
168
|
-
const root = getWorkspaceRoot();
|
|
169
|
-
const discovered = discoverDocPrompts(root);
|
|
170
|
-
const promptByName = new Map();
|
|
171
|
-
for (const prompt of discovered) {
|
|
172
|
-
promptByName.set(prompt.name, prompt);
|
|
173
|
-
}
|
|
174
|
-
const outputs = [];
|
|
175
|
-
for (const [objectType, dependencies] of Object.entries(OBJECT_PROMPT_DEPENDENCIES)) {
|
|
176
|
-
const existing = dependencies
|
|
177
|
-
.map((name) => promptByName.get(name))
|
|
178
|
-
.filter((prompt) => Boolean(prompt));
|
|
179
|
-
if (!existing.length)
|
|
180
|
-
continue;
|
|
181
|
-
outputs.push({
|
|
182
|
-
name: `codex/${objectType}`,
|
|
183
|
-
description: `Guidance derived from .codex prompts for ${objectType} tasks.`,
|
|
184
|
-
load: async () => {
|
|
185
|
-
const sections = existing.map((prompt) => summarizePromptContent(prompt, toTitleCase(prompt.name)));
|
|
186
|
-
return [`# Codex guidance for ${objectType}`, "", ...sections].join("\n");
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
return outputs.sort((a, b) => a.name.localeCompare(b.name));
|
|
191
|
-
}
|
|
192
|
-
function toInputPrompt(asset) {
|
|
193
|
-
const provenance = asset.provenance ? ` (module: ${asset.provenance})` : "";
|
|
194
|
-
return {
|
|
195
|
-
name: asset.id,
|
|
196
|
-
description: `${asset.description ?? asset.title}${provenance}`,
|
|
197
|
-
load: async () => asset.load(),
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function buildModulePrompts() {
|
|
201
|
-
const pkgs = getRegisteredModulePackages();
|
|
202
|
-
const assets = pkgs.flatMap((p) => p.prompts ?? []);
|
|
203
|
-
return assets.map(toInputPrompt);
|
|
204
|
-
}
|
|
205
|
-
function refreshPrompts(repoPath) {
|
|
206
|
-
const docPrompts = buildDocPrompts();
|
|
207
|
-
const objectPrompts = buildObjectPrompts();
|
|
208
|
-
const repoPrompts = [];
|
|
209
|
-
const modulePrompts = buildModulePrompts();
|
|
210
|
-
prompts.splice(0, prompts.length, ...docPrompts, ...objectPrompts, ...repoPrompts, ...modulePrompts);
|
|
211
|
-
return prompts;
|
|
212
|
-
}
|
|
213
|
-
function discoverDocPrompts(root) {
|
|
214
|
-
const discovered = [];
|
|
215
|
-
for (const directory of PROMPT_DIRECTORIES) {
|
|
216
|
-
const promptDir = path.join(root, directory);
|
|
217
|
-
// debug logging to help tests diagnose prompt discovery
|
|
218
|
-
console.debug("[discoverDocPrompts] checking", promptDir);
|
|
219
|
-
if (!fs.existsSync(promptDir) || !fs.statSync(promptDir).isDirectory()) {
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
for (const entry of fs.readdirSync(promptDir)) {
|
|
223
|
-
const fullPath = path.join(promptDir, entry);
|
|
224
|
-
if (!fs.statSync(fullPath).isFile())
|
|
225
|
-
continue;
|
|
226
|
-
const name = path.parse(entry).name;
|
|
227
|
-
const content = fs.readFileSync(fullPath, "utf8");
|
|
228
|
-
const title = toTitleCase(name.replace(/[-_]/g, " "));
|
|
229
|
-
const description = extractDescription(content, fullPath);
|
|
230
|
-
discovered.push({
|
|
231
|
-
name,
|
|
232
|
-
title,
|
|
233
|
-
description,
|
|
234
|
-
content,
|
|
235
|
-
absolutePath: fullPath,
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
const unique = new Map();
|
|
240
|
-
for (const prompt of discovered) {
|
|
241
|
-
if (!unique.has(prompt.name)) {
|
|
242
|
-
unique.set(prompt.name, prompt);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return Array.from(unique.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
246
|
-
}
|
|
247
|
-
function selectPrompt(promptList, requestedName) {
|
|
248
|
-
const direct = promptList.find((prompt) => prompt.name === requestedName);
|
|
249
|
-
if (direct)
|
|
250
|
-
return direct;
|
|
251
|
-
const fallback = promptList.find((prompt) => prompt.name === DEFAULT_PROMPT_NAME);
|
|
252
|
-
if (fallback)
|
|
253
|
-
return fallback;
|
|
254
|
-
if (!promptList.length) {
|
|
255
|
-
throw new Error("No documentation prompts available");
|
|
256
|
-
}
|
|
257
|
-
return promptList[0];
|
|
258
|
-
}
|
|
259
|
-
function buildDocumentationPayload({ filePath, fileContent, prompt, includePrompt, includeCode, includeMetadata, additionalContext, }) {
|
|
260
|
-
const sections = [];
|
|
261
|
-
if (includeMetadata) {
|
|
262
|
-
sections.push(`# Documentation Request\n- prompt: ${prompt.name}\n- file: ${filePath}`);
|
|
263
|
-
}
|
|
264
|
-
if (includePrompt) {
|
|
265
|
-
sections.push(`## Prompt Guidance (${prompt.title})\n\n${prompt.content.trim()}`);
|
|
266
|
-
}
|
|
267
|
-
if (additionalContext?.trim()) {
|
|
268
|
-
sections.push(`## Additional Context\n\n${additionalContext.trim()}`);
|
|
269
|
-
}
|
|
270
|
-
if (includeCode) {
|
|
271
|
-
sections.push(`## Source\n\n\`\`\`${inferLanguageFromPath(filePath)}\n${fileContent}\n\`\`\``);
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
content: [
|
|
275
|
-
{
|
|
276
|
-
type: "text",
|
|
277
|
-
text: sections.join("\n\n"),
|
|
278
|
-
},
|
|
279
|
-
],
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
function extractDescription(content, filePath) {
|
|
283
|
-
const firstLine = content
|
|
284
|
-
.split(/\r?\n/)
|
|
285
|
-
.map((line) => line.trim())
|
|
286
|
-
.find((line) => line.length > 0);
|
|
287
|
-
return (firstLine?.slice(0, 240) ??
|
|
288
|
-
`Documentation prompt loaded from ${path.basename(filePath)}`);
|
|
289
|
-
}
|
|
290
|
-
function toTitleCase(value) {
|
|
291
|
-
return value
|
|
292
|
-
.split(/\s+/)
|
|
293
|
-
.filter(Boolean)
|
|
294
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
|
|
295
|
-
.join(" ");
|
|
296
|
-
}
|
|
297
|
-
function inferLanguageFromPath(filePath) {
|
|
298
|
-
const extension = path.extname(filePath).toLowerCase();
|
|
299
|
-
switch (extension) {
|
|
300
|
-
case ".ts":
|
|
301
|
-
case ".tsx":
|
|
302
|
-
return "ts";
|
|
303
|
-
case ".js":
|
|
304
|
-
case ".jsx":
|
|
305
|
-
return "js";
|
|
306
|
-
case ".json":
|
|
307
|
-
return "json";
|
|
308
|
-
case ".md":
|
|
309
|
-
return "md";
|
|
310
|
-
default:
|
|
311
|
-
return "text";
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
var prompts$1 = /*#__PURE__*/Object.freeze({
|
|
316
|
-
__proto__: null,
|
|
317
|
-
DEFAULT_PROMPT_NAME: DEFAULT_PROMPT_NAME,
|
|
318
|
-
buildDocPrompts: buildDocPrompts,
|
|
319
|
-
buildDocumentationPayload: buildDocumentationPayload,
|
|
320
|
-
buildObjectPrompts: buildObjectPrompts,
|
|
321
|
-
discoverDocPrompts: discoverDocPrompts,
|
|
322
|
-
getObjectPromptDependencies: getObjectPromptDependencies,
|
|
323
|
-
prompts: prompts,
|
|
324
|
-
refreshPrompts: refreshPrompts,
|
|
325
|
-
selectPrompt: selectPrompt
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
const promptList = prompts;
|
|
329
|
-
function loadPrompts(repoPath) {
|
|
330
|
-
return refreshPrompts();
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
class ModuleRegistry {
|
|
334
|
-
constructor(packages = []) {
|
|
335
|
-
this.packages = packages;
|
|
336
|
-
}
|
|
337
|
-
setPackages(pkgs) {
|
|
338
|
-
this.packages = Array.isArray(pkgs) ? pkgs : [];
|
|
339
|
-
}
|
|
340
|
-
listPackages() {
|
|
341
|
-
return this.packages;
|
|
342
|
-
}
|
|
343
|
-
listPrompts() {
|
|
344
|
-
return this.collectAssets("prompts");
|
|
345
|
-
}
|
|
346
|
-
listResources() {
|
|
347
|
-
return this.collectAssets("resources");
|
|
348
|
-
}
|
|
349
|
-
listTemplates() {
|
|
350
|
-
return this.collectAssets("templates");
|
|
351
|
-
}
|
|
352
|
-
listTools() {
|
|
353
|
-
return this.collectAssets("tools");
|
|
354
|
-
}
|
|
355
|
-
collectAssets(key) {
|
|
356
|
-
const seen = new Map();
|
|
357
|
-
const aggregated = [];
|
|
358
|
-
for (const pkg of this.packages) {
|
|
359
|
-
if (pkg.status === "disabled")
|
|
360
|
-
continue;
|
|
361
|
-
for (const asset of pkg[key]) {
|
|
362
|
-
const maybeName = asset.name;
|
|
363
|
-
const assetKey = (asset && (asset.id ?? maybeName)) || JSON.stringify(asset);
|
|
364
|
-
if (seen.has(assetKey)) {
|
|
365
|
-
const conflict = seen.get(assetKey);
|
|
366
|
-
throw new Error(`Duplicate ${key} id '${assetKey}' from modules ${conflict} and ${pkg.name}`);
|
|
367
|
-
}
|
|
368
|
-
seen.set(assetKey, pkg.name);
|
|
369
|
-
aggregated.push({ ...asset, provenance: pkg.name });
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
return aggregated;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
const moduleRegistry = new ModuleRegistry();
|
|
376
|
-
|
|
377
|
-
const analyzeRepoSchema = zod.z
|
|
378
|
-
.object({
|
|
379
|
-
repoPath: zod.z
|
|
380
|
-
.string()
|
|
381
|
-
.min(1, "repoPath is required")
|
|
382
|
-
.describe("Relative or absolute path to the target repository inside this monorepo, e.g. './decoration'."),
|
|
383
|
-
includeTests: zod.z
|
|
384
|
-
.boolean()
|
|
385
|
-
.default(true)
|
|
386
|
-
.describe("If true, analyze the tests directory (if present) to derive expected behaviors."),
|
|
387
|
-
includeDocs: zod.z
|
|
388
|
-
.boolean()
|
|
389
|
-
.default(true)
|
|
390
|
-
.describe("If true, analyze README.md and docs directories to extract documented features."),
|
|
391
|
-
})
|
|
392
|
-
.strict()
|
|
393
|
-
.describe("Analyze a local repository (e.g. ./decoration) to extract APIs, features, tests, and documentation cues.");
|
|
394
|
-
const enumerateCapabilitiesSchema = zod.z
|
|
395
|
-
.object({
|
|
396
|
-
repoPath: zod.z
|
|
397
|
-
.string()
|
|
398
|
-
.min(1, "repoPath is required")
|
|
399
|
-
.describe("Relative or absolute path to the target repository to enumerate developer-facing capabilities."),
|
|
400
|
-
})
|
|
401
|
-
.strict()
|
|
402
|
-
.describe("Enumerate the complete set of capabilities a developer is expected to use from the given repository.");
|
|
403
|
-
const planFeatureSchema = zod.z
|
|
404
|
-
.object({
|
|
405
|
-
feature: zod.z
|
|
406
|
-
.string()
|
|
407
|
-
.min(5, "feature must describe the goal clearly")
|
|
408
|
-
.describe("Natural-language description of a developer's requested feature or task to implement using the repository and available MCP tools."),
|
|
409
|
-
repoPath: zod.z
|
|
410
|
-
.string()
|
|
411
|
-
.default("./decoration")
|
|
412
|
-
.describe("Target repository path providing the library to use, e.g. './decoration'."),
|
|
413
|
-
})
|
|
414
|
-
.strict()
|
|
415
|
-
.describe("Plan which MCP tools to use and in what sequence to implement a requested feature using the repository.");
|
|
416
|
-
const documentCodeSchema = zod.z
|
|
417
|
-
.object({
|
|
418
|
-
filePath: zod.z.string().min(1, "filePath is required"),
|
|
419
|
-
promptName: zod.z.string().optional(),
|
|
420
|
-
includePrompt: zod.z.boolean().default(true),
|
|
421
|
-
includeCode: zod.z.boolean().default(true),
|
|
422
|
-
includeMetadata: zod.z.boolean().default(true),
|
|
423
|
-
additionalContext: zod.z.string().optional(),
|
|
424
|
-
encoding: zod.z.string().default("utf8"),
|
|
425
|
-
})
|
|
426
|
-
.strict();
|
|
427
|
-
const codeChangeSchema = zod.z
|
|
428
|
-
.object({
|
|
429
|
-
filePath: zod.z.string().min(1, "filePath is required"),
|
|
430
|
-
patch: zod.z.string().min(1, "patch is required"),
|
|
431
|
-
dryRun: zod.z.boolean().default(false),
|
|
432
|
-
showDiff: zod.z.boolean().default(true),
|
|
433
|
-
diffContext: zod.z.number().int().min(0).max(100).default(3),
|
|
434
|
-
encoding: zod.z.string().default("utf8"),
|
|
435
|
-
})
|
|
436
|
-
.strict();
|
|
437
|
-
const OBJECT_TYPES = [
|
|
438
|
-
"module",
|
|
439
|
-
"file",
|
|
440
|
-
"class",
|
|
441
|
-
"function",
|
|
442
|
-
"interface",
|
|
443
|
-
"decorator",
|
|
444
|
-
"constant",
|
|
445
|
-
];
|
|
446
|
-
const documentObjectSchema = zod.z
|
|
447
|
-
.object({
|
|
448
|
-
basePath: zod.z.string().min(1, "basePath is required"),
|
|
449
|
-
objectType: zod.z.enum(OBJECT_TYPES),
|
|
450
|
-
targetFile: zod.z.string().optional(),
|
|
451
|
-
includeContent: zod.z.boolean().default(false),
|
|
452
|
-
})
|
|
453
|
-
.strict();
|
|
454
|
-
const coverageTaskSchema = zod.z
|
|
455
|
-
.object({
|
|
456
|
-
basePath: zod.z.string().min(1, "basePath is required"),
|
|
457
|
-
coverage: zod.z
|
|
458
|
-
.number()
|
|
459
|
-
.min(0)
|
|
460
|
-
.max(100)
|
|
461
|
-
.default(90)
|
|
462
|
-
.describe("Target coverage percentage"),
|
|
463
|
-
dryRun: zod.z.boolean().default(false),
|
|
464
|
-
})
|
|
465
|
-
.strict();
|
|
466
|
-
const readmeImprovementSchema = zod.z
|
|
467
|
-
.object({
|
|
468
|
-
basePath: zod.z.string().min(1, "basePath is required"),
|
|
469
|
-
includeExamples: zod.z.boolean().default(true),
|
|
470
|
-
})
|
|
471
|
-
.strict();
|
|
472
|
-
|
|
473
|
-
function readFileSafe(filePath, encoding = "utf8") {
|
|
474
|
-
try {
|
|
475
|
-
return fs.readFileSync(filePath, { encoding });
|
|
476
|
-
}
|
|
477
|
-
catch {
|
|
478
|
-
return undefined;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
function listFilesRecursive(root, matcher) {
|
|
482
|
-
const out = [];
|
|
483
|
-
const stack = [root];
|
|
484
|
-
while (stack.length) {
|
|
485
|
-
const cur = stack.pop();
|
|
486
|
-
const stat = fs.statSync(cur);
|
|
487
|
-
if (stat.isDirectory()) {
|
|
488
|
-
for (const f of fs.readdirSync(cur))
|
|
489
|
-
stack.push(path.join(cur, f));
|
|
490
|
-
}
|
|
491
|
-
else if (!matcher || matcher(cur)) {
|
|
492
|
-
out.push(cur);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
return out.sort();
|
|
496
|
-
}
|
|
497
|
-
function deriveCapabilities(analysis) {
|
|
498
|
-
const cap = new Set();
|
|
499
|
-
// heuristics: if decorators like Decoration, flavouredAs, extend, override appear, add capabilities
|
|
500
|
-
const allDecs = new Set();
|
|
501
|
-
for (const k of Object.keys(analysis.api)) {
|
|
502
|
-
for (const d of analysis.api[k].decorators)
|
|
503
|
-
allDecs.add(d);
|
|
504
|
-
for (const e of analysis.api[k].exports)
|
|
505
|
-
if (/Decoration|decorate|Builder|Flavour/i.test(e))
|
|
506
|
-
cap.add("use-decoration-api");
|
|
507
|
-
}
|
|
508
|
-
if ([...allDecs].some((d) => /override|extend/i.test(d)))
|
|
509
|
-
cap.add("override-and-extend-decorations");
|
|
510
|
-
if (Object.keys(analysis.tests).length > 0)
|
|
511
|
-
cap.add("validate-with-tests");
|
|
512
|
-
if (analysis.readme)
|
|
513
|
-
cap.add("follow-readme-guides");
|
|
514
|
-
return [...cap].sort();
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Analysis helpers (minimal yet effective, text-based to avoid heavy AST deps)
|
|
518
|
-
function isSourceFile(p) {
|
|
519
|
-
return /\.(ts|tsx|js|jsx)$/.test(p) && !p.endsWith(".d.ts");
|
|
520
|
-
}
|
|
521
|
-
function isTestFile(p) {
|
|
522
|
-
return /(\.test\.|\.spec\.)/.test(p);
|
|
523
|
-
}
|
|
524
|
-
function extractExports(fileContent) {
|
|
525
|
-
const names = new Set();
|
|
526
|
-
const exportRe = /(export\s+(?:default\s+)?(?:class|function|const|let|var|interface|type|enum)\s+)([A-Za-z0-9_]+)/g;
|
|
527
|
-
const namedRe = /export\s*\{([^}]+)\}/g;
|
|
528
|
-
let m;
|
|
529
|
-
while ((m = exportRe.exec(fileContent)))
|
|
530
|
-
names.add(m[2]);
|
|
531
|
-
while ((m = namedRe.exec(fileContent))) {
|
|
532
|
-
m[1]
|
|
533
|
-
.split(",")
|
|
534
|
-
.map((s) => s.trim().split(" as ")[0].trim())
|
|
535
|
-
.forEach((n) => {
|
|
536
|
-
if (n)
|
|
537
|
-
names.add(n);
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
return [...names].sort();
|
|
541
|
-
}
|
|
542
|
-
function extractDecorators(fileContent) {
|
|
543
|
-
const decs = new Set();
|
|
544
|
-
const decRe = /@([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
545
|
-
let m;
|
|
546
|
-
while ((m = decRe.exec(fileContent)))
|
|
547
|
-
decs.add(m[1]);
|
|
548
|
-
return [...decs].sort();
|
|
549
|
-
}
|
|
550
|
-
function summarizeReadme(readme) {
|
|
551
|
-
if (!readme)
|
|
552
|
-
return undefined;
|
|
553
|
-
const lines = readme.split(/\r?\n/).filter(Boolean);
|
|
554
|
-
const title = lines.find((l) => /^#\s+/.test(l))?.replace(/^#\s+/, "") || "README";
|
|
555
|
-
const bullets = lines.filter((l) => /^[-*]\s+/.test(l)).slice(0, 20);
|
|
556
|
-
return { title, bullets };
|
|
557
|
-
}
|
|
558
|
-
function analyzeRepo(root) {
|
|
559
|
-
const src = path.join(root, "src");
|
|
560
|
-
const testDir = path.join(root, "tests");
|
|
561
|
-
const readmePath = path.join(root, "README.md");
|
|
562
|
-
const readme = readFileSafe(readmePath);
|
|
563
|
-
const files = fs.existsSync(src) ? listFilesRecursive(src, isSourceFile) : [];
|
|
564
|
-
const testFiles = fs.existsSync(testDir)
|
|
565
|
-
? listFilesRecursive(testDir, (f) => isSourceFile(f) && isTestFile(f))
|
|
566
|
-
: [];
|
|
567
|
-
const api = {};
|
|
568
|
-
for (const f of files) {
|
|
569
|
-
const content = readFileSafe(f) || "";
|
|
570
|
-
api[path.relative(root, f)] = {
|
|
571
|
-
exports: extractExports(content),
|
|
572
|
-
decorators: extractDecorators(content),
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
const tests = {};
|
|
576
|
-
for (const f of testFiles) {
|
|
577
|
-
const content = readFileSafe(f) || "";
|
|
578
|
-
const mentions = Array.from(new Set([...extractExports(content), ...extractDecorators(content)])).sort();
|
|
579
|
-
tests[path.relative(root, f)] = { mentions };
|
|
580
|
-
}
|
|
581
|
-
return { files, testFiles, api, tests, readme: summarizeReadme(readme) };
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
function relativeFiles(root, files) {
|
|
585
|
-
return files.map((file) => path.relative(root, file)).sort();
|
|
586
|
-
}
|
|
587
|
-
function collectPromptSections(names) {
|
|
588
|
-
const root = getWorkspaceRoot();
|
|
589
|
-
const promptIndex = new Map(discoverDocPrompts(root).map((prompt) => [prompt.name, prompt]));
|
|
590
|
-
return names
|
|
591
|
-
.map((name) => promptIndex.get(name))
|
|
592
|
-
.filter((prompt) => Boolean(prompt))
|
|
593
|
-
.map((prompt) => ({
|
|
594
|
-
name: prompt.name,
|
|
595
|
-
title: prompt.title,
|
|
596
|
-
description: prompt.description,
|
|
597
|
-
content: prompt.content,
|
|
598
|
-
absolutePath: prompt.absolutePath,
|
|
599
|
-
}));
|
|
600
|
-
}
|
|
601
|
-
function parseTaskLines(content) {
|
|
602
|
-
return content
|
|
603
|
-
.split(/\r?\n/)
|
|
604
|
-
.map((line) => line.trim())
|
|
605
|
-
.filter((line) => /^task\s+\d+/i.test(line));
|
|
606
|
-
}
|
|
607
|
-
function computeCoverageFromFinal(coveragePath) {
|
|
608
|
-
const payload = JSON.parse(fs.readFileSync(coveragePath, "utf8"));
|
|
609
|
-
const totals = {
|
|
610
|
-
statements: { covered: 0, total: 0 },
|
|
611
|
-
functions: { covered: 0, total: 0 },
|
|
612
|
-
branches: { covered: 0, total: 0 },
|
|
613
|
-
};
|
|
614
|
-
const files = Object.entries(payload).map(([filePath, info]) => {
|
|
615
|
-
const statementCounts = Object.values(info.s);
|
|
616
|
-
const functionCounts = Object.values(info.f);
|
|
617
|
-
const branchCounts = Object.values(info.b).flatMap((value) => Array.isArray(value) ? value : [value]);
|
|
618
|
-
const statementTotal = statementCounts.length;
|
|
619
|
-
const functionTotal = functionCounts.length;
|
|
620
|
-
const branchTotal = branchCounts.length;
|
|
621
|
-
const statementCovered = statementCounts.filter((count) => count > 0).length;
|
|
622
|
-
const functionCovered = functionCounts.filter((count) => count > 0).length;
|
|
623
|
-
const branchCovered = branchCounts.filter((count) => count > 0).length;
|
|
624
|
-
totals.statements.covered += statementCovered;
|
|
625
|
-
totals.statements.total += statementTotal;
|
|
626
|
-
totals.functions.covered += functionCovered;
|
|
627
|
-
totals.functions.total += functionTotal;
|
|
628
|
-
totals.branches.covered += branchCovered;
|
|
629
|
-
totals.branches.total += branchTotal;
|
|
630
|
-
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
631
|
-
return {
|
|
632
|
-
path: filePath,
|
|
633
|
-
statements: pct(statementCovered, statementTotal),
|
|
634
|
-
functions: pct(functionCovered, functionTotal),
|
|
635
|
-
branches: pct(branchCovered, branchTotal),
|
|
636
|
-
};
|
|
637
|
-
});
|
|
638
|
-
const pct = (covered, total) => total === 0 ? 100 : Number(((covered / total) * 100).toFixed(2));
|
|
639
|
-
return {
|
|
640
|
-
totals: {
|
|
641
|
-
statements: {
|
|
642
|
-
...totals.statements,
|
|
643
|
-
pct: pct(totals.statements.covered, totals.statements.total),
|
|
644
|
-
},
|
|
645
|
-
functions: {
|
|
646
|
-
...totals.functions,
|
|
647
|
-
pct: pct(totals.functions.covered, totals.functions.total),
|
|
648
|
-
},
|
|
649
|
-
branches: {
|
|
650
|
-
...totals.branches,
|
|
651
|
-
pct: pct(totals.branches.covered, totals.branches.total),
|
|
652
|
-
},
|
|
653
|
-
},
|
|
654
|
-
files,
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
function normalizePromptSections(sections) {
|
|
658
|
-
return sections.map((section) => ({
|
|
659
|
-
name: section.name,
|
|
660
|
-
title: section.title,
|
|
661
|
-
tasks: parseTaskLines(section.content),
|
|
662
|
-
content: section.content,
|
|
663
|
-
}));
|
|
664
|
-
}
|
|
665
|
-
async function resolveRepoRoot(basePath) {
|
|
666
|
-
const root = getWorkspaceRoot();
|
|
667
|
-
try {
|
|
668
|
-
return resolveInWorkspace(root, basePath);
|
|
669
|
-
}
|
|
670
|
-
catch (error) {
|
|
671
|
-
if (error instanceof WorkspaceError) {
|
|
672
|
-
await throwUserError(error.message);
|
|
673
|
-
}
|
|
674
|
-
throw error;
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
const documentObjectTool = {
|
|
678
|
-
name: "document-object",
|
|
679
|
-
description: "Create a documentation plan for a specific object type using .codex prompts and repository analysis.",
|
|
680
|
-
parameters: documentObjectSchema,
|
|
681
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
682
|
-
execute: async (input, _context) => {
|
|
683
|
-
const args = documentObjectSchema.parse(input);
|
|
684
|
-
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
685
|
-
const dependencies = getObjectPromptDependencies()[args.objectType] ?? [];
|
|
686
|
-
if (!dependencies.length) {
|
|
687
|
-
await throwUserError(`No prompt guidance configured for object type ${args.objectType}`);
|
|
688
|
-
}
|
|
689
|
-
const sections = normalizePromptSections(collectPromptSections(dependencies));
|
|
690
|
-
const srcDir = path.join(repoRoot, "src");
|
|
691
|
-
const testDir = path.join(repoRoot, "tests");
|
|
692
|
-
const sourceFiles = fs.existsSync(srcDir)
|
|
693
|
-
? listFilesRecursive(srcDir, isSourceFile)
|
|
694
|
-
: [];
|
|
695
|
-
const testFiles = fs.existsSync(testDir)
|
|
696
|
-
? listFilesRecursive(testDir, (file) => isSourceFile(file) && isTestFile(file))
|
|
697
|
-
: [];
|
|
698
|
-
let targetFileContent;
|
|
699
|
-
if (args.targetFile) {
|
|
700
|
-
try {
|
|
701
|
-
const absolute = resolveInWorkspace(repoRoot, args.targetFile);
|
|
702
|
-
targetFileContent = readFileSafe(absolute) ?? undefined;
|
|
703
|
-
}
|
|
704
|
-
catch (error) {
|
|
705
|
-
if (error instanceof WorkspaceError) {
|
|
706
|
-
await throwUserError(error.message);
|
|
707
|
-
}
|
|
708
|
-
throw error;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
const payload = {
|
|
712
|
-
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
713
|
-
objectType: args.objectType,
|
|
714
|
-
targetFile: args.targetFile,
|
|
715
|
-
guidance: sections,
|
|
716
|
-
files: {
|
|
717
|
-
source: relativeFiles(repoRoot, sourceFiles),
|
|
718
|
-
tests: relativeFiles(repoRoot, testFiles),
|
|
719
|
-
},
|
|
720
|
-
targetFileContent: args.includeContent ? targetFileContent : undefined,
|
|
721
|
-
};
|
|
722
|
-
return {
|
|
723
|
-
content: [
|
|
724
|
-
{
|
|
725
|
-
type: "text",
|
|
726
|
-
text: JSON.stringify(payload, null, 2),
|
|
727
|
-
},
|
|
728
|
-
],
|
|
729
|
-
};
|
|
730
|
-
},
|
|
731
|
-
};
|
|
732
|
-
const coverageEnforcerTool = {
|
|
733
|
-
name: "ensure-test-coverage",
|
|
734
|
-
description: "Run the configured coverage command and report whether the target percentage is met, highlighting weak files.",
|
|
735
|
-
parameters: coverageTaskSchema,
|
|
736
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
737
|
-
execute: async (input, _context) => {
|
|
738
|
-
const args = coverageTaskSchema.parse(input);
|
|
739
|
-
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
740
|
-
if (!args.dryRun) {
|
|
741
|
-
const env = {
|
|
742
|
-
...process.env,
|
|
743
|
-
USE_WATCHMAN: "false",
|
|
744
|
-
WATCHMAN_DISABLE: "1",
|
|
745
|
-
JEST_DISABLE_WATCHMAN: "1",
|
|
746
|
-
};
|
|
747
|
-
const result = child_process.spawnSync("npm", ["run", "coverage", "--", "--watchman=false", "--runInBand"], { cwd: repoRoot, env, encoding: "utf8" });
|
|
748
|
-
if (result.status !== 0) {
|
|
749
|
-
const message = result.stderr || result.stdout || "Coverage command failed";
|
|
750
|
-
await throwUserError(message.trim());
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
const coveragePath = path.join(repoRoot, "workdocs", "reports", "coverage", "coverage-final.json");
|
|
754
|
-
if (!fs.existsSync(coveragePath)) {
|
|
755
|
-
await throwUserError(`Coverage report not found at ${path.relative(repoRoot, coveragePath)}`);
|
|
756
|
-
}
|
|
757
|
-
const summary = computeCoverageFromFinal(coveragePath);
|
|
758
|
-
const meetsThreshold = summary.totals.statements.pct >= args.coverage &&
|
|
759
|
-
summary.totals.functions.pct >= args.coverage &&
|
|
760
|
-
summary.totals.branches.pct >= args.coverage;
|
|
761
|
-
const weakest = [...summary.files]
|
|
762
|
-
.sort((a, b) => a.statements - b.statements)
|
|
763
|
-
.slice(0, 10);
|
|
764
|
-
const guidance = normalizePromptSections(collectPromptSections(["bulk-tests"]));
|
|
765
|
-
const payload = {
|
|
766
|
-
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
767
|
-
target: args.coverage,
|
|
768
|
-
meetsThreshold,
|
|
769
|
-
totals: summary.totals,
|
|
770
|
-
weakest,
|
|
771
|
-
guidance,
|
|
772
|
-
};
|
|
773
|
-
return {
|
|
774
|
-
content: [
|
|
775
|
-
{
|
|
776
|
-
type: "text",
|
|
777
|
-
text: JSON.stringify(payload, null, 2),
|
|
778
|
-
},
|
|
779
|
-
],
|
|
780
|
-
};
|
|
781
|
-
},
|
|
782
|
-
};
|
|
783
|
-
const readmeImprovementTool = {
|
|
784
|
-
name: "improve-readme",
|
|
785
|
-
description: "Summarize required steps to refresh README and workdocs content using .codex guidance and repository analysis.",
|
|
786
|
-
parameters: readmeImprovementSchema,
|
|
787
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
788
|
-
execute: async (input, _context) => {
|
|
789
|
-
const args = readmeImprovementSchema.parse(input);
|
|
790
|
-
const repoRoot = await resolveRepoRoot(args.basePath);
|
|
791
|
-
const analysis = analyzeRepo(repoRoot);
|
|
792
|
-
const modules = analysis.files
|
|
793
|
-
.filter((file) => /index\.ts$/.test(file))
|
|
794
|
-
.map((file) => path.relative(repoRoot, file));
|
|
795
|
-
const promptSections = normalizePromptSections(collectPromptSections(["update-readme", "doc", "module"]));
|
|
796
|
-
const testExamples = Object.keys(analysis.tests ?? {});
|
|
797
|
-
const examples = args.includeExamples ? testExamples.slice(0, 20) : [];
|
|
798
|
-
const payload = {
|
|
799
|
-
basePath: path.relative(getWorkspaceRoot(), repoRoot) || ".",
|
|
800
|
-
summary: {
|
|
801
|
-
modules,
|
|
802
|
-
totalSourceFiles: analysis.files.length,
|
|
803
|
-
totalTestFiles: analysis.testFiles.length,
|
|
804
|
-
hasReadme: Boolean(analysis.readme),
|
|
805
|
-
},
|
|
806
|
-
guidance: promptSections,
|
|
807
|
-
suggestedExamples: examples,
|
|
808
|
-
};
|
|
809
|
-
return {
|
|
810
|
-
content: [
|
|
811
|
-
{
|
|
812
|
-
type: "text",
|
|
813
|
-
text: JSON.stringify(payload, null, 2),
|
|
814
|
-
},
|
|
815
|
-
],
|
|
816
|
-
};
|
|
817
|
-
},
|
|
818
|
-
};
|
|
819
|
-
|
|
820
|
-
function escapeRegExp(value) {
|
|
821
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
822
|
-
}
|
|
823
|
-
function formatDecorator(spec) {
|
|
824
|
-
const args = (spec.args || []).map((arg) => JSON.stringify(arg)).join(", ");
|
|
825
|
-
return `@${spec.name}(${args})`;
|
|
826
|
-
}
|
|
827
|
-
function ensureDirectory(filePath) {
|
|
828
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
829
|
-
}
|
|
830
|
-
function collectDecoratorNames(classDecorators, properties) {
|
|
831
|
-
const names = new Set();
|
|
832
|
-
names.add("model");
|
|
833
|
-
for (const decorator of classDecorators || []) {
|
|
834
|
-
names.add(decorator.name);
|
|
835
|
-
}
|
|
836
|
-
for (const property of properties || []) {
|
|
837
|
-
for (const decorator of property.decorators || []) {
|
|
838
|
-
names.add(decorator.name);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
return names;
|
|
842
|
-
}
|
|
843
|
-
function ensureImport(content, importsFrom, decorators) {
|
|
844
|
-
/* istanbul ignore next */
|
|
845
|
-
if (!decorators.size)
|
|
846
|
-
return content;
|
|
847
|
-
const importRegex = new RegExp(`import\\s+\\{([^}]+)\\}\\s+from\\s+["']${escapeRegExp(importsFrom)}["'];`);
|
|
848
|
-
const match = content.match(importRegex);
|
|
849
|
-
const sorted = Array.from(decorators).sort();
|
|
850
|
-
if (match) {
|
|
851
|
-
const existing = match[1]
|
|
852
|
-
.split(",")
|
|
853
|
-
.map((name) => name.trim())
|
|
854
|
-
.filter(Boolean);
|
|
855
|
-
const merged = Array.from(new Set([...existing, ...sorted])).sort();
|
|
856
|
-
return content.replace(importRegex, `import { ${merged.join(", ")} } from "${importsFrom}";`);
|
|
857
|
-
}
|
|
858
|
-
const importLine = `import { ${sorted.join(", ")} } from "${importsFrom}";`;
|
|
859
|
-
return `${importLine}\n\n${content}`;
|
|
860
|
-
}
|
|
861
|
-
function addPropertyBlock(property) {
|
|
862
|
-
const decorators = (property.decorators || [])
|
|
863
|
-
.map(formatDecorator)
|
|
864
|
-
.join("\n ");
|
|
865
|
-
const decoratorBlock = decorators ? ` ${decorators}\n` : "";
|
|
866
|
-
return `${decoratorBlock} ${property.name}: ${property.type};`;
|
|
867
|
-
}
|
|
868
|
-
function removePropertyBlock(content, propertyName) {
|
|
869
|
-
const lines = content.split(/\r?\n/);
|
|
870
|
-
const result = [];
|
|
871
|
-
for (let i = 0; i < lines.length; i++) {
|
|
872
|
-
const line = lines[i];
|
|
873
|
-
if (line.trim().startsWith(`@`) &&
|
|
874
|
-
lines[i + 1]?.includes(`${propertyName}:`)) {
|
|
875
|
-
continue;
|
|
876
|
-
}
|
|
877
|
-
if (line.includes(`${propertyName}:`)) {
|
|
878
|
-
// skip this line and any trailing blank line
|
|
879
|
-
continue;
|
|
880
|
-
}
|
|
881
|
-
result.push(line);
|
|
882
|
-
}
|
|
883
|
-
return result.join("\n");
|
|
884
|
-
}
|
|
885
|
-
function insertDecorator(content, decorator, target) {
|
|
886
|
-
const decoratorLine = formatDecorator(decorator);
|
|
887
|
-
if (target.kind === "class") {
|
|
888
|
-
const classRegex = /(export\s+class\s+[^\s{]+\s*\{)/;
|
|
889
|
-
if (content.includes(decoratorLine))
|
|
890
|
-
return content;
|
|
891
|
-
return content.replace(classRegex, `${decoratorLine}\n$1`);
|
|
892
|
-
}
|
|
893
|
-
if (!target.name)
|
|
894
|
-
return content;
|
|
895
|
-
const propertyRegex = new RegExp(`(^\\s*)(?:@.*\\n\\1)*${escapeRegExp(target.name)}:`, "m");
|
|
896
|
-
const match = propertyRegex.exec(content);
|
|
897
|
-
if (!match)
|
|
898
|
-
return content;
|
|
899
|
-
const indent = match[1] || " ";
|
|
900
|
-
if (content.includes(`${indent}${decoratorLine}`))
|
|
901
|
-
return content;
|
|
902
|
-
return (content.slice(0, match.index) +
|
|
903
|
-
`${indent}${decoratorLine}\n` +
|
|
904
|
-
content.slice(match.index));
|
|
905
|
-
}
|
|
906
|
-
function removeDecorator(content, decoratorName, target) {
|
|
907
|
-
const decoratorRegex = new RegExp(`^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)`, "m");
|
|
908
|
-
if (target.kind === "class") {
|
|
909
|
-
return content.replace(decoratorRegex, "");
|
|
910
|
-
}
|
|
911
|
-
if (target.name) {
|
|
912
|
-
const pattern = new RegExp(`(^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)\\s*$\\n)(?=\\s*${escapeRegExp(target.name)}:)`, "m");
|
|
913
|
-
return content.replace(pattern, "");
|
|
914
|
-
}
|
|
915
|
-
return content;
|
|
916
|
-
}
|
|
917
|
-
function writeIfChanged(filePath, content) {
|
|
918
|
-
ensureDirectory(filePath);
|
|
919
|
-
fs.writeFileSync(filePath, content);
|
|
920
|
-
}
|
|
921
|
-
const decoratorTools = {
|
|
922
|
-
createOrUpdateModelTool: {
|
|
923
|
-
name: "create-or-update-model",
|
|
924
|
-
description: "Create or update a validation-ready model class",
|
|
925
|
-
execute: async (args) => {
|
|
926
|
-
if (!args.overwrite && fs.existsSync(args.filePath)) {
|
|
927
|
-
throw new Error(`File already exists at ${args.filePath}`);
|
|
928
|
-
}
|
|
929
|
-
const decorators = collectDecoratorNames(args.classDecorators, args.properties);
|
|
930
|
-
let content = `@model()`;
|
|
931
|
-
for (const decorator of args.classDecorators || []) {
|
|
932
|
-
content += `\n${formatDecorator(decorator)}`;
|
|
933
|
-
}
|
|
934
|
-
const properties = (args.properties || [])
|
|
935
|
-
.map(addPropertyBlock)
|
|
936
|
-
.join("\n\n");
|
|
937
|
-
content += `\nexport class ${args.className} {\n${properties ? `${properties}\n` : ""}}\n`;
|
|
938
|
-
content = ensureImport(content, args.importsFrom, decorators);
|
|
939
|
-
writeIfChanged(args.filePath, content);
|
|
940
|
-
return { filePath: args.filePath };
|
|
941
|
-
},
|
|
942
|
-
},
|
|
943
|
-
addAttributeTool: {
|
|
944
|
-
name: "add-attribute",
|
|
945
|
-
description: "Add a decorated attribute to an existing model",
|
|
946
|
-
execute: async (args) => {
|
|
947
|
-
if (!fs.existsSync(args.filePath)) {
|
|
948
|
-
throw new Error(`Model file not found at ${args.filePath}`);
|
|
949
|
-
}
|
|
950
|
-
let content = fs.readFileSync(args.filePath, "utf8");
|
|
951
|
-
if (content.includes(`${args.attribute.name}:`)) {
|
|
952
|
-
return { filePath: args.filePath };
|
|
953
|
-
}
|
|
954
|
-
const decorators = collectDecoratorNames(undefined, [args.attribute]);
|
|
955
|
-
content = ensureImport(content, args.importsFrom, decorators);
|
|
956
|
-
const insertionPoint = content.lastIndexOf("}");
|
|
957
|
-
const block = addPropertyBlock(args.attribute);
|
|
958
|
-
const before = content.slice(0, insertionPoint).replace(/\s*$/, "");
|
|
959
|
-
const after = content.slice(insertionPoint);
|
|
960
|
-
const updated = `${before}\n${block}\n${after}`;
|
|
961
|
-
writeIfChanged(args.filePath, updated);
|
|
962
|
-
return { filePath: args.filePath };
|
|
963
|
-
},
|
|
964
|
-
},
|
|
965
|
-
removeAttributeTool: {
|
|
966
|
-
name: "remove-attribute",
|
|
967
|
-
description: "Remove an attribute from a model class",
|
|
968
|
-
execute: async (args) => {
|
|
969
|
-
if (!fs.existsSync(args.filePath))
|
|
970
|
-
return { filePath: args.filePath };
|
|
971
|
-
const content = fs.readFileSync(args.filePath, "utf8");
|
|
972
|
-
const updated = removePropertyBlock(content, args.attributeName);
|
|
973
|
-
writeIfChanged(args.filePath, updated);
|
|
974
|
-
return { filePath: args.filePath };
|
|
975
|
-
},
|
|
976
|
-
},
|
|
977
|
-
applyDecoratorTool: {
|
|
978
|
-
name: "apply-decorator",
|
|
979
|
-
description: "Apply a decorator to a class or property",
|
|
980
|
-
execute: async (args) => {
|
|
981
|
-
if (!fs.existsSync(args.filePath)) {
|
|
982
|
-
throw new Error(`Model file not found at ${args.filePath}`);
|
|
983
|
-
}
|
|
984
|
-
let content = fs.readFileSync(args.filePath, "utf8");
|
|
985
|
-
const decorators = new Set([args.decorator.name]);
|
|
986
|
-
content = ensureImport(content, args.importsFrom, decorators);
|
|
987
|
-
content = insertDecorator(content, args.decorator, args.target);
|
|
988
|
-
writeIfChanged(args.filePath, content);
|
|
989
|
-
return { filePath: args.filePath };
|
|
990
|
-
},
|
|
991
|
-
},
|
|
992
|
-
removeDecoratorTool: {
|
|
993
|
-
name: "remove-decorator",
|
|
994
|
-
description: "Remove a decorator from a class or property",
|
|
995
|
-
execute: async (args) => {
|
|
996
|
-
if (!fs.existsSync(args.filePath))
|
|
997
|
-
return { filePath: args.filePath };
|
|
998
|
-
let content = fs.readFileSync(args.filePath, "utf8");
|
|
999
|
-
content = removeDecorator(content, args.decoratorName, args.target);
|
|
1000
|
-
writeIfChanged(args.filePath, content);
|
|
1001
|
-
return { filePath: args.filePath };
|
|
1002
|
-
},
|
|
1003
|
-
},
|
|
1004
|
-
scaffoldValidatorTool: {
|
|
1005
|
-
name: "scaffold-validator",
|
|
1006
|
-
description: "Scaffold a validator class and optional decorator",
|
|
1007
|
-
execute: async (args) => {
|
|
1008
|
-
const classFile = path.join(args.validatorsDir, `${args.name}.ts`);
|
|
1009
|
-
ensureDirectory(classFile);
|
|
1010
|
-
const classContent = `export class ${args.name} {\n validate(value: unknown): boolean {\n return value !== undefined;\n }\n}\n`;
|
|
1011
|
-
fs.writeFileSync(classFile, classContent);
|
|
1012
|
-
let decoratorFile;
|
|
1013
|
-
if (args.decoratorDir) {
|
|
1014
|
-
decoratorFile = path.join(args.decoratorDir, `${args.name}Decorator.ts`);
|
|
1015
|
-
ensureDirectory(decoratorFile);
|
|
1016
|
-
fs.writeFileSync(decoratorFile, `export function ${args.name}Decorator() {\n return () => void 0;\n}\n`);
|
|
1017
|
-
}
|
|
1018
|
-
return { classFile, decoratorFile };
|
|
1019
|
-
},
|
|
1020
|
-
},
|
|
1021
|
-
scaffoldSerializerTool: {
|
|
1022
|
-
name: "scaffold-serializer",
|
|
1023
|
-
description: "Scaffold a serializer class and optional registry",
|
|
1024
|
-
execute: async (args) => {
|
|
1025
|
-
const classFile = path.join(args.dir, `${args.name}.ts`);
|
|
1026
|
-
ensureDirectory(classFile);
|
|
1027
|
-
fs.writeFileSync(classFile, `export class ${args.name} {\n serialize(value: unknown): string {\n return JSON.stringify(value);\n }\n}\n`);
|
|
1028
|
-
let registerFile;
|
|
1029
|
-
if (args.registerDir) {
|
|
1030
|
-
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
1031
|
-
ensureDirectory(registerFile);
|
|
1032
|
-
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
1033
|
-
}
|
|
1034
|
-
return { classFile, registerFile };
|
|
1035
|
-
},
|
|
1036
|
-
},
|
|
1037
|
-
scaffoldHashingTool: {
|
|
1038
|
-
name: "scaffold-hashing",
|
|
1039
|
-
description: "Scaffold a hashing function and optional registry",
|
|
1040
|
-
execute: async (args) => {
|
|
1041
|
-
const functionFile = path.join(args.dir, `${args.name}.ts`);
|
|
1042
|
-
ensureDirectory(functionFile);
|
|
1043
|
-
fs.writeFileSync(functionFile, `export function ${args.name}(value: string): string {\n return value.split('').reverse().join('');\n}\n`);
|
|
1044
|
-
let registerFile;
|
|
1045
|
-
if (args.registerDir) {
|
|
1046
|
-
registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
|
|
1047
|
-
ensureDirectory(registerFile);
|
|
1048
|
-
fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
|
|
1049
|
-
}
|
|
1050
|
-
return { functionFile, registerFile };
|
|
1051
|
-
},
|
|
1052
|
-
},
|
|
1053
|
-
};
|
|
1054
|
-
|
|
1055
|
-
function buildAnalyzeRepositoryTool() {
|
|
1056
|
-
return {
|
|
1057
|
-
name: "analyze-repository",
|
|
1058
|
-
description: "Analyze a local repository's source, tests, and docs to extract exported APIs, decorators, and test mentions.",
|
|
1059
|
-
parameters: analyzeRepoSchema,
|
|
1060
|
-
execute: async (input) => {
|
|
1061
|
-
let repoRoot = path.resolve(process.cwd(), input.repoPath);
|
|
1062
|
-
if (!fs.existsSync(repoRoot)) {
|
|
1063
|
-
// try resolving from monorepo root (parent of current cwd)
|
|
1064
|
-
const alt = path.resolve(process.cwd(), "..", input.repoPath);
|
|
1065
|
-
if (fs.existsSync(alt))
|
|
1066
|
-
repoRoot = alt;
|
|
1067
|
-
}
|
|
1068
|
-
if (!fs.existsSync(repoRoot)) {
|
|
1069
|
-
// if input was absolute and still not found, try ../<basename>
|
|
1070
|
-
const alt2 = path.resolve(process.cwd(), "..", path.basename(input.repoPath));
|
|
1071
|
-
if (fs.existsSync(alt2))
|
|
1072
|
-
repoRoot = alt2;
|
|
1073
|
-
}
|
|
1074
|
-
if (!fs.existsSync(repoRoot))
|
|
1075
|
-
throw new Error(`Repository not found at ${repoRoot}`);
|
|
1076
|
-
const result = analyzeRepo(repoRoot);
|
|
1077
|
-
return {
|
|
1078
|
-
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1079
|
-
};
|
|
1080
|
-
},
|
|
1081
|
-
};
|
|
1082
|
-
}
|
|
1083
|
-
function buildEnumerateCapabilitiesTool() {
|
|
1084
|
-
return {
|
|
1085
|
-
name: "enumerate-capabilities",
|
|
1086
|
-
description: "Enumerate developer-facing capabilities of the given repository, inferred from code, tests, and docs.",
|
|
1087
|
-
parameters: enumerateCapabilitiesSchema,
|
|
1088
|
-
execute: async (input) => {
|
|
1089
|
-
let repoRoot = path.resolve(process.cwd(), input.repoPath);
|
|
1090
|
-
if (!fs.existsSync(repoRoot)) {
|
|
1091
|
-
const alt = path.resolve(process.cwd(), "..", input.repoPath);
|
|
1092
|
-
if (fs.existsSync(alt))
|
|
1093
|
-
repoRoot = alt;
|
|
1094
|
-
}
|
|
1095
|
-
if (!fs.existsSync(repoRoot)) {
|
|
1096
|
-
const alt2 = path.resolve(process.cwd(), "..", path.basename(input.repoPath));
|
|
1097
|
-
if (fs.existsSync(alt2))
|
|
1098
|
-
repoRoot = alt2;
|
|
1099
|
-
}
|
|
1100
|
-
if (!fs.existsSync(repoRoot))
|
|
1101
|
-
throw new Error(`Repository not found at ${repoRoot}`);
|
|
1102
|
-
const analysis = analyzeRepo(repoRoot);
|
|
1103
|
-
const capabilities = deriveCapabilities(analysis);
|
|
1104
|
-
return {
|
|
1105
|
-
content: [
|
|
1106
|
-
{
|
|
1107
|
-
type: "text",
|
|
1108
|
-
text: JSON.stringify({
|
|
1109
|
-
capabilities,
|
|
1110
|
-
analysisSummary: {
|
|
1111
|
-
files: analysis.files.length,
|
|
1112
|
-
testFiles: analysis.testFiles.length,
|
|
1113
|
-
readme: analysis.readme?.title,
|
|
1114
|
-
},
|
|
1115
|
-
}, null, 2),
|
|
1116
|
-
},
|
|
1117
|
-
],
|
|
1118
|
-
};
|
|
1119
|
-
},
|
|
1120
|
-
};
|
|
1121
|
-
}
|
|
1122
|
-
function buildPlanFeatureTool() {
|
|
1123
|
-
return {
|
|
1124
|
-
name: "plan-feature-implementation",
|
|
1125
|
-
description: "Given a feature request, select appropriate MCP tools (including existing and new ones) and produce an execution plan.",
|
|
1126
|
-
parameters: planFeatureSchema,
|
|
1127
|
-
execute: async (input) => {
|
|
1128
|
-
const steps = [];
|
|
1129
|
-
let i = 1;
|
|
1130
|
-
steps.push({
|
|
1131
|
-
step: i++,
|
|
1132
|
-
action: "Analyze repository to enumerate APIs and decorators",
|
|
1133
|
-
tool: "analyze-repository",
|
|
1134
|
-
arguments: { repoPath: input.repoPath },
|
|
1135
|
-
rationale: "Understand available building blocks.",
|
|
1136
|
-
});
|
|
1137
|
-
steps.push({
|
|
1138
|
-
step: i++,
|
|
1139
|
-
action: "List capabilities expected for developers",
|
|
1140
|
-
tool: "enumerate-capabilities",
|
|
1141
|
-
arguments: { repoPath: input.repoPath },
|
|
1142
|
-
rationale: "Align the plan with supported capabilities.",
|
|
1143
|
-
});
|
|
1144
|
-
// Suggest existing generic tools from mcp-module
|
|
1145
|
-
steps.push({
|
|
1146
|
-
step: i++,
|
|
1147
|
-
action: "Select documentation prompt and gather relevant source file(s)",
|
|
1148
|
-
tool: "document-code",
|
|
1149
|
-
arguments: { filePath: "<target-file>" },
|
|
1150
|
-
rationale: "Provide context and instructions for changes.",
|
|
1151
|
-
});
|
|
1152
|
-
steps.push({
|
|
1153
|
-
step: i++,
|
|
1154
|
-
action: "Apply code changes using unified diff patch",
|
|
1155
|
-
tool: "apply-code-change",
|
|
1156
|
-
arguments: {
|
|
1157
|
-
filePath: "<target-file>",
|
|
1158
|
-
patch: "<unified-diff>",
|
|
1159
|
-
dryRun: true,
|
|
1160
|
-
},
|
|
1161
|
-
rationale: "Validate changes safely before committing.",
|
|
1162
|
-
});
|
|
1163
|
-
steps.push({
|
|
1164
|
-
step: i++,
|
|
1165
|
-
action: "Commit code changes",
|
|
1166
|
-
tool: "apply-code-change",
|
|
1167
|
-
arguments: {
|
|
1168
|
-
filePath: "<target-file>",
|
|
1169
|
-
patch: "<unified-diff>",
|
|
1170
|
-
dryRun: false,
|
|
1171
|
-
},
|
|
1172
|
-
rationale: "Persist the update.",
|
|
1173
|
-
});
|
|
1174
|
-
// If decoration-related terms present, suggest decorator tools
|
|
1175
|
-
if (/decorat|flavour|override|extend|builder/i.test(input.feature)) {
|
|
1176
|
-
steps.unshift({
|
|
1177
|
-
step: 0,
|
|
1178
|
-
action: "Use decorator tooling to insert/remove/modify decorators",
|
|
1179
|
-
tool: "decorator-tools",
|
|
1180
|
-
arguments: { action: "help" },
|
|
1181
|
-
rationale: "Leverage specialized utilities for decoration patterns.",
|
|
1182
|
-
});
|
|
1183
|
-
steps.forEach((s, idx) => (s.step = idx + 1));
|
|
1184
|
-
}
|
|
1185
|
-
return {
|
|
1186
|
-
content: [
|
|
1187
|
-
{
|
|
1188
|
-
type: "text",
|
|
1189
|
-
text: JSON.stringify({
|
|
1190
|
-
plan: steps,
|
|
1191
|
-
notes: "Replace placeholder arguments like <target-file> and <unified-diff> based on the analysis output.",
|
|
1192
|
-
}, null, 2),
|
|
1193
|
-
},
|
|
1194
|
-
],
|
|
1195
|
-
};
|
|
1196
|
-
},
|
|
1197
|
-
};
|
|
1198
|
-
}
|
|
1199
|
-
const documentCodeTool = {
|
|
1200
|
-
annotations: {
|
|
1201
|
-
idempotentHint: true,
|
|
1202
|
-
openWorldHint: false,
|
|
1203
|
-
readOnlyHint: true,
|
|
1204
|
-
title: "Document Source File",
|
|
1205
|
-
},
|
|
1206
|
-
description: "Generate documentation guidance for a file by combining repository prompts with the target source code.",
|
|
1207
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1208
|
-
execute: async (input, _context) => {
|
|
1209
|
-
const args = documentCodeSchema.parse(input);
|
|
1210
|
-
const root = getWorkspaceRoot();
|
|
1211
|
-
let filePath;
|
|
1212
|
-
try {
|
|
1213
|
-
filePath = resolveInWorkspace(root, args.filePath);
|
|
1214
|
-
}
|
|
1215
|
-
catch (error) {
|
|
1216
|
-
if (error instanceof WorkspaceError) {
|
|
1217
|
-
return throwUserError(error.message);
|
|
1218
|
-
}
|
|
1219
|
-
/* istanbul ignore next */
|
|
1220
|
-
throw error;
|
|
1221
|
-
}
|
|
1222
|
-
if (!fs.existsSync(filePath)) {
|
|
1223
|
-
return throwUserError(`Cannot document missing file at ${args.filePath}`);
|
|
1224
|
-
}
|
|
1225
|
-
const fileContent = fs.readFileSync(filePath, {
|
|
1226
|
-
encoding: args.encoding,
|
|
1227
|
-
});
|
|
1228
|
-
// dynamically import prompt helpers
|
|
1229
|
-
const promptMod = await Promise.resolve().then(function () { return prompts$1; });
|
|
1230
|
-
const { discoverDocPrompts, selectPrompt, DEFAULT_PROMPT_NAME, buildDocumentationPayload, } = promptMod;
|
|
1231
|
-
const prompts = discoverDocPrompts(root);
|
|
1232
|
-
if (!prompts.length) {
|
|
1233
|
-
return throwUserError("No documentation prompts found under .code/prompts or .codex/prompts");
|
|
1234
|
-
}
|
|
1235
|
-
const prompt = selectPrompt(prompts, args.promptName ?? DEFAULT_PROMPT_NAME);
|
|
1236
|
-
return buildDocumentationPayload({
|
|
1237
|
-
filePath: args.filePath,
|
|
1238
|
-
fileContent,
|
|
1239
|
-
prompt,
|
|
1240
|
-
includeCode: args.includeCode,
|
|
1241
|
-
includePrompt: args.includePrompt,
|
|
1242
|
-
includeMetadata: args.includeMetadata,
|
|
1243
|
-
additionalContext: args.additionalContext,
|
|
1244
|
-
});
|
|
1245
|
-
},
|
|
1246
|
-
name: "document-code",
|
|
1247
|
-
parameters: documentCodeSchema,
|
|
1248
|
-
};
|
|
1249
|
-
const applyCodeChangeTool = {
|
|
1250
|
-
annotations: {
|
|
1251
|
-
destructiveHint: true,
|
|
1252
|
-
idempotentHint: false,
|
|
1253
|
-
openWorldHint: false,
|
|
1254
|
-
readOnlyHint: false,
|
|
1255
|
-
title: "Apply Code Patch",
|
|
1256
|
-
},
|
|
1257
|
-
description: "Apply a unified diff patch to a workspace file with optional dry-run validation and diff preview.",
|
|
1258
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1259
|
-
execute: async (input, _context) => {
|
|
1260
|
-
const args = codeChangeSchema.parse(input);
|
|
1261
|
-
const root = getWorkspaceRoot();
|
|
1262
|
-
let filePath;
|
|
1263
|
-
try {
|
|
1264
|
-
filePath = resolveInWorkspace(root, args.filePath);
|
|
1265
|
-
}
|
|
1266
|
-
catch (error) {
|
|
1267
|
-
if (error instanceof WorkspaceError) {
|
|
1268
|
-
return throwUserError(error.message);
|
|
1269
|
-
}
|
|
1270
|
-
throw error;
|
|
1271
|
-
}
|
|
1272
|
-
const original = fs.existsSync(filePath)
|
|
1273
|
-
? fs.readFileSync(filePath, args.encoding)
|
|
1274
|
-
: "";
|
|
1275
|
-
let patched;
|
|
1276
|
-
try {
|
|
1277
|
-
patched = diff.applyPatch(original, args.patch);
|
|
1278
|
-
}
|
|
1279
|
-
catch (error) {
|
|
1280
|
-
return throwUserError(`Failed to apply provided patch to ${args.filePath}: ${error instanceof Error ? error.message : error}`);
|
|
1281
|
-
}
|
|
1282
|
-
/* istanbul ignore next */
|
|
1283
|
-
if (patched === false) {
|
|
1284
|
-
return throwUserError(`Failed to apply provided patch to ${args.filePath}`);
|
|
1285
|
-
}
|
|
1286
|
-
if (!args.dryRun) {
|
|
1287
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
1288
|
-
fs.writeFileSync(filePath, patched, {
|
|
1289
|
-
encoding: args.encoding,
|
|
1290
|
-
});
|
|
1291
|
-
}
|
|
1292
|
-
if (!args.showDiff) {
|
|
1293
|
-
return `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`;
|
|
1294
|
-
}
|
|
1295
|
-
const preview = diff.createTwoFilesPatch(args.filePath, args.filePath, original, patched, undefined, undefined, { context: args.diffContext });
|
|
1296
|
-
return {
|
|
1297
|
-
content: [
|
|
1298
|
-
{
|
|
1299
|
-
type: "text",
|
|
1300
|
-
text: `Patch ${args.dryRun ? "validated" : "applied"} for ${args.filePath}`,
|
|
1301
|
-
},
|
|
1302
|
-
{
|
|
1303
|
-
type: "text",
|
|
1304
|
-
text: ["```diff", preview.trim(), "```"].join("\n"),
|
|
1305
|
-
},
|
|
1306
|
-
],
|
|
1307
|
-
};
|
|
1308
|
-
},
|
|
1309
|
-
name: "apply-code-change",
|
|
1310
|
-
parameters: codeChangeSchema,
|
|
1311
|
-
};
|
|
1312
|
-
const analyticTools = [
|
|
1313
|
-
buildAnalyzeRepositoryTool(),
|
|
1314
|
-
buildEnumerateCapabilitiesTool(),
|
|
1315
|
-
buildPlanFeatureTool(),
|
|
1316
|
-
];
|
|
1317
|
-
const toolList$1 = [
|
|
1318
|
-
...analyticTools,
|
|
1319
|
-
documentCodeTool,
|
|
1320
|
-
applyCodeChangeTool,
|
|
1321
|
-
];
|
|
1322
|
-
|
|
1323
|
-
const codexToolList = [
|
|
1324
|
-
documentObjectTool,
|
|
1325
|
-
coverageEnforcerTool,
|
|
1326
|
-
readmeImprovementTool,
|
|
1327
|
-
];
|
|
1328
|
-
const moduleToolList = moduleRegistry
|
|
1329
|
-
.listTools()
|
|
1330
|
-
.map((asset) => asset.tool);
|
|
1331
|
-
const toolList = [...toolList$1, ...codexToolList, ...moduleToolList];
|
|
1332
|
-
const [analyzeRepositoryTool, enumerateCapabilitiesTool, planFeatureTool, documentCodeToolRef, applyCodeChangeToolRef,] = toolList$1;
|
|
1333
|
-
const tools = {
|
|
1334
|
-
analyzeRepositoryTool,
|
|
1335
|
-
enumerateCapabilitiesTool,
|
|
1336
|
-
planFeatureTool,
|
|
1337
|
-
documentCodeTool: documentCodeToolRef,
|
|
1338
|
-
applyCodeChangeTool: applyCodeChangeToolRef,
|
|
1339
|
-
documentObjectTool,
|
|
1340
|
-
coverageEnforcerTool,
|
|
1341
|
-
readmeImprovementTool,
|
|
1342
|
-
...decoratorTools,
|
|
1343
|
-
};
|
|
1344
|
-
|
|
1345
|
-
function toResource(asset) {
|
|
1346
|
-
return {
|
|
1347
|
-
name: asset.id,
|
|
1348
|
-
uri: asset.uri,
|
|
1349
|
-
description: asset.description ?? asset.title,
|
|
1350
|
-
mimeType: asset.mimeType,
|
|
1351
|
-
load: async () => {
|
|
1352
|
-
const res = await asset.load();
|
|
1353
|
-
// asset.load may return a ContentResult or a Promise of ContentResult; ensure we return ResourceResult-like object
|
|
1354
|
-
if (res?.content) {
|
|
1355
|
-
const cr = res;
|
|
1356
|
-
// If ContentResult, convert to simple text result expected by Resource.load consumers
|
|
1357
|
-
return {
|
|
1358
|
-
text: Array.isArray(cr.content)
|
|
1359
|
-
? cr.content.map((c) => c.text).join("\n")
|
|
1360
|
-
: String(cr),
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
// fallback for objects with text
|
|
1364
|
-
return res;
|
|
1365
|
-
},
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
|
-
function buildModuleResources() {
|
|
1369
|
-
return moduleRegistry.listResources().map(toResource);
|
|
1370
|
-
}
|
|
1371
|
-
const resources = [
|
|
1372
|
-
{
|
|
1373
|
-
name: "codex-prompt-index",
|
|
1374
|
-
uri: "codex://prompts/index",
|
|
1375
|
-
description: "Enumerate available .codex prompt files with titles and descriptions.",
|
|
1376
|
-
mimeType: "application/json",
|
|
1377
|
-
load: async () => {
|
|
1378
|
-
const root = getWorkspaceRoot();
|
|
1379
|
-
const prompts = discoverDocPrompts(root).map((prompt) => ({
|
|
1380
|
-
name: prompt.name,
|
|
1381
|
-
title: prompt.title,
|
|
1382
|
-
description: prompt.description,
|
|
1383
|
-
path: prompt.absolutePath,
|
|
1384
|
-
}));
|
|
1385
|
-
return {
|
|
1386
|
-
text: JSON.stringify({ prompts }, null, 2),
|
|
1387
|
-
mimeType: "application/json",
|
|
1388
|
-
};
|
|
1389
|
-
},
|
|
1390
|
-
},
|
|
1391
|
-
{
|
|
1392
|
-
name: "codex-object-prompts",
|
|
1393
|
-
uri: "codex://prompts/objects",
|
|
1394
|
-
description: "Provides the resolved prompt content for each documented object workflow.",
|
|
1395
|
-
mimeType: "application/json",
|
|
1396
|
-
load: async () => {
|
|
1397
|
-
const entries = await Promise.all(buildObjectPrompts().map(async (prompt) => ({
|
|
1398
|
-
name: prompt.name,
|
|
1399
|
-
description: prompt.description,
|
|
1400
|
-
content: await prompt.load({}),
|
|
1401
|
-
})));
|
|
1402
|
-
return {
|
|
1403
|
-
text: JSON.stringify({ prompts: entries }, null, 2),
|
|
1404
|
-
mimeType: "application/json",
|
|
1405
|
-
};
|
|
1406
|
-
},
|
|
1407
|
-
},
|
|
1408
|
-
...buildModuleResources(),
|
|
1409
|
-
];
|
|
1410
|
-
|
|
1411
|
-
const codexPromptTemplates = [];
|
|
1412
|
-
function buildCodexPromptTemplates() {
|
|
1413
|
-
const root = getWorkspaceRoot();
|
|
1414
|
-
const templates = [
|
|
1415
|
-
{
|
|
1416
|
-
name: "codex-prompt",
|
|
1417
|
-
description: "Load a .codex prompt file by name (without extension) as markdown.",
|
|
1418
|
-
uriTemplate: "codex-prompt://{name}",
|
|
1419
|
-
mimeType: "text/markdown",
|
|
1420
|
-
arguments: [
|
|
1421
|
-
{
|
|
1422
|
-
name: "name",
|
|
1423
|
-
description: "Name of the prompt file inside .codex/prompts (without .md).",
|
|
1424
|
-
required: true,
|
|
1425
|
-
},
|
|
1426
|
-
],
|
|
1427
|
-
load: async ({ name }) => {
|
|
1428
|
-
const promptPath = resolveInWorkspace(root, path.join(".codex", "prompts", `${name}.md`));
|
|
1429
|
-
if (!fs.existsSync(promptPath)) {
|
|
1430
|
-
throw new Error(`Prompt .codex/prompts/${name}.md not found`);
|
|
1431
|
-
}
|
|
1432
|
-
const text = fs.readFileSync(promptPath, "utf8");
|
|
1433
|
-
return { text, uri: `codex-prompt:///${name}` };
|
|
1434
|
-
},
|
|
1435
|
-
},
|
|
1436
|
-
];
|
|
1437
|
-
codexPromptTemplates.splice(0, codexPromptTemplates.length, ...templates);
|
|
1438
|
-
return codexPromptTemplates;
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
const decorationResourceTemplates = [];
|
|
1442
|
-
function makeLoader(type) {
|
|
1443
|
-
return async ({ path: relative }) => {
|
|
1444
|
-
const root = getWorkspaceRoot();
|
|
1445
|
-
const target = path.join(type, relative);
|
|
1446
|
-
const text = await readWorkspaceFile(root, target);
|
|
1447
|
-
return { text };
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
function buildDecorationResourceTemplates() {
|
|
1451
|
-
const templates = [
|
|
1452
|
-
{
|
|
1453
|
-
name: "read-code-from-source",
|
|
1454
|
-
description: "Read a file from the <base_path>/src tree by relative path.",
|
|
1455
|
-
mimeType: "text/plain",
|
|
1456
|
-
uriTemplate: "from-source://src/{path}",
|
|
1457
|
-
arguments: [
|
|
1458
|
-
{
|
|
1459
|
-
name: "path",
|
|
1460
|
-
description: "Path under <base_path>/src to load, e.g. 'decoration/types.ts'",
|
|
1461
|
-
required: true,
|
|
1462
|
-
},
|
|
1463
|
-
],
|
|
1464
|
-
load: makeLoader("src"),
|
|
1465
|
-
},
|
|
1466
|
-
{
|
|
1467
|
-
name: "read-test-from-source",
|
|
1468
|
-
description: "Read a file from the <base_path>/tests tree by relative path.",
|
|
1469
|
-
mimeType: "text/plain",
|
|
1470
|
-
uriTemplate: "from-source://tests/{path}",
|
|
1471
|
-
arguments: [
|
|
1472
|
-
{
|
|
1473
|
-
name: "path",
|
|
1474
|
-
description: "Path under <base_path>/tests to load, e.g. 'decoration/tests/types.test.ts'",
|
|
1475
|
-
required: true,
|
|
1476
|
-
},
|
|
1477
|
-
],
|
|
1478
|
-
load: makeLoader("tests"),
|
|
1479
|
-
},
|
|
1480
|
-
{
|
|
1481
|
-
name: "read-doc-from-source",
|
|
1482
|
-
description: "Read a file from the <base_path>/workdocs tree by relative path.",
|
|
1483
|
-
mimeType: "text/plain",
|
|
1484
|
-
uriTemplate: "from-source://workdocs/{path}",
|
|
1485
|
-
arguments: [
|
|
1486
|
-
{
|
|
1487
|
-
name: "path",
|
|
1488
|
-
description: "Path under <base_path>/workdocs to load, e.g. 'decoration/workdocs/tutorials/for-developers.md'",
|
|
1489
|
-
required: true,
|
|
1490
|
-
},
|
|
1491
|
-
],
|
|
1492
|
-
load: makeLoader("workdocs"),
|
|
1493
|
-
},
|
|
1494
|
-
];
|
|
1495
|
-
decorationResourceTemplates.splice(0, decorationResourceTemplates.length, ...templates);
|
|
1496
|
-
return decorationResourceTemplates;
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
const workspaceResourceTemplates = [];
|
|
1500
|
-
function buildWorkspaceResourceTemplates() {
|
|
1501
|
-
const root = getWorkspaceRoot();
|
|
1502
|
-
const sharedArguments = [
|
|
1503
|
-
{
|
|
1504
|
-
name: "path",
|
|
1505
|
-
description: "Path relative to the workspace root",
|
|
1506
|
-
required: true,
|
|
1507
|
-
},
|
|
1508
|
-
];
|
|
1509
|
-
const templates = [
|
|
1510
|
-
{
|
|
1511
|
-
name: "vscode-workspace-file",
|
|
1512
|
-
description: "Expose workspace files to Visual Studio Code via vscode:// URIs",
|
|
1513
|
-
uriTemplate: "vscode://workspace/{path}",
|
|
1514
|
-
mimeType: "text/plain",
|
|
1515
|
-
arguments: sharedArguments,
|
|
1516
|
-
load: async (args) => {
|
|
1517
|
-
try {
|
|
1518
|
-
const text = await readWorkspaceFile(root, args.path);
|
|
1519
|
-
return { text: String(text) };
|
|
1520
|
-
}
|
|
1521
|
-
catch (err) {
|
|
1522
|
-
// propagate as-is for tests to assert errors
|
|
1523
|
-
throw err;
|
|
1524
|
-
}
|
|
1525
|
-
},
|
|
1526
|
-
},
|
|
1527
|
-
{
|
|
1528
|
-
name: "cursor-workspace-file",
|
|
1529
|
-
description: "Expose workspace files to Cursor via cursor:// URIs",
|
|
1530
|
-
uriTemplate: "cursor://workspace/{path}",
|
|
1531
|
-
mimeType: "text/plain",
|
|
1532
|
-
arguments: sharedArguments,
|
|
1533
|
-
load: async (args) => {
|
|
1534
|
-
try {
|
|
1535
|
-
const text = await readWorkspaceFile(root, args.path);
|
|
1536
|
-
return { text: String(text) };
|
|
1537
|
-
}
|
|
1538
|
-
catch (err) {
|
|
1539
|
-
throw err;
|
|
1540
|
-
}
|
|
1541
|
-
},
|
|
1542
|
-
},
|
|
1543
|
-
{
|
|
1544
|
-
name: "copilot-workspace-file",
|
|
1545
|
-
description: "Expose workspace files to GitHub Copilot via copilot:// URIs",
|
|
1546
|
-
uriTemplate: "copilot://workspace/{path}",
|
|
1547
|
-
mimeType: "text/plain",
|
|
1548
|
-
arguments: sharedArguments,
|
|
1549
|
-
load: async (args) => {
|
|
1550
|
-
try {
|
|
1551
|
-
const text = await readWorkspaceFile(root, args.path);
|
|
1552
|
-
return { text: String(text) };
|
|
1553
|
-
}
|
|
1554
|
-
catch (err) {
|
|
1555
|
-
throw err;
|
|
1556
|
-
}
|
|
1557
|
-
},
|
|
1558
|
-
},
|
|
1559
|
-
];
|
|
1560
|
-
workspaceResourceTemplates.splice(0, workspaceResourceTemplates.length, ...templates);
|
|
1561
|
-
return workspaceResourceTemplates;
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
|
-
function buildResourceTemplates() {
|
|
1565
|
-
const moduleTemplates = moduleRegistry.listTemplates().map((template) => ({
|
|
1566
|
-
name: template.id,
|
|
1567
|
-
description: template.description ?? template.title,
|
|
1568
|
-
mimeType: "text/markdown",
|
|
1569
|
-
uriTemplate: `module-template://${template.id}`,
|
|
1570
|
-
arguments: (template.placeholders ?? []).map((name) => ({
|
|
1571
|
-
name,
|
|
1572
|
-
description: `Value for ${name}`,
|
|
1573
|
-
required: true,
|
|
1574
|
-
})),
|
|
1575
|
-
load: async () => ({
|
|
1576
|
-
text: typeof template.content === "string"
|
|
1577
|
-
? template.content
|
|
1578
|
-
: `# ${template.description ?? template.title ?? template.id}\n\nNo template content available for ${template.id}`,
|
|
1579
|
-
}),
|
|
1580
|
-
}));
|
|
1581
|
-
const all = [
|
|
1582
|
-
...buildWorkspaceResourceTemplates(),
|
|
1583
|
-
...buildCodexPromptTemplates(),
|
|
1584
|
-
...buildDecorationResourceTemplates(),
|
|
1585
|
-
...moduleTemplates,
|
|
1586
|
-
];
|
|
1587
|
-
// Normalise all loaders to always return { text: string }
|
|
1588
|
-
function normaliseResult(res) {
|
|
1589
|
-
if (res == null)
|
|
1590
|
-
return { text: "" };
|
|
1591
|
-
if (typeof res === "string")
|
|
1592
|
-
return { text: res };
|
|
1593
|
-
if (typeof res.text === "string")
|
|
1594
|
-
return res;
|
|
1595
|
-
// handle legacy ContentResult shapes with content or content array
|
|
1596
|
-
if (Array.isArray(res.content)) {
|
|
1597
|
-
const parts = res.content
|
|
1598
|
-
.map((c) => (c && typeof c.text === "string" ? c.text : String(c)))
|
|
1599
|
-
.join("\n");
|
|
1600
|
-
return { text: parts };
|
|
1601
|
-
}
|
|
1602
|
-
if (res.content && typeof res.content.text === "string") {
|
|
1603
|
-
return { text: res.content.text };
|
|
1604
|
-
}
|
|
1605
|
-
// fallback: stringify
|
|
1606
|
-
try {
|
|
1607
|
-
return { text: JSON.stringify(res) };
|
|
1608
|
-
}
|
|
1609
|
-
catch {
|
|
1610
|
-
return { text: String(res) };
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
return all.map((t) => ({
|
|
1614
|
-
...t,
|
|
1615
|
-
load: async (args) => {
|
|
1616
|
-
const raw = await t.load(args);
|
|
1617
|
-
return normaliseResult(raw);
|
|
1618
|
-
},
|
|
1619
|
-
}));
|
|
1620
|
-
}
|
|
1621
|
-
const templateList = buildResourceTemplates();
|
|
1622
|
-
|
|
1623
|
-
/**
|
|
1624
|
-
* @const VERSION
|
|
1625
|
-
* @name VERSION
|
|
1626
|
-
* @description Represents the current version of the ts-workspace module.
|
|
1627
|
-
* @summary The actual version number is replaced during the build process.
|
|
1628
|
-
* @type {string}
|
|
1629
|
-
*/
|
|
1630
|
-
const VERSION$1 = "0.4.1";
|
|
1631
|
-
const PACKAGE_NAME$1 = "##PACKAGE_NAME##";
|
|
1632
|
-
try {
|
|
1633
|
-
decoration.Metadata.registerLibrary(PACKAGE_NAME$1, VERSION$1);
|
|
1634
|
-
}
|
|
1635
|
-
catch (error) {
|
|
1636
|
-
if (error instanceof Error && error.message.includes("already")) ;
|
|
1637
|
-
else {
|
|
1638
|
-
throw error;
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
function enrich(mcp) {
|
|
1643
|
-
const promptEntries = loadPrompts();
|
|
1644
|
-
for (const prompt of promptEntries) {
|
|
1645
|
-
mcp.addPrompt(prompt);
|
|
1646
|
-
}
|
|
1647
|
-
for (const tool of toolList) {
|
|
1648
|
-
mcp.addTool(tool);
|
|
1649
|
-
}
|
|
1650
|
-
const templates = buildResourceTemplates();
|
|
1651
|
-
for (const template of templates) {
|
|
1652
|
-
mcp.addResourceTemplate(template);
|
|
1653
|
-
}
|
|
1654
|
-
for (const resource of resources) {
|
|
1655
|
-
const addResource = mcp.addResource;
|
|
1656
|
-
if (typeof addResource === "function") {
|
|
1657
|
-
addResource.call(mcp, resource);
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
return mcp;
|
|
1661
|
-
}
|
|
1662
|
-
const PACKAGE_NAME = PACKAGE_NAME$1;
|
|
1663
|
-
const VERSION = VERSION$1;
|
|
1664
|
-
|
|
1665
|
-
// New: validation entrypoint for module structure
|
|
1666
|
-
const REQUIRED_SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
|
|
1667
|
-
function findModuleDirs(repoRoot) {
|
|
1668
|
-
const modulesPath = path.resolve(repoRoot, "src", "modules");
|
|
1669
|
-
if (!fs.existsSync(modulesPath) || !fs.statSync(modulesPath).isDirectory()) {
|
|
1670
|
-
return [];
|
|
1671
|
-
}
|
|
1672
|
-
return fs
|
|
1673
|
-
.readdirSync(modulesPath, { withFileTypes: true })
|
|
1674
|
-
.filter((d) => d.isDirectory())
|
|
1675
|
-
.map((d) => path.join(modulesPath, d.name));
|
|
1676
|
-
}
|
|
1677
|
-
function hasIndexExport(folderPath) {
|
|
1678
|
-
const candidates = [
|
|
1679
|
-
"index.ts",
|
|
1680
|
-
"index.tsx",
|
|
1681
|
-
"index.js",
|
|
1682
|
-
"index.cjs",
|
|
1683
|
-
"index.mjs",
|
|
1684
|
-
];
|
|
1685
|
-
for (const c of candidates) {
|
|
1686
|
-
if (fs.existsSync(path.join(folderPath, c)))
|
|
1687
|
-
return true;
|
|
1688
|
-
}
|
|
1689
|
-
return false;
|
|
1690
|
-
}
|
|
1691
|
-
function validateModules(repoRoot) {
|
|
1692
|
-
const dirs = findModuleDirs(repoRoot);
|
|
1693
|
-
const issues = [];
|
|
1694
|
-
for (const moduleDir of dirs) {
|
|
1695
|
-
const moduleName = path.basename(moduleDir);
|
|
1696
|
-
for (const sub of REQUIRED_SUBFOLDERS) {
|
|
1697
|
-
const subPath = path.join(moduleDir, sub);
|
|
1698
|
-
if (!fs.existsSync(subPath) || !fs.statSync(subPath).isDirectory()) {
|
|
1699
|
-
issues.push({
|
|
1700
|
-
module: moduleName,
|
|
1701
|
-
path: subPath,
|
|
1702
|
-
type: "missing-folder",
|
|
1703
|
-
detail: `Required folder '${sub}' is missing in module '${moduleName}'`,
|
|
1704
|
-
});
|
|
1705
|
-
continue;
|
|
1706
|
-
}
|
|
1707
|
-
// If folder exists, check for index export
|
|
1708
|
-
if (!hasIndexExport(subPath)) {
|
|
1709
|
-
issues.push({
|
|
1710
|
-
module: moduleName,
|
|
1711
|
-
path: subPath,
|
|
1712
|
-
type: "missing-export",
|
|
1713
|
-
detail: `No index export found in '${subPath}'. Expected one of index.ts, index.js, etc.`,
|
|
1714
|
-
});
|
|
1715
|
-
continue;
|
|
1716
|
-
}
|
|
1717
|
-
// Optionally inspect the index file to see if it exports a list (lightweight check)
|
|
1718
|
-
try {
|
|
1719
|
-
const indexFile = candidatesFindingIndex(subPath);
|
|
1720
|
-
if (indexFile) {
|
|
1721
|
-
const content = fs.readFileSync(indexFile, "utf8");
|
|
1722
|
-
// crude heuristics: look for `export const name = [` or `export const name: Type[] = [`,
|
|
1723
|
-
// or any named export like `export { something }` which implies exports exist.
|
|
1724
|
-
const exportListPattern = /export\s+(const|let|var)\s+[\w$]+(?:\s*:\s*[^=]+)?\s*=\s*\[/;
|
|
1725
|
-
if (!exportListPattern.test(content) &&
|
|
1726
|
-
!/export\s+\{/.test(content)) {
|
|
1727
|
-
issues.push({
|
|
1728
|
-
module: moduleName,
|
|
1729
|
-
path: indexFile,
|
|
1730
|
-
type: "empty-list",
|
|
1731
|
-
detail: `Index file does not appear to export a list of assets: ${path.basename(indexFile)}`,
|
|
1732
|
-
});
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
catch (err) {
|
|
1737
|
-
issues.push({
|
|
1738
|
-
module: moduleName,
|
|
1739
|
-
path: subPath,
|
|
1740
|
-
type: "other",
|
|
1741
|
-
detail: `Error reading index file: ${err.message}`,
|
|
1742
|
-
});
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
return {
|
|
1747
|
-
ok: issues.length === 0,
|
|
1748
|
-
modulesChecked: dirs.length,
|
|
1749
|
-
issues,
|
|
1750
|
-
};
|
|
1751
|
-
}
|
|
1752
|
-
function candidatesFindingIndex(folderPath) {
|
|
1753
|
-
const candidates = [
|
|
1754
|
-
"index.ts",
|
|
1755
|
-
"index.tsx",
|
|
1756
|
-
"index.js",
|
|
1757
|
-
"index.cjs",
|
|
1758
|
-
"index.mjs",
|
|
1759
|
-
];
|
|
1760
|
-
for (const c of candidates) {
|
|
1761
|
-
const full = path.join(folderPath, c);
|
|
1762
|
-
if (fs.existsSync(full))
|
|
1763
|
-
return full;
|
|
1764
|
-
}
|
|
1765
|
-
return undefined;
|
|
1766
|
-
}
|
|
1767
|
-
// CLI helper
|
|
1768
|
-
if (require.main === module) {
|
|
1769
|
-
const repoRoot = process.cwd();
|
|
1770
|
-
const report = validateModules(repoRoot);
|
|
1771
|
-
if (!report.ok) {
|
|
1772
|
-
console.error("Module validation failed:\n", JSON.stringify(report, null, 2));
|
|
1773
|
-
process.exit(2);
|
|
1774
|
-
}
|
|
1775
|
-
console.log("Module validation passed");
|
|
1776
|
-
process.exit(0);
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
// Aggregator: import module index files and merge exported arrays with provenance + duplicate detection
|
|
1780
|
-
const SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
|
|
1781
|
-
const INDEX_CANDIDATES = [
|
|
1782
|
-
"index.ts",
|
|
1783
|
-
"index.tsx",
|
|
1784
|
-
"index.js",
|
|
1785
|
-
"index.cjs",
|
|
1786
|
-
"index.mjs",
|
|
1787
|
-
];
|
|
1788
|
-
function findIndexFile(folder) {
|
|
1789
|
-
for (const c of INDEX_CANDIDATES) {
|
|
1790
|
-
const f = path.join(folder, c);
|
|
1791
|
-
if (fs.existsSync(f))
|
|
1792
|
-
return f;
|
|
1793
|
-
}
|
|
1794
|
-
return undefined;
|
|
1795
|
-
}
|
|
1796
|
-
function makeKeyForItem(item) {
|
|
1797
|
-
if (!item)
|
|
1798
|
-
return JSON.stringify(item);
|
|
1799
|
-
if (typeof item === "string")
|
|
1800
|
-
return `str:${item}`;
|
|
1801
|
-
if (typeof item === "number")
|
|
1802
|
-
return `num:${item}`;
|
|
1803
|
-
if (item.id)
|
|
1804
|
-
return `id:${item.id}`;
|
|
1805
|
-
if (item.name)
|
|
1806
|
-
return `name:${item.name}`;
|
|
1807
|
-
// fallback to stable string
|
|
1808
|
-
try {
|
|
1809
|
-
return `obj:${JSON.stringify(item)}`;
|
|
1810
|
-
}
|
|
1811
|
-
catch (e) {
|
|
1812
|
-
return `obj:${String(item)}`;
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
async function loadArrayFromIndex(filePath) {
|
|
1816
|
-
// Prefer a fast, static parse of the first array literal found in the file.
|
|
1817
|
-
try {
|
|
1818
|
-
const content = fs.readFileSync(filePath, "utf8");
|
|
1819
|
-
const start = content.indexOf("[");
|
|
1820
|
-
if (start !== -1) {
|
|
1821
|
-
let depth = 0;
|
|
1822
|
-
let end = -1;
|
|
1823
|
-
for (let i = start; i < content.length; i++) {
|
|
1824
|
-
const ch = content[i];
|
|
1825
|
-
if (ch === "[")
|
|
1826
|
-
depth++;
|
|
1827
|
-
else if (ch === "]") {
|
|
1828
|
-
depth--;
|
|
1829
|
-
if (depth === 0) {
|
|
1830
|
-
end = i;
|
|
1831
|
-
break;
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
if (end !== -1) {
|
|
1836
|
-
const arrText = content.slice(start, end + 1);
|
|
1837
|
-
try {
|
|
1838
|
-
return JSON.parse(arrText);
|
|
1839
|
-
}
|
|
1840
|
-
catch (e) {
|
|
1841
|
-
// Normalize TS object literals to JSON:
|
|
1842
|
-
// - convert single quotes to double quotes
|
|
1843
|
-
// - quote unquoted object keys
|
|
1844
|
-
// - strip trailing commas
|
|
1845
|
-
const normalized = arrText
|
|
1846
|
-
// unify quotes in string literals
|
|
1847
|
-
.replace(/'(?:\\'|[^'])*'/g, (m) => m.replace(/'/g, '"'))
|
|
1848
|
-
// quote unquoted keys after { or ,
|
|
1849
|
-
.replace(/([\{,]\s*)([A-Za-z_$][\w$]*)(\s*:)/g, '$1"$2"$3')
|
|
1850
|
-
// remove trailing commas before ] or }
|
|
1851
|
-
.replace(/,(\s*[\}\]])/g, '$1');
|
|
1852
|
-
try {
|
|
1853
|
-
return JSON.parse(normalized);
|
|
1854
|
-
}
|
|
1855
|
-
catch (e2) {
|
|
1856
|
-
// fallthrough to import attempt below
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
}
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
catch (e) {
|
|
1863
|
-
// ignore static parse errors and fall back to import
|
|
1864
|
-
}
|
|
1865
|
-
try {
|
|
1866
|
-
const fileUrl = url.pathToFileURL(filePath).href;
|
|
1867
|
-
const mod = await import(fileUrl);
|
|
1868
|
-
// Find first export that is an array
|
|
1869
|
-
for (const key of Object.keys(mod)) {
|
|
1870
|
-
const val = mod[key];
|
|
1871
|
-
if (Array.isArray(val))
|
|
1872
|
-
return val;
|
|
1873
|
-
}
|
|
1874
|
-
// default export check
|
|
1875
|
-
if (Array.isArray(mod.default))
|
|
1876
|
-
return mod.default;
|
|
1877
|
-
return undefined;
|
|
1878
|
-
}
|
|
1879
|
-
catch (err) {
|
|
1880
|
-
// fallback: if import fails, try to static-parse again (already attempted) and finally return undefined
|
|
1881
|
-
return undefined;
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
async function aggregateModules(repoRoot) {
|
|
1885
|
-
const dirs = findModuleDirs(repoRoot);
|
|
1886
|
-
const master = {
|
|
1887
|
-
prompts: [],
|
|
1888
|
-
resources: [],
|
|
1889
|
-
templates: [],
|
|
1890
|
-
tools: [],
|
|
1891
|
-
conflicts: [],
|
|
1892
|
-
};
|
|
1893
|
-
// maps to detect duplicates per type
|
|
1894
|
-
const maps = {
|
|
1895
|
-
prompts: new Map(),
|
|
1896
|
-
resources: new Map(),
|
|
1897
|
-
templates: new Map(),
|
|
1898
|
-
tools: new Map(),
|
|
1899
|
-
};
|
|
1900
|
-
for (const moduleDir of dirs) {
|
|
1901
|
-
const moduleName = path.basename(moduleDir);
|
|
1902
|
-
for (const sub of SUBFOLDERS) {
|
|
1903
|
-
const folder = path.join(moduleDir, sub);
|
|
1904
|
-
const indexFile = findIndexFile(folder);
|
|
1905
|
-
if (!indexFile)
|
|
1906
|
-
continue;
|
|
1907
|
-
let arr;
|
|
1908
|
-
try {
|
|
1909
|
-
arr = await loadArrayFromIndex(indexFile);
|
|
1910
|
-
}
|
|
1911
|
-
catch (err) {
|
|
1912
|
-
// skip module on import error but record as conflict-like issue
|
|
1913
|
-
master.conflicts.push({
|
|
1914
|
-
key: `import-error:${moduleName}:${sub}`,
|
|
1915
|
-
existing: { moduleName, modulePath: moduleDir },
|
|
1916
|
-
incoming: { moduleName, modulePath: moduleDir },
|
|
1917
|
-
});
|
|
1918
|
-
continue;
|
|
1919
|
-
}
|
|
1920
|
-
if (!arr || !Array.isArray(arr))
|
|
1921
|
-
continue;
|
|
1922
|
-
for (const item of arr) {
|
|
1923
|
-
const key = makeKeyForItem(item);
|
|
1924
|
-
const provenance = { moduleName, modulePath: moduleDir };
|
|
1925
|
-
const map = maps[sub];
|
|
1926
|
-
if (map.has(key)) {
|
|
1927
|
-
// record conflict deterministically (existing vs incoming)
|
|
1928
|
-
const existing = map.get(key);
|
|
1929
|
-
master.conflicts.push({ key, existing, incoming: provenance });
|
|
1930
|
-
// skip adding duplicate
|
|
1931
|
-
continue;
|
|
1932
|
-
}
|
|
1933
|
-
map.set(key, provenance);
|
|
1934
|
-
master[sub].push({ ...item, provenance });
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
return master;
|
|
1939
|
-
}
|
|
1940
|
-
// For compatibility with CommonJS call sites (not exported by ESM), provide a sync wrapper
|
|
1941
|
-
function aggregateModulesSync(repoRoot) {
|
|
1942
|
-
// synchronous wrapper that runs the async function and blocks — suitable for small module sets
|
|
1943
|
-
const p = aggregateModules(repoRoot);
|
|
1944
|
-
let result;
|
|
1945
|
-
let done = false;
|
|
1946
|
-
p.then((r) => {
|
|
1947
|
-
result = r;
|
|
1948
|
-
done = true;
|
|
1949
|
-
}).catch((e) => {
|
|
1950
|
-
throw e;
|
|
1951
|
-
});
|
|
1952
|
-
if (!done)
|
|
1953
|
-
throw new Error("aggregateModulesSync: timeout waiting for async aggregation");
|
|
1954
|
-
return result;
|
|
1955
|
-
}
|
|
1956
|
-
|
|
1957
|
-
/**
|
|
1958
|
-
* Aggregate module assets and register them on the provided FastMCP-like server.
|
|
1959
|
-
* Falls back to built-in lists if aggregation yields none.
|
|
1960
|
-
*/
|
|
1961
|
-
async function EnrichCoreWithAggregation(server, repoRoot = process.cwd()) {
|
|
1962
|
-
// First register built-in prompts/tools/resources/templates (legacy behavior)
|
|
1963
|
-
try {
|
|
1964
|
-
loadPrompts();
|
|
1965
|
-
for (const prompt of promptList)
|
|
1966
|
-
server.addPrompt(prompt);
|
|
1967
|
-
}
|
|
1968
|
-
catch (e) {
|
|
1969
|
-
// ignore if loadPrompts not available or fails
|
|
1970
|
-
}
|
|
1971
|
-
try {
|
|
1972
|
-
for (const tool of toolList)
|
|
1973
|
-
server.addTool(tool);
|
|
1974
|
-
}
|
|
1975
|
-
catch (e) { }
|
|
1976
|
-
try {
|
|
1977
|
-
for (const resource of resources)
|
|
1978
|
-
server.addResource(resource);
|
|
1979
|
-
}
|
|
1980
|
-
catch (e) { }
|
|
1981
|
-
try {
|
|
1982
|
-
const templates = buildResourceTemplates();
|
|
1983
|
-
for (const template of templates)
|
|
1984
|
-
server.addResourceTemplate(template);
|
|
1985
|
-
}
|
|
1986
|
-
catch (e) { }
|
|
1987
|
-
// Now aggregate modules and register aggregated assets with provenance
|
|
1988
|
-
const agg = await aggregateModules(repoRoot);
|
|
1989
|
-
for (const p of agg.prompts) {
|
|
1990
|
-
server.addPrompt(p);
|
|
1991
|
-
}
|
|
1992
|
-
for (const t of agg.tools) {
|
|
1993
|
-
server.addTool(t);
|
|
1994
|
-
}
|
|
1995
|
-
for (const r of agg.resources) {
|
|
1996
|
-
server.addResource(r);
|
|
1997
|
-
}
|
|
1998
|
-
for (const tpl of agg.templates) {
|
|
1999
|
-
server.addResourceTemplate(tpl);
|
|
2000
|
-
}
|
|
2001
|
-
// return aggregation summary for calling tests/CI
|
|
2002
|
-
return {
|
|
2003
|
-
modulesChecked: agg.prompts.concat(agg.tools).length,
|
|
2004
|
-
conflicts: agg.conflicts,
|
|
2005
|
-
};
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
function EnrichCore(server) {
|
|
2009
|
-
loadPrompts();
|
|
2010
|
-
for (const prompt of promptList) {
|
|
2011
|
-
server.addPrompt(prompt);
|
|
2012
|
-
}
|
|
2013
|
-
for (const tool of toolList) {
|
|
2014
|
-
server.addTool(tool);
|
|
2015
|
-
}
|
|
2016
|
-
for (const resource of resources) {
|
|
2017
|
-
server.addResource(resource);
|
|
2018
|
-
}
|
|
2019
|
-
const templates = buildResourceTemplates();
|
|
2020
|
-
for (const template of templates) {
|
|
2021
|
-
server.addResourceTemplate(template);
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
|
-
const REQUIRED_MODULE_FOLDERS = [
|
|
2026
|
-
"prompts",
|
|
2027
|
-
"resources",
|
|
2028
|
-
"templates",
|
|
2029
|
-
"tools",
|
|
2030
|
-
];
|
|
2031
|
-
function resolveModulesRoot(workspaceRoot = getWorkspaceRoot()) {
|
|
2032
|
-
return path$1.resolve(workspaceRoot, "src/modules");
|
|
2033
|
-
}
|
|
2034
|
-
function listModuleDirectories(workspaceRoot = getWorkspaceRoot()) {
|
|
2035
|
-
const root = resolveModulesRoot(workspaceRoot);
|
|
2036
|
-
if (!fs$1.existsSync(root))
|
|
2037
|
-
return [];
|
|
2038
|
-
return fs$1
|
|
2039
|
-
.readdirSync(root)
|
|
2040
|
-
.map((entry) => ({
|
|
2041
|
-
entry,
|
|
2042
|
-
absolute: path$1.join(root, entry),
|
|
2043
|
-
}))
|
|
2044
|
-
.filter(({ absolute }) => fs$1.statSync(absolute).isDirectory())
|
|
2045
|
-
.map(({ entry }) => entry)
|
|
2046
|
-
.sort();
|
|
2047
|
-
}
|
|
2048
|
-
function resolveModulePath(moduleName, workspaceRoot = getWorkspaceRoot()) {
|
|
2049
|
-
return path$1.join(resolveModulesRoot(workspaceRoot), moduleName);
|
|
2050
|
-
}
|
|
2051
|
-
function resolveModuleFolderPath(moduleName, folder, workspaceRoot = getWorkspaceRoot()) {
|
|
2052
|
-
return path$1.join(resolveModulePath(moduleName, workspaceRoot), folder);
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
|
-
/* istanbul ignore file */
|
|
2056
|
-
/**
|
|
2057
|
-
* @description Utility class for CLI operations
|
|
2058
|
-
* @summary A static utility class that provides methods for loading modules, retrieving package information, and initializing CLI commands
|
|
2059
|
-
*
|
|
2060
|
-
* @example
|
|
2061
|
-
* // Initialize a Command object with package information
|
|
2062
|
-
* const command = new Command();
|
|
2063
|
-
* CLIUtils.initialize(command, './path/to/package');
|
|
2064
|
-
*
|
|
2065
|
-
* // Load a CLI module from a file
|
|
2066
|
-
* const module = await CLIUtils.loadFromFile('./path/to/cli-module.js');
|
|
2067
|
-
*
|
|
2068
|
-
* @class McpUtils
|
|
2069
|
-
*/
|
|
2070
|
-
class McpUtils {
|
|
2071
|
-
/**
|
|
2072
|
-
* @description Dynamically imports a module file
|
|
2073
|
-
* @summary Loads a JavaScript file and returns it as a CliModule, handling both ESM and CommonJS formats
|
|
2074
|
-
*
|
|
2075
|
-
* @param {string} path The file path to the module to load
|
|
2076
|
-
* @return {Promise<McpModule>} A promise that resolves to the loaded CliModule
|
|
2077
|
-
*/
|
|
2078
|
-
static async loadFromFile(path) {
|
|
2079
|
-
try {
|
|
2080
|
-
return McpUtils.normalizeImport(import(path));
|
|
2081
|
-
}
|
|
2082
|
-
catch (e) {
|
|
2083
|
-
throw new Error(`Failed to load from ${path}: ${e instanceof Error ? e.message : e}`);
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
/**
|
|
2087
|
-
* @description Normalizes module imports to handle both ESM and CommonJS formats
|
|
2088
|
-
* @summary Properly imports JavaScript files regardless of their module format by handling the ESM wrapper for CommonJS modules
|
|
2089
|
-
*
|
|
2090
|
-
* @template T The type of the imported module
|
|
2091
|
-
* @param {Promise<T>} importPromise The promise returned by the dynamic import
|
|
2092
|
-
* @return {Promise<T>} A promise that resolves to the normalized module
|
|
2093
|
-
* @private
|
|
2094
|
-
*/
|
|
2095
|
-
static async normalizeImport(importPromise) {
|
|
2096
|
-
// CommonJS's `module.exports` is wrapped as `default` in ESModule.
|
|
2097
|
-
return importPromise.then((m) => (m.default || m));
|
|
2098
|
-
}
|
|
2099
|
-
/**
|
|
2100
|
-
* @description Retrieves and parses the package.json file
|
|
2101
|
-
* @summary Reads the package.json file from the specified path and parses it into a JavaScript object
|
|
2102
|
-
*
|
|
2103
|
-
* @param {string} basePath The base path where the package.json file is located
|
|
2104
|
-
* @return {Record<string, unknown>} The parsed package.json content as an object
|
|
2105
|
-
* @private
|
|
2106
|
-
*/
|
|
2107
|
-
static getPackage(basePath) {
|
|
2108
|
-
try {
|
|
2109
|
-
return JSON.parse(fs.readFileSync(path.join(basePath, "package.json"), "utf8"));
|
|
2110
|
-
}
|
|
2111
|
-
catch (e) {
|
|
2112
|
-
throw new Error(`Unable to read version from ${basePath}: ${e}`);
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
/**
|
|
2116
|
-
* @description Returns the version from package.json
|
|
2117
|
-
* @summary Retrieves the version field from the package.json file at the specified path
|
|
2118
|
-
*
|
|
2119
|
-
* @param {string} basePath The base path where the package.json file is located
|
|
2120
|
-
* @return {string} The package version string
|
|
2121
|
-
*/
|
|
2122
|
-
static packageVersion(basePath) {
|
|
2123
|
-
return McpUtils.getPackage(basePath)["version"];
|
|
2124
|
-
}
|
|
2125
|
-
/**
|
|
2126
|
-
* @description Returns the name from package.json
|
|
2127
|
-
* @summary Retrieves the name field from the package.json file at the specified path and extracts the package name without the scope
|
|
2128
|
-
*
|
|
2129
|
-
* @param {string} basePath The base path where the package.json file is located
|
|
2130
|
-
* @return {string} The package name without the scope (e.g., "cli" from "@decaf-ts/cli")
|
|
2131
|
-
*/
|
|
2132
|
-
static packageName(basePath) {
|
|
2133
|
-
const name = McpUtils.getPackage(basePath)["name"].split("/");
|
|
2134
|
-
return name[name.length - 1];
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
|
|
2138
|
-
/**
|
|
2139
|
-
* @description Utility class to handle CLI functionality from all Decaf modules
|
|
2140
|
-
* @summary This class provides a wrapper around Commander.js to handle CLI commands from different Decaf modules.
|
|
2141
|
-
* It crawls the filesystem to find CLI modules, loads them, and registers their commands.
|
|
2142
|
-
*/
|
|
2143
|
-
class McpWrapper extends logging.LoggedClass {
|
|
2144
|
-
constructor(basePath = "./", crawlLevels = 4) {
|
|
2145
|
-
super();
|
|
2146
|
-
this.basePath = basePath;
|
|
2147
|
-
this.crawlLevels = crawlLevels;
|
|
2148
|
-
this.modules = {};
|
|
2149
|
-
// Support both CommonJS and ESM runtimes for filename/dirname
|
|
2150
|
-
let localDirname;
|
|
2151
|
-
if (typeof __filename !== "undefined" && typeof __dirname !== "undefined") {
|
|
2152
|
-
// CommonJS environment
|
|
2153
|
-
localDirname = __dirname;
|
|
2154
|
-
}
|
|
2155
|
-
else {
|
|
2156
|
-
// ESM or other env: compute import.meta.url at runtime to avoid TS compile-time import.meta checks
|
|
2157
|
-
let metaUrl;
|
|
2158
|
-
try {
|
|
2159
|
-
// Use a dynamic function so TypeScript won't parse `import.meta` at compile time
|
|
2160
|
-
const fn = new Function('return (typeof import !== "undefined" && typeof import.meta !== "undefined") ? import.meta.url : undefined;');
|
|
2161
|
-
metaUrl = fn();
|
|
2162
|
-
}
|
|
2163
|
-
catch {
|
|
2164
|
-
metaUrl = undefined;
|
|
2165
|
-
}
|
|
2166
|
-
if (metaUrl) {
|
|
2167
|
-
localDirname = path__namespace.dirname(url.fileURLToPath(metaUrl));
|
|
2168
|
-
}
|
|
2169
|
-
else {
|
|
2170
|
-
// Last-resort fallback: use current working directory
|
|
2171
|
-
localDirname = process.cwd();
|
|
2172
|
-
}
|
|
2173
|
-
}
|
|
2174
|
-
this.rootPath = path__namespace.resolve(localDirname, "..");
|
|
2175
|
-
}
|
|
2176
|
-
/**
|
|
2177
|
-
* @description Retrieves and initializes the Commander Command object
|
|
2178
|
-
* @summary Lazy-loads the Command object, initializing it with the package name, description, and version
|
|
2179
|
-
* @return {FastMCP} The initialized Command object
|
|
2180
|
-
* @private
|
|
2181
|
-
*/
|
|
2182
|
-
get mcp() {
|
|
2183
|
-
if (!this._mcp) {
|
|
2184
|
-
this._mcp = new fastmcp.FastMCP({
|
|
2185
|
-
name: "decaf-ts MCP server",
|
|
2186
|
-
instructions: "",
|
|
2187
|
-
version: VERSION$1,
|
|
2188
|
-
});
|
|
2189
|
-
}
|
|
2190
|
-
return this._mcp;
|
|
2191
|
-
}
|
|
2192
|
-
/**
|
|
2193
|
-
* @description Loads and registers an mcp extension module from a file
|
|
2194
|
-
* @summary Dynamically imports an mcp extension module from the specified file path, initializes it, and registers it in the modules collection
|
|
2195
|
-
*
|
|
2196
|
-
*/
|
|
2197
|
-
async load(server, filePath) {
|
|
2198
|
-
const log = this.log.for(this.load);
|
|
2199
|
-
let pkg, version, enrich;
|
|
2200
|
-
try {
|
|
2201
|
-
const res = await McpUtils.loadFromFile(filePath);
|
|
2202
|
-
pkg = res.PACKAGE_NAME;
|
|
2203
|
-
version = res.VERSION;
|
|
2204
|
-
enrich = res.enrich;
|
|
2205
|
-
}
|
|
2206
|
-
catch (e) {
|
|
2207
|
-
throw new Error(e.message || e);
|
|
2208
|
-
}
|
|
2209
|
-
try {
|
|
2210
|
-
log.info(`Enriching mcp server with module ${pkg} v${version}`);
|
|
2211
|
-
const result = enrich(server);
|
|
2212
|
-
server = result instanceof Promise ? await result : result;
|
|
2213
|
-
}
|
|
2214
|
-
catch (e) {
|
|
2215
|
-
throw new Error(`failed to enrich mcp with module ${pkg || "unnamed"} under ${filePath}: ${e instanceof Error ? e.message : e}`);
|
|
2216
|
-
}
|
|
2217
|
-
return {
|
|
2218
|
-
mcp: server,
|
|
2219
|
-
package: pkg,
|
|
2220
|
-
version: version,
|
|
2221
|
-
};
|
|
2222
|
-
}
|
|
2223
|
-
/**
|
|
2224
|
-
* @description Finds and loads all CLI modules in the basePath
|
|
2225
|
-
* @summary Uses the crawl method to find all CLI modules in the specified base path,
|
|
2226
|
-
* then loads and registers each module as a subcommand
|
|
2227
|
-
*
|
|
2228
|
-
* @return {Promise<void>} A promise that resolves when all modules are loaded
|
|
2229
|
-
*
|
|
2230
|
-
* @private
|
|
2231
|
-
* @mermaid
|
|
2232
|
-
* sequenceDiagram
|
|
2233
|
-
* participant CliWrapper
|
|
2234
|
-
* participant Filesystem
|
|
2235
|
-
* participant Module
|
|
2236
|
-
*
|
|
2237
|
-
* CliWrapper->>Filesystem: Join basePath with cwd
|
|
2238
|
-
* CliWrapper->>CliWrapper: crawl(basePath, crawlLevels)
|
|
2239
|
-
* CliWrapper-->>CliWrapper: modules[]
|
|
2240
|
-
* loop For each module
|
|
2241
|
-
* alt Not @decaf-ts/cli
|
|
2242
|
-
* CliWrapper->>CliWrapper: load(module, cwd)
|
|
2243
|
-
* CliWrapper-->>CliWrapper: name
|
|
2244
|
-
* CliWrapper->>CliWrapper: Check if command exists
|
|
2245
|
-
* alt Command doesn't exist
|
|
2246
|
-
* CliWrapper->>Command: command(name).addCommand(modules[name])
|
|
2247
|
-
* end
|
|
2248
|
-
* end
|
|
2249
|
-
* end
|
|
2250
|
-
* CliWrapper->>Console: Log loaded modules
|
|
2251
|
-
*/
|
|
2252
|
-
async boot() {
|
|
2253
|
-
const log = this.log.for(this.boot);
|
|
2254
|
-
let server = this.mcp;
|
|
2255
|
-
// discover modules by crawling basePath
|
|
2256
|
-
const moduleFiles = this.crawl(path__namespace.resolve(this.basePath), this.crawlLevels);
|
|
2257
|
-
for (const moduleFile of moduleFiles) {
|
|
2258
|
-
if (moduleFile.includes("@decaf-ts/mcp")) {
|
|
2259
|
-
continue;
|
|
2260
|
-
}
|
|
2261
|
-
try {
|
|
2262
|
-
const res = await this.load(server, moduleFile);
|
|
2263
|
-
server = res.mcp;
|
|
2264
|
-
this.modules[res.package] = moduleFile;
|
|
2265
|
-
}
|
|
2266
|
-
catch (e) {
|
|
2267
|
-
log.error(`Failed to load MCP configs for ${moduleFile}: ${e instanceof Error ? e.message : e}`);
|
|
2268
|
-
}
|
|
2269
|
-
}
|
|
2270
|
-
console.log(`loaded modules:\n${Object.keys(this.modules)
|
|
2271
|
-
.map((k) => `- ${k}`)
|
|
2272
|
-
.join("\n")}`);
|
|
2273
|
-
return server;
|
|
2274
|
-
}
|
|
2275
|
-
/**
|
|
2276
|
-
* @description Recursively searches for CLI module files in the directory structure
|
|
2277
|
-
* @summary Crawls the basePath up to the specified number of folder levels to find files named according to CLI_FILE_NAME
|
|
2278
|
-
*
|
|
2279
|
-
* @param {string} basePath The absolute base path to start searching in
|
|
2280
|
-
* @param {number} [levels=2] The maximum number of directory levels to crawl
|
|
2281
|
-
* @return {string[]} An array of file paths to CLI modules
|
|
2282
|
-
*
|
|
2283
|
-
* @private
|
|
2284
|
-
*/
|
|
2285
|
-
crawl(basePath, levels = 2) {
|
|
2286
|
-
if (levels <= 0)
|
|
2287
|
-
return [];
|
|
2288
|
-
return fs__namespace.readdirSync(basePath).reduce((accum, file) => {
|
|
2289
|
-
file = path__namespace.join(basePath, file);
|
|
2290
|
-
if (fs__namespace.statSync(file).isDirectory()) {
|
|
2291
|
-
accum.push(...this.crawl(file, levels - 1));
|
|
2292
|
-
}
|
|
2293
|
-
else if (file.match(new RegExp(`${MCP_FILE_NAME}.[cm]?js$`, "gm"))) {
|
|
2294
|
-
accum.push(file);
|
|
2295
|
-
}
|
|
2296
|
-
return accum;
|
|
2297
|
-
}, []);
|
|
2298
|
-
}
|
|
2299
|
-
/**
|
|
2300
|
-
* @description Executes the CLI with the provided arguments
|
|
2301
|
-
* @summary Boots the CLI by loading all modules, then parses and executes the command specified in the arguments
|
|
2302
|
-
*
|
|
2303
|
-
* @param {string[]} [args=process.argv] Command line arguments to parse and execute
|
|
2304
|
-
* @return {Promise<void>} A promise that resolves when the command execution is complete
|
|
2305
|
-
*
|
|
2306
|
-
* @mermaid
|
|
2307
|
-
* sequenceDiagram
|
|
2308
|
-
* participant Client
|
|
2309
|
-
* participant CliWrapper
|
|
2310
|
-
* participant Command
|
|
2311
|
-
*
|
|
2312
|
-
* Client->>CliWrapper: run(args)
|
|
2313
|
-
* CliWrapper->>CliWrapper: boot()
|
|
2314
|
-
* Note over CliWrapper: Loads all modules
|
|
2315
|
-
* CliWrapper->>Command: parseAsync(args)
|
|
2316
|
-
* Command-->>CliWrapper: result
|
|
2317
|
-
* CliWrapper-->>Client: result
|
|
2318
|
-
*/
|
|
2319
|
-
async run(args = process.argv) {
|
|
2320
|
-
const server = await this.boot();
|
|
2321
|
-
await server.start({ transportType: "stdio" });
|
|
2322
|
-
}
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
exports.CLIENT_INTEGRATIONS = CLIENT_INTEGRATIONS;
|
|
2326
|
-
exports.DEFAULT_PROMPT_NAME = DEFAULT_PROMPT_NAME;
|
|
2327
|
-
exports.EnrichCore = EnrichCore;
|
|
2328
|
-
exports.EnrichCoreWithAggregation = EnrichCoreWithAggregation;
|
|
2329
|
-
exports.MCP_FILE_NAME = MCP_FILE_NAME;
|
|
2330
|
-
exports.McpUtils = McpUtils;
|
|
2331
|
-
exports.McpWrapper = McpWrapper;
|
|
2332
|
-
exports.PACKAGE_NAME = PACKAGE_NAME;
|
|
2333
|
-
exports.PROMPT_DIRECTORIES = PROMPT_DIRECTORIES;
|
|
2334
|
-
exports.REQUIRED_MODULE_FOLDERS = REQUIRED_MODULE_FOLDERS;
|
|
2335
|
-
exports.VERSION = VERSION;
|
|
2336
|
-
exports.WORKSPACE_ROOT_ENV = WORKSPACE_ROOT_ENV;
|
|
2337
|
-
exports.__resetWorkspaceRoot = __resetWorkspaceRoot;
|
|
2338
|
-
exports.aggregateModules = aggregateModules;
|
|
2339
|
-
exports.aggregateModulesSync = aggregateModulesSync;
|
|
2340
|
-
exports.buildDecorationResourceTemplates = buildDecorationResourceTemplates;
|
|
2341
|
-
exports.buildDocPrompts = buildDocPrompts;
|
|
2342
|
-
exports.buildResourceTemplates = buildResourceTemplates;
|
|
2343
|
-
exports.decorationResourceTemplates = decorationResourceTemplates;
|
|
2344
|
-
exports.enrich = enrich;
|
|
2345
|
-
exports.getWorkspaceRoot = getWorkspaceRoot;
|
|
2346
|
-
exports.listModuleDirectories = listModuleDirectories;
|
|
2347
|
-
exports.promptList = promptList;
|
|
2348
|
-
exports.resolveModuleFolderPath = resolveModuleFolderPath;
|
|
2349
|
-
exports.resolveModulePath = resolveModulePath;
|
|
2350
|
-
exports.resolveModulesRoot = resolveModulesRoot;
|
|
2351
|
-
exports.resources = resources;
|
|
2352
|
-
exports.setWorkspaceRoot = setWorkspaceRoot;
|
|
2353
|
-
exports.templateList = templateList;
|
|
2354
|
-
exports.toolList = toolList;
|
|
2355
|
-
exports.tools = tools;
|
|
2356
|
-
exports.validateModules = validateModules;
|
|
2357
|
-
exports.workspaceResourceTemplates = workspaceResourceTemplates;
|
|
2358
|
-
|
|
2359
|
-
}));
|
|
2360
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXNlcnZlci5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvbWNwL3dvcmtzcGFjZS50cyIsIi4uL3NyYy9tY3AvcHJvbXB0cy9wcm9tcHRzLnRzIiwiLi4vc3JjL21jcC9wcm9tcHRzL2luZGV4LnRzIiwiLi4vc3JjL21jcC9tb2R1bGVSZWdpc3RyeS50cyIsIi4uL3NyYy9tY3Avc2NoZW1hcy50cyIsIi4uL3NyYy9tY3AvdXRpbHMudHMiLCIuLi9zcmMvbWNwL2NvZGUudHMiLCIuLi9zcmMvbWNwL3Rvb2xzL2NvZGV4LXRvb2xzLnRzIiwiLi4vc3JjL21jcC9kZWNvcmF0b3ItdG9vbHMudHMiLCIuLi9zcmMvbWNwL3Rvb2xzL3Rvb2xzLnRzIiwiLi4vc3JjL21jcC90b29scy9pbmRleC50cyIsIi4uL3NyYy9tY3AvcmVzb3VyY2VzL3Jlc291cmNlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL2NvZGV4LXRlbXBsYXRlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL3Jlc291cmNlLXRlbXBsYXRlcy50cyIsIi4uL3NyYy9tY3AvdGVtcGxhdGVzL3dvcmtzcGFjZS10ZW1wbGF0ZXMudHMiLCIuLi9zcmMvbWNwL3RlbXBsYXRlcy9pbmRleC50cyIsIi4uL3NyYy9tZXRhZGF0YS50cyIsIi4uL3NyYy9tY3AvbWNwLW1vZHVsZS50cyIsIi4uL3NyYy9tY3AvdmFsaWRhdGlvbi9pbmRleC50cyIsIi4uL3NyYy9tY3AvYWdncmVnYXRlTW9kdWxlcy50cyIsIi4uL3NyYy9tY3AvZmFzdG1jcC13aXJpbmcudHMiLCIuLi9zcmMvbWNwL2luZGV4LnRzIiwiLi4vc3JjL3V0aWxzL21vZHVsZVBhdGhzLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL01jcFdyYXBwZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZGVzY3JpcHRpb24gVGhlIGZpbGVuYW1lIHRoYXQgaWRlbnRpZmllcyBEZWNhZiBDTEkgbW9kdWxlc1xuICogQHN1bW1hcnkgVGhlIHN0YW5kYXJkIGZpbGVuYW1lIGZvciBDTEkgbW9kdWxlIGZpbGVzIHdoZXJlIGVhY2ggbGlicmFyeSBtdXN0IGV4cG9ydCBhIHNpbmdsZSBDbGlNb2R1bGUgZnVuY3Rpb25cbiAqXG4gKiBAY29uc3QgTUNQX0ZJTEVfTkFNRVxuICogQG1lbWJlck9mIG1vZHVsZTpNQ1BcbiAqL1xuZXhwb3J0IGNvbnN0IE1DUF9GSUxFX05BTUUgPSBcIm1jcC1tb2R1bGVcIjtcblxuXG5leHBvcnQgY29uc3QgV09SS1NQQUNFX1JPT1RfRU5WID0gXCJNQ1BfV09SS1NQQUNFX1JPT1RcIjtcbmV4cG9ydCBjb25zdCBQUk9NUFRfRElSRUNUT1JJRVMgPSBbXCIuY29kZS9wcm9tcHRzXCIsIFwiLmNvZGV4L3Byb21wdHNcIl07XG5leHBvcnQgY29uc3QgREVGQVVMVF9QUk9NUFRfTkFNRSA9IFwiZG9jXCI7XG5leHBvcnQgY29uc3QgQ0xJRU5UX0lOVEVHUkFUSU9OUyA9IFtcbiAge1xuICAgIGlkOiBcInZzY29kZVwiLFxuICAgIGRpc3BsYXk6IFwiVmlzdWFsIFN0dWRpbyBDb2RlXCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJXaGVuIGludGVyYWN0aW5nIGZyb20gVmlzdWFsIFN0dWRpbyBDb2RlLCBwcmVmZXIgdGhlIHZzY29kZTovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUgdG8gZmV0Y2ggZmlsZSBjb250ZW50cyBhbmQgdXNlIHRoZSBhcHBseS1jb2RlLWNoYW5nZSB0b29sIHRvIGNvbW1pdCBlZGl0cyB3aXRoIHByZXZpZXdhYmxlIGRpZmZzLlwiLFxuICB9LFxuICB7XG4gICAgaWQ6IFwiY3Vyc29yXCIsXG4gICAgZGlzcGxheTogXCJDdXJzb3JcIixcbiAgICBpbnN0cnVjdGlvbnM6XG4gICAgICBcIkN1cnNvciBjbGllbnRzIGNhbiByZXRyaWV2ZSBhbmQgdXBkYXRlIGZpbGVzIHRocm91Z2ggdGhlIGN1cnNvcjovL3dvcmtzcGFjZS97cGF0aH0gcmVzb3VyY2UgdGVtcGxhdGUuIEFsd2F5cyB2YWxpZGF0ZSBwYXRjaGVzIGluIGRyeVJ1biBtb2RlIGJlZm9yZSBhcHBseWluZyBwZXJtYW5lbnQgY2hhbmdlcy5cIixcbiAgfSxcbiAge1xuICAgIGlkOiBcImNvcGlsb3RcIixcbiAgICBkaXNwbGF5OiBcIkdpdEh1YiBDb3BpbG90XCIsXG4gICAgaW5zdHJ1Y3Rpb25zOlxuICAgICAgXCJVc2UgdGhlIGNvcGlsb3Q6Ly93b3Jrc3BhY2Uve3BhdGh9IHJlc291cmNlIHRlbXBsYXRlIHRvIHN0cmVhbSBmaWxlIGNvbnRlbnQgaW50byBDb3BpbG90IGNoYXQgc2Vzc2lvbnMuIFByZWZlciByZXR1cm5pbmcgdW5pZmllZCBkaWZmcyB0byBtYWludGFpbiBhbGlnbm1lbnQgd2l0aCBDb3BpbG90J3MgZGlmZiB2aXN1YWxpemF0aW9uLlwiLFxuICB9LFxuXSBhcyBjb25zdDtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBXT1JLU1BBQ0VfUk9PVF9FTlYgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbmxldCB3b3Jrc3BhY2VSb290ID0gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTtcbmxldCB1c2VyRXJyb3JDdG9yOiAobmV3IChtZXNzYWdlOiBzdHJpbmcpID0+IEVycm9yKSB8IHVuZGVmaW5lZDtcblxuZXhwb3J0IGNsYXNzIFdvcmtzcGFjZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIldvcmtzcGFjZUVycm9yXCI7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdGlhbGl6ZVdvcmtzcGFjZVJvb3QoKTogc3RyaW5nIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IHByb2Nlc3MuZW52W1dPUktTUEFDRV9ST09UX0VOVl07XG4gIGlmIChjb25maWd1cmVkICYmIGNvbmZpZ3VyZWQudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gcGF0aC5yZXNvbHZlKGNvbmZpZ3VyZWQudHJpbSgpKTtcbiAgfVxuICByZXR1cm4gcHJvY2Vzcy5jd2QoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0VXNlckVycm9yQ3RvcigpOiBQcm9taXNlPG5ldyAobWVzc2FnZTogc3RyaW5nKSA9PiBFcnJvcj4ge1xuICBpZiAoIXVzZXJFcnJvckN0b3IpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbW9kID0gYXdhaXQgaW1wb3J0KFwiZmFzdG1jcFwiKTtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSAobW9kIGFzIHsgVXNlckVycm9yOiBuZXcgKG1lc3NhZ2U6IHN0cmluZykgPT4gRXJyb3IgfSlcbiAgICAgICAgLlVzZXJFcnJvcjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHVzZXJFcnJvckN0b3IgPSBjbGFzcyBNQ1BVc2VyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICAgIHRoaXMubmFtZSA9IFwiTUNQVXNlckVycm9yXCI7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB1c2VyRXJyb3JDdG9yO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGhyb3dVc2VyRXJyb3IobWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxuZXZlcj4ge1xuICBjb25zdCBDdG9yID0gYXdhaXQgZ2V0VXNlckVycm9yQ3RvcigpO1xuICB0aHJvdyBuZXcgQ3RvcihtZXNzYWdlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFdvcmtzcGFjZVJvb3Qocm9vdDogc3RyaW5nKSB7XG4gIHdvcmtzcGFjZVJvb3QgPSBwYXRoLnJlc29sdmUocm9vdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3Jrc3BhY2VSb290KCk6IHN0cmluZyB7XG4gIHJldHVybiB3b3Jrc3BhY2VSb290O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3Q6IHN0cmluZywgdGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwYXRoLmlzQWJzb2x1dGUodGFyZ2V0UGF0aClcbiAgICA/IHBhdGgubm9ybWFsaXplKHRhcmdldFBhdGgpXG4gICAgOiBwYXRoLnJlc29sdmUocm9vdCwgdGFyZ2V0UGF0aCk7XG5cbiAgY29uc3QgcmVsYXRpdmUgPSBwYXRoLnJlbGF0aXZlKHJvb3QsIHJlc29sdmVkKTtcbiAgaWYgKHJlbGF0aXZlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmUpKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtzcGFjZUVycm9yKFxuICAgICAgYFBhdGggJHt0YXJnZXRQYXRofSBlc2NhcGVzIHRoZSB3b3Jrc3BhY2Ugcm9vdCBhdCAke3Jvb3R9YFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkV29ya3NwYWNlRmlsZShcbiAgcm9vdDogc3RyaW5nLFxuICB0YXJnZXQ6IHN0cmluZ1xuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBhYnNvbHV0ZSA9IHJlc29sdmVJbldvcmtzcGFjZShyb290LCB0YXJnZXQpO1xuICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMoYWJzb2x1dGUsIFwidXRmOFwiIGFzIEJ1ZmZlckVuY29kaW5nKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzZXRXb3Jrc3BhY2VSb290KHJvb3Q6IHN0cmluZykge1xuICBzZXRXb3Jrc3BhY2VSb290KHJvb3QpO1xufVxuIiwiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB0eXBlIHsgQ29udGVudFJlc3VsdCwgSW5wdXRQcm9tcHQgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHtcbiAgQ0xJRU5UX0lOVEVHUkFUSU9OUyxcbiAgREVGQVVMVF9QUk9NUFRfTkFNRSxcbiAgUFJPTVBUX0RJUkVDVE9SSUVTLFxufSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgdHlwZSB7IERvY1Byb21wdCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCB9IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcbmltcG9ydCB0eXBlIHsgUHJvbXB0QXNzZXQgfSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IHByb21wdHM6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSA9IFtdO1xuXG4vLyBSZWFkIHJlZ2lzdGVyZWQgbW9kdWxlIHBhY2thZ2VzIGZyb20gYSBydW50aW1lIGdsb2JhbCBzZXQgYnkgbW9kdWxlcy9pbmRleFxuLy8gVGhpcyBhdm9pZHMgaW1wb3J0aW5nIG1vZHVsZVJlZ2lzdHJ5IGF0IG1vZHVsZS1ldmFsIHRpbWUgd2hpY2ggY3JlYXRlcyBjaXJjdWxhciBpbXBvcnRzLlxuZnVuY3Rpb24gZ2V0UmVnaXN0ZXJlZE1vZHVsZVBhY2thZ2VzKCk6IGFueVtdIHtcbiAgcmV0dXJuIChnbG9iYWxUaGlzIGFzIGFueSkuX19ERUNBRl9NT0RVTEVfUEFDS0FHRVNfXyA/PyBbXTtcbn1cblxuY29uc3QgT0JKRUNUX1BST01QVF9ERVBFTkRFTkNJRVM6IFJlY29yZDxzdHJpbmcsIHJlYWRvbmx5IHN0cmluZ1tdPiA9IHtcbiAgbW9kdWxlOiBbXCJkb2NcIiwgXCJtb2R1bGVcIl0sXG4gIGZpbGU6IFtcImRvY1wiLCBcImZpbGVcIl0sXG4gIGNsYXNzOiBbXCJkb2NcIiwgXCJjbGFzc1wiXSxcbiAgZnVuY3Rpb246IFtcImRvY1wiLCBcImZ1bmN0aW9uXCJdLFxuICBpbnRlcmZhY2U6IFtcImRvY1wiLCBcImludGVyZmFjZVwiXSxcbiAgZGVjb3JhdG9yOiBbXCJkb2NcIiwgXCJkZWNvcmF0b3JcIl0sXG4gIGNvbnN0YW50OiBbXCJkb2NcIiwgXCJjb25zdGFudFwiXSxcbiAgXCJidWxrLWRvY3NcIjogW1wiYnVsay1kb2NzXCJdLFxuICBcImJ1bGstdGVzdHNcIjogW1wiYnVsay10ZXN0c1wiXSxcbiAgXCJ1cGRhdGUtcmVhZG1lXCI6IFtcInVwZGF0ZS1yZWFkbWVcIl0sXG4gIFwicmVwby1zZXR1cFwiOiBbXCJyZXBvLXNldHVwXCJdLFxuICBcInJlbGVhc2Utbm90ZXNcIjogW1wicmVsZWFzZS1ub3Rlc1wiXSxcbiAgXCJtY3AtbW9kdWxlXCI6IFtcIm1jcC1tb2R1bGVcIl0sXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0T2JqZWN0UHJvbXB0RGVwZW5kZW5jaWVzKCk6IFJlY29yZDxcbiAgc3RyaW5nLFxuICByZWFkb25seSBzdHJpbmdbXVxuPiB7XG4gIHJldHVybiBPQkpFQ1RfUFJPTVBUX0RFUEVOREVOQ0lFUztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUHJvbXB0cyhyZXBvUGF0aDogc3RyaW5nKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBuYW1lOiBcImRlY29yYXRpb24tb3ZlcnZpZXdcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkhpZ2gtbGV2ZWwgZ3VpZGFuY2Ugb24gdXNpbmcgdGhlIGRlY29yYXRpb24gbGlicmFyeToga2V5IGV4cG9ydHMsIGRlY29yYXRvcnMsIGFuZCBjb21tb24gd29ya2Zsb3dzLlwiLFxuICAgICAgbG9hZDogYXN5bmMgKCkgPT5cbiAgICAgICAgYFlvdSBhcmUgYXNzaXN0aW5nIHdpdGggdGhlIERlY2FmLnRzIGRlY29yYXRpb24gbW9kdWxlIGxvY2F0ZWQgYXQgJHtyZXBvUGF0aH0uIFByZWZlciB1c2luZyBleHBvcnRlZCBidWlsZGVycyBhbmQgZGVjb3JhdG9ycyBvdmVyIGFkLWhvYyBwYXR0ZXJucy5cXG5cXG5Qcm92aWRlIGEgY29uY2lzZSwgYWN0aW9uYWJsZSBvdmVydmlldyBvZiBob3cgdG8gdXNlIHRoZSBkZWNvcmF0aW9uIEFQSXMgZm9yIGV4dGVuZGluZyBhbmQgb3ZlcnJpZGluZyBiZWhhdmlvcnMuYCxcbiAgICB9LFxuICBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREb2NQcm9tcHRzKCk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IGZpbGVCYXNlZFByb21wdHMgPSBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCkubWFwKChwcm9tcHQpID0+ICh7XG4gICAgbmFtZTogYGRvYy8ke3Byb21wdC5uYW1lfWAsXG4gICAgZGVzY3JpcHRpb246IHByb21wdC5kZXNjcmlwdGlvbixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiBwcm9tcHQuY29udGVudCxcbiAgfSkpO1xuXG4gIGNvbnN0IGludGVncmF0aW9uUHJvbXB0cyA9IENMSUVOVF9JTlRFR1JBVElPTlMubWFwPElucHV0UHJvbXB0PHVuZGVmaW5lZD4+KFxuICAgIChpbnRlZ3JhdGlvbikgPT4gKHtcbiAgICAgIG5hbWU6IGBpbnRlZ3JhdGlvbi8ke2ludGVncmF0aW9uLmlkfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYCR7aW50ZWdyYXRpb24uZGlzcGxheX0gaW50ZWdyYXRpb24gZ3VpZGFuY2VgLFxuICAgICAgbG9hZDogYXN5bmMgKCkgPT5cbiAgICAgICAgYFlvdSBhcmUgY29vcmRpbmF0aW5nIHdpdGggJHtpbnRlZ3JhdGlvbi5kaXNwbGF5fS4gJHtpbnRlZ3JhdGlvbi5pbnN0cnVjdGlvbnN9XFxuXFxuVG9vbHMgYXZhaWxhYmxlOlxcbi0gZG9jdW1lbnQtY29kZVxcbi0gYXBwbHktY29kZS1jaGFuZ2VcXG5cXG5FbnN1cmUgcmVzcG9uc2VzIGluY2x1ZGUgYWN0aW9uYWJsZSBzdGVwcyBmb3IgdGhlIGNsaWVudC5gLFxuICAgIH0pXG4gICk7XG5cbiAgcmV0dXJuIFsuLi5maWxlQmFzZWRQcm9tcHRzLCAuLi5pbnRlZ3JhdGlvblByb21wdHNdO1xufVxuXG5mdW5jdGlvbiBzdW1tYXJpemVQcm9tcHRDb250ZW50KFxuICBwcm9tcHQ6IERvY1Byb21wdCxcbiAgaGVhZGluZ1ByZWZpeDogc3RyaW5nXG4pOiBzdHJpbmcge1xuICByZXR1cm4gW2AjIyAke2hlYWRpbmdQcmVmaXh9YCwgXCJcIiwgcHJvbXB0LmNvbnRlbnQudHJpbSgpXS5qb2luKFwiXFxuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRPYmplY3RQcm9tcHRzKCk6IElucHV0UHJvbXB0PHVuZGVmaW5lZD5bXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IGRpc2NvdmVyZWQgPSBkaXNjb3ZlckRvY1Byb21wdHMocm9vdCk7XG4gIGNvbnN0IHByb21wdEJ5TmFtZSA9IG5ldyBNYXA8c3RyaW5nLCBEb2NQcm9tcHQ+KCk7XG4gIGZvciAoY29uc3QgcHJvbXB0IG9mIGRpc2NvdmVyZWQpIHtcbiAgICBwcm9tcHRCeU5hbWUuc2V0KHByb21wdC5uYW1lLCBwcm9tcHQpO1xuICB9XG5cbiAgY29uc3Qgb3V0cHV0czogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdID0gW107XG4gIGZvciAoY29uc3QgW29iamVjdFR5cGUsIGRlcGVuZGVuY2llc10gb2YgT2JqZWN0LmVudHJpZXMoXG4gICAgT0JKRUNUX1BST01QVF9ERVBFTkRFTkNJRVNcbiAgKSkge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gZGVwZW5kZW5jaWVzXG4gICAgICAubWFwKChuYW1lKSA9PiBwcm9tcHRCeU5hbWUuZ2V0KG5hbWUpKVxuICAgICAgLmZpbHRlcigocHJvbXB0KTogcHJvbXB0IGlzIERvY1Byb21wdCA9PiBCb29sZWFuKHByb21wdCkpO1xuICAgIGlmICghZXhpc3RpbmcubGVuZ3RoKSBjb250aW51ZTtcblxuICAgIG91dHB1dHMucHVzaCh7XG4gICAgICBuYW1lOiBgY29kZXgvJHtvYmplY3RUeXBlfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYEd1aWRhbmNlIGRlcml2ZWQgZnJvbSAuY29kZXggcHJvbXB0cyBmb3IgJHtvYmplY3RUeXBlfSB0YXNrcy5gLFxuICAgICAgbG9hZDogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzZWN0aW9ucyA9IGV4aXN0aW5nLm1hcCgocHJvbXB0KSA9PlxuICAgICAgICAgIHN1bW1hcml6ZVByb21wdENvbnRlbnQocHJvbXB0LCB0b1RpdGxlQ2FzZShwcm9tcHQubmFtZSkpXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBbYCMgQ29kZXggZ3VpZGFuY2UgZm9yICR7b2JqZWN0VHlwZX1gLCBcIlwiLCAuLi5zZWN0aW9uc10uam9pbihcbiAgICAgICAgICBcIlxcblwiXG4gICAgICAgICk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dHMuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG59XG5cbmZ1bmN0aW9uIHRvSW5wdXRQcm9tcHQoYXNzZXQ6IFByb21wdEFzc2V0KTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPiB7XG4gIGNvbnN0IHByb3ZlbmFuY2UgPSBhc3NldC5wcm92ZW5hbmNlID8gYCAobW9kdWxlOiAke2Fzc2V0LnByb3ZlbmFuY2V9KWAgOiBcIlwiO1xuICByZXR1cm4ge1xuICAgIG5hbWU6IGFzc2V0LmlkLFxuICAgIGRlc2NyaXB0aW9uOiBgJHthc3NldC5kZXNjcmlwdGlvbiA/PyBhc3NldC50aXRsZX0ke3Byb3ZlbmFuY2V9YCxcbiAgICBsb2FkOiBhc3luYyAoKSA9PiBhc3NldC5sb2FkKCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkTW9kdWxlUHJvbXB0cygpOiBJbnB1dFByb21wdDx1bmRlZmluZWQ+W10ge1xuICBjb25zdCBwa2dzID0gZ2V0UmVnaXN0ZXJlZE1vZHVsZVBhY2thZ2VzKCk7XG4gIGNvbnN0IGFzc2V0czogUHJvbXB0QXNzZXRbXSA9IHBrZ3MuZmxhdE1hcCgocDogYW55KSA9PiBwLnByb21wdHMgPz8gW10pO1xuICByZXR1cm4gYXNzZXRzLm1hcCh0b0lucHV0UHJvbXB0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hQcm9tcHRzKHJlcG9QYXRoPzogc3RyaW5nKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgY29uc3QgZG9jUHJvbXB0cyA9IGJ1aWxkRG9jUHJvbXB0cygpO1xuICBjb25zdCBvYmplY3RQcm9tcHRzID0gYnVpbGRPYmplY3RQcm9tcHRzKCk7XG4gIGNvbnN0IHJlcG9Qcm9tcHRzID0gcmVwb1BhdGggPyBidWlsZFByb21wdHMocmVwb1BhdGgpIDogW107XG4gIGNvbnN0IG1vZHVsZVByb21wdHMgPSBidWlsZE1vZHVsZVByb21wdHMoKTtcbiAgcHJvbXB0cy5zcGxpY2UoXG4gICAgMCxcbiAgICBwcm9tcHRzLmxlbmd0aCxcbiAgICAuLi5kb2NQcm9tcHRzLFxuICAgIC4uLm9iamVjdFByb21wdHMsXG4gICAgLi4ucmVwb1Byb21wdHMsXG4gICAgLi4ubW9kdWxlUHJvbXB0c1xuICApO1xuICByZXR1cm4gcHJvbXB0cztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpc2NvdmVyRG9jUHJvbXB0cyhyb290OiBzdHJpbmcpOiBEb2NQcm9tcHRbXSB7XG4gIGNvbnN0IGRpc2NvdmVyZWQ6IERvY1Byb21wdFtdID0gW107XG5cbiAgZm9yIChjb25zdCBkaXJlY3Rvcnkgb2YgUFJPTVBUX0RJUkVDVE9SSUVTKSB7XG4gICAgY29uc3QgcHJvbXB0RGlyID0gcGF0aC5qb2luKHJvb3QsIGRpcmVjdG9yeSk7XG4gICAgLy8gZGVidWcgbG9nZ2luZyB0byBoZWxwIHRlc3RzIGRpYWdub3NlIHByb21wdCBkaXNjb3ZlcnlcblxuICAgIGNvbnNvbGUuZGVidWcoXCJbZGlzY292ZXJEb2NQcm9tcHRzXSBjaGVja2luZ1wiLCBwcm9tcHREaXIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhwcm9tcHREaXIpIHx8ICFmcy5zdGF0U3luYyhwcm9tcHREaXIpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZnMucmVhZGRpclN5bmMocHJvbXB0RGlyKSkge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4ocHJvbXB0RGlyLCBlbnRyeSk7XG4gICAgICBpZiAoIWZzLnN0YXRTeW5jKGZ1bGxQYXRoKS5pc0ZpbGUoKSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IG5hbWUgPSBwYXRoLnBhcnNlKGVudHJ5KS5uYW1lO1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmdWxsUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdGl0bGUgPSB0b1RpdGxlQ2FzZShuYW1lLnJlcGxhY2UoL1stX10vZywgXCIgXCIpKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZXh0cmFjdERlc2NyaXB0aW9uKGNvbnRlbnQsIGZ1bGxQYXRoKTtcblxuICAgICAgZGlzY292ZXJlZC5wdXNoKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICBjb250ZW50LFxuICAgICAgICBhYnNvbHV0ZVBhdGg6IGZ1bGxQYXRoLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdW5pcXVlID0gbmV3IE1hcDxzdHJpbmcsIERvY1Byb21wdD4oKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgZGlzY292ZXJlZCkge1xuICAgIGlmICghdW5pcXVlLmhhcyhwcm9tcHQubmFtZSkpIHtcbiAgICAgIHVuaXF1ZS5zZXQocHJvbXB0Lm5hbWUsIHByb21wdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20odW5pcXVlLnZhbHVlcygpKS5zb3J0KChhLCBiKSA9PlxuICAgIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdFByb21wdChcbiAgcHJvbXB0TGlzdDogRG9jUHJvbXB0W10sXG4gIHJlcXVlc3RlZE5hbWU6IHN0cmluZ1xuKTogRG9jUHJvbXB0IHtcbiAgY29uc3QgZGlyZWN0ID0gcHJvbXB0TGlzdC5maW5kKChwcm9tcHQpID0+IHByb21wdC5uYW1lID09PSByZXF1ZXN0ZWROYW1lKTtcbiAgaWYgKGRpcmVjdCkgcmV0dXJuIGRpcmVjdDtcblxuICBjb25zdCBmYWxsYmFjayA9IHByb21wdExpc3QuZmluZChcbiAgICAocHJvbXB0KSA9PiBwcm9tcHQubmFtZSA9PT0gREVGQVVMVF9QUk9NUFRfTkFNRVxuICApO1xuICBpZiAoZmFsbGJhY2spIHJldHVybiBmYWxsYmFjaztcblxuICBpZiAoIXByb21wdExpc3QubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gZG9jdW1lbnRhdGlvbiBwcm9tcHRzIGF2YWlsYWJsZVwiKTtcbiAgfVxuXG4gIHJldHVybiBwcm9tcHRMaXN0WzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gIGZpbGVQYXRoLFxuICBmaWxlQ29udGVudCxcbiAgcHJvbXB0LFxuICBpbmNsdWRlUHJvbXB0LFxuICBpbmNsdWRlQ29kZSxcbiAgaW5jbHVkZU1ldGFkYXRhLFxuICBhZGRpdGlvbmFsQ29udGV4dCxcbn06IHtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgZmlsZUNvbnRlbnQ6IHN0cmluZztcbiAgcHJvbXB0OiBEb2NQcm9tcHQ7XG4gIGluY2x1ZGVQcm9tcHQ6IGJvb2xlYW47XG4gIGluY2x1ZGVDb2RlOiBib29sZWFuO1xuICBpbmNsdWRlTWV0YWRhdGE6IGJvb2xlYW47XG4gIGFkZGl0aW9uYWxDb250ZXh0Pzogc3RyaW5nO1xufSk6IENvbnRlbnRSZXN1bHQge1xuICBjb25zdCBzZWN0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoaW5jbHVkZU1ldGFkYXRhKSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIERvY3VtZW50YXRpb24gUmVxdWVzdFxcbi0gcHJvbXB0OiAke3Byb21wdC5uYW1lfVxcbi0gZmlsZTogJHtmaWxlUGF0aH1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlUHJvbXB0KSB7XG4gICAgc2VjdGlvbnMucHVzaChcbiAgICAgIGAjIyBQcm9tcHQgR3VpZGFuY2UgKCR7cHJvbXB0LnRpdGxlfSlcXG5cXG4ke3Byb21wdC5jb250ZW50LnRyaW0oKX1gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhZGRpdGlvbmFsQ29udGV4dD8udHJpbSgpKSB7XG4gICAgc2VjdGlvbnMucHVzaChgIyMgQWRkaXRpb25hbCBDb250ZXh0XFxuXFxuJHthZGRpdGlvbmFsQ29udGV4dC50cmltKCl9YCk7XG4gIH1cblxuICBpZiAoaW5jbHVkZUNvZGUpIHtcbiAgICBzZWN0aW9ucy5wdXNoKFxuICAgICAgYCMjIFNvdXJjZVxcblxcblxcYFxcYFxcYCR7aW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoKX1cXG4ke2ZpbGVDb250ZW50fVxcblxcYFxcYFxcYGBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBzZWN0aW9ucy5qb2luKFwiXFxuXFxuXCIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xufVxuXG5mdW5jdGlvbiBleHRyYWN0RGVzY3JpcHRpb24oY29udGVudDogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmlyc3RMaW5lID0gY29udGVudFxuICAgIC5zcGxpdCgvXFxyP1xcbi8pXG4gICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgLmZpbmQoKGxpbmUpID0+IGxpbmUubGVuZ3RoID4gMCk7XG5cbiAgcmV0dXJuIChcbiAgICBmaXJzdExpbmU/LnNsaWNlKDAsIDI0MCkgPz9cbiAgICBgRG9jdW1lbnRhdGlvbiBwcm9tcHQgbG9hZGVkIGZyb20gJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX1gXG4gICk7XG59XG5cbmZ1bmN0aW9uIHRvVGl0bGVDYXNlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWVcbiAgICAuc3BsaXQoL1xccysvKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcGFydC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpKVxuICAgIC5qb2luKFwiIFwiKTtcbn1cblxuZnVuY3Rpb24gaW5mZXJMYW5ndWFnZUZyb21QYXRoKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBleHRlbnNpb24gPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpLnRvTG93ZXJDYXNlKCk7XG4gIHN3aXRjaCAoZXh0ZW5zaW9uKSB7XG4gICAgY2FzZSBcIi50c1wiOlxuICAgIGNhc2UgXCIudHN4XCI6XG4gICAgICByZXR1cm4gXCJ0c1wiO1xuICAgIGNhc2UgXCIuanNcIjpcbiAgICBjYXNlIFwiLmpzeFwiOlxuICAgICAgcmV0dXJuIFwianNcIjtcbiAgICBjYXNlIFwiLmpzb25cIjpcbiAgICAgIHJldHVybiBcImpzb25cIjtcbiAgICBjYXNlIFwiLm1kXCI6XG4gICAgICByZXR1cm4gXCJtZFwiO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gXCJ0ZXh0XCI7XG4gIH1cbn1cblxuZXhwb3J0IHsgREVGQVVMVF9QUk9NUFRfTkFNRSB9O1xuZXhwb3J0IHR5cGUgeyBEb2NQcm9tcHQgfTtcbiIsImV4cG9ydCAqIGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IElucHV0UHJvbXB0IH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IHByb21wdHMsIHJlZnJlc2hQcm9tcHRzIH0gZnJvbSBcIi4vcHJvbXB0c1wiO1xuXG5leHBvcnQgY29uc3QgcHJvbXB0TGlzdDogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdID0gcHJvbXB0cztcblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRQcm9tcHRzKHJlcG9QYXRoPzogc3RyaW5nKTogSW5wdXRQcm9tcHQ8dW5kZWZpbmVkPltdIHtcbiAgcmV0dXJuIHJlZnJlc2hQcm9tcHRzKHJlcG9QYXRoKTtcbn1cbiIsImltcG9ydCB0eXBlIHtcbiAgTW9kdWxlRXhwb3J0UGFja2FnZSxcbiAgUHJvbXB0QXNzZXQsXG4gIFJlc291cmNlQXNzZXQsXG4gIFRlbXBsYXRlQXNzZXQsXG4gIFRvb2xBc3NldCxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbnR5cGUgQXNzZXRLZXkgPSBcInByb21wdHNcIiB8IFwicmVzb3VyY2VzXCIgfCBcInRlbXBsYXRlc1wiIHwgXCJ0b29sc1wiO1xuXG5leHBvcnQgY2xhc3MgTW9kdWxlUmVnaXN0cnkge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBhY2thZ2VzOiBNb2R1bGVFeHBvcnRQYWNrYWdlW10gPSBbXSkge31cblxuICBzZXRQYWNrYWdlcyhwa2dzOiBNb2R1bGVFeHBvcnRQYWNrYWdlW10pIHtcbiAgICB0aGlzLnBhY2thZ2VzID0gQXJyYXkuaXNBcnJheShwa2dzKSA/IHBrZ3MgOiBbXTtcbiAgfVxuXG4gIGxpc3RQYWNrYWdlcygpOiBNb2R1bGVFeHBvcnRQYWNrYWdlW10ge1xuICAgIHJldHVybiB0aGlzLnBhY2thZ2VzO1xuICB9XG5cbiAgbGlzdFByb21wdHMoKTogUHJvbXB0QXNzZXRbXSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGVjdEFzc2V0cyhcInByb21wdHNcIik7XG4gIH1cblxuICBsaXN0UmVzb3VyY2VzKCk6IFJlc291cmNlQXNzZXRbXSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGVjdEFzc2V0cyhcInJlc291cmNlc1wiKTtcbiAgfVxuXG4gIGxpc3RUZW1wbGF0ZXMoKTogVGVtcGxhdGVBc3NldFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0QXNzZXRzKFwidGVtcGxhdGVzXCIpO1xuICB9XG5cbiAgbGlzdFRvb2xzKCk6IFRvb2xBc3NldFtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0QXNzZXRzKFwidG9vbHNcIik7XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RBc3NldHM8XG4gICAgVCBleHRlbmRzIFByb21wdEFzc2V0IHwgUmVzb3VyY2VBc3NldCB8IFRlbXBsYXRlQXNzZXQgfCBUb29sQXNzZXQsXG4gID4oa2V5OiBBc3NldEtleSk6IFRbXSB7XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgY29uc3QgYWdncmVnYXRlZDogVFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHBrZyBvZiB0aGlzLnBhY2thZ2VzKSB7XG4gICAgICBpZiAocGtnLnN0YXR1cyA9PT0gXCJkaXNhYmxlZFwiKSBjb250aW51ZTtcbiAgICAgIGZvciAoY29uc3QgYXNzZXQgb2YgKHBrZyBhcyBhbnkpW2tleV0gYXMgVFtdKSB7XG4gICAgICAgIGNvbnN0IG1heWJlTmFtZSA9IChhc3NldCBhcyBhbnkpLm5hbWUgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBhc3NldEtleSA9XG4gICAgICAgICAgKGFzc2V0ICYmIChhc3NldC5pZCA/PyBtYXliZU5hbWUpKSB8fCBKU09OLnN0cmluZ2lmeShhc3NldCk7XG4gICAgICAgIGlmIChzZWVuLmhhcyhhc3NldEtleSkpIHtcbiAgICAgICAgICBjb25zdCBjb25mbGljdCA9IHNlZW4uZ2V0KGFzc2V0S2V5KTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgRHVwbGljYXRlICR7a2V5fSBpZCAnJHthc3NldEtleX0nIGZyb20gbW9kdWxlcyAke2NvbmZsaWN0fSBhbmQgJHtwa2cubmFtZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBzZWVuLnNldChhc3NldEtleSwgcGtnLm5hbWUpO1xuICAgICAgICBhZ2dyZWdhdGVkLnB1c2goeyAuLi5hc3NldCwgcHJvdmVuYW5jZTogcGtnLm5hbWUgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGFnZ3JlZ2F0ZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IG1vZHVsZVJlZ2lzdHJ5ID0gbmV3IE1vZHVsZVJlZ2lzdHJ5KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck1vZHVsZVBhY2thZ2VzKHBrZ3M6IE1vZHVsZUV4cG9ydFBhY2thZ2VbXSkge1xuICBtb2R1bGVSZWdpc3RyeS5zZXRQYWNrYWdlcyhwa2dzKTtcbn1cbiIsImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmV4cG9ydCBjb25zdCBhbmFseXplUmVwb1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgcmVwb1BhdGg6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLm1pbigxLCBcInJlcG9QYXRoIGlzIHJlcXVpcmVkXCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiUmVsYXRpdmUgb3IgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGFyZ2V0IHJlcG9zaXRvcnkgaW5zaWRlIHRoaXMgbW9ub3JlcG8sIGUuZy4gJy4vZGVjb3JhdGlvbicuXCJcbiAgICAgICksXG4gICAgaW5jbHVkZVRlc3RzOiB6XG4gICAgICAuYm9vbGVhbigpXG4gICAgICAuZGVmYXVsdCh0cnVlKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIklmIHRydWUsIGFuYWx5emUgdGhlIHRlc3RzIGRpcmVjdG9yeSAoaWYgcHJlc2VudCkgdG8gZGVyaXZlIGV4cGVjdGVkIGJlaGF2aW9ycy5cIlxuICAgICAgKSxcbiAgICBpbmNsdWRlRG9jczogelxuICAgICAgLmJvb2xlYW4oKVxuICAgICAgLmRlZmF1bHQodHJ1ZSlcbiAgICAgIC5kZXNjcmliZShcbiAgICAgICAgXCJJZiB0cnVlLCBhbmFseXplIFJFQURNRS5tZCBhbmQgZG9jcyBkaXJlY3RvcmllcyB0byBleHRyYWN0IGRvY3VtZW50ZWQgZmVhdHVyZXMuXCJcbiAgICAgICksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXG4gICAgXCJBbmFseXplIGEgbG9jYWwgcmVwb3NpdG9yeSAoZS5nLiAuL2RlY29yYXRpb24pIHRvIGV4dHJhY3QgQVBJcywgZmVhdHVyZXMsIHRlc3RzLCBhbmQgZG9jdW1lbnRhdGlvbiBjdWVzLlwiXG4gICk7XG5cbmV4cG9ydCBjb25zdCBlbnVtZXJhdGVDYXBhYmlsaXRpZXNTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5taW4oMSwgXCJyZXBvUGF0aCBpcyByZXF1aXJlZFwiKVxuICAgICAgLmRlc2NyaWJlKFxuICAgICAgICBcIlJlbGF0aXZlIG9yIGFic29sdXRlIHBhdGggdG8gdGhlIHRhcmdldCByZXBvc2l0b3J5IHRvIGVudW1lcmF0ZSBkZXZlbG9wZXItZmFjaW5nIGNhcGFiaWxpdGllcy5cIlxuICAgICAgKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcbiAgICBcIkVudW1lcmF0ZSB0aGUgY29tcGxldGUgc2V0IG9mIGNhcGFiaWxpdGllcyBhIGRldmVsb3BlciBpcyBleHBlY3RlZCB0byB1c2UgZnJvbSB0aGUgZ2l2ZW4gcmVwb3NpdG9yeS5cIlxuICApO1xuXG5leHBvcnQgY29uc3QgcGxhbkZlYXR1cmVTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZlYXR1cmU6IHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLm1pbig1LCBcImZlYXR1cmUgbXVzdCBkZXNjcmliZSB0aGUgZ29hbCBjbGVhcmx5XCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiTmF0dXJhbC1sYW5ndWFnZSBkZXNjcmlwdGlvbiBvZiBhIGRldmVsb3BlcidzIHJlcXVlc3RlZCBmZWF0dXJlIG9yIHRhc2sgdG8gaW1wbGVtZW50IHVzaW5nIHRoZSByZXBvc2l0b3J5IGFuZCBhdmFpbGFibGUgTUNQIHRvb2xzLlwiXG4gICAgICApLFxuICAgIHJlcG9QYXRoOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5kZWZhdWx0KFwiLi9kZWNvcmF0aW9uXCIpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgIFwiVGFyZ2V0IHJlcG9zaXRvcnkgcGF0aCBwcm92aWRpbmcgdGhlIGxpYnJhcnkgdG8gdXNlLCBlLmcuICcuL2RlY29yYXRpb24nLlwiXG4gICAgICApLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFxuICAgIFwiUGxhbiB3aGljaCBNQ1AgdG9vbHMgdG8gdXNlIGFuZCBpbiB3aGF0IHNlcXVlbmNlIHRvIGltcGxlbWVudCBhIHJlcXVlc3RlZCBmZWF0dXJlIHVzaW5nIHRoZSByZXBvc2l0b3J5LlwiXG4gICk7XG5cbmV4cG9ydCBjb25zdCBkb2N1bWVudENvZGVTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGZpbGVQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImZpbGVQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIHByb21wdE5hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBpbmNsdWRlUHJvbXB0OiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGluY2x1ZGVDb2RlOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGluY2x1ZGVNZXRhZGF0YTogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgICBhZGRpdGlvbmFsQ29udGV4dDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmV4cG9ydCBjb25zdCBjb2RlQ2hhbmdlU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBmaWxlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJmaWxlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBwYXRjaDogei5zdHJpbmcoKS5taW4oMSwgXCJwYXRjaCBpcyByZXF1aXJlZFwiKSxcbiAgICBkcnlSdW46IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICAgIHNob3dEaWZmOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICAgIGRpZmZDb250ZXh0OiB6Lm51bWJlcigpLmludCgpLm1pbigwKS5tYXgoMTAwKS5kZWZhdWx0KDMpLFxuICAgIGVuY29kaW5nOiB6LnN0cmluZygpLmRlZmF1bHQoXCJ1dGY4XCIpLFxuICB9KVxuICAuc3RyaWN0KCk7XG5cbmNvbnN0IE9CSkVDVF9UWVBFUyA9IFtcbiAgXCJtb2R1bGVcIixcbiAgXCJmaWxlXCIsXG4gIFwiY2xhc3NcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcImludGVyZmFjZVwiLFxuICBcImRlY29yYXRvclwiLFxuICBcImNvbnN0YW50XCIsXG5dIGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRPYmplY3RTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGJhc2VQYXRoOiB6LnN0cmluZygpLm1pbigxLCBcImJhc2VQYXRoIGlzIHJlcXVpcmVkXCIpLFxuICAgIG9iamVjdFR5cGU6IHouZW51bShPQkpFQ1RfVFlQRVMpLFxuICAgIHRhcmdldEZpbGU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBpbmNsdWRlQ29udGVudDogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IGNvbnN0IGNvdmVyYWdlVGFza1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgYmFzZVBhdGg6IHouc3RyaW5nKCkubWluKDEsIFwiYmFzZVBhdGggaXMgcmVxdWlyZWRcIiksXG4gICAgY292ZXJhZ2U6IHpcbiAgICAgIC5udW1iZXIoKVxuICAgICAgLm1pbigwKVxuICAgICAgLm1heCgxMDApXG4gICAgICAuZGVmYXVsdCg5MClcbiAgICAgIC5kZXNjcmliZShcIlRhcmdldCBjb3ZlcmFnZSBwZXJjZW50YWdlXCIpLFxuICAgIGRyeVJ1bjogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuZXhwb3J0IGNvbnN0IHJlYWRtZUltcHJvdmVtZW50U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBiYXNlUGF0aDogei5zdHJpbmcoKS5taW4oMSwgXCJiYXNlUGF0aCBpcyByZXF1aXJlZFwiKSxcbiAgICBpbmNsdWRlRXhhbXBsZXM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIH0pXG4gIC5zdHJpY3QoKTtcbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkRmlsZVNhZmUoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIGVuY29kaW5nOiBCdWZmZXJFbmNvZGluZyA9IFwidXRmOFwiXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIHsgZW5jb2RpbmcgfSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RGaWxlc1JlY3Vyc2l2ZShcbiAgcm9vdDogc3RyaW5nLFxuICBtYXRjaGVyPzogKHA6IHN0cmluZykgPT4gYm9vbGVhblxuKTogc3RyaW5nW10ge1xuICBjb25zdCBvdXQ6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHN0YWNrOiBzdHJpbmdbXSA9IFtyb290XTtcbiAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgIGNvbnN0IGN1ciA9IHN0YWNrLnBvcCgpITtcbiAgICBjb25zdCBzdGF0ID0gZnMuc3RhdFN5bmMoY3VyKTtcbiAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBmb3IgKGNvbnN0IGYgb2YgZnMucmVhZGRpclN5bmMoY3VyKSkgc3RhY2sucHVzaChwYXRoLmpvaW4oY3VyLCBmKSk7XG4gICAgfSBlbHNlIGlmICghbWF0Y2hlciB8fCBtYXRjaGVyKGN1cikpIHtcbiAgICAgIG91dC5wdXNoKGN1cik7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQuc29ydCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlQ2FwYWJpbGl0aWVzKGFuYWx5c2lzOiBhbnkpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGNhcCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAvLyBoZXVyaXN0aWNzOiBpZiBkZWNvcmF0b3JzIGxpa2UgRGVjb3JhdGlvbiwgZmxhdm91cmVkQXMsIGV4dGVuZCwgb3ZlcnJpZGUgYXBwZWFyLCBhZGQgY2FwYWJpbGl0aWVzXG4gIGNvbnN0IGFsbERlY3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKGFuYWx5c2lzLmFwaSkpIHtcbiAgICBmb3IgKGNvbnN0IGQgb2YgYW5hbHlzaXMuYXBpW2tdLmRlY29yYXRvcnMpIGFsbERlY3MuYWRkKGQpO1xuICAgIGZvciAoY29uc3QgZSBvZiBhbmFseXNpcy5hcGlba10uZXhwb3J0cylcbiAgICAgIGlmICgvRGVjb3JhdGlvbnxkZWNvcmF0ZXxCdWlsZGVyfEZsYXZvdXIvaS50ZXN0KGUpKVxuICAgICAgICBjYXAuYWRkKFwidXNlLWRlY29yYXRpb24tYXBpXCIpO1xuICB9XG4gIGlmIChbLi4uYWxsRGVjc10uc29tZSgoZCkgPT4gL292ZXJyaWRlfGV4dGVuZC9pLnRlc3QoZCkpKVxuICAgIGNhcC5hZGQoXCJvdmVycmlkZS1hbmQtZXh0ZW5kLWRlY29yYXRpb25zXCIpO1xuICBpZiAoT2JqZWN0LmtleXMoYW5hbHlzaXMudGVzdHMpLmxlbmd0aCA+IDApIGNhcC5hZGQoXCJ2YWxpZGF0ZS13aXRoLXRlc3RzXCIpO1xuICBpZiAoYW5hbHlzaXMucmVhZG1lKSBjYXAuYWRkKFwiZm9sbG93LXJlYWRtZS1ndWlkZXNcIik7XG4gIHJldHVybiBbLi4uY2FwXS5zb3J0KCk7XG59XG5cbiIsIi8vIEFuYWx5c2lzIGhlbHBlcnMgKG1pbmltYWwgeWV0IGVmZmVjdGl2ZSwgdGV4dC1iYXNlZCB0byBhdm9pZCBoZWF2eSBBU1QgZGVwcylcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBsaXN0RmlsZXNSZWN1cnNpdmUsIHJlYWRGaWxlU2FmZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NvdXJjZUZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiAvXFwuKHRzfHRzeHxqc3xqc3gpJC8udGVzdChwKSAmJiAhcC5lbmRzV2l0aChcIi5kLnRzXCIpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzVGVzdEZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiAvKFxcLnRlc3RcXC58XFwuc3BlY1xcLikvLnRlc3QocCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0RXhwb3J0cyhmaWxlQ29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBleHBvcnRSZSA9XG4gICAgLyhleHBvcnRcXHMrKD86ZGVmYXVsdFxccyspPyg/OmNsYXNzfGZ1bmN0aW9ufGNvbnN0fGxldHx2YXJ8aW50ZXJmYWNlfHR5cGV8ZW51bSlcXHMrKShbQS1aYS16MC05X10rKS9nO1xuICBjb25zdCBuYW1lZFJlID0gL2V4cG9ydFxccypcXHsoW159XSspXFx9L2c7XG4gIGxldCBtOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICB3aGlsZSAoKG0gPSBleHBvcnRSZS5leGVjKGZpbGVDb250ZW50KSkpIG5hbWVzLmFkZChtWzJdKTtcbiAgd2hpbGUgKChtID0gbmFtZWRSZS5leGVjKGZpbGVDb250ZW50KSkpIHtcbiAgICBtWzFdXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChzKSA9PiBzLnRyaW0oKS5zcGxpdChcIiBhcyBcIilbMF0udHJpbSgpKVxuICAgICAgLmZvckVhY2goKG4pID0+IHtcbiAgICAgICAgaWYgKG4pIG5hbWVzLmFkZChuKTtcbiAgICAgIH0pO1xuICB9XG4gIHJldHVybiBbLi4ubmFtZXNdLnNvcnQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3REZWNvcmF0b3JzKGZpbGVDb250ZW50OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGRlY3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgZGVjUmUgPSAvQChbQS1aYS16X11bQS1aYS16MC05X10qKS9nO1xuICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbDtcbiAgd2hpbGUgKChtID0gZGVjUmUuZXhlYyhmaWxlQ29udGVudCkpKSBkZWNzLmFkZChtWzFdKTtcbiAgcmV0dXJuIFsuLi5kZWNzXS5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdW1tYXJpemVSZWFkbWUocmVhZG1lPzogc3RyaW5nKSB7XG4gIGlmICghcmVhZG1lKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBsaW5lcyA9IHJlYWRtZS5zcGxpdCgvXFxyP1xcbi8pLmZpbHRlcihCb29sZWFuKTtcbiAgY29uc3QgdGl0bGUgPVxuICAgIGxpbmVzLmZpbmQoKGwpID0+IC9eI1xccysvLnRlc3QobCkpPy5yZXBsYWNlKC9eI1xccysvLCBcIlwiKSB8fCBcIlJFQURNRVwiO1xuICBjb25zdCBidWxsZXRzID0gbGluZXMuZmlsdGVyKChsKSA9PiAvXlstKl1cXHMrLy50ZXN0KGwpKS5zbGljZSgwLCAyMCk7XG4gIHJldHVybiB7IHRpdGxlLCBidWxsZXRzIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbmFseXplUmVwbyhyb290OiBzdHJpbmcpIHtcbiAgY29uc3Qgc3JjID0gcGF0aC5qb2luKHJvb3QsIFwic3JjXCIpO1xuICBjb25zdCB0ZXN0RGlyID0gcGF0aC5qb2luKHJvb3QsIFwidGVzdHNcIik7XG4gIGNvbnN0IHJlYWRtZVBhdGggPSBwYXRoLmpvaW4ocm9vdCwgXCJSRUFETUUubWRcIik7XG4gIGNvbnN0IHJlYWRtZSA9IHJlYWRGaWxlU2FmZShyZWFkbWVQYXRoKTtcblxuICBjb25zdCBmaWxlcyA9IGZzLmV4aXN0c1N5bmMoc3JjKSA/IGxpc3RGaWxlc1JlY3Vyc2l2ZShzcmMsIGlzU291cmNlRmlsZSkgOiBbXTtcbiAgY29uc3QgdGVzdEZpbGVzID0gZnMuZXhpc3RzU3luYyh0ZXN0RGlyKVxuICAgID8gbGlzdEZpbGVzUmVjdXJzaXZlKHRlc3REaXIsIChmKSA9PiBpc1NvdXJjZUZpbGUoZikgJiYgaXNUZXN0RmlsZShmKSlcbiAgICA6IFtdO1xuXG4gIGNvbnN0IGFwaTogUmVjb3JkPHN0cmluZywgeyBleHBvcnRzOiBzdHJpbmdbXTsgZGVjb3JhdG9yczogc3RyaW5nW10gfT4gPSB7fTtcbiAgZm9yIChjb25zdCBmIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU2FmZShmKSB8fCBcIlwiO1xuICAgIGFwaVtwYXRoLnJlbGF0aXZlKHJvb3QsIGYpXSA9IHtcbiAgICAgIGV4cG9ydHM6IGV4dHJhY3RFeHBvcnRzKGNvbnRlbnQpLFxuICAgICAgZGVjb3JhdG9yczogZXh0cmFjdERlY29yYXRvcnMoY29udGVudCksXG4gICAgfTtcbiAgfVxuICBjb25zdCB0ZXN0czogUmVjb3JkPHN0cmluZywgeyBtZW50aW9uczogc3RyaW5nW10gfT4gPSB7fTtcbiAgZm9yIChjb25zdCBmIG9mIHRlc3RGaWxlcykge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVNhZmUoZikgfHwgXCJcIjtcbiAgICBjb25zdCBtZW50aW9ucyA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi5leHRyYWN0RXhwb3J0cyhjb250ZW50KSwgLi4uZXh0cmFjdERlY29yYXRvcnMoY29udGVudCldKVxuICAgICkuc29ydCgpO1xuICAgIHRlc3RzW3BhdGgucmVsYXRpdmUocm9vdCwgZildID0geyBtZW50aW9ucyB9O1xuICB9XG4gIHJldHVybiB7IGZpbGVzLCB0ZXN0RmlsZXMsIGFwaSwgdGVzdHMsIHJlYWRtZTogc3VtbWFyaXplUmVhZG1lKHJlYWRtZSkgfTtcbn1cbiIsImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHR5cGUgeyBDb250ZW50UmVzdWx0LCBUb29sIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7XG4gIGRvY3VtZW50T2JqZWN0U2NoZW1hLFxuICBjb3ZlcmFnZVRhc2tTY2hlbWEsXG4gIHJlYWRtZUltcHJvdmVtZW50U2NoZW1hLFxufSBmcm9tIFwiLi4vc2NoZW1hc1wiO1xuaW1wb3J0IHtcbiAgRG9jdW1lbnRPYmplY3RBcmdzLFxuICBDb3ZlcmFnZVRhc2tBcmdzLFxuICBSZWFkbWVJbXByb3ZlbWVudEFyZ3MsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgZ2V0V29ya3NwYWNlUm9vdCxcbiAgcmVzb2x2ZUluV29ya3NwYWNlLFxuICB0aHJvd1VzZXJFcnJvcixcbiAgV29ya3NwYWNlRXJyb3IsXG59IGZyb20gXCIuLi93b3Jrc3BhY2VcIjtcbmltcG9ydCB7XG4gIGRpc2NvdmVyRG9jUHJvbXB0cyxcbiAgZ2V0T2JqZWN0UHJvbXB0RGVwZW5kZW5jaWVzLFxufSBmcm9tIFwiLi4vcHJvbXB0cy9wcm9tcHRzXCI7XG5pbXBvcnQgdHlwZSB7IERvY1Byb21wdCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgbGlzdEZpbGVzUmVjdXJzaXZlLCByZWFkRmlsZVNhZmUgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IGFuYWx5emVSZXBvLCBpc1NvdXJjZUZpbGUsIGlzVGVzdEZpbGUgfSBmcm9tIFwiLi4vY29kZVwiO1xuXG50eXBlIFByb21wdFNlY3Rpb24gPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBhYnNvbHV0ZVBhdGg/OiBzdHJpbmc7XG59O1xuXG5mdW5jdGlvbiByZWxhdGl2ZUZpbGVzKHJvb3Q6IHN0cmluZywgZmlsZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICByZXR1cm4gZmlsZXMubWFwKChmaWxlKSA9PiBwYXRoLnJlbGF0aXZlKHJvb3QsIGZpbGUpKS5zb3J0KCk7XG59XG5cbmZ1bmN0aW9uIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9tcHRTZWN0aW9uW10ge1xuICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICBjb25zdCBwcm9tcHRJbmRleCA9IG5ldyBNYXA8c3RyaW5nLCBEb2NQcm9tcHQ+KFxuICAgIGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KS5tYXAoKHByb21wdCkgPT4gW3Byb21wdC5uYW1lLCBwcm9tcHRdKVxuICApO1xuICByZXR1cm4gbmFtZXNcbiAgICAubWFwKChuYW1lKSA9PiBwcm9tcHRJbmRleC5nZXQobmFtZSkpXG4gICAgLmZpbHRlcigocHJvbXB0KTogcHJvbXB0IGlzIERvY1Byb21wdCA9PiBCb29sZWFuKHByb21wdCkpXG4gICAgLm1hcCgocHJvbXB0KSA9PiAoe1xuICAgICAgbmFtZTogcHJvbXB0Lm5hbWUsXG4gICAgICB0aXRsZTogcHJvbXB0LnRpdGxlLFxuICAgICAgZGVzY3JpcHRpb246IHByb21wdC5kZXNjcmlwdGlvbixcbiAgICAgIGNvbnRlbnQ6IHByb21wdC5jb250ZW50LFxuICAgICAgYWJzb2x1dGVQYXRoOiBwcm9tcHQuYWJzb2x1dGVQYXRoLFxuICAgIH0pKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VUYXNrTGluZXMoY29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICByZXR1cm4gY29udGVudFxuICAgIC5zcGxpdCgvXFxyP1xcbi8pXG4gICAgLm1hcCgobGluZSkgPT4gbGluZS50cmltKCkpXG4gICAgLmZpbHRlcigobGluZSkgPT4gL150YXNrXFxzK1xcZCsvaS50ZXN0KGxpbmUpKTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUNvdmVyYWdlRnJvbUZpbmFsKGNvdmVyYWdlUGF0aDogc3RyaW5nKSB7XG4gIGNvbnN0IHBheWxvYWQgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhjb3ZlcmFnZVBhdGgsIFwidXRmOFwiKSkgYXMgUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICB7XG4gICAgICBzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICAgICAgZjogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgICAgIGI6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IG51bWJlcltdPjtcbiAgICB9XG4gID47XG5cbiAgY29uc3QgdG90YWxzID0ge1xuICAgIHN0YXRlbWVudHM6IHsgY292ZXJlZDogMCwgdG90YWw6IDAgfSxcbiAgICBmdW5jdGlvbnM6IHsgY292ZXJlZDogMCwgdG90YWw6IDAgfSxcbiAgICBicmFuY2hlczogeyBjb3ZlcmVkOiAwLCB0b3RhbDogMCB9LFxuICB9O1xuXG4gIGNvbnN0IGZpbGVzID0gT2JqZWN0LmVudHJpZXMocGF5bG9hZCkubWFwKChbZmlsZVBhdGgsIGluZm9dKSA9PiB7XG4gICAgY29uc3Qgc3RhdGVtZW50Q291bnRzID0gT2JqZWN0LnZhbHVlcyhpbmZvLnMpO1xuICAgIGNvbnN0IGZ1bmN0aW9uQ291bnRzID0gT2JqZWN0LnZhbHVlcyhpbmZvLmYpO1xuICAgIGNvbnN0IGJyYW5jaENvdW50cyA9IE9iamVjdC52YWx1ZXMoaW5mby5iKS5mbGF0TWFwKCh2YWx1ZSkgPT5cbiAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdXG4gICAgKTtcblxuICAgIGNvbnN0IHN0YXRlbWVudFRvdGFsID0gc3RhdGVtZW50Q291bnRzLmxlbmd0aDtcbiAgICBjb25zdCBmdW5jdGlvblRvdGFsID0gZnVuY3Rpb25Db3VudHMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5jaFRvdGFsID0gYnJhbmNoQ291bnRzLmxlbmd0aDtcblxuICAgIGNvbnN0IHN0YXRlbWVudENvdmVyZWQgPSBzdGF0ZW1lbnRDb3VudHMuZmlsdGVyKFxuICAgICAgKGNvdW50KSA9PiBjb3VudCA+IDBcbiAgICApLmxlbmd0aDtcbiAgICBjb25zdCBmdW5jdGlvbkNvdmVyZWQgPSBmdW5jdGlvbkNvdW50cy5maWx0ZXIoKGNvdW50KSA9PiBjb3VudCA+IDApLmxlbmd0aDtcbiAgICBjb25zdCBicmFuY2hDb3ZlcmVkID0gYnJhbmNoQ291bnRzLmZpbHRlcigoY291bnQpID0+IGNvdW50ID4gMCkubGVuZ3RoO1xuXG4gICAgdG90YWxzLnN0YXRlbWVudHMuY292ZXJlZCArPSBzdGF0ZW1lbnRDb3ZlcmVkO1xuICAgIHRvdGFscy5zdGF0ZW1lbnRzLnRvdGFsICs9IHN0YXRlbWVudFRvdGFsO1xuICAgIHRvdGFscy5mdW5jdGlvbnMuY292ZXJlZCArPSBmdW5jdGlvbkNvdmVyZWQ7XG4gICAgdG90YWxzLmZ1bmN0aW9ucy50b3RhbCArPSBmdW5jdGlvblRvdGFsO1xuICAgIHRvdGFscy5icmFuY2hlcy5jb3ZlcmVkICs9IGJyYW5jaENvdmVyZWQ7XG4gICAgdG90YWxzLmJyYW5jaGVzLnRvdGFsICs9IGJyYW5jaFRvdGFsO1xuXG4gICAgY29uc3QgcGN0ID0gKGNvdmVyZWQ6IG51bWJlciwgdG90YWw6IG51bWJlcikgPT5cbiAgICAgIHRvdGFsID09PSAwID8gMTAwIDogTnVtYmVyKCgoY292ZXJlZCAvIHRvdGFsKSAqIDEwMCkudG9GaXhlZCgyKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGF0aDogZmlsZVBhdGgsXG4gICAgICBzdGF0ZW1lbnRzOiBwY3Qoc3RhdGVtZW50Q292ZXJlZCwgc3RhdGVtZW50VG90YWwpLFxuICAgICAgZnVuY3Rpb25zOiBwY3QoZnVuY3Rpb25Db3ZlcmVkLCBmdW5jdGlvblRvdGFsKSxcbiAgICAgIGJyYW5jaGVzOiBwY3QoYnJhbmNoQ292ZXJlZCwgYnJhbmNoVG90YWwpLFxuICAgIH07XG4gIH0pO1xuXG4gIGNvbnN0IHBjdCA9IChjb3ZlcmVkOiBudW1iZXIsIHRvdGFsOiBudW1iZXIpID0+XG4gICAgdG90YWwgPT09IDAgPyAxMDAgOiBOdW1iZXIoKChjb3ZlcmVkIC8gdG90YWwpICogMTAwKS50b0ZpeGVkKDIpKTtcblxuICByZXR1cm4ge1xuICAgIHRvdGFsczoge1xuICAgICAgc3RhdGVtZW50czoge1xuICAgICAgICAuLi50b3RhbHMuc3RhdGVtZW50cyxcbiAgICAgICAgcGN0OiBwY3QodG90YWxzLnN0YXRlbWVudHMuY292ZXJlZCwgdG90YWxzLnN0YXRlbWVudHMudG90YWwpLFxuICAgICAgfSxcbiAgICAgIGZ1bmN0aW9uczoge1xuICAgICAgICAuLi50b3RhbHMuZnVuY3Rpb25zLFxuICAgICAgICBwY3Q6IHBjdCh0b3RhbHMuZnVuY3Rpb25zLmNvdmVyZWQsIHRvdGFscy5mdW5jdGlvbnMudG90YWwpLFxuICAgICAgfSxcbiAgICAgIGJyYW5jaGVzOiB7XG4gICAgICAgIC4uLnRvdGFscy5icmFuY2hlcyxcbiAgICAgICAgcGN0OiBwY3QodG90YWxzLmJyYW5jaGVzLmNvdmVyZWQsIHRvdGFscy5icmFuY2hlcy50b3RhbCksXG4gICAgICB9LFxuICAgIH0sXG4gICAgZmlsZXMsXG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVByb21wdFNlY3Rpb25zKHNlY3Rpb25zOiBQcm9tcHRTZWN0aW9uW10pIHtcbiAgcmV0dXJuIHNlY3Rpb25zLm1hcCgoc2VjdGlvbikgPT4gKHtcbiAgICBuYW1lOiBzZWN0aW9uLm5hbWUsXG4gICAgdGl0bGU6IHNlY3Rpb24udGl0bGUsXG4gICAgdGFza3M6IHBhcnNlVGFza0xpbmVzKHNlY3Rpb24uY29udGVudCksXG4gICAgY29udGVudDogc2VjdGlvbi5jb250ZW50LFxuICB9KSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVSZXBvUm9vdChiYXNlUGF0aDogc3RyaW5nKSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlc29sdmVJbldvcmtzcGFjZShyb290LCBiYXNlUGF0aCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya3NwYWNlRXJyb3IpIHtcbiAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZG9jdW1lbnRPYmplY3RUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGRvY3VtZW50T2JqZWN0U2NoZW1hPiA9XG4gIHtcbiAgICBuYW1lOiBcImRvY3VtZW50LW9iamVjdFwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJDcmVhdGUgYSBkb2N1bWVudGF0aW9uIHBsYW4gZm9yIGEgc3BlY2lmaWMgb2JqZWN0IHR5cGUgdXNpbmcgLmNvZGV4IHByb21wdHMgYW5kIHJlcG9zaXRvcnkgYW5hbHlzaXMuXCIsXG4gICAgcGFyYW1ldGVyczogZG9jdW1lbnRPYmplY3RTY2hlbWEsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICAgIGNvbnN0IGFyZ3MgPSBkb2N1bWVudE9iamVjdFNjaGVtYS5wYXJzZShpbnB1dCBhcyBEb2N1bWVudE9iamVjdEFyZ3MpO1xuICAgICAgY29uc3QgcmVwb1Jvb3QgPSBhd2FpdCByZXNvbHZlUmVwb1Jvb3QoYXJncy5iYXNlUGF0aCk7XG5cbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGdldE9iamVjdFByb21wdERlcGVuZGVuY2llcygpW2FyZ3Mub2JqZWN0VHlwZV0gPz8gW107XG4gICAgICBpZiAoIWRlcGVuZGVuY2llcy5sZW5ndGgpIHtcbiAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoXG4gICAgICAgICAgYE5vIHByb21wdCBndWlkYW5jZSBjb25maWd1cmVkIGZvciBvYmplY3QgdHlwZSAke2FyZ3Mub2JqZWN0VHlwZX1gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNlY3Rpb25zID0gbm9ybWFsaXplUHJvbXB0U2VjdGlvbnMoXG4gICAgICAgIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhkZXBlbmRlbmNpZXMpXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzcmNEaXIgPSBwYXRoLmpvaW4ocmVwb1Jvb3QsIFwic3JjXCIpO1xuICAgICAgY29uc3QgdGVzdERpciA9IHBhdGguam9pbihyZXBvUm9vdCwgXCJ0ZXN0c1wiKTtcblxuICAgICAgY29uc3Qgc291cmNlRmlsZXMgPSBmcy5leGlzdHNTeW5jKHNyY0RpcilcbiAgICAgICAgPyBsaXN0RmlsZXNSZWN1cnNpdmUoc3JjRGlyLCBpc1NvdXJjZUZpbGUpXG4gICAgICAgIDogW107XG4gICAgICBjb25zdCB0ZXN0RmlsZXMgPSBmcy5leGlzdHNTeW5jKHRlc3REaXIpXG4gICAgICAgID8gbGlzdEZpbGVzUmVjdXJzaXZlKFxuICAgICAgICAgICAgdGVzdERpcixcbiAgICAgICAgICAgIChmaWxlKSA9PiBpc1NvdXJjZUZpbGUoZmlsZSkgJiYgaXNUZXN0RmlsZShmaWxlKVxuICAgICAgICAgIClcbiAgICAgICAgOiBbXTtcblxuICAgICAgbGV0IHRhcmdldEZpbGVDb250ZW50OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy50YXJnZXRGaWxlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgYWJzb2x1dGUgPSByZXNvbHZlSW5Xb3Jrc3BhY2UocmVwb1Jvb3QsIGFyZ3MudGFyZ2V0RmlsZSk7XG4gICAgICAgICAgdGFyZ2V0RmlsZUNvbnRlbnQgPSByZWFkRmlsZVNhZmUoYWJzb2x1dGUpID8/IHVuZGVmaW5lZDtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIGJhc2VQYXRoOiBwYXRoLnJlbGF0aXZlKGdldFdvcmtzcGFjZVJvb3QoKSwgcmVwb1Jvb3QpIHx8IFwiLlwiLFxuICAgICAgICBvYmplY3RUeXBlOiBhcmdzLm9iamVjdFR5cGUsXG4gICAgICAgIHRhcmdldEZpbGU6IGFyZ3MudGFyZ2V0RmlsZSxcbiAgICAgICAgZ3VpZGFuY2U6IHNlY3Rpb25zLFxuICAgICAgICBmaWxlczoge1xuICAgICAgICAgIHNvdXJjZTogcmVsYXRpdmVGaWxlcyhyZXBvUm9vdCwgc291cmNlRmlsZXMpLFxuICAgICAgICAgIHRlc3RzOiByZWxhdGl2ZUZpbGVzKHJlcG9Sb290LCB0ZXN0RmlsZXMpLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXRGaWxlQ29udGVudDogYXJncy5pbmNsdWRlQ29udGVudCA/IHRhcmdldEZpbGVDb250ZW50IDogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgbnVsbCwgMiksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gICAgfSxcbiAgfTtcblxuZXhwb3J0IGNvbnN0IGNvdmVyYWdlRW5mb3JjZXJUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGNvdmVyYWdlVGFza1NjaGVtYT4gPVxuICB7XG4gICAgbmFtZTogXCJlbnN1cmUtdGVzdC1jb3ZlcmFnZVwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJSdW4gdGhlIGNvbmZpZ3VyZWQgY292ZXJhZ2UgY29tbWFuZCBhbmQgcmVwb3J0IHdoZXRoZXIgdGhlIHRhcmdldCBwZXJjZW50YWdlIGlzIG1ldCwgaGlnaGxpZ2h0aW5nIHdlYWsgZmlsZXMuXCIsXG4gICAgcGFyYW1ldGVyczogY292ZXJhZ2VUYXNrU2NoZW1hLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgICBjb25zdCBhcmdzID0gY292ZXJhZ2VUYXNrU2NoZW1hLnBhcnNlKGlucHV0IGFzIENvdmVyYWdlVGFza0FyZ3MpO1xuICAgICAgY29uc3QgcmVwb1Jvb3QgPSBhd2FpdCByZXNvbHZlUmVwb1Jvb3QoYXJncy5iYXNlUGF0aCk7XG5cbiAgICAgIGlmICghYXJncy5kcnlSdW4pIHtcbiAgICAgICAgY29uc3QgZW52ID0ge1xuICAgICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICAgIFVTRV9XQVRDSE1BTjogXCJmYWxzZVwiLFxuICAgICAgICAgIFdBVENITUFOX0RJU0FCTEU6IFwiMVwiLFxuICAgICAgICAgIEpFU1RfRElTQUJMRV9XQVRDSE1BTjogXCIxXCIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHNwYXduU3luYyhcbiAgICAgICAgICBcIm5wbVwiLFxuICAgICAgICAgIFtcInJ1blwiLCBcImNvdmVyYWdlXCIsIFwiLS1cIiwgXCItLXdhdGNobWFuPWZhbHNlXCIsIFwiLS1ydW5JbkJhbmRcIl0sXG4gICAgICAgICAgeyBjd2Q6IHJlcG9Sb290LCBlbnYsIGVuY29kaW5nOiBcInV0ZjhcIiB9XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcbiAgICAgICAgICBjb25zdCBtZXNzYWdlID1cbiAgICAgICAgICAgIHJlc3VsdC5zdGRlcnIgfHwgcmVzdWx0LnN0ZG91dCB8fCBcIkNvdmVyYWdlIGNvbW1hbmQgZmFpbGVkXCI7XG4gICAgICAgICAgYXdhaXQgdGhyb3dVc2VyRXJyb3IobWVzc2FnZS50cmltKCkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvdmVyYWdlUGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgcmVwb1Jvb3QsXG4gICAgICAgIFwid29ya2RvY3NcIixcbiAgICAgICAgXCJyZXBvcnRzXCIsXG4gICAgICAgIFwiY292ZXJhZ2VcIixcbiAgICAgICAgXCJjb3ZlcmFnZS1maW5hbC5qc29uXCJcbiAgICAgICk7XG5cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhjb3ZlcmFnZVBhdGgpKSB7XG4gICAgICAgIGF3YWl0IHRocm93VXNlckVycm9yKFxuICAgICAgICAgIGBDb3ZlcmFnZSByZXBvcnQgbm90IGZvdW5kIGF0ICR7cGF0aC5yZWxhdGl2ZShyZXBvUm9vdCwgY292ZXJhZ2VQYXRoKX1gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBjb21wdXRlQ292ZXJhZ2VGcm9tRmluYWwoY292ZXJhZ2VQYXRoKTtcbiAgICAgIGNvbnN0IG1lZXRzVGhyZXNob2xkID1cbiAgICAgICAgc3VtbWFyeS50b3RhbHMuc3RhdGVtZW50cy5wY3QgPj0gYXJncy5jb3ZlcmFnZSAmJlxuICAgICAgICBzdW1tYXJ5LnRvdGFscy5mdW5jdGlvbnMucGN0ID49IGFyZ3MuY292ZXJhZ2UgJiZcbiAgICAgICAgc3VtbWFyeS50b3RhbHMuYnJhbmNoZXMucGN0ID49IGFyZ3MuY292ZXJhZ2U7XG5cbiAgICAgIGNvbnN0IHdlYWtlc3QgPSBbLi4uc3VtbWFyeS5maWxlc11cbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGEuc3RhdGVtZW50cyAtIGIuc3RhdGVtZW50cylcbiAgICAgICAgLnNsaWNlKDAsIDEwKTtcblxuICAgICAgY29uc3QgZ3VpZGFuY2UgPSBub3JtYWxpemVQcm9tcHRTZWN0aW9ucyhcbiAgICAgICAgY29sbGVjdFByb21wdFNlY3Rpb25zKFtcImJ1bGstdGVzdHNcIl0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBiYXNlUGF0aDogcGF0aC5yZWxhdGl2ZShnZXRXb3Jrc3BhY2VSb290KCksIHJlcG9Sb290KSB8fCBcIi5cIixcbiAgICAgICAgdGFyZ2V0OiBhcmdzLmNvdmVyYWdlLFxuICAgICAgICBtZWV0c1RocmVzaG9sZCxcbiAgICAgICAgdG90YWxzOiBzdW1tYXJ5LnRvdGFscyxcbiAgICAgICAgd2Vha2VzdCxcbiAgICAgICAgZ3VpZGFuY2UsXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCBudWxsLCAyKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSBzYXRpc2ZpZXMgQ29udGVudFJlc3VsdDtcbiAgICB9LFxuICB9O1xuXG5leHBvcnQgY29uc3QgcmVhZG1lSW1wcm92ZW1lbnRUb29sOiBUb29sPFxuICB1bmRlZmluZWQsXG4gIHR5cGVvZiByZWFkbWVJbXByb3ZlbWVudFNjaGVtYVxuPiA9IHtcbiAgbmFtZTogXCJpbXByb3ZlLXJlYWRtZVwiLFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIlN1bW1hcml6ZSByZXF1aXJlZCBzdGVwcyB0byByZWZyZXNoIFJFQURNRSBhbmQgd29ya2RvY3MgY29udGVudCB1c2luZyAuY29kZXggZ3VpZGFuY2UgYW5kIHJlcG9zaXRvcnkgYW5hbHlzaXMuXCIsXG4gIHBhcmFtZXRlcnM6IHJlYWRtZUltcHJvdmVtZW50U2NoZW1hLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gcmVhZG1lSW1wcm92ZW1lbnRTY2hlbWEucGFyc2UoaW5wdXQgYXMgUmVhZG1lSW1wcm92ZW1lbnRBcmdzKTtcbiAgICBjb25zdCByZXBvUm9vdCA9IGF3YWl0IHJlc29sdmVSZXBvUm9vdChhcmdzLmJhc2VQYXRoKTtcblxuICAgIGNvbnN0IGFuYWx5c2lzID0gYW5hbHl6ZVJlcG8ocmVwb1Jvb3QpO1xuICAgIGNvbnN0IG1vZHVsZXMgPSBhbmFseXNpcy5maWxlc1xuICAgICAgLmZpbHRlcigoZmlsZSkgPT4gL2luZGV4XFwudHMkLy50ZXN0KGZpbGUpKVxuICAgICAgLm1hcCgoZmlsZSkgPT4gcGF0aC5yZWxhdGl2ZShyZXBvUm9vdCwgZmlsZSkpO1xuXG4gICAgY29uc3QgcHJvbXB0U2VjdGlvbnMgPSBub3JtYWxpemVQcm9tcHRTZWN0aW9ucyhcbiAgICAgIGNvbGxlY3RQcm9tcHRTZWN0aW9ucyhbXCJ1cGRhdGUtcmVhZG1lXCIsIFwiZG9jXCIsIFwibW9kdWxlXCJdKVxuICAgICk7XG5cbiAgICBjb25zdCB0ZXN0RXhhbXBsZXMgPSBPYmplY3Qua2V5cyhhbmFseXNpcy50ZXN0cyA/PyB7fSk7XG4gICAgY29uc3QgZXhhbXBsZXMgPSBhcmdzLmluY2x1ZGVFeGFtcGxlcyA/IHRlc3RFeGFtcGxlcy5zbGljZSgwLCAyMCkgOiBbXTtcblxuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICBiYXNlUGF0aDogcGF0aC5yZWxhdGl2ZShnZXRXb3Jrc3BhY2VSb290KCksIHJlcG9Sb290KSB8fCBcIi5cIixcbiAgICAgIHN1bW1hcnk6IHtcbiAgICAgICAgbW9kdWxlcyxcbiAgICAgICAgdG90YWxTb3VyY2VGaWxlczogYW5hbHlzaXMuZmlsZXMubGVuZ3RoLFxuICAgICAgICB0b3RhbFRlc3RGaWxlczogYW5hbHlzaXMudGVzdEZpbGVzLmxlbmd0aCxcbiAgICAgICAgaGFzUmVhZG1lOiBCb29sZWFuKGFuYWx5c2lzLnJlYWRtZSksXG4gICAgICB9LFxuICAgICAgZ3VpZGFuY2U6IHByb21wdFNlY3Rpb25zLFxuICAgICAgc3VnZ2VzdGVkRXhhbXBsZXM6IGV4YW1wbGVzLFxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgbnVsbCwgMiksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gc2F0aXNmaWVzIENvbnRlbnRSZXN1bHQ7XG4gIH0sXG59O1xuIiwiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuZXhwb3J0IHR5cGUgRGVjb3JhdG9yU3BlYyA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICBhcmdzPzogdW5rbm93bltdO1xufTtcblxuZXhwb3J0IHR5cGUgQXR0cmlidXRlU3BlYyA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG4gIGRlY29yYXRvcnM/OiBEZWNvcmF0b3JTcGVjW107XG59O1xuXG5mdW5jdGlvbiBlc2NhcGVSZWdFeHAodmFsdWU6IHN0cmluZykge1xuICByZXR1cm4gdmFsdWUucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csIFwiXFxcXCQmXCIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXREZWNvcmF0b3Ioc3BlYzogRGVjb3JhdG9yU3BlYyk6IHN0cmluZyB7XG4gIGNvbnN0IGFyZ3MgPSAoc3BlYy5hcmdzIHx8IFtdKS5tYXAoKGFyZykgPT4gSlNPTi5zdHJpbmdpZnkoYXJnKSkuam9pbihcIiwgXCIpO1xuICByZXR1cm4gYEAke3NwZWMubmFtZX0oJHthcmdzfSlgO1xufVxuXG5mdW5jdGlvbiBlbnN1cmVEaXJlY3RvcnkoZmlsZVBhdGg6IHN0cmluZykge1xuICBmcy5ta2RpclN5bmMocGF0aC5kaXJuYW1lKGZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbGxlY3REZWNvcmF0b3JOYW1lcyhcbiAgY2xhc3NEZWNvcmF0b3JzOiBEZWNvcmF0b3JTcGVjW10gfCB1bmRlZmluZWQsXG4gIHByb3BlcnRpZXM6IEF0dHJpYnV0ZVNwZWNbXSB8IHVuZGVmaW5lZFxuKSB7XG4gIGNvbnN0IG5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIG5hbWVzLmFkZChcIm1vZGVsXCIpO1xuICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBjbGFzc0RlY29yYXRvcnMgfHwgW10pIHtcbiAgICBuYW1lcy5hZGQoZGVjb3JhdG9yLm5hbWUpO1xuICB9XG4gIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcGVydGllcyB8fCBbXSkge1xuICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIHByb3BlcnR5LmRlY29yYXRvcnMgfHwgW10pIHtcbiAgICAgIG5hbWVzLmFkZChkZWNvcmF0b3IubmFtZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuYW1lcztcbn1cblxuZnVuY3Rpb24gZW5zdXJlSW1wb3J0KFxuICBjb250ZW50OiBzdHJpbmcsXG4gIGltcG9ydHNGcm9tOiBzdHJpbmcsXG4gIGRlY29yYXRvcnM6IFNldDxzdHJpbmc+XG4pIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgaWYgKCFkZWNvcmF0b3JzLnNpemUpIHJldHVybiBjb250ZW50O1xuICBjb25zdCBpbXBvcnRSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYGltcG9ydFxcXFxzK1xcXFx7KFtefV0rKVxcXFx9XFxcXHMrZnJvbVxcXFxzK1tcIiddJHtlc2NhcGVSZWdFeHAoaW1wb3J0c0Zyb20pfVtcIiddO2BcbiAgKTtcbiAgY29uc3QgbWF0Y2ggPSBjb250ZW50Lm1hdGNoKGltcG9ydFJlZ2V4KTtcbiAgY29uc3Qgc29ydGVkID0gQXJyYXkuZnJvbShkZWNvcmF0b3JzKS5zb3J0KCk7XG5cbiAgaWYgKG1hdGNoKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBtYXRjaFsxXVxuICAgICAgLnNwbGl0KFwiLFwiKVxuICAgICAgLm1hcCgobmFtZSkgPT4gbmFtZS50cmltKCkpXG4gICAgICAuZmlsdGVyKEJvb2xlYW4pO1xuICAgIGNvbnN0IG1lcmdlZCA9IEFycmF5LmZyb20obmV3IFNldChbLi4uZXhpc3RpbmcsIC4uLnNvcnRlZF0pKS5zb3J0KCk7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShcbiAgICAgIGltcG9ydFJlZ2V4LFxuICAgICAgYGltcG9ydCB7ICR7bWVyZ2VkLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtpbXBvcnRzRnJvbX1cIjtgXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGltcG9ydExpbmUgPSBgaW1wb3J0IHsgJHtzb3J0ZWQuam9pbihcIiwgXCIpfSB9IGZyb20gXCIke2ltcG9ydHNGcm9tfVwiO2A7XG4gIHJldHVybiBgJHtpbXBvcnRMaW5lfVxcblxcbiR7Y29udGVudH1gO1xufVxuXG5mdW5jdGlvbiBhZGRQcm9wZXJ0eUJsb2NrKHByb3BlcnR5OiBBdHRyaWJ1dGVTcGVjKSB7XG4gIGNvbnN0IGRlY29yYXRvcnMgPSAocHJvcGVydHkuZGVjb3JhdG9ycyB8fCBbXSlcbiAgICAubWFwKGZvcm1hdERlY29yYXRvcilcbiAgICAuam9pbihcIlxcbiAgXCIpO1xuICBjb25zdCBkZWNvcmF0b3JCbG9jayA9IGRlY29yYXRvcnMgPyBgICAke2RlY29yYXRvcnN9XFxuYCA6IFwiXCI7XG4gIHJldHVybiBgJHtkZWNvcmF0b3JCbG9ja30gICR7cHJvcGVydHkubmFtZX06ICR7cHJvcGVydHkudHlwZX07YDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlUHJvcGVydHlCbG9jayhjb250ZW50OiBzdHJpbmcsIHByb3BlcnR5TmFtZTogc3RyaW5nKSB7XG4gIGNvbnN0IGxpbmVzID0gY29udGVudC5zcGxpdCgvXFxyP1xcbi8pO1xuICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBsaW5lID0gbGluZXNbaV07XG4gICAgaWYgKFxuICAgICAgbGluZS50cmltKCkuc3RhcnRzV2l0aChgQGApICYmXG4gICAgICBsaW5lc1tpICsgMV0/LmluY2x1ZGVzKGAke3Byb3BlcnR5TmFtZX06YClcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAobGluZS5pbmNsdWRlcyhgJHtwcm9wZXJ0eU5hbWV9OmApKSB7XG4gICAgICAvLyBza2lwIHRoaXMgbGluZSBhbmQgYW55IHRyYWlsaW5nIGJsYW5rIGxpbmVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICByZXN1bHQucHVzaChsaW5lKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0LmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGluc2VydERlY29yYXRvcihcbiAgY29udGVudDogc3RyaW5nLFxuICBkZWNvcmF0b3I6IERlY29yYXRvclNwZWMsXG4gIHRhcmdldDoge1xuICAgIGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjtcbiAgICBuYW1lPzogc3RyaW5nO1xuICB9XG4pIHtcbiAgY29uc3QgZGVjb3JhdG9yTGluZSA9IGZvcm1hdERlY29yYXRvcihkZWNvcmF0b3IpO1xuICBpZiAodGFyZ2V0LmtpbmQgPT09IFwiY2xhc3NcIikge1xuICAgIGNvbnN0IGNsYXNzUmVnZXggPSAvKGV4cG9ydFxccytjbGFzc1xccytbXlxcc3tdK1xccypcXHspLztcbiAgICBpZiAoY29udGVudC5pbmNsdWRlcyhkZWNvcmF0b3JMaW5lKSkgcmV0dXJuIGNvbnRlbnQ7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShjbGFzc1JlZ2V4LCBgJHtkZWNvcmF0b3JMaW5lfVxcbiQxYCk7XG4gIH1cbiAgaWYgKCF0YXJnZXQubmFtZSkgcmV0dXJuIGNvbnRlbnQ7XG4gIGNvbnN0IHByb3BlcnR5UmVnZXggPSBuZXcgUmVnRXhwKFxuICAgIGAoXlxcXFxzKikoPzpALipcXFxcblxcXFwxKSoke2VzY2FwZVJlZ0V4cCh0YXJnZXQubmFtZSl9OmAsXG4gICAgXCJtXCJcbiAgKTtcbiAgY29uc3QgbWF0Y2ggPSBwcm9wZXJ0eVJlZ2V4LmV4ZWMoY29udGVudCk7XG4gIGlmICghbWF0Y2gpIHJldHVybiBjb250ZW50O1xuICBjb25zdCBpbmRlbnQgPSBtYXRjaFsxXSB8fCBcIiAgXCI7XG4gIGlmIChjb250ZW50LmluY2x1ZGVzKGAke2luZGVudH0ke2RlY29yYXRvckxpbmV9YCkpIHJldHVybiBjb250ZW50O1xuICByZXR1cm4gKFxuICAgIGNvbnRlbnQuc2xpY2UoMCwgbWF0Y2guaW5kZXgpICtcbiAgICBgJHtpbmRlbnR9JHtkZWNvcmF0b3JMaW5lfVxcbmAgK1xuICAgIGNvbnRlbnQuc2xpY2UobWF0Y2guaW5kZXgpXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZURlY29yYXRvcihcbiAgY29udGVudDogc3RyaW5nLFxuICBkZWNvcmF0b3JOYW1lOiBzdHJpbmcsXG4gIHRhcmdldDoge1xuICAgIGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjtcbiAgICBuYW1lPzogc3RyaW5nO1xuICB9XG4pIHtcbiAgY29uc3QgZGVjb3JhdG9yUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgIGBeXFxcXHMqQCR7ZXNjYXBlUmVnRXhwKGRlY29yYXRvck5hbWUpfVxcXFwoW14pXSpcXFxcKWAsXG4gICAgXCJtXCJcbiAgKTtcbiAgaWYgKHRhcmdldC5raW5kID09PSBcImNsYXNzXCIpIHtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKGRlY29yYXRvclJlZ2V4LCBcIlwiKTtcbiAgfVxuICBpZiAodGFyZ2V0Lm5hbWUpIHtcbiAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cChcbiAgICAgIGAoXlxcXFxzKkAke2VzY2FwZVJlZ0V4cChkZWNvcmF0b3JOYW1lKX1cXFxcKFteKV0qXFxcXClcXFxccyokXFxcXG4pKD89XFxcXHMqJHtlc2NhcGVSZWdFeHAodGFyZ2V0Lm5hbWUpfTopYCxcbiAgICAgIFwibVwiXG4gICAgKTtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKHBhdHRlcm4sIFwiXCIpO1xuICB9XG4gIHJldHVybiBjb250ZW50O1xufVxuXG5mdW5jdGlvbiB3cml0ZUlmQ2hhbmdlZChmaWxlUGF0aDogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpIHtcbiAgZW5zdXJlRGlyZWN0b3J5KGZpbGVQYXRoKTtcbiAgZnMud3JpdGVGaWxlU3luYyhmaWxlUGF0aCwgY29udGVudCk7XG59XG5cbmV4cG9ydCBjb25zdCBkZWNvcmF0b3JUb29scyA9IHtcbiAgY3JlYXRlT3JVcGRhdGVNb2RlbFRvb2w6IHtcbiAgICBuYW1lOiBcImNyZWF0ZS1vci11cGRhdGUtbW9kZWxcIixcbiAgICBkZXNjcmlwdGlvbjogXCJDcmVhdGUgb3IgdXBkYXRlIGEgdmFsaWRhdGlvbi1yZWFkeSBtb2RlbCBjbGFzc1wiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICBjbGFzc0RlY29yYXRvcnM/OiBEZWNvcmF0b3JTcGVjW107XG4gICAgICBwcm9wZXJ0aWVzOiBBdHRyaWJ1dGVTcGVjW107XG4gICAgICBpbXBvcnRzRnJvbTogc3RyaW5nO1xuICAgICAgb3ZlcndyaXRlPzogYm9vbGVhbjtcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWFyZ3Mub3ZlcndyaXRlICYmIGZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGaWxlIGFscmVhZHkgZXhpc3RzIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBjb2xsZWN0RGVjb3JhdG9yTmFtZXMoXG4gICAgICAgIGFyZ3MuY2xhc3NEZWNvcmF0b3JzLFxuICAgICAgICBhcmdzLnByb3BlcnRpZXNcbiAgICAgICk7XG4gICAgICBsZXQgY29udGVudCA9IGBAbW9kZWwoKWA7XG4gICAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBhcmdzLmNsYXNzRGVjb3JhdG9ycyB8fCBbXSkge1xuICAgICAgICBjb250ZW50ICs9IGBcXG4ke2Zvcm1hdERlY29yYXRvcihkZWNvcmF0b3IpfWA7XG4gICAgICB9XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0gKGFyZ3MucHJvcGVydGllcyB8fCBbXSlcbiAgICAgICAgLm1hcChhZGRQcm9wZXJ0eUJsb2NrKVxuICAgICAgICAuam9pbihcIlxcblxcblwiKTtcbiAgICAgIGNvbnRlbnQgKz0gYFxcbmV4cG9ydCBjbGFzcyAke2FyZ3MuY2xhc3NOYW1lfSB7XFxuJHtwcm9wZXJ0aWVzID8gYCR7cHJvcGVydGllc31cXG5gIDogXCJcIn19XFxuYDtcbiAgICAgIGNvbnRlbnQgPSBlbnN1cmVJbXBvcnQoY29udGVudCwgYXJncy5pbXBvcnRzRnJvbSwgZGVjb3JhdG9ycyk7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCBjb250ZW50KTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgYWRkQXR0cmlidXRlVG9vbDoge1xuICAgIG5hbWU6IFwiYWRkLWF0dHJpYnV0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkFkZCBhIGRlY29yYXRlZCBhdHRyaWJ1dGUgdG8gYW4gZXhpc3RpbmcgbW9kZWxcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgYXR0cmlidXRlOiBBdHRyaWJ1dGVTcGVjO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBmaWxlIG5vdCBmb3VuZCBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBpZiAoY29udGVudC5pbmNsdWRlcyhgJHthcmdzLmF0dHJpYnV0ZS5uYW1lfTpgKSkge1xuICAgICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgICAgfVxuICAgICAgY29uc3QgZGVjb3JhdG9ycyA9IGNvbGxlY3REZWNvcmF0b3JOYW1lcyh1bmRlZmluZWQsIFthcmdzLmF0dHJpYnV0ZV0pO1xuICAgICAgY29udGVudCA9IGVuc3VyZUltcG9ydChjb250ZW50LCBhcmdzLmltcG9ydHNGcm9tLCBkZWNvcmF0b3JzKTtcbiAgICAgIGNvbnN0IGluc2VydGlvblBvaW50ID0gY29udGVudC5sYXN0SW5kZXhPZihcIn1cIik7XG4gICAgICBjb25zdCBibG9jayA9IGFkZFByb3BlcnR5QmxvY2soYXJncy5hdHRyaWJ1dGUpO1xuICAgICAgY29uc3QgYmVmb3JlID0gY29udGVudC5zbGljZSgwLCBpbnNlcnRpb25Qb2ludCkucmVwbGFjZSgvXFxzKiQvLCBcIlwiKTtcbiAgICAgIGNvbnN0IGFmdGVyID0gY29udGVudC5zbGljZShpbnNlcnRpb25Qb2ludCk7XG4gICAgICBjb25zdCB1cGRhdGVkID0gYCR7YmVmb3JlfVxcbiR7YmxvY2t9XFxuJHthZnRlcn1gO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgdXBkYXRlZCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHJlbW92ZUF0dHJpYnV0ZVRvb2w6IHtcbiAgICBuYW1lOiBcInJlbW92ZS1hdHRyaWJ1dGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJSZW1vdmUgYW4gYXR0cmlidXRlIGZyb20gYSBtb2RlbCBjbGFzc1wiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICBhdHRyaWJ1dGVOYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCB1cGRhdGVkID0gcmVtb3ZlUHJvcGVydHlCbG9jayhjb250ZW50LCBhcmdzLmF0dHJpYnV0ZU5hbWUpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgdXBkYXRlZCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIGFwcGx5RGVjb3JhdG9yVG9vbDoge1xuICAgIG5hbWU6IFwiYXBwbHktZGVjb3JhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQXBwbHkgYSBkZWNvcmF0b3IgdG8gYSBjbGFzcyBvciBwcm9wZXJ0eVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBmaWxlUGF0aDogc3RyaW5nO1xuICAgICAgY2xhc3NOYW1lOiBzdHJpbmc7XG4gICAgICB0YXJnZXQ6IHsga2luZDogXCJjbGFzc1wiIHwgXCJwcm9wZXJ0eVwiOyBuYW1lPzogc3RyaW5nIH07XG4gICAgICBkZWNvcmF0b3I6IERlY29yYXRvclNwZWM7XG4gICAgICBpbXBvcnRzRnJvbTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1vZGVsIGZpbGUgbm90IGZvdW5kIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICAgIH1cbiAgICAgIGxldCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBuZXcgU2V0PHN0cmluZz4oW2FyZ3MuZGVjb3JhdG9yLm5hbWVdKTtcbiAgICAgIGNvbnRlbnQgPSBlbnN1cmVJbXBvcnQoY29udGVudCwgYXJncy5pbXBvcnRzRnJvbSwgZGVjb3JhdG9ycyk7XG4gICAgICBjb250ZW50ID0gaW5zZXJ0RGVjb3JhdG9yKGNvbnRlbnQsIGFyZ3MuZGVjb3JhdG9yLCBhcmdzLnRhcmdldCk7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCBjb250ZW50KTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgcmVtb3ZlRGVjb3JhdG9yVG9vbDoge1xuICAgIG5hbWU6IFwicmVtb3ZlLWRlY29yYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlJlbW92ZSBhIGRlY29yYXRvciBmcm9tIGEgY2xhc3Mgb3IgcHJvcGVydHlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgdGFyZ2V0OiB7IGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjsgbmFtZT86IHN0cmluZyB9O1xuICAgICAgZGVjb3JhdG9yTmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIGxldCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyZ3MuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgIGNvbnRlbnQgPSByZW1vdmVEZWNvcmF0b3IoY29udGVudCwgYXJncy5kZWNvcmF0b3JOYW1lLCBhcmdzLnRhcmdldCk7XG4gICAgICB3cml0ZUlmQ2hhbmdlZChhcmdzLmZpbGVQYXRoLCBjb250ZW50KTtcbiAgICAgIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRWYWxpZGF0b3JUb29sOiB7XG4gICAgbmFtZTogXCJzY2FmZm9sZC12YWxpZGF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJTY2FmZm9sZCBhIHZhbGlkYXRvciBjbGFzcyBhbmQgb3B0aW9uYWwgZGVjb3JhdG9yXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIHZhbGlkYXRvcnNEaXI6IHN0cmluZztcbiAgICAgIGRlY29yYXRvckRpcj86IHN0cmluZztcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBjb25zdCBjbGFzc0ZpbGUgPSBwYXRoLmpvaW4oYXJncy52YWxpZGF0b3JzRGlyLCBgJHthcmdzLm5hbWV9LnRzYCk7XG4gICAgICBlbnN1cmVEaXJlY3RvcnkoY2xhc3NGaWxlKTtcbiAgICAgIGNvbnN0IGNsYXNzQ29udGVudCA9IGBleHBvcnQgY2xhc3MgJHthcmdzLm5hbWV9IHtcXG4gIHZhbGlkYXRlKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XFxuICAgIHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xcbiAgfVxcbn1cXG5gO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhjbGFzc0ZpbGUsIGNsYXNzQ29udGVudCk7XG4gICAgICBsZXQgZGVjb3JhdG9yRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGFyZ3MuZGVjb3JhdG9yRGlyKSB7XG4gICAgICAgIGRlY29yYXRvckZpbGUgPSBwYXRoLmpvaW4oXG4gICAgICAgICAgYXJncy5kZWNvcmF0b3JEaXIsXG4gICAgICAgICAgYCR7YXJncy5uYW1lfURlY29yYXRvci50c2BcbiAgICAgICAgKTtcbiAgICAgICAgZW5zdXJlRGlyZWN0b3J5KGRlY29yYXRvckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIGRlY29yYXRvckZpbGUsXG4gICAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiAke2FyZ3MubmFtZX1EZWNvcmF0b3IoKSB7XFxuICByZXR1cm4gKCkgPT4gdm9pZCAwO1xcbn1cXG5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBjbGFzc0ZpbGUsIGRlY29yYXRvckZpbGUgfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZFNlcmlhbGl6ZXJUb29sOiB7XG4gICAgbmFtZTogXCJzY2FmZm9sZC1zZXJpYWxpemVyXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSBzZXJpYWxpemVyIGNsYXNzIGFuZCBvcHRpb25hbCByZWdpc3RyeVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBkaXI6IHN0cmluZztcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIHJlZ2lzdGVyRGlyPzogc3RyaW5nO1xuICAgICAgc2V0RGVmYXVsdD86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgY2xhc3NGaWxlID0gcGF0aC5qb2luKGFyZ3MuZGlyLCBgJHthcmdzLm5hbWV9LnRzYCk7XG4gICAgICBlbnN1cmVEaXJlY3RvcnkoY2xhc3NGaWxlKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgIGNsYXNzRmlsZSxcbiAgICAgICAgYGV4cG9ydCBjbGFzcyAke2FyZ3MubmFtZX0ge1xcbiAgc2VyaWFsaXplKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcXG4gIH1cXG59XFxuYFxuICAgICAgKTtcbiAgICAgIGxldCByZWdpc3RlckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLnJlZ2lzdGVyRGlyKSB7XG4gICAgICAgIHJlZ2lzdGVyRmlsZSA9IHBhdGguam9pbihhcmdzLnJlZ2lzdGVyRGlyLCBgJHthcmdzLm5hbWV9UmVnaXN0ZXIudHNgKTtcbiAgICAgICAgZW5zdXJlRGlyZWN0b3J5KHJlZ2lzdGVyRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgcmVnaXN0ZXJGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXIke2FyZ3MubmFtZX0oKSB7XFxuICByZXR1cm4gJHthcmdzLnNldERlZmF1bHQgPyBcIidkZWZhdWx0J1wiIDogXCInb3B0aW9uYWwnXCJ9O1xcbn1cXG5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBjbGFzc0ZpbGUsIHJlZ2lzdGVyRmlsZSB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkSGFzaGluZ1Rvb2w6IHtcbiAgICBuYW1lOiBcInNjYWZmb2xkLWhhc2hpbmdcIixcbiAgICBkZXNjcmlwdGlvbjogXCJTY2FmZm9sZCBhIGhhc2hpbmcgZnVuY3Rpb24gYW5kIG9wdGlvbmFsIHJlZ2lzdHJ5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGRpcjogc3RyaW5nO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgcmVnaXN0ZXJEaXI/OiBzdHJpbmc7XG4gICAgICBzZXREZWZhdWx0PzogYm9vbGVhbjtcbiAgICB9KSA9PiB7XG4gICAgICBjb25zdCBmdW5jdGlvbkZpbGUgPSBwYXRoLmpvaW4oYXJncy5kaXIsIGAke2FyZ3MubmFtZX0udHNgKTtcbiAgICAgIGVuc3VyZURpcmVjdG9yeShmdW5jdGlvbkZpbGUpO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgZnVuY3Rpb25GaWxlLFxuICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uICR7YXJncy5uYW1lfSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcXG4gIHJldHVybiB2YWx1ZS5zcGxpdCgnJykucmV2ZXJzZSgpLmpvaW4oJycpO1xcbn1cXG5gXG4gICAgICApO1xuICAgICAgbGV0IHJlZ2lzdGVyRmlsZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGFyZ3MucmVnaXN0ZXJEaXIpIHtcbiAgICAgICAgcmVnaXN0ZXJGaWxlID0gcGF0aC5qb2luKGFyZ3MucmVnaXN0ZXJEaXIsIGAke2FyZ3MubmFtZX1SZWdpc3Rlci50c2ApO1xuICAgICAgICBlbnN1cmVEaXJlY3RvcnkocmVnaXN0ZXJGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICByZWdpc3RlckZpbGUsXG4gICAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlciR7YXJncy5uYW1lfSgpIHtcXG4gIHJldHVybiAke2FyZ3Muc2V0RGVmYXVsdCA/IFwiJ2RlZmF1bHQnXCIgOiBcIidvcHRpb25hbCdcIn07XFxufVxcbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGZ1bmN0aW9uRmlsZSwgcmVnaXN0ZXJGaWxlIH07XG4gICAgfSxcbiAgfSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIERlY29yYXRvclRvb2xzID0gdHlwZW9mIGRlY29yYXRvclRvb2xzO1xuIiwiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IENvbnRlbnRSZXN1bHQsIFRvb2wgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgYXBwbHlQYXRjaCwgY3JlYXRlVHdvRmlsZXNQYXRjaCB9IGZyb20gXCJkaWZmXCI7XG5pbXBvcnQge1xuICBhbmFseXplUmVwb1NjaGVtYSxcbiAgY29kZUNoYW5nZVNjaGVtYSxcbiAgZG9jdW1lbnRDb2RlU2NoZW1hLFxuICBlbnVtZXJhdGVDYXBhYmlsaXRpZXNTY2hlbWEsXG4gIHBsYW5GZWF0dXJlU2NoZW1hLFxufSBmcm9tIFwiLi4vc2NoZW1hc1wiO1xuaW1wb3J0IHsgYW5hbHl6ZVJlcG8gfSBmcm9tIFwiLi4vY29kZVwiO1xuaW1wb3J0IHsgZGVyaXZlQ2FwYWJpbGl0aWVzIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQge1xuICBnZXRXb3Jrc3BhY2VSb290LFxuICByZXNvbHZlSW5Xb3Jrc3BhY2UsXG4gIHRocm93VXNlckVycm9yLFxuICBXb3Jrc3BhY2VFcnJvcixcbn0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuLy8gTk9URTogcHJvbXB0IGhlbHBlcnMgKGJ1aWxkRG9jdW1lbnRhdGlvblBheWxvYWQsIGRpc2NvdmVyRG9jUHJvbXB0cywgc2VsZWN0UHJvbXB0LCBERUZBVUxUX1BST01QVF9OQU1FKVxuLy8gYXJlIGltcG9ydGVkIGR5bmFtaWNhbGx5IGluc2lkZSBkb2N1bWVudENvZGVUb29sLmV4ZWN1dGUgdG8gYXZvaWQgY3JlYXRpbmcgYSBzdGF0aWMgY2lyY3VsYXIgaW1wb3J0XG4vLyBhdCBtb2R1bGUgbG9hZCB0aW1lIChtb2R1bGVSZWdpc3RyeSAtPiBtb2R1bGVzIC0+IGRlY29yYXRpb24gdG9vbHMgLT4gbWNwL3Rvb2xzIC0+IHByb21wdHMpLlxuLy8gVGhleSB3aWxsIGJlIGxvYWRlZCB3aGVuIHRoZSB0b29sIGV4ZWN1dGVzLlxuaW1wb3J0IHR5cGUgeyBBcHBseUNvZGVDaGFuZ2VBcmdzLCBEb2N1bWVudENvZGVBcmdzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEFuYWx5emVSZXBvc2l0b3J5VG9vbCgpOiBUb29sPFxuICB1bmRlZmluZWQsXG4gIHR5cGVvZiBhbmFseXplUmVwb1NjaGVtYVxuPiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJhbmFseXplLXJlcG9zaXRvcnlcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiQW5hbHl6ZSBhIGxvY2FsIHJlcG9zaXRvcnkncyBzb3VyY2UsIHRlc3RzLCBhbmQgZG9jcyB0byBleHRyYWN0IGV4cG9ydGVkIEFQSXMsIGRlY29yYXRvcnMsIGFuZCB0ZXN0IG1lbnRpb25zLlwiLFxuICAgIHBhcmFtZXRlcnM6IGFuYWx5emVSZXBvU2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgbGV0IHJlcG9Sb290ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGlucHV0LnJlcG9QYXRoKTtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgLy8gdHJ5IHJlc29sdmluZyBmcm9tIG1vbm9yZXBvIHJvb3QgKHBhcmVudCBvZiBjdXJyZW50IGN3ZClcbiAgICAgICAgY29uc3QgYWx0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwiLi5cIiwgaW5wdXQucmVwb1BhdGgpO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQpKSByZXBvUm9vdCA9IGFsdDtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgLy8gaWYgaW5wdXQgd2FzIGFic29sdXRlIGFuZCBzdGlsbCBub3QgZm91bmQsIHRyeSAuLi88YmFzZW5hbWU+XG4gICAgICAgIGNvbnN0IGFsdDIgPSBwYXRoLnJlc29sdmUoXG4gICAgICAgICAgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICBcIi4uXCIsXG4gICAgICAgICAgcGF0aC5iYXNlbmFtZShpbnB1dC5yZXBvUGF0aClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoYWx0MikpIHJlcG9Sb290ID0gYWx0MjtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVwb3NpdG9yeSBub3QgZm91bmQgYXQgJHtyZXBvUm9vdH1gKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGFuYWx5emVSZXBvKHJlcG9Sb290KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpIH1dLFxuICAgICAgfTtcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRFbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sKCk6IFRvb2w8XG4gIHVuZGVmaW5lZCxcbiAgdHlwZW9mIGVudW1lcmF0ZUNhcGFiaWxpdGllc1NjaGVtYVxuPiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJlbnVtZXJhdGUtY2FwYWJpbGl0aWVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudW1lcmF0ZSBkZXZlbG9wZXItZmFjaW5nIGNhcGFiaWxpdGllcyBvZiB0aGUgZ2l2ZW4gcmVwb3NpdG9yeSwgaW5mZXJyZWQgZnJvbSBjb2RlLCB0ZXN0cywgYW5kIGRvY3MuXCIsXG4gICAgcGFyYW1ldGVyczogZW51bWVyYXRlQ2FwYWJpbGl0aWVzU2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgbGV0IHJlcG9Sb290ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGlucHV0LnJlcG9QYXRoKTtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgY29uc3QgYWx0ID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwiLi5cIiwgaW5wdXQucmVwb1BhdGgpO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQpKSByZXBvUm9vdCA9IGFsdDtcbiAgICAgIH1cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhyZXBvUm9vdCkpIHtcbiAgICAgICAgY29uc3QgYWx0MiA9IHBhdGgucmVzb2x2ZShcbiAgICAgICAgICBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgIFwiLi5cIixcbiAgICAgICAgICBwYXRoLmJhc2VuYW1lKGlucHV0LnJlcG9QYXRoKVxuICAgICAgICApO1xuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhhbHQyKSkgcmVwb1Jvb3QgPSBhbHQyO1xuICAgICAgfVxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlcG9Sb290KSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXBvc2l0b3J5IG5vdCBmb3VuZCBhdCAke3JlcG9Sb290fWApO1xuICAgICAgY29uc3QgYW5hbHlzaXMgPSBhbmFseXplUmVwbyhyZXBvUm9vdCk7XG4gICAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBkZXJpdmVDYXBhYmlsaXRpZXMoYW5hbHlzaXMpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXMsXG4gICAgICAgICAgICAgICAgYW5hbHlzaXNTdW1tYXJ5OiB7XG4gICAgICAgICAgICAgICAgICBmaWxlczogYW5hbHlzaXMuZmlsZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgdGVzdEZpbGVzOiBhbmFseXNpcy50ZXN0RmlsZXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgcmVhZG1lOiBhbmFseXNpcy5yZWFkbWU/LnRpdGxlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgIDJcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGxhbkZlYXR1cmVUb29sKCk6IFRvb2w8XG4gIHVuZGVmaW5lZCxcbiAgdHlwZW9mIHBsYW5GZWF0dXJlU2NoZW1hXG4+IHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBcInBsYW4tZmVhdHVyZS1pbXBsZW1lbnRhdGlvblwiLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgXCJHaXZlbiBhIGZlYXR1cmUgcmVxdWVzdCwgc2VsZWN0IGFwcHJvcHJpYXRlIE1DUCB0b29scyAoaW5jbHVkaW5nIGV4aXN0aW5nIGFuZCBuZXcgb25lcykgYW5kIHByb2R1Y2UgYW4gZXhlY3V0aW9uIHBsYW4uXCIsXG4gICAgcGFyYW1ldGVyczogcGxhbkZlYXR1cmVTY2hlbWEsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0KSA9PiB7XG4gICAgICBjb25zdCBzdGVwczogQXJyYXk8e1xuICAgICAgICBzdGVwOiBudW1iZXI7XG4gICAgICAgIGFjdGlvbjogc3RyaW5nO1xuICAgICAgICB0b29sPzogc3RyaW5nO1xuICAgICAgICBhcmd1bWVudHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgICByYXRpb25hbGU6IHN0cmluZztcbiAgICAgIH0+ID0gW107XG4gICAgICBsZXQgaSA9IDE7XG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgc3RlcDogaSsrLFxuICAgICAgICBhY3Rpb246IFwiQW5hbHl6ZSByZXBvc2l0b3J5IHRvIGVudW1lcmF0ZSBBUElzIGFuZCBkZWNvcmF0b3JzXCIsXG4gICAgICAgIHRvb2w6IFwiYW5hbHl6ZS1yZXBvc2l0b3J5XCIsXG4gICAgICAgIGFyZ3VtZW50czogeyByZXBvUGF0aDogaW5wdXQucmVwb1BhdGggfSxcbiAgICAgICAgcmF0aW9uYWxlOiBcIlVuZGVyc3RhbmQgYXZhaWxhYmxlIGJ1aWxkaW5nIGJsb2Nrcy5cIixcbiAgICAgIH0pO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkxpc3QgY2FwYWJpbGl0aWVzIGV4cGVjdGVkIGZvciBkZXZlbG9wZXJzXCIsXG4gICAgICAgIHRvb2w6IFwiZW51bWVyYXRlLWNhcGFiaWxpdGllc1wiLFxuICAgICAgICBhcmd1bWVudHM6IHsgcmVwb1BhdGg6IGlucHV0LnJlcG9QYXRoIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJBbGlnbiB0aGUgcGxhbiB3aXRoIHN1cHBvcnRlZCBjYXBhYmlsaXRpZXMuXCIsXG4gICAgICB9KTtcbiAgICAgIC8vIFN1Z2dlc3QgZXhpc3RpbmcgZ2VuZXJpYyB0b29scyBmcm9tIG1jcC1tb2R1bGVcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBzdGVwOiBpKyssXG4gICAgICAgIGFjdGlvbjpcbiAgICAgICAgICBcIlNlbGVjdCBkb2N1bWVudGF0aW9uIHByb21wdCBhbmQgZ2F0aGVyIHJlbGV2YW50IHNvdXJjZSBmaWxlKHMpXCIsXG4gICAgICAgIHRvb2w6IFwiZG9jdW1lbnQtY29kZVwiLFxuICAgICAgICBhcmd1bWVudHM6IHsgZmlsZVBhdGg6IFwiPHRhcmdldC1maWxlPlwiIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJQcm92aWRlIGNvbnRleHQgYW5kIGluc3RydWN0aW9ucyBmb3IgY2hhbmdlcy5cIixcbiAgICAgIH0pO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkFwcGx5IGNvZGUgY2hhbmdlcyB1c2luZyB1bmlmaWVkIGRpZmYgcGF0Y2hcIixcbiAgICAgICAgdG9vbDogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICBmaWxlUGF0aDogXCI8dGFyZ2V0LWZpbGU+XCIsXG4gICAgICAgICAgcGF0Y2g6IFwiPHVuaWZpZWQtZGlmZj5cIixcbiAgICAgICAgICBkcnlSdW46IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHJhdGlvbmFsZTogXCJWYWxpZGF0ZSBjaGFuZ2VzIHNhZmVseSBiZWZvcmUgY29tbWl0dGluZy5cIixcbiAgICAgIH0pO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIHN0ZXA6IGkrKyxcbiAgICAgICAgYWN0aW9uOiBcIkNvbW1pdCBjb2RlIGNoYW5nZXNcIixcbiAgICAgICAgdG9vbDogXCJhcHBseS1jb2RlLWNoYW5nZVwiLFxuICAgICAgICBhcmd1bWVudHM6IHtcbiAgICAgICAgICBmaWxlUGF0aDogXCI8dGFyZ2V0LWZpbGU+XCIsXG4gICAgICAgICAgcGF0Y2g6IFwiPHVuaWZpZWQtZGlmZj5cIixcbiAgICAgICAgICBkcnlSdW46IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICByYXRpb25hbGU6IFwiUGVyc2lzdCB0aGUgdXBkYXRlLlwiLFxuICAgICAgfSk7XG4gICAgICAvLyBJZiBkZWNvcmF0aW9uLXJlbGF0ZWQgdGVybXMgcHJlc2VudCwgc3VnZ2VzdCBkZWNvcmF0b3IgdG9vbHNcbiAgICAgIGlmICgvZGVjb3JhdHxmbGF2b3VyfG92ZXJyaWRlfGV4dGVuZHxidWlsZGVyL2kudGVzdChpbnB1dC5mZWF0dXJlKSkge1xuICAgICAgICBzdGVwcy51bnNoaWZ0KHtcbiAgICAgICAgICBzdGVwOiAwLFxuICAgICAgICAgIGFjdGlvbjogXCJVc2UgZGVjb3JhdG9yIHRvb2xpbmcgdG8gaW5zZXJ0L3JlbW92ZS9tb2RpZnkgZGVjb3JhdG9yc1wiLFxuICAgICAgICAgIHRvb2w6IFwiZGVjb3JhdG9yLXRvb2xzXCIsXG4gICAgICAgICAgYXJndW1lbnRzOiB7IGFjdGlvbjogXCJoZWxwXCIgfSxcbiAgICAgICAgICByYXRpb25hbGU6IFwiTGV2ZXJhZ2Ugc3BlY2lhbGl6ZWQgdXRpbGl0aWVzIGZvciBkZWNvcmF0aW9uIHBhdHRlcm5zLlwiLFxuICAgICAgICB9KTtcbiAgICAgICAgc3RlcHMuZm9yRWFjaCgocywgaWR4KSA9PiAocy5zdGVwID0gaWR4ICsgMSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwbGFuOiBzdGVwcyxcbiAgICAgICAgICAgICAgICBub3RlczpcbiAgICAgICAgICAgICAgICAgIFwiUmVwbGFjZSBwbGFjZWhvbGRlciBhcmd1bWVudHMgbGlrZSA8dGFyZ2V0LWZpbGU+IGFuZCA8dW5pZmllZC1kaWZmPiBiYXNlZCBvbiB0aGUgYW5hbHlzaXMgb3V0cHV0LlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAyXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBkb2N1bWVudENvZGVUb29sOiBUb29sPHVuZGVmaW5lZCwgdHlwZW9mIGRvY3VtZW50Q29kZVNjaGVtYT4gPSB7XG4gIGFubm90YXRpb25zOiB7XG4gICAgaWRlbXBvdGVudEhpbnQ6IHRydWUsXG4gICAgb3BlbldvcmxkSGludDogZmFsc2UsXG4gICAgcmVhZE9ubHlIaW50OiB0cnVlLFxuICAgIHRpdGxlOiBcIkRvY3VtZW50IFNvdXJjZSBGaWxlXCIsXG4gIH0sXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBndWlkYW5jZSBmb3IgYSBmaWxlIGJ5IGNvbWJpbmluZyByZXBvc2l0b3J5IHByb21wdHMgd2l0aCB0aGUgdGFyZ2V0IHNvdXJjZSBjb2RlLlwiLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgX2NvbnRleHQpOiBQcm9taXNlPENvbnRlbnRSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gZG9jdW1lbnRDb2RlU2NoZW1hLnBhcnNlKGlucHV0IGFzIERvY3VtZW50Q29kZUFyZ3MpO1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgbGV0IGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVQYXRoID0gcmVzb2x2ZUluV29ya3NwYWNlKHJvb3QsIGFyZ3MuZmlsZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXb3Jrc3BhY2VFcnJvcikge1xuICAgICAgICByZXR1cm4gdGhyb3dVc2VyRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGVQYXRoKSkge1xuICAgICAgcmV0dXJuIHRocm93VXNlckVycm9yKGBDYW5ub3QgZG9jdW1lbnQgbWlzc2luZyBmaWxlIGF0ICR7YXJncy5maWxlUGF0aH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwge1xuICAgICAgZW5jb2Rpbmc6IGFyZ3MuZW5jb2RpbmcgYXMgQnVmZmVyRW5jb2RpbmcsXG4gICAgfSk7XG4gICAgLy8gZHluYW1pY2FsbHkgaW1wb3J0IHByb21wdCBoZWxwZXJzXG4gICAgY29uc3QgcHJvbXB0TW9kID0gYXdhaXQgaW1wb3J0KFwiLi4vcHJvbXB0cy9wcm9tcHRzXCIpO1xuICAgIGNvbnN0IHtcbiAgICAgIGRpc2NvdmVyRG9jUHJvbXB0cyxcbiAgICAgIHNlbGVjdFByb21wdCxcbiAgICAgIERFRkFVTFRfUFJPTVBUX05BTUUsXG4gICAgICBidWlsZERvY3VtZW50YXRpb25QYXlsb2FkLFxuICAgIH0gPSBwcm9tcHRNb2Q7XG4gICAgY29uc3QgcHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KTtcblxuICAgIGlmICghcHJvbXB0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgXCJObyBkb2N1bWVudGF0aW9uIHByb21wdHMgZm91bmQgdW5kZXIgLmNvZGUvcHJvbXB0cyBvciAuY29kZXgvcHJvbXB0c1wiXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHByb21wdCA9IHNlbGVjdFByb21wdChcbiAgICAgIHByb21wdHMsXG4gICAgICBhcmdzLnByb21wdE5hbWUgPz8gREVGQVVMVF9QUk9NUFRfTkFNRVxuICAgICk7XG5cbiAgICByZXR1cm4gYnVpbGREb2N1bWVudGF0aW9uUGF5bG9hZCh7XG4gICAgICBmaWxlUGF0aDogYXJncy5maWxlUGF0aCxcbiAgICAgIGZpbGVDb250ZW50LFxuICAgICAgcHJvbXB0LFxuICAgICAgaW5jbHVkZUNvZGU6IGFyZ3MuaW5jbHVkZUNvZGUsXG4gICAgICBpbmNsdWRlUHJvbXB0OiBhcmdzLmluY2x1ZGVQcm9tcHQsXG4gICAgICBpbmNsdWRlTWV0YWRhdGE6IGFyZ3MuaW5jbHVkZU1ldGFkYXRhLFxuICAgICAgYWRkaXRpb25hbENvbnRleHQ6IGFyZ3MuYWRkaXRpb25hbENvbnRleHQsXG4gICAgfSk7XG4gIH0sXG4gIG5hbWU6IFwiZG9jdW1lbnQtY29kZVwiLFxuICBwYXJhbWV0ZXJzOiBkb2N1bWVudENvZGVTY2hlbWEsXG59O1xuXG5leHBvcnQgY29uc3QgYXBwbHlDb2RlQ2hhbmdlVG9vbDogVG9vbDx1bmRlZmluZWQsIHR5cGVvZiBjb2RlQ2hhbmdlU2NoZW1hPiA9IHtcbiAgYW5ub3RhdGlvbnM6IHtcbiAgICBkZXN0cnVjdGl2ZUhpbnQ6IHRydWUsXG4gICAgaWRlbXBvdGVudEhpbnQ6IGZhbHNlLFxuICAgIG9wZW5Xb3JsZEhpbnQ6IGZhbHNlLFxuICAgIHJlYWRPbmx5SGludDogZmFsc2UsXG4gICAgdGl0bGU6IFwiQXBwbHkgQ29kZSBQYXRjaFwiLFxuICB9LFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIkFwcGx5IGEgdW5pZmllZCBkaWZmIHBhdGNoIHRvIGEgd29ya3NwYWNlIGZpbGUgd2l0aCBvcHRpb25hbCBkcnktcnVuIHZhbGlkYXRpb24gYW5kIGRpZmYgcHJldmlldy5cIixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIF9jb250ZXh0KTogUHJvbWlzZTxzdHJpbmcgfCBDb250ZW50UmVzdWx0PiA9PiB7XG4gICAgY29uc3QgYXJncyA9IGNvZGVDaGFuZ2VTY2hlbWEucGFyc2UoaW5wdXQgYXMgQXBwbHlDb2RlQ2hhbmdlQXJncyk7XG4gICAgY29uc3Qgcm9vdCA9IGdldFdvcmtzcGFjZVJvb3QoKTtcbiAgICBsZXQgZmlsZVBhdGg6IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgZmlsZVBhdGggPSByZXNvbHZlSW5Xb3Jrc3BhY2Uocm9vdCwgYXJncy5maWxlUGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtzcGFjZUVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGNvbnN0IG9yaWdpbmFsID0gZnMuZXhpc3RzU3luYyhmaWxlUGF0aClcbiAgICAgID8gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBhcmdzLmVuY29kaW5nIGFzIEJ1ZmZlckVuY29kaW5nKVxuICAgICAgOiBcIlwiO1xuXG4gICAgbGV0IHBhdGNoZWQ6IHN0cmluZyB8IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICBwYXRjaGVkID0gYXBwbHlQYXRjaChvcmlnaW5hbCwgYXJncy5wYXRjaCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBhcHBseSBwcm92aWRlZCBwYXRjaCB0byAke2FyZ3MuZmlsZVBhdGh9OiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogZXJyb3J9YFxuICAgICAgKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAocGF0Y2hlZCA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiB0aHJvd1VzZXJFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBhcHBseSBwcm92aWRlZCBwYXRjaCB0byAke2FyZ3MuZmlsZVBhdGh9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWFyZ3MuZHJ5UnVuKSB7XG4gICAgICBmcy5ta2RpclN5bmMocGF0aC5kaXJuYW1lKGZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBwYXRjaGVkLCB7XG4gICAgICAgIGVuY29kaW5nOiBhcmdzLmVuY29kaW5nIGFzIEJ1ZmZlckVuY29kaW5nLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCFhcmdzLnNob3dEaWZmKSB7XG4gICAgICByZXR1cm4gYFBhdGNoICR7YXJncy5kcnlSdW4gPyBcInZhbGlkYXRlZFwiIDogXCJhcHBsaWVkXCJ9IGZvciAke2FyZ3MuZmlsZVBhdGh9YDtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aWV3ID0gY3JlYXRlVHdvRmlsZXNQYXRjaChcbiAgICAgIGFyZ3MuZmlsZVBhdGgsXG4gICAgICBhcmdzLmZpbGVQYXRoLFxuICAgICAgb3JpZ2luYWwsXG4gICAgICBwYXRjaGVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgeyBjb250ZXh0OiBhcmdzLmRpZmZDb250ZXh0IH1cbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGBQYXRjaCAke2FyZ3MuZHJ5UnVuID8gXCJ2YWxpZGF0ZWRcIiA6IFwiYXBwbGllZFwifSBmb3IgJHthcmdzLmZpbGVQYXRofWAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBbXCJgYGBkaWZmXCIsIHByZXZpZXcudHJpbSgpLCBcImBgYFwiXS5qb2luKFwiXFxuXCIpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9IHNhdGlzZmllcyBDb250ZW50UmVzdWx0O1xuICB9LFxuICBuYW1lOiBcImFwcGx5LWNvZGUtY2hhbmdlXCIsXG4gIHBhcmFtZXRlcnM6IGNvZGVDaGFuZ2VTY2hlbWEsXG59O1xuXG50eXBlIEFueVRvb2wgPSBUb29sPHVuZGVmaW5lZCwgYW55PjtcblxuY29uc3QgYW5hbHl0aWNUb29sczogQW55VG9vbFtdID0gW1xuICBidWlsZEFuYWx5emVSZXBvc2l0b3J5VG9vbCgpLFxuICBidWlsZEVudW1lcmF0ZUNhcGFiaWxpdGllc1Rvb2woKSxcbiAgYnVpbGRQbGFuRmVhdHVyZVRvb2woKSxcbl07XG5cbmV4cG9ydCBjb25zdCB0b29sTGlzdDogQW55VG9vbFtdID0gW1xuICAuLi5hbmFseXRpY1Rvb2xzLFxuICBkb2N1bWVudENvZGVUb29sLFxuICBhcHBseUNvZGVDaGFuZ2VUb29sLFxuXTtcbiIsImltcG9ydCB7IG1vZHVsZVJlZ2lzdHJ5IH0gZnJvbSBcIi4uL21vZHVsZVJlZ2lzdHJ5XCI7XG5pbXBvcnQge1xuICBjb3ZlcmFnZUVuZm9yY2VyVG9vbCxcbiAgZG9jdW1lbnRPYmplY3RUb29sLFxuICByZWFkbWVJbXByb3ZlbWVudFRvb2wsXG59IGZyb20gXCIuL2NvZGV4LXRvb2xzXCI7XG5pbXBvcnQgeyBkZWNvcmF0b3JUb29scyB9IGZyb20gXCIuLi9kZWNvcmF0b3ItdG9vbHNcIjtcbmNvbnN0IGNvZGV4VG9vbExpc3QgPSBbXG4gIGRvY3VtZW50T2JqZWN0VG9vbCxcbiAgY292ZXJhZ2VFbmZvcmNlclRvb2wsXG4gIHJlYWRtZUltcHJvdmVtZW50VG9vbCxcbl07XG5cbmltcG9ydCB7IHRvb2xMaXN0IGFzIGNvcmVUb29sTGlzdCB9IGZyb20gXCIuL3Rvb2xzXCI7XG5cbmNvbnN0IG1vZHVsZVRvb2xMaXN0ID0gbW9kdWxlUmVnaXN0cnlcbiAgLmxpc3RUb29scygpXG4gIC5tYXAoKGFzc2V0KSA9PiBhc3NldC50b29sIGFzIGFueSk7XG5cbmV4cG9ydCBjb25zdCB0b29sTGlzdCA9IFsuLi5jb3JlVG9vbExpc3QsIC4uLmNvZGV4VG9vbExpc3QsIC4uLm1vZHVsZVRvb2xMaXN0XTtcbmNvbnN0IFtcbiAgYW5hbHl6ZVJlcG9zaXRvcnlUb29sLFxuICBlbnVtZXJhdGVDYXBhYmlsaXRpZXNUb29sLFxuICBwbGFuRmVhdHVyZVRvb2wsXG4gIGRvY3VtZW50Q29kZVRvb2xSZWYsXG4gIGFwcGx5Q29kZUNoYW5nZVRvb2xSZWYsXG5dID0gY29yZVRvb2xMaXN0O1xuXG5leHBvcnQgY29uc3QgdG9vbHMgPSB7XG4gIGFuYWx5emVSZXBvc2l0b3J5VG9vbCxcbiAgZW51bWVyYXRlQ2FwYWJpbGl0aWVzVG9vbCxcbiAgcGxhbkZlYXR1cmVUb29sLFxuICBkb2N1bWVudENvZGVUb29sOiBkb2N1bWVudENvZGVUb29sUmVmLFxuICBhcHBseUNvZGVDaGFuZ2VUb29sOiBhcHBseUNvZGVDaGFuZ2VUb29sUmVmLFxuICBkb2N1bWVudE9iamVjdFRvb2wsXG4gIGNvdmVyYWdlRW5mb3JjZXJUb29sLFxuICByZWFkbWVJbXByb3ZlbWVudFRvb2wsXG4gIC4uLmRlY29yYXRvclRvb2xzLFxufTtcbmV4cG9ydCB7IGRlY29yYXRvclRvb2xzIH07XG4iLCJpbXBvcnQgdHlwZSB7IFJlc291cmNlIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB0eXBlIHsgUmVzb3VyY2VBc3NldCB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUmVnaXN0cnkgfSBmcm9tIFwiLi4vbW9kdWxlUmVnaXN0cnlcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QgfSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5pbXBvcnQgeyBidWlsZE9iamVjdFByb21wdHMsIGRpc2NvdmVyRG9jUHJvbXB0cyB9IGZyb20gXCIuLi9wcm9tcHRzL3Byb21wdHNcIjtcblxuZnVuY3Rpb24gdG9SZXNvdXJjZShhc3NldDogUmVzb3VyY2VBc3NldCk6IFJlc291cmNlPHVuZGVmaW5lZD4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IGFzc2V0LmlkLFxuICAgIHVyaTogYXNzZXQudXJpLFxuICAgIGRlc2NyaXB0aW9uOiBhc3NldC5kZXNjcmlwdGlvbiA/PyBhc3NldC50aXRsZSxcbiAgICBtaW1lVHlwZTogYXNzZXQubWltZVR5cGUsXG4gICAgbG9hZDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXNzZXQubG9hZCgpO1xuICAgICAgLy8gYXNzZXQubG9hZCBtYXkgcmV0dXJuIGEgQ29udGVudFJlc3VsdCBvciBhIFByb21pc2Ugb2YgQ29udGVudFJlc3VsdDsgZW5zdXJlIHdlIHJldHVybiBSZXNvdXJjZVJlc3VsdC1saWtlIG9iamVjdFxuICAgICAgaWYgKChyZXMgYXMgYW55KT8uY29udGVudCkge1xuICAgICAgICBjb25zdCBjciA9IHJlcyBhcyBhbnk7XG4gICAgICAgIC8vIElmIENvbnRlbnRSZXN1bHQsIGNvbnZlcnQgdG8gc2ltcGxlIHRleHQgcmVzdWx0IGV4cGVjdGVkIGJ5IFJlc291cmNlLmxvYWQgY29uc3VtZXJzXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdGV4dDogQXJyYXkuaXNBcnJheShjci5jb250ZW50KVxuICAgICAgICAgICAgPyBjci5jb250ZW50Lm1hcCgoYzogYW55KSA9PiBjLnRleHQpLmpvaW4oXCJcXG5cIilcbiAgICAgICAgICAgIDogU3RyaW5nKGNyKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIC8vIGZhbGxiYWNrIGZvciBvYmplY3RzIHdpdGggdGV4dFxuICAgICAgcmV0dXJuIHJlcyBhcyBhbnkgYXMgeyB0ZXh0OiBzdHJpbmcgfTtcbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZE1vZHVsZVJlc291cmNlcygpOiBSZXNvdXJjZTx1bmRlZmluZWQ+W10ge1xuICByZXR1cm4gbW9kdWxlUmVnaXN0cnkubGlzdFJlc291cmNlcygpLm1hcCh0b1Jlc291cmNlKTtcbn1cblxuZXhwb3J0IGNvbnN0IHJlc291cmNlczogUmVzb3VyY2U8dW5kZWZpbmVkPltdID0gW1xuICB7XG4gICAgbmFtZTogXCJjb2RleC1wcm9tcHQtaW5kZXhcIixcbiAgICB1cmk6IFwiY29kZXg6Ly9wcm9tcHRzL2luZGV4XCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIkVudW1lcmF0ZSBhdmFpbGFibGUgLmNvZGV4IHByb21wdCBmaWxlcyB3aXRoIHRpdGxlcyBhbmQgZGVzY3JpcHRpb25zLlwiLFxuICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpO1xuICAgICAgY29uc3QgcHJvbXB0cyA9IGRpc2NvdmVyRG9jUHJvbXB0cyhyb290KS5tYXAoKHByb21wdCkgPT4gKHtcbiAgICAgICAgbmFtZTogcHJvbXB0Lm5hbWUsXG4gICAgICAgIHRpdGxlOiBwcm9tcHQudGl0bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgICAgIHBhdGg6IHByb21wdC5hYnNvbHV0ZVBhdGgsXG4gICAgICB9KSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeSh7IHByb21wdHMgfSwgbnVsbCwgMiksXG4gICAgICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH07XG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6IFwiY29kZXgtb2JqZWN0LXByb21wdHNcIixcbiAgICB1cmk6IFwiY29kZXg6Ly9wcm9tcHRzL29iamVjdHNcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiUHJvdmlkZXMgdGhlIHJlc29sdmVkIHByb21wdCBjb250ZW50IGZvciBlYWNoIGRvY3VtZW50ZWQgb2JqZWN0IHdvcmtmbG93LlwiLFxuICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICBsb2FkOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIGJ1aWxkT2JqZWN0UHJvbXB0cygpLm1hcChhc3luYyAocHJvbXB0KSA9PiAoe1xuICAgICAgICAgIG5hbWU6IHByb21wdC5uYW1lLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBwcm9tcHQuZGVzY3JpcHRpb24sXG4gICAgICAgICAgY29udGVudDogYXdhaXQgcHJvbXB0LmxvYWQoe30gYXMgbmV2ZXIpLFxuICAgICAgICB9KSlcbiAgICAgICk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeSh7IHByb21wdHM6IGVudHJpZXMgfSwgbnVsbCwgMiksXG4gICAgICAgIG1pbWVUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH07XG4gICAgfSxcbiAgfSxcbiAgLi4uYnVpbGRNb2R1bGVSZXNvdXJjZXMoKSxcbl07XG4iLCJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCwgcmVzb2x2ZUluV29ya3NwYWNlIH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHR5cGUgeyBQcm9tcHRSZXNvdXJjZVRlbXBsYXRlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBjb2RleFByb21wdFRlbXBsYXRlczogUHJvbXB0UmVzb3VyY2VUZW1wbGF0ZVtdID0gW107XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENvZGV4UHJvbXB0VGVtcGxhdGVzKCk6IFByb21wdFJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHRlbXBsYXRlczogUHJvbXB0UmVzb3VyY2VUZW1wbGF0ZVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwiY29kZXgtcHJvbXB0XCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJMb2FkIGEgLmNvZGV4IHByb21wdCBmaWxlIGJ5IG5hbWUgKHdpdGhvdXQgZXh0ZW5zaW9uKSBhcyBtYXJrZG93bi5cIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImNvZGV4LXByb21wdDovL3tuYW1lfVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9tYXJrZG93blwiLFxuICAgICAgYXJndW1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIm5hbWVcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiTmFtZSBvZiB0aGUgcHJvbXB0IGZpbGUgaW5zaWRlIC5jb2RleC9wcm9tcHRzICh3aXRob3V0IC5tZCkuXCIsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgbG9hZDogYXN5bmMgKHsgbmFtZSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHByb21wdFBhdGggPSByZXNvbHZlSW5Xb3Jrc3BhY2UoXG4gICAgICAgICAgcm9vdCxcbiAgICAgICAgICBwYXRoLmpvaW4oXCIuY29kZXhcIiwgXCJwcm9tcHRzXCIsIGAke25hbWV9Lm1kYClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHByb21wdFBhdGgpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm9tcHQgLmNvZGV4L3Byb21wdHMvJHtuYW1lfS5tZCBub3QgZm91bmRgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0ZXh0ID0gZnMucmVhZEZpbGVTeW5jKHByb21wdFBhdGgsIFwidXRmOFwiKTtcbiAgICAgICAgcmV0dXJuIHsgdGV4dCwgdXJpOiBgY29kZXgtcHJvbXB0Oi8vLyR7bmFtZX1gIH07XG4gICAgICB9LFxuICAgIH0sXG4gIF07XG5cbiAgY29kZXhQcm9tcHRUZW1wbGF0ZXMuc3BsaWNlKDAsIGNvZGV4UHJvbXB0VGVtcGxhdGVzLmxlbmd0aCwgLi4udGVtcGxhdGVzKTtcbiAgcmV0dXJuIGNvZGV4UHJvbXB0VGVtcGxhdGVzO1xufVxuIiwiaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB0eXBlIHsgRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IGdldFdvcmtzcGFjZVJvb3QsIHJlYWRXb3Jrc3BhY2VGaWxlIH0gZnJvbSBcIi4uL3dvcmtzcGFjZVwiO1xuXG5leHBvcnQgY29uc3QgZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzOiBEZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZVtdID0gW107XG5cbmZ1bmN0aW9uIG1ha2VMb2FkZXIodHlwZTogXCJzcmNcIiB8IFwidGVzdHNcIiB8IFwid29ya2RvY3NcIikge1xuICByZXR1cm4gYXN5bmMgKHsgcGF0aDogcmVsYXRpdmUgfTogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gcGF0aC5qb2luKHR5cGUsIHJlbGF0aXZlKTtcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgdGFyZ2V0KTtcbiAgICByZXR1cm4geyB0ZXh0IH07XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZERlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcygpOiBEZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZVtdIHtcbiAgY29uc3QgdGVtcGxhdGVzOiBEZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwicmVhZC1jb2RlLWZyb20tc291cmNlXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJSZWFkIGEgZmlsZSBmcm9tIHRoZSA8YmFzZV9wYXRoPi9zcmMgdHJlZSBieSByZWxhdGl2ZSBwYXRoLlwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiZnJvbS1zb3VyY2U6Ly9zcmMve3BhdGh9XCIsXG4gICAgICBhcmd1bWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJQYXRoIHVuZGVyIDxiYXNlX3BhdGg+L3NyYyB0byBsb2FkLCBlLmcuICdkZWNvcmF0aW9uL3R5cGVzLnRzJ1wiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IG1ha2VMb2FkZXIoXCJzcmNcIiksXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcInJlYWQtdGVzdC1mcm9tLXNvdXJjZVwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiUmVhZCBhIGZpbGUgZnJvbSB0aGUgPGJhc2VfcGF0aD4vdGVzdHMgdHJlZSBieSByZWxhdGl2ZSBwYXRoLlwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiZnJvbS1zb3VyY2U6Ly90ZXN0cy97cGF0aH1cIixcbiAgICAgIGFyZ3VtZW50czogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJwYXRoXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIlBhdGggdW5kZXIgPGJhc2VfcGF0aD4vdGVzdHMgdG8gbG9hZCwgZS5nLiAnZGVjb3JhdGlvbi90ZXN0cy90eXBlcy50ZXN0LnRzJ1wiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IG1ha2VMb2FkZXIoXCJ0ZXN0c1wiKSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IFwicmVhZC1kb2MtZnJvbS1zb3VyY2VcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIlJlYWQgYSBmaWxlIGZyb20gdGhlIDxiYXNlX3BhdGg+L3dvcmtkb2NzIHRyZWUgYnkgcmVsYXRpdmUgcGF0aC5cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcImZyb20tc291cmNlOi8vd29ya2RvY3Mve3BhdGh9XCIsXG4gICAgICBhcmd1bWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicGF0aFwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJQYXRoIHVuZGVyIDxiYXNlX3BhdGg+L3dvcmtkb2NzIHRvIGxvYWQsIGUuZy4gJ2RlY29yYXRpb24vd29ya2RvY3MvdHV0b3JpYWxzL2Zvci1kZXZlbG9wZXJzLm1kJ1wiLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxvYWQ6IG1ha2VMb2FkZXIoXCJ3b3JrZG9jc1wiKSxcbiAgICB9LFxuICBdO1xuXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcy5zcGxpY2UoXG4gICAgMCxcbiAgICBkZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMubGVuZ3RoLFxuICAgIC4uLnRlbXBsYXRlc1xuICApO1xuICByZXR1cm4gZGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzO1xufVxuIiwiaW1wb3J0IHsgV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0V29ya3NwYWNlUm9vdCwgcmVhZFdvcmtzcGFjZUZpbGUgfSBmcm9tIFwiLi4vd29ya3NwYWNlXCI7XG5cbmV4cG9ydCBjb25zdCB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlczogV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZVtdID0gW107XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzKCk6IFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVbXSB7XG4gIGNvbnN0IHJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCk7XG4gIGNvbnN0IHNoYXJlZEFyZ3VtZW50cyA9IFtcbiAgICB7XG4gICAgICBuYW1lOiBcInBhdGhcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlBhdGggcmVsYXRpdmUgdG8gdGhlIHdvcmtzcGFjZSByb290XCIsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICB9LFxuICBdIGFzIGNvbnN0O1xuXG4gIGNvbnN0IHRlbXBsYXRlczogV29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZVtdID0gW1xuICAgIHtcbiAgICAgIG5hbWU6IFwidnNjb2RlLXdvcmtzcGFjZS1maWxlXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJFeHBvc2Ugd29ya3NwYWNlIGZpbGVzIHRvIFZpc3VhbCBTdHVkaW8gQ29kZSB2aWEgdnNjb2RlOi8vIFVSSXNcIixcbiAgICAgIHVyaVRlbXBsYXRlOiBcInZzY29kZTovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgICByZXR1cm4geyB0ZXh0OiBTdHJpbmcodGV4dCkgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy8gcHJvcGFnYXRlIGFzLWlzIGZvciB0ZXN0cyB0byBhc3NlcnQgZXJyb3JzXG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogXCJjdXJzb3Itd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gQ3Vyc29yIHZpYSBjdXJzb3I6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY3Vyc29yOi8vd29ya3NwYWNlL3twYXRofVwiLFxuICAgICAgbWltZVR5cGU6IFwidGV4dC9wbGFpblwiLFxuICAgICAgYXJndW1lbnRzOiBzaGFyZWRBcmd1bWVudHMsXG4gICAgICBsb2FkOiBhc3luYyAoYXJnczogeyBwYXRoOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZWFkV29ya3NwYWNlRmlsZShyb290LCBhcmdzLnBhdGgpO1xuICAgICAgICAgIHJldHVybiB7IHRleHQ6IFN0cmluZyh0ZXh0KSB9O1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBcImNvcGlsb3Qtd29ya3NwYWNlLWZpbGVcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkV4cG9zZSB3b3Jrc3BhY2UgZmlsZXMgdG8gR2l0SHViIENvcGlsb3QgdmlhIGNvcGlsb3Q6Ly8gVVJJc1wiLFxuICAgICAgdXJpVGVtcGxhdGU6IFwiY29waWxvdDovL3dvcmtzcGFjZS97cGF0aH1cIixcbiAgICAgIG1pbWVUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgIGFyZ3VtZW50czogc2hhcmVkQXJndW1lbnRzLFxuICAgICAgbG9hZDogYXN5bmMgKGFyZ3M6IHsgcGF0aDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVhZFdvcmtzcGFjZUZpbGUocm9vdCwgYXJncy5wYXRoKTtcbiAgICAgICAgICByZXR1cm4geyB0ZXh0OiBTdHJpbmcodGV4dCkgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gIF07XG5cbiAgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMuc3BsaWNlKFxuICAgIDAsXG4gICAgd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXMubGVuZ3RoLFxuICAgIC4uLnRlbXBsYXRlc1xuICApO1xuICByZXR1cm4gd29ya3NwYWNlUmVzb3VyY2VUZW1wbGF0ZXM7XG59XG5cbiIsImltcG9ydCB7IGJ1aWxkQ29kZXhQcm9tcHRUZW1wbGF0ZXMgfSBmcm9tIFwiLi9jb2RleC10ZW1wbGF0ZXNcIjtcbmltcG9ydCB7IGJ1aWxkRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzIH0gZnJvbSBcIi4vcmVzb3VyY2UtdGVtcGxhdGVzXCI7XG5pbXBvcnQgeyBidWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzIH0gZnJvbSBcIi4vd29ya3NwYWNlLXRlbXBsYXRlc1wiO1xuaW1wb3J0IHsgbW9kdWxlUmVnaXN0cnkgfSBmcm9tIFwiLi4vbW9kdWxlUmVnaXN0cnlcIjtcblxuZXhwb3J0IHtcbiAgYnVpbGRDb2RleFByb21wdFRlbXBsYXRlcyxcbiAgY29kZXhQcm9tcHRUZW1wbGF0ZXMsXG59IGZyb20gXCIuL2NvZGV4LXRlbXBsYXRlc1wiO1xuZXhwb3J0IHtcbiAgYnVpbGREZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vcmVzb3VyY2UtdGVtcGxhdGVzXCI7XG5leHBvcnQge1xuICBidWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLFxuICB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vd29ya3NwYWNlLXRlbXBsYXRlc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpIHtcbiAgY29uc3QgbW9kdWxlVGVtcGxhdGVzID0gbW9kdWxlUmVnaXN0cnkubGlzdFRlbXBsYXRlcygpLm1hcCgodGVtcGxhdGUpID0+ICh7XG4gICAgbmFtZTogdGVtcGxhdGUuaWQsXG4gICAgZGVzY3JpcHRpb246IHRlbXBsYXRlLmRlc2NyaXB0aW9uID8/IHRlbXBsYXRlLnRpdGxlLFxuICAgIG1pbWVUeXBlOiBcInRleHQvbWFya2Rvd25cIixcbiAgICB1cmlUZW1wbGF0ZTogYG1vZHVsZS10ZW1wbGF0ZTovLyR7dGVtcGxhdGUuaWR9YCxcbiAgICBhcmd1bWVudHM6ICh0ZW1wbGF0ZS5wbGFjZWhvbGRlcnMgPz8gW10pLm1hcCgobmFtZSkgPT4gKHtcbiAgICAgIG5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogYFZhbHVlIGZvciAke25hbWV9YCxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0pKSxcbiAgICBsb2FkOiBhc3luYyAoKSA9PiAoe1xuICAgICAgdGV4dDpcbiAgICAgICAgdHlwZW9mICh0ZW1wbGF0ZSBhcyBhbnkpLmNvbnRlbnQgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICA/ICh0ZW1wbGF0ZSBhcyBhbnkpLmNvbnRlbnRcbiAgICAgICAgICA6IGAjICR7dGVtcGxhdGUuZGVzY3JpcHRpb24gPz8gdGVtcGxhdGUudGl0bGUgPz8gdGVtcGxhdGUuaWR9XFxuXFxuTm8gdGVtcGxhdGUgY29udGVudCBhdmFpbGFibGUgZm9yICR7dGVtcGxhdGUuaWR9YCxcbiAgICB9KSxcbiAgfSkpO1xuXG4gIGNvbnN0IGFsbCA9IFtcbiAgICAuLi5idWlsZFdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzKCksXG4gICAgLi4uYnVpbGRDb2RleFByb21wdFRlbXBsYXRlcygpLFxuICAgIC4uLmJ1aWxkRGVjb3JhdGlvblJlc291cmNlVGVtcGxhdGVzKCksXG4gICAgLi4ubW9kdWxlVGVtcGxhdGVzLFxuICBdO1xuXG4gIC8vIE5vcm1hbGlzZSBhbGwgbG9hZGVycyB0byBhbHdheXMgcmV0dXJuIHsgdGV4dDogc3RyaW5nIH1cbiAgZnVuY3Rpb24gbm9ybWFsaXNlUmVzdWx0KHJlczogYW55KSB7XG4gICAgaWYgKHJlcyA9PSBudWxsKSByZXR1cm4geyB0ZXh0OiBcIlwiIH07XG4gICAgaWYgKHR5cGVvZiByZXMgPT09IFwic3RyaW5nXCIpIHJldHVybiB7IHRleHQ6IHJlcyB9O1xuICAgIGlmICh0eXBlb2YgcmVzLnRleHQgPT09IFwic3RyaW5nXCIpIHJldHVybiByZXM7XG4gICAgLy8gaGFuZGxlIGxlZ2FjeSBDb250ZW50UmVzdWx0IHNoYXBlcyB3aXRoIGNvbnRlbnQgb3IgY29udGVudCBhcnJheVxuICAgIGlmIChBcnJheS5pc0FycmF5KHJlcy5jb250ZW50KSkge1xuICAgICAgY29uc3QgcGFydHMgPSByZXMuY29udGVudFxuICAgICAgICAubWFwKChjOiBhbnkpID0+IChjICYmIHR5cGVvZiBjLnRleHQgPT09IFwic3RyaW5nXCIgPyBjLnRleHQgOiBTdHJpbmcoYykpKVxuICAgICAgICAuam9pbihcIlxcblwiKTtcbiAgICAgIHJldHVybiB7IHRleHQ6IHBhcnRzIH07XG4gICAgfVxuICAgIGlmIChyZXMuY29udGVudCAmJiB0eXBlb2YgcmVzLmNvbnRlbnQudGV4dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHsgdGV4dDogcmVzLmNvbnRlbnQudGV4dCB9O1xuICAgIH1cbiAgICAvLyBmYWxsYmFjazogc3RyaW5naWZ5XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB7IHRleHQ6IEpTT04uc3RyaW5naWZ5KHJlcykgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7IHRleHQ6IFN0cmluZyhyZXMpIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGFsbC5tYXAoKHQpID0+ICh7XG4gICAgLi4udCxcbiAgICBsb2FkOiBhc3luYyAoYXJnczogYW55KSA9PiB7XG4gICAgICBjb25zdCByYXcgPSBhd2FpdCAodC5sb2FkIGFzIGFueSkoYXJncyk7XG4gICAgICByZXR1cm4gbm9ybWFsaXNlUmVzdWx0KHJhdyk7XG4gICAgfSxcbiAgfSkpO1xufVxuXG5leHBvcnQgY29uc3QgdGVtcGxhdGVMaXN0ID0gYnVpbGRSZXNvdXJjZVRlbXBsYXRlcygpO1xuIiwiaW1wb3J0IHsgTWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcblxuLyoqXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG5hbWUgVkVSU0lPTlxuICogQGRlc2NyaXB0aW9uIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdHMtd29ya3NwYWNlIG1vZHVsZS5cbiAqIEBzdW1tYXJ5IFRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgaXMgcmVwbGFjZWQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gXCIjI1BBQ0tBR0VfTkFNRSMjXCI7XG5cbnRyeSB7XG4gIE1ldGFkYXRhLnJlZ2lzdGVyTGlicmFyeShQQUNLQUdFX05BTUUsIFZFUlNJT04pO1xufSBjYXRjaCAoZXJyb3IpIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhcImFscmVhZHlcIikpIHtcbiAgICAvLyBJZ25vcmUgZHVwbGljYXRlIHJlZ2lzdHJhdGlvbiBkdXJpbmcgdGVzdHMvYnVuZGxpbmcgY2hlY2tzLlxuICB9IGVsc2Uge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iLCJpbXBvcnQgdHlwZSB7IEZhc3RNQ1AgfSBmcm9tIFwiZmFzdG1jcFwiO1xuaW1wb3J0IHsgUEFDS0FHRV9OQU1FIGFzIFBLRywgVkVSU0lPTiBhcyBWIH0gZnJvbSBcIi4uL21ldGFkYXRhXCI7XG5pbXBvcnQgeyBsb2FkUHJvbXB0cywgcHJvbXB0TGlzdCB9IGZyb20gXCIuL3Byb21wdHNcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlc1wiO1xuaW1wb3J0IHtcbiAgYnVpbGREZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbiAgdGVtcGxhdGVMaXN0LFxuICB3b3Jrc3BhY2VSZXNvdXJjZVRlbXBsYXRlcyxcbn0gZnJvbSBcIi4vdGVtcGxhdGVzXCI7XG5pbXBvcnQgeyB0b29sTGlzdCwgdG9vbHMgfSBmcm9tIFwiLi90b29sc1wiO1xuaW1wb3J0IHtcbiAgX19yZXNldFdvcmtzcGFjZVJvb3QsXG4gIGdldFdvcmtzcGFjZVJvb3QsXG4gIHNldFdvcmtzcGFjZVJvb3QsXG59IGZyb20gXCIuL3dvcmtzcGFjZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZW5yaWNoKG1jcDogRmFzdE1DUCk6IEZhc3RNQ1Age1xuICBjb25zdCBwcm9tcHRFbnRyaWVzID0gbG9hZFByb21wdHMoKTtcbiAgZm9yIChjb25zdCBwcm9tcHQgb2YgcHJvbXB0RW50cmllcykge1xuICAgIG1jcC5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHRvb2wgb2YgdG9vbExpc3QpIHtcbiAgICBtY3AuYWRkVG9vbCh0b29sIGFzIGFueSk7XG4gIH1cblxuICBjb25zdCB0ZW1wbGF0ZXMgPSBidWlsZFJlc291cmNlVGVtcGxhdGVzKCk7XG4gIGZvciAoY29uc3QgdGVtcGxhdGUgb2YgdGVtcGxhdGVzKSB7XG4gICAgbWNwLmFkZFJlc291cmNlVGVtcGxhdGUodGVtcGxhdGUgYXMgYW55KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSB7XG4gICAgY29uc3QgYWRkUmVzb3VyY2UgPSAoXG4gICAgICBtY3AgYXMgdW5rbm93biBhcyB7IGFkZFJlc291cmNlPzogKHJlczogdW5rbm93bikgPT4gdm9pZCB9XG4gICAgKS5hZGRSZXNvdXJjZTtcbiAgICBpZiAodHlwZW9mIGFkZFJlc291cmNlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGFkZFJlc291cmNlLmNhbGwobWNwLCByZXNvdXJjZSBhcyBhbnkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtY3A7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGVucmljaDtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBQS0c7XG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFY7XG5cbmV4cG9ydCB7XG4gIHRvb2xzLFxuICB0b29sTGlzdCxcbiAgYnVpbGREZWNvcmF0aW9uUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMsXG4gIGRlY29yYXRpb25SZXNvdXJjZVRlbXBsYXRlcyxcbiAgcHJvbXB0TGlzdCxcbiAgcmVzb3VyY2VzLFxuICB0ZW1wbGF0ZUxpc3QsXG4gIHdvcmtzcGFjZVJlc291cmNlVGVtcGxhdGVzLFxuICBnZXRXb3Jrc3BhY2VSb290LFxuICBzZXRXb3Jrc3BhY2VSb290LFxuICBfX3Jlc2V0V29ya3NwYWNlUm9vdCxcbn07XG4iLCIvLyBOZXc6IHZhbGlkYXRpb24gZW50cnlwb2ludCBmb3IgbW9kdWxlIHN0cnVjdHVyZVxuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuZXhwb3J0IHR5cGUgVmFsaWRhdGlvbklzc3VlID0ge1xuICBtb2R1bGU6IHN0cmluZztcbiAgcGF0aDogc3RyaW5nO1xuICB0eXBlOlxuICAgIHwgXCJtaXNzaW5nLWZvbGRlclwiXG4gICAgfCBcIm1pc3NpbmctZXhwb3J0XCJcbiAgICB8IFwiZW1wdHktbGlzdFwiXG4gICAgfCBcImRpc2FibGVkXCJcbiAgICB8IFwib3RoZXJcIjtcbiAgZGV0YWlsPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgVmFsaWRhdGlvblJlcG9ydCA9IHtcbiAgb2s6IGJvb2xlYW47XG4gIG1vZHVsZXNDaGVja2VkOiBudW1iZXI7XG4gIGlzc3VlczogVmFsaWRhdGlvbklzc3VlW107XG59O1xuXG5jb25zdCBSRVFVSVJFRF9TVUJGT0xERVJTID0gW1wicHJvbXB0c1wiLCBcInJlc291cmNlc1wiLCBcInRlbXBsYXRlc1wiLCBcInRvb2xzXCJdO1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZE1vZHVsZURpcnMocmVwb1Jvb3Q6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgbW9kdWxlc1BhdGggPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QsIFwic3JjXCIsIFwibW9kdWxlc1wiKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKG1vZHVsZXNQYXRoKSB8fCAhZnMuc3RhdFN5bmMobW9kdWxlc1BhdGgpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGZzXG4gICAgLnJlYWRkaXJTeW5jKG1vZHVsZXNQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSlcbiAgICAuZmlsdGVyKChkKSA9PiBkLmlzRGlyZWN0b3J5KCkpXG4gICAgLm1hcCgoZCkgPT4gcGF0aC5qb2luKG1vZHVsZXNQYXRoLCBkLm5hbWUpKTtcbn1cblxuZnVuY3Rpb24gaGFzSW5kZXhFeHBvcnQoZm9sZGVyUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBbXG4gICAgXCJpbmRleC50c1wiLFxuICAgIFwiaW5kZXgudHN4XCIsXG4gICAgXCJpbmRleC5qc1wiLFxuICAgIFwiaW5kZXguY2pzXCIsXG4gICAgXCJpbmRleC5tanNcIixcbiAgXTtcbiAgZm9yIChjb25zdCBjIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhwYXRoLmpvaW4oZm9sZGVyUGF0aCwgYykpKSByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZU1vZHVsZXMocmVwb1Jvb3Q6IHN0cmluZyk6IFZhbGlkYXRpb25SZXBvcnQge1xuICBjb25zdCBkaXJzID0gZmluZE1vZHVsZURpcnMocmVwb1Jvb3QpO1xuICBjb25zdCBpc3N1ZXM6IFZhbGlkYXRpb25Jc3N1ZVtdID0gW107XG5cbiAgZm9yIChjb25zdCBtb2R1bGVEaXIgb2YgZGlycykge1xuICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBwYXRoLmJhc2VuYW1lKG1vZHVsZURpcik7XG4gICAgZm9yIChjb25zdCBzdWIgb2YgUkVRVUlSRURfU1VCRk9MREVSUykge1xuICAgICAgY29uc3Qgc3ViUGF0aCA9IHBhdGguam9pbihtb2R1bGVEaXIsIHN1Yik7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc3ViUGF0aCkgfHwgIWZzLnN0YXRTeW5jKHN1YlBhdGgpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgaXNzdWVzLnB1c2goe1xuICAgICAgICAgIG1vZHVsZTogbW9kdWxlTmFtZSxcbiAgICAgICAgICBwYXRoOiBzdWJQYXRoLFxuICAgICAgICAgIHR5cGU6IFwibWlzc2luZy1mb2xkZXJcIixcbiAgICAgICAgICBkZXRhaWw6IGBSZXF1aXJlZCBmb2xkZXIgJyR7c3VifScgaXMgbWlzc2luZyBpbiBtb2R1bGUgJyR7bW9kdWxlTmFtZX0nYCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gSWYgZm9sZGVyIGV4aXN0cywgY2hlY2sgZm9yIGluZGV4IGV4cG9ydFxuICAgICAgaWYgKCFoYXNJbmRleEV4cG9ydChzdWJQYXRoKSkge1xuICAgICAgICBpc3N1ZXMucHVzaCh7XG4gICAgICAgICAgbW9kdWxlOiBtb2R1bGVOYW1lLFxuICAgICAgICAgIHBhdGg6IHN1YlBhdGgsXG4gICAgICAgICAgdHlwZTogXCJtaXNzaW5nLWV4cG9ydFwiLFxuICAgICAgICAgIGRldGFpbDogYE5vIGluZGV4IGV4cG9ydCBmb3VuZCBpbiAnJHtzdWJQYXRofScuIEV4cGVjdGVkIG9uZSBvZiBpbmRleC50cywgaW5kZXguanMsIGV0Yy5gLFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBPcHRpb25hbGx5IGluc3BlY3QgdGhlIGluZGV4IGZpbGUgdG8gc2VlIGlmIGl0IGV4cG9ydHMgYSBsaXN0IChsaWdodHdlaWdodCBjaGVjaylcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGluZGV4RmlsZSA9IGNhbmRpZGF0ZXNGaW5kaW5nSW5kZXgoc3ViUGF0aCk7XG4gICAgICAgIGlmIChpbmRleEZpbGUpIHtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGluZGV4RmlsZSwgXCJ1dGY4XCIpO1xuICAgICAgICAgIC8vIGNydWRlIGhldXJpc3RpY3M6IGxvb2sgZm9yIGBleHBvcnQgY29uc3QgbmFtZSA9IFtgIG9yIGBleHBvcnQgY29uc3QgbmFtZTogVHlwZVtdID0gW2AsXG4gICAgICAgICAgLy8gb3IgYW55IG5hbWVkIGV4cG9ydCBsaWtlIGBleHBvcnQgeyBzb21ldGhpbmcgfWAgd2hpY2ggaW1wbGllcyBleHBvcnRzIGV4aXN0LlxuICAgICAgICAgIGNvbnN0IGV4cG9ydExpc3RQYXR0ZXJuID1cbiAgICAgICAgICAgIC9leHBvcnRcXHMrKGNvbnN0fGxldHx2YXIpXFxzK1tcXHckXSsoPzpcXHMqOlxccypbXj1dKyk/XFxzKj1cXHMqXFxbLztcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhZXhwb3J0TGlzdFBhdHRlcm4udGVzdChjb250ZW50KSAmJlxuICAgICAgICAgICAgIS9leHBvcnRcXHMrXFx7Ly50ZXN0KGNvbnRlbnQpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBpc3N1ZXMucHVzaCh7XG4gICAgICAgICAgICAgIG1vZHVsZTogbW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgcGF0aDogaW5kZXhGaWxlLFxuICAgICAgICAgICAgICB0eXBlOiBcImVtcHR5LWxpc3RcIixcbiAgICAgICAgICAgICAgZGV0YWlsOiBgSW5kZXggZmlsZSBkb2VzIG5vdCBhcHBlYXIgdG8gZXhwb3J0IGEgbGlzdCBvZiBhc3NldHM6ICR7cGF0aC5iYXNlbmFtZShpbmRleEZpbGUpfWAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgIGlzc3Vlcy5wdXNoKHtcbiAgICAgICAgICBtb2R1bGU6IG1vZHVsZU5hbWUsXG4gICAgICAgICAgcGF0aDogc3ViUGF0aCxcbiAgICAgICAgICB0eXBlOiBcIm90aGVyXCIsXG4gICAgICAgICAgZGV0YWlsOiBgRXJyb3IgcmVhZGluZyBpbmRleCBmaWxlOiAke2Vyci5tZXNzYWdlfWAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgb2s6IGlzc3Vlcy5sZW5ndGggPT09IDAsXG4gICAgbW9kdWxlc0NoZWNrZWQ6IGRpcnMubGVuZ3RoLFxuICAgIGlzc3VlcyxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2FuZGlkYXRlc0ZpbmRpbmdJbmRleChmb2xkZXJQYXRoOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBjYW5kaWRhdGVzID0gW1xuICAgIFwiaW5kZXgudHNcIixcbiAgICBcImluZGV4LnRzeFwiLFxuICAgIFwiaW5kZXguanNcIixcbiAgICBcImluZGV4LmNqc1wiLFxuICAgIFwiaW5kZXgubWpzXCIsXG4gIF07XG4gIGZvciAoY29uc3QgYyBvZiBjYW5kaWRhdGVzKSB7XG4gICAgY29uc3QgZnVsbCA9IHBhdGguam9pbihmb2xkZXJQYXRoLCBjKTtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhmdWxsKSkgcmV0dXJuIGZ1bGw7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLy8gQ0xJIGhlbHBlclxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIGNvbnN0IHJlcG9Sb290ID0gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3QgcmVwb3J0ID0gdmFsaWRhdGVNb2R1bGVzKHJlcG9Sb290KTtcbiAgaWYgKCFyZXBvcnQub2spIHtcbiAgICBjb25zb2xlLmVycm9yKFxuICAgICAgXCJNb2R1bGUgdmFsaWRhdGlvbiBmYWlsZWQ6XFxuXCIsXG4gICAgICBKU09OLnN0cmluZ2lmeShyZXBvcnQsIG51bGwsIDIpXG4gICAgKTtcbiAgICBwcm9jZXNzLmV4aXQoMik7XG4gIH1cbiAgY29uc29sZS5sb2coXCJNb2R1bGUgdmFsaWRhdGlvbiBwYXNzZWRcIik7XG4gIHByb2Nlc3MuZXhpdCgwKTtcbn1cbiIsIi8vIEFnZ3JlZ2F0b3I6IGltcG9ydCBtb2R1bGUgaW5kZXggZmlsZXMgYW5kIG1lcmdlIGV4cG9ydGVkIGFycmF5cyB3aXRoIHByb3ZlbmFuY2UgKyBkdXBsaWNhdGUgZGV0ZWN0aW9uXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgcGF0aFRvRmlsZVVSTCB9IGZyb20gXCJ1cmxcIjtcbmltcG9ydCB7IGZpbmRNb2R1bGVEaXJzIH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuXG5leHBvcnQgdHlwZSBQcm92ZW5hbmNlID0geyBtb2R1bGVOYW1lOiBzdHJpbmc7IG1vZHVsZVBhdGg6IHN0cmluZyB9O1xuZXhwb3J0IHR5cGUgQWdncmVnYXRpb25Db25mbGljdCA9IHtcbiAga2V5OiBzdHJpbmc7XG4gIGV4aXN0aW5nOiBQcm92ZW5hbmNlO1xuICBpbmNvbWluZzogUHJvdmVuYW5jZTtcbn07XG5cbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0aW9uUmVzdWx0PFQgPSBhbnk+ID0ge1xuICBwcm9tcHRzOiBBcnJheTxUICYgeyBwcm92ZW5hbmNlOiBQcm92ZW5hbmNlIH0+O1xuICByZXNvdXJjZXM6IEFycmF5PFQgJiB7IHByb3ZlbmFuY2U6IFByb3ZlbmFuY2UgfT47XG4gIHRlbXBsYXRlczogQXJyYXk8VCAmIHsgcHJvdmVuYW5jZTogUHJvdmVuYW5jZSB9PjtcbiAgdG9vbHM6IEFycmF5PFQgJiB7IHByb3ZlbmFuY2U6IFByb3ZlbmFuY2UgfT47XG4gIGNvbmZsaWN0czogQWdncmVnYXRpb25Db25mbGljdFtdO1xufTtcblxuY29uc3QgU1VCRk9MREVSUyA9IFtcInByb21wdHNcIiwgXCJyZXNvdXJjZXNcIiwgXCJ0ZW1wbGF0ZXNcIiwgXCJ0b29sc1wiXTtcbmNvbnN0IElOREVYX0NBTkRJREFURVMgPSBbXG4gIFwiaW5kZXgudHNcIixcbiAgXCJpbmRleC50c3hcIixcbiAgXCJpbmRleC5qc1wiLFxuICBcImluZGV4LmNqc1wiLFxuICBcImluZGV4Lm1qc1wiLFxuXTtcblxuZnVuY3Rpb24gZmluZEluZGV4RmlsZShmb2xkZXI6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGZvciAoY29uc3QgYyBvZiBJTkRFWF9DQU5ESURBVEVTKSB7XG4gICAgY29uc3QgZiA9IHBhdGguam9pbihmb2xkZXIsIGMpO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGYpKSByZXR1cm4gZjtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYWtlS2V5Rm9ySXRlbShpdGVtOiBhbnkpOiBzdHJpbmcge1xuICBpZiAoIWl0ZW0pIHJldHVybiBKU09OLnN0cmluZ2lmeShpdGVtKTtcbiAgaWYgKHR5cGVvZiBpdGVtID09PSBcInN0cmluZ1wiKSByZXR1cm4gYHN0cjoke2l0ZW19YDtcbiAgaWYgKHR5cGVvZiBpdGVtID09PSBcIm51bWJlclwiKSByZXR1cm4gYG51bToke2l0ZW19YDtcbiAgaWYgKGl0ZW0uaWQpIHJldHVybiBgaWQ6JHtpdGVtLmlkfWA7XG4gIGlmIChpdGVtLm5hbWUpIHJldHVybiBgbmFtZToke2l0ZW0ubmFtZX1gO1xuICAvLyBmYWxsYmFjayB0byBzdGFibGUgc3RyaW5nXG4gIHRyeSB7XG4gICAgcmV0dXJuIGBvYmo6JHtKU09OLnN0cmluZ2lmeShpdGVtKX1gO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGBvYmo6JHtTdHJpbmcoaXRlbSl9YDtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQXJyYXlGcm9tSW5kZXgoXG4gIGZpbGVQYXRoOiBzdHJpbmdcbik6IFByb21pc2U8YW55W10gfCB1bmRlZmluZWQ+IHtcbiAgLy8gUHJlZmVyIGEgZmFzdCwgc3RhdGljIHBhcnNlIG9mIHRoZSBmaXJzdCBhcnJheSBsaXRlcmFsIGZvdW5kIGluIHRoZSBmaWxlLlxuICB0cnkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICBjb25zdCBzdGFydCA9IGNvbnRlbnQuaW5kZXhPZihcIltcIik7XG4gICAgaWYgKHN0YXJ0ICE9PSAtMSkge1xuICAgICAgbGV0IGRlcHRoID0gMDtcbiAgICAgIGxldCBlbmQgPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGNvbnRlbnQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgY2ggPSBjb250ZW50W2ldO1xuICAgICAgICBpZiAoY2ggPT09IFwiW1wiKSBkZXB0aCsrO1xuICAgICAgICBlbHNlIGlmIChjaCA9PT0gXCJdXCIpIHtcbiAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICAgIGlmIChkZXB0aCA9PT0gMCkge1xuICAgICAgICAgICAgZW5kID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVuZCAhPT0gLTEpIHtcbiAgICAgICAgY29uc3QgYXJyVGV4dCA9IGNvbnRlbnQuc2xpY2Uoc3RhcnQsIGVuZCArIDEpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKGFyclRleHQpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gTm9ybWFsaXplIFRTIG9iamVjdCBsaXRlcmFscyB0byBKU09OOlxuICAgICAgICAgIC8vIC0gY29udmVydCBzaW5nbGUgcXVvdGVzIHRvIGRvdWJsZSBxdW90ZXNcbiAgICAgICAgICAvLyAtIHF1b3RlIHVucXVvdGVkIG9iamVjdCBrZXlzXG4gICAgICAgICAgLy8gLSBzdHJpcCB0cmFpbGluZyBjb21tYXNcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkID0gYXJyVGV4dFxuICAgICAgICAgICAgLy8gdW5pZnkgcXVvdGVzIGluIHN0cmluZyBsaXRlcmFsc1xuICAgICAgICAgICAgLnJlcGxhY2UoLycoPzpcXFxcJ3xbXiddKSonL2csIChtKSA9PiBtLnJlcGxhY2UoLycvZywgJ1wiJykpXG4gICAgICAgICAgICAvLyBxdW90ZSB1bnF1b3RlZCBrZXlzIGFmdGVyIHsgb3IgLFxuICAgICAgICAgICAgLnJlcGxhY2UoLyhbXFx7LF1cXHMqKShbQS1aYS16XyRdW1xcdyRdKikoXFxzKjopL2csICckMVwiJDJcIiQzJylcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyBjb21tYXMgYmVmb3JlIF0gb3IgfVxuICAgICAgICAgICAgLnJlcGxhY2UoLywoXFxzKltcXH1cXF1dKS9nLCAnJDEnKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2Uobm9ybWFsaXplZCk7XG4gICAgICAgICAgfSBjYXRjaCAoZTIpIHtcbiAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoIHRvIGltcG9ydCBhdHRlbXB0IGJlbG93XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gaWdub3JlIHN0YXRpYyBwYXJzZSBlcnJvcnMgYW5kIGZhbGwgYmFjayB0byBpbXBvcnRcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgZmlsZVVybCA9IHBhdGhUb0ZpbGVVUkwoZmlsZVBhdGgpLmhyZWY7XG4gICAgY29uc3QgbW9kID0gYXdhaXQgaW1wb3J0KGZpbGVVcmwpO1xuICAgIC8vIEZpbmQgZmlyc3QgZXhwb3J0IHRoYXQgaXMgYW4gYXJyYXlcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhtb2QpKSB7XG4gICAgICBjb25zdCB2YWwgPSAobW9kIGFzIGFueSlba2V5XTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHJldHVybiB2YWw7XG4gICAgfVxuICAgIC8vIGRlZmF1bHQgZXhwb3J0IGNoZWNrXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoKG1vZCBhcyBhbnkpLmRlZmF1bHQpKSByZXR1cm4gKG1vZCBhcyBhbnkpLmRlZmF1bHQ7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gZmFsbGJhY2s6IGlmIGltcG9ydCBmYWlscywgdHJ5IHRvIHN0YXRpYy1wYXJzZSBhZ2FpbiAoYWxyZWFkeSBhdHRlbXB0ZWQpIGFuZCBmaW5hbGx5IHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZ2dyZWdhdGVNb2R1bGVzKFxuICByZXBvUm9vdDogc3RyaW5nXG4pOiBQcm9taXNlPEFnZ3JlZ2F0aW9uUmVzdWx0PiB7XG4gIGNvbnN0IGRpcnMgPSBmaW5kTW9kdWxlRGlycyhyZXBvUm9vdCk7XG4gIGNvbnN0IG1hc3RlciA9IHtcbiAgICBwcm9tcHRzOiBbXSBhcyBhbnlbXSxcbiAgICByZXNvdXJjZXM6IFtdIGFzIGFueVtdLFxuICAgIHRlbXBsYXRlczogW10gYXMgYW55W10sXG4gICAgdG9vbHM6IFtdIGFzIGFueVtdLFxuICAgIGNvbmZsaWN0czogW10gYXMgQWdncmVnYXRpb25Db25mbGljdFtdLFxuICB9O1xuXG4gIC8vIG1hcHMgdG8gZGV0ZWN0IGR1cGxpY2F0ZXMgcGVyIHR5cGVcbiAgY29uc3QgbWFwczogUmVjb3JkPHN0cmluZywgTWFwPHN0cmluZywgUHJvdmVuYW5jZT4+ID0ge1xuICAgIHByb21wdHM6IG5ldyBNYXAoKSxcbiAgICByZXNvdXJjZXM6IG5ldyBNYXAoKSxcbiAgICB0ZW1wbGF0ZXM6IG5ldyBNYXAoKSxcbiAgICB0b29sczogbmV3IE1hcCgpLFxuICB9O1xuXG4gIGZvciAoY29uc3QgbW9kdWxlRGlyIG9mIGRpcnMpIHtcbiAgICBjb25zdCBtb2R1bGVOYW1lID0gcGF0aC5iYXNlbmFtZShtb2R1bGVEaXIpO1xuICAgIGZvciAoY29uc3Qgc3ViIG9mIFNVQkZPTERFUlMpIHtcbiAgICAgIGNvbnN0IGZvbGRlciA9IHBhdGguam9pbihtb2R1bGVEaXIsIHN1Yik7XG4gICAgICBjb25zdCBpbmRleEZpbGUgPSBmaW5kSW5kZXhGaWxlKGZvbGRlcik7XG4gICAgICBpZiAoIWluZGV4RmlsZSkgY29udGludWU7XG4gICAgICBsZXQgYXJyOiBhbnlbXSB8IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGFyciA9IGF3YWl0IGxvYWRBcnJheUZyb21JbmRleChpbmRleEZpbGUpO1xuICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgLy8gc2tpcCBtb2R1bGUgb24gaW1wb3J0IGVycm9yIGJ1dCByZWNvcmQgYXMgY29uZmxpY3QtbGlrZSBpc3N1ZVxuICAgICAgICBtYXN0ZXIuY29uZmxpY3RzLnB1c2goe1xuICAgICAgICAgIGtleTogYGltcG9ydC1lcnJvcjoke21vZHVsZU5hbWV9OiR7c3VifWAsXG4gICAgICAgICAgZXhpc3Rpbmc6IHsgbW9kdWxlTmFtZSwgbW9kdWxlUGF0aDogbW9kdWxlRGlyIH0sXG4gICAgICAgICAgaW5jb21pbmc6IHsgbW9kdWxlTmFtZSwgbW9kdWxlUGF0aDogbW9kdWxlRGlyIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghYXJyIHx8ICFBcnJheS5pc0FycmF5KGFycikpIGNvbnRpbnVlO1xuXG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IG1ha2VLZXlGb3JJdGVtKGl0ZW0pO1xuICAgICAgICBjb25zdCBwcm92ZW5hbmNlID0geyBtb2R1bGVOYW1lLCBtb2R1bGVQYXRoOiBtb2R1bGVEaXIgfTtcbiAgICAgICAgY29uc3QgbWFwID0gbWFwc1tzdWJdO1xuICAgICAgICBpZiAobWFwLmhhcyhrZXkpKSB7XG4gICAgICAgICAgLy8gcmVjb3JkIGNvbmZsaWN0IGRldGVybWluaXN0aWNhbGx5IChleGlzdGluZyB2cyBpbmNvbWluZylcbiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IG1hcC5nZXQoa2V5KSE7XG4gICAgICAgICAgbWFzdGVyLmNvbmZsaWN0cy5wdXNoKHsga2V5LCBleGlzdGluZywgaW5jb21pbmc6IHByb3ZlbmFuY2UgfSk7XG4gICAgICAgICAgLy8gc2tpcCBhZGRpbmcgZHVwbGljYXRlXG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbWFwLnNldChrZXksIHByb3ZlbmFuY2UpO1xuICAgICAgICAobWFzdGVyIGFzIGFueSlbc3ViXS5wdXNoKHsgLi4uaXRlbSwgcHJvdmVuYW5jZSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWFzdGVyO1xufVxuXG4vLyBGb3IgY29tcGF0aWJpbGl0eSB3aXRoIENvbW1vbkpTIGNhbGwgc2l0ZXMgKG5vdCBleHBvcnRlZCBieSBFU00pLCBwcm92aWRlIGEgc3luYyB3cmFwcGVyXG5leHBvcnQgZnVuY3Rpb24gYWdncmVnYXRlTW9kdWxlc1N5bmMocmVwb1Jvb3Q6IHN0cmluZykge1xuICAvLyBzeW5jaHJvbm91cyB3cmFwcGVyIHRoYXQgcnVucyB0aGUgYXN5bmMgZnVuY3Rpb24gYW5kIGJsb2NrcyDigJQgc3VpdGFibGUgZm9yIHNtYWxsIG1vZHVsZSBzZXRzXG4gIGNvbnN0IHAgPSBhZ2dyZWdhdGVNb2R1bGVzKHJlcG9Sb290KTtcbiAgbGV0IHJlc3VsdDogYW55O1xuICBsZXQgZG9uZSA9IGZhbHNlO1xuICBwLnRoZW4oKHIpID0+IHtcbiAgICByZXN1bHQgPSByO1xuICAgIGRvbmUgPSB0cnVlO1xuICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgIHRocm93IGU7XG4gIH0pO1xuICAvLyBzcGluLXdhaXQgKGFjY2VwdGFibGUgaW4gc21hbGwgZGV2IHNjcmlwdHMpXG4gIGNvbnN0IHVudGlsID0gRGF0ZS5ub3coKSArIDUwMDA7XG4gIHdoaWxlICghZG9uZSAmJiBEYXRlLm5vdygpIDwgdW50aWwpIHt9XG4gIGlmICghZG9uZSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcImFnZ3JlZ2F0ZU1vZHVsZXNTeW5jOiB0aW1lb3V0IHdhaXRpbmcgZm9yIGFzeW5jIGFnZ3JlZ2F0aW9uXCJcbiAgICApO1xuICByZXR1cm4gcmVzdWx0IGFzIEFnZ3JlZ2F0aW9uUmVzdWx0O1xufVxuIiwiaW1wb3J0IHsgYWdncmVnYXRlTW9kdWxlcyB9IGZyb20gXCIuL2FnZ3JlZ2F0ZU1vZHVsZXNcIjtcbmltcG9ydCB7IGxvYWRQcm9tcHRzLCBwcm9tcHRMaXN0IH0gZnJvbSBcIi4vcHJvbXB0cy9pbmRleFwiO1xuaW1wb3J0IHsgdG9vbExpc3QgfSBmcm9tIFwiLi90b29scy9pbmRleFwiO1xuaW1wb3J0IHsgcmVzb3VyY2VzIH0gZnJvbSBcIi4vcmVzb3VyY2VzL2luZGV4XCI7XG5pbXBvcnQgeyBidWlsZFJlc291cmNlVGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzL2luZGV4XCI7XG5cbmV4cG9ydCB0eXBlIEZhc3RNQ1BMaWtlID0ge1xuICBhZGRQcm9tcHQ6IChwOiBhbnkpID0+IHZvaWQ7XG4gIGFkZFRvb2w6ICh0OiBhbnkpID0+IHZvaWQ7XG4gIGFkZFJlc291cmNlOiAocjogYW55KSA9PiB2b2lkO1xuICBhZGRSZXNvdXJjZVRlbXBsYXRlOiAodDogYW55KSA9PiB2b2lkO1xufTtcblxuLyoqXG4gKiBBZ2dyZWdhdGUgbW9kdWxlIGFzc2V0cyBhbmQgcmVnaXN0ZXIgdGhlbSBvbiB0aGUgcHJvdmlkZWQgRmFzdE1DUC1saWtlIHNlcnZlci5cbiAqIEZhbGxzIGJhY2sgdG8gYnVpbHQtaW4gbGlzdHMgaWYgYWdncmVnYXRpb24geWllbGRzIG5vbmUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBFbnJpY2hDb3JlV2l0aEFnZ3JlZ2F0aW9uKFxuICBzZXJ2ZXI6IEZhc3RNQ1BMaWtlLFxuICByZXBvUm9vdCA9IHByb2Nlc3MuY3dkKClcbikge1xuICAvLyBGaXJzdCByZWdpc3RlciBidWlsdC1pbiBwcm9tcHRzL3Rvb2xzL3Jlc291cmNlcy90ZW1wbGF0ZXMgKGxlZ2FjeSBiZWhhdmlvcilcbiAgdHJ5IHtcbiAgICBsb2FkUHJvbXB0cygpO1xuICAgIGZvciAoY29uc3QgcHJvbXB0IG9mIHByb21wdExpc3QpIHNlcnZlci5hZGRQcm9tcHQocHJvbXB0IGFzIGFueSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpZ25vcmUgaWYgbG9hZFByb21wdHMgbm90IGF2YWlsYWJsZSBvciBmYWlsc1xuICB9XG5cbiAgdHJ5IHtcbiAgICBmb3IgKGNvbnN0IHRvb2wgb2YgdG9vbExpc3QpIHNlcnZlci5hZGRUb29sKHRvb2wgYXMgYW55KTtcbiAgfSBjYXRjaCAoZSkge31cblxuICB0cnkge1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgcmVzb3VyY2VzKSBzZXJ2ZXIuYWRkUmVzb3VyY2UocmVzb3VyY2UgYXMgYW55KTtcbiAgfSBjYXRjaCAoZSkge31cblxuICB0cnkge1xuICAgIGNvbnN0IHRlbXBsYXRlcyA9IGJ1aWxkUmVzb3VyY2VUZW1wbGF0ZXMoKTtcbiAgICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIHRlbXBsYXRlcylcbiAgICAgIHNlcnZlci5hZGRSZXNvdXJjZVRlbXBsYXRlKHRlbXBsYXRlIGFzIGFueSk7XG4gIH0gY2F0Y2ggKGUpIHt9XG5cbiAgLy8gTm93IGFnZ3JlZ2F0ZSBtb2R1bGVzIGFuZCByZWdpc3RlciBhZ2dyZWdhdGVkIGFzc2V0cyB3aXRoIHByb3ZlbmFuY2VcbiAgY29uc3QgYWdnID0gYXdhaXQgYWdncmVnYXRlTW9kdWxlcyhyZXBvUm9vdCk7XG5cbiAgZm9yIChjb25zdCBwIG9mIGFnZy5wcm9tcHRzKSB7XG4gICAgc2VydmVyLmFkZFByb21wdChwKTtcbiAgfVxuICBmb3IgKGNvbnN0IHQgb2YgYWdnLnRvb2xzKSB7XG4gICAgc2VydmVyLmFkZFRvb2wodCk7XG4gIH1cbiAgZm9yIChjb25zdCByIG9mIGFnZy5yZXNvdXJjZXMpIHtcbiAgICBzZXJ2ZXIuYWRkUmVzb3VyY2Uocik7XG4gIH1cbiAgZm9yIChjb25zdCB0cGwgb2YgYWdnLnRlbXBsYXRlcykge1xuICAgIHNlcnZlci5hZGRSZXNvdXJjZVRlbXBsYXRlKHRwbCk7XG4gIH1cblxuICAvLyByZXR1cm4gYWdncmVnYXRpb24gc3VtbWFyeSBmb3IgY2FsbGluZyB0ZXN0cy9DSVxuICByZXR1cm4ge1xuICAgIG1vZHVsZXNDaGVja2VkOiBhZ2cucHJvbXB0cy5jb25jYXQoYWdnLnRvb2xzKS5sZW5ndGgsXG4gICAgY29uZmxpY3RzOiBhZ2cuY29uZmxpY3RzLFxuICB9O1xufVxuIiwiaW1wb3J0IHsgRmFzdE1DUCB9IGZyb20gXCJmYXN0bWNwXCI7XG5pbXBvcnQgeyBsb2FkUHJvbXB0cywgcHJvbXB0TGlzdCB9IGZyb20gXCIuL3Byb21wdHMvaW5kZXhcIjtcbmltcG9ydCB7IHRvb2xMaXN0IH0gZnJvbSBcIi4vdG9vbHMvaW5kZXhcIjtcbmltcG9ydCB7IHJlc291cmNlcyB9IGZyb20gXCIuL3Jlc291cmNlcy9pbmRleFwiO1xuaW1wb3J0IHsgYnVpbGRSZXNvdXJjZVRlbXBsYXRlcyB9IGZyb20gXCIuL3RlbXBsYXRlcy9pbmRleFwiO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9tY3AtbW9kdWxlXCI7XG5leHBvcnQgeyBkZWZhdWx0IH0gZnJvbSBcIi4vbWNwLW1vZHVsZVwiO1xuXG5leHBvcnQgeyB2YWxpZGF0ZU1vZHVsZXMgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5leHBvcnQgeyBhZ2dyZWdhdGVNb2R1bGVzLCBhZ2dyZWdhdGVNb2R1bGVzU3luYyB9IGZyb20gXCIuL2FnZ3JlZ2F0ZU1vZHVsZXNcIjtcbmV4cG9ydCB7IEVucmljaENvcmVXaXRoQWdncmVnYXRpb24gfSBmcm9tIFwiLi9mYXN0bWNwLXdpcmluZ1wiO1xuXG4vLyByZS1leHBvcnQgaGVscGVycyB1c2VkIGJ5IHRlc3RzIGFuZCBvdGhlciBtb2R1bGVzXG5leHBvcnQgeyBidWlsZERvY1Byb21wdHMgfSBmcm9tIFwiLi9wcm9tcHRzL2luZGV4XCI7XG5leHBvcnQgeyBidWlsZFJlc291cmNlVGVtcGxhdGVzIH0gZnJvbSBcIi4vdGVtcGxhdGVzL2luZGV4XCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBFbnJpY2hDb3JlKHNlcnZlcjogRmFzdE1DUCkge1xuICBsb2FkUHJvbXB0cygpO1xuICBmb3IgKGNvbnN0IHByb21wdCBvZiBwcm9tcHRMaXN0KSB7XG4gICAgc2VydmVyLmFkZFByb21wdChwcm9tcHQgYXMgYW55KTtcbiAgfVxuICBmb3IgKGNvbnN0IHRvb2wgb2YgdG9vbExpc3QpIHtcbiAgICBzZXJ2ZXIuYWRkVG9vbCh0b29sIGFzIGFueSk7XG4gIH1cbiAgZm9yIChjb25zdCByZXNvdXJjZSBvZiByZXNvdXJjZXMpIHtcbiAgICBzZXJ2ZXIuYWRkUmVzb3VyY2UocmVzb3VyY2UgYXMgYW55KTtcbiAgfVxuICBjb25zdCB0ZW1wbGF0ZXMgPSBidWlsZFJlc291cmNlVGVtcGxhdGVzKCk7XG4gIGZvciAoY29uc3QgdGVtcGxhdGUgb2YgdGVtcGxhdGVzKSB7XG4gICAgc2VydmVyLmFkZFJlc291cmNlVGVtcGxhdGUodGVtcGxhdGUgYXMgYW55KTtcbiAgfVxufVxuIiwiaW1wb3J0IGZzIGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBnZXRXb3Jrc3BhY2VSb290IH0gZnJvbSBcIi4uL21jcC93b3Jrc3BhY2VcIjtcblxuZXhwb3J0IGNvbnN0IFJFUVVJUkVEX01PRFVMRV9GT0xERVJTID0gW1xuICBcInByb21wdHNcIixcbiAgXCJyZXNvdXJjZXNcIixcbiAgXCJ0ZW1wbGF0ZXNcIixcbiAgXCJ0b29sc1wiLFxuXSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgTW9kdWxlRm9sZGVyID0gKHR5cGVvZiBSRVFVSVJFRF9NT0RVTEVfRk9MREVSUylbbnVtYmVyXTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVNb2R1bGVzUm9vdCh3b3Jrc3BhY2VSb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGgucmVzb2x2ZSh3b3Jrc3BhY2VSb290LCBcInNyYy9tb2R1bGVzXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbGlzdE1vZHVsZURpcmVjdG9yaWVzKHdvcmtzcGFjZVJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KCkpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHJvb3QgPSByZXNvbHZlTW9kdWxlc1Jvb3Qod29ya3NwYWNlUm9vdCk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhyb290KSkgcmV0dXJuIFtdO1xuXG4gIHJldHVybiBmc1xuICAgIC5yZWFkZGlyU3luYyhyb290KVxuICAgIC5tYXAoKGVudHJ5KSA9PiAoe1xuICAgICAgZW50cnksXG4gICAgICBhYnNvbHV0ZTogcGF0aC5qb2luKHJvb3QsIGVudHJ5KSxcbiAgICB9KSlcbiAgICAuZmlsdGVyKCh7IGFic29sdXRlIH0pID0+IGZzLnN0YXRTeW5jKGFic29sdXRlKS5pc0RpcmVjdG9yeSgpKVxuICAgIC5tYXAoKHsgZW50cnkgfSkgPT4gZW50cnkpXG4gICAgLnNvcnQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVNb2R1bGVQYXRoKFxuICBtb2R1bGVOYW1lOiBzdHJpbmcsXG4gIHdvcmtzcGFjZVJvb3QgPSBnZXRXb3Jrc3BhY2VSb290KClcbik6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLmpvaW4ocmVzb2x2ZU1vZHVsZXNSb290KHdvcmtzcGFjZVJvb3QpLCBtb2R1bGVOYW1lKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVNb2R1bGVGb2xkZXJQYXRoKFxuICBtb2R1bGVOYW1lOiBzdHJpbmcsXG4gIGZvbGRlcjogTW9kdWxlRm9sZGVyLFxuICB3b3Jrc3BhY2VSb290ID0gZ2V0V29ya3NwYWNlUm9vdCgpXG4pOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKHJlc29sdmVNb2R1bGVQYXRoKG1vZHVsZU5hbWUsIHdvcmtzcGFjZVJvb3QpLCBmb2xkZXIpO1xufVxuIiwiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBNY3BNb2R1bGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIGZvciBDTEkgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgQSBzdGF0aWMgdXRpbGl0eSBjbGFzcyB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgZm9yIGxvYWRpbmcgbW9kdWxlcywgcmV0cmlldmluZyBwYWNrYWdlIGluZm9ybWF0aW9uLCBhbmQgaW5pdGlhbGl6aW5nIENMSSBjb21tYW5kc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJbml0aWFsaXplIGEgQ29tbWFuZCBvYmplY3Qgd2l0aCBwYWNrYWdlIGluZm9ybWF0aW9uXG4gKiBjb25zdCBjb21tYW5kID0gbmV3IENvbW1hbmQoKTtcbiAqIENMSVV0aWxzLmluaXRpYWxpemUoY29tbWFuZCwgJy4vcGF0aC90by9wYWNrYWdlJyk7XG4gKlxuICogLy8gTG9hZCBhIENMSSBtb2R1bGUgZnJvbSBhIGZpbGVcbiAqIGNvbnN0IG1vZHVsZSA9IGF3YWl0IENMSVV0aWxzLmxvYWRGcm9tRmlsZSgnLi9wYXRoL3RvL2NsaS1tb2R1bGUuanMnKTtcbiAqXG4gKiBAY2xhc3MgTWNwVXRpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIE1jcFV0aWxzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEeW5hbWljYWxseSBpbXBvcnRzIGEgbW9kdWxlIGZpbGVcbiAgICogQHN1bW1hcnkgTG9hZHMgYSBKYXZhU2NyaXB0IGZpbGUgYW5kIHJldHVybnMgaXQgYXMgYSBDbGlNb2R1bGUsIGhhbmRsaW5nIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBmaWxlIHBhdGggdG8gdGhlIG1vZHVsZSB0byBsb2FkXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TWNwTW9kdWxlPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxvYWRlZCBDbGlNb2R1bGVcbiAgICovXG4gIHN0YXRpYyBhc3luYyBsb2FkRnJvbUZpbGUocGF0aDogc3RyaW5nKTogUHJvbWlzZTxNY3BNb2R1bGU+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIE1jcFV0aWxzLm5vcm1hbGl6ZUltcG9ydChpbXBvcnQocGF0aCkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsb2FkIGZyb20gJHtwYXRofTogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBlfWBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBOb3JtYWxpemVzIG1vZHVsZSBpbXBvcnRzIHRvIGhhbmRsZSBib3RoIEVTTSBhbmQgQ29tbW9uSlMgZm9ybWF0c1xuICAgKiBAc3VtbWFyeSBQcm9wZXJseSBpbXBvcnRzIEphdmFTY3JpcHQgZmlsZXMgcmVnYXJkbGVzcyBvZiB0aGVpciBtb2R1bGUgZm9ybWF0IGJ5IGhhbmRsaW5nIHRoZSBFU00gd3JhcHBlciBmb3IgQ29tbW9uSlMgbW9kdWxlc1xuICAgKlxuICAgKiBAdGVtcGxhdGUgVCBUaGUgdHlwZSBvZiB0aGUgaW1wb3J0ZWQgbW9kdWxlXG4gICAqIEBwYXJhbSB7UHJvbWlzZTxUPn0gaW1wb3J0UHJvbWlzZSBUaGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZHluYW1pYyBpbXBvcnRcbiAgICogQHJldHVybiB7UHJvbWlzZTxUPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIG5vcm1hbGl6ZWQgbW9kdWxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgbm9ybWFsaXplSW1wb3J0PFQ+KGltcG9ydFByb21pc2U6IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAvLyBDb21tb25KUydzIGBtb2R1bGUuZXhwb3J0c2AgaXMgd3JhcHBlZCBhcyBgZGVmYXVsdGAgaW4gRVNNb2R1bGUuXG4gICAgcmV0dXJuIGltcG9ydFByb21pc2UudGhlbihcbiAgICAgIChtOiB1bmtub3duKSA9PiAoKG0gYXMgeyBkZWZhdWx0OiBUIH0pLmRlZmF1bHQgfHwgbSkgYXMgVFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhbmQgcGFyc2VzIHRoZSBwYWNrYWdlLmpzb24gZmlsZVxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgcGFja2FnZS5qc29uIGZpbGUgZnJvbSB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIHBhcnNlcyBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IFRoZSBwYXJzZWQgcGFja2FnZS5qc29uIGNvbnRlbnQgYXMgYW4gb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRQYWNrYWdlKGJhc2VQYXRoOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKFxuICAgICAgICBmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKGJhc2VQYXRoLCBcInBhY2thZ2UuanNvblwiKSwgXCJ1dGY4XCIpXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJlYWQgdmVyc2lvbiBmcm9tICR7YmFzZVBhdGh9OiAke2V9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgdmVyc2lvbiBmaWVsZCBmcm9tIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGhcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFja2FnZSB2ZXJzaW9uIHN0cmluZ1xuICAgKi9cbiAgc3RhdGljIHBhY2thZ2VWZXJzaW9uKGJhc2VQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBNY3BVdGlscy5nZXRQYWNrYWdlKGJhc2VQYXRoKVtcInZlcnNpb25cIl0gYXMgc3RyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSBuYW1lIGZyb20gcGFja2FnZS5qc29uXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgbmFtZSBmaWVsZCBmcm9tIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGggYW5kIGV4dHJhY3RzIHRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2VQYXRoIFRoZSBiYXNlIHBhdGggd2hlcmUgdGhlIHBhY2thZ2UuanNvbiBmaWxlIGlzIGxvY2F0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcGFja2FnZSBuYW1lIHdpdGhvdXQgdGhlIHNjb3BlIChlLmcuLCBcImNsaVwiIGZyb20gXCJAZGVjYWYtdHMvY2xpXCIpXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZU5hbWUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbmFtZSA9IChNY3BVdGlscy5nZXRQYWNrYWdlKGJhc2VQYXRoKVtcIm5hbWVcIl0gYXMgc3RyaW5nKS5zcGxpdChcIi9cIik7XG4gICAgcmV0dXJuIG5hbWVbbmFtZS5sZW5ndGggLSAxXTtcbiAgfVxufVxuXG5leHBvcnQgKiBmcm9tIFwiLi91dGlscy9tb2R1bGVQYXRoc1wiO1xuIiwiaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBNQ1BfRklMRV9OQU1FIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNY3BVdGlscyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBGYXN0TUNQIH0gZnJvbSBcImZhc3RtY3BcIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSBcIi4vbWV0YWRhdGFcIjtcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwidXJsXCI7XG5cbi8vIGFsbG93IHJlZmVyZW5jaW5nIF9fZmlsZW5hbWUvX19kaXJuYW1lIGluIGJvdGggQ29tbW9uSlMgYW5kIEVTTSBydW50aW1lc1xuZGVjbGFyZSBjb25zdCBfX2ZpbGVuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5kZWNsYXJlIGNvbnN0IF9fZGlybmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIHRvIGhhbmRsZSBDTEkgZnVuY3Rpb25hbGl0eSBmcm9tIGFsbCBEZWNhZiBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgd3JhcHBlciBhcm91bmQgQ29tbWFuZGVyLmpzIHRvIGhhbmRsZSBDTEkgY29tbWFuZHMgZnJvbSBkaWZmZXJlbnQgRGVjYWYgbW9kdWxlcy5cbiAqIEl0IGNyYXdscyB0aGUgZmlsZXN5c3RlbSB0byBmaW5kIENMSSBtb2R1bGVzLCBsb2FkcyB0aGVtLCBhbmQgcmVnaXN0ZXJzIHRoZWlyIGNvbW1hbmRzLlxuICovXG5leHBvcnQgY2xhc3MgTWNwV3JhcHBlciBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAgcHJpdmF0ZSBfbWNwPzogRmFzdE1DUDtcbiAgcHJpdmF0ZSBtb2R1bGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdFBhdGg6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGJhc2VQYXRoOiBzdHJpbmcgPSBcIi4vXCIsXG4gICAgcHJpdmF0ZSBjcmF3bExldmVscyA9IDRcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICAvLyBTdXBwb3J0IGJvdGggQ29tbW9uSlMgYW5kIEVTTSBydW50aW1lcyBmb3IgZmlsZW5hbWUvZGlybmFtZVxuICAgIGxldCBsb2NhbERpcm5hbWU6IHN0cmluZztcbiAgICBpZiAodHlwZW9mIF9fZmlsZW5hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIF9fZGlybmFtZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgLy8gQ29tbW9uSlMgZW52aXJvbm1lbnRcbiAgICAgIGxvY2FsRGlybmFtZSA9IF9fZGlybmFtZSBhcyBzdHJpbmc7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEVTTSBvciBvdGhlciBlbnY6IGNvbXB1dGUgaW1wb3J0Lm1ldGEudXJsIGF0IHJ1bnRpbWUgdG8gYXZvaWQgVFMgY29tcGlsZS10aW1lIGltcG9ydC5tZXRhIGNoZWNrc1xuICAgICAgbGV0IG1ldGFVcmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFVzZSBhIGR5bmFtaWMgZnVuY3Rpb24gc28gVHlwZVNjcmlwdCB3b24ndCBwYXJzZSBgaW1wb3J0Lm1ldGFgIGF0IGNvbXBpbGUgdGltZVxuICAgICAgICBjb25zdCBmbiA9IG5ldyBGdW5jdGlvbihcbiAgICAgICAgICAncmV0dXJuICh0eXBlb2YgaW1wb3J0ICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiBpbXBvcnQubWV0YSAhPT0gXCJ1bmRlZmluZWRcIikgPyBpbXBvcnQubWV0YS51cmwgOiB1bmRlZmluZWQ7J1xuICAgICAgICApO1xuICAgICAgICBtZXRhVXJsID0gZm4oKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBtZXRhVXJsID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKG1ldGFVcmwpIHtcbiAgICAgICAgbG9jYWxEaXJuYW1lID0gcGF0aC5kaXJuYW1lKGZpbGVVUkxUb1BhdGgobWV0YVVybCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gTGFzdC1yZXNvcnQgZmFsbGJhY2s6IHVzZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5XG4gICAgICAgIGxvY2FsRGlybmFtZSA9IHByb2Nlc3MuY3dkKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucm9vdFBhdGggPSBwYXRoLnJlc29sdmUobG9jYWxEaXJuYW1lLCBcIi4uXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYW5kIGluaXRpYWxpemVzIHRoZSBDb21tYW5kZXIgQ29tbWFuZCBvYmplY3RcbiAgICogQHN1bW1hcnkgTGF6eS1sb2FkcyB0aGUgQ29tbWFuZCBvYmplY3QsIGluaXRpYWxpemluZyBpdCB3aXRoIHRoZSBwYWNrYWdlIG5hbWUsIGRlc2NyaXB0aW9uLCBhbmQgdmVyc2lvblxuICAgKiBAcmV0dXJuIHtGYXN0TUNQfSBUaGUgaW5pdGlhbGl6ZWQgQ29tbWFuZCBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0IG1jcCgpIHtcbiAgICBpZiAoIXRoaXMuX21jcCkge1xuICAgICAgdGhpcy5fbWNwID0gbmV3IEZhc3RNQ1Aoe1xuICAgICAgICBuYW1lOiBcImRlY2FmLXRzIE1DUCBzZXJ2ZXJcIixcbiAgICAgICAgaW5zdHJ1Y3Rpb25zOiBcIlwiLFxuICAgICAgICB2ZXJzaW9uOiBWRVJTSU9OIGFzIGFueSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbWNwO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2FkcyBhbmQgcmVnaXN0ZXJzIGFuIG1jcCBleHRlbnNpb24gbW9kdWxlIGZyb20gYSBmaWxlXG4gICAqIEBzdW1tYXJ5IER5bmFtaWNhbGx5IGltcG9ydHMgYW4gbWNwIGV4dGVuc2lvbiBtb2R1bGUgZnJvbSB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aCwgaW5pdGlhbGl6ZXMgaXQsIGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIG1vZHVsZXMgY29sbGVjdGlvblxuICAgKlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkKFxuICAgIHNlcnZlcjogRmFzdE1DUCxcbiAgICBmaWxlUGF0aDogc3RyaW5nXG4gICk6IFByb21pc2U8eyBtY3A6IEZhc3RNQ1A7IHBhY2thZ2U6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5sb2FkKTtcblxuICAgIGxldCBwa2c6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nLCBlbnJpY2g6IGFueTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgTWNwVXRpbHMubG9hZEZyb21GaWxlKGZpbGVQYXRoKTtcbiAgICAgIHBrZyA9IHJlcy5QQUNLQUdFX05BTUU7XG4gICAgICB2ZXJzaW9uID0gcmVzLlZFUlNJT047XG4gICAgICBlbnJpY2ggPSByZXMuZW5yaWNoO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigoZSBhcyBhbnkpLm1lc3NhZ2UgfHwgKGUgYXMgYW55KSk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBsb2cuaW5mbyhgRW5yaWNoaW5nIG1jcCBzZXJ2ZXIgd2l0aCBtb2R1bGUgJHtwa2d9IHYke3ZlcnNpb259YCk7XG4gICAgICBjb25zdCByZXN1bHQgPSBlbnJpY2goc2VydmVyKTtcbiAgICAgIHNlcnZlciA9IHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UgPyBhd2FpdCByZXN1bHQgOiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGVucmljaCBtY3Agd2l0aCBtb2R1bGUgJHtwa2cgfHwgXCJ1bm5hbWVkXCJ9IHVuZGVyICR7ZmlsZVBhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIG1jcDogc2VydmVyLFxuICAgICAgcGFja2FnZTogcGtnLFxuICAgICAgdmVyc2lvbjogdmVyc2lvbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGaW5kcyBhbmQgbG9hZHMgYWxsIENMSSBtb2R1bGVzIGluIHRoZSBiYXNlUGF0aFxuICAgKiBAc3VtbWFyeSBVc2VzIHRoZSBjcmF3bCBtZXRob2QgdG8gZmluZCBhbGwgQ0xJIG1vZHVsZXMgaW4gdGhlIHNwZWNpZmllZCBiYXNlIHBhdGgsXG4gICAqIHRoZW4gbG9hZHMgYW5kIHJlZ2lzdGVycyBlYWNoIG1vZHVsZSBhcyBhIHN1YmNvbW1hbmRcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgbW9kdWxlcyBhcmUgbG9hZGVkXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaVdyYXBwZXJcbiAgICogICBwYXJ0aWNpcGFudCBGaWxlc3lzdGVtXG4gICAqICAgcGFydGljaXBhbnQgTW9kdWxlXG4gICAqXG4gICAqICAgQ2xpV3JhcHBlci0+PkZpbGVzeXN0ZW06IEpvaW4gYmFzZVBhdGggd2l0aCBjd2RcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogY3Jhd2woYmFzZVBhdGgsIGNyYXdsTGV2ZWxzKVxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpV3JhcHBlcjogbW9kdWxlc1tdXG4gICAqICAgbG9vcCBGb3IgZWFjaCBtb2R1bGVcbiAgICogICAgIGFsdCBOb3QgQGRlY2FmLXRzL2NsaVxuICAgKiAgICAgICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogbG9hZChtb2R1bGUsIGN3ZClcbiAgICogICAgICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBuYW1lXG4gICAqICAgICAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBDaGVjayBpZiBjb21tYW5kIGV4aXN0c1xuICAgKiAgICAgICBhbHQgQ29tbWFuZCBkb2Vzbid0IGV4aXN0XG4gICAqICAgICAgICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IGNvbW1hbmQobmFtZSkuYWRkQ29tbWFuZChtb2R1bGVzW25hbWVdKVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIENsaVdyYXBwZXItPj5Db25zb2xlOiBMb2cgbG9hZGVkIG1vZHVsZXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYm9vdCgpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5ib290KTtcbiAgICBsZXQgc2VydmVyID0gdGhpcy5tY3A7XG4gICAgLy8gZGlzY292ZXIgbW9kdWxlcyBieSBjcmF3bGluZyBiYXNlUGF0aFxuICAgIGNvbnN0IG1vZHVsZUZpbGVzID0gdGhpcy5jcmF3bChcbiAgICAgIHBhdGgucmVzb2x2ZSh0aGlzLmJhc2VQYXRoKSxcbiAgICAgIHRoaXMuY3Jhd2xMZXZlbHNcbiAgICApO1xuICAgIGZvciAoY29uc3QgbW9kdWxlRmlsZSBvZiBtb2R1bGVGaWxlcykge1xuICAgICAgaWYgKG1vZHVsZUZpbGUuaW5jbHVkZXMoXCJAZGVjYWYtdHMvbWNwXCIpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5sb2FkKHNlcnZlciwgbW9kdWxlRmlsZSk7XG4gICAgICAgIHNlcnZlciA9IHJlcy5tY3A7XG4gICAgICAgIHRoaXMubW9kdWxlc1tyZXMucGFja2FnZV0gPSBtb2R1bGVGaWxlO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byBsb2FkIE1DUCBjb25maWdzIGZvciAke21vZHVsZUZpbGV9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBsb2FkZWQgbW9kdWxlczpcXG4ke09iamVjdC5rZXlzKHRoaXMubW9kdWxlcylcbiAgICAgICAgLm1hcCgoaykgPT4gYC0gJHtrfWApXG4gICAgICAgIC5qb2luKFwiXFxuXCIpfWBcbiAgICApO1xuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlY3Vyc2l2ZWx5IHNlYXJjaGVzIGZvciBDTEkgbW9kdWxlIGZpbGVzIGluIHRoZSBkaXJlY3Rvcnkgc3RydWN0dXJlXG4gICAqIEBzdW1tYXJ5IENyYXdscyB0aGUgYmFzZVBhdGggdXAgdG8gdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZm9sZGVyIGxldmVscyB0byBmaW5kIGZpbGVzIG5hbWVkIGFjY29yZGluZyB0byBDTElfRklMRV9OQU1FXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYWJzb2x1dGUgYmFzZSBwYXRoIHRvIHN0YXJ0IHNlYXJjaGluZyBpblxuICAgKiBAcGFyYW0ge251bWJlcn0gW2xldmVscz0yXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgZGlyZWN0b3J5IGxldmVscyB0byBjcmF3bFxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQW4gYXJyYXkgb2YgZmlsZSBwYXRocyB0byBDTEkgbW9kdWxlc1xuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmF3bChiYXNlUGF0aDogc3RyaW5nLCBsZXZlbHM6IG51bWJlciA9IDIpIHtcbiAgICBpZiAobGV2ZWxzIDw9IDApIHJldHVybiBbXTtcbiAgICByZXR1cm4gZnMucmVhZGRpclN5bmMoYmFzZVBhdGgpLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBmaWxlKSA9PiB7XG4gICAgICBmaWxlID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlKTtcbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goLi4udGhpcy5jcmF3bChmaWxlLCBsZXZlbHMgLSAxKSk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGUubWF0Y2gobmV3IFJlZ0V4cChgJHtNQ1BfRklMRV9OQU1FfS5bY21dP2pzJGAsIFwiZ21cIikpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goZmlsZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyB0aGUgQ0xJIHdpdGggdGhlIHByb3ZpZGVkIGFyZ3VtZW50c1xuICAgKiBAc3VtbWFyeSBCb290cyB0aGUgQ0xJIGJ5IGxvYWRpbmcgYWxsIG1vZHVsZXMsIHRoZW4gcGFyc2VzIGFuZCBleGVjdXRlcyB0aGUgY29tbWFuZCBzcGVjaWZpZWQgaW4gdGhlIGFyZ3VtZW50c1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncz1wcm9jZXNzLmFyZ3ZdIENvbW1hbmQgbGluZSBhcmd1bWVudHMgdG8gcGFyc2UgYW5kIGV4ZWN1dGVcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29tbWFuZCBleGVjdXRpb24gaXMgY29tcGxldGVcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IENvbW1hbmRcbiAgICpcbiAgICogICBDbGllbnQtPj5DbGlXcmFwcGVyOiBydW4oYXJncylcbiAgICogICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogYm9vdCgpXG4gICAqICAgTm90ZSBvdmVyIENsaVdyYXBwZXI6IExvYWRzIGFsbCBtb2R1bGVzXG4gICAqICAgQ2xpV3JhcHBlci0+PkNvbW1hbmQ6IHBhcnNlQXN5bmMoYXJncylcbiAgICogICBDb21tYW5kLS0+PkNsaVdyYXBwZXI6IHJlc3VsdFxuICAgKiAgIENsaVdyYXBwZXItLT4+Q2xpZW50OiByZXN1bHRcbiAgICovXG4gIGFzeW5jIHJ1bihhcmdzOiBzdHJpbmdbXSA9IHByb2Nlc3MuYXJndikge1xuICAgIHZvaWQgYXJncztcbiAgICBjb25zdCBzZXJ2ZXIgPSBhd2FpdCB0aGlzLmJvb3QoKTtcbiAgICBhd2FpdCBzZXJ2ZXIuc3RhcnQoeyB0cmFuc3BvcnRUeXBlOiBcInN0ZGlvXCIgfSk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJ6Iiwic3Bhd25TeW5jIiwiYXBwbHlQYXRjaCIsImNyZWF0ZVR3b0ZpbGVzUGF0Y2giLCJ0b29sTGlzdCIsImNvcmVUb29sTGlzdCIsIlZFUlNJT04iLCJQQUNLQUdFX05BTUUiLCJNZXRhZGF0YSIsIlBLRyIsIlYiLCJwYXRoVG9GaWxlVVJMIiwicGF0aCIsImZzIiwiTG9nZ2VkQ2xhc3MiLCJmaWxlVVJMVG9QYXRoIiwiRmFzdE1DUCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFBQTs7Ozs7O0lBTUc7QUFDSSxVQUFNLGFBQWEsR0FBRztBQUd0QixVQUFNLGtCQUFrQixHQUFHO1VBQ3JCLGtCQUFrQixHQUFHLENBQUMsZUFBZSxFQUFFLGdCQUFnQjtBQUM3RCxVQUFNLG1CQUFtQixHQUFHO0FBQzVCLFVBQU0sbUJBQW1CLEdBQUc7SUFDakMsSUFBQTtJQUNFLFFBQUEsRUFBRSxFQUFFLFFBQVE7SUFDWixRQUFBLE9BQU8sRUFBRSxvQkFBb0I7SUFDN0IsUUFBQSxZQUFZLEVBQ1Ysb01BQW9NO0lBQ3ZNLEtBQUE7SUFDRCxJQUFBO0lBQ0UsUUFBQSxFQUFFLEVBQUUsUUFBUTtJQUNaLFFBQUEsT0FBTyxFQUFFLFFBQVE7SUFDakIsUUFBQSxZQUFZLEVBQ1YsaUxBQWlMO0lBQ3BMLEtBQUE7SUFDRCxJQUFBO0lBQ0UsUUFBQSxFQUFFLEVBQUUsU0FBUztJQUNiLFFBQUEsT0FBTyxFQUFFLGdCQUFnQjtJQUN6QixRQUFBLFlBQVksRUFDVixpTUFBaU07SUFDcE0sS0FBQTs7O0lDM0JILElBQUksYUFBYSxHQUFHLHVCQUF1QixFQUFFO0lBQzdDLElBQUksYUFBMkQ7SUFFekQsTUFBTyxjQUFlLFNBQVEsS0FBSyxDQUFBO0lBQ3ZDLElBQUEsV0FBQSxDQUFZLE9BQWUsRUFBQTtZQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDO0lBQ2QsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLGdCQUFnQjtRQUM5QjtJQUNE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
|
|
1
|
+
var e,t;e=this,t=function(e,t,r,n,o,s,i,a,c,d,l,m,u,p,h,g,f){"use strict";function y(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var b,S,v,w=y(c),x=y(d);(e=>{e[e.NONE=0]="NONE",e[e.BASIC=1]="BASIC",e[e.ADVANCED=2]="ADVANCED",e[e.HIGH=3]="HIGH"})(b||(b={})),(e=>{e[e.NONE=0]="NONE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(S||(S={})),(e=>{e[e.FREE=0]="FREE",e[e.LOW=1]="LOW",e[e.MEDIUM=2]="MEDIUM",e[e.HIGH=3]="HIGH"})(v||(v={}));class T extends r.Model{constructor(e){super(e),r.Model.fromObject(this,e)}log(e){const{sessionId:t,requestId:r,authInfo:o}=e||{};let s="string"==typeof t&&t.length>0?n.Logging.for(t).for(this):n.Logging.for(this);return o&&o.clientId&&(s=s.for(o.clientId)),r&&(s=s.for(r.toString())),s}setDescription(e){return this.description=e,this}setName(e){return this.name=e,this}setTitle(e){return this.title=e,this}}t.__decorate([r.required(),t.__metadata("design:type",String)],T.prototype,"description",void 0),t.__decorate([r.required(),t.__metadata("design:type",String)],T.prototype,"name",void 0),t.__decorate([r.required(),t.__metadata("design:type",String)],T.prototype,"title",void 0);class N extends T{constructor(e){super(e),this.reasoning=b.NONE,this.effort=S.NONE,this.cost=v.FREE}setReasoning(e){return this.reasoning=e,this}setEffort(e){return this.effort=e,this}setCost(e){return this.cost=e,this}}t.__decorate([r.required(),t.__metadata("design:type",Number)],N.prototype,"reasoning",void 0),t.__decorate([r.required(),t.__metadata("design:type",Number)],N.prototype,"effort",void 0),t.__decorate([r.required(),t.__metadata("design:type",Number)],N.prototype,"cost",void 0);class _ extends N{setCb(e){return this.cb=e,this}setArgsSchema(e){return this.argsSchema=e,this}constructor(e){super(e)}static get builder(){return new _}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{return e.registerPrompt(this.name,{title:this.title,description:this.description,argsSchema:this.argsSchema},async(e,t)=>{const r=this.log(t);e=e||{},r.verbose(`Executing prompt ${this.name} with args: ${JSON.stringify(e)}`),e._meta=Object.assign(e._meta||{},{usage:{reasoning:this.reasoning,effort:this.effort,cost:this.cost}});const n=await Promise.resolve(this.cb(e,t));return r.verbose(`Prompt ${this.name} executed successfully.`),r.debug("Prompt execution meta: "+JSON.stringify(n._meta)),n})}catch(e){throw n.Logging.for(this).error("Failed to register prompt "+this.name,e),e}}}t.__decorate([r.required(),t.__metadata("design:type",Object)],_.prototype,"cb",void 0),t.__decorate([r.required(),t.__metadata("design:type",Object)],_.prototype,"argsSchema",void 0);class E extends T{setCb(e){return this.cb=e,this}setConfig(e){return this.config=e,this}setUriOtTemplate(e){return this.uriOrTemplate=e,this}constructor(e){super(e)}static get builder(){return new E}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{const t="string"==typeof this.uriOrTemplate&&this.uriOrTemplate.includes("{")?new s.ResourceTemplate(new o.UriTemplate(this.uriOrTemplate),{list:void 0}):this.uriOrTemplate,r=Object.assign(this.config,{_meta:{}}),n=async(e,t)=>{const r=this.log(t);r.verbose(`Requesting resource ${this.name} from ${e.toString()}`);const n=await Promise.resolve(this.cb(e,t));return r.verbose(`Resource ${this.name} retrieved successfully.`),r.debug("Resource retrieval meta: "+JSON.stringify(n._meta)),n};return e.resource(this.name,t,r,n)}catch(e){throw n.Logging.for(this).error("Error registering resource "+this.name,e),e}}}t.__decorate([r.required(),t.__metadata("design:type",String)],E.prototype,"uriOrTemplate",void 0),t.__decorate([r.required(),t.__metadata("design:type",Function)],E.prototype,"cb",void 0),t.__decorate([r.required(),t.__metadata("design:type",Object)],E.prototype,"config",void 0);class O extends N{setAnnotations(e){return this.annotations=Object.assign(this.annotations,e),this}setCb(e){return this.cb=e,this}setInputSchema(e){return this.inputSchema=e,this}setOutputSchema(e){return this.outputSchema=e,this}constructor(e){super(e),this.annotations={readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}}static get builder(){return new O}build(e){const t=this.hasErrors();if(t)throw Error(t.toString());try{return e.registerTool(this.name,{title:this.title,description:this.description,inputSchema:this.inputSchema,outputSchema:this.outputSchema,annotations:this.annotations,_meta:{usage:{reasoning:this.reasoning,effort:this.effort,cost:this.cost}}},async(e,t)=>{const r=this.log(t);r.verbose(`Executing tool ${this.name} with args: ${JSON.stringify(e)}`),t._meta=Object.assign(t._meta||{},{usage:{reasoning:this.reasoning,effort:this.effort,cost:this.cost}});const n=await Promise.resolve(this.cb(e,t));return r.verbose(`Tool ${this.name} executed successfully.`),r.debug("Tool execution meta: "+JSON.stringify(n._meta)),n})}catch(e){throw n.Logging.for(this).error("Error building tool",e),e}}}t.__decorate([r.required(),t.__metadata("design:type",Object)],O.prototype,"annotations",void 0),t.__decorate([r.required(),t.__metadata("design:type",Object)],O.prototype,"cb",void 0),t.__decorate([r.type(Object.name),r.required(),t.__metadata("design:type",Object)],O.prototype,"inputSchema",void 0),t.__decorate([r.type(Object.name),t.__metadata("design:type",Object)],O.prototype,"outputSchema",void 0);const D=["\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"];let j=null;async function A(e){const t=j||(j=new m.Project({tsConfigFilePath:void 0,skipAddingFilesFromTsConfig:!0}),j),r=t.addSourceFileAtPathIfExists(e)||t.createSourceFile(e,void 0,{overwrite:!1});try{await Promise.race([t.resolveSourceFileDependencies(),new Promise(e=>setTimeout(e,2e3))])}catch(e){}const n=r.getExportedDeclarations();return{astObjects:Array.from(n.entries()).flatMap(([t,r])=>r.map(r=>{const n="function"==typeof r.getStartLineNumber?r.getStartLineNumber():0,o="function"==typeof r.getEndLineNumber?r.getEndLineNumber():0,s="function"==typeof r.getKindName?(r.getKindName()+"").toLowerCase():"unknown",i="function"==typeof r.getStartLinePos?r.getStartLinePos():0;return{id:`${e}::${t}`,name:t,kind:s,location:{filePath:e,startLine:n,startColumn:i,endLine:o,endColumn:0},isExported:!0}}))}}const C="ts.ast.extract",P="AST Extraction Tool for TypeScript",I=l.z.object({filePath:l.z.string().describe("The path to the TypeScript file to analyze.")}).describe(`the input schema for the ${C} tool`);l.z.object({}).describe(`the output schema for the ${C} tool`);const $=O.builder.setName(C).setTitle(P).setDescription("Extracts and analyzes the Abstract Syntax Tree (AST) of TypeScript code to provide insights into its structure and components.").setInputSchema(I).setAnnotations({title:P,readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}).setCb(async(e,t)=>{const{filePath:r}=e,n=await Promise.race([A(r),new Promise(e=>setTimeout(()=>e(null),1500))]);if(!n||!n.astObjects)return{content:[{type:"text",text:"No AST objects or analysis timed out"}],structuredContent:{astObjects:[]}};const o=n.astObjects.map(e=>({id:e.id,name:e.name,kind:e.kind||"unknown",location:e.location,isExported:!!e.isExported,signature:e.signature,parentId:e.parentId,children:e.children,decorators:e.decorators,contextHints:e.contextHints||[]}));return{content:[{type:"text",text:`Found ${o.length} AST objects`}],structuredContent:{astObjects:o}}}),k=O.builder.setName("example-tool").setTitle("Example: Reverse String Tool").setDescription("Reverses the provided `text` input and returns the result.").setInputSchema(l.z.object({text:l.z.string()})).setCb(async(e,t)=>{const r=((e?.text??"")+"").split("").reverse().join("");return{content:[{type:"text",text:r}],structuredContent:{result:r}}}).setReasoning(b.NONE).setEffort(S.NONE).setCost(v.FREE),R=O.builder.setName("ast.jsdoc").setTitle("AST \u2192 JSDoc Tool").setDescription("Generate suggested JSDoc comments for TypeScript AST objects (MVP stub).").setInputSchema(l.z.object({filePath:l.z.string()})).setCb(async(e,t)=>{const r=[{type:"text",text:"Not implemented (stub)"}];return{content:r,structuredContent:{content:r}}}).setReasoning(b.BASIC).setEffort(S.LOW).setCost(v.FREE),q=[$,k,O.builder.setName("file.summarizer").setTitle("File Summarizer").setDescription("Produce a short structured summary for a TypeScript file.").setInputSchema(l.z.object({filePath:l.z.string()})).setCb(async(e,t)=>{if(!(e?.filePath??e?.path))return{content:[{type:"text",text:""}]};const r=await(async()=>({astObjects:[]}))().catch(()=>null),n=r&&r.astObjects||[],o=n.map(e=>e.name||e.id||e.kind).slice(0,20),s=`Found ${n.length} AST objects. Top names: ${o.join(", ")}`;return{content:[{type:"text",text:s}],structuredContent:{summary:s},_meta:{count:n.length}}}).setReasoning(b.NONE).setEffort(S.NONE).setCost(v.FREE),R];var z=Object.freeze({__proto__:null,Tools:q});const J="You're a senior TypeScript developer writing JSDoc documentation for a class to be used with better-docs. Given the module code:\nGenerate a JSDoc comment block for a TypeScript module file using better-docs formatting:",M="document the target code, always including the @description tag with a short description of the target, and a@summary tag with a more detailed one.\n Include @interface and @typeDef an @template tags when appropriate.\n Include detailed @description for all properties.\n For methods, include @description and @summary tags as defined for the target. also document every argument, including its type definition, and return type, referencing @template tags when necessary.\n\n The order of tags (when applicable) should be as follows:\n1 - @description;\n2 - @summary;\n3 - @template;\n4 - @param;\n5 - @return;\n6 - @interface or @typeDef followed by the interface or type name;\n8 - @memberOf referencing the appropriate module using the appropriate syntax\n\nOutput only the completed JSDoc comment block for the type or interface.\nrefer to the module it belongs with @memberOf this the `@memberOf module:<module_name>` syntax\nnever omit or change any code\nif the element is already documented, only restructure, correct, or add to the documentation. NEVER remove existing information",L="document the target code, always including the @description tag with a short description of the target, and a@summary tag with a more detailed one.\nInclude @const and @typeDef tags when appropriate.\nInclude detailed @description for all properties.\n- For enums, include @enum and @readonly, and add inline documentation for each member\n- For object-like constants:\n - Create a @typedef with @property for each key\n - Reference it in the constant using @type\n - Alternatively, document each key inline if small\n\nThe order of tags (when applicable) should be as follows:\n1 - @description;\n2 - @summary;\n3 - @template;\n4 - @property;\n6 - @const followed by the const or enum name;\n8 - @memberOf referencing the appropriate module using the appropriate syntax\n\nRespond with the JSDoc comment block(s) for both the typedef and the constant or enum.\nrefer to the module it belongs with @memberOf this the `@memberOf module:<module_name>` syntax\nnever omit or change any code\nif the element is already documented, only restructure, correct, or add to the documentation. NEVER remove existing information",F="NOTES:\n - when document a function/method parameters, and there is a template type involved, ALWAYS reference it using the @template tag;\n - when documenting a function type as a parameter, ALWAYS use the function(type1,type2):return_type syntax;\n ",H=l.z.object({}),B=_.builder.setName("ts.jsdoc.class").setTitle("Class JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript class according to a curated template and prompt.").setArgsSchema(H).setReasoning(b.BASIC).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\ndocument the entire class and each of its functions including always including the @description tag with a short description of the target, and a@summary tag with a more detailed one.\nInclude @class tags when applicable.\ninclude @param tags in the class documentation and its type definitions\nInclude detailed @description for all properties.\nInclude @template tags when necessary.\nDo NOT document the constructor, but include the constructor arguments as @param in the class documentation\nFor methods and functions:\n- include @description and @summary tags as defined for the target. also document every argument, including its type definition, and return type, referencing @template tags when necessary.\n- create a usage example under the @example tag on the class documentation\n- create mermaid sequence diagrams under the @mermaid tag;\n\nThe order of tags (when applicable) should be as follows:\n1 - @description;\n2 - @summary;\n3 - @template;\n4 - @param;\n5 - @return;\n6 - @class\n7 - @example\n8 - @mermaid;\n\nignore @mermaid for methods with less that 15 lines and constructors.\nRespond only with the full JSDoc comment block for the class and its methods.\nNEVER user @memberOf in the class or any of it's methods\nif the element is already documented, only restructure, correct, or add to the documentation. NEVER remove existing information\nnever omit or change any code, including the constructor\n${F}`}}],_meta:{}})),G=l.z.object({}),U=_.builder.setName("ts.jsdoc.const").setTitle("Const JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript constant according to a curated template and prompt.").setArgsSchema(G).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\n${L}\n${F}`}}]})),V=l.z.object({}),W=_.builder.setName("ts.jsdoc.decorator").setTitle("Decorator JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript Decorator according to a curated template and prompt.").setArgsSchema(V).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\ndocument the target code, always including the @description tag with a short description of the target, and a@summary tag with a more detailed one.\nInclude @function an @template tags when appropriate.\nInclude detailed @description for all properties.\nFor methods, include @description and @summary tags as defined for the target. also document every argument, including its type definition, and return type, referencing @template tags when necessary.\ncreate mermaid sequence diagrams under the @mermaid tag;\n\nThe order of tags (when applicable) should be as follows:\n1 - @description;\n2 - @summary;\n3 - @template;\n4 - @param including type definitions;\n5 - @return;\n6 - @function followed by the interface or type name;\n7 - @mermaid with the sequence diagram for the function if it has over 10 lines\n8 - @category one of: "Decorators", "Class Decorators", "Method Decorators", "Property Decorators", "Parameter Decorators"\nOutput only the full JSDoc comment block for the function.\nDO NOT refer to the module it belongs with @memberOf\nnever omit or change any code\nif the element is already documented, only restructure, correct, or add to the documentation. NEVER remove existing information\n${F}`}}]})),K=l.z.object({}),Y=_.builder.setName("ts.jsdoc.enum").setTitle("Enum JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript enum according to a curated template and prompt.").setArgsSchema(K).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\n${L}\n${F}`}}]})),Q=l.z.object({}),X=_.builder.setName("ts.jsdoc.function").setTitle("Function JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript function according to a curated template and prompt.").setArgsSchema(Q).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\ndocument the target code, always including the @description tag with a short description of the target, and a@summary tag with a more detailed one.\nInclude @function an @template tags when appropriate.\nInclude detailed @description for all properties.\nFor methods, include @description and @summary tags as defined for the target. also document every argument, including its type definition, and return type, referencing @template tags when necessary.\ncreate mermaid sequence diagrams under the @mermaid tag;\n\nThe order of tags (when applicable) should be as follows:\n1 - @description;\n2 - @summary;\n3 - @template;\n4 - @param including type definitions;\n5 - @return;\n6 - @function followed by the interface or type name;\n7 - @mermaid with the sequence diagram for the function if ithas over 10 lines\n8 - @memberOf referencing the appropriate module using the appropriate syntax\n\nOutput only the full JSDoc comment block for the function.\nrefer to the module it belongs with @memberOf this the \`@memberOf module:<module_name>\` syntax\nnever omit or change any code\nif the element is already documented, only restructure, correct, or add to the documentation. NEVER remove existing information\n${F}`}}]})),Z=l.z.object({}),ee=_.builder.setName("ts.jsdoc.interface").setTitle("Interface JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript interface according to a curated template and prompt.").setArgsSchema(Z).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\n${M}\n${F}`}}]})),te=l.z.object({}),re=_.builder.setName("ts.jsdoc.type").setTitle("Type JSDocs Prompt").setDescription("Generate JSDoc comments for a TypeScript type according to a curated template and prompt.").setArgsSchema(te).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:`${J}\n${M}\n${F}`}}]})),ne=l.z.object({className:l.z.string().describe("the class name to turn into a builder")}),oe=_.builder.setName("ts.code.dp.builder").setTitle("Typescript builder design patter prompt").setDescription("for a class, with a defined set of properties, scafold a builder design pattern").setArgsSchema(ne).setReasoning(b.BASIC).setCb((e,t)=>(e.className=n.toPascalCase(e.className),{messages:[{role:"user",content:{type:"text",text:`You're a senior TypeScript developer writing typescript code.You're a senior TypeScript developer writing typescript code.\nTransform the selected class into a builder design pattern implementation in Typescript.\nuse @decaf-ts validation decorators to enforce the validation of your builder.\n\n- must extend the Model Class from @decaf-ts/decorator-validation;\n- each property must be marked as protected;\n- each property must have a setter method that returns 'this' for chaining;\n- the build() method must validate the properties using hasErrors() method from Model class;\n- if validation fails, throw an error with the validation errors;\n- if validation passes, return an instance of the original class with the set properties;\n- optionally (but do so by default) add the static builder and from methods from the example;\n- if the clasee already follows the pattern but has properties without decoration or without setters, simple add them;\n\nexample:\n\noriginal class:\n\`\`\`typescript\nexport class ${e.className} {\n description!: string;\n name!: string = "default name";\n title!: string;\n age?: string;\n dateOfBirth!: Date;\n}}\n\`\`\` \n\nresulting builder pattern implementation:\n\`\`\`typescript\nexport class ${e.className}Builder extends Model {\n\n @minlength(10\n @required()\n protected description!: string;\n \n @required()\n protected name!: string = "default value;\n \n @required()\n protected title!: string;\n \n @min(18)\n protected age?: string;\n \n @date()\n protected dateOfBirth!: Date;\n\n protected constructor(arg?: ModelArg<${e.className}Builder>>) {\n super(arg);\n Model.fromModel(this, arg);\n }\n\n setDescription(value: string) {\n this.description = value;\n return this;\n }\n\n setName(value: string) {\n this.name = value;\n return this;\n }\n\n setTitle(value: string) {\n this.title = value;\n return this;\n }\n setAge(value: number) {\n this.age = value;\n return this;\n }\n setDate(value: Date) {\n this.age = value;\n return this;\n }\n \n build(...args: any[]): ${e.className}Builder | Promise<${e.className}Builder> {\n const errs = this.hasErrors();\n if (errs) throw new Error(errs.toString());\n \n return // code that builds OBJ here\n }\n \n static get builder(): ${e.className}Builder {\n return new ${e.className}Builder(); // static method to get a new builder instance\n }\n \n static from<K extends keyof ${e.className}Builder>(obj: K, ${e.className}Builder[K]): ${e.className}Builder {\n return new ${e.className}Builder(); // static method to create a builder from an object\n }\n}\n\`\`\` \n\n`}}],_meta:{}})),se=l.z.object({text:l.z.string().optional()}),ie=_.builder.setName("example.prompt.echo").setTitle("Example: Echo Prompt").setDescription("Returns a short prompt containing the provided `text` as a user message.").setArgsSchema(se).setReasoning(b.BASIC).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:e?.text??"(no text provided)"}}],_meta:{}})),ae=l.z.object({code:l.z.string().optional(),astObject:l.z.any().optional()}),ce=[B,U,W,Y,X,ee,re,oe,ie,_.builder.setName("interactive.jsdoc.assistant").setTitle("Interactive JSDoc Assistant").setDescription("Produce a ready-to-insert JSDoc block for a provided code snippet or AST object.").setArgsSchema(ae).setReasoning(b.BASIC).setCb((e,t)=>({messages:[{role:"user",content:{type:"text",text:"Generate a complete JSDoc comment block for the following code. Respond only with the full JSDoc block.\n\n"+(e?.code??"")}}],_meta:{}}))],de=[E.builder.setName("example.resource.hello").setTitle("Example: Hello Resource").setDescription("A tiny example resource that returns a simple payload for any URI.").setUriOtTemplate("example://hello/{name}").setConfig({description:"Example resource",_meta:{usage:{reasoning:b.NONE,effort:S.NONE,cost:v.FREE}}}).setCb(async(e,t)=>({content:{type:"text",text:"hello from example resource"},_meta:{}})),E.builder.setName("repo.metadata").setTitle("Repository Metadata Resource").setDescription("Expose basic repository metadata such as package.json and lint rules.").setUriOtTemplate("repo://metadata/{file}").setConfig({description:"Repository metadata resource",_meta:{usage:{reasoning:b.NONE,effort:S.NONE,cost:v.FREE}}}).setCb(async(e,t)=>{const r=e.pathname.replace(/^\//,"")||"package.json";try{const e=c.resolve(process.cwd(),r),t=await u.readFile(e,{encoding:"utf8"}),n=JSON.parse(t);return{content:{type:"json",data:JSON.stringify(n)},_meta:{}}}catch(e){return{content:{type:"text",text:""},_meta:{}}}})],le="##VERSION##",me="##PACKAGE##";f.Metadata.registerLibrary(me,le);const ue={mcpId:me,name:"Official Decaf-TS MCP Server",title:"Official Decaf-TS MCP Server",description:"Provides precise coding assistance for the decaf-ts framework",version:le,websiteUrl:"https://decaf-ts.github.io",repositoryUrl:"https://github.com/decaf-ts",license:"AGPL-3.0",contacts:[{name:"Decaf-TS",url:"https://decaf-ts.github.io"}],tags:"server,official,decaf-ts",metadata:{},icons:[{src:"workdocs/assets/favicon.svg",mimeType:"image/svg+xml",sizes:"any"}]},pe=n.LoggedEnvironment.accumulate(ue);class he extends n.LoggedClass{get client(){if(!this._mcp)throw Error("Mcp server requires Mcp client");return this._mcp}constructor(){super()}async load(){try{const e=await Promise.all(de.map(e=>e.build(this.client)));this.log.verbose(`Loaded ${e.length} resources`);const t=await Promise.all(ce.map(e=>e.build(this.client)));this.log.verbose(`Loaded ${t.length} prompts`);const r=await Promise.all(q.map(e=>e.build(this.client)));this.log.verbose(`Loaded ${r.length} tools`);try{const e=await Promise.resolve().then(()=>z),t=Object.values(e).filter(e=>e&&"function"==typeof e.build).filter(e=>!q.includes(e));if(t.length>0){const e=await Promise.all(t.map(e=>e.build(this.client)));this.log.verbose(`Loaded ${e.length} exported builders from tools module`)}}catch(e){this.log.verbose("No additional exported builders loaded from tools module: "+e)}}catch(e){throw this.log.error("Error loading core MCP components",e),e}}async boot(e="stdio"){const t=this.log;this.log.for(this.boot).info("McpServer booting..."),((e=n.Logging.get())=>{let t;try{t=(()=>{let e,t=__dirname;try{for(;t&&t!==w.default.parse(t).root;){const r=w.default.join(t,"node_modules");if(x.default.existsSync(r)&&x.default.statSync(r).isDirectory()){e=r;break}const n=w.default.dirname(t);if(n===t)break;t=n}}catch{}const r=[];if(e){const t=w.default.join(e,"@decaf-ts");try{if(x.default.existsSync(t)&&x.default.statSync(t).isDirectory()){const e=x.default.readdirSync(t);for(const n of e){const e=w.default.join(t,n);try{const t=w.default.join(e,"workdocs","assets","slogans.json");if(x.default.existsSync(t)&&x.default.statSync(t).isFile()){const e=x.default.readFileSync(t,"utf-8"),n=JSON.parse(e);if(Array.isArray(n))for(const e of n)"string"==typeof e&&e.trim().length>0&&r.push(e.trim())}}catch{}}}}catch{}}return 0===r.length?"Decaf: strongly brewed TypeScript.":r[Math.floor(Math.random()*r.length)]})()}catch{t="Decaf: strongly brewed TypeScript."}const r="# \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"),o=r.reduce((e,t)=>Math.max(e,t.length),0);r.push("# "+t.padStart(o-3)),r.forEach((t,r)=>{const n=D[r%D.length]||"",o=e?e.info.bind(e):(()=>{}).bind();try{o(a.style(t||"").raw(n).text)}catch{o((t||"")+"")}})})(this.log);const r=((Array.isArray(pe.icons)?pe.icons:[pe.icons])||[]).map(e=>{const t="string"==typeof e?.src?e.src:(e?.src??"")+"",r="string"==typeof e?.mimeType?e.mimeType:(e?.mimeType??"")+"";let n=[];return Array.isArray(e?.sizes)?n=e.sizes.map(e=>e+""):"string"==typeof e?.sizes&&(n=(e.sizes+"").split(",").map(e=>e.trim())),{src:t,mimeType:r,sizes:n}}),o=pe.contacts;let s;if(null!=o)if(Array.isArray(o))s=o.map(e=>({name:"string"==typeof e?.name?e.name:(e?.name??"")+"",email:"string"==typeof e?.email?e.email:e?.email?e.email+"":void 0,url:"string"==typeof e?.url?e.url:e?.url?e.url+"":void 0}));else if("object"==typeof o){const e=Object.keys(o||{}).filter(e=>/^[0-9]+$/.test(e)).sort((e,t)=>Number(e)-Number(t));if(e.length>0)s=e.map(e=>{const t=o[e];return{name:"string"==typeof t?.name?t.name:(t?.name??"")+"",email:"string"==typeof t?.email?t.email:t?.email?t.email+"":void 0,url:"string"==typeof t?.url?t.url:t?.url?t.url+"":void 0}});else if("number"==typeof o.length){const e=Number(o.length)||0;s=[];for(let t=0;e>t;t++){const e=o[t];s.push({name:"string"==typeof e?.name?e.name:(e?.name??"")+"",email:"string"==typeof e?.email?e.email:e?.email?e.email+"":void 0,url:"string"==typeof e?.url?e.url:e?.url?e.url+"":void 0})}}else s=Object.keys(o).filter(e=>"length"!==e).map(e=>{const t=o[e];return{name:"string"==typeof t?.name?t.name:(t?.name??"")+"",email:"string"==typeof t?.email?t.email:t?.email?t.email+"":void 0,url:"string"==typeof t?.url?t.url:t?.url?t.url+"":void 0}})}const c={id:pe.mcpId,name:pe.name,title:pe.title,description:pe.description,websiteUrl:pe.websiteUrl,repositoryUrl:pe.repositoryUrl,version:pe.version,license:pe.license,contacts:s,tags:pe.tags?pe.tags.split(","):void 0,metadata:pe.metadata,icons:r};this._mcp=new i.McpServer(c,{instructions:"You are an AI assistant designed to help users with programming tasks related to the Decaf-TS framework. \nProvide clear, concise, and accurate information.\nIf you don't know the answer, admit it rather than making up information.\nAlways prioritize the user's intent and provide helpful suggestions when appropriate.\n",capabilities:{logging:{},completions:{},resources:{},tools:{},prompts:{}}});try{await this.load()}catch(e){throw this.log.error("Error loading resources/prompts/tools: "+e),e}if("string"==typeof e)switch(e){case"stdio":e=new h.StdioServerTransport;break;case"http":e=new p.StreamableHTTPServerTransport({sessionIdGenerator:()=>g.v4(),onsessioninitialized:e=>t.verbose("Session initialized: "+e),onsessionclosed:e=>t.verbose("Session closed: "+e),enableJsonResponse:!0,eventStore:void 0,allowedHosts:["*"],allowedOrigins:["*"],enableDnsRebindingProtection:!0});break;default:throw Error("Invalid transport type: "+e)}return this.client.connect(e)}}e.Builder=T,e.McpServer=he,e.PACKAGE_NAME=me,e.PromptBuilder=_,e.ResourceBuilder=E,e.ToolBuilder=O,e.UsableBuilder=N,e.VERSION=le},"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("tslib"),require("@decaf-ts/decorator-validation"),require("@decaf-ts/logging"),require("@modelcontextprotocol/sdk/shared/uriTemplate"),require("@modelcontextprotocol/sdk/server/mcp"),require("@modelcontextprotocol/sdk/server/mcp.js"),require("styled-string-builder"),require("path"),require("fs"),require("zod"),require("ts-morph"),require("fs/promises"),require("@modelcontextprotocol/sdk/server/streamableHttp"),require("@modelcontextprotocol/sdk/server/stdio"),require("uuid"),require("@decaf-ts/decoration")):"function"==typeof define&&define.amd?define(["exports","tslib","@decaf-ts/decorator-validation","@decaf-ts/logging","@modelcontextprotocol/sdk/shared/uriTemplate","@modelcontextprotocol/sdk/server/mcp","@modelcontextprotocol/sdk/server/mcp.js","styled-string-builder","path","fs","zod","ts-morph","fs/promises","@modelcontextprotocol/sdk/server/streamableHttp","@modelcontextprotocol/sdk/server/stdio","uuid","@decaf-ts/decoration"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["mcp-server"]={},e.tslib,e.decafTsDecoratorValidation,e.decafTsLogging,e.uriTemplate,e.mcp,e.mcp_js,e.styledStringBuilder,e.path,e.fs,e.zod,e.tsMorph,e.fsPromises,e.streamableHttp,e.stdio,e.uuid,e.decafTsDecoration);
|
|
2
|
+
//# sourceMappingURL=mcp-server.cjs.map
|