@orbat-mapper/control-measures 0.2.0-alpha.3 → 0.2.0-alpha.30

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 (87) hide show
  1. package/README.md +55 -3
  2. package/dist/index-DmAFButD.d.mts +2930 -0
  3. package/dist/index.d.mts +2 -2
  4. package/dist/index.mjs +38 -8
  5. package/dist/preview/index.d.mts +110 -3
  6. package/dist/preview/index.mjs +235 -21
  7. package/dist/renderControlMeasure-CzhJJJHO.mjs +12587 -0
  8. package/media/airborne-attack.svg +1 -1
  9. package/media/airfield-zone.svg +1 -0
  10. package/media/ambush.svg +1 -1
  11. package/media/antitank-ditch-completed.svg +1 -1
  12. package/media/antitank-ditch-under-construction.svg +1 -1
  13. package/media/antitank-wall.svg +1 -1
  14. package/media/area-defense.svg +1 -0
  15. package/media/area-of-operations.svg +1 -0
  16. package/media/area.svg +1 -0
  17. package/media/assault-position.svg +1 -0
  18. package/media/assembly-area.svg +1 -0
  19. package/media/attack-by-fire.svg +1 -1
  20. package/media/attack-helicopter.svg +1 -1
  21. package/media/attack-position.svg +1 -0
  22. package/media/base-camp.svg +1 -0
  23. package/media/battle-handover-line.svg +1 -0
  24. package/media/battle-position.svg +1 -1
  25. package/media/block-arrow.svg +1 -1
  26. package/media/block-mission-task.svg +1 -1
  27. package/media/block.svg +1 -1
  28. package/media/boundary.svg +1 -1
  29. package/media/breach.svg +1 -1
  30. package/media/bypass.svg +1 -1
  31. package/media/canalize.svg +1 -1
  32. package/media/circle.svg +1 -0
  33. package/media/classic-arrow.svg +1 -1
  34. package/media/clear.svg +1 -1
  35. package/media/cover.svg +1 -0
  36. package/media/delay.svg +1 -1
  37. package/media/direction-of-attack-aviation.svg +1 -0
  38. package/media/direction-of-main-attack.svg +1 -0
  39. package/media/direction-of-supporting-attack.svg +1 -0
  40. package/media/disrupt.svg +1 -1
  41. package/media/drop-zone.svg +1 -0
  42. package/media/encirclement.svg +1 -0
  43. package/media/engineer-work-line.svg +1 -0
  44. package/media/extraction-zone.svg +1 -0
  45. package/media/final-protective-fire-left.svg +1 -1
  46. package/media/final-protective-fire-right.svg +1 -1
  47. package/media/fix.svg +1 -1
  48. package/media/flot.svg +1 -1
  49. package/media/fortified-area.svg +1 -1
  50. package/media/fortified-line.svg +1 -1
  51. package/media/frontal-attack.svg +1 -0
  52. package/media/generic-c2-area.svg +1 -0
  53. package/media/generic-c2-line.svg +1 -0
  54. package/media/guard.svg +1 -0
  55. package/media/guerrilla-base.svg +1 -0
  56. package/media/handover-line.svg +1 -0
  57. package/media/isolate.svg +1 -1
  58. package/media/joint-tactical-action-area.svg +1 -0
  59. package/media/landing-zone.svg +1 -0
  60. package/media/light-line.svg +1 -0
  61. package/media/limited-access-area.svg +1 -0
  62. package/media/line.svg +1 -0
  63. package/media/main-attack.svg +1 -1
  64. package/media/named-area-of-interest.svg +1 -0
  65. package/media/no-fire-area-irregular.svg +1 -0
  66. package/media/objective-area.svg +1 -0
  67. package/media/obstacle-bypass-difficult.svg +1 -1
  68. package/media/obstacle-bypass-easy.svg +1 -1
  69. package/media/obstacle-bypass-impossible.svg +1 -1
  70. package/media/phase-line.svg +1 -0
  71. package/media/pickup-zone.svg +1 -0
  72. package/media/polygon.svg +1 -0
  73. package/media/principal-direction-of-fire.svg +1 -1
  74. package/media/rectangle.svg +1 -0
  75. package/media/screen.svg +1 -0
  76. package/media/search-area.svg +1 -1
  77. package/media/strong-point.svg +1 -0
  78. package/media/submarine-action-area.svg +1 -0
  79. package/media/submarine-generated-action-area.svg +1 -0
  80. package/media/support-by-fire.svg +1 -1
  81. package/media/supporting-attack.svg +1 -1
  82. package/media/target-area-of-interest.svg +1 -0
  83. package/media/turn.svg +1 -1
  84. package/media/turning-movement.svg +1 -0
  85. package/package.json +1 -1
  86. package/dist/index-BJYbQlzo.d.mts +0 -1713
  87. package/dist/renderControlMeasure-DkXDSrLz.mjs +0 -6877
@@ -0,0 +1,2930 @@
1
+ import { Feature, FeatureCollection, Geometry, LineString, MultiLineString, MultiPolygon, Point, Polygon, Position } from "geojson";
2
+
3
+ //#region src/internal/api-utils.d.ts
4
+ type ValidationMode = "silent" | "warn" | "throw";
5
+ //#endregion
6
+ //#region src/draw-rules/types.d.ts
7
+ interface AnchorTransformEvent {
8
+ previous: readonly Position[];
9
+ next: readonly Position[];
10
+ activePointIndex?: number;
11
+ }
12
+ interface ControlMeasureDrawRule {
13
+ readonly id: string;
14
+ readonly minimumUserPoints: number;
15
+ readonly canonicalPointCount?: number;
16
+ /**
17
+ * Number of raw (clicked + rubber-band) points at which `derive` can already
18
+ * produce a renderable canonical shape, so the draw controller renders a live
19
+ * symbol preview instead of the bare vertex-marker outline. Lets a measure
20
+ * show feedback before the full `minimumUserPoints` commit threshold is
21
+ * reached — e.g. Area21 pads two points (first click + cursor) up to its
22
+ * three-point search-area shape. Must be <= `minimumUserPoints`. Defaults to
23
+ * `minimumUserPoints` (no early preview).
24
+ */
25
+ readonly minimumPreviewPoints?: number;
26
+ /**
27
+ * Opt a fixed-length draw into the standard dashed interaction guide. Fixed
28
+ * shapes suppress guides by default because their generator preview is
29
+ * normally sufficient. Use this when the guide communicates an incomplete
30
+ * construction state, such as Rectangle's P1-P2 baseline.
31
+ */
32
+ readonly showGuide?: boolean;
33
+ /**
34
+ * Convert raw draw points into the spine rendered by the interaction guide.
35
+ * Defaults to the raw points. A rule may return the first point again at the
36
+ * end when it needs to provide its own closed guide geometry.
37
+ */
38
+ guidePoints?(points: readonly Position[]): Position[];
39
+ /**
40
+ * Number of trailing slots in the canonical control-point array that are
41
+ * NOT user-clicked spine vertices. For Axis1, this is 1 (the width handle
42
+ * at index N-1). Drives four behaviors in TacticalDraw:
43
+ * 1. New clicks insert at `length - trailingFixedSlots` (not appended).
44
+ * 2. Midpoint handles render only between segments inside
45
+ * [0 .. length - 1 - trailingFixedSlots].
46
+ * 3. The "click the last added point to commit" hit test uses
47
+ * `committed[length - 1 - trailingFixedSlots]`.
48
+ * 4. `canCommit` evaluates `length - trailingFixedSlots >= minimumUserPoints`.
49
+ * Defaults to 0 (the entire array is user-clicked spine). See ADR-0008.
50
+ */
51
+ readonly trailingFixedSlots?: number;
52
+ /**
53
+ * The user-spine points form a closed ring even though the first point is not
54
+ * duplicated at the end. TacticalDraw uses this to treat the last→first edge
55
+ * like every other edge for completion and midpoint insertion.
56
+ */
57
+ readonly closedRing?: boolean;
58
+ derive(points: readonly Position[]): Position[];
59
+ transform(event: AnchorTransformEvent): Position[];
60
+ }
61
+ //#endregion
62
+ //#region src/text-amplifiers.d.ts
63
+ /**
64
+ * MIL-STD-2525E Appendix L Table L-II text amplifier fields.
65
+ *
66
+ * A control measure instance carries free-text amplifier fields (unique
67
+ * designation, country, date-time group, …) keyed by their doctrinal field
68
+ * code. Repeated fields use numbered suffixes per the standard (`T`, `T1`,
69
+ * `AS1`, `W1`, …). Graphic amplifiers (echelon `B`, direction of movement `Q`,
70
+ * offset location `BA`) are deliberately excluded — they are geometry
71
+ * concerns, rendered from generator options rather than free text.
72
+ *
73
+ * This module is a leaf: it imports nothing from `./metadata` or
74
+ * `./registry`, so both can depend on it without a cycle.
75
+ */
76
+ type Suffix = "" | "1" | "2";
77
+ /** Doctrinal text amplifier field codes (Table L-II); graphic amplifier fields excluded. */
78
+ type TextAmplifierField = "C" | "H" | "N" | "T" | "V" | "W" | "X" | "Y" | "AM" | "AN" | "AP" | "AS";
79
+ /** A doctrinal field code with its optional repetition suffix, e.g. `"T1"`. */
80
+ type TextAmplifierKey = `${TextAmplifierField}${Suffix}`;
81
+ /**
82
+ * The vocabulary of text amplifier fields: doctrinal code, milsymbol-style
83
+ * friendly alias, and a human-readable label. The single source of truth for
84
+ * both the runtime catalog and the derived alias→code lookup used by
85
+ * {@link normalizeTextAmplifiers}.
86
+ */
87
+ declare const TEXT_AMPLIFIER_FIELDS: {
88
+ readonly C: {
89
+ readonly alias: "quantity";
90
+ readonly label: "Quantity";
91
+ };
92
+ readonly H: {
93
+ readonly alias: "additionalInformation";
94
+ readonly label: "Additional information";
95
+ };
96
+ readonly N: {
97
+ readonly alias: "hostile";
98
+ readonly label: "Hostile (ENY) marker";
99
+ };
100
+ readonly T: {
101
+ readonly alias: "uniqueDesignation";
102
+ readonly label: "Unique designation";
103
+ };
104
+ readonly V: {
105
+ readonly alias: "type";
106
+ readonly label: "Equipment/type";
107
+ };
108
+ readonly W: {
109
+ readonly alias: "dtg";
110
+ readonly label: "Date-time group / O/O";
111
+ };
112
+ readonly X: {
113
+ readonly alias: "altitudeDepth";
114
+ readonly label: "Altitude/depth";
115
+ };
116
+ readonly Y: {
117
+ readonly alias: "location";
118
+ readonly label: "Location";
119
+ };
120
+ readonly AM: {
121
+ readonly alias: "distance";
122
+ readonly label: "Distance/range/radius";
123
+ };
124
+ readonly AN: {
125
+ readonly alias: "azimuth";
126
+ readonly label: "Azimuth";
127
+ };
128
+ readonly AP: {
129
+ readonly alias: "targetNumber";
130
+ readonly label: "Target number";
131
+ };
132
+ readonly AS: {
133
+ readonly alias: "country";
134
+ readonly label: "Country code";
135
+ };
136
+ };
137
+ /** The milsymbol-style friendly alias for a text amplifier field, e.g. `"uniqueDesignation"`. */
138
+ type FriendlyName = (typeof TEXT_AMPLIFIER_FIELDS)[TextAmplifierField]["alias"];
139
+ /** A friendly alias with its optional repetition suffix, e.g. `"country1"`. */
140
+ type FriendlyKey = `${FriendlyName}${Suffix}`;
141
+ /**
142
+ * User-facing amplifier input: either canonical doctrinal keys (`T`, `AS1`,
143
+ * …) or friendly aliases (`uniqueDesignation`, `country1`, …), optionally
144
+ * mixed. Values are free text; see {@link normalizeTextAmplifiers} for how
145
+ * this is resolved to canonical form.
146
+ */
147
+ type TextAmplifiers = Partial<Record<TextAmplifierKey | FriendlyKey, string>>;
148
+ /**
149
+ * Stable key for a non-amplifier generated label. The renderer assigns these
150
+ * from the label's part and per-part label ordinal when a generator has not
151
+ * supplied a doctrinal field key. Generators that can change a label's order
152
+ * should supply an explicit `labelPlacementKey` instead.
153
+ */
154
+ type GeneratedLabelKey = `label:${string}`;
155
+ /**
156
+ * Object form of a per-label override. `rotation` is in stored radians — the
157
+ * same convention as `FeaturePartProps.rotation` (adapters render the
158
+ * on-screen angle as `π − rotation`).
159
+ */
160
+ interface LabelPlacementOverride {
161
+ position?: Position;
162
+ rotation?: number;
163
+ }
164
+ /** A per-label override: a bare anchor (legacy shorthand) or the object form. */
165
+ type AmplifierPlacement = Position | LabelPlacementOverride;
166
+ /**
167
+ * User-adjusted anchor positions (and, optionally, rotations) for doctrinal
168
+ * and generated text labels, keyed by a canonical `TextAmplifierKey` or a
169
+ * synthesized `GeneratedLabelKey`.
170
+ */
171
+ type AmplifierPlacements = Record<string, AmplifierPlacement | undefined>;
172
+ /**
173
+ * Resolves a raw placement entry to its object form: a bare `Position` is
174
+ * legacy shorthand for `{ position }`; an object form passes through only the
175
+ * fields that are actually valid (`position` must be a finite `[lon, lat]`,
176
+ * `rotation` a finite number); `undefined` resolves to `{}`.
177
+ */
178
+ declare function resolveAmplifierPlacement(value: AmplifierPlacement | undefined): LabelPlacementOverride;
179
+ /** Amplifier values resolved to canonical doctrinal keys, as generators receive them. */
180
+ type CanonicalTextAmplifiers = Readonly<Partial<Record<TextAmplifierKey, string>>>;
181
+ /**
182
+ * Resolves any accepted key (canonical or friendly alias, with an optional
183
+ * `1`/`2` suffix) to its canonical key, or `undefined` if unknown — e.g.
184
+ * `"T"` → `"T"`, `"uniqueDesignation1"` → `"T1"`, `"bogus"` → `undefined`.
185
+ */
186
+ declare function canonicalTextAmplifierKey(key: string): TextAmplifierKey | undefined;
187
+ /**
188
+ * Resolves a `TextAmplifiers` record (canonical keys, friendly aliases, or a
189
+ * mix) to `CanonicalTextAmplifiers` keyed purely by doctrinal field code.
190
+ *
191
+ * - Friendly aliases (with an optional `1`/`2` suffix) map to their canonical
192
+ * code (e.g. `country1` → `AS1`).
193
+ * - Values are trimmed; entries that are empty/whitespace-only after
194
+ * trimming, or not strings, are dropped.
195
+ * - When both a canonical key and its friendly alias are present for the same
196
+ * field + suffix, the **canonical key wins** regardless of insertion order.
197
+ * This holds even for an empty/whitespace canonical value: it suppresses
198
+ * (clears) the alias entry rather than letting the alias survive.
199
+ * - Unknown keys are ignored.
200
+ *
201
+ * `undefined` or an empty input returns a shared frozen empty object.
202
+ */
203
+ declare function normalizeTextAmplifiers(input: TextAmplifiers | undefined): CanonicalTextAmplifiers;
204
+ //#endregion
205
+ //#region src/metadata.d.ts
206
+ type ControlMeasureGeometryType = Geometry["type"];
207
+ type ControlMeasureGeometry = "point" | "line" | "area";
208
+ declare const DRAW_RULE_IDS: readonly ["Area1", "Area7", "Area8", "Area11", "Area12", "Area15", "Area21", "Axis1", "Line1", "Line3", "Line9", "Line10", "Line23", "Line24", "Line26", "Line29", "Point1", "Point12", "Rectangle"];
209
+ type DrawRuleId = (typeof DRAW_RULE_IDS)[number];
210
+ interface BaseParamDescriptor {
211
+ key: string;
212
+ label: string;
213
+ description?: string;
214
+ visibleWhen?: (opts: Record<string, unknown>) => boolean;
215
+ }
216
+ interface NumberParamDescriptor extends BaseParamDescriptor {
217
+ type: "number";
218
+ min?: number;
219
+ max?: number;
220
+ step?: number;
221
+ unit?: string;
222
+ }
223
+ interface BooleanParamDescriptor extends BaseParamDescriptor {
224
+ type: "boolean";
225
+ }
226
+ interface ColorParamDescriptor extends BaseParamDescriptor {
227
+ type: "color";
228
+ }
229
+ interface EnumParamDescriptor extends BaseParamDescriptor {
230
+ type: "enum";
231
+ options: readonly {
232
+ label: string;
233
+ value: string | number | boolean;
234
+ }[];
235
+ }
236
+ interface TextParamDescriptor extends BaseParamDescriptor {
237
+ type: "text";
238
+ placeholder?: string;
239
+ maxLength?: number;
240
+ /**
241
+ * The doctrinal Table L-II field this free-text option renders (e.g.
242
+ * `phaseLineName` renders field `T`) — lets metadata-driven UIs (e.g. a
243
+ * label-placement preview) substitute a `<T>`-style placeholder for the
244
+ * option, the same way a `TextAmplifierDescriptor` does for a real
245
+ * amplifier field.
246
+ */
247
+ field?: TextAmplifierField;
248
+ /**
249
+ * Whether the value may contain explicit line breaks that a metadata-driven
250
+ * editor should let the user enter directly (a multi-row textarea rather
251
+ * than a single-line input), e.g. the generic Text measure's `text` option.
252
+ */
253
+ multiline?: boolean;
254
+ }
255
+ type ParamDescriptor = NumberParamDescriptor | BooleanParamDescriptor | ColorParamDescriptor | TextParamDescriptor | EnumParamDescriptor;
256
+ /** Editor-facing description of one text amplifier field a measure accepts. */
257
+ interface TextAmplifierDescriptor {
258
+ key: TextAmplifierKey;
259
+ label: string;
260
+ description?: string;
261
+ placeholder?: string;
262
+ /** Editor hint only — the renderer never truncates the value. */
263
+ maxLength?: number;
264
+ }
265
+ interface ControlMeasureMetadata {
266
+ id: string;
267
+ name: string;
268
+ description: string;
269
+ entity: string;
270
+ entityType: string;
271
+ entitySubtype?: string;
272
+ value: string;
273
+ geometry: ControlMeasureGeometry;
274
+ minCoordinates?: number;
275
+ maxCoordinates?: number;
276
+ geometryTypes?: readonly ControlMeasureGeometryType[];
277
+ drawRule?: DrawRuleId;
278
+ /**
279
+ * Resolved draw rule object (anchor contract) attached by the registry when
280
+ * the kind's `drawRule` id has an implementation. Consumed by the
281
+ * `TacticalDraw` façade to drive click accumulation during draw and
282
+ * vertex-snap during edit — see ADR-0005.
283
+ */
284
+ rule?: ControlMeasureDrawRule;
285
+ params?: readonly ParamDescriptor[];
286
+ /** Text amplifier fields (MIL-STD-2525E Appendix L Table L-II) this measure accepts. */
287
+ textAmplifiers?: readonly TextAmplifierDescriptor[];
288
+ /**
289
+ * Marks a measure that emits a text label whose pixel size should be captured
290
+ * once at draw-commit time (rather than re-resolved on every zoom). Hosts use
291
+ * this to stamp default label sizing onto the committed measure — see
292
+ * `withCommittedAdapterMeasureOptions` in `tactical-draw`. Keeping it on the
293
+ * definition means adding such a measure stays a one-file change (ADR-0013).
294
+ */
295
+ capturesLabelSize?: boolean;
296
+ /**
297
+ * Static, per-kind declaration of what a rendered instance can paint — used
298
+ * by a host editor to decide which style controls (stroke color/width,
299
+ * fill toggle/pattern/color, text color) are meaningful to show for this
300
+ * kind. It describes the *kind*, not a particular instance: a `filled`
301
+ * boolean option still governs whether any given instance is actually
302
+ * filled, this only says whether fill control is meaningful at all.
303
+ */
304
+ paints: ControlMeasurePaintCapability;
305
+ }
306
+ /**
307
+ * A control measure's fill capability, per {@link ControlMeasurePaintCapability.fill}.
308
+ *
309
+ * - `"none"` — no emitted part is ever filled; a fill/fillColor/fillPattern
310
+ * control would be inert.
311
+ * - `"fixed"` — a filled part exists, but the generator pins its
312
+ * `fillPattern` (a solid accent like an echelon marker, or a doctrinal
313
+ * hatch like Limited Access Area's back-hatch) — `cm.style.fillPattern`
314
+ * never reaches it. `fillColor` is *not* pinned, so a fill color override
315
+ * still reaches the part; only the pattern control is inert.
316
+ * - `"user"` — a filled part exists whose pattern the generator leaves
317
+ * unset, so `cm.style.fillPattern` reaches the output. These are exactly
318
+ * the kinds governed by a `filled` boolean {@link ParamDescriptor}
319
+ * (polygon, rectangle, circle, block-arrow).
320
+ */
321
+ type ControlMeasureFillCapability = "none" | "fixed" | "user";
322
+ /** What a rendered control-measure kind can paint — see {@link ControlMeasureMetadata.paints}. */
323
+ interface ControlMeasurePaintCapability {
324
+ /** Whether any emitted part is stroked (non-Point) geometry — gates a stroke color/width control. */
325
+ stroke: boolean;
326
+ /** Whether/how any emitted part is filled — see {@link ControlMeasureFillCapability}. */
327
+ fill: ControlMeasureFillCapability;
328
+ /** Whether the kind emits text label features — gates a text color control. */
329
+ text: boolean;
330
+ }
331
+ //#endregion
332
+ //#region src/define.d.ts
333
+ /**
334
+ * The loosest `FeatureCollection` a control-measure generator may emit: any
335
+ * geometry, with per-feature properties that the renderer normalizes.
336
+ */
337
+ type AnyFeatureCollection = FeatureCollection<Geometry, Record<string, unknown> | null>;
338
+ /** Read-only instance state that can affect generated geometry. */
339
+ interface ControlMeasureGeneratorContext {
340
+ amplifierPlacements?: AmplifierPlacements;
341
+ }
342
+ /**
343
+ * A generator's call signature, constrained only by its inputs and output. The
344
+ * options parameter is typed `never` so that a generator with *any* concrete
345
+ * options type satisfies the bound — function parameters are contravariant, so
346
+ * `(o: BlockOptions) => …` is assignable to `(o: never) => …`. The actual
347
+ * options type is recovered covariantly via {@link OptsOf}, never through this
348
+ * bound. See ADR-0013.
349
+ *
350
+ * The optional third parameter carries the instance's normalized text
351
+ * amplifiers (ADR-0027); a generator that ignores text amplifiers just omits
352
+ * the parameter. The optional fourth parameter carries instance state needed
353
+ * while generating geometry derived from an individual label placement.
354
+ * Generators may omit either trailing parameter.
355
+ */
356
+ type ControlMeasureGenerator = (controlPoints: Position[], options: never, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext) => AnyFeatureCollection;
357
+ /**
358
+ * Everything that defines one control measure, co-located with its generator.
359
+ * `registry.ts` collects these into the single `DEFINITIONS` map, from which
360
+ * the `ControlMeasureId` union, `OptionsByKind`, the generator dispatch, the
361
+ * default options, and rule resolution are all derived rather than maintained
362
+ * as parallel tables. See ADR-0013.
363
+ */
364
+ interface ControlMeasureDefinition<Id extends string, G extends ControlMeasureGenerator> {
365
+ /** Catalog metadata; `id` is pinned to the record's literal key. */
366
+ metadata: ControlMeasureMetadata & {
367
+ id: Id;
368
+ };
369
+ /** Pure generator: control points (+ options) → GeoJSON features. */
370
+ generator: G;
371
+ /** Default options, tied to the generator's own options parameter. */
372
+ defaultOptions: NonNullable<Parameters<G>[1]>;
373
+ /**
374
+ * Resolved draw-rule object, merged back onto metadata by the registry. The
375
+ * doctrinal `drawRule` spec id stays on `metadata` (ADR-0005); the registry
376
+ * guards that `rule` agrees with it. See ADR-0013.
377
+ */
378
+ rule?: ControlMeasureDrawRule;
379
+ /**
380
+ * Representative sample used only by the static catalog/thumbnail previews
381
+ * (the `/preview` subpath). Most measures omit it and fall back to a generic
382
+ * layout keyed off `geometry`/`minCoordinates`/`entityType`; a measure whose
383
+ * symbol needs special framing co-locates the override here rather than in a
384
+ * central per-id switch. Points are **unitless** (~`[-1, 1]`); the resolver
385
+ * scales them to the small degree offsets the projected-meter generators
386
+ * expect. `options` is type-checked against this measure's own options. See
387
+ * ADR-0025.
388
+ */
389
+ previewSample?: PreviewSample<NonNullable<Parameters<G>[1]>>;
390
+ /**
391
+ * Pins orientation-derived defaults — options whose default value depends on
392
+ * the shape's current screen orientation (e.g. Battle Position's echelon
393
+ * anchor, which defaults to the bottom edge) — to their current concrete
394
+ * values. Returns an options patch to merge onto the working options, or
395
+ * `undefined` when there is nothing to freeze (already frozen, or nothing
396
+ * visible to pin). Called by edit hosts when a rotate gesture starts, so a
397
+ * subsequent rigid rotation of the control points preserves the rendered
398
+ * appearance instead of an orientation-relative default silently re-deriving
399
+ * against the new orientation. See ADR-0023.
400
+ */
401
+ freezeOrientation?: (controlPoints: Position[], options: NonNullable<Parameters<G>[1]>) => Partial<NonNullable<Parameters<G>[1]>> | undefined;
402
+ /**
403
+ * Folds a box transform gesture's screen-space delta into option values for a
404
+ * graphic that persists orientation and/or size as options rather than in its
405
+ * geometry — single-point graphics (e.g. Text) have no geometry to encode
406
+ * them. Returns an options patch to merge onto the working options, or
407
+ * `undefined` when the kind carries no such option (or the delta is inert).
408
+ * Edit hosts call this at a rotate/scale gesture's commit, alongside the rigid
409
+ * transform of the control points, so the persisted rotation/size follow the
410
+ * box. The measure owns the unit/sign conversion (e.g. Text stores degrees
411
+ * clockwise-on-screen while the delta is radians). See ADR-0017/0023.
412
+ */
413
+ transformOptions?: (options: NonNullable<Parameters<G>[1]>, delta: BoxTransformDelta) => Partial<NonNullable<Parameters<G>[1]>> | undefined;
414
+ }
415
+ /**
416
+ * A box transform gesture's screen-space delta, folded into orientation- and
417
+ * size-carrying options by {@link ControlMeasureDefinition.transformOptions}.
418
+ * The transform box (ADR-0017) is the source: `scale` is the uniform corner
419
+ * -scale factor (`1` = no scaling), `rotationRadians` the rotate-grip delta
420
+ * (positive = clockwise on screen, matching the box angle convention; `0` = no
421
+ * rotation). A body translate reports neither (`{ scale: 1, rotationRadians: 0 }`).
422
+ */
423
+ interface BoxTransformDelta {
424
+ scale: number;
425
+ rotationRadians: number;
426
+ }
427
+ /**
428
+ * A measure's representative preview input. Shared between the typed
429
+ * {@link ControlMeasureDefinition} field and the erased
430
+ * {@link AnyControlMeasureDefinition}; `Options` is the measure's own options
431
+ * type (or `unknown` once erased). See ADR-0025.
432
+ */
433
+ interface PreviewSample<Options> {
434
+ controlPoints: readonly (readonly [number, number])[];
435
+ options?: Partial<Options>;
436
+ /**
437
+ * Sample text amplifiers (ADR-0027) rendered onto the representative
438
+ * preview, for measures whose doctrinal appearance is carried by amplifier
439
+ * text (e.g. Boundary-style end/center labels) rather than options alone.
440
+ */
441
+ textAmplifiers?: TextAmplifiers;
442
+ }
443
+ /**
444
+ * Extracts a definition's options type covariantly from its generator's
445
+ * (optional) second parameter — robust where inferring through the
446
+ * contravariant parameter position is not. See ADR-0013.
447
+ */
448
+ type OptsOf<D> = D extends {
449
+ generator: (points: Position[], options?: infer O) => unknown;
450
+ } ? O : never;
451
+ //#endregion
452
+ //#region src/generators/cm11-command-control-lines/boundary.d.ts
453
+ /** Configuration options for the Boundary control measure. */
454
+ interface BoundaryOptions {
455
+ /**
456
+ * Field B echelon. One of the keys in {@link ECHELONS} (e.g. `"battalion"`,
457
+ * `"division"`) or an equivalent symbol form (`"II"`, `"XX"`). `"none"`,
458
+ * empty, or unknown renders no glyph and leaves the line continuous.
459
+ * @default "battalion"
460
+ */
461
+ echelon?: string;
462
+ /**
463
+ * Echelon glyph height in meters (ground-anchored). Ignored when
464
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
465
+ * @default 750
466
+ */
467
+ echelonSize?: number;
468
+ /**
469
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to meters
470
+ * against `metersPerPixel`; bakes to a meter size on draw/edit commit
471
+ * (ADR-0020).
472
+ * @default 16
473
+ */
474
+ echelonSizePixels?: number;
475
+ /**
476
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph height.
477
+ * `0` butts the line against the glyph; larger values widen the break.
478
+ * @default 0.3
479
+ */
480
+ echelonPadding?: number;
481
+ /**
482
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when the
483
+ * measure is screen-anchored; required to resolve `echelonSizePixels` and to
484
+ * lock the T/AS text size to the glyph height.
485
+ */
486
+ metersPerPixel?: number;
487
+ /**
488
+ * Number of label groups (echelon + designators), spaced evenly by cumulative
489
+ * arc length along the whole boundary. `1` places a single group at
490
+ * `labelPosition`, whose default is the midpoint of the total length.
491
+ * @default 1
492
+ */
493
+ labelRepetitions?: number;
494
+ /**
495
+ * Spacing between label groups when `labelRepetitions > 1`, relative to an even
496
+ * spread across the whole boundary. `1` spreads them evenly end-to-end; `<1`
497
+ * clusters them toward the midpoint; `>1` pushes them toward the ends
498
+ * (clamped to the boundary). No effect for a single group.
499
+ * @default 1
500
+ */
501
+ labelSpacing?: number;
502
+ /**
503
+ * Position of a single label group as a fraction of cumulative arc length
504
+ * from the boundary's first control point (0) to its last (1). Ignored when
505
+ * `labelRepetitions > 1`.
506
+ * @default 0.5
507
+ */
508
+ labelPosition?: number;
509
+ /**
510
+ * Clearance between the line/echelon glyph and the unit labels, as a ratio
511
+ * of the echelon glyph height (like `echelonPadding`). In `"along"` mode
512
+ * (and on `"standard"` east–west segments) it grows the labels'
513
+ * perpendicular offset from the line; in a `"standard"` north–south crossing
514
+ * row it grows each label's gap to the echelon glyph. Negative values clamp
515
+ * to 0.
516
+ * @default 0.4
517
+ */
518
+ labelPadding?: number;
519
+ /**
520
+ * How the T/AS unit labels and the echelon glyph are oriented:
521
+ *
522
+ * - `"along"` — text runs along the line, offset perpendicular to it, and
523
+ * the echelon glyph turns with the segment (the default).
524
+ * - `"standard"` — MIL-STD-2525E Appendix L §L.5.5.2 / Figure L-10
525
+ * placement. On mostly east–west segments this reads exactly like
526
+ * `"along"`. On mostly north–south segments the whole group rotates to run
527
+ * *perpendicular* to the line instead: a single row of
528
+ * `<unit 1> <echelon> <unit 2>` crossing it (unit 1 on its left-of-travel
529
+ * side), each label aligned away from the glyph so long designations never
530
+ * overlap the line.
531
+ * @default "along"
532
+ */
533
+ labelOrientation?: "along" | "standard";
534
+ /**
535
+ * Round the boundary's corners by curving it through the control points
536
+ * (centripetal Catmull-Rom spline). The spline preserves the endpoints, so
537
+ * the line still meets its drawn anchors.
538
+ * @default false
539
+ */
540
+ smooth?: boolean;
541
+ /**
542
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
543
+ * a denser, smoother curve.
544
+ * @default 12
545
+ */
546
+ smoothResolution?: number;
547
+ }
548
+ /** Default options for the Boundary control measure. */
549
+ declare const DEFAULT_BOUNDARY_OPTIONS: BoundaryOptions;
550
+ /**
551
+ * Creates a Boundary control measure: a polyline through `positions` carrying
552
+ * repeated echelon + unit-designator labels.
553
+ *
554
+ * @param positions - Boundary anchor points (≥2); the input contract is
555
+ * enforced at the render seam (ADR-0014).
556
+ * @param options - {@link BoundaryOptions}.
557
+ * @param textAmplifiers - Normalized text amplifiers (ADR-0027): `T`/`AS` label
558
+ * unit 1 (left-of-travel side), `T1`/`AS1` label unit 2 (right-of-travel side).
559
+ */
560
+ declare function createBoundary(positions: Position[], options?: BoundaryOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | MultiPolygon | Point>;
561
+ //#endregion
562
+ //#region src/projection.d.ts
563
+ type Point2D = [number, number];
564
+ /**
565
+ * Project WGS84 (Lon/Lat) to Web Mercator (Meters).
566
+ */
567
+ declare const project: (lon: number, lat: number) => Point2D;
568
+ /**
569
+ * Unproject Web Mercator (Meters) back to WGS84 (Lon/Lat).
570
+ */
571
+ declare const unproject: (x: number, y: number) => Position;
572
+ /**
573
+ * Great-circle distance in meters between two lon/lat positions (haversine on
574
+ * the WGS84 mean-radius sphere). Accurate at all scales — use this for
575
+ * measurement readouts (segment lengths, radii). Most generators still build
576
+ * geometry in projected Web Mercator meters, so at high latitudes a graphic's
577
+ * Mercator dimensions can exceed the true ground distance this returns; the
578
+ * generic circle is the exception — it samples at constant geodesic radius,
579
+ * so its ring and this readout agree exactly.
580
+ */
581
+ declare const haversineDistance: (a: Position, b: Position) => number;
582
+ //#endregion
583
+ //#region src/internal/sketch.d.ts
584
+ /**
585
+ * Shared `smooth`/`smoothResolution` option pair for free n-point polyline
586
+ * measures (draw rule Line1): curves the rendered path through the control
587
+ * points via a centripetal Catmull-Rom spline. The spline preserves the
588
+ * endpoints, so the line still meets its drawn anchors, and is a no-op for
589
+ * fewer than three control points (a single segment cannot be smoothed).
590
+ */
591
+ interface SmoothLineOptions {
592
+ /**
593
+ * Round the line's corners by curving the path through the control points
594
+ * (centripetal Catmull-Rom spline). The spline preserves the endpoints, so
595
+ * the line still meets its drawn anchors.
596
+ * @default false
597
+ */
598
+ smooth?: boolean;
599
+ /**
600
+ * Number of samples per segment when `smooth` is enabled. Higher values
601
+ * yield a denser, smoother curve.
602
+ * @default (varies per measure)
603
+ */
604
+ smoothResolution?: number;
605
+ }
606
+ //#endregion
607
+ //#region src/internal/line-labels.d.ts
608
+ /**
609
+ * Label sizing per the size-anchor model (ADR-0020, ADR-0028): the presence of
610
+ * `labelSizePixels` marks the labels screen-anchored; `labelSize` alone is
611
+ * ground-anchored. Carrying both behaves screen-anchored (pixels win),
612
+ * matching the geometry options' precedence.
613
+ */
614
+ interface LabelSizeOptions {
615
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
616
+ labelSize?: number;
617
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
618
+ labelSizePixels?: number;
619
+ /**
620
+ * Meters-per-pixel at the current view. Stamped by the host when the labels
621
+ * are screen-anchored; resolves `labelSizePixels` to the projected-meter
622
+ * height that meter-denominated placement (offsets, gaps, row pitch) needs.
623
+ */
624
+ metersPerPixel?: number;
625
+ }
626
+ /** Shared placement options for the fixed-end-label line measures. */
627
+ interface LineLabelOptions extends LabelSizeOptions {
628
+ /**
629
+ * Extra clearance between the line and its labels, as a ratio of the
630
+ * label's resolved text height (`labelSize`, or `labelSizePixels ×
631
+ * metersPerPixel`), like Boundary's `labelPadding`. Negative values clamp
632
+ * to 0. Only effective when a label size resolves — the no-size fallback
633
+ * offset is a fixed meter value, unaffected by this ratio.
634
+ * @default 0
635
+ */
636
+ labelPadding?: number;
637
+ }
638
+ //#endregion
639
+ //#region src/generators/cm11-command-control-lines/light-line.d.ts
640
+ /** Configuration options for the Light line control measure. */
641
+ interface LightLineOptions extends LineLabelOptions, SmoothLineOptions {
642
+ /**
643
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
644
+ * the line, additive to the fixed "LL" labels. Empty or whitespace-only
645
+ * renders no label.
646
+ * @default none
647
+ */
648
+ phaseLineName?: string;
649
+ /**
650
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
651
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
652
+ * Phase Line itself, this measure already carries its own fixed "LL"
653
+ * label, so there is no bare "PL" fallback.
654
+ * @default true
655
+ */
656
+ includePrefix?: boolean;
657
+ }
658
+ /** Default options for the Light line control measure. */
659
+ declare const DEFAULT_LIGHT_LINE_OPTIONS: LightLineOptions;
660
+ /**
661
+ * Creates a Light line control measure: a polyline through `positions`
662
+ * labeled "LL" above the line near each end.
663
+ */
664
+ declare function createLightLine(positions: Position[], options?: LightLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
665
+ //#endregion
666
+ //#region src/generators/cm11-command-control-lines/engineer-work-line.d.ts
667
+ /** Configuration options for the Engineer work line control measure. */
668
+ interface EngineerWorkLineOptions extends LineLabelOptions, SmoothLineOptions {
669
+ /**
670
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
671
+ * the line, additive to the fixed "EWL" labels. Empty or whitespace-only
672
+ * renders no label.
673
+ * @default none
674
+ */
675
+ phaseLineName?: string;
676
+ /**
677
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
678
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
679
+ * Phase Line itself, this measure already carries its own fixed "EWL"
680
+ * label, so there is no bare "PL" fallback.
681
+ * @default true
682
+ */
683
+ includePrefix?: boolean;
684
+ }
685
+ /** Default options for the Engineer work line control measure. */
686
+ declare const DEFAULT_ENGINEER_WORK_LINE_OPTIONS: EngineerWorkLineOptions;
687
+ /**
688
+ * Creates an Engineer work line control measure: a polyline through
689
+ * `positions` labeled "EWL" above the line near each end, plus one center
690
+ * label group at the midpoint of the total arc length carrying the
691
+ * responsible units' Field T/AS designator+country (left-of-travel side
692
+ * above the line, T1/AS1 below). No center group is emitted when all four
693
+ * amplifiers are empty.
694
+ */
695
+ declare function createEngineerWorkLine(positions: Position[], options?: EngineerWorkLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
696
+ //#endregion
697
+ //#region src/generators/cm11-command-control-lines/generic-c2-line.d.ts
698
+ /** Configuration options for the Generic command and control line. */
699
+ interface GenericC2LineOptions extends LineLabelOptions, SmoothLineOptions {
700
+ /**
701
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
702
+ * the line, additive to the H/T/W/W1 amplifier labels. Empty or
703
+ * whitespace-only renders no label.
704
+ * @default none
705
+ */
706
+ phaseLineName?: string;
707
+ /**
708
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
709
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — this
710
+ * measure already carries its own H/T/W/W1 amplifier labels, so there is
711
+ * no bare "PL" fallback.
712
+ * @default true
713
+ */
714
+ includePrefix?: boolean;
715
+ }
716
+ /** Default options for the Generic command and control line. */
717
+ declare const DEFAULT_GENERIC_C2_LINE_OPTIONS: GenericC2LineOptions;
718
+ /**
719
+ * Creates a Generic command and control line: a polyline through `positions`
720
+ * with optional near-end text — `H`/`T` joined above the line, `W`/`W1`
721
+ * joined as a "from - to" range below it. Both rows share the per-tip
722
+ * placement from {@link import("../../internal/line-labels").aboveEndFrames}
723
+ * (inset from the tip, anchored toward the line's interior), one at
724
+ * `base + perp·offset` and the other at `base − perp·offset`.
725
+ */
726
+ declare function createGenericC2Line(positions: Position[], options?: GenericC2LineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
727
+ //#endregion
728
+ //#region src/style.d.ts
729
+ /**
730
+ * Framework-agnostic style hints attached to a `ControlMeasure`.
731
+ *
732
+ * Mirrors the per-feature subset of what map adapters render. The renderer
733
+ * fans these into each emitted feature's `properties.style` ([[StyleHints]]).
734
+ * Adapters merge them over their layer-level style; generator-emitted hints
735
+ * on individual features win over both.
736
+ */
737
+ interface ControlMeasureStyle {
738
+ /**
739
+ * The single symbol color. Control measures are monocolor: one color paints
740
+ * every part, stroked or filled. Input-only — resolved into concrete
741
+ * `strokeColor` / `fillColor` per feature by the renderer and never emitted
742
+ * on output. `strokeColor` / `fillColor` act as optional per-channel
743
+ * overrides. See ADR-0011.
744
+ */
745
+ color?: string;
746
+ strokeColor?: string;
747
+ strokeWidth?: number;
748
+ strokeDash?: number[];
749
+ fillColor?: string;
750
+ /**
751
+ * How a filled part's interior is painted. `"solid"` is explicit so a
752
+ * measure can override a patterned layer default (e.g. a hatch fill set
753
+ * at the façade). Pattern lines are drawn in the resolved fill color —
754
+ * alpha included, there is no separate opacity field. Renderers that
755
+ * cannot draw a pattern degrade to solid.
756
+ */
757
+ fillPattern?: FillPattern;
758
+ /**
759
+ * Display-time graphic opacity multiplier in `[0, 1]`; absent = fully
760
+ * opaque. Unlike `color`'s alpha, this fades the whole graphic — stroke,
761
+ * fill, patterns, and baked labels — as one knob, independent of the
762
+ * authored color. The resolver folds it into each resolved part's color
763
+ * alpha (`final alpha = opacity × color alpha`) rather than adding a new
764
+ * paint channel, so adapters and `toSimpleStyle` need no changes.
765
+ * Display-only: hit-testing and selection reason about color alpha, not
766
+ * this multiplier, so a graphic at `opacity: 0` stays fully selectable.
767
+ * Out-of-range values clamp to `[0, 1]`. See ADR-0040.
768
+ */
769
+ opacity?: number;
770
+ /**
771
+ * Render a contrast-aware halo behind label glyphs so text stays legible on
772
+ * busy backgrounds. Cascades like any other hint (graphicsStyle → measure →
773
+ * generator), letting a host switch halos on for every labeled measure
774
+ * rather than only the generic Text graphic.
775
+ *
776
+ * Text-only: the renderer applies it to features that carry `text` and drops
777
+ * it everywhere else, so a layer-level `true` never leaks onto plain stroked
778
+ * or filled parts. The halo *color* is not authored here — it is derived per
779
+ * feature from the resolved text color, so each label gets a halo that
780
+ * actually contrasts with it. Unlike the other hints this one is consumed by
781
+ * the renderer and lifted to a top-level `textHalo` feature property; it is
782
+ * never emitted on `properties.style`. See ADR-0042.
783
+ */
784
+ textHalo?: boolean;
785
+ }
786
+ /**
787
+ * How a filled part's interior is painted. See `ControlMeasureStyle.fillPattern`.
788
+ */
789
+ type FillPattern = "solid" | "hatch" | "reverse-hatch" | "cross-hatch" | "horizontal" | "vertical" | "dots";
790
+ //#endregion
791
+ //#region src/internal/area-labels.d.ts
792
+ /** Shared placement options for the centered-label area measures. */
793
+ interface AreaLabelOptions extends LabelSizeOptions {
794
+ /**
795
+ * Extra row leading (and ENY inset), as a ratio of the label's resolved
796
+ * text height, like the labeled line measures' own `labelPadding`.
797
+ * Negative values clamp to 0.
798
+ * @default 0
799
+ */
800
+ labelPadding?: number;
801
+ }
802
+ /** Options for {@link labeledAreaFeatures}: {@link buildClosedRing}'s
803
+ * smoothing knobs plus the shared {@link AreaLabelOptions} label placement. */
804
+ interface LabeledAreaOptions extends AreaLabelOptions {
805
+ /**
806
+ * Round the area's corners by curving the boundary through the control
807
+ * points (closed centripetal Catmull-Rom spline).
808
+ * @default false
809
+ */
810
+ smooth?: boolean;
811
+ /**
812
+ * Number of samples per segment when `smooth` is enabled.
813
+ * @default 16
814
+ */
815
+ smoothResolution?: number;
816
+ }
817
+ //#endregion
818
+ //#region src/generators/cm15-maneuver-areas/battlePosition.d.ts
819
+ /**
820
+ * Configuration options for the Battle Position control measure. Also
821
+ * carries the shared {@link AreaLabelOptions} placement for its centered
822
+ * Field T (designator) label.
823
+ */
824
+ interface BattlePositionOptions extends AreaLabelOptions {
825
+ /**
826
+ * Field B echelon. One of the keys in the echelon vocabulary (e.g.
827
+ * `"battalion"`, `"division"`) or an equivalent symbol form (`"II"`, `"XX"`).
828
+ * `"none"`, empty, or unknown renders no glyph and leaves the boundary
829
+ * continuous.
830
+ * @default "battalion"
831
+ */
832
+ echelon?: string;
833
+ /**
834
+ * Echelon glyph height in meters (ground-anchored). Ignored when
835
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
836
+ * @default 750
837
+ */
838
+ echelonSize?: number;
839
+ /**
840
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to meters
841
+ * against `metersPerPixel`; bakes to a meter size on draw/edit commit
842
+ * (ADR-0020).
843
+ * @default 16
844
+ */
845
+ echelonSizePixels?: number;
846
+ /**
847
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph height.
848
+ * `0` butts the boundary against the glyph; larger values widen the break.
849
+ * @default 0.3
850
+ */
851
+ echelonPadding?: number;
852
+ /**
853
+ * Slides the echelon along the boundary, as a signed fraction of the total
854
+ * perimeter measured from its default anchor on the bottom edge. `0` keeps it
855
+ * centered on the bottom; positive/negative values move it around the ring in
856
+ * either direction (wrapping at the seam).
857
+ * @default 0
858
+ */
859
+ echelonPosition?: number;
860
+ /**
861
+ * Absolute anchor for the echelon glyph, as a fraction of the total
862
+ * perimeter measured from the ring seam (the ring's first vertex), wrapped
863
+ * into `[0, 1)`. When omitted, the anchor is "auto": the bottom edge's
864
+ * midpoint (the side opposite the front), recomputed from the current
865
+ * geometry on every render — the long-standing default behavior.
866
+ * `echelonPosition` still applies on top of this anchor as a signed offset,
867
+ * exactly as it does against the auto anchor.
868
+ *
869
+ * Edit controllers freeze this from "auto" to a concrete fraction the
870
+ * moment a rotate gesture starts (see `freezeEchelonAnchor` /
871
+ * `freezeOrientationOptions`): the transform box rotates only the control
872
+ * points and re-renders, so without a pinned anchor the "bottom edge" would
873
+ * keep re-deriving against the rotated geometry and the glyph would jump to
874
+ * a different edge each time a new edge becomes lowest. Freezing the anchor
875
+ * first makes the rotation rigid — the glyph turns with the shape instead.
876
+ * See ADR-0023.
877
+ */
878
+ echelonAnchor?: number;
879
+ /**
880
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when the
881
+ * measure is screen-anchored; required to resolve `echelonSizePixels`.
882
+ */
883
+ metersPerPixel?: number;
884
+ /**
885
+ * Round the area's corners by curving the boundary through the control points
886
+ * (closed centripetal Catmull-Rom spline), matching the rounded shape in the
887
+ * APP-6 template.
888
+ * @default false
889
+ */
890
+ smooth?: boolean;
891
+ /**
892
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
893
+ * a denser, smoother curve.
894
+ * @default 16
895
+ */
896
+ smoothResolution?: number;
897
+ }
898
+ /** Default options for the Battle Position control measure. */
899
+ declare const DEFAULT_BATTLE_POSITION_OPTIONS: BattlePositionOptions;
900
+ /**
901
+ * Creates a Battle Position control measure: a closed area through `positions`
902
+ * carrying a single echelon (Field B) glyph straddling its boundary — anchored
903
+ * to the bottom edge by default, slidable via `echelonPosition`.
904
+ *
905
+ * @param positions - Area anchor points (≥3); the input contract is enforced at
906
+ * the render seam (ADR-0014).
907
+ * @param options - {@link BattlePositionOptions}.
908
+ * @param textAmplifiers - Field T (designation, centered in the area) plus an
909
+ * optional Field N "ENY" hostile marker at the west/east edges (no H/W rows —
910
+ * this measure's template pairs the designation with the Field B glyph, not
911
+ * the plain L-15 boundary template).
912
+ */
913
+ declare function createBattlePosition(positions: Position[], options?: BattlePositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | MultiPolygon | Point>;
914
+ //#endregion
915
+ //#region src/generators/cm15-maneuver-areas/strongPoint.d.ts
916
+ /** Configuration options for the Strong Point control measure. */
917
+ type StrongPointOptions = BattlePositionOptions;
918
+ /** Default options for the Strong Point control measure. */
919
+ declare const DEFAULT_STRONG_POINT_OPTIONS: StrongPointOptions;
920
+ /**
921
+ * Creates a Strong Point control measure: a Battle Position boundary/echelon
922
+ * with outward tics whose length and spacing are the Field B echelon height.
923
+ * Shares the perimeter and echelon placement with Battle Position via the
924
+ * `area-echelon` primitive (single source of truth for ring and gap).
925
+ *
926
+ * @param positions - Area anchor points (>=3); the input contract is enforced
927
+ * at the render seam (ADR-0014).
928
+ * @param options - {@link StrongPointOptions}.
929
+ * @param textAmplifiers - Field T (designation, centered in the area) plus an
930
+ * optional Field N "ENY" hostile marker at the west/east edges, same as
931
+ * Battle Position.
932
+ */
933
+ declare function createStrongPoint(positions: Position[], options?: StrongPointOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | MultiPolygon | Point>;
934
+ //#endregion
935
+ //#region src/generators/cm14-maneuver-lines/direction-of-attack-aviation.d.ts
936
+ interface DirectionOfAttackAviationOptions extends LabelSizeOptions, SmoothLineOptions {
937
+ /** Arrowhead length as a ratio of the route's total length. @default 0.12 */
938
+ arrowheadLengthRatio?: number;
939
+ /** Arrowhead total width as a ratio of its length. @default 1.15 */
940
+ arrowheadWidthRatio?: number;
941
+ /** Bow-tie length as a ratio of the route's total length. @default 0.1 */
942
+ bowTieLengthRatio?: number;
943
+ /** Bow-tie total width as a ratio of its length. @default 0.5 */
944
+ bowTieWidthRatio?: number;
945
+ /** Bow-tie position as a fraction from tail (0) to tip (1). @default 1/3 */
946
+ bowTiePosition?: number;
947
+ /** Field T/W/W1 group position as a fraction from tail (0) to tip (1). @default 2/3 */
948
+ labelPosition?: number;
949
+ /** Extra spacing between the route and W/W1 rows, in label heights. @default 0 */
950
+ labelPadding?: number;
951
+ }
952
+ declare const DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS: DirectionOfAttackAviationOptions;
953
+ /** Builds the route, aviation bow-tie, arrowhead, and optional T/W/W1 labels. */
954
+ declare function createDirectionOfAttackAviation(coordinates: Position[], options?: DirectionOfAttackAviationOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | Point>;
955
+ //#endregion
956
+ //#region src/generators/cm14-maneuver-lines/direction-of-attack-shared.d.ts
957
+ interface DirectionOfAttackLineOptions extends LabelSizeOptions, SmoothLineOptions {
958
+ arrowheadLengthRatio?: number;
959
+ arrowheadWidthRatio?: number;
960
+ /** Field T/W/W1 group position as a fraction from tail (0) to tip (1). */
961
+ labelPosition?: number;
962
+ labelPadding?: number;
963
+ }
964
+ //#endregion
965
+ //#region src/generators/cm14-maneuver-lines/direction-of-main-attack.d.ts
966
+ interface DirectionOfMainAttackOptions extends DirectionOfAttackLineOptions {
967
+ /** Thickness of the outlined arrowhead as a ratio of its length. @default 0.3 */
968
+ arrowheadOutlineRatio?: number;
969
+ }
970
+ declare const DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS: DirectionOfMainAttackOptions;
971
+ declare function createDirectionOfMainAttack(coordinates: Position[], options?: DirectionOfMainAttackOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | Point>;
972
+ //#endregion
973
+ //#region src/generators/cm14-maneuver-lines/direction-of-supporting-attack.d.ts
974
+ type DirectionOfSupportingAttackOptions = DirectionOfAttackLineOptions;
975
+ declare const DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS: DirectionOfSupportingAttackOptions;
976
+ declare function createDirectionOfSupportingAttack(coordinates: Position[], options?: DirectionOfSupportingAttackOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | Point>;
977
+ //#endregion
978
+ //#region src/generators/cm14-maneuver-lines/principalDirectionOfFire.d.ts
979
+ /**
980
+ * Configuration options for the Principal Direction of Fire tactical symbol.
981
+ */
982
+ interface PrincipalDirectionOfFireOptions {
983
+ /** Arrowhead length relative to each arm's own length (default: 0.07) */
984
+ arrowheadLengthRatio?: number;
985
+ /** Arrowhead wing spread relative to the arrowhead length (default: 0.67) */
986
+ arrowheadWidthRatio?: number;
987
+ }
988
+ declare const DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS: Required<PrincipalDirectionOfFireOptions>;
989
+ /**
990
+ * Generates a GeoJSON FeatureCollection for a PRINCIPAL DIRECTION OF FIRE
991
+ * tactical symbol: a "V" of arms from the vertex out to the (independent) tips,
992
+ * each ending in an open arrowhead.
993
+ *
994
+ * Renders one arm per tip, so two points (vertex + one tip) draws the single
995
+ * arm being placed — the live feedback after PT 1 — and three points draws the
996
+ * full V. Points beyond the third are ignored (input contract, ADR-0014).
997
+ *
998
+ * @param coordinates - [PT 1 (vertex), PT 2 (tip), PT 3 (tip)]
999
+ * @param options - Arrowhead sizing parameters
1000
+ */
1001
+ declare function createPrincipalDirectionOfFire(coordinates: Position[], options?: PrincipalDirectionOfFireOptions): FeatureCollection<MultiLineString, Record<string, never>>;
1002
+ //#endregion
1003
+ //#region src/rendered.d.ts
1004
+ /**
1005
+ * Per-feature style hints carried on `properties.style`.
1006
+ *
1007
+ * These are *resolved*: `renderControlMeasure` cascades `graphicsStyle` →
1008
+ * `cm.style` → any generator pattern hint, then expands the monocolor `color`
1009
+ * into concrete `strokeColor` / `fillColor` per feature (see ADR-0011 and
1010
+ * `resolveSymbolColor`). Output therefore carries concrete colors, never the
1011
+ * input-only `color` key, and a `fillColor` only on parts the generator
1012
+ * marked filled.
1013
+ *
1014
+ * Generators contribute paint *role* and *pattern* (a part is filled; a
1015
+ * sub-line is dashed regardless of the user's stroke), never a hue. Adapters
1016
+ * merge the resulting `StyleHints` over their layer-level style at draw time.
1017
+ */
1018
+ interface StyleHints extends ControlMeasureStyle {}
1019
+ /**
1020
+ * Per-feature properties emitted by `renderControlMeasure`.
1021
+ *
1022
+ * Stable-id contract — every feature produced by the renderer has:
1023
+ * - `feature.id` of the form `${cmId}:${part}:${index}`
1024
+ * - `properties.part` matching the `part` segment of the id
1025
+ * - `properties.index` matching the `index` segment of the id
1026
+ *
1027
+ * Adapters rely on this contract to diff renders in place without keeping
1028
+ * their own bookkeeping. Use `controlMeasureIdFromFeature` to recover the
1029
+ * `cmId` from a picked feature.
1030
+ */
1031
+ interface FeaturePartProps {
1032
+ part: string;
1033
+ index: number;
1034
+ style?: StyleHints;
1035
+ /** Label text emitted by generators (e.g. breach "B"). */
1036
+ text?: string;
1037
+ /** Label rotation in radians, emitted by generators. */
1038
+ rotation?: number;
1039
+ /**
1040
+ * Horizontal text alignment relative to the label point: `"start"` = the
1041
+ * text begins at the point, `"end"` = it ends there. Absent = centered.
1042
+ */
1043
+ textAnchor?: "start" | "end";
1044
+ /** Render an opaque light backdrop behind text placed over patterned geometry. */
1045
+ textBackground?: boolean;
1046
+ /** Render a contrast-aware halo behind the glyphs so text stays legible on busy backgrounds. */
1047
+ textHalo?: boolean;
1048
+ /** Halo color contrasting with the resolved text color; present only when `textHalo` is set. */
1049
+ textHaloColor?: string;
1050
+ /** Canonical field key for a text-amplifier label that may be repositioned. */
1051
+ amplifierField?: TextAmplifierKey;
1052
+ /** Stable key used to persist a user-adjusted anchor for any rendered label. */
1053
+ labelPlacementKey?: string;
1054
+ /**
1055
+ * Screen-anchored label size in CSS pixels — held constant on screen
1056
+ * (ADR-0028). Mutually exclusive with `textSizeMeters`; absent both,
1057
+ * adapters render their engine default, screen-fixed.
1058
+ */
1059
+ textSizePixels?: number;
1060
+ /**
1061
+ * Ground-anchored label text height in projected meters (ADR-0028).
1062
+ * Adapters render `clamp(textSizeMeters / resolution, min, max)` px, per
1063
+ * their configured clamp band.
1064
+ */
1065
+ textSizeMeters?: number;
1066
+ /**
1067
+ * Multi-line justification within the text block (Text's `textAlign`
1068
+ * option); the block itself stays centered on the anchor regardless of this
1069
+ * value — unrelated to the block-shifting `textAnchor`.
1070
+ */
1071
+ textJustify?: "left" | "center" | "right";
1072
+ /** Closed typography preset for a text label (Text's `textStyle` option). */
1073
+ textStyle?: "regular" | "italic" | "light" | "caps";
1074
+ /**
1075
+ * Hide threshold in CSS pixels: when the derived on-screen text size exceeds
1076
+ * this, adapters render nothing for the label instead of clamping (ADR-0037)
1077
+ * and skip the default 8-24px ground clamp band.
1078
+ */
1079
+ textMaxSizePixels?: number;
1080
+ }
1081
+ /**
1082
+ * Output of `renderControlMeasure`. A GeoJSON `FeatureCollection` whose
1083
+ * features satisfy the `FeaturePartProps` stable-id contract. See ADR-0010.
1084
+ */
1085
+ type ControlMeasureRender = FeatureCollection<Geometry, FeaturePartProps>;
1086
+ /**
1087
+ * Recover the originating control measure id (`cmId`) from a feature emitted
1088
+ * by `renderControlMeasure`. The feature id must match the stable-id contract
1089
+ * `${cmId}:${part}:${index}`; otherwise this throws.
1090
+ */
1091
+ declare function controlMeasureIdFromFeature(feature: Feature<Geometry, FeaturePartProps> | {
1092
+ id?: string | number;
1093
+ }): string;
1094
+ //#endregion
1095
+ //#region src/generators/cm14-maneuver-lines/finalProtectiveFire.d.ts
1096
+ /**
1097
+ * Configuration options for the Final Protective Fire tactical symbols.
1098
+ *
1099
+ * Identical to Principal Direction of Fire (arrowhead sizing), plus a filled
1100
+ * "blade" running along the inside of one arm.
1101
+ */
1102
+ interface FinalProtectiveFireOptions {
1103
+ /** Arrowhead length relative to each arm's own length (default: 0.07) */
1104
+ arrowheadLengthRatio?: number;
1105
+ /** Arrowhead wing spread relative to the arrowhead length (default: 0.67) */
1106
+ arrowheadWidthRatio?: number;
1107
+ /**
1108
+ * Blade height (its perpendicular reach into the inside of the V) relative
1109
+ * to the bladed arm's own length (default: 0.03).
1110
+ */
1111
+ bladeHeightRatio?: number;
1112
+ }
1113
+ declare const DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS: Required<FinalProtectiveFireOptions>;
1114
+ type FpfProps = {
1115
+ part?: string;
1116
+ fill?: true;
1117
+ style?: StyleHints;
1118
+ };
1119
+ declare function createFinalProtectiveFireLeft(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1120
+ declare function createFinalProtectiveFireRight(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1121
+ //#endregion
1122
+ //#region src/generators/cm15-maneuver-areas/encirclement.d.ts
1123
+ /**
1124
+ * Configuration options for the Encirclement control measure. Also carries
1125
+ * the shared {@link AreaLabelOptions} label placement for its Field N (ENY)
1126
+ * marker — the doctrinal example shows only the hostile marker, no name/H/W
1127
+ * rows.
1128
+ */
1129
+ interface EncirclementOptions extends AreaLabelOptions {
1130
+ /**
1131
+ * Spacing between adjacent barbs as a ratio of the symbol's mean radius;
1132
+ * smaller values pack the barbs more densely. The barbs are then distributed
1133
+ * evenly so they close the ring exactly.
1134
+ * @default 0.4
1135
+ */
1136
+ barbSpacingRatio?: number;
1137
+ /**
1138
+ * Barb length (height/amplitude) as a ratio of the symbol's mean radius.
1139
+ * @default 0.16
1140
+ */
1141
+ barbLengthRatio?: number;
1142
+ /**
1143
+ * Round the boundary by curving it through the control points (closed
1144
+ * centripetal Catmull-Rom) before tracing the barbs.
1145
+ * @default true
1146
+ */
1147
+ smooth?: boolean;
1148
+ /**
1149
+ * Number of samples per segment when `smooth` is enabled.
1150
+ * @default 16
1151
+ */
1152
+ smoothResolution?: number;
1153
+ }
1154
+ /**
1155
+ * Default options for the Encirclement control measure. Not `Required<...>`
1156
+ * — the inherited label-size options ({@link AreaLabelOptions}) have no
1157
+ * static default, so this covers only the barb/smoothing options.
1158
+ */
1159
+ declare const DEFAULT_ENCIRCLEMENT_OPTIONS: EncirclementOptions;
1160
+ /**
1161
+ * Creates an Encirclement tactical graphic: a complete smooth boundary ring
1162
+ * with outward arrowhead barbs resting on it. The boundary is an unfilled
1163
+ * Polygon; the barbs are open "V" strokes (a MultiLineString) whose base is the
1164
+ * boundary arc itself. When a Field N (ENY) marker is set, it masks the
1165
+ * boundary with a knockout gap wherever its text box touches the ring
1166
+ * (mirroring Field B's echelon glyph, ADR-0023) — the boundary becomes a
1167
+ * gapped MultiLineString instead of a closed Polygon, and any barb whose
1168
+ * center falls inside the gap is suppressed; the no-`N` case is unaffected.
1169
+ *
1170
+ * @param positions - Area anchor points (>=3); the input contract is enforced
1171
+ * at the render seam (ADR-0014).
1172
+ * @param options - {@link EncirclementOptions}.
1173
+ * @param textAmplifiers - Field N only — rendered as "ENY" markers at the
1174
+ * ring's west and east edges, per the doctrinal hostile example.
1175
+ */
1176
+ declare function createEncirclement(positions: Position[], options?: EncirclementOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1177
+ //#endregion
1178
+ //#region src/generators/cm15-maneuver-areas/area.d.ts
1179
+ /** Configuration options for the Area control measure. */
1180
+ type AreaOptions = LabeledAreaOptions;
1181
+ /**
1182
+ * Creates an Area control measure: a closed area through `positions` labeled
1183
+ * at its center with an un-prefixed `T` (Field T) plus an `N` (Field N) ENY
1184
+ * marker, per {@link labeledAreaFeatures}.
1185
+ */
1186
+ declare function createArea(positions: Position[], options?: AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1187
+ //#endregion
1188
+ //#region src/generators/cm15-maneuver-areas/area-defense.d.ts
1189
+ interface AreaDefenseOptions extends LabelSizeOptions {
1190
+ /** Angular opening between the two arrow tips, in degrees. */
1191
+ arrowOpeningAngle?: number;
1192
+ /** Angular opening occupied by the AD label, in degrees. */
1193
+ labelOpeningAngle?: number;
1194
+ /** Number of filled outward barbs distributed over both arcs. */
1195
+ barbCount?: number;
1196
+ /** Barb height as a ratio of the radius. */
1197
+ barbLengthRatio?: number;
1198
+ /** Open-arrowhead length as a ratio of the radius. */
1199
+ arrowheadLengthRatio?: number;
1200
+ }
1201
+ declare const DEFAULT_AREA_DEFENSE_OPTIONS: Required<Omit<AreaDefenseOptions, keyof LabelSizeOptions>>;
1202
+ declare function createAreaDefense(coordinates: Position[], options?: AreaDefenseOptions): FeatureCollection<MultiLineString | MultiPolygon | Point>;
1203
+ //#endregion
1204
+ //#region src/generators/cm15-maneuver-areas/assemblyArea.d.ts
1205
+ /** Configuration options for the Assembly area control measure. */
1206
+ type AssemblyAreaOptions = LabeledAreaOptions;
1207
+ /** Default options for the Assembly area control measure. */
1208
+ declare const DEFAULT_ASSEMBLY_AREA_OPTIONS: AssemblyAreaOptions;
1209
+ /**
1210
+ * Creates an Assembly area control measure: a closed area through
1211
+ * `positions` labeled at its center with "AA "-prefixed `T` (Field T) plus
1212
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1213
+ */
1214
+ declare function createAssemblyArea(positions: Position[], options?: AssemblyAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1215
+ //#endregion
1216
+ //#region src/generators/cm15-maneuver-areas/jointTacticalActionArea.d.ts
1217
+ /** Configuration options for the Joint tactical action area control measure. */
1218
+ type JointTacticalActionAreaOptions = LabeledAreaOptions;
1219
+ /** Default options for the Joint tactical action area control measure. */
1220
+ declare const DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS: JointTacticalActionAreaOptions;
1221
+ /**
1222
+ * Creates a Joint tactical action area control measure: a closed area
1223
+ * through `positions` labeled at its center with "JTAA -"-prefixed `T`
1224
+ * (Field T) plus `H`/`W`/`W1`/`N` amplifier rows, per
1225
+ * {@link labeledAreaFeatures}.
1226
+ */
1227
+ declare function createJointTacticalActionArea(positions: Position[], options?: JointTacticalActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1228
+ //#endregion
1229
+ //#region src/generators/cm15-maneuver-areas/submarineActionArea.d.ts
1230
+ /** Configuration options for the Submarine action area control measure. */
1231
+ type SubmarineActionAreaOptions = LabeledAreaOptions;
1232
+ /**
1233
+ * Creates a Submarine action area control measure: a closed area through
1234
+ * `positions` labeled at its center with "SAA -"-prefixed `T` (Field T) plus
1235
+ * `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1236
+ */
1237
+ declare function createSubmarineActionArea(positions: Position[], options?: SubmarineActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1238
+ //#endregion
1239
+ //#region src/generators/cm15-maneuver-areas/submarineGeneratedActionArea.d.ts
1240
+ /** Configuration options for the Submarine-generated action area control measure. */
1241
+ type SubmarineGeneratedActionAreaOptions = LabeledAreaOptions;
1242
+ /**
1243
+ * Creates a Submarine-generated action area control measure: a closed area
1244
+ * through `positions` labeled at its center with "SGSA -"-prefixed `T`
1245
+ * (Field T) plus `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1246
+ */
1247
+ declare function createSubmarineGeneratedActionArea(positions: Position[], options?: SubmarineGeneratedActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1248
+ //#endregion
1249
+ //#region src/generators/cm15-maneuver-areas/dropZone.d.ts
1250
+ /** Configuration options for the Drop zone control measure. */
1251
+ type DropZoneOptions = LabeledAreaOptions;
1252
+ /**
1253
+ * Creates a Drop zone control measure: a closed area through `positions`
1254
+ * labeled at its center with "DZ "-prefixed `T` (Field T) plus an `N`
1255
+ * (Field N) ENY marker, per {@link labeledAreaFeatures}.
1256
+ */
1257
+ declare function createDropZone(positions: Position[], options?: DropZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1258
+ //#endregion
1259
+ //#region src/generators/cm15-maneuver-areas/extractionZone.d.ts
1260
+ /** Configuration options for the Extraction zone control measure. */
1261
+ type ExtractionZoneOptions = LabeledAreaOptions;
1262
+ /**
1263
+ * Creates an Extraction zone control measure: a closed area through
1264
+ * `positions` labeled at its center with "EZ "-prefixed `T` (Field T) plus
1265
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1266
+ */
1267
+ declare function createExtractionZone(positions: Position[], options?: ExtractionZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1268
+ //#endregion
1269
+ //#region src/generators/cm15-maneuver-areas/landingZone.d.ts
1270
+ /** Configuration options for the Landing zone control measure. */
1271
+ type LandingZoneOptions = LabeledAreaOptions;
1272
+ /** Default options for the Landing zone control measure. */
1273
+ declare const DEFAULT_LANDING_ZONE_OPTIONS: LandingZoneOptions;
1274
+ /**
1275
+ * Creates a Landing zone control measure: a closed area through `positions`
1276
+ * labeled at its center with "LZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1277
+ * amplifier rows, per {@link labeledAreaFeatures}.
1278
+ */
1279
+ declare function createLandingZone(positions: Position[], options?: LandingZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1280
+ //#endregion
1281
+ //#region src/generators/cm15-maneuver-areas/limitedAccessArea.d.ts
1282
+ /** Configuration options for the Limited Access Area control measure. */
1283
+ interface LimitedAccessAreaOptions extends AreaLabelOptions {
1284
+ /** Round the area's corners through its control points. */
1285
+ smooth?: boolean;
1286
+ /** Number of samples per segment when smoothing is enabled. */
1287
+ smoothResolution?: number;
1288
+ }
1289
+ /** Creates a back-hatched free area with a movable "LAA" label, centered by default. */
1290
+ declare function createLimitedAccessArea(positions: Position[], options?: LimitedAccessAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1291
+ //#endregion
1292
+ //#region src/generators/cm24-fire-areas/noFireAreaIrregular.d.ts
1293
+ /** Configuration options for the irregular No Fire Area control measure. */
1294
+ interface NoFireAreaIrregularOptions extends AreaLabelOptions {
1295
+ /** Round the area's corners through its control points. */
1296
+ smooth?: boolean;
1297
+ /** Number of samples per segment when smoothing is enabled. */
1298
+ smoothResolution?: number;
1299
+ }
1300
+ /** Creates a back-hatched irregular NFA with its centered movable label fields. */
1301
+ declare function createNoFireAreaIrregular(positions: Position[], options?: NoFireAreaIrregularOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1302
+ //#endregion
1303
+ //#region src/generators/cm15-maneuver-areas/pickupZone.d.ts
1304
+ /** Configuration options for the Pickup zone control measure. */
1305
+ type PickupZoneOptions = LabeledAreaOptions;
1306
+ /** Default options for the Pickup zone control measure. */
1307
+ declare const DEFAULT_PICKUP_ZONE_OPTIONS: PickupZoneOptions;
1308
+ /**
1309
+ * Creates a Pickup zone control measure: a closed area through `positions`
1310
+ * labeled at its center with "PZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1311
+ * amplifier rows, per {@link labeledAreaFeatures}.
1312
+ */
1313
+ declare function createPickupZone(positions: Position[], options?: PickupZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1314
+ //#endregion
1315
+ //#region src/generators/cm15-maneuver-areas/assaultPosition.d.ts
1316
+ /** Configuration options for the Assault position control measure. */
1317
+ type AssaultPositionOptions = LabeledAreaOptions;
1318
+ /**
1319
+ * Creates an Assault position control measure: a closed area through
1320
+ * `positions` labeled at its center with "ASLT "-prefixed `T` (Field T) plus
1321
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1322
+ */
1323
+ declare function createAssaultPosition(positions: Position[], options?: AssaultPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1324
+ //#endregion
1325
+ //#region src/generators/cm15-maneuver-areas/attackPosition.d.ts
1326
+ /** Configuration options for the Attack position control measure. */
1327
+ type AttackPositionOptions = LabeledAreaOptions;
1328
+ /**
1329
+ * Creates an Attack position control measure: a closed area through
1330
+ * `positions` labeled at its center with "ATK "-prefixed `T` (Field T) plus
1331
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1332
+ */
1333
+ declare function createAttackPosition(positions: Position[], options?: AttackPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1334
+ //#endregion
1335
+ //#region src/generators/cm15-maneuver-areas/objectiveArea.d.ts
1336
+ /** Configuration options for the Objective area control measure. */
1337
+ type ObjectiveAreaOptions = LabeledAreaOptions;
1338
+ /**
1339
+ * Creates an Objective area control measure: a closed area through
1340
+ * `positions` labeled at its center with "OBJ "-prefixed `T` (Field T) plus
1341
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1342
+ */
1343
+ declare function createObjectiveArea(positions: Position[], options?: ObjectiveAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1344
+ //#endregion
1345
+ //#region src/generators/cm12-command-control-areas/area-of-operations.d.ts
1346
+ /** Configuration options for the Area of operations control measure. */
1347
+ type AreaOfOperationsOptions = LabeledAreaOptions;
1348
+ /** Default options for the Area of operations control measure. */
1349
+ declare const DEFAULT_AREA_OF_OPERATIONS_OPTIONS: AreaOfOperationsOptions;
1350
+ /**
1351
+ * Creates an Area of operations control measure: a closed area through
1352
+ * `positions` labeled at its center with "AO "-prefixed `T` (Field T) plus
1353
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1354
+ */
1355
+ declare function createAreaOfOperations(positions: Position[], options?: AreaOfOperationsOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1356
+ //#endregion
1357
+ //#region src/generators/cm12-command-control-areas/named-area-of-interest.d.ts
1358
+ /** Configuration options for the Named area of interest control measure. */
1359
+ type NamedAreaOfInterestOptions = LabeledAreaOptions;
1360
+ /**
1361
+ * Creates a Named area of interest control measure: a closed area through
1362
+ * `positions` labeled at its center with "NAI "-prefixed `T` (Field T) plus
1363
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1364
+ */
1365
+ declare function createNamedAreaOfInterest(positions: Position[], options?: NamedAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1366
+ //#endregion
1367
+ //#region src/generators/cm12-command-control-areas/target-area-of-interest.d.ts
1368
+ /** Configuration options for the Target area of interest control measure. */
1369
+ type TargetAreaOfInterestOptions = LabeledAreaOptions;
1370
+ /**
1371
+ * Creates a Target area of interest control measure: a closed area through
1372
+ * `positions` labeled at its center with "TAI "-prefixed `T` (Field T) plus
1373
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1374
+ */
1375
+ declare function createTargetAreaOfInterest(positions: Position[], options?: TargetAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1376
+ //#endregion
1377
+ //#region src/generators/cm12-command-control-areas/airfield-zone.d.ts
1378
+ /** Configuration options for the Airfield zone control measure. */
1379
+ interface AirfieldZoneOptions extends LabeledAreaOptions {
1380
+ /**
1381
+ * The runway glyph's long line, as a ratio of the ring's projected
1382
+ * bounding-box width (full length, not half).
1383
+ * @default 0.55
1384
+ */
1385
+ glyphSizeRatio?: number;
1386
+ }
1387
+ /**
1388
+ * Creates an Airfield zone control measure: a closed area through
1389
+ * `positions` with a runway glyph (two crossed lines forming a shallow
1390
+ * asymmetric X) centered on the ring, and Field H placed outside the area to
1391
+ * the east when set.
1392
+ *
1393
+ * @param positions - Area anchor points (≥3); the input contract is enforced
1394
+ * at the render seam (ADR-0014).
1395
+ * @param options - {@link AirfieldZoneOptions}.
1396
+ * @param textAmplifiers - Field H (placed east of the area) plus an optional
1397
+ * Field N "ENY" hostile marker on the west/east edges.
1398
+ */
1399
+ declare function createAirfieldZone(positions: Position[], options?: AirfieldZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1400
+ //#endregion
1401
+ //#region src/generators/cm12-command-control-areas/echelon-labeled-area.d.ts
1402
+ /**
1403
+ * Configuration options shared by Base Camp and Guerrilla Base: the full L-15
1404
+ * label placement ({@link LabeledAreaOptions}) plus Battle Position's Field B
1405
+ * echelon knobs.
1406
+ */
1407
+ interface EchelonLabeledAreaOptions extends LabeledAreaOptions {
1408
+ /**
1409
+ * Field B echelon straddling the boundary. `"none"` (the default — the
1410
+ * standard's examples show no echelon glyph), empty, or unknown renders no
1411
+ * glyph and leaves the boundary unaffected by echelon masking.
1412
+ * @default "none"
1413
+ */
1414
+ echelon?: string;
1415
+ /**
1416
+ * Echelon glyph height in meters (ground-anchored). Ignored when
1417
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
1418
+ * @default 750
1419
+ */
1420
+ echelonSize?: number;
1421
+ /**
1422
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to
1423
+ * meters against `metersPerPixel`; bakes to a meter size on draw/edit
1424
+ * commit (ADR-0020).
1425
+ * @default 16
1426
+ */
1427
+ echelonSizePixels?: number;
1428
+ /**
1429
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph
1430
+ * height. `0` butts the boundary against the glyph; larger values widen
1431
+ * the break.
1432
+ * @default 0.3
1433
+ */
1434
+ echelonPadding?: number;
1435
+ /**
1436
+ * Slides the echelon along the boundary, as a signed fraction of the total
1437
+ * perimeter measured from its default anchor on the bottom edge.
1438
+ * @default 0
1439
+ */
1440
+ echelonPosition?: number;
1441
+ /**
1442
+ * Absolute anchor for the echelon glyph, as a fraction of the total
1443
+ * perimeter measured from the ring seam, wrapped into `[0, 1)`. See Battle
1444
+ * Position's `echelonAnchor` (ADR-0023) — edit controllers freeze this via
1445
+ * the `freezeOrientation` hook the moment a rotate gesture starts.
1446
+ */
1447
+ echelonAnchor?: number;
1448
+ /**
1449
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when
1450
+ * the measure is screen-anchored; required to resolve `echelonSizePixels`.
1451
+ */
1452
+ metersPerPixel?: number;
1453
+ }
1454
+ //#endregion
1455
+ //#region src/generators/cm12-command-control-areas/base-camp.d.ts
1456
+ /** Configuration options for the Base camp control measure. */
1457
+ type BaseCampOptions = EchelonLabeledAreaOptions;
1458
+ /**
1459
+ * Creates a Base camp control measure: a closed area through `positions`
1460
+ * labeled at its center with "BC "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1461
+ * amplifier rows, and an optional Field B echelon glyph straddling the
1462
+ * boundary, per {@link echelonLabeledAreaFeatures}.
1463
+ */
1464
+ declare function createBaseCamp(positions: Position[], options?: BaseCampOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1465
+ //#endregion
1466
+ //#region src/generators/cm12-command-control-areas/guerrilla-base.d.ts
1467
+ /** Configuration options for the Guerrilla base control measure. */
1468
+ type GuerrillaBaseOptions = EchelonLabeledAreaOptions;
1469
+ /**
1470
+ * Creates a Guerrilla base control measure: a closed area through
1471
+ * `positions` labeled at its center with "GB "-prefixed `T` (Field T) plus
1472
+ * `H`/`W`/`W1`/`N` amplifier rows, and an optional Field B echelon glyph
1473
+ * straddling the boundary, per {@link echelonLabeledAreaFeatures}.
1474
+ */
1475
+ declare function createGuerrillaBase(positions: Position[], options?: GuerrillaBaseOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1476
+ //#endregion
1477
+ //#region src/generators/cm12-command-control-areas/generic-c2-area.d.ts
1478
+ /** Configuration options for the Generic command and control area control measure. */
1479
+ type GenericC2AreaOptions = LabeledAreaOptions;
1480
+ /**
1481
+ * Creates a Generic command and control area control measure: a closed area
1482
+ * through `positions` labeled at its center with the bare `T` (Field T) plus
1483
+ * `H`/`W`/`W1`/`N` amplifier rows — no prefix, per {@link labeledAreaFeatures}.
1484
+ */
1485
+ declare function createGenericC2Area(positions: Position[], options?: GenericC2AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1486
+ //#endregion
1487
+ //#region src/attack-utils.d.ts
1488
+ interface AttackOptions {
1489
+ shaftWidthRatio?: number;
1490
+ smooth?: boolean;
1491
+ smoothResolution?: number;
1492
+ }
1493
+ /**
1494
+ * Calculates the relative metrics (longitudinal and lateral) of the width point
1495
+ * relative to the Tip-Neck axis.
1496
+ *
1497
+ * @param pts - Array of positions [Tip, Neck, ..., WidthPoint]
1498
+ * @returns { longitudinal: number, lateral: number } | null
1499
+ */
1500
+ declare function calculateMetrics(pts: Position[]): {
1501
+ longitudinal: number;
1502
+ lateral: number;
1503
+ } | null;
1504
+ /**
1505
+ * Computes an initial Width Point based on the Tip and Neck positions.
1506
+ * It places the point perpendicular to the neck at a default distance relative to the length.
1507
+ *
1508
+ * @param tip - Tip position (Lon/Lat)
1509
+ * @param neck - Neck position (Lon/Lat)
1510
+ * @returns Width Point position (Lon/Lat)
1511
+ */
1512
+ declare function computeInitialWidthPoint(tip: Position, neck: Position): Position;
1513
+ //#endregion
1514
+ //#region src/generators/cm15-maneuver-areas/mainAttack.d.ts
1515
+ declare const DEFAULT_MAIN_ATTACK_OPTIONS: Required<AttackOptions>;
1516
+ type MainAttackOptions = AttackOptions;
1517
+ /**
1518
+ * Generates a GeoJSON FeatureCollection for a Main Attack tactical symbol.
1519
+ *
1520
+ * The symbol consists of a single MultiLineString feature containing:
1521
+ * 1. **Arrowhead**: A line forming a "chevron" or "roof" shape.
1522
+ * 2. **Shaft**: Two parallel lines behind the arrow.
1523
+ *
1524
+ * The shaft is calculated to terminate exactly where it touches the inner walls
1525
+ * of the arrowhead, creating a seamless connection.
1526
+ *
1527
+ * @param coordinates - An array of GeoJSON Positions (Lon/Lat).
1528
+ * Minimum 3 points required.
1529
+ * **Order matters:** * - Index 0: **Tip** (The sharp point of the arrow)
1530
+ * - Index 1 to N-2: **Spine** (The path the shaft follows)
1531
+ * - Index N-1: **Width Control** (Determines the width of the arrowhead)
1532
+ * @param options - Configuration for ratios and properties.
1533
+ * @returns A GeoJSON FeatureCollection containing a single MultiLineString.
1534
+ */
1535
+ declare function createMainAttack(coordinates: Position[], options?: MainAttackOptions): FeatureCollection<MultiLineString>;
1536
+ //#endregion
1537
+ //#region src/generators/cm15-maneuver-areas/supportingAttack.d.ts
1538
+ type SupportingAttackOptions = AttackOptions;
1539
+ declare const DEFAULT_SUPPORTING_ATTACK_OPTIONS: Required<SupportingAttackOptions>;
1540
+ /**
1541
+ * Generates a GeoJSON FeatureCollection for a Supporting Attack tactical symbol.
1542
+ *
1543
+ * The symbol differs from Main Attack in that it is a single LineString
1544
+ * outlining the arrow shape, rather than a filled Polygon header + Shaft lines.
1545
+ *
1546
+ * @param coordinates - An array of GeoJSON Positions.
1547
+ * @param options - Configuration options.
1548
+ * @returns A GeoJSON FeatureCollection<LineString>.
1549
+ */
1550
+ declare function createSupportingAttack(coordinates: Position[], options?: SupportingAttackOptions): FeatureCollection<LineString>;
1551
+ //#endregion
1552
+ //#region src/generators/cm99-generic-arrows/classicArrow.d.ts
1553
+ /**
1554
+ * A plain, clean arrow for illustrations — not a doctrinal symbol. The shaft is
1555
+ * a straight polyline through the drawn control points (Line1 contract) and the
1556
+ * tip carries a solid triangular arrowhead. No wobble, no curve: the canonical
1557
+ * "draw an arrow" graphic.
1558
+ */
1559
+ /**
1560
+ * Arrowhead silhouette:
1561
+ * - `triangle` — solid triangle with a flat back (the default).
1562
+ * - `barbed` — swept-back barbs with a forward notch (classic arrowhead).
1563
+ * - `concave` — a sharper barbed head with a deep forward notch.
1564
+ * - `diamond` — a rhombus, widest at its middle.
1565
+ * - `harpoon` — an asymmetric single-sided barb.
1566
+ * - `swallowtail` — barbs that sweep back into two trailing tails.
1567
+ * - `chevron` — a thick hollow "V".
1568
+ * - `circle` — a round dot terminator.
1569
+ * - `tee` — a flat crossbar terminator (no point).
1570
+ * - `open` — an unfilled "V", drawn as two strokes meeting at the tip.
1571
+ */
1572
+ type ClassicArrowHeadStyle = "triangle" | "barbed" | "concave" | "diamond" | "harpoon" | "swallowtail" | "chevron" | "circle" | "tee" | "open";
1573
+ interface ClassicArrowOptions {
1574
+ /** Arrowhead silhouette. */
1575
+ arrowheadStyle?: ClassicArrowHeadStyle;
1576
+ /** Round the shaft's corners by curving it through the control points. */
1577
+ smooth?: boolean;
1578
+ /** Number of samples per segment when smooth mode is enabled. */
1579
+ smoothResolution?: number;
1580
+ /** Arrowhead length as a fraction of the total path length. */
1581
+ arrowheadLengthRatio?: number;
1582
+ /** Arrowhead base width as a fraction of the total path length. */
1583
+ arrowheadWidthRatio?: number;
1584
+ }
1585
+ declare const DEFAULT_CLASSIC_ARROW_OPTIONS: Required<ClassicArrowOptions>;
1586
+ /**
1587
+ * Generates a GeoJSON FeatureCollection for the Classic Arrow: a shaft
1588
+ * LineString (trimmed so it doesn't poke through the head) plus a head feature
1589
+ * whose silhouette follows `arrowheadStyle` — a filled Polygon for the solid heads,
1590
+ * or an open "V" LineString for `open`.
1591
+ */
1592
+ declare function createClassicArrow(coordinates: Position[], options?: ClassicArrowOptions): FeatureCollection<LineString | Polygon, {
1593
+ part: "shaft" | "head";
1594
+ fill?: boolean;
1595
+ style?: StyleHints;
1596
+ }>;
1597
+ //#endregion
1598
+ //#region src/generators/cm99-generic-arrows/blockArrow.d.ts
1599
+ /**
1600
+ * A solid "block" arrow for illustrations — not a doctrinal symbol. The whole
1601
+ * arrow is one filled polygon: a shaft band of controllable width that runs
1602
+ * through the drawn Axis1 spine and flares into a wider triangular head at the
1603
+ * tip. Axis1 control points are ordered `[tip, neck, ...spine, width]`.
1604
+ */
1605
+ /**
1606
+ * Arrowhead silhouette (all carved from the one filled body):
1607
+ * - `triangle` — a flat-backed triangular head (the default).
1608
+ * - `barbed` — swept-back barbs with the shaft entering at a forward notch.
1609
+ * - `concave` — a sharper barbed head with a deeper notch.
1610
+ * - `diamond` — a kite that flares to its widest mid-head.
1611
+ * - `harpoon` — an asymmetric single-sided barb.
1612
+ * - `swallowtail` — barbs that sweep back into two trailing tails.
1613
+ * - `tee` — a flat crossbar terminator (no point).
1614
+ */
1615
+ type BlockArrowHeadStyle = "triangle" | "barbed" | "concave" | "diamond" | "harpoon" | "swallowtail" | "tee";
1616
+ interface BlockArrowOptions {
1617
+ /** Shaft band width as a fraction of the total path length. */
1618
+ shaftWidthRatio?: number;
1619
+ /** Arrowhead silhouette. */
1620
+ arrowheadStyle?: BlockArrowHeadStyle;
1621
+ /** Arrowhead base width as a fraction of the total path length. */
1622
+ arrowheadWidthRatio?: number;
1623
+ /** Arrowhead length as a fraction of the total path length. */
1624
+ arrowheadLengthRatio?: number;
1625
+ /** Round the shaft's corners by curving it through the control points. */
1626
+ smooth?: boolean;
1627
+ /** Number of samples per segment when smooth mode is enabled. */
1628
+ smoothResolution?: number;
1629
+ /** Fill the body solid; when false the arrow is drawn as an outline only. */
1630
+ filled?: boolean;
1631
+ }
1632
+ declare const DEFAULT_BLOCK_ARROW_OPTIONS: Required<BlockArrowOptions>;
1633
+ /**
1634
+ * Generates a GeoJSON FeatureCollection for the Block Arrow: a single filled
1635
+ * Polygon whose outline runs up the left side of the shaft, around the head
1636
+ * (whose silhouette follows `arrowheadStyle`) to the tip and back, then down the
1637
+ * right side of the shaft.
1638
+ */
1639
+ declare function createBlockArrow(coordinates: Position[], options?: BlockArrowOptions): FeatureCollection<Polygon, {
1640
+ part: "body";
1641
+ fill: boolean;
1642
+ }>;
1643
+ //#endregion
1644
+ //#region src/generators/cm99-generic-graphics/params.d.ts
1645
+ interface SmoothPathOptions {
1646
+ /** Curve the rendered path through the unchanged control points. */
1647
+ smooth?: boolean;
1648
+ /** Number of samples per segment when smoothing is enabled. */
1649
+ smoothResolution?: number;
1650
+ }
1651
+ interface FilledAreaOptions {
1652
+ /** Fill the polygon interior; false renders only its outline. */
1653
+ filled?: boolean;
1654
+ }
1655
+ //#endregion
1656
+ //#region src/generators/cm99-generic-graphics/line.d.ts
1657
+ type GenericLineOptions = SmoothPathOptions;
1658
+ declare const DEFAULT_GENERIC_LINE_OPTIONS: Required<GenericLineOptions>;
1659
+ declare function createGenericLine(coordinates: Position[], options?: GenericLineOptions): FeatureCollection<LineString>;
1660
+ //#endregion
1661
+ //#region src/generators/cm99-generic-graphics/polygon.d.ts
1662
+ interface GenericPolygonOptions extends SmoothPathOptions, FilledAreaOptions {}
1663
+ declare const DEFAULT_GENERIC_POLYGON_OPTIONS: Required<GenericPolygonOptions>;
1664
+ declare function createGenericPolygon(coordinates: Position[], options?: GenericPolygonOptions): FeatureCollection<Polygon, {
1665
+ part: string;
1666
+ fill: boolean;
1667
+ }>;
1668
+ //#endregion
1669
+ //#region src/generators/cm99-generic-graphics/rectangle.d.ts
1670
+ type GenericRectangleOptions = FilledAreaOptions;
1671
+ declare const DEFAULT_GENERIC_RECTANGLE_OPTIONS: Required<GenericRectangleOptions>;
1672
+ declare function createGenericRectangle(coordinates: Position[], options?: GenericRectangleOptions): FeatureCollection<Polygon, {
1673
+ part: string;
1674
+ fill: boolean;
1675
+ }>;
1676
+ //#endregion
1677
+ //#region src/generators/cm99-generic-graphics/circle.d.ts
1678
+ type GenericCircleOptions = FilledAreaOptions;
1679
+ declare const DEFAULT_GENERIC_CIRCLE_OPTIONS: Required<GenericCircleOptions>;
1680
+ declare function createGenericCircle(coordinates: Position[], options?: GenericCircleOptions): FeatureCollection<Polygon, {
1681
+ part: string;
1682
+ fill: boolean;
1683
+ }>;
1684
+ //#endregion
1685
+ //#region src/generators/cm99-generic-graphics/text.d.ts
1686
+ /** Configuration options for the generic Text control measure. */
1687
+ interface GenericTextOptions {
1688
+ /** Plain text; explicit `\n` breaks lines — never auto-wraps. @default "Text" */
1689
+ text?: string;
1690
+ /**
1691
+ * Placement of the text block relative to the anchor point, and the
1692
+ * justification of its lines. `left` puts the anchor at the block's left edge
1693
+ * (text extends rightward, lines left-justified); `right` puts the anchor at
1694
+ * the right edge (text extends leftward, lines right-justified); `center`
1695
+ * centers the block on the anchor (lines centered). Maps onto the existing
1696
+ * block-shifting `textAnchor` prop (`left` → `start`, `right` → `end`, `center`
1697
+ * → none) plus the `textJustify` prop; rotation always pivots at the anchor.
1698
+ * @default "center"
1699
+ */
1700
+ textAlign?: "left" | "center" | "right";
1701
+ /** Closed typography preset. `caps` uppercases `regular`; `light` is weight 300. @default "regular" */
1702
+ textStyle?: "regular" | "italic" | "light" | "caps";
1703
+ /** Clockwise rotation in degrees on screen. @default 0 */
1704
+ rotation?: number;
1705
+ /**
1706
+ * Text height (cap height) in projected meters — ground-anchored
1707
+ * (ADR-0020). Ignored whenever `sizePixels` is present.
1708
+ */
1709
+ sizeMeters?: number;
1710
+ /**
1711
+ * Text height in CSS pixels — screen-anchored (ADR-0020). A fresh draw is
1712
+ * authored in pixels and bakes to `sizeMeters` on commit.
1713
+ * @default 24
1714
+ */
1715
+ sizePixels?: number;
1716
+ /**
1717
+ * Hide threshold in CSS pixels: once the ground-derived on-screen size
1718
+ * exceeds this, adapters hide the text entirely instead of clamping it
1719
+ * (ADR-0037); there is no minimum, so the text just keeps shrinking on
1720
+ * zoom-out.
1721
+ * @default 200
1722
+ */
1723
+ maxSizePixels?: number;
1724
+ }
1725
+ declare const DEFAULT_GENERIC_TEXT_OPTIONS: GenericTextOptions;
1726
+ declare function createGenericText(coordinates: Position[], options?: GenericTextOptions): FeatureCollection<Point, Record<string, unknown>>;
1727
+ //#endregion
1728
+ //#region src/generators/cm15-maneuver-areas/airborneAttack.d.ts
1729
+ type AirborneAttackOptions = AttackOptions;
1730
+ declare const DEFAULT_AIRBORNE_ATTACK_OPTIONS: Required<AirborneAttackOptions>;
1731
+ /**
1732
+ * Generates a GeoJSON FeatureCollection for an Airborne Attack tactical symbol.
1733
+ *
1734
+ * The symbol is similar to Supporting Attack but features a crossover point
1735
+ * between the shaft and the head (Points 1 and 2/Neck).
1736
+ *
1737
+ * @param coordinates - An array of GeoJSON Positions.
1738
+ * @param options - Configuration options.
1739
+ * @returns A GeoJSON FeatureCollection<LineString>.
1740
+ */
1741
+ declare function createAirborneAttack(coordinates: Position[], options?: AirborneAttackOptions): FeatureCollection<LineString>;
1742
+ //#endregion
1743
+ //#region src/generators/cm15-maneuver-areas/attackHelicopter.d.ts
1744
+ interface AttackHelicopterOptions extends AttackOptions {
1745
+ symbolHeightRatio?: number;
1746
+ triangleSizeRatio?: number;
1747
+ bottomBarWidthRatio?: number;
1748
+ bowtieWidthRatio?: number;
1749
+ }
1750
+ declare const DEFAULT_ATTACK_HELICOPTER_OPTIONS: Required<AttackHelicopterOptions>;
1751
+ /**
1752
+ * Generates a GeoJSON FeatureCollection for an Attack Helicopter tactical symbol.
1753
+ *
1754
+ * The symbol is based on the Airborne Attack (bow tie) geometry but features
1755
+ * an additional symbol (vertical line + triangle) at the crossover point.
1756
+ *
1757
+ * @param coordinates - An array of GeoJSON Positions.
1758
+ * @param options - Configuration options.
1759
+ * @returns A GeoJSON FeatureCollection containing the main graphic and the symbol.
1760
+ */
1761
+ declare function createAttackHelicopter(coordinates: Position[], options?: AttackHelicopterOptions): FeatureCollection<LineString | Polygon>;
1762
+ //#endregion
1763
+ //#region src/generators/cm15-maneuver-areas/supportByFire.d.ts
1764
+ interface SupportByFireOptions {
1765
+ arrowheadWidthRatio?: number;
1766
+ rearLineLengthRatio?: number;
1767
+ rearLineAngle?: number;
1768
+ }
1769
+ declare const DEFAULT_SUPPORT_BY_FIRE_OPTIONS: Required<SupportByFireOptions>;
1770
+ /**
1771
+ * Generates a GeoJSON FeatureCollection for a Support By Fire tactical graphic.
1772
+ *
1773
+ * Input:
1774
+ * - PT1: Left Base
1775
+ * - PT2: Right Base
1776
+ * - PT3: Left Tip
1777
+ * - PT4: Right Tip
1778
+ */
1779
+ declare function createSupportByFire(coordinates: Position[], options?: SupportByFireOptions): FeatureCollection<LineString>;
1780
+ //#endregion
1781
+ //#region src/generators/cm15-maneuver-areas/attackByFire.d.ts
1782
+ interface AttackByFireOptions {
1783
+ arrowheadWidthRatio?: number;
1784
+ rearLineLengthRatio?: number;
1785
+ rearLineAngle?: number;
1786
+ }
1787
+ declare const DEFAULT_ATTACK_BY_FIRE_OPTIONS: Required<AttackByFireOptions>;
1788
+ /**
1789
+ * Generates a GeoJSON FeatureCollection for an Attack By Fire tactical graphic.
1790
+ *
1791
+ * Input:
1792
+ * - PT1: Arrow Tip (Target)
1793
+ * - PT2: Left Base
1794
+ * - PT3: Right Base
1795
+ *
1796
+ * Logic:
1797
+ * - Shaft: Midpoint(PT2, PT3) -> PT1
1798
+ * - Base Line: PT2 -> PT3
1799
+ * - Wings: Splayed out from PT2 and PT3
1800
+ */
1801
+ declare function createAttackByFire(coordinates: Position[], options?: AttackByFireOptions): FeatureCollection<LineString>;
1802
+ //#endregion
1803
+ //#region src/generators/cm14-maneuver-lines/flot.d.ts
1804
+ /**
1805
+ * Configuration options for the FLOT (Forward Line of Own Troops) geometry.
1806
+ */
1807
+ interface FLOTOptions extends SmoothLineOptions, LineLabelOptions {
1808
+ /**
1809
+ * The radius of the semicircular arcs in meters.
1810
+ * Semicircles are placed tangent to each other (diameter = 2 * radius).
1811
+ * This is ignored if radiusPixels is provided along with metersPerPixel.
1812
+ * @default 50
1813
+ */
1814
+ radius?: number;
1815
+ /**
1816
+ * The radius of the semi-circular arcs in pixels.
1817
+ * When provided along with metersPerPixel, the actual meter radius is calculated
1818
+ * dynamically to maintain consistent visual size on screen.
1819
+ * Takes precedence over radius when metersPerPixel is also provided.
1820
+ * @default 10
1821
+ */
1822
+ radiusPixels?: number;
1823
+ /**
1824
+ * The meters-per-pixel ratio at the current zoom level and latitude.
1825
+ * Required when using radiusPixels for zoom-aware sizing.
1826
+ * Can be obtained from the map view's resolution or calculated using getMetersPerPixel().
1827
+ */
1828
+ metersPerPixel?: number;
1829
+ /**
1830
+ * The number of points used to render each individual semi-circle.
1831
+ * Higher values create smoother arcs.
1832
+ * @default 16
1833
+ */
1834
+ arcSegments?: number;
1835
+ }
1836
+ /**
1837
+ * Default options for the FLOT graphic.
1838
+ */
1839
+ declare const DEFAULT_FLOT_OPTIONS: Required<Omit<FLOTOptions, keyof LineLabelOptions>>;
1840
+ /**
1841
+ * Creates a FLOT (Forward Line of Own Troops) tactical graphic.
1842
+ *
1843
+ * Generates a scalloped/arc line representing the forward edge of friendly forces.
1844
+ * The line consists of semi-circular arcs that bulge perpendicular to the base path,
1845
+ * creating a distinctive visual pattern used in military tactical graphics.
1846
+ *
1847
+ * @param positions - Array of GeoJSON positions defining the base path
1848
+ * @param options - Configuration options for the graphic
1849
+ * @returns A GeoJSON FeatureCollection containing the scalloped LineString
1850
+ *
1851
+ * @example
1852
+ * ```typescript
1853
+ * const flot = createFLOT(
1854
+ * [[-122.4194, 37.7749], [-122.4100, 37.7800], [-122.4000, 37.7750]],
1855
+ * { radius: 100, arcSegments: 20 }
1856
+ * );
1857
+ * ```
1858
+ */
1859
+ declare function createFLOT(positions: Position[], options?: FLOTOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1860
+ //#endregion
1861
+ //#region src/generators/cm14-maneuver-lines/phase-line.d.ts
1862
+ /** Configuration options for the Phase line control measure. */
1863
+ interface PhaseLineOptions extends LineLabelOptions, SmoothLineOptions {
1864
+ /**
1865
+ * Prefix the end labels with "PL" (`"PL ECHO"`, or a bare `"PL"` when no
1866
+ * designation is set). When `false`, the label is the bare designation
1867
+ * (`Field T`) alone, and the line carries no label at all when `T` is empty.
1868
+ * @default true
1869
+ */
1870
+ includePrefix?: boolean;
1871
+ }
1872
+ /** Default options for the Phase line control measure. */
1873
+ declare const DEFAULT_PHASE_LINE_OPTIONS: PhaseLineOptions;
1874
+ /**
1875
+ * Creates a Phase line control measure: a polyline through `positions`
1876
+ * labeled at each end with `T` (optionally "PL"-prefixed).
1877
+ */
1878
+ declare function createPhaseLine(positions: Position[], options?: PhaseLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1879
+ //#endregion
1880
+ //#region src/generators/cm14-maneuver-lines/handover-line.d.ts
1881
+ /** Configuration options for the Handover line control measure. */
1882
+ interface HandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1883
+ /**
1884
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1885
+ * the line, additive to the fixed "HOL" labels. Empty or whitespace-only
1886
+ * renders no label.
1887
+ * @default none
1888
+ */
1889
+ phaseLineName?: string;
1890
+ /**
1891
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1892
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1893
+ * Phase Line itself, this measure already carries its own fixed "HOL"
1894
+ * label, so there is no bare "PL" fallback.
1895
+ * @default true
1896
+ */
1897
+ includePrefix?: boolean;
1898
+ }
1899
+ /** Default options for the Handover line control measure. */
1900
+ declare const DEFAULT_HANDOVER_LINE_OPTIONS: HandoverLineOptions;
1901
+ /**
1902
+ * Creates a Handover line control measure: a polyline through `positions`
1903
+ * labeled "HOL" above the line near each end.
1904
+ */
1905
+ declare function createHandoverLine(positions: Position[], options?: HandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1906
+ //#endregion
1907
+ //#region src/generators/cm14-maneuver-lines/battle-handover-line.d.ts
1908
+ /** Configuration options for the Battle handover line control measure. */
1909
+ interface BattleHandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1910
+ /**
1911
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1912
+ * the line, additive to the fixed "BHL" labels. Empty or whitespace-only
1913
+ * renders no label.
1914
+ * @default none
1915
+ */
1916
+ phaseLineName?: string;
1917
+ /**
1918
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1919
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1920
+ * Phase Line itself, this measure already carries its own fixed "BHL"
1921
+ * label, so there is no bare "PL" fallback.
1922
+ * @default true
1923
+ */
1924
+ includePrefix?: boolean;
1925
+ }
1926
+ /** Default options for the Battle handover line control measure. */
1927
+ declare const DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS: BattleHandoverLineOptions;
1928
+ /**
1929
+ * Creates a Battle handover line control measure: a polyline through
1930
+ * `positions` labeled "BHL" above the line near each end.
1931
+ */
1932
+ declare function createBattleHandoverLine(positions: Position[], options?: BattleHandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1933
+ //#endregion
1934
+ //#region src/generators/cm34-mission-tasks/block.d.ts
1935
+ interface BlockMissionTaskOptions {
1936
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1937
+ labelGapRatio?: number;
1938
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1939
+ labelSize?: number;
1940
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1941
+ labelSizePixels?: number;
1942
+ }
1943
+ declare const DEFAULT_BLOCK_MISSION_TASK_OPTIONS: Required<Omit<BlockMissionTaskOptions, "labelSize" | "labelSizePixels">>;
1944
+ /**
1945
+ * Generates a GeoJSON FeatureCollection for a BLOCK mission task symbol (340100).
1946
+ *
1947
+ * Uses the same T-shape geometry as the protection-area Block symbol, with a
1948
+ * "B" label centered on the shaft.
1949
+ *
1950
+ * @param coordinates - [PT. 1, PT. 2, optional PT. 3] as Position arrays
1951
+ * @param options - Configuration options
1952
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1953
+ */
1954
+ declare function createBlockMissionTaskSymbol(coordinates: Position[], options?: BlockMissionTaskOptions): FeatureCollection<MultiLineString | Point>;
1955
+ //#endregion
1956
+ //#region src/generators/cm34-mission-tasks/breach.d.ts
1957
+ /**
1958
+ * Configuration options for the BREACH tactical symbol.
1959
+ */
1960
+ interface BreachOptions {
1961
+ /** Tick mark length ratio relative to front opening (default: 0.15) */
1962
+ tickLengthRatio?: number;
1963
+ /** Tick mark angle in degrees from perpendicular (default: 45) */
1964
+ tickAngle?: number;
1965
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1966
+ labelGapRatio?: number;
1967
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1968
+ labelSize?: number;
1969
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1970
+ labelSizePixels?: number;
1971
+ }
1972
+ /**
1973
+ * Default options for the BREACH symbol.
1974
+ */
1975
+ declare const DEFAULT_BREACH_OPTIONS: Required<Omit<BreachOptions, "labelSize" | "labelSizePixels">>;
1976
+ /**
1977
+ * Generates a GeoJSON FeatureCollection for a BREACH mission task symbol (340200).
1978
+ *
1979
+ * A three-sided bracket (see {@link createBracketSymbol}) whose front opening
1980
+ * endpoints terminate in tick marks pointing **outward** (away from the rear
1981
+ * "B" line).
1982
+ *
1983
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
1984
+ * @param options - Configuration options
1985
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1986
+ */
1987
+ declare function createBreachSymbol(coordinates: Position[], options?: BreachOptions): FeatureCollection<MultiLineString | Point>;
1988
+ //#endregion
1989
+ //#region src/generators/cm34-mission-tasks/bypass.d.ts
1990
+ /**
1991
+ * Configuration options for the BYPASS tactical symbol.
1992
+ */
1993
+ interface BypassOptions {
1994
+ /** Arrowhead length ratio relative to front opening (default: 0.2) */
1995
+ arrowheadLengthRatio?: number;
1996
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1997
+ labelGapRatio?: number;
1998
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1999
+ labelSize?: number;
2000
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2001
+ labelSizePixels?: number;
2002
+ }
2003
+ /**
2004
+ * Default options for the BYPASS symbol.
2005
+ */
2006
+ declare const DEFAULT_BYPASS_OPTIONS: Required<Omit<BypassOptions, "labelSize" | "labelSizePixels">>;
2007
+ /**
2008
+ * Generates a GeoJSON FeatureCollection for a BYPASS mission task symbol (340300).
2009
+ *
2010
+ * A three-sided bracket (see {@link createBracketSymbol}) with a "B" label on
2011
+ * the rear line, whose front opening endpoints terminate in outward-flaring
2012
+ * chevron arrowheads instead of tick marks.
2013
+ *
2014
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
2015
+ * @param options - Configuration options
2016
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
2017
+ */
2018
+ declare function createBypassSymbol(coordinates: Position[], options?: BypassOptions): FeatureCollection<MultiLineString | Point>;
2019
+ //#endregion
2020
+ //#region src/generators/cm34-mission-tasks/canalize.d.ts
2021
+ /**
2022
+ * Configuration options for the CANALIZE tactical symbol.
2023
+ */
2024
+ interface CanalizeOptions {
2025
+ /** Tick mark length ratio relative to front opening (default: 0.15) */
2026
+ tickLengthRatio?: number;
2027
+ /** Tick mark angle in degrees from perpendicular (default: 45) */
2028
+ tickAngle?: number;
2029
+ /** Gap for the 'C' label as a ratio of the front length (default: 0.2) */
2030
+ labelGapRatio?: number;
2031
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2032
+ labelSize?: number;
2033
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2034
+ labelSizePixels?: number;
2035
+ }
2036
+ /**
2037
+ * Default options for the CANALIZE symbol.
2038
+ */
2039
+ declare const DEFAULT_CANALIZE_OPTIONS: Required<Omit<CanalizeOptions, "labelSize" | "labelSizePixels">>;
2040
+ /**
2041
+ * Generates a GeoJSON FeatureCollection for a CANALIZE mission task symbol (340400).
2042
+ *
2043
+ * A three-sided bracket (see {@link createBracketSymbol}) whose front opening
2044
+ * endpoints terminate in tick marks pointing **inward** (toward the rear "C"
2045
+ * line), opposite BREACH's outward-facing ticks.
2046
+ *
2047
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
2048
+ * @param options - Configuration options
2049
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
2050
+ */
2051
+ declare function createCanalizeSymbol(coordinates: Position[], options?: CanalizeOptions): FeatureCollection<MultiLineString | Point>;
2052
+ //#endregion
2053
+ //#region src/generators/cm34-mission-tasks/clear.d.ts
2054
+ /**
2055
+ * Configuration options for the CLEAR tactical mission task symbol.
2056
+ */
2057
+ interface ClearOptions {
2058
+ /**
2059
+ * Padding between the vertical line's endpoints and the outer arrows, as a
2060
+ * ratio of the symbol height. Insets the top and bottom arrows so they sit
2061
+ * clear of PT. 1 / PT. 2 (default: 0.15).
2062
+ */
2063
+ arrowInsetRatio?: number;
2064
+ /** Arrowhead depth (toward the rear) as a ratio of the symbol height (default: 0.15). */
2065
+ arrowheadLengthRatio?: number;
2066
+ /** Arrowhead width (along the vertical line) as a ratio of the symbol height (default: 0.2). */
2067
+ arrowheadWidthRatio?: number;
2068
+ /** Gap for the 'C' label as a ratio of the shaft length (default: 0.2). */
2069
+ labelGapRatio?: number;
2070
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2071
+ labelSize?: number;
2072
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2073
+ labelSizePixels?: number;
2074
+ }
2075
+ /**
2076
+ * Default options for the CLEAR symbol.
2077
+ */
2078
+ declare const DEFAULT_CLEAR_OPTIONS: Required<Omit<ClearOptions, "labelSize" | "labelSizePixels">>;
2079
+ /**
2080
+ * Generates a GeoJSON FeatureCollection for a CLEAR mission task symbol (340500).
2081
+ *
2082
+ * A vertical line (PT. 1 → PT. 2) with three arrows pointing at it,
2083
+ * perpendicular to the line. The arrows come from the rear — the side PT. 3
2084
+ * sits on — and their tips touch the vertical line; each carries a shaft
2085
+ * reaching back to the rear. The arrows are evenly spaced along the line, so
2086
+ * the middle arrow's tip sits at the midpoint of the vertical line and its
2087
+ * shaft carries the 'C' glyph. The arrows stay perpendicular to the vertical
2088
+ * line at any rotation.
2089
+ *
2090
+ * Input Points:
2091
+ * - PT. 1: Top endpoint of the vertical line
2092
+ * - PT. 2: Bottom endpoint of the vertical line — defines height with PT. 1
2093
+ * - PT. 3: Rear point — defines the shaft length (and which side the arrows
2094
+ * come from)
2095
+ *
2096
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
2097
+ * @param options - Configuration options
2098
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
2099
+ */
2100
+ declare function createClearSymbol(coordinates: Position[], options?: ClearOptions): FeatureCollection<MultiLineString | Point>;
2101
+ //#endregion
2102
+ //#region src/generators/cm15-maneuver-areas/searchArea.d.ts
2103
+ /**
2104
+ * Configuration options to tweak the tactical arrow's geometry.
2105
+ */
2106
+ interface TacticalArrowOptions {
2107
+ /** Ratio of arrowhead length to total leg length (default: 0.12) */
2108
+ arrowheadLengthRatio?: number;
2109
+ /** Width multiplier for the arrowhead wings (default: 0.5) */
2110
+ arrowheadWidthRatio?: number;
2111
+ /** Percentage along the leg where the zigzag begins, 0.0-1.0 (default: 0.55) */
2112
+ zigzagStart?: number;
2113
+ /** Percentage along the leg where the zigzag returns, 0.0-1.0 (default: 0.45) */
2114
+ zigzagEnd?: number;
2115
+ /** Perpendicular offset for the lightning "kink", relative to leg length (default: 0.07) */
2116
+ zigzagAmplitudeRatio?: number;
2117
+ }
2118
+ /**
2119
+ * Default options for the tactical arrow.
2120
+ */
2121
+ declare const DEFAULT_TACTICAL_ARROW_OPTIONS: Required<TacticalArrowOptions>;
2122
+ //#endregion
2123
+ //#region src/generators/cm34-mission-tasks/security-task-shared.d.ts
2124
+ interface SecurityTaskOptions extends TacticalArrowOptions {
2125
+ /** Position of each task letter inward from PT. 2/PT. 3 as a ratio of the opening. */
2126
+ labelInsetRatio?: number;
2127
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2128
+ labelSize?: number;
2129
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2130
+ labelSizePixels?: number;
2131
+ }
2132
+ //#endregion
2133
+ //#region src/generators/cm34-mission-tasks/cover.d.ts
2134
+ type CoverOptions = SecurityTaskOptions;
2135
+ declare const DEFAULT_COVER_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2136
+ declare function createCoverSymbol(coordinates: Position[], options?: CoverOptions): FeatureCollection<MultiLineString | Point>;
2137
+ //#endregion
2138
+ //#region src/generators/cm34-mission-tasks/delay.d.ts
2139
+ interface DelayOptions {
2140
+ /** Arrowhead depth as a ratio of the straight-line length (default: 0.12). */
2141
+ arrowheadLengthRatio?: number;
2142
+ /** Arrowhead width as a ratio of the straight-line length (default: 0.12). */
2143
+ arrowheadWidthRatio?: number;
2144
+ /** Gap for the 'D' label as a ratio of the straight-line length (default: 0.18). */
2145
+ labelGapRatio?: number;
2146
+ /** Number of segments used to approximate the 180-degree arc (default: 32). */
2147
+ arcSegments?: number;
2148
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2149
+ labelSize?: number;
2150
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2151
+ labelSizePixels?: number;
2152
+ }
2153
+ declare const DEFAULT_DELAY_OPTIONS: Required<Omit<DelayOptions, "labelSize" | "labelSizePixels">>;
2154
+ declare function createDelaySymbol(coordinates: Position[], options?: DelayOptions): FeatureCollection<MultiLineString | Point>;
2155
+ //#endregion
2156
+ //#region src/generators/cm34-mission-tasks/guard.d.ts
2157
+ type GuardOptions = SecurityTaskOptions;
2158
+ declare const DEFAULT_GUARD_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2159
+ declare function createGuardSymbol(coordinates: Position[], options?: GuardOptions): FeatureCollection<MultiLineString | Point>;
2160
+ //#endregion
2161
+ //#region src/generators/cm34-mission-tasks/isolate.d.ts
2162
+ /**
2163
+ * Configuration options for the ISOLATE tactical mission task symbol.
2164
+ */
2165
+ interface IsolateOptions {
2166
+ /** Angular size of the opening on the friendly side, in degrees (default: 30). */
2167
+ openingAngle?: number;
2168
+ /** Number of inward-pointing arrowhead barbs spaced around the closed arc (default: 9). */
2169
+ barbCount?: number;
2170
+ /** Barb length as a ratio of the symbol radius (default: 0.18). */
2171
+ barbLengthRatio?: number;
2172
+ }
2173
+ /**
2174
+ * Generates a GeoJSON FeatureCollection for an ISOLATE mission task symbol (341500).
2175
+ *
2176
+ * A near-complete circle centered on PT. 1 whose radius reaches PT. 2. The arc
2177
+ * starts (bare) at PT. 2's bearing and sweeps clockwise around the closed
2178
+ * portion to a single arrow tip at the far end; the wedge-shaped gap (default
2179
+ * 30°) between that arrow tip and PT. 2 is the opening — the "friendly side".
2180
+ * Inward-pointing arrowhead barbs are spaced along the closed arc, set in from
2181
+ * both ends so they never touch PT. 2 or the arrow tip, conveying the
2182
+ * sealing-off of the enclosed force. Unlike the bracket mission tasks, isolate
2183
+ * carries no glyph label.
2184
+ *
2185
+ * Input Points:
2186
+ * - PT. 1: Center point
2187
+ * - PT. 2: Start point — fixes the radius and the bearing of the opening
2188
+ *
2189
+ * @param coordinates - [PT. 1, PT. 2] as Position arrays
2190
+ * @param options - Configuration options
2191
+ * @returns GeoJSON FeatureCollection containing a single MultiLineString feature
2192
+ */
2193
+ declare function createIsolateSymbol(coordinates: Position[], options?: IsolateOptions): FeatureCollection<MultiLineString>;
2194
+ //#endregion
2195
+ //#region src/generators/cm34-mission-tasks/screen.d.ts
2196
+ type ScreenOptions = SecurityTaskOptions;
2197
+ declare const DEFAULT_SCREEN_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2198
+ declare function createScreenSymbol(coordinates: Position[], options?: ScreenOptions): FeatureCollection<MultiLineString | Point>;
2199
+ //#endregion
2200
+ //#region src/generators/cm29-protection-lines/antitankDitch.d.ts
2201
+ interface AntitankDitchOptions extends SmoothLineOptions, LineLabelOptions {
2202
+ /**
2203
+ * The tooth depth in meters. Target tooth spacing is roughly 1.15x this depth.
2204
+ * Ignored when toothHeightPixels is provided with metersPerPixel.
2205
+ * @default 50
2206
+ */
2207
+ toothHeight?: number;
2208
+ /**
2209
+ * The tooth depth in pixels. When provided with metersPerPixel, the meter
2210
+ * size is calculated dynamically to maintain a consistent visual size.
2211
+ * @default 10
2212
+ */
2213
+ toothHeightPixels?: number;
2214
+ /**
2215
+ * The target base span of each triangular tooth as a multiple of tooth depth.
2216
+ * Lower values make sharper, denser teeth; higher values make flatter teeth.
2217
+ * @default 1.15
2218
+ */
2219
+ toothWidthRatio?: number;
2220
+ /**
2221
+ * The meters-per-pixel ratio at the current zoom level and latitude. Required
2222
+ * when using toothHeightPixels for zoom-aware sizing.
2223
+ */
2224
+ metersPerPixel?: number;
2225
+ }
2226
+ declare const DEFAULT_ANTITANK_DITCH_OPTIONS: Required<Omit<AntitankDitchOptions, keyof LineLabelOptions>>;
2227
+ declare function createAntitankDitchUnderConstruction(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2228
+ declare function createAntitankDitchCompleted(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiPolygon | Point>;
2229
+ //#endregion
2230
+ //#region src/generators/cm29-protection-lines/antitankWall.d.ts
2231
+ interface AntitankWallOptions extends AntitankDitchOptions {
2232
+ /**
2233
+ * The total gap between consecutive tooth bases as a multiple of tooth base
2234
+ * width. Use 0 for touching teeth; higher values create wider gaps.
2235
+ * @default 1.35
2236
+ */
2237
+ toothSpacingRatio?: number;
2238
+ }
2239
+ declare const DEFAULT_ANTITANK_WALL_OPTIONS: Required<Omit<AntitankWallOptions, keyof LineLabelOptions>>;
2240
+ declare function createAntitankWall(positions: Position[], options?: AntitankWallOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2241
+ //#endregion
2242
+ //#region src/generators/cm29-protection-lines/fortifiedLine.d.ts
2243
+ /**
2244
+ * Configuration options for the Fortified Line geometry.
2245
+ */
2246
+ interface FortifiedLineOptions extends LineLabelOptions {
2247
+ /**
2248
+ * The size of the square teeth in meters.
2249
+ * This controls both the width and height of the castellated pattern.
2250
+ * This is ignored if toothSizePixels is provided along with metersPerPixel.
2251
+ * @default 50
2252
+ */
2253
+ toothSize?: number;
2254
+ /**
2255
+ * The size of the square teeth in pixels.
2256
+ * When provided along with metersPerPixel, the actual meter size is calculated
2257
+ * dynamically to maintain consistent visual size on screen.
2258
+ * Takes precedence over toothSize when metersPerPixel is also provided.
2259
+ * @default 10
2260
+ */
2261
+ toothSizePixels?: number;
2262
+ /**
2263
+ * The meters-per-pixel ratio at the current zoom level and latitude.
2264
+ * Required when using toothSizePixels for zoom-aware sizing.
2265
+ */
2266
+ metersPerPixel?: number;
2267
+ /**
2268
+ * Round the line's corners by curving the base path through the control
2269
+ * points (centripetal Catmull-Rom spline) before generating the castellated
2270
+ * teeth, matching the rounded shape option on the Fortified Area and Battle
2271
+ * Position measures. With fewer than three control points the path is left
2272
+ * unchanged (a single segment cannot be smoothed).
2273
+ * @default false
2274
+ */
2275
+ smooth?: boolean;
2276
+ /**
2277
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
2278
+ * a denser, smoother curve.
2279
+ * @default 16
2280
+ */
2281
+ smoothResolution?: number;
2282
+ }
2283
+ /**
2284
+ * Default options for the Fortified Line graphic.
2285
+ */
2286
+ declare const DEFAULT_FORTIFIED_LINE_OPTIONS: Required<Omit<FortifiedLineOptions, keyof LineLabelOptions>>;
2287
+ /**
2288
+ * Creates a Fortified Line tactical graphic.
2289
+ *
2290
+ * Generates a castellated/square-wave line representing a fortified line.
2291
+ * The line consists of square "teeth" that project perpendicular to the base path.
2292
+ *
2293
+ * @param positions - Array of GeoJSON positions defining the base path
2294
+ * @param options - Configuration options for the graphic
2295
+ * @returns A GeoJSON FeatureCollection containing the castellated LineString
2296
+ */
2297
+ declare function createFortifiedLine(positions: Position[], options?: FortifiedLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
2298
+ //#endregion
2299
+ //#region src/generators/cm15-maneuver-areas/fortifiedArea.d.ts
2300
+ /**
2301
+ * Configuration options for the Fortified Area. Inherits the Fortified Line
2302
+ * options (including `smooth`/`smoothResolution`) unchanged; the area applies
2303
+ * the smoothing as a closed Catmull-Rom ring rather than an open spline. Also
2304
+ * carries the shared {@link AreaLabelOptions} label placement (a plain
2305
+ * intersection, not a re-derivation, so the aliased
2306
+ * {@link DEFAULT_FORTIFIED_AREA_OPTIONS} default still typechecks unchanged —
2307
+ * `AreaLabelOptions`'s fields are all optional).
2308
+ */
2309
+ type FortifiedAreaOptions = FortifiedLineOptions & AreaLabelOptions;
2310
+ declare const DEFAULT_FORTIFIED_AREA_OPTIONS: FortifiedAreaOptions;
2311
+ /**
2312
+ * Creates a Fortified Area tactical graphic.
2313
+ *
2314
+ * Generates a polygon with a castellated/square-wave boundary representing a fortified area.
2315
+ * The boundary consists of square "teeth" that project perpendicular to the path.
2316
+ *
2317
+ * @param positions - Array of GeoJSON positions defining the area boundary.
2318
+ * The first and last positions should match to close the polygon,
2319
+ * or it will be closed automatically.
2320
+ * @param options - Configuration options for the graphic
2321
+ * @param textAmplifiers - Field T (bare, no prefix — "TANGO", not "FA TANGO")
2322
+ * plus Field H/W/W1, centered on the pre-teeth boundary ring (see
2323
+ * `boundaryInput` below), and an optional Field N "ENY" hostile marker on
2324
+ * that ring's west/east edges, masking the castellated boundary beneath it.
2325
+ * @param context - Persisted amplifier placements used to move or restore each
2326
+ * ENY cutout with its independently dragged label.
2327
+ * @returns A GeoJSON FeatureCollection containing the castellated boundary
2328
+ * (a Polygon normally, or a gapped MultiLineString with Field N) plus any
2329
+ * label Points
2330
+ */
2331
+ declare function createFortifiedArea(positions: Position[], options?: FortifiedAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
2332
+ //#endregion
2333
+ //#region src/generators/cm15-maneuver-areas/maneuver-arrow-task-shared.d.ts
2334
+ interface ManeuverArrowTaskOptions extends AttackOptions, LabelSizeOptions {
2335
+ /** Straight crossbar length as a multiple of the arrowhead base width. */
2336
+ crossbarLengthRatio?: number;
2337
+ /** Field T position along the shaft, from tail (0) to head (1). */
2338
+ labelPosition?: number;
2339
+ /** W/W1 position along the shaft, from tail (0) to head (1). */
2340
+ dtgPosition?: number;
2341
+ /** Extra W/W1 row spacing, in label heights. */
2342
+ labelPadding?: number;
2343
+ }
2344
+ //#endregion
2345
+ //#region src/generators/cm15-maneuver-areas/frontal-attack.d.ts
2346
+ type FrontalAttackOptions = ManeuverArrowTaskOptions;
2347
+ declare const DEFAULT_FRONTAL_ATTACK_OPTIONS: FrontalAttackOptions;
2348
+ declare function createFrontalAttack(coordinates: Position[], options?: FrontalAttackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2349
+ //#endregion
2350
+ //#region src/generators/cm15-maneuver-areas/turning-movement.d.ts
2351
+ type TurningMovementOptions = ManeuverArrowTaskOptions;
2352
+ declare const DEFAULT_TURNING_MOVEMENT_OPTIONS: TurningMovementOptions;
2353
+ declare function createTurningMovement(coordinates: Position[], options?: TurningMovementOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2354
+ //#endregion
2355
+ //#region src/generators/cm27-protection-areas/block.d.ts
2356
+ type BlockOptions = Record<never, never>;
2357
+ declare const DEFAULT_BLOCK_OPTIONS: BlockOptions;
2358
+ /**
2359
+ * Generates a GeoJSON FeatureCollection for a "Block" tactical symbol (T-shape).
2360
+ *
2361
+ * @param coordinates - An array of GeoJSON Positions (Lon/Lat).
2362
+ * Expects exactly 3 points:
2363
+ * - PT1 & PT2: Endpoints of the vertical line.
2364
+ * - PT3: Defines the endpoint of the horizontal line (stem).
2365
+ * @param options - Configuration options.
2366
+ * @returns A GeoJSON FeatureCollection containing a LineString.
2367
+ */
2368
+ declare function createBlock(coordinates: Position[], _options?: BlockOptions): FeatureCollection<LineString>;
2369
+ //#endregion
2370
+ //#region src/generators/cm27-protection-areas/disrupt.d.ts
2371
+ interface DisruptOptions {
2372
+ middleArrowLengthRatio?: number;
2373
+ bottomArrowLengthRatio?: number;
2374
+ shaftLengthRatio?: number;
2375
+ arrowheadLengthRatio?: number;
2376
+ arrowheadWidthRatio?: number;
2377
+ }
2378
+ declare const DEFAULT_DISRUPT_OPTIONS: Required<DisruptOptions>;
2379
+ /**
2380
+ * Generates a GeoJSON FeatureCollection for a DISRUPT tactical symbol.
2381
+ *
2382
+ * Input:
2383
+ * - PT1: Top endpoint of the vertical spine
2384
+ * - PT2: Bottom endpoint of the vertical spine
2385
+ * - PT3: Reference point used to determine the longest-arrow offset
2386
+ *
2387
+ * Geometry:
2388
+ * - Spine: PT1 -> PT2
2389
+ * - PT2 -> PT1 defines the baseline orientation; arrow direction is constrained to its perpendicular axis
2390
+ * - PT3 is decomposed and projected onto the perpendicular axis through PT1 to derive a valid longest-arrow tip
2391
+ * - Three arrows placed at PT1, midpoint(PT1, PT2), and PT2
2392
+ * - Center shaft extends opposite arrow direction from midpoint with the same length as the middle arrow
2393
+ * - Top arrow is longest
2394
+ * - Middle and bottom arrows are proportional to the longest arrow
2395
+ * - Arrow heads are returned as filled triangle polygons
2396
+ */
2397
+ declare function createDisrupt(coordinates: Position[], options?: DisruptOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2398
+ //#endregion
2399
+ //#region src/generators/cm27-protection-areas/fix.d.ts
2400
+ interface FixOptions {
2401
+ arrowheadAngle?: number;
2402
+ arrowheadLengthRatio?: number;
2403
+ endSegmentRatio?: number;
2404
+ }
2405
+ declare const DEFAULT_FIX_OPTIONS: Required<FixOptions>;
2406
+ /**
2407
+ * Generates a GeoJSON FeatureCollection for a FIX tactical symbol.
2408
+ *
2409
+ * Input:
2410
+ * - PT1: Arrow tip end
2411
+ * - PT2: Opposite end
2412
+ *
2413
+ * Notes:
2414
+ * - Requires exactly two points.
2415
+ * - Produces one MultiLineString feature containing the zigzag body and open arrowhead wings.
2416
+ */
2417
+ declare function createFix(coordinates: Position[], options?: FixOptions): FeatureCollection<MultiLineString>;
2418
+ //#endregion
2419
+ //#region src/generators/cm27-protection-areas/turn.d.ts
2420
+ interface TurnOptions {
2421
+ arrowheadLengthRatio?: number;
2422
+ arrowheadWidthRatio?: number;
2423
+ arcSegments?: number;
2424
+ }
2425
+ declare const DEFAULT_TURN_OPTIONS: Required<TurnOptions>;
2426
+ /**
2427
+ * Generates a quarter-circle shaft from PT2 (rear) to the arrowhead base.
2428
+ * The arrowhead continues tangent to the arc and places its tip at PT1.
2429
+ * PT3 selects which side of the PT2 -> PT1 chord contains the arc.
2430
+ */
2431
+ declare function createTurn(coordinates: Position[], options?: TurnOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2432
+ //#endregion
2433
+ //#region src/generators/cm27-protection-areas/obstacleBypassEasy.d.ts
2434
+ interface ObstacleBypassEasyOptions {
2435
+ arrowheadLengthRatio?: number;
2436
+ arrowheadWidthRatio?: number;
2437
+ defaultLengthRatio?: number;
2438
+ }
2439
+ declare const DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS: Required<ObstacleBypassEasyOptions>;
2440
+ /**
2441
+ * Generates a GeoJSON FeatureCollection for an "Obstacle Bypass Easy" symbol.
2442
+ *
2443
+ * Input:
2444
+ * - PT1 and PT2 define the tips of the two arrowheads (opening and symbol height)
2445
+ * - PT3 defines signed symbol length along the perpendicular axis through midpoint(PT1, PT2)
2446
+ *
2447
+ * Geometry:
2448
+ * - Rear line is parallel to opening(PT1-PT2) and has equal length
2449
+ * - Two side rails run from rear endpoints to the arrowheads and are parallel to each other
2450
+ * - Rear line is perpendicular to both side rails
2451
+ * - Arrow heads are filled triangle polygons at PT1 and PT2
2452
+ */
2453
+ declare function createObstacleBypassEasy(coordinates: Position[], options?: ObstacleBypassEasyOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2454
+ //#endregion
2455
+ //#region src/generators/cm27-protection-areas/obstacleBypassDifficult.d.ts
2456
+ interface ObstacleBypassDifficultOptions {
2457
+ arrowheadLengthRatio?: number;
2458
+ arrowheadWidthRatio?: number;
2459
+ defaultLengthRatio?: number;
2460
+ zigzagAmplitudeRatio?: number;
2461
+ zigzagSpacingRatio?: number;
2462
+ }
2463
+ declare const DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS: Required<ObstacleBypassDifficultOptions>;
2464
+ declare function createObstacleBypassDifficult(coordinates: Position[], options?: ObstacleBypassDifficultOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2465
+ //#endregion
2466
+ //#region src/generators/cm27-protection-areas/obstacleBypassImpossible.d.ts
2467
+ interface ObstacleBypassImpossibleOptions {
2468
+ arrowheadLengthRatio?: number;
2469
+ arrowheadWidthRatio?: number;
2470
+ defaultLengthRatio?: number;
2471
+ rearBarLengthRatio?: number;
2472
+ rearGapRatio?: number;
2473
+ }
2474
+ declare const DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS: Required<ObstacleBypassImpossibleOptions>;
2475
+ /**
2476
+ * Generates a GeoJSON FeatureCollection for an "Obstacle Bypass Impossible" symbol.
2477
+ *
2478
+ * Input:
2479
+ * - PT1 and PT2 define the tips of the two arrowheads (opening and symbol height)
2480
+ * - PT3 defines signed symbol length along the perpendicular axis through midpoint(PT1, PT2)
2481
+ *
2482
+ * Geometry:
2483
+ * - Same base as obstacle bypass easy
2484
+ * - Rear line has two short perpendicular bars on the rear side
2485
+ */
2486
+ declare function createObstacleBypassImpossible(coordinates: Position[], options?: ObstacleBypassImpossibleOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2487
+ //#endregion
2488
+ //#region src/registry.d.ts
2489
+ /**
2490
+ * The single source of truth for the catalog: one **control measure
2491
+ * definition** record per measure, co-located with its generator and collected
2492
+ * here. The `ControlMeasureId` union, `OptionsByKind`, the generator dispatch,
2493
+ * the default options, and rule resolution are all *derived* from this map
2494
+ * rather than maintained as parallel tables. Adding a measure is a one-file
2495
+ * change plus one line here. See ADR-0013.
2496
+ */
2497
+ declare const DEFINITIONS: {
2498
+ boundary: ControlMeasureDefinition<"boundary", typeof createBoundary>;
2499
+ "light-line": ControlMeasureDefinition<"light-line", typeof createLightLine>;
2500
+ "engineer-work-line": ControlMeasureDefinition<"engineer-work-line", typeof createEngineerWorkLine>;
2501
+ "generic-c2-line": ControlMeasureDefinition<"generic-c2-line", typeof createGenericC2Line>;
2502
+ "battle-position": ControlMeasureDefinition<"battle-position", typeof createBattlePosition>;
2503
+ "strong-point": ControlMeasureDefinition<"strong-point", typeof createStrongPoint>;
2504
+ ambush: ControlMeasureDefinition<"ambush", (controlPoints: import("geojson").Position[], options?: AmbushOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString, Record<string, never>>>;
2505
+ "direction-of-attack-aviation": ControlMeasureDefinition<"direction-of-attack-aviation", typeof createDirectionOfAttackAviation>;
2506
+ "direction-of-main-attack": ControlMeasureDefinition<"direction-of-main-attack", typeof createDirectionOfMainAttack>;
2507
+ "direction-of-supporting-attack": ControlMeasureDefinition<"direction-of-supporting-attack", typeof createDirectionOfSupportingAttack>;
2508
+ "principal-direction-of-fire": ControlMeasureDefinition<"principal-direction-of-fire", typeof createPrincipalDirectionOfFire>;
2509
+ "final-protective-fire-left": ControlMeasureDefinition<"final-protective-fire-left", typeof createFinalProtectiveFireLeft>;
2510
+ "final-protective-fire-right": ControlMeasureDefinition<"final-protective-fire-right", typeof createFinalProtectiveFireRight>;
2511
+ "search-area": ControlMeasureDefinition<"search-area", (controlPoints: import("geojson").Position[], options?: TacticalArrowOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString | import("geojson").MultiPolygon, {
2512
+ part: "shaft" | "head";
2513
+ fill?: boolean;
2514
+ style?: StyleHints;
2515
+ }>>;
2516
+ encirclement: ControlMeasureDefinition<"encirclement", typeof createEncirclement>;
2517
+ area: ControlMeasureDefinition<"area", typeof createArea>;
2518
+ "area-defense": ControlMeasureDefinition<"area-defense", typeof createAreaDefense>;
2519
+ "assembly-area": ControlMeasureDefinition<"assembly-area", typeof createAssemblyArea>;
2520
+ "joint-tactical-action-area": ControlMeasureDefinition<"joint-tactical-action-area", typeof createJointTacticalActionArea>;
2521
+ "submarine-action-area": ControlMeasureDefinition<"submarine-action-area", typeof createSubmarineActionArea>;
2522
+ "submarine-generated-action-area": ControlMeasureDefinition<"submarine-generated-action-area", typeof createSubmarineGeneratedActionArea>;
2523
+ "drop-zone": ControlMeasureDefinition<"drop-zone", typeof createDropZone>;
2524
+ "extraction-zone": ControlMeasureDefinition<"extraction-zone", typeof createExtractionZone>;
2525
+ "landing-zone": ControlMeasureDefinition<"landing-zone", typeof createLandingZone>;
2526
+ "limited-access-area": ControlMeasureDefinition<"limited-access-area", typeof createLimitedAccessArea>;
2527
+ "no-fire-area-irregular": ControlMeasureDefinition<"no-fire-area-irregular", typeof createNoFireAreaIrregular>;
2528
+ "pickup-zone": ControlMeasureDefinition<"pickup-zone", typeof createPickupZone>;
2529
+ "assault-position": ControlMeasureDefinition<"assault-position", typeof createAssaultPosition>;
2530
+ "attack-position": ControlMeasureDefinition<"attack-position", typeof createAttackPosition>;
2531
+ "objective-area": ControlMeasureDefinition<"objective-area", typeof createObjectiveArea>;
2532
+ "area-of-operations": ControlMeasureDefinition<"area-of-operations", typeof createAreaOfOperations>;
2533
+ "named-area-of-interest": ControlMeasureDefinition<"named-area-of-interest", typeof createNamedAreaOfInterest>;
2534
+ "target-area-of-interest": ControlMeasureDefinition<"target-area-of-interest", typeof createTargetAreaOfInterest>;
2535
+ "airfield-zone": ControlMeasureDefinition<"airfield-zone", typeof createAirfieldZone>;
2536
+ "base-camp": ControlMeasureDefinition<"base-camp", typeof createBaseCamp>;
2537
+ "guerrilla-base": ControlMeasureDefinition<"guerrilla-base", typeof createGuerrillaBase>;
2538
+ "generic-c2-area": ControlMeasureDefinition<"generic-c2-area", typeof createGenericC2Area>;
2539
+ "main-attack": ControlMeasureDefinition<"main-attack", typeof createMainAttack>;
2540
+ "supporting-attack": ControlMeasureDefinition<"supporting-attack", typeof createSupportingAttack>;
2541
+ "classic-arrow": ControlMeasureDefinition<"classic-arrow", typeof createClassicArrow>;
2542
+ "block-arrow": ControlMeasureDefinition<"block-arrow", typeof createBlockArrow>;
2543
+ line: ControlMeasureDefinition<"line", typeof createGenericLine>;
2544
+ polygon: ControlMeasureDefinition<"polygon", typeof createGenericPolygon>;
2545
+ rectangle: ControlMeasureDefinition<"rectangle", typeof createGenericRectangle>;
2546
+ circle: ControlMeasureDefinition<"circle", typeof createGenericCircle>;
2547
+ text: ControlMeasureDefinition<"text", typeof createGenericText>;
2548
+ "airborne-attack": ControlMeasureDefinition<"airborne-attack", typeof createAirborneAttack>;
2549
+ "attack-helicopter": ControlMeasureDefinition<"attack-helicopter", typeof createAttackHelicopter>;
2550
+ "support-by-fire": ControlMeasureDefinition<"support-by-fire", typeof createSupportByFire>;
2551
+ "attack-by-fire": ControlMeasureDefinition<"attack-by-fire", typeof createAttackByFire>;
2552
+ flot: ControlMeasureDefinition<"flot", typeof createFLOT>;
2553
+ "phase-line": ControlMeasureDefinition<"phase-line", typeof createPhaseLine>;
2554
+ "handover-line": ControlMeasureDefinition<"handover-line", typeof createHandoverLine>;
2555
+ "battle-handover-line": ControlMeasureDefinition<"battle-handover-line", typeof createBattleHandoverLine>;
2556
+ "block-mission-task": ControlMeasureDefinition<"block-mission-task", typeof createBlockMissionTaskSymbol>;
2557
+ breach: ControlMeasureDefinition<"breach", typeof createBreachSymbol>;
2558
+ bypass: ControlMeasureDefinition<"bypass", typeof createBypassSymbol>;
2559
+ canalize: ControlMeasureDefinition<"canalize", typeof createCanalizeSymbol>;
2560
+ clear: ControlMeasureDefinition<"clear", typeof createClearSymbol>;
2561
+ cover: ControlMeasureDefinition<"cover", typeof createCoverSymbol>;
2562
+ delay: ControlMeasureDefinition<"delay", typeof createDelaySymbol>;
2563
+ guard: ControlMeasureDefinition<"guard", typeof createGuardSymbol>;
2564
+ isolate: ControlMeasureDefinition<"isolate", typeof createIsolateSymbol>;
2565
+ screen: ControlMeasureDefinition<"screen", typeof createScreenSymbol>;
2566
+ "antitank-ditch-under-construction": ControlMeasureDefinition<"antitank-ditch-under-construction", typeof createAntitankDitchUnderConstruction>;
2567
+ "antitank-ditch-completed": ControlMeasureDefinition<"antitank-ditch-completed", typeof createAntitankDitchCompleted>;
2568
+ "antitank-wall": ControlMeasureDefinition<"antitank-wall", typeof createAntitankWall>;
2569
+ "fortified-line": ControlMeasureDefinition<"fortified-line", typeof createFortifiedLine>;
2570
+ "fortified-area": ControlMeasureDefinition<"fortified-area", typeof createFortifiedArea>;
2571
+ "frontal-attack": ControlMeasureDefinition<"frontal-attack", typeof createFrontalAttack>;
2572
+ "turning-movement": ControlMeasureDefinition<"turning-movement", typeof createTurningMovement>;
2573
+ block: ControlMeasureDefinition<"block", typeof createBlock>;
2574
+ disrupt: ControlMeasureDefinition<"disrupt", typeof createDisrupt>;
2575
+ fix: ControlMeasureDefinition<"fix", typeof createFix>;
2576
+ turn: ControlMeasureDefinition<"turn", typeof createTurn>;
2577
+ "obstacle-bypass-easy": ControlMeasureDefinition<"obstacle-bypass-easy", typeof createObstacleBypassEasy>;
2578
+ "obstacle-bypass-difficult": ControlMeasureDefinition<"obstacle-bypass-difficult", typeof createObstacleBypassDifficult>;
2579
+ "obstacle-bypass-impossible": ControlMeasureDefinition<"obstacle-bypass-impossible", typeof createObstacleBypassImpossible>;
2580
+ };
2581
+ type Definitions = typeof DEFINITIONS;
2582
+ /** Stable string id of a control measure — the keys of {@link DEFINITIONS}. */
2583
+ type ControlMeasureId = keyof Definitions;
2584
+ /**
2585
+ * The discriminant for {@link ControlMeasure}. Identical to
2586
+ * {@link ControlMeasureId}; kept as a distinct name for the `<K extends
2587
+ * ControlMeasureKind>` generics threaded through rendering and edit sessions.
2588
+ */
2589
+ type ControlMeasureKind = ControlMeasureId;
2590
+ /** Strips the internal `validationMode` knob from a public options surface. */
2591
+ type PublicOptions<T> = Omit<T, "validationMode">;
2592
+ /**
2593
+ * The per-kind public options map, derived covariantly from each definition's
2594
+ * generator (see {@link OptsOf}). Empty-options kinds resolve to `{}` — exactly
2595
+ * as loose as the former hand-written table. See ADR-0013.
2596
+ */
2597
+ type OptionsByKind = { [K in keyof Definitions]: PublicOptions<OptsOf<Definitions[K]>> };
2598
+ /** Insertion-ordered list of every control-measure id. */
2599
+ declare const CONTROL_MEASURE_IDS: readonly ControlMeasureId[];
2600
+ declare const CONTROL_MEASURE_METADATA: Readonly<Record<ControlMeasureId, ControlMeasureMetadata>>;
2601
+ declare function listControlMeasureMetadata(): readonly ControlMeasureMetadata[];
2602
+ declare function getControlMeasureMetadata(id: ControlMeasureId): ControlMeasureMetadata;
2603
+ declare function getControlMeasureMetadataByValue(value: string): ControlMeasureMetadata | undefined;
2604
+ declare function getDefaultOptions<K extends ControlMeasureKind>(kind: K): OptionsByKind[K];
2605
+ //#endregion
2606
+ //#region src/instance.d.ts
2607
+ interface ControlMeasure<K extends ControlMeasureKind = ControlMeasureKind> {
2608
+ id: string;
2609
+ kind: K;
2610
+ controlPoints: Position[];
2611
+ options?: OptionsByKind[K];
2612
+ style?: ControlMeasureStyle;
2613
+ properties?: Record<string, unknown>;
2614
+ /** Free-text amplifier fields (MIL-STD-2525E Appendix L Table L-II); see `./text-amplifiers`. */
2615
+ textAmplifiers?: TextAmplifiers;
2616
+ /** Optional user-adjusted anchors for independently rendered text amplifiers. */
2617
+ amplifierPlacements?: AmplifierPlacements;
2618
+ schemaVersion?: 1;
2619
+ }
2620
+ declare function isKind<K extends ControlMeasureKind>(cm: ControlMeasure, kind: K): cm is ControlMeasure<K>;
2621
+ /**
2622
+ * Deep-clone a `ControlMeasure` so held references survive mutations to the
2623
+ * original (and vice versa). Used by the session façade to build the
2624
+ * `graphic` half of TacticalDraw's `GraphicSnapshot`. Nested values inside
2625
+ * `options`, `style`, `properties`, and `textAmplifiers` are cloned too —
2626
+ * `properties` is `Record<string, unknown>` and may carry arbitrary host
2627
+ * metadata, so a shallow copy would leak shared references.
2628
+ *
2629
+ * Backed by `structuredClone`: only structured-cloneable values are
2630
+ * supported (no functions, DOM nodes, class instances). Absent optional
2631
+ * fields stay absent on the clone.
2632
+ */
2633
+ declare function cloneControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>): ControlMeasure<K>;
2634
+ //#endregion
2635
+ //#region src/renderControlMeasure.d.ts
2636
+ interface RenderOptions {
2637
+ validationMode?: ValidationMode;
2638
+ /**
2639
+ * Façade-level default style (third / lowest-priority layer). Merged
2640
+ * shallowly under `cm.style` and any per-feature generator hint. When
2641
+ * omitted, style resolution matches the prior two-layer behavior.
2642
+ */
2643
+ graphicsStyle?: ControlMeasureStyle;
2644
+ }
2645
+ /**
2646
+ * Pure render: `ControlMeasure` → `ControlMeasureRender` (a
2647
+ * `FeatureCollection` of `FeaturePartProps`-typed features). Per-feature
2648
+ * stable ids follow `${cm.id}:${part}:${index}`. Style is resolved from the
2649
+ * three layers (graphicsStyle, cm.style, generator hint) and stamped on
2650
+ * `properties.style` when non-empty.
2651
+ */
2652
+ declare function renderControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>, opts?: RenderOptions): ControlMeasureRender;
2653
+ //#endregion
2654
+ //#region src/freeze-orientation.d.ts
2655
+ /**
2656
+ * Dispatches to a measure kind's `freezeOrientation` hook (see
2657
+ * {@link import("./define").ControlMeasureDefinition.freezeOrientation}),
2658
+ * pinning orientation-derived option defaults to their current concrete
2659
+ * values ahead of a rigid rotation of `controlPoints`. Returns `undefined`
2660
+ * when the kind declares no hook, or when the hook itself finds nothing to
2661
+ * freeze. Edit hosts call this when a rotate gesture starts (ADR-0023).
2662
+ */
2663
+ declare function freezeOrientationOptions<K extends ControlMeasureKind>(kind: K, controlPoints: Position[], options: OptionsByKind[K] | undefined): Partial<OptionsByKind[K]> | undefined;
2664
+ /**
2665
+ * Dispatches to a measure kind's `transformOptions` hook (see
2666
+ * {@link import("./define").ControlMeasureDefinition.transformOptions}), folding
2667
+ * a box transform gesture's `delta` (screen-space scale/rotation) into option
2668
+ * values for a graphic that persists orientation/size as options rather than in
2669
+ * geometry. Returns an options patch to merge, or `undefined` when the kind
2670
+ * declares no hook (or the hook finds nothing to fold). Edit hosts call this at
2671
+ * a rotate/scale gesture's commit (ADR-0017).
2672
+ */
2673
+ declare function applyBoxTransformOptions<K extends ControlMeasureKind>(kind: K, options: OptionsByKind[K] | undefined, delta: BoxTransformDelta): Partial<OptionsByKind[K]> | undefined;
2674
+ //#endregion
2675
+ //#region src/styleResolver.d.ts
2676
+ /**
2677
+ * Three-layer style precedence for `renderControlMeasure`.
2678
+ *
2679
+ * Lower-priority → higher-priority: `graphicsStyle` (façade default) →
2680
+ * `measureStyle` (`cm.style`) → `generatorStyle` (per-feature hint emitted
2681
+ * by a generator). Merge is shallow and per-property; higher-priority layers
2682
+ * win key by key. Explicit `null` / `undefined` in a higher-priority layer
2683
+ * is treated as "no opinion" and does not clear a lower-priority key.
2684
+ *
2685
+ * Returns `undefined` when all three layers are absent so the renderer can
2686
+ * omit `properties.style` entirely — keeps the no-style case byte-identical
2687
+ * to a property-less feature.
2688
+ *
2689
+ * Pure function: inputs are never mutated; the returned object is always a
2690
+ * fresh allocation when defined.
2691
+ */
2692
+ declare function resolveStyleHints(graphicsStyle: ControlMeasureStyle | undefined, measureStyle: ControlMeasureStyle | undefined, generatorStyle: StyleHints | undefined): StyleHints | undefined;
2693
+ //#endregion
2694
+ //#region src/toSimpleStyle.d.ts
2695
+ /**
2696
+ * simplestyle-spec properties (the subset this library can express), flat on
2697
+ * `properties`. All keys are optional.
2698
+ *
2699
+ * @see https://github.com/mapbox/simplestyle-spec
2700
+ */
2701
+ interface SimpleStyleProps extends FeaturePartProps {
2702
+ stroke?: string;
2703
+ "stroke-width"?: number;
2704
+ "stroke-opacity"?: number;
2705
+ fill?: string;
2706
+ "fill-opacity"?: number;
2707
+ }
2708
+ /**
2709
+ * A `FeatureCollection` whose features carry simplestyle-spec keys instead of
2710
+ * the nested `properties.style` slot. The `FeaturePartProps` stable-id
2711
+ * contract (`part`, `index`, `feature.id`) is preserved.
2712
+ */
2713
+ type SimpleStyleRender = FeatureCollection<Geometry, SimpleStyleProps>;
2714
+ /**
2715
+ * Lossy interop transform: `ControlMeasureRender` → a `FeatureCollection`
2716
+ * whose features carry simplestyle-spec keys. Operates on the already-resolved
2717
+ * per-feature `style`, so it composes after `renderControlMeasure`'s
2718
+ * three-layer merge and stays a pure post-processing step.
2719
+ *
2720
+ * Lossy mapping, by design:
2721
+ * - `strokeDash` and `fillPattern` have no simplestyle equivalent and are
2722
+ * dropped — dashed sub-lines and patterned fills render solid in
2723
+ * simplestyle consumers.
2724
+ * - colors must be hex or `rgb()/rgba()`; alpha becomes `*-opacity`. Other
2725
+ * color forms (named, `hsl()`) are omitted rather than guessed.
2726
+ */
2727
+ declare function toSimpleStyle(render: ControlMeasureRender): SimpleStyleRender;
2728
+ //#endregion
2729
+ //#region src/internal/graphics-utils.d.ts
2730
+ /**
2731
+ * Small value used to avoid division by zero and floating-point precision issues.
2732
+ */
2733
+ declare const EPSILON = 0.000001;
2734
+ /**
2735
+ * Rounds a number to a specified number of decimal places.
2736
+ */
2737
+ declare const roundToFixed: (v: number, precision?: number) => number;
2738
+ /**
2739
+ * Calculates the meters-per-pixel ratio at a given latitude and zoom level.
2740
+ *
2741
+ * This is essential for maintaining consistent visual sizes on the map
2742
+ * regardless of zoom level. The formula accounts for:
2743
+ * - The Web Mercator projection's tile-based structure
2744
+ * - The latitude-dependent scale distortion in Mercator projection
2745
+ *
2746
+ * @param latitude - The latitude in degrees (affects scale due to projection)
2747
+ * @param zoomLevel - The current map zoom level
2748
+ * @returns The number of meters represented by one pixel at the given location and zoom
2749
+ *
2750
+ * @example
2751
+ * ```typescript
2752
+ * // At zoom 10, latitude 45°
2753
+ * const mpp = getMetersPerPixel(45, 10);
2754
+ * // To get a 20-pixel radius in meters:
2755
+ * const radiusMeters = 20 * mpp;
2756
+ * ```
2757
+ */
2758
+ declare const getMetersPerPixel: (latitude: number, zoomLevel: number) => number;
2759
+ //#endregion
2760
+ //#region src/draw-rules/baseline-frame.d.ts
2761
+ type BaselineFrameOrigin = "p1" | "p2" | "midpoint";
2762
+ type BaselineFrameNormal = "right" | "left";
2763
+ interface BaselineFrameOptions {
2764
+ origin?: BaselineFrameOrigin;
2765
+ normal?: BaselineFrameNormal;
2766
+ }
2767
+ interface BaselineFrame {
2768
+ readonly p1: Point2D;
2769
+ readonly p2: Point2D;
2770
+ readonly origin: Point2D;
2771
+ readonly direction: Point2D;
2772
+ readonly normal: Point2D;
2773
+ readonly length: number;
2774
+ signedNormalDistance(point: Position): number;
2775
+ pointAtNormalDistance(distance: number): Position | null;
2776
+ }
2777
+ declare function createBaselineFrame(p1: Position, p2: Position, options?: BaselineFrameOptions): BaselineFrame | null;
2778
+ //#endregion
2779
+ //#region src/draw-rules/midpoint-perpendicular.d.ts
2780
+ interface MidpointPerpendicularDrawRuleOptions {
2781
+ id: string;
2782
+ defaultDistanceRatio?: number;
2783
+ /** User clicks required to commit. Defaults to `2` (the third point is auto-derived). */
2784
+ minimumUserPoints?: number;
2785
+ /** Raw points at which a live preview can be derived. See {@link ControlMeasureDrawRule}. */
2786
+ minimumPreviewPoints?: number;
2787
+ /**
2788
+ * Index of the slot whose point is constrained to the perpendicular axis
2789
+ * through the configured origin of the other two ("baseline") slots. Must be
2790
+ * `0` or `2`. Defaults to `2`.
2791
+ *
2792
+ * Area11 (Block) and Point12 (obstacle-bypass) use `2`: P1/P2 are the free
2793
+ * baseline endpoints and P3 is constrained. Area7 (Attack-By-Fire) uses `0`:
2794
+ * P1 is the constrained arrowhead tip and P2/P3 are the free back-line
2795
+ * endpoints.
2796
+ */
2797
+ constrainedIndex?: 0 | 2;
2798
+ /** Frame origin for the perpendicular axis. Defaults to `"midpoint"`. */
2799
+ origin?: BaselineFrameOrigin;
2800
+ /** Side the positive normal points to. Defaults to `"right"`. */
2801
+ normal?: BaselineFrameNormal;
2802
+ }
2803
+ declare function createMidpointPerpendicularDrawRule(options: MidpointPerpendicularDrawRuleOptions): ControlMeasureDrawRule;
2804
+ declare function computeDefaultMidpointPerpendicularPoint(p1: Position, p2: Position, distanceRatio?: number): Position | null;
2805
+ declare function getMidpointPerpendicularSignedDistance(p1: Position, p2: Position, controlPoint: Position): number | null;
2806
+ declare function pointOnMidpointPerpendicularAxis(p1: Position, p2: Position, distance: number | null): Position | null;
2807
+ declare function snapToMidpointPerpendicular(p1: Position, p2: Position, controlPoint: Position): Position | null;
2808
+ //#endregion
2809
+ //#region src/draw-rules/area11.d.ts
2810
+ declare const blockDrawRule: ControlMeasureDrawRule;
2811
+ //#endregion
2812
+ //#region src/draw-rules/area12.d.ts
2813
+ /**
2814
+ * Area12 anchor draw rule for Disrupt.
2815
+ *
2816
+ * P1/P2 are the free spine endpoints. P3 is the longest-arrow tip, constrained
2817
+ * to the perpendicular axis through P1 (not the baseline midpoint).
2818
+ */
2819
+ declare const disruptDrawRule: ControlMeasureDrawRule;
2820
+ //#endregion
2821
+ //#region src/draw-rules/area15.d.ts
2822
+ declare const centerRadiusDrawRule: ControlMeasureDrawRule;
2823
+ //#endregion
2824
+ //#region src/draw-rules/point12.d.ts
2825
+ /**
2826
+ * Point12 anchor draw rule for the obstacle-bypass family.
2827
+ *
2828
+ * Shared by `obstacle-bypass-easy`, `obstacle-bypass-difficult`, and
2829
+ * `obstacle-bypass-impossible`: P1/P2 are the arrowhead tips and define the
2830
+ * opening; P3 is constrained to the perpendicular axis through
2831
+ * `midpoint(P1, P2)` and defines the rear of the symbol. Rear-line decoration
2832
+ * (plain, zigzag, barrier marks) is a generator concern, not a draw-rule one.
2833
+ */
2834
+ declare const point12DrawRule: ControlMeasureDrawRule;
2835
+ //#endregion
2836
+ //#region src/draw-rules/area7.d.ts
2837
+ /**
2838
+ * Area7 anchor draw rule for Attack By Fire.
2839
+ *
2840
+ * P2/P3 are the free back-line endpoints; P1 (slot index 0) is the arrowhead
2841
+ * tip, constrained to the perpendicular axis through `midpoint(P2, P3)`.
2842
+ */
2843
+ declare const attackByFireDrawRule: ControlMeasureDrawRule;
2844
+ //#endregion
2845
+ //#region src/draw-rules/line29.d.ts
2846
+ /**
2847
+ * Line29 anchor draw rule for Ambush.
2848
+ *
2849
+ * P2/P3 are the free back-line endpoints; P1 (slot index 0) is the arrowhead
2850
+ * tip, constrained to the perpendicular axis through `midpoint(P2, P3)`.
2851
+ */
2852
+ declare const ambushDrawRule: ControlMeasureDrawRule;
2853
+ //#endregion
2854
+ //#region src/draw-rules/line1.d.ts
2855
+ declare const line1DrawRule: ControlMeasureDrawRule;
2856
+ //#endregion
2857
+ //#region src/draw-rules/line10.d.ts
2858
+ /**
2859
+ * Line10 — PT1 is the arrow tip, PT2 is the rear, and derived PT3 selects
2860
+ * which side of the PT2 -> PT1 chord contains the 90-degree arc.
2861
+ */
2862
+ declare const turnDrawRule: ControlMeasureDrawRule;
2863
+ //#endregion
2864
+ //#region src/draw-rules/line23.d.ts
2865
+ /**
2866
+ * Line23 anchor draw rule for the Clear mission task.
2867
+ *
2868
+ * P1/P2 are the endpoints of the symbol's vertical line (its height); P3 is
2869
+ * constrained to the perpendicular axis through `midpoint(P1, P2)` and defines
2870
+ * the rear of the symbol (the shaft length). Geometrically identical to the
2871
+ * obstacle-bypass `Point12` rule, but kept as its own spec id to match the
2872
+ * doctrinal draw rule for Clear.
2873
+ */
2874
+ declare const line23DrawRule: ControlMeasureDrawRule;
2875
+ //#endregion
2876
+ //#region src/draw-rules/line24.d.ts
2877
+ /**
2878
+ * Line24 anchor draw rule for the Delay mission task.
2879
+ *
2880
+ * PT. 1 and PT. 2 are the free straight-line endpoints. PT. 3 is constrained to
2881
+ * the perpendicular axis through PT. 2, where its signed distance from PT. 2
2882
+ * defines the semicircular arc diameter and side. Unlike the sibling Line23
2883
+ * (Clear) rule, the third point must be placed explicitly (three user clicks),
2884
+ * with a two-point live preview before commit.
2885
+ */
2886
+ declare const line24DrawRule: ControlMeasureDrawRule;
2887
+ //#endregion
2888
+ //#region src/draw-rules/line26.d.ts
2889
+ /**
2890
+ * Line26 anchor draw rule for the Cover, Guard, and Screen security tasks.
2891
+ *
2892
+ * PT. 1/PT. 4 are the outward arrow tips and PT. 2/PT. 3 bound the opening
2893
+ * reserved for the supported tactical symbol. All four anchors are free: the
2894
+ * two sides may independently touch the symbols that define the task limits.
2895
+ * During drawing, the cursor after PT. 1 supplies a provisional PT. 2 and the
2896
+ * rule mirrors that first leg across a temporary center opening, so the full
2897
+ * symbol is visible before PT. 2 is committed.
2898
+ */
2899
+ declare const line26DrawRule: ControlMeasureDrawRule;
2900
+ //#endregion
2901
+ //#region src/draw-rules/area8.d.ts
2902
+ declare const supportByFireDrawRule: ControlMeasureDrawRule;
2903
+ //#endregion
2904
+ //#region src/draw-rules/axis1.d.ts
2905
+ declare const axis1DrawRule: ControlMeasureDrawRule;
2906
+ //#endregion
2907
+ //#region src/draw-rules/rectangle.d.ts
2908
+ declare const rectangleDrawRule: ControlMeasureDrawRule;
2909
+ //#endregion
2910
+ //#region src/generators/cm14-maneuver-lines/ambush.d.ts
2911
+ /**
2912
+ * Configuration options for the Ambush tactical symbol.
2913
+ */
2914
+ interface AmbushOptions {
2915
+ /** Number of segments used to draw the quadratic curve (default: 30) */
2916
+ arcSegments?: number;
2917
+ /** Size of arrowhead relative to chord span (default: 0.15) */
2918
+ arrowheadLengthRatio?: number;
2919
+ /** Width of arrowhead wings relative to its length (default: 0.5) */
2920
+ arrowheadWidthRatio?: number;
2921
+ /** Length of parallel hatches relative to chord span (default: 0.15) */
2922
+ hatchLengthRatio?: number;
2923
+ /** Number of parallel hatches along the curve (default: 5) */
2924
+ hatchCount?: number;
2925
+ /** Depth of the curve toward PT 1 relative to chord span (default: 0.25) */
2926
+ curveDepthRatio?: number;
2927
+ }
2928
+ declare const DEFAULT_AMBUSH_OPTIONS: Required<AmbushOptions>;
2929
+ //#endregion
2930
+ export { DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS as $, DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS as $n, DEFAULT_SUPPORT_BY_FIRE_OPTIONS as $t, roundToFixed as A, PickupZoneOptions as An, CanonicalTextAmplifiers as Ar, DEFAULT_COVER_OPTIONS as At, cloneControlMeasure as B, EncirclementOptions as Bn, AnchorTransformEvent as Br, DEFAULT_BREACH_OPTIONS as Bt, BaselineFrame as C, DEFAULT_MAIN_ATTACK_OPTIONS as Cn, ControlMeasureGeometryType as Cr, DEFAULT_SCREEN_OPTIONS as Ct, createBaselineFrame as D, AreaOfOperationsOptions as Dn, TextAmplifierDescriptor as Dr, DEFAULT_DELAY_OPTIONS as Dt, BaselineFrameOrigin as E, computeInitialWidthPoint as En, ParamDescriptor as Er, GuardOptions as Et, applyBoxTransformOptions as F, AssemblyAreaOptions as Fn, TextAmplifierKey as Fr, CanalizeOptions as Ft, ControlMeasureKind as G, StyleHints as Gn, DEFAULT_HANDOVER_LINE_OPTIONS as Gt, CONTROL_MEASURE_IDS as H, FinalProtectiveFireOptions as Hn, DEFAULT_BLOCK_MISSION_TASK_OPTIONS as Ht, freezeOrientationOptions as I, DEFAULT_ASSEMBLY_AREA_OPTIONS as In, TextAmplifiers as Ir, DEFAULT_CANALIZE_OPTIONS as It, getControlMeasureMetadataByValue as J, PrincipalDirectionOfFireOptions as Jn, PhaseLineOptions as Jt, OptionsByKind as K, controlMeasureIdFromFeature as Kn, HandoverLineOptions as Kt, RenderOptions as L, AreaDefenseOptions as Ln, canonicalTextAmplifierKey as Lr, BypassOptions as Lt, SimpleStyleRender as M, LandingZoneOptions as Mn, LabelPlacementOverride as Mr, TacticalArrowOptions as Mt, toSimpleStyle as N, DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS as Nn, TEXT_AMPLIFIER_FIELDS as Nr, ClearOptions as Nt, EPSILON as O, DEFAULT_AREA_OF_OPERATIONS_OPTIONS as On, AmplifierPlacement as Or, DelayOptions as Ot, resolveStyleHints as P, JointTacticalActionAreaOptions as Pn, TextAmplifierField as Pr, DEFAULT_CLEAR_OPTIONS as Pt, ObstacleBypassImpossibleOptions as Q, DirectionOfMainAttackOptions as Qn, DEFAULT_ATTACK_BY_FIRE_OPTIONS as Qt, renderControlMeasure as R, DEFAULT_AREA_DEFENSE_OPTIONS as Rn, normalizeTextAmplifiers as Rr, DEFAULT_BYPASS_OPTIONS as Rt, snapToMidpointPerpendicular as S, SupportingAttackOptions as Sn, ControlMeasureGeometry as Sr, DEFAULT_ANTITANK_DITCH_OPTIONS as St, BaselineFrameOptions as T, calculateMetrics as Tn, ControlMeasurePaintCapability as Tr, DEFAULT_GUARD_OPTIONS as Tt, CONTROL_MEASURE_METADATA as U, ControlMeasureRender as Un, BattleHandoverLineOptions as Ut, isKind as V, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS as Vn, ControlMeasureDrawRule as Vr, BlockMissionTaskOptions as Vt, ControlMeasureId as W, FeaturePartProps as Wn, DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS as Wt, listControlMeasureMetadata as X, DirectionOfSupportingAttackOptions as Xn, FLOTOptions as Xt, getDefaultOptions as Y, DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS as Yn, DEFAULT_FLOT_OPTIONS as Yt, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS as Z, DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS as Zn, AttackByFireOptions as Zt, MidpointPerpendicularDrawRuleOptions as _, DEFAULT_BLOCK_ARROW_OPTIONS as _n, unproject as _r, DEFAULT_FORTIFIED_LINE_OPTIONS as _t, supportByFireDrawRule as a, DEFAULT_GENERIC_TEXT_OPTIONS as an, ControlMeasureStyle as ar, DEFAULT_FIX_OPTIONS as at, getMidpointPerpendicularSignedDistance as b, DEFAULT_CLASSIC_ARROW_OPTIONS as bn, BoxTransformDelta as br, DEFAULT_ANTITANK_WALL_OPTIONS as bt, line23DrawRule as c, GenericCircleOptions as cn, GenericC2LineOptions as cr, DisruptOptions as ct, ambushDrawRule as d, DEFAULT_GENERIC_POLYGON_OPTIONS as dn, DEFAULT_LIGHT_LINE_OPTIONS as dr, DEFAULT_TURNING_MOVEMENT_OPTIONS as dt, SupportByFireOptions as en, DirectionOfAttackAviationOptions as er, ObstacleBypassDifficultOptions as et, attackByFireDrawRule as f, GenericPolygonOptions as fn, LightLineOptions as fr, TurningMovementOptions as ft, blockDrawRule as g, BlockArrowOptions as gn, project as gr, FortifiedAreaOptions as gt, disruptDrawRule as h, BlockArrowHeadStyle as hn, haversineDistance as hr, DEFAULT_FORTIFIED_AREA_OPTIONS as ht, axis1DrawRule as i, DEFAULT_AIRBORNE_ATTACK_OPTIONS as in, DEFAULT_BATTLE_POSITION_OPTIONS as ir, TurnOptions as it, SimpleStyleProps as j, DEFAULT_LANDING_ZONE_OPTIONS as jn, GeneratedLabelKey as jr, DEFAULT_TACTICAL_ARROW_OPTIONS as jt, getMetersPerPixel as k, DEFAULT_PICKUP_ZONE_OPTIONS as kn, AmplifierPlacements as kr, CoverOptions as kt, turnDrawRule as l, DEFAULT_GENERIC_RECTANGLE_OPTIONS as ln, DEFAULT_ENGINEER_WORK_LINE_OPTIONS as lr, BlockOptions as lt, centerRadiusDrawRule as m, GenericLineOptions as mn, Point2D as mr, FrontalAttackOptions as mt, DEFAULT_AMBUSH_OPTIONS as n, DEFAULT_ATTACK_HELICOPTER_OPTIONS as nn, StrongPointOptions as nr, ObstacleBypassEasyOptions as nt, line26DrawRule as o, GenericTextOptions as on, FillPattern as or, FixOptions as ot, point12DrawRule as p, DEFAULT_GENERIC_LINE_OPTIONS as pn, LabelSizeOptions as pr, DEFAULT_FRONTAL_ATTACK_OPTIONS as pt, getControlMeasureMetadata as q, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS as qn, DEFAULT_PHASE_LINE_OPTIONS as qt, rectangleDrawRule as r, AirborneAttackOptions as rn, BattlePositionOptions as rr, DEFAULT_TURN_OPTIONS as rt, line24DrawRule as s, DEFAULT_GENERIC_CIRCLE_OPTIONS as sn, DEFAULT_GENERIC_C2_LINE_OPTIONS as sr, DEFAULT_DISRUPT_OPTIONS as st, AmbushOptions as t, AttackHelicopterOptions as tn, DEFAULT_STRONG_POINT_OPTIONS as tr, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS as tt, line1DrawRule as u, GenericRectangleOptions as un, EngineerWorkLineOptions as ur, DEFAULT_BLOCK_OPTIONS as ut, computeDefaultMidpointPerpendicularPoint as v, ClassicArrowHeadStyle as vn, BoundaryOptions as vr, FortifiedLineOptions as vt, BaselineFrameNormal as w, MainAttackOptions as wn, ControlMeasureMetadata as wr, ScreenOptions as wt, pointOnMidpointPerpendicularAxis as x, DEFAULT_SUPPORTING_ATTACK_OPTIONS as xn, ControlMeasureFillCapability as xr, AntitankDitchOptions as xt, createMidpointPerpendicularDrawRule as y, ClassicArrowOptions as yn, DEFAULT_BOUNDARY_OPTIONS as yr, AntitankWallOptions as yt, ControlMeasure as z, DEFAULT_ENCIRCLEMENT_OPTIONS as zn, resolveAmplifierPlacement as zr, BreachOptions as zt };