@codeperfect/eslint-plugin 2.0.0 → 2.2.0
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/README.md +3 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/application/custom-rules.d.ts +8 -8
- package/dist/application/custom-rules.js +14 -14
- package/dist/application/index.d.ts +1 -1
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +2 -2
- package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
- package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts +3 -4
- package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.js +5 -3
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-listeners.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-listeners.js +17 -7
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.js +36 -4
- package/dist/domain/architecture/consistent-barrel-files/index.d.ts +2 -0
- package/dist/domain/architecture/consistent-barrel-files/index.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/index.js +3 -1
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts +5 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts.map +1 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.js +247 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts +5 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts.map +1 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.js +136 -0
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.js +8 -3
- package/dist/domain/architecture/consistent-barrel-files/rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/rule.js +12 -5
- package/dist/domain/architecture/index.d.ts +2 -1
- package/dist/domain/architecture/index.d.ts.map +1 -1
- package/dist/domain/architecture/index.js +3 -2
- package/dist/domain/architecture/no-unused-exports/index.d.ts +3 -0
- package/dist/domain/architecture/no-unused-exports/index.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/index.js +2 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-options.d.ts +50 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-options.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-options.js +141 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts +49 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.js +608 -0
- package/dist/domain/architecture/no-unused-exports/rule.d.ts +5 -0
- package/dist/domain/architecture/no-unused-exports/rule.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/rule.js +82 -0
- package/dist/domain/architecture/no-unused-exports/types.d.ts +32 -0
- package/dist/domain/architecture/no-unused-exports/types.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/types.js +2 -0
- package/dist/domain/core/no-multiple-declarators/rule.d.ts.map +1 -1
- package/dist/domain/core/no-multiple-declarators/rule.js +58 -6
- package/dist/domain/core/no-multiple-declarators/types.d.ts +3 -1
- package/dist/domain/core/no-multiple-declarators/types.d.ts.map +1 -1
- package/dist/domain/core/no-multiple-declarators/types.js +5 -2
- package/dist/domain/core/prefer-interface-types/rule.d.ts.map +1 -1
- package/dist/domain/core/prefer-interface-types/rule.js +94 -23
- package/dist/domain/custom-rule-documentation.d.ts +3 -14
- package/dist/domain/custom-rule-documentation.d.ts.map +1 -1
- package/dist/domain/custom-rule-documentation.js +3 -2
- package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +11 -2
- package/dist/domain/docs/no-interface-member-docs/parameter-tags.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +1 -1
- package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +1 -1
- package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/rule.js +12 -4
- package/dist/domain/docs/require-example-language/examples.d.ts +4 -15
- package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/examples.js +119 -26
- package/dist/domain/docs/require-example-language/fixes.d.ts +1 -21
- package/dist/domain/docs/require-example-language/fixes.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/fixes.js +5 -2
- package/dist/domain/docs/require-example-language/reporting.d.ts +2 -38
- package/dist/domain/docs/require-example-language/reporting.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/reporting.js +2 -2
- package/dist/domain/docs/require-example-language/rule.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/rule.js +7 -3
- package/dist/domain/docs/require-example-language/types.d.ts +1 -1
- package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/types.js +1 -1
- package/dist/domain/docs/single-line-jsdoc/rule.d.ts +1 -2
- package/dist/domain/docs/single-line-jsdoc/rule.d.ts.map +1 -1
- package/dist/domain/docs/single-line-jsdoc/rule.js +18 -13
- package/dist/domain/index.d.ts +2 -3
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +3 -4
- package/dist/domain/testing/aaa/analyzer.analysis.d.ts +2 -78
- package/dist/domain/testing/aaa/analyzer.analysis.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts +121 -3
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.js +199 -4
- package/dist/domain/testing/aaa/analyzer.analysis.js +30 -188
- package/dist/domain/testing/aaa/analyzer.assertions.d.ts +1 -92
- package/dist/domain/testing/aaa/analyzer.assertions.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts +93 -0
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.js +184 -0
- package/dist/domain/testing/aaa/analyzer.assertions.js +5 -283
- package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts +62 -0
- package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.assertions.operands.js +106 -0
- package/dist/domain/testing/aaa/analyzer.classification.d.ts +1 -74
- package/dist/domain/testing/aaa/analyzer.classification.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.classification.helpers.d.ts +75 -0
- package/dist/domain/testing/aaa/analyzer.classification.helpers.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.classification.helpers.js +202 -0
- package/dist/domain/testing/aaa/analyzer.classification.js +5 -201
- package/dist/domain/testing/aaa/analyzer.classification.traversal.d.ts +13 -0
- package/dist/domain/testing/aaa/analyzer.classification.traversal.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.classification.traversal.js +32 -0
- package/dist/domain/testing/aaa/analyzer.super.d.ts +6 -13
- package/dist/domain/testing/aaa/analyzer.super.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.super.helpers.d.ts +14 -0
- package/dist/domain/testing/aaa/analyzer.super.helpers.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.super.helpers.js +64 -0
- package/dist/domain/testing/aaa/analyzer.super.js +29 -61
- package/dist/domain/testing/aaa/index.d.ts +1 -2
- package/dist/domain/testing/aaa/index.d.ts.map +1 -1
- package/dist/domain/testing/aaa/index.js +2 -2
- package/dist/domain/testing/aaa/types.d.ts +1 -1
- package/dist/domain/testing/aaa/types.d.ts.map +1 -1
- package/dist/domain/testing/aaa/types.js +1 -1
- package/dist/domain/testing/assert-actual-expected-names/rule.d.ts.map +1 -1
- package/dist/domain/testing/assert-actual-expected-names/rule.js +33 -5
- package/dist/domain/testing/enforce-aaa-phase-purity/index.d.ts +2 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/index.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/index.js +3 -2
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-identifiers.d.ts +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-identifiers.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-identifiers.js +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.js +78 -16
- package/dist/domain/testing/{require-aaa-sections → enforce-aaa-structure}/missing-section-fixes.d.ts +1 -1
- package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.d.ts.map +1 -0
- package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.js +150 -0
- package/dist/domain/testing/enforce-aaa-structure/rule.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-structure/rule.js +165 -3
- package/dist/domain/testing/index.d.ts +0 -3
- package/dist/domain/testing/index.d.ts.map +1 -1
- package/dist/domain/testing/index.js +1 -4
- package/dist/domain/testing/prefer-vi-mocked-import/fix-import-statements.d.ts +1 -15
- package/dist/domain/testing/prefer-vi-mocked-import/fix-import-statements.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/fix-import-statements.js +2 -71
- package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.js +4 -2
- package/dist/domain/testing/prefer-vi-mocked-import/fix.d.ts +1 -13
- package/dist/domain/testing/prefer-vi-mocked-import/fix.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/fix.js +3 -21
- package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.js +2 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.js +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.js +6 -6
- package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts +1 -12
- package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match.js +149 -15
- package/dist/domain/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/rule.js +6 -3
- package/dist/domain/testing/require-act-result-capture/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-act-result-capture/rule.js +42 -10
- package/dist/domain/testing/require-test-companion/index.d.ts +0 -1
- package/dist/domain/testing/require-test-companion/index.d.ts.map +1 -1
- package/dist/domain/testing/require-test-companion/index.js +1 -2
- package/dist/domain/testing/require-test-companion/require-test-companion-listeners.d.ts +2 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-listeners.d.ts.map +1 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-listeners.js +13 -58
- package/dist/domain/testing/require-test-companion/require-test-companion-options.d.ts +2 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-options.d.ts.map +1 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-options.js +6 -5
- package/dist/domain/testing/require-test-companion/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-test-companion/rule.js +34 -9
- package/dist/domain/testing/single-act-statement/rule.d.ts.map +1 -1
- package/dist/domain/testing/single-act-statement/rule.js +11 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/infrastructure/codeperfect-plugin.d.ts +6 -6
- package/dist/infrastructure/codeperfect-plugin.js +5 -5
- package/dist/infrastructure/presets.d.ts.map +1 -1
- package/dist/infrastructure/presets.js +23 -7
- package/package.json +37 -38
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule-test-utilities.d.ts +0 -41
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule-test-utilities.d.ts.map +0 -1
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule-test-utilities.js +0 -87
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.d.ts +0 -40
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.d.ts.map +0 -1
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.js +0 -91
- package/dist/domain/architecture/consistent-barrel-files/rule.repeat-runs.d.ts +0 -4
- package/dist/domain/architecture/consistent-barrel-files/rule.repeat-runs.d.ts.map +0 -1
- package/dist/domain/architecture/consistent-barrel-files/rule.repeat-runs.js +0 -4
- package/dist/domain/architecture/consistent-barrel-files/test-helpers.d.ts +0 -141
- package/dist/domain/architecture/consistent-barrel-files/test-helpers.d.ts.map +0 -1
- package/dist/domain/architecture/consistent-barrel-files/test-helpers.file-writers.d.ts +0 -20
- package/dist/domain/architecture/consistent-barrel-files/test-helpers.file-writers.d.ts.map +0 -1
- package/dist/domain/architecture/consistent-barrel-files/test-helpers.file-writers.js +0 -25
- package/dist/domain/architecture/consistent-barrel-files/test-helpers.js +0 -235
- package/dist/domain/core/no-multiple-declarators/rule-test-helpers.d.ts +0 -101
- package/dist/domain/core/no-multiple-declarators/rule-test-helpers.d.ts.map +0 -1
- package/dist/domain/core/no-multiple-declarators/rule-test-helpers.js +0 -108
- package/dist/domain/core/no-multiple-declarators/rule.fixes.d.ts +0 -35
- package/dist/domain/core/no-multiple-declarators/rule.fixes.d.ts.map +0 -1
- package/dist/domain/core/no-multiple-declarators/rule.fixes.js +0 -95
- package/dist/domain/core/no-multiple-declarators/rule.guardrails.d.ts +0 -4
- package/dist/domain/core/no-multiple-declarators/rule.guardrails.d.ts.map +0 -1
- package/dist/domain/core/no-multiple-declarators/rule.guardrails.js +0 -4
- package/dist/domain/core/no-multiple-declarators/rule.mocked-types.d.ts +0 -4
- package/dist/domain/core/no-multiple-declarators/rule.mocked-types.d.ts.map +0 -1
- package/dist/domain/core/no-multiple-declarators/rule.mocked-types.js +0 -4
- package/dist/domain/core/prefer-interface-types/test-helpers.d.ts +0 -110
- package/dist/domain/core/prefer-interface-types/test-helpers.d.ts.map +0 -1
- package/dist/domain/core/prefer-interface-types/test-helpers.js +0 -116
- package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts +0 -89
- package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts.map +0 -1
- package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.js +0 -129
- package/dist/domain/docs/no-interface-member-docs/test-helpers.d.ts +0 -103
- package/dist/domain/docs/no-interface-member-docs/test-helpers.d.ts.map +0 -1
- package/dist/domain/docs/no-interface-member-docs/test-helpers.js +0 -157
- package/dist/domain/docs/require-example-language/create-fixer.d.ts +0 -5
- package/dist/domain/docs/require-example-language/create-fixer.d.ts.map +0 -1
- package/dist/domain/docs/require-example-language/create-fixer.js +0 -5
- package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.d.ts +0 -4
- package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.d.ts.map +0 -1
- package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.js +0 -5
- package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.d.ts +0 -4
- package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.d.ts.map +0 -1
- package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.js +0 -5
- package/dist/domain/docs/test-helpers.d.ts +0 -50
- package/dist/domain/docs/test-helpers.d.ts.map +0 -1
- package/dist/domain/docs/test-helpers.js +0 -107
- package/dist/domain/testing/aaa/analyzer.classification.member-patterns.d.ts +0 -9
- package/dist/domain/testing/aaa/analyzer.classification.member-patterns.d.ts.map +0 -1
- package/dist/domain/testing/aaa/analyzer.classification.member-patterns.js +0 -10
- package/dist/domain/testing/aaa/analyzer.d.ts +0 -46
- package/dist/domain/testing/aaa/analyzer.d.ts.map +0 -1
- package/dist/domain/testing/aaa/analyzer.js +0 -59
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.d.ts +0 -4
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.d.ts.map +0 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.js +0 -4
- package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.d.ts +0 -42
- package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.d.ts.map +0 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.js +0 -188
- package/dist/domain/testing/enforce-aaa-phase-purity/rule.d.ts +0 -5
- package/dist/domain/testing/enforce-aaa-phase-purity/rule.d.ts.map +0 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/rule.js +0 -34
- package/dist/domain/testing/prefer-vi-mocked-import/rule-test-helpers.d.ts +0 -20
- package/dist/domain/testing/prefer-vi-mocked-import/rule-test-helpers.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vi-mocked-import/rule-test-helpers.js +0 -39
- package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.d.ts +0 -86
- package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.js +0 -150
- package/dist/domain/testing/prefer-vitest-incremental-casts/index.d.ts +0 -2
- package/dist/domain/testing/prefer-vitest-incremental-casts/index.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/index.js +0 -2
- package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.d.ts +0 -14
- package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.js +0 -81
- package/dist/domain/testing/prefer-vitest-incremental-casts/match.d.ts +0 -13
- package/dist/domain/testing/prefer-vitest-incremental-casts/match.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/match.js +0 -189
- package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.d.ts +0 -25
- package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.js +0 -92
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule-test-helpers.d.ts +0 -32
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule-test-helpers.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule-test-helpers.js +0 -164
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.d.ts +0 -5
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.guardrails.d.ts +0 -4
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.guardrails.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.guardrails.js +0 -4
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.input-shapes.d.ts +0 -4
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.input-shapes.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.input-shapes.js +0 -4
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.js +0 -62
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.signature-fallback.d.ts +0 -4
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.signature-fallback.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.signature-fallback.js +0 -4
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.d.ts +0 -24
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.js +0 -113
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-shape-helpers.d.ts +0 -36
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-shape-helpers.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-shape-helpers.js +0 -138
- package/dist/domain/testing/prefer-vitest-incremental-casts/types.d.ts +0 -203
- package/dist/domain/testing/prefer-vitest-incremental-casts/types.d.ts.map +0 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/types.js +0 -2
- package/dist/domain/testing/require-aaa-sections/index.d.ts +0 -2
- package/dist/domain/testing/require-aaa-sections/index.d.ts.map +0 -1
- package/dist/domain/testing/require-aaa-sections/index.js +0 -2
- package/dist/domain/testing/require-aaa-sections/missing-section-fixes.d.ts.map +0 -1
- package/dist/domain/testing/require-aaa-sections/missing-section-fixes.js +0 -150
- package/dist/domain/testing/require-aaa-sections/rule.d.ts +0 -5
- package/dist/domain/testing/require-aaa-sections/rule.d.ts.map +0 -1
- package/dist/domain/testing/require-aaa-sections/rule.js +0 -129
- package/dist/domain/testing/require-aaa-sections/rule.reporting.d.ts +0 -104
- package/dist/domain/testing/require-aaa-sections/rule.reporting.d.ts.map +0 -1
- package/dist/domain/testing/require-aaa-sections/rule.reporting.js +0 -217
- package/dist/domain/testing/require-test-companion/require-test-companion-test-helpers.d.ts +0 -51
- package/dist/domain/testing/require-test-companion/require-test-companion-test-helpers.d.ts.map +0 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-test-helpers.js +0 -184
- package/dist/domain/testing/require-test-companion/require-test-companion-utilities.d.ts +0 -28
- package/dist/domain/testing/require-test-companion/require-test-companion-utilities.d.ts.map +0 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-utilities.js +0 -26
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import * as ts from "typescript";
|
|
4
|
+
import { isPublicApiFile, isTestFile } from "./no-unused-exports-options.js";
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes an absolute file path for safe equality checks.
|
|
7
|
+
* @param inputPath Candidate path.
|
|
8
|
+
* @returns Normalized absolute path suitable for cross-platform comparisons.
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const comparable = toComparableAbsolutePath("/repo/src/feature.ts");
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
const toComparableAbsolutePath = (inputPath) => {
|
|
15
|
+
const absolutePath = path.normalize(path.resolve(inputPath));
|
|
16
|
+
return absolutePath.toLowerCase();
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Converts one unknown value into an indexable record.
|
|
20
|
+
* @param value Candidate value.
|
|
21
|
+
* @returns Record view when the value is object-like.
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const record = asRecord({ type: "Identifier" });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
const asRecord = (value) => value !== null && typeof value === "object"
|
|
28
|
+
? value
|
|
29
|
+
: void 0;
|
|
30
|
+
/**
|
|
31
|
+
* Reads one string property from an object-like value.
|
|
32
|
+
* @param value Candidate object.
|
|
33
|
+
* @param key Lookup key used to read the property.
|
|
34
|
+
* @returns String value when present.
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const name = readStringProperty({ name: "feature" }, "name");
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
const readStringProperty = (value, key) => {
|
|
41
|
+
const record = asRecord(value);
|
|
42
|
+
const property = record?.[key];
|
|
43
|
+
return typeof property === "string" ? property : void 0;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Reads one array property from an object-like value.
|
|
47
|
+
* @param value Candidate object.
|
|
48
|
+
* @param key Lookup key used to read the property.
|
|
49
|
+
* @returns Array value when present.
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const items = readArrayProperty({ elements: [1, 2] }, "elements");
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
const readArrayProperty = (value, key) => {
|
|
56
|
+
const record = asRecord(value);
|
|
57
|
+
const property = record?.[key];
|
|
58
|
+
return Array.isArray(property) ? property : void 0;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Resolves TypeScript parser services program when available.
|
|
62
|
+
* @param context Rule context.
|
|
63
|
+
* @returns TypeScript program when available.
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const program = getTypeScriptProgram(context);
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
const getTypeScriptProgram = (context) => {
|
|
70
|
+
try {
|
|
71
|
+
const services = ESLintUtils.getParserServices(context);
|
|
72
|
+
return services.program;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Collects identifier names from one variable pattern.
|
|
80
|
+
* @param node Variable pattern candidate.
|
|
81
|
+
* @returns Identifier names declared by the pattern.
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const names = collectPatternIdentifierNames(pattern);
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
const collectPatternIdentifierNames = (node) => {
|
|
88
|
+
const pattern = asRecord(node);
|
|
89
|
+
if (pattern === void 0) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
const patternType = readStringProperty(pattern, "type");
|
|
93
|
+
if (patternType === "Identifier") {
|
|
94
|
+
const name = readStringProperty(pattern, "name");
|
|
95
|
+
return name === void 0 ? [] : [name];
|
|
96
|
+
}
|
|
97
|
+
if (patternType === "RestElement") {
|
|
98
|
+
return collectPatternIdentifierNames(pattern["argument"]);
|
|
99
|
+
}
|
|
100
|
+
if (patternType === "AssignmentPattern") {
|
|
101
|
+
return collectPatternIdentifierNames(pattern["left"]);
|
|
102
|
+
}
|
|
103
|
+
if (patternType === "ArrayPattern") {
|
|
104
|
+
return (readArrayProperty(pattern, "elements") ?? []).flatMap((element) => collectPatternIdentifierNames(element));
|
|
105
|
+
}
|
|
106
|
+
if (patternType === "ObjectPattern") {
|
|
107
|
+
return (readArrayProperty(pattern, "properties") ?? []).flatMap((property) => {
|
|
108
|
+
if (readStringProperty(property, "type") === "RestElement") {
|
|
109
|
+
return collectPatternIdentifierNames(asRecord(property)?.["argument"]);
|
|
110
|
+
}
|
|
111
|
+
return collectPatternIdentifierNames(asRecord(property)?.["value"]);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return [];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Reads one export specifier name.
|
|
118
|
+
* @param specifier Export specifier candidate.
|
|
119
|
+
* @returns Exported name when available.
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const name = getExportSpecifierName(specifier);
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
const getExportSpecifierName = (specifier) => {
|
|
126
|
+
const candidate = asRecord(specifier);
|
|
127
|
+
const exportedName = readStringProperty(candidate?.["exported"], "name");
|
|
128
|
+
if (typeof exportedName === "string") {
|
|
129
|
+
return exportedName;
|
|
130
|
+
}
|
|
131
|
+
const localName = readStringProperty(candidate?.["local"], "name");
|
|
132
|
+
return typeof localName === "string" ? localName : void 0;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Reads one local export specifier name.
|
|
136
|
+
* @param specifier Export specifier candidate.
|
|
137
|
+
* @returns Local specifier name when available.
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const name = getExportSpecifierLocalName(specifier);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
const getExportSpecifierLocalName = (specifier) => {
|
|
144
|
+
const candidate = asRecord(specifier);
|
|
145
|
+
return readStringProperty(candidate?.["local"], "name");
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Collects top-level declaration names owned by the current module.
|
|
149
|
+
* @param body Program body statements.
|
|
150
|
+
* @returns Map from locally declared name to its declaration metadata.
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const declarations = collectLocalDeclarationNames(program.body);
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
const collectLocalDeclarationNames = (body) => {
|
|
157
|
+
const declarationNames = new Map();
|
|
158
|
+
for (const statement of body) {
|
|
159
|
+
const declarationCandidate = statement.type === "ExportNamedDeclaration" &&
|
|
160
|
+
statement.declaration !== null &&
|
|
161
|
+
statement.declaration !== void 0
|
|
162
|
+
? statement.declaration
|
|
163
|
+
: statement;
|
|
164
|
+
const declarationCandidateRecord = asRecord(declarationCandidate);
|
|
165
|
+
const declarationCandidateType = readStringProperty(declarationCandidate, "type");
|
|
166
|
+
if (declarationCandidateRecord === void 0 ||
|
|
167
|
+
declarationCandidateType === void 0) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (declarationCandidateType === "FunctionDeclaration" ||
|
|
171
|
+
declarationCandidateType === "ClassDeclaration" ||
|
|
172
|
+
declarationCandidateType === "TSEnumDeclaration" ||
|
|
173
|
+
declarationCandidateType === "TSInterfaceDeclaration" ||
|
|
174
|
+
declarationCandidateType === "TSTypeAliasDeclaration") {
|
|
175
|
+
const declarationName = readStringProperty(declarationCandidateRecord["id"], "name");
|
|
176
|
+
if (declarationName !== void 0) {
|
|
177
|
+
declarationNames.set(declarationName, {
|
|
178
|
+
kind: declarationCandidateType === "TSInterfaceDeclaration" ||
|
|
179
|
+
declarationCandidateType === "TSTypeAliasDeclaration"
|
|
180
|
+
? "type"
|
|
181
|
+
: "value",
|
|
182
|
+
node: statement,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (declarationCandidateType !== "VariableDeclaration") {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const declarations = readArrayProperty(declarationCandidateRecord, "declarations");
|
|
191
|
+
if (declarations === void 0) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
for (const declaration of declarations) {
|
|
195
|
+
const declarationRecord = asRecord(declaration);
|
|
196
|
+
if (declarationRecord === void 0) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
for (const name of collectPatternIdentifierNames(declarationRecord["id"])) {
|
|
200
|
+
declarationNames.set(name, { kind: "value", node: statement });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return declarationNames;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* Collects exported elements from one program body.
|
|
208
|
+
* @param body Program body statements.
|
|
209
|
+
* @returns Exported elements in declaration order.
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const exported = collectExportedElements(program.body);
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
const collectExportedElements = (body) => {
|
|
216
|
+
const exportedElements = [];
|
|
217
|
+
const localDeclarationNames = collectLocalDeclarationNames(body);
|
|
218
|
+
for (const statement of body) {
|
|
219
|
+
if (statement.type === "ExportDefaultDeclaration") {
|
|
220
|
+
exportedElements.push({
|
|
221
|
+
exportedName: "default",
|
|
222
|
+
exportKind: "value",
|
|
223
|
+
node: statement,
|
|
224
|
+
});
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (statement.type !== "ExportNamedDeclaration") {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (statement.source !== null && statement.source !== void 0) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (statement.declaration !== null && statement.declaration !== void 0) {
|
|
234
|
+
const declaration = asRecord(statement.declaration);
|
|
235
|
+
if (readStringProperty(declaration, "type") === "VariableDeclaration") {
|
|
236
|
+
for (const variable of readArrayProperty(declaration, "declarations") ??
|
|
237
|
+
[]) {
|
|
238
|
+
for (const name of collectPatternIdentifierNames(asRecord(variable)?.["id"])) {
|
|
239
|
+
exportedElements.push({
|
|
240
|
+
exportedName: name,
|
|
241
|
+
exportKind: "value",
|
|
242
|
+
node: statement,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const declarationName = readStringProperty(declaration?.["id"], "name");
|
|
249
|
+
const declarationType = readStringProperty(declaration, "type");
|
|
250
|
+
const exportKind = declarationType === "TSInterfaceDeclaration" ||
|
|
251
|
+
declarationType === "TSTypeAliasDeclaration"
|
|
252
|
+
? "type"
|
|
253
|
+
: "value";
|
|
254
|
+
if (typeof declarationName === "string") {
|
|
255
|
+
exportedElements.push({
|
|
256
|
+
exportedName: declarationName,
|
|
257
|
+
exportKind,
|
|
258
|
+
node: statement,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
for (const specifier of statement.specifiers) {
|
|
265
|
+
const localName = getExportSpecifierLocalName(specifier);
|
|
266
|
+
const localDeclaration = localName === void 0 ? void 0 : localDeclarationNames.get(localName);
|
|
267
|
+
if (localDeclaration === void 0) {
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const exportedName = getExportSpecifierName(specifier);
|
|
271
|
+
if (exportedName !== void 0) {
|
|
272
|
+
const statementExportKind = readStringProperty(statement, "exportKind");
|
|
273
|
+
const specifierExportKind = readStringProperty(specifier, "exportKind");
|
|
274
|
+
const isTypeOnlyExport = statementExportKind === "type" || specifierExportKind === "type";
|
|
275
|
+
exportedElements.push({
|
|
276
|
+
exportedName,
|
|
277
|
+
exportKind: isTypeOnlyExport ? "type" : localDeclaration.kind,
|
|
278
|
+
node: localDeclaration.node,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return exportedElements;
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Resolves one symbol to its canonical target.
|
|
287
|
+
* @param symbol Candidate symbol.
|
|
288
|
+
* @param checker TypeScript checker.
|
|
289
|
+
* @returns Resolved canonical symbol.
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* const resolved = resolveCanonicalSymbol(symbol, checker);
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
const resolveCanonicalSymbol = (symbol, checker) => {
|
|
296
|
+
if ((symbol.flags & ts.SymbolFlags.Alias) === 0) {
|
|
297
|
+
return symbol;
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
return checker.getAliasedSymbol(symbol);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
return symbol;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* Builds declaration-site keys for symbol identity matching.
|
|
308
|
+
* @param symbol Symbol being compared.
|
|
309
|
+
* @returns Declaration keys describing where this symbol is declared.
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* const keys = getDeclarationKeys(symbol);
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
const getDeclarationKeys = (symbol) => {
|
|
316
|
+
const declarations = symbol.declarations ?? [];
|
|
317
|
+
return new Set(declarations.map((declaration) => {
|
|
318
|
+
const sourceFilename = declaration.getSourceFile().fileName;
|
|
319
|
+
return `${sourceFilename}:${String(declaration.pos)}:${String(declaration.end)}`;
|
|
320
|
+
}));
|
|
321
|
+
};
|
|
322
|
+
/**
|
|
323
|
+
* Checks whether two symbols reference the same declaration site.
|
|
324
|
+
* @param left Left-hand symbol candidate.
|
|
325
|
+
* @param right Right-hand symbol candidate.
|
|
326
|
+
* @returns True when both symbols identify the same declaration.
|
|
327
|
+
* @example
|
|
328
|
+
* ```typescript
|
|
329
|
+
* const same = isSameSymbol(left, right);
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
const isSameSymbol = (left, right) => {
|
|
333
|
+
if (left === right) {
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
const leftKeys = getDeclarationKeys(left);
|
|
337
|
+
const rightKeys = getDeclarationKeys(right);
|
|
338
|
+
for (const key of leftKeys) {
|
|
339
|
+
if (rightKeys.has(key)) {
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return false;
|
|
344
|
+
};
|
|
345
|
+
/**
|
|
346
|
+
* Resolves one exported symbol by name from a source file.
|
|
347
|
+
* @param program TypeScript program.
|
|
348
|
+
* @param sourceFilename Source file path.
|
|
349
|
+
* @param exportedName Public name exposed by the module export list.
|
|
350
|
+
* @returns Symbol when found.
|
|
351
|
+
* @example
|
|
352
|
+
* ```typescript
|
|
353
|
+
* const symbol = getExportedSymbol(program, sourceFilename, "feature");
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
const getExportedSymbol = (program, sourceFilename, exportedName) => {
|
|
357
|
+
const checker = program.getTypeChecker();
|
|
358
|
+
const sourceFile = program
|
|
359
|
+
.getSourceFiles()
|
|
360
|
+
.find((file) => toComparableAbsolutePath(file.fileName) ===
|
|
361
|
+
toComparableAbsolutePath(sourceFilename));
|
|
362
|
+
if (sourceFile === void 0) {
|
|
363
|
+
return void 0;
|
|
364
|
+
}
|
|
365
|
+
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
366
|
+
if (moduleSymbol === void 0) {
|
|
367
|
+
return void 0;
|
|
368
|
+
}
|
|
369
|
+
const exportedSymbol = checker
|
|
370
|
+
.getExportsOfModule(moduleSymbol)
|
|
371
|
+
.find((symbol) => symbol.getName() === exportedName);
|
|
372
|
+
if (exportedSymbol === void 0) {
|
|
373
|
+
return void 0;
|
|
374
|
+
}
|
|
375
|
+
return resolveCanonicalSymbol(exportedSymbol, checker);
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Checks whether one source file exports the target symbol.
|
|
379
|
+
* @param sourceFile Source file that may expose the symbol.
|
|
380
|
+
* @param checker TypeScript checker.
|
|
381
|
+
* @param targetSymbol Symbol being classified.
|
|
382
|
+
* @returns True when one module export resolves to the target symbol.
|
|
383
|
+
* @example
|
|
384
|
+
* ```typescript
|
|
385
|
+
* const exposed = sourceFileExportsSymbol(sourceFile, checker, targetSymbol);
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
const sourceFileExportsSymbol = (sourceFile, checker, targetSymbol) => {
|
|
389
|
+
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
390
|
+
if (moduleSymbol === void 0) {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
for (const exportedSymbol of checker.getExportsOfModule(moduleSymbol)) {
|
|
394
|
+
const resolvedSymbol = resolveCanonicalSymbol(exportedSymbol, checker);
|
|
395
|
+
if (isSameSymbol(resolvedSymbol, targetSymbol)) {
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return false;
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* Checks whether an identifier participates in one declaration/import/export site.
|
|
403
|
+
* @param identifier Identifier node to evaluate.
|
|
404
|
+
* @returns True when the identifier is declaration-only syntax.
|
|
405
|
+
* @example
|
|
406
|
+
* ```typescript
|
|
407
|
+
* const declaration = isDeclarationOnlyIdentifier(identifier);
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
const isDeclarationOnlyIdentifier = (identifier) => {
|
|
411
|
+
const parent = identifier.parent;
|
|
412
|
+
return (ts.isImportSpecifier(parent) ||
|
|
413
|
+
ts.isImportClause(parent) ||
|
|
414
|
+
ts.isNamespaceImport(parent) ||
|
|
415
|
+
ts.isImportEqualsDeclaration(parent) ||
|
|
416
|
+
ts.isExportSpecifier(parent) ||
|
|
417
|
+
ts.isTypeAliasDeclaration(parent) ||
|
|
418
|
+
ts.isInterfaceDeclaration(parent) ||
|
|
419
|
+
ts.isTypeParameterDeclaration(parent) ||
|
|
420
|
+
(ts.isVariableDeclaration(parent) && parent.name === identifier) ||
|
|
421
|
+
(ts.isFunctionDeclaration(parent) && parent.name === identifier) ||
|
|
422
|
+
(ts.isClassDeclaration(parent) && parent.name === identifier) ||
|
|
423
|
+
(ts.isParameter(parent) && parent.name === identifier));
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* Checks whether one identifier node appears under a type node.
|
|
427
|
+
* @param identifier Candidate identifier.
|
|
428
|
+
* @returns True when the identifier is inside type-only syntax.
|
|
429
|
+
* @example
|
|
430
|
+
* ```typescript
|
|
431
|
+
* const typePosition = isTypePositionIdentifier(identifier);
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
const isTypePositionIdentifier = (identifier) => {
|
|
435
|
+
const visitNode = (current) => {
|
|
436
|
+
if (ts.isTypeQueryNode(current)) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
if (ts.isTypeNode(current)) {
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
if (ts.isExpressionStatement(current) ||
|
|
443
|
+
ts.isCallExpression(current) ||
|
|
444
|
+
ts.isPropertyAccessExpression(current) ||
|
|
445
|
+
ts.isElementAccessExpression(current) ||
|
|
446
|
+
ts.isVariableDeclaration(current) ||
|
|
447
|
+
ts.isReturnStatement(current)) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
if (ts.isSourceFile(current)) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
return visitNode(current.parent);
|
|
454
|
+
};
|
|
455
|
+
return visitNode(identifier);
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* Checks whether one identifier is one concrete usage candidate for the export kind.
|
|
459
|
+
* @param identifier Identifier node.
|
|
460
|
+
* @param exportKind Whether type-only or value usage is required.
|
|
461
|
+
* @returns True when the identifier can satisfy usage.
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* const concrete = isConcreteUsageIdentifier(identifier, "value");
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
const isConcreteUsageIdentifier = (identifier, exportKind) => {
|
|
468
|
+
if (isDeclarationOnlyIdentifier(identifier)) {
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
const inTypePosition = isTypePositionIdentifier(identifier);
|
|
472
|
+
return exportKind === "type" ? inTypePosition : !inTypePosition;
|
|
473
|
+
};
|
|
474
|
+
/**
|
|
475
|
+
* Appends concrete usages from one source file into the accumulator.
|
|
476
|
+
* @param sourceFile Source file to scan.
|
|
477
|
+
* @param checker TypeScript checker.
|
|
478
|
+
* @param targetSymbol Export symbol being classified.
|
|
479
|
+
* @param exportedElement Export metadata.
|
|
480
|
+
* @param consumerIsTestFile Whether source file is a test file.
|
|
481
|
+
* @param usages Mutable usage accumulator.
|
|
482
|
+
* @example
|
|
483
|
+
* ```typescript
|
|
484
|
+
* collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbolKey, exportedElement, false, usages);
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
const collectConcreteUsagesFromSourceFile = (sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages) => {
|
|
488
|
+
const visitNode = (node) => {
|
|
489
|
+
if (!ts.isIdentifier(node)) {
|
|
490
|
+
ts.forEachChild(node, visitNode);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if (!isConcreteUsageIdentifier(node, exportedElement.exportKind)) {
|
|
494
|
+
ts.forEachChild(node, visitNode);
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
const candidateSymbol = checker.getSymbolAtLocation(node);
|
|
498
|
+
if (candidateSymbol === void 0) {
|
|
499
|
+
ts.forEachChild(node, visitNode);
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const resolvedSymbol = resolveCanonicalSymbol(candidateSymbol, checker);
|
|
503
|
+
if (!isSameSymbol(resolvedSymbol, targetSymbol)) {
|
|
504
|
+
ts.forEachChild(node, visitNode);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
usages.push({ isTestFile: consumerIsTestFile });
|
|
508
|
+
ts.forEachChild(node, visitNode);
|
|
509
|
+
};
|
|
510
|
+
visitNode(sourceFile);
|
|
511
|
+
};
|
|
512
|
+
/**
|
|
513
|
+
* Collects public API exposure usages for one exported symbol.
|
|
514
|
+
* @param program TypeScript program.
|
|
515
|
+
* @param sourceFilename Source filename where export is defined.
|
|
516
|
+
* @param state Normalized rule options.
|
|
517
|
+
* @param repoRoot Absolute repository root used for file classification.
|
|
518
|
+
* @param targetSymbol Export symbol being classified.
|
|
519
|
+
* @returns Public API exposure usages for the exported symbol.
|
|
520
|
+
* @example
|
|
521
|
+
* ```typescript
|
|
522
|
+
* const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
|
|
523
|
+
* ```
|
|
524
|
+
*/
|
|
525
|
+
const collectPublicApiExposureUsages = (program, sourceFilename, state, repoRoot, targetSymbol) => {
|
|
526
|
+
const checker = program.getTypeChecker();
|
|
527
|
+
const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
|
|
528
|
+
const normalizedRepoRoot = path.resolve(repoRoot);
|
|
529
|
+
const usages = [];
|
|
530
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
531
|
+
if (sourceFile.isDeclarationFile) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
const publicApiFilename = path.resolve(sourceFile.fileName);
|
|
535
|
+
const normalizedPublicApiFilename = toComparableAbsolutePath(publicApiFilename);
|
|
536
|
+
if (normalizedPublicApiFilename === normalizedSourceFilename) {
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
if (!isPublicApiFile(publicApiFilename, state, normalizedRepoRoot)) {
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
if (!sourceFileExportsSymbol(sourceFile, checker, targetSymbol)) {
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
usages.push({
|
|
546
|
+
isTestFile: isTestFile(publicApiFilename, state, normalizedRepoRoot),
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
return usages;
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* Collects concrete usages of one exported element across the program.
|
|
553
|
+
* @param program TypeScript program.
|
|
554
|
+
* @param sourceFilename Source filename where export is defined.
|
|
555
|
+
* @param state Normalized rule options.
|
|
556
|
+
* @param repoRoot Absolute repository root used for test-file classification.
|
|
557
|
+
* @param exportedElement Exported element to classify.
|
|
558
|
+
* @returns Concrete usages for the exported element.
|
|
559
|
+
* @example
|
|
560
|
+
* ```typescript
|
|
561
|
+
* const usages = collectCrossFileUsages(program, "/repo/src/feature.ts", state, "/repo", exportedElement);
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
const collectCrossFileUsages = (program, sourceFilename, state, repoRoot, exportedElement) => {
|
|
565
|
+
const checker = program.getTypeChecker();
|
|
566
|
+
const targetSymbol = getExportedSymbol(program, sourceFilename, exportedElement.exportedName);
|
|
567
|
+
if (targetSymbol === void 0) {
|
|
568
|
+
return [];
|
|
569
|
+
}
|
|
570
|
+
const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
|
|
571
|
+
const normalizedRepoRoot = path.resolve(repoRoot);
|
|
572
|
+
const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
|
|
573
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
574
|
+
if (sourceFile.isDeclarationFile) {
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
const consumerFilename = path.resolve(sourceFile.fileName);
|
|
578
|
+
const normalizedConsumerFilename = toComparableAbsolutePath(consumerFilename);
|
|
579
|
+
if (normalizedConsumerFilename === normalizedSourceFilename) {
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
const consumerIsTestFile = isTestFile(consumerFilename, state, normalizedRepoRoot);
|
|
583
|
+
collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages);
|
|
584
|
+
}
|
|
585
|
+
return usages;
|
|
586
|
+
};
|
|
587
|
+
/**
|
|
588
|
+
* Classifies one exported name based on cross-file usages.
|
|
589
|
+
* @param usages Collected usages.
|
|
590
|
+
* @returns Classification label.
|
|
591
|
+
* @example
|
|
592
|
+
* ```typescript
|
|
593
|
+
* const classification = classifyExportUsage("feature", usages);
|
|
594
|
+
* ```
|
|
595
|
+
*/
|
|
596
|
+
const classifyExportUsage = (usages) => {
|
|
597
|
+
if (usages.length === 0) {
|
|
598
|
+
return "unused";
|
|
599
|
+
}
|
|
600
|
+
for (const usage of usages) {
|
|
601
|
+
if (!usage.isTestFile) {
|
|
602
|
+
return "production";
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return "test-only";
|
|
606
|
+
};
|
|
607
|
+
export { classifyExportUsage, collectCrossFileUsages, collectExportedElements, getTypeScriptProgram, };
|
|
608
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLWV4cG9ydHMvbm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFTakMsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQVcxRTs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxTQUFpQixFQUFVLEVBQUU7SUFDN0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFFN0QsT0FBTyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWMsRUFBdUMsRUFBRSxDQUN2RSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7SUFDekMsQ0FBQyxDQUFFLEtBQWlDO0lBQ3BDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUViOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sa0JBQWtCLEdBQUcsQ0FDekIsS0FBYyxFQUNkLEdBQVcsRUFDUyxFQUFFO0lBQ3RCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixNQUFNLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvQixPQUFPLE9BQU8sUUFBUSxLQUFLLFFB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LFVBQVUsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sWUFBWSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBRUYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixzQkFBc0IsRUFDdEIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixHQUNyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBU1QsIFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5cbmltcG9ydCB7IEVTTGludFV0aWxzIH0gZnJvbSBcIkB0eXBlc2NyaXB0LWVzbGludC91dGlsc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHR5cGUge1xuICBFeHBvcnRlZEVsZW1lbnQsXG4gIEV4cG9ydEtpbmQsXG4gIEV4cG9ydFVzYWdlLFxuICBOb1VudXNlZEV4cG9ydHNTdGF0ZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuaW1wb3J0IHsgaXNQdWJsaWNBcGlGaWxlLCBpc1Rlc3RGaWxlIH0gZnJvbSBcIi4vbm8tdW51c2VkLWV4cG9ydHMtb3B0aW9uc1wiO1xuXG4vKiogTG9jYWwgdG9wLWxldmVsIGRlY2xhcmF0aW9uIGRpc2NvdmVyZWQgd2hlbiBjb2xsZWN0aW5nIGV4cG9ydCBzb3VyY2VzLiAqL1xuaW50ZXJmYWNlIExvY2FsRGVjbGFyYXRpb24ge1xuICAvKiogRXhwb3J0IGtpbmQgaW1wbGllZCBieSB0aGUgZGVjbGFyYXRpb24uICovXG4gIGtpbmQ6IEV4cG9ydEtpbmQ7XG5cbiAgLyoqIERlY2xhcmF0aW9uIHN0YXRlbWVudCB1c2VkIGZvciBkaWFnbm9zdGljcy4gKi9cbiAgbm9kZTogQVNULlByb2dyYW1bXCJib2R5XCJdW251bWJlcl07XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhbiBhYnNvbHV0ZSBmaWxlIHBhdGggZm9yIHNhZmUgZXF1YWxpdHkgY2hlY2tzLlxuICogQHBhcmFtIGlucHV0UGF0aCBDYW5kaWRhdGUgcGF0aC5cbiAqIEByZXR1cm5zIE5vcm1hbGl6ZWQgYWJzb2x1dGUgcGF0aCBzdWl0YWJsZSBmb3IgY3Jvc3MtcGxhdGZvcm0gY29tcGFyaXNvbnMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY29tcGFyYWJsZSA9IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChcIi9yZXBvL3NyYy9mZWF0dXJlLnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aCA9IChpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKHBhdGgucmVzb2x2ZShpbnB1dFBhdGgpKTtcblxuICByZXR1cm4gYWJzb2x1dGVQYXRoLnRvTG93ZXJDYXNlKCk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIG9uZSB1bmtub3duIHZhbHVlIGludG8gYW4gaW5kZXhhYmxlIHJlY29yZC5cbiAqIEBwYXJhbSB2YWx1ZSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyBSZWNvcmQgdmlldyB3aGVuIHRoZSB2YWx1ZSBpcyBvYmplY3QtbGlrZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh7IHR5cGU6IFwiSWRlbnRpZmllclwiIH0pO1xuICogYGBgXG4gKi9cbmNvbnN0IGFzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQgPT5cbiAgdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiXG4gICAgPyAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgOiB2b2lkIDA7XG5cbi8qKlxuICogUmVhZHMgb25lIHN0cmluZyBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIFN0cmluZyB2YWx1ZSB3aGVuIHByZXNlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eSh7IG5hbWU6IFwiZmVhdHVyZVwiIH0sIFwibmFtZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCByZWFkU3RyaW5nUHJvcGVydHkgPSAoXG4gIHZhbHVlOiB1bmtub3duLFxuICBrZXk6IHN0cmluZyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHJlY29yZCA9IGFzUmVjb3JkKHZhbHVlKTtcbiAgY29uc3QgcHJvcGVydHkgPSByZWNvcmQ/LltrZXldO1xuICByZXR1cm4gdHlwZW9mIHByb3BlcnR5ID09PSBcInN0cmluZ1wiID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBhcnJheSBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIEFycmF5IHZhbHVlIHdoZW4gcHJlc2VudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBpdGVtcyA9IHJlYWRBcnJheVByb3BlcnR5KHsgZWxlbWVudHM6IFsxLCAyXSB9LCBcImVsZW1lbnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHJlYWRBcnJheVByb3BlcnR5ID0gKFxuICB2YWx1ZTogdW5rbm93bixcbiAga2V5OiBzdHJpbmcsXG4pOiB1bmRlZmluZWQgfCB1bmtub3duW10gPT4ge1xuICBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh2YWx1ZSk7XG4gIGNvbnN0IHByb3BlcnR5ID0gcmVjb3JkPy5ba2V5XTtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkocHJvcGVydHkpID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlc29sdmVzIFR5cGVTY3JpcHQgcGFyc2VyIHNlcnZpY2VzIHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAcGFyYW0gY29udGV4dCBSdWxlIGNvbnRleHQuXG4gKiBAcmV0dXJucyBUeXBlU2NyaXB0IHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcHJvZ3JhbSA9IGdldFR5cGVTY3JpcHRQcm9ncmFtKGNvbnRleHQpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFR5cGVTY3JpcHRQcm9ncmFtID0gKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuKTogdHMuUHJvZ3JhbSB8IHVuZGVmaW5lZCA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2VydmljZXMgPSBFU0xpbnRVdGlscy5nZXRQYXJzZXJTZXJ2aWNlcyhjb250ZXh0IGFzIG5ldmVyKTtcbiAgICByZXR1cm4gc2VydmljZXMucHJvZ3JhbTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBpZGVudGlmaWVyIG5hbWVzIGZyb20gb25lIHZhcmlhYmxlIHBhdHRlcm4uXG4gKiBAcGFyYW0gbm9kZSBWYXJpYWJsZSBwYXR0ZXJuIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIElkZW50aWZpZXIgbmFtZXMgZGVjbGFyZWQgYnkgdGhlIHBhdHRlcm4uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZXMgPSBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhwYXR0ZXJuKTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyA9IChub2RlOiB1bmtub3duKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBwYXR0ZXJuID0gYXNSZWNvcmQobm9kZSk7XG5cbiAgaWYgKHBhdHRlcm4gPT09IHZvaWQgMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHBhdHRlcm5UeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KHBhdHRlcm4sIFwidHlwZVwiKTtcblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eShwYXR0ZXJuLCBcIm5hbWVcIik7XG4gICAgcmV0dXJuIG5hbWUgPT09IHZvaWQgMCA/IFtdIDogW25hbWVdO1xuICB9XG5cbiAgaWYgKHBhdHRlcm5UeXBlID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMocGF0dGVybltcImFyZ3VtZW50XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBc3NpZ25tZW50UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKHBhdHRlcm5bXCJsZWZ0XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBcnJheVBhdHRlcm5cIikge1xuICAgIHJldHVybiAocmVhZEFycmF5UHJvcGVydHkocGF0dGVybiwgXCJlbGVtZW50c1wiKSA/PyBbXSkuZmxhdE1hcCgoZWxlbWVudCkgPT5cbiAgICAgIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKGVsZW1lbnQpLFxuICAgICk7XG4gIH1cblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiT2JqZWN0UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIChyZWFkQXJyYXlQcm9wZXJ0eShwYXR0ZXJuLCBcInByb3BlcnRpZXNcIikgPz8gW10pLmZsYXRNYXAoXG4gICAgICAocHJvcGVydHkpID0+IHtcbiAgICAgICAgaWYgKHJlYWRTdHJpbmdQcm9wZXJ0eShwcm9wZXJ0eSwgXCJ0eXBlXCIpID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoXG4gICAgICAgICAgICBhc1JlY29yZChwcm9wZXJ0eSk/LltcImFyZ3VtZW50XCJdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoYXNSZWNvcmQocHJvcGVydHkpPy5bXCJ2YWx1ZVwiXSk7XG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gW107XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBleHBvcnQgc3BlY2lmaWVyIG5hbWUuXG4gKiBAcGFyYW0gc3BlY2lmaWVyIEV4cG9ydCBzcGVjaWZpZXIgY2FuZGlkYXRlLlxuICogQHJldHVybnMgRXhwb3J0ZWQgbmFtZSB3aGVuIGF2YWlsYWJsZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTmFtZShzcGVjaWZpZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldEV4cG9ydFNwZWNpZmllck5hbWUgPSAoc3BlY2lmaWVyOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2FuZGlkYXRlID0gYXNSZWNvcmQoc3BlY2lmaWVyKTtcbiAgY29uc3QgZXhwb3J0ZWROYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGNhbmRpZGF0ZT8uW1wiZXhwb3J0ZWRcIl0sIFwibmFtZVwiKTtcblxuICBpZiAodHlwZW9mIGV4cG9ydGVkTmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBleHBvcnRlZE5hbWU7XG4gIH1cblxuICBjb25zdCBsb2NhbE5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoY2FuZGlkYXRlPy5bXCJsb2NhbFwiXSwgXCJuYW1lXCIpO1xuXG4gIHJldHVybiB0eXBlb2YgbG9jYWxOYW1lID09PSBcInN0cmluZ1wiID8gbG9jYWxOYW1lIDogdm9pZCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBvbmUgbG9jYWwgZXhwb3J0IHNwZWNpZmllciBuYW1lLlxuICogQHBhcmFtIHNwZWNpZmllciBFeHBvcnQgc3BlY2lmaWVyIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIExvY2FsIHNwZWNpZmllciBuYW1lIHdoZW4gYXZhaWxhYmxlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IG5hbWUgPSBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUoc3BlY2lmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUgPSAoXG4gIHNwZWNpZmllcjogdW5rbm93bixcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IGFzUmVjb3JkKHNwZWNpZmllcik7XG5cbiAgcmV0dXJuIHJlYWRTdHJpbmdQcm9wZXJ0eShjYW5kaWRhdGU/LltcImxvY2FsXCJdLCBcIm5hbWVcIik7XG59O1xuXG4vKipcbiAqIENvbGxlY3RzIHRvcC1sZXZlbCBkZWNsYXJhdGlvbiBuYW1lcyBvd25lZCBieSB0aGUgY3VycmVudCBtb2R1bGUuXG4gKiBAcGFyYW0gYm9keSBQcm9ncmFtIGJvZHkgc3RhdGVtZW50cy5cbiAqIEByZXR1cm5zIE1hcCBmcm9tIGxvY2FsbHkgZGVjbGFyZWQgbmFtZSB0byBpdHMgZGVjbGFyYXRpb24gbWV0YWRhdGEuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZGVjbGFyYXRpb25zID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhwcm9ncmFtLmJvZHkpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RMb2NhbERlY2xhcmF0aW9uTmFtZXMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IE1hcDxzdHJpbmcsIExvY2FsRGVjbGFyYXRpb24+ID0+IHtcbiAgY29uc3QgZGVjbGFyYXRpb25OYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBMb2NhbERlY2xhcmF0aW9uPigpO1xuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJvZHkpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbkNhbmRpZGF0ZSA9XG4gICAgICBzdGF0ZW1lbnQudHlwZSA9PT0gXCJFeHBvcnROYW1lZERlY2xhcmF0aW9uXCIgJiZcbiAgICAgIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gbnVsbCAmJlxuICAgICAgc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSB2b2lkIDBcbiAgICAgICAgPyBzdGF0ZW1lbnQuZGVjbGFyYXRpb25cbiAgICAgICAgOiBzdGF0ZW1lbnQ7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPSBhc1JlY29yZChkZWNsYXJhdGlvbkNhbmRpZGF0ZSk7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGUsXG4gICAgICBcInR5cGVcIixcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPT09IHZvaWQgMCB8fFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID09PSB2b2lkIDBcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJUU0VudW1EZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoXG4gICAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlUmVjb3JkW1wiaWRcIl0sXG4gICAgICAgIFwibmFtZVwiLFxuICAgICAgKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGRlY2xhcmF0aW9uTmFtZXMuc2V0KGRlY2xhcmF0aW9uTmFtZSwge1xuICAgICAgICAgIGtpbmQ6XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgICAgOiBcInZhbHVlXCIsXG4gICAgICAgICAgbm9kZTogc3RhdGVtZW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSAhPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY2xhcmF0aW9ucyA9IHJlYWRBcnJheVByb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQsXG4gICAgICBcImRlY2xhcmF0aW9uc1wiLFxuICAgICk7XG5cbiAgICBpZiAoZGVjbGFyYXRpb25zID09PSB2b2lkIDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgZGVjbGFyYXRpb25zKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvblJlY29yZCA9IGFzUmVjb3JkKGRlY2xhcmF0aW9uKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uUmVjb3JkID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgZGVjbGFyYXRpb25SZWNvcmRbXCJpZFwiXSxcbiAgICAgICkpIHtcbiAgICAgICAgZGVjbGFyYXRpb25OYW1lcy5zZXQobmFtZSwgeyBraW5kOiBcInZhbHVlXCIsIG5vZGU6IHN0YXRlbWVudCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGVjbGFyYXRpb25OYW1lcztcbn07XG5cbi8qKlxuICogQ29sbGVjdHMgZXhwb3J0ZWQgZWxlbWVudHMgZnJvbSBvbmUgcHJvZ3JhbSBib2R5LlxuICogQHBhcmFtIGJvZHkgUHJvZ3JhbSBib2R5IHN0YXRlbWVudHMuXG4gKiBAcmV0dXJucyBFeHBvcnRlZCBlbGVtZW50cyBpbiBkZWNsYXJhdGlvbiBvcmRlci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBleHBvcnRlZCA9IGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzKHByb2dyYW0uYm9keSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdEV4cG9ydGVkRWxlbWVudHMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IEV4cG9ydGVkRWxlbWVudFtdID0+IHtcbiAgY29uc3QgZXhwb3J0ZWRFbGVtZW50czogRXhwb3J0ZWRFbGVtZW50W10gPSBbXTtcbiAgY29uc3QgbG9jYWxEZWNsYXJhdGlvbk5hbWVzID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhib2R5KTtcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBib2R5KSB7XG4gICAgaWYgKHN0YXRlbWVudC50eXBlID09PSBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvblwiKSB7XG4gICAgICBleHBvcnRlZEVsZW1lbnRzLnB1c2goe1xuICAgICAgICBleHBvcnRlZE5hbWU6IFwiZGVmYXVsdFwiLFxuICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC50eXBlICE9PSBcIkV4cG9ydE5hbWVkRGVjbGFyYXRpb25cIikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC5zb3VyY2UgIT09IG51bGwgJiYgc3RhdGVtZW50LnNvdXJjZSAhPT0gdm9pZCAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSBudWxsICYmIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gdm9pZCAwKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGFzUmVjb3JkKHN0YXRlbWVudC5kZWNsYXJhdGlvbik7XG5cbiAgICAgIGlmIChyZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKSA9PT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiByZWFkQXJyYXlQcm9wZXJ0eShkZWNsYXJhdGlvbiwgXCJkZWNsYXJhdGlvbnNcIikgPz9cbiAgICAgICAgICBbXSkge1xuICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgICAgIGFzUmVjb3JkKHZhcmlhYmxlKT8uW1wiaWRcIl0sXG4gICAgICAgICAgKSkge1xuICAgICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgZXhwb3J0ZWROYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZGVjbGFyYXRpb25OYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGRlY2xhcmF0aW9uPy5bXCJpZFwiXSwgXCJuYW1lXCIpO1xuICAgICAgICBjb25zdCBkZWNsYXJhdGlvblR5cGUgPSByZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKTtcbiAgICAgICAgY29uc3QgZXhwb3J0S2luZDogRXhwb3J0S2luZCA9XG4gICAgICAgICAgZGVjbGFyYXRpb25UeXBlID09PSBcIlRTSW50ZXJmYWNlRGVjbGFyYXRpb25cIiB8fFxuICAgICAgICAgIGRlY2xhcmF0aW9uVHlwZSA9PT0gXCJUU1R5cGVBbGlhc0RlY2xhcmF0aW9uXCJcbiAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgIDogXCJ2YWx1ZVwiO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb25OYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIGV4cG9ydGVkTmFtZTogZGVjbGFyYXRpb25OYW1lLFxuICAgICAgICAgICAgZXhwb3J0S2luZCxcbiAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiBzdGF0ZW1lbnQuc3BlY2lmaWVycykge1xuICAgICAgY29uc3QgbG9jYWxOYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTG9jYWxOYW1lKHNwZWNpZmllcik7XG4gICAgICBjb25zdCBsb2NhbERlY2xhcmF0aW9uID1cbiAgICAgICAgbG9jYWxOYW1lID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsb2NhbERlY2xhcmF0aW9uTmFtZXMuZ2V0KGxvY2FsTmFtZSk7XG5cbiAgICAgIGlmIChsb2NhbERlY2xhcmF0aW9uID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cG9ydGVkTmFtZSA9IGdldEV4cG9ydFNwZWNpZmllck5hbWUoc3BlY2lmaWVyKTtcblxuICAgICAgaWYgKGV4cG9ydGVkTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHN0YXRlbWVudEV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3RhdGVtZW50LCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IHNwZWNpZmllckV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3BlY2lmaWVyLCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IGlzVHlwZU9ubHlFeHBvcnQgPVxuICAgICAgICAgIHN0YXRlbWVudEV4cG9ydEtpbmQgPT09IFwidHlwZVwiIHx8IHNwZWNpZmllckV4cG9ydEtpbmQgPT09IFwidHlwZVwiO1xuXG4gICAgICAgIGV4cG9ydGVkRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgZXhwb3J0ZWROYW1lLFxuICAgICAgICAgIGV4cG9ydEtpbmQ6IGlzVHlwZU9ubHlFeHBvcnQgPyBcInR5cGVcIiA6IGxvY2FsRGVjbGFyYXRpb24ua2luZCxcbiAgICAgICAgICBub2RlOiBsb2NhbERlY2xhcmF0aW9uLm5vZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBvcnRlZEVsZW1lbnRzO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgc3ltYm9sIHRvIGl0cyBjYW5vbmljYWwgdGFyZ2V0LlxuICogQHBhcmFtIHN5bWJvbCBDYW5kaWRhdGUgc3ltYm9sLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHJldHVybnMgUmVzb2x2ZWQgY2Fub25pY2FsIHN5bWJvbC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVDYW5vbmljYWxTeW1ib2woc3ltYm9sLCBjaGVja2VyKTtcbiAqIGBgYFxuICovXG5jb25zdCByZXNvbHZlQ2Fub25pY2FsU3ltYm9sID0gKFxuICBzeW1ib2w6IHRzLlN5bWJvbCxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiB0cy5TeW1ib2wgPT4ge1xuICBpZiAoKHN5bWJvbC5mbGFncyAmIHRzLlN5bWJvbEZsYWdzLkFsaWFzKSA9PT0gMCkge1xuICAgIHJldHVybiBzeW1ib2w7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBjaGVja2VyLmdldEFsaWFzZWRTeW1ib2woc3ltYm9sKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHN5bWJvbDtcbiAgfVxufTtcblxuLyoqXG4gKiBCdWlsZHMgZGVjbGFyYXRpb24tc2l0ZSBrZXlzIGZvciBzeW1ib2wgaWRlbnRpdHkgbWF0Y2hpbmcuXG4gKiBAcGFyYW0gc3ltYm9sIFN5bWJvbCBiZWluZyBjb21wYXJlZC5cbiAqIEByZXR1cm5zIERlY2xhcmF0aW9uIGtleXMgZGVzY3JpYmluZyB3aGVyZSB0aGlzIHN5bWJvbCBpcyBkZWNsYXJlZC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBrZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKHN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RGVjbGFyYXRpb25LZXlzID0gKHN5bWJvbDogdHMuU3ltYm9sKTogU2V0PHN0cmluZz4gPT4ge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBzeW1ib2wuZGVjbGFyYXRpb25zID8/IFtdO1xuXG4gIHJldHVybiBuZXcgU2V0KFxuICAgIGRlY2xhcmF0aW9ucy5tYXAoKGRlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VGaWxlbmFtZSA9IGRlY2xhcmF0aW9uLmdldFNvdXJjZUZpbGUoKS5maWxlTmFtZTtcbiAgICAgIHJldHVybiBgJHtzb3VyY2VGaWxlbmFtZX06JHtTdHJpbmcoZGVjbGFyYXRpb24ucG9zKX06JHtTdHJpbmcoZGVjbGFyYXRpb24uZW5kKX1gO1xuICAgIH0pLFxuICApO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0d28gc3ltYm9scyByZWZlcmVuY2UgdGhlIHNhbWUgZGVjbGFyYXRpb24gc2l0ZS5cbiAqIEBwYXJhbSBsZWZ0IExlZnQtaGFuZCBzeW1ib2wgY2FuZGlkYXRlLlxuICogQHBhcmFtIHJpZ2h0IFJpZ2h0LWhhbmQgc3ltYm9sIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBib3RoIHN5bWJvbHMgaWRlbnRpZnkgdGhlIHNhbWUgZGVjbGFyYXRpb24uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc2FtZSA9IGlzU2FtZVN5bWJvbChsZWZ0LCByaWdodCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgaXNTYW1lU3ltYm9sID0gKGxlZnQ6IHRzLlN5bWJvbCwgcmlnaHQ6IHRzLlN5bWJvbCk6IGJvb2xlYW4gPT4ge1xuICBpZiAobGVmdCA9PT0gcmlnaHQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGNvbnN0IGxlZnRLZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKGxlZnQpO1xuICBjb25zdCByaWdodEtleXMgPSBnZXREZWNsYXJhdGlvbktleXMocmlnaHQpO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIGxlZnRLZXlzKSB7XG4gICAgaWYgKHJpZ2h0S2V5cy5oYXMoa2V5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgZXhwb3J0ZWQgc3ltYm9sIGJ5IG5hbWUgZnJvbSBhIHNvdXJjZSBmaWxlLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcGFyYW0gZXhwb3J0ZWROYW1lIFB1YmxpYyBuYW1lIGV4cG9zZWQgYnkgdGhlIG1vZHVsZSBleHBvcnQgbGlzdC5cbiAqIEByZXR1cm5zIFN5bWJvbCB3aGVuIGZvdW5kLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKHByb2dyYW0sIHNvdXJjZUZpbGVuYW1lLCBcImZlYXR1cmVcIik7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RXhwb3J0ZWRTeW1ib2wgPSAoXG4gIHByb2dyYW06IHRzLlByb2dyYW0sXG4gIHNvdXJjZUZpbGVuYW1lOiBzdHJpbmcsXG4gIGV4cG9ydGVkTmFtZTogc3RyaW5nLFxuKTogdHMuU3ltYm9sIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2hlY2tlciA9IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKTtcbiAgY29uc3Qgc291cmNlRmlsZSA9IHByb2dyYW1cbiAgICAuZ2V0U291cmNlRmlsZXMoKVxuICAgIC5maW5kKFxuICAgICAgKGZpbGUpID0+XG4gICAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChmaWxlLmZpbGVOYW1lKSA9PT1cbiAgICAgICAgdG9Db21wYXJhYmxlQWJzb2x1dGVQYXRoKHNvdXJjZUZpbGVuYW1lKSxcbiAgICApO1xuXG4gIGlmIChzb3VyY2VGaWxlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgY29uc3QgbW9kdWxlU3ltYm9sID0gY2hlY2tlci5nZXRTeW1ib2xBdExvY2F0aW9uKHNvdXJjZUZpbGUpO1xuXG4gIGlmIChtb2R1bGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBjb25zdCBleHBvcnRlZFN5bWJvbCA9IGNoZWNrZXJcbiAgICAuZ2V0RXhwb3J0c09mTW9kdWxlKG1vZHVsZVN5bWJvbClcbiAgICAuZmluZCgoc3ltYm9sKSA9PiBzeW1ib2wuZ2V0TmFtZSgpID09PSBleHBvcnRlZE5hbWUpO1xuXG4gIGlmIChleHBvcnRlZFN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgb25lIHNvdXJjZSBmaWxlIGV4cG9ydHMgdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0aGF0IG1heSBleHBvc2UgdGhlIHN5bWJvbC5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgY2hlY2tlci5cbiAqIEBwYXJhbSB0YXJnZXRTeW1ib2wgU3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gb25lIG1vZHVsZSBleHBvcnQgcmVzb2x2ZXMgdG8gdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZXhwb3NlZCA9IHNvdXJjZUZpbGVFeHBvcnRzU3ltYm9sKHNvdXJjZUZpbGUsIGNoZWNrZXIsIHRhcmdldFN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3Qgc291cmNlRmlsZUV4cG9ydHNTeW1ib2wgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBtb2R1bGVTeW1ib2wgPSBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24oc291cmNlRmlsZSk7XG5cbiAgaWYgKG1vZHVsZVN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCBleHBvcnRlZFN5bWJvbCBvZiBjaGVja2VyLmdldEV4cG9ydHNPZk1vZHVsZShtb2R1bGVTeW1ib2wpKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcblxuICAgIGlmIChpc1NhbWVTeW1ib2wocmVzb2x2ZWRTeW1ib2wsIHRhcmdldFN5bWJvbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYW4gaWRlbnRpZmllciBwYXJ0aWNpcGF0ZXMgaW4gb25lIGRlY2xhcmF0aW9uL2ltcG9ydC9leHBvcnQgc2l0ZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIElkZW50aWZpZXIgbm9kZSB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBpcyBkZWNsYXJhdGlvbi1vbmx5IHN5bnRheC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBkZWNsYXJhdGlvbiA9IGlzRGVjbGFyYXRpb25Pbmx5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBwYXJlbnQgPSBpZGVudGlmaWVyLnBhcmVudDtcblxuICByZXR1cm4gKFxuICAgIHRzLmlzSW1wb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc0ltcG9ydENsYXVzZShwYXJlbnQpIHx8XG4gICAgdHMuaXNOYW1lc3BhY2VJbXBvcnQocGFyZW50KSB8fFxuICAgIHRzLmlzSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24ocGFyZW50KSB8fFxuICAgIHRzLmlzRXhwb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc0ludGVyZmFjZURlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbihwYXJlbnQpIHx8XG4gICAgKHRzLmlzVmFyaWFibGVEZWNsYXJhdGlvbihwYXJlbnQpICYmIHBhcmVudC5uYW1lID09PSBpZGVudGlmaWVyKSB8fFxuICAgICh0cy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24ocGFyZW50KSAmJiBwYXJlbnQubmFtZSA9PT0gaWRlbnRpZmllcikgfHxcbiAgICAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpIHx8XG4gICAgKHRzLmlzUGFyYW1ldGVyKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIG9uZSBpZGVudGlmaWVyIG5vZGUgYXBwZWFycyB1bmRlciBhIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIENhbmRpZGF0ZSBpZGVudGlmaWVyLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBpZGVudGlmaWVyIGlzIGluc2lkZSB0eXBlLW9ubHkgc3ludGF4LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc1R5cGVQb3NpdGlvbklkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCB2aXNpdE5vZGUgPSAoY3VycmVudDogdHMuTm9kZSk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0cy5pc1R5cGVRdWVyeU5vZGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHMuaXNUeXBlTm9kZShjdXJyZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHMuaXNFeHByZXNzaW9uU3RhdGVtZW50KGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc0NhbGxFeHByZXNzaW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1Byb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNFbGVtZW50QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1JldHVyblN0YXRlbWVudChjdXJyZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0cy5pc1NvdXJjZUZpbGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmlzaXROb2RlKGN1cnJlbnQucGFyZW50KTtcbiAgfTtcblxuICByZXR1cm4gdmlzaXROb2RlKGlkZW50aWZpZXIpO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBvbmUgaWRlbnRpZmllciBpcyBvbmUgY29uY3JldGUgdXNhZ2UgY2FuZGlkYXRlIGZvciB0aGUgZXhwb3J0IGtpbmQuXG4gKiBAcGFyYW0gaWRlbnRpZmllciBJZGVudGlmaWVyIG5vZGUuXG4gKiBAcGFyYW0gZXhwb3J0S2luZCBXaGV0aGVyIHR5cGUtb25seSBvciB2YWx1ZSB1c2FnZSBpcyByZXF1aXJlZC5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBjYW4gc2F0aXNmeSB1c2FnZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBjb25jcmV0ZSA9IGlzQ29uY3JldGVVc2FnZUlkZW50aWZpZXIoaWRlbnRpZmllciwgXCJ2YWx1ZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0NvbmNyZXRlVXNhZ2VJZGVudGlmaWVyID0gKFxuICBpZGVudGlmaWVyOiB0cy5JZGVudGlmaWVyLFxuICBleHBvcnRLaW5kOiBFeHBvcnRLaW5kLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIoaWRlbnRpZmllcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBpblR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcblxuICByZXR1cm4gZXhwb3J0S2luZCA9PT0gXCJ0eXBlXCIgPyBpblR5cGVQb3NpdGlvbiA6ICFpblR5cGVQb3NpdGlvbjtcbn07XG5cbi8qKlxuICogQXBwZW5kcyBjb25jcmV0ZSB1c2FnZXMgZnJvbSBvbmUgc291cmNlIGZpbGUgaW50byB0aGUgYWNjdW11bGF0b3IuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0byBzY2FuLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHBhcmFtIHRhcmdldFN5bWJvbCBFeHBvcnQgc3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcGFyYW0gZXhwb3J0ZWRFbGVtZW50IEV4cG9ydCBtZXRhZGF0YS5cbiAqIEBwYXJhbSBjb25zdW1lcklzVGVzdEZpbGUgV2hldGhlciBzb3VyY2UgZmlsZSBpcyBhIHRlc3QgZmlsZS5cbiAqIEBwYXJhbSB1c2FnZXMgTXV0YWJsZSB1c2FnZSBhY2N1bXVsYXRvci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShzb3VyY2VGaWxlLCBjaGVja2VyLCB0YXJnZXRTeW1ib2xLZXksIGV4cG9ydGVkRWxlbWVudCwgZmFsc2UsIHVzYWdlcyk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdENvbmNyZXRlVXNhZ2VzRnJvbVNvdXJjZUZpbGUgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbiAgZXhwb3J0ZWRFbGVtZW50OiBFeHBvcnRlZEVsZW1lbnQsXG4gIGNvbnN1bWVySXNUZXN0RmlsZTogYm9vbGVhbixcbiAgdXNhZ2VzOiBFeHBvcnRVc2FnZVtdLFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IHZpc2l0Tm9kZSA9IChub2RlOiB0cy5Ob2RlKTogdm9pZCA9PiB7XG4gICAgaWYgKCF0cy5pc0lkZW50aWZpZXIobm9kZSkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaXNDb25jcmV0ZVVzYWdlSWRlbnRpZmllcihub2RlLCBleHBvcnRlZEVsZW1lbnQuZXhwb3J0S2luZCkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbmRpZGF0ZVN5bWJvbCA9IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihub2RlKTtcblxuICAgIGlmIChjYW5kaWRhdGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGNhbmRpZGF0ZVN5bWJvbCwgY2hlY2tlcik7XG5cbiAgICBpZiAoIWlzU2FtZVN5bWJvbChyZXNvbHZlZFN5bWJvbCwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goeyBpc1Rlc3RGaWxlOiBjb25zdW1lcklzVGVzdEZpbGUgfSk7XG4gICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gIH07XG5cbiAgdmlzaXROb2RlKHNvdXJjZUZpbGUpO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBwdWJsaWMgQVBJIGV4cG9zdXJlIHVzYWdlcyBmb3Igb25lIGV4cG9ydGVkIHN5bWJvbC5cbiAqIEBwYXJhbSBwcm9ncmFtIFR5cGVTY3JpcHQgcHJvZ3JhbS5cbiAqIEBwYXJhbSBzb3VyY2VGaWxlbmFtZSBTb3VyY2UgZmlsZW5hbWUgd2hlcmUgZXhwb3J0IGlzIGRlZmluZWQuXG4gKiBAcGFyYW0gc3RhdGUgTm9ybWFsaXplZCBydWxlIG9wdGlvbnMuXG4gKiBAcGFyYW0gcmVwb1Jvb3QgQWJzb2x1dGUgcmVwb3NpdG9yeSByb290IHVzZWQgZm9yIGZpbGUgY2xhc3NpZmljYXRpb24uXG4gKiBAcGFyYW0gdGFyZ2V0U3ltYm9sIEV4cG9ydCBzeW1ib2wgYmVpbmcgY2xhc3NpZmllZC5cbiAqIEByZXR1cm5zIFB1YmxpYyBBUEkgZXhwb3N1cmUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgc3ltYm9sLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzYWdlcyA9IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyhwcm9ncmFtLCBzb3VyY2VGaWxlbmFtZSwgc3RhdGUsIHJlcG9Sb290LCB0YXJnZXRTeW1ib2wpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyA9IChcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgc291cmNlRmlsZW5hbWU6IHN0cmluZyxcbiAgc3RhdGU6IE5vVW51c2VkRXhwb3J0c1N0YXRlLFxuICByZXBvUm9vdDogc3RyaW5nLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IEV4cG9ydFVzYWdlW10gPT4ge1xuICBjb25zdCBjaGVja2VyID0gcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpO1xuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHNvdXJjZUZpbGUgb2YgcHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpKSB7XG4gICAgaWYgKHNvdXJjZUZpbGUuaXNEZWNsYXJhdGlvbkZpbGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHB1YmxpY0FwaUZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9XG4gICAgICB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgocHVibGljQXBpRmlsZW5hbWUpO1xuXG4gICAgaWYgKG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoIWlzUHVibGljQXBpRmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICghc291cmNlRmlsZUV4cG9ydHNTeW1ib2woc291cmNlRmlsZSwgY2hlY2tlciwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goe1xuICAgICAgaXNUZXN0RmlsZTogaXNUZXN0RmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCksXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBjb25jcmV0ZSB1c2FnZXMgb2Ygb25lIGV4cG9ydGVkIGVsZW1lbnQgYWNyb3NzIHRoZSBwcm9ncmFtLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlbmFtZSB3aGVyZSBleHBvcnQgaXMgZGVmaW5lZC5cbiAqIEBwYXJhbSBzdGF0ZSBOb3JtYWxpemVkIHJ1bGUgb3B0aW9ucy5cbiAqIEBwYXJhbSByZXBvUm9vdCBBYnNvbHV0ZSByZXBvc2l0b3J5IHJvb3QgdXNlZCBmb3IgdGVzdC1maWxlIGNsYXNzaWZpY2F0aW9uLlxuICogQHBhcmFtIGV4cG9ydGVkRWxlbWVudCBFeHBvcnRlZCBlbGVtZW50IHRvIGNsYXNzaWZ5LlxuICogQHJldHVybnMgQ29uY3JldGUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgZWxlbWVudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB1c2FnZXMgPSBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzKHByb2dyYW0sIFwiL3JlcG8vc3JjL2ZlYXR1cmUudHNcIiwgc3RhdGUsIFwiL3JlcG9cIiwgZXhwb3J0ZWRFbGVtZW50KTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzID0gKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBzb3VyY2VGaWxlbmFtZTogc3RyaW5nLFxuICBzdGF0ZTogTm9VbnVzZWRFeHBvcnRzU3RhdGUsXG4gIHJlcG9Sb290OiBzdHJpbmcsXG4gIGV4cG9ydGVkRWxlbWVudDogRXhwb3J0ZWRFbGVtZW50LFxuKTogRXhwb3J0VXNhZ2VbXSA9PiB7XG4gIGNvbnN0IGNoZWNrZXIgPSBwcm9ncmFtLmdldFR5cGVDaGVja2VyKCk7XG4gIGNvbnN0IHRhcmdldFN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKFxuICAgIHByb2dyYW0sXG4gICAgc291cmNlRmlsZW5hbWUsXG4gICAgZXhwb3J0ZWRFbGVtZW50LmV4cG9ydGVkTmFtZSxcbiAgKTtcblxuICBpZiAodGFyZ2V0U3ltYm9sID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBjb2xsZWN0UHVibGljQXBpRXhwb3N1cmVVc2FnZXMoXG4gICAgcHJvZ3JhbSxcbiAgICBzb3VyY2VGaWxlbmFtZSxcbiAgICBzdGF0ZSxcbiAgICByZXBvUm9vdCxcbiAgICB0YXJnZXRTeW1ib2wsXG4gICk7XG5cbiAgZm9yIChjb25zdCBzb3VyY2VGaWxlIG9mIHByb2dyYW0uZ2V0U291cmNlRmlsZXMoKSkge1xuICAgIGlmIChzb3VyY2VGaWxlLmlzRGVjbGFyYXRpb25GaWxlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lckZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRDb25zdW1lckZpbGVuYW1lID1cbiAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChjb25zdW1lckZpbGVuYW1lKTtcblxuICAgIGlmIChub3JtYWxpemVkQ29uc3VtZXJGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lcklzVGVzdEZpbGUgPSBpc1Rlc3RGaWxlKFxuICAgICAgY29uc3VtZXJGaWxlbmFtZSxcbiAgICAgIHN0YXRlLFxuICAgICAgbm9ybWFsaXplZFJlcG9Sb290LFxuICAgICk7XG5cbiAgICBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShcbiAgICAgIHNvdXJjZUZpbGUsXG4gICAgICBjaGVja2VyLFxuICAgICAgdGFyZ2V0U3ltYm9sLFxuICAgICAgZXhwb3J0ZWRFbGVtZW50LFxuICAgICAgY29uc3VtZXJJc1Rlc3RGaWxlLFxuICAgICAgdXNhZ2VzLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDbGFzc2lmaWVzIG9uZSBleHBvcnRlZCBuYW1lIGJhc2VkIG9uIGNyb3NzLWZpbGUgdXNhZ2VzLlxuICogQHBhcmFtIHVzYWdlcyBDb2xsZWN0ZWQgdXNhZ2VzLlxuICogQHJldHVybnMgQ2xhc3NpZmljYXRpb24gbGFiZWwuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xhc3NpZmljYXRpb24gPSBjbGFzc2lmeUV4cG9ydFVzYWdlKFwiZmVhdHVyZVwiLCB1c2FnZXMpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNsYXNzaWZ5RXhwb3J0VXNhZ2UgPSAoXG4gIHVzYWdlczogRXhwb3J0VXNhZ2VbXSxcbik6IFwicHJvZHVjdGlvblwiIHwgXCJ0ZXN0LW9ubHlcIiB8IFwidW51c2VkXCIgPT4ge1xuICBpZiAodXNhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBcInVudXNlZFwiO1xuICB9XG5cbiAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICBpZiAoIXVzYWdlLmlzVGVzdEZpbGUpIHtcbiAgICAgIHJldHVybiBcInByb2R1Y3Rpb25cIjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gXCJ0ZXN0LW9ubHlcIjtcbn07XG5cbmV4cG9ydCB7XG4gIGNsYXNzaWZ5RXhwb3J0VXNhZ2UsXG4gIGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXMsXG4gIGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzLFxuICBnZXRUeXBlU2NyaXB0UHJvZ3JhbSxcbn07XG4iXX0=
|