@trdrs/quickcharts 1.1.0 → 1.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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { al as en, C as ChartMessageKey, G as GlyphSourcePort, M as MagnetMode, d as CursorMode, L as LineStyle, I as IDrawing, m as DrawingCounts, D as DrawingStyle, Y as VisibilityPreset, U as ToolPreset, V as ToolTemplate, S as SerializedDrawing, o as DrawingPreferences, l as DrawingAssetPort } from './assets-ySndlUS3.js';
2
2
  import { R as ResourceRef, C as ChartSaveLoadAdapter, q as ChartMeta, t as ChartBody, f as DrawingResourceContext, i as ResourceStore, u as DrawingsMeta, h as DrawingsBody, j as TemplateMeta, T as TemplateBody, v as LayoutMeta, w as LayoutBody, c as DrawingContextKind } from './resources-Ch8eA1Mw.js';
3
3
  export { a as ChartLocalDrawingContext, D as DRAWING_CONTEXT_VERSION, b as DRAWING_DOCUMENT_VERSION, d as DrawingEntry, e as DrawingGroup, g as DrawingTombstone, L as LayoutSharedDrawingContext, M as MemoryResourcesOptions, x as ResourceAbortError, S as SymbolGlobalDrawingContext, y as TemplateKind, W as WriteOutcome, k as drawingContextKey, l as emptyDrawingDocument, m as liveDrawingEntries, n as liveDrawingGroups, z as memorySaveLoadAdapter, o as mergeDrawingDocuments, p as parseDrawingDocument, r as reviseDrawingDocument, s as sameDrawingContext } from './resources-Ch8eA1Mw.js';
4
- import { LineData, UTCTimestamp, HistogramData, WhitespaceData, CreatePriceLineOptions, PriceLineOptions, ISeriesPrimitive, Time, IChartApi, PriceScaleMode, ISeriesApi, SeriesType, SeriesAttachedParameter, TickMarkType } from 'lightweight-charts';
4
+ import { LineData, UTCTimestamp, HistogramData, WhitespaceData, IChartApi, ISeriesApi, CreatePriceLineOptions, PriceLineOptions, ISeriesPrimitive, Time, PriceScaleMode, SeriesType, SeriesAttachedParameter, TickMarkType } from 'lightweight-charts';
5
5
 
6
6
  /** How one symbol's prices are WRITTEN, in five facts. Together they express
7
7
  * every supported form: decimal, pip, fractional, fraction of a fraction, and variable tick.
@@ -348,688 +348,59 @@ declare function tfToUdfResolution(tf: string): string;
348
348
  * isn't widget-servable even if the server serves it). */
349
349
  declare function udfResolutionToTf(resolution: string): string | null;
350
350
 
351
- /** The two modes Quick Charts ships complete. A host switches between them at runtime; it does not
352
- * add a third. A host that keeps named brand presets resolves each preset to a custom light or
353
- * dark palette before passing it in. */
354
- type ThemeMode = 'light' | 'dark';
355
- /** What a role's value is written as. Every value is a CSS token string, so `length` is `'4px'` and
356
- * `duration` is `'150ms'`; the kind says which tokens are valid, and validation enforces it. */
357
- type ThemeRoleKind = 'color' | 'length' | 'font' | 'duration' | 'shadow';
358
- /** The grouping a role belongs to. Families organize the manual and the manifest; they are not part
359
- * of a role's identity. */
360
- type ThemeRoleFamily = 'canvas' | 'series' | 'scale' | 'text' | 'chrome' | 'overlay' | 'state' | 'control' | 'status' | 'illustration' | 'drawing' | 'motion';
361
- /** A readability requirement the palettes must meet: this role's value, read against the value of
362
- * `over`, reaches `min` under the WCAG 2.2 contrast formula. Where `over` is a translucent tint
363
- * such as the hover or selected fill, `on` names the opaque surface the tint is drawn on, and the
364
- * tint is flattened onto it before measuring. Body text needs 4.5, a non-text indicator such as a
365
- * focus ring needs 3. */
366
- interface ThemeContrastRule {
367
- over: string;
368
- on?: string;
369
- min: number;
351
+ /** A locale a product ships or a host registers. `code` is the stable product-facing identifier;
352
+ * `tag` is the canonical BCP 47 value for `Intl` and the document language. */
353
+ interface LocaleDefinition<Code extends string = string> {
354
+ code: Code;
355
+ endonym: string;
356
+ tag: string;
357
+ dir: 'ltr' | 'rtl';
370
358
  }
371
- /** One entry of the inventory. */
372
- interface ThemeRole {
373
- /** The public id, `family.name`. Also the key of `SemanticTheme`. */
374
- id: string;
375
- family: ThemeRoleFamily;
376
- kind: ThemeRoleKind;
377
- /** One sentence naming what the role means, published in the manifest and the manual. */
378
- description: string;
379
- /** Present when the role carries readability requirements: one rule per ground the stylesheet's
380
- * recipes draw it on. */
381
- contrast?: readonly ThemeContrastRule[];
382
- }
383
- /** The complete role inventory. Adding an entry is a minor API change and needs a value in both
384
- * built-in palettes; removing one is breaking. */
385
- declare const THEME_ROLES: readonly [{
386
- readonly id: "canvas.background";
387
- readonly family: "canvas";
388
- readonly kind: "color";
389
- readonly description: "The fill behind the plotted series.";
390
- }, {
391
- readonly id: "canvas.paneBorder";
392
- readonly family: "canvas";
393
- readonly kind: "color";
394
- readonly description: "The divider between stacked panes and around the plot area.";
395
- }, {
396
- readonly id: "series.up";
397
- readonly family: "series";
398
- readonly kind: "color";
399
- readonly description: "A rising value: up volume, a rising study tint, a positive series default.";
400
- }, {
401
- readonly id: "series.down";
402
- readonly family: "series";
403
- readonly kind: "color";
404
- readonly description: "A falling value: down volume, a falling study tint, a negative series default.";
405
- }, {
406
- readonly id: "series.neutral";
407
- readonly family: "series";
408
- readonly kind: "color";
409
- readonly description: "A series or level with no direction, such as a study level line.";
410
- }, {
411
- readonly id: "scale.grid";
412
- readonly family: "scale";
413
- readonly kind: "color";
414
- readonly description: "The grid lines drawn across the plot area.";
415
- }, {
416
- readonly id: "scale.background";
417
- readonly family: "scale";
418
- readonly kind: "color";
419
- readonly description: "The ground behind the price and time scales.";
420
- }, {
421
- readonly id: "scale.border";
422
- readonly family: "scale";
423
- readonly kind: "color";
424
- readonly description: "The line separating a scale from the plot area.";
425
- }, {
426
- readonly id: "scale.text";
427
- readonly family: "scale";
428
- readonly kind: "color";
429
- readonly description: "Tick labels on the price and time scales.";
430
- readonly contrast: readonly [{
431
- readonly over: "scale.background";
432
- readonly min: 4.5;
433
- }];
434
- }, {
435
- readonly id: "scale.crosshair";
436
- readonly family: "scale";
437
- readonly kind: "color";
438
- readonly description: "The crosshair lines that follow the pointer.";
439
- }, {
440
- readonly id: "scale.crosshairLabelBackground";
441
- readonly family: "scale";
442
- readonly kind: "color";
443
- readonly description: "The fill of the crosshair value label on a scale.";
444
- }, {
445
- readonly id: "scale.crosshairLabelText";
446
- readonly family: "scale";
447
- readonly kind: "color";
448
- readonly description: "The value inside the crosshair label.";
449
- readonly contrast: readonly [{
450
- readonly over: "scale.crosshairLabelBackground";
451
- readonly min: 4.5;
452
- }];
453
- }, {
454
- readonly id: "scale.sessionPreMarket";
455
- readonly family: "scale";
456
- readonly kind: "color";
457
- readonly description: "Shading over pre-market bars.";
458
- }, {
459
- readonly id: "scale.sessionExtended";
460
- readonly family: "scale";
461
- readonly kind: "color";
462
- readonly description: "Shading over electronic-hours bars.";
463
- }, {
464
- readonly id: "scale.sessionAfterHours";
465
- readonly family: "scale";
466
- readonly kind: "color";
467
- readonly description: "Shading over after-hours bars.";
468
- }, {
469
- readonly id: "scale.sessionClosed";
470
- readonly family: "scale";
471
- readonly kind: "color";
472
- readonly description: "Shading over bars while the market is closed.";
473
- }, {
474
- readonly id: "text.primary";
475
- readonly family: "text";
476
- readonly kind: "color";
477
- readonly description: "Default ink for chart controls, menus, and dialogs.";
478
- readonly contrast: readonly [{
479
- readonly over: "chrome.surface";
480
- readonly min: 4.5;
481
- }, {
482
- readonly over: "state.selected";
483
- readonly on: "overlay.surface";
484
- readonly min: 4.5;
485
- }];
486
- }, {
487
- readonly id: "text.secondary";
488
- readonly family: "text";
489
- readonly kind: "color";
490
- readonly description: "Supporting ink: descriptions, group headings, secondary values.";
491
- readonly contrast: readonly [{
492
- readonly over: "chrome.surface";
493
- readonly min: 4.5;
494
- }, {
495
- readonly over: "state.selected";
496
- readonly on: "overlay.surface";
497
- readonly min: 4.5;
498
- }, {
499
- readonly over: "state.hover";
500
- readonly on: "overlay.surface";
501
- readonly min: 4.5;
502
- }];
503
- }, {
504
- readonly id: "text.muted";
505
- readonly family: "text";
506
- readonly kind: "color";
507
- readonly description: "The least emphasized readable ink, such as a keyboard hint.";
508
- readonly contrast: readonly [{
509
- readonly over: "chrome.surface";
510
- readonly min: 4.5;
511
- }, {
512
- readonly over: "state.selected";
513
- readonly on: "overlay.surface";
514
- readonly min: 4.5;
515
- }, {
516
- readonly over: "state.hover";
517
- readonly on: "overlay.surface";
518
- readonly min: 4.5;
519
- }];
520
- }, {
521
- readonly id: "text.disabled";
522
- readonly family: "text";
523
- readonly kind: "color";
524
- readonly description: "Ink of a control that cannot be used. WCAG exempts an inactive control from a contrast minimum.";
525
- }, {
526
- readonly id: "text.inverse";
527
- readonly family: "text";
528
- readonly kind: "color";
529
- readonly description: "Ink on an inverted or danger fill: a held mode on the on fill, a destructive action.";
530
- readonly contrast: readonly [{
531
- readonly over: "control.on";
532
- readonly min: 4.5;
533
- }, {
534
- readonly over: "status.negative";
535
- readonly min: 4.5;
536
- }];
537
- }, {
538
- readonly id: "text.link";
539
- readonly family: "text";
540
- readonly kind: "color";
541
- readonly description: "Ink of a text link inside chart chrome, and of a label naming an accent state, such as a running replay.";
542
- readonly contrast: readonly [{
543
- readonly over: "chrome.surface";
544
- readonly min: 4.5;
545
- }, {
546
- readonly over: "overlay.surface";
547
- readonly min: 4.5;
548
- }];
549
- }, {
550
- readonly id: "text.highlight";
551
- readonly family: "text";
552
- readonly kind: "color";
553
- readonly description: "Ink of the part of a label that matches what the reader typed, such as a symbol search.";
554
- readonly contrast: readonly [{
555
- readonly over: "overlay.surface";
556
- readonly min: 4.5;
557
- }, {
558
- readonly over: "chrome.surface";
559
- readonly min: 4.5;
560
- }];
561
- }, {
562
- readonly id: "text.onCanvas";
563
- readonly family: "text";
564
- readonly kind: "color";
565
- readonly description: "Ink drawn directly over the plot area, such as the legend.";
566
- readonly contrast: readonly [{
567
- readonly over: "canvas.background";
568
- readonly min: 4.5;
569
- }];
570
- }, {
571
- readonly id: "text.fontFamily";
572
- readonly family: "text";
573
- readonly kind: "font";
574
- readonly description: "The font stack chart chrome and canvas text share. Quick Charts never downloads a font.";
575
- }, {
576
- readonly id: "text.fontSizeAxis";
577
- readonly family: "text";
578
- readonly kind: "length";
579
- readonly description: "Size of scale and crosshair labels drawn into the canvas.";
580
- }, {
581
- readonly id: "text.fontSizeTitle";
582
- readonly family: "text";
583
- readonly kind: "length";
584
- readonly description: "Size of a dialog or panel title.";
585
- }, {
586
- readonly id: "text.fontSizeBase";
587
- readonly family: "text";
588
- readonly kind: "length";
589
- readonly description: "Size of ordinary control and menu text.";
590
- }, {
591
- readonly id: "text.fontSizeSmall";
592
- readonly family: "text";
593
- readonly kind: "length";
594
- readonly description: "Size of dense control text, such as a legend row.";
595
- }, {
596
- readonly id: "text.fontSizeMicro";
597
- readonly family: "text";
598
- readonly kind: "length";
599
- readonly description: "Size of the smallest chip and hint text.";
600
- }, {
601
- readonly id: "chrome.surface";
602
- readonly family: "chrome";
603
- readonly kind: "color";
604
- readonly description: "The fill of toolbars, rails, bars, and panels.";
605
- }, {
606
- readonly id: "chrome.surfaceRaised";
607
- readonly family: "chrome";
608
- readonly kind: "color";
609
- readonly description: "The fill of a control sitting on a chrome surface, such as a button or field.";
610
- }, {
611
- readonly id: "chrome.border";
612
- readonly family: "chrome";
613
- readonly kind: "color";
614
- readonly description: "The ordinary border of a control or panel.";
615
- }, {
616
- readonly id: "chrome.borderStrong";
617
- readonly family: "chrome";
618
- readonly kind: "color";
619
- readonly description: "A border or divider that must stay visible at a glance.";
620
- readonly contrast: readonly [{
621
- readonly over: "chrome.surface";
622
- readonly min: 3;
623
- }];
624
- }, {
625
- readonly id: "chrome.fieldBorder";
626
- readonly family: "chrome";
627
- readonly kind: "color";
628
- readonly description: "The outline of a text field, such as the symbol search field. The field's mark and prompt name it, so the outline is not its only sign.";
629
- }, {
630
- readonly id: "chrome.caret";
631
- readonly family: "chrome";
632
- readonly kind: "color";
633
- readonly description: "The ink of the arrow that opens a control's menu or flyout.";
634
- readonly contrast: readonly [{
635
- readonly over: "chrome.surface";
636
- readonly min: 3;
637
- }];
638
- }, {
639
- readonly id: "chrome.grip";
640
- readonly family: "chrome";
641
- readonly kind: "color";
642
- readonly description: "The dots of a drag handle on a floating toolbar.";
643
- }, {
644
- readonly id: "chrome.scrollThumb";
645
- readonly family: "chrome";
646
- readonly kind: "color";
647
- readonly description: "The thumb of the thin bar beside a list the viewer scrolls, such as the search results or the indicator list.";
648
- }, {
649
- readonly id: "chrome.radius";
650
- readonly family: "chrome";
651
- readonly kind: "length";
652
- readonly description: "Corner radius of a control.";
653
- }, {
654
- readonly id: "chrome.radiusLarge";
655
- readonly family: "chrome";
656
- readonly kind: "length";
657
- readonly description: "Corner radius of a panel, dialog, or menu.";
658
- }, {
659
- readonly id: "overlay.surface";
660
- readonly family: "overlay";
661
- readonly kind: "color";
662
- readonly description: "The fill of a floating menu, dialog, or popover.";
663
- }, {
664
- readonly id: "overlay.separator";
665
- readonly family: "overlay";
666
- readonly kind: "color";
667
- readonly description: "The rule between groups inside a menu or panel.";
668
- }, {
669
- readonly id: "overlay.shadow";
670
- readonly family: "overlay";
671
- readonly kind: "shadow";
672
- readonly description: "The elevation shadow of a floating surface.";
673
- }, {
674
- readonly id: "overlay.scrim";
675
- readonly family: "overlay";
676
- readonly kind: "color";
677
- readonly description: "The backdrop that dims the chart behind a modal dialog.";
678
- }, {
679
- readonly id: "state.accent";
680
- readonly family: "state";
681
- readonly kind: "color";
682
- readonly description: "The accent a mark, fill, or glyph wears: a chosen day, a selected tab, an armed favorite.";
683
- readonly contrast: readonly [{
684
- readonly over: "chrome.surface";
685
- readonly min: 3;
686
- }, {
687
- readonly over: "overlay.surface";
688
- readonly min: 3;
689
- }];
690
- }, {
691
- readonly id: "state.hover";
692
- readonly family: "state";
693
- readonly kind: "color";
694
- readonly description: "The fill a control takes under the pointer.";
695
- }, {
696
- readonly id: "state.hoverInk";
697
- readonly family: "state";
698
- readonly kind: "color";
699
- readonly description: "The ink a row of a plain picking list, such as the time zone list, dims to under the pointer.";
700
- readonly contrast: readonly [{
701
- readonly over: "state.hover";
702
- readonly on: "overlay.surface";
703
- readonly min: 4.5;
704
- }];
705
- }, {
706
- readonly id: "state.pressed";
707
- readonly family: "state";
708
- readonly kind: "color";
709
- readonly description: "The fill a control takes while the pointer is down, and the fill of an armed tool.";
710
- }, {
711
- readonly id: "state.pressedHover";
712
- readonly family: "state";
713
- readonly kind: "color";
714
- readonly description: "The fill of an armed tool or a held toggle under the pointer.";
715
- }, {
716
- readonly id: "state.selected";
717
- readonly family: "state";
718
- readonly kind: "color";
719
- readonly description: "The fill of a chosen row, tab, or tool.";
720
- }, {
721
- readonly id: "state.focusRing";
722
- readonly family: "state";
723
- readonly kind: "color";
724
- readonly description: "The visible focus indicator, including the active pane ring.";
725
- readonly contrast: readonly [{
726
- readonly over: "chrome.surface";
727
- readonly min: 3;
728
- }];
729
- }, {
730
- readonly id: "state.markInk";
731
- readonly family: "state";
732
- readonly kind: "color";
733
- readonly description: "Ink on the accent or a filled state mark: a chosen day, the replay disc's cut-out.";
734
- readonly contrast: readonly [{
735
- readonly over: "state.accent";
736
- readonly min: 4.5;
737
- }];
738
- }, {
739
- readonly id: "state.selection";
740
- readonly family: "state";
741
- readonly kind: "color";
742
- readonly description: "The tint over selected content.";
743
- }, {
744
- readonly id: "control.on";
745
- readonly family: "control";
746
- readonly kind: "color";
747
- readonly description: "The emphasis fill: a switch, checkbox, or radio that is on, a chosen row, a held mode, and the primary action; also the ring of a checkbox or radio that is off.";
748
- readonly contrast: readonly [{
749
- readonly over: "overlay.surface";
750
- readonly min: 3;
751
- }, {
752
- readonly over: "chrome.surface";
753
- readonly min: 3;
754
- }];
755
- }, {
756
- readonly id: "control.onHover";
757
- readonly family: "control";
758
- readonly kind: "color";
759
- readonly description: "The emphasis fill, and the ring of a radio, under the pointer.";
760
- }, {
761
- readonly id: "control.onPressed";
762
- readonly family: "control";
763
- readonly kind: "color";
764
- readonly description: "The emphasis fill, and the ring of a radio, while the pointer is down.";
765
- }, {
766
- readonly id: "control.off";
767
- readonly family: "control";
768
- readonly kind: "color";
769
- readonly description: "The track of a switch that is off.";
770
- }, {
771
- readonly id: "control.offHover";
772
- readonly family: "control";
773
- readonly kind: "color";
774
- readonly description: "The track of a switch that is off, under the pointer.";
775
- }, {
776
- readonly id: "control.offPressed";
777
- readonly family: "control";
778
- readonly kind: "color";
779
- readonly description: "The track of a switch that is off, while the pointer is down.";
780
- }, {
781
- readonly id: "control.mark";
782
- readonly family: "control";
783
- readonly kind: "color";
784
- readonly description: "The knob of a switch, the check of a checkbox, and the dot of a radio.";
785
- readonly contrast: readonly [{
786
- readonly over: "control.on";
787
- readonly min: 3;
788
- }, {
789
- readonly over: "control.onHover";
790
- readonly min: 3;
791
- }, {
792
- readonly over: "control.onPressed";
793
- readonly min: 3;
794
- }];
795
- }, {
796
- readonly id: "status.positive";
797
- readonly family: "status";
798
- readonly kind: "color";
799
- readonly description: "A positive value or a successful outcome in chart chrome.";
800
- readonly contrast: readonly [{
801
- readonly over: "chrome.surface";
802
- readonly min: 4.5;
803
- }];
804
- }, {
805
- readonly id: "status.negative";
806
- readonly family: "status";
807
- readonly kind: "color";
808
- readonly description: "A negative value or a failed outcome in chart chrome.";
809
- readonly contrast: readonly [{
810
- readonly over: "chrome.surface";
811
- readonly min: 4.5;
812
- }];
813
- }, {
814
- readonly id: "status.warning";
815
- readonly family: "status";
816
- readonly kind: "color";
817
- readonly description: "A condition the reader should notice before acting.";
818
- readonly contrast: readonly [{
819
- readonly over: "chrome.surface";
820
- readonly min: 4.5;
821
- }];
822
- }, {
823
- readonly id: "status.info";
824
- readonly family: "status";
825
- readonly kind: "color";
826
- readonly description: "An informational note in chart chrome.";
827
- readonly contrast: readonly [{
828
- readonly over: "chrome.surface";
829
- readonly min: 4.5;
830
- }];
831
- }, {
832
- readonly id: "status.loading";
833
- readonly family: "status";
834
- readonly kind: "color";
835
- readonly description: "The indicator shown while the chart waits for data.";
836
- }, {
837
- readonly id: "status.sessionPreMarket";
838
- readonly family: "status";
839
- readonly kind: "color";
840
- readonly description: "The session status marker for pre-market.";
841
- }, {
842
- readonly id: "status.sessionOpen";
843
- readonly family: "status";
844
- readonly kind: "color";
845
- readonly description: "The session status marker while the market is open.";
846
- }, {
847
- readonly id: "status.sessionExtended";
848
- readonly family: "status";
849
- readonly kind: "color";
850
- readonly description: "The session status marker for electronic hours.";
851
- }, {
852
- readonly id: "status.sessionAfterHours";
853
- readonly family: "status";
854
- readonly kind: "color";
855
- readonly description: "The session status marker for after-hours.";
856
- }, {
857
- readonly id: "status.sessionClosed";
858
- readonly family: "status";
859
- readonly kind: "color";
860
- readonly description: "The session status marker while the market is closed.";
861
- }, {
862
- readonly id: "illustration.ink";
863
- readonly family: "illustration";
864
- readonly kind: "color";
865
- readonly description: "The line drawing of an empty-state illustration.";
866
- readonly contrast: readonly [{
867
- readonly over: "overlay.surface";
868
- readonly min: 3;
869
- }];
870
- }, {
871
- readonly id: "illustration.accent";
872
- readonly family: "illustration";
873
- readonly kind: "color";
874
- readonly description: "The badge an empty-state illustration wears on the action it invites.";
875
- readonly contrast: readonly [{
876
- readonly over: "overlay.surface";
877
- readonly min: 3;
878
- }];
879
- }, {
880
- readonly id: "illustration.accentInk";
881
- readonly family: "illustration";
882
- readonly kind: "color";
883
- readonly description: "The mark on an illustration's badge.";
884
- readonly contrast: readonly [{
885
- readonly over: "illustration.accent";
886
- readonly min: 3;
887
- }];
888
- }, {
889
- readonly id: "drawing.line";
890
- readonly family: "drawing";
891
- readonly kind: "color";
892
- readonly description: "The stroke of a newly placed drawing.";
893
- }, {
894
- readonly id: "drawing.fill";
895
- readonly family: "drawing";
896
- readonly kind: "color";
897
- readonly description: "The fill of a newly placed drawing that has an area.";
898
- }, {
899
- readonly id: "drawing.text";
900
- readonly family: "drawing";
901
- readonly kind: "color";
902
- readonly description: "The ink of a drawing label.";
903
- }, {
904
- readonly id: "drawing.handle";
905
- readonly family: "drawing";
906
- readonly kind: "color";
907
- readonly description: "The center of a drawing selection handle.";
908
- }, {
909
- readonly id: "drawing.selected";
910
- readonly family: "drawing";
911
- readonly kind: "color";
912
- readonly description: "The highlight of a selected drawing and its handles.";
913
- }, {
914
- readonly id: "motion.durationFast";
915
- readonly family: "motion";
916
- readonly kind: "duration";
917
- readonly description: "A state change the reader should not have to wait for, such as a hover.";
918
- }, {
919
- readonly id: "motion.durationBase";
920
- readonly family: "motion";
921
- readonly kind: "duration";
922
- readonly description: "An ordinary transition, such as a menu opening.";
923
- }];
924
- /** Every role id in the inventory. */
925
- type ThemeRoleId = (typeof THEME_ROLES)[number]['id'];
926
- /** One resolved mode: every role, concrete. Values are CSS tokens, so a length is `'4px'` and a
927
- * duration is `'150ms'`. */
928
- type SemanticTheme = {
929
- readonly [Id in ThemeRoleId]: string;
930
- };
931
- /** What a host supplies: a partial palette for either mode, or both. An omitted role keeps the
932
- * built-in value for that mode. */
933
- interface CustomThemes {
934
- light?: Partial<SemanticTheme>;
935
- dark?: Partial<SemanticTheme>;
936
- }
937
-
938
- /** What went wrong, as a machine-readable code. */
939
- type ThemeDiagnosticCode = 'unknown-role' | 'empty-value' | 'invalid-value';
940
- /** One rejected entry of a host's custom palette. */
941
- interface ThemeDiagnostic {
942
- /** The mode whose palette carried the entry. */
943
- mode: ThemeMode;
944
- /** The key as the host wrote it, whether or not it names a role. */
945
- role: string;
946
- code: ThemeDiagnosticCode;
947
- /** A sentence naming the problem, safe to log or surface in a host's own tooling. */
948
- message: string;
949
- }
950
-
951
- /** What a host receives when the theme changes. */
952
- type ThemeChangeListener = (theme: SemanticTheme, mode: ThemeMode) => void;
953
- /** The runtime theme surface of one Quick Charts instance. */
954
- interface ThemeController {
955
- /** The mode in effect. */
956
- mode(): ThemeMode;
957
- /** Switch modes. The chart keeps its symbol, timeframe, range, drawings, and studies. */
958
- setMode(mode: ThemeMode): void;
959
- /** The complete resolved theme in effect. */
960
- get(): SemanticTheme;
961
- /** Replace the custom palettes. A role a palette does not name returns to its built-in value. */
962
- applyCustom(themes: CustomThemes): void;
963
- /** Drop every custom palette and return to the built-in palette for each mode. */
964
- resetCustom(): void;
965
- /** Anything rejected in the custom palettes currently held. Empty when they are fully usable. */
966
- diagnostics(): readonly ThemeDiagnostic[];
967
- /** Subscribe to theme changes. Returns the unsubscribe. */
968
- onChange(listener: ThemeChangeListener): () => void;
969
- }
970
- /** What a host may set when the controller is created. */
971
- interface ThemeControllerOptions {
972
- /** Defaults to `dark`. */
973
- mode?: ThemeMode;
974
- /** Custom palettes for either mode, or both. */
975
- custom?: CustomThemes;
976
- }
977
- /** Create the theme controller for one chart instance. */
978
- declare function createThemeController(options?: ThemeControllerOptions): ThemeController;
979
-
980
- /** A locale a product ships or a host registers. `code` is the stable product-facing identifier;
981
- * `tag` is the canonical BCP 47 value for `Intl` and the document language. */
982
- interface LocaleDefinition<Code extends string = string> {
983
- code: Code;
984
- endonym: string;
985
- tag: string;
986
- dir: 'ltr' | 'rtl';
987
- }
988
- /** The languages this package ships a dictionary for. */
989
- type ChartLocaleCode = 'en' | 'de' | 'fr' | 'es' | 'it' | 'ca_ES' | 'pl' | 'sv' | 'tr' | 'ru' | 'pt' | 'id_ID' | 'ms_MY' | 'th' | 'vi' | 'ja' | 'ko' | 'zh' | 'zh_TW' | 'ar' | 'he_IL';
990
- type ChartLocale = LocaleDefinition<ChartLocaleCode>;
991
- /** English first, then the Latin-script languages, then the others. Endonyms let every reader find
992
- * their own language in a picker. `scripts/i18n.mjs` reads this table by its line shape, and
993
- * `scripts/test/i18n-inventory.test.ts` pins it equal to the app runtime's inventory. */
994
- declare const BUILT_IN_LOCALES: readonly ChartLocale[];
995
-
996
- type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
997
- /** A message with one form per plural category its language distinguishes (CLDR: English has
998
- * `one` and `other`, Russian `one`/`few`/`many`/`other`, Arabic all six, Japanese `other` alone).
999
- * `other` is always present. `zero` is special: when present it is used for an exact count of 0 in
1000
- * EVERY language, so "No alerts" needs no branch at the call site. The form is selected by the
1001
- * `count` variable. */
1002
- type PluralMessage = {
1003
- other: string;
1004
- } & Partial<Record<Exclude<PluralCategory, 'other'>, string>>;
1005
- type Message = string | PluralMessage;
1006
- /** A catalog: keys to messages. The English catalog is the SOURCE every translation is typed
1007
- * against; keys are dotted by surface (`legend.hideIndicator`), and each surface keeps its own file. */
1008
- type Catalog = Record<string, Message>;
1009
- /** A translation of a catalog: a string for every string, a plural for every plural. The shape is
1010
- * the source's, so a translation cannot miss a key or flatten a plural without failing typecheck. */
1011
- type Translation<Source extends Catalog> = {
1012
- [K in keyof Source]: Source[K] extends string ? string : PluralMessage;
1013
- };
1014
- type Vars = Record<string, string | number>;
1015
- /** The arguments `t` takes for a key: a plural key REQUIRES `count`; a string key takes any vars.
1016
- * Distributive over `K`, so a key chosen at runtime from a union of keys (a label table) is
1017
- * accepted with the arguments any ONE of them takes rather than what all of them would need. */
1018
- type TranslateArgs<Source extends Catalog, K extends keyof Source> = K extends unknown ? Source[K] extends string ? [vars?: Vars] : [vars: Vars & {
1019
- count: number;
1020
- }] : never;
1021
- /** The message for a key in the active language: a plural key picks its form by the language's
1022
- * rules, and numbers in `{slots}` are written with the language's digits and grouping. */
1023
- type Translate<Source extends Catalog> = <K extends keyof Source & string>(key: K, ...args: TranslateArgs<Source, K>) => string;
1024
-
1025
- interface DictionaryLoader<Source extends Catalog, Code extends string = ChartLocaleCode> {
1026
- /** The translation if it is already in memory: synchronous, for a first render that must not flash. */
1027
- ifLoaded(code: Code): Translation<Source> | null;
1028
- /** Load (once) and return a locale's translation. Concurrent callers share one fetch; a locale
1029
- * the catalog does not ship resolves to the source. */
1030
- load(code: Code): Promise<Translation<Source>>;
1031
- /** Whether the catalog ships this locale (the source locale always does). */
1032
- has(code: Code): boolean;
359
+ /** The languages this package ships a dictionary for. */
360
+ type ChartLocaleCode = 'en' | 'de' | 'fr' | 'es' | 'it' | 'ca_ES' | 'pl' | 'sv' | 'tr' | 'ru' | 'pt' | 'id_ID' | 'ms_MY' | 'th' | 'vi' | 'ja' | 'ko' | 'zh' | 'zh_TW' | 'ar' | 'he_IL';
361
+ type ChartLocale = LocaleDefinition<ChartLocaleCode>;
362
+ /** English first, then the Latin-script languages, then the others. Endonyms let every reader find
363
+ * their own language in a picker. `scripts/i18n.mjs` reads this table by its line shape, and
364
+ * `scripts/test/i18n-inventory.test.ts` pins it equal to the app runtime's inventory. */
365
+ declare const BUILT_IN_LOCALES: readonly ChartLocale[];
366
+
367
+ type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
368
+ /** A message with one form per plural category its language distinguishes (CLDR: English has
369
+ * `one` and `other`, Russian `one`/`few`/`many`/`other`, Arabic all six, Japanese `other` alone).
370
+ * `other` is always present. `zero` is special: when present it is used for an exact count of 0 in
371
+ * EVERY language, so "No alerts" needs no branch at the call site. The form is selected by the
372
+ * `count` variable. */
373
+ type PluralMessage = {
374
+ other: string;
375
+ } & Partial<Record<Exclude<PluralCategory, 'other'>, string>>;
376
+ type Message = string | PluralMessage;
377
+ /** A catalog: keys to messages. The English catalog is the SOURCE every translation is typed
378
+ * against; keys are dotted by surface (`legend.hideIndicator`), and each surface keeps its own file. */
379
+ type Catalog = Record<string, Message>;
380
+ /** A translation of a catalog: a string for every string, a plural for every plural. The shape is
381
+ * the source's, so a translation cannot miss a key or flatten a plural without failing typecheck. */
382
+ type Translation<Source extends Catalog> = {
383
+ [K in keyof Source]: Source[K] extends string ? string : PluralMessage;
384
+ };
385
+ type Vars = Record<string, string | number>;
386
+ /** The arguments `t` takes for a key: a plural key REQUIRES `count`; a string key takes any vars.
387
+ * Distributive over `K`, so a key chosen at runtime from a union of keys (a label table) is
388
+ * accepted with the arguments any ONE of them takes rather than what all of them would need. */
389
+ type TranslateArgs<Source extends Catalog, K extends keyof Source> = K extends unknown ? Source[K] extends string ? [vars?: Vars] : [vars: Vars & {
390
+ count: number;
391
+ }] : never;
392
+ /** The message for a key in the active language: a plural key picks its form by the language's
393
+ * rules, and numbers in `{slots}` are written with the language's digits and grouping. */
394
+ type Translate<Source extends Catalog> = <K extends keyof Source & string>(key: K, ...args: TranslateArgs<Source, K>) => string;
395
+
396
+ interface DictionaryLoader<Source extends Catalog, Code extends string = ChartLocaleCode> {
397
+ /** The translation if it is already in memory: synchronous, for a first render that must not flash. */
398
+ ifLoaded(code: Code): Translation<Source> | null;
399
+ /** Load (once) and return a locale's translation. Concurrent callers share one fetch; a locale
400
+ * the catalog does not ship resolves to the source. */
401
+ load(code: Code): Promise<Translation<Source>>;
402
+ /** Whether the catalog ships this locale (the source locale always does). */
403
+ has(code: Code): boolean;
1033
404
  }
1034
405
 
1035
406
  type ChartTranslate = Translate<typeof en>;
@@ -1636,474 +1007,1710 @@ declare const chartDictionaries: DictionaryLoader<{
1636
1007
  readonly one: "{count} day";
1637
1008
  readonly other: "{count} days";
1638
1009
  };
1639
- readonly 'status.durationHours': {
1640
- readonly one: "{count} hour";
1641
- readonly other: "{count} hours";
1010
+ readonly 'status.durationHours': {
1011
+ readonly one: "{count} hour";
1012
+ readonly other: "{count} hours";
1013
+ };
1014
+ readonly 'status.durationMinutes': {
1015
+ readonly one: "{count} minute";
1016
+ readonly other: "{count} minutes";
1017
+ };
1018
+ readonly 'status.durationPair': "{major} {minor}";
1019
+ readonly 'range.oneDay': "1 Day";
1020
+ readonly 'range.fiveDays': "5 Days";
1021
+ readonly 'range.oneMonth': "1 Month";
1022
+ readonly 'range.threeMonths': "3 Months";
1023
+ readonly 'range.sixMonths': "6 Months";
1024
+ readonly 'range.yearToDate': "Year to date";
1025
+ readonly 'range.oneYear': "1 Year";
1026
+ readonly 'range.fiveYears': "5 Years";
1027
+ readonly 'range.all': "All data";
1028
+ readonly 'range.tip': "{range} · {interval} bars";
1029
+ readonly 'range.zoomIn': "Zoom in";
1030
+ readonly 'range.zoomOut': "Zoom out";
1031
+ readonly 'range.scrollLeft': "Scroll left";
1032
+ readonly 'range.scrollRight': "Scroll right";
1033
+ readonly 'range.reset': "Reset chart view";
1034
+ readonly 'range.maximizeChart': "Maximize chart";
1035
+ readonly 'range.restoreChart': "Restore chart";
1036
+ readonly 'timezone.title': "Chart timezone";
1037
+ readonly 'timezone.exchange': "Exchange";
1038
+ readonly 'timeframe.title': "Timeframe";
1039
+ readonly 'timeframe.all': "All timeframes";
1040
+ readonly 'timeframe.unitTicks': "Ticks";
1041
+ readonly 'timeframe.unitSeconds': "Seconds";
1042
+ readonly 'timeframe.unitMinutes': "Minutes";
1043
+ readonly 'timeframe.unitHours': "Hours";
1044
+ readonly 'timeframe.unitDays': "Days";
1045
+ readonly 'timeframe.unitWeeks': "Weeks";
1046
+ readonly 'timeframe.unitMonths': "Months";
1047
+ readonly 'timeframe.countTicks': {
1048
+ readonly one: "{count} Tick";
1049
+ readonly other: "{count} Ticks";
1050
+ };
1051
+ readonly 'timeframe.countSeconds': {
1052
+ readonly one: "{count} Second";
1053
+ readonly other: "{count} Seconds";
1054
+ };
1055
+ readonly 'timeframe.countMinutes': {
1056
+ readonly one: "{count} Minute";
1057
+ readonly other: "{count} Minutes";
1058
+ };
1059
+ readonly 'timeframe.countHours': {
1060
+ readonly one: "{count} Hour";
1061
+ readonly other: "{count} Hours";
1062
+ };
1063
+ readonly 'timeframe.countDays': {
1064
+ readonly one: "{count} Day";
1065
+ readonly other: "{count} Days";
1066
+ };
1067
+ readonly 'timeframe.countWeeks': {
1068
+ readonly one: "{count} Week";
1069
+ readonly other: "{count} Weeks";
1070
+ };
1071
+ readonly 'timeframe.countMonths': {
1072
+ readonly one: "{count} Month";
1073
+ readonly other: "{count} Months";
1074
+ };
1075
+ readonly 'timeframe.delete': "Delete {timeframe}";
1076
+ readonly 'timeframe.save': "Save {timeframe}";
1077
+ readonly 'timeframe.exists': "{timeframe} already exists";
1078
+ readonly 'timeframe.custom': "Custom timeframe";
1079
+ readonly 'timeframe.customCount': "Custom timeframe count";
1080
+ readonly 'timeframe.customUnit': "Custom timeframe unit";
1081
+ readonly 'timeframe.addCustom': "Add custom timeframe";
1082
+ readonly 'timeframe.increment': "Increment";
1083
+ readonly 'timeframe.decrement': "Decrement";
1084
+ readonly 'indicator.smaName': "Simple Moving Average";
1085
+ readonly 'indicator.smaDescription': "Smoothed average over a fixed window";
1086
+ readonly 'indicator.emaName': "Exponential Moving Average";
1087
+ readonly 'indicator.emaDescription': "Recency-weighted moving average";
1088
+ readonly 'indicator.hmaName': "Hull Moving Average";
1089
+ readonly 'indicator.hmaDescription': "Low-lag weighted moving average";
1090
+ readonly 'indicator.vwmaName': "Volume Weighted MA";
1091
+ readonly 'indicator.vwmaDescription': "Moving average weighted by volume";
1092
+ readonly 'indicator.bollingerName': "Bollinger Bands";
1093
+ readonly 'indicator.bollingerDescription': "SMA envelope at two standard deviations";
1094
+ readonly 'indicator.donchianName': "Donchian Channels";
1095
+ readonly 'indicator.donchianDescription': "Rolling highest-high and lowest-low channel";
1096
+ readonly 'indicator.keltnerName': "Keltner Channels";
1097
+ readonly 'indicator.keltnerDescription': "EMA midline with ATR-scaled bands";
1098
+ readonly 'indicator.supertrendName': "Supertrend";
1099
+ readonly 'indicator.supertrendDescription': "ATR trend band that flips with direction";
1100
+ readonly 'indicator.psarName': "Parabolic SAR";
1101
+ readonly 'indicator.psarDescription': "Stop-and-reverse trailing dots";
1102
+ readonly 'indicator.rsiName': "Relative Strength Index";
1103
+ readonly 'indicator.rsiDescription': "Momentum oscillator from 0 to 100";
1104
+ readonly 'indicator.macdName': "MACD";
1105
+ readonly 'indicator.macdDescription': "Moving Average Convergence Divergence";
1106
+ readonly 'indicator.stochasticName': "Stochastic Oscillator";
1107
+ readonly 'indicator.stochasticDescription': "%K and %D momentum from 0 to 100";
1108
+ readonly 'indicator.stochrsiName': "Stochastic RSI";
1109
+ readonly 'indicator.stochrsiDescription': "Stochastic applied to the RSI series";
1110
+ readonly 'indicator.adxName': "Average Directional Index";
1111
+ readonly 'indicator.adxDescription': "Trend strength with +DI and -DI";
1112
+ readonly 'indicator.atrName': "Average True Range";
1113
+ readonly 'indicator.atrDescription': "Volatility: Wilder's true-range average";
1114
+ readonly 'indicator.cciName': "Commodity Channel Index";
1115
+ readonly 'indicator.cciDescription': "Deviation from the typical-price average";
1116
+ readonly 'indicator.williamsName': "Williams %R";
1117
+ readonly 'indicator.williamsDescription': "Overbought and oversold momentum from -100 to 0";
1118
+ readonly 'indicator.rocName': "Rate of Change";
1119
+ readonly 'indicator.rocDescription': "Percent change over the period";
1120
+ readonly 'indicator.momentumName': "Momentum";
1121
+ readonly 'indicator.momentumDescription': "Price difference over the period";
1122
+ readonly 'indicator.volumeName': "Volume";
1123
+ readonly 'indicator.volumeDescription': "Per-bar traded volume histogram";
1124
+ readonly 'indicator.vwapName': "Volume Weighted Avg Price";
1125
+ readonly 'indicator.vwapDescription': "Cumulative volume-weighted average price";
1126
+ readonly 'indicator.obvName': "On-Balance Volume";
1127
+ readonly 'indicator.obvDescription': "Cumulative volume by close direction";
1128
+ readonly 'indicator.mfiName': "Money Flow Index";
1129
+ readonly 'indicator.mfiDescription': "Volume-weighted RSI from 0 to 100";
1130
+ readonly 'host.noVolume': "No volume from this feed";
1131
+ readonly 'host.saveConflict': "Saved elsewhere since you opened it. Load the newer version before saving.";
1132
+ readonly 'host.saveNotFound': "This was deleted elsewhere. Save it again as new.";
1133
+ readonly 'host.loadInvalid': "This could not be opened. Nothing on screen changed.";
1134
+ readonly 'host.loadUnavailable': "Your saved work could not be reached. Nothing on screen changed.";
1135
+ readonly 'host.loadNotRestored': "This could not be opened, and what was on screen could not be put back. The chart is not saving until you open a saved chart or layout. Save a copy first to keep what is on screen.";
1136
+ readonly 'host.notSaving': "The chart is not saving. Open a saved chart or layout to start from a known state. Saving a copy keeps what is on screen, but the chart still will not save.";
1137
+ readonly 'layout.s': "Single chart";
1138
+ readonly 'layout.2h': "2 columns";
1139
+ readonly 'layout.2v': "2 rows";
1140
+ readonly 'layout.3h': "3 columns";
1141
+ readonly 'layout.3v': "3 rows";
1142
+ readonly 'layout.3s': "Large left, 2 stacked right";
1143
+ readonly 'layout.3r': "2 stacked left, large right";
1144
+ readonly 'layout.2_1': "2 above, 1 below";
1145
+ readonly 'layout.1_2': "1 above, 2 below";
1146
+ readonly 'layout.4': "2 × 2 grid";
1147
+ readonly 'layout.4v': "4 rows";
1148
+ readonly 'layout.4h': "4 columns";
1149
+ readonly 'layout.4s': "Large left, 3 stacked right";
1150
+ readonly 'layout.4s_l': "3 stacked left, large right";
1151
+ readonly 'layout.1_3': "1 above, 3 below";
1152
+ readonly 'layout.3_1': "3 above, 1 below";
1153
+ readonly 'layout.2_2_l': "2 columns, 2 stacked right";
1154
+ readonly 'layout.2_2_r': "2 stacked left, 2 columns";
1155
+ readonly 'layout.2_2': "2 above, 2 full-width rows below";
1156
+ readonly 'layout.1_4': "1 above, 4 below";
1157
+ readonly 'layout.5h': "5 columns";
1158
+ readonly 'layout.5v': "5 rows";
1159
+ readonly 'layout.5s': "Large left, 4 stacked right";
1160
+ readonly 'layout.5s_l': "4 stacked left, large right";
1161
+ readonly 'layout.2_3': "2 above, 3 below";
1162
+ readonly 'layout.3_2': "3 above, 2 below";
1163
+ readonly 'layout.4_1': "4 above, 1 below";
1164
+ readonly 'layout.2_3_l': "2 columns, 3 stacked right";
1165
+ readonly 'layout.2_3_r': "3 stacked left, 2 columns";
1166
+ readonly 'layout.6': "3 × 2 grid";
1167
+ readonly 'layout.6h': "6 columns";
1168
+ readonly 'layout.6v': "6 rows";
1169
+ readonly 'layout.6c': "2 × 3 grid";
1170
+ readonly 'layout.2_4': "2 above, 4 below";
1171
+ readonly 'layout.4_2': "4 above, 2 below";
1172
+ readonly 'layout.4_3': "4 above, 3 below";
1173
+ readonly 'layout.7h': "7 columns";
1174
+ readonly 'layout.7s': "Large left, 6 stacked right";
1175
+ readonly 'layout.8': "4 × 2 grid";
1176
+ readonly 'layout.8c': "2 × 4 grid";
1177
+ readonly 'layout.8h': "8 columns";
1178
+ readonly 'layout.8v': "8 rows";
1179
+ readonly 'layout.9s': "3 × 3 grid";
1180
+ readonly 'layout.5_4': "5 above, 4 below";
1181
+ readonly 'layout.9h': "9 columns";
1182
+ readonly 'layout.9v': "9 rows";
1183
+ readonly 'layout.10c5': "5 × 2 grid";
1184
+ readonly 'layout.10h': "10 columns";
1185
+ readonly 'layout.10v': "10 rows";
1186
+ readonly 'layout.12c6': "6 × 2 grid";
1187
+ readonly 'layout.12c4': "4 × 3 grid";
1188
+ readonly 'layout.12h': "12 columns";
1189
+ readonly 'layout.14c7': "7 × 2 grid";
1190
+ readonly 'layout.16c8': "8 × 2 grid";
1191
+ readonly 'layout.16c4': "4 × 4 grid";
1192
+ readonly 'layouts.setup': "Layout setup";
1193
+ readonly 'layouts.arrangement': "Chart arrangement";
1194
+ readonly 'layouts.syncInLayout': "Sync in layout";
1195
+ readonly 'layouts.syncSymbol': "Symbol";
1196
+ readonly 'layouts.syncInterval': "Interval";
1197
+ readonly 'layouts.syncCrosshair': "Crosshair";
1198
+ readonly 'layouts.syncTime': "Time";
1199
+ readonly 'layouts.syncDateRange': "Date range";
1200
+ readonly 'layouts.syncSymbolTip': "Symbol changes on all charts within the layout";
1201
+ readonly 'layouts.syncIntervalTip': "Interval changes on all charts within the layout";
1202
+ readonly 'layouts.syncCrosshairTip': "Crosshair is synced across all charts within the layout";
1203
+ readonly 'layouts.syncTimeTip': "When a chart is clicked, all charts within the layout display the same point of time";
1204
+ readonly 'layouts.syncDateRangeTip': "Date range changes on all charts within the layout";
1205
+ readonly 'layouts.syncSymbolToggle': "Sync symbol";
1206
+ readonly 'layouts.syncIntervalToggle': "Sync interval";
1207
+ readonly 'layouts.syncCrosshairToggle': "Sync crosshair";
1208
+ readonly 'layouts.syncTimeToggle': "Sync time";
1209
+ readonly 'layouts.syncDateRangeToggle': "Sync date range";
1210
+ readonly 'layouts.unnamed': "Unnamed";
1211
+ readonly 'layouts.unsavedChanges': "Unsaved changes";
1212
+ readonly 'layouts.allSaved': "All changes saved";
1213
+ readonly 'layouts.notSaving': "Not saving until this is restored";
1214
+ readonly 'layouts.manage': "Manage layouts";
1215
+ readonly 'layouts.saveLayout': "Save layout";
1216
+ readonly 'layouts.hintSave': "{modifier} + S";
1217
+ readonly 'layouts.hintOpen': "Dot";
1218
+ readonly 'layouts.save': "Save";
1219
+ readonly 'layouts.autosave': "Autosave";
1220
+ readonly 'layouts.rename': "Rename";
1221
+ readonly 'layouts.copyOfName': "{name} copy";
1222
+ readonly 'layouts.saveNewTitle': "Save New Chart Layout";
1223
+ readonly 'layouts.saveNewLabel': "Enter a new chart layout name:";
1224
+ readonly 'layouts.copyTitle': "Make copy of chart layout";
1225
+ readonly 'layouts.renameTitle': "Rename chart layout";
1226
+ readonly 'layouts.createTitle': "Create layout";
1227
+ readonly 'layouts.newLayoutName': "New layout name";
1228
+ readonly 'layouts.createPlaceholder': "My layout";
1229
+ readonly 'layouts.create': "Create";
1230
+ readonly 'layouts.makeCopyRow': "Make a copy…";
1231
+ readonly 'layouts.renameRow': "Rename…";
1232
+ readonly 'layouts.downloadDataRow': "Download chart data";
1233
+ readonly 'layouts.createNewRow': "Create new layout…";
1234
+ readonly 'layouts.recentlyUsed': "Recently used";
1235
+ readonly 'layouts.loading': "Loading";
1236
+ readonly 'layouts.emptyNone': "No saved layouts yet.";
1237
+ readonly 'layouts.openLayoutRow': "Open layout…";
1238
+ readonly 'layouts.listingFacts': "{symbol}, {interval}";
1239
+ readonly 'layouts.listingDated': "{facts} ({date})";
1240
+ readonly 'layouts.dialogTitle': "Layouts";
1241
+ readonly 'layouts.search': "Search";
1242
+ readonly 'layouts.columnName': "Layout name";
1243
+ readonly 'layouts.sortBy': "Sort by layout name, date changed";
1244
+ readonly 'layouts.sortNameAsc': "Layout name (A to Z)";
1245
+ readonly 'layouts.sortNameDesc': "Layout name (Z to A)";
1246
+ readonly 'layouts.sortModifiedAsc': "Date modified (oldest first)";
1247
+ readonly 'layouts.sortModifiedDesc': "Date modified (newest first)";
1248
+ readonly 'layouts.favorite': "Add to favorites";
1249
+ readonly 'layouts.unfavorite': "Remove from favorites";
1250
+ readonly 'layouts.noMatches': "Nothing matches.";
1251
+ readonly 'layouts.delete': "Delete";
1252
+ readonly 'layouts.deleteNamed': "Delete {name}";
1253
+ readonly 'layouts.deleteConfirm': "Delete this chart layout?";
1254
+ readonly 'layouts.deleteConfirmBody': "Doing this will permanently delete your \"{name}\" layout.";
1255
+ readonly 'layouts.cancel': "Cancel";
1256
+ readonly 'layouts.close': "Close";
1257
+ readonly 'layouts.errList': "Could not load your saved layouts.";
1258
+ readonly 'session.pre': "Pre-market";
1259
+ readonly 'session.open': "Market open";
1260
+ readonly 'session.extended': "Extended hours";
1261
+ readonly 'session.after': "After-hours";
1262
+ readonly 'session.closed': "Market closed";
1263
+ readonly 'inputs.cancel': "Cancel";
1264
+ readonly 'inputs.apply': "Apply";
1265
+ readonly 'replay.watermark': "Replay";
1266
+ readonly 'replay.selectBar': "Select bar";
1267
+ readonly 'replay.selectDate': "Select date";
1268
+ readonly 'replay.selectStartingPoint': "Select starting point";
1269
+ readonly 'replay.startBar': "Bar";
1270
+ readonly 'replay.startDate': "Date…";
1271
+ readonly 'replay.startFirst': "First available date";
1272
+ readonly 'replay.startRandom': "Random bar";
1273
+ readonly 'replay.startDateField': "Replay start date";
1274
+ readonly 'replay.startTimeField': "Replay start time (UTC, optional)";
1275
+ readonly 'replay.dateMask': "YYYY-MM-DD";
1276
+ readonly 'replay.timeMask': "HH:MM";
1277
+ readonly 'replay.previousMonth': "Previous month";
1278
+ readonly 'replay.nextMonth': "Next month";
1279
+ readonly 'replay.cancel': "Cancel";
1280
+ readonly 'replay.select': "Select";
1281
+ readonly 'replay.weekdayMon': "Mo";
1282
+ readonly 'replay.weekdayTue': "Tu";
1283
+ readonly 'replay.weekdayWed': "We";
1284
+ readonly 'replay.weekdayThu': "Th";
1285
+ readonly 'replay.weekdayFri': "Fr";
1286
+ readonly 'replay.weekdaySat': "Sa";
1287
+ readonly 'replay.weekdaySun': "Su";
1288
+ readonly 'replay.stepBack': "Step back one bar";
1289
+ readonly 'replay.play': "Play";
1290
+ readonly 'replay.pause': "Pause";
1291
+ readonly 'replay.stepForward': "Step forward one bar";
1292
+ readonly 'replay.goLiveTitle': "Jump to the live edge";
1293
+ readonly 'replay.exit': "Exit replay";
1294
+ readonly 'replay.speed': "Replay speed";
1295
+ readonly 'replay.updatesPerSecond': {
1296
+ readonly one: "{count} update per second";
1297
+ readonly other: "{count} updates per second";
1298
+ };
1299
+ readonly 'replay.oneUpdatePerSeconds': {
1300
+ readonly one: "1 update per {count} second";
1301
+ readonly other: "1 update per {count} seconds";
1302
+ };
1303
+ readonly 'replay.interval': "Update interval";
1304
+ readonly 'replay.intervalHelp': "How much time each replay update advances. Finer than the chart interval, each bar forms from real finer bars.";
1305
+ readonly 'replay.intervalNone': "No finer interval for this chart interval";
1306
+ readonly 'replay.auto': "Auto";
1307
+ readonly 'replay.autoSelectInterval': "Auto select interval";
1308
+ readonly 'menu.resetView': "Reset chart view";
1309
+ readonly 'menu.copyPrice': "Copy price {price}";
1310
+ readonly 'menu.paste': "Paste";
1311
+ readonly 'menu.removeIndicators': {
1312
+ readonly one: "Remove {count} indicator";
1313
+ readonly other: "Remove {count} indicators";
1314
+ };
1315
+ readonly 'menu.removeDrawings': {
1316
+ readonly one: "Remove {count} drawing";
1317
+ readonly other: "Remove {count} drawings";
1318
+ };
1319
+ readonly 'menu.settings': "Settings…";
1320
+ readonly 'tool.trend_line': "Trend line";
1321
+ readonly 'tool.ray': "Ray";
1322
+ readonly 'tool.info_line': "Info line";
1323
+ readonly 'tool.extended': "Extended line";
1324
+ readonly 'tool.trend_angle': "Trend angle";
1325
+ readonly 'tool.horizontal_line': "Horizontal line";
1326
+ readonly 'tool.horizontal_ray': "Horizontal ray";
1327
+ readonly 'tool.vertical_line': "Vertical line";
1328
+ readonly 'tool.cross_line': "Cross line";
1329
+ readonly 'tool.arrow': "Arrow";
1330
+ readonly 'tool.rectangle': "Rectangle";
1331
+ readonly 'tool.rotated_rectangle': "Rotated rectangle";
1332
+ readonly 'tool.ellipse': "Ellipse";
1333
+ readonly 'tool.circle': "Circle";
1334
+ readonly 'tool.triangle': "Triangle";
1335
+ readonly 'tool.arc': "Arc";
1336
+ readonly 'tool.curve': "Curve";
1337
+ readonly 'tool.double_curve': "Double curve";
1338
+ readonly 'tool.regression_trend': "Regression trend";
1339
+ readonly 'tool.parallel_channel': "Parallel channel";
1340
+ readonly 'tool.flat_top_bottom': "Flat top/bottom";
1341
+ readonly 'tool.disjoint_channel': "Disjoint channel";
1342
+ readonly 'tool.fib_retracement': "Fib retracement";
1343
+ readonly 'tool.fib_trend_ext': "Trend-based fib extension";
1344
+ readonly 'tool.fib_channel': "Fib channel";
1345
+ readonly 'tool.fib_timezone': "Fib time zone";
1346
+ readonly 'tool.fib_speed_resist_fan': "Fib speed resistance fan";
1347
+ readonly 'tool.fib_trend_time': "Trend-based fib time";
1348
+ readonly 'tool.fib_circles': "Fib circles";
1349
+ readonly 'tool.fib_spiral': "Fib spiral";
1350
+ readonly 'tool.fib_speed_resist_arcs': "Fib speed resistance arcs";
1351
+ readonly 'tool.fib_wedge': "Fib wedge";
1352
+ readonly 'tool.pitchfan': "Pitchfan";
1353
+ readonly 'tool.pitchfork': "Pitchfork";
1354
+ readonly 'tool.schiff_pitchfork': "Schiff pitchfork";
1355
+ readonly 'tool.schiff_pitchfork_modified': "Modified Schiff pitchfork";
1356
+ readonly 'tool.inside_pitchfork': "Inside pitchfork";
1357
+ readonly 'tool.gannbox': "Gann box";
1358
+ readonly 'tool.gannbox_square': "Gann square";
1359
+ readonly 'tool.gannbox_fixed': "Gann square fixed";
1360
+ readonly 'tool.gannbox_fan': "Gann fan";
1361
+ readonly 'tool.xabcd_pattern': "XABCD pattern";
1362
+ readonly 'tool.cypher_pattern': "Cypher pattern";
1363
+ readonly 'tool.abcd_pattern': "ABCD pattern";
1364
+ readonly 'tool.three_drives': "Three drives pattern";
1365
+ readonly 'tool.triangle_pattern': "Triangle pattern";
1366
+ readonly 'tool.head_and_shoulders': "Head and shoulders";
1367
+ readonly 'tool.elliott_impulse_wave': "Elliott impulse (12345)";
1368
+ readonly 'tool.elliott_correction': "Elliott correction (ABC)";
1369
+ readonly 'tool.elliott_triangle_wave': "Elliott triangle (ABCDE)";
1370
+ readonly 'tool.elliott_double_combo': "Elliott double combo (WXY)";
1371
+ readonly 'tool.elliott_triple_combo': "Elliott triple combo (WXYXZ)";
1372
+ readonly 'tool.cyclic_lines': "Cyclic lines";
1373
+ readonly 'tool.time_cycles': "Time cycles";
1374
+ readonly 'tool.sine_line': "Sine line";
1375
+ readonly 'tool.long_position': "Long position";
1376
+ readonly 'tool.short_position': "Short position";
1377
+ readonly 'tool.forecast': "Position forecast";
1378
+ readonly 'tool.sector': "Sector";
1379
+ readonly 'tool.bars_pattern': "Bars pattern";
1380
+ readonly 'tool.ghost_feed': "Ghost feed";
1381
+ readonly 'tool.anchored_vwap': "Anchored VWAP";
1382
+ readonly 'tool.fixed_range_volume_profile': "Fixed range volume profile";
1383
+ readonly 'tool.anchored_volume_profile': "Anchored volume profile";
1384
+ readonly 'tool.image': "Image";
1385
+ readonly 'tool.content_card': "Content card";
1386
+ readonly 'tool.emoji': "Emoji";
1387
+ readonly 'tool.sticker': "Sticker";
1388
+ readonly 'tool.icon': "Icon";
1389
+ readonly 'tool.text': "Text";
1390
+ readonly 'tool.note': "Note";
1391
+ readonly 'tool.comment': "Comment";
1392
+ readonly 'tool.callout': "Callout";
1393
+ readonly 'tool.price_label': "Price label";
1394
+ readonly 'tool.arrow_up': "Arrow mark up";
1395
+ readonly 'tool.arrow_down': "Arrow mark down";
1396
+ readonly 'tool.arrow_marker': "Arrow marker";
1397
+ readonly 'tool.flag': "Flag mark";
1398
+ readonly 'tool.price_note': "Price note";
1399
+ readonly 'tool.pin': "Pin";
1400
+ readonly 'tool.signpost': "Signpost";
1401
+ readonly 'tool.table': "Table";
1402
+ readonly 'tool.brush': "Brush";
1403
+ readonly 'tool.highlighter': "Highlighter";
1404
+ readonly 'tool.path': "Path";
1405
+ readonly 'tool.polyline': "Polyline";
1406
+ readonly 'tool.price_range': "Price range";
1407
+ readonly 'tool.date_range': "Date range";
1408
+ readonly 'tool.date_and_price_range': "Date and price range";
1409
+ readonly 'tool.measure': "Measure";
1410
+ readonly 'legend.open': "O";
1411
+ readonly 'legend.high': "H";
1412
+ readonly 'legend.low': "L";
1413
+ readonly 'legend.close': "C";
1414
+ readonly 'legend.change': "{change} ({percent}%)";
1415
+ readonly 'legend.indicatorSettings': "Indicator settings";
1416
+ readonly 'legend.showRows': "Show study rows";
1417
+ readonly 'legend.hideRows': "Hide study rows";
1418
+ readonly 'legend.restorePane': "Restore pane";
1419
+ readonly 'legend.collapsePane': "Collapse pane";
1420
+ readonly 'legend.maximizePane': "Maximize pane";
1421
+ readonly 'legend.showIndicator': "Show indicator";
1422
+ readonly 'legend.hideIndicator': "Hide indicator";
1423
+ readonly 'legend.scaleNormal': "Reg";
1424
+ readonly 'legend.scaleLog': "Log";
1425
+ readonly 'legend.scalePercent': "%";
1426
+ readonly 'legend.scaleIndexed': "100";
1427
+ readonly 'legend.changeSymbol': "Change symbol";
1428
+ readonly 'legend.removeCompare': "Remove compare";
1429
+ readonly 'legend.removeIndicator': "Remove indicator";
1430
+ }, ChartLocaleCode>;
1431
+ /** A drawing tool's display name for a registry `type`: the catalog's when it knows the type, else
1432
+ * the registry's own English `name`, so a tool the catalog has not met still has a name. */
1433
+ declare function toolName(t: ChartTranslate, type: string, fallback: string): string;
1434
+ /** A multi-chart arrangement's display name for its code, else the arrangement catalog's English
1435
+ * label. An arrangement code separates its parts with hyphens (`2-2-l`) where a catalog key uses
1436
+ * underscores, so the code is converted rather than asking every caller to. */
1437
+ declare function arrangementName(t: ChartTranslate, code: string, fallback: string): string;
1438
+ /** A `ChartI18n` over the widget's own catalog, starting in `initial` (English when omitted): one
1439
+ * of the built-in codes, or a code the `locales` option registers. */
1440
+ declare function createChartI18n(initial?: string, options?: ChartI18nOptions): ChartI18n;
1441
+
1442
+ /** How a formatted price is punctuated. A price localizes the decimal sign only, so
1443
+ * `groupSign` defaults to '' (no thousands separator) and a host that wants grouping asks for it
1444
+ * explicitly. */
1445
+ interface NumericPunctuation {
1446
+ /** What separates the whole part from the decimals. Default '.', or the locale's sign when a
1447
+ * `locale` is given. */
1448
+ decimalSign?: string;
1449
+ /** What separates thousands in the whole part. Default '': a price is written ungrouped, because
1450
+ * a grouped price is harder to compare against the axis beside it. */
1451
+ groupSign?: string;
1452
+ }
1453
+ interface PriceFormatterOptions {
1454
+ /** A BCP 47 tag used ONCE, at construction, to derive the decimal sign. Anything explicit in
1455
+ * `numericPunctuation` wins over it. */
1456
+ locale?: string;
1457
+ numericPunctuation?: NumericPunctuation;
1458
+ }
1459
+ /** A resolved formatter for one symbol. `format` and `parse` are exact inverses over every price
1460
+ * that lands on the symbol's own grid. */
1461
+ interface PriceFormatter {
1462
+ /** The price as the symbol writes it. */
1463
+ format(price: number): string;
1464
+ /** The number a user typed, or null when the text is not a price in this symbol's format. */
1465
+ parse(text: string): number | null;
1466
+ /** How many digits `format` writes after the decimal sign. 0 for a fractional format, which
1467
+ * writes none; the widest band's width for a variable-tick format, so a column sized from it
1468
+ * never has to reflow. */
1469
+ precision(): number;
1470
+ }
1471
+ /** Build the formatter for one symbol's price format. The result is stateless and reusable; a host
1472
+ * resolves a symbol once and keeps its formatter for as long as the symbol is on screen. */
1473
+ declare function createPriceFormatter(format: PriceFormat, options?: PriceFormatterOptions): PriceFormatter;
1474
+
1475
+ /** The session an instant classifies into. `extended` is trading outside regular hours when the
1476
+ * symbol does not split it into pre-market and after-hours. */
1477
+ type SessionState = 'pre' | 'open' | 'extended' | 'after' | 'closed';
1478
+ /** One subsession of an extended-hours symbol: `regular`,
1479
+ * `extended`, `premarket` or `postmarket`, each with its own session string and, optionally,
1480
+ * the corrections that shorten it. `SymbolInfo.subsessions` satisfies it; an id the chart has
1481
+ * no state for is ignored. */
1482
+ interface SubsessionSource {
1483
+ readonly id: string;
1484
+ readonly session: string;
1485
+ readonly sessionCorrections?: string;
1486
+ }
1487
+ /** What a session model is built from: the symbology triple plus the optional corrections and
1488
+ * subsessions. `SymbolInfo` satisfies it. */
1489
+ interface SessionSource {
1490
+ readonly timezone: string;
1491
+ readonly session: string;
1492
+ readonly sessionHolidays?: string;
1493
+ readonly corrections?: string;
1494
+ readonly subsessions?: readonly SubsessionSource[];
1495
+ }
1496
+ /** One trading stretch of a trading day, in minutes from that day's exchange-local midnight. The
1497
+ * start may be negative (the stretch begins on a previous day) and the end may pass 1440 (it
1498
+ * runs into the next day); the end is exclusive. */
1499
+ interface SessionSegment {
1500
+ readonly start: number;
1501
+ readonly end: number;
1502
+ }
1503
+ /** A schedule: the stretches per weekday (0 = Sunday), and dated overrides keyed 'YYYYMMDD'. */
1504
+ interface SessionSchedule {
1505
+ readonly week: readonly (readonly SessionSegment[])[];
1506
+ readonly corrections: ReadonlyMap<string, readonly SessionSegment[]>;
1507
+ }
1508
+ interface SessionModel {
1509
+ /** The exchange zone every minute here is read in. */
1510
+ readonly timezone: string;
1511
+ /** A `24x7` symbol: always open, no transitions, no timeline. */
1512
+ readonly continuous: boolean;
1513
+ /** The regular session. */
1514
+ readonly regular: SessionSchedule;
1515
+ /** Extended-hours stretches by the state they classify into, from the subsessions. */
1516
+ readonly extended: readonly {
1517
+ readonly state: Exclude<SessionState, 'open' | 'closed'>;
1518
+ readonly schedule: SessionSchedule;
1519
+ }[];
1520
+ /** Full-closure dates, 'YYYYMMDD'. */
1521
+ readonly holidays: ReadonlySet<string>;
1522
+ }
1523
+ /** Build the session model from a symbol's metadata. Null when the grammar cannot read any part
1524
+ * of it: a chart then shows no bands, no status and no timeline for the symbol rather than a
1525
+ * session it guessed. A `regular` subsession, when given, is the regular session; the symbol's
1526
+ * `session` is otherwise. Subsessions with ids the chart has no state for are ignored. */
1527
+ declare function parseSessionModel(source: SessionSource): SessionModel | null;
1528
+ /** Which of a symbol's named sessions a chart displays:
1529
+ * `regular` shows regular hours only, `extended` shows the extended-hours bars as well. A
1530
+ * per-chart preference a host persists. `extended` is the DEFAULT and shows every bar the feed
1531
+ * served; narrowing to `regular` is the opt-in, because a chart that silently hid bars it had
1532
+ * would be lying about the market by default. A symbol without extended hours has nothing to
1533
+ * choose, and every bar shows either way. */
1534
+ type ActiveSubsession = 'regular' | 'extended';
1535
+ declare const DEFAULT_SUBSESSION: ActiveSubsession;
1536
+ /** Whether the symbol declared any hours outside its regular session. Only such a symbol offers a
1537
+ * subsession choice or shades extended hours. */
1538
+ declare function hasExtendedHours(model: SessionModel): boolean;
1539
+ /** The bar filter for the active subsession: under `regular`, on a symbol with extended hours,
1540
+ * keep the bars whose open falls in regular hours; otherwise nothing is filtered (null). For
1541
+ * intraday intervals only: a daily bar spans whole sessions, so a caller applies the filter on
1542
+ * intraday intervals and shows every daily bar. */
1543
+ declare function subsessionBarFilter(model: SessionModel, active: ActiveSubsession): ((epochSecs: number) => boolean) | null;
1544
+ /** The session state at an instant (epoch seconds), under the symbol's exchange clock. */
1545
+ declare function sessionStateAt(model: SessionModel, epochSecs: number): SessionState;
1546
+ /** The next session transition after an instant, exact to the minute, or null when there is
1547
+ * none within eight days (a continuous market, or a long closure). */
1548
+ declare function nextSessionChange(model: SessionModel, epochSecs: number): {
1549
+ atSecs: number;
1550
+ state: SessionState;
1551
+ } | null;
1552
+ interface SessionTimeline {
1553
+ /** The exchange-local day's stretches, closed gaps included, covering 0 to 1440 minutes. */
1554
+ readonly segments: readonly {
1555
+ readonly start: number;
1556
+ readonly end: number;
1557
+ readonly state: SessionState;
1558
+ }[];
1559
+ /** Now, in exchange-local minutes from midnight. */
1560
+ readonly nowMins: number;
1561
+ /** The exchange-local weekday, written in the language of `tag` and upper-cased ("MON"). */
1562
+ readonly dayLabel: string;
1563
+ readonly timezone: string;
1564
+ }
1565
+ /** The exchange-local day's timeline for a status popup. `tag` is the BCP 47 tag the weekday is
1566
+ * written in: a date part, so it comes from Intl rather than the catalog. */
1567
+ declare function sessionTimeline(model: SessionModel, epochSecs: number, tag: string): SessionTimeline;
1568
+ /** A symbol's market status at an instant: the session state and the feed's liveness together,
1569
+ * so a consumer cannot present an end-of-day or delayed feed as a live open market. */
1570
+ interface MarketStatus {
1571
+ readonly state: SessionState;
1572
+ /** The feed's liveness, an explicit part of the status. */
1573
+ readonly dataStatus: DataStatus;
1574
+ /** A `24x7` symbol. */
1575
+ readonly continuous: boolean;
1576
+ /** The next transition, or null when there is none to count down to. */
1577
+ readonly next: {
1578
+ readonly atSecs: number;
1579
+ readonly state: SessionState;
1580
+ } | null;
1581
+ }
1582
+ declare function marketStatus(model: SessionModel, dataStatus: DataStatus, nowSecs: number): MarketStatus;
1583
+ /** The market status straight from a resolved symbol, or null when its session cannot be read. */
1584
+ declare function marketStatusFor(symbol: Pick<SymbolInfo, 'timezone' | 'session' | 'sessionHolidays' | 'corrections' | 'subsessions' | 'dataStatus'>, nowSecs: number): MarketStatus | null;
1585
+ /** The catalog key of a session state's name: the same five words the legend's status dot and
1586
+ * a status popup's title use. */
1587
+ declare const SESSION_STATE_TITLE: Readonly<Record<SessionState, ChartMessageKey>>;
1588
+ /** The title line of a status popup: the feed's liveness when it is not a live stream, the
1589
+ * continuous market's own word, or the session state's name. */
1590
+ declare function marketStatusTitle(t: ChartTranslate, status: MarketStatus): string;
1591
+ /** "3 days 4 hours": the coarsest unit, and the next one down when it is non-zero. Each unit is a
1592
+ * whole phrase and `status.durationPair` owns the order and the separator, so a language decides
1593
+ * both rather than inheriting English's. A duration under a minute reads as one minute. */
1594
+ declare function formatDuration(t: ChartTranslate, secs: number): string;
1595
+ /** The sentence under a status popup's title. An end-of-day feed states that and nothing about
1596
+ * hours; a continuous market states that it never closes; otherwise the session state with a
1597
+ * countdown to the next transition when one is known, and a delayed stream adds that its prices
1598
+ * are delayed. */
1599
+ declare function marketStatusText(t: ChartTranslate, status: MarketStatus, nowSecs: number): string;
1600
+ /** The footer naming the exchange zone a timeline is drawn in: "Exchange timezone: New York
1601
+ * (UTC-4)". */
1602
+ declare function exchangeTimezoneText(t: ChartTranslate, timezone: string, at?: Date): string;
1603
+
1604
+ /** Paints a market's mark into a box the chart owns, and answers what takes it down again. */
1605
+ type SymbolMarkPainter = (request: {
1606
+ symbol: string;
1607
+ host: HTMLElement;
1608
+ size: number;
1609
+ }) => (() => void) | void;
1610
+ /** Paints the mark of the venue a market lists on, the same way. */
1611
+ type VenueMarkPainter = (request: {
1612
+ exchange: string;
1613
+ host: HTMLElement;
1614
+ size: number;
1615
+ }) => (() => void) | void;
1616
+ /** Paints the mark of a data provider, where a row names a provider rather than a venue. */
1617
+ type ProviderMarkPainter = (request: {
1618
+ provider: string;
1619
+ host: HTMLElement;
1620
+ size: number;
1621
+ }) => (() => void) | void;
1622
+ /** Every painter the host lent, as the chart carries them: null where it lent none. */
1623
+ interface MarkPainters {
1624
+ readonly symbol: SymbolMarkPainter | null;
1625
+ readonly venue: VenueMarkPainter | null;
1626
+ readonly provider: ProviderMarkPainter | null;
1627
+ }
1628
+ /** The host's hooks, as an entry point takes them. Each is the host's to lend or withhold, and
1629
+ * every entry point that paints marks takes exactly these, so a host writes them once and hands
1630
+ * the same three to a chart and to a picker it opens away from one. */
1631
+ interface MarkPainterHooks {
1632
+ /** The host's mark for a market, called WHEREVER the chart names one: each chart's legend, the
1633
+ * compare rows under it, every row of the symbol search and compare dialogs, and the market tag
1634
+ * a trading notice wears. It receives the element to paint into and the symbol it stands for,
1635
+ * and returns a disposer that takes the mark down again.
1636
+ *
1637
+ * One hook rather than one per surface, so a market wears the same mark everywhere it appears and
1638
+ * a host implements it once. The chart ships no artwork and fetches none: absent this, every mark
1639
+ * is the neutral monogram the package draws itself. */
1640
+ symbolMark?: SymbolMarkPainter;
1641
+ /** The host's mark for the venue a market lists on, painted beside the venue's name in every row
1642
+ * of the symbol search and compare dialogs. Like `symbolMark`, it receives the element to paint
1643
+ * into and the size of the box, and returns a disposer; absent, a venue wears its initial on the
1644
+ * neutral disc the package draws itself. */
1645
+ venueMark?: VenueMarkPainter;
1646
+ /** The host's mark for the data provider a row names where it names no venue, painted in that
1647
+ * row's source cell the same way. Absent, the provider wears its initial on the neutral disc. */
1648
+ providerMark?: ProviderMarkPainter;
1649
+ }
1650
+
1651
+ /** One glyph: its own grid and the inner markup drawn on it. */
1652
+ interface Glyph {
1653
+ viewBox: string;
1654
+ body: string;
1655
+ /** A glyph that is not square keeps its grid's proportion: the size is its HEIGHT and the width
1656
+ * follows this ratio. Square glyphs omit it. */
1657
+ aspect?: number;
1658
+ /** The height the glyph is drawn at when a caller names none. Glyphs drawn at 28 omit it. */
1659
+ size?: number;
1660
+ }
1661
+
1662
+ interface ChartOverrides {
1663
+ appearance: {
1664
+ background: string;
1665
+ upColor: string;
1666
+ downColor: string;
1667
+ /** Candle anatomy: the border ring and the wick are their OWN colors per direction. They do
1668
+ * NOT follow upColor/downColor; each is set independently. */
1669
+ borderUpColor: string;
1670
+ borderDownColor: string;
1671
+ wickUpColor: string;
1672
+ wickDownColor: string;
1673
+ grid: boolean;
1674
+ /** Shade pre-market / after-hours / overnight stretches. */
1675
+ sessions: boolean;
1676
+ /** Bar-close countdown pill on the price scale. */
1677
+ countdown: boolean;
1678
+ };
1679
+ }
1680
+ /** The brand palette, single-sourced: any surface that speaks for trdrs reads these (the trading
1681
+ * extension's buy line among them), and a rebrand edits two strings. The pair does not reach the
1682
+ * candle bodies; see the note on DEFAULT_OVERRIDES for why. */
1683
+ declare const BRAND_UP = "#4c98fb";
1684
+ declare const BRAND_DOWN = "#f23645";
1685
+ declare const DEFAULT_OVERRIDES: ChartOverrides;
1686
+ /** A recursive partial of the tree — what a host supplies. */
1687
+ type PartialOverrides = {
1688
+ [S in keyof ChartOverrides]?: Partial<ChartOverrides[S]>;
1689
+ };
1690
+ /** Deep-fill a partial over the defaults. One level of nesting by design — the tree is two levels
1691
+ * (section → leaf) and stays that way; new leaves are additive. */
1692
+ declare function mergeOverrides(partial?: PartialOverrides | null): ChartOverrides;
1693
+ /** The precedence composer: deep-fill any number of partials over an explicit BASE, later layers
1694
+ * winning leaf by leaf. The widget's look resolves through this — its theme-derived floor, then
1695
+ * the host's constructor partial, then runtime applyAppearance calls: one ladder where runtime
1696
+ * beats constructor beats theme, expressed as one pure function. */
1697
+ declare function layerOverrides(base: ChartOverrides, ...partials: (PartialOverrides | null | undefined)[]): ChartOverrides;
1698
+
1699
+ /** One resolved role as it is written to the DOM. */
1700
+ interface ThemeDeclaration {
1701
+ /** The private custom-property name. */
1702
+ property: string;
1703
+ /** The resolved value, already a CSS token. */
1704
+ value: string;
1705
+ }
1706
+
1707
+ /** The two modes Quick Charts ships complete. A host switches between them at runtime; it does not
1708
+ * add a third. A host that keeps named brand presets resolves each preset to a custom light or
1709
+ * dark palette before passing it in. */
1710
+ type ThemeMode = 'light' | 'dark';
1711
+ /** What a role's value is written as. Every value is a CSS token string, so `length` is `'4px'` and
1712
+ * `duration` is `'150ms'`; the kind says which tokens are valid, and validation enforces it. */
1713
+ type ThemeRoleKind = 'color' | 'length' | 'font' | 'duration' | 'shadow';
1714
+ /** The grouping a role belongs to. Families organize the manual and the manifest; they are not part
1715
+ * of a role's identity. */
1716
+ type ThemeRoleFamily = 'canvas' | 'series' | 'scale' | 'text' | 'chrome' | 'overlay' | 'state' | 'control' | 'status' | 'illustration' | 'drawing' | 'motion';
1717
+ /** A readability requirement the palettes must meet: this role's value, read against the value of
1718
+ * `over`, reaches `min` under the WCAG 2.2 contrast formula. Where `over` is a translucent tint
1719
+ * such as the hover or selected fill, `on` names the opaque surface the tint is drawn on, and the
1720
+ * tint is flattened onto it before measuring. Body text needs 4.5, a non-text indicator such as a
1721
+ * focus ring needs 3. */
1722
+ interface ThemeContrastRule {
1723
+ over: string;
1724
+ on?: string;
1725
+ min: number;
1726
+ }
1727
+ /** One entry of the inventory. */
1728
+ interface ThemeRole {
1729
+ /** The public id, `family.name`. Also the key of `SemanticTheme`. */
1730
+ id: string;
1731
+ family: ThemeRoleFamily;
1732
+ kind: ThemeRoleKind;
1733
+ /** One sentence naming what the role means, published in the manifest and the manual. */
1734
+ description: string;
1735
+ /** Present when the role carries readability requirements: one rule per ground the stylesheet's
1736
+ * recipes draw it on. */
1737
+ contrast?: readonly ThemeContrastRule[];
1738
+ }
1739
+ /** The complete role inventory. Adding an entry is a minor API change and needs a value in both
1740
+ * built-in palettes; removing one is breaking. */
1741
+ declare const THEME_ROLES: readonly [{
1742
+ readonly id: "canvas.background";
1743
+ readonly family: "canvas";
1744
+ readonly kind: "color";
1745
+ readonly description: "The fill behind the plotted series.";
1746
+ }, {
1747
+ readonly id: "canvas.paneBorder";
1748
+ readonly family: "canvas";
1749
+ readonly kind: "color";
1750
+ readonly description: "The divider between stacked panes and around the plot area.";
1751
+ }, {
1752
+ readonly id: "series.up";
1753
+ readonly family: "series";
1754
+ readonly kind: "color";
1755
+ readonly description: "A rising value: up volume, a rising study tint, a positive series default.";
1756
+ }, {
1757
+ readonly id: "series.down";
1758
+ readonly family: "series";
1759
+ readonly kind: "color";
1760
+ readonly description: "A falling value: down volume, a falling study tint, a negative series default.";
1761
+ }, {
1762
+ readonly id: "series.neutral";
1763
+ readonly family: "series";
1764
+ readonly kind: "color";
1765
+ readonly description: "A series or level with no direction, such as a study level line.";
1766
+ }, {
1767
+ readonly id: "scale.grid";
1768
+ readonly family: "scale";
1769
+ readonly kind: "color";
1770
+ readonly description: "The grid lines drawn across the plot area.";
1771
+ }, {
1772
+ readonly id: "scale.background";
1773
+ readonly family: "scale";
1774
+ readonly kind: "color";
1775
+ readonly description: "The ground behind the price and time scales.";
1776
+ }, {
1777
+ readonly id: "scale.border";
1778
+ readonly family: "scale";
1779
+ readonly kind: "color";
1780
+ readonly description: "The line separating a scale from the plot area.";
1781
+ }, {
1782
+ readonly id: "scale.text";
1783
+ readonly family: "scale";
1784
+ readonly kind: "color";
1785
+ readonly description: "Tick labels on the price and time scales.";
1786
+ readonly contrast: readonly [{
1787
+ readonly over: "scale.background";
1788
+ readonly min: 4.5;
1789
+ }];
1790
+ }, {
1791
+ readonly id: "scale.crosshair";
1792
+ readonly family: "scale";
1793
+ readonly kind: "color";
1794
+ readonly description: "The crosshair lines that follow the pointer.";
1795
+ }, {
1796
+ readonly id: "scale.crosshairLabelBackground";
1797
+ readonly family: "scale";
1798
+ readonly kind: "color";
1799
+ readonly description: "The fill of the crosshair value label on a scale.";
1800
+ }, {
1801
+ readonly id: "scale.crosshairLabelText";
1802
+ readonly family: "scale";
1803
+ readonly kind: "color";
1804
+ readonly description: "The value inside the crosshair label.";
1805
+ readonly contrast: readonly [{
1806
+ readonly over: "scale.crosshairLabelBackground";
1807
+ readonly min: 4.5;
1808
+ }];
1809
+ }, {
1810
+ readonly id: "scale.sessionPreMarket";
1811
+ readonly family: "scale";
1812
+ readonly kind: "color";
1813
+ readonly description: "Shading over pre-market bars.";
1814
+ }, {
1815
+ readonly id: "scale.sessionExtended";
1816
+ readonly family: "scale";
1817
+ readonly kind: "color";
1818
+ readonly description: "Shading over electronic-hours bars.";
1819
+ }, {
1820
+ readonly id: "scale.sessionAfterHours";
1821
+ readonly family: "scale";
1822
+ readonly kind: "color";
1823
+ readonly description: "Shading over after-hours bars.";
1824
+ }, {
1825
+ readonly id: "scale.sessionClosed";
1826
+ readonly family: "scale";
1827
+ readonly kind: "color";
1828
+ readonly description: "Shading over bars while the market is closed.";
1829
+ }, {
1830
+ readonly id: "text.primary";
1831
+ readonly family: "text";
1832
+ readonly kind: "color";
1833
+ readonly description: "Default ink for chart controls, menus, and dialogs.";
1834
+ readonly contrast: readonly [{
1835
+ readonly over: "chrome.surface";
1836
+ readonly min: 4.5;
1837
+ }, {
1838
+ readonly over: "state.selected";
1839
+ readonly on: "overlay.surface";
1840
+ readonly min: 4.5;
1841
+ }];
1842
+ }, {
1843
+ readonly id: "text.secondary";
1844
+ readonly family: "text";
1845
+ readonly kind: "color";
1846
+ readonly description: "Supporting ink: descriptions, group headings, secondary values.";
1847
+ readonly contrast: readonly [{
1848
+ readonly over: "chrome.surface";
1849
+ readonly min: 4.5;
1850
+ }, {
1851
+ readonly over: "state.selected";
1852
+ readonly on: "overlay.surface";
1853
+ readonly min: 4.5;
1854
+ }, {
1855
+ readonly over: "state.hover";
1856
+ readonly on: "overlay.surface";
1857
+ readonly min: 4.5;
1858
+ }];
1859
+ }, {
1860
+ readonly id: "text.muted";
1861
+ readonly family: "text";
1862
+ readonly kind: "color";
1863
+ readonly description: "The least emphasized readable ink, such as a keyboard hint.";
1864
+ readonly contrast: readonly [{
1865
+ readonly over: "chrome.surface";
1866
+ readonly min: 4.5;
1867
+ }, {
1868
+ readonly over: "state.selected";
1869
+ readonly on: "overlay.surface";
1870
+ readonly min: 4.5;
1871
+ }, {
1872
+ readonly over: "state.hover";
1873
+ readonly on: "overlay.surface";
1874
+ readonly min: 4.5;
1875
+ }];
1876
+ }, {
1877
+ readonly id: "text.disabled";
1878
+ readonly family: "text";
1879
+ readonly kind: "color";
1880
+ readonly description: "Ink of a control that cannot be used. WCAG exempts an inactive control from a contrast minimum.";
1881
+ }, {
1882
+ readonly id: "text.inverse";
1883
+ readonly family: "text";
1884
+ readonly kind: "color";
1885
+ readonly description: "Ink on an inverted or danger fill: a held mode on the on fill, a destructive action.";
1886
+ readonly contrast: readonly [{
1887
+ readonly over: "control.on";
1888
+ readonly min: 4.5;
1889
+ }, {
1890
+ readonly over: "status.negative";
1891
+ readonly min: 4.5;
1892
+ }];
1893
+ }, {
1894
+ readonly id: "text.link";
1895
+ readonly family: "text";
1896
+ readonly kind: "color";
1897
+ readonly description: "Ink of a text link inside chart chrome, and of a label naming an accent state, such as a running replay.";
1898
+ readonly contrast: readonly [{
1899
+ readonly over: "chrome.surface";
1900
+ readonly min: 4.5;
1901
+ }, {
1902
+ readonly over: "overlay.surface";
1903
+ readonly min: 4.5;
1904
+ }];
1905
+ }, {
1906
+ readonly id: "text.highlight";
1907
+ readonly family: "text";
1908
+ readonly kind: "color";
1909
+ readonly description: "Ink of the part of a label that matches what the reader typed, such as a symbol search.";
1910
+ readonly contrast: readonly [{
1911
+ readonly over: "overlay.surface";
1912
+ readonly min: 4.5;
1913
+ }, {
1914
+ readonly over: "chrome.surface";
1915
+ readonly min: 4.5;
1916
+ }];
1917
+ }, {
1918
+ readonly id: "text.onCanvas";
1919
+ readonly family: "text";
1920
+ readonly kind: "color";
1921
+ readonly description: "Ink drawn directly over the plot area, such as the legend.";
1922
+ readonly contrast: readonly [{
1923
+ readonly over: "canvas.background";
1924
+ readonly min: 4.5;
1925
+ }];
1926
+ }, {
1927
+ readonly id: "text.fontFamily";
1928
+ readonly family: "text";
1929
+ readonly kind: "font";
1930
+ readonly description: "The font stack chart chrome and canvas text share. Quick Charts never downloads a font.";
1931
+ }, {
1932
+ readonly id: "text.fontSizeAxis";
1933
+ readonly family: "text";
1934
+ readonly kind: "length";
1935
+ readonly description: "Size of scale and crosshair labels drawn into the canvas.";
1936
+ }, {
1937
+ readonly id: "text.fontSizeTitle";
1938
+ readonly family: "text";
1939
+ readonly kind: "length";
1940
+ readonly description: "Size of a dialog or panel title.";
1941
+ }, {
1942
+ readonly id: "text.fontSizeBase";
1943
+ readonly family: "text";
1944
+ readonly kind: "length";
1945
+ readonly description: "Size of ordinary control and menu text.";
1946
+ }, {
1947
+ readonly id: "text.fontSizeSmall";
1948
+ readonly family: "text";
1949
+ readonly kind: "length";
1950
+ readonly description: "Size of dense control text, such as a legend row.";
1951
+ }, {
1952
+ readonly id: "text.fontSizeMicro";
1953
+ readonly family: "text";
1954
+ readonly kind: "length";
1955
+ readonly description: "Size of the smallest chip and hint text.";
1956
+ }, {
1957
+ readonly id: "chrome.surface";
1958
+ readonly family: "chrome";
1959
+ readonly kind: "color";
1960
+ readonly description: "The fill of toolbars, rails, bars, and panels.";
1961
+ }, {
1962
+ readonly id: "chrome.surfaceRaised";
1963
+ readonly family: "chrome";
1964
+ readonly kind: "color";
1965
+ readonly description: "The fill of a control sitting on a chrome surface, such as a button or field.";
1966
+ }, {
1967
+ readonly id: "chrome.border";
1968
+ readonly family: "chrome";
1969
+ readonly kind: "color";
1970
+ readonly description: "The ordinary border of a control or panel.";
1971
+ }, {
1972
+ readonly id: "chrome.borderStrong";
1973
+ readonly family: "chrome";
1974
+ readonly kind: "color";
1975
+ readonly description: "A border or divider that must stay visible at a glance.";
1976
+ readonly contrast: readonly [{
1977
+ readonly over: "chrome.surface";
1978
+ readonly min: 3;
1979
+ }];
1980
+ }, {
1981
+ readonly id: "chrome.fieldBorder";
1982
+ readonly family: "chrome";
1983
+ readonly kind: "color";
1984
+ readonly description: "The outline of a text field, such as the symbol search field. The field's mark and prompt name it, so the outline is not its only sign.";
1985
+ }, {
1986
+ readonly id: "chrome.caret";
1987
+ readonly family: "chrome";
1988
+ readonly kind: "color";
1989
+ readonly description: "The ink of the arrow that opens a control's menu or flyout.";
1990
+ readonly contrast: readonly [{
1991
+ readonly over: "chrome.surface";
1992
+ readonly min: 3;
1993
+ }];
1994
+ }, {
1995
+ readonly id: "chrome.grip";
1996
+ readonly family: "chrome";
1997
+ readonly kind: "color";
1998
+ readonly description: "The dots of a drag handle on a floating toolbar.";
1999
+ }, {
2000
+ readonly id: "chrome.scrollThumb";
2001
+ readonly family: "chrome";
2002
+ readonly kind: "color";
2003
+ readonly description: "The thumb of the thin bar beside a list the viewer scrolls, such as the search results or the indicator list.";
2004
+ }, {
2005
+ readonly id: "chrome.radius";
2006
+ readonly family: "chrome";
2007
+ readonly kind: "length";
2008
+ readonly description: "Corner radius of a control.";
2009
+ }, {
2010
+ readonly id: "chrome.radiusLarge";
2011
+ readonly family: "chrome";
2012
+ readonly kind: "length";
2013
+ readonly description: "Corner radius of a panel, dialog, or menu.";
2014
+ }, {
2015
+ readonly id: "overlay.surface";
2016
+ readonly family: "overlay";
2017
+ readonly kind: "color";
2018
+ readonly description: "The fill of a floating menu, dialog, or popover.";
2019
+ }, {
2020
+ readonly id: "overlay.separator";
2021
+ readonly family: "overlay";
2022
+ readonly kind: "color";
2023
+ readonly description: "The rule between groups inside a menu or panel.";
2024
+ }, {
2025
+ readonly id: "overlay.shadow";
2026
+ readonly family: "overlay";
2027
+ readonly kind: "shadow";
2028
+ readonly description: "The elevation shadow of a floating surface.";
2029
+ }, {
2030
+ readonly id: "overlay.scrim";
2031
+ readonly family: "overlay";
2032
+ readonly kind: "color";
2033
+ readonly description: "The backdrop that dims the chart behind a modal dialog.";
2034
+ }, {
2035
+ readonly id: "state.accent";
2036
+ readonly family: "state";
2037
+ readonly kind: "color";
2038
+ readonly description: "The accent a mark, fill, or glyph wears: a chosen day, a selected tab, an armed favorite.";
2039
+ readonly contrast: readonly [{
2040
+ readonly over: "chrome.surface";
2041
+ readonly min: 3;
2042
+ }, {
2043
+ readonly over: "overlay.surface";
2044
+ readonly min: 3;
2045
+ }];
2046
+ }, {
2047
+ readonly id: "state.hover";
2048
+ readonly family: "state";
2049
+ readonly kind: "color";
2050
+ readonly description: "The fill a control takes under the pointer.";
2051
+ }, {
2052
+ readonly id: "state.hoverInk";
2053
+ readonly family: "state";
2054
+ readonly kind: "color";
2055
+ readonly description: "The ink a row of a plain picking list, such as the time zone list, dims to under the pointer.";
2056
+ readonly contrast: readonly [{
2057
+ readonly over: "state.hover";
2058
+ readonly on: "overlay.surface";
2059
+ readonly min: 4.5;
2060
+ }];
2061
+ }, {
2062
+ readonly id: "state.pressed";
2063
+ readonly family: "state";
2064
+ readonly kind: "color";
2065
+ readonly description: "The fill a control takes while the pointer is down, and the fill of an armed tool.";
2066
+ }, {
2067
+ readonly id: "state.pressedHover";
2068
+ readonly family: "state";
2069
+ readonly kind: "color";
2070
+ readonly description: "The fill of an armed tool or a held toggle under the pointer.";
2071
+ }, {
2072
+ readonly id: "state.selected";
2073
+ readonly family: "state";
2074
+ readonly kind: "color";
2075
+ readonly description: "The fill of a chosen row, tab, or tool.";
2076
+ }, {
2077
+ readonly id: "state.focusRing";
2078
+ readonly family: "state";
2079
+ readonly kind: "color";
2080
+ readonly description: "The visible focus indicator, including the active pane ring.";
2081
+ readonly contrast: readonly [{
2082
+ readonly over: "chrome.surface";
2083
+ readonly min: 3;
2084
+ }];
2085
+ }, {
2086
+ readonly id: "state.markInk";
2087
+ readonly family: "state";
2088
+ readonly kind: "color";
2089
+ readonly description: "Ink on the accent or a filled state mark: a chosen day, the replay disc's cut-out.";
2090
+ readonly contrast: readonly [{
2091
+ readonly over: "state.accent";
2092
+ readonly min: 4.5;
2093
+ }];
2094
+ }, {
2095
+ readonly id: "state.selection";
2096
+ readonly family: "state";
2097
+ readonly kind: "color";
2098
+ readonly description: "The tint over selected content.";
2099
+ }, {
2100
+ readonly id: "control.on";
2101
+ readonly family: "control";
2102
+ readonly kind: "color";
2103
+ readonly description: "The emphasis fill: a switch, checkbox, or radio that is on, a chosen row, a held mode, and the primary action; also the ring of a checkbox or radio that is off.";
2104
+ readonly contrast: readonly [{
2105
+ readonly over: "overlay.surface";
2106
+ readonly min: 3;
2107
+ }, {
2108
+ readonly over: "chrome.surface";
2109
+ readonly min: 3;
2110
+ }];
2111
+ }, {
2112
+ readonly id: "control.onHover";
2113
+ readonly family: "control";
2114
+ readonly kind: "color";
2115
+ readonly description: "The emphasis fill, and the ring of a radio, under the pointer.";
2116
+ }, {
2117
+ readonly id: "control.onPressed";
2118
+ readonly family: "control";
2119
+ readonly kind: "color";
2120
+ readonly description: "The emphasis fill, and the ring of a radio, while the pointer is down.";
2121
+ }, {
2122
+ readonly id: "control.off";
2123
+ readonly family: "control";
2124
+ readonly kind: "color";
2125
+ readonly description: "The track of a switch that is off.";
2126
+ }, {
2127
+ readonly id: "control.offHover";
2128
+ readonly family: "control";
2129
+ readonly kind: "color";
2130
+ readonly description: "The track of a switch that is off, under the pointer.";
2131
+ }, {
2132
+ readonly id: "control.offPressed";
2133
+ readonly family: "control";
2134
+ readonly kind: "color";
2135
+ readonly description: "The track of a switch that is off, while the pointer is down.";
2136
+ }, {
2137
+ readonly id: "control.mark";
2138
+ readonly family: "control";
2139
+ readonly kind: "color";
2140
+ readonly description: "The knob of a switch, the check of a checkbox, and the dot of a radio.";
2141
+ readonly contrast: readonly [{
2142
+ readonly over: "control.on";
2143
+ readonly min: 3;
2144
+ }, {
2145
+ readonly over: "control.onHover";
2146
+ readonly min: 3;
2147
+ }, {
2148
+ readonly over: "control.onPressed";
2149
+ readonly min: 3;
2150
+ }];
2151
+ }, {
2152
+ readonly id: "status.positive";
2153
+ readonly family: "status";
2154
+ readonly kind: "color";
2155
+ readonly description: "A positive value or a successful outcome in chart chrome.";
2156
+ readonly contrast: readonly [{
2157
+ readonly over: "chrome.surface";
2158
+ readonly min: 4.5;
2159
+ }];
2160
+ }, {
2161
+ readonly id: "status.negative";
2162
+ readonly family: "status";
2163
+ readonly kind: "color";
2164
+ readonly description: "A negative value or a failed outcome in chart chrome.";
2165
+ readonly contrast: readonly [{
2166
+ readonly over: "chrome.surface";
2167
+ readonly min: 4.5;
2168
+ }];
2169
+ }, {
2170
+ readonly id: "status.warning";
2171
+ readonly family: "status";
2172
+ readonly kind: "color";
2173
+ readonly description: "A condition the reader should notice before acting.";
2174
+ readonly contrast: readonly [{
2175
+ readonly over: "chrome.surface";
2176
+ readonly min: 4.5;
2177
+ }];
2178
+ }, {
2179
+ readonly id: "status.info";
2180
+ readonly family: "status";
2181
+ readonly kind: "color";
2182
+ readonly description: "An informational note in chart chrome.";
2183
+ readonly contrast: readonly [{
2184
+ readonly over: "chrome.surface";
2185
+ readonly min: 4.5;
2186
+ }];
2187
+ }, {
2188
+ readonly id: "status.loading";
2189
+ readonly family: "status";
2190
+ readonly kind: "color";
2191
+ readonly description: "The indicator shown while the chart waits for data.";
2192
+ }, {
2193
+ readonly id: "status.sessionPreMarket";
2194
+ readonly family: "status";
2195
+ readonly kind: "color";
2196
+ readonly description: "The session status marker for pre-market.";
2197
+ }, {
2198
+ readonly id: "status.sessionOpen";
2199
+ readonly family: "status";
2200
+ readonly kind: "color";
2201
+ readonly description: "The session status marker while the market is open.";
2202
+ }, {
2203
+ readonly id: "status.sessionExtended";
2204
+ readonly family: "status";
2205
+ readonly kind: "color";
2206
+ readonly description: "The session status marker for electronic hours.";
2207
+ }, {
2208
+ readonly id: "status.sessionAfterHours";
2209
+ readonly family: "status";
2210
+ readonly kind: "color";
2211
+ readonly description: "The session status marker for after-hours.";
2212
+ }, {
2213
+ readonly id: "status.sessionClosed";
2214
+ readonly family: "status";
2215
+ readonly kind: "color";
2216
+ readonly description: "The session status marker while the market is closed.";
2217
+ }, {
2218
+ readonly id: "illustration.ink";
2219
+ readonly family: "illustration";
2220
+ readonly kind: "color";
2221
+ readonly description: "The line drawing of an empty-state illustration.";
2222
+ readonly contrast: readonly [{
2223
+ readonly over: "overlay.surface";
2224
+ readonly min: 3;
2225
+ }];
2226
+ }, {
2227
+ readonly id: "illustration.accent";
2228
+ readonly family: "illustration";
2229
+ readonly kind: "color";
2230
+ readonly description: "The badge an empty-state illustration wears on the action it invites.";
2231
+ readonly contrast: readonly [{
2232
+ readonly over: "overlay.surface";
2233
+ readonly min: 3;
2234
+ }];
2235
+ }, {
2236
+ readonly id: "illustration.accentInk";
2237
+ readonly family: "illustration";
2238
+ readonly kind: "color";
2239
+ readonly description: "The mark on an illustration's badge.";
2240
+ readonly contrast: readonly [{
2241
+ readonly over: "illustration.accent";
2242
+ readonly min: 3;
2243
+ }];
2244
+ }, {
2245
+ readonly id: "drawing.line";
2246
+ readonly family: "drawing";
2247
+ readonly kind: "color";
2248
+ readonly description: "The stroke of a newly placed drawing.";
2249
+ }, {
2250
+ readonly id: "drawing.fill";
2251
+ readonly family: "drawing";
2252
+ readonly kind: "color";
2253
+ readonly description: "The fill of a newly placed drawing that has an area.";
2254
+ }, {
2255
+ readonly id: "drawing.text";
2256
+ readonly family: "drawing";
2257
+ readonly kind: "color";
2258
+ readonly description: "The ink of a drawing label.";
2259
+ }, {
2260
+ readonly id: "drawing.handle";
2261
+ readonly family: "drawing";
2262
+ readonly kind: "color";
2263
+ readonly description: "The center of a drawing selection handle.";
2264
+ }, {
2265
+ readonly id: "drawing.selected";
2266
+ readonly family: "drawing";
2267
+ readonly kind: "color";
2268
+ readonly description: "The highlight of a selected drawing and its handles.";
2269
+ }, {
2270
+ readonly id: "motion.durationFast";
2271
+ readonly family: "motion";
2272
+ readonly kind: "duration";
2273
+ readonly description: "A state change the reader should not have to wait for, such as a hover.";
2274
+ }, {
2275
+ readonly id: "motion.durationBase";
2276
+ readonly family: "motion";
2277
+ readonly kind: "duration";
2278
+ readonly description: "An ordinary transition, such as a menu opening.";
2279
+ }];
2280
+ /** Every role id in the inventory. */
2281
+ type ThemeRoleId = (typeof THEME_ROLES)[number]['id'];
2282
+ /** One resolved mode: every role, concrete. Values are CSS tokens, so a length is `'4px'` and a
2283
+ * duration is `'150ms'`. */
2284
+ type SemanticTheme = {
2285
+ readonly [Id in ThemeRoleId]: string;
2286
+ };
2287
+ /** What a host supplies: a partial palette for either mode, or both. An omitted role keeps the
2288
+ * built-in value for that mode. */
2289
+ interface CustomThemes {
2290
+ light?: Partial<SemanticTheme>;
2291
+ dark?: Partial<SemanticTheme>;
2292
+ }
2293
+
2294
+ /** Everything the widget writes on its own root element for one resolved theme. */
2295
+ interface ThemeRootStyle {
2296
+ /** The attribute that scopes the package stylesheet to this instance. */
2297
+ attribute: {
2298
+ name: string;
2299
+ value: ThemeMode;
2300
+ };
2301
+ /** One entry per role, ordered by role id. */
2302
+ declarations: readonly ThemeDeclaration[];
2303
+ }
2304
+ /** The theme values the canvas renderer draws with. The chart appearance ladder sits above these:
2305
+ * a host override of a series color wins over `up` and `down` here, which are the mode's defaults
2306
+ * for anything the appearance tree does not name. */
2307
+ interface CanvasTheme {
2308
+ background: string;
2309
+ paneBorder: string;
2310
+ grid: string;
2311
+ axisText: string;
2312
+ axisBackground: string;
2313
+ axisBorder: string;
2314
+ crosshair: string;
2315
+ crosshairLabelBackground: string;
2316
+ crosshairLabelText: string;
2317
+ /** The size, in CSS pixels, of text drawn into the canvas. */
2318
+ fontSize: number;
2319
+ fontFamily: string;
2320
+ /** Ink for text the chart paints over the plot area, such as the legend. */
2321
+ textOnCanvas: string;
2322
+ up: string;
2323
+ down: string;
2324
+ neutral: string;
2325
+ session: {
2326
+ preMarket: string;
2327
+ extended: string;
2328
+ afterHours: string;
2329
+ closed: string;
2330
+ };
2331
+ }
2332
+ /** Project a resolved theme onto the canvas renderer's inputs. */
2333
+ declare function canvasTheme(theme: SemanticTheme): CanvasTheme;
2334
+
2335
+ /** The style vocabulary. Fixed at seven; a new one is a public API addition, not a config value. */
2336
+ type ChartStyleId = 'candles' | 'hollow' | 'bars' | 'line' | 'area' | 'baseline' | 'stepline';
2337
+ /** Picker and manifest order. */
2338
+ declare const CHART_STYLES: readonly ChartStyleId[];
2339
+ /** Whether a string names a style. A stored or restored value outside the vocabulary degrades to
2340
+ * candles rather than leaving the chart with no series at all. */
2341
+ declare function isChartStyle(raw: unknown): raw is ChartStyleId;
2342
+ /** Coerce a stored or restored value to a style. */
2343
+ declare function coerceChartStyle(raw: unknown): ChartStyleId;
2344
+ /** Styles whose series consumes `{ time, value }` (close only). The rest consume the whole bar.
2345
+ * Every consumer branches on this ONE predicate: a style is value-shaped or bar-shaped, never a
2346
+ * third thing. A value-shaped style has no open, high or low to show, so the legend drops the
2347
+ * OHLC values while it is on. */
2348
+ declare function valueShaped(style: ChartStyleId): boolean;
2349
+
2350
+ /** The inner markup of each miniature, without its `<svg>` wrapper, keyed by the tool's registry type. */
2351
+ declare const TOOL_ICONS: {
2352
+ trend_line: string;
2353
+ ray: string;
2354
+ info_line: string;
2355
+ extended: string;
2356
+ trend_angle: string;
2357
+ horizontal_line: string;
2358
+ horizontal_ray: string;
2359
+ vertical_line: string;
2360
+ cross_line: string;
2361
+ parallel_channel: string;
2362
+ regression_trend: string;
2363
+ flat_top_bottom: string;
2364
+ disjoint_channel: string;
2365
+ pitchfork: string;
2366
+ schiff_pitchfork: string;
2367
+ schiff_pitchfork_modified: string;
2368
+ inside_pitchfork: string;
2369
+ fib_retracement: string;
2370
+ fib_trend_ext: string;
2371
+ fib_channel: string;
2372
+ fib_timezone: string;
2373
+ fib_speed_resist_fan: string;
2374
+ fib_trend_time: string;
2375
+ fib_circles: string;
2376
+ fib_spiral: string;
2377
+ fib_speed_resist_arcs: string;
2378
+ fib_wedge: string;
2379
+ pitchfan: string;
2380
+ gannbox: string;
2381
+ gannbox_fixed: string;
2382
+ gannbox_square: string;
2383
+ gannbox_fan: string;
2384
+ xabcd_pattern: string;
2385
+ cypher_pattern: string;
2386
+ abcd_pattern: string;
2387
+ triangle_pattern: string;
2388
+ three_drives: string;
2389
+ head_and_shoulders: string;
2390
+ elliott_impulse_wave: string;
2391
+ elliott_correction: string;
2392
+ elliott_triangle_wave: string;
2393
+ elliott_double_combo: string;
2394
+ elliott_triple_combo: string;
2395
+ cyclic_lines: string;
2396
+ time_cycles: string;
2397
+ sine_line: string;
2398
+ long_position: string;
2399
+ short_position: string;
2400
+ forecast: string;
2401
+ bars_pattern: string;
2402
+ ghost_feed: string;
2403
+ sector: string;
2404
+ anchored_vwap: string;
2405
+ fixed_range_volume_profile: string;
2406
+ anchored_volume_profile: string;
2407
+ price_range: string;
2408
+ date_range: string;
2409
+ date_and_price_range: string;
2410
+ brush: string;
2411
+ highlighter: string;
2412
+ arrow_marker: string;
2413
+ arrow: string;
2414
+ arrow_up: string;
2415
+ arrow_down: string;
2416
+ rectangle: string;
2417
+ rotated_rectangle: string;
2418
+ path: string;
2419
+ circle: string;
2420
+ ellipse: string;
2421
+ polyline: string;
2422
+ triangle: string;
2423
+ arc: string;
2424
+ curve: string;
2425
+ double_curve: string;
2426
+ text: string;
2427
+ note: string;
2428
+ price_note: string;
2429
+ table: string;
2430
+ callout: string;
2431
+ comment: string;
2432
+ price_label: string;
2433
+ signpost: string;
2434
+ flag: string;
2435
+ image: string;
2436
+ content_card: string;
2437
+ pin: string;
2438
+ };
2439
+ /** A drawing tool that wears a miniature, by its registry type. */
2440
+ type MiniatureTool = keyof typeof TOOL_ICONS;
2441
+
2442
+ declare const ARRANGEMENT_ICONS: {
2443
+ s: {
2444
+ viewBox: string;
2445
+ body: string;
2446
+ };
2447
+ '2h': {
2448
+ viewBox: string;
2449
+ body: string;
1642
2450
  };
1643
- readonly 'status.durationMinutes': {
1644
- readonly one: "{count} minute";
1645
- readonly other: "{count} minutes";
2451
+ '2v': {
2452
+ viewBox: string;
2453
+ body: string;
1646
2454
  };
1647
- readonly 'status.durationPair': "{major} {minor}";
1648
- readonly 'range.oneDay': "1 Day";
1649
- readonly 'range.fiveDays': "5 Days";
1650
- readonly 'range.oneMonth': "1 Month";
1651
- readonly 'range.threeMonths': "3 Months";
1652
- readonly 'range.sixMonths': "6 Months";
1653
- readonly 'range.yearToDate': "Year to date";
1654
- readonly 'range.oneYear': "1 Year";
1655
- readonly 'range.fiveYears': "5 Years";
1656
- readonly 'range.all': "All data";
1657
- readonly 'range.tip': "{range} · {interval} bars";
1658
- readonly 'range.zoomIn': "Zoom in";
1659
- readonly 'range.zoomOut': "Zoom out";
1660
- readonly 'range.scrollLeft': "Scroll left";
1661
- readonly 'range.scrollRight': "Scroll right";
1662
- readonly 'range.reset': "Reset chart view";
1663
- readonly 'range.maximizeChart': "Maximize chart";
1664
- readonly 'range.restoreChart': "Restore chart";
1665
- readonly 'timezone.title': "Chart timezone";
1666
- readonly 'timezone.exchange': "Exchange";
1667
- readonly 'timeframe.title': "Timeframe";
1668
- readonly 'timeframe.all': "All timeframes";
1669
- readonly 'timeframe.unitTicks': "Ticks";
1670
- readonly 'timeframe.unitSeconds': "Seconds";
1671
- readonly 'timeframe.unitMinutes': "Minutes";
1672
- readonly 'timeframe.unitHours': "Hours";
1673
- readonly 'timeframe.unitDays': "Days";
1674
- readonly 'timeframe.unitWeeks': "Weeks";
1675
- readonly 'timeframe.unitMonths': "Months";
1676
- readonly 'timeframe.countTicks': {
1677
- readonly one: "{count} Tick";
1678
- readonly other: "{count} Ticks";
2455
+ '3h': {
2456
+ viewBox: string;
2457
+ body: string;
1679
2458
  };
1680
- readonly 'timeframe.countSeconds': {
1681
- readonly one: "{count} Second";
1682
- readonly other: "{count} Seconds";
2459
+ '3v': {
2460
+ viewBox: string;
2461
+ body: string;
2462
+ };
2463
+ '3s': {
2464
+ viewBox: string;
2465
+ body: string;
2466
+ };
2467
+ '3r': {
2468
+ viewBox: string;
2469
+ body: string;
2470
+ };
2471
+ '2-1': {
2472
+ viewBox: string;
2473
+ body: string;
2474
+ };
2475
+ '1-2': {
2476
+ viewBox: string;
2477
+ body: string;
2478
+ };
2479
+ '4': {
2480
+ viewBox: string;
2481
+ body: string;
2482
+ };
2483
+ '4v': {
2484
+ viewBox: string;
2485
+ body: string;
2486
+ };
2487
+ '4h': {
2488
+ viewBox: string;
2489
+ body: string;
2490
+ };
2491
+ '4s': {
2492
+ viewBox: string;
2493
+ body: string;
2494
+ };
2495
+ '4s-l': {
2496
+ viewBox: string;
2497
+ body: string;
2498
+ };
2499
+ '1-3': {
2500
+ viewBox: string;
2501
+ body: string;
2502
+ };
2503
+ '3-1': {
2504
+ viewBox: string;
2505
+ body: string;
2506
+ };
2507
+ '2-2-l': {
2508
+ viewBox: string;
2509
+ body: string;
2510
+ };
2511
+ '2-2-r': {
2512
+ viewBox: string;
2513
+ body: string;
2514
+ };
2515
+ '2-2': {
2516
+ viewBox: string;
2517
+ body: string;
2518
+ };
2519
+ '1-4': {
2520
+ viewBox: string;
2521
+ body: string;
2522
+ };
2523
+ '5h': {
2524
+ viewBox: string;
2525
+ body: string;
2526
+ };
2527
+ '5v': {
2528
+ viewBox: string;
2529
+ body: string;
2530
+ };
2531
+ '5s': {
2532
+ viewBox: string;
2533
+ body: string;
2534
+ };
2535
+ '5s-l': {
2536
+ viewBox: string;
2537
+ body: string;
2538
+ };
2539
+ '2-3': {
2540
+ viewBox: string;
2541
+ body: string;
2542
+ };
2543
+ '3-2': {
2544
+ viewBox: string;
2545
+ body: string;
2546
+ };
2547
+ '4-1': {
2548
+ viewBox: string;
2549
+ body: string;
2550
+ };
2551
+ '2-3-l': {
2552
+ viewBox: string;
2553
+ body: string;
2554
+ };
2555
+ '2-3-r': {
2556
+ viewBox: string;
2557
+ body: string;
2558
+ };
2559
+ '6': {
2560
+ viewBox: string;
2561
+ body: string;
2562
+ };
2563
+ '6h': {
2564
+ viewBox: string;
2565
+ body: string;
2566
+ };
2567
+ '6v': {
2568
+ viewBox: string;
2569
+ body: string;
2570
+ };
2571
+ '6c': {
2572
+ viewBox: string;
2573
+ body: string;
2574
+ };
2575
+ '2-4': {
2576
+ viewBox: string;
2577
+ body: string;
2578
+ };
2579
+ '4-2': {
2580
+ viewBox: string;
2581
+ body: string;
2582
+ };
2583
+ '4-3': {
2584
+ viewBox: string;
2585
+ body: string;
2586
+ };
2587
+ '7h': {
2588
+ viewBox: string;
2589
+ body: string;
2590
+ };
2591
+ '7s': {
2592
+ viewBox: string;
2593
+ body: string;
1683
2594
  };
1684
- readonly 'timeframe.countMinutes': {
1685
- readonly one: "{count} Minute";
1686
- readonly other: "{count} Minutes";
2595
+ '8': {
2596
+ viewBox: string;
2597
+ body: string;
1687
2598
  };
1688
- readonly 'timeframe.countHours': {
1689
- readonly one: "{count} Hour";
1690
- readonly other: "{count} Hours";
2599
+ '8c': {
2600
+ viewBox: string;
2601
+ body: string;
1691
2602
  };
1692
- readonly 'timeframe.countDays': {
1693
- readonly one: "{count} Day";
1694
- readonly other: "{count} Days";
2603
+ '8h': {
2604
+ viewBox: string;
2605
+ body: string;
1695
2606
  };
1696
- readonly 'timeframe.countWeeks': {
1697
- readonly one: "{count} Week";
1698
- readonly other: "{count} Weeks";
2607
+ '8v': {
2608
+ viewBox: string;
2609
+ body: string;
1699
2610
  };
1700
- readonly 'timeframe.countMonths': {
1701
- readonly one: "{count} Month";
1702
- readonly other: "{count} Months";
2611
+ '9s': {
2612
+ viewBox: string;
2613
+ body: string;
1703
2614
  };
1704
- readonly 'timeframe.delete': "Delete {timeframe}";
1705
- readonly 'timeframe.save': "Save {timeframe}";
1706
- readonly 'timeframe.exists': "{timeframe} already exists";
1707
- readonly 'timeframe.custom': "Custom timeframe";
1708
- readonly 'timeframe.customCount': "Custom timeframe count";
1709
- readonly 'timeframe.customUnit': "Custom timeframe unit";
1710
- readonly 'timeframe.addCustom': "Add custom timeframe";
1711
- readonly 'timeframe.increment': "Increment";
1712
- readonly 'timeframe.decrement': "Decrement";
1713
- readonly 'indicator.smaName': "Simple Moving Average";
1714
- readonly 'indicator.smaDescription': "Smoothed average over a fixed window";
1715
- readonly 'indicator.emaName': "Exponential Moving Average";
1716
- readonly 'indicator.emaDescription': "Recency-weighted moving average";
1717
- readonly 'indicator.hmaName': "Hull Moving Average";
1718
- readonly 'indicator.hmaDescription': "Low-lag weighted moving average";
1719
- readonly 'indicator.vwmaName': "Volume Weighted MA";
1720
- readonly 'indicator.vwmaDescription': "Moving average weighted by volume";
1721
- readonly 'indicator.bollingerName': "Bollinger Bands";
1722
- readonly 'indicator.bollingerDescription': "SMA envelope at two standard deviations";
1723
- readonly 'indicator.donchianName': "Donchian Channels";
1724
- readonly 'indicator.donchianDescription': "Rolling highest-high and lowest-low channel";
1725
- readonly 'indicator.keltnerName': "Keltner Channels";
1726
- readonly 'indicator.keltnerDescription': "EMA midline with ATR-scaled bands";
1727
- readonly 'indicator.supertrendName': "Supertrend";
1728
- readonly 'indicator.supertrendDescription': "ATR trend band that flips with direction";
1729
- readonly 'indicator.psarName': "Parabolic SAR";
1730
- readonly 'indicator.psarDescription': "Stop-and-reverse trailing dots";
1731
- readonly 'indicator.rsiName': "Relative Strength Index";
1732
- readonly 'indicator.rsiDescription': "Momentum oscillator from 0 to 100";
1733
- readonly 'indicator.macdName': "MACD";
1734
- readonly 'indicator.macdDescription': "Moving Average Convergence Divergence";
1735
- readonly 'indicator.stochasticName': "Stochastic Oscillator";
1736
- readonly 'indicator.stochasticDescription': "%K and %D momentum from 0 to 100";
1737
- readonly 'indicator.stochrsiName': "Stochastic RSI";
1738
- readonly 'indicator.stochrsiDescription': "Stochastic applied to the RSI series";
1739
- readonly 'indicator.adxName': "Average Directional Index";
1740
- readonly 'indicator.adxDescription': "Trend strength with +DI and -DI";
1741
- readonly 'indicator.atrName': "Average True Range";
1742
- readonly 'indicator.atrDescription': "Volatility: Wilder's true-range average";
1743
- readonly 'indicator.cciName': "Commodity Channel Index";
1744
- readonly 'indicator.cciDescription': "Deviation from the typical-price average";
1745
- readonly 'indicator.williamsName': "Williams %R";
1746
- readonly 'indicator.williamsDescription': "Overbought and oversold momentum from -100 to 0";
1747
- readonly 'indicator.rocName': "Rate of Change";
1748
- readonly 'indicator.rocDescription': "Percent change over the period";
1749
- readonly 'indicator.momentumName': "Momentum";
1750
- readonly 'indicator.momentumDescription': "Price difference over the period";
1751
- readonly 'indicator.volumeName': "Volume";
1752
- readonly 'indicator.volumeDescription': "Per-bar traded volume histogram";
1753
- readonly 'indicator.vwapName': "Volume Weighted Avg Price";
1754
- readonly 'indicator.vwapDescription': "Cumulative volume-weighted average price";
1755
- readonly 'indicator.obvName': "On-Balance Volume";
1756
- readonly 'indicator.obvDescription': "Cumulative volume by close direction";
1757
- readonly 'indicator.mfiName': "Money Flow Index";
1758
- readonly 'indicator.mfiDescription': "Volume-weighted RSI from 0 to 100";
1759
- readonly 'host.noVolume': "No volume from this feed";
1760
- readonly 'host.saveConflict': "Saved elsewhere since you opened it. Load the newer version before saving.";
1761
- readonly 'host.saveNotFound': "This was deleted elsewhere. Save it again as new.";
1762
- readonly 'host.loadInvalid': "This could not be opened. Nothing on screen changed.";
1763
- readonly 'host.loadUnavailable': "Your saved work could not be reached. Nothing on screen changed.";
1764
- readonly 'host.loadNotRestored': "This could not be opened, and what was on screen could not be put back. The chart is not saving until you open a saved chart or layout. Save a copy first to keep what is on screen.";
1765
- readonly 'host.notSaving': "The chart is not saving. Open a saved chart or layout to start from a known state. Saving a copy keeps what is on screen, but the chart still will not save.";
1766
- readonly 'layout.s': "Single chart";
1767
- readonly 'layout.2h': "2 columns";
1768
- readonly 'layout.2v': "2 rows";
1769
- readonly 'layout.3h': "3 columns";
1770
- readonly 'layout.3v': "3 rows";
1771
- readonly 'layout.3s': "Large left, 2 stacked right";
1772
- readonly 'layout.3r': "2 stacked left, large right";
1773
- readonly 'layout.2_1': "2 above, 1 below";
1774
- readonly 'layout.1_2': "1 above, 2 below";
1775
- readonly 'layout.4': "2 × 2 grid";
1776
- readonly 'layout.4v': "4 rows";
1777
- readonly 'layout.4h': "4 columns";
1778
- readonly 'layout.4s': "Large left, 3 stacked right";
1779
- readonly 'layout.4s_l': "3 stacked left, large right";
1780
- readonly 'layout.1_3': "1 above, 3 below";
1781
- readonly 'layout.3_1': "3 above, 1 below";
1782
- readonly 'layout.2_2_l': "2 columns, 2 stacked right";
1783
- readonly 'layout.2_2_r': "2 stacked left, 2 columns";
1784
- readonly 'layout.2_2': "2 above, 2 full-width rows below";
1785
- readonly 'layout.1_4': "1 above, 4 below";
1786
- readonly 'layout.5h': "5 columns";
1787
- readonly 'layout.5v': "5 rows";
1788
- readonly 'layout.5s': "Large left, 4 stacked right";
1789
- readonly 'layout.5s_l': "4 stacked left, large right";
1790
- readonly 'layout.2_3': "2 above, 3 below";
1791
- readonly 'layout.3_2': "3 above, 2 below";
1792
- readonly 'layout.4_1': "4 above, 1 below";
1793
- readonly 'layout.2_3_l': "2 columns, 3 stacked right";
1794
- readonly 'layout.2_3_r': "3 stacked left, 2 columns";
1795
- readonly 'layout.6': "3 × 2 grid";
1796
- readonly 'layout.6h': "6 columns";
1797
- readonly 'layout.6v': "6 rows";
1798
- readonly 'layout.6c': "2 × 3 grid";
1799
- readonly 'layout.2_4': "2 above, 4 below";
1800
- readonly 'layout.4_2': "4 above, 2 below";
1801
- readonly 'layout.4_3': "4 above, 3 below";
1802
- readonly 'layout.7h': "7 columns";
1803
- readonly 'layout.7s': "Large left, 6 stacked right";
1804
- readonly 'layout.8': "4 × 2 grid";
1805
- readonly 'layout.8c': "2 × 4 grid";
1806
- readonly 'layout.8h': "8 columns";
1807
- readonly 'layout.8v': "8 rows";
1808
- readonly 'layout.9s': "3 × 3 grid";
1809
- readonly 'layout.5_4': "5 above, 4 below";
1810
- readonly 'layout.9h': "9 columns";
1811
- readonly 'layout.9v': "9 rows";
1812
- readonly 'layout.10c5': "5 × 2 grid";
1813
- readonly 'layout.10h': "10 columns";
1814
- readonly 'layout.10v': "10 rows";
1815
- readonly 'layout.12c6': "6 × 2 grid";
1816
- readonly 'layout.12c4': "4 × 3 grid";
1817
- readonly 'layout.12h': "12 columns";
1818
- readonly 'layout.14c7': "7 × 2 grid";
1819
- readonly 'layout.16c8': "8 × 2 grid";
1820
- readonly 'layout.16c4': "4 × 4 grid";
1821
- readonly 'layouts.setup': "Layout setup";
1822
- readonly 'layouts.arrangement': "Chart arrangement";
1823
- readonly 'layouts.syncInLayout': "Sync in layout";
1824
- readonly 'layouts.syncSymbol': "Symbol";
1825
- readonly 'layouts.syncInterval': "Interval";
1826
- readonly 'layouts.syncCrosshair': "Crosshair";
1827
- readonly 'layouts.syncTime': "Time";
1828
- readonly 'layouts.syncDateRange': "Date range";
1829
- readonly 'layouts.syncSymbolTip': "Symbol changes on all charts within the layout";
1830
- readonly 'layouts.syncIntervalTip': "Interval changes on all charts within the layout";
1831
- readonly 'layouts.syncCrosshairTip': "Crosshair is synced across all charts within the layout";
1832
- readonly 'layouts.syncTimeTip': "When a chart is clicked, all charts within the layout display the same point of time";
1833
- readonly 'layouts.syncDateRangeTip': "Date range changes on all charts within the layout";
1834
- readonly 'layouts.syncSymbolToggle': "Sync symbol";
1835
- readonly 'layouts.syncIntervalToggle': "Sync interval";
1836
- readonly 'layouts.syncCrosshairToggle': "Sync crosshair";
1837
- readonly 'layouts.syncTimeToggle': "Sync time";
1838
- readonly 'layouts.syncDateRangeToggle': "Sync date range";
1839
- readonly 'layouts.unnamed': "Unnamed";
1840
- readonly 'layouts.unsavedChanges': "Unsaved changes";
1841
- readonly 'layouts.allSaved': "All changes saved";
1842
- readonly 'layouts.notSaving': "Not saving until this is restored";
1843
- readonly 'layouts.manage': "Manage layouts";
1844
- readonly 'layouts.saveLayout': "Save layout";
1845
- readonly 'layouts.hintSave': "{modifier} + S";
1846
- readonly 'layouts.hintOpen': "Dot";
1847
- readonly 'layouts.save': "Save";
1848
- readonly 'layouts.autosave': "Autosave";
1849
- readonly 'layouts.rename': "Rename";
1850
- readonly 'layouts.copyOfName': "{name} copy";
1851
- readonly 'layouts.saveNewTitle': "Save New Chart Layout";
1852
- readonly 'layouts.saveNewLabel': "Enter a new chart layout name:";
1853
- readonly 'layouts.copyTitle': "Make copy of chart layout";
1854
- readonly 'layouts.renameTitle': "Rename chart layout";
1855
- readonly 'layouts.createTitle': "Create layout";
1856
- readonly 'layouts.newLayoutName': "New layout name";
1857
- readonly 'layouts.createPlaceholder': "My layout";
1858
- readonly 'layouts.create': "Create";
1859
- readonly 'layouts.makeCopyRow': "Make a copy…";
1860
- readonly 'layouts.renameRow': "Rename…";
1861
- readonly 'layouts.downloadDataRow': "Download chart data";
1862
- readonly 'layouts.createNewRow': "Create new layout…";
1863
- readonly 'layouts.recentlyUsed': "Recently used";
1864
- readonly 'layouts.loading': "Loading";
1865
- readonly 'layouts.emptyNone': "No saved layouts yet.";
1866
- readonly 'layouts.openLayoutRow': "Open layout…";
1867
- readonly 'layouts.listingFacts': "{symbol}, {interval}";
1868
- readonly 'layouts.listingDated': "{facts} ({date})";
1869
- readonly 'layouts.dialogTitle': "Layouts";
1870
- readonly 'layouts.search': "Search";
1871
- readonly 'layouts.columnName': "Layout name";
1872
- readonly 'layouts.sortBy': "Sort by layout name, date changed";
1873
- readonly 'layouts.sortNameAsc': "Layout name (A to Z)";
1874
- readonly 'layouts.sortNameDesc': "Layout name (Z to A)";
1875
- readonly 'layouts.sortModifiedAsc': "Date modified (oldest first)";
1876
- readonly 'layouts.sortModifiedDesc': "Date modified (newest first)";
1877
- readonly 'layouts.favorite': "Add to favorites";
1878
- readonly 'layouts.unfavorite': "Remove from favorites";
1879
- readonly 'layouts.noMatches': "Nothing matches.";
1880
- readonly 'layouts.delete': "Delete";
1881
- readonly 'layouts.deleteNamed': "Delete {name}";
1882
- readonly 'layouts.deleteConfirm': "Delete this chart layout?";
1883
- readonly 'layouts.deleteConfirmBody': "Doing this will permanently delete your \"{name}\" layout.";
1884
- readonly 'layouts.cancel': "Cancel";
1885
- readonly 'layouts.close': "Close";
1886
- readonly 'layouts.errList': "Could not load your saved layouts.";
1887
- readonly 'session.pre': "Pre-market";
1888
- readonly 'session.open': "Market open";
1889
- readonly 'session.extended': "Extended hours";
1890
- readonly 'session.after': "After-hours";
1891
- readonly 'session.closed': "Market closed";
1892
- readonly 'inputs.cancel': "Cancel";
1893
- readonly 'inputs.apply': "Apply";
1894
- readonly 'replay.watermark': "Replay";
1895
- readonly 'replay.selectBar': "Select bar";
1896
- readonly 'replay.selectDate': "Select date";
1897
- readonly 'replay.selectStartingPoint': "Select starting point";
1898
- readonly 'replay.startBar': "Bar";
1899
- readonly 'replay.startDate': "Date…";
1900
- readonly 'replay.startFirst': "First available date";
1901
- readonly 'replay.startRandom': "Random bar";
1902
- readonly 'replay.startDateField': "Replay start date";
1903
- readonly 'replay.startTimeField': "Replay start time (UTC, optional)";
1904
- readonly 'replay.dateMask': "YYYY-MM-DD";
1905
- readonly 'replay.timeMask': "HH:MM";
1906
- readonly 'replay.previousMonth': "Previous month";
1907
- readonly 'replay.nextMonth': "Next month";
1908
- readonly 'replay.cancel': "Cancel";
1909
- readonly 'replay.select': "Select";
1910
- readonly 'replay.weekdayMon': "Mo";
1911
- readonly 'replay.weekdayTue': "Tu";
1912
- readonly 'replay.weekdayWed': "We";
1913
- readonly 'replay.weekdayThu': "Th";
1914
- readonly 'replay.weekdayFri': "Fr";
1915
- readonly 'replay.weekdaySat': "Sa";
1916
- readonly 'replay.weekdaySun': "Su";
1917
- readonly 'replay.stepBack': "Step back one bar";
1918
- readonly 'replay.play': "Play";
1919
- readonly 'replay.pause': "Pause";
1920
- readonly 'replay.stepForward': "Step forward one bar";
1921
- readonly 'replay.goLiveTitle': "Jump to the live edge";
1922
- readonly 'replay.exit': "Exit replay";
1923
- readonly 'replay.speed': "Replay speed";
1924
- readonly 'replay.updatesPerSecond': {
1925
- readonly one: "{count} update per second";
1926
- readonly other: "{count} updates per second";
2615
+ '5-4': {
2616
+ viewBox: string;
2617
+ body: string;
1927
2618
  };
1928
- readonly 'replay.oneUpdatePerSeconds': {
1929
- readonly one: "1 update per {count} second";
1930
- readonly other: "1 update per {count} seconds";
2619
+ '9h': {
2620
+ viewBox: string;
2621
+ body: string;
1931
2622
  };
1932
- readonly 'replay.interval': "Update interval";
1933
- readonly 'replay.intervalHelp': "How much time each replay update advances. Finer than the chart interval, each bar forms from real finer bars.";
1934
- readonly 'replay.intervalNone': "No finer interval for this chart interval";
1935
- readonly 'replay.auto': "Auto";
1936
- readonly 'replay.autoSelectInterval': "Auto select interval";
1937
- readonly 'menu.resetView': "Reset chart view";
1938
- readonly 'menu.copyPrice': "Copy price {price}";
1939
- readonly 'menu.paste': "Paste";
1940
- readonly 'menu.removeIndicators': {
1941
- readonly one: "Remove {count} indicator";
1942
- readonly other: "Remove {count} indicators";
2623
+ '9v': {
2624
+ viewBox: string;
2625
+ body: string;
1943
2626
  };
1944
- readonly 'menu.removeDrawings': {
1945
- readonly one: "Remove {count} drawing";
1946
- readonly other: "Remove {count} drawings";
2627
+ '10c5': {
2628
+ viewBox: string;
2629
+ body: string;
1947
2630
  };
1948
- readonly 'menu.settings': "Settings…";
1949
- readonly 'tool.trend_line': "Trend line";
1950
- readonly 'tool.ray': "Ray";
1951
- readonly 'tool.info_line': "Info line";
1952
- readonly 'tool.extended': "Extended line";
1953
- readonly 'tool.trend_angle': "Trend angle";
1954
- readonly 'tool.horizontal_line': "Horizontal line";
1955
- readonly 'tool.horizontal_ray': "Horizontal ray";
1956
- readonly 'tool.vertical_line': "Vertical line";
1957
- readonly 'tool.cross_line': "Cross line";
1958
- readonly 'tool.arrow': "Arrow";
1959
- readonly 'tool.rectangle': "Rectangle";
1960
- readonly 'tool.rotated_rectangle': "Rotated rectangle";
1961
- readonly 'tool.ellipse': "Ellipse";
1962
- readonly 'tool.circle': "Circle";
1963
- readonly 'tool.triangle': "Triangle";
1964
- readonly 'tool.arc': "Arc";
1965
- readonly 'tool.curve': "Curve";
1966
- readonly 'tool.double_curve': "Double curve";
1967
- readonly 'tool.regression_trend': "Regression trend";
1968
- readonly 'tool.parallel_channel': "Parallel channel";
1969
- readonly 'tool.flat_top_bottom': "Flat top/bottom";
1970
- readonly 'tool.disjoint_channel': "Disjoint channel";
1971
- readonly 'tool.fib_retracement': "Fib retracement";
1972
- readonly 'tool.fib_trend_ext': "Trend-based fib extension";
1973
- readonly 'tool.fib_channel': "Fib channel";
1974
- readonly 'tool.fib_timezone': "Fib time zone";
1975
- readonly 'tool.fib_speed_resist_fan': "Fib speed resistance fan";
1976
- readonly 'tool.fib_trend_time': "Trend-based fib time";
1977
- readonly 'tool.fib_circles': "Fib circles";
1978
- readonly 'tool.fib_spiral': "Fib spiral";
1979
- readonly 'tool.fib_speed_resist_arcs': "Fib speed resistance arcs";
1980
- readonly 'tool.fib_wedge': "Fib wedge";
1981
- readonly 'tool.pitchfan': "Pitchfan";
1982
- readonly 'tool.pitchfork': "Pitchfork";
1983
- readonly 'tool.schiff_pitchfork': "Schiff pitchfork";
1984
- readonly 'tool.schiff_pitchfork_modified': "Modified Schiff pitchfork";
1985
- readonly 'tool.inside_pitchfork': "Inside pitchfork";
1986
- readonly 'tool.gannbox': "Gann box";
1987
- readonly 'tool.gannbox_square': "Gann square";
1988
- readonly 'tool.gannbox_fixed': "Gann square fixed";
1989
- readonly 'tool.gannbox_fan': "Gann fan";
1990
- readonly 'tool.xabcd_pattern': "XABCD pattern";
1991
- readonly 'tool.cypher_pattern': "Cypher pattern";
1992
- readonly 'tool.abcd_pattern': "ABCD pattern";
1993
- readonly 'tool.three_drives': "Three drives pattern";
1994
- readonly 'tool.triangle_pattern': "Triangle pattern";
1995
- readonly 'tool.head_and_shoulders': "Head and shoulders";
1996
- readonly 'tool.elliott_impulse_wave': "Elliott impulse (12345)";
1997
- readonly 'tool.elliott_correction': "Elliott correction (ABC)";
1998
- readonly 'tool.elliott_triangle_wave': "Elliott triangle (ABCDE)";
1999
- readonly 'tool.elliott_double_combo': "Elliott double combo (WXY)";
2000
- readonly 'tool.elliott_triple_combo': "Elliott triple combo (WXYXZ)";
2001
- readonly 'tool.cyclic_lines': "Cyclic lines";
2002
- readonly 'tool.time_cycles': "Time cycles";
2003
- readonly 'tool.sine_line': "Sine line";
2004
- readonly 'tool.long_position': "Long position";
2005
- readonly 'tool.short_position': "Short position";
2006
- readonly 'tool.forecast': "Position forecast";
2007
- readonly 'tool.sector': "Sector";
2008
- readonly 'tool.bars_pattern': "Bars pattern";
2009
- readonly 'tool.ghost_feed': "Ghost feed";
2010
- readonly 'tool.anchored_vwap': "Anchored VWAP";
2011
- readonly 'tool.fixed_range_volume_profile': "Fixed range volume profile";
2012
- readonly 'tool.anchored_volume_profile': "Anchored volume profile";
2013
- readonly 'tool.image': "Image";
2014
- readonly 'tool.content_card': "Content card";
2015
- readonly 'tool.emoji': "Emoji";
2016
- readonly 'tool.sticker': "Sticker";
2017
- readonly 'tool.icon': "Icon";
2018
- readonly 'tool.text': "Text";
2019
- readonly 'tool.note': "Note";
2020
- readonly 'tool.comment': "Comment";
2021
- readonly 'tool.callout': "Callout";
2022
- readonly 'tool.price_label': "Price label";
2023
- readonly 'tool.arrow_up': "Arrow mark up";
2024
- readonly 'tool.arrow_down': "Arrow mark down";
2025
- readonly 'tool.arrow_marker': "Arrow marker";
2026
- readonly 'tool.flag': "Flag mark";
2027
- readonly 'tool.price_note': "Price note";
2028
- readonly 'tool.pin': "Pin";
2029
- readonly 'tool.signpost': "Signpost";
2030
- readonly 'tool.table': "Table";
2031
- readonly 'tool.brush': "Brush";
2032
- readonly 'tool.highlighter': "Highlighter";
2033
- readonly 'tool.path': "Path";
2034
- readonly 'tool.polyline': "Polyline";
2035
- readonly 'tool.price_range': "Price range";
2036
- readonly 'tool.date_range': "Date range";
2037
- readonly 'tool.date_and_price_range': "Date and price range";
2038
- readonly 'tool.measure': "Measure";
2039
- readonly 'legend.open': "O";
2040
- readonly 'legend.high': "H";
2041
- readonly 'legend.low': "L";
2042
- readonly 'legend.close': "C";
2043
- readonly 'legend.change': "{change} ({percent}%)";
2044
- readonly 'legend.indicatorSettings': "Indicator settings";
2045
- readonly 'legend.showRows': "Show study rows";
2046
- readonly 'legend.hideRows': "Hide study rows";
2047
- readonly 'legend.restorePane': "Restore pane";
2048
- readonly 'legend.collapsePane': "Collapse pane";
2049
- readonly 'legend.maximizePane': "Maximize pane";
2050
- readonly 'legend.showIndicator': "Show indicator";
2051
- readonly 'legend.hideIndicator': "Hide indicator";
2052
- readonly 'legend.scaleNormal': "Reg";
2053
- readonly 'legend.scaleLog': "Log";
2054
- readonly 'legend.scalePercent': "%";
2055
- readonly 'legend.scaleIndexed': "100";
2056
- readonly 'legend.changeSymbol': "Change symbol";
2057
- readonly 'legend.removeCompare': "Remove compare";
2058
- readonly 'legend.removeIndicator': "Remove indicator";
2059
- }, ChartLocaleCode>;
2060
- /** A drawing tool's display name for a registry `type`: the catalog's when it knows the type, else
2061
- * the registry's own English `name`, so a tool the catalog has not met still has a name. */
2062
- declare function toolName(t: ChartTranslate, type: string, fallback: string): string;
2063
- /** A multi-chart arrangement's display name for its code, else the arrangement catalog's English
2064
- * label. An arrangement code separates its parts with hyphens (`2-2-l`) where a catalog key uses
2065
- * underscores, so the code is converted rather than asking every caller to. */
2066
- declare function arrangementName(t: ChartTranslate, code: string, fallback: string): string;
2067
- /** A `ChartI18n` over the widget's own catalog, starting in `initial` (English when omitted): one
2068
- * of the built-in codes, or a code the `locales` option registers. */
2069
- declare function createChartI18n(initial?: string, options?: ChartI18nOptions): ChartI18n;
2070
-
2071
- interface ChartOverrides {
2072
- appearance: {
2073
- background: string;
2074
- upColor: string;
2075
- downColor: string;
2076
- /** Candle anatomy: the border ring and the wick are their OWN colors per direction. They do
2077
- * NOT follow upColor/downColor; each is set independently. */
2078
- borderUpColor: string;
2079
- borderDownColor: string;
2080
- wickUpColor: string;
2081
- wickDownColor: string;
2082
- grid: boolean;
2083
- /** Shade pre-market / after-hours / overnight stretches. */
2084
- sessions: boolean;
2085
- /** Bar-close countdown pill on the price scale. */
2086
- countdown: boolean;
2631
+ '10h': {
2632
+ viewBox: string;
2633
+ body: string;
2634
+ };
2635
+ '10v': {
2636
+ viewBox: string;
2637
+ body: string;
2638
+ };
2639
+ '12c6': {
2640
+ viewBox: string;
2641
+ body: string;
2642
+ };
2643
+ '12c4': {
2644
+ viewBox: string;
2645
+ body: string;
2646
+ };
2647
+ '12h': {
2648
+ viewBox: string;
2649
+ body: string;
2650
+ };
2651
+ '14c7': {
2652
+ viewBox: string;
2653
+ body: string;
2654
+ };
2655
+ '16c8': {
2656
+ viewBox: string;
2657
+ body: string;
2658
+ };
2659
+ '16c4': {
2660
+ viewBox: string;
2661
+ body: string;
2087
2662
  };
2088
- }
2089
- /** The brand palette, single-sourced: any surface that speaks for trdrs reads these (the trading
2090
- * extension's buy line among them), and a rebrand edits two strings. The pair does not reach the
2091
- * candle bodies; see the note on DEFAULT_OVERRIDES for why. */
2092
- declare const BRAND_UP = "#4c98fb";
2093
- declare const BRAND_DOWN = "#f23645";
2094
- declare const DEFAULT_OVERRIDES: ChartOverrides;
2095
- /** A recursive partial of the tree — what a host supplies. */
2096
- type PartialOverrides = {
2097
- [S in keyof ChartOverrides]?: Partial<ChartOverrides[S]>;
2098
2663
  };
2099
- /** Deep-fill a partial over the defaults. One level of nesting by design — the tree is two levels
2100
- * (section → leaf) and stays that way; new leaves are additive. */
2101
- declare function mergeOverrides(partial?: PartialOverrides | null): ChartOverrides;
2102
- /** The precedence composer: deep-fill any number of partials over an explicit BASE, later layers
2103
- * winning leaf by leaf. The widget's look resolves through this — its theme-derived floor, then
2104
- * the host's constructor partial, then runtime applyAppearance calls: one ladder where runtime
2105
- * beats constructor beats theme, expressed as one pure function. */
2106
- declare function layerOverrides(base: ChartOverrides, ...partials: (PartialOverrides | null | undefined)[]): ChartOverrides;
2664
+ /** A layout arrangement that wears a glyph, by its code. */
2665
+ type ArrangementGlyphCode = keyof typeof ARRANGEMENT_ICONS;
2666
+
2667
+ /** Where one glyph will stand. */
2668
+ interface ChartIconContext {
2669
+ /** The document the glyph is drawn into. Create its nodes with this one, never a global. */
2670
+ readonly document: Document;
2671
+ /** The box the glyph fills, in CSS pixels. The chart sizes the answered element to it, so a
2672
+ * factory draws on whatever grid its viewBox names. */
2673
+ readonly width: number;
2674
+ readonly height: number;
2675
+ /** The reading direction of the control the glyph stands in. When a language turns the widget's
2676
+ * direction around, the chart asks the factory again for every glyph it drew and puts the new
2677
+ * drawing in place of the old; an answer it refuses leaves the old drawing standing. A glyph the
2678
+ * chart mirrors for a right-to-left language is mirrored whatever artwork it wears, so a factory
2679
+ * always draws the left-to-right form of those; `direction` is for artwork that differs otherwise. */
2680
+ readonly direction: 'ltr' | 'rtl';
2681
+ }
2682
+ /** Draws one glyph: a fresh `<svg>` element, never one it answered before or one already in the
2683
+ * document. `currentColor` takes the control's own ink in every theme and state. */
2684
+ type ChartIconFactory = (context: ChartIconContext) => SVGSVGElement;
2685
+ /** Why a host's glyph was not drawn. */
2686
+ type ChartIconFailure = 'threw' | 'not-svg' | 'in-use';
2687
+ /** One glyph the chart could not draw from a host's factory. The control fell back to the chart's
2688
+ * own glyph, or to none where the control is the host's. Each icon reports its first failure. */
2689
+ interface ChartIconDiagnostic {
2690
+ /** The icon: a published icon id, or `toolbarButton` for the glyph of a host's own control. */
2691
+ icon: string;
2692
+ code: ChartIconFailure;
2693
+ message: string;
2694
+ }
2695
+
2696
+ /** The glyphs of the chart's own controls, by meaning, each with every drawing that carries it. */
2697
+ declare const CONTROL_ICONS: Readonly<Record<"info" | "search" | "indicators" | "visible" | "textColor" | "lineColor" | "open" | "close" | "template" | "fillColor" | "locked" | "sync" | "measure" | "image" | "eraser" | "delete" | "remove" | "copy" | "pause" | "play" | "reset" | "scroll" | "hidden" | "add" | "magnet" | "compare" | "replay" | "settings" | "fullscreen" | "marketStatus" | "paneCollapse" | "paneRestore" | "paneMaximize" | "replayStatus" | "replayMark" | "replayCut" | "undo" | "redo" | "tileMaximize" | "tileRestore" | "download" | "chevronDown" | "chevronUp" | "chevronLeft" | "chevronRight" | "check" | "clear" | "goLive" | "stepForward" | "stepBack" | "selectBar" | "firstAvailable" | "randomBar" | "cursorCross" | "cursorDot" | "cursorArrow" | "magnetStrong" | "drawingsShown" | "drawingsHidden" | "indicatorsShown" | "indicatorsHidden" | "allShown" | "allHidden" | "zoomIn" | "grip" | "favoritesBar" | "lineSolid" | "lineDashed" | "lineDotted" | "lineThickness1" | "lineThickness2" | "lineThickness3" | "lineThickness4" | "lineEndNormal" | "lineEndArrow" | "fullscreenExit" | "caret" | "collapse" | "zoomOut" | "rename" | "duplicate" | "favorite" | "favorited" | "sortAscending" | "sortDescending" | "flyout" | "submenu" | "more" | "emptySearch" | "emptyCompare" | "operatorsShow" | "operatorsHide" | "operatorAdd" | "operatorSubtract" | "operatorMultiply" | "operatorDivide" | "operatorPower" | "operatorReciprocal" | "selectDate" | "zoomTool" | "stayInMode" | "stayInModeOn" | "unlocked" | "hide" | "glyphTools" | "visualOrder", readonly Glyph[]>>;
2698
+ /** An icon of one of the chart's own controls. */
2699
+ type ControlIconId = keyof typeof CONTROL_ICONS;
2700
+ /** Every icon a host may draw: a control's glyph by its meaning, a chart style by its id, a drawing
2701
+ * tool by its registry type, and a layout arrangement by its code. Exactly the ids in
2702
+ * `CHART_ICON_IDS`, so an id the chart does not draw is a type error before it is a refusal. */
2703
+ type ChartIconId = ControlIconId | `style.${ChartStyleId}` | `tool.${MiniatureTool}` | `layout.${ArrangementGlyphCode}`;
2704
+ /** A host's drawings for the chart's icons, by id. An icon left out keeps the chart's own. */
2705
+ type ChartIcons = {
2706
+ readonly [K in ChartIconId]?: ChartIconFactory;
2707
+ };
2708
+ /** The glyphs the chart mirrors for a right-to-left language, whatever artwork they wear: a host
2709
+ * draws the left-to-right form of these. */
2710
+ declare const MIRRORED_ICONS: ReadonlySet<ChartIconId>;
2711
+ /** Every published icon id, in catalog order: the controls, then the styles, the tools and the
2712
+ * layouts in their registries' orders. */
2713
+ declare const CHART_ICON_IDS: readonly ChartIconId[];
2107
2714
 
2108
2715
  /** A declared numeric input: `int`/`float` bound by min/max, `enum` an index into `options`. */
2109
2716
  interface ManifestInput {
@@ -2301,101 +2908,41 @@ declare function buildManifestPlots(run: ManifestRun, times: readonly UTCTimesta
2301
2908
  * defensively. */
2302
2909
  declare function latestPlotValue(data: readonly unknown[] | undefined): number | null;
2303
2910
 
2304
- /** One resolved role as it is written to the DOM. */
2305
- interface ThemeDeclaration {
2306
- /** The private custom-property name. */
2307
- property: string;
2308
- /** The resolved value, already a CSS token. */
2309
- value: string;
2310
- }
2311
-
2312
- /** Everything the widget writes on its own root element for one resolved theme. */
2313
- interface ThemeRootStyle {
2314
- /** The attribute that scopes the package stylesheet to this instance. */
2315
- attribute: {
2316
- name: string;
2317
- value: ThemeMode;
2318
- };
2319
- /** One entry per role, ordered by role id. */
2320
- declarations: readonly ThemeDeclaration[];
2321
- }
2322
- /** The theme values the canvas renderer draws with. The chart appearance ladder sits above these:
2323
- * a host override of a series color wins over `up` and `down` here, which are the mode's defaults
2324
- * for anything the appearance tree does not name. */
2325
- interface CanvasTheme {
2326
- background: string;
2327
- paneBorder: string;
2328
- grid: string;
2329
- axisText: string;
2330
- axisBackground: string;
2331
- axisBorder: string;
2332
- crosshair: string;
2333
- crosshairLabelBackground: string;
2334
- crosshairLabelText: string;
2335
- /** The size, in CSS pixels, of text drawn into the canvas. */
2336
- fontSize: number;
2337
- fontFamily: string;
2338
- /** Ink for text the chart paints over the plot area, such as the legend. */
2339
- textOnCanvas: string;
2340
- up: string;
2341
- down: string;
2342
- neutral: string;
2343
- session: {
2344
- preMarket: string;
2345
- extended: string;
2346
- afterHours: string;
2347
- closed: string;
2348
- };
2349
- }
2350
- /** Project a resolved theme onto the canvas renderer's inputs. */
2351
- declare function canvasTheme(theme: SemanticTheme): CanvasTheme;
2352
-
2353
- /** Paints a market's mark into a box the chart owns, and answers what takes it down again. */
2354
- type SymbolMarkPainter = (request: {
2355
- symbol: string;
2356
- host: HTMLElement;
2357
- size: number;
2358
- }) => (() => void) | void;
2359
- /** Paints the mark of the venue a market lists on, the same way. */
2360
- type VenueMarkPainter = (request: {
2361
- exchange: string;
2362
- host: HTMLElement;
2363
- size: number;
2364
- }) => (() => void) | void;
2365
- /** Paints the mark of a data provider, where a row names a provider rather than a venue. */
2366
- type ProviderMarkPainter = (request: {
2367
- provider: string;
2368
- host: HTMLElement;
2369
- size: number;
2370
- }) => (() => void) | void;
2371
- /** Every painter the host lent, as the chart carries them: null where it lent none. */
2372
- interface MarkPainters {
2373
- readonly symbol: SymbolMarkPainter | null;
2374
- readonly venue: VenueMarkPainter | null;
2375
- readonly provider: ProviderMarkPainter | null;
2911
+ /** The symbol's price format, as a study scale falls back to it when the manifest declares no
2912
+ * precision: the formatter writes the scale labels, `minMove` is the symbol's smallest move, and
2913
+ * `key` changes whenever either does so the scale re-applies. */
2914
+ interface SymbolPriceFormat {
2915
+ key: string;
2916
+ formatter: (price: number) => string;
2917
+ minMove: number;
2376
2918
  }
2377
- /** The host's hooks, as an entry point takes them. Each is the host's to lend or withhold, and
2378
- * every entry point that paints marks takes exactly these, so a host writes them once and hands
2379
- * the same three to a chart and to a picker it opens away from one. */
2380
- interface MarkPainterHooks {
2381
- /** The host's mark for a market, called WHEREVER the chart names one: each chart's legend, the
2382
- * compare rows under it, every row of the symbol search and compare dialogs, and the market tag
2383
- * a trading notice wears. It receives the element to paint into and the symbol it stands for,
2384
- * and returns a disposer that takes the mark down again.
2385
- *
2386
- * One hook rather than one per surface, so a market wears the same mark everywhere it appears and
2387
- * a host implements it once. The chart ships no artwork and fetches none: absent this, every mark
2388
- * is the neutral monogram the package draws itself. */
2389
- symbolMark?: SymbolMarkPainter;
2390
- /** The host's mark for the venue a market lists on, painted beside the venue's name in every row
2391
- * of the symbol search and compare dialogs. Like `symbolMark`, it receives the element to paint
2392
- * into and the size of the box, and returns a disposer; absent, a venue wears its initial on the
2393
- * neutral disc the package draws itself. */
2394
- venueMark?: VenueMarkPainter;
2395
- /** The host's mark for the data provider a row names where it names no venue, painted in that
2396
- * row's source cell the same way. Absent, the provider wears its initial on the neutral disc. */
2397
- providerMark?: ProviderMarkPainter;
2919
+ /** The running renderer a host drives. */
2920
+ interface IndicatorsRenderer {
2921
+ /** Render (or re-render) one instance's built spec. A spec carrying `unavailable` removes the
2922
+ * instance's chart objects (the note is the host's to surface). */
2923
+ render(id: string, built: IndicatorPlots): void;
2924
+ remove(id: string): void;
2925
+ /** Remove every rendered instance NOT in `keep` (list-sync after removals), sweeping panes. */
2926
+ prune(keep: ReadonlySet<string>): void;
2927
+ has(id: string): boolean;
2928
+ /** Live pane index per rendered instance — derived fresh on call, because pane indices shift
2929
+ * whenever an emptied pane is swept. */
2930
+ paneOf(): Record<string, number>;
2931
+ /** Clear every plot's data without tearing series down — for a blanked bar buffer during a
2932
+ * symbol/timeframe switch, where stale lines over an empty pane would paint garbage. */
2933
+ blank(): void;
2934
+ destroy(): void;
2398
2935
  }
2936
+ declare function attachIndicators(chart: IChartApi, options?: {
2937
+ candles?: () => ISeriesApi<'Candlestick'> | null;
2938
+ /** The symbol's price format for studies that declare no precision. A host that supplies none
2939
+ * leaves those scales on the library's own default formatting. */
2940
+ symbolPriceFormat?: () => SymbolPriceFormat;
2941
+ /** The undirected ink a level line takes when the manifest declares no color of its own. Read
2942
+ * live, so a theme switch repaints the levels with everything else; the built-in dark palette's
2943
+ * neutral stands in for a host that supplies none. */
2944
+ neutral?: () => string;
2945
+ }): IndicatorsRenderer;
2399
2946
 
2400
2947
  /** Price display as an extension reads it — the chart's own formatter, so an overlay's label and the
2401
2948
  * axis beside it can never disagree about what a number looks like. */
@@ -2853,150 +3400,21 @@ declare function autoIntervalFor(chartTf: string): {
2853
3400
  tf: string;
2854
3401
  sec: number;
2855
3402
  } | null;
2856
- /** A bar shape shared with the datafeed contract ({t,o,h,l,c,v}), kept structural so this module
2857
- * never depends on the feed's own types. */
2858
- interface ReplayBarShape {
2859
- t: number;
2860
- o: number;
2861
- h: number;
2862
- l: number;
2863
- c: number;
2864
- v: number;
2865
- }
2866
- /** The FORMING parent bar after k of its sub-bars have played: open from the first sub, high/low
2867
- * cumulative, close from the latest, volume summed — real finer bars, never synthesized ticks.
2868
- * With k at (or past) the full sub count the REAL parent is returned verbatim, so a fully-formed
2869
- * bar is exact rather than a reconstruction (sub-bar sets can be lossy at session edges). */
2870
- declare function composeFormingBar<B extends ReplayBarShape>(parent: B, subs: readonly ReplayBarShape[], k: number): B;
2871
-
2872
- /** The session an instant classifies into. `extended` is trading outside regular hours when the
2873
- * symbol does not split it into pre-market and after-hours. */
2874
- type SessionState = 'pre' | 'open' | 'extended' | 'after' | 'closed';
2875
- /** One subsession of an extended-hours symbol: `regular`,
2876
- * `extended`, `premarket` or `postmarket`, each with its own session string and, optionally,
2877
- * the corrections that shorten it. `SymbolInfo.subsessions` satisfies it; an id the chart has
2878
- * no state for is ignored. */
2879
- interface SubsessionSource {
2880
- readonly id: string;
2881
- readonly session: string;
2882
- readonly sessionCorrections?: string;
2883
- }
2884
- /** What a session model is built from: the symbology triple plus the optional corrections and
2885
- * subsessions. `SymbolInfo` satisfies it. */
2886
- interface SessionSource {
2887
- readonly timezone: string;
2888
- readonly session: string;
2889
- readonly sessionHolidays?: string;
2890
- readonly corrections?: string;
2891
- readonly subsessions?: readonly SubsessionSource[];
2892
- }
2893
- /** One trading stretch of a trading day, in minutes from that day's exchange-local midnight. The
2894
- * start may be negative (the stretch begins on a previous day) and the end may pass 1440 (it
2895
- * runs into the next day); the end is exclusive. */
2896
- interface SessionSegment {
2897
- readonly start: number;
2898
- readonly end: number;
2899
- }
2900
- /** A schedule: the stretches per weekday (0 = Sunday), and dated overrides keyed 'YYYYMMDD'. */
2901
- interface SessionSchedule {
2902
- readonly week: readonly (readonly SessionSegment[])[];
2903
- readonly corrections: ReadonlyMap<string, readonly SessionSegment[]>;
2904
- }
2905
- interface SessionModel {
2906
- /** The exchange zone every minute here is read in. */
2907
- readonly timezone: string;
2908
- /** A `24x7` symbol: always open, no transitions, no timeline. */
2909
- readonly continuous: boolean;
2910
- /** The regular session. */
2911
- readonly regular: SessionSchedule;
2912
- /** Extended-hours stretches by the state they classify into, from the subsessions. */
2913
- readonly extended: readonly {
2914
- readonly state: Exclude<SessionState, 'open' | 'closed'>;
2915
- readonly schedule: SessionSchedule;
2916
- }[];
2917
- /** Full-closure dates, 'YYYYMMDD'. */
2918
- readonly holidays: ReadonlySet<string>;
2919
- }
2920
- /** Build the session model from a symbol's metadata. Null when the grammar cannot read any part
2921
- * of it: a chart then shows no bands, no status and no timeline for the symbol rather than a
2922
- * session it guessed. A `regular` subsession, when given, is the regular session; the symbol's
2923
- * `session` is otherwise. Subsessions with ids the chart has no state for are ignored. */
2924
- declare function parseSessionModel(source: SessionSource): SessionModel | null;
2925
- /** Which of a symbol's named sessions a chart displays:
2926
- * `regular` shows regular hours only, `extended` shows the extended-hours bars as well. A
2927
- * per-chart preference a host persists. `extended` is the DEFAULT and shows every bar the feed
2928
- * served; narrowing to `regular` is the opt-in, because a chart that silently hid bars it had
2929
- * would be lying about the market by default. A symbol without extended hours has nothing to
2930
- * choose, and every bar shows either way. */
2931
- type ActiveSubsession = 'regular' | 'extended';
2932
- declare const DEFAULT_SUBSESSION: ActiveSubsession;
2933
- /** Whether the symbol declared any hours outside its regular session. Only such a symbol offers a
2934
- * subsession choice or shades extended hours. */
2935
- declare function hasExtendedHours(model: SessionModel): boolean;
2936
- /** The bar filter for the active subsession: under `regular`, on a symbol with extended hours,
2937
- * keep the bars whose open falls in regular hours; otherwise nothing is filtered (null). For
2938
- * intraday intervals only: a daily bar spans whole sessions, so a caller applies the filter on
2939
- * intraday intervals and shows every daily bar. */
2940
- declare function subsessionBarFilter(model: SessionModel, active: ActiveSubsession): ((epochSecs: number) => boolean) | null;
2941
- /** The session state at an instant (epoch seconds), under the symbol's exchange clock. */
2942
- declare function sessionStateAt(model: SessionModel, epochSecs: number): SessionState;
2943
- /** The next session transition after an instant, exact to the minute, or null when there is
2944
- * none within eight days (a continuous market, or a long closure). */
2945
- declare function nextSessionChange(model: SessionModel, epochSecs: number): {
2946
- atSecs: number;
2947
- state: SessionState;
2948
- } | null;
2949
- interface SessionTimeline {
2950
- /** The exchange-local day's stretches, closed gaps included, covering 0 to 1440 minutes. */
2951
- readonly segments: readonly {
2952
- readonly start: number;
2953
- readonly end: number;
2954
- readonly state: SessionState;
2955
- }[];
2956
- /** Now, in exchange-local minutes from midnight. */
2957
- readonly nowMins: number;
2958
- /** The exchange-local weekday, written in the language of `tag` and upper-cased ("MON"). */
2959
- readonly dayLabel: string;
2960
- readonly timezone: string;
2961
- }
2962
- /** The exchange-local day's timeline for a status popup. `tag` is the BCP 47 tag the weekday is
2963
- * written in: a date part, so it comes from Intl rather than the catalog. */
2964
- declare function sessionTimeline(model: SessionModel, epochSecs: number, tag: string): SessionTimeline;
2965
- /** A symbol's market status at an instant: the session state and the feed's liveness together,
2966
- * so a consumer cannot present an end-of-day or delayed feed as a live open market. */
2967
- interface MarketStatus {
2968
- readonly state: SessionState;
2969
- /** The feed's liveness, an explicit part of the status. */
2970
- readonly dataStatus: DataStatus;
2971
- /** A `24x7` symbol. */
2972
- readonly continuous: boolean;
2973
- /** The next transition, or null when there is none to count down to. */
2974
- readonly next: {
2975
- readonly atSecs: number;
2976
- readonly state: SessionState;
2977
- } | null;
3403
+ /** A bar shape shared with the datafeed contract ({t,o,h,l,c,v}), kept structural so this module
3404
+ * never depends on the feed's own types. */
3405
+ interface ReplayBarShape {
3406
+ t: number;
3407
+ o: number;
3408
+ h: number;
3409
+ l: number;
3410
+ c: number;
3411
+ v: number;
2978
3412
  }
2979
- declare function marketStatus(model: SessionModel, dataStatus: DataStatus, nowSecs: number): MarketStatus;
2980
- /** The market status straight from a resolved symbol, or null when its session cannot be read. */
2981
- declare function marketStatusFor(symbol: Pick<SymbolInfo, 'timezone' | 'session' | 'sessionHolidays' | 'corrections' | 'subsessions' | 'dataStatus'>, nowSecs: number): MarketStatus | null;
2982
- /** The catalog key of a session state's name: the same five words the legend's status dot and
2983
- * a status popup's title use. */
2984
- declare const SESSION_STATE_TITLE: Readonly<Record<SessionState, ChartMessageKey>>;
2985
- /** The title line of a status popup: the feed's liveness when it is not a live stream, the
2986
- * continuous market's own word, or the session state's name. */
2987
- declare function marketStatusTitle(t: ChartTranslate, status: MarketStatus): string;
2988
- /** "3 days 4 hours": the coarsest unit, and the next one down when it is non-zero. Each unit is a
2989
- * whole phrase and `status.durationPair` owns the order and the separator, so a language decides
2990
- * both rather than inheriting English's. A duration under a minute reads as one minute. */
2991
- declare function formatDuration(t: ChartTranslate, secs: number): string;
2992
- /** The sentence under a status popup's title. An end-of-day feed states that and nothing about
2993
- * hours; a continuous market states that it never closes; otherwise the session state with a
2994
- * countdown to the next transition when one is known, and a delayed stream adds that its prices
2995
- * are delayed. */
2996
- declare function marketStatusText(t: ChartTranslate, status: MarketStatus, nowSecs: number): string;
2997
- /** The footer naming the exchange zone a timeline is drawn in: "Exchange timezone: New York
2998
- * (UTC-4)". */
2999
- declare function exchangeTimezoneText(t: ChartTranslate, timezone: string, at?: Date): string;
3413
+ /** The FORMING parent bar after k of its sub-bars have played: open from the first sub, high/low
3414
+ * cumulative, close from the latest, volume summed — real finer bars, never synthesized ticks.
3415
+ * With k at (or past) the full sub count the REAL parent is returned verbatim, so a fully-formed
3416
+ * bar is exact rather than a reconstruction (sub-bar sets can be lossy at session edges). */
3417
+ declare function composeFormingBar<B extends ReplayBarShape>(parent: B, subs: readonly ReplayBarShape[], k: number): B;
3000
3418
 
3001
3419
  interface SearchControllerOptions {
3002
3420
  /** Rows per server page. Default 50. */
@@ -3085,21 +3503,6 @@ declare function spreadExpression(query: string): string;
3085
3503
  * lists the ETHBTC markets under the expression row. */
3086
3504
  declare function spreadSearchQuery(query: string): string;
3087
3505
 
3088
- /** The style vocabulary. Fixed at seven; a new one is a public API addition, not a config value. */
3089
- type ChartStyleId = 'candles' | 'hollow' | 'bars' | 'line' | 'area' | 'baseline' | 'stepline';
3090
- /** Picker and manifest order. */
3091
- declare const CHART_STYLES: readonly ChartStyleId[];
3092
- /** Whether a string names a style. A stored or restored value outside the vocabulary degrades to
3093
- * candles rather than leaving the chart with no series at all. */
3094
- declare function isChartStyle(raw: unknown): raw is ChartStyleId;
3095
- /** Coerce a stored or restored value to a style. */
3096
- declare function coerceChartStyle(raw: unknown): ChartStyleId;
3097
- /** Styles whose series consumes `{ time, value }` (close only). The rest consume the whole bar.
3098
- * Every consumer branches on this ONE predicate: a style is value-shaped or bar-shaped, never a
3099
- * third thing. A value-shaped style has no open, high or low to show, so the legend drops the
3100
- * OHLC values while it is on. */
3101
- declare function valueShaped(style: ChartStyleId): boolean;
3102
-
3103
3506
  interface PaneRect {
3104
3507
  x: number;
3105
3508
  y: number;
@@ -3185,488 +3588,173 @@ type ResourceLoadOutcome<Body> = {
3185
3588
  type ResourceRemoveOutcome = {
3186
3589
  kind: 'ok';
3187
3590
  } | {
3188
- kind: 'conflict';
3189
- current: ResourceRef;
3190
- message: string;
3191
- } | {
3192
- kind: 'not-found';
3193
- message: string;
3194
- };
3195
-
3196
- /** The save/load surface a host drives. */
3197
- interface ChartSaveLoadApi {
3198
- adapter: ChartSaveLoadAdapter | null;
3199
- /** Snapshot the chart's state as a name-less save: symbol and timeframe for the listing row, and
3200
- * the opaque, versioned content blob. A loaded chart restores its LOOK as well as its data. */
3201
- serialize(): {
3202
- symbol: string;
3203
- timeframe: string;
3204
- content: string;
3205
- };
3206
- /** Apply a saved chart's content blob. Throws on an unrecognized content version. A blob that
3207
- * fails part-way puts the chart back on the content it held; where that fails too, the chart
3208
- * stops saving and `notSaving()` says so. */
3209
- restore(content: string): void;
3210
- /** The open saved chart, or null while what is on screen is unsaved. */
3211
- current(): OpenResource | null;
3212
- /** True while the chart holds content that could not be put back: a body failed part-way and so
3213
- * did the undo, so the screen is neither content. Saving is refused until a load lands, so a
3214
- * half-applied chart is never written over the last one that was whole. */
3215
- notSaving(): boolean;
3216
- /** Save under `name`: an update of the open chart at its held revision, or a create when nothing
3217
- * is open or `asNew` asks for a copy. Answers `not-saving` while the chart is not saving; a copy
3218
- * is let through, because it creates a chart of its own and leaves the one this chart is bound to
3219
- * standing whole, but the chart still saves nowhere else. Rejects without an adapter. */
3220
- save(name: string, opts?: {
3221
- asNew?: boolean;
3222
- signal?: AbortSignal;
3223
- }): Promise<ResourceSaveOutcome<ChartMeta>>;
3224
- /** Open a saved chart: its content is read and applied FIRST, and only a chart that took it
3225
- * becomes the open chart. Content this build cannot read comes back as `invalid`, an id the
3226
- * store does not hold as `not-found`, a store that could not be reached as `unavailable`, and a
3227
- * load abandoned before it landed as `cancelled`. On every one of them the chart on screen and
3228
- * its save binding are exactly as they were. */
3229
- load(id: string, signal?: AbortSignal): Promise<ResourceLoadOutcome<ChartBody>>;
3230
- /** Delete the open chart at its held revision. What is on screen stays; its binding detaches. */
3231
- remove(signal?: AbortSignal): Promise<ResourceRemoveOutcome>;
3232
- /** Forget the open chart without touching the store: the next save creates. */
3233
- detach(): void;
3234
- }
3235
-
3236
- /** What one step says changed, in the order a diff asks. */
3237
- type HistoryChange = 'symbol' | 'timeframe' | 'style' | 'priceScale' | 'appearance' | 'compareAdd' | 'compareRemove' | 'compareChange' | 'indicatorAdd' | 'indicatorRemove' | 'indicatorChange' | 'drawingAdd' | 'drawingRemove' | 'drawingChange';
3238
- /** The undo surface a control and a command read. */
3239
- interface ChartHistoryApi {
3240
- canUndo(): boolean;
3241
- canRedo(): boolean;
3242
- /** What the next undo would take back, or null when there is nothing to take back. */
3243
- undoChange(): HistoryChange | null;
3244
- /** What the next redo would put back, or null when there is nothing to put back. */
3245
- redoChange(): HistoryChange | null;
3246
- undo(): void;
3247
- redo(): void;
3248
- }
3249
-
3250
- /** A visible window in the feed's unix seconds. */
3251
- interface TimeRange {
3252
- from: number;
3253
- to: number;
3254
- }
3255
- /** A visible window in bar indices. Fractional, and it may run past either end of the data: the
3256
- * right margin is real space a chart can scroll into. */
3257
- interface LogicalRange {
3258
- from: number;
3259
- to: number;
3260
- }
3261
-
3262
- /** How a formatted price is punctuated. A price localizes the decimal sign only, so
3263
- * `groupSign` defaults to '' (no thousands separator) and a host that wants grouping asks for it
3264
- * explicitly. */
3265
- interface NumericPunctuation {
3266
- /** What separates the whole part from the decimals. Default '.', or the locale's sign when a
3267
- * `locale` is given. */
3268
- decimalSign?: string;
3269
- /** What separates thousands in the whole part. Default '': a price is written ungrouped, because
3270
- * a grouped price is harder to compare against the axis beside it. */
3271
- groupSign?: string;
3272
- }
3273
- interface PriceFormatterOptions {
3274
- /** A BCP 47 tag used ONCE, at construction, to derive the decimal sign. Anything explicit in
3275
- * `numericPunctuation` wins over it. */
3276
- locale?: string;
3277
- numericPunctuation?: NumericPunctuation;
3278
- }
3279
- /** A resolved formatter for one symbol. `format` and `parse` are exact inverses over every price
3280
- * that lands on the symbol's own grid. */
3281
- interface PriceFormatter {
3282
- /** The price as the symbol writes it. */
3283
- format(price: number): string;
3284
- /** The number a user typed, or null when the text is not a price in this symbol's format. */
3285
- parse(text: string): number | null;
3286
- /** How many digits `format` writes after the decimal sign. 0 for a fractional format, which
3287
- * writes none; the widest band's width for a variable-tick format, so a column sized from it
3288
- * never has to reflow. */
3289
- precision(): number;
3290
- }
3291
- /** Build the formatter for one symbol's price format. The result is stateless and reusable; a host
3292
- * resolves a symbol once and keeps its formatter for as long as the symbol is on screen. */
3293
- declare function createPriceFormatter(format: PriceFormat, options?: PriceFormatterOptions): PriceFormatter;
3294
-
3295
- /** One glyph: its own grid and the inner markup drawn on it. */
3296
- interface Glyph {
3297
- viewBox: string;
3298
- body: string;
3299
- /** A glyph that is not square keeps its grid's proportion: the size is its HEIGHT and the width
3300
- * follows this ratio. Square glyphs omit it. */
3301
- aspect?: number;
3302
- /** The height the glyph is drawn at when a caller names none. Glyphs drawn at 28 omit it. */
3303
- size?: number;
3304
- }
3305
-
3306
- /** The inner markup of each miniature, without its `<svg>` wrapper, keyed by the tool's registry type. */
3307
- declare const TOOL_ICONS: {
3308
- trend_line: string;
3309
- ray: string;
3310
- info_line: string;
3311
- extended: string;
3312
- trend_angle: string;
3313
- horizontal_line: string;
3314
- horizontal_ray: string;
3315
- vertical_line: string;
3316
- cross_line: string;
3317
- parallel_channel: string;
3318
- regression_trend: string;
3319
- flat_top_bottom: string;
3320
- disjoint_channel: string;
3321
- pitchfork: string;
3322
- schiff_pitchfork: string;
3323
- schiff_pitchfork_modified: string;
3324
- inside_pitchfork: string;
3325
- fib_retracement: string;
3326
- fib_trend_ext: string;
3327
- fib_channel: string;
3328
- fib_timezone: string;
3329
- fib_speed_resist_fan: string;
3330
- fib_trend_time: string;
3331
- fib_circles: string;
3332
- fib_spiral: string;
3333
- fib_speed_resist_arcs: string;
3334
- fib_wedge: string;
3335
- pitchfan: string;
3336
- gannbox: string;
3337
- gannbox_fixed: string;
3338
- gannbox_square: string;
3339
- gannbox_fan: string;
3340
- xabcd_pattern: string;
3341
- cypher_pattern: string;
3342
- abcd_pattern: string;
3343
- triangle_pattern: string;
3344
- three_drives: string;
3345
- head_and_shoulders: string;
3346
- elliott_impulse_wave: string;
3347
- elliott_correction: string;
3348
- elliott_triangle_wave: string;
3349
- elliott_double_combo: string;
3350
- elliott_triple_combo: string;
3351
- cyclic_lines: string;
3352
- time_cycles: string;
3353
- sine_line: string;
3354
- long_position: string;
3355
- short_position: string;
3356
- forecast: string;
3357
- bars_pattern: string;
3358
- ghost_feed: string;
3359
- sector: string;
3360
- anchored_vwap: string;
3361
- fixed_range_volume_profile: string;
3362
- anchored_volume_profile: string;
3363
- price_range: string;
3364
- date_range: string;
3365
- date_and_price_range: string;
3366
- brush: string;
3367
- highlighter: string;
3368
- arrow_marker: string;
3369
- arrow: string;
3370
- arrow_up: string;
3371
- arrow_down: string;
3372
- rectangle: string;
3373
- rotated_rectangle: string;
3374
- path: string;
3375
- circle: string;
3376
- ellipse: string;
3377
- polyline: string;
3378
- triangle: string;
3379
- arc: string;
3380
- curve: string;
3381
- double_curve: string;
3382
- text: string;
3383
- note: string;
3384
- price_note: string;
3385
- table: string;
3386
- callout: string;
3387
- comment: string;
3388
- price_label: string;
3389
- signpost: string;
3390
- flag: string;
3391
- image: string;
3392
- content_card: string;
3393
- pin: string;
3591
+ kind: 'conflict';
3592
+ current: ResourceRef;
3593
+ message: string;
3594
+ } | {
3595
+ kind: 'not-found';
3596
+ message: string;
3394
3597
  };
3395
- /** A drawing tool that wears a miniature, by its registry type. */
3396
- type MiniatureTool = keyof typeof TOOL_ICONS;
3397
3598
 
3398
- declare const ARRANGEMENT_ICONS: {
3399
- s: {
3400
- viewBox: string;
3401
- body: string;
3402
- };
3403
- '2h': {
3404
- viewBox: string;
3405
- body: string;
3406
- };
3407
- '2v': {
3408
- viewBox: string;
3409
- body: string;
3410
- };
3411
- '3h': {
3412
- viewBox: string;
3413
- body: string;
3414
- };
3415
- '3v': {
3416
- viewBox: string;
3417
- body: string;
3418
- };
3419
- '3s': {
3420
- viewBox: string;
3421
- body: string;
3422
- };
3423
- '3r': {
3424
- viewBox: string;
3425
- body: string;
3426
- };
3427
- '2-1': {
3428
- viewBox: string;
3429
- body: string;
3430
- };
3431
- '1-2': {
3432
- viewBox: string;
3433
- body: string;
3434
- };
3435
- '4': {
3436
- viewBox: string;
3437
- body: string;
3438
- };
3439
- '4v': {
3440
- viewBox: string;
3441
- body: string;
3442
- };
3443
- '4h': {
3444
- viewBox: string;
3445
- body: string;
3446
- };
3447
- '4s': {
3448
- viewBox: string;
3449
- body: string;
3450
- };
3451
- '4s-l': {
3452
- viewBox: string;
3453
- body: string;
3454
- };
3455
- '1-3': {
3456
- viewBox: string;
3457
- body: string;
3458
- };
3459
- '3-1': {
3460
- viewBox: string;
3461
- body: string;
3462
- };
3463
- '2-2-l': {
3464
- viewBox: string;
3465
- body: string;
3466
- };
3467
- '2-2-r': {
3468
- viewBox: string;
3469
- body: string;
3470
- };
3471
- '2-2': {
3472
- viewBox: string;
3473
- body: string;
3474
- };
3475
- '1-4': {
3476
- viewBox: string;
3477
- body: string;
3478
- };
3479
- '5h': {
3480
- viewBox: string;
3481
- body: string;
3482
- };
3483
- '5v': {
3484
- viewBox: string;
3485
- body: string;
3486
- };
3487
- '5s': {
3488
- viewBox: string;
3489
- body: string;
3490
- };
3491
- '5s-l': {
3492
- viewBox: string;
3493
- body: string;
3494
- };
3495
- '2-3': {
3496
- viewBox: string;
3497
- body: string;
3498
- };
3499
- '3-2': {
3500
- viewBox: string;
3501
- body: string;
3502
- };
3503
- '4-1': {
3504
- viewBox: string;
3505
- body: string;
3506
- };
3507
- '2-3-l': {
3508
- viewBox: string;
3509
- body: string;
3510
- };
3511
- '2-3-r': {
3512
- viewBox: string;
3513
- body: string;
3514
- };
3515
- '6': {
3516
- viewBox: string;
3517
- body: string;
3518
- };
3519
- '6h': {
3520
- viewBox: string;
3521
- body: string;
3522
- };
3523
- '6v': {
3524
- viewBox: string;
3525
- body: string;
3526
- };
3527
- '6c': {
3528
- viewBox: string;
3529
- body: string;
3530
- };
3531
- '2-4': {
3532
- viewBox: string;
3533
- body: string;
3534
- };
3535
- '4-2': {
3536
- viewBox: string;
3537
- body: string;
3538
- };
3539
- '4-3': {
3540
- viewBox: string;
3541
- body: string;
3542
- };
3543
- '7h': {
3544
- viewBox: string;
3545
- body: string;
3546
- };
3547
- '7s': {
3548
- viewBox: string;
3549
- body: string;
3550
- };
3551
- '8': {
3552
- viewBox: string;
3553
- body: string;
3554
- };
3555
- '8c': {
3556
- viewBox: string;
3557
- body: string;
3558
- };
3559
- '8h': {
3560
- viewBox: string;
3561
- body: string;
3562
- };
3563
- '8v': {
3564
- viewBox: string;
3565
- body: string;
3566
- };
3567
- '9s': {
3568
- viewBox: string;
3569
- body: string;
3570
- };
3571
- '5-4': {
3572
- viewBox: string;
3573
- body: string;
3574
- };
3575
- '9h': {
3576
- viewBox: string;
3577
- body: string;
3578
- };
3579
- '9v': {
3580
- viewBox: string;
3581
- body: string;
3582
- };
3583
- '10c5': {
3584
- viewBox: string;
3585
- body: string;
3586
- };
3587
- '10h': {
3588
- viewBox: string;
3589
- body: string;
3590
- };
3591
- '10v': {
3592
- viewBox: string;
3593
- body: string;
3594
- };
3595
- '12c6': {
3596
- viewBox: string;
3597
- body: string;
3598
- };
3599
- '12c4': {
3600
- viewBox: string;
3601
- body: string;
3602
- };
3603
- '12h': {
3604
- viewBox: string;
3605
- body: string;
3606
- };
3607
- '14c7': {
3608
- viewBox: string;
3609
- body: string;
3610
- };
3611
- '16c8': {
3612
- viewBox: string;
3613
- body: string;
3614
- };
3615
- '16c4': {
3616
- viewBox: string;
3617
- body: string;
3599
+ /** The save/load surface a host drives. */
3600
+ interface ChartSaveLoadApi {
3601
+ adapter: ChartSaveLoadAdapter | null;
3602
+ /** Snapshot the chart's state as a name-less save: symbol and timeframe for the listing row, and
3603
+ * the opaque, versioned content blob. A loaded chart restores its LOOK as well as its data. */
3604
+ serialize(): {
3605
+ symbol: string;
3606
+ timeframe: string;
3607
+ content: string;
3618
3608
  };
3619
- };
3620
- /** A layout arrangement that wears a glyph, by its code. */
3621
- type ArrangementGlyphCode = keyof typeof ARRANGEMENT_ICONS;
3609
+ /** Apply a saved chart's content blob. Throws on an unrecognized content version. A blob that
3610
+ * fails part-way puts the chart back on the content it held; where that fails too, the chart
3611
+ * stops saving and `notSaving()` says so. */
3612
+ restore(content: string): void;
3613
+ /** The open saved chart, or null while what is on screen is unsaved. */
3614
+ current(): OpenResource | null;
3615
+ /** True while the chart holds content that could not be put back: a body failed part-way and so
3616
+ * did the undo, so the screen is neither content. Saving is refused until a load lands, so a
3617
+ * half-applied chart is never written over the last one that was whole. */
3618
+ notSaving(): boolean;
3619
+ /** Save under `name`: an update of the open chart at its held revision, or a create when nothing
3620
+ * is open or `asNew` asks for a copy. Answers `not-saving` while the chart is not saving; a copy
3621
+ * is let through, because it creates a chart of its own and leaves the one this chart is bound to
3622
+ * standing whole, but the chart still saves nowhere else. Rejects without an adapter. */
3623
+ save(name: string, opts?: {
3624
+ asNew?: boolean;
3625
+ signal?: AbortSignal;
3626
+ }): Promise<ResourceSaveOutcome<ChartMeta>>;
3627
+ /** Open a saved chart: its content is read and applied FIRST, and only a chart that took it
3628
+ * becomes the open chart. Content this build cannot read comes back as `invalid`, an id the
3629
+ * store does not hold as `not-found`, a store that could not be reached as `unavailable`, and a
3630
+ * load abandoned before it landed as `cancelled`. On every one of them the chart on screen and
3631
+ * its save binding are exactly as they were. */
3632
+ load(id: string, signal?: AbortSignal): Promise<ResourceLoadOutcome<ChartBody>>;
3633
+ /** Delete the open chart at its held revision. What is on screen stays; its binding detaches. */
3634
+ remove(signal?: AbortSignal): Promise<ResourceRemoveOutcome>;
3635
+ /** Forget the open chart without touching the store: the next save creates. */
3636
+ detach(): void;
3637
+ }
3622
3638
 
3623
- /** Where one glyph will stand. */
3624
- interface ChartIconContext {
3625
- /** The document the glyph is drawn into. Create its nodes with this one, never a global. */
3626
- readonly document: Document;
3627
- /** The box the glyph fills, in CSS pixels. The chart sizes the answered element to it, so a
3628
- * factory draws on whatever grid its viewBox names. */
3629
- readonly width: number;
3630
- readonly height: number;
3631
- /** The reading direction of the control the glyph stands in. When a language turns the widget's
3632
- * direction around, the chart asks the factory again for every glyph it drew and puts the new
3633
- * drawing in place of the old; an answer it refuses leaves the old drawing standing. A glyph the
3634
- * chart mirrors for a right-to-left language is mirrored whatever artwork it wears, so a factory
3635
- * always draws the left-to-right form of those; `direction` is for artwork that differs otherwise. */
3636
- readonly direction: 'ltr' | 'rtl';
3639
+ /** What one step says changed, in the order a diff asks. */
3640
+ type HistoryChange = 'symbol' | 'timeframe' | 'style' | 'priceScale' | 'appearance' | 'compareAdd' | 'compareRemove' | 'compareChange' | 'indicatorAdd' | 'indicatorRemove' | 'indicatorChange' | 'drawingAdd' | 'drawingRemove' | 'drawingChange';
3641
+ /** The undo surface a control and a command read. */
3642
+ interface ChartHistoryApi {
3643
+ canUndo(): boolean;
3644
+ canRedo(): boolean;
3645
+ /** What the next undo would take back, or null when there is nothing to take back. */
3646
+ undoChange(): HistoryChange | null;
3647
+ /** What the next redo would put back, or null when there is nothing to put back. */
3648
+ redoChange(): HistoryChange | null;
3649
+ undo(): void;
3650
+ redo(): void;
3637
3651
  }
3638
- /** Draws one glyph: a fresh `<svg>` element, never one it answered before or one already in the
3639
- * document. `currentColor` takes the control's own ink in every theme and state. */
3640
- type ChartIconFactory = (context: ChartIconContext) => SVGSVGElement;
3641
- /** Why a host's glyph was not drawn. */
3642
- type ChartIconFailure = 'threw' | 'not-svg' | 'in-use';
3643
- /** One glyph the chart could not draw from a host's factory. The control fell back to the chart's
3644
- * own glyph, or to none where the control is the host's. Each icon reports its first failure. */
3645
- interface ChartIconDiagnostic {
3646
- /** The icon: a published icon id, or `toolbarButton` for the glyph of a host's own control. */
3647
- icon: string;
3648
- code: ChartIconFailure;
3652
+
3653
+ /** A visible window in the feed's unix seconds. */
3654
+ interface TimeRange {
3655
+ from: number;
3656
+ to: number;
3657
+ }
3658
+ /** A visible window in bar indices. Fractional, and it may run past either end of the data: the
3659
+ * right margin is real space a chart can scroll into. */
3660
+ interface LogicalRange {
3661
+ from: number;
3662
+ to: number;
3663
+ }
3664
+
3665
+ /** What went wrong, as a machine-readable code. */
3666
+ type ThemeDiagnosticCode = 'unknown-role' | 'empty-value' | 'invalid-value';
3667
+ /** One rejected entry of a host's custom palette. */
3668
+ interface ThemeDiagnostic {
3669
+ /** The mode whose palette carried the entry. */
3670
+ mode: ThemeMode;
3671
+ /** The key as the host wrote it, whether or not it names a role. */
3672
+ role: string;
3673
+ code: ThemeDiagnosticCode;
3674
+ /** A sentence naming the problem, safe to log or surface in a host's own tooling. */
3649
3675
  message: string;
3650
3676
  }
3651
3677
 
3652
- /** The glyphs of the chart's own controls, by meaning, each with every drawing that carries it. */
3653
- declare const CONTROL_ICONS: Readonly<Record<"info" | "search" | "indicators" | "visible" | "textColor" | "lineColor" | "open" | "close" | "template" | "fillColor" | "locked" | "sync" | "measure" | "image" | "eraser" | "delete" | "remove" | "copy" | "pause" | "play" | "reset" | "scroll" | "hidden" | "add" | "magnet" | "compare" | "replay" | "settings" | "fullscreen" | "marketStatus" | "paneCollapse" | "paneRestore" | "paneMaximize" | "replayStatus" | "replayMark" | "replayCut" | "undo" | "redo" | "tileMaximize" | "tileRestore" | "download" | "chevronDown" | "chevronUp" | "chevronLeft" | "chevronRight" | "check" | "clear" | "goLive" | "stepForward" | "stepBack" | "selectBar" | "firstAvailable" | "randomBar" | "cursorCross" | "cursorDot" | "cursorArrow" | "magnetStrong" | "drawingsShown" | "drawingsHidden" | "indicatorsShown" | "indicatorsHidden" | "allShown" | "allHidden" | "zoomIn" | "grip" | "favoritesBar" | "lineSolid" | "lineDashed" | "lineDotted" | "lineThickness1" | "lineThickness2" | "lineThickness3" | "lineThickness4" | "lineEndNormal" | "lineEndArrow" | "fullscreenExit" | "caret" | "collapse" | "zoomOut" | "rename" | "duplicate" | "favorite" | "favorited" | "sortAscending" | "sortDescending" | "flyout" | "submenu" | "more" | "emptySearch" | "emptyCompare" | "operatorsShow" | "operatorsHide" | "operatorAdd" | "operatorSubtract" | "operatorMultiply" | "operatorDivide" | "operatorPower" | "operatorReciprocal" | "selectDate" | "zoomTool" | "stayInMode" | "stayInModeOn" | "unlocked" | "hide" | "glyphTools" | "visualOrder", readonly Glyph[]>>;
3654
- /** An icon of one of the chart's own controls. */
3655
- type ControlIconId = keyof typeof CONTROL_ICONS;
3656
- /** Every icon a host may draw: a control's glyph by its meaning, a chart style by its id, a drawing
3657
- * tool by its registry type, and a layout arrangement by its code. Exactly the ids in
3658
- * `CHART_ICON_IDS`, so an id the chart does not draw is a type error before it is a refusal. */
3659
- type ChartIconId = ControlIconId | `style.${ChartStyleId}` | `tool.${MiniatureTool}` | `layout.${ArrangementGlyphCode}`;
3660
- /** A host's drawings for the chart's icons, by id. An icon left out keeps the chart's own. */
3661
- type ChartIcons = {
3662
- readonly [K in ChartIconId]?: ChartIconFactory;
3678
+ /** What a host receives when the theme changes. */
3679
+ type ThemeChangeListener = (theme: SemanticTheme, mode: ThemeMode) => void;
3680
+ /** The runtime theme surface of one Quick Charts instance. */
3681
+ interface ThemeController {
3682
+ /** The mode in effect. */
3683
+ mode(): ThemeMode;
3684
+ /** Switch modes. The chart keeps its symbol, timeframe, range, drawings, and studies. */
3685
+ setMode(mode: ThemeMode): void;
3686
+ /** The complete resolved theme in effect. */
3687
+ get(): SemanticTheme;
3688
+ /** Replace the custom palettes. A role a palette does not name returns to its built-in value. */
3689
+ applyCustom(themes: CustomThemes): void;
3690
+ /** Drop every custom palette and return to the built-in palette for each mode. */
3691
+ resetCustom(): void;
3692
+ /** Anything rejected in the custom palettes currently held. Empty when they are fully usable. */
3693
+ diagnostics(): readonly ThemeDiagnostic[];
3694
+ /** Subscribe to theme changes. Returns the unsubscribe. */
3695
+ onChange(listener: ThemeChangeListener): () => void;
3696
+ }
3697
+ /** What a host may set when the controller is created. */
3698
+ interface ThemeControllerOptions {
3699
+ /** Defaults to `dark`. */
3700
+ mode?: ThemeMode;
3701
+ /** Custom palettes for either mode, or both. */
3702
+ custom?: CustomThemes;
3703
+ }
3704
+ /** Create the theme controller for one chart instance. */
3705
+ declare function createThemeController(options?: ThemeControllerOptions): ThemeController;
3706
+
3707
+ /** Which handle a command acts on: the widget as a whole, or the active chart. */
3708
+ type CommandScope = 'widget' | 'chart';
3709
+ /** One command. */
3710
+ interface CommandSpec {
3711
+ /** The stable public id, e.g. `chart.style.candles`. */
3712
+ id: string;
3713
+ scope: CommandScope;
3714
+ /** The catalog key the chart's own chrome labels the command with. */
3715
+ label: ChartMessageKey;
3716
+ /** Literal text that wins over `label`. A host contribution names itself in its own words and
3717
+ * owns its own translations, so it does not point at the chart's catalog. */
3718
+ labelText?: string;
3719
+ /** The default shortcut, in `KeyboardEvent` terms (e.g. `Alt+KeyR`). */
3720
+ shortcut?: string;
3721
+ /** Whether the command can run right now, from capability and chart state. */
3722
+ available(): boolean;
3723
+ /** Whether the access policy refuses this argument, for a command whose one id spans many
3724
+ * subjects (the tool to arm). A refused argument answers `denied`, as a refused id does. */
3725
+ refuses?(arg: unknown): boolean;
3726
+ execute(arg?: unknown): void | Promise<void>;
3727
+ }
3728
+ /** What running a command answers. A refusal is a value, never a throw: a menu row, a shortcut and
3729
+ * an operator all need to tell "nothing by that name" from "not allowed" without a try block. */
3730
+ type CommandResult = {
3731
+ kind: 'ok';
3732
+ } | {
3733
+ kind: 'unavailable';
3734
+ } | {
3735
+ kind: 'denied';
3736
+ } | {
3737
+ kind: 'unknown';
3738
+ } | {
3739
+ kind: 'failed';
3740
+ error: unknown;
3663
3741
  };
3664
- /** The glyphs the chart mirrors for a right-to-left language, whatever artwork they wear: a host
3665
- * draws the left-to-right form of these. */
3666
- declare const MIRRORED_ICONS: ReadonlySet<ChartIconId>;
3667
- /** Every published icon id, in catalog order: the controls, then the styles, the tools and the
3668
- * layouts in their registries' orders. */
3669
- declare const CHART_ICON_IDS: readonly ChartIconId[];
3742
+ /** The widget's command surface. */
3743
+ interface CommandRegistry {
3744
+ /** Add a command. Returns its unregister. A second registration of an id replaces the first,
3745
+ * which is what lets a chart re-register its own verbs when its active handle changes. */
3746
+ register(spec: CommandSpec): () => void;
3747
+ /** Every registered command, in registration order. Unavailable and denied commands are listed:
3748
+ * a menu decides whether to draw a disabled row, and hiding one would leave the host guessing. */
3749
+ list(): readonly CommandSpec[];
3750
+ /** Whether `execute` would run this command right now. */
3751
+ available(id: string): boolean;
3752
+ execute(id: string, arg?: unknown): CommandResult;
3753
+ /** Remap a shortcut, or clear it with null. */
3754
+ setShortcut(id: string, shortcut: string | null): void;
3755
+ /** Fires when the registered set or a shortcut changes. Returns the unsubscribe. */
3756
+ onChange(cb: () => void): () => void;
3757
+ }
3670
3758
 
3671
3759
  /** Where a layer's separate-drawing documents live: which context a symbol's document is keyed by,
3672
3760
  * and the store for that context. Both together or neither, so a layer is never half-configured. */
@@ -4056,42 +4144,6 @@ type ReplayPhase = 'off' | 'arming' | 'on';
4056
4144
  * presets). The public surface grows on demand, not by exposure. */
4057
4145
  type ChartDrawingsApi = Omit<DrawingsHandle, 'setSymbol' | 'setTimeframe' | 'setTick' | 'setPriceFormatter' | 'destroy' | 'selectedDrawing' | 'commitEdit' | 'beginPreview' | 'endPreview' | 'textEdit' | 'commitText' | 'cancelText' | 'presets'>;
4058
4146
 
4059
- /** The symbol's price format, as a study scale falls back to it when the manifest declares no
4060
- * precision: the formatter writes the scale labels, `minMove` is the symbol's smallest move, and
4061
- * `key` changes whenever either does so the scale re-applies. */
4062
- interface SymbolPriceFormat {
4063
- key: string;
4064
- formatter: (price: number) => string;
4065
- minMove: number;
4066
- }
4067
- /** The running renderer a host drives. */
4068
- interface IndicatorsRenderer {
4069
- /** Render (or re-render) one instance's built spec. A spec carrying `unavailable` removes the
4070
- * instance's chart objects (the note is the host's to surface). */
4071
- render(id: string, built: IndicatorPlots): void;
4072
- remove(id: string): void;
4073
- /** Remove every rendered instance NOT in `keep` (list-sync after removals), sweeping panes. */
4074
- prune(keep: ReadonlySet<string>): void;
4075
- has(id: string): boolean;
4076
- /** Live pane index per rendered instance — derived fresh on call, because pane indices shift
4077
- * whenever an emptied pane is swept. */
4078
- paneOf(): Record<string, number>;
4079
- /** Clear every plot's data without tearing series down — for a blanked bar buffer during a
4080
- * symbol/timeframe switch, where stale lines over an empty pane would paint garbage. */
4081
- blank(): void;
4082
- destroy(): void;
4083
- }
4084
- declare function attachIndicators(chart: IChartApi, options?: {
4085
- candles?: () => ISeriesApi<'Candlestick'> | null;
4086
- /** The symbol's price format for studies that declare no precision. A host that supplies none
4087
- * leaves those scales on the library's own default formatting. */
4088
- symbolPriceFormat?: () => SymbolPriceFormat;
4089
- /** The undirected ink a level line takes when the manifest declares no color of its own. Read
4090
- * live, so a theme switch repaints the levels with everything else; the built-in dark palette's
4091
- * neutral stands in for a host that supplies none. */
4092
- neutral?: () => string;
4093
- }): IndicatorsRenderer;
4094
-
4095
4147
  /** The compare surface a host drives. */
4096
4148
  interface ChartCompareApi {
4097
4149
  add(symbol: string, opts: {
@@ -4733,56 +4785,15 @@ interface ChartWidgetOptions extends MarkPainterHooks {
4733
4785
  marks?: boolean;
4734
4786
  }
4735
4787
 
4736
- /** Which handle a command acts on: the widget as a whole, or the active chart. */
4737
- type CommandScope = 'widget' | 'chart';
4738
- /** One command. */
4739
- interface CommandSpec {
4740
- /** The stable public id, e.g. `chart.style.candles`. */
4788
+ /** Host-owned activity, displayed with studies but never saved as an indicator or plotted. */
4789
+ interface ChartLegendRow {
4741
4790
  id: string;
4742
- scope: CommandScope;
4743
- /** The catalog key the chart's own chrome labels the command with. */
4744
- label: ChartMessageKey;
4745
- /** Literal text that wins over `label`. A host contribution names itself in its own words and
4746
- * owns its own translations, so it does not point at the chart's catalog. */
4747
- labelText?: string;
4748
- /** The default shortcut, in `KeyboardEvent` terms (e.g. `Alt+KeyR`). */
4749
- shortcut?: string;
4750
- /** Whether the command can run right now, from capability and chart state. */
4751
- available(): boolean;
4752
- /** Whether the access policy refuses this argument, for a command whose one id spans many
4753
- * subjects (the tool to arm). A refused argument answers `denied`, as a refused id does. */
4754
- refuses?(arg: unknown): boolean;
4755
- execute(arg?: unknown): void | Promise<void>;
4756
- }
4757
- /** What running a command answers. A refusal is a value, never a throw: a menu row, a shortcut and
4758
- * an operator all need to tell "nothing by that name" from "not allowed" without a try block. */
4759
- type CommandResult = {
4760
- kind: 'ok';
4761
- } | {
4762
- kind: 'unavailable';
4763
- } | {
4764
- kind: 'denied';
4765
- } | {
4766
- kind: 'unknown';
4767
- } | {
4768
- kind: 'failed';
4769
- error: unknown;
4770
- };
4771
- /** The widget's command surface. */
4772
- interface CommandRegistry {
4773
- /** Add a command. Returns its unregister. A second registration of an id replaces the first,
4774
- * which is what lets a chart re-register its own verbs when its active handle changes. */
4775
- register(spec: CommandSpec): () => void;
4776
- /** Every registered command, in registration order. Unavailable and denied commands are listed:
4777
- * a menu decides whether to draw a disabled row, and hiding one would leave the host guessing. */
4778
- list(): readonly CommandSpec[];
4779
- /** Whether `execute` would run this command right now. */
4780
- available(id: string): boolean;
4781
- execute(id: string, arg?: unknown): CommandResult;
4782
- /** Remap a shortcut, or clear it with null. */
4783
- setShortcut(id: string, shortcut: string | null): void;
4784
- /** Fires when the registered set or a shortcut changes. Returns the unsubscribe. */
4785
- onChange(cb: () => void): () => void;
4791
+ title: string;
4792
+ inputs?: string;
4793
+ status: string;
4794
+ description?: string;
4795
+ settingsLabel?: string;
4796
+ onSettings?: () => void;
4786
4797
  }
4787
4798
 
4788
4799
  /** The widget's fullscreen surface. */
@@ -4913,6 +4924,8 @@ type TopBarSlot = (typeof TOP_BAR_SLOTS)[number];
4913
4924
  * A slot is live for as long as the widget is. A host appends its own node and takes that node back
4914
4925
  * out again; the slot itself belongs to the chart and is never removed or replaced. */
4915
4926
  interface ChartChrome {
4927
+ /** Transient host activity in this chart's native study list. Does not affect chart content. */
4928
+ legendRows(chartId: string, rows: readonly ChartLegendRow[]): void;
4916
4929
  /** One named place in the top bar. Null when the top bar is hidden, which is the answer a host
4917
4930
  * checks before composing a door it would have nowhere to put. */
4918
4931
  topBar(slot: TopBarSlot): HTMLElement | null;
@@ -5498,4 +5511,4 @@ declare function mountSymbolSearch(options: SymbolSearchOptions & {
5498
5511
  container: HTMLElement;
5499
5512
  }): MountedSymbolSearch;
5500
5513
 
5501
- export { ARRANGEMENTS, type AccessPolicy, type ActiveSubsession, type Arrangement, type AttachDrawingsOptions, BRAND_DOWN, BRAND_UP, BUILT_IN_INDICATORS, BUILT_IN_LOCALES, type BarMark, type BarsEvent, type BuiltInIndicator, CHART_ICON_IDS, CHART_STYLES, COLLAPSED_H, COMPARE_COLORS, type CanvasTheme, type Capabilities, ChartBody, type ChartChrome, type ChartCompareApi, type ChartCustomLocale, type ChartDatafeed, type ChartDictionary, type ChartDrawingsApi, type ChartEvents, type ChartExtension, type ChartExtensionChart, type ChartExtensionCommand, type ChartExtensionContext, type ChartExtensionHandle, type ChartExtensionIcon, type ChartExtensionIconPath, type ChartExtensionMenuContext, type ChartExtensionMenuItem, type ChartExtensionMenuProvider, type ChartExtensionPane, type ChartExtensionPriceLine, type ChartExtensionReplayState, type ChartExtensionScope, type ChartExtensionSeries, type ChartHandle, type ChartHistoryApi, type ChartI18n, type ChartI18nOptions, type ChartIconContext, type ChartIconDiagnostic, type ChartIconFactory, type ChartIconFailure, type ChartIconId, type ChartIcons, type ChartLocale, type ChartLocaleCode, type ChartMenuAction, type ChartMenuContext, type ChartMenuIcon, type ChartMenuRow, ChartMessageKey, ChartMeta, type ChartOverrides, type ChartPaneSyncApi, type ChartPreferences, type ChartPriceFormatter, type ChartReplayApi, ChartSaveLoadAdapter, type ChartSaveLoadApi, type ChartStorage, type ChartStyleId, type ChartTimezone, type ChartTranslate, type ChartWidget, type ChartWidgetOptions, type CommandRegistry, type CommandResult, type CommandScope, type CommandSpec, type CompareDeps, type CompareEntry, type CompareHandle, type ComparePlacement, type CompareSnapshot, type CompareSymbol, type ContextMenuHandle, type CustomThemes, DEFAULT_OVERRIDES, DEFAULT_SUBSESSION, DEFAULT_TIMEZONE, type DataStatus, type DatafeedConfig, type DrawingApplyOutcome, DrawingAssetPort, DrawingContextKind, type DrawingDocumentApi, type DrawingDocumentPort, type DrawingDocumentRefusal, type DrawingEvent, type DrawingOwner, DrawingPreferences, type DrawingPresets, type DrawingReadOutcome, type DrawingRejection, type DrawingRejectionReason, DrawingResourceContext, DrawingsBody, type DrawingsEvents, type DrawingsHandle, DrawingsMeta, type DrawingsWorkflow, EXCHANGE_TIMEZONE, type FeatureConfig, type FeedBar, FeedUnavailableError, type FetchLike, FillBetweenPrimitive, type FullscreenApi, type FullscreenOptions, type HistoryChange, type HistoryEventState, type HistoryPage, IMAGE_HEADER_H, type ImageApi, type ImageEvent, type ImageHeader, type ImageOptions, type ImageTextRun, type ImageTile, type IndicatorCategory, type IndicatorDefinition, type IndicatorEvent, type IndicatorFill, type IndicatorInstance, type IndicatorLevel, type IndicatorManifest, type IndicatorOverrides, type IndicatorPickerAction, type IndicatorPickerBuiltInState, type IndicatorPickerCollection, type IndicatorPickerItem, type IndicatorPickerSource, type IndicatorPlot, type IndicatorPlots, type IndicatorsApi, type IndicatorsRenderer, LAYOUT_MENU_ROWS, type LayoutApi, LayoutBody, type LayoutEvent, LayoutMeta, type LayoutOptions, type LayoutSaveLoadApi, type LayoutSyncFlags, type LegendUi, type LogicalRange, MAIN_MIN_H, MIN_BAR_SPACING, MIRRORED_ICONS, type ManifestFill, type ManifestInput, type ManifestLevel, type ManifestPlot, type ManifestRun, type MarkColorRole, type MarkPainters, type MarkPlacement, type MarkShape, type MarketStatus, type MatchSegment, type MountedSymbolSearch, type NumericPunctuation, type OlderPageVerdict, type OpenResource, PRICE_SCALE_MODE, type PaneOp, type PanePlan, type PaneRect, type PaneState, type PartialOverrides, type PlacedImage, type PlotPoint, type PriceFormat, type PriceFormatter, type PriceFormatterOptions, type ProviderMarkPainter, RANGE_PRESETS, RECENT_SYMBOLS_CAP, REPLAY_SPEEDS, type RangeFrameTarget, type RangePreset, type RangeSpan, type RecentsPort, type ReplayEventState, type ReplaySpeed, type ResourceLoadOutcome, ResourceRef, type ResourceRemoveOutcome, type ResourceSaveOutcome, ResourceStore, SCALE_MODES, SCALE_MODE_OPTIONS, SCROLL_STEP_BARS, SESSION_DOT, SESSION_LABEL, SESSION_STATE_TITLE, SPREAD_OPERATORS, type SaveConflictInfo, type ScaleMode, type SearchController, type SearchControllerOptions, type SearchPage, type SearchScope, type SearchState, type SelectedDrawing, type SemanticTheme, type SessionBandsPrimitive, type SessionModel, type SessionSchedule, type SessionSegment, type SessionSource, type SessionState, type SessionTimeline, type SettingsMenuUi, ShadePrimitive, type SpreadOperator, type SubscribeHandlers, type Subsession, type SubsessionId, type SubsessionSource, type SymbolInfo, type SymbolMarkPainter, type SymbolNames, type SymbolPriceFormat, type SymbolRow, type SymbolSearchCache, type SymbolSearchHandle, type SymbolSearchOptions, THEME_ROLES, TIMEFRAME_MAX, TIMEFRAME_PRESETS, TIMEFRAME_PRESET_TOKENS, TIMEFRAME_UNITS, TIMEFRAME_UNIT_NAME, TIMEFRAME_UNIT_SECONDS, TIMEZONES, TOP_BAR_SLOTS, TemplateBody, TemplateMeta, type TextEditSession, type ThemeChangeListener, type ThemeController, type ThemeControllerOptions, type ThemeDeclaration, type ThemeDiagnostic, type ThemeDiagnosticCode, type ThemeMode, type ThemeOptions, type ThemeRole, type ThemeRoleFamily, type ThemeRoleId, type ThemeRoleKind, type ThemeRootStyle, type TickBand, type TimeRange, type Timeframe, type TimeframeGroup, type TimeframeRestrictions, type TimeframeUnit, type TimescaleMark, type TimezoneRow, type ToolbarButton, type ToolbarButtonOptions, type ToolbarButtonState, type TopBarSlot, type TopBarUi, type UdfDatafeedOptions, type UdfSymbolResponse, type UiConfig, type VenueMarkPainter, type WidgetEvents, ZOOM_FACTOR, type ZoneClock, allowedTimeframes, applyBar, applyPlotOverrides, arrangementName, arrangementOf, attachCompare, attachDrawings, attachIndicators, autoIntervalFor, buildManifestPlots, canvasTheme, canvasToBlob, chartContextMenu, chartDictionaries, clipToWindow, coerceChartStyle, coerceScaleMode, compareTimeframes, composeFormingBar, composeImage, createChart, createChartI18n, createPriceFormatter, createSearchController, createSessionBands, createSymbolSearchCache, createThemeController, createUdfDatafeed, effectivePlotColor, exchangeTimezoneText, formatClock, formatDuration, formatTimeframe, frameRange, hasExtendedHours, imageFileName, imageHeaderRuns, imageLayoutHeaderRuns, imageTileRuns, indicatorHidden, isChartStyle, isCollapsed, isIntradayTimeframe, isSymbolPair, isTimezoneChoice, latestPlotValue, layerOverrides, looksLikeSpread, makeCrosshairTimeFormatter, makeTickMarkFormatter, manifestInputDefaults, marketStatus, marketStatusFor, marketStatusText, marketStatusTitle, matchSegments, memoryChartStorage, memoryRecents, mergeOverrides, mountContextMenu, mountSymbolSearch, nextSessionChange, olderPageVerdict, openInputsEditor, openSymbolSearch, overriddenManifest, parseSessionModel, parseTickBands, parseTimeframe, pickCompareColor, placeableByWidget, planPaneOp, promoteRecent, rangeAvailable, rangePresetTip, rangeSpanSeconds, resolveDisplayTimezone, resolveInitialTf, scrolledPosition, seriesTargetOf, sessionStateAt, sessionTimeline, spreadExpression, spreadSearchQuery, subIntervalsFor, subsessionBarFilter, symbolNames, tfSeconds, tfToUdfResolution, tickBandFor, timeframeAllowed, timeframeGroupUnit, timeframeLabel, timeframeOrder, timeframeSeconds, timezoneCity, timezoneLabel, timezoneListing, toolName, tzOffsetLabel, tzOffsetMinutes, udfPriceFormat, udfResolutionToTf, udfSymbolInfo, valueShaped, withFoldedHistory, zoneClock, zoomedBarSpacing };
5514
+ export { ARRANGEMENTS, type AccessPolicy, type ActiveSubsession, type Arrangement, type AttachDrawingsOptions, BRAND_DOWN, BRAND_UP, BUILT_IN_INDICATORS, BUILT_IN_LOCALES, type BarMark, type BarsEvent, type BuiltInIndicator, CHART_ICON_IDS, CHART_STYLES, COLLAPSED_H, COMPARE_COLORS, type CanvasTheme, type Capabilities, ChartBody, type ChartChrome, type ChartCompareApi, type ChartCustomLocale, type ChartDatafeed, type ChartDictionary, type ChartDrawingsApi, type ChartEvents, type ChartExtension, type ChartExtensionChart, type ChartExtensionCommand, type ChartExtensionContext, type ChartExtensionHandle, type ChartExtensionIcon, type ChartExtensionIconPath, type ChartExtensionMenuContext, type ChartExtensionMenuItem, type ChartExtensionMenuProvider, type ChartExtensionPane, type ChartExtensionPriceLine, type ChartExtensionReplayState, type ChartExtensionScope, type ChartExtensionSeries, type ChartHandle, type ChartHistoryApi, type ChartI18n, type ChartI18nOptions, type ChartIconContext, type ChartIconDiagnostic, type ChartIconFactory, type ChartIconFailure, type ChartIconId, type ChartIcons, type ChartLegendRow, type ChartLocale, type ChartLocaleCode, type ChartMenuAction, type ChartMenuContext, type ChartMenuIcon, type ChartMenuRow, ChartMessageKey, ChartMeta, type ChartOverrides, type ChartPaneSyncApi, type ChartPreferences, type ChartPriceFormatter, type ChartReplayApi, ChartSaveLoadAdapter, type ChartSaveLoadApi, type ChartStorage, type ChartStyleId, type ChartTimezone, type ChartTranslate, type ChartWidget, type ChartWidgetOptions, type CommandRegistry, type CommandResult, type CommandScope, type CommandSpec, type CompareDeps, type CompareEntry, type CompareHandle, type ComparePlacement, type CompareSnapshot, type CompareSymbol, type ContextMenuHandle, type CustomThemes, DEFAULT_OVERRIDES, DEFAULT_SUBSESSION, DEFAULT_TIMEZONE, type DataStatus, type DatafeedConfig, type DrawingApplyOutcome, DrawingAssetPort, DrawingContextKind, type DrawingDocumentApi, type DrawingDocumentPort, type DrawingDocumentRefusal, type DrawingEvent, type DrawingOwner, DrawingPreferences, type DrawingPresets, type DrawingReadOutcome, type DrawingRejection, type DrawingRejectionReason, DrawingResourceContext, DrawingsBody, type DrawingsEvents, type DrawingsHandle, DrawingsMeta, type DrawingsWorkflow, EXCHANGE_TIMEZONE, type FeatureConfig, type FeedBar, FeedUnavailableError, type FetchLike, FillBetweenPrimitive, type FullscreenApi, type FullscreenOptions, type HistoryChange, type HistoryEventState, type HistoryPage, IMAGE_HEADER_H, type ImageApi, type ImageEvent, type ImageHeader, type ImageOptions, type ImageTextRun, type ImageTile, type IndicatorCategory, type IndicatorDefinition, type IndicatorEvent, type IndicatorFill, type IndicatorInstance, type IndicatorLevel, type IndicatorManifest, type IndicatorOverrides, type IndicatorPickerAction, type IndicatorPickerBuiltInState, type IndicatorPickerCollection, type IndicatorPickerItem, type IndicatorPickerSource, type IndicatorPlot, type IndicatorPlots, type IndicatorsApi, type IndicatorsRenderer, LAYOUT_MENU_ROWS, type LayoutApi, LayoutBody, type LayoutEvent, LayoutMeta, type LayoutOptions, type LayoutSaveLoadApi, type LayoutSyncFlags, type LegendUi, type LogicalRange, MAIN_MIN_H, MIN_BAR_SPACING, MIRRORED_ICONS, type ManifestFill, type ManifestInput, type ManifestLevel, type ManifestPlot, type ManifestRun, type MarkColorRole, type MarkPainters, type MarkPlacement, type MarkShape, type MarketStatus, type MatchSegment, type MountedSymbolSearch, type NumericPunctuation, type OlderPageVerdict, type OpenResource, PRICE_SCALE_MODE, type PaneOp, type PanePlan, type PaneRect, type PaneState, type PartialOverrides, type PlacedImage, type PlotPoint, type PriceFormat, type PriceFormatter, type PriceFormatterOptions, type ProviderMarkPainter, RANGE_PRESETS, RECENT_SYMBOLS_CAP, REPLAY_SPEEDS, type RangeFrameTarget, type RangePreset, type RangeSpan, type RecentsPort, type ReplayEventState, type ReplaySpeed, type ResourceLoadOutcome, ResourceRef, type ResourceRemoveOutcome, type ResourceSaveOutcome, ResourceStore, SCALE_MODES, SCALE_MODE_OPTIONS, SCROLL_STEP_BARS, SESSION_DOT, SESSION_LABEL, SESSION_STATE_TITLE, SPREAD_OPERATORS, type SaveConflictInfo, type ScaleMode, type SearchController, type SearchControllerOptions, type SearchPage, type SearchScope, type SearchState, type SelectedDrawing, type SemanticTheme, type SessionBandsPrimitive, type SessionModel, type SessionSchedule, type SessionSegment, type SessionSource, type SessionState, type SessionTimeline, type SettingsMenuUi, ShadePrimitive, type SpreadOperator, type SubscribeHandlers, type Subsession, type SubsessionId, type SubsessionSource, type SymbolInfo, type SymbolMarkPainter, type SymbolNames, type SymbolPriceFormat, type SymbolRow, type SymbolSearchCache, type SymbolSearchHandle, type SymbolSearchOptions, THEME_ROLES, TIMEFRAME_MAX, TIMEFRAME_PRESETS, TIMEFRAME_PRESET_TOKENS, TIMEFRAME_UNITS, TIMEFRAME_UNIT_NAME, TIMEFRAME_UNIT_SECONDS, TIMEZONES, TOP_BAR_SLOTS, TemplateBody, TemplateMeta, type TextEditSession, type ThemeChangeListener, type ThemeController, type ThemeControllerOptions, type ThemeDeclaration, type ThemeDiagnostic, type ThemeDiagnosticCode, type ThemeMode, type ThemeOptions, type ThemeRole, type ThemeRoleFamily, type ThemeRoleId, type ThemeRoleKind, type ThemeRootStyle, type TickBand, type TimeRange, type Timeframe, type TimeframeGroup, type TimeframeRestrictions, type TimeframeUnit, type TimescaleMark, type TimezoneRow, type ToolbarButton, type ToolbarButtonOptions, type ToolbarButtonState, type TopBarSlot, type TopBarUi, type UdfDatafeedOptions, type UdfSymbolResponse, type UiConfig, type VenueMarkPainter, type WidgetEvents, ZOOM_FACTOR, type ZoneClock, allowedTimeframes, applyBar, applyPlotOverrides, arrangementName, arrangementOf, attachCompare, attachDrawings, attachIndicators, autoIntervalFor, buildManifestPlots, canvasTheme, canvasToBlob, chartContextMenu, chartDictionaries, clipToWindow, coerceChartStyle, coerceScaleMode, compareTimeframes, composeFormingBar, composeImage, createChart, createChartI18n, createPriceFormatter, createSearchController, createSessionBands, createSymbolSearchCache, createThemeController, createUdfDatafeed, effectivePlotColor, exchangeTimezoneText, formatClock, formatDuration, formatTimeframe, frameRange, hasExtendedHours, imageFileName, imageHeaderRuns, imageLayoutHeaderRuns, imageTileRuns, indicatorHidden, isChartStyle, isCollapsed, isIntradayTimeframe, isSymbolPair, isTimezoneChoice, latestPlotValue, layerOverrides, looksLikeSpread, makeCrosshairTimeFormatter, makeTickMarkFormatter, manifestInputDefaults, marketStatus, marketStatusFor, marketStatusText, marketStatusTitle, matchSegments, memoryChartStorage, memoryRecents, mergeOverrides, mountContextMenu, mountSymbolSearch, nextSessionChange, olderPageVerdict, openInputsEditor, openSymbolSearch, overriddenManifest, parseSessionModel, parseTickBands, parseTimeframe, pickCompareColor, placeableByWidget, planPaneOp, promoteRecent, rangeAvailable, rangePresetTip, rangeSpanSeconds, resolveDisplayTimezone, resolveInitialTf, scrolledPosition, seriesTargetOf, sessionStateAt, sessionTimeline, spreadExpression, spreadSearchQuery, subIntervalsFor, subsessionBarFilter, symbolNames, tfSeconds, tfToUdfResolution, tickBandFor, timeframeAllowed, timeframeGroupUnit, timeframeLabel, timeframeOrder, timeframeSeconds, timezoneCity, timezoneLabel, timezoneListing, toolName, tzOffsetLabel, tzOffsetMinutes, udfPriceFormat, udfResolutionToTf, udfSymbolInfo, valueShaped, withFoldedHistory, zoneClock, zoomedBarSpacing };