@embedpdf/viewer-chrome 3.0.0-next.15 → 3.0.0-next.16

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 (200) hide show
  1. package/dist/{annotation-fonts-BqoLZ4Mp.js → annotation-fonts-DWjVOTP0.js} +2 -2
  2. package/dist/{annotation-fonts-BqoLZ4Mp.js.map → annotation-fonts-DWjVOTP0.js.map} +1 -1
  3. package/dist/{annotation-fonts-Dt0IQXhz.cjs → annotation-fonts-dpfVkhnq.cjs} +2 -2
  4. package/dist/{annotation-fonts-Dt0IQXhz.cjs.map → annotation-fonts-dpfVkhnq.cjs.map} +1 -1
  5. package/dist/{annotation-style-Bzvvp8-N.cjs → annotation-style-B3XKAyZ-.cjs} +3 -3
  6. package/dist/{annotation-style-Bzvvp8-N.cjs.map → annotation-style-B3XKAyZ-.cjs.map} +1 -1
  7. package/dist/{annotation-style--rPIZsuP.js → annotation-style-CXF3X47Z.js} +3 -3
  8. package/dist/{annotation-style--rPIZsuP.js.map → annotation-style-CXF3X47Z.js.map} +1 -1
  9. package/dist/{ar-DnEj5vbP.cjs → ar-B132r9bo.cjs} +93 -1
  10. package/dist/ar-B132r9bo.cjs.map +1 -0
  11. package/dist/{ar-D9XKAmDx.js → ar-BLWFJoA_.js} +93 -1
  12. package/dist/ar-BLWFJoA_.js.map +1 -0
  13. package/dist/attachments-panel-Cxln8xos.cjs +217 -0
  14. package/dist/attachments-panel-Cxln8xos.cjs.map +1 -0
  15. package/dist/attachments-panel-H1ucRbwo.js +217 -0
  16. package/dist/attachments-panel-H1ucRbwo.js.map +1 -0
  17. package/dist/chrome.cjs +21 -0
  18. package/dist/chrome.cjs.map +1 -1
  19. package/dist/chrome.js +21 -0
  20. package/dist/chrome.js.map +1 -1
  21. package/dist/{commands-BmgxhJ8B.js → commands-BkgLP3Om.js} +418 -23
  22. package/dist/commands-BkgLP3Om.js.map +1 -0
  23. package/dist/{commands-CYt4SFUX.cjs → commands-DL1gjZt7.cjs} +433 -20
  24. package/dist/commands-DL1gjZt7.cjs.map +1 -0
  25. package/dist/commands.cjs +2 -1
  26. package/dist/commands.d.cts +3 -1
  27. package/dist/commands.d.ts +3 -1
  28. package/dist/commands.js +2 -2
  29. package/dist/{comments-panel-pEcQg4Vs.cjs → comments-panel-BsnWedTh.cjs} +2 -2
  30. package/dist/{comments-panel-pEcQg4Vs.cjs.map → comments-panel-BsnWedTh.cjs.map} +1 -1
  31. package/dist/{comments-panel-MUVgLCBI.js → comments-panel-D7Eadws9.js} +2 -2
  32. package/dist/{comments-panel-MUVgLCBI.js.map → comments-panel-D7Eadws9.js.map} +1 -1
  33. package/dist/{de-Dv6zvbnd.cjs → de-7_MvFWzN.cjs} +93 -1
  34. package/dist/de-7_MvFWzN.cjs.map +1 -0
  35. package/dist/{de-Bdr4aWzm.js → de-BUhwc9-x.js} +93 -1
  36. package/dist/de-BUhwc9-x.js.map +1 -0
  37. package/dist/{dialog-B5GBisKv.js → dialog-BIb373cg.js} +3 -3
  38. package/dist/dialog-BIb373cg.js.map +1 -0
  39. package/dist/{dialog-t8F13BL_.cjs → dialog-CngKTnAM.cjs} +3 -3
  40. package/dist/dialog-CngKTnAM.cjs.map +1 -0
  41. package/dist/{es-BP09DR9w.cjs → es-DgYj-1L3.cjs} +93 -1
  42. package/dist/es-DgYj-1L3.cjs.map +1 -0
  43. package/dist/{es-BSXz5tBv.js → es-DoXTqFoO.js} +93 -1
  44. package/dist/es-DoXTqFoO.js.map +1 -0
  45. package/dist/{form-design-panel-vWWU9uB-.js → form-design-panel-CgV_5YWC.js} +3 -3
  46. package/dist/{form-design-panel-vWWU9uB-.js.map → form-design-panel-CgV_5YWC.js.map} +1 -1
  47. package/dist/{form-design-panel-B5MXTZ96.cjs → form-design-panel-D0FdmWXW.cjs} +3 -3
  48. package/dist/{form-design-panel-B5MXTZ96.cjs.map → form-design-panel-D0FdmWXW.cjs.map} +1 -1
  49. package/dist/{fr-Ckn3K9v1.js → fr-B-8NDhBA.js} +93 -1
  50. package/dist/fr-B-8NDhBA.js.map +1 -0
  51. package/dist/{fr-BBQQn7tJ.cjs → fr-C856dmQJ.cjs} +93 -1
  52. package/dist/fr-C856dmQJ.cjs.map +1 -0
  53. package/dist/{he-DRsG7bH7.cjs → he-BFTeNc4t.cjs} +93 -1
  54. package/dist/he-BFTeNc4t.cjs.map +1 -0
  55. package/dist/{he-wdGU5PkU.js → he-Dlh0fNXM.js} +93 -1
  56. package/dist/he-Dlh0fNXM.js.map +1 -0
  57. package/dist/{icons-x0Tc05bs.cjs → icons-1UfLUZ_y.cjs} +20 -1
  58. package/dist/icons-1UfLUZ_y.cjs.map +1 -0
  59. package/dist/{icons-BrK5iVL8.js → icons-7dB0Y1ct.js} +20 -1
  60. package/dist/icons-7dB0Y1ct.js.map +1 -0
  61. package/dist/index.cjs +740 -171
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +16 -2
  64. package/dist/index.d.ts +16 -2
  65. package/dist/index.js +727 -170
  66. package/dist/index.js.map +1 -1
  67. package/dist/{it-BuP4o0xQ.cjs → it-Bef-2Yxq.cjs} +93 -1
  68. package/dist/it-Bef-2Yxq.cjs.map +1 -0
  69. package/dist/{it-Us-VmvIu.js → it-BkirG7ol.js} +93 -1
  70. package/dist/it-BkirG7ol.js.map +1 -0
  71. package/dist/{ja-Cizj0-5O.js → ja-CGEjCE-s.js} +93 -1
  72. package/dist/ja-CGEjCE-s.js.map +1 -0
  73. package/dist/{ja-DovEd6ts.cjs → ja-DNw2zqSD.cjs} +93 -1
  74. package/dist/ja-DNw2zqSD.cjs.map +1 -0
  75. package/dist/{ko-DlrXliE1.js → ko-CTkl5vMh.js} +93 -1
  76. package/dist/ko-CTkl5vMh.js.map +1 -0
  77. package/dist/{ko-B-qJEol2.cjs → ko-YHzeBqP6.cjs} +93 -1
  78. package/dist/ko-YHzeBqP6.cjs.map +1 -0
  79. package/dist/{link-editor-CSjqPnj1.cjs → link-editor-CAS7MZM2.cjs} +2 -2
  80. package/dist/{link-editor-CSjqPnj1.cjs.map → link-editor-CAS7MZM2.cjs.map} +1 -1
  81. package/dist/{link-editor-SxM1nnJU.js → link-editor-CkwtqRvb.js} +2 -2
  82. package/dist/{link-editor-SxM1nnJU.js.map → link-editor-CkwtqRvb.js.map} +1 -1
  83. package/dist/{measurement-Bs61XWbJ.js → measurement-CQdbnIrn.js} +2 -2
  84. package/dist/{measurement-Bs61XWbJ.js.map → measurement-CQdbnIrn.js.map} +1 -1
  85. package/dist/{measurement-CcCsHPOX.cjs → measurement-Cxv1Ahxx.cjs} +2 -2
  86. package/dist/{measurement-CcCsHPOX.cjs.map → measurement-Cxv1Ahxx.cjs.map} +1 -1
  87. package/dist/{nl-D3KZDDiJ.cjs → nl-BjkbaLq3.cjs} +93 -1
  88. package/dist/nl-BjkbaLq3.cjs.map +1 -0
  89. package/dist/{nl-0aF7M_0h.js → nl-Dya4sR8_.js} +93 -1
  90. package/dist/nl-Dya4sR8_.js.map +1 -0
  91. package/dist/outline-panel-BpGtBdj0.cjs +707 -0
  92. package/dist/outline-panel-BpGtBdj0.cjs.map +1 -0
  93. package/dist/outline-panel-DO5_REYw.js +707 -0
  94. package/dist/outline-panel-DO5_REYw.js.map +1 -0
  95. package/dist/outline-properties-BCa2cc0t.js +330 -0
  96. package/dist/outline-properties-BCa2cc0t.js.map +1 -0
  97. package/dist/outline-properties-DT3FIxCw.cjs +330 -0
  98. package/dist/outline-properties-DT3FIxCw.cjs.map +1 -0
  99. package/dist/{pl-DSFhAUqx.cjs → pl-CKKdVnpZ.cjs} +93 -1
  100. package/dist/pl-CKKdVnpZ.cjs.map +1 -0
  101. package/dist/{pl-BW--AaCI.js → pl-DA9b5NVg.js} +93 -1
  102. package/dist/pl-DA9b5NVg.js.map +1 -0
  103. package/dist/print-dialog-BqIrHCBh.cjs +276 -0
  104. package/dist/print-dialog-BqIrHCBh.cjs.map +1 -0
  105. package/dist/print-dialog-DvcI2m2_.js +276 -0
  106. package/dist/print-dialog-DvcI2m2_.js.map +1 -0
  107. package/dist/{pt-C5S-8MC5.cjs → pt-DLcszlzi.cjs} +93 -1
  108. package/dist/pt-DLcszlzi.cjs.map +1 -0
  109. package/dist/{pt-DIhpU5pT.js → pt-Nm8yyjbX.js} +93 -1
  110. package/dist/pt-Nm8yyjbX.js.map +1 -0
  111. package/dist/{redact-confirm-CX_SY2ZN.cjs → redact-confirm-C6EiK8yN.cjs} +2 -2
  112. package/dist/{redact-confirm-CX_SY2ZN.cjs.map → redact-confirm-C6EiK8yN.cjs.map} +1 -1
  113. package/dist/{redact-confirm-B6j36TPw.js → redact-confirm-CKuv9iN_.js} +2 -2
  114. package/dist/{redact-confirm-B6j36TPw.js.map → redact-confirm-CKuv9iN_.js.map} +1 -1
  115. package/dist/{redaction-panel-IJDshSJI.js → redaction-panel-CgNZ-pQk.js} +2 -2
  116. package/dist/{redaction-panel-IJDshSJI.js.map → redaction-panel-CgNZ-pQk.js.map} +1 -1
  117. package/dist/{redaction-panel-BmoIl-Ll.cjs → redaction-panel-ZhX0dlMi.cjs} +2 -2
  118. package/dist/{redaction-panel-BmoIl-Ll.cjs.map → redaction-panel-ZhX0dlMi.cjs.map} +1 -1
  119. package/dist/{search-panel-HfIhJm1M.js → search-panel-BE4xzWlm.js} +4 -4
  120. package/dist/{search-panel-HfIhJm1M.js.map → search-panel-BE4xzWlm.js.map} +1 -1
  121. package/dist/{search-panel-s9IoiOtv.cjs → search-panel-wcbTNG1z.cjs} +4 -4
  122. package/dist/{search-panel-s9IoiOtv.cjs.map → search-panel-wcbTNG1z.cjs.map} +1 -1
  123. package/dist/{sheet-BDsa_Sup.cjs → sheet-DTBFiwde.cjs} +30 -11
  124. package/dist/sheet-DTBFiwde.cjs.map +1 -0
  125. package/dist/{sheet-R6XDgyEf.js → sheet-DyjKfAq0.js} +25 -12
  126. package/dist/sheet-DyjKfAq0.js.map +1 -0
  127. package/dist/{sign-dialog-CgnR7akj.cjs → sign-dialog-D5WGx-Yn.cjs} +2 -2
  128. package/dist/{sign-dialog-CgnR7akj.cjs.map → sign-dialog-D5WGx-Yn.cjs.map} +1 -1
  129. package/dist/{sign-dialog-GDqCoQhA.js → sign-dialog-DerNe8qT.js} +2 -2
  130. package/dist/{sign-dialog-GDqCoQhA.js.map → sign-dialog-DerNe8qT.js.map} +1 -1
  131. package/dist/{signature-inspector-DyO313Qf.cjs → signature-inspector-Bz6TAfZM.cjs} +4 -10
  132. package/dist/signature-inspector-Bz6TAfZM.cjs.map +1 -0
  133. package/dist/{signature-inspector-okFz8do6.js → signature-inspector-CsGr9EBk.js} +4 -10
  134. package/dist/signature-inspector-CsGr9EBk.js.map +1 -0
  135. package/dist/{signature-maker-BoYa8vgA.cjs → signature-maker-D_YfBXLn.cjs} +3 -3
  136. package/dist/{signature-maker-BoYa8vgA.cjs.map → signature-maker-D_YfBXLn.cjs.map} +1 -1
  137. package/dist/{signature-maker-BhCmYyHD.js → signature-maker-Dnth4rV4.js} +3 -3
  138. package/dist/{signature-maker-BhCmYyHD.js.map → signature-maker-Dnth4rV4.js.map} +1 -1
  139. package/dist/{signatures-panel-B56PC6d9.cjs → signatures-panel-Ci_LaI1C.cjs} +4 -10
  140. package/dist/signatures-panel-Ci_LaI1C.cjs.map +1 -0
  141. package/dist/{signatures-panel-CgnFfhFm.js → signatures-panel-DZ9ywrjz.js} +4 -10
  142. package/dist/signatures-panel-DZ9ywrjz.js.map +1 -0
  143. package/dist/{stamps-panel-CDO0FPyK.js → stamps-panel-BrczStaz.js} +4 -10
  144. package/dist/stamps-panel-BrczStaz.js.map +1 -0
  145. package/dist/{stamps-panel-B9NYGayn.cjs → stamps-panel-Cv9nJBwx.cjs} +4 -10
  146. package/dist/stamps-panel-Cv9nJBwx.cjs.map +1 -0
  147. package/dist/theme-Be0OZokZ.js +97 -0
  148. package/dist/theme-Be0OZokZ.js.map +1 -0
  149. package/dist/theme-FR26JI3r.cjs +126 -0
  150. package/dist/theme-FR26JI3r.cjs.map +1 -0
  151. package/dist/{toolbar-z9od3tKl.js → toolbar-DF361xWY.js} +7 -6
  152. package/dist/toolbar-DF361xWY.js.map +1 -0
  153. package/dist/{toolbar-CJu2wKTU.cjs → toolbar-ddvpsvTb.cjs} +7 -6
  154. package/dist/toolbar-ddvpsvTb.cjs.map +1 -0
  155. package/dist/{zh-cn-CxkUUBct.js → zh-cn-BMPPkLpL.js} +93 -1
  156. package/dist/zh-cn-BMPPkLpL.js.map +1 -0
  157. package/dist/{zh-cn-3tmMeHqv.cjs → zh-cn-CZOO3p4H.cjs} +93 -1
  158. package/dist/zh-cn-CZOO3p4H.cjs.map +1 -0
  159. package/package.json +4 -4
  160. package/src/styles.css +8 -0
  161. package/dist/ar-D9XKAmDx.js.map +0 -1
  162. package/dist/ar-DnEj5vbP.cjs.map +0 -1
  163. package/dist/commands-BmgxhJ8B.js.map +0 -1
  164. package/dist/commands-CYt4SFUX.cjs.map +0 -1
  165. package/dist/de-Bdr4aWzm.js.map +0 -1
  166. package/dist/de-Dv6zvbnd.cjs.map +0 -1
  167. package/dist/dialog-B5GBisKv.js.map +0 -1
  168. package/dist/dialog-t8F13BL_.cjs.map +0 -1
  169. package/dist/es-BP09DR9w.cjs.map +0 -1
  170. package/dist/es-BSXz5tBv.js.map +0 -1
  171. package/dist/fr-BBQQn7tJ.cjs.map +0 -1
  172. package/dist/fr-Ckn3K9v1.js.map +0 -1
  173. package/dist/he-DRsG7bH7.cjs.map +0 -1
  174. package/dist/he-wdGU5PkU.js.map +0 -1
  175. package/dist/icons-BrK5iVL8.js.map +0 -1
  176. package/dist/icons-x0Tc05bs.cjs.map +0 -1
  177. package/dist/it-BuP4o0xQ.cjs.map +0 -1
  178. package/dist/it-Us-VmvIu.js.map +0 -1
  179. package/dist/ja-Cizj0-5O.js.map +0 -1
  180. package/dist/ja-DovEd6ts.cjs.map +0 -1
  181. package/dist/ko-B-qJEol2.cjs.map +0 -1
  182. package/dist/ko-DlrXliE1.js.map +0 -1
  183. package/dist/nl-0aF7M_0h.js.map +0 -1
  184. package/dist/nl-D3KZDDiJ.cjs.map +0 -1
  185. package/dist/pl-BW--AaCI.js.map +0 -1
  186. package/dist/pl-DSFhAUqx.cjs.map +0 -1
  187. package/dist/pt-C5S-8MC5.cjs.map +0 -1
  188. package/dist/pt-DIhpU5pT.js.map +0 -1
  189. package/dist/sheet-BDsa_Sup.cjs.map +0 -1
  190. package/dist/sheet-R6XDgyEf.js.map +0 -1
  191. package/dist/signature-inspector-DyO313Qf.cjs.map +0 -1
  192. package/dist/signature-inspector-okFz8do6.js.map +0 -1
  193. package/dist/signatures-panel-B56PC6d9.cjs.map +0 -1
  194. package/dist/signatures-panel-CgnFfhFm.js.map +0 -1
  195. package/dist/stamps-panel-B9NYGayn.cjs.map +0 -1
  196. package/dist/stamps-panel-CDO0FPyK.js.map +0 -1
  197. package/dist/toolbar-CJu2wKTU.cjs.map +0 -1
  198. package/dist/toolbar-z9od3tKl.js.map +0 -1
  199. package/dist/zh-cn-3tmMeHqv.cjs.map +0 -1
  200. package/dist/zh-cn-CxkUUBct.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"annotation-style--rPIZsuP.js","names":[],"sources":["../src/ui/annotation-flags.tsx","../src/ui/annotation-style.tsx"],"sourcesContent":["/**\n * The annotation flags section: a live test surface for `/F` (ISO 32000\n * Table 167). Select any annotation(s) and toggle flags. Flags are\n * properties like any other: the reads come from `useAnnotationProperties()`\n * (a flag the selection disagrees on is `mixed`, an indeterminate checkbox),\n * each named as the schema names it, and the writes go through\n * `selection.update({ locked: true })`. The hint under each is the viewer's.\n *\n * Things to try:\n * - `locked`: the selection keeps its outline but loses handles/knob; move,\n * restyle and delete are refused; unchecking it here still works.\n * - `hidden` / `noView`: the annotation disappears (it stays selected, so\n * this panel can bring it back).\n * - `readOnly`: visible but no longer clickable — deselect and try.\n * - `noZoom` / `noRotate`: zoom or rotate the page; the body keeps its\n * screen size / stays upright, anchored at its top-left corner.\n * - `print`: flip it off and print/flatten elsewhere — the annotation is\n * excluded (viewer rendering is unaffected).\n */\nimport {\n useAnnotation,\n useAnnotationProperties,\n type AnnotationFlags,\n} from '@embedpdf/react/annotation';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useEffect, useRef } from 'react';\n\nimport { useLabel } from './labels';\n\n/** What each flag does, in a few words under its name: the hint's key. */\nconst FLAG_HINTS: Readonly<Record<keyof AnnotationFlags, string>> = {\n print: 'annotationFlags.print',\n hidden: 'annotationFlags.hidden',\n noView: 'annotationFlags.noView',\n toggleNoView: 'annotationFlags.toggleNoView',\n readOnly: 'annotationFlags.readOnly',\n locked: 'annotationFlags.locked',\n lockedContents: 'annotationFlags.lockedContents',\n noZoom: 'annotationFlags.noZoom',\n noRotate: 'annotationFlags.noRotate',\n invisible: 'annotationFlags.invisible',\n};\n\nfunction FlagRow({\n label,\n hint,\n value,\n onToggle,\n}: {\n label: string;\n hint: string;\n value: boolean | null;\n onToggle: (next: boolean) => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n // `null` = the selected annotations disagree → the native indeterminate state.\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = value === null;\n }, [value]);\n return (\n <label className=\"hover:bg-hover flex cursor-pointer items-start gap-2.5 rounded px-1.5 py-1.5\">\n <input\n ref={ref}\n type=\"checkbox\"\n className=\"accent-accent mt-0.5\"\n checked={value === true}\n onChange={() => onToggle(value !== true)}\n />\n <span className=\"min-w-0\">\n <span className=\"text-fg block text-sm leading-tight\">{label}</span>\n <span className=\"text-fg-muted block text-xs leading-tight\">{hint}</span>\n </span>\n </label>\n );\n}\n\n/** The `/F` flags of the current selection, live-editable. Renders nothing\n * when nothing is selected (the style panel shows its tool defaults then). */\nexport function AnnotationFlagsSection() {\n const t = useT();\n const label = useLabel();\n const annotation = useAnnotation();\n const { properties, values, mixed } = useAnnotationProperties();\n const flags = properties.filter((property) => property.control === 'flag');\n if (!flags.length) return null;\n const valueOf = (key: keyof AnnotationFlags): boolean | null =>\n mixed.includes(key) ? null : values[key] === true;\n return (\n <section className=\"border-border mt-2 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('annotationFlags.title')}\n </p>\n <div className=\"flex flex-col\">\n {flags.map((flag) => (\n <FlagRow\n key={flag.key}\n label={label(flag)}\n hint={t(FLAG_HINTS[flag.key])}\n value={valueOf(flag.key)}\n onToggle={(next) => void annotation.selection.update({ [flag.key]: next })}\n />\n ))}\n </div>\n </section>\n );\n}\n","/**\n * The annotation style panel. The plugin owns the schema and the state; this\n * file owns only how each property renders and the engine fields it writes\n * back. There is no per-subtype branching here: a new annotation kind that\n * declares its properties in the kind table gets a working style panel for free.\n *\n * Data flow (mirrors examples/react's AnnotationSidebar):\n * selection present → useAnnotationProperties(), write selection.update()\n * nothing selected → useAnnotationProperties(tool), write tools.updateDefaults(tool, …)\n *\n * The look: a six-column swatch grid, range slider, SVG stroke / line-ending\n * dropdowns, font-size combo and align toggles, styled with this app's\n * semantic tokens (bg-surface / text-fg / border-border …).\n */\nimport { useEffect, useRef, useState } from 'react';\nimport { annotationKey } from '@embedpdf/react/annotation';\nimport type { ReactNode } from 'react';\nimport {\n useAnnotation,\n useAnnotationDefaults,\n useAnnotationProperties,\n useAnnotationState,\n type AnnotationOption,\n type AnnotationPatch,\n type AnnotationProperty,\n type BlendMode,\n type FieldValues,\n type LineEnding,\n type LineEndings,\n type TextAlign,\n} from '@embedpdf/react/annotation';\nimport { useCommands } from '@embedpdf/react/commands';\nimport { useInteractionState } from '@embedpdf/react/interaction';\nimport { useDocumentId, useKernelValue, useOptionalCapability } from '@embedpdf/react/runtime';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { useT } from '@embedpdf/react/i18n';\nimport { observeOutsidePress } from '@embedpdf/web';\nimport { Icon } from './icons';\nimport { useAnnotationFonts } from './annotation-fonts';\nimport { AnnotationFlagsSection } from './annotation-flags';\nimport { useLabel } from './labels';\n\n// ── app-level vocabulary (a viewer's decision) ────────────────────────────────\n// The schema says which controls to show, with each one's label and its\n// options' labels; these lists say what the viewer offers inside a color /\n// font / stroke picker.\nconst PRESET_COLORS = [\n '#000000',\n '#5f6368',\n '#e44234',\n '#ff8b00',\n '#ffd500',\n '#00cc66',\n '#00b8d9',\n '#4a90e2',\n '#9b51e0',\n '#f272c8',\n '#a0522d',\n '#ffffff',\n];\n\n/** The standard fonts the picker offers, of the schema's; the registered fonts follow them. */\nconst OFFERED_FONTS: readonly string[] = ['helvetica', 'helvetica-bold', 'times-roman', 'courier'];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 24, 36, 48, 72];\n\n/** A border as the picker draws it; the engine keeps it as three fields. */\ntype Border =\n | { kind: 'solid' }\n | { kind: 'dashed'; dash: number[] }\n | { kind: 'cloudy'; intensity: number };\n\n/** The borders the picker offers: the schema's styles, a dash or a cloud in a few sizes. */\nconst BORDER_OPTS: { key: string; make: () => Border }[] = [\n { key: 'solid', make: () => ({ kind: 'solid' }) },\n { key: 'dashed-6-2', make: () => ({ kind: 'dashed', dash: [6, 2] }) },\n { key: 'dashed-3-3', make: () => ({ kind: 'dashed', dash: [3, 3] }) },\n { key: 'dashed-1-2', make: () => ({ kind: 'dashed', dash: [1, 2] }) },\n { key: 'cloudy-1', make: () => ({ kind: 'cloudy', intensity: 1 }) },\n { key: 'cloudy-2', make: () => ({ kind: 'cloudy', intensity: 2 }) },\n];\nconst borderKey = (border: Border): string =>\n border.kind === 'cloudy'\n ? `cloudy-${border.intensity >= 2 ? 2 : 1}`\n : border.kind === 'dashed'\n ? `dashed-${border.dash.join('-')}`\n : 'solid';\n\n/** The border the three engine fields describe: a cloud wins over the style under it. */\nconst borderOf = (values: FieldValues): Border => {\n const intensity = values.cloudyIntensity as number | null | undefined;\n if (intensity) return { kind: 'cloudy', intensity };\n const dash = values.dashArray as number[] | null | undefined;\n return values.borderStyle === 'dashed'\n ? { kind: 'dashed', dash: dash?.length ? dash : [3, 3] }\n : { kind: 'solid' };\n};\n\n/** The engine fields that state a border, every one of them (a patch replaces each whole). */\nconst borderFields = (border: Border): FieldValues => ({\n borderStyle: border.kind === 'dashed' ? 'dashed' : 'solid',\n dashArray: border.kind === 'dashed' ? border.dash : null,\n cloudyIntensity: border.kind === 'cloudy' ? border.intensity : null,\n});\n\n/** The option of a choice with this value, for its label. */\nconst optionOf = (options: readonly AnnotationOption[], value: string) =>\n options.find((option) => option.value === value);\n\n// ── layout primitives ────────────────────────────────────────────────────────\nfunction Field({\n label,\n mixed,\n children,\n}: {\n label: string;\n mixed?: boolean;\n children: ReactNode;\n}) {\n const t = useT();\n return (\n <section className=\"mb-5\">\n <label className=\"text-fg mb-2 block text-sm font-medium\">\n {label}\n {mixed && (\n <span className=\"text-fg-muted ms-1.5 text-xs font-normal\">{t('stylePanel.mixed')}</span>\n )}\n </label>\n {children}\n </section>\n );\n}\n\n// ── color swatch grid ────────────────────────────────────────────────────────\nconst isTransparent = (color: string | null) =>\n color == null ||\n color === 'transparent' ||\n (/^#([0-9a-f]{8})$/i.test(color) && color.slice(-2).toLowerCase() === '00');\n\nfunction Swatch({\n color,\n active,\n onSelect,\n}: {\n color: string;\n active: boolean;\n onSelect: (color: string) => void;\n}) {\n const t = useT();\n const style = isTransparent(color)\n ? {\n backgroundColor: '#fff',\n backgroundImage:\n 'linear-gradient(45deg, transparent 40%, #ef4444 40%, #ef4444 60%, transparent 60%)',\n backgroundSize: '100% 100%',\n }\n : { backgroundColor: color };\n return (\n <button\n type=\"button\"\n title={isTransparent(color) ? t('stylePanel.transparent') : color}\n onClick={() => onSelect(color)}\n className={`border-border-strong h-5 w-5 rounded-full border ${active ? 'outline-accent outline outline-2 outline-offset-2' : ''}`}\n style={style}\n />\n );\n}\n\nfunction SwatchGrid({\n value,\n onSelect,\n allowTransparent,\n}: {\n value: string | null | undefined;\n onSelect: (color: string) => void;\n allowTransparent?: boolean;\n}) {\n const active = (color: string) => color.toLowerCase() === (value ?? '').toLowerCase();\n return (\n <div className=\"grid grid-cols-6 gap-x-1 gap-y-3\">\n {PRESET_COLORS.map((color) => (\n <Swatch key={color} color={color} active={active(color)} onSelect={onSelect} />\n ))}\n {allowTransparent && (\n <Swatch color=\"transparent\" active={isTransparent(value ?? null)} onSelect={onSelect} />\n )}\n </div>\n );\n}\n\n// ── range slider ─────────────────────────────────────────────────────────────\nfunction RangeSlider({\n value,\n min,\n max,\n step,\n onChange,\n}: {\n value: number;\n min: number;\n max: number;\n step: number;\n onChange: (value: number) => void;\n}) {\n return (\n <input\n type=\"range\"\n className=\"accent-accent mb-1.5 h-1 w-full cursor-pointer\"\n value={value}\n min={min}\n max={max}\n step={step}\n onChange={(event) => onChange(parseFloat(event.target.value))}\n />\n );\n}\n\n// ── dropdown shell (open state, outside-click, trigger + panel) ───────────────\n/** Close an open dropdown on a press outside it; the root holds its trigger too. */\nfunction useOutsideClose(open: boolean, close: () => void) {\n const rootRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const root = rootRef.current;\n return open && root ? observeOutsidePress(root, close) : undefined;\n }, [open, close]);\n return rootRef;\n}\n\nfunction DropdownShell({\n trigger,\n children,\n}: {\n trigger: ReactNode;\n children: (close: () => void) => ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => setOpen((previous) => !previous)}\n className=\"border-border bg-surface text-fg flex w-full items-center justify-between gap-2 rounded border px-3 py-1.5\"\n >\n {trigger}\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary shrink-0\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-60 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {children(() => setOpen(false))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OptionRow({\n selected,\n title,\n onClick,\n children,\n}: {\n selected: boolean;\n /** The option's name, for an option drawn as a picture. */\n title?: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n aria-label={title}\n onClick={onClick}\n className={`hover:bg-hover flex w-full items-center rounded px-2 py-1.5 text-start text-sm ${selected ? 'bg-selected text-accent' : 'text-fg'}`}\n >\n {children}\n </button>\n );\n}\n\n// ── stroke / border preview + picker ─────────────────────────────────────────\nfunction borderSvg(border: Border): ReactNode {\n if (border.kind === 'cloudy') {\n const radius = border.intensity >= 2 ? 5 : 3;\n const bumps = Math.ceil(80 / (radius * 2));\n const step = 80 / bumps;\n const baseline = radius + 1;\n const viewH = radius * 2 + 2;\n const parts = [`M 0 ${baseline}`];\n for (let i = 0; i < bumps; i++)\n parts.push(`A ${radius} ${radius} 0 0 1 ${step * (i + 1)} ${baseline}`);\n return (\n <svg width=\"80\" height={viewH} viewBox={`0 0 80 ${viewH}`}>\n <path\n d={parts.join(' ')}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n }\n const dash = border.kind === 'dashed' ? border.dash.join(' ') : undefined;\n return (\n <svg width=\"80\" height=\"8\" viewBox=\"0 0 80 8\">\n <line\n x1=\"0\"\n y1=\"4\"\n x2=\"80\"\n y2=\"4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeDasharray={dash}\n />\n </svg>\n );\n}\n\nfunction BorderSelect({\n value,\n styles,\n onChange,\n}: {\n value: Border;\n /** The border styles the kind takes, with their labels. */\n styles: readonly AnnotationOption[];\n onChange: (border: Border) => void;\n}) {\n const label = useLabel();\n const options = BORDER_OPTS.filter((option) => optionOf(styles, option.make().kind));\n return (\n <DropdownShell trigger={<span className=\"text-fg-secondary\">{borderSvg(value)}</span>}>\n {(close) =>\n options.map((option) => {\n const border = option.make();\n return (\n <OptionRow\n key={option.key}\n selected={borderKey(value) === option.key}\n title={label(optionOf(styles, border.kind)!)}\n onClick={() => {\n onChange(border);\n close();\n }}\n >\n <span className=\"text-fg-secondary\">{borderSvg(border)}</span>\n </OptionRow>\n );\n })\n }\n </DropdownShell>\n );\n}\n\n// ── line-ending preview + picker ─────────────────────────────────────────────\nconst LE_MARKERS: Partial<Record<LineEnding, ReactNode>> = {\n square: <path d=\"M68 -4 L76 -4 L76 4 L68 4 Z\" />,\n circle: <circle cx=\"72\" cy=\"0\" r=\"4\" />,\n diamond: <path d=\"M72 -5 L77 0 L72 5 L67 0 Z\" />,\n 'open-arrow': <path d=\"M67 -5 L77 0 L67 5\" fill=\"none\" />,\n 'closed-arrow': <path d=\"M67 -5 L77 0 L67 5 Z\" />,\n 'r-open-arrow': <path d=\"M77 -5 L67 0 L77 5\" fill=\"none\" />,\n 'r-closed-arrow': <path d=\"M77 -5 L67 0 L77 5 Z\" />,\n butt: <path d=\"M72 -5 L72 5\" fill=\"none\" />,\n slash: <path d=\"M67 -5 L77 5\" fill=\"none\" />,\n};\nconst LE_LINE_END: Partial<Record<LineEnding, number>> = {\n square: 68,\n circle: 68,\n diamond: 67,\n 'open-arrow': 76,\n 'closed-arrow': 67,\n 'r-open-arrow': 67,\n 'r-closed-arrow': 67,\n butt: 72,\n slash: 72,\n};\n\nfunction LineEndingPreview({ name, side }: { name: LineEnding; side: 'start' | 'end' }) {\n const marker = LE_MARKERS[name];\n const lineEndX = LE_LINE_END[name] ?? 77;\n const transform = side === 'start' ? 'rotate(180 40 10)' : undefined;\n return (\n <svg width=\"80\" height=\"20\" viewBox=\"0 0 80 20\" className=\"text-fg\">\n <g transform={transform}>\n <line x1=\"4\" y1=\"10\" x2={lineEndX} y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n {marker && (\n <g\n transform=\"translate(0, 10)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n {marker}\n </g>\n )}\n </g>\n </svg>\n );\n}\n\nfunction LineEndingSelect({\n side,\n value,\n options,\n onChange,\n}: {\n side: 'start' | 'end';\n value: LineEnding;\n options: readonly AnnotationOption[];\n onChange: (ending: LineEnding) => void;\n}) {\n const label = useLabel();\n return (\n <DropdownShell trigger={<LineEndingPreview name={value} side={side} />}>\n {(close) =>\n options.map((option) => (\n <OptionRow\n key={option.value}\n selected={value === option.value}\n title={label(option)}\n onClick={() => {\n onChange(option.value as LineEnding);\n close();\n }}\n >\n <LineEndingPreview name={option.value as LineEnding} side={side} />\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font family picker ───────────────────────────────────────────────────────\nfunction FontFamilySelect({\n value,\n standard,\n onChange,\n}: {\n value: string;\n /** The schema's standard fonts, with their labels. */\n standard: readonly AnnotationOption[];\n onChange: (family: string) => void;\n}) {\n const label = useLabel();\n // The standard faces the viewer offers plus the configured fonts that are\n // registered and mounted (`engine.fonts`) — a registered key is a\n // `fontFamily` value like any standard name, labelled by the app.\n const configured = useAnnotationFonts();\n const options = [\n ...standard\n .filter((option) => OFFERED_FONTS.includes(option.value))\n .map((option) => ({ value: option.value, label: label(option) })),\n ...configured.map((font) => ({ value: font.key, label: font.label })),\n ];\n // A font the document uses that the picker doesn't offer still shows by its name.\n const named = optionOf(standard, value);\n const current =\n options.find((option) => option.value === value)?.label ?? (named ? label(named) : value);\n return (\n <DropdownShell trigger={<span className=\"text-fg text-sm\">{current}</span>}>\n {(close) =>\n options.map((option) => (\n <OptionRow\n key={option.value}\n selected={option.value === value}\n onClick={() => {\n onChange(option.value);\n close();\n }}\n >\n {option.label}\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font-size combo (number input + preset dropdown) ─────────────────────────\nfunction FontSizeCombo({ value, onChange }: { value: number; onChange: (size: number) => void }) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n // Typed text is a draft until Enter or blur (Escape discards): committing\n // per keystroke would apply \"2\" on the way to \"24\" — to the selected text\n // while editing. Presets commit at once.\n const [draft, setDraft] = useState<string | null>(null);\n const commit = () => {\n if (draft === null) return;\n const size = parseInt(draft, 10);\n setDraft(null);\n if (Number.isFinite(size) && size > 0 && size !== value) onChange(size);\n };\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <input\n type=\"number\"\n min={1}\n value={draft ?? value}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commit();\n setOpen(false);\n } else if (event.key === 'Escape') {\n setDraft(null);\n setOpen(false);\n }\n }}\n onClick={() => setOpen(true)}\n className=\"border-border bg-surface text-fg w-full rounded border px-2 py-1.5 pe-7 text-sm\"\n />\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={() => setOpen((previous) => !previous)}\n className=\"absolute inset-y-0 end-1 flex items-center\"\n >\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-48 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {FONT_SIZES.map((sz) => (\n <OptionRow\n key={sz}\n selected={sz === value}\n onClick={() => {\n setDraft(null);\n onChange(sz);\n setOpen(false);\n }}\n >\n {sz}\n </OptionRow>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction BlendModeSelect({\n value,\n options,\n name,\n onChange,\n}: {\n value: BlendMode;\n options: readonly AnnotationOption[];\n /** The field's label, the select's accessible name. */\n name: string;\n onChange: (mode: BlendMode) => void;\n}) {\n const label = useLabel();\n return (\n <select\n value={value}\n aria-label={name}\n onChange={(event) => onChange(event.target.value as BlendMode)}\n className=\"border-border bg-surface text-fg w-full rounded border px-3 py-1.5 text-sm\"\n >\n {options.map((mode) => (\n <option key={mode.value} value={mode.value}>\n {label(mode)}\n </option>\n ))}\n </select>\n );\n}\n\n// ── align toggle ─────────────────────────────────────────────────────────────\nfunction Toggle({\n active,\n title,\n onClick,\n keepFocus,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n /** Don't take focus on press — a text editor's selection survives the click. */\n keepFocus?: boolean;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n onMouseDown={keepFocus ? (event) => event.preventDefault() : undefined}\n className={`flex h-9 w-9 items-center justify-center rounded border transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\n// ── rich-text formatting: bold / italic / underline in one row ──────────────\ntype FormatSpec = Extract<AnnotationProperty, { key: 'bold' | 'italic' | 'underline' }>;\ntype Format = FormatSpec['key'];\nconst isFormatSpec = (spec: AnnotationProperty): spec is FormatSpec =>\n spec.key === 'bold' || spec.key === 'italic' || spec.key === 'underline';\n\n/**\n * The format toggles a free-text kind declares, in one row. While the text\n * editor holds a range they read and write that range's runs (the plugin\n * routes `toggleTextFormat`); otherwise the annotation's body. The buttons\n * keep focus in the editor so the range survives the click.\n */\nfunction FormatToggles({\n specs,\n values,\n mixed,\n onToggle,\n}: {\n specs: FormatSpec[];\n values: FieldValues;\n mixed: readonly string[];\n onToggle: (format: Format, on: boolean) => void;\n}) {\n const t = useT();\n const label = useLabel();\n return (\n <Field label={t('demo.formatLabel')} mixed={specs.some((spec) => mixed.includes(spec.key))}>\n <div className=\"flex gap-2\">\n {specs.map((spec) => {\n const active = values[spec.key] === true && !mixed.includes(spec.key);\n return (\n <Toggle\n key={spec.key}\n title={label(spec)}\n active={active}\n keepFocus\n onClick={() => onToggle(spec.key, !active)}\n >\n <Icon name={spec.key} size={18} />\n </Toggle>\n );\n })}\n </div>\n </Field>\n );\n}\n\n// ── one control per property: the entire surface an app customizes ──────────\nfunction FieldControl({\n spec,\n values,\n mixed,\n onChange,\n onChangeEach,\n}: {\n spec: AnnotationProperty;\n values: FieldValues;\n mixed: boolean;\n onChange: (patch: FieldValues) => void;\n /** Patch each target relative to itself: one side of its line endings. */\n onChangeEach: (patchOf: (current: FieldValues) => FieldValues) => void;\n}) {\n const t = useT();\n const label = useLabel();\n const value = values[spec.key];\n switch (spec.key) {\n case 'color':\n case 'fontColor':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <SwatchGrid\n value={value as string}\n onSelect={(color) => onChange({ [spec.key]: color })}\n />\n </Field>\n );\n case 'interiorColor':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <SwatchGrid\n value={value as string | null}\n allowTransparent\n onSelect={(color) =>\n onChange({ interiorColor: color === 'transparent' ? null : color })\n }\n />\n </Field>\n );\n case 'opacity': {\n const opacity = (value as number) ?? 1;\n return (\n <Field label={label(spec)} mixed={mixed}>\n <RangeSlider\n value={opacity}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(next) => onChange({ opacity: next })}\n />\n <span className=\"text-fg-muted text-xs\">{Math.round(opacity * 100)}%</span>\n </Field>\n );\n }\n case 'strokeWidth': {\n const strokeWidth = (value as number) ?? spec.min;\n return (\n <Field label={label(spec)} mixed={mixed}>\n <RangeSlider\n value={strokeWidth}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(next) => onChange({ strokeWidth: next })}\n />\n <span className=\"text-fg-muted text-xs\">{`${strokeWidth}px`}</span>\n </Field>\n );\n }\n case 'fontSize':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <FontSizeCombo\n value={(value as number) ?? 12}\n onChange={(next) => onChange({ fontSize: next })}\n />\n </Field>\n );\n case 'borderStyle':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <BorderSelect\n value={borderOf(values)}\n styles={spec.options}\n onChange={(border) => onChange(borderFields(border))}\n />\n </Field>\n );\n case 'lineEndings': {\n const le = (value as LineEndings) ?? { start: 'none', end: 'none' };\n return (\n <Field label={label(spec)} mixed={mixed}>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">{t('stylePanel.lineStart')}</div>\n <LineEndingSelect\n side=\"start\"\n value={le.start}\n options={spec.options}\n onChange={(ending) =>\n onChangeEach((current) => ({\n lineEndings: { ...(current.lineEndings as LineEndings), start: ending },\n }))\n }\n />\n </div>\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">{t('stylePanel.lineEnd')}</div>\n <LineEndingSelect\n side=\"end\"\n value={le.end}\n options={spec.options}\n onChange={(ending) =>\n onChangeEach((current) => ({\n lineEndings: { ...(current.lineEndings as LineEndings), end: ending },\n }))\n }\n />\n </div>\n </div>\n </Field>\n );\n }\n case 'fontFamily':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <FontFamilySelect\n value={(value as string) ?? 'helvetica'}\n standard={spec.options}\n onChange={(family) => onChange({ fontFamily: family })}\n />\n </Field>\n );\n case 'textAlign': {\n const alignIcon: Record<TextAlign, string> = {\n left: 'alignLeft',\n center: 'alignCenter',\n right: 'alignRight',\n };\n return (\n <Field label={label(spec)} mixed={mixed}>\n <div className=\"flex gap-2\">\n {spec.options.map((option) => {\n const al = option.value as TextAlign;\n return (\n <Toggle\n key={al}\n title={label(option)}\n active={value === al}\n onClick={() => onChange({ textAlign: al })}\n >\n <Icon name={alignIcon[al]} size={18} />\n </Toggle>\n );\n })}\n </div>\n </Field>\n );\n }\n // The rich-text format toggles render as one row (see `FormatToggles`);\n // each spec is still declared by the kind, so a kind without rich text\n // never shows them.\n case 'bold':\n case 'italic':\n case 'underline':\n return null;\n case 'blendMode':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <BlendModeSelect\n value={(value as BlendMode) ?? 'normal'}\n options={spec.options}\n name={label(spec)}\n onChange={(blendMode) => onChange({ blendMode })}\n />\n </Field>\n );\n // `link` deliberately renders nothing here: a link is a verb on the\n // selection, edited in the anchored popover (see ui/link-editor.tsx) —\n // never a style-panel section.\n case 'link':\n return null;\n default:\n return null;\n }\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nfunction EmptyState() {\n const t = useT();\n return (\n <div className=\"text-fg-muted flex flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n <Icon name=\"palette\" size={40} className=\"text-fg-disabled\" />\n <p className=\"max-w-[180px] text-sm\">{t('stylePanel.empty')}</p>\n </div>\n );\n}\n\n/** The rich body a format on or off is, merged over a tool's current one. */\nconst FORMAT_BODY: Record<Format, (on: boolean) => Record<string, unknown>> = {\n bold: (on) => ({ weight: on ? 700 : 400 }),\n italic: (on) => ({ italic: on }),\n underline: (on) => ({ decoration: on ? ['underline'] : [] }),\n};\n\n/**\n * The schema-driven style panel. Rendered inside the right sidebar's\n * `annotation-style` surface (see ui/panels.tsx). Owns its own scroll.\n */\nexport function AnnotationStylePanel() {\n const t = useT();\n const annotation = useAnnotation();\n const commands = useCommands();\n const documentId = useDocumentId() ?? undefined;\n // Without a document there is no active tool; the pointer's defaults are empty.\n const activeToolId = useInteractionState((state) => state.activeToolId) ?? 'pointer';\n const selection = useAnnotationProperties();\n const tool = useAnnotationProperties(activeToolId);\n const toolDefaults = useAnnotationDefaults(activeToolId);\n const selected = useAnnotationState((state) => state.selected);\n // The tool by its button's name: the defaults are that tool's.\n const toolLabel = useKernelValue(\n () => commands.resolveCommand(`tool:${activeToolId}`, documentId)?.label ?? null,\n Object.is,\n );\n\n const hasSel = selection.properties.length > 0;\n const { properties, values, mixed } = hasSel ? selection : tool;\n // The flags have their own section below, and a redaction's label its own.\n const fields = properties.filter(\n (property) => property.control !== 'flag' && property.control !== 'text',\n );\n const write = (patch: FieldValues) =>\n hasSel\n ? annotation.selection.update(patch as AnnotationPatch)\n : annotation.tools.updateDefaults(activeToolId, patch);\n const writeEach = (patchOf: (current: FieldValues) => FieldValues) =>\n hasSel\n ? annotation.selection.update(\n (member) => patchOf(member as unknown as FieldValues) as AnnotationPatch,\n )\n : annotation.tools.updateDefaults(activeToolId, patchOf(toolDefaults));\n const toggleFormat = (format: Format, on: boolean) => {\n if (hasSel) return void annotation.text.toggleFormat(format);\n const body = (toolDefaults.richText as { body?: Record<string, unknown> } | undefined)?.body;\n annotation.tools.updateDefaults(activeToolId, {\n richText: { body: { ...body, ...FORMAT_BODY[format](on) } },\n });\n };\n\n // A selection with no editable fields (e.g. a stamp, or a locked annotation —\n // its style is frozen) still shows its flags: that's how you unlock it.\n if (fields.length === 0 && selected.length === 0) return <EmptyState />;\n\n const context = hasSel\n ? t('stylePanel.selected', { params: { count: selected.length } })\n : toolLabel === null\n ? t('stylePanel.defaults')\n : t('stylePanel.toolDefaults', { params: { tool: toolLabel } });\n\n return (\n <div className=\"flex-1 overflow-y-auto p-4\">\n <p className=\"text-fg-muted mb-4 text-[11px] font-semibold uppercase tracking-wide\">\n {context}\n </p>\n {fields.map((spec) =>\n spec.key === 'bold' ? (\n <FormatToggles\n key=\"format\"\n specs={fields.filter((spec): spec is FormatSpec => isFormatSpec(spec))}\n values={values}\n mixed={mixed}\n onToggle={toggleFormat}\n />\n ) : (\n <FieldControl\n key={spec.key}\n spec={spec}\n values={values}\n mixed={mixed.includes(spec.key)}\n onChange={write}\n onChangeEach={writeEach}\n />\n ),\n )}\n {/* Redaction label (`/OverlayText` + `/Repeat`) — kind content, not a\n style field, so it writes through the redaction plugin's updateLabel. */}\n <RedactionLabelSection />\n {/* `/F` flags for whatever is selected — the live flags test surface. */}\n <AnnotationFlagsSection />\n </div>\n );\n}\n\n/**\n * Label editor shown when exactly one redaction mark is selected. The text is\n * what the destructive apply paints over the region (white-on-black by the\n * tool defaults); `repeat` tiles it. Writes ride the annotation update verb\n * via the redaction plugin, which preserves the label's `/DA` styling.\n */\nfunction RedactionLabelSection() {\n const t = useT();\n const redaction = useOptionalCapability(RedactionToken);\n const selected = useAnnotationState((state) => state.selected);\n const mark = selected.length === 1 && selected[0]!.subtype === 'redact' ? selected[0]! : null;\n const [draft, setDraft] = useState<string | null>(null);\n useEffect(() => setDraft(null), [mark?.ref && annotationKey(mark.ref)]);\n if (!redaction || !mark || mark.subtype !== 'redact') return null;\n\n const value = draft ?? mark.overlayText ?? '';\n const commit = () => {\n if (draft === null) return;\n void redaction.updateLabel(mark.ref, { overlayText: draft.length > 0 ? draft : null });\n setDraft(null);\n };\n\n return (\n <div className=\"border-border-subtle mt-4 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('demo.redactLabelTitle')}\n </p>\n <input\n type=\"text\"\n value={value}\n placeholder={t('demo.redactLabelPlaceholder')}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n onKeyDown={(event) => event.key === 'Enter' && commit()}\n className=\"border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm\"\n />\n <label className=\"text-fg mt-2 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={mark.repeat}\n onChange={(event) =>\n void redaction.updateLabel(mark.ref, { repeat: event.target.checked })\n }\n />\n {t('demo.redactLabelRepeat')}\n </label>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"annotation-style-CXF3X47Z.js","names":[],"sources":["../src/ui/annotation-flags.tsx","../src/ui/annotation-style.tsx"],"sourcesContent":["/**\n * The annotation flags section: a live test surface for `/F` (ISO 32000\n * Table 167). Select any annotation(s) and toggle flags. Flags are\n * properties like any other: the reads come from `useAnnotationProperties()`\n * (a flag the selection disagrees on is `mixed`, an indeterminate checkbox),\n * each named as the schema names it, and the writes go through\n * `selection.update({ locked: true })`. The hint under each is the viewer's.\n *\n * Things to try:\n * - `locked`: the selection keeps its outline but loses handles/knob; move,\n * restyle and delete are refused; unchecking it here still works.\n * - `hidden` / `noView`: the annotation disappears (it stays selected, so\n * this panel can bring it back).\n * - `readOnly`: visible but no longer clickable — deselect and try.\n * - `noZoom` / `noRotate`: zoom or rotate the page; the body keeps its\n * screen size / stays upright, anchored at its top-left corner.\n * - `print`: flip it off and print/flatten elsewhere — the annotation is\n * excluded (viewer rendering is unaffected).\n */\nimport {\n useAnnotation,\n useAnnotationProperties,\n type AnnotationFlags,\n} from '@embedpdf/react/annotation';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useEffect, useRef } from 'react';\n\nimport { useLabel } from './labels';\n\n/** What each flag does, in a few words under its name: the hint's key. */\nconst FLAG_HINTS: Readonly<Record<keyof AnnotationFlags, string>> = {\n print: 'annotationFlags.print',\n hidden: 'annotationFlags.hidden',\n noView: 'annotationFlags.noView',\n toggleNoView: 'annotationFlags.toggleNoView',\n readOnly: 'annotationFlags.readOnly',\n locked: 'annotationFlags.locked',\n lockedContents: 'annotationFlags.lockedContents',\n noZoom: 'annotationFlags.noZoom',\n noRotate: 'annotationFlags.noRotate',\n invisible: 'annotationFlags.invisible',\n};\n\nfunction FlagRow({\n label,\n hint,\n value,\n onToggle,\n}: {\n label: string;\n hint: string;\n value: boolean | null;\n onToggle: (next: boolean) => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n // `null` = the selected annotations disagree → the native indeterminate state.\n useEffect(() => {\n if (ref.current) ref.current.indeterminate = value === null;\n }, [value]);\n return (\n <label className=\"hover:bg-hover flex cursor-pointer items-start gap-2.5 rounded px-1.5 py-1.5\">\n <input\n ref={ref}\n type=\"checkbox\"\n className=\"accent-accent mt-0.5\"\n checked={value === true}\n onChange={() => onToggle(value !== true)}\n />\n <span className=\"min-w-0\">\n <span className=\"text-fg block text-sm leading-tight\">{label}</span>\n <span className=\"text-fg-muted block text-xs leading-tight\">{hint}</span>\n </span>\n </label>\n );\n}\n\n/** The `/F` flags of the current selection, live-editable. Renders nothing\n * when nothing is selected (the style panel shows its tool defaults then). */\nexport function AnnotationFlagsSection() {\n const t = useT();\n const label = useLabel();\n const annotation = useAnnotation();\n const { properties, values, mixed } = useAnnotationProperties();\n const flags = properties.filter((property) => property.control === 'flag');\n if (!flags.length) return null;\n const valueOf = (key: keyof AnnotationFlags): boolean | null =>\n mixed.includes(key) ? null : values[key] === true;\n return (\n <section className=\"border-border mt-2 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('annotationFlags.title')}\n </p>\n <div className=\"flex flex-col\">\n {flags.map((flag) => (\n <FlagRow\n key={flag.key}\n label={label(flag)}\n hint={t(FLAG_HINTS[flag.key])}\n value={valueOf(flag.key)}\n onToggle={(next) => void annotation.selection.update({ [flag.key]: next })}\n />\n ))}\n </div>\n </section>\n );\n}\n","/**\n * The annotation style panel. The plugin owns the schema and the state; this\n * file owns only how each property renders and the engine fields it writes\n * back. There is no per-subtype branching here: a new annotation kind that\n * declares its properties in the kind table gets a working style panel for free.\n *\n * Data flow (mirrors examples/react's AnnotationSidebar):\n * selection present → useAnnotationProperties(), write selection.update()\n * nothing selected → useAnnotationProperties(tool), write tools.updateDefaults(tool, …)\n *\n * The look: a six-column swatch grid, range slider, SVG stroke / line-ending\n * dropdowns, font-size combo and align toggles, styled with this app's\n * semantic tokens (bg-surface / text-fg / border-border …).\n */\nimport { useEffect, useRef, useState } from 'react';\nimport { annotationKey } from '@embedpdf/react/annotation';\nimport type { ReactNode } from 'react';\nimport {\n useAnnotation,\n useAnnotationDefaults,\n useAnnotationProperties,\n useAnnotationState,\n type AnnotationOption,\n type AnnotationPatch,\n type AnnotationProperty,\n type BlendMode,\n type FieldValues,\n type LineEnding,\n type LineEndings,\n type TextAlign,\n} from '@embedpdf/react/annotation';\nimport { useCommands } from '@embedpdf/react/commands';\nimport { useInteractionState } from '@embedpdf/react/interaction';\nimport { useDocumentId, useKernelValue, useOptionalCapability } from '@embedpdf/react/runtime';\nimport { RedactionToken } from '@embedpdf/react/redaction';\nimport { useT } from '@embedpdf/react/i18n';\nimport { observeOutsidePress } from '@embedpdf/web';\nimport { Icon } from './icons';\nimport { useAnnotationFonts } from './annotation-fonts';\nimport { AnnotationFlagsSection } from './annotation-flags';\nimport { useLabel } from './labels';\n\n// ── app-level vocabulary (a viewer's decision) ────────────────────────────────\n// The schema says which controls to show, with each one's label and its\n// options' labels; these lists say what the viewer offers inside a color /\n// font / stroke picker.\nconst PRESET_COLORS = [\n '#000000',\n '#5f6368',\n '#e44234',\n '#ff8b00',\n '#ffd500',\n '#00cc66',\n '#00b8d9',\n '#4a90e2',\n '#9b51e0',\n '#f272c8',\n '#a0522d',\n '#ffffff',\n];\n\n/** The standard fonts the picker offers, of the schema's; the registered fonts follow them. */\nconst OFFERED_FONTS: readonly string[] = ['helvetica', 'helvetica-bold', 'times-roman', 'courier'];\n\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 24, 36, 48, 72];\n\n/** A border as the picker draws it; the engine keeps it as three fields. */\ntype Border =\n | { kind: 'solid' }\n | { kind: 'dashed'; dash: number[] }\n | { kind: 'cloudy'; intensity: number };\n\n/** The borders the picker offers: the schema's styles, a dash or a cloud in a few sizes. */\nconst BORDER_OPTS: { key: string; make: () => Border }[] = [\n { key: 'solid', make: () => ({ kind: 'solid' }) },\n { key: 'dashed-6-2', make: () => ({ kind: 'dashed', dash: [6, 2] }) },\n { key: 'dashed-3-3', make: () => ({ kind: 'dashed', dash: [3, 3] }) },\n { key: 'dashed-1-2', make: () => ({ kind: 'dashed', dash: [1, 2] }) },\n { key: 'cloudy-1', make: () => ({ kind: 'cloudy', intensity: 1 }) },\n { key: 'cloudy-2', make: () => ({ kind: 'cloudy', intensity: 2 }) },\n];\nconst borderKey = (border: Border): string =>\n border.kind === 'cloudy'\n ? `cloudy-${border.intensity >= 2 ? 2 : 1}`\n : border.kind === 'dashed'\n ? `dashed-${border.dash.join('-')}`\n : 'solid';\n\n/** The border the three engine fields describe: a cloud wins over the style under it. */\nconst borderOf = (values: FieldValues): Border => {\n const intensity = values.cloudyIntensity as number | null | undefined;\n if (intensity) return { kind: 'cloudy', intensity };\n const dash = values.dashArray as number[] | null | undefined;\n return values.borderStyle === 'dashed'\n ? { kind: 'dashed', dash: dash?.length ? dash : [3, 3] }\n : { kind: 'solid' };\n};\n\n/** The engine fields that state a border, every one of them (a patch replaces each whole). */\nconst borderFields = (border: Border): FieldValues => ({\n borderStyle: border.kind === 'dashed' ? 'dashed' : 'solid',\n dashArray: border.kind === 'dashed' ? border.dash : null,\n cloudyIntensity: border.kind === 'cloudy' ? border.intensity : null,\n});\n\n/** The option of a choice with this value, for its label. */\nconst optionOf = (options: readonly AnnotationOption[], value: string) =>\n options.find((option) => option.value === value);\n\n// ── layout primitives ────────────────────────────────────────────────────────\nfunction Field({\n label,\n mixed,\n children,\n}: {\n label: string;\n mixed?: boolean;\n children: ReactNode;\n}) {\n const t = useT();\n return (\n <section className=\"mb-5\">\n <label className=\"text-fg mb-2 block text-sm font-medium\">\n {label}\n {mixed && (\n <span className=\"text-fg-muted ms-1.5 text-xs font-normal\">{t('stylePanel.mixed')}</span>\n )}\n </label>\n {children}\n </section>\n );\n}\n\n// ── color swatch grid ────────────────────────────────────────────────────────\nconst isTransparent = (color: string | null) =>\n color == null ||\n color === 'transparent' ||\n (/^#([0-9a-f]{8})$/i.test(color) && color.slice(-2).toLowerCase() === '00');\n\nfunction Swatch({\n color,\n active,\n onSelect,\n}: {\n color: string;\n active: boolean;\n onSelect: (color: string) => void;\n}) {\n const t = useT();\n const style = isTransparent(color)\n ? {\n backgroundColor: '#fff',\n backgroundImage:\n 'linear-gradient(45deg, transparent 40%, #ef4444 40%, #ef4444 60%, transparent 60%)',\n backgroundSize: '100% 100%',\n }\n : { backgroundColor: color };\n return (\n <button\n type=\"button\"\n title={isTransparent(color) ? t('stylePanel.transparent') : color}\n onClick={() => onSelect(color)}\n className={`border-border-strong h-5 w-5 rounded-full border ${active ? 'outline-accent outline outline-2 outline-offset-2' : ''}`}\n style={style}\n />\n );\n}\n\nfunction SwatchGrid({\n value,\n onSelect,\n allowTransparent,\n}: {\n value: string | null | undefined;\n onSelect: (color: string) => void;\n allowTransparent?: boolean;\n}) {\n const active = (color: string) => color.toLowerCase() === (value ?? '').toLowerCase();\n return (\n <div className=\"grid grid-cols-6 gap-x-1 gap-y-3\">\n {PRESET_COLORS.map((color) => (\n <Swatch key={color} color={color} active={active(color)} onSelect={onSelect} />\n ))}\n {allowTransparent && (\n <Swatch color=\"transparent\" active={isTransparent(value ?? null)} onSelect={onSelect} />\n )}\n </div>\n );\n}\n\n// ── range slider ─────────────────────────────────────────────────────────────\nfunction RangeSlider({\n value,\n min,\n max,\n step,\n onChange,\n}: {\n value: number;\n min: number;\n max: number;\n step: number;\n onChange: (value: number) => void;\n}) {\n return (\n <input\n type=\"range\"\n className=\"accent-accent mb-1.5 h-1 w-full cursor-pointer\"\n value={value}\n min={min}\n max={max}\n step={step}\n onChange={(event) => onChange(parseFloat(event.target.value))}\n />\n );\n}\n\n// ── dropdown shell (open state, outside-click, trigger + panel) ───────────────\n/** Close an open dropdown on a press outside it; the root holds its trigger too. */\nfunction useOutsideClose(open: boolean, close: () => void) {\n const rootRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const root = rootRef.current;\n return open && root ? observeOutsidePress(root, close) : undefined;\n }, [open, close]);\n return rootRef;\n}\n\nfunction DropdownShell({\n trigger,\n children,\n}: {\n trigger: ReactNode;\n children: (close: () => void) => ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <button\n type=\"button\"\n onClick={() => setOpen((previous) => !previous)}\n className=\"border-border bg-surface text-fg flex w-full items-center justify-between gap-2 rounded border px-3 py-1.5\"\n >\n {trigger}\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary shrink-0\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-60 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {children(() => setOpen(false))}\n </div>\n )}\n </div>\n );\n}\n\nfunction OptionRow({\n selected,\n title,\n onClick,\n children,\n}: {\n selected: boolean;\n /** The option's name, for an option drawn as a picture. */\n title?: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n aria-label={title}\n onClick={onClick}\n className={`hover:bg-hover flex w-full items-center rounded px-2 py-1.5 text-start text-sm ${selected ? 'bg-selected text-accent' : 'text-fg'}`}\n >\n {children}\n </button>\n );\n}\n\n// ── stroke / border preview + picker ─────────────────────────────────────────\nfunction borderSvg(border: Border): ReactNode {\n if (border.kind === 'cloudy') {\n const radius = border.intensity >= 2 ? 5 : 3;\n const bumps = Math.ceil(80 / (radius * 2));\n const step = 80 / bumps;\n const baseline = radius + 1;\n const viewH = radius * 2 + 2;\n const parts = [`M 0 ${baseline}`];\n for (let i = 0; i < bumps; i++)\n parts.push(`A ${radius} ${radius} 0 0 1 ${step * (i + 1)} ${baseline}`);\n return (\n <svg width=\"80\" height={viewH} viewBox={`0 0 80 ${viewH}`}>\n <path\n d={parts.join(' ')}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n }\n const dash = border.kind === 'dashed' ? border.dash.join(' ') : undefined;\n return (\n <svg width=\"80\" height=\"8\" viewBox=\"0 0 80 8\">\n <line\n x1=\"0\"\n y1=\"4\"\n x2=\"80\"\n y2=\"4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeDasharray={dash}\n />\n </svg>\n );\n}\n\nfunction BorderSelect({\n value,\n styles,\n onChange,\n}: {\n value: Border;\n /** The border styles the kind takes, with their labels. */\n styles: readonly AnnotationOption[];\n onChange: (border: Border) => void;\n}) {\n const label = useLabel();\n const options = BORDER_OPTS.filter((option) => optionOf(styles, option.make().kind));\n return (\n <DropdownShell trigger={<span className=\"text-fg-secondary\">{borderSvg(value)}</span>}>\n {(close) =>\n options.map((option) => {\n const border = option.make();\n return (\n <OptionRow\n key={option.key}\n selected={borderKey(value) === option.key}\n title={label(optionOf(styles, border.kind)!)}\n onClick={() => {\n onChange(border);\n close();\n }}\n >\n <span className=\"text-fg-secondary\">{borderSvg(border)}</span>\n </OptionRow>\n );\n })\n }\n </DropdownShell>\n );\n}\n\n// ── line-ending preview + picker ─────────────────────────────────────────────\nconst LE_MARKERS: Partial<Record<LineEnding, ReactNode>> = {\n square: <path d=\"M68 -4 L76 -4 L76 4 L68 4 Z\" />,\n circle: <circle cx=\"72\" cy=\"0\" r=\"4\" />,\n diamond: <path d=\"M72 -5 L77 0 L72 5 L67 0 Z\" />,\n 'open-arrow': <path d=\"M67 -5 L77 0 L67 5\" fill=\"none\" />,\n 'closed-arrow': <path d=\"M67 -5 L77 0 L67 5 Z\" />,\n 'r-open-arrow': <path d=\"M77 -5 L67 0 L77 5\" fill=\"none\" />,\n 'r-closed-arrow': <path d=\"M77 -5 L67 0 L77 5 Z\" />,\n butt: <path d=\"M72 -5 L72 5\" fill=\"none\" />,\n slash: <path d=\"M67 -5 L77 5\" fill=\"none\" />,\n};\nconst LE_LINE_END: Partial<Record<LineEnding, number>> = {\n square: 68,\n circle: 68,\n diamond: 67,\n 'open-arrow': 76,\n 'closed-arrow': 67,\n 'r-open-arrow': 67,\n 'r-closed-arrow': 67,\n butt: 72,\n slash: 72,\n};\n\nfunction LineEndingPreview({ name, side }: { name: LineEnding; side: 'start' | 'end' }) {\n const marker = LE_MARKERS[name];\n const lineEndX = LE_LINE_END[name] ?? 77;\n const transform = side === 'start' ? 'rotate(180 40 10)' : undefined;\n return (\n <svg width=\"80\" height=\"20\" viewBox=\"0 0 80 20\" className=\"text-fg\">\n <g transform={transform}>\n <line x1=\"4\" y1=\"10\" x2={lineEndX} y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n {marker && (\n <g\n transform=\"translate(0, 10)\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n {marker}\n </g>\n )}\n </g>\n </svg>\n );\n}\n\nfunction LineEndingSelect({\n side,\n value,\n options,\n onChange,\n}: {\n side: 'start' | 'end';\n value: LineEnding;\n options: readonly AnnotationOption[];\n onChange: (ending: LineEnding) => void;\n}) {\n const label = useLabel();\n return (\n <DropdownShell trigger={<LineEndingPreview name={value} side={side} />}>\n {(close) =>\n options.map((option) => (\n <OptionRow\n key={option.value}\n selected={value === option.value}\n title={label(option)}\n onClick={() => {\n onChange(option.value as LineEnding);\n close();\n }}\n >\n <LineEndingPreview name={option.value as LineEnding} side={side} />\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font family picker ───────────────────────────────────────────────────────\nfunction FontFamilySelect({\n value,\n standard,\n onChange,\n}: {\n value: string;\n /** The schema's standard fonts, with their labels. */\n standard: readonly AnnotationOption[];\n onChange: (family: string) => void;\n}) {\n const label = useLabel();\n // The standard faces the viewer offers plus the configured fonts that are\n // registered and mounted (`engine.fonts`) — a registered key is a\n // `fontFamily` value like any standard name, labelled by the app.\n const configured = useAnnotationFonts();\n const options = [\n ...standard\n .filter((option) => OFFERED_FONTS.includes(option.value))\n .map((option) => ({ value: option.value, label: label(option) })),\n ...configured.map((font) => ({ value: font.key, label: font.label })),\n ];\n // A font the document uses that the picker doesn't offer still shows by its name.\n const named = optionOf(standard, value);\n const current =\n options.find((option) => option.value === value)?.label ?? (named ? label(named) : value);\n return (\n <DropdownShell trigger={<span className=\"text-fg text-sm\">{current}</span>}>\n {(close) =>\n options.map((option) => (\n <OptionRow\n key={option.value}\n selected={option.value === value}\n onClick={() => {\n onChange(option.value);\n close();\n }}\n >\n {option.label}\n </OptionRow>\n ))\n }\n </DropdownShell>\n );\n}\n\n// ── font-size combo (number input + preset dropdown) ─────────────────────────\nfunction FontSizeCombo({ value, onChange }: { value: number; onChange: (size: number) => void }) {\n const [open, setOpen] = useState(false);\n const rootRef = useOutsideClose(open, () => setOpen(false));\n // Typed text is a draft until Enter or blur (Escape discards): committing\n // per keystroke would apply \"2\" on the way to \"24\" — to the selected text\n // while editing. Presets commit at once.\n const [draft, setDraft] = useState<string | null>(null);\n const commit = () => {\n if (draft === null) return;\n const size = parseInt(draft, 10);\n setDraft(null);\n if (Number.isFinite(size) && size > 0 && size !== value) onChange(size);\n };\n return (\n <div ref={rootRef} className=\"relative w-full\">\n <input\n type=\"number\"\n min={1}\n value={draft ?? value}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commit();\n setOpen(false);\n } else if (event.key === 'Escape') {\n setDraft(null);\n setOpen(false);\n }\n }}\n onClick={() => setOpen(true)}\n className=\"border-border bg-surface text-fg w-full rounded border px-2 py-1.5 pe-7 text-sm\"\n />\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={() => setOpen((previous) => !previous)}\n className=\"absolute inset-y-0 end-1 flex items-center\"\n >\n <Icon name=\"chevronDown\" size={16} className=\"text-fg-secondary\" />\n </button>\n {open && (\n <div className=\"border-border bg-elevated absolute z-10 mt-1 max-h-48 w-full overflow-y-auto rounded border p-1 shadow-lg\">\n {FONT_SIZES.map((sz) => (\n <OptionRow\n key={sz}\n selected={sz === value}\n onClick={() => {\n setDraft(null);\n onChange(sz);\n setOpen(false);\n }}\n >\n {sz}\n </OptionRow>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction BlendModeSelect({\n value,\n options,\n name,\n onChange,\n}: {\n value: BlendMode;\n options: readonly AnnotationOption[];\n /** The field's label, the select's accessible name. */\n name: string;\n onChange: (mode: BlendMode) => void;\n}) {\n const label = useLabel();\n return (\n <select\n value={value}\n aria-label={name}\n onChange={(event) => onChange(event.target.value as BlendMode)}\n className=\"border-border bg-surface text-fg w-full rounded border px-3 py-1.5 text-sm\"\n >\n {options.map((mode) => (\n <option key={mode.value} value={mode.value}>\n {label(mode)}\n </option>\n ))}\n </select>\n );\n}\n\n// ── align toggle ─────────────────────────────────────────────────────────────\nfunction Toggle({\n active,\n title,\n onClick,\n keepFocus,\n children,\n}: {\n active: boolean;\n title: string;\n onClick: () => void;\n /** Don't take focus on press — a text editor's selection survives the click. */\n keepFocus?: boolean;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={title}\n onClick={onClick}\n onMouseDown={keepFocus ? (event) => event.preventDefault() : undefined}\n className={`flex h-9 w-9 items-center justify-center rounded border transition-colors ${\n active\n ? 'border-accent bg-accent text-on-accent'\n : 'border-border bg-surface text-fg hover:bg-hover'\n }`}\n >\n {children}\n </button>\n );\n}\n\n// ── rich-text formatting: bold / italic / underline in one row ──────────────\ntype FormatSpec = Extract<AnnotationProperty, { key: 'bold' | 'italic' | 'underline' }>;\ntype Format = FormatSpec['key'];\nconst isFormatSpec = (spec: AnnotationProperty): spec is FormatSpec =>\n spec.key === 'bold' || spec.key === 'italic' || spec.key === 'underline';\n\n/**\n * The format toggles a free-text kind declares, in one row. While the text\n * editor holds a range they read and write that range's runs (the plugin\n * routes `toggleTextFormat`); otherwise the annotation's body. The buttons\n * keep focus in the editor so the range survives the click.\n */\nfunction FormatToggles({\n specs,\n values,\n mixed,\n onToggle,\n}: {\n specs: FormatSpec[];\n values: FieldValues;\n mixed: readonly string[];\n onToggle: (format: Format, on: boolean) => void;\n}) {\n const t = useT();\n const label = useLabel();\n return (\n <Field label={t('demo.formatLabel')} mixed={specs.some((spec) => mixed.includes(spec.key))}>\n <div className=\"flex gap-2\">\n {specs.map((spec) => {\n const active = values[spec.key] === true && !mixed.includes(spec.key);\n return (\n <Toggle\n key={spec.key}\n title={label(spec)}\n active={active}\n keepFocus\n onClick={() => onToggle(spec.key, !active)}\n >\n <Icon name={spec.key} size={18} />\n </Toggle>\n );\n })}\n </div>\n </Field>\n );\n}\n\n// ── one control per property: the entire surface an app customizes ──────────\nfunction FieldControl({\n spec,\n values,\n mixed,\n onChange,\n onChangeEach,\n}: {\n spec: AnnotationProperty;\n values: FieldValues;\n mixed: boolean;\n onChange: (patch: FieldValues) => void;\n /** Patch each target relative to itself: one side of its line endings. */\n onChangeEach: (patchOf: (current: FieldValues) => FieldValues) => void;\n}) {\n const t = useT();\n const label = useLabel();\n const value = values[spec.key];\n switch (spec.key) {\n case 'color':\n case 'fontColor':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <SwatchGrid\n value={value as string}\n onSelect={(color) => onChange({ [spec.key]: color })}\n />\n </Field>\n );\n case 'interiorColor':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <SwatchGrid\n value={value as string | null}\n allowTransparent\n onSelect={(color) =>\n onChange({ interiorColor: color === 'transparent' ? null : color })\n }\n />\n </Field>\n );\n case 'opacity': {\n const opacity = (value as number) ?? 1;\n return (\n <Field label={label(spec)} mixed={mixed}>\n <RangeSlider\n value={opacity}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(next) => onChange({ opacity: next })}\n />\n <span className=\"text-fg-muted text-xs\">{Math.round(opacity * 100)}%</span>\n </Field>\n );\n }\n case 'strokeWidth': {\n const strokeWidth = (value as number) ?? spec.min;\n return (\n <Field label={label(spec)} mixed={mixed}>\n <RangeSlider\n value={strokeWidth}\n min={spec.min}\n max={spec.max}\n step={spec.step}\n onChange={(next) => onChange({ strokeWidth: next })}\n />\n <span className=\"text-fg-muted text-xs\">{`${strokeWidth}px`}</span>\n </Field>\n );\n }\n case 'fontSize':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <FontSizeCombo\n value={(value as number) ?? 12}\n onChange={(next) => onChange({ fontSize: next })}\n />\n </Field>\n );\n case 'borderStyle':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <BorderSelect\n value={borderOf(values)}\n styles={spec.options}\n onChange={(border) => onChange(borderFields(border))}\n />\n </Field>\n );\n case 'lineEndings': {\n const le = (value as LineEndings) ?? { start: 'none', end: 'none' };\n return (\n <Field label={label(spec)} mixed={mixed}>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">{t('stylePanel.lineStart')}</div>\n <LineEndingSelect\n side=\"start\"\n value={le.start}\n options={spec.options}\n onChange={(ending) =>\n onChangeEach((current) => ({\n lineEndings: { ...(current.lineEndings as LineEndings), start: ending },\n }))\n }\n />\n </div>\n <div>\n <div className=\"text-fg-muted mb-1.5 text-xs\">{t('stylePanel.lineEnd')}</div>\n <LineEndingSelect\n side=\"end\"\n value={le.end}\n options={spec.options}\n onChange={(ending) =>\n onChangeEach((current) => ({\n lineEndings: { ...(current.lineEndings as LineEndings), end: ending },\n }))\n }\n />\n </div>\n </div>\n </Field>\n );\n }\n case 'fontFamily':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <FontFamilySelect\n value={(value as string) ?? 'helvetica'}\n standard={spec.options}\n onChange={(family) => onChange({ fontFamily: family })}\n />\n </Field>\n );\n case 'textAlign': {\n const alignIcon: Record<TextAlign, string> = {\n left: 'alignLeft',\n center: 'alignCenter',\n right: 'alignRight',\n };\n return (\n <Field label={label(spec)} mixed={mixed}>\n <div className=\"flex gap-2\">\n {spec.options.map((option) => {\n const al = option.value as TextAlign;\n return (\n <Toggle\n key={al}\n title={label(option)}\n active={value === al}\n onClick={() => onChange({ textAlign: al })}\n >\n <Icon name={alignIcon[al]} size={18} />\n </Toggle>\n );\n })}\n </div>\n </Field>\n );\n }\n // The rich-text format toggles render as one row (see `FormatToggles`);\n // each spec is still declared by the kind, so a kind without rich text\n // never shows them.\n case 'bold':\n case 'italic':\n case 'underline':\n return null;\n case 'blendMode':\n return (\n <Field label={label(spec)} mixed={mixed}>\n <BlendModeSelect\n value={(value as BlendMode) ?? 'normal'}\n options={spec.options}\n name={label(spec)}\n onChange={(blendMode) => onChange({ blendMode })}\n />\n </Field>\n );\n // `link` deliberately renders nothing here: a link is a verb on the\n // selection, edited in the anchored popover (see ui/link-editor.tsx) —\n // never a style-panel section.\n case 'link':\n return null;\n default:\n return null;\n }\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nfunction EmptyState() {\n const t = useT();\n return (\n <div className=\"text-fg-muted flex flex-1 flex-col items-center justify-center gap-3 p-8 text-center\">\n <Icon name=\"palette\" size={40} className=\"text-fg-disabled\" />\n <p className=\"max-w-[180px] text-sm\">{t('stylePanel.empty')}</p>\n </div>\n );\n}\n\n/** The rich body a format on or off is, merged over a tool's current one. */\nconst FORMAT_BODY: Record<Format, (on: boolean) => Record<string, unknown>> = {\n bold: (on) => ({ weight: on ? 700 : 400 }),\n italic: (on) => ({ italic: on }),\n underline: (on) => ({ decoration: on ? ['underline'] : [] }),\n};\n\n/**\n * The schema-driven style panel. Rendered inside the right sidebar's\n * `annotation-style` surface (see ui/panels.tsx). Owns its own scroll.\n */\nexport function AnnotationStylePanel() {\n const t = useT();\n const annotation = useAnnotation();\n const commands = useCommands();\n const documentId = useDocumentId() ?? undefined;\n // Without a document there is no active tool; the pointer's defaults are empty.\n const activeToolId = useInteractionState((state) => state.activeToolId) ?? 'pointer';\n const selection = useAnnotationProperties();\n const tool = useAnnotationProperties(activeToolId);\n const toolDefaults = useAnnotationDefaults(activeToolId);\n const selected = useAnnotationState((state) => state.selected);\n // The tool by its button's name: the defaults are that tool's.\n const toolLabel = useKernelValue(\n () => commands.resolveCommand(`tool:${activeToolId}`, documentId)?.label ?? null,\n Object.is,\n );\n\n const hasSel = selection.properties.length > 0;\n const { properties, values, mixed } = hasSel ? selection : tool;\n // The flags have their own section below, and a redaction's label its own.\n const fields = properties.filter(\n (property) => property.control !== 'flag' && property.control !== 'text',\n );\n const write = (patch: FieldValues) =>\n hasSel\n ? annotation.selection.update(patch as AnnotationPatch)\n : annotation.tools.updateDefaults(activeToolId, patch);\n const writeEach = (patchOf: (current: FieldValues) => FieldValues) =>\n hasSel\n ? annotation.selection.update(\n (member) => patchOf(member as unknown as FieldValues) as AnnotationPatch,\n )\n : annotation.tools.updateDefaults(activeToolId, patchOf(toolDefaults));\n const toggleFormat = (format: Format, on: boolean) => {\n if (hasSel) return void annotation.text.toggleFormat(format);\n const body = (toolDefaults.richText as { body?: Record<string, unknown> } | undefined)?.body;\n annotation.tools.updateDefaults(activeToolId, {\n richText: { body: { ...body, ...FORMAT_BODY[format](on) } },\n });\n };\n\n // A selection with no editable fields (e.g. a stamp, or a locked annotation —\n // its style is frozen) still shows its flags: that's how you unlock it.\n if (fields.length === 0 && selected.length === 0) return <EmptyState />;\n\n const context = hasSel\n ? t('stylePanel.selected', { params: { count: selected.length } })\n : toolLabel === null\n ? t('stylePanel.defaults')\n : t('stylePanel.toolDefaults', { params: { tool: toolLabel } });\n\n return (\n <div className=\"flex-1 overflow-y-auto p-4\">\n <p className=\"text-fg-muted mb-4 text-[11px] font-semibold uppercase tracking-wide\">\n {context}\n </p>\n {fields.map((spec) =>\n spec.key === 'bold' ? (\n <FormatToggles\n key=\"format\"\n specs={fields.filter((spec): spec is FormatSpec => isFormatSpec(spec))}\n values={values}\n mixed={mixed}\n onToggle={toggleFormat}\n />\n ) : (\n <FieldControl\n key={spec.key}\n spec={spec}\n values={values}\n mixed={mixed.includes(spec.key)}\n onChange={write}\n onChangeEach={writeEach}\n />\n ),\n )}\n {/* Redaction label (`/OverlayText` + `/Repeat`) — kind content, not a\n style field, so it writes through the redaction plugin's updateLabel. */}\n <RedactionLabelSection />\n {/* `/F` flags for whatever is selected — the live flags test surface. */}\n <AnnotationFlagsSection />\n </div>\n );\n}\n\n/**\n * Label editor shown when exactly one redaction mark is selected. The text is\n * what the destructive apply paints over the region (white-on-black by the\n * tool defaults); `repeat` tiles it. Writes ride the annotation update verb\n * via the redaction plugin, which preserves the label's `/DA` styling.\n */\nfunction RedactionLabelSection() {\n const t = useT();\n const redaction = useOptionalCapability(RedactionToken);\n const selected = useAnnotationState((state) => state.selected);\n const mark = selected.length === 1 && selected[0]!.subtype === 'redact' ? selected[0]! : null;\n const [draft, setDraft] = useState<string | null>(null);\n useEffect(() => setDraft(null), [mark?.ref && annotationKey(mark.ref)]);\n if (!redaction || !mark || mark.subtype !== 'redact') return null;\n\n const value = draft ?? mark.overlayText ?? '';\n const commit = () => {\n if (draft === null) return;\n void redaction.updateLabel(mark.ref, { overlayText: draft.length > 0 ? draft : null });\n setDraft(null);\n };\n\n return (\n <div className=\"border-border-subtle mt-4 border-t pt-4\">\n <p className=\"text-fg-muted mb-2 text-[11px] font-semibold uppercase tracking-wide\">\n {t('demo.redactLabelTitle')}\n </p>\n <input\n type=\"text\"\n value={value}\n placeholder={t('demo.redactLabelPlaceholder')}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n onKeyDown={(event) => event.key === 'Enter' && commit()}\n className=\"border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm\"\n />\n <label className=\"text-fg mt-2 flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={mark.repeat}\n onChange={(event) =>\n void redaction.updateLabel(mark.ref, { repeat: event.target.checked })\n }\n />\n {t('demo.redactLabelRepeat')}\n </label>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -100,6 +100,7 @@ const ar = {
100
100
  note: "تعليق",
101
101
  link: "ارتباط",
102
102
  gotoLink: "الانتقال إلى الارتباط",
103
+ saveFile: "حفظ الملف",
103
104
  removeLink: "إزالة الارتباط",
104
105
  delete: "حذف",
105
106
  group: "تجميع",
@@ -156,12 +157,44 @@ const ar = {
156
157
  "annotations-create": "لا يُسمح بإضافة تعليقات توضيحية",
157
158
  "doc-annotate-modify": "لا يُسمح بتغيير التعليقات التوضيحية",
158
159
  "doc-annotate-read": "لا يُسمح بعرض التعليقات التوضيحية",
160
+ "doc-attachments-modify": "لا يُسمح بإضافة ملفات",
159
161
  "doc-download": "لا يُسمح بالتنزيل",
160
162
  "doc-forms-modify": "لا يُسمح بتحرير حقول النماذج",
163
+ "doc-outline-modify": "لا يُسمح بتغيير المخطط",
164
+ "doc-pages-assemble": "لا يُسمح بتغيير الصفحات",
161
165
  "doc-print": "لا يُسمح بالطباعة",
162
166
  "doc-text-copy": "لا يُسمح بالنسخ",
163
167
  "doc-text-search": "لا يُسمح بالبحث"
164
168
  },
169
+ attachment: {
170
+ add: "إضافة ملف",
171
+ save: "حفظ",
172
+ goTo: "الانتقال إلى الصفحة",
173
+ delete: "حذف",
174
+ more: "خيارات إضافية"
175
+ },
176
+ outline: {
177
+ add: "إضافة عنصر",
178
+ addChild: "إضافة عنصر فرعي",
179
+ rename: "إعادة التسمية",
180
+ setDestination: "تعيين الوجهة إلى العرض الحالي",
181
+ properties: "الخصائص…",
182
+ delete: "حذف",
183
+ expandAll: "توسيع الكل",
184
+ collapseAll: "طي الكل",
185
+ more: "مزيد من الخيارات"
186
+ },
187
+ pages: {
188
+ rotateClockwise: "تدوير الصفحة باتجاه عقارب الساعة",
189
+ rotateCounterclockwise: "تدوير الصفحة عكس اتجاه عقارب الساعة",
190
+ delete: "حذف الصفحات",
191
+ duplicate: "تكرار الصفحات",
192
+ insertBlank: "إدراج صفحة فارغة",
193
+ insertFile: "إدراج من ملف…",
194
+ extract: "استخراج الصفحات",
195
+ selectAll: "تحديد كل الصفحات",
196
+ more: "خيارات الصفحة"
197
+ },
165
198
  turnedOff: "{label}: غير متاح"
166
199
  },
167
200
  passwordPrompt: {
@@ -214,6 +247,25 @@ const ar = {
214
247
  other: "أخرى"
215
248
  },
216
249
  goToPage: { go: "انتقال" },
250
+ print: {
251
+ title: "طباعة",
252
+ pages: "الصفحات",
253
+ allPages: "كل الصفحات",
254
+ currentPage: "الصفحة الحالية",
255
+ range: "مخصص",
256
+ rangeLabel: "الصفحات المراد طباعتها",
257
+ rangePlaceholder: "مثال: 1-3, 5",
258
+ rangeInvalid: "أرقام الصفحات من 1 إلى {total}، مثل 1-3, 5",
259
+ annotations: "طباعة التعليقات التوضيحية",
260
+ preparing: "جارٍ التحضير…",
261
+ preparingPage: "جارٍ تحضير الصفحة {page} من {total}…",
262
+ ready: "جاهز للطباعة.",
263
+ images: "تُطبع الصفحات كصور بدقة {dpi} DPI.",
264
+ lowResolution: "يسمح هذا المستند بالطباعة بدقة منخفضة فقط ({dpi} DPI).",
265
+ failed: "تعذّر تحضير الطباعة.",
266
+ cancel: "إلغاء",
267
+ print: "طباعة"
268
+ },
217
269
  panels: {
218
270
  thumbnails: "الصور المصغرة",
219
271
  outline: "المخطط",
@@ -409,6 +461,46 @@ const ar = {
409
461
  noRotate: "يبقى قائمًا عند تدوير الصفحة",
410
462
  invisible: "قديم: إخفاء الأنواع الفرعية غير المعروفة"
411
463
  },
464
+ attachments: {
465
+ loading: "جارٍ تحميل المرفقات…",
466
+ failed: "تعذّرت قراءة المرفقات.",
467
+ empty: "لا يحتوي هذا المستند على ملفات مرفقة",
468
+ drop: "أفلت الملفات لإرفاقها",
469
+ dropHint: "أو أفلت الملفات هنا",
470
+ adding: "جارٍ الإضافة…",
471
+ onPage: "الصفحة {page}",
472
+ count: "{count} ملف",
473
+ countPlural: "{count} ملفات"
474
+ },
475
+ outline: {
476
+ filter: "تصفية المخطط",
477
+ loading: "جارٍ تحميل المخطط…",
478
+ failed: "تعذّرت قراءة المخطط.",
479
+ empty: "لا يحتوي هذا المستند على مخطط",
480
+ noMatches: "لا توجد عناصر مطابقة",
481
+ incomplete: "تعذّرت قراءة جزء من المخطط.",
482
+ untitled: "بلا عنوان",
483
+ properties: {
484
+ title: "خصائص العنصر",
485
+ name: "العنوان",
486
+ color: "اللون",
487
+ noColor: "بلا",
488
+ customColor: "لون مخصص",
489
+ bold: "غامق",
490
+ italic: "مائل",
491
+ open: "موسّع عند فتح المستند",
492
+ target: "الوجهة",
493
+ targetNone: "بلا",
494
+ targetView: "العرض الحالي",
495
+ targetNamed: "إجراء الصفحة",
496
+ targetKept: "يبقى كما هو",
497
+ keptNote: "يشغّل هذا العنصر برنامجًا نصيًا أو يفتح ملفًا آخر، ولا يمكن تغييره هنا.",
498
+ fit: "الملاءمة",
499
+ fitKept: "كما هو",
500
+ save: "حفظ",
501
+ cancel: "إلغاء"
502
+ }
503
+ },
412
504
  linkEditor: {
413
505
  toUrl: "ارتباط بعنوان URL",
414
506
  url: "عنوان URL",
@@ -564,4 +656,4 @@ const ar = {
564
656
  //#endregion
565
657
  exports.ar = ar;
566
658
 
567
- //# sourceMappingURL=ar-DnEj5vbP.cjs.map
659
+ //# sourceMappingURL=ar-B132r9bo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ar-B132r9bo.cjs","names":[],"sources":["../src/locales/ar.ts"],"sourcesContent":["import type { Locale } from '@embedpdf/react/i18n';\n\n/**\n * Arabic pack, in the words Adobe Acrobat's Arabic edition uses. Machine-translated from the\n * English pack (`./en.ts`) and not yet reviewed by a native speaker.\n */\nexport const ar: Locale = {\n code: 'ar',\n name: 'العربية',\n direction: 'rtl',\n translations: {\n measurement: {\n title: 'القياسات',\n distance: 'المسافة',\n perimeter: 'المحيط',\n area: 'المساحة',\n areaUnit: 'وحدة المساحة',\n resetLabel: 'إعادة تعيين موضع التسمية',\n calibrate: 'معايرة المقياس',\n scale: 'المقياس',\n custom: 'مخصص',\n unavailable: 'غير متاح',\n instructions:\n 'اسحب لقياس مسافة، ثم انقر لوضع خط البُعد. انقر على الرؤوس لقياس محيط أو مساحة، ثم انقر نقرًا مزدوجًا للإنهاء. يجب ألا تتقاطع حدود المساحة؛ ولا يمكن إنهاء معاينة غير متاحة. اضغط Escape للإلغاء. اسحب التسمية نفسها لنقلها.',\n sessionOnly: 'يحتفظ هذا المحرك بمعايرة الصفحة لهذه الجلسة فقط.',\n allPages: 'تطبيق على كل الصفحات',\n recalculate: 'إعادة حساب القياسات الحالية',\n preset: 'مقياس مُعد مسبقًا',\n choosePreset: 'اختر إعدادًا مسبقًا',\n unit: 'الوحدة',\n precision: 'الدقة',\n selection: 'القياسات المحددة',\n report: 'تم التحديث: {updated} · تم التخطي: {skipped} · فشل: {failed}',\n knownLength: 'أدخل الطول الحقيقي الذي يمثله الخط الذي رسمته للتو.',\n length: 'الطول المعروف',\n apply: 'تطبيق المقياس',\n applying: 'جارٍ التطبيق…',\n },\n commands: {\n zoom: {\n in: 'تكبير',\n out: 'تصغير',\n fitPage: 'ملاءمة الصفحة',\n fitWidth: 'ملاءمة العرض',\n automatic: 'تلقائي',\n menu: 'تكبير/تصغير',\n level: 'مستوى التكبير',\n p50: '50%',\n p100: '100%',\n p150: '150%',\n p200: '200%',\n p400: '400%',\n },\n pan: 'تحريك',\n pointer: 'المؤشر',\n comment: 'تعليق',\n style: 'النمط',\n menu: 'القائمة',\n viewControls: 'أدوات العرض',\n open: 'فتح',\n download: 'تنزيل',\n print: 'طباعة',\n fullscreen: 'ملء الشاشة',\n spread: {\n group: 'تخطيط الصفحة',\n none: 'صفحة واحدة',\n odd: 'صفحتان',\n even: 'صفحة الغلاف',\n },\n scroll: {\n group: 'التمرير',\n vertical: 'عمودي',\n horizontal: 'أفقي',\n },\n rotate: {\n group: 'تدوير',\n clockwise: 'تدوير باتجاه عقارب الساعة',\n counterclockwise: 'تدوير عكس عقارب الساعة',\n },\n mode: {\n measure: 'قياس',\n group: 'الوضع',\n view: 'عرض',\n annotate: 'تعليق توضيحي',\n shapes: 'أشكال',\n insert: 'إدراج',\n form: 'نموذج',\n redact: 'تنقيح',\n },\n annotate: {\n cancelCreation: 'إلغاء الرسم',\n highlight: 'تمييز',\n strikeout: 'شطب',\n underline: 'تسطير',\n squiggly: 'خط متموج',\n ink: 'رسم',\n inkHighlight: 'قلم تمييز',\n text: 'نص',\n insertText: 'إدراج نص',\n replaceText: 'استبدال النص',\n callout: 'وسيلة شرح',\n note: 'تعليق',\n link: 'ارتباط',\n gotoLink: 'الانتقال إلى الارتباط',\n saveFile: 'حفظ الملف',\n removeLink: 'إزالة الارتباط',\n delete: 'حذف',\n group: 'تجميع',\n ungroup: 'فك التجميع',\n stampFromSelection: 'إنشاء ختم',\n strip: 'إجراءات التعليق التوضيحي',\n },\n selection: {\n copy: 'نسخ',\n strip: 'إجراءات تحديد النص',\n },\n shapes: {\n rectangle: 'مستطيل',\n circle: 'دائرة',\n line: 'خط',\n arrow: 'سهم',\n polygon: 'مضلع',\n polyline: 'خط متعدد',\n },\n insert: {\n stamp: 'ختم',\n attachment: 'إرفاق ملف',\n signature: 'توقيع',\n image: 'صورة',\n },\n form: {\n textfield: 'حقل نص',\n checkbox: 'خانة اختيار',\n radio: 'زر اختيار',\n select: 'قائمة منسدلة',\n listbox: 'مربع قائمة',\n button: 'زر',\n signature: 'حقل توقيع',\n // The Form mode's design switch, which opens the form designer's sidebar.\n design: 'تصميم النموذج',\n },\n redact: {\n mark: 'تحديد للتنقيح',\n applyAll: 'تطبيق التنقيحات',\n clearAll: 'مسح العلامات',\n },\n undo: 'تراجع',\n redo: 'إعادة',\n page: {\n next: 'الصفحة التالية',\n previous: 'الصفحة السابقة',\n first: 'الصفحة الأولى',\n last: 'الصفحة الأخيرة',\n goTo: 'الانتقال إلى الصفحة',\n },\n find: 'بحث',\n shortcuts: 'اختصارات لوحة المفاتيح',\n notAllowed: {\n default: '{label}: غير مسموح',\n 'annotations-create': 'لا يُسمح بإضافة تعليقات توضيحية',\n 'doc-annotate-modify': 'لا يُسمح بتغيير التعليقات التوضيحية',\n 'doc-annotate-read': 'لا يُسمح بعرض التعليقات التوضيحية',\n 'doc-attachments-modify': 'لا يُسمح بإضافة ملفات',\n 'doc-download': 'لا يُسمح بالتنزيل',\n 'doc-forms-modify': 'لا يُسمح بتحرير حقول النماذج',\n 'doc-outline-modify': 'لا يُسمح بتغيير المخطط',\n 'doc-pages-assemble': 'لا يُسمح بتغيير الصفحات',\n 'doc-print': 'لا يُسمح بالطباعة',\n 'doc-text-copy': 'لا يُسمح بالنسخ',\n 'doc-text-search': 'لا يُسمح بالبحث',\n },\n attachment: {\n add: 'إضافة ملف',\n save: 'حفظ',\n goTo: 'الانتقال إلى الصفحة',\n delete: 'حذف',\n more: 'خيارات إضافية',\n },\n outline: {\n add: 'إضافة عنصر',\n addChild: 'إضافة عنصر فرعي',\n rename: 'إعادة التسمية',\n setDestination: 'تعيين الوجهة إلى العرض الحالي',\n properties: 'الخصائص…',\n delete: 'حذف',\n expandAll: 'توسيع الكل',\n collapseAll: 'طي الكل',\n more: 'مزيد من الخيارات',\n },\n // The page commands, in the Pages mode and a page's menu.\n pages: {\n rotateClockwise: 'تدوير الصفحة باتجاه عقارب الساعة',\n rotateCounterclockwise: 'تدوير الصفحة عكس اتجاه عقارب الساعة',\n delete: 'حذف الصفحات',\n duplicate: 'تكرار الصفحات',\n insertBlank: 'إدراج صفحة فارغة',\n insertFile: 'إدراج من ملف…',\n extract: 'استخراج الصفحات',\n selectAll: 'تحديد كل الصفحات',\n more: 'خيارات الصفحة',\n },\n turnedOff: '{label}: غير متاح',\n },\n passwordPrompt: {\n title: 'كلمة المرور مطلوبة',\n required: 'هذا المستند محمي بكلمة مرور. أدخل كلمة المرور لفتحه.',\n incorrect: 'كلمة المرور غير صحيحة. يرجى المحاولة مرة أخرى.',\n incorrectWarning: 'كلمة مرور غير صحيحة',\n label: 'كلمة المرور',\n placeholder: 'أدخل كلمة المرور',\n cancel: 'إلغاء',\n open: 'فتح',\n opening: 'جارٍ الفتح…',\n },\n dropToOpen: {\n label: 'أفلت ملف PDF لفتحه',\n },\n documentError: {\n title: 'تعذر فتح المستند',\n unknown: 'تعذر فتح المستند.',\n notFound: 'تعذر العثور على الملف.',\n notAllowed: 'ليس لديك حق الوصول إلى هذا المستند.',\n damaged: 'هذا الملف ليس PDF أو أنه تالف.',\n unsupported: 'لا يمكن لهذا العارض فتح هذا النوع من المستندات.',\n retry: 'إعادة المحاولة',\n close: 'إغلاق المستند',\n },\n tabs: {\n close: 'إغلاق {name}',\n loading: 'جارٍ التحميل',\n untitled: 'المستند {id}',\n },\n closeUnsaved: {\n title: 'الإغلاق دون حفظ؟',\n body: 'يحتوي «{name}» على تغييرات لم يتم تنزيلها. ستُفقد هذه التغييرات.',\n cancel: 'إلغاء',\n close: 'إغلاق دون حفظ',\n },\n viewOnly: {\n label: 'للعرض فقط',\n turnedOff: 'تم إيقاف تشغيل الأدوات التي تغيّر هذا المستند',\n notAllowed: 'يمكنك قراءة هذا المستند، لكن لا يمكنك تغييره',\n },\n panel: {\n close: 'إغلاق',\n resize: 'تغيير حجم {title}',\n },\n menu: {\n back: 'رجوع',\n },\n shortcuts: {\n document: 'المستند',\n viewing: 'العرض',\n editing: 'التحرير',\n other: 'أخرى',\n },\n goToPage: {\n go: 'انتقال',\n },\n print: {\n title: 'طباعة',\n pages: 'الصفحات',\n allPages: 'كل الصفحات',\n currentPage: 'الصفحة الحالية',\n range: 'مخصص',\n rangeLabel: 'الصفحات المراد طباعتها',\n rangePlaceholder: 'مثال: 1-3, 5',\n rangeInvalid: 'أرقام الصفحات من 1 إلى {total}، مثل 1-3, 5',\n annotations: 'طباعة التعليقات التوضيحية',\n preparing: 'جارٍ التحضير…',\n preparingPage: 'جارٍ تحضير الصفحة {page} من {total}…',\n ready: 'جاهز للطباعة.',\n images: 'تُطبع الصفحات كصور بدقة {dpi} DPI.',\n lowResolution: 'يسمح هذا المستند بالطباعة بدقة منخفضة فقط ({dpi} DPI).',\n failed: 'تعذّر تحضير الطباعة.',\n cancel: 'إلغاء',\n print: 'طباعة',\n },\n panels: {\n thumbnails: 'الصور المصغرة',\n outline: 'المخطط',\n attachments: 'المرفقات',\n search: 'بحث',\n comments: 'التعليقات',\n style: 'النمط',\n stamps: 'الأختام',\n signatures: 'التوقيعات',\n redaction: 'التنقيحات',\n measurement: 'القياسات',\n formDesign: 'تصميم النموذج',\n switch: 'تبديل اللوحة',\n },\n annotation: {\n comment: 'تعليق',\n highlight: 'تمييز',\n underline: 'تسطير',\n squiggly: 'خط متموج',\n strikeout: 'شطب',\n square: 'مربع',\n circle: 'دائرة',\n line: 'خط',\n polygon: 'مضلع',\n polyline: 'خط متعدد',\n ink: 'حبر',\n freeText: 'نص',\n stamp: 'ختم',\n caret: 'علامة إقحام',\n redact: 'تنقيح',\n fileAttachment: 'مرفق',\n // The style panel's labels, as the annotation kinds name them (`labelKey`), by wording:\n // one field is called different things by different kinds.\n style: {\n opacity: 'العتامة',\n stroke: 'الحد',\n fill: 'التعبئة',\n color: 'اللون',\n strokeWidth: 'عرض الحد',\n border: 'الإطار',\n borderStyle: 'نمط الإطار',\n borderColor: 'لون الإطار',\n borderWidth: 'عرض الإطار',\n background: 'الخلفية',\n outline: 'الحد الخارجي',\n lineEndings: 'نهايات الخط',\n blendMode: 'وضع المزج',\n font: 'الخط',\n fontSize: 'حجم الخط',\n textColor: 'لون النص',\n bold: 'غامق',\n italic: 'مائل',\n underline: 'تسطير',\n align: 'محاذاة',\n alignment: 'المحاذاة',\n label: 'التسمية',\n labelFont: 'خط التسمية',\n labelSize: 'حجم التسمية',\n labelColor: 'لون التسمية',\n icon: 'الأيقونة',\n link: 'الارتباط',\n },\n // The annotation flags (`/F`).\n flags: {\n print: 'طباعة',\n hidden: 'مخفي',\n noView: 'عدم العرض',\n toggleNoView: 'تبديل عدم العرض',\n readOnly: 'للقراءة فقط',\n locked: 'مقفل',\n lockedContents: 'محتويات مقفلة',\n noZoom: 'عدم التكبير/التصغير',\n noRotate: 'عدم التدوير',\n invisible: 'غير مرئي',\n },\n borderStyles: { solid: 'متصل', dashed: 'متقطع', cloudy: 'سحابي' },\n lineEndings: {\n none: 'بلا',\n square: 'مربع',\n circle: 'دائرة',\n diamond: 'معيّن',\n openArrow: 'سهم مفتوح',\n closedArrow: 'سهم مغلق',\n butt: 'طرف مسطح',\n reverseOpenArrow: 'سهم مفتوح معكوس',\n reverseClosedArrow: 'سهم مغلق معكوس',\n slash: 'شرطة مائلة',\n },\n blendModes: {\n normal: 'عادي',\n multiply: 'ضرب',\n screen: 'شاشة',\n overlay: 'تراكب',\n darken: 'تغميق',\n lighten: 'تفتيح',\n colorDodge: 'مراوغة اللون',\n colorBurn: 'حرق اللون',\n hardLight: 'ضوء ساطع',\n softLight: 'ضوء خافت',\n difference: 'اختلاف',\n exclusion: 'استبعاد',\n hue: 'تدرج اللون',\n saturation: 'تشبع',\n color: 'لون',\n luminosity: 'إضاءة',\n },\n // The standard PDF fonts, by their names: a language may keep them as they are.\n fonts: {\n courier: 'Courier',\n courierBold: 'Courier Bold',\n courierBoldOblique: 'Courier Bold Oblique',\n courierOblique: 'Courier Oblique',\n helvetica: 'Helvetica',\n helveticaBold: 'Helvetica Bold',\n helveticaBoldOblique: 'Helvetica Bold Oblique',\n helveticaOblique: 'Helvetica Oblique',\n timesRoman: 'Times Roman',\n timesBold: 'Times Bold',\n timesBoldItalic: 'Times Bold Italic',\n timesItalic: 'Times Italic',\n symbol: 'Symbol',\n zapfDingbats: 'Zapf Dingbats',\n },\n alignments: { left: 'يسار', center: 'توسيط', right: 'يمين' },\n noteIcons: {\n comment: 'تعليق',\n key: 'مفتاح',\n note: 'ملاحظة',\n help: 'تعليمات',\n newParagraph: 'فقرة جديدة',\n paragraph: 'فقرة',\n insert: 'إدراج',\n },\n attachmentIcons: {\n pushPin: 'دبوس',\n paperclip: 'مشبك ورق',\n graph: 'رسم بياني',\n tag: 'علامة',\n },\n },\n // A form field's settings, as the form plugin names them (`labelKey`).\n form: {\n settings: {\n name: 'الاسم',\n tooltip: 'تلميح الأداة',\n required: 'مطلوب',\n readOnly: 'للقراءة فقط',\n noExport: 'عدم التصدير',\n defaultValue: 'القيمة الافتراضية',\n maxLength: 'الحد الأقصى للطول',\n multiline: 'أسطر متعددة',\n password: 'كلمة المرور',\n comb: 'حرف واحد في كل خانة',\n radiosInUnison: 'تُحدَّد الأزرار ذات القيمة نفسها معًا',\n keepOneOn: 'إبقاء زر واحد محددًا',\n options: 'الخيارات',\n allowTyping: 'السماح بالكتابة',\n multiSelect: 'اختيارات متعددة',\n },\n },\n // A thumbnail's tooltip.\n thumbnails: { page: 'الصفحة {page}' },\n // The form designer's sidebar: the fields by page, and the selected one's buttons.\n formDesign: {\n empty: 'لا توجد حقول بعد. اختر أداة حقل لإضافة حقل.',\n page: 'الصفحة {page}',\n allFields: 'كل الحقول',\n buttons: 'الأزرار',\n boxes: 'الخانات',\n box: 'الخانة {number}',\n addButton: 'إضافة زر',\n addBox: 'إضافة خانة',\n },\n // The style panel's own words around the properties.\n stylePanel: {\n mixed: '(مختلط)',\n // A color swatch that takes the color away.\n transparent: 'شفاف',\n lineStart: 'البداية',\n lineEnd: 'النهاية',\n empty: 'اختر أداة رسم أو حدد تعليقًا توضيحيًا لتحرير نمطه.',\n selected: 'المحدد: {count}',\n toolDefaults: 'إعدادات {tool} الافتراضية',\n defaults: 'الإعدادات الافتراضية',\n },\n // The flags section of the style panel: its title, and what each flag does.\n annotationFlags: {\n title: 'العلامات (/F)',\n print: 'تضمينه عند طباعة الصفحة',\n hidden: 'مخفي في كل مكان: الشاشة والنقر والطباعة',\n noView: 'مخفي على الشاشة، وقد يُطبع',\n toggleNoView: 'إظهار التعليق التوضيحي غير المعروض أثناء تحديده',\n readOnly: 'مرئي لكن لا يمكن النقر عليه',\n locked: 'لا يمكن نقله أو تغيير حجمه أو حذفه أو تغيير نمطه',\n lockedContents: 'لا يمكن تغيير النص؛ يمكن تغيير الشكل',\n noZoom: 'حجم ثابت على الشاشة (مثبت من أعلى اليسار)',\n noRotate: 'يبقى قائمًا عند تدوير الصفحة',\n invisible: 'قديم: إخفاء الأنواع الفرعية غير المعروفة',\n },\n // The link editor over a selected annotation.\n attachments: {\n loading: 'جارٍ تحميل المرفقات…',\n failed: 'تعذّرت قراءة المرفقات.',\n empty: 'لا يحتوي هذا المستند على ملفات مرفقة',\n drop: 'أفلت الملفات لإرفاقها',\n dropHint: 'أو أفلت الملفات هنا',\n adding: 'جارٍ الإضافة…',\n onPage: 'الصفحة {page}',\n count: '{count} ملف',\n countPlural: '{count} ملفات',\n },\n outline: {\n filter: 'تصفية المخطط',\n loading: 'جارٍ تحميل المخطط…',\n failed: 'تعذّرت قراءة المخطط.',\n empty: 'لا يحتوي هذا المستند على مخطط',\n noMatches: 'لا توجد عناصر مطابقة',\n incomplete: 'تعذّرت قراءة جزء من المخطط.',\n untitled: 'بلا عنوان',\n properties: {\n title: 'خصائص العنصر',\n name: 'العنوان',\n color: 'اللون',\n noColor: 'بلا',\n customColor: 'لون مخصص',\n bold: 'غامق',\n italic: 'مائل',\n open: 'موسّع عند فتح المستند',\n target: 'الوجهة',\n targetNone: 'بلا',\n targetView: 'العرض الحالي',\n targetNamed: 'إجراء الصفحة',\n targetKept: 'يبقى كما هو',\n keptNote: 'يشغّل هذا العنصر برنامجًا نصيًا أو يفتح ملفًا آخر، ولا يمكن تغييره هنا.',\n fit: 'الملاءمة',\n fitKept: 'كما هو',\n save: 'حفظ',\n cancel: 'إلغاء',\n },\n },\n linkEditor: {\n toUrl: 'ارتباط بعنوان URL',\n url: 'عنوان URL',\n toPage: 'ارتباط بصفحة',\n page: 'الصفحة',\n urlPlaceholder: 'https://…',\n pagePlaceholder: 'رقم الصفحة',\n add: 'إضافة ارتباط',\n update: 'تحديث الارتباط',\n },\n demo: {\n starting: 'جارٍ بدء العارض…',\n opening: 'جارٍ فتح المستند…',\n more: 'المزيد',\n searchPlaceholder: 'البحث في المستند…',\n searchCaseSensitive: 'مطابقة حالة الأحرف',\n searchWholeWord: 'الكلمة كاملة',\n searchRegex: 'تعبير عادي',\n searchSearching: 'جارٍ البحث…',\n searchResults: 'عدد النتائج: {count}',\n searchNoResults: 'لا توجد نتائج',\n searchPrevious: 'النتيجة السابقة',\n searchNext: 'النتيجة التالية',\n searchPage: 'الصفحة {page}',\n commentsForbidden: 'ليس لديك حق الوصول إلى التعليقات في هذا المستند.',\n commentsLoading: 'جارٍ تحميل التعليقات…',\n commentsError: 'فشل تحميل التعليقات.',\n commentsRetry: 'إعادة المحاولة',\n commentsEmpty: 'لا توجد تعليقات بعد. استخدم أداة الملاحظة لبدء سلسلة تعليقات.',\n commentsEmptyReadOnly: 'لا توجد تعليقات على هذا المستند.',\n commentsAnonymous: 'غير معروف',\n commentsPage: 'الصفحة {page}',\n commentCount: 'التعليقات: {count}',\n commentCountPlural: 'التعليقات: {count}',\n commentsReply: 'رد',\n commentsReplyPlaceholder: 'رد…',\n commentsAddPlaceholder: 'إضافة تعليق…',\n commentsDelete: 'حذف التعليق',\n commentsDeleteThread: 'حذف سلسلة التعليقات',\n commentsEdit: 'تحرير التعليق',\n commentsStatus: 'الحالة',\n commentsStatusNone: 'بلا حالة',\n commentsStatusAccepted: 'مقبول',\n commentsStatusRejected: 'مرفوض',\n commentsStatusCancelled: 'ملغى',\n commentsStatusCompleted: 'مكتمل',\n empty: 'لا يوجد شيء هنا بعد في لوحة العرض التوضيحي هذه.',\n page: 'الصفحة {current} من {total}',\n goToPage: 'الانتقال إلى الصفحة',\n cancel: 'إلغاء',\n pageBadge: 'ص. {page}',\n redactionEmpty: 'لا توجد تنقيحات معلقة. استخدم أداة التنقيح لتحديد نص أو مناطق.',\n redactionArea: 'علامة منطقة',\n redactionText: 'علامة نص',\n redactionRemove: 'إزالة العلامة',\n redactConfirmTitle: 'تطبيق التنقيحات؟',\n redactConfirmBody:\n 'ستتم إزالة المحتوى الموجود أسفل علامات التنقيح ({count}) نهائيًا. لا يمكن التراجع عن هذا الإجراء.',\n redactConfirmCollateral: 'ستتم أيضًا إزالة تعليقات توضيحية أخرى ({count}).',\n redactApply: 'تطبيق',\n redactApplying: 'جارٍ التطبيق…',\n formatLabel: 'التنسيق',\n fieldSettingsTitle: 'الحقل',\n fieldOptionLabel: 'التسمية',\n fieldOptionValue: 'القيمة',\n fieldOptionAdd: 'إضافة خيار',\n fieldOptionRemove: 'إزالة الخيار',\n fieldNone: 'بلا',\n redactLabelTitle: 'تسمية التنقيح',\n redactLabelPlaceholder: 'مثال: منقّح',\n redactLabelRepeat: 'تكرار التسمية عبر المنطقة',\n stampsAll: 'كل الأختام',\n stampsLoading: 'جارٍ تحميل الأختام…',\n stampsEmpty: 'لا توجد أختام بعد. استورد ملف PDF لتحويل كل صفحة من صفحاته إلى ختم.',\n stampsRemoveStamp: 'إزالة الختم',\n stampsArmedHint: 'انقر على صفحة لوضع الختم.',\n stampsImport: 'استيراد PDF…',\n stampsImporting: 'جارٍ الاستيراد…',\n stampsImportHint: 'استورد ملف PDF كمكتبة أختام — تصبح كل صفحة ختمًا واحدًا.',\n stampsRemoveLibrary: 'إزالة المكتبة',\n stampsExportLibrary: 'تصدير المكتبة كملف PDF',\n stampsCustomLibrary: 'أختامي',\n stampsCustomLabel: 'ختم مخصص',\n stampsError: 'تعذر تحميل الأختام المضمنة.',\n stampsArmError: 'تعذر تجهيز هذا الختم.',\n stampsImportError: 'تعذر استيراد ملف PDF هذا كمكتبة أختام.',\n quickStampsLabel: 'أختام سريعة',\n signaturesEmpty: 'لا توجد توقيعات بعد. أنشئ توقيعًا للتوقيع به.',\n signaturesNew: 'توقيع جديد…',\n signaturesArmedHint: 'انقر على حقل توقيع لتوقيعه، أو في أي مكان على الصفحة لوضع العلامة.',\n signaturesTargetHint: 'اختر علامة للحقل المحدد.',\n signaturesInDocument: 'في هذا المستند',\n signaturesNone: 'لا يحتوي هذا المستند على حقول توقيع.',\n signaturesValidate: 'التحقق',\n signaturesValidating: 'جارٍ التحقق…',\n signaturesSigned: 'موقّع',\n signaturesUnsigned: 'غير موقّع',\n signaturesRename: 'إعادة تسمية',\n signaturesRemove: 'إزالة',\n signaturesExport: 'تصدير كملف PDF',\n signaturesAddInitials: 'إضافة الأحرف الأولى',\n signatureLabel: 'التوقيع',\n initialsLabel: 'الأحرف الأولى',\n makerTitle: 'توقيع جديد',\n makerName: 'الاسم',\n makerNamePlaceholder: 'اسمك',\n makerDraw: 'رسم',\n makerType: 'كتابة',\n makerUpload: 'تحميل',\n makerTypePlaceholder: 'اكتب اسمك',\n makerFont: 'الخط',\n makerUploadHint: 'اختر ملف PNG أو JPEG أو PDF من صفحة واحدة',\n makerClear: 'مسح',\n makerOptional: '(اختياري)',\n makerSave: 'حفظ',\n makerSaving: 'جارٍ الحفظ…',\n makerError: 'تعذر حفظ التوقيع.',\n signTitle: 'توقيع هذا الحقل',\n signReason: 'السبب',\n signLocation: 'الموقع',\n signKind: 'ما يمكن تغييره بعد ذلك',\n signKindApproval: 'توقيع موافقة — يظل ملء النماذج والتوقيعات الإضافية صالحًا',\n signKindCertifyAnnotate: 'تصديق — السماح بالتعليقات وملء النماذج والتوقيعات',\n signKindCertifyFill: 'تصديق — السماح بملء النماذج والتوقيعات فقط',\n signKindCertifyLocked: 'تصديق — عدم السماح بأي تغييرات',\n signButton: 'توقيع',\n signSigning: 'جارٍ التوقيع…',\n signFill: 'وضع دون توقيع',\n signError: 'تعذر توقيع الحقل.',\n inspectTitle: 'التوقيع',\n inspectSigner: 'موقّع بواسطة',\n inspectReason: 'السبب',\n inspectLocation: 'الموقع',\n inspectTime: 'الوقت',\n inspectIntegrity: 'المستند',\n inspectCryptography: 'التوقيع',\n inspectTrust: 'الموقِّع',\n inspectChanges: 'التغييرات اللاحقة',\n inspectDownload: 'تنزيل النسخة الموقّعة',\n verdictValid: 'صالح',\n verdictValidUntrusted: 'صالح، الموقِّع غير موثوق به',\n verdictInvalid: 'غير صالح — تم تعديله بعد التوقيع',\n verdictWillInvalidate: 'صالح، ويصبح غير صالح عند الحفظ',\n signaturesInvalidating:\n 'سيؤدي هذا التغيير إلى إبطال {field} عند حفظ المستند. تراجع عنه للاحتفاظ بالتوقيع.',\n verdictIndeterminate: 'تعذر التحقق',\n verdictUnchanged: 'لا شيء',\n verdictRestored: 'تم تغييره ثم استعادته',\n inspectLaterRevisions: 'المراجعات بعد التوقيع',\n verdictPermitted: 'مسموح',\n verdictForbidden: 'غير مسموح',\n },\n },\n};\n"],"mappings":"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"}