@takazudo/zfb 3.1.0 → 3.2.0

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.
Files changed (58) hide show
  1. package/dist/config.d.ts +28 -3
  2. package/dist/config.js +23 -12
  3. package/dist/config.js.map +1 -1
  4. package/dist/content.js.map +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/island-boundary.d.ts +2 -2
  8. package/dist/island-boundary.js +4 -2
  9. package/dist/island-boundary.js.map +1 -1
  10. package/dist/island.d.ts +8 -4
  11. package/dist/island.js +1 -1
  12. package/dist/island.js.map +1 -1
  13. package/dist/jsx-types.d.ts +1 -1
  14. package/dist/jsx-types.js.map +1 -1
  15. package/dist/runtime.js.map +1 -1
  16. package/dist/slugify.js.map +1 -1
  17. package/dist/zudo-react/description.d.ts +18 -0
  18. package/dist/zudo-react/description.js +41 -0
  19. package/dist/zudo-react/description.js.map +1 -1
  20. package/dist/zudo-react/dom-bindings.d.ts +2 -1
  21. package/dist/zudo-react/dom-bindings.js +16 -22
  22. package/dist/zudo-react/dom-bindings.js.map +1 -1
  23. package/dist/zudo-react/forms.js.map +1 -1
  24. package/dist/zudo-react/hydrate.js +20 -30
  25. package/dist/zudo-react/hydrate.js.map +1 -1
  26. package/dist/zudo-react/index.d.ts +2 -1
  27. package/dist/zudo-react/index.js.map +1 -1
  28. package/dist/zudo-react/jsx-dev-runtime.d.ts +2 -6
  29. package/dist/zudo-react/jsx-dev-runtime.js +3 -3
  30. package/dist/zudo-react/jsx-dev-runtime.js.map +1 -1
  31. package/dist/zudo-react/jsx-runtime.js +2 -2
  32. package/dist/zudo-react/jsx-runtime.js.map +1 -1
  33. package/dist/zudo-react/jsx-types.d.ts +59 -23
  34. package/dist/zudo-react/jsx-types.js.map +1 -1
  35. package/dist/zudo-react/props-transport.d.ts +2 -0
  36. package/dist/zudo-react/props-transport.js +42 -14
  37. package/dist/zudo-react/props-transport.js.map +1 -1
  38. package/dist/zudo-react/raw-html.d.ts +1 -0
  39. package/dist/zudo-react/raw-html.js +120 -0
  40. package/dist/zudo-react/raw-html.js.map +1 -0
  41. package/dist/zudo-react/reactive.js.map +1 -1
  42. package/dist/zudo-react/render-html.d.ts +11 -1
  43. package/dist/zudo-react/render-html.js +83 -56
  44. package/dist/zudo-react/render-html.js.map +1 -1
  45. package/dist/zudo-react/root.js +24 -1
  46. package/dist/zudo-react/root.js.map +1 -1
  47. package/dist/zudo-react/server.d.ts +2 -0
  48. package/dist/zudo-react/server.js.map +1 -1
  49. package/dist/zudo-react/style.d.ts +10 -0
  50. package/dist/zudo-react/style.js +525 -0
  51. package/dist/zudo-react/style.js.map +1 -0
  52. package/dist/zudo-react/testing.d.ts +27 -0
  53. package/dist/zudo-react/testing.js +117 -0
  54. package/dist/zudo-react/testing.js.map +1 -0
  55. package/dist/zudo-react/vocabulary.d.ts +7 -0
  56. package/dist/zudo-react/vocabulary.js +64 -5
  57. package/dist/zudo-react/vocabulary.js.map +1 -1
  58. package/package.json +16 -10
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,wEAAwE;AACxE,uEAAuE;AACvE,mBAAmB;AACnB,EAAE;AACF,kDAAkD;AAClD,sEAAsE;AACtE,gDAAgD;AAChD,2EAA2E;AAC3E,wEAAwE;AACxE,sEAAsE;AACtE,sCAAsC;AACtC,6CAA6C;AAC7C,EAAE;AACF,2EAA2E;AAC3E,oEAAoE;AACpE,sEAAsE;AACtE,8DAA8D;AAE9D,OAAO,EAAE,WAAW,EAAa,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAiBhF,MAAM,CAAC,GAAG,UAA6B,CAAC;AAExC;;;;GAIG;AACH,SAAS,uBAAuB,CAC9B,MAAe,EACf,IAA+B,EAC/B,IAAgB;IAEhB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,YAAY;IACZ,OAAO,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAe,EACf,IAA+B,EAC/B,IAAgB;IAEhB,OAAO,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC;AAC5D,CAAC;AAED,SAAS,IAAI;IACX,sBAAsB;AACxB,CAAC;AAED;;;;;GAKG;AACH,SAAS,OAAO,CAAC,EAAc;IAI7B,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,OAAO;QACL,GAAG;YACD,IAAI,SAAS,IAAI,KAAK;gBAAE,OAAO;YAC/B,KAAK,GAAG,IAAI,CAAC;YACb,EAAE,EAAE,CAAC;QACP,CAAC;QACD,MAAM;YACJ,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC;YACvB,SAAS,GAAG,IAAI,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAgB;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B,IAAI,OAAO,CAAC,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,GAAG,EAAE;YACV,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,YAAY;gBAAE,OAAO;YACzB,IAAI,OAAO,CAAC,CAAC,kBAAkB,KAAK,UAAU;gBAAE,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC/E,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACvC,OAAO,GAAG,EAAE;QACV,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,MAAe,EACf,IAAgB;IAEhB,MAAM,QAAQ,GAAG,CAAC,CAAC,oBAAoB,CAAC;IAExC,qEAAqE;IACrE,qEAAqE;IACrE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;QACf,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzB,GAAG,CAAC,UAAU,EAAE,CAAC;gBACjB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC,EACD,EAAE,SAAS,EAAE,CAAC,EAAE,CACjB,CAAC;IAEF,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,YAAY;gBAAE,OAAO;YACzB,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAe,EAAE,IAAgB;IACtD,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAEhD,wEAAwE;IACxE,sEAAsE;IACtE,cAAc;IACd,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;QACjD,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAEhC,qEAAqE;IACrE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B,IAAI,cAAc,GAAG,IAAI,CAAC;IAE1B,6DAA6D;IAC7D,qEAAqE;IACrE,oEAAoE;IACpE,wEAAwE;IACxE,oBAAoB;IACpB,MAAM,OAAO,GAAG,CAAC,CAAsB,EAAQ,EAAE;QAC/C,IAAI,CAAC,CAAC,CAAC,OAAO;YAAE,OAAO,CAAC,0BAA0B;QAClD,cAAc,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;IAEF,sEAAsE;IACtE,uEAAuE;IACvE,sEAAsE;IACtE,2EAA2E;IAC3E,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;QAC/C,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxC,cAAc,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;SAAM,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QACjD,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACzB,cAAc,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,YAAY;gBAAE,OAAO;YACzB,cAAc,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC;AA0CD,6EAA6E;AAC7E,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,sEAAsE;AACtE,MAAM,YAAY,GAAG,6BAA6B,CAAC;AAEnD,iFAAiF;AACjF,kFAAkF;AAClF,iFAAiF;AACjF,4DAA4D;AAC5D,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAC7D,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AAC9E,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AAElF,2EAA2E;AAC3E,sEAAsE;AACtE,MAAM,KAAK,GAAG,IAAI,OAAO,EAAW,CAAC;AACrC,SAAS,UAAU,CAAC,OAAgB;IAClC,OAAQ,OAA6D,CAAC,QAAQ,CAAC,CAAC;AAClF,CAAC;AACD,SAAS,aAAa,CAAC,OAAgB,EAAE,MAA8B;IACrE,MAAM,MAAM,GAAG,OAA4D,CAAC;IAC5E,IAAI,MAAM;QAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;;QACjC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AACD,SAAS,iBAAiB,CAAC,OAAgB,EAAE,KAAa,EAAE,KAAc;IACxE,MAAM,IAAI,GACR,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC;QACvC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;QAChD,SAAS,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC;AACD,SAAS,aAAa,CAAC,OAAgB,EAAE,KAAa;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;YAAS,CAAC;QACT,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,MAAM;YAAE,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtE,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AACD,SAAS,yBAAyB,CAAC,GAAa;IAC9C,MAAM,MAAM,GAAG,GAA0D,CAAC;IAC1E,IAAI,MAAM,CAAC,WAAW,CAAC;QAAE,OAAO;IAChC,MAAM,GAAG,GAAG,CAAC,KAAY,EAAE,KAAwB,EAAE,EAAE;QACrD,IAAI,KAAK,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC;YACnC,KAAK,CAAC,MAA4C,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC;QAC/E,CAAC;IACH,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE;QAC7B,IAAK,KAAoB,CAAC,WAAW;YAAE,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC,CAAC;IACF,GAAG,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACtD,GAAG,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClD,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3C,GAAG,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,WAAW,CAAC,GAAG,GAAG,EAAE;QACzB,GAAG,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACzD,GAAG,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACrD,GAAG,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9C,GAAG,CAAC,mBAAmB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,+EAA+E;AAC/E,MAAM,YAAY,GAAG,IAAI,OAAO,EAAW,CAAC;AAC5C,sFAAsF;AACtF,wFAAwF;AACxF,oFAAoF;AACpF,uFAAuF;AACvF,sFAAsF;AACtF,8DAA8D;AAC9D,IAAI,gBAAgB,GAA0B,IAAI,CAAC;AAEnD,kEAAkE;AAClE,wCAAwC;AACxC,0FAA0F;AAC1F,yDAAyD;AACzD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAuB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,QAAwB;IACnD,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAE5C,qEAAqE;IACrE,gBAAgB,GAAG,QAAQ,CAAC;IAC5B,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAc,mBAAmB,CAAC,CAAC;IAC/E,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACnC,gEAAgE;QAChE,iEAAiE;QACjE,6DAA6D;QAC7D,+DAA+D;QAC/D,YAAY;QACZ,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,kBAAkB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,gBAAgB,CAAc,4BAA4B,CAAC,CAAC;IAC5F,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,kBAAkB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC5C,IAAI,gBAAgB,KAAK,IAAI;QAAE,OAAO;IAEtC,MAAM,QAAQ,GAAG,gBAAgB,CAAC;IAElC,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAc,mBAAmB,CAAC,CAAC;IAC/E,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,2EAA2E;QAC3E,MAAM,YAAY,GAAG,sBAAsB,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC;QAC7D,kBAAkB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,gBAAgB,CAAc,4BAA4B,CAAC,CAAC;IAC5F,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,kBAAkB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,YAAY,GAAG,sBAAsB,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC;QAC7D,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,SAAS,sBAAsB,CAAC,EAAW;IACzC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,EAAE,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;IACxC,IAAI,UAAU,CAAC,EAAE,CAAC;QAAE,aAAa,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;;QACrD,EAAE,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,EAAW;IAC/B,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACrC,aAAa,CAAC,EAAE,EAAE,0BAA0B,CAAC,CAAC;QAC9C,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAAE,EAAE,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;IAC7D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC1C,MAAM,EAAE,CAAC;QACT,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,kBAAkB,CAAC,EAAW,EAAE,aAAqB;IAC5D,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;QAC/F,OAAO;IACT,CAAC;IACD,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO;IACjC,MAAM,MAAM,GAAG,EAAE,CAAC,aAAa,CAAC;IAChC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;IAChF,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,sCAAsC;IACtC,OAAO,CAAC,IAAI,CACV,iBAAiB,aAAa,4CAA4C;QACxE,0EAA0E;QAC1E,8CAA8C;QAC9C,gBAAgB,aAAa,sDAAsD;QACnF,yDAAyD,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,QAAwB,EACxB,OAAgB,EAChB,aAAqB,EACrB,IAA0B,EAC1B,UAA+B,EAAE;IAEjC,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO;IAEhC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IACtC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;YAC9F,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,iDAAiD,aAAa,MAAM;gBAClE,6DAA6D,CAChE,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,OAAgB,EAChB,GAAiB,EACjB,IAA0B,EAC1B,UAA+B,EAAE;IAEjC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;IACrB,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;QAC7B,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;YAC9F,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,+DAA+D;QAC/D,gEAAgE;QAChE,wBAAwB;QACxB,IAAI,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO;QAChC,uEAAuE;QACvE,mEAAmE;QACnE,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,yEAAyE;QACzE,4EAA4E;QAC5E,IAAI,CAAC,OAAO,CAAC,WAAW;YAAE,OAAO;QACjC,kEAAkE;QAClE,wEAAwE;QACxE,wDAAwD;QACxD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YACxC,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO;YAC5B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC5F,MAAM,IAAI,SAAS,CACjB,0BAA0B,GAAG,CAAC,QAAQ,CAAC,SAAS,0BAA0B,CAC3E,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAe,MAAM,CAAC;YAClC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/B,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACnB,OAAO,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;YAC7C,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,EAAE,CAAC;QACP,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC;IAC5D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,uBAAuB,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvE,6EAA6E;IAC7E,8DAA8D;IAC9D,8EAA8E;IAC9E,sEAAsE;IACtE,8EAA8E;IAC9E,sEAAsE;IACtE,IAAI,IAAI,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACtC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAmB,QAAQ,CAAC,IAAI,EAChC,YAAgC;IAEhC,MAAM,cAAc,GAAG,8CAA8C,CAAC;IACtE,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,cAAc,CAAC,CAAC,CAAC;IAClF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,KAAK,MAAM,MAAM,IAAI,UAAU;YAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,YAAY,GAAG,CAAC;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC;IACtE,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC;IACnF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAmB,CAAC;IAChD,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9D,IAAI,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAW,CAAC;IAClC,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxC,IAAI,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC;QACpC,OAAO,QAAQ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC;QACpF,IAAI,CAAC,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAU,MAAM,CAAC,CAAC;IAC1C,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,SAAS;QACpC,IAAI,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;QACrC,OAAO,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC;QAC5E,IAAI,QAAQ;YAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAAmB,CAAC;IAChD,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,SAAS;QACrC,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;IACpD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAsB,CAAC;IACzD,MAAM,eAAe,GAAc,EAAE,CAAC;IACtC,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,IAAI,QAAQ,GAAmB,MAAM,CAAC;QACtC,OAAO,QAAQ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC;QAC9E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,YAAY,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,CAAC;QACnE,IAAI,QAAQ,GAAmB,MAAM,CAAC;QACtC,IAAI,QAA6B,CAAC;QAClC,OAAO,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAC/C,IAAI,EAAE,KAAK,IAAI;gBAAE,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjD,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,KAAK,GAA+C,EAAE,CAAC;IAC7D,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC;QACjD,MAAM,aAAa,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAW,CAAC;QACrC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAW,CAAC;QAC1C,uEAAuE;QACvE,sDAAsD;QACtD,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7C,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;gBAChD,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CACjC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,KAAK,IAAI,CAChF,CAAC;YACF,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC9B,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QACD,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACxF,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3C,IAAI,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;;gBACvC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,uEAAuE;IACvE,iEAAiE;IACjE,KAAK,MAAM,MAAM,IAAI,eAAe;QAAE,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxE,KAAK,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;QACtC,MAAM,SAAS,GACb,CAAC,GAAG,CAAC,YAAY,CAAC,mCAAmC,CAAC;YACtD,GAAG,CAAC,YAAY,CAAC,mCAAmC,CAAC,KAAK,OAAO,CAAC;QACpE,MAAM,eAAe,GAAG,qBAAqB,CAAC,IAAI,CAChD,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAChF,CAAC;QACF,IACE,CAAC,GAAG,CAAC,YAAY,CAAC,mBAAmB,CAAC;YACtC,CAAC,eAAe;YAChB,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAEtF,SAAS;QACX,KAAK,MAAM,SAAS,IAAI,qBAAqB;YAAE,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QACvF,IAAI,SAAS;YAAE,aAAa,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;QAC1D,GAAG,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,qBAAqB,GAAG;IAC5B,iBAAiB;IACjB,0BAA0B;IAC1B,oBAAoB;IACpB,mBAAmB;IACnB,gBAAgB;CACR,CAAC;AAEX,SAAS,UAAU,CAAC,OAAgB;IAClC,OAAO,CACL,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAC5F,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,IAAa,EAAE,EAAW,EAAE,SAAiB;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,IAAI;QAAE,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;;QAC7C,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,SAAS,CAChB,OAAgB,EAChB,QAA8C;IAE9C,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;IACpE,MAAM,SAAS,GACb,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;IAC9F,IACE,UAAU,KAAK,UAAU;QACzB,SAAS,KAAK,QAAQ,CAAC,SAAS;QAChC,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,KAAK,QAAQ;QACvD,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC,KAAK,cAAc;QAC5D,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,KAAK,QAAQ,CAAC,KAAK;QACzD,GAAG,KAAK,IAAI,EACZ,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,uBAAuB,QAAQ,CAAC,SAAS,iCAAiC,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,CAAC,8CAA8C,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,SAAS,CAAC,4BAA4B,QAAQ,CAAC,SAAS,0BAA0B,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CAAC,oBAAoB,QAAQ,CAAC,SAAS,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAgB;IACzD,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC","sourcesContent":["// Hydration scheduling helper consumed by the hydration runtime (Sub 3).\n//\n// Sub 3 owns the hydration runtime that walks the DOM, finds elements\n// marked with `data-zfb-island`, and dispatches each one through this\n// helper to decide *when* to fire the actual hydrate() call. The helper\n// itself does not know how to hydrate — it only schedules the supplied\n// `fire` callback.\n//\n// The branching matches the `When` union exactly:\n// \"visible\" → IntersectionObserver, threshold 0.0, hydrate on first\n// intersection, then disconnect.\n// \"idle\" → requestIdleCallback if available, otherwise setTimeout(0).\n// \"media\" → matchMedia(target's data-media), hydrate when the query\n// first matches (now or on a later change event), then\n// remove the listener.\n// \"load\" → immediate, synchronous fire.\n//\n// Anything else is treated as \"load\" (with a console.warn in development).\n// The helper is environment-tolerant: callers can run it in jsdom /\n// happy-dom or bare Node, and the absence of `IntersectionObserver` /\n// `requestIdleCallback` / `matchMedia` is handled gracefully.\n\nimport { resolveWhen, type When } from \"./types.js\";\nimport { ROOT_KEY, type RootHandle } from \"./zudo-react/root.js\";\nimport { parseProps as parseOwnedProps } from \"./zudo-react/props-transport.js\";\n\n/**\n * Subset of the global object that this module touches. Cast once at the\n * module top so individual scheduler functions don't repeat the inline\n * widening.\n */\ntype SchedulerGlobal = typeof globalThis & {\n requestIdleCallback?: (\n cb: (deadline: { didTimeout: boolean; timeRemaining: () => number }) => void,\n options?: { timeout?: number },\n ) => number;\n cancelIdleCallback?: (handle: number) => void;\n IntersectionObserver?: typeof IntersectionObserver;\n matchMedia?: typeof matchMedia;\n};\n\nconst g = globalThis as SchedulerGlobal;\n\n/**\n * Internal variant of `scheduleHydrate` that also reports whether the fire\n * callback was invoked synchronously. Unexported — call sites in this module\n * use this to decide whether to register a `pendingCancels` entry.\n */\nfunction scheduleHydrateInternal(\n target: Element,\n when: When | string | undefined,\n fire: () => void,\n): { fired: boolean; cancel: () => void } {\n const resolved = resolveWhen(when);\n\n if (resolved === \"load\") {\n fire();\n return { fired: true, cancel: noop };\n }\n\n if (resolved === \"idle\") {\n return { fired: false, cancel: scheduleIdle(fire) };\n }\n\n if (resolved === \"media\") {\n return scheduleMedia(target, fire);\n }\n\n // \"visible\"\n return scheduleVisible(target, fire);\n}\n\n/**\n * Schedule a hydration `fire` callback for `target` according to `when`.\n *\n * Returns a `cancel` function that aborts the scheduling if it has not\n * fired yet. After firing, calling `cancel` is a no-op. If the helper\n * cannot find the relevant browser API (e.g. running in pure Node with no\n * polyfill), it falls back to firing synchronously so server-side smoke\n * tests still observe the call.\n */\nexport function scheduleHydrate(\n target: Element,\n when: When | string | undefined,\n fire: () => void,\n): () => void {\n return scheduleHydrateInternal(target, when, fire).cancel;\n}\n\nfunction noop(): void {\n // intentionally empty\n}\n\n/**\n * Build a one-shot gate around `fn`. The returned `run` invokes `fn`\n * exactly once provided `cancel` has not been called first; `cancel`\n * marks the gate as cancelled (later `run` invocations become no-ops)\n * and reports whether the gate had already fired.\n */\nfunction oneShot(fn: () => void): {\n run: () => void;\n cancel: () => boolean;\n} {\n let fired = false;\n let cancelled = false;\n return {\n run(): void {\n if (cancelled || fired) return;\n fired = true;\n fn();\n },\n cancel(): boolean {\n if (fired) return true;\n cancelled = true;\n return false;\n },\n };\n}\n\nfunction scheduleIdle(fire: () => void): () => void {\n const gate = oneShot(fire);\n\n if (typeof g.requestIdleCallback === \"function\") {\n const handle = g.requestIdleCallback(gate.run);\n return () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n if (typeof g.cancelIdleCallback === \"function\") g.cancelIdleCallback(handle);\n };\n }\n\n const handle = setTimeout(gate.run, 0);\n return () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n clearTimeout(handle);\n };\n}\n\nfunction scheduleVisible(\n target: Element,\n fire: () => void,\n): { fired: boolean; cancel: () => void } {\n const Observer = g.IntersectionObserver;\n\n // No IntersectionObserver (e.g. very old browsers, bare Node) — fail\n // open and hydrate immediately so the island is at least functional.\n if (typeof Observer !== \"function\") {\n fire();\n return { fired: true, cancel: noop };\n }\n\n const gate = oneShot(fire);\n const observer = new Observer(\n (entries, obs) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n obs.disconnect();\n gate.run();\n return;\n }\n }\n },\n { threshold: 0 },\n );\n\n observer.observe(target);\n\n return {\n fired: false,\n cancel: () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n observer.disconnect();\n },\n };\n}\n\nfunction scheduleMedia(target: Element, fire: () => void): { fired: boolean; cancel: () => void } {\n const query = target.getAttribute(\"data-media\");\n\n // No matchMedia API (e.g. bare Node, very old browser) or missing/empty\n // query — fail open and hydrate immediately so the island is at least\n // functional.\n if (typeof g.matchMedia !== \"function\" || !query) {\n fire();\n return { fired: true, cancel: noop };\n }\n\n const mql = g.matchMedia(query);\n\n // Already matches — fire synchronously (no pending listener needed).\n if (mql.matches) {\n fire();\n return { fired: true, cancel: noop };\n }\n\n const gate = oneShot(fire);\n\n let removeListener = noop;\n\n // Listen for the first change event where the query matches.\n // We do NOT use `{once:true}` because we must ignore un-match events\n // (e.g. viewport widens back above breakpoint) and only fire on the\n // first match event — `{once:true}` would consume any change, including\n // un-match changes.\n const handler = (e: MediaQueryListEvent): void => {\n if (!e.matches) return; // ignore un-match changes\n removeListener();\n gate.run();\n };\n\n // Modern browsers expose the EventTarget API on MediaQueryList; older\n // Safari (<14) only has the deprecated addListener/removeListener pair\n // and throws on addEventListener. Prefer modern, fall back to legacy,\n // and fail open when neither exists (mirrors the missing-matchMedia case).\n if (typeof mql.addEventListener === \"function\") {\n mql.addEventListener(\"change\", handler);\n removeListener = () => mql.removeEventListener(\"change\", handler);\n } else if (typeof mql.addListener === \"function\") {\n mql.addListener(handler);\n removeListener = () => mql.removeListener(handler);\n } else {\n fire();\n return { fired: true, cancel: noop };\n }\n\n return {\n fired: false,\n cancel: () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n removeListener();\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// mountIslands — DOM walk + dynamic-import dispatcher.\n//\n// `mountIslands` is the entry point the generated `islands-runtime-<hash>.js`\n// bundle calls at script load time. It walks the DOM for the two island\n// markers emitted by the server-side hydration step and the `<Island>`\n// JSX wrapper:\n//\n// 1. `[data-zfb-island]` — adopt server-rendered owned DOM.\n// 2. `[data-zfb-island-skip-ssr]` — mount over the fallback when scheduled.\n//\n// The generated shared bundle supplies strict identity and a RootHandle.\n// ---------------------------------------------------------------------------\n\n/**\n * The mount function supplied by a shared-bundle island module.\n *\n * `mode === \"hydrate\"` is used for SSR'd islands, `\"render\"` for\n * SSR-skip islands.\n */\ntype IslandMount = (\n props: Record<string, unknown>,\n element: Element,\n mode: \"hydrate\" | \"render\",\n) => RootHandle | null;\n\ninterface IslandModule {\n identity: { component: string; build: string };\n mount: IslandMount;\n}\n\n/**\n * Map of `componentName → island descriptor` baked into the runtime entry.\n *\n * Each manifest value is an inline module with `mount` or `default`.\n * The shared bundle imports island sources at build time.\n */\nexport type IslandManifestValue = IslandModule;\nexport type IslandManifest = Readonly<Record<string, IslandManifestValue>>;\n\n// data-zfb-transition-persist marker attribute — the client-router's persist\n// contract. Mirrored from client-router/swap-functions.ts: that package owns the\n// body swap (lifting persisted nodes into the incoming body), this package owns\n// island mount/unmount. Both must agree on the literal string. See the port\n// spec at packages/zfb-runtime/docs/client-router/port-spec.md §12.3.\nconst PERSIST_ATTR = \"data-zfb-transition-persist\";\n\n// Cross-package \"needs-remount\" flag set by client-router/swap-functions.ts on a\n// persisted island whose props changed across a body swap. Mirrored literal (same\n// cross-package contract as PERSIST_ATTR above — both packages must agree on the\n// string). Consumed by clearMountedForRemount(). See #1389.\nconst ISLAND_REMOUNT_ATTR = \"data-zfb-island-remount\";\n\n/**\n * Public observation marker; the symbol handle is the live-root guard.\n *\n * State table:\n * - initial/deferred/missing entry/failed mount: marker and handle absent;\n * - successful mount: both present;\n * - discarded root: disposal leaves DOM for the body swap, then clears both;\n * - unchanged island inside a retained persist boundary: handle and marker survive;\n * - changed island inside a retained boundary: metadata and remount flag are set,\n * then the post-swap scan disposes once and mounts in render mode;\n * - removed island inside a retained boundary: dispose and detach before swap;\n * - bundle re-import: dispose the old symbol handle before render mode replaces it.\n */\nexport const ISLAND_MOUNTED_ATTR = \"data-zfb-island-mounted\";\nconst COMPOSITION_KEY = Symbol.for(\"@takazudo/zfb/zudo-react/composition-v1\");\nconst TRACKER_KEY = Symbol.for(\"@takazudo/zfb/zudo-react/composition-tracker-v1\");\n\n// A fresh bundle instance replaces roots installed by a previous instance.\n// Ordinary repeat scans in the same instance keep their live handles.\nconst owned = new WeakSet<Element>();\nfunction rootHandle(element: Element): RootHandle | undefined {\n return (element as unknown as Record<symbol, RootHandle | undefined>)[ROOT_KEY];\n}\nfunction setRootHandle(element: Element, handle: RootHandle | undefined): void {\n const target = element as unknown as Record<symbol, RootHandle | undefined>;\n if (handle) target[ROOT_KEY] = handle;\n else delete target[ROOT_KEY];\n}\nfunction reportIslandError(element: Element, phase: string, error: unknown): void {\n const name =\n element.getAttribute(\"data-zfb-island\") ??\n element.getAttribute(\"data-zfb-island-skip-ssr\") ??\n \"unknown\";\n try {\n console.error(`[zfb] island \"${name}\" ${phase} failed`, error);\n } catch {\n // A broken reporter must not stop other roots.\n }\n}\nfunction disposeIsland(element: Element, phase: string): void {\n const handle = rootHandle(element);\n try {\n handle?.dispose();\n } catch (error) {\n reportIslandError(element, phase, error);\n } finally {\n if (rootHandle(element) === handle) setRootHandle(element, undefined);\n element.removeAttribute(ISLAND_MOUNTED_ATTR);\n }\n}\nfunction installCompositionTracker(doc: Document): void {\n const target = doc as unknown as Record<symbol, (() => void) | undefined>;\n if (target[TRACKER_KEY]) return;\n const set = (event: Event, value: \"active\" | \"idle\") => {\n if (event.target instanceof Element) {\n (event.target as unknown as Record<symbol, string>)[COMPOSITION_KEY] = value;\n }\n };\n const start = (event: Event) => set(event, \"active\");\n const end = (event: Event) => set(event, \"idle\");\n const input = (event: Event) => {\n if ((event as InputEvent).isComposing) set(event, \"active\");\n };\n doc.addEventListener(\"compositionstart\", start, true);\n doc.addEventListener(\"compositionend\", end, true);\n doc.addEventListener(\"input\", input, true);\n doc.addEventListener(\"blur\", end, true);\n target[TRACKER_KEY] = () => {\n doc.removeEventListener(\"compositionstart\", start, true);\n doc.removeEventListener(\"compositionend\", end, true);\n doc.removeEventListener(\"input\", input, true);\n doc.removeEventListener(\"blur\", end, true);\n delete target[TRACKER_KEY];\n };\n}\n\n// Elements for which the nested-island self-wrap warning has already been\n// emitted. Guards against repeated warn spam across re-walks (e.g. SPA swaps).\nconst warnedNested = new WeakSet<Element>();\n// Module-level captured manifest — set by the first `mountIslands` call and reused by\n// `mountNewIslands()` so the client-router does not need to know the manifest directly.\n// Named technical cause (W1B §12.1): the router lives in @takazudo/zfb-runtime; the\n// islands manifest lives in @takazudo/zfb. Passing the manifest through the swap event\n// would require widening the event API or threading manifest into router options. The\n// captured-manifest pattern keeps the package boundary clean.\nlet capturedManifest: IslandManifest | null = null;\n\n// Map of element → cancel-function for deferred-hydration islands\n// (data-when=\"idle\"|\"visible\"|\"media\").\n// Populated in scheduleMount; consulted on `zfb:before-swap` so deferred fires do not run\n// against orphan elements after a body swap. (W1B §12.5)\nconst pendingCancels = new Map<Element, () => void>();\n\n/**\n * Walk the DOM and mount every `[data-zfb-island]` / `[data-zfb-island-skip-ssr]`\n * element using `manifest`.\n *\n * No-op when `document` is undefined (SSR, edge runtime). Safe to call\n * multiple times: each element is mounted at most once thanks to the\n * symbol-handle guard.\n *\n * The manifest is captured at module level so `mountNewIslands()` can re-use\n * it after an SPA body swap without needing the caller to re-supply it.\n */\nexport function mountIslands(manifest: IslandManifest): void {\n if (typeof document === \"undefined\") return;\n\n // Capture the manifest for post-swap re-walks via mountNewIslands().\n capturedManifest = manifest;\n installCompositionTracker(document);\n\n const ssrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island]\");\n for (const el of Array.from(ssrIslands)) {\n const replacing = prepareMount(el);\n // Skip the empty-skeleton case left behind when the server-side\n // rewriter has not run yet (data-zfb-island=\"\" with no component\n // name). The hydration emit step is expected to fill this in\n // before the page reaches the browser; if it didn't, we cannot\n // dispatch.\n const name = el.getAttribute(\"data-zfb-island\");\n if (!name) continue;\n warnIfNestedIsland(el, name);\n scheduleMount(manifest, el, name, replacing ? \"render\" : \"hydrate\", { force: replacing });\n }\n\n const skipSsrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island-skip-ssr]\");\n for (const el of Array.from(skipSsrIslands)) {\n const replacing = prepareMount(el);\n const name = el.getAttribute(\"data-zfb-island-skip-ssr\");\n if (!name) continue;\n warnIfNestedIsland(el, name);\n scheduleMount(manifest, el, name, \"render\", { force: replacing });\n }\n}\n\n/**\n * Re-walk the current document body and mount any new island markers introduced\n * by an SPA body swap. Uses the manifest captured by the previous `mountIslands`\n * call — no manifest arg required.\n *\n * The caller (client-router `router.ts`) invokes this after `swap()` + `runScripts()`\n * and before dispatching `zfb:page-load`, per W1B §12.2 contract.\n *\n * No-op when called before `mountIslands` (capturedManifest is null) or when\n * `document` is undefined.\n */\nexport function mountNewIslands(): void {\n if (typeof document === \"undefined\") return;\n if (capturedManifest === null) return;\n\n const manifest = capturedManifest;\n\n const ssrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island]\");\n for (const el of Array.from(ssrIslands)) {\n const replacing = prepareMount(el);\n const name = el.getAttribute(\"data-zfb-island\");\n if (!name) continue;\n // The router marks changed persisted identity/props on the surviving node.\n const forceRemount = clearMountedForRemount(el) || replacing;\n warnIfNestedIsland(el, name);\n scheduleMount(manifest, el, name, forceRemount ? \"render\" : \"hydrate\", { force: forceRemount });\n }\n\n const skipSsrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island-skip-ssr]\");\n for (const el of Array.from(skipSsrIslands)) {\n const replacing = prepareMount(el);\n const name = el.getAttribute(\"data-zfb-island-skip-ssr\");\n if (!name) continue;\n warnIfNestedIsland(el, name);\n const forceRemount = clearMountedForRemount(el) || replacing;\n scheduleMount(manifest, el, name, \"render\", { force: forceRemount });\n }\n}\n\n/** Consume a persisted root's remount flag and dispose its previous resources. */\nfunction clearMountedForRemount(el: Element): boolean {\n if (!el.hasAttribute(ISLAND_REMOUNT_ATTR)) return false;\n el.removeAttribute(ISLAND_REMOUNT_ATTR);\n if (rootHandle(el)) disposeIsland(el, \"remount disposal\");\n else el.removeAttribute(ISLAND_MOUNTED_ATTR);\n return true;\n}\n\nfunction prepareMount(el: Element): boolean {\n let replacing = false;\n if (rootHandle(el) && !owned.has(el)) {\n disposeIsland(el, \"dev replacement disposal\");\n replacing = true;\n }\n if (!rootHandle(el)) el.removeAttribute(ISLAND_MOUNTED_ATTR);\n return replacing;\n}\n\n/**\n * Cancel deferred-hydration callbacks for all islands in the old body before a\n * swap. Prevents idle / visibility callbacks from running against orphan elements\n * after `swapBodyElement` removes them from the live document. (W1B §12.5)\n *\n * Call this on `zfb:before-swap` (or equivalently, in the router's swap sequence\n * before `swap()` mutates the DOM). Fire-and-forget; safe to call if nothing is\n * pending.\n */\nexport function cancelPendingIslands(): void {\n for (const [el, cancel] of pendingCancels) {\n cancel();\n pendingCancels.delete(el);\n }\n}\n\n/**\n * Warn (once per element, dev-only) when an island marker element is found\n * nested inside another island marker. Self-wrapping an island — emitting a\n * `data-zfb-island` or `data-zfb-island-skip-ssr` container *inside* another\n * island component's render output — mis-hydrates because the runtime will\n * try to mount both the outer and inner islands independently. The outer\n * island's framework instance owns the inner DOM, so a second `hydrate()` /\n * `render()` call against the inner element races with the outer render and\n * produces undefined behaviour.\n *\n * The fix is to author the inner component bare (no `<Island>` in its own\n * render output) and apply the `<Island when=\"...\">` wrapper at the call site.\n */\nfunction warnIfNestedIsland(el: Element, componentName: string): void {\n if (typeof process === \"undefined\" || !process.env || process.env[\"NODE_ENV\"] === \"production\") {\n return;\n }\n if (warnedNested.has(el)) return;\n const parent = el.parentElement;\n if (!parent || typeof parent.closest !== \"function\") return;\n const ancestor = parent.closest(\"[data-zfb-island],[data-zfb-island-skip-ssr]\");\n if (!ancestor) return;\n warnedNested.add(el);\n // eslint-disable-next-line no-console\n console.warn(\n `[zfb] Island \"${componentName}\" is nested inside another island marker. ` +\n `Self-wrapping an island mis-hydrates: the outer framework instance owns ` +\n `the inner DOM, causing a conflicting mount. ` +\n `Fix: author \"${componentName}\" bare (remove <Island> from its own render output) ` +\n `and apply <Island when=\"...\"> at the call site instead.`,\n );\n}\n\nfunction scheduleMount(\n manifest: IslandManifest,\n element: Element,\n componentName: string,\n mode: \"hydrate\" | \"render\",\n options: { force?: boolean } = {},\n): void {\n if (rootHandle(element)) return;\n\n const entry = manifest[componentName];\n if (entry == null) {\n if (typeof process !== \"undefined\" && process.env && process.env[\"NODE_ENV\"] !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[zfb] no island manifest entry for component \"${componentName}\" — ` +\n `the runtime manifest is out of sync with the rendered HTML.`,\n );\n }\n return;\n }\n\n fireInlineMount(element, entry, mode, options);\n}\n\n/**\n * Run the mount step for the inline-module manifest shape used by the\n * shared-bundle path. The module is already in memory (it was imported\n * into the bundle at build time), so there is no async window to\n * coordinate around — we just call `mount` / `default` directly,\n * gated by `data-when` semantics.\n */\nfunction fireInlineMount(\n element: Element,\n mod: IslandModule,\n mode: \"hydrate\" | \"render\",\n options: { force?: boolean } = {},\n): void {\n const fn = mod.mount;\n if (typeof fn !== \"function\") {\n if (typeof process !== \"undefined\" && process.env && process.env[\"NODE_ENV\"] !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\"[zfb] owned island manifest entry did not export mount()\");\n }\n return;\n }\n\n const fire = (): void => {\n // Re-check the guard in case `fire` is invoked from a deferred\n // scheduler (rIC/rAF/visibility) after a sibling caller already\n // mounted this element.\n if (rootHandle(element)) return;\n // When the deferred fire actually runs, the cancel handle is no longer\n // needed — remove it so pendingCancels doesn't hold stale entries.\n pendingCancels.delete(element);\n // Stale-mount race guard for deferred inline mounts: skip if the element\n // was detached (e.g. body swap) while the idle/visible callback was queued.\n if (!element.isConnected) return;\n // Lazy props parse: read and parse data-props only at mount time.\n // For deferred strategies (media, visible, idle) this avoids JSON.parse\n // work at boot time for islands that may never hydrate.\n try {\n const props = readProps(element, mod.identity);\n const result = fn(props, element, mode);\n if (result === null) return;\n if (!result || typeof result.dispose !== \"function\" || typeof result.unmount !== \"function\") {\n throw new TypeError(\n `ZR_ROOT_HANDLE: island ${mod.identity.component} returned no root handle`,\n );\n }\n const handle: RootHandle = result;\n setRootHandle(element, handle);\n owned.add(element);\n element.setAttribute(ISLAND_MOUNTED_ATTR, \"\");\n } catch (error) {\n element.removeAttribute(ISLAND_MOUNTED_ATTR);\n reportIslandError(element, \"mount\", error);\n }\n };\n\n if (options.force) {\n fire();\n return;\n }\n\n const when = element.getAttribute(\"data-when\") ?? undefined;\n const { fired, cancel } = scheduleHydrateInternal(element, when, fire);\n // Track deferred-hydration cancel handle so cancelPendingIslands() can abort\n // idle / visibility callbacks before a body swap. (W1B §12.5)\n // Only register when the scheduler did NOT fire synchronously — a synchronous\n // fire means the island is already handling its mount and there is no\n // deferred callback to cancel. Registering noop after a sync fire would leave\n // a stale pendingCancels entry for an already-handled element. (#743)\n if (when && when !== \"load\" && !fired) {\n pendingCancels.set(element, cancel);\n }\n}\n\n/**\n * Snapshot persistence and island pairings before changing any old-body node.\n * The router lifts only matched persist nodes whose incoming targets are not\n * nested inside another matched target. Their descendants survive that lift.\n */\nexport function unmountIslands(\n root: ParentNode = document.body,\n incomingBody?: ParentNode | null,\n): void {\n const islandSelector = \"[data-zfb-island],[data-zfb-island-skip-ssr]\";\n const oldIslands = Array.from(root.querySelectorAll<HTMLElement>(islandSelector));\n if (!incomingBody) {\n for (const island of oldIslands) disposeIsland(island, \"disposal\");\n return;\n }\n\n const persistSelector = `[${PERSIST_ATTR}]`;\n const oldPersist = Array.from(root.querySelectorAll(persistSelector));\n const incomingPersist = Array.from(incomingBody.querySelectorAll(persistSelector));\n const incomingById = new Map<string, Element>();\n for (const element of incomingPersist) {\n const id = element.getAttribute(PERSIST_ATTR);\n if (id !== null && !incomingById.has(id)) incomingById.set(id, element);\n }\n\n const targets = new Map<Element, Element>();\n for (const element of oldPersist) {\n const id = element.getAttribute(PERSIST_ATTR);\n const target = id === null ? undefined : incomingById.get(id);\n if (target) targets.set(element, target);\n }\n const matchedTargets = new Set(targets.values());\n const lifted = new Set<Element>();\n for (const [element, target] of targets) {\n let ancestor = target.parentElement;\n while (ancestor && !matchedTargets.has(ancestor)) ancestor = ancestor.parentElement;\n if (!ancestor) lifted.add(element);\n }\n const retained = new Set<Element>(lifted);\n for (const element of oldPersist) {\n if (!targets.has(element)) continue;\n let ancestor = element.parentElement;\n while (ancestor && !lifted.has(ancestor)) ancestor = ancestor.parentElement;\n if (ancestor) retained.add(element);\n }\n\n const boundaryById = new Map<string, Element>();\n for (const element of oldPersist) {\n if (!retained.has(element)) continue;\n const id = element.getAttribute(PERSIST_ATTR);\n if (id !== null && !boundaryById.has(id)) boundaryById.set(id, element);\n }\n const oldByBoundary = new Map<Element, Element[]>();\n const incomingByBoundary = new Map<Element, Element[]>();\n const withoutBoundary: Element[] = [];\n for (const island of oldIslands) {\n let ancestor: Element | null = island;\n while (ancestor && !retained.has(ancestor)) ancestor = ancestor.parentElement;\n if (!ancestor) {\n withoutBoundary.push(island);\n continue;\n }\n const group = oldByBoundary.get(ancestor) ?? [];\n group.push(island);\n oldByBoundary.set(ancestor, group);\n }\n for (const island of incomingBody.querySelectorAll(islandSelector)) {\n let ancestor: Element | null = island;\n let boundary: Element | undefined;\n while (ancestor && !boundary) {\n const id = ancestor.getAttribute(PERSIST_ATTR);\n if (id !== null) boundary = boundaryById.get(id);\n ancestor = ancestor.parentElement;\n }\n if (!boundary) continue;\n const group = incomingByBoundary.get(boundary) ?? [];\n group.push(island);\n incomingByBoundary.set(boundary, group);\n }\n\n const pairs: Array<{ old: Element; incoming: Element }> = [];\n const removed: Element[] = [];\n for (const [boundary, oldGroup] of oldByBoundary) {\n const incomingGroup = incomingByBoundary.get(boundary) ?? [];\n const pairedOld = new Set<Element>();\n const pairedIncoming = new Set<Element>();\n // A persisted island root always maps to its own target, even when the\n // target changes component or ceases to be an island.\n if (oldGroup.includes(boundary)) {\n pairedOld.add(boundary);\n const target = targets.get(boundary);\n if (target && incomingGroup.includes(target)) {\n pairs.push({ old: boundary, incoming: target });\n pairedIncoming.add(target);\n } else {\n removed.push(boundary);\n }\n }\n for (const old of oldGroup) {\n if (pairedOld.has(old)) continue;\n const name = islandName(old);\n const incoming = incomingGroup.find(\n (candidate) => !pairedIncoming.has(candidate) && islandName(candidate) === name,\n );\n if (!incoming) continue;\n pairs.push({ old, incoming });\n pairedOld.add(old);\n pairedIncoming.add(incoming);\n }\n const remainingIncoming = incomingGroup.filter((island) => !pairedIncoming.has(island));\n let next = 0;\n for (const old of oldGroup) {\n if (pairedOld.has(old)) continue;\n const incoming = remainingIncoming[next++];\n if (incoming) pairs.push({ old, incoming });\n else removed.push(old);\n }\n }\n\n // Apply only after all boundaries and pairings have been computed. An old\n // descendant removed from a lifted wrapper must be detached as well as\n // disposed, or the post-swap walk could hydrate its mutated DOM.\n for (const island of withoutBoundary) disposeIsland(island, \"disposal\");\n for (const { old, incoming } of pairs) {\n const copyProps =\n !old.hasAttribute(\"data-zfb-transition-persist-props\") ||\n old.getAttribute(\"data-zfb-transition-persist-props\") === \"false\";\n const identityChanged = ISLAND_IDENTITY_ATTRS.some(\n (attribute) => old.getAttribute(attribute) !== incoming.getAttribute(attribute),\n );\n if (\n !old.hasAttribute(ISLAND_REMOUNT_ATTR) &&\n !identityChanged &&\n (!copyProps || old.getAttribute(\"data-props\") === incoming.getAttribute(\"data-props\"))\n )\n continue;\n for (const attribute of ISLAND_IDENTITY_ATTRS) copyAttribute(incoming, old, attribute);\n if (copyProps) copyAttribute(incoming, old, \"data-props\");\n old.setAttribute(ISLAND_REMOUNT_ATTR, \"\");\n }\n for (const island of removed) {\n disposeIsland(island, \"disposal\");\n island.remove();\n }\n}\n\nconst ISLAND_IDENTITY_ATTRS = [\n \"data-zfb-island\",\n \"data-zfb-island-skip-ssr\",\n \"data-zfb-transport\",\n \"data-zfb-protocol\",\n \"data-zfb-build\",\n] as const;\n\nfunction islandName(element: Element): string | null {\n return (\n element.getAttribute(\"data-zfb-island\") ?? element.getAttribute(\"data-zfb-island-skip-ssr\")\n );\n}\n\nfunction copyAttribute(from: Element, to: Element, attribute: string): void {\n const value = from.getAttribute(attribute);\n if (value === null) to.removeAttribute(attribute);\n else to.setAttribute(attribute, value);\n}\n\nfunction readProps(\n element: Element,\n identity: { component: string; build: string },\n): Record<string, unknown> {\n const raw = element.getAttribute(\"data-props\");\n const hasHydrate = element.hasAttribute(\"data-zfb-island\");\n const hasSkipSsr = element.hasAttribute(\"data-zfb-island-skip-ssr\");\n const component =\n element.getAttribute(\"data-zfb-island\") ?? element.getAttribute(\"data-zfb-island-skip-ssr\");\n if (\n hasHydrate === hasSkipSsr ||\n component !== identity.component ||\n element.getAttribute(\"data-zfb-transport\") !== \"json/1\" ||\n element.getAttribute(\"data-zfb-protocol\") !== \"zudo-react/1\" ||\n element.getAttribute(\"data-zfb-build\") !== identity.build ||\n raw === null\n ) {\n throw new TypeError(`ZR_IDENTITY: island ${identity.component} has invalid transport identity`);\n }\n if (element.querySelector(\"[data-zfb-island],[data-zfb-island-skip-ssr]\")) {\n throw new TypeError(`ZR_NESTED_ISLAND: island ${identity.component} contains another island`);\n }\n try {\n return parseOwnedProps(raw);\n } catch (error) {\n throw new TypeError(`ZR_PROPS: island ${identity.component}: ${String(error)}`);\n }\n}\n\n/**\n * Test-only seam. Returns whether the given element has an entry in the\n * module-private `pendingCancels` Map. Used to assert that a synchronous\n * scheduler fire does not leave a stale entry behind. (#743)\n */\nexport function __hasPendingCancelForTests(element: Element): boolean {\n return pendingCancels.has(element);\n}\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["// Hydration scheduling helper consumed by the hydration runtime (Sub 3).\n//\n// Sub 3 owns the hydration runtime that walks the DOM, finds elements\n// marked with `data-zfb-island`, and dispatches each one through this\n// helper to decide *when* to fire the actual hydrate() call. The helper\n// itself does not know how to hydrate — it only schedules the supplied\n// `fire` callback.\n//\n// The branching matches the `When` union exactly:\n// \"visible\" → IntersectionObserver, threshold 0.0, hydrate on first\n// intersection, then disconnect.\n// \"idle\" → requestIdleCallback if available, otherwise setTimeout(0).\n// \"media\" → matchMedia(target's data-media), hydrate when the query\n// first matches (now or on a later change event), then\n// remove the listener.\n// \"load\" → immediate, synchronous fire.\n//\n// Anything else is treated as \"load\" (with a console.warn in development).\n// The helper is environment-tolerant: callers can run it in jsdom /\n// happy-dom or bare Node, and the absence of `IntersectionObserver` /\n// `requestIdleCallback` / `matchMedia` is handled gracefully.\n\nimport { resolveWhen, type When } from \"./types.js\";\nimport { ROOT_KEY, type RootHandle } from \"./zudo-react/root.js\";\nimport { parseProps as parseOwnedProps } from \"./zudo-react/props-transport.js\";\n\n/**\n * Subset of the global object that this module touches. Cast once at the\n * module top so individual scheduler functions don't repeat the inline\n * widening.\n */\ntype SchedulerGlobal = typeof globalThis & {\n requestIdleCallback?: (\n cb: (deadline: { didTimeout: boolean; timeRemaining: () => number }) => void,\n options?: { timeout?: number },\n ) => number;\n cancelIdleCallback?: (handle: number) => void;\n IntersectionObserver?: typeof IntersectionObserver;\n matchMedia?: typeof matchMedia;\n};\n\nconst g = globalThis as SchedulerGlobal;\n\n/**\n * Internal variant of `scheduleHydrate` that also reports whether the fire\n * callback was invoked synchronously. Unexported — call sites in this module\n * use this to decide whether to register a `pendingCancels` entry.\n */\nfunction scheduleHydrateInternal(\n target: Element,\n when: When | string | undefined,\n fire: () => void,\n): { fired: boolean; cancel: () => void } {\n const resolved = resolveWhen(when);\n\n if (resolved === \"load\") {\n fire();\n return { fired: true, cancel: noop };\n }\n\n if (resolved === \"idle\") {\n return { fired: false, cancel: scheduleIdle(fire) };\n }\n\n if (resolved === \"media\") {\n return scheduleMedia(target, fire);\n }\n\n // \"visible\"\n return scheduleVisible(target, fire);\n}\n\n/**\n * Schedule a hydration `fire` callback for `target` according to `when`.\n *\n * Returns a `cancel` function that aborts the scheduling if it has not\n * fired yet. After firing, calling `cancel` is a no-op. If the helper\n * cannot find the relevant browser API (e.g. running in pure Node with no\n * polyfill), it falls back to firing synchronously so server-side smoke\n * tests still observe the call.\n */\nexport function scheduleHydrate(\n target: Element,\n when: When | string | undefined,\n fire: () => void,\n): () => void {\n return scheduleHydrateInternal(target, when, fire).cancel;\n}\n\nfunction noop(): void {\n // intentionally empty\n}\n\n/**\n * Build a one-shot gate around `fn`. The returned `run` invokes `fn`\n * exactly once provided `cancel` has not been called first; `cancel`\n * marks the gate as cancelled (later `run` invocations become no-ops)\n * and reports whether the gate had already fired.\n */\nfunction oneShot(fn: () => void): {\n run: () => void;\n cancel: () => boolean;\n} {\n let fired = false;\n let cancelled = false;\n return {\n run(): void {\n if (cancelled || fired) return;\n fired = true;\n fn();\n },\n cancel(): boolean {\n if (fired) return true;\n cancelled = true;\n return false;\n },\n };\n}\n\nfunction scheduleIdle(fire: () => void): () => void {\n const gate = oneShot(fire);\n\n if (typeof g.requestIdleCallback === \"function\") {\n const handle = g.requestIdleCallback(gate.run);\n return () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n if (typeof g.cancelIdleCallback === \"function\") g.cancelIdleCallback(handle);\n };\n }\n\n const handle = setTimeout(gate.run, 0);\n return () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n clearTimeout(handle);\n };\n}\n\nfunction scheduleVisible(\n target: Element,\n fire: () => void,\n): { fired: boolean; cancel: () => void } {\n const Observer = g.IntersectionObserver;\n\n // No IntersectionObserver (e.g. very old browsers, bare Node) — fail\n // open and hydrate immediately so the island is at least functional.\n if (typeof Observer !== \"function\") {\n fire();\n return { fired: true, cancel: noop };\n }\n\n const gate = oneShot(fire);\n const observer = new Observer(\n (entries, obs) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n obs.disconnect();\n gate.run();\n return;\n }\n }\n },\n { threshold: 0 },\n );\n\n observer.observe(target);\n\n return {\n fired: false,\n cancel: () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n observer.disconnect();\n },\n };\n}\n\nfunction scheduleMedia(target: Element, fire: () => void): { fired: boolean; cancel: () => void } {\n const query = target.getAttribute(\"data-media\");\n\n // No matchMedia API (e.g. bare Node, very old browser) or missing/empty\n // query — fail open and hydrate immediately so the island is at least\n // functional.\n if (typeof g.matchMedia !== \"function\" || !query) {\n fire();\n return { fired: true, cancel: noop };\n }\n\n const mql = g.matchMedia(query);\n\n // Already matches — fire synchronously (no pending listener needed).\n if (mql.matches) {\n fire();\n return { fired: true, cancel: noop };\n }\n\n const gate = oneShot(fire);\n\n let removeListener = noop;\n\n // Listen for the first change event where the query matches.\n // We do NOT use `{once:true}` because we must ignore un-match events\n // (e.g. viewport widens back above breakpoint) and only fire on the\n // first match event — `{once:true}` would consume any change, including\n // un-match changes.\n const handler = (e: MediaQueryListEvent): void => {\n if (!e.matches) return; // ignore un-match changes\n removeListener();\n gate.run();\n };\n\n // Modern browsers expose the EventTarget API on MediaQueryList; older\n // Safari (<14) only has the deprecated addListener/removeListener pair\n // and throws on addEventListener. Prefer modern, fall back to legacy,\n // and fail open when neither exists (mirrors the missing-matchMedia case).\n if (typeof mql.addEventListener === \"function\") {\n mql.addEventListener(\"change\", handler);\n removeListener = () => mql.removeEventListener(\"change\", handler);\n } else if (typeof mql.addListener === \"function\") {\n mql.addListener(handler);\n removeListener = () => mql.removeListener(handler);\n } else {\n fire();\n return { fired: true, cancel: noop };\n }\n\n return {\n fired: false,\n cancel: () => {\n const alreadyFired = gate.cancel();\n if (alreadyFired) return;\n removeListener();\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// mountIslands — DOM walk + dynamic-import dispatcher.\n//\n// `mountIslands` is the entry point the generated `islands-runtime-<hash>.js`\n// bundle calls at script load time. It walks the DOM for the two island\n// markers emitted by the server-side hydration step and the `<Island>`\n// JSX wrapper:\n//\n// 1. `[data-zfb-island]` — adopt server-rendered owned DOM.\n// 2. `[data-zfb-island-skip-ssr]` — mount over the fallback when scheduled.\n//\n// The generated shared bundle supplies strict identity and a RootHandle.\n// ---------------------------------------------------------------------------\n\n/**\n * The mount function supplied by a shared-bundle island module.\n *\n * `mode === \"hydrate\"` is used for SSR'd islands, `\"render\"` for\n * SSR-skip islands.\n */\ntype IslandMount = (\n props: Record<string, unknown>,\n element: Element,\n mode: \"hydrate\" | \"render\",\n) => RootHandle | null;\n\ninterface IslandModule {\n identity: { component: string; build: string };\n mount: IslandMount;\n}\n\n/**\n * Map of `componentName → island descriptor` baked into the runtime entry.\n *\n * Each manifest value is an inline module with `mount` or `default`.\n * The shared bundle imports island sources at build time.\n */\nexport type IslandManifestValue = IslandModule;\nexport type IslandManifest = Readonly<Record<string, IslandManifestValue>>;\n\n// data-zfb-transition-persist marker attribute — the client-router's persist\n// contract. Mirrored from client-router/swap-functions.ts: that package owns the\n// body swap (lifting persisted nodes into the incoming body), this package owns\n// island mount/unmount. Both must agree on the literal string. See the port\n// spec at packages/zfb-runtime/docs/client-router/port-spec.md §12.3.\nconst PERSIST_ATTR = \"data-zfb-transition-persist\";\n\n// Cross-package \"needs-remount\" flag set by client-router/swap-functions.ts on a\n// persisted island whose props changed across a body swap. Mirrored literal (same\n// cross-package contract as PERSIST_ATTR above — both packages must agree on the\n// string). Consumed by clearMountedForRemount(). See #1389.\nconst ISLAND_REMOUNT_ATTR = \"data-zfb-island-remount\";\n\n/**\n * Public observation marker; the symbol handle is the live-root guard.\n *\n * State table:\n * - initial/deferred/missing entry/failed mount: marker and handle absent;\n * - successful mount: both present;\n * - discarded root: disposal leaves DOM for the body swap, then clears both;\n * - unchanged island inside a retained persist boundary: handle and marker survive;\n * - changed island inside a retained boundary: metadata and remount flag are set,\n * then the post-swap scan disposes once and mounts in render mode;\n * - removed island inside a retained boundary: dispose and detach before swap;\n * - bundle re-import: dispose the old symbol handle before render mode replaces it.\n */\nexport const ISLAND_MOUNTED_ATTR = \"data-zfb-island-mounted\";\nconst COMPOSITION_KEY = Symbol.for(\"@takazudo/zfb/zudo-react/composition-v1\");\nconst TRACKER_KEY = Symbol.for(\"@takazudo/zfb/zudo-react/composition-tracker-v1\");\n\n// A fresh bundle instance replaces roots installed by a previous instance.\n// Ordinary repeat scans in the same instance keep their live handles.\nconst owned = new WeakSet<Element>();\nfunction rootHandle(element: Element): RootHandle | undefined {\n return (element as unknown as Record<symbol, RootHandle | undefined>)[ROOT_KEY];\n}\nfunction setRootHandle(element: Element, handle: RootHandle | undefined): void {\n const target = element as unknown as Record<symbol, RootHandle | undefined>;\n if (handle) target[ROOT_KEY] = handle;\n else delete target[ROOT_KEY];\n}\nfunction reportIslandError(element: Element, phase: string, error: unknown): void {\n const name =\n element.getAttribute(\"data-zfb-island\") ??\n element.getAttribute(\"data-zfb-island-skip-ssr\") ??\n \"unknown\";\n try {\n console.error(`[zfb] island \"${name}\" ${phase} failed`, error);\n } catch {\n // A broken reporter must not stop other roots.\n }\n}\nfunction disposeIsland(element: Element, phase: string): void {\n const handle = rootHandle(element);\n try {\n handle?.dispose();\n } catch (error) {\n reportIslandError(element, phase, error);\n } finally {\n if (rootHandle(element) === handle) setRootHandle(element, undefined);\n element.removeAttribute(ISLAND_MOUNTED_ATTR);\n }\n}\nfunction installCompositionTracker(doc: Document): void {\n const target = doc as unknown as Record<symbol, (() => void) | undefined>;\n if (target[TRACKER_KEY]) return;\n const set = (event: Event, value: \"active\" | \"idle\") => {\n if (event.target instanceof Element) {\n (event.target as unknown as Record<symbol, string>)[COMPOSITION_KEY] = value;\n }\n };\n const start = (event: Event) => set(event, \"active\");\n const end = (event: Event) => set(event, \"idle\");\n const input = (event: Event) => {\n if ((event as InputEvent).isComposing) set(event, \"active\");\n };\n doc.addEventListener(\"compositionstart\", start, true);\n doc.addEventListener(\"compositionend\", end, true);\n doc.addEventListener(\"input\", input, true);\n doc.addEventListener(\"blur\", end, true);\n target[TRACKER_KEY] = () => {\n doc.removeEventListener(\"compositionstart\", start, true);\n doc.removeEventListener(\"compositionend\", end, true);\n doc.removeEventListener(\"input\", input, true);\n doc.removeEventListener(\"blur\", end, true);\n delete target[TRACKER_KEY];\n };\n}\n\n// Elements for which the nested-island self-wrap warning has already been\n// emitted. Guards against repeated warn spam across re-walks (e.g. SPA swaps).\nconst warnedNested = new WeakSet<Element>();\n// Module-level captured manifest — set by the first `mountIslands` call and reused by\n// `mountNewIslands()` so the client-router does not need to know the manifest directly.\n// Named technical cause (W1B §12.1): the router lives in @takazudo/zfb-runtime; the\n// islands manifest lives in @takazudo/zfb. Passing the manifest through the swap event\n// would require widening the event API or threading manifest into router options. The\n// captured-manifest pattern keeps the package boundary clean.\nlet capturedManifest: IslandManifest | null = null;\n\n// Map of element → cancel-function for deferred-hydration islands\n// (data-when=\"idle\"|\"visible\"|\"media\").\n// Populated in scheduleMount; consulted on `zfb:before-swap` so deferred fires do not run\n// against orphan elements after a body swap. (W1B §12.5)\nconst pendingCancels = new Map<Element, () => void>();\n\n/**\n * Walk the DOM and mount every `[data-zfb-island]` / `[data-zfb-island-skip-ssr]`\n * element using `manifest`.\n *\n * No-op when `document` is undefined (SSR, edge runtime). Safe to call\n * multiple times: each element is mounted at most once thanks to the\n * symbol-handle guard.\n *\n * The manifest is captured at module level so `mountNewIslands()` can re-use\n * it after an SPA body swap without needing the caller to re-supply it.\n */\nexport function mountIslands(manifest: IslandManifest): void {\n if (typeof document === \"undefined\") return;\n\n // Capture the manifest for post-swap re-walks via mountNewIslands().\n capturedManifest = manifest;\n installCompositionTracker(document);\n\n const ssrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island]\");\n for (const el of Array.from(ssrIslands)) {\n const replacing = prepareMount(el);\n // Skip the empty-skeleton case left behind when the server-side\n // rewriter has not run yet (data-zfb-island=\"\" with no component\n // name). The hydration emit step is expected to fill this in\n // before the page reaches the browser; if it didn't, we cannot\n // dispatch.\n const name = el.getAttribute(\"data-zfb-island\");\n if (!name) continue;\n warnIfNestedIsland(el, name);\n scheduleMount(manifest, el, name, replacing ? \"render\" : \"hydrate\", { force: replacing });\n }\n\n const skipSsrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island-skip-ssr]\");\n for (const el of Array.from(skipSsrIslands)) {\n const replacing = prepareMount(el);\n const name = el.getAttribute(\"data-zfb-island-skip-ssr\");\n if (!name) continue;\n warnIfNestedIsland(el, name);\n scheduleMount(manifest, el, name, \"render\", { force: replacing });\n }\n}\n\n/**\n * Re-walk the current document body and mount any new island markers introduced\n * by an SPA body swap. Uses the manifest captured by the previous `mountIslands`\n * call — no manifest arg required.\n *\n * The caller (client-router `router.ts`) invokes this after `swap()` + `runScripts()`\n * and before dispatching `zfb:page-load`, per W1B §12.2 contract.\n *\n * No-op when called before `mountIslands` (capturedManifest is null) or when\n * `document` is undefined.\n */\nexport function mountNewIslands(): void {\n if (typeof document === \"undefined\") return;\n if (capturedManifest === null) return;\n\n const manifest = capturedManifest;\n\n const ssrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island]\");\n for (const el of Array.from(ssrIslands)) {\n const replacing = prepareMount(el);\n const name = el.getAttribute(\"data-zfb-island\");\n if (!name) continue;\n // The router marks changed persisted identity/props on the surviving node.\n const forceRemount = clearMountedForRemount(el) || replacing;\n warnIfNestedIsland(el, name);\n scheduleMount(manifest, el, name, forceRemount ? \"render\" : \"hydrate\", { force: forceRemount });\n }\n\n const skipSsrIslands = document.querySelectorAll<HTMLElement>(\"[data-zfb-island-skip-ssr]\");\n for (const el of Array.from(skipSsrIslands)) {\n const replacing = prepareMount(el);\n const name = el.getAttribute(\"data-zfb-island-skip-ssr\");\n if (!name) continue;\n warnIfNestedIsland(el, name);\n const forceRemount = clearMountedForRemount(el) || replacing;\n scheduleMount(manifest, el, name, \"render\", { force: forceRemount });\n }\n}\n\n/** Consume a persisted root's remount flag and dispose its previous resources. */\nfunction clearMountedForRemount(el: Element): boolean {\n if (!el.hasAttribute(ISLAND_REMOUNT_ATTR)) return false;\n el.removeAttribute(ISLAND_REMOUNT_ATTR);\n if (rootHandle(el)) disposeIsland(el, \"remount disposal\");\n else el.removeAttribute(ISLAND_MOUNTED_ATTR);\n return true;\n}\n\nfunction prepareMount(el: Element): boolean {\n let replacing = false;\n if (rootHandle(el) && !owned.has(el)) {\n disposeIsland(el, \"dev replacement disposal\");\n replacing = true;\n }\n if (!rootHandle(el)) el.removeAttribute(ISLAND_MOUNTED_ATTR);\n return replacing;\n}\n\n/**\n * Cancel deferred-hydration callbacks for all islands in the old body before a\n * swap. Prevents idle / visibility callbacks from running against orphan elements\n * after `swapBodyElement` removes them from the live document. (W1B §12.5)\n *\n * Call this on `zfb:before-swap` (or equivalently, in the router's swap sequence\n * before `swap()` mutates the DOM). Fire-and-forget; safe to call if nothing is\n * pending.\n */\nexport function cancelPendingIslands(): void {\n for (const [el, cancel] of pendingCancels) {\n cancel();\n pendingCancels.delete(el);\n }\n}\n\n/**\n * Warn (once per element, dev-only) when an island marker element is found\n * nested inside another island marker. Self-wrapping an island — emitting a\n * `data-zfb-island` or `data-zfb-island-skip-ssr` container *inside* another\n * island component's render output — mis-hydrates because the runtime will\n * try to mount both the outer and inner islands independently. The outer\n * island's framework instance owns the inner DOM, so a second `hydrate()` /\n * `render()` call against the inner element races with the outer render and\n * produces undefined behaviour.\n *\n * The fix is to author the inner component bare (no `<Island>` in its own\n * render output) and apply the `<Island when=\"...\">` wrapper at the call site.\n */\nfunction warnIfNestedIsland(el: Element, componentName: string): void {\n if (typeof process === \"undefined\" || !process.env || process.env[\"NODE_ENV\"] === \"production\") {\n return;\n }\n if (warnedNested.has(el)) return;\n const parent = el.parentElement;\n if (!parent || typeof parent.closest !== \"function\") return;\n const ancestor = parent.closest(\"[data-zfb-island],[data-zfb-island-skip-ssr]\");\n if (!ancestor) return;\n warnedNested.add(el);\n // eslint-disable-next-line no-console\n console.warn(\n `[zfb] Island \"${componentName}\" is nested inside another island marker. ` +\n `Self-wrapping an island mis-hydrates: the outer framework instance owns ` +\n `the inner DOM, causing a conflicting mount. ` +\n `Fix: author \"${componentName}\" bare (remove <Island> from its own render output) ` +\n `and apply <Island when=\"...\"> at the call site instead.`,\n );\n}\n\nfunction scheduleMount(\n manifest: IslandManifest,\n element: Element,\n componentName: string,\n mode: \"hydrate\" | \"render\",\n options: { force?: boolean } = {},\n): void {\n if (rootHandle(element)) return;\n\n const entry = manifest[componentName];\n if (entry == null) {\n if (typeof process !== \"undefined\" && process.env && process.env[\"NODE_ENV\"] !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[zfb] no island manifest entry for component \"${componentName}\" — ` +\n `the runtime manifest is out of sync with the rendered HTML.`,\n );\n }\n return;\n }\n\n fireInlineMount(element, entry, mode, options);\n}\n\n/**\n * Run the mount step for the inline-module manifest shape used by the\n * shared-bundle path. The module is already in memory (it was imported\n * into the bundle at build time), so there is no async window to\n * coordinate around — we just call `mount` / `default` directly,\n * gated by `data-when` semantics.\n */\nfunction fireInlineMount(\n element: Element,\n mod: IslandModule,\n mode: \"hydrate\" | \"render\",\n options: { force?: boolean } = {},\n): void {\n const fn = mod.mount;\n if (typeof fn !== \"function\") {\n if (typeof process !== \"undefined\" && process.env && process.env[\"NODE_ENV\"] !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\"[zfb] owned island manifest entry did not export mount()\");\n }\n return;\n }\n\n const fire = (): void => {\n // Re-check the guard in case `fire` is invoked from a deferred\n // scheduler (rIC/rAF/visibility) after a sibling caller already\n // mounted this element.\n if (rootHandle(element)) return;\n // When the deferred fire actually runs, the cancel handle is no longer\n // needed — remove it so pendingCancels doesn't hold stale entries.\n pendingCancels.delete(element);\n // Stale-mount race guard for deferred inline mounts: skip if the element\n // was detached (e.g. body swap) while the idle/visible callback was queued.\n if (!element.isConnected) return;\n // Lazy props parse: read and parse data-props only at mount time.\n // For deferred strategies (media, visible, idle) this avoids JSON.parse\n // work at boot time for islands that may never hydrate.\n try {\n const props = readProps(element, mod.identity);\n const result = fn(props, element, mode);\n if (result === null) return;\n if (!result || typeof result.dispose !== \"function\" || typeof result.unmount !== \"function\") {\n throw new TypeError(\n `ZR_ROOT_HANDLE: island ${mod.identity.component} returned no root handle`,\n );\n }\n const handle: RootHandle = result;\n setRootHandle(element, handle);\n owned.add(element);\n element.setAttribute(ISLAND_MOUNTED_ATTR, \"\");\n } catch (error) {\n element.removeAttribute(ISLAND_MOUNTED_ATTR);\n reportIslandError(element, \"mount\", error);\n }\n };\n\n if (options.force) {\n fire();\n return;\n }\n\n const when = element.getAttribute(\"data-when\") ?? undefined;\n const { fired, cancel } = scheduleHydrateInternal(element, when, fire);\n // Track deferred-hydration cancel handle so cancelPendingIslands() can abort\n // idle / visibility callbacks before a body swap. (W1B §12.5)\n // Only register when the scheduler did NOT fire synchronously — a synchronous\n // fire means the island is already handling its mount and there is no\n // deferred callback to cancel. Registering noop after a sync fire would leave\n // a stale pendingCancels entry for an already-handled element. (#743)\n if (when && when !== \"load\" && !fired) {\n pendingCancels.set(element, cancel);\n }\n}\n\n/**\n * Snapshot persistence and island pairings before changing any old-body node.\n * The router lifts only matched persist nodes whose incoming targets are not\n * nested inside another matched target. Their descendants survive that lift.\n */\nexport function unmountIslands(\n root: ParentNode = document.body,\n incomingBody?: ParentNode | null,\n): void {\n const islandSelector = \"[data-zfb-island],[data-zfb-island-skip-ssr]\";\n const oldIslands = Array.from(root.querySelectorAll<HTMLElement>(islandSelector));\n if (!incomingBody) {\n for (const island of oldIslands) disposeIsland(island, \"disposal\");\n return;\n }\n\n const persistSelector = `[${PERSIST_ATTR}]`;\n const oldPersist = Array.from(root.querySelectorAll(persistSelector));\n const incomingPersist = Array.from(incomingBody.querySelectorAll(persistSelector));\n const incomingById = new Map<string, Element>();\n for (const element of incomingPersist) {\n const id = element.getAttribute(PERSIST_ATTR);\n if (id !== null && !incomingById.has(id)) incomingById.set(id, element);\n }\n\n const targets = new Map<Element, Element>();\n for (const element of oldPersist) {\n const id = element.getAttribute(PERSIST_ATTR);\n const target = id === null ? undefined : incomingById.get(id);\n if (target) targets.set(element, target);\n }\n const matchedTargets = new Set(targets.values());\n const lifted = new Set<Element>();\n for (const [element, target] of targets) {\n let ancestor = target.parentElement;\n while (ancestor && !matchedTargets.has(ancestor)) ancestor = ancestor.parentElement;\n if (!ancestor) lifted.add(element);\n }\n const retained = new Set<Element>(lifted);\n for (const element of oldPersist) {\n if (!targets.has(element)) continue;\n let ancestor = element.parentElement;\n while (ancestor && !lifted.has(ancestor)) ancestor = ancestor.parentElement;\n if (ancestor) retained.add(element);\n }\n\n const boundaryById = new Map<string, Element>();\n for (const element of oldPersist) {\n if (!retained.has(element)) continue;\n const id = element.getAttribute(PERSIST_ATTR);\n if (id !== null && !boundaryById.has(id)) boundaryById.set(id, element);\n }\n const oldByBoundary = new Map<Element, Element[]>();\n const incomingByBoundary = new Map<Element, Element[]>();\n const withoutBoundary: Element[] = [];\n for (const island of oldIslands) {\n let ancestor: Element | null = island;\n while (ancestor && !retained.has(ancestor)) ancestor = ancestor.parentElement;\n if (!ancestor) {\n withoutBoundary.push(island);\n continue;\n }\n const group = oldByBoundary.get(ancestor) ?? [];\n group.push(island);\n oldByBoundary.set(ancestor, group);\n }\n for (const island of incomingBody.querySelectorAll(islandSelector)) {\n let ancestor: Element | null = island;\n let boundary: Element | undefined;\n while (ancestor && !boundary) {\n const id = ancestor.getAttribute(PERSIST_ATTR);\n if (id !== null) boundary = boundaryById.get(id);\n ancestor = ancestor.parentElement;\n }\n if (!boundary) continue;\n const group = incomingByBoundary.get(boundary) ?? [];\n group.push(island);\n incomingByBoundary.set(boundary, group);\n }\n\n const pairs: Array<{ old: Element; incoming: Element }> = [];\n const removed: Element[] = [];\n for (const [boundary, oldGroup] of oldByBoundary) {\n const incomingGroup = incomingByBoundary.get(boundary) ?? [];\n const pairedOld = new Set<Element>();\n const pairedIncoming = new Set<Element>();\n // A persisted island root always maps to its own target, even when the\n // target changes component or ceases to be an island.\n if (oldGroup.includes(boundary)) {\n pairedOld.add(boundary);\n const target = targets.get(boundary);\n if (target && incomingGroup.includes(target)) {\n pairs.push({ old: boundary, incoming: target });\n pairedIncoming.add(target);\n } else {\n removed.push(boundary);\n }\n }\n for (const old of oldGroup) {\n if (pairedOld.has(old)) continue;\n const name = islandName(old);\n const incoming = incomingGroup.find(\n (candidate) => !pairedIncoming.has(candidate) && islandName(candidate) === name,\n );\n if (!incoming) continue;\n pairs.push({ old, incoming });\n pairedOld.add(old);\n pairedIncoming.add(incoming);\n }\n const remainingIncoming = incomingGroup.filter((island) => !pairedIncoming.has(island));\n let next = 0;\n for (const old of oldGroup) {\n if (pairedOld.has(old)) continue;\n const incoming = remainingIncoming[next++];\n if (incoming) pairs.push({ old, incoming });\n else removed.push(old);\n }\n }\n\n // Apply only after all boundaries and pairings have been computed. An old\n // descendant removed from a lifted wrapper must be detached as well as\n // disposed, or the post-swap walk could hydrate its mutated DOM.\n for (const island of withoutBoundary) disposeIsland(island, \"disposal\");\n for (const { old, incoming } of pairs) {\n const copyProps =\n !old.hasAttribute(\"data-zfb-transition-persist-props\") ||\n old.getAttribute(\"data-zfb-transition-persist-props\") === \"false\";\n const identityChanged = ISLAND_IDENTITY_ATTRS.some(\n (attribute) => old.getAttribute(attribute) !== incoming.getAttribute(attribute),\n );\n if (\n !old.hasAttribute(ISLAND_REMOUNT_ATTR) &&\n !identityChanged &&\n (!copyProps || old.getAttribute(\"data-props\") === incoming.getAttribute(\"data-props\"))\n )\n continue;\n for (const attribute of ISLAND_IDENTITY_ATTRS) copyAttribute(incoming, old, attribute);\n if (copyProps) copyAttribute(incoming, old, \"data-props\");\n old.setAttribute(ISLAND_REMOUNT_ATTR, \"\");\n }\n for (const island of removed) {\n disposeIsland(island, \"disposal\");\n island.remove();\n }\n}\n\nconst ISLAND_IDENTITY_ATTRS = [\n \"data-zfb-island\",\n \"data-zfb-island-skip-ssr\",\n \"data-zfb-transport\",\n \"data-zfb-protocol\",\n \"data-zfb-build\",\n] as const;\n\nfunction islandName(element: Element): string | null {\n return (\n element.getAttribute(\"data-zfb-island\") ?? element.getAttribute(\"data-zfb-island-skip-ssr\")\n );\n}\n\nfunction copyAttribute(from: Element, to: Element, attribute: string): void {\n const value = from.getAttribute(attribute);\n if (value === null) to.removeAttribute(attribute);\n else to.setAttribute(attribute, value);\n}\n\nfunction readProps(\n element: Element,\n identity: { component: string; build: string },\n): Record<string, unknown> {\n const raw = element.getAttribute(\"data-props\");\n const hasHydrate = element.hasAttribute(\"data-zfb-island\");\n const hasSkipSsr = element.hasAttribute(\"data-zfb-island-skip-ssr\");\n const component =\n element.getAttribute(\"data-zfb-island\") ?? element.getAttribute(\"data-zfb-island-skip-ssr\");\n if (\n hasHydrate === hasSkipSsr ||\n component !== identity.component ||\n element.getAttribute(\"data-zfb-transport\") !== \"json/1\" ||\n element.getAttribute(\"data-zfb-protocol\") !== \"zudo-react/1\" ||\n element.getAttribute(\"data-zfb-build\") !== identity.build ||\n raw === null\n ) {\n throw new TypeError(`ZR_IDENTITY: island ${identity.component} has invalid transport identity`);\n }\n if (element.querySelector(\"[data-zfb-island],[data-zfb-island-skip-ssr]\")) {\n throw new TypeError(`ZR_NESTED_ISLAND: island ${identity.component} contains another island`);\n }\n try {\n return parseOwnedProps(raw);\n } catch (error) {\n throw new TypeError(`ZR_PROPS: island ${identity.component}: ${String(error)}`);\n }\n}\n\n/**\n * Test-only seam. Returns whether the given element has an entry in the\n * module-private `pendingCancels` Map. Used to assert that a synchronous\n * scheduler fire does not leave a stale entry behind. (#743)\n */\nexport function __hasPendingCancelForTests(element: Element): boolean {\n return pendingCancels.has(element);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"slugify.js","sourceRoot":"","sources":["../src/slugify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8EAA8E;AAC9E,qDAAqD;AACrD,8EAA8E;AAE9E,wDAAwD;AACxD,SAAS,IAAI,CAAC,EAAU;IACtB,qFAAqF;IACrF,OAAO,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,EAAU;IAC5B,IAAI,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,CACL,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,IAAI;QACX,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG;QACV,EAAE,KAAK,GAAG,CACX,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,EAAU;IAC9B,OAAO,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,YAAY,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,GAAG,IAAI,GAAG,CAAC;gBACX,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,+DAA+D;YAC/D,2BAA2B;YAC3B,GAAG,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxB,QAAQ,GAAG,KAAK,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E;;;;;;;GAOG;AACH,SAAS,QAAQ,CAAC,IAAyB,EAAE,IAAY;IACvD,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;IACrD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,aAAa;IACP,QAAQ,CAA0B;IAC3C,IAAI,CAAsB;IAClC,oFAAoF;IAC5E,KAAK,CAA0B;IAEvC,YAAY,WAAoC,MAAM;QACpD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAa,EAAE,IAAY;QAClC,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YAC7B,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,oBAAoB;QACpB,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QAE3B,oDAAoD;QACpD,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACjB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;CACF","sourcesContent":["/**\n * Heading-anchor slug utilities — a pure-TypeScript port of the Rust\n * `slugify` / `next_slug` / `SlugAllocator` in\n * `crates/zfb-content/src/plugins/heading_links.rs`.\n *\n * These functions produce the `id` attribute values that appear on\n * `<h2>`–`<h6>` elements in the rendered HTML. They are intentionally\n * **not** compatible with npm `github-slugger`: stripped punctuation\n * collapses to a `-` separator (`\"a,b\"` → `\"a-b\"`), and leading/trailing\n * whitespace / stripped chars emit nothing rather than a stray dash.\n *\n * ⚠️ These functions produce heading-anchor slugs (e.g. `\"hello-world\"`\n * for `<h2 id=\"hello-world\">`). They are **different** from\n * `_relPathToSlug` in `content.ts`, which converts a file-system relative\n * path into a URL slug for `CollectionEntry.slug`.\n *\n * Parity is enforced by the shared fixture at\n * `crates/zfb-content/tests/fixtures/slugify-parity.json`, consumed by\n * both a Rust integration test and the `slugify.test.ts` vitest suite.\n */\n\n// ---------------------------------------------------------------------------\n// Helpers — mirrors the Rust `is_stripped` predicate\n// ---------------------------------------------------------------------------\n\n/** Unicode General Category Cc (control characters). */\nfunction isCc(ch: string): boolean {\n // \\p{Cc} = general category \"Control\" (C0 + C1 blocks: U+0000–U+001F, U+007F–U+009F)\n return /^\\p{Cc}$/u.test(ch);\n}\n\n/**\n * Returns true when the character should be stripped (maps to a dash\n * separator in the output). Mirrors Rust's `is_stripped`:\n * - Unicode Cc control characters\n * - Explicit ASCII punctuation set: `! \" # $ % & ' ( ) * + , . / : ; < = > ? @ [ \\ ] ^ ` { | } ~`\n */\nfunction isStripped(ch: string): boolean {\n if (isCc(ch)) return true;\n return (\n ch === \"!\" ||\n ch === '\"' ||\n ch === \"#\" ||\n ch === \"$\" ||\n ch === \"%\" ||\n ch === \"&\" ||\n ch === \"'\" ||\n ch === \"(\" ||\n ch === \")\" ||\n ch === \"*\" ||\n ch === \"+\" ||\n ch === \",\" ||\n ch === \".\" ||\n ch === \"/\" ||\n ch === \":\" ||\n ch === \";\" ||\n ch === \"<\" ||\n ch === \"=\" ||\n ch === \">\" ||\n ch === \"?\" ||\n ch === \"@\" ||\n ch === \"[\" ||\n ch === \"\\\\\" ||\n ch === \"]\" ||\n ch === \"^\" ||\n ch === \"`\" ||\n ch === \"{\" ||\n ch === \"|\" ||\n ch === \"}\" ||\n ch === \"~\"\n );\n}\n\n/**\n * Returns true when `ch` is a Unicode whitespace character.\n *\n * Mirrors Rust `char::is_whitespace` which is `\\p{White_Space}/u` — NOT\n * the JS `\\s` class (`\\s` wrongly matches U+FEFF BYTE ORDER MARK and\n * misses U+0085 NEXT LINE).\n */\nfunction isWhitespace(ch: string): boolean {\n return /^\\p{White_Space}$/u.test(ch);\n}\n\n// ---------------------------------------------------------------------------\n// slugify\n// ---------------------------------------------------------------------------\n\n/**\n * Produce a heading-anchor slug from `input`, matching the Rust\n * `slugify()` in `crates/zfb-content/src/plugins/heading_links.rs`.\n *\n * Algorithm (per Unicode code point):\n * - whitespace or stripped punctuation → emit ONE `-` unless the last\n * emitted character was already a `-` (leading separators are skipped\n * because `lastDash` starts `true`).\n * - anything else → push `ch.toLowerCase()` (per-code-point, not\n * whole-string, to avoid Greek final-sigma context collapsing).\n * - finally pop ONE trailing `-` if present.\n *\n * Divergence from npm github-slugger (intentional — parity target is\n * the Rust function, not npm):\n * - `\"a,b\"` → `\"a-b\"` (stripped punctuation emits a dash, not nothing)\n * - `\" --weird-- \"` → `\"--weird--\"` (existing dashes/underscores pass\n * through unchanged)\n */\nexport function slugify(input: string): string {\n let out = \"\";\n let lastDash = true;\n\n for (const ch of input) {\n if (isWhitespace(ch) || isStripped(ch)) {\n if (!lastDash) {\n out += \"-\";\n lastDash = true;\n }\n } else {\n // Per-code-point lowercase — avoids Greek final-sigma context:\n // \"ΦΟΣ\" → \"φοσ\" not \"φος\".\n out += ch.toLowerCase();\n lastDash = false;\n }\n }\n\n if (out.endsWith(\"-\")) {\n out = out.slice(0, -1);\n }\n\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// next_slug\n// ---------------------------------------------------------------------------\n\n/**\n * Allocate the next deduplicated slug for `base` against a per-document\n * counter map.\n *\n * Mirrors Rust `next_slug`: first occurrence returns `base`, second\n * returns `base-1`, third `base-2`, … Empty `base` short-circuits to\n * `\"\"` without mutating the map.\n */\nfunction nextSlug(seen: Map<string, number>, base: string): string {\n if (base === \"\") return \"\";\n const count = seen.get(base) ?? 0;\n const slug = count === 0 ? base : `${base}-${count}`;\n seen.set(base, count + 1);\n return slug;\n}\n\n// ---------------------------------------------------------------------------\n// SlugAllocator\n// ---------------------------------------------------------------------------\n\n/**\n * Strategy-aware slug allocator for a single document.\n *\n * Mirrors Rust `SlugAllocator` in heading_links.rs:70-118.\n *\n * @param strategy `\"flat\"` (default) — per-document dedup counter, mirrors\n * github-slugger numbering. `\"hierarchical\"` — each slug is prefixed with\n * its ancestor chain and deduped on the full candidate path.\n *\n * Depth contract: callers pass `depth` values 2–6 (h2–h6). h1 is never\n * allocated — it is handled by the page layout, not the markdown body.\n */\nexport class SlugAllocator {\n private readonly strategy: \"flat\" | \"hierarchical\";\n private seen: Map<string, number>;\n /** Hierarchical ancestor stack of `[depth, finalId]` pairs. Unused in flat mode. */\n private stack: Array<[number, string]>;\n\n constructor(strategy: \"flat\" | \"hierarchical\" = \"flat\") {\n this.strategy = strategy;\n this.seen = new Map();\n this.stack = [];\n }\n\n /**\n * Allocate the slug for a heading of `depth` (2–6) whose slugified text\n * is `base`. Returns `\"\"` for an empty `base` without mutating state.\n */\n allocate(depth: number, base: string): string {\n if (this.strategy === \"flat\") {\n return nextSlug(this.seen, base);\n }\n\n // Hierarchical mode\n if (base === \"\") return \"\";\n\n // Pop ancestors whose depth >= this heading's depth\n let top = this.stack.at(-1);\n while (top !== undefined && top[0] >= depth) {\n this.stack.pop();\n top = this.stack.at(-1);\n }\n\n const candidate = top !== undefined ? `${top[1]}-${base}` : base;\n const slug = nextSlug(this.seen, candidate);\n this.stack.push([depth, slug]);\n return slug;\n }\n\n /**\n * Clear all per-document state (dedup counters AND the hierarchical\n * ancestor stack). Call between documents to avoid slug counter leakage.\n */\n reset(): void {\n this.seen.clear();\n this.stack = [];\n }\n}\n"]}
1
+ {"version":3,"file":"slugify.js","sourceRoot":"","sources":["../src/slugify.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Heading-anchor slug utilities — a pure-TypeScript port of the Rust\n * `slugify` / `next_slug` / `SlugAllocator` in\n * `crates/zfb-content/src/plugins/heading_links.rs`.\n *\n * These functions produce the `id` attribute values that appear on\n * `<h2>`–`<h6>` elements in the rendered HTML. They are intentionally\n * **not** compatible with npm `github-slugger`: stripped punctuation\n * collapses to a `-` separator (`\"a,b\"` → `\"a-b\"`), and leading/trailing\n * whitespace / stripped chars emit nothing rather than a stray dash.\n *\n * ⚠️ These functions produce heading-anchor slugs (e.g. `\"hello-world\"`\n * for `<h2 id=\"hello-world\">`). They are **different** from\n * `_relPathToSlug` in `content.ts`, which converts a file-system relative\n * path into a URL slug for `CollectionEntry.slug`.\n *\n * Parity is enforced by the shared fixture at\n * `crates/zfb-content/tests/fixtures/slugify-parity.json`, consumed by\n * both a Rust integration test and the `slugify.test.ts` vitest suite.\n */\n\n// ---------------------------------------------------------------------------\n// Helpers — mirrors the Rust `is_stripped` predicate\n// ---------------------------------------------------------------------------\n\n/** Unicode General Category Cc (control characters). */\nfunction isCc(ch: string): boolean {\n // \\p{Cc} = general category \"Control\" (C0 + C1 blocks: U+0000–U+001F, U+007F–U+009F)\n return /^\\p{Cc}$/u.test(ch);\n}\n\n/**\n * Returns true when the character should be stripped (maps to a dash\n * separator in the output). Mirrors Rust's `is_stripped`:\n * - Unicode Cc control characters\n * - Explicit ASCII punctuation set: `! \" # $ % & ' ( ) * + , . / : ; < = > ? @ [ \\ ] ^ ` { | } ~`\n */\nfunction isStripped(ch: string): boolean {\n if (isCc(ch)) return true;\n return (\n ch === \"!\" ||\n ch === '\"' ||\n ch === \"#\" ||\n ch === \"$\" ||\n ch === \"%\" ||\n ch === \"&\" ||\n ch === \"'\" ||\n ch === \"(\" ||\n ch === \")\" ||\n ch === \"*\" ||\n ch === \"+\" ||\n ch === \",\" ||\n ch === \".\" ||\n ch === \"/\" ||\n ch === \":\" ||\n ch === \";\" ||\n ch === \"<\" ||\n ch === \"=\" ||\n ch === \">\" ||\n ch === \"?\" ||\n ch === \"@\" ||\n ch === \"[\" ||\n ch === \"\\\\\" ||\n ch === \"]\" ||\n ch === \"^\" ||\n ch === \"`\" ||\n ch === \"{\" ||\n ch === \"|\" ||\n ch === \"}\" ||\n ch === \"~\"\n );\n}\n\n/**\n * Returns true when `ch` is a Unicode whitespace character.\n *\n * Mirrors Rust `char::is_whitespace` which is `\\p{White_Space}/u` — NOT\n * the JS `\\s` class (`\\s` wrongly matches U+FEFF BYTE ORDER MARK and\n * misses U+0085 NEXT LINE).\n */\nfunction isWhitespace(ch: string): boolean {\n return /^\\p{White_Space}$/u.test(ch);\n}\n\n// ---------------------------------------------------------------------------\n// slugify\n// ---------------------------------------------------------------------------\n\n/**\n * Produce a heading-anchor slug from `input`, matching the Rust\n * `slugify()` in `crates/zfb-content/src/plugins/heading_links.rs`.\n *\n * Algorithm (per Unicode code point):\n * - whitespace or stripped punctuation → emit ONE `-` unless the last\n * emitted character was already a `-` (leading separators are skipped\n * because `lastDash` starts `true`).\n * - anything else → push `ch.toLowerCase()` (per-code-point, not\n * whole-string, to avoid Greek final-sigma context collapsing).\n * - finally pop ONE trailing `-` if present.\n *\n * Divergence from npm github-slugger (intentional — parity target is\n * the Rust function, not npm):\n * - `\"a,b\"` → `\"a-b\"` (stripped punctuation emits a dash, not nothing)\n * - `\" --weird-- \"` → `\"--weird--\"` (existing dashes/underscores pass\n * through unchanged)\n */\nexport function slugify(input: string): string {\n let out = \"\";\n let lastDash = true;\n\n for (const ch of input) {\n if (isWhitespace(ch) || isStripped(ch)) {\n if (!lastDash) {\n out += \"-\";\n lastDash = true;\n }\n } else {\n // Per-code-point lowercase — avoids Greek final-sigma context:\n // \"ΦΟΣ\" → \"φοσ\" not \"φος\".\n out += ch.toLowerCase();\n lastDash = false;\n }\n }\n\n if (out.endsWith(\"-\")) {\n out = out.slice(0, -1);\n }\n\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// next_slug\n// ---------------------------------------------------------------------------\n\n/**\n * Allocate the next deduplicated slug for `base` against a per-document\n * counter map.\n *\n * Mirrors Rust `next_slug`: first occurrence returns `base`, second\n * returns `base-1`, third `base-2`, … Empty `base` short-circuits to\n * `\"\"` without mutating the map.\n */\nfunction nextSlug(seen: Map<string, number>, base: string): string {\n if (base === \"\") return \"\";\n const count = seen.get(base) ?? 0;\n const slug = count === 0 ? base : `${base}-${count}`;\n seen.set(base, count + 1);\n return slug;\n}\n\n// ---------------------------------------------------------------------------\n// SlugAllocator\n// ---------------------------------------------------------------------------\n\n/**\n * Strategy-aware slug allocator for a single document.\n *\n * Mirrors Rust `SlugAllocator` in heading_links.rs:70-118.\n *\n * @param strategy `\"flat\"` (default) — per-document dedup counter, mirrors\n * github-slugger numbering. `\"hierarchical\"` — each slug is prefixed with\n * its ancestor chain and deduped on the full candidate path.\n *\n * Depth contract: callers pass `depth` values 2–6 (h2–h6). h1 is never\n * allocated — it is handled by the page layout, not the markdown body.\n */\nexport class SlugAllocator {\n private readonly strategy: \"flat\" | \"hierarchical\";\n private seen: Map<string, number>;\n /** Hierarchical ancestor stack of `[depth, finalId]` pairs. Unused in flat mode. */\n private stack: Array<[number, string]>;\n\n constructor(strategy: \"flat\" | \"hierarchical\" = \"flat\") {\n this.strategy = strategy;\n this.seen = new Map();\n this.stack = [];\n }\n\n /**\n * Allocate the slug for a heading of `depth` (2–6) whose slugified text\n * is `base`. Returns `\"\"` for an empty `base` without mutating state.\n */\n allocate(depth: number, base: string): string {\n if (this.strategy === \"flat\") {\n return nextSlug(this.seen, base);\n }\n\n // Hierarchical mode\n if (base === \"\") return \"\";\n\n // Pop ancestors whose depth >= this heading's depth\n let top = this.stack.at(-1);\n while (top !== undefined && top[0] >= depth) {\n this.stack.pop();\n top = this.stack.at(-1);\n }\n\n const candidate = top !== undefined ? `${top[1]}-${base}` : base;\n const slug = nextSlug(this.seen, candidate);\n this.stack.push([depth, slug]);\n return slug;\n }\n\n /**\n * Clear all per-document state (dedup counters AND the hierarchical\n * ancestor stack). Call between documents to avoid slug counter leakage.\n */\n reset(): void {\n this.seen.clear();\n this.stack = [];\n }\n}\n"]}
@@ -12,5 +12,23 @@ export interface Description {
12
12
  readonly key: Key | null;
13
13
  }
14
14
  export declare function createDescription(type: ElementType, props: Record<string, unknown> | null, key?: Key | undefined): Description;
15
+ export interface CompilerSource {
16
+ readonly fileName: string;
17
+ readonly lineNumber: number;
18
+ readonly columnNumber: number;
19
+ }
20
+ export type DescriptionSite = {
21
+ readonly kind: "source";
22
+ readonly file: string;
23
+ readonly line: number;
24
+ readonly column: number;
25
+ } | {
26
+ readonly kind: "generated";
27
+ readonly specifier: string;
28
+ readonly line: number;
29
+ readonly column: number;
30
+ };
31
+ export declare function recordSite(description: Description, source: CompilerSource | undefined, caller: Function): Description;
32
+ export declare function descriptionSite(description: Description): DescriptionSite | undefined;
15
33
  export declare function isDescription(value: unknown): value is Description;
16
34
  export declare function flattenChildren(children: Child): readonly Exclude<Child, readonly Child[] | boolean | null | undefined>[];
@@ -25,6 +25,47 @@ export function createDescription(type, props, key) {
25
25
  key: resolved == null ? null : resolved,
26
26
  };
27
27
  }
28
+ const sites = new WeakMap();
29
+ // The build host's SSR router holds a count here only while it re-renders failed pages.
30
+ const siteCapture = Symbol.for("@takazudo/zfb/zudo-react/site-capture-v1");
31
+ function generatedSite(caller) {
32
+ const active = globalThis[siteCapture];
33
+ if (typeof active !== "number" || active < 1)
34
+ return undefined;
35
+ if (typeof Error.captureStackTrace !== "function")
36
+ return undefined;
37
+ const holder = {};
38
+ Error.captureStackTrace(holder, caller);
39
+ const frame = holder.stack?.split("\n")[1]?.trim();
40
+ const match = frame && /([^\s()]+):(\d+):(\d+)\)?$/.exec(frame);
41
+ if (!match)
42
+ return undefined;
43
+ return {
44
+ kind: "generated",
45
+ specifier: match[1],
46
+ line: Number(match[2]),
47
+ column: Number(match[3]),
48
+ };
49
+ }
50
+ export function recordSite(description, source, caller) {
51
+ const site = source &&
52
+ typeof source.fileName === "string" &&
53
+ Number.isInteger(source.lineNumber) &&
54
+ Number.isInteger(source.columnNumber)
55
+ ? {
56
+ kind: "source",
57
+ file: source.fileName,
58
+ line: source.lineNumber,
59
+ column: source.columnNumber,
60
+ }
61
+ : generatedSite(caller);
62
+ if (site)
63
+ sites.set(description, site);
64
+ return description;
65
+ }
66
+ export function descriptionSite(description) {
67
+ return sites.get(description);
68
+ }
28
69
  export function isDescription(value) {
29
70
  return (typeof value === "object" &&
30
71
  value !== null &&
@@ -1 +1 @@
1
- {"version":3,"file":"description.js","sourceRoot":"","sources":["../../src/zudo-react/description.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadonlySignal } from \"./reactive-types.js\";\n\nexport type Key = string | number;\nexport type Scalar = string | number | boolean | null | undefined;\nexport type Child = Scalar | Description | ReadonlySignal<Scalar> | readonly Child[];\nexport type Component<P = Record<string, unknown>> = (props: P) => Child;\nexport const Fragment: unique symbol = Symbol.for(\n \"@takazudo/zfb/zudo-react/fragment-v1\",\n) as typeof Fragment;\nexport type ElementType =\n | string\n | Component<any>\n | typeof import(\"../island.js\").Island\n | typeof Fragment;\n\nexport interface Description {\n readonly $$zudo: \"zudo-react.description.v1\";\n readonly type: ElementType;\n readonly props: Readonly<Record<string, unknown>>;\n readonly key: Key | null;\n}\n\nfunction valueKind(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n if (typeof value === \"object\" && value instanceof Promise) return \"promise\";\n return typeof value;\n}\n\nfunction validKey(value: unknown): value is Key {\n return typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value));\n}\n\nexport function createDescription(\n type: ElementType,\n props: Record<string, unknown> | null,\n key?: Key | undefined,\n): Description {\n const copy = { ...props };\n const resolved = key === undefined ? copy.key : key;\n if (resolved !== undefined && resolved !== null && !validKey(resolved)) {\n throw new TypeError(`Invalid key: ${valueKind(resolved)}`);\n }\n delete copy.key;\n return {\n $$zudo: \"zudo-react.description.v1\",\n type,\n props: copy,\n key: resolved == null ? null : resolved,\n };\n}\n\nexport function isDescription(value: unknown): value is Description {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"$$zudo\" in value &&\n value.$$zudo === \"zudo-react.description.v1\" &&\n \"type\" in value &&\n \"props\" in value &&\n \"key\" in value\n );\n}\n\nfunction isReactive(value: unknown): value is ReadonlySignal<Scalar> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"$$zudoReactive\" in value &&\n value.$$zudoReactive === \"zudo-react.reactive.v1\"\n );\n}\n\nexport function flattenChildren(\n children: Child,\n): readonly Exclude<Child, readonly Child[] | boolean | null | undefined>[] {\n const result: Exclude<Child, readonly Child[] | boolean | null | undefined>[] = [];\n function visit(value: unknown, path: string): void {\n if (value === null || value === undefined || typeof value === \"boolean\") return;\n if (Array.isArray(value)) {\n value.forEach((child, index) => visit(child, `${path}[${index}]`));\n return;\n }\n if (\n typeof value === \"string\" ||\n (typeof value === \"number\" && Number.isFinite(value)) ||\n isDescription(value) ||\n isReactive(value)\n ) {\n result.push(value as (typeof result)[number]);\n return;\n }\n throw new TypeError(`Invalid child ${valueKind(value)} at ${path} in parent <root>`);\n }\n visit(children, \"children\");\n return result;\n}\n"]}
1
+ {"version":3,"file":"description.js","sourceRoot":"","sources":["../../src/zudo-react/description.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,QAAQ,GAAkB,MAAM,CAAC,GAAG,CAC/C,sCAAsC,CACpB,CAAC;AAcrB,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,OAAO;QAAE,OAAO,SAAS,CAAC;IAC5E,OAAO,OAAO,KAAK,CAAC;AACtB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,IAAiB,EACjB,KAAqC,EACrC,GAAqB;IAErB,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACpD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,SAAS,CAAC,gBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC;IAChB,OAAO;QACL,MAAM,EAAE,2BAA2B;QACnC,IAAI;QACJ,KAAK,EAAE,IAAI;QACX,GAAG,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;KACxC,CAAC;AACJ,CAAC;AAsBD,MAAM,KAAK,GAAG,IAAI,OAAO,EAAgC,CAAC;AAC1D,wFAAwF;AACxF,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;AAE3E,SAAS,aAAa,CAAC,MAAgB;IACrC,MAAM,MAAM,GAAI,UAAsC,CAAC,WAAW,CAAC,CAAC;IACpE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/D,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACpE,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,KAAK,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,KAAK,IAAI,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAE;QACpB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,WAAwB,EACxB,MAAkC,EAClC,MAAgB;IAEhB,MAAM,IAAI,GACR,MAAM;QACN,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QACnC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC;QACnC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;QACnC,CAAC,CAAC;YACE,IAAI,EAAE,QAAiB;YACvB,IAAI,EAAE,MAAM,CAAC,QAAQ;YACrB,IAAI,EAAE,MAAM,CAAC,UAAU;YACvB,MAAM,EAAE,MAAM,CAAC,YAAY;SAC5B;QACH,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,IAAI;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACvC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAwB;IACtD,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,QAAQ,IAAI,KAAK;QACjB,KAAK,CAAC,MAAM,KAAK,2BAA2B;QAC5C,MAAM,IAAI,KAAK;QACf,OAAO,IAAI,KAAK;QAChB,KAAK,IAAI,KAAK,CACf,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,gBAAgB,IAAI,KAAK;QACzB,KAAK,CAAC,cAAc,KAAK,wBAAwB,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,QAAe;IAEf,MAAM,MAAM,GAAoE,EAAE,CAAC;IACnF,SAAS,KAAK,CAAC,KAAc,EAAE,IAAY;QACzC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,SAAS;YAAE,OAAO;QAChF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QACD,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACrD,aAAa,CAAC,KAAK,CAAC;YACpB,UAAU,CAAC,KAAK,CAAC,EACjB,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,iBAAiB,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,mBAAmB,CAAC,CAAC;IACvF,CAAC;IACD,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { ReadonlySignal } from \"./reactive-types.js\";\n\nexport type Key = string | number;\nexport type Scalar = string | number | boolean | null | undefined;\nexport type Child = Scalar | Description | ReadonlySignal<Scalar> | readonly Child[];\nexport type Component<P = Record<string, unknown>> = (props: P) => Child;\nexport const Fragment: unique symbol = Symbol.for(\n \"@takazudo/zfb/zudo-react/fragment-v1\",\n) as typeof Fragment;\nexport type ElementType =\n | string\n | Component<any>\n | typeof import(\"../island.js\").Island\n | typeof Fragment;\n\nexport interface Description {\n readonly $$zudo: \"zudo-react.description.v1\";\n readonly type: ElementType;\n readonly props: Readonly<Record<string, unknown>>;\n readonly key: Key | null;\n}\n\nfunction valueKind(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n if (typeof value === \"object\" && value instanceof Promise) return \"promise\";\n return typeof value;\n}\n\nfunction validKey(value: unknown): value is Key {\n return typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value));\n}\n\nexport function createDescription(\n type: ElementType,\n props: Record<string, unknown> | null,\n key?: Key | undefined,\n): Description {\n const copy = { ...props };\n const resolved = key === undefined ? copy.key : key;\n if (resolved !== undefined && resolved !== null && !validKey(resolved)) {\n throw new TypeError(`Invalid key: ${valueKind(resolved)}`);\n }\n delete copy.key;\n return {\n $$zudo: \"zudo-react.description.v1\",\n type,\n props: copy,\n key: resolved == null ? null : resolved,\n };\n}\n\nexport interface CompilerSource {\n readonly fileName: string;\n readonly lineNumber: number;\n readonly columnNumber: number;\n}\n\nexport type DescriptionSite =\n | {\n readonly kind: \"source\";\n readonly file: string;\n readonly line: number;\n readonly column: number;\n }\n | {\n readonly kind: \"generated\";\n readonly specifier: string;\n readonly line: number;\n readonly column: number;\n };\n\nconst sites = new WeakMap<Description, DescriptionSite>();\n// The build host's SSR router holds a count here only while it re-renders failed pages.\nconst siteCapture = Symbol.for(\"@takazudo/zfb/zudo-react/site-capture-v1\");\n\nfunction generatedSite(caller: Function): DescriptionSite | undefined {\n const active = (globalThis as Record<symbol, unknown>)[siteCapture];\n if (typeof active !== \"number\" || active < 1) return undefined;\n if (typeof Error.captureStackTrace !== \"function\") return undefined;\n const holder: { stack?: string } = {};\n Error.captureStackTrace(holder, caller);\n const frame = holder.stack?.split(\"\\n\")[1]?.trim();\n const match = frame && /([^\\s()]+):(\\d+):(\\d+)\\)?$/.exec(frame);\n if (!match) return undefined;\n return {\n kind: \"generated\",\n specifier: match[1]!,\n line: Number(match[2]),\n column: Number(match[3]),\n };\n}\n\nexport function recordSite(\n description: Description,\n source: CompilerSource | undefined,\n caller: Function,\n): Description {\n const site =\n source &&\n typeof source.fileName === \"string\" &&\n Number.isInteger(source.lineNumber) &&\n Number.isInteger(source.columnNumber)\n ? {\n kind: \"source\" as const,\n file: source.fileName,\n line: source.lineNumber,\n column: source.columnNumber,\n }\n : generatedSite(caller);\n if (site) sites.set(description, site);\n return description;\n}\n\nexport function descriptionSite(description: Description): DescriptionSite | undefined {\n return sites.get(description);\n}\n\nexport function isDescription(value: unknown): value is Description {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"$$zudo\" in value &&\n value.$$zudo === \"zudo-react.description.v1\" &&\n \"type\" in value &&\n \"props\" in value &&\n \"key\" in value\n );\n}\n\nfunction isReactive(value: unknown): value is ReadonlySignal<Scalar> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"$$zudoReactive\" in value &&\n value.$$zudoReactive === \"zudo-react.reactive.v1\"\n );\n}\n\nexport function flattenChildren(\n children: Child,\n): readonly Exclude<Child, readonly Child[] | boolean | null | undefined>[] {\n const result: Exclude<Child, readonly Child[] | boolean | null | undefined>[] = [];\n function visit(value: unknown, path: string): void {\n if (value === null || value === undefined || typeof value === \"boolean\") return;\n if (Array.isArray(value)) {\n value.forEach((child, index) => visit(child, `${path}[${index}]`));\n return;\n }\n if (\n typeof value === \"string\" ||\n (typeof value === \"number\" && Number.isFinite(value)) ||\n isDescription(value) ||\n isReactive(value)\n ) {\n result.push(value as (typeof result)[number]);\n return;\n }\n throw new TypeError(`Invalid child ${valueKind(value)} at ${path} in parent <root>`);\n }\n visit(children, \"children\");\n return result;\n}\n"]}
@@ -1,10 +1,11 @@
1
+ import { serializeStyle } from "./style.js";
1
2
  import { type Subscription } from "./reactive.js";
2
3
  import type { ReadonlySignal } from "./reactive-types.js";
3
4
  import type { RuntimeScope } from "./scope.js";
4
5
  import type { RootOptions } from "./root.js";
5
6
  export declare function isReactive(value: unknown): value is ReadonlySignal<unknown>;
6
7
  export declare function read(value: unknown): unknown;
7
- export declare function styleText(value: unknown): string;
8
+ export declare const styleText: typeof serializeStyle;
8
9
  export declare function setAttribute(element: Element, name: string, value: unknown): void;
9
10
  export declare function bind<T>(source: ReadonlySignal<T>, scope: RuntimeScope, options: RootOptions, container: Element, path: string, apply: (value: T) => void, initial: T): Subscription;
10
11
  export declare function listener(name: string): {
@@ -1,6 +1,7 @@
1
+ import { serializeStyle } from "./style.js";
1
2
  import { subscribe, readSnapshot } from "./reactive.js";
2
3
  import { diagnostic, report, rootPath } from "./root.js";
3
- import { booleanAttrs } from "./vocabulary.js";
4
+ import { attributeNamespace, attributeText } from "./vocabulary.js";
4
5
  export function isReactive(value) {
5
6
  return (typeof value === "object" &&
6
7
  value !== null &&
@@ -10,30 +11,23 @@ export function isReactive(value) {
10
11
  export function read(value) {
11
12
  return isReactive(value) ? readSnapshot(value) : value;
12
13
  }
13
- export function styleText(value) {
14
- if (typeof value === "string")
15
- return value;
16
- if (value === null || typeof value !== "object" || Array.isArray(value))
17
- throw new TypeError("ZR_STYLE");
18
- let result = "";
19
- for (const [name, entry] of Object.entries(value)) {
20
- if (!/^(--[a-zA-Z0-9_-]+|[a-z][a-z0-9-]*)$/.test(name) || /[A-Z]/.test(name))
21
- throw new TypeError(`ZR_STYLE: ${name}`);
22
- if (entry == null)
23
- continue;
24
- if (typeof entry !== "string" && !(typeof entry === "number" && Number.isFinite(entry)))
25
- throw new TypeError(`ZR_STYLE: ${name}`);
26
- result += `${name}:${entry};`;
27
- }
28
- return result;
29
- }
14
+ export const styleText = serializeStyle;
30
15
  export function setAttribute(element, name, value) {
31
- if (value == null || (booleanAttrs.has(name) && value === false)) {
32
- element.removeAttribute(name);
16
+ const namespace = attributeNamespace(name);
17
+ const localName = namespace && name.includes(":") ? name.split(":")[1] : name;
18
+ const text = name === "style" && value != null ? styleText(value) : attributeText(name, value);
19
+ if (text === null) {
20
+ if (namespace)
21
+ element.removeAttributeNS(namespace, localName);
22
+ else
23
+ element.removeAttribute(name);
33
24
  return;
34
25
  }
35
- const text = name === "style" ? styleText(value) : booleanAttrs.has(name) ? "" : String(value);
36
- if (element.getAttribute(name) !== text)
26
+ if (namespace) {
27
+ if (element.getAttributeNS(namespace, localName) !== text)
28
+ element.setAttributeNS(namespace, name, text);
29
+ }
30
+ else if (element.getAttribute(name) !== text)
37
31
  element.setAttribute(name, text);
38
32
  }
39
33
  export function bind(source, scope, options, container, path, apply, initial) {
@@ -1 +1 @@
1
- {"version":3,"file":"dom-bindings.js","sourceRoot":"","sources":["../../src/zudo-react/dom-bindings.ts"],"names":[],"mappings":"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","sourcesContent":["import { subscribe, readSnapshot, type Subscription } from \"./reactive.js\";\nimport type { ReadonlySignal } from \"./reactive-types.js\";\nimport type { RuntimeScope } from \"./scope.js\";\nimport type { RootOptions } from \"./root.js\";\nimport { diagnostic, report, rootPath } from \"./root.js\";\nimport { booleanAttrs } from \"./vocabulary.js\";\n\nexport function isReactive(value: unknown): value is ReadonlySignal<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"$$zudoReactive\" in value &&\n value.$$zudoReactive === \"zudo-react.reactive.v1\"\n );\n}\nexport function read(value: unknown): unknown {\n return isReactive(value) ? readSnapshot(value) : value;\n}\nexport function styleText(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (value === null || typeof value !== \"object\" || Array.isArray(value))\n throw new TypeError(\"ZR_STYLE\");\n let result = \"\";\n for (const [name, entry] of Object.entries(value)) {\n if (!/^(--[a-zA-Z0-9_-]+|[a-z][a-z0-9-]*)$/.test(name) || /[A-Z]/.test(name))\n throw new TypeError(`ZR_STYLE: ${name}`);\n if (entry == null) continue;\n if (typeof entry !== \"string\" && !(typeof entry === \"number\" && Number.isFinite(entry)))\n throw new TypeError(`ZR_STYLE: ${name}`);\n result += `${name}:${entry};`;\n }\n return result;\n}\nexport function setAttribute(element: Element, name: string, value: unknown): void {\n if (value == null || (booleanAttrs.has(name) && value === false)) {\n element.removeAttribute(name);\n return;\n }\n const text = name === \"style\" ? styleText(value) : booleanAttrs.has(name) ? \"\" : String(value);\n if (element.getAttribute(name) !== text) element.setAttribute(name, text);\n}\nexport function bind<T>(\n source: ReadonlySignal<T>,\n scope: RuntimeScope,\n options: RootOptions,\n container: Element,\n path: string,\n apply: (value: T) => void,\n initial: T,\n): Subscription {\n let previous = initial;\n const subscription = subscribe(\n () => {\n const next = source.value;\n if (Object.is(previous, next)) return;\n previous = next;\n apply(next);\n },\n {\n active: () => scope.active,\n report: (code, actual) =>\n report(\n options,\n diagnostic(\n options,\n code,\n \"update\",\n `${rootPath(container)}${path}`,\n \"binding update\",\n actual,\n ),\n ),\n },\n );\n subscription.run();\n return subscription;\n}\nexport function listener(name: string): { name: string; capture: boolean } | null {\n const match = /^on:([A-Za-z][A-Za-z0-9_-]*)(:capture)?$/.exec(name);\n return match ? { name: match[1]!, capture: Boolean(match[2]) } : null;\n}\n"]}
1
+ {"version":3,"file":"dom-bindings.js","sourceRoot":"","sources":["../../src/zudo-react/dom-bindings.ts"],"names":[],"mappings":"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","sourcesContent":["import { serializeStyle } from \"./style.js\";\nimport { subscribe, readSnapshot, type Subscription } from \"./reactive.js\";\nimport type { ReadonlySignal } from \"./reactive-types.js\";\nimport type { RuntimeScope } from \"./scope.js\";\nimport type { RootOptions } from \"./root.js\";\nimport { diagnostic, report, rootPath } from \"./root.js\";\nimport { attributeNamespace, attributeText } from \"./vocabulary.js\";\n\nexport function isReactive(value: unknown): value is ReadonlySignal<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"$$zudoReactive\" in value &&\n value.$$zudoReactive === \"zudo-react.reactive.v1\"\n );\n}\nexport function read(value: unknown): unknown {\n return isReactive(value) ? readSnapshot(value) : value;\n}\nexport const styleText = serializeStyle;\nexport function setAttribute(element: Element, name: string, value: unknown): void {\n const namespace = attributeNamespace(name);\n const localName = namespace && name.includes(\":\") ? name.split(\":\")[1]! : name;\n const text = name === \"style\" && value != null ? styleText(value) : attributeText(name, value);\n if (text === null) {\n if (namespace) element.removeAttributeNS(namespace, localName);\n else element.removeAttribute(name);\n return;\n }\n if (namespace) {\n if (element.getAttributeNS(namespace, localName) !== text)\n element.setAttributeNS(namespace, name, text);\n } else if (element.getAttribute(name) !== text) element.setAttribute(name, text);\n}\nexport function bind<T>(\n source: ReadonlySignal<T>,\n scope: RuntimeScope,\n options: RootOptions,\n container: Element,\n path: string,\n apply: (value: T) => void,\n initial: T,\n): Subscription {\n let previous = initial;\n const subscription = subscribe(\n () => {\n const next = source.value;\n if (Object.is(previous, next)) return;\n previous = next;\n apply(next);\n },\n {\n active: () => scope.active,\n report: (code, actual) =>\n report(\n options,\n diagnostic(\n options,\n code,\n \"update\",\n `${rootPath(container)}${path}`,\n \"binding update\",\n actual,\n ),\n ),\n },\n );\n subscription.run();\n return subscription;\n}\nexport function listener(name: string): { name: string; capture: boolean } | null {\n const match = /^on:([A-Za-z][A-Za-z0-9_-]*)(:capture)?$/.exec(name);\n return match ? { name: match[1]!, capture: Boolean(match[2]) } : null;\n}\n"]}