@remnic/core 9.65.6 → 9.65.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/dist/access-admin-ops-surface.d.ts +15 -13
- package/dist/access-admin-ops-surface.js +54 -54
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +15 -13
- package/dist/access-authorization-probe.js +55 -55
- package/dist/access-boundary.d.ts +15 -13
- package/dist/access-boundary.js +54 -54
- package/dist/access-cli.js +156 -148
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +2 -1
- package/dist/access-extraction-force-flush.d.ts +15 -13
- package/dist/access-extraction-force-flush.js +54 -54
- package/dist/access-health-types.d.ts +2 -1
- package/dist/access-http-lcm-compaction.d.ts +15 -13
- package/dist/access-http-lifecycle-flush.d.ts +15 -13
- package/dist/access-http-offline-stream.d.ts +15 -13
- package/dist/access-http-query.d.ts +3 -2
- package/dist/access-http-query.js +56 -56
- package/dist/access-http.d.ts +17 -20
- package/dist/access-http.js +75 -73
- package/dist/access-identity-continuity-surface.d.ts +13 -11
- package/dist/access-identity-continuity-surface.js +54 -54
- package/dist/access-lcm-surface.d.ts +15 -13
- package/dist/access-lcm-surface.js +54 -54
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +15 -13
- package/dist/access-mcp.js +66 -64
- package/dist/access-memory-search-fanout.d.ts +3 -2
- package/dist/{access-namespace-preflight-D_6mo8ms.d.ts → access-namespace-preflight-CpAOrS-9.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +4 -3
- package/dist/access-namespace-preflight.js +54 -54
- package/dist/access-observe-write-surface.d.ts +15 -13
- package/dist/access-observe-write-surface.js +54 -54
- package/dist/access-offline-manifest.d.ts +13 -11
- package/dist/access-offline-manifest.js +6 -6
- package/dist/access-operations-batch.js +58 -58
- package/dist/access-operations.d.ts +21 -19
- package/dist/access-operations.js +63 -61
- package/dist/access-recall-concurrency.d.ts +15 -13
- package/dist/access-recall-concurrency.js +54 -54
- package/dist/access-recall-response.d.ts +15 -13
- package/dist/access-recall-response.js +54 -54
- package/dist/access-recall-surface.d.ts +15 -13
- package/dist/access-recall-surface.js +54 -54
- package/dist/access-schema.d.ts +83 -83
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-sbiNS5UB.d.ts → access-service-Diu61Cfv.d.ts} +72 -72
- package/dist/access-service-helpers.d.ts +15 -13
- package/dist/access-service.d.ts +15 -13
- package/dist/access-service.js +54 -54
- package/dist/access-surface-catalog.d.ts +15 -13
- package/dist/access-surface-catalog.js +66 -56
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +6 -3
- package/dist/action-confidence.d.ts +2 -1
- package/dist/active-context-config.d.ts +27 -0
- package/dist/active-context-config.js +14 -0
- package/dist/active-context-transform.d.ts +267 -0
- package/dist/active-context-transform.js +31 -0
- package/dist/active-memory-bridge.d.ts +2 -1
- package/dist/active-recall.d.ts +2 -1
- package/dist/active-recall.js +13 -12
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +2 -1
- package/dist/artifact-search.d.ts +2 -1
- package/dist/{auto-sync-XVMLL2RH.js → auto-sync-2YPITIWN.js} +6 -6
- package/dist/behavior-learner.d.ts +2 -1
- package/dist/behavior-signals.d.ts +2 -1
- package/dist/bootstrap.d.ts +13 -11
- package/dist/briefing-window.d.ts +5 -2
- package/dist/briefing.d.ts +5 -2
- package/dist/briefing.js +25 -25
- package/dist/buffer-surprise-report.d.ts +2 -1
- package/dist/buffer-turn-helpers.d.ts +2 -1
- package/dist/buffer.d.ts +5 -2
- package/dist/buffer.js +6 -6
- package/dist/bulk-import/index.d.ts +4 -3
- package/dist/calibration.d.ts +2 -1
- package/dist/capabilities.d.ts +2 -1
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/{catalog-DO_7zfkv.d.ts → catalog-9f-vEQLS.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +4 -3
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +2 -1
- package/dist/causal-consolidation.js +28 -28
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +2 -1
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-NZPFCP5A.js → chunk-2PSX5BJU.js} +2 -2
- package/dist/{chunk-RKNJBZ55.js → chunk-2QSZNTDO.js} +4 -4
- package/dist/{chunk-X2DWBWOX.js → chunk-3A2NJP2U.js} +2 -2
- package/dist/chunk-3BCULS4U.js +1093 -0
- package/dist/chunk-3BCULS4U.js.map +1 -0
- package/dist/{chunk-JGG5HVI2.js → chunk-3PKAS6VL.js} +2 -2
- package/dist/{chunk-LSYD7GHZ.js → chunk-3SZD4CYO.js} +3 -3
- package/dist/chunk-43HUVDTD.js +114 -0
- package/dist/chunk-43HUVDTD.js.map +1 -0
- package/dist/{chunk-5TG4MU2U.js → chunk-4F4AQFWL.js} +8 -8
- package/dist/{chunk-D35XLYQ7.js → chunk-4QEYREAV.js} +12 -12
- package/dist/{chunk-46WM6JX2.js → chunk-4ZWCQJNM.js} +5 -5
- package/dist/{chunk-DVYRD4HY.js → chunk-5ACCD4L7.js} +30 -1
- package/dist/chunk-5ACCD4L7.js.map +1 -0
- package/dist/{chunk-W6J4POB6.js → chunk-5DHKCO52.js} +2 -2
- package/dist/{chunk-IRXMJLTW.js → chunk-5HK3CJAR.js} +2 -2
- package/dist/{chunk-NLUCDKLT.js → chunk-5RWZH6PH.js} +2 -2
- package/dist/{chunk-H7BZBSP6.js → chunk-645WOU5I.js} +4 -4
- package/dist/{chunk-AYAZWXJI.js → chunk-76DIF5KT.js} +2 -2
- package/dist/{chunk-OPPBTPUU.js → chunk-7KQB4EBS.js} +4 -4
- package/dist/{chunk-I2HTKOOP.js → chunk-7VZFRUQU.js} +3 -3
- package/dist/{chunk-DPNXADEI.js → chunk-7WOWGRAU.js} +11 -7
- package/dist/chunk-7WOWGRAU.js.map +1 -0
- package/dist/{chunk-JCWY73FK.js → chunk-AHPIFKNG.js} +2 -2
- package/dist/{chunk-FC7TIRFS.js → chunk-AX7UXCHJ.js} +6 -1
- package/dist/chunk-AX7UXCHJ.js.map +1 -0
- package/dist/{chunk-3I22VWB3.js → chunk-AZMLH5UT.js} +2 -2
- package/dist/chunk-B32WYRXX.js +77 -0
- package/dist/chunk-B32WYRXX.js.map +1 -0
- package/dist/{chunk-JOEJG4SD.js → chunk-BEC4YBNA.js} +4 -4
- package/dist/chunk-BWGCOLEL.js +61 -0
- package/dist/chunk-BWGCOLEL.js.map +1 -0
- package/dist/{chunk-BXXOPKT5.js → chunk-CAMNRAJF.js} +2 -2
- package/dist/{chunk-C24UZSFW.js → chunk-CEH2AFXG.js} +6 -6
- package/dist/{chunk-YOXVZJFM.js → chunk-CFVTRUR3.js} +2 -2
- package/dist/{chunk-SVSRPG6M.js → chunk-CPA5NBHN.js} +2 -2
- package/dist/{chunk-7BEPVIH3.js → chunk-CRML27CO.js} +3 -3
- package/dist/{chunk-AXGFOFNY.js → chunk-DA7ITC5Z.js} +2 -2
- package/dist/{chunk-5W7MKXMU.js → chunk-DEACDKE3.js} +144 -78
- package/dist/chunk-DEACDKE3.js.map +1 -0
- package/dist/{chunk-FEO2CDXR.js → chunk-DPCXDG7G.js} +2 -2
- package/dist/{chunk-HZNYJN77.js → chunk-F3NVYTTA.js} +2 -2
- package/dist/{chunk-7SSRXEZJ.js → chunk-F7XUD3PL.js} +2 -2
- package/dist/{chunk-LDBFXD4F.js → chunk-FP7YTTVO.js} +3 -1
- package/dist/chunk-FP7YTTVO.js.map +1 -0
- package/dist/{chunk-XZBXINXZ.js → chunk-GIC6BASP.js} +4 -4
- package/dist/{chunk-PP7R754B.js → chunk-GPFZFCRN.js} +1 -1
- package/dist/{chunk-53MZQEBD.js → chunk-GTO56JY5.js} +2 -2
- package/dist/{chunk-RAIUTAZZ.js → chunk-H2YSH3DG.js} +2 -2
- package/dist/{chunk-HWVNYNIV.js → chunk-HMZKGHMD.js} +2 -2
- package/dist/{chunk-ZXUZ54Z5.js → chunk-HRHO3ZNG.js} +2 -2
- package/dist/{chunk-SDEPLF7V.js → chunk-IBJ6U753.js} +2 -2
- package/dist/chunk-JCCWJHOP.js +240 -0
- package/dist/chunk-JCCWJHOP.js.map +1 -0
- package/dist/{chunk-T3JQTCCO.js → chunk-JI7U6AS3.js} +4 -4
- package/dist/{chunk-TR7DGXGI.js → chunk-JOZUBF4A.js} +5 -5
- package/dist/{chunk-YWBOOBDP.js → chunk-JYSN42VN.js} +71 -71
- package/dist/{chunk-ZPUIRTIZ.js → chunk-KOLJJN5G.js} +12 -75
- package/dist/chunk-KOLJJN5G.js.map +1 -0
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-D2YNNDML.js → chunk-KWIGDKM2.js} +2 -2
- package/dist/{chunk-YUTTMSC7.js → chunk-KZIF6XHX.js} +93 -30
- package/dist/chunk-KZIF6XHX.js.map +1 -0
- package/dist/chunk-LB7WCZHY.js +553 -0
- package/dist/chunk-LB7WCZHY.js.map +1 -0
- package/dist/{chunk-RIAM7DND.js → chunk-LDKPDODJ.js} +2 -2
- package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
- package/dist/{chunk-2JHRCWHT.js → chunk-LKYIOCWL.js} +107 -107
- package/dist/{chunk-XAWIL7TC.js → chunk-LOXHYCVS.js} +2 -2
- package/dist/{chunk-OMZLBT4B.js → chunk-LPNCR4QK.js} +48 -27
- package/dist/chunk-LPNCR4QK.js.map +1 -0
- package/dist/{chunk-OLBZ2WGG.js → chunk-LTBKKSCX.js} +2 -2
- package/dist/{chunk-O4BAGJDN.js → chunk-MDD2RINF.js} +2 -2
- package/dist/{chunk-H63EDPFJ.js → chunk-MI2OTWV5.js} +15 -2
- package/dist/{chunk-H63EDPFJ.js.map → chunk-MI2OTWV5.js.map} +1 -1
- package/dist/{chunk-LBFFNDFM.js → chunk-MINHJ55X.js} +1 -1
- package/dist/chunk-MINHJ55X.js.map +1 -0
- package/dist/{chunk-ROEAEANL.js → chunk-MY2BC6UE.js} +15 -15
- package/dist/{chunk-RACZB5HT.js → chunk-N37X5RU7.js} +4 -4
- package/dist/{chunk-AG46P24C.js → chunk-NNBZS3DY.js} +4 -4
- package/dist/{chunk-PGW64IFQ.js → chunk-NPFUNWNX.js} +2 -2
- package/dist/{chunk-MFOSZUIT.js → chunk-NPIBN2VL.js} +2 -2
- package/dist/{chunk-IF4EY26E.js → chunk-OA2O2GJ4.js} +3 -3
- package/dist/{chunk-6FUMA6AA.js → chunk-ODU2CNNX.js} +2 -2
- package/dist/{chunk-PNAGNVGK.js → chunk-OXRRJXPR.js} +42 -37
- package/dist/chunk-OXRRJXPR.js.map +1 -0
- package/dist/{chunk-TWBQQ3FT.js → chunk-P36Z4JRA.js} +2 -2
- package/dist/{chunk-OUKBMQ2O.js → chunk-PD66CVSD.js} +2 -2
- package/dist/{chunk-MVIYRRVJ.js → chunk-PMVPCZJZ.js} +5 -5
- package/dist/{chunk-US4IRASK.js → chunk-PU56CXZA.js} +6 -6
- package/dist/{chunk-IDQ6DKXC.js → chunk-S5XOSTYM.js} +3 -3
- package/dist/{chunk-DYO24BNB.js → chunk-SEEJOGQX.js} +5 -5
- package/dist/{chunk-7OZSHBWK.js → chunk-SNOIKAHM.js} +2 -2
- package/dist/{chunk-SR7JIRAR.js → chunk-T6ILXUAH.js} +2 -2
- package/dist/{chunk-2RXUZVPU.js → chunk-T7XP6IZE.js} +2 -2
- package/dist/{chunk-KBOG7FJV.js → chunk-TFR3HG4K.js} +3 -3
- package/dist/{chunk-XUZ5CIEE.js → chunk-TUHBYJXL.js} +1 -1
- package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
- package/dist/{chunk-ZK4BFABK.js → chunk-U7EW2W4W.js} +13 -13
- package/dist/{chunk-4K7IW3F7.js → chunk-UD7UNYRD.js} +34 -3
- package/dist/chunk-UD7UNYRD.js.map +1 -0
- package/dist/{chunk-VFYRYFLL.js → chunk-UEBDCMOO.js} +2 -2
- package/dist/{chunk-JFWZRUKP.js → chunk-UENKPWCS.js} +4 -4
- package/dist/{chunk-AAXJNINV.js → chunk-UL4MKZHI.js} +2 -2
- package/dist/chunk-ULM7JCDH.js +154 -0
- package/dist/chunk-ULM7JCDH.js.map +1 -0
- package/dist/{chunk-R2MZCYA6.js → chunk-UNUMFURP.js} +3 -3
- package/dist/{chunk-5GIZM4RX.js → chunk-UPFNQJC7.js} +2 -2
- package/dist/{chunk-W4BMEGQA.js → chunk-UTQUEHC7.js} +2 -2
- package/dist/{chunk-I32NKXE2.js → chunk-V4IDF3EZ.js} +2 -2
- package/dist/{chunk-6LS5OX3U.js → chunk-W2BAGGEW.js} +50 -18
- package/dist/chunk-W2BAGGEW.js.map +1 -0
- package/dist/chunk-W2UOAATB.js +521 -0
- package/dist/chunk-W2UOAATB.js.map +1 -0
- package/dist/{chunk-QMZY3GG6.js → chunk-WNXYT4MK.js} +3 -3
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-T42L3S6A.js → chunk-XBGHAAKR.js} +2 -2
- package/dist/{chunk-RQ2EQRRR.js → chunk-XNWXSGHS.js} +80 -7
- package/dist/chunk-XNWXSGHS.js.map +1 -0
- package/dist/{chunk-THG4GYIE.js → chunk-YEUXERJ6.js} +5 -5
- package/dist/{chunk-BIJAWZYW.js → chunk-YMOPYG3K.js} +6 -6
- package/dist/{chunk-M4AHBM72.js → chunk-Z3YEGSR4.js} +2 -2
- package/dist/{cli-Bfgo0n1L.d.ts → cli-O3F-ht3i.d.ts} +5 -5
- package/dist/cli.d.ts +17 -15
- package/dist/cli.js +106 -104
- package/dist/coding/pre-action-gate.d.ts +2 -1
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.d.ts +5 -2
- package/dist/compounding/engine.js +26 -26
- package/dist/compounding/preference-consolidator.d.ts +4 -3
- package/dist/compression-optimizer.d.ts +2 -1
- package/dist/config-security.js +2 -2
- package/dist/config.d.ts +2 -1
- package/dist/config.js +13 -12
- package/dist/connectors/codex-materialize-runner.d.ts +2 -1
- package/dist/connectors/codex-materialize-runner.js +25 -25
- package/dist/connectors/codex-materialize.d.ts +2 -1
- package/dist/connectors/index.d.ts +2 -1
- package/dist/connectors/index.js +25 -25
- package/dist/consolidation-provenance-check.d.ts +5 -2
- package/dist/consolidation-provenance-check.js +2 -2
- package/dist/consolidation-undo.d.ts +5 -2
- package/dist/context-summary.d.ts +43 -0
- package/dist/context-summary.js +14 -0
- package/dist/context-summary.js.map +1 -0
- package/dist/contradiction/index.d.ts +6 -3
- package/dist/contradiction/index.js +5 -5
- package/dist/converge-config.d.ts +2 -1
- package/dist/convergence-refresh.d.ts +5 -2
- package/dist/convergence-refresh.js +28 -28
- package/dist/conversation-index/backend.d.ts +2 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +2 -1
- package/dist/conversation-index/faiss-adapter.d.ts +2 -1
- package/dist/conversation-index/indexer.d.ts +2 -1
- package/dist/conversation-index/search.d.ts +2 -1
- package/dist/corpus-watermark.d.ts +2 -1
- package/dist/corpus-watermark.js +27 -27
- package/dist/cross-lingual-recall.d.ts +2 -1
- package/dist/day-summary.d.ts +2 -1
- package/dist/delinearize.d.ts +2 -1
- package/dist/dependency-propagation-config.d.ts +2 -1
- package/dist/{dependency-propagation-delivery-D23_x-s5.d.ts → dependency-propagation-delivery-CL6RWXTA.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +2 -1
- package/dist/direct-answer.d.ts +2 -1
- package/dist/embedding-fallback.d.ts +2 -1
- package/dist/enrichment/index.d.ts +2 -1
- package/dist/entity-origin-fields.d.ts +2 -1
- package/dist/entity-retrieval.d.ts +5 -2
- package/dist/entity-retrieval.js +26 -26
- package/dist/entity-schema.d.ts +2 -1
- package/dist/episodic-context.d.ts +2 -1
- package/dist/eval-trajectory-contracts.d.ts +257 -0
- package/dist/eval-trajectory-contracts.js +56 -0
- package/dist/eval-trajectory-contracts.js.map +1 -0
- package/dist/eval-trajectory-store.d.ts +40 -0
- package/dist/eval-trajectory-store.js +19 -0
- package/dist/eval-trajectory-store.js.map +1 -0
- package/dist/eval-trajectory.d.ts +68 -0
- package/dist/eval-trajectory.js +46 -0
- package/dist/eval-trajectory.js.map +1 -0
- package/dist/event-order-recall.js +2 -2
- package/dist/explicit-capture.d.ts +13 -11
- package/dist/explicit-capture.js +6 -6
- package/dist/external-wiki-access.d.ts +15 -13
- package/dist/external-wiki-access.js +55 -55
- package/dist/external-wiki-collection-registration.d.ts +2 -1
- package/dist/external-wiki-collection.d.ts +2 -1
- package/dist/external-wiki-mcp-tools.d.ts +15 -13
- package/dist/extraction-error-classification.d.ts +2 -1
- package/dist/extraction-faithfulness.d.ts +2 -1
- package/dist/extraction-judge-telemetry.d.ts +2 -1
- package/dist/extraction-judge-training.d.ts +2 -1
- package/dist/extraction-judge.d.ts +2 -1
- package/dist/extraction-liveness.d.ts +2 -1
- package/dist/extraction-normalization.d.ts +2 -1
- package/dist/extraction-prompt.d.ts +2 -1
- package/dist/extraction-source-grounding-rules.d.ts +2 -1
- package/dist/extraction-source-grounding.d.ts +2 -1
- package/dist/extraction.d.ts +2 -1
- package/dist/extraction.js +33 -33
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/{forget-SZ2BXDGF.js → forget-2AE4MDK3.js} +3 -3
- package/dist/graph-dashboard-diff.d.ts +2 -1
- package/dist/graph-dashboard-key.d.ts +2 -1
- package/dist/graph-dashboard-parser.d.ts +2 -1
- package/dist/{graph-edge-decay-FXGELBFA.js → graph-edge-decay-A4SDFMMS.js} +4 -4
- package/dist/graph-edge-decay-A4SDFMMS.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +2 -1
- package/dist/graph-path-reconstruction.d.ts +2 -1
- package/dist/graph-path-scoring.d.ts +2 -1
- package/dist/graph-snapshot.d.ts +2 -1
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.d.ts +2 -1
- package/dist/graph.js +3 -3
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +2 -1
- package/dist/importers/index.d.ts +2 -1
- package/dist/in-flight-reads.d.ts +2 -1
- package/dist/{index--QhGIXF2.d.ts → index-C7Xep6S9.d.ts} +2 -2
- package/dist/index.d.ts +706 -701
- package/dist/index.js +271 -200
- package/dist/intent.d.ts +2 -1
- package/dist/lcm/engine.d.ts +3 -2
- package/dist/lcm/engine.js +3 -2
- package/dist/lcm/index.d.ts +4 -2
- package/dist/lcm/index.js +6 -5
- package/dist/lcm/summarizer.d.ts +4 -6
- package/dist/lcm/summarizer.js +2 -1
- package/dist/lcm/tools.d.ts +4 -3
- package/dist/lifecycle.d.ts +2 -1
- package/dist/live-connectors-runner.d.ts +2 -1
- package/dist/local-llm.d.ts +2 -1
- package/dist/local-model-endpoint.d.ts +2 -1
- package/dist/location/index.d.ts +128 -1
- package/dist/location/index.js +60 -750
- package/dist/location/index.js.map +1 -1
- package/dist/maintenance/memory-governance.d.ts +2 -1
- package/dist/maintenance/memory-governance.js +26 -26
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +5 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +25 -25
- package/dist/maintenance/rebuild-memory-projection.d.ts +5 -2
- package/dist/maintenance/rebuild-memory-projection.js +27 -27
- package/dist/{maintenance-PFvY1Pw_.d.ts → maintenance-CJ-xqFp0.d.ts} +4 -3
- package/dist/mcp-memory-inspector-app.d.ts +15 -13
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +18 -2
- package/dist/memory-action-policy.js +3 -1
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-controller.d.ts +2 -1
- package/dist/memory-controller.js +2 -2
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-projection-store.d.ts +2 -1
- package/dist/memory-provenance.d.ts +2 -1
- package/dist/memory-snapshot.d.ts +2 -1
- package/dist/memory-subject-cli.d.ts +15 -13
- package/dist/memory-subject.d.ts +15 -13
- package/dist/memory-subject.js +3 -3
- package/dist/memory-worth-outcomes.d.ts +50 -3
- package/dist/memory-worth-outcomes.js +5 -3
- package/dist/models-json.d.ts +2 -1
- package/dist/namespaces/migrate.d.ts +6 -3
- package/dist/namespaces/migrate.js +26 -26
- package/dist/namespaces/principal.d.ts +2 -1
- package/dist/namespaces/search.d.ts +2 -1
- package/dist/namespaces/search.js +11 -11
- package/dist/namespaces/storage.d.ts +6 -3
- package/dist/namespaces/storage.js +25 -25
- package/dist/native-knowledge.d.ts +2 -1
- package/dist/offline-sync-impression-drain.d.ts +2 -1
- package/dist/offline-sync-impression-drain.js +2 -2
- package/dist/operator-doctor-corpus.d.ts +2 -1
- package/dist/operator-doctor-corpus.js +28 -28
- package/dist/operator-doctor-replica.d.ts +2 -1
- package/dist/operator-toolkit.d.ts +6 -3
- package/dist/operator-toolkit.js +45 -44
- package/dist/orchestration/compression-guideline-coordinator.d.ts +5 -2
- package/dist/orchestration/maintenance.d.ts +7 -4
- package/dist/orchestration/maintenance.js +34 -32
- package/dist/{orchestrator-4wzJrPVm.d.ts → orchestrator-BsntWxLy.d.ts} +8 -8
- package/dist/orchestrator.d.ts +13 -11
- package/dist/orchestrator.js +156 -148
- package/dist/patterns-cli.d.ts +2 -1
- package/dist/{pipeline-CgXgdIrF.d.ts → pipeline-CVoysPm2.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +2 -1
- package/dist/proactive-contention.d.ts +2 -1
- package/dist/provenance.d.ts +2 -1
- package/dist/{public-http-BP3VQDl5.d.ts → public-http-CuOxlTC2.d.ts} +1 -1
- package/dist/{qmd-BppGGxsi.d.ts → qmd-DWMAGA5l.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +3 -2
- package/dist/qmd-recall-cache.d.ts +2 -1
- package/dist/qmd.d.ts +3 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +2 -1
- package/dist/recall-disclosure-escalation.d.ts +2 -1
- package/dist/recall-explain-renderer.d.ts +2 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +2 -1
- package/dist/recall-planner-llm.d.ts +2 -1
- package/dist/recall-state.d.ts +2 -1
- package/dist/recall-tag-filter.d.ts +2 -1
- package/dist/recall-timings.d.ts +2 -1
- package/dist/recall-xray-cli.d.ts +2 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +2 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +2 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +2 -1
- package/dist/reconcile/manifest.d.ts +2 -1
- package/dist/reconcile/manifest.js +3 -3
- package/dist/reconcile/plan.d.ts +2 -1
- package/dist/replay/normalizers/chatgpt.d.ts +2 -1
- package/dist/replay/normalizers/claude.d.ts +2 -1
- package/dist/replay/normalizers/openclaw.d.ts +2 -1
- package/dist/replay/normalizers/shared.d.ts +2 -1
- package/dist/replay/runner.d.ts +2 -1
- package/dist/replay/types.d.ts +2 -1
- package/dist/replica-divergence.d.ts +2 -1
- package/dist/replica-peers-config.d.ts +2 -1
- package/dist/{resolution-4552BNRV.js → resolution-XWBPKYFB.js} +6 -6
- package/dist/resolution-XWBPKYFB.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +2 -1
- package/dist/resume-bundles.js +14 -13
- package/dist/retrieval-agents.d.ts +3 -2
- package/dist/retrieval-tiers.d.ts +2 -1
- package/dist/routing/engine.d.ts +2 -1
- package/dist/routing/store.d.ts +2 -1
- package/dist/salvage-envelope.d.ts +2 -1
- package/dist/salvage-envelope.js +5 -5
- package/dist/schemas.d.ts +124 -124
- package/dist/{scope-profiles-ChZUtxDU.d.ts → scope-profiles-CPWkW_dI.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +2 -1
- package/dist/search/factory.d.ts +2 -1
- package/dist/search/factory.js +10 -10
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.js +15 -15
- package/dist/search/lancedb-backend.d.ts +2 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +2 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +2 -1
- package/dist/search/orama-backend.d.ts +2 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +2 -1
- package/dist/search/remote-backend.d.ts +2 -1
- package/dist/{semantic-consolidation-mSPwQSmF.d.ts → semantic-consolidation-CNFVBXFc.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +3 -2
- package/dist/semantic-consolidation.js +31 -31
- package/dist/semantic-rule-promotion.js +25 -25
- package/dist/semantic-rule-verifier.d.ts +2 -1
- package/dist/semantic-rule-verifier.js +25 -25
- package/dist/{service-BICWLwSP.d.ts → service-Bb-JIdQ0.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +2 -1
- package/dist/session-observer-state.d.ts +2 -1
- package/dist/shared-context/manager.d.ts +8 -7
- package/dist/signal.d.ts +2 -1
- package/dist/source-agent-qualifier.d.ts +2 -1
- package/dist/source-agent-qualifier.js +29 -29
- package/dist/{storage-B7urx1K3.d.ts → storage-CukrlNKk.d.ts} +4 -1
- package/dist/storage.d.ts +5 -2
- package/dist/storage.js +24 -24
- package/dist/subject-config.d.ts +2 -1
- package/dist/subject-config.js +4 -4
- package/dist/summarizer.d.ts +2 -1
- package/dist/summary-snapshot.d.ts +2 -1
- package/dist/support-passport/index.d.ts +18 -16
- package/dist/support-passport/index.js +57 -57
- package/dist/temporal-supersession.d.ts +3 -2
- package/dist/temporal-timeline-recall.d.ts +2 -1
- package/dist/temporal-validity.d.ts +2 -1
- package/dist/threading.d.ts +2 -1
- package/dist/tier-migration.d.ts +5 -2
- package/dist/tier-routing.d.ts +2 -1
- package/dist/topics.d.ts +2 -1
- package/dist/transcript.d.ts +2 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/types.d.ts +78 -78
- package/dist/trust-score-stage.d.ts +2 -1
- package/dist/trust-score.d.ts +2 -1
- package/dist/{types-ETU5N6nB.d.ts → types-djxQlxJ7.d.ts} +3 -2
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -1
- package/dist/verified-recall.js +25 -25
- package/dist/who-knows-cli.d.ts +15 -13
- package/dist/who-knows-cli.js +26 -26
- package/dist/who-knows.d.ts +15 -13
- package/dist/who-knows.js +25 -25
- package/dist/write-envelope.d.ts +2 -1
- package/dist/write-envelope.js +4 -4
- package/package.json +22 -2
- package/src/access-boundary.ts +5 -0
- package/src/access-http.ts +15 -16
- package/src/access-mcp-output-schemas.ts +5 -0
- package/src/access-mcp.ts +6 -6
- package/src/access-operations.ts +2 -0
- package/src/access-surface-catalog.ts +10 -0
- package/src/active-context-config.ts +98 -0
- package/src/active-context-transform.test.ts +533 -0
- package/src/active-context-transform.ts +981 -0
- package/src/config.ts +3 -5
- package/src/context-summary.ts +182 -0
- package/src/eval-trajectory-contracts.ts +411 -0
- package/src/eval-trajectory-store.ts +306 -0
- package/src/eval-trajectory.test.ts +534 -0
- package/src/eval-trajectory.ts +773 -0
- package/src/index.ts +6 -11
- package/src/lcm/summarizer.ts +14 -93
- package/src/location/access-operations.ts +84 -0
- package/src/location/http-glue.test.ts +100 -0
- package/src/location/http-glue.ts +85 -0
- package/src/location/index.ts +3 -0
- package/src/location/mcp-tools.ts +82 -0
- package/src/location/provider-setup.test.ts +106 -0
- package/src/location/provider-setup.ts +103 -0
- package/src/location/scheduler.test.ts +113 -0
- package/src/location/scheduler.ts +98 -0
- package/src/location/surfaces.test.ts +241 -0
- package/src/location/surfaces.ts +329 -0
- package/src/maintenance/day-summary-cron.ts +45 -0
- package/src/mcp-read-only-tools.ts +2 -0
- package/src/memory-action-policy.ts +28 -0
- package/src/memory-worth-outcomes.test.ts +53 -18
- package/src/memory-worth-outcomes.ts +91 -9
- package/src/orchestration/maintenance.ts +22 -30
- package/src/storage/context-transform-ledger.ts +39 -0
- package/src/storage/secure-line-reader.ts +50 -1
- package/src/storage.ts +4 -1
- package/src/types.ts +2 -3
- package/src/wearables/http-glue.ts +28 -0
- package/dist/chunk-4K7IW3F7.js.map +0 -1
- package/dist/chunk-5W7MKXMU.js.map +0 -1
- package/dist/chunk-6LS5OX3U.js.map +0 -1
- package/dist/chunk-DPNXADEI.js.map +0 -1
- package/dist/chunk-DVYRD4HY.js.map +0 -1
- package/dist/chunk-FC7TIRFS.js.map +0 -1
- package/dist/chunk-LBFFNDFM.js.map +0 -1
- package/dist/chunk-LDBFXD4F.js.map +0 -1
- package/dist/chunk-OMZLBT4B.js.map +0 -1
- package/dist/chunk-PNAGNVGK.js.map +0 -1
- package/dist/chunk-RQ2EQRRR.js.map +0 -1
- package/dist/chunk-YUTTMSC7.js.map +0 -1
- package/dist/chunk-ZPUIRTIZ.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → active-context-config.js.map} +0 -0
- /package/dist/{graph-edge-decay-FXGELBFA.js.map → active-context-transform.js.map} +0 -0
- /package/dist/{auto-sync-XVMLL2RH.js.map → auto-sync-2YPITIWN.js.map} +0 -0
- /package/dist/{resolution-4552BNRV.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-NZPFCP5A.js.map → chunk-2PSX5BJU.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-X2DWBWOX.js.map → chunk-3A2NJP2U.js.map} +0 -0
- /package/dist/{chunk-JGG5HVI2.js.map → chunk-3PKAS6VL.js.map} +0 -0
- /package/dist/{chunk-LSYD7GHZ.js.map → chunk-3SZD4CYO.js.map} +0 -0
- /package/dist/{chunk-5TG4MU2U.js.map → chunk-4F4AQFWL.js.map} +0 -0
- /package/dist/{chunk-D35XLYQ7.js.map → chunk-4QEYREAV.js.map} +0 -0
- /package/dist/{chunk-46WM6JX2.js.map → chunk-4ZWCQJNM.js.map} +0 -0
- /package/dist/{chunk-W6J4POB6.js.map → chunk-5DHKCO52.js.map} +0 -0
- /package/dist/{chunk-IRXMJLTW.js.map → chunk-5HK3CJAR.js.map} +0 -0
- /package/dist/{chunk-NLUCDKLT.js.map → chunk-5RWZH6PH.js.map} +0 -0
- /package/dist/{chunk-H7BZBSP6.js.map → chunk-645WOU5I.js.map} +0 -0
- /package/dist/{chunk-AYAZWXJI.js.map → chunk-76DIF5KT.js.map} +0 -0
- /package/dist/{chunk-OPPBTPUU.js.map → chunk-7KQB4EBS.js.map} +0 -0
- /package/dist/{chunk-I2HTKOOP.js.map → chunk-7VZFRUQU.js.map} +0 -0
- /package/dist/{chunk-JCWY73FK.js.map → chunk-AHPIFKNG.js.map} +0 -0
- /package/dist/{chunk-3I22VWB3.js.map → chunk-AZMLH5UT.js.map} +0 -0
- /package/dist/{chunk-JOEJG4SD.js.map → chunk-BEC4YBNA.js.map} +0 -0
- /package/dist/{chunk-BXXOPKT5.js.map → chunk-CAMNRAJF.js.map} +0 -0
- /package/dist/{chunk-C24UZSFW.js.map → chunk-CEH2AFXG.js.map} +0 -0
- /package/dist/{chunk-YOXVZJFM.js.map → chunk-CFVTRUR3.js.map} +0 -0
- /package/dist/{chunk-SVSRPG6M.js.map → chunk-CPA5NBHN.js.map} +0 -0
- /package/dist/{chunk-7BEPVIH3.js.map → chunk-CRML27CO.js.map} +0 -0
- /package/dist/{chunk-AXGFOFNY.js.map → chunk-DA7ITC5Z.js.map} +0 -0
- /package/dist/{chunk-FEO2CDXR.js.map → chunk-DPCXDG7G.js.map} +0 -0
- /package/dist/{chunk-HZNYJN77.js.map → chunk-F3NVYTTA.js.map} +0 -0
- /package/dist/{chunk-7SSRXEZJ.js.map → chunk-F7XUD3PL.js.map} +0 -0
- /package/dist/{chunk-XZBXINXZ.js.map → chunk-GIC6BASP.js.map} +0 -0
- /package/dist/{chunk-PP7R754B.js.map → chunk-GPFZFCRN.js.map} +0 -0
- /package/dist/{chunk-53MZQEBD.js.map → chunk-GTO56JY5.js.map} +0 -0
- /package/dist/{chunk-RAIUTAZZ.js.map → chunk-H2YSH3DG.js.map} +0 -0
- /package/dist/{chunk-HWVNYNIV.js.map → chunk-HMZKGHMD.js.map} +0 -0
- /package/dist/{chunk-ZXUZ54Z5.js.map → chunk-HRHO3ZNG.js.map} +0 -0
- /package/dist/{chunk-SDEPLF7V.js.map → chunk-IBJ6U753.js.map} +0 -0
- /package/dist/{chunk-T3JQTCCO.js.map → chunk-JI7U6AS3.js.map} +0 -0
- /package/dist/{chunk-TR7DGXGI.js.map → chunk-JOZUBF4A.js.map} +0 -0
- /package/dist/{chunk-YWBOOBDP.js.map → chunk-JYSN42VN.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-D2YNNDML.js.map → chunk-KWIGDKM2.js.map} +0 -0
- /package/dist/{chunk-RIAM7DND.js.map → chunk-LDKPDODJ.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-2JHRCWHT.js.map → chunk-LKYIOCWL.js.map} +0 -0
- /package/dist/{chunk-XAWIL7TC.js.map → chunk-LOXHYCVS.js.map} +0 -0
- /package/dist/{chunk-OLBZ2WGG.js.map → chunk-LTBKKSCX.js.map} +0 -0
- /package/dist/{chunk-O4BAGJDN.js.map → chunk-MDD2RINF.js.map} +0 -0
- /package/dist/{chunk-ROEAEANL.js.map → chunk-MY2BC6UE.js.map} +0 -0
- /package/dist/{chunk-RACZB5HT.js.map → chunk-N37X5RU7.js.map} +0 -0
- /package/dist/{chunk-AG46P24C.js.map → chunk-NNBZS3DY.js.map} +0 -0
- /package/dist/{chunk-PGW64IFQ.js.map → chunk-NPFUNWNX.js.map} +0 -0
- /package/dist/{chunk-MFOSZUIT.js.map → chunk-NPIBN2VL.js.map} +0 -0
- /package/dist/{chunk-IF4EY26E.js.map → chunk-OA2O2GJ4.js.map} +0 -0
- /package/dist/{chunk-6FUMA6AA.js.map → chunk-ODU2CNNX.js.map} +0 -0
- /package/dist/{chunk-TWBQQ3FT.js.map → chunk-P36Z4JRA.js.map} +0 -0
- /package/dist/{chunk-OUKBMQ2O.js.map → chunk-PD66CVSD.js.map} +0 -0
- /package/dist/{chunk-MVIYRRVJ.js.map → chunk-PMVPCZJZ.js.map} +0 -0
- /package/dist/{chunk-US4IRASK.js.map → chunk-PU56CXZA.js.map} +0 -0
- /package/dist/{chunk-IDQ6DKXC.js.map → chunk-S5XOSTYM.js.map} +0 -0
- /package/dist/{chunk-DYO24BNB.js.map → chunk-SEEJOGQX.js.map} +0 -0
- /package/dist/{chunk-7OZSHBWK.js.map → chunk-SNOIKAHM.js.map} +0 -0
- /package/dist/{chunk-SR7JIRAR.js.map → chunk-T6ILXUAH.js.map} +0 -0
- /package/dist/{chunk-2RXUZVPU.js.map → chunk-T7XP6IZE.js.map} +0 -0
- /package/dist/{chunk-KBOG7FJV.js.map → chunk-TFR3HG4K.js.map} +0 -0
- /package/dist/{chunk-XUZ5CIEE.js.map → chunk-TUHBYJXL.js.map} +0 -0
- /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
- /package/dist/{chunk-ZK4BFABK.js.map → chunk-U7EW2W4W.js.map} +0 -0
- /package/dist/{chunk-VFYRYFLL.js.map → chunk-UEBDCMOO.js.map} +0 -0
- /package/dist/{chunk-JFWZRUKP.js.map → chunk-UENKPWCS.js.map} +0 -0
- /package/dist/{chunk-AAXJNINV.js.map → chunk-UL4MKZHI.js.map} +0 -0
- /package/dist/{chunk-R2MZCYA6.js.map → chunk-UNUMFURP.js.map} +0 -0
- /package/dist/{chunk-5GIZM4RX.js.map → chunk-UPFNQJC7.js.map} +0 -0
- /package/dist/{chunk-W4BMEGQA.js.map → chunk-UTQUEHC7.js.map} +0 -0
- /package/dist/{chunk-I32NKXE2.js.map → chunk-V4IDF3EZ.js.map} +0 -0
- /package/dist/{chunk-QMZY3GG6.js.map → chunk-WNXYT4MK.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-T42L3S6A.js.map → chunk-XBGHAAKR.js.map} +0 -0
- /package/dist/{chunk-THG4GYIE.js.map → chunk-YEUXERJ6.js.map} +0 -0
- /package/dist/{chunk-BIJAWZYW.js.map → chunk-YMOPYG3K.js.map} +0 -0
- /package/dist/{chunk-M4AHBM72.js.map → chunk-Z3YEGSR4.js.map} +0 -0
- /package/dist/{forget-SZ2BXDGF.js.map → forget-2AE4MDK3.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage.ts","../src/preferences/drift-types.ts","../src/storage/tombstone-migration-sources.ts","../src/storage/memory-read-store.ts","../src/storage/memory-frontmatter-metadata.ts","../src/storage/windowed-memory-read.ts","../src/storage/committed-invalidation.ts","../src/storage/profile-header.ts","../src/storage/questions-file.ts","../src/okf/type-mapping.ts","../src/orchestration/self-deps.ts","../src/storage/entity-store.ts","../src/storage/identity-continuity-store.ts","../src/storage/entity-canonical-id-migration.ts","../src/storage/entity-ref-repair.ts","../src/storage/entity-canonical-id-migration-adapter.ts","../src/storage/entity-canonical-id-migration-runner.ts","../src/storage/memory-migration-serialization.ts","../src/storage/entity-alias-config.ts","../src/utils/yaml-scalar.ts","../src/orchestration/qmd-result-resolver.ts","../src/wearables/fusion/cluster.ts","../src/wearables/fusion/reconcile.ts","../src/wearables/fusion/fuse.ts","../src/wearables/fusion/store.ts","../src/wearables/fusion/reconstruct.ts","../src/meetings/store.ts","../src/storage/supersession-audit.ts","../src/storage/supersession-side-effects.ts","../src/storage/entity-timeline.ts"],"sourcesContent":["import { formatProjectionAge, readProjectionRebuiltAt } from \"./maintenance/projection-support.js\";\nimport {\n lstat,\n readdir,\n readFile,\n realpath,\n stat,\n writeFile,\n mkdir,\n unlink,\n appendFile,\n open,\n} from \"node:fs/promises\";\nimport { appendFileSync, createReadStream, mkdirSync, readFileSync, statSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { computeLegacyContentHash, normalizeContent } from \"./content-hash.js\";\nimport { parseDriftProvenance, serializeDriftProvenance } from \"./preferences/drift-types.js\";\nimport { raceAbort } from \"./abort-error.js\";\nimport { checkCorpusReadAbort, type CorpusReadOptions } from \"./corpus-read-cancellation.js\";\nimport { selectArtifactMatches, type ArtifactSearchOptions } from \"./artifact-search.js\";\nimport path from \"node:path\";\nimport { resolveSafeStoragePath } from \"./storage-paths.js\";\nimport { log } from \"./logger.js\";\nimport { createMemorySnapshot } from \"./memory-snapshot.js\";\nimport { assertMemoryFrontmatterId, warnProjectionFallback } from \"./storage-guards.js\";\nimport { createTombstoneMigrationSourceContents } from \"./storage/tombstone-migration-sources.js\";\nimport { MemoryReadStore, readWindowedMemories, type WindowedMemoryReadOptions, type WindowedMemoryReadResult } from \"./storage/memory-read-store.js\";\nimport { runCommittedInvalidation } from \"./storage/committed-invalidation.js\";\nimport { renderProfileWithLastUpdated, stripOkfProfileFrontmatter, withOkfProfileFrontmatter } from \"./storage/profile-header.js\";\nimport { parseQuestionFile as parseQuestionFileText } from \"./storage/questions-file.js\";\nimport { assertNotOkfReservedBasename, OKF_QUESTION_TYPE, okfTypeForEntityKind, okfTypeForMemory } from \"./okf/type-mapping.js\";\nimport { readMaybeEncryptedLines, readMemoryActionEventRowsFromLines } from \"./storage/secure-line-reader.js\";\nimport {\n appendLifecycleEventsSerialized,\n type DrainPendingLifecycleForSyncResult,\n drainPendingLifecycleLedgerForSync,\n drainPendingLifecycleLedgerIfAny,\n pendingLifecycleLedgerDir,\n ProjectionLedgerLagManager,\n readAllLifecycleEventsFromLedger,\n readAllLifecycleEventsFromLedgerBuffer,\n readBoundedLifecycleEventsFromLedger,\n serializeLifecycleAppendPayload,\n} from \"./storage/memory-lifecycle-ledger-access.js\";\nimport { selfDeps } from \"./orchestration/self-deps.js\";\nimport { EntityStore } from \"./storage/entity-store.js\";\nimport { DeletionRevisionStore, invalidationCommitFingerprint } from \"./storage/deletion-revision-store.js\";\nimport { IdentityContinuityStore } from \"./storage/identity-continuity-store.js\";\nimport * as entityMigration from \"./storage/entity-canonical-id-migration.js\";\nimport * as entityRefs from \"./storage/entity-canonical-id-references.js\";\nimport { EntityRefRepair } from \"./storage/entity-ref-repair.js\";\nimport {\n runLegacyEntityCanonicalIdMigration,\n type EntityCanonicalIdMigrationHost,\n} from \"./storage/entity-canonical-id-migration-adapter.js\";\nimport { EntityCanonicalIdMigrationRunner } from \"./storage/entity-canonical-id-migration-runner.js\";\nimport { rememberRawFrontmatter } from \"./storage/memory-frontmatter-metadata.js\";\nimport { createMemoryEntityRefSerializer } from \"./storage/memory-migration-serialization.js\";\nimport { readEntityAliasConfigSync } from \"./storage/entity-alias-config.js\";\nimport { assertSafeEntityId } from \"./storage/entity-id-safety.js\";\nexport { normalizeEntityName } from \"./entity-id-normalization.js\";\nimport { isErrnoCode } from \"./utils/errno.js\";\nimport { getCategoryDir, categoryDirName } from \"./utils/category-dir.js\";\nimport { decodeYamlScalar } from \"./utils/yaml-scalar.js\";\nimport { qmdCollectionPathParts, qmdResultPathCandidates } from \"./orchestration/qmd-result-resolver.js\";\nimport {\n clearMemoryCache,\n getCachedEntities,\n getCachedMemories,\n invalidateAllForDir,\n invalidateDerivedAndGlobalForDir,\n invalidateForScope,\n invalidateForScopeExceptHot,\n setCachedEntities,\n setCachedMemories,\n updateCacheOnDelete,\n updateCacheOnWrite,\n} from \"./memory-cache.js\";\nimport {\n attachInFlightReader,\n beginCoalescedScan,\n deleteInFlightRead,\n deleteInFlightReadsForDir,\n clearInFlightReads,\n} from \"./in-flight-reads.js\";\nimport * as archive from \"./archive-mutation-version.js\";\nimport { rotateMarkdownFileToArchive } from \"./hygiene.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { withholdToolScopedFromSharedNamespace } from \"./tool-scoped-memory.js\";\nimport {\n serializeProvenanceFields,\n parseProvenanceSources,\n parseProvenanceTag,\n reconcileProvenanceRead,\n} from \"./provenance.js\";\nimport { serializeFaithfulnessFields, parseFaithfulnessField } from \"./extraction-faithfulness.js\";\nimport { createVersion as createPageVersion, type VersioningConfig, type VersionTrigger } from \"./page-versioning.js\";\nimport { isValidTranscriptDate, WEARABLES_DIR_NAME } from \"./wearables/day-store.js\";\nimport { FusionArtifactStore } from \"./wearables/fusion/index.js\";\nimport { MeetingRecordStore } from \"./meetings/store.js\";\nimport {\n SecureStoreLockedError,\n MAGIC_HEADER_SIZE,\n isEncryptedFile,\n probeEncryptedRegularFileHeader,\n readMaybeEncryptedFileBuffer,\n readMaybeEncryptedFile,\n writeMaybeEncryptedFile,\n} from \"./secure-store/secure-fs.js\";\nimport {\n isConsolidationOperator,\n isValidDerivedFromEntry,\n type ConsolidationOperator,\n} from \"./consolidation-operator.js\";\nimport {\n matchEntitySchemaSection,\n normalizeEntityStructuredSection,\n sortStructuredSectionsBySchema,\n} from \"./entity-schema.js\";\nimport {\n hasCitationForTemplate,\n stripCitationForTemplate,\n DEFAULT_CITATION_FORMAT,\n} from \"./source-attribution.js\";\nimport {\n stripCitationMarkersForHashRemoval,\n stripDefaultCitationMarkersWithoutRegex,\n} from \"./storage/citation-hash-source.js\";\nimport {\n TombstoneStore,\n collectRetiredMemoriesForRebuild,\n type TombstoneStoreOptions,\n type TombstoneFileIo,\n type TombstoneReason,\n type TombstoneCreatedBy,\n type TombstoneStats,\n} from \"./lifecycle/tombstones.js\";\nimport { supersessionKeysForFact } from \"./temporal-supersession.js\";\nimport { runSupersessionSideEffects, type SupersessionAuditOptions } from \"./storage/supersession-side-effects.js\";\nimport type {\n AccessTrackingEntry,\n BufferState,\n ConfidenceTier,\n ContinuityIncidentCloseInput,\n ContinuityIncidentOpenInput,\n ContinuityIncidentRecord,\n ContinuityImprovementLoop,\n ContinuityLoopReviewInput,\n ContinuityLoopUpsertInput,\n EntityActivityEntry,\n EntityFile,\n EntityRelationship,\n EntityStructuredSection,\n EntityTimelineEntry,\n ImportanceLevel,\n ImportanceScore,\n MemoryCategory,\n MemoryFile,\n MemoryFrontmatter,\n MemoryLink,\n LifecycleState,\n VerificationState,\n PolicyClass,\n MemoryStatus,\n MemorySubject,\n MemoryActionEvent,\n MemoryLifecycleEvent,\n MemoryLifecycleEventType,\n MemoryLifecycleStateSummary,\n MemoryProjectionCurrentState,\n BehaviorSignalEvent,\n BufferSurpriseEvent,\n MemorySummary,\n MetaState,\n ExtractionFailureClass,\n CompressionGuidelineOptimizerState,\n PluginConfig,\n ScoredEntity,\n TopicScore,\n FileHygieneConfig,\n ProvenanceSource,\n} from \"./types.js\";\nimport { confidenceTier, SPECULATIVE_TTL_DAYS } from \"./types.js\";\nimport {\n collectStructuredSectionFacts,\n compareEntityTimestamps,\n compileEntityFacts,\n ENTITY_TIMELINE_METADATA_MARKER,\n escapeEntityTimelineMetadataValue,\n escapeEntityTimelineText,\n isEntitySynthesisStale,\n isEntitySynthesisTimelinePromotionBullet,\n latestEntityTimelineTimestamp,\n normalizeEntitySectionFact,\n normalizeStructuredSectionFacts,\n normalizeStructuredSectionFactsWithOrigins,\n parseEntityTimelineBullet,\n partitionEntityStructuredSections,\n serializeEntityTimelineEntry,\n} from \"./storage/entity-timeline.js\";\nimport {\n ContentHashIndex,\n FactHashIndexNotAuthoritativeError,\n CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS,\n type ContentHashIndexLockOptions,\n} from \"./storage/content-hash-index.js\";\nimport {\n TombstoneBlockedCaptureIndexHost,\n buildExplicitCaptureDedupKey,\n parseTombstoneBlockedOfflineSyncMemory,\n type TombstoneBlockedCaptureIndexOptions,\n} from \"./storage/tombstone-blocked-capture-index.js\";\nimport {\n buildCapturePathLockIdentity,\n isQueuedReviewMemory,\n tombstoneBlocked,\n} from \"./storage/tombstone-blocked-capture-mutation.js\";\nexport { ContentHashIndex, FactHashIndexNotAuthoritativeError };\nexport type { ContentHashIndexLockOptions };\nexport {\n compareEntityTimestamps,\n compileEntityFacts,\n countEntityStructuredFacts,\n fingerprintEntityStructuredFacts,\n isEntitySynthesisStale,\n normalizeStructuredSectionFacts,\n normalizeStructuredSectionFactsWithOrigins,\n} from \"./storage/entity-timeline.js\";\nimport {\n type ProjectedMemoryBrowseOptions,\n type ProjectedMemoryBrowsePage,\n markProjectedMemoryPathInvalid,\n readProjectedMemoryState,\n readProjectedMemoryBrowse,\n readProjectedGovernanceRecord,\n readProjectedMemoryTimeline,\n updateProjectedMemoryPath,\n} from \"./memory-projection-store.js\";\nimport { inferMemoryStatus, isArchivedMemoryPath, toMemoryPathRel } from \"./memory-lifecycle-ledger-utils.js\";\nimport { normalizeProjectionPreview, normalizeProjectionTags } from \"./memory-projection-format.js\";\nimport { isSupportPassportPrivateMemory } from \"./support-passport/card-projection.js\";\nimport { parseFlexibleIsoTimestamp } from \"./utils/iso-timestamp.js\";\nimport { parseOriginClass } from \"./security/origin-authority.js\";\nimport { detectLanguageHint } from \"./cross-lingual-recall.js\";\nimport {\n composeMemoryEnvelope,\n isSealedMemoryEnvelope,\n sealedWriteToLegacyArgs,\n type SealedMemoryEnvelope,\n} from \"./write-envelope.js\";\n// stripCitation import removed: legacy rebuild fallback was replaced by a\n// skip-with-warning strategy (Finding 1 — Uhol). See ensureFactHashIndexAuthoritative.\ntype SharedVersionKind = \"memory-status\" | \"artifact-write\" | \"cold-write\" | \"memory-corpus\" | \"entity-mutation\";\n\ntype OfflineSyncDigestCacheEntry = {\n statBytes: number;\n mtimeMs: number;\n ctimeMs: number;\n encrypted: boolean;\n sha256: string;\n bytes: number;\n};\nexport interface ReextractJobRequest {\n memoryId: string;\n model: string;\n requestedAt: string;\n source: \"cli-migrate\";\n}\nexport interface MemoryLifecycleEventWriteOptions {\n at?: Date;\n actor?: string;\n reasonCode?: string;\n ruleVersion?: string;\n relatedMemoryIds?: string[];\n correlationId?: string;\n}\n/**\n * Validate a Memory Worth counter (`mw_success` / `mw_fail`) before we persist\n * it. Rejects non-finite, non-integer, and negative values rather than silently\n * clamping — a silent clamp would mask miscounts in the feedback pipeline\n * (issue #560 PR 3). Callers should pass only explicit user/pipeline values;\n * `undefined` is checked at the callsite and skipped entirely.\n */\nfunction assertMemoryWorthCounter(field: \"mw_success\" | \"mw_fail\", value: number): void {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${field} must be a finite number, got ${String(value)}`);\n }\n if (!Number.isInteger(value)) {\n throw new Error(`${field} must be an integer, got ${value}`);\n }\n if (value < 0) {\n throw new Error(`${field} must be >= 0, got ${value}`);\n }\n}\n\nfunction normalizeMemoryWriteTimestamp(field: string, value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\") {\n throw new Error(`${field} must be an ISO timestamp string, got ${String(value)}`);\n }\n const trimmed = value.trim();\n const parsed = parseFlexibleIsoTimestamp(trimmed);\n if (parsed === null) {\n throw new Error(`${field} must be a valid ISO timestamp, got ${JSON.stringify(value)}`);\n }\n return new Date(parsed).toISOString();\n}\n\nfunction serializeFrontmatter(fm: MemoryFrontmatter): string {\n assertMemoryFrontmatterId(fm);\n const lines = [\n \"---\",\n `id: ${fm.id}`,\n `category: ${fm.category}`,\n `created: ${fm.created}`,\n `updated: ${fm.updated}`,\n `source: ${fm.source}`,\n `confidence: ${fm.confidence}`,\n `confidenceTier: ${fm.confidenceTier}`,\n `tags: [${fm.tags.map((t) => `\"${t}\"`).join(\", \")}]`,\n ];\n // OKF v0.1 interop (issue #1946): inert presentation metadata; `category` stays canonical.\n if (fm.language) lines.push(`language: ${fm.language}`);\n if (fm.type !== undefined) lines.push(`type: ${fm.type}`);\n if (fm.origin) lines.push(`origin: ${/^[A-Za-z0-9:_.*-]+$/.test(fm.origin) ? fm.origin : JSON.stringify(fm.origin)}`);\n if (fm.subject) lines.push(`subject: ${fm.subject}`);\n if (fm.entityRef) lines.push(`entityRef: ${fm.entityRef}`);\n if (fm.sourceConnector) {\n // YAML-injection guard (review thread QMPsP): emit unquoted for\n // safe connector IDs (matching the connectors/index.ts validator),\n // or JSON.stringify for values with special characters so newlines,\n // colons, and spaces cannot inject extra frontmatter lines.\n const safe = /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(fm.sourceConnector);\n lines.push(`sourceConnector: ${safe ? fm.sourceConnector : JSON.stringify(fm.sourceConnector)}`);\n }\n if (fm.toolScoped === true) lines.push(\"toolScoped: true\");\n if (fm.supersedes) lines.push(`supersedes: ${fm.supersedes}`);\n if (fm.expiresAt) lines.push(`expiresAt: ${fm.expiresAt}`);\n if (fm.lineage && fm.lineage.length > 0) {\n lines.push(`lineage: [${fm.lineage.map((l) => `\"${l}\"`).join(\", \")}]`);\n }\n // Status management\n if (fm.status && fm.status !== \"active\") lines.push(`status: ${fm.status}`);\n // Tombstone block visibility (issue #1579). Emit only when present so legacy\n // memories round-trip unchanged; the review queue reads these to drive the\n // automatic revocation on approval.\n if (fm.blockedBy) lines.push(`blockedBy: ${fm.blockedBy}`);\n if (fm.tombstoneBlockTier) lines.push(`tombstoneBlockTier: ${fm.tombstoneBlockTier}`);\n if (fm.supersededBy) lines.push(`supersededBy: ${fm.supersededBy}`);\n if (fm.supersededAt) lines.push(`supersededAt: ${fm.supersededAt}`);\n if (fm.supersessionCause) {\n if (fm.supersessionCause !== \"direct\" && fm.supersessionCause !== \"dependency\") {\n throw new Error(\n `serializeFrontmatter: invalid supersessionCause ${JSON.stringify(fm.supersessionCause)} — expected \"direct\" | \"dependency\"`,\n );\n }\n lines.push(`supersessionCause: ${fm.supersessionCause}`);\n }\n if (fm.invalidatedBy) lines.push(`invalidatedBy: ${fm.invalidatedBy}`);\n if (fm.archivedAt) lines.push(`archivedAt: ${fm.archivedAt}`);\n // Issue #680 — explicit fact lifecycle. Emit only when present so legacy\n // memories round-trip unchanged; readers default `valid_at` to `created`.\n if (fm.valid_at) lines.push(`validAt: ${fm.valid_at}`);\n if (fm.invalid_at) lines.push(`invalidAt: ${fm.invalid_at}`);\n // Issue #1578 — bi-temporal ingestion provenance. Validate on write so a\n // corrupt `observedAt` (non-ISO / overflowed) cannot leak onto disk; reads\n // are permissive, mirroring the `valid_at` precedent. `eventTimeSource` is\n // a closed enum — reject anything outside it rather than persisting garbage.\n if (fm.observedAt) {\n const validated = normalizeMemoryWriteTimestamp(\"observedAt\", fm.observedAt);\n if (validated) lines.push(`observedAt: ${validated}`);\n }\n if (fm.eventTimeSource) {\n if (fm.eventTimeSource !== \"extracted\" && fm.eventTimeSource !== \"assumed\") {\n throw new Error(\n `serializeFrontmatter: invalid eventTimeSource ${JSON.stringify(fm.eventTimeSource)} — expected \"extracted\" | \"assumed\"`\n );\n }\n lines.push(`eventTimeSource: ${fm.eventTimeSource}`);\n }\n if (fm.forgottenAt) lines.push(`forgottenAt: ${fm.forgottenAt}`);\n if (fm.forgottenReason) lines.push(`forgottenReason: ${JSON.stringify(fm.forgottenReason)}`);\n // Lifecycle policy fields\n if (fm.lifecycleState) lines.push(`lifecycleState: ${fm.lifecycleState}`);\n if (fm.verificationState) lines.push(`verificationState: ${fm.verificationState}`);\n if (fm.policyClass) lines.push(`policyClass: ${fm.policyClass}`);\n if (fm.lastValidatedAt) lines.push(`lastValidatedAt: ${fm.lastValidatedAt}`);\n if (fm.decayScore !== undefined) lines.push(`decayScore: ${fm.decayScore}`);\n if (fm.heatScore !== undefined) lines.push(`heatScore: ${fm.heatScore}`);\n // Access tracking\n if (fm.accessCount !== undefined && fm.accessCount > 0) {\n lines.push(`accessCount: ${fm.accessCount}`);\n }\n if (fm.lastAccessed) lines.push(`lastAccessed: ${fm.lastAccessed}`);\n // Memory Worth counters (issue #560). Emit verbatim when present — including\n // explicit zeros — so consumers can distinguish \"never observed\" (absent)\n // from \"observed with zero successes\" (present, value 0). Validation below\n // rejects negatives and non-integers so we never persist a corrupt counter.\n if (fm.mw_success !== undefined) {\n assertMemoryWorthCounter(\"mw_success\", fm.mw_success);\n lines.push(`mw_success: ${fm.mw_success}`);\n }\n if (fm.mw_fail !== undefined) {\n assertMemoryWorthCounter(\"mw_fail\", fm.mw_fail);\n lines.push(`mw_fail: ${fm.mw_fail}`);\n }\n lines.push(...serializeDriftProvenance(fm));\n // Importance scoring\n if (fm.importance) {\n lines.push(`importanceScore: ${fm.importance.score}`);\n lines.push(`importanceLevel: ${fm.importance.level}`);\n if (fm.importance.reasons.length > 0) {\n lines.push(\n `importanceReasons: [${fm.importance.reasons\n .map((r) => `\"${r.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`)\n .join(\", \")}]`\n );\n }\n if (fm.importance.keywords.length > 0) {\n lines.push(`importanceKeywords: [${fm.importance.keywords.map((k) => `\"${k}\"`).join(\", \")}]`);\n }\n }\n // Chunking (Phase 2A)\n if (fm.parentId) lines.push(`parentId: ${fm.parentId}`);\n if (fm.chunkIndex !== undefined) lines.push(`chunkIndex: ${fm.chunkIndex}`);\n if (fm.chunkTotal !== undefined) lines.push(`chunkTotal: ${fm.chunkTotal}`);\n // Memory Linking (Phase 3A)\n if (fm.links && fm.links.length > 0) {\n lines.push(\"links:\");\n for (const link of fm.links) {\n lines.push(` - targetId: ${link.targetId}`);\n lines.push(` linkType: ${link.linkType}`);\n lines.push(` strength: ${link.strength}`);\n if (link.reason) lines.push(` reason: ${JSON.stringify(link.reason)}`);\n }\n }\n if (fm.intentGoal) lines.push(`intentGoal: ${fm.intentGoal}`);\n if (fm.intentActionType) lines.push(`intentActionType: ${fm.intentActionType}`);\n if (fm.intentEntityTypes && fm.intentEntityTypes.length > 0) {\n lines.push(`intentEntityTypes: [${fm.intentEntityTypes.map((t) => `\"${t}\"`).join(\", \")}]`);\n }\n if (fm.artifactType) lines.push(`artifactType: ${fm.artifactType}`);\n if (fm.sourceMemoryId) lines.push(`sourceMemoryId: ${fm.sourceMemoryId}`);\n if (fm.sourceTurnId) lines.push(`sourceTurnId: ${fm.sourceTurnId}`);\n // v8.0 Phase 2B: HiMem episode/note classification\n if (fm.memoryKind) lines.push(`memoryKind: ${fm.memoryKind}`);\n // Structured attributes (stored as JSON on a single line)\n if (fm.structuredAttributes && Object.keys(fm.structuredAttributes).length > 0) {\n lines.push(`structuredAttributes: ${JSON.stringify(fm.structuredAttributes)}`);\n }\n // Raw-content dedup hash — format-agnostic archive/consolidation cleanup\n if (fm.contentHash) lines.push(`contentHash: ${fm.contentHash}`);\n // Consolidation provenance (issue #561). Validate on write so malformed\n // entries cannot leak into the on-disk format. Read-through parsing is\n // permissive; only writes go through the validator.\n if (fm.derived_from !== undefined) {\n if (!Array.isArray(fm.derived_from)) {\n throw new Error(`serializeFrontmatter: derived_from must be an array of \"<path>:<version>\" strings`);\n }\n for (const entry of fm.derived_from) {\n if (!isValidDerivedFromEntry(entry)) {\n throw new Error(\n `serializeFrontmatter: invalid derived_from entry ${JSON.stringify(entry)} — expected \"<path>:<version>\" with version >= 0`\n );\n }\n }\n if (fm.derived_from.length > 0) {\n lines.push(\n `derived_from: [${fm.derived_from.map((e) => `\"${e.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`).join(\", \")}]`\n );\n }\n }\n if (fm.derived_via !== undefined) {\n if (!isConsolidationOperator(fm.derived_via)) {\n throw new Error(\n `serializeFrontmatter: invalid derived_via ${JSON.stringify(fm.derived_via)} — expected one of \"split\" | \"merge\" | \"update\" | \"pattern-reinforcement\"`\n );\n }\n lines.push(`derived_via: ${fm.derived_via}`);\n }\n // Pattern-reinforcement metadata (issue #687 PR 2/4). Emit only when\n // present so memories never touched by reinforcement round-trip\n // unchanged; matches the `archivedAt` / `forgottenAt` precedent.\n if (fm.reinforcement_count !== undefined) {\n if (!Number.isInteger(fm.reinforcement_count) || fm.reinforcement_count <= 0) {\n throw new Error(\n `serializeFrontmatter: reinforcement_count must be a positive integer (got ${JSON.stringify(fm.reinforcement_count)})`\n );\n }\n lines.push(`reinforcement_count: ${fm.reinforcement_count}`);\n }\n if (fm.last_reinforced_at) {\n lines.push(`last_reinforced_at: ${fm.last_reinforced_at}`);\n }\n serializeProvenanceFields(fm, lines);\n serializeFaithfulnessFields(fm, lines);\n lines.push(\"---\");\n return lines.join(\"\\n\");\n}\n\nfunction parseStructuredAttributes(raw: string | undefined): Record<string, string> | undefined {\n if (!raw || !raw.trim()) return undefined;\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const result: Record<string, string> = {};\n for (const [k, v] of Object.entries(parsed)) {\n if (typeof k === \"string\" && typeof v === \"string\") {\n result[k] = v;\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n }\n } catch {\n // Not valid JSON — ignore\n }\n return undefined;\n}\n\nfunction parseLinkReasonValue(rawValue: string): string {\n const legacyValue = rawValue.replace(/\\\\\"/g, '\"');\n const looksLikeLegacyPath =\n !rawValue.includes(\"\\\\\\\\\") &&\n (/[A-Za-z]:\\\\[A-Za-z0-9._ -]+(?:\\\\[A-Za-z0-9._ -]+)*/.test(rawValue) ||\n /\\\\[A-Za-z0-9._ -]+\\\\[A-Za-z0-9._ -]+/.test(rawValue));\n\n if (looksLikeLegacyPath) {\n return legacyValue;\n }\n\n try {\n return JSON.parse(`\"${rawValue}\"`) as string;\n } catch {\n return legacyValue;\n }\n}\n\nexport function parseFrontmatterStringValue(rawValue: string | undefined): string | undefined {\n if (rawValue === undefined) return undefined;\n const trimmed = rawValue.trim();\n if (trimmed.length === 0) return undefined;\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n return typeof parsed === \"string\" ? parsed : trimmed;\n } catch {\n return trimmed.slice(1, -1).replace(/\\\\\"/g, '\"');\n }\n }\n return trimmed;\n}\n\n/**\n * Parse a Memory Worth counter from its raw YAML string form. Returns\n * `undefined` for missing, blank, negative, or non-integer values so a\n * corrupt stored counter fails safely rather than poisoning downstream\n * scoring. Pair with `assertMemoryWorthCounter` on the write path.\n */\nfunction bracketListInner(raw: string): string | undefined {\n const trimmed = raw.trim();\n if (!trimmed.startsWith(\"[\") || !trimmed.endsWith(\"]\")) return undefined;\n return trimmed.slice(1, -1);\n}\n\nfunction quotedArrayValues(raw: string): string[] {\n const inner = bracketListInner(raw);\n if (inner === undefined) return [];\n const values: string[] = [];\n let i = 0;\n while (i < inner.length) {\n while (i < inner.length && inner[i] !== '\"') i++;\n if (i >= inner.length) break;\n i++;\n let value = \"\";\n while (i < inner.length) {\n const ch = inner[i++];\n if (ch === \"\\\\\" && i < inner.length) value += ch + inner[i++];\n else if (ch === '\"') {\n values.push(value);\n break;\n } else value += ch;\n }\n }\n return values;\n}\n\nfunction parseMemoryWorthCounterField(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return undefined;\n const n = Number(trimmed);\n if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) return undefined;\n return n;\n}\n\n/**\n * Parse the pattern-reinforcement counter (issue #687 PR 2/4) from its\n * raw YAML string form. Returns `undefined` for missing, blank,\n * non-positive, or non-integer values so a corrupt stored counter\n * fails safely. Pair with the `reinforcement_count > 0 && integer`\n * assertion on the write path in `serializeFrontmatter`.\n */\nfunction parseReinforcementCountField(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return undefined;\n const n = Number(trimmed);\n if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) return undefined;\n return n;\n}\n\nexport function parseFrontmatter(raw: string): { frontmatter: MemoryFrontmatter; content: string } | null {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)([\\s\\S]*)$/);\n if (!match) return null;\n\n const fmBlock = match[1];\n const content = match[2].trim();\n const fm: Record<string, string> = {};\n\n // Collapse YAML block-sequence style into inline flow style so the\n // downstream per-key parsers (derived_from, tags, lineage, etc.) keep\n // working. A key like\n // derived_from:\n // - facts/a.md:2\n // - facts/b.md:5\n // becomes\n // derived_from: [\"facts/a.md:2\", \"facts/b.md:5\"]\n // before the line-split. Only applies when the key's own line has an\n // empty scalar — any inline value or explicit flow sequence short-circuits\n // this and is parsed as-is.\n const rawLines = fmBlock.split(\"\\n\");\n const lines: string[] = [];\n let i = 0;\n while (i < rawLines.length) {\n const line = rawLines[i];\n const colonIdx = line.indexOf(\":\");\n if (colonIdx !== -1 && line.slice(colonIdx + 1).trim() === \"\") {\n const baseIndent = line.match(/^\\s*/)![0].length;\n const items: string[] = [];\n let j = i + 1;\n while (j < rawLines.length) {\n const next = rawLines[j];\n const m = next.match(/^(\\s+)- (.*)$/);\n if (!m || m[1].length <= baseIndent) break;\n // Strip matching surrounding quotes and apply YAML unescape rules\n // so block-style entries round-trip identically to flow-style ones.\n // double-quoted: `\\\"` → `\"`, `\\\\` → `\\`\n // single-quoted: `''` → `'` (YAML's native escape)\n let item = m[2].trim();\n if (item.startsWith('\"') && item.endsWith('\"') && item.length >= 2) {\n item = item.slice(1, -1).replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, \"\\\\\");\n } else if (item.startsWith(\"'\") && item.endsWith(\"'\") && item.length >= 2) {\n item = item.slice(1, -1).replace(/''/g, \"'\");\n }\n items.push(item);\n j++;\n }\n if (items.length > 0) {\n const inline = items.map((v) => `\"${v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`).join(\", \");\n lines.push(`${line.slice(0, colonIdx + 1)} [${inline}]`);\n i = j;\n continue;\n }\n }\n lines.push(line);\n i++;\n }\n\n for (const line of lines) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) continue;\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n fm[key] = value;\n }\n\n let tags: string[] = [];\n const tagsStr = fm.tags ?? \"\";\n const tagInner = bracketListInner(tagsStr);\n if (tagInner !== undefined) {\n tags = tagInner\n .split(\",\")\n .map((t) => t.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n let intentEntityTypes: string[] | undefined;\n const intentEntityTypesStr = fm.intentEntityTypes ?? \"\";\n const intentEntityTypesInner = bracketListInner(intentEntityTypesStr);\n if (intentEntityTypesInner !== undefined) {\n intentEntityTypes = intentEntityTypesInner\n .split(\",\")\n .map((t) => t.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n const conf = parseFloat(fm.confidence ?? \"0.8\");\n\n // Parse lineage array if present\n let lineage: string[] | undefined;\n const lineageStr = fm.lineage ?? \"\";\n const lineageInner = bracketListInner(lineageStr);\n if (lineageInner !== undefined) {\n lineage = lineageInner\n .split(\",\")\n .map((l) => l.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n // Parse consolidation provenance (issue #561). `derived_from` is an\n // array of `\"<path>:<version>\"` strings; parsing is permissive so legacy\n // / malformed entries survive a read, but serialization validates on\n // write (see serializeFrontmatter). `derived_via` is a single operator\n // string; unknown values become `undefined` on read rather than raising.\n //\n // Tokenization handles every inline-YAML flavor we may encounter from\n // external editors and older builds:\n // - our canonical escape: [\"facts/a.md:2\", \"facts/b.md:5\"]\n // - single-quoted: ['facts/a.md:2', 'facts/b.md:5']\n // - bare (no quotes): [facts/a.md:2, facts/b.md:5]\n // Quoted entries preserve embedded commas in the path; bare entries\n // fall back to comma splitting but are still validated on write.\n let derived_from: string[] | undefined;\n const derivedFromStr = (fm.derived_from ?? \"\").trim();\n if (derivedFromStr.startsWith(\"[\") && derivedFromStr.endsWith(\"]\")) {\n const inner = derivedFromStr.slice(1, -1);\n const entries: string[] = [];\n // Hand-rolled tokenizer: walk the inner characters, honoring\n // double-quote escapes (`\\\"`, `\\\\`) and YAML single-quote doubling\n // (`''` in a `'...'` string means a literal `'`). This avoids the\n // `'...'` regex footgun where `''` is parsed as two empty strings.\n // Bare tokens (not quoted) are read until the next comma/whitespace\n // so flow sequences that mix quoted and bare scalars preserve every\n // entry.\n let i = 0;\n while (i < inner.length) {\n const ch = inner[i];\n if (ch === '\"') {\n let buf = \"\";\n i++;\n while (i < inner.length) {\n const c = inner[i];\n if (c === \"\\\\\" && i + 1 < inner.length) {\n const next = inner[i + 1];\n if (next === '\"') {\n buf += '\"';\n i += 2;\n continue;\n }\n if (next === \"\\\\\") {\n buf += \"\\\\\";\n i += 2;\n continue;\n }\n buf += c;\n i++;\n continue;\n }\n if (c === '\"') {\n i++;\n break;\n }\n buf += c;\n i++;\n }\n if (buf.length > 0) entries.push(buf);\n } else if (ch === \"'\") {\n let buf = \"\";\n i++;\n while (i < inner.length) {\n const c = inner[i];\n if (c === \"'\") {\n // YAML single-quote escape: `''` means a literal `'`.\n if (i + 1 < inner.length && inner[i + 1] === \"'\") {\n buf += \"'\";\n i += 2;\n continue;\n }\n i++;\n break;\n }\n buf += c;\n i++;\n }\n if (buf.length > 0) entries.push(buf);\n } else if (ch === \",\" || /\\s/.test(ch)) {\n // Separator between entries — skip.\n i++;\n } else {\n // Bare token — read until next comma or whitespace. Supports\n // mixed-style YAML sequences like `[\"facts/a.md:1\", facts/b.md:2]`\n // where some entries are quoted and others are bare.\n let buf = \"\";\n while (i < inner.length) {\n const c = inner[i];\n if (c === \",\" || /\\s/.test(c)) break;\n buf += c;\n i++;\n }\n if (buf.length > 0) entries.push(buf);\n }\n }\n if (entries.length > 0) derived_from = entries;\n }\n // `derived_via` may arrive quoted from external YAML emitters\n // (`derived_via: \"merge\"` or `'merge'`). Strip a single surrounding\n // quote pair before operator validation so semantically valid entries\n // aren't silently downgraded to `undefined`.\n const derivedViaRaw = (fm.derived_via ?? \"\").trim();\n const derivedViaUnquoted =\n (derivedViaRaw.startsWith('\"') && derivedViaRaw.endsWith('\"')) ||\n (derivedViaRaw.startsWith(\"'\") && derivedViaRaw.endsWith(\"'\"))\n ? derivedViaRaw.slice(1, -1)\n : derivedViaRaw;\n const derived_via = isConsolidationOperator(derivedViaUnquoted) ? derivedViaUnquoted : undefined;\n\n // Parse accessCount\n const accessCount = fm.accessCount ? parseInt(fm.accessCount, 10) : undefined;\n const decayScore = fm.decayScore !== undefined ? parseFloat(fm.decayScore) : undefined;\n const heatScore = fm.heatScore !== undefined ? parseFloat(fm.heatScore) : undefined;\n\n // Parse Memory Worth counters (issue #560). We preserve explicit zeros so\n // callers can distinguish \"observed with zero successes\" from \"never\n // observed\". Invalid (non-integer / negative) stored values round-trip to\n // `undefined` — better to drop corrupt counters than to poison scoring.\n const mw_success = parseMemoryWorthCounterField(fm.mw_success);\n const mw_fail = parseMemoryWorthCounterField(fm.mw_fail);\n\n // Parse importance\n let importance: ImportanceScore | undefined;\n if (fm.importanceScore) {\n const score = parseFloat(fm.importanceScore);\n const level = (fm.importanceLevel as ImportanceLevel) || \"normal\";\n\n // Parse importance reasons array\n let reasons: string[] = [];\n const reasonsStr = fm.importanceReasons ?? \"\";\n if (reasonsStr.trim().startsWith(\"[\") && reasonsStr.trim().endsWith(\"]\")) {\n for (const rawReason of quotedArrayValues(reasonsStr)) {\n const reason = parseLinkReasonValue(rawReason);\n if (reason.length > 0) reasons.push(reason);\n }\n }\n\n // Parse importance keywords array\n let keywords: string[] = [];\n const keywordsStr = fm.importanceKeywords ?? \"\";\n const keywordsInner = bracketListInner(keywordsStr);\n if (keywordsInner !== undefined) {\n keywords = keywordsInner\n .split(\",\")\n .map((k) => k.trim().replace(/^\"|\"$/g, \"\"))\n .filter(Boolean);\n }\n\n importance = { score, level, reasons, keywords };\n }\n\n const result: { frontmatter: MemoryFrontmatter; content: string } = {\n frontmatter: {\n id: fm.id ?? \"\",\n category: (fm.category ?? \"fact\") as MemoryCategory,\n created: fm.created ?? new Date().toISOString(),\n language: fm.language || undefined,\n type: parseFrontmatterStringValue(fm.type),\n updated: fm.updated ?? new Date().toISOString(),\n source: fm.source ?? \"unknown\",\n confidence: conf,\n confidenceTier: (fm.confidenceTier as ConfidenceTier) || confidenceTier(conf),\n tags,\n entityRef: fm.entityRef || undefined,\n origin: fm.origin !== undefined ? parseOriginClass(decodeYamlScalar(fm.origin)) : undefined,\n subject: fm.subject === \"user\" || fm.subject === \"agent\" ? fm.subject : undefined,\n sourceConnector: fm.sourceConnector ? decodeYamlScalar(fm.sourceConnector) || undefined : undefined,\n toolScoped: fm.toolScoped === \"true\" ? true : undefined,\n supersedes: fm.supersedes || undefined,\n expiresAt: fm.expiresAt || undefined,\n lineage: lineage && lineage.length > 0 ? lineage : undefined,\n // Status management\n status: (fm.status as MemoryStatus) || \"active\",\n // Tombstone block visibility (issue #1579) — read-through.\n blockedBy: fm.blockedBy || undefined,\n tombstoneBlockTier:\n fm.tombstoneBlockTier === \"exact\" ||\n fm.tombstoneBlockTier === \"normalized\" ||\n fm.tombstoneBlockTier === \"keyed\" ||\n fm.tombstoneBlockTier === \"semantic\"\n ? fm.tombstoneBlockTier\n : undefined,\n supersededBy: fm.supersededBy || undefined,\n supersededAt: fm.supersededAt || undefined,\n archivedAt: fm.archivedAt || undefined,\n supersessionCause:\n fm.supersessionCause === \"direct\" || fm.supersessionCause === \"dependency\"\n ? fm.supersessionCause\n : undefined,\n invalidatedBy: fm.invalidatedBy || undefined,\n // Issue #680 — explicit fact lifecycle round-trip.\n valid_at: fm.validAt || undefined,\n invalid_at: fm.invalidAt || undefined,\n // Issue #1578 — bi-temporal ingestion provenance round-trip.\n observedAt: fm.observedAt || undefined,\n eventTimeSource:\n fm.eventTimeSource === \"extracted\" || fm.eventTimeSource === \"assumed\" ? fm.eventTimeSource : undefined,\n forgottenAt: fm.forgottenAt || undefined,\n forgottenReason: parseFrontmatterStringValue(fm.forgottenReason),\n lifecycleState: (fm.lifecycleState as LifecycleState) || undefined,\n verificationState: (fm.verificationState as VerificationState) || undefined,\n policyClass: (fm.policyClass as PolicyClass) || undefined,\n lastValidatedAt: fm.lastValidatedAt || undefined,\n decayScore: Number.isFinite(decayScore) ? decayScore : undefined,\n heatScore: Number.isFinite(heatScore) ? heatScore : undefined,\n // Access tracking\n accessCount: accessCount && accessCount > 0 ? accessCount : undefined,\n lastAccessed: fm.lastAccessed || undefined,\n // Memory Worth counters (issue #560)\n mw_success,\n mw_fail,\n ...parseDriftProvenance(fm),\n // Importance scoring\n importance,\n // Chunking\n parentId: fm.parentId || undefined,\n chunkIndex: fm.chunkIndex ? parseInt(fm.chunkIndex, 10) : undefined,\n chunkTotal: fm.chunkTotal ? parseInt(fm.chunkTotal, 10) : undefined,\n // Links are parsed separately below\n intentGoal: fm.intentGoal || undefined,\n intentActionType: fm.intentActionType || undefined,\n intentEntityTypes: intentEntityTypes && intentEntityTypes.length > 0 ? intentEntityTypes : undefined,\n artifactType: (fm.artifactType as MemoryFrontmatter[\"artifactType\"]) || undefined,\n sourceMemoryId: fm.sourceMemoryId || undefined,\n sourceTurnId: fm.sourceTurnId || undefined,\n // v8.0 Phase 2B: HiMem episode/note classification\n memoryKind: (fm.memoryKind as MemoryFrontmatter[\"memoryKind\"]) || undefined,\n // Structured attributes (JSON on a single line)\n structuredAttributes: parseStructuredAttributes(fm.structuredAttributes),\n // Raw-content dedup hash (format-agnostic archive/consolidation cleanup)\n contentHash: fm.contentHash || undefined,\n // Consolidation provenance (issue #561) — read-through only in this\n // PR; no code produces these fields yet.\n derived_from,\n derived_via,\n // Pattern-reinforcement metadata (issue #687 PR 2/4) — drop corrupt values on read (rule 34).\n reinforcement_count: parseReinforcementCountField(fm.reinforcement_count),\n last_reinforced_at: fm.last_reinforced_at || undefined,\n sources: parseProvenanceSources(fm.sources),\n provenance: reconcileProvenanceRead(parseProvenanceTag(fm.provenance), parseProvenanceSources(fm.sources)),\n faithfulness: parseFaithfulnessField(fm.faithfulness),\n },\n content,\n };\n\n // Parse links (YAML array format)\n // Note: Simple parsing - for full YAML we'd need a library.\n if (fmBlock.includes(\"links:\")) {\n const links: MemoryLink[] = [];\n const linkMatches = fmBlock.matchAll(\n /- targetId: (\\S+)\\s+linkType: (\\S+)\\s+strength: ([\\d.]+)(?:\\s+reason: \"((?:\\\\.|[^\"\\\\])*)\")?/g\n );\n for (const match of linkMatches) {\n links.push({\n targetId: match[1],\n linkType: match[2] as MemoryLink[\"linkType\"],\n strength: parseFloat(match[3]),\n reason: match[4] ? parseLinkReasonValue(match[4]) : undefined,\n });\n }\n if (links.length > 0) {\n result.frontmatter.links = links;\n }\n }\n\n return result;\n}\n\nfunction inferEntityTypeFromContent(content: string): string | undefined {\n const typeMatch = content\n .match(/^\\*\\*Type:\\*\\*\\s*([^\\n]+)/m)?.[1]\n ?.trim()\n .toLowerCase();\n return typeMatch || undefined;\n}\n\nconst KNOWN_ENTITY_FILENAME_PREFIXES = new Set([\"company\", \"other\", \"person\", \"place\", \"project\", \"tool\", \"topic\"]);\n\nfunction inferEntityTypeFromFilename(pathRel: string): string | undefined {\n const basename = path.basename(pathRel, \".md\").toLowerCase();\n const separator = basename.indexOf(\"-\");\n if (separator <= 0) return undefined;\n const candidate = basename.slice(0, separator);\n return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : undefined;\n}\n\nexport function normalizeFrontmatterForPath(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n content: string = \"\"\n): MemoryFrontmatter {\n const normalizedPath = pathRel.split(path.sep).join(\"/\");\n let normalizedFrontmatter = frontmatter;\n\n if (\n normalizedPath === \"entities\" ||\n normalizedPath.startsWith(\"entities/\") ||\n normalizedPath.includes(\"/entities/\")\n ) {\n const basename = path.basename(pathRel, \".md\");\n const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || \"entity\";\n const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];\n normalizedFrontmatter = {\n ...normalizedFrontmatter,\n id:\n typeof normalizedFrontmatter.id === \"string\" && normalizedFrontmatter.id.trim().length > 0\n ? normalizedFrontmatter.id\n : basename,\n category: \"entity\",\n tags: existingTags.includes(inferredType) ? existingTags : [...existingTags, inferredType],\n };\n }\n\n if (isArchivedMemoryPath(pathRel) && (!normalizedFrontmatter.status || normalizedFrontmatter.status === \"active\")) {\n return {\n ...normalizedFrontmatter,\n status: \"archived\",\n };\n }\n\n return normalizedFrontmatter;\n}\n\nfunction inferCurrentStateStatus(\n frontmatter: MemoryFrontmatter,\n pathRel: string,\n fallbackStatus: MemoryStatus\n): MemoryStatus {\n return inferMemoryStatus(frontmatter, pathRel, fallbackStatus);\n}\n\n/**\n * Simple Levenshtein distance between two strings.\n */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\n/** Strip hyphens from a string for loose comparison */\nfunction dehyphenate(s: string): string {\n return s.replace(/-/g, \"\");\n}\n\n/** Bounded attempts to acquire the rebuild lock before ensureFactHashIndexAuthoritative surrenders authority (PR #2016). */\nconst FACT_HASH_INDEX_REBUILD_MAX_ATTEMPTS = 3;\n/** Base backoff (ms) between rebuild-lock attempts; doubles each attempt, capped at CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS. */\nconst FACT_HASH_INDEX_REBUILD_RETRY_BASE_MS = 50;\n\n// ---------------------------------------------------------------------------\n// Attribute normalization helper\n// ---------------------------------------------------------------------------\n\n// `stripAttributesSuffix` now lives in ./structured-attributes.ts (shared with\n// the coding surfaces + wearable service). Imported here so internal callers\n// (snapshotBeforeWrite, snapshotForProvenance) resolve, and re-exported to\n// keep the public storage API stable for existing callers (wearables, dist).\nimport { assemblePersistedBody, storedContentIdentityCandidates, stripAttributesSuffix } from \"./structured-attributes.js\";\nexport { stripAttributesSuffix };\n\n// `normalizeAttributePairs` moved to ./structured-attributes.ts (issue #1989\n// PR2) beside `assemblePersistedBody` so the write path and the sealed\n// envelope composer share ONE assembly definition. Re-exported to keep the\n// public storage API stable for existing callers.\nexport { normalizeAttributePairs } from \"./structured-attributes.js\";\n\n// ---------------------------------------------------------------------------\n// Entity file parsing / serialization (Knowledge Graph v7.0)\n// ---------------------------------------------------------------------------\n\nfunction parseEntityFrontmatter(raw: string): {\n frontmatter: {\n created?: string;\n updated?: string;\n synthesisUpdatedAt?: string;\n synthesisTimelineCount?: number;\n synthesisStructuredFactCount?: number;\n synthesisStructuredFactDigest?: string;\n synthesisVersion?: number;\n extraLines?: string[];\n };\n body: string;\n} {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!match) {\n return { frontmatter: {}, body: raw };\n }\n\n const values: Record<string, string> = {};\n const extraLines: string[] = [];\n const recognizedKeys: Record<string, true> = {\n created: true,\n updated: true,\n type: true,\n synthesis_updated_at: true,\n synthesis_timeline_count: true,\n synthesis_structured_fact_count: true,\n synthesis_structured_fact_digest: true,\n synthesis_version: true,\n };\n for (const line of match[1].split(/\\r?\\n/)) {\n if (/^\\s/.test(line)) {\n extraLines.push(line);\n continue;\n }\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) {\n extraLines.push(line);\n continue;\n }\n const key = line.slice(0, colonIdx).trim();\n if (recognizedKeys[key] !== true) {\n extraLines.push(line);\n continue;\n }\n const value = parseManagedFrontmatterValue(line.slice(colonIdx + 1));\n values[key] = value;\n }\n\n const synthesisTimelineCount = Number.parseInt(values.synthesis_timeline_count ?? \"\", 10);\n const synthesisStructuredFactCount = Number.parseInt(values.synthesis_structured_fact_count ?? \"\", 10);\n const synthesisVersion = Number.parseInt(values.synthesis_version ?? \"\", 10);\n return {\n frontmatter: {\n created: values.created || undefined,\n updated: values.updated || undefined,\n synthesisUpdatedAt: values.synthesis_updated_at || undefined,\n synthesisTimelineCount: Number.isFinite(synthesisTimelineCount) ? synthesisTimelineCount : undefined,\n synthesisStructuredFactCount: Number.isFinite(synthesisStructuredFactCount)\n ? synthesisStructuredFactCount\n : undefined,\n synthesisStructuredFactDigest: values.synthesis_structured_fact_digest || undefined,\n synthesisVersion: Number.isFinite(synthesisVersion) ? synthesisVersion : undefined,\n extraLines,\n },\n body: match[2],\n };\n}\n\nfunction parseManagedFrontmatterValue(rawValue: string): string {\n const trimmed = rawValue.trim();\n if (!trimmed) return \"\";\n\n const openingQuote = trimmed[0];\n if (openingQuote === '\"' || openingQuote === \"'\") {\n let escaped = false;\n for (let index = 1; index < trimmed.length; index += 1) {\n const char = trimmed[index];\n if (openingQuote === '\"' && !escaped && char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (!escaped && char === openingQuote) {\n return trimmed.slice(1, index);\n }\n escaped = false;\n }\n return trimmed.slice(1).replace(new RegExp(`${openingQuote}$`), \"\");\n }\n\n for (let index = 0; index < trimmed.length; index += 1) {\n if (trimmed[index] === \"#\" && (index === 0 || /\\s/.test(trimmed[index - 1] ?? \"\"))) {\n return trimmed.slice(0, index).trimEnd();\n }\n }\n\n return trimmed;\n}\n\nfunction readEntitySectionText(\n lines: string[],\n sectionNames: string[],\n options: {\n preserveBullets?: boolean;\n skipTimelineBullets?: boolean;\n } = {}\n): string | undefined {\n const normalizedSections = new Set(sectionNames.map((name) => name.toLowerCase()));\n let section = \"\";\n const sectionLines: string[] = [];\n for (const line of lines) {\n if (line.startsWith(\"## \")) {\n const nextSection = line.slice(3).trim().toLowerCase();\n if (section && !normalizedSections.has(nextSection)) break;\n section = normalizedSections.has(nextSection) ? nextSection : \"\";\n continue;\n }\n if (!section) continue;\n const trimmed = line.trim();\n if (!trimmed) {\n if (options.preserveBullets === true && sectionLines.length > 0 && sectionLines[sectionLines.length - 1] !== \"\") {\n sectionLines.push(\"\");\n }\n continue;\n }\n if (\n options.skipTimelineBullets === true &&\n trimmed.startsWith(\"- \") &&\n isEntitySynthesisTimelinePromotionBullet(trimmed.slice(2))\n ) {\n continue;\n }\n if (trimmed.startsWith(\"- \") && options.preserveBullets !== true) continue;\n sectionLines.push(options.preserveBullets === true ? line.trimEnd() : trimmed);\n }\n while (sectionLines[sectionLines.length - 1] === \"\") {\n sectionLines.pop();\n }\n if (sectionLines.length === 0) return undefined;\n return sectionLines.join(options.preserveBullets === true ? \"\\n\" : \" \");\n}\n\n/**\n * Parse an entity markdown file into a structured EntityFile.\n * Backward compatible: old files without new sections get empty arrays.\n */\nexport function parseEntityFile(content: string, entitySchemas?: PluginConfig[\"entitySchemas\"]): EntityFile {\n const { frontmatter, body } = parseEntityFrontmatter(content);\n const lines = body.split(\"\\n\");\n const recognizedSections = new Set([\n \"facts\",\n \"timeline\",\n \"summary\",\n \"synthesis\",\n \"connected to\",\n \"activity\",\n \"aliases\",\n ]);\n\n // Header\n let name = \"\";\n let type = \"other\";\n let created = frontmatter.created ?? \"\";\n let updated = \"\";\n const legacyFacts: string[] = [];\n const relationships: EntityRelationship[] = [];\n const activity: EntityActivityEntry[] = [];\n const aliases: string[] = [];\n const timeline: EntityTimelineEntry[] = [];\n const extraSections: Array<{ title: string; lines: string[] }> = [];\n\n // Parse name from first heading\n const headingLine = lines.find((l) => l.startsWith(\"# \"));\n if (headingLine) name = headingLine.slice(2).trim();\n\n // Parse type\n const typeLine = lines.find((l) => l.startsWith(\"**Type:**\"));\n if (typeLine) type = typeLine.replace(\"**Type:**\", \"\").trim();\n\n // Parse updated\n const updatedLine = lines.find((l) => l.startsWith(\"**Updated:**\"));\n if (updatedLine) updated = updatedLine.replace(\"**Updated:**\", \"\").trim();\n if (!updated) updated = frontmatter.updated ?? frontmatter.created ?? \"\";\n if (!created) created = updated;\n\n const headingLineIndex = lines.findIndex((l) => l.startsWith(\"# \"));\n const firstSectionIndex = lines.findIndex((l) => l.startsWith(\"## \"));\n const preSectionStartIndex = headingLineIndex > -1 ? headingLineIndex + 1 : 0;\n const preSectionCandidates =\n firstSectionIndex > -1 ? lines.slice(preSectionStartIndex, firstSectionIndex) : lines.slice(preSectionStartIndex);\n const preSectionLines = preSectionCandidates.filter(\n (line) => !line.startsWith(\"**Type:**\") && !line.startsWith(\"**Updated:**\")\n );\n const normalizedPreSectionLines = [...preSectionLines];\n while (normalizedPreSectionLines[0] === \"\") {\n normalizedPreSectionLines.shift();\n }\n const preservedPreSectionLines = normalizedPreSectionLines.some((line) => line.trim().length > 0)\n ? normalizedPreSectionLines\n : [];\n\n const fallbackTimestamp = updated || created || \"\";\n\n // Detect which section we're in\n let section = \"\";\n let currentExtraSection: { title: string; lines: string[] } | null = null;\n for (const line of lines) {\n if (line.startsWith(\"## \")) {\n const heading = line.slice(3).trim();\n section = heading.toLowerCase();\n if (recognizedSections.has(section)) {\n currentExtraSection = null;\n } else {\n currentExtraSection = { title: heading, lines: [] };\n extraSections.push(currentExtraSection);\n }\n continue;\n }\n if (currentExtraSection) {\n currentExtraSection.lines.push(line);\n }\n if (!line.startsWith(\"- \")) continue;\n\n const bullet = line.slice(2).trim();\n if (!bullet) continue;\n\n switch (section) {\n case \"facts\":\n legacyFacts.push(bullet);\n break;\n case \"timeline\": {\n const parsed = parseEntityTimelineBullet(bullet, fallbackTimestamp);\n if (parsed) timeline.push(parsed);\n break;\n }\n case \"summary\":\n case \"synthesis\":\n if (isEntitySynthesisTimelinePromotionBullet(bullet)) {\n const parsed = parseEntityTimelineBullet(bullet, fallbackTimestamp);\n if (parsed) timeline.push(parsed);\n }\n // Summary/synthesis is typically a paragraph after the heading, not a bullet.\n break;\n case \"connected to\": {\n // Format: [[target-entity]] — relationship label\n // Drop the \\s* after the dash and let (.+) capture the rest (trimmed\n // below). This removes the \\s*/(.+) overlap that backtracks polynomially\n // (CodeQL js/polynomial-redos) while staying exactly equivalent to the\n // original /…\\s*[—–-]\\s*(.+)$/ — including whitespace-only labels, which\n // still match and trim to \"\" (unlike a \\S-anchored capture).\n const relMatch = bullet.match(/^\\[\\[([^\\]]+)\\]\\]\\s*[—–-](.+)$/);\n if (relMatch) {\n relationships.push({ target: relMatch[1].trim(), label: relMatch[2].trim() });\n }\n break;\n }\n case \"activity\": {\n // Format: YYYY-MM-DD: note\n // Drop the \\s* after the colon and let (.+) capture the rest (trimmed\n // below): removes the \\s*/(.+) overlap (CodeQL js/polynomial-redos) and\n // stays exactly equivalent to the original, including whitespace-only\n // notes which still match and trim to \"\".\n const actMatch = bullet.match(/^(\\d{4}-\\d{2}-\\d{2}):(.+)$/);\n if (actMatch) {\n activity.push({ date: actMatch[1], note: actMatch[2].trim() });\n }\n break;\n }\n case \"aliases\":\n aliases.push(bullet);\n break;\n }\n }\n\n const legacyFactTimelineEntries = legacyFacts.map((fact) => ({\n timestamp: fallbackTimestamp,\n text: fact,\n source: \"migration\" as const,\n }));\n\n if (legacyFactTimelineEntries.length > 0) {\n const existingTimelineFacts = new Set(\n timeline.map((entry) => entry.text.trim()).filter((entry) => entry.length > 0)\n );\n for (const fact of legacyFactTimelineEntries) {\n const normalizedFact = fact.text.trim();\n if (!normalizedFact || existingTimelineFacts.has(normalizedFact)) continue;\n timeline.push(fact);\n existingTimelineFacts.add(normalizedFact);\n }\n }\n\n const synthesis =\n readEntitySectionText(lines, [\"Synthesis\"], { preserveBullets: true, skipTimelineBullets: true }) ??\n readEntitySectionText(lines, [\"Summary\"], { preserveBullets: true, skipTimelineBullets: true });\n const synthesisUpdatedAt = frontmatter.synthesisUpdatedAt || undefined;\n const synthesisTimelineCount = frontmatter.synthesisTimelineCount;\n const synthesisStructuredFactCount = frontmatter.synthesisStructuredFactCount;\n const synthesisStructuredFactDigest = frontmatter.synthesisStructuredFactDigest;\n const { structuredSections, remainingExtraSections } = partitionEntityStructuredSections(\n type,\n extraSections,\n entitySchemas\n );\n const facts = compileEntityFacts(timeline, structuredSections);\n\n return {\n name,\n type,\n created,\n updated,\n extraFrontmatterLines: frontmatter.extraLines ?? [],\n preSectionLines: preservedPreSectionLines,\n facts,\n summary: synthesis,\n synthesis,\n synthesisUpdatedAt,\n synthesisTimelineCount,\n synthesisStructuredFactCount,\n synthesisStructuredFactDigest,\n synthesisVersion: frontmatter.synthesisVersion,\n timeline,\n structuredSections,\n relationships,\n activity,\n aliases,\n extraSections: remainingExtraSections,\n };\n}\n\n/**\n * Serialize an EntityFile back to markdown.\n * Writes the compiled-truth + timeline format while remaining parse-compatible\n * with the legacy in-memory `summary` and `facts` fields.\n */\nexport function serializeEntityFile(\n entity: EntityFile,\n entitySchemas?: PluginConfig[\"entitySchemas\"],\n okfType?: boolean,\n): string {\n const synthesis = entity.synthesis || entity.summary || \"\";\n const created = entity.created?.trim() || entity.updated || new Date().toISOString();\n const updated = entity.updated || created;\n const timeline = entity.timeline;\n const structuredSections = sortStructuredSectionsBySchema(\n entity.type,\n (entity.structuredSections ?? [])\n .map((section) => {\n const normalized = normalizeStructuredSectionFactsWithOrigins(section.facts, section.factOrigins);\n const result = { ...section, ...normalized };\n if (normalized.factOrigins === undefined) delete result.factOrigins;\n return result;\n })\n .filter((section) => section.facts.length > 0),\n entitySchemas\n );\n const sectionFacts = new Set(collectStructuredSectionFacts(structuredSections));\n const legacyFacts =\n timeline.length === 0\n ? [\n ...new Set(\n entity.facts\n .map((fact) => normalizeEntitySectionFact(fact))\n .filter((fact) => fact.length > 0 && !sectionFacts.has(fact))\n ),\n ]\n : [];\n const synthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || \"\";\n const synthesisTimelineCount = entity.synthesisTimelineCount;\n const synthesisStructuredFactCount = entity.synthesisStructuredFactCount;\n const synthesisStructuredFactDigest = entity.synthesisStructuredFactDigest?.trim() || \"\";\n const synthesisVersion = entity.synthesisVersion ?? (synthesis ? 1 : 0);\n const lines: string[] = [\n \"---\",\n `created: ${created}`,\n `updated: ${updated}`,\n `synthesis_updated_at: \"${synthesisUpdatedAt}\"`,\n ...(synthesisTimelineCount === undefined ? [] : [`synthesis_timeline_count: ${synthesisTimelineCount}`]),\n ...(synthesisStructuredFactCount === undefined\n ? []\n : [`synthesis_structured_fact_count: ${synthesisStructuredFactCount}`]),\n ...(synthesisStructuredFactDigest ? [`synthesis_structured_fact_digest: \"${synthesisStructuredFactDigest}\"`] : []),\n `synthesis_version: ${synthesisVersion}`,\n ...(okfType === false ? [] : [`type: ${okfTypeForEntityKind(entity.type)}`]),\n ...(okfType === false\n ? (entity.extraFrontmatterLines ?? [])\n : (entity.extraFrontmatterLines ?? []).filter((line) => !line.startsWith(\"type:\"))),\n \"---\",\n \"\",\n `# ${entity.name}`,\n \"\",\n `**Type:** ${entity.type}`,\n `**Updated:** ${updated}`,\n \"\",\n ];\n if ((entity.preSectionLines ?? []).length > 0) {\n lines.push(...(entity.preSectionLines ?? []));\n if (entity.preSectionLines?.[entity.preSectionLines.length - 1] !== \"\") {\n lines.push(\"\");\n }\n }\n lines.push(\"## Synthesis\", \"\");\n if (synthesis) {\n lines.push(synthesis);\n }\n lines.push(\"\");\n\n if (timeline.length > 0 || legacyFacts.length === 0) {\n lines.push(\"## Timeline\", \"\");\n for (const entry of timeline) {\n lines.push(serializeEntityTimelineEntry(entry));\n }\n lines.push(\"\");\n }\n if (legacyFacts.length > 0) {\n lines.push(\"## Facts\", \"\");\n for (const fact of legacyFacts) {\n lines.push(`- ${fact}`);\n }\n lines.push(\"\");\n }\n for (const section of structuredSections) {\n lines.push(`## ${section.title}`, \"\");\n for (const [index, fact] of section.facts.entries()) {\n const origin = section.factOrigins?.[index];\n const prefix = origin\n ? `[${ENTITY_TIMELINE_METADATA_MARKER}] [remnic-origin=${escapeEntityTimelineMetadataValue(origin)}] `\n : \"\";\n lines.push(`- ${prefix}${escapeEntityTimelineText(fact)}`);\n }\n lines.push(\"\");\n }\n // Connected to (optional)\n if (entity.relationships.length > 0) {\n lines.push(\"## Connected to\", \"\");\n for (const rel of entity.relationships) {\n lines.push(`- [[${rel.target}]] — ${rel.label}`);\n }\n lines.push(\"\");\n }\n // Activity (optional)\n if (entity.activity.length > 0) {\n lines.push(\"## Activity\", \"\");\n for (const act of entity.activity) {\n lines.push(`- ${act.date}: ${act.note}`);\n }\n lines.push(\"\");\n }\n\n // Aliases (optional)\n if (entity.aliases.length > 0) {\n lines.push(\"## Aliases\", \"\");\n for (const alias of entity.aliases) {\n lines.push(`- ${alias}`);\n }\n lines.push(\"\");\n }\n\n for (const section of entity.extraSections ?? []) {\n lines.push(`## ${section.title}`);\n lines.push(...section.lines);\n if (section.lines.length > 0 && section.lines[section.lines.length - 1] !== \"\") {\n lines.push(\"\");\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function buildEntitySchemaCacheKey(entitySchemas?: PluginConfig[\"entitySchemas\"]): string {\n if (!entitySchemas) return \"\";\n const normalized = Object.entries(entitySchemas)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([entityType, schema]) => [\n entityType,\n {\n sections: schema.sections.map((section) => ({\n key: section.key,\n title: section.title,\n description: section.description,\n aliases: section.aliases ? [...section.aliases] : undefined,\n })),\n },\n ]);\n return JSON.stringify(normalized);\n}\n\n/**\n * Full-schema type guard for a `BUFFER_SURPRISE` telemetry row\n * (issue #563 PR 3).\n *\n * The reader applies `limit` over the count of VALID rows, so\n * applying only a partial check (e.g. \"has a finite surpriseScore\")\n * and then deferring the rest of validation to\n * `reportBufferSurpriseDistribution` would silently count\n * schema-incomplete rows toward the limit, pushing genuinely-valid\n * earlier rows out of the report window. Validate everything the\n * downstream report requires at read time so the limit semantics and\n * the distribution semantics stay consistent.\n */\nexport function isValidBufferSurpriseEvent(value: unknown): value is BufferSurpriseEvent {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const v = value as Record<string, unknown>;\n if (v.event !== \"BUFFER_SURPRISE\") return false;\n if (typeof v.timestamp !== \"string\" || v.timestamp.length === 0) return false;\n if (!Number.isFinite(Date.parse(v.timestamp))) return false;\n if (typeof v.bufferKey !== \"string\" || v.bufferKey.length === 0) return false;\n if (v.sessionKey !== null && typeof v.sessionKey !== \"string\") return false;\n if (v.turnRole !== \"user\" && v.turnRole !== \"assistant\") return false;\n if (typeof v.surpriseScore !== \"number\" || !Number.isFinite(v.surpriseScore)) {\n return false;\n }\n // Surprise is documented as a value in [0, 1] — reject out-of-range\n // rows at read time so they do not consume the caller's `limit`.\n if (v.surpriseScore < 0 || v.surpriseScore > 1) return false;\n if (typeof v.threshold !== \"number\" || !Number.isFinite(v.threshold)) return false;\n if (v.threshold < 0 || v.threshold > 1) return false;\n if (typeof v.triggeredFlush !== \"boolean\") return false;\n if (typeof v.turnCountInWindow !== \"number\" || !Number.isFinite(v.turnCountInWindow)) {\n return false;\n }\n return true;\n}\n\n/** Result of {@link StorageManager.writeMemory} (issue #1645). Carries the\n * persisted id PLUS the non-resurrection tombstone-block outcome (#1579) so\n * post-write callers can observe it — NEVER a silent no-op (rule 34). */\nexport interface MemoryWriteResult {\n /** The persisted memory id. */\n id: string;\n /** True when the #1579 tombstone chokepoint downgraded this write to\n * `pending_review` + `blockedBy`. Callers gate active post-write work on this. */\n tombstoneBlocked: boolean;\n /** The tombstone id that blocked the write, when `tombstoneBlocked`. */\n blockedBy?: string;\n /** Existing pending-review memory id when a blocked write coalesced with it. */\n duplicateOf?: string;\n}\n\n/**\n * Defensively parse the persisted per-fingerprint extraction retry state from\n * meta.json. Mirrors the tolerance of the `processedExtractionFingerprints`\n * loader: unknown/legacy shapes are dropped, never thrown on. Uses `in`/typeof\n * narrowing (no inline casts) so a malformed entry can't slip through typed.\n */\nfunction parseExtractionRetryStateEntries(raw: unknown): NonNullable<MetaState[\"extractionRetryState\"]> {\n if (!Array.isArray(raw)) return [];\n const valid: NonNullable<MetaState[\"extractionRetryState\"]> = [];\n for (const entry of raw) {\n if (!entry || typeof entry !== \"object\") continue;\n if (!(\"fingerprint\" in entry) || typeof entry.fingerprint !== \"string\") continue;\n if (!(\"attempts\" in entry) || typeof entry.attempts !== \"number\" || !Number.isFinite(entry.attempts)) continue;\n if (!(\"nextEligibleAt\" in entry) || typeof entry.nextEligibleAt !== \"string\") continue;\n if (!(\"firstFailedAt\" in entry) || typeof entry.firstFailedAt !== \"string\") continue;\n if (!(\"lastFailureClass\" in entry)) continue;\n const cls = entry.lastFailureClass;\n if (cls !== \"provider_retryable\" && cls !== \"parse_empty\" && cls !== \"auth_config\") continue;\n const lastFailureClass: ExtractionFailureClass = cls;\n valid.push({\n fingerprint: entry.fingerprint,\n attempts: entry.attempts,\n nextEligibleAt: entry.nextEligibleAt,\n firstFailedAt: entry.firstFailedAt,\n lastFailureClass,\n });\n }\n return valid;\n}\n\n/**\n * Options accepted by `StorageManager.writeMemory` (extracted verbatim in\n * issue #1989 PR2 so `SealedWriteExtras` can be derived from it — the\n * sealed-envelope path takes envelope-owned fields from the envelope and\n * everything else from these extras).\n */\nexport interface WriteMemoryOptions {\n actor?: string;\n confidence?: number;\n tags?: string[];\n entityRef?: string;\n source?: string;\n supersedes?: string;\n lineage?: string[];\n importance?: ImportanceScore;\n links?: MemoryLink[];\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n artifactType?: MemoryFrontmatter[\"artifactType\"];\n sourceMemoryId?: string;\n sourceTurnId?: string;\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n expiresAt?: string;\n validAt?: string;\n // Issue #1578 — bi-temporal ingestion provenance. `observedAt` is the\n // ingestion time (when Remnic learned the fact); `eventTimeSource`\n // records whether `validAt` was resolved from an extracted expression\n // or assumed from the ingestion anchor. Both validate on serialize.\n observedAt?: string;\n eventTimeSource?: \"extracted\" | \"assumed\";\n invalidAt?: string;\n structuredAttributes?: Record<string, string>;\n /**\n * When provided, this string is used as the source for the fact-content\n * dedup hash index instead of the persisted body (`content`).\n *\n * Use this when the persisted body differs from the canonical fact text\n * — for example when `content` is a citation-annotated variant of a raw\n * fact. Passing the raw fact as `contentHashSource` ensures that\n * `hasFactContentHash(rawFact)` returns `true` after the write, so\n * subsequent extractions of the same logical fact are correctly deduped\n * even when their citation timestamp differs.\n */\n contentHashSource?: string;\n /**\n * When true, writeMemory marks the fact-hash index dirty via `.add(...)`\n * but does NOT flush it to disk — the caller is responsible for a\n * subsequent batch save (issue #1909). The extraction persist path sets\n * this and relies on the orchestrator's authoritative\n * `saveContentHashIndexes()` batch save plus a per-storage union flush,\n * avoiding a whole-index (which grows with corpus size) rewrite per fact.\n * Default false: every\n * other (single-write) caller keeps the immediate, crash-safe save.\n */\n deferHashIndexSave?: boolean;\n status?: MemoryStatus;\n /**\n * Consolidation provenance (issue #561 PR 2). When the caller is a\n * consolidation / supersession / dedup-merge path, these fields wire\n * the page-version snapshots the new memory was derived from and the\n * operator that produced it. Persisted onto frontmatter as\n * `derived_from` + `derived_via`; validated at serialize time.\n */\n derivedFrom?: string[];\n derivedVia?: ConsolidationOperator;\n /**\n * Faithfulness gate verdict (issue #1576). When provided, persisted to\n * frontmatter so downstream readers (TrustScore #1577, review queue)\n * can consume it. Absent = gate was off or fact predates #1576.\n */\n faithfulness?: import(\"./types.js\").FaithfulnessFrontmatter;\n /**\n * Claim-level provenance spans (issue #1575 PR 2). When provided,\n * persisted to frontmatter so downstream readers (memory_get, x-ray,\n * faithfulness gate #1576) can consume them. Absent = fact predates\n * #1575 or provenance was disabled.\n */\n sources?: ProvenanceSource[];\n provenance?: \"verified\" | \"unverified\" | \"none\";\n origin?: string;\n sourceConnector?: string;\n toolScoped?: true;\n subject?: MemorySubject;\n}\n\n/**\n * `WriteMemoryOptions` minus the fields a `SealedMemoryEnvelope` owns.\n * Passing an envelope-owned field twice is a compile error by construction.\n */\nexport type SealedWriteExtras = Omit<\n WriteMemoryOptions,\n \"confidence\" | \"tags\" | \"entityRef\" | \"source\" | \"expiresAt\" | \"validAt\" | \"structuredAttributes\" | \"sourceConnector\" | \"origin\" | \"subject\"\n>;\n\nexport class StorageManager extends TombstoneBlockedCaptureIndexHost {\n private knowledgeIndexCache: { result: string; builtAt: number } | null = null;\n private readonly deletionRevisionStore: DeletionRevisionStore;\n private artifactIndexCache: { memories: MemoryFile[]; loadedAtMs: number; writeVersion: number } | null = null;\n private projectionLedgerLagManager = new ProjectionLedgerLagManager();\n private static readonly loadedMemorySnapshots = new WeakMap<MemoryFile, string>();\n static readonly KNOWLEDGE_INDEX_CACHE_TTL_MS = 600_000; // 10 minutes (entity mutations invalidate)\n /** Read by storage/memory-read-store.ts (decomposition). */\n static readonly ARTIFACT_INDEX_CACHE_TTL_MS = 60_000; // 1 minute\n private static readonly artifactWriteVersionByDir = new Map<string, number>();\n private static readonly memoryStatusVersionByDir = new Map<string, number>();\n // Corpus version sentinel (issue #1902): bumped on every memory-FILE mutation\n // so the version-keyed hot-memories cache stays coherent across processes,\n // without touching memory-status (which would invalidate the entity cache on\n // every plain create). In-process fallback when the on-disk sentinel is\n // unavailable; canonical source is state/.memory-corpus-version.log.\n private static readonly memoryCorpusVersionByDir = new Map<string, number>();\n // Entity-mutation sentinel: see getEntityMutationVersion.\n private static readonly entityMutationVersionByDir = new Map<string, number>();\n private static readonly secureStoreEntityCacheKeyIds = new WeakMap<Buffer, number>();\n private static nextSecureStoreEntityCacheKeyId = 1;\n // In-process fallback for the cold-write sentinel (used when the disk file\n // is not accessible). The canonical source of truth is state/cold-write.log.\n private static readonly coldWriteVersionByDir = new Map<string, number>();\n\n /**\n * Process-wide default for the hot-memories result cache gate (issue #1902).\n * Set once from config by the orchestrator/access layer via\n * setHotMemoriesCacheDefault() so that EVERY StorageManager — including the\n * ephemeral instances recall sub-stages (verified-recall, semantic-rule\n * verification, ...) construct over the same dir — honors the operator's\n * hotMemoriesCacheEnabled setting. The constructor option overrides this\n * per-instance (tests). Defaults true (cache on).\n */\n private static hotMemoriesCacheDefault = true;\n\n /**\n * Per-memory-directory override of the hot-cache gate (issue #1902, Codex\n * P2). setHotMemoriesCacheDefault(memoryDir, enabled) registers the\n * operator's setting keyed by dir, so a StorageManager constructed over that\n * dir honors ITS owning orchestrator's config — not merely the last\n * orchestrator constructed in the process. Unregistered dirs fall back to\n * the process-wide default above.\n */\n private static readonly hotMemoriesCacheDefaultByDir = new Map<string, boolean>();\n\n /**\n * Process-wide TTL (ms) safety net for the hot cache (issue #1902). Bounds\n * how long a version-keyed entry is served before a fresh disk scan, so\n * external filesystem edits (manual/git/editor) that don't bump the sentinel\n * self-heal. Set from config by the orchestrator via setHotMemoriesCacheDefault.\n * 0 disables the TTL (version invalidation only). Default 60s.\n */\n private static hotMemoriesCacheTtlMs = 60_000;\n\n /**\n * Per-memory-directory override of the hot-cache TTL (issue #1902, Codex P2),\n * mirroring hotMemoriesCacheDefaultByDir. Registered by\n * setHotMemoriesCacheDefault so two orchestrators in one process with\n * different TTLs don't clobber each other's setting. Unregistered dirs fall\n * back to the process-wide default above.\n */\n private static readonly hotMemoriesCacheTtlByDir = new Map<string, number>();\n\n /**\n * Whether the process-wide hot-cache fallbacks (hotMemoriesCacheDefault /\n * hotMemoriesCacheTtlMs) have been seeded by the first\n * setHotMemoriesCacheDefault call (issue #1902, Cursor Low). Only the first\n * registration seeds them; later registrations touch ONLY their per-dir map\n * entry. This makes the process-wide fallback deterministic (first-writer,\n * by init order) instead of last-writer-wins, so a second orchestrator with\n * a divergent config cannot silently flip the fallback that unregistered\n * dirs resolve to. All REGISTERED dirs are isolated by the per-dir maps.\n */\n private static hotMemoriesCacheProcessDefaultSeeded = false;\n\n /**\n * Per-memory-directory gate for scope-aware cache invalidation (issue #1904).\n * Registered from config by the orchestrator via\n * setScopedCacheInvalidationDefault() so every StorageManager built over a\n * memory dir — including ephemeral recall sub-stage instances — honors the\n * operator's setting. Unregistered dirs default to `true` (scoped on). Set\n * `false` to restore the pre-#1904 full-clear-per-write behavior (rollback\n * lever). Read once per write via isScopedCacheInvalidationEnabled().\n */\n private static readonly scopedCacheInvalidationByDir = new Map<string, boolean>();\n\n // Module-level maps for readAllMemories() keyed by base directory, shared\n // across all StorageManager instances (static) so concurrent callers over\n // the same dir cooperate.\n\n // Cache for readAllColdMemories() — keyed by cold root directory path.\n // Prevents an uncached full-tree directory scan on every structured-attribute\n // write (Finding UOGi, PR #402 round-6). Invalidated when cold-tier content\n // changes (via invalidateColdMemoriesCache) and expires after COLD_SCAN_CACHE_TTL_MS.\n // Entries carry a `coldVersion` sentinel (Finding UvUy, PR #402 round-11) bumped\n // on every cold-tier write, making the cache correct across process boundaries\n // (gateway + CLI). After Finding UTsP broadened the scan to the entire cold/\n // subtree, amortizing across back-to-back writes is even more important.\n /** Read by storage/memory-read-store.ts (decomposition). */\n static readonly COLD_SCAN_CACHE_TTL_MS = 30_000; // 30 seconds\n /** Read by storage/memory-read-store.ts (decomposition). */\n static readonly coldMemoriesCache = new Map<\n string,\n { memories: MemoryFile[]; loadedAt: number; coldVersion: number; keyId: string }\n >();\n\n // Cache for readQuestions() — avoids serially re-reading tens of thousands of\n // question files on every recall. 60-second TTL is intentionally short so that\n // newly written questions surface quickly.\n /** Read by storage/memory-read-store.ts (decomposition). */\n static readonly QUESTIONS_CACHE_TTL_MS = 60_000; // 1 minute\n /** Read by storage/memory-read-store.ts (decomposition). */\n static readonly questionsCache = new Map<\n string,\n {\n questions: Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>;\n loadedAt: number;\n }\n >();\n private factHashIndex: ContentHashIndex | null = null;\n private factHashIndexLoadPromise: Promise<ContentHashIndex> | null = null;\n private factHashIndexAuthoritative: boolean | null = null;\n private factHashIndexAuthoritativePromise: Promise<boolean> | null = null;\n /**\n * Fact-ONLY hash membership (PR #2016 / issue #2474) lives on the shared\n * `ContentHashIndex` fact-only partition (`addFact*` / `hasFact*` /\n * `removeFactByHash`), not a parallel set here. The partition carries only\n * `category === \"fact\"` hashes and is the sole source for\n * `hasFactContentHash`, so an over-included non-fact body can never\n * suppress a real fact candidate. In-memory only; never persisted — every\n * authoritative corpus rebuild repopulates it via\n * `ContentHashIndex.clear()` + `addFactByHash`.\n */\n /** Optional lock/retry tuning for the fact-hash index cross-process lock (PR #2016; tests inject tight budgets). */\n factHashIndexLockOptions: ContentHashIndexLockOptions = {};\n private readonly secureAppendChains = new Map<string, Promise<void>>();\n /**\n * Cache of \"is this file encrypted?\" keyed by absolute path, VALIDATED by file\n * identity (size + mtimeMs) — issue #1909 review round 10 finding 1. A prior\n * design cached only a boolean and relied on this instance's own writes to\n * invalidate it; a PEER process encrypting the file would not invalidate,\n * leaving a stale `false` that made the append path write RAW bytes into an\n * encrypted file (corruption). Now each entry records the (size, mtime) the\n * classification was read at; `isEncryptedFileHeader` re-sniffs (header-only)\n * whenever the on-disk identity no longer matches, so a foreign rewrite is\n * detected. The whole-file read is still never performed.\n */\n private readonly secureFileEncryptionSniffCache = new Map<\n string,\n { identity: { size: number; mtimeMs: number }; encrypted: boolean }\n >();\n private offlineSyncDigestCache: Map<string, OfflineSyncDigestCacheEntry> | null = null;\n private offlineSyncDigestCacheLoadPromise: Promise<Map<string, OfflineSyncDigestCacheEntry>> | null = null;\n private offlineSyncDigestCacheWriteChain: Promise<void> = Promise.resolve();\n private offlineSyncDigestCacheWriteTimer: ReturnType<typeof setTimeout> | null = null;\n /** Optional: set by the orchestrator after construction to enable template-aware citation stripping during legacy hash rebuild. */\n citationTemplate: string = DEFAULT_CITATION_FORMAT;\n /** Post-write catalog hook (#1522). Installed by the namespace router; fire-and-forget. */\n onCatalogWrite?: () => void;\n /** Post-write embedding hook (#2019). Installed by the orchestrator; fire-and-forget. */\n onMemoryWrite?: (filePath: string) => void;\n private notifyMemoryWrite(filePath: string): void {\n try {\n this.onMemoryWrite?.(filePath);\n } catch {\n /* fire-and-forget — embedding failures must not block writes */\n }\n }\n private notifyCatalogWrite(): void {\n try {\n this.onCatalogWrite?.();\n } catch {\n /* gotcha #13 */\n }\n }\n\n /**\n * Whether pure state-file writes touch the namespace catalog (issue #1903).\n * Set by `NamespaceStorageRouter.bindCatalogWriteHook` from\n * `namespacesCatalogTouchStateWrites` (default false). State files\n * (`state/buffer.json`, ledgers, indexes) are not namespace memory data, so by\n * default their writes do NOT record a catalog touch.\n */\n touchStateWrites = false;\n\n /**\n * Post-write catalog hook, gated by file path (issue #1903). Namespace data\n * (`facts/`, `cold/`, `entities/`, `artifacts/`, `profile.md`, ...) lives\n * OUTSIDE `stateDir`, so a data write always touches; a write under `stateDir`\n * is a pure state write and is skipped unless `touchStateWrites` is enabled.\n */\n protected notifyCatalogWriteForPath(filePath: string): void {\n if (!this.touchStateWrites && this.isStateFilePath(filePath)) return;\n this.notifyCatalogWrite();\n }\n\n /** Whether `filePath` resolves to `stateDir` itself or a path contained in it. */\n private isStateFilePath(filePath: string): boolean {\n const rel = path.relative(this.stateDir, path.resolve(filePath));\n return rel === \"\" || (!rel.startsWith(\"..\") && !path.isAbsolute(rel));\n }\n\n // ── Tombstone store (issue #1579) ───────────────────────────────────────\n // Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.\n // Lazily loaded from <stateDir>/tombstones.jsonl; invalidated together with\n // every other cache layer via invalidateAllMemoriesCache (rule 25).\n private tombstoneStore: TombstoneStore | null = null;\n private tombstoneStoreLoadPromise: Promise<TombstoneStore> | null = null;\n private tombstonesConfig: {\n enabled: boolean;\n semanticMatch: boolean;\n semanticThreshold: number;\n namespace: string;\n } = { enabled: false, semanticMatch: false, semanticThreshold: 0.9, namespace: \"default\" };\n\n /** Page-versioning configuration. Set by the orchestrator after construction. */\n private _versioningConfig: VersioningConfig | null = null;\n\n /** Set the page-versioning configuration. When `enabled` is false (default), all versioning calls are no-ops. */\n setVersioningConfig(config: VersioningConfig): void {\n this._versioningConfig = config;\n }\n\n /**\n * At-rest encryption key (issue #690 PR 3/4).\n *\n * When non-null, every memory file read is decrypted and every write\n * is encrypted using the secure-fs layer. When null, the storage\n * layer operates in plain-text mode (legacy/unencrypted store).\n *\n * Set by the orchestrator after init/unlock; cleared on lock.\n * The key buffer is NEVER logged or serialized.\n */\n private _secureStoreKey: Buffer | null = null;\n\n /**\n * When true (and `_secureStoreKey` is non-null), new writes are\n * encrypted. Set to false to pause encryption of new writes while\n * still decrypting existing files.\n */\n private _secureStoreEncryptOnWrite = true;\n\n /**\n * When true, the secure-store is configured as required — writes\n * MUST be encrypted and a locked store MUST reject writes rather\n * than silently falling back to plaintext. Set by the orchestrator\n * from `resolveRecallAuxiliaryCapabilities(config).secureStore`.\n */\n private _secureStoreRequired = false;\n\n /**\n * Set or clear the at-rest encryption key.\n *\n * Pass a 32-byte Buffer to enable encryption; pass null to clear\n * (lock) the store. The caller is responsible for key lifecycle —\n * this method does not zero the buffer on replacement; the keyring\n * module (`keyring.ts`) owns zeroization. The setter remains synchronous\n * for existing consumers; call `setSecureStoreKeyAndWait` when unlock must\n * await migration.\n */\n setSecureStoreKey(key: Buffer | null, encryptOnWrite = true): void {\n if (!this.applySecureStoreKey(key, encryptOnWrite) || key === null) return;\n void this.entityCanonicalIdMigration.triggerAfterUnlock().catch((error: unknown) => {\n log.warn(`secure-store unlock migration failed: ${error instanceof Error ? error.message : String(error)}`);\n });\n }\n\n public async setSecureStoreKeyAndWait(key: Buffer | null, encryptOnWrite = true): Promise<void> {\n if (!this.applySecureStoreKey(key, encryptOnWrite) || key === null) return;\n await this.entityCanonicalIdMigration.triggerAfterUnlock();\n }\n\n private applySecureStoreKey(key: Buffer | null, encryptOnWrite: boolean): boolean {\n const sameKey =\n this._secureStoreKey === key ||\n (this._secureStoreKey !== null && key !== null && this._secureStoreKey.equals(key));\n if (sameKey && this._secureStoreEncryptOnWrite === encryptOnWrite) return false;\n\n this._secureStoreKey = key;\n this._secureStoreEncryptOnWrite = encryptOnWrite;\n invalidateAllForDir(this.baseDir);\n this.invalidateKnowledgeIndexCache();\n this.secureFileEncryptionSniffCache.clear();\n this.behaviorSignalsKeyCache = null;\n return true;\n }\n\n private getEntityCacheSecureStoreKey(): string {\n if (!this._secureStoreKey) return \"secure-store:locked\";\n let id = StorageManager.secureStoreEntityCacheKeyIds.get(this._secureStoreKey);\n if (id === undefined) {\n id = StorageManager.nextSecureStoreEntityCacheKeyId++;\n StorageManager.secureStoreEntityCacheKeyIds.set(this._secureStoreKey, id);\n }\n return `secure-store:key:${id}`;\n }\n\n /**\n * Secure-store key identity for the version-keyed hot/archive memory caches\n * (issue #1902, Codex P1). Scopes cached DECRYPTED corpora by the key that\n * decrypted them, so a locked/unkeyed StorageManager for the same baseDir\n * never reads content another instance decrypted under a key (which would\n * bypass the locked-store error). Plaintext and locked stores share the \"\"\n * namespace; an unlocked encrypted store uses its per-key id.\n */\n hotCacheKeyId(): string {\n return this._secureStoreKey === null ? \"\" : this.getEntityCacheSecureStoreKey();\n }\n\n /**\n * Resolved hot-cache gate for THIS store (issue #1902, Cursor Medium): the\n * per-instance override if one was passed, else the per-dir/process default.\n * Recall sub-stages (verified-recall, semantic-rule) read this to honor the\n * operator's opt-out for their derived caches even when the caller omits the\n * flag in options.\n */\n isHotCacheEnabled(): boolean {\n return this.hotMemoriesCacheEnabled;\n }\n\n /**\n * Effective hot-cache TTL (ms) for this store's dir (issue #1902): the per-dir\n * registration if present, else the process-wide default. 0 disables the TTL.\n */\n hotCacheTtlMs(): number {\n return StorageManager.hotMemoriesCacheTtlByDir.get(this.baseDir) ?? StorageManager.hotMemoriesCacheTtlMs;\n }\n\n /**\n * True if `p` lives in this store's cold/ or archive/ tier (issue #1902,\n * Codex P2). Determined RELATIVE to baseDir — a substring scan of the\n * absolute path would misclassify every active path when memoryDir itself is\n * nested under a dir literally named \"cold\" or \"archive\" (e.g.\n * /srv/cold/remnic), skipping the patch and stranding a stale hot entry.\n */\n private isColdOrArchiveTierPath(p: string): boolean {\n const rel = path.relative(this.baseDir, p);\n return (\n rel === \"cold\" || rel === \"archive\" || rel.startsWith(`cold${path.sep}`) || rel.startsWith(`archive${path.sep}`)\n );\n }\n\n /**\n * Mark the secure-store as required for this storage instance.\n * When required and locked, writes throw SecureStoreLockedError\n * rather than silently writing plaintext.\n */\n setSecureStoreRequired(required: boolean): void {\n this._secureStoreRequired = required;\n }\n\n /** Return true iff the secure-store key is currently set (store is unlocked). */\n isSecureStoreUnlocked(): boolean {\n return this._secureStoreKey !== null;\n }\n\n /** Whether a state-file write encrypts at rest (encrypt-on-write on AND key\n * set) — the write mode lifecycle compaction reserves the envelope for (#2033). */\n willEncryptStateWrites(): boolean {\n return this._secureStoreEncryptOnWrite && this._secureStoreKey !== null;\n }\n\n /**\n * Resolve the effective write key: null when encrypt-on-write is off or the\n * store is unlocked-optional; the key when set; else throws\n * SecureStoreLockedError under a required-but-locked store (PR #767) instead\n * of silently writing plaintext.\n *\n * `forceEncrypt` overrides the encrypt-on-write policy flag ONLY (issue\n * #2033): a lifecycle-ledger compaction of an already-encrypted ledger/backup\n * must preserve encryption at rest even when `secureStoreEncryptOnWrite` is\n * paused, or it would silently downgrade encrypted state to plaintext. It\n * never bypasses the LOCK: when the store has no key it still returns null\n * (optional) or throws (required), so a keyless caller can never fabricate an\n * encrypted write.\n */\n private resolveWriteKey(forceEncrypt = false): Buffer | null {\n if (!forceEncrypt && !this._secureStoreEncryptOnWrite) return null;\n if (this._secureStoreKey !== null) return this._secureStoreKey;\n if (this._secureStoreRequired) {\n throw new SecureStoreLockedError(\n \"secure-store is locked — cannot write memory file. \" +\n \"Run `remnic secure-store unlock` to decrypt, or restart the daemon after unlocking.\"\n );\n }\n return null;\n }\n\n /**\n * Snapshot the current content of a page before overwriting.\n * No-op when versioning is disabled or the file does not yet exist.\n */\n private async snapshotBeforeWrite(filePath: string, trigger: VersionTrigger): Promise<void> {\n if (!this._versioningConfig || !this._versioningConfig.enabled) return;\n try {\n // Use the secure-fs read path so the snapshot captures plaintext\n // regardless of whether the file is currently encrypted on disk.\n const existing = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);\n await createPageVersion(filePath, existing, trigger, this._versioningConfig, log, undefined, this.baseDir);\n } catch {\n // File does not exist yet — nothing to snapshot\n }\n }\n\n /**\n * Consolidation provenance helper (issue #561 PR 2).\n *\n * Captures the current on-disk content of a source memory as a\n * page-version snapshot so the downstream consolidated write can record a\n * `derived_from` pointer that actually resolves. Returns the\n * `\"<relative-path>:<versionId>\"` entry expected by the `derived_from`\n * frontmatter field.\n *\n * Returns `null` when versioning is disabled (snapshots would not be\n * created), when the file does not exist (nothing to snapshot), or when\n * the snapshot write itself fails (best-effort — callers skip the entry\n * rather than block the consolidation).\n */\n async snapshotForProvenance(filePath: string): Promise<string | null> {\n if (!this._versioningConfig || !this._versioningConfig.enabled) return null;\n let existing: string;\n try {\n existing = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);\n } catch {\n return null;\n }\n try {\n const version = await createPageVersion(\n filePath,\n existing,\n \"consolidation\",\n this._versioningConfig,\n log,\n undefined,\n this.baseDir\n );\n const rel = path.relative(this.baseDir, filePath).split(path.sep).join(\"/\");\n return `${rel}:${version.versionId}`;\n } catch (err) {\n log.warn(\n `storage.snapshotForProvenance: failed to snapshot ${filePath}: ${err instanceof Error ? err.message : String(err)}`\n );\n return null;\n }\n }\n\n private readonly hotMemoriesCacheEnabled: boolean;\n\n constructor(\n private readonly baseDir: string,\n private readonly entitySchemas?: PluginConfig[\"entitySchemas\"],\n /**\n * Hot-memories result cache gate (issue #1902). When omitted, resolves to\n * the per-directory default registered by setHotMemoriesCacheDefault()\n * (falling back to the process-wide default); pass an explicit boolean to\n * override per-instance (tests, memory-constrained readers).\n */\n hotMemoriesCacheEnabledOverride?: boolean\n ) {\n super();\n this.deletionRevisionStore = new DeletionRevisionStore({\n baseDir,\n deletionRevisionMetadataPath: path.join(baseDir, \".offline-sync\", \"deletion-revisions.v1.json\"),\n invalidationCommitMetadataPath: path.join(baseDir, \".offline-sync\", \"invalidation-commits.v1.json\"),\n deletionRevisionLockPath: path.join(baseDir, \".offline-sync\", \"deletion-revisions.v1.json.lock\"),\n assertManagedStoragePath: (filePath, method) => this.assertManagedStoragePath(filePath, method),\n });\n this.hotMemoriesCacheEnabled =\n hotMemoriesCacheEnabledOverride ??\n StorageManager.hotMemoriesCacheDefaultByDir.get(baseDir) ??\n StorageManager.hotMemoriesCacheDefault;\n // Load this store's alias table at construction (#1534): StorageManager\n // is created in a dozen places (namespace router, operator toolkit,\n // compounding engine, cold storage, ...) and most never call\n // loadAliases() explicitly — every creation path must still get the\n // store's own aliases, never an empty or foreign table.\n this.loadAliasesSync();\n }\n\n /** Set the process-wide hot-memories cache default (issue #1902). The\n * orchestrator/access layer calls this with the operator's\n * hotMemoriesCacheEnabled config so the escape hatch reaches every\n * StorageManager, including ephemeral recall-sub-stage instances. Only an\n * explicit `false` disables; `undefined` (e.g. a cast test config missing\n * the field) leaves the cache on. */\n static setHotMemoriesCacheDefault(memoryDir: string, enabled: boolean | undefined, ttlMs?: number): void {\n // Register per-dir so each orchestrator's config reaches every\n // StorageManager built over its own memory dir (Codex P2). The per-dir map\n // is authoritative for every registered dir.\n StorageManager.hotMemoriesCacheDefaultByDir.set(memoryDir, enabled !== false);\n // TTL safety net: a finite, non-negative override wins (0 honored = disable).\n // Registered per-dir (Codex P2) so concurrent orchestrators with different\n // TTLs don't clobber each other.\n const ttlValid = typeof ttlMs === \"number\" && Number.isFinite(ttlMs) && ttlMs >= 0;\n if (ttlValid) {\n StorageManager.hotMemoriesCacheTtlByDir.set(memoryDir, ttlMs as number);\n }\n // Seed the process-wide fallbacks (for UNregistered dirs) ONCE, from the\n // first registration only (issue #1902, Cursor Low). A later orchestrator\n // with a divergent config must not flip the fallback out from under the\n // first — that was a last-writer-wins race. First-writer is deterministic\n // by init order, and every registered dir is isolated per-dir above.\n if (!StorageManager.hotMemoriesCacheProcessDefaultSeeded) {\n StorageManager.hotMemoriesCacheDefault = enabled !== false;\n if (ttlValid) StorageManager.hotMemoriesCacheTtlMs = ttlMs as number;\n StorageManager.hotMemoriesCacheProcessDefaultSeeded = true;\n }\n }\n\n /** Register the operator's scope-aware cache invalidation gate for a memory\n * dir (issue #1904). The orchestrator/access layer calls this with\n * the operator's scopedCacheInvalidationEnabled flag so the setting reaches every\n * StorageManager built over the dir, including ephemeral recall-sub-stage\n * instances. Only an explicit `false` disables; `undefined` leaves it on. */\n static setScopedCacheInvalidationDefault(memoryDir: string, enabled: boolean | undefined): void {\n StorageManager.scopedCacheInvalidationByDir.set(memoryDir, enabled !== false);\n }\n\n /** OKF `type` emission gate registrations per memory dir (issue #1946). */\n private static readonly okfConformanceByDir = new Map<string, boolean>();\n\n /** Register the OKF conformance gate for a memory dir. Unregistered dirs default to\n * conformance-on; namespace child dirs (<memoryDir>/namespaces/<tok>) inherit the\n * nearest registered ancestor. Only an explicit `false` disables. */\n static setOkfConformanceDefault(memoryDir: string, enabled: boolean | undefined): void {\n StorageManager.okfConformanceByDir.set(memoryDir, enabled !== false);\n }\n\n okfConformanceEnabled(): boolean {\n for (let dir = this.baseDir; ; dir = path.dirname(dir)) {\n const registered = StorageManager.okfConformanceByDir.get(dir);\n if (registered !== undefined) return registered;\n if (dir === path.dirname(dir)) return true;\n }\n }\n\n /**\n * The LIVE class object of this instance (issue #1809 review of the\n * storage decomposition): extracted store modules must read/write the\n * shared static caches (questionsCache, coldMemoriesCache, ...) through\n * the SAME class binding the host methods use. Referencing the imported\n * `StorageManager` symbol from a split bundle chunk can yield a second\n * class copy with its own statics, split-braining the caches\n * (resolveQuestion clears copy A while readQuestions reads copy B).\n */\n get storageManagerClass(): typeof StorageManager {\n return this.constructor as typeof StorageManager;\n }\n\n /** The root directory of this storage instance. */\n /** MemoryReadStore (storage.ts decomposition). Lazy; selfDeps live wiring. */\n private _memoryReadStore: MemoryReadStore | undefined;\n\n private get memoryReadStore(): MemoryReadStore {\n if (!this._memoryReadStore) {\n this._memoryReadStore = new MemoryReadStore(selfDeps<ConstructorParameters<typeof MemoryReadStore>[0]>(this));\n }\n return this._memoryReadStore;\n }\n\n /** EntityStore (storage.ts decomposition). Lazy; selfDeps live wiring. */\n private _entityStore: EntityStore | undefined;\n\n private get entityStore(): EntityStore {\n if (!this._entityStore) {\n this._entityStore = new EntityStore(selfDeps<ConstructorParameters<typeof EntityStore>[0]>(this));\n }\n return this._entityStore;\n }\n\n /** IdentityContinuityStore (storage.ts decomposition). Lazy; selfDeps live wiring. */\n private _identityContinuityStore: IdentityContinuityStore | undefined;\n\n private get identityContinuityStore(): IdentityContinuityStore {\n if (!this._identityContinuityStore) {\n this._identityContinuityStore = new IdentityContinuityStore(\n selfDeps<ConstructorParameters<typeof IdentityContinuityStore>[0]>(this)\n );\n }\n return this._identityContinuityStore;\n }\n\n get dir(): string {\n return this.baseDir;\n }\n\n private identityFilePath(workspaceDir: string, namespace?: string): string {\n const rawNamespace = typeof namespace === \"string\" ? namespace.trim() : \"\";\n if (!rawNamespace) return path.join(workspaceDir, \"IDENTITY.md\");\n const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n return path.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);\n }\n\n private versionFilePath(kind: SharedVersionKind): string {\n return path.join(this.stateDir, `.${kind}-version.log`);\n }\n\n private bumpSharedVersion(kind: SharedVersionKind, fallbackMap: Map<string, number>): number {\n const filePath = this.versionFilePath(kind);\n try {\n mkdirSync(this.stateDir, { recursive: true });\n appendFileSync(filePath, \"x\");\n const next = statSync(filePath).size;\n fallbackMap.set(this.baseDir, next);\n return next;\n } catch {\n const next = (fallbackMap.get(this.baseDir) ?? 0) + 1;\n fallbackMap.set(this.baseDir, next);\n return next;\n }\n }\n\n private readSharedVersion(kind: SharedVersionKind, fallbackMap: Map<string, number>): number {\n const filePath = this.versionFilePath(kind);\n try {\n return statSync(filePath).size;\n } catch {\n return fallbackMap.get(this.baseDir) ?? 0;\n }\n }\n\n protected bumpMemoryStatusVersion(): void {\n this.bumpSharedVersion(\"memory-status\", StorageManager.memoryStatusVersionByDir);\n // Corpus sentinel too: peer processes rescan the hot-memories cache\n // after status/lifecycle/bulk mutations (#1902); invalidateAllForDir\n // below drops the hot layer locally.\n this.bumpSharedVersion(\"memory-corpus\", StorageManager.memoryCorpusVersionByDir);\n // Invalidation chokepoint (#1535): several status/entity mutations\n // (supersede, archiveMemories, writeEntity, commitment cleanup) never\n // call invalidateAllMemoriesCache; the TTL-based QMD caches need this\n // eager clear.\n invalidateAllForDir(this.baseDir);\n }\n\n getMemoryStatusVersion(): number {\n return this.readSharedVersion(\"memory-status\", StorageManager.memoryStatusVersionByDir);\n }\n\n /**\n * Entity content revision used by migration discovery and entity-page cache coherence.\n */\n getEntityMutationVersion(): number {\n return this.readSharedVersion(\"entity-mutation\", StorageManager.entityMutationVersionByDir);\n }\n\n protected bumpEntityMutationVersion(): void {\n invalidateForScope(this.baseDir, \"entity-write\");\n this.bumpSharedVersion(\"entity-mutation\", StorageManager.entityMutationVersionByDir);\n }\n\n /**\n * Corpus version sentinel for the hot-memories result cache (#1902).\n * Distinct from memory-status: bumps on EVERY memory-file mutation so the\n * version-keyed hot cache stays coherent across processes, WITHOUT\n * invalidating the version-keyed entity cache on every plain fact create.\n */\n getMemoryCorpusVersion(): number {\n return this.readSharedVersion(\"memory-corpus\", StorageManager.memoryCorpusVersionByDir);\n }\n\n /**\n * Bump only — NOT invalidateAllForDir (that would drop the very hot\n * entry the write path just patched).\n */\n protected bumpMemoryCorpusVersion(): void {\n this.bumpSharedVersion(\"memory-corpus\", StorageManager.memoryCorpusVersionByDir);\n // Drop the in-flight readAllMemories slot (#1902): a concurrent read\n // must not attach to a scan that began BEFORE this mutation. (The patch\n // path uses bumpMemoryCorpusVersionExclusive and clears the slot itself.)\n deleteInFlightReadsForDir(this.baseDir);\n }\n getArchiveMutationVersion(): number { return archive.getArchiveMutationVersionForDir(this.baseDir); }\n\n /**\n * Corpus bump reporting whether THIS process's append was the only one\n * since the pre-bump size (#1902, Codex P1): the `exclusive` flag lets\n * patchHotMemoriesCache refuse to re-key its locally patched corpus at a\n * version already reflecting a peer's still-unread concurrent append.\n */\n private bumpMemoryCorpusVersionExclusive(): { produced: number; exclusive: boolean } {\n const filePath = this.versionFilePath(\"memory-corpus\");\n try {\n mkdirSync(this.stateDir, { recursive: true });\n let before = 0;\n try {\n before = statSync(filePath).size;\n } catch {\n before = 0;\n }\n appendFileSync(filePath, \"x\");\n const produced = statSync(filePath).size;\n StorageManager.memoryCorpusVersionByDir.set(this.baseDir, produced);\n // Exclusive iff exactly our single byte landed between the two stats.\n return { produced, exclusive: produced === before + 1 };\n } catch {\n const next = (StorageManager.memoryCorpusVersionByDir.get(this.baseDir) ?? 0) + 1;\n StorageManager.memoryCorpusVersionByDir.set(this.baseDir, next);\n return { produced: next, exclusive: true };\n }\n }\n\n protected bumpArtifactWriteVersion(): number {\n return this.bumpSharedVersion(\"artifact-write\", StorageManager.artifactWriteVersionByDir);\n }\n\n private getArtifactWriteVersion(): number {\n return this.readSharedVersion(\"artifact-write\", StorageManager.artifactWriteVersionByDir);\n }\n\n // -------------------------------------------------------------------------\n // Wearable day transcripts\n //\n // Stored under `<baseDir>/wearables/<source>/<YYYY-MM-DD>.md` — outside\n // the memory scan roots (never surfaces as a memory) but inside the QMD\n // collection root (full-text searchable). IO lives here so transcripts\n // inherit the same encrypted-at-rest + atomic-write semantics as\n // memories.\n // -------------------------------------------------------------------------\n\n private get wearablesDir(): string {\n return path.join(this.baseDir, WEARABLES_DIR_NAME);\n }\n\n /**\n * Resolve the on-disk path for a source/day transcript. Throws on\n * malformed inputs — source ids and dates reach this from CLI/MCP/HTTP\n * surfaces and must never become path traversal.\n */\n wearableTranscriptPath(sourceId: string, date: string): string {\n if (typeof sourceId !== \"string\" || !/^[a-z][a-z0-9-]{0,63}$/.test(sourceId)) {\n throw new Error(\n `invalid wearable source id '${String(sourceId)}' — expected lowercase letters, digits, and dashes`\n );\n }\n if (!isValidTranscriptDate(date)) {\n throw new Error(`invalid wearable transcript date '${String(date)}' — expected YYYY-MM-DD`);\n }\n return path.join(this.wearablesDir, sourceId, `${date}.md`);\n }\n\n async writeWearableDayTranscript(sourceId: string, date: string, serialized: string): Promise<void> {\n const targetPath = this.wearableTranscriptPath(sourceId, date);\n // writeMaybeEncryptedFile handles mkdir + atomic temp→rename.\n await this.writeStorageSecureFile(targetPath, serialized);\n }\n\n /** Read a stored day transcript; null when the day has no file. */\n async readWearableDayTranscript(sourceId: string, date: string): Promise<string | null> {\n const targetPath = this.wearableTranscriptPath(sourceId, date);\n try {\n return await readMaybeEncryptedFile(targetPath, this._secureStoreKey, this.baseDir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw err;\n }\n }\n\n async listWearableTranscriptDays(sourceId?: string): Promise<Array<{ source: string; date: string }>> {\n return this.memoryReadStore.listWearableTranscriptDays(sourceId);\n }\n\n private _fusionStore?: FusionArtifactStore;\n\n /** Derived fusion-day IO; file IO lives in wearables/fusion (#1810). */\n fusionArtifactStore(): FusionArtifactStore {\n if (this._fusionStore) return this._fusionStore;\n return (this._fusionStore = new FusionArtifactStore(this.wearablesDir, this.baseDir, {\n writeFile: (p, c) => this.writeStorageSecureFile(p, c),\n readFile: (p) => readMaybeEncryptedFile(p, this._secureStoreKey, this.baseDir),\n readDir: (d) => readdir(d),\n deleteFile: (p) => unlink(p),\n realpath: (p) => realpath(p),\n lstat: (p) => lstat(p).then((st) => ({ isSymbolicLink: st.isSymbolicLink() })),\n }));\n }\n\n private _meetingRecordStore?: MeetingRecordStore;\n\n /**\n * Meeting record IO (issue #1900). Records live under `<baseDir>/meetings/`\n * — inside the QMD collection root (full-text searchable) but outside the\n * memory scan roots — and inherit the same encrypted-at-rest + atomic-write +\n * symlink-containment semantics as memories via the shared secure IO port.\n */\n meetingRecordStore(): MeetingRecordStore {\n if (this._meetingRecordStore) return this._meetingRecordStore;\n return (this._meetingRecordStore = new MeetingRecordStore(this.baseDir, {\n writeFile: (p, c) => this.writeStorageSecureFile(p, c),\n readFile: (p) => readMaybeEncryptedFile(p, this._secureStoreKey, this.baseDir),\n readDir: (d) => readdir(d),\n deleteFile: (p) => unlink(p),\n realpath: (p) => realpath(p),\n lstat: (p) => lstat(p).then((st) => ({ isSymbolicLink: st.isSymbolicLink() })),\n }));\n }\n\n /**\n * Locate a wearable-sourced memory by exact (trimmed) content,\n * ignoring the \"[Attributes: ...]\" suffix writeMemory appends for\n * structuredAttributes — callers pass the raw fact text. Used by the\n * smart trust pipeline to find an earlier borderline write when the\n * same fact re-extracts with stronger evidence.\n */\n async findWearableMemoryByContent(content: string): Promise<{ id: string; status: MemoryStatus | undefined } | null> {\n const needle = stripAttributesSuffix(content);\n const memories = await this.readAllMemories();\n for (const memory of memories) {\n if (\n typeof memory.frontmatter.source === \"string\" &&\n memory.frontmatter.source.startsWith(\"wearable:\") &&\n stripAttributesSuffix(memory.content) === needle\n ) {\n return { id: memory.frontmatter.id, status: memory.frontmatter.status };\n }\n }\n return null;\n }\n\n /**\n * Promote a pending_review wearable memory to active in place,\n * merging updated trust evidence into structuredAttributes. Returns\n * false when the memory is missing or no longer pending_review (a\n * concurrent review decision wins), or when the row is tombstone-blocked\n * (`blockedBy` — issue #1579 threads OcuDx/Ocu1l): writeMemoryFrontmatter\n * bypasses the writeMemory chokepoint, so a blocked row must first be\n * cleared via revokeTombstone before promotion can proceed.\n */\n async promoteWearableMemory(\n id: string,\n attributeUpdates: Record<string, string>,\n confidence?: number\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((entry) => entry.frontmatter.id === id);\n if (!memory) return false;\n if (memory.frontmatter.status !== \"pending_review\") return false;\n // Tombstone-blocked rows need revokeTombstone first (issue #1579 OcuDx/Ocu1l).\n if (memory.frontmatter.blockedBy) return false;\n return this.writeMemoryFrontmatter(memory, {\n status: \"active\",\n // Keep frontmatter confidence in step with the re-scored trust —\n // new smart writes persist trust as confidence, and a promoted\n // row must not keep its stale borderline value.\n ...(typeof confidence === \"number\" && Number.isFinite(confidence)\n ? { confidence: Math.min(1, Math.max(0, confidence)) }\n : {}),\n structuredAttributes: {\n ...(memory.frontmatter.structuredAttributes ?? {}),\n ...attributeUpdates,\n },\n });\n }\n\n /**\n * Demote a pending_review wearable memory to rejected when a re-pass\n * produced an explicit judge-reject verdict, merging the evidence.\n * Returns false when the memory is missing or no longer\n * pending_review — active rows are NEVER auto-demoted (operator\n * approvals and accrued recall signals win; contradiction scans and\n * supersession own active-row retirement).\n */\n async demoteWearableMemory(id: string, attributeUpdates: Record<string, string>): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((entry) => entry.frontmatter.id === id);\n if (!memory) return false;\n if (memory.frontmatter.status !== \"pending_review\") return false;\n return this.writeMemoryFrontmatter(memory, {\n status: \"rejected\",\n structuredAttributes: {\n ...(memory.frontmatter.structuredAttributes ?? {}),\n ...attributeUpdates,\n },\n });\n }\n\n private get factsDir(): string {\n return path.join(this.baseDir, \"facts\");\n }\n private get correctionsDir(): string {\n return path.join(this.baseDir, \"corrections\");\n }\n private get proceduresDir(): string {\n return path.join(this.baseDir, \"procedures\");\n }\n private get reasoningTracesDir(): string {\n return path.join(this.baseDir, \"reasoning-traces\");\n }\n private get entitiesDir(): string {\n return path.join(this.baseDir, \"entities\");\n }\n private resolveEntityFilePath(name: string): string | null {\n if (typeof name !== \"string\") return null;\n const filePath = path.resolve(this.entitiesDir, `${name}.md`);\n const relative = path.relative(this.entitiesDir, filePath);\n if (relative === \"\" || relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n return null;\n }\n return filePath;\n }\n private readStorageSecureFile(filePath: string): Promise<string> {\n return readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);\n }\n async readDependencyPropagationQueueFile(filePath: string): Promise<string> {\n const target = await resolveSafeStoragePath(\n this.baseDir,\n path.relative(\n this.baseDir,\n this.assertManagedStoragePath(filePath, \"storage.readDependencyPropagationQueueFile\"),\n ),\n );\n return this.readStorageSecureFile(target);\n }\n async writeDependencyPropagationQueueFile(filePath: string, content: string): Promise<void> {\n const target = await resolveSafeStoragePath(\n this.baseDir,\n path.relative(\n this.baseDir,\n this.assertManagedStoragePath(filePath, \"storage.writeDependencyPropagationQueueFile\"),\n ),\n );\n return this.writeStorageSecureFile(target, content);\n }\n protected writeStorageSecureFile(filePath: string, content: string | Buffer, forceEncrypt = false): Promise<void> {\n assertNotOkfReservedBasename(filePath);\n const writeKey = this.resolveWriteKey(forceEncrypt);\n return writeMaybeEncryptedFile(filePath, content, writeKey, {}, this.baseDir).then(() => {\n // No manual sniff-cache update needed (issue #1909 round 10): this rewrite\n // changes the file's (size, mtime), so isEncryptedFileHeader re-sniffs on\n // the next append when its identity check misses. Identity validation also\n // covers PEER rewrites that this hook never sees.\n this.notifyCatalogWriteForPath(filePath);\n });\n }\n\n protected assertManagedStoragePath(filePath: string, method: string): string {\n const resolved = path.resolve(filePath);\n const base = path.resolve(this.baseDir);\n const rel = path.relative(base, resolved);\n if (rel === \"\" || rel === \"..\" || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)) {\n throw new Error(`${method}: file path escapes memory dir`);\n }\n return resolved;\n }\n async readDeletionRevisions(): Promise<ReadonlyMap<string, number>> {\n return this.deletionRevisionStore.readDeletionRevisions();\n }\n async hasCommittedInvalidation(\n memory: Pick<MemoryFile, \"content\" | \"frontmatter\">,\n ): Promise<boolean> {\n return this.deletionRevisionStore.hasCommittedInvalidation(memory);\n }\n private async recordCommittedInvalidation(memory: MemoryFile): Promise<void> {\n return this.deletionRevisionStore.recordCommittedInvalidation(memory);\n }\n private async clearCommittedInvalidation(\n memory: Pick<MemoryFile, \"content\" | \"frontmatter\">,\n ): Promise<void> {\n return this.deletionRevisionStore.clearCommittedInvalidation(memory);\n }\n async recordReplicatedDeletionRevision(filePath: string, mtimeMs: number): Promise<void> {\n return this.deletionRevisionStore.recordReplicatedDeletionRevision(filePath, mtimeMs);\n }\n protected async writeManagedStorageFile(filePath: string, write: () => Promise<void>): Promise<void> {\n return this.deletionRevisionStore.writeManagedStorageFile(filePath, write);\n }\n protected async deleteManagedStorageFile(filePath: string, deletionMtimeMs?: number | null): Promise<boolean> {\n return this.deletionRevisionStore.deleteManagedStorageFile(filePath, deletionMtimeMs);\n }\n\n async readOfflineSyncFile(filePath: string): Promise<Buffer> {\n const target = this.assertManagedStoragePath(filePath, \"storage.readOfflineSyncFile\");\n return readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);\n }\n\n async digestOfflineSyncFile(filePath: string): Promise<{ sha256: string; bytes: number }> {\n const target = this.assertManagedStoragePath(filePath, \"storage.digestOfflineSyncFile\");\n const st = await stat(target);\n const relPath = path.relative(this.baseDir, target).split(path.sep).join(\"/\");\n const cache = await this.loadOfflineSyncDigestCache();\n const cached = cache.get(relPath);\n if (\n cached &&\n cached.statBytes === st.size &&\n cached.mtimeMs === st.mtimeMs &&\n cached.ctimeMs === st.ctimeMs &&\n !cached.encrypted\n ) {\n return {\n sha256: cached.sha256,\n bytes: cached.bytes,\n };\n }\n\n const encrypted = await this.offlineSyncFileIsEncrypted(target);\n let digest: { sha256: string; bytes: number };\n if (encrypted) {\n const content = await readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);\n digest = {\n sha256: createHash(\"sha256\").update(content).digest(\"hex\"),\n bytes: content.byteLength,\n };\n } else {\n const hash = createHash(\"sha256\");\n let bytes = 0;\n for await (const rawChunk of createReadStream(target)) {\n const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);\n hash.update(chunk);\n bytes += chunk.length;\n }\n digest = {\n sha256: hash.digest(\"hex\"),\n bytes,\n };\n }\n if (!encrypted) {\n this.rememberOfflineSyncDigest(relPath, st, digest);\n }\n return digest;\n }\n\n private async loadOfflineSyncDigestCache(): Promise<Map<string, OfflineSyncDigestCacheEntry>> {\n if (this.offlineSyncDigestCache) return this.offlineSyncDigestCache;\n if (!this.offlineSyncDigestCacheLoadPromise) {\n this.offlineSyncDigestCacheLoadPromise = this.readOfflineSyncDigestCache();\n }\n this.offlineSyncDigestCache = await this.offlineSyncDigestCacheLoadPromise;\n return this.offlineSyncDigestCache;\n }\n\n private async readOfflineSyncDigestCache(): Promise<Map<string, OfflineSyncDigestCacheEntry>> {\n const cache = new Map<string, OfflineSyncDigestCacheEntry>();\n try {\n const raw = await readFile(this.offlineSyncDigestCachePath, \"utf-8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return cache;\n const entries = (parsed as { entries?: unknown }).entries;\n if (!Array.isArray(entries)) return cache;\n for (const entry of entries) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) continue;\n const record = entry as Record<string, unknown>;\n const cachePath = typeof record.path === \"string\" ? record.path : \"\";\n const statBytes = typeof record.statBytes === \"number\" ? record.statBytes : NaN;\n const mtimeMs = typeof record.mtimeMs === \"number\" ? record.mtimeMs : NaN;\n const ctimeMs = typeof record.ctimeMs === \"number\" ? record.ctimeMs : NaN;\n const bytes = typeof record.bytes === \"number\" ? record.bytes : NaN;\n const sha256 = typeof record.sha256 === \"string\" ? record.sha256 : \"\";\n const encrypted = record.encrypted === true;\n if (\n cachePath.length === 0 ||\n cachePath === \"..\" ||\n cachePath.startsWith(\"../\") ||\n path.isAbsolute(cachePath) ||\n !Number.isFinite(statBytes) ||\n !Number.isFinite(mtimeMs) ||\n !Number.isFinite(ctimeMs) ||\n !Number.isFinite(bytes) ||\n !/^[a-f0-9]{64}$/i.test(sha256)\n ) {\n continue;\n }\n cache.set(cachePath, { statBytes, mtimeMs, ctimeMs, encrypted, sha256, bytes });\n }\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) {\n log.warn(\n `storage.offlineSyncDigestCache: ignoring unreadable cache: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n return cache;\n }\n\n private rememberOfflineSyncDigest(\n relPath: string,\n st: { size: number; mtimeMs: number; ctimeMs: number },\n digest: { sha256: string; bytes: number }\n ): void {\n const cache = this.offlineSyncDigestCache;\n if (!cache) return;\n cache.set(relPath, {\n statBytes: st.size,\n mtimeMs: st.mtimeMs,\n ctimeMs: st.ctimeMs,\n encrypted: false,\n sha256: digest.sha256,\n bytes: digest.bytes,\n });\n this.scheduleOfflineSyncDigestCacheWrite();\n }\n\n private scheduleOfflineSyncDigestCacheWrite(): void {\n if (this.offlineSyncDigestCacheWriteTimer) {\n clearTimeout(this.offlineSyncDigestCacheWriteTimer);\n }\n this.offlineSyncDigestCacheWriteTimer = setTimeout(() => {\n this.offlineSyncDigestCacheWriteTimer = null;\n this.queueOfflineSyncDigestCacheWrite();\n }, 1_000);\n this.offlineSyncDigestCacheWriteTimer.unref?.();\n }\n\n private queueOfflineSyncDigestCacheWrite(): void {\n this.offlineSyncDigestCacheWriteChain = this.offlineSyncDigestCacheWriteChain\n .catch(() => undefined)\n .then(async () => {\n const cache = this.offlineSyncDigestCache;\n if (!cache) return;\n const entries = [...cache.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([entryPath, entry]) => ({ path: entryPath, ...entry }));\n await mkdir(path.dirname(this.offlineSyncDigestCachePath), { recursive: true });\n await writeFile(this.offlineSyncDigestCachePath, `${JSON.stringify({ version: 1, entries })}\\n`, \"utf-8\");\n })\n .catch((err) => {\n log.warn(\n `storage.offlineSyncDigestCache: failed to write cache: ${err instanceof Error ? err.message : String(err)}`\n );\n });\n }\n\n private async offlineSyncFileIsEncrypted(filePath: string): Promise<boolean> {\n const handle = await open(filePath, \"r\");\n try {\n const header = Buffer.alloc(MAGIC_HEADER_SIZE);\n const { bytesRead } = await handle.read(header, 0, header.length, 0);\n return bytesRead >= MAGIC_HEADER_SIZE && isEncryptedFile(header);\n } finally {\n await handle.close();\n }\n }\n\n async writeOfflineSyncStagingFile(filePath: string, content: Buffer): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.writeOfflineSyncStagingFile\");\n await this.writeStorageSecureFile(target, content);\n }\n\n createContentHashIndex(): ContentHashIndex {\n return new ContentHashIndex(\n this.stateDir,\n () => this._secureStoreKey,\n () => this.resolveWriteKey(),\n this.baseDir,\n this.factHashIndexLockOptions\n );\n }\n\n private async appendStorageSecureFile(filePath: string, content: string): Promise<void> {\n const previous = this.secureAppendChains.get(filePath) ?? Promise.resolve();\n const current = previous.catch(() => undefined).then(() => this.appendStorageSecureFileUnlocked(filePath, content));\n const next = current.catch(() => undefined);\n this.secureAppendChains.set(filePath, next);\n try {\n await current;\n } finally {\n if (this.secureAppendChains.get(filePath) === next) {\n this.secureAppendChains.delete(filePath);\n }\n }\n }\n\n /**\n * Classify a file as encrypted by reading ONLY the fixed-size magic header\n * (issue #1909), never the whole file. The result is cached per-path but\n * VALIDATED against the file's (size, mtime) identity (review round 10 finding\n * 1): a `stat` on each call is O(1), and the 12-byte header read happens only\n * on a cache miss or when the on-disk identity changed — so a PEER process\n * rewriting/encrypting the file is detected and we never append raw bytes into\n * an encrypted body. ENOENT and short/empty files classify as not-encrypted\n * (fall through to a plain `appendFile`).\n */\n private async isEncryptedFileHeader(filePath: string): Promise<boolean> {\n let st;\n try {\n st = await stat(filePath);\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return false;\n throw err;\n }\n const cached = this.secureFileEncryptionSniffCache.get(filePath);\n if (cached && cached.identity.size === st.size && cached.identity.mtimeMs === st.mtimeMs) {\n return cached.encrypted;\n }\n let handle;\n try {\n handle = await open(filePath, \"r\");\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return false;\n throw err;\n }\n try {\n const header = Buffer.alloc(MAGIC_HEADER_SIZE);\n const { bytesRead } = await handle.read(header, 0, header.length, 0);\n const encrypted = isEncryptedFile(header.subarray(0, bytesRead));\n this.secureFileEncryptionSniffCache.set(filePath, {\n identity: { size: st.size, mtimeMs: st.mtimeMs },\n encrypted,\n });\n return encrypted;\n } finally {\n await handle.close().catch(() => undefined);\n }\n }\n\n private async appendStorageSecureFileUnlocked(filePath: string, content: string): Promise<void> {\n const writeKey = this.resolveWriteKey();\n await mkdir(path.dirname(filePath), { recursive: true });\n if (writeKey === null) {\n try {\n // Header-only sniff (issue #1909): reads at most MAGIC_HEADER_SIZE bytes\n // instead of the whole target file (a lifecycle ledger can grow to\n // hundreds of MB on a large corpus) to decide \"is this encrypted?\". A\n // plaintext append below cannot flip the classification, so a cached\n // `false` stays valid across appends.\n if (await this.isEncryptedFileHeader(filePath)) {\n const existing = await this.readStorageSecureFile(filePath);\n await writeMaybeEncryptedFile(filePath, `${existing}${content}`, null, {}, this.baseDir);\n this.notifyCatalogWriteForPath(filePath);\n return;\n }\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n }\n // Plaintext append does not touch the header. isEncryptedFileHeader is now\n // (size, mtime)-identity-validated (issue #1909 round 10), so a PEER\n // process that encrypted this file since our last sniff is detected on the\n // stat above and re-sniffed — we will NOT append raw bytes into an\n // encrypted body. A residual sub-call TOCTOU (a peer encrypts between this\n // stat and the appendFile below) is inherent to any check-then-act and is\n // out of scope; the identity check closes the long-lived stale-cache hole.\n await appendFile(filePath, content, \"utf-8\");\n this.notifyCatalogWriteForPath(filePath);\n return;\n }\n\n // Encrypted-store branch (issue #1909, known limitation): the sealed format\n // has no append primitive, so this inherently decrypts + concatenates +\n // rewrites the whole file. Only the plaintext-path sniff read was wasteful.\n let existing = \"\";\n try {\n existing = await this.readStorageSecureFile(filePath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n }\n await writeMaybeEncryptedFile(filePath, `${existing}${content}`, writeKey, {}, this.baseDir);\n this.notifyCatalogWriteForPath(filePath);\n }\n private get stateDir(): string {\n return path.join(this.baseDir, \"state\");\n }\n private get offlineSyncDigestCachePath(): string {\n return path.join(this.baseDir, \".offline-sync\", \"digest-cache.v1.json\");\n }\n private get entitySynthesisQueuePath(): string {\n return path.join(this.stateDir, \"entity-synthesis-queue.json\");\n }\n // ── Tombstone store access (issue #1579) ─────────────────────────────────\n /**\n * The on-disk tombstone log path. Lives under `<stateDir>/tombstones.jsonl`\n * so it is co-located with the fact-hash index and encrypted at rest when\n * the secure-store is enabled (the StorageManager's secure read/write\n * helpers are injected into the store).\n */\n private get tombstonesPath(): string {\n return path.join(this.stateDir, \"tombstones.jsonl\");\n }\n\n /**\n * Configure the tombstone invariant for this storage instance. Installed\n * by the orchestrator after construction (same pattern as\n * `setVersioningConfig` / `citationTemplate`). When `enabled` is false\n * (default until the orchestrator wires config), the chokepoint check is a\n * no-op — pre-feature behavior for rollback safety (rule 30).\n */\n setTombstonesConfig(config: {\n enabled: boolean;\n semanticMatch: boolean;\n semanticThreshold: number;\n namespace: string;\n }): void {\n this.tombstonesConfig = { ...config };\n // Reset the store so the next access rebuilds with the new options.\n if (this.tombstoneStore) {\n this.tombstoneStore.invalidate();\n this.tombstoneStore = null;\n this.tombstoneStoreLoadPromise = null;\n }\n }\n\n private buildTombstoneStore(): TombstoneStore {\n const options: TombstoneStoreOptions = {\n enabled: this.tombstonesConfig.enabled,\n semanticMatch: this.tombstonesConfig.semanticMatch,\n semanticThreshold: this.tombstonesConfig.semanticThreshold,\n hashContent: ContentHashIndex.computeHash,\n normalizeText: ContentHashIndex.normalizeContent,\n // Corpus-path + source-content caches are scoped to one ledger revision\n // so a peer-appended legacy row is verified on the next staleness reload\n // (issue #2367). Implementation lives in storage/tombstone-migration-sources.ts.\n sourceContentsForMemoryIds: createTombstoneMigrationSourceContents({\n tombstonesPath: () => this.tombstonesPath,\n collectTombstoneMigrationPaths: () =>\n this.memoryReadStore.collectTombstoneMigrationPaths(),\n readParsedMemoriesFromPaths: (filePaths, batchSize) =>\n this.readParsedMemoriesFromPaths(filePaths, batchSize),\n storedContentIdentityCandidates: (content) =>\n this.storedContentIdentityCandidates(content),\n }),\n };\n const io: TombstoneFileIo = {\n read: (filePath) => this.readStorageSecureFile(filePath),\n append: (filePath, content) => this.appendStorageSecureFile(filePath, content),\n write: (filePath, content) => this.writeStorageSecureFile(filePath, content),\n stat: (filePath) => statSync(filePath),\n };\n return new TombstoneStore(this.tombstonesPath, this.tombstonesConfig.namespace, options, io);\n }\n\n /**\n * Lazily load the tombstone store. Mirrors the fact-hash-index lazy-load\n * pattern: a single in-flight load promise dedups concurrent first-access.\n * The cross-process staleness probe lives inside the store now (#1579): on\n * each cached access it stats its own file and invalidates if a peer process\n * appended, so the next lookup reloads from disk. If the probe just\n * invalidated the store, fall through to the reload branch — returning null\n * here was the original regression (the chokepoint threw and failed OPEN).\n */\n getTombstoneStore(): Promise<TombstoneStore> {\n if (this.tombstoneStore) {\n // The store owns the staleness probe + reload (#1579): on a cached hit it\n // stats its own file and, if a peer process appended, invalidates + reloads\n // in place. We await it so the chokepoint's lookup always sees a fresh index.\n const cached = this.tombstoneStore;\n return cached.ensureFreshAgainstDisk().then(() => cached);\n }\n if (!this.tombstoneStoreLoadPromise) {\n const store = this.buildTombstoneStore();\n this.tombstoneStoreLoadPromise = store\n .load()\n .then(() => {\n this.tombstoneStore = store;\n return store;\n })\n .catch((err) => {\n this.tombstoneStoreLoadPromise = null;\n throw err;\n });\n }\n return this.tombstoneStoreLoadPromise;\n }\n\n /**\n * Whether tombstones are enabled on this storage. Callers that need to\n * distinguish \"tombstones disabled\" (null return is expected) from\n * \"persistence failed\" (appendTombstone swallows store errors and also\n * returns null) use this to fail closed when enabled (#1580 review OgIqp).\n */\n isTombstonesEnabled(): boolean {\n return this.tombstonesConfig.enabled;\n }\n\n /**\n * Append a tombstone for a retired memory (issue #1579 emitters).\n * Best-effort: a tombstone append failure MUST NOT fail the supersession /\n * correction that triggered it (gotcha #13 / rule 34). The memory is\n * already retired on disk; the tombstone is the non-resurrection guard.\n */\n async appendTombstone(input: {\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n sourceMemoryId: string;\n rawContent: string;\n entityRef?: string;\n supersessionKey?: string;\n operationKey?: string;\n createdAt?: string;\n contentHash?: string;\n }): Promise<string | null> {\n if (!this.tombstonesConfig.enabled) return null;\n try {\n const store = await this.getTombstoneStore();\n // Chokepoint citation strip (#1579 review): both the exact-tier hash\n // and the normalized-text tier must match re-extraction, which hashes\n // the citation-stripped contentHashSource. Idempotent on pre-stripped\n // text (e.g. recordSupersession).\n const strippedRawContent = stripCitationForTemplate(input.rawContent, this.citationTemplate);\n // Canonicalization + post-append recheck (#2213) live in the helper.\n return await entityRefs.appendCanonicalizedTombstone(\n this.stateDir,\n input,\n () => this.currentHistoricalIds(),\n (identity) => store.appendTombstone({ ...input, rawContent: strippedRawContent, ...identity }),\n (tombstoneId) => store.revoke(tombstoneId, input.createdBy),\n input.sourceMemoryId\n );\n } catch (err) {\n log.warn(`tombstone append failed (memory=${input.sourceMemoryId}): ${err}`);\n return null;\n }\n }\n async hasExactTombstone(input: {\n sourceMemoryId: string;\n contentHash?: string;\n entityRef?: string;\n supersessionKey?: string;\n createdAt?: string;\n operationKey?: string;\n }): Promise<boolean> {\n if (!this.tombstonesConfig.enabled) return false;\n try {\n const store = await this.getTombstoneStore();\n return await store.hasExactEntry(input);\n } catch (err) {\n log.warn(`exact tombstone proof failed (memory=${input.sourceMemoryId}): ${err}`);\n return false;\n }\n }\n\n /**\n * Revoke a tombstone (re-allow the content). Used by the review-queue\n * approval path when an operator approves a blocked memory.\n */\n async revokeTombstone(tombstoneId: string, createdBy: TombstoneCreatedBy): Promise<string | null> {\n if (!this.tombstonesConfig.enabled) return null;\n try {\n const store = await this.getTombstoneStore();\n return await store.revoke(tombstoneId, createdBy);\n } catch (err) {\n log.warn(`tombstone revoke failed (id=${tombstoneId}): ${err}`);\n return null;\n }\n }\n\n /** Aggregate tombstone stats for `remnic doctor`. */\n async getTombstoneStats(): Promise<TombstoneStats | null> {\n if (!this.tombstonesConfig.enabled) return null;\n try {\n const store = await this.getTombstoneStore();\n return store.stats();\n } catch (err) {\n log.warn(`tombstone stats failed: ${err}`);\n return null;\n }\n }\n\n /**\n * Rebuild the tombstone log from retired memories on disk. Exposed for\n * `remnic doctor --rebuild-tombstones` and tests.\n */\n async rebuildTombstonesFromFiles(): Promise<number> {\n if (!this.tombstonesConfig.enabled) return 0;\n const store = await this.getTombstoneStore();\n const all = [...(await this.readAllMemories()), ...(await this.readAllColdMemories())];\n // Pure projection (lifecycle/tombstones.ts) keeps this method thin (#1520).\n const retired = collectRetiredMemoriesForRebuild(all, {\n stripCitation: (text) => stripCitationForTemplate(text, this.citationTemplate),\n supersessionKeysForFact,\n });\n return await store.rebuild(retired);\n }\n protected markFactHashIndexNotAuthoritative(): void {\n this.factHashIndexAuthoritative = false;\n }\n protected tombstoneBlockedCaptureIndexOptions(): TombstoneBlockedCaptureIndexOptions {\n return {\n stateDir: this.stateDir,\n memoryDir: this.baseDir,\n secureStoreKeyProvider: () => this._secureStoreKey,\n secureStoreWriteKeyProvider: () => this.resolveWriteKey(),\n lockOptions: () => this.factHashIndexLockOptions,\n parseMemory: (filePath, content) =>\n parseTombstoneBlockedOfflineSyncMemory(\n filePath,\n content,\n this.baseDir,\n parseFrontmatter,\n normalizeFrontmatterForPath,\n toMemoryPathRel\n ),\n readAllMemories: () => this.readAllMemories(),\n readAllColdMemories: () => this.readAllColdMemories(),\n };\n }\n private async getFactHashIndex(): Promise<ContentHashIndex> {\n if (this.factHashIndex) {\n return this.factHashIndex;\n }\n if (!this.factHashIndexLoadPromise) {\n const index = this.createContentHashIndex();\n this.factHashIndexLoadPromise = index\n .load()\n .then(() => {\n this.factHashIndex = index;\n return index;\n })\n .catch((err) => {\n this.factHashIndexLoadPromise = null;\n throw err;\n });\n }\n return this.factHashIndexLoadPromise;\n }\n /**\n * Return the fact-hash index after ensuring it is authoritative — i.e. rebuilt\n * from the durable fact corpus (issue #1909 review round 12). This is the ONE\n * coherent dedup source: the orchestrator's dedup layer\n * (contentHashIndexForStorage) shares THIS instance instead of loading a raw,\n * possibly-stale fact-hashes.txt, so after a crash+restart the orchestrator's\n * hasContentHashDedup sees the same corpus-rebuilt hashes StorageManager does\n * and never re-creates a fact whose per-write flush was deferred and lost.\n */\n async getAuthoritativeFactHashIndex(): Promise<ContentHashIndex> {\n if (!(await this.ensureFactHashIndexAuthoritative())) {\n throw new FactHashIndexNotAuthoritativeError(this.stateDir);\n }\n return this.getFactHashIndex();\n }\n /**\n * Return the shared fact-hash index instance, corpus-rebuilt under the lock\n * when the lock is free. Unlike {@link getAuthoritativeFactHashIndex} this\n * NEVER throws on lock contention — it returns the shared instance (the loaded\n * snapshot when a locked rebuild could not run) so registration writes still\n * land in the one shared index and reconcile to disk. Callers that trust a\n * dedup MISS MUST also consult {@link isFactContentHashAuthoritative} and\n * confirm against the corpus when it is false (PR #2016).\n */\n async getSharedFactHashIndex(): Promise<ContentHashIndex> {\n await this.ensureFactHashIndexAuthoritative();\n return this.getFactHashIndex();\n }\n private async ensureFactHashIndexAuthoritative(): Promise<boolean> {\n if (this.factHashIndexAuthoritative === true) {\n // PR #2016 review: authority is NOT permanent. A peer process can advance\n // the durable fact-hash index after our rebuild, leaving our in-memory\n // snapshot stale but still flagged authoritative — so a dedup MISS is\n // wrongly trusted and a duplicate active memory is written. Gate the fast\n // path on a cheap one-stat freshness check: when the durable index file is\n // unchanged since our last sync we stay authoritative (hot path preserved);\n // when a peer advanced it (or freshness cannot be established) drop\n // authority and rebuild from the corpus below so the miss confirms against\n // ground truth.\n if (this.factHashIndex && (await this.factHashIndex.isDiskFingerprintCurrent())) {\n return true;\n }\n this.factHashIndexAuthoritative = null;\n }\n if (this.factHashIndexAuthoritativePromise) {\n return this.factHashIndexAuthoritativePromise;\n }\n this.factHashIndexAuthoritative = false;\n this.factHashIndexAuthoritativePromise = (async () => {\n // ALWAYS rebuild the index from the durable corpus on first use per\n // process, preserving the #2016 crash/restart invariant. Markerless\n // legacy indexes additionally require body-derived hashes because their\n // frontmatter.contentHash values may use the old normalizer.\n //\n // The scan and publish run under the SAME per-index cross-process lock\n // used by reconcile saves, so migration cannot overwrite a peer's newer\n // additions with an unlocked write.\n //\n // PR #2016 (findings 1-2): bounded-retry the LOCKED rebuild so transient\n // contention (a peer mid reconcile-save) clears within a short budget\n // instead of surrendering authority on the first miss. Each attempt uses\n // the same non-reentrant, bounded-wait file lock, so it can never deadlock\n // with a deferred reconcile-retry. On exhaustion the index is left\n // non-authoritative: getAuthoritativeFactHashIndex() fails explicitly and\n // hasFactContentHash()/isFactContentHashAuthoritative() fall back to the\n // durable corpus so a stale loaded snapshot never answers as current.\n const factHashIndex = await this.getFactHashIndex();\n const maxAttempts = this.factHashIndexLockOptions.retryMaxAttempts ?? FACT_HASH_INDEX_REBUILD_MAX_ATTEMPTS;\n const baseMs = this.factHashIndexLockOptions.retryBaseMs ?? FACT_HASH_INDEX_REBUILD_RETRY_BASE_MS;\n let published = false;\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n published = await factHashIndex.rebuildUnderLock(() =>\n this.rebuildFactHashIndexFromCorpus(factHashIndex)\n );\n if (published || attempt === maxAttempts - 1) break;\n const wait = Math.min(baseMs * 2 ** attempt, CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS);\n await new Promise<void>((resolve) => setTimeout(resolve, wait));\n }\n this.factHashIndexAuthoritative = published;\n if (!published) {\n log.warn(\n `ensureFactHashIndexAuthoritative: fact-hash index lock unavailable after ${maxAttempts} attempt(s); ` +\n `index left non-authoritative (reads verify against the durable corpus; next use retries the locked rebuild)`\n );\n }\n return published;\n })().finally(() => {\n this.factHashIndexAuthoritativePromise = null;\n });\n return this.factHashIndexAuthoritativePromise;\n }\n /**\n * Repopulate `factHashIndex` in memory from the durable HOT+COLD corpus. Runs\n * WHILE the per-index cross-process lock is held (see\n * ContentHashIndex.rebuildUnderLock, which publishes the rebuilt set); this\n * method itself never writes to disk.\n */\n private async rebuildFactHashIndexFromCorpus(factHashIndex: ContentHashIndex): Promise<void> {\n factHashIndex.clear();\n // Fact-ONLY membership is rebuilt in lockstep (PR #2016 / issue #2474):\n // hasFactContentHash reads the index's fact-only partition, never the\n // category-agnostic shared set, so an over-included non-fact body can\n // never satisfy a fact-hash check. `factHashIndex.clear()` above cleared\n // the partition too, and it repopulates in place below — a concurrent\n // in-process writeMemory that adds a fact hash during the corpus-read\n // awaits survives publication (PR #2016 thread SDzOT), exactly as the\n // shared index preserves by mutating its `hashes` set in place.\n // #1909 review round 14: index the HOT and COLD tiers together. A fact or\n // procedure demoted to cold/ is still active and its content-hash must\n // survive the corpus rebuild, or a restart would drop the hash and let the\n // next extraction re-create the demoted memory. Matches the hot+cold union\n // that removeFactContentHashesForMemories already reconciles against.\n const existing = [...(await this.readAllMemories()), ...(await this.readAllColdMemories())];\n let legacyRecovered = 0;\n for (const memory of existing) {\n // #1909 review round 15 (PR #2016): the content-hash dedup index is\n // SHARED across EVERY registered write category. persistExtraction calls\n // addContentHashDedup for every writeCategory it persists — fact,\n // procedure, preference, decision, commitment, correction, and any other\n // extracted category — into THIS one index. A rebuild restricted to\n // fact+procedure dropped every other category's hash on restart, so the\n // next extraction re-created identical active preference/decision/\n // commitment memories (the retired fact-hashes.txt load used to preserve\n // them). Index every active memory regardless of category so the corpus\n // rebuild covers the full registration surface. Over-inclusion is safe:\n // the dedup consumers (hasContentHashDedup in persistExtraction, the\n // explicit-capture negative pre-filter) confirm a hash hit with a\n // same-category corpus scan before dropping anything, so a surplus hash\n // only costs a scan — it can never wrongly suppress a write. Procedures\n // keep their round-13 behaviour: they carry no frontmatter contentHash\n // (writeMemory sets it only for facts), so they fall through to the\n // citation-strip reconstruction below, hashing the stored persist body\n // (title + steps) exactly as buildProcedurePersistBody registered it.\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") continue;\n const hashes = this.corpusRegisteredHashes(memory);\n if (hashes.length === 0) {\n // Skip bodies whose configured citation cannot be stripped safely.\n legacyRecovered++;\n continue;\n }\n for (const hash of hashes) {\n if (memory.frontmatter.category === \"fact\") {\n factHashIndex.addFactByHash(hash);\n } else {\n factHashIndex.addByHash(hash);\n }\n }\n }\n if (legacyRecovered > 0) {\n log.info(\n `ensureFactHashIndexAuthoritative: skipped ${legacyRecovered} legacy memory(ies) with no contentHash in frontmatter`\n );\n }\n }\n private storedContentIdentityCandidates(content: string): string[] {\n return storedContentIdentityCandidates(content, (value) =>\n hasCitationForTemplate(value, this.citationTemplate) ? stripCitationForTemplate(value, this.citationTemplate) : value\n );\n }\n\n /** Returns the current body identity while preserving explicit external identities. */\n private corpusRegisteredHashes(memory: MemoryFile): string[] {\n const persistedHash = memory.frontmatter.contentHash;\n const candidates = this.storedContentIdentityCandidates(memory.content)\n .map((content) => sanitizeMemoryContent(content).text);\n const currentHashes = candidates.map((content) => ContentHashIndex.computeHash(content));\n if (persistedHash && currentHashes.includes(persistedHash)) return [persistedHash];\n if (!persistedHash) return [currentHashes[0] ?? ContentHashIndex.computeHash(\"\")];\n const legacyMatches = candidates.filter(\n (content) => computeLegacyContentHash(content) === persistedHash\n );\n return legacyMatches.length > 0\n ? [...new Set(legacyMatches.map((content) => ContentHashIndex.computeHash(content)))]\n : [persistedHash];\n }\n\n private get questionsDir(): string {\n return path.join(this.baseDir, \"questions\");\n }\n private get artifactsDir(): string {\n return path.join(this.baseDir, \"artifacts\");\n }\n private get identityDir(): string {\n return path.join(this.baseDir, \"identity\");\n }\n private get identityAnchorPath(): string {\n return path.join(this.identityDir, \"identity-anchor.md\");\n }\n private get identityIncidentsDir(): string {\n return path.join(this.identityDir, \"incidents\");\n }\n private get identityAuditsWeeklyDir(): string {\n return path.join(this.identityDir, \"audits\", \"weekly\");\n }\n private get identityAuditsMonthlyDir(): string {\n return path.join(this.identityDir, \"audits\", \"monthly\");\n }\n private get identityImprovementLoopsPath(): string {\n return path.join(this.identityDir, \"improvement-loops.md\");\n }\n private get identityReflectionsPath(): string {\n return path.join(this.identityDir, \"reflections.md\");\n }\n private get profilePath(): string {\n return path.join(this.baseDir, \"profile.md\");\n }\n private get memoryActionsPath(): string {\n return path.join(this.stateDir, \"memory-actions.jsonl\");\n }\n private get memoryLifecycleLedgerPath(): string {\n return path.join(this.stateDir, \"memory-lifecycle-ledger.jsonl\");\n }\n private get compressionGuidelinesPath(): string {\n return path.join(this.stateDir, \"compression-guidelines.md\");\n }\n private get compressionGuidelineDraftPath(): string {\n return path.join(this.stateDir, \"compression-guidelines.draft.md\");\n }\n private get compressionGuidelineStatePath(): string {\n return path.join(this.stateDir, \"compression-guideline-state.json\");\n }\n private get compressionGuidelineDraftStatePath(): string {\n return path.join(this.stateDir, \"compression-guideline-draft-state.json\");\n }\n private get behaviorSignalsPath(): string {\n return path.join(this.stateDir, \"behavior-signals.jsonl\");\n }\n /**\n * In-memory dedup key set for behavior-signals appends (issue #1909),\n * validated by (size, mtime) file identity like the catalog `compactedCache`.\n * Avoids re-reading + JSON.parsing the whole `behavior-signals.jsonl` on\n * every append. A foreign write changes size/mtime, forcing a reload; this\n * process's own appends refresh the identity in place. null => reload.\n */\n private behaviorSignalsKeyCache: { identity: { size: number; mtimeMs: number }; keys: Set<string> } | null = null;\n /**\n * Per-instance serializer for `appendBehaviorSignals` (issue #1909 review\n * round 3). The read→dedup→append→cache-commit transaction must run to\n * completion before the next append starts; otherwise two concurrent callers\n * each snapshot their own `existingKeys`, and the later one commits an\n * INCOMPLETE set under the final file identity, so a subsequent call\n * cache-hits a set missing the earlier batch and writes duplicate signals.\n * The `.catch` links keep the chain alive after a rejected append\n * (AGENTS.md #28).\n */\n private behaviorSignalsAppendChain: Promise<unknown> = Promise.resolve();\n /**\n * Buffer surprise telemetry ledger (issue #563 PR 3).\n *\n * Append-only JSONL of per-turn `BUFFER_SURPRISE` events emitted by\n * `SmartBuffer` when `bufferSurpriseTriggerEnabled` is on. Each row\n * captures the score, the threshold in force at the time, whether the\n * turn caused an extract_now upgrade, and the buffer size. Kept in\n * `state/` alongside the other append-only ledgers so cleanup and\n * governance sweeps can treat it uniformly.\n */\n private get bufferSurpriseLedgerPath(): string {\n return path.join(this.stateDir, \"buffer-surprise-ledger.jsonl\");\n }\n\n /**\n * Entity alias table loaded from THIS store's config/aliases.json.\n * Instance-scoped on purpose (issue #1534): multiple StorageManager\n * instances in one process (namespaces, hosted profiles, tenants) must\n * never share alias state — the previous module-level table let whichever\n * store loaded last rewrite every other store's canonical entity ids.\n */\n private userAliases: Record<string, string> = {};\n private readonly historicalEntityCanonicalIds = new entityRefs.HistoricalEntityCanonicalIdCache();\n private currentHistoricalIds(): Readonly<Record<string, string>> {\n return this.historicalEntityCanonicalIds.get(this.stateDir);\n }\n /** Post-persist repair subsystem (issue #2213) — storage/entity-ref-repair.ts. */\n private _entityRefRepair: EntityRefRepair | undefined;\n private get entityRefRepair(): EntityRefRepair {\n if (!this._entityRefRepair) {\n this._entityRefRepair = new EntityRefRepair({\n stateDir: this.stateDir,\n baseDir: this.baseDir,\n currentHistoricalIds: () => this.currentHistoricalIds(),\n serializeFrontmatter,\n writeTombstoneBlockedMemory: (pathname, fileContent, frontmatter, content) =>\n this.writeTombstoneBlockedMemory(pathname, fileContent, frontmatter, content),\n invalidateAllMemoriesCache: () => this.invalidateAllMemoriesCache(),\n getTombstoneStore: () => this.getTombstoneStore(),\n tombstonesEnabled: () => this.tombstonesConfig.enabled,\n tombstonesNamespace: () => this.tombstonesConfig.namespace,\n });\n }\n return this._entityRefRepair;\n }\n private readonly entityCanonicalIdMigration = new EntityCanonicalIdMigrationRunner(\n () => !(this._secureStoreRequired && !this.isSecureStoreUnlocked()),\n () => this.runLegacyEntityCanonicalIdMigration(),\n () => entityMigration.getFingerprint(this.baseDir, this.entitiesDir, () => String(this.getEntityMutationVersion()))\n );\n normalizeEntityName(raw: string, type: string): string {\n return entityRefs.resolveHistoricalEntityCanonicalId(\n this.entityStore.normalizeEntityName(raw, type),\n this.currentHistoricalIds()\n );\n }\n\n /**\n * Read-only view of this store's user alias table, for call sites that\n * normalize outside the manager (pass it to the free `normalizeEntityName`).\n */\n get entityAliases(): Readonly<Record<string, string>> {\n return this.userAliases;\n }\n\n /**\n * Reload user-defined entity aliases from config/aliases.json in the memory\n * store. File format: { \"variant\": \"canonical\", ... }. The constructor\n * already loads aliases, so this is only needed to pick up file changes\n * (e.g. orchestrator.initialize() re-running on a live instance).\n * Non-object payloads and non-string or empty alias values are ignored.\n */\n async loadAliases(): Promise<void> {\n this.loadAliasesSync();\n }\n\n private loadAliasesSync(): void {\n const aliasPath = path.join(this.baseDir, \"config\", \"aliases.json\");\n this.userAliases = {};\n const raw = readEntityAliasConfigSync(this.baseDir);\n if (raw === undefined) return;\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n log.debug(\"invalid config/aliases.json — using built-in aliases only\");\n return;\n }\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n const cleaned: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value === \"string\" && value.trim().length > 0) {\n assertSafeEntityId(value);\n cleaned[key] = value;\n }\n }\n this.userAliases = cleaned;\n log.debug(`loaded ${Object.keys(cleaned).length} entity aliases from ${aliasPath}`);\n } else {\n log.warn(`ignoring ${aliasPath}: payload must be a JSON object mapping variant → canonical strings`);\n }\n }\n private async runLegacyEntityCanonicalIdMigration(): Promise<string | undefined> {\n const completionFingerprint = await runLegacyEntityCanonicalIdMigration(\n this as unknown as EntityCanonicalIdMigrationHost,\n (content) => parseEntityFile(content, this.entitySchemas),\n (entity) => serializeEntityFile(entity, this.entitySchemas, this.okfConformanceEnabled()),\n createMemoryEntityRefSerializer(serializeFrontmatter)\n );\n return completionFingerprint;\n }\n\n async ensureDirectories(): Promise<void> {\n await mkdir(this.baseDir, { recursive: true });\n await entityMigration.validateRoots(this.baseDir, this.entitiesDir, this.stateDir, this.archiveDir);\n const today = new Date().toISOString().slice(0, 10);\n await mkdir(path.join(this.factsDir, today), { recursive: true });\n await mkdir(path.join(this.proceduresDir, today), { recursive: true });\n await mkdir(path.join(this.reasoningTracesDir, today), { recursive: true });\n await mkdir(this.correctionsDir, { recursive: true });\n await mkdir(this.entitiesDir, { recursive: true });\n await mkdir(this.stateDir, { recursive: true });\n await mkdir(this.questionsDir, { recursive: true });\n await mkdir(this.artifactsDir, { recursive: true });\n await mkdir(this.identityDir, { recursive: true });\n await mkdir(this.identityIncidentsDir, { recursive: true });\n await mkdir(this.identityAuditsWeeklyDir, { recursive: true });\n await mkdir(this.identityAuditsMonthlyDir, { recursive: true });\n await mkdir(path.join(this.baseDir, \"config\"), { recursive: true });\n await this.entityCanonicalIdMigration.ensure();\n // Activate the corpus sentinel at setup (issue #1902, Cursor Medium): an\n // existing corpus predating this feature has a size-0/absent sentinel, which\n // getCachedMemories treats as a miss — so a read-heavy workload would never\n // engage the hot cache until the first mutation bumped it. The daemon calls\n // ensureDirectories() at startup (orchestration/orchestrator-init.ts) before\n // serving recall reads, so seeding a nonzero version here makes the cache\n // engage from the first read. Fires once, only while the version is still 0.\n // Deliberately NOT done on the readAllMemories() path: a write-side-effect\n // during a read perturbs concurrent hot/cold reads in the tier-migration\n // cycle. Fail-open: a failed bump falls back to the in-process counter.\n if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === 0) {\n this.bumpMemoryCorpusVersion();\n }\n await this.entityCanonicalIdMigration.markDirectoriesInitialized();\n }\n\n /**\n * Resolve the on-disk write path for a memory of the given category, creating\n * the target directory. Category routing goes through the shared\n * `getCategoryDir()` chokepoint (utils/category-dir.ts → CATEGORY_DIR_MAP) so\n * decision/preference/moment/etc. outputs land in their dedicated dirs\n * (`decisions/`, `preferences/`, ...) instead of collapsing into `facts/`\n * (issue #1546; CLAUDE.md rule 39). `correction` keeps its historical flat\n * layout (no `<date>` subdir) as the corrections pipeline expects; every other\n * category — including `fact`/`entity`, which fall back to `facts/` — is dated\n * as `<dir>/<date>/`. Read/scan/reindex already iterate every category dir\n * (RECALL_FALLBACK_DIRS; QMD scans baseDir recursively), so writes stay found.\n */\n private async resolveCategoryWritePath(category: MemoryCategory, id: string, today: string): Promise<string> {\n if (category === \"correction\") {\n await mkdir(this.correctionsDir, { recursive: true });\n return path.join(this.correctionsDir, `${id}.md`);\n }\n const datedDir = path.join(getCategoryDir(this.baseDir, category), today);\n await mkdir(datedDir, { recursive: true });\n return path.join(datedDir, `${id}.md`);\n }\n\n private async findExistingTombstoneBlockedMemory(\n content: string,\n category: MemoryCategory,\n sourceConnector?: string\n ): Promise<MemoryFile | null> {\n const identity = buildExplicitCaptureDedupKey(content, category, sourceConnector);\n const memories = [...(await this.readAllMemories()), ...(await this.readAllColdMemories())];\n return (\n memories.find((memory) => {\n if (memory.frontmatter.status !== \"pending_review\" || !memory.frontmatter.blockedBy) return false;\n return (\n buildExplicitCaptureDedupKey(\n memory.content,\n memory.frontmatter.category,\n memory.frontmatter.sourceConnector\n ) === identity\n );\n }) ?? null\n );\n }\n\n /** Derive the inert OKF `type` at the serialization choke point when conformance is on\n * and the parsed frontmatter carried none (issue #1946). Never touches `category`. */\n private withOkfType(fm: MemoryFrontmatter): MemoryFrontmatter {\n if (this.okfConformanceEnabled() && fm.type === undefined) fm.type = okfTypeForMemory(fm);\n return fm;\n }\n async writeMemory(\n category: MemoryCategory,\n content: string,\n options: WriteMemoryOptions = {}\n ) {\n await this.ensureDirectories();\n const rawEntityRef = options.entityRef;\n let refIds = typeof options.entityRef === \"string\" ? this.currentHistoricalIds() : null;\n if (refIds) options = entityRefs.canonicalizeEntityRefOption(options, refIds);\n const now = new Date();\n const today = now.toISOString().slice(0, 10);\n const id = `${category}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const conf = options.confidence ?? 0.8;\n const tier = confidenceTier(conf);\n const validAt = normalizeMemoryWriteTimestamp(\"validAt\", options.validAt);\n const observedAt = normalizeMemoryWriteTimestamp(\"observedAt\", options.observedAt);\n\n // Auto-set TTL for speculative memories\n let expiresAt: string | undefined;\n if (typeof options.expiresAt === \"string\" && options.expiresAt.length > 0) {\n expiresAt = options.expiresAt;\n } else if (tier === \"speculative\") {\n const expiry = new Date(now.getTime() + SPECULATIVE_TTL_DAYS * 24 * 60 * 60 * 1000);\n expiresAt = expiry.toISOString();\n }\n\n const fm: MemoryFrontmatter = {\n id,\n category,\n created: now.toISOString(),\n updated: now.toISOString(),\n language: detectLanguageHint(content),\n source: options.source ?? \"extraction\",\n confidence: conf,\n confidenceTier: tier,\n tags: options.tags ?? [],\n entityRef: options.entityRef,\n supersedes: options.supersedes,\n expiresAt,\n lineage: options.lineage,\n importance: options.importance,\n links: options.links,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n artifactType: options.artifactType,\n sourceMemoryId: options.sourceMemoryId,\n sourceTurnId: options.sourceTurnId,\n memoryKind: options.memoryKind,\n valid_at: validAt,\n observedAt,\n eventTimeSource: options.eventTimeSource,\n invalid_at: normalizeMemoryWriteTimestamp(\"invalidAt\", options.invalidAt),\n structuredAttributes: options.structuredAttributes,\n };\n if (options.status !== undefined) {\n fm.status = options.status;\n }\n // Consolidation provenance (issue #561 PR 2). Fields are independent\n // at the storage layer:\n // - `derivedFrom: []` → coerced to undefined so we never emit the\n // invalid `derived_from: []` form the write validator rejects.\n // - `derivedVia` may stand alone: an orphan operator marker (e.g.\n // `derived_via: merge` with no `derived_from`) is the correct\n // serialization when page-versioning is disabled and snapshots\n // can't be captured. Downstream logic still needs to identify\n // the memory as a consolidation output. Review feedback: PR #624\n // codex / cursor threads.\n if (options.derivedFrom !== undefined && options.derivedFrom.length > 0) {\n fm.derived_from = options.derivedFrom;\n }\n if (options.derivedVia !== undefined) {\n fm.derived_via = options.derivedVia;\n }\n // Faithfulness gate frontmatter (issue #1576).\n if (options.faithfulness !== undefined) {\n fm.faithfulness = options.faithfulness;\n }\n // Claim-level provenance (issue #1575 PR 2). Wire through to frontmatter\n // so verified spans survive extraction → storage → memory_get end-to-end.\n if (options.sources !== undefined) {\n fm.sources = options.sources;\n }\n if (options.provenance !== undefined) {\n fm.provenance = options.provenance;\n }\n if (options.sourceConnector !== undefined) {\n fm.sourceConnector = options.sourceConnector;\n }\n if (options.origin !== undefined) fm.origin = parseOriginClass(options.origin);\n if (options.subject !== undefined) fm.subject = options.subject;\n // Assemble the persisted body (attribute-suffix enrichment + combined\n // sanitize) via the SHARED helper — the sealed-envelope composer uses the\n // same one, so the two write paths cannot diverge (issue #1989 PR2).\n const sanitized = assemblePersistedBody(content, options.structuredAttributes);\n if (!sanitized.clean) {\n log.warn(`memory content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n if (\n options.toolScoped ||\n withholdToolScopedFromSharedNamespace({\n content: sanitized.text,\n sourceConnector: options.sourceConnector,\n })\n ) {\n fm.toolScoped = true;\n }\n\n // Persist the raw-content dedup hash on the frontmatter so archive and\n // consolidation paths can remove the correct hash from ContentHashIndex\n // regardless of what citation format (if any) has been appended to the\n // stored body. Mirrors the logic in the fact-hash-index update below.\n let factHashSourceForTombstone: string | null = null;\n if (category === \"fact\") {\n const hashSource =\n options.contentHashSource !== undefined && options.contentHashSource.length > 0\n ? sanitizeMemoryContent(options.contentHashSource).text\n : sanitized.text;\n fm.contentHash = ContentHashIndex.computeHash(hashSource);\n factHashSourceForTombstone = hashSource;\n }\n\n // ── Non-resurrection chokepoint (issue #1579) ────────────────────────\n // A match persists the fact as pending_review + blockedBy — VISIBLE,\n // never a silent drop (rule 34) — and skips active dedup registration\n // (rule 44). Pre-gate revalidation (#2213): re-resolve from the caller's\n // ORIGINAL ref so the lookup and the persisted ref share one id space.\n if (refIds && typeof rawEntityRef === \"string\" && this.currentHistoricalIds() !== refIds) {\n refIds = this.currentHistoricalIds();\n fm.entityRef = entityRefs.resolveHistoricalEntityCanonicalId(rawEntityRef, refIds);\n }\n let tombstoneBlocked = false;\n let gateRef: string | undefined;\n let statusBeforeBlock: MemoryFrontmatter[\"status\"];\n // Re-run after journal moves that change the final entityRef.\n const applyTombstoneGate = async (): Promise<void> => {\n if (tombstoneBlocked) {\n if (fm.entityRef === gateRef) return;\n tombstoneBlocked = false;\n fm.status = statusBeforeBlock;\n delete fm.blockedBy;\n delete fm.tombstoneBlockTier;\n }\n if (category !== \"fact\" || factHashSourceForTombstone === null) return;\n const statusBefore = fm.status;\n const match = await this.entityRefRepair.gate(fm, sanitized.text, options.structuredAttributes);\n if (match) {\n gateRef = fm.entityRef;\n statusBeforeBlock = statusBefore;\n tombstoneBlocked = true;\n }\n };\n await applyTombstoneGate();\n\n const fileContent = `${serializeFrontmatter(this.withOkfType(fm))}\\n\\n${sanitized.text}\\n`;\n\n const filePath = await this.resolveCategoryWritePath(category, id, today);\n const persistFile = async (): Promise<MemoryFile | null> => {\n if (tombstoneBlocked) {\n const duplicate = await this.findExistingTombstoneBlockedMemory(sanitized.text, category, fm.sourceConnector);\n if (duplicate) return duplicate;\n }\n await this.snapshotBeforeWrite(filePath, \"write\");\n await this.writeTombstoneBlockedMemory(filePath, fileContent, fm, sanitized.text, async () => {\n this.invalidateAllMemoriesCache();\n });\n if (refIds && typeof rawEntityRef === \"string\") {\n const refBeforeRepair = fm.entityRef;\n try {\n await entityRefs.repairEntityRefAfterJournalMove({\n stateDir: this.stateDir,\n currentIds: () => this.currentHistoricalIds(),\n idsAtResolve: refIds,\n rawRef: rawEntityRef,\n frontmatter: fm,\n rewrite: async () => {\n await applyTombstoneGate();\n await this.writeTombstoneBlockedMemory(\n filePath,\n `${serializeFrontmatter(this.withOkfType(fm))}\\n\\n${sanitized.text}\\n`,\n fm,\n sanitized.text,\n async () => this.invalidateAllMemoriesCache()\n );\n this.invalidateAllMemoriesCache();\n },\n });\n } catch (err) {\n await unlink(filePath).catch(() => undefined);\n this.invalidateAllMemoriesCache();\n await this.rebuildTombstoneBlockedCaptureAfterInvalidationForPath(filePath);\n throw err;\n }\n await this.entityRefRepair.syncProjection(id, refBeforeRepair, fm.entityRef);\n }\n return null;\n };\n const duplicateBlocked = await this.withTombstoneBlockedCaptureWriteLock(persistFile, [\n buildCapturePathLockIdentity(filePath),\n buildExplicitCaptureDedupKey(sanitized.text, category, fm.sourceConnector),\n ]);\n if (duplicateBlocked) {\n return {\n id: duplicateBlocked.frontmatter.id,\n tombstoneBlocked: true,\n blockedBy: duplicateBlocked.frontmatter.blockedBy,\n duplicateOf: duplicateBlocked.frontmatter.id,\n memory: duplicateBlocked,\n };\n }\n await this.patchHotMemoriesCache({ addedPath: filePath }, \"memory-create\");\n this.notifyMemoryWrite(filePath);\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.writeMemory\", {\n memoryId: id,\n eventType: \"created\",\n timestamp: fm.created,\n actor: options.actor ?? \"storage.writeMemory\",\n after: this.summarizeLifecycleState(fm, filePath),\n relatedMemoryIds: [\n ...(options.supersedes ? [options.supersedes] : []),\n ...(options.lineage ?? []).filter(Boolean),\n ],\n });\n if (category === \"fact\" && !tombstoneBlocked) {\n // Rule 44 (#1579): only active (un-blocked) facts enter the hash\n // index — a blocked entry would silently ban the content on the next\n // extraction.\n try {\n const factHashIndex = await this.getFactHashIndex();\n // Index the caller's contentHashSource (raw fact text before\n // citation annotation) when provided, so hasFactContentHash(rawFact)\n // matches subsequent extractions; else the sanitized persisted body.\n const hashText =\n options.contentHashSource !== undefined && options.contentHashSource.length > 0\n ? sanitizeMemoryContent(options.contentHashSource).text\n : sanitized.text;\n factHashIndex.addFact(hashText);\n // Gate only the flush (issue #1909): the `.add(...)` above already set\n // dirty=true. When the caller defers, it owns the batch save\n // (extraction persist -> saveContentHashIndexes()). Single-write callers\n // (explicit capture, import, wearable, native writes) flush immediately —\n // via the SAME cross-process locked reconcile the batch/append and\n // rebuild paths use (PR #2016 thread SDyCk), never the unlocked whole-file\n // save() that could clobber, or be clobbered by, a peer's concurrent\n // locked rebuild/reconcile and drop this durable fact from the index.\n if (!options.deferHashIndexSave) {\n await factHashIndex.saveMergingWithDisk();\n // A locked reconcile that times out defers to an unref'd background\n // retry and returns WITHOUT publishing (dirty retained). A single-write\n // caller must not observe that as durable (PR #2016 thread SD7Tk):\n // drain the deferred retry inline so the addition lands on disk (or\n // exhausts its bounded attempts, falling back to the corpus-rebuild\n // safety net) before writeMemory returns. No-op when the save already\n // published (not dirty).\n await factHashIndex.flushReconcileRetry();\n }\n } catch (err) {\n log.warn(`storage.writeMemory completed but failed to update fact hash index: ${err}`);\n }\n }\n log.debug(`wrote memory ${id} to ${filePath}`);\n return { id, tombstoneBlocked, ...(fm.blockedBy ? { blockedBy: fm.blockedBy } : {}), memory: { path: filePath, frontmatter: fm, content: sanitized.text } };\n }\n\n /**\n * Sealed-envelope write entry point (issue #1989 PR2).\n *\n * Byte-identity with `writeMemory` is BY DELEGATION: the envelope-owned\n * fields are unpacked into the exact `writeMemory` arguments a legacy\n * caller would have passed, so the persisted output is produced by the\n * same code path. The composer's `persistedBody` was assembled with the\n * same `assemblePersistedBody` helper `writeMemory` uses, so fingerprints\n * derived from the envelope match the stored body (§13).\n *\n * Differences from a raw `writeMemory` call are REJECTIONS, not silent\n * changes: the composer enforces tag/attribute caps, strict validAt, and\n * plain-object attributes that the legacy path never validated.\n *\n * `envelope.ttl` maps to `expiresAt` verbatim; converting duration\n * expressions (`\"90d\"`) to instants remains the access layer's job (PR3).\n * `envelope.sourceReason` is access-layer metadata with no frontmatter\n * field and is deliberately not persisted here.\n */\n async writeSealedMemory(envelope: SealedMemoryEnvelope, extras: SealedWriteExtras = {}) {\n if (!isSealedMemoryEnvelope(envelope)) {\n throw new Error(\n \"writeSealedMemory: value is not a valid sealed memory envelope (fails the composeMemoryEnvelope contract)\"\n );\n }\n const { category, content, options } = sealedWriteToLegacyArgs(envelope, extras);\n return this.writeMemory(category, content, options as WriteMemoryOptions);\n }\n\n async hasFactContentHash(content: string): Promise<boolean> {\n const authoritative = await this.ensureFactHashIndexAuthoritative();\n const sanitized = sanitizeMemoryContent(content);\n const hash = ContentHashIndex.computeHash(sanitized.text);\n // Fact-ONLY answer (PR #2016). The shared content-hash index is\n // category-agnostic — the round-15 authoritative rebuild indexes EVERY\n // active category and addContentHashDedup registers all of them — so it\n // cannot tell a FACT from an unrelated preference/decision/note/moment with\n // the same normalized body. Direct consumers\n // (createWearableMemoryWriter.hasFactContentHash, the explicit-capture\n // negative pre-filter) treat a hit as terminal BEFORE their own source/\n // category confirmation, so answering from the shared index would let a\n // non-fact suppress a real fact candidate. Only category === \"fact\" registers\n // a fact-content hash at write time (writeMemory), so answer from the\n // fact-only membership rebuilt in lockstep with the shared index. When the\n // index is authoritative that set is current (rebuild + write/removal\n // upkeep); otherwise the snapshot may be stale, so verify against the durable\n // fact corpus (ground truth) so a lock-contended read never suppresses a fact.\n if (authoritative) {\n const factHashIndex = await this.getFactHashIndex();\n return factHashIndex.hasFact(sanitized.text);\n }\n return await this.factContentHashPresentInCorpus(hash);\n }\n\n private async factContentHashPresentInCorpus(targetHash: string): Promise<boolean> {\n const existing = [...(await this.readAllMemories()), ...(await this.readAllColdMemories())];\n for (const memory of existing) {\n if (memory.frontmatter.category !== \"fact\") continue;\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") continue;\n if (this.corpusRegisteredHashes(memory).includes(targetHash)) return true;\n }\n return false;\n }\n\n private factContentHashesForRemoval(memory: MemoryFile): string[] {\n if (memory.frontmatter.category !== \"fact\") return [];\n return this.corpusRegisteredHashes(memory);\n }\n\n private async addActiveFactContentHash(memory: MemoryFile): Promise<void> {\n if (memory.frontmatter.category !== \"fact\") return;\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") return;\n const hashes = this.factContentHashesForRemoval(memory);\n if (hashes.length === 0) return;\n\n await this.ensureFactHashIndexAuthoritative();\n const factHashIndex = await this.getFactHashIndex();\n for (const hash of hashes) {\n factHashIndex.addFactByHash(hash);\n }\n // PR #2016 thread SDzOP: flush through the SAME cross-process locked\n // reconcile the write/batch/rebuild paths use, never the unlocked whole-file\n // save() — an unlocked overwrite drops a concurrent extraction's appended\n // hash and can be clobbered by a peer's locked publish. saveMergingWithDisk\n // republishes only OUR delta ((on-disk \\ removed) ∪ added) under the lock.\n await factHashIndex.saveMergingWithDisk();\n // A locked reconcile that times out defers to an unref'd background retry\n // and returns WITHOUT publishing (dirty retained). The reactivation path is\n // a lifecycle boundary just like writeMemory (PR #2016 thread\n // PRRT_kwDORJXyws6SEHvh): a short-lived caller must not observe the deferral\n // as durable. Drain the deferred retry inline so the reintroduced hash lands\n // on disk (or exhausts its bounded attempts, falling back to the\n // corpus-rebuild safety net) before returning. No-op — no duplicated retry\n // work — when the save already published (not dirty).\n await factHashIndex.flushReconcileRetry();\n }\n\n /**\n * Re-register a fact's contentHash in the dedup index after a tombstone\n * block is lifted on approval (issue #1579 thread ObnTy). `writeMemory`\n * skips hash-index registration for tombstone-blocked facts (rule 44); when\n * the review queue later promotes such a fact back to `status: active`, the\n * hash must enter the index or the next extraction of the same content\n * creates a second active fact. Reads the memory by id so the caller (the\n * review CLI) does not need to re-parse the file. No-op for non-facts or\n * facts that are not active.\n */\n async restoreFactHashAfterApproval(memoryId: string): Promise<void> {\n const all = await this.readAllMemories();\n const memory = all.find((m) => m.frontmatter.id === memoryId);\n if (!memory) return;\n await this.addActiveFactContentHash(memory);\n }\n\n private async syncFactHashIndexAfterRewrite(before: MemoryFile, after: MemoryFile): Promise<void> {\n if (before.frontmatter.category !== \"fact\" && after.frontmatter.category !== \"fact\") return;\n\n const beforeHashes = this.factContentHashesForRemoval(before);\n const afterHashes = this.factContentHashesForRemoval(after);\n const beforeStatus = inferMemoryStatus(before.frontmatter, before.path);\n const afterStatus = inferMemoryStatus(after.frontmatter, after.path);\n const hashesChanged =\n beforeHashes.length !== afterHashes.length ||\n beforeHashes.some((hash, index) => hash !== afterHashes[index]);\n if (!hashesChanged && beforeStatus === afterStatus) return;\n\n if (beforeStatus === \"active\" && beforeHashes.length > 0 && (hashesChanged || afterStatus !== \"active\")) {\n await this.removeFactContentHashesForMemories([before]);\n }\n if (afterStatus === \"active\" && afterHashes.length > 0 && (hashesChanged || beforeStatus !== \"active\")) {\n await this.addActiveFactContentHash(after);\n }\n }\n\n async removeFactContentHashesForMemories(memories: MemoryFile[]): Promise<void> {\n await this.ensureFactHashIndexAuthoritative();\n const factHashIndex = await this.getFactHashIndex();\n const removedIds = new Set(\n memories\n .map((memory) => memory.frontmatter.id)\n .filter((id): id is string => typeof id === \"string\" && id.length > 0)\n );\n const removedHashes = new Set<string>();\n for (const memory of memories) {\n for (const hash of this.factContentHashesForRemoval(memory)) {\n removedHashes.add(hash);\n }\n }\n if (removedHashes.size === 0) return;\n\n const remainingActiveHashes = new Set<string>();\n const remainingMemories = [...(await this.readAllMemories()), ...(await this.readAllColdMemories())];\n for (const memory of remainingMemories) {\n if (memory.frontmatter.category !== \"fact\") continue;\n if (removedIds.has(memory.frontmatter.id)) continue;\n if (inferMemoryStatus(memory.frontmatter, memory.path) !== \"active\") continue;\n for (const hash of this.factContentHashesForRemoval(memory)) {\n remainingActiveHashes.add(hash);\n }\n }\n\n for (const hash of removedHashes) {\n if (!remainingActiveHashes.has(hash)) {\n factHashIndex.removeByHash(hash);\n factHashIndex.removeFactByHash(hash);\n }\n }\n // PR #2016 thread SDzOP: serialize the removal with the per-index lock via\n // the removal-aware reconcile, never the unlocked whole-file save(). The\n // unlocked overwrite republished this instance's stale in-memory set,\n // silently clobbering a concurrent extraction's appended hash; the reconcile\n // reads the latest on-disk state, drops only OUR removed hashes, and keeps a\n // peer's concurrent append.\n await factHashIndex.saveMergingWithDisk();\n }\n\n /**\n * Remove a memory's fact-ONLY partition membership in lockstep with the\n * shared, category-agnostic index removal the orchestrator's\n * `removeContentHashForMemory` performs on archival / semantic\n * consolidation (PR #2016 threads SDzOP / SDzOR). Without this, the\n * partition kept a removed/superseded fact's hash and `hasFactContentHash`\n * returned a stale `true` until the next corpus rebuild, so wearable /\n * explicit-capture / promotion callers skipped a valid write. No-op when\n * the fact-hash index has not been loaded in this process yet (the\n * partition is empty then and the corpus rebuild excludes the removed\n * memory). No-op for non-facts.\n */\n removeFactOnlyHashForMemory(memory: MemoryFile): void {\n if (memory.frontmatter.category !== \"fact\") return;\n const factHashIndex = this.factHashIndex;\n if (!factHashIndex) return;\n for (const hash of this.factContentHashesForRemoval(memory)) {\n factHashIndex.removeFactByHash(hash);\n }\n }\n\n async isFactContentHashAuthoritative(): Promise<boolean> {\n return await this.ensureFactHashIndexAuthoritative();\n }\n\n async writeArtifact(\n quote: string,\n options: {\n actor?: string;\n tags?: string[];\n confidence?: number;\n artifactType?: MemoryFrontmatter[\"artifactType\"];\n sourceMemoryId?: string;\n sourceTurnId?: string;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n sourceConnector?: string; origin?: string;\n toolScoped?: true;\n } = {}\n ): Promise<string> {\n await this.ensureDirectories();\n const now = new Date();\n const day = now.toISOString().slice(0, 10);\n const dir = path.join(this.artifactsDir, day);\n await mkdir(dir, { recursive: true });\n\n const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;\n const fm: MemoryFrontmatter = {\n id,\n category: \"fact\",\n created: now.toISOString(),\n updated: now.toISOString(),\n source: \"artifact\",\n confidence: options.confidence ?? 0.9,\n confidenceTier: confidenceTier(options.confidence ?? 0.9),\n tags: options.tags ?? [],\n artifactType: options.artifactType ?? \"fact\",\n sourceMemoryId: options.sourceMemoryId,\n sourceTurnId: options.sourceTurnId,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n ...(options.sourceConnector ? { sourceConnector: options.sourceConnector } : {}),\n ...(options.origin ? { origin: parseOriginClass(options.origin) } : {}),\n ...(options.toolScoped ? { toolScoped: true as const } : {}),\n };\n\n const sanitized = sanitizeMemoryContent(quote);\n if (!sanitized.clean) {\n log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(\", \")}`);\n return \"\";\n }\n const filePath = path.join(dir, `${id}.md`);\n await this.writeStorageSecureFile(filePath, `${serializeFrontmatter(this.withOkfType(fm))}\\n\\n${sanitized.text}\\n`);\n const actor =\n typeof options.actor === \"string\" && options.actor.length > 0 ? options.actor : \"storage.writeArtifact\";\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.writeArtifact\", {\n memoryId: id,\n eventType: \"created\",\n timestamp: fm.created,\n actor,\n after: this.summarizeLifecycleState(fm, filePath),\n relatedMemoryIds: options.sourceMemoryId ? [options.sourceMemoryId] : [],\n });\n this.bumpArtifactWriteVersion();\n // Always invalidate on write. This avoids stale mixed snapshots when multiple\n // processes share the same memoryDir and write concurrently.\n this.artifactIndexCache = null;\n return id;\n }\n\n private async readAllArtifactsCached(options?: CorpusReadOptions): Promise<MemoryFile[]> {\n return this.memoryReadStore.readAllArtifactsCached(options);\n }\n\n async searchArtifacts(\n query: string,\n maxResults: number,\n options: ArtifactSearchOptions = {},\n ): Promise<MemoryFile[]> {\n return selectArtifactMatches(\n () => this.readAllArtifactsCached({ abortSignal: options.abortSignal }),\n query,\n maxResults,\n options,\n );\n }\n\n async writeEntity(\n name: string,\n type: string,\n facts: string[],\n options: {\n timestamp?: string;\n source?: string;\n sessionKey?: string;\n principal?: string;\n origin?: string;\n structuredSections?: EntityStructuredSection[];\n } = {}\n ): Promise<string> {\n return this.entityStore.writeEntity(name, type, facts, options);\n }\n\n async readProfile(): Promise<string> {\n try {\n return stripOkfProfileFrontmatter(await readMaybeEncryptedFile(this.profilePath, this._secureStoreKey, this.baseDir));\n } catch (error) {\n if (error instanceof SecureStoreLockedError) {\n throw error;\n }\n if (isErrnoCode(error, \"ENOENT\")) return \"\";\n throw error;\n }\n }\n\n async writeProfile(content: string): Promise<void> {\n const timestamp = new Date().toISOString();\n const stampedContent = withOkfProfileFrontmatter(\n renderProfileWithLastUpdated(content, timestamp),\n timestamp,\n this.okfConformanceEnabled(),\n );\n await this.ensureDirectories();\n await this.snapshotBeforeWrite(this.profilePath, \"consolidation\");\n await this.writeStorageSecureFile(this.profilePath, stampedContent);\n log.debug(\"updated profile.md\");\n }\n\n private static normalizeForDedup(s: string): string {\n if (typeof s !== \"string\") return \"\";\n return s\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n }\n\n /**\n * Check if a new bullet is a fuzzy duplicate of any existing bullet.\n * Returns true if the new bullet should be skipped.\n */\n private static isFuzzyDuplicate(newNorm: string, existingNorms: string[]): boolean {\n for (const existing of existingNorms) {\n // Exact normalized match\n if (newNorm === existing) return true;\n\n // Containment check: shorter must be >60% length of longer\n const shorter = newNorm.length <= existing.length ? newNorm : existing;\n const longer = newNorm.length > existing.length ? newNorm : existing;\n if (shorter.length > 20 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {\n return true;\n }\n }\n return false;\n }\n\n async appendToProfile(updates: string[]): Promise<void> {\n // Filter out non-string entries that the LLM may return\n updates = updates.filter((u) => typeof u === \"string\" && u.trim().length > 0);\n if (updates.length === 0) return;\n const existing = await this.readProfile();\n\n const lines = existing ? existing.split(\"\\n\") : [];\n const existingBulletRaw = lines.filter((l) => l.startsWith(\"- \")).map((l) => l.slice(2).trim());\n const existingNorms = existingBulletRaw.map(StorageManager.normalizeForDedup);\n\n const newBullets = updates.filter((u) => {\n const norm = StorageManager.normalizeForDedup(u);\n return !StorageManager.isFuzzyDuplicate(norm, existingNorms);\n });\n if (newBullets.length === 0) return;\n\n if (!existing) {\n const content = [\"# Behavioral Profile\", \"\", ...newBullets.map((b) => `- ${b}`), \"\"].join(\"\\n\");\n await this.writeProfile(content);\n } else {\n const withBullets = existing.trimEnd() + \"\\n\" + newBullets.map((b) => `- ${b}`).join(\"\\n\") + \"\\n\";\n await this.writeProfile(withBullets);\n }\n }\n\n /** Check if profile.md exceeds the max line cap and needs LLM consolidation */\n async profileNeedsConsolidation(triggerLines?: number): Promise<boolean> {\n const profile = await this.readProfile();\n if (!profile) return false;\n const lineCount = profile.split(\"\\n\").length;\n const threshold =\n typeof triggerLines === \"number\" ? Math.max(0, Math.floor(triggerLines)) : StorageManager.PROFILE_MAX_LINES;\n return lineCount > threshold;\n }\n\n private rememberMemorySnapshot<T extends MemoryFile | null>(memory: T): T {\n if (memory !== null && !StorageManager.loadedMemorySnapshots.has(memory)) {\n StorageManager.loadedMemorySnapshots.set(memory, createMemorySnapshot(memory));\n }\n return memory;\n }\n\n private rememberMemorySnapshots(memories: MemoryFile[]): MemoryFile[] {\n for (const memory of memories) this.rememberMemorySnapshot(memory);\n return memories;\n }\n\n async readAllMemories(options?: CorpusReadOptions): Promise<MemoryFile[]> {\n checkCorpusReadAbort(options);\n if (this.hotMemoriesCacheEnabled) {\n const cached = getCachedMemories(\n this.baseDir,\n this.getMemoryCorpusVersion(),\n this.hotCacheKeyId(),\n this.hotCacheTtlMs()\n );\n if (cached !== null) return this.rememberMemorySnapshots(cached);\n }\n // Snapshot the secure-store key identity ONCE (issue #1902, Codex Medium):\n // hotCacheKeyId() can change mid-scan if setSecureStoreKey(null/other) runs\n // during the await. Recomputing it at publish time would store K-decrypted\n // results under the new \"\"/other identity, letting a locked/differently-keyed\n // read match the entry and receive plaintext instead of SecureStoreLockedError.\n // The in-flight slot get/set/delete also key on this snapshot so a mid-scan\n // key change can't orphan the slot registered under the old identity.\n const keyId = this.hotCacheKeyId();\n const inFlight = attachInFlightReader(this.baseDir, keyId, options?.abortSignal);\n if (inFlight) {\n // A joiner never cancels the shared scan on its own, but it does stop waiting\n // on it, and its departure counts: if it was the last waiter the scan is\n // cancelled (issue #2307 review).\n try {\n return this.rememberMemorySnapshots(\n await raceAbort(inFlight.read, options?.abortSignal, \"corpus read aborted\"),\n );\n } finally {\n inFlight.waiter.leave();\n }\n }\n\n // Sole-waiter cancellation lives with the registry that decides whether this\n // scan is still cancellable at all — see `beginCoalescedScan` (issue #2307).\n const scan = beginCoalescedScan(this.baseDir, keyId, options?.abortSignal);\n const readPromise = (async (): Promise<MemoryFile[]> => {\n const version = this.getMemoryCorpusVersion();\n const memories = await this._readAllMemoriesFromDisk({ abortSignal: scan.scanSignal });\n // Publish only if neither the corpus version NOR the key identity changed\n // during the scan. The version guard prevents clobbering a newer patched +\n // re-keyed entry; the keyId guard prevents publishing this key's decrypted\n // corpus under a since-changed identity (Codex Medium, #1902). A cancelled\n // scan never arrives here — the checkpoints throw — so a partial corpus is\n // never published.\n if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === version && this.hotCacheKeyId() === keyId) {\n setCachedMemories(this.baseDir, memories, version, keyId, this.hotCacheTtlMs());\n }\n return memories;\n })();\n scan.arm(readPromise);\n try {\n // The starter races its own signal too. Refcounting means a sole waiter's\n // abort rejects the scan itself, but while another reader keeps the scan\n // alive the starter would otherwise sit here and be handed the full corpus\n // after cancelling — the joiner path's contract, applied symmetrically\n // (issue #2307 review). The scan is NOT aborted here: it belongs to the\n // readers still waiting, and a completed scan is still worth caching for\n // them.\n return this.rememberMemorySnapshots(\n await raceAbort(readPromise, options?.abortSignal, \"corpus read aborted\"),\n );\n } finally {\n scan.leave();\n deleteInFlightRead(this.baseDir, keyId, readPromise);\n }\n }\n\n /** Invalidate the readAllMemories() cache after writes that add/remove memories. */\n /** Public cache invalidation for callers that need authoritative disk reads\n * (e.g. projection verify/rebuild). */\n invalidateAllMemoriesCacheForDir(): void {\n this.invalidateAllMemoriesCache();\n }\n\n /** Invalidate only the cache layers affected by direct tier file deletes. */\n invalidateMemoryCachesForTiers(tiers: Iterable<\"hot\" | \"cold\" | \"archive\">): void {\n let hotChanged = false;\n let coldChanged = false;\n let archiveChanged = false;\n for (const tier of tiers) {\n if (tier === \"cold\") {\n coldChanged = true;\n } else if (tier === \"archive\") {\n hotChanged = true;\n archiveChanged = true;\n } else if (tier === \"hot\") {\n hotChanged = true;\n }\n }\n if (hotChanged) this.invalidateAllMemoriesCache();\n archive.bumpArchiveMutationIfChanged(this.baseDir, archiveChanged);\n if (coldChanged) {\n this.invalidateColdMemoriesCache();\n }\n }\n\n /** Clear ALL static caches. Use in tests that write files directly\n * (bypassing StorageManager.writeMemory) to avoid stale reads. */\n static clearAllStaticCaches(): void {\n clearInFlightReads();\n StorageManager.questionsCache.clear();\n StorageManager.coldMemoriesCache.clear(); // also wipe the cold-scan TTL cache\n StorageManager.artifactWriteVersionByDir.clear();\n StorageManager.memoryStatusVersionByDir.clear();\n StorageManager.memoryCorpusVersionByDir.clear();\n StorageManager.entityMutationVersionByDir.clear();\n StorageManager.coldWriteVersionByDir.clear();\n clearMemoryCache();\n StorageManager.hotMemoriesCacheDefaultByDir.clear();\n StorageManager.hotMemoriesCacheTtlByDir.clear();\n StorageManager.hotMemoriesCacheDefault = true;\n StorageManager.hotMemoriesCacheTtlMs = 60_000;\n StorageManager.hotMemoriesCacheProcessDefaultSeeded = false;\n StorageManager.scopedCacheInvalidationByDir.clear();\n }\n\n /** Cancel any in-flight concurrent read so the next readAllMemories()\n * starts a fresh disk scan and sees the just-written data.\n *\n * Finding UvBq (PR #402 round-11): this method intentionally does NOT\n * invalidate the cold-scan cache. Ordinary hot-tier writes (writeMemory)\n * do not change cold-tier content, so evicting the cold cache on every hot\n * write was defeating the burst-dedup optimisation — the cold cache was\n * cleared before applyTemporalSupersession ran, causing a full cold-tree\n * disk scan on every write in a burst. Cold cache invalidation is handled\n * exclusively by invalidateColdMemoriesCache(), which is called only when\n * cold content actually changes (hot→cold demotions, writeMemoryFileAtomic\n * inside cold/, archiveMemory, etc.). */\n protected invalidateAllMemoriesCache(): void {\n deleteInFlightReadsForDir(this.baseDir);\n // Bulk/ambiguous mutations drop the hot layer wholesale (below); bump the\n // corpus sentinel too so PEER processes rescan instead of serving a warm\n // pre-mutation corpus entry (issue #1902 cross-process coherence).\n this.bumpMemoryCorpusVersion();\n // Invalidation chokepoint (issue #1535 / #1904): evict the layers a\n // memory-mutate can affect — hot, archive, derived episode/rule views, and\n // both QMD result caches (qmdSearchCache and qmdRecallCache). Before the QMD\n // caches were invalidated on mutations, recall served pre-edit bundles for\n // the remainder of its fresh/stale TTL window. The `entities` layer is NOT\n // in memory-mutate scope: these funnel callers (update/frontmatter/move/\n // archive/invalidate/bulk/offline-sync) never rewrite entity files, and the\n // ones that touch entity-derived state additionally bump the status version\n // (which does the full clear). scopedCacheInvalidationEnabled=false restores\n // the pre-#1904 full clear of every layer (rollback lever).\n if (StorageManager.scopedCacheInvalidationByDir.get(this.baseDir) ?? true) {\n invalidateForScope(this.baseDir, \"memory-mutate\");\n } else {\n invalidateAllForDir(this.baseDir);\n }\n // Issue #1579 — tombstone store is a cache layer too (rule 25: clear ALL\n // cache layers). A tombstone append from another path (supersession /\n // correction) must be visible to the next writeMemory lookup on this\n // instance without waiting for a process restart.\n if (this.tombstoneStore) {\n this.tombstoneStore.invalidate();\n this.tombstoneStore = null;\n this.tombstoneStoreLoadPromise = null;\n }\n }\n\n /**\n * Single-file write/delete fast path for the hot-memories cache (issue\n * #1902). Keeps THIS process's version-keyed corpus entry warm by patching\n * the changed memory in place, bumps the dedicated `.memory-corpus-version.log`\n * sentinel so PEER processes rescan (memory-status is deliberately NOT bumped\n * here so plain creates/content edits don't invalidate the entity cache), and\n * evicts only the derived/global layers (which\n * are cheap to rebuild and are never patched). Mirrors the in-flight-dedup\n * and tombstone-store invalidation that invalidateAllMemoriesCache() does.\n *\n * `added` is the written MemoryFile (writes/overwrites); `removedPath` is a\n * deleted path. A path outside the active scan roots (under cold/ or\n * archive/) is NOT applied to the hot map — that cache holds active memories\n * only — but the version bump and derived/global eviction still run so\n * coherence is preserved. Bulk/ambiguous mutations keep the wholesale\n * invalidateAllMemoriesCache() drop instead (issue #1902 Step 5).\n */\n private async patchHotMemoriesCache(\n opts: { addedPath?: string; removedPath?: string },\n scope: \"memory-create\" | \"memory-mutate\" = \"memory-mutate\"\n ): Promise<void> {\n const prevVersion = this.getMemoryCorpusVersion();\n // Snapshot the key identity once (issue #1902, Codex Medium): a mid-await\n // setSecureStoreKey change would otherwise let the post-await patch/re-key\n // store this key's decrypted memory under a since-changed identity.\n const keyId = this.hotCacheKeyId();\n const warm =\n this.hotMemoriesCacheEnabled &&\n getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;\n if (warm && opts.removedPath !== undefined && !this.isColdOrArchiveTierPath(opts.removedPath)) {\n updateCacheOnDelete(this.baseDir, opts.removedPath, keyId);\n }\n // Bump the corpus sentinel AND drop the in-flight slot BEFORE the awaited\n // one-file re-parse below (Cursor Medium, #1902). The on-disk write already\n // landed in the caller, so advancing the version now makes any concurrent\n // readAllMemories() during the re-parse window miss the still-old hot entry\n // and start a FRESH scan of disk truth (which includes the write) instead of\n // serving the pre-write corpus or joining a pre-write in-flight scan.\n // memory-status is deliberately NOT bumped here so plain creates/content\n // edits don't invalidate the entity cache (issue #1902).\n const { produced, exclusive } = this.bumpMemoryCorpusVersionExclusive();\n deleteInFlightReadsForDir(this.baseDir);\n let patchedOk = warm;\n if (warm && opts.addedPath !== undefined && !this.isColdOrArchiveTierPath(opts.addedPath)) {\n // Re-read + parse the ONE just-written file so the cached object is\n // exactly what a fresh disk scan would yield — serialize→parse normalizes\n // fields (e.g. an empty array becomes undefined), and the in-memory write\n // object would otherwise diverge from disk truth. This is a single O(1)\n // read (the file is page-cache-hot), NOT the O(corpus) scan the cache\n // exists to avoid.\n // Best-effort re-parse: this cache patch runs AFTER the on-disk write and\n // corpus-version bump have already persisted, so it must never fail the\n // completed mutation. If the re-read throws (e.g. setSecureStoreKey(null)\n // locked the store mid-await → SecureStoreLockedError), treat the entry as\n // unpatchable — leave it version-invalidated so the next read rescans —\n // rather than propagating and making writeMemory/updateMemory reject an\n // already-durable write (which a caller would retry, duplicating memories).\n // Issue #1902, Codex Medium.\n let parsed: MemoryFile | undefined;\n try {\n [parsed] = await this.readParsedMemoriesFromPaths([opts.addedPath], 1);\n } catch {\n parsed = undefined;\n }\n if (parsed) {\n updateCacheOnWrite(this.baseDir, parsed, keyId);\n } else {\n // Could not re-parse the write — don't trust the patched entry; leaving\n // it tagged at prevVersion means the version-bumped read rejects it\n // (version mismatch) and rescans.\n patchedOk = false;\n }\n }\n if (\n patchedOk &&\n exclusive &&\n produced === prevVersion + 1 &&\n this.getMemoryCorpusVersion() === produced &&\n this.hotCacheKeyId() === keyId\n ) {\n // Re-key the patched entry (still tagged prevVersion) to the version THIS\n // mutation produced — ONLY if no peer appended between prevVersion capture\n // and our bump (produced === prevVersion + 1), our bump was exclusive, and\n // no further peer append landed during the re-parse (still === produced).\n // Otherwise a concurrent read has already republished disk truth at the\n // newer version, or our patched corpus lacks a peer's write — either way\n // leave it version-rejected so the next read rescans.\n const patched = getCachedMemories(this.baseDir, prevVersion, keyId);\n if (patched) setCachedMemories(this.baseDir, patched, produced, keyId, this.hotCacheTtlMs());\n }\n // Evict the non-hot layers; the hot layer is patched (or intentionally left\n // to be version-rejected) above, not dropped here. Scope-aware (issue #1904):\n // a `memory-create` evicts ONLY the derived episode/rule views, keeping the\n // global QMD result caches and the version-keyed entity cache warm (a create\n // adds a doc that is not yet in the QMD index and changes no existing doc's\n // recall visibility). A `memory-mutate` (or scoped-off rollback) still evicts\n // the derived + global QMD views so a superseded/edited memory cannot resurface\n // from a stale recall bundle (issue #1535 correctness contract).\n if (scope === \"memory-create\" && (StorageManager.scopedCacheInvalidationByDir.get(this.baseDir) ?? true)) {\n invalidateForScopeExceptHot(this.baseDir, \"memory-create\");\n } else {\n invalidateDerivedAndGlobalForDir(this.baseDir);\n }\n if (this.tombstoneStore) {\n this.tombstoneStore.invalidate();\n this.tombstoneStore = null;\n this.tombstoneStoreLoadPromise = null;\n }\n }\n\n /**\n * Invalidate the cold-scan cache for this storage root and bump the\n * on-disk cold-version sentinel so that other processes (gateway, CLI) see\n * the change immediately on their next readAllColdMemories() call.\n *\n * Must be called whenever a memory is written INTO the cold tier — hot→cold\n * demotion, atomic writes inside cold/, archiving a cold memory, etc.\n * NOT called on ordinary hot-tier writes (those don't change cold contents).\n *\n * Finding UvUy (PR #402 round-11): bumping the sentinel here makes the\n * per-process in-memory cache safe across process boundaries.\n */\n protected invalidateColdMemoriesCache(): void {\n const coldRoot = path.join(this.baseDir, \"cold\");\n StorageManager.coldMemoriesCache.delete(coldRoot);\n this.bumpColdWriteVersion();\n // Invalidation chokepoint (issue #1535): cold-tier mutations can reach\n // this funnel without invalidateAllMemoriesCache() (e.g. the cold-only\n // branch of invalidateMemoryCachesForTiers used by maintenance/purge), so\n // the chokepoint must fire here too — cold memories are recallable and a\n // cold delete must not leave stale QMD recall bundles behind.\n invalidateAllForDir(this.baseDir);\n }\n\n /** Return the current cold-write version counter for this storage root.\n * Reads the on-disk sentinel (state/cold-write.log) so it reflects writes\n * made by other processes. */\n private readColdWriteVersion(): number {\n return this.readSharedVersion(\"cold-write\", StorageManager.coldWriteVersionByDir);\n }\n\n /** Bump the on-disk cold-write version sentinel and update the in-process\n * fallback map. Called by invalidateColdMemoriesCache(). */\n private bumpColdWriteVersion(): void {\n this.bumpSharedVersion(\"cold-write\", StorageManager.coldWriteVersionByDir);\n }\n\n private normalizeMemoryReadBatchSize(batchSize?: number): number {\n if (typeof batchSize !== \"number\" || !Number.isFinite(batchSize)) {\n return 50;\n }\n return Math.max(1, Math.floor(batchSize));\n }\n\n /**\n * Public cheap active-memory path scan (issue #2149 corpus watermark). Lists\n * active memory file paths without parsing frontmatter — safe on a 100k+\n * corpus, unlike readAllMemories().\n */\n async collectActiveMemoryPaths(\n options?: { propagateReadErrors?: boolean } & CorpusReadOptions,\n ): Promise<string[]> {\n return this.memoryReadStore.collectActiveMemoryPaths(options);\n }\n\n /**\n * Public cheap cold-tier path scan (issue #2156 finding D corpus census).\n * Lists demoted-but-reachable memory paths under `cold/` without parsing\n * frontmatter, so the divergence watermark counts the cold tier too.\n */\n async collectColdMemoryPaths(options?: { propagateReadErrors?: boolean }): Promise<string[]> {\n return this.memoryReadStore.collectColdMemoryPaths(options);\n }\n\n /**\n * Combined hot+cold corpus-mutation sentinel (issue #2156). Changes whenever\n * EITHER tier is written, so a divergence census can bracket its hot/cold scan\n * and detect a tier migration (write-cold-then-unlink-hot) racing the walkers,\n * then retry for a consistent snapshot instead of caching a transient\n * double-count or miss.\n */\n getCorpusScanVersion(): string {\n return `${this.getMemoryCorpusVersion()}:${this.readColdWriteVersion()}`;\n }\n\n private async readParsedMemoriesFromPaths(\n filePaths: string[],\n batchSize?: number,\n options?: CorpusReadOptions,\n ): Promise<MemoryFile[]> {\n if (filePaths.length === 0) return [];\n\n const normalizedBatchSize = this.normalizeMemoryReadBatchSize(batchSize);\n const memories: MemoryFile[] = [];\n for (let i = 0; i < filePaths.length; i += normalizedBatchSize) {\n // Per batch: the parse phase is as long as the walk on a large corpus, and\n // an abandoned caller must not keep paying for it (issue #2307).\n checkCorpusReadAbort(options);\n const batch = filePaths.slice(i, i + normalizedBatchSize);\n const results = await Promise.all(\n batch.map(async (fullPath) => {\n try {\n const raw = await readMaybeEncryptedFile(fullPath, this._secureStoreKey, this.baseDir);\n const parsed = parseFrontmatter(raw);\n if (!parsed) return null;\n return rememberRawFrontmatter(\n {\n path: fullPath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, fullPath),\n parsed.content\n ),\n content: parsed.content,\n } satisfies MemoryFile,\n raw\n );\n } catch (err) {\n // Re-throw store-locked errors so a locked encrypted store fails\n // loudly rather than appearing as an empty memory corpus (Cursor\n // review finding, PR #767).\n if (err instanceof SecureStoreLockedError) throw err;\n return null;\n }\n })\n );\n for (const memory of results) {\n if (memory !== null) memories.push(memory);\n }\n }\n // Once more after the loop: a signal that fired during the LAST batch's await\n // would otherwise let this return successfully, publishing to the cache and\n // handing results to a caller that had already given up (issue #2307 review).\n checkCorpusReadAbort(options);\n return memories;\n }\n\n private async readWindowUpdatedMs(filePath: string): Promise<number | null> {\n try {\n const raw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/);\n if (!match) return null;\n const frontmatterBlock = match[1];\n const rawUpdated =\n frontmatterBlock.match(/^[ \\t]*updated:[ \\t]*\"?([^\"\\r\\n]*)\"?/m)?.[1] ||\n frontmatterBlock.match(/^[ \\t]*created:[ \\t]*\"?([^\"\\r\\n]*)\"?/m)?.[1] ||\n null;\n const updatedMs = rawUpdated ? Date.parse(rawUpdated.trim()) : Number.NaN;\n return Number.isFinite(updatedMs) ? updatedMs : null;\n } catch {\n return null;\n }\n }\n\n private async filterWindowPathsByUpdatedAfter(filePaths: string[], updatedAfterMs: number): Promise<string[]> {\n const results = await Promise.all(\n filePaths.map(async (filePath) => {\n const updatedMs = await this.readWindowUpdatedMs(filePath);\n if (updatedMs !== null) {\n return updatedMs >= updatedAfterMs ? filePath : null;\n }\n try {\n const fileStat = await stat(filePath);\n return fileStat.mtimeMs >= updatedAfterMs ? filePath : null;\n } catch {\n return filePath;\n }\n })\n );\n return results.filter((filePath): filePath is string => filePath !== null);\n }\n\n private orderWindowPaths(filePaths: string[]): string[] {\n const correctionPaths: string[] = [];\n const factPaths: string[] = [];\n\n for (const filePath of filePaths) {\n if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path.sep}`)) {\n correctionPaths.push(filePath);\n } else {\n factPaths.push(filePath);\n }\n }\n\n correctionPaths.sort((left, right) => right.localeCompare(left));\n factPaths.sort((left, right) => right.localeCompare(left));\n\n if (correctionPaths.length === 0) return factPaths;\n if (factPaths.length === 0) return correctionPaths;\n\n const ordered: string[] = [];\n const maxLength = Math.max(correctionPaths.length, factPaths.length);\n for (let i = 0; i < maxLength; i += 1) {\n const correctionPath = correctionPaths[i];\n if (correctionPath) ordered.push(correctionPath);\n const factPath = factPaths[i];\n if (factPath) ordered.push(factPath);\n }\n return ordered;\n }\n\n private async readWindowBoundedBatch(\n candidateBatchPaths: string[],\n remainingSlots: number,\n remainingInspectionBudget: number,\n readBatchSize: number\n ): Promise<{ memories: MemoryFile[]; filePaths: string[] }> {\n const memories: MemoryFile[] = [];\n const filePaths: string[] = [];\n const normalizedReadBatchSize = this.normalizeMemoryReadBatchSize(readBatchSize);\n\n for (let index = 0; index < candidateBatchPaths.length; ) {\n if (memories.length >= remainingSlots || filePaths.length >= remainingInspectionBudget) break;\n const availableSlots = remainingSlots - memories.length;\n const availableInspectionBudget = remainingInspectionBudget - filePaths.length;\n const parallelWindow =\n availableSlots >= 4 && availableInspectionBudget >= 4 ? Math.min(normalizedReadBatchSize, 4) : 1;\n const candidatePaths = candidateBatchPaths.slice(\n index,\n index + Math.min(parallelWindow, availableInspectionBudget)\n );\n index += candidatePaths.length;\n if (candidatePaths.length === 0) break;\n filePaths.push(...candidatePaths);\n const parsedMemories = await this.readParsedMemoriesFromPaths(candidatePaths, candidatePaths.length);\n if (parsedMemories.length === 0) continue;\n memories.push(...parsedMemories.slice(0, availableSlots));\n }\n\n return { memories, filePaths };\n }\n\n async readMemoriesWindow(options: WindowedMemoryReadOptions = {}): Promise<WindowedMemoryReadResult> {\n return readWindowedMemories(this.memoryReadStore, options, { enabled: this.hotMemoriesCacheEnabled, baseDir: this.baseDir, corpusVersion: this.getMemoryCorpusVersion(), cacheKeyId: this.hotCacheKeyId(), ttlMs: this.hotCacheTtlMs() }, (memories) => this.rememberMemorySnapshots(memories));\n }\n\n private async _readAllMemoriesFromDisk(options?: CorpusReadOptions): Promise<MemoryFile[]> {\n const filePaths = await this.collectActiveMemoryPaths(options);\n return this.readParsedMemoriesFromPaths(filePaths, 50, options);\n }\n\n async readAllColdMemories(): Promise<MemoryFile[]> {\n return this.rememberMemorySnapshots(await this.memoryReadStore.readAllColdMemories());\n }\n\n /**\n * Read archived memory markdown files under archive/.\n * Used by long-term recall fallback when hot recall has no hits.\n */\n async readArchivedMemories(): Promise<MemoryFile[]> {\n const memories: MemoryFile[] = [];\n const root = this.archiveDir;\n\n const readDir = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await readDir(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n try {\n const raw = await readMaybeEncryptedFile(fullPath, this._secureStoreKey, this.baseDir);\n const parsed = parseFrontmatter(raw);\n if (parsed) {\n memories.push(\n rememberRawFrontmatter(\n {\n path: fullPath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.baseDir, fullPath),\n parsed.content\n ),\n content: parsed.content,\n },\n raw\n )\n );\n }\n } catch (err) {\n // A bad archive member must not hide readable siblings. A locked\n // secure store remains authoritative even for one member.\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) {\n log.warn(`skipping unreadable archived memory ${fullPath}: ${err}`);\n }\n }\n }\n }\n } catch (error) {\n if (error instanceof SecureStoreLockedError) throw error;\n if (!isErrnoCode(error, \"ENOENT\")) throw error;\n }\n };\n\n await readDir(root);\n return this.rememberMemorySnapshots(memories);\n }\n\n async readMemoryByPath(filePath: string): Promise<MemoryFile | null> {\n return this.rememberMemorySnapshot(await this.memoryReadStore.readMemoryByPath(filePath));\n }\n\n private resolveTierRootDir(tier: \"hot\" | \"cold\"): string {\n return tier === \"cold\" ? path.join(this.baseDir, \"cold\") : this.baseDir;\n }\n\n private resolveMemoryDateDir(memory: MemoryFile): string {\n const preferred = memory.frontmatter.created || memory.frontmatter.updated;\n const dateToken = (preferred ?? \"\").slice(0, 10);\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(dateToken) ? dateToken : new Date().toISOString().slice(0, 10);\n }\n\n private isArtifactMemory(memory: MemoryFile): boolean {\n if (memory.frontmatter.source === \"artifact\") return true;\n if (memory.frontmatter.artifactType !== undefined) return true;\n return /[\\\\/]artifacts[\\\\/]/.test(memory.path);\n }\n\n buildTierMemoryPath(memory: MemoryFile, tier: \"hot\" | \"cold\"): string {\n const root = this.resolveTierRootDir(tier);\n if (this.isArtifactMemory(memory)) {\n return path.join(root, \"artifacts\", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);\n }\n if (memory.frontmatter.category === \"correction\") {\n // corrections/ is flat (no date subdir); preserved across tier moves.\n return path.join(root, \"corrections\", `${memory.frontmatter.id}.md`);\n }\n const dir = categoryDirName(memory.frontmatter.category);\n return path.join(root, dir, this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);\n }\n private async writeMemoryFileAtomic(targetPath: string, memory: MemoryFile): Promise<void> {\n assertNotOkfReservedBasename(targetPath);\n // Whole-record rewrite (tier moves) — #2213. Repair, not just detect:\n // the source is unlinked after the move, so a mapping parked across this\n // write would strand the moved copy with nothing left to reconcile from.\n const refIdsAtWrite = this.currentHistoricalIds();\n const rawRef = memory.frontmatter.entityRef;\n const frontmatter = entityRefs.canonicalizeEntityRefOption(memory.frontmatter, refIdsAtWrite);\n const persist = (): Promise<void> =>\n writeMaybeEncryptedFile(\n targetPath,\n `${serializeFrontmatter(this.withOkfType(frontmatter))}\\n\\n${memory.content}\\n`,\n this.resolveWriteKey(),\n {},\n this.baseDir\n );\n // Snapshot pre-write destination bytes (raw — encryption-agnostic) so a\n // repair failure restores them or removes a fresh copy (§14): a retained\n // destination would duplicate the record across tiers under a stale ref.\n const priorDest = await readFile(targetPath).catch(() => null);\n await persist();\n if (typeof rawRef === \"string\") {\n const refBeforeRepair = frontmatter.entityRef;\n try {\n await entityRefs.repairEntityRefAfterJournalMove({\n stateDir: this.stateDir,\n currentIds: () => this.currentHistoricalIds(),\n idsAtResolve: refIdsAtWrite,\n rawRef,\n frontmatter,\n rewrite: persist,\n });\n } catch (err) {\n if (priorDest === null) {\n await unlink(targetPath).catch(() => undefined);\n } else {\n await writeFile(targetPath, priorDest).catch(() => undefined);\n }\n this.invalidateAllMemoriesCache();\n throw err;\n }\n await this.entityRefRepair.syncProjection(memory.frontmatter.id, refBeforeRepair, frontmatter.entityRef);\n }\n // Sync the caller's record with the ref the file now carries: tier-move\n // callers keep using the passed MemoryFile, and a stale legacy ref would\n // mis-route later attribution/projection work (Cursor Medium, round 21).\n if (memory.frontmatter.entityRef !== frontmatter.entityRef) {\n memory.frontmatter.entityRef = frontmatter.entityRef;\n }\n this.invalidateAllMemoriesCache();\n this.notifyCatalogWrite();\n }\n async moveMemoryToPath(memory: MemoryFile, targetPath: string): Promise<boolean> {\n const { recordArchiveDelete, recordArchiveWrite } = archive;\n const changed = await this.withTombstoneBlockedMemoryPathLock(\n memory.path,\n async (current) => {\n const destination = await this.readMemoryByPath(targetPath);\n if (current?.frontmatter.id !== memory.frontmatter.id) {\n if (current === null && destination?.frontmatter.id === memory.frontmatter.id) return false;\n throw new Error(`memory ${memory.frontmatter.id} changed before its tier move`);\n }\n const callerSnapshot = StorageManager.loadedMemorySnapshots.get(memory);\n const currentSnapshot = createMemorySnapshot(current);\n if (\n callerSnapshot === undefined\n ? current.frontmatter.updated !== memory.frontmatter.updated\n : currentSnapshot !== callerSnapshot\n ) {\n throw new Error(`memory ${memory.frontmatter.id} changed before its tier move`);\n }\n const coordinate =\n tombstoneBlocked(current.frontmatter) ||\n isQueuedReviewMemory(current) ||\n (destination !== null && tombstoneBlocked(destination.frontmatter)) ||\n isQueuedReviewMemory(destination);\n const index = this.getTombstoneBlockedCaptureIndex();\n const marker = coordinate ? await index.prepareWrite() : undefined;\n const projectedPath = toMemoryPathRel(this.baseDir, targetPath);\n let durable = false;\n try {\n if (destination?.frontmatter.id === current.frontmatter.id) {\n await recordArchiveDelete(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));\n durable = true;\n this.invalidateAllMemoriesCache();\n updateProjectedMemoryPath(this.baseDir, current.frontmatter.id, projectedPath);\n } else {\n await recordArchiveWrite(this.baseDir, targetPath, () => this.writeMemoryFileAtomic(targetPath, current));\n if (memory.frontmatter.entityRef !== current.frontmatter.entityRef) {\n memory.frontmatter.entityRef = current.frontmatter.entityRef;\n }\n durable = true;\n const sourcePath = path.resolve(current.path);\n const destPath = path.resolve(targetPath);\n if (sourcePath !== destPath) {\n await recordArchiveDelete(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));\n this.invalidateAllMemoriesCache();\n updateProjectedMemoryPath(this.baseDir, current.frontmatter.id, projectedPath);\n }\n }\n if (marker !== undefined) await this.rebuildTombstoneBlockedCaptureAfterInvalidation(marker);\n } catch (error) {\n if (marker !== undefined && !durable) await index.discardWrite(marker).catch(() => index.markUntrusted());\n if (marker !== undefined && durable) index.markUntrusted();\n throw error;\n }\n return true;\n },\n [targetPath]\n );\n if (this.isColdOrArchiveTierPath(memory.path) || this.isColdOrArchiveTierPath(targetPath)) {\n this.invalidateColdMemoriesCache();\n }\n return changed;\n }\n\n async migrateMemoryToTier(\n memory: MemoryFile,\n targetTier: \"hot\" | \"cold\"\n ): Promise<{ changed: boolean; targetPath: string }> {\n const targetPath = this.buildTierMemoryPath(memory, targetTier);\n const sourcePath = path.resolve(memory.path);\n const destPath = path.resolve(targetPath);\n if (sourcePath === destPath) {\n return { changed: false, targetPath };\n }\n const changed = await this.moveMemoryToPath(memory, targetPath);\n if (!changed) return { changed: false, targetPath };\n this.bumpMemoryStatusVersion();\n return { changed, targetPath };\n }\n\n private get archiveDir(): string {\n return path.join(this.baseDir, \"archive\");\n }\n\n /**\n * Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.\n * Updates frontmatter with archived status before moving.\n * Returns the new file path on success, null on failure.\n */\n async archiveMemory(memory: MemoryFile, lifecycle?: MemoryLifecycleEventWriteOptions): Promise<string | null> {\n const { recordArchiveDelete, recordArchiveWrite } = archive;\n const archiveCurrent = async (current: MemoryFile, markDurable: () => void): Promise<string | null> => {\n try {\n const now = lifecycle?.at ?? new Date();\n const today = now.toISOString().slice(0, 10);\n const destDir = path.join(this.archiveDir, today);\n await mkdir(destDir, { recursive: true });\n // Whole-record rewrite — inherited-entityRef rule (issue #2213).\n const refIdsAtWrite = this.currentHistoricalIds();\n const updatedFm: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(\n {\n ...current.frontmatter,\n status: \"archived\",\n archivedAt: now.toISOString(),\n updated: now.toISOString(),\n },\n refIdsAtWrite\n );\n const fileContent = `${serializeFrontmatter(this.withOkfType(updatedFm))}\\n\\n${current.content}\\n`;\n const destPath = path.join(destDir, path.basename(current.path));\n // Snapshot a pre-existing destination (retried archive) so a repair\n // failure restores it instead of deleting the only archived copy (§14).\n const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);\n await recordArchiveWrite(this.baseDir, destPath, () => this.writeStorageSecureFile(destPath, fileContent));\n if (typeof current.frontmatter.entityRef === \"string\") {\n try {\n await this.entityRefRepair.repair(\n destPath,\n updatedFm,\n current.frontmatter.entityRef,\n refIdsAtWrite,\n current.content\n );\n } catch (err) {\n if (priorDest === null) {\n await recordArchiveDelete(this.baseDir, destPath, () =>\n unlink(destPath).then(\n () => true,\n () => false\n )\n );\n } else {\n await recordArchiveDelete(this.baseDir, destPath, () =>\n this.writeStorageSecureFile(destPath, priorDest).then(\n () => true,\n () => false\n )\n );\n }\n throw err;\n }\n }\n const deleted = await recordArchiveDelete(this.baseDir, current.path, () =>\n this.deleteManagedStorageFile(current.path));\n if (!deleted) return null;\n markDurable();\n markProjectedMemoryPathInvalid(this.baseDir, current.frontmatter.id);\n this.invalidateAllMemoriesCache();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\n \"storage.archiveMemory\",\n {\n memoryId: current.frontmatter.id,\n eventType: \"archived\",\n timestamp: updatedFm.archivedAt ?? updatedFm.updated,\n actor: lifecycle?.actor ?? \"storage.archiveMemory\",\n reasonCode: lifecycle?.reasonCode,\n before: this.summarizeLifecycleState(current.frontmatter, current.path),\n after: this.summarizeLifecycleState(updatedFm, destPath),\n relatedMemoryIds: lifecycle?.relatedMemoryIds,\n correlationId: lifecycle?.correlationId,\n },\n lifecycle?.ruleVersion\n );\n this.bumpMemoryStatusVersion();\n log.debug(`archived memory ${current.frontmatter.id} → ${destPath}`);\n return destPath;\n } catch (err) {\n log.warn(`failed to archive memory ${current.frontmatter.id}: ${err}`);\n return null;\n }\n };\n return await this.runTombstoneBlockedArchive(memory, archiveCurrent);\n }\n\n /** Alias of listEntityNames (kept for legacy callers; sorted). */\n async readEntities(): Promise<string[]> {\n return this.entityStore.listEntityNames();\n }\n\n async readEntity(name: string): Promise<string> {\n return this.entityStore.readEntity(name);\n }\n\n async listEntityNames(): Promise<string[]> {\n return this.entityStore.listEntityNames();\n }\n\n /**\n * Find an existing entity that fuzzy-matches the proposed name.\n * Returns the existing entity filename (without .md) or null if no match.\n *\n * Matching priority:\n * 1. Exact normalized match (handled by normalizeEntityName already)\n * 2. Dehyphenated match: \"jane-doe\" vs \"janedoe\"\n * 3. Substring containment: \"handle-janedoe\" contains \"janedoe\"\n * 4. Levenshtein ≤ 2 on dehyphenated names\n */\n async findMatchingEntity(proposedName: string, type: string): Promise<string | null> {\n const existing = await this.listEntityNames();\n if (existing.length === 0) return null;\n\n const typePrefix = `${type.toLowerCase()}-`;\n // Extract the name part from the proposed normalized name\n const proposedFull = this.normalizeEntityName(proposedName, type);\n const proposedNamePart = proposedFull.startsWith(typePrefix) ? proposedFull.slice(typePrefix.length) : proposedFull;\n const proposedDehyph = dehyphenate(proposedNamePart);\n\n // Only compare against entities of the same type\n const sameType = existing.filter((e) => e.startsWith(typePrefix));\n\n for (const entity of sameType) {\n const entityNamePart = entity.slice(typePrefix.length);\n const entityDehyph = dehyphenate(entityNamePart);\n\n // Already the exact normalized form\n if (entity === proposedFull) return entity;\n\n // Dehyphenated exact match\n if (entityDehyph === proposedDehyph) return entity;\n\n // Substring containment (shorter must be >60% length of longer)\n const shorter = proposedDehyph.length <= entityDehyph.length ? proposedDehyph : entityDehyph;\n const longer = proposedDehyph.length > entityDehyph.length ? proposedDehyph : entityDehyph;\n if (shorter.length > 3 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {\n return entity;\n }\n\n // Levenshtein distance ≤ 2 (only for names of reasonable length)\n if (proposedDehyph.length >= 4 && entityDehyph.length >= 4) {\n const dist = levenshtein(proposedDehyph, entityDehyph);\n if (dist <= 2) return entity;\n }\n }\n\n return null;\n }\n\n async invalidateMemory(\n id: string,\n expectedSnapshot?: Pick<MemoryFile, \"content\" | \"frontmatter\"> & Partial<Pick<MemoryFile, \"path\">>,\n options?: { recordCommitProof?: boolean },\n ): Promise<boolean> {\n const memory = expectedSnapshot?.path\n ? await this.readMemoryByPath(expectedSnapshot.path)\n : (await this.readAllMemories()).find((candidate) => candidate.frontmatter.id === id) ?? null;\n if (!memory || memory.frontmatter.id !== id) return false;\n\n return await this.runTombstoneBlockedInvalidation(memory, async (current, rebuildMarker, markDurable) => {\n if (\n expectedSnapshot &&\n invalidationCommitFingerprint(current) !== invalidationCommitFingerprint(expectedSnapshot)\n ) {\n return false;\n }\n return runCommittedInvalidation({\n memoryId: id,\n recordProof: options?.recordCommitProof === true ? () => this.recordCommittedInvalidation(current) : undefined,\n clearProof: options?.recordCommitProof === true ? () => this.clearCommittedInvalidation(current) : undefined,\n deleteMemory: () => archive.recordArchiveDelete(this.baseDir, current.path, () =>\n this.deleteManagedStorageFile(current.path)),\n afterDelete: async () => {\n markDurable();\n markProjectedMemoryPathInvalid(this.baseDir, id);\n this.invalidateAllMemoriesCache();\n if (this.isColdOrArchiveTierPath(current.path)) this.invalidateColdMemoriesCache();\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);\n this.bumpMemoryStatusVersion();\n log.debug(`invalidated memory ${id}`);\n },\n });\n });\n }\n\n private async updateMemoryFromCurrent(\n memory: MemoryFile,\n newContent: string,\n options?: { supersedes?: string; lineage?: string[]; actor?: string; sourceConnector?: string },\n ): Promise<boolean> {\n const mergedLineage = [...(memory.frontmatter.lineage ?? []), ...(options?.lineage ?? [])].filter(\n (v, i, a) => a.indexOf(v) === i\n );\n const refIdsAtWrite = this.currentHistoricalIds();\n const updated: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(\n {\n ...memory.frontmatter,\n updated: new Date().toISOString(),\n supersedes: options?.supersedes ?? memory.frontmatter.supersedes,\n lineage: mergedLineage.length > 0 ? mergedLineage : undefined,\n ...(memory.frontmatter.sourceConnector === undefined && options?.sourceConnector\n ? { sourceConnector: options.sourceConnector }\n : {}),\n },\n refIdsAtWrite\n );\n const sanitized = sanitizeMemoryContent(newContent);\n if (!sanitized.clean) {\n log.warn(`updated memory content sanitized for ${memory.frontmatter.id}; violations=${sanitized.violations.join(\", \")}`);\n }\n const fileContent = `${serializeFrontmatter(this.withOkfType(updated))}\\n\\n${sanitized.text}\\n`;\n await this.writeTombstoneBlockedUpdate(memory, fileContent, updated, sanitized.text, async () => {\n this.invalidateAllMemoriesCache();\n if (this.isColdOrArchiveTierPath(memory.path)) this.invalidateColdMemoriesCache();\n });\n if (typeof memory.frontmatter.entityRef === \"string\") {\n await this.entityRefRepair.repair(\n memory.path,\n updated,\n memory.frontmatter.entityRef,\n refIdsAtWrite,\n sanitized.text,\n { onFailRestore: memory }\n );\n }\n await this.patchHotMemoriesCache({ addedPath: memory.path });\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.updateMemory\", {\n memoryId: memory.frontmatter.id,\n eventType: \"updated\",\n timestamp: updated.updated,\n actor: options?.actor ?? \"storage.updateMemory\",\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updated, memory.path),\n relatedMemoryIds: [\n ...(updated.supersedes ? [updated.supersedes] : []),\n ...(updated.lineage ?? []).filter(Boolean),\n ],\n });\n log.debug(`updated memory ${memory.frontmatter.id}`);\n return true;\n }\n\n async updateMemory(\n id: string,\n newContent: string,\n options?: { supersedes?: string; lineage?: string[]; actor?: string; sourceConnector?: string }\n ): Promise<boolean> {\n const memory = (await this.readAllMemories()).find((candidate) => candidate.frontmatter.id === id);\n if (!memory) return false;\n return await this.updateMemoryFromCurrent(memory, newContent, options);\n }\n\n async updateMemoryIfUnchanged(\n expected: MemoryFile,\n newContent: string,\n options?: { supersedes?: string; lineage?: string[]; actor?: string; sourceConnector?: string }\n ): Promise<boolean> {\n const sanitized = sanitizeMemoryContent(newContent);\n const oldIdentity = buildExplicitCaptureDedupKey(\n expected.content,\n expected.frontmatter.category,\n expected.frontmatter.sourceConnector\n );\n const newIdentity = buildExplicitCaptureDedupKey(\n sanitized.text,\n expected.frontmatter.category,\n expected.frontmatter.sourceConnector\n );\n return await this.withTombstoneBlockedCaptureWriteLock(\n async () => {\n const current = await this.readMemoryByPath(expected.path);\n if (!current || current.frontmatter.id !== expected.frontmatter.id) return false;\n if (invalidationCommitFingerprint(current) !== invalidationCommitFingerprint(expected)) return false;\n return await this.updateMemoryFromCurrent(current, newContent, options);\n },\n [buildCapturePathLockIdentity(expected.path), oldIdentity, newIdentity]\n );\n }\n\n\n /**\n * Update frontmatter fields without changing memory content.\n * Returns false when the memory is not found.\n */\n async writeMemoryFrontmatter(\n memory: MemoryFile,\n patch: Partial<MemoryFrontmatter>,\n lifecycle?: MemoryLifecycleEventWriteOptions\n ): Promise<boolean> {\n const beforeStatus = memory.frontmatter.status ?? \"active\";\n // Canonicalize the EFFECTIVE merged entityRef (issue #2213) — an\n // unrelated patch must not rewrite an inherited legacy ref back out.\n const resolveIds = this.currentHistoricalIds();\n const updated: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(\n { ...memory.frontmatter, ...patch },\n resolveIds\n );\n const refIds = typeof updated.entityRef === \"string\" ? resolveIds : null;\n const afterStatus = updated.status ?? \"active\";\n\n const fileContent = `${serializeFrontmatter(this.withOkfType(updated))}\\n\\n${memory.content}\\n`;\n await this.writeTombstoneBlockedFrontmatter(memory, fileContent, updated, async () => {\n this.invalidateAllMemoriesCache();\n // Rebuild the blocked index from the post-write cold-tier cache.\n if (memory.path.includes(`${path.sep}cold${path.sep}`)) {\n this.invalidateColdMemoriesCache();\n }\n });\n const rawMergedRef = typeof patch.entityRef === \"string\" ? patch.entityRef : memory.frontmatter.entityRef;\n if (refIds && typeof rawMergedRef === \"string\") {\n await this.entityRefRepair.repair(memory.path, updated, rawMergedRef, refIds, memory.content, {\n onFailRestore: memory,\n });\n }\n await this.patchHotMemoriesCache({ addedPath: memory.path });\n if (memory.path.includes(`${path.sep}cold${path.sep}`)) {\n this.invalidateColdMemoriesCache();\n }\n try {\n await this.syncFactHashIndexAfterRewrite(memory, {\n ...memory,\n frontmatter: updated,\n });\n } catch (err) {\n log.warn(`storage.writeMemoryFrontmatter completed but failed to update fact hash index: ${err}`);\n }\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\n \"storage.writeMemoryFrontmatter\",\n {\n memoryId: updated.id,\n eventType: this.frontmatterPatchEventType(memory.frontmatter, updated),\n timestamp: updated.updated ?? new Date().toISOString(),\n actor: lifecycle?.actor ?? \"storage.writeMemoryFrontmatter\",\n reasonCode: lifecycle?.reasonCode,\n before: this.summarizeLifecycleState(memory.frontmatter, memory.path),\n after: this.summarizeLifecycleState(updated, memory.path),\n relatedMemoryIds: [\n ...(lifecycle?.relatedMemoryIds ?? []),\n ...(updated.supersededBy ? [updated.supersededBy] : []),\n ...(updated.supersedes ? [updated.supersedes] : []),\n ],\n correlationId: lifecycle?.correlationId,\n },\n lifecycle?.ruleVersion\n );\n if (beforeStatus !== afterStatus) {\n // Status/lifecycle change must bump memory-status so the version-keyed\n // entity/derived caches and peer processes observe it (issue #1902:\n // restored — corpus bump alone doesn't cover status-derived views).\n this.bumpMemoryStatusVersion();\n }\n return true;\n }\n /**\n * Update frontmatter only when the persisted memory still matches the\n * expected semantic snapshot.\n */\n async writeMemoryFrontmatterIfUnchanged(\n expected: MemoryFile,\n patch: Partial<MemoryFrontmatter>,\n lifecycle?: MemoryLifecycleEventWriteOptions\n ): Promise<boolean> {\n return await this.withTombstoneBlockedMemoryPathLock(expected.path, async (current) => {\n if (!current) return false;\n if (invalidationCommitFingerprint(current) !== invalidationCommitFingerprint(expected)) return false;\n return await this.writeMemoryFrontmatter(current, patch, lifecycle);\n });\n }\n\n\n /**\n * Update frontmatter by memory ID.\n * Prefer writeMemoryFrontmatter(memory, patch) in batch loops to avoid full-corpus rescans.\n */\n async updateMemoryFrontmatter(id: string, patch: Partial<MemoryFrontmatter>): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === id);\n if (!memory) return false;\n return this.writeMemoryFrontmatter(memory, patch);\n }\n\n /** Remove memories past their TTL expiresAt date */\n async cleanExpiredTTL(): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n const now = Date.now();\n const deleted: MemoryFile[] = [];\n\n for (const m of memories) {\n if (!m.frontmatter.expiresAt) continue;\n const expiresAt = new Date(m.frontmatter.expiresAt).getTime();\n if (expiresAt >= now) continue;\n const removed = await this.deleteMemoryForMaintenance(m, (current) => {\n const currentExpiresAt = current.frontmatter.expiresAt\n ? new Date(current.frontmatter.expiresAt).getTime()\n : Number.NaN;\n return Number.isFinite(currentExpiresAt) && currentExpiresAt < now;\n });\n if (removed) {\n deleted.push(removed);\n log.debug(`cleaned expired memory ${removed.frontmatter.id} (TTL expired)`);\n }\n }\n\n if (deleted.length > 0) {\n this.invalidateAllMemoriesCache();\n this.bumpMemoryStatusVersion();\n }\n\n return deleted;\n }\n\n async loadBuffer(): Promise<BufferState> {\n const bufferPath = path.join(this.stateDir, \"buffer.json\");\n try {\n const raw = await this.readStorageSecureFile(bufferPath);\n return JSON.parse(raw) as BufferState;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return { turns: [], lastExtractionAt: null, extractionCount: 0 };\n }\n }\n\n async saveBuffer(state: BufferState): Promise<void> {\n await this.ensureDirectories();\n const bufferPath = path.join(this.stateDir, \"buffer.json\");\n await this.writeStorageSecureFile(bufferPath, JSON.stringify(state, null, 2));\n }\n\n async loadMeta(): Promise<MetaState> {\n const metaPath = path.join(this.stateDir, \"meta.json\");\n try {\n const raw = await this.readStorageSecureFile(metaPath);\n const parsed = JSON.parse(raw) as MetaState;\n return {\n extractionCount: typeof parsed.extractionCount === \"number\" ? parsed.extractionCount : 0,\n lastExtractionAt: parsed.lastExtractionAt ?? null,\n lastConsolidationAt: parsed.lastConsolidationAt ?? null,\n totalMemories: typeof parsed.totalMemories === \"number\" ? parsed.totalMemories : 0,\n totalEntities: typeof parsed.totalEntities === \"number\" ? parsed.totalEntities : 0,\n processedExtractionFingerprints: Array.isArray(parsed.processedExtractionFingerprints)\n ? parsed.processedExtractionFingerprints\n .filter(\n (entry) =>\n entry &&\n typeof entry === \"object\" &&\n typeof (entry as { fingerprint?: unknown }).fingerprint === \"string\" &&\n typeof (entry as { observedAt?: unknown }).observedAt === \"string\"\n )\n .map((entry) => ({\n fingerprint: (entry as { fingerprint: string }).fingerprint,\n observedAt: (entry as { observedAt: string }).observedAt,\n }))\n : [],\n extractionRetryState: parseExtractionRetryStateEntries(parsed.extractionRetryState),\n };\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return {\n extractionCount: 0,\n lastExtractionAt: null,\n lastConsolidationAt: null,\n totalMemories: 0,\n totalEntities: 0,\n processedExtractionFingerprints: [],\n };\n }\n }\n\n async saveMeta(state: MetaState): Promise<void> {\n await this.ensureDirectories();\n const metaPath = path.join(this.stateDir, \"meta.json\");\n await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));\n }\n\n async appendMemoryActionEvents(events: MemoryActionEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n const nowIso = new Date().toISOString();\n const payload = events\n .map((event) => {\n const normalized: MemoryActionEvent = {\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n })\n .join(\"\");\n\n await this.appendStorageSecureFile(this.memoryActionsPath, payload);\n return events.length;\n }\n\n async appendMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n // Lock-serialized against compaction; on lock-budget exhaustion the event\n // spills to a durable encrypted pending queue, not dropped (#1910, #2033).\n await appendLifecycleEventsSerialized(\n this.memoryLifecycleLedgerPath,\n (p) => this.appendStorageSecureFile(this.memoryLifecycleLedgerPath, p),\n serializeLifecycleAppendPayload(events),\n { writeSecure: (p, c) => this.writeStorageSecureFile(p, c), readSecure: (p) => this.readStorageSecureFile(p) }\n );\n return events.length;\n }\n\n /** Drain the durable pending lifecycle-append spill into the ledger (#2033);\n * fast no-op when nothing is pending. Returns true when rows were drained. */\n async drainPendingMemoryLifecycleEvents(): Promise<boolean> {\n return drainPendingLifecycleLedgerIfAny(\n this.memoryLifecycleLedgerPath,\n { writeSecure: (p, c) => this.writeStorageSecureFile(p, c), readSecure: (p) => this.readStorageSecureFile(p) },\n (p) => this.appendStorageSecureFile(this.memoryLifecycleLedgerPath, p),\n () => this.ensureDirectories()\n );\n }\n\n /** Offline-sync pre-snapshot drain (#2033): fold pending lifecycle spills into\n * the active ledger and report whether durable rows STILL remain in the\n * offline-sync-EXCLUDED pending queue. The caller aborts the snapshot when\n * `pendingDeferred` is true so append-only rows are never silently omitted. */\n async drainPendingMemoryLifecycleEventsForSync(): Promise<DrainPendingLifecycleForSyncResult> {\n return drainPendingLifecycleLedgerForSync(\n this.memoryLifecycleLedgerPath,\n { writeSecure: (p, c) => this.writeStorageSecureFile(p, c), readSecure: (p) => this.readStorageSecureFile(p) },\n (p) => this.appendStorageSecureFile(this.memoryLifecycleLedgerPath, p),\n () => this.ensureDirectories()\n );\n }\n\n /** Drain pending lifecycle spills for any ledger inside this storage root.\n * The offline CLI uses this path-aware variant for per-namespace ledgers so\n * secure-store encryption and path-bound authentication remain consistent. */\n async drainPendingMemoryLifecycleEventsForSyncAt(ledgerPath: string): Promise<DrainPendingLifecycleForSyncResult> {\n const target = this.assertManagedStoragePath(ledgerPath, \"storage.drainPendingMemoryLifecycleEventsForSyncAt\");\n return drainPendingLifecycleLedgerForSync(\n target,\n {\n writeSecure: (p, c) => this.writeStorageSecureFile(p, c),\n readSecure: (p) => this.readStorageSecureFile(p),\n },\n (payload) => this.appendStorageSecureFile(target, payload),\n async () => {\n await mkdir(path.dirname(target), { recursive: true });\n }\n );\n }\n\n /** Rewrite the ledger through the secure writer (#1910); re-encrypts when unlocked, throws when locked.\n * `targetPath` re-encrypts under a decryptable backup path's own AAD;\n * Buffer content passes through verbatim (#2033). `forceEncrypt` preserves\n * encryption at rest for an already-encrypted ledger/backup even when the\n * `secureStoreEncryptOnWrite` policy is paused, so a compaction never\n * downgrades encrypted state to plaintext (#2033); it never bypasses the lock. */\n async writeMemoryLifecycleLedgerContent(\n content: string | Buffer,\n targetPath: string = this.memoryLifecycleLedgerPath,\n forceEncrypt = false\n ): Promise<void> {\n await this.ensureDirectories();\n await this.writeStorageSecureFile(targetPath, content, forceEncrypt);\n }\n\n async appendBufferSurpriseEvents(events: BufferSurpriseEvent[]): Promise<number> {\n return this.memoryReadStore.appendBufferSurpriseEvents(events);\n }\n\n async readBufferSurpriseEvents(options: { limit?: number } = {}): Promise<BufferSurpriseEvent[]> {\n return this.memoryReadStore.readBufferSurpriseEvents(options);\n }\n\n async appendBehaviorSignals(events: BehaviorSignalEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n // Serialize the whole read→dedup→append→cache-commit transaction per\n // instance (issue #1909 review round 3) so concurrent callers cannot each\n // commit an incomplete dedup set. The chain recovers after a rejection.\n const run = this.behaviorSignalsAppendChain\n .catch(() => undefined)\n .then(() => this.appendBehaviorSignalsUnlocked(events));\n this.behaviorSignalsAppendChain = run.catch(() => undefined);\n return run;\n }\n\n private async appendBehaviorSignalsUnlocked(events: BehaviorSignalEvent[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n\n let existingKeys: Set<string>;\n let identity: { size: number; mtimeMs: number } | null = null;\n try {\n const st = await stat(this.behaviorSignalsPath);\n identity = { size: st.size, mtimeMs: st.mtimeMs };\n if (\n this.behaviorSignalsKeyCache &&\n this.behaviorSignalsKeyCache.identity.size === identity.size &&\n this.behaviorSignalsKeyCache.identity.mtimeMs === identity.mtimeMs\n ) {\n // Cache hit (issue #1909): reuse the dedup set — no read, no parse.\n existingKeys = this.behaviorSignalsKeyCache.keys;\n } else {\n // Foreign change (or first load): rebuild by streaming the file so we\n // never materialize the whole (unbounded) ledger as one string.\n existingKeys = new Set<string>();\n for await (const line of readMaybeEncryptedLines(this.behaviorSignalsPath, () =>\n this.readStorageSecureFile(this.behaviorSignalsPath)\n )) {\n const row = line.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<BehaviorSignalEvent>;\n if (typeof parsed.memoryId === \"string\" && typeof parsed.signalHash === \"string\") {\n existingKeys.add(`${parsed.memoryId}:${parsed.signalHash}`);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n }\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n existingKeys = new Set<string>();\n identity = null;\n }\n\n const nowIso = new Date().toISOString();\n // Collect newly-seen keys in a SEPARATE set — never mutate `existingKeys`\n // (which may alias the cached set) before the append is durable. A failed\n // append must leave the cached dedup set matching what is actually on disk,\n // otherwise a retry would cache-hit a poisoned set and silently drop the\n // events forever (issue #1909 review: pre-durability aliasing).\n const pending = new Set<string>();\n const deduped: BehaviorSignalEvent[] = [];\n for (const event of events) {\n const key = `${event.memoryId}:${event.signalHash}`;\n if (existingKeys.has(key) || pending.has(key)) continue;\n pending.add(key);\n deduped.push({\n ...event,\n timestamp: event.timestamp && event.timestamp.length > 0 ? event.timestamp : nowIso,\n });\n }\n\n if (deduped.length === 0) {\n // Nothing appended — the file identity is unchanged and `existingKeys` was\n // not mutated, so caching it lets the next append hit (issue #1909).\n if (identity) this.behaviorSignalsKeyCache = { identity, keys: existingKeys };\n return 0;\n }\n const payload = deduped.map((event) => `${JSON.stringify(event)}\\n`).join(\"\");\n // May throw (I/O error, SecureStoreLockedError). If it does, we fall through\n // to the caller WITHOUT having touched `existingKeys` or the cache, so the\n // dropped events can be retried.\n await this.appendStorageSecureFile(this.behaviorSignalsPath, payload);\n // Durable now: fold the new keys into the set (in place, O(new keys) — keeps\n // the per-append win). Only cache the refreshed identity if the file grew by\n // EXACTLY our payload — otherwise a foreign writer (another instance/process)\n // interleaved and the file now holds rows whose keys are NOT in existingKeys;\n // caching that identity would let a later same-instance append cache-hit an\n // incomplete set and write duplicates (review round 8 thread 5). On any\n // mismatch, invalidate so the next append reloads from disk.\n for (const key of pending) existingKeys.add(key);\n try {\n const st = await stat(this.behaviorSignalsPath);\n const expectedSize = (identity?.size ?? 0) + Buffer.byteLength(payload, \"utf-8\");\n if (st.size === expectedSize) {\n this.behaviorSignalsKeyCache = {\n identity: { size: st.size, mtimeMs: st.mtimeMs },\n keys: existingKeys,\n };\n } else {\n // Foreign interleave (or encrypted whole-file rewrite): our key set may\n // be missing peer rows — force a reload on the next append.\n this.behaviorSignalsKeyCache = null;\n }\n } catch {\n // Fail-open: force a reload on the next append.\n this.behaviorSignalsKeyCache = null;\n }\n return deduped.length;\n }\n\n async appendReextractJobs(events: ReextractJobRequest[]): Promise<number> {\n if (events.length === 0) return 0;\n await this.ensureDirectories();\n const filePath = path.join(this.stateDir, \"reextract-jobs.jsonl\");\n const lines = events.map((event) => JSON.stringify(event)).join(\"\\n\") + \"\\n\";\n try {\n await this.appendStorageSecureFile(filePath, lines);\n return events.length;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return 0;\n }\n }\n\n async readReextractJobs(limit: number = 200): Promise<ReextractJobRequest[]> {\n const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1000, Math.floor(limit))) : 200;\n const filePath = path.join(this.stateDir, \"reextract-jobs.jsonl\");\n try {\n const raw = await this.readStorageSecureFile(filePath);\n const lines = raw.split(\"\\n\").filter((line) => line.trim().length > 0);\n const parsed: ReextractJobRequest[] = [];\n for (const line of lines) {\n try {\n const record = JSON.parse(line) as Partial<ReextractJobRequest>;\n if (\n typeof record.memoryId !== \"string\" ||\n record.memoryId.length === 0 ||\n typeof record.model !== \"string\" ||\n record.model.length === 0 ||\n typeof record.requestedAt !== \"string\" ||\n record.requestedAt.length === 0 ||\n record.source !== \"cli-migrate\"\n ) {\n continue;\n }\n parsed.push({\n memoryId: record.memoryId,\n model: record.model,\n requestedAt: record.requestedAt,\n source: \"cli-migrate\",\n });\n } catch {\n continue;\n }\n }\n return parsed.slice(-safeLimit);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n }\n\n async readBehaviorSignals(limit: number = 200): Promise<BehaviorSignalEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n try {\n const raw = await this.readStorageSecureFile(this.behaviorSignalsPath);\n const out: BehaviorSignalEvent[] = [];\n const lines = raw.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0 && out.length < cappedLimit; i -= 1) {\n const row = lines[i]?.trim();\n if (!row) continue;\n try {\n const parsed = JSON.parse(row) as Partial<BehaviorSignalEvent>;\n if (\n typeof parsed.timestamp === \"string\" &&\n typeof parsed.namespace === \"string\" &&\n typeof parsed.memoryId === \"string\" &&\n typeof parsed.category === \"string\" &&\n typeof parsed.signalType === \"string\" &&\n typeof parsed.direction === \"string\" &&\n typeof parsed.confidence === \"number\" &&\n typeof parsed.signalHash === \"string\" &&\n typeof parsed.source === \"string\"\n ) {\n out.push(parsed as BehaviorSignalEvent);\n }\n } catch {\n // Ignore malformed rows (fail-open).\n }\n }\n return out.reverse();\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n }\n\n async readMemoryActionEvents(limit: number = 200): Promise<MemoryActionEvent[]> {\n return (await this.readMemoryActionEventRows(limit)).map((row) => row.event);\n }\n\n async readMemoryActionEventRows(limit: number = 200): Promise<Array<{ line: number; event: MemoryActionEvent }>> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0 || Number.isNaN(cappedLimit)) return [];\n\n try {\n return await readMemoryActionEventRowsFromLines(\n readMaybeEncryptedLines(this.memoryActionsPath, () => this.readStorageSecureFile(this.memoryActionsPath)),\n cappedLimit\n );\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n }\n\n async readAllMemoryLifecycleEvents(): Promise<MemoryLifecycleEvent[]> {\n return readAllLifecycleEventsFromLedger(this.memoryLifecycleLedgerPath, (p) => this.readStorageSecureFile(p));\n }\n\n /** Raw decrypted ledger bytes as a Buffer, never a string, so an oversized\n * ledger cannot throw on decode before recovery (#2033). */\n async readMemoryLifecycleLedgerRawBufferForCompaction(): Promise<Buffer> {\n return readMaybeEncryptedFileBuffer(this.memoryLifecycleLedgerPath, this._secureStoreKey, this.baseDir);\n }\n async readAllMemoryLifecycleEventsForCompaction(): Promise<MemoryLifecycleEvent[]> {\n if (!(await probeEncryptedRegularFileHeader(this.memoryLifecycleLedgerPath))) {\n return readAllLifecycleEventsFromLedger(this.memoryLifecycleLedgerPath, (p) => this.readStorageSecureFile(p));\n }\n return readAllLifecycleEventsFromLedgerBuffer(this.memoryLifecycleLedgerPath, (p) =>\n readMaybeEncryptedFileBuffer(p, this._secureStoreKey, this.baseDir)\n );\n }\n\n async readMemoryLifecycleEvents(limit: number = 200): Promise<MemoryLifecycleEvent[]> {\n return readBoundedLifecycleEventsFromLedger(\n this.memoryLifecycleLedgerPath,\n (p) => this.readStorageSecureFile(p),\n limit\n );\n }\n\n async writeCompressionGuidelines(content: string): Promise<void> {\n await this.ensureDirectories();\n await this.writeStorageSecureFile(this.compressionGuidelinesPath, content);\n }\n\n async readCompressionGuidelines(): Promise<string | null> {\n try {\n return await this.readStorageSecureFile(this.compressionGuidelinesPath);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async writeCompressionGuidelineDraft(content: string): Promise<void> {\n await this.ensureDirectories();\n await this.writeStorageSecureFile(this.compressionGuidelineDraftPath, content);\n }\n\n async readCompressionGuidelineDraft(): Promise<string | null> {\n try {\n return await this.readStorageSecureFile(this.compressionGuidelineDraftPath);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async writeCompressionGuidelineOptimizerState(state: CompressionGuidelineOptimizerState): Promise<void> {\n await this.ensureDirectories();\n await this.writeStorageSecureFile(this.compressionGuidelineStatePath, `${JSON.stringify(state, null, 2)}\\n`);\n }\n\n async writeCompressionGuidelineDraftState(state: CompressionGuidelineOptimizerState): Promise<void> {\n await this.ensureDirectories();\n await this.writeStorageSecureFile(this.compressionGuidelineDraftStatePath, `${JSON.stringify(state, null, 2)}\\n`);\n }\n\n async readCompressionGuidelineOptimizerState(): Promise<CompressionGuidelineOptimizerState | null> {\n return this.readCompressionGuidelineStateFile(this.compressionGuidelineStatePath);\n }\n\n async readCompressionGuidelineDraftState(): Promise<CompressionGuidelineOptimizerState | null> {\n return this.readCompressionGuidelineStateFile(this.compressionGuidelineDraftStatePath);\n }\n\n async activateCompressionGuidelineDraft(options?: {\n expectedContentHash?: string;\n expectedGuidelineVersion?: number;\n }): Promise<boolean> {\n const [draftContent, draftState] = await Promise.all([\n this.readCompressionGuidelineDraft(),\n this.readCompressionGuidelineDraftState(),\n ]);\n if (!draftContent || !draftState) return false;\n if (\n typeof options?.expectedContentHash === \"string\" &&\n options.expectedContentHash.length > 0 &&\n draftState.contentHash !== options.expectedContentHash\n ) {\n return false;\n }\n if (\n typeof options?.expectedGuidelineVersion === \"number\" &&\n Number.isFinite(options.expectedGuidelineVersion) &&\n draftState.guidelineVersion !== options.expectedGuidelineVersion\n ) {\n return false;\n }\n if (draftState.contentHash) {\n const contentHash = createHash(\"sha256\").update(draftContent).digest(\"hex\");\n if (contentHash !== draftState.contentHash) return false;\n }\n\n await this.writeCompressionGuidelines(draftContent);\n await this.writeCompressionGuidelineOptimizerState({\n ...draftState,\n activationState: \"active\",\n });\n await Promise.all([\n unlink(this.compressionGuidelineDraftPath).catch(() => undefined),\n unlink(this.compressionGuidelineDraftStatePath).catch(() => undefined),\n ]);\n return true;\n }\n\n private async readCompressionGuidelineStateFile(\n filePath: string\n ): Promise<CompressionGuidelineOptimizerState | null> {\n return this.memoryReadStore.readCompressionGuidelineStateFile(filePath);\n }\n\n async writeIdentityAnchor(content: string): Promise<void> {\n return this.identityContinuityStore.writeIdentityAnchor(content);\n }\n\n async readIdentityAnchor(): Promise<string | null> {\n return this.identityContinuityStore.readIdentityAnchor();\n }\n\n async appendContinuityIncident(input: ContinuityIncidentOpenInput): Promise<ContinuityIncidentRecord> {\n return this.identityContinuityStore.appendContinuityIncident(input);\n }\n\n async readContinuityIncidents(\n limit: number = 200,\n state: \"open\" | \"closed\" | \"all\" = \"all\"\n ): Promise<ContinuityIncidentRecord[]> {\n return this.identityContinuityStore.readContinuityIncidents(limit, state);\n }\n\n async closeContinuityIncident(\n id: string,\n closure: ContinuityIncidentCloseInput\n ): Promise<ContinuityIncidentRecord | null> {\n return this.identityContinuityStore.closeContinuityIncident(id, closure);\n }\n\n async writeIdentityAudit(period: \"weekly\" | \"monthly\", key: string, content: string): Promise<string> {\n return this.identityContinuityStore.writeIdentityAudit(period, key, content);\n }\n\n async readIdentityAudit(period: \"weekly\" | \"monthly\", key: string): Promise<string | null> {\n return this.identityContinuityStore.readIdentityAudit(period, key);\n }\n\n async writeIdentityImprovementLoops(content: string): Promise<void> {\n return this.identityContinuityStore.writeIdentityImprovementLoops(content);\n }\n\n async readIdentityImprovementLoops(): Promise<string | null> {\n return this.identityContinuityStore.readIdentityImprovementLoops();\n }\n\n async readIdentityImprovementLoopRegister(): Promise<ContinuityImprovementLoop[]> {\n return this.identityContinuityStore.readIdentityImprovementLoopRegister();\n }\n\n async upsertIdentityImprovementLoop(input: ContinuityLoopUpsertInput): Promise<ContinuityImprovementLoop> {\n return this.identityContinuityStore.upsertIdentityImprovementLoop(input);\n }\n\n async reviewIdentityImprovementLoop(\n id: string,\n input: ContinuityLoopReviewInput\n ): Promise<ContinuityImprovementLoop | null> {\n return this.identityContinuityStore.reviewIdentityImprovementLoop(id, input);\n }\n\n // ---------------------------------------------------------------------------\n // Question storage\n // ---------------------------------------------------------------------------\n\n private generateId(prefix: string = \"m\"): string {\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 4);\n return `${prefix}-${ts}-${rand}`;\n }\n\n async writeQuestion(question: string, context: string, priority: number): Promise<string> {\n await mkdir(this.questionsDir, { recursive: true });\n\n const id = this.generateId(\"q\");\n const frontmatter: Record<string, unknown> = {\n id,\n created: new Date().toISOString(),\n priority,\n resolved: false,\n ...(this.okfConformanceEnabled() ? { type: OKF_QUESTION_TYPE } : {}),\n };\n\n const content = `---\\n${Object.entries(frontmatter)\n .map(([k, v]) => `${k}: ${JSON.stringify(v)}`)\n .join(\"\\n\")}\\n---\\n\\n${question}\\n\\n**Context:** ${context}\\n`;\n\n const filePath = path.join(this.questionsDir, `${id}.md`);\n await this.writeStorageSecureFile(filePath, content);\n\n log.debug(`wrote question ${id} to ${filePath}`);\n this.invalidateQuestionsCache();\n return id;\n }\n\n async readQuestions(opts?: { unresolvedOnly?: boolean }): Promise<\n Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>\n > {\n return this.memoryReadStore.readQuestions(opts);\n }\n\n /** Invalidate the questions cache (call after writing a question). */\n invalidateQuestionsCache(): void {\n StorageManager.questionsCache.delete(this.questionsDir);\n }\n\n private parseQuestionFile(raw: string, filePath: string) {\n return parseQuestionFileText(raw, filePath);\n }\n\n async resolveQuestion(id: string): Promise<boolean> {\n const questions = await this.readQuestions();\n const q = questions.find((q) => q.id === id);\n if (!q) return false;\n\n let raw = await this.readStorageSecureFile(q.filePath);\n raw = raw.replace(/resolved: false/, \"resolved: true\");\n raw = raw.replace(/---\\n\\n/, `resolvedAt: \"${new Date().toISOString()}\"\\n---\\n\\n`);\n await this.writeStorageSecureFile(q.filePath, raw);\n this.invalidateQuestionsCache();\n log.debug(`resolved question ${id}`);\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Identity file\n // ---------------------------------------------------------------------------\n\n async readIdentity(workspaceDir: string, namespace?: string): Promise<string> {\n const identityPath = this.identityFilePath(workspaceDir, namespace);\n try {\n return await readFile(identityPath, \"utf-8\");\n } catch {\n return \"\";\n }\n }\n\n async writeIdentity(workspaceDir: string, content: string, namespace?: string): Promise<void> {\n const identityPath = this.identityFilePath(workspaceDir, namespace);\n await writeFile(identityPath, content, \"utf-8\");\n log.debug(`wrote consolidated IDENTITY.md (${content.length} chars)`);\n }\n\n /** Max size for IDENTITY.md before we stop appending reflections (15KB leaves room under 20KB gateway limit) */\n private static readonly IDENTITY_MAX_BYTES = 15_000;\n /** Minimum interval between reflections (1 hour) */\n private static readonly REFLECTION_COOLDOWN_MS = 60 * 60 * 1000;\n\n async appendToIdentity(\n workspaceDir: string,\n reflection: string,\n opts?: { hygiene?: FileHygieneConfig; namespace?: string }\n ): Promise<void> {\n const identityPath = this.identityFilePath(workspaceDir, opts?.namespace);\n\n let existing = \"\";\n try {\n existing = await readFile(identityPath, \"utf-8\");\n } catch {\n // File doesn't exist yet\n }\n\n const hygiene = opts?.hygiene;\n const rotateEnabled =\n hygiene?.enabled === true &&\n hygiene.rotateEnabled === true &&\n Array.isArray(hygiene.rotatePaths) &&\n hygiene.rotatePaths.includes(path.basename(identityPath));\n\n // Rotation/splitting: preserve full history, keep the bootstrap file small.\n if (rotateEnabled) {\n const maxBytes = hygiene.rotateMaxBytes;\n if (existing.length > maxBytes) {\n const archiveDir = path.join(workspaceDir, hygiene.archiveDir);\n const { newContent } = await rotateMarkdownFileToArchive({\n filePath: identityPath,\n archiveDir,\n archivePrefix: \"IDENTITY\",\n keepTailChars: hygiene.rotateKeepTailChars,\n });\n await writeFile(identityPath, newContent, \"utf-8\");\n existing = newContent;\n log.info(`rotated IDENTITY.md to archive (size=${existing.length} chars, maxBytes=${maxBytes})`);\n }\n } else {\n // Legacy behavior: skip if file is too large\n if (existing.length > StorageManager.IDENTITY_MAX_BYTES) {\n log.debug(\n `IDENTITY.md is ${existing.length} chars (limit ${StorageManager.IDENTITY_MAX_BYTES}); skipping reflection`\n );\n return;\n }\n }\n\n // Rate-limit: skip if last reflection was less than 1 hour ago\n const lastMatch = existing.match(/## Reflection — (\\S+)\\s*$/m);\n if (lastMatch) {\n // Find the LAST reflection timestamp\n const allMatches = [...existing.matchAll(/## Reflection — (\\S+)/g)];\n if (allMatches.length > 0) {\n const lastTimestamp = allMatches[allMatches.length - 1][1];\n const elapsed = Date.now() - new Date(lastTimestamp).getTime();\n if (elapsed < StorageManager.REFLECTION_COOLDOWN_MS) {\n log.debug(\n `reflection cooldown: ${Math.round(elapsed / 1000)}s since last (need ${StorageManager.REFLECTION_COOLDOWN_MS / 1000}s)`\n );\n return;\n }\n }\n }\n\n const timestamp = new Date().toISOString();\n const section = `\\n\\n## Reflection — ${timestamp}\\n\\n${reflection}\\n`;\n\n await writeFile(identityPath, existing + section, \"utf-8\");\n log.debug(`appended reflection to ${identityPath}`);\n }\n\n async readIdentityReflections(): Promise<string | null> {\n try {\n return await this.readStorageSecureFile(this.identityReflectionsPath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async writeIdentityReflections(content: string): Promise<void> {\n await mkdir(this.identityDir, { recursive: true });\n await this.writeStorageSecureFile(this.identityReflectionsPath, content);\n }\n\n async appendIdentityReflection(reflection: string): Promise<void> {\n let existing = \"\";\n try {\n existing = await this.readStorageSecureFile(this.identityReflectionsPath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n // File doesn't exist yet.\n }\n\n if (existing.length > StorageManager.IDENTITY_MAX_BYTES) {\n log.debug(\n `identity/reflections.md is ${existing.length} chars (limit ${StorageManager.IDENTITY_MAX_BYTES}); skipping reflection`\n );\n return;\n }\n\n const allMatches = [...existing.matchAll(/## Reflection — (\\S+)/g)];\n if (allMatches.length > 0) {\n const lastTimestamp = allMatches[allMatches.length - 1][1];\n const elapsed = Date.now() - new Date(lastTimestamp).getTime();\n if (elapsed < StorageManager.REFLECTION_COOLDOWN_MS) {\n log.debug(\n `reflection cooldown: ${Math.round(elapsed / 1000)}s since last (need ${StorageManager.REFLECTION_COOLDOWN_MS / 1000}s)`\n );\n return;\n }\n }\n\n const timestamp = new Date().toISOString();\n const section = `${existing.trimEnd().length > 0 ? \"\\n\\n\" : \"\"}## Reflection — ${timestamp}\\n\\n${reflection}\\n`;\n await mkdir(this.identityDir, { recursive: true });\n await this.writeStorageSecureFile(this.identityReflectionsPath, `${existing.trimEnd()}${section}`);\n log.debug(`appended namespace-local reflection to ${this.identityReflectionsPath}`);\n }\n\n // Entity-file mutators live on EntityStore (issue #2213): journal-resolved\n // with legacy-file fallback, under the entity-mutation lock.\n async addEntityRelationship(name: string, rel: EntityRelationship): Promise<void> {\n return this.entityStore.addEntityRelationship(name, rel);\n }\n\n async addEntityActivity(name: string, entry: EntityActivityEntry, maxEntries: number): Promise<void> {\n return this.entityStore.addEntityActivity(name, entry, maxEntries);\n }\n\n async addEntityAlias(name: string, alias: string): Promise<void> {\n return this.entityStore.addEntityAlias(name, alias);\n }\n\n async updateEntitySynthesis(\n name: string,\n synthesis: string,\n options: {\n entityUpdatedAt?: string;\n synthesisStructuredFactCount?: number;\n synthesisStructuredFactDigest?: string;\n synthesisTimelineCount?: number;\n updatedAt?: string;\n incrementVersion?: boolean;\n } = {}\n ): Promise<void> {\n return this.entityStore.updateEntitySynthesis(name, synthesis, options);\n }\n\n /** Backward-compatible alias for legacy callers/tests. */\n async updateEntitySummary(name: string, summary: string): Promise<void> {\n const updatedAt = new Date().toISOString();\n const raw = await this.readEntity(name);\n await this.updateEntitySynthesis(name, summary, {\n entityUpdatedAt: updatedAt,\n synthesisTimelineCount: raw ? parseEntityFile(raw, this.entitySchemas).timeline.length : undefined,\n updatedAt,\n });\n }\n\n async readEntitySynthesisQueue(): Promise<string[]> {\n try {\n const raw = await this.readStorageSecureFile(this.entitySynthesisQueuePath);\n const parsed = JSON.parse(raw) as { entityNames?: unknown };\n return Array.isArray(parsed.entityNames)\n ? parsed.entityNames.filter((value): value is string => typeof value === \"string\")\n : [];\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n }\n\n async refreshEntitySynthesisQueue(): Promise<string[]> {\n const entityNames = await this.listEntityNames();\n const entityQueueEntries = await Promise.all(\n entityNames.map(async (entityName) => {\n const raw = await this.readEntity(entityName);\n if (!raw) return null;\n return {\n entityName,\n entity: parseEntityFile(raw, this.entitySchemas),\n };\n })\n );\n const staleEntityNames = entityQueueEntries\n .filter((entry): entry is { entityName: string; entity: EntityFile } => entry !== null)\n .filter(({ entity }) => isEntitySynthesisStale(entity))\n .sort((left, right) => {\n const leftTs = latestEntityTimelineTimestamp(left.entity) ?? \"\";\n const rightTs = latestEntityTimelineTimestamp(right.entity) ?? \"\";\n return compareEntityTimestamps(rightTs, leftTs);\n })\n .map(({ entityName }) => entityName);\n\n await mkdir(this.stateDir, { recursive: true });\n await this.writeStorageSecureFile(\n this.entitySynthesisQueuePath,\n JSON.stringify(\n {\n updatedAt: new Date().toISOString(),\n entityNames: staleEntityNames,\n },\n null,\n 2\n ) + \"\\n\"\n );\n return staleEntityNames;\n }\n\n async removeEntitySynthesisQueueEntries(entityNames: string[]): Promise<void> {\n if (entityNames.length === 0) return;\n const queue = await this.readEntitySynthesisQueue();\n if (queue.length === 0) return;\n const removals = new Set(entityNames);\n const nextQueue = queue.filter((name) => !removals.has(name));\n await mkdir(this.stateDir, { recursive: true });\n await this.writeStorageSecureFile(\n this.entitySynthesisQueuePath,\n JSON.stringify(\n {\n updatedAt: new Date().toISOString(),\n entityNames: nextQueue,\n },\n null,\n 2\n ) + \"\\n\"\n );\n }\n\n async migrateEntityFilesToCompiledTruthTimeline(): Promise<{ total: number; migrated: number }> {\n return this.entityStore.migrateEntityFilesToCompiledTruthTimeline();\n }\n\n // ---------------------------------------------------------------------------\n // Scoring + Knowledge Index (Knowledge Graph v7.0)\n // ---------------------------------------------------------------------------\n\n async readAllEntityFiles(options?: CorpusReadOptions): Promise<EntityFile[]> {\n return this.entityStore.readAllEntityFiles(options);\n }\n\n /**\n * Score an entity based on recency, frequency, activity, type priority,\n * and relationship density.\n *\n * score = recency*0.40 + frequency*0.25 + activity*0.15 + typePriority*0.10 + relationshipDensity*0.10\n */\n static scoreEntity(entity: EntityFile, now: Date): number {\n // Recency: 1 / (1 + daysSince/7) — 7-day half-life\n const updated = entity.updated ? new Date(entity.updated).getTime() : 0;\n const daysSince = Math.max(0, (now.getTime() - updated) / (1000 * 60 * 60 * 24));\n const recency = 1 / (1 + daysSince / 7);\n\n // Frequency: min(facts.length / 20, 1.0)\n const frequency = Math.min(entity.facts.length / 20, 1.0);\n\n // Activity: min(activity.length / 10, 1.0)\n const activityScore = Math.min(entity.activity.length / 10, 1.0);\n\n // Type priority\n const TYPE_PRIORITY: Record<string, number> = {\n person: 1.0,\n project: 0.8,\n company: 0.7,\n tool: 0.6,\n place: 0.5,\n other: 0.3,\n };\n const typePriority = TYPE_PRIORITY[entity.type.toLowerCase()] ?? 0.3;\n\n // Relationship density: min(relationships.length / 8, 1.0)\n const relDensity = Math.min(entity.relationships.length / 8, 1.0);\n\n return recency * 0.4 + frequency * 0.25 + activityScore * 0.15 + typePriority * 0.1 + relDensity * 0.1;\n }\n\n async buildKnowledgeIndex(\n config: PluginConfig,\n overrides?: { maxEntities?: number; maxChars?: number }\n ): Promise<{ result: string; cached: boolean }> {\n return this.entityStore.buildKnowledgeIndex(config, overrides);\n }\n\n /** Invalidate the Knowledge Index cache (call after entity mutations). */\n invalidateKnowledgeIndexCache(): void {\n this.knowledgeIndexCache = null;\n }\n\n // ---------------------------------------------------------------------------\n // Commitment decay\n // ---------------------------------------------------------------------------\n\n /** Max lines for profile.md before LLM consolidation triggers */\n private static readonly PROFILE_MAX_LINES = 300;\n\n async mergeFragmentedEntities(): Promise<number> {\n return this.entityStore.mergeFragmentedEntities();\n }\n\n async cleanExpiredCommitments(decayDays: number): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n const cutoff = Date.now() - decayDays * 24 * 60 * 60 * 1000;\n const deleted: MemoryFile[] = [];\n\n for (const m of memories) {\n if (m.frontmatter.category !== \"commitment\") continue;\n // Only decay commitments that have been marked as resolved/expired\n // (indicated by tags containing \"fulfilled\" or \"expired\")\n const isResolved = m.frontmatter.tags.some((t) => t === \"fulfilled\" || t === \"expired\");\n if (!isResolved) continue;\n\n const updatedAt = new Date(m.frontmatter.updated).getTime();\n if (updatedAt >= cutoff) continue;\n try {\n const removed = await this.deleteMemoryForMaintenance(m, (current) => {\n const currentResolved = current.frontmatter.tags.some((tag) => tag === \"fulfilled\" || tag === \"expired\");\n const currentUpdatedAt = new Date(current.frontmatter.updated).getTime();\n return currentResolved && currentUpdatedAt < cutoff;\n });\n if (removed) {\n deleted.push(removed);\n log.debug(`cleaned expired commitment ${removed.frontmatter.id}`);\n }\n } catch {\n // Ignore\n }\n }\n\n if (deleted.length > 0) {\n this.bumpMemoryStatusVersion();\n }\n\n return deleted;\n }\n\n // ---------------------------------------------------------------------------\n // Access Tracking (Phase 1A)\n // ---------------------------------------------------------------------------\n\n /**\n * Flush batched access tracking updates to disk.\n * Called during consolidation or when buffer exceeds max size.\n */\n async flushAccessTracking(entries: AccessTrackingEntry[]): Promise<number> {\n if (entries.length === 0) return 0;\n\n const memories = await this.readAllMemories();\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n const memoryPathMap = new Map(memories.map((m) => [path.resolve(m.path), m]));\n let updated = 0;\n // Capture the corpus version + warmth BEFORE writing so we can patch the hot\n // entries in place and then re-key them to the version this flush produces\n // (issue #1902). Access-tracking flush is batched (consolidation / buffer\n // full), not per-recall, so the single corpus bump below is cheap.\n const prevVersion = this.getMemoryCorpusVersion();\n // Snapshot the secure-store key identity once (Cursor Medium #1902), mirroring\n // readAllMemories/patchHotMemoriesCache: a mid-flush setSecureStoreKey change\n // would otherwise let loop patches or the re-keyed entry be stored under a\n // different identity than the one that decrypted this corpus.\n const keyId = this.hotCacheKeyId();\n const warm =\n this.hotMemoriesCacheEnabled &&\n getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;\n // Record each applied patch so the end-of-flush re-key can re-apply them on\n // top of whatever is cached at prevVersion — robust to a concurrent scan\n // that republished an UNpatched corpus mid-flush (Cursor Medium #1902).\n const appliedPatches = new Map<string, { accessCount: number; lastAccessed: string }>();\n\n for (const entry of entries) {\n const memory = entry.memoryPath\n ? memoryPathMap.get(path.resolve(entry.memoryPath))\n : memoryMap.get(entry.memoryId);\n if (!memory) continue;\n\n try {\n const applied = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {\n if (current?.frontmatter.id !== entry.memoryId) return null;\n const rowIds = this.currentHistoricalIds();\n const newFm: MemoryFrontmatter = entityRefs.canonicalizeEntityRefOption(\n { ...current.frontmatter, accessCount: entry.newCount, lastAccessed: entry.lastAccessed },\n rowIds\n );\n const fileContent = `${serializeFrontmatter(this.withOkfType(newFm))}\\n\\n${current.content}\\n`;\n await this.writeTombstoneBlockedFrontmatter(current, fileContent, newFm);\n if (typeof current.frontmatter.entityRef === \"string\") {\n await this.entityRefRepair.repair(\n current.path,\n newFm,\n current.frontmatter.entityRef,\n rowIds,\n current.content,\n { onFailRestore: current }\n );\n }\n return { current, newFm };\n });\n if (applied === null) continue;\n if (warm) {\n updateCacheOnWrite(this.baseDir, { ...applied.current, frontmatter: applied.newFm }, keyId);\n }\n appliedPatches.set(path.resolve(memory.path), {\n accessCount: entry.newCount,\n lastAccessed: entry.lastAccessed,\n });\n updated++;\n } catch (err) {\n log.debug(`failed to update access tracking for ${entry.memoryId}: ${err}`);\n }\n }\n\n if (updated > 0) {\n // Advance the corpus sentinel so PEER processes rescan and don't overwrite\n // this process's increments (Codex P2): WorkspaceOpsCoordinator computes\n // existingCount + update.count from the cached value, so a peer serving a\n // stale count would undercount. Re-key the locally patched entries to the\n // produced version so this process stays warm — only when our bump was\n // exclusive and still the current sentinel; otherwise a peer also wrote\n // and we must let the next read rescan.\n const { produced, exclusive } = this.bumpMemoryCorpusVersionExclusive();\n // Drop the in-flight read slot after the bump (parity with\n // patchHotMemoriesCache, Cursor Medium #1902): a readAllMemories scan that\n // started before the flush would otherwise keep awaiting a pre-flush scan\n // and could republish it at the old version, clobbering our patches. New\n // readers now start a fresh scan at the bumped version.\n deleteInFlightReadsForDir(this.baseDir);\n if (\n warm &&\n exclusive &&\n produced === prevVersion + 1 &&\n this.getMemoryCorpusVersion() === produced &&\n this.hotCacheKeyId() === keyId\n ) {\n const cur = getCachedMemories(this.baseDir, prevVersion, keyId);\n if (cur) {\n // Re-apply our patches on top of whatever is cached at prevVersion\n // before re-keying (Cursor Medium #1902): a concurrent readAllMemories\n // that finished in the prevVersion epoch may have republished a full\n // UNpatched corpus via its publish guard, clobbering our in-loop\n // updateCacheOnWrite patches. Re-applying is idempotent and makes the\n // re-key robust to that race; the publish guard blocks any scan\n // finishing AFTER our bump, so this is the only window.\n const reapplied = cur.map((m) => {\n const patch = appliedPatches.get(path.resolve(m.path));\n return patch\n ? {\n ...m,\n frontmatter: { ...m.frontmatter, accessCount: patch.accessCount, lastAccessed: patch.lastAccessed },\n }\n : m;\n });\n setCachedMemories(this.baseDir, reapplied, produced, keyId, this.hotCacheTtlMs());\n }\n }\n // Evict the derived (episode/rule) + global (QMD recall/search) layers,\n // mirroring patchHotMemoriesCache (Cursor Medium, #1902). The hot layer is\n // patched + re-keyed above; without this the derived caches linger at\n // prevVersion and the QMD recall bundle keeps pre-flush accessCount-based\n // boost ordering until an unrelated mutation invalidates them.\n invalidateDerivedAndGlobalForDir(this.baseDir);\n log.debug(`flushed access tracking for ${updated} memories`);\n }\n return updated;\n }\n\n async getMemoryById(id: string): Promise<MemoryFile | null> {\n const memories = await this.readAllMemories();\n return memories.find((m) => m.frontmatter.id === id) ?? null;\n }\n\n async getMemoryByIdIncludingArchived(id: string): Promise<MemoryFile | null> {\n const active = await this.getMemoryById(id);\n return active ?? (await this.readAllColdMemories()).find((memory) => memory.frontmatter.id === id) ??\n (await this.readArchivedMemories()).find((memory) => memory.frontmatter.id === id) ?? null;\n }\n\n /** Resolve existing active memory IDs through a lightweight directory scan. */\n async findExistingMemoryPaths(\n ids: string[],\n preferredPaths: Map<string, string[]> = new Map()\n ): Promise<Map<string, string[]>> {\n if (ids.length === 0) return new Map();\n const wantedIds = new Set(ids);\n const filePaths = await this.collectActiveMemoryPaths();\n const pathsById = new Map<string, string[]>();\n const filePathsById = new Map<string, string[]>();\n for (const filePath of filePaths) {\n const memoryId = path.basename(filePath, \".md\");\n if (!wantedIds.has(memoryId)) continue;\n const paths = filePathsById.get(memoryId) ?? [];\n paths.push(filePath);\n filePathsById.set(memoryId, paths);\n }\n for (const id of wantedIds) {\n const existingPaths = filePathsById.get(id) ?? [];\n const preferred = preferredPaths.get(id) ?? [];\n const preferredMatches: string[] = [];\n for (const preferredPath of preferred) {\n const directCandidates = new Set(qmdResultPathCandidates(this.baseDir, preferredPath));\n const directMatch = existingPaths.find((filePath) => directCandidates.has(path.resolve(filePath)));\n if (directMatch) {\n preferredMatches.push(directMatch);\n continue;\n }\n\n const candidates = new Set<string>();\n const parts = qmdCollectionPathParts(preferredPath);\n if (parts) {\n for (const candidate of qmdResultPathCandidates(this.baseDir, parts.relativePath)) {\n candidates.add(candidate);\n }\n }\n const match = existingPaths.find((filePath) => candidates.has(path.resolve(filePath)));\n if (match) preferredMatches.push(match);\n }\n if (preferredMatches.length > 0) {\n pathsById.set(id, preferredMatches);\n } else if (existingPaths.length > 0) {\n pathsById.set(id, existingPaths);\n }\n }\n return pathsById;\n }\n\n /**\n * Check which of the given memory IDs actually exist on disk.\n */\n async filterExistingMemoryIds(ids: string[]): Promise<Set<string>> {\n return new Set((await this.findExistingMemoryPaths(ids)).keys());\n }\n\n async getProjectedMemoryState(id: string): Promise<MemoryProjectionCurrentState | null> {\n const projected = readProjectedMemoryState(this.baseDir, id);\n if (projected) return projected;\n warnProjectionFallback(this.baseDir, \"getProjectedMemoryState\");\n const active = await this.getMemoryById(id);\n if (active) return this.toProjectedCurrentState(active, \"active\");\n\n const archived = (await this.readArchivedMemories()).find((memory) => memory.frontmatter.id === id);\n if (!archived) return null;\n\n return this.toProjectedCurrentState(archived, \"archived\");\n }\n\n async browseProjectedMemories(options: ProjectedMemoryBrowseOptions): Promise<ProjectedMemoryBrowsePage | null> {\n return (\n readProjectedMemoryBrowse(this.baseDir, options) ??\n warnProjectionFallback(this.baseDir, \"browseProjectedMemories\")\n );\n }\n\n async getProjectedGovernanceRecord(): Promise<ReturnType<typeof readProjectedGovernanceRecord>> {\n return readProjectedGovernanceRecord(this.baseDir);\n }\n\n private toProjectedCurrentState(memory: MemoryFile, fallbackStatus: MemoryStatus): MemoryProjectionCurrentState {\n const pathRel = toMemoryPathRel(this.baseDir, memory.path);\n return {\n memoryId: memory.frontmatter.id,\n category: memory.frontmatter.category,\n status: inferCurrentStateStatus(memory.frontmatter, pathRel, fallbackStatus),\n lifecycleState: memory.frontmatter.lifecycleState,\n path: memory.path,\n pathRel,\n created: memory.frontmatter.created,\n updated: memory.frontmatter.updated,\n archivedAt: memory.frontmatter.archivedAt,\n supersededAt: memory.frontmatter.supersededAt,\n entityRef: memory.frontmatter.entityRef,\n source: memory.frontmatter.source,\n confidence: memory.frontmatter.confidence,\n confidenceTier: memory.frontmatter.confidenceTier,\n memoryKind: memory.frontmatter.memoryKind,\n accessCount: memory.frontmatter.accessCount,\n lastAccessed: memory.frontmatter.lastAccessed,\n tags: normalizeProjectionTags(memory.frontmatter.tags),\n preview: normalizeProjectionPreview(memory.content),\n privateRecord: isSupportPassportPrivateMemory(memory),\n };\n }\n\n async getMemoryTimeline(memoryId: string, limit: number = 200): Promise<MemoryLifecycleEvent[]> {\n const cappedLimit = Math.max(0, Math.floor(limit));\n if (cappedLimit === 0) return [];\n\n const projected = readProjectedMemoryTimeline(this.baseDir, memoryId, cappedLimit);\n if (projected && projected.length > 0) return projected;\n return this.projectionLedgerLagManager.resolveTimelineWithLag({\n baseDir: this.baseDir,\n ledgerPath: this.memoryLifecycleLedgerPath,\n memoryId,\n cappedLimit,\n readSecureFile: (p) => this.readStorageSecureFile(p),\n projectionAge: () => formatProjectionAge(readProjectionRebuiltAt(this.baseDir)),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Chunking (Phase 2A)\n // ---------------------------------------------------------------------------\n\n /**\n * Write a memory chunk with parent reference.\n * Chunk IDs follow format: {parentId}-chunk-{index}\n */\n async writeChunk(\n parentId: string,\n chunkIndex: number,\n chunkTotal: number,\n category: MemoryCategory,\n content: string,\n options: {\n confidence?: number;\n tags?: string[];\n entityRef?: string;\n source?: string;\n importance?: ImportanceScore;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n validAt?: string;\n /** Lifecycle status (issue #1576): pending_review chunks stay out of active recall. */\n status?: import(\"./types.js\").MemoryStatus;\n /**\n * Tombstone block provenance (issue #1645): when the parent fact was\n * tombstone-blocked, propagate the tombstone id onto each chunk so an\n * independently-surfaced chunk (memory_get/x-ray/doctor) reveals the block\n * and the chunk stays pending_review, never an active resurrection.\n */\n blockedBy?: string;\n /** Faithfulness gate verdict (issue #1576), propagated from the parent fact. */\n faithfulness?: import(\"./types.js\").FaithfulnessFrontmatter;\n /** Claim-level provenance spans (issue #1575 PR 2), propagated from the parent fact so a chunk surfaced independently (memory_get/x-ray) preserves them (chatgpt-codex-connector thread Ocvmo). */\n sources?: ProvenanceSource[];\n /** Coarse provenance tag (issue #1575 PR 2), propagated from the parent. */\n provenance?: \"verified\" | \"unverified\" | \"none\";\n // Issue #1578 — bi-temporal bounds + ingestion provenance propagated from\n // the parent fact so an independently-surfaced chunk expires at the same\n // invalid_at window and carries the same observed-at anchor.\n invalidAt?: string;\n observedAt?: string;\n eventTimeSource?: \"extracted\" | \"assumed\";\n sourceConnector?: string;\n origin?: string;\n toolScoped?: true;\n } = {}\n ): Promise<string> {\n await this.ensureDirectories();\n const rawEntityRef = options.entityRef;\n let refIds = typeof options.entityRef === \"string\" ? this.currentHistoricalIds() : null;\n if (refIds) options = entityRefs.canonicalizeEntityRefOption(options, refIds);\n const now = new Date();\n const today = now.toISOString().slice(0, 10);\n const id = `${parentId}-chunk-${chunkIndex}`;\n const conf = options.confidence ?? 0.8;\n const tier = confidenceTier(conf);\n const validAt = normalizeMemoryWriteTimestamp(\"validAt\", options.validAt);\n const chunkInvalidAt = normalizeMemoryWriteTimestamp(\"invalidAt\", options.invalidAt);\n const chunkObservedAt = normalizeMemoryWriteTimestamp(\"observedAt\", options.observedAt);\n const sanitized = sanitizeMemoryContent(content);\n if (!sanitized.clean) {\n log.warn(`chunk content sanitized for ${id}; violations=${sanitized.violations.join(\", \")}`);\n }\n\n const fm: MemoryFrontmatter = {\n id,\n category,\n created: now.toISOString(),\n updated: now.toISOString(),\n source: options.source ?? \"chunking\",\n confidence: conf,\n confidenceTier: tier,\n tags: options.tags ?? [],\n entityRef: options.entityRef,\n importance: options.importance,\n parentId,\n chunkIndex,\n chunkTotal,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n memoryKind: options.memoryKind,\n valid_at: validAt,\n invalid_at: chunkInvalidAt,\n observedAt: chunkObservedAt,\n eventTimeSource: options.eventTimeSource,\n ...(options.status ? { status: options.status } : {}),\n ...(options.blockedBy ? { blockedBy: options.blockedBy } : {}),\n ...(options.faithfulness ? { faithfulness: options.faithfulness } : {}),\n ...(options.sources ? { sources: options.sources } : {}),\n ...(options.provenance ? { provenance: options.provenance } : {}),\n ...(options.sourceConnector ? { sourceConnector: options.sourceConnector } : {}),\n ...(options.origin ? { origin: parseOriginClass(options.origin) } : {}),\n ...(options.toolScoped ||\n withholdToolScopedFromSharedNamespace({\n content: sanitized.text,\n sourceConnector: options.sourceConnector,\n })\n ? { toolScoped: true as const }\n : {}),\n };\n\n const filePath = await this.resolveCategoryWritePath(category, id, today);\n const fileContent = `${serializeFrontmatter(this.withOkfType(fm))}\\n\\n${sanitized.text}\\n`;\n\n const written = await this.writeTombstoneBlockedChunk(\n filePath,\n fileContent,\n fm,\n sanitized.text,\n () => this.findExistingTombstoneBlockedMemory(sanitized.text, category, fm.sourceConnector),\n async (priorChunk) => {\n if (refIds && typeof rawEntityRef === \"string\") {\n await this.entityRefRepair.repair(filePath, fm, rawEntityRef, refIds, sanitized.text, {\n regateFact: true,\n ...(priorChunk ? { onFailRestore: priorChunk } : { onFailRemove: filePath }),\n });\n }\n // Keep the version-keyed hot-memories cache coherent with the new chunk\n // file (issue #1902) — same single-file patch path writeMemory uses.\n await this.patchHotMemoriesCache({ addedPath: filePath }, \"memory-create\");\n log.debug(`wrote chunk ${id} (${chunkIndex + 1}/${chunkTotal}) to ${filePath}`);\n }\n );\n return written;\n }\n\n /**\n * Get all chunks for a given parent memory ID.\n * Returns chunks sorted by chunkIndex.\n */\n async getChunksForParent(parentId: string): Promise<MemoryFile[]> {\n const memories = await this.readAllMemories();\n return memories\n .filter((m) => m.frontmatter.parentId === parentId)\n .sort((a, b) => (a.frontmatter.chunkIndex ?? 0) - (b.frontmatter.chunkIndex ?? 0));\n }\n\n async supersedeMemory(\n oldMemoryId: string,\n newMemoryId: string,\n reason: string,\n supersessionMetadata?: Pick<MemoryFrontmatter, \"supersessionCause\" | \"invalidatedBy\">,\n options: {\n actor?: string; requireActive?: boolean; acceptExactReplay?: boolean;\n expectedSnapshot?: Pick<MemoryFile, \"content\" | \"frontmatter\"> & Partial<Pick<MemoryFile, \"path\">>;\n audit?: SupersessionAuditOptions;\n } = {},\n ): Promise<boolean> {\n const matchesSupersession = (memory: MemoryFile): boolean =>\n memory.frontmatter.status === \"superseded\" &&\n memory.frontmatter.supersededBy === newMemoryId &&\n (supersessionMetadata === undefined ||\n (memory.frontmatter.supersessionCause === supersessionMetadata.supersessionCause &&\n memory.frontmatter.invalidatedBy === supersessionMetadata.invalidatedBy));\n const isExactReplay = (memory: MemoryFile): boolean =>\n options.acceptExactReplay === true && matchesSupersession(memory);\n let oldMemory: MemoryFile | undefined;\n if (options.expectedSnapshot?.path) {\n const selected = await this.readMemoryByPath(options.expectedSnapshot.path);\n if (!selected || selected.frontmatter.id !== oldMemoryId) {\n return false;\n }\n if (\n invalidationCommitFingerprint(selected) !== invalidationCommitFingerprint(options.expectedSnapshot) &&\n !isExactReplay(selected)\n ) {\n return false;\n }\n oldMemory = selected;\n } else {\n const memories = [\n ...(await this.readAllMemories()),\n ...(await this.readAllColdMemories()),\n ...(await this.readArchivedMemories()),\n ];\n const candidates = memories.filter((memory) => memory.frontmatter.id === oldMemoryId);\n oldMemory =\n candidates.find(\n (memory) =>\n inferMemoryStatus(memory.frontmatter, toMemoryPathRel(this.baseDir, memory.path)) === \"active\",\n ) ??\n candidates.find(isExactReplay) ??\n candidates[0];\n if (\n oldMemory &&\n options.expectedSnapshot &&\n invalidationCommitFingerprint(oldMemory) !== invalidationCommitFingerprint(options.expectedSnapshot) &&\n !isExactReplay(oldMemory)\n ) {\n return false;\n }\n }\n if (!oldMemory) return false;\n const requireActiveAtWrite =\n options.requireActive === true ||\n inferMemoryStatus(oldMemory.frontmatter, toMemoryPathRel(this.baseDir, oldMemory.path)) === \"active\";\n\n const operationId = createHash(\"sha256\")\n .update(\n JSON.stringify({\n oldMemoryId,\n newMemoryId,\n reason,\n supersessionMetadata: supersessionMetadata ?? null,\n }),\n )\n .digest(\"hex\");\n const initialNow = new Date().toISOString();\n let currentBefore = oldMemory;\n let updatedFm = oldMemory.frontmatter;\n let exactReplay = false;\n\n try {\n const written = await this.withTombstoneBlockedMemoryPathLock(oldMemory.path, async (current) => {\n if (current?.frontmatter.id !== oldMemoryId) return false;\n if (matchesSupersession(current)) {\n currentBefore = current;\n updatedFm = current.frontmatter;\n return options.acceptExactReplay === true ? \"exact-replay\" : false;\n }\n if (\n options.expectedSnapshot &&\n invalidationCommitFingerprint(current) !== invalidationCommitFingerprint(options.expectedSnapshot)\n ) {\n return false;\n }\n if (\n current.frontmatter.supersededBy !== undefined ||\n (requireActiveAtWrite &&\n inferMemoryStatus(current.frontmatter, toMemoryPathRel(this.baseDir, current.path)) !== \"active\")\n ) {\n return false;\n }\n currentBefore = current;\n const refIdsAtWrite = this.currentHistoricalIds();\n updatedFm = entityRefs.canonicalizeEntityRefOption(\n {\n ...current.frontmatter,\n ...supersessionMetadata,\n status: \"superseded\",\n supersededBy: newMemoryId,\n supersededAt: initialNow,\n updated: initialNow,\n },\n refIdsAtWrite\n );\n const fileContent = `${serializeFrontmatter(this.withOkfType(updatedFm))}\\n\\n${current.content}\\n`;\n await this.writeTombstoneBlockedFrontmatter(current, fileContent, updatedFm);\n if (this.isColdOrArchiveTierPath(current.path)) this.invalidateColdMemoriesCache();\n if (typeof current.frontmatter.entityRef === \"string\") {\n await this.entityRefRepair.repair(\n current.path,\n updatedFm,\n current.frontmatter.entityRef,\n refIdsAtWrite,\n current.content,\n { onFailRestore: current }\n );\n }\n return true;\n });\n if (!written) return false;\n exactReplay = written === \"exact-replay\";\n if (exactReplay && typeof updatedFm.entityRef === \"string\") {\n await this.entityRefRepair.repair(\n currentBefore.path,\n updatedFm,\n updatedFm.entityRef,\n this.currentHistoricalIds(),\n currentBefore.content,\n { onFailRestore: currentBefore },\n );\n }\n const supersededAt = updatedFm.supersededAt ?? initialNow;\n const beforeState = this.summarizeLifecycleState(\n currentBefore.frontmatter,\n currentBefore.path,\n );\n const afterState = this.summarizeLifecycleState(updatedFm, currentBefore.path);\n const sideEffectsComplete = await runSupersessionSideEffects({\n oldMemoryId,\n newMemoryId,\n reason,\n now: supersededAt,\n operationId,\n exactReplay,\n currentBefore,\n updatedFm,\n actor: options.actor, audit: options.audit,\n citationTemplate: this.citationTemplate,\n correctionsDir: this.correctionsDir,\n readMemoryByPath: (filePath) => this.readMemoryByPath(filePath),\n isColdOrArchiveTierPath: (memoryPath) => this.isColdOrArchiveTierPath(memoryPath),\n invalidateColdMemoriesCache: () => this.invalidateColdMemoriesCache(),\n invalidateAllMemoriesCache: () => this.invalidateAllMemoriesCache(),\n bumpMemoryCorpusVersion: () => this.bumpMemoryCorpusVersion(),\n appendLifecycleEvent: async () => {\n let lifecycleEvents: MemoryLifecycleEvent[] = [];\n try {\n lifecycleEvents = await this.getMemoryTimeline(oldMemoryId, 200);\n } catch (error) {\n log.warn(`supersession lifecycle replay check failed for ${oldMemoryId}: ${error}`);\n }\n if (\n lifecycleEvents.some(\n (event) =>\n event.memoryId === oldMemoryId &&\n event.eventType === \"superseded\" &&\n (event.correlationId === operationId ||\n (event.correlationId === undefined &&\n event.reasonCode === reason &&\n event.timestamp === supersededAt &&\n event.relatedMemoryIds?.includes(newMemoryId))),\n )\n ) {\n return;\n }\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.supersedeMemory\", {\n memoryId: oldMemoryId,\n eventType: \"superseded\",\n timestamp: supersededAt,\n actor: options.actor ?? \"storage.supersedeMemory\",\n reasonCode: reason,\n before: exactReplay ? { ...beforeState, status: \"active\" } : beforeState,\n after: afterState,\n relatedMemoryIds: [newMemoryId],\n correlationId: operationId,\n });\n },\n bumpMemoryStatusVersion: () => this.bumpMemoryStatusVersion(),\n hasExactTombstone: (input) => this.hasExactTombstone(input),\n appendTombstone: (input) => this.appendTombstone(input),\n writeSealedMemory: (envelope, extras) => this.writeSealedMemory(envelope, extras),\n });\n return sideEffectsComplete || options.acceptExactReplay !== true;\n } catch (err) {\n log.error(`failed to supersede memory ${oldMemoryId}:`, err);\n return false;\n }\n }\n\n private get summariesDir(): string {\n return path.join(this.baseDir, \"summaries\");\n }\n\n async writeSummary(summary: MemorySummary): Promise<void> {\n await mkdir(this.summariesDir, { recursive: true });\n const filePath = path.join(this.summariesDir, `${summary.id}.json`);\n await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));\n log.debug(`wrote summary ${summary.id}`);\n }\n\n async readSummaries(): Promise<MemorySummary[]> {\n try {\n const files = await readdir(this.summariesDir);\n const summaries: MemorySummary[] = [];\n\n for (const file of files) {\n if (!file.endsWith(\".json\")) continue;\n const filePath = path.join(this.summariesDir, file);\n const raw = await this.readStorageSecureFile(filePath);\n summaries.push(JSON.parse(raw) as MemorySummary);\n }\n\n return summaries;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n }\n\n async archiveMemories(memoryIds: string[], summaryId: string): Promise<number> {\n const memories = await this.readAllMemories();\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n let archived = 0;\n\n for (const id of memoryIds) {\n const memory = memoryMap.get(id);\n if (!memory) continue;\n\n const now = new Date().toISOString();\n let currentBefore = memory;\n let updatedFm = memory.frontmatter;\n\n try {\n const written = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {\n if (current?.frontmatter.id !== id) return false;\n currentBefore = current;\n const rowIds = this.currentHistoricalIds();\n updatedFm = entityRefs.canonicalizeEntityRefOption(\n { ...current.frontmatter, status: \"archived\", archivedAt: now, updated: now },\n rowIds\n );\n const fileContent = `${serializeFrontmatter(this.withOkfType(updatedFm))}\\n\\n${current.content}\\n`;\n await this.writeTombstoneBlockedFrontmatter(current, fileContent, updatedFm);\n if (typeof current.frontmatter.entityRef === \"string\") {\n await this.entityRefRepair.repair(\n current.path,\n updatedFm,\n current.frontmatter.entityRef,\n rowIds,\n current.content,\n { onFailRestore: current }\n );\n }\n return true;\n });\n if (!written) continue;\n // Per-file corpus bump BEFORE the awaited lifecycle append (#1902):\n // the end-of-loop status bump fires only after the whole batch.\n this.bumpMemoryCorpusVersion();\n await this.appendGeneratedMemoryLifecycleEventFailOpen(\"storage.archiveMemories\", {\n memoryId: id,\n eventType: \"archived\",\n timestamp: updatedFm.archivedAt ?? updatedFm.updated,\n actor: \"storage.archiveMemories\",\n reasonCode: `summary:${summaryId}`,\n before: this.summarizeLifecycleState(currentBefore.frontmatter, currentBefore.path),\n after: this.summarizeLifecycleState(updatedFm, currentBefore.path),\n relatedMemoryIds: [summaryId],\n });\n archived++;\n } catch {\n // Ignore individual failures\n }\n }\n\n if (archived > 0) {\n this.bumpMemoryStatusVersion();\n log.debug(`archived ${archived} memories for summary ${summaryId}`);\n }\n return archived;\n }\n\n async saveTopics(topics: TopicScore[]): Promise<void> {\n const metaPath = path.join(this.stateDir, \"topics.json\");\n await mkdir(this.stateDir, { recursive: true });\n await this.writeStorageSecureFile(\n metaPath,\n JSON.stringify({ topics, updatedAt: new Date().toISOString() }, null, 2)\n );\n log.debug(`saved ${topics.length} topic scores`);\n }\n\n async loadTopics(): Promise<{ topics: TopicScore[]; updatedAt: string | null }> {\n const metaPath = path.join(this.stateDir, \"topics.json\");\n try {\n const raw = await this.readStorageSecureFile(metaPath);\n return JSON.parse(raw) as { topics: TopicScore[]; updatedAt: string | null };\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return { topics: [], updatedAt: null };\n }\n }\n\n async addLinksToMemory(\n memoryId: string,\n links: MemoryLink[],\n lifecycle?: MemoryLifecycleEventWriteOptions\n ): Promise<boolean> {\n const memories = await this.readAllMemories();\n const memory = memories.find((m) => m.frontmatter.id === memoryId);\n if (!memory) return false;\n\n const existingLinks = memory.frontmatter.links ?? [];\n const mergedLinks = [...existingLinks];\n\n for (const link of links) {\n if (!mergedLinks.some((l) => l.targetId === link.targetId && l.linkType === link.linkType)) {\n mergedLinks.push(link);\n }\n }\n\n try {\n await this.writeMemoryFrontmatter(\n memory,\n {\n links: mergedLinks,\n updated: new Date().toISOString(),\n },\n lifecycle\n );\n log.debug(`added ${links.length} links to memory ${memoryId}`);\n return true;\n } catch (err) {\n log.error(`failed to add links to memory ${memoryId}:`, err);\n return false;\n }\n }\n\n private summarizeLifecycleState(frontmatter: MemoryFrontmatter, filePath: string): MemoryLifecycleStateSummary {\n return {\n category: frontmatter.category,\n path: filePath,\n status: frontmatter.status ?? \"active\",\n lifecycleState: frontmatter.lifecycleState,\n };\n }\n\n private frontmatterPatchEventType(before: MemoryFrontmatter, after: MemoryFrontmatter): MemoryLifecycleEventType {\n const beforeStatus = before.status ?? \"active\";\n const afterStatus = after.status ?? \"active\";\n if (beforeStatus !== \"archived\" && afterStatus === \"archived\") return \"archived\";\n if (beforeStatus !== \"superseded\" && afterStatus === \"superseded\") return \"superseded\";\n if (beforeStatus !== \"rejected\" && afterStatus === \"rejected\") return \"rejected\";\n if (beforeStatus !== \"active\" && afterStatus === \"active\") {\n return \"restored\";\n }\n return \"updated\";\n }\n\n private async appendGeneratedMemoryLifecycleEvent(\n input: Omit<MemoryLifecycleEvent, \"eventId\" | \"ruleVersion\">,\n ruleVersion = \"memory-lifecycle-ledger.v1\"\n ): Promise<void> {\n await this.appendMemoryLifecycleEvents([\n {\n ...input,\n eventId: this.generateId(\"mle\"),\n ruleVersion,\n },\n ]);\n }\n\n private async appendGeneratedMemoryLifecycleEventFailOpen(\n operation: string,\n input: Omit<MemoryLifecycleEvent, \"eventId\" | \"ruleVersion\">,\n ruleVersion?: string\n ): Promise<void> {\n try {\n await this.appendGeneratedMemoryLifecycleEvent(input, ruleVersion);\n } catch (appendErr) {\n log.warn(`${operation} completed but failed to append lifecycle event: ${appendErr}`);\n }\n }\n}\n","/**\n * Shared preference-drift type surfaces (issue #2371).\n *\n * These live in the preferences module rather than in `types.ts` so the\n * cross-cutting fields drift detection introduces are declared next to the\n * subsystem that owns them, and `types.ts` composes them through `extends`\n * instead of growing another inline block.\n */\n\nimport type { DriftDetectionConfig } from \"./drift-config.js\";\n\n/**\n * Drift verdict persisted on `preference` memories. `corroborated` is\n * deliberately NOT a member: a corroborated preference clears `driftState` and\n * stamps `lastCorroborated`, so the stored enum only carries a negative\n * verdict.\n */\nexport type MemoryDriftState = \"stale\" | \"drifted\";\n\n/**\n * Derived drift provenance stamped by the scan AFTER a memory exists — never\n * supplied at compose time, which is why these fields stay outside the sealed\n * write envelope for exactly the reason `mw_success` / `mw_fail` do.\n *\n * Mixed into `MemoryFrontmatter`.\n */\nexport interface MemoryDriftProvenance {\n /**\n * `stale` means the lookback window held no corroborating evidence either\n * way; `drifted` means recent evidence pointed away from the preference and\n * a review item was opened. Absent means \"not classified\".\n */\n driftState?: MemoryDriftState;\n /** ISO 8601 timestamp of the last run that found corroborating evidence. */\n lastCorroborated?: string;\n}\n\n/**\n * Per-recall render hint, mixed into `QmdSearchResult`. Set by the\n * preference-drift recall stage when `driftDetection.annotateAfterDays` is on\n * and absent otherwise. Never persisted — this annotates one injection, it is\n * not memory state.\n */\nexport interface RecallDriftAnnotation {\n driftNote?: string;\n}\n\n/** Mixed into `PluginConfig`. */\nexport interface DriftDetectionSettings {\n driftDetection: DriftDetectionConfig;\n}\n\n/**\n * Frontmatter codec for the drift stamps. Lives here, beside the interface it\n * serializes, so `storage.ts` stays a caller rather than growing another\n * field-specific block.\n */\nexport function serializeDriftProvenance(fm: MemoryDriftProvenance): string[] {\n const lines: string[] = [];\n if (fm.driftState !== undefined) {\n // An unrecognized verdict on write is a caller bug that must surface, not\n // something to persist silently.\n if (fm.driftState !== \"stale\" && fm.driftState !== \"drifted\") {\n throw new Error(\n `serializeFrontmatter: invalid driftState ${JSON.stringify(fm.driftState)} — expected \"stale\" | \"drifted\"`,\n );\n }\n lines.push(`driftState: ${fm.driftState}`);\n }\n if (fm.lastCorroborated) lines.push(`lastCorroborated: ${fm.lastCorroborated}`);\n return lines;\n}\n\n/**\n * Read the drift stamps back. A hand-edited or unrecognized stored verdict\n * round-trips to `undefined` rather than poisoning recall damping — the same\n * policy the Memory Worth counters use for corrupt values.\n */\nexport function parseDriftProvenance(\n fm: Record<string, string | undefined>,\n): MemoryDriftProvenance {\n return {\n driftState:\n fm.driftState === \"stale\" || fm.driftState === \"drifted\" ? fm.driftState : undefined,\n lastCorroborated: fm.lastCorroborated || undefined,\n };\n}\n","import { statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { TombstoneStoreOptions } from \"../lifecycle/tombstones.js\";\nimport type { MemoryFile } from \"../types.js\";\n\n/**\n * Deps injected by `StorageManager.buildTombstoneStore` so this module owns no\n * storage-god-file imports (issue #1533 ratchet).\n */\nexport interface TombstoneMigrationSourceDeps {\n /** On-disk tombstone ledger path; its mtime scopes both caches below. */\n tombstonesPath: () => string;\n collectTombstoneMigrationPaths: () => Promise<string[]>;\n readParsedMemoriesFromPaths: (filePaths: string[], batchSize?: number) => Promise<MemoryFile[]>;\n storedContentIdentityCandidates: (content: string) => string[];\n}\n\n/**\n * Build the `sourceContentsForMemoryIds` callback `TombstoneStore` uses to\n * verify pre-Unicode rows against their retired source memories. The corpus\n * path snapshot and the resolved source-content map are memoized for one\n * ledger revision only (issue #2367): a peer process can create and retire a\n * legacy-format memory after this snapshot, and the staleness reload must\n * resolve the new row against a FRESH path list — otherwise the row stays\n * unverified (withheld from the lookup tiers) until restart.\n */\nexport function createTombstoneMigrationSourceContents(\n deps: TombstoneMigrationSourceDeps,\n): NonNullable<TombstoneStoreOptions[\"sourceContentsForMemoryIds\"]> {\n let sourcePathsPromise: Promise<string[]> | undefined;\n let sourceContentsByIdPromise: Promise<Map<string, readonly string[]>> | undefined;\n let ledgerMtimeMs: number | null = null;\n const dropCachesIfLedgerChanged = (): void => {\n let mtimeMs: number | null;\n try {\n mtimeMs = Math.floor(statSync(deps.tombstonesPath()).mtimeMs);\n } catch {\n return; // ENOENT / stat failure — keep whatever is cached.\n }\n if (mtimeMs === ledgerMtimeMs) return;\n ledgerMtimeMs = mtimeMs;\n sourcePathsPromise = undefined;\n sourceContentsByIdPromise = undefined;\n };\n return async (sourceMemoryIds) => {\n for (;;) {\n dropCachesIfLedgerChanged();\n // In-flight fills are bound to the ledger revision they started\n // against: if the ledger advances while a fill awaits, restart\n // against the fresh revision instead of publishing a cache built\n // from a stale path snapshot (issue #2367 review round 2).\n const revision = ledgerMtimeMs;\n const requested = new Set(sourceMemoryIds);\n const sourcePaths = await (sourcePathsPromise ??= deps.collectTombstoneMigrationPaths());\n if (ledgerMtimeMs !== revision) continue;\n const directPaths = sourcePaths.filter((filePath) =>\n requested.has(path.basename(filePath, \".md\"))\n );\n const contents = new Map<string, readonly string[]>();\n for (const memory of await deps.readParsedMemoriesFromPaths(directPaths, 50)) {\n const id = memory.frontmatter.id;\n if (requested.has(id) && !contents.has(id)) {\n contents.set(id, deps.storedContentIdentityCandidates(memory.content));\n }\n }\n // Re-check after the direct-path read too: a concurrent drop during\n // that await must not let this call publish a fill built from the\n // stale snapshot into the freshly cleared slot (issue #2367 round 3).\n if (ledgerMtimeMs !== revision) continue;\n if (contents.size === requested.size) return contents;\n const fill = (sourceContentsByIdPromise ??= (async () => {\n const allContents = new Map<string, readonly string[]>();\n for (const memory of await deps.readParsedMemoriesFromPaths(sourcePaths, 50)) {\n const id = memory.frontmatter.id;\n if (!allContents.has(id)) {\n allContents.set(id, deps.storedContentIdentityCandidates(memory.content));\n }\n }\n return allContents;\n })());\n const allContents = await fill;\n if (ledgerMtimeMs !== revision) continue;\n for (const id of requested) {\n const content = allContents.get(id);\n if (content !== undefined) contents.set(id, content);\n }\n return contents;\n }\n };\n}\n","/**\n * Memory read store (extracted from storage.ts StorageManager; god-file\n * decomposition, #1526 playbook: verbatim move + live selfDeps wiring).\n *\n * Owns the bulk/windowed read surfaces of the storage layer: active\n * memory path collection, windowed and cold reads, path-addressed reads,\n * cached artifact index reads, questions, buffer-surprise ledger\n * read/append, compression-guideline state, and wearable transcript-day\n * listing.\n */\n\nimport type { Dirent, Stats } from \"node:fs\";\nimport { lstat, readdir, realpath, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { toMemoryPathRel } from \"../memory-lifecycle-ledger-utils.js\";\nimport { SecureStoreLockedError, readMaybeEncryptedFile } from \"../secure-store/secure-fs.js\";\nimport { type BufferSurpriseEvent, type CompressionGuidelineOptimizerState, type MemoryFile, type PluginConfig, confidenceTier } from \"../types.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { assertPathInsideRoot } from \"../utils/path-containment.js\";\nimport { isAbortError } from \"../abort-error.js\";\nimport { checkCorpusReadAbort, type CorpusReadOptions } from \"../corpus-read-cancellation.js\";\nimport { isValidTranscriptDate } from \"../wearables/day-store.js\";\nimport {\n isValidBufferSurpriseEvent,\n normalizeFrontmatterForPath,\n parseEntityFile,\n parseFrontmatter,\n StorageManager,\n} from \"../storage.js\";\nimport { rememberRawFrontmatter } from \"./memory-frontmatter-metadata.js\";\n\nexport interface MemoryReadStoreDeps {\n /** Live class object of the host instance — shared static caches (see storage.ts storageManagerClass). */\n readonly storageManagerClass: typeof StorageManager;\n readonly _secureStoreKey: Buffer | null;\n appendStorageSecureFile(filePath: string, content: string): Promise<void>;\n artifactIndexCache: { memories: MemoryFile[]; loadedAtMs: number; writeVersion: number } | null;\n readonly artifactsDir: string;\n readonly baseDir: string;\n readonly bufferSurpriseLedgerPath: string;\n collectActiveMemoryPaths(): Promise<string[]>;\n readonly correctionsDir: string;\n ensureDirectories(): Promise<void>;\n readonly entitySchemas: PluginConfig[\"entitySchemas\"] | undefined;\n readonly factsDir: string;\n filterWindowPathsByUpdatedAfter(filePaths: string[], updatedAfterMs: number): Promise<string[]>;\n getArtifactWriteVersion(): number;\n normalizeMemoryReadBatchSize(batchSize?: number): number;\n orderWindowPaths(filePaths: string[]): string[];\n parseQuestionFile(\n raw: string,\n filePath: string,\n ): {\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n } | null;\n readonly proceduresDir: string;\n readonly questionsDir: string;\n readColdWriteVersion(): number;\n /** Secure-store key identity for keying decrypted-corpus caches (#1902). */\n hotCacheKeyId(): string;\n readMemoryByPath(filePath: string): Promise<MemoryFile | null>;\n readParsedMemoriesFromPaths(\n filePaths: string[],\n batchSize?: number,\n ): Promise<MemoryFile[]>;\n readStorageSecureFile(filePath: string): Promise<string>;\n readWindowBoundedBatch(\n candidateBatchPaths: string[],\n remainingSlots: number,\n remainingInspectionBudget: number,\n readBatchSize: number,\n ): Promise<{ memories: MemoryFile[]; filePaths: string[] }>;\n readonly reasoningTracesDir: string;\n resolveTierRootDir(tier: \"hot\" | \"cold\"): string;\n readonly wearablesDir: string;\n}\n\n/**\n * A backend READ failure worth propagating from a strict (census) scan: an\n * errno-coded fs error that is NOT `ENOENT`. `ENOENT` (an absent dir) and\n * code-less rejections (symlink-escape containment failures from\n * assertPathInsideRoot) are expected and skipped; `EACCES`/`EIO`/… mean the\n * corpus is unreadable and a divergence census must fail loud rather than\n * silently publish a partial count (issue #2156 round-5). Non-strict (recall)\n * callers ignore this and degrade to a best-effort partial scan.\n */\nfunction isPropagatableReadError(err: unknown): boolean {\n const code = (err as NodeJS.ErrnoException).code;\n return typeof code === \"string\" && code !== \"ENOENT\";\n}\n\nexport class MemoryReadStore {\n constructor(\n private readonly deps: MemoryReadStoreDeps,\n ) {}\n\n /**\n * List stored transcript days, newest first, optionally scoped to one\n * source. Non-transcript files in the tree are ignored.\n */\n async listWearableTranscriptDays(\n sourceId?: string,\n ): Promise<Array<{ source: string; date: string }>> {\n const days: Array<{ source: string; date: string }> = [];\n let sources: string[];\n if (sourceId !== undefined) {\n sources = [sourceId];\n } else {\n try {\n const entries = await readdir(this.deps.wearablesDir, { withFileTypes: true });\n sources = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw err;\n }\n }\n for (const source of sources) {\n if (!/^[a-z][a-z0-9-]{0,63}$/.test(source)) continue;\n let entries: string[];\n try {\n entries = await readdir(path.join(this.deps.wearablesDir, source));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n throw err;\n }\n for (const entry of entries) {\n if (!entry.endsWith(\".md\")) continue;\n const date = entry.slice(0, -3);\n if (!isValidTranscriptDate(date)) continue;\n days.push({ source, date });\n }\n }\n days.sort((a, b) => {\n if (a.date > b.date) return -1;\n if (a.date < b.date) return 1;\n if (a.source < b.source) return -1;\n if (a.source > b.source) return 1;\n return 0;\n });\n return days;\n }\n\n async readAllArtifactsCached(options?: CorpusReadOptions): Promise<MemoryFile[]> {\n checkCorpusReadAbort(options);\n if (\n this.deps.artifactIndexCache &&\n Date.now() - this.deps.artifactIndexCache.loadedAtMs <= this.deps.storageManagerClass.ARTIFACT_INDEX_CACHE_TTL_MS &&\n this.deps.artifactIndexCache.writeVersion === this.deps.getArtifactWriteVersion()\n ) {\n return this.deps.artifactIndexCache.memories;\n }\n\n const scanArtifacts = async (): Promise<MemoryFile[]> => {\n const artifacts: MemoryFile[] = [];\n const readDir = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n // Per-entry, so a tree of any shape has a checkpoint: this scan has no\n // in-flight dedup, so every abandoned recall used to start another\n // full walk of it (issue #2307).\n checkCorpusReadAbort(options);\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await readDir(fullPath);\n continue;\n }\n if (!entry.name.endsWith(\".md\")) continue;\n const memory = await this.deps.readMemoryByPath(fullPath);\n if (!memory) continue;\n artifacts.push(memory);\n }\n } catch (err) {\n // A cancelled scan must surface, not be swallowed as \"directory doesn't\n // exist yet\" — otherwise a partial walk would be cached as complete.\n if (isAbortError(err)) throw err;\n // Directory doesn't exist yet\n }\n };\n await readDir(this.deps.artifactsDir);\n return artifacts;\n };\n\n const MAX_REBUILD_RETRIES = 2;\n let latestArtifacts: MemoryFile[] = [];\n for (let attempt = 0; attempt <= MAX_REBUILD_RETRIES; attempt += 1) {\n checkCorpusReadAbort(options);\n const versionBefore = this.deps.getArtifactWriteVersion();\n const artifacts = await scanArtifacts();\n const versionAfter = this.deps.getArtifactWriteVersion();\n latestArtifacts = artifacts;\n // A signal that fired during the last file read of the walk would otherwise\n // publish this scan and return it as if uncancelled (issue #2307 review).\n checkCorpusReadAbort(options);\n if (versionAfter === versionBefore) {\n this.deps.artifactIndexCache = { memories: artifacts, loadedAtMs: Date.now(), writeVersion: versionAfter };\n return artifacts;\n }\n }\n\n // Highly concurrent writer churn; keep cache invalid so next read retries a clean rebuild.\n // Return best-effort latest scan instead of an empty set to avoid dropping recall entirely.\n this.deps.artifactIndexCache = null;\n return latestArtifacts;\n }\n\n /**\n * Recursively collect `*.md` paths under `startDirs`, hardened against symlink\n * escape: a category dir symlinked outside memoryDir (e.g. decisions/ -> an\n * external dir) must NOT pull out-of-store files into a scan (info leak). Same\n * walker-hardening pattern as document-scanner.ts / cli.ts /\n * consolidation-provenance-check.ts; reuses the shared containment helper.\n * Paths only — no frontmatter parse.\n */\n private async collectContainedMarkdownPaths(\n startDirs: readonly string[],\n propagateReadErrors = false,\n options?: CorpusReadOptions,\n ): Promise<string[]> {\n const filePaths: string[] = [];\n\n // Resolve the memory root once for the containment checks below.\n let memoryRootReal: string;\n try {\n memoryRootReal = await realpath(this.deps.baseDir);\n } catch (err) {\n // ENOENT: a not-yet-created root ⇒ empty. Any other errno is a backend\n // read failure — propagate for strict census callers (never publish an\n // unreadable corpus as empty); non-strict (recall) callers degrade.\n if (propagateReadErrors && isPropagatableReadError(err)) throw err;\n return filePaths;\n }\n\n const collectPaths = async (dir: string): Promise<void> => {\n checkCorpusReadAbort(options);\n // Directory-level guard, isolated from per-entry handling: skip symlinked\n // or non-directory category dirs and assert the resolved dir stays inside\n // the memory root before reading. A failure here means the whole subtree\n // does not exist or escaped the store — fail closed by skipping it.\n let dirStat: Stats;\n try {\n dirStat = await lstat(dir);\n } catch (err) {\n // ENOENT (absent category dir) is expected; a backend read error\n // (EACCES/EIO/…) propagates in strict census mode.\n if (propagateReadErrors && isPropagatableReadError(err)) throw err;\n return;\n }\n if (dirStat.isSymbolicLink()) return; // never follow symlinks out of the store (both modes)\n if (!dirStat.isDirectory()) {\n // A category root that EXISTS but is not a directory (e.g. `facts/`\n // replaced by a regular file) is a layout/backend failure: a strict\n // census must not silently publish the remaining categories as healthy.\n // Non-strict (recall) stays best-effort and skips it (issue #2156 round-10).\n if (propagateReadErrors) {\n throw new Error(`corpus scan: expected a directory but found a non-directory at ${dir}`);\n }\n return;\n }\n let entries: Dirent[];\n try {\n assertPathInsideRoot(memoryRootReal, await realpath(dir), dir);\n entries = await readdir(dir, { withFileTypes: true });\n } catch (err) {\n // A containment failure carries no errno (skip); a backend read error\n // (EACCES …) propagates in strict census mode so a partial subtree is\n // not silently counted.\n if (propagateReadErrors && isPropagatableReadError(err)) throw err;\n return;\n }\n\n const subdirs: string[] = [];\n for (const entry of entries) {\n // Outside the per-entry try/catch below, which deliberately swallows\n // non-propagatable errors — a cancellation must never be swallowed with\n // them (issue #2307).\n checkCorpusReadAbort(options);\n // Never follow symlinked entries out of the store.\n if (entry.isSymbolicLink()) continue;\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n subdirs.push(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n // Isolate per-entry failures in their own try/catch: a containment or\n // realpath failure on ONE .md entry must not drop sibling files or,\n // crucially, the deferred subdir recursion below (Cursor Bugbot:\n // \"Poisoned md skips sibling subdirs\"). Mirrors the per-file try/catch\n // in search/document-scanner.ts scanDir and\n // consolidation-provenance-check.ts walkMarkdownFiles.\n try {\n assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);\n filePaths.push(fullPath);\n } catch (err) {\n // ENOENT (vanished mid-scan) or a code-less containment/symlink\n // rejection ⇒ skip just this file. A backend read error propagates\n // in strict census mode.\n if (propagateReadErrors && isPropagatableReadError(err)) throw err;\n }\n }\n }\n // Recurse into real subdirectories regardless of any single poisoned entry\n // above, so valid nested in-store memories are never dropped.\n for (const subdir of subdirs) {\n await collectPaths(subdir);\n }\n };\n\n for (const dir of startDirs) {\n await collectPaths(dir);\n }\n // A signal that fired during the last directory read would otherwise return a\n // truncated path list as if it were the whole corpus (issue #2307 review).\n checkCorpusReadAbort(options);\n return filePaths;\n }\n\n async collectActiveMemoryPaths(\n options?: { propagateReadErrors?: boolean } & CorpusReadOptions,\n ): Promise<string[]> {\n // Scan EVERY supported memory category directory, not just the legacy four\n // (facts/procedures/reasoning-traces/corrections). Issue #1497: the QMD\n // filesystem-fallback recall path (orchestrator `recent_scan` ->\n // readAllMemoriesForNamespaces -> readAllMemories -> here) must read every\n // recall category dir so on-disk memories in preferences/decisions/moments/\n // commitments/principles/rules/skills/relationships are not missed when QMD\n // is disabled, missing, or unhealthy. RECALL_FALLBACK_DIRS is the single\n // source of truth derived from ALL_CATEGORY_DIRS (shared with\n // ensureDirectories() and the write routing in utils/category-dir.ts).\n // These paths resolve identically to the legacy this.deps.factsDir /\n // this.deps.correctionsDir / this.deps.proceduresDir / this.deps.reasoningTracesDir\n // getters (all `path.join(this.deps.baseDir, <dir>)`), so the scan stays\n // namespace-aware: this.deps.baseDir is per-namespace, set by the storage router.\n // Deliberately EXCLUDED (issue #1497 + PR #1503 review): the non-category\n // content dirs that ensureDirectories() also creates — entities/, state/,\n // artifacts/, identity/, config/ — plus the root profile.md, AND the\n // questions/ queue dir. questions/ holds operational question-QUEUE items\n // written by writeQuestion() (frontmatter `{ id, created, priority,\n // resolved }`), read only via readQuestions() and surfaced through the\n // dedicated, disabled-by-default `injectQuestions` recall-pipeline stage —\n // never as standard recall memories. The QMD primary recall corpus does not\n // include them, so the fallback must not either (corpus parity; CLAUDE.md\n // rule #39). Were questions/ scanned here, parseFrontmatter() would accept\n // those files (they have a `---` frontmatter block) and leak queue items\n // into recall. None of these excluded dirs are in RECALL_FALLBACK_DIRS; the\n // exclusion is asserted by tests in storage-fallback-category-dirs.test.ts.\n return this.collectContainedMarkdownPaths(\n RECALL_FALLBACK_DIRS.map((dir) => path.join(this.deps.baseDir, dir)),\n options?.propagateReadErrors ?? false,\n options,\n );\n }\n\n /**\n * Cold-tier memory paths for the corpus census (issue #2156 finding D).\n * Demoted memories move to `<baseDir>/cold/...` but stay active and reachable\n * via cold recall, so the divergence census MUST count them — otherwise two\n * replicas whose cold tiers differ show a false \"converged\" digest. Paths\n * only, same symlink/containment hardening as the hot scan. This is NOT part\n * of the recall fallback corpus (collectActiveMemoryPaths), whose scan is\n * intentionally unchanged.\n */\n async collectColdMemoryPaths(\n options?: { propagateReadErrors?: boolean } & CorpusReadOptions,\n ): Promise<string[]> {\n return this.collectContainedMarkdownPaths(\n [this.deps.resolveTierRootDir(\"cold\")],\n options?.propagateReadErrors ?? false,\n options,\n );\n }\n\n async collectTombstoneMigrationPaths(): Promise<string[]> {\n const tiers = await Promise.all([\n this.collectActiveMemoryPaths(),\n this.collectColdMemoryPaths(),\n this.collectContainedMarkdownPaths([path.join(this.deps.baseDir, \"archive\")]),\n ]);\n return tiers.flat();\n }\n\n async readMemoriesWindow(options: {\n maxMemories?: number;\n batchSize?: number;\n updatedAfter?: Date;\n } = {}): Promise<{ memories: MemoryFile[]; filePaths: string[] }> {\n const allPaths = await this.deps.collectActiveMemoryPaths();\n const sortedPaths = this.deps.orderWindowPaths(allPaths);\n const maxMemories =\n typeof options.maxMemories === \"number\" && Number.isFinite(options.maxMemories)\n ? Math.max(1, Math.floor(options.maxMemories))\n : undefined;\n const maxCandidatePaths = maxMemories === undefined ? undefined : maxMemories * 2;\n const updatedAfterMs = options.updatedAfter?.getTime();\n const normalizedBatchSize = this.deps.normalizeMemoryReadBatchSize(options.batchSize);\n const memories: MemoryFile[] = [];\n const selectedPaths: string[] = [];\n\n for (let i = 0; i < sortedPaths.length; i += normalizedBatchSize) {\n if (\n maxMemories !== undefined\n && (memories.length >= maxMemories || (maxCandidatePaths !== undefined && selectedPaths.length >= maxCandidatePaths))\n ) {\n return { memories, filePaths: selectedPaths };\n }\n const batchPaths = sortedPaths.slice(i, i + normalizedBatchSize);\n const candidateBatchPaths = updatedAfterMs === undefined\n ? batchPaths\n : await this.deps.filterWindowPathsByUpdatedAfter(batchPaths, updatedAfterMs);\n const remainingSlots = maxMemories === undefined ? undefined : Math.max(0, maxMemories - memories.length);\n const remainingInspectionBudget = maxCandidatePaths === undefined ? undefined : Math.max(0, maxCandidatePaths - selectedPaths.length);\n const { memories: batchMemories, filePaths: parsedCandidatePaths } = remainingSlots === undefined\n ? {\n memories: await this.deps.readParsedMemoriesFromPaths(candidateBatchPaths, normalizedBatchSize),\n filePaths: candidateBatchPaths,\n }\n : await this.deps.readWindowBoundedBatch(\n candidateBatchPaths,\n remainingSlots,\n remainingInspectionBudget ?? remainingSlots,\n normalizedBatchSize,\n );\n selectedPaths.push(...parsedCandidatePaths);\n for (const memory of batchMemories) {\n memories.push(memory);\n if (maxMemories !== undefined && memories.length >= maxMemories) {\n return { memories, filePaths: selectedPaths };\n }\n }\n }\n\n return { memories, filePaths: selectedPaths };\n }\n\n /**\n * Read all memories from the cold tier by scanning the entire cold/ root\n * tree. Previously this only scanned cold/facts/ and cold/corrections/, but\n * structuredAttributes can appear on any MemoryCategory (preference, decision,\n * entity, etc.). buildTierMemoryPath now routes each category to its own\n * cold/<dir>/ subtree via the shared categoryDirName() chokepoint (issue\n * #1546), so cold decisions/preferences/... live outside cold/facts/.\n * Scanning the full coldRoot covers every category dir and guards against\n * files placed in unexpected subdirectories during manual operations or future\n * refactors.\n *\n * Broadened in PR #402 round-6 (Finding UTsP): scanning only facts/ and\n * corrections/ was a narrower-than-necessary subset of the cold directory\n * tree. Correctness trumps the minor performance difference — cold scans\n * already happen at most once per supersession write.\n *\n * Used by applyTemporalSupersession so that memories already demoted to\n * cold/ can still be marked superseded when a newer hot fact arrives.\n *\n * Cached with a TTL (Finding UOGi, PR #402 round-6): back-to-back\n * structured-attribute writes in the same burst reuse the cached result\n * instead of re-scanning the cold tree on every call. The cache is\n * invalidated whenever a write calls invalidateAllMemoriesCache() (which\n * covers any hot→cold demotion that changes cold-tier contents) and\n * expires after COLD_SCAN_CACHE_TTL_MS as a safety net.\n */\n async readAllColdMemories(): Promise<MemoryFile[]> {\n const coldRoot = this.deps.resolveTierRootDir(\"cold\");\n\n // Read the on-disk cold-version sentinel BEFORE checking the cache so that\n // writes made by other processes (gateway + CLI) are detected immediately.\n // Finding UvUy (PR #402 round-11): without this check the cache served\n // stale data for up to 30s when another process wrote a new cold memory.\n const currentColdVersion = this.deps.readColdWriteVersion();\n\n // Return cached result if still valid by TTL, sentinel version, AND the\n // secure-store key identity (issue #1902). readParsedMemoriesFromPaths\n // decrypts per this manager's key, so a differently-keyed manager must not\n // read a cold corpus another instance decrypted for the same coldRoot.\n const keyId = this.deps.hotCacheKeyId();\n const cached = this.deps.storageManagerClass.coldMemoriesCache.get(coldRoot);\n if (\n cached &&\n cached.keyId === keyId &&\n Date.now() - cached.loadedAt < this.deps.storageManagerClass.COLD_SCAN_CACHE_TTL_MS &&\n cached.coldVersion === currentColdVersion\n ) {\n return cached.memories;\n }\n\n const filePaths: string[] = [];\n\n const collectPaths = async (dir: string) => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n const subdirs: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n subdirs.push(fullPath);\n } else if (entry.name.endsWith(\".md\")) {\n filePaths.push(fullPath);\n }\n }\n for (const subdir of subdirs) {\n await collectPaths(subdir);\n }\n } catch {\n // Directory does not exist yet — cold tier may be empty.\n }\n };\n\n // Scan the entire cold root so that memories in any subdirectory (facts/,\n // corrections/, artifacts/, or any future category-specific subdirectory)\n // are included. This is broader than the previous facts/+corrections/ scan\n // and ensures that any memory with structuredAttributes is found regardless\n // of which category it was written with.\n await collectPaths(coldRoot);\n const memories = await this.deps.readParsedMemoriesFromPaths(filePaths, 50);\n\n // Store in cache with the sentinel version captured above so that any\n // subsequent cold-version bump (by this or another process) invalidates it.\n this.deps.storageManagerClass.coldMemoriesCache.set(coldRoot, { memories, loadedAt: Date.now(), coldVersion: currentColdVersion, keyId });\n return memories;\n }\n\n /** Read a single memory file by its absolute path. Returns null if unreadable. */\n async readMemoryByPath(filePath: string): Promise<MemoryFile | null> {\n try {\n const raw = await readMaybeEncryptedFile(filePath, this.deps._secureStoreKey, this.deps.baseDir);\n // Note: the outer catch intentionally swallows most errors (ENOENT etc.)\n // but SecureStoreLockedError must propagate — see re-throw below.\n const parsed = parseFrontmatter(raw);\n if (parsed) {\n return rememberRawFrontmatter({\n path: filePath,\n frontmatter: normalizeFrontmatterForPath(\n parsed.frontmatter,\n toMemoryPathRel(this.deps.baseDir, filePath),\n parsed.content,\n ),\n content: parsed.content,\n }, raw);\n }\n\n // Entity files use a `# Name` + `**Type:** ...` markdown format rather than\n // YAML frontmatter. Build a synthetic MemoryFile so entity files returned by\n // the direct retrieval agent participate in boostSearchResults and last-recall\n // tracking rather than being silently dropped.\n const normalizedPath = filePath.split(path.sep).join(\"/\");\n if (normalizedPath.includes(\"/entities/\") && filePath.endsWith(\".md\")) {\n const entity = parseEntityFile(raw, this.deps.entitySchemas);\n if (!entity.name) return null;\n const nameWithoutExt = path.basename(filePath, \".md\");\n // Fall back to file mtime rather than new Date() so that entities without\n // an explicit Updated: timestamp are not treated as freshly created on every\n // read. Using new Date() would inflate boostSearchResults recency scores for\n // every entity that lacks a timestamp.\n // Use epoch as the last-resort fallback so that entities without a\n // parseable timestamp don't appear as \"freshly created\" and inflate scores.\n const fileMtime = entity.updated\n || await stat(filePath).then((s) => s.mtime.toISOString()).catch(() => new Date(0).toISOString());\n return {\n path: filePath,\n frontmatter: {\n id: nameWithoutExt,\n category: \"entity\",\n created: fileMtime,\n updated: fileMtime,\n source: \"entity_extraction\",\n confidence: 0.9,\n confidenceTier: confidenceTier(0.9),\n tags: entity.type ? [entity.type] : [],\n },\n content: raw,\n };\n }\n\n return null;\n } catch (err) {\n // Re-throw store-locked errors — callers need to distinguish \"locked\"\n // from \"file not found / parse error\". Swallowing a locked error here\n // would silently return null and leave the daemon appearing to work\n // while returning no memories (subtle data loss).\n if (err instanceof SecureStoreLockedError) throw err;\n return null;\n }\n }\n\n /**\n * Append a batch of `BUFFER_SURPRISE` telemetry events (issue #563 PR 3).\n *\n * Each event records a single buffer flush decision driven by the\n * surprise gate. The ledger is consumed by\n * `reportBufferSurpriseDistribution` (Doctor report) and by downstream\n * benchmark analysis. This method is fire-and-forget by contract:\n * callers log but do not fail the hot path if the append throws.\n */\n async appendBufferSurpriseEvents(\n events: BufferSurpriseEvent[],\n ): Promise<number> {\n if (events.length === 0) return 0;\n await this.deps.ensureDirectories();\n\n const nowIso = new Date().toISOString();\n const payload = events\n .map((event) => {\n const normalized: BufferSurpriseEvent = {\n ...event,\n event: \"BUFFER_SURPRISE\",\n timestamp:\n event.timestamp && event.timestamp.length > 0\n ? event.timestamp\n : nowIso,\n };\n return `${JSON.stringify(normalized)}\\n`;\n })\n .join(\"\");\n\n await this.deps.appendStorageSecureFile(this.deps.bufferSurpriseLedgerPath, payload);\n return events.length;\n }\n\n /**\n * Read the buffer-surprise ledger, most recent rows last.\n *\n * `limit` bounds the number of **valid rows** returned (not the\n * number of raw lines parsed). We parse every row, discard malformed\n * ones, then take the tail — so a partial/truncated trailing line\n * (the common failure mode after an interrupted append) cannot hide\n * otherwise-valid recent data above it.\n *\n * Non-positive / non-integer / non-finite limits return `[]` rather\n * than the entire file, matching the other ledger readers in this\n * class and protecting against `slice(-0.5)` → `slice(-0)` silently\n * devolving into an unbounded parse.\n *\n * # Performance note\n *\n * For very large ledgers (issue #563 follow-up), a tail-first reader\n * would avoid parsing the full file when only a recent window is\n * needed. We keep the full-scan implementation here because:\n *\n * - the ledger is opt-in (flag off by default), so early deployments\n * accumulate rows slowly;\n * - telemetry rows are small (~200 bytes), so even 100k rows parse\n * in well under a second;\n * - the governance archive/cleanup flow can trim the ledger when\n * size becomes a concern, reusing the existing maintenance hooks.\n *\n * Swap to a chunked tail-reader if production logs show this is a\n * hot path — leaving that work for a follow-up keeps this PR scoped\n * to correctness, not optimization.\n */\n async readBufferSurpriseEvents(\n options: { limit?: number } = {},\n ): Promise<BufferSurpriseEvent[]> {\n let raw: string;\n try {\n raw = await this.deps.readStorageSecureFile(this.deps.bufferSurpriseLedgerPath);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n const code = (err as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") return [];\n throw err;\n }\n\n // Resolve the effective limit up front. Any non-finite / non-positive\n // value returns no rows — callers who want \"everything\" should OMIT\n // the `limit` key (treated as \"no bound\" below). We intentionally\n // reject `Infinity` too, because the slice math `events.slice(-Inf)`\n // is surprising and ambiguous; omit the key instead. Fractional\n // values <1 floor to 0, which would make `slice(-0)` return the\n // entire file — guard against that too.\n let effectiveLimit: number | null = null;\n if (options.limit !== undefined) {\n if (\n typeof options.limit !== \"number\" ||\n !Number.isFinite(options.limit) ||\n options.limit <= 0\n ) {\n return [];\n }\n const floored = Math.floor(options.limit);\n if (floored <= 0) return [];\n effectiveLimit = floored;\n }\n\n const lines = raw.split(\"\\n\");\n const events: BufferSurpriseEvent[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length === 0) continue;\n try {\n const parsed = JSON.parse(trimmed);\n if (isValidBufferSurpriseEvent(parsed)) {\n events.push(parsed);\n }\n } catch {\n // Malformed row — fail open, skip.\n }\n }\n\n events.sort(\n (left, right) => Date.parse(left.timestamp) - Date.parse(right.timestamp),\n );\n\n if (effectiveLimit === null) return events;\n // Slice over VALID rows, not raw lines, so malformed tails cannot\n // mask good data above them. Sort by event timestamp before slicing\n // so concurrent probe completion order cannot make an older scored\n // turn look newer than a later scored turn.\n return events.slice(-effectiveLimit);\n }\n\n async readCompressionGuidelineStateFile(\n filePath: string,\n ): Promise<CompressionGuidelineOptimizerState | null> {\n const isFiniteNonNegativeInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value) && Number.isInteger(value) && value >= 0;\n const isValidActionSummary = (\n value: unknown,\n ): value is NonNullable<CompressionGuidelineOptimizerState[\"actionSummaries\"]>[number] => {\n if (!value || typeof value !== \"object\") return false;\n const summary = value as NonNullable<CompressionGuidelineOptimizerState[\"actionSummaries\"]>[number];\n return (\n typeof summary.action === \"string\" &&\n isFiniteNonNegativeInteger(summary.total) &&\n summary.outcomes !== null &&\n typeof summary.outcomes === \"object\" &&\n isFiniteNonNegativeInteger(summary.outcomes.applied) &&\n isFiniteNonNegativeInteger(summary.outcomes.skipped) &&\n isFiniteNonNegativeInteger(summary.outcomes.failed) &&\n summary.quality !== null &&\n typeof summary.quality === \"object\" &&\n isFiniteNonNegativeInteger(summary.quality.good) &&\n isFiniteNonNegativeInteger(summary.quality.poor) &&\n isFiniteNonNegativeInteger(summary.quality.unknown)\n );\n };\n const isValidRuleUpdate = (\n value: unknown,\n ): value is NonNullable<CompressionGuidelineOptimizerState[\"ruleUpdates\"]>[number] => {\n if (!value || typeof value !== \"object\") return false;\n const rule = value as NonNullable<CompressionGuidelineOptimizerState[\"ruleUpdates\"]>[number];\n return (\n typeof rule.action === \"string\" &&\n typeof rule.delta === \"number\" &&\n Number.isFinite(rule.delta) &&\n (rule.direction === \"increase\" || rule.direction === \"decrease\" || rule.direction === \"hold\") &&\n (rule.confidence === \"low\" || rule.confidence === \"medium\" || rule.confidence === \"high\") &&\n Array.isArray(rule.notes) &&\n rule.notes.every((note) => typeof note === \"string\")\n );\n };\n\n try {\n const raw = await this.deps.readStorageSecureFile(filePath);\n const parsed = JSON.parse(raw) as Partial<CompressionGuidelineOptimizerState>;\n const sourceWindow = parsed?.sourceWindow as Partial<CompressionGuidelineOptimizerState[\"sourceWindow\"]>;\n const eventCounts = parsed?.eventCounts as Partial<CompressionGuidelineOptimizerState[\"eventCounts\"]>;\n const activationState =\n parsed?.activationState === \"draft\" || parsed?.activationState === \"active\"\n ? parsed.activationState\n : undefined;\n const contentHash =\n typeof parsed?.contentHash === \"string\" && parsed.contentHash.length > 0\n ? parsed.contentHash\n : undefined;\n const actionSummaries = Array.isArray(parsed?.actionSummaries)\n ? parsed.actionSummaries.filter(isValidActionSummary)\n : undefined;\n const ruleUpdates = Array.isArray(parsed?.ruleUpdates)\n ? parsed.ruleUpdates.filter(isValidRuleUpdate)\n : undefined;\n if (\n !isFiniteNonNegativeInteger(parsed?.version) ||\n typeof parsed?.updatedAt !== \"string\" ||\n parsed.updatedAt.length === 0 ||\n !sourceWindow ||\n typeof sourceWindow.from !== \"string\" ||\n sourceWindow.from.length === 0 ||\n typeof sourceWindow.to !== \"string\" ||\n sourceWindow.to.length === 0 ||\n !eventCounts ||\n !isFiniteNonNegativeInteger(eventCounts.total) ||\n !isFiniteNonNegativeInteger(eventCounts.applied) ||\n !isFiniteNonNegativeInteger(eventCounts.skipped) ||\n !isFiniteNonNegativeInteger(eventCounts.failed) ||\n !isFiniteNonNegativeInteger(parsed?.guidelineVersion)\n ) {\n return null;\n }\n\n return {\n version: parsed.version,\n updatedAt: parsed.updatedAt,\n sourceWindow: {\n from: sourceWindow.from,\n to: sourceWindow.to,\n },\n eventCounts: {\n total: eventCounts.total,\n applied: eventCounts.applied,\n skipped: eventCounts.skipped,\n failed: eventCounts.failed,\n },\n guidelineVersion: parsed.guidelineVersion,\n ...(contentHash ? { contentHash } : {}),\n ...(activationState ? { activationState } : {}),\n ...(actionSummaries ? { actionSummaries } : {}),\n ...(ruleUpdates ? { ruleUpdates } : {}),\n };\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async readQuestions(\n opts?: { unresolvedOnly?: boolean },\n ): Promise<\n Array<{\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n }>\n > {\n const cacheKey = this.deps.questionsDir;\n const cached = this.deps.storageManagerClass.questionsCache.get(cacheKey);\n if (cached && Date.now() - cached.loadedAt < this.deps.storageManagerClass.QUESTIONS_CACHE_TTL_MS) {\n // Check dir mtime for cross-process invalidation — if another process\n // wrote/resolved a question, the directory mtime will be newer than loadedAt.\n try {\n const dirStat = await stat(this.deps.questionsDir);\n if (dirStat.mtimeMs <= cached.loadedAt) {\n const all = cached.questions;\n return opts?.unresolvedOnly ? all.filter((q) => !q.resolved) : all;\n }\n } catch {\n // Dir doesn't exist — fall through to re-read\n }\n }\n\n try {\n const files = await readdir(this.deps.questionsDir);\n const questions = [];\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n const filePath = path.join(this.deps.questionsDir, file);\n const raw = await readMaybeEncryptedFile(filePath, this.deps._secureStoreKey, this.deps.baseDir);\n const parsed = this.deps.parseQuestionFile(raw, filePath);\n if (parsed) {\n questions.push(parsed);\n }\n }\n const sorted = questions.sort((a, b) => b.priority - a.priority);\n this.deps.storageManagerClass.questionsCache.set(cacheKey, { questions: sorted, loadedAt: Date.now() });\n return opts?.unresolvedOnly ? sorted.filter((q) => !q.resolved) : sorted;\n } catch {\n return [];\n }\n }\n}\nexport { readWindowedMemories, type WindowedMemoryReadOptions, type WindowedMemoryReadResult } from \"./windowed-memory-read.js\";\n","export type RawFrontmatterOwner = object;\n\nconst rawDocumentByMemory = new WeakMap<RawFrontmatterOwner, string>();\n\nexport function rememberRawFrontmatter<T extends RawFrontmatterOwner>(owner: T, raw: string): T {\n if (/^---\\r?\\n[\\s\\S]*?\\r?\\n---(?:\\r?\\n|$)/.test(raw)) rawDocumentByMemory.set(owner, raw);\n return owner;\n}\n\nexport function readRawMemoryDocument(owner: RawFrontmatterOwner): string | undefined {\n return rawDocumentByMemory.get(owner);\n}\n","import { stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getCachedMemories } from \"../memory-cache.js\";\nimport { readRawMemoryDocument } from \"./memory-frontmatter-metadata.js\";\nimport type { MemoryFile } from \"../types.js\";\nimport type { MemoryReadStore } from \"./memory-read-store.js\";\n\nexport interface WindowedMemoryReadOptions {\n maxMemories?: number;\n batchSize?: number;\n updatedAfter?: Date;\n /** Require candidate paths so malformed files can be reported by governance. */\n includeMalformedPaths?: boolean;\n}\n\nexport interface WindowedMemoryReadResult {\n memories: MemoryFile[];\n filePaths: string[];\n}\n\ntype WindowedMemoryReadStore = Pick<MemoryReadStore, \"readMemoriesWindow\">;\n\ntype HotMemoryCache = {\n enabled: boolean;\n baseDir: string;\n corpusVersion: number;\n cacheKeyId: string;\n ttlMs?: number;\n};\n\n/**\n * Serve the briefing-only updatedAfter shape from the warm corpus cache, then\n * delegate all other window reads to MemoryReadStore.\n */\nexport async function readWindowedMemories(\n store: WindowedMemoryReadStore,\n options: WindowedMemoryReadOptions,\n hotCache: HotMemoryCache,\n rememberMemorySnapshots: (memories: MemoryFile[]) => MemoryFile[]\n): Promise<WindowedMemoryReadResult> {\n if (\n options.updatedAfter !== undefined &&\n (!(options.updatedAfter instanceof Date) || !Number.isFinite(options.updatedAfter.getTime()))\n ) {\n throw new TypeError(\"updatedAfter must be a valid Date\");\n }\n if (\n hotCache.enabled &&\n options.updatedAfter !== undefined &&\n options.maxMemories === undefined &&\n options.batchSize === undefined &&\n options.includeMalformedPaths !== true\n ) {\n const cached = getCachedMemories(hotCache.baseDir, hotCache.corpusVersion, hotCache.cacheKeyId, hotCache.ttlMs);\n if (cached !== null) {\n const updatedAfterMs = options.updatedAfter.getTime();\n const selected = (\n await Promise.all(\n cached.map(async (memory) => {\n const timestampMs = await readWindowTimestamp(memory);\n return timestampMs === null || timestampMs >= updatedAfterMs ? memory : null;\n })\n )\n ).filter((memory): memory is MemoryFile => memory !== null);\n const memories = orderWindowMemories(selected, hotCache.baseDir);\n return { memories: rememberMemorySnapshots(memories), filePaths: memories.map((memory) => memory.path) };\n }\n }\n const result = await store.readMemoriesWindow(options);\n return {\n ...result,\n memories: rememberMemorySnapshots(result.memories),\n };\n}\n\nasync function readWindowTimestamp(memory: MemoryFile): Promise<number | null> {\n const rawDocument = readRawMemoryDocument(memory);\n const frontmatterBlock = rawDocument?.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/)?.[1];\n const rawTimestamp =\n frontmatterBlock?.match(/^[ \\t]*updated:[ \\t]*\"?([^\"\\r\\n]*)\"?/m)?.[1] ||\n frontmatterBlock?.match(/^[ \\t]*created:[ \\t]*\"?([^\"\\r\\n]*)\"?/m)?.[1] ||\n memory.frontmatter.updated ||\n memory.frontmatter.created;\n const timestampMs = typeof rawTimestamp === \"string\" ? Date.parse(rawTimestamp.trim()) : Number.NaN;\n if (Number.isFinite(timestampMs)) return timestampMs;\n try {\n return (await stat(memory.path)).mtimeMs;\n } catch {\n return null;\n }\n}\n\nfunction orderWindowMemories(memories: MemoryFile[], baseDir: string): MemoryFile[] {\n const correctionsRoot = path.join(baseDir, \"corrections\");\n const corrections = memories\n .filter((memory) => memory.path === correctionsRoot || memory.path.startsWith(`${correctionsRoot}${path.sep}`))\n .sort((left, right) => right.path.localeCompare(left.path));\n const facts = memories\n .filter((memory) => memory.path !== correctionsRoot && !memory.path.startsWith(`${correctionsRoot}${path.sep}`))\n .sort((left, right) => right.path.localeCompare(left.path));\n const ordered: MemoryFile[] = [];\n for (let index = 0; index < Math.max(corrections.length, facts.length); index += 1) {\n const correction = corrections[index];\n if (correction) ordered.push(correction);\n const fact = facts[index];\n if (fact) ordered.push(fact);\n }\n return ordered;\n}\n","import { log } from \"../logger.js\";\n\nexport interface CommittedInvalidationCallbacks {\n memoryId: string;\n recordProof: (() => Promise<void>) | undefined;\n clearProof: (() => Promise<void>) | undefined;\n deleteMemory: () => Promise<boolean>;\n afterDelete: () => Promise<void>;\n}\n\nasync function clearProofFailOpen(callbacks: CommittedInvalidationCallbacks): Promise<void> {\n await callbacks.clearProof?.().catch((error) => {\n log.warn(`failed to clear invalidation proof for ${callbacks.memoryId}: ${error}`);\n });\n}\n\nexport async function runCommittedInvalidation(\n callbacks: CommittedInvalidationCallbacks,\n): Promise<boolean> {\n let deletionCompleted = false;\n try {\n await callbacks.recordProof?.();\n if (!await callbacks.deleteMemory()) {\n await clearProofFailOpen(callbacks);\n return false;\n }\n deletionCompleted = true;\n await callbacks.afterDelete();\n return true;\n } catch (error) {\n if (!deletionCompleted) await clearProofFailOpen(callbacks);\n throw error;\n }\n}\n","const LAST_UPDATED_HEADER = /^\\*Last updated:[^*]*\\*$/;\nconst PROFILE_TITLE = /^ {0,3}#(?:[ \\t]+|$)/;\nconst MARKDOWN_HEADING = /^ {0,3}#{1,6}(?:[ \\t]+|$)/;\nconst MARKDOWN_LIST_ITEM = /^(?:[-+*]|\\d{1,9}[.)])[ \\t]+/;\nconst MARKDOWN_LIST_ITEM_CAN_INTERRUPT = /^(?:[-+*]|1[.)])[ \\t]+/;\nconst MARKDOWN_THEMATIC_BREAK = /^(?:(?:\\*[ \\t]*){3,}|(?:-[ \\t]*){3,}|(?:_[ \\t]*){3,})$/;\nconst MARKDOWN_SETEXT_UNDERLINE = /^(?:=+|-+)$/;\nconst MARKDOWN_BLOCK_QUOTE = /^>/;\nconst MARKDOWN_LINK_REFERENCE =\n /^\\[(?:\\\\.|[^\\\\\\[\\]])+\\]:[ \\t]*(?:<[^>\\n]*>|([^\\s]+))(?:[ \\t]+(?:\"[^\"\\n]*\"|'[^'\\n]*'|\\([^)\\n]*\\)))?$/;\nconst MARKDOWN_LINK_REFERENCE_LABEL = /^\\[(?:\\\\.|[^\\\\\\[\\]])+\\]:[ \\t]*$/;\nconst MARKDOWN_LINK_REFERENCE_CONTINUATION =\n /^ {1,3}(?:\"[^\"\\n]*\"|'[^'\\n]*'|\\([^)\\n]*\\))$/;\nconst MARKDOWN_LINK_REFERENCE_DESTINATION_CONTINUATION =\n /^ {1,3}(?:<[^>\\n]*>|(?![\"'(])[^\\s]+(?:[ \\t]+(?:\"[^\"\\n]*\"|'[^'\\n]*'|\\([^)\\n]*\\)))?)$/;\nconst UTF8_BOM = \"\\uFEFF\";\n\ntype FenceMarker = {\n indentation: number;\n character: string;\n length: number;\n trailing: string;\n};\n\nfunction isLastUpdatedHeader(line: string): boolean {\n const withoutBom = line.startsWith(UTF8_BOM) ? line.slice(1) : line;\n if (isIndentedCodeLine(withoutBom)) return false;\n return LAST_UPDATED_HEADER.test(withoutBom.trim());\n}\n\nfunction isIndentedCodeLine(line: string): boolean {\n let indentation = 0;\n while (line[indentation] === \" \") indentation += 1;\n return indentation >= 4 || line[indentation] === \"\\t\";\n}\n\nfunction getFenceMarker(line: string): FenceMarker | null {\n let indentation = 0;\n while (line[indentation] === \" \") indentation += 1;\n if (indentation > 3 || line[indentation] === \"\\t\") return null;\n const trimmed = line.slice(indentation);\n const character = trimmed[0];\n if (character !== \"`\" && character !== \"~\") return null;\n let length = 0;\n while (trimmed[length] === character) length += 1;\n if (length < 3) return null;\n const trailing = trimmed.slice(length);\n if (character === \"`\" && trailing.includes(\"`\")) return null;\n return { indentation, character, length, trailing };\n}\n\nfunction isClosingFence(fence: FenceMarker, openFence: FenceMarker): boolean {\n return (\n fence.character === openFence.character &&\n fence.length >= openFence.length &&\n fence.trailing.trim() === \"\"\n );\n}\n\nconst RAW_HTML_BLOCK_TAGS = [\"pre\", \"textarea\", \"script\", \"style\"] as const;\nconst HTML_BLOCK_TAGS = [\n \"address\",\n \"article\",\n \"aside\",\n \"base\",\n \"basefont\",\n \"blockquote\",\n \"body\",\n \"caption\",\n \"center\",\n \"col\",\n \"colgroup\",\n \"dd\",\n \"details\",\n \"dialog\",\n \"dir\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"frame\",\n \"frameset\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"head\",\n \"header\",\n \"hgroup\",\n \"hr\",\n \"html\",\n \"iframe\",\n \"legend\",\n \"li\",\n \"link\",\n \"main\",\n \"menu\",\n \"menuitem\",\n \"nav\",\n \"noframes\",\n \"ol\",\n \"optgroup\",\n \"option\",\n \"p\",\n \"param\",\n \"search\",\n \"section\",\n \"summary\",\n \"table\",\n \"tbody\",\n \"td\",\n \"tfoot\",\n \"th\",\n \"thead\",\n \"title\",\n \"tr\",\n \"track\",\n \"ul\",\n] as const;\n\ntype HtmlBlock = {\n endMarker: string | null;\n endsAtBlankLine: boolean;\n tagName: string | null;\n depth: number;\n};\ntype OpenHtmlBlock = HtmlBlock & {\n listIndentation: number | null;\n};\n\nfunction findHtmlBlockTag(line: string, tags: readonly string[]): string | null {\n const isClosing = line.startsWith(\"</\");\n const nameStart = isClosing ? 2 : 1;\n for (const tag of tags) {\n const nextCharacter = line[nameStart + tag.length];\n const isSelfClosingSlash =\n !isClosing && nextCharacter === \"/\" && line[nameStart + tag.length + 1] === \">\";\n if (\n line.startsWith(`${isClosing ? \"</\" : \"<\"}${tag}`) &&\n (nextCharacter === undefined ||\n nextCharacter === \">\" ||\n isSelfClosingSlash ||\n nextCharacter === \" \" ||\n nextCharacter === \"\\t\")\n ) {\n return tag;\n }\n }\n return null;\n}\n\ntype HtmlTag = {\n name: string;\n isClosing: boolean;\n isSelfClosing: boolean;\n};\n\nfunction isAsciiLetter(character: string): boolean {\n return (\n (character >= \"a\" && character <= \"z\") ||\n (character >= \"A\" && character <= \"Z\")\n );\n}\n\nfunction isHtmlTagNameCharacter(character: string): boolean {\n return (\n isAsciiLetter(character) ||\n (character >= \"0\" && character <= \"9\") ||\n character === \"-\"\n );\n}\nconst HTML_ATTRIBUTES =\n /^(?:[A-Za-z_:][A-Za-z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)(?:\\s+[A-Za-z_:][A-Za-z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*$/;\n\nfunction hasValidHtmlTagAttributes(attributeText: string, isClosing: boolean): boolean {\n const trimmed = attributeText.trim();\n if (isClosing || trimmed === \"\") return trimmed === \"\";\n const withoutSelfClosingSlash = trimmed.endsWith(\"/\")\n ? trimmed.slice(0, -1).trimEnd()\n : trimmed;\n return withoutSelfClosingSlash === \"\" || HTML_ATTRIBUTES.test(withoutSelfClosingSlash);\n}\n\nfunction findCompleteHtmlTag(line: string): HtmlTag | null {\n let index = 1;\n const isClosing = line[index] === \"/\";\n if (isClosing) index += 1;\n const nameStart = index;\n if (!isAsciiLetter(line[index] ?? \"\")) return null;\n while (isHtmlTagNameCharacter(line[index] ?? \"\")) index += 1;\n const nextCharacter = line[index] ?? \"\";\n if (\n nextCharacter !== \">\" &&\n nextCharacter !== \"/\" &&\n nextCharacter !== \" \" &&\n nextCharacter !== \"\\t\"\n ) {\n return null;\n }\n const name = line.slice(nameStart, index).toLowerCase();\n let quote: string | null = null;\n for (; index < line.length; index += 1) {\n const character = line[index]!;\n if (quote) {\n if (character === quote) quote = null;\n continue;\n }\n if (character === \"\\\"\" || character === \"'\") {\n quote = character;\n continue;\n }\n if (character === \">\" && line.slice(index + 1).trim() === \"\") {\n const tagBody = line.slice(nameStart, index).trimEnd();\n if (!hasValidHtmlTagAttributes(tagBody.slice(name.length), isClosing)) return null;\n return {\n name,\n isClosing,\n isSelfClosing: !isClosing && tagBody.endsWith(\"/\"),\n };\n }\n }\n return null;\n}\nfunction findHtmlTagPrefix(line: string): HtmlTag | null {\n let quote: string | null = null;\n for (let index = 1; index < line.length; index += 1) {\n const character = line[index]!;\n if (quote) {\n if (character === quote) quote = null;\n continue;\n }\n if (character === \"\\\"\" || character === \"'\") {\n quote = character;\n continue;\n }\n if (character !== \">\") continue;\n return findCompleteHtmlTag(line.slice(0, index + 1));\n }\n return null;\n}\n\n\nfunction findHtmlTags(line: string): HtmlTag[] {\n const tags: HtmlTag[] = [];\n let index = 0;\n while (index < line.length) {\n if (line[index] !== \"<\") {\n index += 1;\n continue;\n }\n\n let cursor = index + 1;\n const isClosing = line[cursor] === \"/\";\n if (isClosing) cursor += 1;\n const nameStart = cursor;\n if (!isAsciiLetter(line[cursor] ?? \"\")) {\n index += 1;\n continue;\n }\n while (isHtmlTagNameCharacter(line[cursor] ?? \"\")) cursor += 1;\n const name = line.slice(nameStart, cursor).toLowerCase();\n let quote: string | null = null;\n for (; cursor < line.length; cursor += 1) {\n const character = line[cursor] ?? \"\";\n if (quote) {\n if (character === quote) quote = null;\n continue;\n }\n if (character === \"\\\"\" || character === \"'\") {\n quote = character;\n continue;\n }\n if (character !== \">\") continue;\n const tagBody = line.slice(nameStart, cursor).trimEnd();\n tags.push({\n name,\n isClosing,\n isSelfClosing: !isClosing && tagBody.endsWith(\"/\"),\n });\n index = cursor + 1;\n break;\n }\n if (cursor >= line.length) break;\n }\n return tags;\n}\n\nfunction updateHtmlBlockDepth(\n htmlBlock: OpenHtmlBlock,\n line: string,\n skipFirstOpening: boolean,\n): OpenHtmlBlock | null {\n if (!htmlBlock.tagName) return htmlBlock;\n let depth = htmlBlock.depth;\n let skippedFirstOpening = !skipFirstOpening;\n for (const tag of findHtmlTags(line)) {\n if (tag.name !== htmlBlock.tagName) continue;\n if (tag.isClosing) {\n depth -= 1;\n } else if (!tag.isSelfClosing) {\n if (!skippedFirstOpening) {\n skippedFirstOpening = true;\n continue;\n }\n depth += 1;\n }\n }\n if (depth > 0) return { ...htmlBlock, depth };\n return htmlBlock.endsAtBlankLine\n ? { ...htmlBlock, endMarker: null, endsAtBlankLine: true, tagName: null, depth: 0 }\n : null;\n}\n\nfunction hasSpacedSelfClosingSlash(line: string): boolean {\n return /\\s\\/\\s*>/.test(line);\n}\nfunction findHtmlBlockStart(\n normalizedLine: string,\n trimmedLine: string,\n allowGenericHtmlBlock: boolean,\n): HtmlBlock | null {\n const rawTag = findHtmlBlockTag(normalizedLine, RAW_HTML_BLOCK_TAGS);\n if (rawTag) {\n const completeTag =\n findCompleteHtmlTag(trimmedLine) ?? findHtmlTagPrefix(trimmedLine);\n if (!completeTag && normalizedLine.startsWith(\"</\")) return null;\n if (completeTag?.isSelfClosing && !hasSpacedSelfClosingSlash(trimmedLine)) return null;\n const endMarker = `</${rawTag}>`;\n if (hasHtmlBlockEndMarker(normalizedLine, endMarker)) {\n if (!completeTag || completeTag.isClosing) return null;\n return { endMarker, endsAtBlankLine: false, tagName: null, depth: 0 };\n }\n return { endMarker, endsAtBlankLine: false, tagName: null, depth: 0 };\n }\n if (normalizedLine.startsWith(\"<!--\")) {\n return { endMarker: \"-->\", endsAtBlankLine: false, tagName: null, depth: 0 };\n }\n if (normalizedLine.startsWith(\"<?\")) {\n return { endMarker: \"?>\", endsAtBlankLine: false, tagName: null, depth: 0 };\n }\n if (trimmedLine.startsWith(\"<![CDATA[\")) {\n return { endMarker: \"]]>\", endsAtBlankLine: false, tagName: null, depth: 0 };\n }\n const declarationFirst = trimmedLine[2];\n if (\n trimmedLine.startsWith(\"<!\") &&\n declarationFirst &&\n declarationFirst >= \"A\" &&\n declarationFirst <= \"Z\"\n ) {\n return { endMarker: \">\", endsAtBlankLine: false, tagName: null, depth: 0 };\n }\n const blockTag = findHtmlBlockTag(normalizedLine, HTML_BLOCK_TAGS);\n if (blockTag) {\n const completeTag =\n findCompleteHtmlTag(trimmedLine) ?? findHtmlTagPrefix(trimmedLine);\n if (!completeTag) {\n return { endMarker: null, endsAtBlankLine: true, tagName: null, depth: 0 };\n }\n if (completeTag.isSelfClosing) {\n return { endMarker: null, endsAtBlankLine: true, tagName: null, depth: 0 };\n }\n return { endMarker: `</${blockTag}>`, endsAtBlankLine: true, tagName: blockTag, depth: 1 };\n }\n if (!allowGenericHtmlBlock) return null;\n const genericTag = findCompleteHtmlTag(trimmedLine);\n if (!genericTag) return null;\n if (genericTag.isClosing || genericTag.isSelfClosing) {\n return { endMarker: null, endsAtBlankLine: true, tagName: null, depth: 0 };\n }\n return { endMarker: `</${genericTag.name}>`, endsAtBlankLine: true, tagName: genericTag.name, depth: 1 };\n}\n\n\ntype ProfileLine = {\n content: string;\n ending: string;\n};\n\nfunction parseProfileLines(content: string): ProfileLine[] {\n const segments = content.split(/(\\r\\n|\\n|\\r)/);\n const lines: ProfileLine[] = [];\n for (let index = 0; index < segments.length; index += 2) {\n lines.push({\n content: segments[index] ?? \"\",\n ending: segments[index + 1] ?? \"\",\n });\n }\n return lines;\n}\n\nfunction renderProfileLines(lines: ProfileLine[]): string {\n let rendered = \"\";\n for (const line of lines) {\n rendered += line.content + line.ending;\n }\n return rendered;\n}\n\nfunction findFrontmatterEnd(lines: ProfileLine[]): number {\n const firstLine = lines[0]?.content.startsWith(UTF8_BOM) ? lines[0].content.slice(1) : lines[0]?.content;\n if (firstLine !== \"---\") return -1;\n for (let index = 1; index < lines.length; index += 1) {\n const line = lines[index]?.content.trimEnd();\n if (line === \"---\" || line === \"...\") return index;\n }\n return -1;\n}\n\nfunction hasHtmlBlockEndMarker(line: string, endMarker: string): boolean {\n return line.includes(endMarker);\n}\n\nfunction shouldCloseHtmlBlock(line: string, endMarker: string): boolean {\n const normalizedLine = line.trimStart().toLowerCase();\n return normalizedLine.includes(endMarker.toLowerCase());\n}\n\n\nfunction canStartGenericHtmlBlock(\n lines: ProfileLine[],\n index: number,\n previousHtmlTerminator: boolean,\n): boolean {\n const previousLine = lines[index - 1]?.content.trim() ?? \"\";\n if (previousLine === \"\") return true;\n return (\n isCompletedIndentedCodeBlock(lines, index) ||\n (isMetadataBoundary(previousLine, previousHtmlTerminator) &&\n !isLastUpdatedHeader(previousLine) &&\n !MARKDOWN_LIST_ITEM.test(previousLine) &&\n !MARKDOWN_BLOCK_QUOTE.test(previousLine))\n );\n}\n\nfunction isHtmlBlockBoundary(\n lines: ProfileLine[],\n index: number,\n htmlTerminatorIndexes: ReadonlySet<number>,\n): boolean {\n if (htmlTerminatorIndexes.has(index)) return true;\n const line = lines[index]?.content ?? \"\";\n const parserLine = index === 0 && line.startsWith(UTF8_BOM) ? line.slice(1) : line;\n if (isIndentedCodeLine(parserLine) || getFenceMarker(parserLine)) return false;\n const trimmedLine = parserLine.trimStart();\n return (\n findHtmlBlockStart(\n trimmedLine.toLowerCase(),\n trimmedLine,\n canStartGenericHtmlBlock(lines, index, htmlTerminatorIndexes.has(index - 1)),\n ) !== null\n );\n}\n\nfunction visitProfileMetadataLines(\n lines: ProfileLine[],\n visit: (line: string, index: number) => void,\n onHtmlBlockTerminator?: (index: number) => void,\n onFenceBlockTerminator?: (index: number) => void,\n): void {\n const frontmatterEnd = findFrontmatterEnd(lines);\n const htmlTerminatorIndexes = new Set<number>();\n const markHtmlTerminator = (index: number): void => {\n htmlTerminatorIndexes.add(index);\n onHtmlBlockTerminator?.(index);\n };\n let openFence: (FenceMarker & { listIndentation: number | null }) | null = null;\n let openHtmlBlock: OpenHtmlBlock | null = null;\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index]?.content ?? \"\";\n const parserLine = index === 0 && line.startsWith(UTF8_BOM) ? line.slice(1) : line;\n if (index <= frontmatterEnd) continue;\n const fence = getFenceMarker(parserLine);\n if (openFence) {\n const indentation = parserLine.length - parserLine.trimStart().length;\n const leavesListContainer =\n openFence.listIndentation !== null &&\n parserLine.trim() !== \"\" &&\n indentation < openFence.listIndentation;\n if (!leavesListContainer) {\n if (fence && isClosingFence(fence, openFence)) openFence = null;\n continue;\n }\n openFence = null;\n if (index > 0) onFenceBlockTerminator?.(index - 1);\n }\n const trimmedLine = parserLine.trimStart();\n const normalizedLine = trimmedLine.toLowerCase();\n if (openHtmlBlock) {\n const indentation = parserLine.length - parserLine.trimStart().length;\n const leavesListContainer =\n openHtmlBlock.listIndentation !== null &&\n parserLine.trim() !== \"\" &&\n indentation < openHtmlBlock.listIndentation;\n if (!leavesListContainer) {\n if (openHtmlBlock.endsAtBlankLine && normalizedLine === \"\") {\n openHtmlBlock = null;\n continue;\n }\n if (openHtmlBlock.tagName) {\n const nextHtmlBlock = updateHtmlBlockDepth(openHtmlBlock, normalizedLine, false);\n if (!nextHtmlBlock) markHtmlTerminator(index);\n openHtmlBlock = nextHtmlBlock;\n continue;\n }\n if (openHtmlBlock.endMarker && shouldCloseHtmlBlock(normalizedLine, openHtmlBlock.endMarker)) {\n openHtmlBlock = null;\n markHtmlTerminator(index);\n }\n continue;\n }\n openHtmlBlock = null;\n if (index > 0) markHtmlTerminator(index - 1);\n }\n if (isIndentedCodeLine(parserLine)) continue;\n if (fence) {\n openFence = {\n ...fence,\n listIndentation: isNestedListContent(lines, index, fence.indentation)\n ? fence.indentation\n : null,\n };\n continue;\n }\n const htmlBlock = findHtmlBlockStart(\n normalizedLine,\n trimmedLine,\n canStartGenericHtmlBlock(lines, index, htmlTerminatorIndexes.has(index - 1)),\n );\n if (htmlBlock) {\n markHtmlTerminator(index);\n const indentation = parserLine.length - parserLine.trimStart().length;\n const htmlBlockWithContainer = {\n ...htmlBlock,\n listIndentation: isNestedListContent(lines, index, indentation) ? indentation : null,\n };\n if (htmlBlock.tagName) {\n openHtmlBlock = updateHtmlBlockDepth(htmlBlockWithContainer, normalizedLine, true);\n if (!openHtmlBlock) markHtmlTerminator(index);\n } else if (htmlBlock.endMarker && shouldCloseHtmlBlock(normalizedLine, htmlBlock.endMarker)) {\n openHtmlBlock = null;\n markHtmlTerminator(index);\n } else {\n openHtmlBlock = htmlBlockWithContainer;\n }\n continue;\n }\n visit(line, index);\n }\n}\n\nfunction isCompletedIndentedCodeBlock(lines: ProfileLine[], index: number): boolean {\n if (!isIndentedCodeLine(lines[index - 1]?.content ?? \"\")) return false;\n let sawBlank = false;\n for (let previousIndex = index - 2; previousIndex >= 0; previousIndex -= 1) {\n const previousLine = lines[previousIndex]?.content ?? \"\";\n if (previousLine.trim() === \"\") {\n sawBlank = true;\n continue;\n }\n if (isIndentedCodeLine(previousLine)) continue;\n return sawBlank;\n }\n return true;\n}\n\nfunction isListContinuation(lines: ProfileLine[], index: number, indentation: number): boolean {\n for (let previousIndex = index - 1; previousIndex >= 0; previousIndex -= 1) {\n const previousLine = lines[previousIndex]?.content ?? \"\";\n if (previousLine.trim() === \"\") return false;\n const previousIndentation = previousLine.length - previousLine.trimStart().length;\n if (previousIndentation > indentation) continue;\n const previousBoundaryLine = previousLine.trimStart();\n if (MARKDOWN_LIST_ITEM.test(previousBoundaryLine)) return true;\n if (\n MARKDOWN_HEADING.test(previousBoundaryLine) ||\n MARKDOWN_THEMATIC_BREAK.test(previousBoundaryLine) ||\n MARKDOWN_BLOCK_QUOTE.test(previousBoundaryLine) ||\n getFenceMarker(previousLine) !== null\n ) {\n return false;\n }\n }\n return false;\n}\n\nfunction isNestedListContent(lines: ProfileLine[], index: number, indentation: number): boolean {\n for (let previousIndex = index - 1; previousIndex >= 0; previousIndex -= 1) {\n const previousLine = lines[previousIndex]?.content ?? \"\";\n if (previousLine.trim() === \"\") continue;\n const previousIndentation = previousLine.length - previousLine.trimStart().length;\n if (previousIndentation >= indentation) continue;\n if (\n MARKDOWN_LIST_ITEM.test(previousLine.trimStart()) ||\n isListContinuation(lines, previousIndex, indentation)\n ) {\n return true;\n }\n break;\n }\n return false;\n}\n\nfunction isValidBareLinkDestination(destination: string): boolean {\n let parentheses = 0;\n for (let index = 0; index < destination.length; index += 1) {\n const character = destination[index];\n if (character === \"\\\\\") {\n if (index + 1 >= destination.length) return false;\n index += 1;\n continue;\n }\n if (character === \"<\" || character === \">\") return false;\n if (character === \"(\") {\n parentheses += 1;\n } else if (character === \")\") {\n if (parentheses === 0) return false;\n parentheses -= 1;\n }\n }\n return parentheses === 0;\n}\n\nfunction isMarkdownLinkReferenceDefinition(line: string): boolean {\n const match = MARKDOWN_LINK_REFERENCE.exec(line);\n return match !== null && (match[1] === undefined || isValidBareLinkDestination(match[1]));\n}\n\nfunction isMarkdownLinkReferenceDefinitionEnd(lines: ProfileLine[], index: number): boolean {\n const line = lines[index]?.content ?? \"\";\n const boundaryLine = /^ {0,3}(?=\\S)/.test(line) ? line.trimStart() : line;\n if (isMarkdownLinkReferenceDefinition(boundaryLine)) return true;\n if (MARKDOWN_LINK_REFERENCE_CONTINUATION.test(line)) {\n const previousLine = lines[index - 1]?.content ?? \"\";\n const previousBoundaryLine =\n /^ {0,3}(?=\\S)/.test(previousLine) ? previousLine.trimStart() : previousLine;\n if (isMarkdownLinkReferenceDefinition(previousBoundaryLine)) return true;\n const destinationLine = lines[index - 1]?.content ?? \"\";\n if (!MARKDOWN_LINK_REFERENCE_DESTINATION_CONTINUATION.test(destinationLine)) return false;\n const labelLine = lines[index - 2]?.content ?? \"\";\n const labelBoundaryLine =\n /^ {0,3}(?=\\S)/.test(labelLine) ? labelLine.trimStart() : labelLine;\n return MARKDOWN_LINK_REFERENCE_LABEL.test(labelBoundaryLine);\n }\n if (!MARKDOWN_LINK_REFERENCE_DESTINATION_CONTINUATION.test(line)) return false;\n const previousLine = lines[index - 1]?.content ?? \"\";\n const previousBoundaryLine =\n /^ {0,3}(?=\\S)/.test(previousLine) ? previousLine.trimStart() : previousLine;\n return MARKDOWN_LINK_REFERENCE_LABEL.test(previousBoundaryLine);\n}\n\nfunction isProfileTitleLine(lines: ProfileLine[], index: number, line: string): boolean {\n const titleLine = index === 0 && line.startsWith(UTF8_BOM) ? line.slice(1) : line;\n if (!PROFILE_TITLE.test(titleLine)) return false;\n const indentation = titleLine.length - titleLine.trimStart().length;\n if (indentation === 0 || index === 0) return true;\n const previousLine = lines[index - 1]?.content.trim() ?? \"\";\n return previousLine === \"\"\n ? !isNestedListContent(lines, index, indentation)\n : previousLine === \"---\" || previousLine === \"...\";\n}\n\nfunction findProfileTitleIndex(lines: ProfileLine[]): number {\n let titleIndex = -1;\n visitProfileMetadataLines(lines, (line, index) => {\n if (titleIndex >= 0) return;\n if (isProfileTitleLine(lines, index, line)) titleIndex = index;\n });\n return titleIndex;\n}\n\nfunction isSetextHeadingText(line: string): boolean {\n const withoutBom = line.startsWith(UTF8_BOM) ? line.slice(1) : line;\n const boundaryLine = withoutBom.trim();\n return (\n boundaryLine !== \"\" &&\n !MARKDOWN_HEADING.test(boundaryLine) &&\n !MARKDOWN_LIST_ITEM.test(boundaryLine) &&\n !MARKDOWN_BLOCK_QUOTE.test(boundaryLine) &&\n !MARKDOWN_THEMATIC_BREAK.test(boundaryLine) &&\n !isMarkdownLinkReferenceDefinition(boundaryLine) &&\n getFenceMarker(withoutBom) === null\n );\n}\n\nfunction isMetadataBoundary(\n line: string,\n htmlTerminator = false,\n allowSetext = true,\n allowParagraphListInterrupt = false,\n setextPreviousLine = \"\",\n): boolean {\n const listPattern = allowParagraphListInterrupt\n ? MARKDOWN_LIST_ITEM_CAN_INTERRUPT\n : MARKDOWN_LIST_ITEM;\n const boundaryLine = /^ {0,3}(?=\\S)/.test(line) ? line.trimStart() : line;\n const isSetextUnderline =\n !allowSetext &&\n MARKDOWN_SETEXT_UNDERLINE.test(boundaryLine) &&\n isSetextHeadingText(setextPreviousLine);\n return (\n line.trim() === \"\" ||\n MARKDOWN_HEADING.test(boundaryLine) ||\n listPattern.test(boundaryLine) ||\n (allowSetext && MARKDOWN_SETEXT_UNDERLINE.test(boundaryLine)) ||\n (MARKDOWN_THEMATIC_BREAK.test(boundaryLine) && !isSetextUnderline) ||\n MARKDOWN_BLOCK_QUOTE.test(boundaryLine) ||\n isMarkdownLinkReferenceDefinition(boundaryLine) ||\n isLastUpdatedHeader(line) ||\n getFenceMarker(line) !== null ||\n htmlTerminator\n );\n}\n\nfunction isStandaloneMetadataLine(\n lines: ProfileLine[],\n index: number,\n frontmatterEnd: number,\n htmlTerminatorIndexes: ReadonlySet<number>,\n fenceTerminatorIndexes: ReadonlySet<number>,\n standaloneHeaderIndexes: ReadonlySet<number>,\n): boolean {\n const currentLine = lines[index]?.content ?? \"\";\n const currentWithoutBom = currentLine.startsWith(UTF8_BOM)\n ? currentLine.slice(1)\n : currentLine;\n const indentation = currentWithoutBom.length - currentWithoutBom.trimStart().length;\n const previousLine = lines[index - 1]?.content.trimEnd() ?? \"\";\n const nextLine = lines[index + 1]?.content.trimEnd() ?? \"\";\n const previousWithoutBom = previousLine.startsWith(UTF8_BOM)\n ? previousLine.slice(1)\n : previousLine;\n const nextWithoutBom = nextLine.startsWith(UTF8_BOM) ? nextLine.slice(1) : nextLine;\n const previousLinkReferenceBoundary = isMarkdownLinkReferenceDefinitionEnd(lines, index - 1);\n const previousMetadataBoundary =\n isCompletedIndentedCodeBlock(lines, index) ||\n previousLinkReferenceBoundary ||\n fenceTerminatorIndexes.has(index - 1) ||\n (isMetadataBoundary(\n previousWithoutBom,\n htmlTerminatorIndexes.has(index - 1),\n ) &&\n (!isLastUpdatedHeader(previousWithoutBom) || standaloneHeaderIndexes.has(index - 1)));\n const nextHtmlBlockBoundary = isHtmlBlockBoundary(\n lines,\n index + 1,\n htmlTerminatorIndexes,\n );\n const nextMetadataBoundary =\n nextHtmlBlockBoundary ||\n isMetadataBoundary(\n nextWithoutBom,\n htmlTerminatorIndexes.has(index + 1),\n false,\n true,\n currentWithoutBom,\n );\n const previousContainerMarker =\n !MARKDOWN_THEMATIC_BREAK.test(previousWithoutBom) &&\n (MARKDOWN_LIST_ITEM.test(previousWithoutBom) || MARKDOWN_BLOCK_QUOTE.test(previousWithoutBom));\n const nestedListContent =\n indentation > 0 && isNestedListContent(lines, index, indentation);\n const startsBlock =\n (index === 0 || index === frontmatterEnd + 1 || previousMetadataBoundary) &&\n !previousContainerMarker &&\n !nestedListContent;\n const endsBlock = index === lines.length - 1 || nextMetadataBoundary;\n const compactHeaderAfterTitle = isProfileTitleLine(lines, index - 1, previousWithoutBom);\n const compactHeaderAfterHeader =\n isLastUpdatedHeader(previousWithoutBom) && standaloneHeaderIndexes.has(index - 1);\n return startsBlock && (endsBlock || compactHeaderAfterTitle || compactHeaderAfterHeader);\n}\n\nfunction findProfileHeaderIndexes(lines: ProfileLine[]): number[] {\n const indexes: number[] = [];\n const frontmatterEnd = findFrontmatterEnd(lines);\n const htmlTerminatorIndexes = new Set<number>();\n const fenceTerminatorIndexes = new Set<number>();\n const standaloneHeaderIndexes = new Set<number>();\n visitProfileMetadataLines(\n lines,\n (line, index) => {\n if (\n isLastUpdatedHeader(line) &&\n isStandaloneMetadataLine(\n lines,\n index,\n frontmatterEnd,\n htmlTerminatorIndexes,\n fenceTerminatorIndexes,\n standaloneHeaderIndexes,\n )\n ) {\n indexes.push(index);\n standaloneHeaderIndexes.add(index);\n }\n },\n (index) => htmlTerminatorIndexes.add(index),\n (index) => fenceTerminatorIndexes.add(index),\n );\n return indexes;\n}\n\nfunction insertHeaderAfter(lines: ProfileLine[], index: number, header: string): void {\n const insertAt = index + 1;\n const ending = lines[index]?.ending || lines[insertAt]?.ending || \"\\n\";\n if (lines[insertAt]?.content.trim() === \"\") {\n lines.splice(\n insertAt + 1,\n 0,\n { content: header, ending },\n { content: \"\", ending },\n );\n } else {\n lines.splice(\n insertAt,\n 0,\n { content: \"\", ending },\n { content: header, ending },\n { content: \"\", ending },\n );\n }\n}\n\nfunction prependHeader(lines: ProfileLine[], header: string): string {\n const frontmatterEnd = findFrontmatterEnd(lines);\n if (frontmatterEnd >= 0) {\n insertHeaderAfter(lines, frontmatterEnd, header);\n return renderProfileLines(lines);\n }\n const ending = lines[0]?.ending || \"\\n\";\n if (lines[0]?.content.startsWith(UTF8_BOM)) {\n lines[0].content = lines[0].content.slice(1);\n lines.unshift(\n { content: `${UTF8_BOM}${header}`, ending },\n { content: \"\", ending },\n );\n return renderProfileLines(lines);\n }\n lines.unshift(\n { content: header, ending },\n { content: \"\", ending },\n );\n return renderProfileLines(lines);\n}\n\nexport function renderProfileWithLastUpdated(content: string, updatedAt: string): string {\n const lines = parseProfileLines(content);\n const header = `*Last updated: ${updatedAt}*`;\n const titleIndex = findProfileTitleIndex(lines);\n const headerIndexes = findProfileHeaderIndexes(lines);\n\n if (headerIndexes.length > 0) {\n const firstHeaderIndex = headerIndexes[0];\n if (firstHeaderIndex === undefined) return renderProfileLines(lines);\n const canonicalIndex =\n titleIndex >= 0\n ? headerIndexes.find((index) => index > titleIndex) ?? firstHeaderIndex\n : firstHeaderIndex;\n const preserveBomAtFileStart = headerIndexes.some((index) =>\n lines[index].content.startsWith(UTF8_BOM),\n );\n const bomPrefix =\n canonicalIndex === 0 && lines[canonicalIndex].content.startsWith(UTF8_BOM)\n ? UTF8_BOM\n : \"\";\n lines[canonicalIndex].content = `${bomPrefix}${header}`;\n for (let index = headerIndexes.length - 1; index >= 0; index -= 1) {\n const headerIndex = headerIndexes[index];\n if (headerIndex === undefined || headerIndex === canonicalIndex) continue;\n lines.splice(headerIndex, 1);\n }\n if (preserveBomAtFileStart && !lines[0].content.startsWith(UTF8_BOM)) {\n lines[0].content = `${UTF8_BOM}${lines[0].content}`;\n }\n return renderProfileLines(lines);\n }\n\n if (titleIndex < 0) return prependHeader(lines, header);\n\n insertHeaderAfter(lines, titleIndex, header);\n return renderProfileLines(lines);\n}\n\n/**\n * OKF v0.1 profile frontmatter (issue #1946). `profile.md` gains a leading\n * frontmatter block so the memory directory is a conformant OKF knowledge\n * bundle; every reader strips it so the bytes injected into prompts are\n * unchanged. Line-scan based (no regex) per the regex-safety rule.\n */\n\n/** Prepend the OKF block when enabled and not already present. No-op otherwise. */\nexport function withOkfProfileFrontmatter(content: string, timestamp: string, enabled: boolean): string {\n if (!enabled || stripOkfProfileFrontmatter(content) !== content) return content;\n return `---\\ntype: Profile\\ntitle: User Profile\\ntimestamp: ${timestamp}\\n---\\n${content}`;\n}\n\n/**\n * Strip the OKF profile block from the start of `profile.md` content.\n * Only a leading block whose keys include `type: Profile` is removed, so\n * hand-written content without the marker round-trips byte-identically.\n */\nexport function stripOkfProfileFrontmatter(content: string): string {\n if (!content.startsWith(\"---\\n\") && !content.startsWith(\"---\\r\\n\")) return content;\n const lines = content.split(\"\\n\");\n for (let index = 1; index < lines.length; index += 1) {\n const line = lines[index]!;\n if (line === \"---\" || line === \"---\\r\") {\n return lines.slice(1, index).some((l) => l.startsWith(\"type: Profile\"))\n ? lines.slice(index + 1).join(\"\\n\")\n : content;\n }\n if (line === \"\" || line === \"\\r\" || line === \"...\") return content;\n }\n return content;\n}\n","/**\n * Question file format (issue #1946 extraction from storage.ts so the\n * surface file stays under its structural ceiling). Pure text parsing —\n * no filesystem, no caches; StorageManager delegates through so the\n * selfDeps consumers (MemoryReadStore) keep their seam unchanged.\n */\nimport path from \"node:path\";\n\nexport interface ParsedQuestionFile {\n id: string;\n question: string;\n context: string;\n priority: number;\n resolved: boolean;\n created: string;\n filePath: string;\n}\n\nexport function parseQuestionFile(raw: string, filePath: string): ParsedQuestionFile | null {\n if (!raw.startsWith(\"---\\n\")) return null;\n const close = raw.indexOf(\"\\n---\\n\\n\", 4);\n if (close === -1) return null;\n const frontmatterStr = raw.slice(4, close);\n const body = raw.slice(close + 6).trim();\n\n const id = extractFrontmatterValue(frontmatterStr, \"id\") ?? path.basename(filePath, \".md\");\n const created = extractFrontmatterValue(frontmatterStr, \"created\") ?? \"\";\n const priority = parseFloat(extractFrontmatterValue(frontmatterStr, \"priority\") ?? \"0.5\");\n const resolved = extractFrontmatterValue(frontmatterStr, \"resolved\") === \"true\";\n\n const contextMarker = \"**Context:**\";\n const contextAt = body.indexOf(contextMarker);\n const question = contextAt === -1 ? body : body.slice(0, contextAt).trim();\n const context = contextAt === -1 ? \"\" : body.slice(contextAt + contextMarker.length).trim();\n\n return { id, question, context, priority, resolved, created, filePath };\n}\n\nfunction extractFrontmatterValue(frontmatter: string, key: string): string | null {\n const prefix = `${key}:`;\n for (const line of frontmatter.split(\"\\n\")) {\n if (!line.startsWith(prefix)) continue;\n let value = line.slice(prefix.length).trim();\n if (value.startsWith('\"') && value.endsWith('\"') && value.length >= 2) {\n value = value.slice(1, -1);\n }\n return value;\n }\n return null;\n}\n","/**\n * OKF v0.1 `type` mapping (issue #1946) — the single source of truth for\n * the inert `type` metadata emitted alongside Remnic's canonical fields.\n *\n * `category` remains the canonical internal field; `type` is\n * presentation/interop metadata for OKF consumers and NEVER overrides\n * `category` on parse (the parser reads `type` into its own field only).\n */\nimport path from \"node:path\";\n\n/** OKF `type` values derived from Remnic memory categories. */\nexport const OKF_TYPE_BY_CATEGORY: Readonly<Record<string, string>> = Object.freeze({\n fact: \"Memory Fact\",\n decision: \"Decision\",\n preference: \"Preference\",\n commitment: \"Commitment\",\n relationship: \"Relationship\",\n principle: \"Principle\",\n moment: \"Moment\",\n skill: \"Skill\",\n correction: \"Correction\",\n rule: \"Rule\",\n});\n\n/** Fallback for categories not listed above (unknown/future categories). */\nexport const OKF_TYPE_FALLBACK = \"Memory\";\n\n/** Stable domain seam over the category table (single mapping source, AGENTS.md pattern 9). */\nexport function okfTypeForCategory(category: string): string {\n return OKF_TYPE_BY_CATEGORY[category] ?? OKF_TYPE_FALLBACK;\n}\n\n/** Artifact memories report `Artifact` regardless of their storage category. */\nexport function okfTypeForMemory(fm: { category: string; artifactType?: string }): string {\n return fm.artifactType ? \"Artifact\" : okfTypeForCategory(fm.category);\n}\n\n/** OKF types for entity files, derived from the entity kind. */\nexport const OKF_TYPE_BY_ENTITY_KIND: Readonly<Record<string, string>> = Object.freeze({\n person: \"Person\",\n company: \"Company\",\n organization: \"Organization\",\n project: \"Project\",\n topic: \"Topic\",\n technology: \"Technology\",\n place: \"Place\",\n event: \"Event\",\n});\n\n/** Stable domain seam over the entity-kind table (single mapping source). */\nexport function okfTypeForEntityKind(kind: string | undefined): string {\n const normalized = kind?.trim().toLowerCase();\n return (normalized !== undefined && OKF_TYPE_BY_ENTITY_KIND[normalized]) || \"Entity\";\n}\n\n/** Fixed OKF types for non-memory bundle files. */\nexport const OKF_PROFILE_TYPE = \"Profile\";\nexport const OKF_QUESTION_TYPE = \"Question\";\nexport const OKF_DECISION_RECORD_TYPE = \"Decision Record\";\n\n/**\n * OKF §6/§7 reserve `index.md` and `log.md` for bundle-level files with a\n * different contract. Remnic never writes them (separate issue), and writes\n * targeting those basenames are rejected outright so a stray ID can never\n * shadow a reserved bundle file.\n */\nexport const OKF_RESERVED_BASENAMES: Readonly<Record<string, true>> = Object.freeze({\n \"index.md\": true,\n \"log.md\": true,\n});\n\nexport function assertNotOkfReservedBasename(filePath: string): void {\n const basename = path.basename(filePath);\n if (OKF_RESERVED_BASENAMES[basename] === true) {\n throw new Error(\n `OKF reserved basename '${basename}' is not a valid memory file target (${filePath}); OKF §6/§7 reserves it for bundle-level files.`,\n );\n }\n}\n","/**\n * Live self-deps factory (issue #1526 seam 27).\n *\n * Every coordinator extracted from the orchestrator (seams 4–26) takes a\n * deps bundle whose property names MATCH the orchestrator's own member\n * names, wired as live accessors / late-binding arrows so instance-level\n * test stubs and subclass overrides keep taking effect. Those hand-written\n * wiring blocks were ~100 lines each and pure repetition. This factory\n * replaces them with a Proxy that preserves the exact semantics:\n *\n * - property GET reads `self[prop]` live on every access (late binding —\n * an instance stub installed after coordinator creation is observed);\n * - method properties are bound to `self` at access time, so `this`\n * inside the orchestrator method stays the orchestrator;\n * - property SET writes through to `self` (gate fields like\n * `deferredReady` / `lastXraySnapshot` stay on the orchestrator);\n * - getters on `self` (e.g. `fastLlmForRerank`) are invoked live.\n *\n * The `as unknown as T` cast is deliberate: the deps interfaces reference\n * the orchestrator's PRIVATE members, which TypeScript cannot verify\n * structurally from outside the class. The interfaces remain fully\n * enforced on the coordinator side. Per-access `bind` costs nanoseconds\n * and allocates one closure per property access — negligible against the\n * I/O-bound work every coordinator method performs.\n */\nexport function selfDeps<T extends object>(self: object): T {\n const source = self as Record<PropertyKey, unknown>;\n return new Proxy(Object.create(null) as object, {\n get(_target, prop) {\n const value = source[prop as string];\n // Bind ONLY prototype/concise methods (they have no own `prototype`\n // property). Class-valued deps (e.g. `storageManagerClass`, used by\n // the storage decomposition to reach shared static caches) must pass\n // through unbound: Function.prototype.bind returns a bound function\n // WITHOUT the original's own static properties, which silently\n // strips the class's statics. Plain data and arrows also pass\n // through unchanged (arrows ignore bind receivers anyway).\n return typeof value === \"function\" &&\n !Object.prototype.hasOwnProperty.call(value, \"prototype\")\n ? (value as (...args: unknown[]) => unknown).bind(self)\n : value;\n },\n set(_target, prop, value) {\n // Fail fast on writes to properties the orchestrator does not\n // declare (Kilo review on PR #1801): returning false makes the\n // assignment throw a TypeError in strict mode, matching the\n // error-safety of the hand-written accessor blocks this factory\n // replaced. Legitimate gate-field writes (deferredReady,\n // lastXraySnapshot, …) all target existing members.\n if (!((prop as string) in source)) return false;\n source[prop as string] = value;\n return true;\n },\n has(_target, prop) {\n return (prop as string) in source;\n },\n }) as unknown as T;\n}\n","/**\n * Entity store (extracted from storage.ts StorageManager; god-file\n * decomposition, #1526 playbook: verbatim move + live selfDeps wiring so\n * Object.create(prototype) fakes and instance stubs keep working).\n *\n * Owns the entity file subsystem:\n * - entity name normalization (alias table aware)\n * - entity read/write (incl. schema-validated structured sections)\n * - entity synthesis updates and knowledge-index construction\n * - fragmented-entity merge (consolidation)\n */\n\nimport { readdir, unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { checkCorpusReadAbort, type CorpusReadOptions } from \"../corpus-read-cancellation.js\";\nimport { normalizeEntityStructuredSection, sortStructuredSectionsBySchema } from \"../entity-schema.js\";\nimport { withEntityCanonicalMutationLock } from \"./entity-canonical-id-lock.js\";\nimport { log } from \"../logger.js\";\nimport { getCachedEntities, setCachedEntities } from \"../memory-cache.js\";\nimport type { VersionTrigger } from \"../page-versioning.js\";\nimport { SecureStoreLockedError } from \"../secure-store/secure-fs.js\";\nimport type {\n EntityActivityEntry,\n EntityFile,\n EntityRelationship,\n EntityStructuredSection,\n PluginConfig,\n ScoredEntity,\n} from \"../types.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport {\n reconcileIfJournalMovedSync,\n requestEntityCanonicalIdReconcileSync,\n resolveHistoricalEntityCanonicalId,\n} from \"./entity-canonical-id-references.js\";\nimport {\n buildEntitySchemaCacheKey,\n compareEntityTimestamps,\n compileEntityFacts,\n countEntityStructuredFacts,\n fingerprintEntityStructuredFacts,\n normalizeEntityName as normalizeEntityNameShared,\n normalizeStructuredSectionFactsWithOrigins,\n parseEntityFile,\n serializeEntityFile,\n StorageManager,\n} from \"../storage.js\";\n// Issue #1533 Phase B: importers take entity-file parsing from this storage/\n// subsystem module, not the storage.ts god file (see check-ratchets.mjs).\nexport { parseEntityFile } from \"../storage.js\";\nimport { parseOriginClass } from \"../security/origin-authority.js\";\n\nexport interface EntityStoreDeps {\n /** Live class object of the host instance — shared static caches (see storage.ts storageManagerClass). */\n readonly storageManagerClass: typeof StorageManager;\n readonly baseDir: string;\n bumpMemoryStatusVersion(): void;\n /** Entity-mutation sentinel for the migration fingerprint (issue #2213). */\n bumpEntityMutationVersion(): void;\n ensureDirectories(): Promise<void>;\n readonly entitiesDir: string;\n readonly entitySchemas: PluginConfig[\"entitySchemas\"] | undefined;\n currentHistoricalIds(): Readonly<Record<string, string>>;\n findMatchingEntity(proposedName: string, type: string): Promise<string | null>;\n getEntityCacheSecureStoreKey(): string;\n getEntityMutationVersion(): number;\n getMemoryStatusVersion(): number;\n invalidateKnowledgeIndexCache(): void;\n knowledgeIndexCache: { result: string; builtAt: number } | null;\n okfConformanceEnabled(): boolean;\n normalizeEntityName(raw: string, type: string): string;\n readAllEntityFiles(): Promise<EntityFile[]>;\n readStorageSecureFile(filePath: string): Promise<string>;\n removeEntitySynthesisQueueEntries(entityNames: string[]): Promise<void>;\n resolveEntityFilePath(name: string): string | null;\n snapshotBeforeWrite(filePath: string, trigger: VersionTrigger): Promise<void>;\n readonly userAliases: Record<string, string>;\n writeStorageSecureFile(filePath: string, content: string | Buffer): Promise<void>;\n}\n\nexport class EntityStore {\n constructor(\n private readonly deps: EntityStoreDeps,\n ) {}\n\n /** Normalize an entity name using this store's alias table. */\n normalizeEntityName(raw: string, type: string): string {\n return normalizeEntityNameShared(raw, type, this.deps.userAliases);\n }\n\n /**\n * Read an entity file by id, resolving through the migration journal with a\n * fallback to the caller's original id (issue #2213): mid-migration, the\n * journal maps legacy → canonical BEFORE the file moves — writing the\n * still-existing legacy file is safe (the rename retry carries it), while\n * resolving only the canonical path silently drops the mutation.\n */\n private async readEntityForMutation(\n name: string,\n method: string,\n historicalIds: Readonly<Record<string, string>>,\n ): Promise<{ filePath: string; entity: EntityFile } | null> {\n const canonical = resolveHistoricalEntityCanonicalId(name, historicalIds);\n for (const candidate of canonical === name ? [name] : [canonical, name]) {\n const filePath = path.join(this.deps.entitiesDir, `${candidate}.md`);\n try {\n const entity = parseEntityFile(await this.deps.readStorageSecureFile(filePath), this.deps.entitySchemas);\n return { filePath, entity };\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n }\n }\n log.debug(`${method}: entity file ${canonical}.md not found`);\n return null;\n }\n\n /**\n * Locked read-modify-write for the entity-file mutators (issue #2213):\n * holding the entity-mutation lock keeps `migrateEntityFilePair` (which\n * takes the same lock) from moving the file between the fallback read and\n * this write — an unlocked write could recreate a just-renamed legacy file.\n * The journal itself is NOT serialized by this lock (`pruneBlocked` can\n * park a mapping mid-mutation), so the journal identity is REVALIDATED\n * just before committing — a moved journal restarts resolution against the\n * fresh table instead of writing into a since-contested claimant — and\n * checked once more after the write for a move across the write itself.\n * `mutate` returns false to skip the write. Resolves true when written.\n */\n private async mutateEntityFile(\n name: string,\n method: string,\n mutate: (entity: EntityFile, historicalIds: Readonly<Record<string, string>>) => boolean,\n ): Promise<boolean> {\n const stateDir = path.join(this.deps.baseDir, \"state\");\n return withEntityCanonicalMutationLock(stateDir, async () => {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const idsAtResolve = this.deps.currentHistoricalIds();\n const located = await this.readEntityForMutation(name, method, idsAtResolve);\n const mutated = located !== null && mutate(located.entity, idsAtResolve);\n // Revalidate BEFORE honoring either verdict: a journal that moved\n // makes both the resolution AND a dedupe-based no-op stale (a parked\n // mapping can make \"already present on the claimant\" wrong).\n if (this.deps.currentHistoricalIds() !== idsAtResolve) continue;\n if (!located || !mutated) return false;\n located.entity.updated = new Date().toISOString();\n await this.deps.writeStorageSecureFile(\n located.filePath,\n serializeEntityFile(located.entity, this.deps.entitySchemas, this.deps.okfConformanceEnabled()),\n );\n reconcileIfJournalMovedSync(stateDir, idsAtResolve, this.deps.currentHistoricalIds());\n this.deps.invalidateKnowledgeIndexCache();\n this.deps.bumpEntityMutationVersion();\n return true;\n }\n // The journal kept moving under us. A silent false would DROP the\n // requested mutation (the reconcile pass rewrites existing references;\n // it cannot replay a mutation that was never written) — surface a\n // retryable error so the caller's persist machinery logs/retries it.\n requestEntityCanonicalIdReconcileSync(stateDir);\n throw new Error(\n `${method}: entity canonical-id journal kept changing; mutation not applied — retry`,\n );\n });\n }\n\n /** Add a relationship to an entity file. Deduplicates by target+label. */\n async addEntityRelationship(name: string, rel: EntityRelationship): Promise<void> {\n await this.mutateEntityFile(name, \"addEntityRelationship\", (entity, historicalIds) => {\n // Resolve the target with the SAME snapshot the locked read used, and\n // dedupe against CANONICALIZED stored targets — an existing edge the\n // migration has not rewritten yet still names the legacy id, and a\n // plain equality check would miss it and leave duplicates after the\n // rewrite (issue #2213).\n const target = resolveHistoricalEntityCanonicalId(rel.target, historicalIds);\n const duplicate = entity.relationships.some(\n (r) => resolveHistoricalEntityCanonicalId(r.target, historicalIds) === target && r.label === rel.label,\n );\n if (duplicate) return false;\n entity.relationships.push({ ...rel, target });\n return true;\n });\n }\n\n /** Add an activity entry to an entity file; prunes oldest beyond maxEntries. */\n async addEntityActivity(name: string, entry: EntityActivityEntry, maxEntries: number): Promise<void> {\n await this.mutateEntityFile(name, \"addEntityActivity\", (entity) => {\n entity.activity.unshift(entry);\n if (entity.activity.length > maxEntries) entity.activity = entity.activity.slice(0, maxEntries);\n return true;\n });\n }\n\n async addEntityAlias(name: string, alias: string): Promise<void> {\n const wrote = await this.mutateEntityFile(name, \"addEntityAlias\", (entity) => {\n if (entity.aliases.includes(alias)) return false;\n entity.aliases.push(alias);\n return true;\n });\n if (wrote) this.deps.bumpMemoryStatusVersion();\n }\n\n async writeEntity(\n name: string,\n type: string,\n facts: string[],\n options: {\n timestamp?: string;\n source?: string;\n sessionKey?: string;\n principal?: string;\n origin?: string;\n structuredSections?: EntityStructuredSection[];\n } = {},\n ): Promise<string> {\n await this.deps.ensureDirectories();\n return withEntityCanonicalMutationLock(\n path.join(this.deps.baseDir, \"state\"),\n () => this.writeEntityUnlocked(name, type, facts, options),\n );\n }\n\n private async writeEntityUnlocked(\n name: string,\n type: string,\n facts: string[],\n options: {\n timestamp?: string;\n source?: string;\n sessionKey?: string;\n principal?: string;\n origin?: string;\n structuredSections?: EntityStructuredSection[];\n } = {},\n ): Promise<string> {\n if (typeof name !== \"string\" || !name.trim() || typeof type !== \"string\" || !type.trim()) {\n log.warn(\"writeEntity: invalid entity payload, skipping\", {\n nameType: typeof name,\n typeType: typeof type,\n });\n return \"\";\n }\n const safeFacts = Array.isArray(facts)\n ? [...new Set(\n facts\n .filter((fact) => typeof fact === \"string\")\n .map((fact) => fact.trim())\n .filter((fact) => fact.length > 0),\n )]\n : [];\n let normalized = this.deps.normalizeEntityName(name, type);\n\n // Check for fuzzy match against existing entities before creating a new file\n const match = await this.deps.findMatchingEntity(name, type);\n if (match && match !== normalized) {\n log.debug(`fuzzy match: \"${normalized}\" → existing \"${match}\"`);\n normalized = match;\n }\n\n const filePath = path.join(this.deps.entitiesDir, `${normalized}.md`);\n\n // Parse existing file to preserve relationships/activity/aliases/summary\n let entity: EntityFile = {\n name,\n type,\n created: \"\",\n updated: new Date().toISOString(),\n facts: [],\n summary: undefined,\n synthesis: undefined,\n synthesisUpdatedAt: undefined,\n synthesisVersion: undefined,\n synthesisStructuredFactCount: undefined,\n synthesisStructuredFactDigest: undefined,\n timeline: [],\n relationships: [],\n activity: [],\n aliases: [],\n };\n try {\n const existing = await this.deps.readStorageSecureFile(filePath);\n entity = parseEntityFile(existing, this.deps.entitySchemas);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n // File doesn't exist yet\n }\n\n const timestamp = options.timestamp?.trim() || new Date().toISOString();\n const source = options.source?.trim() || undefined;\n const sessionKey = options.sessionKey?.trim() || undefined;\n const principal = options.principal?.trim() || undefined;\n const origin = options.origin?.trim() ? parseOriginClass(options.origin) : undefined;\n const structuredSectionMap = new Map(\n (entity.structuredSections ?? []).map((section) => [section.key, {\n ...section,\n facts: [...section.facts],\n ...(section.factOrigins ? { factOrigins: [...section.factOrigins] } : {}),\n }]),\n );\n for (const section of options.structuredSections ?? []) {\n const normalizedSection = normalizeEntityStructuredSection(type, section, this.deps.entitySchemas);\n const normalized = normalizeStructuredSectionFactsWithOrigins(section.facts, section.factOrigins, origin);\n if (normalized.facts.length === 0) continue;\n const existingSection = structuredSectionMap.get(normalizedSection.key);\n if (!existingSection) {\n structuredSectionMap.set(normalizedSection.key, {\n key: normalizedSection.key,\n title: normalizedSection.title,\n ...normalized,\n });\n continue;\n }\n const existingOrigins = existingSection.facts.map((_, index) => existingSection.factOrigins?.[index]);\n const incomingOrigins = normalized.facts.map((_, index) => normalized.factOrigins?.[index]);\n const merged = normalizeStructuredSectionFactsWithOrigins(\n [...existingSection.facts, ...normalized.facts],\n [...existingOrigins, ...incomingOrigins],\n );\n existingSection.facts = merged.facts;\n existingSection.factOrigins = merged.factOrigins;\n if (!existingSection.title.trim() && normalizedSection.title.trim()) {\n existingSection.title = normalizedSection.title;\n }\n }\n for (const fact of safeFacts) {\n const nextEntry = {\n timestamp,\n text: fact,\n ...(source ? { source } : {}),\n ...(sessionKey ? { sessionKey } : {}),\n ...(principal ? { principal } : {}),\n ...(origin ? { origin } : {}),\n };\n const alreadyPresent = entity.timeline.some((entry) =>\n entry.timestamp === nextEntry.timestamp\n && entry.text === nextEntry.text\n && entry.source === nextEntry.source\n && entry.sessionKey === nextEntry.sessionKey\n && entry.principal === nextEntry.principal\n && entry.origin === nextEntry.origin\n );\n if (alreadyPresent) continue;\n entity.timeline.push(nextEntry);\n }\n entity.structuredSections = sortStructuredSectionsBySchema(\n type,\n Array.from(structuredSectionMap.values()).filter((section) => section.facts.length > 0),\n this.deps.entitySchemas,\n );\n entity.facts = compileEntityFacts(entity.timeline, entity.structuredSections);\n entity.summary = entity.synthesis || entity.summary;\n entity.name = name;\n entity.type = type;\n entity.created = entity.created || timestamp;\n entity.updated = new Date().toISOString();\n\n await this.deps.snapshotBeforeWrite(filePath, \"write\");\n await this.deps.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.deps.entitySchemas, this.deps.okfConformanceEnabled()));\n this.deps.invalidateKnowledgeIndexCache();\n this.deps.bumpMemoryStatusVersion(); // invalidate entity cache\n this.deps.bumpEntityMutationVersion();\n log.debug(`wrote entity ${normalized}`);\n return normalized;\n }\n\n async readEntity(name: string): Promise<string> {\n const filePath = this.deps.resolveEntityFilePath(name);\n if (filePath === null) {\n return \"\";\n }\n try {\n return await this.deps.readStorageSecureFile(filePath);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return \"\";\n }\n }\n\n /** Return sorted list of entity filenames (without .md extension) */\n async listEntityNames(): Promise<string[]> {\n try {\n const entries = await readdir(this.deps.entitiesDir);\n return entries\n .filter((e) => e.endsWith(\".md\"))\n .map((e) => e.replace(\".md\", \"\"))\n .sort();\n } catch {\n return [];\n }\n }\n\n /** Re-serialize every entity file into the compiled-truth timeline shape. */\n async migrateEntityFilesToCompiledTruthTimeline(): Promise<{ total: number; migrated: number }> {\n const entityNames = await this.listEntityNames();\n const stateDir = path.join(this.deps.baseDir, \"state\");\n let migrated = 0;\n for (const entityName of entityNames) {\n // Read+rewrite under the entity MUTATION lock (issue #2213): an\n // unlocked whole-record rewrite could restore relationship targets a\n // peer migration rewrote between the read and the write, and this\n // path bumps only the status version, which never re-triggers the\n // completed migration's reference scan.\n const wrote = await withEntityCanonicalMutationLock(stateDir, async () => {\n const raw = await this.readEntity(entityName);\n if (!raw) return false;\n const serialized = serializeEntityFile(parseEntityFile(raw, this.deps.entitySchemas), this.deps.entitySchemas, this.deps.okfConformanceEnabled());\n if (raw.trimEnd() === serialized.trimEnd()) return false;\n const filePath = this.deps.resolveEntityFilePath(entityName);\n if (filePath === null) return false;\n await this.deps.writeStorageSecureFile(filePath, serialized);\n this.deps.bumpEntityMutationVersion();\n return true;\n });\n if (wrote) migrated += 1;\n }\n if (migrated > 0) {\n this.deps.invalidateKnowledgeIndexCache();\n this.deps.bumpMemoryStatusVersion();\n }\n return { total: entityNames.length, migrated };\n }\n\n /**\n * Set or rewrite the synthesis layer of an entity file.\n */\n async updateEntitySynthesis(\n name: string,\n synthesis: string,\n options: {\n entityUpdatedAt?: string;\n synthesisStructuredFactCount?: number;\n synthesisStructuredFactDigest?: string;\n synthesisTimelineCount?: number;\n updatedAt?: string;\n incrementVersion?: boolean;\n } = {},\n ): Promise<void> {\n return withEntityCanonicalMutationLock(\n path.join(this.deps.baseDir, \"state\"),\n () => this.updateEntitySynthesisUnlocked(name, synthesis, options),\n );\n }\n\n private async updateEntitySynthesisUnlocked(\n name: string,\n synthesis: string,\n options: {\n entityUpdatedAt?: string;\n synthesisStructuredFactCount?: number;\n synthesisStructuredFactDigest?: string;\n synthesisTimelineCount?: number;\n updatedAt?: string;\n incrementVersion?: boolean;\n } = {},\n ): Promise<void> {\n const filePath = path.join(this.deps.entitiesDir, `${name}.md`);\n let entity: EntityFile;\n try {\n const content = await this.deps.readStorageSecureFile(filePath);\n entity = parseEntityFile(content, this.deps.entitySchemas);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n log.debug(`updateEntitySynthesis: entity file ${name}.md not found`);\n return;\n }\n\n const updatedAt = options.updatedAt?.trim() || entity.synthesisUpdatedAt?.trim() || undefined;\n const entityUpdatedAt = options.entityUpdatedAt?.trim() || updatedAt || entity.updated || new Date().toISOString();\n const synthesisTimelineCount = Number.isInteger(options.synthesisTimelineCount)\n && (options.synthesisTimelineCount ?? 0) >= 0\n ? options.synthesisTimelineCount\n : undefined;\n const synthesisStructuredFactCount = Number.isInteger(options.synthesisStructuredFactCount)\n && (options.synthesisStructuredFactCount ?? 0) >= 0\n ? options.synthesisStructuredFactCount\n : countEntityStructuredFacts(entity);\n const synthesisStructuredFactDigest = options.synthesisStructuredFactDigest?.trim()\n || fingerprintEntityStructuredFacts(entity);\n entity.synthesis = synthesis.trim();\n entity.summary = entity.synthesis;\n entity.synthesisUpdatedAt = updatedAt;\n entity.synthesisTimelineCount = synthesisTimelineCount;\n entity.synthesisStructuredFactCount = synthesisStructuredFactCount;\n entity.synthesisStructuredFactDigest = synthesisStructuredFactDigest;\n entity.synthesisVersion = Math.max(0, entity.synthesisVersion ?? 0)\n + (options.incrementVersion === false ? 0 : 1);\n entity.updated = entityUpdatedAt;\n await this.deps.writeStorageSecureFile(filePath, serializeEntityFile(entity, this.deps.entitySchemas, this.deps.okfConformanceEnabled()));\n await this.deps.removeEntitySynthesisQueueEntries([\n ...new Set([name, this.deps.normalizeEntityName(entity.name, entity.type)]),\n ]);\n this.deps.invalidateKnowledgeIndexCache();\n this.deps.bumpMemoryStatusVersion(); // invalidate entity cache\n this.deps.bumpEntityMutationVersion();\n }\n\n /**\n * Read all entity files and return lightweight EntityFile objects.\n * Parsing is fast (~50-100ms for ~1,800 files) since entity files are small.\n */\n async readAllEntityFiles(options?: CorpusReadOptions): Promise<EntityFile[]> {\n checkCorpusReadAbort(options);\n const currentVersion = this.deps.getMemoryStatusVersion();\n const cacheKey = [\n this.deps.getEntityCacheSecureStoreKey(),\n buildEntitySchemaCacheKey(this.deps.entitySchemas),\n this.deps.getEntityMutationVersion(),\n ].join(\"\\u0000\");\n const cached = getCachedEntities(this.deps.baseDir, currentVersion, cacheKey);\n if (cached) return cached;\n\n try {\n const entries = await readdir(this.deps.entitiesDir);\n const mdFiles = entries.filter((e) => e.endsWith(\".md\"));\n if (mdFiles.length === 0) return [];\n\n // Read all entity files in parallel batches to avoid O(N) sequential I/O.\n // With 3000+ entity files, sequential reads can take 15-20s under load.\n // Batching at 100 keeps file-descriptor pressure manageable while staying fast.\n const BATCH_SIZE = 100;\n const entities: EntityFile[] = [];\n for (let i = 0; i < mdFiles.length; i += BATCH_SIZE) {\n // Per batch, so an abandoned caller stops within one batch of I/O instead\n // of reading every entity file for a result nobody awaits (issue #2307).\n checkCorpusReadAbort(options);\n const batch = mdFiles.slice(i, i + BATCH_SIZE);\n const results = await Promise.all(\n batch.map(async (entry) => {\n try {\n return await this.deps.readStorageSecureFile(path.join(this.deps.entitiesDir, entry));\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }),\n );\n for (const content of results) {\n if (content !== null) entities.push(parseEntityFile(content, this.deps.entitySchemas));\n }\n }\n // A signal that fired during the last batch's await would otherwise publish\n // and return as if uncancelled (issue #2307 review).\n checkCorpusReadAbort(options);\n setCachedEntities(this.deps.baseDir, entities, currentVersion, cacheKey);\n return entities;\n } catch (err) {\n if (err instanceof SecureStoreLockedError || !isErrnoCode(err, \"ENOENT\")) throw err;\n // Directory doesn't exist yet\n return [];\n }\n }\n\n /**\n * Build the Knowledge Index: a compact markdown table of top-scored entities.\n * Respects maxEntities and maxChars limits from config.\n */\n async buildKnowledgeIndex(\n config: PluginConfig,\n overrides?: { maxEntities?: number; maxChars?: number },\n ): Promise<{ result: string; cached: boolean }> {\n const useDefaultLimits =\n overrides?.maxEntities === undefined &&\n overrides?.maxChars === undefined;\n // Return cached index if still fresh\n if (\n useDefaultLimits &&\n this.deps.knowledgeIndexCache &&\n Date.now() - this.deps.knowledgeIndexCache.builtAt < this.deps.storageManagerClass.KNOWLEDGE_INDEX_CACHE_TTL_MS\n ) {\n return { result: this.deps.knowledgeIndexCache.result, cached: true };\n }\n\n const entities = await this.deps.readAllEntityFiles();\n if (entities.length === 0) {\n if (useDefaultLimits) this.deps.knowledgeIndexCache = { result: \"\", builtAt: Date.now() };\n return { result: \"\", cached: false };\n }\n\n const now = new Date();\n const scored: ScoredEntity[] = entities.map((e) => ({\n name: e.name,\n type: e.type,\n score: this.deps.storageManagerClass.scoreEntity(e, now),\n factCount: e.facts.length,\n summary: e.synthesis ?? e.summary,\n topRelationships: e.relationships.slice(0, 3).map((r) => r.target),\n }));\n\n // Sort by score descending, take top N\n scored.sort((a, b) => b.score - a.score);\n const maxEntities = typeof overrides?.maxEntities === \"number\"\n ? Math.max(0, Math.floor(overrides.maxEntities))\n : config.knowledgeIndexMaxEntities;\n const topN = scored.slice(0, maxEntities);\n\n if (topN.length === 0) {\n if (useDefaultLimits) this.deps.knowledgeIndexCache = { result: \"\", builtAt: Date.now() };\n return { result: \"\", cached: false };\n }\n\n // Build markdown table\n const header = \"## Knowledge Index\\n\\n| Entity | Type | Summary | Connected to |\\n|--------|------|---------|-------------|\";\n const rows: string[] = [];\n let totalChars = header.length;\n const maxChars = typeof overrides?.maxChars === \"number\"\n ? Math.max(0, Math.floor(overrides.maxChars))\n : config.knowledgeIndexMaxChars;\n\n for (const entity of topN) {\n const summary = entity.summary || `${entity.factCount} facts`;\n const connected = entity.topRelationships.length > 0\n ? entity.topRelationships.join(\", \")\n : \"—\";\n const row = `| ${entity.name} | ${entity.type} | ${summary} | ${connected} |`;\n\n if (totalChars + row.length + 1 > maxChars) break;\n rows.push(row);\n totalChars += row.length + 1;\n }\n\n const result = rows.length === 0 ? \"\" : `${header}\\n${rows.join(\"\\n\")}\\n`;\n if (useDefaultLimits) this.deps.knowledgeIndexCache = { result, builtAt: Date.now() };\n return { result, cached: false };\n }\n\n /**\n * Merge fragmented entity files that resolve to the same canonical name.\n * Preserves relationships, activity, aliases, and summary from all fragments.\n * Returns count of files merged.\n */\n async mergeFragmentedEntities(): Promise<number> {\n return withEntityCanonicalMutationLock(\n path.join(this.deps.baseDir, \"state\"),\n () => this.mergeFragmentedEntitiesUnlocked(),\n );\n }\n\n private async mergeFragmentedEntitiesUnlocked(): Promise<number> {\n let merged = 0;\n try {\n const entries = await readdir(this.deps.entitiesDir);\n const mdFiles = entries.filter((e) => e.endsWith(\".md\"));\n\n // Group files by their canonical name\n const groups = new Map<string, string[]>();\n for (const file of mdFiles) {\n const baseName = file.replace(\".md\", \"\");\n // Extract type and name from filename (type-rest-of-name)\n const dashIdx = baseName.indexOf(\"-\");\n if (dashIdx === -1) continue;\n const type = baseName.slice(0, dashIdx);\n const restOfName = baseName.slice(dashIdx + 1);\n const canonical = this.deps.normalizeEntityName(restOfName, type);\n\n if (!groups.has(canonical)) groups.set(canonical, []);\n groups.get(canonical)!.push(file);\n }\n\n // Merge groups with more than one file\n for (const [canonical, files] of groups) {\n if (files.length <= 1) continue;\n\n // Parse all files and merge into a single EntityFile\n const mergedEntity: EntityFile = {\n name: \"\",\n type: \"other\",\n created: \"\",\n updated: \"\",\n extraFrontmatterLines: [],\n preSectionLines: [],\n facts: [],\n summary: undefined,\n synthesis: undefined,\n synthesisUpdatedAt: undefined,\n synthesisTimelineCount: undefined,\n synthesisStructuredFactCount: undefined,\n synthesisStructuredFactDigest: undefined,\n synthesisVersion: undefined,\n timeline: [],\n relationships: [],\n activity: [],\n aliases: [],\n structuredSections: [],\n extraSections: [],\n };\n\n for (const file of files) {\n const filePath = path.join(this.deps.entitiesDir, file);\n try {\n const content = await this.deps.readStorageSecureFile(filePath);\n const parsed = parseEntityFile(content, this.deps.entitySchemas);\n\n // Prefer specific types over \"other\"\n if (!mergedEntity.type || mergedEntity.type === \"other\") {\n mergedEntity.type = parsed.type;\n }\n\n // Keep latest update time\n if (!mergedEntity.updated || compareEntityTimestamps(parsed.updated, mergedEntity.updated) > 0) {\n mergedEntity.updated = parsed.updated;\n }\n\n const parsedCreated = parsed.created || parsed.updated;\n const mergedCreated = mergedEntity.created?.trim() || \"\";\n const parsedCreatedMs = parsedCreated ? Date.parse(parsedCreated) : Number.NaN;\n const mergedCreatedMs = mergedCreated ? Date.parse(mergedCreated) : Number.NaN;\n const parsedCreatedIsValid = Number.isFinite(parsedCreatedMs);\n const mergedCreatedIsValid = Number.isFinite(mergedCreatedMs);\n if (\n parsedCreated &&\n (\n !mergedCreated\n || (parsedCreatedIsValid && !mergedCreatedIsValid)\n || (\n parsedCreatedIsValid\n && mergedCreatedIsValid\n && parsedCreatedMs < mergedCreatedMs\n )\n || (\n !parsedCreatedIsValid\n && !mergedCreatedIsValid\n && compareEntityTimestamps(parsedCreated, mergedCreated) < 0\n )\n )\n ) {\n mergedEntity.created = parsedCreated;\n }\n\n // Keep longest/best name\n if (parsed.name.length > mergedEntity.name.length) {\n mergedEntity.name = parsed.name;\n }\n\n const parsedSynthesisUpdatedAt = parsed.synthesisUpdatedAt?.trim() || undefined;\n const mergedSynthesisUpdatedAt = mergedEntity.synthesisUpdatedAt?.trim() || undefined;\n\n // Prefer the freshest synthesis/summary available.\n if (\n parsed.synthesis &&\n (!mergedEntity.synthesis\n || (!mergedSynthesisUpdatedAt && Boolean(parsedSynthesisUpdatedAt))\n || (Boolean(mergedSynthesisUpdatedAt)\n && Boolean(parsedSynthesisUpdatedAt)\n && compareEntityTimestamps(parsedSynthesisUpdatedAt, mergedSynthesisUpdatedAt) > 0))\n ) {\n mergedEntity.synthesis = parsed.synthesis;\n mergedEntity.summary = parsed.synthesis;\n mergedEntity.synthesisUpdatedAt = parsedSynthesisUpdatedAt;\n mergedEntity.synthesisTimelineCount = parsed.synthesisTimelineCount;\n mergedEntity.synthesisStructuredFactCount = parsed.synthesisStructuredFactCount;\n mergedEntity.synthesisStructuredFactDigest = parsed.synthesisStructuredFactDigest;\n mergedEntity.synthesisVersion = parsed.synthesisVersion;\n } else if (!mergedEntity.summary && parsed.summary) {\n mergedEntity.summary = parsed.summary;\n mergedEntity.synthesis = parsed.summary;\n mergedEntity.synthesisUpdatedAt = parsedSynthesisUpdatedAt;\n mergedEntity.synthesisTimelineCount = parsed.synthesisTimelineCount;\n mergedEntity.synthesisStructuredFactCount = parsed.synthesisStructuredFactCount;\n mergedEntity.synthesisStructuredFactDigest = parsed.synthesisStructuredFactDigest;\n mergedEntity.synthesisVersion = parsed.synthesisVersion;\n }\n\n // Collect all timeline evidence; facts are derived below.\n mergedEntity.timeline.push(...parsed.timeline);\n\n // Collect relationships (dedup later)\n mergedEntity.relationships.push(...parsed.relationships);\n\n // Collect activity entries\n mergedEntity.activity.push(...parsed.activity);\n\n // Collect aliases\n mergedEntity.aliases.push(...parsed.aliases);\n\n const mergedStructuredSectionMap = new Map(\n (mergedEntity.structuredSections ?? []).map((section) => [section.key, {\n ...section,\n facts: [...section.facts],\n factOrigins: section.factOrigins ? [...section.factOrigins] : undefined,\n }]),\n );\n for (const section of parsed.structuredSections ?? []) {\n const existingSection = mergedStructuredSectionMap.get(section.key);\n if (!existingSection) {\n const facts: string[] = [];\n const factOrigins: Array<string | undefined> = [];\n for (const [index, fact] of section.facts.entries()) {\n const trimmed = fact.trim();\n if (!trimmed || facts.includes(trimmed)) continue;\n facts.push(trimmed);\n factOrigins.push(section.factOrigins?.[index]);\n }\n mergedStructuredSectionMap.set(section.key, {\n key: section.key,\n title: section.title,\n facts,\n factOrigins: section.factOrigins ? factOrigins : undefined,\n });\n continue;\n }\n\n if (section.factOrigins && !existingSection.factOrigins) {\n existingSection.factOrigins = existingSection.facts.map(() => undefined);\n }\n for (const [index, fact] of section.facts.entries()) {\n const trimmed = fact.trim();\n if (!trimmed) continue;\n const existingIndex = existingSection.facts.indexOf(trimmed);\n const origin = section.factOrigins?.[index];\n if (existingIndex === -1) {\n existingSection.facts.push(trimmed);\n existingSection.factOrigins?.push(origin);\n } else if (existingSection.factOrigins?.[existingIndex] !== origin) {\n existingSection.factOrigins?.splice(existingIndex, 1, undefined);\n }\n }\n if (!existingSection.title.trim() && section.title.trim()) {\n existingSection.title = section.title;\n }\n }\n mergedEntity.structuredSections = Array.from(mergedStructuredSectionMap.values());\n\n // Preserve custom metadata and user-authored freeform content from fragments.\n mergedEntity.extraFrontmatterLines!.push(...(parsed.extraFrontmatterLines ?? []));\n mergedEntity.preSectionLines!.push(...(parsed.preSectionLines ?? []));\n mergedEntity.extraSections!.push(...(parsed.extraSections ?? []).map((section) => ({\n title: section.title,\n lines: [...section.lines],\n })));\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n // Skip unreadable\n }\n }\n\n const timelineByKey = new Map<string, (typeof mergedEntity.timeline)[number]>();\n for (const entry of mergedEntity.timeline) {\n const key = JSON.stringify([\n entry.timestamp,\n entry.source ?? \"\",\n entry.sessionKey ?? \"\",\n entry.principal ?? \"\",\n entry.text,\n ]);\n const existing = timelineByKey.get(key);\n if (!existing) {\n timelineByKey.set(key, entry);\n } else if (existing.origin !== entry.origin) {\n existing.origin = undefined;\n }\n }\n mergedEntity.timeline = [...timelineByKey.values()];\n // Deduplicate relationships by target+label\n const relKeys = new Set<string>();\n mergedEntity.relationships = mergedEntity.relationships.filter((r) => {\n const key = `${r.target}::${r.label}`;\n if (relKeys.has(key)) return false;\n relKeys.add(key);\n return true;\n });\n\n // Sort activity by date descending, deduplicate by date+note\n const actKeys = new Set<string>();\n mergedEntity.activity = mergedEntity.activity\n .filter((a) => {\n const key = `${a.date}::${a.note}`;\n if (actKeys.has(key)) return false;\n actKeys.add(key);\n return true;\n })\n .sort((a, b) => b.date.localeCompare(a.date));\n\n // Deduplicate aliases\n mergedEntity.aliases = [...new Set(mergedEntity.aliases)];\n mergedEntity.structuredSections = sortStructuredSectionsBySchema(\n mergedEntity.type,\n mergedEntity.structuredSections ?? [],\n this.deps.entitySchemas,\n );\n mergedEntity.facts = compileEntityFacts(mergedEntity.timeline, mergedEntity.structuredSections);\n\n const extraSectionKeys = new Set<string>();\n mergedEntity.extraSections = (mergedEntity.extraSections ?? []).filter((section) => {\n const key = `${section.title}::${section.lines.join(\"\\n\")}`;\n if (extraSectionKeys.has(key)) return false;\n extraSectionKeys.add(key);\n return true;\n });\n\n // Fallback name from canonical\n if (!mergedEntity.name) {\n const dashIdx = canonical.indexOf(\"-\");\n mergedEntity.name = dashIdx !== -1 ? canonical.slice(dashIdx + 1) : canonical;\n }\n\n mergedEntity.created = mergedEntity.created || mergedEntity.updated || new Date().toISOString();\n mergedEntity.updated = mergedEntity.updated || new Date().toISOString();\n\n const canonicalPath = path.join(this.deps.entitiesDir, `${canonical}.md`);\n await this.deps.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.deps.entitySchemas, this.deps.okfConformanceEnabled()));\n this.deps.bumpEntityMutationVersion();\n\n // Remove non-canonical files\n for (const file of files) {\n const filePath = path.join(this.deps.entitiesDir, file);\n if (filePath !== canonicalPath) {\n try {\n await unlink(filePath);\n merged++;\n log.debug(`merged entity ${file} → ${canonical}.md`);\n } catch {\n // Ignore\n }\n }\n }\n }\n } catch (err) {\n if (err instanceof SecureStoreLockedError || !isErrnoCode(err, \"ENOENT\")) throw err;\n // Directory doesn't exist yet\n }\n\n return merged;\n }\n}\n","/**\n * Identity-continuity persistence extracted from StorageManager.\n *\n * The host keeps the public API while this store owns anchors, incidents,\n * audits, and improvement-loop files. Dependencies stay live through\n * `selfDeps`, preserving secure-store and catalog-write behavior.\n */\n\nimport { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n closeContinuityIncidentRecord,\n createContinuityIncidentRecord,\n parseContinuityImprovementLoops,\n parseContinuityIncident,\n reviewContinuityLoopInMarkdown,\n serializeContinuityIncident,\n upsertContinuityLoopInMarkdown,\n} from \"../identity-continuity.js\";\nimport { SecureStoreLockedError } from \"../secure-store/secure-fs.js\";\nimport type {\n ContinuityImprovementLoop,\n ContinuityIncidentCloseInput,\n ContinuityIncidentOpenInput,\n ContinuityIncidentRecord,\n ContinuityLoopReviewInput,\n ContinuityLoopUpsertInput,\n} from \"../types.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\n\nexport interface IdentityContinuityStoreDeps {\n ensureDirectories(): Promise<void>;\n generateId(prefix?: string): string;\n readonly identityAnchorPath: string;\n readonly identityIncidentsDir: string;\n readonly identityAuditsWeeklyDir: string;\n readonly identityAuditsMonthlyDir: string;\n readonly identityImprovementLoopsPath: string;\n readStorageSecureFile(filePath: string): Promise<string>;\n writeStorageSecureFile(filePath: string, content: string | Buffer): Promise<void>;\n}\n\nexport class IdentityContinuityStore {\n constructor(private readonly deps: IdentityContinuityStoreDeps) {}\n\n async writeIdentityAnchor(content: string): Promise<void> {\n await this.deps.ensureDirectories();\n await this.deps.writeStorageSecureFile(this.deps.identityAnchorPath, content);\n }\n\n async readIdentityAnchor(): Promise<string | null> {\n try {\n return await this.deps.readStorageSecureFile(this.deps.identityAnchorPath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async appendContinuityIncident(input: ContinuityIncidentOpenInput): Promise<ContinuityIncidentRecord> {\n await this.deps.ensureDirectories();\n const now = new Date();\n const nowIso = now.toISOString();\n const date = nowIso.slice(0, 10);\n const id = this.deps.generateId(\"incident\");\n const incident = createContinuityIncidentRecord(id, input, nowIso);\n const filePath = path.join(this.deps.identityIncidentsDir, `${date}-${id}.md`);\n await this.deps.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));\n return { ...incident, filePath };\n }\n\n async readContinuityIncidents(\n limit = 200,\n state: \"open\" | \"closed\" | \"all\" = \"all\"\n ): Promise<ContinuityIncidentRecord[]> {\n const normalizedLimit = Number.isFinite(limit) ? Math.floor(limit) : 0;\n const cappedLimit = Math.max(0, normalizedLimit);\n if (cappedLimit === 0) return [];\n\n try {\n const candidates = await this.readContinuityIncidentFileNames();\n const incidents: ContinuityIncidentRecord[] = [];\n\n for (const file of candidates) {\n if (incidents.length >= cappedLimit) break;\n const filePath = path.join(this.deps.identityIncidentsDir, file);\n try {\n const raw = await this.deps.readStorageSecureFile(filePath);\n const parsed = parseContinuityIncident(raw);\n if (!parsed) continue;\n if (state !== \"all\" && parsed.state !== state) continue;\n incidents.push({ ...parsed, filePath });\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n // Fail-open on malformed/missing files.\n }\n }\n return incidents;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return [];\n }\n }\n\n async closeContinuityIncident(\n id: string,\n closure: ContinuityIncidentCloseInput\n ): Promise<ContinuityIncidentRecord | null> {\n const directFilePath = await this.findContinuityIncidentFilePathById(id);\n const target = directFilePath ? await this.readContinuityIncidentFile(directFilePath) : null;\n if (!target || !directFilePath) return null;\n if (target.state === \"closed\") return target;\n\n const closed = closeContinuityIncidentRecord(target, closure, new Date().toISOString());\n await this.deps.writeStorageSecureFile(directFilePath, serializeContinuityIncident(closed));\n return { ...closed, filePath: directFilePath };\n }\n\n async writeIdentityAudit(period: \"weekly\" | \"monthly\", key: string, content: string): Promise<string> {\n await this.deps.ensureDirectories();\n const safeKey = this.sanitizeIdentityAuditKey(key);\n const dir = period === \"weekly\" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;\n const filePath = path.join(dir, `${safeKey}.md`);\n await this.deps.writeStorageSecureFile(filePath, content);\n return filePath;\n }\n\n async readIdentityAudit(period: \"weekly\" | \"monthly\", key: string): Promise<string | null> {\n try {\n const safeKey = this.sanitizeIdentityAuditKey(key);\n const dir = period === \"weekly\" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;\n return await this.deps.readStorageSecureFile(path.join(dir, `${safeKey}.md`));\n } catch (err) {\n if (err instanceof Error && err.message === \"Invalid identity audit key\") return null;\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async writeIdentityImprovementLoops(content: string): Promise<void> {\n await this.deps.ensureDirectories();\n await this.deps.writeStorageSecureFile(this.deps.identityImprovementLoopsPath, content);\n }\n\n async readIdentityImprovementLoops(): Promise<string | null> {\n try {\n return await this.deps.readStorageSecureFile(this.deps.identityImprovementLoopsPath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return null;\n }\n }\n\n async readIdentityImprovementLoopRegister(): Promise<ContinuityImprovementLoop[]> {\n const raw = await this.readIdentityImprovementLoops();\n if (!raw) return [];\n return parseContinuityImprovementLoops(raw);\n }\n\n async upsertIdentityImprovementLoop(input: ContinuityLoopUpsertInput): Promise<ContinuityImprovementLoop> {\n const nowIso = new Date().toISOString();\n const raw = await this.readIdentityImprovementLoops();\n const { markdown, loop } = upsertContinuityLoopInMarkdown(raw, input, nowIso);\n await this.writeIdentityImprovementLoops(markdown);\n return loop;\n }\n\n async reviewIdentityImprovementLoop(\n id: string,\n input: ContinuityLoopReviewInput\n ): Promise<ContinuityImprovementLoop | null> {\n const raw = await this.readIdentityImprovementLoops();\n const { markdown, loop } = reviewContinuityLoopInMarkdown(raw, id, input, new Date().toISOString());\n if (!loop) return null;\n await this.writeIdentityImprovementLoops(markdown);\n return loop;\n }\n\n private async readContinuityIncidentFileNames(): Promise<string[]> {\n const files = await readdir(this.deps.identityIncidentsDir);\n return files\n .filter((file) => file.endsWith(\".md\"))\n .sort()\n .reverse();\n }\n\n private async readContinuityIncidentFile(filePath: string): Promise<ContinuityIncidentRecord | null> {\n try {\n const raw = await this.deps.readStorageSecureFile(filePath);\n const parsed = parseContinuityIncident(raw);\n return parsed ? { ...parsed, filePath } : null;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n return null;\n }\n }\n\n private async findContinuityIncidentFilePathById(id: string): Promise<string | null> {\n const fileNames = await this.readContinuityIncidentFileNames();\n const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));\n if (directMatch) {\n const directPath = path.join(this.deps.identityIncidentsDir, directMatch);\n const parsed = await this.readContinuityIncidentFile(directPath);\n if (parsed?.id === id) return directPath;\n }\n\n for (const fileName of fileNames) {\n const filePath = path.join(this.deps.identityIncidentsDir, fileName);\n const parsed = await this.readContinuityIncidentFile(filePath);\n if (parsed?.id === id) return filePath;\n }\n return null;\n }\n\n private sanitizeIdentityAuditKey(key: string): string {\n const trimmed = key.trim();\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(trimmed) || trimmed.includes(\"..\")) {\n throw new Error(\"Invalid identity audit key\");\n }\n return trimmed;\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport {\n access,\n lstat,\n readFile,\n readdir,\n realpath,\n rename,\n stat as statFile,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { lstatSync, readFileSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { computeSupersessionKey, normalizeSupersessionKey } from \"../temporal-supersession.js\";\nimport type { EntityFile, MemoryFile } from \"../types.js\";\nimport { log } from \"../logger.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { withHeldFileLock } from \"../utils/serialize-mutations.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { assertPathInsideRoot } from \"../utils/path-containment.js\";\nimport { withEntityCanonicalMutationLock } from \"./entity-canonical-id-lock.js\";\nimport { assertSafeEntityId } from \"./entity-id-safety.js\";\n\nimport {\n ENTITY_CANONICAL_ID_MIGRATION_FILE,\n ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER,\n ENTITY_CANONICAL_ID_RECONCILE_MARKER,\n resolveHistoricalEntityCanonicalId,\n} from \"./entity-canonical-id-references.js\";\n\nconst ENTITY_CANONICAL_ID_MIGRATION_VERSION = 1;\nconst ENTITY_CANONICAL_ID_MIGRATION_LOCK_STALE_MS = 60_000;\nconst ENTITY_CANONICAL_ID_MIGRATION_LOCK_MAX_WAIT_MS = 300_000;\nconst TOMBSTONE_LOCK_STALE_MS = 30_000;\nconst TOMBSTONE_LOCK_MAX_WAIT_MS = 5_000;\nconst MEMORY_REWRITE_MAX_PASSES = 3;\nconst ENTITY_MAPPING_RESCAN_MAX_PASSES = 3;\n\nconst EntityCanonicalIdMigrationStateSchema = z.object({\n version: z.literal(ENTITY_CANONICAL_ID_MIGRATION_VERSION),\n complete: z.boolean(),\n mappings: z.record(z.string().min(1)),\n /**\n * Pairs the migration refused to resolve, PARKED rather than dropped.\n * Deleting the record would strand the collision: once an operator removes\n * the legacy file, no later scan can rediscover the mapping, so references\n * still naming the legacy id would never be rewritten. Optional so a journal\n * written by an older build still parses.\n */\n blocked: z.record(z.string().min(1)).optional(),\n});\n\ntype EntityCanonicalIdMigrationState = z.infer<typeof EntityCanonicalIdMigrationStateSchema>;\n\nexport interface EntityCanonicalIdMigrationDependencies {\n stateDir: string;\n entitiesDir: string;\n normalizeEntityName(raw: string, type: string): string;\n resolveEntityFilePath(id: string): string | null;\n readStorageSecureFile(filePath: string): Promise<string>;\n writeStorageSecureFile(filePath: string, content: string, forceEncrypt?: boolean): Promise<void>;\n isEncryptedStorageFile(filePath: string): Promise<boolean>;\n snapshotBeforeWrite(filePath: string, trigger: \"write\"): Promise<void>;\n parseEntityFile(content: string): EntityFile;\n serializeEntityFile(entity: EntityFile): string;\n serializeMemoryWithEntityRef(memory: MemoryFile, entityRef: string): string;\n readMemoryByPath(filePath: string): Promise<MemoryFile | null>;\n readAllMemories(): Promise<MemoryFile[]>;\n readAllColdMemories(): Promise<MemoryFile[]>;\n readArchivedMemories(): Promise<MemoryFile[]>;\n validateMemoryScanRoots?(): Promise<void>;\n rewriteProjectedEntityReferences(mappings: Readonly<Record<string, string>>): Promise<void>;\n rewriteProjectedMemoryEntityReference(\n memoryId: string,\n previousEntityRef: string,\n nextEntityRef: string,\n ): Promise<void>;\n invalidateKnowledgeIndexCache(): void;\n invalidateAllMemoriesCache(): void;\n invalidateColdMemoriesCache(): void;\n bumpMemoryStatusVersion(): void;\n readMigrationFingerprint?(): Promise<string>;\n}\n\nasync function fingerprintPath(filePath: string): Promise<string> {\n let fileStat;\n try {\n fileStat = await lstat(filePath);\n } catch (error) {\n if (!isErrnoCode(error, \"ENOENT\")) throw error;\n }\n return fileStat\n ? `${fileStat.dev}:${fileStat.ino}:${fileStat.mtimeMs}:${fileStat.ctimeMs}:${fileStat.size}`\n : \"missing\";\n}\n\nasync function fingerprintEntityEntries(entitiesDir: string): Promise<string> {\n let names: string[];\n try {\n names = (await readdir(entitiesDir))\n .filter((name) => path.extname(name) === \".md\")\n .sort();\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return \"missing\";\n throw error;\n }\n const hash = createHash(\"sha256\");\n for (const name of names) {\n hash.update(`${name.length}:${name}:`);\n try {\n const entry = await lstat(path.join(entitiesDir, name), { bigint: true });\n hash.update(`${entry.dev}:${entry.ino}:${entry.size}:${entry.mtimeNs}:${entry.ctimeNs}`);\n } catch (error) {\n if (!isErrnoCode(error, \"ENOENT\")) throw error;\n hash.update(\"missing\");\n }\n hash.update(\"\\n\");\n }\n return hash.digest(\"hex\");\n}\n\n/**\n * Completion fingerprint for migration inputs only. Entity entry identities\n * catch same-path edits that do not change the directory inode; the cooperative\n * sentinel covers managed writes. Memory-corpus writes stay excluded so plain\n * fact writes do not reopen migration.\n */\nexport async function getFingerprint(\n baseDir: string,\n entitiesDir: string,\n getEntityMutationVersion: () => string,\n): Promise<string> {\n const [\n entityDirectoryFingerprint,\n entityEntriesFingerprint,\n aliasFingerprint,\n reconcileFingerprint,\n consumingFingerprint,\n ] = await Promise.all([\n fingerprintPath(entitiesDir),\n fingerprintEntityEntries(entitiesDir),\n fingerprintPath(path.join(baseDir, \"config\", \"aliases.json\")),\n fingerprintPath(path.join(baseDir, \"state\", ENTITY_CANONICAL_ID_RECONCILE_MARKER)),\n fingerprintPath(path.join(baseDir, \"state\", ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER)),\n ]);\n return [\n entityDirectoryFingerprint,\n entityEntriesFingerprint,\n aliasFingerprint,\n reconcileFingerprint,\n consumingFingerprint,\n getEntityMutationVersion(),\n ].join(\":\");\n}\n\nexport async function validateRoots(\n baseDir: string,\n entitiesDir: string,\n stateDir: string,\n archiveDir: string,\n): Promise<void> {\n let baseStat;\n try {\n baseStat = await lstat(baseDir);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return;\n throw error;\n }\n if (baseStat.isSymbolicLink() || !baseStat.isDirectory()) {\n throw new Error(`Refusing entity canonical-id migration through unsafe memory root: ${baseDir}.`);\n }\n const memoryRoot = await realpath(baseDir);\n const roots = [\n entitiesDir,\n stateDir,\n ...RECALL_FALLBACK_DIRS.map((directory) => path.join(baseDir, directory)),\n path.join(baseDir, \"cold\"),\n archiveDir,\n ];\n for (const root of roots) {\n let rootStat;\n try {\n rootStat = await lstat(root);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) continue;\n throw error;\n }\n if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {\n throw new Error(`Refusing entity canonical-id migration through unsafe memory root: ${root}.`);\n }\n assertPathInsideRoot(memoryRoot, await realpath(root), root);\n }\n}\n\nfunction statePath(deps: EntityCanonicalIdMigrationDependencies): string {\n return path.join(deps.stateDir, ENTITY_CANONICAL_ID_MIGRATION_FILE);\n}\n\nasync function assertSafeMigrationStateFile(\n deps: EntityCanonicalIdMigrationDependencies,\n): Promise<void> {\n const migrationStatePath = statePath(deps);\n let fileStat;\n try {\n fileStat = await lstat(migrationStatePath);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return;\n throw error;\n }\n if (fileStat.isSymbolicLink() || !fileStat.isFile()) {\n throw new Error(\n `Refusing entity canonical-id migration through unsafe migration state file: ${migrationStatePath}.`,\n );\n }\n const [stateRoot, stateFile] = await Promise.all([\n realpath(deps.stateDir),\n realpath(migrationStatePath),\n ]);\n assertPathInsideRoot(stateRoot, stateFile, migrationStatePath);\n}\nasync function assertSafeTombstoneFile(\n deps: EntityCanonicalIdMigrationDependencies,\n tombstonePath: string,\n): Promise<boolean> {\n let fileStat;\n try {\n fileStat = await lstat(tombstonePath);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return false;\n throw error;\n }\n if (fileStat.isSymbolicLink() || !fileStat.isFile()) {\n throw new Error(\n `Refusing entity canonical-id migration through unsafe tombstone ledger: ${tombstonePath}.`,\n );\n }\n const [stateRoot, tombstoneFile] = await Promise.all([\n realpath(deps.stateDir),\n realpath(tombstonePath),\n ]);\n assertPathInsideRoot(stateRoot, tombstoneFile, tombstonePath);\n return true;\n}\n\nfunction lockPath(deps: EntityCanonicalIdMigrationDependencies): string {\n return path.join(deps.stateDir, \"entity-canonical-id-migration.lock\");\n}\n\n\nasync function readState(\n deps: EntityCanonicalIdMigrationDependencies\n): Promise<EntityCanonicalIdMigrationState | null> {\n await assertSafeMigrationStateFile(deps);\n let raw: string;\n try {\n raw = await readFile(statePath(deps), \"utf-8\");\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return null;\n throw error;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\"Invalid entity canonical-id migration state.\");\n }\n const result = EntityCanonicalIdMigrationStateSchema.safeParse(parsed);\n if (!result.success) throw new Error(\"Invalid entity canonical-id migration state.\");\n for (const mappings of [result.data.mappings, result.data.blocked ?? {}]) {\n for (const [legacyId, canonicalId] of Object.entries(mappings)) {\n assertSafeEntityId(legacyId);\n assertSafeEntityId(canonicalId);\n }\n }\n return result.data;\n}\n\nasync function writeState(\n deps: EntityCanonicalIdMigrationDependencies,\n state: EntityCanonicalIdMigrationState\n): Promise<void> {\n const destination = statePath(deps);\n const temporary = `${destination}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await writeFile(temporary, `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n await rename(temporary, destination);\n } finally {\n await unlink(temporary).catch(() => undefined);\n }\n}\n\n/**\n * Every journal publish — additive merges, completion markers, prunes —\n * serializes under the entity MUTATION lock (issue #2213 review): entity\n * writers, post-persist repair settles, and tombstone appends revalidate\n * the journal identity under that lock, so an unlocked publish could land\n * inside their resolve→write window and strand the write on a superseded\n * id space.\n */\nasync function publishState(\n deps: EntityCanonicalIdMigrationDependencies,\n state: EntityCanonicalIdMigrationState\n): Promise<void> {\n await withEntityCanonicalMutationLock(deps.stateDir, async () => {\n await writeState(deps, state);\n });\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return false;\n throw error;\n }\n}\n\nasync function sameFileIdentity(leftPath: string, rightPath: string): Promise<boolean> {\n try {\n const [left, right] = await Promise.all([statFile(leftPath), statFile(rightPath)]);\n return left.dev === right.dev && left.ino === right.ino;\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return false;\n throw error;\n }\n}\n\nasync function assertNotSymlink(filePath: string, label: string): Promise<void> {\n let stat;\n try {\n stat = await lstat(filePath);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return;\n throw error;\n }\n if (stat.isSymbolicLink()) {\n throw new Error(`Refusing entity canonical-id migration through symlink: ${label}.`);\n }\n}\nasync function assertNotMemorySymlink(filePath: string): Promise<void> {\n let stat;\n try {\n stat = await lstat(filePath);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return;\n throw error;\n }\n if (stat.isSymbolicLink()) {\n throw new Error(`Refusing entity canonical-id migration through symlinked memory: ${filePath}.`);\n }\n}\nasync function assertEntityContentUnchanged(\n deps: EntityCanonicalIdMigrationDependencies,\n filePath: string,\n expectedContent: string,\n legacyId: string,\n): Promise<void> {\n const latestContent = await deps.readStorageSecureFile(filePath);\n if (latestContent !== expectedContent) {\n throw new Error(`Legacy entity id ${legacyId} changed while migration was running; retry migration.`);\n }\n}\n\nasync function readSafeEntityEntries(entitiesDir: string): Promise<string[]> {\n const rootStat = await lstat(entitiesDir);\n if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {\n throw new Error(\"Refusing entity canonical-id migration through a symlinked or non-directory entities root.\");\n }\n const entries = await readdir(entitiesDir);\n for (const entry of entries) {\n await assertNotSymlink(path.join(entitiesDir, entry), entry);\n }\n return entries;\n}\n\n/**\n * Legacy ids the migration cannot resolve on its own, mapped to the canonical\n * id they collide with. Two entity files describing one entity is an ORDINARY\n * operator state, and picking a winner would silently drop whichever side lost.\n * So the pair is skipped and reported: reads of the legacy id keep working\n * exactly as they did before the migration ran.\n */\nexport type BlockedEntityPairs = Map<string, string>;\n\nasync function discoverMappings(\n deps: EntityCanonicalIdMigrationDependencies,\n knownMappings: Readonly<Record<string, string>> = {},\n blocked: BlockedEntityPairs = new Map(),\n): Promise<Record<string, string>> {\n const mappings: Record<string, string> = {};\n const canonicalOwners = new Map<string, string[]>();\n // Blocks describe THIS scan of the directory, so they are rebuilt per pass.\n // Accumulating them across a run would let a collision another writer has\n // since resolved keep pruning its now-valid mapping: the entity file gets\n // renamed while the pruned mapping skips the reference rewrite, stranding\n // memories on a filename that no longer exists.\n blocked.clear();\n const entityEntries = await readSafeEntityEntries(deps.entitiesDir);\n for (const entry of entityEntries) {\n if (!entry.endsWith(\".md\")) continue;\n const legacyId = entry.slice(0, -\".md\".length);\n assertSafeEntityId(legacyId);\n const legacyPath = deps.resolveEntityFilePath(legacyId);\n if (legacyPath === null) continue;\n const entityContent = await deps.readStorageSecureFile(legacyPath);\n if (\n !/^#[ \\t]+[^\\r\\n \\t]/m.test(entityContent)\n || !/^\\*\\*Type:\\*\\*[ \\t]*[^\\r\\n \\t]/m.test(entityContent)\n ) {\n throw new Error(`Cannot migrate malformed entity file ${entry}: missing name heading or type.`);\n }\n const entity = deps.parseEntityFile(entityContent);\n if (!entity.name.trim() || !entity.type.trim()) {\n throw new Error(`Cannot migrate malformed entity file ${entry}: missing name or type.`);\n }\n const canonicalId = deps.normalizeEntityName(entity.name, entity.type);\n assertSafeEntityId(canonicalId);\n if (legacyId === canonicalId) continue;\n const canonicalPath = deps.resolveEntityFilePath(canonicalId);\n if (canonicalPath === null) continue;\n const canonicalExists = await fileExists(canonicalPath);\n if (\n canonicalExists\n && await sameFileIdentity(legacyPath, canonicalPath)\n && knownMappings[legacyId] === canonicalId\n ) continue;\n if (canonicalExists) {\n const canonicalContent = await deps.readStorageSecureFile(canonicalPath);\n if (entityContent !== canonicalContent) {\n blocked.set(legacyId, canonicalId);\n continue;\n }\n }\n canonicalOwners.set(canonicalId, [...(canonicalOwners.get(canonicalId) ?? []), legacyId]);\n mappings[legacyId] = canonicalId;\n }\n // A canonical id claimed by more than one legacy file has no non-arbitrary\n // winner, and readdir order is not stable (§6) - so the \"winner\" would differ\n // between hosts reading identical data. Block every claimant instead.\n for (const [canonicalId, claimants] of canonicalOwners) {\n if (claimants.length < 2) continue;\n for (const legacyId of claimants) {\n blocked.set(legacyId, canonicalId);\n delete mappings[legacyId];\n }\n }\n return mappings;\n}\n\nasync function rewriteReferences(\n deps: EntityCanonicalIdMigrationDependencies,\n mappings: Readonly<Record<string, string>>,\n refreshLock: () => Promise<boolean>\n): Promise<{ rewroteColdMemory: boolean }> {\n let rewroteColdMemory = false;\n for (let pass = 0; pass < MEMORY_REWRITE_MAX_PASSES; pass += 1) {\n deps.invalidateAllMemoriesCache();\n deps.invalidateColdMemoriesCache();\n const [hotMemories, coldMemories, archivedMemories] = await Promise.all([\n deps.readAllMemories(),\n deps.readAllColdMemories(),\n deps.readArchivedMemories(),\n ]);\n const seenPaths = new Set<string>();\n let rewroteAny = false;\n for (const memory of [...hotMemories, ...coldMemories, ...archivedMemories]) {\n const memoryPath = path.resolve(memory.path);\n if (seenPaths.has(memoryPath)) continue;\n seenPaths.add(memoryPath);\n const previousEntityRef = memory.frontmatter.entityRef;\n const canonicalId = previousEntityRef ? mappings[previousEntityRef] : undefined;\n if (!previousEntityRef || !canonicalId) continue;\n await assertNotMemorySymlink(memory.path);\n const observedMemoryFingerprint = await fingerprintPath(memory.path);\n if (observedMemoryFingerprint === \"missing\") continue;\n if (!(await refreshLock())) throw new Error(\"Lost entity canonical-id migration lock.\");\n const latestMemory = await deps.readMemoryByPath(memory.path);\n if (!latestMemory) continue;\n const latestMemoryFingerprint = await fingerprintPath(latestMemory.path);\n if (latestMemoryFingerprint !== observedMemoryFingerprint) continue;\n const latestPreviousEntityRef = latestMemory.frontmatter.entityRef;\n const latestCanonicalId = latestPreviousEntityRef ? mappings[latestPreviousEntityRef] : undefined;\n if (!latestPreviousEntityRef || !latestCanonicalId) continue;\n const memoryEncrypted = await deps.isEncryptedStorageFile(latestMemory.path);\n if ((await fingerprintPath(latestMemory.path)) !== latestMemoryFingerprint) continue;\n await deps.snapshotBeforeWrite(latestMemory.path, \"write\");\n if ((await fingerprintPath(latestMemory.path)) !== latestMemoryFingerprint) continue;\n await deps.writeStorageSecureFile(\n latestMemory.path,\n deps.serializeMemoryWithEntityRef(latestMemory, latestCanonicalId),\n memoryEncrypted,\n );\n await deps.rewriteProjectedMemoryEntityReference(\n latestMemory.frontmatter.id,\n latestPreviousEntityRef,\n latestCanonicalId,\n );\n rewroteAny = true;\n rewroteColdMemory ||= latestMemory.path.includes(`${path.sep}cold${path.sep}`);\n }\n if (!rewroteAny) return { rewroteColdMemory };\n }\n throw new Error(\"Memory references changed while entity canonical-id migration was running; retry migration.\");\n}\n\nfunction rewriteTombstoneLine(\n line: string,\n mappings: Readonly<Record<string, string>>,\n normalizedMappings: ReadonlyMap<string, string>,\n): string {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n return line;\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return line;\n\n const tombstone = parsed as Record<string, unknown>;\n let changed = false;\n if (typeof tombstone.entityRef === \"string\") {\n const canonicalId = mappings[tombstone.entityRef];\n if (canonicalId) {\n tombstone.entityRef = canonicalId;\n changed = true;\n }\n }\n if (typeof tombstone.supersessionKey === \"string\") {\n const separator = tombstone.supersessionKey.indexOf(\"::\");\n if (separator < 0) return changed ? JSON.stringify(tombstone) : line;\n const normalizedLegacyId = normalizeSupersessionKey(tombstone.supersessionKey.slice(0, separator));\n const canonicalId = normalizedMappings.get(normalizedLegacyId);\n if (canonicalId) {\n const canonicalKey = computeSupersessionKey(canonicalId, tombstone.supersessionKey.slice(separator + 2));\n if (canonicalKey) {\n tombstone.supersessionKey = canonicalKey;\n changed = true;\n }\n }\n }\n return changed ? JSON.stringify(tombstone) : line;\n}\n\nasync function rewriteTombstoneReferences(\n deps: EntityCanonicalIdMigrationDependencies,\n mappings: Readonly<Record<string, string>>,\n refreshLock: () => Promise<boolean>\n): Promise<void> {\n const tombstonePath = path.join(deps.stateDir, \"tombstones.jsonl\");\n const normalizedMappings = new Map<string, string>();\n for (const [legacyId, canonicalId] of Object.entries(mappings)) {\n const normalizedLegacyId = normalizeSupersessionKey(legacyId);\n if (normalizedLegacyId && !normalizedMappings.has(normalizedLegacyId)) {\n normalizedMappings.set(normalizedLegacyId, canonicalId);\n }\n }\n\n await withHeldFileLock(\n path.join(deps.stateDir, \"tombstones.lock\"),\n {\n staleMs: TOMBSTONE_LOCK_STALE_MS,\n maxWaitMs: TOMBSTONE_LOCK_MAX_WAIT_MS,\n },\n async (acquired, tombstoneLock) => {\n if (!acquired) throw new Error(\"Timed out waiting for active tombstone migration.\");\n if (!(await assertSafeTombstoneFile(deps, tombstonePath))) return;\n const tombstoneEncrypted = await deps.isEncryptedStorageFile(tombstonePath);\n const original = await deps.readStorageSecureFile(tombstonePath);\n let changed = false;\n const rewritten = original\n .split(\"\\n\")\n .map((line) => {\n const next = rewriteTombstoneLine(line, mappings, normalizedMappings);\n changed ||= next !== line;\n return next;\n })\n .join(\"\\n\");\n if (!changed) return;\n if (!(await refreshLock())) throw new Error(\"Lost entity canonical-id migration lock.\");\n if (!(await tombstoneLock.refresh())) throw new Error(\"Lost tombstone migration lock.\");\n await deps.snapshotBeforeWrite(tombstonePath, \"write\");\n await deps.writeStorageSecureFile(tombstonePath, rewritten, tombstoneEncrypted);\n },\n );\n}\n\nasync function rewriteRelationshipTargets(\n deps: EntityCanonicalIdMigrationDependencies,\n mappings: Readonly<Record<string, string>>,\n refreshLock: () => Promise<boolean>\n): Promise<boolean> {\n let rewritten = false;\n const entries = await readSafeEntityEntries(deps.entitiesDir);\n for (const entry of entries) {\n if (!entry.endsWith(\".md\")) continue;\n const entityPath = deps.resolveEntityFilePath(entry.slice(0, -\".md\".length));\n if (entityPath === null) continue;\n const observedEntityFingerprint = await fingerprintPath(entityPath);\n if (observedEntityFingerprint === \"missing\") continue;\n const entity = deps.parseEntityFile(await deps.readStorageSecureFile(entityPath));\n const relationships = entity.relationships.map((relationship) => {\n const target = mappings[relationship.target];\n return target ? { ...relationship, target } : relationship;\n });\n if (relationships.every((relationship, index) => relationship === entity.relationships[index])) continue;\n const rewroteEntity = await withEntityCanonicalMutationLock(\n deps.stateDir,\n async (refreshEntityLock) => {\n if (!(await refreshLock())) throw new Error(\"Lost entity canonical-id migration lock.\");\n const latestEntity = deps.parseEntityFile(await deps.readStorageSecureFile(entityPath));\n if ((await fingerprintPath(entityPath)) !== observedEntityFingerprint) return false;\n const latestRelationships = latestEntity.relationships.map((relationship) => {\n const target = mappings[relationship.target];\n return target ? { ...relationship, target } : relationship;\n });\n if (latestRelationships.every((relationship, index) => relationship === latestEntity.relationships[index])) {\n return false;\n }\n const entityEncrypted = await deps.isEncryptedStorageFile(entityPath);\n if (!(await refreshEntityLock())) throw new Error(\"Lost entity mutation lock.\");\n if ((await fingerprintPath(entityPath)) !== observedEntityFingerprint) return false;\n await deps.snapshotBeforeWrite(entityPath, \"write\");\n if ((await fingerprintPath(entityPath)) !== observedEntityFingerprint) return false;\n await deps.writeStorageSecureFile(\n entityPath,\n deps.serializeEntityFile({ ...latestEntity, relationships: latestRelationships }),\n entityEncrypted,\n );\n return true;\n },\n );\n rewritten ||= rewroteEntity;\n }\n return rewritten;\n}\n\nasync function rewriteKnownReferences(\n deps: EntityCanonicalIdMigrationDependencies,\n mappings: Readonly<Record<string, string>>,\n refreshLock: () => Promise<boolean>,\n): Promise<boolean> {\n await rewriteRelationshipTargets(deps, mappings, refreshLock);\n let rewroteColdMemory = (await rewriteReferences(deps, mappings, refreshLock)).rewroteColdMemory;\n await rewriteTombstoneReferences(deps, mappings, refreshLock);\n await deps.rewriteProjectedEntityReferences(mappings);\n const finalMemoryPass = await rewriteReferences(deps, mappings, refreshLock);\n rewroteColdMemory ||= finalMemoryPass.rewroteColdMemory;\n return rewroteColdMemory;\n}\n\nfunction wouldCreateMappingCycle(\n mappings: Readonly<Record<string, string>>,\n legacyId: string,\n canonicalId: string,\n): boolean {\n let current = canonicalId;\n const seen = new Set<string>();\n while (true) {\n if (current === legacyId) return true;\n if (seen.has(current)) return false;\n seen.add(current);\n const next = mappings[current];\n if (!next || next === current) return false;\n current = next;\n }\n}\n\nfunction rejectMappingCycles(\n existing: Readonly<Record<string, string>>,\n discovered: Readonly<Record<string, string>>,\n): Record<string, string> {\n const accepted: Record<string, string> = {};\n const merged = { ...existing };\n for (const [legacyId, canonicalId] of Object.entries(discovered)) {\n if (\n merged[legacyId] === undefined &&\n wouldCreateMappingCycle(merged, legacyId, canonicalId)\n ) continue;\n accepted[legacyId] = canonicalId;\n merged[legacyId] = canonicalId;\n }\n return accepted;\n}\n\nfunction mergeDiscoveredMappings(\n existing: Readonly<Record<string, string>>,\n discovered: Readonly<Record<string, string>>,\n): Record<string, string> {\n const merged = { ...existing };\n const canonicalOwners = new Map<string, string>();\n for (const [legacyId, canonicalId] of Object.entries(discovered)) {\n const previousMapping = merged[legacyId];\n if (previousMapping !== undefined && previousMapping !== canonicalId) {\n // A -> B collapses to A -> C once B -> C exists, so a rescan that still\n // reads A -> B off disk is reporting the same chain, not a new target.\n // Only a target the chain cannot reach is a real conflict.\n let hop: string | undefined = canonicalId;\n const seen = new Set<string>();\n while (hop !== undefined && hop !== previousMapping && !seen.has(hop)) {\n seen.add(hop);\n hop = merged[hop];\n }\n if (hop !== previousMapping) {\n throw new Error(`Legacy entity id ${legacyId} changed canonical target during migration.`);\n }\n continue;\n }\n if (previousMapping === undefined && wouldCreateMappingCycle(merged, legacyId, canonicalId)) continue;\n const previousOwner = canonicalOwners.get(canonicalId);\n if (previousOwner !== undefined && previousOwner !== legacyId) {\n throw new Error(\n `Cannot migrate legacy entity ids ${previousOwner} and ${legacyId}: both normalize to ${canonicalId}.`,\n );\n }\n merged[legacyId] = canonicalId;\n canonicalOwners.set(canonicalId, legacyId);\n }\n return merged;\n}\nfunction collapseMappings(mappings: Readonly<Record<string, string>>): Record<string, string> {\n const collapsed: Record<string, string> = {};\n for (const legacyId of Object.keys(mappings)) {\n let current = legacyId;\n const seen = new Set<string>();\n while (true) {\n const next = mappings[current];\n if (!next || next === current) break;\n if (seen.has(current)) {\n throw new Error(`Entity canonical-id migration mapping cycle includes ${legacyId}.`);\n }\n seen.add(current);\n current = next;\n }\n if (current !== legacyId) collapsed[legacyId] = current;\n }\n return collapsed;\n}\n\ntype EntityFileMigrationResult = {\n deferred: boolean;\n progressed: boolean;\n /** The pair collided on content; skipped and reported, never migrated. */\n blocked?: boolean;\n};\n\nasync function migrateEntityFilePair(\n deps: EntityCanonicalIdMigrationDependencies,\n legacyId: string,\n canonicalId: string,\n refreshMigrationLock: () => Promise<boolean>,\n): Promise<EntityFileMigrationResult> {\n return withEntityCanonicalMutationLock(deps.stateDir, async (refreshEntityLock) => {\n assertSafeEntityId(legacyId);\n assertSafeEntityId(canonicalId);\n const legacyPath = deps.resolveEntityFilePath(legacyId);\n const canonicalPath = deps.resolveEntityFilePath(canonicalId);\n if (legacyPath === null || canonicalPath === null) {\n throw new Error(\"Invalid entity canonical-id migration path.\");\n }\n await assertNotSymlink(legacyPath, legacyId);\n await assertNotSymlink(canonicalPath, canonicalId);\n const legacyExists = await fileExists(legacyPath);\n const canonicalExists = await fileExists(canonicalPath);\n if (!legacyExists && !canonicalExists) return { deferred: true, progressed: false };\n if (legacyExists && canonicalExists) {\n if (await sameFileIdentity(legacyPath, canonicalPath)) return { deferred: false, progressed: false };\n const [legacyContent, canonicalContent, legacyEncrypted, canonicalEncrypted] = await Promise.all([\n deps.readStorageSecureFile(legacyPath),\n deps.readStorageSecureFile(canonicalPath),\n deps.isEncryptedStorageFile(legacyPath),\n deps.isEncryptedStorageFile(canonicalPath),\n ]);\n if (legacyContent !== canonicalContent) {\n // A mapping persisted by an older build, or a file changed since\n // discovery. Same verdict as discovery: skip the pair, keep both files.\n return { deferred: false, progressed: false, blocked: true };\n }\n if (legacyEncrypted && !canonicalEncrypted) {\n if (!(await refreshMigrationLock()) || !(await refreshEntityLock())) {\n throw new Error(\"Lost entity canonical-id migration lock.\");\n }\n await deps.snapshotBeforeWrite(canonicalPath, \"write\");\n await deps.writeStorageSecureFile(canonicalPath, legacyContent, true);\n if ((await deps.readStorageSecureFile(canonicalPath)) !== legacyContent) {\n throw new Error(`Cannot verify migrated entity id ${canonicalId}.`);\n }\n }\n if (!(await refreshMigrationLock()) || !(await refreshEntityLock())) {\n throw new Error(\"Lost entity canonical-id migration lock.\");\n }\n await deps.snapshotBeforeWrite(legacyPath, \"write\");\n await assertNotSymlink(legacyPath, legacyId);\n await assertEntityContentUnchanged(deps, legacyPath, legacyContent, legacyId);\n await unlink(legacyPath);\n return { deferred: false, progressed: true };\n }\n if (!legacyExists) return { deferred: false, progressed: false };\n if (!(await refreshMigrationLock()) || !(await refreshEntityLock())) {\n throw new Error(\"Lost entity canonical-id migration lock.\");\n }\n const entityEncrypted = await deps.isEncryptedStorageFile(legacyPath);\n const entityContent = await deps.readStorageSecureFile(legacyPath);\n await assertNotSymlink(legacyPath, legacyId);\n await assertEntityContentUnchanged(deps, legacyPath, entityContent, legacyId);\n let canonicalFingerprintAfterWrite: string | null = null;\n try {\n await deps.writeStorageSecureFile(canonicalPath, entityContent, entityEncrypted);\n canonicalFingerprintAfterWrite = await fingerprintPath(canonicalPath);\n if ((await deps.readStorageSecureFile(canonicalPath)) !== entityContent) {\n throw new Error(`Cannot verify migrated entity id ${canonicalId}.`);\n }\n if (!(await refreshMigrationLock()) || !(await refreshEntityLock())) {\n throw new Error(\"Lost entity canonical-id migration lock.\");\n }\n await deps.snapshotBeforeWrite(legacyPath, \"write\");\n await assertNotSymlink(legacyPath, legacyId);\n await assertEntityContentUnchanged(deps, legacyPath, entityContent, legacyId);\n await unlink(legacyPath);\n } catch (error) {\n if (!canonicalExists && canonicalFingerprintAfterWrite !== null) {\n try {\n if ((await fingerprintPath(canonicalPath)) === canonicalFingerprintAfterWrite) {\n await assertNotSymlink(canonicalPath, canonicalId);\n await unlink(canonicalPath);\n }\n } catch {\n // Preserve the migration error when cleanup races another writer.\n }\n }\n throw error;\n }\n return { deferred: false, progressed: true };\n });\n}\n\nexport async function migrateLegacyEntityCanonicalIds(\n deps: EntityCanonicalIdMigrationDependencies,\n): Promise<string | undefined> {\n return withHeldFileLock(\n lockPath(deps),\n {\n staleMs: ENTITY_CANONICAL_ID_MIGRATION_LOCK_STALE_MS,\n maxWaitMs: ENTITY_CANONICAL_ID_MIGRATION_LOCK_MAX_WAIT_MS,\n },\n async (acquired, lock) => {\n if (!acquired) throw new Error(\"Timed out waiting for active entity canonical-id migration.\");\n await deps.validateMemoryScanRoots?.();\n await readSafeEntityEntries(deps.entitiesDir);\n // A raw-byte writer (offline sync, consolidation-undo, governance\n // restore) may have landed memory bytes this process never vetted; the\n // marker requests ONE reference-reconciliation pass (issue #2213). The\n // observed generation is RENAMED aside before the pass so a request made\n // WHILE this run scans creates a fresh marker that survives finish() —\n // and a `.consuming` file left by a crashed run still owes its pass.\n const reconcileMarkerPath = path.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_MARKER);\n const consumingMarkerPath = path.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER);\n let reconcileRequested = await fileExists(consumingMarkerPath);\n if (await fileExists(reconcileMarkerPath)) {\n try {\n await rename(reconcileMarkerPath, consumingMarkerPath);\n reconcileRequested = true;\n } catch (error) {\n if (!isErrnoCode(error, \"ENOENT\")) throw error;\n }\n }\n let state = await readState(deps);\n if (!state) {\n state = {\n version: ENTITY_CANONICAL_ID_MIGRATION_VERSION,\n complete: false,\n mappings: {},\n };\n }\n const blocked: BlockedEntityPairs = new Map();\n // ONE aggregated line per run, not one per pair per restart: this used to\n // abort the daemon, so the operator needs the whole list and the remedy.\n const finish = async (): Promise<string | undefined> => {\n if (blocked.size > 0) {\n const pairs = [...blocked].map(([legacyId, canonicalId]) => `${legacyId} -> ${canonicalId}`).join(\", \");\n log.warn(\n `entity canonical-id migration skipped ${blocked.size} unresolvable pair(s): ${pairs}. `\n + \"Both files were kept and the legacy id still resolves; merge or delete one side to migrate it.\",\n );\n }\n // Every finish() path either just rewrote references (main/reconcile\n // paths), has none to rewrite (empty mappings), or observed no marker\n // (stable no-op) — so the CONSUMED generation is removed here. A fresh\n // marker written mid-run is untouched, and a crash before this point\n // leaves `.consuming` set for the next run (the rewrite is idempotent).\n if (reconcileRequested) {\n await unlink(consumingMarkerPath).catch((error: unknown) => {\n if (!isErrnoCode(error, \"ENOENT\")) throw error;\n });\n }\n // A FRESH marker written while this run scanned means bytes landed the\n // pass may not have covered. Withholding the completion fingerprint\n // makes the runner's stability check fail, so it immediately retries —\n // and the retry consumes the fresh generation. ORDER MATTERS: read the\n // fingerprint BEFORE the marker check. A marker landing after the\n // fingerprint read but before the check is caught by the check; one\n // landing after the check is absent from the returned fingerprint, so\n // the live marker mismatches the runner's cached completion and the\n // next ensure() re-invokes. Checking first left a window where the\n // fingerprint could SEAL a marker the check never saw.\n const completionFingerprint = await deps.readMigrationFingerprint?.();\n if (await fileExists(reconcileMarkerPath)) return undefined;\n return completionFingerprint;\n };\n /**\n * Drop blocked pairs from the working set. Discovery only refuses to\n * ADD them; a mapping persisted by an earlier run would otherwise still\n * be applied - migrating one claimant and rewriting every reference onto\n * the canonical file, i.e. picking the winner this fix exists to avoid,\n * off stale state rather than what is on disk.\n */\n /** @returns true when a park was promoted back into the mapping set. */\n const pruneBlocked = async (): Promise<boolean> => {\n const current = state;\n if (!current) return false;\n // THIS scan's verdict wins over the journal: normalization can change\n // between runs, so a stale parked target would otherwise be promoted\n // later and rewrite references onto an id that does not exist.\n let revived = false;\n const parked: Record<string, string> = { ...(current.blocked ?? {}) };\n const active: Record<string, string> = {};\n for (const [legacyId, canonicalId] of Object.entries(current.mappings)) {\n if (!blocked.has(legacyId)) active[legacyId] = canonicalId;\n }\n for (const [legacyId, canonicalId] of blocked) parked[legacyId] = canonicalId;\n // A parked pair whose legacy file is gone was resolved by keeping the\n // canonical side. The rename is moot; the reference rewrite is not, and\n // this record is the only thing that can still perform it.\n // A park survives ONLY while this scan re-establishes the collision.\n // Anything else - the scan found a real migration, or found the source\n // needs none (already canonical under a newer normalization) - makes\n // the record obsolete, and keeping it lets a later deletion promote a\n // target the entity never occupied.\n for (const [legacyId, canonicalId] of Object.entries(parked)) {\n if (blocked.has(legacyId)) continue;\n delete parked[legacyId];\n if (active[legacyId] !== undefined) continue;\n const legacyPath = deps.resolveEntityFilePath(legacyId);\n if (legacyPath !== null && (await fileExists(legacyPath))) continue;\n // Source gone: the rename is moot, but references still name it and\n // this record is the only thing that can still rewrite them.\n active[legacyId] = canonicalId;\n revived = true;\n }\n // Reviving a whole chain at once yields A -> B -> C, and each rewrite\n // surface makes a different number of passes over it - so collapse\n // transitively before anything consumes the set.\n const collapsed = collapseMappings(active);\n // Parked targets follow ACTIVE moves only: hopping over a still-blocked\n // link would jump to an id the migration has not been allowed to reach.\n for (const [legacyId, canonicalId] of Object.entries(parked)) {\n const moved = collapsed[canonicalId];\n if (moved !== undefined && moved !== legacyId) parked[legacyId] = moved;\n }\n const same = (a: Record<string, string>, b: Record<string, string>): boolean =>\n Object.keys(a).length === Object.keys(b).length\n && Object.entries(a).every(([key, value]) => b[key] === value);\n if (same(collapsed, current.mappings) && same(parked, current.blocked ?? {})) return revived;\n // Parking/removing an active mapping mid-entity-write would land an\n // alias/activity/relationship mutation on a now-unrelated canonical\n // claimant — the reconcile pass rewrites references, it cannot move\n // a misplaced mutation. publishState serializes under the lock.\n state = { ...current, mappings: collapsed, blocked: parked };\n await publishState(deps, state);\n return revived;\n };\n const previousMappings = state.mappings;\n const collapsedMappings = collapseMappings(previousMappings);\n const mappingsChanged =\n Object.keys(collapsedMappings).length !== Object.keys(previousMappings).length\n || Object.entries(collapsedMappings).some(([legacyId, canonicalId]) =>\n previousMappings[legacyId] !== canonicalId\n );\n state = { ...state, mappings: collapsedMappings };\n for (let migrationPass = 0; migrationPass < ENTITY_MAPPING_RESCAN_MAX_PASSES; migrationPass += 1) {\n if (!(await lock.refresh())) throw new Error(\"Lost entity canonical-id migration lock.\");\n const discoveredBefore = rejectMappingCycles(\n state.mappings,\n await discoverMappings(deps, state.mappings, blocked),\n );\n const revivedBefore = await pruneBlocked();\n const mergedBefore = collapseMappings(mergeDiscoveredMappings(state.mappings, discoveredBefore));\n // Stable completed journal → no-op (issue #2213). Retained mappings are\n // read-compat state whose references were already rewritten (to\n // convergence) before `complete: true` was persisted, so re-running\n // `rewriteKnownReferences` here re-read the ENTIRE hot+cold+archived\n // corpus — twice — and invalidated every memory cache on EVERY\n // `ensureDirectories()`. On a write-active daemon that was a\n // self-sustaining hot loop (multi-GB/s of re-reads, caches never warm,\n // recall degraded to the fallback path). A park revived by THIS run's\n // pruneBlocked still owes its reference rewrite: it falls through to\n // the main flow below, which demotes `complete` BEFORE rewriting — so\n // a crash mid-rewrite resumes, which the old in-place rewrite did not.\n if (\n state.complete\n && Object.keys(discoveredBefore).length === 0\n && !mappingsChanged\n && !revivedBefore\n ) {\n // Stable journal, but a raw-byte writer requested reconciliation:\n // run ONE bounded rewrite pass over the retained mappings, then let\n // finish() consume the marker.\n if (reconcileRequested && Object.keys(state.mappings).length > 0) {\n const rewroteColdMemory = await rewriteKnownReferences(\n deps,\n state.mappings,\n () => lock.refresh(),\n );\n deps.invalidateKnowledgeIndexCache();\n deps.invalidateAllMemoriesCache();\n if (rewroteColdMemory) deps.invalidateColdMemoriesCache();\n deps.bumpMemoryStatusVersion();\n }\n return finish();\n }\n if (\n state.complete\n || Object.keys(discoveredBefore).length > 0\n || Object.keys(mergedBefore).length !== Object.keys(state.mappings).length\n ) {\n state = { ...state, complete: false, mappings: mergedBefore };\n await publishState(deps, state);\n }\n if (Object.keys(state.mappings).length === 0) {\n if (!(await lock.refresh())) throw new Error(\"Lost entity canonical-id migration lock.\");\n const discoveredAfter = rejectMappingCycles(\n state.mappings,\n await discoverMappings(deps, state.mappings, blocked),\n );\n // Reconcile before declaring completion: this rescan can resolve a\n // park (another writer removed the legacy file), and completing\n // without promoting it strands its references behind a fingerprint\n // that already reflects the deletion - so no later run revisits it.\n const revivedInRescan = await pruneBlocked();\n if (Object.keys(discoveredAfter).length === 0 && !revivedInRescan) {\n await publishState(deps, { ...state, complete: true });\n return finish();\n }\n state = {\n ...state,\n complete: false,\n mappings: collapseMappings(mergeDiscoveredMappings(state.mappings, discoveredAfter)),\n };\n await publishState(deps, state);\n continue;\n }\n let pendingMappings = Object.entries(state.mappings);\n while (pendingMappings.length > 0) {\n const deferredMappings: Array<[string, string]> = [];\n let progressed = false;\n for (const [legacyId, canonicalId] of pendingMappings) {\n const result = await migrateEntityFilePair(\n deps,\n legacyId,\n canonicalId,\n () => lock.refresh(),\n );\n if (result.blocked) blocked.set(legacyId, canonicalId);\n else if (result.deferred) deferredMappings.push([legacyId, canonicalId]);\n progressed ||= result.progressed;\n }\n if (deferredMappings.length === 0) break;\n if (!progressed) {\n const [legacyId, canonicalId] = deferredMappings[0]!;\n throw new Error(\n `Cannot migrate legacy entity id ${legacyId}: both files are missing and no intermediate mapping can advance migration.`,\n );\n }\n pendingMappings = deferredMappings;\n }\n await pruneBlocked();\n\n const rewroteColdMemory = await rewriteKnownReferences(\n deps,\n state.mappings,\n () => lock.refresh(),\n );\n deps.invalidateKnowledgeIndexCache();\n deps.invalidateAllMemoriesCache();\n if (rewroteColdMemory) deps.invalidateColdMemoriesCache();\n deps.bumpMemoryStatusVersion();\n\n if (!(await lock.refresh())) throw new Error(\"Lost entity canonical-id migration lock.\");\n const discoveredAfter = rejectMappingCycles(\n state.mappings,\n await discoverMappings(deps, state.mappings, blocked),\n );\n // A park resolved after the rewrite pass is promoted here, and a\n // promotion still has to be APPLIED. Completing on `discoveredAfter`\n // alone fingerprints the post-deletion corpus, so the runner never\n // retries and those references stay stranded.\n const revivedAfterRewrite = await pruneBlocked();\n if (Object.keys(discoveredAfter).length === 0 && !revivedAfterRewrite) {\n await publishState(deps, { ...state, complete: true });\n return finish();\n }\n state = {\n ...state,\n complete: false,\n mappings: collapseMappings(mergeDiscoveredMappings(state.mappings, discoveredAfter)),\n };\n await publishState(deps, state);\n }\n throw new Error(\"Entity canonical-id migration mappings changed while migration was running; retry migration.\");\n }\n );\n}\n","/**\n * Post-persist entity-reference repair (issue #2213), extracted from\n * storage.ts (#1520 god-file ratchet).\n *\n * Every store-mediated writer that persists an `entityRef` resolves it at\n * the write; when the canonical-id journal moves ACROSS the write (a peer\n * migration publishing between resolve and persist), the repair re-resolves\n * from the caller's ORIGINAL ref and rewrites through the blocked-capture\n * surface. On repair failure the caller-declared rollback runs BEFORE the\n * error propagates (AGENTS.md §14): a caller that reports failure must\n * leave disk in the state peers/caches were told about.\n */\nimport { unlink } from \"node:fs/promises\";\nimport { log } from \"../logger.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport * as entityRefs from \"./entity-canonical-id-references.js\";\nimport {\n applyTombstoneResurrectionGate,\n type TombstoneMatch,\n type TombstoneStore,\n} from \"../lifecycle/tombstones.js\";\nimport { supersessionKeysForFact } from \"../temporal-supersession.js\";\nimport { ContentHashIndex } from \"./content-hash-index.js\";\nimport { rewriteProjectedMemoryEntityReference } from \"../memory-projection-mutations.js\";\n\nexport interface EntityRefRepairDeps {\n readonly stateDir: string;\n readonly baseDir: string;\n currentHistoricalIds(): Readonly<Record<string, string>>;\n serializeFrontmatter(fm: MemoryFrontmatter): string;\n writeTombstoneBlockedMemory(\n pathname: string,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n ): Promise<void>;\n invalidateAllMemoriesCache(): void;\n getTombstoneStore(): Promise<TombstoneStore>;\n tombstonesEnabled(): boolean;\n tombstonesNamespace(): string;\n}\n\nexport interface EntityRefRepairOptions {\n /** Re-run the add-only resurrection gate under the FINAL ref before the\n * rewrite (chunk writes, where `body` IS the hash source). */\n regateFact?: boolean;\n /** Rollback: rewrite this pre-mutation record on repair failure. */\n onFailRestore?: MemoryFile;\n /** Rollback: unlink a file this mutation created on repair failure. */\n onFailRemove?: string;\n}\n\nexport class EntityRefRepair {\n constructor(private readonly deps: EntityRefRepairDeps) {}\n\n /**\n * Shared lookup+apply core for the write-time resurrection gate (#1579 /\n * #2213): fail-open, add-only; writeMemory's gate + chunk-repair re-gate\n * consult this one implementation (rule 43).\n */\n async gate(\n fm: MemoryFrontmatter,\n canonicalBody: string,\n structuredAttributes?: Record<string, string>,\n ): Promise<TombstoneMatch | null> {\n if (!this.deps.tombstonesEnabled()) return null;\n try {\n const store = await this.deps.getTombstoneStore();\n // Pass EVERY derived key (thread Ociag/Oci-W): emitters register one\n // tombstone per key, so the block can be on any of them.\n const supersessionKeys =\n fm.entityRef && structuredAttributes\n ? supersessionKeysForFact({ entityRef: fm.entityRef, structuredAttributes })\n : [];\n const match = applyTombstoneResurrectionGate(store, fm, {\n normalizedText: ContentHashIndex.normalizeContent(canonicalBody),\n supersessionKeys,\n namespace: this.deps.tombstonesNamespace(),\n });\n if (match) {\n log.info(\n `tombstone: blocked resurrection of fact ${fm.id} (tier=${match.matchedTier}, tombstone=${match.tombstoneId}, reason=${match.reason})`\n );\n }\n return match;\n } catch (err) {\n // Fail-open (rule 34): a lookup error must not block the write.\n log.warn(`tombstone lookup failed for fact ${fm.id} (fail-open): ${err}`);\n return null;\n }\n }\n\n /** Post-persist repair delegate — see the references module for semantics. */\n async repair(\n filePath: string,\n fm: MemoryFrontmatter,\n rawRef: string,\n refIds: Readonly<Record<string, string>>,\n body: string,\n opts: EntityRefRepairOptions = {},\n ): Promise<void> {\n const refBeforeRepair = fm.entityRef;\n try {\n await entityRefs.repairEntityRefAfterJournalMove({\n stateDir: this.deps.stateDir,\n currentIds: () => this.deps.currentHistoricalIds(),\n idsAtResolve: refIds,\n rawRef,\n frontmatter: fm,\n rewrite: async () => {\n if (opts.regateFact && fm.category === \"fact\") {\n await this.gate(fm, body, fm.structuredAttributes);\n }\n // Blocked-capture surface: a repair rewrite of a tombstone-blocked\n // record must keep TombstoneBlockedCaptureIndex consistent.\n await this.deps.writeTombstoneBlockedMemory(\n filePath,\n `${this.deps.serializeFrontmatter(fm)}\\n\\n${body}\\n`,\n fm,\n body,\n );\n this.deps.invalidateAllMemoriesCache();\n },\n });\n } catch (err) {\n if (opts.onFailRestore) {\n await this.restore(opts.onFailRestore);\n } else if (opts.onFailRemove) {\n await unlink(opts.onFailRemove).catch(() => undefined);\n this.deps.invalidateAllMemoriesCache();\n }\n throw err;\n }\n await this.syncProjection(fm.id, refBeforeRepair, fm.entityRef);\n }\n\n /**\n * Restore a record's pre-mutation bytes through the blocked-capture\n * surface when a post-persist repair fails (§14).\n */\n async restore(before: MemoryFile): Promise<void> {\n try {\n await this.deps.writeTombstoneBlockedMemory(\n before.path,\n `${this.deps.serializeFrontmatter(before.frontmatter)}\\n\\n${before.content}\\n`,\n before.frontmatter,\n before.content,\n );\n } catch (restoreErr) {\n log.warn(`failed to restore ${before.frontmatter.id} after repair failure: ${restoreErr}`);\n }\n this.deps.invalidateAllMemoriesCache();\n }\n\n /**\n * Projection rows written under the pre-repair claimant cannot be restored\n * once the mapping is parked (Codex P1). Fail-open: projection is rebuildable.\n */\n async syncProjection(\n memoryId: string,\n refBefore: string | undefined,\n refAfter: string | undefined,\n ): Promise<void> {\n if (typeof refBefore !== \"string\" || typeof refAfter !== \"string\" || refBefore === refAfter) return;\n try {\n await rewriteProjectedMemoryEntityReference(this.deps.baseDir, memoryId, refBefore, refAfter);\n } catch (err) {\n log.warn(`projection entityRef sync failed for ${memoryId}: ${err}`);\n }\n }\n}\n","import type { EntityFile, MemoryFile } from \"../types.js\";\nimport {\n getFingerprint,\n migrateLegacyEntityCanonicalIds,\n validateRoots,\n type EntityCanonicalIdMigrationDependencies,\n} from \"./entity-canonical-id-migration.js\";\nimport {\n rewriteProjectedEntityReferences,\n rewriteProjectedMemoryEntityReference,\n} from \"../memory-projection-mutations.js\";\n\nexport interface EntityCanonicalIdMigrationHost {\n readonly baseDir: string;\n readonly entitiesDir: string;\n readonly stateDir: string;\n readonly archiveDir: string;\n normalizeEntityName(raw: string, type: string): string;\n resolveEntityFilePath(id: string): string | null;\n readStorageSecureFile(filePath: string): Promise<string>;\n writeStorageSecureFile(filePath: string, content: string, forceEncrypt?: boolean): Promise<void>;\n isEncryptedFileHeader(filePath: string): Promise<boolean>;\n snapshotBeforeWrite(filePath: string, trigger: \"write\"): Promise<void>;\n readMemoryByPath(filePath: string): Promise<MemoryFile | null>;\n readAllMemories(): Promise<MemoryFile[]>;\n readAllColdMemories(): Promise<MemoryFile[]>;\n readArchivedMemories(): Promise<MemoryFile[]>;\n invalidateKnowledgeIndexCache(): void;\n invalidateAllMemoriesCache(): void;\n invalidateColdMemoriesCache(): void;\n bumpMemoryStatusVersion(): void;\n getEntityMutationVersion(): number;\n}\n\nexport async function runLegacyEntityCanonicalIdMigration(\n host: EntityCanonicalIdMigrationHost,\n parseEntityFile: (content: string) => EntityFile,\n serializeEntityFile: (entity: EntityFile) => string,\n serializeMemoryWithEntityRef: (memory: MemoryFile, entityRef: string) => string,\n): Promise<string | undefined> {\n const readMigrationFingerprint = () =>\n getFingerprint(host.baseDir, host.entitiesDir, () => String(host.getEntityMutationVersion()));\n const completionFingerprint = await migrateLegacyEntityCanonicalIds({\n stateDir: host.stateDir,\n entitiesDir: host.entitiesDir,\n normalizeEntityName: host.normalizeEntityName.bind(host),\n resolveEntityFilePath: host.resolveEntityFilePath.bind(host),\n readStorageSecureFile: host.readStorageSecureFile.bind(host),\n writeStorageSecureFile: host.writeStorageSecureFile.bind(host),\n isEncryptedStorageFile: host.isEncryptedFileHeader.bind(host),\n snapshotBeforeWrite: host.snapshotBeforeWrite.bind(host),\n parseEntityFile,\n serializeEntityFile,\n serializeMemoryWithEntityRef,\n readMemoryByPath: host.readMemoryByPath.bind(host),\n readAllMemories: host.readAllMemories.bind(host),\n readAllColdMemories: host.readAllColdMemories.bind(host),\n readArchivedMemories: host.readArchivedMemories.bind(host),\n validateMemoryScanRoots: () =>\n validateRoots(host.baseDir, host.entitiesDir, host.stateDir, host.archiveDir),\n rewriteProjectedEntityReferences: (mappings) =>\n rewriteProjectedEntityReferences(host.baseDir, mappings),\n rewriteProjectedMemoryEntityReference: (memoryId, previousEntityRef, nextEntityRef) =>\n rewriteProjectedMemoryEntityReference(host.baseDir, memoryId, previousEntityRef, nextEntityRef),\n invalidateKnowledgeIndexCache: host.invalidateKnowledgeIndexCache.bind(host),\n invalidateAllMemoriesCache: host.invalidateAllMemoriesCache.bind(host),\n invalidateColdMemoriesCache: host.invalidateColdMemoriesCache.bind(host),\n bumpMemoryStatusVersion: host.bumpMemoryStatusVersion.bind(host),\n readMigrationFingerprint,\n } satisfies EntityCanonicalIdMigrationDependencies);\n // An undefined completion fingerprint is a deliberate signal (issue #2213):\n // a reconcile marker landed while the run scanned, and recomputing the\n // fingerprint here would seal that pending request into the runner's\n // completed state. Propagate it so the runner retries instead.\n return completionFingerprint;\n}\n","export class EntityCanonicalIdMigrationRunner {\n private inFlight: Promise<void> | null = null;\n private directoriesInitialized = false;\n private migrationComplete = false;\n private completedFingerprint: string | null = null;\n\n public constructor(\n private readonly canRun: () => boolean,\n private readonly runMigration: () => Promise<string | void>,\n private readonly readFingerprint: () => Promise<string> = async () => \"static\",\n ) {}\n\n public async markDirectoriesInitialized(): Promise<void> {\n this.directoriesInitialized = true;\n await this.ensure();\n }\n\n public ensure(): Promise<void> {\n if (!this.canRun()) return Promise.resolve();\n if (this.inFlight) return this.inFlight;\n const migration = this.runOrReuse();\n this.inFlight = migration;\n void migration.then(\n () => this.clearInFlight(migration),\n () => this.clearInFlight(migration),\n );\n return migration;\n }\n\n public triggerAfterUnlock(): Promise<void> {\n if (!this.directoriesInitialized) return Promise.resolve();\n return this.ensure();\n }\n\n private async runOrReuse(): Promise<void> {\n let fingerprintAtStart = await this.readFingerprint();\n if (this.migrationComplete && fingerprintAtStart === this.completedFingerprint) return;\n\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const completionFingerprint = await this.runMigration();\n const fingerprintAfterMigration = await this.readFingerprint();\n const fingerprintAfterStabilityRead = await this.readFingerprint();\n const returnedFingerprint =\n typeof completionFingerprint === \"string\" ? completionFingerprint : fingerprintAfterMigration;\n if (\n returnedFingerprint === fingerprintAfterMigration\n && fingerprintAfterMigration === fingerprintAfterStabilityRead\n && (\n typeof completionFingerprint === \"string\"\n || fingerprintAfterMigration === fingerprintAtStart\n )\n ) {\n this.migrationComplete = true;\n this.completedFingerprint = fingerprintAfterStabilityRead;\n return;\n }\n fingerprintAtStart = fingerprintAfterStabilityRead;\n }\n\n this.migrationComplete = false;\n this.completedFingerprint = null;\n throw new Error(\"Entity canonical-id migration fingerprint changed while migration was completing; retry migration.\");\n }\n\n private clearInFlight(migration: Promise<void>): void {\n if (this.inFlight === migration) this.inFlight = null;\n }\n}\n","import type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport { readRawMemoryDocument } from \"./memory-frontmatter-metadata.js\";\nimport { canonicalizeEntityRefFrontmatter } from \"./entity-canonical-id-references.js\";\n\nexport type MemoryEntityRefSerializer = (memory: MemoryFile, entityRef: string) => string;\n\nexport function serializeMemoryWithEntityRef(\n memory: MemoryFile,\n entityRef: string,\n fallback: MemoryEntityRefSerializer,\n): string {\n const rawDocument = readRawMemoryDocument(memory);\n if (rawDocument === undefined) return fallback(memory, entityRef);\n const currentEntityRef = memory.frontmatter.entityRef;\n if (currentEntityRef === undefined) return fallback(memory, entityRef);\n if (currentEntityRef === entityRef) return rawDocument;\n const rewritten = canonicalizeEntityRefFrontmatter(rawDocument, { [currentEntityRef]: entityRef });\n if (rewritten !== rawDocument) return rewritten;\n return fallback(memory, entityRef);\n}\n\nexport function createMemoryEntityRefSerializer(\n serializeFrontmatter: (frontmatter: MemoryFrontmatter) => string,\n): MemoryEntityRefSerializer {\n return (memory, entityRef) =>\n serializeMemoryWithEntityRef(\n memory,\n entityRef,\n (fallbackMemory, fallbackEntityRef) =>\n `${serializeFrontmatter({ ...fallbackMemory.frontmatter, entityRef: fallbackEntityRef })}\\n\\n${fallbackMemory.content}\\n`,\n );\n}\n","import {\n closeSync,\n constants,\n fstatSync,\n lstatSync,\n openSync,\n readFileSync,\n realpathSync,\n} from \"node:fs\";\nimport path from \"node:path\";\n\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { assertPathInsideRoot } from \"../utils/path-containment.js\";\n\nfunction resolveSafeAliasRoots(baseDir: string, configDir: string): string | undefined {\n let baseStat;\n try {\n baseStat = lstatSync(baseDir);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return undefined;\n throw error;\n }\n if (baseStat.isSymbolicLink() || !baseStat.isDirectory()) {\n throw new Error(`Refusing unsafe entity alias memory root: ${baseDir}.`);\n }\n\n let configStat;\n try {\n configStat = lstatSync(configDir);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return undefined;\n throw error;\n }\n if (configStat.isSymbolicLink() || !configStat.isDirectory()) {\n throw new Error(`Refusing unsafe entity alias config root: ${configDir}.`);\n }\n\n const memoryRoot = realpathSync(baseDir);\n assertPathInsideRoot(memoryRoot, realpathSync(configDir), configDir);\n return memoryRoot;\n}\n\nexport function readEntityAliasConfigSync(baseDir: string): string | undefined {\n const configDir = path.join(baseDir, \"config\");\n const aliasPath = path.join(configDir, \"aliases.json\");\n let memoryRoot = resolveSafeAliasRoots(baseDir, configDir);\n if (memoryRoot === undefined) return undefined;\n\n let aliasPreflight;\n try {\n aliasPreflight = lstatSync(aliasPath);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return undefined;\n throw error;\n }\n if (aliasPreflight.isSymbolicLink() || !aliasPreflight.isFile()) {\n throw new Error(`Refusing unsafe entity alias config file: ${aliasPath}.`);\n }\n\n let fd: number;\n try {\n fd = openSync(\n aliasPath,\n constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0),\n );\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) {\n resolveSafeAliasRoots(baseDir, configDir);\n return undefined;\n }\n if (isErrnoCode(error, \"ELOOP\")) {\n throw new Error(`Refusing unsafe entity alias config file: ${aliasPath}.`);\n }\n throw error;\n }\n try {\n const opened = fstatSync(fd);\n memoryRoot = resolveSafeAliasRoots(baseDir, configDir);\n if (memoryRoot === undefined) {\n throw new Error(`Refusing unsafe entity alias config root: ${configDir}.`);\n }\n const aliasStat = lstatSync(aliasPath);\n if (\n !opened.isFile() ||\n aliasStat.isSymbolicLink() ||\n !aliasStat.isFile() ||\n aliasStat.dev !== opened.dev ||\n aliasStat.ino !== opened.ino\n ) {\n throw new Error(`Refusing unsafe entity alias config file: ${aliasPath}.`);\n }\n assertPathInsideRoot(memoryRoot, realpathSync(aliasPath), aliasPath);\n return readFileSync(fd, \"utf-8\");\n } finally {\n closeSync(fd);\n }\n}\n","/**\n * Decode a YAML double-quoted scalar: strip surrounding quotes and decode\n * JSON escape sequences. Used for fields that may be quoted at serialization\n * time to prevent frontmatter injection (e.g. sourceConnector).\n * Only double-quoted (JSON-compatible) values are decoded — the serializer\n * never emits single-quoted scalars.\n */\nexport function decodeYamlScalar(value: string): string {\n const trimmed = value.trim();\n if (trimmed.length >= 2 && trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n try {\n const decoded = JSON.parse(trimmed);\n if (typeof decoded === \"string\") return decoded;\n } catch {\n // Fall through to strip quotes if JSON.parse fails\n }\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n","/**\n * QMD result resolver — extracted from the orchestrator (issue #1526 seam 11).\n *\n * Owns the subsystem that resolves a QMD search-result path back to the\n * concrete `MemoryFile` (and its owning namespace/storage). Three concerns\n * live here:\n *\n * - `readQmdResultMemory` — resolve a result path to a `MemoryFile`,\n * handling cold-tier collections, namespace-prefixed collections, and\n * absolute vs relative paths.\n * - `resolveColdQmdResultForRecall` — wrap a result with its owner\n * namespace so the recall pipeline can scope-filter candidates.\n * - `storageForAbsoluteQmdResultPath` — find the `StorageManager` whose\n * directory tree contains an absolute result path.\n *\n * Behavior-preserving move from orchestrator.ts — no logic changes. The\n * orchestrator constructs one instance and keeps thin delegating methods so\n * existing call sites (recallInternal, applyColdFallbackPipeline,\n * loadSearchResultMemoryMap, suggestLinksForMemory, and the\n * RecallRerankCoordinator callback) continue to work.\n *\n * Config, the storage router, and the orchestrator's namespace-resolution\n * helpers are accessed through getter callbacks (not captured at\n * construction) so that post-construction reassignment of the\n * orchestrator's live fields is honored. This mirrors the\n * RecallRerankCoordinator / ConversationIndexCoordinator accessor pattern.\n */\n\nimport path from \"node:path\";\nimport { resolveNamespaceCapabilities } from \"../capabilities.js\";\nimport type { StorageManager } from \"../index.js\";\nimport { log } from \"../logger.js\";\nimport { namespaceIdentityFromToken } from \"../namespaces/identity.js\";\nimport { normalizeQmdResultPath } from \"../namespaces/search.js\";\nimport { SecureStoreLockedError } from \"../secure-store/index.js\";\nimport { isPathInsideStorageRoot } from \"../storage-paths.js\";\nimport { isSupportPassportPrivateMemory } from \"../support-passport/card-projection.js\";\nimport type { MemoryFile, PluginConfig, QmdSearchResult } from \"../types.js\";\nimport { ALL_CATEGORY_DIRS } from \"../utils/category-dir.js\";\n\nconst INTERNAL_QMD_ROOTS = new Set([\n ...ALL_CATEGORY_DIRS,\n \"activity\",\n \"archive\",\n \"artifacts\",\n \"cold\",\n \"config\",\n \"entities\",\n \"identity\",\n \"locations\",\n \"meetings\",\n \"namespaces\",\n \"state\",\n \"summaries\",\n \"transcripts\",\n \"wearables\",\n \"work\",\n \"workspace\",\n]);\n\nconst PRIVATE_RESULT_RESOLUTION_CONCURRENCY = 16;\n\n/**\n * Split a relative QMD result path into its collection prefix and the\n * remainder. Returns `null` for absolute paths, date-only prefixes, or\n * paths with no collection separator.\n */\nexport function qmdCollectionPathParts(resultPath: string): {\n collection: string;\n relativePath: string;\n} | null {\n if (!resultPath || path.isAbsolute(resultPath)) return null;\n if (resultPath.trim().startsWith(\"qmd://\")) {\n try {\n const parsed = new URL(resultPath.trim());\n if (parsed.protocol !== \"qmd:\" || !parsed.hostname) return null;\n const collection = parsed.hostname;\n const relativePath = normalizeQmdResultPath(resultPath, collection).replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\n if (!relativePath) return null;\n return { collection, relativePath };\n } catch {\n return null;\n }\n }\n const normalized = resultPath.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\n const slashIndex = normalized.indexOf(\"/\");\n if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;\n const collection = normalized.slice(0, slashIndex);\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(collection)) return null;\n return {\n collection,\n relativePath: normalized.slice(slashIndex + 1),\n };\n}\n\n/**\n * Build the set of on-disk candidate paths to probe for a QMD result,\n * constrained to the storage root so a result path can never escape the\n * namespace directory.\n */\nexport function qmdResultPathCandidates(storageDir: string, resultPath: string): string[] {\n const candidates = new Set<string>();\n const storageRoot = path.resolve(storageDir);\n const addCandidate = (candidate: string) => {\n const resolved = path.resolve(candidate);\n if (isPathInsideStorageRoot(storageRoot, resolved)) {\n candidates.add(resolved);\n }\n };\n const addRelativeCandidates = (relativePath: string) => {\n const normalized = relativePath.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\n if (!normalized) return;\n addCandidate(path.join(storageRoot, normalized));\n if (/^\\d{4}-\\d{2}-\\d{2}\\//.test(normalized)) {\n addCandidate(path.join(storageRoot, \"facts\", normalized));\n }\n };\n\n if (path.isAbsolute(resultPath)) {\n addCandidate(resultPath);\n // Daemon-mode results can arrive pre-absolutized against the storage\n // root while the file lives under facts/<date>/ (hot-facts collection\n // registered at the facts/ subtree — issue #2111). Mirror the relative\n // branch's facts/ fallback; addCandidate re-checks containment.\n const relative = path.relative(storageRoot, path.resolve(resultPath));\n if (relative && !relative.startsWith(\"..\") && !path.isAbsolute(relative)) {\n const normalized = relative.split(path.sep).join(\"/\");\n if (/^\\d{4}-\\d{2}-\\d{2}\\//.test(normalized)) {\n addCandidate(path.join(storageRoot, \"facts\", normalized));\n }\n }\n } else {\n addRelativeCandidates(resultPath);\n }\n\n return [...candidates];\n}\n\n/**\n * Extract a non-empty `dir` from a storage, returning `null` when the\n * property is absent or not a non-empty string at runtime. Proxy-backed\n * fake storages used in recall paths may not provide a real `dir`, so\n * every caller must handle the null case (skip or fall back to a direct\n * `readMemoryByPath`).\n */\nfunction storageDirOrNull(storage: StorageManager): string | null {\n const dir = storage.dir;\n return typeof dir === \"string\" && dir.length > 0 ? dir : null;\n}\n\n/**\n * Coordinator for resolving QMD search-result paths to concrete memory\n * files and their owning namespace/storage.\n */\nexport class QmdResultResolver {\n private readonly getConfig: () => PluginConfig;\n private readonly storageFor: (namespace: string) => Promise<StorageManager>;\n private readonly storageDirNamespace: (storageDir: string) => string;\n private readonly qmdCollectionNamespaceFromPrefix: (collectionPrefix: string) => string | null;\n private readonly namespaceFromPath: (p: string) => string;\n\n constructor(options: {\n getConfig: () => PluginConfig;\n storageFor: (namespace: string) => Promise<StorageManager>;\n storageDirNamespace: (storageDir: string) => string;\n qmdCollectionNamespaceFromPrefix: (collectionPrefix: string) => string | null;\n namespaceFromPath: (p: string) => string;\n }) {\n this.getConfig = options.getConfig;\n this.storageFor = options.storageFor;\n this.storageDirNamespace = options.storageDirNamespace;\n this.qmdCollectionNamespaceFromPrefix = options.qmdCollectionNamespaceFromPrefix;\n this.namespaceFromPath = options.namespaceFromPath;\n }\n\n async readQmdResultMemory(\n resultPath: string,\n fallbackStorage: StorageManager,\n recallNamespaces: readonly string[] = [],\n preferredNamespace?: string\n ): Promise<MemoryFile | null> {\n const parts = qmdCollectionPathParts(resultPath);\n const fallbackStorageDir = storageDirOrNull(fallbackStorage);\n const config = this.getConfig();\n const coldCollection = config.qmdColdCollection ?? \"openclaw-engram-cold\";\n const fallbackResultPath =\n resultPath.trim().startsWith(\"qmd://\") && parts?.collection === config.qmdCollection\n ? parts.relativePath\n : resultPath;\n if (parts && parts.collection === coldCollection) {\n const storages: StorageManager[] = [];\n const seenStorageDirs = new Set<string>();\n const addStorage = (storage: StorageManager): void => {\n const storageDir = storageDirOrNull(storage);\n const storageKey = storageDir ? path.resolve(storageDir) : `storage-without-dir-${storages.length}`;\n if (seenStorageDirs.has(storageKey)) return;\n seenStorageDirs.add(storageKey);\n storages.push(storage);\n };\n\n const fallbackNamespace =\n fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : config.defaultNamespace;\n if (\n recallNamespaces.length === 0 ||\n !resolveNamespaceCapabilities(config).namespaces ||\n recallNamespaces.includes(fallbackNamespace)\n ) {\n addStorage(fallbackStorage);\n }\n\n if (recallNamespaces.length > 0) {\n for (const namespace of recallNamespaces) {\n try {\n addStorage(await this.storageFor(namespace));\n } catch (err) {\n log.debug(\"qmd cold result namespace storage lookup skipped\", {\n path: resultPath,\n namespace,\n error: (err as Error).message,\n });\n }\n }\n }\n\n for (const storage of storages) {\n const storageDir = storageDirOrNull(storage);\n if (!storageDir) {\n const memory = await storage.readMemoryByPath(resultPath);\n if (memory) return memory;\n continue;\n }\n try {\n const coldRoot = path.join(storageDir, \"cold\");\n for (const candidate of qmdResultPathCandidates(coldRoot, parts.relativePath)) {\n const memory = await storage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n log.debug(\"qmd cold result path lookup failed open\", {\n path: resultPath,\n collection: coldCollection,\n error: (err as Error).message,\n });\n }\n }\n return null;\n }\n const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;\n\n if (parts && collectionNamespace) {\n try {\n const collectionStorage = await this.storageFor(collectionNamespace);\n for (const candidate of qmdResultPathCandidates(collectionStorage.dir, parts.relativePath)) {\n const memory = await collectionStorage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n return null;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n log.debug(\"qmd result namespace path lookup failed open\", {\n path: resultPath,\n namespace: collectionNamespace,\n error: (err as Error).message,\n });\n return null;\n }\n }\n\n if (preferredNamespace) {\n try {\n const preferredStorage = await this.storageFor(preferredNamespace);\n for (const candidate of qmdResultPathCandidates(preferredStorage.dir, fallbackResultPath)) {\n const memory = await preferredStorage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n log.debug(\"qmd preferred namespace path lookup failed open\", {\n path: resultPath,\n namespace: preferredNamespace,\n error: (err as Error).message,\n });\n }\n // The caller supplied an explicit owning namespace. For a relative path\n // the preferred store was the only correct lead, so a miss means the hit\n // is stale/deleted — do NOT fall through to the default store and validate\n // a same-relative-path memory from the wrong namespace (#2020). Absolute\n // paths still fall through: the absolute branch resolves the true owner.\n if (!path.isAbsolute(fallbackResultPath)) return null;\n }\n if (path.isAbsolute(fallbackResultPath)) {\n if (!fallbackStorageDir) {\n return await fallbackStorage.readMemoryByPath(fallbackResultPath);\n }\n const ownerStorage = await this.storageForAbsoluteQmdResultPath(\n fallbackResultPath,\n fallbackStorage,\n recallNamespaces\n );\n if (!ownerStorage) return null;\n for (const candidate of qmdResultPathCandidates(ownerStorage.dir, fallbackResultPath)) {\n const memory = await ownerStorage.storage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n return null;\n }\n\n if (!fallbackStorageDir) {\n return await fallbackStorage.readMemoryByPath(fallbackResultPath);\n }\n for (const candidate of qmdResultPathCandidates(fallbackStorageDir, fallbackResultPath)) {\n const memory = await fallbackStorage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n return null;\n }\n\n async filterPrivateSearchResults(\n results: QmdSearchResult[],\n fallbackStorage: StorageManager,\n namespaces: readonly string[] = [],\n preserveUnresolved = false,\n visibilityCache = new Map<string, boolean>()\n ): Promise<QmdSearchResult[]> {\n const namespaceKey = namespaces.join(\"\\0\");\n const entries = results\n .filter((result) => Boolean(result.path))\n .map((result) => ({\n result,\n cacheKey: `${namespaceKey}\\0${preserveUnresolved ? \"1\" : \"0\"}\\0${result.namespace ?? \"\"}\\0${result.path}`,\n }));\n const pending = new Map<string, QmdSearchResult>();\n for (const { result, cacheKey } of entries) {\n if (!visibilityCache.has(cacheKey)) pending.set(cacheKey, result);\n }\n const unresolved = [...pending];\n for (let offset = 0; offset < unresolved.length; offset += PRIVATE_RESULT_RESOLUTION_CONCURRENCY) {\n await Promise.all(\n unresolved.slice(offset, offset + PRIVATE_RESULT_RESOLUTION_CONCURRENCY).map(async ([cacheKey, result]) => {\n visibilityCache.set(\n cacheKey,\n await this.isVisibleSearchResult(result, fallbackStorage, namespaces, preserveUnresolved)\n );\n })\n );\n }\n return entries.filter(({ cacheKey }) => visibilityCache.get(cacheKey) === true).map(({ result }) => result);\n }\n\n private async isVisibleSearchResult(\n result: QmdSearchResult,\n fallbackStorage: StorageManager,\n namespaces: readonly string[],\n preserveUnresolved: boolean\n ): Promise<boolean> {\n const parts = qmdCollectionPathParts(result.path);\n const config = this.getConfig();\n const collectionIsKnownInternal = parts !== null && INTERNAL_QMD_ROOTS.has(parts.collection);\n const collectionIsConfigured =\n parts !== null &&\n (parts.collection === config.qmdCollection ||\n parts.collection === (config.qmdColdCollection ?? \"openclaw-engram-cold\") ||\n this.qmdCollectionNamespaceFromPrefix(parts.collection) !== null);\n let memory = await this.readQmdResultMemory(result.path, fallbackStorage, namespaces, result.namespace);\n if (!memory && parts && !collectionIsKnownInternal && !collectionIsConfigured) {\n memory = await this.readQmdResultMemory(parts.relativePath, fallbackStorage, namespaces, result.namespace);\n }\n const absoluteInsideMemoryRoot =\n path.isAbsolute(result.path) &&\n isPathInsideStorageRoot(path.resolve(config.memoryDir), path.resolve(result.path));\n const hasExplicitQmdCollection = result.path.trim().startsWith(\"qmd://\");\n const unresolvedInternalPath =\n !memory &&\n (absoluteInsideMemoryRoot ||\n (collectionIsKnownInternal && (!preserveUnresolved || hasExplicitQmdCollection)) ||\n (hasExplicitQmdCollection && collectionIsConfigured));\n const unresolvedExternalCollection =\n !memory &&\n ((parts !== null && !collectionIsKnownInternal && !collectionIsConfigured) ||\n (path.isAbsolute(result.path) &&\n !isPathInsideStorageRoot(path.resolve(config.memoryDir), path.resolve(result.path))));\n return (\n (memory !== null && !isSupportPassportPrivateMemory(memory)) ||\n (!memory && !unresolvedInternalPath && (preserveUnresolved || unresolvedExternalCollection))\n );\n }\n\n async resolveColdQmdResultForRecall(\n result: QmdSearchResult,\n fallbackStorage: StorageManager,\n recallNamespaces: readonly string[] = []\n ): Promise<{ namespace: string; result: QmdSearchResult } | null> {\n const memory = await this.readQmdResultMemory(result.path, fallbackStorage, recallNamespaces, result.namespace);\n if (!memory) return null;\n\n let ownerNamespace: string | null = null;\n if (path.isAbsolute(memory.path)) {\n const ownerStorage = await this.storageForAbsoluteQmdResultPath(memory.path, fallbackStorage, recallNamespaces);\n ownerNamespace = ownerStorage?.namespace ?? null;\n if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;\n }\n ownerNamespace ??= this.namespaceFromPath(memory.path);\n if (recallNamespaces.length > 0 && !recallNamespaces.includes(ownerNamespace)) {\n return null;\n }\n\n return {\n namespace: ownerNamespace,\n result: {\n ...result,\n docid: result.docid || memory.frontmatter.id,\n path: memory.path,\n snippet: result.snippet || memory.content.slice(0, 400),\n origin: memory.frontmatter.origin,\n },\n };\n }\n\n async storageForAbsoluteQmdResultPath(\n resultPath: string,\n fallbackStorage: StorageManager,\n recallNamespaces: readonly string[] = []\n ): Promise<{ storage: StorageManager; dir: string; namespace: string } | null> {\n const resolvedPath = path.resolve(resultPath);\n const config = this.getConfig();\n const memoryRoot = path.resolve(config.memoryDir);\n const namespacesRoot = path.join(memoryRoot, \"namespaces\");\n const fallbackStorageDir = storageDirOrNull(fallbackStorage);\n const matches: Array<{ storage: StorageManager; dir: string; namespace: string }> = [];\n const seenDirs = new Set<string>();\n\n const maybeAddStorage = (storage: StorageManager, namespace: string) => {\n const storageDir = storageDirOrNull(storage);\n if (!storageDir) return;\n const candidateRoot = path.resolve(storageDir);\n if (seenDirs.has(candidateRoot)) return;\n if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;\n if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {\n return;\n }\n seenDirs.add(candidateRoot);\n matches.push({ storage, dir: candidateRoot, namespace });\n };\n\n const fallbackNamespace =\n fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : config.defaultNamespace;\n maybeAddStorage(fallbackStorage, fallbackNamespace);\n\n const candidateNamespaces = new Set<string>();\n candidateNamespaces.add(config.defaultNamespace);\n candidateNamespaces.add(config.sharedNamespace);\n for (const ns of recallNamespaces) {\n candidateNamespaces.add(ns);\n }\n if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {\n const relativeToNamespaces = path.relative(namespacesRoot, resolvedPath);\n const [namespaceSegment] = relativeToNamespaces.split(/[\\\\/]/);\n if (namespaceSegment) {\n candidateNamespaces.add(namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment);\n }\n }\n for (const policy of config.namespacePolicies ?? []) {\n candidateNamespaces.add(policy.name);\n }\n\n for (const ns of candidateNamespaces) {\n if (!ns) continue;\n try {\n maybeAddStorage(await this.storageFor(ns), ns);\n } catch {}\n }\n\n matches.sort((a, b) => b.dir.length - a.dir.length);\n return matches[0] ?? null;\n }\n}\n","/**\n * Wearable cross-source fusion — deterministic conversation clustering.\n *\n * Conversations from multiple sources recording the same real-world event\n * overlap or sit within a proximity gap. This module groups them into\n * clusters that are fully deterministic: the only inputs are start/end\n * times, source ids, and conversation ids (no randomness, no LLM).\n *\n * Cross-source time proximity BRIDGES the same real-world conversation\n * recorded by DIFFERENT sources. A single source's own distinct\n * conversations are never merged by time proximity alone — that would\n * collapse the source's conversation boundaries. Two same-source\n * conversations may end up in one cluster only when a different-source\n * conversation within the gap corroborates that they are part of the same\n * real-world event (a cross-source chain/bridge).\n */\n\nimport type { FusionConversationInput } from \"./types.js\";\n\n/** Default max gap (ms) between two conversations to merge into one cluster. */\nexport const DEFAULT_PROXIMITY_GAP_MS = 5 * 60_000;\n\ninterface Interval {\n start: number;\n end: number;\n}\n\n/** The latest extent of a set of segments as an epoch-ms value + its ISO.\n * Each segment contributes its OWN extent — its `endIso` when known,\n * otherwise its `startIso` — and the result is the maximum. Reconstructed\n * `--:--` transcripts rebuild segments with only a start, so this reaches\n * the last segment start; segment ISOs are already cross-midnight-rolled by\n * the reconstruct layer, so the derived end is consistent with the segment\n * timeline. Returns undefined when no segment carries a parseable extent.\n *\n * This is the SINGLE shared primitive behind every end/interval derivation\n * in the fusion pipeline (cluster interval, fused conversation end): when a\n * conversation-level end is missing, the window falls back to the latest\n * segment extent instead of collapsing to a zero-length point at the start.\n */\nexport interface SegmentExtent {\n /** Epoch ms of the latest extent. */\n ms: number;\n /** ISO string that produced `ms` (a segment endIso, else its startIso). */\n iso: string;\n}\n\nexport function maxSegmentExtent(\n segments: readonly { endIso?: string; startIso?: string }[],\n): SegmentExtent | undefined {\n let best: SegmentExtent | undefined;\n for (const seg of segments) {\n const iso = seg.endIso ?? seg.startIso;\n if (iso === undefined) continue;\n const ms = Date.parse(iso);\n if (!Number.isFinite(ms)) continue;\n if (best === undefined || ms > best.ms) {\n best = { ms, iso };\n }\n }\n return best;\n}\n\n/**\n * Resolve a conversation's effective [start, end] window in epoch ms.\n *\n * When the conversation carries no explicit end (`endIso` undefined — the\n * reconstructed form of a stored transcript whose heading end renders as\n * `--:--`), the window is derived from the segments so it spans the actual\n * utterances instead of collapsing to a zero-length point at the start:\n *\n * 1. conversation `endIso`, when known;\n * 2. the latest segment END (`segment.endIso`);\n * 3. the latest segment START (`segment.startIso`) — reconstructed\n * transcripts rebuild segments with only a start, so the window must\n * reach the last segment start;\n * 4. the conversation start itself (no segments at all).\n *\n * Each segment contributes its own extent (end when known, otherwise its\n * start); the window end is the maximum extent. Segment ISOs are already\n * rolled for cross-midnight by the reconstruct layer, so the derived end is\n * consistent with the segment timeline. The end is clamped to `>= start` so\n * the window is always valid regardless of input anomalies.\n */\nfunction effectiveInterval(conversation: FusionConversationInput): Interval {\n const start = Date.parse(conversation.startIso);\n const endRaw =\n conversation.endIso !== undefined ? Date.parse(conversation.endIso) : NaN;\n // No conversation-level end (\"--:--\"): derive the window from the latest\n // SEGMENT extent via the shared primitive, so every end/interval derivation\n // in the pipeline uses ONE coherent implementation. Falling back only to\n // `start` would produce a zero/negative-length window that drops or\n // mis-clusters the conversation (issue #1810).\n const end = Number.isFinite(endRaw)\n ? (endRaw as number)\n : (maxSegmentExtent(conversation.segments)?.ms ?? start);\n // Clamp universally so the window is always non-negative. An explicit\n // conversation end that precedes the start (malformed/cross-day input)\n // would otherwise yield a negative-length window that shrinks the merge\n // horizon and can split a within-gap cluster.\n return { start, end: Math.max(end, start) };\n}\n\nfunction compareConversation(\n a: FusionConversationInput,\n b: FusionConversationInput,\n): number {\n if (a.source !== b.source) return a.source < b.source ? -1 : 1;\n if (a.conversationId !== b.conversationId) {\n return a.conversationId < b.conversationId ? -1 : 1;\n }\n return 0;\n}\n\n/**\n * Cluster conversations across sources for one day. Returns clusters in\n * chronological order; each cluster is sorted by (start, source, id).\n * Conversations whose start time is unparseable are emitted as\n * single-element clusters at the tail (sorted by source then id) so no\n * data is lost.\n *\n * ## Cross-source bridging rule (issue #1849)\n *\n * Time proximity is meant to bridge the SAME real-world conversation\n * recorded by DIFFERENT sources — not to merge one source's own distinct\n * conversations. Two conversations from the SAME source are therefore\n * never directly joined by time proximity alone; they may end up in the\n * same cluster only through a cross-source chain where a different-source\n * conversation within the gap corroborates the bridge. This preserves the\n * source's own conversation boundaries when no other source corroborates\n * a merge.\n *\n * Concretely, a union-find pass links every pair of conversations that\n * (a) come from DIFFERENT sources and (b) sit within the proximity gap\n * (the later start ≤ the earlier end + gap). The transitive closure then\n * groups same-source conversations that are bridged by at least one\n * intervening different-source conversation. A single source with two\n * near-back-to-back conversations and no other source recording the same\n * window stays in two separate clusters.\n */\nexport function clusterConversations(\n inputs: readonly FusionConversationInput[],\n proximityGapMs: number = DEFAULT_PROXIMITY_GAP_MS,\n): FusionConversationInput[][] {\n const finite: Array<{ conv: FusionConversationInput; interval: Interval }> = [];\n const noStart: FusionConversationInput[] = [];\n for (const conv of inputs) {\n const interval = effectiveInterval(conv);\n if (Number.isFinite(interval.start)) {\n finite.push({ conv, interval });\n } else {\n noStart.push(conv);\n }\n }\n\n // Deterministic processing + output ordering: (start, source, id).\n finite.sort((a, b) => {\n if (a.interval.start !== b.interval.start) {\n return a.interval.start - b.interval.start;\n }\n return compareConversation(a.conv, b.conv);\n });\n\n const n = finite.length;\n\n // Union-find so that same-source pairs are never directly joined by time\n // proximity alone; they may share a cluster only through a cross-source\n // bridge (transitive closure over different-source proximity edges).\n const parent = new Array<number>(n);\n for (let i = 0; i < n; i++) parent[i] = i;\n\n const find = (x: number): number => {\n let root = x;\n while (parent[root] !== root) root = parent[root];\n // Path compression.\n let cur = x;\n while (parent[cur] !== root) {\n const next = parent[cur]!;\n parent[cur] = root;\n cur = next;\n }\n return root;\n };\n\n const union = (a: number, b: number): void => {\n const ra = find(a);\n const rb = find(b);\n if (ra !== rb) parent[ra] = rb;\n };\n\n // Link every cross-source pair within the proximity gap. `finite` is\n // sorted by start, so once j's start exceeds i's end + gap, every later\n // j is also out of reach — break early.\n for (let i = 0; i < n; i++) {\n const endGap = finite[i]!.interval.end + proximityGapMs;\n for (let j = i + 1; j < n; j++) {\n if (finite[j]!.interval.start > endGap) break;\n // Only DIFFERENT sources may be directly joined by proximity.\n if (finite[i]!.conv.source === finite[j]!.conv.source) continue;\n union(i, j);\n }\n }\n\n // Group conversations by union-find root. Because `finite` is sorted and\n // we iterate in index order, each group's conversations stay in (start,\n // source, id) order, and groups are discovered in chronological order\n // (the first root seen belongs to the earliest-starting conversation).\n const clusters: FusionConversationInput[][] = [];\n const rootToCluster = new Map<number, number>();\n for (let i = 0; i < n; i++) {\n const root = find(i);\n let idx = rootToCluster.get(root);\n if (idx === undefined) {\n idx = clusters.length;\n rootToCluster.set(root, idx);\n clusters.push([]);\n }\n clusters[idx]!.push(finite[i]!.conv);\n }\n\n // Conversations with no parseable start can't be ordered in time, so\n // each becomes its own cluster, appended after the time-ordered ones.\n // Sort for determinism (source, id).\n noStart.sort(compareConversation);\n for (const conv of noStart) {\n clusters.push([conv]);\n }\n\n return clusters;\n}\n","/**\n * Wearable cross-source fusion — deterministic reconciliation.\n *\n * Given one cluster (conversations from N sources that overlapped in\n * time), produce a single reconciled timeline where each utterance\n * carries the best source's text plus per-segment provenance, and\n * conflicts that could not be settled deterministically are recorded as\n * disagreements.\n *\n * Reconciliation rules (all deterministic, no LLM):\n * - text: prefer higher source trust, then the more-complete (longer)\n * transcript over a truncated one; otherwise a stable tie-break.\n * - disagreement: when two sources offer genuinely different text for\n * the same window/speaker (neither contains the other), record every\n * candidate and keep a provisional winner marked uncertain — we never\n * silently pick.\n * - speaker: resolved labels unify the wearer across sources; generic\n * labels that cannot be cross-matched keep a lowered confidence.\n *\n * Full segment-level alignment beyond time windows is a deferred\n * follow-up (see PR body). This pass aligns by (speaker, time window).\n */\n\nimport { resolveSpeaker, type SpeakerRegistry } from \"../speakers.js\";\nimport { maxSegmentExtent } from \"./cluster.js\";\nimport type { WearableConversation } from \"../types.js\";\nimport type {\n FusionConversationInput,\n FusionOptions,\n FusionSegmentInput,\n FusedDisagreement,\n FusedSegment,\n FusedSpeaker,\n SegmentPickReason,\n} from \"./types.js\";\n\n/** Default max drift (ms) for two segments to align across sources. */\nexport const DEFAULT_WINDOW_TOLERANCE_MS = 30_000;\n/** Default trust weight for a source with no configured prior. */\nexport const DEFAULT_SOURCE_TRUST = 0.8;\n/** Trust prior at which a source is considered \"more trusted\" than another. */\nconst TRUST_DECISION_EPSILON = 1e-9;\n/** Labels that cannot be confidently cross-matched between sources.\n * Raw provider diarization keys (e.g. Omi `SPEAKER_00`) are generic too:\n * they carry no cross-source identity, so they get the same lowered\n * confidence as bare \"Speaker N\". */\nconst GENERIC_LABEL_PATTERN = /^(Speaker \\d+|Unknown speaker|SPEAKER_\\d+)$/i;\n\nexport interface FuseClusterResult {\n sources: string[];\n speakers: FusedSpeaker[];\n title?: string;\n summary?: string;\n startIso: string;\n endIso?: string;\n segments: FusedSegment[];\n disagreements: FusedDisagreement[];\n}\n\ninterface TaggedSegment {\n source: string;\n conversationId: string;\n speakerLabel: string;\n isSelf: boolean;\n text: string;\n startMs: number;\n startIso?: string;\n endIso?: string;\n sourceTrust: number;\n /** Original position in the flattened input (sources in first-appearance\n * order, then segment order within each source). Carried through\n * alignment so equal-time segments keep their transcript sequence. */\n originalIndex: number;\n}\n\ninterface AlignGroup {\n /** Match key: \"self\" for the wearer, else the resolved label. */\n key: string;\n speakerLabel: string;\n isSelf: boolean;\n members: TaggedSegment[];\n anchorMs: number;\n /** The anchor member's ORIGINAL start ISO — the canonical utterance\n * time the fused segment is emitted at (groups are sorted by anchorMs,\n * so the emitted startIso must come from here, not from the chosen\n * higher-trust source's later clock, or pre-sorted chronology breaks).\n * Undefined for untimestamped (missing-start) groups. */\n anchorStartIso?: string;\n /** The anchor member's ORIGINAL end ISO, when known. */\n anchorEndIso?: string;\n /** Earliest original sequence index among members — the secondary sort\n * key so equal-anchorMs groups keep transcript/source order. */\n originalIndex: number;\n}\n\n/** Match key that unifies the wearer across sources. */\nfunction speakerKey(label: string, isSelf: boolean): string {\n return isSelf ? \"self\" : label;\n}\n\nfunction resolveTrust(\n source: string,\n trustMap: Record<string, number> | undefined,\n): number {\n const value = trustMap?.[source];\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return Math.min(1, Math.max(0, value));\n }\n return DEFAULT_SOURCE_TRUST;\n}\n\n/** Lowercased, punctuation-stripped word sequence — order-sensitive. */\nfunction normalizeWords(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, \" \")\n .split(/\\s+/)\n .filter((word) => word.length > 0);\n}\n\nfunction wordsEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/** True when `short` is an exact leading prefix of `long` (truncation). */\nfunction isWordPrefix(short: string[], long: string[]): boolean {\n if (short.length === 0 || short.length > long.length) return false;\n for (let i = 0; i < short.length; i++) {\n if (short[i] !== long[i]) return false;\n }\n return true;\n}\n\n/** Whether two normalized word sequences corroborate the SAME utterance.\n * Exact match always corroborates; a leading-word-prefix (truncation)\n * corroborates only when `allowPrefix` is set (timestamped alignment),\n * so the more-complete-wins override can reunite a clipped transcript\n * with its full wording. Untimed alignment passes `allowPrefix = false`\n * and demands an exact word match. */\nfunction wordsCorroborate(\n a: string[],\n b: string[],\n allowPrefix: boolean,\n): boolean {\n if (wordsEqual(a, b)) return true;\n if (!allowPrefix) return false;\n return isWordPrefix(a, b) || isWordPrefix(b, a);\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.min(1, Math.max(0, value));\n}\n\n/**\n * Build fusion inputs from raw provider conversations + the shared\n * speaker registry. This is the precise connector path: full ISO\n * timestamps and resolved speaker labels. (The on-demand service path\n * instead reconstructs inputs from stored transcripts — see\n * `reconstruct.ts`.)\n */\nexport function fusionInputsFromConversations(\n sourceId: string,\n conversations: readonly WearableConversation[],\n registry: SpeakerRegistry,\n): FusionConversationInput[] {\n return conversations.map((conversation) => {\n const segments: FusionSegmentInput[] = conversation.segments.map((raw) => {\n const resolved = resolveSpeaker(sourceId, raw, registry);\n return {\n speaker: resolved.label,\n isSelf: resolved.isSelf,\n text: raw.text,\n ...(raw.startIso !== undefined ? { startIso: raw.startIso } : {}),\n ...(raw.endIso !== undefined ? { endIso: raw.endIso } : {}),\n };\n });\n return {\n source: sourceId,\n conversationId: conversation.id,\n startIso: conversation.startIso,\n ...(conversation.endIso !== undefined ? { endIso: conversation.endIso } : {}),\n ...(conversation.title !== undefined ? { title: conversation.title } : {}),\n ...(conversation.summary !== undefined ? { summary: conversation.summary } : {}),\n segments,\n };\n });\n}\n\n/**\n * Fuse one cluster into a reconciled conversation (without id/date).\n */\nexport function fuseCluster(\n cluster: readonly FusionConversationInput[],\n options: FusionOptions = {},\n): FuseClusterResult {\n const trustMap = options.sourceTrust;\n const toleranceMs = options.windowToleranceMs ?? DEFAULT_WINDOW_TOLERANCE_MS;\n\n // Sources in first-appearance order.\n const sources: string[] = [];\n const sourcesSeen = new Set<string>();\n for (const conv of cluster) {\n if (!sourcesSeen.has(conv.source)) {\n sourcesSeen.add(conv.source);\n sources.push(conv.source);\n }\n }\n\n // Earliest start / latest end across the cluster. The fused END considers\n // BOTH every conversation's explicit endIso AND every segment's own extent\n // (endIso ?? startIso) across ALL members: a stored transcript whose\n // heading end renders as \"--:--\" rebuilds segments with only a start, so\n // its later segment starts must still extend the fused window — otherwise\n // a source with an explicit SHORT end would clip the fused conversation\n // before the missing-end source's last utterance (issue #1849). Segment\n // extents use the SAME `maxSegmentExtent` primitive as the cluster\n // interval, so there is one coherent end derivation in the pipeline.\n let startMs = Number.POSITIVE_INFINITY;\n let endMs = Number.NEGATIVE_INFINITY;\n let startIso: string | undefined;\n let endIso: string | undefined;\n for (const conv of cluster) {\n const ms = Date.parse(conv.startIso);\n if (Number.isFinite(ms) && ms < startMs) {\n startMs = ms;\n startIso = conv.startIso;\n }\n if (conv.endIso !== undefined) {\n const endM = Date.parse(conv.endIso);\n if (Number.isFinite(endM) && endM > endMs) {\n endMs = endM;\n endIso = conv.endIso;\n }\n }\n }\n // Fall back to / extend with the latest segment extent across ALL members\n // so a missing-end (\"--:--\") source's later segment starts are not lost.\n const segmentExtent = maxSegmentExtent(\n cluster.flatMap((conv) => conv.segments),\n );\n if (segmentExtent !== undefined && segmentExtent.ms > endMs) {\n endMs = segmentExtent.ms;\n endIso = segmentExtent.iso;\n }\n // Clamp the fused window end to >= start so it is always valid, mirroring\n // cluster.ts. A malformed explicit/derived end preceding the cluster start\n // would otherwise yield a negative-length window.\n if (endIso !== undefined && Number.isFinite(startMs) && endMs < startMs) {\n endIso = startIso;\n endMs = startMs;\n }\n if (startIso === undefined) {\n // No parseable start in the cluster — fall back to the first conv's\n // start string so the required field stays present downstream.\n startIso = cluster[0]?.startIso ?? new Date(0).toISOString();\n }\n\n // Title / summary: first non-empty in cluster order.\n let title: string | undefined;\n let summary: string | undefined;\n for (const conv of cluster) {\n if (title === undefined && conv.title !== undefined && conv.title.trim().length > 0) {\n title = conv.title.trim();\n }\n if (\n summary === undefined &&\n conv.summary !== undefined &&\n conv.summary.trim().length > 0\n ) {\n summary = conv.summary.trim();\n }\n if (title !== undefined && summary !== undefined) break;\n }\n\n // Flatten + tag every segment with its source provenance and trust.\n const tagged: TaggedSegment[] = [];\n for (const conv of cluster) {\n const sourceTrust = resolveTrust(conv.source, trustMap);\n for (const segment of conv.segments) {\n const startMsValue =\n segment.startIso !== undefined ? Date.parse(segment.startIso) : NaN;\n tagged.push({\n source: conv.source,\n conversationId: conv.conversationId,\n speakerLabel: segment.speaker,\n isSelf: segment.isSelf,\n text: segment.text,\n startMs: Number.isFinite(startMsValue)\n ? (startMsValue as number)\n : Number.POSITIVE_INFINITY,\n ...(segment.startIso !== undefined ? { startIso: segment.startIso } : {}),\n ...(segment.endIso !== undefined ? { endIso: segment.endIso } : {}),\n sourceTrust,\n originalIndex: tagged.length,\n });\n }\n }\n\n // Deterministic order: time first. Equal-time (and both-missing)\n // segments keep their ORIGINAL transcript/source sequence instead of\n // being scrambled by source or speaker label, so minute-precision and\n // untimestamped utterances are not reordered relative to their input.\n tagged.sort((a, b) => {\n const aFinite = Number.isFinite(a.startMs);\n const bFinite = Number.isFinite(b.startMs);\n if (aFinite && bFinite && a.startMs !== b.startMs) return a.startMs - b.startMs;\n if (aFinite !== bFinite) return aFinite ? -1 : 1;\n return a.originalIndex - b.originalIndex;\n });\n\n // Greedy cross-source alignment: a group holds at most one segment per\n // source (so two sequential same-source utterances never collapse). A\n // segment joins an existing group when their time windows match (or both\n // are untimestamped) AND the text corroborates the SAME utterance.\n // Speaker is matched in two tiers: first an exact same-speaker group;\n // only when none exists does a segment join a group whose utterance\n // corroborates but whose speaker label DISAGREES. That is a speaker\n // conflict on the same utterance — fused into one segment and recorded\n // as a disagreement (see reconcileGroup) rather than emitted as two\n // separate segments. This does NOT collapse distinct utterances: the\n // text must corroborate, so different-worded same-window segments\n // (the r2 separation) still stay apart.\n const groups: AlignGroup[] = [];\n for (const seg of tagged) {\n const key = speakerKey(seg.speakerLabel, seg.isSelf);\n const segMissing = !Number.isFinite(seg.startMs);\n const segWords = normalizeWords(seg.text);\n\n // True when `group` has room for `seg`'s source and corroborates the\n // same utterance (matching time window + corroborating text). Speaker\n // is intentionally NOT tested here — the caller decides whether a\n // same-speaker match or a speaker-conflict match is acceptable.\n const corroborates = (group: AlignGroup): boolean => {\n if (group.members.some((member) => member.source === seg.source)) {\n return false;\n }\n // Missing-start segments only align with other missing-start groups.\n const groupMissing = !Number.isFinite(group.anchorMs);\n if (groupMissing !== segMissing) return false;\n if (!groupMissing && Math.abs(seg.startMs - group.anchorMs) > toleranceMs) {\n return false;\n }\n // Cross-source corroboration gate: distinct utterances that merely\n // share a speaker and a time window (timestamped) — or a speaker key\n // alone (untimed) — must NOT collapse. Timestamped alignment accepts\n // an exact word match OR a leading-word prefix (truncation) so the\n // more-complete-wins override can reunite a clipped transcript with\n // its full wording; untimed alignment has no anchor, so exact only.\n return group.members.some((member) =>\n wordsCorroborate(normalizeWords(member.text), segWords, !groupMissing),\n );\n };\n\n // Choose the CLOSEST corroborating group instead of the first match\n // (issue #1849). Within windowToleranceMs several groups can corroborate\n // the same short utterance — e.g. a speaker repeating \"yes\" at 10:00 and\n // 10:20 with a 30s window — so a later source segment at 10:21\n // corroborates BOTH. First-match would attach it to the earliest (10:00)\n // group even though 10:20 is nearer, misattributing provenance and\n // potentially reordering the fused timeline. Scan every candidate and\n // keep the one whose anchor is nearest to this segment by\n // |anchorMs - startMs|; ties break on the smaller anchor, then on the\n // order the group was created (stable, never dependent on key order).\n // Single-occurrence behavior is unchanged: the lone corroborating group\n // is trivially the closest.\n const closestCorroborating = (\n wantSameSpeaker: boolean,\n ): AlignGroup | undefined => {\n let best: AlignGroup | undefined;\n let bestDelta = Infinity;\n for (const group of groups) {\n if (\n (group.key === key) !== wantSameSpeaker ||\n !corroborates(group)\n ) {\n continue;\n }\n const delta =\n !segMissing && Number.isFinite(group.anchorMs)\n ? Math.abs(seg.startMs - group.anchorMs)\n : 0;\n if (\n best === undefined ||\n delta < bestDelta ||\n (delta === bestDelta && group.anchorMs < best.anchorMs)\n ) {\n best = group;\n bestDelta = delta;\n }\n }\n return best;\n };\n\n // Prefer an exact same-speaker corroborating group.\n let chosen = closestCorroborating(true);\n if (chosen === undefined) {\n // Fall back: same utterance (time+text corroborate) but a different\n // speaker label -> speaker conflict, aligned into one segment.\n chosen = closestCorroborating(false);\n }\n\n if (chosen !== undefined) {\n chosen.members.push(seg);\n if (seg.originalIndex < chosen.originalIndex) {\n chosen.originalIndex = seg.originalIndex;\n }\n } else {\n groups.push({\n key,\n speakerLabel: seg.speakerLabel,\n isSelf: seg.isSelf,\n members: [seg],\n anchorMs: seg.startMs,\n // The creating segment is the EARLIEST member (tagged is\n // time-sorted), so its clock IS the group anchor that groups are\n // sorted by and that the fused segment must be emitted at.\n anchorStartIso: seg.startIso,\n anchorEndIso: seg.endIso,\n originalIndex: seg.originalIndex,\n });\n }\n }\n\n // Output groups in time order; missing-start groups last. Equal-anchorMs\n // (and all-missing) groups tie-break on original transcript/source\n // sequence — not source/speaker label — so equal-time utterances keep\n // the order they appeared in their input transcripts.\n groups.sort((a, b) => {\n const aMissing = !Number.isFinite(a.anchorMs);\n const bMissing = !Number.isFinite(b.anchorMs);\n if (aMissing !== bMissing) return aMissing ? 1 : -1;\n if (!aMissing && a.anchorMs !== b.anchorMs) return a.anchorMs - b.anchorMs;\n return a.originalIndex - b.originalIndex;\n });\n\n const segments: FusedSegment[] = [];\n const disagreements: FusedDisagreement[] = [];\n for (const group of groups) {\n const reconciled = reconcileGroup(group);\n segments.push(reconciled.segment);\n disagreements.push(...reconciled.disagreements);\n }\n // Belt-and-suspenders: segments are built from anchor-sorted groups with\n // each segment's startIso pinned to its group anchor, so the array is\n // already chronological. This explicit, STABLE re-sort guarantees that\n // invariant end to end — no trust-based text/content swap can ever\n // reorder the timeline, even if a future change alters how a fused\n // segment's timestamp is derived. Stability contract:\n // - timestamped segments sort by startMs ascending;\n // - missing/invalid timestamps keep their position (timestamped before\n // missing, preserving original relative order among missing ones);\n // - equal timestamps preserve prior order via a deterministic secondary\n // key (the pre-sort index), never reordering by source/speaker — so\n // cross-source clock skew does not scramble same-anchor utterances.\n const preSortOrder = new Map(segments.map((seg, i) => [seg, i]));\n segments.sort((a, b) => {\n const aMs = a.startIso !== undefined ? Date.parse(a.startIso) : Number.NaN;\n const bMs = b.startIso !== undefined ? Date.parse(b.startIso) : Number.NaN;\n const aFinite = Number.isFinite(aMs);\n const bFinite = Number.isFinite(bMs);\n if (aFinite && bFinite) {\n if (aMs !== bMs) return aMs - bMs;\n } else if (aFinite !== bFinite) {\n return aFinite ? -1 : 1;\n }\n // Equal timestamp (or both missing): preserve prior order — never let\n // a naive ts-only comparator scramble equal/missing-time entries.\n return (preSortOrder.get(a) ?? 0) - (preSortOrder.get(b) ?? 0);\n });\n // Cross-segment ASR disagreements: distinct utterances kept as separate\n // segments (never collapsed) yet sharing a speaker + time window and\n // disagreeing on wording. Neither side's content is lost — both remain\n // visible segments — but the unresolved conflict is still surfaced for\n // review and each involved segment's confidence is lowered, matching\n // how an in-group conflict is flagged.\n detectCrossSegmentDisagreements(segments, toleranceMs, disagreements);\n\n const result: FuseClusterResult = {\n sources,\n speakers: collectSpeakers(tagged),\n startIso,\n segments,\n disagreements,\n };\n if (endIso !== undefined) result.endIso = endIso;\n if (title !== undefined) result.title = title;\n if (summary !== undefined) result.summary = summary;\n return result;\n}\n\ninterface ReconciledGroup {\n segment: FusedSegment;\n disagreements: FusedDisagreement[];\n}\n\nfunction reconcileGroup(group: AlignGroup): ReconciledGroup {\n const members = group.members;\n // Rank: higher trust, then more-complete (longer), then stable source\n // order, finally the original transcript index — a total order so the\n // comparator returns 0 only for an identical item (never nonzero on a\n // tie), keeping the sort stable and contract-compliant.\n const ranked = [...members].sort((a, b) => {\n if (Math.abs(b.sourceTrust - a.sourceTrust) > TRUST_DECISION_EPSILON) {\n return b.sourceTrust - a.sourceTrust;\n }\n if (b.text.length !== a.text.length) return b.text.length - a.text.length;\n if (a.source !== b.source) return a.source < b.source ? -1 : 1;\n if (a.conversationId !== b.conversationId) {\n return a.conversationId < b.conversationId ? -1 : 1;\n }\n return a.originalIndex - b.originalIndex;\n });\n const top = ranked[0];\n const topWords = normalizeWords(top.text);\n\n // Truncation override: the top-ranked (highest-trust) member may be a\n // CLIPPED version of a corroborating candidate — e.g. a summary source\n // clipped at \"The deploy window opens at\" while a verbatim source has\n // the full sentence. Trust dominates the rank, so without this the\n // truncated high-trust text would win despite the documented\n // \"more-complete wins\" rule. When the top's words are a strict prefix of\n // another member's words, adopt the LONGEST such more-complete member's\n // text + provenance.\n let chosen = top;\n if (topWords.length > 0) {\n let bestLen = -1;\n for (const candidate of ranked) {\n if (candidate === top) continue;\n const candidateWords = normalizeWords(candidate.text);\n if (\n isWordPrefix(topWords, candidateWords) &&\n candidateWords.length > topWords.length &&\n candidateWords.length > bestLen\n ) {\n chosen = candidate;\n bestLen = candidateWords.length;\n }\n }\n }\n const truncatedOverride = chosen !== top;\n const others = ranked.filter((member) => member !== chosen);\n\n const chosenWords = normalizeWords(chosen.text);\n\n const reason: SegmentPickReason =\n members.length === 1\n ? \"only-source\"\n : truncatedOverride\n ? \"more-complete\"\n : others.some(\n (r) => chosen.sourceTrust - r.sourceTrust > TRUST_DECISION_EPSILON,\n )\n ? \"higher-trust\"\n : others.some((r) => chosen.text.length - r.text.length > 0)\n ? \"more-complete\"\n : \"tie-break\";\n\n // Conflict detection: a candidate whose word sequence differs from the\n // chosen text AND is not a containment (one a prefix/truncation of the\n // other). Containment is \"more-complete wins\" with no disagreement.\n const disagree: Array<{ source: string; value: string }> = [];\n let conflict = false;\n for (const candidate of others) {\n const candidateWords = normalizeWords(candidate.text);\n if (chosenWords.length === 0 && candidateWords.length === 0) continue;\n if (wordsEqual(chosenWords, candidateWords)) continue;\n if (\n isWordPrefix(candidateWords, chosenWords) ||\n isWordPrefix(chosenWords, candidateWords)\n ) {\n continue;\n }\n conflict = true;\n disagree.push({ source: candidate.source, value: candidate.text });\n }\n\n // Speaker-attribution conflict: members of the same utterance disagree\n // on who spoke (same time window + corroborating text, different label).\n // Detected from member labels — not the group key — so a group that\n // absorbed a conflicting speaker is handled identically. The chosen\n // (top-ranked) member's attribution wins the segment provisionally;\n // every source's label is surfaced as a disagreement with full\n // provenance so no attribution is silently lost.\n const distinctSpeakerKeys = new Set(\n members.map((m) => speakerKey(m.speakerLabel, m.isSelf)),\n );\n const speakerConflict = distinctSpeakerKeys.size > 1;\n\n const alternatives = others.map((candidate) => ({\n source: candidate.source,\n text: candidate.text,\n }));\n\n // Confidence: single source -> its trust; corroboration boosts; a\n // recorded text OR speaker conflict lowers it.\n const confidence =\n conflict || speakerConflict\n ? clamp01(chosen.sourceTrust * 0.7)\n : members.length > 1\n ? clamp01(chosen.sourceTrust + 0.1 * (members.length - 1))\n : clamp01(chosen.sourceTrust);\n\n // TIMELINE POSITION (startIso/endIso) comes from the group/window ANCHOR\n // — the canonical utterance time the groups are sorted by — NOT from the\n // chosen (higher-trust) source's clock. The chosen source may be LATER\n // than the anchor (a low-trust utterance at 10:00 corroborated by a\n // high-trust source at 10:25 within tolerance); emitting chosen.startIso\n // would print the fused segment at 10:25 even though the group sits at\n // the 10:00 anchor, jumping it past an intervening 10:10 utterance and\n // corrupting the chronology. The chosen source still provides the TEXT;\n // only the timeline position is anchored. Its original clock is kept in\n // provenance so the source's recording time stays traceable.\n const segment: FusedSegment = {\n speaker: chosen.speakerLabel,\n isSelf: chosen.isSelf,\n text: chosen.text,\n confidence,\n provenance: {\n source: chosen.source,\n conversationId: chosen.conversationId,\n sourceTrust: chosen.sourceTrust,\n reason,\n alternatives,\n ...(chosen.startIso !== undefined\n ? { sourceStartIso: chosen.startIso }\n : {}),\n ...(chosen.endIso !== undefined ? { sourceEndIso: chosen.endIso } : {}),\n },\n ...(group.anchorStartIso !== undefined\n ? { startIso: group.anchorStartIso }\n : {}),\n ...(group.anchorEndIso !== undefined ? { endIso: group.anchorEndIso } : {}),\n };\n\n const disagreements: FusedDisagreement[] = [];\n // The disagreement subject is the EMITTED timeline position (the group\n // anchor), coherent with segment.startIso — not the chosen source's\n // possibly-later clock.\n const anchorIso =\n group.anchorStartIso ??\n (Number.isFinite(group.anchorMs)\n ? new Date(group.anchorMs).toISOString()\n : undefined);\n if (conflict) {\n disagreements.push({\n kind: \"asr-text\",\n subject: anchorIso ?? \"(no timestamp)\",\n candidates: [{ source: chosen.source, value: chosen.text }, ...disagree],\n provisional: { source: chosen.source, value: chosen.text },\n });\n }\n if (speakerConflict) {\n // One candidate per source (a group holds one member per source),\n // sorted by source for determinism; the chosen source is provisional.\n const speakerCandidates = members\n .map((m) => ({ source: m.source, value: m.speakerLabel }))\n .sort((a, b) =>\n a.source < b.source ? -1 : a.source > b.source ? 1 : 0,\n );\n disagreements.push({\n kind: \"speaker\",\n subject: anchorIso ?? \"(no timestamp)\",\n candidates: speakerCandidates,\n provisional: { source: chosen.source, value: chosen.speakerLabel },\n });\n }\n\n return { segment, disagreements };\n}\n\n/**\n * Detect ASR-text disagreements BETWEEN segments that were intentionally\n * kept separate (distinct utterances) yet share a speaker and a time\n * window and disagree on wording. Unlike an in-group conflict (same\n * utterance bridged by a truncation), these never merged — so neither\n * side's content is lost — but the unresolved disagreement is still\n * surfaced for review and each involved segment's confidence is lowered.\n *\n * Timestamped only: untimestamped segments have no window anchor to compare\n * against. Mutates `confidence` on involved segments and appends to `out`.\n */\nfunction detectCrossSegmentDisagreements(\n segments: FusedSegment[],\n toleranceMs: number,\n out: FusedDisagreement[],\n): void {\n const n = segments.length;\n if (n < 2) return;\n const claimed = new Array<boolean>(n).fill(false);\n for (let i = 0; i < n; i++) {\n if (claimed[i]) continue;\n const seed = segments[i]!;\n const seedMs =\n seed.startIso !== undefined ? Date.parse(seed.startIso) : NaN;\n if (!Number.isFinite(seedMs)) continue;\n const seedWords = normalizeWords(seed.text);\n const clusterIdx: number[] = [];\n for (let j = i + 1; j < n; j++) {\n if (claimed[j]) continue;\n const cand = segments[j]!;\n // Speaker identity is matched via speakerKey() — the SAME\n // normalization grouping uses (line 305) — not the raw display\n // label. The wearer is often labeled differently per source (e.g.\n // \"Me (you)\" vs an override \"Alex (you)\"); both normalize to\n // \"self\". Matching on the raw label would skip them, leaving a real\n // same-window ASR-text disagreement undetected and both confidences\n // wrongly high. (Issue #1849.)\n if (\n speakerKey(cand.speaker, cand.isSelf) !==\n speakerKey(seed.speaker, seed.isSelf)\n ) {\n continue;\n }\n if (cand.provenance.source === seed.provenance.source) continue;\n const candMs =\n cand.startIso !== undefined ? Date.parse(cand.startIso) : NaN;\n if (!Number.isFinite(candMs)) continue;\n if (Math.abs(candMs - seedMs) > toleranceMs) continue;\n if (wordsCorroborate(seedWords, normalizeWords(cand.text), true)) {\n continue;\n }\n clusterIdx.push(j);\n }\n if (clusterIdx.length === 0) continue;\n clusterIdx.unshift(i);\n for (const idx of clusterIdx) claimed[idx] = true;\n\n const involved = clusterIdx.map((idx) => segments[idx]!);\n // Stable secondary key: each involved segment's position in the\n // reconciled segment array (clusterIdx is ascending). Two cands can\n // share a source, so source alone is NOT a total order here; the\n // position tie-break makes the comparator return 0 only for an\n // identical item and keeps the ranking deterministic — mirroring\n // reconcileGroup's originalIndex tie-break.\n const involvedOrder = new Map(involved.map((seg, i) => [seg, i]));\n involved.sort((a, b) => {\n if (\n Math.abs(b.provenance.sourceTrust - a.provenance.sourceTrust) >\n TRUST_DECISION_EPSILON\n ) {\n return b.provenance.sourceTrust - a.provenance.sourceTrust;\n }\n if (b.text.length !== a.text.length) return b.text.length - a.text.length;\n if (a.provenance.source !== b.provenance.source) {\n return a.provenance.source < b.provenance.source ? -1 : 1;\n }\n return involvedOrder.get(a)! - involvedOrder.get(b)!;\n });\n const provisional = involved[0]!;\n const anchorIso = involved\n .map((s) => s.startIso)\n .filter((v): v is string => v !== undefined)\n .sort()[0];\n\n for (const seg of involved) {\n seg.confidence = clamp01(seg.provenance.sourceTrust * 0.7);\n }\n\n out.push({\n kind: \"asr-text\",\n subject: anchorIso ?? \"(no timestamp)\",\n candidates: involved.map((s) => ({\n source: s.provenance.source,\n value: s.text,\n })),\n provisional: {\n source: provisional.provenance.source,\n value: provisional.text,\n },\n });\n }\n}\n\n/**\n * Build the reconciled speaker list. The wearer unifies across all\n * sources; generic labels (bare \"Speaker N\" or a raw key) seen in only\n * one source get a lowered confidence since they could not be\n * confidently matched across sources.\n */\nfunction collectSpeakers(tagged: readonly TaggedSegment[]): FusedSpeaker[] {\n interface Acc {\n label: string;\n isSelf: boolean;\n sources: Set<string>;\n generic: boolean;\n }\n const order: string[] = [];\n const acc = new Map<string, Acc>();\n for (const seg of tagged) {\n const key = speakerKey(seg.speakerLabel, seg.isSelf);\n let entry = acc.get(key);\n if (entry === undefined) {\n entry = {\n label: seg.speakerLabel,\n isSelf: seg.isSelf,\n sources: new Set<string>(),\n generic: GENERIC_LABEL_PATTERN.test(seg.speakerLabel),\n };\n acc.set(key, entry);\n order.push(key);\n }\n entry.sources.add(seg.source);\n }\n return order.map((key) => {\n const entry = acc.get(key);\n if (entry === undefined) throw new Error(\"fusion speaker accumulator miss\");\n const sourceCount = entry.sources.size;\n const confidence = entry.isSelf\n ? sourceCount > 1\n ? 0.95\n : 0.85\n : entry.generic\n ? sourceCount > 1\n ? 0.7\n : 0.5\n : sourceCount > 1\n ? 0.9\n : 0.7;\n return {\n label: entry.label,\n isSelf: entry.isSelf,\n confidence,\n sources: [...entry.sources].sort(),\n };\n });\n}\n","/**\n * Wearable cross-source fusion — day-level orchestrator.\n *\n * Takes every enabled source's normalized conversations for one day,\n * clusters them across sources, reconciles each cluster, and attaches a\n * stable content-hash id so re-running over unchanged inputs produces a\n * byte-identical artifact (idempotent — no duplicate files).\n *\n * Deterministic end to end: no timestamps from \"now\", no LLM, no\n * randomness. The only time-derived value is the `fusedAt` frontmatter\n * field added at storage time (excluded from the content hash).\n */\n\nimport { createHash } from \"node:crypto\";\nimport { clusterConversations } from \"./cluster.js\";\nimport {\n DEFAULT_SOURCE_TRUST,\n DEFAULT_WINDOW_TOLERANCE_MS,\n fuseCluster,\n type FuseClusterResult,\n} from \"./reconcile.js\";\nimport { DEFAULT_PROXIMITY_GAP_MS } from \"./cluster.js\";\nimport type {\n FusionConversationInput,\n FusionDayResult,\n FusionOptions,\n FusedConversationProvenance,\n FusedWearableConversation,\n} from \"./types.js\";\n\nconst FUSION_ID_PREFIX = \"fusion\";\n/**\n * Fusion algorithm/schema version. Folded into the day content hash (the\n * idempotency key) so a change to the clustering, reconciliation, or\n * reconstruction algorithm invalidates cached artifacts even when the raw\n * inputs and fusion config are byte-identical — pre-existing `_fusion/`\n * files are regenerated rather than served stale. Bump this whenever the\n * fusion algorithm meaningfully changes (this PR changed it repeatedly).\n * The per-conversation id (`canonicalInputsKey`) is intentionally NOT\n * folded with the version, so a conversation keeps a stable identity.\n */\nexport const FUSION_ALGO_VERSION = \"2026-07-12-1\";\n\n/**\n * Canonical, stable serialization of a set of fusion inputs — the base\n * for the per-conversation id. Input-only so a conversation keeps a\n * stable identity across re-runs regardless of input order. The day\n * content hash additionally folds the effective fusion config (see\n * `canonicalDayKey`) so a config change invalidates the cached artifact.\n */\nfunction canonicalInputsKey(\n date: string,\n inputs: readonly FusionConversationInput[],\n): string {\n const sorted = [...inputs].sort((a, b) => {\n if (a.source !== b.source) return a.source < b.source ? -1 : 1;\n if (a.conversationId !== b.conversationId) {\n return a.conversationId < b.conversationId ? -1 : 1;\n }\n return 0;\n });\n // Serialize the structured tuples UNAMBIGUOUSLY before hashing. The old\n // `|`/newline-delimited form could collide: a speaker label or segment\n // text containing `|` (or a newline plus a forged `seg|…`/`conv|…`\n // prefix) could make two DISTINCT inputs serialize to identical bytes,\n // hashing alike — so fuseDay wrongly took the idempotent-skip path and\n // kept serving a stale artifact. JSON string quoting makes every field\n // boundary unforgeable, and the positional array order is the\n // deterministic key order (no object keys to sort).\n const record = [\n date,\n sorted.map((conv) => [\n conv.source,\n conv.conversationId,\n conv.startIso,\n conv.endIso ?? \"\",\n conv.title ?? \"\",\n conv.summary ?? \"\",\n conv.segments.map((segment) => [\n segment.speaker,\n segment.isSelf ? \"self\" : \"other\",\n segment.startIso ?? \"\",\n segment.endIso ?? \"\",\n segment.text,\n ]),\n ]),\n ];\n return createHash(\"sha256\").update(JSON.stringify(record), \"utf-8\").digest(\"hex\");\n}\n\n/**\n * Effective-config fingerprint folded into the day content hash so a\n * change to any clustering/reconciliation knob (proximity gap, window\n * tolerance, or per-source trust) invalidates the cached artifact.\n * Defaults are resolved so an explicit default hashes identically to an\n * omission, keeping the skip-unchanged path deterministic. Only sources\n * that actually contribute to the day are included, so a trust change\n * for an absent source cannot spuriously trigger a rebuild.\n */\nfunction configFingerprint(\n options: FusionOptions,\n sources: readonly string[],\n): string {\n const proximityGapMs = options.proximityGapMs ?? DEFAULT_PROXIMITY_GAP_MS;\n const windowToleranceMs =\n options.windowToleranceMs ?? DEFAULT_WINDOW_TOLERANCE_MS;\n const trustMap = options.sourceTrust ?? {};\n // JSON form so a source id (or future field) containing `|` cannot forge\n // a trust-entry boundary and collide two distinct effective configs into\n // one day hash.\n const trustEntries = [...new Set(sources)]\n .sort()\n .map((source) => [source, trustMap[source] ?? DEFAULT_SOURCE_TRUST]);\n return JSON.stringify([proximityGapMs, windowToleranceMs, trustEntries]);\n}\n\n/**\n * Day idempotency key: the input-only hash combined with the effective\n * fusion-config fingerprint AND the fusion algorithm version. Same inputs +\n * same config + same version => same hash (no duplicate rewrite); a config\n * change OR an algorithm-version bump => new hash => rebuild. The version\n * is what forces regeneration when the ALGORITHM itself changes but the\n * inputs and config are byte-identical (issue #1849).\n */\nexport function canonicalDayKey(\n date: string,\n inputs: readonly FusionConversationInput[],\n options: FusionOptions,\n algoVersion: string = FUSION_ALGO_VERSION,\n): string {\n const inputsKey = canonicalInputsKey(date, inputs);\n const fingerprint = configFingerprint(\n options,\n inputs.map((conv) => conv.source),\n );\n return createHash(\"sha256\")\n .update(inputsKey)\n .update(\"\\n\")\n .update(fingerprint)\n .update(\"\\n\")\n .update(algoVersion)\n .digest(\"hex\");\n}\n\nfunction buildProvenance(\n cluster: readonly FusionConversationInput[],\n proximityGapMs: number,\n windowToleranceMs: number,\n): FusedConversationProvenance {\n return {\n contributions: cluster.map((conv) => ({\n source: conv.source,\n conversationId: conv.conversationId,\n startIso: conv.startIso,\n ...(conv.endIso !== undefined ? { endIso: conv.endIso } : {}),\n segmentCount: conv.segments.length,\n })),\n proximityGapMs,\n windowToleranceMs,\n method: \"time-proximity\",\n };\n}\n\n/**\n * Fuse every source's conversations for one day into a stable result.\n * Empty input yields an empty (but well-formed) result so callers can\n * treat \"nothing to fuse\" uniformly.\n */\nexport function fuseDay(\n date: string,\n inputs: readonly FusionConversationInput[],\n options: FusionOptions = {},\n): FusionDayResult {\n const proximityGapMs = options.proximityGapMs ?? DEFAULT_PROXIMITY_GAP_MS;\n const windowToleranceMs =\n options.windowToleranceMs ?? DEFAULT_WINDOW_TOLERANCE_MS;\n\n const clusters = clusterConversations(inputs, proximityGapMs);\n const conversations: FusedWearableConversation[] = clusters.map((cluster) => {\n const fused: FuseClusterResult = fuseCluster(cluster, {\n ...options,\n windowToleranceMs,\n });\n const id = `${FUSION_ID_PREFIX}-${canonicalInputsKey(date, cluster).slice(0, 24)}`;\n const result: FusedWearableConversation = {\n id,\n date,\n startIso: fused.startIso,\n sources: fused.sources,\n speakers: fused.speakers,\n segments: fused.segments,\n disagreements: fused.disagreements,\n provenance: buildProvenance(cluster, proximityGapMs, windowToleranceMs),\n };\n if (fused.endIso !== undefined) result.endIso = fused.endIso;\n if (fused.title !== undefined) result.title = fused.title;\n if (fused.summary !== undefined) result.summary = fused.summary;\n return result;\n });\n\n const sourcesSeen = new Set<string>();\n const sources: string[] = [];\n for (const conv of conversations) {\n for (const source of conv.sources) {\n if (!sourcesSeen.has(source)) {\n sourcesSeen.add(source);\n sources.push(source);\n }\n }\n }\n\n return {\n date,\n conversations,\n sources,\n contentHash: canonicalDayKey(date, inputs, options),\n };\n}\n","/**\n * Wearable cross-source fusion — derived-day file serialization.\n *\n * One derived file per fused day, stored ALONGSIDE raw source transcripts\n * (under the wearables tree) but never overwriting them. Format mirrors\n * the day-transcript convention: YAML frontmatter (`kind:\n * wearable-fusion`) + a JSON body carrying the structured\n * `FusedWearableConversation[]`. The frontmatter `contentHash` is the\n * idempotency key derived from inputs plus the effective fusion config,\n * so an unchanged re-run (same inputs AND config) produces a\n * byte-identical file.\n */\n\nimport { createHash } from \"node:crypto\";\nimport * as path from \"node:path\";\nimport { pathIsInside } from \"../../utils/path-containment.js\";\nimport { isValidTranscriptDate } from \"../day-store.js\";\nimport type {\n FusedDayFile,\n FusedDayMeta,\n FusedWearableConversation,\n} from \"./types.js\";\n\nexport const FUSION_KIND = \"wearable-fusion\" as const;\n\n/** Hash the canonical JSON body for idempotent skip-unchanged checks. */\nexport function hashFusionBody(\n conversations: readonly FusedWearableConversation[],\n): string {\n return createHash(\"sha256\")\n .update(JSON.stringify(conversations), \"utf-8\")\n .digest(\"hex\");\n}\n\nexport function composeFusionDayMeta(\n date: string,\n conversations: readonly FusedWearableConversation[],\n sources: readonly string[],\n contentHash: string,\n fusedAt: string,\n): FusedDayMeta {\n return {\n kind: FUSION_KIND,\n date,\n sourceCount: sources.length,\n conversationCount: conversations.length,\n contentHash,\n bodyHash: hashFusionBody(conversations),\n fusedAt,\n };\n}\n\n/** Serialize meta + conversations into the persisted file format. */\nexport function serializeFusionDay(\n meta: FusedDayMeta,\n conversations: readonly FusedWearableConversation[],\n): string {\n const lines: string[] = [\"---\"];\n lines.push(`kind: ${meta.kind}`);\n lines.push(`date: ${JSON.stringify(meta.date)}`);\n lines.push(`sourceCount: ${meta.sourceCount}`);\n lines.push(`conversationCount: ${meta.conversationCount}`);\n lines.push(`contentHash: ${JSON.stringify(meta.contentHash)}`);\n lines.push(`bodyHash: ${JSON.stringify(meta.bodyHash)}`);\n lines.push(`fusedAt: ${JSON.stringify(meta.fusedAt)}`);\n lines.push(\"---\");\n lines.push(\"\");\n return `${lines.join(\"\\n\")}\\n${JSON.stringify(conversations, null, 2)}\\n`;\n}\n\nfunction parseScalar(value: string): string {\n const trimmed = value.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"') && trimmed.length >= 2) {\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed === \"string\") return parsed;\n } catch {\n // Fall through to the raw value below.\n }\n }\n return trimmed;\n}\n\nfunction parseNonNegativeInt(value: string | undefined): number {\n if (value === undefined) return 0;\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed < 0) return 0;\n return Math.floor(parsed);\n}\n\nconst FUSED_SEGMENT_PICK_REASONS: Record<string, true> = {\n \"only-source\": true,\n \"higher-trust\": true,\n \"more-complete\": true,\n \"tie-break\": true,\n};\n\nconst FUSED_DISAGREEMENT_KINDS: Record<string, true> = {\n \"asr-text\": true,\n speaker: true,\n timestamp: true,\n};\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\n/** Structural guard for a parsed segment-provenance record. */\nfunction isFusedSegmentProvenance(value: unknown): boolean {\n if (!isPlainObject(value)) return false;\n if (typeof value.source !== \"string\") return false;\n if (typeof value.conversationId !== \"string\") return false;\n if (typeof value.sourceTrust !== \"number\") return false;\n if (typeof value.reason !== \"string\") return false;\n if (!(value.reason in FUSED_SEGMENT_PICK_REASONS)) return false;\n return (\n Array.isArray(value.alternatives) &&\n value.alternatives.every(\n (alt) =>\n isPlainObject(alt) && typeof alt.source === \"string\" && typeof alt.text === \"string\",\n )\n );\n}\n\n/** Structural guard for a parsed fused segment. */\nfunction isFusedSegment(value: unknown): boolean {\n if (!isPlainObject(value)) return false;\n if (typeof value.speaker !== \"string\") return false;\n if (typeof value.isSelf !== \"boolean\") return false;\n if (typeof value.text !== \"string\") return false;\n if (typeof value.confidence !== \"number\") return false;\n return isFusedSegmentProvenance(value.provenance);\n}\n\n/** Structural guard for a parsed fused speaker. */\nfunction isFusedSpeaker(value: unknown): boolean {\n if (!isPlainObject(value)) return false;\n if (typeof value.label !== \"string\") return false;\n if (typeof value.isSelf !== \"boolean\") return false;\n if (typeof value.confidence !== \"number\") return false;\n return isStringArray(value.sources);\n}\n\n/** Structural guard for a parsed fused disagreement. */\nfunction isFusedDisagreement(value: unknown): boolean {\n if (!isPlainObject(value)) return false;\n if (typeof value.kind !== \"string\") return false;\n if (!(value.kind in FUSED_DISAGREEMENT_KINDS)) return false;\n if (typeof value.subject !== \"string\") return false;\n return (\n Array.isArray(value.candidates) &&\n value.candidates.every(\n (cand) =>\n isPlainObject(cand) && typeof cand.source === \"string\" && typeof cand.value === \"string\",\n )\n );\n}\n\n/** Structural guard for a parsed fused-conversation contribution record. */\nfunction isFusedContribution(value: unknown): boolean {\n if (!isPlainObject(value)) return false;\n if (typeof value.source !== \"string\") return false;\n if (typeof value.conversationId !== \"string\") return false;\n if (typeof value.startIso !== \"string\") return false;\n return typeof value.segmentCount === \"number\";\n}\n\n/** Structural guard for a parsed fused-conversation provenance record. */\nfunction isFusedConversationProvenance(value: unknown): boolean {\n if (!isPlainObject(value)) return false;\n if (!Array.isArray(value.contributions) || !value.contributions.every(isFusedContribution)) {\n return false;\n }\n if (typeof value.proximityGapMs !== \"number\") return false;\n if (typeof value.windowToleranceMs !== \"number\") return false;\n return value.method === \"time-proximity\";\n}\n\n/**\n * Structural guard for a parsed fused conversation. Every required field of\n * `FusedWearableConversation` (and its nested segments / speakers /\n * disagreements / provenance) must be present with the right shape, so a\n * null, wrong-typed, or partial element (`[{}]`, `[null]`, `[{id:1}]`) is\n * rejected and the caller treats the body as corrupt (parseOk:false →\n * self-repair rewrite) rather than trusting it.\n */\nfunction isFusedWearableConversation(value: unknown): value is FusedWearableConversation {\n if (!isPlainObject(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.date !== \"string\") return false;\n if (typeof value.startIso !== \"string\") return false;\n if (!isStringArray(value.sources)) return false;\n if (!Array.isArray(value.speakers) || !value.speakers.every(isFusedSpeaker)) return false;\n if (!Array.isArray(value.segments) || !value.segments.every(isFusedSegment)) return false;\n if (!Array.isArray(value.disagreements) || !value.disagreements.every(isFusedDisagreement)) {\n return false;\n }\n return isFusedConversationProvenance(value.provenance);\n}\n\n/**\n * Parse a persisted fused-day file. Returns null when the content does\n * not look like a fusion artifact (wrong kind / missing frontmatter) so\n * callers can distinguish \"not fused\" from a malformed file. A non-null\n * result carries `parseOk`: false when the JSON body failed to parse, was\n * not an array, or held a malformed element (conversations is empty in\n * that case), true for a well-formed (incl. legitimately-empty `[]`)\n * body — so the skip-unchanged path can force a self-repair rewrite\n * regardless of the recomputed conversation count or body hash.\n */\nexport function parseFusionDay(raw: string): FusedDayFile | null {\n if (!raw.startsWith(\"---\\n\")) return null;\n const closeIndex = raw.indexOf(\"\\n---\\n\", 4);\n if (closeIndex === -1) return null;\n const header = raw.slice(4, closeIndex);\n const body = raw.slice(closeIndex + 5).replace(/^\\n/, \"\");\n\n const scalars = new Map<string, string>();\n for (const line of header.split(\"\\n\")) {\n const match = line.match(/^([A-Za-z][A-Za-z0-9]*): (.*)$/);\n if (match) scalars.set(match[1], parseScalar(match[2]));\n }\n\n if (scalars.get(\"kind\") !== FUSION_KIND) return null;\n const date = scalars.get(\"date\");\n if (date === undefined) return null;\n\n let conversations: FusedWearableConversation[] = [];\n let parseOk = true;\n const bodyTrimmed = body.trim();\n if (bodyTrimmed.length === 0) {\n // An existing artifact whose body is blank or whitespace-only (no\n // JSON at all) is corrupt — it is NOT a valid empty `[]`. The\n // serializer always writes `JSON.stringify(conversations, null, 2)`\n // which produces `[]` for zero conversations, so a blank body means\n // the file was truncated, partially written, or manually emptied.\n // Flag parseOk:false so fusedConversations() surfaces the corruption\n // and fuseDay() repairs it (issue #1849).\n parseOk = false;\n } else {\n try {\n const parsed: unknown = JSON.parse(bodyTrimmed);\n if (Array.isArray(parsed) && parsed.every(isFusedWearableConversation)) {\n conversations = parsed;\n } else {\n // Valid JSON but not a well-formed FusedWearableConversation[]\n // (non-array, or an array carrying a null / wrong-typed /\n // missing-required-field element) — flag corrupt so callers\n // recompute fusion rather than trusting a partial read. A\n // legitimately-empty [] is accepted with parseOk left true.\n parseOk = false;\n }\n } catch {\n // A truncated/corrupt body fails to parse; flag parseOk:false so the\n // skip-unchanged path forces a self-repair rewrite (even when the\n // frontmatter hash matches and the recomputed count is also zero).\n parseOk = false;\n }\n }\n\n const meta: FusedDayMeta = {\n kind: FUSION_KIND,\n date,\n sourceCount: parseNonNegativeInt(scalars.get(\"sourceCount\")),\n conversationCount: parseNonNegativeInt(scalars.get(\"conversationCount\")),\n contentHash: scalars.get(\"contentHash\") ?? \"\",\n bodyHash: scalars.get(\"bodyHash\") ?? \"\",\n fusedAt: scalars.get(\"fusedAt\") ?? \"\",\n };\n return { meta, conversations, parseOk };\n}\n\n/** Reserved underscore-prefixed subdir for derived fusion artifacts. */\nexport const FUSION_DIR_NAME = \"_fusion\";\n\n/**\n * Encrypted-at-rest + atomic file IO the fusion artifact store needs.\n * Satisfied by StorageManager (which owns the secure-store key + atomic\n * write path) and injected so this module performs NO direct fs — the\n * derived files inherit the same encrypted-at-rest + atomic-write\n * semantics as raw day transcripts without this module knowing the key.\n */\nexport interface FusionFileIo {\n writeFile(filePath: string, content: string): Promise<void>;\n /** Read a file; rejects with ENOENT when it is absent. */\n readFile(filePath: string): Promise<string>;\n /** Directory entries; rejects with ENOENT when the directory is absent. */\n readDir(dirPath: string): Promise<string[]>;\n /** Remove a file; rejects with ENOENT when it is absent. */\n deleteFile(filePath: string): Promise<void>;\n /**\n * Resolve a path through symlinks (node:fs/promises realpath); rejects\n * with ENOENT when the path is absent. Used by the symlink-containment\n * guard so a symlinked `_fusion` dir (or a symlinked wearables root)\n * that resolves outside the memory dir is rejected before any\n * read/write/delete (AGENTS.md #3).\n */\n realpath(filePath: string): Promise<string>;\n /**\n * Stat a path WITHOUT following a trailing symlink\n * (node:fs/promises lstat); rejects with ENOENT when the path is\n * absent. Used to detect a pre-existing symlink at the fusion\n * artifact directory itself, which is rejected even when its\n * target resolves inside the memory dir (issue #1849).\n */\n lstat(filePath: string): Promise<{ isSymbolicLink: boolean }>;\n}\n\n/**\n * Owns the derived fused-day artifact files under\n * `<wearablesDir>/_fusion/<YYYY-MM-DD>.md`. Path construction, date\n * validation, and newest-first listing live here (relocated out of the\n * root storage module — issue #1810 ratchet); the bytes flow through the\n * injected secure IO.\n */\nexport class FusionArtifactStore {\n constructor(\n private readonly wearablesDir: string,\n private readonly memoryDir: string,\n private readonly io: FusionFileIo,\n ) {}\n\n fusedDayPath(date: string): string {\n if (!isValidTranscriptDate(date)) {\n throw new Error(\n `invalid wearable fusion date '${String(date)}' — expected YYYY-MM-DD`,\n );\n }\n return path.join(this.wearablesDir, FUSION_DIR_NAME, `${date}.md`);\n }\n\n async writeFusedDay(date: string, serialized: string): Promise<void> {\n const filePath = this.fusedDayPath(date);\n await this.assertPathContained(filePath);\n await this.io.writeFile(filePath, serialized);\n }\n\n /** Read a stored fused-day artifact; null when absent. */\n async readFusedDay(date: string): Promise<string | null> {\n const filePath = this.fusedDayPath(date);\n await this.assertPathContained(filePath);\n try {\n return await this.io.readFile(filePath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw err;\n }\n }\n\n /**\n * Remove a stored fused-day artifact. Idempotent: a no-op when the\n * artifact is already absent. Used to clear a now-stale derived file\n * before a fusion run that deliberately refuses to fuse (e.g. a day\n * whose sources later conflict on timezone) so fusedConversations()\n * does not keep serving a stale view (issue #1849).\n */\n async deleteFusedDay(date: string): Promise<void> {\n const filePath = this.fusedDayPath(date);\n await this.assertPathContained(filePath);\n try {\n await this.io.deleteFile(filePath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw err;\n }\n }\n\n /** List dates with stored fused artifacts, newest first. */\n async listFusedDays(): Promise<string[]> {\n const fusionDir = path.join(this.wearablesDir, FUSION_DIR_NAME);\n await this.assertPathContained(fusionDir);\n let entries: string[];\n try {\n entries = await this.io.readDir(fusionDir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw err;\n }\n const days: string[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(\".md\")) continue;\n const date = entry.slice(0, -3);\n if (!isValidTranscriptDate(date)) continue;\n days.push(date);\n }\n days.sort((a, b) => (a > b ? -1 : a < b ? 1 : 0));\n return days;\n }\n\n /**\n * Reject a symlinked/traversing fusion artifact path before any IO. The\n * fusion dir (`<wearablesDir>/_fusion`) and its parents are followed\n * directly by the secure IO; a symlink placed there (attacker-writable\n * or a malformed memory dir) would otherwise be followed and\n * read/write/delete outside the allowed root (AGENTS.md pattern #3).\n *\n * Containment is anchored to the real MEMORY-DIR root, not the\n * wearables dir, AND the wearables root is checked explicitly: if\n * `wearablesDir` itself is a symlink that resolves outside memoryDir, a\n * leaf candidate like `<wearablesDir>/_fusion/<date>.md` may not yet\n * exist (so its realpath ENOENT-skips) and the write would silently\n * create the file inside the symlinked escape target. Checking\n * `wearablesDir` itself — which resolves through the symlink when it\n * exists — closes that gap, while the per-leaf checks catch a nested\n * `_fusion` or per-file symlink. Absent paths are allowed (a fresh\n * write creates them lexically under the root; only a path that\n * resolves to an existing target can redirect IO). Mirrors\n * `assertPathInsideRoot` in the storage walkers.\n */\n private async assertPathContained(targetPath: string): Promise<void> {\n let rootReal: string;\n try {\n rootReal = await this.io.realpath(this.memoryDir);\n } catch {\n // Fresh memory dir not yet on disk — no symlink can resolve through\n // a missing root, so fall back to a lexical resolve.\n rootReal = path.resolve(this.memoryDir);\n }\n // The wearables root first (catches a symlinked wearables dir even\n // when the leaf artifact does not yet exist), then the fusion dir and\n // the target file itself.\n await this.assertNoEscape(rootReal, this.wearablesDir);\n await this.assertNoEscape(rootReal, path.dirname(targetPath));\n await this.assertNoEscape(rootReal, targetPath);\n // Reject a symlinked `_fusion` dir outright — even when its\n // target resolves INSIDE the memory dir. The managed fusion root\n // is always a real directory created by the secure write; a\n // pre-existing link there is tampering/aliasing and is refused\n // before a single byte is written or read (issue #1849).\n await this.assertFusionDirNotSymlinked();\n }\n\n /**\n * Refuse a pre-existing symbolic link at the `<wearablesDir>/_fusion`\n * directory. Unlike `assertNoEscape` (which follows the link and only\n * rejects when the target lands outside the memory dir), this catches a\n * fusion root that aliases an in-bounds path — e.g. a `_fusion` link\n * pointed at a raw source transcript — so fusion IO never writes\n * through it and overwrites the aliased file. Absent dirs are allowed\n * (a fresh write creates a real directory lexically under the root).\n */\n private async assertFusionDirNotSymlinked(): Promise<void> {\n const fusionDir = path.join(this.wearablesDir, FUSION_DIR_NAME);\n let stat: { isSymbolicLink: boolean };\n try {\n stat = await this.io.lstat(fusionDir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw err;\n }\n if (stat.isSymbolicLink) {\n throw new Error(\n \"wearable fusion dir '_fusion' is a symbolic link — refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)\",\n );\n }\n }\n\n /**\n * Refuse a candidate whose realpath escapes the memory root. Absent\n * candidates are allowed: a missing path cannot yet redirect IO, and\n * the secure write creates it lexically under the root.\n */\n private async assertNoEscape(rootReal: string, candidate: string): Promise<void> {\n let candidateReal: string;\n try {\n candidateReal = await this.io.realpath(candidate);\n } catch {\n return; // absent — nothing to follow\n }\n if (!pathIsInside(rootReal, candidateReal)) {\n throw new Error(\n \"wearable fusion artifact path resolves outside the memory dir — refusing to follow a symlink/traversal (AGENTS.md pattern #3)\",\n );\n }\n }\n}\n","/**\n * Wearable cross-source fusion — reconstruct inputs from stored transcripts.\n *\n * The on-demand service path fuses from already-synced day transcripts\n * (offline, no connector calls). Those files store a human-readable\n * markdown body, so this module parses it back into the normalized\n * `FusionConversationInput[]` shape the fusion engine consumes.\n *\n * Precision caveat (documented, accepted for this foundational PR):\n * the rendered body carries minute-precision clock times in the\n * configured timezone. We reconstruct them as `${date}T${HH}:${MM}:00Z`\n * — every source for a given day is rendered in the SAME timezone, so\n * relative within-day comparisons and time-window alignment stay\n * correct even though the absolute ISO is timezone-normalized. Full\n * segment-level alignment with sub-minute precision is a deferred\n * follow-up (see PR body).\n */\n\nimport {\n isValidTranscriptDate,\n parseTranscriptSegmentLine,\n unescapeSegmentText,\n unescapeSpeakerLabel,\n} from \"../day-store.js\";\nimport { hasSelfMarker } from \"../speakers.js\";\nimport type {\n FusionConversationInput,\n FusionSegmentInput,\n} from \"./types.js\";\n\nconst CONVERSATION_HEADING =\n /^## (.+?)\\u2013(.+?)(?:\\s\\u00b7\\s(.*))?\\s\\(conversation (.+)\\)$/;\nconst LOCATION_LINE = /^\\*Location: (.+)\\*$/;\nconst CLOCK_PATTERN = /^(\\d{2}):(\\d{2})$/;\n\n/** Minutes in a 24-hour day. */\nconst MINUTES_PER_DAY = 24 * 60;\n\n/**\n * Upper bound on a plausible single-conversation duration, used to decide\n * whether an earlier heading end clock (or segment clock) is a genuine\n * midnight wrap (start -> midnight -> end/segment within this bound)\n * versus a malformed/ordinary earlier clock that should stay on the same\n * date and be clamped downstream. Generous enough that any legitimate\n * overnight wrap a wearable source would emit still rolls forward; tight\n * enough that a near-24h implied span (e.g. 14:00 -> 13:00) is treated as\n * the error it almost certainly is instead of producing a day-spanning\n * window that broadly clusters unrelated neighbors (#1849).\n */\nconst MAX_PLAUSIBLE_WRAP_MINUTES = 12 * 60;\n\n/** Rendered clock (\"HH:MM\") -> timezone-normalized ISO; \"--:--\" -> undefined. */\nfunction clockToIso(clock: string, date: string): string | undefined {\n const match = CLOCK_PATTERN.exec(clock.trim());\n if (match === null) return undefined;\n // en-US hour12:false renders the first wall-clock hour (00:xx) as 24:xx\n // on some ICU builds. CLOCK_PATTERN matches \"24\", which would build an\n // invalid ISO (24:01-24:59 => NaN) or a next-day instant (24:00 => start\n // of next day). Normalize to 00:xx on the SAME rendered date; cross-\n // midnight conversation windows are rolled forward by the caller.\n const hour = match[1] === \"24\" ? \"00\" : match[1];\n return `${date}T${hour}:${match[2]}:00.000Z`;\n}\n\n/**\n * Minutes-of-day for a rendered clock (24:xx normalized to 0), or\n * undefined when the clock is not parseable (e.g. \"--:--\"). Used to\n * detect conversations that wrap past midnight.\n */\nfunction clockMinutesOfDay(clock: string): number | undefined {\n const match = CLOCK_PATTERN.exec(clock.trim());\n if (match === null) return undefined;\n const hour = match[1] === \"24\" ? 0 : Number.parseInt(match[1], 10);\n return hour * 60 + Number.parseInt(match[2], 10);\n}\n\n/** Increment a YYYY-MM-DD date string by one calendar day (UTC arithmetic). */\nfunction nextCalendarDay(date: string): string {\n const [y, m, d] = date.split(\"-\").map((part) => Number.parseInt(part, 10));\n const dt = new Date(Date.UTC(y, m - 1, d));\n dt.setUTCDate(dt.getUTCDate() + 1);\n const yy = dt.getUTCFullYear();\n const mm = String(dt.getUTCMonth() + 1).padStart(2, \"0\");\n const dd = String(dt.getUTCDate()).padStart(2, \"0\");\n return `${yy}-${mm}-${dd}`;\n}\n\n/**\n * Reconstruct fusion inputs for a day from one or more sources' stored\n * transcript bodies. Each body is the markdown produced by\n * `composeDayTranscriptBody` (frontmatter already stripped by the\n * caller via `parseDayTranscript`).\n */\nexport function reconstructFusionInputs(\n date: string,\n dayTranscripts: ReadonlyArray<{\n source: string;\n body: string;\n /**\n * Whether the body was written by the escape-aware serializer\n * (`bodyIsEscaped(meta)`). When falsy (legacy) the segment text and\n * speaker label are used verbatim — no escape decoding — so a legacy\n * transcript's literal two-character `\\n`/`\\r` is never altered\n * (issue #1849).\n */\n escaped?: boolean;\n }>,\n): FusionConversationInput[] {\n if (!isValidTranscriptDate(date)) return [];\n const inputs: FusionConversationInput[] = [];\n\n for (const { source, body, escaped } of dayTranscripts) {\n let current: {\n conversationId: string;\n title?: string;\n startIso?: string;\n endIso?: string;\n segments: FusionSegmentInput[];\n /** True when the heading end clock precedes the start clock (the\n * conversation window wrapped past midnight); rolls `endIso` forward.\n * Post-midnight SEGMENTS roll independently via `wrapStartMin`. */\n wrapped: boolean;\n wrapStartMin?: number;\n } | null = null;\n\n const flushCurrent = () => {\n if (current === null) return;\n const startIso =\n current.startIso ??\n current.segments.find((segment) => segment.startIso !== undefined)?.startIso ??\n `${date}T00:00:00.000Z`;\n const input: FusionConversationInput = {\n source,\n conversationId: current.conversationId,\n startIso,\n segments: current.segments,\n };\n if (current.endIso !== undefined) input.endIso = current.endIso;\n if (current.title !== undefined) input.title = current.title;\n inputs.push(input);\n current = null;\n };\n\n for (const rawLine of body.split(\"\\n\")) {\n const line = rawLine.trimEnd();\n if (line.length === 0) continue;\n\n const heading = CONVERSATION_HEADING.exec(line);\n if (heading !== null) {\n flushCurrent();\n const [, startClock, endClock, title, id] = heading;\n const startMin = clockMinutesOfDay(startClock);\n const endMin = clockMinutesOfDay(endClock);\n // A conversation whose end clock reads EARLIER than its start\n // clock MAY have wrapped past midnight. Roll its end to the next\n // calendar day ONLY when the implied wrap duration (start ->\n // midnight -> end) is within a plausible single-conversation\n // bound; a near-24h implied span (e.g. start 14:00, end 13:00)\n // is almost certainly a malformed/ordinary earlier clock, not a\n // midnight crossing. Leaving that end on the SAME date keeps\n // endIso < startIso so the downstream cluster clamp collapses it\n // to the start instead of stretching the window across most of\n // the day and broadly clustering unrelated neighbors (#1849).\n // Post-midnight SEGMENTS roll independently below under the SAME\n // plausibility bound: a segment whose clock precedes the start\n // clock is rolled only when the implied wrap is plausible.\n const wrapped =\n startMin !== undefined && endMin !== undefined && endMin < startMin;\n const wrapDuration =\n startMin !== undefined && endMin !== undefined\n ? MINUTES_PER_DAY - startMin + endMin\n : undefined;\n const plausibleWrap =\n wrapped &&\n wrapDuration !== undefined &&\n wrapDuration <= MAX_PLAUSIBLE_WRAP_MINUTES;\n const startIso = clockToIso(startClock, date);\n const endIso = plausibleWrap\n ? clockToIso(endClock, nextCalendarDay(date))\n : clockToIso(endClock, date);\n current = {\n conversationId: id,\n segments: [],\n wrapped,\n ...(startMin !== undefined ? { wrapStartMin: startMin } : {}),\n ...(startIso !== undefined ? { startIso } : {}),\n ...(endIso !== undefined ? { endIso } : {}),\n ...(title !== undefined && title.length > 0 ? { title } : {}),\n };\n continue;\n }\n\n if (LOCATION_LINE.exec(line) !== null) continue;\n\n const segmentMatch = parseTranscriptSegmentLine(line);\n if (segmentMatch !== null) {\n if (current === null) continue; // segment outside any conversation\n const { label, clock, text: rawText } = segmentMatch;\n const text = escaped ? unescapeSegmentText(rawText) : rawText;\n const segMin = clockMinutesOfDay(clock);\n // A segment clock EARLIER than the conversation start clock MAY\n // have crossed midnight. Roll it to the next calendar day ONLY\n // when the implied wrap duration (start -> midnight -> segment)\n // is within the SAME plausible single-conversation bound as the\n // heading end; a near-24h implied span (e.g. start 14:00,\n // segment 13:00) is almost certainly a malformed/provider-skew\n // earlier clock, not a midnight crossing. Leaving it on the SAME\n // date keeps segIso < startIso so the downstream cluster clamp\n // collapses it instead of stretching the interval across most of\n // the day and broadly clustering unrelated neighbors (#1849).\n // Driven by the segment-vs-start comparison directly — NOT gated\n // on `wrapped` — so a heading whose end is missing/unparseable\n // (e.g. `## 23:55–--:--`) still rolls a plausible `[00:05]`\n // segment forward.\n const segWrapDuration =\n current.wrapStartMin !== undefined && segMin !== undefined\n ? MINUTES_PER_DAY - current.wrapStartMin + segMin\n : undefined;\n const plausibleSegWrap =\n current.wrapStartMin !== undefined &&\n segMin !== undefined &&\n segMin < current.wrapStartMin &&\n segWrapDuration !== undefined &&\n segWrapDuration <= MAX_PLAUSIBLE_WRAP_MINUTES;\n const segDate = plausibleSegWrap ? nextCalendarDay(date) : date;\n const startIso = clockToIso(clock, segDate);\n // Decode the safely-serialized speaker label back to its original\n // form ONLY when the body is escape-aware; legacy raw labels are\n // used verbatim so their literal characters are never altered\n // (#1849).\n const speaker = escaped\n ? unescapeSpeakerLabel(label.trim())\n : label.trim();\n const segment: FusionSegmentInput = {\n speaker,\n // Self status is read from the RESERVED `(you)` marker, which the\n // renderer guarantees can only appear on the wearer's label -\n // never on a non-self display name (issue #1849).\n isSelf: hasSelfMarker(speaker),\n text,\n ...(startIso !== undefined ? { startIso } : {}),\n };\n current.segments.push(segment);\n }\n // Unrecognized lines (e.g. the H1 source header) are ignored.\n }\n flushCurrent();\n }\n\n return inputs;\n}\n","/**\n * Meeting record composition, serialization, and the on-disk store (#1900).\n *\n * One markdown file per meeting under `<memoryDir>/meetings/<YYYY-MM-DD>/<id>.md`\n * with YAML frontmatter. Placement mirrors the wearables day-store rationale:\n *\n * - OUTSIDE the memory scan roots (facts/, procedures/, …) so meeting\n * transcripts never surface as memories in recall or governance passes;\n * - INSIDE the QMD collection root (the memory dir) so records are full-text\n * searchable after the next index update — but never auto-recalled raw.\n *\n * Records rebuild idempotently on `contentHash`: an unchanged meeting re-writes\n * nothing. The transcript body reuses the wearables day-store line grammar\n * (`**Name** [HH:MM]: text`, escape-aware) so existing parsers apply. File IO is\n * injected (like the fusion artifact store) so encrypted-at-rest + atomic-write\n * semantics are inherited without this module touching the secure-store key.\n */\n\nimport { createHash } from \"node:crypto\";\nimport * as path from \"node:path\";\n\nimport { pathIsInside } from \"../utils/path-containment.js\";\nimport { escapeSegmentText, escapeSpeakerLabel, isValidTranscriptDate } from \"../wearables/day-store.js\";\nimport type { FusedSegment } from \"../wearables/fusion/types.js\";\nimport type { FusedMeeting, MeetingDetectionSource, MeetingRecord } from \"./types.js\";\n\nexport const MEETINGS_DIR_NAME = \"meetings\";\nexport const MEETING_KIND = \"meeting\" as const;\nexport const MEETING_FORMAT_VERSION = 1;\n\n/** `mtg-YYYY-MM-DD-<8 hex>` — the id shape derived by `meetingId`. */\nconst MEETING_ID_PATTERN = /^mtg-(\\d{4}-\\d{2}-\\d{2})-[0-9a-f]{8}$/;\n\n/** The detection-source label from a meeting id would be ambiguous, so validate\n * an id AND confirm its embedded date matches the directory it lives under. */\nexport function meetingIdDate(id: string): string | null {\n const match = MEETING_ID_PATTERN.exec(id);\n return match === null ? null : match[1]!;\n}\n\n/** Base fields (identity + detection) a fused meeting is composed with. */\nexport interface MeetingRecordBase {\n id: string;\n date: string;\n startUtc: string;\n endUtc: string;\n app?: string;\n detectionSource: MeetingDetectionSource;\n title?: string;\n}\n\n/** Canonical semantic content hashed for idempotency (excludes contentHash). */\nfunction canonicalContent(base: MeetingRecordBase, fused: FusedMeeting): string {\n return JSON.stringify({\n formatVersion: MEETING_FORMAT_VERSION,\n id: base.id,\n date: base.date,\n startUtc: base.startUtc,\n endUtc: base.endUtc,\n app: base.app ?? null,\n detectionSource: base.detectionSource,\n title: base.title ?? null,\n attendees: fused.attendees,\n sources: fused.sources,\n corroboratedBy: fused.corroboratedBy,\n screenContext: fused.screenContext,\n contextExcerpts: fused.contextExcerpts,\n transcript: fused.transcript,\n speakers: fused.speakers,\n snapshotCount: fused.snapshotCount,\n });\n}\n\n/** Compose a full meeting record (with contentHash) from its base + fused view. */\nexport function composeMeetingRecord(base: MeetingRecordBase, fused: FusedMeeting): MeetingRecord {\n const contentHash = createHash(\"sha256\").update(canonicalContent(base, fused), \"utf-8\").digest(\"hex\");\n return {\n ...base,\n ...fused,\n contentHash,\n formatVersion: MEETING_FORMAT_VERSION,\n };\n}\n\nfunction formatClockUtc(iso: string): string {\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return \"--:--\";\n return new Date(ms).toISOString().slice(11, 16);\n}\n\nfunction renderTranscriptLine(segment: FusedSegment): string {\n const clock = formatClockUtc(segment.startIso ?? \"\");\n return `**${escapeSpeakerLabel(segment.speaker)}** [${clock}]: ${escapeSegmentText(segment.text)}`;\n}\n\nfunction frontmatterList(key: string, values: readonly string[]): string[] {\n if (values.length === 0) return [`${key}: []`];\n const lines = [`${key}:`];\n for (const value of values) lines.push(` - ${JSON.stringify(value)}`);\n return lines;\n}\n\n/** Serialize a meeting record into its persisted markdown form. */\nexport function serializeMeetingRecord(record: MeetingRecord): string {\n const lines: string[] = [\"---\"];\n lines.push(`kind: ${MEETING_KIND}`);\n lines.push(`formatVersion: ${record.formatVersion}`);\n lines.push(`id: ${JSON.stringify(record.id)}`);\n lines.push(`date: ${JSON.stringify(record.date)}`);\n lines.push(`startUtc: ${JSON.stringify(record.startUtc)}`);\n lines.push(`endUtc: ${JSON.stringify(record.endUtc)}`);\n if (record.app !== undefined) lines.push(`app: ${JSON.stringify(record.app)}`);\n lines.push(`detectionSource: ${JSON.stringify(record.detectionSource)}`);\n if (record.title !== undefined) lines.push(`title: ${JSON.stringify(record.title)}`);\n lines.push(...frontmatterList(\"attendees\", record.attendees));\n lines.push(...frontmatterList(\"sources\", record.sources));\n lines.push(...frontmatterList(\"corroboratedBy\", record.corroboratedBy));\n lines.push(`snapshotCount: ${record.snapshotCount}`);\n lines.push(`contentHash: ${JSON.stringify(record.contentHash)}`);\n lines.push(\"---\");\n lines.push(\"\");\n\n const heading = record.title !== undefined && record.title.length > 0 ? ` · ${record.title}` : \"\";\n lines.push(`# Meeting ${record.id}${heading}`);\n lines.push(\"\");\n\n lines.push(\"## Attendees\");\n lines.push(\"\");\n if (record.attendees.length === 0) {\n lines.push(\"_None resolved._\");\n } else {\n for (const attendee of record.attendees) lines.push(`- ${attendee}`);\n }\n lines.push(\"\");\n\n if (record.screenContext.length > 0 || record.contextExcerpts.length > 0) {\n lines.push(\"## Screen context\");\n lines.push(\"\");\n for (const event of record.screenContext) {\n lines.push(`- [${event.clock}] ${event.label}`);\n }\n if (record.contextExcerpts.length > 0) {\n if (record.screenContext.length > 0) lines.push(\"\");\n lines.push(\"Notable excerpts:\");\n lines.push(\"\");\n for (const excerpt of record.contextExcerpts) lines.push(`> ${excerpt.replace(/\\n/g, \" \")}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"## Transcript\");\n lines.push(\"\");\n if (record.transcript.length === 0) {\n lines.push(\"_No transcript segments in this window._\");\n } else {\n for (const segment of record.transcript) lines.push(renderTranscriptLine(segment));\n }\n lines.push(\"\");\n\n return `${lines.join(\"\\n\")}`;\n}\n\n/** A meeting record's frontmatter, parsed for listing + idempotency checks. */\nexport interface MeetingRecordSummary {\n id: string;\n date: string;\n startUtc: string;\n endUtc: string;\n app?: string;\n detectionSource: string;\n title?: string;\n attendees: string[];\n sources: string[];\n corroboratedBy: string[];\n snapshotCount: number;\n contentHash: string;\n}\n\nfunction parseScalar(value: string): string {\n const trimmed = value.trim();\n if (trimmed.startsWith('\"')) {\n try {\n return JSON.parse(trimmed) as string;\n } catch {\n return trimmed;\n }\n }\n return trimmed;\n}\n\n/** Parse a meeting record's frontmatter. Returns null when the content is not a\n * meeting record (wrong kind, missing frontmatter) so callers distinguish a\n * non-record from a corrupt one. */\nexport function parseMeetingRecordSummary(raw: string): MeetingRecordSummary | null {\n if (!raw.startsWith(\"---\\n\")) return null;\n const closeIndex = raw.indexOf(\"\\n---\\n\", 4);\n if (closeIndex === -1) return null;\n const frontmatter = raw.slice(4, closeIndex).split(\"\\n\");\n\n const scalars: Record<string, string> = {};\n const lists: Record<string, string[]> = {};\n let currentList: string | null = null;\n for (const line of frontmatter) {\n const listItem = /^ {2}- (.*)$/.exec(line);\n if (listItem !== null && currentList !== null) {\n lists[currentList]!.push(parseScalar(listItem[1]!));\n continue;\n }\n const kv = /^([A-Za-z][A-Za-z0-9]*):\\s*(.*)$/.exec(line);\n if (kv === null) continue;\n const key = kv[1]!;\n const value = kv[2]!;\n if (value === \"\") {\n currentList = key;\n lists[key] = [];\n } else if (value === \"[]\") {\n currentList = null;\n lists[key] = [];\n } else {\n currentList = null;\n scalars[key] = value;\n }\n }\n\n if (scalars.kind !== undefined && parseScalar(scalars.kind) !== MEETING_KIND) return null;\n const id = scalars.id !== undefined ? parseScalar(scalars.id) : undefined;\n const contentHash = scalars.contentHash !== undefined ? parseScalar(scalars.contentHash) : undefined;\n if (id === undefined || contentHash === undefined) return null;\n\n return {\n id,\n date: scalars.date !== undefined ? parseScalar(scalars.date) : \"\",\n startUtc: scalars.startUtc !== undefined ? parseScalar(scalars.startUtc) : \"\",\n endUtc: scalars.endUtc !== undefined ? parseScalar(scalars.endUtc) : \"\",\n ...(scalars.app !== undefined ? { app: parseScalar(scalars.app) } : {}),\n detectionSource: scalars.detectionSource !== undefined ? parseScalar(scalars.detectionSource) : \"\",\n ...(scalars.title !== undefined ? { title: parseScalar(scalars.title) } : {}),\n attendees: lists.attendees ?? [],\n sources: lists.sources ?? [],\n corroboratedBy: lists.corroboratedBy ?? [],\n snapshotCount: scalars.snapshotCount !== undefined ? Number(scalars.snapshotCount) || 0 : 0,\n contentHash,\n };\n}\n\n/**\n * Encrypted-at-rest + atomic file IO the meeting record store needs. Satisfied\n * by StorageManager (which owns the secure-store key + atomic write path) and\n * injected so this module performs NO direct fs — records inherit the same\n * encrypted-at-rest + atomic-write semantics as memories. Same shape as the\n * fusion artifact store's IO port (kept per-module, not shared, so each store's\n * boundary stays explicit).\n */\nexport interface MeetingRecordFileIo {\n writeFile(filePath: string, content: string): Promise<void>;\n readFile(filePath: string): Promise<string>;\n readDir(dirPath: string): Promise<string[]>;\n deleteFile(filePath: string): Promise<void>;\n realpath(filePath: string): Promise<string>;\n lstat(filePath: string): Promise<{ isSymbolicLink: boolean }>;\n}\n\n/** Result of an idempotent record save. */\nexport interface MeetingSaveResult {\n path: string;\n /** False when the on-disk contentHash already matched (nothing rewritten). */\n written: boolean;\n contentHash: string;\n}\n\n/**\n * Owns the meeting record files under `<memoryDir>/meetings/<date>/<id>.md`.\n * Path construction, date/id validation, and symlink containment live here; the\n * bytes flow through the injected secure IO. Containment is anchored to the real\n * memory-dir root and mirrors the fusion artifact store (AGENTS.md pattern #3).\n */\nexport class MeetingRecordStore {\n private readonly meetingsDir: string;\n\n constructor(\n private readonly memoryDir: string,\n private readonly io: MeetingRecordFileIo,\n ) {\n this.meetingsDir = path.join(memoryDir, MEETINGS_DIR_NAME);\n }\n\n recordPath(date: string, id: string): string {\n if (!isValidTranscriptDate(date)) {\n throw new Error(`invalid meeting date '${String(date)}' — expected YYYY-MM-DD`);\n }\n const idDate = meetingIdDate(id);\n if (idDate === null) {\n throw new Error(`invalid meeting id '${String(id)}' — expected mtg-YYYY-MM-DD-<hash>`);\n }\n if (idDate !== date) {\n throw new Error(`meeting id '${id}' does not belong to date '${date}'`);\n }\n return path.join(this.meetingsDir, date, `${id}.md`);\n }\n\n /** Idempotently persist a record: skip the write when contentHash is unchanged. */\n async saveMeetingRecord(record: MeetingRecord): Promise<MeetingSaveResult> {\n const filePath = this.recordPath(record.date, record.id);\n await this.assertPathContained(filePath);\n const existing = await this.readRaw(filePath);\n if (existing !== null) {\n const summary = parseMeetingRecordSummary(existing);\n if (summary !== null && summary.contentHash === record.contentHash) {\n return { path: filePath, written: false, contentHash: record.contentHash };\n }\n }\n await this.io.writeFile(filePath, serializeMeetingRecord(record));\n return { path: filePath, written: true, contentHash: record.contentHash };\n }\n\n /** Read a stored record's raw markdown; null when absent. */\n async readMeetingRecord(date: string, id: string): Promise<string | null> {\n const filePath = this.recordPath(date, id);\n await this.assertPathContained(filePath);\n return this.readRaw(filePath);\n }\n\n /**\n * Read + parse every stored record for a day exactly ONCE, sorted by start\n * time (ascending, id tiebreak). The single day-read path both `listMeetingIds`\n * and `listMeetingSummaries` derive from — no record is read twice.\n */\n private async readDaySummaries(date: string): Promise<MeetingRecordSummary[]> {\n if (!isValidTranscriptDate(date)) {\n throw new Error(`invalid meeting date '${String(date)}' — expected YYYY-MM-DD`);\n }\n const dayDir = path.join(this.meetingsDir, date);\n await this.assertPathContained(dayDir);\n let entries: string[];\n try {\n entries = await this.io.readDir(dayDir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw err;\n }\n const summaries: MeetingRecordSummary[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(\".md\")) continue;\n const id = entry.slice(0, -3);\n if (meetingIdDate(id) !== date) continue;\n const raw = await this.readMeetingRecord(date, id);\n if (raw === null) continue;\n const summary = parseMeetingRecordSummary(raw);\n if (summary !== null) summaries.push(summary);\n }\n summaries.sort((a, b) => (a.startUtc < b.startUtc ? -1 : a.startUtc > b.startUtc ? 1 : SORT_STR(a.id, b.id)));\n return summaries;\n }\n\n /** List meeting ids stored for a day, sorted by start time (ascending). */\n async listMeetingIds(date: string): Promise<string[]> {\n return (await this.readDaySummaries(date)).map((summary) => summary.id);\n }\n\n /** Read parsed summaries for a day, sorted by start time. */\n async listMeetingSummaries(date: string): Promise<MeetingRecordSummary[]> {\n return this.readDaySummaries(date);\n }\n\n /** List dates that have at least one stored meeting record, newest first. */\n async listMeetingDates(): Promise<string[]> {\n await this.assertPathContained(this.meetingsDir);\n let entries: string[];\n try {\n entries = await this.io.readDir(this.meetingsDir);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw err;\n }\n const dates = entries.filter((entry) => isValidTranscriptDate(entry));\n dates.sort((a, b) => (a > b ? -1 : a < b ? 1 : 0));\n return dates;\n }\n\n /** Remove a stored record. Idempotent: a no-op when already absent. */\n async deleteMeetingRecord(date: string, id: string): Promise<void> {\n const filePath = this.recordPath(date, id);\n await this.assertPathContained(filePath);\n try {\n await this.io.deleteFile(filePath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw err;\n }\n }\n\n private async readRaw(filePath: string): Promise<string | null> {\n try {\n return await this.io.readFile(filePath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw err;\n }\n }\n\n private async assertPathContained(targetPath: string): Promise<void> {\n let rootReal: string;\n try {\n rootReal = await this.io.realpath(this.memoryDir);\n } catch {\n rootReal = path.resolve(this.memoryDir);\n }\n await this.assertNoEscape(rootReal, this.meetingsDir);\n await this.assertNoEscape(rootReal, path.dirname(targetPath));\n await this.assertNoEscape(rootReal, targetPath);\n // Reject a symlinked meetings root OR a symlinked intermediate day directory\n // outright — even when the link resolves inside the memory dir (aliasing /\n // tampering) — before any read/write (AGENTS.md pattern #3).\n await this.assertNotSymlink(this.meetingsDir, \"directory\");\n const dayDir = this.dayDirWithin(targetPath);\n if (dayDir !== null) await this.assertNotSymlink(dayDir, \"directory\");\n // Reject a symlinked LEAF record file too: lstat'ing only the root + day dir\n // let a pre-existing `<id>.md` symlink (e.g. into facts/) pass realpath\n // containment, so the read/write would FOLLOW the link and leak raw\n // transcript into the recall corpus. Refuse the link before any IO.\n if (targetPath.endsWith(\".md\")) await this.assertNotSymlink(targetPath, \"record file\");\n }\n\n /** The `<meetings>/<date>` directory on the path to `targetPath`, or null when\n * `targetPath` is the meetings root itself. */\n private dayDirWithin(targetPath: string): string | null {\n const rel = path.relative(this.meetingsDir, targetPath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return null;\n const first = rel.split(path.sep)[0];\n if (first === undefined || first.length === 0) return null;\n return path.join(this.meetingsDir, first);\n }\n\n private async assertNotSymlink(target: string, kind: \"directory\" | \"record file\"): Promise<void> {\n let stat: { isSymbolicLink: boolean };\n try {\n stat = await this.io.lstat(target);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw err;\n }\n if (stat.isSymbolicLink) {\n const label = path.relative(this.memoryDir, target) || MEETINGS_DIR_NAME;\n throw new Error(\n `meetings ${kind} '${label}' is a symbolic link — refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)`,\n );\n }\n }\n\n private async assertNoEscape(rootReal: string, candidate: string): Promise<void> {\n let candidateReal: string;\n try {\n candidateReal = await this.io.realpath(candidate);\n } catch {\n return;\n }\n if (!pathIsInside(rootReal, candidateReal)) {\n throw new Error(\n \"meeting record path resolves outside the memory dir — refusing to follow a symlink/traversal (AGENTS.md pattern #3)\",\n );\n }\n }\n}\n\nconst SORT_STR = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n","import { readdir } from \"node:fs/promises\";\nimport type { Dirent } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { stripAttributesSuffix } from \"../structured-attributes.js\";\nimport type { MemoryFile } from \"../types.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\n\nexport interface SupersessionAuditLookup {\n correctionsDir: string;\n readMemoryByPath(filePath: string): Promise<MemoryFile | null>;\n}\n\nexport async function hasSupersessionAudit(\n lookup: SupersessionAuditLookup,\n oldMemoryId: string,\n newMemoryId: string,\n auditBody: string,\n structuredAttributes?: Record<string, string>\n): Promise<boolean> {\n let entries: Dirent[];\n try {\n entries = await readdir(lookup.correctionsDir, { withFileTypes: true });\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return false;\n throw error;\n }\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const memory = await lookup.readMemoryByPath(path.join(lookup.correctionsDir, entry.name));\n if (\n memory?.frontmatter.category === \"correction\" &&\n (memory.frontmatter.sourceMemoryId === oldMemoryId ||\n (memory.frontmatter.sourceMemoryId === undefined && memory.frontmatter.lineage?.includes(oldMemoryId))) &&\n memory.frontmatter.lineage?.includes(newMemoryId) &&\n stripAttributesSuffix(memory.content) === auditBody &&\n (structuredAttributes === undefined ||\n Object.entries(structuredAttributes).every(\n ([key, value]) => memory.frontmatter.structuredAttributes?.[key] === value\n ))\n ) {\n return true;\n }\n }\n return false;\n}\n","import {\n buildRetiredFactTombstoneInputs,\n type TombstoneCreatedBy,\n type TombstoneReason,\n} from \"../lifecycle/tombstones.js\";\nimport { log } from \"../logger.js\";\nimport { stripCitationForTemplate } from \"../source-attribution.js\";\nimport { supersessionKeysForFact } from \"../temporal-supersession.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport { composeMemoryEnvelope, type SealedMemoryEnvelope } from \"../write-envelope.js\";\nimport { hasSupersessionAudit } from \"./supersession-audit.js\";\n\ntype TombstoneInput = {\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n sourceMemoryId: string;\n rawContent: string;\n entityRef?: string;\n supersessionKey?: string;\n operationKey?: string;\n createdAt?: string;\n contentHash?: string;\n};\n\nexport interface SupersessionSideEffectOptions {\n oldMemoryId: string;\n newMemoryId: string;\n reason: string;\n now: string;\n operationId: string;\n exactReplay: boolean;\n currentBefore: MemoryFile;\n updatedFm: MemoryFrontmatter;\n actor?: string;\n audit?: SupersessionAuditOptions;\n citationTemplate: string;\n correctionsDir: string;\n readMemoryByPath: (filePath: string) => Promise<MemoryFile | null>;\n isColdOrArchiveTierPath: (memoryPath: string) => boolean;\n invalidateColdMemoriesCache: () => void;\n invalidateAllMemoriesCache: () => void;\n bumpMemoryCorpusVersion: () => void;\n appendLifecycleEvent: () => Promise<void>;\n bumpMemoryStatusVersion: () => void;\n hasExactTombstone: (input: TombstoneInput) => Promise<boolean>;\n appendTombstone: (input: TombstoneInput) => Promise<string | null>;\n writeSealedMemory: (\n envelope: SealedMemoryEnvelope,\n extras: { actor?: string; lineage: [string, string]; sourceMemoryId: string }\n ) => Promise<unknown>;\n}\n\nexport interface SupersessionAuditOptions {\n content: string;\n tags?: string[];\n structuredAttributes?: Record<string, string>;\n source?: string;\n}\n\nexport async function runSupersessionSideEffects(options: SupersessionSideEffectOptions): Promise<boolean> {\n const {\n oldMemoryId,\n newMemoryId,\n reason,\n now,\n operationId,\n exactReplay,\n currentBefore,\n updatedFm,\n citationTemplate,\n } = options;\n try {\n if (options.isColdOrArchiveTierPath(currentBefore.path)) options.invalidateColdMemoriesCache();\n if (exactReplay) options.invalidateAllMemoriesCache();\n else options.bumpMemoryCorpusVersion();\n await options.appendLifecycleEvent();\n options.bumpMemoryStatusVersion();\n log.debug(`superseded memory ${oldMemoryId} by ${newMemoryId}: ${reason}`);\n\n if (currentBefore.frontmatter.category === \"fact\") {\n for (const input of buildRetiredFactTombstoneInputs(\n {\n id: oldMemoryId,\n content: stripCitationForTemplate(currentBefore.content, citationTemplate),\n contentHash: currentBefore.frontmatter.contentHash,\n entityRef: updatedFm.entityRef,\n structuredAttributes: currentBefore.frontmatter.structuredAttributes,\n },\n {\n reason: \"contradiction_resolution\",\n createdBy: \"contradiction_resolution\",\n createdAt: now,\n supersessionKeysForFact,\n }\n )) {\n const exactInput = { ...input, operationKey: operationId };\n const exists = (await options.hasExactTombstone(exactInput)) || (await options.hasExactTombstone(input));\n if (!exists) await options.appendTombstone(exactInput);\n }\n }\n\n const auditBody = `Superseded: ${options.audit?.content ?? currentBefore.content}\\n\\nReason: ${reason}`;\n const auditExists = await hasSupersessionAudit(\n {\n correctionsDir: options.correctionsDir,\n readMemoryByPath: options.readMemoryByPath,\n },\n oldMemoryId,\n newMemoryId,\n auditBody,\n options.audit?.structuredAttributes\n );\n if (!auditExists) {\n const auditEnvelope = composeMemoryEnvelope(\n {\n content: auditBody,\n category: \"correction\",\n confidence: 1,\n tags: options.audit?.tags ?? [\"supersession\", \"auto-resolved\"],\n structuredAttributes: options.audit?.structuredAttributes,\n },\n { source: options.audit?.source ?? \"contradiction-detection\" }\n );\n await options.writeSealedMemory(auditEnvelope, {\n actor: options.actor,\n lineage: [oldMemoryId, newMemoryId],\n sourceMemoryId: oldMemoryId,\n });\n }\n options.invalidateAllMemoriesCache();\n return true;\n } catch (err) {\n log.error(`supersession side effects failed for ${oldMemoryId}:`, err);\n return false;\n }\n}\n","// Entity timeline / structured-section pure helpers extracted from storage.ts\n// (issue #1909 PR write-hot-paths). Pure functions only — no I/O — so they are\n// safe to share across the write path and entity parsing without circular\n// runtime coupling. storage.ts imports these back and re-exports the ones that\n// were previously part of its public API.\nimport { createHash } from \"node:crypto\";\nimport { matchEntitySchemaSection, normalizeEntityStructuredSection } from \"../entity-schema.js\";\nimport type { EntityFile, EntityStructuredSection, EntityTimelineEntry, PluginConfig } from \"../types.js\";\nexport const ENTITY_TIMELINE_METADATA_MARKER = \"remnic-meta-v1\";\n\nexport function parseEntityTimelineBullet(bullet: string, fallbackTimestamp: string): EntityTimelineEntry | null {\n const trimmed = bullet.trim();\n if (!trimmed) return null;\n\n let rest = trimmed;\n const entry: EntityTimelineEntry = {\n timestamp: trimmed.startsWith(\"[\") ? \"\" : fallbackTimestamp,\n text: \"\",\n };\n const consumedMetadataSegments: string[] = [];\n let metadataMarkerSeen = false;\n let literalSingleSourceSegment: string | undefined;\n\n if (!trimmed.startsWith(\"[\")) {\n entry.text = unescapeEntityTimelineText(trimmed);\n return entry.text ? entry : null;\n }\n\n const firstEnd = trimmed.indexOf(\"]\");\n if (firstEnd === -1) {\n entry.text = trimmed;\n return entry.text ? entry : null;\n }\n\n const firstToken = trimmed.slice(1, firstEnd).trim();\n const parsedTimestamp = Date.parse(firstToken);\n if (Number.isFinite(parsedTimestamp)) {\n entry.timestamp = firstToken || fallbackTimestamp;\n rest = trimmed.slice(firstEnd + 1).trimStart();\n }\n\n while (rest.startsWith(\"[\")) {\n const end = findEntityTimelineTokenEnd(rest);\n if (end === -1) break;\n const rawSegment = rest.slice(0, end + 1);\n const token = rest.slice(1, end).trim();\n const nextRest = rest.slice(end + 1).trimStart();\n if (token === ENTITY_TIMELINE_METADATA_MARKER) {\n metadataMarkerSeen = true;\n consumedMetadataSegments.push(rawSegment);\n rest = nextRest;\n continue;\n }\n const equalsIdx = token.indexOf(\"=\");\n if (equalsIdx === -1) {\n if (rest === trimmed) {\n entry.text = trimmed;\n return entry.text ? entry : null;\n }\n break;\n }\n const key = token.slice(0, equalsIdx).trim().toLowerCase();\n const value = unescapeEntityTimelineMetadataValue(token.slice(equalsIdx + 1).trim());\n if (!value) break;\n if (key === \"remnic-origin\" && !metadataMarkerSeen) {\n entry.text = rest.trim();\n return entry.text ? entry : null;\n }\n switch (key) {\n case \"source_meta\":\n entry.source = value;\n break;\n case \"source\":\n if (\n consumedMetadataSegments.length === 0 &&\n !nextRest.startsWith(\"[\") &&\n nextRest.length > 0 &&\n !isManagedEntityTimelineSource(value)\n ) {\n literalSingleSourceSegment = rawSegment;\n rest = nextRest;\n break;\n }\n entry.source = value;\n break;\n case \"session\":\n case \"sessionkey\":\n entry.sessionKey = value;\n break;\n case \"principal\":\n entry.principal = value;\n break;\n case \"remnic-origin\":\n entry.origin = value;\n break;\n default:\n entry.text = rest.trim();\n return entry.text ? entry : null;\n }\n if (literalSingleSourceSegment) break;\n consumedMetadataSegments.push(rawSegment);\n rest = nextRest;\n }\n\n if (literalSingleSourceSegment) {\n return {\n timestamp: entry.timestamp,\n text: `${literalSingleSourceSegment} ${rest}`.trim(),\n };\n }\n entry.text = unescapeEntityTimelineText(rest.trim());\n if (!entry.text) return null;\n return entry;\n}\n\nexport function isEntitySynthesisTimelinePromotionBullet(bullet: string): boolean {\n const trimmed = bullet.trim();\n if (!trimmed.startsWith(\"[\")) return false;\n\n const firstEnd = findEntityTimelineTokenEnd(trimmed);\n if (firstEnd === -1) return false;\n\n const firstToken = trimmed.slice(1, firstEnd).trim();\n return looksLikeEntityTimelineTimestamp(firstToken);\n}\n\nexport function looksLikeEntityTimelineTimestamp(token: string): boolean {\n if (!/^\\d{4}-\\d{2}-\\d{2}(?:[T\\s].*)?$/.test(token)) return false;\n return Number.isFinite(Date.parse(token));\n}\n\nexport function isManagedEntityTimelineSource(source: string): boolean {\n switch (source.trim().toLowerCase()) {\n case \"artifact\":\n case \"chunking\":\n case \"cli-migrate\":\n case \"compounding-promotion\":\n case \"consolidation\":\n case \"contradiction-detection\":\n case \"entity_extraction\":\n case \"explicit\":\n case \"explicit-inline\":\n case \"explicit-inline-review\":\n case \"explicit-review\":\n case \"extraction\":\n case \"extraction-shared-promotion\":\n case \"manual\":\n case \"migration\":\n case \"migration-rechunk\":\n case \"proactive\":\n case \"replay\":\n case \"semantic-consolidation\":\n case \"unknown\":\n return true;\n default:\n return false;\n }\n}\n\nexport function findEntityTimelineTokenEnd(input: string): number {\n let escaped = false;\n for (let index = 0; index < input.length; index += 1) {\n const char = input[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"]\") return index;\n }\n return -1;\n}\n\nexport function escapeEntityTimelineMetadataValue(value: string): string {\n let escaped = \"\";\n for (const char of value) {\n switch (char) {\n case \"\\\\\":\n escaped += \"\\\\\\\\\";\n break;\n case \"]\":\n escaped += \"\\\\]\";\n break;\n case \"\\n\":\n escaped += \"\\\\n\";\n break;\n case \"\\r\":\n escaped += \"\\\\r\";\n break;\n case \"\\t\":\n escaped += \"\\\\t\";\n break;\n default: {\n const codePoint = char.codePointAt(0) ?? 0;\n if (codePoint < 0x20) {\n escaped += `\\\\u${codePoint.toString(16).padStart(4, \"0\")}`;\n } else {\n escaped += char;\n }\n }\n }\n }\n return escaped;\n}\n\nexport function unescapeEntityTimelineMetadataValue(value: string): string {\n if (!value.includes(\"\\\\\")) return value;\n\n let result = \"\";\n for (let index = 0; index < value.length; index += 1) {\n const char = value[index];\n if (char !== \"\\\\\") {\n result += char;\n continue;\n }\n\n const next = value[index + 1];\n if (!next) {\n result += \"\\\\\";\n break;\n }\n\n switch (next) {\n case \"n\":\n result += \"\\n\";\n index += 1;\n break;\n case \"r\":\n result += \"\\r\";\n index += 1;\n break;\n case \"t\":\n result += \"\\t\";\n index += 1;\n break;\n case \"u\": {\n const hex = value.slice(index + 2, index + 6);\n if (/^[0-9a-fA-F]{4}$/.test(hex)) {\n result += String.fromCharCode(parseInt(hex, 16));\n index += 5;\n break;\n }\n result += \"u\";\n index += 1;\n break;\n }\n default:\n result += next;\n index += 1;\n break;\n }\n }\n return result;\n}\nexport function escapeEntityTimelineText(value: string): string {\n return /^\\\\*\\[(?:remnic-origin=|remnic-meta-v1\\])/i.test(value) ? `\\\\${value}` : value;\n}\n\nexport function unescapeEntityTimelineText(value: string): string {\n return /^\\\\+\\[(?:remnic-origin=|remnic-meta-v1\\])/i.test(value) ? value.slice(1) : value;\n}\n\nexport function serializeEntityTimelineEntry(entry: EntityTimelineEntry): string {\n const tokens: string[] = [];\n if (entry.timestamp.trim().length > 0) {\n tokens.push(`[${entry.timestamp}]`);\n }\n if (entry.source) {\n const sourceKey = isManagedEntityTimelineSource(entry.source) ? \"source\" : \"source_meta\";\n tokens.push(`[${sourceKey}=${escapeEntityTimelineMetadataValue(entry.source)}]`);\n }\n if (entry.sessionKey) {\n tokens.push(`[session=${escapeEntityTimelineMetadataValue(entry.sessionKey)}]`);\n }\n if (entry.principal) {\n tokens.push(`[principal=${escapeEntityTimelineMetadataValue(entry.principal)}]`);\n }\n if (entry.origin) {\n tokens.push(`[${ENTITY_TIMELINE_METADATA_MARKER}]`);\n tokens.push(`[remnic-origin=${escapeEntityTimelineMetadataValue(entry.origin)}]`);\n }\n const serializedMetadata = tokens.length > 0 ? `${tokens.join(\" \")} ` : \"\";\n return `- ${serializedMetadata}${escapeEntityTimelineText(entry.text)}`.trimEnd();\n}\n\nexport function dedupeEntityTimelineFacts(timeline: EntityTimelineEntry[]): string[] {\n return [...new Set(timeline.map((entry) => entry.text.trim()).filter((entry) => entry.length > 0))];\n}\n\nexport function normalizeEntitySectionFact(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nexport function normalizeStructuredSectionFactsWithOrigins(\n facts: string[],\n factOrigins?: Array<string | undefined>,\n defaultOrigin?: string,\n): Pick<EntityStructuredSection, \"facts\" | \"factOrigins\"> {\n const normalizedFacts: string[] = [];\n const origins: Array<string | undefined> = [];\n const seen = new Map<string, number>();\n for (const [index, fact] of facts.entries()) {\n const normalized = normalizeEntitySectionFact(fact);\n if (!normalized) continue;\n const existingIndex = seen.get(normalized) ?? -1;\n const origin = factOrigins?.[index] ?? defaultOrigin;\n if (existingIndex >= 0) {\n if (origins[existingIndex] !== origin) origins[existingIndex] = undefined;\n continue;\n }\n seen.set(normalized, normalizedFacts.length);\n normalizedFacts.push(normalized);\n origins.push(origin);\n }\n return {\n facts: normalizedFacts,\n ...(origins.some((origin) => origin !== undefined) ? { factOrigins: origins } : {}),\n };\n}\nexport function normalizeStructuredSectionFacts(facts: string[]): string[] {\n return [...new Set(facts.map((fact) => normalizeEntitySectionFact(fact)).filter((fact) => fact.length > 0))];\n}\n\nexport function collectStructuredSectionFacts(structuredSections: EntityStructuredSection[]): string[] {\n const facts: string[] = [];\n for (const section of structuredSections) {\n for (const fact of section.facts) {\n const normalized = normalizeEntitySectionFact(fact);\n if (!normalized) continue;\n facts.push(normalized);\n }\n }\n return [...new Set(facts)];\n}\n\nexport function compileEntityFacts(\n timeline: EntityTimelineEntry[],\n structuredSections: EntityStructuredSection[]\n): string[] {\n const facts: string[] = [];\n const seen = new Set<string>();\n for (const fact of dedupeEntityTimelineFacts(timeline)) {\n if (seen.has(fact)) continue;\n seen.add(fact);\n facts.push(fact);\n }\n for (const fact of collectStructuredSectionFacts(structuredSections)) {\n if (seen.has(fact)) continue;\n seen.add(fact);\n facts.push(fact);\n }\n return facts;\n}\n\nfunction parseEntityStructuredSectionFacts(\n lines: string[],\n): Pick<EntityStructuredSection, \"facts\" | \"factOrigins\"> {\n const facts: string[] = [];\n const factOrigins: Array<string | undefined> = [];\n let currentBlock: string[] = [];\n let currentOrigin: string | undefined;\n\n const flushCurrentBlock = (): void => {\n const normalized = normalizeEntitySectionFact(currentBlock.join(\" \"));\n if (normalized.length > 0) {\n facts.push(normalized);\n factOrigins.push(currentOrigin);\n }\n currentBlock = [];\n currentOrigin = undefined;\n };\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line) {\n flushCurrentBlock();\n continue;\n }\n if (line.startsWith(\"- \")) {\n flushCurrentBlock();\n const bullet = line.slice(2).trim();\n const metadataPrefix = `[${ENTITY_TIMELINE_METADATA_MARKER}] `;\n const hasMarker = bullet.startsWith(metadataPrefix);\n const originStart = metadataPrefix.length;\n const originPrefix = hasMarker && bullet.startsWith(\"[remnic-origin=\", originStart);\n const originEndOffset = originPrefix\n ? findEntityTimelineTokenEnd(bullet.slice(originStart))\n : -1;\n const originEnd = originEndOffset >= 0 ? originEndOffset + originStart : -1;\n const token = originEnd >= 0 ? bullet.slice(originStart + 15, originEnd) : \"\";\n currentBlock = [originEnd >= 0\n ? unescapeEntityTimelineText(bullet.slice(originEnd + 1).trimStart())\n : unescapeEntityTimelineText(hasMarker ? bullet.slice(metadataPrefix.length) : bullet)];\n currentOrigin = originEnd >= 0\n ? unescapeEntityTimelineMetadataValue(token)\n : undefined;\n continue;\n }\n currentBlock.push(line);\n }\n flushCurrentBlock();\n return normalizeStructuredSectionFactsWithOrigins(facts, factOrigins);\n}\nfunction looksLikeStructuredSectionFactList(lines: string[]): boolean {\n const firstNonBlank = lines.find((line) => line.trim().length > 0)?.trim() ?? \"\";\n return firstNonBlank.startsWith(\"- \");\n}\n\nexport function partitionEntityStructuredSections(\n entityType: string,\n extraSections: Array<{ title: string; lines: string[] }>,\n entitySchemas?: PluginConfig[\"entitySchemas\"]\n): {\n structuredSections: EntityStructuredSection[];\n remainingExtraSections: Array<{ title: string; lines: string[] }>;\n} {\n const structuredSections: EntityStructuredSection[] = [];\n const remainingExtraSections: Array<{ title: string; lines: string[] }> = [];\n const structuredSectionIndex = new Map<string, EntityStructuredSection>();\n\n for (const section of extraSections) {\n const matchedSection = matchEntitySchemaSection(entityType, section.title, entitySchemas);\n if (!matchedSection && !looksLikeStructuredSectionFactList(section.lines)) {\n remainingExtraSections.push(section);\n continue;\n }\n const parsedFacts = parseEntityStructuredSectionFacts(section.lines);\n if (!matchedSection && parsedFacts.facts.length === 0) {\n remainingExtraSections.push(section);\n continue;\n }\n const normalizedSection = matchedSection\n ? { key: matchedSection.key, title: matchedSection.title }\n : normalizeEntityStructuredSection(entityType, { key: section.title, title: section.title }, entitySchemas);\n if (parsedFacts.facts.length === 0) {\n remainingExtraSections.push(section);\n continue;\n }\n const existing = structuredSectionIndex.get(normalizedSection.key);\n if (existing) {\n const existingOrigins = existing.facts.map((_, index) => existing.factOrigins?.[index]);\n const incomingOrigins = parsedFacts.facts.map((_, index) => parsedFacts.factOrigins?.[index]);\n const merged = normalizeStructuredSectionFactsWithOrigins(\n [...existing.facts, ...parsedFacts.facts],\n [...existingOrigins, ...incomingOrigins],\n );\n existing.facts = merged.facts;\n existing.factOrigins = merged.factOrigins;\n continue;\n }\n const structuredSection: EntityStructuredSection = {\n key: normalizedSection.key,\n title: normalizedSection.title,\n facts: parsedFacts.facts,\n ...(parsedFacts.factOrigins ? { factOrigins: parsedFacts.factOrigins } : {}),\n };\n structuredSections.push(structuredSection);\n structuredSectionIndex.set(normalizedSection.key, structuredSection);\n }\n\n return {\n structuredSections,\n remainingExtraSections,\n };\n}\n\nexport function latestEntityTimelineTimestamp(entity: EntityFile): string | undefined {\n let latestRaw: string | undefined;\n for (const entry of entity.timeline) {\n const timestamp = entry.timestamp.trim();\n if (!timestamp) continue;\n if (!latestRaw || compareEntityTimestamps(timestamp, latestRaw) > 0) {\n latestRaw = timestamp;\n }\n }\n return latestRaw;\n}\n\nexport function compareEntityTimestamps(left?: string, right?: string): number {\n const leftValue = left?.trim() ?? \"\";\n const rightValue = right?.trim() ?? \"\";\n\n if (!leftValue && !rightValue) return 0;\n if (!leftValue) return -1;\n if (!rightValue) return 1;\n\n const leftMs = Date.parse(leftValue);\n const rightMs = Date.parse(rightValue);\n const leftParsed = Number.isFinite(leftMs);\n const rightParsed = Number.isFinite(rightMs);\n\n if (leftParsed && rightParsed) {\n if (leftMs === rightMs) return 0;\n return leftMs > rightMs ? 1 : -1;\n }\n if (leftParsed) return 1;\n if (rightParsed) return -1;\n return leftValue.localeCompare(rightValue);\n}\n\nexport function countEntityStructuredFacts(entity: EntityFile): number {\n return (entity.structuredSections ?? []).reduce((count, section) => count + section.facts.length, 0);\n}\n\nexport function fingerprintEntityStructuredFacts(entity: Pick<EntityFile, \"structuredSections\">): string | undefined {\n const normalizedSections = (entity.structuredSections ?? [])\n .map((section) => ({\n key: section.key.trim().toLowerCase(),\n title: section.title.replace(/\\s+/g, \" \").trim(),\n facts: normalizeStructuredSectionFacts(section.facts)\n .slice()\n .sort((left, right) => left.localeCompare(right)),\n }))\n .filter((section) => section.facts.length > 0)\n .sort(\n (left, right) =>\n left.key.localeCompare(right.key) ||\n left.title.localeCompare(right.title) ||\n left.facts.join(\"\\n\").localeCompare(right.facts.join(\"\\n\"))\n );\n if (normalizedSections.length === 0) return undefined;\n return createHash(\"sha256\").update(JSON.stringify(normalizedSections)).digest(\"hex\");\n}\n\nexport function isEntitySynthesisStale(entity: EntityFile): boolean {\n const structuredFactCount = countEntityStructuredFacts(entity);\n const structuredFactDigest = fingerprintEntityStructuredFacts(entity);\n const storedStructuredFactDigest = entity.synthesisStructuredFactDigest?.trim() || undefined;\n if (entity.timeline.length === 0 && structuredFactCount === 0) return false;\n if (!entity.synthesis?.trim()) return true;\n if (entity.synthesisTimelineCount === undefined) return true;\n if (structuredFactCount > 0 && entity.synthesisStructuredFactCount === undefined) return true;\n if (structuredFactCount > 0 && !storedStructuredFactDigest) return true;\n const latestTimelineTimestamp = latestEntityTimelineTimestamp(entity);\n if (!latestTimelineTimestamp) {\n return (\n entity.timeline.length > entity.synthesisTimelineCount ||\n structuredFactCount > (entity.synthesisStructuredFactCount ?? 0) ||\n structuredFactDigest !== storedStructuredFactDigest\n );\n }\n if (!entity.synthesisUpdatedAt?.trim()) return true;\n const timelineFreshness = compareEntityTimestamps(latestTimelineTimestamp, entity.synthesisUpdatedAt);\n if (timelineFreshness > 0) return true;\n return (\n entity.timeline.length > entity.synthesisTimelineCount ||\n structuredFactCount > (entity.synthesisStructuredFactCount ?? 0) ||\n structuredFactDigest !== storedStructuredFactDigest\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;AAAA,EACE,SAAAA;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,YAAAC;AAAA,EACA,QAAAC;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB,kBAAkB,WAAyB,YAAAC,iBAAgB;AACpF,SAAS,cAAAC,mBAAkB;;;AC2CpB,SAAS,yBAAyB,IAAqC;AAC5E,QAAM,QAAkB,CAAC;AACzB,MAAI,GAAG,eAAe,QAAW;AAG/B,QAAI,GAAG,eAAe,WAAW,GAAG,eAAe,WAAW;AAC5D,YAAM,IAAI;AAAA,QACR,4CAA4C,KAAK,UAAU,GAAG,UAAU,CAAC;AAAA,MAC3E;AAAA,IACF;AACA,UAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAAA,EAC3C;AACA,MAAI,GAAG,iBAAkB,OAAM,KAAK,qBAAqB,GAAG,gBAAgB,EAAE;AAC9E,SAAO;AACT;AAOO,SAAS,qBACd,IACuB;AACvB,SAAO;AAAA,IACL,YACE,GAAG,eAAe,WAAW,GAAG,eAAe,YAAY,GAAG,aAAa;AAAA,IAC7E,kBAAkB,GAAG,oBAAoB;AAAA,EAC3C;AACF;;;ADlEA,OAAOC,YAAU;;;AEpBjB,SAAS,gBAAgB;AACzB,OAAO,UAAU;AAyBV,SAAS,uCACd,MACkE;AAClE,MAAI;AACJ,MAAI;AACJ,MAAI,gBAA+B;AACnC,QAAM,4BAA4B,MAAY;AAC5C,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,MAAM,SAAS,KAAK,eAAe,CAAC,EAAE,OAAO;AAAA,IAC9D,QAAQ;AACN;AAAA,IACF;AACA,QAAI,YAAY,cAAe;AAC/B,oBAAgB;AAChB,yBAAqB;AACrB,gCAA4B;AAAA,EAC9B;AACA,SAAO,OAAO,oBAAoB;AAChC,eAAS;AACP,gCAA0B;AAK1B,YAAM,WAAW;AACjB,YAAM,YAAY,IAAI,IAAI,eAAe;AACzC,YAAM,cAAc,OAAO,uBAAuB,KAAK,+BAA+B;AACtF,UAAI,kBAAkB,SAAU;AAChC,YAAM,cAAc,YAAY;AAAA,QAAO,CAAC,aACtC,UAAU,IAAI,KAAK,SAAS,UAAU,KAAK,CAAC;AAAA,MAC9C;AACA,YAAM,WAAW,oBAAI,IAA+B;AACpD,iBAAW,UAAU,MAAM,KAAK,4BAA4B,aAAa,EAAE,GAAG;AAC5E,cAAM,KAAK,OAAO,YAAY;AAC9B,YAAI,UAAU,IAAI,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE,GAAG;AAC1C,mBAAS,IAAI,IAAI,KAAK,gCAAgC,OAAO,OAAO,CAAC;AAAA,QACvE;AAAA,MACF;AAIA,UAAI,kBAAkB,SAAU;AAChC,UAAI,SAAS,SAAS,UAAU,KAAM,QAAO;AAC7C,YAAM,OAAQ,+BAA+B,YAAY;AACvD,cAAMC,eAAc,oBAAI,IAA+B;AACvD,mBAAW,UAAU,MAAM,KAAK,4BAA4B,aAAa,EAAE,GAAG;AAC5E,gBAAM,KAAK,OAAO,YAAY;AAC9B,cAAI,CAACA,aAAY,IAAI,EAAE,GAAG;AACxB,YAAAA,aAAY,IAAI,IAAI,KAAK,gCAAgC,OAAO,OAAO,CAAC;AAAA,UAC1E;AAAA,QACF;AACA,eAAOA;AAAA,MACT,GAAG;AACH,YAAM,cAAc,MAAM;AAC1B,UAAI,kBAAkB,SAAU;AAChC,iBAAW,MAAM,WAAW;AAC1B,cAAM,UAAU,YAAY,IAAI,EAAE;AAClC,YAAI,YAAY,OAAW,UAAS,IAAI,IAAI,OAAO;AAAA,MACrD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC7EA,SAAS,OAAO,SAAS,UAAU,QAAAC,aAAY;AAC/C,OAAOC,WAAU;;;ACXjB,IAAM,sBAAsB,oBAAI,QAAqC;AAE9D,SAAS,uBAAsD,OAAU,KAAgB;AAC9F,MAAI,uCAAuC,KAAK,GAAG,EAAG,qBAAoB,IAAI,OAAO,GAAG;AACxF,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAgD;AACpF,SAAO,oBAAoB,IAAI,KAAK;AACtC;;;ACXA,SAAS,YAAY;AACrB,OAAOC,WAAU;AAiCjB,eAAsB,qBACpB,OACA,SACA,UACA,yBACmC;AACnC,MACE,QAAQ,iBAAiB,WACxB,EAAE,QAAQ,wBAAwB,SAAS,CAAC,OAAO,SAAS,QAAQ,aAAa,QAAQ,CAAC,IAC3F;AACA,UAAM,IAAI,UAAU,mCAAmC;AAAA,EACzD;AACA,MACE,SAAS,WACT,QAAQ,iBAAiB,UACzB,QAAQ,gBAAgB,UACxB,QAAQ,cAAc,UACtB,QAAQ,0BAA0B,MAClC;AACA,UAAM,SAAS,kBAAkB,SAAS,SAAS,SAAS,eAAe,SAAS,YAAY,SAAS,KAAK;AAC9G,QAAI,WAAW,MAAM;AACnB,YAAM,iBAAiB,QAAQ,aAAa,QAAQ;AACpD,YAAM,YACJ,MAAM,QAAQ;AAAA,QACZ,OAAO,IAAI,OAAO,WAAW;AAC3B,gBAAM,cAAc,MAAM,oBAAoB,MAAM;AACpD,iBAAO,gBAAgB,QAAQ,eAAe,iBAAiB,SAAS;AAAA,QAC1E,CAAC;AAAA,MACH,GACA,OAAO,CAAC,WAAiC,WAAW,IAAI;AAC1D,YAAM,WAAW,oBAAoB,UAAU,SAAS,OAAO;AAC/D,aAAO,EAAE,UAAU,wBAAwB,QAAQ,GAAG,WAAW,SAAS,IAAI,CAAC,WAAW,OAAO,IAAI,EAAE;AAAA,IACzG;AAAA,EACF;AACA,QAAM,SAAS,MAAM,MAAM,mBAAmB,OAAO;AACrD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,wBAAwB,OAAO,QAAQ;AAAA,EACnD;AACF;AAEA,eAAe,oBAAoB,QAA4C;AAC7E,QAAM,cAAc,sBAAsB,MAAM;AAChD,QAAM,mBAAmB,aAAa,MAAM,wCAAwC,IAAI,CAAC;AACzF,QAAM,eACJ,kBAAkB,MAAM,uCAAuC,IAAI,CAAC,KACpE,kBAAkB,MAAM,uCAAuC,IAAI,CAAC,KACpE,OAAO,YAAY,WACnB,OAAO,YAAY;AACrB,QAAM,cAAc,OAAO,iBAAiB,WAAW,KAAK,MAAM,aAAa,KAAK,CAAC,IAAI,OAAO;AAChG,MAAI,OAAO,SAAS,WAAW,EAAG,QAAO;AACzC,MAAI;AACF,YAAQ,MAAM,KAAK,OAAO,IAAI,GAAG;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,oBAAoB,UAAwB,SAA+B;AAClF,QAAM,kBAAkBC,MAAK,KAAK,SAAS,aAAa;AACxD,QAAM,cAAc,SACjB,OAAO,CAAC,WAAW,OAAO,SAAS,mBAAmB,OAAO,KAAK,WAAW,GAAG,eAAe,GAAGA,MAAK,GAAG,EAAE,CAAC,EAC7G,KAAK,CAAC,MAAM,UAAU,MAAM,KAAK,cAAc,KAAK,IAAI,CAAC;AAC5D,QAAM,QAAQ,SACX,OAAO,CAAC,WAAW,OAAO,SAAS,mBAAmB,CAAC,OAAO,KAAK,WAAW,GAAG,eAAe,GAAGA,MAAK,GAAG,EAAE,CAAC,EAC9G,KAAK,CAAC,MAAM,UAAU,MAAM,KAAK,cAAc,KAAK,IAAI,CAAC;AAC5D,QAAM,UAAwB,CAAC;AAC/B,WAAS,QAAQ,GAAG,QAAQ,KAAK,IAAI,YAAY,QAAQ,MAAM,MAAM,GAAG,SAAS,GAAG;AAClF,UAAM,aAAa,YAAY,KAAK;AACpC,QAAI,WAAY,SAAQ,KAAK,UAAU;AACvC,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,KAAM,SAAQ,KAAK,IAAI;AAAA,EAC7B;AACA,SAAO;AACT;;;AFfA,SAAS,wBAAwB,KAAuB;AACtD,QAAM,OAAQ,IAA8B;AAC5C,SAAO,OAAO,SAAS,YAAY,SAAS;AAC9C;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YACmB,MACjB;AADiB;AAAA,EAChB;AAAA,EADgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOnB,MAAM,2BACJ,UACkD;AAClD,UAAM,OAAgD,CAAC;AACvD,QAAI;AACJ,QAAI,aAAa,QAAW;AAC1B,gBAAU,CAAC,QAAQ;AAAA,IACrB,OAAO;AACL,UAAI;AACF,cAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,cAAc,EAAE,eAAe,KAAK,CAAC;AAC7E,kBAAU,QACP,OAAO,CAAC,UAAU,MAAM,YAAY,CAAC,EACrC,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,MAC9B,SAAS,KAAK;AACZ,YAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,cAAM;AAAA,MACR;AAAA,IACF;AACA,eAAW,UAAU,SAAS;AAC5B,UAAI,CAAC,yBAAyB,KAAK,MAAM,EAAG;AAC5C,UAAI;AACJ,UAAI;AACF,kBAAU,MAAM,QAAQC,MAAK,KAAK,KAAK,KAAK,cAAc,MAAM,CAAC;AAAA,MACnE,SAAS,KAAK;AACZ,YAAK,IAA8B,SAAS,SAAU;AACtD,cAAM;AAAA,MACR;AACA,iBAAW,SAAS,SAAS;AAC3B,YAAI,CAAC,MAAM,SAAS,KAAK,EAAG;AAC5B,cAAM,OAAO,MAAM,MAAM,GAAG,EAAE;AAC9B,YAAI,CAAC,sBAAsB,IAAI,EAAG;AAClC,aAAK,KAAK,EAAE,QAAQ,KAAK,CAAC;AAAA,MAC5B;AAAA,IACF;AACA,SAAK,KAAK,CAAC,GAAG,MAAM;AAClB,UAAI,EAAE,OAAO,EAAE,KAAM,QAAO;AAC5B,UAAI,EAAE,OAAO,EAAE,KAAM,QAAO;AAC5B,UAAI,EAAE,SAAS,EAAE,OAAQ,QAAO;AAChC,UAAI,EAAE,SAAS,EAAE,OAAQ,QAAO;AAChC,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,uBAAuB,SAAoD;AAC/E,yBAAqB,OAAO;AAC5B,QACE,KAAK,KAAK,sBACV,KAAK,IAAI,IAAI,KAAK,KAAK,mBAAmB,cAAc,KAAK,KAAK,oBAAoB,+BACtF,KAAK,KAAK,mBAAmB,iBAAiB,KAAK,KAAK,wBAAwB,GAChF;AACA,aAAO,KAAK,KAAK,mBAAmB;AAAA,IACtC;AAEA,UAAM,gBAAgB,YAAmC;AACvD,YAAM,YAA0B,CAAC;AACjC,YAAM,UAAU,OAAO,QAAgB;AACrC,YAAI;AACF,gBAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,qBAAW,SAAS,SAAS;AAI3B,iCAAqB,OAAO;AAC5B,kBAAM,WAAWA,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,gBAAI,MAAM,YAAY,GAAG;AACvB,oBAAM,QAAQ,QAAQ;AACtB;AAAA,YACF;AACA,gBAAI,CAAC,MAAM,KAAK,SAAS,KAAK,EAAG;AACjC,kBAAM,SAAS,MAAM,KAAK,KAAK,iBAAiB,QAAQ;AACxD,gBAAI,CAAC,OAAQ;AACb,sBAAU,KAAK,MAAM;AAAA,UACvB;AAAA,QACF,SAAS,KAAK;AAGZ,cAAI,aAAa,GAAG,EAAG,OAAM;AAAA,QAE/B;AAAA,MACF;AACA,YAAM,QAAQ,KAAK,KAAK,YAAY;AACpC,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB;AAC5B,QAAI,kBAAgC,CAAC;AACrC,aAAS,UAAU,GAAG,WAAW,qBAAqB,WAAW,GAAG;AAClE,2BAAqB,OAAO;AAC5B,YAAM,gBAAgB,KAAK,KAAK,wBAAwB;AACxD,YAAM,YAAY,MAAM,cAAc;AACtC,YAAM,eAAe,KAAK,KAAK,wBAAwB;AACvD,wBAAkB;AAGlB,2BAAqB,OAAO;AAC5B,UAAI,iBAAiB,eAAe;AAClC,aAAK,KAAK,qBAAqB,EAAE,UAAU,WAAW,YAAY,KAAK,IAAI,GAAG,cAAc,aAAa;AACzG,eAAO;AAAA,MACT;AAAA,IACF;AAIA,SAAK,KAAK,qBAAqB;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,8BACZ,WACA,sBAAsB,OACtB,SACmB;AACnB,UAAM,YAAsB,CAAC;AAG7B,QAAI;AACJ,QAAI;AACF,uBAAiB,MAAM,SAAS,KAAK,KAAK,OAAO;AAAA,IACnD,SAAS,KAAK;AAIZ,UAAI,uBAAuB,wBAAwB,GAAG,EAAG,OAAM;AAC/D,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,OAAO,QAA+B;AACzD,2BAAqB,OAAO;AAK5B,UAAI;AACJ,UAAI;AACF,kBAAU,MAAM,MAAM,GAAG;AAAA,MAC3B,SAAS,KAAK;AAGZ,YAAI,uBAAuB,wBAAwB,GAAG,EAAG,OAAM;AAC/D;AAAA,MACF;AACA,UAAI,QAAQ,eAAe,EAAG;AAC9B,UAAI,CAAC,QAAQ,YAAY,GAAG;AAK1B,YAAI,qBAAqB;AACvB,gBAAM,IAAI,MAAM,kEAAkE,GAAG,EAAE;AAAA,QACzF;AACA;AAAA,MACF;AACA,UAAI;AACJ,UAAI;AACF,6BAAqB,gBAAgB,MAAM,SAAS,GAAG,GAAG,GAAG;AAC7D,kBAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,MACtD,SAAS,KAAK;AAIZ,YAAI,uBAAuB,wBAAwB,GAAG,EAAG,OAAM;AAC/D;AAAA,MACF;AAEA,YAAM,UAAoB,CAAC;AAC3B,iBAAW,SAAS,SAAS;AAI3B,6BAAqB,OAAO;AAE5B,YAAI,MAAM,eAAe,EAAG;AAC5B,cAAM,WAAWA,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,YAAI,MAAM,YAAY,GAAG;AACvB,kBAAQ,KAAK,QAAQ;AAAA,QACvB,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;AAOrC,cAAI;AACF,iCAAqB,gBAAgB,MAAM,SAAS,QAAQ,GAAG,QAAQ;AACvE,sBAAU,KAAK,QAAQ;AAAA,UACzB,SAAS,KAAK;AAIZ,gBAAI,uBAAuB,wBAAwB,GAAG,EAAG,OAAM;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAGA,iBAAW,UAAU,SAAS;AAC5B,cAAM,aAAa,MAAM;AAAA,MAC3B;AAAA,IACF;AAEA,eAAW,OAAO,WAAW;AAC3B,YAAM,aAAa,GAAG;AAAA,IACxB;AAGA,yBAAqB,OAAO;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,yBACJ,SACmB;AA2BnB,WAAO,KAAK;AAAA,MACV,qBAAqB,IAAI,CAAC,QAAQA,MAAK,KAAK,KAAK,KAAK,SAAS,GAAG,CAAC;AAAA,MACnE,SAAS,uBAAuB;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,uBACJ,SACmB;AACnB,WAAO,KAAK;AAAA,MACV,CAAC,KAAK,KAAK,mBAAmB,MAAM,CAAC;AAAA,MACrC,SAAS,uBAAuB;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iCAAoD;AACxD,UAAM,QAAQ,MAAM,QAAQ,IAAI;AAAA,MAC9B,KAAK,yBAAyB;AAAA,MAC9B,KAAK,uBAAuB;AAAA,MAC5B,KAAK,8BAA8B,CAACA,MAAK,KAAK,KAAK,KAAK,SAAS,SAAS,CAAC,CAAC;AAAA,IAC9E,CAAC;AACD,WAAO,MAAM,KAAK;AAAA,EACpB;AAAA,EAEA,MAAM,mBAAmB,UAIrB,CAAC,GAA6D;AAChE,UAAM,WAAW,MAAM,KAAK,KAAK,yBAAyB;AAC1D,UAAM,cAAc,KAAK,KAAK,iBAAiB,QAAQ;AACvD,UAAM,cACJ,OAAO,QAAQ,gBAAgB,YAAY,OAAO,SAAS,QAAQ,WAAW,IAC1E,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,WAAW,CAAC,IAC3C;AACN,UAAM,oBAAoB,gBAAgB,SAAY,SAAY,cAAc;AAChF,UAAM,iBAAiB,QAAQ,cAAc,QAAQ;AACrD,UAAM,sBAAsB,KAAK,KAAK,6BAA6B,QAAQ,SAAS;AACpF,UAAM,WAAyB,CAAC;AAChC,UAAM,gBAA0B,CAAC;AAEjC,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK,qBAAqB;AAChE,UACE,gBAAgB,WACZ,SAAS,UAAU,eAAgB,sBAAsB,UAAa,cAAc,UAAU,oBAClG;AACA,eAAO,EAAE,UAAU,WAAW,cAAc;AAAA,MAC9C;AACA,YAAM,aAAa,YAAY,MAAM,GAAG,IAAI,mBAAmB;AAC/D,YAAM,sBAAsB,mBAAmB,SAC3C,aACA,MAAM,KAAK,KAAK,gCAAgC,YAAY,cAAc;AAC9E,YAAM,iBAAiB,gBAAgB,SAAY,SAAY,KAAK,IAAI,GAAG,cAAc,SAAS,MAAM;AACxG,YAAM,4BAA4B,sBAAsB,SAAY,SAAY,KAAK,IAAI,GAAG,oBAAoB,cAAc,MAAM;AACpI,YAAM,EAAE,UAAU,eAAe,WAAW,qBAAqB,IAAI,mBAAmB,SACpF;AAAA,QACE,UAAU,MAAM,KAAK,KAAK,4BAA4B,qBAAqB,mBAAmB;AAAA,QAC9F,WAAW;AAAA,MACb,IACA,MAAM,KAAK,KAAK;AAAA,QACd;AAAA,QACA;AAAA,QACA,6BAA6B;AAAA,QAC7B;AAAA,MACF;AACJ,oBAAc,KAAK,GAAG,oBAAoB;AAC1C,iBAAW,UAAU,eAAe;AAClC,iBAAS,KAAK,MAAM;AACpB,YAAI,gBAAgB,UAAa,SAAS,UAAU,aAAa;AAC/D,iBAAO,EAAE,UAAU,WAAW,cAAc;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,WAAW,cAAc;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BA,MAAM,sBAA6C;AACjD,UAAM,WAAW,KAAK,KAAK,mBAAmB,MAAM;AAMpD,UAAM,qBAAqB,KAAK,KAAK,qBAAqB;AAM1D,UAAM,QAAQ,KAAK,KAAK,cAAc;AACtC,UAAM,SAAS,KAAK,KAAK,oBAAoB,kBAAkB,IAAI,QAAQ;AAC3E,QACE,UACA,OAAO,UAAU,SACjB,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,KAAK,oBAAoB,0BAC7D,OAAO,gBAAgB,oBACvB;AACA,aAAO,OAAO;AAAA,IAChB;AAEA,UAAM,YAAsB,CAAC;AAE7B,UAAM,eAAe,OAAO,QAAgB;AAC1C,UAAI;AACF,cAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,cAAM,UAAoB,CAAC;AAC3B,mBAAW,SAAS,SAAS;AAC3B,gBAAM,WAAWA,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,cAAI,MAAM,YAAY,GAAG;AACvB,oBAAQ,KAAK,QAAQ;AAAA,UACvB,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;AACrC,sBAAU,KAAK,QAAQ;AAAA,UACzB;AAAA,QACF;AACA,mBAAW,UAAU,SAAS;AAC5B,gBAAM,aAAa,MAAM;AAAA,QAC3B;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAOA,UAAM,aAAa,QAAQ;AAC3B,UAAM,WAAW,MAAM,KAAK,KAAK,4BAA4B,WAAW,EAAE;AAI1E,SAAK,KAAK,oBAAoB,kBAAkB,IAAI,UAAU,EAAE,UAAU,UAAU,KAAK,IAAI,GAAG,aAAa,oBAAoB,MAAM,CAAC;AACxI,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,iBAAiB,UAA8C;AACnE,QAAI;AACF,YAAM,MAAM,MAAM,uBAAuB,UAAU,KAAK,KAAK,iBAAiB,KAAK,KAAK,OAAO;AAG/F,YAAM,SAAS,iBAAiB,GAAG;AACnC,UAAI,QAAQ;AACV,eAAO,uBAAuB;AAAA,UAC5B,MAAM;AAAA,UACN,aAAa;AAAA,YACX,OAAO;AAAA,YACP,gBAAgB,KAAK,KAAK,SAAS,QAAQ;AAAA,YAC3C,OAAO;AAAA,UACT;AAAA,UACA,SAAS,OAAO;AAAA,QAClB,GAAG,GAAG;AAAA,MACR;AAMA,YAAM,iBAAiB,SAAS,MAAMA,MAAK,GAAG,EAAE,KAAK,GAAG;AACxD,UAAI,eAAe,SAAS,YAAY,KAAK,SAAS,SAAS,KAAK,GAAG;AACrE,cAAM,SAAS,gBAAgB,KAAK,KAAK,KAAK,aAAa;AAC3D,YAAI,CAAC,OAAO,KAAM,QAAO;AACzB,cAAM,iBAAiBA,MAAK,SAAS,UAAU,KAAK;AAOpD,cAAM,YAAY,OAAO,WACpB,MAAMC,MAAK,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,CAAC,EAAE,MAAM,OAAM,oBAAI,KAAK,CAAC,GAAE,YAAY,CAAC;AAClG,eAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,YACX,IAAI;AAAA,YACJ,UAAU;AAAA,YACV,SAAS;AAAA,YACT,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,gBAAgB,eAAe,GAAG;AAAA,YAClC,MAAM,OAAO,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;AAAA,UACvC;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,KAAK;AAKZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,2BACJ,QACiB;AACjB,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,KAAK,kBAAkB;AAElC,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,UAAU,OACb,IAAI,CAAC,UAAU;AACd,YAAM,aAAkC;AAAA,QACtC,GAAG;AAAA,QACH,OAAO;AAAA,QACP,WACE,MAAM,aAAa,MAAM,UAAU,SAAS,IACxC,MAAM,YACN;AAAA,MACR;AACA,aAAO,GAAG,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,IACtC,CAAC,EACA,KAAK,EAAE;AAEV,UAAM,KAAK,KAAK,wBAAwB,KAAK,KAAK,0BAA0B,OAAO;AACnF,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiCA,MAAM,yBACJ,UAA8B,CAAC,GACC;AAChC,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,KAAK,KAAK,sBAAsB,KAAK,KAAK,wBAAwB;AAAA,IAChF,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,YAAM,OAAQ,IAA8B;AAC5C,UAAI,SAAS,SAAU,QAAO,CAAC;AAC/B,YAAM;AAAA,IACR;AASA,QAAI,iBAAgC;AACpC,QAAI,QAAQ,UAAU,QAAW;AAC/B,UACE,OAAO,QAAQ,UAAU,YACzB,CAAC,OAAO,SAAS,QAAQ,KAAK,KAC9B,QAAQ,SAAS,GACjB;AACA,eAAO,CAAC;AAAA,MACV;AACA,YAAM,UAAU,KAAK,MAAM,QAAQ,KAAK;AACxC,UAAI,WAAW,EAAG,QAAO,CAAC;AAC1B,uBAAiB;AAAA,IACnB;AAEA,UAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,UAAM,SAAgC,CAAC;AACvC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,QAAQ,WAAW,EAAG;AAC1B,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,OAAO;AACjC,YAAI,2BAA2B,MAAM,GAAG;AACtC,iBAAO,KAAK,MAAM;AAAA,QACpB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO;AAAA,MACL,CAAC,MAAM,UAAU,KAAK,MAAM,KAAK,SAAS,IAAI,KAAK,MAAM,MAAM,SAAS;AAAA,IAC1E;AAEA,QAAI,mBAAmB,KAAM,QAAO;AAKpC,WAAO,OAAO,MAAM,CAAC,cAAc;AAAA,EACrC;AAAA,EAEA,MAAM,kCACJ,UACoD;AACpD,UAAM,6BAA6B,CAAC,UAClC,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,OAAO,UAAU,KAAK,KAAK,SAAS;AAC7F,UAAM,uBAAuB,CAC3B,UACwF;AACxF,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,YAAM,UAAU;AAChB,aACE,OAAO,QAAQ,WAAW,YAC1B,2BAA2B,QAAQ,KAAK,KACxC,QAAQ,aAAa,QACrB,OAAO,QAAQ,aAAa,YAC5B,2BAA2B,QAAQ,SAAS,OAAO,KACnD,2BAA2B,QAAQ,SAAS,OAAO,KACnD,2BAA2B,QAAQ,SAAS,MAAM,KAClD,QAAQ,YAAY,QACpB,OAAO,QAAQ,YAAY,YAC3B,2BAA2B,QAAQ,QAAQ,IAAI,KAC/C,2BAA2B,QAAQ,QAAQ,IAAI,KAC/C,2BAA2B,QAAQ,QAAQ,OAAO;AAAA,IAEtD;AACA,UAAM,oBAAoB,CACxB,UACoF;AACpF,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,YAAM,OAAO;AACb,aACE,OAAO,KAAK,WAAW,YACvB,OAAO,KAAK,UAAU,YACtB,OAAO,SAAS,KAAK,KAAK,MACzB,KAAK,cAAc,cAAc,KAAK,cAAc,cAAc,KAAK,cAAc,YACrF,KAAK,eAAe,SAAS,KAAK,eAAe,YAAY,KAAK,eAAe,WAClF,MAAM,QAAQ,KAAK,KAAK,KACxB,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ;AAAA,IAEvD;AAEA,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAC1D,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,YAAM,eAAe,QAAQ;AAC7B,YAAM,cAAc,QAAQ;AAC5B,YAAM,kBACJ,QAAQ,oBAAoB,WAAW,QAAQ,oBAAoB,WAC/D,OAAO,kBACP;AACN,YAAM,cACJ,OAAO,QAAQ,gBAAgB,YAAY,OAAO,YAAY,SAAS,IACnE,OAAO,cACP;AACN,YAAM,kBAAkB,MAAM,QAAQ,QAAQ,eAAe,IACzD,OAAO,gBAAgB,OAAO,oBAAoB,IAClD;AACJ,YAAM,cAAc,MAAM,QAAQ,QAAQ,WAAW,IACjD,OAAO,YAAY,OAAO,iBAAiB,IAC3C;AACJ,UACE,CAAC,2BAA2B,QAAQ,OAAO,KAC3C,OAAO,QAAQ,cAAc,YAC7B,OAAO,UAAU,WAAW,KAC5B,CAAC,gBACD,OAAO,aAAa,SAAS,YAC7B,aAAa,KAAK,WAAW,KAC7B,OAAO,aAAa,OAAO,YAC3B,aAAa,GAAG,WAAW,KAC3B,CAAC,eACD,CAAC,2BAA2B,YAAY,KAAK,KAC7C,CAAC,2BAA2B,YAAY,OAAO,KAC/C,CAAC,2BAA2B,YAAY,OAAO,KAC/C,CAAC,2BAA2B,YAAY,MAAM,KAC9C,CAAC,2BAA2B,QAAQ,gBAAgB,GACpD;AACA,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,SAAS,OAAO;AAAA,QAChB,WAAW,OAAO;AAAA,QAClB,cAAc;AAAA,UACZ,MAAM,aAAa;AAAA,UACnB,IAAI,aAAa;AAAA,QACnB;AAAA,QACA,aAAa;AAAA,UACX,OAAO,YAAY;AAAA,UACnB,SAAS,YAAY;AAAA,UACrB,SAAS,YAAY;AAAA,UACrB,QAAQ,YAAY;AAAA,QACtB;AAAA,QACA,kBAAkB,OAAO;AAAA,QACzB,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,QACrC,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,QAC7C,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,QAC7C,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,MACvC;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,MAWA;AACA,UAAM,WAAW,KAAK,KAAK;AAC3B,UAAM,SAAS,KAAK,KAAK,oBAAoB,eAAe,IAAI,QAAQ;AACxE,QAAI,UAAU,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,KAAK,oBAAoB,wBAAwB;AAGjG,UAAI;AACF,cAAM,UAAU,MAAMA,MAAK,KAAK,KAAK,YAAY;AACjD,YAAI,QAAQ,WAAW,OAAO,UAAU;AACtC,gBAAM,MAAM,OAAO;AACnB,iBAAO,MAAM,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,IAAI;AAAA,QACjE;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ,MAAM,QAAQ,KAAK,KAAK,YAAY;AAClD,YAAM,YAAY,CAAC;AACnB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,SAAS,KAAK,EAAG;AAC3B,cAAM,WAAWD,MAAK,KAAK,KAAK,KAAK,cAAc,IAAI;AACvD,cAAM,MAAM,MAAM,uBAAuB,UAAU,KAAK,KAAK,iBAAiB,KAAK,KAAK,OAAO;AAC/F,cAAM,SAAS,KAAK,KAAK,kBAAkB,KAAK,QAAQ;AACxD,YAAI,QAAQ;AACV,oBAAU,KAAK,MAAM;AAAA,QACvB;AAAA,MACF;AACA,YAAM,SAAS,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAC/D,WAAK,KAAK,oBAAoB,eAAe,IAAI,UAAU,EAAE,WAAW,QAAQ,UAAU,KAAK,IAAI,EAAE,CAAC;AACtG,aAAO,MAAM,iBAAiB,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,IAAI;AAAA,IACpE,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;;;AG51BA,eAAe,mBAAmB,WAA0D;AAC1F,QAAM,UAAU,aAAa,EAAE,MAAM,CAAC,UAAU;AAC9C,QAAI,KAAK,0CAA0C,UAAU,QAAQ,KAAK,KAAK,EAAE;AAAA,EACnF,CAAC;AACH;AAEA,eAAsB,yBACpB,WACkB;AAClB,MAAI,oBAAoB;AACxB,MAAI;AACF,UAAM,UAAU,cAAc;AAC9B,QAAI,CAAC,MAAM,UAAU,aAAa,GAAG;AACnC,YAAM,mBAAmB,SAAS;AAClC,aAAO;AAAA,IACT;AACA,wBAAoB;AACpB,UAAM,UAAU,YAAY;AAC5B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,CAAC,kBAAmB,OAAM,mBAAmB,SAAS;AAC1D,UAAM;AAAA,EACR;AACF;;;ACjCA,IAAM,sBAAsB;AAC5B,IAAM,gBAAgB;AACtB,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,mCAAmC;AACzC,IAAM,0BAA0B;AAChC,IAAM,4BAA4B;AAClC,IAAM,uBAAuB;AAC7B,IAAM,0BACJ;AACF,IAAM,gCAAgC;AACtC,IAAM,uCACJ;AACF,IAAM,mDACJ;AACF,IAAM,WAAW;AASjB,SAAS,oBAAoB,MAAuB;AAClD,QAAM,aAAa,KAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,CAAC,IAAI;AAC/D,MAAI,mBAAmB,UAAU,EAAG,QAAO;AAC3C,SAAO,oBAAoB,KAAK,WAAW,KAAK,CAAC;AACnD;AAEA,SAAS,mBAAmB,MAAuB;AACjD,MAAI,cAAc;AAClB,SAAO,KAAK,WAAW,MAAM,IAAK,gBAAe;AACjD,SAAO,eAAe,KAAK,KAAK,WAAW,MAAM;AACnD;AAEA,SAAS,eAAe,MAAkC;AACxD,MAAI,cAAc;AAClB,SAAO,KAAK,WAAW,MAAM,IAAK,gBAAe;AACjD,MAAI,cAAc,KAAK,KAAK,WAAW,MAAM,IAAM,QAAO;AAC1D,QAAM,UAAU,KAAK,MAAM,WAAW;AACtC,QAAM,YAAY,QAAQ,CAAC;AAC3B,MAAI,cAAc,OAAO,cAAc,IAAK,QAAO;AACnD,MAAI,SAAS;AACb,SAAO,QAAQ,MAAM,MAAM,UAAW,WAAU;AAChD,MAAI,SAAS,EAAG,QAAO;AACvB,QAAM,WAAW,QAAQ,MAAM,MAAM;AACrC,MAAI,cAAc,OAAO,SAAS,SAAS,GAAG,EAAG,QAAO;AACxD,SAAO,EAAE,aAAa,WAAW,QAAQ,SAAS;AACpD;AAEA,SAAS,eAAe,OAAoB,WAAiC;AAC3E,SACE,MAAM,cAAc,UAAU,aAC9B,MAAM,UAAU,UAAU,UAC1B,MAAM,SAAS,KAAK,MAAM;AAE9B;AAEA,IAAM,sBAAsB,CAAC,OAAO,YAAY,UAAU,OAAO;AACjE,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAYA,SAAS,iBAAiB,MAAc,MAAwC;AAC9E,QAAM,YAAY,KAAK,WAAW,IAAI;AACtC,QAAM,YAAY,YAAY,IAAI;AAClC,aAAW,OAAO,MAAM;AACtB,UAAM,gBAAgB,KAAK,YAAY,IAAI,MAAM;AACjD,UAAM,qBACJ,CAAC,aAAa,kBAAkB,OAAO,KAAK,YAAY,IAAI,SAAS,CAAC,MAAM;AAC9E,QACE,KAAK,WAAW,GAAG,YAAY,OAAO,GAAG,GAAG,GAAG,EAAE,MAChD,kBAAkB,UACjB,kBAAkB,OAClB,sBACA,kBAAkB,OAClB,kBAAkB,MACpB;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,cAAc,WAA4B;AACjD,SACG,aAAa,OAAO,aAAa,OACjC,aAAa,OAAO,aAAa;AAEtC;AAEA,SAAS,uBAAuB,WAA4B;AAC1D,SACE,cAAc,SAAS,KACtB,aAAa,OAAO,aAAa,OAClC,cAAc;AAElB;AACA,IAAM,kBACJ;AAEF,SAAS,0BAA0B,eAAuB,WAA6B;AACrF,QAAM,UAAU,cAAc,KAAK;AACnC,MAAI,aAAa,YAAY,GAAI,QAAO,YAAY;AACpD,QAAM,0BAA0B,QAAQ,SAAS,GAAG,IAChD,QAAQ,MAAM,GAAG,EAAE,EAAE,QAAQ,IAC7B;AACJ,SAAO,4BAA4B,MAAM,gBAAgB,KAAK,uBAAuB;AACvF;AAEA,SAAS,oBAAoB,MAA8B;AACzD,MAAI,QAAQ;AACZ,QAAM,YAAY,KAAK,KAAK,MAAM;AAClC,MAAI,UAAW,UAAS;AACxB,QAAM,YAAY;AAClB,MAAI,CAAC,cAAc,KAAK,KAAK,KAAK,EAAE,EAAG,QAAO;AAC9C,SAAO,uBAAuB,KAAK,KAAK,KAAK,EAAE,EAAG,UAAS;AAC3D,QAAM,gBAAgB,KAAK,KAAK,KAAK;AACrC,MACE,kBAAkB,OAClB,kBAAkB,OAClB,kBAAkB,OAClB,kBAAkB,KAClB;AACA,WAAO;AAAA,EACT;AACA,QAAM,OAAO,KAAK,MAAM,WAAW,KAAK,EAAE,YAAY;AACtD,MAAI,QAAuB;AAC3B,SAAO,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACtC,UAAM,YAAY,KAAK,KAAK;AAC5B,QAAI,OAAO;AACT,UAAI,cAAc,MAAO,SAAQ;AACjC;AAAA,IACF;AACA,QAAI,cAAc,OAAQ,cAAc,KAAK;AAC3C,cAAQ;AACR;AAAA,IACF;AACA,QAAI,cAAc,OAAO,KAAK,MAAM,QAAQ,CAAC,EAAE,KAAK,MAAM,IAAI;AAC5D,YAAM,UAAU,KAAK,MAAM,WAAW,KAAK,EAAE,QAAQ;AACrD,UAAI,CAAC,0BAA0B,QAAQ,MAAM,KAAK,MAAM,GAAG,SAAS,EAAG,QAAO;AAC9E,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,eAAe,CAAC,aAAa,QAAQ,SAAS,GAAG;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AACA,SAAS,kBAAkB,MAA8B;AACvD,MAAI,QAAuB;AAC3B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,YAAY,KAAK,KAAK;AAC5B,QAAI,OAAO;AACT,UAAI,cAAc,MAAO,SAAQ;AACjC;AAAA,IACF;AACA,QAAI,cAAc,OAAQ,cAAc,KAAK;AAC3C,cAAQ;AACR;AAAA,IACF;AACA,QAAI,cAAc,IAAK;AACvB,WAAO,oBAAoB,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAGA,SAAS,aAAa,MAAyB;AAC7C,QAAM,OAAkB,CAAC;AACzB,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,QAAQ;AAC1B,QAAI,KAAK,KAAK,MAAM,KAAK;AACvB,eAAS;AACT;AAAA,IACF;AAEA,QAAI,SAAS,QAAQ;AACrB,UAAM,YAAY,KAAK,MAAM,MAAM;AACnC,QAAI,UAAW,WAAU;AACzB,UAAM,YAAY;AAClB,QAAI,CAAC,cAAc,KAAK,MAAM,KAAK,EAAE,GAAG;AACtC,eAAS;AACT;AAAA,IACF;AACA,WAAO,uBAAuB,KAAK,MAAM,KAAK,EAAE,EAAG,WAAU;AAC7D,UAAM,OAAO,KAAK,MAAM,WAAW,MAAM,EAAE,YAAY;AACvD,QAAI,QAAuB;AAC3B,WAAO,SAAS,KAAK,QAAQ,UAAU,GAAG;AACxC,YAAM,YAAY,KAAK,MAAM,KAAK;AAClC,UAAI,OAAO;AACT,YAAI,cAAc,MAAO,SAAQ;AACjC;AAAA,MACF;AACA,UAAI,cAAc,OAAQ,cAAc,KAAK;AAC3C,gBAAQ;AACR;AAAA,MACF;AACA,UAAI,cAAc,IAAK;AACvB,YAAM,UAAU,KAAK,MAAM,WAAW,MAAM,EAAE,QAAQ;AACtD,WAAK,KAAK;AAAA,QACR;AAAA,QACA;AAAA,QACA,eAAe,CAAC,aAAa,QAAQ,SAAS,GAAG;AAAA,MACnD,CAAC;AACD,cAAQ,SAAS;AACjB;AAAA,IACF;AACA,QAAI,UAAU,KAAK,OAAQ;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAAS,qBACP,WACA,MACA,kBACsB;AACtB,MAAI,CAAC,UAAU,QAAS,QAAO;AAC/B,MAAI,QAAQ,UAAU;AACtB,MAAI,sBAAsB,CAAC;AAC3B,aAAW,OAAO,aAAa,IAAI,GAAG;AACpC,QAAI,IAAI,SAAS,UAAU,QAAS;AACpC,QAAI,IAAI,WAAW;AACjB,eAAS;AAAA,IACX,WAAW,CAAC,IAAI,eAAe;AAC7B,UAAI,CAAC,qBAAqB;AACxB,8BAAsB;AACtB;AAAA,MACF;AACA,eAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,QAAQ,EAAG,QAAO,EAAE,GAAG,WAAW,MAAM;AAC5C,SAAO,UAAU,kBACb,EAAE,GAAG,WAAW,WAAW,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO,EAAE,IAChF;AACN;AAEA,SAAS,0BAA0B,MAAuB;AACxD,SAAO,WAAW,KAAK,IAAI;AAC7B;AACA,SAAS,mBACP,gBACA,aACA,uBACkB;AAClB,QAAM,SAAS,iBAAiB,gBAAgB,mBAAmB;AACnE,MAAI,QAAQ;AACV,UAAM,cACJ,oBAAoB,WAAW,KAAK,kBAAkB,WAAW;AACnE,QAAI,CAAC,eAAe,eAAe,WAAW,IAAI,EAAG,QAAO;AAC5D,QAAI,aAAa,iBAAiB,CAAC,0BAA0B,WAAW,EAAG,QAAO;AAClF,UAAM,YAAY,KAAK,MAAM;AAC7B,QAAI,sBAAsB,gBAAgB,SAAS,GAAG;AACpD,UAAI,CAAC,eAAe,YAAY,UAAW,QAAO;AAClD,aAAO,EAAE,WAAW,iBAAiB,OAAO,SAAS,MAAM,OAAO,EAAE;AAAA,IACtE;AACA,WAAO,EAAE,WAAW,iBAAiB,OAAO,SAAS,MAAM,OAAO,EAAE;AAAA,EACtE;AACA,MAAI,eAAe,WAAW,MAAM,GAAG;AACrC,WAAO,EAAE,WAAW,OAAO,iBAAiB,OAAO,SAAS,MAAM,OAAO,EAAE;AAAA,EAC7E;AACA,MAAI,eAAe,WAAW,IAAI,GAAG;AACnC,WAAO,EAAE,WAAW,MAAM,iBAAiB,OAAO,SAAS,MAAM,OAAO,EAAE;AAAA,EAC5E;AACA,MAAI,YAAY,WAAW,WAAW,GAAG;AACvC,WAAO,EAAE,WAAW,OAAO,iBAAiB,OAAO,SAAS,MAAM,OAAO,EAAE;AAAA,EAC7E;AACA,QAAM,mBAAmB,YAAY,CAAC;AACtC,MACE,YAAY,WAAW,IAAI,KAC3B,oBACA,oBAAoB,OACpB,oBAAoB,KACpB;AACA,WAAO,EAAE,WAAW,KAAK,iBAAiB,OAAO,SAAS,MAAM,OAAO,EAAE;AAAA,EAC3E;AACA,QAAM,WAAW,iBAAiB,gBAAgB,eAAe;AACjE,MAAI,UAAU;AACZ,UAAM,cACJ,oBAAoB,WAAW,KAAK,kBAAkB,WAAW;AACnE,QAAI,CAAC,aAAa;AAChB,aAAO,EAAE,WAAW,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO,EAAE;AAAA,IAC3E;AACA,QAAI,YAAY,eAAe;AAC7B,aAAO,EAAE,WAAW,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO,EAAE;AAAA,IAC3E;AACA,WAAO,EAAE,WAAW,KAAK,QAAQ,KAAK,iBAAiB,MAAM,SAAS,UAAU,OAAO,EAAE;AAAA,EAC3F;AACA,MAAI,CAAC,sBAAuB,QAAO;AACnC,QAAM,aAAa,oBAAoB,WAAW;AAClD,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,WAAW,aAAa,WAAW,eAAe;AACpD,WAAO,EAAE,WAAW,MAAM,iBAAiB,MAAM,SAAS,MAAM,OAAO,EAAE;AAAA,EAC3E;AACA,SAAO,EAAE,WAAW,KAAK,WAAW,IAAI,KAAK,iBAAiB,MAAM,SAAS,WAAW,MAAM,OAAO,EAAE;AACzG;AAQA,SAAS,kBAAkB,SAAgC;AACzD,QAAM,WAAW,QAAQ,MAAM,cAAc;AAC7C,QAAM,QAAuB,CAAC;AAC9B,WAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,GAAG;AACvD,UAAM,KAAK;AAAA,MACT,SAAS,SAAS,KAAK,KAAK;AAAA,MAC5B,QAAQ,SAAS,QAAQ,CAAC,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAA8B;AACxD,MAAI,WAAW;AACf,aAAW,QAAQ,OAAO;AACxB,gBAAY,KAAK,UAAU,KAAK;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAA8B;AACxD,QAAM,YAAY,MAAM,CAAC,GAAG,QAAQ,WAAW,QAAQ,IAAI,MAAM,CAAC,EAAE,QAAQ,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG;AACjG,MAAI,cAAc,MAAO,QAAO;AAChC,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,UAAM,OAAO,MAAM,KAAK,GAAG,QAAQ,QAAQ;AAC3C,QAAI,SAAS,SAAS,SAAS,MAAO,QAAO;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,MAAc,WAA4B;AACvE,SAAO,KAAK,SAAS,SAAS;AAChC;AAEA,SAAS,qBAAqB,MAAc,WAA4B;AACtE,QAAM,iBAAiB,KAAK,UAAU,EAAE,YAAY;AACpD,SAAO,eAAe,SAAS,UAAU,YAAY,CAAC;AACxD;AAGA,SAAS,yBACP,OACA,OACA,wBACS;AACT,QAAM,eAAe,MAAM,QAAQ,CAAC,GAAG,QAAQ,KAAK,KAAK;AACzD,MAAI,iBAAiB,GAAI,QAAO;AAChC,SACE,6BAA6B,OAAO,KAAK,KACxC,mBAAmB,cAAc,sBAAsB,KACtD,CAAC,oBAAoB,YAAY,KACjC,CAAC,mBAAmB,KAAK,YAAY,KACrC,CAAC,qBAAqB,KAAK,YAAY;AAE7C;AAEA,SAAS,oBACP,OACA,OACA,uBACS;AACT,MAAI,sBAAsB,IAAI,KAAK,EAAG,QAAO;AAC7C,QAAM,OAAO,MAAM,KAAK,GAAG,WAAW;AACtC,QAAM,aAAa,UAAU,KAAK,KAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,CAAC,IAAI;AAC9E,MAAI,mBAAmB,UAAU,KAAK,eAAe,UAAU,EAAG,QAAO;AACzE,QAAM,cAAc,WAAW,UAAU;AACzC,SACE;AAAA,IACE,YAAY,YAAY;AAAA,IACxB;AAAA,IACA,yBAAyB,OAAO,OAAO,sBAAsB,IAAI,QAAQ,CAAC,CAAC;AAAA,EAC7E,MAAM;AAEV;AAEA,SAAS,0BACP,OACA,OACA,uBACA,wBACM;AACN,QAAM,iBAAiB,mBAAmB,KAAK;AAC/C,QAAM,wBAAwB,oBAAI,IAAY;AAC9C,QAAM,qBAAqB,CAAC,UAAwB;AAClD,0BAAsB,IAAI,KAAK;AAC/B,4BAAwB,KAAK;AAAA,EAC/B;AACA,MAAI,YAAuE;AAC3E,MAAI,gBAAsC;AAC1C,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,UAAM,OAAO,MAAM,KAAK,GAAG,WAAW;AACtC,UAAM,aAAa,UAAU,KAAK,KAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,CAAC,IAAI;AAC9E,QAAI,SAAS,eAAgB;AAC7B,UAAM,QAAQ,eAAe,UAAU;AACvC,QAAI,WAAW;AACb,YAAM,cAAc,WAAW,SAAS,WAAW,UAAU,EAAE;AAC/D,YAAM,sBACJ,UAAU,oBAAoB,QAC9B,WAAW,KAAK,MAAM,MACtB,cAAc,UAAU;AAC1B,UAAI,CAAC,qBAAqB;AACxB,YAAI,SAAS,eAAe,OAAO,SAAS,EAAG,aAAY;AAC3D;AAAA,MACF;AACA,kBAAY;AACZ,UAAI,QAAQ,EAAG,0BAAyB,QAAQ,CAAC;AAAA,IACnD;AACA,UAAM,cAAc,WAAW,UAAU;AACzC,UAAM,iBAAiB,YAAY,YAAY;AAC/C,QAAI,eAAe;AACjB,YAAM,cAAc,WAAW,SAAS,WAAW,UAAU,EAAE;AAC/D,YAAM,sBACJ,cAAc,oBAAoB,QAClC,WAAW,KAAK,MAAM,MACtB,cAAc,cAAc;AAC9B,UAAI,CAAC,qBAAqB;AACxB,YAAI,cAAc,mBAAmB,mBAAmB,IAAI;AAC1D,0BAAgB;AAChB;AAAA,QACF;AACA,YAAI,cAAc,SAAS;AACzB,gBAAM,gBAAgB,qBAAqB,eAAe,gBAAgB,KAAK;AAC/E,cAAI,CAAC,cAAe,oBAAmB,KAAK;AAC5C,0BAAgB;AAChB;AAAA,QACF;AACA,YAAI,cAAc,aAAa,qBAAqB,gBAAgB,cAAc,SAAS,GAAG;AAC5F,0BAAgB;AAChB,6BAAmB,KAAK;AAAA,QAC1B;AACA;AAAA,MACF;AACA,sBAAgB;AAChB,UAAI,QAAQ,EAAG,oBAAmB,QAAQ,CAAC;AAAA,IAC7C;AACA,QAAI,mBAAmB,UAAU,EAAG;AACpC,QAAI,OAAO;AACT,kBAAY;AAAA,QACV,GAAG;AAAA,QACH,iBAAiB,oBAAoB,OAAO,OAAO,MAAM,WAAW,IAChE,MAAM,cACN;AAAA,MACN;AACA;AAAA,IACF;AACA,UAAM,YAAY;AAAA,MAChB;AAAA,MACA;AAAA,MACA,yBAAyB,OAAO,OAAO,sBAAsB,IAAI,QAAQ,CAAC,CAAC;AAAA,IAC7E;AACA,QAAI,WAAW;AACb,yBAAmB,KAAK;AACxB,YAAM,cAAc,WAAW,SAAS,WAAW,UAAU,EAAE;AAC/D,YAAM,yBAAyB;AAAA,QAC7B,GAAG;AAAA,QACH,iBAAiB,oBAAoB,OAAO,OAAO,WAAW,IAAI,cAAc;AAAA,MAClF;AACA,UAAI,UAAU,SAAS;AACrB,wBAAgB,qBAAqB,wBAAwB,gBAAgB,IAAI;AACjF,YAAI,CAAC,cAAe,oBAAmB,KAAK;AAAA,MAC9C,WAAW,UAAU,aAAa,qBAAqB,gBAAgB,UAAU,SAAS,GAAG;AAC3F,wBAAgB;AAChB,2BAAmB,KAAK;AAAA,MAC1B,OAAO;AACL,wBAAgB;AAAA,MAClB;AACA;AAAA,IACF;AACA,UAAM,MAAM,KAAK;AAAA,EACnB;AACF;AAEA,SAAS,6BAA6B,OAAsB,OAAwB;AAClF,MAAI,CAAC,mBAAmB,MAAM,QAAQ,CAAC,GAAG,WAAW,EAAE,EAAG,QAAO;AACjE,MAAI,WAAW;AACf,WAAS,gBAAgB,QAAQ,GAAG,iBAAiB,GAAG,iBAAiB,GAAG;AAC1E,UAAM,eAAe,MAAM,aAAa,GAAG,WAAW;AACtD,QAAI,aAAa,KAAK,MAAM,IAAI;AAC9B,iBAAW;AACX;AAAA,IACF;AACA,QAAI,mBAAmB,YAAY,EAAG;AACtC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAsB,OAAe,aAA8B;AAC7F,WAAS,gBAAgB,QAAQ,GAAG,iBAAiB,GAAG,iBAAiB,GAAG;AAC1E,UAAM,eAAe,MAAM,aAAa,GAAG,WAAW;AACtD,QAAI,aAAa,KAAK,MAAM,GAAI,QAAO;AACvC,UAAM,sBAAsB,aAAa,SAAS,aAAa,UAAU,EAAE;AAC3E,QAAI,sBAAsB,YAAa;AACvC,UAAM,uBAAuB,aAAa,UAAU;AACpD,QAAI,mBAAmB,KAAK,oBAAoB,EAAG,QAAO;AAC1D,QACE,iBAAiB,KAAK,oBAAoB,KAC1C,wBAAwB,KAAK,oBAAoB,KACjD,qBAAqB,KAAK,oBAAoB,KAC9C,eAAe,YAAY,MAAM,MACjC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAsB,OAAe,aAA8B;AAC9F,WAAS,gBAAgB,QAAQ,GAAG,iBAAiB,GAAG,iBAAiB,GAAG;AAC1E,UAAM,eAAe,MAAM,aAAa,GAAG,WAAW;AACtD,QAAI,aAAa,KAAK,MAAM,GAAI;AAChC,UAAM,sBAAsB,aAAa,SAAS,aAAa,UAAU,EAAE;AAC3E,QAAI,uBAAuB,YAAa;AACxC,QACE,mBAAmB,KAAK,aAAa,UAAU,CAAC,KAChD,mBAAmB,OAAO,eAAe,WAAW,GACpD;AACA,aAAO;AAAA,IACT;AACA;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,2BAA2B,aAA8B;AAChE,MAAI,cAAc;AAClB,WAAS,QAAQ,GAAG,QAAQ,YAAY,QAAQ,SAAS,GAAG;AAC1D,UAAM,YAAY,YAAY,KAAK;AACnC,QAAI,cAAc,MAAM;AACtB,UAAI,QAAQ,KAAK,YAAY,OAAQ,QAAO;AAC5C,eAAS;AACT;AAAA,IACF;AACA,QAAI,cAAc,OAAO,cAAc,IAAK,QAAO;AACnD,QAAI,cAAc,KAAK;AACrB,qBAAe;AAAA,IACjB,WAAW,cAAc,KAAK;AAC5B,UAAI,gBAAgB,EAAG,QAAO;AAC9B,qBAAe;AAAA,IACjB;AAAA,EACF;AACA,SAAO,gBAAgB;AACzB;AAEA,SAAS,kCAAkC,MAAuB;AAChE,QAAM,QAAQ,wBAAwB,KAAK,IAAI;AAC/C,SAAO,UAAU,SAAS,MAAM,CAAC,MAAM,UAAa,2BAA2B,MAAM,CAAC,CAAC;AACzF;AAEA,SAAS,qCAAqC,OAAsB,OAAwB;AAC1F,QAAM,OAAO,MAAM,KAAK,GAAG,WAAW;AACtC,QAAM,eAAe,gBAAgB,KAAK,IAAI,IAAI,KAAK,UAAU,IAAI;AACrE,MAAI,kCAAkC,YAAY,EAAG,QAAO;AAC5D,MAAI,qCAAqC,KAAK,IAAI,GAAG;AACnD,UAAME,gBAAe,MAAM,QAAQ,CAAC,GAAG,WAAW;AAClD,UAAMC,wBACJ,gBAAgB,KAAKD,aAAY,IAAIA,cAAa,UAAU,IAAIA;AAClE,QAAI,kCAAkCC,qBAAoB,EAAG,QAAO;AACpE,UAAM,kBAAkB,MAAM,QAAQ,CAAC,GAAG,WAAW;AACrD,QAAI,CAAC,iDAAiD,KAAK,eAAe,EAAG,QAAO;AACpF,UAAM,YAAY,MAAM,QAAQ,CAAC,GAAG,WAAW;AAC/C,UAAM,oBACJ,gBAAgB,KAAK,SAAS,IAAI,UAAU,UAAU,IAAI;AAC5D,WAAO,8BAA8B,KAAK,iBAAiB;AAAA,EAC7D;AACA,MAAI,CAAC,iDAAiD,KAAK,IAAI,EAAG,QAAO;AACzE,QAAM,eAAe,MAAM,QAAQ,CAAC,GAAG,WAAW;AAClD,QAAM,uBACJ,gBAAgB,KAAK,YAAY,IAAI,aAAa,UAAU,IAAI;AAClE,SAAO,8BAA8B,KAAK,oBAAoB;AAChE;AAEA,SAAS,mBAAmB,OAAsB,OAAe,MAAuB;AACtF,QAAM,YAAY,UAAU,KAAK,KAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,CAAC,IAAI;AAC7E,MAAI,CAAC,cAAc,KAAK,SAAS,EAAG,QAAO;AAC3C,QAAM,cAAc,UAAU,SAAS,UAAU,UAAU,EAAE;AAC7D,MAAI,gBAAgB,KAAK,UAAU,EAAG,QAAO;AAC7C,QAAM,eAAe,MAAM,QAAQ,CAAC,GAAG,QAAQ,KAAK,KAAK;AACzD,SAAO,iBAAiB,KACpB,CAAC,oBAAoB,OAAO,OAAO,WAAW,IAC9C,iBAAiB,SAAS,iBAAiB;AACjD;AAEA,SAAS,sBAAsB,OAA8B;AAC3D,MAAI,aAAa;AACjB,4BAA0B,OAAO,CAAC,MAAM,UAAU;AAChD,QAAI,cAAc,EAAG;AACrB,QAAI,mBAAmB,OAAO,OAAO,IAAI,EAAG,cAAa;AAAA,EAC3D,CAAC;AACD,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAuB;AAClD,QAAM,aAAa,KAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,CAAC,IAAI;AAC/D,QAAM,eAAe,WAAW,KAAK;AACrC,SACE,iBAAiB,MACjB,CAAC,iBAAiB,KAAK,YAAY,KACnC,CAAC,mBAAmB,KAAK,YAAY,KACrC,CAAC,qBAAqB,KAAK,YAAY,KACvC,CAAC,wBAAwB,KAAK,YAAY,KAC1C,CAAC,kCAAkC,YAAY,KAC/C,eAAe,UAAU,MAAM;AAEnC;AAEA,SAAS,mBACP,MACA,iBAAiB,OACjB,cAAc,MACd,8BAA8B,OAC9B,qBAAqB,IACZ;AACT,QAAM,cAAc,8BAChB,mCACA;AACJ,QAAM,eAAe,gBAAgB,KAAK,IAAI,IAAI,KAAK,UAAU,IAAI;AACrE,QAAM,oBACJ,CAAC,eACD,0BAA0B,KAAK,YAAY,KAC3C,oBAAoB,kBAAkB;AACxC,SACE,KAAK,KAAK,MAAM,MAChB,iBAAiB,KAAK,YAAY,KAClC,YAAY,KAAK,YAAY,KAC5B,eAAe,0BAA0B,KAAK,YAAY,KAC1D,wBAAwB,KAAK,YAAY,KAAK,CAAC,qBAChD,qBAAqB,KAAK,YAAY,KACtC,kCAAkC,YAAY,KAC9C,oBAAoB,IAAI,KACxB,eAAe,IAAI,MAAM,QACzB;AAEJ;AAEA,SAAS,yBACP,OACA,OACA,gBACA,uBACA,wBACA,yBACS;AACT,QAAM,cAAc,MAAM,KAAK,GAAG,WAAW;AAC7C,QAAM,oBAAoB,YAAY,WAAW,QAAQ,IACrD,YAAY,MAAM,CAAC,IACnB;AACJ,QAAM,cAAc,kBAAkB,SAAS,kBAAkB,UAAU,EAAE;AAC7E,QAAM,eAAe,MAAM,QAAQ,CAAC,GAAG,QAAQ,QAAQ,KAAK;AAC5D,QAAM,WAAW,MAAM,QAAQ,CAAC,GAAG,QAAQ,QAAQ,KAAK;AACxD,QAAM,qBAAqB,aAAa,WAAW,QAAQ,IACvD,aAAa,MAAM,CAAC,IACpB;AACJ,QAAM,iBAAiB,SAAS,WAAW,QAAQ,IAAI,SAAS,MAAM,CAAC,IAAI;AAC3E,QAAM,gCAAgC,qCAAqC,OAAO,QAAQ,CAAC;AAC3F,QAAM,2BACJ,6BAA6B,OAAO,KAAK,KACzC,iCACA,uBAAuB,IAAI,QAAQ,CAAC,KACnC;AAAA,IACC;AAAA,IACA,sBAAsB,IAAI,QAAQ,CAAC;AAAA,EACrC,MACG,CAAC,oBAAoB,kBAAkB,KAAK,wBAAwB,IAAI,QAAQ,CAAC;AACtF,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF;AACA,QAAM,uBACJ,yBACA;AAAA,IACE;AAAA,IACA,sBAAsB,IAAI,QAAQ,CAAC;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF,QAAM,0BACJ,CAAC,wBAAwB,KAAK,kBAAkB,MAC/C,mBAAmB,KAAK,kBAAkB,KAAK,qBAAqB,KAAK,kBAAkB;AAC9F,QAAM,oBACJ,cAAc,KAAK,oBAAoB,OAAO,OAAO,WAAW;AAClE,QAAM,eACH,UAAU,KAAK,UAAU,iBAAiB,KAAK,6BAChD,CAAC,2BACD,CAAC;AACH,QAAM,YAAY,UAAU,MAAM,SAAS,KAAK;AAChD,QAAM,0BAA0B,mBAAmB,OAAO,QAAQ,GAAG,kBAAkB;AACvF,QAAM,2BACJ,oBAAoB,kBAAkB,KAAK,wBAAwB,IAAI,QAAQ,CAAC;AAClF,SAAO,gBAAgB,aAAa,2BAA2B;AACjE;AAEA,SAAS,yBAAyB,OAAgC;AAChE,QAAM,UAAoB,CAAC;AAC3B,QAAM,iBAAiB,mBAAmB,KAAK;AAC/C,QAAM,wBAAwB,oBAAI,IAAY;AAC9C,QAAM,yBAAyB,oBAAI,IAAY;AAC/C,QAAM,0BAA0B,oBAAI,IAAY;AAChD;AAAA,IACE;AAAA,IACA,CAAC,MAAM,UAAU;AACf,UACE,oBAAoB,IAAI,KACxB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,GACA;AACA,gBAAQ,KAAK,KAAK;AAClB,gCAAwB,IAAI,KAAK;AAAA,MACnC;AAAA,IACF;AAAA,IACA,CAAC,UAAU,sBAAsB,IAAI,KAAK;AAAA,IAC1C,CAAC,UAAU,uBAAuB,IAAI,KAAK;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAsB,OAAe,QAAsB;AACpF,QAAM,WAAW,QAAQ;AACzB,QAAM,SAAS,MAAM,KAAK,GAAG,UAAU,MAAM,QAAQ,GAAG,UAAU;AAClE,MAAI,MAAM,QAAQ,GAAG,QAAQ,KAAK,MAAM,IAAI;AAC1C,UAAM;AAAA,MACJ,WAAW;AAAA,MACX;AAAA,MACA,EAAE,SAAS,QAAQ,OAAO;AAAA,MAC1B,EAAE,SAAS,IAAI,OAAO;AAAA,IACxB;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,EAAE,SAAS,IAAI,OAAO;AAAA,MACtB,EAAE,SAAS,QAAQ,OAAO;AAAA,MAC1B,EAAE,SAAS,IAAI,OAAO;AAAA,IACxB;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAAsB,QAAwB;AACnE,QAAM,iBAAiB,mBAAmB,KAAK;AAC/C,MAAI,kBAAkB,GAAG;AACvB,sBAAkB,OAAO,gBAAgB,MAAM;AAC/C,WAAO,mBAAmB,KAAK;AAAA,EACjC;AACA,QAAM,SAAS,MAAM,CAAC,GAAG,UAAU;AACnC,MAAI,MAAM,CAAC,GAAG,QAAQ,WAAW,QAAQ,GAAG;AAC1C,UAAM,CAAC,EAAE,UAAU,MAAM,CAAC,EAAE,QAAQ,MAAM,CAAC;AAC3C,UAAM;AAAA,MACJ,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,IAAI,OAAO;AAAA,MAC1C,EAAE,SAAS,IAAI,OAAO;AAAA,IACxB;AACA,WAAO,mBAAmB,KAAK;AAAA,EACjC;AACA,QAAM;AAAA,IACJ,EAAE,SAAS,QAAQ,OAAO;AAAA,IAC1B,EAAE,SAAS,IAAI,OAAO;AAAA,EACxB;AACA,SAAO,mBAAmB,KAAK;AACjC;AAEO,SAAS,6BAA6B,SAAiB,WAA2B;AACvF,QAAM,QAAQ,kBAAkB,OAAO;AACvC,QAAM,SAAS,kBAAkB,SAAS;AAC1C,QAAM,aAAa,sBAAsB,KAAK;AAC9C,QAAM,gBAAgB,yBAAyB,KAAK;AAEpD,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,mBAAmB,cAAc,CAAC;AACxC,QAAI,qBAAqB,OAAW,QAAO,mBAAmB,KAAK;AACnE,UAAM,iBACJ,cAAc,IACV,cAAc,KAAK,CAAC,UAAU,QAAQ,UAAU,KAAK,mBACrD;AACN,UAAM,yBAAyB,cAAc;AAAA,MAAK,CAAC,UACjD,MAAM,KAAK,EAAE,QAAQ,WAAW,QAAQ;AAAA,IAC1C;AACA,UAAM,YACJ,mBAAmB,KAAK,MAAM,cAAc,EAAE,QAAQ,WAAW,QAAQ,IACrE,WACA;AACN,UAAM,cAAc,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM;AACrD,aAAS,QAAQ,cAAc,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AACjE,YAAM,cAAc,cAAc,KAAK;AACvC,UAAI,gBAAgB,UAAa,gBAAgB,eAAgB;AACjE,YAAM,OAAO,aAAa,CAAC;AAAA,IAC7B;AACA,QAAI,0BAA0B,CAAC,MAAM,CAAC,EAAE,QAAQ,WAAW,QAAQ,GAAG;AACpE,YAAM,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC,EAAE,OAAO;AAAA,IACnD;AACA,WAAO,mBAAmB,KAAK;AAAA,EACjC;AAEA,MAAI,aAAa,EAAG,QAAO,cAAc,OAAO,MAAM;AAEtD,oBAAkB,OAAO,YAAY,MAAM;AAC3C,SAAO,mBAAmB,KAAK;AACjC;AAUO,SAAS,0BAA0B,SAAiB,WAAmB,SAA0B;AACtG,MAAI,CAAC,WAAW,2BAA2B,OAAO,MAAM,QAAS,QAAO;AACxE,SAAO;AAAA;AAAA;AAAA,aAAuD,SAAS;AAAA;AAAA,EAAU,OAAO;AAC1F;AAOO,SAAS,2BAA2B,SAAyB;AAClE,MAAI,CAAC,QAAQ,WAAW,OAAO,KAAK,CAAC,QAAQ,WAAW,SAAS,EAAG,QAAO;AAC3E,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,SAAS,SAAS,SAAS,SAAS;AACtC,aAAO,MAAM,MAAM,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,eAAe,CAAC,IAClE,MAAM,MAAM,QAAQ,CAAC,EAAE,KAAK,IAAI,IAChC;AAAA,IACN;AACA,QAAI,SAAS,MAAM,SAAS,QAAQ,SAAS,MAAO,QAAO;AAAA,EAC7D;AACA,SAAO;AACT;;;ACn5BA,OAAOC,WAAU;AAYV,SAAS,kBAAkB,KAAa,UAA6C;AAC1F,MAAI,CAAC,IAAI,WAAW,OAAO,EAAG,QAAO;AACrC,QAAM,QAAQ,IAAI,QAAQ,aAAa,CAAC;AACxC,MAAI,UAAU,GAAI,QAAO;AACzB,QAAM,iBAAiB,IAAI,MAAM,GAAG,KAAK;AACzC,QAAM,OAAO,IAAI,MAAM,QAAQ,CAAC,EAAE,KAAK;AAEvC,QAAM,KAAK,wBAAwB,gBAAgB,IAAI,KAAKA,MAAK,SAAS,UAAU,KAAK;AACzF,QAAM,UAAU,wBAAwB,gBAAgB,SAAS,KAAK;AACtE,QAAM,WAAW,WAAW,wBAAwB,gBAAgB,UAAU,KAAK,KAAK;AACxF,QAAM,WAAW,wBAAwB,gBAAgB,UAAU,MAAM;AAEzE,QAAM,gBAAgB;AACtB,QAAM,YAAY,KAAK,QAAQ,aAAa;AAC5C,QAAM,WAAW,cAAc,KAAK,OAAO,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK;AACzE,QAAM,UAAU,cAAc,KAAK,KAAK,KAAK,MAAM,YAAY,cAAc,MAAM,EAAE,KAAK;AAE1F,SAAO,EAAE,IAAI,UAAU,SAAS,UAAU,UAAU,SAAS,SAAS;AACxE;AAEA,SAAS,wBAAwB,aAAqB,KAA4B;AAChF,QAAM,SAAS,GAAG,GAAG;AACrB,aAAW,QAAQ,YAAY,MAAM,IAAI,GAAG;AAC1C,QAAI,CAAC,KAAK,WAAW,MAAM,EAAG;AAC9B,QAAI,QAAQ,KAAK,MAAM,OAAO,MAAM,EAAE,KAAK;AAC3C,QAAI,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM,UAAU,GAAG;AACrE,cAAQ,MAAM,MAAM,GAAG,EAAE;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;ACzCA,OAAOC,WAAU;AAGV,IAAM,uBAAyD,OAAO,OAAO;AAAA,EAClF,MAAM;AAAA,EACN,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,MAAM;AACR,CAAC;AAGM,IAAM,oBAAoB;AAG1B,SAAS,mBAAmB,UAA0B;AAC3D,SAAO,qBAAqB,QAAQ,KAAK;AAC3C;AAGO,SAAS,iBAAiB,IAAyD;AACxF,SAAO,GAAG,eAAe,aAAa,mBAAmB,GAAG,QAAQ;AACtE;AAGO,IAAM,0BAA4D,OAAO,OAAO;AAAA,EACrF,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,cAAc;AAAA,EACd,SAAS;AAAA,EACT,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,OAAO;AACT,CAAC;AAGM,SAAS,qBAAqB,MAAkC;AACrE,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAC5C,SAAQ,eAAe,UAAa,wBAAwB,UAAU,KAAM;AAC9E;AAIO,IAAM,oBAAoB;AAS1B,IAAM,yBAAyD,OAAO,OAAO;AAAA,EAClF,YAAY;AAAA,EACZ,UAAU;AACZ,CAAC;AAEM,SAAS,6BAA6B,UAAwB;AACnE,QAAM,WAAWC,MAAK,SAAS,QAAQ;AACvC,MAAI,uBAAuB,QAAQ,MAAM,MAAM;AAC7C,UAAM,IAAI;AAAA,MACR,0BAA0B,QAAQ,wCAAwC,QAAQ;AAAA,IACpF;AAAA,EACF;AACF;;;ACrDO,SAAS,SAA2B,MAAiB;AAC1D,QAAM,SAAS;AACf,SAAO,IAAI,MAAM,uBAAO,OAAO,IAAI,GAAa;AAAA,IAC9C,IAAI,SAAS,MAAM;AACjB,YAAM,QAAQ,OAAO,IAAc;AAQnC,aAAO,OAAO,UAAU,cACtB,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,WAAW,IACrD,MAA0C,KAAK,IAAI,IACpD;AAAA,IACN;AAAA,IACA,IAAI,SAAS,MAAM,OAAO;AAOxB,UAAI,EAAG,QAAmB,QAAS,QAAO;AAC1C,aAAO,IAAc,IAAI;AACzB,aAAO;AAAA,IACT;AAAA,IACA,IAAI,SAAS,MAAM;AACjB,aAAQ,QAAmB;AAAA,IAC7B;AAAA,EACF,CAAC;AACH;;;AC7CA,SAAS,WAAAC,UAAS,cAAc;AAChC,OAAOC,WAAU;AAmEV,IAAM,cAAN,MAAkB;AAAA,EACvB,YACmB,MACjB;AADiB;AAAA,EAChB;AAAA,EADgB;AAAA;AAAA,EAInB,oBAAoB,KAAa,MAAsB;AACrD,WAAO,oBAA0B,KAAK,MAAM,KAAK,KAAK,WAAW;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,sBACZ,MACA,QACA,eAC0D;AAC1D,UAAM,YAAY,mCAAmC,MAAM,aAAa;AACxE,eAAW,aAAa,cAAc,OAAO,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,GAAG;AACvE,YAAM,WAAWC,MAAK,KAAK,KAAK,KAAK,aAAa,GAAG,SAAS,KAAK;AACnE,UAAI;AACF,cAAM,SAAS,gBAAgB,MAAM,KAAK,KAAK,sBAAsB,QAAQ,GAAG,KAAK,KAAK,aAAa;AACvG,eAAO,EAAE,UAAU,OAAO;AAAA,MAC5B,SAAS,KAAK;AACZ,YAAI,eAAe,uBAAwB,OAAM;AACjD,YAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,MACzC;AAAA,IACF;AACA,QAAI,MAAM,GAAG,MAAM,iBAAiB,SAAS,eAAe;AAC5D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAc,iBACZ,MACA,QACA,QACkB;AAClB,UAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,SAAS,OAAO;AACrD,WAAO,gCAAgC,UAAU,YAAY;AAC3D,eAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,cAAM,eAAe,KAAK,KAAK,qBAAqB;AACpD,cAAM,UAAU,MAAM,KAAK,sBAAsB,MAAM,QAAQ,YAAY;AAC3E,cAAM,UAAU,YAAY,QAAQ,OAAO,QAAQ,QAAQ,YAAY;AAIvE,YAAI,KAAK,KAAK,qBAAqB,MAAM,aAAc;AACvD,YAAI,CAAC,WAAW,CAAC,QAAS,QAAO;AACjC,gBAAQ,OAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AAChD,cAAM,KAAK,KAAK;AAAA,UACd,QAAQ;AAAA,UACR,oBAAoB,QAAQ,QAAQ,KAAK,KAAK,eAAe,KAAK,KAAK,sBAAsB,CAAC;AAAA,QAChG;AACA,oCAA4B,UAAU,cAAc,KAAK,KAAK,qBAAqB,CAAC;AACpF,aAAK,KAAK,8BAA8B;AACxC,aAAK,KAAK,0BAA0B;AACpC,eAAO;AAAA,MACT;AAKA,4CAAsC,QAAQ;AAC9C,YAAM,IAAI;AAAA,QACR,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,sBAAsB,MAAc,KAAwC;AAChF,UAAM,KAAK,iBAAiB,MAAM,yBAAyB,CAAC,QAAQ,kBAAkB;AAMpF,YAAM,SAAS,mCAAmC,IAAI,QAAQ,aAAa;AAC3E,YAAM,YAAY,OAAO,cAAc;AAAA,QACrC,CAAC,MAAM,mCAAmC,EAAE,QAAQ,aAAa,MAAM,UAAU,EAAE,UAAU,IAAI;AAAA,MACnG;AACA,UAAI,UAAW,QAAO;AACtB,aAAO,cAAc,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC;AAC5C,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,kBAAkB,MAAc,OAA4B,YAAmC;AACnG,UAAM,KAAK,iBAAiB,MAAM,qBAAqB,CAAC,WAAW;AACjE,aAAO,SAAS,QAAQ,KAAK;AAC7B,UAAI,OAAO,SAAS,SAAS,WAAY,QAAO,WAAW,OAAO,SAAS,MAAM,GAAG,UAAU;AAC9F,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,MAAc,OAA8B;AAC/D,UAAM,QAAQ,MAAM,KAAK,iBAAiB,MAAM,kBAAkB,CAAC,WAAW;AAC5E,UAAI,OAAO,QAAQ,SAAS,KAAK,EAAG,QAAO;AAC3C,aAAO,QAAQ,KAAK,KAAK;AACzB,aAAO;AAAA,IACT,CAAC;AACD,QAAI,MAAO,MAAK,KAAK,wBAAwB;AAAA,EAC/C;AAAA,EAEA,MAAM,YACJ,MACA,MACA,OACA,UAOI,CAAC,GACY;AACjB,UAAM,KAAK,KAAK,kBAAkB;AAClC,WAAO;AAAA,MACLA,MAAK,KAAK,KAAK,KAAK,SAAS,OAAO;AAAA,MACpC,MAAM,KAAK,oBAAoB,MAAM,MAAM,OAAO,OAAO;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAc,oBACZ,MACA,MACA,OACA,UAOI,CAAC,GACY;AACjB,QAAI,OAAO,SAAS,YAAY,CAAC,KAAK,KAAK,KAAK,OAAO,SAAS,YAAY,CAAC,KAAK,KAAK,GAAG;AACxF,UAAI,KAAK,iDAAiD;AAAA,QACxD,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,IACT;AACA,UAAM,YAAY,MAAM,QAAQ,KAAK,IACjC,CAAC,GAAG,IAAI;AAAA,MACR,MACG,OAAO,CAAC,SAAS,OAAO,SAAS,QAAQ,EACzC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AAAA,IACrC,CAAC,IACC,CAAC;AACL,QAAI,aAAa,KAAK,KAAK,oBAAoB,MAAM,IAAI;AAGzD,UAAM,QAAQ,MAAM,KAAK,KAAK,mBAAmB,MAAM,IAAI;AAC3D,QAAI,SAAS,UAAU,YAAY;AACjC,UAAI,MAAM,iBAAiB,UAAU,sBAAiB,KAAK,GAAG;AAC9D,mBAAa;AAAA,IACf;AAEA,UAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,aAAa,GAAG,UAAU,KAAK;AAGpE,QAAI,SAAqB;AAAA,MACvB;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,MAChC,OAAO,CAAC;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,MACX,oBAAoB;AAAA,MACpB,kBAAkB;AAAA,MAClB,8BAA8B;AAAA,MAC9B,+BAA+B;AAAA,MAC/B,UAAU,CAAC;AAAA,MACX,eAAe,CAAC;AAAA,MAChB,UAAU,CAAC;AAAA,MACX,SAAS,CAAC;AAAA,IACZ;AACA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAC/D,eAAS,gBAAgB,UAAU,KAAK,KAAK,aAAa;AAAA,IAC5D,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,IAEzC;AAEA,UAAM,YAAY,QAAQ,WAAW,KAAK,MAAK,oBAAI,KAAK,GAAE,YAAY;AACtE,UAAM,SAAS,QAAQ,QAAQ,KAAK,KAAK;AACzC,UAAM,aAAa,QAAQ,YAAY,KAAK,KAAK;AACjD,UAAM,YAAY,QAAQ,WAAW,KAAK,KAAK;AAC/C,UAAM,SAAS,QAAQ,QAAQ,KAAK,IAAI,iBAAiB,QAAQ,MAAM,IAAI;AAC3E,UAAM,uBAAuB,IAAI;AAAA,OAC9B,OAAO,sBAAsB,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,KAAK;AAAA,QAC/D,GAAG;AAAA,QACH,OAAO,CAAC,GAAG,QAAQ,KAAK;AAAA,QACxB,GAAI,QAAQ,cAAc,EAAE,aAAa,CAAC,GAAG,QAAQ,WAAW,EAAE,IAAI,CAAC;AAAA,MACzE,CAAC,CAAC;AAAA,IACJ;AACA,eAAW,WAAW,QAAQ,sBAAsB,CAAC,GAAG;AACtD,YAAM,oBAAoB,iCAAiC,MAAM,SAAS,KAAK,KAAK,aAAa;AACjG,YAAMC,cAAa,2CAA2C,QAAQ,OAAO,QAAQ,aAAa,MAAM;AACxG,UAAIA,YAAW,MAAM,WAAW,EAAG;AACnC,YAAM,kBAAkB,qBAAqB,IAAI,kBAAkB,GAAG;AACtE,UAAI,CAAC,iBAAiB;AACpB,6BAAqB,IAAI,kBAAkB,KAAK;AAAA,UAC9C,KAAK,kBAAkB;AAAA,UACvB,OAAO,kBAAkB;AAAA,UACzB,GAAGA;AAAA,QACL,CAAC;AACD;AAAA,MACF;AACA,YAAM,kBAAkB,gBAAgB,MAAM,IAAI,CAAC,GAAG,UAAU,gBAAgB,cAAc,KAAK,CAAC;AACpG,YAAM,kBAAkBA,YAAW,MAAM,IAAI,CAAC,GAAG,UAAUA,YAAW,cAAc,KAAK,CAAC;AAC1F,YAAM,SAAS;AAAA,QACb,CAAC,GAAG,gBAAgB,OAAO,GAAGA,YAAW,KAAK;AAAA,QAC9C,CAAC,GAAG,iBAAiB,GAAG,eAAe;AAAA,MACzC;AACA,sBAAgB,QAAQ,OAAO;AAC/B,sBAAgB,cAAc,OAAO;AACrC,UAAI,CAAC,gBAAgB,MAAM,KAAK,KAAK,kBAAkB,MAAM,KAAK,GAAG;AACnE,wBAAgB,QAAQ,kBAAkB;AAAA,MAC5C;AAAA,IACF;AACA,eAAW,QAAQ,WAAW;AAC5B,YAAM,YAAY;AAAA,QAChB;AAAA,QACA,MAAM;AAAA,QACN,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,QAC3B,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,QACnC,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,QACjC,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC7B;AACA,YAAM,iBAAiB,OAAO,SAAS;AAAA,QAAK,CAAC,UAC3C,MAAM,cAAc,UAAU,aAC3B,MAAM,SAAS,UAAU,QACzB,MAAM,WAAW,UAAU,UAC3B,MAAM,eAAe,UAAU,cAC/B,MAAM,cAAc,UAAU,aAC9B,MAAM,WAAW,UAAU;AAAA,MAChC;AACA,UAAI,eAAgB;AACpB,aAAO,SAAS,KAAK,SAAS;AAAA,IAChC;AACA,WAAO,qBAAqB;AAAA,MAC1B;AAAA,MACA,MAAM,KAAK,qBAAqB,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,QAAQ,MAAM,SAAS,CAAC;AAAA,MACtF,KAAK,KAAK;AAAA,IACZ;AACA,WAAO,QAAQ,mBAAmB,OAAO,UAAU,OAAO,kBAAkB;AAC5E,WAAO,UAAU,OAAO,aAAa,OAAO;AAC5C,WAAO,OAAO;AACd,WAAO,OAAO;AACd,WAAO,UAAU,OAAO,WAAW;AACnC,WAAO,WAAU,oBAAI,KAAK,GAAE,YAAY;AAExC,UAAM,KAAK,KAAK,oBAAoB,UAAU,OAAO;AACrD,UAAM,KAAK,KAAK,uBAAuB,UAAU,oBAAoB,QAAQ,KAAK,KAAK,eAAe,KAAK,KAAK,sBAAsB,CAAC,CAAC;AACxI,SAAK,KAAK,8BAA8B;AACxC,SAAK,KAAK,wBAAwB;AAClC,SAAK,KAAK,0BAA0B;AACpC,QAAI,MAAM,gBAAgB,UAAU,EAAE;AACtC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,MAA+B;AAC9C,UAAM,WAAW,KAAK,KAAK,sBAAsB,IAAI;AACrD,QAAI,aAAa,MAAM;AACrB,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAAA,IACvD,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBAAqC;AACzC,QAAI;AACF,YAAM,UAAU,MAAMC,SAAQ,KAAK,KAAK,WAAW;AACnD,aAAO,QACJ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC,EAC/B,KAAK;AAAA,IACV,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,4CAA0F;AAC9F,UAAM,cAAc,MAAM,KAAK,gBAAgB;AAC/C,UAAM,WAAWF,MAAK,KAAK,KAAK,KAAK,SAAS,OAAO;AACrD,QAAI,WAAW;AACf,eAAW,cAAc,aAAa;AAMpC,YAAM,QAAQ,MAAM,gCAAgC,UAAU,YAAY;AACxE,cAAM,MAAM,MAAM,KAAK,WAAW,UAAU;AAC5C,YAAI,CAAC,IAAK,QAAO;AACjB,cAAM,aAAa,oBAAoB,gBAAgB,KAAK,KAAK,KAAK,aAAa,GAAG,KAAK,KAAK,eAAe,KAAK,KAAK,sBAAsB,CAAC;AAChJ,YAAI,IAAI,QAAQ,MAAM,WAAW,QAAQ,EAAG,QAAO;AACnD,cAAM,WAAW,KAAK,KAAK,sBAAsB,UAAU;AAC3D,YAAI,aAAa,KAAM,QAAO;AAC9B,cAAM,KAAK,KAAK,uBAAuB,UAAU,UAAU;AAC3D,aAAK,KAAK,0BAA0B;AACpC,eAAO;AAAA,MACT,CAAC;AACD,UAAI,MAAO,aAAY;AAAA,IACzB;AACA,QAAI,WAAW,GAAG;AAChB,WAAK,KAAK,8BAA8B;AACxC,WAAK,KAAK,wBAAwB;AAAA,IACpC;AACA,WAAO,EAAE,OAAO,YAAY,QAAQ,SAAS;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBACJ,MACA,WACA,UAOI,CAAC,GACU;AACf,WAAO;AAAA,MACLA,MAAK,KAAK,KAAK,KAAK,SAAS,OAAO;AAAA,MACpC,MAAM,KAAK,8BAA8B,MAAM,WAAW,OAAO;AAAA,IACnE;AAAA,EACF;AAAA,EAEA,MAAc,8BACZ,MACA,WACA,UAOI,CAAC,GACU;AACf,UAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,aAAa,GAAG,IAAI,KAAK;AAC9D,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAC9D,eAAS,gBAAgB,SAAS,KAAK,KAAK,aAAa;AAAA,IAC3D,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,UAAI,MAAM,sCAAsC,IAAI,eAAe;AACnE;AAAA,IACF;AAEA,UAAM,YAAY,QAAQ,WAAW,KAAK,KAAK,OAAO,oBAAoB,KAAK,KAAK;AACpF,UAAM,kBAAkB,QAAQ,iBAAiB,KAAK,KAAK,aAAa,OAAO,YAAW,oBAAI,KAAK,GAAE,YAAY;AACjH,UAAM,yBAAyB,OAAO,UAAU,QAAQ,sBAAsB,MACxE,QAAQ,0BAA0B,MAAM,IAC1C,QAAQ,yBACR;AACJ,UAAM,+BAA+B,OAAO,UAAU,QAAQ,4BAA4B,MACpF,QAAQ,gCAAgC,MAAM,IAChD,QAAQ,+BACR,2BAA2B,MAAM;AACrC,UAAM,gCAAgC,QAAQ,+BAA+B,KAAK,KAC7E,iCAAiC,MAAM;AAC5C,WAAO,YAAY,UAAU,KAAK;AAClC,WAAO,UAAU,OAAO;AACxB,WAAO,qBAAqB;AAC5B,WAAO,yBAAyB;AAChC,WAAO,+BAA+B;AACtC,WAAO,gCAAgC;AACvC,WAAO,mBAAmB,KAAK,IAAI,GAAG,OAAO,oBAAoB,CAAC,KAC7D,QAAQ,qBAAqB,QAAQ,IAAI;AAC9C,WAAO,UAAU;AACjB,UAAM,KAAK,KAAK,uBAAuB,UAAU,oBAAoB,QAAQ,KAAK,KAAK,eAAe,KAAK,KAAK,sBAAsB,CAAC,CAAC;AACxI,UAAM,KAAK,KAAK,kCAAkC;AAAA,MAChD,GAAG,oBAAI,IAAI,CAAC,MAAM,KAAK,KAAK,oBAAoB,OAAO,MAAM,OAAO,IAAI,CAAC,CAAC;AAAA,IAC5E,CAAC;AACD,SAAK,KAAK,8BAA8B;AACxC,SAAK,KAAK,wBAAwB;AAClC,SAAK,KAAK,0BAA0B;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAmB,SAAoD;AAC3E,yBAAqB,OAAO;AAC5B,UAAM,iBAAiB,KAAK,KAAK,uBAAuB;AACxD,UAAM,WAAW;AAAA,MACf,KAAK,KAAK,6BAA6B;AAAA,MACvC,0BAA0B,KAAK,KAAK,aAAa;AAAA,MACjD,KAAK,KAAK,yBAAyB;AAAA,IACrC,EAAE,KAAK,IAAQ;AACf,UAAM,SAAS,kBAAkB,KAAK,KAAK,SAAS,gBAAgB,QAAQ;AAC5E,QAAI,OAAQ,QAAO;AAEnB,QAAI;AACF,YAAM,UAAU,MAAME,SAAQ,KAAK,KAAK,WAAW;AACnD,YAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AACvD,UAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAKlC,YAAM,aAAa;AACnB,YAAM,WAAyB,CAAC;AAChC,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,YAAY;AAGnD,6BAAqB,OAAO;AAC5B,cAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,UAAU;AAC7C,cAAM,UAAU,MAAM,QAAQ;AAAA,UAC5B,MAAM,IAAI,OAAO,UAAU;AACzB,gBAAI;AACF,qBAAO,MAAM,KAAK,KAAK,sBAAsBF,MAAK,KAAK,KAAK,KAAK,aAAa,KAAK,CAAC;AAAA,YACtF,SAAS,KAAK;AACZ,kBAAI,eAAe,uBAAwB,OAAM;AACjD,kBAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,qBAAO;AAAA,YACT;AAAA,UACF,CAAC;AAAA,QACH;AACA,mBAAW,WAAW,SAAS;AAC7B,cAAI,YAAY,KAAM,UAAS,KAAK,gBAAgB,SAAS,KAAK,KAAK,aAAa,CAAC;AAAA,QACvF;AAAA,MACF;AAGA,2BAAqB,OAAO;AAC5B,wBAAkB,KAAK,KAAK,SAAS,UAAU,gBAAgB,QAAQ;AACvE,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA0B,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAEhF,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBACJ,QACA,WAC8C;AAC9C,UAAM,mBACJ,WAAW,gBAAgB,UAC3B,WAAW,aAAa;AAE1B,QACE,oBACA,KAAK,KAAK,uBACV,KAAK,IAAI,IAAI,KAAK,KAAK,oBAAoB,UAAU,KAAK,KAAK,oBAAoB,8BACnF;AACA,aAAO,EAAE,QAAQ,KAAK,KAAK,oBAAoB,QAAQ,QAAQ,KAAK;AAAA,IACtE;AAEA,UAAM,WAAW,MAAM,KAAK,KAAK,mBAAmB;AACpD,QAAI,SAAS,WAAW,GAAG;AACzB,UAAI,iBAAkB,MAAK,KAAK,sBAAsB,EAAE,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE;AACxF,aAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACrC;AAEA,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,SAAyB,SAAS,IAAI,CAAC,OAAO;AAAA,MAClD,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,OAAO,KAAK,KAAK,oBAAoB,YAAY,GAAG,GAAG;AAAA,MACvD,WAAW,EAAE,MAAM;AAAA,MACnB,SAAS,EAAE,aAAa,EAAE;AAAA,MAC1B,kBAAkB,EAAE,cAAc,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,IACnE,EAAE;AAGF,WAAO,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACvC,UAAM,cAAc,OAAO,WAAW,gBAAgB,WAClD,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,WAAW,CAAC,IAC7C,OAAO;AACX,UAAM,OAAO,OAAO,MAAM,GAAG,WAAW;AAExC,QAAI,KAAK,WAAW,GAAG;AACrB,UAAI,iBAAkB,MAAK,KAAK,sBAAsB,EAAE,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE;AACxF,aAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACrC;AAGA,UAAM,SAAS;AACf,UAAM,OAAiB,CAAC;AACxB,QAAI,aAAa,OAAO;AACxB,UAAM,WAAW,OAAO,WAAW,aAAa,WAC5C,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,QAAQ,CAAC,IAC1C,OAAO;AAEX,eAAW,UAAU,MAAM;AACzB,YAAM,UAAU,OAAO,WAAW,GAAG,OAAO,SAAS;AACrD,YAAM,YAAY,OAAO,iBAAiB,SAAS,IAC/C,OAAO,iBAAiB,KAAK,IAAI,IACjC;AACJ,YAAM,MAAM,KAAK,OAAO,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO,MAAM,SAAS;AAEzE,UAAI,aAAa,IAAI,SAAS,IAAI,SAAU;AAC5C,WAAK,KAAK,GAAG;AACb,oBAAc,IAAI,SAAS;AAAA,IAC7B;AAEA,UAAM,SAAS,KAAK,WAAW,IAAI,KAAK,GAAG,MAAM;AAAA,EAAK,KAAK,KAAK,IAAI,CAAC;AAAA;AACrE,QAAI,iBAAkB,MAAK,KAAK,sBAAsB,EAAE,QAAQ,SAAS,KAAK,IAAI,EAAE;AACpF,WAAO,EAAE,QAAQ,QAAQ,MAAM;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,0BAA2C;AAC/C,WAAO;AAAA,MACLA,MAAK,KAAK,KAAK,KAAK,SAAS,OAAO;AAAA,MACpC,MAAM,KAAK,gCAAgC;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,MAAc,kCAAmD;AAC/D,QAAI,SAAS;AACb,QAAI;AACF,YAAM,UAAU,MAAME,SAAQ,KAAK,KAAK,WAAW;AACnD,YAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AAGvD,YAAM,SAAS,oBAAI,IAAsB;AACzC,iBAAW,QAAQ,SAAS;AAC1B,cAAM,WAAW,KAAK,QAAQ,OAAO,EAAE;AAEvC,cAAM,UAAU,SAAS,QAAQ,GAAG;AACpC,YAAI,YAAY,GAAI;AACpB,cAAM,OAAO,SAAS,MAAM,GAAG,OAAO;AACtC,cAAM,aAAa,SAAS,MAAM,UAAU,CAAC;AAC7C,cAAM,YAAY,KAAK,KAAK,oBAAoB,YAAY,IAAI;AAEhE,YAAI,CAAC,OAAO,IAAI,SAAS,EAAG,QAAO,IAAI,WAAW,CAAC,CAAC;AACpD,eAAO,IAAI,SAAS,EAAG,KAAK,IAAI;AAAA,MAClC;AAGA,iBAAW,CAAC,WAAW,KAAK,KAAK,QAAQ;AACvC,YAAI,MAAM,UAAU,EAAG;AAGvB,cAAM,eAA2B;AAAA,UAC/B,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,UACT,uBAAuB,CAAC;AAAA,UACxB,iBAAiB,CAAC;AAAA,UAClB,OAAO,CAAC;AAAA,UACR,SAAS;AAAA,UACT,WAAW;AAAA,UACX,oBAAoB;AAAA,UACpB,wBAAwB;AAAA,UACxB,8BAA8B;AAAA,UAC9B,+BAA+B;AAAA,UAC/B,kBAAkB;AAAA,UAClB,UAAU,CAAC;AAAA,UACX,eAAe,CAAC;AAAA,UAChB,UAAU,CAAC;AAAA,UACX,SAAS,CAAC;AAAA,UACV,oBAAoB,CAAC;AAAA,UACrB,eAAe,CAAC;AAAA,QAClB;AAEA,mBAAW,QAAQ,OAAO;AACxB,gBAAM,WAAWF,MAAK,KAAK,KAAK,KAAK,aAAa,IAAI;AACtD,cAAI;AACF,kBAAM,UAAU,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAC9D,kBAAM,SAAS,gBAAgB,SAAS,KAAK,KAAK,aAAa;AAG/D,gBAAI,CAAC,aAAa,QAAQ,aAAa,SAAS,SAAS;AACvD,2BAAa,OAAO,OAAO;AAAA,YAC7B;AAGA,gBAAI,CAAC,aAAa,WAAW,wBAAwB,OAAO,SAAS,aAAa,OAAO,IAAI,GAAG;AAC9F,2BAAa,UAAU,OAAO;AAAA,YAChC;AAEA,kBAAM,gBAAgB,OAAO,WAAW,OAAO;AAC/C,kBAAM,gBAAgB,aAAa,SAAS,KAAK,KAAK;AACtD,kBAAM,kBAAkB,gBAAgB,KAAK,MAAM,aAAa,IAAI,OAAO;AAC3E,kBAAM,kBAAkB,gBAAgB,KAAK,MAAM,aAAa,IAAI,OAAO;AAC3E,kBAAM,uBAAuB,OAAO,SAAS,eAAe;AAC5D,kBAAM,uBAAuB,OAAO,SAAS,eAAe;AAC5D,gBACE,kBAEE,CAAC,iBACG,wBAAwB,CAAC,wBAE3B,wBACG,wBACA,kBAAkB,mBAGrB,CAAC,wBACE,CAAC,wBACD,wBAAwB,eAAe,aAAa,IAAI,IAG/D;AACA,2BAAa,UAAU;AAAA,YACzB;AAGA,gBAAI,OAAO,KAAK,SAAS,aAAa,KAAK,QAAQ;AACjD,2BAAa,OAAO,OAAO;AAAA,YAC7B;AAEA,kBAAM,2BAA2B,OAAO,oBAAoB,KAAK,KAAK;AACtE,kBAAM,2BAA2B,aAAa,oBAAoB,KAAK,KAAK;AAG5E,gBACE,OAAO,cACN,CAAC,aAAa,aACT,CAAC,4BAA4B,QAAQ,wBAAwB,KAC7D,QAAQ,wBAAwB,KAC/B,QAAQ,wBAAwB,KAChC,wBAAwB,0BAA0B,wBAAwB,IAAI,IACrF;AACA,2BAAa,YAAY,OAAO;AAChC,2BAAa,UAAU,OAAO;AAC9B,2BAAa,qBAAqB;AAClC,2BAAa,yBAAyB,OAAO;AAC7C,2BAAa,+BAA+B,OAAO;AACnD,2BAAa,gCAAgC,OAAO;AACpD,2BAAa,mBAAmB,OAAO;AAAA,YACzC,WAAW,CAAC,aAAa,WAAW,OAAO,SAAS;AAClD,2BAAa,UAAU,OAAO;AAC9B,2BAAa,YAAY,OAAO;AAChC,2BAAa,qBAAqB;AAClC,2BAAa,yBAAyB,OAAO;AAC7C,2BAAa,+BAA+B,OAAO;AACnD,2BAAa,gCAAgC,OAAO;AACpD,2BAAa,mBAAmB,OAAO;AAAA,YACzC;AAGA,yBAAa,SAAS,KAAK,GAAG,OAAO,QAAQ;AAG7C,yBAAa,cAAc,KAAK,GAAG,OAAO,aAAa;AAGvD,yBAAa,SAAS,KAAK,GAAG,OAAO,QAAQ;AAG7C,yBAAa,QAAQ,KAAK,GAAG,OAAO,OAAO;AAE3C,kBAAM,6BAA6B,IAAI;AAAA,eACpC,aAAa,sBAAsB,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,KAAK;AAAA,gBACrE,GAAG;AAAA,gBACH,OAAO,CAAC,GAAG,QAAQ,KAAK;AAAA,gBACxB,aAAa,QAAQ,cAAc,CAAC,GAAG,QAAQ,WAAW,IAAI;AAAA,cAChE,CAAC,CAAC;AAAA,YACJ;AACA,uBAAW,WAAW,OAAO,sBAAsB,CAAC,GAAG;AACrD,oBAAM,kBAAkB,2BAA2B,IAAI,QAAQ,GAAG;AAClE,kBAAI,CAAC,iBAAiB;AACpB,sBAAM,QAAkB,CAAC;AACzB,sBAAM,cAAyC,CAAC;AAChD,2BAAW,CAAC,OAAO,IAAI,KAAK,QAAQ,MAAM,QAAQ,GAAG;AACnD,wBAAM,UAAU,KAAK,KAAK;AAC1B,sBAAI,CAAC,WAAW,MAAM,SAAS,OAAO,EAAG;AACzC,wBAAM,KAAK,OAAO;AAClB,8BAAY,KAAK,QAAQ,cAAc,KAAK,CAAC;AAAA,gBAC/C;AACA,2CAA2B,IAAI,QAAQ,KAAK;AAAA,kBAC1C,KAAK,QAAQ;AAAA,kBACb,OAAO,QAAQ;AAAA,kBACf;AAAA,kBACA,aAAa,QAAQ,cAAc,cAAc;AAAA,gBACnD,CAAC;AACD;AAAA,cACF;AAEA,kBAAI,QAAQ,eAAe,CAAC,gBAAgB,aAAa;AACvD,gCAAgB,cAAc,gBAAgB,MAAM,IAAI,MAAM,MAAS;AAAA,cACzE;AACA,yBAAW,CAAC,OAAO,IAAI,KAAK,QAAQ,MAAM,QAAQ,GAAG;AACnD,sBAAM,UAAU,KAAK,KAAK;AAC1B,oBAAI,CAAC,QAAS;AACd,sBAAM,gBAAgB,gBAAgB,MAAM,QAAQ,OAAO;AAC3D,sBAAM,SAAS,QAAQ,cAAc,KAAK;AAC1C,oBAAI,kBAAkB,IAAI;AACxB,kCAAgB,MAAM,KAAK,OAAO;AAClC,kCAAgB,aAAa,KAAK,MAAM;AAAA,gBAC1C,WAAW,gBAAgB,cAAc,aAAa,MAAM,QAAQ;AAClE,kCAAgB,aAAa,OAAO,eAAe,GAAG,MAAS;AAAA,gBACjE;AAAA,cACF;AACA,kBAAI,CAAC,gBAAgB,MAAM,KAAK,KAAK,QAAQ,MAAM,KAAK,GAAG;AACzD,gCAAgB,QAAQ,QAAQ;AAAA,cAClC;AAAA,YACF;AACA,yBAAa,qBAAqB,MAAM,KAAK,2BAA2B,OAAO,CAAC;AAGhF,yBAAa,sBAAuB,KAAK,GAAI,OAAO,yBAAyB,CAAC,CAAE;AAChF,yBAAa,gBAAiB,KAAK,GAAI,OAAO,mBAAmB,CAAC,CAAE;AACpE,yBAAa,cAAe,KAAK,IAAI,OAAO,iBAAiB,CAAC,GAAG,IAAI,CAAC,aAAa;AAAA,cACjF,OAAO,QAAQ;AAAA,cACf,OAAO,CAAC,GAAG,QAAQ,KAAK;AAAA,YAC1B,EAAE,CAAC;AAAA,UACL,SAAS,KAAK;AACZ,gBAAI,eAAe,uBAAwB,OAAM;AACjD,gBAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,UAEzC;AAAA,QACF;AAEA,cAAM,gBAAgB,oBAAI,IAAoD;AAC9E,mBAAW,SAAS,aAAa,UAAU;AACzC,gBAAM,MAAM,KAAK,UAAU;AAAA,YACzB,MAAM;AAAA,YACN,MAAM,UAAU;AAAA,YAChB,MAAM,cAAc;AAAA,YACpB,MAAM,aAAa;AAAA,YACnB,MAAM;AAAA,UACR,CAAC;AACD,gBAAM,WAAW,cAAc,IAAI,GAAG;AACtC,cAAI,CAAC,UAAU;AACb,0BAAc,IAAI,KAAK,KAAK;AAAA,UAC9B,WAAW,SAAS,WAAW,MAAM,QAAQ;AAC3C,qBAAS,SAAS;AAAA,UACpB;AAAA,QACF;AACA,qBAAa,WAAW,CAAC,GAAG,cAAc,OAAO,CAAC;AAElD,cAAM,UAAU,oBAAI,IAAY;AAChC,qBAAa,gBAAgB,aAAa,cAAc,OAAO,CAAC,MAAM;AACpE,gBAAM,MAAM,GAAG,EAAE,MAAM,KAAK,EAAE,KAAK;AACnC,cAAI,QAAQ,IAAI,GAAG,EAAG,QAAO;AAC7B,kBAAQ,IAAI,GAAG;AACf,iBAAO;AAAA,QACT,CAAC;AAGD,cAAM,UAAU,oBAAI,IAAY;AAChC,qBAAa,WAAW,aAAa,SAClC,OAAO,CAAC,MAAM;AACb,gBAAM,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI;AAChC,cAAI,QAAQ,IAAI,GAAG,EAAG,QAAO;AAC7B,kBAAQ,IAAI,GAAG;AACf,iBAAO;AAAA,QACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAG9C,qBAAa,UAAU,CAAC,GAAG,IAAI,IAAI,aAAa,OAAO,CAAC;AACxD,qBAAa,qBAAqB;AAAA,UAChC,aAAa;AAAA,UACb,aAAa,sBAAsB,CAAC;AAAA,UACpC,KAAK,KAAK;AAAA,QACZ;AACA,qBAAa,QAAQ,mBAAmB,aAAa,UAAU,aAAa,kBAAkB;AAE9F,cAAM,mBAAmB,oBAAI,IAAY;AACzC,qBAAa,iBAAiB,aAAa,iBAAiB,CAAC,GAAG,OAAO,CAAC,YAAY;AAClF,gBAAM,MAAM,GAAG,QAAQ,KAAK,KAAK,QAAQ,MAAM,KAAK,IAAI,CAAC;AACzD,cAAI,iBAAiB,IAAI,GAAG,EAAG,QAAO;AACtC,2BAAiB,IAAI,GAAG;AACxB,iBAAO;AAAA,QACT,CAAC;AAGD,YAAI,CAAC,aAAa,MAAM;AACtB,gBAAM,UAAU,UAAU,QAAQ,GAAG;AACrC,uBAAa,OAAO,YAAY,KAAK,UAAU,MAAM,UAAU,CAAC,IAAI;AAAA,QACtE;AAEA,qBAAa,UAAU,aAAa,WAAW,aAAa,YAAW,oBAAI,KAAK,GAAE,YAAY;AAC9F,qBAAa,UAAU,aAAa,YAAW,oBAAI,KAAK,GAAE,YAAY;AAEtE,cAAM,gBAAgBA,MAAK,KAAK,KAAK,KAAK,aAAa,GAAG,SAAS,KAAK;AACxE,cAAM,KAAK,KAAK,uBAAuB,eAAe,oBAAoB,cAAc,KAAK,KAAK,eAAe,KAAK,KAAK,sBAAsB,CAAC,CAAC;AACnJ,aAAK,KAAK,0BAA0B;AAGpC,mBAAW,QAAQ,OAAO;AACxB,gBAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,aAAa,IAAI;AACtD,cAAI,aAAa,eAAe;AAC9B,gBAAI;AACF,oBAAM,OAAO,QAAQ;AACrB;AACA,kBAAI,MAAM,iBAAiB,IAAI,WAAM,SAAS,KAAK;AAAA,YACrD,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA0B,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,IAElF;AAEA,WAAO;AAAA,EACT;AACF;;;ACx5BA,SAAS,WAAAG,gBAAe;AACxB,OAAOC,WAAU;AAiCV,IAAM,0BAAN,MAA8B;AAAA,EACnC,YAA6B,MAAmC;AAAnC;AAAA,EAAoC;AAAA,EAApC;AAAA,EAE7B,MAAM,oBAAoB,SAAgC;AACxD,UAAM,KAAK,KAAK,kBAAkB;AAClC,UAAM,KAAK,KAAK,uBAAuB,KAAK,KAAK,oBAAoB,OAAO;AAAA,EAC9E;AAAA,EAEA,MAAM,qBAA6C;AACjD,QAAI;AACF,aAAO,MAAM,KAAK,KAAK,sBAAsB,KAAK,KAAK,kBAAkB;AAAA,IAC3E,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,yBAAyB,OAAuE;AACpG,UAAM,KAAK,KAAK,kBAAkB;AAClC,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,OAAO,OAAO,MAAM,GAAG,EAAE;AAC/B,UAAM,KAAK,KAAK,KAAK,WAAW,UAAU;AAC1C,UAAM,WAAW,+BAA+B,IAAI,OAAO,MAAM;AACjE,UAAM,WAAWC,MAAK,KAAK,KAAK,KAAK,sBAAsB,GAAG,IAAI,IAAI,EAAE,KAAK;AAC7E,UAAM,KAAK,KAAK,uBAAuB,UAAU,4BAA4B,QAAQ,CAAC;AACtF,WAAO,EAAE,GAAG,UAAU,SAAS;AAAA,EACjC;AAAA,EAEA,MAAM,wBACJ,QAAQ,KACR,QAAmC,OACE;AACrC,UAAM,kBAAkB,OAAO,SAAS,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI;AACrE,UAAM,cAAc,KAAK,IAAI,GAAG,eAAe;AAC/C,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,QAAI;AACF,YAAM,aAAa,MAAM,KAAK,gCAAgC;AAC9D,YAAM,YAAwC,CAAC;AAE/C,iBAAW,QAAQ,YAAY;AAC7B,YAAI,UAAU,UAAU,YAAa;AACrC,cAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,sBAAsB,IAAI;AAC/D,YAAI;AACF,gBAAM,MAAM,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAC1D,gBAAM,SAAS,wBAAwB,GAAG;AAC1C,cAAI,CAAC,OAAQ;AACb,cAAI,UAAU,SAAS,OAAO,UAAU,MAAO;AAC/C,oBAAU,KAAK,EAAE,GAAG,QAAQ,SAAS,CAAC;AAAA,QACxC,SAAS,KAAK;AACZ,cAAI,eAAe,uBAAwB,OAAM;AAAA,QAEnD;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,wBACJ,IACA,SAC0C;AAC1C,UAAM,iBAAiB,MAAM,KAAK,mCAAmC,EAAE;AACvE,UAAM,SAAS,iBAAiB,MAAM,KAAK,2BAA2B,cAAc,IAAI;AACxF,QAAI,CAAC,UAAU,CAAC,eAAgB,QAAO;AACvC,QAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,UAAM,SAAS,8BAA8B,QAAQ,UAAS,oBAAI,KAAK,GAAE,YAAY,CAAC;AACtF,UAAM,KAAK,KAAK,uBAAuB,gBAAgB,4BAA4B,MAAM,CAAC;AAC1F,WAAO,EAAE,GAAG,QAAQ,UAAU,eAAe;AAAA,EAC/C;AAAA,EAEA,MAAM,mBAAmB,QAA8B,KAAa,SAAkC;AACpG,UAAM,KAAK,KAAK,kBAAkB;AAClC,UAAM,UAAU,KAAK,yBAAyB,GAAG;AACjD,UAAM,MAAM,WAAW,WAAW,KAAK,KAAK,0BAA0B,KAAK,KAAK;AAChF,UAAM,WAAWA,MAAK,KAAK,KAAK,GAAG,OAAO,KAAK;AAC/C,UAAM,KAAK,KAAK,uBAAuB,UAAU,OAAO;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,QAA8B,KAAqC;AACzF,QAAI;AACF,YAAM,UAAU,KAAK,yBAAyB,GAAG;AACjD,YAAM,MAAM,WAAW,WAAW,KAAK,KAAK,0BAA0B,KAAK,KAAK;AAChF,aAAO,MAAM,KAAK,KAAK,sBAAsBA,MAAK,KAAK,KAAK,GAAG,OAAO,KAAK,CAAC;AAAA,IAC9E,SAAS,KAAK;AACZ,UAAI,eAAe,SAAS,IAAI,YAAY,6BAA8B,QAAO;AACjF,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,8BAA8B,SAAgC;AAClE,UAAM,KAAK,KAAK,kBAAkB;AAClC,UAAM,KAAK,KAAK,uBAAuB,KAAK,KAAK,8BAA8B,OAAO;AAAA,EACxF;AAAA,EAEA,MAAM,+BAAuD;AAC3D,QAAI;AACF,aAAO,MAAM,KAAK,KAAK,sBAAsB,KAAK,KAAK,4BAA4B;AAAA,IACrF,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,sCAA4E;AAChF,UAAM,MAAM,MAAM,KAAK,6BAA6B;AACpD,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,WAAO,gCAAgC,GAAG;AAAA,EAC5C;AAAA,EAEA,MAAM,8BAA8B,OAAsE;AACxG,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,MAAM,MAAM,KAAK,6BAA6B;AACpD,UAAM,EAAE,UAAU,KAAK,IAAI,+BAA+B,KAAK,OAAO,MAAM;AAC5E,UAAM,KAAK,8BAA8B,QAAQ;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,8BACJ,IACA,OAC2C;AAC3C,UAAM,MAAM,MAAM,KAAK,6BAA6B;AACpD,UAAM,EAAE,UAAU,KAAK,IAAI,+BAA+B,KAAK,IAAI,QAAO,oBAAI,KAAK,GAAE,YAAY,CAAC;AAClG,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,KAAK,8BAA8B,QAAQ;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kCAAqD;AACjE,UAAM,QAAQ,MAAMC,SAAQ,KAAK,KAAK,oBAAoB;AAC1D,WAAO,MACJ,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,CAAC,EACrC,KAAK,EACL,QAAQ;AAAA,EACb;AAAA,EAEA,MAAc,2BAA2B,UAA4D;AACnG,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,KAAK,sBAAsB,QAAQ;AAC1D,YAAM,SAAS,wBAAwB,GAAG;AAC1C,aAAO,SAAS,EAAE,GAAG,QAAQ,SAAS,IAAI;AAAA,IAC5C,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,mCAAmC,IAAoC;AACnF,UAAM,YAAY,MAAM,KAAK,gCAAgC;AAC7D,UAAM,cAAc,UAAU,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,KAAK,CAAC;AACvE,QAAI,aAAa;AACf,YAAM,aAAaD,MAAK,KAAK,KAAK,KAAK,sBAAsB,WAAW;AACxE,YAAM,SAAS,MAAM,KAAK,2BAA2B,UAAU;AAC/D,UAAI,QAAQ,OAAO,GAAI,QAAO;AAAA,IAChC;AAEA,eAAW,YAAY,WAAW;AAChC,YAAM,WAAWA,MAAK,KAAK,KAAK,KAAK,sBAAsB,QAAQ;AACnE,YAAM,SAAS,MAAM,KAAK,2BAA2B,QAAQ;AAC7D,UAAI,QAAQ,OAAO,GAAI,QAAO;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,yBAAyB,KAAqB;AACpD,UAAM,UAAU,IAAI,KAAK;AACzB,QAAI,CAAC,+BAA+B,KAAK,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AAC3E,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AACF;;;AC9NA,SAAS,YAAY,kBAAkB;AACvC;AAAA,EACE;AAAA,EACA,SAAAE;AAAA,EACA;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,UAAAC;AAAA,EACA;AAAA,OACK;AACP,OAAOC,WAAU;AAEjB,SAAS,SAAS;AAkBlB,IAAM,wCAAwC;AAC9C,IAAM,8CAA8C;AACpD,IAAM,iDAAiD;AACvD,IAAM,0BAA0B;AAChC,IAAM,6BAA6B;AACnC,IAAM,4BAA4B;AAClC,IAAM,mCAAmC;AAEzC,IAAM,wCAAwC,EAAE,OAAO;AAAA,EACrD,SAAS,EAAE,QAAQ,qCAAqC;AAAA,EACxD,UAAU,EAAE,QAAQ;AAAA,EACpB,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AAChD,CAAC;AAkCD,eAAe,gBAAgB,UAAmC;AAChE,MAAI;AACJ,MAAI;AACF,eAAW,MAAMC,OAAM,QAAQ;AAAA,EACjC,SAAS,OAAO;AACd,QAAI,CAAC,YAAY,OAAO,QAAQ,EAAG,OAAM;AAAA,EAC3C;AACA,SAAO,WACH,GAAG,SAAS,GAAG,IAAI,SAAS,GAAG,IAAI,SAAS,OAAO,IAAI,SAAS,OAAO,IAAI,SAAS,IAAI,KACxF;AACN;AAEA,eAAe,yBAAyB,aAAsC;AAC5E,MAAI;AACJ,MAAI;AACF,aAAS,MAAMC,SAAQ,WAAW,GAC/B,OAAO,CAAC,SAASC,MAAK,QAAQ,IAAI,MAAM,KAAK,EAC7C,KAAK;AAAA,EACV,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACA,QAAM,OAAO,WAAW,QAAQ;AAChC,aAAW,QAAQ,OAAO;AACxB,SAAK,OAAO,GAAG,KAAK,MAAM,IAAI,IAAI,GAAG;AACrC,QAAI;AACF,YAAM,QAAQ,MAAMF,OAAME,MAAK,KAAK,aAAa,IAAI,GAAG,EAAE,QAAQ,KAAK,CAAC;AACxE,WAAK,OAAO,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO,EAAE;AAAA,IACzF,SAAS,OAAO;AACd,UAAI,CAAC,YAAY,OAAO,QAAQ,EAAG,OAAM;AACzC,WAAK,OAAO,SAAS;AAAA,IACvB;AACA,SAAK,OAAO,IAAI;AAAA,EAClB;AACA,SAAO,KAAK,OAAO,KAAK;AAC1B;AAQA,eAAsB,eACpB,SACA,aACA,0BACiB;AACjB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpB,gBAAgB,WAAW;AAAA,IAC3B,yBAAyB,WAAW;AAAA,IACpC,gBAAgBA,MAAK,KAAK,SAAS,UAAU,cAAc,CAAC;AAAA,IAC5D,gBAAgBA,MAAK,KAAK,SAAS,SAAS,oCAAoC,CAAC;AAAA,IACjF,gBAAgBA,MAAK,KAAK,SAAS,SAAS,8CAA8C,CAAC;AAAA,EAC7F,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,yBAAyB;AAAA,EAC3B,EAAE,KAAK,GAAG;AACZ;AAEA,eAAsB,cACpB,SACA,aACA,UACA,YACe;AACf,MAAI;AACJ,MAAI;AACF,eAAW,MAAMF,OAAM,OAAO;AAAA,EAChC,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG;AAClC,UAAM;AAAA,EACR;AACA,MAAI,SAAS,eAAe,KAAK,CAAC,SAAS,YAAY,GAAG;AACxD,UAAM,IAAI,MAAM,sEAAsE,OAAO,GAAG;AAAA,EAClG;AACA,QAAM,aAAa,MAAMG,UAAS,OAAO;AACzC,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG,qBAAqB,IAAI,CAAC,cAAcD,MAAK,KAAK,SAAS,SAAS,CAAC;AAAA,IACxEA,MAAK,KAAK,SAAS,MAAM;AAAA,IACzB;AAAA,EACF;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI;AACJ,QAAI;AACF,iBAAW,MAAMF,OAAM,IAAI;AAAA,IAC7B,SAAS,OAAO;AACd,UAAI,YAAY,OAAO,QAAQ,EAAG;AAClC,YAAM;AAAA,IACR;AACA,QAAI,SAAS,eAAe,KAAK,CAAC,SAAS,YAAY,GAAG;AACxD,YAAM,IAAI,MAAM,sEAAsE,IAAI,GAAG;AAAA,IAC/F;AACA,yBAAqB,YAAY,MAAMG,UAAS,IAAI,GAAG,IAAI;AAAA,EAC7D;AACF;AAEA,SAAS,UAAU,MAAsD;AACvE,SAAOD,MAAK,KAAK,KAAK,UAAU,kCAAkC;AACpE;AAEA,eAAe,6BACb,MACe;AACf,QAAM,qBAAqB,UAAU,IAAI;AACzC,MAAI;AACJ,MAAI;AACF,eAAW,MAAMF,OAAM,kBAAkB;AAAA,EAC3C,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG;AAClC,UAAM;AAAA,EACR;AACA,MAAI,SAAS,eAAe,KAAK,CAAC,SAAS,OAAO,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,+EAA+E,kBAAkB;AAAA,IACnG;AAAA,EACF;AACA,QAAM,CAAC,WAAW,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC/CG,UAAS,KAAK,QAAQ;AAAA,IACtBA,UAAS,kBAAkB;AAAA,EAC7B,CAAC;AACD,uBAAqB,WAAW,WAAW,kBAAkB;AAC/D;AACA,eAAe,wBACb,MACA,eACkB;AAClB,MAAI;AACJ,MAAI;AACF,eAAW,MAAMH,OAAM,aAAa;AAAA,EACtC,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACA,MAAI,SAAS,eAAe,KAAK,CAAC,SAAS,OAAO,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,2EAA2E,aAAa;AAAA,IAC1F;AAAA,EACF;AACA,QAAM,CAAC,WAAW,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,IACnDG,UAAS,KAAK,QAAQ;AAAA,IACtBA,UAAS,aAAa;AAAA,EACxB,CAAC;AACD,uBAAqB,WAAW,eAAe,aAAa;AAC5D,SAAO;AACT;AAEA,SAAS,SAAS,MAAsD;AACtE,SAAOD,MAAK,KAAK,KAAK,UAAU,oCAAoC;AACtE;AAGA,eAAe,UACb,MACiD;AACjD,QAAM,6BAA6B,IAAI;AACvC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,SAAS,UAAU,IAAI,GAAG,OAAO;AAAA,EAC/C,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACA,QAAM,SAAS,sCAAsC,UAAU,MAAM;AACrE,MAAI,CAAC,OAAO,QAAS,OAAM,IAAI,MAAM,8CAA8C;AACnF,aAAW,YAAY,CAAC,OAAO,KAAK,UAAU,OAAO,KAAK,WAAW,CAAC,CAAC,GAAG;AACxE,eAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC9D,yBAAmB,QAAQ;AAC3B,yBAAmB,WAAW;AAAA,IAChC;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAEA,eAAe,WACb,MACA,OACe;AACf,QAAM,cAAc,UAAU,IAAI;AAClC,QAAM,YAAY,GAAG,WAAW,IAAI,QAAQ,GAAG,IAAI,WAAW,CAAC;AAC/D,MAAI;AACF,UAAM,UAAU,WAAW,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AACzE,UAAM,OAAO,WAAW,WAAW;AAAA,EACrC,UAAE;AACA,UAAME,QAAO,SAAS,EAAE,MAAM,MAAM,MAAS;AAAA,EAC/C;AACF;AAUA,eAAe,aACb,MACA,OACe;AACf,QAAM,gCAAgC,KAAK,UAAU,YAAY;AAC/D,UAAM,WAAW,MAAM,KAAK;AAAA,EAC9B,CAAC;AACH;AAEA,eAAe,WAAW,UAAoC;AAC5D,MAAI;AACF,UAAM,OAAO,QAAQ;AACrB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACF;AAEA,eAAe,iBAAiB,UAAkB,WAAqC;AACrF,MAAI;AACF,UAAM,CAAC,MAAM,KAAK,IAAI,MAAM,QAAQ,IAAI,CAAC,SAAS,QAAQ,GAAG,SAAS,SAAS,CAAC,CAAC;AACjF,WAAO,KAAK,QAAQ,MAAM,OAAO,KAAK,QAAQ,MAAM;AAAA,EACtD,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACF;AAEA,eAAe,iBAAiB,UAAkB,OAA8B;AAC9E,MAAIC;AACJ,MAAI;AACF,IAAAA,QAAO,MAAML,OAAM,QAAQ;AAAA,EAC7B,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG;AAClC,UAAM;AAAA,EACR;AACA,MAAIK,MAAK,eAAe,GAAG;AACzB,UAAM,IAAI,MAAM,2DAA2D,KAAK,GAAG;AAAA,EACrF;AACF;AACA,eAAe,uBAAuB,UAAiC;AACrE,MAAIA;AACJ,MAAI;AACF,IAAAA,QAAO,MAAML,OAAM,QAAQ;AAAA,EAC7B,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG;AAClC,UAAM;AAAA,EACR;AACA,MAAIK,MAAK,eAAe,GAAG;AACzB,UAAM,IAAI,MAAM,oEAAoE,QAAQ,GAAG;AAAA,EACjG;AACF;AACA,eAAe,6BACb,MACA,UACA,iBACA,UACe;AACf,QAAM,gBAAgB,MAAM,KAAK,sBAAsB,QAAQ;AAC/D,MAAI,kBAAkB,iBAAiB;AACrC,UAAM,IAAI,MAAM,oBAAoB,QAAQ,wDAAwD;AAAA,EACtG;AACF;AAEA,eAAe,sBAAsB,aAAwC;AAC3E,QAAM,WAAW,MAAML,OAAM,WAAW;AACxC,MAAI,SAAS,eAAe,KAAK,CAAC,SAAS,YAAY,GAAG;AACxD,UAAM,IAAI,MAAM,4FAA4F;AAAA,EAC9G;AACA,QAAM,UAAU,MAAMC,SAAQ,WAAW;AACzC,aAAW,SAAS,SAAS;AAC3B,UAAM,iBAAiBC,MAAK,KAAK,aAAa,KAAK,GAAG,KAAK;AAAA,EAC7D;AACA,SAAO;AACT;AAWA,eAAe,iBACb,MACA,gBAAkD,CAAC,GACnD,UAA8B,oBAAI,IAAI,GACL;AACjC,QAAM,WAAmC,CAAC;AAC1C,QAAM,kBAAkB,oBAAI,IAAsB;AAMlD,UAAQ,MAAM;AACd,QAAM,gBAAgB,MAAM,sBAAsB,KAAK,WAAW;AAClE,aAAW,SAAS,eAAe;AACjC,QAAI,CAAC,MAAM,SAAS,KAAK,EAAG;AAC5B,UAAM,WAAW,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM;AAC7C,uBAAmB,QAAQ;AAC3B,UAAM,aAAa,KAAK,sBAAsB,QAAQ;AACtD,QAAI,eAAe,KAAM;AACzB,UAAM,gBAAgB,MAAM,KAAK,sBAAsB,UAAU;AACjE,QACE,CAAC,sBAAsB,KAAK,aAAa,KACtC,CAAC,kCAAkC,KAAK,aAAa,GACxD;AACA,YAAM,IAAI,MAAM,wCAAwC,KAAK,iCAAiC;AAAA,IAChG;AACA,UAAM,SAAS,KAAK,gBAAgB,aAAa;AACjD,QAAI,CAAC,OAAO,KAAK,KAAK,KAAK,CAAC,OAAO,KAAK,KAAK,GAAG;AAC9C,YAAM,IAAI,MAAM,wCAAwC,KAAK,yBAAyB;AAAA,IACxF;AACA,UAAM,cAAc,KAAK,oBAAoB,OAAO,MAAM,OAAO,IAAI;AACrE,uBAAmB,WAAW;AAC9B,QAAI,aAAa,YAAa;AAC9B,UAAM,gBAAgB,KAAK,sBAAsB,WAAW;AAC5D,QAAI,kBAAkB,KAAM;AAC5B,UAAM,kBAAkB,MAAM,WAAW,aAAa;AACtD,QACE,mBACG,MAAM,iBAAiB,YAAY,aAAa,KAChD,cAAc,QAAQ,MAAM,YAC/B;AACF,QAAI,iBAAiB;AACnB,YAAMI,oBAAmB,MAAM,KAAK,sBAAsB,aAAa;AACvE,UAAI,kBAAkBA,mBAAkB;AACtC,gBAAQ,IAAI,UAAU,WAAW;AACjC;AAAA,MACF;AAAA,IACF;AACA,oBAAgB,IAAI,aAAa,CAAC,GAAI,gBAAgB,IAAI,WAAW,KAAK,CAAC,GAAI,QAAQ,CAAC;AACxF,aAAS,QAAQ,IAAI;AAAA,EACvB;AAIA,aAAW,CAAC,aAAa,SAAS,KAAK,iBAAiB;AACtD,QAAI,UAAU,SAAS,EAAG;AAC1B,eAAW,YAAY,WAAW;AAChC,cAAQ,IAAI,UAAU,WAAW;AACjC,aAAO,SAAS,QAAQ;AAAA,IAC1B;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,kBACb,MACA,UACA,aACyC;AACzC,MAAI,oBAAoB;AACxB,WAAS,OAAO,GAAG,OAAO,2BAA2B,QAAQ,GAAG;AAC9D,SAAK,2BAA2B;AAChC,SAAK,4BAA4B;AACjC,UAAM,CAAC,aAAa,cAAc,gBAAgB,IAAI,MAAM,QAAQ,IAAI;AAAA,MACtE,KAAK,gBAAgB;AAAA,MACrB,KAAK,oBAAoB;AAAA,MACzB,KAAK,qBAAqB;AAAA,IAC5B,CAAC;AACD,UAAM,YAAY,oBAAI,IAAY;AAClC,QAAI,aAAa;AACjB,eAAW,UAAU,CAAC,GAAG,aAAa,GAAG,cAAc,GAAG,gBAAgB,GAAG;AAC3E,YAAM,aAAaJ,MAAK,QAAQ,OAAO,IAAI;AAC3C,UAAI,UAAU,IAAI,UAAU,EAAG;AAC/B,gBAAU,IAAI,UAAU;AACxB,YAAM,oBAAoB,OAAO,YAAY;AAC7C,YAAM,cAAc,oBAAoB,SAAS,iBAAiB,IAAI;AACtE,UAAI,CAAC,qBAAqB,CAAC,YAAa;AACxC,YAAM,uBAAuB,OAAO,IAAI;AACxC,YAAM,4BAA4B,MAAM,gBAAgB,OAAO,IAAI;AACnE,UAAI,8BAA8B,UAAW;AAC7C,UAAI,CAAE,MAAM,YAAY,EAAI,OAAM,IAAI,MAAM,0CAA0C;AACtF,YAAM,eAAe,MAAM,KAAK,iBAAiB,OAAO,IAAI;AAC5D,UAAI,CAAC,aAAc;AACnB,YAAM,0BAA0B,MAAM,gBAAgB,aAAa,IAAI;AACvE,UAAI,4BAA4B,0BAA2B;AAC3D,YAAM,0BAA0B,aAAa,YAAY;AACzD,YAAM,oBAAoB,0BAA0B,SAAS,uBAAuB,IAAI;AACxF,UAAI,CAAC,2BAA2B,CAAC,kBAAmB;AACpD,YAAM,kBAAkB,MAAM,KAAK,uBAAuB,aAAa,IAAI;AAC3E,UAAK,MAAM,gBAAgB,aAAa,IAAI,MAAO,wBAAyB;AAC5E,YAAM,KAAK,oBAAoB,aAAa,MAAM,OAAO;AACzD,UAAK,MAAM,gBAAgB,aAAa,IAAI,MAAO,wBAAyB;AAC5E,YAAM,KAAK;AAAA,QACT,aAAa;AAAA,QACb,KAAK,6BAA6B,cAAc,iBAAiB;AAAA,QACjE;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,aAAa,YAAY;AAAA,QACzB;AAAA,QACA;AAAA,MACF;AACA,mBAAa;AACb,4BAAsB,aAAa,KAAK,SAAS,GAAGA,MAAK,GAAG,OAAOA,MAAK,GAAG,EAAE;AAAA,IAC/E;AACA,QAAI,CAAC,WAAY,QAAO,EAAE,kBAAkB;AAAA,EAC9C;AACA,QAAM,IAAI,MAAM,6FAA6F;AAC/G;AAEA,SAAS,qBACP,MACA,UACA,oBACQ;AACR,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO;AAE3E,QAAM,YAAY;AAClB,MAAI,UAAU;AACd,MAAI,OAAO,UAAU,cAAc,UAAU;AAC3C,UAAM,cAAc,SAAS,UAAU,SAAS;AAChD,QAAI,aAAa;AACf,gBAAU,YAAY;AACtB,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,MAAI,OAAO,UAAU,oBAAoB,UAAU;AACjD,UAAM,YAAY,UAAU,gBAAgB,QAAQ,IAAI;AACxD,QAAI,YAAY,EAAG,QAAO,UAAU,KAAK,UAAU,SAAS,IAAI;AAChE,UAAM,qBAAqB,yBAAyB,UAAU,gBAAgB,MAAM,GAAG,SAAS,CAAC;AACjG,UAAM,cAAc,mBAAmB,IAAI,kBAAkB;AAC7D,QAAI,aAAa;AACf,YAAM,eAAe,uBAAuB,aAAa,UAAU,gBAAgB,MAAM,YAAY,CAAC,CAAC;AACvG,UAAI,cAAc;AAChB,kBAAU,kBAAkB;AAC5B,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACA,SAAO,UAAU,KAAK,UAAU,SAAS,IAAI;AAC/C;AAEA,eAAe,2BACb,MACA,UACA,aACe;AACf,QAAM,gBAAgBA,MAAK,KAAK,KAAK,UAAU,kBAAkB;AACjE,QAAM,qBAAqB,oBAAI,IAAoB;AACnD,aAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC9D,UAAM,qBAAqB,yBAAyB,QAAQ;AAC5D,QAAI,sBAAsB,CAAC,mBAAmB,IAAI,kBAAkB,GAAG;AACrE,yBAAmB,IAAI,oBAAoB,WAAW;AAAA,IACxD;AAAA,EACF;AAEA,QAAM;AAAA,IACJA,MAAK,KAAK,KAAK,UAAU,iBAAiB;AAAA,IAC1C;AAAA,MACE,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,OAAO,UAAU,kBAAkB;AACjC,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,mDAAmD;AAClF,UAAI,CAAE,MAAM,wBAAwB,MAAM,aAAa,EAAI;AAC3D,YAAM,qBAAqB,MAAM,KAAK,uBAAuB,aAAa;AAC1E,YAAM,WAAW,MAAM,KAAK,sBAAsB,aAAa;AAC/D,UAAI,UAAU;AACd,YAAM,YAAY,SACf,MAAM,IAAI,EACV,IAAI,CAAC,SAAS;AACb,cAAM,OAAO,qBAAqB,MAAM,UAAU,kBAAkB;AACpE,oBAAY,SAAS;AACrB,eAAO;AAAA,MACT,CAAC,EACA,KAAK,IAAI;AACZ,UAAI,CAAC,QAAS;AACd,UAAI,CAAE,MAAM,YAAY,EAAI,OAAM,IAAI,MAAM,0CAA0C;AACtF,UAAI,CAAE,MAAM,cAAc,QAAQ,EAAI,OAAM,IAAI,MAAM,gCAAgC;AACtF,YAAM,KAAK,oBAAoB,eAAe,OAAO;AACrD,YAAM,KAAK,uBAAuB,eAAe,WAAW,kBAAkB;AAAA,IAChF;AAAA,EACF;AACF;AAEA,eAAe,2BACb,MACA,UACA,aACkB;AAClB,MAAI,YAAY;AAChB,QAAM,UAAU,MAAM,sBAAsB,KAAK,WAAW;AAC5D,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,SAAS,KAAK,EAAG;AAC5B,UAAM,aAAa,KAAK,sBAAsB,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC;AAC3E,QAAI,eAAe,KAAM;AACzB,UAAM,4BAA4B,MAAM,gBAAgB,UAAU;AAClE,QAAI,8BAA8B,UAAW;AAC7C,UAAM,SAAS,KAAK,gBAAgB,MAAM,KAAK,sBAAsB,UAAU,CAAC;AAChF,UAAM,gBAAgB,OAAO,cAAc,IAAI,CAAC,iBAAiB;AAC/D,YAAM,SAAS,SAAS,aAAa,MAAM;AAC3C,aAAO,SAAS,EAAE,GAAG,cAAc,OAAO,IAAI;AAAA,IAChD,CAAC;AACD,QAAI,cAAc,MAAM,CAAC,cAAc,UAAU,iBAAiB,OAAO,cAAc,KAAK,CAAC,EAAG;AAChG,UAAM,gBAAgB,MAAM;AAAA,MAC1B,KAAK;AAAA,MACL,OAAO,sBAAsB;AAC3B,YAAI,CAAE,MAAM,YAAY,EAAI,OAAM,IAAI,MAAM,0CAA0C;AACtF,cAAM,eAAe,KAAK,gBAAgB,MAAM,KAAK,sBAAsB,UAAU,CAAC;AACtF,YAAK,MAAM,gBAAgB,UAAU,MAAO,0BAA2B,QAAO;AAC9E,cAAM,sBAAsB,aAAa,cAAc,IAAI,CAAC,iBAAiB;AAC3E,gBAAM,SAAS,SAAS,aAAa,MAAM;AAC3C,iBAAO,SAAS,EAAE,GAAG,cAAc,OAAO,IAAI;AAAA,QAChD,CAAC;AACD,YAAI,oBAAoB,MAAM,CAAC,cAAc,UAAU,iBAAiB,aAAa,cAAc,KAAK,CAAC,GAAG;AAC1G,iBAAO;AAAA,QACT;AACA,cAAM,kBAAkB,MAAM,KAAK,uBAAuB,UAAU;AACpE,YAAI,CAAE,MAAM,kBAAkB,EAAI,OAAM,IAAI,MAAM,4BAA4B;AAC9E,YAAK,MAAM,gBAAgB,UAAU,MAAO,0BAA2B,QAAO;AAC9E,cAAM,KAAK,oBAAoB,YAAY,OAAO;AAClD,YAAK,MAAM,gBAAgB,UAAU,MAAO,0BAA2B,QAAO;AAC9E,cAAM,KAAK;AAAA,UACT;AAAA,UACA,KAAK,oBAAoB,EAAE,GAAG,cAAc,eAAe,oBAAoB,CAAC;AAAA,UAChF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,kBAAc;AAAA,EAChB;AACA,SAAO;AACT;AAEA,eAAe,uBACb,MACA,UACA,aACkB;AAClB,QAAM,2BAA2B,MAAM,UAAU,WAAW;AAC5D,MAAI,qBAAqB,MAAM,kBAAkB,MAAM,UAAU,WAAW,GAAG;AAC/E,QAAM,2BAA2B,MAAM,UAAU,WAAW;AAC5D,QAAM,KAAK,iCAAiC,QAAQ;AACpD,QAAM,kBAAkB,MAAM,kBAAkB,MAAM,UAAU,WAAW;AAC3E,wBAAsB,gBAAgB;AACtC,SAAO;AACT;AAEA,SAAS,wBACP,UACA,UACA,aACS;AACT,MAAI,UAAU;AACd,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,MAAM;AACX,QAAI,YAAY,SAAU,QAAO;AACjC,QAAI,KAAK,IAAI,OAAO,EAAG,QAAO;AAC9B,SAAK,IAAI,OAAO;AAChB,UAAM,OAAO,SAAS,OAAO;AAC7B,QAAI,CAAC,QAAQ,SAAS,QAAS,QAAO;AACtC,cAAU;AAAA,EACZ;AACF;AAEA,SAAS,oBACP,UACA,YACwB;AACxB,QAAM,WAAmC,CAAC;AAC1C,QAAM,SAAS,EAAE,GAAG,SAAS;AAC7B,aAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,UAAU,GAAG;AAChE,QACE,OAAO,QAAQ,MAAM,UACrB,wBAAwB,QAAQ,UAAU,WAAW,EACrD;AACF,aAAS,QAAQ,IAAI;AACrB,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,wBACP,UACA,YACwB;AACxB,QAAM,SAAS,EAAE,GAAG,SAAS;AAC7B,QAAM,kBAAkB,oBAAI,IAAoB;AAChD,aAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,UAAU,GAAG;AAChE,UAAM,kBAAkB,OAAO,QAAQ;AACvC,QAAI,oBAAoB,UAAa,oBAAoB,aAAa;AAIpE,UAAI,MAA0B;AAC9B,YAAM,OAAO,oBAAI,IAAY;AAC7B,aAAO,QAAQ,UAAa,QAAQ,mBAAmB,CAAC,KAAK,IAAI,GAAG,GAAG;AACrE,aAAK,IAAI,GAAG;AACZ,cAAM,OAAO,GAAG;AAAA,MAClB;AACA,UAAI,QAAQ,iBAAiB;AAC3B,cAAM,IAAI,MAAM,oBAAoB,QAAQ,6CAA6C;AAAA,MAC3F;AACA;AAAA,IACF;AACA,QAAI,oBAAoB,UAAa,wBAAwB,QAAQ,UAAU,WAAW,EAAG;AAC7F,UAAM,gBAAgB,gBAAgB,IAAI,WAAW;AACrD,QAAI,kBAAkB,UAAa,kBAAkB,UAAU;AAC7D,YAAM,IAAI;AAAA,QACR,oCAAoC,aAAa,QAAQ,QAAQ,uBAAuB,WAAW;AAAA,MACrG;AAAA,IACF;AACA,WAAO,QAAQ,IAAI;AACnB,oBAAgB,IAAI,aAAa,QAAQ;AAAA,EAC3C;AACA,SAAO;AACT;AACA,SAAS,iBAAiB,UAAoE;AAC5F,QAAM,YAAoC,CAAC;AAC3C,aAAW,YAAY,OAAO,KAAK,QAAQ,GAAG;AAC5C,QAAI,UAAU;AACd,UAAM,OAAO,oBAAI,IAAY;AAC7B,WAAO,MAAM;AACX,YAAM,OAAO,SAAS,OAAO;AAC7B,UAAI,CAAC,QAAQ,SAAS,QAAS;AAC/B,UAAI,KAAK,IAAI,OAAO,GAAG;AACrB,cAAM,IAAI,MAAM,wDAAwD,QAAQ,GAAG;AAAA,MACrF;AACA,WAAK,IAAI,OAAO;AAChB,gBAAU;AAAA,IACZ;AACA,QAAI,YAAY,SAAU,WAAU,QAAQ,IAAI;AAAA,EAClD;AACA,SAAO;AACT;AASA,eAAe,sBACb,MACA,UACA,aACA,sBACoC;AACpC,SAAO,gCAAgC,KAAK,UAAU,OAAO,sBAAsB;AACjF,uBAAmB,QAAQ;AAC3B,uBAAmB,WAAW;AAC9B,UAAM,aAAa,KAAK,sBAAsB,QAAQ;AACtD,UAAM,gBAAgB,KAAK,sBAAsB,WAAW;AAC5D,QAAI,eAAe,QAAQ,kBAAkB,MAAM;AACjD,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AACA,UAAM,iBAAiB,YAAY,QAAQ;AAC3C,UAAM,iBAAiB,eAAe,WAAW;AACjD,UAAM,eAAe,MAAM,WAAW,UAAU;AAChD,UAAM,kBAAkB,MAAM,WAAW,aAAa;AACtD,QAAI,CAAC,gBAAgB,CAAC,gBAAiB,QAAO,EAAE,UAAU,MAAM,YAAY,MAAM;AAClF,QAAI,gBAAgB,iBAAiB;AACnC,UAAI,MAAM,iBAAiB,YAAY,aAAa,EAAG,QAAO,EAAE,UAAU,OAAO,YAAY,MAAM;AACnG,YAAM,CAAC,eAAeI,mBAAkB,iBAAiB,kBAAkB,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC/F,KAAK,sBAAsB,UAAU;AAAA,QACrC,KAAK,sBAAsB,aAAa;AAAA,QACxC,KAAK,uBAAuB,UAAU;AAAA,QACtC,KAAK,uBAAuB,aAAa;AAAA,MAC3C,CAAC;AACD,UAAI,kBAAkBA,mBAAkB;AAGtC,eAAO,EAAE,UAAU,OAAO,YAAY,OAAO,SAAS,KAAK;AAAA,MAC7D;AACA,UAAI,mBAAmB,CAAC,oBAAoB;AAC1C,YAAI,CAAE,MAAM,qBAAqB,KAAM,CAAE,MAAM,kBAAkB,GAAI;AACnE,gBAAM,IAAI,MAAM,0CAA0C;AAAA,QAC5D;AACA,cAAM,KAAK,oBAAoB,eAAe,OAAO;AACrD,cAAM,KAAK,uBAAuB,eAAe,eAAe,IAAI;AACpE,YAAK,MAAM,KAAK,sBAAsB,aAAa,MAAO,eAAe;AACvE,gBAAM,IAAI,MAAM,oCAAoC,WAAW,GAAG;AAAA,QACpE;AAAA,MACF;AACA,UAAI,CAAE,MAAM,qBAAqB,KAAM,CAAE,MAAM,kBAAkB,GAAI;AACnE,cAAM,IAAI,MAAM,0CAA0C;AAAA,MAC5D;AACA,YAAM,KAAK,oBAAoB,YAAY,OAAO;AAClD,YAAM,iBAAiB,YAAY,QAAQ;AAC3C,YAAM,6BAA6B,MAAM,YAAY,eAAe,QAAQ;AAC5E,YAAMF,QAAO,UAAU;AACvB,aAAO,EAAE,UAAU,OAAO,YAAY,KAAK;AAAA,IAC7C;AACA,QAAI,CAAC,aAAc,QAAO,EAAE,UAAU,OAAO,YAAY,MAAM;AAC/D,QAAI,CAAE,MAAM,qBAAqB,KAAM,CAAE,MAAM,kBAAkB,GAAI;AACnE,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AACA,UAAM,kBAAkB,MAAM,KAAK,uBAAuB,UAAU;AACpE,UAAM,gBAAgB,MAAM,KAAK,sBAAsB,UAAU;AACjE,UAAM,iBAAiB,YAAY,QAAQ;AAC3C,UAAM,6BAA6B,MAAM,YAAY,eAAe,QAAQ;AAC5E,QAAI,iCAAgD;AACpD,QAAI;AACF,YAAM,KAAK,uBAAuB,eAAe,eAAe,eAAe;AAC/E,uCAAiC,MAAM,gBAAgB,aAAa;AACpE,UAAK,MAAM,KAAK,sBAAsB,aAAa,MAAO,eAAe;AACvE,cAAM,IAAI,MAAM,oCAAoC,WAAW,GAAG;AAAA,MACpE;AACA,UAAI,CAAE,MAAM,qBAAqB,KAAM,CAAE,MAAM,kBAAkB,GAAI;AACnE,cAAM,IAAI,MAAM,0CAA0C;AAAA,MAC5D;AACA,YAAM,KAAK,oBAAoB,YAAY,OAAO;AAClD,YAAM,iBAAiB,YAAY,QAAQ;AAC3C,YAAM,6BAA6B,MAAM,YAAY,eAAe,QAAQ;AAC5E,YAAMA,QAAO,UAAU;AAAA,IACzB,SAAS,OAAO;AACd,UAAI,CAAC,mBAAmB,mCAAmC,MAAM;AAC/D,YAAI;AACF,cAAK,MAAM,gBAAgB,aAAa,MAAO,gCAAgC;AAC7E,kBAAM,iBAAiB,eAAe,WAAW;AACjD,kBAAMA,QAAO,aAAa;AAAA,UAC5B;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,YAAM;AAAA,IACR;AACA,WAAO,EAAE,UAAU,OAAO,YAAY,KAAK;AAAA,EAC7C,CAAC;AACH;AAEA,eAAsB,gCACpB,MAC6B;AAC7B,SAAO;AAAA,IACL,SAAS,IAAI;AAAA,IACb;AAAA,MACE,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,IACA,OAAO,UAAU,SAAS;AACxB,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,6DAA6D;AAC5F,YAAM,KAAK,0BAA0B;AACrC,YAAM,sBAAsB,KAAK,WAAW;AAO5C,YAAM,sBAAsBF,MAAK,KAAK,KAAK,UAAU,oCAAoC;AACzF,YAAM,sBAAsBA,MAAK,KAAK,KAAK,UAAU,8CAA8C;AACnG,UAAI,qBAAqB,MAAM,WAAW,mBAAmB;AAC7D,UAAI,MAAM,WAAW,mBAAmB,GAAG;AACzC,YAAI;AACF,gBAAM,OAAO,qBAAqB,mBAAmB;AACrD,+BAAqB;AAAA,QACvB,SAAS,OAAO;AACd,cAAI,CAAC,YAAY,OAAO,QAAQ,EAAG,OAAM;AAAA,QAC3C;AAAA,MACF;AACA,UAAI,QAAQ,MAAM,UAAU,IAAI;AAChC,UAAI,CAAC,OAAO;AACV,gBAAQ;AAAA,UACN,SAAS;AAAA,UACT,UAAU;AAAA,UACV,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AACA,YAAM,UAA8B,oBAAI,IAAI;AAG5C,YAAM,SAAS,YAAyC;AACtD,YAAI,QAAQ,OAAO,GAAG;AACpB,gBAAM,QAAQ,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,UAAU,WAAW,MAAM,GAAG,QAAQ,OAAO,WAAW,EAAE,EAAE,KAAK,IAAI;AACtG,cAAI;AAAA,YACF,yCAAyC,QAAQ,IAAI,0BAA0B,KAAK;AAAA,UAEtF;AAAA,QACF;AAMA,YAAI,oBAAoB;AACtB,gBAAME,QAAO,mBAAmB,EAAE,MAAM,CAAC,UAAmB;AAC1D,gBAAI,CAAC,YAAY,OAAO,QAAQ,EAAG,OAAM;AAAA,UAC3C,CAAC;AAAA,QACH;AAWA,cAAM,wBAAwB,MAAM,KAAK,2BAA2B;AACpE,YAAI,MAAM,WAAW,mBAAmB,EAAG,QAAO;AAClD,eAAO;AAAA,MACT;AASA,YAAM,eAAe,YAA8B;AACjD,cAAM,UAAU;AAChB,YAAI,CAAC,QAAS,QAAO;AAIrB,YAAI,UAAU;AACd,cAAM,SAAiC,EAAE,GAAI,QAAQ,WAAW,CAAC,EAAG;AACpE,cAAM,SAAiC,CAAC;AACxC,mBAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG;AACtE,cAAI,CAAC,QAAQ,IAAI,QAAQ,EAAG,QAAO,QAAQ,IAAI;AAAA,QACjD;AACA,mBAAW,CAAC,UAAU,WAAW,KAAK,QAAS,QAAO,QAAQ,IAAI;AASlE,mBAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC5D,cAAI,QAAQ,IAAI,QAAQ,EAAG;AAC3B,iBAAO,OAAO,QAAQ;AACtB,cAAI,OAAO,QAAQ,MAAM,OAAW;AACpC,gBAAM,aAAa,KAAK,sBAAsB,QAAQ;AACtD,cAAI,eAAe,QAAS,MAAM,WAAW,UAAU,EAAI;AAG3D,iBAAO,QAAQ,IAAI;AACnB,oBAAU;AAAA,QACZ;AAIA,cAAM,YAAY,iBAAiB,MAAM;AAGzC,mBAAW,CAAC,UAAU,WAAW,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC5D,gBAAM,QAAQ,UAAU,WAAW;AACnC,cAAI,UAAU,UAAa,UAAU,SAAU,QAAO,QAAQ,IAAI;AAAA,QACpE;AACA,cAAM,OAAO,CAAC,GAA2B,MACvC,OAAO,KAAK,CAAC,EAAE,WAAW,OAAO,KAAK,CAAC,EAAE,UACtC,OAAO,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,GAAG,MAAM,KAAK;AAC/D,YAAI,KAAK,WAAW,QAAQ,QAAQ,KAAK,KAAK,QAAQ,QAAQ,WAAW,CAAC,CAAC,EAAG,QAAO;AAKrF,gBAAQ,EAAE,GAAG,SAAS,UAAU,WAAW,SAAS,OAAO;AAC3D,cAAM,aAAa,MAAM,KAAK;AAC9B,eAAO;AAAA,MACT;AACA,YAAM,mBAAmB,MAAM;AAC/B,YAAM,oBAAoB,iBAAiB,gBAAgB;AAC3D,YAAM,kBACJ,OAAO,KAAK,iBAAiB,EAAE,WAAW,OAAO,KAAK,gBAAgB,EAAE,UACrE,OAAO,QAAQ,iBAAiB,EAAE;AAAA,QAAK,CAAC,CAAC,UAAU,WAAW,MAC/D,iBAAiB,QAAQ,MAAM;AAAA,MACjC;AACF,cAAQ,EAAE,GAAG,OAAO,UAAU,kBAAkB;AAChD,eAAS,gBAAgB,GAAG,gBAAgB,kCAAkC,iBAAiB,GAAG;AAChG,YAAI,CAAE,MAAM,KAAK,QAAQ,EAAI,OAAM,IAAI,MAAM,0CAA0C;AACvF,cAAM,mBAAmB;AAAA,UACvB,MAAM;AAAA,UACN,MAAM,iBAAiB,MAAM,MAAM,UAAU,OAAO;AAAA,QACtD;AACA,cAAM,gBAAgB,MAAM,aAAa;AACzC,cAAM,eAAe,iBAAiB,wBAAwB,MAAM,UAAU,gBAAgB,CAAC;AAY/F,YACE,MAAM,YACH,OAAO,KAAK,gBAAgB,EAAE,WAAW,KACzC,CAAC,mBACD,CAAC,eACJ;AAIA,cAAI,sBAAsB,OAAO,KAAK,MAAM,QAAQ,EAAE,SAAS,GAAG;AAChE,kBAAMG,qBAAoB,MAAM;AAAA,cAC9B;AAAA,cACA,MAAM;AAAA,cACN,MAAM,KAAK,QAAQ;AAAA,YACrB;AACA,iBAAK,8BAA8B;AACnC,iBAAK,2BAA2B;AAChC,gBAAIA,mBAAmB,MAAK,4BAA4B;AACxD,iBAAK,wBAAwB;AAAA,UAC/B;AACA,iBAAO,OAAO;AAAA,QAChB;AACA,YACE,MAAM,YACH,OAAO,KAAK,gBAAgB,EAAE,SAAS,KACvC,OAAO,KAAK,YAAY,EAAE,WAAW,OAAO,KAAK,MAAM,QAAQ,EAAE,QACpE;AACA,kBAAQ,EAAE,GAAG,OAAO,UAAU,OAAO,UAAU,aAAa;AAC5D,gBAAM,aAAa,MAAM,KAAK;AAAA,QAChC;AACA,YAAI,OAAO,KAAK,MAAM,QAAQ,EAAE,WAAW,GAAG;AAC5C,cAAI,CAAE,MAAM,KAAK,QAAQ,EAAI,OAAM,IAAI,MAAM,0CAA0C;AACvF,gBAAMC,mBAAkB;AAAA,YACtB,MAAM;AAAA,YACN,MAAM,iBAAiB,MAAM,MAAM,UAAU,OAAO;AAAA,UACtD;AAKA,gBAAM,kBAAkB,MAAM,aAAa;AAC3C,cAAI,OAAO,KAAKA,gBAAe,EAAE,WAAW,KAAK,CAAC,iBAAiB;AACjE,kBAAM,aAAa,MAAM,EAAE,GAAG,OAAO,UAAU,KAAK,CAAC;AACrD,mBAAO,OAAO;AAAA,UAChB;AACA,kBAAQ;AAAA,YACN,GAAG;AAAA,YACH,UAAU;AAAA,YACV,UAAU,iBAAiB,wBAAwB,MAAM,UAAUA,gBAAe,CAAC;AAAA,UACrF;AACA,gBAAM,aAAa,MAAM,KAAK;AAC9B;AAAA,QACF;AACA,YAAI,kBAAkB,OAAO,QAAQ,MAAM,QAAQ;AACnD,eAAO,gBAAgB,SAAS,GAAG;AACjC,gBAAM,mBAA4C,CAAC;AACnD,cAAI,aAAa;AACjB,qBAAW,CAAC,UAAU,WAAW,KAAK,iBAAiB;AACrD,kBAAM,SAAS,MAAM;AAAA,cACnB;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM,KAAK,QAAQ;AAAA,YACrB;AACA,gBAAI,OAAO,QAAS,SAAQ,IAAI,UAAU,WAAW;AAAA,qBAC5C,OAAO,SAAU,kBAAiB,KAAK,CAAC,UAAU,WAAW,CAAC;AACvE,2BAAe,OAAO;AAAA,UACxB;AACA,cAAI,iBAAiB,WAAW,EAAG;AACnC,cAAI,CAAC,YAAY;AACf,kBAAM,CAAC,UAAU,WAAW,IAAI,iBAAiB,CAAC;AAClD,kBAAM,IAAI;AAAA,cACR,mCAAmC,QAAQ;AAAA,YAC7C;AAAA,UACF;AACA,4BAAkB;AAAA,QACpB;AACA,cAAM,aAAa;AAEnB,cAAM,oBAAoB,MAAM;AAAA,UAC9B;AAAA,UACA,MAAM;AAAA,UACN,MAAM,KAAK,QAAQ;AAAA,QACrB;AACA,aAAK,8BAA8B;AACnC,aAAK,2BAA2B;AAChC,YAAI,kBAAmB,MAAK,4BAA4B;AACxD,aAAK,wBAAwB;AAE7B,YAAI,CAAE,MAAM,KAAK,QAAQ,EAAI,OAAM,IAAI,MAAM,0CAA0C;AACvF,cAAM,kBAAkB;AAAA,UACtB,MAAM;AAAA,UACN,MAAM,iBAAiB,MAAM,MAAM,UAAU,OAAO;AAAA,QACtD;AAKA,cAAM,sBAAsB,MAAM,aAAa;AAC/C,YAAI,OAAO,KAAK,eAAe,EAAE,WAAW,KAAK,CAAC,qBAAqB;AACrE,gBAAM,aAAa,MAAM,EAAE,GAAG,OAAO,UAAU,KAAK,CAAC;AACrD,iBAAO,OAAO;AAAA,QAChB;AACA,gBAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU;AAAA,UACV,UAAU,iBAAiB,wBAAwB,MAAM,UAAU,eAAe,CAAC;AAAA,QACrF;AACA,cAAM,aAAa,MAAM,KAAK;AAAA,MAChC;AACA,YAAM,IAAI,MAAM,8FAA8F;AAAA,IAChH;AAAA,EACF;AACF;;;AC9kCA,SAAS,UAAAC,eAAc;AAwChB,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,MAA2B;AAA3B;AAAA,EAA4B;AAAA,EAA5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7B,MAAM,KACJ,IACA,eACA,sBACgC;AAChC,QAAI,CAAC,KAAK,KAAK,kBAAkB,EAAG,QAAO;AAC3C,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,KAAK,kBAAkB;AAGhD,YAAM,mBACJ,GAAG,aAAa,uBACZ,wBAAwB,EAAE,WAAW,GAAG,WAAW,qBAAqB,CAAC,IACzE,CAAC;AACP,YAAM,QAAQ,+BAA+B,OAAO,IAAI;AAAA,QACtD,gBAAgB,iBAAiB,iBAAiB,aAAa;AAAA,QAC/D;AAAA,QACA,WAAW,KAAK,KAAK,oBAAoB;AAAA,MAC3C,CAAC;AACD,UAAI,OAAO;AACT,YAAI;AAAA,UACF,2CAA2C,GAAG,EAAE,UAAU,MAAM,WAAW,eAAe,MAAM,WAAW,YAAY,MAAM,MAAM;AAAA,QACrI;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AAEZ,UAAI,KAAK,oCAAoC,GAAG,EAAE,iBAAiB,GAAG,EAAE;AACxE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,OACJ,UACA,IACA,QACA,QACA,MACA,OAA+B,CAAC,GACjB;AACf,UAAM,kBAAkB,GAAG;AAC3B,QAAI;AACF,YAAiB,gCAAgC;AAAA,QAC/C,UAAU,KAAK,KAAK;AAAA,QACpB,YAAY,MAAM,KAAK,KAAK,qBAAqB;AAAA,QACjD,cAAc;AAAA,QACd;AAAA,QACA,aAAa;AAAA,QACb,SAAS,YAAY;AACnB,cAAI,KAAK,cAAc,GAAG,aAAa,QAAQ;AAC7C,kBAAM,KAAK,KAAK,IAAI,MAAM,GAAG,oBAAoB;AAAA,UACnD;AAGA,gBAAM,KAAK,KAAK;AAAA,YACd;AAAA,YACA,GAAG,KAAK,KAAK,qBAAqB,EAAE,CAAC;AAAA;AAAA,EAAO,IAAI;AAAA;AAAA,YAChD;AAAA,YACA;AAAA,UACF;AACA,eAAK,KAAK,2BAA2B;AAAA,QACvC;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,KAAK,eAAe;AACtB,cAAM,KAAK,QAAQ,KAAK,aAAa;AAAA,MACvC,WAAW,KAAK,cAAc;AAC5B,cAAMC,QAAO,KAAK,YAAY,EAAE,MAAM,MAAM,MAAS;AACrD,aAAK,KAAK,2BAA2B;AAAA,MACvC;AACA,YAAM;AAAA,IACR;AACA,UAAM,KAAK,eAAe,GAAG,IAAI,iBAAiB,GAAG,SAAS;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,QAAmC;AAC/C,QAAI;AACF,YAAM,KAAK,KAAK;AAAA,QACd,OAAO;AAAA,QACP,GAAG,KAAK,KAAK,qBAAqB,OAAO,WAAW,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AAAA,QAC1E,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAAA,IACF,SAAS,YAAY;AACnB,UAAI,KAAK,qBAAqB,OAAO,YAAY,EAAE,0BAA0B,UAAU,EAAE;AAAA,IAC3F;AACA,SAAK,KAAK,2BAA2B;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eACJ,UACA,WACA,UACe;AACf,QAAI,OAAO,cAAc,YAAY,OAAO,aAAa,YAAY,cAAc,SAAU;AAC7F,QAAI;AACF,YAAM,sCAAsC,KAAK,KAAK,SAAS,UAAU,WAAW,QAAQ;AAAA,IAC9F,SAAS,KAAK;AACZ,UAAI,KAAK,wCAAwC,QAAQ,KAAK,GAAG,EAAE;AAAA,IACrE;AAAA,EACF;AACF;;;ACxIA,eAAsB,oCACpB,MACAC,kBACAC,sBACAC,+BAC6B;AAC7B,QAAM,2BAA2B,MAC/B,eAAe,KAAK,SAAS,KAAK,aAAa,MAAM,OAAO,KAAK,yBAAyB,CAAC,CAAC;AAC9F,QAAM,wBAAwB,MAAM,gCAAgC;AAAA,IAClE,UAAU,KAAK;AAAA,IACf,aAAa,KAAK;AAAA,IAClB,qBAAqB,KAAK,oBAAoB,KAAK,IAAI;AAAA,IACvD,uBAAuB,KAAK,sBAAsB,KAAK,IAAI;AAAA,IAC3D,uBAAuB,KAAK,sBAAsB,KAAK,IAAI;AAAA,IAC3D,wBAAwB,KAAK,uBAAuB,KAAK,IAAI;AAAA,IAC7D,wBAAwB,KAAK,sBAAsB,KAAK,IAAI;AAAA,IAC5D,qBAAqB,KAAK,oBAAoB,KAAK,IAAI;AAAA,IACvD,iBAAAF;AAAA,IACA,qBAAAC;AAAA,IACA,8BAAAC;AAAA,IACA,kBAAkB,KAAK,iBAAiB,KAAK,IAAI;AAAA,IACjD,iBAAiB,KAAK,gBAAgB,KAAK,IAAI;AAAA,IAC/C,qBAAqB,KAAK,oBAAoB,KAAK,IAAI;AAAA,IACvD,sBAAsB,KAAK,qBAAqB,KAAK,IAAI;AAAA,IACzD,yBAAyB,MACvB,cAAc,KAAK,SAAS,KAAK,aAAa,KAAK,UAAU,KAAK,UAAU;AAAA,IAC9E,kCAAkC,CAAC,aACjC,iCAAiC,KAAK,SAAS,QAAQ;AAAA,IACzD,uCAAuC,CAAC,UAAU,mBAAmB,kBACnE,sCAAsC,KAAK,SAAS,UAAU,mBAAmB,aAAa;AAAA,IAChG,+BAA+B,KAAK,8BAA8B,KAAK,IAAI;AAAA,IAC3E,4BAA4B,KAAK,2BAA2B,KAAK,IAAI;AAAA,IACrE,6BAA6B,KAAK,4BAA4B,KAAK,IAAI;AAAA,IACvE,yBAAyB,KAAK,wBAAwB,KAAK,IAAI;AAAA,IAC/D;AAAA,EACF,CAAkD;AAKlD,SAAO;AACT;;;AC3EO,IAAM,mCAAN,MAAuC;AAAA,EAMrC,YACY,QACA,cACA,kBAAyC,YAAY,UACtE;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAHgB;AAAA,EACA;AAAA,EACA;AAAA,EARX,WAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,uBAAsC;AAAA,EAQ9C,MAAa,6BAA4C;AACvD,SAAK,yBAAyB;AAC9B,UAAM,KAAK,OAAO;AAAA,EACpB;AAAA,EAEO,SAAwB;AAC7B,QAAI,CAAC,KAAK,OAAO,EAAG,QAAO,QAAQ,QAAQ;AAC3C,QAAI,KAAK,SAAU,QAAO,KAAK;AAC/B,UAAM,YAAY,KAAK,WAAW;AAClC,SAAK,WAAW;AAChB,SAAK,UAAU;AAAA,MACb,MAAM,KAAK,cAAc,SAAS;AAAA,MAClC,MAAM,KAAK,cAAc,SAAS;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA,EAEO,qBAAoC;AACzC,QAAI,CAAC,KAAK,uBAAwB,QAAO,QAAQ,QAAQ;AACzD,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,MAAc,aAA4B;AACxC,QAAI,qBAAqB,MAAM,KAAK,gBAAgB;AACpD,QAAI,KAAK,qBAAqB,uBAAuB,KAAK,qBAAsB;AAEhF,aAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,YAAM,wBAAwB,MAAM,KAAK,aAAa;AACtD,YAAM,4BAA4B,MAAM,KAAK,gBAAgB;AAC7D,YAAM,gCAAgC,MAAM,KAAK,gBAAgB;AACjE,YAAM,sBACJ,OAAO,0BAA0B,WAAW,wBAAwB;AACtE,UACE,wBAAwB,6BACrB,8BAA8B,kCAE/B,OAAO,0BAA0B,YAC9B,8BAA8B,qBAEnC;AACA,aAAK,oBAAoB;AACzB,aAAK,uBAAuB;AAC5B;AAAA,MACF;AACA,2BAAqB;AAAA,IACvB;AAEA,SAAK,oBAAoB;AACzB,SAAK,uBAAuB;AAC5B,UAAM,IAAI,MAAM,oGAAoG;AAAA,EACtH;AAAA,EAEQ,cAAc,WAAgC;AACpD,QAAI,KAAK,aAAa,UAAW,MAAK,WAAW;AAAA,EACnD;AACF;;;AC7DO,SAAS,6BACd,QACA,WACA,UACQ;AACR,QAAM,cAAc,sBAAsB,MAAM;AAChD,MAAI,gBAAgB,OAAW,QAAO,SAAS,QAAQ,SAAS;AAChE,QAAM,mBAAmB,OAAO,YAAY;AAC5C,MAAI,qBAAqB,OAAW,QAAO,SAAS,QAAQ,SAAS;AACrE,MAAI,qBAAqB,UAAW,QAAO;AAC3C,QAAM,YAAY,iCAAiC,aAAa,EAAE,CAAC,gBAAgB,GAAG,UAAU,CAAC;AACjG,MAAI,cAAc,YAAa,QAAO;AACtC,SAAO,SAAS,QAAQ,SAAS;AACnC;AAEO,SAAS,gCACdC,uBAC2B;AAC3B,SAAO,CAAC,QAAQ,cACd;AAAA,IACE;AAAA,IACA;AAAA,IACA,CAAC,gBAAgB,sBACf,GAAGA,sBAAqB,EAAE,GAAG,eAAe,aAAa,WAAW,kBAAkB,CAAC,CAAC;AAAA;AAAA,EAAO,eAAe,OAAO;AAAA;AAAA,EACzH;AACJ;;;AC/BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAOC,WAAU;AAKjB,SAAS,sBAAsB,SAAiB,WAAuC;AACrF,MAAI;AACJ,MAAI;AACF,eAAW,UAAU,OAAO;AAAA,EAC9B,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACA,MAAI,SAAS,eAAe,KAAK,CAAC,SAAS,YAAY,GAAG;AACxD,UAAM,IAAI,MAAM,6CAA6C,OAAO,GAAG;AAAA,EACzE;AAEA,MAAI;AACJ,MAAI;AACF,iBAAa,UAAU,SAAS;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACA,MAAI,WAAW,eAAe,KAAK,CAAC,WAAW,YAAY,GAAG;AAC5D,UAAM,IAAI,MAAM,6CAA6C,SAAS,GAAG;AAAA,EAC3E;AAEA,QAAM,aAAa,aAAa,OAAO;AACvC,uBAAqB,YAAY,aAAa,SAAS,GAAG,SAAS;AACnE,SAAO;AACT;AAEO,SAAS,0BAA0B,SAAqC;AAC7E,QAAM,YAAYC,MAAK,KAAK,SAAS,QAAQ;AAC7C,QAAM,YAAYA,MAAK,KAAK,WAAW,cAAc;AACrD,MAAI,aAAa,sBAAsB,SAAS,SAAS;AACzD,MAAI,eAAe,OAAW,QAAO;AAErC,MAAI;AACJ,MAAI;AACF,qBAAiB,UAAU,SAAS;AAAA,EACtC,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACA,MAAI,eAAe,eAAe,KAAK,CAAC,eAAe,OAAO,GAAG;AAC/D,UAAM,IAAI,MAAM,6CAA6C,SAAS,GAAG;AAAA,EAC3E;AAEA,MAAI;AACJ,MAAI;AACF,SAAK;AAAA,MACH;AAAA,MACA,UAAU,YAAY,UAAU,cAAc,MAAM,UAAU,cAAc;AAAA,IAC9E;AAAA,EACF,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,GAAG;AAChC,4BAAsB,SAAS,SAAS;AACxC,aAAO;AAAA,IACT;AACA,QAAI,YAAY,OAAO,OAAO,GAAG;AAC/B,YAAM,IAAI,MAAM,6CAA6C,SAAS,GAAG;AAAA,IAC3E;AACA,UAAM;AAAA,EACR;AACA,MAAI;AACF,UAAM,SAAS,UAAU,EAAE;AAC3B,iBAAa,sBAAsB,SAAS,SAAS;AACrD,QAAI,eAAe,QAAW;AAC5B,YAAM,IAAI,MAAM,6CAA6C,SAAS,GAAG;AAAA,IAC3E;AACA,UAAM,YAAY,UAAU,SAAS;AACrC,QACE,CAAC,OAAO,OAAO,KACf,UAAU,eAAe,KACzB,CAAC,UAAU,OAAO,KAClB,UAAU,QAAQ,OAAO,OACzB,UAAU,QAAQ,OAAO,KACzB;AACA,YAAM,IAAI,MAAM,6CAA6C,SAAS,GAAG;AAAA,IAC3E;AACA,yBAAqB,YAAY,aAAa,SAAS,GAAG,SAAS;AACnE,WAAO,aAAa,IAAI,OAAO;AAAA,EACjC,UAAE;AACA,cAAU,EAAE;AAAA,EACd;AACF;;;ACzFO,SAAS,iBAAiB,OAAuB;AACtD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,UAAU,KAAK,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AAC3E,QAAI;AACF,YAAM,UAAU,KAAK,MAAM,OAAO;AAClC,UAAI,OAAO,YAAY,SAAU,QAAO;AAAA,IAC1C,QAAQ;AAAA,IAER;AACA,WAAO,QAAQ,MAAM,GAAG,EAAE;AAAA,EAC5B;AACA,SAAO;AACT;;;ACSA,OAAOC,YAAU;AAYjB,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC,GAAG;AAAA,EACH;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,wCAAwC;AAOvC,SAAS,uBAAuB,YAG9B;AACP,MAAI,CAAC,cAAcC,OAAK,WAAW,UAAU,EAAG,QAAO;AACvD,MAAI,WAAW,KAAK,EAAE,WAAW,QAAQ,GAAG;AAC1C,QAAI;AACF,YAAM,SAAS,IAAI,IAAI,WAAW,KAAK,CAAC;AACxC,UAAI,OAAO,aAAa,UAAU,CAAC,OAAO,SAAU,QAAO;AAC3D,YAAMC,cAAa,OAAO;AAC1B,YAAM,eAAe,uBAAuB,YAAYA,WAAU,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE;AAC1G,UAAI,CAAC,aAAc,QAAO;AAC1B,aAAO,EAAE,YAAAA,aAAY,aAAa;AAAA,IACpC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,aAAa,WAAW,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE;AACpE,QAAM,aAAa,WAAW,QAAQ,GAAG;AACzC,MAAI,cAAc,KAAK,cAAc,WAAW,SAAS,EAAG,QAAO;AACnE,QAAM,aAAa,WAAW,MAAM,GAAG,UAAU;AACjD,MAAI,sBAAsB,KAAK,UAAU,EAAG,QAAO;AACnD,SAAO;AAAA,IACL;AAAA,IACA,cAAc,WAAW,MAAM,aAAa,CAAC;AAAA,EAC/C;AACF;AAOO,SAAS,wBAAwB,YAAoB,YAA8B;AACxF,QAAM,aAAa,oBAAI,IAAY;AACnC,QAAM,cAAcD,OAAK,QAAQ,UAAU;AAC3C,QAAM,eAAe,CAAC,cAAsB;AAC1C,UAAM,WAAWA,OAAK,QAAQ,SAAS;AACvC,QAAI,wBAAwB,aAAa,QAAQ,GAAG;AAClD,iBAAW,IAAI,QAAQ;AAAA,IACzB;AAAA,EACF;AACA,QAAM,wBAAwB,CAAC,iBAAyB;AACtD,UAAM,aAAa,aAAa,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE;AACtE,QAAI,CAAC,WAAY;AACjB,iBAAaA,OAAK,KAAK,aAAa,UAAU,CAAC;AAC/C,QAAI,uBAAuB,KAAK,UAAU,GAAG;AAC3C,mBAAaA,OAAK,KAAK,aAAa,SAAS,UAAU,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,MAAIA,OAAK,WAAW,UAAU,GAAG;AAC/B,iBAAa,UAAU;AAKvB,UAAME,YAAWF,OAAK,SAAS,aAAaA,OAAK,QAAQ,UAAU,CAAC;AACpE,QAAIE,aAAY,CAACA,UAAS,WAAW,IAAI,KAAK,CAACF,OAAK,WAAWE,SAAQ,GAAG;AACxE,YAAM,aAAaA,UAAS,MAAMF,OAAK,GAAG,EAAE,KAAK,GAAG;AACpD,UAAI,uBAAuB,KAAK,UAAU,GAAG;AAC3C,qBAAaA,OAAK,KAAK,aAAa,SAAS,UAAU,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,EACF,OAAO;AACL,0BAAsB,UAAU;AAAA,EAClC;AAEA,SAAO,CAAC,GAAG,UAAU;AACvB;AASA,SAAS,iBAAiB,SAAwC;AAChE,QAAM,MAAM,QAAQ;AACpB,SAAO,OAAO,QAAQ,YAAY,IAAI,SAAS,IAAI,MAAM;AAC3D;AAMO,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAMT;AACD,SAAK,YAAY,QAAQ;AACzB,SAAK,aAAa,QAAQ;AAC1B,SAAK,sBAAsB,QAAQ;AACnC,SAAK,mCAAmC,QAAQ;AAChD,SAAK,oBAAoB,QAAQ;AAAA,EACnC;AAAA,EAEA,MAAM,oBACJ,YACA,iBACA,mBAAsC,CAAC,GACvC,oBAC4B;AAC5B,UAAM,QAAQ,uBAAuB,UAAU;AAC/C,UAAM,qBAAqB,iBAAiB,eAAe;AAC3D,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,iBAAiB,OAAO,qBAAqB;AACnD,UAAM,qBACJ,WAAW,KAAK,EAAE,WAAW,QAAQ,KAAK,OAAO,eAAe,OAAO,gBACnE,MAAM,eACN;AACN,QAAI,SAAS,MAAM,eAAe,gBAAgB;AAChD,YAAM,WAA6B,CAAC;AACpC,YAAM,kBAAkB,oBAAI,IAAY;AACxC,YAAM,aAAa,CAAC,YAAkC;AACpD,cAAM,aAAa,iBAAiB,OAAO;AAC3C,cAAM,aAAa,aAAaA,OAAK,QAAQ,UAAU,IAAI,uBAAuB,SAAS,MAAM;AACjG,YAAI,gBAAgB,IAAI,UAAU,EAAG;AACrC,wBAAgB,IAAI,UAAU;AAC9B,iBAAS,KAAK,OAAO;AAAA,MACvB;AAEA,YAAM,oBACJ,uBAAuB,OAAO,KAAK,oBAAoB,kBAAkB,IAAI,OAAO;AACtF,UACE,iBAAiB,WAAW,KAC5B,CAAC,6BAA6B,MAAM,EAAE,cACtC,iBAAiB,SAAS,iBAAiB,GAC3C;AACA,mBAAW,eAAe;AAAA,MAC5B;AAEA,UAAI,iBAAiB,SAAS,GAAG;AAC/B,mBAAW,aAAa,kBAAkB;AACxC,cAAI;AACF,uBAAW,MAAM,KAAK,WAAW,SAAS,CAAC;AAAA,UAC7C,SAAS,KAAK;AACZ,gBAAI,MAAM,oDAAoD;AAAA,cAC5D,MAAM;AAAA,cACN;AAAA,cACA,OAAQ,IAAc;AAAA,YACxB,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,iBAAW,WAAW,UAAU;AAC9B,cAAM,aAAa,iBAAiB,OAAO;AAC3C,YAAI,CAAC,YAAY;AACf,gBAAM,SAAS,MAAM,QAAQ,iBAAiB,UAAU;AACxD,cAAI,OAAQ,QAAO;AACnB;AAAA,QACF;AACA,YAAI;AACF,gBAAM,WAAWA,OAAK,KAAK,YAAY,MAAM;AAC7C,qBAAW,aAAa,wBAAwB,UAAU,MAAM,YAAY,GAAG;AAC7E,kBAAM,SAAS,MAAM,QAAQ,iBAAiB,SAAS;AACvD,gBAAI,OAAQ,QAAO;AAAA,UACrB;AAAA,QACF,SAAS,KAAK;AACZ,cAAI,eAAe,uBAAwB,OAAM;AACjD,cAAI,MAAM,2CAA2C;AAAA,YACnD,MAAM;AAAA,YACN,YAAY;AAAA,YACZ,OAAQ,IAAc;AAAA,UACxB,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAM,sBAAsB,QAAQ,KAAK,iCAAiC,MAAM,UAAU,IAAI;AAE9F,QAAI,SAAS,qBAAqB;AAChC,UAAI;AACF,cAAM,oBAAoB,MAAM,KAAK,WAAW,mBAAmB;AACnE,mBAAW,aAAa,wBAAwB,kBAAkB,KAAK,MAAM,YAAY,GAAG;AAC1F,gBAAM,SAAS,MAAM,kBAAkB,iBAAiB,SAAS;AACjE,cAAI,OAAQ,QAAO;AAAA,QACrB;AACA,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,YAAI,eAAe,uBAAwB,OAAM;AACjD,YAAI,MAAM,gDAAgD;AAAA,UACxD,MAAM;AAAA,UACN,WAAW;AAAA,UACX,OAAQ,IAAc;AAAA,QACxB,CAAC;AACD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,oBAAoB;AACtB,UAAI;AACF,cAAM,mBAAmB,MAAM,KAAK,WAAW,kBAAkB;AACjE,mBAAW,aAAa,wBAAwB,iBAAiB,KAAK,kBAAkB,GAAG;AACzF,gBAAM,SAAS,MAAM,iBAAiB,iBAAiB,SAAS;AAChE,cAAI,OAAQ,QAAO;AAAA,QACrB;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,eAAe,uBAAwB,OAAM;AACjD,YAAI,MAAM,mDAAmD;AAAA,UAC3D,MAAM;AAAA,UACN,WAAW;AAAA,UACX,OAAQ,IAAc;AAAA,QACxB,CAAC;AAAA,MACH;AAMA,UAAI,CAACA,OAAK,WAAW,kBAAkB,EAAG,QAAO;AAAA,IACnD;AACA,QAAIA,OAAK,WAAW,kBAAkB,GAAG;AACvC,UAAI,CAAC,oBAAoB;AACvB,eAAO,MAAM,gBAAgB,iBAAiB,kBAAkB;AAAA,MAClE;AACA,YAAM,eAAe,MAAM,KAAK;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,CAAC,aAAc,QAAO;AAC1B,iBAAW,aAAa,wBAAwB,aAAa,KAAK,kBAAkB,GAAG;AACrF,cAAM,SAAS,MAAM,aAAa,QAAQ,iBAAiB,SAAS;AACpE,YAAI,OAAQ,QAAO;AAAA,MACrB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,oBAAoB;AACvB,aAAO,MAAM,gBAAgB,iBAAiB,kBAAkB;AAAA,IAClE;AACA,eAAW,aAAa,wBAAwB,oBAAoB,kBAAkB,GAAG;AACvF,YAAM,SAAS,MAAM,gBAAgB,iBAAiB,SAAS;AAC/D,UAAI,OAAQ,QAAO;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,2BACJ,SACA,iBACA,aAAgC,CAAC,GACjC,qBAAqB,OACrB,kBAAkB,oBAAI,IAAqB,GACf;AAC5B,UAAM,eAAe,WAAW,KAAK,IAAI;AACzC,UAAM,UAAU,QACb,OAAO,CAAC,WAAW,QAAQ,OAAO,IAAI,CAAC,EACvC,IAAI,CAAC,YAAY;AAAA,MAChB;AAAA,MACA,UAAU,GAAG,YAAY,KAAK,qBAAqB,MAAM,GAAG,KAAK,OAAO,aAAa,EAAE,KAAK,OAAO,IAAI;AAAA,IACzG,EAAE;AACJ,UAAM,UAAU,oBAAI,IAA6B;AACjD,eAAW,EAAE,QAAQ,SAAS,KAAK,SAAS;AAC1C,UAAI,CAAC,gBAAgB,IAAI,QAAQ,EAAG,SAAQ,IAAI,UAAU,MAAM;AAAA,IAClE;AACA,UAAM,aAAa,CAAC,GAAG,OAAO;AAC9B,aAAS,SAAS,GAAG,SAAS,WAAW,QAAQ,UAAU,uCAAuC;AAChG,YAAM,QAAQ;AAAA,QACZ,WAAW,MAAM,QAAQ,SAAS,qCAAqC,EAAE,IAAI,OAAO,CAAC,UAAU,MAAM,MAAM;AACzG,0BAAgB;AAAA,YACd;AAAA,YACA,MAAM,KAAK,sBAAsB,QAAQ,iBAAiB,YAAY,kBAAkB;AAAA,UAC1F;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,QAAQ,OAAO,CAAC,EAAE,SAAS,MAAM,gBAAgB,IAAI,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,MAAM,MAAM;AAAA,EAC5G;AAAA,EAEA,MAAc,sBACZ,QACA,iBACA,YACA,oBACkB;AAClB,UAAM,QAAQ,uBAAuB,OAAO,IAAI;AAChD,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,4BAA4B,UAAU,QAAQ,mBAAmB,IAAI,MAAM,UAAU;AAC3F,UAAM,yBACJ,UAAU,SACT,MAAM,eAAe,OAAO,iBAC3B,MAAM,gBAAgB,OAAO,qBAAqB,2BAClD,KAAK,iCAAiC,MAAM,UAAU,MAAM;AAChE,QAAI,SAAS,MAAM,KAAK,oBAAoB,OAAO,MAAM,iBAAiB,YAAY,OAAO,SAAS;AACtG,QAAI,CAAC,UAAU,SAAS,CAAC,6BAA6B,CAAC,wBAAwB;AAC7E,eAAS,MAAM,KAAK,oBAAoB,MAAM,cAAc,iBAAiB,YAAY,OAAO,SAAS;AAAA,IAC3G;AACA,UAAM,2BACJA,OAAK,WAAW,OAAO,IAAI,KAC3B,wBAAwBA,OAAK,QAAQ,OAAO,SAAS,GAAGA,OAAK,QAAQ,OAAO,IAAI,CAAC;AACnF,UAAM,2BAA2B,OAAO,KAAK,KAAK,EAAE,WAAW,QAAQ;AACvE,UAAM,yBACJ,CAAC,WACA,4BACE,8BAA8B,CAAC,sBAAsB,6BACrD,4BAA4B;AACjC,UAAM,+BACJ,CAAC,WACC,UAAU,QAAQ,CAAC,6BAA6B,CAAC,0BAChDA,OAAK,WAAW,OAAO,IAAI,KAC1B,CAAC,wBAAwBA,OAAK,QAAQ,OAAO,SAAS,GAAGA,OAAK,QAAQ,OAAO,IAAI,CAAC;AACxF,WACG,WAAW,QAAQ,CAAC,+BAA+B,MAAM,KACzD,CAAC,UAAU,CAAC,2BAA2B,sBAAsB;AAAA,EAElE;AAAA,EAEA,MAAM,8BACJ,QACA,iBACA,mBAAsC,CAAC,GACyB;AAChE,UAAM,SAAS,MAAM,KAAK,oBAAoB,OAAO,MAAM,iBAAiB,kBAAkB,OAAO,SAAS;AAC9G,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI,iBAAgC;AACpC,QAAIA,OAAK,WAAW,OAAO,IAAI,GAAG;AAChC,YAAM,eAAe,MAAM,KAAK,gCAAgC,OAAO,MAAM,iBAAiB,gBAAgB;AAC9G,uBAAiB,cAAc,aAAa;AAC5C,UAAI,CAAC,kBAAkB,6BAA6B,KAAK,UAAU,CAAC,EAAE,WAAY,QAAO;AAAA,IAC3F;AACA,uBAAmB,KAAK,kBAAkB,OAAO,IAAI;AACrD,QAAI,iBAAiB,SAAS,KAAK,CAAC,iBAAiB,SAAS,cAAc,GAAG;AAC7E,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,WAAW;AAAA,MACX,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,OAAO,OAAO,SAAS,OAAO,YAAY;AAAA,QAC1C,MAAM,OAAO;AAAA,QACb,SAAS,OAAO,WAAW,OAAO,QAAQ,MAAM,GAAG,GAAG;AAAA,QACtD,QAAQ,OAAO,YAAY;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gCACJ,YACA,iBACA,mBAAsC,CAAC,GACsC;AAC7E,UAAM,eAAeA,OAAK,QAAQ,UAAU;AAC5C,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,aAAaA,OAAK,QAAQ,OAAO,SAAS;AAChD,UAAM,iBAAiBA,OAAK,KAAK,YAAY,YAAY;AACzD,UAAM,qBAAqB,iBAAiB,eAAe;AAC3D,UAAM,UAA8E,CAAC;AACrF,UAAM,WAAW,oBAAI,IAAY;AAEjC,UAAM,kBAAkB,CAAC,SAAyB,cAAsB;AACtE,YAAM,aAAa,iBAAiB,OAAO;AAC3C,UAAI,CAAC,WAAY;AACjB,YAAM,gBAAgBA,OAAK,QAAQ,UAAU;AAC7C,UAAI,SAAS,IAAI,aAAa,EAAG;AACjC,UAAI,CAAC,wBAAwB,eAAe,YAAY,EAAG;AAC3D,UAAI,kBAAkB,cAAc,wBAAwB,gBAAgB,YAAY,GAAG;AACzF;AAAA,MACF;AACA,eAAS,IAAI,aAAa;AAC1B,cAAQ,KAAK,EAAE,SAAS,KAAK,eAAe,UAAU,CAAC;AAAA,IACzD;AAEA,UAAM,oBACJ,uBAAuB,OAAO,KAAK,oBAAoB,kBAAkB,IAAI,OAAO;AACtF,oBAAgB,iBAAiB,iBAAiB;AAElD,UAAM,sBAAsB,oBAAI,IAAY;AAC5C,wBAAoB,IAAI,OAAO,gBAAgB;AAC/C,wBAAoB,IAAI,OAAO,eAAe;AAC9C,eAAW,MAAM,kBAAkB;AACjC,0BAAoB,IAAI,EAAE;AAAA,IAC5B;AACA,QAAI,wBAAwB,gBAAgB,YAAY,GAAG;AACzD,YAAM,uBAAuBA,OAAK,SAAS,gBAAgB,YAAY;AACvE,YAAM,CAAC,gBAAgB,IAAI,qBAAqB,MAAM,OAAO;AAC7D,UAAI,kBAAkB;AACpB,4BAAoB,IAAI,2BAA2B,gBAAgB,KAAK,gBAAgB;AAAA,MAC1F;AAAA,IACF;AACA,eAAW,UAAU,OAAO,qBAAqB,CAAC,GAAG;AACnD,0BAAoB,IAAI,OAAO,IAAI;AAAA,IACrC;AAEA,eAAW,MAAM,qBAAqB;AACpC,UAAI,CAAC,GAAI;AACT,UAAI;AACF,wBAAgB,MAAM,KAAK,WAAW,EAAE,GAAG,EAAE;AAAA,MAC/C,QAAQ;AAAA,MAAC;AAAA,IACX;AAEA,YAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,SAAS,EAAE,IAAI,MAAM;AAClD,WAAO,QAAQ,CAAC,KAAK;AAAA,EACvB;AACF;;;ACxcO,IAAM,2BAA2B,IAAI;AA2BrC,SAAS,iBACd,UAC2B;AAC3B,MAAI;AACJ,aAAW,OAAO,UAAU;AAC1B,UAAM,MAAM,IAAI,UAAU,IAAI;AAC9B,QAAI,QAAQ,OAAW;AACvB,UAAM,KAAK,KAAK,MAAM,GAAG;AACzB,QAAI,CAAC,OAAO,SAAS,EAAE,EAAG;AAC1B,QAAI,SAAS,UAAa,KAAK,KAAK,IAAI;AACtC,aAAO,EAAE,IAAI,IAAI;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAuBA,SAAS,kBAAkB,cAAiD;AAC1E,QAAM,QAAQ,KAAK,MAAM,aAAa,QAAQ;AAC9C,QAAM,SACJ,aAAa,WAAW,SAAY,KAAK,MAAM,aAAa,MAAM,IAAI;AAMxE,QAAM,MAAM,OAAO,SAAS,MAAM,IAC7B,SACA,iBAAiB,aAAa,QAAQ,GAAG,MAAM;AAKpD,SAAO,EAAE,OAAO,KAAK,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C;AAEA,SAAS,oBACP,GACA,GACQ;AACR,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO,EAAE,SAAS,EAAE,SAAS,KAAK;AAC7D,MAAI,EAAE,mBAAmB,EAAE,gBAAgB;AACzC,WAAO,EAAE,iBAAiB,EAAE,iBAAiB,KAAK;AAAA,EACpD;AACA,SAAO;AACT;AA4BO,SAAS,qBACd,QACA,iBAAyB,0BACI;AAC7B,QAAM,SAAuE,CAAC;AAC9E,QAAM,UAAqC,CAAC;AAC5C,aAAW,QAAQ,QAAQ;AACzB,UAAM,WAAW,kBAAkB,IAAI;AACvC,QAAI,OAAO,SAAS,SAAS,KAAK,GAAG;AACnC,aAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAAA,IAChC,OAAO;AACL,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,EACF;AAGA,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,QAAI,EAAE,SAAS,UAAU,EAAE,SAAS,OAAO;AACzC,aAAO,EAAE,SAAS,QAAQ,EAAE,SAAS;AAAA,IACvC;AACA,WAAO,oBAAoB,EAAE,MAAM,EAAE,IAAI;AAAA,EAC3C,CAAC;AAED,QAAM,IAAI,OAAO;AAKjB,QAAM,SAAS,IAAI,MAAc,CAAC;AAClC,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,QAAO,CAAC,IAAI;AAExC,QAAM,OAAO,CAAC,MAAsB;AAClC,QAAI,OAAO;AACX,WAAO,OAAO,IAAI,MAAM,KAAM,QAAO,OAAO,IAAI;AAEhD,QAAI,MAAM;AACV,WAAO,OAAO,GAAG,MAAM,MAAM;AAC3B,YAAM,OAAO,OAAO,GAAG;AACvB,aAAO,GAAG,IAAI;AACd,YAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,CAAC,GAAW,MAAoB;AAC5C,UAAM,KAAK,KAAK,CAAC;AACjB,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,OAAO,GAAI,QAAO,EAAE,IAAI;AAAA,EAC9B;AAKA,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,SAAS,OAAO,CAAC,EAAG,SAAS,MAAM;AACzC,aAAS,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;AAC9B,UAAI,OAAO,CAAC,EAAG,SAAS,QAAQ,OAAQ;AAExC,UAAI,OAAO,CAAC,EAAG,KAAK,WAAW,OAAO,CAAC,EAAG,KAAK,OAAQ;AACvD,YAAM,GAAG,CAAC;AAAA,IACZ;AAAA,EACF;AAMA,QAAM,WAAwC,CAAC;AAC/C,QAAM,gBAAgB,oBAAI,IAAoB;AAC9C,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,OAAO,KAAK,CAAC;AACnB,QAAI,MAAM,cAAc,IAAI,IAAI;AAChC,QAAI,QAAQ,QAAW;AACrB,YAAM,SAAS;AACf,oBAAc,IAAI,MAAM,GAAG;AAC3B,eAAS,KAAK,CAAC,CAAC;AAAA,IAClB;AACA,aAAS,GAAG,EAAG,KAAK,OAAO,CAAC,EAAG,IAAI;AAAA,EACrC;AAKA,UAAQ,KAAK,mBAAmB;AAChC,aAAW,QAAQ,SAAS;AAC1B,aAAS,KAAK,CAAC,IAAI,CAAC;AAAA,EACtB;AAEA,SAAO;AACT;;;AChMO,IAAM,8BAA8B;AAEpC,IAAM,uBAAuB;AAEpC,IAAM,yBAAyB;AAK/B,IAAM,wBAAwB;AAkD9B,SAAS,WAAW,OAAe,QAAyB;AAC1D,SAAO,SAAS,SAAS;AAC3B;AAEA,SAAS,aACP,QACA,UACQ;AACR,QAAM,QAAQ,WAAW,MAAM;AAC/B,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA,EACvC;AACA,SAAO;AACT;AAGA,SAAS,eAAe,MAAwB;AAC9C,SAAO,KACJ,YAAY,EACZ,QAAQ,qBAAqB,GAAG,EAChC,MAAM,KAAK,EACX,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AACrC;AAEA,SAAS,WAAW,GAAa,GAAsB;AACrD,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAGA,SAAS,aAAa,OAAiB,MAAyB;AAC9D,MAAI,MAAM,WAAW,KAAK,MAAM,SAAS,KAAK,OAAQ,QAAO;AAC7D,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAG,QAAO;AAAA,EACnC;AACA,SAAO;AACT;AAQA,SAAS,iBACP,GACA,GACA,aACS;AACT,MAAI,WAAW,GAAG,CAAC,EAAG,QAAO;AAC7B,MAAI,CAAC,YAAa,QAAO;AACzB,SAAO,aAAa,GAAG,CAAC,KAAK,aAAa,GAAG,CAAC;AAChD;AAEA,SAAS,QAAQ,OAAuB;AACtC,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AASO,SAAS,8BACd,UACA,eACA,UAC2B;AAC3B,SAAO,cAAc,IAAI,CAAC,iBAAiB;AACzC,UAAM,WAAiC,aAAa,SAAS,IAAI,CAAC,QAAQ;AACxE,YAAM,WAAW,eAAe,UAAU,KAAK,QAAQ;AACvD,aAAO;AAAA,QACL,SAAS,SAAS;AAAA,QAClB,QAAQ,SAAS;AAAA,QACjB,MAAM,IAAI;AAAA,QACV,GAAI,IAAI,aAAa,SAAY,EAAE,UAAU,IAAI,SAAS,IAAI,CAAC;AAAA,QAC/D,GAAI,IAAI,WAAW,SAAY,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;AAAA,MAC3D;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,gBAAgB,aAAa;AAAA,MAC7B,UAAU,aAAa;AAAA,MACvB,GAAI,aAAa,WAAW,SAAY,EAAE,QAAQ,aAAa,OAAO,IAAI,CAAC;AAAA,MAC3E,GAAI,aAAa,UAAU,SAAY,EAAE,OAAO,aAAa,MAAM,IAAI,CAAC;AAAA,MACxE,GAAI,aAAa,YAAY,SAAY,EAAE,SAAS,aAAa,QAAQ,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKO,SAAS,YACd,SACA,UAAyB,CAAC,GACP;AACnB,QAAM,WAAW,QAAQ;AACzB,QAAM,cAAc,QAAQ,qBAAqB;AAGjD,QAAM,UAAoB,CAAC;AAC3B,QAAM,cAAc,oBAAI,IAAY;AACpC,aAAW,QAAQ,SAAS;AAC1B,QAAI,CAAC,YAAY,IAAI,KAAK,MAAM,GAAG;AACjC,kBAAY,IAAI,KAAK,MAAM;AAC3B,cAAQ,KAAK,KAAK,MAAM;AAAA,IAC1B;AAAA,EACF;AAWA,MAAI,UAAU,OAAO;AACrB,MAAI,QAAQ,OAAO;AACnB,MAAI;AACJ,MAAI;AACJ,aAAW,QAAQ,SAAS;AAC1B,UAAM,KAAK,KAAK,MAAM,KAAK,QAAQ;AACnC,QAAI,OAAO,SAAS,EAAE,KAAK,KAAK,SAAS;AACvC,gBAAU;AACV,iBAAW,KAAK;AAAA,IAClB;AACA,QAAI,KAAK,WAAW,QAAW;AAC7B,YAAM,OAAO,KAAK,MAAM,KAAK,MAAM;AACnC,UAAI,OAAO,SAAS,IAAI,KAAK,OAAO,OAAO;AACzC,gBAAQ;AACR,iBAAS,KAAK;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB;AAAA,IACpB,QAAQ,QAAQ,CAAC,SAAS,KAAK,QAAQ;AAAA,EACzC;AACA,MAAI,kBAAkB,UAAa,cAAc,KAAK,OAAO;AAC3D,YAAQ,cAAc;AACtB,aAAS,cAAc;AAAA,EACzB;AAIA,MAAI,WAAW,UAAa,OAAO,SAAS,OAAO,KAAK,QAAQ,SAAS;AACvE,aAAS;AACT,YAAQ;AAAA,EACV;AACA,MAAI,aAAa,QAAW;AAG1B,eAAW,QAAQ,CAAC,GAAG,aAAY,oBAAI,KAAK,CAAC,GAAE,YAAY;AAAA,EAC7D;AAGA,MAAI;AACJ,MAAI;AACJ,aAAW,QAAQ,SAAS;AAC1B,QAAI,UAAU,UAAa,KAAK,UAAU,UAAa,KAAK,MAAM,KAAK,EAAE,SAAS,GAAG;AACnF,cAAQ,KAAK,MAAM,KAAK;AAAA,IAC1B;AACA,QACE,YAAY,UACZ,KAAK,YAAY,UACjB,KAAK,QAAQ,KAAK,EAAE,SAAS,GAC7B;AACA,gBAAU,KAAK,QAAQ,KAAK;AAAA,IAC9B;AACA,QAAI,UAAU,UAAa,YAAY,OAAW;AAAA,EACpD;AAGA,QAAM,SAA0B,CAAC;AACjC,aAAW,QAAQ,SAAS;AAC1B,UAAM,cAAc,aAAa,KAAK,QAAQ,QAAQ;AACtD,eAAW,WAAW,KAAK,UAAU;AACnC,YAAM,eACJ,QAAQ,aAAa,SAAY,KAAK,MAAM,QAAQ,QAAQ,IAAI;AAClE,aAAO,KAAK;AAAA,QACV,QAAQ,KAAK;AAAA,QACb,gBAAgB,KAAK;AAAA,QACrB,cAAc,QAAQ;AAAA,QACtB,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,SAAS,OAAO,SAAS,YAAY,IAChC,eACD,OAAO;AAAA,QACX,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,QACvE,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,QACjE;AAAA,QACA,eAAe,OAAO;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,EACF;AAMA,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,UAAM,UAAU,OAAO,SAAS,EAAE,OAAO;AACzC,UAAM,UAAU,OAAO,SAAS,EAAE,OAAO;AACzC,QAAI,WAAW,WAAW,EAAE,YAAY,EAAE,QAAS,QAAO,EAAE,UAAU,EAAE;AACxE,QAAI,YAAY,QAAS,QAAO,UAAU,KAAK;AAC/C,WAAO,EAAE,gBAAgB,EAAE;AAAA,EAC7B,CAAC;AAcD,QAAM,SAAuB,CAAC;AAC9B,aAAW,OAAO,QAAQ;AACxB,UAAM,MAAM,WAAW,IAAI,cAAc,IAAI,MAAM;AACnD,UAAM,aAAa,CAAC,OAAO,SAAS,IAAI,OAAO;AAC/C,UAAM,WAAW,eAAe,IAAI,IAAI;AAMxC,UAAM,eAAe,CAAC,UAA+B;AACnD,UAAI,MAAM,QAAQ,KAAK,CAAC,WAAW,OAAO,WAAW,IAAI,MAAM,GAAG;AAChE,eAAO;AAAA,MACT;AAEA,YAAM,eAAe,CAAC,OAAO,SAAS,MAAM,QAAQ;AACpD,UAAI,iBAAiB,WAAY,QAAO;AACxC,UAAI,CAAC,gBAAgB,KAAK,IAAI,IAAI,UAAU,MAAM,QAAQ,IAAI,aAAa;AACzE,eAAO;AAAA,MACT;AAOA,aAAO,MAAM,QAAQ;AAAA,QAAK,CAAC,WACzB,iBAAiB,eAAe,OAAO,IAAI,GAAG,UAAU,CAAC,YAAY;AAAA,MACvE;AAAA,IACF;AAcA,UAAM,uBAAuB,CAC3B,oBAC2B;AAC3B,UAAI;AACJ,UAAI,YAAY;AAChB,iBAAW,SAAS,QAAQ;AAC1B,YACG,MAAM,QAAQ,QAAS,mBACxB,CAAC,aAAa,KAAK,GACnB;AACA;AAAA,QACF;AACA,cAAM,QACJ,CAAC,cAAc,OAAO,SAAS,MAAM,QAAQ,IACzC,KAAK,IAAI,IAAI,UAAU,MAAM,QAAQ,IACrC;AACN,YACE,SAAS,UACT,QAAQ,aACP,UAAU,aAAa,MAAM,WAAW,KAAK,UAC9C;AACA,iBAAO;AACP,sBAAY;AAAA,QACd;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAGA,QAAI,SAAS,qBAAqB,IAAI;AACtC,QAAI,WAAW,QAAW;AAGxB,eAAS,qBAAqB,KAAK;AAAA,IACrC;AAEA,QAAI,WAAW,QAAW;AACxB,aAAO,QAAQ,KAAK,GAAG;AACvB,UAAI,IAAI,gBAAgB,OAAO,eAAe;AAC5C,eAAO,gBAAgB,IAAI;AAAA,MAC7B;AAAA,IACF,OAAO;AACL,aAAO,KAAK;AAAA,QACV;AAAA,QACA,cAAc,IAAI;AAAA,QAClB,QAAQ,IAAI;AAAA,QACZ,SAAS,CAAC,GAAG;AAAA,QACb,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA,QAId,gBAAgB,IAAI;AAAA,QACpB,cAAc,IAAI;AAAA,QAClB,eAAe,IAAI;AAAA,MACrB,CAAC;AAAA,IACH;AAAA,EACF;AAMA,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,UAAM,WAAW,CAAC,OAAO,SAAS,EAAE,QAAQ;AAC5C,UAAM,WAAW,CAAC,OAAO,SAAS,EAAE,QAAQ;AAC5C,QAAI,aAAa,SAAU,QAAO,WAAW,IAAI;AACjD,QAAI,CAAC,YAAY,EAAE,aAAa,EAAE,SAAU,QAAO,EAAE,WAAW,EAAE;AAClE,WAAO,EAAE,gBAAgB,EAAE;AAAA,EAC7B,CAAC;AAED,QAAM,WAA2B,CAAC;AAClC,QAAM,gBAAqC,CAAC;AAC5C,aAAW,SAAS,QAAQ;AAC1B,UAAM,aAAa,eAAe,KAAK;AACvC,aAAS,KAAK,WAAW,OAAO;AAChC,kBAAc,KAAK,GAAG,WAAW,aAAa;AAAA,EAChD;AAaA,QAAM,eAAe,IAAI,IAAI,SAAS,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/D,WAAS,KAAK,CAAC,GAAG,MAAM;AACtB,UAAM,MAAM,EAAE,aAAa,SAAY,KAAK,MAAM,EAAE,QAAQ,IAAI,OAAO;AACvE,UAAM,MAAM,EAAE,aAAa,SAAY,KAAK,MAAM,EAAE,QAAQ,IAAI,OAAO;AACvE,UAAM,UAAU,OAAO,SAAS,GAAG;AACnC,UAAM,UAAU,OAAO,SAAS,GAAG;AACnC,QAAI,WAAW,SAAS;AACtB,UAAI,QAAQ,IAAK,QAAO,MAAM;AAAA,IAChC,WAAW,YAAY,SAAS;AAC9B,aAAO,UAAU,KAAK;AAAA,IACxB;AAGA,YAAQ,aAAa,IAAI,CAAC,KAAK,MAAM,aAAa,IAAI,CAAC,KAAK;AAAA,EAC9D,CAAC;AAOD,kCAAgC,UAAU,aAAa,aAAa;AAEpE,QAAM,SAA4B;AAAA,IAChC;AAAA,IACA,UAAU,gBAAgB,MAAM;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,WAAW,OAAW,QAAO,SAAS;AAC1C,MAAI,UAAU,OAAW,QAAO,QAAQ;AACxC,MAAI,YAAY,OAAW,QAAO,UAAU;AAC5C,SAAO;AACT;AAOA,SAAS,eAAe,OAAoC;AAC1D,QAAM,UAAU,MAAM;AAKtB,QAAM,SAAS,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM;AACzC,QAAI,KAAK,IAAI,EAAE,cAAc,EAAE,WAAW,IAAI,wBAAwB;AACpE,aAAO,EAAE,cAAc,EAAE;AAAA,IAC3B;AACA,QAAI,EAAE,KAAK,WAAW,EAAE,KAAK,OAAQ,QAAO,EAAE,KAAK,SAAS,EAAE,KAAK;AACnE,QAAI,EAAE,WAAW,EAAE,OAAQ,QAAO,EAAE,SAAS,EAAE,SAAS,KAAK;AAC7D,QAAI,EAAE,mBAAmB,EAAE,gBAAgB;AACzC,aAAO,EAAE,iBAAiB,EAAE,iBAAiB,KAAK;AAAA,IACpD;AACA,WAAO,EAAE,gBAAgB,EAAE;AAAA,EAC7B,CAAC;AACD,QAAM,MAAM,OAAO,CAAC;AACpB,QAAM,WAAW,eAAe,IAAI,IAAI;AAUxC,MAAI,SAAS;AACb,MAAI,SAAS,SAAS,GAAG;AACvB,QAAI,UAAU;AACd,eAAW,aAAa,QAAQ;AAC9B,UAAI,cAAc,IAAK;AACvB,YAAM,iBAAiB,eAAe,UAAU,IAAI;AACpD,UACE,aAAa,UAAU,cAAc,KACrC,eAAe,SAAS,SAAS,UACjC,eAAe,SAAS,SACxB;AACA,iBAAS;AACT,kBAAU,eAAe;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACA,QAAM,oBAAoB,WAAW;AACrC,QAAM,SAAS,OAAO,OAAO,CAAC,WAAW,WAAW,MAAM;AAE1D,QAAM,cAAc,eAAe,OAAO,IAAI;AAE9C,QAAM,SACJ,QAAQ,WAAW,IACf,gBACA,oBACE,kBACA,OAAO;AAAA,IACL,CAAC,MAAM,OAAO,cAAc,EAAE,cAAc;AAAA,EAC9C,IACE,iBACA,OAAO,KAAK,CAAC,MAAM,OAAO,KAAK,SAAS,EAAE,KAAK,SAAS,CAAC,IACvD,kBACA;AAKZ,QAAM,WAAqD,CAAC;AAC5D,MAAI,WAAW;AACf,aAAW,aAAa,QAAQ;AAC9B,UAAM,iBAAiB,eAAe,UAAU,IAAI;AACpD,QAAI,YAAY,WAAW,KAAK,eAAe,WAAW,EAAG;AAC7D,QAAI,WAAW,aAAa,cAAc,EAAG;AAC7C,QACE,aAAa,gBAAgB,WAAW,KACxC,aAAa,aAAa,cAAc,GACxC;AACA;AAAA,IACF;AACA,eAAW;AACX,aAAS,KAAK,EAAE,QAAQ,UAAU,QAAQ,OAAO,UAAU,KAAK,CAAC;AAAA,EACnE;AASA,QAAM,sBAAsB,IAAI;AAAA,IAC9B,QAAQ,IAAI,CAAC,MAAM,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC;AAAA,EACzD;AACA,QAAM,kBAAkB,oBAAoB,OAAO;AAEnD,QAAM,eAAe,OAAO,IAAI,CAAC,eAAe;AAAA,IAC9C,QAAQ,UAAU;AAAA,IAClB,MAAM,UAAU;AAAA,EAClB,EAAE;AAIF,QAAM,aACJ,YAAY,kBACR,QAAQ,OAAO,cAAc,GAAG,IAChC,QAAQ,SAAS,IACf,QAAQ,OAAO,cAAc,OAAO,QAAQ,SAAS,EAAE,IACvD,QAAQ,OAAO,WAAW;AAYlC,QAAM,UAAwB;AAAA,IAC5B,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO;AAAA,IACf,MAAM,OAAO;AAAA,IACb;AAAA,IACA,YAAY;AAAA,MACV,QAAQ,OAAO;AAAA,MACf,gBAAgB,OAAO;AAAA,MACvB,aAAa,OAAO;AAAA,MACpB;AAAA,MACA;AAAA,MACA,GAAI,OAAO,aAAa,SACpB,EAAE,gBAAgB,OAAO,SAAS,IAClC,CAAC;AAAA,MACL,GAAI,OAAO,WAAW,SAAY,EAAE,cAAc,OAAO,OAAO,IAAI,CAAC;AAAA,IACvE;AAAA,IACA,GAAI,MAAM,mBAAmB,SACzB,EAAE,UAAU,MAAM,eAAe,IACjC,CAAC;AAAA,IACL,GAAI,MAAM,iBAAiB,SAAY,EAAE,QAAQ,MAAM,aAAa,IAAI,CAAC;AAAA,EAC3E;AAEA,QAAM,gBAAqC,CAAC;AAI5C,QAAM,YACJ,MAAM,mBACL,OAAO,SAAS,MAAM,QAAQ,IAC3B,IAAI,KAAK,MAAM,QAAQ,EAAE,YAAY,IACrC;AACN,MAAI,UAAU;AACZ,kBAAc,KAAK;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,aAAa;AAAA,MACtB,YAAY,CAAC,EAAE,QAAQ,OAAO,QAAQ,OAAO,OAAO,KAAK,GAAG,GAAG,QAAQ;AAAA,MACvE,aAAa,EAAE,QAAQ,OAAO,QAAQ,OAAO,OAAO,KAAK;AAAA,IAC3D,CAAC;AAAA,EACH;AACA,MAAI,iBAAiB;AAGnB,UAAM,oBAAoB,QACvB,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,aAAa,EAAE,EACxD;AAAA,MAAK,CAAC,GAAG,MACR,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS,IAAI;AAAA,IACvD;AACF,kBAAc,KAAK;AAAA,MACjB,MAAM;AAAA,MACN,SAAS,aAAa;AAAA,MACtB,YAAY;AAAA,MACZ,aAAa,EAAE,QAAQ,OAAO,QAAQ,OAAO,OAAO,aAAa;AAAA,IACnE,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,SAAS,cAAc;AAClC;AAaA,SAAS,gCACP,UACA,aACA,KACM;AACN,QAAM,IAAI,SAAS;AACnB,MAAI,IAAI,EAAG;AACX,QAAM,UAAU,IAAI,MAAe,CAAC,EAAE,KAAK,KAAK;AAChD,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,QAAQ,CAAC,EAAG;AAChB,UAAM,OAAO,SAAS,CAAC;AACvB,UAAM,SACJ,KAAK,aAAa,SAAY,KAAK,MAAM,KAAK,QAAQ,IAAI;AAC5D,QAAI,CAAC,OAAO,SAAS,MAAM,EAAG;AAC9B,UAAM,YAAY,eAAe,KAAK,IAAI;AAC1C,UAAM,aAAuB,CAAC;AAC9B,aAAS,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;AAC9B,UAAI,QAAQ,CAAC,EAAG;AAChB,YAAM,OAAO,SAAS,CAAC;AAQvB,UACE,WAAW,KAAK,SAAS,KAAK,MAAM,MACpC,WAAW,KAAK,SAAS,KAAK,MAAM,GACpC;AACA;AAAA,MACF;AACA,UAAI,KAAK,WAAW,WAAW,KAAK,WAAW,OAAQ;AACvD,YAAM,SACJ,KAAK,aAAa,SAAY,KAAK,MAAM,KAAK,QAAQ,IAAI;AAC5D,UAAI,CAAC,OAAO,SAAS,MAAM,EAAG;AAC9B,UAAI,KAAK,IAAI,SAAS,MAAM,IAAI,YAAa;AAC7C,UAAI,iBAAiB,WAAW,eAAe,KAAK,IAAI,GAAG,IAAI,GAAG;AAChE;AAAA,MACF;AACA,iBAAW,KAAK,CAAC;AAAA,IACnB;AACA,QAAI,WAAW,WAAW,EAAG;AAC7B,eAAW,QAAQ,CAAC;AACpB,eAAW,OAAO,WAAY,SAAQ,GAAG,IAAI;AAE7C,UAAM,WAAW,WAAW,IAAI,CAAC,QAAQ,SAAS,GAAG,CAAE;AAOvD,UAAM,gBAAgB,IAAI,IAAI,SAAS,IAAI,CAAC,KAAKG,OAAM,CAAC,KAAKA,EAAC,CAAC,CAAC;AAChE,aAAS,KAAK,CAAC,GAAG,MAAM;AACtB,UACE,KAAK,IAAI,EAAE,WAAW,cAAc,EAAE,WAAW,WAAW,IAC5D,wBACA;AACA,eAAO,EAAE,WAAW,cAAc,EAAE,WAAW;AAAA,MACjD;AACA,UAAI,EAAE,KAAK,WAAW,EAAE,KAAK,OAAQ,QAAO,EAAE,KAAK,SAAS,EAAE,KAAK;AACnE,UAAI,EAAE,WAAW,WAAW,EAAE,WAAW,QAAQ;AAC/C,eAAO,EAAE,WAAW,SAAS,EAAE,WAAW,SAAS,KAAK;AAAA,MAC1D;AACA,aAAO,cAAc,IAAI,CAAC,IAAK,cAAc,IAAI,CAAC;AAAA,IACpD,CAAC;AACD,UAAM,cAAc,SAAS,CAAC;AAC9B,UAAM,YAAY,SACf,IAAI,CAAC,MAAM,EAAE,QAAQ,EACrB,OAAO,CAAC,MAAmB,MAAM,MAAS,EAC1C,KAAK,EAAE,CAAC;AAEX,eAAW,OAAO,UAAU;AAC1B,UAAI,aAAa,QAAQ,IAAI,WAAW,cAAc,GAAG;AAAA,IAC3D;AAEA,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MACN,SAAS,aAAa;AAAA,MACtB,YAAY,SAAS,IAAI,CAAC,OAAO;AAAA,QAC/B,QAAQ,EAAE,WAAW;AAAA,QACrB,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,MACF,aAAa;AAAA,QACX,QAAQ,YAAY,WAAW;AAAA,QAC/B,OAAO,YAAY;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAQA,SAAS,gBAAgB,QAAkD;AAOzE,QAAM,QAAkB,CAAC;AACzB,QAAM,MAAM,oBAAI,IAAiB;AACjC,aAAW,OAAO,QAAQ;AACxB,UAAM,MAAM,WAAW,IAAI,cAAc,IAAI,MAAM;AACnD,QAAI,QAAQ,IAAI,IAAI,GAAG;AACvB,QAAI,UAAU,QAAW;AACvB,cAAQ;AAAA,QACN,OAAO,IAAI;AAAA,QACX,QAAQ,IAAI;AAAA,QACZ,SAAS,oBAAI,IAAY;AAAA,QACzB,SAAS,sBAAsB,KAAK,IAAI,YAAY;AAAA,MACtD;AACA,UAAI,IAAI,KAAK,KAAK;AAClB,YAAM,KAAK,GAAG;AAAA,IAChB;AACA,UAAM,QAAQ,IAAI,IAAI,MAAM;AAAA,EAC9B;AACA,SAAO,MAAM,IAAI,CAAC,QAAQ;AACxB,UAAM,QAAQ,IAAI,IAAI,GAAG;AACzB,QAAI,UAAU,OAAW,OAAM,IAAI,MAAM,iCAAiC;AAC1E,UAAM,cAAc,MAAM,QAAQ;AAClC,UAAM,aAAa,MAAM,SACrB,cAAc,IACZ,OACA,OACF,MAAM,UACJ,cAAc,IACZ,MACA,MACF,cAAc,IACZ,MACA;AACR,WAAO;AAAA,MACL,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,MACd;AAAA,MACA,SAAS,CAAC,GAAG,MAAM,OAAO,EAAE,KAAK;AAAA,IACnC;AAAA,EACF,CAAC;AACH;;;ACjzBA,SAAS,cAAAC,mBAAkB;AAiB3B,IAAM,mBAAmB;AAWlB,IAAM,sBAAsB;AASnC,SAAS,mBACP,MACA,QACQ;AACR,QAAM,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM;AACxC,QAAI,EAAE,WAAW,EAAE,OAAQ,QAAO,EAAE,SAAS,EAAE,SAAS,KAAK;AAC7D,QAAI,EAAE,mBAAmB,EAAE,gBAAgB;AACzC,aAAO,EAAE,iBAAiB,EAAE,iBAAiB,KAAK;AAAA,IACpD;AACA,WAAO;AAAA,EACT,CAAC;AASD,QAAM,SAAS;AAAA,IACb;AAAA,IACA,OAAO,IAAI,CAAC,SAAS;AAAA,MACnB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,UAAU;AAAA,MACf,KAAK,SAAS;AAAA,MACd,KAAK,WAAW;AAAA,MAChB,KAAK,SAAS,IAAI,CAAC,YAAY;AAAA,QAC7B,QAAQ;AAAA,QACR,QAAQ,SAAS,SAAS;AAAA,QAC1B,QAAQ,YAAY;AAAA,QACpB,QAAQ,UAAU;AAAA,QAClB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,SAAOC,YAAW,QAAQ,EAAE,OAAO,KAAK,UAAU,MAAM,GAAG,OAAO,EAAE,OAAO,KAAK;AAClF;AAWA,SAAS,kBACP,SACA,SACQ;AACR,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,oBACJ,QAAQ,qBAAqB;AAC/B,QAAM,WAAW,QAAQ,eAAe,CAAC;AAIzC,QAAM,eAAe,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EACtC,KAAK,EACL,IAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,MAAM,KAAK,oBAAoB,CAAC;AACrE,SAAO,KAAK,UAAU,CAAC,gBAAgB,mBAAmB,YAAY,CAAC;AACzE;AAUO,SAAS,gBACd,MACA,QACA,SACA,cAAsB,qBACd;AACR,QAAM,YAAY,mBAAmB,MAAM,MAAM;AACjD,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,OAAO,IAAI,CAAC,SAAS,KAAK,MAAM;AAAA,EAClC;AACA,SAAOA,YAAW,QAAQ,EACvB,OAAO,SAAS,EAChB,OAAO,IAAI,EACX,OAAO,WAAW,EAClB,OAAO,IAAI,EACX,OAAO,WAAW,EAClB,OAAO,KAAK;AACjB;AAEA,SAAS,gBACP,SACA,gBACA,mBAC6B;AAC7B,SAAO;AAAA,IACL,eAAe,QAAQ,IAAI,CAAC,UAAU;AAAA,MACpC,QAAQ,KAAK;AAAA,MACb,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,MACf,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAC3D,cAAc,KAAK,SAAS;AAAA,IAC9B,EAAE;AAAA,IACF;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AACF;AAOO,SAAS,QACd,MACA,QACA,UAAyB,CAAC,GACT;AACjB,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,oBACJ,QAAQ,qBAAqB;AAE/B,QAAM,WAAW,qBAAqB,QAAQ,cAAc;AAC5D,QAAM,gBAA6C,SAAS,IAAI,CAAC,YAAY;AAC3E,UAAM,QAA2B,YAAY,SAAS;AAAA,MACpD,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AACD,UAAM,KAAK,GAAG,gBAAgB,IAAI,mBAAmB,MAAM,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAChF,UAAM,SAAoC;AAAA,MACxC;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,SAAS,MAAM;AAAA,MACf,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,eAAe,MAAM;AAAA,MACrB,YAAY,gBAAgB,SAAS,gBAAgB,iBAAiB;AAAA,IACxE;AACA,QAAI,MAAM,WAAW,OAAW,QAAO,SAAS,MAAM;AACtD,QAAI,MAAM,UAAU,OAAW,QAAO,QAAQ,MAAM;AACpD,QAAI,MAAM,YAAY,OAAW,QAAO,UAAU,MAAM;AACxD,WAAO;AAAA,EACT,CAAC;AAED,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,eAAe;AAChC,eAAW,UAAU,KAAK,SAAS;AACjC,UAAI,CAAC,YAAY,IAAI,MAAM,GAAG;AAC5B,oBAAY,IAAI,MAAM;AACtB,gBAAQ,KAAK,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,gBAAgB,MAAM,QAAQ,OAAO;AAAA,EACpD;AACF;;;AC5MA,SAAS,cAAAC,mBAAkB;AAC3B,YAAYC,YAAU;AASf,IAAM,cAAc;AAGpB,SAAS,eACd,eACQ;AACR,SAAOC,YAAW,QAAQ,EACvB,OAAO,KAAK,UAAU,aAAa,GAAG,OAAO,EAC7C,OAAO,KAAK;AACjB;AAEO,SAAS,qBACd,MACA,eACA,SACA,aACA,SACc;AACd,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,aAAa,QAAQ;AAAA,IACrB,mBAAmB,cAAc;AAAA,IACjC;AAAA,IACA,UAAU,eAAe,aAAa;AAAA,IACtC;AAAA,EACF;AACF;AAGO,SAAS,mBACd,MACA,eACQ;AACR,QAAM,QAAkB,CAAC,KAAK;AAC9B,QAAM,KAAK,SAAS,KAAK,IAAI,EAAE;AAC/B,QAAM,KAAK,SAAS,KAAK,UAAU,KAAK,IAAI,CAAC,EAAE;AAC/C,QAAM,KAAK,gBAAgB,KAAK,WAAW,EAAE;AAC7C,QAAM,KAAK,sBAAsB,KAAK,iBAAiB,EAAE;AACzD,QAAM,KAAK,gBAAgB,KAAK,UAAU,KAAK,WAAW,CAAC,EAAE;AAC7D,QAAM,KAAK,aAAa,KAAK,UAAU,KAAK,QAAQ,CAAC,EAAE;AACvD,QAAM,KAAK,YAAY,KAAK,UAAU,KAAK,OAAO,CAAC,EAAE;AACrD,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA,EAAK,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC;AAAA;AACvE;AAEA,SAAS,YAAY,OAAuB;AAC1C,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,KAAK,QAAQ,UAAU,GAAG;AAC3E,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,OAAO;AACjC,UAAI,OAAO,WAAW,SAAU,QAAO;AAAA,IACzC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAmC;AAC9D,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,EAAG,QAAO;AACnD,SAAO,KAAK,MAAM,MAAM;AAC1B;AAEA,IAAM,6BAAmD;AAAA,EACvD,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,aAAa;AACf;AAEA,IAAM,2BAAiD;AAAA,EACrD,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,WAAW;AACb;AAEA,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,cAAc,OAAmC;AACxD,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ;AAC/E;AAGA,SAAS,yBAAyB,OAAyB;AACzD,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,OAAO,MAAM,WAAW,SAAU,QAAO;AAC7C,MAAI,OAAO,MAAM,mBAAmB,SAAU,QAAO;AACrD,MAAI,OAAO,MAAM,gBAAgB,SAAU,QAAO;AAClD,MAAI,OAAO,MAAM,WAAW,SAAU,QAAO;AAC7C,MAAI,EAAE,MAAM,UAAU,4BAA6B,QAAO;AAC1D,SACE,MAAM,QAAQ,MAAM,YAAY,KAChC,MAAM,aAAa;AAAA,IACjB,CAAC,QACC,cAAc,GAAG,KAAK,OAAO,IAAI,WAAW,YAAY,OAAO,IAAI,SAAS;AAAA,EAChF;AAEJ;AAGA,SAAS,eAAe,OAAyB;AAC/C,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,OAAO,MAAM,YAAY,SAAU,QAAO;AAC9C,MAAI,OAAO,MAAM,WAAW,UAAW,QAAO;AAC9C,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO;AAC3C,MAAI,OAAO,MAAM,eAAe,SAAU,QAAO;AACjD,SAAO,yBAAyB,MAAM,UAAU;AAClD;AAGA,SAAS,eAAe,OAAyB;AAC/C,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,OAAO,MAAM,UAAU,SAAU,QAAO;AAC5C,MAAI,OAAO,MAAM,WAAW,UAAW,QAAO;AAC9C,MAAI,OAAO,MAAM,eAAe,SAAU,QAAO;AACjD,SAAO,cAAc,MAAM,OAAO;AACpC;AAGA,SAAS,oBAAoB,OAAyB;AACpD,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO;AAC3C,MAAI,EAAE,MAAM,QAAQ,0BAA2B,QAAO;AACtD,MAAI,OAAO,MAAM,YAAY,SAAU,QAAO;AAC9C,SACE,MAAM,QAAQ,MAAM,UAAU,KAC9B,MAAM,WAAW;AAAA,IACf,CAAC,SACC,cAAc,IAAI,KAAK,OAAO,KAAK,WAAW,YAAY,OAAO,KAAK,UAAU;AAAA,EACpF;AAEJ;AAGA,SAAS,oBAAoB,OAAyB;AACpD,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,OAAO,MAAM,WAAW,SAAU,QAAO;AAC7C,MAAI,OAAO,MAAM,mBAAmB,SAAU,QAAO;AACrD,MAAI,OAAO,MAAM,aAAa,SAAU,QAAO;AAC/C,SAAO,OAAO,MAAM,iBAAiB;AACvC;AAGA,SAAS,8BAA8B,OAAyB;AAC9D,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,CAAC,MAAM,QAAQ,MAAM,aAAa,KAAK,CAAC,MAAM,cAAc,MAAM,mBAAmB,GAAG;AAC1F,WAAO;AAAA,EACT;AACA,MAAI,OAAO,MAAM,mBAAmB,SAAU,QAAO;AACrD,MAAI,OAAO,MAAM,sBAAsB,SAAU,QAAO;AACxD,SAAO,MAAM,WAAW;AAC1B;AAUA,SAAS,4BAA4B,OAAoD;AACvF,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,MAAI,OAAO,MAAM,OAAO,SAAU,QAAO;AACzC,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO;AAC3C,MAAI,OAAO,MAAM,aAAa,SAAU,QAAO;AAC/C,MAAI,CAAC,cAAc,MAAM,OAAO,EAAG,QAAO;AAC1C,MAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,SAAS,MAAM,cAAc,EAAG,QAAO;AACpF,MAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,SAAS,MAAM,cAAc,EAAG,QAAO;AACpF,MAAI,CAAC,MAAM,QAAQ,MAAM,aAAa,KAAK,CAAC,MAAM,cAAc,MAAM,mBAAmB,GAAG;AAC1F,WAAO;AAAA,EACT;AACA,SAAO,8BAA8B,MAAM,UAAU;AACvD;AAYO,SAAS,eAAe,KAAkC;AAC/D,MAAI,CAAC,IAAI,WAAW,OAAO,EAAG,QAAO;AACrC,QAAM,aAAa,IAAI,QAAQ,WAAW,CAAC;AAC3C,MAAI,eAAe,GAAI,QAAO;AAC9B,QAAM,SAAS,IAAI,MAAM,GAAG,UAAU;AACtC,QAAM,OAAO,IAAI,MAAM,aAAa,CAAC,EAAE,QAAQ,OAAO,EAAE;AAExD,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,UAAM,QAAQ,KAAK,MAAM,gCAAgC;AACzD,QAAI,MAAO,SAAQ,IAAI,MAAM,CAAC,GAAG,YAAY,MAAM,CAAC,CAAC,CAAC;AAAA,EACxD;AAEA,MAAI,QAAQ,IAAI,MAAM,MAAM,YAAa,QAAO;AAChD,QAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,MAAI,SAAS,OAAW,QAAO;AAE/B,MAAI,gBAA6C,CAAC;AAClD,MAAI,UAAU;AACd,QAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,YAAY,WAAW,GAAG;AAQ5B,cAAU;AAAA,EACZ,OAAO;AACL,QAAI;AACF,YAAM,SAAkB,KAAK,MAAM,WAAW;AAC9C,UAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM,2BAA2B,GAAG;AACtE,wBAAgB;AAAA,MAClB,OAAO;AAML,kBAAU;AAAA,MACZ;AAAA,IACF,QAAQ;AAIN,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,OAAqB;AAAA,IACzB,MAAM;AAAA,IACN;AAAA,IACA,aAAa,oBAAoB,QAAQ,IAAI,aAAa,CAAC;AAAA,IAC3D,mBAAmB,oBAAoB,QAAQ,IAAI,mBAAmB,CAAC;AAAA,IACvE,aAAa,QAAQ,IAAI,aAAa,KAAK;AAAA,IAC3C,UAAU,QAAQ,IAAI,UAAU,KAAK;AAAA,IACrC,SAAS,QAAQ,IAAI,SAAS,KAAK;AAAA,EACrC;AACA,SAAO,EAAE,MAAM,eAAe,QAAQ;AACxC;AAGO,IAAM,kBAAkB;AA0CxB,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YACmB,cACA,WACA,IACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAHgB;AAAA,EACA;AAAA,EACA;AAAA,EAGnB,aAAa,MAAsB;AACjC,QAAI,CAAC,sBAAsB,IAAI,GAAG;AAChC,YAAM,IAAI;AAAA,QACR,iCAAiC,OAAO,IAAI,CAAC;AAAA,MAC/C;AAAA,IACF;AACA,WAAY,YAAK,KAAK,cAAc,iBAAiB,GAAG,IAAI,KAAK;AAAA,EACnE;AAAA,EAEA,MAAM,cAAc,MAAc,YAAmC;AACnE,UAAM,WAAW,KAAK,aAAa,IAAI;AACvC,UAAM,KAAK,oBAAoB,QAAQ;AACvC,UAAM,KAAK,GAAG,UAAU,UAAU,UAAU;AAAA,EAC9C;AAAA;AAAA,EAGA,MAAM,aAAa,MAAsC;AACvD,UAAM,WAAW,KAAK,aAAa,IAAI;AACvC,UAAM,KAAK,oBAAoB,QAAQ;AACvC,QAAI;AACF,aAAO,MAAM,KAAK,GAAG,SAAS,QAAQ;AAAA,IACxC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,MAA6B;AAChD,UAAM,WAAW,KAAK,aAAa,IAAI;AACvC,UAAM,KAAK,oBAAoB,QAAQ;AACvC,QAAI;AACF,YAAM,KAAK,GAAG,WAAW,QAAQ;AAAA,IACnC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU;AACtD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,gBAAmC;AACvC,UAAM,YAAiB,YAAK,KAAK,cAAc,eAAe;AAC9D,UAAM,KAAK,oBAAoB,SAAS;AACxC,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,GAAG,QAAQ,SAAS;AAAA,IAC3C,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,YAAM;AAAA,IACR;AACA,UAAM,OAAiB,CAAC;AACxB,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,SAAS,KAAK,EAAG;AAC5B,YAAM,OAAO,MAAM,MAAM,GAAG,EAAE;AAC9B,UAAI,CAAC,sBAAsB,IAAI,EAAG;AAClC,WAAK,KAAK,IAAI;AAAA,IAChB;AACA,SAAK,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AAChD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAc,oBAAoB,YAAmC;AACnE,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,KAAK,GAAG,SAAS,KAAK,SAAS;AAAA,IAClD,QAAQ;AAGN,iBAAgB,eAAQ,KAAK,SAAS;AAAA,IACxC;AAIA,UAAM,KAAK,eAAe,UAAU,KAAK,YAAY;AACrD,UAAM,KAAK,eAAe,UAAe,eAAQ,UAAU,CAAC;AAC5D,UAAM,KAAK,eAAe,UAAU,UAAU;AAM9C,UAAM,KAAK,4BAA4B;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,8BAA6C;AACzD,UAAM,YAAiB,YAAK,KAAK,cAAc,eAAe;AAC9D,QAAIC;AACJ,QAAI;AACF,MAAAA,QAAO,MAAM,KAAK,GAAG,MAAM,SAAS;AAAA,IACtC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU;AACtD,YAAM;AAAA,IACR;AACA,QAAIA,MAAK,gBAAgB;AACvB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,eAAe,UAAkB,WAAkC;AAC/E,QAAI;AACJ,QAAI;AACF,sBAAgB,MAAM,KAAK,GAAG,SAAS,SAAS;AAAA,IAClD,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,aAAa,UAAU,aAAa,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACjcA,IAAM,uBACJ;AACF,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AAGtB,IAAM,kBAAkB,KAAK;AAa7B,IAAM,6BAA6B,KAAK;AAGxC,SAAS,WAAW,OAAe,MAAkC;AACnE,QAAM,QAAQ,cAAc,KAAK,MAAM,KAAK,CAAC;AAC7C,MAAI,UAAU,KAAM,QAAO;AAM3B,QAAM,OAAO,MAAM,CAAC,MAAM,OAAO,OAAO,MAAM,CAAC;AAC/C,SAAO,GAAG,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC;AACpC;AAOA,SAAS,kBAAkB,OAAmC;AAC5D,QAAM,QAAQ,cAAc,KAAK,MAAM,KAAK,CAAC;AAC7C,MAAI,UAAU,KAAM,QAAO;AAC3B,QAAM,OAAO,MAAM,CAAC,MAAM,OAAO,IAAI,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AACjE,SAAO,OAAO,KAAK,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AACjD;AAGA,SAAS,gBAAgB,MAAsB;AAC7C,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,SAAS,OAAO,SAAS,MAAM,EAAE,CAAC;AACzE,QAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;AACzC,KAAG,WAAW,GAAG,WAAW,IAAI,CAAC;AACjC,QAAM,KAAK,GAAG,eAAe;AAC7B,QAAM,KAAK,OAAO,GAAG,YAAY,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACvD,QAAM,KAAK,OAAO,GAAG,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,SAAO,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE;AAC1B;AAQO,SAAS,wBACd,MACA,gBAY2B;AAC3B,MAAI,CAAC,sBAAsB,IAAI,EAAG,QAAO,CAAC;AAC1C,QAAM,SAAoC,CAAC;AAE3C,aAAW,EAAE,QAAQ,MAAM,QAAQ,KAAK,gBAAgB;AACtD,QAAI,UAWO;AAEX,UAAM,eAAe,MAAM;AACzB,UAAI,YAAY,KAAM;AACtB,YAAM,WACJ,QAAQ,YACR,QAAQ,SAAS,KAAK,CAAC,YAAY,QAAQ,aAAa,MAAS,GAAG,YACpE,GAAG,IAAI;AACT,YAAM,QAAiC;AAAA,QACrC;AAAA,QACA,gBAAgB,QAAQ;AAAA,QACxB;AAAA,QACA,UAAU,QAAQ;AAAA,MACpB;AACA,UAAI,QAAQ,WAAW,OAAW,OAAM,SAAS,QAAQ;AACzD,UAAI,QAAQ,UAAU,OAAW,OAAM,QAAQ,QAAQ;AACvD,aAAO,KAAK,KAAK;AACjB,gBAAU;AAAA,IACZ;AAEA,eAAW,WAAW,KAAK,MAAM,IAAI,GAAG;AACtC,YAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAI,KAAK,WAAW,EAAG;AAEvB,YAAM,UAAU,qBAAqB,KAAK,IAAI;AAC9C,UAAI,YAAY,MAAM;AACpB,qBAAa;AACb,cAAM,CAAC,EAAE,YAAY,UAAU,OAAO,EAAE,IAAI;AAC5C,cAAM,WAAW,kBAAkB,UAAU;AAC7C,cAAM,SAAS,kBAAkB,QAAQ;AAczC,cAAM,UACJ,aAAa,UAAa,WAAW,UAAa,SAAS;AAC7D,cAAM,eACJ,aAAa,UAAa,WAAW,SACjC,kBAAkB,WAAW,SAC7B;AACN,cAAM,gBACJ,WACA,iBAAiB,UACjB,gBAAgB;AAClB,cAAM,WAAW,WAAW,YAAY,IAAI;AAC5C,cAAM,SAAS,gBACX,WAAW,UAAU,gBAAgB,IAAI,CAAC,IAC1C,WAAW,UAAU,IAAI;AAC7B,kBAAU;AAAA,UACR,gBAAgB;AAAA,UAChB,UAAU,CAAC;AAAA,UACX;AAAA,UACA,GAAI,aAAa,SAAY,EAAE,cAAc,SAAS,IAAI,CAAC;AAAA,UAC3D,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,UAC7C,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,UACzC,GAAI,UAAU,UAAa,MAAM,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC;AAAA,QAC7D;AACA;AAAA,MACF;AAEA,UAAI,cAAc,KAAK,IAAI,MAAM,KAAM;AAEvC,YAAM,eAAe,2BAA2B,IAAI;AACpD,UAAI,iBAAiB,MAAM;AACzB,YAAI,YAAY,KAAM;AACtB,cAAM,EAAE,OAAO,OAAO,MAAM,QAAQ,IAAI;AACxC,cAAM,OAAO,UAAU,oBAAoB,OAAO,IAAI;AACtD,cAAM,SAAS,kBAAkB,KAAK;AAetC,cAAM,kBACJ,QAAQ,iBAAiB,UAAa,WAAW,SAC7C,kBAAkB,QAAQ,eAAe,SACzC;AACN,cAAM,mBACJ,QAAQ,iBAAiB,UACzB,WAAW,UACX,SAAS,QAAQ,gBACjB,oBAAoB,UACpB,mBAAmB;AACrB,cAAM,UAAU,mBAAmB,gBAAgB,IAAI,IAAI;AAC3D,cAAM,WAAW,WAAW,OAAO,OAAO;AAK1C,cAAM,UAAU,UACZ,qBAAqB,MAAM,KAAK,CAAC,IACjC,MAAM,KAAK;AACf,cAAM,UAA8B;AAAA,UAClC;AAAA;AAAA;AAAA;AAAA,UAIA,QAAQ,cAAc,OAAO;AAAA,UAC7B;AAAA,UACA,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,QAC/C;AACA,gBAAQ,SAAS,KAAK,OAAO;AAAA,MAC/B;AAAA,IAEF;AACA,iBAAa;AAAA,EACf;AAEA,SAAO;AACT;;;ACxOA,SAAS,cAAAC,mBAAkB;AAC3B,YAAYC,YAAU;AAOf,IAAM,oBAAoB;AAC1B,IAAM,eAAe;AACrB,IAAM,yBAAyB;AAGtC,IAAM,qBAAqB;AAIpB,SAAS,cAAc,IAA2B;AACvD,QAAM,QAAQ,mBAAmB,KAAK,EAAE;AACxC,SAAO,UAAU,OAAO,OAAO,MAAM,CAAC;AACxC;AAcA,SAAS,iBAAiB,MAAyB,OAA6B;AAC9E,SAAO,KAAK,UAAU;AAAA,IACpB,eAAe;AAAA,IACf,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,UAAU,KAAK;AAAA,IACf,QAAQ,KAAK;AAAA,IACb,KAAK,KAAK,OAAO;AAAA,IACjB,iBAAiB,KAAK;AAAA,IACtB,OAAO,KAAK,SAAS;AAAA,IACrB,WAAW,MAAM;AAAA,IACjB,SAAS,MAAM;AAAA,IACf,gBAAgB,MAAM;AAAA,IACtB,eAAe,MAAM;AAAA,IACrB,iBAAiB,MAAM;AAAA,IACvB,YAAY,MAAM;AAAA,IAClB,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,EACvB,CAAC;AACH;AAGO,SAAS,qBAAqB,MAAyB,OAAoC;AAChG,QAAM,cAAcC,YAAW,QAAQ,EAAE,OAAO,iBAAiB,MAAM,KAAK,GAAG,OAAO,EAAE,OAAO,KAAK;AACpG,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,IACA,eAAe;AAAA,EACjB;AACF;AAEA,SAAS,eAAe,KAAqB;AAC3C,QAAM,KAAK,KAAK,MAAM,GAAG;AACzB,MAAI,OAAO,MAAM,EAAE,EAAG,QAAO;AAC7B,SAAO,IAAI,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,IAAI,EAAE;AAChD;AAEA,SAAS,qBAAqB,SAA+B;AAC3D,QAAM,QAAQ,eAAe,QAAQ,YAAY,EAAE;AACnD,SAAO,KAAK,mBAAmB,QAAQ,OAAO,CAAC,OAAO,KAAK,MAAM,kBAAkB,QAAQ,IAAI,CAAC;AAClG;AAEA,SAAS,gBAAgB,KAAa,QAAqC;AACzE,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC,GAAG,GAAG,MAAM;AAC7C,QAAM,QAAQ,CAAC,GAAG,GAAG,GAAG;AACxB,aAAW,SAAS,OAAQ,OAAM,KAAK,OAAO,KAAK,UAAU,KAAK,CAAC,EAAE;AACrE,SAAO;AACT;AAGO,SAAS,uBAAuB,QAA+B;AACpE,QAAM,QAAkB,CAAC,KAAK;AAC9B,QAAM,KAAK,SAAS,YAAY,EAAE;AAClC,QAAM,KAAK,kBAAkB,OAAO,aAAa,EAAE;AACnD,QAAM,KAAK,OAAO,KAAK,UAAU,OAAO,EAAE,CAAC,EAAE;AAC7C,QAAM,KAAK,SAAS,KAAK,UAAU,OAAO,IAAI,CAAC,EAAE;AACjD,QAAM,KAAK,aAAa,KAAK,UAAU,OAAO,QAAQ,CAAC,EAAE;AACzD,QAAM,KAAK,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;AACrD,MAAI,OAAO,QAAQ,OAAW,OAAM,KAAK,QAAQ,KAAK,UAAU,OAAO,GAAG,CAAC,EAAE;AAC7E,QAAM,KAAK,oBAAoB,KAAK,UAAU,OAAO,eAAe,CAAC,EAAE;AACvE,MAAI,OAAO,UAAU,OAAW,OAAM,KAAK,UAAU,KAAK,UAAU,OAAO,KAAK,CAAC,EAAE;AACnF,QAAM,KAAK,GAAG,gBAAgB,aAAa,OAAO,SAAS,CAAC;AAC5D,QAAM,KAAK,GAAG,gBAAgB,WAAW,OAAO,OAAO,CAAC;AACxD,QAAM,KAAK,GAAG,gBAAgB,kBAAkB,OAAO,cAAc,CAAC;AACtE,QAAM,KAAK,kBAAkB,OAAO,aAAa,EAAE;AACnD,QAAM,KAAK,gBAAgB,KAAK,UAAU,OAAO,WAAW,CAAC,EAAE;AAC/D,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAEb,QAAM,UAAU,OAAO,UAAU,UAAa,OAAO,MAAM,SAAS,IAAI,SAAM,OAAO,KAAK,KAAK;AAC/F,QAAM,KAAK,aAAa,OAAO,EAAE,GAAG,OAAO,EAAE;AAC7C,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,EAAE;AACb,MAAI,OAAO,UAAU,WAAW,GAAG;AACjC,UAAM,KAAK,kBAAkB;AAAA,EAC/B,OAAO;AACL,eAAW,YAAY,OAAO,UAAW,OAAM,KAAK,KAAK,QAAQ,EAAE;AAAA,EACrE;AACA,QAAM,KAAK,EAAE;AAEb,MAAI,OAAO,cAAc,SAAS,KAAK,OAAO,gBAAgB,SAAS,GAAG;AACxE,UAAM,KAAK,mBAAmB;AAC9B,UAAM,KAAK,EAAE;AACb,eAAW,SAAS,OAAO,eAAe;AACxC,YAAM,KAAK,MAAM,MAAM,KAAK,KAAK,MAAM,KAAK,EAAE;AAAA,IAChD;AACA,QAAI,OAAO,gBAAgB,SAAS,GAAG;AACrC,UAAI,OAAO,cAAc,SAAS,EAAG,OAAM,KAAK,EAAE;AAClD,YAAM,KAAK,mBAAmB;AAC9B,YAAM,KAAK,EAAE;AACb,iBAAW,WAAW,OAAO,gBAAiB,OAAM,KAAK,KAAK,QAAQ,QAAQ,OAAO,GAAG,CAAC,EAAE;AAAA,IAC7F;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,EAAE;AACb,MAAI,OAAO,WAAW,WAAW,GAAG;AAClC,UAAM,KAAK,0CAA0C;AAAA,EACvD,OAAO;AACL,eAAW,WAAW,OAAO,WAAY,OAAM,KAAK,qBAAqB,OAAO,CAAC;AAAA,EACnF;AACA,QAAM,KAAK,EAAE;AAEb,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAC5B;AAkBA,SAASC,aAAY,OAAuB;AAC1C,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,QAAI;AACF,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,0BAA0B,KAA0C;AAClF,MAAI,CAAC,IAAI,WAAW,OAAO,EAAG,QAAO;AACrC,QAAM,aAAa,IAAI,QAAQ,WAAW,CAAC;AAC3C,MAAI,eAAe,GAAI,QAAO;AAC9B,QAAM,cAAc,IAAI,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI;AAEvD,QAAM,UAAkC,CAAC;AACzC,QAAM,QAAkC,CAAC;AACzC,MAAI,cAA6B;AACjC,aAAW,QAAQ,aAAa;AAC9B,UAAM,WAAW,eAAe,KAAK,IAAI;AACzC,QAAI,aAAa,QAAQ,gBAAgB,MAAM;AAC7C,YAAM,WAAW,EAAG,KAAKA,aAAY,SAAS,CAAC,CAAE,CAAC;AAClD;AAAA,IACF;AACA,UAAM,KAAK,mCAAmC,KAAK,IAAI;AACvD,QAAI,OAAO,KAAM;AACjB,UAAM,MAAM,GAAG,CAAC;AAChB,UAAM,QAAQ,GAAG,CAAC;AAClB,QAAI,UAAU,IAAI;AAChB,oBAAc;AACd,YAAM,GAAG,IAAI,CAAC;AAAA,IAChB,WAAW,UAAU,MAAM;AACzB,oBAAc;AACd,YAAM,GAAG,IAAI,CAAC;AAAA,IAChB,OAAO;AACL,oBAAc;AACd,cAAQ,GAAG,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,UAAaA,aAAY,QAAQ,IAAI,MAAM,aAAc,QAAO;AACrF,QAAM,KAAK,QAAQ,OAAO,SAAYA,aAAY,QAAQ,EAAE,IAAI;AAChE,QAAM,cAAc,QAAQ,gBAAgB,SAAYA,aAAY,QAAQ,WAAW,IAAI;AAC3F,MAAI,OAAO,UAAa,gBAAgB,OAAW,QAAO;AAE1D,SAAO;AAAA,IACL;AAAA,IACA,MAAM,QAAQ,SAAS,SAAYA,aAAY,QAAQ,IAAI,IAAI;AAAA,IAC/D,UAAU,QAAQ,aAAa,SAAYA,aAAY,QAAQ,QAAQ,IAAI;AAAA,IAC3E,QAAQ,QAAQ,WAAW,SAAYA,aAAY,QAAQ,MAAM,IAAI;AAAA,IACrE,GAAI,QAAQ,QAAQ,SAAY,EAAE,KAAKA,aAAY,QAAQ,GAAG,EAAE,IAAI,CAAC;AAAA,IACrE,iBAAiB,QAAQ,oBAAoB,SAAYA,aAAY,QAAQ,eAAe,IAAI;AAAA,IAChG,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAOA,aAAY,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,IAC3E,WAAW,MAAM,aAAa,CAAC;AAAA,IAC/B,SAAS,MAAM,WAAW,CAAC;AAAA,IAC3B,gBAAgB,MAAM,kBAAkB,CAAC;AAAA,IACzC,eAAe,QAAQ,kBAAkB,SAAY,OAAO,QAAQ,aAAa,KAAK,IAAI;AAAA,IAC1F;AAAA,EACF;AACF;AAiCO,IAAM,qBAAN,MAAyB;AAAA,EAG9B,YACmB,WACA,IACjB;AAFiB;AACA;AAEjB,SAAK,cAAmB,YAAK,WAAW,iBAAiB;AAAA,EAC3D;AAAA,EAJmB;AAAA,EACA;AAAA,EAJF;AAAA,EASjB,WAAW,MAAc,IAAoB;AAC3C,QAAI,CAAC,sBAAsB,IAAI,GAAG;AAChC,YAAM,IAAI,MAAM,yBAAyB,OAAO,IAAI,CAAC,8BAAyB;AAAA,IAChF;AACA,UAAM,SAAS,cAAc,EAAE;AAC/B,QAAI,WAAW,MAAM;AACnB,YAAM,IAAI,MAAM,uBAAuB,OAAO,EAAE,CAAC,yCAAoC;AAAA,IACvF;AACA,QAAI,WAAW,MAAM;AACnB,YAAM,IAAI,MAAM,eAAe,EAAE,8BAA8B,IAAI,GAAG;AAAA,IACxE;AACA,WAAY,YAAK,KAAK,aAAa,MAAM,GAAG,EAAE,KAAK;AAAA,EACrD;AAAA;AAAA,EAGA,MAAM,kBAAkB,QAAmD;AACzE,UAAM,WAAW,KAAK,WAAW,OAAO,MAAM,OAAO,EAAE;AACvD,UAAM,KAAK,oBAAoB,QAAQ;AACvC,UAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ;AAC5C,QAAI,aAAa,MAAM;AACrB,YAAM,UAAU,0BAA0B,QAAQ;AAClD,UAAI,YAAY,QAAQ,QAAQ,gBAAgB,OAAO,aAAa;AAClE,eAAO,EAAE,MAAM,UAAU,SAAS,OAAO,aAAa,OAAO,YAAY;AAAA,MAC3E;AAAA,IACF;AACA,UAAM,KAAK,GAAG,UAAU,UAAU,uBAAuB,MAAM,CAAC;AAChE,WAAO,EAAE,MAAM,UAAU,SAAS,MAAM,aAAa,OAAO,YAAY;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,kBAAkB,MAAc,IAAoC;AACxE,UAAM,WAAW,KAAK,WAAW,MAAM,EAAE;AACzC,UAAM,KAAK,oBAAoB,QAAQ;AACvC,WAAO,KAAK,QAAQ,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,iBAAiB,MAA+C;AAC5E,QAAI,CAAC,sBAAsB,IAAI,GAAG;AAChC,YAAM,IAAI,MAAM,yBAAyB,OAAO,IAAI,CAAC,8BAAyB;AAAA,IAChF;AACA,UAAM,SAAc,YAAK,KAAK,aAAa,IAAI;AAC/C,UAAM,KAAK,oBAAoB,MAAM;AACrC,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,GAAG,QAAQ,MAAM;AAAA,IACxC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,YAAM;AAAA,IACR;AACA,UAAM,YAAoC,CAAC;AAC3C,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,SAAS,KAAK,EAAG;AAC5B,YAAM,KAAK,MAAM,MAAM,GAAG,EAAE;AAC5B,UAAI,cAAc,EAAE,MAAM,KAAM;AAChC,YAAM,MAAM,MAAM,KAAK,kBAAkB,MAAM,EAAE;AACjD,UAAI,QAAQ,KAAM;AAClB,YAAM,UAAU,0BAA0B,GAAG;AAC7C,UAAI,YAAY,KAAM,WAAU,KAAK,OAAO;AAAA,IAC9C;AACA,cAAU,KAAK,CAAC,GAAG,MAAO,EAAE,WAAW,EAAE,WAAW,KAAK,EAAE,WAAW,EAAE,WAAW,IAAI,SAAS,EAAE,IAAI,EAAE,EAAE,CAAE;AAC5G,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,eAAe,MAAiC;AACpD,YAAQ,MAAM,KAAK,iBAAiB,IAAI,GAAG,IAAI,CAAC,YAAY,QAAQ,EAAE;AAAA,EACxE;AAAA;AAAA,EAGA,MAAM,qBAAqB,MAA+C;AACxE,WAAO,KAAK,iBAAiB,IAAI;AAAA,EACnC;AAAA;AAAA,EAGA,MAAM,mBAAsC;AAC1C,UAAM,KAAK,oBAAoB,KAAK,WAAW;AAC/C,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,GAAG,QAAQ,KAAK,WAAW;AAAA,IAClD,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,YAAM;AAAA,IACR;AACA,UAAM,QAAQ,QAAQ,OAAO,CAAC,UAAU,sBAAsB,KAAK,CAAC;AACpE,UAAM,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AACjD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,oBAAoB,MAAc,IAA2B;AACjE,UAAM,WAAW,KAAK,WAAW,MAAM,EAAE;AACzC,UAAM,KAAK,oBAAoB,QAAQ;AACvC,QAAI;AACF,YAAM,KAAK,GAAG,WAAW,QAAQ;AAAA,IACnC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU;AACtD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,QAAQ,UAA0C;AAC9D,QAAI;AACF,aAAO,MAAM,KAAK,GAAG,SAAS,QAAQ;AAAA,IACxC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,YAAmC;AACnE,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,KAAK,GAAG,SAAS,KAAK,SAAS;AAAA,IAClD,QAAQ;AACN,iBAAgB,eAAQ,KAAK,SAAS;AAAA,IACxC;AACA,UAAM,KAAK,eAAe,UAAU,KAAK,WAAW;AACpD,UAAM,KAAK,eAAe,UAAe,eAAQ,UAAU,CAAC;AAC5D,UAAM,KAAK,eAAe,UAAU,UAAU;AAI9C,UAAM,KAAK,iBAAiB,KAAK,aAAa,WAAW;AACzD,UAAM,SAAS,KAAK,aAAa,UAAU;AAC3C,QAAI,WAAW,KAAM,OAAM,KAAK,iBAAiB,QAAQ,WAAW;AAKpE,QAAI,WAAW,SAAS,KAAK,EAAG,OAAM,KAAK,iBAAiB,YAAY,aAAa;AAAA,EACvF;AAAA;AAAA;AAAA,EAIQ,aAAa,YAAmC;AACtD,UAAM,MAAW,gBAAS,KAAK,aAAa,UAAU;AACtD,QAAI,QAAQ,MAAM,IAAI,WAAW,IAAI,KAAU,kBAAW,GAAG,EAAG,QAAO;AACvE,UAAM,QAAQ,IAAI,MAAW,UAAG,EAAE,CAAC;AACnC,QAAI,UAAU,UAAa,MAAM,WAAW,EAAG,QAAO;AACtD,WAAY,YAAK,KAAK,aAAa,KAAK;AAAA,EAC1C;AAAA,EAEA,MAAc,iBAAiB,QAAgB,MAAkD;AAC/F,QAAIC;AACJ,QAAI;AACF,MAAAA,QAAO,MAAM,KAAK,GAAG,MAAM,MAAM;AAAA,IACnC,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU;AACtD,YAAM;AAAA,IACR;AACA,QAAIA,MAAK,gBAAgB;AACvB,YAAM,QAAa,gBAAS,KAAK,WAAW,MAAM,KAAK;AACvD,YAAM,IAAI;AAAA,QACR,YAAY,IAAI,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,UAAkB,WAAkC;AAC/E,QAAI;AACJ,QAAI;AACF,sBAAgB,MAAM,KAAK,GAAG,SAAS,SAAS;AAAA,IAClD,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,aAAa,UAAU,aAAa,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,WAAW,CAAC,GAAW,MAAuB,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;;;AChd7E,SAAS,WAAAC,gBAAe;AAExB,OAAOC,YAAU;AAWjB,eAAsB,qBACpB,QACA,aACA,aACA,WACA,sBACkB;AAClB,MAAI;AACJ,MAAI;AACF,cAAU,MAAMC,SAAQ,OAAO,gBAAgB,EAAE,eAAe,KAAK,CAAC;AAAA,EACxE,SAAS,OAAO;AACd,QAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AAEA,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,KAAK,EAAG;AACpD,UAAM,SAAS,MAAM,OAAO,iBAAiBC,OAAK,KAAK,OAAO,gBAAgB,MAAM,IAAI,CAAC;AACzF,QACE,QAAQ,YAAY,aAAa,iBAChC,OAAO,YAAY,mBAAmB,eACpC,OAAO,YAAY,mBAAmB,UAAa,OAAO,YAAY,SAAS,SAAS,WAAW,MACtG,OAAO,YAAY,SAAS,SAAS,WAAW,KAChD,sBAAsB,OAAO,OAAO,MAAM,cACzC,yBAAyB,UACxB,OAAO,QAAQ,oBAAoB,EAAE;AAAA,MACnC,CAAC,CAAC,KAAK,KAAK,MAAM,OAAO,YAAY,uBAAuB,GAAG,MAAM;AAAA,IACvE,IACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;ACaA,eAAsB,2BAA2B,SAA0D;AACzG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,MAAI;AACF,QAAI,QAAQ,wBAAwB,cAAc,IAAI,EAAG,SAAQ,4BAA4B;AAC7F,QAAI,YAAa,SAAQ,2BAA2B;AAAA,QAC/C,SAAQ,wBAAwB;AACrC,UAAM,QAAQ,qBAAqB;AACnC,YAAQ,wBAAwB;AAChC,QAAI,MAAM,qBAAqB,WAAW,OAAO,WAAW,KAAK,MAAM,EAAE;AAEzE,QAAI,cAAc,YAAY,aAAa,QAAQ;AACjD,iBAAW,SAAS;AAAA,QAClB;AAAA,UACE,IAAI;AAAA,UACJ,SAAS,yBAAyB,cAAc,SAAS,gBAAgB;AAAA,UACzE,aAAa,cAAc,YAAY;AAAA,UACvC,WAAW,UAAU;AAAA,UACrB,sBAAsB,cAAc,YAAY;AAAA,QAClD;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,UACX;AAAA,QACF;AAAA,MACF,GAAG;AACD,cAAM,aAAa,EAAE,GAAG,OAAO,cAAc,YAAY;AACzD,cAAM,SAAU,MAAM,QAAQ,kBAAkB,UAAU,KAAO,MAAM,QAAQ,kBAAkB,KAAK;AACtG,YAAI,CAAC,OAAQ,OAAM,QAAQ,gBAAgB,UAAU;AAAA,MACvD;AAAA,IACF;AAEA,UAAM,YAAY,eAAe,QAAQ,OAAO,WAAW,cAAc,OAAO;AAAA;AAAA,UAAe,MAAM;AACrG,UAAM,cAAc,MAAM;AAAA,MACxB;AAAA,QACE,gBAAgB,QAAQ;AAAA,QACxB,kBAAkB,QAAQ;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IACjB;AACA,QAAI,CAAC,aAAa;AAChB,YAAM,gBAAgB;AAAA,QACpB;AAAA,UACE,SAAS;AAAA,UACT,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,MAAM,QAAQ,OAAO,QAAQ,CAAC,gBAAgB,eAAe;AAAA,UAC7D,sBAAsB,QAAQ,OAAO;AAAA,QACvC;AAAA,QACA,EAAE,QAAQ,QAAQ,OAAO,UAAU,0BAA0B;AAAA,MAC/D;AACA,YAAM,QAAQ,kBAAkB,eAAe;AAAA,QAC7C,OAAO,QAAQ;AAAA,QACf,SAAS,CAAC,aAAa,WAAW;AAAA,QAClC,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AACA,YAAQ,2BAA2B;AACnC,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,QAAI,MAAM,wCAAwC,WAAW,KAAK,GAAG;AACrE,WAAO;AAAA,EACT;AACF;;;AClIA,SAAS,cAAAC,mBAAkB;AAGpB,IAAM,kCAAkC;AAExC,SAAS,0BAA0B,QAAgB,mBAAuD;AAC/G,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI,OAAO;AACX,QAAM,QAA6B;AAAA,IACjC,WAAW,QAAQ,WAAW,GAAG,IAAI,KAAK;AAAA,IAC1C,MAAM;AAAA,EACR;AACA,QAAM,2BAAqC,CAAC;AAC5C,MAAI,qBAAqB;AACzB,MAAI;AAEJ,MAAI,CAAC,QAAQ,WAAW,GAAG,GAAG;AAC5B,UAAM,OAAO,2BAA2B,OAAO;AAC/C,WAAO,MAAM,OAAO,QAAQ;AAAA,EAC9B;AAEA,QAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,MAAI,aAAa,IAAI;AACnB,UAAM,OAAO;AACb,WAAO,MAAM,OAAO,QAAQ;AAAA,EAC9B;AAEA,QAAM,aAAa,QAAQ,MAAM,GAAG,QAAQ,EAAE,KAAK;AACnD,QAAM,kBAAkB,KAAK,MAAM,UAAU;AAC7C,MAAI,OAAO,SAAS,eAAe,GAAG;AACpC,UAAM,YAAY,cAAc;AAChC,WAAO,QAAQ,MAAM,WAAW,CAAC,EAAE,UAAU;AAAA,EAC/C;AAEA,SAAO,KAAK,WAAW,GAAG,GAAG;AAC3B,UAAM,MAAM,2BAA2B,IAAI;AAC3C,QAAI,QAAQ,GAAI;AAChB,UAAM,aAAa,KAAK,MAAM,GAAG,MAAM,CAAC;AACxC,UAAM,QAAQ,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK;AACtC,UAAM,WAAW,KAAK,MAAM,MAAM,CAAC,EAAE,UAAU;AAC/C,QAAI,UAAU,iCAAiC;AAC7C,2BAAqB;AACrB,+BAAyB,KAAK,UAAU;AACxC,aAAO;AACP;AAAA,IACF;AACA,UAAM,YAAY,MAAM,QAAQ,GAAG;AACnC,QAAI,cAAc,IAAI;AACpB,UAAI,SAAS,SAAS;AACpB,cAAM,OAAO;AACb,eAAO,MAAM,OAAO,QAAQ;AAAA,MAC9B;AACA;AAAA,IACF;AACA,UAAM,MAAM,MAAM,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY;AACzD,UAAM,QAAQ,oCAAoC,MAAM,MAAM,YAAY,CAAC,EAAE,KAAK,CAAC;AACnF,QAAI,CAAC,MAAO;AACZ,QAAI,QAAQ,mBAAmB,CAAC,oBAAoB;AAClD,YAAM,OAAO,KAAK,KAAK;AACvB,aAAO,MAAM,OAAO,QAAQ;AAAA,IAC9B;AACA,YAAQ,KAAK;AAAA,MACX,KAAK;AACH,cAAM,SAAS;AACf;AAAA,MACF,KAAK;AACH,YACE,yBAAyB,WAAW,KACpC,CAAC,SAAS,WAAW,GAAG,KACxB,SAAS,SAAS,KAClB,CAAC,8BAA8B,KAAK,GACpC;AACA,uCAA6B;AAC7B,iBAAO;AACP;AAAA,QACF;AACA,cAAM,SAAS;AACf;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,cAAM,aAAa;AACnB;AAAA,MACF,KAAK;AACH,cAAM,YAAY;AAClB;AAAA,MACF,KAAK;AACH,cAAM,SAAS;AACf;AAAA,MACF;AACE,cAAM,OAAO,KAAK,KAAK;AACvB,eAAO,MAAM,OAAO,QAAQ;AAAA,IAChC;AACA,QAAI,2BAA4B;AAChC,6BAAyB,KAAK,UAAU;AACxC,WAAO;AAAA,EACT;AAEA,MAAI,4BAA4B;AAC9B,WAAO;AAAA,MACL,WAAW,MAAM;AAAA,MACjB,MAAM,GAAG,0BAA0B,IAAI,IAAI,GAAG,KAAK;AAAA,IACrD;AAAA,EACF;AACA,QAAM,OAAO,2BAA2B,KAAK,KAAK,CAAC;AACnD,MAAI,CAAC,MAAM,KAAM,QAAO;AACxB,SAAO;AACT;AAEO,SAAS,yCAAyC,QAAyB;AAChF,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,QAAQ,WAAW,GAAG,EAAG,QAAO;AAErC,QAAM,WAAW,2BAA2B,OAAO;AACnD,MAAI,aAAa,GAAI,QAAO;AAE5B,QAAM,aAAa,QAAQ,MAAM,GAAG,QAAQ,EAAE,KAAK;AACnD,SAAO,iCAAiC,UAAU;AACpD;AAEO,SAAS,iCAAiC,OAAwB;AACvE,MAAI,CAAC,kCAAkC,KAAK,KAAK,EAAG,QAAO;AAC3D,SAAO,OAAO,SAAS,KAAK,MAAM,KAAK,CAAC;AAC1C;AAEO,SAAS,8BAA8B,QAAyB;AACrE,UAAQ,OAAO,KAAK,EAAE,YAAY,GAAG;AAAA,IACnC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,2BAA2B,OAAuB;AAChE,MAAI,UAAU;AACd,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,SAAS;AACX,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,MAAM;AACjB,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,IAAK,QAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAEO,SAAS,kCAAkC,OAAuB;AACvE,MAAI,UAAU;AACd,aAAW,QAAQ,OAAO;AACxB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,mBAAW;AACX;AAAA,MACF,KAAK;AACH,mBAAW;AACX;AAAA,MACF,KAAK;AACH,mBAAW;AACX;AAAA,MACF,KAAK;AACH,mBAAW;AACX;AAAA,MACF,KAAK;AACH,mBAAW;AACX;AAAA,MACF,SAAS;AACP,cAAM,YAAY,KAAK,YAAY,CAAC,KAAK;AACzC,YAAI,YAAY,IAAM;AACpB,qBAAW,MAAM,UAAU,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,QAC1D,OAAO;AACL,qBAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,oCAAoC,OAAuB;AACzE,MAAI,CAAC,MAAM,SAAS,IAAI,EAAG,QAAO;AAElC,MAAI,SAAS;AACb,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,SAAS,MAAM;AACjB,gBAAU;AACV;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,QAAI,CAAC,MAAM;AACT,gBAAU;AACV;AAAA,IACF;AAEA,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,kBAAU;AACV,iBAAS;AACT;AAAA,MACF,KAAK;AACH,kBAAU;AACV,iBAAS;AACT;AAAA,MACF,KAAK;AACH,kBAAU;AACV,iBAAS;AACT;AAAA,MACF,KAAK,KAAK;AACR,cAAM,MAAM,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAC5C,YAAI,mBAAmB,KAAK,GAAG,GAAG;AAChC,oBAAU,OAAO,aAAa,SAAS,KAAK,EAAE,CAAC;AAC/C,mBAAS;AACT;AAAA,QACF;AACA,kBAAU;AACV,iBAAS;AACT;AAAA,MACF;AAAA,MACA;AACE,kBAAU;AACV,iBAAS;AACT;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AACT;AACO,SAAS,yBAAyB,OAAuB;AAC9D,SAAO,6CAA6C,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK;AACnF;AAEO,SAAS,2BAA2B,OAAuB;AAChE,SAAO,6CAA6C,KAAK,KAAK,IAAI,MAAM,MAAM,CAAC,IAAI;AACrF;AAEO,SAAS,6BAA6B,OAAoC;AAC/E,QAAM,SAAmB,CAAC;AAC1B,MAAI,MAAM,UAAU,KAAK,EAAE,SAAS,GAAG;AACrC,WAAO,KAAK,IAAI,MAAM,SAAS,GAAG;AAAA,EACpC;AACA,MAAI,MAAM,QAAQ;AAChB,UAAM,YAAY,8BAA8B,MAAM,MAAM,IAAI,WAAW;AAC3E,WAAO,KAAK,IAAI,SAAS,IAAI,kCAAkC,MAAM,MAAM,CAAC,GAAG;AAAA,EACjF;AACA,MAAI,MAAM,YAAY;AACpB,WAAO,KAAK,YAAY,kCAAkC,MAAM,UAAU,CAAC,GAAG;AAAA,EAChF;AACA,MAAI,MAAM,WAAW;AACnB,WAAO,KAAK,cAAc,kCAAkC,MAAM,SAAS,CAAC,GAAG;AAAA,EACjF;AACA,MAAI,MAAM,QAAQ;AAChB,WAAO,KAAK,IAAI,+BAA+B,GAAG;AAClD,WAAO,KAAK,kBAAkB,kCAAkC,MAAM,MAAM,CAAC,GAAG;AAAA,EAClF;AACA,QAAM,qBAAqB,OAAO,SAAS,IAAI,GAAG,OAAO,KAAK,GAAG,CAAC,MAAM;AACxE,SAAO,KAAK,kBAAkB,GAAG,yBAAyB,MAAM,IAAI,CAAC,GAAG,QAAQ;AAClF;AAEO,SAAS,0BAA0B,UAA2C;AACnF,SAAO,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,CAAC,UAAU,MAAM,KAAK,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC,CAAC,CAAC;AACpG;AAEO,SAAS,2BAA2B,OAAuB;AAChE,SAAO,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACzC;AAEO,SAAS,2CACd,OACA,aACA,eACwD;AACxD,QAAM,kBAA4B,CAAC;AACnC,QAAM,UAAqC,CAAC;AAC5C,QAAM,OAAO,oBAAI,IAAoB;AACrC,aAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,UAAM,aAAa,2BAA2B,IAAI;AAClD,QAAI,CAAC,WAAY;AACjB,UAAM,gBAAgB,KAAK,IAAI,UAAU,KAAK;AAC9C,UAAM,SAAS,cAAc,KAAK,KAAK;AACvC,QAAI,iBAAiB,GAAG;AACtB,UAAI,QAAQ,aAAa,MAAM,OAAQ,SAAQ,aAAa,IAAI;AAChE;AAAA,IACF;AACA,SAAK,IAAI,YAAY,gBAAgB,MAAM;AAC3C,oBAAgB,KAAK,UAAU;AAC/B,YAAQ,KAAK,MAAM;AAAA,EACrB;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,GAAI,QAAQ,KAAK,CAAC,WAAW,WAAW,MAAS,IAAI,EAAE,aAAa,QAAQ,IAAI,CAAC;AAAA,EACnF;AACF;AACO,SAAS,gCAAgC,OAA2B;AACzE,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,2BAA2B,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC;AAC7G;AAEO,SAAS,8BAA8B,oBAAyD;AACrG,QAAM,QAAkB,CAAC;AACzB,aAAW,WAAW,oBAAoB;AACxC,eAAW,QAAQ,QAAQ,OAAO;AAChC,YAAM,aAAa,2BAA2B,IAAI;AAClD,UAAI,CAAC,WAAY;AACjB,YAAM,KAAK,UAAU;AAAA,IACvB;AAAA,EACF;AACA,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;AAC3B;AAEO,SAAS,mBACd,UACA,oBACU;AACV,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,0BAA0B,QAAQ,GAAG;AACtD,QAAI,KAAK,IAAI,IAAI,EAAG;AACpB,SAAK,IAAI,IAAI;AACb,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,aAAW,QAAQ,8BAA8B,kBAAkB,GAAG;AACpE,QAAI,KAAK,IAAI,IAAI,EAAG;AACpB,SAAK,IAAI,IAAI;AACb,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AAEA,SAAS,kCACP,OACwD;AACxD,QAAM,QAAkB,CAAC;AACzB,QAAM,cAAyC,CAAC;AAChD,MAAI,eAAyB,CAAC;AAC9B,MAAI;AAEJ,QAAM,oBAAoB,MAAY;AACpC,UAAM,aAAa,2BAA2B,aAAa,KAAK,GAAG,CAAC;AACpE,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,KAAK,UAAU;AACrB,kBAAY,KAAK,aAAa;AAAA,IAChC;AACA,mBAAe,CAAC;AAChB,oBAAgB;AAAA,EAClB;AAEA,aAAW,WAAW,OAAO;AAC3B,UAAM,OAAO,QAAQ,KAAK;AAC1B,QAAI,CAAC,MAAM;AACT,wBAAkB;AAClB;AAAA,IACF;AACA,QAAI,KAAK,WAAW,IAAI,GAAG;AACzB,wBAAkB;AAClB,YAAM,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK;AAClC,YAAM,iBAAiB,IAAI,+BAA+B;AAC1D,YAAM,YAAY,OAAO,WAAW,cAAc;AAClD,YAAM,cAAc,eAAe;AACnC,YAAM,eAAe,aAAa,OAAO,WAAW,mBAAmB,WAAW;AAClF,YAAM,kBAAkB,eACpB,2BAA2B,OAAO,MAAM,WAAW,CAAC,IACpD;AACJ,YAAM,YAAY,mBAAmB,IAAI,kBAAkB,cAAc;AACzE,YAAM,QAAQ,aAAa,IAAI,OAAO,MAAM,cAAc,IAAI,SAAS,IAAI;AAC3E,qBAAe,CAAC,aAAa,IACzB,2BAA2B,OAAO,MAAM,YAAY,CAAC,EAAE,UAAU,CAAC,IAClE,2BAA2B,YAAY,OAAO,MAAM,eAAe,MAAM,IAAI,MAAM,CAAC;AACxF,sBAAgB,aAAa,IACzB,oCAAoC,KAAK,IACzC;AACJ;AAAA,IACF;AACA,iBAAa,KAAK,IAAI;AAAA,EACxB;AACA,oBAAkB;AAClB,SAAO,2CAA2C,OAAO,WAAW;AACtE;AACA,SAAS,mCAAmC,OAA0B;AACpE,QAAM,gBAAgB,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC,GAAG,KAAK,KAAK;AAC9E,SAAO,cAAc,WAAW,IAAI;AACtC;AAEO,SAAS,kCACd,YACA,eACA,eAIA;AACA,QAAM,qBAAgD,CAAC;AACvD,QAAM,yBAAoE,CAAC;AAC3E,QAAM,yBAAyB,oBAAI,IAAqC;AAExE,aAAW,WAAW,eAAe;AACnC,UAAM,iBAAiB,yBAAyB,YAAY,QAAQ,OAAO,aAAa;AACxF,QAAI,CAAC,kBAAkB,CAAC,mCAAmC,QAAQ,KAAK,GAAG;AACzE,6BAAuB,KAAK,OAAO;AACnC;AAAA,IACF;AACA,UAAM,cAAc,kCAAkC,QAAQ,KAAK;AACnE,QAAI,CAAC,kBAAkB,YAAY,MAAM,WAAW,GAAG;AACrD,6BAAuB,KAAK,OAAO;AACnC;AAAA,IACF;AACA,UAAM,oBAAoB,iBACtB,EAAE,KAAK,eAAe,KAAK,OAAO,eAAe,MAAM,IACvD,iCAAiC,YAAY,EAAE,KAAK,QAAQ,OAAO,OAAO,QAAQ,MAAM,GAAG,aAAa;AAC5G,QAAI,YAAY,MAAM,WAAW,GAAG;AAClC,6BAAuB,KAAK,OAAO;AACnC;AAAA,IACF;AACA,UAAM,WAAW,uBAAuB,IAAI,kBAAkB,GAAG;AACjE,QAAI,UAAU;AACZ,YAAM,kBAAkB,SAAS,MAAM,IAAI,CAAC,GAAG,UAAU,SAAS,cAAc,KAAK,CAAC;AACtF,YAAM,kBAAkB,YAAY,MAAM,IAAI,CAAC,GAAG,UAAU,YAAY,cAAc,KAAK,CAAC;AAC5F,YAAM,SAAS;AAAA,QACb,CAAC,GAAG,SAAS,OAAO,GAAG,YAAY,KAAK;AAAA,QACxC,CAAC,GAAG,iBAAiB,GAAG,eAAe;AAAA,MACzC;AACA,eAAS,QAAQ,OAAO;AACxB,eAAS,cAAc,OAAO;AAC9B;AAAA,IACF;AACA,UAAM,oBAA6C;AAAA,MACjD,KAAK,kBAAkB;AAAA,MACvB,OAAO,kBAAkB;AAAA,MACzB,OAAO,YAAY;AAAA,MACnB,GAAI,YAAY,cAAc,EAAE,aAAa,YAAY,YAAY,IAAI,CAAC;AAAA,IAC5E;AACA,uBAAmB,KAAK,iBAAiB;AACzC,2BAAuB,IAAI,kBAAkB,KAAK,iBAAiB;AAAA,EACrE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,8BAA8B,QAAwC;AACpF,MAAI;AACJ,aAAW,SAAS,OAAO,UAAU;AACnC,UAAM,YAAY,MAAM,UAAU,KAAK;AACvC,QAAI,CAAC,UAAW;AAChB,QAAI,CAAC,aAAa,wBAAwB,WAAW,SAAS,IAAI,GAAG;AACnE,kBAAY;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,wBAAwB,MAAe,OAAwB;AAC7E,QAAM,YAAY,MAAM,KAAK,KAAK;AAClC,QAAM,aAAa,OAAO,KAAK,KAAK;AAEpC,MAAI,CAAC,aAAa,CAAC,WAAY,QAAO;AACtC,MAAI,CAAC,UAAW,QAAO;AACvB,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,SAAS,KAAK,MAAM,SAAS;AACnC,QAAM,UAAU,KAAK,MAAM,UAAU;AACrC,QAAM,aAAa,OAAO,SAAS,MAAM;AACzC,QAAM,cAAc,OAAO,SAAS,OAAO;AAE3C,MAAI,cAAc,aAAa;AAC7B,QAAI,WAAW,QAAS,QAAO;AAC/B,WAAO,SAAS,UAAU,IAAI;AAAA,EAChC;AACA,MAAI,WAAY,QAAO;AACvB,MAAI,YAAa,QAAO;AACxB,SAAO,UAAU,cAAc,UAAU;AAC3C;AAEO,SAAS,2BAA2B,QAA4B;AACrE,UAAQ,OAAO,sBAAsB,CAAC,GAAG,OAAO,CAAC,OAAO,YAAY,QAAQ,QAAQ,MAAM,QAAQ,CAAC;AACrG;AAEO,SAAS,iCAAiC,QAAoE;AACnH,QAAM,sBAAsB,OAAO,sBAAsB,CAAC,GACvD,IAAI,CAAC,aAAa;AAAA,IACjB,KAAK,QAAQ,IAAI,KAAK,EAAE,YAAY;AAAA,IACpC,OAAO,QAAQ,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAAA,IAC/C,OAAO,gCAAgC,QAAQ,KAAK,EACjD,MAAM,EACN,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AAAA,EACpD,EAAE,EACD,OAAO,CAAC,YAAY,QAAQ,MAAM,SAAS,CAAC,EAC5C;AAAA,IACC,CAAC,MAAM,UACL,KAAK,IAAI,cAAc,MAAM,GAAG,KAChC,KAAK,MAAM,cAAc,MAAM,KAAK,KACpC,KAAK,MAAM,KAAK,IAAI,EAAE,cAAc,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAC9D;AACF,MAAI,mBAAmB,WAAW,EAAG,QAAO;AAC5C,SAAOC,YAAW,QAAQ,EAAE,OAAO,KAAK,UAAU,kBAAkB,CAAC,EAAE,OAAO,KAAK;AACrF;AAEO,SAAS,uBAAuB,QAA6B;AAClE,QAAM,sBAAsB,2BAA2B,MAAM;AAC7D,QAAM,uBAAuB,iCAAiC,MAAM;AACpE,QAAM,6BAA6B,OAAO,+BAA+B,KAAK,KAAK;AACnF,MAAI,OAAO,SAAS,WAAW,KAAK,wBAAwB,EAAG,QAAO;AACtE,MAAI,CAAC,OAAO,WAAW,KAAK,EAAG,QAAO;AACtC,MAAI,OAAO,2BAA2B,OAAW,QAAO;AACxD,MAAI,sBAAsB,KAAK,OAAO,iCAAiC,OAAW,QAAO;AACzF,MAAI,sBAAsB,KAAK,CAAC,2BAA4B,QAAO;AACnE,QAAM,0BAA0B,8BAA8B,MAAM;AACpE,MAAI,CAAC,yBAAyB;AAC5B,WACE,OAAO,SAAS,SAAS,OAAO,0BAChC,uBAAuB,OAAO,gCAAgC,MAC9D,yBAAyB;AAAA,EAE7B;AACA,MAAI,CAAC,OAAO,oBAAoB,KAAK,EAAG,QAAO;AAC/C,QAAM,oBAAoB,wBAAwB,yBAAyB,OAAO,kBAAkB;AACpG,MAAI,oBAAoB,EAAG,QAAO;AAClC,SACE,OAAO,SAAS,SAAS,OAAO,0BAChC,uBAAuB,OAAO,gCAAgC,MAC9D,yBAAyB;AAE7B;;;A7B7QA,SAAS,yBAAyB,OAAiC,OAAqB;AACtF,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,IAAI,MAAM,GAAG,KAAK,iCAAiC,OAAO,KAAK,CAAC,EAAE;AAAA,EAC1E;AACA,MAAI,CAAC,OAAO,UAAU,KAAK,GAAG;AAC5B,UAAM,IAAI,MAAM,GAAG,KAAK,4BAA4B,KAAK,EAAE;AAAA,EAC7D;AACA,MAAI,QAAQ,GAAG;AACb,UAAM,IAAI,MAAM,GAAG,KAAK,sBAAsB,KAAK,EAAE;AAAA,EACvD;AACF;AAEA,SAAS,8BAA8B,OAAe,OAA+C;AACnG,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,MAAM,GAAG,KAAK,yCAAyC,OAAO,KAAK,CAAC,EAAE;AAAA,EAClF;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,SAAS,0BAA0B,OAAO;AAChD,MAAI,WAAW,MAAM;AACnB,UAAM,IAAI,MAAM,GAAG,KAAK,uCAAuC,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,EACxF;AACA,SAAO,IAAI,KAAK,MAAM,EAAE,YAAY;AACtC;AAEA,SAAS,qBAAqB,IAA+B;AAC3D,4BAA0B,EAAE;AAC5B,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,OAAO,GAAG,EAAE;AAAA,IACZ,aAAa,GAAG,QAAQ;AAAA,IACxB,YAAY,GAAG,OAAO;AAAA,IACtB,YAAY,GAAG,OAAO;AAAA,IACtB,WAAW,GAAG,MAAM;AAAA,IACpB,eAAe,GAAG,UAAU;AAAA,IAC5B,mBAAmB,GAAG,cAAc;AAAA,IACpC,UAAU,GAAG,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,EACnD;AAEA,MAAI,GAAG,SAAU,OAAM,KAAK,aAAa,GAAG,QAAQ,EAAE;AACtD,MAAI,GAAG,SAAS,OAAW,OAAM,KAAK,SAAS,GAAG,IAAI,EAAE;AACxD,MAAI,GAAG,OAAQ,OAAM,KAAK,WAAW,sBAAsB,KAAK,GAAG,MAAM,IAAI,GAAG,SAAS,KAAK,UAAU,GAAG,MAAM,CAAC,EAAE;AACpH,MAAI,GAAG,QAAS,OAAM,KAAK,YAAY,GAAG,OAAO,EAAE;AACnD,MAAI,GAAG,UAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AACzD,MAAI,GAAG,iBAAiB;AAKtB,UAAM,OAAO,+BAA+B,KAAK,GAAG,eAAe;AACnE,UAAM,KAAK,oBAAoB,OAAO,GAAG,kBAAkB,KAAK,UAAU,GAAG,eAAe,CAAC,EAAE;AAAA,EACjG;AACA,MAAI,GAAG,eAAe,KAAM,OAAM,KAAK,kBAAkB;AACzD,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC5D,MAAI,GAAG,UAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AACzD,MAAI,GAAG,WAAW,GAAG,QAAQ,SAAS,GAAG;AACvC,UAAM,KAAK,aAAa,GAAG,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;AAAA,EACvE;AAEA,MAAI,GAAG,UAAU,GAAG,WAAW,SAAU,OAAM,KAAK,WAAW,GAAG,MAAM,EAAE;AAI1E,MAAI,GAAG,UAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AACzD,MAAI,GAAG,mBAAoB,OAAM,KAAK,uBAAuB,GAAG,kBAAkB,EAAE;AACpF,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAClE,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAClE,MAAI,GAAG,mBAAmB;AACxB,QAAI,GAAG,sBAAsB,YAAY,GAAG,sBAAsB,cAAc;AAC9E,YAAM,IAAI;AAAA,QACR,mDAAmD,KAAK,UAAU,GAAG,iBAAiB,CAAC;AAAA,MACzF;AAAA,IACF;AACA,UAAM,KAAK,sBAAsB,GAAG,iBAAiB,EAAE;AAAA,EACzD;AACA,MAAI,GAAG,cAAe,OAAM,KAAK,kBAAkB,GAAG,aAAa,EAAE;AACrE,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAG5D,MAAI,GAAG,SAAU,OAAM,KAAK,YAAY,GAAG,QAAQ,EAAE;AACrD,MAAI,GAAG,WAAY,OAAM,KAAK,cAAc,GAAG,UAAU,EAAE;AAK3D,MAAI,GAAG,YAAY;AACjB,UAAM,YAAY,8BAA8B,cAAc,GAAG,UAAU;AAC3E,QAAI,UAAW,OAAM,KAAK,eAAe,SAAS,EAAE;AAAA,EACtD;AACA,MAAI,GAAG,iBAAiB;AACtB,QAAI,GAAG,oBAAoB,eAAe,GAAG,oBAAoB,WAAW;AAC1E,YAAM,IAAI;AAAA,QACR,iDAAiD,KAAK,UAAU,GAAG,eAAe,CAAC;AAAA,MACrF;AAAA,IACF;AACA,UAAM,KAAK,oBAAoB,GAAG,eAAe,EAAE;AAAA,EACrD;AACA,MAAI,GAAG,YAAa,OAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAC/D,MAAI,GAAG,gBAAiB,OAAM,KAAK,oBAAoB,KAAK,UAAU,GAAG,eAAe,CAAC,EAAE;AAE3F,MAAI,GAAG,eAAgB,OAAM,KAAK,mBAAmB,GAAG,cAAc,EAAE;AACxE,MAAI,GAAG,kBAAmB,OAAM,KAAK,sBAAsB,GAAG,iBAAiB,EAAE;AACjF,MAAI,GAAG,YAAa,OAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAC/D,MAAI,GAAG,gBAAiB,OAAM,KAAK,oBAAoB,GAAG,eAAe,EAAE;AAC3E,MAAI,GAAG,eAAe,OAAW,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC1E,MAAI,GAAG,cAAc,OAAW,OAAM,KAAK,cAAc,GAAG,SAAS,EAAE;AAEvE,MAAI,GAAG,gBAAgB,UAAa,GAAG,cAAc,GAAG;AACtD,UAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAAA,EAC7C;AACA,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAKlE,MAAI,GAAG,eAAe,QAAW;AAC/B,6BAAyB,cAAc,GAAG,UAAU;AACpD,UAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAAA,EAC3C;AACA,MAAI,GAAG,YAAY,QAAW;AAC5B,6BAAyB,WAAW,GAAG,OAAO;AAC9C,UAAM,KAAK,YAAY,GAAG,OAAO,EAAE;AAAA,EACrC;AACA,QAAM,KAAK,GAAG,yBAAyB,EAAE,CAAC;AAE1C,MAAI,GAAG,YAAY;AACjB,UAAM,KAAK,oBAAoB,GAAG,WAAW,KAAK,EAAE;AACpD,UAAM,KAAK,oBAAoB,GAAG,WAAW,KAAK,EAAE;AACpD,QAAI,GAAG,WAAW,QAAQ,SAAS,GAAG;AACpC,YAAM;AAAA,QACJ,uBAAuB,GAAG,WAAW,QAClC,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC,GAAG,EAC/D,KAAK,IAAI,CAAC;AAAA,MACf;AAAA,IACF;AACA,QAAI,GAAG,WAAW,SAAS,SAAS,GAAG;AACrC,YAAM,KAAK,wBAAwB,GAAG,WAAW,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;AAAA,IAC9F;AAAA,EACF;AAEA,MAAI,GAAG,SAAU,OAAM,KAAK,aAAa,GAAG,QAAQ,EAAE;AACtD,MAAI,GAAG,eAAe,OAAW,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC1E,MAAI,GAAG,eAAe,OAAW,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAE1E,MAAI,GAAG,SAAS,GAAG,MAAM,SAAS,GAAG;AACnC,UAAM,KAAK,QAAQ;AACnB,eAAW,QAAQ,GAAG,OAAO;AAC3B,YAAM,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAC3C,YAAM,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAC3C,YAAM,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAC3C,UAAI,KAAK,OAAQ,OAAM,KAAK,eAAe,KAAK,UAAU,KAAK,MAAM,CAAC,EAAE;AAAA,IAC1E;AAAA,EACF;AACA,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAC5D,MAAI,GAAG,iBAAkB,OAAM,KAAK,qBAAqB,GAAG,gBAAgB,EAAE;AAC9E,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;AAC3D,UAAM,KAAK,uBAAuB,GAAG,kBAAkB,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG;AAAA,EAC3F;AACA,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAClE,MAAI,GAAG,eAAgB,OAAM,KAAK,mBAAmB,GAAG,cAAc,EAAE;AACxE,MAAI,GAAG,aAAc,OAAM,KAAK,iBAAiB,GAAG,YAAY,EAAE;AAElE,MAAI,GAAG,WAAY,OAAM,KAAK,eAAe,GAAG,UAAU,EAAE;AAE5D,MAAI,GAAG,wBAAwB,OAAO,KAAK,GAAG,oBAAoB,EAAE,SAAS,GAAG;AAC9E,UAAM,KAAK,yBAAyB,KAAK,UAAU,GAAG,oBAAoB,CAAC,EAAE;AAAA,EAC/E;AAEA,MAAI,GAAG,YAAa,OAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAI/D,MAAI,GAAG,iBAAiB,QAAW;AACjC,QAAI,CAAC,MAAM,QAAQ,GAAG,YAAY,GAAG;AACnC,YAAM,IAAI,MAAM,mFAAmF;AAAA,IACrG;AACA,eAAW,SAAS,GAAG,cAAc;AACnC,UAAI,CAAC,wBAAwB,KAAK,GAAG;AACnC,cAAM,IAAI;AAAA,UACR,oDAAoD,KAAK,UAAU,KAAK,CAAC;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AACA,QAAI,GAAG,aAAa,SAAS,GAAG;AAC9B,YAAM;AAAA,QACJ,kBAAkB,GAAG,aAAa,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,MAC/G;AAAA,IACF;AAAA,EACF;AACA,MAAI,GAAG,gBAAgB,QAAW;AAChC,QAAI,CAAC,wBAAwB,GAAG,WAAW,GAAG;AAC5C,YAAM,IAAI;AAAA,QACR,6CAA6C,KAAK,UAAU,GAAG,WAAW,CAAC;AAAA,MAC7E;AAAA,IACF;AACA,UAAM,KAAK,gBAAgB,GAAG,WAAW,EAAE;AAAA,EAC7C;AAIA,MAAI,GAAG,wBAAwB,QAAW;AACxC,QAAI,CAAC,OAAO,UAAU,GAAG,mBAAmB,KAAK,GAAG,uBAAuB,GAAG;AAC5E,YAAM,IAAI;AAAA,QACR,6EAA6E,KAAK,UAAU,GAAG,mBAAmB,CAAC;AAAA,MACrH;AAAA,IACF;AACA,UAAM,KAAK,wBAAwB,GAAG,mBAAmB,EAAE;AAAA,EAC7D;AACA,MAAI,GAAG,oBAAoB;AACzB,UAAM,KAAK,uBAAuB,GAAG,kBAAkB,EAAE;AAAA,EAC3D;AACA,4BAA0B,IAAI,KAAK;AACnC,8BAA4B,IAAI,KAAK;AACrC,QAAM,KAAK,KAAK;AAChB,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,0BAA0B,KAA6D;AAC9F,MAAI,CAAC,OAAO,CAAC,IAAI,KAAK,EAAG,QAAO;AAChC,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC3E,YAAM,SAAiC,CAAC;AACxC,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,YAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAClD,iBAAO,CAAC,IAAI;AAAA,QACd;AAAA,MACF;AACA,aAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AAAA,IACnD;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,UAA0B;AACtD,QAAM,cAAc,SAAS,QAAQ,QAAQ,GAAG;AAChD,QAAM,sBACJ,CAAC,SAAS,SAAS,MAAM,MACxB,qDAAqD,KAAK,QAAQ,KACjE,uCAAuC,KAAK,QAAQ;AAExD,MAAI,qBAAqB;AACvB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,IAAI,QAAQ,GAAG;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,4BAA4B,UAAkD;AAC5F,MAAI,aAAa,OAAW,QAAO;AACnC,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AACpD,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,OAAO;AACjC,aAAO,OAAO,WAAW,WAAW,SAAS;AAAA,IAC/C,QAAQ;AACN,aAAO,QAAQ,MAAM,GAAG,EAAE,EAAE,QAAQ,QAAQ,GAAG;AAAA,IACjD;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,iBAAiB,KAAiC;AACzD,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,SAAS,GAAG,EAAG,QAAO;AAC/D,SAAO,QAAQ,MAAM,GAAG,EAAE;AAC5B;AAEA,SAAS,kBAAkB,KAAuB;AAChD,QAAM,QAAQ,iBAAiB,GAAG;AAClC,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,QAAM,SAAmB,CAAC;AAC1B,MAAI,IAAI;AACR,SAAO,IAAI,MAAM,QAAQ;AACvB,WAAO,IAAI,MAAM,UAAU,MAAM,CAAC,MAAM,IAAK;AAC7C,QAAI,KAAK,MAAM,OAAQ;AACvB;AACA,QAAI,QAAQ;AACZ,WAAO,IAAI,MAAM,QAAQ;AACvB,YAAM,KAAK,MAAM,GAAG;AACpB,UAAI,OAAO,QAAQ,IAAI,MAAM,OAAQ,UAAS,KAAK,MAAM,GAAG;AAAA,eACnD,OAAO,KAAK;AACnB,eAAO,KAAK,KAAK;AACjB;AAAA,MACF,MAAO,UAAS;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,6BAA6B,KAA6C;AACjF,MAAI,QAAQ,OAAW,QAAO;AAC9B,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,IAAI,OAAO,OAAO;AACxB,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,EAAG,QAAO;AACjE,SAAO;AACT;AASA,SAAS,6BAA6B,KAA6C;AACjF,MAAI,QAAQ,OAAW,QAAO;AAC9B,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,IAAI,OAAO,OAAO;AACxB,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,KAAK,KAAK,EAAG,QAAO;AAClE,SAAO;AACT;AAEO,SAAS,iBAAiB,KAAyE;AACxG,QAAM,QAAQ,IAAI,MAAM,kDAAkD;AAC1E,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,UAAU,MAAM,CAAC;AACvB,QAAM,UAAU,MAAM,CAAC,EAAE,KAAK;AAC9B,QAAM,KAA6B,CAAC;AAapC,QAAM,WAAW,QAAQ,MAAM,IAAI;AACnC,QAAM,QAAkB,CAAC;AACzB,MAAI,IAAI;AACR,SAAO,IAAI,SAAS,QAAQ;AAC1B,UAAM,OAAO,SAAS,CAAC;AACvB,UAAM,WAAW,KAAK,QAAQ,GAAG;AACjC,QAAI,aAAa,MAAM,KAAK,MAAM,WAAW,CAAC,EAAE,KAAK,MAAM,IAAI;AAC7D,YAAM,aAAa,KAAK,MAAM,MAAM,EAAG,CAAC,EAAE;AAC1C,YAAM,QAAkB,CAAC;AACzB,UAAI,IAAI,IAAI;AACZ,aAAO,IAAI,SAAS,QAAQ;AAC1B,cAAM,OAAO,SAAS,CAAC;AACvB,cAAM,IAAI,KAAK,MAAM,eAAe;AACpC,YAAI,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,WAAY;AAKrC,YAAI,OAAO,EAAE,CAAC,EAAE,KAAK;AACrB,YAAI,KAAK,WAAW,GAAG,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,UAAU,GAAG;AAClE,iBAAO,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,QAAQ,GAAG,EAAE,QAAQ,SAAS,IAAI;AAAA,QACrE,WAAW,KAAK,WAAW,GAAG,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,UAAU,GAAG;AACzE,iBAAO,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,OAAO,GAAG;AAAA,QAC7C;AACA,cAAM,KAAK,IAAI;AACf;AAAA,MACF;AACA,UAAI,MAAM,SAAS,GAAG;AACpB,cAAM,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI;AAC/F,cAAM,KAAK,GAAG,KAAK,MAAM,GAAG,WAAW,CAAC,CAAC,KAAK,MAAM,GAAG;AACvD,YAAI;AACJ;AAAA,MACF;AAAA,IACF;AACA,UAAM,KAAK,IAAI;AACf;AAAA,EACF;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,KAAK,QAAQ,GAAG;AACjC,QAAI,aAAa,GAAI;AACrB,UAAM,MAAM,KAAK,MAAM,GAAG,QAAQ,EAAE,KAAK;AACzC,UAAM,QAAQ,KAAK,MAAM,WAAW,CAAC,EAAE,KAAK;AAC5C,OAAG,GAAG,IAAI;AAAA,EACZ;AAEA,MAAI,OAAiB,CAAC;AACtB,QAAM,UAAU,GAAG,QAAQ;AAC3B,QAAM,WAAW,iBAAiB,OAAO;AACzC,MAAI,aAAa,QAAW;AAC1B,WAAO,SACJ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,EACnB;AAEA,MAAI;AACJ,QAAM,uBAAuB,GAAG,qBAAqB;AACrD,QAAM,yBAAyB,iBAAiB,oBAAoB;AACpE,MAAI,2BAA2B,QAAW;AACxC,wBAAoB,uBACjB,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,EACnB;AAEA,QAAM,OAAO,WAAW,GAAG,cAAc,KAAK;AAG9C,MAAI;AACJ,QAAM,aAAa,GAAG,WAAW;AACjC,QAAM,eAAe,iBAAiB,UAAU;AAChD,MAAI,iBAAiB,QAAW;AAC9B,cAAU,aACP,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,EACnB;AAeA,MAAI;AACJ,QAAM,kBAAkB,GAAG,gBAAgB,IAAI,KAAK;AACpD,MAAI,eAAe,WAAW,GAAG,KAAK,eAAe,SAAS,GAAG,GAAG;AAClE,UAAM,QAAQ,eAAe,MAAM,GAAG,EAAE;AACxC,UAAM,UAAoB,CAAC;AAQ3B,QAAIC,KAAI;AACR,WAAOA,KAAI,MAAM,QAAQ;AACvB,YAAM,KAAK,MAAMA,EAAC;AAClB,UAAI,OAAO,KAAK;AACd,YAAI,MAAM;AACV,QAAAA;AACA,eAAOA,KAAI,MAAM,QAAQ;AACvB,gBAAM,IAAI,MAAMA,EAAC;AACjB,cAAI,MAAM,QAAQA,KAAI,IAAI,MAAM,QAAQ;AACtC,kBAAM,OAAO,MAAMA,KAAI,CAAC;AACxB,gBAAI,SAAS,KAAK;AAChB,qBAAO;AACP,cAAAA,MAAK;AACL;AAAA,YACF;AACA,gBAAI,SAAS,MAAM;AACjB,qBAAO;AACP,cAAAA,MAAK;AACL;AAAA,YACF;AACA,mBAAO;AACP,YAAAA;AACA;AAAA,UACF;AACA,cAAI,MAAM,KAAK;AACb,YAAAA;AACA;AAAA,UACF;AACA,iBAAO;AACP,UAAAA;AAAA,QACF;AACA,YAAI,IAAI,SAAS,EAAG,SAAQ,KAAK,GAAG;AAAA,MACtC,WAAW,OAAO,KAAK;AACrB,YAAI,MAAM;AACV,QAAAA;AACA,eAAOA,KAAI,MAAM,QAAQ;AACvB,gBAAM,IAAI,MAAMA,EAAC;AACjB,cAAI,MAAM,KAAK;AAEb,gBAAIA,KAAI,IAAI,MAAM,UAAU,MAAMA,KAAI,CAAC,MAAM,KAAK;AAChD,qBAAO;AACP,cAAAA,MAAK;AACL;AAAA,YACF;AACA,YAAAA;AACA;AAAA,UACF;AACA,iBAAO;AACP,UAAAA;AAAA,QACF;AACA,YAAI,IAAI,SAAS,EAAG,SAAQ,KAAK,GAAG;AAAA,MACtC,WAAW,OAAO,OAAO,KAAK,KAAK,EAAE,GAAG;AAEtC,QAAAA;AAAA,MACF,OAAO;AAIL,YAAI,MAAM;AACV,eAAOA,KAAI,MAAM,QAAQ;AACvB,gBAAM,IAAI,MAAMA,EAAC;AACjB,cAAI,MAAM,OAAO,KAAK,KAAK,CAAC,EAAG;AAC/B,iBAAO;AACP,UAAAA;AAAA,QACF;AACA,YAAI,IAAI,SAAS,EAAG,SAAQ,KAAK,GAAG;AAAA,MACtC;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,EAAG,gBAAe;AAAA,EACzC;AAKA,QAAM,iBAAiB,GAAG,eAAe,IAAI,KAAK;AAClD,QAAM,qBACH,cAAc,WAAW,GAAG,KAAK,cAAc,SAAS,GAAG,KAC3D,cAAc,WAAW,GAAG,KAAK,cAAc,SAAS,GAAG,IACxD,cAAc,MAAM,GAAG,EAAE,IACzB;AACN,QAAM,cAAc,wBAAwB,kBAAkB,IAAI,qBAAqB;AAGvF,QAAM,cAAc,GAAG,cAAc,SAAS,GAAG,aAAa,EAAE,IAAI;AACpE,QAAM,aAAa,GAAG,eAAe,SAAY,WAAW,GAAG,UAAU,IAAI;AAC7E,QAAM,YAAY,GAAG,cAAc,SAAY,WAAW,GAAG,SAAS,IAAI;AAM1E,QAAM,aAAa,6BAA6B,GAAG,UAAU;AAC7D,QAAM,UAAU,6BAA6B,GAAG,OAAO;AAGvD,MAAI;AACJ,MAAI,GAAG,iBAAiB;AACtB,UAAM,QAAQ,WAAW,GAAG,eAAe;AAC3C,UAAM,QAAS,GAAG,mBAAuC;AAGzD,QAAI,UAAoB,CAAC;AACzB,UAAM,aAAa,GAAG,qBAAqB;AAC3C,QAAI,WAAW,KAAK,EAAE,WAAW,GAAG,KAAK,WAAW,KAAK,EAAE,SAAS,GAAG,GAAG;AACxE,iBAAW,aAAa,kBAAkB,UAAU,GAAG;AACrD,cAAM,SAAS,qBAAqB,SAAS;AAC7C,YAAI,OAAO,SAAS,EAAG,SAAQ,KAAK,MAAM;AAAA,MAC5C;AAAA,IACF;AAGA,QAAI,WAAqB,CAAC;AAC1B,UAAM,cAAc,GAAG,sBAAsB;AAC7C,UAAM,gBAAgB,iBAAiB,WAAW;AAClD,QAAI,kBAAkB,QAAW;AAC/B,iBAAW,cACR,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,UAAU,EAAE,CAAC,EACzC,OAAO,OAAO;AAAA,IACnB;AAEA,iBAAa,EAAE,OAAO,OAAO,SAAS,SAAS;AAAA,EACjD;AAEA,QAAM,SAA8D;AAAA,IAClE,aAAa;AAAA,MACX,IAAI,GAAG,MAAM;AAAA,MACb,UAAW,GAAG,YAAY;AAAA,MAC1B,SAAS,GAAG,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC9C,UAAU,GAAG,YAAY;AAAA,MACzB,MAAM,4BAA4B,GAAG,IAAI;AAAA,MACzC,SAAS,GAAG,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC9C,QAAQ,GAAG,UAAU;AAAA,MACrB,YAAY;AAAA,MACZ,gBAAiB,GAAG,kBAAqC,eAAe,IAAI;AAAA,MAC5E;AAAA,MACA,WAAW,GAAG,aAAa;AAAA,MAC3B,QAAQ,GAAG,WAAW,SAAY,iBAAiB,iBAAiB,GAAG,MAAM,CAAC,IAAI;AAAA,MAClF,SAAS,GAAG,YAAY,UAAU,GAAG,YAAY,UAAU,GAAG,UAAU;AAAA,MACxE,iBAAiB,GAAG,kBAAkB,iBAAiB,GAAG,eAAe,KAAK,SAAY;AAAA,MAC1F,YAAY,GAAG,eAAe,SAAS,OAAO;AAAA,MAC9C,YAAY,GAAG,cAAc;AAAA,MAC7B,WAAW,GAAG,aAAa;AAAA,MAC3B,SAAS,WAAW,QAAQ,SAAS,IAAI,UAAU;AAAA;AAAA,MAEnD,QAAS,GAAG,UAA2B;AAAA;AAAA,MAEvC,WAAW,GAAG,aAAa;AAAA,MAC3B,oBACE,GAAG,uBAAuB,WAC1B,GAAG,uBAAuB,gBAC1B,GAAG,uBAAuB,WAC1B,GAAG,uBAAuB,aACtB,GAAG,qBACH;AAAA,MACN,cAAc,GAAG,gBAAgB;AAAA,MACjC,cAAc,GAAG,gBAAgB;AAAA,MACjC,YAAY,GAAG,cAAc;AAAA,MAC7B,mBACE,GAAG,sBAAsB,YAAY,GAAG,sBAAsB,eAC1D,GAAG,oBACH;AAAA,MACN,eAAe,GAAG,iBAAiB;AAAA;AAAA,MAEnC,UAAU,GAAG,WAAW;AAAA,MACxB,YAAY,GAAG,aAAa;AAAA;AAAA,MAE5B,YAAY,GAAG,cAAc;AAAA,MAC7B,iBACE,GAAG,oBAAoB,eAAe,GAAG,oBAAoB,YAAY,GAAG,kBAAkB;AAAA,MAChG,aAAa,GAAG,eAAe;AAAA,MAC/B,iBAAiB,4BAA4B,GAAG,eAAe;AAAA,MAC/D,gBAAiB,GAAG,kBAAqC;AAAA,MACzD,mBAAoB,GAAG,qBAA2C;AAAA,MAClE,aAAc,GAAG,eAA+B;AAAA,MAChD,iBAAiB,GAAG,mBAAmB;AAAA,MACvC,YAAY,OAAO,SAAS,UAAU,IAAI,aAAa;AAAA,MACvD,WAAW,OAAO,SAAS,SAAS,IAAI,YAAY;AAAA;AAAA,MAEpD,aAAa,eAAe,cAAc,IAAI,cAAc;AAAA,MAC5D,cAAc,GAAG,gBAAgB;AAAA;AAAA,MAEjC;AAAA,MACA;AAAA,MACA,GAAG,qBAAqB,EAAE;AAAA;AAAA,MAE1B;AAAA;AAAA,MAEA,UAAU,GAAG,YAAY;AAAA,MACzB,YAAY,GAAG,aAAa,SAAS,GAAG,YAAY,EAAE,IAAI;AAAA,MAC1D,YAAY,GAAG,aAAa,SAAS,GAAG,YAAY,EAAE,IAAI;AAAA;AAAA,MAE1D,YAAY,GAAG,cAAc;AAAA,MAC7B,kBAAkB,GAAG,oBAAoB;AAAA,MACzC,mBAAmB,qBAAqB,kBAAkB,SAAS,IAAI,oBAAoB;AAAA,MAC3F,cAAe,GAAG,gBAAsD;AAAA,MACxE,gBAAgB,GAAG,kBAAkB;AAAA,MACrC,cAAc,GAAG,gBAAgB;AAAA;AAAA,MAEjC,YAAa,GAAG,cAAkD;AAAA;AAAA,MAElE,sBAAsB,0BAA0B,GAAG,oBAAoB;AAAA;AAAA,MAEvE,aAAa,GAAG,eAAe;AAAA;AAAA;AAAA,MAG/B;AAAA,MACA;AAAA;AAAA,MAEA,qBAAqB,6BAA6B,GAAG,mBAAmB;AAAA,MACxE,oBAAoB,GAAG,sBAAsB;AAAA,MAC7C,SAAS,uBAAuB,GAAG,OAAO;AAAA,MAC1C,YAAY,wBAAwB,mBAAmB,GAAG,UAAU,GAAG,uBAAuB,GAAG,OAAO,CAAC;AAAA,MACzG,cAAc,uBAAuB,GAAG,YAAY;AAAA,IACtD;AAAA,IACA;AAAA,EACF;AAIA,MAAI,QAAQ,SAAS,QAAQ,GAAG;AAC9B,UAAM,QAAsB,CAAC;AAC7B,UAAM,cAAc,QAAQ;AAAA,MAC1B;AAAA,IACF;AACA,eAAWC,UAAS,aAAa;AAC/B,YAAM,KAAK;AAAA,QACT,UAAUA,OAAM,CAAC;AAAA,QACjB,UAAUA,OAAM,CAAC;AAAA,QACjB,UAAU,WAAWA,OAAM,CAAC,CAAC;AAAA,QAC7B,QAAQA,OAAM,CAAC,IAAI,qBAAqBA,OAAM,CAAC,CAAC,IAAI;AAAA,MACtD,CAAC;AAAA,IACH;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,YAAY,QAAQ;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,2BAA2B,SAAqC;AACvE,QAAM,YAAY,QACf,MAAM,4BAA4B,IAAI,CAAC,GACtC,KAAK,EACN,YAAY;AACf,SAAO,aAAa;AACtB;AAEA,IAAM,iCAAiC,oBAAI,IAAI,CAAC,WAAW,SAAS,UAAU,SAAS,WAAW,QAAQ,OAAO,CAAC;AAElH,SAAS,4BAA4B,SAAqC;AACxE,QAAM,WAAWC,OAAK,SAAS,SAAS,KAAK,EAAE,YAAY;AAC3D,QAAM,YAAY,SAAS,QAAQ,GAAG;AACtC,MAAI,aAAa,EAAG,QAAO;AAC3B,QAAM,YAAY,SAAS,MAAM,GAAG,SAAS;AAC7C,SAAO,+BAA+B,IAAI,SAAS,IAAI,YAAY;AACrE;AAEO,SAAS,4BACd,aACA,SACA,UAAkB,IACC;AACnB,QAAM,iBAAiB,QAAQ,MAAMA,OAAK,GAAG,EAAE,KAAK,GAAG;AACvD,MAAI,wBAAwB;AAE5B,MACE,mBAAmB,cACnB,eAAe,WAAW,WAAW,KACrC,eAAe,SAAS,YAAY,GACpC;AACA,UAAM,WAAWA,OAAK,SAAS,SAAS,KAAK;AAC7C,UAAM,eAAe,2BAA2B,OAAO,KAAK,4BAA4B,OAAO,KAAK;AACpG,UAAM,eAAe,MAAM,QAAQ,YAAY,IAAI,IAAI,YAAY,OAAO,CAAC;AAC3E,4BAAwB;AAAA,MACtB,GAAG;AAAA,MACH,IACE,OAAO,sBAAsB,OAAO,YAAY,sBAAsB,GAAG,KAAK,EAAE,SAAS,IACrF,sBAAsB,KACtB;AAAA,MACN,UAAU;AAAA,MACV,MAAM,aAAa,SAAS,YAAY,IAAI,eAAe,CAAC,GAAG,cAAc,YAAY;AAAA,IAC3F;AAAA,EACF;AAEA,MAAI,qBAAqB,OAAO,MAAM,CAAC,sBAAsB,UAAU,sBAAsB,WAAW,WAAW;AACjH,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,wBACP,aACA,SACA,gBACc;AACd,SAAO,kBAAkB,aAAa,SAAS,cAAc;AAC/D;AAKA,SAAS,YAAY,GAAW,GAAmB;AACjD,QAAM,IAAI,EAAE;AACZ,QAAM,IAAI,EAAE;AACZ,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,MAAM,EAAG,QAAO;AAEpB,QAAM,KAAiB,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAAG,MAAM,IAAI,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;AACnF,WAAS,IAAI,GAAG,KAAK,GAAG,IAAK,IAAG,CAAC,EAAE,CAAC,IAAI;AACxC,WAAS,IAAI,GAAG,KAAK,GAAG,IAAK,IAAG,CAAC,EAAE,CAAC,IAAI;AAExC,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,SAAG,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;AAAA,IACjH;AAAA,EACF;AACA,SAAO,GAAG,CAAC,EAAE,CAAC;AAChB;AAGA,SAAS,YAAY,GAAmB;AACtC,SAAO,EAAE,QAAQ,MAAM,EAAE;AAC3B;AAGA,IAAM,uCAAuC;AAE7C,IAAM,wCAAwC;AAuB9C,SAAS,uBAAuB,KAY9B;AACA,QAAM,QAAQ,IAAI,MAAM,6CAA6C;AACrE,MAAI,CAAC,OAAO;AACV,WAAO,EAAE,aAAa,CAAC,GAAG,MAAM,IAAI;AAAA,EACtC;AAEA,QAAM,SAAiC,CAAC;AACxC,QAAM,aAAuB,CAAC;AAC9B,QAAM,iBAAuC;AAAA,IAC3C,SAAS;AAAA,IACT,SAAS;AAAA,IACT,MAAM;AAAA,IACN,sBAAsB;AAAA,IACtB,0BAA0B;AAAA,IAC1B,iCAAiC;AAAA,IACjC,kCAAkC;AAAA,IAClC,mBAAmB;AAAA,EACrB;AACA,aAAW,QAAQ,MAAM,CAAC,EAAE,MAAM,OAAO,GAAG;AAC1C,QAAI,MAAM,KAAK,IAAI,GAAG;AACpB,iBAAW,KAAK,IAAI;AACpB;AAAA,IACF;AACA,UAAM,WAAW,KAAK,QAAQ,GAAG;AACjC,QAAI,aAAa,IAAI;AACnB,iBAAW,KAAK,IAAI;AACpB;AAAA,IACF;AACA,UAAM,MAAM,KAAK,MAAM,GAAG,QAAQ,EAAE,KAAK;AACzC,QAAI,eAAe,GAAG,MAAM,MAAM;AAChC,iBAAW,KAAK,IAAI;AACpB;AAAA,IACF;AACA,UAAM,QAAQ,6BAA6B,KAAK,MAAM,WAAW,CAAC,CAAC;AACnE,WAAO,GAAG,IAAI;AAAA,EAChB;AAEA,QAAM,yBAAyB,OAAO,SAAS,OAAO,4BAA4B,IAAI,EAAE;AACxF,QAAM,+BAA+B,OAAO,SAAS,OAAO,mCAAmC,IAAI,EAAE;AACrG,QAAM,mBAAmB,OAAO,SAAS,OAAO,qBAAqB,IAAI,EAAE;AAC3E,SAAO;AAAA,IACL,aAAa;AAAA,MACX,SAAS,OAAO,WAAW;AAAA,MAC3B,SAAS,OAAO,WAAW;AAAA,MAC3B,oBAAoB,OAAO,wBAAwB;AAAA,MACnD,wBAAwB,OAAO,SAAS,sBAAsB,IAAI,yBAAyB;AAAA,MAC3F,8BAA8B,OAAO,SAAS,4BAA4B,IACtE,+BACA;AAAA,MACJ,+BAA+B,OAAO,oCAAoC;AAAA,MAC1E,kBAAkB,OAAO,SAAS,gBAAgB,IAAI,mBAAmB;AAAA,MACzE;AAAA,IACF;AAAA,IACA,MAAM,MAAM,CAAC;AAAA,EACf;AACF;AAEA,SAAS,6BAA6B,UAA0B;AAC9D,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,eAAe,QAAQ,CAAC;AAC9B,MAAI,iBAAiB,OAAO,iBAAiB,KAAK;AAChD,QAAI,UAAU;AACd,aAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,YAAM,OAAO,QAAQ,KAAK;AAC1B,UAAI,iBAAiB,OAAO,CAAC,WAAW,SAAS,MAAM;AACrD,kBAAU;AACV;AAAA,MACF;AACA,UAAI,CAAC,WAAW,SAAS,cAAc;AACrC,eAAO,QAAQ,MAAM,GAAG,KAAK;AAAA,MAC/B;AACA,gBAAU;AAAA,IACZ;AACA,WAAO,QAAQ,MAAM,CAAC,EAAE,QAAQ,IAAI,OAAO,GAAG,YAAY,GAAG,GAAG,EAAE;AAAA,EACpE;AAEA,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GAAG;AACtD,QAAI,QAAQ,KAAK,MAAM,QAAQ,UAAU,KAAK,KAAK,KAAK,QAAQ,QAAQ,CAAC,KAAK,EAAE,IAAI;AAClF,aAAO,QAAQ,MAAM,GAAG,KAAK,EAAE,QAAQ;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,sBACP,OACA,cACA,UAGI,CAAC,GACe;AACpB,QAAM,qBAAqB,IAAI,IAAI,aAAa,IAAI,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;AACjF,MAAI,UAAU;AACd,QAAM,eAAyB,CAAC;AAChC,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,YAAM,cAAc,KAAK,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY;AACrD,UAAI,WAAW,CAAC,mBAAmB,IAAI,WAAW,EAAG;AACrD,gBAAU,mBAAmB,IAAI,WAAW,IAAI,cAAc;AAC9D;AAAA,IACF;AACA,QAAI,CAAC,QAAS;AACd,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,SAAS;AACZ,UAAI,QAAQ,oBAAoB,QAAQ,aAAa,SAAS,KAAK,aAAa,aAAa,SAAS,CAAC,MAAM,IAAI;AAC/G,qBAAa,KAAK,EAAE;AAAA,MACtB;AACA;AAAA,IACF;AACA,QACE,QAAQ,wBAAwB,QAChC,QAAQ,WAAW,IAAI,KACvB,yCAAyC,QAAQ,MAAM,CAAC,CAAC,GACzD;AACA;AAAA,IACF;AACA,QAAI,QAAQ,WAAW,IAAI,KAAK,QAAQ,oBAAoB,KAAM;AAClE,iBAAa,KAAK,QAAQ,oBAAoB,OAAO,KAAK,QAAQ,IAAI,OAAO;AAAA,EAC/E;AACA,SAAO,aAAa,aAAa,SAAS,CAAC,MAAM,IAAI;AACnD,iBAAa,IAAI;AAAA,EACnB;AACA,MAAI,aAAa,WAAW,EAAG,QAAO;AACtC,SAAO,aAAa,KAAK,QAAQ,oBAAoB,OAAO,OAAO,GAAG;AACxE;AAMO,SAAS,gBAAgB,SAAiB,eAA2D;AAC1G,QAAM,EAAE,aAAa,KAAK,IAAI,uBAAuB,OAAO;AAC5D,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,qBAAqB,oBAAI,IAAI;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,UAAU,YAAY,WAAW;AACrC,MAAI,UAAU;AACd,QAAM,cAAwB,CAAC;AAC/B,QAAM,gBAAsC,CAAC;AAC7C,QAAM,WAAkC,CAAC;AACzC,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAkC,CAAC;AACzC,QAAM,gBAA2D,CAAC;AAGlE,QAAM,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC;AACxD,MAAI,YAAa,QAAO,YAAY,MAAM,CAAC,EAAE,KAAK;AAGlD,QAAM,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAC5D,MAAI,SAAU,QAAO,SAAS,QAAQ,aAAa,EAAE,EAAE,KAAK;AAG5D,QAAM,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,cAAc,CAAC;AAClE,MAAI,YAAa,WAAU,YAAY,QAAQ,gBAAgB,EAAE,EAAE,KAAK;AACxE,MAAI,CAAC,QAAS,WAAU,YAAY,WAAW,YAAY,WAAW;AACtE,MAAI,CAAC,QAAS,WAAU;AAExB,QAAM,mBAAmB,MAAM,UAAU,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC;AAClE,QAAM,oBAAoB,MAAM,UAAU,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC;AACpE,QAAM,uBAAuB,mBAAmB,KAAK,mBAAmB,IAAI;AAC5E,QAAM,uBACJ,oBAAoB,KAAK,MAAM,MAAM,sBAAsB,iBAAiB,IAAI,MAAM,MAAM,oBAAoB;AAClH,QAAM,kBAAkB,qBAAqB;AAAA,IAC3C,CAAC,SAAS,CAAC,KAAK,WAAW,WAAW,KAAK,CAAC,KAAK,WAAW,cAAc;AAAA,EAC5E;AACA,QAAM,4BAA4B,CAAC,GAAG,eAAe;AACrD,SAAO,0BAA0B,CAAC,MAAM,IAAI;AAC1C,8BAA0B,MAAM;AAAA,EAClC;AACA,QAAM,2BAA2B,0BAA0B,KAAK,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC,IAC5F,4BACA,CAAC;AAEL,QAAM,oBAAoB,WAAW,WAAW;AAGhD,MAAI,UAAU;AACd,MAAI,sBAAiE;AACrE,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,KAAK,GAAG;AAC1B,YAAM,UAAU,KAAK,MAAM,CAAC,EAAE,KAAK;AACnC,gBAAU,QAAQ,YAAY;AAC9B,UAAI,mBAAmB,IAAI,OAAO,GAAG;AACnC,8BAAsB;AAAA,MACxB,OAAO;AACL,8BAAsB,EAAE,OAAO,SAAS,OAAO,CAAC,EAAE;AAClD,sBAAc,KAAK,mBAAmB;AAAA,MACxC;AACA;AAAA,IACF;AACA,QAAI,qBAAqB;AACvB,0BAAoB,MAAM,KAAK,IAAI;AAAA,IACrC;AACA,QAAI,CAAC,KAAK,WAAW,IAAI,EAAG;AAE5B,UAAM,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK;AAClC,QAAI,CAAC,OAAQ;AAEb,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,oBAAY,KAAK,MAAM;AACvB;AAAA,MACF,KAAK,YAAY;AACf,cAAM,SAAS,0BAA0B,QAAQ,iBAAiB;AAClE,YAAI,OAAQ,UAAS,KAAK,MAAM;AAChC;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AACH,YAAI,yCAAyC,MAAM,GAAG;AACpD,gBAAM,SAAS,0BAA0B,QAAQ,iBAAiB;AAClE,cAAI,OAAQ,UAAS,KAAK,MAAM;AAAA,QAClC;AAEA;AAAA,MACF,KAAK,gBAAgB;AAOnB,cAAM,WAAW,OAAO,MAAM,gCAAgC;AAC9D,YAAI,UAAU;AACZ,wBAAc,KAAK,EAAE,QAAQ,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,QAC9E;AACA;AAAA,MACF;AAAA,MACA,KAAK,YAAY;AAMf,cAAM,WAAW,OAAO,MAAM,4BAA4B;AAC1D,YAAI,UAAU;AACZ,mBAAS,KAAK,EAAE,MAAM,SAAS,CAAC,GAAG,MAAM,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,QAC/D;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,gBAAQ,KAAK,MAAM;AACnB;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,4BAA4B,YAAY,IAAI,CAAC,UAAU;AAAA,IAC3D,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,EAAE;AAEF,MAAI,0BAA0B,SAAS,GAAG;AACxC,UAAM,wBAAwB,IAAI;AAAA,MAChC,SAAS,IAAI,CAAC,UAAU,MAAM,KAAK,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,IAC/E;AACA,eAAW,QAAQ,2BAA2B;AAC5C,YAAM,iBAAiB,KAAK,KAAK,KAAK;AACtC,UAAI,CAAC,kBAAkB,sBAAsB,IAAI,cAAc,EAAG;AAClE,eAAS,KAAK,IAAI;AAClB,4BAAsB,IAAI,cAAc;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,YACJ,sBAAsB,OAAO,CAAC,WAAW,GAAG,EAAE,iBAAiB,MAAM,qBAAqB,KAAK,CAAC,KAChG,sBAAsB,OAAO,CAAC,SAAS,GAAG,EAAE,iBAAiB,MAAM,qBAAqB,KAAK,CAAC;AAChG,QAAM,qBAAqB,YAAY,sBAAsB;AAC7D,QAAM,yBAAyB,YAAY;AAC3C,QAAM,+BAA+B,YAAY;AACjD,QAAM,gCAAgC,YAAY;AAClD,QAAM,EAAE,oBAAoB,uBAAuB,IAAI;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ,mBAAmB,UAAU,kBAAkB;AAE7D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,uBAAuB,YAAY,cAAc,CAAC;AAAA,IAClD,iBAAiB;AAAA,IACjB;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,YAAY;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB;AACF;AAOO,SAAS,oBACd,QACA,eACA,SACQ;AACR,QAAM,YAAY,OAAO,aAAa,OAAO,WAAW;AACxD,QAAM,UAAU,OAAO,SAAS,KAAK,KAAK,OAAO,YAAW,oBAAI,KAAK,GAAE,YAAY;AACnF,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,WAAW,OAAO;AACxB,QAAM,qBAAqB;AAAA,IACzB,OAAO;AAAA,KACN,OAAO,sBAAsB,CAAC,GAC5B,IAAI,CAAC,YAAY;AAChB,YAAM,aAAa,2CAA2C,QAAQ,OAAO,QAAQ,WAAW;AAChG,YAAM,SAAS,EAAE,GAAG,SAAS,GAAG,WAAW;AAC3C,UAAI,WAAW,gBAAgB,OAAW,QAAO,OAAO;AACxD,aAAO;AAAA,IACT,CAAC,EACA,OAAO,CAAC,YAAY,QAAQ,MAAM,SAAS,CAAC;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,eAAe,IAAI,IAAI,8BAA8B,kBAAkB,CAAC;AAC9E,QAAM,cACJ,SAAS,WAAW,IAChB;AAAA,IACE,GAAG,IAAI;AAAA,MACL,OAAO,MACJ,IAAI,CAAC,SAAS,2BAA2B,IAAI,CAAC,EAC9C,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC;AAAA,IAChE;AAAA,EACF,IACA,CAAC;AACP,QAAM,qBAAqB,OAAO,oBAAoB,KAAK,KAAK;AAChE,QAAM,yBAAyB,OAAO;AACtC,QAAM,+BAA+B,OAAO;AAC5C,QAAM,gCAAgC,OAAO,+BAA+B,KAAK,KAAK;AACtF,QAAM,mBAAmB,OAAO,qBAAqB,YAAY,IAAI;AACrE,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO;AAAA,IACnB,0BAA0B,kBAAkB;AAAA,IAC5C,GAAI,2BAA2B,SAAY,CAAC,IAAI,CAAC,6BAA6B,sBAAsB,EAAE;AAAA,IACtG,GAAI,iCAAiC,SACjC,CAAC,IACD,CAAC,oCAAoC,4BAA4B,EAAE;AAAA,IACvE,GAAI,gCAAgC,CAAC,sCAAsC,6BAA6B,GAAG,IAAI,CAAC;AAAA,IAChH,sBAAsB,gBAAgB;AAAA,IACtC,GAAI,YAAY,QAAQ,CAAC,IAAI,CAAC,SAAS,qBAAqB,OAAO,IAAI,CAAC,EAAE;AAAA,IAC1E,GAAI,YAAY,QACX,OAAO,yBAAyB,CAAC,KACjC,OAAO,yBAAyB,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,WAAW,OAAO,CAAC;AAAA,IACnF;AAAA,IACA;AAAA,IACA,KAAK,OAAO,IAAI;AAAA,IAChB;AAAA,IACA,aAAa,OAAO,IAAI;AAAA,IACxB,gBAAgB,OAAO;AAAA,IACvB;AAAA,EACF;AACA,OAAK,OAAO,mBAAmB,CAAC,GAAG,SAAS,GAAG;AAC7C,UAAM,KAAK,GAAI,OAAO,mBAAmB,CAAC,CAAE;AAC5C,QAAI,OAAO,kBAAkB,OAAO,gBAAgB,SAAS,CAAC,MAAM,IAAI;AACtE,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AACA,QAAM,KAAK,gBAAgB,EAAE;AAC7B,MAAI,WAAW;AACb,UAAM,KAAK,SAAS;AAAA,EACtB;AACA,QAAM,KAAK,EAAE;AAEb,MAAI,SAAS,SAAS,KAAK,YAAY,WAAW,GAAG;AACnD,UAAM,KAAK,eAAe,EAAE;AAC5B,eAAW,SAAS,UAAU;AAC5B,YAAM,KAAK,6BAA6B,KAAK,CAAC;AAAA,IAChD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAK,YAAY,EAAE;AACzB,eAAW,QAAQ,aAAa;AAC9B,YAAM,KAAK,KAAK,IAAI,EAAE;AAAA,IACxB;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,aAAW,WAAW,oBAAoB;AACxC,UAAM,KAAK,MAAM,QAAQ,KAAK,IAAI,EAAE;AACpC,eAAW,CAAC,OAAO,IAAI,KAAK,QAAQ,MAAM,QAAQ,GAAG;AACnD,YAAM,SAAS,QAAQ,cAAc,KAAK;AAC1C,YAAM,SAAS,SACX,IAAI,+BAA+B,oBAAoB,kCAAkC,MAAM,CAAC,OAChG;AACJ,YAAM,KAAK,KAAK,MAAM,GAAG,yBAAyB,IAAI,CAAC,EAAE;AAAA,IAC3D;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,cAAc,SAAS,GAAG;AACnC,UAAM,KAAK,mBAAmB,EAAE;AAChC,eAAW,OAAO,OAAO,eAAe;AACtC,YAAM,KAAK,OAAO,IAAI,MAAM,aAAQ,IAAI,KAAK,EAAE;AAAA,IACjD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,KAAK,eAAe,EAAE;AAC5B,eAAW,OAAO,OAAO,UAAU;AACjC,YAAM,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE;AAAA,IACzC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,KAAK,cAAc,EAAE;AAC3B,eAAW,SAAS,OAAO,SAAS;AAClC,YAAM,KAAK,KAAK,KAAK,EAAE;AAAA,IACzB;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,aAAW,WAAW,OAAO,iBAAiB,CAAC,GAAG;AAChD,UAAM,KAAK,MAAM,QAAQ,KAAK,EAAE;AAChC,UAAM,KAAK,GAAG,QAAQ,KAAK;AAC3B,QAAI,QAAQ,MAAM,SAAS,KAAK,QAAQ,MAAM,QAAQ,MAAM,SAAS,CAAC,MAAM,IAAI;AAC9E,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,0BAA0B,eAAuD;AAC/F,MAAI,CAAC,cAAe,QAAO;AAC3B,QAAM,aAAa,OAAO,QAAQ,aAAa,EAC5C,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC,EACnD,IAAI,CAAC,CAAC,YAAY,MAAM,MAAM;AAAA,IAC7B;AAAA,IACA;AAAA,MACE,UAAU,OAAO,SAAS,IAAI,CAAC,aAAa;AAAA,QAC1C,KAAK,QAAQ;AAAA,QACb,OAAO,QAAQ;AAAA,QACf,aAAa,QAAQ;AAAA,QACrB,SAAS,QAAQ,UAAU,CAAC,GAAG,QAAQ,OAAO,IAAI;AAAA,MACpD,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AACH,SAAO,KAAK,UAAU,UAAU;AAClC;AAeO,SAAS,2BAA2B,OAA8C;AACvF,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AACxE,QAAM,IAAI;AACV,MAAI,EAAE,UAAU,kBAAmB,QAAO;AAC1C,MAAI,OAAO,EAAE,cAAc,YAAY,EAAE,UAAU,WAAW,EAAG,QAAO;AACxE,MAAI,CAAC,OAAO,SAAS,KAAK,MAAM,EAAE,SAAS,CAAC,EAAG,QAAO;AACtD,MAAI,OAAO,EAAE,cAAc,YAAY,EAAE,UAAU,WAAW,EAAG,QAAO;AACxE,MAAI,EAAE,eAAe,QAAQ,OAAO,EAAE,eAAe,SAAU,QAAO;AACtE,MAAI,EAAE,aAAa,UAAU,EAAE,aAAa,YAAa,QAAO;AAChE,MAAI,OAAO,EAAE,kBAAkB,YAAY,CAAC,OAAO,SAAS,EAAE,aAAa,GAAG;AAC5E,WAAO;AAAA,EACT;AAGA,MAAI,EAAE,gBAAgB,KAAK,EAAE,gBAAgB,EAAG,QAAO;AACvD,MAAI,OAAO,EAAE,cAAc,YAAY,CAAC,OAAO,SAAS,EAAE,SAAS,EAAG,QAAO;AAC7E,MAAI,EAAE,YAAY,KAAK,EAAE,YAAY,EAAG,QAAO;AAC/C,MAAI,OAAO,EAAE,mBAAmB,UAAW,QAAO;AAClD,MAAI,OAAO,EAAE,sBAAsB,YAAY,CAAC,OAAO,SAAS,EAAE,iBAAiB,GAAG;AACpF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAuBA,SAAS,iCAAiC,KAA8D;AACtG,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,QAAM,QAAwD,CAAC;AAC/D,aAAW,SAAS,KAAK;AACvB,QAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,QAAI,EAAE,iBAAiB,UAAU,OAAO,MAAM,gBAAgB,SAAU;AACxE,QAAI,EAAE,cAAc,UAAU,OAAO,MAAM,aAAa,YAAY,CAAC,OAAO,SAAS,MAAM,QAAQ,EAAG;AACtG,QAAI,EAAE,oBAAoB,UAAU,OAAO,MAAM,mBAAmB,SAAU;AAC9E,QAAI,EAAE,mBAAmB,UAAU,OAAO,MAAM,kBAAkB,SAAU;AAC5E,QAAI,EAAE,sBAAsB,OAAQ;AACpC,UAAM,MAAM,MAAM;AAClB,QAAI,QAAQ,wBAAwB,QAAQ,iBAAiB,QAAQ,cAAe;AACpF,UAAM,mBAA2C;AACjD,UAAM,KAAK;AAAA,MACT,aAAa,MAAM;AAAA,MACnB,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,eAAe,MAAM;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAiGO,IAAMC,kBAAN,MAAM,wBAAuB,iCAAiC;AAAA,EAycnE,YACmB,SACA,eAOjB,iCACA;AACA,UAAM;AAVW;AACA;AAUjB,SAAK,wBAAwB,IAAI,sBAAsB;AAAA,MACrD;AAAA,MACA,8BAA8BC,OAAK,KAAK,SAAS,iBAAiB,4BAA4B;AAAA,MAC9F,gCAAgCA,OAAK,KAAK,SAAS,iBAAiB,8BAA8B;AAAA,MAClG,0BAA0BA,OAAK,KAAK,SAAS,iBAAiB,iCAAiC;AAAA,MAC/F,0BAA0B,CAAC,UAAU,WAAW,KAAK,yBAAyB,UAAU,MAAM;AAAA,IAChG,CAAC;AACD,SAAK,0BACH,mCACA,gBAAe,6BAA6B,IAAI,OAAO,KACvD,gBAAe;AAMjB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EA5BmB;AAAA,EACA;AAAA,EA1cX,sBAAkE;AAAA,EACzD;AAAA,EACT,qBAAkG;AAAA,EAClG,6BAA6B,IAAI,2BAA2B;AAAA,EACpE,OAAwB,wBAAwB,oBAAI,QAA4B;AAAA,EAChF,OAAgB,+BAA+B;AAAA;AAAA;AAAA,EAE/C,OAAgB,8BAA8B;AAAA;AAAA,EAC9C,OAAwB,4BAA4B,oBAAI,IAAoB;AAAA,EAC5E,OAAwB,2BAA2B,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3E,OAAwB,2BAA2B,oBAAI,IAAoB;AAAA;AAAA,EAE3E,OAAwB,6BAA6B,oBAAI,IAAoB;AAAA,EAC7E,OAAwB,+BAA+B,oBAAI,QAAwB;AAAA,EACnF,OAAe,kCAAkC;AAAA;AAAA;AAAA,EAGjD,OAAwB,wBAAwB,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxE,OAAe,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUzC,OAAwB,+BAA+B,oBAAI,IAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShF,OAAe,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASvC,OAAwB,2BAA2B,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY3E,OAAe,uCAAuC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWtD,OAAwB,+BAA+B,oBAAI,IAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAehF,OAAgB,yBAAyB;AAAA;AAAA;AAAA,EAEzC,OAAgB,oBAAoB,oBAAI,IAGtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMF,OAAgB,yBAAyB;AAAA;AAAA;AAAA,EAEzC,OAAgB,iBAAiB,oBAAI,IAcnC;AAAA,EACM,gBAAyC;AAAA,EACzC,2BAA6D;AAAA,EAC7D,6BAA6C;AAAA,EAC7C,oCAA6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYrE,2BAAwD,CAAC;AAAA,EACxC,qBAAqB,oBAAI,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYpD,iCAAiC,oBAAI,IAGpD;AAAA,EACM,yBAA0E;AAAA,EAC1E,oCAA8F;AAAA,EAC9F,mCAAkD,QAAQ,QAAQ;AAAA,EAClE,mCAAyE;AAAA;AAAA,EAEjF,mBAA2B;AAAA;AAAA,EAE3B;AAAA;AAAA,EAEA;AAAA,EACQ,kBAAkB,UAAwB;AAChD,QAAI;AACF,WAAK,gBAAgB,QAAQ;AAAA,IAC/B,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EACQ,qBAA2B;AACjC,QAAI;AACF,WAAK,iBAAiB;AAAA,IACxB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,0BAA0B,UAAwB;AAC1D,QAAI,CAAC,KAAK,oBAAoB,KAAK,gBAAgB,QAAQ,EAAG;AAC9D,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA,EAGQ,gBAAgB,UAA2B;AACjD,UAAM,MAAMA,OAAK,SAAS,KAAK,UAAUA,OAAK,QAAQ,QAAQ,CAAC;AAC/D,WAAO,QAAQ,MAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAACA,OAAK,WAAW,GAAG;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAwC;AAAA,EACxC,4BAA4D;AAAA,EAC5D,mBAKJ,EAAE,SAAS,OAAO,eAAe,OAAO,mBAAmB,KAAK,WAAW,UAAU;AAAA;AAAA,EAGjF,oBAA6C;AAAA;AAAA,EAGrD,oBAAoB,QAAgC;AAClD,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,kBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjC,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ7B,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY/B,kBAAkB,KAAoB,iBAAiB,MAAY;AACjE,QAAI,CAAC,KAAK,oBAAoB,KAAK,cAAc,KAAK,QAAQ,KAAM;AACpE,SAAK,KAAK,2BAA2B,mBAAmB,EAAE,MAAM,CAAC,UAAmB;AAClF,UAAI,KAAK,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IAC5G,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,yBAAyB,KAAoB,iBAAiB,MAAqB;AAC9F,QAAI,CAAC,KAAK,oBAAoB,KAAK,cAAc,KAAK,QAAQ,KAAM;AACpE,UAAM,KAAK,2BAA2B,mBAAmB;AAAA,EAC3D;AAAA,EAEQ,oBAAoB,KAAoB,gBAAkC;AAChF,UAAM,UACJ,KAAK,oBAAoB,OACxB,KAAK,oBAAoB,QAAQ,QAAQ,QAAQ,KAAK,gBAAgB,OAAO,GAAG;AACnF,QAAI,WAAW,KAAK,+BAA+B,eAAgB,QAAO;AAE1E,SAAK,kBAAkB;AACvB,SAAK,6BAA6B;AAClC,wBAAoB,KAAK,OAAO;AAChC,SAAK,8BAA8B;AACnC,SAAK,+BAA+B,MAAM;AAC1C,SAAK,0BAA0B;AAC/B,WAAO;AAAA,EACT;AAAA,EAEQ,+BAAuC;AAC7C,QAAI,CAAC,KAAK,gBAAiB,QAAO;AAClC,QAAI,KAAK,gBAAe,6BAA6B,IAAI,KAAK,eAAe;AAC7E,QAAI,OAAO,QAAW;AACpB,WAAK,gBAAe;AACpB,sBAAe,6BAA6B,IAAI,KAAK,iBAAiB,EAAE;AAAA,IAC1E;AACA,WAAO,oBAAoB,EAAE;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,gBAAwB;AACtB,WAAO,KAAK,oBAAoB,OAAO,KAAK,KAAK,6BAA6B;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBAA6B;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAwB;AACtB,WAAO,gBAAe,yBAAyB,IAAI,KAAK,OAAO,KAAK,gBAAe;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,wBAAwB,GAAoB;AAClD,UAAM,MAAMA,OAAK,SAAS,KAAK,SAAS,CAAC;AACzC,WACE,QAAQ,UAAU,QAAQ,aAAa,IAAI,WAAW,OAAOA,OAAK,GAAG,EAAE,KAAK,IAAI,WAAW,UAAUA,OAAK,GAAG,EAAE;AAAA,EAEnH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,uBAAuB,UAAyB;AAC9C,SAAK,uBAAuB;AAAA,EAC9B;AAAA;AAAA,EAGA,wBAAiC;AAC/B,WAAO,KAAK,oBAAoB;AAAA,EAClC;AAAA;AAAA;AAAA,EAIA,yBAAkC;AAChC,WAAO,KAAK,8BAA8B,KAAK,oBAAoB;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,gBAAgB,eAAe,OAAsB;AAC3D,QAAI,CAAC,gBAAgB,CAAC,KAAK,2BAA4B,QAAO;AAC9D,QAAI,KAAK,oBAAoB,KAAM,QAAO,KAAK;AAC/C,QAAI,KAAK,sBAAsB;AAC7B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,oBAAoB,UAAkB,SAAwC;AAC1F,QAAI,CAAC,KAAK,qBAAqB,CAAC,KAAK,kBAAkB,QAAS;AAChE,QAAI;AAGF,YAAM,WAAW,MAAM,uBAAuB,UAAU,KAAK,iBAAiB,KAAK,OAAO;AAC1F,YAAM,cAAkB,UAAU,UAAU,SAAS,KAAK,mBAAmB,KAAK,QAAW,KAAK,OAAO;AAAA,IAC3G,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,sBAAsB,UAA0C;AACpE,QAAI,CAAC,KAAK,qBAAqB,CAAC,KAAK,kBAAkB,QAAS,QAAO;AACvE,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,uBAAuB,UAAU,KAAK,iBAAiB,KAAK,OAAO;AAAA,IACtF,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,UAAU,MAAM;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP;AACA,YAAM,MAAMA,OAAK,SAAS,KAAK,SAAS,QAAQ,EAAE,MAAMA,OAAK,GAAG,EAAE,KAAK,GAAG;AAC1E,aAAO,GAAG,GAAG,IAAI,QAAQ,SAAS;AAAA,IACpC,SAAS,KAAK;AACZ,UAAI;AAAA,QACF,qDAAqD,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACpH;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCjB,OAAO,2BAA2B,WAAmB,SAA8B,OAAsB;AAIvG,oBAAe,6BAA6B,IAAI,WAAW,YAAY,KAAK;AAI5E,UAAM,WAAW,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS;AACjF,QAAI,UAAU;AACZ,sBAAe,yBAAyB,IAAI,WAAW,KAAe;AAAA,IACxE;AAMA,QAAI,CAAC,gBAAe,sCAAsC;AACxD,sBAAe,0BAA0B,YAAY;AACrD,UAAI,SAAU,iBAAe,wBAAwB;AACrD,sBAAe,uCAAuC;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,kCAAkC,WAAmB,SAAoC;AAC9F,oBAAe,6BAA6B,IAAI,WAAW,YAAY,KAAK;AAAA,EAC9E;AAAA;AAAA,EAGA,OAAwB,sBAAsB,oBAAI,IAAqB;AAAA;AAAA;AAAA;AAAA,EAKvE,OAAO,yBAAyB,WAAmB,SAAoC;AACrF,oBAAe,oBAAoB,IAAI,WAAW,YAAY,KAAK;AAAA,EACrE;AAAA,EAEA,wBAAiC;AAC/B,aAAS,MAAM,KAAK,WAAW,MAAMA,OAAK,QAAQ,GAAG,GAAG;AACtD,YAAM,aAAa,gBAAe,oBAAoB,IAAI,GAAG;AAC7D,UAAI,eAAe,OAAW,QAAO;AACrC,UAAI,QAAQA,OAAK,QAAQ,GAAG,EAAG,QAAO;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,IAAI,sBAA6C;AAC/C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA,EAIQ;AAAA,EAER,IAAY,kBAAmC;AAC7C,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,mBAAmB,IAAI,gBAAgB,SAA2D,IAAI,CAAC;AAAA,IAC9G;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ;AAAA,EAER,IAAY,cAA2B;AACrC,QAAI,CAAC,KAAK,cAAc;AACtB,WAAK,eAAe,IAAI,YAAY,SAAuD,IAAI,CAAC;AAAA,IAClG;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ;AAAA,EAER,IAAY,0BAAmD;AAC7D,QAAI,CAAC,KAAK,0BAA0B;AAClC,WAAK,2BAA2B,IAAI;AAAA,QAClC,SAAmE,IAAI;AAAA,MACzE;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,iBAAiB,cAAsB,WAA4B;AACzE,UAAM,eAAe,OAAO,cAAc,WAAW,UAAU,KAAK,IAAI;AACxE,QAAI,CAAC,aAAc,QAAOA,OAAK,KAAK,cAAc,aAAa;AAC/D,UAAM,gBAAgB,aAAa,QAAQ,oBAAoB,GAAG;AAClE,WAAOA,OAAK,KAAK,cAAc,YAAY,aAAa,KAAK;AAAA,EAC/D;AAAA,EAEQ,gBAAgB,MAAiC;AACvD,WAAOA,OAAK,KAAK,KAAK,UAAU,IAAI,IAAI,cAAc;AAAA,EACxD;AAAA,EAEQ,kBAAkB,MAAyB,aAA0C;AAC3F,UAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,QAAI;AACF,gBAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,qBAAe,UAAU,GAAG;AAC5B,YAAM,OAAOC,UAAS,QAAQ,EAAE;AAChC,kBAAY,IAAI,KAAK,SAAS,IAAI;AAClC,aAAO;AAAA,IACT,QAAQ;AACN,YAAM,QAAQ,YAAY,IAAI,KAAK,OAAO,KAAK,KAAK;AACpD,kBAAY,IAAI,KAAK,SAAS,IAAI;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,kBAAkB,MAAyB,aAA0C;AAC3F,UAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,QAAI;AACF,aAAOA,UAAS,QAAQ,EAAE;AAAA,IAC5B,QAAQ;AACN,aAAO,YAAY,IAAI,KAAK,OAAO,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA,EAEU,0BAAgC;AACxC,SAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAI/E,SAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAK/E,wBAAoB,KAAK,OAAO;AAAA,EAClC;AAAA,EAEA,yBAAiC;AAC/B,WAAO,KAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA,EAKA,2BAAmC;AACjC,WAAO,KAAK,kBAAkB,mBAAmB,gBAAe,0BAA0B;AAAA,EAC5F;AAAA,EAEU,4BAAkC;AAC1C,uBAAmB,KAAK,SAAS,cAAc;AAC/C,SAAK,kBAAkB,mBAAmB,gBAAe,0BAA0B;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,yBAAiC;AAC/B,WAAO,KAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,0BAAgC;AACxC,SAAK,kBAAkB,iBAAiB,gBAAe,wBAAwB;AAI/E,8BAA0B,KAAK,OAAO;AAAA,EACxC;AAAA,EACA,4BAAoC;AAAE,WAAe,gCAAgC,KAAK,OAAO;AAAA,EAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5F,mCAA6E;AACnF,UAAM,WAAW,KAAK,gBAAgB,eAAe;AACrD,QAAI;AACF,gBAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,UAAI,SAAS;AACb,UAAI;AACF,iBAASA,UAAS,QAAQ,EAAE;AAAA,MAC9B,QAAQ;AACN,iBAAS;AAAA,MACX;AACA,qBAAe,UAAU,GAAG;AAC5B,YAAM,WAAWA,UAAS,QAAQ,EAAE;AACpC,sBAAe,yBAAyB,IAAI,KAAK,SAAS,QAAQ;AAElE,aAAO,EAAE,UAAU,WAAW,aAAa,SAAS,EAAE;AAAA,IACxD,QAAQ;AACN,YAAM,QAAQ,gBAAe,yBAAyB,IAAI,KAAK,OAAO,KAAK,KAAK;AAChF,sBAAe,yBAAyB,IAAI,KAAK,SAAS,IAAI;AAC9D,aAAO,EAAE,UAAU,MAAM,WAAW,KAAK;AAAA,IAC3C;AAAA,EACF;AAAA,EAEU,2BAAmC;AAC3C,WAAO,KAAK,kBAAkB,kBAAkB,gBAAe,yBAAyB;AAAA,EAC1F;AAAA,EAEQ,0BAAkC;AACxC,WAAO,KAAK,kBAAkB,kBAAkB,gBAAe,yBAAyB;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,IAAY,eAAuB;AACjC,WAAOD,OAAK,KAAK,KAAK,SAAS,kBAAkB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,uBAAuB,UAAkB,MAAsB;AAC7D,QAAI,OAAO,aAAa,YAAY,CAAC,yBAAyB,KAAK,QAAQ,GAAG;AAC5E,YAAM,IAAI;AAAA,QACR,+BAA+B,OAAO,QAAQ,CAAC;AAAA,MACjD;AAAA,IACF;AACA,QAAI,CAAC,sBAAsB,IAAI,GAAG;AAChC,YAAM,IAAI,MAAM,qCAAqC,OAAO,IAAI,CAAC,8BAAyB;AAAA,IAC5F;AACA,WAAOA,OAAK,KAAK,KAAK,cAAc,UAAU,GAAG,IAAI,KAAK;AAAA,EAC5D;AAAA,EAEA,MAAM,2BAA2B,UAAkB,MAAc,YAAmC;AAClG,UAAM,aAAa,KAAK,uBAAuB,UAAU,IAAI;AAE7D,UAAM,KAAK,uBAAuB,YAAY,UAAU;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,0BAA0B,UAAkB,MAAsC;AACtF,UAAM,aAAa,KAAK,uBAAuB,UAAU,IAAI;AAC7D,QAAI;AACF,aAAO,MAAM,uBAAuB,YAAY,KAAK,iBAAiB,KAAK,OAAO;AAAA,IACpF,SAAS,KAAK;AACZ,UAAK,IAA8B,SAAS,SAAU,QAAO;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,2BAA2B,UAAqE;AACpG,WAAO,KAAK,gBAAgB,2BAA2B,QAAQ;AAAA,EACjE;AAAA,EAEQ;AAAA;AAAA,EAGR,sBAA2C;AACzC,QAAI,KAAK,aAAc,QAAO,KAAK;AACnC,WAAQ,KAAK,eAAe,IAAI,oBAAoB,KAAK,cAAc,KAAK,SAAS;AAAA,MACnF,WAAW,CAAC,GAAG,MAAM,KAAK,uBAAuB,GAAG,CAAC;AAAA,MACrD,UAAU,CAAC,MAAM,uBAAuB,GAAG,KAAK,iBAAiB,KAAK,OAAO;AAAA,MAC7E,SAAS,CAAC,MAAME,SAAQ,CAAC;AAAA,MACzB,YAAY,CAAC,MAAMC,QAAO,CAAC;AAAA,MAC3B,UAAU,CAAC,MAAMC,UAAS,CAAC;AAAA,MAC3B,OAAO,CAAC,MAAMC,OAAM,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,gBAAgB,GAAG,eAAe,EAAE,EAAE;AAAA,IAC/E,CAAC;AAAA,EACH;AAAA,EAEQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR,qBAAyC;AACvC,QAAI,KAAK,oBAAqB,QAAO,KAAK;AAC1C,WAAQ,KAAK,sBAAsB,IAAI,mBAAmB,KAAK,SAAS;AAAA,MACtE,WAAW,CAAC,GAAG,MAAM,KAAK,uBAAuB,GAAG,CAAC;AAAA,MACrD,UAAU,CAAC,MAAM,uBAAuB,GAAG,KAAK,iBAAiB,KAAK,OAAO;AAAA,MAC7E,SAAS,CAAC,MAAMH,SAAQ,CAAC;AAAA,MACzB,YAAY,CAAC,MAAMC,QAAO,CAAC;AAAA,MAC3B,UAAU,CAAC,MAAMC,UAAS,CAAC;AAAA,MAC3B,OAAO,CAAC,MAAMC,OAAM,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,gBAAgB,GAAG,eAAe,EAAE,EAAE;AAAA,IAC/E,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,4BAA4B,SAAmF;AACnH,UAAM,SAAS,sBAAsB,OAAO;AAC5C,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,eAAW,UAAU,UAAU;AAC7B,UACE,OAAO,OAAO,YAAY,WAAW,YACrC,OAAO,YAAY,OAAO,WAAW,WAAW,KAChD,sBAAsB,OAAO,OAAO,MAAM,QAC1C;AACA,eAAO,EAAE,IAAI,OAAO,YAAY,IAAI,QAAQ,OAAO,YAAY,OAAO;AAAA,MACxE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,sBACJ,IACA,kBACA,YACkB;AAClB,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,UAAU,MAAM,YAAY,OAAO,EAAE;AACnE,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,OAAO,YAAY,WAAW,iBAAkB,QAAO;AAE3D,QAAI,OAAO,YAAY,UAAW,QAAO;AACzC,WAAO,KAAK,uBAAuB,QAAQ;AAAA,MACzC,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIR,GAAI,OAAO,eAAe,YAAY,OAAO,SAAS,UAAU,IAC5D,EAAE,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,CAAC,EAAE,IACnD,CAAC;AAAA,MACL,sBAAsB;AAAA,QACpB,GAAI,OAAO,YAAY,wBAAwB,CAAC;AAAA,QAChD,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,qBAAqB,IAAY,kBAA4D;AACjG,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,UAAU,MAAM,YAAY,OAAO,EAAE;AACnE,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,OAAO,YAAY,WAAW,iBAAkB,QAAO;AAC3D,WAAO,KAAK,uBAAuB,QAAQ;AAAA,MACzC,QAAQ;AAAA,MACR,sBAAsB;AAAA,QACpB,GAAI,OAAO,YAAY,wBAAwB,CAAC;AAAA,QAChD,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,IAAY,WAAmB;AAC7B,WAAOL,OAAK,KAAK,KAAK,SAAS,OAAO;AAAA,EACxC;AAAA,EACA,IAAY,iBAAyB;AACnC,WAAOA,OAAK,KAAK,KAAK,SAAS,aAAa;AAAA,EAC9C;AAAA,EACA,IAAY,gBAAwB;AAClC,WAAOA,OAAK,KAAK,KAAK,SAAS,YAAY;AAAA,EAC7C;AAAA,EACA,IAAY,qBAA6B;AACvC,WAAOA,OAAK,KAAK,KAAK,SAAS,kBAAkB;AAAA,EACnD;AAAA,EACA,IAAY,cAAsB;AAChC,WAAOA,OAAK,KAAK,KAAK,SAAS,UAAU;AAAA,EAC3C;AAAA,EACQ,sBAAsB,MAA6B;AACzD,QAAI,OAAO,SAAS,SAAU,QAAO;AACrC,UAAM,WAAWA,OAAK,QAAQ,KAAK,aAAa,GAAG,IAAI,KAAK;AAC5D,UAAMM,YAAWN,OAAK,SAAS,KAAK,aAAa,QAAQ;AACzD,QAAIM,cAAa,MAAMA,UAAS,WAAW,IAAI,KAAKN,OAAK,WAAWM,SAAQ,GAAG;AAC7E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EACQ,sBAAsB,UAAmC;AAC/D,WAAO,uBAAuB,UAAU,KAAK,iBAAiB,KAAK,OAAO;AAAA,EAC5E;AAAA,EACA,MAAM,mCAAmC,UAAmC;AAC1E,UAAM,SAAS,MAAM;AAAA,MACnB,KAAK;AAAA,MACLN,OAAK;AAAA,QACH,KAAK;AAAA,QACL,KAAK,yBAAyB,UAAU,4CAA4C;AAAA,MACtF;AAAA,IACF;AACA,WAAO,KAAK,sBAAsB,MAAM;AAAA,EAC1C;AAAA,EACA,MAAM,oCAAoC,UAAkB,SAAgC;AAC1F,UAAM,SAAS,MAAM;AAAA,MACnB,KAAK;AAAA,MACLA,OAAK;AAAA,QACH,KAAK;AAAA,QACL,KAAK,yBAAyB,UAAU,6CAA6C;AAAA,MACvF;AAAA,IACF;AACA,WAAO,KAAK,uBAAuB,QAAQ,OAAO;AAAA,EACpD;AAAA,EACU,uBAAuB,UAAkB,SAA0B,eAAe,OAAsB;AAChH,iCAA6B,QAAQ;AACrC,UAAM,WAAW,KAAK,gBAAgB,YAAY;AAClD,WAAO,wBAAwB,UAAU,SAAS,UAAU,CAAC,GAAG,KAAK,OAAO,EAAE,KAAK,MAAM;AAKvF,WAAK,0BAA0B,QAAQ;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEU,yBAAyB,UAAkB,QAAwB;AAC3E,UAAM,WAAWA,OAAK,QAAQ,QAAQ;AACtC,UAAM,OAAOA,OAAK,QAAQ,KAAK,OAAO;AACtC,UAAM,MAAMA,OAAK,SAAS,MAAM,QAAQ;AACxC,QAAI,QAAQ,MAAM,QAAQ,QAAQ,IAAI,WAAW,KAAKA,OAAK,GAAG,EAAE,KAAKA,OAAK,WAAW,GAAG,GAAG;AACzF,YAAM,IAAI,MAAM,GAAG,MAAM,gCAAgC;AAAA,IAC3D;AACA,WAAO;AAAA,EACT;AAAA,EACA,MAAM,wBAA8D;AAClE,WAAO,KAAK,sBAAsB,sBAAsB;AAAA,EAC1D;AAAA,EACA,MAAM,yBACJ,QACkB;AAClB,WAAO,KAAK,sBAAsB,yBAAyB,MAAM;AAAA,EACnE;AAAA,EACA,MAAc,4BAA4B,QAAmC;AAC3E,WAAO,KAAK,sBAAsB,4BAA4B,MAAM;AAAA,EACtE;AAAA,EACA,MAAc,2BACZ,QACe;AACf,WAAO,KAAK,sBAAsB,2BAA2B,MAAM;AAAA,EACrE;AAAA,EACA,MAAM,iCAAiC,UAAkB,SAAgC;AACvF,WAAO,KAAK,sBAAsB,iCAAiC,UAAU,OAAO;AAAA,EACtF;AAAA,EACA,MAAgB,wBAAwB,UAAkB,OAA2C;AACnG,WAAO,KAAK,sBAAsB,wBAAwB,UAAU,KAAK;AAAA,EAC3E;AAAA,EACA,MAAgB,yBAAyB,UAAkB,iBAAmD;AAC5G,WAAO,KAAK,sBAAsB,yBAAyB,UAAU,eAAe;AAAA,EACtF;AAAA,EAEA,MAAM,oBAAoB,UAAmC;AAC3D,UAAM,SAAS,KAAK,yBAAyB,UAAU,6BAA6B;AACpF,WAAO,6BAA6B,QAAQ,KAAK,iBAAiB,KAAK,OAAO;AAAA,EAChF;AAAA,EAEA,MAAM,sBAAsB,UAA8D;AACxF,UAAM,SAAS,KAAK,yBAAyB,UAAU,+BAA+B;AACtF,UAAM,KAAK,MAAMO,MAAK,MAAM;AAC5B,UAAM,UAAUP,OAAK,SAAS,KAAK,SAAS,MAAM,EAAE,MAAMA,OAAK,GAAG,EAAE,KAAK,GAAG;AAC5E,UAAM,QAAQ,MAAM,KAAK,2BAA2B;AACpD,UAAM,SAAS,MAAM,IAAI,OAAO;AAChC,QACE,UACA,OAAO,cAAc,GAAG,QACxB,OAAO,YAAY,GAAG,WACtB,OAAO,YAAY,GAAG,WACtB,CAAC,OAAO,WACR;AACA,aAAO;AAAA,QACL,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,KAAK,2BAA2B,MAAM;AAC9D,QAAI;AACJ,QAAI,WAAW;AACb,YAAM,UAAU,MAAM,6BAA6B,QAAQ,KAAK,iBAAiB,KAAK,OAAO;AAC7F,eAAS;AAAA,QACP,QAAQQ,YAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAAA,QACzD,OAAO,QAAQ;AAAA,MACjB;AAAA,IACF,OAAO;AACL,YAAM,OAAOA,YAAW,QAAQ;AAChC,UAAI,QAAQ;AACZ,uBAAiB,YAAY,iBAAiB,MAAM,GAAG;AACrD,cAAM,QAAQ,OAAO,SAAS,QAAQ,IAAI,WAAW,OAAO,KAAK,QAAQ;AACzE,aAAK,OAAO,KAAK;AACjB,iBAAS,MAAM;AAAA,MACjB;AACA,eAAS;AAAA,QACP,QAAQ,KAAK,OAAO,KAAK;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,WAAW;AACd,WAAK,0BAA0B,SAAS,IAAI,MAAM;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,6BAAgF;AAC5F,QAAI,KAAK,uBAAwB,QAAO,KAAK;AAC7C,QAAI,CAAC,KAAK,mCAAmC;AAC3C,WAAK,oCAAoC,KAAK,2BAA2B;AAAA,IAC3E;AACA,SAAK,yBAAyB,MAAM,KAAK;AACzC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,6BAAgF;AAC5F,UAAM,QAAQ,oBAAI,IAAyC;AAC3D,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,KAAK,4BAA4B,OAAO;AACnE,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO;AAC3E,YAAM,UAAW,OAAiC;AAClD,UAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,QAAO;AACpC,iBAAW,SAAS,SAAS;AAC3B,YAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG;AACjE,cAAM,SAAS;AACf,cAAM,YAAY,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;AAClE,cAAM,YAAY,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;AAC5E,cAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,cAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,cAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,cAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AACnE,cAAM,YAAY,OAAO,cAAc;AACvC,YACE,UAAU,WAAW,KACrB,cAAc,QACd,UAAU,WAAW,KAAK,KAC1BT,OAAK,WAAW,SAAS,KACzB,CAAC,OAAO,SAAS,SAAS,KAC1B,CAAC,OAAO,SAAS,OAAO,KACxB,CAAC,OAAO,SAAS,OAAO,KACxB,CAAC,OAAO,SAAS,KAAK,KACtB,CAAC,kBAAkB,KAAK,MAAM,GAC9B;AACA;AAAA,QACF;AACA,cAAM,IAAI,WAAW,EAAE,WAAW,SAAS,SAAS,WAAW,QAAQ,MAAM,CAAC;AAAA,MAChF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,GAAG;AAC/B,YAAI;AAAA,UACF,8DAA8D,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAChH;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,0BACN,SACA,IACA,QACM;AACN,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,MAAO;AACZ,UAAM,IAAI,SAAS;AAAA,MACjB,WAAW,GAAG;AAAA,MACd,SAAS,GAAG;AAAA,MACZ,SAAS,GAAG;AAAA,MACZ,WAAW;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,IAChB,CAAC;AACD,SAAK,oCAAoC;AAAA,EAC3C;AAAA,EAEQ,sCAA4C;AAClD,QAAI,KAAK,kCAAkC;AACzC,mBAAa,KAAK,gCAAgC;AAAA,IACpD;AACA,SAAK,mCAAmC,WAAW,MAAM;AACvD,WAAK,mCAAmC;AACxC,WAAK,iCAAiC;AAAA,IACxC,GAAG,GAAK;AACR,SAAK,iCAAiC,QAAQ;AAAA,EAChD;AAAA,EAEQ,mCAAyC;AAC/C,SAAK,mCAAmC,KAAK,iCAC1C,MAAM,MAAM,MAAS,EACrB,KAAK,YAAY;AAChB,YAAM,QAAQ,KAAK;AACnB,UAAI,CAAC,MAAO;AACZ,YAAM,UAAU,CAAC,GAAG,MAAM,QAAQ,CAAC,EAChC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,WAAW,KAAK,OAAO,EAAE,MAAM,WAAW,GAAG,MAAM,EAAE;AAC9D,YAAM,MAAMA,OAAK,QAAQ,KAAK,0BAA0B,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9E,YAAMU,WAAU,KAAK,4BAA4B,GAAG,KAAK,UAAU,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;AAAA,GAAM,OAAO;AAAA,IAC1G,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI;AAAA,QACF,0DAA0D,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC5G;AAAA,IACF,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,2BAA2B,UAAoC;AAC3E,UAAM,SAAS,MAAM,KAAK,UAAU,GAAG;AACvC,QAAI;AACF,YAAM,SAAS,OAAO,MAAM,iBAAiB;AAC7C,YAAM,EAAE,UAAU,IAAI,MAAM,OAAO,KAAK,QAAQ,GAAG,OAAO,QAAQ,CAAC;AACnE,aAAO,aAAa,qBAAqB,gBAAgB,MAAM;AAAA,IACjE,UAAE;AACA,YAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,4BAA4B,UAAkB,SAAgC;AAClF,UAAM,SAAS,KAAK,yBAAyB,UAAU,qCAAqC;AAC5F,UAAM,KAAK,uBAAuB,QAAQ,OAAO;AAAA,EACnD;AAAA,EAEA,yBAA2C;AACzC,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK,gBAAgB;AAAA,MAC3B,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,MAAc,wBAAwB,UAAkB,SAAgC;AACtF,UAAM,WAAW,KAAK,mBAAmB,IAAI,QAAQ,KAAK,QAAQ,QAAQ;AAC1E,UAAM,UAAU,SAAS,MAAM,MAAM,MAAS,EAAE,KAAK,MAAM,KAAK,gCAAgC,UAAU,OAAO,CAAC;AAClH,UAAM,OAAO,QAAQ,MAAM,MAAM,MAAS;AAC1C,SAAK,mBAAmB,IAAI,UAAU,IAAI;AAC1C,QAAI;AACF,YAAM;AAAA,IACR,UAAE;AACA,UAAI,KAAK,mBAAmB,IAAI,QAAQ,MAAM,MAAM;AAClD,aAAK,mBAAmB,OAAO,QAAQ;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAc,sBAAsB,UAAoC;AACtE,QAAI;AACJ,QAAI;AACF,WAAK,MAAMH,MAAK,QAAQ;AAAA,IAC1B,SAAS,KAAK;AACZ,UAAI,YAAY,KAAK,QAAQ,EAAG,QAAO;AACvC,YAAM;AAAA,IACR;AACA,UAAM,SAAS,KAAK,+BAA+B,IAAI,QAAQ;AAC/D,QAAI,UAAU,OAAO,SAAS,SAAS,GAAG,QAAQ,OAAO,SAAS,YAAY,GAAG,SAAS;AACxF,aAAO,OAAO;AAAA,IAChB;AACA,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,KAAK,UAAU,GAAG;AAAA,IACnC,SAAS,KAAK;AACZ,UAAI,YAAY,KAAK,QAAQ,EAAG,QAAO;AACvC,YAAM;AAAA,IACR;AACA,QAAI;AACF,YAAM,SAAS,OAAO,MAAM,iBAAiB;AAC7C,YAAM,EAAE,UAAU,IAAI,MAAM,OAAO,KAAK,QAAQ,GAAG,OAAO,QAAQ,CAAC;AACnE,YAAM,YAAY,gBAAgB,OAAO,SAAS,GAAG,SAAS,CAAC;AAC/D,WAAK,+BAA+B,IAAI,UAAU;AAAA,QAChD,UAAU,EAAE,MAAM,GAAG,MAAM,SAAS,GAAG,QAAQ;AAAA,QAC/C;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT,UAAE;AACA,YAAM,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAc,gCAAgC,UAAkB,SAAgC;AAC9F,UAAM,WAAW,KAAK,gBAAgB;AACtC,UAAM,MAAMP,OAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAI,aAAa,MAAM;AACrB,UAAI;AAMF,YAAI,MAAM,KAAK,sBAAsB,QAAQ,GAAG;AAC9C,gBAAMW,YAAW,MAAM,KAAK,sBAAsB,QAAQ;AAC1D,gBAAM,wBAAwB,UAAU,GAAGA,SAAQ,GAAG,OAAO,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO;AACvF,eAAK,0BAA0B,QAAQ;AACvC;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,MACzC;AAQA,YAAM,WAAW,UAAU,SAAS,OAAO;AAC3C,WAAK,0BAA0B,QAAQ;AACvC;AAAA,IACF;AAKA,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAM,KAAK,sBAAsB,QAAQ;AAAA,IACtD,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,IACzC;AACA,UAAM,wBAAwB,UAAU,GAAG,QAAQ,GAAG,OAAO,IAAI,UAAU,CAAC,GAAG,KAAK,OAAO;AAC3F,SAAK,0BAA0B,QAAQ;AAAA,EACzC;AAAA,EACA,IAAY,WAAmB;AAC7B,WAAOX,OAAK,KAAK,KAAK,SAAS,OAAO;AAAA,EACxC;AAAA,EACA,IAAY,6BAAqC;AAC/C,WAAOA,OAAK,KAAK,KAAK,SAAS,iBAAiB,sBAAsB;AAAA,EACxE;AAAA,EACA,IAAY,2BAAmC;AAC7C,WAAOA,OAAK,KAAK,KAAK,UAAU,6BAA6B;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAY,iBAAyB;AACnC,WAAOA,OAAK,KAAK,KAAK,UAAU,kBAAkB;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBAAoB,QAKX;AACP,SAAK,mBAAmB,EAAE,GAAG,OAAO;AAEpC,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAW;AAC/B,WAAK,iBAAiB;AACtB,WAAK,4BAA4B;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,sBAAsC;AAC5C,UAAM,UAAiC;AAAA,MACrC,SAAS,KAAK,iBAAiB;AAAA,MAC/B,eAAe,KAAK,iBAAiB;AAAA,MACrC,mBAAmB,KAAK,iBAAiB;AAAA,MACzC,aAAa,iBAAiB;AAAA,MAC9B,eAAe,iBAAiB;AAAA;AAAA;AAAA;AAAA,MAIhC,4BAA4B,uCAAuC;AAAA,QACjE,gBAAgB,MAAM,KAAK;AAAA,QAC3B,gCAAgC,MAC9B,KAAK,gBAAgB,+BAA+B;AAAA,QACtD,6BAA6B,CAAC,WAAW,cACvC,KAAK,4BAA4B,WAAW,SAAS;AAAA,QACvD,iCAAiC,CAAC,YAChC,KAAK,gCAAgC,OAAO;AAAA,MAChD,CAAC;AAAA,IACH;AACA,UAAM,KAAsB;AAAA,MAC1B,MAAM,CAAC,aAAa,KAAK,sBAAsB,QAAQ;AAAA,MACvD,QAAQ,CAAC,UAAU,YAAY,KAAK,wBAAwB,UAAU,OAAO;AAAA,MAC7E,OAAO,CAAC,UAAU,YAAY,KAAK,uBAAuB,UAAU,OAAO;AAAA,MAC3E,MAAM,CAAC,aAAaC,UAAS,QAAQ;AAAA,IACvC;AACA,WAAO,IAAI,eAAe,KAAK,gBAAgB,KAAK,iBAAiB,WAAW,SAAS,EAAE;AAAA,EAC7F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,oBAA6C;AAC3C,QAAI,KAAK,gBAAgB;AAIvB,YAAM,SAAS,KAAK;AACpB,aAAO,OAAO,uBAAuB,EAAE,KAAK,MAAM,MAAM;AAAA,IAC1D;AACA,QAAI,CAAC,KAAK,2BAA2B;AACnC,YAAM,QAAQ,KAAK,oBAAoB;AACvC,WAAK,4BAA4B,MAC9B,KAAK,EACL,KAAK,MAAM;AACV,aAAK,iBAAiB;AACtB,eAAO;AAAA,MACT,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,aAAK,4BAA4B;AACjC,cAAM;AAAA,MACR,CAAC;AAAA,IACL;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,sBAA+B;AAC7B,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,OAUK;AACzB,QAAI,CAAC,KAAK,iBAAiB,QAAS,QAAO;AAC3C,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,kBAAkB;AAK3C,YAAM,qBAAqB,yBAAyB,MAAM,YAAY,KAAK,gBAAgB;AAE3F,aAAO,MAAiB;AAAA,QACtB,KAAK;AAAA,QACL;AAAA,QACA,MAAM,KAAK,qBAAqB;AAAA,QAChC,CAAC,aAAa,MAAM,gBAAgB,EAAE,GAAG,OAAO,YAAY,oBAAoB,GAAG,SAAS,CAAC;AAAA,QAC7F,CAAC,gBAAgB,MAAM,OAAO,aAAa,MAAM,SAAS;AAAA,QAC1D,MAAM;AAAA,MACR;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,KAAK,mCAAmC,MAAM,cAAc,MAAM,GAAG,EAAE;AAC3E,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,MAAM,kBAAkB,OAOH;AACnB,QAAI,CAAC,KAAK,iBAAiB,QAAS,QAAO;AAC3C,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,kBAAkB;AAC3C,aAAO,MAAM,MAAM,cAAc,KAAK;AAAA,IACxC,SAAS,KAAK;AACZ,UAAI,KAAK,wCAAwC,MAAM,cAAc,MAAM,GAAG,EAAE;AAChF,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBAAgB,aAAqB,WAAuD;AAChG,QAAI,CAAC,KAAK,iBAAiB,QAAS,QAAO;AAC3C,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,kBAAkB;AAC3C,aAAO,MAAM,MAAM,OAAO,aAAa,SAAS;AAAA,IAClD,SAAS,KAAK;AACZ,UAAI,KAAK,+BAA+B,WAAW,MAAM,GAAG,EAAE;AAC9D,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,oBAAoD;AACxD,QAAI,CAAC,KAAK,iBAAiB,QAAS,QAAO;AAC3C,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,kBAAkB;AAC3C,aAAO,MAAM,MAAM;AAAA,IACrB,SAAS,KAAK;AACZ,UAAI,KAAK,2BAA2B,GAAG,EAAE;AACzC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,6BAA8C;AAClD,QAAI,CAAC,KAAK,iBAAiB,QAAS,QAAO;AAC3C,UAAM,QAAQ,MAAM,KAAK,kBAAkB;AAC3C,UAAM,MAAM,CAAC,GAAI,MAAM,KAAK,gBAAgB,GAAI,GAAI,MAAM,KAAK,oBAAoB,CAAE;AAErF,UAAM,UAAU,iCAAiC,KAAK;AAAA,MACpD,eAAe,CAAC,SAAS,yBAAyB,MAAM,KAAK,gBAAgB;AAAA,MAC7E;AAAA,IACF,CAAC;AACD,WAAO,MAAM,MAAM,QAAQ,OAAO;AAAA,EACpC;AAAA,EACU,oCAA0C;AAClD,SAAK,6BAA6B;AAAA,EACpC;AAAA,EACU,sCAA2E;AACnF,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,WAAW,KAAK;AAAA,MAChB,wBAAwB,MAAM,KAAK;AAAA,MACnC,6BAA6B,MAAM,KAAK,gBAAgB;AAAA,MACxD,aAAa,MAAM,KAAK;AAAA,MACxB,aAAa,CAAC,UAAU,YACtB;AAAA,QACE;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACF,iBAAiB,MAAM,KAAK,gBAAgB;AAAA,MAC5C,qBAAqB,MAAM,KAAK,oBAAoB;AAAA,IACtD;AAAA,EACF;AAAA,EACA,MAAc,mBAA8C;AAC1D,QAAI,KAAK,eAAe;AACtB,aAAO,KAAK;AAAA,IACd;AACA,QAAI,CAAC,KAAK,0BAA0B;AAClC,YAAM,QAAQ,KAAK,uBAAuB;AAC1C,WAAK,2BAA2B,MAC7B,KAAK,EACL,KAAK,MAAM;AACV,aAAK,gBAAgB;AACrB,eAAO;AAAA,MACT,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,aAAK,2BAA2B;AAChC,cAAM;AAAA,MACR,CAAC;AAAA,IACL;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gCAA2D;AAC/D,QAAI,CAAE,MAAM,KAAK,iCAAiC,GAAI;AACpD,YAAM,IAAI,mCAAmC,KAAK,QAAQ;AAAA,IAC5D;AACA,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,yBAAoD;AACxD,UAAM,KAAK,iCAAiC;AAC5C,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EACA,MAAc,mCAAqD;AACjE,QAAI,KAAK,+BAA+B,MAAM;AAU5C,UAAI,KAAK,iBAAkB,MAAM,KAAK,cAAc,yBAAyB,GAAI;AAC/E,eAAO;AAAA,MACT;AACA,WAAK,6BAA6B;AAAA,IACpC;AACA,QAAI,KAAK,mCAAmC;AAC1C,aAAO,KAAK;AAAA,IACd;AACA,SAAK,6BAA6B;AAClC,SAAK,qCAAqC,YAAY;AAkBpD,YAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,YAAM,cAAc,KAAK,yBAAyB,oBAAoB;AACtE,YAAM,SAAS,KAAK,yBAAyB,eAAe;AAC5D,UAAI,YAAY;AAChB,eAAS,UAAU,GAAG,UAAU,aAAa,WAAW,GAAG;AACzD,oBAAY,MAAM,cAAc;AAAA,UAAiB,MAC/C,KAAK,+BAA+B,aAAa;AAAA,QACnD;AACA,YAAI,aAAa,YAAY,cAAc,EAAG;AAC9C,cAAM,OAAO,KAAK,IAAI,SAAS,KAAK,SAAS,qCAAqC;AAClF,cAAM,IAAI,QAAc,CAACW,aAAY,WAAWA,UAAS,IAAI,CAAC;AAAA,MAChE;AACA,WAAK,6BAA6B;AAClC,UAAI,CAAC,WAAW;AACd,YAAI;AAAA,UACF,4EAA4E,WAAW;AAAA,QAEzF;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAAG,EAAE,QAAQ,MAAM;AACjB,WAAK,oCAAoC;AAAA,IAC3C,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,+BAA+B,eAAgD;AAC3F,kBAAc,MAAM;AAcpB,UAAM,WAAW,CAAC,GAAI,MAAM,KAAK,gBAAgB,GAAI,GAAI,MAAM,KAAK,oBAAoB,CAAE;AAC1F,QAAI,kBAAkB;AACtB,eAAW,UAAU,UAAU;AAmB7B,UAAI,kBAAkB,OAAO,aAAa,OAAO,IAAI,MAAM,SAAU;AACrE,YAAM,SAAS,KAAK,uBAAuB,MAAM;AACjD,UAAI,OAAO,WAAW,GAAG;AAEvB;AACA;AAAA,MACF;AACA,iBAAW,QAAQ,QAAQ;AACzB,YAAI,OAAO,YAAY,aAAa,QAAQ;AAC1C,wBAAc,cAAc,IAAI;AAAA,QAClC,OAAO;AACL,wBAAc,UAAU,IAAI;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AACA,QAAI,kBAAkB,GAAG;AACvB,UAAI;AAAA,QACF,6CAA6C,eAAe;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAAA,EACQ,gCAAgC,SAA2B;AACjE,WAAO;AAAA,MAAgC;AAAA,MAAS,CAAC,UAC/C,uBAAuB,OAAO,KAAK,gBAAgB,IAAI,yBAAyB,OAAO,KAAK,gBAAgB,IAAI;AAAA,IAClH;AAAA,EACF;AAAA;AAAA,EAGQ,uBAAuB,QAA8B;AAC3D,UAAM,gBAAgB,OAAO,YAAY;AACzC,UAAM,aAAa,KAAK,gCAAgC,OAAO,OAAO,EACnE,IAAI,CAAC,YAAY,sBAAsB,OAAO,EAAE,IAAI;AACvD,UAAM,gBAAgB,WAAW,IAAI,CAAC,YAAY,iBAAiB,YAAY,OAAO,CAAC;AACvF,QAAI,iBAAiB,cAAc,SAAS,aAAa,EAAG,QAAO,CAAC,aAAa;AACjF,QAAI,CAAC,cAAe,QAAO,CAAC,cAAc,CAAC,KAAK,iBAAiB,YAAY,EAAE,CAAC;AAChF,UAAM,gBAAgB,WAAW;AAAA,MAC/B,CAAC,YAAY,yBAAyB,OAAO,MAAM;AAAA,IACrD;AACA,WAAO,cAAc,SAAS,IAC1B,CAAC,GAAG,IAAI,IAAI,cAAc,IAAI,CAAC,YAAY,iBAAiB,YAAY,OAAO,CAAC,CAAC,CAAC,IAClF,CAAC,aAAa;AAAA,EACpB;AAAA,EAEA,IAAY,eAAuB;AACjC,WAAOZ,OAAK,KAAK,KAAK,SAAS,WAAW;AAAA,EAC5C;AAAA,EACA,IAAY,eAAuB;AACjC,WAAOA,OAAK,KAAK,KAAK,SAAS,WAAW;AAAA,EAC5C;AAAA,EACA,IAAY,cAAsB;AAChC,WAAOA,OAAK,KAAK,KAAK,SAAS,UAAU;AAAA,EAC3C;AAAA,EACA,IAAY,qBAA6B;AACvC,WAAOA,OAAK,KAAK,KAAK,aAAa,oBAAoB;AAAA,EACzD;AAAA,EACA,IAAY,uBAA+B;AACzC,WAAOA,OAAK,KAAK,KAAK,aAAa,WAAW;AAAA,EAChD;AAAA,EACA,IAAY,0BAAkC;AAC5C,WAAOA,OAAK,KAAK,KAAK,aAAa,UAAU,QAAQ;AAAA,EACvD;AAAA,EACA,IAAY,2BAAmC;AAC7C,WAAOA,OAAK,KAAK,KAAK,aAAa,UAAU,SAAS;AAAA,EACxD;AAAA,EACA,IAAY,+BAAuC;AACjD,WAAOA,OAAK,KAAK,KAAK,aAAa,sBAAsB;AAAA,EAC3D;AAAA,EACA,IAAY,0BAAkC;AAC5C,WAAOA,OAAK,KAAK,KAAK,aAAa,gBAAgB;AAAA,EACrD;AAAA,EACA,IAAY,cAAsB;AAChC,WAAOA,OAAK,KAAK,KAAK,SAAS,YAAY;AAAA,EAC7C;AAAA,EACA,IAAY,oBAA4B;AACtC,WAAOA,OAAK,KAAK,KAAK,UAAU,sBAAsB;AAAA,EACxD;AAAA,EACA,IAAY,4BAAoC;AAC9C,WAAOA,OAAK,KAAK,KAAK,UAAU,+BAA+B;AAAA,EACjE;AAAA,EACA,IAAY,4BAAoC;AAC9C,WAAOA,OAAK,KAAK,KAAK,UAAU,2BAA2B;AAAA,EAC7D;AAAA,EACA,IAAY,gCAAwC;AAClD,WAAOA,OAAK,KAAK,KAAK,UAAU,iCAAiC;AAAA,EACnE;AAAA,EACA,IAAY,gCAAwC;AAClD,WAAOA,OAAK,KAAK,KAAK,UAAU,kCAAkC;AAAA,EACpE;AAAA,EACA,IAAY,qCAA6C;AACvD,WAAOA,OAAK,KAAK,KAAK,UAAU,wCAAwC;AAAA,EAC1E;AAAA,EACA,IAAY,sBAA8B;AACxC,WAAOA,OAAK,KAAK,KAAK,UAAU,wBAAwB;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,0BAAqG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWrG,6BAA+C,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWvE,IAAY,2BAAmC;AAC7C,WAAOA,OAAK,KAAK,KAAK,UAAU,8BAA8B;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,cAAsC,CAAC;AAAA,EAC9B,+BAA+B,IAAe,iCAAiC;AAAA,EACxF,uBAAyD;AAC/D,WAAO,KAAK,6BAA6B,IAAI,KAAK,QAAQ;AAAA,EAC5D;AAAA;AAAA,EAEQ;AAAA,EACR,IAAY,kBAAmC;AAC7C,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,mBAAmB,IAAI,gBAAgB;AAAA,QAC1C,UAAU,KAAK;AAAA,QACf,SAAS,KAAK;AAAA,QACd,sBAAsB,MAAM,KAAK,qBAAqB;AAAA,QACtD;AAAA,QACA,6BAA6B,CAAC,UAAU,aAAa,aAAa,YAChE,KAAK,4BAA4B,UAAU,aAAa,aAAa,OAAO;AAAA,QAC9E,4BAA4B,MAAM,KAAK,2BAA2B;AAAA,QAClE,mBAAmB,MAAM,KAAK,kBAAkB;AAAA,QAChD,mBAAmB,MAAM,KAAK,iBAAiB;AAAA,QAC/C,qBAAqB,MAAM,KAAK,iBAAiB;AAAA,MACnD,CAAC;AAAA,IACH;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EACiB,6BAA6B,IAAI;AAAA,IAChD,MAAM,EAAE,KAAK,wBAAwB,CAAC,KAAK,sBAAsB;AAAA,IACjE,MAAM,KAAK,oCAAoC;AAAA,IAC/C,MAAsB,eAAe,KAAK,SAAS,KAAK,aAAa,MAAM,OAAO,KAAK,yBAAyB,CAAC,CAAC;AAAA,EACpH;AAAA,EACA,oBAAoB,KAAa,MAAsB;AACrD,WAAkB;AAAA,MAChB,KAAK,YAAY,oBAAoB,KAAK,IAAI;AAAA,MAC9C,KAAK,qBAAqB;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,gBAAkD;AACpD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAA6B;AACjC,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,YAAYA,OAAK,KAAK,KAAK,SAAS,UAAU,cAAc;AAClE,SAAK,cAAc,CAAC;AACpB,UAAM,MAAM,0BAA0B,KAAK,OAAO;AAClD,QAAI,QAAQ,OAAW;AACvB,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,GAAG;AAAA,IACzB,QAAQ;AACN,UAAI,MAAM,gEAA2D;AACrE;AAAA,IACF;AACA,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC3E,YAAM,UAAkC,CAAC;AACzC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,YAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,6BAAmB,KAAK;AACxB,kBAAQ,GAAG,IAAI;AAAA,QACjB;AAAA,MACF;AACA,WAAK,cAAc;AACnB,UAAI,MAAM,UAAU,OAAO,KAAK,OAAO,EAAE,MAAM,wBAAwB,SAAS,EAAE;AAAA,IACpF,OAAO;AACL,UAAI,KAAK,YAAY,SAAS,0EAAqE;AAAA,IACrG;AAAA,EACF;AAAA,EACA,MAAc,sCAAmE;AAC/E,UAAM,wBAAwB,MAAM;AAAA,MAClC;AAAA,MACA,CAAC,YAAY,gBAAgB,SAAS,KAAK,aAAa;AAAA,MACxD,CAAC,WAAW,oBAAoB,QAAQ,KAAK,eAAe,KAAK,sBAAsB,CAAC;AAAA,MACxF,gCAAgC,oBAAoB;AAAA,IACtD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBAAmC;AACvC,UAAM,MAAM,KAAK,SAAS,EAAE,WAAW,KAAK,CAAC;AAC7C,UAAsB,cAAc,KAAK,SAAS,KAAK,aAAa,KAAK,UAAU,KAAK,UAAU;AAClG,UAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,UAAM,MAAMA,OAAK,KAAK,KAAK,UAAU,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,UAAM,MAAMA,OAAK,KAAK,KAAK,eAAe,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;AACrE,UAAM,MAAMA,OAAK,KAAK,KAAK,oBAAoB,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1E,UAAM,MAAM,KAAK,gBAAgB,EAAE,WAAW,KAAK,CAAC;AACpD,UAAM,MAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAM,MAAM,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,MAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAClD,UAAM,MAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAClD,UAAM,MAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAM,MAAM,KAAK,sBAAsB,EAAE,WAAW,KAAK,CAAC;AAC1D,UAAM,MAAM,KAAK,yBAAyB,EAAE,WAAW,KAAK,CAAC;AAC7D,UAAM,MAAM,KAAK,0BAA0B,EAAE,WAAW,KAAK,CAAC;AAC9D,UAAM,MAAMA,OAAK,KAAK,KAAK,SAAS,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClE,UAAM,KAAK,2BAA2B,OAAO;AAW7C,QAAI,KAAK,2BAA2B,KAAK,uBAAuB,MAAM,GAAG;AACvE,WAAK,wBAAwB;AAAA,IAC/B;AACA,UAAM,KAAK,2BAA2B,2BAA2B;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAc,yBAAyB,UAA0B,IAAY,OAAgC;AAC3G,QAAI,aAAa,cAAc;AAC7B,YAAM,MAAM,KAAK,gBAAgB,EAAE,WAAW,KAAK,CAAC;AACpD,aAAOA,OAAK,KAAK,KAAK,gBAAgB,GAAG,EAAE,KAAK;AAAA,IAClD;AACA,UAAM,WAAWA,OAAK,KAAK,eAAe,KAAK,SAAS,QAAQ,GAAG,KAAK;AACxE,UAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AACzC,WAAOA,OAAK,KAAK,UAAU,GAAG,EAAE,KAAK;AAAA,EACvC;AAAA,EAEA,MAAc,mCACZ,SACA,UACA,iBAC4B;AAC5B,UAAM,WAAW,6BAA6B,SAAS,UAAU,eAAe;AAChF,UAAM,WAAW,CAAC,GAAI,MAAM,KAAK,gBAAgB,GAAI,GAAI,MAAM,KAAK,oBAAoB,CAAE;AAC1F,WACE,SAAS,KAAK,CAAC,WAAW;AACxB,UAAI,OAAO,YAAY,WAAW,oBAAoB,CAAC,OAAO,YAAY,UAAW,QAAO;AAC5F,aACE;AAAA,QACE,OAAO;AAAA,QACP,OAAO,YAAY;AAAA,QACnB,OAAO,YAAY;AAAA,MACrB,MAAM;AAAA,IAEV,CAAC,KAAK;AAAA,EAEV;AAAA;AAAA;AAAA,EAIQ,YAAY,IAA0C;AAC5D,QAAI,KAAK,sBAAsB,KAAK,GAAG,SAAS,OAAW,IAAG,OAAO,iBAAiB,EAAE;AACxF,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YACJ,UACA,SACA,UAA8B,CAAC,GAC/B;AACA,UAAM,KAAK,kBAAkB;AAC7B,UAAM,eAAe,QAAQ;AAC7B,QAAI,SAAS,OAAO,QAAQ,cAAc,WAAW,KAAK,qBAAqB,IAAI;AACnF,QAAI,OAAQ,WAAqB,4BAA4B,SAAS,MAAM;AAC5E,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AAC3C,UAAM,KAAK,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC9E,UAAM,OAAO,QAAQ,cAAc;AACnC,UAAM,OAAO,eAAe,IAAI;AAChC,UAAM,UAAU,8BAA8B,WAAW,QAAQ,OAAO;AACxE,UAAM,aAAa,8BAA8B,cAAc,QAAQ,UAAU;AAGjF,QAAI;AACJ,QAAI,OAAO,QAAQ,cAAc,YAAY,QAAQ,UAAU,SAAS,GAAG;AACzE,kBAAY,QAAQ;AAAA,IACtB,WAAW,SAAS,eAAe;AACjC,YAAM,SAAS,IAAI,KAAK,IAAI,QAAQ,IAAI,uBAAuB,KAAK,KAAK,KAAK,GAAI;AAClF,kBAAY,OAAO,YAAY;AAAA,IACjC;AAEA,UAAM,KAAwB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,SAAS,IAAI,YAAY;AAAA,MACzB,SAAS,IAAI,YAAY;AAAA,MACzB,UAAU,mBAAmB,OAAO;AAAA,MACpC,QAAQ,QAAQ,UAAU;AAAA,MAC1B,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,WAAW,QAAQ;AAAA,MACnB,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,YAAY,QAAQ;AAAA,MACpB,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,kBAAkB,QAAQ;AAAA,MAC1B,mBAAmB,QAAQ;AAAA,MAC3B,cAAc,QAAQ;AAAA,MACtB,gBAAgB,QAAQ;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,YAAY,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV;AAAA,MACA,iBAAiB,QAAQ;AAAA,MACzB,YAAY,8BAA8B,aAAa,QAAQ,SAAS;AAAA,MACxE,sBAAsB,QAAQ;AAAA,IAChC;AACA,QAAI,QAAQ,WAAW,QAAW;AAChC,SAAG,SAAS,QAAQ;AAAA,IACtB;AAWA,QAAI,QAAQ,gBAAgB,UAAa,QAAQ,YAAY,SAAS,GAAG;AACvE,SAAG,eAAe,QAAQ;AAAA,IAC5B;AACA,QAAI,QAAQ,eAAe,QAAW;AACpC,SAAG,cAAc,QAAQ;AAAA,IAC3B;AAEA,QAAI,QAAQ,iBAAiB,QAAW;AACtC,SAAG,eAAe,QAAQ;AAAA,IAC5B;AAGA,QAAI,QAAQ,YAAY,QAAW;AACjC,SAAG,UAAU,QAAQ;AAAA,IACvB;AACA,QAAI,QAAQ,eAAe,QAAW;AACpC,SAAG,aAAa,QAAQ;AAAA,IAC1B;AACA,QAAI,QAAQ,oBAAoB,QAAW;AACzC,SAAG,kBAAkB,QAAQ;AAAA,IAC/B;AACA,QAAI,QAAQ,WAAW,OAAW,IAAG,SAAS,iBAAiB,QAAQ,MAAM;AAC7E,QAAI,QAAQ,YAAY,OAAW,IAAG,UAAU,QAAQ;AAIxD,UAAM,YAAY,sBAAsB,SAAS,QAAQ,oBAAoB;AAC7E,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,gCAAgC,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,IAC9F;AACA,QACE,QAAQ,cACR,sCAAsC;AAAA,MACpC,SAAS,UAAU;AAAA,MACnB,iBAAiB,QAAQ;AAAA,IAC3B,CAAC,GACD;AACA,SAAG,aAAa;AAAA,IAClB;AAMA,QAAI,6BAA4C;AAChD,QAAI,aAAa,QAAQ;AACvB,YAAM,aACJ,QAAQ,sBAAsB,UAAa,QAAQ,kBAAkB,SAAS,IAC1E,sBAAsB,QAAQ,iBAAiB,EAAE,OACjD,UAAU;AAChB,SAAG,cAAc,iBAAiB,YAAY,UAAU;AACxD,mCAA6B;AAAA,IAC/B;AAOA,QAAI,UAAU,OAAO,iBAAiB,YAAY,KAAK,qBAAqB,MAAM,QAAQ;AACxF,eAAS,KAAK,qBAAqB;AACnC,SAAG,YAAuB,mCAAmC,cAAc,MAAM;AAAA,IACnF;AACA,QAAIa,oBAAmB;AACvB,QAAI;AACJ,QAAI;AAEJ,UAAM,qBAAqB,YAA2B;AACpD,UAAIA,mBAAkB;AACpB,YAAI,GAAG,cAAc,QAAS;AAC9B,QAAAA,oBAAmB;AACnB,WAAG,SAAS;AACZ,eAAO,GAAG;AACV,eAAO,GAAG;AAAA,MACZ;AACA,UAAI,aAAa,UAAU,+BAA+B,KAAM;AAChE,YAAM,eAAe,GAAG;AACxB,YAAM,QAAQ,MAAM,KAAK,gBAAgB,KAAK,IAAI,UAAU,MAAM,QAAQ,oBAAoB;AAC9F,UAAI,OAAO;AACT,kBAAU,GAAG;AACb,4BAAoB;AACpB,QAAAA,oBAAmB;AAAA,MACrB;AAAA,IACF;AACA,UAAM,mBAAmB;AAEzB,UAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,EAAE,CAAC,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AAEtF,UAAM,WAAW,MAAM,KAAK,yBAAyB,UAAU,IAAI,KAAK;AACxE,UAAM,cAAc,YAAwC;AAC1D,UAAIA,mBAAkB;AACpB,cAAM,YAAY,MAAM,KAAK,mCAAmC,UAAU,MAAM,UAAU,GAAG,eAAe;AAC5G,YAAI,UAAW,QAAO;AAAA,MACxB;AACA,YAAM,KAAK,oBAAoB,UAAU,OAAO;AAChD,YAAM,KAAK,4BAA4B,UAAU,aAAa,IAAI,UAAU,MAAM,YAAY;AAC5F,aAAK,2BAA2B;AAAA,MAClC,CAAC;AACD,UAAI,UAAU,OAAO,iBAAiB,UAAU;AAC9C,cAAM,kBAAkB,GAAG;AAC3B,YAAI;AACF,gBAAiB,gCAAgC;AAAA,YAC/C,UAAU,KAAK;AAAA,YACf,YAAY,MAAM,KAAK,qBAAqB;AAAA,YAC5C,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,SAAS,YAAY;AACnB,oBAAM,mBAAmB;AACzB,oBAAM,KAAK;AAAA,gBACT;AAAA,gBACA,GAAG,qBAAqB,KAAK,YAAY,EAAE,CAAC,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AAAA,gBAClE;AAAA,gBACA,UAAU;AAAA,gBACV,YAAY,KAAK,2BAA2B;AAAA,cAC9C;AACA,mBAAK,2BAA2B;AAAA,YAClC;AAAA,UACF,CAAC;AAAA,QACH,SAAS,KAAK;AACZ,gBAAMV,QAAO,QAAQ,EAAE,MAAM,MAAM,MAAS;AAC5C,eAAK,2BAA2B;AAChC,gBAAM,KAAK,uDAAuD,QAAQ;AAC1E,gBAAM;AAAA,QACR;AACA,cAAM,KAAK,gBAAgB,eAAe,IAAI,iBAAiB,GAAG,SAAS;AAAA,MAC7E;AACA,aAAO;AAAA,IACT;AACA,UAAM,mBAAmB,MAAM,KAAK,qCAAqC,aAAa;AAAA,MACpF,6BAA6B,QAAQ;AAAA,MACrC,6BAA6B,UAAU,MAAM,UAAU,GAAG,eAAe;AAAA,IAC3E,CAAC;AACD,QAAI,kBAAkB;AACpB,aAAO;AAAA,QACL,IAAI,iBAAiB,YAAY;AAAA,QACjC,kBAAkB;AAAA,QAClB,WAAW,iBAAiB,YAAY;AAAA,QACxC,aAAa,iBAAiB,YAAY;AAAA,QAC1C,QAAQ;AAAA,MACV;AAAA,IACF;AACA,UAAM,KAAK,sBAAsB,EAAE,WAAW,SAAS,GAAG,eAAe;AACzE,SAAK,kBAAkB,QAAQ;AAC/B,UAAM,KAAK,4CAA4C,uBAAuB;AAAA,MAC5E,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW,GAAG;AAAA,MACd,OAAO,QAAQ,SAAS;AAAA,MACxB,OAAO,KAAK,wBAAwB,IAAI,QAAQ;AAAA,MAChD,kBAAkB;AAAA,QAChB,GAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,QACjD,IAAI,QAAQ,WAAW,CAAC,GAAG,OAAO,OAAO;AAAA,MAC3C;AAAA,IACF,CAAC;AACD,QAAI,aAAa,UAAU,CAACU,mBAAkB;AAI5C,UAAI;AACF,cAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAIlD,cAAM,WACJ,QAAQ,sBAAsB,UAAa,QAAQ,kBAAkB,SAAS,IAC1E,sBAAsB,QAAQ,iBAAiB,EAAE,OACjD,UAAU;AAChB,sBAAc,QAAQ,QAAQ;AAS9B,YAAI,CAAC,QAAQ,oBAAoB;AAC/B,gBAAM,cAAc,oBAAoB;AAQxC,gBAAM,cAAc,oBAAoB;AAAA,QAC1C;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,KAAK,uEAAuE,GAAG,EAAE;AAAA,MACvF;AAAA,IACF;AACA,QAAI,MAAM,gBAAgB,EAAE,OAAO,QAAQ,EAAE;AAC7C,WAAO,EAAE,IAAI,kBAAAA,mBAAkB,GAAI,GAAG,YAAY,EAAE,WAAW,GAAG,UAAU,IAAI,CAAC,GAAI,QAAQ,EAAE,MAAM,UAAU,aAAa,IAAI,SAAS,UAAU,KAAK,EAAE;AAAA,EAC5J;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,kBAAkB,UAAgC,SAA4B,CAAC,GAAG;AACtF,QAAI,CAAC,uBAAuB,QAAQ,GAAG;AACrC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,EAAE,UAAU,SAAS,QAAQ,IAAI,wBAAwB,UAAU,MAAM;AAC/E,WAAO,KAAK,YAAY,UAAU,SAAS,OAA6B;AAAA,EAC1E;AAAA,EAEA,MAAM,mBAAmB,SAAmC;AAC1D,UAAM,gBAAgB,MAAM,KAAK,iCAAiC;AAClE,UAAM,YAAY,sBAAsB,OAAO;AAC/C,UAAM,OAAO,iBAAiB,YAAY,UAAU,IAAI;AAexD,QAAI,eAAe;AACjB,YAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,aAAO,cAAc,QAAQ,UAAU,IAAI;AAAA,IAC7C;AACA,WAAO,MAAM,KAAK,+BAA+B,IAAI;AAAA,EACvD;AAAA,EAEA,MAAc,+BAA+B,YAAsC;AACjF,UAAM,WAAW,CAAC,GAAI,MAAM,KAAK,gBAAgB,GAAI,GAAI,MAAM,KAAK,oBAAoB,CAAE;AAC1F,eAAW,UAAU,UAAU;AAC7B,UAAI,OAAO,YAAY,aAAa,OAAQ;AAC5C,UAAI,kBAAkB,OAAO,aAAa,OAAO,IAAI,MAAM,SAAU;AACrE,UAAI,KAAK,uBAAuB,MAAM,EAAE,SAAS,UAAU,EAAG,QAAO;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,4BAA4B,QAA8B;AAChE,QAAI,OAAO,YAAY,aAAa,OAAQ,QAAO,CAAC;AACpD,WAAO,KAAK,uBAAuB,MAAM;AAAA,EAC3C;AAAA,EAEA,MAAc,yBAAyB,QAAmC;AACxE,QAAI,OAAO,YAAY,aAAa,OAAQ;AAC5C,QAAI,kBAAkB,OAAO,aAAa,OAAO,IAAI,MAAM,SAAU;AACrE,UAAM,SAAS,KAAK,4BAA4B,MAAM;AACtD,QAAI,OAAO,WAAW,EAAG;AAEzB,UAAM,KAAK,iCAAiC;AAC5C,UAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,eAAW,QAAQ,QAAQ;AACzB,oBAAc,cAAc,IAAI;AAAA,IAClC;AAMA,UAAM,cAAc,oBAAoB;AASxC,UAAM,cAAc,oBAAoB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,6BAA6B,UAAiC;AAClE,UAAM,MAAM,MAAM,KAAK,gBAAgB;AACvC,UAAM,SAAS,IAAI,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,QAAQ;AAC5D,QAAI,CAAC,OAAQ;AACb,UAAM,KAAK,yBAAyB,MAAM;AAAA,EAC5C;AAAA,EAEA,MAAc,8BAA8B,QAAoB,OAAkC;AAChG,QAAI,OAAO,YAAY,aAAa,UAAU,MAAM,YAAY,aAAa,OAAQ;AAErF,UAAM,eAAe,KAAK,4BAA4B,MAAM;AAC5D,UAAM,cAAc,KAAK,4BAA4B,KAAK;AAC1D,UAAM,eAAe,kBAAkB,OAAO,aAAa,OAAO,IAAI;AACtE,UAAM,cAAc,kBAAkB,MAAM,aAAa,MAAM,IAAI;AACnE,UAAM,gBACJ,aAAa,WAAW,YAAY,UACpC,aAAa,KAAK,CAAC,MAAM,UAAU,SAAS,YAAY,KAAK,CAAC;AAChE,QAAI,CAAC,iBAAiB,iBAAiB,YAAa;AAEpD,QAAI,iBAAiB,YAAY,aAAa,SAAS,MAAM,iBAAiB,gBAAgB,WAAW;AACvG,YAAM,KAAK,mCAAmC,CAAC,MAAM,CAAC;AAAA,IACxD;AACA,QAAI,gBAAgB,YAAY,YAAY,SAAS,MAAM,iBAAiB,iBAAiB,WAAW;AACtG,YAAM,KAAK,yBAAyB,KAAK;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,mCAAmC,UAAuC;AAC9E,UAAM,KAAK,iCAAiC;AAC5C,UAAM,gBAAgB,MAAM,KAAK,iBAAiB;AAClD,UAAM,aAAa,IAAI;AAAA,MACrB,SACG,IAAI,CAAC,WAAW,OAAO,YAAY,EAAE,EACrC,OAAO,CAAC,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC;AAAA,IACzE;AACA,UAAM,gBAAgB,oBAAI,IAAY;AACtC,eAAW,UAAU,UAAU;AAC7B,iBAAW,QAAQ,KAAK,4BAA4B,MAAM,GAAG;AAC3D,sBAAc,IAAI,IAAI;AAAA,MACxB;AAAA,IACF;AACA,QAAI,cAAc,SAAS,EAAG;AAE9B,UAAM,wBAAwB,oBAAI,IAAY;AAC9C,UAAM,oBAAoB,CAAC,GAAI,MAAM,KAAK,gBAAgB,GAAI,GAAI,MAAM,KAAK,oBAAoB,CAAE;AACnG,eAAW,UAAU,mBAAmB;AACtC,UAAI,OAAO,YAAY,aAAa,OAAQ;AAC5C,UAAI,WAAW,IAAI,OAAO,YAAY,EAAE,EAAG;AAC3C,UAAI,kBAAkB,OAAO,aAAa,OAAO,IAAI,MAAM,SAAU;AACrE,iBAAW,QAAQ,KAAK,4BAA4B,MAAM,GAAG;AAC3D,8BAAsB,IAAI,IAAI;AAAA,MAChC;AAAA,IACF;AAEA,eAAW,QAAQ,eAAe;AAChC,UAAI,CAAC,sBAAsB,IAAI,IAAI,GAAG;AACpC,sBAAc,aAAa,IAAI;AAC/B,sBAAc,iBAAiB,IAAI;AAAA,MACrC;AAAA,IACF;AAOA,UAAM,cAAc,oBAAoB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,4BAA4B,QAA0B;AACpD,QAAI,OAAO,YAAY,aAAa,OAAQ;AAC5C,UAAM,gBAAgB,KAAK;AAC3B,QAAI,CAAC,cAAe;AACpB,eAAW,QAAQ,KAAK,4BAA4B,MAAM,GAAG;AAC3D,oBAAc,iBAAiB,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,iCAAmD;AACvD,WAAO,MAAM,KAAK,iCAAiC;AAAA,EACrD;AAAA,EAEA,MAAM,cACJ,OACA,UAYI,CAAC,GACY;AACjB,UAAM,KAAK,kBAAkB;AAC7B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,MAAM,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AACzC,UAAM,MAAMb,OAAK,KAAK,KAAK,cAAc,GAAG;AAC5C,UAAM,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAEpC,UAAM,KAAK,YAAY,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC3E,UAAM,KAAwB;AAAA,MAC5B;AAAA,MACA,UAAU;AAAA,MACV,SAAS,IAAI,YAAY;AAAA,MACzB,SAAS,IAAI,YAAY;AAAA,MACzB,QAAQ;AAAA,MACR,YAAY,QAAQ,cAAc;AAAA,MAClC,gBAAgB,eAAe,QAAQ,cAAc,GAAG;AAAA,MACxD,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,cAAc,QAAQ,gBAAgB;AAAA,MACtC,gBAAgB,QAAQ;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,YAAY,QAAQ;AAAA,MACpB,kBAAkB,QAAQ;AAAA,MAC1B,mBAAmB,QAAQ;AAAA,MAC3B,GAAI,QAAQ,kBAAkB,EAAE,iBAAiB,QAAQ,gBAAgB,IAAI,CAAC;AAAA,MAC9E,GAAI,QAAQ,SAAS,EAAE,QAAQ,iBAAiB,QAAQ,MAAM,EAAE,IAAI,CAAC;AAAA,MACrE,GAAI,QAAQ,aAAa,EAAE,YAAY,KAAc,IAAI,CAAC;AAAA,IAC5D;AAEA,UAAM,YAAY,sBAAsB,KAAK;AAC7C,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,iCAAiC,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAC7F,aAAO;AAAA,IACT;AACA,UAAM,WAAWA,OAAK,KAAK,KAAK,GAAG,EAAE,KAAK;AAC1C,UAAM,KAAK,uBAAuB,UAAU,GAAG,qBAAqB,KAAK,YAAY,EAAE,CAAC,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA,CAAI;AAClH,UAAM,QACJ,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,SAAS,IAAI,QAAQ,QAAQ;AAClF,UAAM,KAAK,4CAA4C,yBAAyB;AAAA,MAC9E,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW,GAAG;AAAA,MACd;AAAA,MACA,OAAO,KAAK,wBAAwB,IAAI,QAAQ;AAAA,MAChD,kBAAkB,QAAQ,iBAAiB,CAAC,QAAQ,cAAc,IAAI,CAAC;AAAA,IACzE,CAAC;AACD,SAAK,yBAAyB;AAG9B,SAAK,qBAAqB;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,uBAAuB,SAAoD;AACvF,WAAO,KAAK,gBAAgB,uBAAuB,OAAO;AAAA,EAC5D;AAAA,EAEA,MAAM,gBACJ,OACA,YACA,UAAiC,CAAC,GACX;AACvB,WAAO;AAAA,MACL,MAAM,KAAK,uBAAuB,EAAE,aAAa,QAAQ,YAAY,CAAC;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,YACJ,MACA,MACA,OACA,UAOI,CAAC,GACY;AACjB,WAAO,KAAK,YAAY,YAAY,MAAM,MAAM,OAAO,OAAO;AAAA,EAChE;AAAA,EAEA,MAAM,cAA+B;AACnC,QAAI;AACF,aAAO,2BAA2B,MAAM,uBAAuB,KAAK,aAAa,KAAK,iBAAiB,KAAK,OAAO,CAAC;AAAA,IACtH,SAAS,OAAO;AACd,UAAI,iBAAiB,wBAAwB;AAC3C,cAAM;AAAA,MACR;AACA,UAAI,YAAY,OAAO,QAAQ,EAAG,QAAO;AACzC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,SAAgC;AACjD,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,iBAAiB;AAAA,MACrB,6BAA6B,SAAS,SAAS;AAAA,MAC/C;AAAA,MACA,KAAK,sBAAsB;AAAA,IAC7B;AACA,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,oBAAoB,KAAK,aAAa,eAAe;AAChE,UAAM,KAAK,uBAAuB,KAAK,aAAa,cAAc;AAClE,QAAI,MAAM,oBAAoB;AAAA,EAChC;AAAA,EAEA,OAAe,kBAAkB,GAAmB;AAClD,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,WAAO,EACJ,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,QAAQ,QAAQ,GAAG,EACnB,KAAK;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe,iBAAiB,SAAiB,eAAkC;AACjF,eAAW,YAAY,eAAe;AAEpC,UAAI,YAAY,SAAU,QAAO;AAGjC,YAAM,UAAU,QAAQ,UAAU,SAAS,SAAS,UAAU;AAC9D,YAAM,SAAS,QAAQ,SAAS,SAAS,SAAS,UAAU;AAC5D,UAAI,QAAQ,SAAS,MAAM,QAAQ,SAAS,OAAO,SAAS,OAAO,OAAO,SAAS,OAAO,GAAG;AAC3F,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,SAAkC;AAEtD,cAAU,QAAQ,OAAO,CAAC,MAAM,OAAO,MAAM,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC;AAC5E,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,WAAW,MAAM,KAAK,YAAY;AAExC,UAAM,QAAQ,WAAW,SAAS,MAAM,IAAI,IAAI,CAAC;AACjD,UAAM,oBAAoB,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;AAC9F,UAAM,gBAAgB,kBAAkB,IAAI,gBAAe,iBAAiB;AAE5E,UAAM,aAAa,QAAQ,OAAO,CAAC,MAAM;AACvC,YAAM,OAAO,gBAAe,kBAAkB,CAAC;AAC/C,aAAO,CAAC,gBAAe,iBAAiB,MAAM,aAAa;AAAA,IAC7D,CAAC;AACD,QAAI,WAAW,WAAW,EAAG;AAE7B,QAAI,CAAC,UAAU;AACb,YAAM,UAAU,CAAC,wBAAwB,IAAI,GAAG,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,IAAI;AAC9F,YAAM,KAAK,aAAa,OAAO;AAAA,IACjC,OAAO;AACL,YAAM,cAAc,SAAS,QAAQ,IAAI,OAAO,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI;AAC7F,YAAM,KAAK,aAAa,WAAW;AAAA,IACrC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,0BAA0B,cAAyC;AACvE,UAAM,UAAU,MAAM,KAAK,YAAY;AACvC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAY,QAAQ,MAAM,IAAI,EAAE;AACtC,UAAM,YACJ,OAAO,iBAAiB,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,CAAC,IAAI,gBAAe;AAC5F,WAAO,YAAY;AAAA,EACrB;AAAA,EAEQ,uBAAoD,QAAc;AACxE,QAAI,WAAW,QAAQ,CAAC,gBAAe,sBAAsB,IAAI,MAAM,GAAG;AACxE,sBAAe,sBAAsB,IAAI,QAAQ,qBAAqB,MAAM,CAAC;AAAA,IAC/E;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,UAAsC;AACpE,eAAW,UAAU,SAAU,MAAK,uBAAuB,MAAM;AACjE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,SAAoD;AACxE,yBAAqB,OAAO;AAC5B,QAAI,KAAK,yBAAyB;AAChC,YAAM,SAAS;AAAA,QACb,KAAK;AAAA,QACL,KAAK,uBAAuB;AAAA,QAC5B,KAAK,cAAc;AAAA,QACnB,KAAK,cAAc;AAAA,MACrB;AACA,UAAI,WAAW,KAAM,QAAO,KAAK,wBAAwB,MAAM;AAAA,IACjE;AAQA,UAAM,QAAQ,KAAK,cAAc;AACjC,UAAM,WAAW,qBAAqB,KAAK,SAAS,OAAO,SAAS,WAAW;AAC/E,QAAI,UAAU;AAIZ,UAAI;AACF,eAAO,KAAK;AAAA,UACV,MAAM,UAAU,SAAS,MAAM,SAAS,aAAa,qBAAqB;AAAA,QAC5E;AAAA,MACF,UAAE;AACA,iBAAS,OAAO,MAAM;AAAA,MACxB;AAAA,IACF;AAIA,UAAM,OAAO,mBAAmB,KAAK,SAAS,OAAO,SAAS,WAAW;AACzE,UAAM,eAAe,YAAmC;AACtD,YAAM,UAAU,KAAK,uBAAuB;AAC5C,YAAM,WAAW,MAAM,KAAK,yBAAyB,EAAE,aAAa,KAAK,WAAW,CAAC;AAOrF,UAAI,KAAK,2BAA2B,KAAK,uBAAuB,MAAM,WAAW,KAAK,cAAc,MAAM,OAAO;AAC/G,0BAAkB,KAAK,SAAS,UAAU,SAAS,OAAO,KAAK,cAAc,CAAC;AAAA,MAChF;AACA,aAAO;AAAA,IACT,GAAG;AACH,SAAK,IAAI,WAAW;AACpB,QAAI;AAQF,aAAO,KAAK;AAAA,QACV,MAAM,UAAU,aAAa,SAAS,aAAa,qBAAqB;AAAA,MAC1E;AAAA,IACF,UAAE;AACA,WAAK,MAAM;AACX,yBAAmB,KAAK,SAAS,OAAO,WAAW;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mCAAyC;AACvC,SAAK,2BAA2B;AAAA,EAClC;AAAA;AAAA,EAGA,+BAA+B,OAAmD;AAChF,QAAI,aAAa;AACjB,QAAI,cAAc;AAClB,QAAI,iBAAiB;AACrB,eAAW,QAAQ,OAAO;AACxB,UAAI,SAAS,QAAQ;AACnB,sBAAc;AAAA,MAChB,WAAW,SAAS,WAAW;AAC7B,qBAAa;AACb,yBAAiB;AAAA,MACnB,WAAW,SAAS,OAAO;AACzB,qBAAa;AAAA,MACf;AAAA,IACF;AACA,QAAI,WAAY,MAAK,2BAA2B;AAChD,IAAQ,6BAA6B,KAAK,SAAS,cAAc;AACjE,QAAI,aAAa;AACf,WAAK,4BAA4B;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,OAAO,uBAA6B;AAClC,uBAAmB;AACnB,oBAAe,eAAe,MAAM;AACpC,oBAAe,kBAAkB,MAAM;AACvC,oBAAe,0BAA0B,MAAM;AAC/C,oBAAe,yBAAyB,MAAM;AAC9C,oBAAe,yBAAyB,MAAM;AAC9C,oBAAe,2BAA2B,MAAM;AAChD,oBAAe,sBAAsB,MAAM;AAC3C,qBAAiB;AACjB,oBAAe,6BAA6B,MAAM;AAClD,oBAAe,yBAAyB,MAAM;AAC9C,oBAAe,0BAA0B;AACzC,oBAAe,wBAAwB;AACvC,oBAAe,uCAAuC;AACtD,oBAAe,6BAA6B,MAAM;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcU,6BAAmC;AAC3C,8BAA0B,KAAK,OAAO;AAItC,SAAK,wBAAwB;AAW7B,QAAI,gBAAe,6BAA6B,IAAI,KAAK,OAAO,KAAK,MAAM;AACzE,yBAAmB,KAAK,SAAS,eAAe;AAAA,IAClD,OAAO;AACL,0BAAoB,KAAK,OAAO;AAAA,IAClC;AAKA,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAW;AAC/B,WAAK,iBAAiB;AACtB,WAAK,4BAA4B;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAc,sBACZ,MACA,QAA2C,iBAC5B;AACf,UAAM,cAAc,KAAK,uBAAuB;AAIhD,UAAM,QAAQ,KAAK,cAAc;AACjC,UAAM,OACJ,KAAK,2BACL,kBAAkB,KAAK,SAAS,aAAa,OAAO,KAAK,cAAc,CAAC,MAAM;AAChF,QAAI,QAAQ,KAAK,gBAAgB,UAAa,CAAC,KAAK,wBAAwB,KAAK,WAAW,GAAG;AAC7F,0BAAoB,KAAK,SAAS,KAAK,aAAa,KAAK;AAAA,IAC3D;AASA,UAAM,EAAE,UAAU,UAAU,IAAI,KAAK,iCAAiC;AACtE,8BAA0B,KAAK,OAAO;AACtC,QAAI,YAAY;AAChB,QAAI,QAAQ,KAAK,cAAc,UAAa,CAAC,KAAK,wBAAwB,KAAK,SAAS,GAAG;AAezF,UAAI;AACJ,UAAI;AACF,SAAC,MAAM,IAAI,MAAM,KAAK,4BAA4B,CAAC,KAAK,SAAS,GAAG,CAAC;AAAA,MACvE,QAAQ;AACN,iBAAS;AAAA,MACX;AACA,UAAI,QAAQ;AACV,2BAAmB,KAAK,SAAS,QAAQ,KAAK;AAAA,MAChD,OAAO;AAIL,oBAAY;AAAA,MACd;AAAA,IACF;AACA,QACE,aACA,aACA,aAAa,cAAc,KAC3B,KAAK,uBAAuB,MAAM,YAClC,KAAK,cAAc,MAAM,OACzB;AAQA,YAAM,UAAU,kBAAkB,KAAK,SAAS,aAAa,KAAK;AAClE,UAAI,QAAS,mBAAkB,KAAK,SAAS,SAAS,UAAU,OAAO,KAAK,cAAc,CAAC;AAAA,IAC7F;AASA,QAAI,UAAU,oBAAoB,gBAAe,6BAA6B,IAAI,KAAK,OAAO,KAAK,OAAO;AACxG,kCAA4B,KAAK,SAAS,eAAe;AAAA,IAC3D,OAAO;AACL,uCAAiC,KAAK,OAAO;AAAA,IAC/C;AACA,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAW;AAC/B,WAAK,iBAAiB;AACtB,WAAK,4BAA4B;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcU,8BAAoC;AAC5C,UAAM,WAAWA,OAAK,KAAK,KAAK,SAAS,MAAM;AAC/C,oBAAe,kBAAkB,OAAO,QAAQ;AAChD,SAAK,qBAAqB;AAM1B,wBAAoB,KAAK,OAAO;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA+B;AACrC,WAAO,KAAK,kBAAkB,cAAc,gBAAe,qBAAqB;AAAA,EAClF;AAAA;AAAA;AAAA,EAIQ,uBAA6B;AACnC,SAAK,kBAAkB,cAAc,gBAAe,qBAAqB;AAAA,EAC3E;AAAA,EAEQ,6BAA6B,WAA4B;AAC/D,QAAI,OAAO,cAAc,YAAY,CAAC,OAAO,SAAS,SAAS,GAAG;AAChE,aAAO;AAAA,IACT;AACA,WAAO,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,CAAC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,yBACJ,SACmB;AACnB,WAAO,KAAK,gBAAgB,yBAAyB,OAAO;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,uBAAuB,SAAgE;AAC3F,WAAO,KAAK,gBAAgB,uBAAuB,OAAO;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,uBAA+B;AAC7B,WAAO,GAAG,KAAK,uBAAuB,CAAC,IAAI,KAAK,qBAAqB,CAAC;AAAA,EACxE;AAAA,EAEA,MAAc,4BACZ,WACA,WACA,SACuB;AACvB,QAAI,UAAU,WAAW,EAAG,QAAO,CAAC;AAEpC,UAAM,sBAAsB,KAAK,6BAA6B,SAAS;AACvE,UAAM,WAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,qBAAqB;AAG9D,2BAAqB,OAAO;AAC5B,YAAM,QAAQ,UAAU,MAAM,GAAG,IAAI,mBAAmB;AACxD,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,MAAM,IAAI,OAAO,aAAa;AAC5B,cAAI;AACF,kBAAM,MAAM,MAAM,uBAAuB,UAAU,KAAK,iBAAiB,KAAK,OAAO;AACrF,kBAAM,SAAS,iBAAiB,GAAG;AACnC,gBAAI,CAAC,OAAQ,QAAO;AACpB,mBAAO;AAAA,cACL;AAAA,gBACE,MAAM;AAAA,gBACN,aAAa;AAAA,kBACX,OAAO;AAAA,kBACP,gBAAgB,KAAK,SAAS,QAAQ;AAAA,kBACtC,OAAO;AAAA,gBACT;AAAA,gBACA,SAAS,OAAO;AAAA,cAClB;AAAA,cACA;AAAA,YACF;AAAA,UACF,SAAS,KAAK;AAIZ,gBAAI,eAAe,uBAAwB,OAAM;AACjD,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAAA,MACH;AACA,iBAAW,UAAU,SAAS;AAC5B,YAAI,WAAW,KAAM,UAAS,KAAK,MAAM;AAAA,MAC3C;AAAA,IACF;AAIA,yBAAqB,OAAO;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oBAAoB,UAA0C;AAC1E,QAAI;AACF,YAAM,MAAM,MAAM,uBAAuB,UAAU,KAAK,iBAAiB,KAAK,OAAO;AACrF,YAAM,QAAQ,IAAI,MAAM,wCAAwC;AAChE,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,mBAAmB,MAAM,CAAC;AAChC,YAAM,aACJ,iBAAiB,MAAM,uCAAuC,IAAI,CAAC,KACnE,iBAAiB,MAAM,uCAAuC,IAAI,CAAC,KACnE;AACF,YAAM,YAAY,aAAa,KAAK,MAAM,WAAW,KAAK,CAAC,IAAI,OAAO;AACtE,aAAO,OAAO,SAAS,SAAS,IAAI,YAAY;AAAA,IAClD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,gCAAgC,WAAqB,gBAA2C;AAC5G,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,UAAU,IAAI,OAAO,aAAa;AAChC,cAAM,YAAY,MAAM,KAAK,oBAAoB,QAAQ;AACzD,YAAI,cAAc,MAAM;AACtB,iBAAO,aAAa,iBAAiB,WAAW;AAAA,QAClD;AACA,YAAI;AACF,gBAAM,WAAW,MAAMO,MAAK,QAAQ;AACpC,iBAAO,SAAS,WAAW,iBAAiB,WAAW;AAAA,QACzD,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,QAAQ,OAAO,CAAC,aAAiC,aAAa,IAAI;AAAA,EAC3E;AAAA,EAEQ,iBAAiB,WAA+B;AACtD,UAAM,kBAA4B,CAAC;AACnC,UAAM,YAAsB,CAAC;AAE7B,eAAW,YAAY,WAAW;AAChC,UAAI,aAAa,KAAK,kBAAkB,SAAS,WAAW,GAAG,KAAK,cAAc,GAAGP,OAAK,GAAG,EAAE,GAAG;AAChG,wBAAgB,KAAK,QAAQ;AAAA,MAC/B,OAAO;AACL,kBAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF;AAEA,oBAAgB,KAAK,CAAC,MAAM,UAAU,MAAM,cAAc,IAAI,CAAC;AAC/D,cAAU,KAAK,CAAC,MAAM,UAAU,MAAM,cAAc,IAAI,CAAC;AAEzD,QAAI,gBAAgB,WAAW,EAAG,QAAO;AACzC,QAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,UAAM,UAAoB,CAAC;AAC3B,UAAM,YAAY,KAAK,IAAI,gBAAgB,QAAQ,UAAU,MAAM;AACnE,aAAS,IAAI,GAAG,IAAI,WAAW,KAAK,GAAG;AACrC,YAAM,iBAAiB,gBAAgB,CAAC;AACxC,UAAI,eAAgB,SAAQ,KAAK,cAAc;AAC/C,YAAM,WAAW,UAAU,CAAC;AAC5B,UAAI,SAAU,SAAQ,KAAK,QAAQ;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,uBACZ,qBACA,gBACA,2BACA,eAC0D;AAC1D,UAAM,WAAyB,CAAC;AAChC,UAAM,YAAsB,CAAC;AAC7B,UAAM,0BAA0B,KAAK,6BAA6B,aAAa;AAE/E,aAAS,QAAQ,GAAG,QAAQ,oBAAoB,UAAU;AACxD,UAAI,SAAS,UAAU,kBAAkB,UAAU,UAAU,0BAA2B;AACxF,YAAM,iBAAiB,iBAAiB,SAAS;AACjD,YAAM,4BAA4B,4BAA4B,UAAU;AACxE,YAAM,iBACJ,kBAAkB,KAAK,6BAA6B,IAAI,KAAK,IAAI,yBAAyB,CAAC,IAAI;AACjG,YAAM,iBAAiB,oBAAoB;AAAA,QACzC;AAAA,QACA,QAAQ,KAAK,IAAI,gBAAgB,yBAAyB;AAAA,MAC5D;AACA,eAAS,eAAe;AACxB,UAAI,eAAe,WAAW,EAAG;AACjC,gBAAU,KAAK,GAAG,cAAc;AAChC,YAAM,iBAAiB,MAAM,KAAK,4BAA4B,gBAAgB,eAAe,MAAM;AACnG,UAAI,eAAe,WAAW,EAAG;AACjC,eAAS,KAAK,GAAG,eAAe,MAAM,GAAG,cAAc,CAAC;AAAA,IAC1D;AAEA,WAAO,EAAE,UAAU,UAAU;AAAA,EAC/B;AAAA,EAEA,MAAM,mBAAmB,UAAqC,CAAC,GAAsC;AACnG,WAAO,qBAAqB,KAAK,iBAAiB,SAAS,EAAE,SAAS,KAAK,yBAAyB,SAAS,KAAK,SAAS,eAAe,KAAK,uBAAuB,GAAG,YAAY,KAAK,cAAc,GAAG,OAAO,KAAK,cAAc,EAAE,GAAG,CAAC,aAAa,KAAK,wBAAwB,QAAQ,CAAC;AAAA,EAChS;AAAA,EAEA,MAAc,yBAAyB,SAAoD;AACzF,UAAM,YAAY,MAAM,KAAK,yBAAyB,OAAO;AAC7D,WAAO,KAAK,4BAA4B,WAAW,IAAI,OAAO;AAAA,EAChE;AAAA,EAEA,MAAM,sBAA6C;AACjD,WAAO,KAAK,wBAAwB,MAAM,KAAK,gBAAgB,oBAAoB,CAAC;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,uBAA8C;AAClD,UAAM,WAAyB,CAAC;AAChC,UAAM,OAAO,KAAK;AAElB,UAAM,UAAU,OAAO,QAAgB;AACrC,UAAI;AACF,cAAM,UAAU,MAAME,SAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,mBAAW,SAAS,SAAS;AAC3B,gBAAM,WAAWF,OAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,cAAI,MAAM,YAAY,GAAG;AACvB,kBAAM,QAAQ,QAAQ;AAAA,UACxB,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;AACrC,gBAAI;AACF,oBAAM,MAAM,MAAM,uBAAuB,UAAU,KAAK,iBAAiB,KAAK,OAAO;AACrF,oBAAM,SAAS,iBAAiB,GAAG;AACnC,kBAAI,QAAQ;AACV,yBAAS;AAAA,kBACP;AAAA,oBACE;AAAA,sBACE,MAAM;AAAA,sBACN,aAAa;AAAA,wBACX,OAAO;AAAA,wBACP,gBAAgB,KAAK,SAAS,QAAQ;AAAA,wBACtC,OAAO;AAAA,sBACT;AAAA,sBACA,SAAS,OAAO;AAAA,oBAClB;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF,SAAS,KAAK;AAGZ,kBAAI,eAAe,uBAAwB,OAAM;AACjD,kBAAI,CAAC,YAAY,KAAK,QAAQ,GAAG;AAC/B,oBAAI,KAAK,uCAAuC,QAAQ,KAAK,GAAG,EAAE;AAAA,cACpE;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,YAAI,iBAAiB,uBAAwB,OAAM;AACnD,YAAI,CAAC,YAAY,OAAO,QAAQ,EAAG,OAAM;AAAA,MAC3C;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI;AAClB,WAAO,KAAK,wBAAwB,QAAQ;AAAA,EAC9C;AAAA,EAEA,MAAM,iBAAiB,UAA8C;AACnE,WAAO,KAAK,uBAAuB,MAAM,KAAK,gBAAgB,iBAAiB,QAAQ,CAAC;AAAA,EAC1F;AAAA,EAEQ,mBAAmB,MAA8B;AACvD,WAAO,SAAS,SAASA,OAAK,KAAK,KAAK,SAAS,MAAM,IAAI,KAAK;AAAA,EAClE;AAAA,EAEQ,qBAAqB,QAA4B;AACvD,UAAM,YAAY,OAAO,YAAY,WAAW,OAAO,YAAY;AACnE,UAAM,aAAa,aAAa,IAAI,MAAM,GAAG,EAAE;AAC/C,WAAO,sBAAsB,KAAK,SAAS,IAAI,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EACjG;AAAA,EAEQ,iBAAiB,QAA6B;AACpD,QAAI,OAAO,YAAY,WAAW,WAAY,QAAO;AACrD,QAAI,OAAO,YAAY,iBAAiB,OAAW,QAAO;AAC1D,WAAO,sBAAsB,KAAK,OAAO,IAAI;AAAA,EAC/C;AAAA,EAEA,oBAAoB,QAAoB,MAA8B;AACpE,UAAM,OAAO,KAAK,mBAAmB,IAAI;AACzC,QAAI,KAAK,iBAAiB,MAAM,GAAG;AACjC,aAAOA,OAAK,KAAK,MAAM,aAAa,KAAK,qBAAqB,MAAM,GAAG,GAAG,OAAO,YAAY,EAAE,KAAK;AAAA,IACtG;AACA,QAAI,OAAO,YAAY,aAAa,cAAc;AAEhD,aAAOA,OAAK,KAAK,MAAM,eAAe,GAAG,OAAO,YAAY,EAAE,KAAK;AAAA,IACrE;AACA,UAAM,MAAM,gBAAgB,OAAO,YAAY,QAAQ;AACvD,WAAOA,OAAK,KAAK,MAAM,KAAK,KAAK,qBAAqB,MAAM,GAAG,GAAG,OAAO,YAAY,EAAE,KAAK;AAAA,EAC9F;AAAA,EACA,MAAc,sBAAsB,YAAoB,QAAmC;AACzF,iCAA6B,UAAU;AAIvC,UAAM,gBAAgB,KAAK,qBAAqB;AAChD,UAAM,SAAS,OAAO,YAAY;AAClC,UAAM,cAAyB,4BAA4B,OAAO,aAAa,aAAa;AAC5F,UAAM,UAAU,MACd;AAAA,MACE;AAAA,MACA,GAAG,qBAAqB,KAAK,YAAY,WAAW,CAAC,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AAAA,MAC3E,KAAK,gBAAgB;AAAA,MACrB,CAAC;AAAA,MACD,KAAK;AAAA,IACP;AAIF,UAAM,YAAY,MAAMS,UAAS,UAAU,EAAE,MAAM,MAAM,IAAI;AAC7D,UAAM,QAAQ;AACd,QAAI,OAAO,WAAW,UAAU;AAC9B,YAAM,kBAAkB,YAAY;AACpC,UAAI;AACF,cAAiB,gCAAgC;AAAA,UAC/C,UAAU,KAAK;AAAA,UACf,YAAY,MAAM,KAAK,qBAAqB;AAAA,UAC5C,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA,SAAS;AAAA,QACX,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,cAAc,MAAM;AACtB,gBAAMN,QAAO,UAAU,EAAE,MAAM,MAAM,MAAS;AAAA,QAChD,OAAO;AACL,gBAAMO,WAAU,YAAY,SAAS,EAAE,MAAM,MAAM,MAAS;AAAA,QAC9D;AACA,aAAK,2BAA2B;AAChC,cAAM;AAAA,MACR;AACA,YAAM,KAAK,gBAAgB,eAAe,OAAO,YAAY,IAAI,iBAAiB,YAAY,SAAS;AAAA,IACzG;AAIA,QAAI,OAAO,YAAY,cAAc,YAAY,WAAW;AAC1D,aAAO,YAAY,YAAY,YAAY;AAAA,IAC7C;AACA,SAAK,2BAA2B;AAChC,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EACA,MAAM,iBAAiB,QAAoB,YAAsC;AAC/E,UAAM,EAAE,qBAAAI,sBAAqB,mBAAmB,IAAI;AACpD,UAAM,UAAU,MAAM,KAAK;AAAA,MACzB,OAAO;AAAA,MACP,OAAO,YAAY;AACjB,cAAM,cAAc,MAAM,KAAK,iBAAiB,UAAU;AAC1D,YAAI,SAAS,YAAY,OAAO,OAAO,YAAY,IAAI;AACrD,cAAI,YAAY,QAAQ,aAAa,YAAY,OAAO,OAAO,YAAY,GAAI,QAAO;AACtF,gBAAM,IAAI,MAAM,UAAU,OAAO,YAAY,EAAE,+BAA+B;AAAA,QAChF;AACA,cAAM,iBAAiB,gBAAe,sBAAsB,IAAI,MAAM;AACtE,cAAM,kBAAkB,qBAAqB,OAAO;AACpD,YACE,mBAAmB,SACf,QAAQ,YAAY,YAAY,OAAO,YAAY,UACnD,oBAAoB,gBACxB;AACA,gBAAM,IAAI,MAAM,UAAU,OAAO,YAAY,EAAE,+BAA+B;AAAA,QAChF;AACA,cAAM,aACJ,iBAAiB,QAAQ,WAAW,KACpC,qBAAqB,OAAO,KAC3B,gBAAgB,QAAQ,iBAAiB,YAAY,WAAW,KACjE,qBAAqB,WAAW;AAClC,cAAM,QAAQ,KAAK,gCAAgC;AACnD,cAAM,SAAS,aAAa,MAAM,MAAM,aAAa,IAAI;AACzD,cAAM,gBAAgB,gBAAgB,KAAK,SAAS,UAAU;AAC9D,YAAI,UAAU;AACd,YAAI;AACF,cAAI,aAAa,YAAY,OAAO,QAAQ,YAAY,IAAI;AAC1D,kBAAMA,qBAAoB,KAAK,SAAS,QAAQ,MAAM,MAAM,KAAK,yBAAyB,QAAQ,IAAI,CAAC;AACvG,sBAAU;AACV,iBAAK,2BAA2B;AAChC,sCAA0B,KAAK,SAAS,QAAQ,YAAY,IAAI,aAAa;AAAA,UAC/E,OAAO;AACL,kBAAM,mBAAmB,KAAK,SAAS,YAAY,MAAM,KAAK,sBAAsB,YAAY,OAAO,CAAC;AACxG,gBAAI,OAAO,YAAY,cAAc,QAAQ,YAAY,WAAW;AAClE,qBAAO,YAAY,YAAY,QAAQ,YAAY;AAAA,YACrD;AACA,sBAAU;AACV,kBAAM,aAAad,OAAK,QAAQ,QAAQ,IAAI;AAC5C,kBAAM,WAAWA,OAAK,QAAQ,UAAU;AACxC,gBAAI,eAAe,UAAU;AAC3B,oBAAMc,qBAAoB,KAAK,SAAS,QAAQ,MAAM,MAAM,KAAK,yBAAyB,QAAQ,IAAI,CAAC;AACvG,mBAAK,2BAA2B;AAChC,wCAA0B,KAAK,SAAS,QAAQ,YAAY,IAAI,aAAa;AAAA,YAC/E;AAAA,UACF;AACA,cAAI,WAAW,OAAW,OAAM,KAAK,gDAAgD,MAAM;AAAA,QAC7F,SAAS,OAAO;AACd,cAAI,WAAW,UAAa,CAAC,QAAS,OAAM,MAAM,aAAa,MAAM,EAAE,MAAM,MAAM,MAAM,cAAc,CAAC;AACxG,cAAI,WAAW,UAAa,QAAS,OAAM,cAAc;AACzD,gBAAM;AAAA,QACR;AACA,eAAO;AAAA,MACT;AAAA,MACA,CAAC,UAAU;AAAA,IACb;AACA,QAAI,KAAK,wBAAwB,OAAO,IAAI,KAAK,KAAK,wBAAwB,UAAU,GAAG;AACzF,WAAK,4BAA4B;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBACJ,QACA,YACmD;AACnD,UAAM,aAAa,KAAK,oBAAoB,QAAQ,UAAU;AAC9D,UAAM,aAAad,OAAK,QAAQ,OAAO,IAAI;AAC3C,UAAM,WAAWA,OAAK,QAAQ,UAAU;AACxC,QAAI,eAAe,UAAU;AAC3B,aAAO,EAAE,SAAS,OAAO,WAAW;AAAA,IACtC;AACA,UAAM,UAAU,MAAM,KAAK,iBAAiB,QAAQ,UAAU;AAC9D,QAAI,CAAC,QAAS,QAAO,EAAE,SAAS,OAAO,WAAW;AAClD,SAAK,wBAAwB;AAC7B,WAAO,EAAE,SAAS,WAAW;AAAA,EAC/B;AAAA,EAEA,IAAY,aAAqB;AAC/B,WAAOA,OAAK,KAAK,KAAK,SAAS,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAc,QAAoB,WAAsE;AAC5G,UAAM,EAAE,qBAAAc,sBAAqB,mBAAmB,IAAI;AACpD,UAAM,iBAAiB,OAAO,SAAqB,gBAAoD;AACrG,UAAI;AACF,cAAM,MAAM,WAAW,MAAM,oBAAI,KAAK;AACtC,cAAM,QAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AAC3C,cAAM,UAAUd,OAAK,KAAK,KAAK,YAAY,KAAK;AAChD,cAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAExC,cAAM,gBAAgB,KAAK,qBAAqB;AAChD,cAAM,YAA0C;AAAA,UAC9C;AAAA,YACE,GAAG,QAAQ;AAAA,YACX,QAAQ;AAAA,YACR,YAAY,IAAI,YAAY;AAAA,YAC5B,SAAS,IAAI,YAAY;AAAA,UAC3B;AAAA,UACA;AAAA,QACF;AACA,cAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,SAAS,CAAC,CAAC;AAAA;AAAA,EAAO,QAAQ,OAAO;AAAA;AAC9F,cAAM,WAAWA,OAAK,KAAK,SAASA,OAAK,SAAS,QAAQ,IAAI,CAAC;AAG/D,cAAM,YAAY,MAAM,KAAK,sBAAsB,QAAQ,EAAE,MAAM,MAAM,IAAI;AAC7E,cAAM,mBAAmB,KAAK,SAAS,UAAU,MAAM,KAAK,uBAAuB,UAAU,WAAW,CAAC;AACzG,YAAI,OAAO,QAAQ,YAAY,cAAc,UAAU;AACrD,cAAI;AACF,kBAAM,KAAK,gBAAgB;AAAA,cACzB;AAAA,cACA;AAAA,cACA,QAAQ,YAAY;AAAA,cACpB;AAAA,cACA,QAAQ;AAAA,YACV;AAAA,UACF,SAAS,KAAK;AACZ,gBAAI,cAAc,MAAM;AACtB,oBAAMc;AAAA,gBAAoB,KAAK;AAAA,gBAAS;AAAA,gBAAU,MAChDX,QAAO,QAAQ,EAAE;AAAA,kBACf,MAAM;AAAA,kBACN,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,YACF,OAAO;AACL,oBAAMW;AAAA,gBAAoB,KAAK;AAAA,gBAAS;AAAA,gBAAU,MAChD,KAAK,uBAAuB,UAAU,SAAS,EAAE;AAAA,kBAC/C,MAAM;AAAA,kBACN,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AACA,kBAAM;AAAA,UACR;AAAA,QACF;AACA,cAAM,UAAU,MAAMA,qBAAoB,KAAK,SAAS,QAAQ,MAAM,MACpE,KAAK,yBAAyB,QAAQ,IAAI,CAAC;AAC7C,YAAI,CAAC,QAAS,QAAO;AACrB,oBAAY;AACZ,uCAA+B,KAAK,SAAS,QAAQ,YAAY,EAAE;AACnE,aAAK,2BAA2B;AAChC,cAAM,KAAK;AAAA,UACT;AAAA,UACA;AAAA,YACE,UAAU,QAAQ,YAAY;AAAA,YAC9B,WAAW;AAAA,YACX,WAAW,UAAU,cAAc,UAAU;AAAA,YAC7C,OAAO,WAAW,SAAS;AAAA,YAC3B,YAAY,WAAW;AAAA,YACvB,QAAQ,KAAK,wBAAwB,QAAQ,aAAa,QAAQ,IAAI;AAAA,YACtE,OAAO,KAAK,wBAAwB,WAAW,QAAQ;AAAA,YACvD,kBAAkB,WAAW;AAAA,YAC7B,eAAe,WAAW;AAAA,UAC5B;AAAA,UACA,WAAW;AAAA,QACb;AACA,aAAK,wBAAwB;AAC7B,YAAI,MAAM,mBAAmB,QAAQ,YAAY,EAAE,WAAM,QAAQ,EAAE;AACnE,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,YAAI,KAAK,4BAA4B,QAAQ,YAAY,EAAE,KAAK,GAAG,EAAE;AACrE,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO,MAAM,KAAK,2BAA2B,QAAQ,cAAc;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,eAAkC;AACtC,WAAO,KAAK,YAAY,gBAAgB;AAAA,EAC1C;AAAA,EAEA,MAAM,WAAW,MAA+B;AAC9C,WAAO,KAAK,YAAY,WAAW,IAAI;AAAA,EACzC;AAAA,EAEA,MAAM,kBAAqC;AACzC,WAAO,KAAK,YAAY,gBAAgB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,mBAAmB,cAAsB,MAAsC;AACnF,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,QAAI,SAAS,WAAW,EAAG,QAAO;AAElC,UAAM,aAAa,GAAG,KAAK,YAAY,CAAC;AAExC,UAAM,eAAe,KAAK,oBAAoB,cAAc,IAAI;AAChE,UAAM,mBAAmB,aAAa,WAAW,UAAU,IAAI,aAAa,MAAM,WAAW,MAAM,IAAI;AACvG,UAAM,iBAAiB,YAAY,gBAAgB;AAGnD,UAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,CAAC;AAEhE,eAAW,UAAU,UAAU;AAC7B,YAAM,iBAAiB,OAAO,MAAM,WAAW,MAAM;AACrD,YAAM,eAAe,YAAY,cAAc;AAG/C,UAAI,WAAW,aAAc,QAAO;AAGpC,UAAI,iBAAiB,eAAgB,QAAO;AAG5C,YAAM,UAAU,eAAe,UAAU,aAAa,SAAS,iBAAiB;AAChF,YAAM,SAAS,eAAe,SAAS,aAAa,SAAS,iBAAiB;AAC9E,UAAI,QAAQ,SAAS,KAAK,QAAQ,SAAS,OAAO,SAAS,OAAO,OAAO,SAAS,OAAO,GAAG;AAC1F,eAAO;AAAA,MACT;AAGA,UAAI,eAAe,UAAU,KAAK,aAAa,UAAU,GAAG;AAC1D,cAAM,OAAO,YAAY,gBAAgB,YAAY;AACrD,YAAI,QAAQ,EAAG,QAAO;AAAA,MACxB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBACJ,IACA,kBACA,SACkB;AAClB,UAAM,SAAS,kBAAkB,OAC7B,MAAM,KAAK,iBAAiB,iBAAiB,IAAI,KAChD,MAAM,KAAK,gBAAgB,GAAG,KAAK,CAAC,cAAc,UAAU,YAAY,OAAO,EAAE,KAAK;AAC3F,QAAI,CAAC,UAAU,OAAO,YAAY,OAAO,GAAI,QAAO;AAEpD,WAAO,MAAM,KAAK,gCAAgC,QAAQ,OAAO,SAAS,eAAe,gBAAgB;AACvG,UACE,oBACA,8BAA8B,OAAO,MAAM,8BAA8B,gBAAgB,GACzF;AACA,eAAO;AAAA,MACT;AACA,aAAO,yBAAyB;AAAA,QAC9B,UAAU;AAAA,QACV,aAAa,SAAS,sBAAsB,OAAO,MAAM,KAAK,4BAA4B,OAAO,IAAI;AAAA,QACrG,YAAY,SAAS,sBAAsB,OAAO,MAAM,KAAK,2BAA2B,OAAO,IAAI;AAAA,QACnG,cAAc,MAAc,oBAAoB,KAAK,SAAS,QAAQ,MAAM,MAC1E,KAAK,yBAAyB,QAAQ,IAAI,CAAC;AAAA,QAC7C,aAAa,YAAY;AACvB,sBAAY;AACZ,yCAA+B,KAAK,SAAS,EAAE;AAC/C,eAAK,2BAA2B;AAChC,cAAI,KAAK,wBAAwB,QAAQ,IAAI,EAAG,MAAK,4BAA4B;AACjF,gBAAM,KAAK,gDAAgD,aAAa;AACxE,eAAK,wBAAwB;AAC7B,cAAI,MAAM,sBAAsB,EAAE,EAAE;AAAA,QACtC;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,wBACZ,QACA,YACA,SACkB;AAClB,UAAM,gBAAgB,CAAC,GAAI,OAAO,YAAY,WAAW,CAAC,GAAI,GAAI,SAAS,WAAW,CAAC,CAAE,EAAE;AAAA,MACzF,CAAC,GAAG,GAAG,MAAM,EAAE,QAAQ,CAAC,MAAM;AAAA,IAChC;AACA,UAAM,gBAAgB,KAAK,qBAAqB;AAChD,UAAM,UAAwC;AAAA,MAC5C;AAAA,QACE,GAAG,OAAO;AAAA,QACV,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,QAChC,YAAY,SAAS,cAAc,OAAO,YAAY;AAAA,QACtD,SAAS,cAAc,SAAS,IAAI,gBAAgB;AAAA,QACpD,GAAI,OAAO,YAAY,oBAAoB,UAAa,SAAS,kBAC7D,EAAE,iBAAiB,QAAQ,gBAAgB,IAC3C,CAAC;AAAA,MACP;AAAA,MACA;AAAA,IACF;AACA,UAAM,YAAY,sBAAsB,UAAU;AAClD,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,wCAAwC,OAAO,YAAY,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,IACzH;AACA,UAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,OAAO,CAAC,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AAC3F,UAAM,KAAK,4BAA4B,QAAQ,aAAa,SAAS,UAAU,MAAM,YAAY;AAC/F,WAAK,2BAA2B;AAChC,UAAI,KAAK,wBAAwB,OAAO,IAAI,EAAG,MAAK,4BAA4B;AAAA,IAClF,CAAC;AACD,QAAI,OAAO,OAAO,YAAY,cAAc,UAAU;AACpD,YAAM,KAAK,gBAAgB;AAAA,QACzB,OAAO;AAAA,QACP;AAAA,QACA,OAAO,YAAY;AAAA,QACnB;AAAA,QACA,UAAU;AAAA,QACV,EAAE,eAAe,OAAO;AAAA,MAC1B;AAAA,IACF;AACA,UAAM,KAAK,sBAAsB,EAAE,WAAW,OAAO,KAAK,CAAC;AAC3D,UAAM,KAAK,4CAA4C,wBAAwB;AAAA,MAC7E,UAAU,OAAO,YAAY;AAAA,MAC7B,WAAW;AAAA,MACX,WAAW,QAAQ;AAAA,MACnB,OAAO,SAAS,SAAS;AAAA,MACzB,QAAQ,KAAK,wBAAwB,OAAO,aAAa,OAAO,IAAI;AAAA,MACpE,OAAO,KAAK,wBAAwB,SAAS,OAAO,IAAI;AAAA,MACxD,kBAAkB;AAAA,QAChB,GAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,QACjD,IAAI,QAAQ,WAAW,CAAC,GAAG,OAAO,OAAO;AAAA,MAC3C;AAAA,IACF,CAAC;AACD,QAAI,MAAM,kBAAkB,OAAO,YAAY,EAAE,EAAE;AACnD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,IACA,YACA,SACkB;AAClB,UAAM,UAAU,MAAM,KAAK,gBAAgB,GAAG,KAAK,CAAC,cAAc,UAAU,YAAY,OAAO,EAAE;AACjG,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,MAAM,KAAK,wBAAwB,QAAQ,YAAY,OAAO;AAAA,EACvE;AAAA,EAEA,MAAM,wBACJ,UACA,YACA,SACkB;AAClB,UAAM,YAAY,sBAAsB,UAAU;AAClD,UAAM,cAAc;AAAA,MAClB,SAAS;AAAA,MACT,SAAS,YAAY;AAAA,MACrB,SAAS,YAAY;AAAA,IACvB;AACA,UAAM,cAAc;AAAA,MAClB,UAAU;AAAA,MACV,SAAS,YAAY;AAAA,MACrB,SAAS,YAAY;AAAA,IACvB;AACA,WAAO,MAAM,KAAK;AAAA,MAChB,YAAY;AACV,cAAM,UAAU,MAAM,KAAK,iBAAiB,SAAS,IAAI;AACzD,YAAI,CAAC,WAAW,QAAQ,YAAY,OAAO,SAAS,YAAY,GAAI,QAAO;AAC3E,YAAI,8BAA8B,OAAO,MAAM,8BAA8B,QAAQ,EAAG,QAAO;AAC/F,eAAO,MAAM,KAAK,wBAAwB,SAAS,YAAY,OAAO;AAAA,MACxE;AAAA,MACA,CAAC,6BAA6B,SAAS,IAAI,GAAG,aAAa,WAAW;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,uBACJ,QACA,OACA,WACkB;AAClB,UAAM,eAAe,OAAO,YAAY,UAAU;AAGlD,UAAM,aAAa,KAAK,qBAAqB;AAC7C,UAAM,UAAwC;AAAA,MAC5C,EAAE,GAAG,OAAO,aAAa,GAAG,MAAM;AAAA,MAClC;AAAA,IACF;AACA,UAAM,SAAS,OAAO,QAAQ,cAAc,WAAW,aAAa;AACpE,UAAM,cAAc,QAAQ,UAAU;AAEtC,UAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,OAAO,CAAC,CAAC;AAAA;AAAA,EAAO,OAAO,OAAO;AAAA;AAC3F,UAAM,KAAK,iCAAiC,QAAQ,aAAa,SAAS,YAAY;AACpF,WAAK,2BAA2B;AAEhC,UAAI,OAAO,KAAK,SAAS,GAAGd,OAAK,GAAG,OAAOA,OAAK,GAAG,EAAE,GAAG;AACtD,aAAK,4BAA4B;AAAA,MACnC;AAAA,IACF,CAAC;AACD,UAAM,eAAe,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY,OAAO,YAAY;AAChG,QAAI,UAAU,OAAO,iBAAiB,UAAU;AAC9C,YAAM,KAAK,gBAAgB,OAAO,OAAO,MAAM,SAAS,cAAc,QAAQ,OAAO,SAAS;AAAA,QAC5F,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AACA,UAAM,KAAK,sBAAsB,EAAE,WAAW,OAAO,KAAK,CAAC;AAC3D,QAAI,OAAO,KAAK,SAAS,GAAGA,OAAK,GAAG,OAAOA,OAAK,GAAG,EAAE,GAAG;AACtD,WAAK,4BAA4B;AAAA,IACnC;AACA,QAAI;AACF,YAAM,KAAK,8BAA8B,QAAQ;AAAA,QAC/C,GAAG;AAAA,QACH,aAAa;AAAA,MACf,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,KAAK,kFAAkF,GAAG,EAAE;AAAA,IAClG;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACE,UAAU,QAAQ;AAAA,QAClB,WAAW,KAAK,0BAA0B,OAAO,aAAa,OAAO;AAAA,QACrE,WAAW,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrD,OAAO,WAAW,SAAS;AAAA,QAC3B,YAAY,WAAW;AAAA,QACvB,QAAQ,KAAK,wBAAwB,OAAO,aAAa,OAAO,IAAI;AAAA,QACpE,OAAO,KAAK,wBAAwB,SAAS,OAAO,IAAI;AAAA,QACxD,kBAAkB;AAAA,UAChB,GAAI,WAAW,oBAAoB,CAAC;AAAA,UACpC,GAAI,QAAQ,eAAe,CAAC,QAAQ,YAAY,IAAI,CAAC;AAAA,UACrD,GAAI,QAAQ,aAAa,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,QACnD;AAAA,QACA,eAAe,WAAW;AAAA,MAC5B;AAAA,MACA,WAAW;AAAA,IACb;AACA,QAAI,iBAAiB,aAAa;AAIhC,WAAK,wBAAwB;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kCACJ,UACA,OACA,WACkB;AAClB,WAAO,MAAM,KAAK,mCAAmC,SAAS,MAAM,OAAO,YAAY;AACrF,UAAI,CAAC,QAAS,QAAO;AACrB,UAAI,8BAA8B,OAAO,MAAM,8BAA8B,QAAQ,EAAG,QAAO;AAC/F,aAAO,MAAM,KAAK,uBAAuB,SAAS,OAAO,SAAS;AAAA,IACpE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,wBAAwB,IAAY,OAAqD;AAC7F,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE;AAC3D,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,KAAK,uBAAuB,QAAQ,KAAK;AAAA,EAClD;AAAA;AAAA,EAGA,MAAM,kBAAyC;AAC7C,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAwB,CAAC;AAE/B,eAAW,KAAK,UAAU;AACxB,UAAI,CAAC,EAAE,YAAY,UAAW;AAC9B,YAAM,YAAY,IAAI,KAAK,EAAE,YAAY,SAAS,EAAE,QAAQ;AAC5D,UAAI,aAAa,IAAK;AACtB,YAAM,UAAU,MAAM,KAAK,2BAA2B,GAAG,CAAC,YAAY;AACpE,cAAM,mBAAmB,QAAQ,YAAY,YACzC,IAAI,KAAK,QAAQ,YAAY,SAAS,EAAE,QAAQ,IAChD,OAAO;AACX,eAAO,OAAO,SAAS,gBAAgB,KAAK,mBAAmB;AAAA,MACjE,CAAC;AACD,UAAI,SAAS;AACX,gBAAQ,KAAK,OAAO;AACpB,YAAI,MAAM,0BAA0B,QAAQ,YAAY,EAAE,gBAAgB;AAAA,MAC5E;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,GAAG;AACtB,WAAK,2BAA2B;AAChC,WAAK,wBAAwB;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAmC;AACvC,UAAM,aAAaA,OAAK,KAAK,KAAK,UAAU,aAAa;AACzD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,sBAAsB,UAAU;AACvD,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,EAAE,OAAO,CAAC,GAAG,kBAAkB,MAAM,iBAAiB,EAAE;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,OAAmC;AAClD,UAAM,KAAK,kBAAkB;AAC7B,UAAM,aAAaA,OAAK,KAAK,KAAK,UAAU,aAAa;AACzD,UAAM,KAAK,uBAAuB,YAAY,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAM,WAA+B;AACnC,UAAM,WAAWA,OAAK,KAAK,KAAK,UAAU,WAAW;AACrD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,sBAAsB,QAAQ;AACrD,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,aAAO;AAAA,QACL,iBAAiB,OAAO,OAAO,oBAAoB,WAAW,OAAO,kBAAkB;AAAA,QACvF,kBAAkB,OAAO,oBAAoB;AAAA,QAC7C,qBAAqB,OAAO,uBAAuB;AAAA,QACnD,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB;AAAA,QACjF,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB;AAAA,QACjF,iCAAiC,MAAM,QAAQ,OAAO,+BAA+B,IACjF,OAAO,gCACJ;AAAA,UACC,CAAC,UACC,SACA,OAAO,UAAU,YACjB,OAAQ,MAAoC,gBAAgB,YAC5D,OAAQ,MAAmC,eAAe;AAAA,QAC9D,EACC,IAAI,CAAC,WAAW;AAAA,UACf,aAAc,MAAkC;AAAA,UAChD,YAAa,MAAiC;AAAA,QAChD,EAAE,IACJ,CAAC;AAAA,QACL,sBAAsB,iCAAiC,OAAO,oBAAoB;AAAA,MACpF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,qBAAqB;AAAA,QACrB,eAAe;AAAA,QACf,eAAe;AAAA,QACf,iCAAiC,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAAiC;AAC9C,UAAM,KAAK,kBAAkB;AAC7B,UAAM,WAAWA,OAAK,KAAK,KAAK,UAAU,WAAW;AACrD,UAAM,KAAK,uBAAuB,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,yBAAyB,QAA8C;AAC3E,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAE7B,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AACtC,UAAM,UAAU,OACb,IAAI,CAAC,UAAU;AACd,YAAM,aAAgC;AAAA,QACpC,GAAG;AAAA,QACH,WAAW,MAAM,aAAa,MAAM,UAAU,SAAS,IAAI,MAAM,YAAY;AAAA,MAC/E;AACA,aAAO,GAAG,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,IACtC,CAAC,EACA,KAAK,EAAE;AAEV,UAAM,KAAK,wBAAwB,KAAK,mBAAmB,OAAO;AAClE,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,4BAA4B,QAAiD;AACjF,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAG7B,UAAM;AAAA,MACJ,KAAK;AAAA,MACL,CAAC,MAAM,KAAK,wBAAwB,KAAK,2BAA2B,CAAC;AAAA,MACrE,gCAAgC,MAAM;AAAA,MACtC,EAAE,aAAa,CAAC,GAAG,MAAM,KAAK,uBAAuB,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,KAAK,sBAAsB,CAAC,EAAE;AAAA,IAC/G;AACA,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA,EAIA,MAAM,oCAAsD;AAC1D,WAAO;AAAA,MACL,KAAK;AAAA,MACL,EAAE,aAAa,CAAC,GAAG,MAAM,KAAK,uBAAuB,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,KAAK,sBAAsB,CAAC,EAAE;AAAA,MAC7G,CAAC,MAAM,KAAK,wBAAwB,KAAK,2BAA2B,CAAC;AAAA,MACrE,MAAM,KAAK,kBAAkB;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,2CAAwF;AAC5F,WAAO;AAAA,MACL,KAAK;AAAA,MACL,EAAE,aAAa,CAAC,GAAG,MAAM,KAAK,uBAAuB,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,KAAK,sBAAsB,CAAC,EAAE;AAAA,MAC7G,CAAC,MAAM,KAAK,wBAAwB,KAAK,2BAA2B,CAAC;AAAA,MACrE,MAAM,KAAK,kBAAkB;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,2CAA2C,YAAiE;AAChH,UAAM,SAAS,KAAK,yBAAyB,YAAY,oDAAoD;AAC7G,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,aAAa,CAAC,GAAG,MAAM,KAAK,uBAAuB,GAAG,CAAC;AAAA,QACvD,YAAY,CAAC,MAAM,KAAK,sBAAsB,CAAC;AAAA,MACjD;AAAA,MACA,CAAC,YAAY,KAAK,wBAAwB,QAAQ,OAAO;AAAA,MACzD,YAAY;AACV,cAAM,MAAMA,OAAK,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kCACJ,SACA,aAAqB,KAAK,2BAC1B,eAAe,OACA;AACf,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,uBAAuB,YAAY,SAAS,YAAY;AAAA,EACrE;AAAA,EAEA,MAAM,2BAA2B,QAAgD;AAC/E,WAAO,KAAK,gBAAgB,2BAA2B,MAAM;AAAA,EAC/D;AAAA,EAEA,MAAM,yBAAyB,UAA8B,CAAC,GAAmC;AAC/F,WAAO,KAAK,gBAAgB,yBAAyB,OAAO;AAAA,EAC9D;AAAA,EAEA,MAAM,sBAAsB,QAAgD;AAC1E,QAAI,OAAO,WAAW,EAAG,QAAO;AAIhC,UAAM,MAAM,KAAK,2BACd,MAAM,MAAM,MAAS,EACrB,KAAK,MAAM,KAAK,8BAA8B,MAAM,CAAC;AACxD,SAAK,6BAA6B,IAAI,MAAM,MAAM,MAAS;AAC3D,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,8BAA8B,QAAgD;AAC1F,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAE7B,QAAI;AACJ,QAAI,WAAqD;AACzD,QAAI;AACF,YAAM,KAAK,MAAMO,MAAK,KAAK,mBAAmB;AAC9C,iBAAW,EAAE,MAAM,GAAG,MAAM,SAAS,GAAG,QAAQ;AAChD,UACE,KAAK,2BACL,KAAK,wBAAwB,SAAS,SAAS,SAAS,QACxD,KAAK,wBAAwB,SAAS,YAAY,SAAS,SAC3D;AAEA,uBAAe,KAAK,wBAAwB;AAAA,MAC9C,OAAO;AAGL,uBAAe,oBAAI,IAAY;AAC/B,yBAAiB,QAAQ;AAAA,UAAwB,KAAK;AAAA,UAAqB,MACzE,KAAK,sBAAsB,KAAK,mBAAmB;AAAA,QACrD,GAAG;AACD,gBAAM,MAAM,KAAK,KAAK;AACtB,cAAI,CAAC,IAAK;AACV,cAAI;AACF,kBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,gBAAI,OAAO,OAAO,aAAa,YAAY,OAAO,OAAO,eAAe,UAAU;AAChF,2BAAa,IAAI,GAAG,OAAO,QAAQ,IAAI,OAAO,UAAU,EAAE;AAAA,YAC5D;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,qBAAe,oBAAI,IAAY;AAC/B,iBAAW;AAAA,IACb;AAEA,UAAM,UAAS,oBAAI,KAAK,GAAE,YAAY;AAMtC,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,UAAiC,CAAC;AACxC,eAAW,SAAS,QAAQ;AAC1B,YAAM,MAAM,GAAG,MAAM,QAAQ,IAAI,MAAM,UAAU;AACjD,UAAI,aAAa,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,EAAG;AAC/C,cAAQ,IAAI,GAAG;AACf,cAAQ,KAAK;AAAA,QACX,GAAG;AAAA,QACH,WAAW,MAAM,aAAa,MAAM,UAAU,SAAS,IAAI,MAAM,YAAY;AAAA,MAC/E,CAAC;AAAA,IACH;AAEA,QAAI,QAAQ,WAAW,GAAG;AAGxB,UAAI,SAAU,MAAK,0BAA0B,EAAE,UAAU,MAAM,aAAa;AAC5E,aAAO;AAAA,IACT;AACA,UAAM,UAAU,QAAQ,IAAI,CAAC,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,CAAI,EAAE,KAAK,EAAE;AAI5E,UAAM,KAAK,wBAAwB,KAAK,qBAAqB,OAAO;AAQpE,eAAW,OAAO,QAAS,cAAa,IAAI,GAAG;AAC/C,QAAI;AACF,YAAM,KAAK,MAAMA,MAAK,KAAK,mBAAmB;AAC9C,YAAM,gBAAgB,UAAU,QAAQ,KAAK,OAAO,WAAW,SAAS,OAAO;AAC/E,UAAI,GAAG,SAAS,cAAc;AAC5B,aAAK,0BAA0B;AAAA,UAC7B,UAAU,EAAE,MAAM,GAAG,MAAM,SAAS,GAAG,QAAQ;AAAA,UAC/C,MAAM;AAAA,QACR;AAAA,MACF,OAAO;AAGL,aAAK,0BAA0B;AAAA,MACjC;AAAA,IACF,QAAQ;AAEN,WAAK,0BAA0B;AAAA,IACjC;AACA,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,oBAAoB,QAAgD;AACxE,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,KAAK,kBAAkB;AAC7B,UAAM,WAAWP,OAAK,KAAK,KAAK,UAAU,sBAAsB;AAChE,UAAM,QAAQ,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,IAAI,IAAI;AACxE,QAAI;AACF,YAAM,KAAK,wBAAwB,UAAU,KAAK;AAClD,aAAO,OAAO;AAAA,IAChB,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAAgB,KAAqC;AAC3E,UAAM,YAAY,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,KAAK,MAAM,KAAK,CAAC,CAAC,IAAI;AAC5F,UAAM,WAAWA,OAAK,KAAK,KAAK,UAAU,sBAAsB;AAChE,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,sBAAsB,QAAQ;AACrD,YAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC;AACrE,YAAM,SAAgC,CAAC;AACvC,iBAAW,QAAQ,OAAO;AACxB,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cACE,OAAO,OAAO,aAAa,YAC3B,OAAO,SAAS,WAAW,KAC3B,OAAO,OAAO,UAAU,YACxB,OAAO,MAAM,WAAW,KACxB,OAAO,OAAO,gBAAgB,YAC9B,OAAO,YAAY,WAAW,KAC9B,OAAO,WAAW,eAClB;AACA;AAAA,UACF;AACA,iBAAO,KAAK;AAAA,YACV,UAAU,OAAO;AAAA,YACjB,OAAO,OAAO;AAAA,YACd,aAAa,OAAO;AAAA,YACpB,QAAQ;AAAA,UACV,CAAC;AAAA,QACH,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AACA,aAAO,OAAO,MAAM,CAAC,SAAS;AAAA,IAChC,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,QAAgB,KAAqC;AAC7E,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,sBAAsB,KAAK,mBAAmB;AACrE,YAAM,MAA6B,CAAC;AACpC,YAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,eAAS,IAAI,MAAM,SAAS,GAAG,KAAK,KAAK,IAAI,SAAS,aAAa,KAAK,GAAG;AACzE,cAAM,MAAM,MAAM,CAAC,GAAG,KAAK;AAC3B,YAAI,CAAC,IAAK;AACV,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cACE,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,WAAW,UACzB;AACA,gBAAI,KAAK,MAA6B;AAAA,UACxC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,aAAO,IAAI,QAAQ;AAAA,IACrB,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,QAAgB,KAAmC;AAC9E,YAAQ,MAAM,KAAK,0BAA0B,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK;AAAA,EAC7E;AAAA,EAEA,MAAM,0BAA0B,QAAgB,KAAiE;AAC/G,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,KAAK,OAAO,MAAM,WAAW,EAAG,QAAO,CAAC;AAE5D,QAAI;AACF,aAAO,MAAM;AAAA,QACX,wBAAwB,KAAK,mBAAmB,MAAM,KAAK,sBAAsB,KAAK,iBAAiB,CAAC;AAAA,QACxG;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,+BAAgE;AACpE,WAAO,iCAAiC,KAAK,2BAA2B,CAAC,MAAM,KAAK,sBAAsB,CAAC,CAAC;AAAA,EAC9G;AAAA;AAAA;AAAA,EAIA,MAAM,kDAAmE;AACvE,WAAO,6BAA6B,KAAK,2BAA2B,KAAK,iBAAiB,KAAK,OAAO;AAAA,EACxG;AAAA,EACA,MAAM,4CAA6E;AACjF,QAAI,CAAE,MAAM,gCAAgC,KAAK,yBAAyB,GAAI;AAC5E,aAAO,iCAAiC,KAAK,2BAA2B,CAAC,MAAM,KAAK,sBAAsB,CAAC,CAAC;AAAA,IAC9G;AACA,WAAO;AAAA,MAAuC,KAAK;AAAA,MAA2B,CAAC,MAC7E,6BAA6B,GAAG,KAAK,iBAAiB,KAAK,OAAO;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAM,0BAA0B,QAAgB,KAAsC;AACpF,WAAO;AAAA,MACL,KAAK;AAAA,MACL,CAAC,MAAM,KAAK,sBAAsB,CAAC;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,2BAA2B,SAAgC;AAC/D,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,uBAAuB,KAAK,2BAA2B,OAAO;AAAA,EAC3E;AAAA,EAEA,MAAM,4BAAoD;AACxD,QAAI;AACF,aAAO,MAAM,KAAK,sBAAsB,KAAK,yBAAyB;AAAA,IACxE,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,+BAA+B,SAAgC;AACnE,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,uBAAuB,KAAK,+BAA+B,OAAO;AAAA,EAC/E;AAAA,EAEA,MAAM,gCAAwD;AAC5D,QAAI;AACF,aAAO,MAAM,KAAK,sBAAsB,KAAK,6BAA6B;AAAA,IAC5E,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,wCAAwC,OAA0D;AACtG,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,uBAAuB,KAAK,+BAA+B,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EAC7G;AAAA,EAEA,MAAM,oCAAoC,OAA0D;AAClG,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,uBAAuB,KAAK,oCAAoC,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAAA,EAClH;AAAA,EAEA,MAAM,yCAA6F;AACjG,WAAO,KAAK,kCAAkC,KAAK,6BAA6B;AAAA,EAClF;AAAA,EAEA,MAAM,qCAAyF;AAC7F,WAAO,KAAK,kCAAkC,KAAK,kCAAkC;AAAA,EACvF;AAAA,EAEA,MAAM,kCAAkC,SAGnB;AACnB,UAAM,CAAC,cAAc,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,MACnD,KAAK,8BAA8B;AAAA,MACnC,KAAK,mCAAmC;AAAA,IAC1C,CAAC;AACD,QAAI,CAAC,gBAAgB,CAAC,WAAY,QAAO;AACzC,QACE,OAAO,SAAS,wBAAwB,YACxC,QAAQ,oBAAoB,SAAS,KACrC,WAAW,gBAAgB,QAAQ,qBACnC;AACA,aAAO;AAAA,IACT;AACA,QACE,OAAO,SAAS,6BAA6B,YAC7C,OAAO,SAAS,QAAQ,wBAAwB,KAChD,WAAW,qBAAqB,QAAQ,0BACxC;AACA,aAAO;AAAA,IACT;AACA,QAAI,WAAW,aAAa;AAC1B,YAAM,cAAcQ,YAAW,QAAQ,EAAE,OAAO,YAAY,EAAE,OAAO,KAAK;AAC1E,UAAI,gBAAgB,WAAW,YAAa,QAAO;AAAA,IACrD;AAEA,UAAM,KAAK,2BAA2B,YAAY;AAClD,UAAM,KAAK,wCAAwC;AAAA,MACjD,GAAG;AAAA,MACH,iBAAiB;AAAA,IACnB,CAAC;AACD,UAAM,QAAQ,IAAI;AAAA,MAChBL,QAAO,KAAK,6BAA6B,EAAE,MAAM,MAAM,MAAS;AAAA,MAChEA,QAAO,KAAK,kCAAkC,EAAE,MAAM,MAAM,MAAS;AAAA,IACvE,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kCACZ,UACoD;AACpD,WAAO,KAAK,gBAAgB,kCAAkC,QAAQ;AAAA,EACxE;AAAA,EAEA,MAAM,oBAAoB,SAAgC;AACxD,WAAO,KAAK,wBAAwB,oBAAoB,OAAO;AAAA,EACjE;AAAA,EAEA,MAAM,qBAA6C;AACjD,WAAO,KAAK,wBAAwB,mBAAmB;AAAA,EACzD;AAAA,EAEA,MAAM,yBAAyB,OAAuE;AACpG,WAAO,KAAK,wBAAwB,yBAAyB,KAAK;AAAA,EACpE;AAAA,EAEA,MAAM,wBACJ,QAAgB,KAChB,QAAmC,OACE;AACrC,WAAO,KAAK,wBAAwB,wBAAwB,OAAO,KAAK;AAAA,EAC1E;AAAA,EAEA,MAAM,wBACJ,IACA,SAC0C;AAC1C,WAAO,KAAK,wBAAwB,wBAAwB,IAAI,OAAO;AAAA,EACzE;AAAA,EAEA,MAAM,mBAAmB,QAA8B,KAAa,SAAkC;AACpG,WAAO,KAAK,wBAAwB,mBAAmB,QAAQ,KAAK,OAAO;AAAA,EAC7E;AAAA,EAEA,MAAM,kBAAkB,QAA8B,KAAqC;AACzF,WAAO,KAAK,wBAAwB,kBAAkB,QAAQ,GAAG;AAAA,EACnE;AAAA,EAEA,MAAM,8BAA8B,SAAgC;AAClE,WAAO,KAAK,wBAAwB,8BAA8B,OAAO;AAAA,EAC3E;AAAA,EAEA,MAAM,+BAAuD;AAC3D,WAAO,KAAK,wBAAwB,6BAA6B;AAAA,EACnE;AAAA,EAEA,MAAM,sCAA4E;AAChF,WAAO,KAAK,wBAAwB,oCAAoC;AAAA,EAC1E;AAAA,EAEA,MAAM,8BAA8B,OAAsE;AACxG,WAAO,KAAK,wBAAwB,8BAA8B,KAAK;AAAA,EACzE;AAAA,EAEA,MAAM,8BACJ,IACA,OAC2C;AAC3C,WAAO,KAAK,wBAAwB,8BAA8B,IAAI,KAAK;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA,EAMQ,WAAW,SAAiB,KAAa;AAC/C,UAAM,KAAK,KAAK,IAAI,EAAE,SAAS,EAAE;AACjC,UAAM,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC;AAClD,WAAO,GAAG,MAAM,IAAI,EAAE,IAAI,IAAI;AAAA,EAChC;AAAA,EAEA,MAAM,cAAc,UAAkB,SAAiB,UAAmC;AACxF,UAAM,MAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAElD,UAAM,KAAK,KAAK,WAAW,GAAG;AAC9B,UAAM,cAAuC;AAAA,MAC3C;AAAA,MACA,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,MAChC;AAAA,MACA,UAAU;AAAA,MACV,GAAI,KAAK,sBAAsB,IAAI,EAAE,MAAM,kBAAkB,IAAI,CAAC;AAAA,IACpE;AAEA,UAAM,UAAU;AAAA,EAAQ,OAAO,QAAQ,WAAW,EAC/C,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,EAAE,EAC5C,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,EAAY,QAAQ;AAAA;AAAA,eAAoB,OAAO;AAAA;AAE5D,UAAM,WAAWH,OAAK,KAAK,KAAK,cAAc,GAAG,EAAE,KAAK;AACxD,UAAM,KAAK,uBAAuB,UAAU,OAAO;AAEnD,QAAI,MAAM,kBAAkB,EAAE,OAAO,QAAQ,EAAE;AAC/C,SAAK,yBAAyB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,MAUlB;AACA,WAAO,KAAK,gBAAgB,cAAc,IAAI;AAAA,EAChD;AAAA;AAAA,EAGA,2BAAiC;AAC/B,oBAAe,eAAe,OAAO,KAAK,YAAY;AAAA,EACxD;AAAA,EAEQ,kBAAkB,KAAa,UAAkB;AACvD,WAAO,kBAAsB,KAAK,QAAQ;AAAA,EAC5C;AAAA,EAEA,MAAM,gBAAgB,IAA8B;AAClD,UAAM,YAAY,MAAM,KAAK,cAAc;AAC3C,UAAM,IAAI,UAAU,KAAK,CAACe,OAAMA,GAAE,OAAO,EAAE;AAC3C,QAAI,CAAC,EAAG,QAAO;AAEf,QAAI,MAAM,MAAM,KAAK,sBAAsB,EAAE,QAAQ;AACrD,UAAM,IAAI,QAAQ,mBAAmB,gBAAgB;AACrD,UAAM,IAAI,QAAQ,WAAW,iBAAgB,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA,CAAY;AACjF,UAAM,KAAK,uBAAuB,EAAE,UAAU,GAAG;AACjD,SAAK,yBAAyB;AAC9B,QAAI,MAAM,qBAAqB,EAAE,EAAE;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,cAAsB,WAAqC;AAC5E,UAAM,eAAe,KAAK,iBAAiB,cAAc,SAAS;AAClE,QAAI;AACF,aAAO,MAAMN,UAAS,cAAc,OAAO;AAAA,IAC7C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,cAAsB,SAAiB,WAAmC;AAC5F,UAAM,eAAe,KAAK,iBAAiB,cAAc,SAAS;AAClE,UAAMC,WAAU,cAAc,SAAS,OAAO;AAC9C,QAAI,MAAM,mCAAmC,QAAQ,MAAM,SAAS;AAAA,EACtE;AAAA;AAAA,EAGA,OAAwB,qBAAqB;AAAA;AAAA,EAE7C,OAAwB,yBAAyB,KAAK,KAAK;AAAA,EAE3D,MAAM,iBACJ,cACA,YACA,MACe;AACf,UAAM,eAAe,KAAK,iBAAiB,cAAc,MAAM,SAAS;AAExE,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAMD,UAAS,cAAc,OAAO;AAAA,IACjD,QAAQ;AAAA,IAER;AAEA,UAAM,UAAU,MAAM;AACtB,UAAM,gBACJ,SAAS,YAAY,QACrB,QAAQ,kBAAkB,QAC1B,MAAM,QAAQ,QAAQ,WAAW,KACjC,QAAQ,YAAY,SAAST,OAAK,SAAS,YAAY,CAAC;AAG1D,QAAI,eAAe;AACjB,YAAM,WAAW,QAAQ;AACzB,UAAI,SAAS,SAAS,UAAU;AAC9B,cAAM,aAAaA,OAAK,KAAK,cAAc,QAAQ,UAAU;AAC7D,cAAM,EAAE,WAAW,IAAI,MAAM,4BAA4B;AAAA,UACvD,UAAU;AAAA,UACV;AAAA,UACA,eAAe;AAAA,UACf,eAAe,QAAQ;AAAA,QACzB,CAAC;AACD,cAAMU,WAAU,cAAc,YAAY,OAAO;AACjD,mBAAW;AACX,YAAI,KAAK,wCAAwC,SAAS,MAAM,oBAAoB,QAAQ,GAAG;AAAA,MACjG;AAAA,IACF,OAAO;AAEL,UAAI,SAAS,SAAS,gBAAe,oBAAoB;AACvD,YAAI;AAAA,UACF,kBAAkB,SAAS,MAAM,iBAAiB,gBAAe,kBAAkB;AAAA,QACrF;AACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,SAAS,MAAM,4BAA4B;AAC7D,QAAI,WAAW;AAEb,YAAM,aAAa,CAAC,GAAG,SAAS,SAAS,wBAAwB,CAAC;AAClE,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,gBAAgB,WAAW,WAAW,SAAS,CAAC,EAAE,CAAC;AACzD,cAAM,UAAU,KAAK,IAAI,IAAI,IAAI,KAAK,aAAa,EAAE,QAAQ;AAC7D,YAAI,UAAU,gBAAe,wBAAwB;AACnD,cAAI;AAAA,YACF,wBAAwB,KAAK,MAAM,UAAU,GAAI,CAAC,sBAAsB,gBAAe,yBAAyB,GAAI;AAAA,UACtH;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,UAAU;AAAA;AAAA,uBAAuB,SAAS;AAAA;AAAA,EAAO,UAAU;AAAA;AAEjE,UAAMA,WAAU,cAAc,WAAW,SAAS,OAAO;AACzD,QAAI,MAAM,0BAA0B,YAAY,EAAE;AAAA,EACpD;AAAA,EAEA,MAAM,0BAAkD;AACtD,QAAI;AACF,aAAO,MAAM,KAAK,sBAAsB,KAAK,uBAAuB;AAAA,IACtE,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,yBAAyB,SAAgC;AAC7D,UAAM,MAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAM,KAAK,uBAAuB,KAAK,yBAAyB,OAAO;AAAA,EACzE;AAAA,EAEA,MAAM,yBAAyB,YAAmC;AAChE,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAM,KAAK,sBAAsB,KAAK,uBAAuB;AAAA,IAC1E,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,IAEzC;AAEA,QAAI,SAAS,SAAS,gBAAe,oBAAoB;AACvD,UAAI;AAAA,QACF,8BAA8B,SAAS,MAAM,iBAAiB,gBAAe,kBAAkB;AAAA,MACjG;AACA;AAAA,IACF;AAEA,UAAM,aAAa,CAAC,GAAG,SAAS,SAAS,wBAAwB,CAAC;AAClE,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,gBAAgB,WAAW,WAAW,SAAS,CAAC,EAAE,CAAC;AACzD,YAAM,UAAU,KAAK,IAAI,IAAI,IAAI,KAAK,aAAa,EAAE,QAAQ;AAC7D,UAAI,UAAU,gBAAe,wBAAwB;AACnD,YAAI;AAAA,UACF,wBAAwB,KAAK,MAAM,UAAU,GAAI,CAAC,sBAAsB,gBAAe,yBAAyB,GAAI;AAAA,QACtH;AACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,UAAU,GAAG,SAAS,QAAQ,EAAE,SAAS,IAAI,SAAS,EAAE,wBAAmB,SAAS;AAAA;AAAA,EAAO,UAAU;AAAA;AAC3G,UAAM,MAAM,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;AACjD,UAAM,KAAK,uBAAuB,KAAK,yBAAyB,GAAG,SAAS,QAAQ,CAAC,GAAG,OAAO,EAAE;AACjG,QAAI,MAAM,0CAA0C,KAAK,uBAAuB,EAAE;AAAA,EACpF;AAAA;AAAA;AAAA,EAIA,MAAM,sBAAsB,MAAc,KAAwC;AAChF,WAAO,KAAK,YAAY,sBAAsB,MAAM,GAAG;AAAA,EACzD;AAAA,EAEA,MAAM,kBAAkB,MAAc,OAA4B,YAAmC;AACnG,WAAO,KAAK,YAAY,kBAAkB,MAAM,OAAO,UAAU;AAAA,EACnE;AAAA,EAEA,MAAM,eAAe,MAAc,OAA8B;AAC/D,WAAO,KAAK,YAAY,eAAe,MAAM,KAAK;AAAA,EACpD;AAAA,EAEA,MAAM,sBACJ,MACA,WACA,UAOI,CAAC,GACU;AACf,WAAO,KAAK,YAAY,sBAAsB,MAAM,WAAW,OAAO;AAAA,EACxE;AAAA;AAAA,EAGA,MAAM,oBAAoB,MAAc,SAAgC;AACtE,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,MAAM,MAAM,KAAK,WAAW,IAAI;AACtC,UAAM,KAAK,sBAAsB,MAAM,SAAS;AAAA,MAC9C,iBAAiB;AAAA,MACjB,wBAAwB,MAAM,gBAAgB,KAAK,KAAK,aAAa,EAAE,SAAS,SAAS;AAAA,MACzF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,2BAA8C;AAClD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,sBAAsB,KAAK,wBAAwB;AAC1E,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,aAAO,MAAM,QAAQ,OAAO,WAAW,IACnC,OAAO,YAAY,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IAC/E,CAAC;AAAA,IACP,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,8BAAiD;AACrD,UAAM,cAAc,MAAM,KAAK,gBAAgB;AAC/C,UAAM,qBAAqB,MAAM,QAAQ;AAAA,MACvC,YAAY,IAAI,OAAO,eAAe;AACpC,cAAM,MAAM,MAAM,KAAK,WAAW,UAAU;AAC5C,YAAI,CAAC,IAAK,QAAO;AACjB,eAAO;AAAA,UACL;AAAA,UACA,QAAQ,gBAAgB,KAAK,KAAK,aAAa;AAAA,QACjD;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,mBAAmB,mBACtB,OAAO,CAAC,UAA+D,UAAU,IAAI,EACrF,OAAO,CAAC,EAAE,OAAO,MAAM,uBAAuB,MAAM,CAAC,EACrD,KAAK,CAAC,MAAM,UAAU;AACrB,YAAM,SAAS,8BAA8B,KAAK,MAAM,KAAK;AAC7D,YAAM,UAAU,8BAA8B,MAAM,MAAM,KAAK;AAC/D,aAAO,wBAAwB,SAAS,MAAM;AAAA,IAChD,CAAC,EACA,IAAI,CAAC,EAAE,WAAW,MAAM,UAAU;AAErC,UAAM,MAAM,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,KAAK;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,QACH;AAAA,UACE,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC,aAAa;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI;AAAA,IACN;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kCAAkC,aAAsC;AAC5E,QAAI,YAAY,WAAW,EAAG;AAC9B,UAAM,QAAQ,MAAM,KAAK,yBAAyB;AAClD,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,WAAW,IAAI,IAAI,WAAW;AACpC,UAAM,YAAY,MAAM,OAAO,CAAC,SAAS,CAAC,SAAS,IAAI,IAAI,CAAC;AAC5D,UAAM,MAAM,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,KAAK;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,QACH;AAAA,UACE,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC,aAAa;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI;AAAA,IACN;AAAA,EACF;AAAA,EAEA,MAAM,4CAA0F;AAC9F,WAAO,KAAK,YAAY,0CAA0C;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAmB,SAAoD;AAC3E,WAAO,KAAK,YAAY,mBAAmB,OAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,YAAY,QAAoB,KAAmB;AAExD,UAAM,UAAU,OAAO,UAAU,IAAI,KAAK,OAAO,OAAO,EAAE,QAAQ,IAAI;AACtE,UAAM,YAAY,KAAK,IAAI,IAAI,IAAI,QAAQ,IAAI,YAAY,MAAO,KAAK,KAAK,GAAG;AAC/E,UAAM,UAAU,KAAK,IAAI,YAAY;AAGrC,UAAM,YAAY,KAAK,IAAI,OAAO,MAAM,SAAS,IAAI,CAAG;AAGxD,UAAM,gBAAgB,KAAK,IAAI,OAAO,SAAS,SAAS,IAAI,CAAG;AAG/D,UAAM,gBAAwC;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,UAAM,eAAe,cAAc,OAAO,KAAK,YAAY,CAAC,KAAK;AAGjE,UAAM,aAAa,KAAK,IAAI,OAAO,cAAc,SAAS,GAAG,CAAG;AAEhE,WAAO,UAAU,MAAM,YAAY,OAAO,gBAAgB,OAAO,eAAe,MAAM,aAAa;AAAA,EACrG;AAAA,EAEA,MAAM,oBACJ,QACA,WAC8C;AAC9C,WAAO,KAAK,YAAY,oBAAoB,QAAQ,SAAS;AAAA,EAC/D;AAAA;AAAA,EAGA,gCAAsC;AACpC,SAAK,sBAAsB;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAwB,oBAAoB;AAAA,EAE5C,MAAM,0BAA2C;AAC/C,WAAO,KAAK,YAAY,wBAAwB;AAAA,EAClD;AAAA,EAEA,MAAM,wBAAwB,WAA0C;AACtE,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,KAAK,IAAI,IAAI,YAAY,KAAK,KAAK,KAAK;AACvD,UAAM,UAAwB,CAAC;AAE/B,eAAW,KAAK,UAAU;AACxB,UAAI,EAAE,YAAY,aAAa,aAAc;AAG7C,YAAM,aAAa,EAAE,YAAY,KAAK,KAAK,CAAC,MAAM,MAAM,eAAe,MAAM,SAAS;AACtF,UAAI,CAAC,WAAY;AAEjB,YAAM,YAAY,IAAI,KAAK,EAAE,YAAY,OAAO,EAAE,QAAQ;AAC1D,UAAI,aAAa,OAAQ;AACzB,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,2BAA2B,GAAG,CAAC,YAAY;AACpE,gBAAM,kBAAkB,QAAQ,YAAY,KAAK,KAAK,CAAC,QAAQ,QAAQ,eAAe,QAAQ,SAAS;AACvG,gBAAM,mBAAmB,IAAI,KAAK,QAAQ,YAAY,OAAO,EAAE,QAAQ;AACvE,iBAAO,mBAAmB,mBAAmB;AAAA,QAC/C,CAAC;AACD,YAAI,SAAS;AACX,kBAAQ,KAAK,OAAO;AACpB,cAAI,MAAM,8BAA8B,QAAQ,YAAY,EAAE,EAAE;AAAA,QAClE;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,GAAG;AACtB,WAAK,wBAAwB;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAoB,SAAiD;AACzE,QAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC;AACpE,UAAM,gBAAgB,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAACV,OAAK,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;AAC5E,QAAI,UAAU;AAKd,UAAM,cAAc,KAAK,uBAAuB;AAKhD,UAAM,QAAQ,KAAK,cAAc;AACjC,UAAM,OACJ,KAAK,2BACL,kBAAkB,KAAK,SAAS,aAAa,OAAO,KAAK,cAAc,CAAC,MAAM;AAIhF,UAAM,iBAAiB,oBAAI,IAA2D;AAEtF,eAAW,SAAS,SAAS;AAC3B,YAAM,SAAS,MAAM,aACjB,cAAc,IAAIA,OAAK,QAAQ,MAAM,UAAU,CAAC,IAChD,UAAU,IAAI,MAAM,QAAQ;AAChC,UAAI,CAAC,OAAQ;AAEb,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,mCAAmC,OAAO,MAAM,OAAO,YAAY;AAC5F,cAAI,SAAS,YAAY,OAAO,MAAM,SAAU,QAAO;AACvD,gBAAM,SAAS,KAAK,qBAAqB;AACzC,gBAAM,QAAsC;AAAA,YAC1C,EAAE,GAAG,QAAQ,aAAa,aAAa,MAAM,UAAU,cAAc,MAAM,aAAa;AAAA,YACxF;AAAA,UACF;AACA,gBAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC;AAAA;AAAA,EAAO,QAAQ,OAAO;AAAA;AAC1F,gBAAM,KAAK,iCAAiC,SAAS,aAAa,KAAK;AACvE,cAAI,OAAO,QAAQ,YAAY,cAAc,UAAU;AACrD,kBAAM,KAAK,gBAAgB;AAAA,cACzB,QAAQ;AAAA,cACR;AAAA,cACA,QAAQ,YAAY;AAAA,cACpB;AAAA,cACA,QAAQ;AAAA,cACR,EAAE,eAAe,QAAQ;AAAA,YAC3B;AAAA,UACF;AACA,iBAAO,EAAE,SAAS,MAAM;AAAA,QAC1B,CAAC;AACD,YAAI,YAAY,KAAM;AACtB,YAAI,MAAM;AACR,6BAAmB,KAAK,SAAS,EAAE,GAAG,QAAQ,SAAS,aAAa,QAAQ,MAAM,GAAG,KAAK;AAAA,QAC5F;AACA,uBAAe,IAAIA,OAAK,QAAQ,OAAO,IAAI,GAAG;AAAA,UAC5C,aAAa,MAAM;AAAA,UACnB,cAAc,MAAM;AAAA,QACtB,CAAC;AACD;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,MAAM,wCAAwC,MAAM,QAAQ,KAAK,GAAG,EAAE;AAAA,MAC5E;AAAA,IACF;AAEA,QAAI,UAAU,GAAG;AAQf,YAAM,EAAE,UAAU,UAAU,IAAI,KAAK,iCAAiC;AAMtE,gCAA0B,KAAK,OAAO;AACtC,UACE,QACA,aACA,aAAa,cAAc,KAC3B,KAAK,uBAAuB,MAAM,YAClC,KAAK,cAAc,MAAM,OACzB;AACA,cAAM,MAAM,kBAAkB,KAAK,SAAS,aAAa,KAAK;AAC9D,YAAI,KAAK;AAQP,gBAAM,YAAY,IAAI,IAAI,CAAC,MAAM;AAC/B,kBAAM,QAAQ,eAAe,IAAIA,OAAK,QAAQ,EAAE,IAAI,CAAC;AACrD,mBAAO,QACH;AAAA,cACE,GAAG;AAAA,cACH,aAAa,EAAE,GAAG,EAAE,aAAa,aAAa,MAAM,aAAa,cAAc,MAAM,aAAa;AAAA,YACpG,IACA;AAAA,UACN,CAAC;AACD,4BAAkB,KAAK,SAAS,WAAW,UAAU,OAAO,KAAK,cAAc,CAAC;AAAA,QAClF;AAAA,MACF;AAMA,uCAAiC,KAAK,OAAO;AAC7C,UAAI,MAAM,+BAA+B,OAAO,WAAW;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,IAAwC;AAC1D,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,WAAO,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,EAAE,KAAK;AAAA,EAC1D;AAAA,EAEA,MAAM,+BAA+B,IAAwC;AAC3E,UAAM,SAAS,MAAM,KAAK,cAAc,EAAE;AAC1C,WAAO,WAAW,MAAM,KAAK,oBAAoB,GAAG,KAAK,CAAC,WAAW,OAAO,YAAY,OAAO,EAAE,MAC9F,MAAM,KAAK,qBAAqB,GAAG,KAAK,CAAC,WAAW,OAAO,YAAY,OAAO,EAAE,KAAK;AAAA,EAC1F;AAAA;AAAA,EAGA,MAAM,wBACJ,KACA,iBAAwC,oBAAI,IAAI,GAChB;AAChC,QAAI,IAAI,WAAW,EAAG,QAAO,oBAAI,IAAI;AACrC,UAAM,YAAY,IAAI,IAAI,GAAG;AAC7B,UAAM,YAAY,MAAM,KAAK,yBAAyB;AACtD,UAAM,YAAY,oBAAI,IAAsB;AAC5C,UAAM,gBAAgB,oBAAI,IAAsB;AAChD,eAAW,YAAY,WAAW;AAChC,YAAM,WAAWA,OAAK,SAAS,UAAU,KAAK;AAC9C,UAAI,CAAC,UAAU,IAAI,QAAQ,EAAG;AAC9B,YAAM,QAAQ,cAAc,IAAI,QAAQ,KAAK,CAAC;AAC9C,YAAM,KAAK,QAAQ;AACnB,oBAAc,IAAI,UAAU,KAAK;AAAA,IACnC;AACA,eAAW,MAAM,WAAW;AAC1B,YAAM,gBAAgB,cAAc,IAAI,EAAE,KAAK,CAAC;AAChD,YAAM,YAAY,eAAe,IAAI,EAAE,KAAK,CAAC;AAC7C,YAAM,mBAA6B,CAAC;AACpC,iBAAW,iBAAiB,WAAW;AACrC,cAAM,mBAAmB,IAAI,IAAI,wBAAwB,KAAK,SAAS,aAAa,CAAC;AACrF,cAAM,cAAc,cAAc,KAAK,CAAC,aAAa,iBAAiB,IAAIA,OAAK,QAAQ,QAAQ,CAAC,CAAC;AACjG,YAAI,aAAa;AACf,2BAAiB,KAAK,WAAW;AACjC;AAAA,QACF;AAEA,cAAM,aAAa,oBAAI,IAAY;AACnC,cAAM,QAAQ,uBAAuB,aAAa;AAClD,YAAI,OAAO;AACT,qBAAW,aAAa,wBAAwB,KAAK,SAAS,MAAM,YAAY,GAAG;AACjF,uBAAW,IAAI,SAAS;AAAA,UAC1B;AAAA,QACF;AACA,cAAM,QAAQ,cAAc,KAAK,CAAC,aAAa,WAAW,IAAIA,OAAK,QAAQ,QAAQ,CAAC,CAAC;AACrF,YAAI,MAAO,kBAAiB,KAAK,KAAK;AAAA,MACxC;AACA,UAAI,iBAAiB,SAAS,GAAG;AAC/B,kBAAU,IAAI,IAAI,gBAAgB;AAAA,MACpC,WAAW,cAAc,SAAS,GAAG;AACnC,kBAAU,IAAI,IAAI,aAAa;AAAA,MACjC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBAAwB,KAAqC;AACjE,WAAO,IAAI,KAAK,MAAM,KAAK,wBAAwB,GAAG,GAAG,KAAK,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,wBAAwB,IAA0D;AACtF,UAAM,YAAY,yBAAyB,KAAK,SAAS,EAAE;AAC3D,QAAI,UAAW,QAAO;AACtB,2BAAuB,KAAK,SAAS,yBAAyB;AAC9D,UAAM,SAAS,MAAM,KAAK,cAAc,EAAE;AAC1C,QAAI,OAAQ,QAAO,KAAK,wBAAwB,QAAQ,QAAQ;AAEhE,UAAM,YAAY,MAAM,KAAK,qBAAqB,GAAG,KAAK,CAAC,WAAW,OAAO,YAAY,OAAO,EAAE;AAClG,QAAI,CAAC,SAAU,QAAO;AAEtB,WAAO,KAAK,wBAAwB,UAAU,UAAU;AAAA,EAC1D;AAAA,EAEA,MAAM,wBAAwB,SAAkF;AAC9G,WACE,0BAA0B,KAAK,SAAS,OAAO,KAC/C,uBAAuB,KAAK,SAAS,yBAAyB;AAAA,EAElE;AAAA,EAEA,MAAM,+BAA0F;AAC9F,WAAO,8BAA8B,KAAK,OAAO;AAAA,EACnD;AAAA,EAEQ,wBAAwB,QAAoB,gBAA4D;AAC9G,UAAM,UAAU,gBAAgB,KAAK,SAAS,OAAO,IAAI;AACzD,WAAO;AAAA,MACL,UAAU,OAAO,YAAY;AAAA,MAC7B,UAAU,OAAO,YAAY;AAAA,MAC7B,QAAQ,wBAAwB,OAAO,aAAa,SAAS,cAAc;AAAA,MAC3E,gBAAgB,OAAO,YAAY;AAAA,MACnC,MAAM,OAAO;AAAA,MACb;AAAA,MACA,SAAS,OAAO,YAAY;AAAA,MAC5B,SAAS,OAAO,YAAY;AAAA,MAC5B,YAAY,OAAO,YAAY;AAAA,MAC/B,cAAc,OAAO,YAAY;AAAA,MACjC,WAAW,OAAO,YAAY;AAAA,MAC9B,QAAQ,OAAO,YAAY;AAAA,MAC3B,YAAY,OAAO,YAAY;AAAA,MAC/B,gBAAgB,OAAO,YAAY;AAAA,MACnC,YAAY,OAAO,YAAY;AAAA,MAC/B,aAAa,OAAO,YAAY;AAAA,MAChC,cAAc,OAAO,YAAY;AAAA,MACjC,MAAM,wBAAwB,OAAO,YAAY,IAAI;AAAA,MACrD,SAAS,2BAA2B,OAAO,OAAO;AAAA,MAClD,eAAe,+BAA+B,MAAM;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,UAAkB,QAAgB,KAAsC;AAC9F,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACjD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAE/B,UAAM,YAAY,4BAA4B,KAAK,SAAS,UAAU,WAAW;AACjF,QAAI,aAAa,UAAU,SAAS,EAAG,QAAO;AAC9C,WAAO,KAAK,2BAA2B,uBAAuB;AAAA,MAC5D,SAAS,KAAK;AAAA,MACd,YAAY,KAAK;AAAA,MACjB;AAAA,MACA;AAAA,MACA,gBAAgB,CAAC,MAAM,KAAK,sBAAsB,CAAC;AAAA,MACnD,eAAe,MAAM,oBAAoB,wBAAwB,KAAK,OAAO,CAAC;AAAA,IAChF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WACJ,UACA,YACA,YACA,UACA,SACA,UAmCI,CAAC,GACY;AACjB,UAAM,KAAK,kBAAkB;AAC7B,UAAM,eAAe,QAAQ;AAC7B,QAAI,SAAS,OAAO,QAAQ,cAAc,WAAW,KAAK,qBAAqB,IAAI;AACnF,QAAI,OAAQ,WAAqB,4BAA4B,SAAS,MAAM;AAC5E,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE;AAC3C,UAAM,KAAK,GAAG,QAAQ,UAAU,UAAU;AAC1C,UAAM,OAAO,QAAQ,cAAc;AACnC,UAAM,OAAO,eAAe,IAAI;AAChC,UAAM,UAAU,8BAA8B,WAAW,QAAQ,OAAO;AACxE,UAAM,iBAAiB,8BAA8B,aAAa,QAAQ,SAAS;AACnF,UAAM,kBAAkB,8BAA8B,cAAc,QAAQ,UAAU;AACtF,UAAM,YAAY,sBAAsB,OAAO;AAC/C,QAAI,CAAC,UAAU,OAAO;AACpB,UAAI,KAAK,+BAA+B,EAAE,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,IAC7F;AAEA,UAAM,KAAwB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,SAAS,IAAI,YAAY;AAAA,MACzB,SAAS,IAAI,YAAY;AAAA,MACzB,QAAQ,QAAQ,UAAU;AAAA,MAC1B,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACvB,WAAW,QAAQ;AAAA,MACnB,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,QAAQ;AAAA,MACpB,kBAAkB,QAAQ;AAAA,MAC1B,mBAAmB,QAAQ;AAAA,MAC3B,YAAY,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,iBAAiB,QAAQ;AAAA,MACzB,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACnD,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC5D,GAAI,QAAQ,eAAe,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;AAAA,MACrE,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,MACtD,GAAI,QAAQ,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,MAC/D,GAAI,QAAQ,kBAAkB,EAAE,iBAAiB,QAAQ,gBAAgB,IAAI,CAAC;AAAA,MAC9E,GAAI,QAAQ,SAAS,EAAE,QAAQ,iBAAiB,QAAQ,MAAM,EAAE,IAAI,CAAC;AAAA,MACrE,GAAI,QAAQ,cACZ,sCAAsC;AAAA,QACpC,SAAS,UAAU;AAAA,QACnB,iBAAiB,QAAQ;AAAA,MAC3B,CAAC,IACG,EAAE,YAAY,KAAc,IAC5B,CAAC;AAAA,IACP;AAEA,UAAM,WAAW,MAAM,KAAK,yBAAyB,UAAU,IAAI,KAAK;AACxE,UAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,EAAE,CAAC,CAAC;AAAA;AAAA,EAAO,UAAU,IAAI;AAAA;AAEtF,UAAM,UAAU,MAAM,KAAK;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,MAAM,KAAK,mCAAmC,UAAU,MAAM,UAAU,GAAG,eAAe;AAAA,MAC1F,OAAO,eAAe;AACpB,YAAI,UAAU,OAAO,iBAAiB,UAAU;AAC9C,gBAAM,KAAK,gBAAgB,OAAO,UAAU,IAAI,cAAc,QAAQ,UAAU,MAAM;AAAA,YACpF,YAAY;AAAA,YACZ,GAAI,aAAa,EAAE,eAAe,WAAW,IAAI,EAAE,cAAc,SAAS;AAAA,UAC5E,CAAC;AAAA,QACH;AAGA,cAAM,KAAK,sBAAsB,EAAE,WAAW,SAAS,GAAG,eAAe;AACzE,YAAI,MAAM,eAAe,EAAE,KAAK,aAAa,CAAC,IAAI,UAAU,QAAQ,QAAQ,EAAE;AAAA,MAChF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAmB,UAAyC;AAChE,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,WAAO,SACJ,OAAO,CAAC,MAAM,EAAE,YAAY,aAAa,QAAQ,EACjD,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,cAAc,MAAM,EAAE,YAAY,cAAc,EAAE;AAAA,EACrF;AAAA,EAEA,MAAM,gBACJ,aACA,aACA,QACA,sBACA,UAII,CAAC,GACa;AAClB,UAAM,sBAAsB,CAAC,WAC3B,OAAO,YAAY,WAAW,gBAC9B,OAAO,YAAY,iBAAiB,gBACnC,yBAAyB,UACvB,OAAO,YAAY,sBAAsB,qBAAqB,qBAC7D,OAAO,YAAY,kBAAkB,qBAAqB;AAChE,UAAM,gBAAgB,CAAC,WACrB,QAAQ,sBAAsB,QAAQ,oBAAoB,MAAM;AAClE,QAAI;AACJ,QAAI,QAAQ,kBAAkB,MAAM;AAClC,YAAM,WAAW,MAAM,KAAK,iBAAiB,QAAQ,iBAAiB,IAAI;AAC1E,UAAI,CAAC,YAAY,SAAS,YAAY,OAAO,aAAa;AACxD,eAAO;AAAA,MACT;AACA,UACE,8BAA8B,QAAQ,MAAM,8BAA8B,QAAQ,gBAAgB,KAClG,CAAC,cAAc,QAAQ,GACvB;AACA,eAAO;AAAA,MACT;AACA,kBAAY;AAAA,IACd,OAAO;AACL,YAAM,WAAW;AAAA,QACf,GAAI,MAAM,KAAK,gBAAgB;AAAA,QAC/B,GAAI,MAAM,KAAK,oBAAoB;AAAA,QACnC,GAAI,MAAM,KAAK,qBAAqB;AAAA,MACtC;AACA,YAAM,aAAa,SAAS,OAAO,CAAC,WAAW,OAAO,YAAY,OAAO,WAAW;AACpF,kBACE,WAAW;AAAA,QACT,CAAC,WACC,kBAAkB,OAAO,aAAa,gBAAgB,KAAK,SAAS,OAAO,IAAI,CAAC,MAAM;AAAA,MAC1F,KACA,WAAW,KAAK,aAAa,KAC7B,WAAW,CAAC;AACd,UACE,aACA,QAAQ,oBACR,8BAA8B,SAAS,MAAM,8BAA8B,QAAQ,gBAAgB,KACnG,CAAC,cAAc,SAAS,GACxB;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,CAAC,UAAW,QAAO;AACvB,UAAM,uBACJ,QAAQ,kBAAkB,QAC1B,kBAAkB,UAAU,aAAa,gBAAgB,KAAK,SAAS,UAAU,IAAI,CAAC,MAAM;AAE9F,UAAM,cAAcQ,YAAW,QAAQ,EACpC;AAAA,MACC,KAAK,UAAU;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA,sBAAsB,wBAAwB;AAAA,MAChD,CAAC;AAAA,IACH,EACC,OAAO,KAAK;AACf,UAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC1C,QAAI,gBAAgB;AACpB,QAAI,YAAY,UAAU;AAC1B,QAAI,cAAc;AAElB,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,mCAAmC,UAAU,MAAM,OAAO,YAAY;AAC/F,YAAI,SAAS,YAAY,OAAO,YAAa,QAAO;AACpD,YAAI,oBAAoB,OAAO,GAAG;AAChC,0BAAgB;AAChB,sBAAY,QAAQ;AACpB,iBAAO,QAAQ,sBAAsB,OAAO,iBAAiB;AAAA,QAC/D;AACA,YACE,QAAQ,oBACR,8BAA8B,OAAO,MAAM,8BAA8B,QAAQ,gBAAgB,GACjG;AACA,iBAAO;AAAA,QACT;AACA,YACE,QAAQ,YAAY,iBAAiB,UACpC,wBACC,kBAAkB,QAAQ,aAAa,gBAAgB,KAAK,SAAS,QAAQ,IAAI,CAAC,MAAM,UAC1F;AACA,iBAAO;AAAA,QACT;AACA,wBAAgB;AAChB,cAAM,gBAAgB,KAAK,qBAAqB;AAChD,oBAAuB;AAAA,UACrB;AAAA,YACE,GAAG,QAAQ;AAAA,YACX,GAAG;AAAA,YACH,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,cAAc;AAAA,YACd,SAAS;AAAA,UACX;AAAA,UACA;AAAA,QACF;AACA,cAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,SAAS,CAAC,CAAC;AAAA;AAAA,EAAO,QAAQ,OAAO;AAAA;AAC9F,cAAM,KAAK,iCAAiC,SAAS,aAAa,SAAS;AAC3E,YAAI,KAAK,wBAAwB,QAAQ,IAAI,EAAG,MAAK,4BAA4B;AACjF,YAAI,OAAO,QAAQ,YAAY,cAAc,UAAU;AACrD,gBAAM,KAAK,gBAAgB;AAAA,YACzB,QAAQ;AAAA,YACR;AAAA,YACA,QAAQ,YAAY;AAAA,YACpB;AAAA,YACA,QAAQ;AAAA,YACR,EAAE,eAAe,QAAQ;AAAA,UAC3B;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AACD,UAAI,CAAC,QAAS,QAAO;AACrB,oBAAc,YAAY;AAC1B,UAAI,eAAe,OAAO,UAAU,cAAc,UAAU;AAC1D,cAAM,KAAK,gBAAgB;AAAA,UACzB,cAAc;AAAA,UACd;AAAA,UACA,UAAU;AAAA,UACV,KAAK,qBAAqB;AAAA,UAC1B,cAAc;AAAA,UACd,EAAE,eAAe,cAAc;AAAA,QACjC;AAAA,MACF;AACA,YAAM,eAAe,UAAU,gBAAgB;AAC/C,YAAM,cAAc,KAAK;AAAA,QACvB,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AACA,YAAM,aAAa,KAAK,wBAAwB,WAAW,cAAc,IAAI;AAC7E,YAAM,sBAAsB,MAAM,2BAA2B;AAAA,QAC3D;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,QAAQ;AAAA,QAAO,OAAO,QAAQ;AAAA,QACrC,kBAAkB,KAAK;AAAA,QACvB,gBAAgB,KAAK;AAAA,QACrB,kBAAkB,CAAC,aAAa,KAAK,iBAAiB,QAAQ;AAAA,QAC9D,yBAAyB,CAAC,eAAe,KAAK,wBAAwB,UAAU;AAAA,QAChF,6BAA6B,MAAM,KAAK,4BAA4B;AAAA,QACpE,4BAA4B,MAAM,KAAK,2BAA2B;AAAA,QAClE,yBAAyB,MAAM,KAAK,wBAAwB;AAAA,QAC5D,sBAAsB,YAAY;AAChC,cAAI,kBAA0C,CAAC;AAC/C,cAAI;AACF,8BAAkB,MAAM,KAAK,kBAAkB,aAAa,GAAG;AAAA,UACjE,SAAS,OAAO;AACd,gBAAI,KAAK,kDAAkD,WAAW,KAAK,KAAK,EAAE;AAAA,UACpF;AACA,cACE,gBAAgB;AAAA,YACd,CAAC,UACC,MAAM,aAAa,eACnB,MAAM,cAAc,iBACnB,MAAM,kBAAkB,eACtB,MAAM,kBAAkB,UACvB,MAAM,eAAe,UACrB,MAAM,cAAc,gBACpB,MAAM,kBAAkB,SAAS,WAAW;AAAA,UACpD,GACA;AACA;AAAA,UACF;AACA,gBAAM,KAAK,4CAA4C,2BAA2B;AAAA,YAChF,UAAU;AAAA,YACV,WAAW;AAAA,YACX,WAAW;AAAA,YACX,OAAO,QAAQ,SAAS;AAAA,YACxB,YAAY;AAAA,YACZ,QAAQ,cAAc,EAAE,GAAG,aAAa,QAAQ,SAAS,IAAI;AAAA,YAC7D,OAAO;AAAA,YACP,kBAAkB,CAAC,WAAW;AAAA,YAC9B,eAAe;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,QACA,yBAAyB,MAAM,KAAK,wBAAwB;AAAA,QAC5D,mBAAmB,CAAC,UAAU,KAAK,kBAAkB,KAAK;AAAA,QAC1D,iBAAiB,CAAC,UAAU,KAAK,gBAAgB,KAAK;AAAA,QACtD,mBAAmB,CAAC,UAAU,WAAW,KAAK,kBAAkB,UAAU,MAAM;AAAA,MAClF,CAAC;AACD,aAAO,uBAAuB,QAAQ,sBAAsB;AAAA,IAC9D,SAAS,KAAK;AACZ,UAAI,MAAM,8BAA8B,WAAW,KAAK,GAAG;AAC3D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAY,eAAuB;AACjC,WAAOR,OAAK,KAAK,KAAK,SAAS,WAAW;AAAA,EAC5C;AAAA,EAEA,MAAM,aAAa,SAAuC;AACxD,UAAM,MAAM,KAAK,cAAc,EAAE,WAAW,KAAK,CAAC;AAClD,UAAM,WAAWA,OAAK,KAAK,KAAK,cAAc,GAAG,QAAQ,EAAE,OAAO;AAClE,UAAM,KAAK,uBAAuB,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC5E,QAAI,MAAM,iBAAiB,QAAQ,EAAE,EAAE;AAAA,EACzC;AAAA,EAEA,MAAM,gBAA0C;AAC9C,QAAI;AACF,YAAM,QAAQ,MAAME,SAAQ,KAAK,YAAY;AAC7C,YAAM,YAA6B,CAAC;AAEpC,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,SAAS,OAAO,EAAG;AAC7B,cAAM,WAAWF,OAAK,KAAK,KAAK,cAAc,IAAI;AAClD,cAAM,MAAM,MAAM,KAAK,sBAAsB,QAAQ;AACrD,kBAAU,KAAK,KAAK,MAAM,GAAG,CAAkB;AAAA,MACjD;AAEA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,WAAqB,WAAoC;AAC7E,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC;AACpE,QAAI,WAAW;AAEf,eAAW,MAAM,WAAW;AAC1B,YAAM,SAAS,UAAU,IAAI,EAAE;AAC/B,UAAI,CAAC,OAAQ;AAEb,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAI,gBAAgB;AACpB,UAAI,YAAY,OAAO;AAEvB,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,mCAAmC,OAAO,MAAM,OAAO,YAAY;AAC5F,cAAI,SAAS,YAAY,OAAO,GAAI,QAAO;AAC3C,0BAAgB;AAChB,gBAAM,SAAS,KAAK,qBAAqB;AACzC,sBAAuB;AAAA,YACrB,EAAE,GAAG,QAAQ,aAAa,QAAQ,YAAY,YAAY,KAAK,SAAS,IAAI;AAAA,YAC5E;AAAA,UACF;AACA,gBAAM,cAAc,GAAG,qBAAqB,KAAK,YAAY,SAAS,CAAC,CAAC;AAAA;AAAA,EAAO,QAAQ,OAAO;AAAA;AAC9F,gBAAM,KAAK,iCAAiC,SAAS,aAAa,SAAS;AAC3E,cAAI,OAAO,QAAQ,YAAY,cAAc,UAAU;AACrD,kBAAM,KAAK,gBAAgB;AAAA,cACzB,QAAQ;AAAA,cACR;AAAA,cACA,QAAQ,YAAY;AAAA,cACpB;AAAA,cACA,QAAQ;AAAA,cACR,EAAE,eAAe,QAAQ;AAAA,YAC3B;AAAA,UACF;AACA,iBAAO;AAAA,QACT,CAAC;AACD,YAAI,CAAC,QAAS;AAGd,aAAK,wBAAwB;AAC7B,cAAM,KAAK,4CAA4C,2BAA2B;AAAA,UAChF,UAAU;AAAA,UACV,WAAW;AAAA,UACX,WAAW,UAAU,cAAc,UAAU;AAAA,UAC7C,OAAO;AAAA,UACP,YAAY,WAAW,SAAS;AAAA,UAChC,QAAQ,KAAK,wBAAwB,cAAc,aAAa,cAAc,IAAI;AAAA,UAClF,OAAO,KAAK,wBAAwB,WAAW,cAAc,IAAI;AAAA,UACjE,kBAAkB,CAAC,SAAS;AAAA,QAC9B,CAAC;AACD;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,QAAI,WAAW,GAAG;AAChB,WAAK,wBAAwB;AAC7B,UAAI,MAAM,YAAY,QAAQ,yBAAyB,SAAS,EAAE;AAAA,IACpE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,QAAqC;AACpD,UAAM,WAAWA,OAAK,KAAK,KAAK,UAAU,aAAa;AACvD,UAAM,MAAM,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,UAAU,EAAE,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,GAAG,MAAM,CAAC;AAAA,IACzE;AACA,QAAI,MAAM,SAAS,OAAO,MAAM,eAAe;AAAA,EACjD;AAAA,EAEA,MAAM,aAA0E;AAC9E,UAAM,WAAWA,OAAK,KAAK,KAAK,UAAU,aAAa;AACvD,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,sBAAsB,QAAQ;AACrD,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAwB,OAAM;AACjD,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,aAAO,EAAE,QAAQ,CAAC,GAAG,WAAW,KAAK;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,UACA,OACA,WACkB;AAClB,UAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,UAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,QAAQ;AACjE,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,gBAAgB,OAAO,YAAY,SAAS,CAAC;AACnD,UAAM,cAAc,CAAC,GAAG,aAAa;AAErC,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,YAAY,KAAK,CAAC,MAAM,EAAE,aAAa,KAAK,YAAY,EAAE,aAAa,KAAK,QAAQ,GAAG;AAC1F,oBAAY,KAAK,IAAI;AAAA,MACvB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC;AAAA,QACA;AAAA,MACF;AACA,UAAI,MAAM,SAAS,MAAM,MAAM,oBAAoB,QAAQ,EAAE;AAC7D,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,MAAM,iCAAiC,QAAQ,KAAK,GAAG;AAC3D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,wBAAwB,aAAgC,UAA+C;AAC7G,WAAO;AAAA,MACL,UAAU,YAAY;AAAA,MACtB,MAAM;AAAA,MACN,QAAQ,YAAY,UAAU;AAAA,MAC9B,gBAAgB,YAAY;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,0BAA0B,QAA2B,OAAoD;AAC/G,UAAM,eAAe,OAAO,UAAU;AACtC,UAAM,cAAc,MAAM,UAAU;AACpC,QAAI,iBAAiB,cAAc,gBAAgB,WAAY,QAAO;AACtE,QAAI,iBAAiB,gBAAgB,gBAAgB,aAAc,QAAO;AAC1E,QAAI,iBAAiB,cAAc,gBAAgB,WAAY,QAAO;AACtE,QAAI,iBAAiB,YAAY,gBAAgB,UAAU;AACzD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oCACZ,OACA,cAAc,8BACC;AACf,UAAM,KAAK,4BAA4B;AAAA,MACrC;AAAA,QACE,GAAG;AAAA,QACH,SAAS,KAAK,WAAW,KAAK;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,4CACZ,WACA,OACA,aACe;AACf,QAAI;AACF,YAAM,KAAK,oCAAoC,OAAO,WAAW;AAAA,IACnE,SAAS,WAAW;AAClB,UAAI,KAAK,GAAG,SAAS,oDAAoD,SAAS,EAAE;AAAA,IACtF;AAAA,EACF;AACF;","names":["lstat","readdir","readFile","realpath","stat","writeFile","unlink","statSync","createHash","path","allContents","stat","path","path","path","path","stat","previousLine","previousBoundaryLine","path","path","path","readdir","path","path","normalized","readdir","readdir","path","path","readdir","lstat","readdir","realpath","unlink","path","lstat","readdir","path","realpath","unlink","stat","canonicalContent","rewroteColdMemory","discoveredAfter","unlink","unlink","parseEntityFile","serializeEntityFile","serializeMemoryWithEntityRef","serializeFrontmatter","path","path","path","path","collection","relative","i","createHash","createHash","createHash","path","createHash","stat","createHash","path","createHash","parseScalar","stat","readdir","path","readdir","path","createHash","createHash","i","match","path","StorageManager","path","statSync","readdir","unlink","realpath","lstat","relative","stat","createHash","readFile","writeFile","existing","resolve","tombstoneBlocked","recordArchiveDelete","q"]}
|