@remnic/core 10.0.69 → 10.0.70
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.js +80 -77
- package/dist/access-authorization-probe.js +81 -78
- package/dist/access-boundary.js +80 -77
- package/dist/access-cli.js +194 -191
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +80 -77
- package/dist/access-http-briefing.js +81 -78
- package/dist/access-http-query.js +82 -79
- package/dist/access-http.js +104 -101
- package/dist/access-identity-continuity-surface.js +80 -77
- package/dist/access-lcm-surface.js +80 -77
- package/dist/access-mcp.js +93 -90
- package/dist/access-namespace-preflight.js +80 -77
- package/dist/access-observe-lcm-archive.d.ts +5 -0
- package/dist/access-observe-lcm-archive.d.ts.map +1 -0
- package/dist/access-observe-lcm-archive.js +9 -0
- package/dist/access-observe-objective-state.d.ts +8 -0
- package/dist/access-observe-objective-state.d.ts.map +1 -0
- package/dist/access-observe-objective-state.js +17 -0
- package/dist/access-observe-stage-timing.d.ts +11 -0
- package/dist/access-observe-stage-timing.d.ts.map +1 -0
- package/dist/access-observe-stage-timing.js +9 -0
- package/dist/access-observe-stage-timing.js.map +1 -0
- package/dist/access-observe-write-category.js +13 -13
- package/dist/access-observe-write-surface.d.ts.map +1 -1
- package/dist/access-observe-write-surface.js +80 -77
- package/dist/access-offline-manifest.js +8 -8
- package/dist/access-operations-batch.js +83 -80
- package/dist/access-operations.js +90 -87
- package/dist/access-recall-concurrency.js +80 -77
- package/dist/access-recall-response.js +80 -77
- package/dist/access-recall-surface.js +80 -77
- package/dist/access-schema.js +12 -12
- package/dist/access-service.d.ts +1 -0
- package/dist/access-service.d.ts.map +1 -1
- package/dist/access-service.js +80 -77
- package/dist/access-surface-catalog.js +82 -79
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-recall.js +24 -24
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/briefing.js +15 -15
- package/dist/buffer.js +8 -8
- package/dist/calibration.js +4 -4
- package/dist/{capsule-crypto-GWVG7LGC.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +20 -20
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +3 -3
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-NCZGGGWI.js → chunk-2BBMCMJS.js} +12 -12
- package/dist/{chunk-UVVFPCPX.js → chunk-2GV24KFD.js} +2 -2
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-QDZWQBLU.js → chunk-2R7OCBRR.js} +2 -2
- package/dist/{chunk-U2CAGMUD.js → chunk-2YPIFJHL.js} +2 -2
- package/dist/{chunk-4SOWMA55.js → chunk-3AASGFR4.js} +3 -3
- package/dist/{chunk-CI3MAAIY.js → chunk-3F7N4I5I.js} +2 -2
- package/dist/{chunk-PLCYKAWH.js → chunk-3ICAWZUU.js} +4 -4
- package/dist/{chunk-B4DXREWC.js → chunk-3W37NITP.js} +2 -2
- package/dist/{chunk-R4ZHF4K2.js → chunk-43FLJLT2.js} +4 -4
- package/dist/{chunk-RLVI2M5Q.js → chunk-4BOBW6H4.js} +2 -2
- package/dist/{chunk-HXFIILGF.js → chunk-4RASUAN3.js} +4 -4
- package/dist/{chunk-JLMOH5JA.js → chunk-5FMGPV34.js} +2 -2
- package/dist/{chunk-EI6M5NVK.js → chunk-5JBVPJCT.js} +2 -2
- package/dist/{chunk-74AY3S7U.js → chunk-5RW247F5.js} +10 -10
- package/dist/{chunk-P4TV3TQ2.js → chunk-5VQSKBNF.js} +5 -5
- package/dist/{chunk-H5DIRCZP.js → chunk-64U42JL5.js} +18 -18
- package/dist/{chunk-4XINO77L.js → chunk-66JOLMWS.js} +2 -2
- package/dist/{chunk-WHROVQ5Q.js → chunk-66PEACZP.js} +3 -3
- package/dist/{chunk-GKL6QYZO.js → chunk-6L63IN3M.js} +1 -1
- package/dist/{chunk-Y3XPSGNF.js → chunk-6QS5NQJH.js} +2 -2
- package/dist/{chunk-KOLJJN5G.js → chunk-AQNHEDXP.js} +11 -4
- package/dist/chunk-AQNHEDXP.js.map +1 -0
- package/dist/{chunk-6WKWL53V.js → chunk-B7YAIHAV.js} +127 -121
- package/dist/chunk-B7YAIHAV.js.map +1 -0
- package/dist/{chunk-M4IEZGCK.js → chunk-BFBS7OFQ.js} +7 -7
- package/dist/{chunk-4PG5R6BJ.js → chunk-BNU5TQLR.js} +2 -2
- package/dist/{chunk-B3MWELZ3.js → chunk-BW33YTF3.js} +2 -2
- package/dist/{chunk-H6VJSITJ.js → chunk-CIL4GHMD.js} +3 -3
- package/dist/{chunk-5UM4H64E.js → chunk-D3AGBN6G.js} +2 -2
- package/dist/{chunk-IG3EZ3TF.js → chunk-DM3UZUCN.js} +2 -2
- package/dist/{chunk-PMDOGXA2.js → chunk-EF3HNVL4.js} +2 -2
- package/dist/{chunk-TVE7W67N.js → chunk-EIZ4MK33.js} +2 -2
- package/dist/{chunk-AUFPPBC3.js → chunk-ENPJX3BB.js} +3 -3
- package/dist/{chunk-63A2BU2B.js → chunk-F4ZHKDBW.js} +5 -5
- package/dist/{chunk-3LBDEGQA.js → chunk-FDUCIUQ5.js} +2 -2
- package/dist/{chunk-CTH2CQCB.js → chunk-FM6UKZAE.js} +2 -2
- package/dist/{chunk-XVZA6VXC.js → chunk-FZVROZKC.js} +4 -4
- package/dist/{chunk-IAGVM7EY.js → chunk-GMSRLDVR.js} +2 -2
- package/dist/{chunk-HPB5TF55.js → chunk-GT4G2S2Y.js} +3 -3
- package/dist/{chunk-645WOU5I.js → chunk-H7BZBSP6.js} +4 -4
- package/dist/{chunk-5MGKGEL7.js → chunk-HNF7IMYQ.js} +2 -2
- package/dist/{chunk-W7K5BP3M.js → chunk-HQPFACXO.js} +2 -2
- package/dist/{chunk-TECK5IVY.js → chunk-HZNURRDS.js} +2 -2
- package/dist/{chunk-SXTVZ6JL.js → chunk-I6HRHJRA.js} +2 -2
- package/dist/{chunk-NHWDTOBN.js → chunk-ILD7N3XC.js} +20 -20
- package/dist/{chunk-4NV7O76Q.js → chunk-J5TVHCDG.js} +2 -2
- package/dist/{chunk-AL3TCNSJ.js → chunk-J6GZ2254.js} +4 -4
- package/dist/{chunk-OH55F76C.js → chunk-JEX2JL3U.js} +2 -2
- package/dist/{chunk-AVGDYYMA.js → chunk-JGQEF33K.js} +3 -3
- package/dist/{chunk-6P7U3HWG.js → chunk-K36RMINQ.js} +3 -3
- package/dist/{chunk-UW6LBFYN.js → chunk-K47G2CBP.js} +6 -6
- package/dist/{chunk-3RHU5MD7.js → chunk-K7LLGCPH.js} +2 -2
- package/dist/{chunk-BUKK5SWA.js → chunk-KQAFEZQX.js} +2 -2
- package/dist/chunk-L3E7MLMK.js +20 -0
- package/dist/chunk-L3E7MLMK.js.map +1 -0
- package/dist/{chunk-R2BIVU2Z.js → chunk-LTST4R7U.js} +2 -2
- package/dist/{chunk-IZBIDPMY.js → chunk-LYTKNK5O.js} +2 -2
- package/dist/{chunk-HH73M65H.js → chunk-MCFI6G7U.js} +3 -3
- package/dist/{chunk-V6SBA5O7.js → chunk-MFKBYXBY.js} +5 -5
- package/dist/{chunk-AYJQ644F.js → chunk-MK7HXGM6.js} +2 -2
- package/dist/{chunk-MOIJWWNA.js → chunk-MKMIY3E7.js} +13 -13
- package/dist/{chunk-EXQJMFRF.js → chunk-MRN2MKB7.js} +2 -2
- package/dist/{chunk-W26D2USW.js → chunk-MUH7RR6T.js} +6 -6
- package/dist/{chunk-64JLBFCQ.js → chunk-N7NAGECH.js} +2 -2
- package/dist/{chunk-75DCOS6I.js → chunk-OAKOAOEG.js} +67 -67
- package/dist/{chunk-DDBB55L2.js → chunk-OAQO5AZJ.js} +121 -121
- package/dist/{chunk-OPFVXM2D.js → chunk-OX6GY22Q.js} +2 -2
- package/dist/chunk-QCFZDYYG.js +34 -0
- package/dist/chunk-QCFZDYYG.js.map +1 -0
- package/dist/{chunk-MMCO4SRG.js → chunk-QNN4FYBD.js} +19 -11
- package/dist/chunk-QNN4FYBD.js.map +1 -0
- package/dist/{chunk-XWE3EOWX.js → chunk-RZED7FAU.js} +2 -2
- package/dist/{chunk-YSATDEBY.js → chunk-SBRUTD5O.js} +5 -5
- package/dist/{chunk-WVP2I6C5.js → chunk-SDL22RRW.js} +50 -11
- package/dist/chunk-SDL22RRW.js.map +1 -0
- package/dist/{chunk-ZORS5BG5.js → chunk-SQO5SEKA.js} +10 -10
- package/dist/{chunk-PRKNAIGZ.js → chunk-T6T2RMWW.js} +5 -5
- package/dist/{chunk-O5ZINWW3.js → chunk-THFSCUFC.js} +2 -2
- package/dist/{chunk-CIEEYVUB.js → chunk-TPX7XXY4.js} +2 -2
- package/dist/{chunk-OCK4D5PC.js → chunk-TSZP7GGJ.js} +2 -2
- package/dist/{chunk-L334PSLW.js → chunk-U2A56LLF.js} +8 -8
- package/dist/{chunk-TGQW3AMK.js → chunk-UIFWZMO7.js} +23 -23
- package/dist/{chunk-LN4X2NDA.js → chunk-UJ2FP2RV.js} +10 -10
- package/dist/{chunk-4MPAKYZU.js → chunk-VDYRXI3E.js} +5 -5
- package/dist/{chunk-IHCXMYSE.js → chunk-VPEIWMUT.js} +2 -2
- package/dist/{chunk-ELHJK7LM.js → chunk-WBN66HPI.js} +6 -6
- package/dist/{chunk-BJLCV2P3.js → chunk-WGRAB3KB.js} +2 -2
- package/dist/{chunk-IVUVQPTQ.js → chunk-WIW4LOZL.js} +2 -2
- package/dist/{chunk-5KDDAQ6K.js → chunk-WN2DASTS.js} +10 -10
- package/dist/chunk-WZU5AGO6.js +38 -0
- package/dist/chunk-WZU5AGO6.js.map +1 -0
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-5Y6VA6X2.js → chunk-XDUP6SWG.js} +2 -2
- package/dist/{chunk-GHHQLSSY.js → chunk-XR4QR3JT.js} +3 -3
- package/dist/{chunk-64S6X4IU.js → chunk-XTN54NML.js} +4 -4
- package/dist/{chunk-QGFR73SN.js → chunk-YIG4HPY4.js} +2 -2
- package/dist/{chunk-UYUFDTIX.js → chunk-YIXWY4OZ.js} +2 -2
- package/dist/{chunk-GJ4HU6LK.js → chunk-YLMTFRZR.js} +2 -2
- package/dist/{chunk-GGD2YDS6.js → chunk-YRMSHA7H.js} +2 -2
- package/dist/{chunk-Y7427SL7.js → chunk-ZG4GNPRE.js} +216 -50
- package/dist/chunk-ZG4GNPRE.js.map +1 -0
- package/dist/{chunk-KZZ5EZ7O.js → chunk-ZS5LREUZ.js} +2 -2
- package/dist/{chunk-JLGBJ4AX.js → chunk-ZYEWTVNQ.js} +10 -10
- package/dist/cli.js +131 -128
- package/dist/coding/export-okf-codegraph.js +14 -14
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +16 -16
- package/dist/config.js +24 -24
- package/dist/connectors/codex-materialize-runner.js +17 -17
- package/dist/connectors/codex-materialize.js +2 -2
- package/dist/connectors/index.js +18 -18
- package/dist/consolidation-provenance-check.js +2 -2
- package/dist/convergence-refresh.js +18 -18
- package/dist/corpus-watermark.js +18 -18
- package/dist/deep-recall-http-glue.js +13 -13
- package/dist/deep-recall.js +2 -2
- package/dist/embedding-fallback.js +2 -2
- package/dist/entity-retrieval.js +18 -18
- package/dist/event-order-recall.js +2 -2
- package/dist/external-wiki-access.js +81 -78
- package/dist/extraction-span-materialize.js +2 -2
- package/dist/extraction.js +30 -30
- package/dist/{graph-edge-decay-OEX5OGMI.js → graph-edge-decay-CXTNJ7IQ.js} +6 -6
- package/dist/graph-edge-decay-CXTNJ7IQ.js.map +1 -0
- package/dist/graph-jsonl.js +4 -4
- package/dist/graph-snapshot.js +4 -4
- package/dist/graph.js +3 -3
- package/dist/harmonic-retrieval.js +15 -15
- package/dist/index.js +279 -276
- package/dist/lcm/archive.d.ts +12 -2
- package/dist/lcm/archive.d.ts.map +1 -1
- package/dist/lcm/archive.js +2 -2
- package/dist/lcm/engine.d.ts +59 -8
- package/dist/lcm/engine.d.ts.map +1 -1
- package/dist/lcm/engine.js +6 -6
- package/dist/lcm/index.js +16 -16
- package/dist/lcm/queue.d.ts +7 -3
- package/dist/lcm/queue.d.ts.map +1 -1
- package/dist/lcm/queue.js +1 -1
- package/dist/lcm/summarizer.d.ts +8 -1
- package/dist/lcm/summarizer.d.ts.map +1 -1
- package/dist/lcm/summarizer.js +3 -3
- package/dist/local-llm.js +4 -4
- package/dist/location/index.js +17 -17
- package/dist/maintenance/memory-governance.js +16 -16
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +15 -15
- package/dist/maintenance/rebuild-memory-projection-runner.js +18 -18
- package/dist/maintenance/rebuild-memory-projection.js +17 -17
- package/dist/memory-browse-operations.js +81 -78
- package/dist/memory-browse.js +6 -6
- package/dist/namespaces/migrate.js +16 -16
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.js +15 -15
- package/dist/offline-sync-changeset-generations.js +5 -5
- package/dist/offline-sync-embedding-generation.js +4 -4
- package/dist/offline-sync-snapshot-stream.js +7 -7
- package/dist/offline-sync.js +9 -9
- package/dist/operator-doctor-corpus.js +19 -19
- package/dist/operator-toolkit.js +39 -39
- package/dist/orchestration/buffer-drain-runner.js +194 -191
- package/dist/orchestration/buffer-drain-runner.js.map +1 -1
- package/dist/orchestration/maintenance.js +31 -31
- package/dist/orchestrator.js +195 -192
- package/dist/qmd.js +4 -4
- package/dist/recall-navigation-operations.js +81 -78
- package/dist/recall-navigation.js +80 -77
- package/dist/recall-state-view-admission.js +6 -6
- package/dist/recall-why-service.js +6 -6
- package/dist/resume-bundles.js +27 -27
- package/dist/search/factory.js +6 -6
- package/dist/search/index.js +12 -12
- package/dist/semantic-consolidation.js +23 -23
- package/dist/semantic-rule-promotion.js +15 -15
- package/dist/semantic-rule-verifier.js +15 -15
- package/dist/source-agent-qualifier.js +22 -22
- package/dist/standup/build.js +15 -15
- package/dist/storage.js +14 -14
- package/dist/summarizer.js +6 -6
- package/dist/support-passport/index.js +83 -80
- 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/export-okf.js +15 -15
- package/dist/verified-recall.js +15 -15
- package/dist/who-knows-cli.js +16 -16
- package/dist/who-knows.js +15 -15
- package/package.json +2 -2
- package/src/access-observe-lcm-archive.ts +30 -0
- package/src/access-observe-lcm-fail-closed.test.ts +118 -0
- package/src/access-observe-objective-state.ts +40 -0
- package/src/access-observe-stage-timing.test.ts +246 -0
- package/src/access-observe-stage-timing.ts +58 -0
- package/src/access-observe-write-surface.ts +45 -45
- package/src/access-service.ts +1 -0
- package/src/lcm/archive.ts +59 -7
- package/src/lcm/engine.ts +256 -53
- package/src/lcm/queue.test.ts +32 -14
- package/src/lcm/queue.ts +24 -16
- package/src/lcm/summarizer.ts +15 -2
- package/src/lcm-durability.test.ts +856 -0
- package/src/lcm-engine.test.ts +12 -3
- package/dist/chunk-6WKWL53V.js.map +0 -1
- package/dist/chunk-KOLJJN5G.js.map +0 -1
- package/dist/chunk-MMCO4SRG.js.map +0 -1
- package/dist/chunk-WVP2I6C5.js.map +0 -1
- package/dist/chunk-Y7427SL7.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-observe-lcm-archive.js.map} +0 -0
- /package/dist/{graph-edge-decay-OEX5OGMI.js.map → access-observe-objective-state.js.map} +0 -0
- /package/dist/{chunk-NCZGGGWI.js.map → chunk-2BBMCMJS.js.map} +0 -0
- /package/dist/{chunk-UVVFPCPX.js.map → chunk-2GV24KFD.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-QDZWQBLU.js.map → chunk-2R7OCBRR.js.map} +0 -0
- /package/dist/{chunk-U2CAGMUD.js.map → chunk-2YPIFJHL.js.map} +0 -0
- /package/dist/{chunk-4SOWMA55.js.map → chunk-3AASGFR4.js.map} +0 -0
- /package/dist/{chunk-CI3MAAIY.js.map → chunk-3F7N4I5I.js.map} +0 -0
- /package/dist/{chunk-PLCYKAWH.js.map → chunk-3ICAWZUU.js.map} +0 -0
- /package/dist/{chunk-B4DXREWC.js.map → chunk-3W37NITP.js.map} +0 -0
- /package/dist/{chunk-R4ZHF4K2.js.map → chunk-43FLJLT2.js.map} +0 -0
- /package/dist/{chunk-RLVI2M5Q.js.map → chunk-4BOBW6H4.js.map} +0 -0
- /package/dist/{chunk-HXFIILGF.js.map → chunk-4RASUAN3.js.map} +0 -0
- /package/dist/{chunk-JLMOH5JA.js.map → chunk-5FMGPV34.js.map} +0 -0
- /package/dist/{chunk-EI6M5NVK.js.map → chunk-5JBVPJCT.js.map} +0 -0
- /package/dist/{chunk-74AY3S7U.js.map → chunk-5RW247F5.js.map} +0 -0
- /package/dist/{chunk-P4TV3TQ2.js.map → chunk-5VQSKBNF.js.map} +0 -0
- /package/dist/{chunk-H5DIRCZP.js.map → chunk-64U42JL5.js.map} +0 -0
- /package/dist/{chunk-4XINO77L.js.map → chunk-66JOLMWS.js.map} +0 -0
- /package/dist/{chunk-WHROVQ5Q.js.map → chunk-66PEACZP.js.map} +0 -0
- /package/dist/{chunk-GKL6QYZO.js.map → chunk-6L63IN3M.js.map} +0 -0
- /package/dist/{chunk-Y3XPSGNF.js.map → chunk-6QS5NQJH.js.map} +0 -0
- /package/dist/{chunk-M4IEZGCK.js.map → chunk-BFBS7OFQ.js.map} +0 -0
- /package/dist/{chunk-4PG5R6BJ.js.map → chunk-BNU5TQLR.js.map} +0 -0
- /package/dist/{chunk-B3MWELZ3.js.map → chunk-BW33YTF3.js.map} +0 -0
- /package/dist/{chunk-H6VJSITJ.js.map → chunk-CIL4GHMD.js.map} +0 -0
- /package/dist/{chunk-5UM4H64E.js.map → chunk-D3AGBN6G.js.map} +0 -0
- /package/dist/{chunk-IG3EZ3TF.js.map → chunk-DM3UZUCN.js.map} +0 -0
- /package/dist/{chunk-PMDOGXA2.js.map → chunk-EF3HNVL4.js.map} +0 -0
- /package/dist/{chunk-TVE7W67N.js.map → chunk-EIZ4MK33.js.map} +0 -0
- /package/dist/{chunk-AUFPPBC3.js.map → chunk-ENPJX3BB.js.map} +0 -0
- /package/dist/{chunk-63A2BU2B.js.map → chunk-F4ZHKDBW.js.map} +0 -0
- /package/dist/{chunk-3LBDEGQA.js.map → chunk-FDUCIUQ5.js.map} +0 -0
- /package/dist/{chunk-CTH2CQCB.js.map → chunk-FM6UKZAE.js.map} +0 -0
- /package/dist/{chunk-XVZA6VXC.js.map → chunk-FZVROZKC.js.map} +0 -0
- /package/dist/{chunk-IAGVM7EY.js.map → chunk-GMSRLDVR.js.map} +0 -0
- /package/dist/{chunk-HPB5TF55.js.map → chunk-GT4G2S2Y.js.map} +0 -0
- /package/dist/{chunk-645WOU5I.js.map → chunk-H7BZBSP6.js.map} +0 -0
- /package/dist/{chunk-5MGKGEL7.js.map → chunk-HNF7IMYQ.js.map} +0 -0
- /package/dist/{chunk-W7K5BP3M.js.map → chunk-HQPFACXO.js.map} +0 -0
- /package/dist/{chunk-TECK5IVY.js.map → chunk-HZNURRDS.js.map} +0 -0
- /package/dist/{chunk-SXTVZ6JL.js.map → chunk-I6HRHJRA.js.map} +0 -0
- /package/dist/{chunk-NHWDTOBN.js.map → chunk-ILD7N3XC.js.map} +0 -0
- /package/dist/{chunk-4NV7O76Q.js.map → chunk-J5TVHCDG.js.map} +0 -0
- /package/dist/{chunk-AL3TCNSJ.js.map → chunk-J6GZ2254.js.map} +0 -0
- /package/dist/{chunk-OH55F76C.js.map → chunk-JEX2JL3U.js.map} +0 -0
- /package/dist/{chunk-AVGDYYMA.js.map → chunk-JGQEF33K.js.map} +0 -0
- /package/dist/{chunk-6P7U3HWG.js.map → chunk-K36RMINQ.js.map} +0 -0
- /package/dist/{chunk-UW6LBFYN.js.map → chunk-K47G2CBP.js.map} +0 -0
- /package/dist/{chunk-3RHU5MD7.js.map → chunk-K7LLGCPH.js.map} +0 -0
- /package/dist/{chunk-BUKK5SWA.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-R2BIVU2Z.js.map → chunk-LTST4R7U.js.map} +0 -0
- /package/dist/{chunk-IZBIDPMY.js.map → chunk-LYTKNK5O.js.map} +0 -0
- /package/dist/{chunk-HH73M65H.js.map → chunk-MCFI6G7U.js.map} +0 -0
- /package/dist/{chunk-V6SBA5O7.js.map → chunk-MFKBYXBY.js.map} +0 -0
- /package/dist/{chunk-AYJQ644F.js.map → chunk-MK7HXGM6.js.map} +0 -0
- /package/dist/{chunk-MOIJWWNA.js.map → chunk-MKMIY3E7.js.map} +0 -0
- /package/dist/{chunk-EXQJMFRF.js.map → chunk-MRN2MKB7.js.map} +0 -0
- /package/dist/{chunk-W26D2USW.js.map → chunk-MUH7RR6T.js.map} +0 -0
- /package/dist/{chunk-64JLBFCQ.js.map → chunk-N7NAGECH.js.map} +0 -0
- /package/dist/{chunk-75DCOS6I.js.map → chunk-OAKOAOEG.js.map} +0 -0
- /package/dist/{chunk-DDBB55L2.js.map → chunk-OAQO5AZJ.js.map} +0 -0
- /package/dist/{chunk-OPFVXM2D.js.map → chunk-OX6GY22Q.js.map} +0 -0
- /package/dist/{chunk-XWE3EOWX.js.map → chunk-RZED7FAU.js.map} +0 -0
- /package/dist/{chunk-YSATDEBY.js.map → chunk-SBRUTD5O.js.map} +0 -0
- /package/dist/{chunk-ZORS5BG5.js.map → chunk-SQO5SEKA.js.map} +0 -0
- /package/dist/{chunk-PRKNAIGZ.js.map → chunk-T6T2RMWW.js.map} +0 -0
- /package/dist/{chunk-O5ZINWW3.js.map → chunk-THFSCUFC.js.map} +0 -0
- /package/dist/{chunk-CIEEYVUB.js.map → chunk-TPX7XXY4.js.map} +0 -0
- /package/dist/{chunk-OCK4D5PC.js.map → chunk-TSZP7GGJ.js.map} +0 -0
- /package/dist/{chunk-L334PSLW.js.map → chunk-U2A56LLF.js.map} +0 -0
- /package/dist/{chunk-TGQW3AMK.js.map → chunk-UIFWZMO7.js.map} +0 -0
- /package/dist/{chunk-LN4X2NDA.js.map → chunk-UJ2FP2RV.js.map} +0 -0
- /package/dist/{chunk-4MPAKYZU.js.map → chunk-VDYRXI3E.js.map} +0 -0
- /package/dist/{chunk-IHCXMYSE.js.map → chunk-VPEIWMUT.js.map} +0 -0
- /package/dist/{chunk-ELHJK7LM.js.map → chunk-WBN66HPI.js.map} +0 -0
- /package/dist/{chunk-BJLCV2P3.js.map → chunk-WGRAB3KB.js.map} +0 -0
- /package/dist/{chunk-IVUVQPTQ.js.map → chunk-WIW4LOZL.js.map} +0 -0
- /package/dist/{chunk-5KDDAQ6K.js.map → chunk-WN2DASTS.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-5Y6VA6X2.js.map → chunk-XDUP6SWG.js.map} +0 -0
- /package/dist/{chunk-GHHQLSSY.js.map → chunk-XR4QR3JT.js.map} +0 -0
- /package/dist/{chunk-64S6X4IU.js.map → chunk-XTN54NML.js.map} +0 -0
- /package/dist/{chunk-QGFR73SN.js.map → chunk-YIG4HPY4.js.map} +0 -0
- /package/dist/{chunk-UYUFDTIX.js.map → chunk-YIXWY4OZ.js.map} +0 -0
- /package/dist/{chunk-GJ4HU6LK.js.map → chunk-YLMTFRZR.js.map} +0 -0
- /package/dist/{chunk-GGD2YDS6.js.map → chunk-YRMSHA7H.js.map} +0 -0
- /package/dist/{chunk-KZZ5EZ7O.js.map → chunk-ZS5LREUZ.js.map} +0 -0
- /package/dist/{chunk-JLGBJ4AX.js.map → chunk-ZYEWTVNQ.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lcm/summarizer.ts"],"sourcesContent":["import { summarizeContextPure, type SummarizeFn } from \"../context-summary.js\";\nimport { estimateTokens } from \"./archive.js\";\nimport type { LcmArchive, LcmMessage } from \"./archive.js\";\nimport type { LcmDag } from \"./dag.js\";\n\n/** Generate a ULID-like ID (timestamp + random). */\nfunction generateNodeId(): string {\n const ts = Date.now().toString(36).padStart(9, \"0\");\n const rand = Math.random().toString(36).slice(2, 10);\n return `lcm-${ts}-${rand}`;\n}\n\n// `SummarizeFn` moved to the shared pure summary seam (context-summary.ts,\n// #2347); re-exported here for back-compat with existing imports.\nexport type { SummarizeFn };\n\nexport interface LcmSummarizerConfig {\n leafBatchSize: number;\n rollupFanIn: number;\n maxDepth: number;\n deterministicMaxTokens: number;\n telemetryPrefilterEnabled: boolean;\n}\n\nexport class LcmSummarizer {\n constructor(\n private readonly archive: LcmArchive,\n private readonly dag: LcmDag,\n private readonly summarizeFn: SummarizeFn,\n private readonly config: LcmSummarizerConfig,\n ) {}\n\n /**\n * Run incremental summarization for a session.\n * Creates leaf nodes from unsummarized messages, then rolls up as needed.\n */\n async summarizeIncremental(sessionId: string): Promise<number> {\n let nodesCreated = 0;\n\n // Phase 1: Create leaf nodes from unsummarized messages\n const unsummarized = this.archive.getUnsummarizedMessages(sessionId);\n if (unsummarized.length >= this.config.leafBatchSize) {\n const batches = chunkArray(unsummarized, this.config.leafBatchSize);\n // Only process complete batches (leave partial for next time)\n const completeBatches = unsummarized.length % this.config.leafBatchSize === 0\n ? batches\n : batches.slice(0, -1);\n\n for (const batch of completeBatches) {\n const created = await this.createLeafNode(sessionId, batch);\n if (created) nodesCreated++;\n }\n }\n\n // Phase 2: Roll up at each depth level\n if (nodesCreated > 0) {\n nodesCreated += await this.rollupAll(sessionId);\n }\n\n return nodesCreated;\n }\n\n /** Create a leaf summary node (depth 0) from a batch of messages. */\n private async createLeafNode(\n sessionId: string,\n messages: LcmMessage[],\n ): Promise<boolean> {\n if (messages.length === 0) return false;\n\n const combinedText = messages\n .map((m) => `[${m.role}] ${m.content}`)\n .join(\"\\n\\n\");\n\n const inputTokens = estimateTokens(combinedText);\n const targetTokens = Math.max(64, Math.ceil(inputTokens * 0.25));\n\n const summary = await this.summarizeWithEscalation(combinedText, targetTokens);\n\n this.dag.insertNode({\n id: generateNodeId(),\n session_id: sessionId,\n depth: 0,\n parent_id: null,\n summary_text: summary.text,\n token_count: estimateTokens(summary.text),\n msg_start: messages[0].turn_index,\n msg_end: messages[messages.length - 1].turn_index,\n escalation: summary.escalation,\n });\n\n return true;\n }\n\n /** Roll up orphan nodes at each depth level up to maxDepth. */\n private async rollupAll(sessionId: string): Promise<number> {\n let totalCreated = 0;\n\n for (let depth = 0; depth < this.config.maxDepth; depth++) {\n const orphans = this.dag.getOrphanNodesAtDepth(sessionId, depth);\n if (orphans.length < this.config.rollupFanIn) continue;\n\n const batches = chunkArray(orphans, this.config.rollupFanIn);\n // Only process complete batches\n const completeBatches = orphans.length % this.config.rollupFanIn === 0\n ? batches\n : batches.slice(0, -1);\n\n for (const batch of completeBatches) {\n const combinedText = batch\n .map((n) => n.summary_text)\n .join(\"\\n\\n\");\n\n const inputTokens = estimateTokens(combinedText);\n const targetTokens = Math.max(64, Math.ceil(inputTokens * 0.25));\n\n const summary = await this.summarizeWithEscalation(combinedText, targetTokens);\n\n const parentId = generateNodeId();\n this.dag.insertNode({\n id: parentId,\n session_id: sessionId,\n depth: depth + 1,\n parent_id: null,\n summary_text: summary.text,\n token_count: estimateTokens(summary.text),\n msg_start: batch[0].msg_start,\n msg_end: batch[batch.length - 1].msg_end,\n escalation: summary.escalation,\n });\n\n this.dag.setParent(\n batch.map((n) => n.id),\n parentId,\n );\n\n totalCreated++;\n }\n }\n\n return totalCreated;\n }\n\n /**\n * Three-level escalation, delegated to the shared pure summary seam\n * (context-summary.ts): 0 = normal LLM, 1 = aggressive, 2 = deterministic.\n */\n private async summarizeWithEscalation(\n text: string,\n targetTokens: number,\n ): Promise<{ text: string; escalation: number }> {\n const { deterministicMaxTokens, telemetryPrefilterEnabled } = this.config;\n const result = await summarizeContextPure(text, targetTokens, \"auto\", {\n llm: this.summarizeFn,\n deterministicMaxTokens,\n telemetryPrefilterEnabled,\n });\n return { text: result.text, escalation: result.escalation ?? 2 };\n }\n}\n\n\nfunction chunkArray<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lcm/queue.ts"],"sourcesContent":["export interface LcmObserveMessage {\n role: string;\n content: string;\n parts?: import(\"../message-parts/index.js\").LcmMessagePartInput[];\n rawContent?: unknown;\n sourceFormat?: import(\"../message-parts/index.js\").MessagePartSourceFormat;\n}\n\nexport interface LcmWorkQueueHooks {\n onJobStart?: (input: {\n sessionId: string;\n depth: number;\n inFlight: number;\n waitMs: number;\n }) => void;\n onJobFinish?: (input: {\n sessionId: string;\n depth: number;\n inFlight: number;\n waitMs: number;\n runMs: number;\n totalMs: number;\n error?: unknown;\n }) => void;\n}\n\nexport interface LcmWorkQueueOptions {\n concurrency?: number;\n worker: (sessionId: string, messages: LcmObserveMessage[]) => Promise<void>;\n hooks?: LcmWorkQueueHooks;\n}\n\ninterface PendingJob {\n sessionId: string;\n messages: LcmObserveMessage[];\n enqueuedAt: number;\n}\n\n/**\n * Small keyed work queue for LCM observe processing.\n *\n * Jobs are coalesced per session while they are pending. A session can have\n * at most one in-flight job at a time, and the queue processes jobs FIFO up to\n * the configured concurrency limit.\n */\nexport class LcmWorkQueue {\n private readonly concurrency: number;\n private readonly worker: (\n sessionId: string,\n messages: LcmObserveMessage[],\n ) => Promise<void>;\n private readonly hooks: LcmWorkQueueHooks;\n private readonly pending = new Map<string, PendingJob>();\n private readonly inFlightSessions = new Set<string>();\n private inFlight = 0;\n private readonly idleWaiters: Array<() => void> = [];\n private readonly sessionIdleWaiters = new Map<string, Array<() => void>>();\n private drainScheduled = false;\n\n constructor(options: LcmWorkQueueOptions) {\n this.concurrency = Math.max(1, Math.floor(options.concurrency ?? 1));\n this.worker = options.worker;\n this.hooks = options.hooks ?? {};\n }\n\n enqueue(sessionId: string, messages: LcmObserveMessage[]): void {\n if (messages.length === 0) return;\n\n const now = Date.now();\n const existing = this.pending.get(sessionId);\n if (existing) {\n existing.messages.push(...messages.map((message) => ({ ...message })));\n } else {\n this.pending.set(sessionId, {\n sessionId,\n messages: messages.map((message) => ({ ...message })),\n enqueuedAt: now,\n });\n }\n\n this.scheduleDrain();\n }\n\n get depth(): number {\n return this.pending.size;\n }\n\n get inFlightCount(): number {\n return this.inFlight;\n }\n\n async whenIdle(): Promise<void> {\n if (this.depth === 0 && this.inFlight === 0) return;\n await new Promise<void>((resolve) => {\n this.idleWaiters.push(resolve);\n });\n }\n\n async whenSessionIdle(sessionId: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (!this.pending.has(sessionId) && !this.inFlightSessions.has(sessionId)) return;\n await new Promise<void>((resolve, reject) => {\n const finish = (): void => {\n abortSignal?.removeEventListener(\"abort\", onAbort);\n resolve();\n };\n const onAbort = (): void => {\n const remaining = (this.sessionIdleWaiters.get(sessionId) ?? []).filter((waiter) => waiter !== finish);\n if (remaining.length === 0) this.sessionIdleWaiters.delete(sessionId);\n else this.sessionIdleWaiters.set(sessionId, remaining);\n reject(abortSignal?.reason instanceof Error ? abortSignal.reason : new DOMException(\"Aborted\", \"AbortError\"));\n };\n const waiters = this.sessionIdleWaiters.get(sessionId) ?? [];\n waiters.push(finish);\n this.sessionIdleWaiters.set(sessionId, waiters);\n abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n }\n\n private startAvailableJobs(): void {\n while (this.inFlight < this.concurrency && this.pending.size > 0) {\n const next = Array.from(this.pending.entries()).find(\n ([sessionId]) => !this.inFlightSessions.has(sessionId),\n );\n if (!next) break;\n\n const [sessionId, job] = next;\n this.pending.delete(sessionId);\n this.inFlight++;\n this.inFlightSessions.add(sessionId);\n\n const startedAt = Date.now();\n const waitMs = startedAt - job.enqueuedAt;\n this.hooks.onJobStart?.({\n sessionId,\n depth: this.depth,\n inFlight: this.inFlight,\n waitMs,\n });\n\n void this.runJob(job, startedAt, waitMs);\n }\n\n this.resolveIdleWaitersIfNeeded();\n }\n\n private scheduleDrain(): void {\n if (this.drainScheduled) return;\n this.drainScheduled = true;\n\n queueMicrotask(() => {\n this.drainScheduled = false;\n this.startAvailableJobs();\n });\n }\n\n private async runJob(\n job: PendingJob,\n startedAt: number,\n waitMs: number,\n ): Promise<void> {\n let error: unknown;\n\n try {\n await this.worker(job.sessionId, job.messages);\n } catch (err) {\n error = err;\n } finally {\n const finishedAt = Date.now();\n const runMs = finishedAt - startedAt;\n const totalMs = finishedAt - job.enqueuedAt;\n\n this.inFlight--;\n this.inFlightSessions.delete(job.sessionId);\n this.hooks.onJobFinish?.({\n sessionId: job.sessionId,\n depth: this.depth,\n inFlight: this.inFlight,\n waitMs,\n runMs,\n totalMs,\n error,\n });\n\n if (this.pending.size > 0) {\n this.scheduleDrain();\n } else {\n this.resolveIdleWaitersIfNeeded();\n }\n this.resolveSessionIdleWaitersIfNeeded(job.sessionId);\n }\n }\n\n private resolveIdleWaitersIfNeeded(): void {\n if (this.depth !== 0 || this.inFlight !== 0) return;\n\n const waiters = this.idleWaiters.splice(0, this.idleWaiters.length);\n for (const resolve of waiters) resolve();\n }\n\n private resolveSessionIdleWaitersIfNeeded(sessionId: string): void {\n if (this.pending.has(sessionId) || this.inFlightSessions.has(sessionId))\n return;\n\n const waiters = this.sessionIdleWaiters.get(sessionId);\n if (!waiters || waiters.length === 0) return;\n\n this.sessionIdleWaiters.delete(sessionId);\n for (const resolve of waiters) resolve();\n }\n}\n"],"mappings":"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","names":["sessionId"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lcm/archive.ts"],"sourcesContent":["import type Database from \"better-sqlite3\";\nimport { log } from \"../logger.js\";\nimport {\n type LcmMessagePartInput,\n type MessagePartSourceFormat,\n parseMessageParts,\n} from \"../message-parts/index.js\";\nimport { estimateTokenCount } from \"../token-estimate.js\";\n\nexport interface LcmMessage {\n id: number;\n session_id: string;\n turn_index: number;\n role: string;\n content: string;\n token_count: number;\n created_at: string;\n metadata: string | null;\n}\n\nexport interface LcmSearchResult {\n turn_index: number;\n role: string;\n snippet: string;\n session_id: string;\n score: number;\n}\n\nexport interface LcmSearchWithContentResult {\n id: number;\n turn_index: number;\n role: string;\n content: string;\n session_id: string;\n score: number;\n}\n\nexport interface LcmStructuredRecallMatch {\n part_id: number;\n message_id: number;\n turn_index: number;\n role: string;\n content: string;\n session_id: string;\n kind: string;\n tool_name: string | null;\n file_path: string | null;\n payload: string;\n score: number;\n}\n\n/** Shared script-aware token estimate used by LCM accounting. */\nexport const estimateTokens = estimateTokenCount;\n\nconst PUBLIC_LCM_SEARCH_LIMIT = 100;\n\nfunction normalizeSearchLimit(limit: number, fallback = 10, max = PUBLIC_LCM_SEARCH_LIMIT): number {\n if (typeof limit !== \"number\" || !Number.isFinite(limit)) return fallback;\n const normalized = Math.floor(limit);\n if (normalized <= 0) return 0;\n return Math.min(max, normalized);\n}\n\nfunction escapeSqlLike(value: string): string {\n return value.replace(/[\\\\%_]/g, (match) => `\\\\${match}`);\n}\n\nexport class LcmArchive {\n constructor(private readonly db: Database.Database) {}\n\n /** Append a message to the archive. Returns the row id. */\n appendMessage(\n sessionId: string,\n turnIndex: number,\n role: string,\n content: string,\n metadata?: Record<string, unknown>,\n parts?: LcmMessagePartInput[],\n ): number {\n const tokenCount = estimateTokens(content);\n const now = new Date().toISOString();\n const metaJson = metadata ? JSON.stringify(metadata) : null;\n\n const stmt = this.db.prepare(`\n INSERT INTO lcm_messages (session_id, turn_index, role, content, token_count, created_at, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n const result = stmt.run(sessionId, turnIndex, role, content, tokenCount, now, metaJson);\n const rowId = Number(result.lastInsertRowid);\n\n // Keep FTS in sync\n this.db\n .prepare(\"INSERT INTO lcm_messages_fts (rowid, content) VALUES (?, ?)\")\n .run(rowId, content);\n\n if (parts && parts.length > 0) {\n this.insertMessageParts(rowId, parts, now);\n }\n\n return rowId;\n }\n\n /** Append multiple messages in a single transaction. */\n appendMessages(\n sessionId: string,\n messages: Array<{\n turnIndex: number;\n role: string;\n content: string;\n metadata?: Record<string, unknown>;\n parts?: LcmMessagePartInput[];\n rawContent?: unknown;\n sourceFormat?: MessagePartSourceFormat;\n }>,\n options: { messagePartsEnabled?: boolean } = {},\n ): void {\n if (messages.length === 0) return;\n const captureMessageParts = options.messagePartsEnabled !== false;\n\n const txn = this.db.transaction(() => {\n for (const msg of messages) {\n const explicitParts =\n msg.parts && msg.parts.length > 0 ? msg.parts : undefined;\n const rawContent = msg.rawContent ?? msg.content;\n const parts =\n captureMessageParts\n ? explicitParts ??\n parseMessageParts(rawContent, {\n sourceFormat: msg.sourceFormat,\n renderedContent: msg.content,\n })\n : undefined;\n this.appendMessage(\n sessionId,\n msg.turnIndex,\n msg.role,\n msg.content,\n msg.metadata,\n parts,\n );\n }\n });\n txn();\n }\n\n insertMessageParts(\n messageId: number,\n parts: LcmMessagePartInput[],\n fallbackCreatedAt: string,\n ): void {\n if (parts.length === 0) return;\n const stmt = this.db.prepare(`\n INSERT INTO lcm_message_parts (message_id, ordinal, kind, payload, tool_name, file_path, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n for (let index = 0; index < parts.length; index += 1) {\n const part = parts[index]!;\n const rawPart = part as unknown as Record<string, unknown>;\n const toolName = part.toolName ?? asNullableString(rawPart.tool_name);\n const filePath = part.filePath ?? asNullableString(rawPart.file_path);\n const createdAt = part.createdAt ?? asNullableString(rawPart.created_at);\n stmt.run(\n messageId,\n part.ordinal ?? index,\n part.kind,\n JSON.stringify(part.payload ?? {}),\n toolName ?? null,\n filePath ?? null,\n createdAt ?? fallbackCreatedAt,\n );\n }\n }\n\n /** Get the highest turn_index for a session, or -1 if none. */\n getMaxTurnIndex(sessionId: string): number {\n const row = this.db\n .prepare(\"SELECT MAX(turn_index) as max_turn FROM lcm_messages WHERE session_id = ?\")\n .get(sessionId) as { max_turn: number | null } | undefined;\n return row?.max_turn ?? -1;\n }\n\n /** Retrieve messages in a turn range (inclusive). */\n getMessages(sessionId: string, fromTurn: number, toTurn: number): LcmMessage[] {\n return this.db\n .prepare(\n \"SELECT * FROM lcm_messages WHERE session_id = ? AND turn_index >= ? AND turn_index <= ? ORDER BY turn_index\",\n )\n .all(sessionId, fromTurn, toTurn) as LcmMessage[];\n }\n\n /** Retrieve unsummarized messages (after last leaf summary). */\n getUnsummarizedMessages(sessionId: string): LcmMessage[] {\n const lastLeafEnd = this.db\n .prepare(\n \"SELECT MAX(msg_end) as last_end FROM lcm_summary_nodes WHERE session_id = ? AND depth = 0\",\n )\n .get(sessionId) as { last_end: number | null } | undefined;\n\n const lastSummarized = lastLeafEnd?.last_end ?? -1;\n return this.db\n .prepare(\n \"SELECT * FROM lcm_messages WHERE session_id = ? AND turn_index > ? ORDER BY turn_index\",\n )\n .all(sessionId, lastSummarized) as LcmMessage[];\n }\n\n /** Full-text search across all messages. */\n search(query: string, limit: number, sessionId?: string, sessionPrefix?: string): LcmSearchResult[] {\n try {\n const ftsQuery = sanitizeFtsQuery(query);\n if (!ftsQuery) return [];\n const cappedLimit = normalizeSearchLimit(limit);\n if (cappedLimit === 0) return [];\n\n let sql: string;\n const params: unknown[] = [ftsQuery];\n\n if (sessionId) {\n sql = `\n SELECT m.turn_index, m.role, snippet(lcm_messages_fts, 0, '>>>', '<<<', '...', 48) as snippet,\n m.session_id, rank\n FROM lcm_messages_fts f\n JOIN lcm_messages m ON m.id = f.rowid\n WHERE lcm_messages_fts MATCH ?\n AND m.session_id = ?\n ORDER BY rank\n LIMIT ?\n `;\n params.push(sessionId, cappedLimit);\n } else if (sessionPrefix) {\n sql = `\n SELECT m.turn_index, m.role, snippet(lcm_messages_fts, 0, '>>>', '<<<', '...', 48) as snippet,\n m.session_id, rank\n FROM lcm_messages_fts f\n JOIN lcm_messages m ON m.id = f.rowid\n WHERE lcm_messages_fts MATCH ?\n AND m.session_id LIKE ? ESCAPE '\\\\'\n ORDER BY rank\n LIMIT ?\n `;\n params.push(`${escapeSqlLike(sessionPrefix)}%`, cappedLimit);\n } else {\n sql = `\n SELECT m.turn_index, m.role, snippet(lcm_messages_fts, 0, '>>>', '<<<', '...', 48) as snippet,\n m.session_id, rank\n FROM lcm_messages_fts f\n JOIN lcm_messages m ON m.id = f.rowid\n WHERE lcm_messages_fts MATCH ?\n ORDER BY rank\n LIMIT ?\n `;\n params.push(cappedLimit);\n }\n\n const rows = this.db.prepare(sql).all(...params) as Array<{\n turn_index: number;\n role: string;\n snippet: string;\n session_id: string;\n rank: number;\n }>;\n\n return rows.map((r) => ({\n turn_index: r.turn_index,\n role: r.role,\n snippet: r.snippet,\n session_id: r.session_id,\n score: -r.rank, // FTS5 rank is negative; negate for ascending score\n }));\n } catch (err) {\n log.debug(`LCM FTS search error: ${err}`);\n return [];\n }\n }\n\n /**\n * Full-text search returning focused excerpts around matching terms.\n * Returns ~1000-char windows centered on query term matches.\n * Deduplicates by message id and returns results sorted by FTS rank.\n */\n searchWithContent(query: string, limit: number, sessionId?: string, excerptChars = 1000, sessionPrefix?: string): LcmSearchWithContentResult[] {\n try {\n const ftsQuery = sanitizeFtsQuery(query);\n if (!ftsQuery) return [];\n const cappedLimit = normalizeSearchLimit(limit);\n if (cappedLimit === 0) return [];\n\n // Extract content words from query for excerpt windowing\n const queryWords = query\n .replace(/[^\\w\\s]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !STOPWORDS.has(w.toLowerCase()))\n .map((w) => w.toLowerCase());\n\n let sql: string;\n const params: unknown[] = [ftsQuery];\n\n if (sessionId) {\n sql = `\n SELECT m.id, m.turn_index, m.role, m.content, m.session_id, rank\n FROM lcm_messages_fts f\n JOIN lcm_messages m ON m.id = f.rowid\n WHERE lcm_messages_fts MATCH ?\n AND m.session_id = ?\n ORDER BY rank\n LIMIT ?\n `;\n params.push(sessionId, cappedLimit);\n } else if (sessionPrefix) {\n sql = `\n SELECT m.id, m.turn_index, m.role, m.content, m.session_id, rank\n FROM lcm_messages_fts f\n JOIN lcm_messages m ON m.id = f.rowid\n WHERE lcm_messages_fts MATCH ?\n AND m.session_id LIKE ? ESCAPE '\\\\'\n ORDER BY rank\n LIMIT ?\n `;\n params.push(`${escapeSqlLike(sessionPrefix)}%`, cappedLimit);\n } else {\n sql = `\n SELECT m.id, m.turn_index, m.role, m.content, m.session_id, rank\n FROM lcm_messages_fts f\n JOIN lcm_messages m ON m.id = f.rowid\n WHERE lcm_messages_fts MATCH ?\n ORDER BY rank\n LIMIT ?\n `;\n params.push(cappedLimit);\n }\n\n const rows = this.db.prepare(sql).all(...params) as Array<{\n id: number;\n turn_index: number;\n role: string;\n content: string;\n session_id: string;\n rank: number;\n }>;\n\n // Deduplicate by message id (same message may match multiple terms)\n const seen = new Set<number>();\n const results: LcmSearchWithContentResult[] = [];\n for (const r of rows) {\n if (seen.has(r.id)) continue;\n seen.add(r.id);\n results.push({\n id: r.id,\n turn_index: r.turn_index,\n role: r.role,\n content: extractExcerpt(r.content, queryWords, excerptChars),\n session_id: r.session_id,\n score: -r.rank,\n });\n }\n return results;\n } catch (err) {\n log.debug(`LCM FTS searchWithContent error: ${err}`);\n return [];\n }\n }\n\n searchStructuredParts(\n query: string,\n limit: number,\n sessionId?: string,\n ): LcmStructuredRecallMatch[] {\n const cappedLimit = Math.max(0, Math.min(20, Math.floor(limit)));\n if (cappedLimit === 0) return [];\n\n const fileTerms = extractStructuredFileTerms(query);\n const toolTerms = extractStructuredToolTerms(query);\n if (fileTerms.length === 0 && toolTerms.length === 0) return [];\n\n const matchWhere: string[] = [];\n const whereParams: unknown[] = [];\n for (const term of fileTerms) {\n matchWhere.push(\"(p.file_path = ? OR p.file_path LIKE ? ESCAPE '\\\\')\");\n whereParams.push(term, `%${escapeLike(term)}%`);\n }\n for (const term of toolTerms) {\n matchWhere.push(\"p.tool_name LIKE ? ESCAPE '\\\\'\");\n whereParams.push(`%${escapeLike(term)}%`);\n }\n const where = [`(${matchWhere.join(\" OR \")})`];\n if (sessionId) {\n where.push(\"m.session_id = ?\");\n whereParams.push(sessionId);\n }\n const exactFileScoreParams = [...fileTerms];\n const sqlParams = [...exactFileScoreParams, ...whereParams, cappedLimit];\n\n const rows = this.db.prepare(`\n SELECT\n p.id AS part_id,\n p.message_id AS message_id,\n m.turn_index AS turn_index,\n m.role AS role,\n m.content AS content,\n m.session_id AS session_id,\n p.kind AS kind,\n p.tool_name AS tool_name,\n p.file_path AS file_path,\n p.payload AS payload,\n CASE\n WHEN p.file_path IN (${fileTerms.map(() => \"?\").join(\",\") || \"NULL\"}) THEN 3\n WHEN p.file_path IS NOT NULL THEN 2\n WHEN p.tool_name IS NOT NULL THEN 1\n ELSE 0\n END AS score\n FROM lcm_message_parts p\n JOIN lcm_messages m ON m.id = p.message_id\n WHERE ${where.join(\" AND \")}\n ORDER BY score DESC, m.turn_index DESC, p.ordinal ASC\n LIMIT ?\n `).all(...sqlParams) as LcmStructuredRecallMatch[];\n\n return rows;\n }\n\n /** Get total message count for a session. */\n getMessageCount(sessionId: string): number {\n const row = this.db\n .prepare(\"SELECT COUNT(*) as cnt FROM lcm_messages WHERE session_id = ?\")\n .get(sessionId) as { cnt: number };\n return row.cnt;\n }\n\n /** Get total message count across all sessions. */\n getTotalMessageCount(): number {\n const row = this.db\n .prepare(\"SELECT COUNT(*) as cnt FROM lcm_messages\")\n .get() as { cnt: number };\n return row.cnt;\n }\n\n /** Delete all archived messages for one session. */\n deleteSession(sessionId: string): number {\n const txn = this.db.transaction(() => {\n this.db\n .prepare(\n \"DELETE FROM lcm_messages_fts WHERE rowid IN (SELECT id FROM lcm_messages WHERE session_id = ?)\",\n )\n .run(sessionId);\n this.db\n .prepare(\n \"DELETE FROM lcm_message_parts WHERE message_id IN (SELECT id FROM lcm_messages WHERE session_id = ?)\",\n )\n .run(sessionId);\n const result = this.db\n .prepare(\"DELETE FROM lcm_messages WHERE session_id = ?\")\n .run(sessionId);\n return result.changes;\n });\n return txn();\n }\n\n /** Delete all archived messages. */\n deleteAll(): number {\n const txn = this.db.transaction(() => {\n this.db.prepare(\"DELETE FROM lcm_messages_fts\").run();\n this.db.prepare(\"DELETE FROM lcm_message_parts\").run();\n const result = this.db.prepare(\"DELETE FROM lcm_messages\").run();\n return result.changes;\n });\n return txn();\n }\n\n /** Prune messages older than retentionDays. */\n pruneOldMessages(retentionDays: number): number {\n const cutoff = new Date(Date.now() - retentionDays * 86400_000).toISOString();\n\n const txn = this.db.transaction(() => {\n // Delete from FTS and child tables first. Some handles may not have\n // foreign_keys enabled, so do not rely on ON DELETE CASCADE for parts.\n this.db\n .prepare(\n \"DELETE FROM lcm_messages_fts WHERE rowid IN (SELECT id FROM lcm_messages WHERE created_at < ?)\",\n )\n .run(cutoff);\n this.db\n .prepare(\n \"DELETE FROM lcm_message_parts WHERE message_id IN (SELECT id FROM lcm_messages WHERE created_at < ?)\",\n )\n .run(cutoff);\n\n const result = this.db\n .prepare(\"DELETE FROM lcm_messages WHERE created_at < ?\")\n .run(cutoff);\n return result.changes;\n });\n return txn();\n }\n}\n\n/**\n * Extract a focused excerpt from content centered on query term matches.\n * Returns a window of ~excerptChars around the first matching term.\n * If content is shorter than excerptChars, returns the full content.\n */\nfunction extractExcerpt(content: string, queryWords: string[], excerptChars: number): string {\n if (content.length <= excerptChars) return content;\n\n // Find the earliest position of any query word in the content\n const contentLower = content.toLowerCase();\n let bestPos = -1;\n for (const word of queryWords) {\n const pos = contentLower.indexOf(word);\n if (pos !== -1 && (bestPos === -1 || pos < bestPos)) {\n bestPos = pos;\n }\n }\n\n // If no match found (shouldn't happen for FTS results), return start\n if (bestPos === -1) {\n return content.slice(0, excerptChars) + \"...\";\n }\n\n // Center the window around the match\n const halfWindow = Math.floor(excerptChars / 2);\n let start = Math.max(0, bestPos - halfWindow);\n let end = Math.min(content.length, start + excerptChars);\n\n // Adjust start if we hit the end\n if (end === content.length) {\n start = Math.max(0, end - excerptChars);\n }\n\n // Extend to sentence boundaries if possible\n if (start > 0) {\n const sentenceStart = content.lastIndexOf(\". \", start);\n if (sentenceStart !== -1 && start - sentenceStart < 200) {\n start = sentenceStart + 2;\n }\n }\n if (end < content.length) {\n const sentenceEnd = content.indexOf(\". \", end - 1);\n if (sentenceEnd !== -1 && sentenceEnd - end < 200) {\n end = sentenceEnd + 1;\n }\n }\n\n const prefix = start > 0 ? \"...\" : \"\";\n const suffix = end < content.length ? \"...\" : \"\";\n return prefix + content.slice(start, end) + suffix;\n}\n\nconst STOPWORDS = new Set([\n \"a\", \"an\", \"the\", \"is\", \"are\", \"was\", \"were\", \"be\", \"been\", \"being\",\n \"have\", \"has\", \"had\", \"do\", \"does\", \"did\", \"will\", \"would\", \"could\",\n \"should\", \"may\", \"might\", \"shall\", \"can\", \"to\", \"of\", \"in\", \"for\",\n \"on\", \"with\", \"at\", \"by\", \"from\", \"as\", \"into\", \"about\", \"between\",\n \"through\", \"during\", \"before\", \"after\", \"and\", \"but\", \"or\", \"nor\",\n \"not\", \"so\", \"if\", \"then\", \"than\", \"that\", \"this\", \"it\", \"its\",\n \"what\", \"which\", \"who\", \"whom\", \"how\", \"when\", \"where\", \"why\",\n \"all\", \"each\", \"every\", \"both\", \"few\", \"more\", \"most\", \"other\",\n \"some\", \"such\", \"no\", \"only\", \"own\", \"same\", \"just\", \"very\",\n \"my\", \"your\", \"his\", \"her\", \"our\", \"their\", \"me\", \"him\", \"us\", \"them\",\n \"i\", \"you\", \"he\", \"she\", \"we\", \"they\",\n]);\n\nfunction extractStructuredFileTerms(query: string): string[] {\n const terms = new Set<string>();\n for (const raw of splitQueryTerms(query)) {\n const cleaned = trimStructuredQueryTerm(raw);\n if (\n cleaned.includes(\"/\") ||\n hasStructuredFileExtension(cleaned)\n ) {\n terms.add(cleaned);\n const basename = cleaned.split(\"/\").pop();\n if (basename && basename !== cleaned) terms.add(basename);\n }\n }\n return [...terms].filter((term) => term.length > 1).slice(0, 12);\n}\n\nfunction splitQueryTerms(query: string): string[] {\n const terms: string[] = [];\n let term = \"\";\n for (const char of query.slice(0, 20_000)) {\n if (char === \" \" || char === \"\\n\" || char === \"\\r\" || char === \"\\t\") {\n if (term.length > 0) terms.push(term);\n term = \"\";\n continue;\n }\n term += char;\n if (term.length > 512) {\n terms.push(term);\n term = \"\";\n }\n }\n if (term.length > 0) terms.push(term);\n return terms;\n}\n\nfunction trimStructuredQueryTerm(raw: string): string {\n const leading = new Set([\"`\", \"'\", \"\\\"\", \"(\", \"[\", \"{\"]);\n const trailing = new Set([\"`\", \"'\", \"\\\"\", \",\", \".\", \"?\", \"!\", \":\", \";\", \")\", \"]\", \"}\"]);\n let start = 0;\n let end = raw.length;\n while (start < end && leading.has(raw[start]!)) start += 1;\n while (end > start && trailing.has(raw[end - 1]!)) end -= 1;\n return raw.slice(start, end);\n}\n\nfunction hasStructuredFileExtension(value: string): boolean {\n const slash = value.lastIndexOf(\"/\");\n const basename = value.slice(slash + 1);\n const dot = basename.lastIndexOf(\".\");\n if (dot <= 0 || dot === basename.length - 1) return false;\n const ext = basename.slice(dot + 1);\n if (ext.length < 1 || ext.length > 12) return false;\n for (const char of ext) {\n const code = char.charCodeAt(0);\n const valid =\n (code >= 48 && code <= 57) ||\n (code >= 65 && code <= 90) ||\n (code >= 97 && code <= 122) ||\n char === \"_\" ||\n char === \"+\" ||\n char === \"-\";\n if (!valid) return false;\n }\n return true;\n}\n\nfunction extractStructuredToolTerms(query: string): string[] {\n const lower = query.toLowerCase();\n if (!/\\b(tool|command|invocation|called|used|ran|read|write|patch|edit|grep|search)\\b/.test(lower)) {\n return [];\n }\n return query\n .replace(/[^\\w.-]/g, \" \")\n .split(/\\s+/)\n .filter((term) => term.length > 2 && !STOPWORDS.has(term.toLowerCase()))\n .slice(0, 8);\n}\n\nfunction escapeLike(value: string): string {\n return value.replace(/[\\\\%_]/g, (char) => `\\\\${char}`);\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim().length > 0 ? value : null;\n}\n\n/**\n * Sanitize a query for FTS5 MATCH.\n * Uses OR logic so partial matches rank higher than no matches.\n * Filters stopwords to focus on content words.\n */\nfunction sanitizeFtsQuery(raw: string): string {\n const words = raw\n .replace(/[^\\w\\s]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !STOPWORDS.has(w.toLowerCase()));\n if (words.length === 0) {\n // If all words were stopwords, fall back to using all words\n const allWords = raw.replace(/[^\\w\\s]/g, \" \").split(/\\s+/).filter((w) => w.length > 1);\n if (allWords.length === 0) return \"\";\n return allWords.map((w) => `\"${w}\"`).join(\" OR \");\n }\n return words.map((w) => `\"${w}\"`).join(\" OR \");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lcm/engine.ts"],"sourcesContent":["import type Database from \"better-sqlite3\";\nimport { openLcmDatabase, ensureLcmStateDir } from \"./schema.js\";\nimport { LcmArchive, type LcmMessage, type LcmStructuredRecallMatch } from \"./archive.js\";\nimport { LcmDag } from \"./dag.js\";\nimport { LcmSummarizer, type SummarizeFn } from \"./summarizer.js\";\nimport {\n assembleCompressedHistoryWithTrace,\n type LcmRecallConfig,\n type LcmRecallWithTraceResult,\n} from \"./recall.js\";\nimport { LcmWorkQueue, type LcmObserveMessage } from \"./queue.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport { estimateTokenCount } from \"../token-estimate.js\";\nimport { log } from \"../logger.js\";\nimport { nativeBindingRecoveryHint } from \"../native-binding-hint.js\";\nexport interface LcmEngineConfig {\n enabled: boolean;\n leafBatchSize: number;\n rollupFanIn: number;\n freshTailTurns: number;\n maxDepth: number;\n deterministicMaxTokens: number;\n archiveRetentionDays: number;\n recallBudgetShare: number;\n observeConcurrency: number;\n telemetryPrefilterEnabled: boolean;\n messagePartsEnabled: boolean;\n messagePartsRecallMaxResults: number;\n}\n\n/** An expanded archive row with stable lineage identity; content may be budget-truncated. */\nexport interface LcmExpandedMessage {\n id: number;\n session_id: string;\n turn_index: number;\n role: string;\n content: string;\n}\n\nfunction positiveInteger(value: unknown, fallback: number, min = 1): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.floor(value));\n}\n\nfunction abortOnSignal<T>(abortSignal: AbortSignal | undefined, work: Promise<T>): Promise<T> {\n if (abortSignal === undefined) return work;\n abortSignal.throwIfAborted();\n return new Promise((resolve, reject) => {\n const onAbort = (): void => {\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new DOMException(\"Aborted\", \"AbortError\"));\n };\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n work.then(resolve, reject).finally(() => abortSignal.removeEventListener(\"abort\", onAbort));\n });\n}\n\nexport function extractLcmConfig(cfg: PluginConfig): LcmEngineConfig {\n return {\n enabled: (cfg as any).lcmEnabled === true,\n leafBatchSize: positiveInteger((cfg as any).lcmLeafBatchSize, 8),\n rollupFanIn: positiveInteger((cfg as any).lcmRollupFanIn, 4, 2),\n freshTailTurns: positiveInteger((cfg as any).lcmFreshTailTurns, 16),\n maxDepth: positiveInteger((cfg as any).lcmMaxDepth, 5),\n deterministicMaxTokens: positiveInteger((cfg as any).lcmDeterministicMaxTokens, 512),\n archiveRetentionDays: positiveInteger((cfg as any).lcmArchiveRetentionDays, 90, 0),\n recallBudgetShare: (cfg as any).lcmRecallBudgetShare ?? 0.15,\n observeConcurrency:\n typeof (cfg as any).lcmObserveConcurrency === \"number\" &&\n Number.isFinite((cfg as any).lcmObserveConcurrency)\n ? Math.max(1, Math.floor((cfg as any).lcmObserveConcurrency))\n : 1,\n telemetryPrefilterEnabled: (cfg as any).lcmTelemetryPrefilterEnabled !== false,\n messagePartsEnabled: (cfg as any).messagePartsEnabled === true,\n messagePartsRecallMaxResults:\n typeof (cfg as any).messagePartsRecallMaxResults === \"number\"\n ? Math.max(0, Math.floor((cfg as any).messagePartsRecallMaxResults))\n : 6,\n };\n}\n\nfunction normalizeLcmSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nfunction normalizeOptionalLcmSessionId(sessionId?: string): string | undefined {\n if (sessionId === undefined) {\n return undefined;\n }\n const normalized = normalizeLcmSessionId(sessionId);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nconst EMPTY_LCM_STATS = {\n totalMessages: 0,\n totalSummaryNodes: 0,\n maxDepth: -1,\n} as const;\n\nexport class LcmEngine {\n private db: Database.Database | null = null;\n private archive: LcmArchive | null = null;\n private dag: LcmDag | null = null;\n private summarizer: LcmSummarizer | null = null;\n private observeQueue: LcmWorkQueue | null = null;\n private closed = false;\n private readonly config: LcmEngineConfig;\n private readonly memoryDir: string;\n private initPromise: Promise<void> | null = null;\n private readonly pendingObserveInitCounts = new Map<string, number>();\n private readonly pendingObserveInitWaiters = new Map<string, Array<() => void>>();\n private readonly pendingObserveInitIdleWaiters: Array<() => void> = [];\n\n constructor(\n pluginConfig: PluginConfig,\n private readonly summarizeFn: SummarizeFn,\n ) {\n this.config = extractLcmConfig(pluginConfig);\n this.memoryDir = pluginConfig.memoryDir;\n }\n\n get enabled(): boolean {\n return this.config.enabled;\n }\n\n /** Lazy init — open database on first use. */\n async ensureInitialized(): Promise<void> {\n if (this.closed) return;\n if (this.db) return;\n if (this.initPromise) {\n await this.initPromise;\n return;\n }\n this.initPromise = this.doInit().catch((err) => {\n // Reset so next call retries instead of caching the failure\n this.initPromise = null;\n throw err;\n });\n await this.initPromise;\n }\n\n private async doInit(): Promise<void> {\n await ensureLcmStateDir(this.memoryDir);\n const db = openLcmDatabase(this.memoryDir);\n const archive = new LcmArchive(db);\n const dag = new LcmDag(db);\n const { telemetryPrefilterEnabled } = this.config;\n const summarizer = new LcmSummarizer(\n archive,\n dag,\n this.summarizeFn,\n {\n leafBatchSize: this.config.leafBatchSize,\n rollupFanIn: this.config.rollupFanIn,\n maxDepth: this.config.maxDepth,\n deterministicMaxTokens: this.config.deterministicMaxTokens,\n telemetryPrefilterEnabled,\n },\n );\n const observeQueue = new LcmWorkQueue({\n concurrency: this.config.observeConcurrency,\n worker: async (sessionId, messages) => {\n await this.processObserveMessages(sessionId, messages);\n },\n hooks: {\n onJobStart: ({ sessionId, depth, inFlight, waitMs }) => {\n log.debug(\n `LCM observe queue start: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms`,\n );\n },\n onJobFinish: ({\n sessionId,\n depth,\n inFlight,\n waitMs,\n runMs,\n totalMs,\n error,\n }) => {\n if (error) {\n log.error(\n `LCM observe queue failure: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms, run=${runMs}ms, total=${totalMs}ms, error=${error}`,\n );\n return;\n }\n\n log.debug(\n `LCM observe queue finish: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms, run=${runMs}ms, total=${totalMs}ms`,\n );\n },\n },\n });\n\n if (this.closed) {\n db.close();\n return;\n }\n\n this.db = db;\n this.archive = archive;\n this.dag = dag;\n this.summarizer = summarizer;\n this.observeQueue = observeQueue;\n log.info(\"LCM engine initialized\");\n }\n\n /**\n * Enqueue messages from agent_end hook.\n * The queue worker performs the archive append and incremental summarization.\n */\n async observeMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): Promise<void> {\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n this.enqueueObserveMessages(normalizedSessionId, messages);\n }\n\n /** Enqueue an observe job without waiting for worker completion. */\n enqueueObserveMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): void {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n if (messages.length === 0) return;\n\n this.reservePendingObserveInit(normalizedSessionId);\n\n void this.ensureInitialized()\n .then(() => {\n if (this.closed || !this.observeQueue) return;\n this.observeQueue.enqueue(normalizedSessionId, messages);\n log.debug(\n `LCM observe enqueued: session=${normalizedSessionId}, depth=${this.observeQueue.depth}, inFlight=${this.observeQueue.inFlightCount}`,\n );\n })\n .catch((err) => {\n if (this.closed) return;\n log.error(\n `LCM observe enqueue initialization error: ${err}${nativeBindingRecoveryHint(err)}`,\n );\n })\n .finally(() => {\n this.releasePendingObserveInit(normalizedSessionId);\n });\n }\n\n private async processObserveMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): Promise<void> {\n if (this.closed) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.summarizer) return;\n\n if (messages.length === 0) return;\n\n const currentMax = this.archive.getMaxTurnIndex(sessionId);\n const { messagePartsEnabled } = this.config;\n const newMessages = messages.map((m, i) => ({\n turnIndex: currentMax + 1 + i,\n role: m.role,\n content: m.content,\n parts: messagePartsEnabled ? m.parts : undefined,\n rawContent: messagePartsEnabled ? m.rawContent : undefined,\n sourceFormat: messagePartsEnabled ? m.sourceFormat : undefined,\n }));\n\n this.archive.appendMessages(sessionId, newMessages, {\n messagePartsEnabled,\n });\n\n // Trigger incremental summarization inside the worker, after append.\n try {\n await this.summarizer.summarizeIncremental(sessionId);\n } catch (err) {\n log.debug(`LCM incremental summarization error: ${err}`);\n }\n }\n\n get observeQueueDepth(): number {\n return this.observeQueue?.depth ?? 0;\n }\n\n get observeQueueInFlightCount(): number {\n return this.observeQueue?.inFlightCount ?? 0;\n }\n\n async waitForObserveQueueIdle(): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n await this.ensureInitialized();\n if (this.closed) return;\n await this.waitForPendingObserveInitIdle();\n await this.observeQueue?.whenIdle();\n }\n\n async waitForSessionObserveIdle(sessionId: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n abortSignal?.throwIfAborted();\n if (this.closed) return;\n await this.waitForPendingObserveInitIdle(normalizedSessionId, abortSignal);\n await this.observeQueue?.whenSessionIdle(normalizedSessionId, abortSignal) ?? Promise.resolve();\n }\n\n private reservePendingObserveInit(sessionId: string): void {\n const count = this.pendingObserveInitCounts.get(sessionId) ?? 0;\n this.pendingObserveInitCounts.set(sessionId, count + 1);\n }\n\n private releasePendingObserveInit(sessionId: string): void {\n const count = this.pendingObserveInitCounts.get(sessionId);\n if (!count) return;\n\n if (count === 1) {\n this.pendingObserveInitCounts.delete(sessionId);\n const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];\n this.pendingObserveInitWaiters.delete(sessionId);\n for (const resolve of waiters) resolve();\n if (this.pendingObserveInitCounts.size === 0) {\n const idleWaiters = this.pendingObserveInitIdleWaiters.splice(\n 0,\n this.pendingObserveInitIdleWaiters.length,\n );\n for (const resolve of idleWaiters) resolve();\n }\n return;\n }\n\n this.pendingObserveInitCounts.set(sessionId, count - 1);\n }\n\n private async waitForPendingObserveInitIdle(sessionId?: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (sessionId) {\n if (!this.pendingObserveInitCounts.has(sessionId)) return;\n await new Promise<void>((resolve, reject) => {\n const finish = (): void => {\n abortSignal?.removeEventListener(\"abort\", onAbort);\n resolve();\n };\n const onAbort = (): void => {\n const remaining = (this.pendingObserveInitWaiters.get(sessionId) ?? []).filter((waiter) => waiter !== finish);\n if (remaining.length === 0) this.pendingObserveInitWaiters.delete(sessionId);\n else this.pendingObserveInitWaiters.set(sessionId, remaining);\n reject(abortSignal?.reason instanceof Error ? abortSignal.reason : new DOMException(\"Aborted\", \"AbortError\"));\n };\n const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];\n waiters.push(finish);\n this.pendingObserveInitWaiters.set(sessionId, waiters);\n abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n return;\n }\n\n if (this.pendingObserveInitCounts.size === 0) return;\n await new Promise<void>((resolve) => {\n this.pendingObserveInitIdleWaiters.push(resolve);\n });\n }\n\n /** Build the compressed history recall section for a session. */\n async assembleRecall(\n sessionId: string,\n budgetChars: number,\n ): Promise<string> {\n return (await this.assembleRecallWithTrace(sessionId, budgetChars)).text;\n }\n\n /** Build compressed recall plus content-free selected-summary receipts. */\n async assembleRecallWithTrace(\n sessionId: string,\n budgetChars: number,\n ): Promise<LcmRecallWithTraceResult> {\n if (!this.config.enabled) return { text: \"\", selectedSummaries: [] };\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return { text: \"\", selectedSummaries: [] };\n await this.ensureInitialized();\n\n const effectiveBudget = Math.ceil(\n budgetChars * this.config.recallBudgetShare,\n );\n if (effectiveBudget <= 0) return { text: \"\", selectedSummaries: [] };\n\n return assembleCompressedHistoryWithTrace(this.dag!, this.archive!, normalizedSessionId, {\n freshTailTurns: this.config.freshTailTurns,\n budgetChars: effectiveBudget,\n });\n }\n\n async searchStructuredParts(\n sessionId: string,\n query: string,\n limit = this.config.messagePartsRecallMaxResults,\n ): Promise<LcmStructuredRecallMatch[]> {\n const { messagePartsEnabled } = this.config;\n if (!this.config.enabled || !messagePartsEnabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n if (!this.archive) return [];\n return this.archive.searchStructuredParts(query, limit, normalizedSessionId);\n }\n\n formatStructuredRecall(\n matches: LcmStructuredRecallMatch[],\n budgetChars: number,\n ): string {\n if (matches.length === 0 || budgetChars <= 0) return \"\";\n const lines: string[] = [];\n let used = \"## Structured Session Matches\\n\\n\".length;\n for (const match of matches) {\n const label = match.file_path\n ? `${match.kind} ${match.file_path}`\n : match.tool_name\n ? `${match.kind} ${match.tool_name}`\n : match.kind;\n const excerpt = match.content.replace(/\\s+/g, \" \").slice(0, 220);\n const line = `- turn ${match.turn_index} (${match.role}): ${label} — ${excerpt}`;\n if (used + line.length + 1 > budgetChars) break;\n lines.push(line);\n used += line.length + 1;\n }\n return lines.length > 0 ? `## Structured Session Matches\\n\\n${lines.join(\"\\n\")}` : \"\";\n }\n\n /** Flush pending summaries before compaction (called from before_compaction hook). */\n async preCompactionFlush(sessionId: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n abortSignal?.throwIfAborted();\n await this.waitForSessionObserveIdle(normalizedSessionId, abortSignal);\n abortSignal?.throwIfAborted();\n\n try {\n await abortOnSignal(abortSignal, this.summarizer!.summarizeIncremental(normalizedSessionId));\n } catch (err) {\n if (abortSignal?.aborted) throw err;\n log.debug(`LCM pre-compaction flush error: ${err}`);\n }\n }\n\n /** Record a compaction event with real token counts (called from after_compaction hook). */\n async recordCompaction(\n sessionId: string,\n tokensBefore: number,\n tokensAfter: number,\n ): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n await this.waitForSessionObserveIdle(normalizedSessionId);\n\n const maxTurn = this.archive!.getMaxTurnIndex(normalizedSessionId);\n\n this.dag!.recordCompaction(normalizedSessionId, maxTurn, tokensBefore, tokensAfter);\n log.info(\n `LCM compaction recorded: session=${normalizedSessionId}, turn=${maxTurn}, tokens ${tokensBefore}→${tokensAfter}`,\n );\n }\n\n /** Verify archive coverage after compaction. */\n async verifyPostCompaction(sessionId: string): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n\n const msgCount = this.archive!.getMessageCount(normalizedSessionId);\n const nodeCount = this.dag!.getNodeCount(normalizedSessionId);\n log.debug(\n `LCM post-compaction verify: session=${normalizedSessionId}, messages=${msgCount}, summaryNodes=${nodeCount}`,\n );\n }\n\n // ── MCP Tool implementations ──\n\n /** Search across all conversation history via FTS (snippet mode). */\n async searchContext(\n query: string,\n limit: number,\n sessionId?: string,\n sessionPrefix?: string,\n ): Promise<\n Array<{\n turn_index: number;\n role: string;\n snippet: string;\n session_id: string;\n }>\n > {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) return [];\n const normalizedSessionPrefix = normalizeOptionalLcmSessionId(sessionPrefix);\n if (sessionPrefix !== undefined && !normalizedSessionPrefix) return [];\n await this.ensureInitialized();\n return this.archive!.search(query, limit, normalizedSessionId, normalizedSessionPrefix);\n }\n\n /** Search via FTS returning full message content (not snippets). */\n async searchContextFull(\n query: string,\n limit: number,\n sessionId?: string,\n sessionPrefix?: string,\n ): Promise<\n Array<{\n id: number;\n turn_index: number;\n role: string;\n content: string;\n session_id: string;\n score: number;\n }>\n > {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) return [];\n const normalizedSessionPrefix = normalizeOptionalLcmSessionId(sessionPrefix);\n if (sessionPrefix !== undefined && !normalizedSessionPrefix) return [];\n await this.ensureInitialized();\n return this.archive!.searchWithContent(\n query,\n limit,\n normalizedSessionId,\n 1000,\n normalizedSessionPrefix,\n );\n }\n\n /** Get a compressed summary of a turn range. */\n async describeContext(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n ): Promise<{ summary: string; turn_count: number; depth: number } | null> {\n if (!this.config.enabled) return null;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return null;\n await this.ensureInitialized();\n\n const nodes = this.dag!.getCoveringNodes(normalizedSessionId, fromTurn, toTurn);\n if (nodes.length === 0) {\n // No summary exists — build a description from raw messages\n const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n if (messages.length === 0) return null;\n const preview = messages\n .slice(0, 5)\n .map((m) => `[${m.role}] ${m.content.slice(0, 100)}`)\n .join(\"\\n\");\n return {\n summary: `No summary available for this range. Preview of ${messages.length} messages:\\n${preview}`,\n turn_count: messages.length,\n depth: -1,\n };\n }\n\n // Use the deepest covering node\n const best = nodes[0]; // Already sorted by depth DESC\n return {\n summary: best.summary_text,\n turn_count: best.msg_end - best.msg_start + 1,\n depth: best.depth,\n };\n }\n\n /**\n * Retrieve raw archived messages for a turn range (inclusive bounds),\n * read-only and unshaped — no token-budget trimming (issue #2331\n * episodic-context). Callers own truncation and cleaning.\n */\n async getTurnRange(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n ): Promise<LcmMessage[]> {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n return this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n }\n\n /** Retrieve raw messages for a turn range (lossless expansion). */\n async expandContext(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n maxTokens: number,\n ): Promise<LcmExpandedMessage[]> {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n\n const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n if (messages.length === 0) return [];\n\n // Enforce the token budget while keeping the existing first/last shape.\n const tokenBudget = Math.max(0, Math.floor(maxTokens));\n if (tokenBudget === 0) return [];\n const totalTokens = messages.reduce(\n (sum, message) => sum + estimateTokenCount(message.content),\n 0,\n );\n if (totalTokens <= tokenBudget) {\n return messages.map((m) => ({\n id: m.id,\n session_id: m.session_id,\n turn_index: m.turn_index,\n role: m.role,\n content: m.content,\n }));\n }\n\n const result: LcmExpandedMessage[] = [];\n const lastMsg = messages[messages.length - 1];\n const reservedLastTokens = Math.min(\n estimateTokenCount(lastMsg.content),\n Math.max(1, Math.floor(tokenBudget * 0.3)),\n );\n let remainingTokens = tokenBudget - reservedLastTokens;\n\n for (let i = 0; i < messages.length - 1; i++) {\n if (remainingTokens <= 0) break;\n const content = truncateToTokenBudget(\n messages[i].content,\n remainingTokens,\n );\n if (!content) continue;\n result.push({\n id: messages[i].id,\n session_id: messages[i].session_id,\n turn_index: messages[i].turn_index,\n role: messages[i].role,\n content,\n });\n remainingTokens -= estimateTokenCount(content);\n }\n\n const lastContent = truncateToTokenBudget(\n lastMsg.content,\n reservedLastTokens + remainingTokens,\n );\n if (lastContent) {\n result.push({\n id: lastMsg.id,\n session_id: lastMsg.session_id,\n turn_index: lastMsg.turn_index,\n role: lastMsg.role,\n content: lastContent,\n });\n }\n return result;\n }\n\n\n /** Get statistics about the LCM archive. */\n async getStats(sessionId?: string): Promise<{\n totalMessages: number;\n totalSummaryNodes: number;\n maxDepth: number;\n maxTurnIndex?: number;\n }> {\n if (!this.config.enabled)\n return { totalMessages: 0, totalSummaryNodes: 0, maxDepth: -1 };\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) {\n return { ...EMPTY_LCM_STATS };\n }\n await this.ensureInitialized();\n\n if (normalizedSessionId) {\n return {\n totalMessages: this.archive!.getMessageCount(normalizedSessionId),\n totalSummaryNodes: this.dag!.getNodeCount(normalizedSessionId),\n maxDepth: this.dag!.getMaxDepth(normalizedSessionId),\n maxTurnIndex: this.archive!.getMaxTurnIndex(normalizedSessionId),\n };\n }\n\n return {\n totalMessages: this.archive!.getTotalMessageCount(),\n totalSummaryNodes: 0, // Would need a global count query\n maxDepth: -1,\n };\n }\n\n /** Clear all LCM archive and summary state for one session. */\n async clearSession(sessionId: string): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.dag) return;\n await this.waitForSessionObserveIdle(normalizedSessionId);\n this.dag.deleteSession(normalizedSessionId);\n this.archive.deleteSession(normalizedSessionId);\n }\n\n /** Clear all LCM archive and summary state without closing the engine. */\n async clearAll(): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.dag) return;\n await this.waitForObserveQueueIdle();\n this.dag.deleteAll();\n this.archive.deleteAll();\n }\n\n /** Prune old data beyond retention period. */\n async prune(): Promise<{ messagesPruned: number; nodesPruned: number }> {\n if (!this.config.enabled) return { messagesPruned: 0, nodesPruned: 0 };\n await this.ensureInitialized();\n\n const messagesPruned = this.archive!.pruneOldMessages(\n this.config.archiveRetentionDays,\n );\n const nodesPruned = this.dag!.pruneOldNodes(\n this.config.archiveRetentionDays,\n );\n return { messagesPruned, nodesPruned };\n }\n\n /** Close the database connection. */\n close(): void {\n this.closed = true;\n if (this.db) {\n this.db.close();\n }\n this.db = null;\n this.archive = null;\n this.dag = null;\n this.summarizer = null;\n this.observeQueue = null;\n this.initPromise = null;\n }\n}\nfunction truncateToTokenBudget(text: string, maxTokens: number): string {\n if (maxTokens <= 0) return \"\";\n if (estimateTokenCount(text) <= maxTokens) return text;\n const codePoints = [...text];\n let low = 0;\n let high = codePoints.length;\n while (low < high) {\n const mid = Math.ceil((low + high) / 2);\n if (estimateTokenCount(codePoints.slice(0, mid).join(\"\")) <= maxTokens) {\n low = mid;\n } else {\n high = mid - 1;\n }\n }\n return codePoints.slice(0, low).join(\"\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAS,gBAAgB,OAAgB,UAAkB,MAAM,GAAW;AAC1E,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACjE,SAAO,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC;AACxC;AAEA,SAAS,cAAiB,aAAsC,MAA8B;AAC5F,MAAI,gBAAgB,OAAW,QAAO;AACtC,cAAY,eAAe;AAC3B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,UAAU,MAAY;AAC1B,aAAO,YAAY,kBAAkB,QAAQ,YAAY,SAAS,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,IAC7G;AACA,gBAAY,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAC7D,SAAK,KAAK,SAAS,MAAM,EAAE,QAAQ,MAAM,YAAY,oBAAoB,SAAS,OAAO,CAAC;AAAA,EAC5F,CAAC;AACH;AAEO,SAAS,iBAAiB,KAAoC;AACnE,SAAO;AAAA,IACL,SAAU,IAAY,eAAe;AAAA,IACrC,eAAe,gBAAiB,IAAY,kBAAkB,CAAC;AAAA,IAC/D,aAAa,gBAAiB,IAAY,gBAAgB,GAAG,CAAC;AAAA,IAC9D,gBAAgB,gBAAiB,IAAY,mBAAmB,EAAE;AAAA,IAClE,UAAU,gBAAiB,IAAY,aAAa,CAAC;AAAA,IACrD,wBAAwB,gBAAiB,IAAY,2BAA2B,GAAG;AAAA,IACnF,sBAAsB,gBAAiB,IAAY,yBAAyB,IAAI,CAAC;AAAA,IACjF,mBAAoB,IAAY,wBAAwB;AAAA,IACxD,oBACE,OAAQ,IAAY,0BAA0B,YAC5C,OAAO,SAAU,IAAY,qBAAqB,IAChD,KAAK,IAAI,GAAG,KAAK,MAAO,IAAY,qBAAqB,CAAC,IAC1D;AAAA,IACN,2BAA4B,IAAY,iCAAiC;AAAA,IACzE,qBAAsB,IAAY,wBAAwB;AAAA,IAC1D,8BACE,OAAQ,IAAY,iCAAiC,WACjD,KAAK,IAAI,GAAG,KAAK,MAAO,IAAY,4BAA4B,CAAC,IACjE;AAAA,EACR;AACF;AAEA,SAAS,sBAAsB,WAA2B;AACxD,SAAO,UAAU,KAAK;AACxB;AAEA,SAAS,8BAA8B,WAAwC;AAC7E,MAAI,cAAc,QAAW;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,sBAAsB,SAAS;AAClD,SAAO,WAAW,SAAS,IAAI,aAAa;AAC9C;AAEA,IAAM,kBAAkB;AAAA,EACtB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,UAAU;AACZ;AAEO,IAAM,YAAN,MAAgB;AAAA,EAcrB,YACE,cACiB,aACjB;AADiB;AAEjB,SAAK,SAAS,iBAAiB,YAAY;AAC3C,SAAK,YAAY,aAAa;AAAA,EAChC;AAAA,EAJmB;AAAA,EAfX,KAA+B;AAAA,EAC/B,UAA6B;AAAA,EAC7B,MAAqB;AAAA,EACrB,aAAmC;AAAA,EACnC,eAAoC;AAAA,EACpC,SAAS;AAAA,EACA;AAAA,EACA;AAAA,EACT,cAAoC;AAAA,EAC3B,2BAA2B,oBAAI,IAAoB;AAAA,EACnD,4BAA4B,oBAAI,IAA+B;AAAA,EAC/D,gCAAmD,CAAC;AAAA,EAUrE,IAAI,UAAmB;AACrB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA,EAGA,MAAM,oBAAmC;AACvC,QAAI,KAAK,OAAQ;AACjB,QAAI,KAAK,GAAI;AACb,QAAI,KAAK,aAAa;AACpB,YAAM,KAAK;AACX;AAAA,IACF;AACA,SAAK,cAAc,KAAK,OAAO,EAAE,MAAM,CAAC,QAAQ;AAE9C,WAAK,cAAc;AACnB,YAAM;AAAA,IACR,CAAC;AACD,UAAM,KAAK;AAAA,EACb;AAAA,EAEA,MAAc,SAAwB;AACpC,UAAM,kBAAkB,KAAK,SAAS;AACtC,UAAM,KAAK,gBAAgB,KAAK,SAAS;AACzC,UAAM,UAAU,IAAI,WAAW,EAAE;AACjC,UAAM,MAAM,IAAI,OAAO,EAAE;AACzB,UAAM,EAAE,0BAA0B,IAAI,KAAK;AAC3C,UAAM,aAAa,IAAI;AAAA,MACrB;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL;AAAA,QACE,eAAe,KAAK,OAAO;AAAA,QAC3B,aAAa,KAAK,OAAO;AAAA,QACzB,UAAU,KAAK,OAAO;AAAA,QACtB,wBAAwB,KAAK,OAAO;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AACA,UAAM,eAAe,IAAI,aAAa;AAAA,MACpC,aAAa,KAAK,OAAO;AAAA,MACzB,QAAQ,OAAO,WAAW,aAAa;AACrC,cAAM,KAAK,uBAAuB,WAAW,QAAQ;AAAA,MACvD;AAAA,MACA,OAAO;AAAA,QACL,YAAY,CAAC,EAAE,WAAW,OAAO,UAAU,OAAO,MAAM;AACtD,cAAI;AAAA,YACF,oCAAoC,SAAS,WAAW,KAAK,cAAc,QAAQ,UAAU,MAAM;AAAA,UACrG;AAAA,QACF;AAAA,QACA,aAAa,CAAC;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,MAAM;AACJ,cAAI,OAAO;AACT,gBAAI;AAAA,cACF,sCAAsC,SAAS,WAAW,KAAK,cAAc,QAAQ,UAAU,MAAM,WAAW,KAAK,aAAa,OAAO,aAAa,KAAK;AAAA,YAC7J;AACA;AAAA,UACF;AAEA,cAAI;AAAA,YACF,qCAAqC,SAAS,WAAW,KAAK,cAAc,QAAQ,UAAU,MAAM,WAAW,KAAK,aAAa,OAAO;AAAA,UAC1I;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,KAAK,QAAQ;AACf,SAAG,MAAM;AACT;AAAA,IACF;AAEA,SAAK,KAAK;AACV,SAAK,UAAU;AACf,SAAK,MAAM;AACX,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,QAAI,KAAK,wBAAwB;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBACJ,WACA,UACe;AACf,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,SAAK,uBAAuB,qBAAqB,QAAQ;AAAA,EAC3D;AAAA;AAAA,EAGA,uBACE,WACA,UACM;AACN,QAAI,CAAC,KAAK,OAAO,WAAW,KAAK,OAAQ;AACzC,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,QAAI,SAAS,WAAW,EAAG;AAE3B,SAAK,0BAA0B,mBAAmB;AAElD,SAAK,KAAK,kBAAkB,EACzB,KAAK,MAAM;AACV,UAAI,KAAK,UAAU,CAAC,KAAK,aAAc;AACvC,WAAK,aAAa,QAAQ,qBAAqB,QAAQ;AACvD,UAAI;AAAA,QACF,iCAAiC,mBAAmB,WAAW,KAAK,aAAa,KAAK,cAAc,KAAK,aAAa,aAAa;AAAA,MACrI;AAAA,IACF,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,KAAK,OAAQ;AACjB,UAAI;AAAA,QACF,6CAA6C,GAAG,GAAG,0BAA0B,GAAG,CAAC;AAAA,MACnF;AAAA,IACF,CAAC,EACA,QAAQ,MAAM;AACb,WAAK,0BAA0B,mBAAmB;AAAA,IACpD,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,uBACZ,WACA,UACe;AACf,QAAI,KAAK,OAAQ;AACjB,UAAM,KAAK,kBAAkB;AAC7B,QAAI,KAAK,UAAU,CAAC,KAAK,WAAW,CAAC,KAAK,WAAY;AAEtD,QAAI,SAAS,WAAW,EAAG;AAE3B,UAAM,aAAa,KAAK,QAAQ,gBAAgB,SAAS;AACzD,UAAM,EAAE,oBAAoB,IAAI,KAAK;AACrC,UAAM,cAAc,SAAS,IAAI,CAAC,GAAG,OAAO;AAAA,MAC1C,WAAW,aAAa,IAAI;AAAA,MAC5B,MAAM,EAAE;AAAA,MACR,SAAS,EAAE;AAAA,MACX,OAAO,sBAAsB,EAAE,QAAQ;AAAA,MACvC,YAAY,sBAAsB,EAAE,aAAa;AAAA,MACjD,cAAc,sBAAsB,EAAE,eAAe;AAAA,IACvD,EAAE;AAEF,SAAK,QAAQ,eAAe,WAAW,aAAa;AAAA,MAClD;AAAA,IACF,CAAC;AAGD,QAAI;AACF,YAAM,KAAK,WAAW,qBAAqB,SAAS;AAAA,IACtD,SAAS,KAAK;AACZ,UAAI,MAAM,wCAAwC,GAAG,EAAE;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,IAAI,oBAA4B;AAC9B,WAAO,KAAK,cAAc,SAAS;AAAA,EACrC;AAAA,EAEA,IAAI,4BAAoC;AACtC,WAAO,KAAK,cAAc,iBAAiB;AAAA,EAC7C;AAAA,EAEA,MAAM,0BAAyC;AAC7C,QAAI,CAAC,KAAK,OAAO,WAAW,KAAK,OAAQ;AACzC,UAAM,KAAK,kBAAkB;AAC7B,QAAI,KAAK,OAAQ;AACjB,UAAM,KAAK,8BAA8B;AACzC,UAAM,KAAK,cAAc,SAAS;AAAA,EACpC;AAAA,EAEA,MAAM,0BAA0B,WAAmB,aAA0C;AAC3F,iBAAa,eAAe;AAC5B,QAAI,CAAC,KAAK,OAAO,WAAW,KAAK,OAAQ;AACzC,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,UAAM,KAAK,kBAAkB;AAC7B,iBAAa,eAAe;AAC5B,QAAI,KAAK,OAAQ;AACjB,UAAM,KAAK,8BAA8B,qBAAqB,WAAW;AACzE,UAAM,KAAK,cAAc,gBAAgB,qBAAqB,WAAW,KAAK,QAAQ,QAAQ;AAAA,EAChG;AAAA,EAEQ,0BAA0B,WAAyB;AACzD,UAAM,QAAQ,KAAK,yBAAyB,IAAI,SAAS,KAAK;AAC9D,SAAK,yBAAyB,IAAI,WAAW,QAAQ,CAAC;AAAA,EACxD;AAAA,EAEQ,0BAA0B,WAAyB;AACzD,UAAM,QAAQ,KAAK,yBAAyB,IAAI,SAAS;AACzD,QAAI,CAAC,MAAO;AAEZ,QAAI,UAAU,GAAG;AACf,WAAK,yBAAyB,OAAO,SAAS;AAC9C,YAAM,UAAU,KAAK,0BAA0B,IAAI,SAAS,KAAK,CAAC;AAClE,WAAK,0BAA0B,OAAO,SAAS;AAC/C,iBAAW,WAAW,QAAS,SAAQ;AACvC,UAAI,KAAK,yBAAyB,SAAS,GAAG;AAC5C,cAAM,cAAc,KAAK,8BAA8B;AAAA,UACrD;AAAA,UACA,KAAK,8BAA8B;AAAA,QACrC;AACA,mBAAW,WAAW,YAAa,SAAQ;AAAA,MAC7C;AACA;AAAA,IACF;AAEA,SAAK,yBAAyB,IAAI,WAAW,QAAQ,CAAC;AAAA,EACxD;AAAA,EAEA,MAAc,8BAA8B,WAAoB,aAA0C;AACxG,iBAAa,eAAe;AAC5B,QAAI,WAAW;AACb,UAAI,CAAC,KAAK,yBAAyB,IAAI,SAAS,EAAG;AACnD,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,cAAM,SAAS,MAAY;AACzB,uBAAa,oBAAoB,SAAS,OAAO;AACjD,kBAAQ;AAAA,QACV;AACA,cAAM,UAAU,MAAY;AAC1B,gBAAM,aAAa,KAAK,0BAA0B,IAAI,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,WAAW,WAAW,MAAM;AAC5G,cAAI,UAAU,WAAW,EAAG,MAAK,0BAA0B,OAAO,SAAS;AAAA,cACtE,MAAK,0BAA0B,IAAI,WAAW,SAAS;AAC5D,iBAAO,aAAa,kBAAkB,QAAQ,YAAY,SAAS,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,QAC9G;AACA,cAAM,UAAU,KAAK,0BAA0B,IAAI,SAAS,KAAK,CAAC;AAClE,gBAAQ,KAAK,MAAM;AACnB,aAAK,0BAA0B,IAAI,WAAW,OAAO;AACrD,qBAAa,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,MAChE,CAAC;AACD;AAAA,IACF;AAEA,QAAI,KAAK,yBAAyB,SAAS,EAAG;AAC9C,UAAM,IAAI,QAAc,CAAC,YAAY;AACnC,WAAK,8BAA8B,KAAK,OAAO;AAAA,IACjD,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,eACJ,WACA,aACiB;AACjB,YAAQ,MAAM,KAAK,wBAAwB,WAAW,WAAW,GAAG;AAAA,EACtE;AAAA;AAAA,EAGA,MAAM,wBACJ,WACA,aACmC;AACnC,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO,EAAE,MAAM,IAAI,mBAAmB,CAAC,EAAE;AACnE,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB,QAAO,EAAE,MAAM,IAAI,mBAAmB,CAAC,EAAE;AACnE,UAAM,KAAK,kBAAkB;AAE7B,UAAM,kBAAkB,KAAK;AAAA,MAC3B,cAAc,KAAK,OAAO;AAAA,IAC5B;AACA,QAAI,mBAAmB,EAAG,QAAO,EAAE,MAAM,IAAI,mBAAmB,CAAC,EAAE;AAEnE,WAAO,mCAAmC,KAAK,KAAM,KAAK,SAAU,qBAAqB;AAAA,MACvF,gBAAgB,KAAK,OAAO;AAAA,MAC5B,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,sBACJ,WACA,OACA,QAAQ,KAAK,OAAO,8BACiB;AACrC,UAAM,EAAE,oBAAoB,IAAI,KAAK;AACrC,QAAI,CAAC,KAAK,OAAO,WAAW,CAAC,oBAAqB,QAAO,CAAC;AAC1D,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB,QAAO,CAAC;AAClC,UAAM,KAAK,kBAAkB;AAC7B,QAAI,CAAC,KAAK,QAAS,QAAO,CAAC;AAC3B,WAAO,KAAK,QAAQ,sBAAsB,OAAO,OAAO,mBAAmB;AAAA,EAC7E;AAAA,EAEA,uBACE,SACA,aACQ;AACR,QAAI,QAAQ,WAAW,KAAK,eAAe,EAAG,QAAO;AACrD,UAAM,QAAkB,CAAC;AACzB,QAAI,OAAO,oCAAoC;AAC/C,eAAW,SAAS,SAAS;AAC3B,YAAM,QAAQ,MAAM,YAChB,GAAG,MAAM,IAAI,IAAI,MAAM,SAAS,KAChC,MAAM,YACJ,GAAG,MAAM,IAAI,IAAI,MAAM,SAAS,KAChC,MAAM;AACZ,YAAM,UAAU,MAAM,QAAQ,QAAQ,QAAQ,GAAG,EAAE,MAAM,GAAG,GAAG;AAC/D,YAAM,OAAO,UAAU,MAAM,UAAU,KAAK,MAAM,IAAI,MAAM,KAAK,WAAM,OAAO;AAC9E,UAAI,OAAO,KAAK,SAAS,IAAI,YAAa;AAC1C,YAAM,KAAK,IAAI;AACf,cAAQ,KAAK,SAAS;AAAA,IACxB;AACA,WAAO,MAAM,SAAS,IAAI;AAAA;AAAA,EAAoC,MAAM,KAAK,IAAI,CAAC,KAAK;AAAA,EACrF;AAAA;AAAA,EAGA,MAAM,mBAAmB,WAAmB,aAA0C;AACpF,iBAAa,eAAe;AAC5B,QAAI,CAAC,KAAK,OAAO,QAAS;AAC1B,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,UAAM,KAAK,kBAAkB;AAC7B,iBAAa,eAAe;AAC5B,UAAM,KAAK,0BAA0B,qBAAqB,WAAW;AACrE,iBAAa,eAAe;AAE5B,QAAI;AACF,YAAM,cAAc,aAAa,KAAK,WAAY,qBAAqB,mBAAmB,CAAC;AAAA,IAC7F,SAAS,KAAK;AACZ,UAAI,aAAa,QAAS,OAAM;AAChC,UAAI,MAAM,mCAAmC,GAAG,EAAE;AAAA,IACpD;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,iBACJ,WACA,cACA,aACe;AACf,QAAI,CAAC,KAAK,OAAO,QAAS;AAC1B,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,0BAA0B,mBAAmB;AAExD,UAAM,UAAU,KAAK,QAAS,gBAAgB,mBAAmB;AAEjE,SAAK,IAAK,iBAAiB,qBAAqB,SAAS,cAAc,WAAW;AAClF,QAAI;AAAA,MACF,oCAAoC,mBAAmB,UAAU,OAAO,YAAY,YAAY,SAAI,WAAW;AAAA,IACjH;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,qBAAqB,WAAkC;AAC3D,QAAI,CAAC,KAAK,OAAO,QAAS;AAC1B,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,UAAM,KAAK,kBAAkB;AAE7B,UAAM,WAAW,KAAK,QAAS,gBAAgB,mBAAmB;AAClE,UAAM,YAAY,KAAK,IAAK,aAAa,mBAAmB;AAC5D,QAAI;AAAA,MACF,uCAAuC,mBAAmB,cAAc,QAAQ,kBAAkB,SAAS;AAAA,IAC7G;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,OACA,OACA,WACA,eAQA;AACA,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO,CAAC;AAClC,UAAM,sBAAsB,8BAA8B,SAAS;AACnE,QAAI,cAAc,UAAa,CAAC,oBAAqB,QAAO,CAAC;AAC7D,UAAM,0BAA0B,8BAA8B,aAAa;AAC3E,QAAI,kBAAkB,UAAa,CAAC,wBAAyB,QAAO,CAAC;AACrE,UAAM,KAAK,kBAAkB;AAC7B,WAAO,KAAK,QAAS,OAAO,OAAO,OAAO,qBAAqB,uBAAuB;AAAA,EACxF;AAAA;AAAA,EAGA,MAAM,kBACJ,OACA,OACA,WACA,eAUA;AACA,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO,CAAC;AAClC,UAAM,sBAAsB,8BAA8B,SAAS;AACnE,QAAI,cAAc,UAAa,CAAC,oBAAqB,QAAO,CAAC;AAC7D,UAAM,0BAA0B,8BAA8B,aAAa;AAC3E,QAAI,kBAAkB,UAAa,CAAC,wBAAyB,QAAO,CAAC;AACrE,UAAM,KAAK,kBAAkB;AAC7B,WAAO,KAAK,QAAS;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,gBACJ,WACA,UACA,QACwE;AACxE,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO;AACjC,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB,QAAO;AACjC,UAAM,KAAK,kBAAkB;AAE7B,UAAM,QAAQ,KAAK,IAAK,iBAAiB,qBAAqB,UAAU,MAAM;AAC9E,QAAI,MAAM,WAAW,GAAG;AAEtB,YAAM,WAAW,KAAK,QAAS,YAAY,qBAAqB,UAAU,MAAM;AAChF,UAAI,SAAS,WAAW,EAAG,QAAO;AAClC,YAAM,UAAU,SACb,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,EAAE,QAAQ,MAAM,GAAG,GAAG,CAAC,EAAE,EACnD,KAAK,IAAI;AACZ,aAAO;AAAA,QACL,SAAS,mDAAmD,SAAS,MAAM;AAAA,EAAe,OAAO;AAAA,QACjG,YAAY,SAAS;AAAA,QACrB,OAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,OAAO,MAAM,CAAC;AACpB,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,YAAY,KAAK,UAAU,KAAK,YAAY;AAAA,MAC5C,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aACJ,WACA,UACA,QACuB;AACvB,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO,CAAC;AAClC,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB,QAAO,CAAC;AAClC,UAAM,KAAK,kBAAkB;AAC7B,WAAO,KAAK,QAAS,YAAY,qBAAqB,UAAU,MAAM;AAAA,EACxE;AAAA;AAAA,EAGA,MAAM,cACJ,WACA,UACA,QACA,WAC+B;AAC/B,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO,CAAC;AAClC,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB,QAAO,CAAC;AAClC,UAAM,KAAK,kBAAkB;AAE7B,UAAM,WAAW,KAAK,QAAS,YAAY,qBAAqB,UAAU,MAAM;AAChF,QAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AAGnC,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,CAAC;AACrD,QAAI,gBAAgB,EAAG,QAAO,CAAC;AAC/B,UAAM,cAAc,SAAS;AAAA,MAC3B,CAAC,KAAK,YAAY,MAAM,mBAAmB,QAAQ,OAAO;AAAA,MAC1D;AAAA,IACF;AACA,QAAI,eAAe,aAAa;AAC9B,aAAO,SAAS,IAAI,CAAC,OAAO;AAAA,QAC1B,IAAI,EAAE;AAAA,QACN,YAAY,EAAE;AAAA,QACd,YAAY,EAAE;AAAA,QACd,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,MACb,EAAE;AAAA,IACJ;AAEA,UAAM,SAA+B,CAAC;AACtC,UAAM,UAAU,SAAS,SAAS,SAAS,CAAC;AAC5C,UAAM,qBAAqB,KAAK;AAAA,MAC9B,mBAAmB,QAAQ,OAAO;AAAA,MAClC,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,GAAG,CAAC;AAAA,IAC3C;AACA,QAAI,kBAAkB,cAAc;AAEpC,aAAS,IAAI,GAAG,IAAI,SAAS,SAAS,GAAG,KAAK;AAC5C,UAAI,mBAAmB,EAAG;AAC1B,YAAM,UAAU;AAAA,QACd,SAAS,CAAC,EAAE;AAAA,QACZ;AAAA,MACF;AACA,UAAI,CAAC,QAAS;AACd,aAAO,KAAK;AAAA,QACV,IAAI,SAAS,CAAC,EAAE;AAAA,QAChB,YAAY,SAAS,CAAC,EAAE;AAAA,QACxB,YAAY,SAAS,CAAC,EAAE;AAAA,QACxB,MAAM,SAAS,CAAC,EAAE;AAAA,QAClB;AAAA,MACF,CAAC;AACD,yBAAmB,mBAAmB,OAAO;AAAA,IAC/C;AAEA,UAAM,cAAc;AAAA,MAClB,QAAQ;AAAA,MACR,qBAAqB;AAAA,IACvB;AACA,QAAI,aAAa;AACf,aAAO,KAAK;AAAA,QACV,IAAI,QAAQ;AAAA,QACZ,YAAY,QAAQ;AAAA,QACpB,YAAY,QAAQ;AAAA,QACpB,MAAM,QAAQ;AAAA,QACd,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,SAAS,WAKZ;AACD,QAAI,CAAC,KAAK,OAAO;AACf,aAAO,EAAE,eAAe,GAAG,mBAAmB,GAAG,UAAU,GAAG;AAChE,UAAM,sBAAsB,8BAA8B,SAAS;AACnE,QAAI,cAAc,UAAa,CAAC,qBAAqB;AACnD,aAAO,EAAE,GAAG,gBAAgB;AAAA,IAC9B;AACA,UAAM,KAAK,kBAAkB;AAE7B,QAAI,qBAAqB;AACvB,aAAO;AAAA,QACL,eAAe,KAAK,QAAS,gBAAgB,mBAAmB;AAAA,QAChE,mBAAmB,KAAK,IAAK,aAAa,mBAAmB;AAAA,QAC7D,UAAU,KAAK,IAAK,YAAY,mBAAmB;AAAA,QACnD,cAAc,KAAK,QAAS,gBAAgB,mBAAmB;AAAA,MACjE;AAAA,IACF;AAEA,WAAO;AAAA,MACL,eAAe,KAAK,QAAS,qBAAqB;AAAA,MAClD,mBAAmB;AAAA;AAAA,MACnB,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aAAa,WAAkC;AACnD,QAAI,CAAC,KAAK,OAAO,WAAW,KAAK,OAAQ;AACzC,UAAM,sBAAsB,sBAAsB,SAAS;AAC3D,QAAI,CAAC,oBAAqB;AAC1B,UAAM,KAAK,kBAAkB;AAC7B,QAAI,KAAK,UAAU,CAAC,KAAK,WAAW,CAAC,KAAK,IAAK;AAC/C,UAAM,KAAK,0BAA0B,mBAAmB;AACxD,SAAK,IAAI,cAAc,mBAAmB;AAC1C,SAAK,QAAQ,cAAc,mBAAmB;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,WAA0B;AAC9B,QAAI,CAAC,KAAK,OAAO,WAAW,KAAK,OAAQ;AACzC,UAAM,KAAK,kBAAkB;AAC7B,QAAI,KAAK,UAAU,CAAC,KAAK,WAAW,CAAC,KAAK,IAAK;AAC/C,UAAM,KAAK,wBAAwB;AACnC,SAAK,IAAI,UAAU;AACnB,SAAK,QAAQ,UAAU;AAAA,EACzB;AAAA;AAAA,EAGA,MAAM,QAAkE;AACtE,QAAI,CAAC,KAAK,OAAO,QAAS,QAAO,EAAE,gBAAgB,GAAG,aAAa,EAAE;AACrE,UAAM,KAAK,kBAAkB;AAE7B,UAAM,iBAAiB,KAAK,QAAS;AAAA,MACnC,KAAK,OAAO;AAAA,IACd;AACA,UAAM,cAAc,KAAK,IAAK;AAAA,MAC5B,KAAK,OAAO;AAAA,IACd;AACA,WAAO,EAAE,gBAAgB,YAAY;AAAA,EACvC;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,SAAS;AACd,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAM;AAAA,IAChB;AACA,SAAK,KAAK;AACV,SAAK,UAAU;AACf,SAAK,MAAM;AACX,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACrB;AACF;AACA,SAAS,sBAAsB,MAAc,WAA2B;AACtE,MAAI,aAAa,EAAG,QAAO;AAC3B,MAAI,mBAAmB,IAAI,KAAK,UAAW,QAAO;AAClD,QAAM,aAAa,CAAC,GAAG,IAAI;AAC3B,MAAI,MAAM;AACV,MAAI,OAAO,WAAW;AACtB,SAAO,MAAM,MAAM;AACjB,UAAM,MAAM,KAAK,MAAM,MAAM,QAAQ,CAAC;AACtC,QAAI,mBAAmB,WAAW,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,KAAK,WAAW;AACtE,YAAM;AAAA,IACR,OAAO;AACL,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACA,SAAO,WAAW,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE;AACzC;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|