@weasel-js/routing 1.5.1 → 1.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/dist/{chunk-ZZICE4J7.js → chunk-H5AGTB2J.js} +12 -12
- package/dist/chunk-H5AGTB2J.js.map +1 -0
- package/dist/{index-DhFGCPmN.d.ts → index-D4hKg8yu.d.ts} +12 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +18 -10
- package/dist/react.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-ZZICE4J7.js.map +0 -1
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interactions/actions/activeToolContext.tsx","../src/interactions/actions/depRegistry.tsx","../src/interactions/dispatcher/useGestureDispatcher.tsx","../src/interactions/actions/ActionsProvider.tsx","../src/contributions/useContributions.ts","../src/tools/useTools.ts"],"names":["createContext","useMemo","jsx","useContext","useRef","useEffect","Fragment","useCallback"],"mappings":";;;;;AAuCA,IAAM,iBAAA,GAAoB,cAA6C,IAAI,CAAA;AASpE,SAAS,yBAAA,CAA0B;AAAA,EACxC,QAAA;AAAA,EACA,aAAA,GAAgB;AAClB,CAAA,EAAmC;AACjC,EAAA,MAAM,CAAC,MAAA,EAAQ,cAAc,CAAA,GAAI,SAAS,aAAa,CAAA;AACvD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AAE3D,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,CAAC,EAAA,KAAe;AAC5C,IAAA,cAAA,CAAe,EAAE,CAAA;AAAA,EACnB,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,EAAA,KAAe;AAC7C,IAAA,cAAA,CAAe,CAAC,CAAA,KAAM,CAAC,GAAG,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAClC,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,CAAC,EAAA,KAAgB;AAC7C,IAAA,cAAA,CAAe,CAAC,CAAA,KAAM;AACpB,MAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAC3B,MAAA,IAAI,OAAO,MAAA,EAAW,OAAO,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AAC1C,MAAA,MAAM,CAAA,GAAI,CAAA,CAAE,WAAA,CAAY,EAAE,CAAA;AAC1B,MAAA,OAAO,CAAA,KAAM,EAAA,GAAK,CAAA,GAAI,CAAC,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,GAAG,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,IAC5D,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO,EAAE,MAAA,EAAQ,WAAA,EAAa,SAAA,EAAW,YAAY,SAAA,EAAU,CAAA;AAAA,IAC/D,CAAC,MAAA,EAAQ,WAAA,EAAa,SAAA,EAAW,YAAY,SAAS;AAAA,GACxD;AAEA,EAAA,uBACE,GAAA,CAAC,iBAAA,CAAkB,QAAA,EAAlB,EAA2B,OAAe,QAAA,EAAS,CAAA;AAExD;AAIO,SAAS,oBAAA,GAA+C;AAC7D,EAAA,MAAM,KAAA,GAAQ,WAAW,iBAAiB,CAAA;AAC1C,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAQO,SAAS,4BAAA,GAA8D;AAC5E,EAAA,OAAO,WAAW,iBAAiB,CAAA;AACrC;AAQO,SAAS,+BAAA,CAAgC;AAAA,EAC9C;AACF,CAAA,EAEG;AACD,EAAA,MAAM,MAAA,GAAS,WAAW,iBAAiB,CAAA;AAC3C,EAAA,IAAI,MAAA,KAAW,IAAA,EAAM,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAS,CAAA;AACxC,EAAA,uBAAO,GAAA,CAAC,6BAA2B,QAAA,EAAS,CAAA;AAC9C;ACpFA,IAAM,kBAAA,GAAqBA,cAAkC,IAAI,CAAA;AAI1D,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAS,EAA4B;AAMzE,EAAA,MAAM,UAAA,GAAa,MAAA,iBAAO,IAAI,GAAA,EAAgC,CAAA;AAE9D,EAAA,MAAM,QAAA,GAAWC,QAAqB,OAAO;AAAA,IAC3C,QAAA,EAAU,CAAoB,IAAA,EAAS,MAAA,KAA+B;AACpE,MAAA,MAAM,GAAA,GAAM,IAAA;AACZ,MAAA,MAAM,KAAA,GAAQ,MAAA;AACd,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACxC,MAAA,IAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA;AAAA,sBACX,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,CAAC,KAAK,CAAC,CAAA;AACxC,MAAA,IAAI,QAAA,GAAW,KAAA;AACf,MAAA,OAAO,MAAM;AACX,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,QAAA,GAAW,IAAA;AACX,QAAA,MAAM,GAAA,GAAM,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACtC,QAAA,IAAI,CAAC,GAAA,EAAK;AAGV,QAAA,MAAM,CAAA,GAAI,GAAA,CAAI,WAAA,CAAY,KAAK,CAAA;AAC/B,QAAA,IAAI,MAAM,EAAA,EAAI;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AACf,QAAA,IAAI,IAAI,MAAA,KAAW,CAAA,EAAG,UAAA,CAAW,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,MACrD,CAAA;AAAA,IACF,CAAA;AAAA,IACA,GAAA,EAAK,CAAoB,IAAA,KACvB,UAAA,CAAW,OAAA,CAAQ,IAAI,IAAc,CAAA,EAAG,EAAA,CAAG,EAAE,CAAA;AAAI,GACrD,CAAA,EAAI,EAAE,CAAA;AAEN,EAAA,uBAAOC,GAAAA,CAAC,kBAAA,CAAmB,UAAnB,EAA4B,KAAA,EAAO,UAAW,QAAA,EAAS,CAAA;AACjE;AAGO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,CAAA,GAAIC,WAAW,kBAAkB,CAAA;AACvC,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,MAAM,IAAI,MAAM,8HAA8H,CAAA;AAAA,EAChJ;AACA,EAAA,OAAO,CAAA;AACT;AAOO,SAAS,sBAAA,GAA6C;AAC3D,EAAA,OAAOA,WAAW,kBAAkB,CAAA;AACtC;AAKO,SAAS,YAAA,CAAgC,MAAS,MAAA,EAA4B;AACnF,EAAA,MAAM,WAAW,cAAA,EAAe;AAChC,EAAA,MAAM,SAAA,GAAY,OAAO,MAAM,CAAA;AAC/B,EAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,SAAS,QAAA,CAAS,IAAA,EAAM,MAAM,SAAA,CAAU,SAAS,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AACrB;AC7DA,IAAM,cAAA,GAAiB,iBAAA;AAWvB,SAAS,SAAS,CAAA,EAEhB;AACA,EAAA,OAAO;AAAA,IACL,GAAI,OAAO,CAAA,CAAE,QAAA,KAAa,QAAA,GAAW,EAAE,QAAA,EAAU,CAAA,CAAE,QAAA,EAAS,GAAI,EAAC;AAAA,IACjE,GAAI,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,GAAI,EAAC;AAAA,IACxD,GAAI,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,GAAI;AAAC,GAC1D;AACF;AAMA,IAAM,MAAA,GACJ,OAAO,SAAA,KAAc,WAAA,IACrB,MAAA,CAAO,IAAA;AAAA;AAAA;AAAA,EAGJ,SAAA,CAAoC,YAAY,SAAA,CAAU;AAC7D,CAAA;AAqDF,SAAS,YAAA,CACP,MACA,OAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,CAAC,IAAA,EAAM,MAAA,KAAW,MAAK,CAAE,QAAA,CAAS,MAAM,MAAM,CAAA;AAAA,IACxD,GAAA,EAAK,CAAoB,IAAA,KAAsC;AAC7D,MAAA,MAAM,GAAA,GAAM,OAAA,EAAQ,GAAI,IAAI,CAAA;AAC5B,MAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAC9B,MAAA,OAAO,IAAA,EAAK,CAAE,GAAA,CAAI,IAAI,CAAA;AAAA,IACxB;AAAA,GACF;AACF;AAgPA,SAAS,0BACP,SAAA,EACwD;AACxD,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,SAAS,CAAA;AACzB,EAAA,IAAI,GAAA,CAAI,SAAS,CAAA,EAAG;AAClB,IAAA,OAAO,EAAE,UAAU,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAE,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,EAC/C;AAEA,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,IAAA,IAAA,IAAQ,CAAA,CAAE,CAAA;AACV,IAAA,IAAA,IAAQ,CAAA,CAAE,CAAA;AAAA,EACZ;AACA,EAAA,MAAM,QAAA,GAAW,EAAE,CAAA,EAAG,IAAA,GAAO,IAAI,MAAA,EAAQ,CAAA,EAAG,IAAA,GAAO,GAAA,CAAI,MAAA,EAAO;AAE9D,EAAA,MAAM,KAAK,GAAA,CAAI,CAAC,EAAE,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AAC7B,EAAA,MAAM,KAAK,GAAA,CAAI,CAAC,EAAE,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AAC7B,EAAA,MAAM,SAAS,IAAA,CAAK,IAAA,CAAK,EAAA,GAAK,EAAA,GAAK,KAAK,EAAE,CAAA;AAC1C,EAAA,OAAO,EAAE,UAAU,MAAA,EAAO;AAC5B;AAeO,SAAS,qBAAqB,IAAA,EAAyC;AAC5E,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,WAAW,OAAA,GAAU,IAAA,EAAM,WAAW,IAAA,EAAM,YAAA,EAAc,gBAAgB,UAAA,EAAY,aAAA,EAAe,eAAe,aAAA,EAAe,aAAA,EAAe,YAAY,aAAA,EAAe,KAAA,EAAO,UAAS,GAAI,IAAA;AAI7N,EAAA,MAAM,cAAA,GAAiB,UAAU,OAAA,KAAY,KAAA;AAC7C,EAAA,MAAM,YAAA,GAAe,UAAU,KAAA,KAAU,KAAA;AACzC,EAAA,MAAM,kBAAA,GAAqB,UAAU,WAAA,KAAgB,KAAA;AACrD,EAAA,MAAM,aAAA,GAAgB,UAAU,MAAA,KAAW,KAAA;AAC3C,EAAA,MAAM,gBAAA,GAAmBC,OAAO,aAAa,CAAA;AAC7C,EAAA,gBAAA,CAAiB,OAAA,GAAU,aAAA;AAC3B,EAAA,MAAM,aAAa,oBAAA,EAAqB;AACxC,EAAA,MAAM,cAAc,cAAA,EAAe;AAInC,EAAA,MAAM,aAAA,GAAgBA,OAA0B,IAAI,CAAA;AACpD,EAAA,IAAI,CAAC,cAAc,OAAA,EAAS;AAC1B,IAAA,aAAA,CAAc,OAAA,GAAU,iBAAiB,gBAAA,EAAiB;AAAA,EAC5D;AAMA,EAAA,MAAM,SAASA,MAAAA,CAA0B;AAAA,IACvC,OAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAc,UAAA,CAAW,MAAA;AAAA,IACzB,aAAa,UAAA,CAAW,WAAA;AAAA,IACxB,SAAA;AAAA,IACA,KAAA,EAAO;AAAA,GACR,CAAA;AACD,EAAA,MAAA,CAAO,OAAA,GAAU;AAAA,IACf,OAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAc,UAAA,CAAW,MAAA;AAAA,IACzB,aAAa,UAAA,CAAW,WAAA;AAAA,IACxB,SAAA;AAAA,IACA,KAAA,EAAO;AAAA,GACT;AAGA,EAAA,MAAM,gBAAgBA,MAAAA,CAA6B;AAAA,IACjD,EAAA,EAAI,IAAA;AAAA,IAAM,YAAY,aAAA,CAAc,OAAA;AAAA,IAAS,YAAA;AAAA,IAAc,cAAA;AAAA,IAAgB,aAAA;AAAA,IAC3E;AAAA,GACD,CAAA;AACD,EAAA,aAAA,CAAc,OAAA,GAAU;AAAA,IACtB,EAAA,EAAI,IAAA;AAAA,IAAM,YAAY,aAAA,CAAc,OAAA;AAAA,IAAS,YAAA;AAAA,IAAc,cAAA;AAAA,IAAgB,aAAA;AAAA,IAC3E;AAAA,GACF;AACA,EAAA,MAAM,QAAA,GAAWA,OAAO,KAAK,CAAA;AAC7B,EAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAGnB,EAAA,MAAM,iBAAiB,MAAoB;AAAA,IACzC,cAAc,OAAA,CAAQ,UAAA;AAAA,IACtB,GAAA,CAAI,QAAA,CAAS,OAAA,EAAS,OAAA,EAAQ,IAAK,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU;AAAA,GAChE;AACA,EAAA,MAAM,gBAAA,GAAmBA,OAAO,aAAa,CAAA;AAC7C,EAAA,gBAAA,CAAiB,OAAA,GAAU,aAAA;AAC3B,EAAA,MAAM,gBAAA,GAAmBA,OAAO,aAAa,CAAA;AAC7C,EAAA,gBAAA,CAAiB,OAAA,GAAU,aAAA;AAM3B,EAAA,MAAM,YAAA,GAAeA,OAA+D,IAAI,CAAA;AAmBxF,EAAA,MAAM,aAAA,GAAgBA,MAAAA,CAAO,UAAA,CAAW,MAAM,CAAA;AAC9C,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,aAAA,CAAc,OAAA,KAAY,UAAA,CAAW,MAAA,EAAQ;AAC/C,MAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAA,CAAI,aAAA,CAAc,OAAO,CAAA;AACpD,MAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,QAAA,MAAM,OAAA,GAAU,SAAS,WAAA,IAAc;AACvC,QAAA,IAAI;AACF,UAAA,QAAA,CAAS,YAAA,CAAa,EAAE,OAAA,EAAwC,CAAA;AAAA,QAClE,SAAS,GAAA,EAAK;AACZ,UAAA,OAAA,CAAQ,KAAA;AAAA,YACN,CAAA,cAAA,EAAiB,cAAc,OAAO,CAAA,oBAAA,CAAA;AAAA,YACtC;AAAA,WACF;AAAA,QACF;AAAA,MACF;AACA,MAAA,KAAA,MAAW,CAAA,IAAK,cAAA,EAAe,EAAG,CAAA,CAAE,UAAU,QAAQ,CAAA;AAAA,IACxD;AACA,IAAA,aAAA,CAAc,UAAU,UAAA,CAAW,MAAA;AAAA,EACrC,CAAC,CAAA;AAED,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAI,QAAA,GAAW,KAAA;AAKf,IAAA,IAAI,QAAA,GAA0B,IAAA;AAG9B,IAAA,MAAM,SAAS,MAA4B;AACzC,MAAA,IAAI,QAAA,KAAa,IAAA,EAAM,OAAO,aAAA,CAAc,OAAA;AAC5C,MAAA,OAAO,QAAA,CAAS,OAAA,EAAS,OAAA,EAAQ,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,QAAQ,CAAA,IAC3D,aAAA,CAAc,OAAA;AAAA,IACrB,CAAA;AAIA,IAAA,MAAM,OAAA,GAAU,CAAC,SAAA,EAA0B,OAAA,EAAiB,OAAA,KAA0B;AACpF,MAAA,QAAA,GAAW,QAAA,CAAS,SAAS,QAAA,CAAS,EAAA,CAAG,WAAW,OAAA,EAAS,OAAO,EAAE,EAAA,IAAM,IAAA;AAAA,IAC9E,CAAA;AAEA,IAAA,MAAM,SAAA,GAAY,CAAC,SAAA,EAAmB,OAAA,EAAiB,OAAA,KAA0B;AAC/E,MAAA,QAAA,GAAW,QAAA,CAAS,SAAS,QAAA,CAAS,KAAA,CAAM,WAAW,OAAA,EAAS,OAAO,EAAE,EAAA,IAAM,IAAA;AAAA,IACjF,CAAA;AACA,IAAA,MAAM,YAAA,GAAe,CAAC,SAAA,KAA4B;AAChD,MAAA,QAAA,CAAS,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AAAA,IAC1C,CAAA;AAIA,IAAA,MAAM,aAAA,GAAgB,MAAkB,MAAA,EAAO,CAAE,UAAA;AAEjD,IAAA,MAAM,UAAA,GAAa,YAAA,CAAa,MAAM,MAAA,CAAO,OAAA,CAAQ,aAAa,MAAM,MAAA,EAAO,CAAE,IAAA,IAAQ,CAAA;AAGzF,IAAA,MAAM,aAAA,GAAgB,MACpB,MAAA,EAAO,CAAE,UAAA,IAAa;AACxB,IAAA,MAAM,SAAS,OAA0B;AAAA,MACvC,GAAG,MAAA,CAAO,OAAA;AAAA,MAAS,WAAA,EAAa,UAAA;AAAA,MAAY,UAAA,EAAY;AAAA,KAC1D,CAAA;AACA,IAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AAQzB,IAAA,MAAM,OAAA,GAAU,CAAC,EAAA,EAAY,EAAA,KAAyC;AACpE,MAAA,MAAM,EAAA,GAAK,QAAO,CAAE,aAAA;AACpB,MAAA,OAAO,EAAA,GAAK,GAAG,EAAA,EAAI,EAAE,IAAI,EAAE,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAG;AAAA,IAC1C,CAAA;AAYA,IAAA,MAAM,QAAA,GAAW,CAAC,EAAA,EAAgB,EAAA,KAA6C;AAC7E,MAAA,MAAM,CAAA,GAAI,MAAM,aAAA,EAAc;AAC9B,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,QAAA,EAAS,CAAE,IAAA;AAC5B,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,WAAA,CAAY,EAAA,EAAI,QAAQ,CAAA;AACzC,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,QAAA,EAAS,CAAE,IAAA;AAC3B,MAAA,IAAI,MAAA,GAAS,CAAA,IAAK,KAAA,GAAQ,CAAA,mBAAoB,OAAA,IAAU;AACxD,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAIA,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AAKjC,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAyB;AAK1C,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA0D;AAC/E,MAAA,MAAM,IAAA,GAAO,QAAQ,qBAAA,EAAsB;AAC3C,MAAA,IAAI,CAAC,MAAM,OAAO,CAAA;AAClB,MAAA,MAAM,CAAC,GAAG,CAAC,CAAA,GAAI,mBAAmB,IAAA,EAAM,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA;AAChD,MAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAAA,IAChB,CAAA;AACA,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,yBAAA;AAAA,QAC3B,CAAC,GAAG,IAAA,CAAK,MAAA,EAAQ,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG;AAAA,OACrC;AACA,MAAA,OAAO,EAAE,QAAA,EAAU,aAAA,CAAc,QAAQ,GAAG,MAAA,EAAO;AAAA,IACrD,CAAA;AAKA,IAAA,IAAI,eAAA,GAAkF,IAAA;AACtF,IAAA,MAAM,gBAAA,GAAmB,CAAA;AAOzB,IAAA,MAAM,iBAAA,GAAoB,CAAA;AAK1B,IAAA,MAAM,aAAA,GAAgB,GAAA;AACtB,IAAA,MAAM,eAAA,uBAAsB,GAAA,EAA2C;AAEvE,IAAA,MAAM,eAAA,GAAkB,CAAC,SAAA,KAA4B;AACnD,MAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,GAAA,CAAI,SAAS,CAAA;AACvC,MAAA,IAAI,MAAM,MAAA,EAAW;AACnB,QAAA,YAAA,CAAa,CAAC,CAAA;AACd,QAAA,eAAA,CAAgB,OAAO,SAAS,CAAA;AAAA,MAClC;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,qBAAqB,MAAY;AACrC,MAAA,KAAA,MAAW,CAAA,IAAK,eAAA,CAAgB,MAAA,EAAO,eAAgB,CAAC,CAAA;AACxD,MAAA,eAAA,CAAgB,KAAA,EAAM;AAAA,IACxB,CAAA;AAKA,IAAA,MAAM,aAAA,GAAgB,CAAC,SAAA,KAA4B;AACjD,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA,EAAG,IAAA;AAClC,MAAA,IAAI,CAAC,IAAA,EAAM;AAEX,MAAA,MAAM,MAAA,GAAS;AAAA,QACb,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,QACvE,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,QACvE,GAAI,KAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS,GAAI;AAAC,OACnE;AAEA,MAAA,MAAM,SAAS,QAAA,CAAS;AAAA,QACtB,IAAA,EAAM,WAAA;AAAA,QACN,GAAG,IAAA,CAAK,MAAA;AAAA,QACR,GAAG,IAAA,CAAK,MAAA;AAAA,QACR,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,GAAG;AAAA,OACU,CAAA;AAEf,MAAA,IAAI,WAAW,WAAA,EAAa;AAC1B,QAAA,QAAA,CAAS;AAAA,UACP,IAAA,EAAM,aAAA;AAAA,UACN,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,GAAG;AAAA,SACU,CAAA;AAAA,MACjB;AAAA,IACF,CAAA;AAMA,IAAA,MAAM,mBAAA,GAAsB,GAAA;AAC5B,IAAA,MAAM,mBAAA,GAAsB,CAAA;AAM5B,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAqB;AACtC,MAAA,IAAI,gBAAA,CAAiB,CAAA,CAAE,MAAM,CAAA,EAAG;AAQhC,MAAA,IAAI,EAAE,MAAA,IAAU,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,EAAG;AACnC,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA;AAAA,MACF;AAOA,MAAA,MAAM,KAAA,GAAoB;AAAA,QACxB,IAAA,EAAM,KAAA;AAAA,QACN,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,QAAQ,CAAA,CAAE;AAAA,OACZ;AACA,MAAA,MAAM,SAAA,GAAY,SAAS,KAAK,CAAA;AAMhC,MAAA,MAAM,MAAA,GAAqB;AAAA,QACzB,IAAA,EAAM,UAAA;AAAA,QACN,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,KAAA,EAAO,MAAA;AAAA,QACP,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE;AAAA,OACd;AACA,MAAA,MAAM,UAAA,GAAa,SAAS,MAAM,CAAA;AAElC,MAAA,IAAI,eAAe,SAAA,EAAW;AAC5B,QAAA,QAAA,CAAS,GAAA,CAAI,EAAE,GAAG,CAAA;AAAA,MACpB;AAEA,MAAA,IAAI,SAAA,KAAc,SAAA,IAAa,UAAA,KAAe,SAAA,EAAW;AACvD,QAAA,CAAA,CAAE,cAAA,EAAe;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAqB;AACpC,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,EAAG;AAC1B,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,UAAA;AAAA,QACN,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,KAAA,EAAO,IAAA;AAAA,QACP,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE;AAAA,OACd;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,QAAA,CAAS,MAAA,CAAO,EAAE,GAAG,CAAA;AAAA,IACvB,CAAA;AAMA,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAC,GAAG,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAO;AACrD,MAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,QAAA,MAAM,EAAA,GAAiB;AAAA,UACrB,IAAA,EAAM,UAAA;AAAA,UACN,GAAA;AAAA,UACA,KAAA,EAAO,IAAA;AAAA,UACP,MAAA,EAAQ,KAAA;AAAA,UACR,OAAA,EAAS,KAAA;AAAA,UACT,OAAA,EAAS,KAAA;AAAA,UACT,QAAA,EAAU;AAAA,SACZ;AACA,QAAA,QAAA,CAAS,EAAE,CAAA;AAAA,MACb;AACA,MAAA,QAAA,CAAS,KAAA,EAAM;AAAA,IACjB,CAAA;AAMA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAkB;AACjC,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAKlC,MAAA,MAAM,IAAA,GAAO,QAAQ,qBAAA,EAAsB;AAC3C,MAAA,MAAM,CAAC,MAAA,EAAQ,MAAM,CAAA,GAAI,IAAA,GACrB,mBAAmB,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA,GAC7C,CAAC,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACzB,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAC7C,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,QAAQ,CAAA,IAAK,MAAA;AACxD,MAAA,MAAM,IAAA,GAAO,MAAA,EAAO,CAAE,cAAA,GAAiB,QAAQ,CAAA;AAC/C,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,OAAA;AAAA,QACN,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,OAAA,EAAS,MAAA;AAAA,QACT,OAAA,EAAS,MAAA;AAAA,QACT,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,IAAA,EAAK,GAAI,EAAC;AAAA,QAC5D,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,IAAA,EAAK,GAAI;AAAC,OAC5D;AACA,MAAA,MAAM,MAAA,GAAS,SAAS,EAAE,CAAA;AAK1B,MAAA,IAAI,WAAW,SAAA,EAAW;AACxB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,CAAA,CAAE,eAAA,EAAgB;AAAA,MACpB;AAAA,IACF,CAAA;AAMA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAoB;AASzC,MAAA,IAAA,CAAK,CAAA,CAAE,MAAA,IAAU,CAAA,MAAO,CAAA,EAAG;AAC3B,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,SAAA,CAAU,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAE3C,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACtC,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,CAAC,CAAA,IAAK,MAAA;AACjD,MAAA,MAAM,IAAA,GAAO,MAAA,EAAO,CAAE,cAAA,GAAiB,CAAC,CAAA;AACxC,MAAA,MAAM,aAAa,IAAA,EAAM,IAAA;AACzB,MAAA,MAAM,WAAW,IAAA,EAAM,IAAA;AACvB,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,aAAA;AAAA,QACN,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAG,SAAS,CAAC,CAAA;AAAA,QACb,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,KAAa;AAAC,OAC/C;AAMA,MAAA,IAAA,CAAK,GAAA,CAAI,EAAE,SAAA,EAAW;AAAA,QACpB,OAAA,EAAS,kBAAA,CAAmB,MAAA,EAAQ,CAAA,EAAG;AAAA,UACrC,MAAA,EAAQ,aAAA;AAAA,UACR,KAAA,EAAO,WAAA;AAAA,UACP,UAAU,MAAM;AAAE,YAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAAA,UAAG;AAAA,SACjD,CAAA;AAAA,QACD,KAAK,EAAE,CAAA,EAAG,EAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA,EAAQ;AAAA;AAAA;AAAA,QAGlC,QAAA,EAAU,EAAE,EAAA,EAAI,OAAA,EAAS,EAAE,OAAA,EAAS,OAAA,EAAS,EAAE,OAAA,EAAQ;AAAA,QACvD,IAAA,EAAM;AAAA,UACJ,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,QAAQ,CAAA,CAAE,CAAA;AAAA,UACV,QAAQ,CAAA,CAAE,CAAA;AAAA,UACV,UAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE;AAAA;AACd,OACD,CAAA;AAYD,MAAA,IAAI,IAAA,CAAK,OAAO,CAAA,EAAG,QAAA,CAAS,EAAE,GAAG,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,CAAA;AAIrD,MAAA,IAAA,CAAK,CAAA,CAAE,gBAAgB,OAAA,IAAW,CAAA,CAAE,gBAAgB,KAAA,KAC7C,IAAA,CAAK,SAAS,CAAA,EAAG;AACtB,QAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAC3B,QAAA,eAAA,CAAgB,GAAA;AAAA,UACd,CAAA,CAAE,SAAA;AAAA,UACF,WAAW,MAAM;AACf,YAAA,eAAA,CAAgB,MAAA,CAAO,EAAE,SAAS,CAAA;AAClC,YAAA,IAAI,QAAA,EAAU;AACd,YAAA,aAAA,CAAc,EAAE,SAAS,CAAA;AAAA,UAC3B,GAAG,aAAa;AAAA,SAClB;AAAA,MACF;AAGA,MAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,EAAG;AAClB,QAAA,kBAAA,EAAmB;AAkBnB,QAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,MAAA,EAAO,IAAK,QAAA,GAAW,IAAA;AAE5C,QAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,YAAA,EAAa;AAI1C,QAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,UAAA,eAAA,GAAkB,EAAE,SAAS,IAAA,CAAK,IAAA,EAAM,UAAU,EAAE,GAAG,UAAS,EAAE;AAAA,QACpE,CAAA,MAAO;AACL,UAAA,eAAA,CAAgB,UAAU,IAAA,CAAK,IAAA;AAAA,QACjC;AACA,QAAA,MAAM,EAAA,GAAiB;AAAA,UACrB,IAAA,EAAM,YAAA;AAAA,UACN,SAAS,IAAA,CAAK,IAAA;AAAA,UACd,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,QAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,QAAA,CAAS,EAAE,CAAA;AAAA,MACb;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAoB;AACzC,MAAA,OAAA,CAAQ,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACzC,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AAChC,MAAA,IAAI,GAAA,MAAS,GAAA,GAAM,EAAE,GAAG,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,CAAA,CAAE,OAAA,EAAQ;AAUhD,MAAA,MAAM,WAAW,GAAA,EAAK,QAAA;AACtB,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,GAAU,QAAA,CAAS,OAAA;AAChC,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,GAAU,QAAA,CAAS,OAAA;AAChC,QAAA,IAAI,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,KAAK,iBAAA,EAAmB;AAC3C,UAAA,GAAA,CAAI,QAAA,GAAW,IAAA;AACf,UAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAC3B,UAAA,QAAA,CAAS,SAAS,EAAE,CAAA;AAAA,QACtB;AAAA,MACF;AAKA,MAAA,MAAM,WAAA,GAAc,CAAA,WAAA,EAAc,IAAA,CAAK,IAAI,CAAA,CAAA;AAC3C,MAAA,IAAI,IAAA,CAAK,QAAQ,CAAA,IAAK,aAAA,GAAgB,QAAA,EAAS,CAAE,GAAA,CAAI,WAAW,CAAA,EAAG;AACjE,QAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAO,GAAI,YAAA,EAAa;AAC1C,QAAA,MAAM,IAAA,GAAmB;AAAA,UACvB,IAAA,EAAM,YAAA;AAAA,UACN,SAAS,IAAA,CAAK,IAAA;AAAA,UACd,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,QAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MAEf;AAEA,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACtC,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,aAAA;AAAA,QACN,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,GAAG,CAAA,CAAE,CAAA;AAAA,QACL,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAG,SAAS,CAAC;AAAA,OACf;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AAEX,MAAA,SAAA,GAAY;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAC/B,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,kBAAA,EAAmB;AAAA,IACrB,CAAA;AA+BA,IAAA,IAAI,SAAA,GAGO,IAAA;AACX,IAAA,IAAI,gBAAA,GAAmB,KAAA;AACvB,IAAA,MAAM,mBAAmB,MAAM;AAC7B,MAAA,gBAAA,CAAiB,OAAA,IAAU,EAAG,WAAA,CAAY,IAAI,CAAA;AAC9C,MAAA,IAAI,oBAAoB,MAAA,EAAQ;AAC9B,QAAA,MAAA,CAAO,MAAM,MAAA,GAAS,EAAA;AACtB,QAAA,gBAAA,GAAmB,KAAA;AAAA,MACrB;AAAA,IACF,CAAA;AACA,IAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAA4B;AACpD,MAAA,MAAM,IAAA,GAAO,IAAA,KAAS,IAAA,GAAO,IAAA,GAAO,kBAAkB,IAAI,CAAA;AAC1D,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ;AACpB,QAAA,gBAAA,EAAiB;AACjB,QAAA;AAAA,MACF;AAIA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,KAAS,SAAA,GAAY,IAAA,GAAO,IAAA;AACjD,MAAA,gBAAA,CAAiB,OAAA,IAAU,EAAG,WAAA,CAAY,OAAO,CAAA;AACjD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,KAAS,KAAA,GAAQ,KAAK,GAAA,GAAM,MAAA;AAChD,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,gBAAA,EAAiB;AACjB,QAAA;AAAA,MACF;AACA,MAAA,MAAA,CAAO,MAAM,MAAA,GAAS,MAAA;AACtB,MAAA,gBAAA,GAAmB,IAAA;AAAA,IACrB,CAAA;AASA,IAAA,SAAS,kBAAA,GAA2B;AAClC,MAAA,MAAM,OAAA,GAAU,iBAAiB,OAAA,IAAU;AAC3C,MAAA,IAAI,CAAC,OAAA,EAAS,MAAA,MAAY,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW;AACjD,MAAA,MAAM,CAAA,GAAI,OAAO,qBAAA,EAAsB;AACvC,MAAA,OAAA,CAAQ,UAAA,CAAW,UAAU,OAAA,GAAU,CAAA,CAAE,MAAM,SAAA,CAAU,OAAA,GAAU,EAAE,GAAG,CAAA;AAAA,IAC1E;AAEA,IAAA,SAAS,kBAAA,GAA2B;AAClC,MAAA,kBAAA,EAAmB;AACnB,MAAA,kBAAA,EAAmB;AAAA,IACrB;AAEA,IAAA,SAAS,kBAAA,GAA2B;AAClC,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,SAAA,EAAW;AAK3B,MAAA,IAAI,IAAA,CAAK,OAAO,CAAA,IAAK,aAAA,GAAgB,QAAA,EAAS,CAAE,OAAO,CAAA,EAAG;AACxD,QAAA,gBAAA,CAAiB,aAAA,EAAc,CAAE,cAAA,EAAgB,CAAA;AACjD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,CAAA,GAAI,SAAA;AAGV,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAClC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACtC,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,CAAC,CAAA,IAAK,MAAA;AACjD,MAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,QAAA,gBAAA,CAAiB,WAAW,MAAM,CAAA;AAClC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAA,GAAY,MAAA,EAAO,CAAE,cAAA,GAAiB,CAAC,CAAA;AAC7C,MAAA,MAAM,aAAa,SAAA,EAAW,IAAA;AAC9B,MAAA,MAAM,WAAW,SAAA,EAAW,IAAA;AAC5B,MAAA,MAAM,KAAA,GAAQ;AAAA,QACZ,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,KAAa;AAAC,OAC/C;AACA,MAAA,MAAM,MAAM,MAAA,EAAO;AACnB,MAAA,MAAM,UAAA,GAAa,eAAc,CAAE,WAAA;AAAA,QACjC,EAAE,IAAA,EAAM,aAAA,EAAe,CAAA,EAAG,CAAA,CAAE,GAAG,CAAA,EAAG,CAAA,CAAE,CAAA,EAAG,OAAA,EAAS,EAAE,OAAA,EAAS,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,GAAG,KAAA,EAAM;AAAA,QACxF;AAAA,SACC,MAAA,CAAO,MAAA;AAEV,MAAA,MAAM,MAAA,GAAS,UAAA,IAAc,aAAA,EAAc,CAAE,WAAA;AAAA,QAC3C,EAAE,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,CAAA,CAAE,GAAG,MAAA,EAAQ,CAAA,CAAE,CAAA,EAAG,MAAA,EAAQ,EAAE,CAAA,EAAG,MAAA,EAAQ,CAAA,CAAE,CAAA,EAAG,GAAG,KAAA,EAAM;AAAA,QAC9E;AAAA,SACC,MAAA,CAAO,MAAA;AACV,MAAA,gBAAA,CAAiB,UAAU,IAAI,CAAA;AAAA,IACjC;AAIA,IAAA,MAAM,0BAAA,GAA6B,CAAC,CAAA,KAAqB;AACvD,MAAA,IAAI,CAAC,SAAA,EAAW;AAChB,MAAA,SAAA,GAAY;AAAA,QACV,GAAG,SAAA;AAAA,QACH,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,IAAI,CAAC,UAAU,kBAAA,EAAmB;AAAA,MACpC,GAAG,CAAC,CAAA;AAAA,IACN,CAAA;AAIA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAoB;AACvC,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,EAAG;AAC3B,MAAA,aAAA,CAAc,CAAC,CAAA;AAAA,IACjB,CAAA;AAEA,IAAA,MAAM,sBAAsB,MAAM;AAChC,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,gBAAA,CAAiB,OAAA,MAAa,YAAA,EAAa;AAC3C,MAAA,gBAAA,EAAiB;AAAA,IACnB,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAoB;AACvC,MAAA,OAAA,CAAQ,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACzC,MAAA,eAAA,CAAgB,EAAE,SAAS,CAAA;AAC3B,MAAA,MAAM,WAAW,IAAA,CAAK,IAAA;AAItB,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AAChC,MAAA,IAAA,CAAK,MAAA,CAAO,EAAE,SAAS,CAAA;AAOvB,MAAA,MAAM,mBAAA,GAAsB,KAAK,QAAA,IAAY,IAAA;AAO7C,MAAA,IAAI,QAAA,IAAY,CAAA,IAAK,IAAA,CAAK,IAAA,GAAO,CAAA,EAAG;AAClC,QAAA,MAAM,WAAA,GAAc,cAAc,QAAQ,CAAA,CAAA;AAC1C,QAAA,IAAI,eAAc,CAAE,QAAA,EAAS,CAAE,GAAA,CAAI,WAAW,CAAA,EAAG;AAO/C,UAAA,aAAA,EAAc,CAAE,UAAU,QAAQ,CAAA;AAAA,QACpC;AAEA,QAAA,MAAM,KAAA,GAAQ,eAAA;AACd,QAAA,IAAI,KAAA,EAAO;AAGT,UAAA,MAAM,QAAA,GAAW,aAAA;AAAA,YACf,yBAAA,CAA0B;AAAA,cACxB,GAAG,CAAC,GAAG,IAAA,CAAK,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA;AAAA,cACtC,EAAE,CAAA,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG,EAAE,OAAA;AAAQ,aAC9B,CAAA,CAAE;AAAA,WACL;AACA,UAAA,MAAM,EAAA,GAAK,QAAA,CAAS,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACvC,UAAA,MAAM,EAAA,GAAK,QAAA,CAAS,CAAA,GAAI,KAAA,CAAM,QAAA,CAAS,CAAA;AACvC,UAAA,IAAI,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,KAAK,gBAAA,EAAkB;AAC1C,YAAA,MAAM,GAAA,GAAkB;AAAA,cACtB,IAAA,EAAM,eAAA;AAAA,cACN,SAAS,KAAA,CAAM,OAAA;AAAA,cACf,QAAQ,CAAA,CAAE,MAAA;AAAA,cACV,SAAS,CAAA,CAAE,OAAA;AAAA,cACX,SAAS,CAAA,CAAE,OAAA;AAAA,cACX,UAAU,CAAA,CAAE;AAAA,aACd;AACA,YAAA,QAAA,CAAS,GAAG,CAAA;AAAA,UACd;AACA,UAAA,eAAA,GAAkB,IAAA;AAAA,QACpB;AAAA,MACF;AASA,MAAA,MAAM,eAAA,GAAkB,GAAA,GACnB,GAAA,CAAI,IAAA,CAAK,OAAA,KAAY,CAAA,CAAE,OAAA,IAAW,GAAA,CAAI,IAAA,CAAK,OAAA,KAAY,CAAA,CAAE,OAAA,GAC1D,IAAA;AACJ,MAAA,MAAM,eAAA,GACJ,aAAA,EAAc,CAAE,QAAA,EAAS,CAAE,IAAI,gBAAA,CAAiB,CAAA,CAAE,SAAS,CAAC,CAAA,IAAK,eAAA;AAEnE,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AACxC,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,WAAA;AAAA,QACN,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,GAAG,GAAA,CAAI,CAAA;AAAA,QACP,GAAG,GAAA,CAAI,CAAA;AAAA,QACP,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE;AAAA,OACd;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AAEX,MAAA,MAAM,OAAO,GAAA,EAAK,IAAA;AAalB,MAAA,IAAI,CAAC,eAAA,IAAmB,mBAAA,IAAuB,IAAA,EAAM;AACnD,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAC3C,QAAA,MAAM,OAAA,GAAsB;AAAA,UAC1B,IAAA,EAAM,OAAA;AAAA,UACN,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,SAAS,CAAA,CAAE,OAAA;AAAA,UACX,UAAU,CAAA,CAAE,QAAA;AAAA,UACZ,QAAQ,MAAA,CAAO,CAAA;AAAA,UACf,QAAQ,MAAA,CAAO,CAAA;AAAA,UACf,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,UACvE,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,UACvE,GAAI,KAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS,GAAI;AAAC,SACnE;AACA,QAAA,QAAA,CAAS,OAAO,CAAA;AAOhB,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,QAAA,MAAM,OAAO,YAAA,CAAa,OAAA;AAC1B,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,IAAW,IAAA,EAAM,OAAA,IAAW,CAAA,CAAA;AACzC,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,OAAA,IAAW,IAAA,EAAM,OAAA,IAAW,CAAA,CAAA;AACzC,QAAA,IAAI,IAAA,IAAQ,GAAA,GAAM,IAAA,CAAK,CAAA,GAAI,mBAAA,IAAuB,KAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,GAAI,mBAAA,EAAqB;AAC1F,UAAA,MAAM,KAAA,GAAoB;AAAA,YACxB,IAAA,EAAM,aAAA;AAAA,YACN,QAAQ,CAAA,CAAE,MAAA;AAAA,YACV,QAAQ,CAAA,CAAE,MAAA;AAAA,YACV,SAAS,CAAA,CAAE,OAAA;AAAA,YACX,SAAS,CAAA,CAAE,OAAA;AAAA,YACX,UAAU,CAAA,CAAE,QAAA;AAAA,YACZ,QAAQ,MAAA,CAAO,CAAA;AAAA,YACf,QAAQ,MAAA,CAAO,CAAA;AAAA,YACf,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,YACvE,GAAI,KAAK,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,IAAA,CAAK,UAAA,EAAW,GAAI,EAAC;AAAA,YACvE,GAAI,KAAK,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,IAAA,CAAK,QAAA,EAAS,GAAI;AAAC,WACnE;AAGA,UAAA,gBAAA,CAAiB,OAAA,GAAU,EAAE,CAAA,EAAG,MAAA,CAAO,GAAG,CAAA,EAAG,MAAA,CAAO,GAAG,CAAA;AACvD,UAAA,QAAA,CAAS,KAAK,CAAA;AACd,UAAA,YAAA,CAAa,OAAA,GAAU,IAAA;AAAA,QACzB,CAAA,MAAO;AACL,UAAA,YAAA,CAAa,OAAA,GAAU,EAAE,CAAA,EAAG,GAAA,EAAK,SAAS,CAAA,CAAE,OAAA,EAAS,OAAA,EAAS,CAAA,CAAE,OAAA,EAAQ;AAAA,QAC1E;AAAA,MACF;AAIA,MAAA,YAAA,CAAa,EAAE,SAAS,CAAA;AAKxB,MAAA,SAAA,GAAY;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAC/B,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,UAAA,CAAW,MAAM;AACf,QAAA,IAAI,CAAC,UAAU,kBAAA,EAAmB;AAAA,MACpC,GAAG,CAAC,CAAA;AAAA,IACN,CAAA;AAOA,IAAA,MAAM,eAAA,GAAkB,CAAC,SAAA,KAAsB;AAG7C,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA;AAC9B,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,IAAA,CAAK,OAAO,SAAS,CAAA;AACrB,MAAA,OAAA,CAAQ,WAAW,GAAA,CAAI,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,IAAI,CAAC,CAAA;AACvC,MAAA,eAAA,CAAgB,SAAS,CAAA;AAGzB,MAAA,eAAA,GAAkB,IAAA;AAClB,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,eAAA;AAAA,QACN,SAAA;AAAA,QACA,MAAA,EAAQ,IAAI,IAAA,CAAK,MAAA;AAAA,QACjB,OAAA,EAAS,IAAI,IAAA,CAAK,OAAA;AAAA,QAClB,OAAA,EAAS,IAAI,IAAA,CAAK,OAAA;AAAA,QAClB,QAAA,EAAU,IAAI,IAAA,CAAK;AAAA,OACrB;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AACX,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB,CAAA;AAMA,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAAkB;AAEvC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAClC,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAGtC,MAAA,MAAM,UAAA,GAAa,MAAA,EAAO,CAAE,YAAA,GAAe,CAAC,CAAA,IAAK,MAAA;AACjD,MAAA,MAAM,QAAA,GAAW,MAAA,EAAO,CAAE,cAAA,GAAiB,CAAC,CAAA;AAC5C,MAAA,MAAM,EAAA,GAAiB;AAAA,QACrB,IAAA,EAAM,aAAA;AAAA,QACN,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,QAAQ,CAAA,CAAE,CAAA;AAAA,QACV,QAAQ,CAAA,CAAE,CAAA;AAAA,QACV,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,QACjD,GAAI,UAAU,IAAA,KAAS,MAAA,GAAY,EAAE,UAAA,EAAY,QAAA,CAAS,IAAA,EAAK,GAAI,EAAC;AAAA,QACpE,GAAI,UAAU,IAAA,KAAS,MAAA,GAAY,EAAE,QAAA,EAAU,QAAA,CAAS,IAAA,EAAK,GAAI;AAAC,OACpE;AACA,MAAA,QAAA,CAAS,EAAE,CAAA;AAAA,IACb,CAAA;AAWA,IAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAiB;AACnC,MAAA,IAAI,CAAC,EAAE,YAAA,EAAc;AAErB,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,CAAA,CAAE,aAAa,UAAA,GAAa,MAAA;AAC5B,MAAA,MAAA,EAAQ,SAAA,CAAU,IAAI,cAAc,CAAA;AAAA,IACtC,CAAA;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,MAAA,EAAQ,SAAA,CAAU,OAAO,cAAc,CAAA;AAAA,IACzC,CAAA;AAMA,IAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAiB;AAC/B,MAAA,MAAA,EAAQ,SAAA,CAAU,OAAO,cAAc,CAAA;AACvC,MAAA,MAAM,KAAK,CAAA,CAAE,YAAA;AACb,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,OAAO,CAAA;AAClC,MAAA,MAAM,MAAA,GAAS,QAAO,CAAE,UAAA;AACxB,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAItC,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,QAAQ,CAAA,CAAE,MAAA;AAAA,QAAQ,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,SAAS,CAAA,CAAE,OAAA;AAAA,QAAS,UAAU,CAAA,CAAE;AAAA,OACxE;AACA,MAAA,KAAK,qBAAA,CAAsB,EAAE,CAAA,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU;AAC7C,QAAA,IAAI,QAAA,EAAU;AACd,QAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,QAAA,QAAA,CAAS;AAAA,UACP,IAAA,EAAM,MAAA;AAAA,UAAQ,KAAA;AAAA,UACd,GAAG,CAAA,CAAE,CAAA;AAAA,UAAG,GAAG,CAAA,CAAE,CAAA;AAAA,UAAG,SAAS,CAAA,CAAE,OAAA;AAAA,UAAS,SAAS,CAAA,CAAE,OAAA;AAAA,UAC/C,GAAG;AAAA,WACF,MAAM,CAAA;AAAA,MACX,CAAC,CAAA;AAAA,IACH,CAAA;AAEA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAsB;AAGrC,MAAA,IAAI,gBAAA,CAAiB,CAAA,CAAE,MAAM,CAAA,EAAG;AAChC,MAAA,MAAM,KAAK,CAAA,CAAE,aAAA;AACb,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,MAAM,KAAA,GAAQ,uBAAuB,EAAE,CAAA;AACvC,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAKxB,MAAA,MAAM,SAAS,QAAA,CAAS;AAAA,QACtB,IAAA,EAAM,OAAA;AAAA,QAAS,KAAA;AAAA;AAAA,QAEf,MAAA,EAAQ,KAAA;AAAA,QAAO,OAAA,EAAS,KAAA;AAAA,QAAO,OAAA,EAAS,KAAA;AAAA,QAAO,QAAA,EAAU;AAAA,OAC1D,CAAA;AACD,MAAA,IAAI,MAAA,KAAW,SAAA,EAAW,CAAA,CAAE,cAAA,EAAe;AAAA,IAC7C,CAAA;AAMA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC5C,MAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,OAAO,CAAA;AAAA,IAC1C;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,QAAQ,YAAY,CAAA;AAI5C,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,0BAA0B,CAAA;AAC7D,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,0BAA0B,CAAA;AAC3D,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,MAAA,EAAQ,gBAAA,CAAiB,gBAAgB,mBAAmB,CAAA;AAC5D,MAAA,MAAA,EAAQ,gBAAA,CAAiB,eAAe,aAAa,CAAA;AACrD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,eAAe,WAAW,CAAA;AAAA,IACrD;AACA,IAAA,IAAI,YAAA,UAAsB,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,OAAA,EAAS,OAAO,CAAA;AAC/E,IAAA,IAAI,kBAAA,EAAoB,MAAA,EAAQ,gBAAA,CAAiB,aAAA,EAAe,aAAa,CAAA;AAC7E,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,MAAA,EAAQ,gBAAA,CAAiB,aAAa,UAAU,CAAA;AAChD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,YAAY,UAAU,CAAA;AAC/C,MAAA,MAAA,EAAQ,gBAAA,CAAiB,aAAa,WAAW,CAAA;AACjD,MAAA,MAAA,EAAQ,gBAAA,CAAiB,QAAQ,MAAM,CAAA;AACvC,MAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,OAAO,CAAA;AAAA,IAC1C;AAMA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAC/C,QAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAAA,MAC7C;AACA,MAAA,MAAA,CAAO,mBAAA,CAAoB,QAAQ,YAAY,CAAA;AAC/C,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,0BAA0B,CAAA;AAChE,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,0BAA0B,CAAA;AAC9D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,gBAAgB,mBAAmB,CAAA;AAC/D,MAAA,MAAA,EAAQ,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAC5C,MAAA,MAAA,EAAQ,mBAAA,CAAoB,eAAe,aAAa,CAAA;AACxD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,eAAe,WAAW,CAAA;AACtD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,eAAe,aAAa,CAAA;AACxD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,aAAa,UAAU,CAAA;AACnD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,YAAY,UAAU,CAAA;AAClD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,aAAa,WAAW,CAAA;AACpD,MAAA,MAAA,EAAQ,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAC1C,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAG3C,MAAA,MAAA,EAAQ,SAAA,CAAU,OAAO,cAAc,CAAA;AACvC,MAAA,gBAAA,EAAiB;AACjB,MAAA,kBAAA,EAAmB;AACnB,MAAA,QAAA,GAAW,IAAA;AAGX,MAAA,KAAA,MAAW,KAAK,IAAA,CAAK,MAAA,EAAO,EAAG,CAAA,CAAE,QAAQ,MAAA,EAAO;AAChD,MAAA,IAAA,CAAK,KAAA,EAAM;AACX,MAAA,KAAA,MAAW,CAAA,IAAK,cAAA,EAAe,EAAG,CAAA,CAAE,UAAU,QAAQ,CAAA;AAAA,IACxD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,QAAA,EAAU,WAAW,cAAA,EAAgB,YAAA,EAAc,kBAAA,EAAoB,aAAa,CAAC,CAAA;AACpG;ACx/CA,IAAM,cAAA,GAAiBL,cAAsC,IAAI,CAAA;AAYjE,SAAS,SAAS,IAAA,EAAmD;AACnE,EAAA,MAAM,QAAA,GAAWI,MAAAA,iBAA4B,IAAI,GAAA,EAAK,CAAA;AACtD,EAAA,MAAM,YAAA,GAAeA,MAAAA,iBAAwB,IAAI,GAAA,EAAK,CAAA;AACtD,EAAA,MAAM,QAAA,GAAWA,OAAkE,IAAI,CAAA;AAEvF,EAAA,OAAOH,QAAgC,MAAM;AAC3C,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,MAAM,UAAU,CAAC,EAAA,KAAwB,QAAA,CAAS,OAAA,CAAQ,IAAI,EAAE,CAAA;AAChE,IAAA,MAAM,SAAS,MAAY;AACzB,MAAA,KAAA,MAAW,CAAA,IAAK,aAAa,OAAA,EAAS;AACpC,QAAA,IAAI;AACF,UAAA,CAAA,EAAE;AAAA,QACJ,SAAS,GAAA,EAAK;AACZ,UAAA,OAAA,CAAQ,KAAA,CAAM,4CAA4C,GAAG,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,CAAA;AACA,IAAA,OAAO;AAAA,MACL,GAAG,IAAA;AAAA,MACH,MAAM,MAAM;AACV,QAAA,MAAM,GAAA,GAAM,KAAK,IAAA,EAAK;AACtB,QAAA,IAAI,QAAA,CAAS,OAAA,CAAQ,IAAA,KAAS,CAAA,EAAG,OAAO,GAAA;AACxC,QAAA,MAAM,SAAS,QAAA,CAAS,OAAA;AACxB,QAAA,IAAI,MAAA,IAAU,MAAA,CAAO,GAAA,KAAQ,GAAA,SAAY,MAAA,CAAO,GAAA;AAChD,QAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,OAAO,CAAC,CAAA,KAAM,CAAC,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAC,CAAA;AACxE,QAAA,QAAA,CAAS,OAAA,GAAU,EAAE,GAAA,EAAK,GAAA,EAAI;AAC9B,QAAA,OAAO,GAAA;AAAA,MACT,CAAA;AAAA,MACA,OAAA,EAAS,CAAC,EAAA,EAAI,MAAA,KAAY,OAAA,CAAQ,EAAE,CAAA,GAAI,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,EAAA,EAAI,MAAM,CAAA;AAAA,MACvE,KAAA,EAAO,CAAC,EAAA,EAAI,MAAA,KAAY,OAAA,CAAQ,EAAE,CAAA,GAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,MAAM,CAAA;AAAA,MAClE,SAAA,EAAW,CAAC,QAAA,KAAa;AACvB,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AACvC,QAAA,YAAA,CAAa,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACjC,QAAA,OAAO,MAAM;AACX,UAAA,OAAA,EAAQ;AACR,UAAA,YAAA,CAAa,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAAA,QACtC,CAAA;AAAA,MACF,CAAA;AAAA,MACA,IAAA,EAAM,CAAC,EAAA,KAAe;AACpB,QAAA,QAAA,CAAS,OAAA,CAAQ,IAAI,EAAA,EAAA,CAAK,QAAA,CAAS,QAAQ,GAAA,CAAI,EAAE,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAC5D,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,QAAA,MAAA,EAAO;AACP,QAAA,IAAI,QAAA,GAAW,KAAA;AACf,QAAA,OAAO,MAAM;AACX,UAAA,IAAI,QAAA,EAAU;AACd,UAAA,QAAA,GAAW,IAAA;AACX,UAAA,MAAM,IAAA,GAAO,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AACpC,UAAA,IAAI,SAAS,MAAA,EAAW;AACxB,UAAA,IAAI,OAAO,CAAA,EAAG,QAAA,CAAS,QAAQ,GAAA,CAAI,EAAA,EAAI,OAAO,CAAC,CAAA;AAAA,eAC1C,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,EAAE,CAAA;AAC/B,UAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,UAAA,MAAA,EAAO;AAAA,QACT,CAAA;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACX;AAYO,SAAS,YAAA,CAAa,EAAE,QAAA,EAAS,EAA0C;AAChF,EAAA,MAAM,SAAS,kBAAA,EAAmB;AAClC,EAAA,MAAM,MAAA,GAAS,SAAS,MAAM,CAAA;AAC9B,EAAA,IAAI,CAAC,MAAA,EAAQ,uBAAOC,GAAAA,CAAAI,QAAAA,EAAA,EAAG,QAAA,EAAS,CAAA;AAChC,EAAA,uBAAOJ,GAAAA,CAAC,cAAA,CAAe,UAAf,EAAwB,KAAA,EAAO,QAAS,QAAA,EAAS,CAAA;AAC3D;AAgBA,SAAS,SAAA,CAAa,KAAuB,KAAA,EAA6B;AACxE,EAAA,IAAI,KAAA,KAAU,IAAA,EAAM,OAAO,MAAM;AAAA,EAAC,CAAA;AAClC,EAAA,GAAA,CAAI,OAAA,CAAQ,KAAK,KAAK,CAAA;AACtB,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,OAAO,MAAM;AACX,IAAA,IAAI,QAAA,EAAU;AACd,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,WAAA,CAAY,KAAK,CAAA;AACvC,IAAA,IAAI,MAAM,EAAA,EAAI,GAAA,CAAI,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACvC,CAAA;AACF;AAEO,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAS,EAA0C;AAMnF,EAAA,MAAM,UAAA,GAAaE,MAAAA,iBAA8B,IAAI,GAAA,EAAK,CAAA;AAC1D,EAAA,MAAM,UAAA,GAAa,CAAC,EAAA,KAAmC,UAAA,CAAW,QAAQ,GAAA,CAAI,EAAE,CAAA,EAAG,EAAA,CAAG,EAAE,CAAA;AACxF,EAAA,MAAM,UAAA,GAAaA,OAAO,CAAC,CAAA;AAC3B,EAAA,MAAM,SAAA,GAAYA,MAAAA,CAA0B,EAAE,CAAA;AAC9C,EAAA,MAAM,YAAA,GAAeA,OAAO,EAAE,CAAA;AAC9B,EAAA,MAAM,YAAA,GAAeA,MAAAA,iBAAwB,IAAI,GAAA,EAAK,CAAA;AAKtD,EAAA,MAAM,SAAS,sBAAA,EAAuB;AACtC,EAAA,MAAM,SAAA,GAAYA,OAA2B,MAAM,CAAA;AACnD,EAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAIpB,EAAA,MAAM,SAAA,GAAYA,OAAO,KAAK,CAAA;AAU9B,EAAA,MAAM,cAAA,GAAiBA,MAAAA,CAAsB,EAAE,CAAA;AAI/C,EAAA,MAAM,aAAA,GAAgBA,MAAAA,CAAqB,EAAE,CAAA;AAQ7C,EAAA,MAAM,KAAA,GAAQH,QAAsB,MAAM;AACxC,IAAA,MAAM,WAAW,MAAyB;AACxC,MAAA,MAAM,IAAI,UAAA,CAAW,OAAA;AACrB,MAAA,IAAI,YAAA,CAAa,OAAA,KAAY,CAAA,EAAG,OAAO,SAAA,CAAU,OAAA;AACjD,MAAA,MAAM,MAAM,MAAA,CAAO,MAAA;AAAA,QACjB,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,OAAA,CAAQ,MAAA,EAAO,EAAG,CAAC,KAAA,KAAU,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAC;AAAA,OAC5E;AACA,MAAA,SAAA,CAAU,OAAA,GAAU,GAAA;AACpB,MAAA,YAAA,CAAa,OAAA,GAAU,CAAA;AACvB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AACA,IAAA,MAAM,SAAS,MAAY;AACzB,MAAA,KAAA,MAAW,CAAA,IAAK,aAAa,OAAA,EAAS;AACpC,QAAA,IAAI;AACF,UAAA,CAAA,EAAE;AAAA,QACJ,SAAS,GAAA,EAAK;AACZ,UAAA,OAAA,CAAQ,KAAA,CAAM,4CAA4C,GAAG,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,CAAA;AACA,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,CAAC,MAAA,KAAmB;AAC5B,QAAA,gBAAA,CAAiB,OAAO,EAAE,CAAA;AAC1B,QAAA,4BAAA,CAA6B,MAAM,CAAA;AACnC,QAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,OAAO,EAAE,CAAA;AAC9C,QAAA,IAAI,KAAA,EAAO,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA;AAAA,wBACZ,OAAA,CAAQ,GAAA,CAAI,OAAO,EAAA,EAAI,CAAC,MAAM,CAAC,CAAA;AAC/C,QAAA,UAAA,CAAW,OAAA,EAAA;AACX,QAAA,MAAA,EAAO;AACP,QAAA,IAAI,QAAA,GAAW,KAAA;AACf,QAAA,OAAO,MAAM;AACX,UAAA,IAAI,QAAA,EAAU;AACd,UAAA,QAAA,GAAW,IAAA;AACX,UAAA,MAAM,GAAA,GAAM,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,OAAO,EAAE,CAAA;AAC5C,UAAA,IAAI,CAAC,GAAA,EAAK;AAGV,UAAA,MAAM,CAAA,GAAI,GAAA,CAAI,WAAA,CAAY,MAAM,CAAA;AAChC,UAAA,IAAI,MAAM,EAAA,EAAI;AACd,UAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AACf,UAAA,IAAI,IAAI,MAAA,KAAW,CAAA,aAAc,OAAA,CAAQ,MAAA,CAAO,OAAO,EAAE,CAAA;AACzD,UAAA,UAAA,CAAW,OAAA,EAAA;AACX,UAAA,MAAA,EAAO;AAAA,QACT,CAAA;AAAA,MACF,CAAA;AAAA,MACA,UAAA,EAAY,CAAC,EAAA,KAAe;AAG1B,QAAA,IAAI,UAAA,CAAW,OAAA,CAAQ,MAAA,CAAO,EAAE,CAAA,EAAG;AACjC,UAAA,UAAA,CAAW,OAAA,EAAA;AACX,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF,CAAA;AAAA,MACA,IAAA,EAAM,MAAM,QAAA,EAAS;AAAA,MACrB,OAAA,EAAS,CAAC,EAAA,EAAY,MAAA,KAAqC;AACzD,QAAA,MAAM,CAAA,GAAI,WAAW,EAAE,CAAA;AACvB,QAAA,IAAI,CAAC,GAAG,OAAO,KAAA;AACf,QAAA,IAAI;AACF,UAAA,IAAI,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,OAAA,CAAQ,WAAW,WAAA,EAAa;AACjD,YAAA,MAAM,IAAI,cAAA,CAAe,OAAA,CAAQ,EAAA,CAAG,CAAA,CAAE,KAAK,SAAA,CAAU,OAAA;AAKrD,YAAA,MAAM,IAAA,GAAO,CAAC,CAAA,GACV,EAAC,GACD,EAAE,QAAA,GACA,qBAAA,CAAsB,CAAA,EAAG,CAAC,CAAA,GAC1B;AAAA,cACE,SAAA,EAAW,CAAA,CAAE,GAAA,CAAI,WAAsB,CAAA;AAAA,cACvC,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,OAAkB,CAAA;AAAA,cAC/B,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,SAAoB,CAAA;AAAA,cACnC,IAAA,EAAM,CAAA,CAAE,GAAA,CAAI,MAAiB,CAAA;AAAA,cAC7B,UAAA,EAAY,CAAA,CAAE,GAAA,CAAI,YAAuB,CAAA;AAAA,cACzC,eAAA,EAAiB,CAAA,CAAE,GAAA,CAAI,iBAA4B;AAAA,aACrD;AACN,YAAA,CAAA,CAAE,OAAA,CAAQ,GAAA,CAAI,IAAA,EAAe,MAAM,CAAA;AAAA,UACrC;AAAA,QACF,SAAS,GAAA,EAAK;AACZ,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,EAAE,CAAA,OAAA,CAAA,EAAW,GAAG,CAAA;AAAA,QACnE;AACA,QAAA,OAAO,IAAA;AAAA,MACT,CAAA;AAAA,MACA,SAAA,EAAW,CAAC,QAAA,KAAyB;AACnC,QAAA,YAAA,CAAa,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACjC,QAAA,OAAO,MAAM;AACX,UAAA,YAAA,CAAa,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAAA,QACtC,CAAA;AAAA,MACF,CAAA;AAAA,MACA,aAAA,EAAe,CAAC,CAAA,KAAyB;AACvC,QAAA,IAAI,CAAA,IAAK,aAAA,CAAc,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,aAAA,CAAc,OAAA,CAAQ,EAAA,CAAG,EAAE,CAAA,KAAM,CAAA,IACvE,CAAC,UAAU,OAAA,EAAS;AACzB,UAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,UAAA,eAAA,EAAgB;AAAA,QAClB;AACA,QAAA,OAAO,SAAA,CAAU,eAAe,CAAC,CAAA;AAAA,MACnC,CAAA;AAAA,MACA,cAAA,EAAgB,CAAC,CAAA,KAA0B,SAAA,CAAU,gBAAgB,CAAC,CAAA;AAAA,MACtE,KAAA,EAAO,CAAC,EAAA,EAAY,MAAA,KAAqC;AACvD,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,OAAA,CAAQ,EAAA,CAAG,EAAE,CAAA,IAAK,IAAA;AAC7C,QAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,QAAA,MAAM,IAAI,cAAA,CAAe,OAAA,CAAQ,EAAA,CAAG,EAAE,KAAK,SAAA,CAAU,OAAA;AACrD,QAAA,MAAM,CAAA,GAAI,WAAW,EAAE,CAAA;AAMvB,QAAA,MAAM,IAAA,GAAO,CAAC,CAAA,GACV,EAAC,GACD,GAAG,QAAA,GACD,qBAAA,CAAsB,CAAA,EAAG,CAAC,CAAA,GAC1B;AAAA,UACE,SAAA,EAAW,CAAA,CAAE,GAAA,CAAI,WAAsB,CAAA;AAAA,UACvC,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,OAAkB,CAAA;AAAA,UAC/B,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,SAAoB,CAAA;AAAA,UACnC,IAAA,EAAM,CAAA,CAAE,GAAA,CAAI,MAAiB,CAAA;AAAA,UAC7B,UAAA,EAAY,CAAA,CAAE,GAAA,CAAI,YAAuB,CAAA;AAAA,UACzC,eAAA,EAAiB,CAAA,CAAE,GAAA,CAAI,iBAA4B;AAAA,SACrD;AACN,QAAA,OAAO,IAAA,CAAK,cAAA,CAAe,EAAA,EAAI,IAAA,EAAe,MAAM,CAAA;AAAA,MACtD;AAAA,KACF;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAIL,EAAA,MAAM,QAAA,GAAW,SAAS,KAAK,CAAA;AAE/B,EAAA,uBAAOC,GAAAA,CAAC,cAAA,CAAe,UAAf,EAAwB,KAAA,EAAO,UAAW,QAAA,EAAS,CAAA;AAC7D;AAgBA,SAAS,eAAA,GAAwB;AAC/B,EAAA,IAAI,CAAC,MAAA,EAAQ;AACb,EAAA,OAAA,CAAQ,IAAA;AAAA,IACN;AAAA,GAGF;AACF;AAEA,IAAM,UAAmB,MAAM;AAC7B,EAAA,IAAI;AACF,IAAA,OAAO,OAAA,CAAS,MAAA,CAAA,IAAA,CAAuD,GAAA,EAAK,GAAG,CAAA;AAAA,EACjF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA,GAAG;AAEI,SAAS,kBAAA,GAA6C;AAC3D,EAAA,OAAOC,WAAW,cAAc,CAAA;AAClC;AASO,SAAS,UAAU,MAAA,EAAsB;AAC9C,EAAA,MAAM,MAAM,kBAAA,EAAmB;AAC/B,EAAAE,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,WAAA,EAAc,OAAO,EAAE,CAAA,wGAAA;AAAA,SACzB;AAAA,MACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,OAAO,GAAA,CAAI,SAAS,MAAM,CAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,GAAA,EAAK,MAAM,CAAC,CAAA;AAClB;AC1TO,SAAS,iBACd,IAAA,EAC4B;AAC5B,EAAA,MAAM,MAAM,oBAAA,EAAqB;AACjC,EAAA,MAAM,kBAAkB,kBAAA,EAAmB;AAK3C,EAAA,MAAM,iBAAA,GAAoBD,OAAO,KAAK,CAAA;AACtC,EAAA,MAAM,aAAA,GAAgB,CAAC,iBAAA,CAAkB,OAAA;AACzC,EAAA,MAAM,sBAAA,GAAyBA,OAAO,KAAK,CAAA;AAC3C,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAC5B,IAAA,sBAAA,CAAuB,OAAA,GAAU,GAAA,CAAI,MAAA,KAAW,QAAA,IAAY,KAAK,OAAA,KAAY,QAAA;AAAA,EAC/E;AACA,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,uBAAuB,OAAA,EAAS;AACrC,IAAA,sBAAA,CAAuB,OAAA,GAAU,KAAA;AACjC,IAAA,GAAA,CAAI,SAAA,CAAU,KAAK,OAAO,CAAA;AAAA,EAG5B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAA,GAAU,aAAA,IAAiB,GAAA,CAAI,MAAA,KAAW,QAAA,IAAY,KAAK,OAAA,KAAY,QAAA,GACzE,IAAA,CAAK,OAAA,GACL,GAAA,CAAI,MAAA;AAIR,EAAA,MAAM,UAAA,GAAaD,MAAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AACtC,EAAA,UAAA,CAAW,UAAU,IAAA,CAAK,OAAA;AAC1B,EAAA,MAAM,UAAA,GAAaA,OAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,EAAA,MAAM,UAAA,GAAaA,MAAAA,CAA0B,GAAA,CAAI,WAAW,CAAA;AAC5D,EAAA,UAAA,CAAW,UAAU,GAAA,CAAI,WAAA;AAEzB,EAAA,MAAM,UAAA,GAAaG,WAAAA,CAAY,CAAC,EAAA,KAAe;AAAE,IAAA,GAAA,CAAI,UAAU,EAAE,CAAA;AAAA,EAAG,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAI5E,EAAA,MAAM,QAAA,GAAWA,YAAY,MAAM;AACjC,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,IAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,OAAO,CAAA;AAClC,IAAA,MAAM,UAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,MAAA,MAAM,KAAA,GAAQ,WAAW,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACxD,MAAA,IAAI,KAAA,IAAS,CAAC,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IAC3D;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,WAAW,OAAA,EAAS;AACtC,MAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IAClD;AACA,IAAA,OAAO;AAAA,MACL,OAAA;AAAA,MACA,KAAA,EAAO,EAAE,SAAA,EAAW,UAAA,CAAW,SAAS,UAAA;AAAW,KACrD;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,cAAA,GAAiBA,YAAY,MAAuB;AACxD,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,QAAA,EAAS;AACpC,IAAA,OAAO,aAAA,CAAc,SAAS,KAAK,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,QAAA,GAAWA,WAAAA,CAAY,CAAC,QAAA,GAA4B,KAAA,KAAsB;AAC9E,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,QAAA,EAAS;AACpC,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,MAAM,UAAsB,EAAC;AAC7B,IAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AACpB,MAAA,IAAA,CAAK,KAAA,CAAM,eAAA,IAAmB,KAAA,MAAW,QAAA,EAAU;AACnD,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,OAAO,IAAI,KAAA,CAAM,OAAA,GAAU,CAAC,KAAA,CAAM,OAAO,CAAA;AAC5E,MAAA,MAAM,KAAA,GAAQ,UAAU,KAAA,CAAM,EAAA,EAAI,MAAM,WAAA,IAAe,IAAI,KAAK,CAAA;AAChE,MAAA,IAAI,KAAA,KAAU,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,GAAG,MAAM,CAAA;AAAA,WAAA,IACpC,KAAA,KAAU,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,GAAG,MAAM,CAAA;AAAA,WAAA,IACzC,KAAA,KAAU,SAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,GAAG,MAAM,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,CAAC,GAAG,MAAA,EAAQ,GAAG,MAAA,EAAQ,GAAG,OAAO,CAAA;AAAA,EAC1C,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAKb,EAAA,MAAM,UAAA,GAAa,KAAK,OAAA,CACrB,GAAA,CAAI,CAAC,CAAA,KAAO,CAAA,CAAE,WAAA,EAAa,OAAA,GAAU,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,CAAA,CAAE,WAAA,CAAY,OAAO,CAAA,CAAA,GAAK,EAAG,EAC7E,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA;AACX,EAAAF,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,eAAA,IAAmB,UAAA,KAAe,EAAA,EAAI;AAC3C,IAAA,MAAM,QAAkC,UAAA,CAAW,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,KAAA,KAAU;AAC3E,MAAA,MAAM,CAAC,MAAA,EAAQ,OAAO,CAAA,GAAI,KAAA,CAAM,MAAM,GAAG,CAAA;AACzC,MAAA,OAAO,EAAE,MAAA,EAAQ,GAAA,EAAK,aAAA,CAAc,OAAwB,CAAA,EAAE;AAAA,IAChE,CAAC,CAAA;AACD,IAAA,OAAO,gBAAgB,QAAA,CAAS,qBAAA,CAAsB,wBAAA,CAAyB,KAAK,CAAC,CAAC,CAAA;AAAA,EACxF,CAAA,EAAG,CAAC,eAAA,EAAiB,UAAU,CAAC,CAAA;AAWhC,EAAA,MAAM,kBAAA,GAAqBD,OAAsB,IAAI,CAAA;AACrD,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AACvD,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAM,EAAG;AACd,IAAA,IAAI,kBAAA,CAAmB,YAAY,QAAA,EAAU;AAC7C,IAAA,kBAAA,CAAmB,OAAA,GAAU,QAAA;AAM7B,IAAA,MAAM,WAAsC,EAAC;AAC7C,IAAA,MAAM,UAAqC,EAAC;AAC5C,IAAA,KAAA,MAAW,KAAA,IAAS,WAAW,OAAA,EAAS;AACtC,MAAA,IAAI,KAAA,CAAM,WAAA,EAAa,KAAA,EAAO,QAAA,CAAS,KAAK,KAAK,CAAA;AACjD,MAAA,IAAI,KAAA,CAAM,aAAa,MAAA,IAAU,KAAA,CAAM,aAAa,OAAA,EAAS,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IACjF;AACA,IAAA,oBAAA,CAAqB;AAAA,MACnB,QAAA;AAAA,MACA,OAAA;AAAA,MACA,OAAA,EAAS,eAAA,EAAiB,IAAA,EAAK,IAAK;AAAC,KACtC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,QAAA,EAAU,eAAe,CAAC,CAAA;AAQ9B,EAAA,OAAOJ,OAAAA;AAAA,IACL,OAAO;AAAA,MACL,IAAI,OAAA,GAAU;AAAE,QAAA,OAAO,UAAA,CAAW,OAAA;AAAA,MAAS,CAAA;AAAA,MAC3C,OAAA;AAAA,MACA,UAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,UAAA,EAAY,cAAA,EAAgB,QAAQ;AAAA,GAChD;AACF;;;AC9IA,SAAS,WAAA,CAA+B,MAAS,IAAA,EAA6B;AAC5E,EAAA,MAAM,MAAA,GAAU,KAAK,GAAA,EAAgD,MAAA;AACrE,EAAA,MAAM,WAAA,GAA2B;AAAA,IAC/B,GAAG,IAAA,CAAK,WAAA;AAAA,IACR,CAAC,IAAI,GAAG,IAAA;AAAA,IACR,GAAI,MAAA,GAAS,EAAE,OAAA,EAAS,MAAA,KAAW;AAAC,GACtC;AACA,EAAA,OAAO,eAAA,CAAgB,KAAK,WAAA,EAAa,WAAW,IAAI,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,WAAA,EAAY;AACxF;AAEA,SAAS,eAAA,CAAgB,GAA4B,CAAA,EAAyB;AAC5E,EAAA,IAAI,CAAC,GAAG,OAAO,KAAA;AACf,EAAA,MAAM,IAAA,mBAAO,IAAI,GAAA,CAAI,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,GAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAC3D,EAAA,KAAA,MAAW,GAAA,IAAO,MAAM,IAAI,CAAA,CAAE,GAAG,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA,EAAG,OAAO,KAAA;AACtD,EAAA,OAAO,IAAA;AACT;AAmBO,SAAS,SACd,IAAA,EACoB;AACpB,EAAA,IAAI,EAAE,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,QAAA,CAAA,EAAW;AACnC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,IAAA,CAAK,MAAM,CAAA,iBAAA,CAAmB,CAAA;AAAA,EACrE;AAEA,EAAA,MAAM,MAAM,oBAAA,EAAqB;AAEjC,EAAA,MAAM,OAAA,GAAUA,QAAQ,MAAM;AAC5B,IAAA,MAAM,WAAgD,EAAC;AACvD,IAAA,KAAA,MAAW,CAAC,IAAI,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AACtD,MAAA,QAAA,CAAS,EAAE,CAAA,GAAI,WAAA,CAAY,IAAA,EAAM,OAAO,CAAA;AAAA,IAC1C;AACA,IAAA,MAAM,OAAA,GAAA,CAAW,IAAA,CAAK,OAAA,IAAW,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,WAAA,CAAY,CAAA,EAAG,QAAQ,CAAC,CAAA;AACxE,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAoC;AACrD,IAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,GAAG,MAAA,CAAO,OAAO,QAAQ,CAAA,EAAG,GAAG,OAAO,CAAA,EAAG;AAC3D,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAC9B,MAAA,IAAI,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,EAAE,GAAG,IAAA,EAAM,WAAA,EAAa,EAAE,GAAG,KAAA,CAAM,WAAA,EAAa,GAAG,IAAA,CAAK,WAAA,IAAe,CAAA;AAAA,WAC/F,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,EAAE,UAAU,OAAA,EAAS,OAAA,EAAS,CAAC,GAAG,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAE;AAAA,EAC1D,GAAG,CAAC,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,OAAO,CAAC,CAAA;AAEhC,EAAA,MAAM,aAAA,GAAgB,iBAA2B,EAAE,OAAA,EAAS,QAAQ,OAAA,EAAS,OAAA,EAAS,IAAA,CAAK,MAAA,EAAQ,CAAA;AAEnG,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,WAAA,CAAY,EAAA,CAAG,EAAE,CAAA,IAAK,IAAA;AAIhD,EAAA,MAAM,UAAA,GAAaG,OAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AACrB,EAAA,MAAM,SAAA,GAAYA,MAAAA,CAAO,aAAA,CAAc,OAAO,CAAA;AAC9C,EAAA,SAAA,CAAU,UAAU,aAAA,CAAc,OAAA;AAClC,EAAA,MAAM,SAAA,GAAYA,OAAO,aAAa,CAAA;AACtC,EAAA,SAAA,CAAU,OAAA,GAAU,aAAA;AAEpB,EAAA,MAAM,aAAa,aAAA,CAAc,UAAA;AACjC,EAAA,MAAM,SAAA,GAAYG,WAAAA;AAAA,IAChB,CAAC,EAAA,KAAe;AACd,MAAA,IAAI,EAAE,EAAA,IAAM,UAAA,CAAW,OAAA,CAAQ,QAAA,CAAA,EAAW;AACxC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,YAAA,EAAe,EAAE,CAAA,iBAAA,CAAmB,CAAA;AAAA,MACtD;AACA,MAAA,IAAA,CAAK,OAAA,EAAS,SAAA,EAAW,SAAA,CAAU,OAAA,EAAS,UAAK,EAAE,CAAA;AACnD,MAAA,UAAA,CAAW,EAAE,CAAA;AAAA,IACf,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,YAAA,GAAeA,WAAAA;AAAA,IACnB,CAAC,EAAA,KAAe;AACd,MAAA,IAAI,EAAE,EAAA,IAAM,UAAA,CAAW,OAAA,CAAQ,QAAA,CAAA,EAAW;AACxC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,EAAE,CAAA,iBAAA,CAAmB,CAAA;AAAA,MACzD;AACA,MAAA,IAAA,CAAK,OAAA,EAAS,mBAAmB,EAAE,CAAA;AACnC,MAAA,GAAA,CAAI,WAAW,EAAE,CAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAAC,GAAG;AAAA,GACN;AAEA,EAAA,MAAM,eAAA,GAAkBA,YAAY,MAAM;AACxC,IAAA,IAAI,UAAU,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,oBAAA,EAAsB,UAAU,OAAO,CAAA;AAC5E,IAAA,GAAA,CAAI,SAAA,EAAU;AAAA,EAChB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,GAAA,GAAMA,WAAAA;AAAA,IACV,CAAC,EAAA,KACC,EAAA,IAAM,UAAA,CAAW,QAAQ,QAAA,IACtB,UAAA,CAAW,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAAA,IACvD;AAAC,GACH;AAMA,EAAA,MAAM,SAAS,aAAA,CAAc,OAAA;AAC7B,EAAA,MAAM,oBAAoB,aAAA,CAAc,QAAA;AAIxC,EAAA,MAAM,WAAA,GACJ,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA,CAAE,IAAA,GAAO,IAAA,CAAK,GAAG,IAC3C,GAAA,GAAM,OAAA,CAAQ,QAAQ,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AACnD,EAAA,OAAON,OAAAA;AAAA,IACL,OAAO;AAAA,MACL,MAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,OAAA,EAAS,WAAW,OAAA,CAAQ,OAAA;AAAA,MAC5B,QAAA,EAAU,WAAW,OAAA,CAAQ,QAAA;AAAA,MAC7B,GAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA;AAAA;AAAA;AAAA,IAIA,CAAC,QAAQ,SAAA,EAAW,aAAA,EAAe,cAAc,eAAA,EAAiB,GAAA,EAAK,mBAAmB,WAAW;AAAA,GACvG;AACF","file":"react.js","sourcesContent":["/**\n * ActiveToolContext — runtime selection state for tools.\n *\n * Holds the currently active tool id and a hotkey stack (tools held active\n * temporarily, e.g. space-for-hand). Read by the gesture dispatcher to\n * determine which tool's bindings are in scope; written by tool-switching\n * actions (`tool.activate`) and offhand hotkey actions (`tool.offhand`),\n * both parametric on `params.toolId`.\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md`\n * § \"Types\" and § \"Dispatcher contract\".\n */\n\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n useCallback,\n type ReactNode,\n} from 'react';\n\n/** Which tool is active, plus the stack of tools temporarily held active by a\n * hotkey (space-for-hand and the like). The dispatcher reads this to decide\n * whose bindings are in scope. */\nexport interface ActiveToolContextValue {\n active: string;\n hotkeyStack: string[];\n setActive(id: string): void;\n pushHotkey(id: string): void;\n /**\n * Disengage a hotkey-held tool. With `id`, removes that tool's own entry\n * wherever it now sits — holds do not have to come up in the order they went\n * down, and popping the top would disengage a tool whose key is still held.\n * With no id, pops the top.\n */\n popHotkey(id?: string): void;\n}\n\nconst ActiveToolContext = createContext<ActiveToolContextValue | null>(null);\n\n/** Props for `<ActiveToolContextProvider>`. */\nexport interface ActiveToolContextProviderProps {\n children: ReactNode;\n initialActive?: string;\n}\n\n/** Provides active-tool state for a canvas. `<SceneCanvas>` mounts one. */\nexport function ActiveToolContextProvider({\n children,\n initialActive = 'select',\n}: ActiveToolContextProviderProps) {\n const [active, setActiveState] = useState(initialActive);\n const [hotkeyStack, setHotkeyStack] = useState<string[]>([]);\n\n const setActive = useCallback((id: string) => {\n setActiveState(id);\n }, []);\n const pushHotkey = useCallback((id: string) => {\n setHotkeyStack((s) => [...s, id]);\n }, []);\n const popHotkey = useCallback((id?: string) => {\n setHotkeyStack((s) => {\n if (s.length === 0) return s;\n if (id === undefined) return s.slice(0, -1);\n const i = s.lastIndexOf(id);\n return i === -1 ? s : [...s.slice(0, i), ...s.slice(i + 1)];\n });\n }, []);\n\n const value = useMemo<ActiveToolContextValue>(\n () => ({ active, hotkeyStack, setActive, pushHotkey, popHotkey }),\n [active, hotkeyStack, setActive, pushHotkey, popHotkey],\n );\n\n return (\n <ActiveToolContext.Provider value={value}>{children}</ActiveToolContext.Provider>\n );\n}\n\n/** The active-tool state in scope. Throws outside a provider; use\n * `useActiveToolContextOptional` where one is not guaranteed. */\nexport function useActiveToolContext(): ActiveToolContextValue {\n const value = useContext(ActiveToolContext);\n if (value === null) {\n throw new Error(\n 'useActiveToolContext: no ActiveToolContextProvider in scope. Wrap your tree with <ActiveToolContextProvider> (typically inside <SceneCanvas>).',\n );\n }\n return value;\n}\n\n/**\n * Like `useActiveToolContext`, but returns `null` when no\n * `<ActiveToolContextProvider>` is in scope instead of throwing. Used by\n * `useStandardActions` to preserve its silent-no-op contract when no provider\n * is present.\n */\nexport function useOptionalActiveToolContext(): ActiveToolContextValue | null {\n return useContext(ActiveToolContext);\n}\n\n/**\n * Conditional `<ActiveToolContextProvider>` wrapper. Mounts a provider only\n * when no parent provider is in scope — otherwise renders children unwrapped\n * so callers (e.g. `<WeaselProvider>`, `<SceneCanvas>`) defer to the host's\n * existing scope. Mirrors `ActionsProviderIfRoot` / `DepRegistryProviderIfRoot`.\n */\nexport function ActiveToolContextProviderIfRoot({\n children,\n}: {\n children: ReactNode;\n}) {\n const parent = useContext(ActiveToolContext);\n if (parent !== null) return <>{children}</>;\n return <ActiveToolContextProvider>{children}</ActiveToolContextProvider>;\n}\n","/**\n * Dep registry for registry unification.\n *\n * Holds named \"live source\" thunks. Actions declare `requires: ['selection']`;\n * the dispatcher calls `registry.get('selection')` at invocation time to\n * build a typed Deps bag.\n *\n * `DepSchema` — the map of dep name → value type — is the single source of\n * truth for what `requires`/`register`/`get` accept. Its concrete fields live\n * in `./depSchema` (co-located with the dep value types). It is declared there\n * as a plain `export interface` rather than via a cross-module\n * `declare module './depRegistry'` augmentation: that augmentation does NOT\n * merge once rollup-plugin-dts flattens both files into one `.d.ts` chunk,\n * which silently emptied `DepSchema` for consumers. Consumers still extend it\n * via `declare module '@weasel-js/core'` augmentation.\n */\nimport {\n createContext, useContext, useEffect, useMemo, useRef,\n type ReactNode,\n} from 'react';\nimport type { DepSchema, DepName } from '../../index';\n\nexport type { DepSchema, DepName };\n\n/** Holds the live sources an action's declared dependencies resolve to.\n * Sources are thunks, read at invocation time, so an action never captures\n * stale state. */\nexport interface DepRegistry {\n register<K extends DepName>(name: K, source: () => DepSchema[K]): () => void;\n get<K extends DepName>(name: K): DepSchema[K] | undefined;\n}\n\nconst DepRegistryContext = createContext<DepRegistry | null>(null);\n\n/** Provides the dep registry for a canvas. `<SceneCanvas>` mounts one; a\n * consumer registering its own dep sources must be inside it. */\nexport function DepRegistryProvider({ children }: { children: ReactNode }) {\n // A stack of sources per name, newest live — the same shape as\n // `ActionsProvider`'s registrant stack, one layer down. Two canvases under\n // one provider both register `view` / `scene` / `selection`; with a single\n // slot the second displaced the first and either one's teardown then deleted\n // the name outright, taking the dep away from the canvas still on screen.\n const sourcesRef = useRef(new Map<string, (() => unknown)[]>());\n\n const registry = useMemo<DepRegistry>(() => ({\n register: <K extends DepName>(name: K, source: () => DepSchema[K]) => {\n const key = name as string;\n const entry = source as () => unknown;\n const stack = sourcesRef.current.get(key);\n if (stack) stack.push(entry);\n else sourcesRef.current.set(key, [entry]);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = sourcesRef.current.get(key);\n if (!cur) return;\n // Our own entry, wherever it now sits: a source already displaced must\n // take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(entry);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) sourcesRef.current.delete(key);\n };\n },\n get: <K extends DepName>(name: K) =>\n sourcesRef.current.get(name as string)?.at(-1)?.() as DepSchema[K] | undefined,\n }), []);\n\n return <DepRegistryContext.Provider value={registry}>{children}</DepRegistryContext.Provider>;\n}\n\n/** The dep registry in scope. Throws outside a `<DepRegistryProvider>`. */\nexport function useDepRegistry(): DepRegistry {\n const r = useContext(DepRegistryContext);\n if (r === null) {\n throw new Error('useDepRegistry: no DepRegistryProvider in scope. Wrap your tree with <DepRegistryProvider> (typically inside <SceneCanvas>).');\n }\n return r;\n}\n\n/**\n * Like `useDepRegistry`, but returns `null` when no `<DepRegistryProvider>` is\n * in scope instead of throwing. Used by `useStandardActions` to preserve its\n * silent-no-op contract when neither provider is present.\n */\nexport function useOptionalDepRegistry(): DepRegistry | null {\n return useContext(DepRegistryContext);\n}\n\n/** Register a live source for `name` for the lifetime of the calling\n * component. The `source` thunk is called at dispatch time and should\n * return the latest value. */\nexport function useDepSource<K extends DepName>(name: K, source: () => DepSchema[K]) {\n const registry = useDepRegistry();\n const sourceRef = useRef(source);\n sourceRef.current = source;\n useEffect(() => {\n return registry.register(name, () => sourceRef.current());\n }, [name, registry]);\n}\n","/**\n * useGestureDispatcher — React seam mounting the gesture dispatcher.\n *\n * Composes the four input channels (window keydown/keyup, canvas wheel, canvas\n * pointer events, multi-touch synthesized from PointerEvents) and routes each\n * event to the dispatcher for the view it landed in — one view unless `views`\n * says otherwise. Reads ActiveToolContext + DepRegistry internally; consumer\n * passes the canvas ref, actions registry, and tools map.\n *\n * Side-effect only (returns void).\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md` § Q4.\n */\nimport { useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\nimport { isEditableTarget } from '../keyHelpers';\nimport { useActiveToolContext } from '../actions/activeToolContext';\nimport { useDepRegistry, type DepRegistry } from '../actions/depRegistry';\nimport type { DepName, DepSchema } from '../../index';\nimport type { ActionsRegistry } from '../actions/registry';\nimport type { AffordanceHit } from '../actions/invoker';\nimport type { Tool, ToolCtx } from '../../tools/types';\nimport { createDispatcher, pointerGestureId, type Dispatcher, type DispatcherContext } from './dispatcher';\nimport { openPointerSession, type PointerSession } from '../pointerSession';\nimport { clientToCanvasRect } from '../../viewport/clientToCanvas';\nimport { itemsFromDataTransfer, itemsFromClipboardData } from '../../ingestion/ingestItems';\nimport type { InputEvent } from './matcher';\nimport type { BodyTarget, BodyClassification } from '@weasel-js/gestures';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { PaintedCursorState } from '@weasel-js/cursor';\nimport { resolveCursorTier } from '@weasel-js/cursor';\n\n// ---------------------------------------------------------------------------\n// Drop-over styling — class toggled on the canvas while an OS drag hovers it;\n// consumers style it. Not exported: the string is an observable public value\n// but the symbol is internal.\n// ---------------------------------------------------------------------------\n\n/** Class toggled on the canvas while an OS drag hovers it — consumers style it. */\nconst DROPOVER_CLASS = 'weasel-dropover';\n\n/**\n * Lift the stylus fields off a DOM `PointerEvent` onto the normalized\n * `InputEvent`. Kept as a spread-able partial so a synthetic event that\n * carries none of them stays free of `undefined`-valued keys.\n *\n * These ride the drag trail (`InvocationCtx.drag.points`) so pressure- and\n * tilt-aware actions — `insertAction`'s pencil kind today — can reach the\n * per-sample data without their own pointer plumbing.\n */\nfunction stylusOf(e: PointerEvent): {\n pressure?: number; tiltX?: number; tiltY?: number;\n} {\n return {\n ...(typeof e.pressure === 'number' ? { pressure: e.pressure } : {}),\n ...(typeof e.tiltX === 'number' ? { tiltX: e.tiltX } : {}),\n ...(typeof e.tiltY === 'number' ? { tiltY: e.tiltY } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Platform detection — module-level constant so it's stable across renders.\n// ---------------------------------------------------------------------------\n\nconst IS_MAC =\n typeof navigator !== 'undefined' &&\n /mac/i.test(\n // `||`, not `??`: jsdom (and some embedders) report an empty-string\n // platform, which is not nullish and would swallow the UA fallback.\n (navigator as { platform?: string }).platform || navigator.userAgent,\n );\n\n// ---------------------------------------------------------------------------\n// API\n// ---------------------------------------------------------------------------\n\n/**\n * Everything about handling an input event that depends on *which view* it\n * landed in: the dispatcher that runs it, and the three lookups that resolve\n * a client point against that view's camera.\n *\n * @internal One per view. The hook builds the `id: null` one from its flat\n * options; `views` supplies the rest, and the hook chooses between them per\n * event, so that it — and its listener set — still mounts exactly once.\n */\nexport interface DispatcherViewTarget {\n /** `null` is the root view — the whole canvas. Matches `ViewTarget.id`. */\n id: string | null;\n dispatcher: Dispatcher;\n affordanceAt: UseGestureDispatcherOptions['affordanceAt'];\n classifyTarget: UseGestureDispatcherOptions['classifyTarget'];\n clientToWorld: UseGestureDispatcherOptions['clientToWorld'];\n /**\n * The deps this view answers for itself — its camera, its selection, and\n * whatever else is per-view rather than per-canvas. Read per event; every\n * name it does not carry still resolves through the canvas registry.\n *\n * This is why a view does not get a `DepRegistryProvider` of its own. The\n * registry is where a consumer registers *sources*, and one per view would\n * fragment that: a consumer overriding `insert` would have to know how many\n * views exist and override each. An overlay keeps one place to register and\n * one authority per dep, with the view claiming only what is genuinely its.\n *\n * Without this a gesture inside a panel pans the whole canvas and selects\n * into the canvas's selection — correct coordinates alone do not make\n * routing correct.\n */\n deps?: () => Partial<DepSchema>;\n /**\n * This view's chrome-caps rule context, for the eligibility filter. The rule\n * table is the surface's, but a rule keyed on selection or the in-flight\n * action answers per view — so an action hidden in one panel must not\n * decline a gesture in another. `undefined` means \"nothing gates here\", the\n * same answer a surface with no mode registry gives.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n}\n\n/**\n * `base` with the routed view's own deps in front of it. Both sides are read\n * through thunks, so the result is stable for the life of a listener set while\n * still answering for whichever view the current event landed in.\n */\nfunction withViewDeps(\n base: () => DepRegistry,\n overlay: () => Partial<DepSchema> | undefined,\n): DepRegistry {\n return {\n register: (name, source) => base().register(name, source),\n get: <K extends DepName>(name: K): DepSchema[K] | undefined => {\n const own = overlay()?.[name];\n if (own !== undefined) return own as DepSchema[K];\n return base().get(name);\n },\n };\n}\n\n/**\n * The part of `features/viewports`' `ViewResolver` the dispatcher needs: which\n * view a client point belongs to, pinned to the view a gesture began in.\n *\n * @internal Structural on purpose — a `ViewResolver` satisfies it, and the\n * dispatcher stays free of the viewport module.\n */\nexport interface ViewIdResolver {\n begin(pointerId: number, clientX: number, clientY: number): { id: string | null };\n at(pointerId: number | null, clientX: number, clientY: number): { id: string | null };\n end(pointerId: number): void;\n}\n\n/** Per-channel switches for the listeners `useGestureDispatcher` attaches to\n * the canvas element. Omitted or `true` attaches the channel. */\nexport interface DispatcherChannels {\n /** `pointerdown`, hover `pointermove`, `pointerleave` — press, drag, click,\n * long-press, multi-touch and the hover-cursor pump. */\n pointer?: boolean;\n /** `wheel`. */\n wheel?: boolean;\n /** `contextmenu`. Off leaves the browser's native menu in place. */\n contextMenu?: boolean;\n /** OS drop on the element plus `paste` on the window. Off leaves the\n * element a non-drop-target and stops `weasel-dropover` being applied. */\n ingest?: boolean;\n}\n\n/** Options for `useGestureDispatcher`: the element to listen on, the actions\n * and tools in play, and the hooks that turn raw DOM events into the world\n * coordinates and hit targets bindings match against. */\nexport interface UseGestureDispatcherOptions {\n /** Ref to the canvas element. Pointer/wheel/multitouch listeners attach here. */\n canvasRef: RefObject<HTMLElement | null>;\n /** Action registry (ActionsRegistry from registry.tsx). */\n actions: ActionsRegistry;\n /** Tool definitions keyed by id. Typically passes an empty Map. */\n toolsById: ReadonlyMap<string, Tool>;\n /** Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it). */\n enabled?: boolean;\n /**\n * Observer fired whenever the dispatcher synthesizes a double click, in\n * world coordinates. Runs BEFORE the event is dispatched and independently\n * of which binding (if any) handles it.\n *\n * This is deliberately not an Action. `<SceneCanvas onDoubleClick>` is a\n * notification — \"the user double-clicked, here's what they hit\" — and a\n * notification must not compete with behavior for the gesture. As a binding\n * it would lose to `enterPathEdit` on any body hit and silently never fire.\n * Routing it here keeps a single definition of \"double click\" (the point of\n * consolidating the kit's three detectors) without giving it\n * first-match-wins semantics it shouldn't have.\n */\n onDoubleClick?: (world: { x: number; y: number }) => void;\n /**\n * Default true. Set false to leave the window `keydown`/`keyup` listeners\n * unattached so keyboard-bound actions never dispatch — pointer, wheel, and\n * contextmenu channels stay live. `<SceneCanvas>` wires this to\n * `enableKeybindings`, so opting out of keybindings disables the modern\n * dispatcher key path as well as the legacy `useKeybindings` hook.\n */\n keyboard?: boolean;\n /**\n * Optional affordance classifier. Called with the **world** coordinates of\n * the pointer — this hook applies the routed view's `clientToWorld` before\n * calling it, the same conversion that produces `InputEvent.x`/`y`, so a\n * consumer hit-tests in one space. Returns an `AffordanceHit` when the\n * pointer lands on a known affordance (resize handle, rotate handle, etc.)\n * or `null` when the pointer hit open canvas.\n *\n * The hit is packed into `InputEvent.pointerdown.affordance` and flows\n * through into `InvocationCtx.drag.affordance`. Action invokers that require\n * a specific affordance (e.g. `resizeAction` requires `handle:*`) use this\n * field as a guard in their `start` body.\n *\n * When omitted, `affordance` is always `undefined` — meaning only consumers\n * that explicitly wire a classifier get affordance-gated behavior.\n * `<SceneCanvas>` wires the full chrome→dispatcher bridge.\n */\n affordanceAt?: (worldPoint: { x: number; y: number }) => AffordanceHit | null;\n\n /**\n * Optional body classifier. Called on every pointerdown with the world-space\n * coordinates of the pointer. Its result is packed onto the event as\n * `bodyTarget` + `bodyKind`, which `matchTarget` reads to resolve the\n * string-form `TargetSpec` values in `Tool.bindings`.\n *\n * `body` is `'empty'` when nothing is under the pointer, `'selected-body'`\n * when the topmost hit belongs to the current selection, or\n * `'unselected-body'` when it belongs to a node that isn't selected. `kind`\n * is the hit node's semantic kind, when the scene can name it.\n *\n * When omitted, every body-derived target form (`'empty'`,\n * `'selected-body'`, `'unselected-body'`, `kind:<k>`, `kind:<k>:selected`)\n * never matches — bindings using those specs are silently skipped.\n * `<SceneCanvas>` wires this.\n *\n * World coordinates, on every path, for the same reason as `affordanceAt`.\n */\n classifyTarget?: (worldPoint: { x: number; y: number }) => BodyClassification;\n\n /**\n * Optional pre-created `Dispatcher`. When provided, this hook pumps events\n * into the supplied instance instead of creating its own. Lets a parent\n * scope (e.g. `<SceneCanvas>`) share one dispatcher between the gesture\n * mounter and other consumers (the preview-ghost layer).\n */\n dispatcher?: Dispatcher;\n\n /**\n * Converts a client-space pointer position (e.g. `e.clientX`, `e.clientY`)\n * to world-space coordinates. When supplied, every pointer/wheel event's\n * `x`/`y` is converted before the dispatcher builds `InvocationCtx.world`.\n *\n * Without this, `ctx.world` is populated with the raw client coords, which\n * silently breaks any action whose overlay/output uses absolute world\n * positions (marquee, lasso polyline, world-space affordances). Actions\n * that only read `drag.delta` are unaffected because client→world deltas\n * are equal at scale 1, but as soon as a consumer pans/zooms the view the\n * deltas diverge too.\n *\n * `<SceneCanvas>` always wires this via its canvas rect + current view.\n * Tests / harnesses without a view can omit it and continue passing raw\n * coordinates as before.\n */\n clientToWorld?: (clientX: number, clientY: number) => { x: number; y: number };\n\n /**\n * Invoked once per pump event (`pointermove`, `pointerup`, `pointercancel`,\n * `key-held` up-phase, `multitouch` move) when a dispatcher-side handle is\n * in flight. Lets the host canvas schedule a redraw so dispatcher-only\n * overlays (marquee, lasso, preview-ghost) repaint on each frame.\n *\n * Required because dispatcher actions don't go through the legacy\n * `tools.dispatcher.onGestureChange` redraw bump that ambient tool drags\n * relied on. Without it, the overlay layer's `draw` never runs between\n * pointerdown and pointerup, and the chrome flashes once at gesture start\n * and then sits frozen until the gesture ends.\n *\n * `<SceneCanvas>` wires this to the canvas's `requestRedraw`. Test\n * harnesses can omit it; their dispatchers won't paint between events but\n * that's already the test contract.\n */\n requestRedraw?: () => void;\n /**\n * The surface's painted-cursor channel, read live because the canvas handle\n * it lives on arrives a render after this hook runs.\n *\n * Given one, a cursor the CSS tier cannot express — sized in world units, or\n * past the size the browser drops the image at — is published here and drawn\n * by the painted-cursor layer instead. Without one, such a cursor resolves to\n * `none` and the pointer shows nothing.\n */\n paintedCursor?: () => PaintedCursorState | undefined;\n\n /**\n * Thunk returning the live `RuleCtx` for the current frame. When supplied,\n * the dispatcher filters matched candidates by their declared\n * `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`\n * wires this; tests / harnesses without chrome-caps state can omit it.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n\n /**\n * Which of the canvas element's input channels to attach. Every one\n * defaults to `true`; naming a channel `false` leaves its listeners\n * unattached, so the element behaves as if the dispatcher were not there.\n *\n * A mount that binds two gestures should not also have to take the rest of\n * the pipeline's side effects: `contextMenu` suppresses the native menu\n * unconditionally, and `ingest` makes the element a valid drop target and\n * styles it while an OS drag hovers. `@weasel-js/labkit`'s loupe mounts on\n * a lab's own canvas host for a wheel and a held key, and turning the other\n * three off is what keeps right-click and file drops working there.\n *\n * The window keyboard channel is `keyboard` instead of an entry here,\n * because `<SceneCanvas enableKeybindings>` drives it.\n */\n channels?: DispatcherChannels;\n\n /**\n * Routing for a canvas hosting more than one view: the non-root dispatch\n * records to choose between, read fresh per event, and the resolver that\n * chooses. Omit for a single view — then every event runs on the record the\n * flat options above describe, which is what they are: view zero.\n *\n * A resolved id with no live record falls back to the root, so a view that\n * unmounts mid-gesture degrades instead of dropping the event.\n *\n * Keyboard and paste have no coordinates to resolve; they run on the view\n * the last coordinate-bearing event resolved to.\n *\n * @internal\n */\n views?: {\n targets: () => readonly DispatcherViewTarget[];\n resolver: ViewIdResolver;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** A pointer held on the canvas, and everything a press is synthesized from. */\ninterface HeldPointer {\n session: PointerSession;\n /** Latest screen position, for the multitouch centroid and spread. */\n pos: { x: number; y: number };\n /** The press, withheld from the dispatcher until movement crosses\n * `DRAG_THRESHOLD_PX`. Null once forwarded, or once multitouch claimed\n * the pointer — see the multi-pointer policy in `onPointerDown`. */\n buffered: { ev: InputEvent; clientX: number; clientY: number } | null;\n /** Press-time state replayed onto a synthesized click, long-press or\n * contextmenu, whose matchers resolve targets against it. */\n down: {\n target: unknown;\n clientX: number;\n clientY: number;\n /** World-space press point, forwarded onto the synthesized click as\n * `pressX`/`pressY` — see `ClickEvent`. */\n worldX: number;\n worldY: number;\n affordance?: unknown;\n bodyTarget?: BodyTarget;\n bodyKind?: string;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n };\n}\n\n/**\n * Compute centroid and spread (distance between first two pointers) from\n * the active pointer positions. Returns a centroid of (0, 0) and spread\n * of 0 when fewer than 2 pointers are present.\n */\nfunction computeMultiTouchGeometry(\n positions: Iterable<{ x: number; y: number }>,\n): { centroid: { x: number; y: number }; spread: number } {\n const pts = [...positions];\n if (pts.length < 2) {\n return { centroid: { x: 0, y: 0 }, spread: 0 };\n }\n // Centroid across all active pointers.\n let sumX = 0;\n let sumY = 0;\n for (const p of pts) {\n sumX += p.x;\n sumY += p.y;\n }\n const centroid = { x: sumX / pts.length, y: sumY / pts.length };\n // Spread = distance between the first two pointers (primary pair).\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const spread = Math.sqrt(dx * dx + dy * dy);\n return { centroid, spread };\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\n/**\n * Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard and\n * multitouch listeners in, normalized input events out, routed through the\n * dispatcher to whichever action a binding names.\n *\n * Everything it needs beyond its options — the active tool, the dep registry —\n * comes from context, so it must be mounted inside `<SceneCanvas>`'s\n * providers.\n */\nexport function useGestureDispatcher(opts: UseGestureDispatcherOptions): void {\n const { canvasRef, actions, toolsById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, requestRedraw, paintedCursor, getRuleCtx, onDoubleClick, views, channels } = opts;\n // Read out as four booleans, not the object: the attach effect depends on\n // them, and an inline `channels={{...}}` would re-bind every listener on\n // every render.\n const pointerChannel = channels?.pointer !== false;\n const wheelChannel = channels?.wheel !== false;\n const contextMenuChannel = channels?.contextMenu !== false;\n const ingestChannel = channels?.ingest !== false;\n const onDoubleClickRef = useRef(onDoubleClick);\n onDoubleClickRef.current = onDoubleClick;\n const activeTool = useActiveToolContext();\n const depRegistry = useDepRegistry();\n\n // Single dispatcher instance, stable across renders. When a `dispatcher`\n // is supplied via options, adopt it; otherwise create one lazily.\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = dispatcherOpt ?? createDispatcher();\n }\n\n // Stable ref to the latest context values so event listeners always see\n // current state without needing to re-register on every render.\n // No `getRuleCtx` here: eligibility is a per-view answer, so it rides on the\n // dispatch record and `ctxNow` installs the routed view's.\n const ctxRef = useRef<DispatcherContext>({\n actions,\n depRegistry,\n activeToolId: activeTool.active,\n hotkeyStack: activeTool.hotkeyStack,\n toolsById,\n isMac: IS_MAC,\n });\n ctxRef.current = {\n actions,\n depRegistry,\n activeToolId: activeTool.active,\n hotkeyStack: activeTool.hotkeyStack,\n toolsById,\n isMac: IS_MAC,\n };\n\n // The flat options are view zero.\n const rootTargetRef = useRef<DispatcherViewTarget>({\n id: null, dispatcher: dispatcherRef.current, affordanceAt, classifyTarget, clientToWorld,\n getRuleCtx,\n });\n rootTargetRef.current = {\n id: null, dispatcher: dispatcherRef.current, affordanceAt, classifyTarget, clientToWorld,\n getRuleCtx,\n };\n const viewsRef = useRef(views);\n viewsRef.current = views;\n\n /** Every live dispatcher — what a cancel-everything has to reach. */\n const allDispatchers = (): Dispatcher[] => [\n rootTargetRef.current.dispatcher,\n ...(viewsRef.current?.targets() ?? []).map((t) => t.dispatcher),\n ];\n const requestRedrawRef = useRef(requestRedraw);\n requestRedrawRef.current = requestRedraw;\n const paintedCursorRef = useRef(paintedCursor);\n paintedCursorRef.current = paintedCursor;\n\n // Double-click synthesis state. Lives at hook level (not inside the effect)\n // so it survives effect re-runs — otherwise HMR / StrictMode / a transient\n // deps change resets it between the two clicks and the doubleclick never\n // fires.\n const lastClickRef = useRef<{ t: number; clientX: number; clientY: number } | null>(null);\n\n // Tool-switch lifecycle. Two things have to happen when the active tool\n // changes (and only then — not on initial mount):\n // 1. Fire the outgoing tool's `onDeactivate(ctx)` so it can clean up\n // tool-owned scratch state. Pen relies on this to discard a\n // half-built path the user hasn't committed.\n // 2. Cancel any in-flight ongoing dispatcher handles so the new tool\n // doesn't inherit a live gesture.\n //\n // The `ToolCtx` passed to `onDeactivate` is intentionally minimal — at\n // this lifecycle moment there's no event-driven cursor position, hit\n // result, or modifier state to populate. We pass the tool's own scratch\n // (via `initScratch()`, which tools that hold persistent state implement\n // as a singleton ref-return) so cleanup hooks can read/mutate the only\n // state they actually care about. Fields the implementation reads beyond\n // `scratch` will read undefined; tools whose cleanup needs more should\n // either rely on closure-captured refs (the pen-tool pattern) or wait\n // until we have a real cause to broaden the contract.\n const prevActiveRef = useRef(activeTool.active);\n useEffect(() => {\n if (prevActiveRef.current !== activeTool.active) {\n const prevTool = toolsById.get(prevActiveRef.current) as Tool<unknown> | undefined;\n if (prevTool?.onDeactivate) {\n const scratch = prevTool.initScratch?.();\n try {\n prevTool.onDeactivate({ scratch } as unknown as ToolCtx<unknown>);\n } catch (err) {\n console.error(\n `weasel: tool \"${prevActiveRef.current}\".onDeactivate threw`,\n err,\n );\n }\n }\n for (const d of allDispatchers()) d.cancelAll('cancel');\n }\n prevActiveRef.current = activeTool.active;\n });\n\n useEffect(() => {\n if (!enabled) return;\n\n let disposed = false;\n\n // The view the current event belongs to, as an id rather than a record:\n // the record is rebuilt every render, so holding one across events would\n // dispatch through last render's lookups.\n let routedId: string | null = null;\n\n /** The dispatch record for the routed view. */\n const target = (): DispatcherViewTarget => {\n if (routedId === null) return rootTargetRef.current;\n return viewsRef.current?.targets().find((t) => t.id === routedId)\n ?? rootTargetRef.current;\n };\n\n /** Route an event with coordinates. `pointerId` is `null` for input with\n * nothing to capture — wheel, hover, contextmenu, drop. */\n const routeAt = (pointerId: number | null, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.at(pointerId, clientX, clientY).id ?? null;\n };\n /** Route a pointerdown, pinning the pointer to the view it landed in. */\n const routeDown = (pointerId: number, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.begin(pointerId, clientX, clientY).id ?? null;\n };\n const routeRelease = (pointerId: number): void => {\n viewsRef.current?.resolver.end(pointerId);\n };\n\n // Resolved per event, not bound once: the dispatcher an event runs on is\n // a property of the view it landed in.\n const dispatcherNow = (): Dispatcher => target().dispatcher;\n\n const routedDeps = withViewDeps(() => ctxRef.current.depRegistry, () => target().deps?.());\n // Eligibility is evaluated against the routed view's rule context, not the\n // surface's — same reason its deps are.\n const routedRuleCtx = (): ReturnType<NonNullable<DispatcherViewTarget['getRuleCtx']>> =>\n target().getRuleCtx?.();\n const ctxNow = (): DispatcherContext => ({\n ...ctxRef.current, depRegistry: routedDeps, getRuleCtx: routedRuleCtx,\n });\n const canvas = canvasRef.current;\n\n // Convert a client-space pointer position to world-space. When no\n // `clientToWorld` thunk is wired (legacy harnesses / tests), this is the\n // identity — preserves pre-fix behavior for callers that pass raw event\n // coords as if they were world. SceneCanvas always wires the thunk via\n // its canvas rect + current view, so `ctx.world` becomes real world coords\n // for areaSelect / lassoSelect / world-space affordance consumers.\n const toWorld = (cx: number, cy: number): { x: number; y: number } => {\n const fn = target().clientToWorld;\n return fn ? fn(cx, cy) : { x: cx, y: cy };\n };\n\n // Dispatch + bump the host canvas's redraw when any handle was in flight\n // before, during, or after the event. Without this, dispatcher-only\n // overlays (marquee, lasso) never repaint after their initial frame.\n // `before` captures the pre-event state so we redraw on the pump that\n // CLOSES a gesture (e.g. pointerup-with-no-remaining-handles still needs\n // to clear the overlay).\n //\n // `on` is for the one path that dispatches after its event has left the\n // stack (drop, whose items materialize async) — by then the routed view\n // is whatever moved under the cursor since.\n const dispatch = (ev: InputEvent, on?: Dispatcher): 'handled' | 'unhandled' => {\n const d = on ?? dispatcherNow();\n const before = d.inFlight().size;\n const result = d.handleInput(ev, ctxNow());\n const after = d.inFlight().size;\n if (before > 0 || after > 0) requestRedrawRef.current?.();\n return result;\n };\n\n // Tracks keys that have an in-flight key-held handle so we fire the up\n // phase only when warranted.\n const heldKeys = new Set<string>();\n\n // Every pointer currently held on the canvas, one `openPointerSession`\n // each. The session owns capture, pointer identity, teardown and the\n // three recovery rules; the record owns what the dispatcher synthesizes.\n const held = new Map<number, HeldPointer>();\n // Pinch anchors land in `zoomAt`, which measures from the canvas top-left,\n // so the centroid is converted here — the same step the wheel listener\n // takes for its own anchor. Client coords would drift the zoom by the\n // canvas's offset from the viewport.\n const toCanvasLocal = (p: { x: number; y: number }): { x: number; y: number } => {\n const rect = canvas?.getBoundingClientRect();\n if (!rect) return p;\n const [x, y] = clientToCanvasRect(rect, p.x, p.y);\n return { x, y };\n };\n const heldGeometry = () => {\n const { centroid, spread } = computeMultiTouchGeometry(\n [...held.values()].map((p) => p.pos),\n );\n return { centroid: toCanvasLocal(centroid), spread };\n };\n\n // Tracks the start state of an active multitouch episode so we can\n // synthesize a `multitouchtap` event on release when the centroid hasn't\n // moved past the tap threshold. `fingers` records the peak count.\n let multiTouchStart: { fingers: number; centroid: { x: number; y: number } } | null = null;\n const TAP_THRESHOLD_PX = 8;\n\n // Pixel distance the pointer must travel between pointerdown and the first\n // pointermove before we treat the gesture as a drag and forward the\n // pointerdown to the dispatcher. Below this, pointerup is treated as a\n // click — no drag handle is ever opened, so `moveAction` (and other\n // ongoing drag actions) don't fire on a stationary press-and-release.\n const DRAG_THRESHOLD_PX = 4;\n\n // Long-press synthesis. Armed on pointerdown for touch/pen, cancelled by\n // movement past DRAG_THRESHOLD_PX, by release, by cancel, or by a second\n // pointer landing (so it can never fire mid-pinch).\n const LONG_PRESS_MS = 500;\n const longPressTimers = new Map<number, ReturnType<typeof setTimeout>>();\n\n const cancelLongPress = (pointerId: number): void => {\n const t = longPressTimers.get(pointerId);\n if (t !== undefined) {\n clearTimeout(t);\n longPressTimers.delete(pointerId);\n }\n };\n\n const cancelAllLongPress = (): void => {\n for (const t of longPressTimers.values()) clearTimeout(t);\n longPressTimers.clear();\n };\n\n /** Fire a synthesized long-press, falling back to contextmenu when the\n * long-press matched nothing. The fallback is what makes existing\n * `contextMenu` bindings reachable by touch with no consumer change. */\n const fireLongPress = (pointerId: number): void => {\n const down = held.get(pointerId)?.down;\n if (!down) return;\n\n const shared = {\n target: down.target,\n altKey: down.altKey,\n ctrlKey: down.ctrlKey,\n metaKey: down.metaKey,\n shiftKey: down.shiftKey,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n\n const result = dispatch({\n kind: 'longpress',\n x: down.worldX,\n y: down.worldY,\n clientX: down.clientX,\n clientY: down.clientY,\n ...shared,\n } as InputEvent);\n\n if (result === 'unhandled') {\n dispatch({\n kind: 'contextmenu',\n worldX: down.worldX,\n worldY: down.worldY,\n ...shared,\n } as InputEvent);\n }\n };\n\n // Double-click synthesis thresholds. 600ms matches the upper end of OS\n // double-click settings; 8px tolerates the natural drift of a real\n // mouse / trackpad between the two clicks. State (`lastClickRef`)\n // lives at hook level so it survives effect re-runs.\n const DOUBLE_CLICK_MAX_MS = 600;\n const DOUBLE_CLICK_MAX_PX = 8;\n\n // -----------------------------------------------------------------------\n // Window key listeners\n // -----------------------------------------------------------------------\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (isEditableTarget(e.target)) return;\n\n // Autorepeat for a key that's already engaged a key-held binding is\n // suppressed entirely — no dispatch (no trace flood) and the\n // browser default is blocked. Holding Space-for-hand otherwise\n // streamed an 'unhandled' immediate-`key` trace entry per repeat.\n // Autorepeat for a key that ISN'T held still dispatches normally,\n // so things like Cmd+= step-zoom keep auto-repeating.\n if (e.repeat && heldKeys.has(e.key)) {\n e.preventDefault();\n return;\n }\n\n // Dispatch both key and key-held forms unconditionally. The dispatcher\n // de-dupes naturally because each form uses a different gestureId and\n // different GestureSpec kind. `matchBest` returns 'unhandled' when no\n // binding matches the alternate form, so there's no double-fire risk.\n\n const keyEv: InputEvent = {\n kind: 'key',\n key: e.key,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n repeat: e.repeat,\n };\n const keyResult = dispatch(keyEv);\n\n // Always dispatch key-held DOWN, even on autorepeat. The dispatcher's\n // own defense returns 'handled' (no-op) when a handle is already in\n // flight for this gestureId, which both prevents start() re-invocation\n // and lets us preventDefault the repeat so the page doesn't react.\n const heldEv: InputEvent = {\n kind: 'key-held',\n key: e.key,\n phase: 'down',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n const heldResult = dispatch(heldEv);\n\n if (heldResult === 'handled') {\n heldKeys.add(e.key);\n }\n\n if (keyResult === 'handled' || heldResult === 'handled') {\n e.preventDefault();\n }\n };\n\n const onKeyUp = (e: KeyboardEvent) => {\n if (!heldKeys.has(e.key)) return;\n const ev: InputEvent = {\n kind: 'key-held',\n key: e.key,\n phase: 'up',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n heldKeys.delete(e.key);\n };\n\n // A window that loses focus never delivers the keyup, so without this every\n // in-flight key-held handle stays engaged until that key is pressed again.\n // Nor can a drag trust the release it may or may not see later, so every\n // held pointer is canceled — through its session, which reports once.\n const onWindowBlur = () => {\n for (const p of [...held.values()]) p.session.cancel();\n for (const key of heldKeys) {\n const ev: InputEvent = {\n kind: 'key-held',\n key,\n phase: 'up',\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n };\n dispatch(ev);\n }\n heldKeys.clear();\n };\n\n // -----------------------------------------------------------------------\n // Canvas wheel listener\n // -----------------------------------------------------------------------\n\n const onWheel = (e: WheelEvent) => {\n routeAt(null, e.clientX, e.clientY);\n // Convert client-space cursor to canvas-local: zoomAt() (and any other\n // wheel consumer of clientX/Y) anchors in canvas-top-left coords, not\n // viewport coords. Without this, anchored-wheel zoom drifts by the\n // canvas's offset from the viewport top-left.\n const rect = canvas?.getBoundingClientRect();\n const [localX, localY] = rect\n ? clientToCanvasRect(rect, e.clientX, e.clientY)\n : [e.clientX, e.clientY];\n const hitPoint = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(hitPoint) ?? undefined;\n const body = target().classifyTarget?.(hitPoint);\n const ev: InputEvent = {\n kind: 'wheel',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n deltaX: e.deltaX,\n deltaY: e.deltaY,\n clientX: localX,\n clientY: localY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(body?.body !== undefined ? { bodyTarget: body.body } : {}),\n ...(body?.kind !== undefined ? { bodyKind: body.kind } : {}),\n };\n const result = dispatch(ev);\n // When a binding claims the wheel (viewport.zoom on Cmd+wheel, viewport.pan\n // on plain wheel, etc.), the page must not also scroll. Suppress the\n // default + bubble so a parent scroll container doesn't move while the\n // canvas is zooming or panning.\n if (result === 'handled') {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n // -----------------------------------------------------------------------\n // Canvas pointer listeners + multi-touch synthesis\n // -----------------------------------------------------------------------\n\n const onPointerDown = (e: PointerEvent) => {\n // Only the primary button drives gesture dispatch. `pointerdown` reports\n // `button === 0` for the left mouse button and for touch / pen contact;\n // secondary (right, `2`) and middle (`1`) mouse buttons are left for the\n // consumer's own tools (e.g. right-drag viewport pan) and the browser\n // context menu. Without this guard a right-drag is classified and routed\n // exactly like a left-drag — selecting + transforming under the cursor\n // instead of letting an ambient pan tool claim it. An absent `button`\n // (synthetic / programmatic events) counts as primary.\n if ((e.button ?? 0) !== 0) return;\n if (!canvas) return;\n routeDown(e.pointerId, e.clientX, e.clientY);\n\n const w = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const body = target().classifyTarget?.(w);\n const bodyTarget = body?.body;\n const bodyKind = body?.kind;\n const ev: InputEvent = {\n kind: 'pointerdown',\n target: e.target,\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n // The session owns the rest of this pointer: capture, the moves and the\n // release, and the three recovery rules for a release that never\n // arrives. A press on a pointer one is already open for cancels that\n // stale gesture before this handler runs — its `pointerdown` listener is\n // on the document, in the capture phase, ahead of this one on the canvas.\n held.set(e.pointerId, {\n session: openPointerSession(canvas, e, {\n onMove: onPointerMove,\n onEnd: onPointerUp,\n onCancel: () => { onPointerCancel(e.pointerId); },\n }),\n pos: { x: e.clientX, y: e.clientY },\n // Deferred until the first past-threshold pointermove: a bare\n // press-and-release should fire `click`, not start a drag action.\n buffered: { ev, clientX: e.clientX, clientY: e.clientY },\n down: {\n target: e.target,\n clientX: e.clientX,\n clientY: e.clientY,\n worldX: w.x,\n worldY: w.y,\n affordance,\n bodyTarget,\n bodyKind,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n },\n });\n\n // The press itself dispatches now, for bindings that must act while the\n // button is still down and before the gesture is classified (select\n // highlights the pressed node here). `matchSpec` routes the two copies\n // to disjoint spec kinds — `pointerDown` matches only this one, `drag`\n // only the buffered one — so a single press never fires both.\n //\n // Withheld once a second pointer is down: this press belongs to the\n // multitouch channel under the MULTI-POINTER POLICY below, which clears\n // the buffered copy for the same reason. Without this a pinch's second\n // finger ran `select.pick` and moved the selection under the gesture.\n if (held.size < 2) dispatch({ ...ev, stage: 'press' });\n\n // Arm long-press for touch / pen only, and only for a lone pointer —\n // a second finger means a multi-touch gesture, not a long-press.\n if ((e.pointerType === 'touch' || e.pointerType === 'pen')\n && held.size === 1) {\n cancelLongPress(e.pointerId);\n longPressTimers.set(\n e.pointerId,\n setTimeout(() => {\n longPressTimers.delete(e.pointerId);\n if (disposed) return;\n fireLongPress(e.pointerId);\n }, LONG_PRESS_MS),\n );\n }\n\n // Synthesize a multi-touch event when >= 2 pointers are active.\n if (held.size >= 2) {\n cancelAllLongPress();\n // MULTI-POINTER POLICY: the multitouch channel takes ownership of\n // every pointer that hasn't already committed to a gesture. Clearing\n // the buffered press is what enforces it — a claimed pointer opens no\n // drag handle on the next move, and synthesizes no click on release\n // (both of those read the buffer). The `multitouch-<fingers>` handle\n // and the `multitouchtap` synthesis below are the whole gesture.\n //\n // This used to hold by accident: `gestureIdFor` returned one key for\n // every pointer, so a second finger's press found the first's handle\n // in flight and no-oped. Per-pointer keying removes the accident, so\n // the policy has to be stated. Stating it is the improvement — a\n // pointer that is part of a pinch is not also dragging something.\n //\n // Note the asymmetry: a pointer that already opened a drag has no\n // buffer left to claim, so its gesture survives the second finger\n // landing. Yanking a drag out from under someone who rested a palm is\n // worse than letting it finish.\n for (const p of held.values()) p.buffered = null;\n\n const { centroid, spread } = heldGeometry();\n // Capture start state for tap synthesis. On the first 1→2 transition\n // we record the centroid; subsequent pointerdowns at higher finger\n // counts only bump the recorded peak fingers count.\n if (!multiTouchStart) {\n multiTouchStart = { fingers: held.size, centroid: { ...centroid } };\n } else {\n multiTouchStart.fingers = held.size;\n }\n const mt: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mt);\n }\n };\n\n const onPointerMove = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n const rec = held.get(e.pointerId);\n if (rec) rec.pos = { x: e.clientX, y: e.clientY };\n\n // Threshold gate: if a pointerdown is buffered for this pointer and\n // the movement crossed the drag threshold, forward the buffered\n // pointerdown to the dispatcher BEFORE the pointermove. This is what\n // opens the ongoing drag handle (matching `kind: 'drag'` bindings);\n // subsequent pointermoves pump it via `onMove`. Sub-threshold\n // pointermoves are still forwarded so existing pump paths (e.g. other\n // in-flight handles) keep working, but they're no-ops when no handle\n // exists.\n const buffered = rec?.buffered;\n if (rec && buffered) {\n const dx = e.clientX - buffered.clientX;\n const dy = e.clientY - buffered.clientY;\n if (Math.hypot(dx, dy) >= DRAG_THRESHOLD_PX) {\n rec.buffered = null;\n cancelLongPress(e.pointerId);\n dispatch(buffered.ev);\n }\n }\n\n // If a multitouch handle is in flight, synthesize a multitouch pump event\n // with the updated centroid + spread. The dispatcher routes this to the\n // handle's onMove (because the event carries centroid data).\n const mtGestureId = `multitouch-${held.size}`;\n if (held.size >= 2 && dispatcherNow().inFlight().has(mtGestureId)) {\n const { centroid, spread } = heldGeometry();\n const mtEv: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mtEv);\n // Also dispatch the raw pointermove so single-pointer handles can coexist.\n }\n\n const w = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointermove',\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n };\n dispatch(ev);\n\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n refreshHoverCursor();\n };\n\n // -----------------------------------------------------------------------\n // Hover-cursor pump\n // -----------------------------------------------------------------------\n //\n // On every idle pointermove (no pressed pointer, no in-flight handle),\n // resolve what sits under the pointer and write a cursor override\n // directly to `canvas.style.cursor`. Precedence:\n //\n // 1. Affordance hit declaring `AffordanceHit.cursor` (resize corners,\n // rotate ring) — the same `affordanceAt` hit-test pointerdown uses.\n // 2. The action a drag from here would route to (`resolveOnly`, the\n // same match walk pointerdown takes), when it declares\n // `Action.cursor` — e.g. `viewport.dragPan` → 'grab' over empty\n // canvas when pan would win the drag.\n // 3. Otherwise the action a click here would route to, when it\n // declares one — e.g. Alt over a path segment in path-edit mode.\n // 4. No override — clear the inline style so the active tool's\n // React-managed `Tool.cursor` (the implicit base) shows through.\n //\n // Mid-gesture the pump stands down; the tool-cursor pipeline\n // (function-form `Tool.cursor` re-resolving on `gestureTick`) owns the\n // cursor there. The override is an inline style on purpose: clearing it\n // restores the React-managed base without effect churn.\n //\n // `lastHover` lets modifier keydown/keyup refresh the prediction without\n // pointer movement (a held Space re-routes the drag to the hand tool).\n // That refresh is deferred a tick so React can commit the hotkey-stack /\n // active-tool state the key event just changed — `ctxRef` is only\n // rewritten on render.\n let lastHover: {\n clientX: number; clientY: number;\n altKey: boolean; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean;\n } | null = null;\n let cursorOverridden = false;\n const clearHoverCursor = () => {\n paintedCursorRef.current?.()?.setOverride(null);\n if (cursorOverridden && canvas) {\n canvas.style.cursor = '';\n cursorOverridden = false;\n }\n };\n const applyHoverCursor = (spec: CursorSpec | null) => {\n const tier = spec === null ? null : resolveCursorTier(spec);\n if (!tier || !canvas) {\n clearHoverCursor();\n return;\n }\n // A painted cursor is two writes, not one: the native cursor gets out of\n // the way and the layer is told what to draw. Doing only the first is a\n // pointer with no cursor at all.\n const painted = tier.kind === 'painted' ? tier : null;\n paintedCursorRef.current?.()?.setOverride(painted);\n const cursor = tier.kind === 'css' ? tier.css : 'none';\n if (!cursor) {\n clearHoverCursor();\n return;\n }\n canvas.style.cursor = cursor;\n cursorOverridden = true;\n };\n /**\n * Where the painted-cursor layer should draw, in canvas-local CSS px.\n *\n * Pushed after the cursor has been resolved, not before: on the move that\n * first selects a painted cursor, a position written ahead of the decision\n * is discarded and the glyph does not appear until the next move. Guarded\n * on `active()`, so an ordinary CSS cursor costs no layout read per move.\n */\n function pushPaintedPointer(): void {\n const painted = paintedCursorRef.current?.();\n if (!painted?.active() || !canvas || !lastHover) return;\n const r = canvas.getBoundingClientRect();\n painted.setPointer(lastHover.clientX - r.left, lastHover.clientY - r.top);\n }\n\n function refreshHoverCursor(): void {\n resolveHoverCursor();\n pushPaintedPointer();\n }\n\n function resolveHoverCursor(): void {\n if (!canvas || !lastHover) return;\n // Mid-gesture the prediction is meaningless — what matters is what the\n // gesture IS. An in-flight action's `activeCursor` wins; with none\n // declared the override clears and the active tool's `Tool.cursor`\n // shows through, as before.\n if (held.size > 0 || dispatcherNow().inFlight().size > 0) {\n applyHoverCursor(dispatcherNow().inFlightCursor());\n return;\n }\n const h = lastHover;\n // Idle: re-resolve. Mid-gesture the branch above already returned, so a\n // pinned pointer is never unpinned by a hover refresh.\n routeAt(null, h.clientX, h.clientY);\n const w = toWorld(h.clientX, h.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n if (affordance?.cursor) {\n applyHoverCursor(affordance.cursor);\n return;\n }\n const hoverBody = target().classifyTarget?.(w);\n const bodyTarget = hoverBody?.body;\n const bodyKind = hoverBody?.kind;\n const where = {\n altKey: h.altKey,\n ctrlKey: h.ctrlKey,\n metaKey: h.metaKey,\n shiftKey: h.shiftKey,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n const ctx = ctxNow();\n const dragCursor = dispatcherNow().resolveOnly(\n { kind: 'pointerdown', x: w.x, y: w.y, clientX: h.clientX, clientY: h.clientY, ...where },\n ctx,\n )?.action.cursor;\n // A drag's hint first; failing that, what a click here would do.\n const cursor = dragCursor ?? dispatcherNow().resolveOnly(\n { kind: 'click', worldX: w.x, worldY: w.y, pressX: w.x, pressY: w.y, ...where },\n ctx,\n )?.action.cursor;\n applyHoverCursor(cursor ?? null);\n }\n /** Modifier/hotkey changes re-route the predicted drag without pointer\n * movement. Refresh after a tick so the key event's React state\n * (hotkey stack, active tool) has committed into `ctxRef`. */\n const scheduleHoverCursorRefresh = (e: KeyboardEvent) => {\n if (!lastHover) return;\n lastHover = {\n ...lastHover,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n // A held pointer's moves arrive through its session, which keeps seeing\n // them once the pointer has left the canvas or the canvas is gone. The\n // canvas listener is left with the hover half.\n const onHoverMove = (e: PointerEvent) => {\n if (held.has(e.pointerId)) return;\n onPointerMove(e);\n };\n\n const onHoverPointerLeave = () => {\n lastHover = null;\n paintedCursorRef.current?.()?.clearPointer();\n clearHoverCursor();\n };\n\n const onPointerUp = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n cancelLongPress(e.pointerId);\n const prevSize = held.size;\n // The record outlives the map entry: everything below is synthesized\n // from the press, and reads it after this pointer has stopped counting\n // towards `held.size`.\n const rec = held.get(e.pointerId);\n held.delete(e.pointerId);\n\n // A press still buffered never crossed the drag threshold — the\n // dispatcher never saw it, so no drag handle is in flight and this\n // release is a click. Crossing the threshold clears the buffer whether\n // or not a drag binding matched, which makes this the authoritative\n // \"did the pointer move?\" signal for click synthesis.\n const staysUnderThreshold = rec?.buffered != null;\n\n // When pointer count drops below 2, commit any in-flight multitouch handle\n // and (if the centroid never moved past the tap threshold) synthesize a\n // `multitouchtap` event carrying the peak fingers count.\n // The gestureId is keyed by the PREVIOUS size (before this pointer was removed)\n // because that was the handle's finger count when it was opened.\n if (prevSize >= 2 && held.size < 2) {\n const mtGestureId = `multitouch-${prevSize}`;\n if (dispatcherNow().inFlight().has(mtGestureId)) {\n // Synthesize a pointerup for the multitouch gesture — dispatcher needs\n // a pointerup to route to onEnd, but multitouch handles are keyed by\n // finger count, not by pointer. We use cancelAll to safely commit all\n // in-flight handles of this gesture; only the multitouch handle\n // should be active (see the multi-pointer policy in onPointerDown).\n // Use 'commit' because this is a natural lift (not a cancel).\n dispatcherNow().cancelAll('commit');\n }\n // Synthesize a tap if the centroid hasn't moved past threshold.\n const start = multiTouchStart;\n if (start) {\n // Final centroid uses the pointer positions BEFORE this pointer was\n // removed — it is already out of `held`, so add it back in.\n const centroid = toCanvasLocal(\n computeMultiTouchGeometry([\n ...[...held.values()].map((p) => p.pos),\n { x: e.clientX, y: e.clientY },\n ]).centroid,\n );\n const dx = centroid.x - start.centroid.x;\n const dy = centroid.y - start.centroid.y;\n if (Math.hypot(dx, dy) <= TAP_THRESHOLD_PX) {\n const tap: InputEvent = {\n kind: 'multitouchtap',\n fingers: start.fingers,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(tap);\n }\n multiTouchStart = null;\n }\n }\n\n // Check whether a drag handle is in-flight BEFORE sending pointerup.\n // If THIS pointer's handle is in-flight AND the pointer moved between\n // down and up, this is the end of a real drag — pump it and don't\n // synthesize a click. If no handle is in-flight, or the handle was\n // opened but the pointer never moved (sub-threshold \"tap\" that an\n // over-broad ambient drag binding accepted), we still synthesize a\n // click so click-specific bindings (e.g. clearSelection on empty) fire.\n const movedDuringDrag = rec\n ? (rec.down.clientX !== e.clientX || rec.down.clientY !== e.clientY)\n : true;\n const hadDragInFlight =\n dispatcherNow().inFlight().has(pointerGestureId(e.pointerId)) && movedDuringDrag;\n\n const wUp = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointerup',\n pointerId: e.pointerId,\n x: wUp.x,\n y: wUp.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n\n const down = rec?.down;\n\n // Synthesize a click when the pointer neither opened a drag handle nor\n // travelled past the drag threshold. Carry the `bodyTarget` from the\n // pointerdown so click specs with string-form targets ('empty',\n // 'selected-body') match.\n //\n // The threshold half of that test is load-bearing for any tool that\n // binds `click` but not `drag`: without it, dragging clear across the\n // canvas and releasing synthesized a click, because \"no drag handle\n // opened\" was the only condition. `ClickSpec` documents itself as\n // \"pointerdown + pointerup without movement past the threshold\" — this\n // is the code finally agreeing with it.\n if (!hadDragInFlight && staysUnderThreshold && down) {\n const wClick = toWorld(e.clientX, e.clientY);\n const clickEv: InputEvent = {\n kind: 'click',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n worldX: wClick.x,\n worldY: wClick.y,\n pressX: down.worldX,\n pressY: down.worldY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n dispatch(clickEv);\n\n // Double-click synthesis: emit a `doubleclick` event AFTER the\n // second click when two clicks land within DOUBLE_CLICK_MAX_MS and\n // DOUBLE_CLICK_MAX_PX. Reset the tracker after a successful\n // doubleclick so a third click doesn't compose another one\n // (triple-click semantics are not modeled).\n const now = Date.now();\n const prev = lastClickRef.current;\n const dx = e.clientX - (prev?.clientX ?? 0);\n const dy = e.clientY - (prev?.clientY ?? 0);\n if (prev && now - prev.t < DOUBLE_CLICK_MAX_MS && Math.hypot(dx, dy) < DOUBLE_CLICK_MAX_PX) {\n const dblEv: InputEvent = {\n kind: 'doubleclick',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n worldX: wClick.x,\n worldY: wClick.y,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n // Notify observers first — see `onDoubleClick`'s doc for why this\n // is not modeled as a binding.\n onDoubleClickRef.current?.({ x: wClick.x, y: wClick.y });\n dispatch(dblEv);\n lastClickRef.current = null;\n } else {\n lastClickRef.current = { t: now, clientX: e.clientX, clientY: e.clientY };\n }\n }\n\n // Every synthesized event this release produces has been dispatched, so\n // the pointer's view can be unpinned.\n routeRelease(e.pointerId);\n\n // Re-resolve the hover cursor at the release point — deferred a tick\n // so any state the up/click actions changed (selection, active tool)\n // has committed before prediction reruns.\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n\n // Every way a gesture ends without a release: the browser cancelling the\n // pointer, capture going away, a press proving the tracked one had already\n // ended. The session decides which of those happened; the dispatcher\n // treats them alike, and reads the press's own modifiers because a cancel\n // carries none of its own.\n const onPointerCancel = (pointerId: number) => {\n // On teardown every session is cancelled at once; `cancelAll` ends those\n // gestures, so re-entering dispatch here would end them twice.\n if (disposed) return;\n const rec = held.get(pointerId);\n if (!rec) return;\n held.delete(pointerId);\n routeAt(pointerId, rec.pos.x, rec.pos.y);\n cancelLongPress(pointerId);\n // Drop any pending multitouch-tap start state — a cancel means we should\n // not synthesize a tap on the subsequent up.\n multiTouchStart = null;\n const ev: InputEvent = {\n kind: 'pointercancel',\n pointerId,\n altKey: rec.down.altKey,\n ctrlKey: rec.down.ctrlKey,\n metaKey: rec.down.metaKey,\n shiftKey: rec.down.shiftKey,\n };\n dispatch(ev);\n routeRelease(pointerId);\n };\n\n // -----------------------------------------------------------------------\n // Canvas contextmenu listener (right-click)\n // -----------------------------------------------------------------------\n\n const onContextMenu = (e: MouseEvent) => {\n // Suppress native menu so tools/actions own the right-click UX.\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const w = toWorld(e.clientX, e.clientY);\n // A secondary button never reaches `onPointerDown`, so unlike click and\n // long-press there is no press to replay the classification from.\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const menuBody = target().classifyTarget?.(w);\n const ev: InputEvent = {\n kind: 'contextmenu',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n worldX: w.x,\n worldY: w.y,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(menuBody?.body !== undefined ? { bodyTarget: menuBody.body } : {}),\n ...(menuBody?.kind !== undefined ? { bodyKind: menuBody.kind } : {}),\n };\n dispatch(ev);\n };\n\n // -----------------------------------------------------------------------\n // External-content ingestion: OS drop on the canvas, paste on window.\n // Items are materialized DURING the event (DataTransfer is only live on\n // the event stack); dispatch happens when materialization resolves.\n // -----------------------------------------------------------------------\n\n // Attached to both dragover and dragenter: cancelling dragenter (WHATWG)\n // guarantees the element stays the active drop target and shows the copy\n // cursor on entry rather than waiting for the first dragover tick.\n const onDragOver = (e: DragEvent) => {\n if (!e.dataTransfer) return;\n // preventDefault is what makes the canvas a valid drop target.\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n canvas?.classList.add(DROPOVER_CLASS);\n };\n\n const onDragLeave = () => {\n canvas?.classList.remove(DROPOVER_CLASS);\n };\n\n // No stopPropagation: handled-ness is only known after the async\n // materialization microtask, so a conditional stop (wheel-style) is\n // impossible; an unconditional one would swallow drops the kit doesn't\n // dispatch. Callers that need exclusivity should gate on the action result.\n const onDrop = (e: DragEvent) => {\n canvas?.classList.remove(DROPOVER_CLASS);\n const dt = e.dataTransfer;\n if (!dt) return;\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const dropOn = target().dispatcher;\n const w = toWorld(e.clientX, e.clientY);\n // Real modifiers forwarded (Option-drag is a copy-drag on macOS); the\n // kit ingest binding declares all modifiers optional, so they can't\n // block the default route — but a consumer binding may key on them.\n const base = {\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n void itemsFromDataTransfer(dt).then((items) => {\n if (disposed) return;\n if (items.length === 0) return;\n dispatch({\n kind: 'drop', items,\n x: w.x, y: w.y, clientX: e.clientX, clientY: e.clientY,\n ...base,\n }, dropOn);\n });\n };\n\n const onPaste = (e: ClipboardEvent) => {\n // Text-editing surfaces (inputs, the text-edit overlay) own their own\n // paste — never steal it for scene ingestion.\n if (isEditableTarget(e.target)) return;\n const cd = e.clipboardData;\n if (!cd) return;\n const items = itemsFromClipboardData(cd);\n if (items.length === 0) return;\n // Wheel's shape: dispatch first, suppress the default only when a\n // binding claimed it. Clipboard items materialize synchronously, so\n // unlike `onDrop` the result is known while `preventDefault` is still\n // honored — and a paste no binding wanted stays the page's to handle.\n const result = dispatch({\n kind: 'paste', items,\n // ClipboardEvent carries no modifier state.\n altKey: false, ctrlKey: false, metaKey: false, shiftKey: false,\n });\n if (result === 'handled') e.preventDefault();\n };\n\n // -----------------------------------------------------------------------\n // Attach\n // -----------------------------------------------------------------------\n\n if (keyboard) {\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n }\n window.addEventListener('blur', onWindowBlur);\n // Hover-cursor refresh on modifier/hotkey changes — separate listeners\n // (not folded into onKeyDown/onKeyUp) so the pump also tracks modifiers\n // when `keyboard: false` disables gesture key dispatch.\n window.addEventListener('keydown', scheduleHoverCursorRefresh);\n window.addEventListener('keyup', scheduleHoverCursorRefresh);\n if (pointerChannel) {\n canvas?.addEventListener('pointerleave', onHoverPointerLeave);\n canvas?.addEventListener('pointerdown', onPointerDown);\n canvas?.addEventListener('pointermove', onHoverMove);\n }\n if (wheelChannel) canvas?.addEventListener('wheel', onWheel, { passive: false });\n if (contextMenuChannel) canvas?.addEventListener('contextmenu', onContextMenu);\n if (ingestChannel) {\n canvas?.addEventListener('dragenter', onDragOver);\n canvas?.addEventListener('dragover', onDragOver);\n canvas?.addEventListener('dragleave', onDragLeave);\n canvas?.addEventListener('drop', onDrop);\n window.addEventListener('paste', onPaste);\n }\n\n // -----------------------------------------------------------------------\n // Cleanup\n // -----------------------------------------------------------------------\n\n return () => {\n if (keyboard) {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n }\n window.removeEventListener('blur', onWindowBlur);\n window.removeEventListener('keydown', scheduleHoverCursorRefresh);\n window.removeEventListener('keyup', scheduleHoverCursorRefresh);\n canvas?.removeEventListener('pointerleave', onHoverPointerLeave);\n canvas?.removeEventListener('wheel', onWheel);\n canvas?.removeEventListener('pointerdown', onPointerDown);\n canvas?.removeEventListener('pointermove', onHoverMove);\n canvas?.removeEventListener('contextmenu', onContextMenu);\n canvas?.removeEventListener('dragenter', onDragOver);\n canvas?.removeEventListener('dragover', onDragOver);\n canvas?.removeEventListener('dragleave', onDragLeave);\n canvas?.removeEventListener('drop', onDrop);\n window.removeEventListener('paste', onPaste);\n // Detach is unconditional: a channel turned off mid-life must still\n // have whatever it attached while it was on taken back off.\n canvas?.classList.remove(DROPOVER_CLASS);\n clearHoverCursor();\n cancelAllLongPress();\n disposed = true;\n // `disposed` first: the sessions' cancels must not re-enter dispatch on\n // the way out, and `cancelAll` below is what ends the gestures.\n for (const p of held.values()) p.session.cancel();\n held.clear();\n for (const d of allDispatchers()) d.cancelAll('cancel');\n };\n }, [enabled, keyboard, canvasRef, pointerChannel, wheelChannel, contextMenuChannel, ingestChannel]);\n}\n","/**\n * @experimental\n * The React half of the actions registry: the context, the provider that owns\n * the id → descriptor stack, the mute scope, and the two hooks. The store\n * contract it implements is in `registry.tsx`.\n */\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { Action } from './action';\nimport { useOptionalDepRegistry, type DepRegistry, type DepName } from './depRegistry';\nimport { buildDepsFromRequires } from './buildDeps';\nimport type { Dispatcher } from '../dispatcher/dispatcher';\nimport { validateActionId, validateActionDefaultBinding, type ActionsRegistry } from './registry';\n\n\nconst ActionsContext = createContext<ActionsRegistry | null>(null);\n\n/** Everything a registry does apart from muting, which is layered on top of it\n * once per scope by `useMuted`. */\ntype ActionsStore = Omit<ActionsRegistry, 'mute'>;\n\n/**\n * Layers a mute set over `base`. Registration, `unregister`, `trigger`'s\n * effects, and the dispatcher / dep-registry slots all pass straight through,\n * so what one scope registers every sibling still sees; only this scope's own\n * reads and invocations skip what it muted.\n */\nfunction useMuted(base: ActionsStore | null): ActionsRegistry | null {\n const mutedRef = useRef<Map<string, number>>(new Map());\n const listenersRef = useRef<Set<() => void>>(new Set());\n const cacheRef = useRef<{ src: readonly Action[]; out: readonly Action[] } | null>(null);\n\n return useMemo<ActionsRegistry | null>(() => {\n if (!base) return null;\n const isMuted = (id: string): boolean => mutedRef.current.has(id);\n const notify = (): void => {\n for (const l of listenersRef.current) {\n try {\n l();\n } catch (err) {\n console.error('weasel ActionsRegistry: subscriber threw', err);\n }\n }\n };\n return {\n ...base,\n list: () => {\n const src = base.list();\n if (mutedRef.current.size === 0) return src;\n const cached = cacheRef.current;\n if (cached && cached.src === src) return cached.out;\n const out = Object.freeze(src.filter((a) => !mutedRef.current.has(a.id)));\n cacheRef.current = { src, out };\n return out;\n },\n trigger: (id, params) => (isMuted(id) ? false : base.trigger(id, params)),\n begin: (id, params) => (isMuted(id) ? null : base.begin(id, params)),\n subscribe: (listener) => {\n const offBase = base.subscribe(listener);\n listenersRef.current.add(listener);\n return () => {\n offBase();\n listenersRef.current.delete(listener);\n };\n },\n mute: (id: string) => {\n mutedRef.current.set(id, (mutedRef.current.get(id) ?? 0) + 1);\n cacheRef.current = null;\n notify();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const held = mutedRef.current.get(id);\n if (held === undefined) return;\n if (held > 1) mutedRef.current.set(id, held - 1);\n else mutedRef.current.delete(id);\n cacheRef.current = null;\n notify();\n };\n },\n };\n }, [base]);\n}\n\n/**\n * @experimental\n * A view of the registry in scope that can declare ids not for itself. Wrap\n * anything that should be able to opt out of an action — a second\n * `<SceneCanvas>` sharing the host's `<ActionsProvider>` mounts one — and its\n * `mute` calls stay inside it. Renders nothing of its own.\n *\n * Not a `BindingScope`: that names the tier a binding matches at (hotkey /\n * active / ambient), which this has nothing to do with.\n */\nexport function ActionsScope({ children }: { children: ReactNode }): ReactElement {\n const parent = useActionsRegistry();\n const scoped = useMuted(parent);\n if (!scoped) return <>{children}</>;\n return <ActionsContext.Provider value={scoped}>{children}</ActionsContext.Provider>;\n}\n\n/**\n * @experimental\n * Mounts an `ActionsRegistry` for its lifetime. Children call\n * `useActionsRegistry()` or `useAction()` to participate. Mounts no input\n * listener of its own — the gesture dispatcher owns input.\n */\n/**\n * Push `value` onto an owner stack and hand back its release.\n *\n * Newest wins, but the release takes out *its own* entry wherever it now sits,\n * so a displaced owner leaving cannot disturb the one above it and the owner\n * on top leaving uncovers the one below rather than emptying the stack. A\n * `null` value registers nothing and releases to a no-op. Double-release safe.\n */\nfunction pushOwner<T>(ref: { current: T[] }, value: T | null): () => void {\n if (value === null) return () => {};\n ref.current.push(value);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const i = ref.current.lastIndexOf(value);\n if (i !== -1) ref.current.splice(i, 1);\n };\n}\n\nexport function ActionsProvider({ children }: { children: ReactNode }): ReactElement {\n // A stack of registrants per id, newest live. Two canvases under one provider\n // both register `viewport.zoom`; with a single slot the second displaced the\n // first and its teardown then deleted the entry outright, taking wheel zoom\n // away from the canvas still on screen. Stacking means a displaced registrant\n // is restored when the one above it leaves.\n const actionsRef = useRef<Map<string, Action[]>>(new Map());\n const liveAction = (id: string): Action | undefined => actionsRef.current.get(id)?.at(-1);\n const versionRef = useRef(0);\n const cachedRef = useRef<readonly Action[]>([]);\n const cachedVerRef = useRef(-1);\n const listenersRef = useRef<Set<() => void>>(new Set());\n\n // Trigger() consults the optional dep registry so actions can be fired\n // imperatively from ActionBar / palette callers — the registered\n // `invoker.run` receives a deps bag built fresh from the registry.\n const depReg = useOptionalDepRegistry();\n const depRegRef = useRef<DepRegistry | null>(depReg);\n depRegRef.current = depReg;\n\n // One warning per registry: the message is about the scope, not about which\n // canvas lost, and a page of canvases would otherwise repeat it per mount.\n const warnedRef = useRef(false);\n\n // Dep registry wired via setDepRegistry — set by SceneCanvas's registrar\n // when this provider sits above the dep-registry scope (consumer root\n // <ActionsProvider>). Preferred over the context read above.\n //\n // A stack, newest live, for the same reason the registrant stacks above are:\n // two canvases under one provider both wire themselves, and with a single\n // slot whichever one unmounts empties it — taking the wiring away from the\n // canvas still on screen. The dispatcher ref below is the same story.\n const wiredDepRegRef = useRef<DepRegistry[]>([]);\n\n // Dispatcher stack — wired from SceneCanvas via setDispatcher so that\n // begin() can delegate to beginUiOngoing.\n const dispatcherRef = useRef<Dispatcher[]>([]);\n\n // The legacy keystroke loop that walked every action's\n // `defaultBinding: KeyBinding` and matched against keydown is gone, along\n // with the per-action consumer hooks (`useEscape`, `useDelete`, ...) that\n // carried their own `useKeybinding` listener. Every kit-standard descriptor\n // now routes through the gesture dispatcher via `defaultBinding`.\n\n const store = useMemo<ActionsStore>(() => {\n const snapshot = (): readonly Action[] => {\n const v = versionRef.current;\n if (cachedVerRef.current === v) return cachedRef.current;\n const out = Object.freeze(\n Array.from(actionsRef.current.values(), (stack) => stack[stack.length - 1]),\n );\n cachedRef.current = out;\n cachedVerRef.current = v;\n return out;\n };\n const notify = (): void => {\n for (const l of listenersRef.current) {\n try {\n l();\n } catch (err) {\n console.error('weasel ActionsRegistry: subscriber threw', err);\n }\n }\n };\n return {\n register: (action: Action) => {\n validateActionId(action.id);\n validateActionDefaultBinding(action);\n const stack = actionsRef.current.get(action.id);\n if (stack) stack.push(action);\n else actionsRef.current.set(action.id, [action]);\n versionRef.current++;\n notify();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = actionsRef.current.get(action.id);\n if (!cur) return;\n // Our own entry, wherever it now sits: a registrant that was already\n // displaced must take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(action);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) actionsRef.current.delete(action.id);\n versionRef.current++;\n notify();\n };\n },\n unregister: (id: string) => {\n // Drops every registrant of `id`, not just the live one — this is the\n // \"this action should not exist\" door, not a release.\n if (actionsRef.current.delete(id)) {\n versionRef.current++;\n notify();\n }\n },\n list: () => snapshot(),\n trigger: (id: string, params?: Record<string, unknown>) => {\n const a = liveAction(id);\n if (!a) return false;\n try {\n if (a.invoker && a.invoker.timing === 'immediate') {\n const r = wiredDepRegRef.current.at(-1) ?? depRegRef.current;\n // Prefer the action's declared `requires` (same contract the\n // dispatcher uses — shared `buildDepsFromRequires`, including\n // the dev-mode undeclared-read guard); legacy fixed bag\n // otherwise.\n const deps = !r\n ? {}\n : a.requires\n ? buildDepsFromRequires(a, r)\n : {\n selection: r.get('selection' as DepName),\n scene: r.get('scene' as DepName),\n history: r.get('history' as DepName),\n view: r.get('view' as DepName),\n activeTool: r.get('activeTool' as DepName),\n booleansAdapter: r.get('booleansAdapter' as DepName),\n };\n a.invoker.run(deps as never, params);\n }\n } catch (err) {\n console.error(`weasel ActionsRegistry: action \"${id}\" threw`, err);\n }\n return true;\n },\n subscribe: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => {\n listenersRef.current.delete(listener);\n };\n },\n setDispatcher: (d: Dispatcher | null) => {\n if (d && dispatcherRef.current.length > 0 && dispatcherRef.current.at(-1) !== d\n && !warnedRef.current) {\n warnedRef.current = true;\n warnSharedScope();\n }\n return pushOwner(dispatcherRef, d);\n },\n setDepRegistry: (r: DepRegistry | null) => pushOwner(wiredDepRegRef, r),\n begin: (id: string, params?: Record<string, unknown>) => {\n const disp = dispatcherRef.current.at(-1) ?? null;\n if (!disp) return null;\n const r = wiredDepRegRef.current.at(-1) ?? depRegRef.current;\n const a = liveAction(id);\n // Same resolution order as `trigger`: the action's declared `requires`\n // when it has one, the legacy fixed bag otherwise. The fixed bag has no\n // `applyOps`, so the paint actions — which declare it and are the only\n // callers of `begin` — used to fall back to the scene's own history\n // instead of the consumer's.\n const deps = !r\n ? {}\n : a?.requires\n ? buildDepsFromRequires(a, r)\n : {\n selection: r.get('selection' as DepName),\n scene: r.get('scene' as DepName),\n history: r.get('history' as DepName),\n view: r.get('view' as DepName),\n activeTool: r.get('activeTool' as DepName),\n booleansAdapter: r.get('booleansAdapter' as DepName),\n };\n return disp.beginUiOngoing(id, deps as never, params);\n },\n };\n }, []);\n\n // The provider is a scope in its own right, so a lone canvas can mute\n // without one wrapped around it.\n const registry = useMuted(store)!;\n\n return <ActionsContext.Provider value={registry}>{children}</ActionsContext.Provider>;\n}\n\n/**\n * @experimental\n * Returns the parent `ActionsRegistry`, or `null` when no provider is in scope.\n */\n/**\n * `import.meta.env.DEV` read through a cast — core must not depend on a\n * bundler's ambient augmentation (`vite/client`) to compile. Mirrors the same\n * cast in SceneCanvas.tsx, dispatcher.ts and buildDeps.ts.\n */\n/**\n * A second `<SceneCanvas>` claiming one registry leaves the first unable to\n * dispatch anything, and the symptom — a canvas that stops responding — names\n * neither canvas nor the registry they share.\n */\nfunction warnSharedScope(): void {\n if (!IS_DEV) return;\n console.warn(\n 'weasel: a second dispatcher claimed this <ActionsProvider>, so only the ' +\n 'newest <SceneCanvas> under it will respond to input. Give each canvas its ' +\n 'own scope with <WeaselProvider isolate>.',\n );\n}\n\nconst IS_DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\nexport function useActionsRegistry(): ActionsRegistry | null {\n return useContext(ActionsContext);\n}\n\n/**\n * @experimental\n * Register an `Action` for the lifetime of the calling component. No-op (with\n * a dev-only warning) when no `ActionsProvider` is in scope. Re-registers on\n * `action` reference change (consumers should memoize stable identities to\n * avoid churn).\n */\nexport function useAction(action: Action): void {\n const reg = useActionsRegistry();\n useEffect(() => {\n if (!reg) {\n if (IS_DEV) {\n console.warn(\n `useAction(\"${action.id}\"): no <ActionsProvider> is in scope, so the action was not registered and its bindings will never fire.`,\n );\n }\n return;\n }\n return reg.register(action);\n }, [reg, action]);\n}\n","// src/contributions/useContributions.ts\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { ScopedBinding } from '../interactions/dispatcher/matcher';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useActionsRegistry } from '../interactions/actions/ActionsProvider';\nimport {\n buildToolOffhandBindings,\n makeToolOffhandAction,\n offhandKeyFor,\n type ToolOffhandBindingSpec,\n} from '../interactions/actions/toolOffhand';\nimport { reportRouteConflicts } from '../tools/routing/reflection/conflicts';\nimport type { Tool } from '../tools/types';\nimport type { HotkeyTrigger } from './types';\nimport { scopeBindings } from './assemble';\nimport { liveScope } from './eligibility';\nimport type { Contribution, OverlayPosition } from './types';\nimport { isDev } from '../devFlag';\n\nexport interface UseContributionsOptions<TOverlay = unknown> {\n /** Every registry entry, in declaration order. Order decides which of two\n * same-specificity bindings in one scope tier wins. */\n entries: readonly Contribution<TOverlay>[];\n /** Desired focused entry id. First-mount-wins against the shared\n * `ActiveToolContext` — see `useTools` for the full semantics. */\n focused: string;\n}\n\nexport interface ContributionsApi<TOverlay = unknown> {\n /** Every entry, as passed in. */\n entries: readonly Contribution<TOverlay>[];\n /** Currently focused entry id. */\n focused: string;\n /** Focus an entry. Writes through to the shared `ActiveToolContext`. */\n setFocused: (id: string) => void;\n /** Every live binding, tiered by the declaring entry's eligibility. */\n scopedBindings(): ScopedBinding[];\n /** Overlays of every live entry declaring `position`, ordered active, then\n * hotkey, then ambient. */\n overlays(position?: OverlayPosition): TOverlay[];\n}\n\n/**\n * Assembles one registry: every entry's bindings and overlays, each tiered by\n * what the entry declares about its own eligibility rather than by which\n * argument a consumer passed it in.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally): focus and held-key state live\n * in the context so the gesture dispatcher and every sibling caller read the\n * same source of truth.\n */\nexport function useContributions<TOverlay = unknown>(\n opts: UseContributionsOptions<TOverlay>,\n): ContributionsApi<TOverlay> {\n const ctx = useActiveToolContext();\n const actionsRegistry = useActionsRegistry();\n\n // First-mount sync: if context is at its default ('select') and the caller\n // wants something else, push it. Captured at first render; the setState runs\n // in a post-commit effect so it never updates state during render.\n const hasInitializedRef = useRef(false);\n const isFirstRender = !hasInitializedRef.current;\n const needsFirstMountSyncRef = useRef(false);\n if (isFirstRender) {\n hasInitializedRef.current = true;\n needsFirstMountSyncRef.current = ctx.active === 'select' && opts.focused !== 'select';\n }\n useEffect(() => {\n if (!needsFirstMountSyncRef.current) return;\n needsFirstMountSyncRef.current = false;\n ctx.setActive(opts.focused);\n // First-mount sync only — deliberately runs once after mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const focused = isFirstRender && ctx.active === 'select' && opts.focused !== 'select'\n ? opts.focused\n : ctx.active;\n\n // Refs so the memoized callbacks below see latest values without\n // re-creating themselves.\n const entriesRef = useRef(opts.entries);\n entriesRef.current = opts.entries;\n const focusedRef = useRef(focused);\n focusedRef.current = focused;\n const engagedRef = useRef<readonly string[]>(ctx.hotkeyStack);\n engagedRef.current = ctx.hotkeyStack;\n\n const setFocused = useCallback((id: string) => { ctx.setActive(id); }, [ctx]);\n\n /** Live eligibility state, plus the entries ordered so that hotkey-engaged\n * ones come first — stack order breaks ties within the hotkey tier. */\n const snapshot = useCallback(() => {\n const engaged = engagedRef.current;\n const engagedIds = new Set(engaged);\n const ordered: Contribution<TOverlay>[] = [];\n for (const id of engaged) {\n const entry = entriesRef.current.find((e) => e.id === id);\n if (entry && !ordered.includes(entry)) ordered.push(entry);\n }\n for (const entry of entriesRef.current) {\n if (!ordered.includes(entry)) ordered.push(entry);\n }\n return {\n ordered,\n state: { focusedId: focusedRef.current, engagedIds },\n };\n }, []);\n\n const scopedBindings = useCallback((): ScopedBinding[] => {\n const { ordered, state } = snapshot();\n return scopeBindings(ordered, state);\n }, [snapshot]);\n\n const overlays = useCallback((position: OverlayPosition = 'top'): TOverlay[] => {\n const { ordered, state } = snapshot();\n const active: TOverlay[] = [];\n const hotkey: TOverlay[] = [];\n const ambient: TOverlay[] = [];\n for (const entry of ordered) {\n if (!entry.overlay) continue;\n if ((entry.overlayPosition ?? 'top') !== position) continue;\n const layers = Array.isArray(entry.overlay) ? entry.overlay : [entry.overlay];\n const scope = liveScope(entry.id, entry.eligibility ?? {}, state);\n if (scope === 'active') active.push(...layers);\n else if (scope === 'hotkey') hotkey.push(...layers);\n else if (scope === 'ambient') ambient.push(...layers);\n }\n return [...active, ...hotkey, ...ambient];\n }, [snapshot]);\n\n // A declared `offhand` trigger registers its own engagement. One\n // consolidated `tool.offhand` action serves every entry that declares one;\n // its invoker reads `params.toolId` off the matched binding.\n const offhandSig = opts.entries\n .map((e) => (e.eligibility?.offhand ? `${e.id}:${e.eligibility.offhand}` : ''))\n .filter(Boolean)\n .join(',');\n useEffect(() => {\n if (!actionsRegistry || offhandSig === '') return;\n const specs: ToolOffhandBindingSpec[] = offhandSig.split(',').map((entry) => {\n const [toolId, trigger] = entry.split(':');\n return { toolId, key: offhandKeyFor(trigger as HotkeyTrigger) };\n });\n return actionsRegistry.register(makeToolOffhandAction(buildToolOffhandBindings(specs)));\n }, [actionsRegistry, offhandSig]);\n\n // Route-conflict check. Two entries declaring the same (phase, gesture, arg,\n // target, modifiers) tuple in one scope are resolved by declaration order and\n // almost certainly not as either author intended. This is where the entry set\n // is assembled, so this is where it looks.\n //\n // Dev-only, and deduped on a signature of the entry set: the check walks\n // every binding of every entry, and consumers usually rebuild the entry list\n // each render. Actions are read inside the effect, after the registrations\n // that ran in child effects have landed.\n const lastConflictSigRef = useRef<string | null>(null);\n const entrySig = opts.entries.map((e) => e.id).join(',');\n useEffect(() => {\n if (!isDev()) return;\n if (lastConflictSigRef.current === entrySig) return;\n lastConflictSigRef.current = entrySig;\n // An entry can be in both buckets and usually is: every tool `defineTool`\n // builds declares `focus: true`, and an ambient one carries `always: true`\n // on top of that. Sorting on \"not focus-eligible\" put ambient tools in the\n // registry bucket, which is never compared against itself — registry tools\n // take turns in the active slot — so ambient-vs-ambient went unreported.\n const registry: Tool<unknown, TOverlay>[] = [];\n const ambient: Tool<unknown, TOverlay>[] = [];\n for (const entry of entriesRef.current) {\n if (entry.eligibility?.focus) registry.push(entry);\n if (entry.eligibility?.always || entry.eligibility?.claimed) ambient.push(entry);\n }\n reportRouteConflicts({\n registry,\n ambient,\n actions: actionsRegistry?.list() ?? [],\n });\n }, [entrySig, actionsRegistry]);\n\n // Memoized so consumers using the result as an effect dep don't see identity\n // churn every render — which loops infinitely when the consumer setStates\n // from inside such an effect. `entries` is a getter for that reason: read as\n // a property it would be captured at memo time, and a consumer that adds an\n // entry without switching tools would get a live, hittable binding with no\n // palette entry. The other two members already read the ref, being calls.\n return useMemo(\n () => ({\n get entries() { return entriesRef.current; },\n focused,\n setFocused,\n scopedBindings,\n overlays,\n }),\n [focused, setFocused, scopedBindings, overlays],\n );\n}\n","// src/tools/useTools.ts\nimport { useCallback, useMemo, useRef } from 'react';\nimport { dlog } from '../dlog';\nimport type { AnyTool, AnyToolOf } from './types';\nimport type { HotkeyTrigger } from '../contributions/types';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useContributions } from '../contributions/useContributions';\nimport type { Contribution, Eligibility, OverlayPosition } from '../contributions/types';\n\n/** Options for `useTools`: which tools exist, which one starts active, and\n * which run continuously regardless of the active one. */\nexport interface UseToolsOptions<TOverlay = unknown> {\n /** Initial active-slot tool id. Must exist in `registry`. */\n active: string;\n /** Tools eligible for the active slot or hotkey slot. The keys are the\n * tool ids; the values are the tool records. A tool with `hotkey` set\n * is wired into the hotkey slot whenever the engagement state matches. */\n registry: Record<string, AnyToolOf<TOverlay>>;\n /** Always-on tools — listen continuously regardless of active slot. */\n ambient?: AnyToolOf<TOverlay>[];\n}\n\n/** The tool registry's runtime surface: which tool is active, which is\n * temporarily held by a hotkey, and how to change either. */\nexport interface ToolsApi<TOverlay = unknown> {\n /** Current active-slot tool id. */\n active: string;\n /** Set the active-slot tool. The gesture dispatcher watches the active\n * tool and cancels any in-flight handle itself. */\n setActive: (id: string) => void;\n /** Currently hotkey-engaged tool id (or `null`). Derived as the top of\n * the hotkey stack for backwards compat with the pre-stack API. */\n hotkeyEngaged: string | null;\n /** Engage a hotkey-slot tool by id. */\n engageHotkey: (id: string) => void;\n /** Disengage the hotkey-slot tool, if any. */\n disengageHotkey: () => void;\n /** All always-on tools, in registration order. */\n ambient: readonly AnyToolOf<TOverlay>[];\n /** Full registry — for userland UI (palette buttons, etc.). */\n registry: Readonly<Record<string, AnyToolOf<TOverlay>>>;\n /** Returns true if a tool with the given id is in the registry or ambient list. */\n has(id: string): boolean;\n /** All overlay layers from currently-engaged tools (active slot, hotkey\n * slot if engaged, all ambient slot tools) that declare `position`.\n * Filters out tools with no `overlay` field. Order: active, then hotkey\n * (if engaged), then ambient (registration order). */\n getActiveOverlays(position?: OverlayPosition): TOverlay[];\n}\n\n/** The slot a caller passed a tool in, restated as declared eligibility.\n * `ToolDef.hotkey` becomes `offhand` — it is the same declaration, read off\n * the authored form via the `def` reflection handle. A tool that already\n * declares what its slot implies is returned as-is: `ToolsApi.registry`\n * hands back the objects the caller passed, and consumers compare identity. */\nfunction declareSlot<T extends AnyTool>(tool: T, slot: 'focus' | 'always'): T {\n const hotkey = (tool.def as { hotkey?: HotkeyTrigger } | undefined)?.hotkey;\n const eligibility: Eligibility = {\n ...tool.eligibility,\n [slot]: true,\n ...(hotkey ? { offhand: hotkey } : {}),\n };\n return sameEligibility(tool.eligibility, eligibility) ? tool : { ...tool, eligibility };\n}\n\nfunction sameEligibility(a: Eligibility | undefined, b: Eligibility): boolean {\n if (!a) return false;\n const keys = new Set([...Object.keys(a), ...Object.keys(b)]) as Set<keyof Eligibility>;\n for (const key of keys) if (a[key] !== b[key]) return false;\n return true;\n}\n\n/**\n * Manages the active tool and hotkey slot.\n *\n * A thin shim over {@link useContributions}: the `registry` / `ambient`\n * arguments are restated as declared eligibility (`focus` / `always`), and\n * assembly happens in one place for tools and non-tool contributions alike.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state\n * lives in the context so the gesture dispatcher and any sibling\n * `useTools` calls all read the same source of truth.\n *\n * **First-mount-wins semantics**: if `opts.active` differs from the context\n * default (`'select'`) on first mount, `useTools` pushes `opts.active` to\n * the context. Subsequent mounts respect whatever the context currently\n * holds (the first caller wins).\n */\nexport function useTools<TOverlay = unknown>(\n opts: UseToolsOptions<TOverlay>,\n): ToolsApi<TOverlay> {\n if (!(opts.active in opts.registry)) {\n throw new Error(`useTools: active \"${opts.active}\" not in registry`);\n }\n\n const ctx = useActiveToolContext();\n\n const slotted = useMemo(() => {\n const registry: Record<string, AnyToolOf<TOverlay>> = {};\n for (const [id, tool] of Object.entries(opts.registry)) {\n registry[id] = declareSlot(tool, 'focus');\n }\n const ambient = (opts.ambient ?? []).map((t) => declareSlot(t, 'always'));\n const byId = new Map<string, Contribution<TOverlay>>();\n for (const tool of [...Object.values(registry), ...ambient]) {\n const prior = byId.get(tool.id);\n if (prior) byId.set(tool.id, { ...tool, eligibility: { ...prior.eligibility, ...tool.eligibility } });\n else byId.set(tool.id, tool);\n }\n return { registry, ambient, entries: [...byId.values()] };\n }, [opts.registry, opts.ambient]);\n\n const contributions = useContributions<TOverlay>({ entries: slotted.entries, focused: opts.active });\n\n const hotkeyEngaged = ctx.hotkeyStack.at(-1) ?? null;\n\n // Refs so the memoized callbacks below see latest values without\n // re-creating themselves.\n const slottedRef = useRef(slotted);\n slottedRef.current = slotted;\n const activeRef = useRef(contributions.focused);\n activeRef.current = contributions.focused;\n const hotkeyRef = useRef(hotkeyEngaged);\n hotkeyRef.current = hotkeyEngaged;\n\n const setFocused = contributions.setFocused;\n const setActive = useCallback(\n (id: string) => {\n if (!(id in slottedRef.current.registry)) {\n throw new Error(`setActive: \"${id}\" not in registry`);\n }\n dlog('tools', 'active:', activeRef.current, '→', id);\n setFocused(id);\n },\n [setFocused],\n );\n\n const engageHotkey = useCallback(\n (id: string) => {\n if (!(id in slottedRef.current.registry)) {\n throw new Error(`engageHotkey: \"${id}\" not in registry`);\n }\n dlog('tools', 'hotkey engaged:', id);\n ctx.pushHotkey(id);\n },\n [ctx],\n );\n\n const disengageHotkey = useCallback(() => {\n if (hotkeyRef.current) dlog('tools', 'hotkey disengaged:', hotkeyRef.current);\n ctx.popHotkey();\n }, [ctx]);\n\n const has = useCallback(\n (id: string): boolean =>\n id in slottedRef.current.registry\n || slottedRef.current.ambient.some((t) => t.id === id),\n [],\n );\n\n // Memoize the returned ToolsApi so consumers using `tools` as a dep (e.g.\n // SceneCanvas's `onToolsCreated` useEffect) don't see identity churn on\n // every render — which otherwise loops infinitely when the consumer\n // setStates from inside `onToolsCreated`.\n const active = contributions.focused;\n const getActiveOverlays = contributions.overlays;\n // Which tools exist, not which object holds them: callers commonly rebuild\n // `opts.registry` as a literal every render, and keying the memo on\n // `slotted` itself would hand them a new `ToolsApi` per render.\n const registryKey =\n Object.keys(slotted.registry).sort().join('|')\n + '#' + slotted.ambient.map((t) => t.id).join('|');\n return useMemo(\n () => ({\n active,\n setActive,\n hotkeyEngaged,\n engageHotkey,\n disengageHotkey,\n ambient: slottedRef.current.ambient,\n registry: slottedRef.current.registry,\n has,\n getActiveOverlays,\n }),\n // `registryKey` isn't read in the body on purpose: the body reads\n // `slottedRef.current`, and the key is what tells us that ref's contents moved.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [active, setActive, hotkeyEngaged, engageHotkey, disengageHotkey, has, getActiveOverlays, registryKey],\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/interactions/actions/activeToolContext.tsx","../src/interactions/actions/depRegistry.tsx","../src/interactions/dispatcher/useGestureDispatcher.tsx","../src/interactions/actions/ActionsProvider.tsx","../src/contributions/useContributions.ts","../src/tools/useTools.ts"],"names":["createContext","useMemo","jsx","useContext","useRef","useEffect","Fragment","useCallback"],"mappings":"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","file":"react.js","sourcesContent":["/**\n * ActiveToolContext — runtime selection state for tools.\n *\n * Holds the currently active tool id and a hotkey stack (tools held active\n * temporarily, e.g. space-for-hand). Read by the gesture dispatcher to\n * determine which tool's bindings are in scope; written by tool-switching\n * actions (`tool.activate`) and offhand hotkey actions (`tool.offhand`),\n * both parametric on `params.toolId`.\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md`\n * § \"Types\" and § \"Dispatcher contract\".\n */\n\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n useCallback,\n type ReactNode,\n} from 'react';\n\n/** Which tool is active, plus the stack of tools temporarily held active by a\n * hotkey (space-for-hand and the like). The dispatcher reads this to decide\n * whose bindings are in scope. */\nexport interface ActiveToolContextValue {\n active: string;\n hotkeyStack: string[];\n setActive(id: string): void;\n pushHotkey(id: string): void;\n /**\n * Disengage a hotkey-held tool. With `id`, removes that tool's own entry\n * wherever it now sits — holds do not have to come up in the order they went\n * down, and popping the top would disengage a tool whose key is still held.\n * With no id, pops the top.\n */\n popHotkey(id?: string): void;\n}\n\nconst ActiveToolContext = createContext<ActiveToolContextValue | null>(null);\n\n/** Props for `<ActiveToolContextProvider>`. */\nexport interface ActiveToolContextProviderProps {\n children: ReactNode;\n initialActive?: string;\n}\n\n/** Provides active-tool state for a canvas. `<SceneCanvas>` mounts one. */\nexport function ActiveToolContextProvider({\n children,\n initialActive = 'select',\n}: ActiveToolContextProviderProps) {\n const [active, setActiveState] = useState(initialActive);\n const [hotkeyStack, setHotkeyStack] = useState<string[]>([]);\n\n const setActive = useCallback((id: string) => {\n setActiveState(id);\n }, []);\n const pushHotkey = useCallback((id: string) => {\n setHotkeyStack((s) => [...s, id]);\n }, []);\n const popHotkey = useCallback((id?: string) => {\n setHotkeyStack((s) => {\n if (s.length === 0) return s;\n if (id === undefined) return s.slice(0, -1);\n const i = s.lastIndexOf(id);\n return i === -1 ? s : [...s.slice(0, i), ...s.slice(i + 1)];\n });\n }, []);\n\n const value = useMemo<ActiveToolContextValue>(\n () => ({ active, hotkeyStack, setActive, pushHotkey, popHotkey }),\n [active, hotkeyStack, setActive, pushHotkey, popHotkey],\n );\n\n return (\n <ActiveToolContext.Provider value={value}>{children}</ActiveToolContext.Provider>\n );\n}\n\n/** The active-tool state in scope. Throws outside a provider; use\n * `useActiveToolContextOptional` where one is not guaranteed. */\nexport function useActiveToolContext(): ActiveToolContextValue {\n const value = useContext(ActiveToolContext);\n if (value === null) {\n throw new Error(\n 'useActiveToolContext: no ActiveToolContextProvider in scope. Wrap your tree with <ActiveToolContextProvider> (typically inside <SceneCanvas>).',\n );\n }\n return value;\n}\n\n/**\n * Like `useActiveToolContext`, but returns `null` when no\n * `<ActiveToolContextProvider>` is in scope instead of throwing. Used by\n * `useStandardActions` to preserve its silent-no-op contract when no provider\n * is present.\n */\nexport function useOptionalActiveToolContext(): ActiveToolContextValue | null {\n return useContext(ActiveToolContext);\n}\n\n/**\n * Conditional `<ActiveToolContextProvider>` wrapper. Mounts a provider only\n * when no parent provider is in scope — otherwise renders children unwrapped\n * so callers (e.g. `<WeaselProvider>`, `<SceneCanvas>`) defer to the host's\n * existing scope. Mirrors `ActionsProviderIfRoot` / `DepRegistryProviderIfRoot`.\n */\nexport function ActiveToolContextProviderIfRoot({\n children,\n}: {\n children: ReactNode;\n}) {\n const parent = useContext(ActiveToolContext);\n if (parent !== null) return <>{children}</>;\n return <ActiveToolContextProvider>{children}</ActiveToolContextProvider>;\n}\n","/**\n * Dep registry for registry unification.\n *\n * Holds named \"live source\" thunks. Actions declare `requires: ['selection']`;\n * the dispatcher calls `registry.get('selection')` at invocation time to\n * build a typed Deps bag.\n *\n * `DepSchema` — the map of dep name → value type — is the single source of\n * truth for what `requires`/`register`/`get` accept. Its concrete fields live\n * in `./depSchema` (co-located with the dep value types). It is declared there\n * as a plain `export interface` rather than via a cross-module\n * `declare module './depRegistry'` augmentation: that augmentation does NOT\n * merge once rollup-plugin-dts flattens both files into one `.d.ts` chunk,\n * which silently emptied `DepSchema` for consumers. Consumers still extend it\n * via `declare module '@weasel-js/core'` augmentation.\n */\nimport {\n createContext, useContext, useEffect, useMemo, useRef,\n type ReactNode,\n} from 'react';\nimport type { DepSchema, DepName } from '../../index';\n\nexport type { DepSchema, DepName };\n\n/** Holds the live sources an action's declared dependencies resolve to.\n * Sources are thunks, read at invocation time, so an action never captures\n * stale state. */\nexport interface DepRegistry {\n register<K extends DepName>(name: K, source: () => DepSchema[K]): () => void;\n get<K extends DepName>(name: K): DepSchema[K] | undefined;\n}\n\nconst DepRegistryContext = createContext<DepRegistry | null>(null);\n\n/** Provides the dep registry for a canvas. `<SceneCanvas>` mounts one; a\n * consumer registering its own dep sources must be inside it. */\nexport function DepRegistryProvider({ children }: { children: ReactNode }) {\n // A stack of sources per name, newest live — the same shape as\n // `ActionsProvider`'s registrant stack, one layer down. Two canvases under\n // one provider both register `view` / `scene` / `selection`; with a single\n // slot the second displaced the first and either one's teardown then deleted\n // the name outright, taking the dep away from the canvas still on screen.\n const sourcesRef = useRef(new Map<string, (() => unknown)[]>());\n\n const registry = useMemo<DepRegistry>(() => ({\n register: <K extends DepName>(name: K, source: () => DepSchema[K]) => {\n const key = name as string;\n const entry = source as () => unknown;\n const stack = sourcesRef.current.get(key);\n if (stack) stack.push(entry);\n else sourcesRef.current.set(key, [entry]);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = sourcesRef.current.get(key);\n if (!cur) return;\n // Our own entry, wherever it now sits: a source already displaced must\n // take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(entry);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) sourcesRef.current.delete(key);\n };\n },\n get: <K extends DepName>(name: K) =>\n sourcesRef.current.get(name as string)?.at(-1)?.() as DepSchema[K] | undefined,\n }), []);\n\n return <DepRegistryContext.Provider value={registry}>{children}</DepRegistryContext.Provider>;\n}\n\n/** The dep registry in scope. Throws outside a `<DepRegistryProvider>`. */\nexport function useDepRegistry(): DepRegistry {\n const r = useContext(DepRegistryContext);\n if (r === null) {\n throw new Error('useDepRegistry: no DepRegistryProvider in scope. Wrap your tree with <DepRegistryProvider> (typically inside <SceneCanvas>).');\n }\n return r;\n}\n\n/**\n * Like `useDepRegistry`, but returns `null` when no `<DepRegistryProvider>` is\n * in scope instead of throwing. Used by `useStandardActions` to preserve its\n * silent-no-op contract when neither provider is present.\n */\nexport function useOptionalDepRegistry(): DepRegistry | null {\n return useContext(DepRegistryContext);\n}\n\n/** Register a live source for `name` for the lifetime of the calling\n * component. The `source` thunk is called at dispatch time and should\n * return the latest value. */\nexport function useDepSource<K extends DepName>(name: K, source: () => DepSchema[K]) {\n const registry = useDepRegistry();\n const sourceRef = useRef(source);\n sourceRef.current = source;\n useEffect(() => {\n return registry.register(name, () => sourceRef.current());\n }, [name, registry]);\n}\n","/**\n * useGestureDispatcher — React seam mounting the gesture dispatcher.\n *\n * Composes the four input channels (window keydown/keyup, canvas wheel, canvas\n * pointer events, multi-touch synthesized from PointerEvents) and routes each\n * event to the dispatcher for the view it landed in — one view unless `views`\n * says otherwise. Reads ActiveToolContext + DepRegistry internally; consumer\n * passes the canvas ref, actions registry, and tools map.\n *\n * Side-effect only (returns void).\n *\n * See `docs/superpowers/specs/2026-05-16-registry-unification-design.md` § Q4.\n */\nimport { useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\nimport { isEditableTarget } from '../keyHelpers';\nimport { useActiveToolContext } from '../actions/activeToolContext';\nimport { useDepRegistry, type DepRegistry } from '../actions/depRegistry';\nimport type { DepName, DepSchema } from '../../index';\nimport type { ActionsRegistry } from '../actions/registry';\nimport type { AffordanceHit } from '../actions/invoker';\nimport type { Tool, ToolCtx } from '../../tools/types';\nimport { createDispatcher, pointerGestureId, type Dispatcher, type DispatcherContext } from './dispatcher';\nimport { openPointerSession, type PointerSession } from '../pointerSession';\nimport { clientToCanvasRect } from '../../viewport/clientToCanvas';\nimport { itemsFromDataTransfer, itemsFromClipboardData } from '../../ingestion/ingestItems';\nimport type { InputEvent } from './matcher';\nimport type { BodyTarget, BodyClassification } from '@weasel-js/gestures';\nimport type { CursorSpec } from '@weasel-js/cursor';\nimport type { PaintedCursorState } from '@weasel-js/cursor';\nimport { resolveCursorTier } from '@weasel-js/cursor';\n\n// ---------------------------------------------------------------------------\n// Drop-over styling — class toggled on the canvas while an OS drag hovers it;\n// consumers style it. Not exported: the string is an observable public value\n// but the symbol is internal.\n// ---------------------------------------------------------------------------\n\n/** Class toggled on the canvas while an OS drag hovers it — consumers style it. */\nconst DROPOVER_CLASS = 'weasel-dropover';\n\n/**\n * Lift the stylus fields off a DOM `PointerEvent` onto the normalized\n * `InputEvent`. Kept as a spread-able partial so a synthetic event that\n * carries none of them stays free of `undefined`-valued keys.\n *\n * These ride the drag trail (`InvocationCtx.drag.points`) so pressure- and\n * tilt-aware actions — `insertAction`'s pencil kind today — can reach the\n * per-sample data without their own pointer plumbing.\n */\nfunction stylusOf(e: PointerEvent): {\n pressure?: number; tiltX?: number; tiltY?: number;\n} {\n return {\n ...(typeof e.pressure === 'number' ? { pressure: e.pressure } : {}),\n ...(typeof e.tiltX === 'number' ? { tiltX: e.tiltX } : {}),\n ...(typeof e.tiltY === 'number' ? { tiltY: e.tiltY } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Platform detection — module-level constant so it's stable across renders.\n// ---------------------------------------------------------------------------\n\nconst IS_MAC =\n typeof navigator !== 'undefined' &&\n /mac/i.test(\n // `||`, not `??`: jsdom (and some embedders) report an empty-string\n // platform, which is not nullish and would swallow the UA fallback.\n (navigator as { platform?: string }).platform || navigator.userAgent,\n );\n\n// ---------------------------------------------------------------------------\n// API\n// ---------------------------------------------------------------------------\n\n/**\n * Everything about handling an input event that depends on *which view* it\n * landed in: the dispatcher that runs it, and the three lookups that resolve\n * a client point against that view's camera.\n *\n * @internal One per view. The hook builds the `id: null` one from its flat\n * options; `views` supplies the rest, and the hook chooses between them per\n * event, so that it — and its listener set — still mounts exactly once.\n */\nexport interface DispatcherViewTarget {\n /** `null` is the root view — the whole canvas. Matches `ViewTarget.id`. */\n id: string | null;\n dispatcher: Dispatcher;\n affordanceAt: UseGestureDispatcherOptions['affordanceAt'];\n classifyTarget: UseGestureDispatcherOptions['classifyTarget'];\n clientToWorld: UseGestureDispatcherOptions['clientToWorld'];\n /**\n * The deps this view answers for itself — its camera, its selection, and\n * whatever else is per-view rather than per-canvas. Read per event; every\n * name it does not carry still resolves through the canvas registry.\n *\n * This is why a view does not get a `DepRegistryProvider` of its own. The\n * registry is where a consumer registers *sources*, and one per view would\n * fragment that: a consumer overriding `insert` would have to know how many\n * views exist and override each. An overlay keeps one place to register and\n * one authority per dep, with the view claiming only what is genuinely its.\n *\n * Without this a gesture inside a panel pans the whole canvas and selects\n * into the canvas's selection — correct coordinates alone do not make\n * routing correct.\n */\n deps?: () => Partial<DepSchema>;\n /**\n * This view's chrome-caps rule context, for the eligibility filter. The rule\n * table is the surface's, but a rule keyed on selection or the in-flight\n * action answers per view — so an action hidden in one panel must not\n * decline a gesture in another. `undefined` means \"nothing gates here\", the\n * same answer a surface with no mode registry gives.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n}\n\n/**\n * `base` with the routed view's own deps in front of it. Both sides are read\n * through thunks, so the result is stable for the life of a listener set while\n * still answering for whichever view the current event landed in.\n */\nfunction withViewDeps(\n base: () => DepRegistry,\n overlay: () => Partial<DepSchema> | undefined,\n): DepRegistry {\n return {\n register: (name, source) => base().register(name, source),\n get: <K extends DepName>(name: K): DepSchema[K] | undefined => {\n const own = overlay()?.[name];\n if (own !== undefined) return own as DepSchema[K];\n return base().get(name);\n },\n };\n}\n\n/**\n * The part of `features/viewports`' `ViewResolver` the dispatcher needs: which\n * view a client point belongs to, pinned to the view a gesture began in.\n *\n * @internal Structural on purpose — a `ViewResolver` satisfies it, and the\n * dispatcher stays free of the viewport module.\n */\nexport interface ViewIdResolver {\n begin(pointerId: number, clientX: number, clientY: number): { id: string | null };\n at(pointerId: number | null, clientX: number, clientY: number): { id: string | null };\n end(pointerId: number): void;\n}\n\n/** Per-channel switches for the listeners `useGestureDispatcher` attaches to\n * the canvas element. Omitted or `true` attaches the channel. */\nexport interface DispatcherChannels {\n /** `pointerdown`, hover `pointermove`, `pointerleave` — press, drag, click,\n * long-press, multi-touch and the hover-cursor pump. */\n pointer?: boolean;\n /** `wheel`. */\n wheel?: boolean;\n /** `contextmenu`. Off leaves the browser's native menu in place. */\n contextMenu?: boolean;\n /** OS drop on the element plus `paste` on the window. Off leaves the\n * element a non-drop-target and stops `weasel-dropover` being applied. */\n ingest?: boolean;\n}\n\n/** Options for `useGestureDispatcher`: the element to listen on, the actions\n * and tools in play, and the hooks that turn raw DOM events into the world\n * coordinates and hit targets bindings match against. */\nexport interface UseGestureDispatcherOptions {\n /** Ref to the canvas element. Pointer/wheel/multitouch listeners attach here. */\n canvasRef: RefObject<HTMLElement | null>;\n /** Action registry (ActionsRegistry from registry.tsx). */\n actions: ActionsRegistry;\n /** Tool definitions keyed by id. Typically passes an empty Map. */\n toolsById: ReadonlyMap<string, Tool>;\n /** Default true. Set false to opt out of dispatcher wiring (e.g. demos that disable it). */\n enabled?: boolean;\n /**\n * Observer fired whenever the dispatcher synthesizes a double click, in\n * world coordinates. Runs BEFORE the event is dispatched and independently\n * of which binding (if any) handles it.\n *\n * This is deliberately not an Action. `<SceneCanvas onDoubleClick>` is a\n * notification — \"the user double-clicked, here's what they hit\" — and a\n * notification must not compete with behavior for the gesture. As a binding\n * it would lose to `enterPathEdit` on any body hit and silently never fire.\n * Routing it here keeps a single definition of \"double click\" (the point of\n * consolidating the kit's three detectors) without giving it\n * first-match-wins semantics it shouldn't have.\n */\n onDoubleClick?: (world: { x: number; y: number }) => void;\n /**\n * Default true. Set false to leave the window `keydown`/`keyup` listeners\n * unattached so keyboard-bound actions never dispatch — pointer, wheel, and\n * contextmenu channels stay live. `<SceneCanvas>` wires this to\n * `enableKeybindings`, so opting out of keybindings disables the modern\n * dispatcher key path as well as the legacy `useKeybindings` hook.\n */\n keyboard?: boolean;\n /**\n * Optional affordance classifier. Called with the **world** coordinates of\n * the pointer — this hook applies the routed view's `clientToWorld` before\n * calling it, the same conversion that produces `InputEvent.x`/`y`, so a\n * consumer hit-tests in one space. Returns an `AffordanceHit` when the\n * pointer lands on a known affordance (resize handle, rotate handle, etc.)\n * or `null` when the pointer hit open canvas.\n *\n * The hit is packed into `InputEvent.pointerdown.affordance` and flows\n * through into `InvocationCtx.drag.affordance`. Action invokers that require\n * a specific affordance (e.g. `resizeAction` requires `handle:*`) use this\n * field as a guard in their `start` body.\n *\n * When omitted, `affordance` is always `undefined` — meaning only consumers\n * that explicitly wire a classifier get affordance-gated behavior.\n * `<SceneCanvas>` wires the full chrome→dispatcher bridge.\n */\n affordanceAt?: (worldPoint: { x: number; y: number }) => AffordanceHit | null;\n\n /**\n * Optional body classifier. Called on every pointerdown with the world-space\n * coordinates of the pointer. Its result is packed onto the event as\n * `bodyTarget` + `bodyKind`, which `matchTarget` reads to resolve the\n * string-form `TargetSpec` values in `Tool.bindings`.\n *\n * `body` is `'empty'` when nothing is under the pointer, `'selected-body'`\n * when the topmost hit belongs to the current selection, or\n * `'unselected-body'` when it belongs to a node that isn't selected. `kind`\n * is the hit node's semantic kind, when the scene can name it.\n *\n * When omitted, every body-derived target form (`'empty'`,\n * `'selected-body'`, `'unselected-body'`, `kind:<k>`, `kind:<k>:selected`)\n * never matches — bindings using those specs are silently skipped.\n * `<SceneCanvas>` wires this.\n *\n * World coordinates, on every path, for the same reason as `affordanceAt`.\n */\n classifyTarget?: (worldPoint: { x: number; y: number }) => BodyClassification;\n\n /**\n * Optional pre-created `Dispatcher`. When provided, this hook pumps events\n * into the supplied instance instead of creating its own. Lets a parent\n * scope (e.g. `<SceneCanvas>`) share one dispatcher between the gesture\n * mounter and other consumers (the preview-ghost layer).\n */\n dispatcher?: Dispatcher;\n\n /**\n * Converts a client-space pointer position (e.g. `e.clientX`, `e.clientY`)\n * to world-space coordinates. When supplied, every pointer/wheel event's\n * `x`/`y` is converted before the dispatcher builds `InvocationCtx.world`.\n *\n * Without this, `ctx.world` is populated with the raw client coords, which\n * silently breaks any action whose overlay/output uses absolute world\n * positions (marquee, lasso polyline, world-space affordances). Actions\n * that only read `drag.delta` are unaffected because client→world deltas\n * are equal at scale 1, but as soon as a consumer pans/zooms the view the\n * deltas diverge too.\n *\n * `<SceneCanvas>` always wires this via its canvas rect + current view.\n * Tests / harnesses without a view can omit it and continue passing raw\n * coordinates as before.\n */\n clientToWorld?: (clientX: number, clientY: number) => { x: number; y: number };\n\n /**\n * Invoked once per pump event (`pointermove`, `pointerup`, `pointercancel`,\n * `key-held` up-phase, `multitouch` move) when a dispatcher-side handle is\n * in flight. Lets the host canvas schedule a redraw so dispatcher-only\n * overlays (marquee, lasso, preview-ghost) repaint on each frame.\n *\n * Required because dispatcher actions don't go through the legacy\n * `tools.dispatcher.onGestureChange` redraw bump that ambient tool drags\n * relied on. Without it, the overlay layer's `draw` never runs between\n * pointerdown and pointerup, and the chrome flashes once at gesture start\n * and then sits frozen until the gesture ends.\n *\n * `<SceneCanvas>` wires this to the canvas's `requestRedraw`. Test\n * harnesses can omit it; their dispatchers won't paint between events but\n * that's already the test contract.\n */\n requestRedraw?: () => void;\n /**\n * The surface's painted-cursor channel, read live because the canvas handle\n * it lives on arrives a render after this hook runs.\n *\n * Given one, a cursor the CSS tier cannot express — sized in world units, or\n * past the size the browser drops the image at — is published here and drawn\n * by the painted-cursor layer instead. Without one, such a cursor resolves to\n * `none` and the pointer shows nothing.\n */\n paintedCursor?: () => PaintedCursorState | undefined;\n\n /**\n * Thunk returning the live `RuleCtx` for the current frame. When supplied,\n * the dispatcher filters matched candidates by their declared\n * `Action.eligible` rule (omitted => always eligible). `<SceneCanvas>`\n * wires this; tests / harnesses without chrome-caps state can omit it.\n */\n getRuleCtx?: () => import('../../eligibility').RuleCtx | undefined;\n\n /**\n * Which of the canvas element's input channels to attach. Every one\n * defaults to `true`; naming a channel `false` leaves its listeners\n * unattached, so the element behaves as if the dispatcher were not there.\n *\n * A mount that binds two gestures should not also have to take the rest of\n * the pipeline's side effects: `contextMenu` suppresses the native menu\n * unconditionally, and `ingest` makes the element a valid drop target and\n * styles it while an OS drag hovers. `@weasel-js/labkit`'s loupe mounts on\n * a lab's own canvas host for a wheel and a held key, and turning the other\n * three off is what keeps right-click and file drops working there.\n *\n * The window keyboard channel is `keyboard` instead of an entry here,\n * because `<SceneCanvas enableKeybindings>` drives it.\n */\n channels?: DispatcherChannels;\n\n /**\n * Routing for a canvas hosting more than one view: the non-root dispatch\n * records to choose between, read fresh per event, and the resolver that\n * chooses. Omit for a single view — then every event runs on the record the\n * flat options above describe, which is what they are: view zero.\n *\n * A resolved id with no live record falls back to the root, so a view that\n * unmounts mid-gesture degrades instead of dropping the event.\n *\n * Keyboard and paste have no coordinates to resolve; they run on the view\n * the last coordinate-bearing event resolved to.\n *\n * @internal\n */\n views?: {\n targets: () => readonly DispatcherViewTarget[];\n resolver: ViewIdResolver;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** A pointer held on the canvas, and everything a press is synthesized from. */\ninterface HeldPointer {\n session: PointerSession;\n /** Latest screen position, for the multitouch centroid and spread. */\n pos: { x: number; y: number };\n /** The press, withheld from the dispatcher until movement crosses\n * `DRAG_THRESHOLD_PX`. Null once forwarded, or once multitouch claimed\n * the pointer — see the multi-pointer policy in `onPointerDown`. */\n buffered: { ev: InputEvent; clientX: number; clientY: number } | null;\n /** Press-time state replayed onto a synthesized click, long-press or\n * contextmenu, whose matchers resolve targets against it. */\n down: {\n target: unknown;\n clientX: number;\n clientY: number;\n /** World-space press point, forwarded onto the synthesized click as\n * `pressX`/`pressY` — see `ClickEvent`. */\n worldX: number;\n worldY: number;\n affordance?: unknown;\n bodyTarget?: BodyTarget;\n bodyKind?: string;\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n };\n}\n\n/**\n * Compute centroid and spread (distance between first two pointers) from\n * the active pointer positions. Returns a centroid of (0, 0) and spread\n * of 0 when fewer than 2 pointers are present.\n */\nfunction computeMultiTouchGeometry(\n positions: Iterable<{ x: number; y: number }>,\n): { centroid: { x: number; y: number }; spread: number } {\n const pts = [...positions];\n if (pts.length < 2) {\n return { centroid: { x: 0, y: 0 }, spread: 0 };\n }\n // Centroid across all active pointers.\n let sumX = 0;\n let sumY = 0;\n for (const p of pts) {\n sumX += p.x;\n sumY += p.y;\n }\n const centroid = { x: sumX / pts.length, y: sumY / pts.length };\n // Spread = distance between the first two pointers (primary pair).\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const spread = Math.sqrt(dx * dx + dy * dy);\n return { centroid, spread };\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\n/**\n * Attach the input pipeline to a canvas: DOM pointer, wheel, keyboard and\n * multitouch listeners in, normalized input events out, routed through the\n * dispatcher to whichever action a binding names.\n *\n * Everything it needs beyond its options — the active tool, the dep registry —\n * comes from context, so it must be mounted inside `<SceneCanvas>`'s\n * providers.\n */\nexport function useGestureDispatcher(opts: UseGestureDispatcherOptions): void {\n const { canvasRef, actions, toolsById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld, requestRedraw, paintedCursor, getRuleCtx, onDoubleClick, views, channels } = opts;\n // Read out as four booleans, not the object: the attach effect depends on\n // them, and an inline `channels={{...}}` would re-bind every listener on\n // every render.\n const pointerChannel = channels?.pointer !== false;\n const wheelChannel = channels?.wheel !== false;\n const contextMenuChannel = channels?.contextMenu !== false;\n const ingestChannel = channels?.ingest !== false;\n const onDoubleClickRef = useRef(onDoubleClick);\n onDoubleClickRef.current = onDoubleClick;\n const activeTool = useActiveToolContext();\n const depRegistry = useDepRegistry();\n\n // Single dispatcher instance, stable across renders. When a `dispatcher`\n // is supplied via options, adopt it; otherwise create one lazily.\n const dispatcherRef = useRef<Dispatcher | null>(null);\n if (!dispatcherRef.current) {\n dispatcherRef.current = dispatcherOpt ?? createDispatcher();\n }\n\n // Stable ref to the latest context values so event listeners always see\n // current state without needing to re-register on every render.\n // No `getRuleCtx` here: eligibility is a per-view answer, so it rides on the\n // dispatch record and `ctxNow` installs the routed view's.\n const ctxRef = useRef<DispatcherContext>({\n actions,\n depRegistry,\n activeToolId: activeTool.active,\n hotkeyStack: activeTool.hotkeyStack,\n toolsById,\n isMac: IS_MAC,\n });\n ctxRef.current = {\n actions,\n depRegistry,\n activeToolId: activeTool.active,\n hotkeyStack: activeTool.hotkeyStack,\n toolsById,\n isMac: IS_MAC,\n };\n\n // The flat options are view zero.\n const rootTargetRef = useRef<DispatcherViewTarget>({\n id: null, dispatcher: dispatcherRef.current, affordanceAt, classifyTarget, clientToWorld,\n getRuleCtx,\n });\n rootTargetRef.current = {\n id: null, dispatcher: dispatcherRef.current, affordanceAt, classifyTarget, clientToWorld,\n getRuleCtx,\n };\n const viewsRef = useRef(views);\n viewsRef.current = views;\n\n /** Every live dispatcher — what a cancel-everything has to reach. */\n const allDispatchers = (): Dispatcher[] => [\n rootTargetRef.current.dispatcher,\n ...(viewsRef.current?.targets() ?? []).map((t) => t.dispatcher),\n ];\n const requestRedrawRef = useRef(requestRedraw);\n requestRedrawRef.current = requestRedraw;\n const paintedCursorRef = useRef(paintedCursor);\n paintedCursorRef.current = paintedCursor;\n\n // Double-click synthesis state. Lives at hook level (not inside the effect)\n // so it survives effect re-runs — otherwise HMR / StrictMode / a transient\n // deps change resets it between the two clicks and the doubleclick never\n // fires.\n const lastClickRef = useRef<{ t: number; clientX: number; clientY: number } | null>(null);\n\n // Tool-switch lifecycle. Two things have to happen when the active tool\n // changes (and only then — not on initial mount):\n // 1. Fire the outgoing tool's `onDeactivate(ctx)` so it can clean up\n // tool-owned scratch state. Pen relies on this to discard a\n // half-built path the user hasn't committed.\n // 2. Cancel any in-flight ongoing dispatcher handles so the new tool\n // doesn't inherit a live gesture.\n //\n // The `ToolCtx` passed to `onDeactivate` is intentionally minimal — at\n // this lifecycle moment there's no event-driven cursor position, hit\n // result, or modifier state to populate. We pass the tool's own scratch\n // (via `initScratch()`, which tools that hold persistent state implement\n // as a singleton ref-return) so cleanup hooks can read/mutate the only\n // state they actually care about. Fields the implementation reads beyond\n // `scratch` will read undefined; tools whose cleanup needs more should\n // either rely on closure-captured refs (the pen-tool pattern) or wait\n // until we have a real cause to broaden the contract.\n const prevActiveRef = useRef(activeTool.active);\n useEffect(() => {\n if (prevActiveRef.current !== activeTool.active) {\n const prevTool = toolsById.get(prevActiveRef.current) as Tool<unknown> | undefined;\n if (prevTool?.onDeactivate) {\n const scratch = prevTool.initScratch?.();\n try {\n prevTool.onDeactivate({ scratch } as unknown as ToolCtx<unknown>);\n } catch (err) {\n console.error(\n `weasel: tool \"${prevActiveRef.current}\".onDeactivate threw`,\n err,\n );\n }\n }\n for (const d of allDispatchers()) d.cancelAll('cancel');\n }\n prevActiveRef.current = activeTool.active;\n });\n\n useEffect(() => {\n if (!enabled) return;\n\n let disposed = false;\n\n // The view the current event belongs to, as an id rather than a record:\n // the record is rebuilt every render, so holding one across events would\n // dispatch through last render's lookups.\n let routedId: string | null = null;\n\n /** The dispatch record for the routed view. */\n const target = (): DispatcherViewTarget => {\n if (routedId === null) return rootTargetRef.current;\n return viewsRef.current?.targets().find((t) => t.id === routedId)\n ?? rootTargetRef.current;\n };\n\n /** Route an event with coordinates. `pointerId` is `null` for input with\n * nothing to capture — wheel, hover, contextmenu, drop. */\n const routeAt = (pointerId: number | null, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.at(pointerId, clientX, clientY).id ?? null;\n };\n /** Route a pointerdown, pinning the pointer to the view it landed in. */\n const routeDown = (pointerId: number, clientX: number, clientY: number): void => {\n routedId = viewsRef.current?.resolver.begin(pointerId, clientX, clientY).id ?? null;\n };\n const routeRelease = (pointerId: number): void => {\n viewsRef.current?.resolver.end(pointerId);\n };\n\n // Resolved per event, not bound once: the dispatcher an event runs on is\n // a property of the view it landed in.\n const dispatcherNow = (): Dispatcher => target().dispatcher;\n\n const routedDeps = withViewDeps(() => ctxRef.current.depRegistry, () => target().deps?.());\n // Eligibility is evaluated against the routed view's rule context, not the\n // surface's — same reason its deps are.\n const routedRuleCtx = (): ReturnType<NonNullable<DispatcherViewTarget['getRuleCtx']>> =>\n target().getRuleCtx?.();\n const ctxNow = (): DispatcherContext => ({\n ...ctxRef.current, depRegistry: routedDeps, getRuleCtx: routedRuleCtx,\n });\n const canvas = canvasRef.current;\n\n // Convert a client-space pointer position to world-space. When no\n // `clientToWorld` thunk is wired (legacy harnesses / tests), this is the\n // identity — preserves pre-fix behavior for callers that pass raw event\n // coords as if they were world. SceneCanvas always wires the thunk via\n // its canvas rect + current view, so `ctx.world` becomes real world coords\n // for areaSelect / lassoSelect / world-space affordance consumers.\n const toWorld = (cx: number, cy: number): { x: number; y: number } => {\n const fn = target().clientToWorld;\n return fn ? fn(cx, cy) : { x: cx, y: cy };\n };\n\n // Dispatch + bump the host canvas's redraw when any handle was in flight\n // before, during, or after the event. Without this, dispatcher-only\n // overlays (marquee, lasso) never repaint after their initial frame.\n // `before` captures the pre-event state so we redraw on the pump that\n // CLOSES a gesture (e.g. pointerup-with-no-remaining-handles still needs\n // to clear the overlay).\n //\n // `on` is for the one path that dispatches after its event has left the\n // stack (drop, whose items materialize async) — by then the routed view\n // is whatever moved under the cursor since.\n const dispatch = (ev: InputEvent, on?: Dispatcher): 'handled' | 'unhandled' => {\n const d = on ?? dispatcherNow();\n const before = d.inFlight().size;\n const result = d.handleInput(ev, ctxNow());\n const after = d.inFlight().size;\n if (before > 0 || after > 0) requestRedrawRef.current?.();\n return result;\n };\n\n // Tracks keys that have an in-flight key-held handle so we fire the up\n // phase only when warranted.\n const heldKeys = new Set<string>();\n\n // Every pointer currently held on the canvas, one `openPointerSession`\n // each. The session owns capture, pointer identity, teardown and the\n // three recovery rules; the record owns what the dispatcher synthesizes.\n const held = new Map<number, HeldPointer>();\n // Pinch anchors land in `zoomAt`, which measures from the canvas top-left,\n // so the centroid is converted here — the same step the wheel listener\n // takes for its own anchor. Client coords would drift the zoom by the\n // canvas's offset from the viewport.\n const toCanvasLocal = (p: { x: number; y: number }): { x: number; y: number } => {\n const rect = canvas?.getBoundingClientRect();\n if (!rect) return p;\n const [x, y] = clientToCanvasRect(rect, p.x, p.y);\n return { x, y };\n };\n const heldGeometry = () => {\n const { centroid, spread } = computeMultiTouchGeometry(\n [...held.values()].map((p) => p.pos),\n );\n return { centroid: toCanvasLocal(centroid), spread };\n };\n\n // Tracks the start state of an active multitouch episode so we can\n // synthesize a `multitouchtap` event on release when the centroid hasn't\n // moved past the tap threshold. `fingers` records the peak count.\n let multiTouchStart: { fingers: number; centroid: { x: number; y: number } } | null = null;\n const TAP_THRESHOLD_PX = 8;\n\n // Pixel distance the pointer must travel between pointerdown and the first\n // pointermove before we treat the gesture as a drag and forward the\n // pointerdown to the dispatcher. Below this, pointerup is treated as a\n // click — no drag handle is ever opened, so `moveAction` (and other\n // ongoing drag actions) don't fire on a stationary press-and-release.\n const DRAG_THRESHOLD_PX = 4;\n\n // Long-press synthesis. Armed on pointerdown for touch/pen, cancelled by\n // movement past DRAG_THRESHOLD_PX, by release, by cancel, or by a second\n // pointer landing (so it can never fire mid-pinch).\n const LONG_PRESS_MS = 500;\n const longPressTimers = new Map<number, ReturnType<typeof setTimeout>>();\n\n const cancelLongPress = (pointerId: number): void => {\n const t = longPressTimers.get(pointerId);\n if (t !== undefined) {\n clearTimeout(t);\n longPressTimers.delete(pointerId);\n }\n };\n\n const cancelAllLongPress = (): void => {\n for (const t of longPressTimers.values()) clearTimeout(t);\n longPressTimers.clear();\n };\n\n /** Fire a synthesized long-press, falling back to contextmenu when the\n * long-press matched nothing. The fallback is what makes existing\n * `contextMenu` bindings reachable by touch with no consumer change. */\n const fireLongPress = (pointerId: number): void => {\n const down = held.get(pointerId)?.down;\n if (!down) return;\n\n const shared = {\n target: down.target,\n altKey: down.altKey,\n ctrlKey: down.ctrlKey,\n metaKey: down.metaKey,\n shiftKey: down.shiftKey,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n\n const result = dispatch({\n kind: 'longpress',\n x: down.worldX,\n y: down.worldY,\n clientX: down.clientX,\n clientY: down.clientY,\n ...shared,\n } as InputEvent);\n\n if (result === 'unhandled') {\n dispatch({\n kind: 'contextmenu',\n x: down.worldX,\n y: down.worldY,\n clientX: down.clientX,\n clientY: down.clientY,\n ...shared,\n } as InputEvent);\n }\n };\n\n // Double-click synthesis thresholds. 600ms matches the upper end of OS\n // double-click settings; 8px tolerates the natural drift of a real\n // mouse / trackpad between the two clicks. State (`lastClickRef`)\n // lives at hook level so it survives effect re-runs.\n const DOUBLE_CLICK_MAX_MS = 600;\n const DOUBLE_CLICK_MAX_PX = 8;\n\n // -----------------------------------------------------------------------\n // Window key listeners\n // -----------------------------------------------------------------------\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (isEditableTarget(e.target)) return;\n\n // Autorepeat for a key that's already engaged a key-held binding is\n // suppressed entirely — no dispatch (no trace flood) and the\n // browser default is blocked. Holding Space-for-hand otherwise\n // streamed an 'unhandled' immediate-`key` trace entry per repeat.\n // Autorepeat for a key that ISN'T held still dispatches normally,\n // so things like Cmd+= step-zoom keep auto-repeating.\n if (e.repeat && heldKeys.has(e.key)) {\n e.preventDefault();\n return;\n }\n\n // Dispatch both key and key-held forms unconditionally. The dispatcher\n // de-dupes naturally because each form uses a different gestureId and\n // different GestureSpec kind. `matchBest` returns 'unhandled' when no\n // binding matches the alternate form, so there's no double-fire risk.\n\n const keyEv: InputEvent = {\n kind: 'key',\n key: e.key,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n repeat: e.repeat,\n };\n const keyResult = dispatch(keyEv);\n\n // Always dispatch key-held DOWN, even on autorepeat. The dispatcher's\n // own defense returns 'handled' (no-op) when a handle is already in\n // flight for this gestureId, which both prevents start() re-invocation\n // and lets us preventDefault the repeat so the page doesn't react.\n const heldEv: InputEvent = {\n kind: 'key-held',\n key: e.key,\n phase: 'down',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n const heldResult = dispatch(heldEv);\n\n if (heldResult === 'handled') {\n heldKeys.add(e.key);\n }\n\n if (keyResult === 'handled' || heldResult === 'handled') {\n e.preventDefault();\n }\n };\n\n const onKeyUp = (e: KeyboardEvent) => {\n if (!heldKeys.has(e.key)) return;\n const ev: InputEvent = {\n kind: 'key-held',\n key: e.key,\n phase: 'up',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n heldKeys.delete(e.key);\n };\n\n // A window that loses focus never delivers the keyup, so without this every\n // in-flight key-held handle stays engaged until that key is pressed again.\n // Nor can a drag trust the release it may or may not see later, so every\n // held pointer is canceled — through its session, which reports once.\n const onWindowBlur = () => {\n for (const p of [...held.values()]) p.session.cancel();\n for (const key of heldKeys) {\n const ev: InputEvent = {\n kind: 'key-held',\n key,\n phase: 'up',\n altKey: false,\n ctrlKey: false,\n metaKey: false,\n shiftKey: false,\n };\n dispatch(ev);\n }\n heldKeys.clear();\n };\n\n // -----------------------------------------------------------------------\n // Canvas wheel listener\n // -----------------------------------------------------------------------\n\n const onWheel = (e: WheelEvent) => {\n routeAt(null, e.clientX, e.clientY);\n // Convert client-space cursor to canvas-local: zoomAt() (and any other\n // wheel consumer of clientX/Y) anchors in canvas-top-left coords, not\n // viewport coords. Without this, anchored-wheel zoom drifts by the\n // canvas's offset from the viewport top-left.\n const rect = canvas?.getBoundingClientRect();\n const [localX, localY] = rect\n ? clientToCanvasRect(rect, e.clientX, e.clientY)\n : [e.clientX, e.clientY];\n const hitPoint = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(hitPoint) ?? undefined;\n const body = target().classifyTarget?.(hitPoint);\n const ev: InputEvent = {\n kind: 'wheel',\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n deltaX: e.deltaX,\n deltaY: e.deltaY,\n clientX: localX,\n clientY: localY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(body?.body !== undefined ? { bodyTarget: body.body } : {}),\n ...(body?.kind !== undefined ? { bodyKind: body.kind } : {}),\n };\n const result = dispatch(ev);\n // When a binding claims the wheel (viewport.zoom on Cmd+wheel, viewport.pan\n // on plain wheel, etc.), the page must not also scroll. Suppress the\n // default + bubble so a parent scroll container doesn't move while the\n // canvas is zooming or panning.\n if (result === 'handled') {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n // -----------------------------------------------------------------------\n // Canvas pointer listeners + multi-touch synthesis\n // -----------------------------------------------------------------------\n\n const onPointerDown = (e: PointerEvent) => {\n // Only the primary button drives gesture dispatch. `pointerdown` reports\n // `button === 0` for the left mouse button and for touch / pen contact;\n // secondary (right, `2`) and middle (`1`) mouse buttons are left for the\n // consumer's own tools (e.g. right-drag viewport pan) and the browser\n // context menu. Without this guard a right-drag is classified and routed\n // exactly like a left-drag — selecting + transforming under the cursor\n // instead of letting an ambient pan tool claim it. An absent `button`\n // (synthetic / programmatic events) counts as primary.\n if ((e.button ?? 0) !== 0) return;\n if (!canvas) return;\n routeDown(e.pointerId, e.clientX, e.clientY);\n\n const w = toWorld(e.clientX, e.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const body = target().classifyTarget?.(w);\n const bodyTarget = body?.body;\n const bodyKind = body?.kind;\n const ev: InputEvent = {\n kind: 'pointerdown',\n target: e.target,\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n // The session owns the rest of this pointer: capture, the moves and the\n // release, and the three recovery rules for a release that never\n // arrives. A press on a pointer one is already open for cancels that\n // stale gesture before this handler runs — its `pointerdown` listener is\n // on the document, in the capture phase, ahead of this one on the canvas.\n held.set(e.pointerId, {\n session: openPointerSession(canvas, e, {\n onMove: onPointerMove,\n onEnd: onPointerUp,\n onCancel: () => { onPointerCancel(e.pointerId); },\n }),\n pos: { x: e.clientX, y: e.clientY },\n // Deferred until the first past-threshold pointermove: a bare\n // press-and-release should fire `click`, not start a drag action.\n buffered: { ev, clientX: e.clientX, clientY: e.clientY },\n down: {\n target: e.target,\n clientX: e.clientX,\n clientY: e.clientY,\n worldX: w.x,\n worldY: w.y,\n affordance,\n bodyTarget,\n bodyKind,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n },\n });\n\n // The press itself dispatches now, for bindings that must act while the\n // button is still down and before the gesture is classified (select\n // highlights the pressed node here). `matchSpec` routes the two copies\n // to disjoint spec kinds — `pointerDown` matches only this one, `drag`\n // only the buffered one — so a single press never fires both.\n //\n // Withheld once a second pointer is down: this press belongs to the\n // multitouch channel under the MULTI-POINTER POLICY below, which clears\n // the buffered copy for the same reason. Without this a pinch's second\n // finger ran `select.pick` and moved the selection under the gesture.\n if (held.size < 2) dispatch({ ...ev, stage: 'press' });\n\n // Arm long-press for touch / pen only, and only for a lone pointer —\n // a second finger means a multi-touch gesture, not a long-press.\n if ((e.pointerType === 'touch' || e.pointerType === 'pen')\n && held.size === 1) {\n cancelLongPress(e.pointerId);\n longPressTimers.set(\n e.pointerId,\n setTimeout(() => {\n longPressTimers.delete(e.pointerId);\n if (disposed) return;\n fireLongPress(e.pointerId);\n }, LONG_PRESS_MS),\n );\n }\n\n // Synthesize a multi-touch event when >= 2 pointers are active.\n if (held.size >= 2) {\n cancelAllLongPress();\n // MULTI-POINTER POLICY: the multitouch channel takes ownership of\n // every pointer that hasn't already committed to a gesture. Clearing\n // the buffered press is what enforces it — a claimed pointer opens no\n // drag handle on the next move, and synthesizes no click on release\n // (both of those read the buffer). The `multitouch-<fingers>` handle\n // and the `multitouchtap` synthesis below are the whole gesture.\n //\n // This used to hold by accident: `gestureIdFor` returned one key for\n // every pointer, so a second finger's press found the first's handle\n // in flight and no-oped. Per-pointer keying removes the accident, so\n // the policy has to be stated. Stating it is the improvement — a\n // pointer that is part of a pinch is not also dragging something.\n //\n // Note the asymmetry: a pointer that already opened a drag has no\n // buffer left to claim, so its gesture survives the second finger\n // landing. Yanking a drag out from under someone who rested a palm is\n // worse than letting it finish.\n for (const p of held.values()) p.buffered = null;\n\n const { centroid, spread } = heldGeometry();\n // Capture start state for tap synthesis. On the first 1→2 transition\n // we record the centroid; subsequent pointerdowns at higher finger\n // counts only bump the recorded peak fingers count.\n if (!multiTouchStart) {\n multiTouchStart = { fingers: held.size, centroid: { ...centroid } };\n } else {\n multiTouchStart.fingers = held.size;\n }\n const mt: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mt);\n }\n };\n\n const onPointerMove = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n const rec = held.get(e.pointerId);\n if (rec) rec.pos = { x: e.clientX, y: e.clientY };\n\n // Threshold gate: if a pointerdown is buffered for this pointer and\n // the movement crossed the drag threshold, forward the buffered\n // pointerdown to the dispatcher BEFORE the pointermove. This is what\n // opens the ongoing drag handle (matching `kind: 'drag'` bindings);\n // subsequent pointermoves pump it via `onMove`. Sub-threshold\n // pointermoves are still forwarded so existing pump paths (e.g. other\n // in-flight handles) keep working, but they're no-ops when no handle\n // exists.\n const buffered = rec?.buffered;\n if (rec && buffered) {\n const dx = e.clientX - buffered.clientX;\n const dy = e.clientY - buffered.clientY;\n if (Math.hypot(dx, dy) >= DRAG_THRESHOLD_PX) {\n rec.buffered = null;\n cancelLongPress(e.pointerId);\n dispatch(buffered.ev);\n }\n }\n\n // If a multitouch handle is in flight, synthesize a multitouch pump event\n // with the updated centroid + spread. The dispatcher routes this to the\n // handle's onMove (because the event carries centroid data).\n const mtGestureId = `multitouch-${held.size}`;\n if (held.size >= 2 && dispatcherNow().inFlight().has(mtGestureId)) {\n const { centroid, spread } = heldGeometry();\n const mtEv: InputEvent = {\n kind: 'multitouch',\n fingers: held.size,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n centroid,\n spread,\n };\n dispatch(mtEv);\n // Also dispatch the raw pointermove so single-pointer handles can coexist.\n }\n\n const w = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointermove',\n pointerId: e.pointerId,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n ...stylusOf(e),\n };\n dispatch(ev);\n\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n refreshHoverCursor();\n };\n\n // -----------------------------------------------------------------------\n // Hover-cursor pump\n // -----------------------------------------------------------------------\n //\n // On every idle pointermove (no pressed pointer, no in-flight handle),\n // resolve what sits under the pointer and write a cursor override\n // directly to `canvas.style.cursor`. Precedence:\n //\n // 1. Affordance hit declaring `AffordanceHit.cursor` (resize corners,\n // rotate ring) — the same `affordanceAt` hit-test pointerdown uses.\n // 2. The action a drag from here would route to (`resolveOnly`, the\n // same match walk pointerdown takes), when it declares\n // `Action.cursor` — e.g. `viewport.dragPan` → 'grab' over empty\n // canvas when pan would win the drag.\n // 3. Otherwise the action a click here would route to, when it\n // declares one — e.g. Alt over a path segment in path-edit mode.\n // 4. No override — clear the inline style so the active tool's\n // React-managed `Tool.cursor` (the implicit base) shows through.\n //\n // Mid-gesture the pump stands down; the tool-cursor pipeline\n // (function-form `Tool.cursor` re-resolving on `gestureTick`) owns the\n // cursor there. The override is an inline style on purpose: clearing it\n // restores the React-managed base without effect churn.\n //\n // `lastHover` lets modifier keydown/keyup refresh the prediction without\n // pointer movement (a held Space re-routes the drag to the hand tool).\n // That refresh is deferred a tick so React can commit the hotkey-stack /\n // active-tool state the key event just changed — `ctxRef` is only\n // rewritten on render.\n let lastHover: {\n clientX: number; clientY: number;\n altKey: boolean; ctrlKey: boolean; metaKey: boolean; shiftKey: boolean;\n } | null = null;\n let cursorOverridden = false;\n const clearHoverCursor = () => {\n paintedCursorRef.current?.()?.setOverride(null);\n if (cursorOverridden && canvas) {\n canvas.style.cursor = '';\n cursorOverridden = false;\n }\n };\n const applyHoverCursor = (spec: CursorSpec | null) => {\n const tier = spec === null ? null : resolveCursorTier(spec);\n if (!tier || !canvas) {\n clearHoverCursor();\n return;\n }\n // A painted cursor is two writes, not one: the native cursor gets out of\n // the way and the layer is told what to draw. Doing only the first is a\n // pointer with no cursor at all.\n const painted = tier.kind === 'painted' ? tier : null;\n paintedCursorRef.current?.()?.setOverride(painted);\n const cursor = tier.kind === 'css' ? tier.css : 'none';\n if (!cursor) {\n clearHoverCursor();\n return;\n }\n canvas.style.cursor = cursor;\n cursorOverridden = true;\n };\n /**\n * Where the painted-cursor layer should draw, in canvas-local CSS px.\n *\n * Pushed after the cursor has been resolved, not before: on the move that\n * first selects a painted cursor, a position written ahead of the decision\n * is discarded and the glyph does not appear until the next move. Guarded\n * on `active()`, so an ordinary CSS cursor costs no layout read per move.\n */\n function pushPaintedPointer(): void {\n const painted = paintedCursorRef.current?.();\n if (!painted?.active() || !canvas || !lastHover) return;\n const r = canvas.getBoundingClientRect();\n painted.setPointer(lastHover.clientX - r.left, lastHover.clientY - r.top);\n }\n\n function refreshHoverCursor(): void {\n resolveHoverCursor();\n pushPaintedPointer();\n }\n\n function resolveHoverCursor(): void {\n if (!canvas || !lastHover) return;\n // Mid-gesture the prediction is meaningless — what matters is what the\n // gesture IS. An in-flight action's `activeCursor` wins; with none\n // declared the override clears and the active tool's `Tool.cursor`\n // shows through, as before.\n if (held.size > 0 || dispatcherNow().inFlight().size > 0) {\n applyHoverCursor(dispatcherNow().inFlightCursor());\n return;\n }\n const h = lastHover;\n // Idle: re-resolve. Mid-gesture the branch above already returned, so a\n // pinned pointer is never unpinned by a hover refresh.\n routeAt(null, h.clientX, h.clientY);\n const w = toWorld(h.clientX, h.clientY);\n const affordance = target().affordanceAt?.(w) ?? undefined;\n if (affordance?.cursor) {\n applyHoverCursor(affordance.cursor);\n return;\n }\n const hoverBody = target().classifyTarget?.(w);\n const bodyTarget = hoverBody?.body;\n const bodyKind = hoverBody?.kind;\n const where = {\n altKey: h.altKey,\n ctrlKey: h.ctrlKey,\n metaKey: h.metaKey,\n shiftKey: h.shiftKey,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(bodyTarget !== undefined ? { bodyTarget } : {}),\n ...(bodyKind !== undefined ? { bodyKind } : {}),\n };\n const ctx = ctxNow();\n const dragCursor = dispatcherNow().resolveOnly(\n { kind: 'pointerdown', x: w.x, y: w.y, clientX: h.clientX, clientY: h.clientY, ...where },\n ctx,\n )?.action.cursor;\n // A drag's hint first; failing that, what a click here would do.\n const cursor = dragCursor ?? dispatcherNow().resolveOnly(\n { kind: 'click', x: w.x, y: w.y, pressX: w.x, pressY: w.y, ...where },\n ctx,\n )?.action.cursor;\n applyHoverCursor(cursor ?? null);\n }\n /** Modifier/hotkey changes re-route the predicted drag without pointer\n * movement. Refresh after a tick so the key event's React state\n * (hotkey stack, active tool) has committed into `ctxRef`. */\n const scheduleHoverCursorRefresh = (e: KeyboardEvent) => {\n if (!lastHover) return;\n lastHover = {\n ...lastHover,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n // A held pointer's moves arrive through its session, which keeps seeing\n // them once the pointer has left the canvas or the canvas is gone. The\n // canvas listener is left with the hover half.\n const onHoverMove = (e: PointerEvent) => {\n if (held.has(e.pointerId)) return;\n onPointerMove(e);\n };\n\n const onHoverPointerLeave = () => {\n lastHover = null;\n paintedCursorRef.current?.()?.clearPointer();\n clearHoverCursor();\n };\n\n const onPointerUp = (e: PointerEvent) => {\n routeAt(e.pointerId, e.clientX, e.clientY);\n cancelLongPress(e.pointerId);\n const prevSize = held.size;\n // The record outlives the map entry: everything below is synthesized\n // from the press, and reads it after this pointer has stopped counting\n // towards `held.size`.\n const rec = held.get(e.pointerId);\n held.delete(e.pointerId);\n\n // A press still buffered never crossed the drag threshold — the\n // dispatcher never saw it, so no drag handle is in flight and this\n // release is a click. Crossing the threshold clears the buffer whether\n // or not a drag binding matched, which makes this the authoritative\n // \"did the pointer move?\" signal for click synthesis.\n const staysUnderThreshold = rec?.buffered != null;\n\n // When pointer count drops below 2, commit any in-flight multitouch handle\n // and (if the centroid never moved past the tap threshold) synthesize a\n // `multitouchtap` event carrying the peak fingers count.\n // The gestureId is keyed by the PREVIOUS size (before this pointer was removed)\n // because that was the handle's finger count when it was opened.\n if (prevSize >= 2 && held.size < 2) {\n const mtGestureId = `multitouch-${prevSize}`;\n if (dispatcherNow().inFlight().has(mtGestureId)) {\n // Synthesize a pointerup for the multitouch gesture — dispatcher needs\n // a pointerup to route to onEnd, but multitouch handles are keyed by\n // finger count, not by pointer. We use cancelAll to safely commit all\n // in-flight handles of this gesture; only the multitouch handle\n // should be active (see the multi-pointer policy in onPointerDown).\n // Use 'commit' because this is a natural lift (not a cancel).\n dispatcherNow().cancelAll('commit');\n }\n // Synthesize a tap if the centroid hasn't moved past threshold.\n const start = multiTouchStart;\n if (start) {\n // Final centroid uses the pointer positions BEFORE this pointer was\n // removed — it is already out of `held`, so add it back in.\n const centroid = toCanvasLocal(\n computeMultiTouchGeometry([\n ...[...held.values()].map((p) => p.pos),\n { x: e.clientX, y: e.clientY },\n ]).centroid,\n );\n const dx = centroid.x - start.centroid.x;\n const dy = centroid.y - start.centroid.y;\n if (Math.hypot(dx, dy) <= TAP_THRESHOLD_PX) {\n const tap: InputEvent = {\n kind: 'multitouchtap',\n fingers: start.fingers,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(tap);\n }\n multiTouchStart = null;\n }\n }\n\n // Check whether a drag handle is in-flight BEFORE sending pointerup.\n // If THIS pointer's handle is in-flight AND the pointer moved between\n // down and up, this is the end of a real drag — pump it and don't\n // synthesize a click. If no handle is in-flight, or the handle was\n // opened but the pointer never moved (sub-threshold \"tap\" that an\n // over-broad ambient drag binding accepted), we still synthesize a\n // click so click-specific bindings (e.g. clearSelection on empty) fire.\n const movedDuringDrag = rec\n ? (rec.down.clientX !== e.clientX || rec.down.clientY !== e.clientY)\n : true;\n const hadDragInFlight =\n dispatcherNow().inFlight().has(pointerGestureId(e.pointerId)) && movedDuringDrag;\n\n const wUp = toWorld(e.clientX, e.clientY);\n const ev: InputEvent = {\n kind: 'pointerup',\n pointerId: e.pointerId,\n x: wUp.x,\n y: wUp.y,\n clientX: e.clientX,\n clientY: e.clientY,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n };\n dispatch(ev);\n\n const down = rec?.down;\n\n // Synthesize a click when the pointer neither opened a drag handle nor\n // travelled past the drag threshold. Carry the `bodyTarget` from the\n // pointerdown so click specs with string-form targets ('empty',\n // 'selected-body') match.\n //\n // The threshold half of that test is load-bearing for any tool that\n // binds `click` but not `drag`: without it, dragging clear across the\n // canvas and releasing synthesized a click, because \"no drag handle\n // opened\" was the only condition. `ClickSpec` documents itself as\n // \"pointerdown + pointerup without movement past the threshold\" — this\n // is the code finally agreeing with it.\n if (!hadDragInFlight && staysUnderThreshold && down) {\n const wClick = toWorld(e.clientX, e.clientY);\n const clickEv: InputEvent = {\n kind: 'click',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: wClick.x,\n y: wClick.y,\n clientX: e.clientX,\n clientY: e.clientY,\n pressX: down.worldX,\n pressY: down.worldY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n dispatch(clickEv);\n\n // Double-click synthesis: emit a `doubleclick` event AFTER the\n // second click when two clicks land within DOUBLE_CLICK_MAX_MS and\n // DOUBLE_CLICK_MAX_PX. Reset the tracker after a successful\n // doubleclick so a third click doesn't compose another one\n // (triple-click semantics are not modeled).\n const now = Date.now();\n const prev = lastClickRef.current;\n const dx = e.clientX - (prev?.clientX ?? 0);\n const dy = e.clientY - (prev?.clientY ?? 0);\n if (prev && now - prev.t < DOUBLE_CLICK_MAX_MS && Math.hypot(dx, dy) < DOUBLE_CLICK_MAX_PX) {\n const dblEv: InputEvent = {\n kind: 'doubleclick',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: wClick.x,\n y: wClick.y,\n clientX: e.clientX,\n clientY: e.clientY,\n ...(down.affordance !== undefined ? { affordance: down.affordance } : {}),\n ...(down.bodyTarget !== undefined ? { bodyTarget: down.bodyTarget } : {}),\n ...(down.bodyKind !== undefined ? { bodyKind: down.bodyKind } : {}),\n };\n // Notify observers first — see `onDoubleClick`'s doc for why this\n // is not modeled as a binding.\n onDoubleClickRef.current?.({ x: wClick.x, y: wClick.y });\n dispatch(dblEv);\n lastClickRef.current = null;\n } else {\n lastClickRef.current = { t: now, clientX: e.clientX, clientY: e.clientY };\n }\n }\n\n // Every synthesized event this release produces has been dispatched, so\n // the pointer's view can be unpinned.\n routeRelease(e.pointerId);\n\n // Re-resolve the hover cursor at the release point — deferred a tick\n // so any state the up/click actions changed (selection, active tool)\n // has committed before prediction reruns.\n lastHover = {\n clientX: e.clientX, clientY: e.clientY,\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n setTimeout(() => {\n if (!disposed) refreshHoverCursor();\n }, 0);\n };\n\n // Every way a gesture ends without a release: the browser cancelling the\n // pointer, capture going away, a press proving the tracked one had already\n // ended. The session decides which of those happened; the dispatcher\n // treats them alike, and reads the press's own modifiers because a cancel\n // carries none of its own.\n const onPointerCancel = (pointerId: number) => {\n // On teardown every session is cancelled at once; `cancelAll` ends those\n // gestures, so re-entering dispatch here would end them twice.\n if (disposed) return;\n const rec = held.get(pointerId);\n if (!rec) return;\n held.delete(pointerId);\n routeAt(pointerId, rec.pos.x, rec.pos.y);\n cancelLongPress(pointerId);\n // Drop any pending multitouch-tap start state — a cancel means we should\n // not synthesize a tap on the subsequent up.\n multiTouchStart = null;\n const ev: InputEvent = {\n kind: 'pointercancel',\n pointerId,\n altKey: rec.down.altKey,\n ctrlKey: rec.down.ctrlKey,\n metaKey: rec.down.metaKey,\n shiftKey: rec.down.shiftKey,\n };\n dispatch(ev);\n routeRelease(pointerId);\n };\n\n // -----------------------------------------------------------------------\n // Canvas contextmenu listener (right-click)\n // -----------------------------------------------------------------------\n\n const onContextMenu = (e: MouseEvent) => {\n // Suppress native menu so tools/actions own the right-click UX.\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const w = toWorld(e.clientX, e.clientY);\n // A secondary button never reaches `onPointerDown`, so unlike click and\n // long-press there is no press to replay the classification from.\n const affordance = target().affordanceAt?.(w) ?? undefined;\n const menuBody = target().classifyTarget?.(w);\n const ev: InputEvent = {\n kind: 'contextmenu',\n target: e.target,\n altKey: e.altKey,\n ctrlKey: e.ctrlKey,\n metaKey: e.metaKey,\n shiftKey: e.shiftKey,\n x: w.x,\n y: w.y,\n clientX: e.clientX,\n clientY: e.clientY,\n ...(affordance !== undefined ? { affordance } : {}),\n ...(menuBody?.body !== undefined ? { bodyTarget: menuBody.body } : {}),\n ...(menuBody?.kind !== undefined ? { bodyKind: menuBody.kind } : {}),\n };\n dispatch(ev);\n };\n\n // -----------------------------------------------------------------------\n // External-content ingestion: OS drop on the canvas, paste on window.\n // Items are materialized DURING the event (DataTransfer is only live on\n // the event stack); dispatch happens when materialization resolves.\n // -----------------------------------------------------------------------\n\n // Attached to both dragover and dragenter: cancelling dragenter (WHATWG)\n // guarantees the element stays the active drop target and shows the copy\n // cursor on entry rather than waiting for the first dragover tick.\n const onDragOver = (e: DragEvent) => {\n if (!e.dataTransfer) return;\n // preventDefault is what makes the canvas a valid drop target.\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n canvas?.classList.add(DROPOVER_CLASS);\n };\n\n const onDragLeave = () => {\n canvas?.classList.remove(DROPOVER_CLASS);\n };\n\n // No stopPropagation: handled-ness is only known after the async\n // materialization microtask, so a conditional stop (wheel-style) is\n // impossible; an unconditional one would swallow drops the kit doesn't\n // dispatch. Callers that need exclusivity should gate on the action result.\n const onDrop = (e: DragEvent) => {\n canvas?.classList.remove(DROPOVER_CLASS);\n const dt = e.dataTransfer;\n if (!dt) return;\n e.preventDefault();\n routeAt(null, e.clientX, e.clientY);\n const dropOn = target().dispatcher;\n const w = toWorld(e.clientX, e.clientY);\n // Real modifiers forwarded (Option-drag is a copy-drag on macOS); the\n // kit ingest binding declares all modifiers optional, so they can't\n // block the default route — but a consumer binding may key on them.\n const base = {\n altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey,\n };\n void itemsFromDataTransfer(dt).then((items) => {\n if (disposed) return;\n if (items.length === 0) return;\n dispatch({\n kind: 'drop', items,\n x: w.x, y: w.y, clientX: e.clientX, clientY: e.clientY,\n ...base,\n }, dropOn);\n });\n };\n\n const onPaste = (e: ClipboardEvent) => {\n // Text-editing surfaces (inputs, the text-edit overlay) own their own\n // paste — never steal it for scene ingestion.\n if (isEditableTarget(e.target)) return;\n const cd = e.clipboardData;\n if (!cd) return;\n const items = itemsFromClipboardData(cd);\n if (items.length === 0) return;\n // Wheel's shape: dispatch first, suppress the default only when a\n // binding claimed it. Clipboard items materialize synchronously, so\n // unlike `onDrop` the result is known while `preventDefault` is still\n // honored — and a paste no binding wanted stays the page's to handle.\n const result = dispatch({\n kind: 'paste', items,\n // ClipboardEvent carries no modifier state.\n altKey: false, ctrlKey: false, metaKey: false, shiftKey: false,\n });\n if (result === 'handled') e.preventDefault();\n };\n\n // -----------------------------------------------------------------------\n // Attach\n // -----------------------------------------------------------------------\n\n if (keyboard) {\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n }\n window.addEventListener('blur', onWindowBlur);\n // Hover-cursor refresh on modifier/hotkey changes — separate listeners\n // (not folded into onKeyDown/onKeyUp) so the pump also tracks modifiers\n // when `keyboard: false` disables gesture key dispatch.\n window.addEventListener('keydown', scheduleHoverCursorRefresh);\n window.addEventListener('keyup', scheduleHoverCursorRefresh);\n if (pointerChannel) {\n canvas?.addEventListener('pointerleave', onHoverPointerLeave);\n canvas?.addEventListener('pointerdown', onPointerDown);\n canvas?.addEventListener('pointermove', onHoverMove);\n }\n if (wheelChannel) canvas?.addEventListener('wheel', onWheel, { passive: false });\n if (contextMenuChannel) canvas?.addEventListener('contextmenu', onContextMenu);\n if (ingestChannel) {\n canvas?.addEventListener('dragenter', onDragOver);\n canvas?.addEventListener('dragover', onDragOver);\n canvas?.addEventListener('dragleave', onDragLeave);\n canvas?.addEventListener('drop', onDrop);\n window.addEventListener('paste', onPaste);\n }\n\n // -----------------------------------------------------------------------\n // Cleanup\n // -----------------------------------------------------------------------\n\n return () => {\n if (keyboard) {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n }\n window.removeEventListener('blur', onWindowBlur);\n window.removeEventListener('keydown', scheduleHoverCursorRefresh);\n window.removeEventListener('keyup', scheduleHoverCursorRefresh);\n canvas?.removeEventListener('pointerleave', onHoverPointerLeave);\n canvas?.removeEventListener('wheel', onWheel);\n canvas?.removeEventListener('pointerdown', onPointerDown);\n canvas?.removeEventListener('pointermove', onHoverMove);\n canvas?.removeEventListener('contextmenu', onContextMenu);\n canvas?.removeEventListener('dragenter', onDragOver);\n canvas?.removeEventListener('dragover', onDragOver);\n canvas?.removeEventListener('dragleave', onDragLeave);\n canvas?.removeEventListener('drop', onDrop);\n window.removeEventListener('paste', onPaste);\n // Detach is unconditional: a channel turned off mid-life must still\n // have whatever it attached while it was on taken back off.\n canvas?.classList.remove(DROPOVER_CLASS);\n clearHoverCursor();\n cancelAllLongPress();\n disposed = true;\n // `disposed` first: the sessions' cancels must not re-enter dispatch on\n // the way out, and `cancelAll` below is what ends the gestures.\n for (const p of held.values()) p.session.cancel();\n held.clear();\n for (const d of allDispatchers()) d.cancelAll('cancel');\n };\n }, [enabled, keyboard, canvasRef, pointerChannel, wheelChannel, contextMenuChannel, ingestChannel]);\n}\n","/**\n * @experimental\n * The React half of the actions registry: the context, the provider that owns\n * the id → descriptor stack, the mute scope, and the two hooks. The store\n * contract it implements is in `registry.tsx`.\n */\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { Action } from './action';\nimport { useOptionalDepRegistry, type DepRegistry, type DepName } from './depRegistry';\nimport { buildDepsFromRequires } from './buildDeps';\nimport type { Dispatcher } from '../dispatcher/dispatcher';\nimport { validateActionId, validateActionDefaultBinding, type ActionsRegistry } from './registry';\n\n\nconst ActionsContext = createContext<ActionsRegistry | null>(null);\n\n/** Everything a registry does apart from muting, which is layered on top of it\n * once per scope by `useMuted`. */\ntype ActionsStore = Omit<ActionsRegistry, 'mute'>;\n\n/**\n * Layers a mute set over `base`. Registration, `unregister`, `trigger`'s\n * effects, and the dispatcher / dep-registry slots all pass straight through,\n * so what one scope registers every sibling still sees; only this scope's own\n * reads and invocations skip what it muted.\n */\nfunction useMuted(base: ActionsStore | null): ActionsRegistry | null {\n const mutedRef = useRef<Map<string, number>>(new Map());\n const listenersRef = useRef<Set<() => void>>(new Set());\n const cacheRef = useRef<{ src: readonly Action[]; out: readonly Action[] } | null>(null);\n\n return useMemo<ActionsRegistry | null>(() => {\n if (!base) return null;\n const isMuted = (id: string): boolean => mutedRef.current.has(id);\n const notify = (): void => {\n for (const l of listenersRef.current) {\n try {\n l();\n } catch (err) {\n console.error('weasel ActionsRegistry: subscriber threw', err);\n }\n }\n };\n return {\n ...base,\n list: () => {\n const src = base.list();\n if (mutedRef.current.size === 0) return src;\n const cached = cacheRef.current;\n if (cached && cached.src === src) return cached.out;\n const out = Object.freeze(src.filter((a) => !mutedRef.current.has(a.id)));\n cacheRef.current = { src, out };\n return out;\n },\n trigger: (id, params) => (isMuted(id) ? false : base.trigger(id, params)),\n begin: (id, params) => (isMuted(id) ? null : base.begin(id, params)),\n subscribe: (listener) => {\n const offBase = base.subscribe(listener);\n listenersRef.current.add(listener);\n return () => {\n offBase();\n listenersRef.current.delete(listener);\n };\n },\n mute: (id: string) => {\n mutedRef.current.set(id, (mutedRef.current.get(id) ?? 0) + 1);\n cacheRef.current = null;\n notify();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const held = mutedRef.current.get(id);\n if (held === undefined) return;\n if (held > 1) mutedRef.current.set(id, held - 1);\n else mutedRef.current.delete(id);\n cacheRef.current = null;\n notify();\n };\n },\n };\n }, [base]);\n}\n\n/**\n * @experimental\n * A view of the registry in scope that can declare ids not for itself. Wrap\n * anything that should be able to opt out of an action — a second\n * `<SceneCanvas>` sharing the host's `<ActionsProvider>` mounts one — and its\n * `mute` calls stay inside it. Renders nothing of its own.\n *\n * Not a `BindingScope`: that names the tier a binding matches at (hotkey /\n * active / ambient), which this has nothing to do with.\n */\nexport function ActionsScope({ children }: { children: ReactNode }): ReactElement {\n const parent = useActionsRegistry();\n const scoped = useMuted(parent);\n if (!scoped) return <>{children}</>;\n return <ActionsContext.Provider value={scoped}>{children}</ActionsContext.Provider>;\n}\n\n/**\n * @experimental\n * Mounts an `ActionsRegistry` for its lifetime. Children call\n * `useActionsRegistry()` or `useAction()` to participate. Mounts no input\n * listener of its own — the gesture dispatcher owns input.\n */\n/**\n * Push `value` onto an owner stack and hand back its release.\n *\n * Newest wins, but the release takes out *its own* entry wherever it now sits,\n * so a displaced owner leaving cannot disturb the one above it and the owner\n * on top leaving uncovers the one below rather than emptying the stack. A\n * `null` value registers nothing and releases to a no-op. Double-release safe.\n */\nfunction pushOwner<T>(ref: { current: T[] }, value: T | null): () => void {\n if (value === null) return () => {};\n ref.current.push(value);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const i = ref.current.lastIndexOf(value);\n if (i !== -1) ref.current.splice(i, 1);\n };\n}\n\nexport function ActionsProvider({ children }: { children: ReactNode }): ReactElement {\n // A stack of registrants per id, newest live. Two canvases under one provider\n // both register `viewport.zoom`; with a single slot the second displaced the\n // first and its teardown then deleted the entry outright, taking wheel zoom\n // away from the canvas still on screen. Stacking means a displaced registrant\n // is restored when the one above it leaves.\n const actionsRef = useRef<Map<string, Action[]>>(new Map());\n const liveAction = (id: string): Action | undefined => actionsRef.current.get(id)?.at(-1);\n const versionRef = useRef(0);\n const cachedRef = useRef<readonly Action[]>([]);\n const cachedVerRef = useRef(-1);\n const listenersRef = useRef<Set<() => void>>(new Set());\n\n // Trigger() consults the optional dep registry so actions can be fired\n // imperatively from ActionBar / palette callers — the registered\n // `invoker.run` receives a deps bag built fresh from the registry.\n const depReg = useOptionalDepRegistry();\n const depRegRef = useRef<DepRegistry | null>(depReg);\n depRegRef.current = depReg;\n\n // One warning per registry: the message is about the scope, not about which\n // canvas lost, and a page of canvases would otherwise repeat it per mount.\n const warnedRef = useRef(false);\n\n // Dep registry wired via setDepRegistry — set by SceneCanvas's registrar\n // when this provider sits above the dep-registry scope (consumer root\n // <ActionsProvider>). Preferred over the context read above.\n //\n // A stack, newest live, for the same reason the registrant stacks above are:\n // two canvases under one provider both wire themselves, and with a single\n // slot whichever one unmounts empties it — taking the wiring away from the\n // canvas still on screen. The dispatcher ref below is the same story.\n const wiredDepRegRef = useRef<DepRegistry[]>([]);\n\n // Dispatcher stack — wired from SceneCanvas via setDispatcher so that\n // begin() can delegate to beginUiOngoing.\n const dispatcherRef = useRef<Dispatcher[]>([]);\n\n // The legacy keystroke loop that walked every action's\n // `defaultBinding: KeyBinding` and matched against keydown is gone, along\n // with the per-action consumer hooks (`useEscape`, `useDelete`, ...) that\n // carried their own `useKeybinding` listener. Every kit-standard descriptor\n // now routes through the gesture dispatcher via `defaultBinding`.\n\n const store = useMemo<ActionsStore>(() => {\n const snapshot = (): readonly Action[] => {\n const v = versionRef.current;\n if (cachedVerRef.current === v) return cachedRef.current;\n const out = Object.freeze(\n Array.from(actionsRef.current.values(), (stack) => stack[stack.length - 1]),\n );\n cachedRef.current = out;\n cachedVerRef.current = v;\n return out;\n };\n const notify = (): void => {\n for (const l of listenersRef.current) {\n try {\n l();\n } catch (err) {\n console.error('weasel ActionsRegistry: subscriber threw', err);\n }\n }\n };\n return {\n register: (action: Action) => {\n validateActionId(action.id);\n validateActionDefaultBinding(action);\n const stack = actionsRef.current.get(action.id);\n if (stack) stack.push(action);\n else actionsRef.current.set(action.id, [action]);\n versionRef.current++;\n notify();\n let released = false;\n return () => {\n if (released) return;\n released = true;\n const cur = actionsRef.current.get(action.id);\n if (!cur) return;\n // Our own entry, wherever it now sits: a registrant that was already\n // displaced must take itself out without disturbing the one above it.\n const i = cur.lastIndexOf(action);\n if (i === -1) return;\n cur.splice(i, 1);\n if (cur.length === 0) actionsRef.current.delete(action.id);\n versionRef.current++;\n notify();\n };\n },\n unregister: (id: string) => {\n // Drops every registrant of `id`, not just the live one — this is the\n // \"this action should not exist\" door, not a release.\n if (actionsRef.current.delete(id)) {\n versionRef.current++;\n notify();\n }\n },\n list: () => snapshot(),\n trigger: (id: string, params?: Record<string, unknown>) => {\n const a = liveAction(id);\n if (!a) return false;\n try {\n if (a.invoker && a.invoker.timing === 'immediate') {\n const r = wiredDepRegRef.current.at(-1) ?? depRegRef.current;\n // Prefer the action's declared `requires` (same contract the\n // dispatcher uses — shared `buildDepsFromRequires`, including\n // the dev-mode undeclared-read guard); legacy fixed bag\n // otherwise.\n const deps = !r\n ? {}\n : a.requires\n ? buildDepsFromRequires(a, r)\n : {\n selection: r.get('selection' as DepName),\n scene: r.get('scene' as DepName),\n history: r.get('history' as DepName),\n view: r.get('view' as DepName),\n activeTool: r.get('activeTool' as DepName),\n booleansAdapter: r.get('booleansAdapter' as DepName),\n };\n a.invoker.run(deps as never, params);\n }\n } catch (err) {\n console.error(`weasel ActionsRegistry: action \"${id}\" threw`, err);\n }\n return true;\n },\n subscribe: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => {\n listenersRef.current.delete(listener);\n };\n },\n setDispatcher: (d: Dispatcher | null) => {\n if (d && dispatcherRef.current.length > 0 && dispatcherRef.current.at(-1) !== d\n && !warnedRef.current) {\n warnedRef.current = true;\n warnSharedScope();\n }\n return pushOwner(dispatcherRef, d);\n },\n setDepRegistry: (r: DepRegistry | null) => pushOwner(wiredDepRegRef, r),\n begin: (id: string, params?: Record<string, unknown>) => {\n const disp = dispatcherRef.current.at(-1) ?? null;\n if (!disp) return null;\n const r = wiredDepRegRef.current.at(-1) ?? depRegRef.current;\n const a = liveAction(id);\n // Same resolution order as `trigger`: the action's declared `requires`\n // when it has one, the legacy fixed bag otherwise. The fixed bag has no\n // `applyOps`, so the paint actions — which declare it and are the only\n // callers of `begin` — used to fall back to the scene's own history\n // instead of the consumer's.\n const deps = !r\n ? {}\n : a?.requires\n ? buildDepsFromRequires(a, r)\n : {\n selection: r.get('selection' as DepName),\n scene: r.get('scene' as DepName),\n history: r.get('history' as DepName),\n view: r.get('view' as DepName),\n activeTool: r.get('activeTool' as DepName),\n booleansAdapter: r.get('booleansAdapter' as DepName),\n };\n return disp.beginUiOngoing(id, deps as never, params);\n },\n };\n }, []);\n\n // The provider is a scope in its own right, so a lone canvas can mute\n // without one wrapped around it.\n const registry = useMuted(store)!;\n\n return <ActionsContext.Provider value={registry}>{children}</ActionsContext.Provider>;\n}\n\n/**\n * @experimental\n * Returns the parent `ActionsRegistry`, or `null` when no provider is in scope.\n */\n/**\n * `import.meta.env.DEV` read through a cast — core must not depend on a\n * bundler's ambient augmentation (`vite/client`) to compile. Mirrors the same\n * cast in SceneCanvas.tsx, dispatcher.ts and buildDeps.ts.\n */\n/**\n * A second `<SceneCanvas>` claiming one registry leaves the first unable to\n * dispatch anything, and the symptom — a canvas that stops responding — names\n * neither canvas nor the registry they share.\n */\nfunction warnSharedScope(): void {\n if (!IS_DEV) return;\n console.warn(\n 'weasel: a second dispatcher claimed this <ActionsProvider>, so only the ' +\n 'newest <SceneCanvas> under it will respond to input. Give each canvas its ' +\n 'own scope with <WeaselProvider isolate>.',\n );\n}\n\nconst IS_DEV: boolean = (() => {\n try {\n return Boolean((import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV);\n } catch {\n return false;\n }\n})();\n\nexport function useActionsRegistry(): ActionsRegistry | null {\n return useContext(ActionsContext);\n}\n\n/**\n * @experimental\n * Register an `Action` for the lifetime of the calling component. No-op (with\n * a dev-only warning) when no `ActionsProvider` is in scope. Re-registers on\n * `action` reference change (consumers should memoize stable identities to\n * avoid churn).\n */\nexport function useAction(action: Action): void {\n const reg = useActionsRegistry();\n useEffect(() => {\n if (!reg) {\n if (IS_DEV) {\n console.warn(\n `useAction(\"${action.id}\"): no <ActionsProvider> is in scope, so the action was not registered and its bindings will never fire.`,\n );\n }\n return;\n }\n return reg.register(action);\n }, [reg, action]);\n}\n","// src/contributions/useContributions.ts\nimport { useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { ScopedBinding } from '../interactions/dispatcher/matcher';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useActionsRegistry } from '../interactions/actions/ActionsProvider';\nimport {\n buildToolOffhandBindings,\n makeToolOffhandAction,\n offhandKeyFor,\n type ToolOffhandBindingSpec,\n} from '../interactions/actions/toolOffhand';\nimport { reportRouteConflicts } from '../tools/routing/reflection/conflicts';\nimport type { Tool } from '../tools/types';\nimport type { HotkeyTrigger } from './types';\nimport { scopeBindings } from './assemble';\nimport { liveScope } from './eligibility';\nimport type { Contribution, OverlayPosition } from './types';\nimport { isDev } from '../devFlag';\n\nexport interface UseContributionsOptions<TOverlay = unknown> {\n /** Every registry entry, in declaration order. Order decides which of two\n * same-specificity bindings in one scope tier wins. */\n entries: readonly Contribution<TOverlay>[];\n /** Desired focused entry id. First-mount-wins against the shared\n * `ActiveToolContext` — see `useTools` for the full semantics. */\n focused: string;\n}\n\nexport interface ContributionsApi<TOverlay = unknown> {\n /** Every entry, as passed in. */\n entries: readonly Contribution<TOverlay>[];\n /** Currently focused entry id. */\n focused: string;\n /** Focus an entry. Writes through to the shared `ActiveToolContext`. */\n setFocused: (id: string) => void;\n /** Every live binding, tiered by the declaring entry's eligibility. */\n scopedBindings(): ScopedBinding[];\n /** Overlays of every live entry declaring `position`, ordered active, then\n * hotkey, then ambient. */\n overlays(position?: OverlayPosition): TOverlay[];\n}\n\n/**\n * Assembles one registry: every entry's bindings and overlays, each tiered by\n * what the entry declares about its own eligibility rather than by which\n * argument a consumer passed it in.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally): focus and held-key state live\n * in the context so the gesture dispatcher and every sibling caller read the\n * same source of truth.\n */\nexport function useContributions<TOverlay = unknown>(\n opts: UseContributionsOptions<TOverlay>,\n): ContributionsApi<TOverlay> {\n const ctx = useActiveToolContext();\n const actionsRegistry = useActionsRegistry();\n\n // First-mount sync: if context is at its default ('select') and the caller\n // wants something else, push it. Captured at first render; the setState runs\n // in a post-commit effect so it never updates state during render.\n const hasInitializedRef = useRef(false);\n const isFirstRender = !hasInitializedRef.current;\n const needsFirstMountSyncRef = useRef(false);\n if (isFirstRender) {\n hasInitializedRef.current = true;\n needsFirstMountSyncRef.current = ctx.active === 'select' && opts.focused !== 'select';\n }\n useEffect(() => {\n if (!needsFirstMountSyncRef.current) return;\n needsFirstMountSyncRef.current = false;\n ctx.setActive(opts.focused);\n // First-mount sync only — deliberately runs once after mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const focused = isFirstRender && ctx.active === 'select' && opts.focused !== 'select'\n ? opts.focused\n : ctx.active;\n\n // Refs so the memoized callbacks below see latest values without\n // re-creating themselves.\n const entriesRef = useRef(opts.entries);\n entriesRef.current = opts.entries;\n const focusedRef = useRef(focused);\n focusedRef.current = focused;\n const engagedRef = useRef<readonly string[]>(ctx.hotkeyStack);\n engagedRef.current = ctx.hotkeyStack;\n\n const setFocused = useCallback((id: string) => { ctx.setActive(id); }, [ctx]);\n\n /** Live eligibility state, plus the entries ordered so that hotkey-engaged\n * ones come first — stack order breaks ties within the hotkey tier. */\n const snapshot = useCallback(() => {\n const engaged = engagedRef.current;\n const engagedIds = new Set(engaged);\n const ordered: Contribution<TOverlay>[] = [];\n for (const id of engaged) {\n const entry = entriesRef.current.find((e) => e.id === id);\n if (entry && !ordered.includes(entry)) ordered.push(entry);\n }\n for (const entry of entriesRef.current) {\n if (!ordered.includes(entry)) ordered.push(entry);\n }\n return {\n ordered,\n state: { focusedId: focusedRef.current, engagedIds },\n };\n }, []);\n\n const scopedBindings = useCallback((): ScopedBinding[] => {\n const { ordered, state } = snapshot();\n return scopeBindings(ordered, state);\n }, [snapshot]);\n\n const overlays = useCallback((position: OverlayPosition = 'top'): TOverlay[] => {\n const { ordered, state } = snapshot();\n const active: TOverlay[] = [];\n const hotkey: TOverlay[] = [];\n const ambient: TOverlay[] = [];\n for (const entry of ordered) {\n if (!entry.overlay) continue;\n if ((entry.overlayPosition ?? 'top') !== position) continue;\n const layers = Array.isArray(entry.overlay) ? entry.overlay : [entry.overlay];\n const scope = liveScope(entry.id, entry.eligibility ?? {}, state);\n if (scope === 'active') active.push(...layers);\n else if (scope === 'hotkey') hotkey.push(...layers);\n else if (scope === 'ambient') ambient.push(...layers);\n }\n return [...active, ...hotkey, ...ambient];\n }, [snapshot]);\n\n // A declared `offhand` trigger registers its own engagement. One\n // consolidated `tool.offhand` action serves every entry that declares one;\n // its invoker reads `params.toolId` off the matched binding.\n const offhandSig = opts.entries\n .map((e) => (e.eligibility?.offhand ? `${e.id}:${e.eligibility.offhand}` : ''))\n .filter(Boolean)\n .join(',');\n useEffect(() => {\n if (!actionsRegistry || offhandSig === '') return;\n const specs: ToolOffhandBindingSpec[] = offhandSig.split(',').map((entry) => {\n const [toolId, trigger] = entry.split(':');\n return { toolId, key: offhandKeyFor(trigger as HotkeyTrigger) };\n });\n return actionsRegistry.register(makeToolOffhandAction(buildToolOffhandBindings(specs)));\n }, [actionsRegistry, offhandSig]);\n\n // Route-conflict check. Two entries declaring the same (phase, gesture, arg,\n // target, modifiers) tuple in one scope are resolved by declaration order and\n // almost certainly not as either author intended. This is where the entry set\n // is assembled, so this is where it looks.\n //\n // Dev-only, and deduped on a signature of the entry set: the check walks\n // every binding of every entry, and consumers usually rebuild the entry list\n // each render. Actions are read inside the effect, after the registrations\n // that ran in child effects have landed.\n const lastConflictSigRef = useRef<string | null>(null);\n const entrySig = opts.entries.map((e) => e.id).join(',');\n useEffect(() => {\n if (!isDev()) return;\n if (lastConflictSigRef.current === entrySig) return;\n lastConflictSigRef.current = entrySig;\n // An entry can be in both buckets and usually is: every tool `defineTool`\n // builds declares `focus: true`, and an ambient one carries `always: true`\n // on top of that. Sorting on \"not focus-eligible\" put ambient tools in the\n // registry bucket, which is never compared against itself — registry tools\n // take turns in the active slot — so ambient-vs-ambient went unreported.\n const registry: Tool<unknown, TOverlay>[] = [];\n const ambient: Tool<unknown, TOverlay>[] = [];\n for (const entry of entriesRef.current) {\n if (entry.eligibility?.focus) registry.push(entry);\n if (entry.eligibility?.always || entry.eligibility?.claimed) ambient.push(entry);\n }\n reportRouteConflicts({\n registry,\n ambient,\n actions: actionsRegistry?.list() ?? [],\n });\n }, [entrySig, actionsRegistry]);\n\n // Memoized so consumers using the result as an effect dep don't see identity\n // churn every render — which loops infinitely when the consumer setStates\n // from inside such an effect. `entries` is a getter for that reason: read as\n // a property it would be captured at memo time, and a consumer that adds an\n // entry without switching tools would get a live, hittable binding with no\n // palette entry. The other two members already read the ref, being calls.\n return useMemo(\n () => ({\n get entries() { return entriesRef.current; },\n focused,\n setFocused,\n scopedBindings,\n overlays,\n }),\n [focused, setFocused, scopedBindings, overlays],\n );\n}\n","// src/tools/useTools.ts\nimport { useCallback, useMemo, useRef } from 'react';\nimport { dlog } from '../dlog';\nimport type { AnyTool, AnyToolOf } from './types';\nimport type { HotkeyTrigger } from '../contributions/types';\nimport { useActiveToolContext } from '../interactions/actions/activeToolContext';\nimport { useContributions } from '../contributions/useContributions';\nimport type { Contribution, Eligibility, OverlayPosition } from '../contributions/types';\n\n/** Options for `useTools`: which tools exist, which one starts active, and\n * which run continuously regardless of the active one. */\nexport interface UseToolsOptions<TOverlay = unknown> {\n /** Initial active-slot tool id. Must exist in `registry`. */\n active: string;\n /** Tools eligible for the active slot or hotkey slot. The keys are the\n * tool ids; the values are the tool records. A tool with `hotkey` set\n * is wired into the hotkey slot whenever the engagement state matches. */\n registry: Record<string, AnyToolOf<TOverlay>>;\n /** Always-on tools — listen continuously regardless of active slot. */\n ambient?: AnyToolOf<TOverlay>[];\n}\n\n/** The tool registry's runtime surface: which tool is active, which is\n * temporarily held by a hotkey, and how to change either. */\nexport interface ToolsApi<TOverlay = unknown> {\n /** Current active-slot tool id. */\n active: string;\n /** Set the active-slot tool. The gesture dispatcher watches the active\n * tool and cancels any in-flight handle itself. */\n setActive: (id: string) => void;\n /** Currently hotkey-engaged tool id (or `null`). Derived as the top of\n * the hotkey stack for backwards compat with the pre-stack API. */\n hotkeyEngaged: string | null;\n /** Engage a hotkey-slot tool by id. */\n engageHotkey: (id: string) => void;\n /** Disengage the hotkey-slot tool, if any. */\n disengageHotkey: () => void;\n /** All always-on tools, in registration order. */\n ambient: readonly AnyToolOf<TOverlay>[];\n /** Full registry — for userland UI (palette buttons, etc.). */\n registry: Readonly<Record<string, AnyToolOf<TOverlay>>>;\n /** Returns true if a tool with the given id is in the registry or ambient list. */\n has(id: string): boolean;\n /** All overlay layers from currently-engaged tools (active slot, hotkey\n * slot if engaged, all ambient slot tools) that declare `position`.\n * Filters out tools with no `overlay` field. Order: active, then hotkey\n * (if engaged), then ambient (registration order). */\n getActiveOverlays(position?: OverlayPosition): TOverlay[];\n}\n\n/** The slot a caller passed a tool in, restated as declared eligibility.\n * `ToolDef.hotkey` becomes `offhand` — it is the same declaration, read off\n * the authored form via the `def` reflection handle. A tool that already\n * declares what its slot implies is returned as-is: `ToolsApi.registry`\n * hands back the objects the caller passed, and consumers compare identity. */\nfunction declareSlot<T extends AnyTool>(tool: T, slot: 'focus' | 'always'): T {\n const hotkey = (tool.def as { hotkey?: HotkeyTrigger } | undefined)?.hotkey;\n const eligibility: Eligibility = {\n ...tool.eligibility,\n [slot]: true,\n ...(hotkey ? { offhand: hotkey } : {}),\n };\n return sameEligibility(tool.eligibility, eligibility) ? tool : { ...tool, eligibility };\n}\n\nfunction sameEligibility(a: Eligibility | undefined, b: Eligibility): boolean {\n if (!a) return false;\n const keys = new Set([...Object.keys(a), ...Object.keys(b)]) as Set<keyof Eligibility>;\n for (const key of keys) if (a[key] !== b[key]) return false;\n return true;\n}\n\n/**\n * Manages the active tool and hotkey slot.\n *\n * A thin shim over {@link useContributions}: the `registry` / `ambient`\n * arguments are restated as declared eligibility (`focus` / `always`), and\n * assembly happens in one place for tools and non-tool contributions alike.\n *\n * Requires `<ActiveToolContextProvider>` (or `<WeaselProvider>` /\n * `<SceneCanvas>`, which mount one internally) in scope: active/hotkey state\n * lives in the context so the gesture dispatcher and any sibling\n * `useTools` calls all read the same source of truth.\n *\n * **First-mount-wins semantics**: if `opts.active` differs from the context\n * default (`'select'`) on first mount, `useTools` pushes `opts.active` to\n * the context. Subsequent mounts respect whatever the context currently\n * holds (the first caller wins).\n */\nexport function useTools<TOverlay = unknown>(\n opts: UseToolsOptions<TOverlay>,\n): ToolsApi<TOverlay> {\n if (!(opts.active in opts.registry)) {\n throw new Error(`useTools: active \"${opts.active}\" not in registry`);\n }\n\n const ctx = useActiveToolContext();\n\n const slotted = useMemo(() => {\n const registry: Record<string, AnyToolOf<TOverlay>> = {};\n for (const [id, tool] of Object.entries(opts.registry)) {\n registry[id] = declareSlot(tool, 'focus');\n }\n const ambient = (opts.ambient ?? []).map((t) => declareSlot(t, 'always'));\n const byId = new Map<string, Contribution<TOverlay>>();\n for (const tool of [...Object.values(registry), ...ambient]) {\n const prior = byId.get(tool.id);\n if (prior) byId.set(tool.id, { ...tool, eligibility: { ...prior.eligibility, ...tool.eligibility } });\n else byId.set(tool.id, tool);\n }\n return { registry, ambient, entries: [...byId.values()] };\n }, [opts.registry, opts.ambient]);\n\n const contributions = useContributions<TOverlay>({ entries: slotted.entries, focused: opts.active });\n\n const hotkeyEngaged = ctx.hotkeyStack.at(-1) ?? null;\n\n // Refs so the memoized callbacks below see latest values without\n // re-creating themselves.\n const slottedRef = useRef(slotted);\n slottedRef.current = slotted;\n const activeRef = useRef(contributions.focused);\n activeRef.current = contributions.focused;\n const hotkeyRef = useRef(hotkeyEngaged);\n hotkeyRef.current = hotkeyEngaged;\n\n const setFocused = contributions.setFocused;\n const setActive = useCallback(\n (id: string) => {\n if (!(id in slottedRef.current.registry)) {\n throw new Error(`setActive: \"${id}\" not in registry`);\n }\n dlog('tools', 'active:', activeRef.current, '→', id);\n setFocused(id);\n },\n [setFocused],\n );\n\n const engageHotkey = useCallback(\n (id: string) => {\n if (!(id in slottedRef.current.registry)) {\n throw new Error(`engageHotkey: \"${id}\" not in registry`);\n }\n dlog('tools', 'hotkey engaged:', id);\n ctx.pushHotkey(id);\n },\n [ctx],\n );\n\n const disengageHotkey = useCallback(() => {\n if (hotkeyRef.current) dlog('tools', 'hotkey disengaged:', hotkeyRef.current);\n ctx.popHotkey();\n }, [ctx]);\n\n const has = useCallback(\n (id: string): boolean =>\n id in slottedRef.current.registry\n || slottedRef.current.ambient.some((t) => t.id === id),\n [],\n );\n\n // Memoize the returned ToolsApi so consumers using `tools` as a dep (e.g.\n // SceneCanvas's `onToolsCreated` useEffect) don't see identity churn on\n // every render — which otherwise loops infinitely when the consumer\n // setStates from inside `onToolsCreated`.\n const active = contributions.focused;\n const getActiveOverlays = contributions.overlays;\n // Which tools exist, not which object holds them: callers commonly rebuild\n // `opts.registry` as a literal every render, and keying the memo on\n // `slotted` itself would hand them a new `ToolsApi` per render.\n const registryKey =\n Object.keys(slotted.registry).sort().join('|')\n + '#' + slotted.ambient.map((t) => t.id).join('|');\n return useMemo(\n () => ({\n active,\n setActive,\n hotkeyEngaged,\n engageHotkey,\n disengageHotkey,\n ambient: slottedRef.current.ambient,\n registry: slottedRef.current.registry,\n has,\n getActiveOverlays,\n }),\n // `registryKey` isn't read in the body on purpose: the body reads\n // `slottedRef.current`, and the key is what tells us that ref's contents moved.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [active, setActive, hotkeyEngaged, engageHotkey, disengageHotkey, has, getActiveOverlays, registryKey],\n );\n}\n"]}
|