@embedpdf/plugin-measurement 3.0.0-next.14 → 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.
- package/README.md +57 -43
- package/dist/contract-BGn30CU9.d.cts +185 -0
- package/dist/contract-BHj3w9WF.cjs +178 -0
- package/dist/contract-BHj3w9WF.cjs.map +1 -0
- package/dist/contract-CSnWNeXI.d.ts +185 -0
- package/dist/contract-DyqqYfyE.js +131 -0
- package/dist/contract-DyqqYfyE.js.map +1 -0
- package/dist/contract.cjs +4 -1
- package/dist/contract.d.cts +2 -2
- package/dist/contract.d.ts +2 -2
- package/dist/contract.js +2 -2
- package/dist/index.cjs +554 -396
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +553 -399
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/dist/contract-BnLRuw-Z.d.cts +0 -101
- package/dist/contract-C_ugpRGJ.d.ts +0 -101
- package/dist/contract-DO0emN-T.js +0 -7
- package/dist/contract-DO0emN-T.js.map +0 -1
- package/dist/contract-Dy7X9nSj.cjs +0 -11
- package/dist/contract-Dy7X9nSj.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,59 +1,73 @@
|
|
|
1
1
|
# @embedpdf/plugin-measurement
|
|
2
2
|
|
|
3
|
-
Document-scoped page calibration,
|
|
3
|
+
Document-scoped page calibration, measurement authoring, and measurement readouts.
|
|
4
4
|
Install alongside `annotationPlugin()` and `interactionPlugin()`:
|
|
5
5
|
|
|
6
6
|
```ts
|
|
7
|
-
import {
|
|
8
|
-
measurementPlugin,
|
|
9
|
-
MeasurementToken,
|
|
10
|
-
} from '@embedpdf/plugin-measurement';
|
|
7
|
+
import { measurementPlugin, MeasurementToken } from '@embedpdf/plugin-measurement';
|
|
11
8
|
|
|
12
9
|
const plugins = [
|
|
13
|
-
/* interaction, annotation, ... */
|
|
14
|
-
|
|
15
|
-
}),
|
|
10
|
+
/* interaction, annotation, ... */
|
|
11
|
+
measurementPlugin({ defaultScale: 'metric' }),
|
|
16
12
|
];
|
|
13
|
+
|
|
17
14
|
const measurements = viewer.get(MeasurementToken);
|
|
18
|
-
await measurements.calibrate(
|
|
19
|
-
value: 5,
|
|
20
|
-
unit: 'm',
|
|
21
|
-
});
|
|
15
|
+
await measurements.calibrate({ page, from, to, distance: { value: 5, unit: 'm' } });
|
|
22
16
|
```
|
|
23
17
|
|
|
24
|
-
`calibrate` points are
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
length already expresses the full
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
`{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
18
|
+
`calibrate` points are page space, like the `CalibrationRequest` the calibrate
|
|
19
|
+
tool produces; the plugin converts them to PDF user space, and the line's length
|
|
20
|
+
is rounded through the engine's float32 coordinate rules. `UserUnit` participates
|
|
21
|
+
in ratio presets; a calibration from a known length already expresses the full
|
|
22
|
+
conversion.
|
|
23
|
+
|
|
24
|
+
The annotation plugin supplies the `distance`, `perimeter`, `area`, and
|
|
25
|
+
`calibrate` tools. A measurement captures the last viewport containing its
|
|
26
|
+
**first point**. A foreign or invalid winning viewport prevents creation; the
|
|
27
|
+
default scale is used only outside all viewports. Until the page's viewport reads
|
|
28
|
+
finish, measurement creation is unavailable.
|
|
29
|
+
`createMeasurement({ kind, page, points })` creates the same annotations from
|
|
30
|
+
code, resolves `{ annotation }`, and rejects with `not-ready` before the page's
|
|
31
|
+
scale is known. A page is a ref or an index everywhere.
|
|
32
|
+
`startCalibration()` arms the calibrate tool, and throws `permission-denied`
|
|
33
|
+
without `doc.annotate.modify`; its two points arrive as
|
|
34
|
+
`onCalibrationRequested` (and `getCalibrationRequest()`) awaiting the real
|
|
35
|
+
length, and `dismissCalibration()` drops the request.
|
|
36
|
+
|
|
37
|
+
`setScale`, `setPreset`, `setUnit`, `setAreaUnit`, `setPrecision`, and
|
|
38
|
+
`clearScale` take a page target — one page, an array of pages, or `'all'` — and
|
|
39
|
+
`{ recalculate?: boolean }`. `calibrate` writes its input page unless `applyTo`
|
|
40
|
+
names a wider target. Recalculation defaults to true. Every annotation stores its
|
|
41
|
+
own scale snapshot. Setting `recalculate: false` changes subsequent measurements
|
|
42
|
+
while preserving existing values.
|
|
43
|
+
|
|
44
|
+
Each scale change resolves to one report per page listing updated, skipped, and
|
|
45
|
+
failed annotations; `listLastReports()` keeps the last set and `onScaleChanged`
|
|
46
|
+
fires per page. A page-wide annotation read failure appears as `error`. A
|
|
47
|
+
single-page viewport write failure rejects before annotation writes; multi-page
|
|
48
|
+
operations (several pages or `'all'`) return per-page `scaleError` results and
|
|
49
|
+
finish the remaining pages. Page scales persist in the PDF when the engine
|
|
50
|
+
provides `page.measure`; without it they last for the session
|
|
51
|
+
(`getPageScale(page).persistent === false`).
|
|
52
|
+
|
|
53
|
+
`canCalibrate()` mirrors `doc.annotate.modify`; `canMeasure(page)` combines
|
|
47
54
|
annotation creation authority and viewport readiness. Per-record permissions and
|
|
48
|
-
PDF flags gate recalculation and caption dragging.
|
|
49
|
-
and cannot be edited as comment text.
|
|
55
|
+
PDF flags gate recalculation and caption dragging. Measurement contents are
|
|
56
|
+
derived and cannot be edited as comment text. `getReadout(ref)` formats a
|
|
57
|
+
measurement annotation; `measureDistance` and `measureArea` convert page-space
|
|
58
|
+
points in the page's scale without creating anything.
|
|
59
|
+
|
|
60
|
+
The settings, `defaultScale` and `presets`, change while the app runs:
|
|
61
|
+
`updateSettings()`, `resetSettings()` and `onSettingsChanged`, shared by every
|
|
62
|
+
document.
|
|
50
63
|
|
|
51
|
-
React consumers import `measurementPlugin`, `useMeasurement
|
|
52
|
-
`
|
|
53
|
-
|
|
64
|
+
React consumers import `measurementPlugin`, `useMeasurement` (the capability),
|
|
65
|
+
`useMeasurementState` (`busy`, `calibrationRequest`, `lastReports`),
|
|
66
|
+
`useMeasurementSettings`, `usePageScale`, `useMeasurementReadout` and
|
|
67
|
+
`useMeasurementEvent` from `@embedpdf/react/measurement`. The full viewer includes a Measure toolbar
|
|
68
|
+
(distance, perimeter, area, calibrate), a scale sidebar, and a known-length
|
|
69
|
+
calibration dialog.
|
|
54
70
|
|
|
55
71
|
Distance captions use standard PDF line-axis offsets. Their live layout uses an
|
|
56
72
|
estimated Helvetica advance; committed annotations render the native PDF
|
|
57
|
-
appearance.
|
|
58
|
-
initial viewer increment; readouts and page recalculation support their existing
|
|
59
|
-
engine annotations.
|
|
73
|
+
appearance.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { EventHook, OperationOptions, SettingsApi } from "@embedpdf/core";
|
|
2
|
+
import { Point } from "@embedpdf/core-geometry";
|
|
3
|
+
import { Annotation, AnnotationRef, AnnotationRef as AnnotationRef$1, AreaUnit, AreaUnit as AreaUnit$1, LengthUnit, LengthUnit as LengthUnit$1, MeasurementReadout, MeasurementReadout as MeasurementReadout$1, MeasurementUnavailable, MeasurementUnavailable as MeasurementUnavailable$1, PageRef, PdfMeasure, PdfMeasure as PdfMeasure$1, PdfMeasurement, SerializedEngineError } from "@embedpdf/engine-core/runtime";
|
|
4
|
+
import { RecalibrationReport, RecalibrationReport as RecalibrationReport$1 } from "@embedpdf/plugin-annotation/contract/host";
|
|
5
|
+
//#region src/token.d.ts
|
|
6
|
+
declare const MeasurementToken: import("@embedpdf/core").CapabilityToken<MeasurementCapability>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/contract.d.ts
|
|
9
|
+
/** One page, several pages, or every page of the document: each a ref or an index. */
|
|
10
|
+
type PageTarget = PageRef | number | readonly (PageRef | number)[] | 'all';
|
|
11
|
+
interface ScalePreset {
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
paper: number;
|
|
15
|
+
real: number;
|
|
16
|
+
unit: LengthUnit;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The measurement plugin's settings. `measurementPlugin(config)` registers
|
|
20
|
+
* them over {@link MEASUREMENT_DEFAULTS}, and `updateSettings()` changes them
|
|
21
|
+
* for every document while the app runs.
|
|
22
|
+
*/
|
|
23
|
+
interface MeasurementSettings {
|
|
24
|
+
/**
|
|
25
|
+
* The scale of a page that has none: 1:1 in meters (`'metric'`) or in
|
|
26
|
+
* feet (`'imperial'`), or a scale of your own.
|
|
27
|
+
*/
|
|
28
|
+
readonly defaultScale: 'metric' | 'imperial' | PdfMeasure;
|
|
29
|
+
/** The scales `listPresets()` offers. */
|
|
30
|
+
readonly presets: readonly ScalePreset[];
|
|
31
|
+
}
|
|
32
|
+
/** What the measurement settings are when the app registers none. */
|
|
33
|
+
declare const MEASUREMENT_DEFAULTS: MeasurementSettings;
|
|
34
|
+
/** What `measurementPlugin(config)` takes: either setting, each a whole value. */
|
|
35
|
+
type MeasurementConfig = Partial<MeasurementSettings>;
|
|
36
|
+
interface ScaleChangeOptions extends OperationOptions {
|
|
37
|
+
/** Re-measure the page's measurement annotations with the new scale. Default true. */
|
|
38
|
+
recalculate?: boolean;
|
|
39
|
+
}
|
|
40
|
+
interface PageScale {
|
|
41
|
+
measure: PdfMeasurement | null;
|
|
42
|
+
source: 'owned' | 'foreign' | 'default';
|
|
43
|
+
/** The page's viewports are known. */
|
|
44
|
+
ready: boolean;
|
|
45
|
+
/** The engine can persist a scale into the document. */
|
|
46
|
+
persistent: boolean;
|
|
47
|
+
/** Why the last read of the page's viewports failed; the last known viewports stay in effect. */
|
|
48
|
+
error?: SerializedEngineError;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A page's scale where there is none to read: before a document opens, or for
|
|
52
|
+
* a page that isn't there. Not ready, with no measure; the same object every
|
|
53
|
+
* time, so a framework read compares it by identity.
|
|
54
|
+
*/
|
|
55
|
+
declare const NO_PAGE_SCALE: PageScale;
|
|
56
|
+
/**
|
|
57
|
+
* The readout where there is no measurement to read: before a document
|
|
58
|
+
* opens, or for an annotation that isn't there. `getReadout` answers it too.
|
|
59
|
+
*/
|
|
60
|
+
declare const NO_READOUT: MeasurementUnavailable;
|
|
61
|
+
/** Two points captured by the calibrate tool, awaiting the real length. Page space. */
|
|
62
|
+
interface CalibrationRequest {
|
|
63
|
+
page: PageRef;
|
|
64
|
+
from: Point;
|
|
65
|
+
to: Point;
|
|
66
|
+
/** The captured length in PDF user space (the scale is derived from it). */
|
|
67
|
+
userSpaceLength: number;
|
|
68
|
+
}
|
|
69
|
+
interface CalibrateInput {
|
|
70
|
+
/** The page, as a ref or an index. */
|
|
71
|
+
page: PageRef | number;
|
|
72
|
+
/** The two ends of the known length, in page space. */
|
|
73
|
+
from: Point;
|
|
74
|
+
to: Point;
|
|
75
|
+
/** The real-world length between the two points. */
|
|
76
|
+
distance: {
|
|
77
|
+
value: number;
|
|
78
|
+
unit: LengthUnit;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** A failed viewport write is reported per page for a multi-page change.
|
|
82
|
+
* Single-page failures reject before any annotation write. */
|
|
83
|
+
type ScaleChangeReport = (RecalibrationReport & {
|
|
84
|
+
scaleError?: never;
|
|
85
|
+
}) | {
|
|
86
|
+
page: PageRef;
|
|
87
|
+
scale?: never;
|
|
88
|
+
error?: never;
|
|
89
|
+
updated: [];
|
|
90
|
+
skipped: [];
|
|
91
|
+
failed: [];
|
|
92
|
+
scaleError: SerializedEngineError;
|
|
93
|
+
};
|
|
94
|
+
type MeasurementKind = 'distance' | 'perimeter' | 'area';
|
|
95
|
+
interface CreateMeasurementInput {
|
|
96
|
+
kind: MeasurementKind;
|
|
97
|
+
/** The page, as a ref or an index. */
|
|
98
|
+
page: PageRef | number;
|
|
99
|
+
/** Page-space points: two for a distance, the vertices otherwise. */
|
|
100
|
+
points: readonly Point[];
|
|
101
|
+
/** The authoring tool whose defaults apply (defaults to the kind's own tool). */
|
|
102
|
+
tool?: string;
|
|
103
|
+
}
|
|
104
|
+
interface MeasurementScaleChangedEvent {
|
|
105
|
+
readonly page: PageRef;
|
|
106
|
+
readonly report: ScaleChangeReport;
|
|
107
|
+
}
|
|
108
|
+
interface CalibrationRequestedEvent {
|
|
109
|
+
readonly request: CalibrationRequest;
|
|
110
|
+
}
|
|
111
|
+
interface CalibrationCompletedEvent {
|
|
112
|
+
readonly page: PageRef;
|
|
113
|
+
}
|
|
114
|
+
type CalibrationDismissedEvent = Record<string, never>;
|
|
115
|
+
/**
|
|
116
|
+
* Page scales, calibration and measurement readouts for one document. A page
|
|
117
|
+
* argument is a ref or an index: a read given a page that isn't there
|
|
118
|
+
* answers empty, a verb refuses it with `not-found`. Every async verb takes
|
|
119
|
+
* a `signal`. The settings belong to the plugin, not to a document: a change
|
|
120
|
+
* reaches every open document.
|
|
121
|
+
*/
|
|
122
|
+
interface MeasurementCapability extends SettingsApi<MeasurementSettings> {
|
|
123
|
+
/** May write a page scale and calibrate (`doc.annotate.modify`). */
|
|
124
|
+
canCalibrate(): boolean;
|
|
125
|
+
/** May measure on the page: `annotations:create`, and the page's scale has loaded. */
|
|
126
|
+
canMeasure(page: PageRef | number): boolean;
|
|
127
|
+
/** The resolved scale, its source and readiness. Reference-stable while unchanged. */
|
|
128
|
+
getPageScale(page: PageRef | number): PageScale;
|
|
129
|
+
/** Load the page's viewports. Resolves at once when already known. Rejects `not-found`. */
|
|
130
|
+
ensureLoaded(page: PageRef | number, options?: OperationOptions): Promise<void>;
|
|
131
|
+
/** A scale change is in flight. */
|
|
132
|
+
isBusy(): boolean;
|
|
133
|
+
/** The reports of the last scale change, one per page. */
|
|
134
|
+
listLastReports(): readonly ScaleChangeReport[];
|
|
135
|
+
listPresets(): readonly ScalePreset[];
|
|
136
|
+
listUnits(): readonly LengthUnit[];
|
|
137
|
+
listAreaUnits(): readonly AreaUnit[];
|
|
138
|
+
/**
|
|
139
|
+
* The formatted measurement of a measurement annotation, or why there is
|
|
140
|
+
* none ({@link NO_READOUT} for an annotation that isn't there). The same
|
|
141
|
+
* object until the annotation changes.
|
|
142
|
+
*/
|
|
143
|
+
getReadout(ref: AnnotationRef): MeasurementReadout | MeasurementUnavailable;
|
|
144
|
+
/** A distance between two page-space points in the page's scale: a pure conversion, no annotation. */
|
|
145
|
+
measureDistance(page: PageRef | number, from: Point, to: Point): MeasurementReadout | MeasurementUnavailable;
|
|
146
|
+
/** The area of a page-space polygon in the page's scale: a pure conversion, no annotation. */
|
|
147
|
+
measureArea(page: PageRef | number, vertices: readonly Point[]): MeasurementReadout | MeasurementUnavailable;
|
|
148
|
+
/** Two points captured, awaiting a length. */
|
|
149
|
+
getCalibrationRequest(): CalibrationRequest | null;
|
|
150
|
+
setScale(pages: PageTarget, measure: PdfMeasure, options?: ScaleChangeOptions): Promise<readonly ScaleChangeReport[]>;
|
|
151
|
+
/** Derive a scale from a known length between two page points. `applyTo` widens the write (default: the input page). Fires `onCalibrationCompleted`. */
|
|
152
|
+
calibrate(input: CalibrateInput, options?: ScaleChangeOptions & {
|
|
153
|
+
applyTo?: PageTarget;
|
|
154
|
+
}): Promise<readonly ScaleChangeReport[]>;
|
|
155
|
+
setUnit(pages: PageTarget, unit: LengthUnit, options?: ScaleChangeOptions): Promise<readonly ScaleChangeReport[]>;
|
|
156
|
+
setAreaUnit(pages: PageTarget, unit: AreaUnit, options?: ScaleChangeOptions): Promise<readonly ScaleChangeReport[]>;
|
|
157
|
+
setPrecision(pages: PageTarget, precision: number, options?: ScaleChangeOptions): Promise<readonly ScaleChangeReport[]>;
|
|
158
|
+
/** A scale from the `presets` setting. Rejects `not-found` for an unknown preset. */
|
|
159
|
+
setPreset(pages: PageTarget, presetId: string, options?: ScaleChangeOptions): Promise<readonly ScaleChangeReport[]>;
|
|
160
|
+
/** Back to the default scale (the owned viewport is removed). */
|
|
161
|
+
clearScale(pages: PageTarget, options?: ScaleChangeOptions): Promise<readonly ScaleChangeReport[]>;
|
|
162
|
+
/**
|
|
163
|
+
* Create a measurement annotation with the page's scale and the tool's
|
|
164
|
+
* style. Resolves `{ annotation }`. Rejects `permission-denied` without
|
|
165
|
+
* `annotations:create`, `not-ready` before the scale is known,
|
|
166
|
+
* `not-found` for a page that isn't in the document.
|
|
167
|
+
*/
|
|
168
|
+
createMeasurement(input: CreateMeasurementInput, options?: OperationOptions): Promise<{
|
|
169
|
+
annotation: Annotation;
|
|
170
|
+
}>;
|
|
171
|
+
/**
|
|
172
|
+
* Arm the calibrate tool (two points, then `onCalibrationRequested`).
|
|
173
|
+
* Throws `permission-denied` without `doc.annotate.modify` (see `canCalibrate`).
|
|
174
|
+
*/
|
|
175
|
+
startCalibration(): void;
|
|
176
|
+
/** Drop the pending request. Fires `onCalibrationDismissed` when there was one. */
|
|
177
|
+
dismissCalibration(): void;
|
|
178
|
+
readonly onScaleChanged: EventHook<MeasurementScaleChangedEvent>;
|
|
179
|
+
readonly onCalibrationRequested: EventHook<CalibrationRequestedEvent>;
|
|
180
|
+
readonly onCalibrationCompleted: EventHook<CalibrationCompletedEvent>;
|
|
181
|
+
readonly onCalibrationDismissed: EventHook<CalibrationDismissedEvent>;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { RecalibrationReport$1 as C, MeasurementToken as D, ScalePreset as E, PdfMeasure$1 as S, ScaleChangeReport as T, MeasurementUnavailable$1 as _, CalibrationDismissedEvent as a, PageScale as b, CreateMeasurementInput as c, MeasurementCapability as d, MeasurementConfig as f, MeasurementSettings as g, MeasurementScaleChangedEvent as h, CalibrationCompletedEvent as i, LengthUnit$1 as l, MeasurementReadout$1 as m, AreaUnit$1 as n, CalibrationRequest as o, MeasurementKind as p, CalibrateInput as r, CalibrationRequestedEvent as s, AnnotationRef$1 as t, MEASUREMENT_DEFAULTS as u, NO_PAGE_SCALE as v, ScaleChangeOptions as w, PageTarget as x, NO_READOUT as y };
|
|
185
|
+
//# sourceMappingURL=contract-BGn30CU9.d.cts.map
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
let _embedpdf_core = require("@embedpdf/core");
|
|
2
|
+
let _embedpdf_engine_core_runtime = require("@embedpdf/engine-core/runtime");
|
|
3
|
+
//#region src/scale.ts
|
|
4
|
+
/** Scale arithmetic: the default presets and scale, and unit and precision edits of a scale. */
|
|
5
|
+
/** The scales offered when the app registers none: metric 1:1 to 1:200, and two imperial ones. */
|
|
6
|
+
const DEFAULT_PRESETS = [
|
|
7
|
+
...[
|
|
8
|
+
1,
|
|
9
|
+
10,
|
|
10
|
+
20,
|
|
11
|
+
50,
|
|
12
|
+
100,
|
|
13
|
+
200
|
|
14
|
+
].map((real) => ({
|
|
15
|
+
id: `metric-${real}`,
|
|
16
|
+
label: `1:${real}`,
|
|
17
|
+
paper: 1,
|
|
18
|
+
real,
|
|
19
|
+
unit: "m"
|
|
20
|
+
})),
|
|
21
|
+
{
|
|
22
|
+
id: "imperial-quarter",
|
|
23
|
+
label: "1/4 in = 1 ft",
|
|
24
|
+
paper: 1,
|
|
25
|
+
real: 48,
|
|
26
|
+
unit: "ft"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "imperial-eighth",
|
|
30
|
+
label: "1/8 in = 1 ft",
|
|
31
|
+
paper: 1,
|
|
32
|
+
real: 96,
|
|
33
|
+
unit: "ft"
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
/** The scale of a page that has none, from the `defaultScale` setting. */
|
|
37
|
+
const defaultMeasure = (defaultScale, userUnit = 1) => typeof defaultScale === "object" ? defaultScale : (0, _embedpdf_engine_core_runtime.measureFromRatio)(1, 1, defaultScale === "imperial" ? "ft" : "m", { userUnit });
|
|
38
|
+
function withUnit(measure, unit, area = (0, _embedpdf_engine_core_runtime.squareOf)(unit)) {
|
|
39
|
+
const basis = measure.x[0]?.unit.trim();
|
|
40
|
+
if (!(basis in _embedpdf_engine_core_runtime.METRES)) throw new RangeError("This scale has an unknown base unit; calibrate it first");
|
|
41
|
+
const previous = measure.distance[measure.distance.length - 1];
|
|
42
|
+
const precision = previous?.fraction === "fraction" ? 100 : previous?.precision ?? 100;
|
|
43
|
+
return {
|
|
44
|
+
...measure,
|
|
45
|
+
distance: [{
|
|
46
|
+
unit,
|
|
47
|
+
conversion: _embedpdf_engine_core_runtime.METRES[basis] / _embedpdf_engine_core_runtime.METRES[unit],
|
|
48
|
+
precision,
|
|
49
|
+
fraction: "decimal"
|
|
50
|
+
}],
|
|
51
|
+
area: [{
|
|
52
|
+
unit: (0, _embedpdf_engine_core_runtime.areaUnitLabel)(area),
|
|
53
|
+
conversion: _embedpdf_engine_core_runtime.METRES[basis] ** 2 / (0, _embedpdf_engine_core_runtime.squareMetres)(area),
|
|
54
|
+
precision,
|
|
55
|
+
fraction: "decimal"
|
|
56
|
+
}]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function withPrecision(measure, precision) {
|
|
60
|
+
if (!Number.isInteger(Math.log10(precision)) || precision < 1 || precision > 1e9) throw new RangeError("Invalid decimal precision");
|
|
61
|
+
const update = (formats) => formats.map((format, index) => index === formats.length - 1 ? {
|
|
62
|
+
...format,
|
|
63
|
+
precision,
|
|
64
|
+
fraction: "decimal"
|
|
65
|
+
} : format);
|
|
66
|
+
return {
|
|
67
|
+
...measure,
|
|
68
|
+
distance: update(measure.distance),
|
|
69
|
+
area: update(measure.area)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Change the area display unit while preserving imported distance formatting. */
|
|
73
|
+
function withAreaUnit(measure, unit) {
|
|
74
|
+
const basis = measure.x[0]?.unit.trim();
|
|
75
|
+
if (!(basis in _embedpdf_engine_core_runtime.METRES)) throw new RangeError("This scale has an unknown base unit; calibrate it first");
|
|
76
|
+
const previous = measure.area[measure.area.length - 1];
|
|
77
|
+
const precision = previous?.fraction === "fraction" ? 100 : previous?.precision ?? 100;
|
|
78
|
+
return {
|
|
79
|
+
...measure,
|
|
80
|
+
area: [{
|
|
81
|
+
unit: (0, _embedpdf_engine_core_runtime.areaUnitLabel)(unit),
|
|
82
|
+
conversion: _embedpdf_engine_core_runtime.METRES[basis] ** 2 / (0, _embedpdf_engine_core_runtime.squareMetres)(unit),
|
|
83
|
+
precision,
|
|
84
|
+
fraction: "decimal"
|
|
85
|
+
}]
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/token.ts
|
|
90
|
+
/** The package token, created once here and re-exported by `contract.ts`. */
|
|
91
|
+
const MeasurementToken = (0, _embedpdf_core.createCapabilityToken)("measurement", {
|
|
92
|
+
hint: `add measurementPlugin() from '@embedpdf/plugin-measurement' to your plugins list`,
|
|
93
|
+
promises: {
|
|
94
|
+
ensureLoaded: true,
|
|
95
|
+
setScale: true,
|
|
96
|
+
calibrate: true,
|
|
97
|
+
setUnit: true,
|
|
98
|
+
setAreaUnit: true,
|
|
99
|
+
setPrecision: true,
|
|
100
|
+
setPreset: true,
|
|
101
|
+
clearScale: true,
|
|
102
|
+
createMeasurement: true
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/contract.ts
|
|
107
|
+
/** What the measurement settings are when the app registers none. */
|
|
108
|
+
const MEASUREMENT_DEFAULTS = {
|
|
109
|
+
defaultScale: "metric",
|
|
110
|
+
presets: DEFAULT_PRESETS
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* A page's scale where there is none to read: before a document opens, or for
|
|
114
|
+
* a page that isn't there. Not ready, with no measure; the same object every
|
|
115
|
+
* time, so a framework read compares it by identity.
|
|
116
|
+
*/
|
|
117
|
+
const NO_PAGE_SCALE = Object.freeze({
|
|
118
|
+
measure: null,
|
|
119
|
+
source: "default",
|
|
120
|
+
ready: false,
|
|
121
|
+
persistent: false
|
|
122
|
+
});
|
|
123
|
+
/**
|
|
124
|
+
* The readout where there is no measurement to read: before a document
|
|
125
|
+
* opens, or for an annotation that isn't there. `getReadout` answers it too.
|
|
126
|
+
*/
|
|
127
|
+
const NO_READOUT = Object.freeze({ unavailable: "not-dimension" });
|
|
128
|
+
//#endregion
|
|
129
|
+
Object.defineProperty(exports, "MEASUREMENT_DEFAULTS", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
get: function() {
|
|
132
|
+
return MEASUREMENT_DEFAULTS;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
Object.defineProperty(exports, "MeasurementToken", {
|
|
136
|
+
enumerable: true,
|
|
137
|
+
get: function() {
|
|
138
|
+
return MeasurementToken;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(exports, "NO_PAGE_SCALE", {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function() {
|
|
144
|
+
return NO_PAGE_SCALE;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
Object.defineProperty(exports, "NO_READOUT", {
|
|
148
|
+
enumerable: true,
|
|
149
|
+
get: function() {
|
|
150
|
+
return NO_READOUT;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(exports, "defaultMeasure", {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function() {
|
|
156
|
+
return defaultMeasure;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
Object.defineProperty(exports, "withAreaUnit", {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
get: function() {
|
|
162
|
+
return withAreaUnit;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
Object.defineProperty(exports, "withPrecision", {
|
|
166
|
+
enumerable: true,
|
|
167
|
+
get: function() {
|
|
168
|
+
return withPrecision;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
Object.defineProperty(exports, "withUnit", {
|
|
172
|
+
enumerable: true,
|
|
173
|
+
get: function() {
|
|
174
|
+
return withUnit;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
//# sourceMappingURL=contract-BHj3w9WF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-BHj3w9WF.cjs","names":["METRES"],"sources":["../src/scale.ts","../src/token.ts","../src/contract.ts"],"sourcesContent":["/** Scale arithmetic: the default presets and scale, and unit and precision edits of a scale. */\nimport {\n areaUnitLabel,\n measureFromRatio,\n METRES,\n squareMetres,\n squareOf,\n} from '@embedpdf/engine-core/runtime';\nimport type { AreaUnit, LengthUnit, PdfMeasure } from '@embedpdf/engine-core/runtime';\n\nimport type { MeasurementSettings, ScalePreset } from './contract';\n\n/** The scales offered when the app registers none: metric 1:1 to 1:200, and two imperial ones. */\nexport const DEFAULT_PRESETS: readonly ScalePreset[] = [\n ...[1, 10, 20, 50, 100, 200].map((real) => ({\n id: `metric-${real}`,\n label: `1:${real}`,\n paper: 1,\n real,\n unit: 'm' as const,\n })),\n { id: 'imperial-quarter', label: '1/4 in = 1 ft', paper: 1, real: 48, unit: 'ft' },\n { id: 'imperial-eighth', label: '1/8 in = 1 ft', paper: 1, real: 96, unit: 'ft' },\n];\n\n/** The scale of a page that has none, from the `defaultScale` setting. */\nexport const defaultMeasure = (\n defaultScale: MeasurementSettings['defaultScale'],\n userUnit = 1,\n): PdfMeasure =>\n typeof defaultScale === 'object'\n ? defaultScale\n : measureFromRatio(1, 1, defaultScale === 'imperial' ? 'ft' : 'm', { userUnit });\n\nexport function withUnit(\n measure: PdfMeasure,\n unit: LengthUnit,\n area: AreaUnit = squareOf(unit),\n): PdfMeasure {\n const basis = measure.x[0]?.unit.trim() as LengthUnit;\n if (!(basis in METRES)) {\n throw new RangeError('This scale has an unknown base unit; calibrate it first');\n }\n const previous = measure.distance[measure.distance.length - 1];\n const precision = previous?.fraction === 'fraction' ? 100 : (previous?.precision ?? 100);\n return {\n ...measure,\n distance: [{ unit, conversion: METRES[basis] / METRES[unit], precision, fraction: 'decimal' }],\n area: [\n {\n unit: areaUnitLabel(area),\n conversion: METRES[basis] ** 2 / squareMetres(area),\n precision,\n fraction: 'decimal',\n },\n ],\n };\n}\n\nexport function withPrecision(measure: PdfMeasure, precision: number): PdfMeasure {\n if (!Number.isInteger(Math.log10(precision)) || precision < 1 || precision > 1e9) {\n throw new RangeError('Invalid decimal precision');\n }\n const update = (formats: PdfMeasure['distance']) =>\n formats.map((format, index) =>\n index === formats.length - 1\n ? { ...format, precision, fraction: 'decimal' as const }\n : format,\n );\n return { ...measure, distance: update(measure.distance), area: update(measure.area) };\n}\n\n/** Change the area display unit while preserving imported distance formatting. */\nexport function withAreaUnit(measure: PdfMeasure, unit: AreaUnit): PdfMeasure {\n const basis = measure.x[0]?.unit.trim() as LengthUnit;\n if (!(basis in METRES)) {\n throw new RangeError('This scale has an unknown base unit; calibrate it first');\n }\n const previous = measure.area[measure.area.length - 1];\n const precision = previous?.fraction === 'fraction' ? 100 : (previous?.precision ?? 100);\n return {\n ...measure,\n area: [\n {\n unit: areaUnitLabel(unit),\n conversion: METRES[basis] ** 2 / squareMetres(unit),\n precision,\n fraction: 'decimal',\n },\n ],\n };\n}\n","/** The package token, created once here and re-exported by `contract.ts`. */\nimport { createCapabilityToken } from '@embedpdf/core';\n\nimport type { MeasurementCapability } from './contract';\n\nexport const MeasurementToken = createCapabilityToken<MeasurementCapability>('measurement', {\n hint: `add measurementPlugin() from '@embedpdf/plugin-measurement' to your plugins list`,\n // Without a document, an adapter's stand-in rejects these with `not-ready`, as the\n // capability would; the type asks for every member that returns a promise.\n promises: {\n ensureLoaded: true,\n setScale: true,\n calibrate: true,\n setUnit: true,\n setAreaUnit: true,\n setPrecision: true,\n setPreset: true,\n clearScale: true,\n createMeasurement: true,\n },\n});\n","/**\n * @embedpdf/plugin-measurement/contract: the public measurement vocabulary:\n * page scale, calibration, scale-aware readouts, and measurement creation.\n * Creating a measurement annotation is `annotation.create` with a\n * measurement tool; this plugin adds the page-scale sugar around it.\n */\nimport type { EventHook, OperationOptions, SettingsApi } from '@embedpdf/core';\nimport type { Point } from '@embedpdf/core-geometry';\nimport type {\n Annotation,\n AnnotationRef,\n AreaUnit,\n LengthUnit,\n MeasurementReadout,\n MeasurementUnavailable,\n PageRef,\n PdfMeasure,\n PdfMeasurement,\n SerializedEngineError,\n} from '@embedpdf/engine-core/runtime';\nimport type { RecalibrationReport } from '@embedpdf/plugin-annotation/contract/host';\n\nimport { DEFAULT_PRESETS } from './scale';\n\nexport { MeasurementToken } from './token';\nexport type { RecalibrationReport } from '@embedpdf/plugin-annotation/contract/host';\nexport type {\n AnnotationRef,\n AreaUnit,\n LengthUnit,\n MeasurementReadout,\n MeasurementUnavailable,\n PdfMeasure,\n} from '@embedpdf/engine-core/runtime';\n\n/** One page, several pages, or every page of the document: each a ref or an index. */\nexport type PageTarget = PageRef | number | readonly (PageRef | number)[] | 'all';\n\nexport interface ScalePreset {\n id: string;\n label: string;\n paper: number;\n real: number;\n unit: LengthUnit;\n}\n\n/**\n * The measurement plugin's settings. `measurementPlugin(config)` registers\n * them over {@link MEASUREMENT_DEFAULTS}, and `updateSettings()` changes them\n * for every document while the app runs.\n */\nexport interface MeasurementSettings {\n /**\n * The scale of a page that has none: 1:1 in meters (`'metric'`) or in\n * feet (`'imperial'`), or a scale of your own.\n */\n readonly defaultScale: 'metric' | 'imperial' | PdfMeasure;\n /** The scales `listPresets()` offers. */\n readonly presets: readonly ScalePreset[];\n}\n\n/** What the measurement settings are when the app registers none. */\nexport const MEASUREMENT_DEFAULTS: MeasurementSettings = {\n defaultScale: 'metric',\n presets: DEFAULT_PRESETS,\n};\n\n/** What `measurementPlugin(config)` takes: either setting, each a whole value. */\nexport type MeasurementConfig = Partial<MeasurementSettings>;\n\nexport interface ScaleChangeOptions extends OperationOptions {\n /** Re-measure the page's measurement annotations with the new scale. Default true. */\n recalculate?: boolean;\n}\n\nexport interface PageScale {\n measure: PdfMeasurement | null;\n source: 'owned' | 'foreign' | 'default';\n /** The page's viewports are known. */\n ready: boolean;\n /** The engine can persist a scale into the document. */\n persistent: boolean;\n /** Why the last read of the page's viewports failed; the last known viewports stay in effect. */\n error?: SerializedEngineError;\n}\n\n/**\n * A page's scale where there is none to read: before a document opens, or for\n * a page that isn't there. Not ready, with no measure; the same object every\n * time, so a framework read compares it by identity.\n */\nexport const NO_PAGE_SCALE: PageScale = Object.freeze({\n measure: null,\n source: 'default',\n ready: false,\n persistent: false,\n});\n\n/**\n * The readout where there is no measurement to read: before a document\n * opens, or for an annotation that isn't there. `getReadout` answers it too.\n */\nexport const NO_READOUT: MeasurementUnavailable = Object.freeze({ unavailable: 'not-dimension' });\n\n/** Two points captured by the calibrate tool, awaiting the real length. Page space. */\nexport interface CalibrationRequest {\n page: PageRef;\n from: Point;\n to: Point;\n /** The captured length in PDF user space (the scale is derived from it). */\n userSpaceLength: number;\n}\n\nexport interface CalibrateInput {\n /** The page, as a ref or an index. */\n page: PageRef | number;\n /** The two ends of the known length, in page space. */\n from: Point;\n to: Point;\n /** The real-world length between the two points. */\n distance: { value: number; unit: LengthUnit };\n}\n\n/** A failed viewport write is reported per page for a multi-page change.\n * Single-page failures reject before any annotation write. */\nexport type ScaleChangeReport =\n | (RecalibrationReport & { scaleError?: never })\n | {\n page: PageRef;\n scale?: never;\n error?: never;\n updated: [];\n skipped: [];\n failed: [];\n scaleError: SerializedEngineError;\n };\n\nexport type MeasurementKind = 'distance' | 'perimeter' | 'area';\n\nexport interface CreateMeasurementInput {\n kind: MeasurementKind;\n /** The page, as a ref or an index. */\n page: PageRef | number;\n /** Page-space points: two for a distance, the vertices otherwise. */\n points: readonly Point[];\n /** The authoring tool whose defaults apply (defaults to the kind's own tool). */\n tool?: string;\n}\n\n// ── events ──\nexport interface MeasurementScaleChangedEvent {\n readonly page: PageRef;\n readonly report: ScaleChangeReport;\n}\nexport interface CalibrationRequestedEvent {\n readonly request: CalibrationRequest;\n}\nexport interface CalibrationCompletedEvent {\n readonly page: PageRef;\n}\nexport type CalibrationDismissedEvent = Record<string, never>;\n\n/**\n * Page scales, calibration and measurement readouts for one document. A page\n * argument is a ref or an index: a read given a page that isn't there\n * answers empty, a verb refuses it with `not-found`. Every async verb takes\n * a `signal`. The settings belong to the plugin, not to a document: a change\n * reaches every open document.\n */\nexport interface MeasurementCapability extends SettingsApi<MeasurementSettings> {\n // ── twins ──\n /** May write a page scale and calibrate (`doc.annotate.modify`). */\n canCalibrate(): boolean;\n /** May measure on the page: `annotations:create`, and the page's scale has loaded. */\n canMeasure(page: PageRef | number): boolean;\n\n // ── reading ──\n /** The resolved scale, its source and readiness. Reference-stable while unchanged. */\n getPageScale(page: PageRef | number): PageScale;\n /** Load the page's viewports. Resolves at once when already known. Rejects `not-found`. */\n ensureLoaded(page: PageRef | number, options?: OperationOptions): Promise<void>;\n /** A scale change is in flight. */\n isBusy(): boolean;\n /** The reports of the last scale change, one per page. */\n listLastReports(): readonly ScaleChangeReport[];\n listPresets(): readonly ScalePreset[];\n listUnits(): readonly LengthUnit[];\n listAreaUnits(): readonly AreaUnit[];\n /**\n * The formatted measurement of a measurement annotation, or why there is\n * none ({@link NO_READOUT} for an annotation that isn't there). The same\n * object until the annotation changes.\n */\n getReadout(ref: AnnotationRef): MeasurementReadout | MeasurementUnavailable;\n /** A distance between two page-space points in the page's scale: a pure conversion, no annotation. */\n measureDistance(\n page: PageRef | number,\n from: Point,\n to: Point,\n ): MeasurementReadout | MeasurementUnavailable;\n /** The area of a page-space polygon in the page's scale: a pure conversion, no annotation. */\n measureArea(\n page: PageRef | number,\n vertices: readonly Point[],\n ): MeasurementReadout | MeasurementUnavailable;\n /** Two points captured, awaiting a length. */\n getCalibrationRequest(): CalibrationRequest | null;\n\n // ── the scale ──\n // Every scale change rejects `permission-denied` without\n // `doc.annotate.modify` (see `canCalibrate`), and `not-found` for a page\n // that isn't in the document.\n setScale(\n pages: PageTarget,\n measure: PdfMeasure,\n options?: ScaleChangeOptions,\n ): Promise<readonly ScaleChangeReport[]>;\n /** Derive a scale from a known length between two page points. `applyTo` widens the write (default: the input page). Fires `onCalibrationCompleted`. */\n calibrate(\n input: CalibrateInput,\n options?: ScaleChangeOptions & { applyTo?: PageTarget },\n ): Promise<readonly ScaleChangeReport[]>;\n setUnit(\n pages: PageTarget,\n unit: LengthUnit,\n options?: ScaleChangeOptions,\n ): Promise<readonly ScaleChangeReport[]>;\n setAreaUnit(\n pages: PageTarget,\n unit: AreaUnit,\n options?: ScaleChangeOptions,\n ): Promise<readonly ScaleChangeReport[]>;\n setPrecision(\n pages: PageTarget,\n precision: number,\n options?: ScaleChangeOptions,\n ): Promise<readonly ScaleChangeReport[]>;\n /** A scale from the `presets` setting. Rejects `not-found` for an unknown preset. */\n setPreset(\n pages: PageTarget,\n presetId: string,\n options?: ScaleChangeOptions,\n ): Promise<readonly ScaleChangeReport[]>;\n /** Back to the default scale (the owned viewport is removed). */\n clearScale(\n pages: PageTarget,\n options?: ScaleChangeOptions,\n ): Promise<readonly ScaleChangeReport[]>;\n\n // ── measuring ──\n /**\n * Create a measurement annotation with the page's scale and the tool's\n * style. Resolves `{ annotation }`. Rejects `permission-denied` without\n * `annotations:create`, `not-ready` before the scale is known,\n * `not-found` for a page that isn't in the document.\n */\n createMeasurement(\n input: CreateMeasurementInput,\n options?: OperationOptions,\n ): Promise<{ annotation: Annotation }>;\n\n // ── calibration flow ──\n /**\n * Arm the calibrate tool (two points, then `onCalibrationRequested`).\n * Throws `permission-denied` without `doc.annotate.modify` (see `canCalibrate`).\n */\n startCalibration(): void;\n /** Drop the pending request. Fires `onCalibrationDismissed` when there was one. */\n dismissCalibration(): void;\n\n // ── events ──\n readonly onScaleChanged: EventHook<MeasurementScaleChangedEvent>;\n readonly onCalibrationRequested: EventHook<CalibrationRequestedEvent>;\n readonly onCalibrationCompleted: EventHook<CalibrationCompletedEvent>;\n readonly onCalibrationDismissed: EventHook<CalibrationDismissedEvent>;\n}\n"],"mappings":";;;;;AAaA,MAAa,kBAA0C;CACrD,GAAG;EAAC;EAAG;EAAI;EAAI;EAAI;EAAK;CAAG,CAAC,CAAC,KAAK,UAAU;EAC1C,IAAI,UAAU;EACd,OAAO,KAAK;EACZ,OAAO;EACP;EACA,MAAM;CACR,EAAE;CACF;EAAE,IAAI;EAAoB,OAAO;EAAiB,OAAO;EAAG,MAAM;EAAI,MAAM;CAAK;CACjF;EAAE,IAAI;EAAmB,OAAO;EAAiB,OAAO;EAAG,MAAM;EAAI,MAAM;CAAK;AAClF;;AAGA,MAAa,kBACX,cACA,WAAW,MAEX,OAAO,iBAAiB,WACpB,gBAAA,GAAA,8BAAA,iBAAA,CACiB,GAAG,GAAG,iBAAiB,aAAa,OAAO,KAAK,EAAE,SAAS,CAAC;AAEnF,SAAgB,SACd,SACA,MACA,QAAA,GAAA,8BAAA,SAAA,CAA0B,IAAI,GAClB;CACZ,MAAM,QAAQ,QAAQ,EAAE,EAAE,EAAE,KAAK,KAAK;CACtC,IAAI,EAAE,SAASA,8BAAAA,SACb,MAAM,IAAI,WAAW,yDAAyD;CAEhF,MAAM,WAAW,QAAQ,SAAS,QAAQ,SAAS,SAAS;CAC5D,MAAM,YAAY,UAAU,aAAa,aAAa,MAAO,UAAU,aAAa;CACpF,OAAO;EACL,GAAG;EACH,UAAU,CAAC;GAAE;GAAM,YAAYA,8BAAAA,OAAO,SAASA,8BAAAA,OAAO;GAAO;GAAW,UAAU;EAAU,CAAC;EAC7F,MAAM,CACJ;GACE,OAAA,GAAA,8BAAA,cAAA,CAAoB,IAAI;GACxB,YAAYA,8BAAAA,OAAO,UAAU,KAAA,GAAA,8BAAA,aAAA,CAAiB,IAAI;GAClD;GACA,UAAU;EACZ,CACF;CACF;AACF;AAEA,SAAgB,cAAc,SAAqB,WAA+B;CAChF,IAAI,CAAC,OAAO,UAAU,KAAK,MAAM,SAAS,CAAC,KAAK,YAAY,KAAK,YAAY,KAC3E,MAAM,IAAI,WAAW,2BAA2B;CAElD,MAAM,UAAU,YACd,QAAQ,KAAK,QAAQ,UACnB,UAAU,QAAQ,SAAS,IACvB;EAAE,GAAG;EAAQ;EAAW,UAAU;CAAmB,IACrD,MACN;CACF,OAAO;EAAE,GAAG;EAAS,UAAU,OAAO,QAAQ,QAAQ;EAAG,MAAM,OAAO,QAAQ,IAAI;CAAE;AACtF;;AAGA,SAAgB,aAAa,SAAqB,MAA4B;CAC5E,MAAM,QAAQ,QAAQ,EAAE,EAAE,EAAE,KAAK,KAAK;CACtC,IAAI,EAAE,SAASA,8BAAAA,SACb,MAAM,IAAI,WAAW,yDAAyD;CAEhF,MAAM,WAAW,QAAQ,KAAK,QAAQ,KAAK,SAAS;CACpD,MAAM,YAAY,UAAU,aAAa,aAAa,MAAO,UAAU,aAAa;CACpF,OAAO;EACL,GAAG;EACH,MAAM,CACJ;GACE,OAAA,GAAA,8BAAA,cAAA,CAAoB,IAAI;GACxB,YAAYA,8BAAAA,OAAO,UAAU,KAAA,GAAA,8BAAA,aAAA,CAAiB,IAAI;GAClD;GACA,UAAU;EACZ,CACF;CACF;AACF;;;;ACtFA,MAAa,oBAAA,GAAA,eAAA,sBAAA,CAAgE,eAAe;CAC1F,MAAM;CAGN,UAAU;EACR,cAAc;EACd,UAAU;EACV,WAAW;EACX,SAAS;EACT,aAAa;EACb,cAAc;EACd,WAAW;EACX,YAAY;EACZ,mBAAmB;CACrB;AACF,CAAC;;;;AC0CD,MAAa,uBAA4C;CACvD,cAAc;CACd,SAAS;AACX;;;;;;AA0BA,MAAa,gBAA2B,OAAO,OAAO;CACpD,SAAS;CACT,QAAQ;CACR,OAAO;CACP,YAAY;AACd,CAAC;;;;;AAMD,MAAa,aAAqC,OAAO,OAAO,EAAE,aAAa,gBAAgB,CAAC"}
|