@orbat-mapper/control-measures 0.2.0-alpha.9 → 0.2.0

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 (88) hide show
  1. package/README.md +49 -0
  2. package/dist/{index-26Xb77jE.d.mts → index-DtgRm_dz.d.mts} +1313 -255
  3. package/dist/index.d.mts +2 -2
  4. package/dist/index.mjs +20 -5
  5. package/dist/preview/index.d.mts +114 -3
  6. package/dist/preview/index.mjs +242 -23
  7. package/dist/{renderControlMeasure-CFdgTURO.mjs → renderControlMeasure-CAfC2nEw.mjs} +9570 -3988
  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 -1
  33. package/media/classic-arrow.svg +1 -1
  34. package/media/clear.svg +1 -1
  35. package/media/counterattack.svg +1 -0
  36. package/media/cover.svg +1 -0
  37. package/media/delay.svg +1 -1
  38. package/media/direction-of-attack-aviation.svg +1 -0
  39. package/media/direction-of-main-attack.svg +1 -0
  40. package/media/direction-of-supporting-attack.svg +1 -0
  41. package/media/disrupt.svg +1 -1
  42. package/media/drop-zone.svg +1 -0
  43. package/media/encirclement.svg +1 -1
  44. package/media/engineer-work-line.svg +1 -0
  45. package/media/extraction-zone.svg +1 -0
  46. package/media/final-protective-fire-left.svg +1 -1
  47. package/media/final-protective-fire-right.svg +1 -1
  48. package/media/fix.svg +1 -1
  49. package/media/flot.svg +1 -1
  50. package/media/fortified-area.svg +1 -1
  51. package/media/fortified-line.svg +1 -1
  52. package/media/forward-edge-of-battle-area.svg +1 -0
  53. package/media/frontal-attack.svg +1 -0
  54. package/media/generic-c2-area.svg +1 -0
  55. package/media/generic-c2-line.svg +1 -0
  56. package/media/guard.svg +1 -0
  57. package/media/guerrilla-base.svg +1 -0
  58. package/media/handover-line.svg +1 -0
  59. package/media/isolate.svg +1 -1
  60. package/media/joint-tactical-action-area.svg +1 -0
  61. package/media/landing-zone.svg +1 -0
  62. package/media/light-line.svg +1 -0
  63. package/media/limited-access-area.svg +1 -0
  64. package/media/line.svg +1 -1
  65. package/media/main-attack.svg +1 -1
  66. package/media/named-area-of-interest.svg +1 -0
  67. package/media/no-fire-area-irregular.svg +1 -0
  68. package/media/objective-area.svg +1 -0
  69. package/media/obstacle-bypass-difficult.svg +1 -1
  70. package/media/obstacle-bypass-easy.svg +1 -1
  71. package/media/obstacle-bypass-impossible.svg +1 -1
  72. package/media/phase-line.svg +1 -0
  73. package/media/pickup-zone.svg +1 -0
  74. package/media/polygon.svg +1 -1
  75. package/media/principal-direction-of-fire.svg +1 -1
  76. package/media/rectangle.svg +1 -1
  77. package/media/screen.svg +1 -0
  78. package/media/search-area.svg +1 -1
  79. package/media/secondary-direction-of-fire.svg +1 -0
  80. package/media/strong-point.svg +1 -1
  81. package/media/submarine-action-area.svg +1 -0
  82. package/media/submarine-generated-action-area.svg +1 -0
  83. package/media/support-by-fire.svg +1 -1
  84. package/media/supporting-attack.svg +1 -1
  85. package/media/target-area-of-interest.svg +1 -0
  86. package/media/turn.svg +1 -1
  87. package/media/turning-movement.svg +1 -0
  88. package/package.json +1 -1
@@ -23,6 +23,13 @@ interface ControlMeasureDrawRule {
23
23
  * `minimumUserPoints` (no early preview).
24
24
  */
25
25
  readonly minimumPreviewPoints?: number;
26
+ /**
27
+ * Let a repeat click on the latest point commit the rule's early derived
28
+ * preview before `minimumUserPoints` raw anchors have been placed. Use only
29
+ * when `derive` produces a meaningful default canonical shape from
30
+ * `minimumPreviewPoints` points.
31
+ */
32
+ readonly finishOnLastPointRepeat?: boolean;
26
33
  /**
27
34
  * Opt a fixed-length draw into the standard dashed interaction guide. Fixed
28
35
  * shapes suppress guides by default because their generator preview is
@@ -145,6 +152,37 @@ type FriendlyKey = `${FriendlyName}${Suffix}`;
145
152
  * this is resolved to canonical form.
146
153
  */
147
154
  type TextAmplifiers = Partial<Record<TextAmplifierKey | FriendlyKey, string>>;
155
+ /**
156
+ * Stable key for a non-amplifier generated label. The renderer assigns these
157
+ * from the label's part and per-part label ordinal when a generator has not
158
+ * supplied a doctrinal field key. Generators that can change a label's order
159
+ * should supply an explicit `labelPlacementKey` instead.
160
+ */
161
+ type GeneratedLabelKey = `label:${string}`;
162
+ /**
163
+ * Object form of a per-label override. `rotation` is in stored radians — the
164
+ * same convention as `FeaturePartProps.rotation` (adapters render the
165
+ * on-screen angle as `π − rotation`).
166
+ */
167
+ interface LabelPlacementOverride {
168
+ position?: Position;
169
+ rotation?: number;
170
+ }
171
+ /** A per-label override: a bare anchor (legacy shorthand) or the object form. */
172
+ type AmplifierPlacement = Position | LabelPlacementOverride;
173
+ /**
174
+ * User-adjusted anchor positions (and, optionally, rotations) for doctrinal
175
+ * and generated text labels, keyed by a canonical `TextAmplifierKey` or a
176
+ * synthesized `GeneratedLabelKey`.
177
+ */
178
+ type AmplifierPlacements = Record<string, AmplifierPlacement | undefined>;
179
+ /**
180
+ * Resolves a raw placement entry to its object form: a bare `Position` is
181
+ * legacy shorthand for `{ position }`; an object form passes through only the
182
+ * fields that are actually valid (`position` must be a finite `[lon, lat]`,
183
+ * `rotation` a finite number); `undefined` resolves to `{}`.
184
+ */
185
+ declare function resolveAmplifierPlacement(value: AmplifierPlacement | undefined): LabelPlacementOverride;
148
186
  /** Amplifier values resolved to canonical doctrinal keys, as generators receive them. */
149
187
  type CanonicalTextAmplifiers = Readonly<Partial<Record<TextAmplifierKey, string>>>;
150
188
  /**
@@ -174,7 +212,7 @@ declare function normalizeTextAmplifiers(input: TextAmplifiers | undefined): Can
174
212
  //#region src/metadata.d.ts
175
213
  type ControlMeasureGeometryType = Geometry["type"];
176
214
  type ControlMeasureGeometry = "point" | "line" | "area";
177
- declare const DRAW_RULE_IDS: readonly ["Area1", "Area7", "Area8", "Area11", "Area12", "Area15", "Area21", "Axis1", "Line1", "Line3", "Line9", "Line10", "Line23", "Line24", "Line29", "Point12", "Rectangle"];
215
+ 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"];
178
216
  type DrawRuleId = (typeof DRAW_RULE_IDS)[number];
179
217
  interface BaseParamDescriptor {
180
218
  key: string;
@@ -206,6 +244,20 @@ interface TextParamDescriptor extends BaseParamDescriptor {
206
244
  type: "text";
207
245
  placeholder?: string;
208
246
  maxLength?: number;
247
+ /**
248
+ * The doctrinal Table L-II field this free-text option renders (e.g.
249
+ * `phaseLineName` renders field `T`) — lets metadata-driven UIs (e.g. a
250
+ * label-placement preview) substitute a `<T>`-style placeholder for the
251
+ * option, the same way a `TextAmplifierDescriptor` does for a real
252
+ * amplifier field.
253
+ */
254
+ field?: TextAmplifierField;
255
+ /**
256
+ * Whether the value may contain explicit line breaks that a metadata-driven
257
+ * editor should let the user enter directly (a multi-row textarea rather
258
+ * than a single-line input), e.g. the generic Text measure's `text` option.
259
+ */
260
+ multiline?: boolean;
209
261
  }
210
262
  type ParamDescriptor = NumberParamDescriptor | BooleanParamDescriptor | ColorParamDescriptor | TextParamDescriptor | EnumParamDescriptor;
211
263
  /** Editor-facing description of one text amplifier field a measure accepts. */
@@ -248,6 +300,40 @@ interface ControlMeasureMetadata {
248
300
  * definition means adding such a measure stays a one-file change (ADR-0013).
249
301
  */
250
302
  capturesLabelSize?: boolean;
303
+ /**
304
+ * Static, per-kind declaration of what a rendered instance can paint — used
305
+ * by a host editor to decide which style controls (stroke color/width,
306
+ * fill toggle/pattern/color, text color) are meaningful to show for this
307
+ * kind. It describes the *kind*, not a particular instance: a `filled`
308
+ * boolean option still governs whether any given instance is actually
309
+ * filled, this only says whether fill control is meaningful at all.
310
+ */
311
+ paints: ControlMeasurePaintCapability;
312
+ }
313
+ /**
314
+ * A control measure's fill capability, per {@link ControlMeasurePaintCapability.fill}.
315
+ *
316
+ * - `"none"` — no emitted part is ever filled; a fill/fillColor/fillPattern
317
+ * control would be inert.
318
+ * - `"fixed"` — a filled part exists, but the generator pins its
319
+ * `fillPattern` (a solid accent like an echelon marker, or a doctrinal
320
+ * hatch like Limited Access Area's back-hatch) — `cm.style.fillPattern`
321
+ * never reaches it. `fillColor` is *not* pinned, so a fill color override
322
+ * still reaches the part; only the pattern control is inert.
323
+ * - `"user"` — a filled part exists whose pattern the generator leaves
324
+ * unset, so `cm.style.fillPattern` reaches the output. These are exactly
325
+ * the kinds governed by a `filled` boolean {@link ParamDescriptor}
326
+ * (polygon, rectangle, circle, block-arrow).
327
+ */
328
+ type ControlMeasureFillCapability = "none" | "fixed" | "user";
329
+ /** What a rendered control-measure kind can paint — see {@link ControlMeasureMetadata.paints}. */
330
+ interface ControlMeasurePaintCapability {
331
+ /** Whether any emitted part is stroked (non-Point) geometry — gates a stroke color/width control. */
332
+ stroke: boolean;
333
+ /** Whether/how any emitted part is filled — see {@link ControlMeasureFillCapability}. */
334
+ fill: ControlMeasureFillCapability;
335
+ /** Whether the kind emits text label features — gates a text color control. */
336
+ text: boolean;
251
337
  }
252
338
  //#endregion
253
339
  //#region src/define.d.ts
@@ -256,6 +342,10 @@ interface ControlMeasureMetadata {
256
342
  * geometry, with per-feature properties that the renderer normalizes.
257
343
  */
258
344
  type AnyFeatureCollection = FeatureCollection<Geometry, Record<string, unknown> | null>;
345
+ /** Read-only instance state that can affect generated geometry. */
346
+ interface ControlMeasureGeneratorContext {
347
+ amplifierPlacements?: AmplifierPlacements;
348
+ }
259
349
  /**
260
350
  * A generator's call signature, constrained only by its inputs and output. The
261
351
  * options parameter is typed `never` so that a generator with *any* concrete
@@ -266,9 +356,11 @@ type AnyFeatureCollection = FeatureCollection<Geometry, Record<string, unknown>
266
356
  *
267
357
  * The optional third parameter carries the instance's normalized text
268
358
  * amplifiers (ADR-0027); a generator that ignores text amplifiers just omits
269
- * the parameter — fewer params is still assignable to this bound.
359
+ * the parameter. The optional fourth parameter carries instance state needed
360
+ * while generating geometry derived from an individual label placement.
361
+ * Generators may omit either trailing parameter.
270
362
  */
271
- type ControlMeasureGenerator = (controlPoints: Position[], options: never, textAmplifiers?: CanonicalTextAmplifiers) => AnyFeatureCollection;
363
+ type ControlMeasureGenerator = (controlPoints: Position[], options: never, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext) => AnyFeatureCollection;
272
364
  /**
273
365
  * Everything that defines one control measure, co-located with its generator.
274
366
  * `registry.ts` collects these into the single `DEFINITIONS` map, from which
@@ -314,6 +406,30 @@ interface ControlMeasureDefinition<Id extends string, G extends ControlMeasureGe
314
406
  * against the new orientation. See ADR-0023.
315
407
  */
316
408
  freezeOrientation?: (controlPoints: Position[], options: NonNullable<Parameters<G>[1]>) => Partial<NonNullable<Parameters<G>[1]>> | undefined;
409
+ /**
410
+ * Folds a box transform gesture's screen-space delta into option values for a
411
+ * graphic that persists orientation and/or size as options rather than in its
412
+ * geometry — single-point graphics (e.g. Text) have no geometry to encode
413
+ * them. Returns an options patch to merge onto the working options, or
414
+ * `undefined` when the kind carries no such option (or the delta is inert).
415
+ * Edit hosts call this at a rotate/scale gesture's commit, alongside the rigid
416
+ * transform of the control points, so the persisted rotation/size follow the
417
+ * box. The measure owns the unit/sign conversion (e.g. Text stores degrees
418
+ * clockwise-on-screen while the delta is radians). See ADR-0017/0023.
419
+ */
420
+ transformOptions?: (options: NonNullable<Parameters<G>[1]>, delta: BoxTransformDelta) => Partial<NonNullable<Parameters<G>[1]>> | undefined;
421
+ }
422
+ /**
423
+ * A box transform gesture's screen-space delta, folded into orientation- and
424
+ * size-carrying options by {@link ControlMeasureDefinition.transformOptions}.
425
+ * The transform box (ADR-0017) is the source: `scale` is the uniform corner
426
+ * -scale factor (`1` = no scaling), `rotationRadians` the rotate-grip delta
427
+ * (positive = clockwise on screen, matching the box angle convention; `0` = no
428
+ * rotation). A body translate reports neither (`{ scale: 1, rotationRadians: 0 }`).
429
+ */
430
+ interface BoxTransformDelta {
431
+ scale: number;
432
+ rotationRadians: number;
317
433
  }
318
434
  /**
319
435
  * A measure's representative preview input. Shared between the typed
@@ -324,6 +440,12 @@ interface ControlMeasureDefinition<Id extends string, G extends ControlMeasureGe
324
440
  interface PreviewSample<Options> {
325
441
  controlPoints: readonly (readonly [number, number])[];
326
442
  options?: Partial<Options>;
443
+ /**
444
+ * Sample text amplifiers (ADR-0027) rendered onto the representative
445
+ * preview, for measures whose doctrinal appearance is carried by amplifier
446
+ * text (e.g. Boundary-style end/center labels) rather than options alone.
447
+ */
448
+ textAmplifiers?: TextAmplifiers;
327
449
  }
328
450
  /**
329
451
  * Extracts a definition's options type covariantly from its generator's
@@ -369,23 +491,10 @@ interface BoundaryOptions {
369
491
  * lock the T/AS text size to the glyph height.
370
492
  */
371
493
  metersPerPixel?: number;
372
- /**
373
- * Map zoom captured at draw-commit (`capturesLabelSize`). Forwarded onto the
374
- * T/AS labels as `textSizeZoom` so a ground-anchored boundary's text scales
375
- * with zoom like its meter-baked echelon glyph (maplibre).
376
- */
377
- labelSizeZoom?: number;
378
- /**
379
- * Map resolution (meters-per-pixel) captured at draw-commit
380
- * (`capturesLabelSize`). Forwarded onto the T/AS labels as `textSizeResolution`
381
- * so a ground-anchored boundary's text scales with zoom (OpenLayers), and used
382
- * as the reference resolution that sizes the text to the glyph height.
383
- */
384
- labelSizeResolution?: number;
385
494
  /**
386
495
  * Number of label groups (echelon + designators), spaced evenly by cumulative
387
- * arc length along the whole boundary. `1` places a single group at the
388
- * midpoint of the total length (which may fall on any segment).
496
+ * arc length along the whole boundary. `1` places a single group at
497
+ * `labelPosition`, whose default is the midpoint of the total length.
389
498
  * @default 1
390
499
  */
391
500
  labelRepetitions?: number;
@@ -397,6 +506,13 @@ interface BoundaryOptions {
397
506
  * @default 1
398
507
  */
399
508
  labelSpacing?: number;
509
+ /**
510
+ * Position of a single label group as a fraction of cumulative arc length
511
+ * from the boundary's first control point (0) to its last (1). Ignored when
512
+ * `labelRepetitions > 1`.
513
+ * @default 0.5
514
+ */
515
+ labelPosition?: number;
400
516
  /**
401
517
  * Clearance between the line/echelon glyph and the unit labels, as a ratio
402
518
  * of the echelon glyph height (like `echelonPadding`). In `"along"` mode
@@ -450,9 +566,269 @@ declare const DEFAULT_BOUNDARY_OPTIONS: BoundaryOptions;
450
566
  */
451
567
  declare function createBoundary(positions: Position[], options?: BoundaryOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | MultiPolygon | Point>;
452
568
  //#endregion
569
+ //#region src/projection.d.ts
570
+ type Point2D = [number, number];
571
+ /**
572
+ * Project WGS84 (Lon/Lat) to Web Mercator (Meters).
573
+ */
574
+ declare const project: (lon: number, lat: number) => Point2D;
575
+ /**
576
+ * Unproject Web Mercator (Meters) back to WGS84 (Lon/Lat).
577
+ */
578
+ declare const unproject: (x: number, y: number) => Position;
579
+ /**
580
+ * Great-circle distance in meters between two lon/lat positions (haversine on
581
+ * the WGS84 mean-radius sphere). Accurate at all scales — use this for
582
+ * measurement readouts (segment lengths, radii). Most generators still build
583
+ * geometry in projected Web Mercator meters, so at high latitudes a graphic's
584
+ * Mercator dimensions can exceed the true ground distance this returns; the
585
+ * generic circle is the exception — it samples at constant geodesic radius,
586
+ * so its ring and this readout agree exactly.
587
+ */
588
+ declare const haversineDistance: (a: Position, b: Position) => number;
589
+ //#endregion
590
+ //#region src/internal/sketch.d.ts
591
+ /**
592
+ * Shared `smooth`/`smoothResolution` option pair for free n-point polyline
593
+ * measures (draw rule Line1): curves the rendered path through the control
594
+ * points via a centripetal Catmull-Rom spline. The spline preserves the
595
+ * endpoints, so the line still meets its drawn anchors, and is a no-op for
596
+ * fewer than three control points (a single segment cannot be smoothed).
597
+ */
598
+ interface SmoothLineOptions {
599
+ /**
600
+ * Round the line's corners by curving the path through the control points
601
+ * (centripetal Catmull-Rom spline). The spline preserves the endpoints, so
602
+ * the line still meets its drawn anchors.
603
+ * @default false
604
+ */
605
+ smooth?: boolean;
606
+ /**
607
+ * Number of samples per segment when `smooth` is enabled. Higher values
608
+ * yield a denser, smoother curve.
609
+ * @default (varies per measure)
610
+ */
611
+ smoothResolution?: number;
612
+ }
613
+ //#endregion
614
+ //#region src/internal/line-labels.d.ts
615
+ /**
616
+ * Label sizing per the size-anchor model (ADR-0020, ADR-0028): the presence of
617
+ * `labelSizePixels` marks the labels screen-anchored; `labelSize` alone is
618
+ * ground-anchored. Carrying both behaves screen-anchored (pixels win),
619
+ * matching the geometry options' precedence.
620
+ */
621
+ interface LabelSizeOptions {
622
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
623
+ labelSize?: number;
624
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
625
+ labelSizePixels?: number;
626
+ /**
627
+ * Meters-per-pixel at the current view. Stamped by the host when the labels
628
+ * are screen-anchored; resolves `labelSizePixels` to the projected-meter
629
+ * height that meter-denominated placement (offsets, gaps, row pitch) needs.
630
+ */
631
+ metersPerPixel?: number;
632
+ }
633
+ /** Shared placement options for the fixed-end-label line measures. */
634
+ interface LineLabelOptions extends LabelSizeOptions {
635
+ /**
636
+ * Extra clearance between the line and its labels, as a ratio of the
637
+ * label's resolved text height (`labelSize`, or `labelSizePixels ×
638
+ * metersPerPixel`), like Boundary's `labelPadding`. Negative values clamp
639
+ * to 0. Only effective when a label size resolves — the no-size fallback
640
+ * offset is a fixed meter value, unaffected by this ratio.
641
+ * @default 0
642
+ */
643
+ labelPadding?: number;
644
+ }
645
+ //#endregion
646
+ //#region src/generators/cm11-command-control-lines/light-line.d.ts
647
+ /** Configuration options for the Light line control measure. */
648
+ interface LightLineOptions extends LineLabelOptions, SmoothLineOptions {
649
+ /**
650
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
651
+ * the line, additive to the fixed "LL" labels. Empty or whitespace-only
652
+ * renders no label.
653
+ * @default none
654
+ */
655
+ phaseLineName?: string;
656
+ /**
657
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
658
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
659
+ * Phase Line itself, this measure already carries its own fixed "LL"
660
+ * label, so there is no bare "PL" fallback.
661
+ * @default true
662
+ */
663
+ includePrefix?: boolean;
664
+ }
665
+ /** Default options for the Light line control measure. */
666
+ declare const DEFAULT_LIGHT_LINE_OPTIONS: LightLineOptions;
667
+ /**
668
+ * Creates a Light line control measure: a polyline through `positions`
669
+ * labeled "LL" above the line near each end.
670
+ */
671
+ declare function createLightLine(positions: Position[], options?: LightLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
672
+ //#endregion
673
+ //#region src/generators/cm11-command-control-lines/engineer-work-line.d.ts
674
+ /** Configuration options for the Engineer work line control measure. */
675
+ interface EngineerWorkLineOptions extends LineLabelOptions, SmoothLineOptions {
676
+ /**
677
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
678
+ * the line, additive to the fixed "EWL" labels. Empty or whitespace-only
679
+ * renders no label.
680
+ * @default none
681
+ */
682
+ phaseLineName?: string;
683
+ /**
684
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
685
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
686
+ * Phase Line itself, this measure already carries its own fixed "EWL"
687
+ * label, so there is no bare "PL" fallback.
688
+ * @default true
689
+ */
690
+ includePrefix?: boolean;
691
+ }
692
+ /** Default options for the Engineer work line control measure. */
693
+ declare const DEFAULT_ENGINEER_WORK_LINE_OPTIONS: EngineerWorkLineOptions;
694
+ /**
695
+ * Creates an Engineer work line control measure: a polyline through
696
+ * `positions` labeled "EWL" above the line near each end, plus one center
697
+ * label group at the midpoint of the total arc length carrying the
698
+ * responsible units' Field T/AS designator+country (left-of-travel side
699
+ * above the line, T1/AS1 below). No center group is emitted when all four
700
+ * amplifiers are empty.
701
+ */
702
+ declare function createEngineerWorkLine(positions: Position[], options?: EngineerWorkLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
703
+ //#endregion
704
+ //#region src/generators/cm11-command-control-lines/generic-c2-line.d.ts
705
+ /** Configuration options for the Generic command and control line. */
706
+ interface GenericC2LineOptions extends LineLabelOptions, SmoothLineOptions {
707
+ /**
708
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
709
+ * the line, additive to the H/T/W/W1 amplifier labels. Empty or
710
+ * whitespace-only renders no label.
711
+ * @default none
712
+ */
713
+ phaseLineName?: string;
714
+ /**
715
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
716
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — this
717
+ * measure already carries its own H/T/W/W1 amplifier labels, so there is
718
+ * no bare "PL" fallback.
719
+ * @default true
720
+ */
721
+ includePrefix?: boolean;
722
+ }
723
+ /** Default options for the Generic command and control line. */
724
+ declare const DEFAULT_GENERIC_C2_LINE_OPTIONS: GenericC2LineOptions;
725
+ /**
726
+ * Creates a Generic command and control line: a polyline through `positions`
727
+ * with optional near-end text — `H`/`T` joined above the line, `W`/`W1`
728
+ * joined as a "from - to" range below it. Both rows share the per-tip
729
+ * placement from {@link import("../../internal/line-labels").aboveEndFrames}
730
+ * (inset from the tip, anchored toward the line's interior), one at
731
+ * `base + perp·offset` and the other at `base − perp·offset`.
732
+ */
733
+ declare function createGenericC2Line(positions: Position[], options?: GenericC2LineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
734
+ //#endregion
735
+ //#region src/style.d.ts
736
+ /**
737
+ * Framework-agnostic style hints attached to a `ControlMeasure`.
738
+ *
739
+ * Mirrors the per-feature subset of what map adapters render. The renderer
740
+ * fans these into each emitted feature's `properties.style` ([[StyleHints]]).
741
+ * Adapters merge them over their layer-level style; generator-emitted hints
742
+ * on individual features win over both.
743
+ */
744
+ interface ControlMeasureStyle {
745
+ /**
746
+ * The single symbol color. Control measures are monocolor: one color paints
747
+ * every part, stroked or filled. Input-only — resolved into concrete
748
+ * `strokeColor` / `fillColor` per feature by the renderer and never emitted
749
+ * on output. `strokeColor` / `fillColor` act as optional per-channel
750
+ * overrides. See ADR-0011.
751
+ */
752
+ color?: string;
753
+ strokeColor?: string;
754
+ strokeWidth?: number;
755
+ strokeDash?: number[];
756
+ fillColor?: string;
757
+ /**
758
+ * How a filled part's interior is painted. `"solid"` is explicit so a
759
+ * measure can override a patterned layer default (e.g. a hatch fill set
760
+ * at the façade). Pattern lines are drawn in the resolved fill color —
761
+ * alpha included, there is no separate opacity field. Renderers that
762
+ * cannot draw a pattern degrade to solid.
763
+ */
764
+ fillPattern?: FillPattern;
765
+ /**
766
+ * Display-time graphic opacity multiplier in `[0, 1]`; absent = fully
767
+ * opaque. Unlike `color`'s alpha, this fades the whole graphic — stroke,
768
+ * fill, patterns, and baked labels — as one knob, independent of the
769
+ * authored color. The resolver folds it into each resolved part's color
770
+ * alpha (`final alpha = opacity × color alpha`) rather than adding a new
771
+ * paint channel, so adapters and `toSimpleStyle` need no changes.
772
+ * Display-only: hit-testing and selection reason about color alpha, not
773
+ * this multiplier, so a graphic at `opacity: 0` stays fully selectable.
774
+ * Out-of-range values clamp to `[0, 1]`. See ADR-0040.
775
+ */
776
+ opacity?: number;
777
+ /**
778
+ * Render a contrast-aware halo behind label glyphs so text stays legible on
779
+ * busy backgrounds. Cascades like any other hint (graphicsStyle → measure →
780
+ * generator), letting a host switch halos on for every labeled measure
781
+ * rather than only the generic Text graphic.
782
+ *
783
+ * Text-only: the renderer applies it to features that carry `text` and drops
784
+ * it everywhere else, so a layer-level `true` never leaks onto plain stroked
785
+ * or filled parts. The halo *color* is not authored here — it is derived per
786
+ * feature from the resolved text color, so each label gets a halo that
787
+ * actually contrasts with it. Unlike the other hints this one is consumed by
788
+ * the renderer and lifted to a top-level `textHalo` feature property; it is
789
+ * never emitted on `properties.style`. See ADR-0042.
790
+ */
791
+ textHalo?: boolean;
792
+ }
793
+ /**
794
+ * How a filled part's interior is painted. See `ControlMeasureStyle.fillPattern`.
795
+ */
796
+ type FillPattern = "solid" | "hatch" | "reverse-hatch" | "cross-hatch" | "horizontal" | "vertical" | "dots";
797
+ //#endregion
798
+ //#region src/internal/area-labels.d.ts
799
+ /** Shared placement options for the centered-label area measures. */
800
+ interface AreaLabelOptions extends LabelSizeOptions {
801
+ /**
802
+ * Extra row leading (and ENY inset), as a ratio of the label's resolved
803
+ * text height, like the labeled line measures' own `labelPadding`.
804
+ * Negative values clamp to 0.
805
+ * @default 0
806
+ */
807
+ labelPadding?: number;
808
+ }
809
+ /** Options for {@link labeledAreaFeatures}: {@link buildClosedRing}'s
810
+ * smoothing knobs plus the shared {@link AreaLabelOptions} label placement. */
811
+ interface LabeledAreaOptions extends AreaLabelOptions {
812
+ /**
813
+ * Round the area's corners by curving the boundary through the control
814
+ * points (closed centripetal Catmull-Rom spline).
815
+ * @default false
816
+ */
817
+ smooth?: boolean;
818
+ /**
819
+ * Number of samples per segment when `smooth` is enabled.
820
+ * @default 16
821
+ */
822
+ smoothResolution?: number;
823
+ }
824
+ //#endregion
453
825
  //#region src/generators/cm15-maneuver-areas/battlePosition.d.ts
454
- /** Configuration options for the Battle Position control measure. */
455
- interface BattlePositionOptions {
826
+ /**
827
+ * Configuration options for the Battle Position control measure. Also
828
+ * carries the shared {@link AreaLabelOptions} placement for its centered
829
+ * Field T (designator) label.
830
+ */
831
+ interface BattlePositionOptions extends AreaLabelOptions {
456
832
  /**
457
833
  * Field B echelon. One of the keys in the echelon vocabulary (e.g.
458
834
  * `"battalion"`, `"division"`) or an equivalent symbol form (`"II"`, `"XX"`).
@@ -536,8 +912,12 @@ declare const DEFAULT_BATTLE_POSITION_OPTIONS: BattlePositionOptions;
536
912
  * @param positions - Area anchor points (≥3); the input contract is enforced at
537
913
  * the render seam (ADR-0014).
538
914
  * @param options - {@link BattlePositionOptions}.
915
+ * @param textAmplifiers - Field T (designation, centered in the area) plus an
916
+ * optional Field N "ENY" hostile marker at the west/east edges (no H/W rows —
917
+ * this measure's template pairs the designation with the Field B glyph, not
918
+ * the plain L-15 boundary template).
539
919
  */
540
- declare function createBattlePosition(positions: Position[], options?: BattlePositionOptions): FeatureCollection<MultiLineString | MultiPolygon>;
920
+ declare function createBattlePosition(positions: Position[], options?: BattlePositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | MultiPolygon | Point>;
541
921
  //#endregion
542
922
  //#region src/generators/cm15-maneuver-areas/strongPoint.d.ts
543
923
  /** Configuration options for the Strong Point control measure. */
@@ -553,8 +933,54 @@ declare const DEFAULT_STRONG_POINT_OPTIONS: StrongPointOptions;
553
933
  * @param positions - Area anchor points (>=3); the input contract is enforced
554
934
  * at the render seam (ADR-0014).
555
935
  * @param options - {@link StrongPointOptions}.
936
+ * @param textAmplifiers - Field T (designation, centered in the area) plus an
937
+ * optional Field N "ENY" hostile marker at the west/east edges, same as
938
+ * Battle Position.
556
939
  */
557
- declare function createStrongPoint(positions: Position[], options?: StrongPointOptions): FeatureCollection<MultiLineString | MultiPolygon>;
940
+ declare function createStrongPoint(positions: Position[], options?: StrongPointOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | MultiPolygon | Point>;
941
+ //#endregion
942
+ //#region src/generators/cm14-maneuver-lines/direction-of-attack-aviation.d.ts
943
+ interface DirectionOfAttackAviationOptions extends LabelSizeOptions, SmoothLineOptions {
944
+ /** Arrowhead length as a ratio of the route's total length. @default 0.12 */
945
+ arrowheadLengthRatio?: number;
946
+ /** Arrowhead total width as a ratio of its length. @default 1.15 */
947
+ arrowheadWidthRatio?: number;
948
+ /** Bow-tie length as a ratio of the route's total length. @default 0.1 */
949
+ bowTieLengthRatio?: number;
950
+ /** Bow-tie total width as a ratio of its length. @default 0.5 */
951
+ bowTieWidthRatio?: number;
952
+ /** Bow-tie position as a fraction from tail (0) to tip (1). @default 1/3 */
953
+ bowTiePosition?: number;
954
+ /** Field T/W/W1 group position as a fraction from tail (0) to tip (1). @default 2/3 */
955
+ labelPosition?: number;
956
+ /** Extra spacing between the route and W/W1 rows, in label heights. @default 0 */
957
+ labelPadding?: number;
958
+ }
959
+ declare const DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS: DirectionOfAttackAviationOptions;
960
+ /** Builds the route, aviation bow-tie, arrowhead, and optional T/W/W1 labels. */
961
+ declare function createDirectionOfAttackAviation(coordinates: Position[], options?: DirectionOfAttackAviationOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | Point>;
962
+ //#endregion
963
+ //#region src/generators/cm14-maneuver-lines/direction-of-attack-shared.d.ts
964
+ interface DirectionOfAttackLineOptions extends LabelSizeOptions, SmoothLineOptions {
965
+ arrowheadLengthRatio?: number;
966
+ arrowheadWidthRatio?: number;
967
+ /** Field T/W/W1 group position as a fraction from tail (0) to tip (1). */
968
+ labelPosition?: number;
969
+ labelPadding?: number;
970
+ }
971
+ //#endregion
972
+ //#region src/generators/cm14-maneuver-lines/direction-of-main-attack.d.ts
973
+ interface DirectionOfMainAttackOptions extends DirectionOfAttackLineOptions {
974
+ /** Thickness of the outlined arrowhead as a ratio of its length. @default 0.3 */
975
+ arrowheadOutlineRatio?: number;
976
+ }
977
+ declare const DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS: DirectionOfMainAttackOptions;
978
+ declare function createDirectionOfMainAttack(coordinates: Position[], options?: DirectionOfMainAttackOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | Point>;
979
+ //#endregion
980
+ //#region src/generators/cm14-maneuver-lines/direction-of-supporting-attack.d.ts
981
+ type DirectionOfSupportingAttackOptions = DirectionOfAttackLineOptions;
982
+ declare const DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS: DirectionOfSupportingAttackOptions;
983
+ declare function createDirectionOfSupportingAttack(coordinates: Position[], options?: DirectionOfSupportingAttackOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | Point>;
558
984
  //#endregion
559
985
  //#region src/generators/cm14-maneuver-lines/principalDirectionOfFire.d.ts
560
986
  /**
@@ -581,6 +1007,119 @@ declare const DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS: Required<PrincipalDir
581
1007
  */
582
1008
  declare function createPrincipalDirectionOfFire(coordinates: Position[], options?: PrincipalDirectionOfFireOptions): FeatureCollection<MultiLineString, Record<string, never>>;
583
1009
  //#endregion
1010
+ //#region src/generators/cm14-maneuver-lines/secondaryDirectionOfFire.d.ts
1011
+ /** Configuration options for the Secondary Direction of Fire tactical symbol. */
1012
+ type SecondaryDirectionOfFireOptions = PrincipalDirectionOfFireOptions;
1013
+ declare const DEFAULT_SECONDARY_DIRECTION_OF_FIRE_OPTIONS: Required<SecondaryDirectionOfFireOptions>;
1014
+ /** Dash and gap lengths used by the two fire-direction arms. */
1015
+ declare const SECONDARY_DIRECTION_OF_FIRE_DASH: readonly [6, 4];
1016
+ interface SecondaryDirectionOfFireProperties extends Record<string, unknown> {
1017
+ part: "arms" | "arrowheads";
1018
+ style: {
1019
+ strokeDash: number[];
1020
+ };
1021
+ }
1022
+ /**
1023
+ * Creates the same V-shaped field-of-fire geometry as Principal Direction of
1024
+ * Fire, with dashed arms and solid open arrowheads.
1025
+ *
1026
+ * @param coordinates - [PT 1 (vertex), PT 2 (tip), PT 3 (tip)]
1027
+ * @param options - Arrowhead sizing parameters
1028
+ */
1029
+ declare function createSecondaryDirectionOfFire(coordinates: Position[], options?: SecondaryDirectionOfFireOptions): FeatureCollection<MultiLineString, SecondaryDirectionOfFireProperties>;
1030
+ //#endregion
1031
+ //#region src/rendered.d.ts
1032
+ /**
1033
+ * Per-feature style hints carried on `properties.style`.
1034
+ *
1035
+ * These are *resolved*: `renderControlMeasure` cascades `graphicsStyle` →
1036
+ * `cm.style` → any generator pattern hint, then expands the monocolor `color`
1037
+ * into concrete `strokeColor` / `fillColor` per feature (see ADR-0011 and
1038
+ * `resolveSymbolColor`). Output therefore carries concrete colors, never the
1039
+ * input-only `color` key, and a `fillColor` only on parts the generator
1040
+ * marked filled.
1041
+ *
1042
+ * Generators contribute paint *role* and *pattern* (a part is filled; a
1043
+ * sub-line is dashed regardless of the user's stroke), never a hue. Adapters
1044
+ * merge the resulting `StyleHints` over their layer-level style at draw time.
1045
+ */
1046
+ interface StyleHints extends ControlMeasureStyle {}
1047
+ /**
1048
+ * Per-feature properties emitted by `renderControlMeasure`.
1049
+ *
1050
+ * Stable-id contract — every feature produced by the renderer has:
1051
+ * - `feature.id` of the form `${cmId}:${part}:${index}`
1052
+ * - `properties.part` matching the `part` segment of the id
1053
+ * - `properties.index` matching the `index` segment of the id
1054
+ *
1055
+ * Adapters rely on this contract to diff renders in place without keeping
1056
+ * their own bookkeeping. Use `controlMeasureIdFromFeature` to recover the
1057
+ * `cmId` from a picked feature.
1058
+ */
1059
+ interface FeaturePartProps {
1060
+ part: string;
1061
+ index: number;
1062
+ style?: StyleHints;
1063
+ /** Label text emitted by generators (e.g. breach "B"). */
1064
+ text?: string;
1065
+ /** Label rotation in radians, emitted by generators. */
1066
+ rotation?: number;
1067
+ /**
1068
+ * Horizontal text alignment relative to the label point: `"start"` = the
1069
+ * text begins at the point, `"end"` = it ends there. Absent = centered.
1070
+ */
1071
+ textAnchor?: "start" | "end";
1072
+ /** Render an opaque light backdrop behind text placed over patterned geometry. */
1073
+ textBackground?: boolean;
1074
+ /** Render a contrast-aware halo behind the glyphs so text stays legible on busy backgrounds. */
1075
+ textHalo?: boolean;
1076
+ /** Halo color contrasting with the resolved text color; present only when `textHalo` is set. */
1077
+ textHaloColor?: string;
1078
+ /** Canonical field key for a text-amplifier label that may be repositioned. */
1079
+ amplifierField?: TextAmplifierKey;
1080
+ /** Stable key used to persist a user-adjusted anchor for any rendered label. */
1081
+ labelPlacementKey?: string;
1082
+ /**
1083
+ * Screen-anchored label size in CSS pixels — held constant on screen
1084
+ * (ADR-0028). Mutually exclusive with `textSizeMeters`; absent both,
1085
+ * adapters render their engine default, screen-fixed.
1086
+ */
1087
+ textSizePixels?: number;
1088
+ /**
1089
+ * Ground-anchored label text height in projected meters (ADR-0028).
1090
+ * Adapters render `clamp(textSizeMeters / resolution, min, max)` px, per
1091
+ * their configured clamp band.
1092
+ */
1093
+ textSizeMeters?: number;
1094
+ /**
1095
+ * Multi-line justification within the text block (Text's `textAlign`
1096
+ * option); the block itself stays centered on the anchor regardless of this
1097
+ * value — unrelated to the block-shifting `textAnchor`.
1098
+ */
1099
+ textJustify?: "left" | "center" | "right";
1100
+ /** Closed typography preset for a text label (Text's `textStyle` option). */
1101
+ textStyle?: "regular" | "italic" | "light" | "caps";
1102
+ /**
1103
+ * Hide threshold in CSS pixels: when the derived on-screen text size exceeds
1104
+ * this, adapters render nothing for the label instead of clamping (ADR-0037)
1105
+ * and skip the default 8-24px ground clamp band.
1106
+ */
1107
+ textMaxSizePixels?: number;
1108
+ }
1109
+ /**
1110
+ * Output of `renderControlMeasure`. A GeoJSON `FeatureCollection` whose
1111
+ * features satisfy the `FeaturePartProps` stable-id contract. See ADR-0010.
1112
+ */
1113
+ type ControlMeasureRender = FeatureCollection<Geometry, FeaturePartProps>;
1114
+ /**
1115
+ * Recover the originating control measure id (`cmId`) from a feature emitted
1116
+ * by `renderControlMeasure`. The feature id must match the stable-id contract
1117
+ * `${cmId}:${part}:${index}`; otherwise this throws.
1118
+ */
1119
+ declare function controlMeasureIdFromFeature(feature: Feature<Geometry, FeaturePartProps> | {
1120
+ id?: string | number;
1121
+ }): string;
1122
+ //#endregion
584
1123
  //#region src/generators/cm14-maneuver-lines/finalProtectiveFire.d.ts
585
1124
  /**
586
1125
  * Configuration options for the Final Protective Fire tactical symbols.
@@ -594,70 +1133,384 @@ interface FinalProtectiveFireOptions {
594
1133
  /** Arrowhead wing spread relative to the arrowhead length (default: 0.67) */
595
1134
  arrowheadWidthRatio?: number;
596
1135
  /**
597
- * Blade height (its perpendicular reach into the inside of the V) relative
598
- * to the bladed arm's own length (default: 0.03).
1136
+ * Blade height (its perpendicular reach into the inside of the V) relative
1137
+ * to the bladed arm's own length (default: 0.03).
1138
+ */
1139
+ bladeHeightRatio?: number;
1140
+ }
1141
+ declare const DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS: Required<FinalProtectiveFireOptions>;
1142
+ type FpfProps = {
1143
+ part?: string;
1144
+ fill?: true;
1145
+ style?: StyleHints;
1146
+ };
1147
+ declare function createFinalProtectiveFireLeft(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1148
+ declare function createFinalProtectiveFireRight(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1149
+ //#endregion
1150
+ //#region src/generators/cm15-maneuver-areas/encirclement.d.ts
1151
+ /**
1152
+ * Configuration options for the Encirclement control measure. Also carries
1153
+ * the shared {@link AreaLabelOptions} label placement for its Field N (ENY)
1154
+ * marker — the doctrinal example shows only the hostile marker, no name/H/W
1155
+ * rows.
1156
+ */
1157
+ interface EncirclementOptions extends AreaLabelOptions {
1158
+ /**
1159
+ * Spacing between adjacent barbs as a ratio of the symbol's mean radius;
1160
+ * smaller values pack the barbs more densely. The barbs are then distributed
1161
+ * evenly so they close the ring exactly.
1162
+ * @default 0.4
1163
+ */
1164
+ barbSpacingRatio?: number;
1165
+ /**
1166
+ * Barb length (height/amplitude) as a ratio of the symbol's mean radius.
1167
+ * @default 0.16
1168
+ */
1169
+ barbLengthRatio?: number;
1170
+ /**
1171
+ * Round the boundary by curving it through the control points (closed
1172
+ * centripetal Catmull-Rom) before tracing the barbs.
1173
+ * @default true
1174
+ */
1175
+ smooth?: boolean;
1176
+ /**
1177
+ * Number of samples per segment when `smooth` is enabled.
1178
+ * @default 16
1179
+ */
1180
+ smoothResolution?: number;
1181
+ }
1182
+ /**
1183
+ * Default options for the Encirclement control measure. Not `Required<...>`
1184
+ * — the inherited label-size options ({@link AreaLabelOptions}) have no
1185
+ * static default, so this covers only the barb/smoothing options.
1186
+ */
1187
+ declare const DEFAULT_ENCIRCLEMENT_OPTIONS: EncirclementOptions;
1188
+ /**
1189
+ * Creates an Encirclement tactical graphic: a complete smooth boundary ring
1190
+ * with outward arrowhead barbs resting on it. The boundary is an unfilled
1191
+ * Polygon; the barbs are open "V" strokes (a MultiLineString) whose base is the
1192
+ * boundary arc itself. When a Field N (ENY) marker is set, it masks the
1193
+ * boundary with a knockout gap wherever its text box touches the ring
1194
+ * (mirroring Field B's echelon glyph, ADR-0023) — the boundary becomes a
1195
+ * gapped MultiLineString instead of a closed Polygon, and any barb whose
1196
+ * center falls inside the gap is suppressed; the no-`N` case is unaffected.
1197
+ *
1198
+ * @param positions - Area anchor points (>=3); the input contract is enforced
1199
+ * at the render seam (ADR-0014).
1200
+ * @param options - {@link EncirclementOptions}.
1201
+ * @param textAmplifiers - Field N only — rendered as "ENY" markers at the
1202
+ * ring's west and east edges, per the doctrinal hostile example.
1203
+ */
1204
+ declare function createEncirclement(positions: Position[], options?: EncirclementOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1205
+ //#endregion
1206
+ //#region src/generators/cm15-maneuver-areas/area.d.ts
1207
+ /** Configuration options for the Area control measure. */
1208
+ type AreaOptions = LabeledAreaOptions;
1209
+ /**
1210
+ * Creates an Area control measure: a closed area through `positions` labeled
1211
+ * at its center with an un-prefixed `T` (Field T) plus an `N` (Field N) ENY
1212
+ * marker, per {@link labeledAreaFeatures}.
1213
+ */
1214
+ declare function createArea(positions: Position[], options?: AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1215
+ //#endregion
1216
+ //#region src/generators/cm15-maneuver-areas/area-defense.d.ts
1217
+ interface AreaDefenseOptions extends LabelSizeOptions {
1218
+ /** Angular opening between the two arrow tips, in degrees. */
1219
+ arrowOpeningAngle?: number;
1220
+ /** Angular opening occupied by the AD label, in degrees. */
1221
+ labelOpeningAngle?: number;
1222
+ /** Number of filled outward barbs distributed over both arcs. */
1223
+ barbCount?: number;
1224
+ /** Barb height as a ratio of the radius. */
1225
+ barbLengthRatio?: number;
1226
+ /** Open-arrowhead length as a ratio of the radius. */
1227
+ arrowheadLengthRatio?: number;
1228
+ }
1229
+ declare const DEFAULT_AREA_DEFENSE_OPTIONS: Required<Omit<AreaDefenseOptions, keyof LabelSizeOptions>>;
1230
+ declare function createAreaDefense(coordinates: Position[], options?: AreaDefenseOptions): FeatureCollection<MultiLineString | MultiPolygon | Point>;
1231
+ //#endregion
1232
+ //#region src/generators/cm15-maneuver-areas/assemblyArea.d.ts
1233
+ /** Configuration options for the Assembly area control measure. */
1234
+ type AssemblyAreaOptions = LabeledAreaOptions;
1235
+ /** Default options for the Assembly area control measure. */
1236
+ declare const DEFAULT_ASSEMBLY_AREA_OPTIONS: AssemblyAreaOptions;
1237
+ /**
1238
+ * Creates an Assembly area control measure: a closed area through
1239
+ * `positions` labeled at its center with "AA "-prefixed `T` (Field T) plus
1240
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1241
+ */
1242
+ declare function createAssemblyArea(positions: Position[], options?: AssemblyAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1243
+ //#endregion
1244
+ //#region src/generators/cm15-maneuver-areas/jointTacticalActionArea.d.ts
1245
+ /** Configuration options for the Joint tactical action area control measure. */
1246
+ type JointTacticalActionAreaOptions = LabeledAreaOptions;
1247
+ /** Default options for the Joint tactical action area control measure. */
1248
+ declare const DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS: JointTacticalActionAreaOptions;
1249
+ /**
1250
+ * Creates a Joint tactical action area control measure: a closed area
1251
+ * through `positions` labeled at its center with "JTAA -"-prefixed `T`
1252
+ * (Field T) plus `H`/`W`/`W1`/`N` amplifier rows, per
1253
+ * {@link labeledAreaFeatures}.
1254
+ */
1255
+ declare function createJointTacticalActionArea(positions: Position[], options?: JointTacticalActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1256
+ //#endregion
1257
+ //#region src/generators/cm15-maneuver-areas/submarineActionArea.d.ts
1258
+ /** Configuration options for the Submarine action area control measure. */
1259
+ type SubmarineActionAreaOptions = LabeledAreaOptions;
1260
+ /**
1261
+ * Creates a Submarine action area control measure: a closed area through
1262
+ * `positions` labeled at its center with "SAA -"-prefixed `T` (Field T) plus
1263
+ * `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1264
+ */
1265
+ declare function createSubmarineActionArea(positions: Position[], options?: SubmarineActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1266
+ //#endregion
1267
+ //#region src/generators/cm15-maneuver-areas/submarineGeneratedActionArea.d.ts
1268
+ /** Configuration options for the Submarine-generated action area control measure. */
1269
+ type SubmarineGeneratedActionAreaOptions = LabeledAreaOptions;
1270
+ /**
1271
+ * Creates a Submarine-generated action area control measure: a closed area
1272
+ * through `positions` labeled at its center with "SGSA -"-prefixed `T`
1273
+ * (Field T) plus `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1274
+ */
1275
+ declare function createSubmarineGeneratedActionArea(positions: Position[], options?: SubmarineGeneratedActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1276
+ //#endregion
1277
+ //#region src/generators/cm15-maneuver-areas/dropZone.d.ts
1278
+ /** Configuration options for the Drop zone control measure. */
1279
+ type DropZoneOptions = LabeledAreaOptions;
1280
+ /**
1281
+ * Creates a Drop zone control measure: a closed area through `positions`
1282
+ * labeled at its center with "DZ "-prefixed `T` (Field T) plus an `N`
1283
+ * (Field N) ENY marker, per {@link labeledAreaFeatures}.
1284
+ */
1285
+ declare function createDropZone(positions: Position[], options?: DropZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1286
+ //#endregion
1287
+ //#region src/generators/cm15-maneuver-areas/extractionZone.d.ts
1288
+ /** Configuration options for the Extraction zone control measure. */
1289
+ type ExtractionZoneOptions = LabeledAreaOptions;
1290
+ /**
1291
+ * Creates an Extraction zone control measure: a closed area through
1292
+ * `positions` labeled at its center with "EZ "-prefixed `T` (Field T) plus
1293
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1294
+ */
1295
+ declare function createExtractionZone(positions: Position[], options?: ExtractionZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1296
+ //#endregion
1297
+ //#region src/generators/cm15-maneuver-areas/landingZone.d.ts
1298
+ /** Configuration options for the Landing zone control measure. */
1299
+ type LandingZoneOptions = LabeledAreaOptions;
1300
+ /** Default options for the Landing zone control measure. */
1301
+ declare const DEFAULT_LANDING_ZONE_OPTIONS: LandingZoneOptions;
1302
+ /**
1303
+ * Creates a Landing zone control measure: a closed area through `positions`
1304
+ * labeled at its center with "LZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1305
+ * amplifier rows, per {@link labeledAreaFeatures}.
1306
+ */
1307
+ declare function createLandingZone(positions: Position[], options?: LandingZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1308
+ //#endregion
1309
+ //#region src/generators/cm15-maneuver-areas/limitedAccessArea.d.ts
1310
+ /** Configuration options for the Limited Access Area control measure. */
1311
+ interface LimitedAccessAreaOptions extends AreaLabelOptions {
1312
+ /** Round the area's corners through its control points. */
1313
+ smooth?: boolean;
1314
+ /** Number of samples per segment when smoothing is enabled. */
1315
+ smoothResolution?: number;
1316
+ }
1317
+ /** Creates a back-hatched free area with a movable "LAA" label, centered by default. */
1318
+ declare function createLimitedAccessArea(positions: Position[], options?: LimitedAccessAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1319
+ //#endregion
1320
+ //#region src/generators/cm24-fire-areas/noFireAreaIrregular.d.ts
1321
+ /** Configuration options for the irregular No Fire Area control measure. */
1322
+ interface NoFireAreaIrregularOptions extends AreaLabelOptions {
1323
+ /** Round the area's corners through its control points. */
1324
+ smooth?: boolean;
1325
+ /** Number of samples per segment when smoothing is enabled. */
1326
+ smoothResolution?: number;
1327
+ }
1328
+ /** Creates a back-hatched irregular NFA with its centered movable label fields. */
1329
+ declare function createNoFireAreaIrregular(positions: Position[], options?: NoFireAreaIrregularOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1330
+ //#endregion
1331
+ //#region src/generators/cm15-maneuver-areas/pickupZone.d.ts
1332
+ /** Configuration options for the Pickup zone control measure. */
1333
+ type PickupZoneOptions = LabeledAreaOptions;
1334
+ /** Default options for the Pickup zone control measure. */
1335
+ declare const DEFAULT_PICKUP_ZONE_OPTIONS: PickupZoneOptions;
1336
+ /**
1337
+ * Creates a Pickup zone control measure: a closed area through `positions`
1338
+ * labeled at its center with "PZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1339
+ * amplifier rows, per {@link labeledAreaFeatures}.
1340
+ */
1341
+ declare function createPickupZone(positions: Position[], options?: PickupZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1342
+ //#endregion
1343
+ //#region src/generators/cm15-maneuver-areas/assaultPosition.d.ts
1344
+ /** Configuration options for the Assault position control measure. */
1345
+ type AssaultPositionOptions = LabeledAreaOptions;
1346
+ /**
1347
+ * Creates an Assault position control measure: a closed area through
1348
+ * `positions` labeled at its center with "ASLT "-prefixed `T` (Field T) plus
1349
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1350
+ */
1351
+ declare function createAssaultPosition(positions: Position[], options?: AssaultPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1352
+ //#endregion
1353
+ //#region src/generators/cm15-maneuver-areas/attackPosition.d.ts
1354
+ /** Configuration options for the Attack position control measure. */
1355
+ type AttackPositionOptions = LabeledAreaOptions;
1356
+ /**
1357
+ * Creates an Attack position control measure: a closed area through
1358
+ * `positions` labeled at its center with "ATK "-prefixed `T` (Field T) plus
1359
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1360
+ */
1361
+ declare function createAttackPosition(positions: Position[], options?: AttackPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1362
+ //#endregion
1363
+ //#region src/generators/cm15-maneuver-areas/objectiveArea.d.ts
1364
+ /** Configuration options for the Objective area control measure. */
1365
+ type ObjectiveAreaOptions = LabeledAreaOptions;
1366
+ /**
1367
+ * Creates an Objective area control measure: a closed area through
1368
+ * `positions` labeled at its center with "OBJ "-prefixed `T` (Field T) plus
1369
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1370
+ */
1371
+ declare function createObjectiveArea(positions: Position[], options?: ObjectiveAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1372
+ //#endregion
1373
+ //#region src/generators/cm12-command-control-areas/area-of-operations.d.ts
1374
+ /** Configuration options for the Area of operations control measure. */
1375
+ type AreaOfOperationsOptions = LabeledAreaOptions;
1376
+ /** Default options for the Area of operations control measure. */
1377
+ declare const DEFAULT_AREA_OF_OPERATIONS_OPTIONS: AreaOfOperationsOptions;
1378
+ /**
1379
+ * Creates an Area of operations control measure: a closed area through
1380
+ * `positions` labeled at its center with "AO "-prefixed `T` (Field T) plus
1381
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1382
+ */
1383
+ declare function createAreaOfOperations(positions: Position[], options?: AreaOfOperationsOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1384
+ //#endregion
1385
+ //#region src/generators/cm12-command-control-areas/named-area-of-interest.d.ts
1386
+ /** Configuration options for the Named area of interest control measure. */
1387
+ type NamedAreaOfInterestOptions = LabeledAreaOptions;
1388
+ /**
1389
+ * Creates a Named area of interest control measure: a closed area through
1390
+ * `positions` labeled at its center with "NAI "-prefixed `T` (Field T) plus
1391
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1392
+ */
1393
+ declare function createNamedAreaOfInterest(positions: Position[], options?: NamedAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1394
+ //#endregion
1395
+ //#region src/generators/cm12-command-control-areas/target-area-of-interest.d.ts
1396
+ /** Configuration options for the Target area of interest control measure. */
1397
+ type TargetAreaOfInterestOptions = LabeledAreaOptions;
1398
+ /**
1399
+ * Creates a Target area of interest control measure: a closed area through
1400
+ * `positions` labeled at its center with "TAI "-prefixed `T` (Field T) plus
1401
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1402
+ */
1403
+ declare function createTargetAreaOfInterest(positions: Position[], options?: TargetAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1404
+ //#endregion
1405
+ //#region src/generators/cm12-command-control-areas/airfield-zone.d.ts
1406
+ /** Configuration options for the Airfield zone control measure. */
1407
+ interface AirfieldZoneOptions extends LabeledAreaOptions {
1408
+ /**
1409
+ * The runway glyph's long line, as a ratio of the ring's projected
1410
+ * bounding-box width (full length, not half).
1411
+ * @default 0.55
1412
+ */
1413
+ glyphSizeRatio?: number;
1414
+ }
1415
+ /**
1416
+ * Creates an Airfield zone control measure: a closed area through
1417
+ * `positions` with a runway glyph (two crossed lines forming a shallow
1418
+ * asymmetric X) centered on the ring, and Field H placed outside the area to
1419
+ * the east when set.
1420
+ *
1421
+ * @param positions - Area anchor points (≥3); the input contract is enforced
1422
+ * at the render seam (ADR-0014).
1423
+ * @param options - {@link AirfieldZoneOptions}.
1424
+ * @param textAmplifiers - Field H (placed east of the area) plus an optional
1425
+ * Field N "ENY" hostile marker on the west/east edges.
1426
+ */
1427
+ declare function createAirfieldZone(positions: Position[], options?: AirfieldZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1428
+ //#endregion
1429
+ //#region src/generators/cm12-command-control-areas/echelon-labeled-area.d.ts
1430
+ /**
1431
+ * Configuration options shared by Base Camp and Guerrilla Base: the full L-15
1432
+ * label placement ({@link LabeledAreaOptions}) plus Battle Position's Field B
1433
+ * echelon knobs.
1434
+ */
1435
+ interface EchelonLabeledAreaOptions extends LabeledAreaOptions {
1436
+ /**
1437
+ * Field B echelon straddling the boundary. `"none"` (the default — the
1438
+ * standard's examples show no echelon glyph), empty, or unknown renders no
1439
+ * glyph and leaves the boundary unaffected by echelon masking.
1440
+ * @default "none"
1441
+ */
1442
+ echelon?: string;
1443
+ /**
1444
+ * Echelon glyph height in meters (ground-anchored). Ignored when
1445
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
1446
+ * @default 750
1447
+ */
1448
+ echelonSize?: number;
1449
+ /**
1450
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to
1451
+ * meters against `metersPerPixel`; bakes to a meter size on draw/edit
1452
+ * commit (ADR-0020).
1453
+ * @default 16
599
1454
  */
600
- bladeHeightRatio?: number;
601
- }
602
- declare const DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS: Required<FinalProtectiveFireOptions>;
603
- type FpfProps = {
604
- part?: string;
605
- fill?: true;
606
- };
607
- declare function createFinalProtectiveFireLeft(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
608
- declare function createFinalProtectiveFireRight(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
609
- //#endregion
610
- //#region src/generators/cm15-maneuver-areas/encirclement.d.ts
611
- /** Configuration options for the Encirclement control measure. */
612
- interface EncirclementOptions {
1455
+ echelonSizePixels?: number;
613
1456
  /**
614
- * Spacing between adjacent barbs as a ratio of the symbol's mean radius;
615
- * smaller values pack the barbs more densely. The barbs are then distributed
616
- * evenly so they close the ring exactly.
617
- * @default 0.4
1457
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph
1458
+ * height. `0` butts the boundary against the glyph; larger values widen
1459
+ * the break.
1460
+ * @default 0.3
618
1461
  */
619
- barbSpacingRatio?: number;
1462
+ echelonPadding?: number;
620
1463
  /**
621
- * Barb length (height/amplitude) as a ratio of the symbol's mean radius.
622
- * @default 0.16
1464
+ * Slides the echelon along the boundary, as a signed fraction of the total
1465
+ * perimeter measured from its default anchor on the bottom edge.
1466
+ * @default 0
623
1467
  */
624
- barbLengthRatio?: number;
1468
+ echelonPosition?: number;
625
1469
  /**
626
- * Round the boundary by curving it through the control points (closed
627
- * centripetal Catmull-Rom) before tracing the barbs.
628
- * @default true
1470
+ * Absolute anchor for the echelon glyph, as a fraction of the total
1471
+ * perimeter measured from the ring seam, wrapped into `[0, 1)`. See Battle
1472
+ * Position's `echelonAnchor` (ADR-0023) — edit controllers freeze this via
1473
+ * the `freezeOrientation` hook the moment a rotate gesture starts.
629
1474
  */
630
- smooth?: boolean;
1475
+ echelonAnchor?: number;
631
1476
  /**
632
- * Number of samples per segment when `smooth` is enabled.
633
- * @default 16
1477
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when
1478
+ * the measure is screen-anchored; required to resolve `echelonSizePixels`.
634
1479
  */
635
- smoothResolution?: number;
1480
+ metersPerPixel?: number;
636
1481
  }
637
- /** Default options for the Encirclement control measure. */
638
- declare const DEFAULT_ENCIRCLEMENT_OPTIONS: Required<EncirclementOptions>;
1482
+ //#endregion
1483
+ //#region src/generators/cm12-command-control-areas/base-camp.d.ts
1484
+ /** Configuration options for the Base camp control measure. */
1485
+ type BaseCampOptions = EchelonLabeledAreaOptions;
639
1486
  /**
640
- * Creates an Encirclement tactical graphic: a complete smooth boundary ring
641
- * with outward arrowhead barbs resting on it. The boundary is an unfilled
642
- * Polygon; the barbs are open "V" strokes (a MultiLineString) whose base is the
643
- * boundary arc itself.
644
- *
645
- * @param positions - Area anchor points (>=3); the input contract is enforced
646
- * at the render seam (ADR-0014).
647
- * @param options - {@link EncirclementOptions}.
1487
+ * Creates a Base camp control measure: a closed area through `positions`
1488
+ * labeled at its center with "BC "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1489
+ * amplifier rows, and an optional Field B echelon glyph straddling the
1490
+ * boundary, per {@link echelonLabeledAreaFeatures}.
648
1491
  */
649
- declare function createEncirclement(positions: Position[], options?: EncirclementOptions): FeatureCollection<Polygon | MultiLineString>;
1492
+ declare function createBaseCamp(positions: Position[], options?: BaseCampOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
650
1493
  //#endregion
651
- //#region src/projection.d.ts
652
- type Point2D = [number, number];
1494
+ //#region src/generators/cm12-command-control-areas/guerrilla-base.d.ts
1495
+ /** Configuration options for the Guerrilla base control measure. */
1496
+ type GuerrillaBaseOptions = EchelonLabeledAreaOptions;
653
1497
  /**
654
- * Project WGS84 (Lon/Lat) to Web Mercator (Meters).
1498
+ * Creates a Guerrilla base control measure: a closed area through
1499
+ * `positions` labeled at its center with "GB "-prefixed `T` (Field T) plus
1500
+ * `H`/`W`/`W1`/`N` amplifier rows, and an optional Field B echelon glyph
1501
+ * straddling the boundary, per {@link echelonLabeledAreaFeatures}.
655
1502
  */
656
- declare const project: (lon: number, lat: number) => Point2D;
1503
+ declare function createGuerrillaBase(positions: Position[], options?: GuerrillaBaseOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1504
+ //#endregion
1505
+ //#region src/generators/cm12-command-control-areas/generic-c2-area.d.ts
1506
+ /** Configuration options for the Generic command and control area control measure. */
1507
+ type GenericC2AreaOptions = LabeledAreaOptions;
657
1508
  /**
658
- * Unproject Web Mercator (Meters) back to WGS84 (Lon/Lat).
1509
+ * Creates a Generic command and control area control measure: a closed area
1510
+ * through `positions` labeled at its center with the bare `T` (Field T) plus
1511
+ * `H`/`W`/`W1`/`N` amplifier rows — no prefix, per {@link labeledAreaFeatures}.
659
1512
  */
660
- declare const unproject: (x: number, y: number) => Position;
1513
+ declare function createGenericC2Area(positions: Position[], options?: GenericC2AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
661
1514
  //#endregion
662
1515
  //#region src/attack-utils.d.ts
663
1516
  interface AttackOptions {
@@ -767,6 +1620,7 @@ declare const DEFAULT_CLASSIC_ARROW_OPTIONS: Required<ClassicArrowOptions>;
767
1620
  declare function createClassicArrow(coordinates: Position[], options?: ClassicArrowOptions): FeatureCollection<LineString | Polygon, {
768
1621
  part: "shaft" | "head";
769
1622
  fill?: boolean;
1623
+ style?: StyleHints;
770
1624
  }>;
771
1625
  //#endregion
772
1626
  //#region src/generators/cm99-generic-arrows/blockArrow.d.ts
@@ -856,6 +1710,49 @@ declare function createGenericCircle(coordinates: Position[], options?: GenericC
856
1710
  fill: boolean;
857
1711
  }>;
858
1712
  //#endregion
1713
+ //#region src/generators/cm99-generic-graphics/text.d.ts
1714
+ /** Configuration options for the generic Text control measure. */
1715
+ interface GenericTextOptions {
1716
+ /** Plain text; explicit `\n` breaks lines — never auto-wraps. @default "Text" */
1717
+ text?: string;
1718
+ /**
1719
+ * Placement of the text block relative to the anchor point, and the
1720
+ * justification of its lines. `left` puts the anchor at the block's left edge
1721
+ * (text extends rightward, lines left-justified); `right` puts the anchor at
1722
+ * the right edge (text extends leftward, lines right-justified); `center`
1723
+ * centers the block on the anchor (lines centered). Maps onto the existing
1724
+ * block-shifting `textAnchor` prop (`left` → `start`, `right` → `end`, `center`
1725
+ * → none) plus the `textJustify` prop; rotation always pivots at the anchor.
1726
+ * @default "center"
1727
+ */
1728
+ textAlign?: "left" | "center" | "right";
1729
+ /** Closed typography preset. `caps` uppercases `regular`; `light` is weight 300. @default "regular" */
1730
+ textStyle?: "regular" | "italic" | "light" | "caps";
1731
+ /** Clockwise rotation in degrees on screen. @default 0 */
1732
+ rotation?: number;
1733
+ /**
1734
+ * Text height (cap height) in projected meters — ground-anchored
1735
+ * (ADR-0020). Ignored whenever `sizePixels` is present.
1736
+ */
1737
+ sizeMeters?: number;
1738
+ /**
1739
+ * Text height in CSS pixels — screen-anchored (ADR-0020). A fresh draw is
1740
+ * authored in pixels and bakes to `sizeMeters` on commit.
1741
+ * @default 24
1742
+ */
1743
+ sizePixels?: number;
1744
+ /**
1745
+ * Hide threshold in CSS pixels: once the ground-derived on-screen size
1746
+ * exceeds this, adapters hide the text entirely instead of clamping it
1747
+ * (ADR-0037); there is no minimum, so the text just keeps shrinking on
1748
+ * zoom-out.
1749
+ * @default 200
1750
+ */
1751
+ maxSizePixels?: number;
1752
+ }
1753
+ declare const DEFAULT_GENERIC_TEXT_OPTIONS: GenericTextOptions;
1754
+ declare function createGenericText(coordinates: Position[], options?: GenericTextOptions): FeatureCollection<Point, Record<string, unknown>>;
1755
+ //#endregion
859
1756
  //#region src/generators/cm15-maneuver-areas/airborneAttack.d.ts
860
1757
  type AirborneAttackOptions = AttackOptions;
861
1758
  declare const DEFAULT_AIRBORNE_ATTACK_OPTIONS: Required<AirborneAttackOptions>;
@@ -935,7 +1832,7 @@ declare function createAttackByFire(coordinates: Position[], options?: AttackByF
935
1832
  /**
936
1833
  * Configuration options for the FLOT (Forward Line of Own Troops) geometry.
937
1834
  */
938
- interface FLOTOptions {
1835
+ interface FLOTOptions extends SmoothLineOptions, LineLabelOptions {
939
1836
  /**
940
1837
  * The radius of the semicircular arcs in meters.
941
1838
  * Semicircles are placed tangent to each other (diameter = 2 * radius).
@@ -967,7 +1864,7 @@ interface FLOTOptions {
967
1864
  /**
968
1865
  * Default options for the FLOT graphic.
969
1866
  */
970
- declare const DEFAULT_FLOT_OPTIONS: Required<Omit<FLOTOptions, "metersPerPixel">>;
1867
+ declare const DEFAULT_FLOT_OPTIONS: Required<Omit<FLOTOptions, keyof LineLabelOptions>>;
971
1868
  /**
972
1869
  * Creates a FLOT (Forward Line of Own Troops) tactical graphic.
973
1870
  *
@@ -987,20 +1884,155 @@ declare const DEFAULT_FLOT_OPTIONS: Required<Omit<FLOTOptions, "metersPerPixel">
987
1884
  * );
988
1885
  * ```
989
1886
  */
990
- declare function createFLOT(positions: Position[], options?: FLOTOptions): FeatureCollection<LineString>;
1887
+ declare function createFLOT(positions: Position[], options?: FLOTOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1888
+ //#endregion
1889
+ //#region src/generators/cm14-maneuver-lines/phase-line.d.ts
1890
+ /** Configuration options for the Phase line control measure. */
1891
+ interface PhaseLineOptions extends LineLabelOptions, SmoothLineOptions {
1892
+ /**
1893
+ * Prefix the end labels with "PL" (`"PL ECHO"`, or a bare `"PL"` when no
1894
+ * designation is set). When `false`, the label is the bare designation
1895
+ * (`Field T`) alone, and the line carries no label at all when `T` is empty.
1896
+ * @default true
1897
+ */
1898
+ includePrefix?: boolean;
1899
+ }
1900
+ /** Default options for the Phase line control measure. */
1901
+ declare const DEFAULT_PHASE_LINE_OPTIONS: PhaseLineOptions;
1902
+ /**
1903
+ * Creates a Phase line control measure: a polyline through `positions`
1904
+ * labeled at each end with `T` (optionally "PL"-prefixed).
1905
+ */
1906
+ declare function createPhaseLine(positions: Position[], options?: PhaseLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1907
+ //#endregion
1908
+ //#region src/generators/cm14-maneuver-lines/forward-edge-of-battle-area.d.ts
1909
+ /** Configuration options for the Forward edge of the battle area control measure. */
1910
+ interface ForwardEdgeOfBattleAreaOptions extends LineLabelOptions, SmoothLineOptions {
1911
+ /**
1912
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1913
+ * the line, additive to the fixed "FEBA" labels. Empty or whitespace-only
1914
+ * renders no label.
1915
+ * @default none
1916
+ */
1917
+ phaseLineName?: string;
1918
+ /**
1919
+ * Prefix the `phaseLineName` label with "PL" (`"PL MOCHA"`, or a bare
1920
+ * "MOCHA" when `false`). No effect when `phaseLineName` is empty.
1921
+ * @default true
1922
+ */
1923
+ includePrefix?: boolean;
1924
+ }
1925
+ /** Default options for the Forward edge of the battle area control measure. */
1926
+ declare const DEFAULT_FORWARD_EDGE_OF_BATTLE_AREA_OPTIONS: ForwardEdgeOfBattleAreaOptions;
1927
+ /**
1928
+ * Creates a Forward edge of the battle area control measure: a polyline
1929
+ * through `positions` labeled "FEBA" above the line near each end.
1930
+ */
1931
+ declare function createForwardEdgeOfBattleArea(positions: Position[], options?: ForwardEdgeOfBattleAreaOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1932
+ //#endregion
1933
+ //#region src/generators/cm14-maneuver-lines/bridgehead-line.d.ts
1934
+ /** Configuration options for the Bridgehead line control measure. */
1935
+ interface BridgeheadLineOptions extends LineLabelOptions, SmoothLineOptions {
1936
+ /** Optional phase-line name rendered beyond both ends of the line. */
1937
+ phaseLineName?: string;
1938
+ /** Prefix the phase-line name with "PL". @default true */
1939
+ includePrefix?: boolean;
1940
+ }
1941
+ /** Default options for the Bridgehead line control measure. */
1942
+ declare const DEFAULT_BRIDGEHEAD_LINE_OPTIONS: BridgeheadLineOptions;
1943
+ /** Creates a Bridgehead line labeled "BL" above both ends. */
1944
+ declare function createBridgeheadLine(positions: Position[], options?: BridgeheadLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1945
+ //#endregion
1946
+ //#region src/generators/cm14-maneuver-lines/holding-line.d.ts
1947
+ /** Configuration options for the Holding line control measure. */
1948
+ interface HoldingLineOptions extends LineLabelOptions, SmoothLineOptions {
1949
+ /** Optional phase-line name rendered beyond both ends of the line. */
1950
+ phaseLineName?: string;
1951
+ /** Prefix the phase-line name with "PL". @default true */
1952
+ includePrefix?: boolean;
1953
+ }
1954
+ /** Default options for the Holding line control measure. */
1955
+ declare const DEFAULT_HOLDING_LINE_OPTIONS: HoldingLineOptions;
1956
+ /** Creates a Holding line labeled "HL" above both ends. */
1957
+ declare function createHoldingLine(positions: Position[], options?: HoldingLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1958
+ //#endregion
1959
+ //#region src/generators/cm14-maneuver-lines/release-line.d.ts
1960
+ /** Configuration options for the Release line control measure. */
1961
+ interface ReleaseLineOptions extends LineLabelOptions, SmoothLineOptions {
1962
+ /** Optional phase-line name rendered beyond both ends of the line. */
1963
+ phaseLineName?: string;
1964
+ /** Prefix the phase-line name with "PL". @default true */
1965
+ includePrefix?: boolean;
1966
+ }
1967
+ /** Default options for the Release line control measure. */
1968
+ declare const DEFAULT_RELEASE_LINE_OPTIONS: ReleaseLineOptions;
1969
+ /** Creates a Release line labeled "RL" above both ends. */
1970
+ declare function createReleaseLine(positions: Position[], options?: ReleaseLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1971
+ //#endregion
1972
+ //#region src/generators/cm14-maneuver-lines/handover-line.d.ts
1973
+ /** Configuration options for the Handover line control measure. */
1974
+ interface HandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1975
+ /**
1976
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1977
+ * the line, additive to the fixed "HOL" labels. Empty or whitespace-only
1978
+ * renders no label.
1979
+ * @default none
1980
+ */
1981
+ phaseLineName?: string;
1982
+ /**
1983
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1984
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1985
+ * Phase Line itself, this measure already carries its own fixed "HOL"
1986
+ * label, so there is no bare "PL" fallback.
1987
+ * @default true
1988
+ */
1989
+ includePrefix?: boolean;
1990
+ }
1991
+ /** Default options for the Handover line control measure. */
1992
+ declare const DEFAULT_HANDOVER_LINE_OPTIONS: HandoverLineOptions;
1993
+ /**
1994
+ * Creates a Handover line control measure: a polyline through `positions`
1995
+ * labeled "HOL" above the line near each end.
1996
+ */
1997
+ declare function createHandoverLine(positions: Position[], options?: HandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1998
+ //#endregion
1999
+ //#region src/generators/cm14-maneuver-lines/battle-handover-line.d.ts
2000
+ /** Configuration options for the Battle handover line control measure. */
2001
+ interface BattleHandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
2002
+ /**
2003
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
2004
+ * the line, additive to the fixed "BHL" labels. Empty or whitespace-only
2005
+ * renders no label.
2006
+ * @default none
2007
+ */
2008
+ phaseLineName?: string;
2009
+ /**
2010
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
2011
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
2012
+ * Phase Line itself, this measure already carries its own fixed "BHL"
2013
+ * label, so there is no bare "PL" fallback.
2014
+ * @default true
2015
+ */
2016
+ includePrefix?: boolean;
2017
+ }
2018
+ /** Default options for the Battle handover line control measure. */
2019
+ declare const DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS: BattleHandoverLineOptions;
2020
+ /**
2021
+ * Creates a Battle handover line control measure: a polyline through
2022
+ * `positions` labeled "BHL" above the line near each end.
2023
+ */
2024
+ declare function createBattleHandoverLine(positions: Position[], options?: BattleHandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
991
2025
  //#endregion
992
2026
  //#region src/generators/cm34-mission-tasks/block.d.ts
993
2027
  interface BlockMissionTaskOptions {
994
2028
  /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
995
2029
  labelGapRatio?: number;
996
- /** Label height in CSS pixels at the draw/reference zoom. */
2030
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2031
+ labelSize?: number;
2032
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
997
2033
  labelSizePixels?: number;
998
- /** Map zoom at which labelSizePixels was captured. */
999
- labelSizeZoom?: number;
1000
- /** Map resolution at which labelSizePixels was captured. */
1001
- labelSizeResolution?: number;
1002
2034
  }
1003
- declare const DEFAULT_BLOCK_MISSION_TASK_OPTIONS: Required<Omit<BlockMissionTaskOptions, "labelSizePixels" | "labelSizeZoom" | "labelSizeResolution">>;
2035
+ declare const DEFAULT_BLOCK_MISSION_TASK_OPTIONS: Required<Omit<BlockMissionTaskOptions, "labelSize" | "labelSizePixels">>;
1004
2036
  /**
1005
2037
  * Generates a GeoJSON FeatureCollection for a BLOCK mission task symbol (340100).
1006
2038
  *
@@ -1024,17 +2056,15 @@ interface BreachOptions {
1024
2056
  tickAngle?: number;
1025
2057
  /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1026
2058
  labelGapRatio?: number;
1027
- /** Label height in CSS pixels at the draw/reference zoom. */
2059
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2060
+ labelSize?: number;
2061
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1028
2062
  labelSizePixels?: number;
1029
- /** Map zoom at which labelSizePixels was captured. */
1030
- labelSizeZoom?: number;
1031
- /** Map resolution at which labelSizePixels was captured. */
1032
- labelSizeResolution?: number;
1033
2063
  }
1034
2064
  /**
1035
2065
  * Default options for the BREACH symbol.
1036
2066
  */
1037
- declare const DEFAULT_BREACH_OPTIONS: Required<Omit<BreachOptions, "labelSizePixels" | "labelSizeZoom" | "labelSizeResolution">>;
2067
+ declare const DEFAULT_BREACH_OPTIONS: Required<Omit<BreachOptions, "labelSize" | "labelSizePixels">>;
1038
2068
  /**
1039
2069
  * Generates a GeoJSON FeatureCollection for a BREACH mission task symbol (340200).
1040
2070
  *
@@ -1057,17 +2087,15 @@ interface BypassOptions {
1057
2087
  arrowheadLengthRatio?: number;
1058
2088
  /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1059
2089
  labelGapRatio?: number;
1060
- /** Label height in CSS pixels at the draw/reference zoom. */
2090
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2091
+ labelSize?: number;
2092
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1061
2093
  labelSizePixels?: number;
1062
- /** Map zoom at which labelSizePixels was captured. */
1063
- labelSizeZoom?: number;
1064
- /** Map resolution at which labelSizePixels was captured. */
1065
- labelSizeResolution?: number;
1066
2094
  }
1067
2095
  /**
1068
2096
  * Default options for the BYPASS symbol.
1069
2097
  */
1070
- declare const DEFAULT_BYPASS_OPTIONS: Required<Omit<BypassOptions, "labelSizePixels" | "labelSizeZoom" | "labelSizeResolution">>;
2098
+ declare const DEFAULT_BYPASS_OPTIONS: Required<Omit<BypassOptions, "labelSize" | "labelSizePixels">>;
1071
2099
  /**
1072
2100
  * Generates a GeoJSON FeatureCollection for a BYPASS mission task symbol (340300).
1073
2101
  *
@@ -1092,17 +2120,15 @@ interface CanalizeOptions {
1092
2120
  tickAngle?: number;
1093
2121
  /** Gap for the 'C' label as a ratio of the front length (default: 0.2) */
1094
2122
  labelGapRatio?: number;
1095
- /** Label height in CSS pixels at the draw/reference zoom. */
2123
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2124
+ labelSize?: number;
2125
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1096
2126
  labelSizePixels?: number;
1097
- /** Map zoom at which labelSizePixels was captured. */
1098
- labelSizeZoom?: number;
1099
- /** Map resolution at which labelSizePixels was captured. */
1100
- labelSizeResolution?: number;
1101
2127
  }
1102
2128
  /**
1103
2129
  * Default options for the CANALIZE symbol.
1104
2130
  */
1105
- declare const DEFAULT_CANALIZE_OPTIONS: Required<Omit<CanalizeOptions, "labelSizePixels" | "labelSizeZoom" | "labelSizeResolution">>;
2131
+ declare const DEFAULT_CANALIZE_OPTIONS: Required<Omit<CanalizeOptions, "labelSize" | "labelSizePixels">>;
1106
2132
  /**
1107
2133
  * Generates a GeoJSON FeatureCollection for a CANALIZE mission task symbol (340400).
1108
2134
  *
@@ -1133,17 +2159,15 @@ interface ClearOptions {
1133
2159
  arrowheadWidthRatio?: number;
1134
2160
  /** Gap for the 'C' label as a ratio of the shaft length (default: 0.2). */
1135
2161
  labelGapRatio?: number;
1136
- /** Label height in CSS pixels at the draw/reference zoom. */
2162
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2163
+ labelSize?: number;
2164
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1137
2165
  labelSizePixels?: number;
1138
- /** Map zoom at which labelSizePixels was captured. */
1139
- labelSizeZoom?: number;
1140
- /** Map resolution at which labelSizePixels was captured. */
1141
- labelSizeResolution?: number;
1142
2166
  }
1143
2167
  /**
1144
2168
  * Default options for the CLEAR symbol.
1145
2169
  */
1146
- declare const DEFAULT_CLEAR_OPTIONS: Required<Omit<ClearOptions, "labelSizePixels" | "labelSizeZoom" | "labelSizeResolution">>;
2170
+ declare const DEFAULT_CLEAR_OPTIONS: Required<Omit<ClearOptions, "labelSize" | "labelSizePixels">>;
1147
2171
  /**
1148
2172
  * Generates a GeoJSON FeatureCollection for a CLEAR mission task symbol (340500).
1149
2173
  *
@@ -1167,6 +2191,51 @@ declare const DEFAULT_CLEAR_OPTIONS: Required<Omit<ClearOptions, "labelSizePixel
1167
2191
  */
1168
2192
  declare function createClearSymbol(coordinates: Position[], options?: ClearOptions): FeatureCollection<MultiLineString | Point>;
1169
2193
  //#endregion
2194
+ //#region src/generators/cm34-mission-tasks/counterattack.d.ts
2195
+ interface CounterattackOptions extends AttackOptions, LabelSizeOptions {
2196
+ /** CATK label position along the shaft, from tail (0) to arrowhead base (1). */
2197
+ labelPosition?: number;
2198
+ }
2199
+ declare const DEFAULT_COUNTERATTACK_OPTIONS: Required<Omit<CounterattackOptions, keyof LabelSizeOptions>>;
2200
+ /** Generates the Counterattack mission task (340600). */
2201
+ declare function createCounterattack(coordinates: Position[], options?: CounterattackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
2202
+ //#endregion
2203
+ //#region src/generators/cm15-maneuver-areas/searchArea.d.ts
2204
+ /**
2205
+ * Configuration options to tweak the tactical arrow's geometry.
2206
+ */
2207
+ interface TacticalArrowOptions {
2208
+ /** Ratio of arrowhead length to total leg length (default: 0.12) */
2209
+ arrowheadLengthRatio?: number;
2210
+ /** Width multiplier for the arrowhead wings (default: 0.5) */
2211
+ arrowheadWidthRatio?: number;
2212
+ /** Percentage along the leg where the zigzag begins, 0.0-1.0 (default: 0.55) */
2213
+ zigzagStart?: number;
2214
+ /** Percentage along the leg where the zigzag returns, 0.0-1.0 (default: 0.45) */
2215
+ zigzagEnd?: number;
2216
+ /** Perpendicular offset for the lightning "kink", relative to leg length (default: 0.07) */
2217
+ zigzagAmplitudeRatio?: number;
2218
+ }
2219
+ /**
2220
+ * Default options for the tactical arrow.
2221
+ */
2222
+ declare const DEFAULT_TACTICAL_ARROW_OPTIONS: Required<TacticalArrowOptions>;
2223
+ //#endregion
2224
+ //#region src/generators/cm34-mission-tasks/security-task-shared.d.ts
2225
+ interface SecurityTaskOptions extends TacticalArrowOptions {
2226
+ /** Position of each task letter inward from PT. 2/PT. 3 as a ratio of the opening. */
2227
+ labelInsetRatio?: number;
2228
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2229
+ labelSize?: number;
2230
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2231
+ labelSizePixels?: number;
2232
+ }
2233
+ //#endregion
2234
+ //#region src/generators/cm34-mission-tasks/cover.d.ts
2235
+ type CoverOptions = SecurityTaskOptions;
2236
+ declare const DEFAULT_COVER_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2237
+ declare function createCoverSymbol(coordinates: Position[], options?: CoverOptions): FeatureCollection<MultiLineString | Point>;
2238
+ //#endregion
1170
2239
  //#region src/generators/cm34-mission-tasks/delay.d.ts
1171
2240
  interface DelayOptions {
1172
2241
  /** Arrowhead depth as a ratio of the straight-line length (default: 0.12). */
@@ -1177,16 +2246,19 @@ interface DelayOptions {
1177
2246
  labelGapRatio?: number;
1178
2247
  /** Number of segments used to approximate the 180-degree arc (default: 32). */
1179
2248
  arcSegments?: number;
1180
- /** Label height in CSS pixels at the draw/reference zoom. */
2249
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2250
+ labelSize?: number;
2251
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1181
2252
  labelSizePixels?: number;
1182
- /** Map zoom at which labelSizePixels was captured. */
1183
- labelSizeZoom?: number;
1184
- /** Map resolution at which labelSizePixels was captured. */
1185
- labelSizeResolution?: number;
1186
2253
  }
1187
- declare const DEFAULT_DELAY_OPTIONS: Required<Omit<DelayOptions, "labelSizePixels" | "labelSizeZoom" | "labelSizeResolution">>;
2254
+ declare const DEFAULT_DELAY_OPTIONS: Required<Omit<DelayOptions, "labelSize" | "labelSizePixels">>;
1188
2255
  declare function createDelaySymbol(coordinates: Position[], options?: DelayOptions): FeatureCollection<MultiLineString | Point>;
1189
2256
  //#endregion
2257
+ //#region src/generators/cm34-mission-tasks/guard.d.ts
2258
+ type GuardOptions = SecurityTaskOptions;
2259
+ declare const DEFAULT_GUARD_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2260
+ declare function createGuardSymbol(coordinates: Position[], options?: GuardOptions): FeatureCollection<MultiLineString | Point>;
2261
+ //#endregion
1190
2262
  //#region src/generators/cm34-mission-tasks/isolate.d.ts
1191
2263
  /**
1192
2264
  * Configuration options for the ISOLATE tactical mission task symbol.
@@ -1221,8 +2293,13 @@ interface IsolateOptions {
1221
2293
  */
1222
2294
  declare function createIsolateSymbol(coordinates: Position[], options?: IsolateOptions): FeatureCollection<MultiLineString>;
1223
2295
  //#endregion
2296
+ //#region src/generators/cm34-mission-tasks/screen.d.ts
2297
+ type ScreenOptions = SecurityTaskOptions;
2298
+ declare const DEFAULT_SCREEN_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2299
+ declare function createScreenSymbol(coordinates: Position[], options?: ScreenOptions): FeatureCollection<MultiLineString | Point>;
2300
+ //#endregion
1224
2301
  //#region src/generators/cm29-protection-lines/antitankDitch.d.ts
1225
- interface AntitankDitchOptions {
2302
+ interface AntitankDitchOptions extends SmoothLineOptions, LineLabelOptions {
1226
2303
  /**
1227
2304
  * The tooth depth in meters. Target tooth spacing is roughly 1.15x this depth.
1228
2305
  * Ignored when toothHeightPixels is provided with metersPerPixel.
@@ -1247,14 +2324,9 @@ interface AntitankDitchOptions {
1247
2324
  */
1248
2325
  metersPerPixel?: number;
1249
2326
  }
1250
- declare const DEFAULT_ANTITANK_DITCH_OPTIONS: Required<Omit<AntitankDitchOptions, "metersPerPixel">>;
1251
- declare function createAntitankDitchUnderConstruction(positions: Position[], options?: AntitankDitchOptions): FeatureCollection<MultiLineString, {
1252
- part: "ditch";
1253
- }>;
1254
- declare function createAntitankDitchCompleted(positions: Position[], options?: AntitankDitchOptions): FeatureCollection<MultiPolygon, {
1255
- part: "teeth";
1256
- fill: boolean;
1257
- }>;
2327
+ declare const DEFAULT_ANTITANK_DITCH_OPTIONS: Required<Omit<AntitankDitchOptions, keyof LineLabelOptions>>;
2328
+ declare function createAntitankDitchUnderConstruction(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2329
+ declare function createAntitankDitchCompleted(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiPolygon | Point>;
1258
2330
  //#endregion
1259
2331
  //#region src/generators/cm29-protection-lines/antitankWall.d.ts
1260
2332
  interface AntitankWallOptions extends AntitankDitchOptions {
@@ -1265,16 +2337,14 @@ interface AntitankWallOptions extends AntitankDitchOptions {
1265
2337
  */
1266
2338
  toothSpacingRatio?: number;
1267
2339
  }
1268
- declare const DEFAULT_ANTITANK_WALL_OPTIONS: Required<Omit<AntitankWallOptions, "metersPerPixel">>;
1269
- declare function createAntitankWall(positions: Position[], options?: AntitankWallOptions): FeatureCollection<MultiLineString, {
1270
- part: "wall";
1271
- }>;
2340
+ declare const DEFAULT_ANTITANK_WALL_OPTIONS: Required<Omit<AntitankWallOptions, keyof LineLabelOptions>>;
2341
+ declare function createAntitankWall(positions: Position[], options?: AntitankWallOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
1272
2342
  //#endregion
1273
2343
  //#region src/generators/cm29-protection-lines/fortifiedLine.d.ts
1274
2344
  /**
1275
2345
  * Configuration options for the Fortified Line geometry.
1276
2346
  */
1277
- interface FortifiedLineOptions {
2347
+ interface FortifiedLineOptions extends LineLabelOptions {
1278
2348
  /**
1279
2349
  * The size of the square teeth in meters.
1280
2350
  * This controls both the width and height of the castellated pattern.
@@ -1314,7 +2384,7 @@ interface FortifiedLineOptions {
1314
2384
  /**
1315
2385
  * Default options for the Fortified Line graphic.
1316
2386
  */
1317
- declare const DEFAULT_FORTIFIED_LINE_OPTIONS: Required<Omit<FortifiedLineOptions, "metersPerPixel">>;
2387
+ declare const DEFAULT_FORTIFIED_LINE_OPTIONS: Required<Omit<FortifiedLineOptions, keyof LineLabelOptions>>;
1318
2388
  /**
1319
2389
  * Creates a Fortified Line tactical graphic.
1320
2390
  *
@@ -1325,16 +2395,20 @@ declare const DEFAULT_FORTIFIED_LINE_OPTIONS: Required<Omit<FortifiedLineOptions
1325
2395
  * @param options - Configuration options for the graphic
1326
2396
  * @returns A GeoJSON FeatureCollection containing the castellated LineString
1327
2397
  */
1328
- declare function createFortifiedLine(positions: Position[], options?: FortifiedLineOptions): FeatureCollection<LineString>;
2398
+ declare function createFortifiedLine(positions: Position[], options?: FortifiedLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1329
2399
  //#endregion
1330
2400
  //#region src/generators/cm15-maneuver-areas/fortifiedArea.d.ts
1331
2401
  /**
1332
2402
  * Configuration options for the Fortified Area. Inherits the Fortified Line
1333
2403
  * options (including `smooth`/`smoothResolution`) unchanged; the area applies
1334
- * the smoothing as a closed Catmull-Rom ring rather than an open spline.
2404
+ * the smoothing as a closed Catmull-Rom ring rather than an open spline. Also
2405
+ * carries the shared {@link AreaLabelOptions} label placement (a plain
2406
+ * intersection, not a re-derivation, so the aliased
2407
+ * {@link DEFAULT_FORTIFIED_AREA_OPTIONS} default still typechecks unchanged —
2408
+ * `AreaLabelOptions`'s fields are all optional).
1335
2409
  */
1336
- type FortifiedAreaOptions = FortifiedLineOptions;
1337
- declare const DEFAULT_FORTIFIED_AREA_OPTIONS: Required<Omit<FortifiedLineOptions, "metersPerPixel">>;
2410
+ type FortifiedAreaOptions = FortifiedLineOptions & AreaLabelOptions;
2411
+ declare const DEFAULT_FORTIFIED_AREA_OPTIONS: FortifiedAreaOptions;
1338
2412
  /**
1339
2413
  * Creates a Fortified Area tactical graphic.
1340
2414
  *
@@ -1345,9 +2419,42 @@ declare const DEFAULT_FORTIFIED_AREA_OPTIONS: Required<Omit<FortifiedLineOptions
1345
2419
  * The first and last positions should match to close the polygon,
1346
2420
  * or it will be closed automatically.
1347
2421
  * @param options - Configuration options for the graphic
1348
- * @returns A GeoJSON FeatureCollection containing the castellated Polygon
1349
- */
1350
- declare function createFortifiedArea(positions: Position[], options?: FortifiedAreaOptions): FeatureCollection<Polygon>;
2422
+ * @param textAmplifiers - Field T (bare, no prefix — "TANGO", not "FA TANGO")
2423
+ * plus Field H/W/W1, centered on the pre-teeth boundary ring (see
2424
+ * `boundaryInput` below), and an optional Field N "ENY" hostile marker on
2425
+ * that ring's west/east edges, masking the castellated boundary beneath it.
2426
+ * @param context - Persisted amplifier placements used to move or restore each
2427
+ * ENY cutout with its independently dragged label.
2428
+ * @returns A GeoJSON FeatureCollection containing the castellated boundary
2429
+ * (a Polygon normally, or a gapped MultiLineString with Field N) plus any
2430
+ * label Points
2431
+ */
2432
+ declare function createFortifiedArea(positions: Position[], options?: FortifiedAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
2433
+ //#endregion
2434
+ //#region src/generators/cm15-maneuver-areas/maneuver-arrow-task-shared.d.ts
2435
+ interface ManeuverArrowTaskOptions extends AttackOptions, LabelSizeOptions {
2436
+ /** Straight crossbar length as a multiple of the arrowhead base width. */
2437
+ crossbarLengthRatio?: number;
2438
+ /** Field T position along the shaft, from tail (0) to head (1). */
2439
+ labelPosition?: number;
2440
+ /** W/W1 position along the shaft, from tail (0) to head (1). */
2441
+ dtgPosition?: number;
2442
+ /** Extra W/W1 row spacing, in label heights. */
2443
+ labelPadding?: number;
2444
+ }
2445
+ //#endregion
2446
+ //#region src/generators/cm15-maneuver-areas/frontal-attack.d.ts
2447
+ type FrontalAttackOptions = ManeuverArrowTaskOptions;
2448
+ declare const DEFAULT_FRONTAL_ATTACK_OPTIONS: FrontalAttackOptions;
2449
+ declare function createFrontalAttack(coordinates: Position[], options?: FrontalAttackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2450
+ //#endregion
2451
+ //#region src/generators/cm15-maneuver-areas/turning-movement.d.ts
2452
+ interface TurningMovementOptions extends ManeuverArrowTaskOptions {
2453
+ /** Crossbar position along the shaft, from tail (0) to arrowhead base (1). */
2454
+ crossbarPosition?: number;
2455
+ }
2456
+ declare const DEFAULT_TURNING_MOVEMENT_OPTIONS: TurningMovementOptions;
2457
+ declare function createTurningMovement(coordinates: Position[], options?: TurningMovementOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
1351
2458
  //#endregion
1352
2459
  //#region src/generators/cm27-protection-areas/block.d.ts
1353
2460
  type BlockOptions = Record<never, never>;
@@ -1493,17 +2600,47 @@ declare function createObstacleBypassImpossible(coordinates: Position[], options
1493
2600
  */
1494
2601
  declare const DEFINITIONS: {
1495
2602
  boundary: ControlMeasureDefinition<"boundary", typeof createBoundary>;
2603
+ "light-line": ControlMeasureDefinition<"light-line", typeof createLightLine>;
2604
+ "engineer-work-line": ControlMeasureDefinition<"engineer-work-line", typeof createEngineerWorkLine>;
2605
+ "generic-c2-line": ControlMeasureDefinition<"generic-c2-line", typeof createGenericC2Line>;
1496
2606
  "battle-position": ControlMeasureDefinition<"battle-position", typeof createBattlePosition>;
1497
2607
  "strong-point": ControlMeasureDefinition<"strong-point", typeof createStrongPoint>;
1498
2608
  ambush: ControlMeasureDefinition<"ambush", (controlPoints: import("geojson").Position[], options?: AmbushOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString, Record<string, never>>>;
2609
+ "direction-of-attack-aviation": ControlMeasureDefinition<"direction-of-attack-aviation", typeof createDirectionOfAttackAviation>;
2610
+ "direction-of-main-attack": ControlMeasureDefinition<"direction-of-main-attack", typeof createDirectionOfMainAttack>;
2611
+ "direction-of-supporting-attack": ControlMeasureDefinition<"direction-of-supporting-attack", typeof createDirectionOfSupportingAttack>;
1499
2612
  "principal-direction-of-fire": ControlMeasureDefinition<"principal-direction-of-fire", typeof createPrincipalDirectionOfFire>;
2613
+ "secondary-direction-of-fire": ControlMeasureDefinition<"secondary-direction-of-fire", typeof createSecondaryDirectionOfFire>;
1500
2614
  "final-protective-fire-left": ControlMeasureDefinition<"final-protective-fire-left", typeof createFinalProtectiveFireLeft>;
1501
2615
  "final-protective-fire-right": ControlMeasureDefinition<"final-protective-fire-right", typeof createFinalProtectiveFireRight>;
1502
2616
  "search-area": ControlMeasureDefinition<"search-area", (controlPoints: import("geojson").Position[], options?: TacticalArrowOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString | import("geojson").MultiPolygon, {
1503
2617
  part: "shaft" | "head";
1504
2618
  fill?: boolean;
2619
+ style?: StyleHints;
1505
2620
  }>>;
1506
2621
  encirclement: ControlMeasureDefinition<"encirclement", typeof createEncirclement>;
2622
+ area: ControlMeasureDefinition<"area", typeof createArea>;
2623
+ "area-defense": ControlMeasureDefinition<"area-defense", typeof createAreaDefense>;
2624
+ "assembly-area": ControlMeasureDefinition<"assembly-area", typeof createAssemblyArea>;
2625
+ "joint-tactical-action-area": ControlMeasureDefinition<"joint-tactical-action-area", typeof createJointTacticalActionArea>;
2626
+ "submarine-action-area": ControlMeasureDefinition<"submarine-action-area", typeof createSubmarineActionArea>;
2627
+ "submarine-generated-action-area": ControlMeasureDefinition<"submarine-generated-action-area", typeof createSubmarineGeneratedActionArea>;
2628
+ "drop-zone": ControlMeasureDefinition<"drop-zone", typeof createDropZone>;
2629
+ "extraction-zone": ControlMeasureDefinition<"extraction-zone", typeof createExtractionZone>;
2630
+ "landing-zone": ControlMeasureDefinition<"landing-zone", typeof createLandingZone>;
2631
+ "limited-access-area": ControlMeasureDefinition<"limited-access-area", typeof createLimitedAccessArea>;
2632
+ "no-fire-area-irregular": ControlMeasureDefinition<"no-fire-area-irregular", typeof createNoFireAreaIrregular>;
2633
+ "pickup-zone": ControlMeasureDefinition<"pickup-zone", typeof createPickupZone>;
2634
+ "assault-position": ControlMeasureDefinition<"assault-position", typeof createAssaultPosition>;
2635
+ "attack-position": ControlMeasureDefinition<"attack-position", typeof createAttackPosition>;
2636
+ "objective-area": ControlMeasureDefinition<"objective-area", typeof createObjectiveArea>;
2637
+ "area-of-operations": ControlMeasureDefinition<"area-of-operations", typeof createAreaOfOperations>;
2638
+ "named-area-of-interest": ControlMeasureDefinition<"named-area-of-interest", typeof createNamedAreaOfInterest>;
2639
+ "target-area-of-interest": ControlMeasureDefinition<"target-area-of-interest", typeof createTargetAreaOfInterest>;
2640
+ "airfield-zone": ControlMeasureDefinition<"airfield-zone", typeof createAirfieldZone>;
2641
+ "base-camp": ControlMeasureDefinition<"base-camp", typeof createBaseCamp>;
2642
+ "guerrilla-base": ControlMeasureDefinition<"guerrilla-base", typeof createGuerrillaBase>;
2643
+ "generic-c2-area": ControlMeasureDefinition<"generic-c2-area", typeof createGenericC2Area>;
1507
2644
  "main-attack": ControlMeasureDefinition<"main-attack", typeof createMainAttack>;
1508
2645
  "supporting-attack": ControlMeasureDefinition<"supporting-attack", typeof createSupportingAttack>;
1509
2646
  "classic-arrow": ControlMeasureDefinition<"classic-arrow", typeof createClassicArrow>;
@@ -1512,23 +2649,37 @@ declare const DEFINITIONS: {
1512
2649
  polygon: ControlMeasureDefinition<"polygon", typeof createGenericPolygon>;
1513
2650
  rectangle: ControlMeasureDefinition<"rectangle", typeof createGenericRectangle>;
1514
2651
  circle: ControlMeasureDefinition<"circle", typeof createGenericCircle>;
2652
+ text: ControlMeasureDefinition<"text", typeof createGenericText>;
1515
2653
  "airborne-attack": ControlMeasureDefinition<"airborne-attack", typeof createAirborneAttack>;
1516
2654
  "attack-helicopter": ControlMeasureDefinition<"attack-helicopter", typeof createAttackHelicopter>;
1517
2655
  "support-by-fire": ControlMeasureDefinition<"support-by-fire", typeof createSupportByFire>;
1518
2656
  "attack-by-fire": ControlMeasureDefinition<"attack-by-fire", typeof createAttackByFire>;
1519
2657
  flot: ControlMeasureDefinition<"flot", typeof createFLOT>;
2658
+ "phase-line": ControlMeasureDefinition<"phase-line", typeof createPhaseLine>;
2659
+ "forward-edge-of-battle-area": ControlMeasureDefinition<"forward-edge-of-battle-area", typeof createForwardEdgeOfBattleArea>;
2660
+ "bridgehead-line": ControlMeasureDefinition<"bridgehead-line", typeof createBridgeheadLine>;
2661
+ "holding-line": ControlMeasureDefinition<"holding-line", typeof createHoldingLine>;
2662
+ "release-line": ControlMeasureDefinition<"release-line", typeof createReleaseLine>;
2663
+ "handover-line": ControlMeasureDefinition<"handover-line", typeof createHandoverLine>;
2664
+ "battle-handover-line": ControlMeasureDefinition<"battle-handover-line", typeof createBattleHandoverLine>;
1520
2665
  "block-mission-task": ControlMeasureDefinition<"block-mission-task", typeof createBlockMissionTaskSymbol>;
1521
2666
  breach: ControlMeasureDefinition<"breach", typeof createBreachSymbol>;
1522
2667
  bypass: ControlMeasureDefinition<"bypass", typeof createBypassSymbol>;
1523
2668
  canalize: ControlMeasureDefinition<"canalize", typeof createCanalizeSymbol>;
1524
2669
  clear: ControlMeasureDefinition<"clear", typeof createClearSymbol>;
2670
+ counterattack: ControlMeasureDefinition<"counterattack", typeof createCounterattack>;
2671
+ cover: ControlMeasureDefinition<"cover", typeof createCoverSymbol>;
1525
2672
  delay: ControlMeasureDefinition<"delay", typeof createDelaySymbol>;
2673
+ guard: ControlMeasureDefinition<"guard", typeof createGuardSymbol>;
1526
2674
  isolate: ControlMeasureDefinition<"isolate", typeof createIsolateSymbol>;
2675
+ screen: ControlMeasureDefinition<"screen", typeof createScreenSymbol>;
1527
2676
  "antitank-ditch-under-construction": ControlMeasureDefinition<"antitank-ditch-under-construction", typeof createAntitankDitchUnderConstruction>;
1528
2677
  "antitank-ditch-completed": ControlMeasureDefinition<"antitank-ditch-completed", typeof createAntitankDitchCompleted>;
1529
2678
  "antitank-wall": ControlMeasureDefinition<"antitank-wall", typeof createAntitankWall>;
1530
2679
  "fortified-line": ControlMeasureDefinition<"fortified-line", typeof createFortifiedLine>;
1531
2680
  "fortified-area": ControlMeasureDefinition<"fortified-area", typeof createFortifiedArea>;
2681
+ "frontal-attack": ControlMeasureDefinition<"frontal-attack", typeof createFrontalAttack>;
2682
+ "turning-movement": ControlMeasureDefinition<"turning-movement", typeof createTurningMovement>;
1532
2683
  block: ControlMeasureDefinition<"block", typeof createBlock>;
1533
2684
  disrupt: ControlMeasureDefinition<"disrupt", typeof createDisrupt>;
1534
2685
  fix: ControlMeasureDefinition<"fix", typeof createFix>;
@@ -1562,30 +2713,6 @@ declare function getControlMeasureMetadata(id: ControlMeasureId): ControlMeasure
1562
2713
  declare function getControlMeasureMetadataByValue(value: string): ControlMeasureMetadata | undefined;
1563
2714
  declare function getDefaultOptions<K extends ControlMeasureKind>(kind: K): OptionsByKind[K];
1564
2715
  //#endregion
1565
- //#region src/style.d.ts
1566
- /**
1567
- * Framework-agnostic style hints attached to a `ControlMeasure`.
1568
- *
1569
- * Mirrors the per-feature subset of what map adapters render. The renderer
1570
- * fans these into each emitted feature's `properties.style` ([[StyleHints]]).
1571
- * Adapters merge them over their layer-level style; generator-emitted hints
1572
- * on individual features win over both.
1573
- */
1574
- interface ControlMeasureStyle {
1575
- /**
1576
- * The single symbol color. Control measures are monocolor: one color paints
1577
- * every part, stroked or filled. Input-only — resolved into concrete
1578
- * `strokeColor` / `fillColor` per feature by the renderer and never emitted
1579
- * on output. `strokeColor` / `fillColor` act as optional per-channel
1580
- * overrides. See ADR-0011.
1581
- */
1582
- color?: string;
1583
- strokeColor?: string;
1584
- strokeWidth?: number;
1585
- strokeDash?: number[];
1586
- fillColor?: string;
1587
- }
1588
- //#endregion
1589
2716
  //#region src/instance.d.ts
1590
2717
  interface ControlMeasure<K extends ControlMeasureKind = ControlMeasureKind> {
1591
2718
  id: string;
@@ -1596,13 +2723,15 @@ interface ControlMeasure<K extends ControlMeasureKind = ControlMeasureKind> {
1596
2723
  properties?: Record<string, unknown>;
1597
2724
  /** Free-text amplifier fields (MIL-STD-2525E Appendix L Table L-II); see `./text-amplifiers`. */
1598
2725
  textAmplifiers?: TextAmplifiers;
2726
+ /** Optional user-adjusted anchors for independently rendered text amplifiers. */
2727
+ amplifierPlacements?: AmplifierPlacements;
1599
2728
  schemaVersion?: 1;
1600
2729
  }
1601
2730
  declare function isKind<K extends ControlMeasureKind>(cm: ControlMeasure, kind: K): cm is ControlMeasure<K>;
1602
2731
  /**
1603
2732
  * Deep-clone a `ControlMeasure` so held references survive mutations to the
1604
2733
  * original (and vice versa). Used by the session façade to build the
1605
- * `measure` half of `ControlMeasureSnapshot`. Nested values inside
2734
+ * `graphic` half of TacticalDraw's `GraphicSnapshot`. Nested values inside
1606
2735
  * `options`, `style`, `properties`, and `textAmplifiers` are cloned too —
1607
2736
  * `properties` is `Record<string, unknown>` and may carry arbitrary host
1608
2737
  * metadata, so a shallow copy would leak shared references.
@@ -1613,82 +2742,6 @@ declare function isKind<K extends ControlMeasureKind>(cm: ControlMeasure, kind:
1613
2742
  */
1614
2743
  declare function cloneControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>): ControlMeasure<K>;
1615
2744
  //#endregion
1616
- //#region src/rendered.d.ts
1617
- /**
1618
- * Per-feature style hints carried on `properties.style`.
1619
- *
1620
- * These are *resolved*: `renderControlMeasure` cascades `graphicsStyle` →
1621
- * `cm.style` → any generator pattern hint, then expands the monocolor `color`
1622
- * into concrete `strokeColor` / `fillColor` per feature (see ADR-0011 and
1623
- * `resolveSymbolColor`). Output therefore carries concrete colors, never the
1624
- * input-only `color` key, and a `fillColor` only on parts the generator
1625
- * marked filled.
1626
- *
1627
- * Generators contribute paint *role* and *pattern* (a part is filled; a
1628
- * sub-line is dashed regardless of the user's stroke), never a hue. Adapters
1629
- * merge the resulting `StyleHints` over their layer-level style at draw time.
1630
- */
1631
- interface StyleHints extends ControlMeasureStyle {}
1632
- /**
1633
- * Per-feature properties emitted by `renderControlMeasure`.
1634
- *
1635
- * Stable-id contract — every feature produced by the renderer has:
1636
- * - `feature.id` of the form `${cmId}:${part}:${index}`
1637
- * - `properties.part` matching the `part` segment of the id
1638
- * - `properties.index` matching the `index` segment of the id
1639
- *
1640
- * Adapters rely on this contract to diff renders in place without keeping
1641
- * their own bookkeeping. Use `controlMeasureIdFromFeature` to recover the
1642
- * `cmId` from a picked feature.
1643
- */
1644
- interface FeaturePartProps {
1645
- part: string;
1646
- index: number;
1647
- style?: StyleHints;
1648
- /** Label text emitted by generators (e.g. breach "B"). */
1649
- text?: string;
1650
- /** Label rotation in radians, emitted by generators. */
1651
- rotation?: number;
1652
- /**
1653
- * Horizontal text alignment relative to the label point: `"start"` = the
1654
- * text begins at the point, `"end"` = it ends there. Absent = centered.
1655
- */
1656
- textAnchor?: "start" | "end";
1657
- /** Label size in CSS pixels at the draw/reference zoom. */
1658
- textSizePixels?: number;
1659
- /** Map zoom at which textSizePixels was captured. */
1660
- textSizeZoom?: number;
1661
- /** Map resolution at which textSizePixels was captured. */
1662
- textSizeResolution?: number;
1663
- }
1664
- /**
1665
- * Output of `renderControlMeasure`. A GeoJSON `FeatureCollection` whose
1666
- * features satisfy the `FeaturePartProps` stable-id contract. See ADR-0010.
1667
- */
1668
- type ControlMeasureRender = FeatureCollection<Geometry, FeaturePartProps>;
1669
- /**
1670
- * A `ControlMeasure` paired with its `Render` at a single point in time.
1671
- *
1672
- * The unit delivered to `EditChangeEvent` listeners (as `measure` and
1673
- * `previous`) and resolved from `TacticalDraw.draw()` / `.edit()`. The
1674
- * `measure` half is a defensive clone (see `cloneControlMeasure`) so held
1675
- * references remain valid after the originating session has closed.
1676
- *
1677
- * See ADR-0010.
1678
- */
1679
- interface ControlMeasureSnapshot<K extends ControlMeasureKind = ControlMeasureKind> {
1680
- measure: ControlMeasure<K>;
1681
- render: ControlMeasureRender;
1682
- }
1683
- /**
1684
- * Recover the originating control measure id (`cmId`) from a feature emitted
1685
- * by `renderControlMeasure`. The feature id must match the stable-id contract
1686
- * `${cmId}:${part}:${index}`; otherwise this throws.
1687
- */
1688
- declare function controlMeasureIdFromFeature(feature: Feature<Geometry, FeaturePartProps> | {
1689
- id?: string | number;
1690
- }): string;
1691
- //#endregion
1692
2745
  //#region src/renderControlMeasure.d.ts
1693
2746
  interface RenderOptions {
1694
2747
  validationMode?: ValidationMode;
@@ -1718,6 +2771,16 @@ declare function renderControlMeasure<K extends ControlMeasureKind>(cm: ControlM
1718
2771
  * freeze. Edit hosts call this when a rotate gesture starts (ADR-0023).
1719
2772
  */
1720
2773
  declare function freezeOrientationOptions<K extends ControlMeasureKind>(kind: K, controlPoints: Position[], options: OptionsByKind[K] | undefined): Partial<OptionsByKind[K]> | undefined;
2774
+ /**
2775
+ * Dispatches to a measure kind's `transformOptions` hook (see
2776
+ * {@link import("./define").ControlMeasureDefinition.transformOptions}), folding
2777
+ * a box transform gesture's `delta` (screen-space scale/rotation) into option
2778
+ * values for a graphic that persists orientation/size as options rather than in
2779
+ * geometry. Returns an options patch to merge, or `undefined` when the kind
2780
+ * declares no hook (or the hook finds nothing to fold). Edit hosts call this at
2781
+ * a rotate/scale gesture's commit (ADR-0017).
2782
+ */
2783
+ declare function applyBoxTransformOptions<K extends ControlMeasureKind>(kind: K, options: OptionsByKind[K] | undefined, delta: BoxTransformDelta): Partial<OptionsByKind[K]> | undefined;
1721
2784
  //#endregion
1722
2785
  //#region src/styleResolver.d.ts
1723
2786
  /**
@@ -1765,8 +2828,9 @@ type SimpleStyleRender = FeatureCollection<Geometry, SimpleStyleProps>;
1765
2828
  * three-layer merge and stays a pure post-processing step.
1766
2829
  *
1767
2830
  * Lossy mapping, by design:
1768
- * - `strokeDash` has no simplestyle equivalent and is dropped — dashed
1769
- * doctrinal sub-lines render solid in simplestyle consumers.
2831
+ * - `strokeDash` and `fillPattern` have no simplestyle equivalent and are
2832
+ * dropped — dashed sub-lines and patterned fills render solid in
2833
+ * simplestyle consumers.
1770
2834
  * - colors must be hex or `rgb()/rgba()`; alpha becomes `*-opacity`. Other
1771
2835
  * color forms (named, `hsl()`) are omitted rather than guessed.
1772
2836
  */
@@ -1830,6 +2894,8 @@ interface MidpointPerpendicularDrawRuleOptions {
1830
2894
  minimumUserPoints?: number;
1831
2895
  /** Raw points at which a live preview can be derived. See {@link ControlMeasureDrawRule}. */
1832
2896
  minimumPreviewPoints?: number;
2897
+ /** Allow a repeated last point to commit the early derived preview. */
2898
+ finishOnLastPointRepeat?: boolean;
1833
2899
  /**
1834
2900
  * Index of the slot whose point is constrained to the perpendicular axis
1835
2901
  * through the configured origin of the other two ("baseline") slots. Must be
@@ -1931,6 +2997,19 @@ declare const line23DrawRule: ControlMeasureDrawRule;
1931
2997
  */
1932
2998
  declare const line24DrawRule: ControlMeasureDrawRule;
1933
2999
  //#endregion
3000
+ //#region src/draw-rules/line26.d.ts
3001
+ /**
3002
+ * Line26 anchor draw rule for the Cover, Guard, and Screen security tasks.
3003
+ *
3004
+ * PT. 1/PT. 4 are the outward arrow tips and PT. 2/PT. 3 bound the opening
3005
+ * reserved for the supported tactical symbol. All four anchors are free: the
3006
+ * two sides may independently touch the symbols that define the task limits.
3007
+ * During drawing, the cursor after PT. 1 supplies a provisional PT. 2 and the
3008
+ * rule mirrors that first leg across a temporary center opening, so the full
3009
+ * symbol is visible before PT. 2 is committed.
3010
+ */
3011
+ declare const line26DrawRule: ControlMeasureDrawRule;
3012
+ //#endregion
1934
3013
  //#region src/draw-rules/area8.d.ts
1935
3014
  declare const supportByFireDrawRule: ControlMeasureDrawRule;
1936
3015
  //#endregion
@@ -1960,25 +3039,4 @@ interface AmbushOptions {
1960
3039
  }
1961
3040
  declare const DEFAULT_AMBUSH_OPTIONS: Required<AmbushOptions>;
1962
3041
  //#endregion
1963
- //#region src/generators/cm15-maneuver-areas/searchArea.d.ts
1964
- /**
1965
- * Configuration options to tweak the tactical arrow's geometry.
1966
- */
1967
- interface TacticalArrowOptions {
1968
- /** Ratio of arrowhead length to total leg length (default: 0.12) */
1969
- arrowheadLengthRatio?: number;
1970
- /** Width multiplier for the arrowhead wings (default: 0.5) */
1971
- arrowheadWidthRatio?: number;
1972
- /** Percentage along the leg where the zigzag begins, 0.0-1.0 (default: 0.55) */
1973
- zigzagStart?: number;
1974
- /** Percentage along the leg where the zigzag returns, 0.0-1.0 (default: 0.45) */
1975
- zigzagEnd?: number;
1976
- /** Perpendicular offset for the lightning "kink", relative to leg length (default: 0.07) */
1977
- zigzagAmplitudeRatio?: number;
1978
- }
1979
- /**
1980
- * Default options for the tactical arrow.
1981
- */
1982
- declare const DEFAULT_TACTICAL_ARROW_OPTIONS: Required<TacticalArrowOptions>;
1983
- //#endregion
1984
- export { getControlMeasureMetadata as $, DEFAULT_GENERIC_LINE_OPTIONS as $t, getMetersPerPixel as A, ControlMeasureMetadata as An, DEFAULT_CANALIZE_OPTIONS as At, ControlMeasureSnapshot as B, AnchorTransformEvent as Bn, DEFAULT_ATTACK_BY_FIRE_OPTIONS as Bt, snapToMidpointPerpendicular as C, StrongPointOptions as Cn, AntitankDitchOptions as Ct, BaselineFrameOrigin as D, DEFAULT_BOUNDARY_OPTIONS as Dn, ClearOptions as Dt, BaselineFrameOptions as E, BoundaryOptions as En, DelayOptions as Et, resolveStyleHints as F, TextAmplifierField as Fn, BlockMissionTaskOptions as Ft, cloneControlMeasure as G, AirborneAttackOptions as Gt, StyleHints as H, SupportByFireOptions as Ht, freezeOrientationOptions as I, TextAmplifierKey as In, DEFAULT_BLOCK_MISSION_TASK_OPTIONS as It, CONTROL_MEASURE_IDS as J, GenericCircleOptions as Jt, isKind as K, DEFAULT_AIRBORNE_ATTACK_OPTIONS as Kt, RenderOptions as L, TextAmplifiers as Ln, DEFAULT_FLOT_OPTIONS as Lt, SimpleStyleProps as M, TextAmplifierDescriptor as Mn, DEFAULT_BYPASS_OPTIONS as Mt, SimpleStyleRender as N, CanonicalTextAmplifiers as Nn, BreachOptions as Nt, createBaselineFrame as O, ControlMeasureGeometry as On, DEFAULT_CLEAR_OPTIONS as Ot, toSimpleStyle as P, TEXT_AMPLIFIER_FIELDS as Pn, DEFAULT_BREACH_OPTIONS as Pt, OptionsByKind as Q, GenericPolygonOptions as Qt, renderControlMeasure as R, canonicalTextAmplifierKey as Rn, FLOTOptions as Rt, pointOnMidpointPerpendicularAxis as S, DEFAULT_STRONG_POINT_OPTIONS as Sn, DEFAULT_ANTITANK_WALL_OPTIONS as St, BaselineFrameNormal as T, DEFAULT_BATTLE_POSITION_OPTIONS as Tn, DEFAULT_DELAY_OPTIONS as Tt, controlMeasureIdFromFeature as U, AttackHelicopterOptions as Ut, FeaturePartProps as V, ControlMeasureDrawRule as Vn, DEFAULT_SUPPORT_BY_FIRE_OPTIONS as Vt, ControlMeasure as W, DEFAULT_ATTACK_HELICOPTER_OPTIONS as Wt, ControlMeasureId as X, GenericRectangleOptions as Xt, CONTROL_MEASURE_METADATA as Y, DEFAULT_GENERIC_RECTANGLE_OPTIONS as Yt, ControlMeasureKind as Z, DEFAULT_GENERIC_POLYGON_OPTIONS as Zt, blockDrawRule as _, EncirclementOptions as _n, DEFAULT_FORTIFIED_AREA_OPTIONS as _t, rectangleDrawRule as a, ClassicArrowOptions as an, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS as at, createMidpointPerpendicularDrawRule as b, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS as bn, FortifiedLineOptions as bt, line24DrawRule as c, SupportingAttackOptions as cn, ObstacleBypassEasyOptions as ct, line1DrawRule as d, calculateMetrics as dn, DEFAULT_FIX_OPTIONS as dt, GenericLineOptions as en, getControlMeasureMetadataByValue as et, ambushDrawRule as f, computeInitialWidthPoint as fn, FixOptions as ft, disruptDrawRule as g, DEFAULT_ENCIRCLEMENT_OPTIONS as gn, DEFAULT_BLOCK_OPTIONS as gt, centerRadiusDrawRule as h, unproject as hn, BlockOptions as ht, DEFAULT_AMBUSH_OPTIONS as i, ClassicArrowHeadStyle as in, ObstacleBypassImpossibleOptions as it, roundToFixed as j, ParamDescriptor as jn, BypassOptions as jt, EPSILON as k, ControlMeasureGeometryType as kn, CanalizeOptions as kt, line23DrawRule as l, DEFAULT_MAIN_ATTACK_OPTIONS as ln, DEFAULT_TURN_OPTIONS as lt, point12DrawRule as m, project as mn, DisruptOptions as mt, TacticalArrowOptions as n, BlockArrowOptions as nn, listControlMeasureMetadata as nt, axis1DrawRule as o, DEFAULT_CLASSIC_ARROW_OPTIONS as on, ObstacleBypassDifficultOptions as ot, attackByFireDrawRule as p, Point2D as pn, DEFAULT_DISRUPT_OPTIONS as pt, ControlMeasureStyle as q, DEFAULT_GENERIC_CIRCLE_OPTIONS as qt, AmbushOptions as r, DEFAULT_BLOCK_ARROW_OPTIONS as rn, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS as rt, supportByFireDrawRule as s, DEFAULT_SUPPORTING_ATTACK_OPTIONS as sn, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS as st, DEFAULT_TACTICAL_ARROW_OPTIONS as t, BlockArrowHeadStyle as tn, getDefaultOptions as tt, turnDrawRule as u, MainAttackOptions as un, TurnOptions as ut, MidpointPerpendicularDrawRuleOptions as v, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS as vn, FortifiedAreaOptions as vt, BaselineFrame as w, BattlePositionOptions as wn, DEFAULT_ANTITANK_DITCH_OPTIONS as wt, getMidpointPerpendicularSignedDistance as x, PrincipalDirectionOfFireOptions as xn, AntitankWallOptions as xt, computeDefaultMidpointPerpendicularPoint as y, FinalProtectiveFireOptions as yn, DEFAULT_FORTIFIED_LINE_OPTIONS as yt, ControlMeasureRender as z, normalizeTextAmplifiers as zn, AttackByFireOptions as zt };
3042
+ export { DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS as $, ControlMeasureRender as $n, AnchorTransformEvent as $r, BridgeheadLineOptions as $t, roundToFixed as A, DEFAULT_CLASSIC_ARROW_OPTIONS as An, unproject as Ar, DEFAULT_COVER_OPTIONS as At, cloneControlMeasure as B, PickupZoneOptions as Bn, TextAmplifierDescriptor as Br, DEFAULT_BYPASS_OPTIONS as Bt, BaselineFrame as C, DEFAULT_GENERIC_LINE_OPTIONS as Cn, EngineerWorkLineOptions as Cr, DEFAULT_SCREEN_OPTIONS as Ct, createBaselineFrame as D, DEFAULT_BLOCK_ARROW_OPTIONS as Dn, Point2D as Dr, DEFAULT_DELAY_OPTIONS as Dt, BaselineFrameOrigin as E, BlockArrowOptions as En, LabelSizeOptions as Er, GuardOptions as Et, applyBoxTransformOptions as F, calculateMetrics as Fn, ControlMeasureGeometry as Fr, ClearOptions as Ft, ControlMeasureKind as G, AssemblyAreaOptions as Gn, LabelPlacementOverride as Gr, BattleHandoverLineOptions as Gt, CONTROL_MEASURE_IDS as H, LandingZoneOptions as Hn, AmplifierPlacements as Hr, DEFAULT_BREACH_OPTIONS as Ht, freezeOrientationOptions as I, computeInitialWidthPoint as In, ControlMeasureGeometryType as Ir, DEFAULT_CLEAR_OPTIONS as It, getControlMeasureMetadataByValue as J, DEFAULT_AREA_DEFENSE_OPTIONS as Jn, TextAmplifierKey as Jr, HandoverLineOptions as Jt, OptionsByKind as K, DEFAULT_ASSEMBLY_AREA_OPTIONS as Kn, TEXT_AMPLIFIER_FIELDS as Kr, DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS as Kt, RenderOptions as L, AreaOfOperationsOptions as Ln, ControlMeasureMetadata as Lr, CanalizeOptions as Lt, SimpleStyleRender as M, SupportingAttackOptions as Mn, DEFAULT_BOUNDARY_OPTIONS as Mr, TacticalArrowOptions as Mt, toSimpleStyle as N, DEFAULT_MAIN_ATTACK_OPTIONS as Nn, BoxTransformDelta as Nr, CounterattackOptions as Nt, EPSILON as O, ClassicArrowHeadStyle as On, haversineDistance as Or, DelayOptions as Ot, resolveStyleHints as P, MainAttackOptions as Pn, ControlMeasureFillCapability as Pr, DEFAULT_COUNTERATTACK_OPTIONS as Pt, ObstacleBypassImpossibleOptions as Q, FinalProtectiveFireOptions as Qn, resolveAmplifierPlacement as Qr, HoldingLineOptions as Qt, renderControlMeasure as R, DEFAULT_AREA_OF_OPERATIONS_OPTIONS as Rn, ControlMeasurePaintCapability as Rr, DEFAULT_CANALIZE_OPTIONS as Rt, snapToMidpointPerpendicular as S, GenericPolygonOptions as Sn, DEFAULT_ENGINEER_WORK_LINE_OPTIONS as Sr, DEFAULT_ANTITANK_DITCH_OPTIONS as St, BaselineFrameOptions as T, BlockArrowHeadStyle as Tn, LightLineOptions as Tr, DEFAULT_GUARD_OPTIONS as Tt, CONTROL_MEASURE_METADATA as U, DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS as Un, CanonicalTextAmplifiers as Ur, BlockMissionTaskOptions as Ut, isKind as V, DEFAULT_LANDING_ZONE_OPTIONS as Vn, AmplifierPlacement as Vr, BreachOptions as Vt, ControlMeasureId as W, JointTacticalActionAreaOptions as Wn, GeneratedLabelKey as Wr, DEFAULT_BLOCK_MISSION_TASK_OPTIONS as Wt, listControlMeasureMetadata as X, EncirclementOptions as Xn, canonicalTextAmplifierKey as Xr, ReleaseLineOptions as Xt, getDefaultOptions as Y, DEFAULT_ENCIRCLEMENT_OPTIONS as Yn, TextAmplifiers as Yr, DEFAULT_RELEASE_LINE_OPTIONS as Yt, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS as Z, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS as Zn, normalizeTextAmplifiers as Zr, DEFAULT_HOLDING_LINE_OPTIONS as Zt, MidpointPerpendicularDrawRuleOptions as _, DEFAULT_GENERIC_CIRCLE_OPTIONS as _n, DEFAULT_BATTLE_POSITION_OPTIONS as _r, DEFAULT_FORTIFIED_LINE_OPTIONS as _t, supportByFireDrawRule as a, DEFAULT_FLOT_OPTIONS as an, SecondaryDirectionOfFireOptions as ar, DEFAULT_FIX_OPTIONS as at, getMidpointPerpendicularSignedDistance as b, GenericRectangleOptions as bn, DEFAULT_GENERIC_C2_LINE_OPTIONS as br, DEFAULT_ANTITANK_WALL_OPTIONS as bt, line23DrawRule as c, DEFAULT_ATTACK_BY_FIRE_OPTIONS as cn, DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS as cr, DisruptOptions as ct, ambushDrawRule as d, AttackHelicopterOptions as dn, DirectionOfMainAttackOptions as dr, DEFAULT_TURNING_MOVEMENT_OPTIONS as dt, ControlMeasureDrawRule as ei, DEFAULT_BRIDGEHEAD_LINE_OPTIONS as en, FeaturePartProps as er, ObstacleBypassDifficultOptions as et, attackByFireDrawRule as f, DEFAULT_ATTACK_HELICOPTER_OPTIONS as fn, DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS as fr, TurningMovementOptions as ft, blockDrawRule as g, GenericTextOptions as gn, BattlePositionOptions as gr, FortifiedAreaOptions as gt, disruptDrawRule as h, DEFAULT_GENERIC_TEXT_OPTIONS as hn, StrongPointOptions as hr, DEFAULT_FORTIFIED_AREA_OPTIONS as ht, axis1DrawRule as i, PhaseLineOptions as in, SECONDARY_DIRECTION_OF_FIRE_DASH as ir, TurnOptions as it, SimpleStyleProps as j, DEFAULT_SUPPORTING_ATTACK_OPTIONS as jn, BoundaryOptions as jr, DEFAULT_TACTICAL_ARROW_OPTIONS as jt, getMetersPerPixel as k, ClassicArrowOptions as kn, project as kr, CoverOptions as kt, turnDrawRule as l, DEFAULT_SUPPORT_BY_FIRE_OPTIONS as ln, DirectionOfSupportingAttackOptions as lr, BlockOptions as lt, centerRadiusDrawRule as m, DEFAULT_AIRBORNE_ATTACK_OPTIONS as mn, DEFAULT_STRONG_POINT_OPTIONS as mr, FrontalAttackOptions as mt, DEFAULT_AMBUSH_OPTIONS as n, ForwardEdgeOfBattleAreaOptions as nn, controlMeasureIdFromFeature as nr, ObstacleBypassEasyOptions as nt, line26DrawRule as o, FLOTOptions as on, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS as or, FixOptions as ot, point12DrawRule as p, AirborneAttackOptions as pn, DirectionOfAttackAviationOptions as pr, DEFAULT_FRONTAL_ATTACK_OPTIONS as pt, getControlMeasureMetadata as q, AreaDefenseOptions as qn, TextAmplifierField as qr, DEFAULT_HANDOVER_LINE_OPTIONS as qt, rectangleDrawRule as r, DEFAULT_PHASE_LINE_OPTIONS as rn, DEFAULT_SECONDARY_DIRECTION_OF_FIRE_OPTIONS as rr, DEFAULT_TURN_OPTIONS as rt, line24DrawRule as s, AttackByFireOptions as sn, PrincipalDirectionOfFireOptions as sr, DEFAULT_DISRUPT_OPTIONS as st, AmbushOptions as t, DEFAULT_FORWARD_EDGE_OF_BATTLE_AREA_OPTIONS as tn, StyleHints as tr, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS as tt, line1DrawRule as u, SupportByFireOptions as un, DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS as ur, DEFAULT_BLOCK_OPTIONS as ut, computeDefaultMidpointPerpendicularPoint as v, GenericCircleOptions as vn, ControlMeasureStyle as vr, FortifiedLineOptions as vt, BaselineFrameNormal as w, GenericLineOptions as wn, DEFAULT_LIGHT_LINE_OPTIONS as wr, ScreenOptions as wt, pointOnMidpointPerpendicularAxis as x, DEFAULT_GENERIC_POLYGON_OPTIONS as xn, GenericC2LineOptions as xr, AntitankDitchOptions as xt, createMidpointPerpendicularDrawRule as y, DEFAULT_GENERIC_RECTANGLE_OPTIONS as yn, FillPattern as yr, AntitankWallOptions as yt, ControlMeasure as z, DEFAULT_PICKUP_ZONE_OPTIONS as zn, ParamDescriptor as zr, BypassOptions as zt };