react-klinecharts-ui 1.0.0 → 1.1.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.cjs CHANGED
@@ -1,32 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunkLGYYJ2GP_cjs = require('./chunk-LGYYJ2GP.cjs');
3
+ var chunkSZDU2D3D_cjs = require('./chunk-SZDU2D3D.cjs');
4
+ var chunkF24D6PWY_cjs = require('./chunk-F24D6PWY.cjs');
5
+ require('./chunk-Q7SFCCGT.cjs');
4
6
  var react = require('react');
5
7
  var klinecharts = require('klinecharts');
6
8
  var jsxRuntime = require('react/jsx-runtime');
7
9
 
8
- var KlinechartsUIStateContext = react.createContext(null);
9
- var KlinechartsUIDispatchContext = react.createContext(null);
10
- function useKlinechartsUIDispatch() {
11
- const ctx = react.useContext(KlinechartsUIDispatchContext);
12
- if (!ctx) {
13
- throw new Error(
14
- "useKlinechartsUI must be used within a <KlinechartsUIProvider>"
15
- );
16
- }
17
- return ctx;
18
- }
19
- function useKlinechartsUI() {
20
- const state = react.useContext(KlinechartsUIStateContext);
21
- const dispatch = react.useContext(KlinechartsUIDispatchContext);
22
- if (!state || !dispatch) {
23
- throw new Error(
24
- "useKlinechartsUI must be used within a <KlinechartsUIProvider>"
25
- );
26
- }
27
- return { state, ...dispatch };
28
- }
29
-
30
10
  // src/data/periods.ts
31
11
  var DEFAULT_PERIODS = [
32
12
  { span: 1, type: "minute", label: "1m" },
@@ -40,6 +20,50 @@ var DEFAULT_PERIODS = [
40
20
  { span: 1, type: "month", label: "M" },
41
21
  { span: 1, type: "year", label: "Y" }
42
22
  ];
23
+
24
+ // src/storage/types.ts
25
+ var DEFAULT_STORAGE_NAMESPACES = [
26
+ "alerts",
27
+ "settings",
28
+ "indicators"
29
+ ];
30
+ var DEFAULT_STORAGE_KEY_PREFIX = "rkui:";
31
+
32
+ // src/storage/createDefaultStorage.ts
33
+ var NOOP_ADAPTER = {
34
+ getItem: () => null,
35
+ setItem: () => {
36
+ },
37
+ removeItem: () => {
38
+ }
39
+ };
40
+ function createDefaultStorage() {
41
+ if (typeof localStorage === "undefined") return NOOP_ADAPTER;
42
+ try {
43
+ const probe = localStorage.getItem("__rkui_probe__");
44
+ return probe === null ? localStorage : localStorage;
45
+ } catch {
46
+ return NOOP_ADAPTER;
47
+ }
48
+ }
49
+ function resolveStorage(options) {
50
+ const adapter = options?.adapter ?? createDefaultStorage();
51
+ const keyPrefix = options?.keyPrefix ?? DEFAULT_STORAGE_KEY_PREFIX;
52
+ const namespaces = new Set(
53
+ options?.namespaces ?? DEFAULT_STORAGE_NAMESPACES
54
+ );
55
+ return {
56
+ adapter,
57
+ namespaces,
58
+ keyPrefix,
59
+ key(namespace) {
60
+ return `${keyPrefix}${namespace}`;
61
+ },
62
+ persists(namespace) {
63
+ return namespaces.has(namespace);
64
+ }
65
+ };
66
+ }
43
67
  function reducer(state, action) {
44
68
  switch (action.type) {
45
69
  case "SET_CHART":
@@ -103,13 +127,16 @@ function KlinechartsUIProvider({
103
127
  defaultPeriod,
104
128
  defaultTheme = "light",
105
129
  defaultTimezone = "Asia/Shanghai",
106
- defaultMainIndicators = ["MA"],
107
- defaultSubIndicators = ["VOL"],
130
+ // NOTE: no destructuring default here — the init function must distinguish
131
+ // "consumer passed default*" (wins) from "use stored value" (hydrate).
132
+ defaultMainIndicators,
133
+ defaultSubIndicators,
108
134
  defaultLocale = "en-US",
109
135
  periods,
110
136
  styles,
111
137
  registerExtensions: shouldRegister = true,
112
138
  overlays: extraOverlays,
139
+ storage: storageOptions,
113
140
  children,
114
141
  onStateChange,
115
142
  onSymbolChange,
@@ -120,6 +147,11 @@ function KlinechartsUIProvider({
120
147
  onSubIndicatorsChange,
121
148
  onSettingsChange
122
149
  }) {
150
+ const resolvedStorage = react.useMemo(
151
+ () => storageOptions ? resolveStorage(storageOptions) : null,
152
+ // eslint-disable-next-line react-hooks/exhaustive-deps
153
+ []
154
+ );
123
155
  const [state, dispatch] = react.useReducer(
124
156
  reducer,
125
157
  {
@@ -132,41 +164,61 @@ function KlinechartsUIProvider({
132
164
  defaultSubIndicators,
133
165
  defaultLocale,
134
166
  periods,
135
- styles
136
- },
137
- (opts) => ({
138
- chart: null,
139
- datafeed: opts.datafeed,
140
- symbol: opts.defaultSymbol ?? null,
141
- period: opts.defaultPeriod ?? (opts.periods ?? DEFAULT_PERIODS)[0],
142
- theme: opts.defaultTheme ?? "light",
143
- timezone: opts.defaultTimezone ?? "Asia/Shanghai",
144
- isLoading: false,
145
- locale: opts.defaultLocale ?? "en-US",
146
- periods: opts.periods ?? DEFAULT_PERIODS,
147
- mainIndicators: opts.defaultMainIndicators ?? ["MA"],
148
- subIndicators: (opts.defaultSubIndicators ?? ["VOL"]).reduce(
149
- (acc, name) => ({ ...acc, [name]: "" }),
150
- {}
151
- ),
152
- indicatorAxes: {},
153
- indicatorVisibility: {},
154
- alerts: [],
155
- measure: { isActive: false, fromPoint: null, result: null },
156
- replay: {
157
- isReplaying: false,
158
- isPaused: false,
159
- speed: 1,
160
- barIndex: 0,
161
- totalBars: 0
162
- },
163
- styles: opts.styles,
164
- screenshotUrl: null
165
- })
167
+ styles,
168
+ storage: resolvedStorage
169
+ },
170
+ (opts) => {
171
+ const s = opts.storage;
172
+ const read = (ns, fallback) => {
173
+ if (!s || !s.persists(ns)) return fallback;
174
+ try {
175
+ const raw = s.adapter.getItem(s.key(ns));
176
+ return raw ? JSON.parse(raw) : fallback;
177
+ } catch {
178
+ return fallback;
179
+ }
180
+ };
181
+ const storedIndicators = read("indicators", {});
182
+ return {
183
+ chart: null,
184
+ datafeed: opts.datafeed,
185
+ symbol: opts.defaultSymbol ?? null,
186
+ period: opts.defaultPeriod ?? (opts.periods ?? DEFAULT_PERIODS)[0],
187
+ theme: opts.defaultTheme ?? "light",
188
+ timezone: opts.defaultTimezone ?? "Asia/Shanghai",
189
+ isLoading: false,
190
+ locale: opts.defaultLocale ?? "en-US",
191
+ periods: opts.periods ?? DEFAULT_PERIODS,
192
+ // Persistence semantics: STORED values win over `default*` props —
193
+ // the user's saved configuration should survive reload even when the
194
+ // app passes defaults. Only when storage is empty/unconfigured do the
195
+ // `default*` props apply, falling back to the built-ins last.
196
+ // (Settings live in useKlinechartsUISettings useState and hydrate
197
+ // separately via the dispatch-context `storage`.)
198
+ mainIndicators: storedIndicators.main ?? opts.defaultMainIndicators ?? ["MA"],
199
+ subIndicators: storedIndicators.sub ?? (opts.defaultSubIndicators ? opts.defaultSubIndicators.reduce(
200
+ (acc, name) => ({ ...acc, [name]: "" }),
201
+ {}
202
+ ) : { VOL: "" }),
203
+ indicatorAxes: storedIndicators.axes ?? {},
204
+ indicatorVisibility: storedIndicators.visibility ?? {},
205
+ alerts: read("alerts", []),
206
+ measure: { isActive: false, fromPoint: null, result: null },
207
+ replay: {
208
+ isReplaying: false,
209
+ isPaused: false,
210
+ speed: 1,
211
+ barIndex: 0,
212
+ totalBars: 0
213
+ },
214
+ styles: opts.styles,
215
+ screenshotUrl: null
216
+ };
217
+ }
166
218
  );
167
219
  const fullscreenContainerRef = react.useRef(null);
168
220
  const undoRedoListenerRef = react.useRef(null);
169
- const alertTriggeredListenerRef = react.useRef(null);
221
+ const alertTriggeredListenersRef = react.useRef(/* @__PURE__ */ new Set());
170
222
  const replayIntervalRef = react.useRef(null);
171
223
  const replaySavedDataRef = react.useRef([]);
172
224
  const replayIndexRef = react.useRef(0);
@@ -230,7 +282,7 @@ function KlinechartsUIProvider({
230
282
  });
231
283
  react.useEffect(() => {
232
284
  if (shouldRegister) {
233
- chunkLGYYJ2GP_cjs.registerExtensions();
285
+ chunkSZDU2D3D_cjs.registerExtensions();
234
286
  }
235
287
  extraOverlaysRef.current?.forEach((overlay) => klinecharts.registerOverlay(overlay));
236
288
  }, [shouldRegister]);
@@ -244,23 +296,53 @@ function KlinechartsUIProvider({
244
296
  const chart = state.chart;
245
297
  if (!chart || !hasAlerts) return;
246
298
  alertPrevCloseRef.current = null;
299
+ const prevValueByAlert = /* @__PURE__ */ new Map();
247
300
  const interval = setInterval(() => {
248
301
  const dataList = chart.getDataList();
249
302
  if (!dataList || dataList.length === 0) return;
250
- const currentClose = dataList[dataList.length - 1].close;
251
- const prevClose = alertPrevCloseRef.current;
252
- alertPrevCloseRef.current = currentClose;
253
- if (prevClose === null) return;
303
+ const lastIdx = dataList.length - 1;
304
+ const indicatorCache = /* @__PURE__ */ new Map();
305
+ const readIndicatorValue = (indicatorId, figureKey) => {
306
+ const cacheKey = `${indicatorId}:${figureKey}`;
307
+ if (indicatorCache.has(cacheKey)) return indicatorCache.get(cacheKey);
308
+ let value = null;
309
+ try {
310
+ const indicators2 = chart.getIndicators({ id: indicatorId });
311
+ const ind = indicators2?.[0];
312
+ const result = ind?.result;
313
+ const last = Array.isArray(result) ? result[lastIdx] : null;
314
+ if (last && typeof last === "object") {
315
+ const v = last[figureKey];
316
+ value = typeof v === "number" ? v : null;
317
+ }
318
+ } catch {
319
+ value = null;
320
+ }
321
+ indicatorCache.set(cacheKey, value);
322
+ return value;
323
+ };
254
324
  const alerts = stateRef.current.alerts;
255
325
  const triggeredIds = [];
256
326
  for (const alert of alerts) {
257
327
  if (alert.triggered) continue;
258
- const crossedUp = prevClose < alert.price && currentClose >= alert.price;
259
- const crossedDown = prevClose > alert.price && currentClose <= alert.price;
328
+ const target = alert.target ?? { type: "price" };
329
+ let currentValue;
330
+ if (target.type === "indicator") {
331
+ currentValue = readIndicatorValue(target.indicatorId, target.figureKey);
332
+ } else {
333
+ currentValue = dataList[lastIdx].close;
334
+ }
335
+ if (currentValue === null || !Number.isFinite(currentValue)) continue;
336
+ const prevValue = prevValueByAlert.get(alert.id) ?? null;
337
+ prevValueByAlert.set(alert.id, currentValue);
338
+ if (prevValue === null) continue;
339
+ const crossedUp = prevValue < alert.price && currentValue >= alert.price;
340
+ const crossedDown = prevValue > alert.price && currentValue <= alert.price;
260
341
  const shouldTrigger = alert.condition === "crossing_up" ? crossedUp : alert.condition === "crossing_down" ? crossedDown : crossedUp || crossedDown;
261
342
  if (shouldTrigger) {
262
343
  triggeredIds.push(alert.id);
263
- alertTriggeredListenerRef.current?.({ ...alert, triggered: true });
344
+ const fired = { ...alert, triggered: true };
345
+ alertTriggeredListenersRef.current.forEach((cb) => cb(fired));
264
346
  }
265
347
  }
266
348
  if (triggeredIds.length > 0) {
@@ -275,6 +357,36 @@ function KlinechartsUIProvider({
275
357
  react.useEffect(() => {
276
358
  alertPrevCloseRef.current = null;
277
359
  }, [state.symbol, state.period]);
360
+ const writeNs = react.useCallback(
361
+ (ns, value) => {
362
+ if (!resolvedStorage || !resolvedStorage.persists(ns)) return;
363
+ try {
364
+ resolvedStorage.adapter.setItem(
365
+ resolvedStorage.key(ns),
366
+ JSON.stringify(value)
367
+ );
368
+ } catch {
369
+ }
370
+ },
371
+ [resolvedStorage]
372
+ );
373
+ react.useEffect(() => {
374
+ writeNs("alerts", state.alerts);
375
+ }, [state.alerts, writeNs]);
376
+ react.useEffect(() => {
377
+ writeNs("indicators", {
378
+ main: state.mainIndicators,
379
+ sub: state.subIndicators,
380
+ axes: state.indicatorAxes,
381
+ visibility: state.indicatorVisibility
382
+ });
383
+ }, [
384
+ state.mainIndicators,
385
+ state.subIndicators,
386
+ state.indicatorAxes,
387
+ state.indicatorVisibility,
388
+ writeNs
389
+ ]);
278
390
  react.useEffect(() => {
279
391
  return () => {
280
392
  if (replayIntervalRef.current !== null) {
@@ -290,18 +402,19 @@ function KlinechartsUIProvider({
290
402
  onSettingsChange: onSettingsChangeRef.current,
291
403
  fullscreenContainerRef,
292
404
  undoRedoListenerRef,
293
- alertTriggeredListenerRef,
405
+ alertTriggeredListenersRef,
294
406
  replayIntervalRef,
295
407
  replaySavedDataRef,
296
- replayIndexRef
408
+ replayIndexRef,
409
+ storage: resolvedStorage
297
410
  }),
298
411
  // eslint-disable-next-line react-hooks/exhaustive-deps
299
- [enhancedDispatch]
412
+ [enhancedDispatch, resolvedStorage]
300
413
  );
301
- return /* @__PURE__ */ jsxRuntime.jsx(KlinechartsUIStateContext.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(KlinechartsUIDispatchContext.Provider, { value: dispatchValue, children }) });
414
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkF24D6PWY_cjs.KlinechartsUIStateContext.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(chunkF24D6PWY_cjs.KlinechartsUIDispatchContext.Provider, { value: dispatchValue, children }) });
302
415
  }
303
416
  function useKlinechartsUITheme() {
304
- const { state, dispatch } = useKlinechartsUI();
417
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
305
418
  const setTheme = react.useCallback(
306
419
  (theme) => {
307
420
  state.chart?.setStyles(theme);
@@ -322,11 +435,11 @@ function useKlinechartsUITheme() {
322
435
 
323
436
  // src/hooks/useKlinechartsUILoading.ts
324
437
  function useKlinechartsUILoading() {
325
- const { state } = useKlinechartsUI();
438
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
326
439
  return { isLoading: state.isLoading };
327
440
  }
328
441
  function usePeriods() {
329
- const { state, dispatch } = useKlinechartsUI();
442
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
330
443
  const setPeriod = react.useCallback(
331
444
  (period) => {
332
445
  dispatch({ type: "SET_PERIOD", period });
@@ -364,7 +477,7 @@ var TIMEZONES = [
364
477
 
365
478
  // src/hooks/useTimezone.ts
366
479
  function useTimezone() {
367
- const { state, dispatch } = useKlinechartsUI();
480
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
368
481
  const timezones = react.useMemo(
369
482
  () => TIMEZONES.map((tz) => ({
370
483
  key: tz.key,
@@ -386,7 +499,7 @@ function useTimezone() {
386
499
  };
387
500
  }
388
501
  function useSymbolSearch(debounceMs = 300) {
389
- const { state, dispatch, datafeed } = useKlinechartsUI();
502
+ const { state, dispatch, datafeed } = chunkF24D6PWY_cjs.useKlinechartsUI();
390
503
  const [query, setQueryState] = react.useState("");
391
504
  const [results, setResults] = react.useState([]);
392
505
  const [isSearching, setIsSearching] = react.useState(false);
@@ -748,8 +861,8 @@ var INDICATOR_PARAMS = {
748
861
  // src/hooks/useIndicators.ts
749
862
  var COLLAPSED_HEIGHT = 30;
750
863
  function useIndicators() {
751
- const { state, dispatch } = useKlinechartsUI();
752
- const { undoRedoListenerRef } = useKlinechartsUIDispatch();
864
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
865
+ const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
753
866
  const paneHeightsRef = react.useRef({});
754
867
  const collapsedPanesRef = react.useRef(/* @__PURE__ */ new Set());
755
868
  const mainIndicators = react.useMemo(() => {
@@ -1246,8 +1359,8 @@ var DRAWING_CATEGORIES = [
1246
1359
  // src/hooks/useDrawingTools.ts
1247
1360
  var DRAWING_GROUP_ID = "drawing_tools";
1248
1361
  function useDrawingTools() {
1249
- const { state } = useKlinechartsUI();
1250
- const { undoRedoListenerRef } = useKlinechartsUIDispatch();
1362
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
1363
+ const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
1251
1364
  const [activeTool, setActiveTool] = react.useState(null);
1252
1365
  const [magnetMode, setMagnetModeState] = react.useState("normal");
1253
1366
  const [isLocked, setIsLocked] = react.useState(false);
@@ -1437,8 +1550,18 @@ var defaultSettings = {
1437
1550
  tooltipShowRule: "always"
1438
1551
  };
1439
1552
  function useKlinechartsUISettings() {
1440
- const { state, onSettingsChange } = useKlinechartsUI();
1441
- const [settings, setSettings] = react.useState(defaultSettings);
1553
+ const { state, onSettingsChange } = chunkF24D6PWY_cjs.useKlinechartsUI();
1554
+ const { storage } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
1555
+ const [settings, setSettings] = react.useState(() => {
1556
+ if (storage && storage.persists("settings")) {
1557
+ try {
1558
+ const raw = storage.adapter.getItem(storage.key("settings"));
1559
+ if (raw) return { ...defaultSettings, ...JSON.parse(raw) };
1560
+ } catch {
1561
+ }
1562
+ }
1563
+ return defaultSettings;
1564
+ });
1442
1565
  const isInitialMount = react.useRef(true);
1443
1566
  react.useEffect(() => {
1444
1567
  if (isInitialMount.current) {
@@ -1447,6 +1570,14 @@ function useKlinechartsUISettings() {
1447
1570
  }
1448
1571
  onSettingsChange?.({ ...settings });
1449
1572
  }, [settings, onSettingsChange]);
1573
+ react.useEffect(() => {
1574
+ if (!storage || !storage.persists("settings")) return;
1575
+ if (isInitialMount.current) return;
1576
+ try {
1577
+ storage.adapter.setItem(storage.key("settings"), JSON.stringify(settings));
1578
+ } catch {
1579
+ }
1580
+ }, [settings, storage]);
1450
1581
  const candleTypes = react.useMemo(
1451
1582
  () => CANDLE_TYPES.map((ct) => ({
1452
1583
  key: ct.key,
@@ -1688,7 +1819,7 @@ function useKlinechartsUISettings() {
1688
1819
  };
1689
1820
  }
1690
1821
  function useScreenshot() {
1691
- const { state, dispatch } = useKlinechartsUI();
1822
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
1692
1823
  const capture = react.useCallback(() => {
1693
1824
  if (!state.chart) return;
1694
1825
  const url = state.chart.getConvertPictureUrl(true, "jpeg", state.theme === "dark" ? "#151517" : "#ffffff");
@@ -1717,7 +1848,7 @@ function useScreenshot() {
1717
1848
  };
1718
1849
  }
1719
1850
  function useHotkeys() {
1720
- const { state } = useKlinechartsUI();
1851
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
1721
1852
  const registerHotkey = react.useCallback((template) => {
1722
1853
  klinecharts.registerHotkey(template);
1723
1854
  }, []);
@@ -1746,7 +1877,7 @@ function useHotkeys() {
1746
1877
  };
1747
1878
  }
1748
1879
  function useChartAxes() {
1749
- const { state } = useKlinechartsUI();
1880
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
1750
1881
  const overrideXAxis = react.useCallback(
1751
1882
  (override) => {
1752
1883
  if (!state.chart) return;
@@ -1764,7 +1895,7 @@ function useChartAxes() {
1764
1895
  return { overrideXAxis, overrideYAxis };
1765
1896
  }
1766
1897
  function useFullscreen() {
1767
- const { fullscreenContainerRef } = useKlinechartsUIDispatch();
1898
+ const { fullscreenContainerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
1768
1899
  const [isFullscreen, setIsFullscreen] = react.useState(false);
1769
1900
  const enter = react.useCallback(() => {
1770
1901
  const el = fullscreenContainerRef.current;
@@ -1819,7 +1950,7 @@ function useFullscreen() {
1819
1950
  };
1820
1951
  }
1821
1952
  function useOrderLines() {
1822
- const { state } = useKlinechartsUI();
1953
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
1823
1954
  const callbacksRef = react.useRef(/* @__PURE__ */ new Map());
1824
1955
  const ownedIdsRef = react.useRef(/* @__PURE__ */ new Set());
1825
1956
  const createOrderLine = react.useCallback(
@@ -1916,8 +2047,8 @@ function useOrderLines() {
1916
2047
  }
1917
2048
  var DRAWING_GROUP_ID2 = "drawing_tools";
1918
2049
  function useUndoRedo() {
1919
- const { state, dispatch } = useKlinechartsUI();
1920
- const { undoRedoListenerRef } = useKlinechartsUIDispatch();
2050
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
2051
+ const { undoRedoListenerRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
1921
2052
  const [undoStack, setUndoStack] = react.useState([]);
1922
2053
  const [redoStack, setRedoStack] = react.useState([]);
1923
2054
  const isProcessingRef = react.useRef(false);
@@ -2259,7 +2390,7 @@ function getEntry(id) {
2259
2390
  }
2260
2391
  }
2261
2392
  function useLayoutManager() {
2262
- const { state, dispatch } = useKlinechartsUI();
2393
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
2263
2394
  const [layouts, setLayouts] = react.useState(
2264
2395
  () => getLayoutIds().map((id) => getEntry(id)).filter((e) => e !== null)
2265
2396
  );
@@ -2563,7 +2694,7 @@ var SHADOW_KEYS = [
2563
2694
  ];
2564
2695
  var scriptCounter = 0;
2565
2696
  function useScriptEditor() {
2566
- const { state } = useKlinechartsUI();
2697
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
2567
2698
  const [code, setCode] = react.useState(DEFAULT_SCRIPT);
2568
2699
  const [scriptName, setScriptName] = react.useState("");
2569
2700
  const [params, setParams] = react.useState("14");
@@ -2600,7 +2731,7 @@ ${code}`
2600
2731
  const shadowValues = SHADOW_KEYS.map(() => void 0);
2601
2732
  const sampleResult = compiledFn(
2602
2733
  ...shadowValues,
2603
- chunkLGYYJ2GP_cjs.TA_default,
2734
+ chunkSZDU2D3D_cjs.TA_default,
2604
2735
  dataList,
2605
2736
  parsedParams
2606
2737
  );
@@ -2627,7 +2758,7 @@ ${code}`
2627
2758
  shortName: (scriptName.trim() || `Script #${scriptCounter}`) + (placement === "main" ? " (Main)" : " (Sub)"),
2628
2759
  calcParams: parsedParams,
2629
2760
  figures,
2630
- calc: (liveDataList) => compiledFn(...shadowValues, chunkLGYYJ2GP_cjs.TA_default, liveDataList, parsedParams),
2761
+ calc: (liveDataList) => compiledFn(...shadowValues, chunkSZDU2D3D_cjs.TA_default, liveDataList, parsedParams),
2631
2762
  extendData: {
2632
2763
  isCustomScript: true,
2633
2764
  code,
@@ -2738,7 +2869,7 @@ ${code}`
2738
2869
  };
2739
2870
  }
2740
2871
  function useCrosshair() {
2741
- const { state } = useKlinechartsUI();
2872
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
2742
2873
  const [barData, setBarData] = react.useState(null);
2743
2874
  const rafRef = react.useRef(0);
2744
2875
  const handler = react.useCallback(
@@ -2788,11 +2919,11 @@ function useCrosshair() {
2788
2919
  }
2789
2920
  var alertCounter = 0;
2790
2921
  function useAlerts() {
2791
- const { state, dispatch } = useKlinechartsUI();
2792
- const { alertTriggeredListenerRef } = useKlinechartsUIDispatch();
2922
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
2923
+ const { alertTriggeredListenersRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
2793
2924
  const alerts = state.alerts;
2794
2925
  const addAlert = react.useCallback(
2795
- (price, condition, message, extendData) => {
2926
+ (price, condition, message, extendData, target) => {
2796
2927
  const id = `alert_${++alertCounter}`;
2797
2928
  const precision = state.chart?.getSymbol()?.pricePrecision ?? 2;
2798
2929
  const resolvedExtendData = {
@@ -2805,11 +2936,14 @@ function useAlerts() {
2805
2936
  condition,
2806
2937
  message,
2807
2938
  triggered: false,
2808
- extendData: resolvedExtendData
2939
+ extendData: resolvedExtendData,
2940
+ // Persist the target only when it's an indicator alert; omit for the
2941
+ // default price target so existing serialized alerts stay compatible.
2942
+ ...target && target.type === "indicator" ? { target } : {}
2809
2943
  };
2810
2944
  dispatch({ type: "ADD_ALERT", alert });
2811
2945
  if (state.chart) {
2812
- chunkLGYYJ2GP_cjs.ensureAlertLineRegistered();
2946
+ chunkSZDU2D3D_cjs.ensureAlertLineRegistered();
2813
2947
  state.chart.createOverlay({
2814
2948
  name: "alertLine",
2815
2949
  id,
@@ -2836,9 +2970,13 @@ function useAlerts() {
2836
2970
  }, [state.chart, dispatch]);
2837
2971
  const onAlertTriggered = react.useCallback(
2838
2972
  (callback) => {
2839
- alertTriggeredListenerRef.current = callback;
2973
+ const set = alertTriggeredListenersRef.current;
2974
+ set.add(callback);
2975
+ return () => {
2976
+ set.delete(callback);
2977
+ };
2840
2978
  },
2841
- [alertTriggeredListenerRef]
2979
+ [alertTriggeredListenersRef]
2842
2980
  );
2843
2981
  return {
2844
2982
  alerts,
@@ -2849,7 +2987,7 @@ function useAlerts() {
2849
2987
  };
2850
2988
  }
2851
2989
  function useDataExport() {
2852
- const { state } = useKlinechartsUI();
2990
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
2853
2991
  const exportAll = react.useCallback(
2854
2992
  (format) => {
2855
2993
  if (!state.chart) return;
@@ -2915,8 +3053,8 @@ function downloadData(dataList, format, ticker) {
2915
3053
  URL.revokeObjectURL(url);
2916
3054
  }
2917
3055
  function useWatchlist() {
2918
- const { state } = useKlinechartsUI();
2919
- const { dispatch, datafeed } = useKlinechartsUIDispatch();
3056
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
3057
+ const { dispatch, datafeed } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
2920
3058
  const [items, setItems] = react.useState([]);
2921
3059
  const subscriptionsRef = react.useRef(/* @__PURE__ */ new Map());
2922
3060
  const activeSymbol = state.symbol?.ticker ?? null;
@@ -2985,8 +3123,8 @@ function useWatchlist() {
2985
3123
  };
2986
3124
  }
2987
3125
  function useReplay() {
2988
- const { state, dispatch } = useKlinechartsUI();
2989
- const { replayIntervalRef, replaySavedDataRef, replayIndexRef } = useKlinechartsUIDispatch();
3126
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
3127
+ const { replayIntervalRef, replaySavedDataRef, replayIndexRef } = chunkF24D6PWY_cjs.useKlinechartsUIDispatch();
2990
3128
  const { isReplaying, isPaused, speed, barIndex, totalBars } = state.replay;
2991
3129
  const clearInterval_ = react.useCallback(() => {
2992
3130
  if (replayIntervalRef.current !== null) {
@@ -3135,7 +3273,7 @@ var DEFAULT_COLORS = [
3135
3273
  "#8bc34a"
3136
3274
  ];
3137
3275
  function useCompare() {
3138
- const { state, datafeed } = useKlinechartsUI();
3276
+ const { state, datafeed } = chunkF24D6PWY_cjs.useKlinechartsUI();
3139
3277
  const [symbols, setSymbols] = react.useState([]);
3140
3278
  const indicatorsRef = react.useRef(/* @__PURE__ */ new Map());
3141
3279
  const instanceSalt = react.useId().replace(/[^a-zA-Z0-9]/g, "");
@@ -3281,7 +3419,7 @@ function computeResult(from, to) {
3281
3419
  return { from, to, priceDiff, pricePercent, bars, timeDiff };
3282
3420
  }
3283
3421
  function useMeasure() {
3284
- const { state, dispatch } = useKlinechartsUI();
3422
+ const { state, dispatch } = chunkF24D6PWY_cjs.useKlinechartsUI();
3285
3423
  const { isActive, fromPoint, result } = state.measure;
3286
3424
  const cleanup = react.useCallback(() => {
3287
3425
  state.chart?.removeOverlay({ id: MEASURE_OVERLAY_ID });
@@ -3362,7 +3500,7 @@ function useMeasure() {
3362
3500
  }
3363
3501
  var annotationCounter = 0;
3364
3502
  function useAnnotations() {
3365
- const { state } = useKlinechartsUI();
3503
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
3366
3504
  const [annotations, setAnnotations] = react.useState([]);
3367
3505
  const addAnnotation = react.useCallback(
3368
3506
  (text, price, timestamp, color) => {
@@ -3442,265 +3580,375 @@ function useAnnotations() {
3442
3580
  clearAnnotations
3443
3581
  };
3444
3582
  }
3583
+ var WorkspaceContext = react.createContext(null);
3584
+ function useWorkspace() {
3585
+ const ctx = react.useContext(WorkspaceContext);
3586
+ if (!ctx) {
3587
+ throw new Error("useWorkspace must be used within a <WorkspaceProvider>");
3588
+ }
3589
+ return ctx;
3590
+ }
3445
3591
 
3446
- // src/utils/createDataLoader.ts
3447
- function createDataLoader(datafeed, dispatch) {
3448
- let oldestTimestamp = null;
3449
- let currentGen = 0;
3450
- return {
3451
- getBars: async (params) => {
3592
+ // src/workspace/types.ts
3593
+ var DEFAULT_SYNC_CONFIG = {
3594
+ crosshair: true,
3595
+ scroll: true,
3596
+ zoom: true,
3597
+ symbol: true,
3598
+ period: true
3599
+ };
3600
+ function reducer2(state, action) {
3601
+ switch (action.type) {
3602
+ case "SET_CELLS":
3603
+ return { ...state, cells: action.cells };
3604
+ case "ADD_CELL":
3605
+ return { ...state, cells: [...state.cells, action.cell] };
3606
+ case "REMOVE_CELL": {
3607
+ const cells = state.cells.filter((c) => c.id !== action.id);
3608
+ return {
3609
+ cells,
3610
+ activeCellId: state.activeCellId === action.id ? cells[0]?.id ?? null : state.activeCellId
3611
+ };
3612
+ }
3613
+ case "SET_CELL_SYMBOL":
3614
+ return {
3615
+ ...state,
3616
+ cells: state.cells.map(
3617
+ (c) => c.id === action.id ? { ...c, symbol: action.symbol } : c
3618
+ )
3619
+ };
3620
+ case "SET_CELL_PERIOD":
3621
+ return {
3622
+ ...state,
3623
+ cells: state.cells.map(
3624
+ (c) => c.id === action.id ? { ...c, period: action.period } : c
3625
+ )
3626
+ };
3627
+ case "SET_ACTIVE_CELL":
3628
+ return { ...state, activeCellId: action.id };
3629
+ default:
3630
+ return state;
3631
+ }
3632
+ }
3633
+ function WorkspaceProvider({
3634
+ defaultCells,
3635
+ sync,
3636
+ children
3637
+ }) {
3638
+ const [state, dispatch] = react.useReducer(reducer2, defaultCells, (cells) => ({
3639
+ cells,
3640
+ activeCellId: cells[0]?.id ?? null
3641
+ }));
3642
+ const chartsRef = react.useRef(/* @__PURE__ */ new Map());
3643
+ const broadcastingRef = react.useRef(false);
3644
+ const resolvedSync = react.useMemo(
3645
+ () => ({ ...DEFAULT_SYNC_CONFIG, ...sync }),
3646
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3647
+ []
3648
+ );
3649
+ const value = react.useMemo(
3650
+ () => ({
3651
+ state,
3652
+ dispatch,
3653
+ chartsRef,
3654
+ broadcastingRef,
3655
+ sync: resolvedSync
3656
+ }),
3657
+ [state, resolvedSync]
3658
+ );
3659
+ return /* @__PURE__ */ jsxRuntime.jsx(WorkspaceContext.Provider, { value, children });
3660
+ }
3661
+ function useChartSync({ cellId }) {
3662
+ const { chartsRef, broadcastingRef, sync, dispatch: workspaceDispatch } = useWorkspace();
3663
+ const { state } = chunkF24D6PWY_cjs.useKlinechartsUI();
3664
+ const chart = state.chart;
3665
+ react.useEffect(() => {
3666
+ if (!chart) return;
3667
+ chartsRef.current.set(cellId, chart);
3668
+ return () => {
3669
+ chartsRef.current.delete(cellId);
3670
+ };
3671
+ }, [chart, cellId, chartsRef]);
3672
+ react.useEffect(() => {
3673
+ if (!chart) return;
3674
+ const broadcast = (fn) => {
3675
+ if (broadcastingRef.current) return;
3676
+ broadcastingRef.current = true;
3452
3677
  try {
3453
- dispatch({ type: "SET_LOADING", isLoading: true });
3454
- if (params.type === "init") {
3455
- oldestTimestamp = null;
3456
- const gen = ++currentGen;
3457
- const data = await datafeed.getHistoryKLineData(
3458
- params.symbol,
3459
- { ...params.period, label: "" },
3460
- 0,
3461
- Date.now()
3462
- );
3463
- if (gen !== currentGen) return;
3464
- if (data.length > 0) {
3465
- oldestTimestamp = data[0].timestamp;
3466
- }
3467
- params.callback(data, {
3468
- forward: data.length > 0,
3469
- backward: false
3470
- });
3471
- } else if (params.type === "forward" && oldestTimestamp !== null) {
3472
- const gen = currentGen;
3473
- const data = await datafeed.getHistoryKLineData(
3474
- params.symbol,
3475
- { ...params.period, label: "" },
3476
- 0,
3477
- oldestTimestamp - 1
3478
- );
3479
- if (gen !== currentGen) return;
3480
- if (data.length > 0) {
3481
- oldestTimestamp = data[0].timestamp;
3678
+ chartsRef.current.forEach((target, id) => {
3679
+ if (id !== cellId) {
3680
+ try {
3681
+ fn(target);
3682
+ } catch {
3683
+ }
3482
3684
  }
3483
- params.callback(data, {
3484
- forward: data.length > 0,
3485
- backward: false
3486
- });
3487
- } else if (params.type === "backward") {
3488
- params.callback([], { forward: false, backward: false });
3489
- }
3490
- } catch (error) {
3491
- console.error("Failed to load chart data:", error);
3492
- params.callback([], { forward: false, backward: false });
3685
+ });
3493
3686
  } finally {
3494
- dispatch({ type: "SET_LOADING", isLoading: false });
3687
+ broadcastingRef.current = false;
3495
3688
  }
3496
- },
3497
- subscribeBar: (params) => {
3498
- datafeed.subscribe(
3499
- params.symbol,
3500
- { ...params.period, label: "" },
3501
- (klineData) => params.callback(klineData)
3689
+ };
3690
+ const onCrosshairChange = (data) => {
3691
+ if (!sync.crosshair) return;
3692
+ const crosshair = data;
3693
+ if (!crosshair) return;
3694
+ broadcast((target) => target.executeAction("onCrosshairChange", crosshair));
3695
+ };
3696
+ const onScroll = () => {
3697
+ if (!sync.scroll) return;
3698
+ let range = null;
3699
+ try {
3700
+ range = chart.getVisibleRange();
3701
+ } catch {
3702
+ return;
3703
+ }
3704
+ if (!range || range.realTo == null) return;
3705
+ broadcast(
3706
+ (target) => target.scrollToTimestamp(range.realTo, 0)
3502
3707
  );
3503
- },
3504
- unsubscribeBar: (params) => {
3505
- datafeed.unsubscribe(params.symbol, { ...params.period, label: "" });
3708
+ };
3709
+ const onZoom = () => {
3710
+ if (!sync.zoom) return;
3711
+ let bar = 0;
3712
+ try {
3713
+ bar = chart.getBarSpace().bar;
3714
+ } catch {
3715
+ return;
3716
+ }
3717
+ broadcast((target) => target.setBarSpace(bar));
3718
+ };
3719
+ chart.subscribeAction("onCrosshairChange", onCrosshairChange);
3720
+ chart.subscribeAction("onScroll", onScroll);
3721
+ chart.subscribeAction("onZoom", onZoom);
3722
+ return () => {
3723
+ chart.unsubscribeAction("onCrosshairChange", onCrosshairChange);
3724
+ chart.unsubscribeAction("onScroll", onScroll);
3725
+ chart.unsubscribeAction("onZoom", onZoom);
3726
+ };
3727
+ }, [chart, cellId, chartsRef, broadcastingRef, sync.crosshair, sync.scroll, sync.zoom]);
3728
+ react.useEffect(() => {
3729
+ if (state.symbol) {
3730
+ workspaceDispatch({ type: "SET_CELL_SYMBOL", id: cellId, symbol: state.symbol });
3506
3731
  }
3507
- };
3732
+ }, [state.symbol]);
3733
+ react.useEffect(() => {
3734
+ workspaceDispatch({ type: "SET_CELL_PERIOD", id: cellId, period: state.period });
3735
+ }, [state.period]);
3508
3736
  }
3509
3737
 
3510
3738
  Object.defineProperty(exports, "TA", {
3511
3739
  enumerable: true,
3512
- get: function () { return chunkLGYYJ2GP_cjs.TA_default; }
3740
+ get: function () { return chunkSZDU2D3D_cjs.TA_default; }
3513
3741
  });
3514
3742
  Object.defineProperty(exports, "abcd", {
3515
3743
  enumerable: true,
3516
- get: function () { return chunkLGYYJ2GP_cjs.abcd_default; }
3744
+ get: function () { return chunkSZDU2D3D_cjs.abcd_default; }
3517
3745
  });
3518
3746
  Object.defineProperty(exports, "alertLine", {
3519
3747
  enumerable: true,
3520
- get: function () { return chunkLGYYJ2GP_cjs.alertLine_default; }
3748
+ get: function () { return chunkSZDU2D3D_cjs.alertLine_default; }
3521
3749
  });
3522
3750
  Object.defineProperty(exports, "anyWaves", {
3523
3751
  enumerable: true,
3524
- get: function () { return chunkLGYYJ2GP_cjs.anyWaves_default; }
3752
+ get: function () { return chunkSZDU2D3D_cjs.anyWaves_default; }
3525
3753
  });
3526
3754
  Object.defineProperty(exports, "arrow", {
3527
3755
  enumerable: true,
3528
- get: function () { return chunkLGYYJ2GP_cjs.arrow_default; }
3756
+ get: function () { return chunkSZDU2D3D_cjs.arrow_default; }
3529
3757
  });
3530
3758
  Object.defineProperty(exports, "bollTv", {
3531
3759
  enumerable: true,
3532
- get: function () { return chunkLGYYJ2GP_cjs.bollTv_default; }
3760
+ get: function () { return chunkSZDU2D3D_cjs.bollTv_default; }
3533
3761
  });
3534
3762
  Object.defineProperty(exports, "brush", {
3535
3763
  enumerable: true,
3536
- get: function () { return chunkLGYYJ2GP_cjs.brush_default; }
3764
+ get: function () { return chunkSZDU2D3D_cjs.brush_default; }
3537
3765
  });
3538
3766
  Object.defineProperty(exports, "cci", {
3539
3767
  enumerable: true,
3540
- get: function () { return chunkLGYYJ2GP_cjs.cci_default; }
3768
+ get: function () { return chunkSZDU2D3D_cjs.cci_default; }
3541
3769
  });
3542
3770
  Object.defineProperty(exports, "circle", {
3543
3771
  enumerable: true,
3544
- get: function () { return chunkLGYYJ2GP_cjs.circle_default; }
3772
+ get: function () { return chunkSZDU2D3D_cjs.circle_default; }
3545
3773
  });
3546
3774
  Object.defineProperty(exports, "depthOverlay", {
3547
3775
  enumerable: true,
3548
- get: function () { return chunkLGYYJ2GP_cjs.depthOverlay_default; }
3776
+ get: function () { return chunkSZDU2D3D_cjs.depthOverlay_default; }
3549
3777
  });
3550
3778
  Object.defineProperty(exports, "eightWaves", {
3551
3779
  enumerable: true,
3552
- get: function () { return chunkLGYYJ2GP_cjs.eightWaves_default; }
3780
+ get: function () { return chunkSZDU2D3D_cjs.eightWaves_default; }
3553
3781
  });
3554
3782
  Object.defineProperty(exports, "elliottWave", {
3555
3783
  enumerable: true,
3556
- get: function () { return chunkLGYYJ2GP_cjs.elliottWave_default; }
3784
+ get: function () { return chunkSZDU2D3D_cjs.elliottWave_default; }
3557
3785
  });
3558
3786
  Object.defineProperty(exports, "fibRetracement", {
3559
3787
  enumerable: true,
3560
- get: function () { return chunkLGYYJ2GP_cjs.fibRetracement_default; }
3788
+ get: function () { return chunkSZDU2D3D_cjs.fibRetracement_default; }
3561
3789
  });
3562
3790
  Object.defineProperty(exports, "fibonacciCircle", {
3563
3791
  enumerable: true,
3564
- get: function () { return chunkLGYYJ2GP_cjs.fibonacciCircle_default; }
3792
+ get: function () { return chunkSZDU2D3D_cjs.fibonacciCircle_default; }
3565
3793
  });
3566
3794
  Object.defineProperty(exports, "fibonacciExtension", {
3567
3795
  enumerable: true,
3568
- get: function () { return chunkLGYYJ2GP_cjs.fibonacciExtension_default; }
3796
+ get: function () { return chunkSZDU2D3D_cjs.fibonacciExtension_default; }
3569
3797
  });
3570
3798
  Object.defineProperty(exports, "fibonacciSegment", {
3571
3799
  enumerable: true,
3572
- get: function () { return chunkLGYYJ2GP_cjs.fibonacciSegment_default; }
3800
+ get: function () { return chunkSZDU2D3D_cjs.fibonacciSegment_default; }
3573
3801
  });
3574
3802
  Object.defineProperty(exports, "fibonacciSpeedResistanceFan", {
3575
3803
  enumerable: true,
3576
- get: function () { return chunkLGYYJ2GP_cjs.fibonacciSpeedResistanceFan_default; }
3804
+ get: function () { return chunkSZDU2D3D_cjs.fibonacciSpeedResistanceFan_default; }
3577
3805
  });
3578
3806
  Object.defineProperty(exports, "fibonacciSpiral", {
3579
3807
  enumerable: true,
3580
- get: function () { return chunkLGYYJ2GP_cjs.fibonacciSpiral_default; }
3808
+ get: function () { return chunkSZDU2D3D_cjs.fibonacciSpiral_default; }
3581
3809
  });
3582
3810
  Object.defineProperty(exports, "fiveWaves", {
3583
3811
  enumerable: true,
3584
- get: function () { return chunkLGYYJ2GP_cjs.fiveWaves_default; }
3812
+ get: function () { return chunkSZDU2D3D_cjs.fiveWaves_default; }
3585
3813
  });
3586
3814
  Object.defineProperty(exports, "gannBox", {
3587
3815
  enumerable: true,
3588
- get: function () { return chunkLGYYJ2GP_cjs.gannBox_default; }
3816
+ get: function () { return chunkSZDU2D3D_cjs.gannBox_default; }
3589
3817
  });
3590
3818
  Object.defineProperty(exports, "gannFan", {
3591
3819
  enumerable: true,
3592
- get: function () { return chunkLGYYJ2GP_cjs.gannFan_default; }
3820
+ get: function () { return chunkSZDU2D3D_cjs.gannFan_default; }
3593
3821
  });
3594
3822
  Object.defineProperty(exports, "hma", {
3595
3823
  enumerable: true,
3596
- get: function () { return chunkLGYYJ2GP_cjs.hma_default; }
3824
+ get: function () { return chunkSZDU2D3D_cjs.hma_default; }
3597
3825
  });
3598
3826
  Object.defineProperty(exports, "ichimoku", {
3599
3827
  enumerable: true,
3600
- get: function () { return chunkLGYYJ2GP_cjs.ichimoku_default; }
3828
+ get: function () { return chunkSZDU2D3D_cjs.ichimoku_default; }
3601
3829
  });
3602
3830
  Object.defineProperty(exports, "indicators", {
3603
3831
  enumerable: true,
3604
- get: function () { return chunkLGYYJ2GP_cjs.indicators; }
3832
+ get: function () { return chunkSZDU2D3D_cjs.indicators; }
3605
3833
  });
3606
3834
  Object.defineProperty(exports, "longPosition", {
3607
3835
  enumerable: true,
3608
- get: function () { return chunkLGYYJ2GP_cjs.longPosition_default; }
3836
+ get: function () { return chunkSZDU2D3D_cjs.longPosition_default; }
3609
3837
  });
3610
3838
  Object.defineProperty(exports, "maRibbon", {
3611
3839
  enumerable: true,
3612
- get: function () { return chunkLGYYJ2GP_cjs.maRibbon_default; }
3840
+ get: function () { return chunkSZDU2D3D_cjs.maRibbon_default; }
3613
3841
  });
3614
3842
  Object.defineProperty(exports, "macdTv", {
3615
3843
  enumerable: true,
3616
- get: function () { return chunkLGYYJ2GP_cjs.macdTv_default; }
3844
+ get: function () { return chunkSZDU2D3D_cjs.macdTv_default; }
3617
3845
  });
3618
3846
  Object.defineProperty(exports, "measure", {
3619
3847
  enumerable: true,
3620
- get: function () { return chunkLGYYJ2GP_cjs.measure_default; }
3848
+ get: function () { return chunkSZDU2D3D_cjs.measure_default; }
3621
3849
  });
3622
3850
  Object.defineProperty(exports, "orderLine", {
3623
3851
  enumerable: true,
3624
- get: function () { return chunkLGYYJ2GP_cjs.orderLine_default; }
3852
+ get: function () { return chunkSZDU2D3D_cjs.orderLine_default; }
3625
3853
  });
3626
3854
  Object.defineProperty(exports, "overlays", {
3627
3855
  enumerable: true,
3628
- get: function () { return chunkLGYYJ2GP_cjs.overlays; }
3856
+ get: function () { return chunkSZDU2D3D_cjs.overlays; }
3629
3857
  });
3630
3858
  Object.defineProperty(exports, "parallelChannel", {
3631
3859
  enumerable: true,
3632
- get: function () { return chunkLGYYJ2GP_cjs.parallelChannel_default; }
3860
+ get: function () { return chunkSZDU2D3D_cjs.parallelChannel_default; }
3633
3861
  });
3634
3862
  Object.defineProperty(exports, "parallelogram", {
3635
3863
  enumerable: true,
3636
- get: function () { return chunkLGYYJ2GP_cjs.parallelogram_default; }
3864
+ get: function () { return chunkSZDU2D3D_cjs.parallelogram_default; }
3637
3865
  });
3638
3866
  Object.defineProperty(exports, "pivotPoints", {
3639
3867
  enumerable: true,
3640
- get: function () { return chunkLGYYJ2GP_cjs.pivotPoints_default; }
3868
+ get: function () { return chunkSZDU2D3D_cjs.pivotPoints_default; }
3641
3869
  });
3642
3870
  Object.defineProperty(exports, "ray", {
3643
3871
  enumerable: true,
3644
- get: function () { return chunkLGYYJ2GP_cjs.ray_default; }
3872
+ get: function () { return chunkSZDU2D3D_cjs.ray_default; }
3645
3873
  });
3646
3874
  Object.defineProperty(exports, "rect", {
3647
3875
  enumerable: true,
3648
- get: function () { return chunkLGYYJ2GP_cjs.rect_default; }
3876
+ get: function () { return chunkSZDU2D3D_cjs.rect_default; }
3649
3877
  });
3650
3878
  Object.defineProperty(exports, "registerExtensions", {
3651
3879
  enumerable: true,
3652
- get: function () { return chunkLGYYJ2GP_cjs.registerExtensions; }
3880
+ get: function () { return chunkSZDU2D3D_cjs.registerExtensions; }
3653
3881
  });
3654
3882
  Object.defineProperty(exports, "rsiTv", {
3655
3883
  enumerable: true,
3656
- get: function () { return chunkLGYYJ2GP_cjs.rsiTv_default; }
3884
+ get: function () { return chunkSZDU2D3D_cjs.rsiTv_default; }
3657
3885
  });
3658
3886
  Object.defineProperty(exports, "shortPosition", {
3659
3887
  enumerable: true,
3660
- get: function () { return chunkLGYYJ2GP_cjs.shortPosition_default; }
3888
+ get: function () { return chunkSZDU2D3D_cjs.shortPosition_default; }
3661
3889
  });
3662
3890
  Object.defineProperty(exports, "stochastic", {
3663
3891
  enumerable: true,
3664
- get: function () { return chunkLGYYJ2GP_cjs.stochastic_default; }
3892
+ get: function () { return chunkSZDU2D3D_cjs.stochastic_default; }
3665
3893
  });
3666
3894
  Object.defineProperty(exports, "superTrend", {
3667
3895
  enumerable: true,
3668
- get: function () { return chunkLGYYJ2GP_cjs.superTrend_default; }
3896
+ get: function () { return chunkSZDU2D3D_cjs.superTrend_default; }
3669
3897
  });
3670
3898
  Object.defineProperty(exports, "threeWaves", {
3671
3899
  enumerable: true,
3672
- get: function () { return chunkLGYYJ2GP_cjs.threeWaves_default; }
3900
+ get: function () { return chunkSZDU2D3D_cjs.threeWaves_default; }
3673
3901
  });
3674
3902
  Object.defineProperty(exports, "triangle", {
3675
3903
  enumerable: true,
3676
- get: function () { return chunkLGYYJ2GP_cjs.triangle_default; }
3904
+ get: function () { return chunkSZDU2D3D_cjs.triangle_default; }
3677
3905
  });
3678
3906
  Object.defineProperty(exports, "vwap", {
3679
3907
  enumerable: true,
3680
- get: function () { return chunkLGYYJ2GP_cjs.vwap_default; }
3908
+ get: function () { return chunkSZDU2D3D_cjs.vwap_default; }
3681
3909
  });
3682
3910
  Object.defineProperty(exports, "xabcd", {
3683
3911
  enumerable: true,
3684
- get: function () { return chunkLGYYJ2GP_cjs.xabcd_default; }
3912
+ get: function () { return chunkSZDU2D3D_cjs.xabcd_default; }
3913
+ });
3914
+ Object.defineProperty(exports, "KlinechartsUIDispatchContext", {
3915
+ enumerable: true,
3916
+ get: function () { return chunkF24D6PWY_cjs.KlinechartsUIDispatchContext; }
3917
+ });
3918
+ Object.defineProperty(exports, "KlinechartsUIStateContext", {
3919
+ enumerable: true,
3920
+ get: function () { return chunkF24D6PWY_cjs.KlinechartsUIStateContext; }
3921
+ });
3922
+ Object.defineProperty(exports, "createDataLoader", {
3923
+ enumerable: true,
3924
+ get: function () { return chunkF24D6PWY_cjs.createDataLoader; }
3925
+ });
3926
+ Object.defineProperty(exports, "useKlinechartsUI", {
3927
+ enumerable: true,
3928
+ get: function () { return chunkF24D6PWY_cjs.useKlinechartsUI; }
3685
3929
  });
3686
3930
  exports.CANDLE_TYPES = CANDLE_TYPES;
3687
3931
  exports.COMPARE_RULES = COMPARE_RULES;
3688
3932
  exports.DEFAULT_PERIODS = DEFAULT_PERIODS;
3933
+ exports.DEFAULT_STORAGE_KEY_PREFIX = DEFAULT_STORAGE_KEY_PREFIX;
3934
+ exports.DEFAULT_STORAGE_NAMESPACES = DEFAULT_STORAGE_NAMESPACES;
3935
+ exports.DEFAULT_SYNC_CONFIG = DEFAULT_SYNC_CONFIG;
3689
3936
  exports.DRAWING_CATEGORIES = DRAWING_CATEGORIES;
3690
3937
  exports.INDICATOR_PARAMS = INDICATOR_PARAMS;
3691
- exports.KlinechartsUIDispatchContext = KlinechartsUIDispatchContext;
3692
3938
  exports.KlinechartsUIProvider = KlinechartsUIProvider;
3693
- exports.KlinechartsUIStateContext = KlinechartsUIStateContext;
3694
3939
  exports.MAIN_INDICATORS = MAIN_INDICATORS;
3695
3940
  exports.PRICE_AXIS_TYPES = PRICE_AXIS_TYPES;
3696
3941
  exports.SUB_INDICATORS = SUB_INDICATORS;
3697
3942
  exports.TIMEZONES = TIMEZONES;
3698
3943
  exports.TOOLTIP_SHOW_RULES = TOOLTIP_SHOW_RULES;
3944
+ exports.WorkspaceProvider = WorkspaceProvider;
3699
3945
  exports.YAXIS_POSITIONS = YAXIS_POSITIONS;
3700
- exports.createDataLoader = createDataLoader;
3946
+ exports.createDefaultStorage = createDefaultStorage;
3947
+ exports.resolveStorage = resolveStorage;
3701
3948
  exports.useAlerts = useAlerts;
3702
3949
  exports.useAnnotations = useAnnotations;
3703
3950
  exports.useChartAxes = useChartAxes;
3951
+ exports.useChartSync = useChartSync;
3704
3952
  exports.useCompare = useCompare;
3705
3953
  exports.useCrosshair = useCrosshair;
3706
3954
  exports.useDataExport = useDataExport;
@@ -3708,7 +3956,6 @@ exports.useDrawingTools = useDrawingTools;
3708
3956
  exports.useFullscreen = useFullscreen;
3709
3957
  exports.useHotkeys = useHotkeys;
3710
3958
  exports.useIndicators = useIndicators;
3711
- exports.useKlinechartsUI = useKlinechartsUI;
3712
3959
  exports.useKlinechartsUILoading = useKlinechartsUILoading;
3713
3960
  exports.useKlinechartsUISettings = useKlinechartsUISettings;
3714
3961
  exports.useKlinechartsUITheme = useKlinechartsUITheme;
@@ -3723,5 +3970,6 @@ exports.useSymbolSearch = useSymbolSearch;
3723
3970
  exports.useTimezone = useTimezone;
3724
3971
  exports.useUndoRedo = useUndoRedo;
3725
3972
  exports.useWatchlist = useWatchlist;
3973
+ exports.useWorkspace = useWorkspace;
3726
3974
  //# sourceMappingURL=index.cjs.map
3727
3975
  //# sourceMappingURL=index.cjs.map