@tiangong-lca/cli 0.0.6 → 0.0.8
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 +154 -30
- package/dist/src/cli.js +2235 -149
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-author.js +100 -0
- package/dist/src/lib/dataset-author.js.map +1 -0
- package/dist/src/lib/dataset-bilingual.js +545 -0
- package/dist/src/lib/dataset-bilingual.js.map +1 -0
- package/dist/src/lib/dataset-contract.js +350 -0
- package/dist/src/lib/dataset-contract.js.map +1 -0
- package/dist/src/lib/dataset-evidence-search.js +636 -0
- package/dist/src/lib/dataset-evidence-search.js.map +1 -0
- package/dist/src/lib/dataset-import-lca.js +171 -0
- package/dist/src/lib/dataset-import-lca.js.map +1 -0
- package/dist/src/lib/dataset-local.js +231 -0
- package/dist/src/lib/dataset-local.js.map +1 -0
- package/dist/src/lib/dataset-references-rewrite.js +214 -0
- package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
- package/dist/src/lib/dataset-remote-refresh.js +166 -0
- package/dist/src/lib/dataset-remote-refresh.js.map +1 -0
- package/dist/src/lib/dataset-remote-verify.js +543 -0
- package/dist/src/lib/dataset-remote-verify.js.map +1 -0
- package/dist/src/lib/dataset-validate.js +247 -0
- package/dist/src/lib/dataset-validate.js.map +1 -0
- package/dist/src/lib/flow-payload-validation.js +51 -0
- package/dist/src/lib/flow-payload-validation.js.map +1 -0
- package/dist/src/lib/flow-publish-reviewed-data.js +16 -0
- package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +182 -12
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-regen-product.js +2 -10
- package/dist/src/lib/flow-regen-product.js.map +1 -1
- package/dist/src/lib/flow-remediate.js +4 -8
- package/dist/src/lib/flow-remediate.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +1021 -0
- package/dist/src/lib/identity-preflight.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
- package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-graph.js +248 -0
- package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
- package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
- package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
- package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
- package/dist/src/lib/process-auto-build.js +158 -8
- package/dist/src/lib/process-auto-build.js.map +1 -1
- package/dist/src/lib/process-batch-build.js +6 -3
- package/dist/src/lib/process-batch-build.js.map +1 -1
- package/dist/src/lib/process-dedup-review.js +921 -0
- package/dist/src/lib/process-dedup-review.js.map +1 -0
- package/dist/src/lib/process-flow-build-plan.js +1071 -0
- package/dist/src/lib/process-flow-build-plan.js.map +1 -0
- package/dist/src/lib/process-payload-validation.js +57 -0
- package/dist/src/lib/process-payload-validation.js.map +1 -0
- package/dist/src/lib/process-publish-build.js +126 -10
- package/dist/src/lib/process-publish-build.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +1037 -0
- package/dist/src/lib/process-refresh-references.js.map +1 -0
- package/dist/src/lib/process-required-fields.js +810 -0
- package/dist/src/lib/process-required-fields.js.map +1 -0
- package/dist/src/lib/process-resume-build.js +4 -6
- package/dist/src/lib/process-resume-build.js.map +1 -1
- package/dist/src/lib/process-save-draft-run.js +35 -13
- package/dist/src/lib/process-save-draft-run.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +859 -0
- package/dist/src/lib/process-scope-statistics.js.map +1 -0
- package/dist/src/lib/process-verify-rows.js +250 -0
- package/dist/src/lib/process-verify-rows.js.map +1 -0
- package/dist/src/lib/publish.js +101 -1
- package/dist/src/lib/publish.js.map +1 -1
- package/dist/src/lib/remote.js +4 -4
- package/dist/src/lib/remote.js.map +1 -1
- package/dist/src/lib/review-flow.js +58 -0
- package/dist/src/lib/review-flow.js.map +1 -1
- package/dist/src/lib/review-lifecyclemodel.js +2 -2
- package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
- package/dist/src/lib/review-process.js +150 -2
- package/dist/src/lib/review-process.js.map +1 -1
- package/dist/src/lib/runtime-rulesets.js +283 -0
- package/dist/src/lib/runtime-rulesets.js.map +1 -0
- package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
- package/dist/src/lib/tidas-sdk-validation.js +96 -0
- package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
- package/dist/src/lib/user-api-key.js +1 -1
- package/dist/src/lib/user-api-key.js.map +1 -1
- package/package.json +5 -5
- /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
- /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-scope-statistics.js","sourceRoot":"","sources":["../../../src/lib/process-scope-statistics.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAI9E,MAAM,mBAAmB,GAAG,CAAC,CAAC,EAAE,GAAG,CAAU,CAAC;AAC9C,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AA4I9B,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED,SAAS,MAAM,CAAC,MAAY,IAAI,IAAI,EAAE;IACpC,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAgC,EAAE,KAAa,EAAE,IAAY;IACtF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAK,KAAgB,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,QAAQ,CAAC,YAAY,KAAK,4BAA4B,EAAE;YAChE,IAAI;YACJ,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAe,CAAC;AACzB,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAoC;IAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,mBAAmB,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,QAAQ,CAAC,+DAA+D,EAAE;gBAClF,IAAI,EAAE,mCAAmC;gBACzC,QAAQ,EAAE,CAAC;aACZ,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,QAAQ,CAAC,qDAAqD,EAAE;YACxE,IAAI,EAAE,oCAAoC;YAC1C,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,WAAW,CAAC,KAAyB;IAC5C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;QAC7B,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,4DAA4D,EAAE;QAC/E,IAAI,EAAE,6BAA6B;QACnC,QAAQ,EAAE,CAAC;KACZ,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,QAAsB,EAAE,KAAa;IACpE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAAC,GAAG,KAAK,yBAAyB,EAAE;YACpD,IAAI,EAAE,mCAAmC;YACzC,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;SACvB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,OAOjC;IACC,IAAI,SAAS,GAAY,IAAI,CAAC;IAE9B,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE;gBACpD,GAAG,OAAO,CAAC,IAAI;gBACf,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;aAC/C,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,gBAAgB,QAAQ,CAAC,MAAM,GAAG,EAAE;oBACrE,IAAI,EAAE,qCAAqC;oBAC3C,QAAQ,EAAE,CAAC;oBACX,OAAO,EAAE;wBACP,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,IAAI;wBACJ,GAAG,EAAE,OAAO,CAAC,GAAG;qBACjB;iBACF,CAAC,CAAC;YACL,CAAC;YACD,OAAO;gBACL,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,OAAO,EAAE,IAAI,OAAO,CAAC;oBACnB,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE;oBAC5D,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;iBAC3D,CAAC;gBACF,IAAI;aACL,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBAClC,MAAM;YACR,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,IAAI,SAAS,YAAY,QAAQ,EAAE,CAAC;QAClC,MAAM,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,iBAAiB,OAAO,CAAC,UAAU,cAAc,EAAE;QACpF,IAAI,EAAE,qCAAqC;QAC3C,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,OAMnC;IACC,MAAM,OAAO,GAAG,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC;QAC/C,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC;QACpC,GAAG,EAAE,GAAG,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe;QACvE,IAAI,EAAE;YACJ,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,cAAc;gBAC9B,aAAa,EAAE,UAAU,OAAO,CAAC,WAAW,EAAE;gBAC9C,MAAM,EAAE,kBAAkB;aAC3B;SACF;QACD,KAAK,EAAE,8BAA8B;QACrC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAAC,2DAA2D,EAAE;YAC9E,IAAI,EAAE,uCAAuC;YAC7C,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAS/B;IACC,MAAM,OAAO,GAAG,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC;QAC/C,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxE,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QAC3C,IAAI,UAAU,GAAkB,IAAI,CAAC;QACrC,IAAI,QAAQ,GAAG,EAAE,CAAC;QAElB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,cAAc,oBAAoB,CAAC,CAAC;YAC3D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,yDAAyD,CAAC,CAAC;YAC1F,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,SAAS,EAAE,CAAC,CAAC;YACtD,IAAI,OAAO,CAAC,KAAK,KAAK,cAAc,EAAE,CAAC;gBACrC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,QAAQ,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACxC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAExD,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC;gBACpC,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;gBACnB,IAAI,EAAE;oBACJ,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE;wBACP,MAAM,EAAE,OAAO,CAAC,cAAc;wBAC9B,aAAa,EAAE,UAAU,OAAO,CAAC,WAAW,EAAE;wBAC9C,MAAM,EAAE,kBAAkB;wBAC1B,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC1D;iBACF;gBACD,KAAK,EAAE,mDAAmD,SAAS,GAAG;gBACtE,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,cAAc,GAAG,QAAQ;iBAC5B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;iBACvC,MAAM,CAAC,CAAC,GAAG,EAAsB,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;YACrD,IAAI,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;YAE7B,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;gBAC5E,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC3D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;oBACxB,KAAK,IAAI,UAAU,CAAC;gBACtB,CAAC;YACH,CAAC;YAED,IAAI,cAAc,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAC7C,MAAM;YACR,CAAC;YAED,MAAM,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;YAC3D,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,KAAK,IAAI,IAAI;KACrB,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,GAAG,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,EAAE;QACF,OAAO;QACP,UAAU,EAAE,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;QAC1E,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC;QAC9C,WAAW,EAAE,sBAAsB,CAAC,KAAK,CAAC,WAAW,CAAC;QACtD,QAAQ,EAAE,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC;QAChD,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAsB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAsB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,UAAU,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjF,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,IAAmB;IACtD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,KAAK,GACT,IAAI,KAAK,IAAI;QACX,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,IAAI,CACP,CAAC,IAAI,EAAE,EAAE,CACP,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE;YAChE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAC1B,CAAC;IACR,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,4BAA4B,CAAC,kBAA8B;IAClE,MAAM,OAAO,GAAG,OAAO,CACpB,kBAAkB,CAAC,yBAAoD,EAAE,CACxE,uBAAuB,CACxB;QAEI,kBAAkB,CAAC,yBAAwC,CAAC,uBAAuB,CAGrF,EAAE,CAAC,cAAc,CAAC,CACtB,CAAC;IAEF,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;SAC/D,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,QAAQ,CAAC,IAAI,CAAC;SAClB,SAAS,CAAC,MAAM,CAAC;SACjB,WAAW,EAAE;SACb,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;SAChC,OAAO,CAAC,4BAA4B,EAAE,GAAG,CAAC;SAC1C,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAgB;IACzC,MAAM,KAAK,GAAG;QACZ,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;YAC9B,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;YAChC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/B,WAAW,CAAC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC;YAC9C,WAAW,CAAC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC;YAChD,cAAc,CAAC,IAAI,CAAC,wBAAwB,CAAC;QAC/C,WAAW,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;YACzC,WAAW,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;YAC3C,cAAc,CAAC,IAAI,CAAC,mBAAmB,CAAC;QAC1C,WAAW,CAAC,IAAI,CAAC,4BAA4B,EAAE,IAAI,CAAC;YAClD,WAAW,CAAC,IAAI,CAAC,4BAA4B,EAAE,IAAI,CAAC;YACpD,cAAc,CAAC,IAAI,CAAC,4BAA4B,CAAC;KACpD,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,qBAAqB,CAC5B,kBAA8B,EAC9B,UAAsB;IAMtB,MAAM,IAAI,GAAG,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,UAAU,GAAG;QACjB;YACE,WAAW,EAAE,0BAA0B;YACvC,KAAK,EACH,WAAW,CAAC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC;gBAChD,WAAW,CAAC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC;gBAChD,cAAc,CAAC,IAAI,CAAC,wBAAwB,CAAC;SAChD;QACD;YACE,WAAW,EAAE,2CAA2C;YACxD,KAAK,EACH,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,yCAAyC,EAAE,IAAI,CAAC,CAAC;gBACpF,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,yCAAyC,EAAE,IAAI,CAAC,CAAC;gBACpF,WAAW,CAAC,cAAc,CAAC,UAAU,CAAC,yCAAyC,CAAC,CAAC;SACpF;QACD;YACE,WAAW,EAAE,UAAU;YACvB,KAAK,EACH,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;gBAChC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;gBAChC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC;SAChC;KACF,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;gBACL,GAAG,SAAS;gBACZ,SAAS,EAAE,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC;aAC/C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW,EAAE,SAAS;QACtB,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;KACd,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,cAA0B,EAC1B,kBAA8B;IAS9B,MAAM,kBAAkB,GAAG,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC;QACpE,CAAC,CAAC,cAAc,CAAC,kBAAkB;QACnC,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,QAAQ,GAAG,QAAQ,CAAC,kBAAkB,CAAC,qBAAqB,CAAC;QACjE,CAAC,CAAC,kBAAkB,CAAC,qBAAqB;QAC1C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAChC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,KAAK,aAAa,CAC/F,CAAC;IACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,MAAM,OAAO,GACX,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/F,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IACpD,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,MAAM,gBAAgB,GACpB,WAAW,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,IAAI,CAAC;QACrD,WAAW,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,IAAI,CAAC;QACrD,cAAc,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,MAAM,gBAAgB,GACpB,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAChC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAChC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAEpD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO;YACL,GAAG,EAAE,QAAQ,SAAS,EAAE;YACxB,cAAc,EAAE,SAAS;YACzB,mBAAmB,EAAE,cAAc;YACnC,KAAK,EAAE,gBAAgB,IAAI,mBAAmB,IAAI,SAAS;YAC3D,WAAW,EAAE,mBAAmB;YAChC,0BAA0B,EAAE,QAAQ,KAAK,IAAI;SAC9C,CAAC;IACJ,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,EAAE,SAAS,kBAAkB,CAAC,gBAAgB,CAAC,EAAE;YACpD,cAAc,EAAE,EAAE;YAClB,mBAAmB,EAAE,EAAE;YACvB,KAAK,EAAE,gBAAgB;YACvB,WAAW,EAAE,kCAAkC;YAC/C,0BAA0B,EAAE,QAAQ,KAAK,IAAI;SAC9C,CAAC;IACJ,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,EAAE,QAAQ,kBAAkB,CAAC,gBAAgB,CAAC,EAAE;YACnD,cAAc,EAAE,EAAE;YAClB,mBAAmB,EAAE,EAAE;YACvB,KAAK,EAAE,gBAAgB;YACvB,WAAW,EAAE,mBAAmB;YAChC,0BAA0B,EAAE,QAAQ,KAAK,IAAI;SAC9C,CAAC;IACJ,CAAC;IAED,OAAO;QACL,GAAG,EAAE,EAAE;QACP,cAAc,EAAE,EAAE;QAClB,mBAAmB,EAAE,EAAE;QACvB,KAAK,EAAE,EAAE;QACT,WAAW,EAAE,SAAS;QACtB,0BAA0B,EAAE,QAAQ,KAAK,IAAI;KAC9C,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,GAA6B,EAC7B,GAAW,EACX,OAAgC,EAAE;IAElC,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;QAC/B,KAAK,EAAE,CAAC;QACR,GAAG,IAAI;KACR,CAAC;IACF,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;IACpB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,aAAa,CAAC,GAA6B;IAClD,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;SACtB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACtB,GAAG;QACH,GAAG,KAAK;KACT,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAmB,EACnB,OAA0B,EAC1B,QAA4B,EAC5B,cAAsB;IAEtB,MAAM,eAAe,GAAG,IAAI,GAAG,EAAuB,CAAC;IACvD,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3D,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;IACxD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;IACnD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;IACrD,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEnD,IAAI,yBAAyB,GAAG,CAAC,CAAC;IAClC,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,4BAA4B,GAAG,CAAC,CAAC;IACrC,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,cAAc,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC;QAClE,cAAc,CAAC,WAAW,EAAE,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC;QAEtD,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,MAAM,kBAAkB,GAAG,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC;YACpE,CAAC,CAAC,cAAc,CAAC,kBAAkB;YACnC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC,kBAAkB,CAAC;YACxE,CAAC,CAAC,kBAAkB,CAAC,kBAAkB;YACvC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,UAAU,GAAG,QAAQ,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAChG,MAAM,sBAAsB,GAAG,QAAQ,CAAC,cAAc,CAAC,sBAAsB,CAAC;YAC5E,CAAC,CAAC,cAAc,CAAC,sBAAsB;YACvC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,SAAS,GAAG,QAAQ,CAAC,sBAAsB,CAAC,sBAAsB,CAAC;YACvE,CAAC,CAAC,sBAAsB,CAAC,sBAAsB;YAC/C,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC;QACrE,cAAc,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;QACnD,IAAI,aAAa,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACzD,eAAe,IAAI,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,qBAAqB,GAAG,4BAA4B,CAAC,kBAAkB,CAAC,CAAC;QAC/E,MAAM,aAAa,GACjB,qBAAqB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,IAAI;YAC9D,qBAAqB,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI;YAC7D,EAAE,CAAC;QACL,MAAM,UAAU,GAAG,qBAAqB,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QACvF,IAAI,aAAa,EAAE,CAAC;YAClB,cAAc,CAAC,mBAAmB,EAAE,aAAa,EAAE;gBACjD,WAAW,EAAE,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;aAC1E,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,yBAAyB,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,UAAU,EAAE,CAAC;YACf,cAAc,CAAC,gBAAgB,EAAE,UAAU,EAAE;gBAC3C,WAAW,EAAE,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;aAC1E,CAAC,CAAC;QACL,CAAC;QAED,MAAM,KAAK,GAAG,qBAAqB,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAE;gBAC3C,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;YACH,cAAc,CAAC,iBAAiB,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,gBAAgB,IAAI,CAAC,CAAC;QACxB,CAAC;QAED,MAAM,OAAO,GAAG,uBAAuB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAC5E,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,EAAE;gBACzC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;gBAChD,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAC;YACH,cAAc,CAAC,mBAAmB,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,kBAAkB,IAAI,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;YACvC,4BAA4B,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,MAAM,oBAAoB,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,EAAE,IAAI,CAAC,GAAG;QAChB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAiC;KACpD,CAAC,CAAC,CAAC;IACJ,MAAM,iBAAiB,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvE,MAAM,EAAE,IAAI,CAAC,GAAG;QAChB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAiC;KACpD,CAAC,CAAC,CAAC;IACJ,MAAM,YAAY,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7D,eAAe,EAAE,IAAI,CAAC,GAAG;QACzB,KAAK,EAAE,IAAI,CAAC,KAAe;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAqB;KACxC,CAAC,CAAC,CAAC;IACJ,MAAM,cAAc,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACjE,WAAW,EAAE,IAAI,CAAC,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,KAAe;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,cAAwB;QAC7C,mBAAmB,EAAE,IAAI,CAAC,mBAA6B;QACvD,WAAW,EAAE,IAAI,CAAC,WAAqB;KACxC,CAAC,CAAC,CAAC;IACJ,MAAM,oBAAoB,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7E,eAAe,EAAE,IAAI,CAAC,GAAG;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,OAAO,EAAE;YACP,cAAc,EAAE,CAAC;YACjB,gBAAgB,EAAE,cAAc;YAChC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,WAAW,EAAE,OAAO,CAAC,UAAU;YAC/B,OAAO,EAAE,QAAQ,CAAC,MAAM;YACxB,iBAAiB,EAAE,QAAQ,CAAC,eAAe;YAC3C,kBAAkB,EAAE,IAAI,CAAC,MAAM;YAC/B,6BAA6B,EAAE,QAAQ,CAAC,yBAAyB;YACjE,kBAAkB,EAAE,MAAM,CAAC,WAAW,CACpC,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CACzE;YACD,+BAA+B,EAAE,WAAW,CAAC,IAAI;YACjD,oBAAoB,EAAE,mBAAmB,CAAC,IAAI;YAC9C,iBAAiB,EAAE,gBAAgB,CAAC,IAAI;YACxC,WAAW,EAAE,WAAW,CAAC,IAAI;YAC7B,iBAAiB,EAAE,eAAe;YAClC,kBAAkB,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM;YACzE,aAAa,EAAE,aAAa,CAAC,IAAI;YACjC,qBAAqB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM;YAClF,wBAAwB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM;YACtF,2BAA2B,EAAE,yBAAyB;YACtD,kBAAkB,EAAE,gBAAgB;YACpC,oBAAoB,EAAE,kBAAkB;YACxC,+BAA+B,EAAE,4BAA4B;YAC7D,kBAAkB,EAAE;gBAClB,oBAAoB,EAClB,+GAA+G;gBACjH,WAAW,EACT,2HAA2H;gBAC7H,iBAAiB,EAAE,8DAA8D;gBACjF,aAAa,EACX,gHAAgH;aACnH;SACF;QACD,oBAAoB;QACpB,iBAAiB;QACjB,YAAY;QACZ,cAAc;QACd,oBAAoB;QACpB,kBAAkB,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAClE,WAAW,EAAE,IAAI,CAAC,GAAG;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,oBAAoB,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtE,WAAW,EAAE,IAAI,CAAC,GAAG;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,oBAAoB,CAC3B,UAA2C,EAC3C,UAAuB;IAEvB,MAAM,IAAI,GAAG,UAAU,KAAK,IAAI,CAAC;IACjC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,iBAAiB,OAAO,CAAC,gBAAgB,EAAE,CACxF,CAAC;IACF,KAAK,CAAC,IAAI,CACR,IAAI;QACF,CAAC,CAAC,cAAc,OAAO,CAAC,KAAK,qBAAqB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;QACnF,CAAC,CAAC,kBAAkB,OAAO,CAAC,KAAK,qBAAqB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAC1F,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,oBAAoB,OAAO,OAAO,CAAC,kBAAkB,IAAI,CACvF,CAAC;IACF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,yBAAyB,OAAO,OAAO,CAAC,+BAA+B,IAAI,CACvG,CAAC;IACF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,mCAAmC,OAAO,OAAO,CAAC,oBAAoB,IAAI,CACxG,CAAC;IACF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,oCAAoC,OAAO,OAAO,CAAC,iBAAiB,IAAI,CACtG,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,OAAO,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,OAAO,OAAO,CAAC,iBAAiB,IAAI,CAAC,CAAC;IAC3F,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,OAAO,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;IACjF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE;QACxE,KAAK,CAAC,IAAI,CAAC,kBAAkB,SAAS,SAAS,KAAK,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KACzB,IAAI;QACF,CAAC,CAAC,4CAA4C;QAC9C,CAAC,CAAC,2GACN,EAAE,CACH,CAAC;IACF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KACxB,IAAI;QACF,CAAC,CAAC,+DAA+D;QACjE,CAAC,CAAC,0GACN,EAAE,CACH,CAAC;IACF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,KACjC,IAAI;QACF,CAAC,CAAC,2CAA2C;QAC7C,CAAC,CAAC,gEACN,EAAE,CACH,CAAC;IACF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAC1B,IAAI;QACF,CAAC,CAAC,8EAA8E;QAChF,CAAC,CAAC,0GACN,EAAE,CACH,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;IACvE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5B,UAAU,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CACjG,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACpD,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,CAC9F,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACtD,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,OAAO,qBAAqB,CAAC,QAAQ,CAAC;SACnC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;SACvC,MAAM,CAAC,CAAC,GAAG,EAAsB,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAyC;IAEzC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAAC,mCAAmC,EAAE;YACtD,IAAI,EAAE,gCAAgC;YACtC,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAChC,OAAO,CAAC,QAAQ,IAAI,iBAAiB,EACrC,aAAa,EACb,iCAAiC,CAClC,CAAC;IACF,MAAM,SAAS,GAAG,iBAAiB,CACjC,OAAO,CAAC,SAAS,IAAI,kBAAkB,EACvC,cAAc,EACd,+BAA+B,CAChC,CAAC;IACF,MAAM,UAAU,GAAG,iBAAiB,CAClC,OAAO,CAAC,UAAU,IAAI,mBAAmB,EACzC,sCAAsC,EACtC,mCAAmC,CACpC,CAAC;IAEF,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAC;IAC9F,MAAM,oBAAoB,GAAG,IAAI,CAAC,IAAI,CACpC,cAAc,EACd,QAAQ,EACR,kCAAkC,CACnC,CAAC;IACF,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE3C,IAAI,IAAmB,CAAC;IACxB,IAAI,QAA4B,CAAC;IAEjC,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,oBAAoB,CAAC,CAAC;QAC5D,QAAQ,GAAG;YACT,MAAM,EAAE,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC;YACjD,eAAe,EAAE,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,CAAC;YACpE,yBAAyB,EACvB,OAAO,QAAQ,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;SAC/E,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAK,KAAmB,CAAC;QAC5D,MAAM,WAAW,GAAG,0BAA0B,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,qBAAqB,GAAG,4BAA4B,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACnF,MAAM,MAAM,GACV,KAAK,KAAK,cAAc;YACtB,CAAC,CAAC,MAAM,oBAAoB,CAAC;gBACzB,GAAG;gBACH,SAAS;gBACT,SAAS;gBACT,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE;gBAC9B,UAAU;aACX,CAAC;YACJ,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC;YACtC,GAAG;YACH,SAAS;YACT,SAAS;YACT,UAAU;YACV,KAAK;YACL,UAAU;YACV,QAAQ;YACR,MAAM;SACP,CAAC,CAAC;QACH,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QACrB,QAAQ,GAAG;YACT,MAAM;YACN,eAAe,EAAE,WAAW,CAAC,qBAAqB,CAAC,KAAK,CAAC;YACzD,yBAAyB,EAAE,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;SACzD,CAAC;QAEF,sBAAsB,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QAC/C,iBAAiB,CAAC,oBAAoB,EAAE;YACtC,cAAc,EAAE,CAAC;YACjB,gBAAgB,EAAE,cAAc;YAChC,iBAAiB,EAAE,QAAQ,CAAC,eAAe;YAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM;YACxB,KAAK;YACL,WAAW,EAAE,UAAU;YACvB,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,QAAQ,CAAC,yBAAyB;SAC/C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAG,mBAAmB,CACpC,IAAI,EACJ;QACE,KAAK;QACL,UAAU;KACX,EACD,QAAQ,EACR,cAAc,CACf,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAC;IACvF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,sBAAsB,CAAC,CAAC;IACjF,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,8BAA8B,CAAC,CAAC;IAC7F,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,6BAA6B,CAAC,CAAC;IACvF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,EAAE,mCAAmC,CAAC,CAAC;IAE/F,iBAAiB,CAAC,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACnD,iBAAiB,CAAC,UAAU,EAAE;QAC5B,OAAO,EAAE,UAAU,CAAC,oBAAoB;QACxC,IAAI,EAAE,UAAU,CAAC,iBAAiB;KACnC,CAAC,CAAC;IACH,iBAAiB,CAAC,SAAS,EAAE;QAC3B,aAAa,EAAE,UAAU,CAAC,YAAY;QACtC,cAAc,EAAE,UAAU,CAAC,kBAAkB;KAC9C,CAAC,CAAC;IACH,iBAAiB,CAAC,WAAW,EAAE;QAC7B,eAAe,EAAE,UAAU,CAAC,cAAc;QAC1C,cAAc,EAAE,UAAU,CAAC,oBAAoB;KAChD,CAAC,CAAC;IACH,iBAAiB,CAAC,eAAe,EAAE,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACpE,iBAAiB,CAAC,UAAU,EAAE,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IACtE,iBAAiB,CAAC,YAAY,EAAE,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IAExE,OAAO;QACL,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,cAAc;QAChC,MAAM,EAAE,oCAAoC;QAC5C,OAAO,EAAE,cAAc;QACvB,KAAK;QACL,WAAW,EAAE,UAAU;QACvB,kBAAkB,EAAE,UAAU,CAAC,OAAO,CAAC,kBAAkB;QACzD,oBAAoB,EAAE,UAAU,CAAC,OAAO,CAAC,oBAAoB;QAC7D,iBAAiB,EAAE,UAAU,CAAC,OAAO,CAAC,iBAAiB;QACvD,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW;QAC3C,iBAAiB,EAAE,UAAU,CAAC,OAAO,CAAC,iBAAiB;QACvD,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,aAAa;QAC/C,KAAK,EAAE;YACL,iBAAiB,EAAE,oBAAoB;YACvC,aAAa,EAAE,gBAAgB;YAC/B,qBAAqB,EAAE,WAAW;YAClC,cAAc,EAAE,UAAU;YAC1B,aAAa,EAAE,SAAS;YACxB,eAAe,EAAE,WAAW;YAC5B,uBAAuB,EAAE,eAAe;YACxC,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,YAAY;SACxB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,mBAAmB;IACnB,WAAW;IACX,UAAU;IACV,4BAA4B;IAC5B,qBAAqB;IACrB,uBAAuB;IACvB,kBAAkB;IAClB,gBAAgB;IAChB,cAAc;IACd,WAAW;IACX,WAAW;IACX,gBAAgB;IAChB,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,iBAAiB;IACjB,oBAAoB;IACpB,oBAAoB;IACpB,oBAAoB;IACpB,iBAAiB;CAClB,CAAC","sourcesContent":["import path from 'node:path';\nimport {\n readJsonArtifact,\n readJsonLinesArtifact,\n writeJsonArtifact,\n writeJsonLinesArtifact,\n writeTextArtifact,\n} from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike, ResponseLike } from './http.js';\nimport { deriveSupabaseProjectBaseUrl, requireSupabaseRestRuntime } from './supabase-client.js';\nimport { resolveSupabaseUserSession } from './supabase-session.js';\nimport { redactEmail, requireUserApiKeyCredentials } from './user-api-key.js';\n\ntype JsonRecord = Record<string, unknown>;\n\nconst DEFAULT_STATE_CODES = [0, 100] as const;\nconst DEFAULT_PAGE_SIZE = 200;\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_RETRIES = 4;\n\ntype ProcessScopeStatisticsScope = 'visible' | 'current-user';\n\ntype SnapshotRow = {\n id: string;\n version: string;\n state_code: number | null;\n user_id: string | null;\n modified_at: string | null;\n model_id: string | null;\n json: JsonRecord;\n};\n\ntype ClassificationEntry = {\n level: number;\n text: string;\n};\n\ntype StatisticsMetadata = {\n userId: string | null;\n maskedUserEmail: string | null;\n totalRowsReportedByRemote: number | null;\n};\n\ntype StatisticsOptions = {\n scope: ProcessScopeStatisticsScope;\n stateCodes: number[];\n};\n\ntype CountRecord = {\n count: number;\n [key: string]: unknown;\n};\n\nexport type RunProcessScopeStatisticsOptions = {\n outDir: string;\n scope?: ProcessScopeStatisticsScope;\n stateCodes?: number[];\n pageSize?: number | null;\n reuseSnapshot?: boolean;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n maxRetries?: number;\n now?: Date;\n};\n\nexport type ProcessScopeStatisticsReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed_process_scope_statistics';\n out_dir: string;\n scope: ProcessScopeStatisticsScope;\n state_codes: number[];\n total_process_rows: number;\n domain_count_primary: number;\n domain_count_leaf: number;\n craft_count: number;\n unit_process_rows: number;\n product_count: number;\n files: {\n snapshot_manifest: string;\n snapshot_rows: string;\n process_scope_summary: string;\n domain_summary: string;\n craft_summary: string;\n product_summary: string;\n type_of_dataset_summary: string;\n report: string;\n report_zh: string;\n };\n};\n\ntype ProcessScopeStatisticsSummary = {\n schema_version: 1;\n generated_at_utc: string;\n scope: ProcessScopeStatisticsScope;\n state_codes: number[];\n user_id: string | null;\n masked_user_email: string | null;\n total_process_rows: number;\n total_rows_reported_by_remote: number | null;\n rows_by_state_code: Record<string, number>;\n distinct_visible_owner_user_ids: number;\n domain_count_primary: number;\n domain_count_leaf: number;\n craft_count: number;\n unit_process_rows: number;\n unit_process_share: number;\n product_count: number;\n products_with_flow_id: number;\n products_without_flow_id: number;\n rows_missing_classification: number;\n rows_missing_craft: number;\n rows_missing_product: number;\n rows_missing_reference_exchange: number;\n metric_definitions: Record<string, string>;\n};\n\ntype ProcessScopeStatisticsArtifacts = {\n summary: ProcessScopeStatisticsSummary;\n domainPrimarySummary: Array<{\n domain: string;\n count: number;\n sample_path?: string;\n }>;\n domainLeafSummary: Array<{\n domain: string;\n count: number;\n sample_path?: string;\n }>;\n craftSummary: Array<{\n craft_signature: string;\n label: string;\n count: number;\n source_kind: string;\n }>;\n productSummary: Array<{\n product_key: string;\n label: string;\n count: number;\n stable_flow_id: string;\n stable_flow_version: string;\n source_kind: string;\n }>;\n typeOfDataSetSummary: Array<{\n type_of_dataset: string;\n count: number;\n }>;\n craftSourceSummary: Array<{\n source_kind: string;\n count: number;\n }>;\n productSourceSummary: Array<{\n source_kind: string;\n count: number;\n }>;\n};\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimText(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction normalizeOptionalToken(value: unknown): string | null {\n const trimmed = trimText(value);\n return trimmed ? trimmed : null;\n}\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction toPositiveInteger(value: number | null | undefined, label: string, code: string): number {\n if (!Number.isInteger(value) || (value as number) <= 0) {\n throw new CliError(`Expected ${label} to be a positive integer.`, {\n code,\n exitCode: 2,\n });\n }\n return value as number;\n}\n\nfunction normalizeStateCodes(value: readonly number[] | undefined): number[] {\n if (!Array.isArray(value) || value.length === 0) {\n return [...DEFAULT_STATE_CODES];\n }\n\n const seen = new Set<number>();\n const normalized: number[] = [];\n for (const entry of value) {\n if (!Number.isInteger(entry) || entry < 0) {\n throw new CliError('Expected --state-codes to contain only non-negative integers.', {\n code: 'PROCESS_SCOPE_STATE_CODES_INVALID',\n exitCode: 2,\n });\n }\n if (!seen.has(entry)) {\n normalized.push(entry);\n seen.add(entry);\n }\n }\n if (normalized.length === 0) {\n throw new CliError('--state-codes must contain at least one state code.', {\n code: 'PROCESS_SCOPE_STATE_CODES_REQUIRED',\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nfunction ensureScope(value: string | undefined): ProcessScopeStatisticsScope {\n if (value === undefined || value === 'visible') {\n return 'visible';\n }\n if (value === 'current-user') {\n return 'current-user';\n }\n throw new CliError(\"Expected --scope to be either 'visible' or 'current-user'.\", {\n code: 'PROCESS_SCOPE_SCOPE_INVALID',\n exitCode: 2,\n });\n}\n\nasync function parseJsonResponse(response: ResponseLike, label: string): Promise<unknown> {\n const text = await response.text();\n const contentType = response.headers.get('content-type') ?? '';\n if (!text.trim()) {\n return null;\n }\n if (!contentType.includes('application/json')) {\n return text;\n }\n try {\n return JSON.parse(text);\n } catch (error) {\n throw new CliError(`${label} returned invalid JSON.`, {\n code: 'PROCESS_SCOPE_REMOTE_INVALID_JSON',\n exitCode: 1,\n details: String(error),\n });\n }\n}\n\nasync function fetchJsonWithRetry(options: {\n url: string;\n init: RequestInit;\n label: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n}): Promise<{ status: number; headers: Headers; body: unknown }> {\n let lastError: unknown = null;\n\n for (let attempt = 1; attempt <= options.maxRetries; attempt += 1) {\n try {\n const response = await options.fetchImpl(options.url, {\n ...options.init,\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n const body = await parseJsonResponse(response, options.label);\n if (!response.ok) {\n throw new CliError(`${options.label} failed with ${response.status}.`, {\n code: 'PROCESS_SCOPE_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: {\n status: response.status,\n body,\n url: options.url,\n },\n });\n }\n return {\n status: response.status,\n headers: new Headers({\n 'content-range': response.headers.get('content-range') ?? '',\n 'content-type': response.headers.get('content-type') ?? '',\n }),\n body,\n };\n } catch (error) {\n lastError = error;\n if (attempt >= options.maxRetries) {\n break;\n }\n await new Promise((resolve) => setTimeout(resolve, attempt * 1_500));\n }\n }\n\n if (lastError instanceof CliError) {\n throw lastError;\n }\n\n throw new CliError(`${options.label} failed after ${options.maxRetries} attempt(s).`, {\n code: 'PROCESS_SCOPE_REMOTE_REQUEST_FAILED',\n exitCode: 1,\n details: String(lastError),\n });\n}\n\nasync function resolveCurrentUserId(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n maxRetries: number;\n}): Promise<string> {\n const runtime = requireSupabaseRestRuntime(options.env);\n const session = await resolveSupabaseUserSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n const body = await fetchJsonWithRetry({\n url: `${deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl)}/auth/v1/user`,\n init: {\n method: 'GET',\n headers: {\n apikey: runtime.publishableKey,\n Authorization: `Bearer ${session.accessToken}`,\n Accept: 'application/json',\n },\n },\n label: 'supabase current-user lookup',\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n const userId = isRecord(body.body) ? normalizeOptionalToken(body.body.id) : null;\n if (!userId) {\n throw new CliError('Supabase current-user lookup succeeded without a user id.', {\n code: 'PROCESS_SCOPE_CURRENT_USER_ID_MISSING',\n exitCode: 1,\n });\n }\n return userId;\n}\n\nasync function fetchProcessRows(options: {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n timeoutMs: number;\n maxRetries: number;\n scope: ProcessScopeStatisticsScope;\n stateCodes: number[];\n pageSize: number;\n userId: string | null;\n}): Promise<{ rows: SnapshotRow[]; total: number | null }> {\n const runtime = requireSupabaseRestRuntime(options.env);\n const session = await resolveSupabaseUserSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n const rows: SnapshotRow[] = [];\n let total = 0;\n\n for (const stateCode of options.stateCodes) {\n let stateTotal: number | null = null;\n let cursorId = '';\n\n while (true) {\n const url = new URL(`${projectBaseUrl}/rest/v1/processes`);\n url.searchParams.set('select', 'id,version,state_code,user_id,modified_at,model_id,json');\n url.searchParams.set('state_code', `eq.${stateCode}`);\n if (options.scope === 'current-user') {\n url.searchParams.set('user_id', `eq.${options.userId ?? ''}`);\n }\n if (cursorId) {\n url.searchParams.set('id', `gt.${cursorId}`);\n }\n url.searchParams.set('order', 'id.asc');\n url.searchParams.set('limit', String(options.pageSize));\n\n const page = await fetchJsonWithRetry({\n url: url.toString(),\n init: {\n method: 'GET',\n headers: {\n apikey: runtime.publishableKey,\n Authorization: `Bearer ${session.accessToken}`,\n Accept: 'application/json',\n ...(stateTotal === null ? { Prefer: 'count=exact' } : {}),\n },\n },\n label: `process scope statistics page fetch (state_code=${stateCode})`,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n maxRetries: options.maxRetries,\n });\n\n const pageRows = Array.isArray(page.body) ? page.body : [];\n const normalizedRows = pageRows\n .map((row) => normalizeSnapshotRow(row))\n .filter((row): row is SnapshotRow => row !== null);\n rows.push(...normalizedRows);\n\n if (stateTotal === null) {\n const match = page.headers.get('content-range')?.match(/\\/(\\d+)$/u) ?? null;\n stateTotal = match ? Number.parseInt(match[1]!, 10) : null;\n if (stateTotal !== null) {\n total += stateTotal;\n }\n }\n\n if (normalizedRows.length < options.pageSize) {\n break;\n }\n\n const lastRow = normalizedRows[normalizedRows.length - 1]!;\n cursorId = lastRow.id;\n }\n }\n\n return {\n rows,\n total: total || null,\n };\n}\n\nfunction normalizeSnapshotRow(value: unknown): SnapshotRow | null {\n if (!isRecord(value)) {\n return null;\n }\n const id = normalizeOptionalToken(value.id);\n const version = normalizeOptionalToken(value.version);\n const payload = normalizePayload(value.json);\n if (!id || !version || !payload) {\n return null;\n }\n return {\n id,\n version,\n state_code: typeof value.state_code === 'number' ? value.state_code : null,\n user_id: normalizeOptionalToken(value.user_id),\n modified_at: normalizeOptionalToken(value.modified_at),\n model_id: normalizeOptionalToken(value.model_id),\n json: payload,\n };\n}\n\nfunction normalizePayload(value: unknown): JsonRecord | null {\n if (isRecord(value)) {\n return value;\n }\n if (typeof value === 'string' && value.trim()) {\n try {\n const parsed = JSON.parse(value);\n return isRecord(parsed) ? parsed : null;\n } catch {\n return null;\n }\n }\n return null;\n}\n\nfunction getLangList(value: unknown): JsonRecord[] {\n if (value === null || value === undefined || value === '') {\n return [];\n }\n if (Array.isArray(value)) {\n return value.filter((item): item is JsonRecord => isRecord(item));\n }\n if (isRecord(value)) {\n const langString = value['common:langString'];\n if (Array.isArray(langString)) {\n return langString.filter((item): item is JsonRecord => isRecord(item));\n }\n if (isRecord(langString)) {\n return [langString];\n }\n if (typeof value['#text'] === 'string' || typeof value['@xml:lang'] === 'string') {\n return [value];\n }\n }\n if (typeof value === 'string') {\n return [{ '@xml:lang': 'en', '#text': value }];\n }\n return [];\n}\n\nfunction getLangText(value: unknown, lang: string | null): string {\n const list = getLangList(value);\n const exact =\n lang === null\n ? null\n : list.find(\n (item) =>\n trimText(item['@xml:lang']).toLowerCase() === lang.toLowerCase() &&\n trimText(item['#text']),\n );\n const fallback = list.find((item) => trimText(item['#text']));\n return trimText((exact ?? fallback)?.['#text']);\n}\n\nfunction getAnyLangText(value: unknown): string {\n return getLangText(value, null);\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (value === null || value === undefined || value === '') {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n\nfunction extractClassificationEntries(dataSetInformation: JsonRecord): ClassificationEntry[] {\n const classes = asArray(\n (dataSetInformation.classificationInformation as JsonRecord | undefined)?.[\n 'common:classification'\n ] &&\n (\n (dataSetInformation.classificationInformation as JsonRecord)['common:classification'] as\n | JsonRecord\n | undefined\n )?.['common:class'],\n );\n\n return classes\n .map((entry) => {\n if (!isRecord(entry)) {\n return null;\n }\n const level = Number.parseInt(trimText(entry['@level']) || '0', 10);\n const text = trimText(entry['#text']);\n if (!text) {\n return null;\n }\n return { level, text };\n })\n .filter((entry): entry is ClassificationEntry => entry !== null)\n .sort((left, right) => left.level - right.level);\n}\n\nfunction normalizeSignature(text: string): string {\n return trimText(text)\n .normalize('NFKC')\n .toLowerCase()\n .replace(/[\\u3000\\u00a0]/gu, ' ')\n .replace(/[,,;;::()()[\\]{}<>|/\\\\]+/gu, ' ')\n .replace(/\\s+/gu, ' ')\n .trim();\n}\n\nfunction firstClause(text: string): string {\n const normalized = trimText(text);\n if (!normalized) {\n return '';\n }\n const [first] = normalized.split(/[.;;。]/u);\n return first.trim();\n}\n\nfunction renderProcessName(name: JsonRecord): string {\n const parts = [\n getLangText(name.baseName, 'en') ||\n getLangText(name.baseName, 'zh') ||\n getAnyLangText(name.baseName),\n getLangText(name.treatmentStandardsRoutes, 'en') ||\n getLangText(name.treatmentStandardsRoutes, 'zh') ||\n getAnyLangText(name.treatmentStandardsRoutes),\n getLangText(name.mixAndLocationTypes, 'en') ||\n getLangText(name.mixAndLocationTypes, 'zh') ||\n getAnyLangText(name.mixAndLocationTypes),\n getLangText(name.functionalUnitFlowProperties, 'en') ||\n getLangText(name.functionalUnitFlowProperties, 'zh') ||\n getAnyLangText(name.functionalUnitFlowProperties),\n ].filter((part) => trimText(part));\n\n return parts.join('; ');\n}\n\nfunction extractCraftCandidate(\n dataSetInformation: JsonRecord,\n technology: JsonRecord,\n): {\n source_kind: string;\n label: string;\n signature: string;\n} {\n const name = isRecord(dataSetInformation.name) ? dataSetInformation.name : {};\n const candidates = [\n {\n source_kind: 'treatmentStandardsRoutes',\n label:\n getLangText(name.treatmentStandardsRoutes, 'en') ||\n getLangText(name.treatmentStandardsRoutes, 'zh') ||\n getAnyLangText(name.treatmentStandardsRoutes),\n },\n {\n source_kind: 'technologyDescriptionAndIncludedProcesses',\n label:\n firstClause(getLangText(technology.technologyDescriptionAndIncludedProcesses, 'en')) ||\n firstClause(getLangText(technology.technologyDescriptionAndIncludedProcesses, 'zh')) ||\n firstClause(getAnyLangText(technology.technologyDescriptionAndIncludedProcesses)),\n },\n {\n source_kind: 'baseName',\n label:\n getLangText(name.baseName, 'en') ||\n getLangText(name.baseName, 'zh') ||\n getAnyLangText(name.baseName),\n },\n ];\n\n for (const candidate of candidates) {\n if (trimText(candidate.label)) {\n return {\n ...candidate,\n signature: normalizeSignature(candidate.label),\n };\n }\n }\n\n return {\n source_kind: 'missing',\n label: '',\n signature: '',\n };\n}\n\nfunction extractReferenceProduct(\n processDataSet: JsonRecord,\n dataSetInformation: JsonRecord,\n): {\n key: string;\n stable_flow_id: string;\n stable_flow_version: string;\n label: string;\n source_kind: string;\n missing_reference_exchange: boolean;\n} {\n const processInformation = isRecord(processDataSet.processInformation)\n ? processDataSet.processInformation\n : {};\n const quantRef = isRecord(processInformation.quantitativeReference)\n ? processInformation.quantitativeReference\n : {};\n const refInternalId = trimText(quantRef.referenceToReferenceFlow);\n const exchangesBlock = isRecord(processDataSet.exchanges) ? processDataSet.exchanges : {};\n const exchanges = asArray(exchangesBlock.exchange);\n const refExchange = exchanges.find(\n (exchange) => isRecord(exchange) && trimText(exchange['@dataSetInternalID']) === refInternalId,\n );\n const exchange = isRecord(refExchange) ? refExchange : null;\n const flowRef =\n exchange && isRecord(exchange.referenceToFlowDataSet) ? exchange.referenceToFlowDataSet : {};\n\n const flowRefId = trimText(flowRef['@refObjectId']);\n const flowRefVersion = trimText(flowRef['@version']);\n const shortDescription =\n getLangText(flowRef['common:shortDescription'], 'en') ||\n getLangText(flowRef['common:shortDescription'], 'zh') ||\n getAnyLangText(flowRef['common:shortDescription']);\n const name = isRecord(dataSetInformation.name) ? dataSetInformation.name : {};\n const fallbackBaseName =\n getLangText(name.baseName, 'en') ||\n getLangText(name.baseName, 'zh') ||\n getAnyLangText(name.baseName);\n const fallbackProcessName = renderProcessName(name);\n\n if (flowRefId) {\n return {\n key: `flow:${flowRefId}`,\n stable_flow_id: flowRefId,\n stable_flow_version: flowRefVersion,\n label: shortDescription || fallbackProcessName || flowRefId,\n source_kind: 'reference_flow_id',\n missing_reference_exchange: exchange === null,\n };\n }\n\n if (shortDescription) {\n return {\n key: `label:${normalizeSignature(shortDescription)}`,\n stable_flow_id: '',\n stable_flow_version: '',\n label: shortDescription,\n source_kind: 'reference_flow_short_description',\n missing_reference_exchange: exchange === null,\n };\n }\n\n if (fallbackBaseName) {\n return {\n key: `base:${normalizeSignature(fallbackBaseName)}`,\n stable_flow_id: '',\n stable_flow_version: '',\n label: fallbackBaseName,\n source_kind: 'process_base_name',\n missing_reference_exchange: exchange === null,\n };\n }\n\n return {\n key: '',\n stable_flow_id: '',\n stable_flow_version: '',\n label: '',\n source_kind: 'missing',\n missing_reference_exchange: exchange === null,\n };\n}\n\nfunction incrementCount(\n map: Map<string, CountRecord>,\n key: string,\n seed: Record<string, unknown> = {},\n): void {\n const existing = map.get(key) ?? {\n count: 0,\n ...seed,\n };\n existing.count += 1;\n map.set(key, existing);\n}\n\nfunction toSortedArray(map: Map<string, CountRecord>): Array<{ key: string } & CountRecord> {\n return [...map.entries()]\n .map(([key, value]) => ({\n key,\n ...value,\n }))\n .sort((left, right) => right.count - left.count || left.key.localeCompare(right.key));\n}\n\nfunction calculateStatistics(\n rows: SnapshotRow[],\n options: StatisticsOptions,\n metadata: StatisticsMetadata,\n generatedAtUtc: string,\n): ProcessScopeStatisticsArtifacts {\n const stateCodeCounts = new Map<string, CountRecord>();\n const typeOfDataSetCounts = new Map<string, CountRecord>();\n const domainPrimaryCounts = new Map<string, CountRecord>();\n const domainLeafCounts = new Map<string, CountRecord>();\n const craftCounts = new Map<string, CountRecord>();\n const craftSourceCounts = new Map<string, CountRecord>();\n const productCounts = new Map<string, CountRecord>();\n const productSourceCounts = new Map<string, CountRecord>();\n const ownerCounts = new Map<string, CountRecord>();\n\n let rowsMissingClassification = 0;\n let rowsMissingCraft = 0;\n let rowsMissingProduct = 0;\n let rowsMissingReferenceExchange = 0;\n let unitProcessRows = 0;\n\n for (const row of rows) {\n incrementCount(stateCodeCounts, String(row.state_code ?? 'null'));\n incrementCount(ownerCounts, row.user_id ?? 'missing');\n\n const processDataSet = isRecord(row.json.processDataSet) ? row.json.processDataSet : {};\n const processInformation = isRecord(processDataSet.processInformation)\n ? processDataSet.processInformation\n : {};\n const dataSetInformation = isRecord(processInformation.dataSetInformation)\n ? processInformation.dataSetInformation\n : {};\n const technology = isRecord(processInformation.technology) ? processInformation.technology : {};\n const modellingAndValidation = isRecord(processDataSet.modellingAndValidation)\n ? processDataSet.modellingAndValidation\n : {};\n const lciMethod = isRecord(modellingAndValidation.LCIMethodAndAllocation)\n ? modellingAndValidation.LCIMethodAndAllocation\n : {};\n\n const typeOfDataSet = trimText(lciMethod.typeOfDataSet) || 'missing';\n incrementCount(typeOfDataSetCounts, typeOfDataSet);\n if (typeOfDataSet.toLowerCase().includes('unit process')) {\n unitProcessRows += 1;\n }\n\n const classificationEntries = extractClassificationEntries(dataSetInformation);\n const primaryDomain =\n classificationEntries.find((entry) => entry.level === 1)?.text ??\n classificationEntries[classificationEntries.length - 1]?.text ??\n '';\n const leafDomain = classificationEntries[classificationEntries.length - 1]?.text ?? '';\n if (primaryDomain) {\n incrementCount(domainPrimaryCounts, primaryDomain, {\n sample_path: classificationEntries.map((entry) => entry.text).join(' > '),\n });\n } else {\n rowsMissingClassification += 1;\n }\n if (leafDomain) {\n incrementCount(domainLeafCounts, leafDomain, {\n sample_path: classificationEntries.map((entry) => entry.text).join(' > '),\n });\n }\n\n const craft = extractCraftCandidate(dataSetInformation, technology);\n if (craft.signature) {\n incrementCount(craftCounts, craft.signature, {\n label: craft.label,\n source_kind: craft.source_kind,\n });\n incrementCount(craftSourceCounts, craft.source_kind);\n } else {\n rowsMissingCraft += 1;\n }\n\n const product = extractReferenceProduct(processDataSet, dataSetInformation);\n if (product.key) {\n incrementCount(productCounts, product.key, {\n label: product.label,\n stable_flow_id: product.stable_flow_id,\n stable_flow_version: product.stable_flow_version,\n source_kind: product.source_kind,\n });\n incrementCount(productSourceCounts, product.source_kind);\n } else {\n rowsMissingProduct += 1;\n }\n if (product.missing_reference_exchange) {\n rowsMissingReferenceExchange += 1;\n }\n }\n\n const domainPrimarySummary = toSortedArray(domainPrimaryCounts).map((item) => ({\n domain: item.key,\n count: item.count,\n sample_path: item.sample_path as string | undefined,\n }));\n const domainLeafSummary = toSortedArray(domainLeafCounts).map((item) => ({\n domain: item.key,\n count: item.count,\n sample_path: item.sample_path as string | undefined,\n }));\n const craftSummary = toSortedArray(craftCounts).map((item) => ({\n craft_signature: item.key,\n label: item.label as string,\n count: item.count,\n source_kind: item.source_kind as string,\n }));\n const productSummary = toSortedArray(productCounts).map((item) => ({\n product_key: item.key,\n label: item.label as string,\n count: item.count,\n stable_flow_id: item.stable_flow_id as string,\n stable_flow_version: item.stable_flow_version as string,\n source_kind: item.source_kind as string,\n }));\n const typeOfDataSetSummary = toSortedArray(typeOfDataSetCounts).map((item) => ({\n type_of_dataset: item.key,\n count: item.count,\n }));\n\n return {\n summary: {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n scope: options.scope,\n state_codes: options.stateCodes,\n user_id: metadata.userId,\n masked_user_email: metadata.maskedUserEmail,\n total_process_rows: rows.length,\n total_rows_reported_by_remote: metadata.totalRowsReportedByRemote,\n rows_by_state_code: Object.fromEntries(\n [...stateCodeCounts.entries()].map(([key, value]) => [key, value.count]),\n ),\n distinct_visible_owner_user_ids: ownerCounts.size,\n domain_count_primary: domainPrimaryCounts.size,\n domain_count_leaf: domainLeafCounts.size,\n craft_count: craftCounts.size,\n unit_process_rows: unitProcessRows,\n unit_process_share: rows.length === 0 ? 0 : unitProcessRows / rows.length,\n product_count: productCounts.size,\n products_with_flow_id: productSummary.filter((item) => item.stable_flow_id).length,\n products_without_flow_id: productSummary.filter((item) => !item.stable_flow_id).length,\n rows_missing_classification: rowsMissingClassification,\n rows_missing_craft: rowsMissingCraft,\n rows_missing_product: rowsMissingProduct,\n rows_missing_reference_exchange: rowsMissingReferenceExchange,\n metric_definitions: {\n domain_count_primary:\n 'Unique level-1 classification text; fallback to the deepest available classification when level 1 is missing.',\n craft_count:\n 'Unique normalized craft or route signatures derived from treatmentStandardsRoutes, or fallback technology/base-name text.',\n unit_process_rows: 'Rows whose typeOfDataSet contains the phrase \"Unit process\".',\n product_count:\n 'Unique reference products, keyed by reference flow ID when present and by normalized label fallback otherwise.',\n },\n },\n domainPrimarySummary,\n domainLeafSummary,\n craftSummary,\n productSummary,\n typeOfDataSetSummary,\n craftSourceSummary: toSortedArray(craftSourceCounts).map((item) => ({\n source_kind: item.key,\n count: item.count,\n })),\n productSourceSummary: toSortedArray(productSourceCounts).map((item) => ({\n source_kind: item.key,\n count: item.count,\n })),\n };\n}\n\nfunction escapePipe(value: unknown): string {\n return String(value ?? '').replace(/\\|/gu, '\\\\|');\n}\n\nfunction renderMarkdownReport(\n statistics: ProcessScopeStatisticsArtifacts,\n reportLang: 'en' | 'zh',\n): string {\n const isZh = reportLang === 'zh';\n const summary = statistics.summary;\n const lines: string[] = [];\n\n lines.push(isZh ? '# Process 覆盖统计' : '# Process Scope Statistics');\n lines.push('');\n lines.push(\n isZh ? `统计时间:${summary.generated_at_utc}` : `Generated at: ${summary.generated_at_utc}`,\n );\n lines.push(\n isZh\n ? `范围:\\`scope=${summary.scope}\\`, \\`state_codes=${summary.state_codes.join(',')}\\``\n : `Scope: \\`scope=${summary.scope}\\`, \\`state_codes=${summary.state_codes.join(',')}\\``,\n );\n lines.push('');\n lines.push(isZh ? '## 核心结果' : '## Headline Metrics');\n lines.push('');\n lines.push(\n `- ${isZh ? '总 process 行数' : 'Total process rows'}: \\`${summary.total_process_rows}\\``,\n );\n lines.push(\n `- ${isZh ? '可见 owner 数' : 'Distinct visible owners'}: \\`${summary.distinct_visible_owner_user_ids}\\``,\n );\n lines.push(\n `- ${isZh ? '领域数量(一级分类口径)' : 'Domain count (primary definition)'}: \\`${summary.domain_count_primary}\\``,\n );\n lines.push(\n `- ${isZh ? '领域数量(叶子分类口径)' : 'Domain count (leaf classification)'}: \\`${summary.domain_count_leaf}\\``,\n );\n lines.push(`- ${isZh ? '工艺/路线数量' : 'Craft / route count'}: \\`${summary.craft_count}\\``);\n lines.push(`- ${isZh ? '单元过程行数' : 'Unit-process rows'}: \\`${summary.unit_process_rows}\\``);\n lines.push(`- ${isZh ? '产品数量' : 'Product count'}: \\`${summary.product_count}\\``);\n lines.push('');\n lines.push(isZh ? '## 状态分布' : '## State-code Distribution');\n lines.push('');\n Object.entries(summary.rows_by_state_code).forEach(([stateCode, count]) => {\n lines.push(`- \\`state_code=${stateCode}\\`: \\`${count}\\``);\n });\n lines.push('');\n lines.push(isZh ? '## 统计口径' : '## Metric Definitions');\n lines.push('');\n lines.push(\n `- ${isZh ? '领域' : 'Domain'}: ${\n isZh\n ? '优先使用 classification level=1;若缺失,则回退到最深层分类。'\n : 'Prefer classification level 1; fall back to the deepest available classification when level 1 is missing.'\n }`,\n );\n lines.push(\n `- ${isZh ? '工艺' : 'Craft'}: ${\n isZh\n ? '优先使用 `treatmentStandardsRoutes`;为空时回退到技术说明首句,再回退到 `baseName`。'\n : 'Prefer `treatmentStandardsRoutes`; fall back to the first clause of technology text, then to `baseName`.'\n }`,\n );\n lines.push(\n `- ${isZh ? '单元过程' : 'Unit process'}: ${\n isZh\n ? '以 `typeOfDataSet` 是否包含 `Unit process` 为准。'\n : 'Rows are counted when `typeOfDataSet` contains `Unit process`.'\n }`,\n );\n lines.push(\n `- ${isZh ? '产品' : 'Product'}: ${\n isZh\n ? '优先按 reference flow UUID 聚合;缺失时回退到 reference flow 短描述,再回退到 process base name。'\n : 'Prefer reference-flow UUIDs; fall back to reference-flow short descriptions, then to process base names.'\n }`,\n );\n lines.push('');\n\n lines.push(isZh ? '## Top 领域' : '## Top Domains');\n lines.push('');\n lines.push(`| ${isZh ? '领域' : 'Domain'} | ${isZh ? '数量' : 'Count'} |`);\n lines.push('| --- | --- |');\n statistics.domainPrimarySummary.slice(0, 15).forEach((item) => {\n lines.push(`| ${escapePipe(item.domain)} | ${item.count} |`);\n });\n lines.push('');\n\n lines.push(isZh ? '## Top 工艺/路线' : '## Top Crafts / Routes');\n lines.push('');\n lines.push(\n `| ${isZh ? '工艺/路线' : 'Craft / Route'} | ${isZh ? '数量' : 'Count'} | ${isZh ? '来源' : 'Source'} |`,\n );\n lines.push('| --- | --- | --- |');\n statistics.craftSummary.slice(0, 15).forEach((item) => {\n lines.push(`| ${escapePipe(item.label)} | ${item.count} | ${item.source_kind} |`);\n });\n lines.push('');\n\n lines.push(isZh ? '## Top 产品' : '## Top Products');\n lines.push('');\n lines.push(\n `| ${isZh ? '产品' : 'Product'} | ${isZh ? '数量' : 'Count'} | ${isZh ? '标识来源' : 'Key source'} |`,\n );\n lines.push('| --- | --- | --- |');\n statistics.productSummary.slice(0, 15).forEach((item) => {\n lines.push(`| ${escapePipe(item.label)} | ${item.count} | ${item.source_kind} |`);\n });\n lines.push('');\n\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction readSnapshotRows(filePath: string): SnapshotRow[] {\n return readJsonLinesArtifact(filePath)\n .map((row) => normalizeSnapshotRow(row))\n .filter((row): row is SnapshotRow => row !== null);\n}\n\nfunction readSnapshotManifest(filePath: string): JsonRecord | null {\n const value = readJsonArtifact(filePath);\n return isRecord(value) ? value : null;\n}\n\nexport async function runProcessScopeStatistics(\n options: RunProcessScopeStatisticsOptions,\n): Promise<ProcessScopeStatisticsReport> {\n const outDir = trimText(options.outDir);\n if (!outDir) {\n throw new CliError('Missing required --out-dir value.', {\n code: 'PROCESS_SCOPE_OUT_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n const scope = ensureScope(options.scope);\n const stateCodes = normalizeStateCodes(options.stateCodes);\n const pageSize = toPositiveInteger(\n options.pageSize ?? DEFAULT_PAGE_SIZE,\n '--page-size',\n 'PROCESS_SCOPE_PAGE_SIZE_INVALID',\n );\n const timeoutMs = toPositiveInteger(\n options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n '--timeout-ms',\n 'PROCESS_SCOPE_TIMEOUT_INVALID',\n );\n const maxRetries = toPositiveInteger(\n options.maxRetries ?? DEFAULT_MAX_RETRIES,\n 'process scope statistics retry count',\n 'PROCESS_SCOPE_MAX_RETRIES_INVALID',\n );\n\n const resolvedOutDir = path.resolve(outDir);\n const snapshotRowsPath = path.join(resolvedOutDir, 'inputs', 'processes.snapshot.rows.jsonl');\n const snapshotManifestPath = path.join(\n resolvedOutDir,\n 'inputs',\n 'processes.snapshot.manifest.json',\n );\n const generatedAtUtc = nowIso(options.now);\n\n let rows: SnapshotRow[];\n let metadata: StatisticsMetadata;\n\n if (options.reuseSnapshot) {\n rows = readSnapshotRows(snapshotRowsPath);\n const manifest = readSnapshotManifest(snapshotManifestPath);\n metadata = {\n userId: normalizeOptionalToken(manifest?.user_id),\n maskedUserEmail: normalizeOptionalToken(manifest?.masked_user_email),\n totalRowsReportedByRemote:\n typeof manifest?.total_rows === 'number' ? manifest.total_rows : rows.length,\n };\n } else {\n const env = options.env ?? process.env;\n const fetchImpl = options.fetchImpl ?? (fetch as FetchLike);\n const restRuntime = requireSupabaseRestRuntime(env);\n const userApiKeyCredentials = requireUserApiKeyCredentials(restRuntime.userApiKey);\n const userId =\n scope === 'current-user'\n ? await resolveCurrentUserId({\n env,\n fetchImpl,\n timeoutMs,\n now: options.now ?? new Date(),\n maxRetries,\n })\n : null;\n const snapshot = await fetchProcessRows({\n env,\n fetchImpl,\n timeoutMs,\n maxRetries,\n scope,\n stateCodes,\n pageSize,\n userId,\n });\n rows = snapshot.rows;\n metadata = {\n userId,\n maskedUserEmail: redactEmail(userApiKeyCredentials.email),\n totalRowsReportedByRemote: snapshot.total ?? rows.length,\n };\n\n writeJsonLinesArtifact(snapshotRowsPath, rows);\n writeJsonArtifact(snapshotManifestPath, {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n masked_user_email: metadata.maskedUserEmail,\n user_id: metadata.userId,\n scope,\n state_codes: stateCodes,\n page_size: pageSize,\n total_rows: metadata.totalRowsReportedByRemote,\n });\n }\n\n const statistics = calculateStatistics(\n rows,\n {\n scope,\n stateCodes,\n },\n metadata,\n generatedAtUtc,\n );\n\n const summaryPath = path.join(resolvedOutDir, 'outputs', 'process-scope-summary.json');\n const domainPath = path.join(resolvedOutDir, 'outputs', 'domain-summary.json');\n const craftPath = path.join(resolvedOutDir, 'outputs', 'craft-summary.json');\n const productPath = path.join(resolvedOutDir, 'outputs', 'product-summary.json');\n const datasetTypePath = path.join(resolvedOutDir, 'outputs', 'type-of-dataset-summary.json');\n const reportPath = path.join(resolvedOutDir, 'reports', 'process-scope-statistics.md');\n const reportZhPath = path.join(resolvedOutDir, 'reports', 'process-scope-statistics.zh-CN.md');\n\n writeJsonArtifact(summaryPath, statistics.summary);\n writeJsonArtifact(domainPath, {\n primary: statistics.domainPrimarySummary,\n leaf: statistics.domainLeafSummary,\n });\n writeJsonArtifact(craftPath, {\n craft_summary: statistics.craftSummary,\n source_summary: statistics.craftSourceSummary,\n });\n writeJsonArtifact(productPath, {\n product_summary: statistics.productSummary,\n source_summary: statistics.productSourceSummary,\n });\n writeJsonArtifact(datasetTypePath, statistics.typeOfDataSetSummary);\n writeTextArtifact(reportPath, renderMarkdownReport(statistics, 'en'));\n writeTextArtifact(reportZhPath, renderMarkdownReport(statistics, 'zh'));\n\n return {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n status: 'completed_process_scope_statistics',\n out_dir: resolvedOutDir,\n scope,\n state_codes: stateCodes,\n total_process_rows: statistics.summary.total_process_rows,\n domain_count_primary: statistics.summary.domain_count_primary,\n domain_count_leaf: statistics.summary.domain_count_leaf,\n craft_count: statistics.summary.craft_count,\n unit_process_rows: statistics.summary.unit_process_rows,\n product_count: statistics.summary.product_count,\n files: {\n snapshot_manifest: snapshotManifestPath,\n snapshot_rows: snapshotRowsPath,\n process_scope_summary: summaryPath,\n domain_summary: domainPath,\n craft_summary: craftPath,\n product_summary: productPath,\n type_of_dataset_summary: datasetTypePath,\n report: reportPath,\n report_zh: reportZhPath,\n },\n };\n}\n\nexport const __testInternals = {\n calculateStatistics,\n ensureScope,\n escapePipe,\n extractClassificationEntries,\n extractCraftCandidate,\n extractReferenceProduct,\n fetchJsonWithRetry,\n fetchProcessRows,\n getAnyLangText,\n getLangList,\n getLangText,\n normalizePayload,\n normalizeSignature,\n normalizeSnapshotRow,\n normalizeStateCodes,\n parseJsonResponse,\n readSnapshotManifest,\n resolveCurrentUserId,\n renderMarkdownReport,\n toPositiveInteger,\n};\n"]}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
|
|
4
|
+
import { CliError } from './errors.js';
|
|
5
|
+
import { validateProcessPayload, } from './process-payload-validation.js';
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function trimText(value) {
|
|
10
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
11
|
+
}
|
|
12
|
+
function requiredNonEmpty(value, label, code) {
|
|
13
|
+
const normalized = value.trim();
|
|
14
|
+
if (!normalized) {
|
|
15
|
+
throw new CliError(`Missing required ${label}.`, {
|
|
16
|
+
code,
|
|
17
|
+
exitCode: 2,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return normalized;
|
|
21
|
+
}
|
|
22
|
+
function readRowsFile(filePath) {
|
|
23
|
+
if (!existsSync(filePath)) {
|
|
24
|
+
throw new CliError(`Rows file not found: ${filePath}`, {
|
|
25
|
+
code: 'PROCESS_VERIFY_ROWS_FILE_NOT_FOUND',
|
|
26
|
+
exitCode: 2,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const text = readFileSync(filePath, 'utf8');
|
|
30
|
+
if (filePath.toLowerCase().endsWith('.jsonl')) {
|
|
31
|
+
return text
|
|
32
|
+
.split(/\r?\n/u)
|
|
33
|
+
.map((line) => line.trim())
|
|
34
|
+
.filter(Boolean)
|
|
35
|
+
.map((line, index) => {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(line);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new CliError(`Rows file contains invalid JSONL at line ${index + 1}: ${filePath}`, {
|
|
41
|
+
code: 'PROCESS_VERIFY_ROWS_FILE_INVALID_JSONL',
|
|
42
|
+
exitCode: 2,
|
|
43
|
+
details: String(error),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(text);
|
|
50
|
+
if (Array.isArray(parsed)) {
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
if (isRecord(parsed) && Array.isArray(parsed.rows)) {
|
|
54
|
+
return parsed.rows;
|
|
55
|
+
}
|
|
56
|
+
return [parsed];
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new CliError(`Rows file is not valid JSON: ${filePath}`, {
|
|
60
|
+
code: 'PROCESS_VERIFY_ROWS_FILE_INVALID_JSON',
|
|
61
|
+
exitCode: 2,
|
|
62
|
+
details: String(error),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function getPayload(row) {
|
|
67
|
+
if (isRecord(row) && isRecord(row.process)) {
|
|
68
|
+
return row.process;
|
|
69
|
+
}
|
|
70
|
+
if (isRecord(row) && isRecord(row.json_ordered)) {
|
|
71
|
+
return row.json_ordered;
|
|
72
|
+
}
|
|
73
|
+
if (isRecord(row) && isRecord(row.json)) {
|
|
74
|
+
return row.json;
|
|
75
|
+
}
|
|
76
|
+
if (isRecord(row)) {
|
|
77
|
+
return row;
|
|
78
|
+
}
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
function firstNonEmpty(...values) {
|
|
82
|
+
for (const value of values) {
|
|
83
|
+
const normalized = trimText(value);
|
|
84
|
+
if (normalized) {
|
|
85
|
+
return normalized;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
function getIdentity(row, payload, index) {
|
|
91
|
+
const root = isRecord(payload.processDataSet) ? payload.processDataSet : payload;
|
|
92
|
+
const processInformation = isRecord(root.processInformation) ? root.processInformation : {};
|
|
93
|
+
const dataSetInformation = isRecord(processInformation.dataSetInformation)
|
|
94
|
+
? processInformation.dataSetInformation
|
|
95
|
+
: {};
|
|
96
|
+
const administrativeInformation = isRecord(root.administrativeInformation)
|
|
97
|
+
? root.administrativeInformation
|
|
98
|
+
: {};
|
|
99
|
+
const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
|
|
100
|
+
? administrativeInformation.publicationAndOwnership
|
|
101
|
+
: {};
|
|
102
|
+
return {
|
|
103
|
+
row_index: index,
|
|
104
|
+
id: firstNonEmpty(isRecord(row) ? row.id : null, isRecord(row) ? row.process_id : null, dataSetInformation['common:UUID'], payload.id, payload['@id']),
|
|
105
|
+
version: firstNonEmpty(isRecord(row) ? row.version : null, publicationAndOwnership['common:dataSetVersion'], payload.version, payload['@version']),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function getLangList(value) {
|
|
109
|
+
if (value === null || value === undefined || value === '') {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
if (Array.isArray(value)) {
|
|
113
|
+
return value.filter((entry) => isRecord(entry));
|
|
114
|
+
}
|
|
115
|
+
if (isRecord(value)) {
|
|
116
|
+
const langString = value['common:langString'];
|
|
117
|
+
if (Array.isArray(langString)) {
|
|
118
|
+
return langString.filter((entry) => isRecord(entry));
|
|
119
|
+
}
|
|
120
|
+
if (isRecord(langString)) {
|
|
121
|
+
return [langString];
|
|
122
|
+
}
|
|
123
|
+
if (value['#text'] !== undefined || value['@xml:lang'] !== undefined) {
|
|
124
|
+
return [value];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (typeof value === 'string') {
|
|
128
|
+
return [{ '@xml:lang': 'en', '#text': value }];
|
|
129
|
+
}
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
function getLangText(value, lang) {
|
|
133
|
+
const entries = getLangList(value);
|
|
134
|
+
if (lang) {
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
if (trimText(entry['@xml:lang']).toLowerCase() === lang.toLowerCase() &&
|
|
137
|
+
trimText(entry['#text'])) {
|
|
138
|
+
return trimText(entry['#text']);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const entry of entries) {
|
|
143
|
+
if (trimText(entry['#text'])) {
|
|
144
|
+
return trimText(entry['#text']);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return '';
|
|
148
|
+
}
|
|
149
|
+
function hasOwn(objectValue, key) {
|
|
150
|
+
return Object.prototype.hasOwnProperty.call(objectValue, key);
|
|
151
|
+
}
|
|
152
|
+
function summarizeNameFields(payload) {
|
|
153
|
+
const root = isRecord(payload.processDataSet) ? payload.processDataSet : payload;
|
|
154
|
+
const processInformation = isRecord(root.processInformation) ? root.processInformation : {};
|
|
155
|
+
const dataSetInformation = isRecord(processInformation.dataSetInformation)
|
|
156
|
+
? processInformation.dataSetInformation
|
|
157
|
+
: {};
|
|
158
|
+
const name = isRecord(dataSetInformation.name) ? dataSetInformation.name : {};
|
|
159
|
+
const fieldNames = [
|
|
160
|
+
'baseName',
|
|
161
|
+
'treatmentStandardsRoutes',
|
|
162
|
+
'mixAndLocationTypes',
|
|
163
|
+
'functionalUnitFlowProperties',
|
|
164
|
+
];
|
|
165
|
+
const fields = {};
|
|
166
|
+
for (const fieldName of fieldNames) {
|
|
167
|
+
fields[fieldName] = {
|
|
168
|
+
present: hasOwn(name, fieldName),
|
|
169
|
+
en: getLangText(name[fieldName], 'en'),
|
|
170
|
+
zh: getLangText(name[fieldName], 'zh'),
|
|
171
|
+
any: getLangText(name[fieldName], null),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const missingRequired = ['baseName', 'treatmentStandardsRoutes', 'mixAndLocationTypes'].filter((fieldName) => !fields[fieldName].present);
|
|
175
|
+
return {
|
|
176
|
+
missing_required_fields: missingRequired,
|
|
177
|
+
fields,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function nowIso(now = new Date()) {
|
|
181
|
+
return now.toISOString();
|
|
182
|
+
}
|
|
183
|
+
export async function runProcessVerifyRows(options) {
|
|
184
|
+
const rowsFile = path.resolve(requiredNonEmpty(options.rowsFile, '--rows-file', 'PROCESS_VERIFY_ROWS_FILE_REQUIRED'));
|
|
185
|
+
const outDir = path.resolve(requiredNonEmpty(options.outDir, '--out-dir', 'PROCESS_VERIFY_OUT_DIR_REQUIRED'));
|
|
186
|
+
const validate = options.validateProcessPayloadImpl ?? validateProcessPayload;
|
|
187
|
+
const rows = readRowsFile(rowsFile);
|
|
188
|
+
const generatedAtUtc = nowIso(options.now);
|
|
189
|
+
const records = rows.map((row, index) => {
|
|
190
|
+
const payload = getPayload(row);
|
|
191
|
+
const identity = getIdentity(row, payload, index);
|
|
192
|
+
const validation = validate(payload);
|
|
193
|
+
const nameSummary = summarizeNameFields(payload);
|
|
194
|
+
return {
|
|
195
|
+
...identity,
|
|
196
|
+
status: validation.ok && nameSummary.missing_required_fields.length === 0 ? 'ok' : 'invalid',
|
|
197
|
+
validation,
|
|
198
|
+
name_summary: nameSummary,
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
const invalidRows = records
|
|
202
|
+
.filter((record) => record.status === 'invalid')
|
|
203
|
+
.map((record) => ({
|
|
204
|
+
id: record.id,
|
|
205
|
+
version: record.version,
|
|
206
|
+
row_index: record.row_index,
|
|
207
|
+
missing_required_fields: record.name_summary.missing_required_fields,
|
|
208
|
+
schema_issue_count: record.validation.issue_count,
|
|
209
|
+
}));
|
|
210
|
+
const invalidCount = invalidRows.length;
|
|
211
|
+
const summaryPath = path.join(outDir, 'outputs', 'summary.json');
|
|
212
|
+
const verificationPath = path.join(outDir, 'outputs', 'verification.jsonl');
|
|
213
|
+
writeJsonArtifact(summaryPath, {
|
|
214
|
+
generated_at_utc: generatedAtUtc,
|
|
215
|
+
rows_file: rowsFile,
|
|
216
|
+
row_count: records.length,
|
|
217
|
+
invalid_count: invalidCount,
|
|
218
|
+
schema_invalid_count: records.filter((record) => !record.validation.ok).length,
|
|
219
|
+
missing_required_name_field_count: records.filter((record) => record.name_summary.missing_required_fields.length > 0).length,
|
|
220
|
+
invalid_rows: invalidRows,
|
|
221
|
+
});
|
|
222
|
+
writeJsonLinesArtifact(verificationPath, records);
|
|
223
|
+
return {
|
|
224
|
+
schema_version: 1,
|
|
225
|
+
generated_at_utc: generatedAtUtc,
|
|
226
|
+
status: invalidCount > 0
|
|
227
|
+
? 'completed_with_invalid_process_rows'
|
|
228
|
+
: 'completed_process_row_verification',
|
|
229
|
+
rows_file: rowsFile,
|
|
230
|
+
out_dir: outDir,
|
|
231
|
+
row_count: records.length,
|
|
232
|
+
invalid_count: invalidCount,
|
|
233
|
+
schema_invalid_count: records.filter((record) => !record.validation.ok).length,
|
|
234
|
+
missing_required_name_field_count: records.filter((record) => record.name_summary.missing_required_fields.length > 0).length,
|
|
235
|
+
invalid_rows: invalidRows,
|
|
236
|
+
files: {
|
|
237
|
+
summary_json: summaryPath,
|
|
238
|
+
verification_jsonl: verificationPath,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
export const __testInternals = {
|
|
243
|
+
getIdentity,
|
|
244
|
+
getLangList,
|
|
245
|
+
getLangText,
|
|
246
|
+
getPayload,
|
|
247
|
+
readRowsFile,
|
|
248
|
+
summarizeNameFields,
|
|
249
|
+
};
|
|
250
|
+
//# sourceMappingURL=process-verify-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-verify-rows.js","sourceRoot":"","sources":["../../../src/lib/process-verify-rows.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport {\n validateProcessPayload,\n type ProcessPayloadValidationResult,\n} from './process-payload-validation.js';\n\ntype JsonObject = Record<string, unknown>;\n\ntype NameFieldKey =\n | 'baseName'\n | 'treatmentStandardsRoutes'\n | 'mixAndLocationTypes'\n | 'functionalUnitFlowProperties';\n\nexport type ProcessVerifyNameFieldSummary = {\n present: boolean;\n en: string;\n zh: string;\n any: string;\n};\n\nexport type ProcessVerifyRowRecord = {\n row_index: number;\n id: string | null;\n version: string | null;\n status: 'ok' | 'invalid';\n validation: ProcessPayloadValidationResult;\n name_summary: {\n missing_required_fields: Array<'baseName' | 'treatmentStandardsRoutes' | 'mixAndLocationTypes'>;\n fields: Record<NameFieldKey, ProcessVerifyNameFieldSummary>;\n };\n};\n\nexport type ProcessVerifyRowsReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed_process_row_verification' | 'completed_with_invalid_process_rows';\n rows_file: string;\n out_dir: string;\n row_count: number;\n invalid_count: number;\n schema_invalid_count: number;\n missing_required_name_field_count: number;\n invalid_rows: Array<{\n id: string | null;\n version: string | null;\n row_index: number;\n missing_required_fields: Array<'baseName' | 'treatmentStandardsRoutes' | 'mixAndLocationTypes'>;\n schema_issue_count: number;\n }>;\n files: {\n summary_json: string;\n verification_jsonl: string;\n };\n};\n\nexport type RunProcessVerifyRowsOptions = {\n rowsFile: string;\n outDir: string;\n now?: Date;\n validateProcessPayloadImpl?: (payload: JsonObject) => ProcessPayloadValidationResult;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimText(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction requiredNonEmpty(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label}.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nfunction readRowsFile(filePath: string): unknown[] {\n if (!existsSync(filePath)) {\n throw new CliError(`Rows file not found: ${filePath}`, {\n code: 'PROCESS_VERIFY_ROWS_FILE_NOT_FOUND',\n exitCode: 2,\n });\n }\n\n const text = readFileSync(filePath, 'utf8');\n if (filePath.toLowerCase().endsWith('.jsonl')) {\n return text\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line, index) => {\n try {\n return JSON.parse(line) as unknown;\n } catch (error) {\n throw new CliError(`Rows file contains invalid JSONL at line ${index + 1}: ${filePath}`, {\n code: 'PROCESS_VERIFY_ROWS_FILE_INVALID_JSONL',\n exitCode: 2,\n details: String(error),\n });\n }\n });\n }\n\n try {\n const parsed = JSON.parse(text) as unknown;\n if (Array.isArray(parsed)) {\n return parsed;\n }\n if (isRecord(parsed) && Array.isArray(parsed.rows)) {\n return parsed.rows;\n }\n return [parsed];\n } catch (error) {\n throw new CliError(`Rows file is not valid JSON: ${filePath}`, {\n code: 'PROCESS_VERIFY_ROWS_FILE_INVALID_JSON',\n exitCode: 2,\n details: String(error),\n });\n }\n}\n\nfunction getPayload(row: unknown): JsonObject {\n if (isRecord(row) && isRecord(row.process)) {\n return row.process;\n }\n if (isRecord(row) && isRecord(row.json_ordered)) {\n return row.json_ordered;\n }\n if (isRecord(row) && isRecord(row.json)) {\n return row.json;\n }\n if (isRecord(row)) {\n return row;\n }\n\n return {};\n}\n\nfunction firstNonEmpty(...values: unknown[]): string | null {\n for (const value of values) {\n const normalized = trimText(value);\n if (normalized) {\n return normalized;\n }\n }\n return null;\n}\n\nfunction getIdentity(row: unknown, payload: JsonObject, index: number) {\n const root = isRecord(payload.processDataSet) ? payload.processDataSet : payload;\n const processInformation = isRecord(root.processInformation) ? root.processInformation : {};\n const dataSetInformation = isRecord(processInformation.dataSetInformation)\n ? processInformation.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n\n return {\n row_index: index,\n id: firstNonEmpty(\n isRecord(row) ? row.id : null,\n isRecord(row) ? row.process_id : null,\n dataSetInformation['common:UUID'],\n payload.id,\n payload['@id'],\n ),\n version: firstNonEmpty(\n isRecord(row) ? row.version : null,\n publicationAndOwnership['common:dataSetVersion'],\n payload.version,\n payload['@version'],\n ),\n };\n}\n\nfunction getLangList(value: unknown): JsonObject[] {\n if (value === null || value === undefined || value === '') {\n return [];\n }\n if (Array.isArray(value)) {\n return value.filter((entry): entry is JsonObject => isRecord(entry));\n }\n if (isRecord(value)) {\n const langString = value['common:langString'];\n if (Array.isArray(langString)) {\n return langString.filter((entry): entry is JsonObject => isRecord(entry));\n }\n if (isRecord(langString)) {\n return [langString];\n }\n if (value['#text'] !== undefined || value['@xml:lang'] !== undefined) {\n return [value];\n }\n }\n if (typeof value === 'string') {\n return [{ '@xml:lang': 'en', '#text': value }];\n }\n return [];\n}\n\nfunction getLangText(value: unknown, lang: string | null): string {\n const entries = getLangList(value);\n if (lang) {\n for (const entry of entries) {\n if (\n trimText(entry['@xml:lang']).toLowerCase() === lang.toLowerCase() &&\n trimText(entry['#text'])\n ) {\n return trimText(entry['#text']);\n }\n }\n }\n for (const entry of entries) {\n if (trimText(entry['#text'])) {\n return trimText(entry['#text']);\n }\n }\n return '';\n}\n\nfunction hasOwn(objectValue: JsonObject, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(objectValue, key);\n}\n\nfunction summarizeNameFields(payload: JsonObject): {\n missing_required_fields: Array<'baseName' | 'treatmentStandardsRoutes' | 'mixAndLocationTypes'>;\n fields: Record<NameFieldKey, ProcessVerifyNameFieldSummary>;\n} {\n const root = isRecord(payload.processDataSet) ? payload.processDataSet : payload;\n const processInformation = isRecord(root.processInformation) ? root.processInformation : {};\n const dataSetInformation = isRecord(processInformation.dataSetInformation)\n ? processInformation.dataSetInformation\n : {};\n const name = isRecord(dataSetInformation.name) ? dataSetInformation.name : {};\n\n const fieldNames: NameFieldKey[] = [\n 'baseName',\n 'treatmentStandardsRoutes',\n 'mixAndLocationTypes',\n 'functionalUnitFlowProperties',\n ];\n\n const fields = {} as Record<NameFieldKey, ProcessVerifyNameFieldSummary>;\n for (const fieldName of fieldNames) {\n fields[fieldName] = {\n present: hasOwn(name, fieldName),\n en: getLangText(name[fieldName], 'en'),\n zh: getLangText(name[fieldName], 'zh'),\n any: getLangText(name[fieldName], null),\n };\n }\n\n const missingRequired = ['baseName', 'treatmentStandardsRoutes', 'mixAndLocationTypes'].filter(\n (fieldName) => !fields[fieldName as NameFieldKey].present,\n ) as Array<'baseName' | 'treatmentStandardsRoutes' | 'mixAndLocationTypes'>;\n\n return {\n missing_required_fields: missingRequired,\n fields,\n };\n}\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nexport async function runProcessVerifyRows(\n options: RunProcessVerifyRowsOptions,\n): Promise<ProcessVerifyRowsReport> {\n const rowsFile = path.resolve(\n requiredNonEmpty(options.rowsFile, '--rows-file', 'PROCESS_VERIFY_ROWS_FILE_REQUIRED'),\n );\n const outDir = path.resolve(\n requiredNonEmpty(options.outDir, '--out-dir', 'PROCESS_VERIFY_OUT_DIR_REQUIRED'),\n );\n const validate = options.validateProcessPayloadImpl ?? validateProcessPayload;\n const rows = readRowsFile(rowsFile);\n const generatedAtUtc = nowIso(options.now);\n\n const records: ProcessVerifyRowRecord[] = rows.map((row, index) => {\n const payload = getPayload(row);\n const identity = getIdentity(row, payload, index);\n const validation = validate(payload);\n const nameSummary = summarizeNameFields(payload);\n return {\n ...identity,\n status: validation.ok && nameSummary.missing_required_fields.length === 0 ? 'ok' : 'invalid',\n validation,\n name_summary: nameSummary,\n };\n });\n\n const invalidRows = records\n .filter((record) => record.status === 'invalid')\n .map((record) => ({\n id: record.id,\n version: record.version,\n row_index: record.row_index,\n missing_required_fields: record.name_summary.missing_required_fields,\n schema_issue_count: record.validation.issue_count,\n }));\n const invalidCount = invalidRows.length;\n const summaryPath = path.join(outDir, 'outputs', 'summary.json');\n const verificationPath = path.join(outDir, 'outputs', 'verification.jsonl');\n\n writeJsonArtifact(summaryPath, {\n generated_at_utc: generatedAtUtc,\n rows_file: rowsFile,\n row_count: records.length,\n invalid_count: invalidCount,\n schema_invalid_count: records.filter((record) => !record.validation.ok).length,\n missing_required_name_field_count: records.filter(\n (record) => record.name_summary.missing_required_fields.length > 0,\n ).length,\n invalid_rows: invalidRows,\n });\n writeJsonLinesArtifact(verificationPath, records);\n\n return {\n schema_version: 1,\n generated_at_utc: generatedAtUtc,\n status:\n invalidCount > 0\n ? 'completed_with_invalid_process_rows'\n : 'completed_process_row_verification',\n rows_file: rowsFile,\n out_dir: outDir,\n row_count: records.length,\n invalid_count: invalidCount,\n schema_invalid_count: records.filter((record) => !record.validation.ok).length,\n missing_required_name_field_count: records.filter(\n (record) => record.name_summary.missing_required_fields.length > 0,\n ).length,\n invalid_rows: invalidRows,\n files: {\n summary_json: summaryPath,\n verification_jsonl: verificationPath,\n },\n };\n}\n\nexport const __testInternals = {\n getIdentity,\n getLangList,\n getLangText,\n getPayload,\n readRowsFile,\n summarizeNameFields,\n};\n"]}
|
package/dist/src/lib/publish.js
CHANGED
|
@@ -3,12 +3,16 @@ import { CliError } from './errors.js';
|
|
|
3
3
|
import { writeJsonArtifact } from './artifacts.js';
|
|
4
4
|
import { readJsonInput } from './io.js';
|
|
5
5
|
import { syncLifecyclemodelBundleRecord, } from './lifecyclemodel-bundle-save.js';
|
|
6
|
+
import { summarizeProcessPayloadValidation, validateProcessPayload, } from './process-payload-validation.js';
|
|
6
7
|
import { syncStateAwareProcessRecord } from './process-save-draft.js';
|
|
7
8
|
import { buildRunId, resolveRunLayout } from './run.js';
|
|
9
|
+
import { getRuntimeRuleset } from './runtime-rulesets.js';
|
|
8
10
|
import { hasSupabaseRestRuntime, syncSupabaseJsonOrderedRecord, } from './supabase-json-ordered-write.js';
|
|
9
11
|
const DEFAULT_MAX_ATTEMPTS = 5;
|
|
10
12
|
const DEFAULT_RETRY_DELAY_SECONDS = 2.0;
|
|
11
13
|
const DEFAULT_DATASET_VERSION = '01.01.000';
|
|
14
|
+
const PUBLISH_VERIFICATION_RULESET_ID = 'publish-run/default';
|
|
15
|
+
const PUBLISH_VERIFICATION_RULESET_VERSION = '1';
|
|
12
16
|
function isRecord(value) {
|
|
13
17
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
18
|
}
|
|
@@ -359,10 +363,27 @@ async function publish_lifecyclemodels(entries, options) {
|
|
|
359
363
|
}
|
|
360
364
|
async function publish_processes(entries, options) {
|
|
361
365
|
const reports = [];
|
|
366
|
+
const validate = options.validateProcessPayloadImpl ?? validateProcessPayload;
|
|
362
367
|
for (const item of entries) {
|
|
363
368
|
const payload = load_dataset_entry(item.entry, item.origin.base_dir);
|
|
364
369
|
try {
|
|
365
370
|
const [datasetId, version] = extract_process_identity(payload);
|
|
371
|
+
const validation = validate(payload);
|
|
372
|
+
if (!validation.ok) {
|
|
373
|
+
reports.push({
|
|
374
|
+
table: 'processes',
|
|
375
|
+
id: datasetId,
|
|
376
|
+
version,
|
|
377
|
+
status: 'failed',
|
|
378
|
+
source: item.origin.source,
|
|
379
|
+
bundle_path: item.origin.bundle_path,
|
|
380
|
+
validation,
|
|
381
|
+
error: {
|
|
382
|
+
message: summarizeProcessPayloadValidation(validation),
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
366
387
|
const report = {
|
|
367
388
|
table: 'processes',
|
|
368
389
|
id: datasetId,
|
|
@@ -370,6 +391,7 @@ async function publish_processes(entries, options) {
|
|
|
370
391
|
status: 'prepared',
|
|
371
392
|
source: item.origin.source,
|
|
372
393
|
bundle_path: item.origin.bundle_path,
|
|
394
|
+
validation,
|
|
373
395
|
};
|
|
374
396
|
reports.push(await maybe_execute_dataset(report, payload, {
|
|
375
397
|
...options,
|
|
@@ -483,7 +505,7 @@ function build_default_dataset_executor(options) {
|
|
|
483
505
|
fetchImpl: options.fetchImpl,
|
|
484
506
|
timeoutMs: options.timeoutMs,
|
|
485
507
|
audit: {
|
|
486
|
-
command: 'tiangong publish run',
|
|
508
|
+
command: 'tiangong-lca publish run',
|
|
487
509
|
source: args.source,
|
|
488
510
|
bundle_path: args.bundle_path,
|
|
489
511
|
},
|
|
@@ -544,6 +566,66 @@ function resolve_dataset_executors(options) {
|
|
|
544
566
|
process_build_runs: explicit.process_build_runs,
|
|
545
567
|
};
|
|
546
568
|
}
|
|
569
|
+
function dataset_failure_finding(report, fallbackCode) {
|
|
570
|
+
const validationIssue = report.validation?.ok === false ? report.validation.issues[0] : null;
|
|
571
|
+
return {
|
|
572
|
+
code: validationIssue?.code ?? fallbackCode,
|
|
573
|
+
severity: 'blocker',
|
|
574
|
+
message: validationIssue?.message ??
|
|
575
|
+
report.error?.message ??
|
|
576
|
+
report.reason ??
|
|
577
|
+
'Publish dataset failed.',
|
|
578
|
+
table: report.table,
|
|
579
|
+
id: report.id,
|
|
580
|
+
version: report.version,
|
|
581
|
+
...(validationIssue?.path ? { path: validationIssue.path } : {}),
|
|
582
|
+
...(report.bundle_path !== undefined ? { bundle_path: report.bundle_path } : {}),
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
function process_build_run_failure_finding(report) {
|
|
586
|
+
return {
|
|
587
|
+
code: 'process_build_run_publish_failed',
|
|
588
|
+
severity: 'blocker',
|
|
589
|
+
message: report.error?.message ?? 'Process build run publish failed.',
|
|
590
|
+
table: 'process_build_runs',
|
|
591
|
+
id: report.run_id,
|
|
592
|
+
version: null,
|
|
593
|
+
bundle_path: report.bundle_path,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
function build_publish_verification_report(options) {
|
|
597
|
+
const ruleset = getRuntimeRuleset('publish-run/default');
|
|
598
|
+
const datasetFindings = [
|
|
599
|
+
...options.lifecyclemodels,
|
|
600
|
+
...options.processes,
|
|
601
|
+
...options.sources,
|
|
602
|
+
].flatMap((report) => report.status === 'failed'
|
|
603
|
+
? [dataset_failure_finding(report, `${report.table}_publish_failed`)]
|
|
604
|
+
: []);
|
|
605
|
+
const processBuildRunFindings = options.processBuildRuns.flatMap((report) => report.status === 'failed' ? [process_build_run_failure_finding(report)] : []);
|
|
606
|
+
const blockers = [...datasetFindings, ...processBuildRunFindings];
|
|
607
|
+
return {
|
|
608
|
+
schema_version: 1,
|
|
609
|
+
generated_at_utc: options.now.toISOString(),
|
|
610
|
+
command: 'publish run',
|
|
611
|
+
status: blockers.length > 0 ? 'blocked' : 'passed',
|
|
612
|
+
ruleset_id: PUBLISH_VERIFICATION_RULESET_ID,
|
|
613
|
+
ruleset_version: PUBLISH_VERIFICATION_RULESET_VERSION,
|
|
614
|
+
ruleset_source_version: ruleset.source_version,
|
|
615
|
+
ruleset_rule_ids: ruleset.rule_ids,
|
|
616
|
+
commit: options.commit,
|
|
617
|
+
findings: blockers,
|
|
618
|
+
blockers,
|
|
619
|
+
next_action: blockers.length > 0 ? 'fix_blockers' : 'ready_for_commit_or_publish',
|
|
620
|
+
counts: {
|
|
621
|
+
findings: blockers.length,
|
|
622
|
+
blockers: blockers.length,
|
|
623
|
+
failed: options.failed,
|
|
624
|
+
deferred: options.deferred,
|
|
625
|
+
executed: options.executed,
|
|
626
|
+
},
|
|
627
|
+
};
|
|
628
|
+
}
|
|
547
629
|
export async function runPublish(options) {
|
|
548
630
|
const requestPath = path.resolve(options.inputPath);
|
|
549
631
|
const requestDir = path.dirname(requestPath);
|
|
@@ -562,6 +644,7 @@ export async function runPublish(options) {
|
|
|
562
644
|
normalized_request: path.join(outDir, 'normalized-request.json'),
|
|
563
645
|
collected_inputs: path.join(outDir, 'collected-inputs.json'),
|
|
564
646
|
relation_manifest: path.join(outDir, 'relation-manifest.json'),
|
|
647
|
+
verification_report: path.join(outDir, 'verification-report.json'),
|
|
565
648
|
publish_report: path.join(outDir, 'publish-report.json'),
|
|
566
649
|
};
|
|
567
650
|
writeJsonArtifact(files.normalized_request, normalized);
|
|
@@ -578,6 +661,7 @@ export async function runPublish(options) {
|
|
|
578
661
|
commit: normalized.publish.commit,
|
|
579
662
|
executor: executors.processes,
|
|
580
663
|
publish: normalized.publish,
|
|
664
|
+
validateProcessPayloadImpl: options.validateProcessPayloadImpl,
|
|
581
665
|
})
|
|
582
666
|
: [];
|
|
583
667
|
const sources = normalized.publish.publish_sources
|
|
@@ -600,6 +684,17 @@ export async function runPublish(options) {
|
|
|
600
684
|
const failed = publishEntries.filter((item) => item.status === 'failed').length;
|
|
601
685
|
const executed = publishEntries.filter((item) => item.status === 'executed').length;
|
|
602
686
|
const deferred = publishEntries.filter((item) => item.status.startsWith('deferred')).length;
|
|
687
|
+
const verification = build_publish_verification_report({
|
|
688
|
+
now,
|
|
689
|
+
commit: normalized.publish.commit,
|
|
690
|
+
failed,
|
|
691
|
+
deferred,
|
|
692
|
+
executed,
|
|
693
|
+
lifecyclemodels,
|
|
694
|
+
processes,
|
|
695
|
+
sources,
|
|
696
|
+
processBuildRuns,
|
|
697
|
+
});
|
|
603
698
|
const report = {
|
|
604
699
|
generated_at_utc: now.toISOString(),
|
|
605
700
|
request_path: requestPath,
|
|
@@ -618,13 +713,18 @@ export async function runPublish(options) {
|
|
|
618
713
|
failed,
|
|
619
714
|
},
|
|
620
715
|
files,
|
|
716
|
+
verification,
|
|
621
717
|
lifecyclemodels,
|
|
622
718
|
processes,
|
|
623
719
|
sources,
|
|
624
720
|
process_build_runs: processBuildRuns,
|
|
625
721
|
relations,
|
|
626
722
|
};
|
|
723
|
+
writeJsonArtifact(files.verification_report, verification);
|
|
627
724
|
writeJsonArtifact(files.publish_report, report);
|
|
628
725
|
return report;
|
|
629
726
|
}
|
|
727
|
+
export const __testInternals = {
|
|
728
|
+
build_publish_verification_report,
|
|
729
|
+
};
|
|
630
730
|
//# sourceMappingURL=publish.js.map
|