@ifc-lite/ids-authoring 0.0.0-stage → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +469 -2
- package/dist/bsdd/cache.d.ts +37 -0
- package/dist/bsdd/cache.d.ts.map +1 -0
- package/dist/bsdd/cache.js +116 -0
- package/dist/bsdd/cache.js.map +1 -0
- package/dist/bsdd/contract.d.ts +31 -0
- package/dist/bsdd/contract.d.ts.map +1 -0
- package/dist/bsdd/contract.js +185 -0
- package/dist/bsdd/contract.js.map +1 -0
- package/dist/bsdd/dictionary.d.ts +42 -0
- package/dist/bsdd/dictionary.d.ts.map +1 -0
- package/dist/bsdd/dictionary.js +115 -0
- package/dist/bsdd/dictionary.js.map +1 -0
- package/dist/bsdd/generator.d.ts +82 -0
- package/dist/bsdd/generator.d.ts.map +1 -0
- package/dist/bsdd/generator.js +155 -0
- package/dist/bsdd/generator.js.map +1 -0
- package/dist/bsdd/http-source.d.ts +15 -0
- package/dist/bsdd/http-source.d.ts.map +1 -0
- package/dist/bsdd/http-source.js +196 -0
- package/dist/bsdd/http-source.js.map +1 -0
- package/dist/bsdd/idb-store.d.ts +16 -0
- package/dist/bsdd/idb-store.d.ts.map +1 -0
- package/dist/bsdd/idb-store.js +58 -0
- package/dist/bsdd/idb-store.js.map +1 -0
- package/dist/bsdd/insert.d.ts +55 -0
- package/dist/bsdd/insert.d.ts.map +1 -0
- package/dist/bsdd/insert.js +105 -0
- package/dist/bsdd/insert.js.map +1 -0
- package/dist/bsdd/mapping.d.ts +62 -0
- package/dist/bsdd/mapping.d.ts.map +1 -0
- package/dist/bsdd/mapping.js +163 -0
- package/dist/bsdd/mapping.js.map +1 -0
- package/dist/bsdd/picker.d.ts +91 -0
- package/dist/bsdd/picker.d.ts.map +1 -0
- package/dist/bsdd/picker.js +151 -0
- package/dist/bsdd/picker.js.map +1 -0
- package/dist/bsdd/types.d.ts +162 -0
- package/dist/bsdd/types.d.ts.map +1 -0
- package/dist/bsdd/types.js +26 -0
- package/dist/bsdd/types.js.map +1 -0
- package/dist/bsdd/uri-health.d.ts +65 -0
- package/dist/bsdd/uri-health.d.ts.map +1 -0
- package/dist/bsdd/uri-health.js +110 -0
- package/dist/bsdd/uri-health.js.map +1 -0
- package/dist/canonical-json.d.ts +7 -0
- package/dist/canonical-json.d.ts.map +1 -0
- package/dist/canonical-json.js +20 -0
- package/dist/canonical-json.js.map +1 -0
- package/dist/comments/view.d.ts +37 -0
- package/dist/comments/view.d.ts.map +1 -0
- package/dist/comments/view.js +61 -0
- package/dist/comments/view.js.map +1 -0
- package/dist/compound/expand.d.ts +5 -0
- package/dist/compound/expand.d.ts.map +1 -0
- package/dist/compound/expand.js +135 -0
- package/dist/compound/expand.js.map +1 -0
- package/dist/compound/from-bsdd.d.ts +9 -0
- package/dist/compound/from-bsdd.d.ts.map +1 -0
- package/dist/compound/from-bsdd.js +166 -0
- package/dist/compound/from-bsdd.js.map +1 -0
- package/dist/diff/align.d.ts +42 -0
- package/dist/diff/align.d.ts.map +1 -0
- package/dist/diff/align.js +78 -0
- package/dist/diff/align.js.map +1 -0
- package/dist/diff/changelog-text.d.ts +39 -0
- package/dist/diff/changelog-text.d.ts.map +1 -0
- package/dist/diff/changelog-text.js +120 -0
- package/dist/diff/changelog-text.js.map +1 -0
- package/dist/diff/changelog.d.ts +28 -0
- package/dist/diff/changelog.d.ts.map +1 -0
- package/dist/diff/changelog.js +173 -0
- package/dist/diff/changelog.js.map +1 -0
- package/dist/diff/compare.d.ts +25 -0
- package/dist/diff/compare.d.ts.map +1 -0
- package/dist/diff/compare.js +150 -0
- package/dist/diff/compare.js.map +1 -0
- package/dist/diff/diff.d.ts +13 -0
- package/dist/diff/diff.d.ts.map +1 -0
- package/dist/diff/diff.js +140 -0
- package/dist/diff/diff.js.map +1 -0
- package/dist/diff/index.d.ts +5 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +7 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/patch.d.ts +10 -0
- package/dist/diff/patch.d.ts.map +1 -0
- package/dist/diff/patch.js +177 -0
- package/dist/diff/patch.js.map +1 -0
- package/dist/diff/types.d.ts +201 -0
- package/dist/diff/types.d.ts.map +1 -0
- package/dist/diff/types.js +5 -0
- package/dist/diff/types.js.map +1 -0
- package/dist/document/fields.d.ts +33 -0
- package/dist/document/fields.d.ts.map +1 -0
- package/dist/document/fields.js +117 -0
- package/dist/document/fields.js.map +1 -0
- package/dist/document/from-ids.d.ts +32 -0
- package/dist/document/from-ids.d.ts.map +1 -0
- package/dist/document/from-ids.js +47 -0
- package/dist/document/from-ids.js.map +1 -0
- package/dist/document/node-index.d.ts +32 -0
- package/dist/document/node-index.d.ts.map +1 -0
- package/dist/document/node-index.js +127 -0
- package/dist/document/node-index.js.map +1 -0
- package/dist/document/types.d.ts +170 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +19 -0
- package/dist/document/types.js.map +1 -0
- package/dist/gate/bsdd.d.ts +12 -0
- package/dist/gate/bsdd.d.ts.map +1 -0
- package/dist/gate/bsdd.js +17 -0
- package/dist/gate/bsdd.js.map +1 -0
- package/dist/gate/check.d.ts +6 -0
- package/dist/gate/check.d.ts.map +1 -0
- package/dist/gate/check.js +125 -0
- package/dist/gate/check.js.map +1 -0
- package/dist/gate/context.d.ts +51 -0
- package/dist/gate/context.d.ts.map +1 -0
- package/dist/gate/context.js +74 -0
- package/dist/gate/context.js.map +1 -0
- package/dist/gate/grounding-pset.d.ts +5 -0
- package/dist/gate/grounding-pset.d.ts.map +1 -0
- package/dist/gate/grounding-pset.js +179 -0
- package/dist/gate/grounding-pset.js.map +1 -0
- package/dist/gate/grounding.d.ts +48 -0
- package/dist/gate/grounding.d.ts.map +1 -0
- package/dist/gate/grounding.js +146 -0
- package/dist/gate/grounding.js.map +1 -0
- package/dist/gate/rank.d.ts +28 -0
- package/dist/gate/rank.d.ts.map +1 -0
- package/dist/gate/rank.js +68 -0
- package/dist/gate/rank.js.map +1 -0
- package/dist/gate/structural.d.ts +43 -0
- package/dist/gate/structural.d.ts.map +1 -0
- package/dist/gate/structural.js +175 -0
- package/dist/gate/structural.js.map +1 -0
- package/dist/gate/types.d.ts +45 -0
- package/dist/gate/types.d.ts.map +1 -0
- package/dist/gate/types.js +5 -0
- package/dist/gate/types.js.map +1 -0
- package/dist/gate/values.d.ts +19 -0
- package/dist/gate/values.d.ts.map +1 -0
- package/dist/gate/values.js +124 -0
- package/dist/gate/values.js.map +1 -0
- package/dist/headless/apply-gated.d.ts +32 -0
- package/dist/headless/apply-gated.d.ts.map +1 -0
- package/dist/headless/apply-gated.js +26 -0
- package/dist/headless/apply-gated.js.map +1 -0
- package/dist/headless/diff.d.ts +41 -0
- package/dist/headless/diff.d.ts.map +1 -0
- package/dist/headless/diff.js +116 -0
- package/dist/headless/diff.js.map +1 -0
- package/dist/headless/node-path.d.ts +10 -0
- package/dist/headless/node-path.d.ts.map +1 -0
- package/dist/headless/node-path.js +24 -0
- package/dist/headless/node-path.js.map +1 -0
- package/dist/headless/read.d.ts +26 -0
- package/dist/headless/read.d.ts.map +1 -0
- package/dist/headless/read.js +78 -0
- package/dist/headless/read.js.map +1 -0
- package/dist/headless/schema-lookup.d.ts +52 -0
- package/dist/headless/schema-lookup.d.ts.map +1 -0
- package/dist/headless/schema-lookup.js +77 -0
- package/dist/headless/schema-lookup.js.map +1 -0
- package/dist/headless/write.d.ts +46 -0
- package/dist/headless/write.d.ts.map +1 -0
- package/dist/headless/write.js +103 -0
- package/dist/headless/write.js.map +1 -0
- package/dist/history/history.d.ts +90 -0
- package/dist/history/history.d.ts.map +1 -0
- package/dist/history/history.js +86 -0
- package/dist/history/history.js.map +1 -0
- package/dist/history/persistence.d.ts +33 -0
- package/dist/history/persistence.d.ts.map +1 -0
- package/dist/history/persistence.js +71 -0
- package/dist/history/persistence.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/context.d.ts +15 -0
- package/dist/lint/context.d.ts.map +1 -0
- package/dist/lint/context.js +24 -0
- package/dist/lint/context.js.map +1 -0
- package/dist/lint/docs.d.ts +18 -0
- package/dist/lint/docs.d.ts.map +1 -0
- package/dist/lint/docs.js +117 -0
- package/dist/lint/docs.js.map +1 -0
- package/dist/lint/engine.d.ts +21 -0
- package/dist/lint/engine.d.ts.map +1 -0
- package/dist/lint/engine.js +123 -0
- package/dist/lint/engine.js.map +1 -0
- package/dist/lint/fix.d.ts +27 -0
- package/dist/lint/fix.d.ts.map +1 -0
- package/dist/lint/fix.js +22 -0
- package/dist/lint/fix.js.map +1 -0
- package/dist/lint/precision.d.ts +51 -0
- package/dist/lint/precision.d.ts.map +1 -0
- package/dist/lint/precision.js +64 -0
- package/dist/lint/precision.js.map +1 -0
- package/dist/lint/rules/bsdd.d.ts +5 -0
- package/dist/lint/rules/bsdd.d.ts.map +1 -0
- package/dist/lint/rules/bsdd.js +123 -0
- package/dist/lint/rules/bsdd.js.map +1 -0
- package/dist/lint/rules/card.d.ts +10 -0
- package/dist/lint/rules/card.d.ts.map +1 -0
- package/dist/lint/rules/card.js +140 -0
- package/dist/lint/rules/card.js.map +1 -0
- package/dist/lint/rules/doc-ver-part.d.ts +7 -0
- package/dist/lint/rules/doc-ver-part.d.ts.map +1 -0
- package/dist/lint/rules/doc-ver-part.js +155 -0
- package/dist/lint/rules/doc-ver-part.js.map +1 -0
- package/dist/lint/rules/entity.d.ts +12 -0
- package/dist/lint/rules/entity.d.ts.map +1 -0
- package/dist/lint/rules/entity.js +215 -0
- package/dist/lint/rules/entity.js.map +1 -0
- package/dist/lint/rules/index.d.ts +4 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/index.js +63 -0
- package/dist/lint/rules/index.js.map +1 -0
- package/dist/lint/rules/pdt-att.d.ts +7 -0
- package/dist/lint/rules/pdt-att.d.ts.map +1 -0
- package/dist/lint/rules/pdt-att.js +209 -0
- package/dist/lint/rules/pdt-att.js.map +1 -0
- package/dist/lint/rules/pset.d.ts +12 -0
- package/dist/lint/rules/pset.d.ts.map +1 -0
- package/dist/lint/rules/pset.js +263 -0
- package/dist/lint/rules/pset.js.map +1 -0
- package/dist/lint/rules/regex.d.ts +6 -0
- package/dist/lint/rules/regex.d.ts.map +1 -0
- package/dist/lint/rules/regex.js +184 -0
- package/dist/lint/rules/regex.js.map +1 -0
- package/dist/lint/rules/spec-doc.d.ts +5 -0
- package/dist/lint/rules/spec-doc.d.ts.map +1 -0
- package/dist/lint/rules/spec-doc.js +132 -0
- package/dist/lint/rules/spec-doc.js.map +1 -0
- package/dist/lint/rules/spec.d.ts +24 -0
- package/dist/lint/rules/spec.d.ts.map +1 -0
- package/dist/lint/rules/spec.js +162 -0
- package/dist/lint/rules/spec.js.map +1 -0
- package/dist/lint/rules/units.d.ts +4 -0
- package/dist/lint/rules/units.d.ts.map +1 -0
- package/dist/lint/rules/units.js +101 -0
- package/dist/lint/rules/units.js.map +1 -0
- package/dist/lint/rules/util.d.ts +37 -0
- package/dist/lint/rules/util.d.ts.map +1 -0
- package/dist/lint/rules/util.js +117 -0
- package/dist/lint/rules/util.js.map +1 -0
- package/dist/lint/rules/value-sites.d.ts +28 -0
- package/dist/lint/rules/value-sites.d.ts.map +1 -0
- package/dist/lint/rules/value-sites.js +81 -0
- package/dist/lint/rules/value-sites.js.map +1 -0
- package/dist/lint/rules/values.d.ts +22 -0
- package/dist/lint/rules/values.d.ts.map +1 -0
- package/dist/lint/rules/values.js +237 -0
- package/dist/lint/rules/values.js.map +1 -0
- package/dist/lint/rules/xsd-regex.d.ts +34 -0
- package/dist/lint/rules/xsd-regex.d.ts.map +1 -0
- package/dist/lint/rules/xsd-regex.js +149 -0
- package/dist/lint/rules/xsd-regex.js.map +1 -0
- package/dist/lint/solver/sample.d.ts +3 -0
- package/dist/lint/solver/sample.d.ts.map +1 -0
- package/dist/lint/solver/sample.js +134 -0
- package/dist/lint/solver/sample.js.map +1 -0
- package/dist/lint/solver/solver.d.ts +39 -0
- package/dist/lint/solver/solver.d.ts.map +1 -0
- package/dist/lint/solver/solver.js +126 -0
- package/dist/lint/solver/solver.js.map +1 -0
- package/dist/lint/suppress.d.ts +12 -0
- package/dist/lint/suppress.d.ts.map +1 -0
- package/dist/lint/suppress.js +56 -0
- package/dist/lint/suppress.js.map +1 -0
- package/dist/lint/types.d.ts +162 -0
- package/dist/lint/types.d.ts.map +1 -0
- package/dist/lint/types.js +5 -0
- package/dist/lint/types.js.map +1 -0
- package/dist/lint/walk.d.ts +20 -0
- package/dist/lint/walk.d.ts.map +1 -0
- package/dist/lint/walk.js +47 -0
- package/dist/lint/walk.js.map +1 -0
- package/dist/match/cascade.d.ts +53 -0
- package/dist/match/cascade.d.ts.map +1 -0
- package/dist/match/cascade.js +135 -0
- package/dist/match/cascade.js.map +1 -0
- package/dist/match/reidentify.d.ts +46 -0
- package/dist/match/reidentify.d.ts.map +1 -0
- package/dist/match/reidentify.js +67 -0
- package/dist/match/reidentify.js.map +1 -0
- package/dist/merge/comments.d.ts +13 -0
- package/dist/merge/comments.d.ts.map +1 -0
- package/dist/merge/comments.js +61 -0
- package/dist/merge/comments.js.map +1 -0
- package/dist/merge/index.d.ts +4 -0
- package/dist/merge/index.d.ts.map +1 -0
- package/dist/merge/index.js +6 -0
- package/dist/merge/index.js.map +1 -0
- package/dist/merge/keys.d.ts +22 -0
- package/dist/merge/keys.d.ts.map +1 -0
- package/dist/merge/keys.js +54 -0
- package/dist/merge/keys.js.map +1 -0
- package/dist/merge/merge.d.ts +8 -0
- package/dist/merge/merge.d.ts.map +1 -0
- package/dist/merge/merge.js +206 -0
- package/dist/merge/merge.js.map +1 -0
- package/dist/merge/order.d.ts +11 -0
- package/dist/merge/order.d.ts.map +1 -0
- package/dist/merge/order.js +117 -0
- package/dist/merge/order.js.map +1 -0
- package/dist/merge/sidecar.d.ts +12 -0
- package/dist/merge/sidecar.d.ts.map +1 -0
- package/dist/merge/sidecar.js +64 -0
- package/dist/merge/sidecar.js.map +1 -0
- package/dist/merge/types.d.ts +50 -0
- package/dist/merge/types.d.ts.map +1 -0
- package/dist/merge/types.js +5 -0
- package/dist/merge/types.js.map +1 -0
- package/dist/merge/view.d.ts +28 -0
- package/dist/merge/view.d.ts.map +1 -0
- package/dist/merge/view.js +35 -0
- package/dist/merge/view.js.map +1 -0
- package/dist/ops/draft.d.ts +33 -0
- package/dist/ops/draft.d.ts.map +1 -0
- package/dist/ops/draft.js +253 -0
- package/dist/ops/draft.js.map +1 -0
- package/dist/ops/json-schema-lite.d.ts +41 -0
- package/dist/ops/json-schema-lite.d.ts.map +1 -0
- package/dist/ops/json-schema-lite.js +119 -0
- package/dist/ops/json-schema-lite.js.map +1 -0
- package/dist/ops/schema-values.d.ts +5 -0
- package/dist/ops/schema-values.d.ts.map +1 -0
- package/dist/ops/schema-values.js +233 -0
- package/dist/ops/schema-values.js.map +1 -0
- package/dist/ops/schema.d.ts +27 -0
- package/dist/ops/schema.d.ts.map +1 -0
- package/dist/ops/schema.js +258 -0
- package/dist/ops/schema.js.map +1 -0
- package/dist/ops/sidecar-ops.d.ts +85 -0
- package/dist/ops/sidecar-ops.d.ts.map +1 -0
- package/dist/ops/sidecar-ops.js +5 -0
- package/dist/ops/sidecar-ops.js.map +1 -0
- package/dist/ops/types.d.ts +400 -0
- package/dist/ops/types.d.ts.map +1 -0
- package/dist/ops/types.js +5 -0
- package/dist/ops/types.js.map +1 -0
- package/dist/ops/units.d.ts +4 -0
- package/dist/ops/units.d.ts.map +1 -0
- package/dist/ops/units.js +75 -0
- package/dist/ops/units.js.map +1 -0
- package/dist/reducer/apply.d.ts +33 -0
- package/dist/reducer/apply.d.ts.map +1 -0
- package/dist/reducer/apply.js +123 -0
- package/dist/reducer/apply.js.map +1 -0
- package/dist/reducer/comment-ops.d.ts +18 -0
- package/dist/reducer/comment-ops.d.ts.map +1 -0
- package/dist/reducer/comment-ops.js +104 -0
- package/dist/reducer/comment-ops.js.map +1 -0
- package/dist/reducer/edit.d.ts +38 -0
- package/dist/reducer/edit.d.ts.map +1 -0
- package/dist/reducer/edit.js +126 -0
- package/dist/reducer/edit.js.map +1 -0
- package/dist/reducer/facet-ops.d.ts +20 -0
- package/dist/reducer/facet-ops.d.ts.map +1 -0
- package/dist/reducer/facet-ops.js +184 -0
- package/dist/reducer/facet-ops.js.map +1 -0
- package/dist/reducer/meta-ops.d.ts +20 -0
- package/dist/reducer/meta-ops.d.ts.map +1 -0
- package/dist/reducer/meta-ops.js +52 -0
- package/dist/reducer/meta-ops.js.map +1 -0
- package/dist/reducer/spec-ops.d.ts +29 -0
- package/dist/reducer/spec-ops.d.ts.map +1 -0
- package/dist/reducer/spec-ops.js +181 -0
- package/dist/reducer/spec-ops.js.map +1 -0
- package/dist/reducer/test-ops.d.ts +15 -0
- package/dist/reducer/test-ops.d.ts.map +1 -0
- package/dist/reducer/test-ops.js +90 -0
- package/dist/reducer/test-ops.js.map +1 -0
- package/dist/reducer/value-ops.d.ts +26 -0
- package/dist/reducer/value-ops.d.ts.map +1 -0
- package/dist/reducer/value-ops.js +173 -0
- package/dist/reducer/value-ops.js.map +1 -0
- package/dist/render/describe.d.ts +20 -0
- package/dist/render/describe.d.ts.map +1 -0
- package/dist/render/describe.js +47 -0
- package/dist/render/describe.js.map +1 -0
- package/dist/revision/index.d.ts +4 -0
- package/dist/revision/index.d.ts.map +1 -0
- package/dist/revision/index.js +7 -0
- package/dist/revision/index.js.map +1 -0
- package/dist/revision/revision.d.ts +79 -0
- package/dist/revision/revision.d.ts.map +1 -0
- package/dist/revision/revision.js +120 -0
- package/dist/revision/revision.js.map +1 -0
- package/dist/revision/sha256.d.ts +3 -0
- package/dist/revision/sha256.d.ts.map +1 -0
- package/dist/revision/sha256.js +69 -0
- package/dist/revision/sha256.js.map +1 -0
- package/dist/revision/verify.d.ts +21 -0
- package/dist/revision/verify.d.ts.map +1 -0
- package/dist/revision/verify.js +51 -0
- package/dist/revision/verify.js.map +1 -0
- package/dist/revision/view.d.ts +36 -0
- package/dist/revision/view.d.ts.map +1 -0
- package/dist/revision/view.js +32 -0
- package/dist/revision/view.js.map +1 -0
- package/dist/sidecar/idsz.d.ts +14 -0
- package/dist/sidecar/idsz.d.ts.map +1 -0
- package/dist/sidecar/idsz.js +58 -0
- package/dist/sidecar/idsz.js.map +1 -0
- package/dist/sidecar/sidecar-schema.d.ts +4 -0
- package/dist/sidecar/sidecar-schema.d.ts.map +1 -0
- package/dist/sidecar/sidecar-schema.js +69 -0
- package/dist/sidecar/sidecar-schema.js.map +1 -0
- package/dist/sidecar/sidecar.d.ts +102 -0
- package/dist/sidecar/sidecar.d.ts.map +1 -0
- package/dist/sidecar/sidecar.js +160 -0
- package/dist/sidecar/sidecar.js.map +1 -0
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/junit.d.ts +10 -0
- package/dist/testing/junit.d.ts.map +1 -0
- package/dist/testing/junit.js +51 -0
- package/dist/testing/junit.js.map +1 -0
- package/dist/testing/outcome.d.ts +10 -0
- package/dist/testing/outcome.d.ts.map +1 -0
- package/dist/testing/outcome.js +22 -0
- package/dist/testing/outcome.js.map +1 -0
- package/dist/testing/runner.d.ts +72 -0
- package/dist/testing/runner.d.ts.map +1 -0
- package/dist/testing/runner.js +60 -0
- package/dist/testing/runner.js.map +1 -0
- package/dist/testing/types.d.ts +60 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +5 -0
- package/dist/testing/types.js.map +1 -0
- package/dist/testing/view.d.ts +31 -0
- package/dist/testing/view.d.ts.map +1 -0
- package/dist/testing/view.js +30 -0
- package/dist/testing/view.js.map +1 -0
- package/dist/uuid.d.ts +39 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +84 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +56 -3
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
export const LINT_DOCS_DIR = 'docs/guide/ids-lint';
|
|
5
|
+
export const NAV_BEGIN = '# BEGIN GENERATED ids-lint-nav';
|
|
6
|
+
export const NAV_END = '# END GENERATED ids-lint-nav';
|
|
7
|
+
const BANNER = '<!-- Generated from the rule metadata in packages/ids-authoring/src/lint/rules by packages/ids-authoring/scripts/generate-lint-docs.mjs. Do not edit by hand. -->';
|
|
8
|
+
const AREA_NAMES = {
|
|
9
|
+
ENT: 'Entities',
|
|
10
|
+
PDT: 'Predefined types',
|
|
11
|
+
ATT: 'Attributes',
|
|
12
|
+
PSET: 'Property sets',
|
|
13
|
+
PROP: 'Properties',
|
|
14
|
+
VAL: 'Values',
|
|
15
|
+
UNIT: 'Units',
|
|
16
|
+
REGEX: 'Patterns',
|
|
17
|
+
CARD: 'Cardinality',
|
|
18
|
+
SPEC: 'Specifications',
|
|
19
|
+
DOC: 'Document',
|
|
20
|
+
VER: 'IFC versions',
|
|
21
|
+
PART: 'partOf relations',
|
|
22
|
+
BSDD: 'bSDD references',
|
|
23
|
+
};
|
|
24
|
+
/** Severity as the catalogue tables show it: `info (opt-in)` for rules that are off by default. */
|
|
25
|
+
export function severityLabel(rule) {
|
|
26
|
+
return rule.optIn ? `${rule.defaultSeverity} (opt-in)` : rule.defaultSeverity;
|
|
27
|
+
}
|
|
28
|
+
export function pageName(code) {
|
|
29
|
+
return `${code.toLowerCase()}.md`;
|
|
30
|
+
}
|
|
31
|
+
function rulePage(rule) {
|
|
32
|
+
const lines = [
|
|
33
|
+
BANNER,
|
|
34
|
+
'',
|
|
35
|
+
`# ${rule.code}: ${rule.title}`,
|
|
36
|
+
'',
|
|
37
|
+
'| Default severity | Kind | Scope | Quick fix |',
|
|
38
|
+
'|---|---|---|---|',
|
|
39
|
+
`| ${severityLabel(rule)} | ${rule.kind} | ${rule.scope === 'spec' ? 'specification' : 'document'} | ${rule.fix ? 'yes' : 'no'} |`,
|
|
40
|
+
'',
|
|
41
|
+
rule.rationale,
|
|
42
|
+
'',
|
|
43
|
+
];
|
|
44
|
+
if (rule.optIn) {
|
|
45
|
+
lines.push('## Enabling', '', `This rule is off by default. Enable it in the linter config, at its default severity or another one: \`createLinter(ctx, { severity: { '${rule.code}': '${rule.defaultSeverity}' } })\`. Naming it in \`rules\` also enables it.`, '');
|
|
46
|
+
}
|
|
47
|
+
if (rule.example)
|
|
48
|
+
lines.push('## Example', '', '```xml', rule.example, '```', '');
|
|
49
|
+
if (rule.fix)
|
|
50
|
+
lines.push('## Quick fix', '', `${rule.fix} Quick fixes are proposals: they are op batches that pass the grounding gate and are never applied automatically.`, '');
|
|
51
|
+
if (rule.assumptions?.length) {
|
|
52
|
+
lines.push('## Verified assumptions', '');
|
|
53
|
+
for (const a of rule.assumptions)
|
|
54
|
+
lines.push(`- **${a.id}**: ${a.verified}`);
|
|
55
|
+
lines.push('');
|
|
56
|
+
}
|
|
57
|
+
if (rule.references?.length) {
|
|
58
|
+
lines.push('## References', '');
|
|
59
|
+
for (const r of rule.references)
|
|
60
|
+
lines.push(`- <${r}>`);
|
|
61
|
+
lines.push('');
|
|
62
|
+
}
|
|
63
|
+
lines.push('## Suppressing', '', `Add a suppression with a reason for \`${rule.code}\` (or \`IDSL-${rule.area}-*\`) to the node, its facet, its specification or the document in the Studio sidecar (\`meta.suppressions\`).`, '', '[All lint rules](index.md)', '');
|
|
64
|
+
return lines.join('\n');
|
|
65
|
+
}
|
|
66
|
+
function indexPage(rules) {
|
|
67
|
+
const lines = [
|
|
68
|
+
BANNER,
|
|
69
|
+
'',
|
|
70
|
+
'# IDS lint rules',
|
|
71
|
+
'',
|
|
72
|
+
'The IDS audit answers "is this a valid IDS 1.0 file?". Lint answers "does this IDS mean what the author intends, and will it behave well?": abstract entities that match nothing, `^` in XSD patterns, millimetres where metres are expected, requirements that can never fail or never pass. Lint runs on a `StudioDocument` from `@ifc-lite/ids-authoring` and returns diagnostics with stable codes.',
|
|
73
|
+
'',
|
|
74
|
+
'```ts',
|
|
75
|
+
"import { createLintContext, createLinter, fromIdsDocument } from '@ifc-lite/ids-authoring';",
|
|
76
|
+
"import { parseIDS } from '@ifc-lite/ids';",
|
|
77
|
+
'',
|
|
78
|
+
'declare const xml: string;',
|
|
79
|
+
'const linter = createLinter(await createLintContext());',
|
|
80
|
+
'const { diagnostics } = linter.lint(fromIdsDocument(parseIDS(xml)));',
|
|
81
|
+
'for (const d of diagnostics) console.log(d.code, d.severity, d.message, d.fixes?.map((f) => f.label));',
|
|
82
|
+
'```',
|
|
83
|
+
'',
|
|
84
|
+
'Keep one linter per open document: specification-level findings are cached and only changed specifications are re-checked. A quick fix is a batch of Studio ops; check it with `checkQuickFix` (the grounding gate) and commit it like any other edit. A suppression in the sidecar (`meta.suppressions`, with a reason) silences a rule on a node and everything below it.',
|
|
85
|
+
'',
|
|
86
|
+
'Rules that depend on an IDS semantic the standard leaves open ship at `info` until the semantic is verified against the buildingSMART test cases; each rule page lists what was verified.',
|
|
87
|
+
'',
|
|
88
|
+
'Rules marked *opt-in* are off by default because they fire on most real documents. Enable one by giving it a severity in the linter config (`severity: { \'IDSL-SPEC-008\': \'info\' }`) or by naming it in `rules`.',
|
|
89
|
+
'',
|
|
90
|
+
];
|
|
91
|
+
const areas = [...new Set(rules.map((r) => r.area))];
|
|
92
|
+
for (const area of areas) {
|
|
93
|
+
lines.push(`## ${AREA_NAMES[area] ?? area}`, '', '| Code | Severity | Rule | Quick fix |', '|---|---|---|---|');
|
|
94
|
+
for (const r of rules.filter((x) => x.area === area))
|
|
95
|
+
lines.push(`| [${r.code}](${pageName(r.code)}) | ${severityLabel(r)} | ${r.title} | ${r.fix ? 'yes' : 'no'} |`);
|
|
96
|
+
lines.push('');
|
|
97
|
+
}
|
|
98
|
+
return lines.join('\n');
|
|
99
|
+
}
|
|
100
|
+
/** Every page of `docs/guide/ids-lint/`, keyed by file name. */
|
|
101
|
+
export function renderLintDocs(rules) {
|
|
102
|
+
const pages = new Map([['index.md', indexPage(rules)]]);
|
|
103
|
+
for (const r of rules)
|
|
104
|
+
pages.set(pageName(r.code), rulePage(r));
|
|
105
|
+
return pages;
|
|
106
|
+
}
|
|
107
|
+
/** The generated block of the mkdocs nav (indented for its place under "User Guide"). */
|
|
108
|
+
export function renderLintNav(rules, indent = ' ') {
|
|
109
|
+
const yamlString = (s) => JSON.stringify(s);
|
|
110
|
+
return [
|
|
111
|
+
`${indent}${NAV_BEGIN} (packages/ids-authoring/scripts/generate-lint-docs.mjs)`,
|
|
112
|
+
`${indent}- Overview: guide/ids-lint/index.md`,
|
|
113
|
+
...rules.map((r) => `${indent}- ${yamlString(`${r.code} ${r.title}`)}: guide/ids-lint/${pageName(r.code)}`),
|
|
114
|
+
`${indent}${NAV_END}`,
|
|
115
|
+
].join('\n');
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/lint/docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { StudioDocument } from '../document/types.js';
|
|
2
|
+
import type { Uuid } from '../uuid.js';
|
|
3
|
+
import type { LintContext, LintOptions, LintResult, LintRule } from './types.js';
|
|
4
|
+
export declare const LINT_DOCS_BASE = "https://ifclite.dev/docs/guide/ids-lint/";
|
|
5
|
+
export declare function lintDocsUrl(code: string): string;
|
|
6
|
+
export interface Linter {
|
|
7
|
+
/** The active rules, in registry order. */
|
|
8
|
+
readonly rules: readonly LintRule[];
|
|
9
|
+
lint(doc: StudioDocument, hint?: {
|
|
10
|
+
touched?: Iterable<Uuid>;
|
|
11
|
+
}): LintResult;
|
|
12
|
+
}
|
|
13
|
+
export interface LinterOptions extends LintOptions {
|
|
14
|
+
/** The rule registry to draw from (default: the full catalogue). */
|
|
15
|
+
registry?: readonly LintRule[];
|
|
16
|
+
}
|
|
17
|
+
/** Create an incremental linter. Keep one per open document. */
|
|
18
|
+
export declare function createLinter(ctx: LintContext, options?: LinterOptions): Linter;
|
|
19
|
+
/** One-shot lint of a whole document (no cache reuse). */
|
|
20
|
+
export declare function lintDocument(doc: StudioDocument, ctx: LintContext, options?: LinterOptions): LintResult;
|
|
21
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/lint/engine.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAyB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,KAAK,EAIV,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EAGT,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,cAAc,6CAA6C,CAAC;AAIzE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAWD,MAAM,WAAW,MAAM;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC;CAC5E;AAED,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,oEAAoE;IACpE,QAAQ,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CAChC;AAsBD,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAwElF;AAMD,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,aAAkB,GAAG,UAAU,CAE3G"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { LINT_RULES } from './rules/index.js';
|
|
5
|
+
import { applySuppressions } from './suppress.js';
|
|
6
|
+
import { specView } from './walk.js';
|
|
7
|
+
export const LINT_DOCS_BASE = 'https://ifclite.dev/docs/guide/ids-lint/';
|
|
8
|
+
const CODE = /^IDSL-[A-Z]+-\d{3}$/;
|
|
9
|
+
export function lintDocsUrl(code) {
|
|
10
|
+
return `${LINT_DOCS_BASE}${code.toLowerCase()}/`;
|
|
11
|
+
}
|
|
12
|
+
function validateRegistry(registry) {
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
for (const r of registry) {
|
|
15
|
+
if (!CODE.test(r.code))
|
|
16
|
+
throw new Error(`lint rule code "${r.code}" does not match IDSL-<AREA>-<nnn>`);
|
|
17
|
+
if (!r.code.startsWith(`IDSL-${r.area}-`))
|
|
18
|
+
throw new Error(`lint rule ${r.code} is filed under area ${r.area}`);
|
|
19
|
+
if (seen.has(r.code))
|
|
20
|
+
throw new Error(`duplicate lint rule code ${r.code}`);
|
|
21
|
+
seen.add(r.code);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function specTouched(nodes, touched) {
|
|
25
|
+
if (touched.size === 0)
|
|
26
|
+
return false;
|
|
27
|
+
if (touched.has(nodes.id))
|
|
28
|
+
return true;
|
|
29
|
+
for (const f of [...nodes.applicability, ...nodes.requirements]) {
|
|
30
|
+
if (touched.has(f.id))
|
|
31
|
+
return true;
|
|
32
|
+
for (const c of Object.values(f.constraints))
|
|
33
|
+
if (c && touched.has(c))
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/** Create an incremental linter. Keep one per open document. */
|
|
39
|
+
export function createLinter(ctx, options = {}) {
|
|
40
|
+
const registry = options.registry ?? LINT_RULES;
|
|
41
|
+
validateRegistry(registry);
|
|
42
|
+
const only = options.rules ? new Set(options.rules) : undefined;
|
|
43
|
+
const severityOf = (r) => options.severity?.[r.code] ?? r.defaultSeverity;
|
|
44
|
+
const enabled = (r) => {
|
|
45
|
+
if (severityOf(r) === 'off')
|
|
46
|
+
return false;
|
|
47
|
+
if (only)
|
|
48
|
+
return only.has(r.code);
|
|
49
|
+
return !r.optIn || options.severity?.[r.code] !== undefined;
|
|
50
|
+
};
|
|
51
|
+
const rules = registry.filter(enabled);
|
|
52
|
+
const specRules = rules.filter((r) => r.scope === 'spec');
|
|
53
|
+
const docRules = rules.filter((r) => r.scope === 'document');
|
|
54
|
+
const cache = new Map();
|
|
55
|
+
const stamp = (rule, f, specId) => {
|
|
56
|
+
const d = {
|
|
57
|
+
code: rule.code,
|
|
58
|
+
severity: options.severity?.[rule.code] ? severityOf(rule) : (f.severity ?? rule.defaultSeverity),
|
|
59
|
+
nodeId: f.nodeId,
|
|
60
|
+
message: f.message,
|
|
61
|
+
why: rule.rationale,
|
|
62
|
+
docsUrl: lintDocsUrl(rule.code),
|
|
63
|
+
};
|
|
64
|
+
if (specId)
|
|
65
|
+
d.specId = specId;
|
|
66
|
+
if (f.field)
|
|
67
|
+
d.field = f.field;
|
|
68
|
+
if (f.fixes?.length)
|
|
69
|
+
d.fixes = f.fixes;
|
|
70
|
+
return d;
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
rules,
|
|
74
|
+
lint(doc, hint = {}) {
|
|
75
|
+
const touched = new Set(hint.touched ?? []);
|
|
76
|
+
const input = { ctx, doc };
|
|
77
|
+
const views = doc.ids.specifications.map((s, i) => specView(s, doc.nodes.specs[i], i));
|
|
78
|
+
const next = new Map();
|
|
79
|
+
const diagnostics = [];
|
|
80
|
+
let specsLinted = 0;
|
|
81
|
+
for (const view of views) {
|
|
82
|
+
const prior = cache.get(view.specId);
|
|
83
|
+
const reusable = prior &&
|
|
84
|
+
prior.spec === view.spec &&
|
|
85
|
+
prior.nodes === view.nodes &&
|
|
86
|
+
prior.custom === doc.meta.custom &&
|
|
87
|
+
prior.bsddRevision === ctx.bsdd?.revision &&
|
|
88
|
+
!specTouched(view.nodes, touched);
|
|
89
|
+
let entry;
|
|
90
|
+
if (reusable) {
|
|
91
|
+
entry = prior;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
specsLinted++;
|
|
95
|
+
const found = specRules.flatMap((r) => r.check(view, input).map((f) => stamp(r, f, view.specId)));
|
|
96
|
+
entry = { spec: view.spec, nodes: view.nodes, custom: doc.meta.custom, bsddRevision: ctx.bsdd?.revision, diagnostics: found };
|
|
97
|
+
}
|
|
98
|
+
next.set(view.specId, entry);
|
|
99
|
+
diagnostics.push(...entry.diagnostics);
|
|
100
|
+
}
|
|
101
|
+
cache.clear();
|
|
102
|
+
for (const [k, v] of next)
|
|
103
|
+
cache.set(k, v);
|
|
104
|
+
const specOf = new Map(views.map((v) => [v.specId, v.specId]));
|
|
105
|
+
for (const r of docRules) {
|
|
106
|
+
for (const f of r.check(views, input)) {
|
|
107
|
+
const owner = specOf.get(f.nodeId) ?? views.find((v) => ownsNode(v.nodes, f.nodeId))?.specId;
|
|
108
|
+
diagnostics.push(stamp(r, f, owner));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const { active, suppressed } = applySuppressions(doc, diagnostics);
|
|
112
|
+
return { diagnostics: active, suppressed, stats: { specsLinted, specsReused: views.length - specsLinted } };
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function ownsNode(nodes, id) {
|
|
117
|
+
return specTouched(nodes, new Set([id]));
|
|
118
|
+
}
|
|
119
|
+
/** One-shot lint of a whole document (no cache reuse). */
|
|
120
|
+
export function lintDocument(doc, ctx, options = {}) {
|
|
121
|
+
return createLinter(ctx, options).lint(doc);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/lint/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick-fix contract helpers.
|
|
3
|
+
*
|
|
4
|
+
* A quick fix is a labelled op batch. Its op ids (and any node ids it
|
|
5
|
+
* mints) are derived deterministically from the rule code, the node and a
|
|
6
|
+
* variant tag, so the same document always yields byte-identical
|
|
7
|
+
* diagnostics; that keeps the engine cache and snapshot tests stable.
|
|
8
|
+
*
|
|
9
|
+
* `checkQuickFix` runs the batch through the grounding gate. Every fix the
|
|
10
|
+
* catalogue emits passes the gate on the document it was computed for
|
|
11
|
+
* (enforced by the rule tests).
|
|
12
|
+
*/
|
|
13
|
+
import type { StudioDocument } from '../document/types.js';
|
|
14
|
+
import type { GateContext } from '../gate/context.js';
|
|
15
|
+
import type { GateResult } from '../gate/types.js';
|
|
16
|
+
import type { PrimitiveOp } from '../ops/types.js';
|
|
17
|
+
import { type Uuid } from '../uuid.js';
|
|
18
|
+
import type { QuickFix } from './types.js';
|
|
19
|
+
/** Deterministic id source for one fix. */
|
|
20
|
+
export declare function fixIds(code: string, nodeId: Uuid, variant?: string): () => Uuid;
|
|
21
|
+
/** A primitive op without its `opId` (distributes over the union). */
|
|
22
|
+
export type OpBody = PrimitiveOp extends infer O ? (O extends PrimitiveOp ? Omit<O, 'opId'> : never) : never;
|
|
23
|
+
/** Build a quick fix from op bodies; op ids are derived. */
|
|
24
|
+
export declare function quickFix(label: string, code: string, nodeId: Uuid, variant: string, bodies: readonly OpBody[]): QuickFix;
|
|
25
|
+
/** Check a quick fix against the document it was computed for. */
|
|
26
|
+
export declare function checkQuickFix(doc: StudioDocument, fix: QuickFix, gate: GateContext): GateResult;
|
|
27
|
+
//# sourceMappingURL=fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/lint/fix.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAY,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,2CAA2C;AAC3C,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,SAAK,GAAG,MAAM,IAAI,CAI3E;AAED,sEAAsE;AACtE,MAAM,MAAM,MAAM,GAAG,WAAW,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,WAAW,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;AAE7G,4DAA4D;AAC5D,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,IAAI,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,QAAQ,CAIV;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAE/F"}
|
package/dist/lint/fix.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { checkOps } from '../gate/check.js';
|
|
5
|
+
import { deriveId } from '../uuid.js';
|
|
6
|
+
/** Deterministic id source for one fix. */
|
|
7
|
+
export function fixIds(code, nodeId, variant = '') {
|
|
8
|
+
let n = 0;
|
|
9
|
+
const seed = `lint|${code}|${nodeId}|${variant}`;
|
|
10
|
+
return () => deriveId(seed, `#${n++}`);
|
|
11
|
+
}
|
|
12
|
+
/** Build a quick fix from op bodies; op ids are derived. */
|
|
13
|
+
export function quickFix(label, code, nodeId, variant, bodies) {
|
|
14
|
+
const next = fixIds(code, nodeId, `${variant}|ops`);
|
|
15
|
+
const ops = bodies.map((b) => ({ ...b, opId: next() }));
|
|
16
|
+
return { label, ops };
|
|
17
|
+
}
|
|
18
|
+
/** Check a quick fix against the document it was computed for. */
|
|
19
|
+
export function checkQuickFix(doc, fix, gate) {
|
|
20
|
+
return checkOps(fix.ops, doc, gate);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/lint/fix.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAgB/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,OAAO,EAAE,QAAQ,EAAa,MAAM,YAAY,CAAC;AAGjD,2CAA2C;AAC3C,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,MAAY,EAAE,OAAO,GAAG,EAAE;IAC7D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,IAAI,GAAG,QAAQ,IAAI,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;IACjD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAKD,4DAA4D;AAC5D,MAAM,UAAU,QAAQ,CACtB,KAAa,EACb,IAAY,EACZ,MAAY,EACZ,OAAe,EACf,MAAyB;IAEzB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,MAAM,CAAC,CAAC;IACpD,MAAM,GAAG,GAAe,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACjF,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACxB,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,aAAa,CAAC,GAAmB,EAAE,GAAa,EAAE,IAAiB;IACjF,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lint precision measurement (IDS-054, FR-C05).
|
|
3
|
+
*
|
|
4
|
+
* Every finding on a labelled corpus file must be explained by a label:
|
|
5
|
+
* either a per-finding verdict (`file|code|message`) or, for `info` rules
|
|
6
|
+
* whose condition is a plain fact about the document (no description, an
|
|
7
|
+
* exact real comparison, …), a rule-level verdict. Unlabelled findings
|
|
8
|
+
* count as false positives, so a new rule cannot raise precision by
|
|
9
|
+
* staying silent about its findings.
|
|
10
|
+
*
|
|
11
|
+
* precision = justified / (justified + falsePositive + unlabelled)
|
|
12
|
+
*/
|
|
13
|
+
import type { IDSDocument } from '@ifc-lite/ids';
|
|
14
|
+
import type { LintContext, LintSeverity } from './types.js';
|
|
15
|
+
export interface Verdict {
|
|
16
|
+
verdict: 'justified' | 'false-positive';
|
|
17
|
+
reason: string;
|
|
18
|
+
}
|
|
19
|
+
export interface PrecisionLabels {
|
|
20
|
+
/** Rule-level verdicts, allowed for `info` rules only. */
|
|
21
|
+
rules: Record<string, Verdict>;
|
|
22
|
+
/** Per-finding verdicts keyed `file|code|message`. */
|
|
23
|
+
findings: Record<string, Verdict>;
|
|
24
|
+
}
|
|
25
|
+
export interface PrecisionCase {
|
|
26
|
+
file: string;
|
|
27
|
+
ids: IDSDocument;
|
|
28
|
+
}
|
|
29
|
+
/** Findings of one rule at one severity (a rule may demote individual findings). */
|
|
30
|
+
export interface RuleTally {
|
|
31
|
+
code: string;
|
|
32
|
+
severity: LintSeverity;
|
|
33
|
+
justified: number;
|
|
34
|
+
falsePositive: number;
|
|
35
|
+
unlabelled: number;
|
|
36
|
+
}
|
|
37
|
+
export interface PrecisionReport {
|
|
38
|
+
files: number;
|
|
39
|
+
findings: number;
|
|
40
|
+
precision: number;
|
|
41
|
+
/** Precision over warning and error findings only. */
|
|
42
|
+
precisionWarnError: number;
|
|
43
|
+
rules: RuleTally[];
|
|
44
|
+
unlabelled: string[];
|
|
45
|
+
falsePositives: string[];
|
|
46
|
+
/** Labels that matched no finding (stale). */
|
|
47
|
+
unusedLabels: string[];
|
|
48
|
+
}
|
|
49
|
+
export declare function findingKey(file: string, code: string, message: string): string;
|
|
50
|
+
export declare function measurePrecision(cases: readonly PrecisionCase[], labels: PrecisionLabels, ctx: LintContext): PrecisionReport;
|
|
51
|
+
//# sourceMappingURL=precision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"precision.d.ts","sourceRoot":"","sources":["../../src/lint/precision.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,WAAW,GAAG,gBAAgB,CAAC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;CAClB;AAED,oFAAoF;AACpF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAMD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9E;AAOD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,GAAG,eAAe,CA4C5H"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { fromIdsDocument } from '../document/from-ids.js';
|
|
5
|
+
import { lintDocument } from './engine.js';
|
|
6
|
+
import { LINT_RULES } from './rules/index.js';
|
|
7
|
+
function ratio(good, all) {
|
|
8
|
+
return all === 0 ? 1 : good / all;
|
|
9
|
+
}
|
|
10
|
+
export function findingKey(file, code, message) {
|
|
11
|
+
return `${file}|${code}|${message}`;
|
|
12
|
+
}
|
|
13
|
+
/** Precision covers the whole catalogue, so opt-in rules are switched on at their default severity. */
|
|
14
|
+
const ALL_RULES_ON = Object.fromEntries(LINT_RULES.filter((r) => r.optIn).map((r) => [r.code, r.defaultSeverity]));
|
|
15
|
+
export function measurePrecision(cases, labels, ctx) {
|
|
16
|
+
const tallies = new Map();
|
|
17
|
+
const unlabelled = [];
|
|
18
|
+
const falsePositives = [];
|
|
19
|
+
const used = new Set();
|
|
20
|
+
let findings = 0;
|
|
21
|
+
for (const c of cases) {
|
|
22
|
+
const { diagnostics } = lintDocument(fromIdsDocument(c.ids), ctx, { severity: ALL_RULES_ON });
|
|
23
|
+
for (const d of diagnostics) {
|
|
24
|
+
findings++;
|
|
25
|
+
const key = findingKey(c.file, d.code, d.message);
|
|
26
|
+
const tallyKey = `${d.code}|${d.severity}`;
|
|
27
|
+
const t = tallies.get(tallyKey) ?? { code: d.code, severity: d.severity, justified: 0, falsePositive: 0, unlabelled: 0 };
|
|
28
|
+
tallies.set(tallyKey, t);
|
|
29
|
+
const ruleLevel = d.severity === 'info' ? labels.rules[d.code] : undefined;
|
|
30
|
+
const v = labels.findings[key] ?? ruleLevel;
|
|
31
|
+
if (labels.findings[key])
|
|
32
|
+
used.add(key);
|
|
33
|
+
else if (ruleLevel)
|
|
34
|
+
used.add(`rule:${d.code}`);
|
|
35
|
+
if (!v) {
|
|
36
|
+
t.unlabelled++;
|
|
37
|
+
unlabelled.push(key);
|
|
38
|
+
}
|
|
39
|
+
else if (v.verdict === 'justified') {
|
|
40
|
+
t.justified++;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
t.falsePositive++;
|
|
44
|
+
falsePositives.push(key);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const rules = [...tallies.values()].sort((a, b) => a.code.localeCompare(b.code) || a.severity.localeCompare(b.severity));
|
|
49
|
+
const sum = (list, k) => list.reduce((n, t) => n + t[k], 0);
|
|
50
|
+
const all = (list) => sum(list, 'justified') + sum(list, 'falsePositive') + sum(list, 'unlabelled');
|
|
51
|
+
const we = rules.filter((t) => t.severity !== 'info');
|
|
52
|
+
const unusedLabels = [...Object.keys(labels.findings).filter((k) => !used.has(k)), ...Object.keys(labels.rules).filter((k) => !used.has(`rule:${k}`)).map((k) => `rule:${k}`)];
|
|
53
|
+
return {
|
|
54
|
+
files: cases.length,
|
|
55
|
+
findings,
|
|
56
|
+
precision: ratio(sum(rules, 'justified'), all(rules)),
|
|
57
|
+
precisionWarnError: ratio(sum(we, 'justified'), all(we)),
|
|
58
|
+
rules,
|
|
59
|
+
unlabelled,
|
|
60
|
+
falsePositives,
|
|
61
|
+
unusedLabels,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=precision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"precision.js","sourceRoot":"","sources":["../../src/lint/precision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bsdd.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/bsdd.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAsB,QAAQ,EAAE,MAAM,aAAa,CAAC;AAgBhE,eAAO,MAAM,QAAQ,EAAE,QAkCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,QA4BtB,CAAC;AAOF,eAAO,MAAM,QAAQ,EAAE,QAoCtB,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { quickFix } from '../fix.js';
|
|
5
|
+
import { allFacets, at, where } from '../walk.js';
|
|
6
|
+
import { gated, literals, single } from './util.js';
|
|
7
|
+
function uriOf(view) {
|
|
8
|
+
const f = view.facet;
|
|
9
|
+
return f.type === 'property' || f.type === 'classification' || f.type === 'material' ? f.uri : undefined;
|
|
10
|
+
}
|
|
11
|
+
function recordOf(view, ctx) {
|
|
12
|
+
const uri = uriOf(view);
|
|
13
|
+
return uri ? ctx.bsdd?.get(uri) : undefined;
|
|
14
|
+
}
|
|
15
|
+
const lastSegment = (uri) => decodeURIComponent(uri.slice(uri.lastIndexOf('/') + 1));
|
|
16
|
+
export const BSDD_001 = {
|
|
17
|
+
code: 'IDSL-BSDD-001',
|
|
18
|
+
area: 'BSDD',
|
|
19
|
+
scope: 'spec',
|
|
20
|
+
kind: 'static',
|
|
21
|
+
defaultSeverity: 'warning',
|
|
22
|
+
title: 'bSDD URI not found or inactive',
|
|
23
|
+
rationale: 'The facet points at a bSDD class or property that bSDD does not know (any more), or that its owner has deprecated. Tools that follow the URI find nothing or an outdated definition, and the classification or property the requirement asks for may no longer be maintained. URIs are checked in the background (rate-limited, cached for 24 hours); an unchecked URI is not reported.',
|
|
24
|
+
fix: 'Point the facet at the replacement bSDD publishes (and, for a classification, its code).',
|
|
25
|
+
example: '<classification uri="https://identifier.buildingsmart.org/uri/…/class/OLD-CODE" cardinality="required"> … </classification>',
|
|
26
|
+
check(spec, { ctx, doc }) {
|
|
27
|
+
const out = [];
|
|
28
|
+
for (const view of allFacets(spec)) {
|
|
29
|
+
const record = recordOf(view, ctx);
|
|
30
|
+
if (!record || (record.state !== 'notFound' && record.state !== 'inactive'))
|
|
31
|
+
continue;
|
|
32
|
+
const replacement = record.replacedBy?.length === 1 ? record.replacedBy[0] : undefined;
|
|
33
|
+
const message = record.state === 'notFound'
|
|
34
|
+
? `${where(view)}: bSDD does not know ${record.uri}`
|
|
35
|
+
: `${where(view)}: ${record.uri} is inactive in bSDD${record.replacedBy?.length ? `; replaced by ${record.replacedBy.join(', ')}` : ''}`;
|
|
36
|
+
let fixes;
|
|
37
|
+
if (replacement) {
|
|
38
|
+
const bodies = [{ kind: 'facet.setUri', payload: { facetId: view.facetId, uri: replacement } }];
|
|
39
|
+
const f = view.facet;
|
|
40
|
+
if (f.type === 'classification' && single(f.value) === lastSegment(record.uri)) {
|
|
41
|
+
bodies.push({ kind: 'value.set', payload: { facetId: view.facetId, field: 'classification.value', value: { kind: 'equals', value: lastSegment(replacement) } } });
|
|
42
|
+
}
|
|
43
|
+
fixes = gated(doc, ctx, [quickFix('Use the replacement', this.code, view.facetId, replacement, bodies)]);
|
|
44
|
+
}
|
|
45
|
+
out.push({ nodeId: view.facetId, message, ...(fixes ? { fixes } : {}) });
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
export const BSDD_002 = {
|
|
51
|
+
code: 'IDSL-BSDD-002',
|
|
52
|
+
area: 'BSDD',
|
|
53
|
+
scope: 'spec',
|
|
54
|
+
kind: 'static',
|
|
55
|
+
defaultSeverity: 'info',
|
|
56
|
+
title: 'Classification system differs from the bSDD dictionary name',
|
|
57
|
+
rationale: 'IDS checks a classification by its system name and code. When the facet references a bSDD class, the system should be the name of the dictionary that publishes the class, as bSDD gives it; authoring tools that write classifications from bSDD use that name, so a different or missing system name may match nothing.',
|
|
58
|
+
fix: 'Use the bSDD dictionary name as the system.',
|
|
59
|
+
example: '<classification uri="https://identifier.buildingsmart.org/uri/…/class/EW"><value><simpleValue>EW</simpleValue></value><system><simpleValue>My system</simpleValue></system></classification>',
|
|
60
|
+
check(spec, { ctx, doc }) {
|
|
61
|
+
const out = [];
|
|
62
|
+
for (const view of allFacets(spec)) {
|
|
63
|
+
const f = view.facet;
|
|
64
|
+
const record = recordOf(view, ctx);
|
|
65
|
+
const name = record?.dictionaryName;
|
|
66
|
+
if (f.type !== 'classification' || !name)
|
|
67
|
+
continue;
|
|
68
|
+
const system = f.system ? literals(f.system) : [];
|
|
69
|
+
if (system.includes(name) || (f.system && f.system.type === 'pattern'))
|
|
70
|
+
continue;
|
|
71
|
+
const fix = quickFix(`Use "${name}"`, this.code, view.facetId, name, [{ kind: 'value.set', payload: { facetId: view.facetId, field: 'classification.system', value: { kind: 'equals', value: name } } }]);
|
|
72
|
+
const message = system.length
|
|
73
|
+
? `${where(view)}: system "${system.join('", "')}" differs from the bSDD dictionary name "${name}"`
|
|
74
|
+
: `${where(view)}: no system; the bSDD dictionary is "${name}"`;
|
|
75
|
+
out.push({ ...at(view, 'classification.system'), message, fixes: gated(doc, ctx, [fix]) });
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
/** Literal values of a value constraint, or undefined when it is not a literal/enumeration. */
|
|
81
|
+
function valueLiterals(c) {
|
|
82
|
+
return c && (c.type === 'simpleValue' || c.type === 'enumeration') ? literals(c) : undefined;
|
|
83
|
+
}
|
|
84
|
+
export const BSDD_003 = {
|
|
85
|
+
code: 'IDSL-BSDD-003',
|
|
86
|
+
area: 'BSDD',
|
|
87
|
+
scope: 'spec',
|
|
88
|
+
kind: 'static',
|
|
89
|
+
defaultSeverity: 'warning',
|
|
90
|
+
title: 'Value outside the allowed values bSDD publishes',
|
|
91
|
+
rationale: 'The property requirement references a bSDD property with a list of allowed values, but its value (or enumeration) contains values that list does not have (neither as a code nor as a label). A model filled from bSDD can then never pass, or the IDS has drifted from the dictionary. Allowing fewer values than bSDD (a project narrowing) is fine and not reported.',
|
|
92
|
+
fix: 'Keep the values bSDD allows, or take its full list.',
|
|
93
|
+
example: '<property uri="https://identifier.buildingsmart.org/uri/…/prop/FireRating"> … <value><simpleValue>EI 60</simpleValue></value></property>',
|
|
94
|
+
check(spec, { ctx, doc }) {
|
|
95
|
+
const out = [];
|
|
96
|
+
for (const view of allFacets(spec)) {
|
|
97
|
+
const f = view.facet;
|
|
98
|
+
const record = recordOf(view, ctx);
|
|
99
|
+
const allowed = record?.allowedValues;
|
|
100
|
+
if (f.type !== 'property' || !allowed?.length)
|
|
101
|
+
continue;
|
|
102
|
+
const values = valueLiterals(f.value);
|
|
103
|
+
if (!values)
|
|
104
|
+
continue;
|
|
105
|
+
// A value may be written as the bSDD code or as its label.
|
|
106
|
+
const accepted = new Set([...allowed, ...(record?.allowedLabels ?? [])]);
|
|
107
|
+
const outside = values.filter((v) => !accepted.has(v));
|
|
108
|
+
if (!outside.length)
|
|
109
|
+
continue;
|
|
110
|
+
const kept = values.filter((v) => accepted.has(v));
|
|
111
|
+
const base = f.value && 'base' in f.value && f.value.base ? f.value.base : undefined;
|
|
112
|
+
const fixes = [
|
|
113
|
+
kept.length
|
|
114
|
+
? quickFix('Keep the allowed values', this.code, view.facetId, 'keep', [{ kind: 'value.set', payload: { facetId: view.facetId, field: 'property.value', value: { kind: 'raw', constraint: kept.length === 1 ? { type: 'simpleValue', value: kept[0] } : { type: 'enumeration', values: kept, ...(base ? { base } : {}) } } } }])
|
|
115
|
+
: undefined,
|
|
116
|
+
quickFix('Use the bSDD values', this.code, view.facetId, 'all', [{ kind: 'value.set', payload: { facetId: view.facetId, field: 'property.value', value: { kind: 'raw', constraint: { type: 'enumeration', values: [...allowed], ...(base ? { base } : {}) } } } }]),
|
|
117
|
+
];
|
|
118
|
+
out.push({ ...at(view, 'property.value'), message: `${where(view)}: ${outside.map((v) => `"${v}"`).join(', ')} not among the bSDD values (${allowed.join(', ')})`, fixes: gated(doc, ctx, fixes) });
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
//# sourceMappingURL=bsdd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bsdd.js","sourceRoot":"","sources":["../../../src/lint/rules/bsdd.ts"],"names":[],"mappings":"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"}
|