@nestos/kanban 0.0.0-stage → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +165 -2
- package/dist/activity-BbC4sgKL.d.cts +258 -0
- package/dist/activity-Czlan5xW.d.ts +258 -0
- package/dist/activity-module-DaO1Rry0.d.cts +22 -0
- package/dist/activity-module-T22wliZu.d.ts +22 -0
- package/dist/activity-ports-Dqxa86zT.d.cts +12 -0
- package/dist/activity-ports-cxfrelaL.d.ts +12 -0
- package/dist/activity.cjs +16 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +12 -0
- package/dist/activity.d.ts +12 -0
- package/dist/activity.js +16 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-3JYLJPE5.js +95 -0
- package/dist/chunk-3JYLJPE5.js.map +1 -0
- package/dist/chunk-3LEIHB7Y.js +221 -0
- package/dist/chunk-3LEIHB7Y.js.map +1 -0
- package/dist/chunk-4XF6LQSU.cjs +9 -0
- package/dist/chunk-4XF6LQSU.cjs.map +1 -0
- package/dist/chunk-5Q7WB63A.cjs +282 -0
- package/dist/chunk-5Q7WB63A.cjs.map +1 -0
- package/dist/chunk-7KDOTBRX.cjs +58 -0
- package/dist/chunk-7KDOTBRX.cjs.map +1 -0
- package/dist/chunk-AHHEGTUA.js +148 -0
- package/dist/chunk-AHHEGTUA.js.map +1 -0
- package/dist/chunk-AOHQCX7K.cjs +95 -0
- package/dist/chunk-AOHQCX7K.cjs.map +1 -0
- package/dist/chunk-DINLR6E6.cjs +443 -0
- package/dist/chunk-DINLR6E6.cjs.map +1 -0
- package/dist/chunk-EYTVC2H5.cjs +1612 -0
- package/dist/chunk-EYTVC2H5.cjs.map +1 -0
- package/dist/chunk-FEE2YBZ7.js +1972 -0
- package/dist/chunk-FEE2YBZ7.js.map +1 -0
- package/dist/chunk-FNO5K3A7.js +282 -0
- package/dist/chunk-FNO5K3A7.js.map +1 -0
- package/dist/chunk-IHHDXZPZ.js +382 -0
- package/dist/chunk-IHHDXZPZ.js.map +1 -0
- package/dist/chunk-J3EAIVA3.js +280 -0
- package/dist/chunk-J3EAIVA3.js.map +1 -0
- package/dist/chunk-KH3WF3K4.js +443 -0
- package/dist/chunk-KH3WF3K4.js.map +1 -0
- package/dist/chunk-M35X5PHO.js +196 -0
- package/dist/chunk-M35X5PHO.js.map +1 -0
- package/dist/chunk-QRGZD2JU.cjs +1972 -0
- package/dist/chunk-QRGZD2JU.cjs.map +1 -0
- package/dist/chunk-RBOER6EW.cjs +221 -0
- package/dist/chunk-RBOER6EW.cjs.map +1 -0
- package/dist/chunk-RQP77ZTY.js +9 -0
- package/dist/chunk-RQP77ZTY.js.map +1 -0
- package/dist/chunk-RSH6QSEC.cjs +196 -0
- package/dist/chunk-RSH6QSEC.cjs.map +1 -0
- package/dist/chunk-VMRDXOLX.cjs +148 -0
- package/dist/chunk-VMRDXOLX.cjs.map +1 -0
- package/dist/chunk-X4UHZX6F.js +58 -0
- package/dist/chunk-X4UHZX6F.js.map +1 -0
- package/dist/chunk-XBSGUVCY.cjs +382 -0
- package/dist/chunk-XBSGUVCY.cjs.map +1 -0
- package/dist/chunk-XKDZHAUE.js +1612 -0
- package/dist/chunk-XKDZHAUE.js.map +1 -0
- package/dist/chunk-ZUZGAO6G.cjs +280 -0
- package/dist/chunk-ZUZGAO6G.cjs.map +1 -0
- package/dist/content-C5aJZFlw.d.cts +35 -0
- package/dist/content-hLH5BNud.d.ts +35 -0
- package/dist/contracts/index.cjs +31 -0
- package/dist/contracts/index.cjs.map +1 -0
- package/dist/contracts/index.d.cts +5 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.js +31 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/discovery-9E-LfwIw.d.cts +61 -0
- package/dist/discovery-D60yrjej.d.ts +61 -0
- package/dist/discovery.cjs +377 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +22 -0
- package/dist/discovery.d.ts +22 -0
- package/dist/discovery.js +377 -0
- package/dist/discovery.js.map +1 -0
- package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
- package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
- package/dist/execution.cjs +18 -0
- package/dist/execution.cjs.map +1 -0
- package/dist/execution.d.cts +42 -0
- package/dist/execution.d.ts +42 -0
- package/dist/execution.js +18 -0
- package/dist/execution.js.map +1 -0
- package/dist/index.cjs +74 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/module-CYfE7YhM.d.ts +11 -0
- package/dist/module-Ca9L3qCn.d.cts +11 -0
- package/dist/planning-CHrOqQ6b.d.cts +879 -0
- package/dist/planning-CHrOqQ6b.d.ts +879 -0
- package/dist/ports-B0McVg7B.d.ts +143 -0
- package/dist/ports-BeGO1VRI.d.cts +49 -0
- package/dist/ports-GQy0x-RI.d.cts +143 -0
- package/dist/ports-ykGiNUSx.d.ts +49 -0
- package/dist/runtime/index.cjs +205 -0
- package/dist/runtime/index.cjs.map +1 -0
- package/dist/runtime/index.d.cts +75 -0
- package/dist/runtime/index.d.ts +75 -0
- package/dist/runtime/index.js +205 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/integration.cjs +423 -0
- package/dist/runtime/integration.cjs.map +1 -0
- package/dist/runtime/integration.d.cts +658 -0
- package/dist/runtime/integration.d.ts +658 -0
- package/dist/runtime/integration.js +423 -0
- package/dist/runtime/integration.js.map +1 -0
- package/dist/storage.cjs +21 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +71 -0
- package/dist/storage.d.ts +71 -0
- package/dist/storage.js +21 -0
- package/dist/storage.js.map +1 -0
- package/dist/store-DPwHzGiz.d.cts +28 -0
- package/dist/store-DgdrPCV9.d.ts +28 -0
- package/dist/task-projection-CSorlMws.d.ts +11 -0
- package/dist/task-projection-DKKB_ueb.d.cts +11 -0
- package/examples/standalone.ts +22 -0
- package/package.json +143 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-5Q7WB63A.cjs","../src/session-activity-query.ts","../src/session-relations.ts","../src/session-activity.ts","../src/activity-module.ts"],"names":["page","board","item"],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACVA,MAAA,SAAsB,iBAAA,CAAkB,IAAA,EAAqB,OAAA,EAAiB,KAAA,EAC1E,OAAA,EAAkH;AAClH,EAAA,MAAM,EAAC,UAAA,EAAU,KAAA,EAAM,GAAG,MAAK,EAAA,EAAE,KAAA;AACjC,EAAA,GAAA,CAAG,CAAC,CAAC,KAAA,EAAM,SAAA,EAAU,QAAA,EAAS,QAAQ,CAAA,CAAE,QAAA,CAAS,SAAS,CAAA,EAAG,MAAM,IAAI,kCAAA,CAAY,0BAA0B,CAAA;AAC7G,EAAA,GAAA,CAAG,UAAA,IAAY,KAAA,EAAO;AAAC,IAAA,MAAMA,MAAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,KAAK,CAAA;AAAE,IAAA,OAAO,EAAC,GAAGA,KAAAA,EAAK,KAAA,EAAM,MAAM,OAAA,CAAQA,KAAAA,CAAK,KAAK,EAAC,CAAA;AAAA,EAAE;AACnH,EAAA,MAAM,EAAC,MAAA,EAAO,MAAA,EAAM,EAAA,EAAG,GAAG,QAAO,EAAA,EAAE,KAAA;AACnC,EAAA,GAAA,CAAG,CAAC,MAAA,CAAO,aAAA,CAAc,KAAK,EAAA,GAAG,MAAA,EAAM,EAAA,GAAG,MAAA,EAAM,GAAA,EAAK,MAAM,IAAI,kCAAA,CAAY,mBAAmB,CAAA;AAC9F,EAAA,IAAI,KAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,EAAC,GAAG,OAAA,EAAQ,KAAA,EAAM,IAAG,CAAC,CAAA,EAAG,KAAA,EAAK,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA;AAAE,EAAA,MAAM,SAAA,EAAS,IAAA,CAAK,QAAA;AACpG,EAAA,MAAA,CAAM,IAAA,CAAK,UAAA,EAAY;AACnB,IAAA,GAAA,CAAG,IAAA,CAAK,OAAA,GAAQ,GAAA,EAAO,MAAM,IAAI,kCAAA,CAAY,sBAAsB,CAAA;AACnE,IAAA,KAAA,EAAK,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,EAAC,GAAG,OAAA,EAAQ,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,IAAA,CAAK,WAAU,CAAC,CAAA;AAC3E,IAAA,GAAA,CAAG,IAAA,CAAK,SAAA,IAAW,QAAA,EAAU,MAAM,IAAI,kCAAA,CAAY,cAAc,CAAA;AAAE,IAAA,IAAA,CAAK,IAAA,CAAK,GAAG,IAAA,CAAK,KAAK,CAAA;AAAA,EAC9F;AACA,EAAA,MAAM,SAAA,EAAA,CAAU,MAAM,OAAA,CAAQ,IAAI,CAAA,CAAA,CAAG,MAAA,CAAO,CAAA,GAAA,EAAA,GAAK,gBAAA,CAAiB,GAAA,EAAI,SAAS,CAAC,CAAA;AAChF,EAAA,GAAA,CAAA,CAAI,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,EAAC,GAAG,OAAA,EAAQ,KAAA,EAAM,EAAC,CAAC,CAAA,CAAA,CAAG,SAAA,IAAW,QAAA,EAAU,MAAM,IAAI,kCAAA,CAAY,cAAc,CAAA;AAC7G,EAAA,MAAM,MAAA,EAAM,6CAAA,IAAc,CAAK,SAAA,CAAU,EAAC,OAAA,EAAQ,SAAA,EAAU,MAAK,CAAC,CAAC,CAAA,EAAG,UAAA,EAAU,6CAAA,IAAc,CAAK,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,EAAE,CAAC,CAAC,CAAA;AACvI,EAAA,IAAI,MAAA,EAAM,CAAA;AACV,EAAA,GAAA,CAAG,MAAA,EAAQ;AACP,IAAA,IAAI,KAAA;AAAM,IAAA,IAAI;AAAC,MAAA,MAAA,EAAM,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAAA,IAAE,EAAA,UAAQ;AAAC,MAAA,MAAM,IAAI,kCAAA,CAAY,gBAAgB,CAAA;AAAA,IAAE;AACzF,IAAA,GAAA,CAAG,KAAA,CAAM,MAAA,IAAQ,KAAA,EAAO,MAAM,IAAI,kCAAA,CAAY,uBAAuB,CAAA;AACrE,IAAA,GAAA,CAAG,KAAA,CAAM,SAAA,IAAW,SAAA,GAAU,KAAA,CAAM,UAAA,IAAY,SAAA,EAAW,MAAM,IAAI,kCAAA,CAAY,cAAc,CAAA;AAC/F,IAAA,MAAA,EAAM,QAAA,CAAS,SAAA,CAAU,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,GAAA,IAAK,KAAA,CAAM,KAAK,EAAA,EAAE,CAAA;AAAE,IAAA,GAAA,CAAG,MAAA,EAAM,CAAA,EAAG,MAAM,IAAI,kCAAA,CAAY,gBAAgB,CAAA;AAAA,EAC5G;AACA,EAAA,MAAM,MAAA,EAAM,QAAA,CAAS,KAAA,CAAM,KAAA,EAAM,MAAA,EAAM,KAAK,CAAA;AAC5C,EAAA,OAAO,EAAC,QAAA,EAAS,KAAA,EAAM,QAAA,CAAS,MAAA,EAAO,KAAA,EAAM,GAAI,MAAA,EAAM,KAAA,CAAM,OAAA,EAAO,QAAA,CAAS,OAAA,EAAO,EAAC,UAAA,EAAW,IAAA,CAAK,SAAA,CAAU,EAAC,KAAA,EAAM,QAAA,EAAS,SAAA,EAAU,KAAA,EAAM,KAAA,CAAM,EAAA,CAAG,CAAA,CAAE,CAAA,CAAG,GAAE,CAAC,EAAC,EAAA,EAAG,CAAC,EAAE,CAAA;AAC3K;AACA,SAAS,gBAAA,CAAiB,GAAA,EAA+B,MAAA,EAAyB;AAC9E,EAAA,MAAM,QAAA,EAAQ,GAAA,CAAI,SAAA;AAAU,EAAA,GAAA,CAAG,CAAC,QAAA,GAAS,OAAA,CAAQ,KAAA,EAAO,OAAO,KAAA;AAC/D,EAAA,OAAO,OAAA,IAAS,UAAA,EAAU,OAAA,CAAQ,MAAA,IAAQ,UAAA,EAAU,OAAA,IAAS,SAAA,EAAS,OAAA,CAAQ,OAAA,EAAO,OAAA,CAAQ,MAAA,IAAQ,UAAA,GAAW,OAAA,CAAQ,MAAA;AAC5H;ADuBA;AACA;AEvDO,SAAS,mBAAA,CAAoB,IAAA,EAAkB,QAAA,EAAqC,QAAA,EAA2D;AAClJ,EAAA,OAAO,CAAC,GAAG,QAAA,CAAS,GAAA,CAAI,CAAA,GAAA,EAAA,GAAO;AAC3B,IAAA,MAAM,SAAA,EAAW,QAAA,CAAS,UAAA,kBAAW,GAAA,CAAI,QAAA,UAAY,IAAE,CAAA;AACvD,IAAA,MAAM,UAAA,kBAAgD,QAAA,2BAAU,SAAA,IAAW,IAAA,CAAK,GAAA,EAAK;AAAA,MACjF,EAAA,EAAI,QAAA,CAAS,EAAA;AAAA,MAAI,OAAA,EAAS,WAAA;AAAA,MAAa,UAAA,EAAY,QAAA,CAAS,EAAA;AAAA,MAAI,OAAA,EAAS,QAAA,CAAS,OAAA;AAAA,MAClF,OAAA,EAAS,QAAA,CAAS,OAAA;AAAA,MAAS,SAAA,EAAW,QAAA,CAAS,UAAA;AAAA,MAAY,IAAA,EAAM,QAAA,CAAS,IAAA;AAAA,MAC1E,GAAI,QAAA,CAAS,aAAA,EAAe,EAAC,kBAAA,EAAoB,QAAA,CAAS,YAAA,CAAa,mBAAkB,EAAA,EAAI,CAAC;AAAA,IAClG,EAAA,EAAI,KAAA,CAAA;AACJ,IAAA,OAAO,EAAC,SAAA,EAAW,GAAA,CAAI,EAAA,EAAI,OAAA,EAAS,WAAA,EAAsB,GAAI,UAAA,EAAY,EAAC,UAAS,EAAA,EAAI,CAAC,EAAE,CAAA;AAAA,EAC/F,CAAC,CAAA,EAAG,GAAG,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,CAAA,GAAA,EAAA,GAAO,CAAC,QAAA,CAAS,IAAA,CAAK,CAAA,GAAA,EAAA,GAAO,GAAA,CAAI,GAAA,IAAO,GAAA,CAAI,SAAS,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,GAAA,EAAA,GAAA,CAAQ,EAAC,SAAA,EAAW,GAAA,CAAI,SAAA,EAAW,OAAA,EAAS,aAAqB,CAAA,CAAE,CAAC,CAAA;AACpK;AAGA,MAAA,SAAsB,sBAAA,CAAuB,YAAA,EAA0C,SAAA,EACnF,OAAA,EAA2F;AAC3F,EAAA,MAAM,QAAA,kBAAU,IAAI,GAAA,CAAmH,CAAA;AACvI,EAAA,IAAA,CAAA,MAAW,IAAA,GAAO,YAAA,EAAc;AAC5B,IAAA,IAAI,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,SAAS,CAAA;AACrC,IAAA,GAAA,CAAI,CAAC,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,SAAA,EAAW,MAAA,EAAQ,EAAC,QAAA,kBAAU,IAAI,GAAA,CAAI,CAAA,EAAG,UAAA,kBAAY,IAAI,GAAA,CAAI,EAAC,CAAC,CAAA;AAC3F,IAAA,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,OAAO,CAAA;AAC9B,IAAA,GAAA,CAAI,GAAA,CAAI,SAAA,EAAW,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,EAAA,EAAI,EAAC,GAAG,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,EAAE,CAAA,EAAG,GAAG,GAAA,CAAI,UAAS,CAAC,CAAA;AAAA,EAC3H;AACA,EAAA,MAAM,KAAA,EAA+B,CAAC,CAAA,EAAG,QAAA,EAAU,CAAC,GAAG,OAAO,CAAA;AAAG,EAAA,IAAI,KAAA,EAAO,CAAA;AAC5E,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,EAAC,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,MAAA,EAAQ,CAAC,EAAC,CAAA,EAAG,MAAA,CAAA,EAAA,GAAY;AAC5E,IAAA,MAAA,CAAO,KAAA,EAAO,OAAA,CAAQ,MAAA,EAAQ;AAC1B,MAAA,MAAM,CAAC,SAAA,EAAW,KAAK,EAAA,EAAI,OAAA,CAAQ,IAAA,EAAM,CAAA,EAAG,MAAA,EAAQ,MAAM,OAAA,CAAQ,SAAS,CAAA;AAC3E,MAAA,IAAA,CAAK,IAAA,CAAK;AAAA,QAAC,GAAG,KAAA;AAAA,QAAO,OAAA,EAAS,UAAA,IAAc,SAAA;AAAA,QAAW,QAAA,EAAU,CAAC,GAAG,KAAA,CAAM,QAAQ,CAAA,CAAE,IAAA,CAAK,CAAA;AAAA,QACtF,UAAA,EAAY,CAAC,GAAG,KAAA,CAAM,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,EAAA,GAAA,kBAAO,CAAA,CAAE,SAAA,UAAa,GAAA,EAAA,EAAA,kBAAM,CAAA,CAAE,SAAA,UAAa,GAAA,EAAA,GAAM,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC;AAAA,MAAC,CAAC,CAAA;AAAA,IACvI;AAAA,EACJ,CAAC,CAAC,CAAA;AACF,EAAA,OAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM,MAAA,CAAO,CAAA,CAAE,OAAO,EAAA,EAAI,MAAA,CAAO,CAAA,CAAE,OAAO,EAAA,GAAK,CAAA,CAAE,SAAA,CAAU,aAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9G;AFgEA;AACA;AG1FO,SAAS,iBAAA,CAAkB,IAAA,EAA6C,eAAA,EAAyB;AAAC,EAAA,OAAA,kBAAQ,IAAA,UAAQ,CAAC,GAAA,CAAA,CAAG,MAAA,CAAO,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,OAAA,IAAS,eAAe,CAAA;AAAE;AACvK,SAAS,cAAA,CAAe,IAAA,EAA2C,MAAA,EAAe,QAAA,EAA8B,eAAA,EAAyB;AACrI,EAAA,MAAM,QAAA,EAAQ,iBAAA,CAAkB,IAAA,EAAM,eAAe,CAAA,CAAE,EAAA,CAAG,CAAA,CAAE,CAAA,EAAE,OAAA,EAAO,MAAA,CAAO,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,MAAA,CAAO,CAAA,QAAA,EAAA,GAAU,QAAA,CAAS,OAAA,IAAS,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAE,CAAA,EAAA,GAAI,CAAA,CAAE,QAAA,EAAQ,CAAA,CAAE,OAAO,CAAA,CAAE,CAAC,CAAA;AACrL,EAAA,GAAA,CAAG,CAAC,QAAA,GAAS,CAAC,OAAA,GAAQ,OAAA,CAAQ,SAAA,IAAW,MAAA,CAAO,EAAA,EAAI,OAAO,OAAA;AAC3D,EAAA,OAAO,CAAC,UAAA,EAAW,SAAA,EAAU,SAAA,EAAU,WAAW,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,OAAO,EAAA,GAAG,QAAA,CAAS,UAAA,kBAAW,OAAA,CAAQ,QAAA,UAAY,IAAE,EAAA,EAAE,KAAA,EAAA,EAAU,OAAA;AACxI;AAGO,SAAS,2BAAA,CAA4B,IAAA,EAAqB,OAAA,EAAmD,GAAA,EAAwH,eAAA,EAAyB;AACjQ,EAAA,MAAM,QAAA,EAAQ,sBAAA,CAAuB,OAAA,EAAQ,GAAG,CAAA;AAChD,EAAA,MAAM,QAAA,EAAQ,MAAA,CAAM,OAAA,EAAe,IAAA,EAAA,GAAkC;AACjE,IAAA,GAAA,CAAG,CAAC,IAAA,CAAK,IAAA,CAAK,CAAA,GAAA,EAAA,GAAK,iBAAA,CAAkB,GAAA,CAAI,YAAA,EAAa,eAAe,CAAA,CAAE,MAAM,CAAA,EAAE,OAAO,IAAA;AACtF,IAAA,MAAM,CAAC,KAAA,EAAM,QAAQ,EAAA,EAAE,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,aAAA,CAAc,IAAA,EAAK,OAAO,CAAA,EAAE,IAAA,CAAK,QAAA,CAAS,OAAO,CAAC,CAAC,CAAA,EAAG,SAAA,EAAS,IAAI,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,EAAA,GAAK,CAAC,GAAA,CAAI,EAAA,EAAG,cAAA,CAAe,GAAA,CAAI,YAAA,EAAa,GAAA,CAAI,EAAA,EAAG,QAAA,EAAS,eAAe,CAAC,CAAC,CAAC,CAAA;AACzM,IAAA,MAAM,IAAA,EAAI,CAAC,GAAG,IAAI,GAAA,CAAI,CAAC,GAAG,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAA,GAAA,EAAA,GAAK,IAAA,EAAI,CAAC,GAAA,CAAI,EAAE,EAAA,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA,EAAG,OAAA,kBAAO,IAAI,GAAA,CAAmC,CAAA;AAAE,IAAA,IAAI,KAAA,EAAK,CAAA;AACvI,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,EAAC,MAAA,EAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,MAAA,EAAO,CAAC,EAAC,CAAA,EAAE,MAAA,CAAA,EAAA,GAAS;AAAC,MAAA,MAAA,CAAM,KAAA,EAAK,GAAA,CAAI,MAAA,EAAQ;AAAC,QAAA,MAAM,GAAA,EAAG,GAAA,CAAI,IAAA,EAAM,CAAA;AAAE,QAAA,MAAA,CAAO,GAAA,CAAI,EAAA,EAAG,MAAM,OAAA,CAAQ,KAAA,EAAM,EAAE,CAAC,CAAA;AAAA,MAAE;AAAA,IAAC,CAAC,CAAC,CAAA;AAC9J,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,EAAA,GAAK;AAAC,MAAA,MAAM,QAAA,EAAQ,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAE,MAAA,OAAO,EAAC,GAAG,GAAA,EAAI,GAAI,QAAA,EAAQ,EAAC,SAAA,EAAU,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,EAAC,EAAA,EAAG,CAAC,EAAE,CAAA;AAAA,IAAE,CAAC,CAAA;AAAA,EAClI,CAAA;AACA,EAAA,OAAO;AAAA,IACH,aAAA,EAAc,CAAC,OAAA,EAAe,MAAA,EAAuD,CAAC,CAAA,EAAA,GAAI,iBAAA,CAAkB,IAAA,EAAK,OAAA,EAAQ,KAAA,EAAM,CAAA,IAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IAC1J,MAAM,gBAAA,CAAiB,OAAA,EAAe,MAAA,EAAe,MAAA,EAAwD,CAAC,CAAA,EAAG;AAC7G,MAAA,MAAM,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,CAAA;AACzB,MAAA,GAAA,CAAI,CAAC,MAAA,GAAS,OAAO,MAAA,IAAU,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,KAAK,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,IAAA,CAAK,CAAA,GAAA,EAAA,GAAO,IAAA,IAAQ,gBAAgB,EAAA,GAAK,KAAA,CAAM,eAAA,IAAmB,KAAA,EAAA,GAAa,OAAO,KAAA,CAAM,eAAA,IAAmB,SAAA,EAAW,MAAM,IAAI,kCAAA,CAAY,eAAe,CAAA;AACrP,MAAA,MAAM,EAAC,KAAI,EAAA,EAAE,MAAM,IAAA,CAAK,IAAA,CAAK,OAAA,EAAQ,MAAM,CAAA,EAAE,SAAA,EAAS,iBAAA,CAAkB,IAAA,CAAK,YAAA,EAAa,eAAe,CAAA;AACzG,MAAA,GAAA,CAAG,CAAC,QAAA,CAAS,OAAA,GAAU,CAAC,KAAA,CAAM,cAAA,EAAe,OAAO,EAAC,OAAA,EAAQ,CAAC,EAAC,CAAA;AAC/D,MAAA,MAAM,CAAC,KAAA,EAAM,QAAQ,EAAA,EAAE,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,aAAA,CAAc,IAAA,EAAK,OAAO,CAAA,EAAE,IAAA,CAAK,QAAA,CAAS,OAAO,CAAC,CAAC,CAAA,EAAE,KAAA,EAAK,cAAA,CAAe,IAAA,CAAK,YAAA,EAAa,MAAA,EAAO,QAAA,EAAS,eAAe,CAAA;AACpK,MAAA,IAAI,YAAA;AACJ,MAAA,MAAM,QAAA,EAAU,KAAA,CAAM,eAAA,EAAiB,sBAAM,OAAA,6BAAS,MAAA,qBAAO,OAAA,0BAAA,CAAU,KAAA,EAAO,IAAA,EAAM,QAAQ,CAAA,qBAAE,KAAA,mBAAM,CAAA,KAAA,EAAA,GAAS;AACzG,QAAA,MAAM,UAAA,kBAAa,KAAA,6BAA2B,MAAA;AAC9C,QAAA,aAAA,EAAe,UAAA,GAAa,wBAAA,CAAyB,IAAA,CAAK,SAAS,EAAA,EAAI,UAAA,EAAY,0BAAA;AACnF,QAAA,IAAI;AAAC,UAAA,GAAA,CAAI,EAAC,WAAA,EAAa,0CAAA,CAAW,EAAG,KAAA,EAAO,mBAAA,EAAqB,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,YAAA,EAAc,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,QAAO,CAAC,CAAA;AAAA,QAAE,EAAA,WAAQ;AAAA,QAAoD;AACvM,QAAA,OAAO,CAAC,CAAA;AAAA,MACZ,CAAC,IAAA,EAAI,CAAC,CAAA;AACN,MAAA,MAAM,SAAA,EAAW,KAAA,CAAM,eAAA,EAAiB,MAAM,sBAAA,CAAuB;AAAA,QACjE,GAAG,mBAAA,CAAoB,IAAA,EAAM,QAAA,EAAU,QAAQ,CAAA;AAAA,QAAG,oBAAG,OAAA,UAAW,CAAC;AAAA,MACrE,CAAA,kBAAG,IAAA,6BAAM,IAAA,EAAI,CAAA,EAAA,EAAA,GAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,EAAA,EAAI,KAAA,CAAA;AACzC,MAAA,OAAO;AAAA,QAAC,OAAA,EAAQ,KAAA,yDAAM,QAAA,mCAAU,IAAA,2BAAK,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,UAAA,IAAY,IAAA,CAAK,EAAE,GAAA,gBAAK,MAAM,OAAA,CAAQ,KAAA,EAAM,IAAA,CAAK,EAAE,IAAA,EAAG,KAAA,CAAA;AAAA,QAChG,OAAA,EAAQ,QAAA,CAAS,GAAA,CAAI,CAAA,GAAA,EAAA,GAAA,CAAM,EAAC,SAAA,EAAU,GAAA,CAAI,EAAA,EAAG,SAAA,EAAU,GAAA,CAAI,QAAA,EAAS,OAAA,EAAQ,IAAA,IAAM,KAAI,CAAA,CAAE,CAAA,CAAE,OAAA,CAAQ,CAAA;AAAA,QAAG,GAAI,SAAA,EAAW,EAAC,SAAQ,EAAA,EAAI,CAAC,CAAA;AAAA,QAAI,GAAI,aAAA,EAAe,EAAC,aAAY,EAAA,EAAI,CAAC;AAAA,MAAE,CAAA;AAAA,IACrL,CAAA;AAAA,IACA,QAAA,EAAS,CAAC,KAAA,EAAkB,OAAA,EAAgC,KAAA,EAAA,GAAoB,eAAA,CAAgB,IAAA,EAAK,OAAA,EAAQ,KAAA,EAAM,OAAA,EAAQ,KAAA,EAAM,eAAe;AAAA,EACpJ,CAAA;AACJ;AACA,SAAS,sBAAA,CAAuB,OAAA,EAA+C,GAAA,EAAuD;AAClI,EAAA,MAAM,IAAA,mCAAI,OAAA,+BAAS,KAAA,UAAO,IAAA,CAAK,KAAA,EAAK,MAAA,kBAAM,IAAI,GAAA,CAAmC,CAAA;AACjF,EAAA,OAAO,MAAA,CAAM,KAAA,EAAkB,SAAA,EAAA,GAAmD;AAC9E,IAAA,MAAM,QAAA,EAAQ,GAAA,CAAI,CAAA,EAAE,IAAA,EAAI,IAAA,CAAK,SAAA,CAAU,CAAC,KAAA,CAAM,EAAA,EAAG,SAAS,CAAC,CAAA;AAC3D,IAAA,IAAI;AACA,MAAA,GAAA,CAAG,CAAC,OAAA,EAAS,MAAM,IAAI,kCAAA,CAAY,+BAA+B,CAAA;AAClE,MAAA,MAAM,IAAA,EAAI,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAM,SAAS,CAAA;AACtD,MAAA,GAAA,CAAG,GAAA,CAAI,UAAA,IAAY,SAAA,EAAW,MAAM,IAAI,kCAAA,CAAY,iCAAiC,CAAA;AACrF,MAAA,MAAM,MAAA,EAAM,GAAA,CAAI,MAAA,GAAO,GAAA,CAAI,WAAA,IAAa,KAAA,EAAA,GAAW,GAAA,CAAI,EAAA,EAAE,GAAA,CAAI,WAAA,EAAW,GAAA;AACxE,MAAA,MAAM,MAAA,EAA6B;AAAA,QAAC,SAAA;AAAA,QAAU,GAAI,OAAO,GAAA,CAAI,WAAA,IAAa,SAAA,GAAU,GAAA,CAAI,UAAA,CAAW,OAAA,GAAQ,KAAA,GAAM,CAAC,GAAA,CAAI,UAAA,CAAW,QAAA,CAAS,IAAI,EAAA,EAAE,EAAC,UAAA,EAAW,GAAA,CAAI,WAAU,EAAA,EAAE,CAAC,CAAA;AAAA,QAAG,KAAA,kBAAM,GAAA,uBAAI,KAAA,+BAAO,KAAA,qBAAM,CAAA,EAAE,GAAG,GAAA;AAAA,QAAE,KAAA,EAAM,GAAA,CAAI,KAAA;AAAA,QAAM,SAAA,EAAU,GAAA,CAAI,SAAA;AAAA,QAAU,cAAA,EAAe,GAAA,CAAI,cAAA;AAAA,QAAe,UAAA,EAAW,GAAA,CAAI,UAAA;AAAA,QAAW,KAAA;AAAA,QAC9S,MAAA,EAAO,CAAC,MAAA,GAAO,GAAA,CAAI,eAAA,IAAiB,KAAA,EAAA,GAAW,GAAA,CAAI,eAAA,GAAgB,GAAA,CAAI,EAAA,GAAG,GAAA,CAAI,EAAA,EAAE,GAAA,CAAI,eAAA,GAAgB,GAAA;AAAA,QAAO,GAAI,GAAA,CAAI,KAAA,GAAM,wBAAA,CAAyB,IAAA,CAAK,GAAA,CAAI,IAAI,EAAA,EAAE,EAAC,IAAA,EAAK,GAAA,CAAI,KAAI,EAAA,EAAE,CAAC;AAAA,MAAE,CAAA;AACxL,MAAA,GAAA,CAAG,KAAA,CAAM,KAAA,GAAM,GAAA,EAAK,KAAA,CAAM,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,KAAM,CAAA;AAAE,MAAA,KAAA,CAAM,GAAA,CAAI,GAAA,EAAI,KAAK,CAAA;AAAE,MAAA,OAAO,KAAA;AAAA,IAC7F,EAAA,MAAA,CAAQ,KAAA,EAAO;AACX,MAAA,MAAM,UAAA,kBAAW,KAAA,+BAA0B,MAAA,EAAK,KAAA,EAAK,UAAA,GAAW,wBAAA,CAAyB,IAAA,CAAK,SAAS,EAAA,EAAE,UAAA,EAAU,yBAAA;AACnH,MAAA,IAAI;AAAC,QAAA,GAAA,CAAI,EAAC,WAAA,EAAY,0CAAA,CAAW,EAAE,SAAA,EAAU,KAAA,EAAM,kBAAA,EAAmB,MAAA,EAAO,SAAA,EAAU,IAAA,EAAK,UAAA,EAAW,GAAA,CAAI,EAAA,EAAE,QAAO,CAAC,CAAA;AAAA,MAAE,EAAA,WAAQ;AAAA,MAA2D;AAC1L,MAAA,MAAM,MAAA,EAAM,CAAC,KAAA,EAAM,WAAA,EAAY,YAAA,EAAa,cAAA,EAAe,yBAAyB,CAAA,CAAE,QAAA,CAAS,IAAI,EAAA,EAAE,KAAA,CAAM,GAAA,CAAI,GAAG,EAAA,EAAE,KAAA,CAAA;AACpH,MAAA,OAAO,EAAC,GAAG,KAAA,EAAM,SAAA,EAAU,KAAA,mCAAM,KAAA,+BAAO,OAAA,UAAS,WAAA,EAAU,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,KAAA,EAAM,KAAI,CAAA;AAAA,IAC3F;AAAA,EACJ,CAAA;AACJ;AACA,MAAA,SAAe,aAAA,CAAc,IAAA,EAAqB,OAAA,EAAuC;AACrF,EAAA,MAAM,MAAA,8BAAA,CAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,CAAA,CAAA,CAAG,IAAA,CAAK,CAAAC,MAAAA,EAAAA,GAAOA,MAAAA,CAAM,GAAA,IAAK,OAAO,CAAA,gBAAK,MAAM,IAAA,CAAK,IAAA,CAAK,OAAO,GAAA;AAC7F,EAAA,OAAO,EAAC,GAAG,KAAA,EAAM,KAAA,EAAM,CAAC,EAAC,CAAA;AAC7B;AACA,MAAA,SAAe,eAAA,CAAgB,IAAA,EAAqB,OAAA,EAAgD,KAAA,EAAmB,OAAA,EAAiC,KAAA,EAAmB,eAAA,EAAwC;AAC/M,EAAA,GAAA,iBAAG,OAAA,+BAAS,OAAA,IAAO,iBAAA,GAAkB,OAAA,CAAQ,SAAA,CAAU,OAAA,IAAS,eAAA,EAAiB,MAAA;AACjF,EAAA,GAAA,CAAG,CAAC,QAAA,GAAS,CAAC,OAAA,CAAQ,SAAA,CAAU,QAAA,EAAU,MAAM,IAAI,kCAAA,CAAY,+BAA+B,CAAA;AAC/F,EAAA,MAAM,KAAA,EAAK,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,CAAAC,KAAAA,EAAAA,GAAMA,KAAAA,CAAK,GAAA,IAAK,OAAA,CAAQ,MAAM,CAAA;AAAE,EAAA,GAAA,CAAG,CAAC,IAAA,EAAM,MAAM,IAAI,kCAAA,CAAY,gBAAgB,CAAA;AAC5G,EAAA,MAAM,IAAA,EAAI,4CAAA,yCAAa,KAAe,CAAC,CAAA,EAAG,YAAA,kBAAY,KAAA,uBAAM,OAAA,+BAAS,IAAA,qBAAK,CAAA,MAAA,EAAA,GAAQ,4CAAA,MAAmB,EAAA,IAAI,IAAA,mBAAK,MAAA,uBAAO,KAAA,+BAAO,QAAA,qBAAS,aAAa,GAAC,GAAA;AACnJ,EAAA,GAAA,CAAG,CAAC,YAAA,mBAAa,IAAA,uBAAK,KAAA,+BAAO,cAAA,IAAc,IAAA,GAAK,CAAA,CAAE,IAAA,CAAK,MAAA,IAAQ,KAAA,EAAA,GAAW,0CAAA,KAAW,EAAM,IAAI,CAAA,CAAE,IAAA,CAAK,CAAA,SAAA,EAAA,GAAW,4CAAA,SAAsB,EAAA,IAAI,GAAG,CAAA,CAAA,EAAI,MAAM,IAAI,kCAAA,CAAY,qCAAqC,CAAA;AAC7M,EAAA,MAAM,OAAA,EAAO,MAAA,CAAO,MAAA,CAAA,CAAQ,MAAM,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,EAAE,CAAA,CAAA,CAAG,UAAU,CAAA,CAAE,MAAA,CAAO,CAAA,QAAA,EAAA,GAAU,QAAA,CAAS,OAAA,IAAS,IAAA,CAAK,EAAE,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAE,CAAA,EAAA,GAAI,CAAA,CAAE,QAAA,EAAQ,CAAA,CAAE,OAAO,CAAA,CAAE,CAAC,CAAA;AACrJ,EAAA,GAAA,CAAG,OAAA,GAAQ,OAAA,CAAQ,SAAA,CAAU,SAAA,IAAW,MAAA,CAAO,EAAA,EAAI,MAAM,IAAI,kCAAA,CAAY,0BAA0B,CAAA;AACnG,EAAA,GAAA,CAAG,OAAA,GAAQ,iBAAA,CAAkB,IAAA,CAAK,YAAA,EAAa,eAAe,CAAA,CAAE,IAAA,CAAK,CAAA,GAAA,EAAA,GAAK,GAAA,CAAI,SAAA,IAAW,MAAA,CAAO,GAAA,GAAI,GAAA,CAAI,GAAA,IAAK,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA,EAAG,MAAM,IAAI,kCAAA,CAAY,0BAA0B,CAAA;AACpL,EAAA,GAAA,CAAG,OAAA,CAAQ,MAAA,CAAO,gBAAA,EAAkB,OAAO,OAAA,CAAQ,MAAA,CAAO,gBAAA,CAAiB,KAAA,EAAM,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA;AACrG,EAAA,MAAM,MAAA,EAAM,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAM,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA;AACnE,EAAA,GAAA,CAAG,KAAA,CAAM,UAAA,IAAY,OAAA,CAAQ,SAAA,CAAU,GAAA,GAAI,KAAA,CAAM,KAAA,EAAO,MAAM,IAAI,kCAAA,CAAY,+BAA+B,CAAA;AACjH;AH6HA;AACA;AIpMO,SAAS,0BAAA,CAA2B,OAAA,EAA4D;AACnG,EAAA,MAAM,EAAC,iBAAA,EAAmB,eAAA,EAAiB,GAAG,KAAI,EAAA,EAAI,OAAA;AACtD,EAAA,IAAI,QAAA;AACJ,EAAA,MAAM,QAAA,EAAQ,kDAAA;AAAW,IAAC,GAAG,IAAA;AAAA,IACzB,SAAA,EAAU,MAAA,CAAM,KAAA,EAAA,GAAO;AAAC,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAE,MAAA,MAAM,QAAA,CAAS,QAAA,CAAS,KAAA,CAAM,KAAA,EAAM,KAAA,CAAM,OAAA,EAAQ,KAAA,CAAM,KAAK,CAAA;AAAA,IAAE;AAAA,EACvH,CAAC,CAAA;AACD,EAAA,SAAA,EAAS,2BAAA,CAA4B,OAAA,EAAQ,iBAAA,EAAkB,IAAA,CAAK,GAAA,EAAI,eAAe,CAAA;AACvF,EAAA,IAAI,SAAA,EAAW,KAAA;AACf,EAAA,MAAM,QAAA,kBAAU,IAAI,GAAA,CAAsB,CAAA;AAC1C,EAAA,MAAM,MAAA,EAAQ,CAAI,GAAA,EAAA,GAAsC;AACpD,IAAA,GAAA,CAAI,QAAA,EAAU,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,kCAAA,CAAY,kBAAkB,CAAC,CAAA;AACvE,IAAA,MAAM,KAAA,EAAO,OAAA,CAAQ,OAAA,CAAQ,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAA,EAAA,GAAM;AAAC,MAAA,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA;AAAA,IAAE,CAAC,CAAA;AAC9E,IAAA,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAAG,IAAA,OAAO,IAAA;AAAA,EAC9B,CAAA;AACA,EAAA,MAAM,QAAA,EAAU,MAAA,CAAA,EAAA,GAAY;AACxB,IAAA,SAAA,EAAW,IAAA;AACX,IAAA,MAAM,OAAA,CAAQ,UAAA,CAAW,CAAC,GAAG,OAAO,CAAC,CAAA;AACrC,IAAA,MAAM,OAAA,CAAQ,OAAA,CAAQ,CAAA;AAAA,EAC1B,CAAA;AACA,EAAA,OAAO;AAAA,IACH,GAAG,WAAA,CAAY,OAAA,EAAS,KAAK,CAAA;AAAA,IAC7B,aAAA,EAAe,CAAA,GAAI,IAAA,EAAA,GAAS,KAAA,CAAM,CAAA,EAAA,GAAM,QAAA,CAAS,aAAA,CAAc,GAAG,IAAI,CAAC,CAAA;AAAA,IACvE,gBAAA,EAAkB,CAAA,GAAI,IAAA,EAAA,GAAS,KAAA,CAAM,CAAA,EAAA,GAAM,QAAA,CAAS,gBAAA,CAAiB,GAAG,IAAI,CAAC,CAAA;AAAA,IAC7E,OAAA,EAAS,CAAA,SAAA,EAAA,GAAa,KAAA,CAAM,CAAA,EAAA,GAAM,aAAA,CAAc,OAAA,EAAS,eAAA,EAAiB,SAAS,CAAC,CAAA;AAAA,IACpF,OAAA;AAAA,IAAS,OAAA,EAAS;AAAA,EACtB,CAAA;AACJ;AAEA,SAAS,WAAA,CAAY,OAAA,EAAqB,KAAA,EAAsG;AAC5I,EAAA,OAAO;AAAA,IACH,MAAA,EAAQ,CAAC,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IACpD,IAAA,EAAM,CAAC,EAAA,EAAA,GAAO,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,IAC1C,IAAA,EAAM,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC,OAAA,EAAS,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC5C,OAAA,EAAS,CAAC,EAAA,EAAI,OAAA,EAAA,GAAY,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,OAAO,CAAC,CAAA;AAAA,IAClE,MAAA,EAAQ,CAAC,EAAA,EAAI,KAAA,EAAO,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,EAAA,EAAI,KAAA,EAAO,KAAK,CAAC,CAAA;AAAA,IAC1E,KAAA,EAAO,CAAC,EAAA,EAAI,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,KAAA,CAAM,EAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAC1D,IAAA,EAAM,CAAC,EAAA,EAAI,IAAA,EAAA,GAAS,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,IACtD,QAAA,EAAU,CAAC,EAAA,EAAA,GAAO,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IAClD,IAAA,EAAM,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC,QAAA,EAAU,CAAC,EAAA,EAAA,GAAO,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IAClD,OAAA,EAAS,CAAC,SAAA,EAAA,GAAc,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAC,CAAA;AAAA,IAC9D,OAAA,EAAS,CAAC,EAAA,EAAI,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAC9D,OAAA,EAAS,CAAC,EAAA,EAAI,KAAA,EAAA,GAAU,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,EAAA,EAAI,KAAK,CAAC,CAAA;AAAA,IAC9D,MAAA,EAAQ,CAAC,EAAA,EAAI,MAAA,EAAA,GAAW,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,EAAA,EAAI,MAAM,CAAC,CAAA;AAAA,IAC9D,gBAAA,EAAkB,CAAA,EAAA,GAAM,KAAA,CAAM,CAAA,EAAA,GAAM,OAAA,CAAQ,gBAAA,CAAiB,CAAC;AAAA,EAClE,CAAA;AACJ;AACA,MAAA,SAAe,aAAA,CAAc,OAAA,EAAqB,eAAA,EAAyB,SAAA,EAAmB;AAC1F,EAAA,MAAM,OAAA,EAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAA;AAC9C,EAAA,IAAA,CAAA,MAAW,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,CAAA,EAAG;AACzC,IAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,CAAA,GAAA,EAAA,GAAO,GAAA,CAAI,GAAA,IAAO,KAAA,CAAM,EAAE,CAAA,EAAG,QAAA;AAC7C,IAAA,MAAM,QAAA,EAAU,MAAM,OAAA,CAAQ,KAAA,CAAM,KAAA,CAAM,EAAA,EAAI,EAAC,IAAA,EAAM,KAAA,EAAO,SAAA,EAAW,EAAC,MAAA,EAAQ,eAAA,EAAiB,EAAA,EAAI,UAAS,CAAA,EAAG,KAAA,EAAO,EAAC,CAAC,CAAA;AAC1H,IAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,MAAA;AACX;AJ6MA;AACA;AACE;AACA;AACF,+GAAC","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-5Q7WB63A.cjs","sourcesContent":[null,"import {sha256HexSync} from './utils';\nimport type {KanbanService, KanbanSessionActivityQuery, KanbanSessionItemPage, KanbanSessionItemSummary} from './contracts';\nimport {KanbanError} from './ports';\n/** Filter before pagination; Session activity changes invalidate the filtered keyset. */\nexport async function querySessionItems(core: KanbanService, boardId: string, input: KanbanSessionActivityQuery,\n project: (rows: KanbanSessionItemSummary[])=>Promise<KanbanSessionItemSummary[]>): Promise<KanbanSessionItemPage> {\n const {execution='all',...query}=input;\n if(!['all','running','recent','active'].includes(execution)) throw new KanbanError('INVALID_EXECUTION_FILTER');\n if(execution==='all') {const page=await core.query(boardId,query);return {...page,items:await project(page.items)};}\n const {cursor,limit=50,...filters}=query;\n if(!Number.isSafeInteger(limit)||limit<1||limit>200) throw new KanbanError('INVALID_PAGE_SIZE');\n let page=await core.query(boardId,{...filters,limit:200}), rows=[...page.items];const revision=page.revision;\n while(page.nextCursor) {\n if(rows.length>=10000) throw new KanbanError('ACTIVITY_QUERY_LIMIT');\n page=await core.query(boardId,{...filters,limit:200,cursor:page.nextCursor});\n if(page.revision!==revision) throw new KanbanError('CURSOR_STALE');rows.push(...page.items);\n }\n const matching=(await project(rows)).filter(row=>matchesExecution(row,execution));\n if((await core.query(boardId,{...filters,limit:1})).revision!==revision) throw new KanbanError('CURSOR_STALE');\n const scope=sha256HexSync(JSON.stringify({filters,execution,limit})), signature=sha256HexSync(JSON.stringify(matching.map(row=>row.id)));\n let start=0;\n if(cursor) {\n let saved;try {saved=JSON.parse(cursor);} catch {throw new KanbanError('INVALID_CURSOR');}\n if(saved.scope!==scope) throw new KanbanError('CURSOR_SCOPE_MISMATCH');\n if(saved.revision!==revision||saved.signature!==signature) throw new KanbanError('CURSOR_STALE');\n start=matching.findIndex(row=>row.id===saved.after)+1;if(start<1) throw new KanbanError('INVALID_CURSOR');\n }\n const items=matching.slice(start,start+limit);\n return {revision,total:matching.length,items,...(start+items.length<matching.length?{nextCursor:JSON.stringify({scope,revision,signature,after:items.at(-1)!.id})}: {})};\n}\nfunction matchesExecution(row: KanbanSessionItemSummary, filter: string): boolean {\n const session=row.execution;if(!session||session.stale) return false;\n return filter==='running'?session.state==='running':filter==='recent'?session.recent:session.state==='running'||session.recent;\n}\n","import type {KanbanItem, KanbanExternalReference, KanbanWorkflowState, KanbanSessionAssociation, KanbanRelatedSession, KanbanSessionExecution, KanbanExecutionSession} from './contracts';\n\nexport function sessionAssociations(item: KanbanItem, bindings: KanbanExternalReference[], workflow: KanbanWorkflowState): KanbanSessionAssociation[] {\n return [...bindings.map(ref => {\n const dispatch = workflow.dispatches[ref.revision ?? ''];\n const execution: KanbanSessionExecution | undefined = dispatch?.itemId === item.id ? {\n id: dispatch.id, purpose: 'execution', dispatchId: dispatch.id, attempt: dispatch.attempt,\n outcome: dispatch.outcome, createdAt: dispatch.preparedAt, code: dispatch.code,\n ...(dispatch.continuation ? {previousDispatchId: dispatch.continuation.previousDispatchId} : {}),\n } : undefined;\n return {sessionId: ref.id, purpose: 'execution' as const, ...(execution ? {execution} : {})};\n }), ...item.participants.filter(row => !bindings.some(ref => ref.id === row.sessionId)).map(row => ({sessionId: row.sessionId, purpose: 'discussion' as const}))];\n}\n\n/** Session identity and run identity are independent; neither activity nor a hook selects the primary. */\nexport async function projectRelatedSessions(associations: KanbanSessionAssociation[], currentId: string | undefined,\n inspect: (id: string) => Promise<KanbanExecutionSession>): Promise<KanbanRelatedSession[]> {\n const grouped = new Map<string, {purposes: Set<KanbanSessionAssociation['purpose']>; executions: Map<string, KanbanSessionExecution>}>();\n for (const row of associations) {\n let group = grouped.get(row.sessionId);\n if (!group) grouped.set(row.sessionId, group = {purposes: new Set(), executions: new Map()});\n group.purposes.add(row.purpose);\n if (row.execution) group.executions.set(row.execution.id, {...group.executions.get(row.execution.id), ...row.execution});\n }\n const rows: KanbanRelatedSession[] = [], entries = [...grouped]; let next = 0;\n await Promise.all(Array.from({length: Math.min(entries.length, 8)}, async () => {\n while (next < entries.length) {\n const [sessionId, group] = entries[next++], state = await inspect(sessionId);\n rows.push({...state, current: sessionId === currentId, purposes: [...group.purposes].sort(),\n executions: [...group.executions.values()].sort((a, b) => (a.createdAt ?? 0) - (b.createdAt ?? 0) || a.id.localeCompare(b.id))});\n }\n }));\n return rows.sort((a, b) => Number(b.current) - Number(a.current) || a.sessionId.localeCompare(b.sessionId));\n}\n","import type {KanbanBoard, KanbanCommand, KanbanActor, KanbanService, KanbanExecutionSession, KanbanExternalReference, KanbanSessionItemSummary, KanbanWorkflowState} from './contracts';\nimport type {KanbanSessionSource} from './activity-ports';\nimport {principal,principalKey,candidates} from './identity';\nimport {KanbanError} from './ports';\nimport {querySessionItems} from './session-activity-query';\nimport {randomUUID} from './utils';\nimport {sessionAssociations, projectRelatedSessions} from './session-relations';\nexport interface KanbanSessionActivityOptions {source: KanbanSessionSource; now?:()=>number}\nexport function executionBindings(refs: KanbanExternalReference[] | undefined, referenceSystem: string) {return (refs ?? []).filter(ref=>ref.system===referenceSystem);}\nfunction currentBinding(refs: KanbanExternalReference[]|undefined, itemId:string, workflow:KanbanWorkflowState, referenceSystem: string) {\n const binding=executionBindings(refs, referenceSystem).at(-1),latest=Object.values(workflow.dispatches).filter(dispatch=>dispatch.itemId===itemId).sort((a,b)=>b.attempt-a.attempt)[0];\n if(!binding||!latest||binding.revision===latest.id) return binding;\n return ['prepared','running','unknown','succeeded'].includes(latest.outcome)||workflow.dispatches[binding.revision ?? '']?undefined:binding;\n}\n\n/** Optional resource projection; access checks remain owned by the injected source. */\nexport function createKanbanSessionActivity(core: KanbanService, options: KanbanSessionActivityOptions | undefined, log: (event: {operationId:string;sessionId?:string;stage:string;result:'failure';code:string;durationMs:number})=>void, referenceSystem: string) {\n const inspect=createSessionInspector(options,log);\n const project=async(boardId:string,rows:KanbanSessionItemSummary[])=>{\n if(!rows.some(row=>executionBindings(row.externalRefs,referenceSystem).length))return rows;\n const [board,workflow]=await Promise.all([boardMetadata(core,boardId),core.workflow(boardId)]), bindings=new Map(rows.map(row=>[row.id,currentBinding(row.externalRefs,row.id,workflow,referenceSystem)]));\n const ids=[...new Set([...bindings.values()].flatMap(ref=>ref?[ref.id]:[]))], states=new Map<string,KanbanExecutionSession>();let next=0;\n await Promise.all(Array.from({length:Math.min(ids.length,8)},async()=>{while(next<ids.length) {const id=ids[next++];states.set(id,await inspect(board,id));}}));\n return rows.map(row=>{const binding=bindings.get(row.id);return {...row,...(binding?{execution:states.get(binding.id)}: {})};});\n };\n return {\n queryActivity:(boardId:string,query:import('./contracts').KanbanSessionActivityQuery={})=>querySessionItems(core,boardId,query,rows=>project(boardId,rows)),\n async executionSession(boardId:string,itemId:string, query: import('./contracts').KanbanSessionDetailQuery = {}) {\n const started = Date.now();\n if (!query || typeof query !== 'object' || Array.isArray(query) || Object.keys(query).some(key => key !== 'includeRelated') || query.includeRelated !== undefined && typeof query.includeRelated !== 'boolean') throw new KanbanError('INVALID_QUERY');\n const {item}=await core.item(boardId,itemId),bindings=executionBindings(item.externalRefs,referenceSystem);\n if(!bindings.length && !query.includeRelated)return {history:[]};\n const [board,workflow]=await Promise.all([boardMetadata(core,boardId),core.workflow(boardId)]),last=currentBinding(item.externalRefs,itemId,workflow,referenceSystem);\n let sessionsCode: string | undefined;\n const related = query.includeRelated ? await options?.source.related?.(board, item, workflow).catch(error => {\n const candidate = (error as {code?: string})?.code;\n sessionsCode = candidate && /^[A-Z][A-Z0-9_]{0,79}$/.test(candidate) ? candidate : 'SESSION_RELATIONS_FAILED';\n try {log({operationId: randomUUID(), stage: 'session.relations', result: 'failure', code: sessionsCode, durationMs: Date.now() - started});} catch { /* Diagnostics cannot hide known associations. */ }\n return [];\n }) : [];\n const sessions = query.includeRelated ? await projectRelatedSessions([\n ...sessionAssociations(item, bindings, workflow), ...related ?? [],\n ], last?.id, id => inspect(board, id)) : undefined;\n return {current:last?(sessions?.find(row=>row.sessionId===last.id) ?? await inspect(board,last.id)):undefined,\n history:bindings.map(ref=>({sessionId:ref.id,bindingId:ref.revision,current:ref===last})).reverse(), ...(sessions ? {sessions} : {}), ...(sessionsCode ? {sessionsCode} : {})};\n },\n validate:(board:KanbanBoard,command:KanbanCommand|undefined,actor:KanbanActor)=>validateBinding(core,options,board,command,actor,referenceSystem),\n };\n}\nfunction createSessionInspector(options:KanbanSessionActivityOptions|undefined,log:Parameters<typeof createKanbanSessionActivity>[2]) {\n const now=options?.now ?? Date.now, cache=new Map<string,KanbanExecutionSession>();\n return async(board:KanbanBoard,sessionId:string):Promise<KanbanExecutionSession>=>{\n const started=now(),key=JSON.stringify([board.id,sessionId]);\n try {\n if(!options) throw new KanbanError('EXECUTION_SESSION_UNAVAILABLE');\n const row=await options.source.inspect(board,sessionId);\n if(row.sessionId!==sessionId) throw new KanbanError('SESSION_ACTIVITY_SCOPE_MISMATCH');\n const stale=row.stale||row.observedAt===undefined||now()-row.observedAt>90000;\n const value:KanbanExecutionSession={sessionId,...(typeof row.resourceId==='string'&&row.resourceId.length<=4096&&!row.resourceId.includes('\\0')?{resourceId:row.resourceId}:{}),title:row.title?.slice(0,256),state:row.state,createdAt:row.createdAt,lastActivityAt:row.lastActivityAt,observedAt:row.observedAt,stale,\n recent:!stale&&row.lastActivityAt!==undefined&&row.lastActivityAt<=now()&&now()-row.lastActivityAt<=600000,...(row.code&&/^[A-Z][A-Z0-9_]{0,79}$/.test(row.code)?{code:row.code}:{})};\n if(cache.size>=256) cache.delete(cache.keys().next().value!);cache.set(key,value);return value;\n } catch(error) {\n const candidate=(error as {code?:string})?.code,code=candidate&&/^[A-Z][A-Z0-9_]{0,79}$/.test(candidate)?candidate:'SESSION_ACTIVITY_FAILED';\n try {log({operationId:randomUUID(),sessionId,stage:'session.activity',result:'failure',code,durationMs:now()-started});} catch { /* Observation diagnostics cannot change assignments. */ }\n const prior=['EIO','ETIMEDOUT','ECONNRESET','ECONNREFUSED','SESSION_ACTIVITY_FAILED'].includes(code)?cache.get(key):undefined;\n return {...prior,sessionId,state:prior?.state ?? 'unknown',stale:true,recent:false,code};\n }\n };\n}\nasync function boardMetadata(core: KanbanService, boardId: string): Promise<KanbanBoard> {\n const board=(await core.catalog()).find(board=>board.id===boardId) ?? await core.read(boardId);\n return {...board,items:[]};\n}\nasync function validateBinding(core: KanbanService, options:KanbanSessionActivityOptions|undefined, board:KanbanBoard, command:KanbanCommand|undefined, actor:KanbanActor, referenceSystem: string): Promise<void> {\n if(command?.type!=='link-reference'||command.reference.system!==referenceSystem) return;\n if(!options||!command.reference.revision) throw new KanbanError('EXECUTION_SESSION_UNAVAILABLE');\n const item=board.items.find(item=>item.id===command.itemId);if(!item) throw new KanbanError('ITEM_NOT_FOUND');\n const key=principalKey(principal(actor)), coordinator=board.members?.some(member=>principalKey(member)===key&&member.roles?.includes('coordinator'));\n if(!coordinator&&item.owner?.principalId!==key&&!(item.owner===undefined&&candidates(board,item).some(candidate=>principalKey(candidate)===key))) throw new KanbanError('EXECUTION_SESSION_ASSIGNMENT_DENIED');\n const active=Object.values((await core.workflow(board.id)).dispatches).filter(dispatch=>dispatch.itemId===item.id).sort((a,b)=>b.attempt-a.attempt)[0];\n if(active&&command.reference.revision!==active.id) throw new KanbanError('EXECUTION_SESSION_LOCKED');\n if(active&&executionBindings(item.externalRefs,referenceSystem).some(ref=>ref.revision===active.id&&ref.id!==command.reference.id)) throw new KanbanError('EXECUTION_SESSION_LOCKED');\n if(options.source.authorizeBinding) return options.source.authorizeBinding(board,command.reference.id);\n const state=await options.source.inspect(board,command.reference.id);\n if(state.sessionId!==command.reference.id||state.stale) throw new KanbanError('EXECUTION_SESSION_UNAVAILABLE');\n}\n","import {createKanbanModule as createCore, type KanbanModuleHandle as CoreHandle} from './module';\nimport type {KanbanModuleOptions} from './ports';\nimport {KanbanError} from './ports';\nimport type {KanbanSessionActivityQuery, KanbanSessionItemPage, KanbanExecutionSessionDetail} from './contracts';\nimport {createKanbanSessionActivity, type KanbanSessionActivityOptions} from './session-activity';\nexport interface KanbanActivityModuleOptions extends KanbanModuleOptions {\n executionSessions?: KanbanSessionActivityOptions;\n referenceSystem: string;\n}\nexport interface KanbanActivityHandle extends CoreHandle {\n queryActivity: (boardId: string, query?: KanbanSessionActivityQuery) => Promise<KanbanSessionItemPage>;\n executionSession: (boardId: string, itemId: string, query?: import('./contracts').KanbanSessionDetailQuery) => Promise<KanbanExecutionSessionDetail>;\n}\n\n/** Application integrations stay outside the portable core. */\nexport function createKanbanActivityModule(options: KanbanActivityModuleOptions): KanbanActivityHandle {\n const {executionSessions, referenceSystem, ...core} = options;\n let activity: ReturnType<typeof createKanbanSessionActivity>;\n const service=createCore({...core,\n authorize:async input=>{await core.authorize(input);await activity.validate(input.board,input.command,input.actor);},\n });\n activity=createKanbanSessionActivity(service,executionSessions,core.log,referenceSystem);\n let stopping = false;\n const pending = new Set<Promise<unknown>>();\n const track = <T>(run: () => Promise<T>): Promise<T> => {\n if (stopping) return Promise.reject(new KanbanError('SERVICE_STOPPING'));\n const work = Promise.resolve().then(run).finally(() => {pending.delete(work);});\n pending.add(work); return work;\n };\n const quiesce = async () => {\n stopping = true;\n await Promise.allSettled([...pending]);\n await service.quiesce();\n };\n return {\n ...forwardCore(service, track),\n queryActivity: (...args) => track(() => activity.queryActivity(...args)),\n executionSession: (...args) => track(() => activity.executionSession(...args)),\n related: sessionId => track(() => relatedBoards(service, referenceSystem, sessionId)),\n quiesce, dispose: quiesce,\n };\n}\n\nfunction forwardCore(service: CoreHandle, track: <T>(run: () => Promise<T>) => Promise<T>): Omit<CoreHandle, 'related' | 'quiesce' | 'dispose'> {\n return {\n create: (input) => track(() => service.create(input)),\n read: (id) => track(() => service.read(id)),\n list: () => track(() => service.list()),\n catalog: () => track(() => service.catalog()),\n execute: (id, request) => track(() => service.execute(id, request)),\n events: (id, after, limit) => track(() => service.events(id, after, limit)),\n query: (id, query) => track(() => service.query(id, query)),\n item: (id, item) => track(() => service.item(id, item)),\n overview: (id) => track(() => service.overview(id)),\n scan: () => track(() => service.scan()),\n workflow: (id) => track(() => service.workflow(id)),\n resolve: (reference) => track(() => service.resolve(reference)),\n suggest: (id, query) => track(() => service.suggest(id, query)),\n records: (id, query) => track(() => service.records(id, query)),\n record: (id, record) => track(() => service.record(id, record)),\n currentPrincipal: () => track(() => service.currentPrincipal()),\n };\n}\nasync function relatedBoards(service: CoreHandle, referenceSystem: string, sessionId: string) {\n const boards = await service.related(sessionId);\n for (const board of await service.catalog()) {\n if (boards.some(old => old.id === board.id)) continue;\n const matches = await service.query(board.id, {view: 'all', reference: {system: referenceSystem, id: sessionId}, limit: 1});\n if (matches.total) boards.push(await service.read(board.id));\n }\n return boards;\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/contracts/references.ts
|
|
2
|
+
function kanbanReference(board, entity) {
|
|
3
|
+
const prefix = board.number ? `KB-${board.number}` : board.id;
|
|
4
|
+
if (!entity) return prefix;
|
|
5
|
+
if (!entity.number) return `${prefix}/${entity.id}`;
|
|
6
|
+
return entity.kind ? `${prefix}/${entity.kind === "log" ? "L" : "D"}-${entity.number}` : `${prefix}#${entity.number}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/contracts/configuration.ts
|
|
10
|
+
var DEFAULT_KANBAN_WORK_TYPES = [
|
|
11
|
+
{ id: "initiative", label: "Goal", rank: 0, executable: false },
|
|
12
|
+
{ id: "feature", label: "Group", rank: 1, executable: false },
|
|
13
|
+
{ id: "task", label: "Action", rank: 2, executable: true },
|
|
14
|
+
{ id: "fix", label: "Fix", rank: 2, executable: true },
|
|
15
|
+
{ id: "subtask", label: "Subtask", rank: 3, executable: true }
|
|
16
|
+
];
|
|
17
|
+
function executableWorkItem(board, item) {
|
|
18
|
+
return _optionalChain([item, 'access', _ => _.planning, 'optionalAccess', _2 => _2.execution]) !== "children" && (_nullishCoalesce(board.workTypes, () => ( DEFAULT_KANBAN_WORK_TYPES))).some((type) => type.id === (_nullishCoalesce(_nullishCoalesce(_optionalChain([item, 'access', _3 => _3.planning, 'optionalAccess', _4 => _4.kind]), () => ( board.defaultWorkType)), () => ( "task"))) && type.executable);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/contracts/discovery.ts
|
|
22
|
+
var DEFAULT_KANBAN_SCAN_POLICY = {
|
|
23
|
+
idleMs: 3e5,
|
|
24
|
+
includeArchived: true,
|
|
25
|
+
maxSessions: 20,
|
|
26
|
+
maxInputBytes: 128 * 1024,
|
|
27
|
+
leaseMs: 6e5,
|
|
28
|
+
autoCreate: false
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// src/contracts/automation.ts
|
|
32
|
+
function sameAutomationBinding(left, right) {
|
|
33
|
+
const signature = (value) => JSON.stringify([
|
|
34
|
+
_optionalChain([value, 'optionalAccess', _5 => _5.planner, 'optionalAccess', _6 => _6.system]),
|
|
35
|
+
_optionalChain([value, 'optionalAccess', _7 => _7.planner, 'optionalAccess', _8 => _8.id]),
|
|
36
|
+
_optionalChain([value, 'optionalAccess', _9 => _9.planner, 'optionalAccess', _10 => _10.revision]),
|
|
37
|
+
_optionalChain([value, 'optionalAccess', _11 => _11.executor, 'optionalAccess', _12 => _12.system]),
|
|
38
|
+
_optionalChain([value, 'optionalAccess', _13 => _13.executor, 'optionalAccess', _14 => _14.id]),
|
|
39
|
+
_optionalChain([value, 'optionalAccess', _15 => _15.executor, 'optionalAccess', _16 => _16.revision]),
|
|
40
|
+
_optionalChain([value, 'optionalAccess', _17 => _17.coordinator, 'optionalAccess', _18 => _18.kind]),
|
|
41
|
+
_optionalChain([value, 'optionalAccess', _19 => _19.coordinator, 'optionalAccess', _20 => _20.id]),
|
|
42
|
+
_optionalChain([value, 'optionalAccess', _21 => _21.worker, 'optionalAccess', _22 => _22.kind]),
|
|
43
|
+
_optionalChain([value, 'optionalAccess', _23 => _23.worker, 'optionalAccess', _24 => _24.id]),
|
|
44
|
+
_optionalChain([value, 'optionalAccess', _25 => _25.autoAccept]),
|
|
45
|
+
_optionalChain([value, 'optionalAccess', _26 => _26.preparation]),
|
|
46
|
+
Object.entries(_nullishCoalesce(_optionalChain([value, 'optionalAccess', _27 => _27.preparationOptions]), () => ( {}))).sort(([a], [b]) => a.localeCompare(b))
|
|
47
|
+
]);
|
|
48
|
+
return signature(left) === signature(right);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
exports.kanbanReference = kanbanReference; exports.DEFAULT_KANBAN_WORK_TYPES = DEFAULT_KANBAN_WORK_TYPES; exports.executableWorkItem = executableWorkItem; exports.DEFAULT_KANBAN_SCAN_POLICY = DEFAULT_KANBAN_SCAN_POLICY; exports.sameAutomationBinding = sameAutomationBinding;
|
|
58
|
+
//# sourceMappingURL=chunk-7KDOTBRX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-7KDOTBRX.cjs","../src/contracts/references.ts","../src/contracts/configuration.ts","../src/contracts/discovery.ts","../src/contracts/automation.ts"],"names":[],"mappings":"AAAA;ACGO,SAAS,eAAA,CAAgB,KAAA,EAAsC,MAAA,EAA2E;AAC7I,EAAA,MAAM,OAAA,EAAS,KAAA,CAAM,OAAA,EAAS,CAAA,GAAA,EAAM,KAAA,CAAM,MAAM,CAAA,EAAA;AAC5B,EAAA;AAC6B,EAAA;AACR,EAAA;AAC7C;ADDmD;AACA;AECiB;AACrB,EAAA;AACF,EAAA;AACF,EAAA;AACQ,EAAA;AACJ,EAAA;AAC/C;AAKiK;AAC3H,EAAA;AAEtC;AFJmD;AACA;AGO6B;AACpE,EAAA;AAAyB,EAAA;AAAmB,EAAA;AAAyB,EAAA;AAAe,EAAA;AAAoB,EAAA;AACpH;AHAmD;AACA;AIT+D;AACvC,EAAA;AAAiB,oBAAA;AAAwB,oBAAA;AAAoB,oBAAA;AAC/G,oBAAA;AAAyB,oBAAA;AAAqB,oBAAA;AAA8B,oBAAA;AAA0B,oBAAA;AACxG,oBAAA;AAAqB,oBAAA;AAAW,oBAAA;AAAmB,oBAAA;AAA2D,IAAA;AAAyC,EAAA;AAChI,EAAA;AAC9C;AJuBmD;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-7KDOTBRX.cjs","sourcesContent":[null,"import type {KanbanBoard} from './contracts';\n\nexport interface KanbanReferenceTarget {boardId: string; itemId?: string; recordId?: string; reference: string; scope: KanbanBoard['scope']}\nexport function kanbanReference(board: {id: string; number?: number}, entity?: {id: string; number?: number; kind?: 'log' | 'decision'}): string {\n const prefix = board.number ? `KB-${board.number}` : board.id;\n if (!entity) return prefix;\n if (!entity.number) return `${prefix}/${entity.id}`;\n return entity.kind ? `${prefix}/${entity.kind === 'log' ? 'L' : 'D'}-${entity.number}` : `${prefix}#${entity.number}`;\n}\n","import type {KanbanItem, KanbanBoard} from './contracts';\n\nexport interface KanbanPrincipal {kind: 'agent' | 'human' | 'service'; id: string}\nexport interface KanbanMember extends KanbanPrincipal {\n responsibility: string; roles?: Array<'worker' | 'reviewer' | 'coordinator'>;\n}\nexport interface KanbanWorkType {id: string; label: string; rank: number; executable: boolean}\nexport interface KanbanColumn {id: string; label: string; states: KanbanItem['status'][]}\nexport interface KanbanNotificationPolicy {rules?: Record<string, 'info' | 'error' | 'none'>}\nexport const DEFAULT_KANBAN_WORK_TYPES: readonly KanbanWorkType[] = [\n {id: 'initiative', label: 'Goal', rank: 0, executable: false},\n {id: 'feature', label: 'Group', rank: 1, executable: false},\n {id: 'task', label: 'Action', rank: 2, executable: true},\n {id: 'fix', label: 'Fix', rank: 2, executable: true},\n {id: 'subtask', label: 'Subtask', rank: 3, executable: true},\n];\n\nexport interface KanbanExternalReference {system: string; id: string; revision?: string}\n\n/** A composite work item delegates execution to its children. */\nexport function executableWorkItem(board:Pick<KanbanBoard,'workTypes'|'defaultWorkType'>, item:{planning?:{kind:string;execution?:'direct'|'children'}}):boolean {\n return item.planning?.execution!=='children'&&(board.workTypes??DEFAULT_KANBAN_WORK_TYPES)\n .some(type=>type.id===(item.planning?.kind??board.defaultWorkType??'task')&&type.executable);\n}\n","import type {KanbanItemSummary} from './planning';\nimport type {KanbanBoard} from './contracts';\n\nexport type {KanbanSourceRef, KanbanDiscoveryChange, KanbanDiscoveryBatch} from './source';\nimport type {KanbanDiscoveryChange} from './source';\nexport interface KanbanScanSession {\n id: string; revision: string; updatedAt: number | null; idleSince: number | null;\n activity: 'idle' | 'active' | 'waiting' | 'unknown'; archived: boolean; scannerOwned?: boolean;\n}\nexport interface KanbanScanText {\n session: KanbanScanSession; complete: boolean;\n messages: Array<{id: string; role: 'user' | 'assistant'; text: string}>;\n}\nexport interface KanbanScanConnection {\n kind: 'local' | 'remote'; connectionId: string;\n /** Explicit consent for moving source text to a different execution boundary. */\n allowContentTransfer: boolean;\n}\nexport interface KanbanScanPolicy {\n idleMs: number; includeArchived: boolean; maxSessions: number; maxInputBytes: number; leaseMs: number;\n autoCreate: boolean; connection: KanbanScanConnection;\n}\nexport interface KanbanScanInput {\n projectContext?: {totalRecords: number; excludedRecords?: number; omittedRecords: number; records: import('./context').KanbanProjectRecord[]};\n context?: {totalItems: number; omittedItems: number; archivedTotal: number; archivedItems: KanbanItemSummary[]};\n runId: string; executorId: string; board: KanbanBoard; sessions: KanbanScanText[]; connection: KanbanScanConnection;\n}\nexport const DEFAULT_KANBAN_SCAN_POLICY: Omit<KanbanScanPolicy, 'connection'> = {\n idleMs: 300000, includeArchived: true, maxSessions: 20, maxInputBytes: 128 * 1024, leaseMs: 600000, autoCreate: false,\n};\n\nexport interface KanbanDiscoveryResult {changes: KanbanDiscoveryChange[]; records?: import('./context').KanbanRecordInput[]}\n","import type {KanbanExternalReference, KanbanPrincipal} from './configuration';\n\nexport interface KanbanAutomationSettings {\n preparation?: KanbanExternalReference;\n preparationOptions?: Record<string, string>;\n enabled: boolean; planner: KanbanExternalReference; executor: KanbanExternalReference;\n coordinator: KanbanPrincipal; worker: KanbanPrincipal; autoAccept: boolean;\n}\nexport interface KanbanAutomationOption {\n name: string; label: string; defaultValue?: string;\n choices?: Array<{value: string; label: string}>;\n}\nexport interface KanbanAutomationTarget {reference: KanbanExternalReference; label: string; options?: KanbanAutomationOption[]}\nexport interface KanbanAutomationCatalog {\n preparations?: KanbanAutomationTarget[];\n targets: KanbanAutomationTarget[]; coordinator: KanbanPrincipal; worker: KanbanPrincipal;\n}\nexport interface KanbanAnalysisStatus {\n itemId: string; state: 'analyzing' | 'ready' | 'clarification' | 'failed' | 'unknown';\n reason?: string; code?: string; dependencies?: string[];\n}\nexport function sameAutomationBinding(left?: KanbanAutomationSettings, right?: KanbanAutomationSettings): boolean {\n const signature = (value?: KanbanAutomationSettings) => JSON.stringify([value?.planner?.system, value?.planner?.id, value?.planner?.revision,\n value?.executor?.system, value?.executor?.id, value?.executor?.revision, value?.coordinator?.kind, value?.coordinator?.id,\n value?.worker?.kind, value?.worker?.id, value?.autoAccept, value?.preparation, Object.entries(value?.preparationOptions ?? {}).sort(([a], [b]) => a.localeCompare(b))]);\n return signature(left) === signature(right);\n}\n"]}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import {
|
|
2
|
+
allocateBoardNumber,
|
|
3
|
+
archiveKey,
|
|
4
|
+
boardCounterKey,
|
|
5
|
+
boardKey,
|
|
6
|
+
boardNumberKey,
|
|
7
|
+
counter,
|
|
8
|
+
decodeRow,
|
|
9
|
+
encodeBoard,
|
|
10
|
+
encodeRow,
|
|
11
|
+
hydrate,
|
|
12
|
+
indexedView,
|
|
13
|
+
numberEntities,
|
|
14
|
+
patchBoardNumber,
|
|
15
|
+
receiptDigest,
|
|
16
|
+
rowChanges,
|
|
17
|
+
rowKeys,
|
|
18
|
+
verifyReceipt,
|
|
19
|
+
viewFromState
|
|
20
|
+
} from "./chunk-XKDZHAUE.js";
|
|
21
|
+
import {
|
|
22
|
+
KanbanError
|
|
23
|
+
} from "./chunk-M35X5PHO.js";
|
|
24
|
+
|
|
25
|
+
// src/store.ts
|
|
26
|
+
import { FSError } from "@nestos/vfs-core";
|
|
27
|
+
var SeqKanbanStore = class _SeqKanbanStore {
|
|
28
|
+
constructor(fs, path, bodies) {
|
|
29
|
+
this.fs = fs;
|
|
30
|
+
this.path = path;
|
|
31
|
+
this.bodies = bodies ?? { read: async (hash) => {
|
|
32
|
+
const body = await fs.meta.assets.getAsset(path, `${hash}.json`);
|
|
33
|
+
if (body === null || body instanceof ArrayBuffer) return body;
|
|
34
|
+
throw new KanbanError("BODY_INTEGRITY");
|
|
35
|
+
}, write: async (hash, bytes) => {
|
|
36
|
+
await fs.meta.assets.putAsset(path, `${hash}.json`, bytes);
|
|
37
|
+
} };
|
|
38
|
+
}
|
|
39
|
+
bodies;
|
|
40
|
+
static async open(fs, directory = "/kanban", bodies) {
|
|
41
|
+
if (!fs.meta.seq?.transaction) throw new KanbanError("TRANSACTION_REQUIRED");
|
|
42
|
+
try {
|
|
43
|
+
await fs.driver.createFile({ parentPath: directory, name: "boards.seq", type: "seqfile", recursive: true });
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (!(error instanceof FSError) || error.code !== "EEXIST") throw error;
|
|
46
|
+
}
|
|
47
|
+
return new _SeqKanbanStore(fs, `${directory}/boards.seq`, bodies);
|
|
48
|
+
}
|
|
49
|
+
async boardId(number) {
|
|
50
|
+
return this.fs.meta.seq.getEntry(this.path, boardNumberKey(number));
|
|
51
|
+
}
|
|
52
|
+
async ids() {
|
|
53
|
+
return JSON.parse(await this.fs.meta.seq.getEntry(this.path, "index") ?? "[]");
|
|
54
|
+
}
|
|
55
|
+
async events(id, after, limit, through) {
|
|
56
|
+
const end = Math.min(through, after + limit);
|
|
57
|
+
const keys = Array.from({ length: Math.max(0, end - after) }, (_, index) => `event/${encodeURIComponent(id)}/${String(after + index + 1).padStart(16, "0")}`);
|
|
58
|
+
if (!keys.length) return [];
|
|
59
|
+
const rows = await this.fs.meta.seq.getEntries(this.path, keys);
|
|
60
|
+
return keys.filter((key) => rows[key] !== void 0).map((key) => JSON.parse(rows[key]));
|
|
61
|
+
}
|
|
62
|
+
async archived(boardId, itemId) {
|
|
63
|
+
const raw = await this.fs.meta.seq.getEntry(this.path, archiveKey(boardId, itemId));
|
|
64
|
+
if (!raw) return null;
|
|
65
|
+
const record = await decodeRow(raw, this.bodies);
|
|
66
|
+
record.item.number ??= (await this.view(boardId))?.state.archiveIndex?.find((item) => item.id === itemId)?.number;
|
|
67
|
+
return record;
|
|
68
|
+
}
|
|
69
|
+
async load(id, receiptKey) {
|
|
70
|
+
return this.fs.meta.seq.transaction(async (tx) => {
|
|
71
|
+
const raw = await tx.getEntry(this.path, boardKey(id));
|
|
72
|
+
return { raw, rows: await tx.getEntries(this.path, rowKeys(raw)), receipt: receiptKey ? await tx.getEntry(this.path, receiptKey) : void 0 };
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async view(id) {
|
|
76
|
+
const raw = await this.fs.meta.seq.getEntry(this.path, boardKey(id));
|
|
77
|
+
const indexed = indexedView(raw);
|
|
78
|
+
if (indexed) return indexed;
|
|
79
|
+
const state = await this.read(id);
|
|
80
|
+
return state ? viewFromState(state) : null;
|
|
81
|
+
}
|
|
82
|
+
async read(id) {
|
|
83
|
+
return hydrate(await this.load(id), this.bodies);
|
|
84
|
+
}
|
|
85
|
+
async update(id, operationId, fingerprint, change) {
|
|
86
|
+
const receiptKey = `receipt/${encodeURIComponent(id)}/${encodeURIComponent(operationId)}`;
|
|
87
|
+
const before = await this.load(id, receiptKey), current = await hydrate(before, this.bodies), receipt = before.receipt;
|
|
88
|
+
if (receipt) {
|
|
89
|
+
verifyReceipt(receipt, fingerprint);
|
|
90
|
+
if (!current) throw new KanbanError("CORRUPT_RECEIPT");
|
|
91
|
+
return current;
|
|
92
|
+
}
|
|
93
|
+
const original = JSON.stringify(current), next = change(current);
|
|
94
|
+
numberEntities(next);
|
|
95
|
+
if (JSON.stringify(next) === original) return next;
|
|
96
|
+
return this.persist(id, receiptKey, fingerprint, before, next);
|
|
97
|
+
}
|
|
98
|
+
async persist(id, receiptKey, fingerprint, before, next) {
|
|
99
|
+
const events = [...next.events], archives = await Promise.all((next.archiveWrites ?? []).map(async (write) => ({ key: archiveKey(id, write.id), value: write.value ? await encodeRow(write.value, this.bodies) : null })));
|
|
100
|
+
delete next.archiveWrites;
|
|
101
|
+
next.events = [];
|
|
102
|
+
const encoded = await encodeBoard(next, this.bodies);
|
|
103
|
+
const committed = await this.fs.meta.seq.transaction(async (tx) => {
|
|
104
|
+
const latestReceipt = await tx.getEntry(this.path, receiptKey);
|
|
105
|
+
if (latestReceipt) {
|
|
106
|
+
verifyReceipt(latestReceipt, fingerprint);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
if (await tx.getEntry(this.path, boardKey(id)) !== before.raw) throw new KanbanError("REVISION_CONFLICT");
|
|
110
|
+
await commitBoardNumber(tx, this.path, id, before, next, encoded);
|
|
111
|
+
const eventRows = events.map((event) => ({ key: `event/${encodeURIComponent(id)}/${String(event.sequence).padStart(16, "0")}`, value: JSON.stringify(event) }));
|
|
112
|
+
await writeRows(tx, this.path, [
|
|
113
|
+
...eventRows,
|
|
114
|
+
...rowChanges(before, encoded),
|
|
115
|
+
...archives,
|
|
116
|
+
{ key: boardKey(id), value: encoded.raw },
|
|
117
|
+
{ key: receiptKey, value: receiptDigest(fingerprint) }
|
|
118
|
+
]);
|
|
119
|
+
const ids = JSON.parse(await tx.getEntry(this.path, "index") ?? "[]");
|
|
120
|
+
if (!ids.includes(id)) await tx.setEntry(this.path, "index", JSON.stringify([...ids, id]));
|
|
121
|
+
return next;
|
|
122
|
+
});
|
|
123
|
+
if (committed) return committed;
|
|
124
|
+
const replay = await this.read(id);
|
|
125
|
+
if (!replay) throw new KanbanError("CORRUPT_RECEIPT");
|
|
126
|
+
return replay;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
async function writeRows(tx, path, rows) {
|
|
130
|
+
for (const row of rows) {
|
|
131
|
+
if (row.value === null) await tx.deleteEntry(path, row.key);
|
|
132
|
+
else await tx.setEntry(path, row.key, row.value);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function commitBoardNumber(tx, path, id, before, next, encoded) {
|
|
136
|
+
const previous = counter(await tx.getEntry(path, boardCounterKey));
|
|
137
|
+
next.board.number = allocateBoardNumber(before.raw, previous);
|
|
138
|
+
const owner = await tx.getEntry(path, boardNumberKey(next.board.number));
|
|
139
|
+
if (owner !== null && owner !== id) throw new KanbanError("INVALID_NUMBERING");
|
|
140
|
+
encoded.raw = patchBoardNumber(encoded.raw, next.board.number);
|
|
141
|
+
await tx.setEntry(path, boardCounterKey, String(Math.max(previous, next.board.number)));
|
|
142
|
+
await tx.setEntry(path, boardNumberKey(next.board.number), id);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
SeqKanbanStore
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=chunk-AHHEGTUA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"sourcesContent":["import {numberEntities, boardCounterKey, boardNumberKey, counter, allocateBoardNumber, patchBoardNumber} from './numbering';\nimport type { KanbanEvent, KanbanArchivedItem } from './contracts';\nimport { FSError, type IFileSystem } from '@nestos/vfs-core';\nimport { KanbanError, type KanbanState, type KanbanStore } from './ports';\nimport {indexedView, viewFromState, archiveKey, boardKey as key, rowKeys, hydrate, encodeBoard, rowChanges, encodeRow, decodeRow, receiptDigest, verifyReceipt, type StoredBoard, type KanbanBodyStore} from './storage-codec';\n\n/** One user-scoped journal, with atomic board/index/receipt commits. */\nexport class SeqKanbanStore implements KanbanStore {\n private readonly bodies: KanbanBodyStore;\n private constructor(private readonly fs: IFileSystem, private readonly path: string, bodies?: KanbanBodyStore) {\n this.bodies = bodies ?? {read: async hash => {\n const body = await fs.meta.assets.getAsset(path, `${hash}.json`);\n if (body === null || body instanceof ArrayBuffer) return body;\n throw new KanbanError('BODY_INTEGRITY');\n }, write: async (hash, bytes) => {await fs.meta.assets.putAsset(path, `${hash}.json`, bytes);}};\n }\n static async open(fs: IFileSystem, directory = '/kanban', bodies?: KanbanBodyStore): Promise<SeqKanbanStore> {\n if (!fs.meta.seq?.transaction) throw new KanbanError('TRANSACTION_REQUIRED');\n try { await fs.driver.createFile({ parentPath: directory, name: 'boards.seq', type: 'seqfile', recursive: true }); }\n catch (error) { if (!(error instanceof FSError) || error.code !== 'EEXIST') throw error; }\n return new SeqKanbanStore(fs, `${directory}/boards.seq`, bodies);\n }\n async boardId(number: number): Promise<string | null> {return this.fs.meta.seq!.getEntry(this.path, boardNumberKey(number));}\n async ids(): Promise<string[]> {\n return JSON.parse(await this.fs.meta.seq!.getEntry(this.path, 'index') ?? '[]');\n }\n async events(id: string, after: number, limit: number, through: number): Promise<KanbanEvent[]> {\n const end = Math.min(through, after + limit);\n const keys = Array.from({length: Math.max(0, end - after)}, (_, index) =>\n `event/${encodeURIComponent(id)}/${String(after + index + 1).padStart(16, '0')}`);\n if (!keys.length) return [];\n // The committed sequence freezes this immutable prefix; bulk key reads avoid history scans.\n const rows = await this.fs.meta.seq!.getEntries(this.path, keys);\n return keys.filter(key => rows[key] !== undefined).map(key => JSON.parse(rows[key]) as KanbanEvent);\n }\n\n async archived(boardId: string, itemId: string): Promise<KanbanArchivedItem | null> {\n const raw = await this.fs.meta.seq!.getEntry(this.path, archiveKey(boardId, itemId));\n if (!raw) return null; const record = await decodeRow<KanbanArchivedItem>(raw, this.bodies);\n record.item.number ??= (await this.view(boardId))?.state.archiveIndex?.find(item => item.id === itemId)?.number; return record;\n }\n private async load(id: string, receiptKey?: string): Promise<StoredBoard & {receipt?: string | null}> {\n return this.fs.meta.seq!.transaction!(async tx => {\n const raw = await tx.getEntry(this.path, key(id));\n return {raw, rows: await tx.getEntries(this.path, rowKeys(raw)), receipt: receiptKey ? await tx.getEntry(this.path, receiptKey) : undefined};\n });\n }\n async view(id: string) {\n const raw = await this.fs.meta.seq!.getEntry(this.path, key(id));\n const indexed = indexedView(raw); if (indexed) return indexed;\n const state = await this.read(id); return state ? viewFromState(state) : null;\n }\n async read(id: string): Promise<KanbanState | null> {return hydrate(await this.load(id), this.bodies);}\n async update(id: string, operationId: string, fingerprint: string,\n change: (state: KanbanState | null) => KanbanState): Promise<KanbanState> {\n const receiptKey = `receipt/${encodeURIComponent(id)}/${encodeURIComponent(operationId)}`;\n const before = await this.load(id, receiptKey), current = await hydrate(before, this.bodies), receipt = before.receipt;\n if (receipt) {verifyReceipt(receipt, fingerprint); if (!current) throw new KanbanError('CORRUPT_RECEIPT'); return current;}\n const original = JSON.stringify(current), next = change(current);\n numberEntities(next);\n if (JSON.stringify(next) === original) return next;\n return this.persist(id, receiptKey, fingerprint, before, next);\n }\n private async persist(id: string, receiptKey: string, fingerprint: string, before: StoredBoard, next: KanbanState): Promise<KanbanState> {\n const events = [...next.events], archives = await Promise.all((next.archiveWrites ?? []).map(async write =>\n ({key: archiveKey(id, write.id), value: write.value ? await encodeRow(write.value, this.bodies) : null})));\n delete next.archiveWrites; next.events = [];\n // No asset I/O runs under the SeqFile transaction: it may use the same backend.\n const encoded = await encodeBoard(next, this.bodies);\n const committed = await this.fs.meta.seq!.transaction!(async tx => {\n const latestReceipt = await tx.getEntry(this.path, receiptKey);\n if (latestReceipt) {verifyReceipt(latestReceipt, fingerprint); return null;}\n if (await tx.getEntry(this.path, key(id)) !== before.raw) throw new KanbanError('REVISION_CONFLICT');\n await commitBoardNumber(tx, this.path, id, before, next, encoded);\n const eventRows = events.map(event => ({key: `event/${encodeURIComponent(id)}/${String(event.sequence).padStart(16, '0')}`, value: JSON.stringify(event)}));\n await writeRows(tx, this.path, [...eventRows, ...rowChanges(before, encoded), ...archives,\n {key: key(id), value: encoded.raw!}, {key: receiptKey, value: receiptDigest(fingerprint)}]);\n const ids: string[] = JSON.parse(await tx.getEntry(this.path, 'index') ?? '[]');\n if (!ids.includes(id)) await tx.setEntry(this.path, 'index', JSON.stringify([...ids, id]));\n return next;\n });\n if (committed) return committed;\n const replay = await this.read(id); if (!replay) throw new KanbanError('CORRUPT_RECEIPT'); return replay;\n }\n}\nasync function writeRows(tx: import('@nestos/vfs-core').ISeqFileTransaction, path: string, rows: Array<{key: string; value: string | null}>): Promise<void> {\n for (const row of rows) {\n if (row.value === null) await tx.deleteEntry(path, row.key);\n else await tx.setEntry(path, row.key, row.value);\n }\n}\n\nasync function commitBoardNumber(tx: import('@nestos/vfs-core').ISeqFileTransaction, path: string, id: string, before: StoredBoard, next: KanbanState, encoded: StoredBoard): Promise<void> {\n const previous = counter(await tx.getEntry(path, boardCounterKey));\n next.board.number = allocateBoardNumber(before.raw, previous);\n const owner = await tx.getEntry(path, boardNumberKey(next.board.number));\n if (owner !== null && owner !== id) throw new KanbanError('INVALID_NUMBERING');\n encoded.raw = patchBoardNumber(encoded.raw!, next.board.number);\n await tx.setEntry(path, boardCounterKey, String(Math.max(previous, next.board.number)));\n await tx.setEntry(path, boardNumberKey(next.board.number), id);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/contracts/board-control.ts
|
|
2
|
+
function boardAllowsStart(board, item) {
|
|
3
|
+
return !board.lifecycle && !_optionalChain([board, 'access', _ => _.executionControl, 'optionalAccess', _2 => _2.paused]) && (_optionalChain([board, 'access', _3 => _3.executionControl, 'optionalAccess', _4 => _4.mode]) !== "manual" || _optionalChain([item, 'optionalAccess', _5 => _5.launch, 'optionalAccess', _6 => _6.requestedAt]) !== void 0);
|
|
4
|
+
}
|
|
5
|
+
function boardControlPhase(board) {
|
|
6
|
+
if (board.lifecycle) return board.lifecycle.intent === "delete" ? "waiting-deletion" : board.lifecycle.phase === "ready" ? "cancelled" : "cancelling";
|
|
7
|
+
const policy = board.executionControl;
|
|
8
|
+
const controls = Object.entries(_nullishCoalesce(_optionalChain([policy, 'optionalAccess', _7 => _7.controls]), () => ( {}))).flatMap(([id, controlId]) => {
|
|
9
|
+
const item = board.items.find((item2) => item2.id === id);
|
|
10
|
+
return item && !["completed", "cancelled", "review"].includes(item.status) && _optionalChain([item, 'access', _8 => _8.control, 'optionalAccess', _9 => _9.id]) === controlId ? [item.control] : [];
|
|
11
|
+
});
|
|
12
|
+
if (controls.some((control) => _optionalChain([control, 'optionalAccess', _10 => _10.state]) === "failed" || _optionalChain([control, 'optionalAccess', _11 => _11.state]) === "unknown")) return "error";
|
|
13
|
+
if (controls.some((control) => _optionalChain([control, 'optionalAccess', _12 => _12.state]) === "requested" || _optionalChain([control, 'optionalAccess', _13 => _13.state]) === "accepted")) return _optionalChain([policy, 'optionalAccess', _14 => _14.paused]) ? "pausing" : "resuming";
|
|
14
|
+
return _optionalChain([policy, 'optionalAccess', _15 => _15.paused]) ? "paused" : _nullishCoalesce(_optionalChain([policy, 'optionalAccess', _16 => _16.mode]), () => ( "automatic"));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/contracts/task-projection.ts
|
|
18
|
+
var TASK_START_DELAY_MS = 3e5;
|
|
19
|
+
function taskStartAt(item) {
|
|
20
|
+
return _nullishCoalesce(_optionalChain([item, 'access', _17 => _17.launch, 'optionalAccess', _18 => _18.startAt]), () => ( item.createdAt + TASK_START_DELAY_MS));
|
|
21
|
+
}
|
|
22
|
+
function taskEditing(item, now) {
|
|
23
|
+
return (_nullishCoalesce(_optionalChain([item, 'access', _19 => _19.launch, 'optionalAccess', _20 => _20.editing, 'optionalAccess', _21 => _21.expiresAt]), () => ( 0))) > now;
|
|
24
|
+
}
|
|
25
|
+
function taskDue(item, now) {
|
|
26
|
+
return !taskEditing(item, now) && !item.blocked && (!item.control || item.control.action === "resume" && item.control.state === "resumed") && (_optionalChain([item, 'access', _22 => _22.launch, 'optionalAccess', _23 => _23.requestedAt]) !== void 0 || _optionalChain([item, 'access', _24 => _24.launch, 'optionalAccess', _25 => _25.mode]) !== "manual" && taskStartAt(item) <= now);
|
|
27
|
+
}
|
|
28
|
+
function projectKanbanTask(item, workflow, now = Date.now(), all = []) {
|
|
29
|
+
const dispatch = Object.values(_nullishCoalesce(_optionalChain([workflow, 'optionalAccess', _26 => _26.dispatches]), () => ( {}))).filter((d) => d.itemId === item.id).sort((a, b) => b.attempt - a.attempt)[0];
|
|
30
|
+
const fact = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(terminalFact(item), () => ( controlFact(item))), () => ( issueFact(item, dispatch))), () => ( failureFact(item, dispatch))), () => ( executionFact(item, dispatch))), () => ( waitingFact(item, now, all)));
|
|
31
|
+
const extra = [];
|
|
32
|
+
if (!["completed", "cancelled"].includes(item.status) && _optionalChain([item, 'access', _27 => _27.control, 'optionalAccess', _28 => _28.action]) !== "cancel") {
|
|
33
|
+
if (!_optionalChain([fact, 'access', _29 => _29.actions, 'optionalAccess', _30 => _30.includes, 'call', _31 => _31("cancel")])) extra.push("cancel");
|
|
34
|
+
if (item.status !== "review" && !_optionalChain([fact, 'access', _32 => _32.actions, 'optionalAccess', _33 => _33.includes, 'call', _34 => _34("pause")]) && !_optionalChain([fact, 'access', _35 => _35.actions, 'optionalAccess', _36 => _36.includes, 'call', _37 => _37("resume")]) && (_optionalChain([dispatch, 'optionalAccess', _38 => _38.controlCapabilities, 'optionalAccess', _39 => _39.pause]) === "boundary" || !dispatch)) extra.push("pause");
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
...fact,
|
|
38
|
+
startAt: taskStartAt(item),
|
|
39
|
+
dispatchId: _optionalChain([dispatch, 'optionalAccess', _40 => _40.id]),
|
|
40
|
+
sessionId: _optionalChain([dispatch, 'optionalAccess', _41 => _41.executionSessionId]),
|
|
41
|
+
actions: item.deletedAt === void 0 ? [..._nullishCoalesce(fact.actions, () => ( [])), ...extra, ...dispatch || _optionalChain([item, 'access', _42 => _42.launch, 'optionalAccess', _43 => _43.admittedAt]) !== void 0 || ["claimed", "review", "completed"].includes(item.status) ? ["fix"] : [], ..._optionalChain([dispatch, 'optionalAccess', _44 => _44.executionSessionId]) ? ["open-session"] : []] : []
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function terminalFact(item) {
|
|
45
|
+
if (item.status === "completed" || item.status === "cancelled") return { phase: item.status, actions: ["delete"] };
|
|
46
|
+
if (_optionalChain([item, 'access', _45 => _45.control, 'optionalAccess', _46 => _46.action]) === "cancel") return { phase: item.control.state === "failed" ? "error" : item.control.state === "unknown" ? "unknown" : "cancelling", reason: item.control.code, actions: item.control.state === "failed" ? ["cancel"] : [] };
|
|
47
|
+
if (item.status === "review") return { phase: "review", actions: ["review"] };
|
|
48
|
+
}
|
|
49
|
+
function issueFact(item, dispatch) {
|
|
50
|
+
const issue = _optionalChain([item, 'access', _47 => _47.issues, 'optionalAccess', _48 => _48.find, 'call', _49 => _49((i) => !i.resolvedBy && (!dispatch || i.attemptId === dispatch.id))]);
|
|
51
|
+
if (issue) return { phase: issue.type === "clarification" ? "waiting-input" : "error", reason: issue.id, actions: ["resolve"] };
|
|
52
|
+
}
|
|
53
|
+
function controlFact(item) {
|
|
54
|
+
const control = item.control;
|
|
55
|
+
if (!control) return;
|
|
56
|
+
const reason = control.code;
|
|
57
|
+
if (control.state === "unknown") return { phase: "unknown", reason };
|
|
58
|
+
if (control.state === "failed") return { phase: "error", reason, actions: ["resume"] };
|
|
59
|
+
if (control.action === "pause") return { phase: control.state === "paused" ? "paused" : "pausing", reason, actions: ["resume"] };
|
|
60
|
+
if (["requested", "accepted"].includes(control.state)) return { phase: "resuming", reason };
|
|
61
|
+
}
|
|
62
|
+
function failureFact(item, dispatch) {
|
|
63
|
+
if (_optionalChain([dispatch, 'optionalAccess', _50 => _50.outcome]) === "unknown" || _optionalChain([item, 'access', _51 => _51.analysis, 'optionalAccess', _52 => _52.state]) === "unknown") return { phase: "unknown", reason: _nullishCoalesce(_optionalChain([dispatch, 'optionalAccess', _53 => _53.code]), () => ( _optionalChain([item, 'access', _54 => _54.analysis, 'optionalAccess', _55 => _55.code]))) };
|
|
64
|
+
if (dispatch && ["failed", "cancelled", "rejected"].includes(dispatch.outcome)) return { phase: "error", reason: _nullishCoalesce(dispatch.code, () => ( dispatch.outcome)) };
|
|
65
|
+
if (_optionalChain([item, 'access', _56 => _56.analysis, 'optionalAccess', _57 => _57.state]) === "failed") return { phase: "error", reason: item.analysis.code };
|
|
66
|
+
}
|
|
67
|
+
function executionFact(item, dispatch) {
|
|
68
|
+
if (item.blocked) return { phase: item.blocked.reason === "WORKSPACE_INPUT_REQUIRED" ? "waiting-input" : "error", reason: item.blocked.reason };
|
|
69
|
+
if (_optionalChain([dispatch, 'optionalAccess', _58 => _58.outcome]) === "prepared") return { phase: "preparing" };
|
|
70
|
+
if (_optionalChain([dispatch, 'optionalAccess', _59 => _59.outcome]) === "running" || item.status === "claimed") return { phase: "running", actions: _optionalChain([dispatch, 'optionalAccess', _60 => _60.controlCapabilities, 'optionalAccess', _61 => _61.pause]) === "boundary" ? ["pause"] : [] };
|
|
71
|
+
}
|
|
72
|
+
function waitingFact(item, now, all) {
|
|
73
|
+
const analysis = analysisFact(item);
|
|
74
|
+
if (analysis) return analysis;
|
|
75
|
+
const dependency = _optionalChain([item, 'access', _62 => _62.planning, 'optionalAccess', _63 => _63.dependencies, 'access', _64 => _64.find, 'call', _65 => _65((id) => _optionalChain([all, 'access', _66 => _66.find, 'call', _67 => _67((i) => i.id === id), 'optionalAccess', _68 => _68.status]) !== "completed")]);
|
|
76
|
+
if (dependency) return { phase: "waiting-dependency", reason: "DEPENDENCY_UNFINISHED:" + dependency, actions: _optionalChain([item, 'access', _69 => _69.launch, 'optionalAccess', _70 => _70.admittedAt]) === void 0 ? ["edit", "cancel"] : [] };
|
|
77
|
+
if (taskEditing(item, now)) return { phase: "waiting-start", reason: "EDIT_LEASE_ACTIVE" };
|
|
78
|
+
if (_optionalChain([item, 'access', _71 => _71.launch, 'optionalAccess', _72 => _72.admittedAt]) !== void 0) return { phase: "queued" };
|
|
79
|
+
return { phase: "waiting-start", reason: _optionalChain([item, 'access', _73 => _73.launch, 'optionalAccess', _74 => _74.mode]) === "manual" ? "MANUAL_START_REQUIRED" : taskDue(item, now) ? "ADMISSION_PENDING" : "START_AT_PENDING", actions: ["run", "edit", "pause", "cancel"] };
|
|
80
|
+
}
|
|
81
|
+
function analysisFact(item) {
|
|
82
|
+
if (_optionalChain([item, 'access', _75 => _75.analysis, 'optionalAccess', _76 => _76.state]) === "clarification") return { phase: "waiting-input", reason: item.analysis.reason };
|
|
83
|
+
if (_optionalChain([item, 'access', _77 => _77.analysis, 'optionalAccess', _78 => _78.state]) === "analyzing") return { phase: "analyzing" };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
exports.boardAllowsStart = boardAllowsStart; exports.boardControlPhase = boardControlPhase; exports.TASK_START_DELAY_MS = TASK_START_DELAY_MS; exports.taskStartAt = taskStartAt; exports.taskEditing = taskEditing; exports.taskDue = taskDue; exports.projectKanbanTask = projectKanbanTask;
|
|
95
|
+
//# sourceMappingURL=chunk-AOHQCX7K.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/li/share/prj/x1/libraries/kanban/dist/chunk-AOHQCX7K.cjs","../src/contracts/board-control.ts","../src/contracts/task-projection.ts"],"names":["item"],"mappings":"AAAA;ACOO,SAAS,gBAAA,CAAiB,KAAA,EAA4D,IAAA,EAA4C;AACrI,EAAA,OAAO,CAAC,KAAA,CAAM,UAAA,GAAa,iBAAC,KAAA,mBAAM,gBAAA,6BAAkB,SAAA,GAAA,iBAAW,KAAA,qBAAM,gBAAA,6BAAkB,OAAA,IAAS,SAAA,mBAAY,IAAA,6BAAM,MAAA,6BAAQ,cAAA,IAAgB,KAAA,CAAA,CAAA;AAC9I;AACO,SAAS,iBAAA,CAAkB,KAAA,EAAoP;AAClR,EAAA,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,OAAO,KAAA,CAAM,SAAA,CAAU,OAAA,IAAW,SAAA,EAAW,mBAAA,EAAqB,KAAA,CAAM,SAAA,CAAU,MAAA,IAAU,QAAA,EAAU,YAAA,EAAc,YAAA;AACzI,EAAA,MAAM,OAAA,EAAS,KAAA,CAAM,gBAAA;AACrB,EAAA,MAAM,SAAA,EAAW,MAAA,CAAO,OAAA,kCAAQ,MAAA,6BAAQ,UAAA,UAAY,CAAC,GAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,EAAA,EAAI,SAAS,CAAA,EAAA,GAAM;AACjF,IAAA,MAAM,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,CAAAA,KAAAA,EAAAA,GAAQA,KAAAA,CAAK,GAAA,IAAO,EAAE,CAAA;AACpD,IAAA,OAAO,KAAA,GAAQ,CAAC,CAAC,WAAA,EAAa,WAAA,EAAa,QAAQ,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,MAAM,EAAA,mBAAK,IAAA,qBAAK,OAAA,6BAAS,KAAA,IAAO,UAAA,EAAY,CAAC,IAAA,CAAK,OAAO,EAAA,EAAI,CAAC,CAAA;AAAA,EACrI,CAAC,CAAA;AACD,EAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,CAAA,OAAA,EAAA,mBAAW,OAAA,+BAAS,QAAA,IAAU,SAAA,mBAAY,OAAA,+BAAS,QAAA,IAAU,SAAS,CAAA,EAAG,OAAO,OAAA;AAClG,EAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,CAAA,OAAA,EAAA,mBAAW,OAAA,+BAAS,QAAA,IAAU,YAAA,mBAAe,OAAA,+BAAS,QAAA,IAAU,UAAU,CAAA,EAAG,uBAAO,MAAA,+BAAQ,SAAA,EAAS,UAAA,EAAY,UAAA;AACnI,EAAA,uBAAO,MAAA,+BAAQ,SAAA,EAAS,SAAA,mCAAW,MAAA,+BAAQ,MAAA,UAAQ,aAAA;AACvD;ADLA;AACA;AEZO,IAAM,oBAAA,EAAoB,GAAA;AAC1B,SAAS,WAAA,CAAY,IAAA,EAA6C;AAAC,EAAA,wCAAO,IAAA,uBAAK,MAAA,+BAAQ,SAAA,UAAS,IAAA,CAAK,UAAA,EAAU,qBAAA;AAAoB;AACnI,SAAS,WAAA,CAAY,IAAA,EAAyB,GAAA,EAAoB;AAAC,EAAA,OAAA,kCAAQ,IAAA,uBAAK,MAAA,+BAAQ,OAAA,+BAAS,WAAA,UAAW,GAAA,EAAA,EAAG,GAAA;AAAI;AACnH,SAAS,OAAA,CAAQ,IAAA,EAAU,GAAA,EAAoB;AAClD,EAAA,OAAO,CAAC,WAAA,CAAY,IAAA,EAAK,GAAG,EAAA,GAAG,CAAC,IAAA,CAAK,QAAA,GAAA,CAAU,CAAC,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,OAAA,IAAW,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAU,SAAA,EAAA,GAAA,iBACpH,IAAA,uBAAK,MAAA,+BAAQ,cAAA,IAAc,KAAA,EAAA,mBAAW,IAAA,uBAAK,MAAA,+BAAQ,OAAA,IAAO,SAAA,GAAU,WAAA,CAAY,IAAI,EAAA,GAAG,GAAA,CAAA;AAClG;AAEO,SAAS,iBAAA,CAAkB,IAAA,EAAU,QAAA,EAA8B,IAAA,EAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAE,IAAA,EAAiD,CAAC,CAAA,EAAwB;AAC/J,EAAA,MAAM,SAAA,EAAS,MAAA,CAAO,MAAA,kCAAO,QAAA,+BAAU,YAAA,UAAY,CAAC,GAAC,CAAA,CAAE,MAAA,CAAO,CAAA,CAAA,EAAA,GAAG,CAAA,CAAE,OAAA,IAAS,IAAA,CAAK,EAAE,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAE,CAAA,EAAA,GAAI,CAAA,CAAE,QAAA,EAAQ,CAAA,CAAE,OAAO,CAAA,CAAE,CAAC,CAAA;AACvH,EAAA,MAAM,KAAA,uFAAK,YAAA,CAAa,IAAI,CAAA,UAAG,WAAA,CAAY,IAAI,GAAA,UAAG,SAAA,CAAU,IAAA,EAAK,QAAQ,GAAA,UAAG,WAAA,CAAY,IAAA,EAAK,QAAQ,GAAA,UAAG,aAAA,CAAc,IAAA,EAAK,QAAQ,GAAA,UAAG,WAAA,CAAY,IAAA,EAAK,GAAA,EAAI,GAAG,GAAA;AAC9J,EAAA,MAAM,MAAA,EAAyC,CAAC,CAAA;AAChD,EAAA,GAAA,CAAI,CAAC,CAAC,WAAA,EAAY,WAAW,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,MAAM,EAAA,mBAAK,IAAA,uBAAK,OAAA,+BAAS,SAAA,IAAW,QAAA,EAAU;AACvF,IAAA,GAAA,CAAI,iBAAC,IAAA,uBAAK,OAAA,+BAAS,QAAA,qBAAS,QAAQ,GAAA,EAAG,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAC1D,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,SAAA,GAAY,iBAAC,IAAA,uBAAK,OAAA,+BAAS,QAAA,qBAAS,OAAO,IAAA,GAAK,iBAAC,IAAA,uBAAK,OAAA,+BAAS,QAAA,qBAAS,QAAQ,IAAA,GAAA,iBAAM,QAAA,+BAAU,mBAAA,+BAAqB,QAAA,IAAU,WAAA,GAAc,CAAC,QAAA,CAAA,EAAW,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAAA,EACnM;AACA,EAAA,OAAO;AAAA,IAAC,GAAG,IAAA;AAAA,IAAK,OAAA,EAAQ,WAAA,CAAY,IAAI,CAAA;AAAA,IAAE,UAAA,kBAAW,QAAA,+BAAU,IAAA;AAAA,IAAG,SAAA,kBAAU,QAAA,+BAAU,oBAAA;AAAA,IAClF,OAAA,EAAQ,IAAA,CAAK,UAAA,IAAc,KAAA,EAAA,EAAY,CAAC,oBAAG,IAAA,CAAK,OAAA,UAAS,CAAC,GAAA,EAAE,GAAG,KAAA,EAAM,GAAI,SAAA,mBAAU,IAAA,uBAAK,MAAA,+BAAQ,aAAA,IAAa,KAAA,EAAA,GAAW,CAAC,SAAA,EAAU,QAAA,EAAS,WAAW,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,MAAM,EAAA,EAAE,CAAC,KAAc,EAAA,EAAE,CAAC,CAAA,EAAG,mBAAI,QAAA,+BAAU,qBAAA,EAAmB,CAAC,cAAuB,EAAA,EAAE,CAAC,CAAE,EAAA,EAAI,CAAC;AAAA,EAAC,CAAA;AAChR;AACA,SAAS,YAAA,CAAa,IAAA,EAA0B;AAC5C,EAAA,GAAA,CAAG,IAAA,CAAK,OAAA,IAAS,YAAA,GAAa,IAAA,CAAK,OAAA,IAAS,WAAA,EAAY,OAAO,EAAC,KAAA,EAAM,IAAA,CAAK,MAAA,EAAO,OAAA,EAAQ,CAAC,QAAQ,EAAC,CAAA;AACpG,EAAA,GAAA,iBAAG,IAAA,uBAAK,OAAA,+BAAS,SAAA,IAAS,QAAA,EAAS,OAAO,EAAC,KAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAQ,SAAA,EAAS,QAAA,EAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAQ,UAAA,EAAU,UAAA,EAAU,YAAA,EAAa,MAAA,EAAO,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAK,OAAA,EAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,IAAQ,SAAA,EAAS,CAAC,QAAQ,EAAA,EAAE,CAAC,EAAC,CAAA;AACzN,EAAA,GAAA,CAAG,IAAA,CAAK,OAAA,IAAS,QAAA,EAAS,OAAO,EAAC,KAAA,EAAM,QAAA,EAAS,OAAA,EAAQ,CAAC,QAAQ,EAAC,CAAA;AACvE;AACA,SAAS,SAAA,CAAU,IAAA,EAAU,QAAA,EAAyC;AAClE,EAAA,MAAM,MAAA,kBAAM,IAAA,uBAAK,MAAA,+BAAQ,IAAA,qBAAK,CAAA,CAAA,EAAA,GAAG,CAAC,CAAA,CAAE,WAAA,GAAA,CAAa,CAAC,SAAA,GAAU,CAAA,CAAE,UAAA,IAAY,QAAA,CAAS,EAAA,CAAG,GAAA;AACtF,EAAA,GAAA,CAAG,KAAA,EAAM,OAAO,EAAC,KAAA,EAAM,KAAA,CAAM,KAAA,IAAO,gBAAA,EAAgB,gBAAA,EAAgB,OAAA,EAAQ,MAAA,EAAO,KAAA,CAAM,EAAA,EAAG,OAAA,EAAQ,CAAC,SAAS,EAAC,CAAA;AACnH;AACA,SAAS,WAAA,CAAY,IAAA,EAA0B;AAC3C,EAAA,MAAM,QAAA,EAAQ,IAAA,CAAK,OAAA;AAAQ,EAAA,GAAA,CAAG,CAAC,OAAA,EAAQ,MAAA;AACvC,EAAA,MAAM,OAAA,EAAO,OAAA,CAAQ,IAAA;AACrB,EAAA,GAAA,CAAG,OAAA,CAAQ,MAAA,IAAQ,SAAA,EAAU,OAAO,EAAC,KAAA,EAAM,SAAA,EAAU,OAAM,CAAA;AAC3D,EAAA,GAAA,CAAG,OAAA,CAAQ,MAAA,IAAQ,QAAA,EAAS,OAAO,EAAC,KAAA,EAAM,OAAA,EAAQ,MAAA,EAAO,OAAA,EAAQ,CAAC,QAAQ,EAAC,CAAA;AAC3E,EAAA,GAAA,CAAG,OAAA,CAAQ,OAAA,IAAS,OAAA,EAAQ,OAAO,EAAC,KAAA,EAAM,OAAA,CAAQ,MAAA,IAAQ,SAAA,EAAS,SAAA,EAAS,SAAA,EAAU,MAAA,EAAO,OAAA,EAAQ,CAAC,QAAQ,EAAC,CAAA;AAC/G,EAAA,GAAA,CAAG,CAAC,WAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,OAAA,CAAQ,KAAK,CAAA,EAAE,OAAO,EAAC,KAAA,EAAM,UAAA,EAAW,OAAM,CAAA;AACvF;AACA,SAAS,WAAA,CAAY,IAAA,EAAU,QAAA,EAAyC;AACpE,EAAA,GAAA,iBAAG,QAAA,+BAAU,UAAA,IAAU,UAAA,mBAAW,IAAA,uBAAK,QAAA,+BAAU,QAAA,IAAQ,SAAA,EAAU,OAAO,EAAC,KAAA,EAAM,SAAA,EAAU,MAAA,mCAAO,QAAA,+BAAU,MAAA,0BAAM,IAAA,uBAAK,QAAA,+BAAU,SAAI,CAAA;AACrI,EAAA,GAAA,CAAG,SAAA,GAAU,CAAC,QAAA,EAAS,WAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAE,OAAO,EAAC,KAAA,EAAM,OAAA,EAAQ,MAAA,mBAAO,QAAA,CAAS,IAAA,UAAM,QAAA,CAAS,UAAO,CAAA;AACtI,EAAA,GAAA,iBAAG,IAAA,uBAAK,QAAA,+BAAU,QAAA,IAAQ,QAAA,EAAS,OAAO,EAAC,KAAA,EAAM,OAAA,EAAQ,MAAA,EAAO,IAAA,CAAK,QAAA,CAAS,KAAI,CAAA;AACtF;AACA,SAAS,aAAA,CAAc,IAAA,EAAU,QAAA,EAAyC;AACtE,EAAA,GAAA,CAAG,IAAA,CAAK,OAAA,EAAQ,OAAO,EAAC,KAAA,EAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,IAAS,2BAAA,EAA2B,gBAAA,EAAgB,OAAA,EAAQ,MAAA,EAAO,IAAA,CAAK,OAAA,CAAQ,OAAM,CAAA;AACjI,EAAA,GAAA,iBAAG,QAAA,+BAAU,UAAA,IAAU,UAAA,EAAW,OAAO,EAAC,KAAA,EAAM,YAAW,CAAA;AAC3D,EAAA,GAAA,iBAAG,QAAA,+BAAU,UAAA,IAAU,UAAA,GAAW,IAAA,CAAK,OAAA,IAAS,SAAA,EAAU,OAAO,EAAC,KAAA,EAAM,SAAA,EAAU,OAAA,kBAAQ,QAAA,+BAAU,mBAAA,+BAAqB,QAAA,IAAQ,WAAA,EAAW,CAAC,OAAO,EAAA,EAAE,CAAC,EAAC,CAAA;AAC5J;AACA,SAAS,WAAA,CAAY,IAAA,EAAU,GAAA,EAAW,GAAA,EAAuD;AAC7F,EAAA,MAAM,SAAA,EAAS,YAAA,CAAa,IAAI,CAAA;AAAE,EAAA,GAAA,CAAG,QAAA,EAAS,OAAO,QAAA;AACrD,EAAA,MAAM,WAAA,kBAAW,IAAA,uBAAK,QAAA,+BAAU,YAAA,uBAAa,IAAA,qBAAK,CAAA,EAAA,EAAA,mBAAI,GAAA,uBAAI,IAAA,qBAAK,CAAA,CAAA,EAAA,GAAG,CAAA,CAAE,GAAA,IAAK,EAAE,CAAA,+BAAG,SAAA,IAAS,WAAW,GAAA;AAClG,EAAA,GAAA,CAAG,UAAA,EAAW,OAAO,EAAC,KAAA,EAAM,oBAAA,EAAqB,MAAA,EAAO,yBAAA,EAAyB,UAAA,EAAW,OAAA,kBAAQ,IAAA,uBAAK,MAAA,+BAAQ,aAAA,IAAa,KAAA,EAAA,EAAU,CAAC,MAAA,EAAO,QAAQ,EAAA,EAAE,CAAC,EAAC,CAAA;AAC5J,EAAA,GAAA,CAAG,WAAA,CAAY,IAAA,EAAK,GAAG,CAAA,EAAE,OAAO,EAAC,KAAA,EAAM,eAAA,EAAgB,MAAA,EAAO,oBAAmB,CAAA;AACjF,EAAA,GAAA,iBAAG,IAAA,uBAAK,MAAA,+BAAQ,aAAA,IAAa,KAAA,CAAA,EAAU,OAAO,EAAC,KAAA,EAAM,SAAQ,CAAA;AAC7D,EAAA,OAAO,EAAC,KAAA,EAAM,eAAA,EAAgB,MAAA,kBAAO,IAAA,uBAAK,MAAA,+BAAQ,OAAA,IAAO,SAAA,EAAS,wBAAA,EAAwB,OAAA,CAAQ,IAAA,EAAK,GAAG,EAAA,EAAE,oBAAA,EAAoB,kBAAA,EAAmB,OAAA,EAAQ,CAAC,KAAA,EAAM,MAAA,EAAO,OAAA,EAAQ,QAAQ,EAAC,CAAA;AAC9L;AACA,SAAS,YAAA,CAAa,IAAA,EAA0B;AAC5C,EAAA,GAAA,iBAAG,IAAA,uBAAK,QAAA,+BAAU,QAAA,IAAQ,eAAA,EAAgB,OAAO,EAAC,KAAA,EAAM,eAAA,EAAgB,MAAA,EAAO,IAAA,CAAK,QAAA,CAAS,OAAM,CAAA;AACnG,EAAA,GAAA,iBAAG,IAAA,uBAAK,QAAA,+BAAU,QAAA,IAAQ,WAAA,EAAY,OAAO,EAAC,KAAA,EAAM,YAAW,CAAA;AACnE;AFuBA;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF,8RAAC","file":"/home/li/share/prj/x1/libraries/kanban/dist/chunk-AOHQCX7K.cjs","sourcesContent":[null,"import type {KanbanBoard, KanbanItem} from './contracts';\n\nexport interface KanbanBoardControl {\n mode: 'automatic' | 'manual'; paused: boolean;\n controls: Record<string, string>;\n}\n/** Manual mode still honors an explicit per-task run request. */\nexport function boardAllowsStart(board: Pick<KanbanBoard, 'executionControl' | 'lifecycle'>, item?: Pick<KanbanItem, 'launch'>): boolean {\n return !board.lifecycle && !board.executionControl?.paused && (board.executionControl?.mode !== 'manual' || item?.launch?.requestedAt !== undefined);\n}\nexport function boardControlPhase(board: Pick<KanbanBoard, 'executionControl' | 'lifecycle'> & {items: Array<Pick<KanbanItem, 'id' | 'status' | 'control'>>}): 'automatic' | 'manual' | 'pausing' | 'paused' | 'resuming' | 'error' | 'cancelling' | 'cancelled' | 'waiting-deletion' {\n if (board.lifecycle) return board.lifecycle.intent === 'delete' ? 'waiting-deletion' : board.lifecycle.phase === 'ready' ? 'cancelled' : 'cancelling';\n const policy = board.executionControl;\n const controls = Object.entries(policy?.controls ?? {}).flatMap(([id, controlId]) => {\n const item = board.items.find(item => item.id === id);\n return item && !['completed', 'cancelled', 'review'].includes(item.status) && item.control?.id === controlId ? [item.control] : [];\n });\n if (controls.some(control => control?.state === 'failed' || control?.state === 'unknown')) return 'error';\n if (controls.some(control => control?.state === 'requested' || control?.state === 'accepted')) return policy?.paused ? 'pausing' : 'resuming';\n return policy?.paused ? 'paused' : policy?.mode ?? 'automatic';\n}\n","import type {KanbanDispatch,KanbanItem,KanbanItemSummary,KanbanWorkflowState,KanbanTaskProjection,KanbanTaskPhase} from './index';\n\ntype Item=Pick<KanbanItem,'deletedAt'|'id'|'status'|'createdAt'|'launch'|'analysis'|'control'|'issues'|'blocked'|'externalRefs'|'planning'>;\ntype Fact={phase:KanbanTaskPhase;reason?:string;actions?:KanbanTaskProjection['actions']};\nexport const TASK_START_DELAY_MS=300000;\nexport function taskStartAt(item:Pick<Item,'createdAt'|'launch'>):number {return item.launch?.startAt??item.createdAt+TASK_START_DELAY_MS;}\nexport function taskEditing(item:Pick<Item,'launch'>,now:number):boolean {return (item.launch?.editing?.expiresAt??0)>now;}\nexport function taskDue(item:Item,now:number):boolean {\n return !taskEditing(item,now)&&!item.blocked&&(!item.control || item.control.action === 'resume' && item.control.state === 'resumed')\n &&(item.launch?.requestedAt!==undefined||item.launch?.mode!=='manual'&&taskStartAt(item)<=now);\n}\n/** Ordered evidence projection shared by storage queries, CLI and UI. Session idle never proves acceptance. */\nexport function projectKanbanTask(item:Item,workflow?:KanbanWorkflowState,now=Date.now(),all:Array<Pick<KanbanItemSummary,'id'|'status'>>=[]):KanbanTaskProjection {\n const dispatch=Object.values(workflow?.dispatches??{}).filter(d=>d.itemId===item.id).sort((a,b)=>b.attempt-a.attempt)[0];\n const fact=terminalFact(item)??controlFact(item)??issueFact(item,dispatch)??failureFact(item,dispatch)??executionFact(item,dispatch)??waitingFact(item,now,all);\n const extra: KanbanTaskProjection['actions'] = [];\n if (!['completed','cancelled'].includes(item.status) && item.control?.action !== 'cancel') {\n if (!fact.actions?.includes('cancel')) extra.push('cancel');\n if (item.status !== 'review' && !fact.actions?.includes('pause') && !fact.actions?.includes('resume') && (dispatch?.controlCapabilities?.pause === 'boundary' || !dispatch)) extra.push('pause');\n }\n return {...fact,startAt:taskStartAt(item),dispatchId:dispatch?.id,sessionId:dispatch?.executionSessionId,\n actions:item.deletedAt === undefined ? [...fact.actions??[],...extra,...(dispatch||item.launch?.admittedAt!==undefined||['claimed','review','completed'].includes(item.status)?['fix' as const]:[]),...(dispatch?.executionSessionId?['open-session' as const]:[])] : []};\n}\nfunction terminalFact(item:Item):Fact|undefined {\n if(item.status==='completed'||item.status==='cancelled')return {phase:item.status,actions:['delete']};\n if(item.control?.action==='cancel')return {phase:item.control.state==='failed'?'error':item.control.state==='unknown'?'unknown':'cancelling',reason:item.control.code,actions:item.control.state==='failed'?['cancel']:[]};\n if(item.status==='review')return {phase:'review',actions:['review']};\n}\nfunction issueFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n const issue=item.issues?.find(i=>!i.resolvedBy&&(!dispatch||i.attemptId===dispatch.id));\n if(issue)return {phase:issue.type==='clarification'?'waiting-input':'error',reason:issue.id,actions:['resolve']};\n}\nfunction controlFact(item:Item):Fact|undefined {\n const control=item.control;if(!control)return;\n const reason=control.code;\n if(control.state==='unknown')return {phase:'unknown',reason};\n if(control.state==='failed')return {phase:'error',reason,actions:['resume']};\n if(control.action==='pause')return {phase:control.state==='paused'?'paused':'pausing',reason,actions:['resume']};\n if(['requested','accepted'].includes(control.state))return {phase:'resuming',reason};\n}\nfunction failureFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n if(dispatch?.outcome==='unknown'||item.analysis?.state==='unknown')return {phase:'unknown',reason:dispatch?.code??item.analysis?.code};\n if(dispatch&&['failed','cancelled','rejected'].includes(dispatch.outcome))return {phase:'error',reason:dispatch.code??dispatch.outcome};\n if(item.analysis?.state==='failed')return {phase:'error',reason:item.analysis.code};\n}\nfunction executionFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n if(item.blocked)return {phase:item.blocked.reason==='WORKSPACE_INPUT_REQUIRED'?'waiting-input':'error',reason:item.blocked.reason};\n if(dispatch?.outcome==='prepared')return {phase:'preparing'};\n if(dispatch?.outcome==='running'||item.status==='claimed')return {phase:'running',actions:dispatch?.controlCapabilities?.pause==='boundary'?['pause']:[]};\n}\nfunction waitingFact(item:Item,now:number,all:Array<Pick<KanbanItemSummary,'id'|'status'>>):Fact {\n const analysis=analysisFact(item);if(analysis)return analysis;\n const dependency=item.planning?.dependencies.find(id=>all.find(i=>i.id===id)?.status!=='completed');\n if(dependency)return {phase:'waiting-dependency',reason:'DEPENDENCY_UNFINISHED:'+dependency,actions:item.launch?.admittedAt===undefined?['edit','cancel']:[]};\n if(taskEditing(item,now))return {phase:'waiting-start',reason:'EDIT_LEASE_ACTIVE'};\n if(item.launch?.admittedAt!==undefined)return {phase:'queued'};\n return {phase:'waiting-start',reason:item.launch?.mode==='manual'?'MANUAL_START_REQUIRED':taskDue(item,now)?'ADMISSION_PENDING':'START_AT_PENDING',actions:['run','edit','pause','cancel']};\n}\nfunction analysisFact(item:Item):Fact|undefined {\n if(item.analysis?.state==='clarification')return {phase:'waiting-input',reason:item.analysis.reason};\n if(item.analysis?.state==='analyzing')return {phase:'analyzing'};\n}\n"]}
|