@embedpdf/viewer-chrome 3.0.0-next.13 → 3.0.0-next.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chrome.cjs +22 -1
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +1 -0
- package/dist/chrome.d.ts +1 -0
- package/dist/chrome.js +22 -1
- package/dist/chrome.js.map +1 -1
- package/dist/commands.cjs +55 -1
- package/dist/commands.cjs.map +1 -1
- package/dist/commands.d.cts +1 -1
- package/dist/commands.d.ts +1 -1
- package/dist/commands.js +55 -1
- package/dist/commands.js.map +1 -1
- package/dist/{es-DYwzfxyt.cjs → es-BXLlBo2b.cjs} +29 -1
- package/dist/es-BXLlBo2b.cjs.map +1 -0
- package/dist/{es-sN6uqBgD.js → es-CLgTsFDS.js} +29 -1
- package/dist/es-CLgTsFDS.js.map +1 -0
- package/dist/index.cjs +428 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +423 -8
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/es-DYwzfxyt.cjs.map +0 -1
- package/dist/es-sN6uqBgD.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ let _embedpdf_react_interaction = require("@embedpdf/react/interaction");
|
|
|
33
33
|
let _embedpdf_react_selection = require("@embedpdf/react/selection");
|
|
34
34
|
let _embedpdf_react_annotation = require("@embedpdf/react/annotation");
|
|
35
35
|
let _embedpdf_react_stamp = require("@embedpdf/react/stamp");
|
|
36
|
+
let _embedpdf_react_measurement = require("@embedpdf/react/measurement");
|
|
36
37
|
let _embedpdf_react_redaction = require("@embedpdf/react/redaction");
|
|
37
38
|
let _embedpdf_react_actions = require("@embedpdf/react/actions");
|
|
38
39
|
let _embedpdf_react_form = require("@embedpdf/react/form");
|
|
@@ -105,6 +106,32 @@ const en = {
|
|
|
105
106
|
code: "en",
|
|
106
107
|
name: "English",
|
|
107
108
|
translations: {
|
|
109
|
+
measurement: {
|
|
110
|
+
title: "Measurements",
|
|
111
|
+
distance: "Distance",
|
|
112
|
+
perimeter: "Perimeter",
|
|
113
|
+
area: "Area",
|
|
114
|
+
areaUnit: "Area unit",
|
|
115
|
+
resetLabel: "Reset label position",
|
|
116
|
+
calibrate: "Calibrate scale",
|
|
117
|
+
scale: "Scale",
|
|
118
|
+
custom: "Custom",
|
|
119
|
+
unavailable: "Unavailable",
|
|
120
|
+
instructions: "Drag to measure a distance, then click to place its dimension line. Click vertices for a perimeter or area and double-click to finish. Area boundaries must not cross; an unavailable preview cannot be finished. Press Escape to cancel. Drag the label itself to move it.",
|
|
121
|
+
sessionOnly: "This engine keeps page calibration for this session only.",
|
|
122
|
+
allPages: "Apply to all pages",
|
|
123
|
+
recalculate: "Recalculate existing measurements",
|
|
124
|
+
preset: "Scale preset",
|
|
125
|
+
choosePreset: "Choose a preset",
|
|
126
|
+
unit: "Unit",
|
|
127
|
+
precision: "Precision",
|
|
128
|
+
selection: "Selected measurements",
|
|
129
|
+
report: "{updated} updated · {skipped} skipped · {failed} failed",
|
|
130
|
+
knownLength: "Enter the real length represented by the line you just drew.",
|
|
131
|
+
length: "Known length",
|
|
132
|
+
apply: "Apply scale",
|
|
133
|
+
applying: "Applying…"
|
|
134
|
+
},
|
|
108
135
|
commands: {
|
|
109
136
|
zoom: {
|
|
110
137
|
in: "Zoom In",
|
|
@@ -148,6 +175,7 @@ const en = {
|
|
|
148
175
|
counterclockwise: "Rotate Counter-Clockwise"
|
|
149
176
|
},
|
|
150
177
|
mode: {
|
|
178
|
+
measure: "Measure",
|
|
151
179
|
group: "Mode",
|
|
152
180
|
view: "View",
|
|
153
181
|
annotate: "Annotate",
|
|
@@ -157,6 +185,7 @@ const en = {
|
|
|
157
185
|
redact: "Redact"
|
|
158
186
|
},
|
|
159
187
|
annotate: {
|
|
188
|
+
cancelCreation: "Cancel drawing",
|
|
160
189
|
highlight: "Highlight",
|
|
161
190
|
strikeout: "Strikeout",
|
|
162
191
|
underline: "Underline",
|
|
@@ -472,7 +501,40 @@ function createViewerHandle(kernel) {
|
|
|
472
501
|
*
|
|
473
502
|
* GENERATED by scratchpad/extract-icons.mjs — 93 icons (slot tags by hand).
|
|
474
503
|
*/
|
|
504
|
+
const measurementOutline = [{
|
|
505
|
+
d: "M5 4H19M20 5V19M19 20H5M4 19V5",
|
|
506
|
+
stroke: "primary"
|
|
507
|
+
}, {
|
|
508
|
+
d: "M3.1 3.1h1.8v1.8H3.1zM19.1 3.1h1.8v1.8h-1.8zM3.1 19.1h1.8v1.8H3.1zM19.1 19.1h1.8v1.8h-1.8z",
|
|
509
|
+
stroke: "primary"
|
|
510
|
+
}];
|
|
475
511
|
const ICON_PATHS = {
|
|
512
|
+
ruler: ["M3 8h18v8H3z", "M7 8v4M11 8v2M15 8v4M19 8v2"],
|
|
513
|
+
distance: [{
|
|
514
|
+
d: "M5 12H19",
|
|
515
|
+
stroke: "primary",
|
|
516
|
+
strokeDasharray: "2 2"
|
|
517
|
+
}, {
|
|
518
|
+
d: "M3.5 10.5a1.5 1.5 0 1 0 0 3a1.5 1.5 0 1 0 0-3M20.5 10.5a1.5 1.5 0 1 0 0 3a1.5 1.5 0 1 0 0-3",
|
|
519
|
+
stroke: "primary",
|
|
520
|
+
fill: "primary",
|
|
521
|
+
fillOpacity: .25
|
|
522
|
+
}],
|
|
523
|
+
perimeter: measurementOutline,
|
|
524
|
+
area: [
|
|
525
|
+
{
|
|
526
|
+
d: "M5 4H19V5H20V19H19V20H5V19H4V5H5Z",
|
|
527
|
+
fill: "primary",
|
|
528
|
+
fillOpacity: .08
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
d: "M4.5 7.5L7.5 4.5M4.5 10.5L10.5 4.5M4.5 13.5L13.5 4.5M4.5 16.5L16.5 4.5M4.5 19.5L19.5 4.5M7.5 19.5L19.5 7.5M10.5 19.5L19.5 10.5M13.5 19.5L19.5 13.5M16.5 19.5L19.5 16.5",
|
|
532
|
+
stroke: "primary",
|
|
533
|
+
strokeWidth: .6,
|
|
534
|
+
strokeOpacity: .5
|
|
535
|
+
},
|
|
536
|
+
...measurementOutline
|
|
537
|
+
],
|
|
476
538
|
alertTriangle: ["M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"],
|
|
477
539
|
alignBottom: [
|
|
478
540
|
"M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z",
|
|
@@ -522,6 +584,11 @@ const ICON_PATHS = {
|
|
|
522
584
|
"M19 16h-12a2 2 0 0 0 -2 2",
|
|
523
585
|
"M9 8h6"
|
|
524
586
|
],
|
|
587
|
+
calibrate: [
|
|
588
|
+
"M12 12m-7.5 0a7.5 7.5 0 1 0 15 0a7.5 7.5 0 1 0 -15 0",
|
|
589
|
+
"M12 2.75V7M12 17V21.25M2.75 12H7M17 12H21.25",
|
|
590
|
+
"M12 12m-2.5 0a2.5 2.5 0 1 0 5 0a2.5 2.5 0 1 0 -5 0"
|
|
591
|
+
],
|
|
525
592
|
callout: [
|
|
526
593
|
{
|
|
527
594
|
d: "M20 6v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1",
|
|
@@ -944,6 +1011,11 @@ const ICON_PATHS = {
|
|
|
944
1011
|
],
|
|
945
1012
|
ungroup: ["M4 5a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z", "M13 14a1 1 0 0 1 1 -1h5a1 1 0 0 1 1 1v5a1 1 0 0 1 -1 1h-5a1 1 0 0 1 -1 -1z"],
|
|
946
1013
|
unlock: ["M7 11V7a5 5 0 0 1 9.9-1"],
|
|
1014
|
+
updateScale: [
|
|
1015
|
+
"M3.5 13.5L18.5 7.5L21.25 14.5L6.25 20.5L3.5 13.5Z",
|
|
1016
|
+
"M8 12.8L9 15.2M11.5 11.4L12.2 13.2M15 10L16 12.4",
|
|
1017
|
+
"M4 9.39849C4.10585 8.34804 4.487 7.34411 5.10497 6.48809C5.72294 5.63207 6.55584 4.95427 7.51957 4.52312C8.4833 4.09198 9.54373 3.92277 10.5938 4.03257C11.6438 4.14237 12.6463 4.5273 13.5 5.14849M11.5 6.00003L13.5 5.14849L12.7807 2.96999"
|
|
1018
|
+
],
|
|
947
1019
|
vertical: [
|
|
948
1020
|
"M8 7l4 -4l4 4",
|
|
949
1021
|
"M8 17l4 4l4 -4",
|
|
@@ -1013,7 +1085,11 @@ function Icon({ name, size = 20, strokeWidth = 2, className, title, accent }) {
|
|
|
1013
1085
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1014
1086
|
d: p.d,
|
|
1015
1087
|
fill: fill ?? "none",
|
|
1016
|
-
stroke
|
|
1088
|
+
stroke,
|
|
1089
|
+
strokeWidth: p.strokeWidth,
|
|
1090
|
+
strokeDasharray: p.strokeDasharray,
|
|
1091
|
+
strokeOpacity: p.strokeOpacity,
|
|
1092
|
+
fillOpacity: p.fillOpacity
|
|
1017
1093
|
}, i);
|
|
1018
1094
|
})
|
|
1019
1095
|
});
|
|
@@ -1047,6 +1123,335 @@ function ThemeProvider({ children, preference = "system", target }) {
|
|
|
1047
1123
|
});
|
|
1048
1124
|
}
|
|
1049
1125
|
//#endregion
|
|
1126
|
+
//#region src/ui/measurement.tsx
|
|
1127
|
+
const control = "border-border bg-surface text-fg w-full rounded-md border px-2 py-1.5 text-sm disabled:opacity-50";
|
|
1128
|
+
const button = "border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm disabled:opacity-50";
|
|
1129
|
+
const useCurrentPon = () => (0, _embedpdf_react_runtime.useSelector)(_embedpdf_react_stage.StageToken, (c) => c.pages()[c.currentPage()]?.pon ?? -1);
|
|
1130
|
+
function MeasurementScaleButton() {
|
|
1131
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
1132
|
+
const scale = (0, _embedpdf_react_measurement.usePageScale)(useCurrentPon());
|
|
1133
|
+
const surface = (0, _embedpdf_react_shell.useSurface)("measurement");
|
|
1134
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1135
|
+
className: `${button} inline-flex items-center gap-1.5 whitespace-nowrap`,
|
|
1136
|
+
onClick: () => surface.open({ exclusive: "right" }),
|
|
1137
|
+
title: t("measurement.title"),
|
|
1138
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
1139
|
+
name: "updateScale",
|
|
1140
|
+
size: 20,
|
|
1141
|
+
className: "shrink-0"
|
|
1142
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
1143
|
+
t("measurement.scale"),
|
|
1144
|
+
":",
|
|
1145
|
+
" ",
|
|
1146
|
+
scale.measure?.subtype === "RL" ? scale.measure.ratio ?? t("measurement.custom") : t("measurement.unavailable")
|
|
1147
|
+
] })]
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
function MeasurementSection() {
|
|
1151
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
1152
|
+
const pon = useCurrentPon();
|
|
1153
|
+
const measurement = (0, _embedpdf_react_measurement.useMeasurement)();
|
|
1154
|
+
const scale = (0, _embedpdf_react_measurement.usePageScale)(pon);
|
|
1155
|
+
const anno = (0, _embedpdf_react_runtime.useCapability)(_embedpdf_react_annotation.AnnotationToken);
|
|
1156
|
+
const selected = (0, _embedpdf_react_runtime.useSelector)(_embedpdf_react_annotation.AnnotationToken, (c) => c.selection());
|
|
1157
|
+
const resettable = (0, _embedpdf_react_runtime.useSelector)(_embedpdf_react_annotation.AnnotationToken, (c) => c.getSelected().filter((annotation) => (annotation.subtype === "polygon" || annotation.subtype === "polyline") && annotation.caption?.center && c.canEdit(annotation.ref) && !annotation.flags.lockedContents), (a, b) => a.length === b.length && a.every((annotation, i) => annotation === b[i]));
|
|
1158
|
+
const readouts = (0, _embedpdf_react_runtime.useSelector)(_embedpdf_react_measurement.MeasurementToken, (c) => anno.getSelected().map((d) => c.readout(d.ref)).filter((r) => !("unavailable" in r)), (a, b) => JSON.stringify(a) === JSON.stringify(b));
|
|
1159
|
+
const reports = (0, _embedpdf_react_runtime.useSelector)(_embedpdf_react_measurement.MeasurementToken, (c) => c.lastReports());
|
|
1160
|
+
const [allPages, setAllPages] = (0, react.useState)(false);
|
|
1161
|
+
const [recalculate, setRecalculate] = (0, react.useState)(true);
|
|
1162
|
+
const [error, setError] = (0, react.useState)(null);
|
|
1163
|
+
const disabled = measurement.busy || !measurement.canCalibratePage || !scale.ready;
|
|
1164
|
+
const rectilinear = scale.measure?.subtype === "RL" ? scale.measure : null;
|
|
1165
|
+
const options = {
|
|
1166
|
+
allPages,
|
|
1167
|
+
recalculate
|
|
1168
|
+
};
|
|
1169
|
+
const run = async (work) => {
|
|
1170
|
+
setError(null);
|
|
1171
|
+
try {
|
|
1172
|
+
await work();
|
|
1173
|
+
} catch (e) {
|
|
1174
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
const precision = rectilinear?.distance[rectilinear.distance.length - 1]?.precision ?? 100;
|
|
1178
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1179
|
+
className: "flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4 text-sm",
|
|
1180
|
+
children: [
|
|
1181
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1182
|
+
className: "text-fg-muted",
|
|
1183
|
+
children: t("measurement.instructions")
|
|
1184
|
+
}),
|
|
1185
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1186
|
+
className: "text-fg-muted",
|
|
1187
|
+
children: [t("measurement.scale"), ": "]
|
|
1188
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: rectilinear?.ratio ?? t("measurement.unavailable") })] }),
|
|
1189
|
+
scale.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1190
|
+
role: "alert",
|
|
1191
|
+
className: "text-red-600",
|
|
1192
|
+
children: scale.error.message
|
|
1193
|
+
}),
|
|
1194
|
+
!scale.persistent && scale.ready && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1195
|
+
className: "text-fg-muted",
|
|
1196
|
+
children: t("measurement.sessionOnly")
|
|
1197
|
+
}),
|
|
1198
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1199
|
+
className: "flex items-center gap-2",
|
|
1200
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1201
|
+
type: "checkbox",
|
|
1202
|
+
checked: allPages,
|
|
1203
|
+
disabled: measurement.busy,
|
|
1204
|
+
onChange: (e) => setAllPages(e.target.checked)
|
|
1205
|
+
}), t("measurement.allPages")]
|
|
1206
|
+
}),
|
|
1207
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1208
|
+
className: "flex items-center gap-2",
|
|
1209
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1210
|
+
type: "checkbox",
|
|
1211
|
+
checked: recalculate,
|
|
1212
|
+
disabled: measurement.busy,
|
|
1213
|
+
onChange: (e) => setRecalculate(e.target.checked)
|
|
1214
|
+
}), t("measurement.recalculate")]
|
|
1215
|
+
}),
|
|
1216
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("measurement.preset"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1217
|
+
"aria-label": t("measurement.preset"),
|
|
1218
|
+
className: control,
|
|
1219
|
+
value: "",
|
|
1220
|
+
disabled,
|
|
1221
|
+
onChange: (e) => void run(() => measurement.setPreset(pon, e.target.value, options)),
|
|
1222
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1223
|
+
value: "",
|
|
1224
|
+
disabled: true,
|
|
1225
|
+
children: t("measurement.choosePreset")
|
|
1226
|
+
}), measurement.presets().map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1227
|
+
value: p.id,
|
|
1228
|
+
children: p.label
|
|
1229
|
+
}, p.id))]
|
|
1230
|
+
})] }),
|
|
1231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("measurement.unit"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1232
|
+
"aria-label": t("measurement.unit"),
|
|
1233
|
+
className: control,
|
|
1234
|
+
value: rectilinear?.distance[0]?.unit.trim() ?? "",
|
|
1235
|
+
disabled: disabled || !rectilinear,
|
|
1236
|
+
onChange: (e) => void run(() => measurement.setUnit(pon, e.target.value, void 0, options)),
|
|
1237
|
+
children: [!measurement.units().includes(rectilinear?.distance[0]?.unit.trim()) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1238
|
+
value: rectilinear?.distance[0]?.unit.trim() ?? "",
|
|
1239
|
+
children: t("measurement.custom")
|
|
1240
|
+
}), measurement.units().map((u) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1241
|
+
value: u,
|
|
1242
|
+
children: u
|
|
1243
|
+
}, u))]
|
|
1244
|
+
})] }),
|
|
1245
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("measurement.areaUnit"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1246
|
+
"aria-label": t("measurement.areaUnit"),
|
|
1247
|
+
className: control,
|
|
1248
|
+
value: rectilinear?.area[0]?.unit.trim().replace("²", "2") ?? "",
|
|
1249
|
+
disabled: disabled || !rectilinear,
|
|
1250
|
+
onChange: (e) => void run(() => measurement.setAreaUnit(pon, e.target.value, options)),
|
|
1251
|
+
children: [!measurement.areaUnits().includes(rectilinear?.area[0]?.unit.trim().replace("²", "2")) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1252
|
+
value: rectilinear?.area[0]?.unit.trim().replace("²", "2") ?? "",
|
|
1253
|
+
children: t("measurement.custom")
|
|
1254
|
+
}), measurement.areaUnits().map((unit) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1255
|
+
value: unit,
|
|
1256
|
+
children: unit.replace("2", "²")
|
|
1257
|
+
}, unit))]
|
|
1258
|
+
})] }),
|
|
1259
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("measurement.precision"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1260
|
+
"aria-label": t("measurement.precision"),
|
|
1261
|
+
className: control,
|
|
1262
|
+
value: precision,
|
|
1263
|
+
disabled: disabled || !rectilinear,
|
|
1264
|
+
onChange: (e) => void run(() => measurement.setPrecision(pon, Number(e.target.value), options)),
|
|
1265
|
+
children: [![
|
|
1266
|
+
1,
|
|
1267
|
+
10,
|
|
1268
|
+
100,
|
|
1269
|
+
1e3,
|
|
1270
|
+
1e4
|
|
1271
|
+
].includes(precision) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1272
|
+
value: precision,
|
|
1273
|
+
children: t("measurement.custom")
|
|
1274
|
+
}), [
|
|
1275
|
+
1,
|
|
1276
|
+
10,
|
|
1277
|
+
100,
|
|
1278
|
+
1e3,
|
|
1279
|
+
1e4
|
|
1280
|
+
].map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1281
|
+
value: p,
|
|
1282
|
+
children: 1 / p
|
|
1283
|
+
}, p))]
|
|
1284
|
+
})] }),
|
|
1285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1286
|
+
className: button,
|
|
1287
|
+
disabled,
|
|
1288
|
+
onClick: () => measurement.startCalibration(),
|
|
1289
|
+
children: t("measurement.calibrate")
|
|
1290
|
+
}),
|
|
1291
|
+
selected.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1292
|
+
className: "border-border-subtle border-t pt-3",
|
|
1293
|
+
children: [
|
|
1294
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
1295
|
+
className: "mb-1 font-medium",
|
|
1296
|
+
children: t("measurement.selection")
|
|
1297
|
+
}),
|
|
1298
|
+
readouts.length ? readouts.map((readout, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1299
|
+
className: "mb-2",
|
|
1300
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [
|
|
1301
|
+
t(`measurement.${readout.kind}`),
|
|
1302
|
+
": ",
|
|
1303
|
+
readout.label
|
|
1304
|
+
] }), readout.perimeter && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [
|
|
1305
|
+
t("measurement.perimeter"),
|
|
1306
|
+
": ",
|
|
1307
|
+
readout.perimeter
|
|
1308
|
+
] })]
|
|
1309
|
+
}, i)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1310
|
+
className: "text-fg-muted",
|
|
1311
|
+
children: t("measurement.unavailable")
|
|
1312
|
+
}),
|
|
1313
|
+
resettable.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1314
|
+
className: button,
|
|
1315
|
+
disabled: measurement.busy,
|
|
1316
|
+
onClick: () => void run(async () => {
|
|
1317
|
+
for (const annotation of resettable) if (annotation.subtype === "polygon" || annotation.subtype === "polyline") await anno.update(annotation.ref, {
|
|
1318
|
+
subtype: annotation.subtype,
|
|
1319
|
+
caption: { center: null }
|
|
1320
|
+
});
|
|
1321
|
+
}),
|
|
1322
|
+
children: t("measurement.resetLabel")
|
|
1323
|
+
})
|
|
1324
|
+
]
|
|
1325
|
+
}),
|
|
1326
|
+
reports.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1327
|
+
role: "status",
|
|
1328
|
+
children: t("measurement.report", { params: {
|
|
1329
|
+
updated: reports.reduce((n, r) => n + r.updated.length, 0),
|
|
1330
|
+
skipped: reports.reduce((n, r) => n + r.skipped.length, 0),
|
|
1331
|
+
failed: reports.reduce((n, r) => n + r.failed.length + (r.scaleError || r.error ? 1 : 0), 0)
|
|
1332
|
+
} })
|
|
1333
|
+
}),
|
|
1334
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1335
|
+
role: "alert",
|
|
1336
|
+
className: "text-red-600",
|
|
1337
|
+
children: error
|
|
1338
|
+
})
|
|
1339
|
+
]
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
function CalibrationDialog() {
|
|
1343
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
1344
|
+
const measurement = (0, _embedpdf_react_measurement.useMeasurement)();
|
|
1345
|
+
const request = (0, _embedpdf_react_runtime.useSelector)(_embedpdf_react_measurement.MeasurementToken, (c) => c.calibrationRequest());
|
|
1346
|
+
const input = (0, react.useRef)(null);
|
|
1347
|
+
const [value, setValue] = (0, react.useState)("");
|
|
1348
|
+
const [unit, setUnit] = (0, react.useState)("m");
|
|
1349
|
+
const [allPages, setAllPages] = (0, react.useState)(false);
|
|
1350
|
+
const [recalculate, setRecalculate] = (0, react.useState)(true);
|
|
1351
|
+
const [error, setError] = (0, react.useState)(null);
|
|
1352
|
+
(0, react.useEffect)(() => {
|
|
1353
|
+
setValue("");
|
|
1354
|
+
setError(null);
|
|
1355
|
+
input.current?.focus();
|
|
1356
|
+
}, [request]);
|
|
1357
|
+
if (!request) return null;
|
|
1358
|
+
const submit = async () => {
|
|
1359
|
+
setError(null);
|
|
1360
|
+
try {
|
|
1361
|
+
await measurement.calibrate(request.pon, request.from, request.to, {
|
|
1362
|
+
value: Number(value),
|
|
1363
|
+
unit
|
|
1364
|
+
}, {
|
|
1365
|
+
allPages,
|
|
1366
|
+
recalculate
|
|
1367
|
+
});
|
|
1368
|
+
measurement.dismissCalibration();
|
|
1369
|
+
} catch (e) {
|
|
1370
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1374
|
+
className: "fixed inset-0 z-50 grid place-items-center bg-black/40",
|
|
1375
|
+
onKeyDown: (e) => {
|
|
1376
|
+
if (e.key === "Escape" && !measurement.busy) measurement.dismissCalibration();
|
|
1377
|
+
},
|
|
1378
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
1379
|
+
role: "dialog",
|
|
1380
|
+
"aria-modal": "true",
|
|
1381
|
+
"aria-labelledby": "measurement-calibration-title",
|
|
1382
|
+
className: "border-border bg-surface flex w-96 flex-col gap-4 rounded-lg border p-5 shadow-xl",
|
|
1383
|
+
onSubmit: (e) => {
|
|
1384
|
+
e.preventDefault();
|
|
1385
|
+
submit();
|
|
1386
|
+
},
|
|
1387
|
+
children: [
|
|
1388
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
1389
|
+
id: "measurement-calibration-title",
|
|
1390
|
+
className: "font-semibold",
|
|
1391
|
+
children: t("measurement.calibrate")
|
|
1392
|
+
}),
|
|
1393
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1394
|
+
className: "text-fg-muted text-sm",
|
|
1395
|
+
children: t("measurement.knownLength")
|
|
1396
|
+
}),
|
|
1397
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("measurement.length"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1398
|
+
ref: input,
|
|
1399
|
+
"aria-label": t("measurement.length"),
|
|
1400
|
+
className: control,
|
|
1401
|
+
type: "number",
|
|
1402
|
+
min: "0",
|
|
1403
|
+
step: "any",
|
|
1404
|
+
value,
|
|
1405
|
+
onChange: (e) => setValue(e.target.value)
|
|
1406
|
+
})] }),
|
|
1407
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("measurement.unit"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
1408
|
+
className: control,
|
|
1409
|
+
"aria-label": t("measurement.unit"),
|
|
1410
|
+
value: unit,
|
|
1411
|
+
onChange: (e) => setUnit(e.target.value),
|
|
1412
|
+
children: measurement.units().map((u) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", { children: u }, u))
|
|
1413
|
+
})] }),
|
|
1414
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1415
|
+
className: "flex items-center gap-2 text-sm",
|
|
1416
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1417
|
+
type: "checkbox",
|
|
1418
|
+
checked: allPages,
|
|
1419
|
+
onChange: (e) => setAllPages(e.target.checked)
|
|
1420
|
+
}), t("measurement.allPages")]
|
|
1421
|
+
}),
|
|
1422
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1423
|
+
className: "flex items-center gap-2 text-sm",
|
|
1424
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1425
|
+
type: "checkbox",
|
|
1426
|
+
checked: recalculate,
|
|
1427
|
+
onChange: (e) => setRecalculate(e.target.checked)
|
|
1428
|
+
}), t("measurement.recalculate")]
|
|
1429
|
+
}),
|
|
1430
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1431
|
+
role: "alert",
|
|
1432
|
+
className: "text-sm text-red-600",
|
|
1433
|
+
children: error
|
|
1434
|
+
}),
|
|
1435
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1436
|
+
className: "flex justify-end gap-2",
|
|
1437
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1438
|
+
type: "button",
|
|
1439
|
+
className: button,
|
|
1440
|
+
disabled: measurement.busy,
|
|
1441
|
+
onClick: () => measurement.dismissCalibration(),
|
|
1442
|
+
children: t("demo.cancel")
|
|
1443
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1444
|
+
className: button,
|
|
1445
|
+
type: "submit",
|
|
1446
|
+
disabled: measurement.busy || !measurement.canCalibratePage || !(Number(value) > 0) || !Number.isFinite(Number(value)),
|
|
1447
|
+
children: measurement.busy ? t("measurement.applying") : t("measurement.apply")
|
|
1448
|
+
})]
|
|
1449
|
+
})
|
|
1450
|
+
]
|
|
1451
|
+
})
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
//#endregion
|
|
1050
1455
|
//#region src/config/default-stamps.ts
|
|
1051
1456
|
/**
|
|
1052
1457
|
* The viewer's BUILT-IN stamp library: `@embedpdf/default-stamps`, the
|
|
@@ -1616,6 +2021,7 @@ function AppToolbar({ bar, className }) {
|
|
|
1616
2021
|
run
|
|
1617
2022
|
}),
|
|
1618
2023
|
renderCustom: {
|
|
2024
|
+
"measurement-scale": () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MeasurementScaleButton, {}),
|
|
1619
2025
|
"zoom-controls": (variant) => variant === "inline" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZoomControls, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZoomButton, {}),
|
|
1620
2026
|
"quick-stamps": () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuickStamps, {})
|
|
1621
2027
|
},
|
|
@@ -2062,7 +2468,13 @@ function iconGlyph(name, accent) {
|
|
|
2062
2468
|
const fill = spec.fill === true ? INK : spec.fill ? accent?.[spec.fill] : void 0;
|
|
2063
2469
|
const stroke = spec.stroke ? accent?.[spec.stroke] ?? INK : spec.fill ? "none" : INK;
|
|
2064
2470
|
halo.push(`<path d="${spec.d}" fill="none" stroke="${HALO}" stroke-width="3.5"/>`);
|
|
2065
|
-
|
|
2471
|
+
const decoration = [
|
|
2472
|
+
["stroke-width", spec.strokeWidth],
|
|
2473
|
+
["stroke-dasharray", spec.strokeDasharray],
|
|
2474
|
+
["stroke-opacity", spec.strokeOpacity],
|
|
2475
|
+
["fill-opacity", spec.fillOpacity]
|
|
2476
|
+
].filter(([, value]) => value !== void 0).map(([key, value]) => `${key}="${value}"`).join(" ");
|
|
2477
|
+
draw.push(`<path d="${spec.d}" fill="${fill ?? "none"}" stroke="${stroke}" ${decoration}/>`);
|
|
2066
2478
|
}
|
|
2067
2479
|
return halo.join("") + draw.join("");
|
|
2068
2480
|
}
|
|
@@ -4471,12 +4883,13 @@ function RightSidebar() {
|
|
|
4471
4883
|
const comment = (0, _embedpdf_react_shell.useSurface)("comment");
|
|
4472
4884
|
const style = (0, _embedpdf_react_shell.useSurface)("annotation-style");
|
|
4473
4885
|
const redaction = (0, _embedpdf_react_shell.useSurface)("redaction");
|
|
4886
|
+
const measurement = (0, _embedpdf_react_shell.useSurface)("measurement");
|
|
4474
4887
|
const stamps = (0, _embedpdf_react_shell.useSurface)("stamps");
|
|
4475
4888
|
const signatures = (0, _embedpdf_react_shell.useSurface)("signatures");
|
|
4476
|
-
const active = search.isOpen ? "search" : comment.isOpen ? "comment" : style.isOpen ? "style" : redaction.isOpen ? "redaction" : stamps.isOpen ? "stamps" : signatures.isOpen ? "signatures" : null;
|
|
4889
|
+
const active = measurement.isOpen ? "measurement" : search.isOpen ? "search" : comment.isOpen ? "comment" : style.isOpen ? "style" : redaction.isOpen ? "redaction" : stamps.isOpen ? "stamps" : signatures.isOpen ? "signatures" : null;
|
|
4477
4890
|
if (!active) return null;
|
|
4478
|
-
const titleKey = active === "search" ? "demo.searchTitle" : active === "comment" ? "demo.commentsTitle" : active === "redaction" ? "demo.redactionTitle" : active === "stamps" ? "demo.stampsTitle" : active === "signatures" ? "demo.signaturesTitle" : "demo.styleTitle";
|
|
4479
|
-
const close = active === "search" ? search.close : active === "comment" ? comment.close : active === "redaction" ? redaction.close : active === "stamps" ? stamps.close : active === "signatures" ? signatures.close : style.close;
|
|
4891
|
+
const titleKey = active === "measurement" ? "measurement.title" : active === "search" ? "demo.searchTitle" : active === "comment" ? "demo.commentsTitle" : active === "redaction" ? "demo.redactionTitle" : active === "stamps" ? "demo.stampsTitle" : active === "signatures" ? "demo.signaturesTitle" : "demo.styleTitle";
|
|
4892
|
+
const close = active === "measurement" ? measurement.close : active === "search" ? search.close : active === "comment" ? comment.close : active === "redaction" ? redaction.close : active === "stamps" ? stamps.close : active === "signatures" ? signatures.close : style.close;
|
|
4480
4893
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
4481
4894
|
className: "border-border-subtle bg-surface flex w-72 shrink-0 flex-col border-l",
|
|
4482
4895
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -4493,7 +4906,7 @@ function RightSidebar() {
|
|
|
4493
4906
|
size: 16
|
|
4494
4907
|
})
|
|
4495
4908
|
})]
|
|
4496
|
-
}), active === "style" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnnotationStylePanel, {}) : active === "search" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchPanel, {}, documentId ?? "none") : active === "redaction" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RedactionPanel, {}) : active === "stamps" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StampsPanel, {}) : active === "signatures" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SignaturesPanel, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommentsPanel, {}, documentId ?? "none")]
|
|
4909
|
+
}), active === "measurement" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MeasurementSection, {}, documentId ?? "none") : active === "style" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AnnotationStylePanel, {}) : active === "search" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchPanel, {}, documentId ?? "none") : active === "redaction" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RedactionPanel, {}) : active === "stamps" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StampsPanel, {}) : active === "signatures" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SignaturesPanel, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommentsPanel, {}, documentId ?? "none")]
|
|
4497
4910
|
});
|
|
4498
4911
|
}
|
|
4499
4912
|
function PageControls() {
|
|
@@ -5546,6 +5959,7 @@ function Shell() {
|
|
|
5546
5959
|
}),
|
|
5547
5960
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RightSidebar, {}),
|
|
5548
5961
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RedactConfirmModal, {}),
|
|
5962
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CalibrationDialog, {}),
|
|
5549
5963
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SignatureBridge, {}),
|
|
5550
5964
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SignDialog, {}),
|
|
5551
5965
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SignatureMakerModal, {})
|
|
@@ -5576,7 +5990,7 @@ function Shell() {
|
|
|
5576
5990
|
* changing these props on a mounted viewer does not rebuild the workspace.
|
|
5577
5991
|
*/
|
|
5578
5992
|
/** Lazy built-in packs — a strings override for one of these wraps its loader. */
|
|
5579
|
-
const BUILTIN_LOADERS = { es: () => Promise.resolve().then(() => require("./es-
|
|
5993
|
+
const BUILTIN_LOADERS = { es: () => Promise.resolve().then(() => require("./es-BXLlBo2b.cjs")).then((m) => m.es) };
|
|
5580
5994
|
const isDict = (v) => typeof v === "object" && v !== null;
|
|
5581
5995
|
/**
|
|
5582
5996
|
* Deep-merge `over` into `base` (immutably), expanding dotted keys —
|
|
@@ -5727,6 +6141,7 @@ function FullViewer({ engine, initialDocuments, fallback, commands, icons, strin
|
|
|
5727
6141
|
}),
|
|
5728
6142
|
(0, _embedpdf_react_link.linkPlugin)(),
|
|
5729
6143
|
(0, _embedpdf_react_redaction.redactionPlugin)(),
|
|
6144
|
+
(0, _embedpdf_react_measurement.measurementPlugin)(),
|
|
5730
6145
|
(0, _embedpdf_react_search.searchPlugin)(),
|
|
5731
6146
|
demoToolsPlugin(),
|
|
5732
6147
|
(0, _embedpdf_react_i18n.i18nPlugin)({
|
|
@@ -5795,6 +6210,12 @@ Object.defineProperty(exports, "InteractionToken", {
|
|
|
5795
6210
|
return _embedpdf_react_interaction.InteractionToken;
|
|
5796
6211
|
}
|
|
5797
6212
|
});
|
|
6213
|
+
Object.defineProperty(exports, "MeasurementToken", {
|
|
6214
|
+
enumerable: true,
|
|
6215
|
+
get: function() {
|
|
6216
|
+
return _embedpdf_react_measurement.MeasurementToken;
|
|
6217
|
+
}
|
|
6218
|
+
});
|
|
5798
6219
|
Object.defineProperty(exports, "MetadataToken", {
|
|
5799
6220
|
enumerable: true,
|
|
5800
6221
|
get: function() {
|