@semiont/frontend 0.5.7 → 0.5.9

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 (145) hide show
  1. package/dist/assets/{CookiePreferences-CQa2Mwuc.js → CookiePreferences-CwQNSYq4.js} +2 -2
  2. package/dist/assets/{CookiePreferences-CQa2Mwuc.js.map → CookiePreferences-CwQNSYq4.js.map} +1 -1
  3. package/dist/assets/{KeyboardShortcutsContext-4ZRypoQr.js → KeyboardShortcutsContext-CfYRiurd.js} +2 -2
  4. package/dist/assets/{KeyboardShortcutsContext-4ZRypoQr.js.map → KeyboardShortcutsContext-CfYRiurd.js.map} +1 -1
  5. package/dist/assets/PdfAnnotationCanvas.client-U4EVBZEV-hNsmZuyz.js +2 -0
  6. package/dist/assets/PdfAnnotationCanvas.client-U4EVBZEV-hNsmZuyz.js.map +1 -0
  7. package/dist/assets/{ToolbarPanels-BA4fpTjN.js → ToolbarPanels-DhP2342d.js} +2 -2
  8. package/dist/assets/{ToolbarPanels-BA4fpTjN.js.map → ToolbarPanels-DhP2342d.js.map} +1 -1
  9. package/dist/assets/{ar-SONK6MON-Bg_g0nKu.js → ar-WA47UUWA-Bg_g0nKu.js} +1 -1
  10. package/dist/assets/{ar-SONK6MON-Bg_g0nKu.js.map → ar-WA47UUWA-Bg_g0nKu.js.map} +1 -1
  11. package/dist/assets/{bn-ZKPRITNG-D3W-5Rrq.js → bn-5ANDRIU6-D3W-5Rrq.js} +1 -1
  12. package/dist/assets/{bn-ZKPRITNG-D3W-5Rrq.js.map → bn-5ANDRIU6-D3W-5Rrq.js.map} +1 -1
  13. package/dist/assets/{client-xSsFQAGt.js → client-3m7lyOF-.js} +2 -2
  14. package/dist/assets/{client-xSsFQAGt.js.map → client-3m7lyOF-.js.map} +1 -1
  15. package/dist/assets/{client-C8P-NF_R.js → client-B-MhGs0Z.js} +2 -2
  16. package/dist/assets/{client-C8P-NF_R.js.map → client-B-MhGs0Z.js.map} +1 -1
  17. package/dist/assets/{client-C5NXgCxS.js → client-CSwC62BQ.js} +2 -2
  18. package/dist/assets/{client-C5NXgCxS.js.map → client-CSwC62BQ.js.map} +1 -1
  19. package/dist/assets/{client-DdxBbstZ.js → client-sNRwAXfy.js} +2 -2
  20. package/dist/assets/{client-DdxBbstZ.js.map → client-sNRwAXfy.js.map} +1 -1
  21. package/dist/assets/{cs-LPXQ7NHQ-2LzMsUs5.js → cs-3RU7F4JX-2LzMsUs5.js} +1 -1
  22. package/dist/assets/{cs-LPXQ7NHQ-2LzMsUs5.js.map → cs-3RU7F4JX-2LzMsUs5.js.map} +1 -1
  23. package/dist/assets/{da-6TKY7MCY-DyKRptR2.js → da-GSW5P5HG-DyKRptR2.js} +1 -1
  24. package/dist/assets/{da-6TKY7MCY-DyKRptR2.js.map → da-GSW5P5HG-DyKRptR2.js.map} +1 -1
  25. package/dist/assets/{de-C3GNII74-DuEZ0oQs.js → de-JUAUYF4Z-DuEZ0oQs.js} +1 -1
  26. package/dist/assets/{de-C3GNII74-DuEZ0oQs.js.map → de-JUAUYF4Z-DuEZ0oQs.js.map} +1 -1
  27. package/dist/assets/{el-UBCXQDJ7-BfaVdiXe.js → el-JNLWCKEC-BfaVdiXe.js} +1 -1
  28. package/dist/assets/{el-UBCXQDJ7-BfaVdiXe.js.map → el-JNLWCKEC-BfaVdiXe.js.map} +1 -1
  29. package/dist/assets/{en-L45VK7BS-BREpSrvO.js → en-RBN2GUHF-Bbg1LCI1.js} +1 -1
  30. package/dist/assets/{es-BQ23TRI7-BOyWYGWS.js → es-WPOX225H-BOyWYGWS.js} +1 -1
  31. package/dist/assets/{es-BQ23TRI7-BOyWYGWS.js.map → es-WPOX225H-BOyWYGWS.js.map} +1 -1
  32. package/dist/assets/{fa-AFTBZB77-D2lXkg8T.js → fa-TAEP6N77-D2lXkg8T.js} +1 -1
  33. package/dist/assets/{fa-AFTBZB77-D2lXkg8T.js.map → fa-TAEP6N77-D2lXkg8T.js.map} +1 -1
  34. package/dist/assets/{fi-WOYNLZC2-cxycD0z_.js → fi-ZVZHANSP-cxycD0z_.js} +1 -1
  35. package/dist/assets/{fi-WOYNLZC2-cxycD0z_.js.map → fi-ZVZHANSP-cxycD0z_.js.map} +1 -1
  36. package/dist/assets/{fr-NDSMIFJM-BAn0-4x3.js → fr-VLZW7M4N-BAn0-4x3.js} +1 -1
  37. package/dist/assets/{fr-NDSMIFJM-BAn0-4x3.js.map → fr-VLZW7M4N-BAn0-4x3.js.map} +1 -1
  38. package/dist/assets/{he-VJXVRDOY-CO99w2C-.js → he-QFAFYA77-CO99w2C-.js} +1 -1
  39. package/dist/assets/{he-VJXVRDOY-CO99w2C-.js.map → he-QFAFYA77-CO99w2C-.js.map} +1 -1
  40. package/dist/assets/{hi-BF6PHIE2-B-glDmjd.js → hi-AO3DQPCV-B-glDmjd.js} +1 -1
  41. package/dist/assets/{hi-BF6PHIE2-B-glDmjd.js.map → hi-AO3DQPCV-B-glDmjd.js.map} +1 -1
  42. package/dist/assets/{id-GXG5QCZY-pIWqz5D1.js → id-GTXF42WM-pIWqz5D1.js} +1 -1
  43. package/dist/assets/{id-GXG5QCZY-pIWqz5D1.js.map → id-GTXF42WM-pIWqz5D1.js.map} +1 -1
  44. package/dist/assets/index-Cx0aNta6.css +1 -0
  45. package/dist/assets/index-D2LrA6v6.js +141 -0
  46. package/dist/assets/index-D2LrA6v6.js.map +1 -0
  47. package/dist/assets/{it-XKHHCBAF-BIVnRKJx.js → it-AS5GM232-BIVnRKJx.js} +1 -1
  48. package/dist/assets/{it-XKHHCBAF-BIVnRKJx.js.map → it-AS5GM232-BIVnRKJx.js.map} +1 -1
  49. package/dist/assets/{ja-TX7VM4XD-C8mqh5If.js → ja-GZ4HLUOF-C8mqh5If.js} +1 -1
  50. package/dist/assets/{ja-TX7VM4XD-C8mqh5If.js.map → ja-GZ4HLUOF-C8mqh5If.js.map} +1 -1
  51. package/dist/assets/{ko-DNC7EQ7J-GlrkT0k0.js → ko-A4XUXFGJ-GlrkT0k0.js} +1 -1
  52. package/dist/assets/{ko-DNC7EQ7J-GlrkT0k0.js.map → ko-A4XUXFGJ-GlrkT0k0.js.map} +1 -1
  53. package/dist/assets/{layout-2BOrZAoT.js → layout--kttJwjx.js} +2 -2
  54. package/dist/assets/{layout-2BOrZAoT.js.map → layout--kttJwjx.js.map} +1 -1
  55. package/dist/assets/{layout-5FLtbdhm.js → layout-CIBMGRGg.js} +2 -2
  56. package/dist/assets/{layout-5FLtbdhm.js.map → layout-CIBMGRGg.js.map} +1 -1
  57. package/dist/assets/{layout-DzdDsd3P.js → layout-ChjT2XMf.js} +2 -2
  58. package/dist/assets/{layout-DzdDsd3P.js.map → layout-ChjT2XMf.js.map} +1 -1
  59. package/dist/assets/{layout-CDH3Am1z.js → layout-DTOSfecO.js} +2 -2
  60. package/dist/assets/{layout-CDH3Am1z.js.map → layout-DTOSfecO.js.map} +1 -1
  61. package/dist/assets/{ms-POZGBKPH-CgcHbUoC.js → ms-YBAO3S6K-CgcHbUoC.js} +1 -1
  62. package/dist/assets/{ms-POZGBKPH-CgcHbUoC.js.map → ms-YBAO3S6K-CgcHbUoC.js.map} +1 -1
  63. package/dist/assets/{nl-IRMTKI7Z-DCK_99k9.js → nl-3TJGIIIU-DCK_99k9.js} +1 -1
  64. package/dist/assets/{nl-IRMTKI7Z-DCK_99k9.js.map → nl-3TJGIIIU-DCK_99k9.js.map} +1 -1
  65. package/dist/assets/{no-ZUDJA4S6-DAsTyX8P.js → no-4AXIQPRQ-DAsTyX8P.js} +1 -1
  66. package/dist/assets/{no-ZUDJA4S6-DAsTyX8P.js.map → no-4AXIQPRQ-DAsTyX8P.js.map} +1 -1
  67. package/dist/assets/{not-found-BMdN8mPs.js → not-found-CkW7yXCZ.js} +2 -2
  68. package/dist/assets/{not-found-BMdN8mPs.js.map → not-found-CkW7yXCZ.js.map} +1 -1
  69. package/dist/assets/{page-vslu8nIa.js → page-10-2WEh9.js} +2 -2
  70. package/dist/assets/{page-vslu8nIa.js.map → page-10-2WEh9.js.map} +1 -1
  71. package/dist/assets/{page-C3vf9APn.js → page-B2YCNfqB.js} +2 -2
  72. package/dist/assets/{page-C3vf9APn.js.map → page-B2YCNfqB.js.map} +1 -1
  73. package/dist/assets/{page-DwNbxb_72.js → page-BSoOqqDp2.js} +2 -2
  74. package/dist/assets/{page-DwNbxb_72.js.map → page-BSoOqqDp2.js.map} +1 -1
  75. package/dist/assets/{page-CqeyagPz.js → page-Bk28sWf5.js} +2 -2
  76. package/dist/assets/{page-CqeyagPz.js.map → page-Bk28sWf5.js.map} +1 -1
  77. package/dist/assets/{page-DiM4fD5f.js → page-BkM7uTwY.js} +2 -2
  78. package/dist/assets/{page-DiM4fD5f.js.map → page-BkM7uTwY.js.map} +1 -1
  79. package/dist/assets/{page-DB8nPCSg.js → page-BmB9iWba.js} +2 -2
  80. package/dist/assets/{page-DB8nPCSg.js.map → page-BmB9iWba.js.map} +1 -1
  81. package/dist/assets/{page-D9v0O50E.js → page-Bn2RYSD3.js} +2 -2
  82. package/dist/assets/{page-D9v0O50E.js.map → page-Bn2RYSD3.js.map} +1 -1
  83. package/dist/assets/{page-q6M0EXCY.js → page-BnjWmDsM.js} +2 -2
  84. package/dist/assets/{page-q6M0EXCY.js.map → page-BnjWmDsM.js.map} +1 -1
  85. package/dist/assets/{page-DFTvfk1t.js → page-ByOTWnuA.js} +2 -2
  86. package/dist/assets/{page-DFTvfk1t.js.map → page-ByOTWnuA.js.map} +1 -1
  87. package/dist/assets/{page-SMoiAlZl.js → page-CC4n7boQ.js} +2 -2
  88. package/dist/assets/{page-SMoiAlZl.js.map → page-CC4n7boQ.js.map} +1 -1
  89. package/dist/assets/{page-BzpGsQbe.js → page-CNQxEyNO.js} +2 -2
  90. package/dist/assets/{page-BzpGsQbe.js.map → page-CNQxEyNO.js.map} +1 -1
  91. package/dist/assets/{page-CHEBd0hh.js → page-CQvf9PwP.js} +2 -2
  92. package/dist/assets/{page-CHEBd0hh.js.map → page-CQvf9PwP.js.map} +1 -1
  93. package/dist/assets/{page-BxQNNFfW.js → page-CVsMMJ4D.js} +2 -2
  94. package/dist/assets/{page-BxQNNFfW.js.map → page-CVsMMJ4D.js.map} +1 -1
  95. package/dist/assets/page-CW6-9F9w.js +2 -0
  96. package/dist/assets/{page-B3PCCUTg.js.map → page-CW6-9F9w.js.map} +1 -1
  97. package/dist/assets/{page-Cx6TDy84.js → page-D4PdxwPW.js} +2 -2
  98. package/dist/assets/{page-Cx6TDy84.js.map → page-D4PdxwPW.js.map} +1 -1
  99. package/dist/assets/{page-lhTg_rP4.js → page-DE5OCneW.js} +2 -2
  100. package/dist/assets/{page-lhTg_rP4.js.map → page-DE5OCneW.js.map} +1 -1
  101. package/dist/assets/{page-C7lI-Rdx.js → page-aP22HQnz.js} +2 -2
  102. package/dist/assets/{page-C7lI-Rdx.js.map → page-aP22HQnz.js.map} +1 -1
  103. package/dist/assets/page-ps7dwO8y.js +2 -0
  104. package/dist/assets/{page-D_ZFOdXa.js.map → page-ps7dwO8y.js.map} +1 -1
  105. package/dist/assets/pdf-CHHhr2g_.js +55 -0
  106. package/dist/assets/pdf-CHHhr2g_.js.map +1 -0
  107. package/dist/assets/pdf.worker.min-CrMmvqMo.mjs +29 -0
  108. package/dist/assets/{pl-2NGAXL5U-CMMCajpA.js → pl-5GP6GKXO-CMMCajpA.js} +1 -1
  109. package/dist/assets/{pl-2NGAXL5U-CMMCajpA.js.map → pl-5GP6GKXO-CMMCajpA.js.map} +1 -1
  110. package/dist/assets/{pt-ABMCXZUM-69xFHtfx.js → pt-26Y6JFG5-69xFHtfx.js} +1 -1
  111. package/dist/assets/{pt-ABMCXZUM-69xFHtfx.js.map → pt-26Y6JFG5-69xFHtfx.js.map} +1 -1
  112. package/dist/assets/{ro-VOJP6O5X-DMzHGaHE.js → ro-C7UXFRWJ-DMzHGaHE.js} +1 -1
  113. package/dist/assets/{ro-VOJP6O5X-DMzHGaHE.js.map → ro-C7UXFRWJ-DMzHGaHE.js.map} +1 -1
  114. package/dist/assets/{routing-1L7p7DNA.js → routing-D3tVcFuL.js} +2 -2
  115. package/dist/assets/{routing-1L7p7DNA.js.map → routing-D3tVcFuL.js.map} +1 -1
  116. package/dist/assets/routing-GE3qy379.js +2 -0
  117. package/dist/assets/{routing-BcOlOpMI.js.map → routing-GE3qy379.js.map} +1 -1
  118. package/dist/assets/{sv-4HVFIIE5-BLvpn4fZ.js → sv-44DVD76T-BLvpn4fZ.js} +1 -1
  119. package/dist/assets/{sv-4HVFIIE5-BLvpn4fZ.js.map → sv-44DVD76T-BLvpn4fZ.js.map} +1 -1
  120. package/dist/assets/{th-IFPZP3HQ-Bgb4bUeg.js → th-GIQRTBOY-Bgb4bUeg.js} +1 -1
  121. package/dist/assets/{th-IFPZP3HQ-Bgb4bUeg.js.map → th-GIQRTBOY-Bgb4bUeg.js.map} +1 -1
  122. package/dist/assets/{tr-2GYEAMJ4-DfAWOqqm.js → tr-WMQWO4D6-DfAWOqqm.js} +1 -1
  123. package/dist/assets/{tr-2GYEAMJ4-DfAWOqqm.js.map → tr-WMQWO4D6-DfAWOqqm.js.map} +1 -1
  124. package/dist/assets/{uk-XCJBVLLD-Cr0S5UE-.js → uk-I7ML6RGG-Cr0S5UE-.js} +1 -1
  125. package/dist/assets/{uk-XCJBVLLD-Cr0S5UE-.js.map → uk-I7ML6RGG-Cr0S5UE-.js.map} +1 -1
  126. package/dist/assets/{vi-4FR7CB2F-CLx4LvVe.js → vi-FGWECASQ-CLx4LvVe.js} +1 -1
  127. package/dist/assets/{vi-4FR7CB2F-CLx4LvVe.js.map → vi-FGWECASQ-CLx4LvVe.js.map} +1 -1
  128. package/dist/assets/web-k3l0Woeo.js +2 -0
  129. package/dist/assets/web-k3l0Woeo.js.map +1 -0
  130. package/dist/assets/{zh-NSKFOINB-BpcLGXRm.js → zh-L5FN73XC-BpcLGXRm.js} +1 -1
  131. package/dist/assets/{zh-NSKFOINB-BpcLGXRm.js.map → zh-L5FN73XC-BpcLGXRm.js.map} +1 -1
  132. package/dist/index.html +2 -2
  133. package/package.json +1 -1
  134. package/dist/assets/PdfAnnotationCanvas.client-NIMALXNZ-QiAmdknm.js +0 -2
  135. package/dist/assets/PdfAnnotationCanvas.client-NIMALXNZ-QiAmdknm.js.map +0 -1
  136. package/dist/assets/index-C6By-chD.css +0 -1
  137. package/dist/assets/index-DQSZfVR2.js +0 -141
  138. package/dist/assets/index-DQSZfVR2.js.map +0 -1
  139. package/dist/assets/page-B3PCCUTg.js +0 -2
  140. package/dist/assets/page-D_ZFOdXa.js +0 -2
  141. package/dist/assets/routing-BcOlOpMI.js +0 -2
  142. package/dist/assets/web-DWMjUWgV.js +0 -2
  143. package/dist/assets/web-DWMjUWgV.js.map +0 -1
  144. package/dist/pdfjs/pdf.min.mjs +0 -21
  145. package/dist/pdfjs/pdf.worker.min.mjs +0 -21
@@ -1 +1 @@
1
- {"version":3,"file":"layout-2BOrZAoT.js","names":["ForwardRef","ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/BookOpenIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ClockIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/TagIcon.js","../../src/components/moderation/ModerationNavigation.tsx","../../src/app/[locale]/moderate/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction BookOpenIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(BookOpenIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ClockIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ClockIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction TagIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z\"\n }), /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M6 6h.008v.008H6V6Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(TagIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n ClockIcon,\n TagIcon,\n BookOpenIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface ModerationNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function ModerationNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: ModerationNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Moderation.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('recentResources'),\n href: '/moderate/recent',\n icon: ClockIcon,\n description: t('recentResourcesDescription')\n },\n {\n name: t('entityTags'),\n href: '/moderate/entity-tags',\n icon: TagIcon,\n description: t('entityTagsDescription')\n },\n {\n name: t('tagSchemas'),\n href: '/moderate/tag-schemas',\n icon: BookOpenIcon,\n description: t('tagSchemasDescription')\n },\n {\n name: t('linkedData'),\n href: '/moderate/linked-data',\n icon: ArrowsRightLeftIcon,\n description: t('linkedDataDescription')\n }\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { ModerationNavigation } from '@/components/moderation/ModerationNavigation';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction ModerateLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"moderation-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <ModerationNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function ModerateLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <ModerateLayoutBody />;\n}\n"],"x_google_ignoreList":[0,1,2],"mappings":"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"}
1
+ {"version":3,"file":"layout--kttJwjx.js","names":["ForwardRef","ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/BookOpenIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ClockIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/TagIcon.js","../../src/components/moderation/ModerationNavigation.tsx","../../src/app/[locale]/moderate/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction BookOpenIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(BookOpenIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ClockIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ClockIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction TagIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z\"\n }), /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M6 6h.008v.008H6V6Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(TagIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n ClockIcon,\n TagIcon,\n BookOpenIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface ModerationNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function ModerationNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: ModerationNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Moderation.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('recentResources'),\n href: '/moderate/recent',\n icon: ClockIcon,\n description: t('recentResourcesDescription')\n },\n {\n name: t('entityTags'),\n href: '/moderate/entity-tags',\n icon: TagIcon,\n description: t('entityTagsDescription')\n },\n {\n name: t('tagSchemas'),\n href: '/moderate/tag-schemas',\n icon: BookOpenIcon,\n description: t('tagSchemasDescription')\n },\n {\n name: t('linkedData'),\n href: '/moderate/linked-data',\n icon: ArrowsRightLeftIcon,\n description: t('linkedDataDescription')\n }\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { ModerationNavigation } from '@/components/moderation/ModerationNavigation';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction ModerateLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"moderation-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <ModerationNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function ModerateLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <ModerateLayoutBody />;\n}\n"],"x_google_ignoreList":[0,1,2],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{i as t,t as n}from"./i18n-X0oNIUcF.js";import{t as r}from"./vendor-Bd-5Ya9C.js";import{J as i,M as a,at as o,it as s,k as c,m as l,ot as u,rn as d}from"./index-DQSZfVR2.js";import{a as f,c as p,l as m,n as h,o as g,u as _}from"./KeyboardShortcutsContext-4ZRypoQr.js";import{i as v}from"./routing-BcOlOpMI.js";var y=e(t());function b({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m19.5 8.25-7.5 7.5-7.5-7.5`}))}var x=y.forwardRef(b);function S({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m4.5 15.75 7.5-7.5 7.5 7.5`}))}var C=y.forwardRef(S);function w(){let e=v();return i({"nav:external":(0,y.useCallback)(({url:t,cancelFallback:n})=>{n(),e.push(t)},[e]),"nav:push":(0,y.useCallback)(({path:t})=>{e.push(t)},[e])}),null}function T(e,t){let n=e.match(/\{(\w+),\s*plural,\s*/);if(!n)return e;let r=t[n[1]];if(r===void 0)return e;let i=n[0].length+n.index,a=1,o=i;for(let t=i;t<e.length;t++)if(e[t]===`{`)a++;else if(e[t]===`}`&&(a--,a===0)){o=t;break}let s=e.substring(i,o),c={},l=/(?:=(\d+)|(\w+))\s*\{([^}]+)\}/g,u;for(;(u=l.exec(s))!==null;){let[,e,t,n]=u,r=e===void 0?t:`=${e}`;c[r]=n}let d=c[`=${r}`];if(d!==void 0){let t=d.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}let f=c.other;if(f!==void 0){let t=f.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}return e}function E(e,t){let n=T(e,t);return Object.entries(t).forEach(([e,t])=>{n=n.replace(RegExp(`\\{\\{${e}\\}\\}`,`g`),String(t))}),n}function D(){let{i18n:e}=n();return(0,y.useMemo)(()=>({t:(t,n,r)=>{let i=e.getResourceBundle(e.language,`translation`)?.[t]?.[n];return i?r&&typeof i==`string`?E(i,r):i:`${t}.${n}`}}),[e,e.language])}var O=r();function k({children:e}){return(0,O.jsx)(u,{translationManager:D(),children:(0,O.jsx)(s,{children:(0,O.jsx)(o,{children:(0,O.jsx)(l,{children:(0,O.jsx)(h,{children:(0,O.jsxs)(a,{children:[(0,O.jsx)(w,{}),e]})})})})})})}function A({className:e=``}){let{t}=n(),r=(e,n)=>t(`CookieBanner.${e}`,n),[i,a]=(0,y.useState)(!1),[o,s]=(0,y.useState)(!1),[c,l]=(0,y.useState)(!1),[u,d]=(0,y.useState)(`GENERAL`),[h,v]=(0,y.useState)({necessary:!0,analytics:!1,marketing:!1,preferences:!1});(0,y.useEffect)(()=>{(async()=>{if(m()){a(!0);try{let[e,t]=await Promise.all([g(),f()]);d(e?`GDPR`:t?`CCPA`:`GENERAL`)}catch(e){console.error(`Failed to detect region:`,e),d(`GENERAL`)}}})()},[]);let b=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!0,marketing:!0,preferences:!0})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},S=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!1,marketing:!1,preferences:!1})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},w=async()=>{l(!0);try{await Promise.resolve(p(h)),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},T=e=>{e!==`necessary`&&v(t=>({...t,[e]:!t[e]}))},E=()=>{switch(u){case`GDPR`:return{title:r(`gdprTitle`),description:r(`gdprDescription`),learnMore:r(`gdprLearnMore`)};case`CCPA`:return{title:r(`ccpaTitle`),description:r(`ccpaDescription`),learnMore:r(`ccpaLearnMore`)};default:return{title:r(`generalTitle`),description:r(`generalDescription`),learnMore:r(`generalLearnMore`)}}};if(!i)return null;let D=E();return(0,O.jsx)(`div`,{className:e,style:{position:`fixed`,bottom:0,left:0,right:0,zIndex:50,backgroundColor:`var(--semiont-bg-primary)`,borderTop:`1px solid var(--semiont-border-primary)`,boxShadow:`var(--semiont-shadow-lg)`},children:(0,O.jsx)(`div`,{style:{maxWidth:`80rem`,margin:`0 auto`,padding:`1rem 1.5rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:`1.5rem`,flexWrap:`wrap`},children:[(0,O.jsxs)(`div`,{style:{flex:1,minWidth:`300px`},children:[(0,O.jsx)(`h3`,{style:{fontSize:`1.125rem`,fontWeight:600,color:`var(--semiont-text-primary)`,marginBottom:`0.5rem`},children:D.title}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,color:`var(--semiont-text-secondary)`,marginBottom:`0.25rem`},children:D.description}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:D.learnMore})]}),(0,O.jsxs)(`div`,{style:{display:`flex`,gap:`0.75rem`,alignItems:`center`,flexWrap:`wrap`},children:[(0,O.jsxs)(`button`,{type:`button`,onClick:()=>s(!o),className:`semiont-button--secondary`,style:{display:`flex`,alignItems:`center`,gap:`0.25rem`},children:[r(`customize`),o?(0,O.jsx)(C,{style:{width:`1rem`,height:`1rem`}}):(0,O.jsx)(x,{style:{width:`1rem`,height:`1rem`}})]}),u!==`GDPR`&&(0,O.jsx)(`button`,{type:`button`,onClick:S,disabled:c,className:`semiont-button--secondary`,children:r(c?`saving`:`rejectAll`)}),(0,O.jsx)(`button`,{type:`button`,onClick:b,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`acceptAll`)})]})]}),o&&(0,O.jsx)(`div`,{style:{borderTop:`1px solid var(--semiont-border-primary)`,paddingTop:`1rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsx)(`h4`,{style:{fontSize:`1rem`,fontWeight:500,color:`var(--semiont-text-primary)`},children:r(`cookiePreferences`)}),(0,O.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`0.75rem`},children:_.map(e=>(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:`0.75rem`},children:[(0,O.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,height:`1.25rem`},children:(0,O.jsx)(`input`,{id:`cookie-${e.id}`,type:`checkbox`,checked:h[e.id]||!1,onChange:()=>T(e.id),disabled:e.required||c,style:{accentColor:`var(--semiont-color-primary-600, #2563eb)`}})}),(0,O.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,O.jsxs)(`label`,{htmlFor:`cookie-${e.id}`,style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,fontWeight:500,color:`var(--semiont-text-primary)`,cursor:`pointer`},children:[e.name,e.required&&(0,O.jsx)(`span`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`,marginLeft:`0.25rem`},children:r(`required`)})]}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-secondary)`,marginTop:`0.25rem`},children:e.description}),(0,O.jsxs)(`details`,{style:{marginTop:`0.25rem`},children:[(0,O.jsx)(`summary`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-color-primary-600, #2563eb)`,cursor:`pointer`},children:r(`viewCookies`)}),(0,O.jsx)(`div`,{style:{marginTop:`0.25rem`,fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:e.cookies.join(`, `)})]})]})]},e.id))}),(0,O.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:`0.75rem`,paddingTop:`1rem`},children:[(0,O.jsx)(`button`,{type:`button`,onClick:()=>s(!1),className:`semiont-button--secondary`,children:r(`cancel`)}),(0,O.jsx)(`button`,{type:`button`,onClick:w,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`savePreferences`)})]})]})})]})})})}function j(){return(0,O.jsxs)(k,{children:[(0,O.jsx)(c,{}),(0,O.jsx)(d,{}),(0,O.jsx)(A,{})]})}export{j as default};
2
- //# sourceMappingURL=layout-5FLtbdhm.js.map
1
+ import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{i as t,t as n}from"./i18n-X0oNIUcF.js";import{t as r}from"./vendor-Bd-5Ya9C.js";import{J as i,M as a,an as o,at as s,it as c,k as l,m as u,ot as d}from"./index-D2LrA6v6.js";import{a as f,c as p,l as m,n as h,o as g,u as _}from"./KeyboardShortcutsContext-CfYRiurd.js";import{i as v}from"./routing-GE3qy379.js";var y=e(t());function b({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m19.5 8.25-7.5 7.5-7.5-7.5`}))}var x=y.forwardRef(b);function S({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m4.5 15.75 7.5-7.5 7.5 7.5`}))}var C=y.forwardRef(S);function w(){let e=v();return i({"nav:external":(0,y.useCallback)(({url:t,cancelFallback:n})=>{n(),e.push(t)},[e]),"nav:push":(0,y.useCallback)(({path:t})=>{e.push(t)},[e])}),null}function T(e,t){let n=e.match(/\{(\w+),\s*plural,\s*/);if(!n)return e;let r=t[n[1]];if(r===void 0)return e;let i=n[0].length+n.index,a=1,o=i;for(let t=i;t<e.length;t++)if(e[t]===`{`)a++;else if(e[t]===`}`&&(a--,a===0)){o=t;break}let s=e.substring(i,o),c={},l=/(?:=(\d+)|(\w+))\s*\{([^}]+)\}/g,u;for(;(u=l.exec(s))!==null;){let[,e,t,n]=u,r=e===void 0?t:`=${e}`;c[r]=n}let d=c[`=${r}`];if(d!==void 0){let t=d.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}let f=c.other;if(f!==void 0){let t=f.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}return e}function E(e,t){let n=T(e,t);return Object.entries(t).forEach(([e,t])=>{n=n.replace(RegExp(`\\{\\{${e}\\}\\}`,`g`),String(t))}),n}function D(){let{i18n:e}=n();return(0,y.useMemo)(()=>({t:(t,n,r)=>{let i=e.getResourceBundle(e.language,`translation`)?.[t]?.[n];return i?r&&typeof i==`string`?E(i,r):i:`${t}.${n}`}}),[e,e.language])}var O=r();function k({children:e}){return(0,O.jsx)(d,{translationManager:D(),children:(0,O.jsx)(c,{children:(0,O.jsx)(s,{children:(0,O.jsx)(u,{children:(0,O.jsx)(h,{children:(0,O.jsxs)(a,{children:[(0,O.jsx)(w,{}),e]})})})})})})}function A({className:e=``}){let{t}=n(),r=(e,n)=>t(`CookieBanner.${e}`,n),[i,a]=(0,y.useState)(!1),[o,s]=(0,y.useState)(!1),[c,l]=(0,y.useState)(!1),[u,d]=(0,y.useState)(`GENERAL`),[h,v]=(0,y.useState)({necessary:!0,analytics:!1,marketing:!1,preferences:!1});(0,y.useEffect)(()=>{(async()=>{if(m()){a(!0);try{let[e,t]=await Promise.all([g(),f()]);d(e?`GDPR`:t?`CCPA`:`GENERAL`)}catch(e){console.error(`Failed to detect region:`,e),d(`GENERAL`)}}})()},[]);let b=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!0,marketing:!0,preferences:!0})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},S=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!1,marketing:!1,preferences:!1})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},w=async()=>{l(!0);try{await Promise.resolve(p(h)),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},T=e=>{e!==`necessary`&&v(t=>({...t,[e]:!t[e]}))},E=()=>{switch(u){case`GDPR`:return{title:r(`gdprTitle`),description:r(`gdprDescription`),learnMore:r(`gdprLearnMore`)};case`CCPA`:return{title:r(`ccpaTitle`),description:r(`ccpaDescription`),learnMore:r(`ccpaLearnMore`)};default:return{title:r(`generalTitle`),description:r(`generalDescription`),learnMore:r(`generalLearnMore`)}}};if(!i)return null;let D=E();return(0,O.jsx)(`div`,{className:e,style:{position:`fixed`,bottom:0,left:0,right:0,zIndex:50,backgroundColor:`var(--semiont-bg-primary)`,borderTop:`1px solid var(--semiont-border-primary)`,boxShadow:`var(--semiont-shadow-lg)`},children:(0,O.jsx)(`div`,{style:{maxWidth:`80rem`,margin:`0 auto`,padding:`1rem 1.5rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:`1.5rem`,flexWrap:`wrap`},children:[(0,O.jsxs)(`div`,{style:{flex:1,minWidth:`300px`},children:[(0,O.jsx)(`h3`,{style:{fontSize:`1.125rem`,fontWeight:600,color:`var(--semiont-text-primary)`,marginBottom:`0.5rem`},children:D.title}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,color:`var(--semiont-text-secondary)`,marginBottom:`0.25rem`},children:D.description}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:D.learnMore})]}),(0,O.jsxs)(`div`,{style:{display:`flex`,gap:`0.75rem`,alignItems:`center`,flexWrap:`wrap`},children:[(0,O.jsxs)(`button`,{type:`button`,onClick:()=>s(!o),className:`semiont-button--secondary`,style:{display:`flex`,alignItems:`center`,gap:`0.25rem`},children:[r(`customize`),o?(0,O.jsx)(C,{style:{width:`1rem`,height:`1rem`}}):(0,O.jsx)(x,{style:{width:`1rem`,height:`1rem`}})]}),u!==`GDPR`&&(0,O.jsx)(`button`,{type:`button`,onClick:S,disabled:c,className:`semiont-button--secondary`,children:r(c?`saving`:`rejectAll`)}),(0,O.jsx)(`button`,{type:`button`,onClick:b,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`acceptAll`)})]})]}),o&&(0,O.jsx)(`div`,{style:{borderTop:`1px solid var(--semiont-border-primary)`,paddingTop:`1rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsx)(`h4`,{style:{fontSize:`1rem`,fontWeight:500,color:`var(--semiont-text-primary)`},children:r(`cookiePreferences`)}),(0,O.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`0.75rem`},children:_.map(e=>(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:`0.75rem`},children:[(0,O.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,height:`1.25rem`},children:(0,O.jsx)(`input`,{id:`cookie-${e.id}`,type:`checkbox`,checked:h[e.id]||!1,onChange:()=>T(e.id),disabled:e.required||c,style:{accentColor:`var(--semiont-color-primary-600, #2563eb)`}})}),(0,O.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,O.jsxs)(`label`,{htmlFor:`cookie-${e.id}`,style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,fontWeight:500,color:`var(--semiont-text-primary)`,cursor:`pointer`},children:[e.name,e.required&&(0,O.jsx)(`span`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`,marginLeft:`0.25rem`},children:r(`required`)})]}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-secondary)`,marginTop:`0.25rem`},children:e.description}),(0,O.jsxs)(`details`,{style:{marginTop:`0.25rem`},children:[(0,O.jsx)(`summary`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-color-primary-600, #2563eb)`,cursor:`pointer`},children:r(`viewCookies`)}),(0,O.jsx)(`div`,{style:{marginTop:`0.25rem`,fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:e.cookies.join(`, `)})]})]})]},e.id))}),(0,O.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:`0.75rem`,paddingTop:`1rem`},children:[(0,O.jsx)(`button`,{type:`button`,onClick:()=>s(!1),className:`semiont-button--secondary`,children:r(`cancel`)}),(0,O.jsx)(`button`,{type:`button`,onClick:w,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`savePreferences`)})]})]})})]})})})}function j(){return(0,O.jsxs)(k,{children:[(0,O.jsx)(l,{}),(0,O.jsx)(o,{}),(0,O.jsx)(A,{})]})}export{j as default};
2
+ //# sourceMappingURL=layout-CIBMGRGg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-5FLtbdhm.js","names":["ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/ChevronDownIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ChevronUpIcon.js","../../src/components/knowledge/NavigationHandler.tsx","../../src/hooks/useMergedTranslationManager.ts","../../src/app/providers.tsx","../../src/components/CookieBanner.tsx","../../src/app/[locale]/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction ChevronDownIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m19.5 8.25-7.5 7.5-7.5-7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronDownIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ChevronUpIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m4.5 15.75 7.5-7.5 7.5 7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronUpIcon);\nexport default ForwardRef;","import { useCallback } from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { useEventSubscriptions } from '@semiont/react-ui';\n\n/**\n * NavigationHandler - Connects NavigationEventBus to Next.js router\n *\n * This component subscribes to navigation events from @semiont/react-ui\n * components and handles them using Next.js client-side routing.\n *\n * Benefits:\n * - Client-side navigation (no page reload)\n * - Preserves React state\n * - Faster navigation\n * - Better UX\n *\n * Must be mounted in app layout to handle all navigation requests.\n */\nexport function NavigationHandler() {\n const router = useRouter();\n\n // Handle external navigation events\n const handleExternalNavigate = useCallback(({ url, cancelFallback }: { url: string; resourceId?: string; cancelFallback: () => void }) => {\n cancelFallback(); // Prevent window.location fallback since we're handling with client-side routing\n router.push(url);\n }, [router]);\n\n // Handle router push events\n const handleRouterPush = useCallback(({ path }: { path: string; reason?: string }) => {\n router.push(path);\n }, [router]);\n\n useEventSubscriptions({\n 'nav:external': handleExternalNavigate,\n 'nav:push': handleRouterPush,\n });\n\n // This component only manages navigation, doesn't render anything\n return null;\n}\n","import { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { TranslationManager } from '@semiont/react-ui';\n\ntype Messages = Record<string, Record<string, string>>;\n\n/**\n * Process ICU MessageFormat plural syntax.\n * Supports: `{count, plural, =0 {text} =1 {text} other {text}}` with `#` as\n * the count placeholder inside each branch.\n *\n * Mirrors the reference implementation in\n * `packages/react-ui/src/contexts/TranslationContext.tsx`. Kept in sync\n * deliberately — diverging the two managers is what produced the\n * literal-plural-format render bug in the Tags panel.\n */\nexport function processPluralFormat(text: string, params: Record<string, unknown>): string {\n const pluralMatch = text.match(/\\{(\\w+),\\s*plural,\\s*/);\n if (!pluralMatch) return text;\n\n const paramName = pluralMatch[1]!;\n const count = params[paramName];\n if (count === undefined) return text;\n\n // Find the matching closing brace by counting nested pairs.\n const startPos = pluralMatch[0].length + pluralMatch.index!;\n let braceCount = 1;\n let endPos = startPos;\n for (let i = startPos; i < text.length; i++) {\n if (text[i] === '{') braceCount++;\n else if (text[i] === '}') {\n braceCount--;\n if (braceCount === 0) { endPos = i; break; }\n }\n }\n\n const pluralCases = text.substring(startPos, endPos);\n const cases: Record<string, string> = {};\n const caseRegex = /(?:=(\\d+)|(\\w+))\\s*\\{([^}]+)\\}/g;\n let caseMatch;\n while ((caseMatch = caseRegex.exec(pluralCases)) !== null) {\n const [, exactNumber, keyword, textContent] = caseMatch;\n const key = exactNumber !== undefined ? `=${exactNumber}` : keyword!;\n cases[key] = textContent!;\n }\n\n const exactMatch = cases[`=${count}`];\n if (exactMatch !== undefined) {\n const replaced = exactMatch.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n const otherCase = cases['other'];\n if (otherCase !== undefined) {\n const replaced = otherCase.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n return text;\n}\n\n/**\n * Run a translation string through the standard interpolation pipeline:\n * plural format first (since it may consume more of the string), then\n * `{{paramKey}}` parameter substitution. Exported for unit testing.\n */\nexport function interpolateTranslation(\n translation: string,\n params: Record<string, unknown>,\n): string {\n let result = processPluralFormat(translation, params);\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n}\n\n/**\n * Translation Manager for Frontend\n *\n * Wraps react-i18next. The messages JSON (loaded by i18next-http-backend) has\n * the same flat namespace structure: { \"Namespace\": { \"key\": \"value\" } }.\n * TranslationManager.t(namespace, key) maps directly to this structure.\n *\n * Interpolation supports two syntaxes, in this precedence order:\n *\n * 1. ICU MessageFormat plural — `{count, plural, =0 {…} =1 {…} other {…}}`\n * — used for count-sensitive strings like \"1 category selected\" /\n * \"3 categories selected\".\n * 2. Double-brace parameter substitution — `{{paramKey}}` — used for\n * everything else (`{{mode}}`, `{{delay}}`, etc.).\n *\n * The two managers (this one and the reference in\n * `@semiont/react-ui/contexts/TranslationContext`) implement the same\n * interpolation contract; keep them aligned when changing either.\n */\nexport function useMergedTranslationManager(): TranslationManager {\n const { i18n } = useTranslation();\n\n return useMemo(() => {\n return {\n t: (namespace: string, key: string, params?: Record<string, unknown>): string => {\n const messages = i18n.getResourceBundle(i18n.language, 'translation') as Messages | undefined;\n const translation = messages?.[namespace]?.[key];\n\n if (!translation) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(`Translation not found: ${namespace}.${key} (locale: ${i18n.language})`);\n }\n return `${namespace}.${key}`;\n }\n\n if (params && typeof translation === 'string') {\n return interpolateTranslation(translation, params);\n }\n\n return translation;\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [i18n, i18n.language]);\n}\n","import React from 'react';\nimport {\n ToastProvider,\n LiveRegionProvider,\n TranslationProvider,\n ThemeProvider,\n SemiontProvider,\n} from '@semiont/react-ui';\nimport { KeyboardShortcutsProvider } from '@/contexts/KeyboardShortcutsContext';\nimport { NavigationHandler } from '@/components/knowledge/NavigationHandler';\nimport { useMergedTranslationManager } from '@/hooks/useMergedTranslationManager';\n\n/**\n * Root Provider Composition for Semiont Frontend.\n *\n * Wires up GLOBAL contexts that every page needs.\n *\n * The module-scoped `SemiontBrowser` singleton (KB list, active KB,\n * per-KB SemiontSession) is made available via `<SemiontProvider>` at\n * the app root — mounting it here is cheap because the singleton itself\n * survives every React re-render and route change.\n *\n * Auth-dependent UI (ProtectedErrorBoundary, SessionExpiredModal,\n * PermissionDeniedModal) is bundled in `AuthShell` and mounted only in\n * protected layouts (know/, admin/, moderate/, auth/welcome/). Pre-app\n * routes (landing, OAuth flow) intentionally do NOT mount AuthShell —\n * they have no session UI.\n *\n * The `SemiontClient` is owned by the per-KB `SemiontSession`, which\n * `SemiontBrowser` constructs on demand. Components read\n * `useObservable(useSemiont().activeSession$)?.client`.\n *\n * The event bus lives inside the client (owned by `SemiontSession`).\n * Components emit via `session?.emit(...)` and subscribe via\n * `useEventSubscription[s]`.\n *\n * Provider order — outer to inner:\n * 1. TranslationProvider — i18n\n * 2. SemiontProvider — SemiontBrowser singleton\n * 3. ToastProvider — toast notifications\n * 4. LiveRegionProvider — a11y live region\n * 5. KeyboardShortcutsProvider — keyboard shortcuts\n * 6. ThemeProvider — theme\n * + NavigationHandler\n */\nexport function Providers({ children }: { children: React.ReactNode }) {\n const translationManager = useMergedTranslationManager();\n\n return (\n <TranslationProvider translationManager={translationManager}>\n <SemiontProvider>\n <ToastProvider>\n <LiveRegionProvider>\n <KeyboardShortcutsProvider>\n <ThemeProvider>\n <NavigationHandler />\n {children}\n </ThemeProvider>\n </KeyboardShortcutsProvider>\n </LiveRegionProvider>\n </ToastProvider>\n </SemiontProvider>\n </TranslationProvider>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n setCookieConsent,\n shouldShowBanner,\n COOKIE_CATEGORIES,\n CookieConsent,\n isCCPAApplicable,\n isGDPRApplicable,\n type CookieCategory\n} from '@/lib/cookies';\nimport { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';\n\ninterface CookieBannerProps {\n className?: string;\n}\n\nexport function CookieBanner({ className = '' }: CookieBannerProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`CookieBanner.${k}`, p as any) as string;\n const [isVisible, setIsVisible] = useState(false);\n const [showDetails, setShowDetails] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [region, setRegion] = useState<'GDPR' | 'CCPA' | 'GENERAL'>('GENERAL');\n const [consent, setConsent] = useState<Partial<CookieConsent>>({\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n });\n\n useEffect(() => {\n const checkVisibility = async () => {\n if (shouldShowBanner()) {\n setIsVisible(true);\n\n try {\n // Determine applicable regulation\n const [isGDPR, isCCPA] = await Promise.all([\n isGDPRApplicable(),\n isCCPAApplicable()\n ]);\n\n if (isGDPR) {\n setRegion('GDPR');\n } else if (isCCPA) {\n setRegion('CCPA');\n } else {\n setRegion('GENERAL');\n }\n } catch (error) {\n // If region detection fails, default to GENERAL\n console.error('Failed to detect region:', error);\n setRegion('GENERAL');\n }\n }\n };\n\n checkVisibility();\n }, []);\n\n const handleAcceptAll = async () => {\n setIsLoading(true);\n\n try {\n const fullConsent = {\n necessary: true,\n analytics: true,\n marketing: true,\n preferences: true\n };\n\n await Promise.resolve(setCookieConsent(fullConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleRejectAll = async () => {\n setIsLoading(true);\n\n try {\n const minimalConsent = {\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n };\n\n await Promise.resolve(setCookieConsent(minimalConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSavePreferences = async () => {\n setIsLoading(true);\n\n try {\n await Promise.resolve(setCookieConsent(consent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleCategoryToggle = (categoryId: keyof Omit<CookieConsent, 'timestamp' | 'version'>) => {\n if (categoryId === 'necessary') return; // Can't toggle necessary cookies\n\n setConsent(prev => ({\n ...prev,\n [categoryId]: !prev[categoryId]\n }));\n };\n\n const getBannerText = () => {\n switch (region) {\n case 'GDPR':\n return {\n title: t('gdprTitle'),\n description: t('gdprDescription'),\n learnMore: t('gdprLearnMore')\n };\n case 'CCPA':\n return {\n title: t('ccpaTitle'),\n description: t('ccpaDescription'),\n learnMore: t('ccpaLearnMore')\n };\n default:\n return {\n title: t('generalTitle'),\n description: t('generalDescription'),\n learnMore: t('generalLearnMore')\n };\n }\n };\n\n if (!isVisible) return null;\n\n const bannerText = getBannerText();\n\n return (\n <div\n className={className}\n style={{\n position: 'fixed',\n bottom: 0,\n left: 0,\n right: 0,\n zIndex: 50,\n backgroundColor: 'var(--semiont-bg-primary)',\n borderTop: '1px solid var(--semiont-border-primary)',\n boxShadow: 'var(--semiont-shadow-lg)',\n }}\n >\n <div style={{ maxWidth: '80rem', margin: '0 auto', padding: '1rem 1.5rem' }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Main banner content */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '1.5rem', flexWrap: 'wrap' }}>\n <div style={{ flex: 1, minWidth: '300px' }}>\n <h3 style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n color: 'var(--semiont-text-primary)',\n marginBottom: '0.5rem',\n }}>\n {bannerText.title}\n </h3>\n <p style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n color: 'var(--semiont-text-secondary)',\n marginBottom: '0.25rem',\n }}>\n {bannerText.description}\n </p>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {bannerText.learnMore}\n </p>\n </div>\n\n {/* Action buttons */}\n <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(!showDetails)}\n className=\"semiont-button--secondary\"\n style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}\n >\n {t('customize')}\n {showDetails ? (\n <ChevronUpIcon style={{ width: '1rem', height: '1rem' }} />\n ) : (\n <ChevronDownIcon style={{ width: '1rem', height: '1rem' }} />\n )}\n </button>\n\n {region !== 'GDPR' && (\n <button\n type=\"button\"\n onClick={handleRejectAll}\n disabled={isLoading}\n className=\"semiont-button--secondary\"\n >\n {isLoading ? t('saving') : t('rejectAll')}\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={handleAcceptAll}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('acceptAll')}\n </button>\n </div>\n </div>\n\n {/* Detailed preferences */}\n {showDetails && (\n <div style={{\n borderTop: '1px solid var(--semiont-border-primary)',\n paddingTop: '1rem',\n }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <h4 style={{\n fontSize: '1rem',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n }}>\n {t('cookiePreferences')}\n </h4>\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>\n {COOKIE_CATEGORIES.map((category: CookieCategory) => (\n <div key={category.id} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.75rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', height: '1.25rem' }}>\n <input\n id={`cookie-${category.id}`}\n type=\"checkbox\"\n checked={consent[category.id] || false}\n onChange={() => handleCategoryToggle(category.id)}\n disabled={category.required || isLoading}\n style={{ accentColor: 'var(--semiont-color-primary-600, #2563eb)' }}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <label\n htmlFor={`cookie-${category.id}`}\n style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n cursor: 'pointer',\n }}\n >\n {category.name}\n {category.required && (\n <span style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n marginLeft: '0.25rem',\n }}>\n {t('required')}\n </span>\n )}\n </label>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-secondary)',\n marginTop: '0.25rem',\n }}>\n {category.description}\n </p>\n <details style={{ marginTop: '0.25rem' }}>\n <summary style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-color-primary-600, #2563eb)',\n cursor: 'pointer',\n }}>\n {t('viewCookies')}\n </summary>\n <div style={{\n marginTop: '0.25rem',\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {category.cookies.join(', ')}\n </div>\n </details>\n </div>\n </div>\n ))}\n </div>\n\n <div style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '0.75rem',\n paddingTop: '1rem',\n }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(false)}\n className=\"semiont-button--secondary\"\n >\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('savePreferences')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default CookieBanner;\n","import { Outlet } from 'react-router-dom';\nimport { Providers } from '../providers';\nimport { CookieBanner } from '@/components/CookieBanner';\nimport { SkipLinks } from '@semiont/react-ui';\n\n/**\n * Locale Layout — root layout for all /:locale/* routes.\n *\n * Mounts only auth-independent providers. Auth-dependent providers\n * (KnowledgeBaseProvider, AuthProvider, SessionProvider, modals)\n * are mounted via AuthShell in protected layouts (know/, admin/,\n * moderate/, auth/welcome/).\n */\nexport default function LocaleLayout() {\n return (\n <Providers>\n <SkipLinks />\n <Outlet />\n <CookieBanner />\n </Providers>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"layout-CIBMGRGg.js","names":["ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/ChevronDownIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ChevronUpIcon.js","../../src/components/knowledge/NavigationHandler.tsx","../../src/hooks/useMergedTranslationManager.ts","../../src/app/providers.tsx","../../src/components/CookieBanner.tsx","../../src/app/[locale]/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction ChevronDownIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m19.5 8.25-7.5 7.5-7.5-7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronDownIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ChevronUpIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m4.5 15.75 7.5-7.5 7.5 7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronUpIcon);\nexport default ForwardRef;","import { useCallback } from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { useEventSubscriptions } from '@semiont/react-ui';\n\n/**\n * NavigationHandler - Connects NavigationEventBus to Next.js router\n *\n * This component subscribes to navigation events from @semiont/react-ui\n * components and handles them using Next.js client-side routing.\n *\n * Benefits:\n * - Client-side navigation (no page reload)\n * - Preserves React state\n * - Faster navigation\n * - Better UX\n *\n * Must be mounted in app layout to handle all navigation requests.\n */\nexport function NavigationHandler() {\n const router = useRouter();\n\n // Handle external navigation events\n const handleExternalNavigate = useCallback(({ url, cancelFallback }: { url: string; resourceId?: string; cancelFallback: () => void }) => {\n cancelFallback(); // Prevent window.location fallback since we're handling with client-side routing\n router.push(url);\n }, [router]);\n\n // Handle router push events\n const handleRouterPush = useCallback(({ path }: { path: string; reason?: string }) => {\n router.push(path);\n }, [router]);\n\n useEventSubscriptions({\n 'nav:external': handleExternalNavigate,\n 'nav:push': handleRouterPush,\n });\n\n // This component only manages navigation, doesn't render anything\n return null;\n}\n","import { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { TranslationManager } from '@semiont/react-ui';\n\ntype Messages = Record<string, Record<string, string>>;\n\n/**\n * Process ICU MessageFormat plural syntax.\n * Supports: `{count, plural, =0 {text} =1 {text} other {text}}` with `#` as\n * the count placeholder inside each branch.\n *\n * Mirrors the reference implementation in\n * `packages/react-ui/src/contexts/TranslationContext.tsx`. Kept in sync\n * deliberately — diverging the two managers is what produced the\n * literal-plural-format render bug in the Tags panel.\n */\nexport function processPluralFormat(text: string, params: Record<string, unknown>): string {\n const pluralMatch = text.match(/\\{(\\w+),\\s*plural,\\s*/);\n if (!pluralMatch) return text;\n\n const paramName = pluralMatch[1]!;\n const count = params[paramName];\n if (count === undefined) return text;\n\n // Find the matching closing brace by counting nested pairs.\n const startPos = pluralMatch[0].length + pluralMatch.index!;\n let braceCount = 1;\n let endPos = startPos;\n for (let i = startPos; i < text.length; i++) {\n if (text[i] === '{') braceCount++;\n else if (text[i] === '}') {\n braceCount--;\n if (braceCount === 0) { endPos = i; break; }\n }\n }\n\n const pluralCases = text.substring(startPos, endPos);\n const cases: Record<string, string> = {};\n const caseRegex = /(?:=(\\d+)|(\\w+))\\s*\\{([^}]+)\\}/g;\n let caseMatch;\n while ((caseMatch = caseRegex.exec(pluralCases)) !== null) {\n const [, exactNumber, keyword, textContent] = caseMatch;\n const key = exactNumber !== undefined ? `=${exactNumber}` : keyword!;\n cases[key] = textContent!;\n }\n\n const exactMatch = cases[`=${count}`];\n if (exactMatch !== undefined) {\n const replaced = exactMatch.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n const otherCase = cases['other'];\n if (otherCase !== undefined) {\n const replaced = otherCase.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n return text;\n}\n\n/**\n * Run a translation string through the standard interpolation pipeline:\n * plural format first (since it may consume more of the string), then\n * `{{paramKey}}` parameter substitution. Exported for unit testing.\n */\nexport function interpolateTranslation(\n translation: string,\n params: Record<string, unknown>,\n): string {\n let result = processPluralFormat(translation, params);\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n}\n\n/**\n * Translation Manager for Frontend\n *\n * Wraps react-i18next. The messages JSON (loaded by i18next-http-backend) has\n * the same flat namespace structure: { \"Namespace\": { \"key\": \"value\" } }.\n * TranslationManager.t(namespace, key) maps directly to this structure.\n *\n * Interpolation supports two syntaxes, in this precedence order:\n *\n * 1. ICU MessageFormat plural — `{count, plural, =0 {…} =1 {…} other {…}}`\n * — used for count-sensitive strings like \"1 category selected\" /\n * \"3 categories selected\".\n * 2. Double-brace parameter substitution — `{{paramKey}}` — used for\n * everything else (`{{mode}}`, `{{delay}}`, etc.).\n *\n * The two managers (this one and the reference in\n * `@semiont/react-ui/contexts/TranslationContext`) implement the same\n * interpolation contract; keep them aligned when changing either.\n */\nexport function useMergedTranslationManager(): TranslationManager {\n const { i18n } = useTranslation();\n\n return useMemo(() => {\n return {\n t: (namespace: string, key: string, params?: Record<string, unknown>): string => {\n const messages = i18n.getResourceBundle(i18n.language, 'translation') as Messages | undefined;\n const translation = messages?.[namespace]?.[key];\n\n if (!translation) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(`Translation not found: ${namespace}.${key} (locale: ${i18n.language})`);\n }\n return `${namespace}.${key}`;\n }\n\n if (params && typeof translation === 'string') {\n return interpolateTranslation(translation, params);\n }\n\n return translation;\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [i18n, i18n.language]);\n}\n","import React from 'react';\nimport {\n ToastProvider,\n LiveRegionProvider,\n TranslationProvider,\n ThemeProvider,\n SemiontProvider,\n} from '@semiont/react-ui';\nimport { KeyboardShortcutsProvider } from '@/contexts/KeyboardShortcutsContext';\nimport { NavigationHandler } from '@/components/knowledge/NavigationHandler';\nimport { useMergedTranslationManager } from '@/hooks/useMergedTranslationManager';\n\n/**\n * Root Provider Composition for Semiont Frontend.\n *\n * Wires up GLOBAL contexts that every page needs.\n *\n * The module-scoped `SemiontBrowser` singleton (KB list, active KB,\n * per-KB SemiontSession) is made available via `<SemiontProvider>` at\n * the app root — mounting it here is cheap because the singleton itself\n * survives every React re-render and route change.\n *\n * Auth-dependent UI (ProtectedErrorBoundary, SessionExpiredModal,\n * PermissionDeniedModal) is bundled in `AuthShell` and mounted only in\n * protected layouts (know/, admin/, moderate/, auth/welcome/). Pre-app\n * routes (landing, OAuth flow) intentionally do NOT mount AuthShell —\n * they have no session UI.\n *\n * The `SemiontClient` is owned by the per-KB `SemiontSession`, which\n * `SemiontBrowser` constructs on demand. Components read\n * `useObservable(useSemiont().activeSession$)?.client`.\n *\n * The event bus lives inside the client (owned by `SemiontSession`).\n * Components emit via `session?.emit(...)` and subscribe via\n * `useEventSubscription[s]`.\n *\n * Provider order — outer to inner:\n * 1. TranslationProvider — i18n\n * 2. SemiontProvider — SemiontBrowser singleton\n * 3. ToastProvider — toast notifications\n * 4. LiveRegionProvider — a11y live region\n * 5. KeyboardShortcutsProvider — keyboard shortcuts\n * 6. ThemeProvider — theme\n * + NavigationHandler\n */\nexport function Providers({ children }: { children: React.ReactNode }) {\n const translationManager = useMergedTranslationManager();\n\n return (\n <TranslationProvider translationManager={translationManager}>\n <SemiontProvider>\n <ToastProvider>\n <LiveRegionProvider>\n <KeyboardShortcutsProvider>\n <ThemeProvider>\n <NavigationHandler />\n {children}\n </ThemeProvider>\n </KeyboardShortcutsProvider>\n </LiveRegionProvider>\n </ToastProvider>\n </SemiontProvider>\n </TranslationProvider>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n setCookieConsent,\n shouldShowBanner,\n COOKIE_CATEGORIES,\n CookieConsent,\n isCCPAApplicable,\n isGDPRApplicable,\n type CookieCategory\n} from '@/lib/cookies';\nimport { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';\n\ninterface CookieBannerProps {\n className?: string;\n}\n\nexport function CookieBanner({ className = '' }: CookieBannerProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`CookieBanner.${k}`, p as any) as string;\n const [isVisible, setIsVisible] = useState(false);\n const [showDetails, setShowDetails] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [region, setRegion] = useState<'GDPR' | 'CCPA' | 'GENERAL'>('GENERAL');\n const [consent, setConsent] = useState<Partial<CookieConsent>>({\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n });\n\n useEffect(() => {\n const checkVisibility = async () => {\n if (shouldShowBanner()) {\n setIsVisible(true);\n\n try {\n // Determine applicable regulation\n const [isGDPR, isCCPA] = await Promise.all([\n isGDPRApplicable(),\n isCCPAApplicable()\n ]);\n\n if (isGDPR) {\n setRegion('GDPR');\n } else if (isCCPA) {\n setRegion('CCPA');\n } else {\n setRegion('GENERAL');\n }\n } catch (error) {\n // If region detection fails, default to GENERAL\n console.error('Failed to detect region:', error);\n setRegion('GENERAL');\n }\n }\n };\n\n checkVisibility();\n }, []);\n\n const handleAcceptAll = async () => {\n setIsLoading(true);\n\n try {\n const fullConsent = {\n necessary: true,\n analytics: true,\n marketing: true,\n preferences: true\n };\n\n await Promise.resolve(setCookieConsent(fullConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleRejectAll = async () => {\n setIsLoading(true);\n\n try {\n const minimalConsent = {\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n };\n\n await Promise.resolve(setCookieConsent(minimalConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSavePreferences = async () => {\n setIsLoading(true);\n\n try {\n await Promise.resolve(setCookieConsent(consent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleCategoryToggle = (categoryId: keyof Omit<CookieConsent, 'timestamp' | 'version'>) => {\n if (categoryId === 'necessary') return; // Can't toggle necessary cookies\n\n setConsent(prev => ({\n ...prev,\n [categoryId]: !prev[categoryId]\n }));\n };\n\n const getBannerText = () => {\n switch (region) {\n case 'GDPR':\n return {\n title: t('gdprTitle'),\n description: t('gdprDescription'),\n learnMore: t('gdprLearnMore')\n };\n case 'CCPA':\n return {\n title: t('ccpaTitle'),\n description: t('ccpaDescription'),\n learnMore: t('ccpaLearnMore')\n };\n default:\n return {\n title: t('generalTitle'),\n description: t('generalDescription'),\n learnMore: t('generalLearnMore')\n };\n }\n };\n\n if (!isVisible) return null;\n\n const bannerText = getBannerText();\n\n return (\n <div\n className={className}\n style={{\n position: 'fixed',\n bottom: 0,\n left: 0,\n right: 0,\n zIndex: 50,\n backgroundColor: 'var(--semiont-bg-primary)',\n borderTop: '1px solid var(--semiont-border-primary)',\n boxShadow: 'var(--semiont-shadow-lg)',\n }}\n >\n <div style={{ maxWidth: '80rem', margin: '0 auto', padding: '1rem 1.5rem' }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Main banner content */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '1.5rem', flexWrap: 'wrap' }}>\n <div style={{ flex: 1, minWidth: '300px' }}>\n <h3 style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n color: 'var(--semiont-text-primary)',\n marginBottom: '0.5rem',\n }}>\n {bannerText.title}\n </h3>\n <p style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n color: 'var(--semiont-text-secondary)',\n marginBottom: '0.25rem',\n }}>\n {bannerText.description}\n </p>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {bannerText.learnMore}\n </p>\n </div>\n\n {/* Action buttons */}\n <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(!showDetails)}\n className=\"semiont-button--secondary\"\n style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}\n >\n {t('customize')}\n {showDetails ? (\n <ChevronUpIcon style={{ width: '1rem', height: '1rem' }} />\n ) : (\n <ChevronDownIcon style={{ width: '1rem', height: '1rem' }} />\n )}\n </button>\n\n {region !== 'GDPR' && (\n <button\n type=\"button\"\n onClick={handleRejectAll}\n disabled={isLoading}\n className=\"semiont-button--secondary\"\n >\n {isLoading ? t('saving') : t('rejectAll')}\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={handleAcceptAll}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('acceptAll')}\n </button>\n </div>\n </div>\n\n {/* Detailed preferences */}\n {showDetails && (\n <div style={{\n borderTop: '1px solid var(--semiont-border-primary)',\n paddingTop: '1rem',\n }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <h4 style={{\n fontSize: '1rem',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n }}>\n {t('cookiePreferences')}\n </h4>\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>\n {COOKIE_CATEGORIES.map((category: CookieCategory) => (\n <div key={category.id} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.75rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', height: '1.25rem' }}>\n <input\n id={`cookie-${category.id}`}\n type=\"checkbox\"\n checked={consent[category.id] || false}\n onChange={() => handleCategoryToggle(category.id)}\n disabled={category.required || isLoading}\n style={{ accentColor: 'var(--semiont-color-primary-600, #2563eb)' }}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <label\n htmlFor={`cookie-${category.id}`}\n style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n cursor: 'pointer',\n }}\n >\n {category.name}\n {category.required && (\n <span style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n marginLeft: '0.25rem',\n }}>\n {t('required')}\n </span>\n )}\n </label>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-secondary)',\n marginTop: '0.25rem',\n }}>\n {category.description}\n </p>\n <details style={{ marginTop: '0.25rem' }}>\n <summary style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-color-primary-600, #2563eb)',\n cursor: 'pointer',\n }}>\n {t('viewCookies')}\n </summary>\n <div style={{\n marginTop: '0.25rem',\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {category.cookies.join(', ')}\n </div>\n </details>\n </div>\n </div>\n ))}\n </div>\n\n <div style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '0.75rem',\n paddingTop: '1rem',\n }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(false)}\n className=\"semiont-button--secondary\"\n >\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('savePreferences')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default CookieBanner;\n","import { Outlet } from 'react-router-dom';\nimport { Providers } from '../providers';\nimport { CookieBanner } from '@/components/CookieBanner';\nimport { SkipLinks } from '@semiont/react-ui';\n\n/**\n * Locale Layout — root layout for all /:locale/* routes.\n *\n * Mounts only auth-independent providers. Auth-dependent providers\n * (KnowledgeBaseProvider, AuthProvider, SessionProvider, modals)\n * are mounted via AuthShell in protected layouts (know/, admin/,\n * moderate/, auth/welcome/).\n */\nexport default function LocaleLayout() {\n return (\n <Providers>\n <SkipLinks />\n <Outlet />\n <CookieBanner />\n </Providers>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{i as t,t as n}from"./i18n-X0oNIUcF.js";import{t as r}from"./vendor-Bd-5Ya9C.js";import{J as i,O as a,Q as o,f as s,rn as c,st as l,u}from"./index-DQSZfVR2.js";import{t as d}from"./KeyboardShortcutsContext-4ZRypoQr.js";import{n as f,t as p}from"./CookiePreferences-CQa2Mwuc.js";import{t as m}from"./ArrowsRightLeftIcon-C7eE1lVN.js";import{n as h,t as g}from"./ChevronLeftIcon-BItMAxjy.js";import{t as _}from"./CommandLineIcon-BxjxKXBi.js";import{i as v,r as y,t as b}from"./routing-BcOlOpMI.js";import{n as x,t as S}from"./routing-1L7p7DNA.js";var C=e(t());function w({title:e,titleId:t,...n},r){return C.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?C.createElement(`title`,{id:t},e):null,C.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z`}))}var T=C.forwardRef(w),E=r();function D({href:e,to:t,...n}){return(0,E.jsx)(b,{to:e??``,...n})}function O({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:o}=n(),s=(e,t)=>o(`Administration.${e}`,t),{t:c}=n(),l=(e,t)=>c(`Sidebar.${e}`,t),u=y();i({"shell:sidebar-toggle":(0,C.useCallback)(()=>{t()},[t])});let d=[{name:s(`users`),href:`/admin/users`,icon:T,description:s(`usersDescription`)},{name:s(`oauthSettings`),href:`/admin/security`,icon:f,description:s(`oauthSettingsDescription`)},{name:s(`exchange`),href:`/admin/exchange`,icon:m,description:s(`exchangeDescription`)},{name:s(`devops`),href:`/admin/devops`,icon:_,description:s(`devopsDescription`)}];return(0,E.jsx)(a,{title:s(`title`),items:d,currentPath:u,LinkComponent:D,...r&&{dropdownContent:r},isCollapsed:e,icons:{chevronLeft:g,bars:h},collapseSidebarLabel:l(`collapseSidebar`),expandSidebarLabel:l(`expandSidebar`)})}function k(){let{t:e}=n(),t=(0,C.useContext)(d),r=o(l().activeSession$),i=o(r?.user$),a=r?.kb??null,f=v();return a?(0,E.jsxs)(`div`,{className:`min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col`,children:[(0,E.jsxs)(`div`,{className:`flex flex-1`,children:[(0,E.jsx)(s,{Link:S,routes:x,t:t=>e(`Navigation.${t}`),tHome:t=>e(`Home.${t}`),brandingLink:`/`,collapsible:!0,storageKey:`admin-sidebar-collapsed`,isAuthenticated:!!i,isAdmin:i?.isAdmin??!1,isModerator:i?.isModerator??!1,children:(e,t,n)=>(0,E.jsx)(O,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})}),(0,E.jsx)(`main`,{className:`flex-1 p-6 flex flex-col`,children:(0,E.jsx)(`div`,{className:`max-w-7xl mx-auto flex-1 flex flex-col w-full`,children:(0,E.jsx)(c,{})})})]}),(0,E.jsx)(u,{Link:S,routes:x,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:p,...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]}):(f.push(`/know`),null)}function A(){return(0,E.jsx)(k,{})}export{A as default};
2
- //# sourceMappingURL=layout-DzdDsd3P.js.map
1
+ import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{i as t,t as n}from"./i18n-X0oNIUcF.js";import{t as r}from"./vendor-Bd-5Ya9C.js";import{J as i,O as a,Q as o,an as s,f as c,st as l,u}from"./index-D2LrA6v6.js";import{t as d}from"./KeyboardShortcutsContext-CfYRiurd.js";import{n as f,t as p}from"./CookiePreferences-CwQNSYq4.js";import{t as m}from"./ArrowsRightLeftIcon-C7eE1lVN.js";import{n as h,t as g}from"./ChevronLeftIcon-BItMAxjy.js";import{t as _}from"./CommandLineIcon-BxjxKXBi.js";import{i as v,r as y,t as b}from"./routing-GE3qy379.js";import{n as x,t as S}from"./routing-D3tVcFuL.js";var C=e(t());function w({title:e,titleId:t,...n},r){return C.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?C.createElement(`title`,{id:t},e):null,C.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z`}))}var T=C.forwardRef(w),E=r();function D({href:e,to:t,...n}){return(0,E.jsx)(b,{to:e??``,...n})}function O({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:o}=n(),s=(e,t)=>o(`Administration.${e}`,t),{t:c}=n(),l=(e,t)=>c(`Sidebar.${e}`,t),u=y();i({"shell:sidebar-toggle":(0,C.useCallback)(()=>{t()},[t])});let d=[{name:s(`users`),href:`/admin/users`,icon:T,description:s(`usersDescription`)},{name:s(`oauthSettings`),href:`/admin/security`,icon:f,description:s(`oauthSettingsDescription`)},{name:s(`exchange`),href:`/admin/exchange`,icon:m,description:s(`exchangeDescription`)},{name:s(`devops`),href:`/admin/devops`,icon:_,description:s(`devopsDescription`)}];return(0,E.jsx)(a,{title:s(`title`),items:d,currentPath:u,LinkComponent:D,...r&&{dropdownContent:r},isCollapsed:e,icons:{chevronLeft:g,bars:h},collapseSidebarLabel:l(`collapseSidebar`),expandSidebarLabel:l(`expandSidebar`)})}function k(){let{t:e}=n(),t=(0,C.useContext)(d),r=o(l().activeSession$),i=o(r?.user$),a=r?.kb??null,f=v();return a?(0,E.jsxs)(`div`,{className:`min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col`,children:[(0,E.jsxs)(`div`,{className:`flex flex-1`,children:[(0,E.jsx)(c,{Link:S,routes:x,t:t=>e(`Navigation.${t}`),tHome:t=>e(`Home.${t}`),brandingLink:`/`,collapsible:!0,storageKey:`admin-sidebar-collapsed`,isAuthenticated:!!i,isAdmin:i?.isAdmin??!1,isModerator:i?.isModerator??!1,children:(e,t,n)=>(0,E.jsx)(O,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})}),(0,E.jsx)(`main`,{className:`flex-1 p-6 flex flex-col`,children:(0,E.jsx)(`div`,{className:`max-w-7xl mx-auto flex-1 flex flex-col w-full`,children:(0,E.jsx)(s,{})})})]}),(0,E.jsx)(u,{Link:S,routes:x,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:p,...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]}):(f.push(`/know`),null)}function A(){return(0,E.jsx)(k,{})}export{A as default};
2
+ //# sourceMappingURL=layout-ChjT2XMf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-DzdDsd3P.js","names":[],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/UsersIcon.js","../../src/components/admin/AdminNavigation.tsx","../../src/app/[locale]/admin/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction UsersIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(UsersIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n UsersIcon,\n ShieldCheckIcon,\n CommandLineIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface AdminNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function AdminNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: AdminNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Administration.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('users'),\n href: '/admin/users',\n icon: UsersIcon,\n description: t('usersDescription')\n },\n {\n name: t('oauthSettings'),\n href: '/admin/security',\n icon: ShieldCheckIcon,\n description: t('oauthSettingsDescription')\n },\n {\n name: t('exchange'),\n href: '/admin/exchange',\n icon: ArrowsRightLeftIcon,\n description: t('exchangeDescription')\n },\n {\n name: t('devops'),\n href: '/admin/devops',\n icon: CommandLineIcon,\n description: t('devopsDescription')\n },\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { AdminNavigation } from '@/components/admin/AdminNavigation';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction AdminLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"admin-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <AdminNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function AdminLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <AdminLayoutBody />;\n}\n"],"x_google_ignoreList":[0],"mappings":"smBACA,SAAS,EAAU,CACjB,QACA,UACA,GAAG,GACF,EAAQ,CACT,OAAoB,EAAM,cAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,KAAM,OACN,QAAS,YACT,YAAa,IACb,OAAQ,eACR,cAAe,OACf,YAAa,OACb,IAAK,EACL,kBAAmB,CACrB,EAAG,CAAK,EAAG,EAAqB,EAAM,cAAc,QAAS,CAC3D,GAAI,CACN,EAAG,CAAK,EAAI,KAAmB,EAAM,cAAc,OAAQ,CACzD,cAAe,QACf,eAAgB,QAChB,EAAG,2XACL,CAAC,CAAC,CACJ,CACA,IAAM,EAA2B,EAAM,WAAW,CAAS,QCF3D,SAAS,EAAS,CAAE,OAAM,GAAI,EAAK,GAAG,GAAgE,CACpG,OAAO,EAAA,EAAA,KAAC,EAAD,CAAM,GAAK,GAAQ,GAAe,GAAI,CAAQ,CAAA,CACvD,CAEA,SAAgB,EAAgB,CAAE,cAAa,kBAAiB,kBAAwC,CACtG,GAAM,CAAE,EAAG,GAAO,EAAe,EAC3B,GAAK,EAAW,IAAgC,EAAG,kBAAkB,IAAK,CAAQ,EAClF,CAAE,EAAG,GAAc,EAAe,EAClC,GAAY,EAAW,IAAgC,EAAU,WAAW,IAAK,CAAQ,EACzF,EAAW,EAAY,EAQ7B,EAAsB,CACpB,wBAAA,EAAA,EAAA,iBAN4C,CAC5C,EAAgB,CAClB,EAAG,CAAC,CAAe,CAIO,CAC1B,CAAC,EAED,IAAM,EAAqC,CACzC,CACE,KAAM,EAAE,OAAO,EACf,KAAM,eACN,KAAM,EACN,YAAa,EAAE,kBAAkB,CACnC,EACA,CACE,KAAM,EAAE,eAAe,EACvB,KAAM,kBACN,KAAM,EACN,YAAa,EAAE,0BAA0B,CAC3C,EACA,CACE,KAAM,EAAE,UAAU,EAClB,KAAM,kBACN,KAAM,EACN,YAAa,EAAE,qBAAqB,CACtC,EACA,CACE,KAAM,EAAE,QAAQ,EAChB,KAAM,gBACN,KAAM,EACN,YAAa,EAAE,mBAAmB,CACpC,CACF,EAEA,OACE,EAAA,EAAA,KAAC,EAAD,CACE,MAAO,EAAE,OAAO,EAChB,MAAO,EACP,YAAa,EACb,cAAe,EACf,GAAK,GAAkB,CAAE,gBAAiB,CAAe,EAC5C,cACb,MAAO,CACL,YAAa,EACb,KAAM,CACR,EACA,qBAAsB,EAAS,iBAAiB,EAChD,mBAAoB,EAAS,eAAe,CAC7C,CAAA,CAEL,CCvEA,SAAS,GAAkB,CACzB,GAAM,CAAE,KAAM,EAAe,EACvB,GAAA,EAAA,EAAA,YAA6B,CAAwB,EAErD,EAAU,EADA,EACc,EAAQ,cAAc,EAC9C,EAAO,EAAc,GAAS,KAAK,EACnC,EAAsB,GAAS,IAAM,KACrC,EAAS,EAAU,EAWzB,OATK,GAUH,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kEAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,EACE,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACR,EAAI,GAAgB,EAAE,cAAc,GAAK,EACzC,MAAQ,GAAgB,EAAE,QAAQ,GAAK,EACvC,aAAa,IACb,YAAa,GACb,WAAW,0BACM,gBAAA,CAfA,CAAC,EAgBT,QAfD,GAAM,SAAW,GAgBZ,YAfD,GAAM,aAAe,aAiB/B,EAAa,EAAiB,KAC9B,EAAA,EAAA,KAAC,EAAD,CACe,cACI,kBACD,gBACjB,CAAA,CAEQ,CAAA,GACb,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,qCACd,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,0DACb,EAAA,EAAA,KAAC,EAAD,CAAS,CAAA,CACN,CAAA,CACD,CAAA,CACH,KACL,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACR,GAAI,EAAa,IAAqC,EAAE,UAAU,IAAO,CAAa,EACnE,oBACnB,GAAK,GAAiB,kBAAoB,CAAE,mBAAoB,EAAgB,gBAAiB,CAClG,CAAA,CACE,KA5CL,EAAO,KAAK,OAAO,EACZ,KA6CX,CAEA,SAAwB,GAAc,CAGpC,OAAO,EAAA,EAAA,KAAC,EAAD,CAAkB,CAAA,CAC3B"}
1
+ {"version":3,"file":"layout-ChjT2XMf.js","names":[],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/UsersIcon.js","../../src/components/admin/AdminNavigation.tsx","../../src/app/[locale]/admin/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction UsersIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(UsersIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n UsersIcon,\n ShieldCheckIcon,\n CommandLineIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface AdminNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function AdminNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: AdminNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Administration.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('users'),\n href: '/admin/users',\n icon: UsersIcon,\n description: t('usersDescription')\n },\n {\n name: t('oauthSettings'),\n href: '/admin/security',\n icon: ShieldCheckIcon,\n description: t('oauthSettingsDescription')\n },\n {\n name: t('exchange'),\n href: '/admin/exchange',\n icon: ArrowsRightLeftIcon,\n description: t('exchangeDescription')\n },\n {\n name: t('devops'),\n href: '/admin/devops',\n icon: CommandLineIcon,\n description: t('devopsDescription')\n },\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { AdminNavigation } from '@/components/admin/AdminNavigation';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction AdminLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"admin-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <AdminNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function AdminLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <AdminLayoutBody />;\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{i as t,t as n}from"./i18n-X0oNIUcF.js";import{t as r}from"./vendor-Bd-5Ya9C.js";import{J as i,N as a,Q as o,Z as s,f as c,rn as l,rt as u,s as d,st as f,tt as p,u as m,v as h}from"./index-DQSZfVR2.js";import{t as g}from"./KeyboardShortcutsContext-4ZRypoQr.js";import{t as _}from"./CookiePreferences-CQa2Mwuc.js";import{n as v,t as y}from"./ToolbarPanels-BA4fpTjN.js";import{n as b,t as x}from"./ChevronLeftIcon-BItMAxjy.js";import{t as S}from"./XMarkIcon-D1vU4NLc.js";import{i as C,r as w,t as T}from"./routing-BcOlOpMI.js";import{n as E,t as D}from"./routing-1L7p7DNA.js";var O=e(t()),k=r(),A=({className:e})=>(0,k.jsx)(`span`,{className:e,style:{fontSize:`1.25rem`,lineHeight:`1`},children:`🔭`});function j({href:e,to:t,...n}){return(0,k.jsx)(T,{to:e??``,...n})}function M({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:a}=n(),s=(e,t)=>a(`Sidebar.${e}`,t),c=w(),l=C(),u=f(),p=o(u.openResources$)??[],m=u.removeOpenResource.bind(u),h=u.reorderOpenResources.bind(u),g=[{name:s(`discover`),href:`/know/discover`,icon:A,description:s(`searchAndBrowse`)},{name:s(`compose`),href:`/know/compose`,icon:v,description:s(`composeNewResource`)}];return i({"shell:sidebar-toggle":(0,O.useCallback)(()=>{t()},[t]),"tabs:close":(0,O.useCallback)(({resourceId:e})=>{m(e),c===`/know/resource/${e}`&&l.push(`/know/discover`)},[m,c,l]),"tabs:reorder":(0,O.useCallback)(({oldIndex:e,newIndex:t})=>{h(e,t)},[h])}),(0,k.jsx)(`div`,{className:`flex flex-col h-full`,children:(0,k.jsx)(`div`,{className:`flex-1 min-h-0 overflow-y-auto`,children:(0,k.jsx)(d,{fixedItems:g,resources:p,isCollapsed:e,currentPath:c,LinkComponent:j,onNavigate:e=>{l.push(e)},getResourceHref:e=>`/know/resource/${e}`,className:`knowledge-navigation`,translations:{title:s(`title`)},icons:{chevronLeft:x,bars:b,close:S},navigationMenu:r})})})}function N(){let{t:e}=n(),t=(t,n)=>e(`Navigation.${t}`,n),{t:r}=n(),i=(e,t)=>r(`Home.${e}`,t),a=o(o(f().activeSession$)?.user$);return(0,k.jsx)(c,{Link:D,routes:E,t,tHome:i,brandingLink:`/`,collapsible:!0,storageKey:`knowledgeNavCollapsed`,isAuthenticated:!!a,isAdmin:a?.isAdmin??!1,isModerator:a?.isModerator??!1,children:(e,t,n)=>(0,k.jsx)(M,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})})}function P(){return null}function F(){let{t:e}=n(),t=t=>e(`DiscoverEmptyState.${t}`),r=f(),i=o(r.kbs$)??[],a=o(r.activeSession$)?.kb??null,s=a?r.getKbSessionStatus(a.id):null;return i.length===0?(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`28rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:t(`noKnowledgeBases`)}),(0,k.jsx)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5,marginBottom:`0.75rem`},children:t(`noKnowledgeBasesHint`)}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`findKnowledgeBases`)}),` · `,(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont-template-kb`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`createNew`)})]})]}):s===`authenticated`?null:(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`24rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:a?.label??``}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[t(s===`expired`?`sessionExpired`:`signedOut`),` `,t(`signInHint`)]})]})}function I({t:e,keyboardContext:t}){let n=o(p().activePanel$)??null,{theme:r}=u(),{showLineNumbers:i}=s();return(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center`,children:(0,k.jsx)(F,{})})}),(0,k.jsx)(y,{activePanel:n,showLineNumbers:i,theme:r}),(0,k.jsx)(a,{activePanel:n,context:`simple`})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})}function L(){let{t:e}=n(),t=(0,O.useContext)(g),r=f(),i=o(r.activeKbId$),a=o(r.activeSession$),s=o(r.sessionActivating$),c=o(a?.token$),u=a?.kb??null;return i!=null&&a==null&&s?(0,k.jsx)(`div`,{className:`h-screen flex items-center justify-center`,children:(0,k.jsxs)(`div`,{className:`text-center`,children:[(0,k.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4`}),(0,k.jsx)(`p`,{className:`text-gray-600 dark:text-gray-400`,children:`Loading...`})]})}):!u||!c?(0,k.jsx)(I,{t:(t,n)=>e(t,n),keyboardContext:t}):(0,k.jsxs)(h,{children:[(0,k.jsx)(P,{}),(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(N,{}),(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden`,children:(0,k.jsx)(l,{})})})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})]})}function R(){return(0,k.jsx)(L,{})}export{R as default};
2
- //# sourceMappingURL=layout-CDH3Am1z.js.map
1
+ import{n as e}from"./rolldown-runtime-Bh1tDfsg.js";import{i as t,t as n}from"./i18n-X0oNIUcF.js";import{t as r}from"./vendor-Bd-5Ya9C.js";import{J as i,N as a,Q as o,Z as s,an as c,f as l,rt as u,s as d,st as f,tt as p,u as m,v as h}from"./index-D2LrA6v6.js";import{t as g}from"./KeyboardShortcutsContext-CfYRiurd.js";import{t as _}from"./CookiePreferences-CwQNSYq4.js";import{n as v,t as y}from"./ToolbarPanels-DhP2342d.js";import{n as b,t as x}from"./ChevronLeftIcon-BItMAxjy.js";import{t as S}from"./XMarkIcon-D1vU4NLc.js";import{i as C,r as w,t as T}from"./routing-GE3qy379.js";import{n as E,t as D}from"./routing-D3tVcFuL.js";var O=e(t()),k=r(),A=({className:e})=>(0,k.jsx)(`span`,{className:e,style:{fontSize:`1.25rem`,lineHeight:`1`},children:`🔭`});function j({href:e,to:t,...n}){return(0,k.jsx)(T,{to:e??``,...n})}function M({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:a}=n(),s=(e,t)=>a(`Sidebar.${e}`,t),c=w(),l=C(),u=f(),p=o(u.openResources$)??[],m=u.removeOpenResource.bind(u),h=u.reorderOpenResources.bind(u),g=[{name:s(`discover`),href:`/know/discover`,icon:A,description:s(`searchAndBrowse`)},{name:s(`compose`),href:`/know/compose`,icon:v,description:s(`composeNewResource`)}];return i({"shell:sidebar-toggle":(0,O.useCallback)(()=>{t()},[t]),"tabs:close":(0,O.useCallback)(({resourceId:e})=>{m(e),c===`/know/resource/${e}`&&l.push(`/know/discover`)},[m,c,l]),"tabs:reorder":(0,O.useCallback)(({oldIndex:e,newIndex:t})=>{h(e,t)},[h])}),(0,k.jsx)(`div`,{className:`flex flex-col h-full`,children:(0,k.jsx)(`div`,{className:`flex-1 min-h-0 overflow-y-auto`,children:(0,k.jsx)(d,{fixedItems:g,resources:p,isCollapsed:e,currentPath:c,LinkComponent:j,onNavigate:e=>{l.push(e)},getResourceHref:e=>`/know/resource/${e}`,className:`knowledge-navigation`,translations:{title:s(`title`)},icons:{chevronLeft:x,bars:b,close:S},navigationMenu:r})})})}function N(){let{t:e}=n(),t=(t,n)=>e(`Navigation.${t}`,n),{t:r}=n(),i=(e,t)=>r(`Home.${e}`,t),a=o(o(f().activeSession$)?.user$);return(0,k.jsx)(l,{Link:D,routes:E,t,tHome:i,brandingLink:`/`,collapsible:!0,storageKey:`knowledgeNavCollapsed`,isAuthenticated:!!a,isAdmin:a?.isAdmin??!1,isModerator:a?.isModerator??!1,children:(e,t,n)=>(0,k.jsx)(M,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})})}function P(){return null}function F(){let{t:e}=n(),t=t=>e(`DiscoverEmptyState.${t}`),r=f(),i=o(r.kbs$)??[],a=o(r.activeSession$)?.kb??null,s=a?r.getKbSessionStatus(a.id):null;return i.length===0?(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`28rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:t(`noKnowledgeBases`)}),(0,k.jsx)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5,marginBottom:`0.75rem`},children:t(`noKnowledgeBasesHint`)}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`findKnowledgeBases`)}),` · `,(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont-template-kb`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`createNew`)})]})]}):s===`authenticated`?null:(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`24rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:a?.label??``}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[t(s===`expired`?`sessionExpired`:`signedOut`),` `,t(`signInHint`)]})]})}function I({t:e,keyboardContext:t}){let n=o(p().activePanel$)??null,{theme:r}=u(),{showLineNumbers:i}=s();return(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center`,children:(0,k.jsx)(F,{})})}),(0,k.jsx)(y,{activePanel:n,showLineNumbers:i,theme:r}),(0,k.jsx)(a,{activePanel:n,context:`simple`})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})}function L(){let{t:e}=n(),t=(0,O.useContext)(g),r=f(),i=o(r.activeKbId$),a=o(r.activeSession$),s=o(r.sessionActivating$),l=o(a?.token$),u=a?.kb??null;return i!=null&&a==null&&s?(0,k.jsx)(`div`,{className:`h-screen flex items-center justify-center`,children:(0,k.jsxs)(`div`,{className:`text-center`,children:[(0,k.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4`}),(0,k.jsx)(`p`,{className:`text-gray-600 dark:text-gray-400`,children:`Loading...`})]})}):!u||!l?(0,k.jsx)(I,{t:(t,n)=>e(t,n),keyboardContext:t}):(0,k.jsxs)(h,{children:[(0,k.jsx)(P,{}),(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(N,{}),(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden`,children:(0,k.jsx)(c,{})})})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})]})}function R(){return(0,k.jsx)(L,{})}export{R as default};
2
+ //# sourceMappingURL=layout-DTOSfecO.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-CDH3Am1z.js","names":[],"sources":["../../src/components/knowledge/KnowledgeNavigation.tsx","../../src/components/knowledge/KnowledgeSidebarWrapper.tsx","../../src/app/[locale]/know/layout.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname, useRouter } from '@/i18n/routing';\nimport { PlusIcon, ChevronLeftIcon, Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline';\nimport {\n useSemiont,\n useObservable,\n useEventSubscriptions,\n CollapsibleResourceNavigation,\n type NavigationItem,\n} from '@semiont/react-ui';\nimport type { OpenResource } from '@semiont/sdk';\n// Custom telescope icon component\nconst TelescopeIcon = ({ className }: { className?: string }) => (\n <span className={className} style={{ fontSize: '1.25rem', lineHeight: '1' }}>🔭</span>\n);\n\ninterface KnowledgeNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: CollapsibleResourceNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function KnowledgeNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: KnowledgeNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n const router = useRouter();\n const semiont = useSemiont();\n const openResources = useObservable(semiont.openResources$) ?? [];\n const removeResource = semiont.removeOpenResource.bind(semiont);\n const reorderResources = semiont.reorderOpenResources.bind(semiont);\n\n const fixedNavigation: NavigationItem[] = [\n {\n name: t('discover'),\n href: '/know/discover',\n icon: TelescopeIcon,\n description: t('searchAndBrowse')\n },\n {\n name: t('compose'),\n href: '/know/compose',\n icon: PlusIcon,\n description: t('composeNewResource')\n }\n ];\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Handle resource close events\n const handleResourceClose = useCallback(({ resourceId }: { resourceId: string }) => {\n removeResource(resourceId);\n\n // If we're closing the currently viewed document, navigate to Discover\n if (pathname === `/know/resource/${resourceId}`) {\n router.push('/know/discover');\n }\n }, [removeResource, pathname, router]);\n\n // Handle resource reorder events\n const handleResourceReorder = useCallback(({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {\n reorderResources(oldIndex, newIndex);\n }, [reorderResources]);\n\n // Subscribe to navigation events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n 'tabs:close': handleResourceClose,\n 'tabs:reorder': handleResourceReorder,\n });\n\n // Handle navigation\n const handleNavigate = (path: string) => {\n router.push(path);\n };\n\n // Build resource href\n const getResourceHref = (resourceId: string) => {\n return `/know/resource/${resourceId}`;\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <CollapsibleResourceNavigation\n fixedItems={fixedNavigation}\n resources={openResources as OpenResource[]}\n isCollapsed={isCollapsed}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n onNavigate={handleNavigate}\n getResourceHref={getResourceHref}\n className=\"knowledge-navigation\"\n translations={{\n title: t('title')\n }}\n icons={{\n chevronLeft: ChevronLeftIcon,\n bars: Bars3Icon,\n close: XMarkIcon\n }}\n navigationMenu={navigationMenu}\n />\n </div>\n </div>\n );\n}","import { useTranslation } from 'react-i18next';\nimport { LeftSidebar, useSemiont, useObservable } from '@semiont/react-ui';\nimport { KnowledgeNavigation } from './KnowledgeNavigation';\nimport { Link, routes } from '@/lib/routing';\n\nexport function KnowledgeSidebarWrapper() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Navigation.${k}`, p as any) as string;\n const { t: _tHome } = useTranslation();\n const tHome = (k: string, p?: Record<string, unknown>) => _tHome(`Home.${k}`, p as any) as string;\n const session = useObservable(useSemiont().activeSession$);\n const user = useObservable(session?.user$);\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={t}\n tHome={tHome}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"knowledgeNavCollapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <KnowledgeNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n );\n}\n","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { KnowledgeSidebarWrapper } from '@/components/knowledge/KnowledgeSidebarWrapper';\nimport {\n Footer,\n ResourceAnnotationsProvider,\n Toolbar,\n useSemiont,\n useShellStateUnit,\n useObservable,\n useTheme,\n useLineNumbers,\n} from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\n\nfunction GlobalEventsConnector() {\n return null;\n}\n\n/**\n * Empty state for the main content area when no KB is connected or authenticated.\n * Shows contextual guidance based on whether any KBs exist.\n */\nfunction DiscoverEmptyState() {\n const { t: _t } = useTranslation();\n const t = (k: string) => _t(`DiscoverEmptyState.${k}`) as string;\n const semiont = useSemiont();\n const knowledgeBases = useObservable(semiont.kbs$) ?? [];\n const activeKnowledgeBase = useObservable(semiont.activeSession$)?.kb ?? null;\n const status = activeKnowledgeBase\n ? semiont.getKbSessionStatus(activeKnowledgeBase.id)\n : null;\n\n if (knowledgeBases.length === 0) {\n return (\n <div style={{ textAlign: 'center', maxWidth: '28rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>{t('noKnowledgeBases')}</h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5, marginBottom: '0.75rem' }}>\n {t('noKnowledgeBasesHint')}\n </p>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n <a href=\"https://github.com/The-AI-Alliance/semiont\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('findKnowledgeBases')}</a>\n {' · '}\n <a href=\"https://github.com/The-AI-Alliance/semiont-template-kb\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('createNew')}</a>\n </p>\n </div>\n );\n }\n\n if (status === 'authenticated') {\n return null;\n }\n\n return (\n <div style={{ textAlign: 'center', maxWidth: '24rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>\n {activeKnowledgeBase?.label ?? ''}\n </h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n {status === 'expired' ? t('sessionExpired') : t('signedOut')}\n {' '}{t('signInHint')}\n </p>\n </div>\n );\n}\n\nfunction UnauthenticatedKnowledgeLayout({ t, keyboardContext }: { t: (key: string, params?: Record<string, unknown>) => string; keyboardContext: { openKeyboardHelp?: () => void } | null }) {\n const browseStateUnit = useShellStateUnit();\n const activePanel = useObservable(browseStateUnit.activePanel$) ?? null;\n const { theme } = useTheme();\n const { showLineNumbers } = useLineNumbers();\n\n return (\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center\">\n <DiscoverEmptyState />\n </div>\n </main>\n <ToolbarPanels\n activePanel={activePanel}\n showLineNumbers={showLineNumbers}\n theme={theme}\n />\n <Toolbar activePanel={activePanel} context=\"simple\" />\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nfunction KnowledgeLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const activeKbId = useObservable(semiont.activeKbId$);\n const session = useObservable(semiont.activeSession$);\n const sessionActivating = useObservable(semiont.sessionActivating$);\n const token = useObservable(session?.token$);\n const activeKnowledgeBase = session?.kb ?? null;\n // \"Loading\" = a session construction is actively in flight. Without\n // the `sessionActivating` guard we'd sit on the spinner forever after\n // any `signOut`, which also leaves `activeKbId` set but `session`\n // null.\n const isLoading = activeKbId != null && session == null && sessionActivating;\n\n if (isLoading) {\n return (\n <div className=\"h-screen flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4\"></div>\n <p className=\"text-gray-600 dark:text-gray-400\">Loading...</p>\n </div>\n </div>\n );\n }\n\n if (!activeKnowledgeBase || !token) {\n return (\n <UnauthenticatedKnowledgeLayout t={(key: string, params?: Record<string, unknown>) => t(key, params as any) as string} keyboardContext={keyboardContext} />\n );\n }\n\n return (\n <ResourceAnnotationsProvider>\n <GlobalEventsConnector />\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <KnowledgeSidebarWrapper />\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n </ResourceAnnotationsProvider>\n );\n}\n\nexport default function KnowledgeLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <KnowledgeLayoutBody />;\n}\n"],"mappings":"0oBAcM,GAAiB,CAAE,gBACvB,EAAA,EAAA,KAAC,OAAD,CAAiB,YAAW,MAAO,CAAE,SAAU,UAAW,WAAY,GAAI,WAAG,IAAQ,CAAA,EAUvF,SAAS,EAAS,CAAE,OAAM,GAAI,EAAK,GAAG,GAAgE,CACpG,OAAO,EAAA,EAAA,KAAC,EAAD,CAAM,GAAK,GAAQ,GAAe,GAAI,CAAQ,CAAA,CACvD,CAEA,SAAgB,EAAoB,CAAE,cAAa,kBAAiB,kBAA4C,CAC9G,GAAM,CAAE,EAAG,GAAO,EAAe,EAC3B,GAAK,EAAW,IAAgC,EAAG,WAAW,IAAK,CAAQ,EAC3E,EAAW,EAAY,EACvB,EAAS,EAAU,EACnB,EAAU,EAAW,EACrB,EAAgB,EAAc,EAAQ,cAAc,GAAK,CAAC,EAC1D,EAAiB,EAAQ,mBAAmB,KAAK,CAAO,EACxD,EAAmB,EAAQ,qBAAqB,KAAK,CAAO,EAE5D,EAAoC,CACxC,CACE,KAAM,EAAE,UAAU,EAClB,KAAM,iBACN,KAAM,EACN,YAAa,EAAE,iBAAiB,CAClC,EACA,CACE,KAAM,EAAE,SAAS,EACjB,KAAM,gBACN,KAAM,EACN,YAAa,EAAE,oBAAoB,CACrC,CACF,EAuCA,OAhBA,EAAsB,CACpB,wBAAA,EAAA,EAAA,iBArB4C,CAC5C,EAAgB,CAClB,EAAG,CAAC,CAAe,CAmBO,EACxB,cAAA,EAAA,EAAA,cAjBuC,CAAE,gBAAyC,CAClF,EAAe,CAAU,EAGrB,IAAa,kBAAkB,KACjC,EAAO,KAAK,gBAAgB,CAEhC,EAAG,CAAC,EAAgB,EAAU,CAAM,CAUpB,EACd,gBAAA,EAAA,EAAA,cARyC,CAAE,WAAU,cAAuD,CAC5G,EAAiB,EAAU,CAAQ,CACrC,EAAG,CAAC,CAAgB,CAMF,CAClB,CAAC,GAaC,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,iCACb,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,2CACb,EAAA,EAAA,KAAC,EAAD,CACE,WAAY,EACZ,UAAW,EACE,cACb,YAAa,EACb,cAAe,EACf,WAlBgB,GAAiB,CACvC,EAAO,KAAK,CAAI,CAClB,EAiByB,gBAdA,GAChB,kBAAkB,IAcnB,UAAU,uBACV,aAAc,CACZ,MAAO,EAAE,OAAO,CAClB,EACA,MAAO,CACL,YAAa,EACb,KAAM,EACN,MAAO,CACT,EACgB,gBACjB,CAAA,CACE,CAAA,CACF,CAAA,CAET,CC/GA,SAAgB,GAA0B,CACxC,GAAM,CAAE,EAAG,GAAO,EAAe,EAC3B,GAAK,EAAW,IAAgC,EAAG,cAAc,IAAK,CAAQ,EAC9E,CAAE,EAAG,GAAW,EAAe,EAC/B,GAAS,EAAW,IAAgC,EAAO,QAAQ,IAAK,CAAQ,EAEhF,EAAO,EADG,EAAc,EAAW,EAAE,cAChB,GAAS,KAAK,EAKzC,OACE,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACL,EACI,QACP,aAAa,IACb,YAAa,GACb,WAAW,wBACM,gBAAA,CAbI,CAAC,EAcb,QAbG,GAAM,SAAW,GAchB,YAbG,GAAM,aAAe,aAenC,EAAa,EAAiB,KAC9B,EAAA,EAAA,KAAC,EAAD,CACe,cACI,kBACD,gBACjB,CAAA,CAEQ,CAAA,CAEjB,CCnBA,SAAS,GAAwB,CAC/B,OAAO,IACT,CAMA,SAAS,GAAqB,CAC5B,GAAM,CAAE,EAAG,GAAO,EAAe,EAC3B,EAAK,GAAc,EAAG,sBAAsB,GAAG,EAC/C,EAAU,EAAW,EACrB,EAAiB,EAAc,EAAQ,IAAI,GAAK,CAAC,EACjD,EAAsB,EAAc,EAAQ,cAAc,GAAG,IAAM,KACnE,EAAS,EACX,EAAQ,mBAAmB,EAAoB,EAAE,EACjD,KAsBJ,OApBI,EAAe,SAAW,GAE1B,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,UAAW,SAAU,SAAU,OAAQ,WAArD,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,MAAO,CAAE,SAAU,SAAU,WAAY,IAAK,aAAc,QAAS,WAAI,EAAE,kBAAkB,CAAM,CAAA,GACvG,EAAA,EAAA,KAAC,IAAD,CAAG,MAAO,CAAE,MAAO,mCAAoC,SAAU,UAAW,WAAY,IAAK,aAAc,SAAU,WAClH,EAAE,sBAAsB,CACxB,CAAA,GACH,EAAA,EAAA,MAAC,IAAD,CAAG,MAAO,CAAE,MAAO,mCAAoC,SAAU,UAAW,WAAY,GAAI,WAA5F,EACE,EAAA,EAAA,KAAC,IAAD,CAAG,KAAK,6CAA6C,OAAO,SAAS,IAAI,sBAAsB,MAAO,CAAE,MAAO,kCAAmC,WAAI,EAAE,oBAAoB,CAAK,CAAA,EAChL,OACD,EAAA,EAAA,KAAC,IAAD,CAAG,KAAK,yDAAyD,OAAO,SAAS,IAAI,sBAAsB,MAAO,CAAE,MAAO,kCAAmC,WAAI,EAAE,WAAW,CAAK,CAAA,CACnL,GACA,IAIL,IAAW,gBACN,MAIP,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,UAAW,SAAU,SAAU,OAAQ,WAArD,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,MAAO,CAAE,SAAU,SAAU,WAAY,IAAK,aAAc,QAAS,WACtE,GAAqB,OAAS,EAC7B,CAAA,GACJ,EAAA,EAAA,MAAC,IAAD,CAAG,MAAO,CAAE,MAAO,mCAAoC,SAAU,UAAW,WAAY,GAAI,WAA5F,CAC0B,EAAvB,IAAW,UAAc,iBAAsB,WAAW,EAC1D,IAAK,EAAE,YAAY,CACnB,GACA,GAET,CAEA,SAAS,EAA+B,CAAE,IAAG,mBAAgJ,CAE3L,IAAM,EAAc,EADI,EACU,EAAgB,YAAY,GAAK,KAC7D,CAAE,SAAU,EAAS,EACrB,CAAE,mBAAoB,EAAe,EAE3C,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,sGAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uCAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,kEACd,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mGACb,EAAA,EAAA,KAAC,EAAD,CAAqB,CAAA,CAClB,CAAA,CACD,CAAA,GACN,EAAA,EAAA,KAAC,EAAD,CACe,cACI,kBACV,OACR,CAAA,GACD,EAAA,EAAA,KAAC,EAAD,CAAsB,cAAa,QAAQ,QAAU,CAAA,CAClD,KACL,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACR,GAAI,EAAa,IAAqC,EAAE,UAAU,IAAO,CAAa,EACnE,oBACnB,gBAAiB,EAAE,wBAAyB,QAC5C,GAAK,GAAiB,kBAAoB,CAAE,mBAAoB,EAAgB,gBAAiB,CAClG,CAAA,CACE,GAET,CAEA,SAAS,GAAsB,CAC7B,GAAM,CAAE,KAAM,EAAe,EACvB,GAAA,EAAA,EAAA,YAA6B,CAAwB,EACrD,EAAU,EAAW,EACrB,EAAa,EAAc,EAAQ,WAAW,EAC9C,EAAU,EAAc,EAAQ,cAAc,EAC9C,EAAoB,EAAc,EAAQ,kBAAkB,EAC5D,EAAQ,EAAc,GAAS,MAAM,EACrC,EAAsB,GAAS,IAAM,KAwB3C,OAnBkB,GAAc,MAAQ,GAAW,MAAQ,GAIvD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sDACb,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6EAAmF,CAAA,GAClG,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,4CAAmC,YAAa,CAAA,CAC1D,GACF,CAAA,EAIL,CAAC,GAAuB,CAAC,GAEzB,EAAA,EAAA,KAAC,EAAD,CAAgC,GAAI,EAAa,IAAqC,EAAE,EAAK,CAAa,EAA8B,iBAAkB,CAAA,GAK5J,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,CAAwB,CAAA,GACxB,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,sGAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uCAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAA0B,CAAA,GAC1B,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,kEACd,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uEACb,EAAA,EAAA,KAAC,EAAD,CAAS,CAAA,CACN,CAAA,CACD,CAAA,CACH,KACL,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACR,GAAI,EAAa,IAAqC,EAAE,UAAU,IAAO,CAAa,EACnE,oBACnB,gBAAiB,EAAE,wBAAyB,QAC5C,GAAK,GAAiB,kBAAoB,CAAE,mBAAoB,EAAgB,gBAAiB,CAClG,CAAA,CACE,GACsB,CAAA,CAAA,CAEjC,CAEA,SAAwB,GAAkB,CAGxC,OAAO,EAAA,EAAA,KAAC,EAAD,CAAsB,CAAA,CAC/B"}
1
+ {"version":3,"file":"layout-DTOSfecO.js","names":[],"sources":["../../src/components/knowledge/KnowledgeNavigation.tsx","../../src/components/knowledge/KnowledgeSidebarWrapper.tsx","../../src/app/[locale]/know/layout.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname, useRouter } from '@/i18n/routing';\nimport { PlusIcon, ChevronLeftIcon, Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline';\nimport {\n useSemiont,\n useObservable,\n useEventSubscriptions,\n CollapsibleResourceNavigation,\n type NavigationItem,\n} from '@semiont/react-ui';\nimport type { OpenResource } from '@semiont/sdk';\n// Custom telescope icon component\nconst TelescopeIcon = ({ className }: { className?: string }) => (\n <span className={className} style={{ fontSize: '1.25rem', lineHeight: '1' }}>🔭</span>\n);\n\ninterface KnowledgeNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: CollapsibleResourceNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function KnowledgeNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: KnowledgeNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n const router = useRouter();\n const semiont = useSemiont();\n const openResources = useObservable(semiont.openResources$) ?? [];\n const removeResource = semiont.removeOpenResource.bind(semiont);\n const reorderResources = semiont.reorderOpenResources.bind(semiont);\n\n const fixedNavigation: NavigationItem[] = [\n {\n name: t('discover'),\n href: '/know/discover',\n icon: TelescopeIcon,\n description: t('searchAndBrowse')\n },\n {\n name: t('compose'),\n href: '/know/compose',\n icon: PlusIcon,\n description: t('composeNewResource')\n }\n ];\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Handle resource close events\n const handleResourceClose = useCallback(({ resourceId }: { resourceId: string }) => {\n removeResource(resourceId);\n\n // If we're closing the currently viewed document, navigate to Discover\n if (pathname === `/know/resource/${resourceId}`) {\n router.push('/know/discover');\n }\n }, [removeResource, pathname, router]);\n\n // Handle resource reorder events\n const handleResourceReorder = useCallback(({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {\n reorderResources(oldIndex, newIndex);\n }, [reorderResources]);\n\n // Subscribe to navigation events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n 'tabs:close': handleResourceClose,\n 'tabs:reorder': handleResourceReorder,\n });\n\n // Handle navigation\n const handleNavigate = (path: string) => {\n router.push(path);\n };\n\n // Build resource href\n const getResourceHref = (resourceId: string) => {\n return `/know/resource/${resourceId}`;\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <CollapsibleResourceNavigation\n fixedItems={fixedNavigation}\n resources={openResources as OpenResource[]}\n isCollapsed={isCollapsed}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n onNavigate={handleNavigate}\n getResourceHref={getResourceHref}\n className=\"knowledge-navigation\"\n translations={{\n title: t('title')\n }}\n icons={{\n chevronLeft: ChevronLeftIcon,\n bars: Bars3Icon,\n close: XMarkIcon\n }}\n navigationMenu={navigationMenu}\n />\n </div>\n </div>\n );\n}","import { useTranslation } from 'react-i18next';\nimport { LeftSidebar, useSemiont, useObservable } from '@semiont/react-ui';\nimport { KnowledgeNavigation } from './KnowledgeNavigation';\nimport { Link, routes } from '@/lib/routing';\n\nexport function KnowledgeSidebarWrapper() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Navigation.${k}`, p as any) as string;\n const { t: _tHome } = useTranslation();\n const tHome = (k: string, p?: Record<string, unknown>) => _tHome(`Home.${k}`, p as any) as string;\n const session = useObservable(useSemiont().activeSession$);\n const user = useObservable(session?.user$);\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={t}\n tHome={tHome}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"knowledgeNavCollapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <KnowledgeNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n );\n}\n","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { KnowledgeSidebarWrapper } from '@/components/knowledge/KnowledgeSidebarWrapper';\nimport {\n Footer,\n ResourceAnnotationsProvider,\n Toolbar,\n useSemiont,\n useShellStateUnit,\n useObservable,\n useTheme,\n useLineNumbers,\n} from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\n\nfunction GlobalEventsConnector() {\n return null;\n}\n\n/**\n * Empty state for the main content area when no KB is connected or authenticated.\n * Shows contextual guidance based on whether any KBs exist.\n */\nfunction DiscoverEmptyState() {\n const { t: _t } = useTranslation();\n const t = (k: string) => _t(`DiscoverEmptyState.${k}`) as string;\n const semiont = useSemiont();\n const knowledgeBases = useObservable(semiont.kbs$) ?? [];\n const activeKnowledgeBase = useObservable(semiont.activeSession$)?.kb ?? null;\n const status = activeKnowledgeBase\n ? semiont.getKbSessionStatus(activeKnowledgeBase.id)\n : null;\n\n if (knowledgeBases.length === 0) {\n return (\n <div style={{ textAlign: 'center', maxWidth: '28rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>{t('noKnowledgeBases')}</h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5, marginBottom: '0.75rem' }}>\n {t('noKnowledgeBasesHint')}\n </p>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n <a href=\"https://github.com/The-AI-Alliance/semiont\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('findKnowledgeBases')}</a>\n {' · '}\n <a href=\"https://github.com/The-AI-Alliance/semiont-template-kb\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('createNew')}</a>\n </p>\n </div>\n );\n }\n\n if (status === 'authenticated') {\n return null;\n }\n\n return (\n <div style={{ textAlign: 'center', maxWidth: '24rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>\n {activeKnowledgeBase?.label ?? ''}\n </h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n {status === 'expired' ? t('sessionExpired') : t('signedOut')}\n {' '}{t('signInHint')}\n </p>\n </div>\n );\n}\n\nfunction UnauthenticatedKnowledgeLayout({ t, keyboardContext }: { t: (key: string, params?: Record<string, unknown>) => string; keyboardContext: { openKeyboardHelp?: () => void } | null }) {\n const browseStateUnit = useShellStateUnit();\n const activePanel = useObservable(browseStateUnit.activePanel$) ?? null;\n const { theme } = useTheme();\n const { showLineNumbers } = useLineNumbers();\n\n return (\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center\">\n <DiscoverEmptyState />\n </div>\n </main>\n <ToolbarPanels\n activePanel={activePanel}\n showLineNumbers={showLineNumbers}\n theme={theme}\n />\n <Toolbar activePanel={activePanel} context=\"simple\" />\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nfunction KnowledgeLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const activeKbId = useObservable(semiont.activeKbId$);\n const session = useObservable(semiont.activeSession$);\n const sessionActivating = useObservable(semiont.sessionActivating$);\n const token = useObservable(session?.token$);\n const activeKnowledgeBase = session?.kb ?? null;\n // \"Loading\" = a session construction is actively in flight. Without\n // the `sessionActivating` guard we'd sit on the spinner forever after\n // any `signOut`, which also leaves `activeKbId` set but `session`\n // null.\n const isLoading = activeKbId != null && session == null && sessionActivating;\n\n if (isLoading) {\n return (\n <div className=\"h-screen flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4\"></div>\n <p className=\"text-gray-600 dark:text-gray-400\">Loading...</p>\n </div>\n </div>\n );\n }\n\n if (!activeKnowledgeBase || !token) {\n return (\n <UnauthenticatedKnowledgeLayout t={(key: string, params?: Record<string, unknown>) => t(key, params as any) as string} keyboardContext={keyboardContext} />\n );\n }\n\n return (\n <ResourceAnnotationsProvider>\n <GlobalEventsConnector />\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <KnowledgeSidebarWrapper />\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n </ResourceAnnotationsProvider>\n );\n}\n\nexport default function KnowledgeLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <KnowledgeLayoutBody />;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  var e={annotations:`Anotasi`,history:`Sejarah`,resourceInfo:`Maklumat Sumber`,collaboration:`Kolaborasi`,userAccount:`Akaun Pengguna`,settings:`Tetapan`,knowledgeBase:`Pangkalan Pengetahuan`},t={title:`Maklumat Sumber`,locale:`Lokasi`,notSpecified:`Tidak dinyatakan`,entityTypeTags:`Tag Jenis Entiti`,representation:`Perwakilan`,mediaType:`Jenis Media`,byteSize:`Saiz`,clone:`Klon`,cloneDescription:`Jana pautan klon yang boleh dikongsi untuk sumber ini`,archive:`Arkib`,archiveDescription:`Alihkan sumber ini ke status diarkibkan`,unarchive:`Nyaharkib`,unarchiveDescription:`Pulihkan sumber ini ke status aktif`,provenance:`Asal-usul`,createdAt:`Dicipta`,modifiedAt:`Diubah suai`,attributedTo:`Dikaitkan dengan`,derivedFrom:`Diperoleh daripada`,storageUri:`Storan`},n={title:`Kolaborasi`,connectionStatus:`Status Sambungan`,live:`Langsung`,disconnected:`Terputus`,events:`{{count}} peristiwa`,lastSync:`Penyegerakan terakhir:`,noActivity:`Tiada aktiviti lagi`,justNow:`Baru sahaja`,secondsAgo:`{{count}} saat yang lalu`,minuteAgo:`1 minit yang lalu`,minutesAgo:`{{count}} minit yang lalu`,hourAgo:`1 jam yang lalu`,hoursAgo:`{{count}} jam yang lalu`,realtimeActive:`Kemas kini masa nyata sedang aktif`,reconnecting:`Menyambung semula ke pelayan...`,sharing:`Perkongsian`,collaborationComingSoon:`Ciri kolaborasi akan datang tidak lama lagi`},r={history:`Sejarah`,loading:`Memuatkan...`,user:`Pengguna`,viewOriginal:`Lihat asal`,viewAnnotation:`Lihat anotasi: {{content}}`,resourceCreated:`Sumber Dicipta`,resourceCloned:`Diklon`,resourceArchived:`Diarkibkan`,resourceUnarchived:`Dinyaharkibkan`,highlightAdded:`Sorotan Ditambah`,highlightRemoved:`Sorotan Dibuang`,referenceCreated:`Rujukan Dicipta`,referenceResolved:`Rujukan Diselesaikan`,referenceDeleted:`Rujukan Dipadam`,entitytagAdded:`Tag Ditambah`,entitytagRemoved:`Tag Dibuang`,assessmentAdded:`Penilaian Ditambah`,assessmentRemoved:`Penilaian Dibuang`,annotationAdded:`Anotasi Ditambah`,annotationRemoved:`Anotasi Dibuang`,annotationBodyUpdated:`Anotasi Dikemas Kini`,jobEvent:`Peristiwa Tugas`,embeddingComputed:`Embedding dikira`,justNow:`baru sahaja`,minutesAgo:`{{count}}m lalu`,hoursAgo:`{{count}}j lalu`,daysAgo:`{{count}}h lalu`},i={title:`Ulasan`,noComments:`Tiada ulasan lagi. Pilih teks dan klik Ulasan untuk menambah satu.`,commentPlaceholder:`Taip ulasan anda di sini...`,save:`Simpan`,cancel:`Batal`,edit:`Sunting`,annotateComments:`Anotasi Ulasan`,instructions:`Arahan`,optional:`(pilihan)`,instructionsPlaceholder:`cth., Fokus pada istilah teknikal...`,annotate:`Anotasi`,annotating:`Menganotasi...`,toneLabel:`Nada`,toneOptional:`(pilihan)`,toneScholarly:`Ilmiah`,toneExplanatory:`Penjelasan`,toneConversational:`Perbualan`,toneTechnical:`Teknikal`,densityLabel:`Ketumpatan`,densitySparse:`Jarang`,densityDense:`Padat`,fragmentSelected:`Fragmen dipilih`,imageRegionSelected:`Kawasan imej dipilih`,closeProgress:`Tutup`},a={title:`Sorotan`,noHighlights:`Tiada sorotan lagi. Gunakan anotasi AI untuk mencari petikan penting.`,annotateHighlights:`Anotasi Sorotan`,instructions:`Arahan`,optional:`(pilihan)`,instructionsPlaceholder:`cth., Fokus pada konsep teknikal utama...`,annotate:`Anotasi`,annotating:`Menganotasi...`,cancel:`Batal`,densityLabel:`Ketumpatan`,densitySparse:`Jarang`,densityDense:`Padat`,closeProgress:`Tutup`},o={title:`Penilaian`,noAssessments:`Tiada penilaian lagi. Gunakan anotasi AI untuk menilai petikan.`,assessmentPlaceholder:`Taip penilaian anda di sini...`,save:`Simpan`,cancel:`Batal`,annotateAssessments:`Anotasi Penilaian`,instructions:`Arahan`,optional:`(pilihan)`,instructionsPlaceholder:`cth., Nilai dakwaan untuk ketepatan dan bukti...`,annotate:`Anotasi`,annotating:`Menganotasi...`,toneLabel:`Nada`,toneOptional:`(pilihan)`,toneAnalytical:`Analitikal`,toneCritical:`Kritikal`,toneBalanced:`Seimbang`,toneConstructive:`Konstruktif`,densityLabel:`Ketumpatan`,densitySparse:`Jarang`,densityDense:`Padat`,fragmentSelected:`Fragmen dipilih`,imageRegionSelected:`Kawasan imej dipilih`,closeProgress:`Tutup`},s={title:`Tag`,noTags:`Tiada tag lagi. Gunakan anotasi AI untuk mengenal pasti peranan struktur.`,noSchemas:"Tiada skema tag didaftarkan untuk pangkalan pengetahuan ini. Pentadbir KB mesti mendaftarkan sekurang-kurangnya satu skema analisis struktur (cth. melalui kemahiran `register-tag-schemas`) sebelum penandaan boleh digunakan.",annotateTags:`Anotasi Tag`,selectSchema:`Pilih Rangka Kerja`,selectCategories:`Pilih Kategori`,annotate:`Anotasi`,annotating:`Menganotasi...`,cancel:`Batal`,selectAll:`Pilih Semua`,deselectAll:`Nyahpilih Semua`,categoriesSelected:`{count, plural, =0 {Tiada kategori dipilih} =1 {1 kategori dipilih} other {# kategori dipilih}}`,createTagForSelection:`Cipta Tag untuk Pilihan`,selectCategory:`Pilih Kategori`,chooseCategory:`Pilih kategori...`,fragmentSelected:`Fragmen dipilih`,imageRegionSelected:`Kawasan imej dipilih`},c={title:`Anotasi`,statistics:`Statistik`,highlight:`Sorotan`,reference:`Rujukan`,assessment:`Penilaian`,comment:`Ulasan`,tag:`Tag`},l={title:`Statistik`,highlights:`Sorotan`,comments:`Ulasan`,assessments:`Penilaian`,tags:`Tag`,references:`Rujukan`,stub:`Stub`,resolved:`Diselesaikan`,entityTypes:`Jenis Entiti`},u={title:`Rujukan`,noReferences:`Tiada rujukan lagi. Pilih teks untuk mencipta rujukan ke sumber lain.`,outgoingReferences:`Rujukan Keluar`,incomingReferences:`Rujukan Masuk`,noIncomingReferences:`Tiada rujukan masuk`,stub:`Rujukan stub (tidak dipautkan)`,resolved:`Rujukan diselesaikan (dipautkan)`,open:`Buka`,unlink:`Nyahpaut`,resolve:`Selesaikan rujukan`,cancel:`Batal`,createReference:`Cipta Rujukan`,entityTypesOptional:`Jenis Entiti (Pilihan)`,fragmentSelected:`Fragmen dipilih`,imageRegionSelected:`Kawasan imej dipilih`,annotateReferences:`Anotasi Rujukan`,selectEntityTypes:`Jenis entiti:`,select:`Pilih`,deselect:`Nyahpilih`,noEntityTypes:`Tiada jenis entiti tersedia`,typesSelected:`{count, plural, =1 {1 jenis dipilih} other {# jenis dipilih}}`,annotate:`Anotasi`,annotating:`Menganotasi...`,includeDescriptiveReferences:`Sertakan rujukan deskriptif`,descriptiveReferencesTooltip:`Cari juga frasa seperti 'CEO tersebut', 'gergasi teknologi tersebut', 'ahli fizik tersebut' (selain nama)`,annotationProgressTitle:`Menganotasi Rujukan Entiti`,cancelAnnotation:`Batalkan anotasi`,found:`{{count}} ditemui`,complete:`Anotasi selesai!`,failed:`Anotasi gagal`,current:`Semasa: {{entityType}}`,closeProgress:`Tutup`,loading:`memuatkan...`,loadingEllipsis:`Memuatkan...`,untitledResource:`Sumber Tanpa Tajuk`,noText:`Tiada teks`},d={title:`Pintasan Papan Kekunci`,closeDialog:`Tutup dialog`,or:`atau`,navigationTitle:`Navigasi`,navOpenSearch:`Buka carian global`,navOpenSearchAlt:`Buka carian global (alternatif)`,navCreateResource:`Cipta sumber baharu`,navCloseOverlays:`Tutup semua tindanan (tekan dua kali)`,navShowHelp:`Tunjukkan bantuan pintasan papan kekunci`,sidebarTitle:`Bar Sisi Pengetahuan`,sidebarCollapse:`Kecilkan bar sisi`,sidebarExpand:`Kembangkan bar sisi`,sidebarPickup:`Angkat tab sumber (apabila difokuskan)`,sidebarMove:`Alihkan tab sumber (apabila menyeret)`,sidebarDrop:`Lepaskan tab sumber (apabila menyeret)`,sidebarCancel:`Batalkan operasi seret`,annotationsTitle:`Anotasi Sumber`,annotHighlight:`Cipta sorotan daripada anotasi (terus)`,annotReference:`Buka tetingkap timbul rujukan untuk anotasi`,annotDelete:`Padam anotasi yang difokuskan`,annotNavigate:`Navigasi melalui anotasi`,annotNavigateBack:`Navigasi anotasi ke belakang`,listsTitle:`Senarai & Grid`,listsFilterNav:`Navigasi penapis jenis entiti`,listsGridNav:`Navigasi grid sumber`,listsJumpFirst:`Lompat ke item pertama`,listsJumpLast:`Lompat ke item terakhir`,searchModalTitle:`Dalam Modal Carian`,searchNav:`Navigasi hasil carian`,searchSelect:`Pilih hasil`,searchClose:`Tutup carian`,modalTitle:`Kawalan Modal`,modalClose:`Tutup modal aktif`,modalNavForward:`Navigasi ke hadapan melalui butang`,modalNavBackward:`Navigasi ke belakang melalui butang`,modalActivate:`Aktifkan butang yang difokuskan`,accessibilityTitle:`Kebolehcapaian`,a11ySkipLinks:`Navigasi ke pautan langkau (apabila di permulaan halaman)`,a11yFollowLink:`Ikuti pautan langkau`,macNote:`Menggunakan pintasan papan kekunci Mac. ⌘ ialah kekunci Command.`,windowsNote:`Menggunakan pintasan papan kekunci Windows/Linux. Ctrl ialah kekunci Control.`,footerHint:`Tekan {{key}} pada bila-bila masa untuk menunjukkan bantuan ini`,close:`Tutup`},f={modeGroup:`Mod`,browse:`Layari`,annotate:`Anotasi`,selectionGroup:`Motivasi`,clickGroup:`Klik`,shapeGroup:`Bentuk`,none:`Tiada`,linking:`Rujukan`,highlighting:`Sorotan`,assessing:`Nilai`,commenting:`Ulasan`,tagging:`Tag`,detail:`Perincian`,follow:`Ikuti`,deleting:`Padam`,jsonld:`JSON-LD`,rectangle:`Segi Empat Tepat`,circle:`Bulatan`,polygon:`Poligon`},p={title:`Navigasi`,collapseSidebar:`Kecilkan bar sisi`,expandSidebar:`Kembangkan bar sisi`,dragToReorder:`Seret untuk menyusun semula`,dragToReorderDoc:`Seret untuk menyusun semula {{name}}`,closeResource:`Tutup sumber`,dragInstructions:`Untuk menyusun semula sumber: Gunakan Tab untuk navigasi ke sumber. Tekan Alt+Anak panah atas untuk bergerak ke atas atau Alt+Anak panah bawah untuk bergerak ke bawah. Untuk seret dan lepas: Tekan bar ruang untuk mengangkat item. Gunakan kekunci anak panah untuk mengalihkannya. Tekan bar ruang sekali lagi untuk melepaskan.`},m={deleteConfirmationTitle:`Padam Anotasi`,deleteConfirmationMessage:`Adakah anda pasti mahu memadam anotasi ini? Tindakan ini tidak boleh dibatalkan.`,deleteConfirmationCancel:`Batal`,deleteConfirmationDelete:`Padam`},h={title:`Tetapan`,lineNumbers:`Nombor Baris`,lineNumbersVisible:`Kelihatan`,lineNumbersHidden:`Tersembunyi`,theme:`Tema`,themeLight:`Cerah`,themeDark:`Gelap`,themeSystem:`Sistem`,themeSystemActive:`Sistem ({{mode}})`,themeModeActive:`Menggunakan mod {{mode}}`,language:`Bahasa`,languageHint:`Tukar bahasa dalam navigasi utama`,languageChanging:`Menukar bahasa...`,hoverDelay:`Kelewatan Terapung`,hoverDelayFast:`Pantas`,hoverDelaySlow:`Perlahan`,hoverDelayDescription:`Kelewatan {{delay}}ms sebelum kesan terapung muncul`},g={},_={gatherTitle:`Konteks Dikumpul`,configureGenerationTitle:`Konfigurasi Penjanaan`,configureSearchTitle:`Konfigurasi carian`,searchResultsTitle:`Hasil carian`,sourceContextLabel:`Konteks anotasi dalam sumber`,connectionsLabel:`Anotasi rakan sebaya`,citedByLabel:`Sumber dipetik oleh`,userHintLabel:`Petunjuk`,userHintPlaceholder:`Terangkan apa yang dirujuk oleh anotasi ini...`,loadingContext:`Mengumpul konteks...`,failedContext:`Gagal mengumpul konteks`,cancel:`Batal`,generate:`Jana`,compose:`Karang`,resolutionStrategyLabel:`Strategi resolusi`,back:`Kembali`,link:`Pautan`,score:`Skor`,noResults:`Tiada hasil ditemui`,resourceTitle:`Tajuk Sumber`,resourceTitlePlaceholder:`Masukkan tajuk sumber...`,additionalInstructions:`Arahan Tambahan`,additionalInstructionsPlaceholder:`Masukkan arahan tambahan...`,language:`Bahasa`,languageHelp:`Bahasa untuk kandungan yang dijana`,creativity:`Kreativiti`,creativityFocused:`Tertumpu`,creativityCreative:`Kreatif`,maxLength:`Panjang Maksimum`,maxLengthHelp:`Bilangan maksimum token`,maxResults:`Hasil Maksimum`,semanticScoring:`Pemarkahan Semantik`,semanticScoringHelp:`Gunakan AI untuk menilai hasil mengikut kerelevanan semantik`,searching:`Mencari...`,search:`Cari`},v={Toolbar:e,ResourceInfoPanel:t,CollaborationPanel:n,AnnotationHistory:r,CommentsPanel:i,HighlightPanel:a,AssessmentPanel:o,TaggingPanel:s,UnifiedAnnotationsPanel:c,StatisticsPanel:l,ReferencesPanel:u,KeyboardShortcuts:d,AnnotateToolbar:f,CollapsibleResourceNavigation:p,ResourceViewer:m,Settings:h,AnnotateView:g,ReferenceWizard:_};export{f as AnnotateToolbar,g as AnnotateView,r as AnnotationHistory,o as AssessmentPanel,n as CollaborationPanel,p as CollapsibleResourceNavigation,i as CommentsPanel,a as HighlightPanel,d as KeyboardShortcuts,_ as ReferenceWizard,u as ReferencesPanel,t as ResourceInfoPanel,m as ResourceViewer,h as Settings,l as StatisticsPanel,s as TaggingPanel,e as Toolbar,c as UnifiedAnnotationsPanel,v as default};
2
- //# sourceMappingURL=ms-POZGBKPH-CgcHbUoC.js.map
2
+ //# sourceMappingURL=ms-YBAO3S6K-CgcHbUoC.js.map