@trdrs/quickcharts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +18 -0
  4. package/README.md +2325 -0
  5. package/THIRD-PARTY-NOTICES.md +263 -0
  6. package/dist/adapters/rest.d.ts +143 -0
  7. package/dist/adapters/rest.js +214 -0
  8. package/dist/adapters/rest.js.map +1 -0
  9. package/dist/ar-G7MVXRE4.js +1028 -0
  10. package/dist/ar-G7MVXRE4.js.map +1 -0
  11. package/dist/assets-C1GQvm0w.d.ts +1452 -0
  12. package/dist/ca_ES-EUSRU4VG.js +1028 -0
  13. package/dist/ca_ES-EUSRU4VG.js.map +1 -0
  14. package/dist/chunk-AKXIFHQN.js +172 -0
  15. package/dist/chunk-AKXIFHQN.js.map +1 -0
  16. package/dist/chunk-KFBQSPNA.js +107 -0
  17. package/dist/chunk-KFBQSPNA.js.map +1 -0
  18. package/dist/chunk-PD3DEWMQ.js +6959 -0
  19. package/dist/chunk-PD3DEWMQ.js.map +1 -0
  20. package/dist/de-2SVTG25S.js +1028 -0
  21. package/dist/de-2SVTG25S.js.map +1 -0
  22. package/dist/drawings.d.ts +237 -0
  23. package/dist/drawings.js +199 -0
  24. package/dist/drawings.js.map +1 -0
  25. package/dist/es-UDHZM4W7.js +1028 -0
  26. package/dist/es-UDHZM4W7.js.map +1 -0
  27. package/dist/feature-manifest.json +3453 -0
  28. package/dist/fr-35VN4G4S.js +1028 -0
  29. package/dist/fr-35VN4G4S.js.map +1 -0
  30. package/dist/he_IL-JPZMCURP.js +1028 -0
  31. package/dist/he_IL-JPZMCURP.js.map +1 -0
  32. package/dist/id_ID-XSTFHHJQ.js +1028 -0
  33. package/dist/id_ID-XSTFHHJQ.js.map +1 -0
  34. package/dist/index.d.ts +5487 -0
  35. package/dist/index.js +24040 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/it-EIY6JESQ.js +1028 -0
  38. package/dist/it-EIY6JESQ.js.map +1 -0
  39. package/dist/ja-42N4XRCW.js +1028 -0
  40. package/dist/ja-42N4XRCW.js.map +1 -0
  41. package/dist/ko-3VRPTIP3.js +1028 -0
  42. package/dist/ko-3VRPTIP3.js.map +1 -0
  43. package/dist/ms_MY-SKN7O6M5.js +1028 -0
  44. package/dist/ms_MY-SKN7O6M5.js.map +1 -0
  45. package/dist/pl-TYARHCLT.js +1028 -0
  46. package/dist/pl-TYARHCLT.js.map +1 -0
  47. package/dist/pt-72IIFLL4.js +1028 -0
  48. package/dist/pt-72IIFLL4.js.map +1 -0
  49. package/dist/quickcharts.css +6217 -0
  50. package/dist/resources-Ch8eA1Mw.d.ts +228 -0
  51. package/dist/rest-openapi.json +1664 -0
  52. package/dist/ru-TPH4F7IB.js +1028 -0
  53. package/dist/ru-TPH4F7IB.js.map +1 -0
  54. package/dist/sv-DC5RS67Z.js +1028 -0
  55. package/dist/sv-DC5RS67Z.js.map +1 -0
  56. package/dist/th-I6H6AOZ3.js +1028 -0
  57. package/dist/th-I6H6AOZ3.js.map +1 -0
  58. package/dist/theme-manifest.json +1246 -0
  59. package/dist/tr-7FSUVCNW.js +1028 -0
  60. package/dist/tr-7FSUVCNW.js.map +1 -0
  61. package/dist/vi-DLRPHLLH.js +1028 -0
  62. package/dist/vi-DLRPHLLH.js.map +1 -0
  63. package/dist/zh-ZXIQBBEP.js +1028 -0
  64. package/dist/zh-ZXIQBBEP.js.map +1 -0
  65. package/dist/zh_TW-TYNUJU7U.js +1028 -0
  66. package/dist/zh_TW-TYNUJU7U.js.map +1 -0
  67. package/package.json +100 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/ca_ES/legend.ts","../src/i18n/ca_ES/tools.ts","../src/i18n/ca_ES/menu.ts","../src/i18n/ca_ES/replay.ts","../src/i18n/ca_ES/inputs.ts","../src/i18n/ca_ES/session.ts","../src/i18n/ca_ES/layouts.ts","../src/i18n/ca_ES/host.ts","../src/i18n/ca_ES/indicators.ts","../src/i18n/ca_ES/timeframe.ts","../src/i18n/ca_ES/timezone.ts","../src/i18n/ca_ES/range.ts","../src/i18n/ca_ES/status.ts","../src/i18n/ca_ES/search.ts","../src/i18n/ca_ES/drawing.ts","../src/i18n/ca_ES/command.ts","../src/i18n/ca_ES/chrome.ts","../src/i18n/ca_ES/history.ts","../src/i18n/ca_ES/picker.ts","../src/i18n/ca_ES/settings.ts","../src/i18n/ca_ES/toast.ts","../src/i18n/ca_ES/index.ts"],"sourcesContent":["import type { Translation } from '../runtime'\nimport type { legend as source } from '../en/legend'\n\nexport const legend: Translation<typeof source> = {\n 'legend.open': 'O',\n 'legend.high': 'H',\n 'legend.low': 'L',\n 'legend.close': 'C',\n 'legend.change': '{change} ({percent}%)',\n 'legend.indicatorSettings': 'Configuració de l’indicador',\n 'legend.showRows': 'Show study rows',\n 'legend.hideRows': 'Hide study rows',\n 'legend.restorePane': 'Restaura el panell',\n 'legend.collapsePane': 'Redueix el panell',\n 'legend.maximizePane': 'Maximitza el panell',\n 'legend.showIndicator': 'Mostra l’indicador',\n 'legend.hideIndicator': 'Amaga l’indicador',\n 'legend.scaleNormal': 'Reg',\n 'legend.scaleLog': 'Log',\n 'legend.scalePercent': '%',\n 'legend.scaleIndexed': '100',\n 'legend.changeSymbol': 'Canvia el símbol',\n 'legend.removeCompare': 'Elimina la comparació',\n 'legend.removeIndicator': 'Remove indicator',\n}\n","import type { Translation } from '../runtime'\nimport type { tools as source } from '../en/tools'\n\nexport const tools: Translation<typeof source> = {\n 'tool.trend_line': 'Línia de tendència',\n 'tool.ray': 'Raig',\n 'tool.info_line': 'Línia informativa',\n 'tool.extended': 'Línia estesa',\n 'tool.trend_angle': 'Angle de tendència',\n 'tool.horizontal_line': 'Línia horitzontal',\n 'tool.horizontal_ray': 'Raig horitzontal',\n 'tool.vertical_line': 'Línia vertical',\n 'tool.cross_line': 'Línia creuada',\n 'tool.arrow': 'Fletxa',\n 'tool.rectangle': 'Rectangle',\n 'tool.rotated_rectangle': 'Rectangle girat',\n 'tool.ellipse': 'El·lipse',\n 'tool.circle': 'Cercle',\n 'tool.triangle': 'Triangle',\n 'tool.arc': 'Arc',\n 'tool.curve': 'Corba',\n 'tool.double_curve': 'Corba doble',\n 'tool.regression_trend': 'Tendència de regressió',\n 'tool.parallel_channel': 'Canal paral·lel',\n 'tool.flat_top_bottom': 'Màxim/mínim plans',\n 'tool.disjoint_channel': 'Canal disjunt',\n 'tool.fib_retracement': 'Retrocés de Fibonacci',\n 'tool.fib_trend_ext': 'Extensió de Fibonacci per tendència',\n 'tool.fib_channel': 'Canal de Fibonacci',\n 'tool.fib_timezone': 'Zona temporal de Fibonacci',\n 'tool.fib_speed_resist_fan': 'Ventall de velocitat i resistència de Fibonacci',\n 'tool.fib_trend_time': 'Temps de Fibonacci per tendència',\n 'tool.fib_circles': 'Cercles de Fibonacci',\n 'tool.fib_spiral': 'Espiral de Fibonacci',\n 'tool.fib_speed_resist_arcs': 'Arcs de velocitat i resistència de Fibonacci',\n 'tool.fib_wedge': 'Falca de Fibonacci',\n 'tool.pitchfan': 'Ventall de forca',\n 'tool.pitchfork': 'Forca',\n 'tool.schiff_pitchfork': 'Forca de Schiff',\n 'tool.schiff_pitchfork_modified': 'Forca de Schiff modificada',\n 'tool.inside_pitchfork': 'Forca interna',\n 'tool.gannbox': 'Caixa de Gann',\n 'tool.gannbox_square': 'Quadrat de Gann',\n 'tool.gannbox_fixed': 'Quadrat de Gann fix',\n 'tool.gannbox_fan': 'Ventall de Gann',\n 'tool.xabcd_pattern': 'Patró XABCD',\n 'tool.cypher_pattern': 'Patró Cypher',\n 'tool.abcd_pattern': 'Patró ABCD',\n 'tool.three_drives': 'Patró de tres impulsos',\n 'tool.triangle_pattern': 'Patró de triangle',\n 'tool.head_and_shoulders': 'Cap i espatlles',\n 'tool.elliott_impulse_wave': 'Impuls d’Elliott (12345)',\n 'tool.elliott_correction': 'Correcció d’Elliott (ABC)',\n 'tool.elliott_triangle_wave': 'Triangle d’Elliott (ABCDE)',\n 'tool.elliott_double_combo': 'Combinació doble d’Elliott (WXY)',\n 'tool.elliott_triple_combo': 'Combinació triple d’Elliott (WXYXZ)',\n 'tool.cyclic_lines': 'Línies cícliques',\n 'tool.time_cycles': 'Cicles temporals',\n 'tool.sine_line': 'Línia sinusoidal',\n 'tool.long_position': 'Posició llarga',\n 'tool.short_position': 'Posició curta',\n 'tool.forecast': 'Previsió de posició',\n 'tool.sector': 'Sector',\n 'tool.bars_pattern': 'Patró de barres',\n 'tool.ghost_feed': 'Feed fantasma',\n 'tool.anchored_vwap': 'VWAP ancorat',\n 'tool.fixed_range_volume_profile': 'Perfil de volum de rang fix',\n 'tool.anchored_volume_profile': 'Perfil de volum ancorat',\n 'tool.image': 'Imatge',\n 'tool.content_card': 'Fitxa de contingut',\n 'tool.emoji': 'Emoji',\n 'tool.sticker': 'Adhesiu',\n 'tool.icon': 'Icona',\n 'tool.text': 'Text',\n 'tool.note': 'Nota',\n 'tool.comment': 'Comentari',\n 'tool.callout': 'Globus',\n 'tool.price_label': 'Etiqueta de preu',\n 'tool.arrow_up': 'Marca de fletxa amunt',\n 'tool.arrow_down': 'Marca de fletxa avall',\n 'tool.arrow_marker': 'Marcador de fletxa',\n 'tool.flag': 'Marca de bandera',\n 'tool.price_note': 'Nota de preu',\n 'tool.pin': 'Xinxeta',\n 'tool.signpost': 'Senyal',\n 'tool.table': 'Taula',\n 'tool.brush': 'Pinzell',\n 'tool.highlighter': 'Marcador fluorescent',\n 'tool.path': 'Camí',\n 'tool.polyline': 'Polilínia',\n 'tool.price_range': 'Rang de preus',\n 'tool.date_range': 'Rang de dates',\n 'tool.date_and_price_range': 'Rang de dates i preus',\n 'tool.measure': 'Mesura',\n}\n","import type { Translation } from '../runtime'\nimport type { menu as source } from '../en/menu'\n\nexport const menu: Translation<typeof source> = {\n 'menu.resetView': 'Restableix la vista del gràfic',\n 'menu.copyPrice': 'Copia el preu {price}',\n 'menu.paste': 'Enganxa',\n 'menu.removeIndicators': { one: 'Elimina {count} indicador', many: 'Elimina {count} indicadors', other: 'Elimina {count} indicadors' },\n 'menu.removeDrawings': { one: 'Elimina {count} dibuix', many: 'Elimina {count} dibuixos', other: 'Elimina {count} dibuixos' },\n 'menu.settings': 'Configuració…',\n}\n","import type { Translation } from '../runtime'\nimport type { replay as source } from '../en/replay'\n\nexport const replay: Translation<typeof source> = {\n 'replay.watermark': 'Replay',\n 'replay.selectBar': 'Select bar',\n 'replay.selectDate': 'Select date',\n 'replay.selectStartingPoint': 'Select starting point',\n 'replay.startBar': 'Bar',\n 'replay.startDate': 'Date…',\n 'replay.startFirst': 'First available date',\n 'replay.startRandom': 'Random bar',\n 'replay.startDateField': 'Replay start date',\n 'replay.startTimeField': 'Replay start time (UTC, optional)',\n 'replay.dateMask': 'YYYY-MM-DD',\n 'replay.timeMask': 'HH:MM',\n 'replay.previousMonth': 'Previous month',\n 'replay.nextMonth': 'Next month',\n 'replay.cancel': 'Cancel',\n 'replay.select': 'Select',\n 'replay.weekdayMon': 'Mo',\n 'replay.weekdayTue': 'Tu',\n 'replay.weekdayWed': 'We',\n 'replay.weekdayThu': 'Th',\n 'replay.weekdayFri': 'Fr',\n 'replay.weekdaySat': 'Sa',\n 'replay.weekdaySun': 'Su',\n 'replay.stepBack': 'Retrocedeix una barra',\n 'replay.play': 'Reprodueix',\n 'replay.pause': 'Pausa',\n 'replay.stepForward': 'Avança una barra',\n 'replay.goLiveTitle': 'Salta a l’extrem en directe',\n 'replay.exit': 'Surt de la repetició',\n 'replay.speed': 'Replay speed',\n 'replay.updatesPerSecond': { one: '{count} update per second', many: '{count} updates per second', other: '{count} updates per second' },\n 'replay.oneUpdatePerSeconds': { one: '1 update per {count} second', many: '1 update per {count} seconds', other: '1 update per {count} seconds' },\n 'replay.interval': 'Update interval',\n 'replay.intervalHelp': 'How much time each replay update advances. Finer than the chart interval, each bar forms from real finer bars.',\n 'replay.intervalNone': 'No finer interval for this chart interval',\n 'replay.auto': 'Automàtic',\n 'replay.autoSelectInterval': 'Auto select interval',\n}\n","import type { Translation } from '../runtime'\nimport type { inputs as source } from '../en/inputs'\n\nexport const inputs: Translation<typeof source> = {\n 'inputs.cancel': 'Cancel·la',\n 'inputs.apply': 'Aplica',\n}\n","import type { Translation } from '../runtime'\nimport type { session as source } from '../en/session'\n\nexport const session: Translation<typeof source> = {\n 'session.pre': 'Preobertura',\n 'session.open': 'Mercat obert',\n 'session.extended': 'Extended hours',\n 'session.after': 'Postmercat',\n 'session.closed': 'Mercat tancat',\n}\n","import type { Translation } from '../runtime'\nimport type { layouts as source } from '../en/layouts'\n\nexport const layouts: Translation<typeof source> = {\n 'layout.s': 'Un sol gràfic',\n 'layout.2h': '2 columnes',\n 'layout.2v': '2 files',\n 'layout.3h': '3 columnes',\n 'layout.3v': '3 files',\n 'layout.3s': 'Gran a l’esquerra, 2 apilats a la dreta',\n 'layout.3r': '2 apilats a l’esquerra, gran a la dreta',\n 'layout.2_1': '2 a dalt, 1 a baix',\n 'layout.1_2': '1 a dalt, 2 a baix',\n 'layout.4': 'Quadrícula 2 × 2',\n 'layout.4v': '4 files',\n 'layout.4h': '4 columnes',\n 'layout.4s': 'Gran a l’esquerra, 3 apilats a la dreta',\n 'layout.4s_l': '3 apilats a l’esquerra, gran a la dreta',\n 'layout.1_3': '1 a dalt, 3 a baix',\n 'layout.3_1': '3 a dalt, 1 a baix',\n 'layout.2_2_l': '2 columnes, 2 apilats a la dreta',\n 'layout.2_2_r': '2 apilats a l’esquerra, 2 columnes',\n 'layout.2_2': '2 a dalt, 2 files d’amplada completa a baix',\n 'layout.1_4': '1 a dalt, 4 a baix',\n 'layout.5h': '5 columnes',\n 'layout.5v': '5 files',\n 'layout.5s': 'Gran a l’esquerra, 4 apilats a la dreta',\n 'layout.5s_l': '4 apilats a l’esquerra, gran a la dreta',\n 'layout.2_3': '2 a dalt, 3 a baix',\n 'layout.3_2': '3 a dalt, 2 a baix',\n 'layout.4_1': '4 a dalt, 1 a baix',\n 'layout.2_3_l': '2 columnes, 3 apilats a la dreta',\n 'layout.2_3_r': '3 apilats a l’esquerra, 2 columnes',\n 'layout.6': 'Quadrícula 3 × 2',\n 'layout.6h': '6 columnes',\n 'layout.6v': '6 files',\n 'layout.6c': 'Quadrícula 2 × 3',\n 'layout.2_4': '2 a dalt, 4 a baix',\n 'layout.4_2': '4 a dalt, 2 a baix',\n 'layout.4_3': '4 a dalt, 3 a baix',\n 'layout.7h': '7 columnes',\n 'layout.7s': 'Gran a l’esquerra, 6 apilats a la dreta',\n 'layout.8': 'Quadrícula 4 × 2',\n 'layout.8c': 'Quadrícula 2 × 4',\n 'layout.8h': '8 columnes',\n 'layout.8v': '8 files',\n 'layout.9s': 'Quadrícula 3 × 3',\n 'layout.5_4': '5 a dalt, 4 a baix',\n 'layout.9h': '9 columnes',\n 'layout.9v': '9 files',\n 'layout.10c5': 'Quadrícula 5 × 2',\n 'layout.10h': '10 columnes',\n 'layout.10v': '10 files',\n 'layout.12c6': 'Quadrícula 6 × 2',\n 'layout.12c4': 'Quadrícula 4 × 3',\n 'layout.12h': '12 columnes',\n 'layout.14c7': 'Quadrícula 7 × 2',\n 'layout.16c8': 'Quadrícula 8 × 2',\n 'layout.16c4': 'Quadrícula 4 × 4',\n 'layouts.setup': 'Layout setup',\n 'layouts.arrangement': 'Chart arrangement',\n 'layouts.syncInLayout': 'Sync in layout',\n 'layouts.syncSymbol': 'Symbol',\n 'layouts.syncInterval': 'Interval',\n 'layouts.syncCrosshair': 'Crosshair',\n 'layouts.syncTime': 'Time',\n 'layouts.syncDateRange': 'Date range',\n 'layouts.syncSymbolTip': 'Symbol changes on all charts within the layout',\n 'layouts.syncIntervalTip': 'Interval changes on all charts within the layout',\n 'layouts.syncCrosshairTip': 'Crosshair is synced across all charts within the layout',\n 'layouts.syncTimeTip': 'When a chart is clicked, all charts within the layout display the same point of time',\n 'layouts.syncDateRangeTip': 'Date range changes on all charts within the layout',\n 'layouts.syncSymbolToggle': 'Sync symbol',\n 'layouts.syncIntervalToggle': 'Sync interval',\n 'layouts.syncCrosshairToggle': 'Sync crosshair',\n 'layouts.syncTimeToggle': 'Sync time',\n 'layouts.syncDateRangeToggle': 'Sync date range',\n 'layouts.unnamed': 'Unnamed',\n 'layouts.unsavedChanges': 'Unsaved changes',\n 'layouts.allSaved': 'All changes saved',\n 'layouts.notSaving': 'Not saving until this is restored',\n 'layouts.manage': 'Manage layouts',\n 'layouts.saveLayout': 'Save layout',\n 'layouts.hintSave': '{modifier} + S',\n 'layouts.hintOpen': 'Dot',\n 'layouts.save': 'Save',\n 'layouts.autosave': 'Autosave',\n 'layouts.rename': 'Rename',\n 'layouts.copyOfName': '{name} copy',\n 'layouts.saveNewTitle': 'Save New Chart Layout',\n 'layouts.saveNewLabel': 'Enter a new chart layout name:',\n 'layouts.copyTitle': 'Make copy of chart layout',\n 'layouts.renameTitle': 'Rename chart layout',\n 'layouts.createTitle': 'Create layout',\n 'layouts.newLayoutName': 'New layout name',\n 'layouts.createPlaceholder': 'My layout',\n 'layouts.create': 'Create',\n 'layouts.makeCopyRow': 'Make a copy…',\n 'layouts.renameRow': 'Rename…',\n 'layouts.downloadDataRow': 'Download chart data',\n 'layouts.createNewRow': 'Create new layout…',\n 'layouts.recentlyUsed': 'Recently used',\n 'layouts.loading': 'Loading',\n 'layouts.emptyNone': 'No saved layouts yet.',\n 'layouts.openLayoutRow': 'Open layout…',\n 'layouts.listingFacts': '{symbol}, {interval}',\n 'layouts.listingDated': '{facts} ({date})',\n 'layouts.dialogTitle': 'Layouts',\n 'layouts.search': 'Search',\n 'layouts.columnName': 'Layout name',\n 'layouts.sortBy': 'Sort by layout name, date changed',\n 'layouts.sortNameAsc': 'Layout name (A to Z)',\n 'layouts.sortNameDesc': 'Layout name (Z to A)',\n 'layouts.sortModifiedAsc': 'Date modified (oldest first)',\n 'layouts.sortModifiedDesc': 'Date modified (newest first)',\n 'layouts.favorite': 'Add to favorites',\n 'layouts.unfavorite': 'Remove from favorites',\n 'layouts.noMatches': 'Nothing matches.',\n 'layouts.delete': 'Delete',\n 'layouts.deleteNamed': 'Delete {name}',\n 'layouts.deleteConfirm': 'Delete this chart layout?',\n 'layouts.deleteConfirmBody': 'Doing this will permanently delete your \"{name}\" layout.',\n 'layouts.cancel': 'Cancel',\n 'layouts.close': 'Close',\n 'layouts.errList': 'Could not load your saved layouts.',\n}\n","import type { Translation } from '../runtime'\nimport type { host as source } from '../en/host'\n\nexport const host: Translation<typeof source> = {\n 'host.noVolume': 'Aquest feed no proporciona volum',\n 'host.saveConflict': 'Saved elsewhere since you opened it. Load the newer version before saving.',\n 'host.saveNotFound': 'This was deleted elsewhere. Save it again as new.',\n 'host.loadInvalid': 'This could not be opened. Nothing on screen changed.',\n 'host.loadUnavailable': 'Your saved work could not be reached. Nothing on screen changed.',\n '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.',\n '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.',\n}\n","import type { Translation } from '../runtime'\nimport type { indicators as source } from '../en/indicators'\n\nexport const indicators: Translation<typeof source> = {\n 'indicator.smaName': 'Simple Moving Average',\n 'indicator.smaDescription': 'Smoothed average over a fixed window',\n 'indicator.emaName': 'Exponential Moving Average',\n 'indicator.emaDescription': 'Recency-weighted moving average',\n 'indicator.hmaName': 'Hull Moving Average',\n 'indicator.hmaDescription': 'Low-lag weighted moving average',\n 'indicator.vwmaName': 'Volume Weighted MA',\n 'indicator.vwmaDescription': 'Moving average weighted by volume',\n 'indicator.bollingerName': 'Bollinger Bands',\n 'indicator.bollingerDescription': 'SMA envelope at two standard deviations',\n 'indicator.donchianName': 'Donchian Channels',\n 'indicator.donchianDescription': 'Rolling highest-high and lowest-low channel',\n 'indicator.keltnerName': 'Keltner Channels',\n 'indicator.keltnerDescription': 'EMA midline with ATR-scaled bands',\n 'indicator.supertrendName': 'Supertrend',\n 'indicator.supertrendDescription': 'ATR trend band that flips with direction',\n 'indicator.psarName': 'Parabolic SAR',\n 'indicator.psarDescription': 'Stop-and-reverse trailing dots',\n 'indicator.rsiName': 'Relative Strength Index',\n 'indicator.rsiDescription': 'Momentum oscillator from 0 to 100',\n 'indicator.macdName': 'MACD',\n 'indicator.macdDescription': 'Moving Average Convergence Divergence',\n 'indicator.stochasticName': 'Stochastic Oscillator',\n 'indicator.stochasticDescription': '%K and %D momentum from 0 to 100',\n 'indicator.stochrsiName': 'Stochastic RSI',\n 'indicator.stochrsiDescription': 'Stochastic applied to the RSI series',\n 'indicator.adxName': 'Average Directional Index',\n 'indicator.adxDescription': 'Trend strength with +DI and -DI',\n 'indicator.atrName': 'Average True Range',\n 'indicator.atrDescription': 'Volatility: Wilder\\'s true-range average',\n 'indicator.cciName': 'Commodity Channel Index',\n 'indicator.cciDescription': 'Deviation from the typical-price average',\n 'indicator.williamsName': 'Williams %R',\n 'indicator.williamsDescription': 'Overbought and oversold momentum from -100 to 0',\n 'indicator.rocName': 'Rate of Change',\n 'indicator.rocDescription': 'Percent change over the period',\n 'indicator.momentumName': 'Momentum',\n 'indicator.momentumDescription': 'Price difference over the period',\n 'indicator.volumeName': 'Volume',\n 'indicator.volumeDescription': 'Per-bar traded volume histogram',\n 'indicator.vwapName': 'Volume Weighted Avg Price',\n 'indicator.vwapDescription': 'Cumulative volume-weighted average price',\n 'indicator.obvName': 'On-Balance Volume',\n 'indicator.obvDescription': 'Cumulative volume by close direction',\n 'indicator.mfiName': 'Money Flow Index',\n 'indicator.mfiDescription': 'Volume-weighted RSI from 0 to 100',\n}\n","import type { Translation } from '../runtime'\nimport type { timeframe as source } from '../en/timeframe'\n\nexport const timeframe: Translation<typeof source> = {\n 'timeframe.title': 'Interval',\n 'timeframe.all': 'Tots els intervals',\n 'timeframe.unitTicks': 'Ticks',\n 'timeframe.unitSeconds': 'Segons',\n 'timeframe.unitMinutes': 'Minuts',\n 'timeframe.unitHours': 'Hores',\n 'timeframe.unitDays': 'Dies',\n 'timeframe.unitWeeks': 'Setmanes',\n 'timeframe.unitMonths': 'Mesos',\n 'timeframe.countTicks': { one: '{count} tick', many: '{count} ticks', other: '{count} ticks' },\n 'timeframe.countSeconds': { one: '{count} segon', many: '{count} segons', other: '{count} segons' },\n 'timeframe.countMinutes': { one: '{count} minut', many: '{count} minuts', other: '{count} minuts' },\n 'timeframe.countHours': { one: '{count} hora', many: '{count} hores', other: '{count} hores' },\n 'timeframe.countDays': { one: '{count} dia', many: '{count} dies', other: '{count} dies' },\n 'timeframe.countWeeks': { one: '{count} setmana', many: '{count} setmanes', other: '{count} setmanes' },\n 'timeframe.countMonths': { one: '{count} mes', many: '{count} mesos', other: '{count} mesos' },\n 'timeframe.delete': 'Elimina {timeframe}',\n 'timeframe.save': 'Desa {timeframe}',\n 'timeframe.exists': '{timeframe} ja existeix',\n 'timeframe.custom': 'Interval personalitzat',\n 'timeframe.customCount': 'Nombre de l’interval personalitzat',\n 'timeframe.customUnit': 'Unitat de l’interval personalitzat',\n 'timeframe.addCustom': 'Afegeix un interval personalitzat',\n 'timeframe.increment': 'Incrementa',\n 'timeframe.decrement': 'Decrementa',\n}\n","import type { Translation } from '../runtime'\nimport type { timezone as source } from '../en/timezone'\n\nexport const timezone: Translation<typeof source> = {\n 'timezone.title': 'Fus horari del gràfic',\n 'timezone.exchange': 'Borsa',\n}\n","import type { Translation } from '../runtime'\nimport type { range as source } from '../en/range'\n\nexport const range: Translation<typeof source> = {\n 'range.oneDay': '1 dia',\n 'range.fiveDays': '5 dies',\n 'range.oneMonth': '1 mes',\n 'range.threeMonths': '3 mesos',\n 'range.sixMonths': '6 mesos',\n 'range.yearToDate': 'Any en curs',\n 'range.oneYear': '1 any',\n 'range.fiveYears': '5 anys',\n 'range.all': 'Totes les dades',\n 'range.tip': '{range} · barres de {interval}',\n 'range.zoomIn': 'Amplia',\n 'range.zoomOut': 'Redueix',\n 'range.scrollLeft': 'Desplaça a l’esquerra',\n 'range.scrollRight': 'Desplaça a la dreta',\n 'range.reset': 'Restableix la vista del gràfic',\n 'range.maximizeChart': 'Maximize chart',\n 'range.restoreChart': 'Restore chart',\n}\n","import type { Translation } from '../runtime'\nimport type { status as source } from '../en/status'\n\nexport const status: Translation<typeof source> = {\n 'status.title': 'Estat del mercat',\n 'status.unknownTitle': 'Sessió desconeguda',\n 'status.unknown': 'Encara no s’ha resolt la sessió de negociació d’aquest símbol.',\n 'status.endOfDayTitle': 'End of day',\n 'status.endOfDay': 'Prices update once a day, after the session closes.',\n 'status.delayed': 'Prices are delayed.',\n 'status.delayedPair': '{status} {delay}',\n 'status.continuousTitle': 'Obert 24/7',\n 'status.continuous': 'This market trades around the clock and never closes.',\n 'status.open': 'El mercat és obert per a la negociació regular.',\n 'status.openCloses': 'El mercat és obert per a la negociació regular. Tanca d’aquí a {until}.',\n 'status.extended': 'Market is open for extended-hours trading.',\n 'status.extendedRegular': 'Market is open for extended-hours trading. Regular hours start in {until}.',\n 'status.extendedCloses': 'Market is open for extended-hours trading. Closes in {until}.',\n 'status.pre': 'El mercat és obert per a la negociació de preobertura.',\n 'status.preRegular': 'El mercat és obert per a la negociació de preobertura. L’horari regular comença d’aquí a {until}.',\n 'status.after': 'El mercat és obert per a la negociació posterior al tancament.',\n 'status.afterEnds': 'El mercat és obert per a la negociació posterior al tancament. Acaba d’aquí a {until}.',\n 'status.closed': 'El mercat és tancat.',\n 'status.closedPre': 'El mercat és tancat. La preobertura comença d’aquí a {until}.',\n 'status.closedOpens': 'El mercat és tancat. Obre d’aquí a {until}.',\n 'status.exchangeTimezone': 'Fus horari de la borsa: {zone}',\n 'status.durationDays': { one: '{count} dia', many: '{count} dies', other: '{count} dies' },\n 'status.durationHours': { one: '{count} hora', many: '{count} hores', other: '{count} hores' },\n 'status.durationMinutes': { one: '{count} minut', many: '{count} minuts', other: '{count} minuts' },\n 'status.durationPair': '{major} {minor}',\n}\n","import type { Translation } from '../runtime'\nimport type { search as source } from '../en/search'\n\nexport const search: Translation<typeof source> = {\n 'search.title': 'Cerca de símbols',\n 'search.compareTitle': 'Compara símbols',\n 'search.changeSymbolTitle': 'Canvia el símbol',\n 'search.placeholder': 'Search symbol',\n 'search.clear': 'Esborra',\n 'search.close': 'Close',\n 'search.noMatches': 'No symbols match your criteria',\n 'search.loadingMore': 'Loading more',\n 'search.failed': 'Search failed.',\n 'search.results': 'Symbols',\n 'search.samePercent': 'Mateixa escala %',\n 'search.newScale': 'Nova escala de preus',\n 'search.newPane': 'Nou panell',\n 'search.added': 'Símbols afegits',\n 'search.recent': 'Símbols recents',\n 'search.addedMark': '{symbol} és al gràfic. Fes clic per eliminar-lo.',\n 'search.compareEmpty': 'No symbols here yet. Why not add some?',\n 'search.allClasses': 'All',\n 'search.classFilter': 'Asset class',\n 'search.opDivision': 'Divisió',\n 'search.opSubtraction': 'Resta',\n 'search.opAddition': 'Suma',\n 'search.opMultiplication': 'Multiplicació',\n 'search.opExponentiation': 'Exponenciació',\n 'search.opReciprocal': 'Recíproc',\n 'search.opsHide': 'Amaga els operadors de spread',\n 'search.opsShow': 'Mostra els operadors de spread',\n 'search.ops': 'Spread operators',\n}\n","import type { Translation } from '../runtime'\nimport type { drawing as source } from '../en/drawing'\n\nexport const drawing: Translation<typeof source> = {\n 'drawing.toolbar': 'Drawing tools',\n 'drawing.groupTrend': 'Trend tools',\n 'drawing.groupFibGann': 'Fibonacci & Gann',\n 'drawing.groupPatterns': 'Patterns',\n 'drawing.groupForecast': 'Forecast & measure',\n 'drawing.groupGlyphs': 'Emojis & stickers',\n 'drawing.shapes': 'Shapes',\n 'drawing.textNotes': 'Text & notes',\n 'drawing.groupMenu': '{group} menu',\n 'drawing.sectionLines': 'Lines',\n 'drawing.sectionChannels': 'Channels',\n 'drawing.sectionPitchforks': 'Pitchforks',\n 'drawing.sectionFibonacci': 'Fibonacci',\n 'drawing.sectionGann': 'Gann',\n 'drawing.sectionChartPatterns': 'Chart patterns',\n 'drawing.sectionElliott': 'Elliott waves',\n 'drawing.sectionCycles': 'Cycles',\n 'drawing.sectionForecasting': 'Forecasting',\n 'drawing.sectionVolumeBased': 'Volume based',\n 'drawing.sectionMeasures': 'Measures',\n 'drawing.sectionBrushes': 'Brushes',\n 'drawing.sectionArrows': 'Arrows',\n 'drawing.sectionContent': 'Content',\n 'drawing.sectionGlyphs': 'Emojis, stickers, icons',\n 'drawing.cursor': 'Cursor',\n 'drawing.cursorMenu': 'Cursor menu',\n 'drawing.cursorCross': 'Cross',\n 'drawing.cursorDot': 'Dot',\n 'drawing.cursorArrow': 'Arrow',\n 'drawing.cursorEraser': 'Eraser',\n 'drawing.measure': 'Measure',\n 'drawing.zoomIn': 'Zoom in',\n 'drawing.magnet': 'Magnet',\n 'drawing.magnetMenu': 'Magnet menu',\n 'drawing.magnetWeak': 'Weak magnet',\n 'drawing.magnetStrong': 'Strong magnet',\n 'drawing.stayInDrawingMode': 'Stay in drawing mode',\n 'drawing.lockAll': 'Lock all drawings',\n 'drawing.unlockAll': 'Unlock all drawings',\n 'drawing.hideMenu': 'Hide menu',\n 'drawing.hideDrawings': 'Hide drawings',\n 'drawing.showDrawings': 'Show drawings',\n 'drawing.hideIndicators': 'Hide indicators',\n 'drawing.showIndicators': 'Show indicators',\n 'drawing.hideAll': 'Hide all',\n 'drawing.showAll': 'Show all',\n 'drawing.syncLabel': 'Sync drawings across the layout',\n 'drawing.syncOnHelp': 'New drawings are replicated to all charts in the layout and shown when the same ticker is selected',\n 'drawing.syncOffHelp': 'New drawings stay on the chart that drew them',\n 'drawing.removeMenu': 'Remove menu',\n 'drawing.removeDrawings': 'Remove drawings',\n 'drawing.countDrawings': { one: '{count} drawing', many: '{count} drawings', other: '{count} drawings' },\n 'drawing.countIndicators': { one: '{count} indicator', many: '{count} indicators', other: '{count} indicators' },\n 'drawing.removeItems': 'Remove {items}',\n 'drawing.removeBoth': 'Remove {drawings} & {indicators}',\n 'drawing.nothingToRemove': 'Nothing to remove',\n 'drawing.alwaysRemoveLocked': 'Always remove locked drawings',\n 'drawing.favTools': 'Favorite drawing tools',\n 'drawing.favToolsBar': 'Favorite drawing tools toolbar',\n 'drawing.favAdd': 'Add {tool} to favorites',\n 'drawing.favRemove': 'Remove {tool} from favorites',\n 'drawing.moveToolbar': 'Move toolbar',\n 'drawing.moveFavoritesToolbar': 'Move favorites toolbar',\n 'drawing.settingsBar': 'Selected drawing',\n 'drawing.templates': 'Templates',\n 'drawing.drawingTemplates': 'Drawing templates',\n 'drawing.saveTemplateAs': 'Save drawing template as...',\n 'drawing.applyDefaultTemplate': 'Apply default drawing template',\n 'drawing.removeTemplateNamed': 'Remove template {name}',\n 'drawing.remove': 'Remove',\n 'drawing.addRowShort': '+ Row',\n 'drawing.addColumnShort': '+ Col',\n 'drawing.drawingColor': 'Drawing color',\n 'drawing.backgroundColor': 'Background color',\n 'drawing.thickness': 'Thickness',\n 'drawing.lineThickness': 'Line thickness',\n 'drawing.thicknessValue': 'Thickness {n}px',\n 'drawing.lineStyle': 'Line style',\n 'drawing.lineStyleValue': 'Line style {name}',\n 'drawing.lineSolid': 'Line',\n 'drawing.lineDashed': 'Dashed line',\n 'drawing.lineDotted': 'Dotted line',\n 'drawing.settings': 'Settings',\n 'drawing.drawingSettings': 'Drawing settings',\n 'drawing.lock': 'Lock',\n 'drawing.unlock': 'Unlock',\n 'drawing.lockDrawing': 'Lock drawing',\n 'drawing.unlockDrawing': 'Unlock drawing',\n 'drawing.deleteDrawing': 'Delete drawing',\n 'drawing.more': 'More',\n 'drawing.moreActions': 'More drawing actions',\n 'drawing.visualOrder': 'Visual order',\n 'drawing.visibilityOnIntervals': 'Visibility on intervals',\n 'drawing.clone': 'Clone',\n 'drawing.copy': 'Copy',\n 'drawing.modifierControl': 'Ctrl',\n 'drawing.modifierCommand': 'Cmd',\n 'drawing.hintClone': '{modifier} + Drag',\n 'drawing.hintCopy': '{modifier} + C',\n 'drawing.hintPaste': '{modifier} + V',\n 'drawing.deleteWithKey': 'Delete (Del)',\n 'drawing.statusDrawingsHidden': 'Drawings hidden',\n 'drawing.statusDrawingsShown': 'Drawings shown',\n 'drawing.statusIndicatorsHidden': 'Indicators hidden',\n 'drawing.statusIndicatorsShown': 'Indicators shown',\n 'drawing.statusAllHidden': 'Drawings and indicators hidden',\n 'drawing.statusAllShown': 'Drawings and indicators shown',\n 'drawing.statusAllLocked': 'All drawings locked',\n 'drawing.statusAllUnlocked': 'All drawings unlocked',\n 'drawing.hide': 'Hide',\n 'drawing.bringToFront': 'Bring to front',\n 'drawing.sendToBack': 'Send to back',\n 'drawing.bringForward': 'Bring forward',\n 'drawing.sendBackward': 'Send backward',\n 'drawing.visCurrentAndAbove': 'Current interval and above',\n 'drawing.visCurrentAndBelow': 'Current interval and below',\n 'drawing.visCurrentOnly': 'Current interval only',\n 'drawing.visAll': 'All intervals',\n 'drawing.saveTemplate': 'Save drawing template',\n 'drawing.templateName': 'Template name',\n 'drawing.save': 'Save',\n 'drawing.deleteTemplateTitle': 'Delete this template?',\n 'drawing.deleteTemplateBody': 'Doing this will permanently delete your \"{name}\" drawing template.',\n 'drawing.settingsTitle': '{tool} settings',\n 'drawing.tabInputs': 'Inputs',\n 'drawing.tabStyle': 'Style',\n 'drawing.tabText': 'Text',\n 'drawing.tabTable': 'Table',\n 'drawing.tabCoordinates': 'Coordinates',\n 'drawing.tabVisibility': 'Visibility',\n 'drawing.template': 'Template',\n 'drawing.saveAs': 'Save as...',\n 'drawing.applyDefaults': 'Apply defaults',\n 'drawing.cancel': 'Cancel',\n 'drawing.ok': 'Ok',\n 'drawing.delete': 'Delete',\n 'drawing.close': 'Close',\n 'drawing.color': 'Color',\n 'drawing.rowLine': 'Line',\n 'drawing.background': 'Background',\n 'drawing.border': 'Border',\n 'drawing.profitColor': 'Target zone color',\n 'drawing.stopColor': 'Stop zone color',\n 'drawing.textColor': 'Text color',\n 'drawing.fontSize': 'Font size',\n 'drawing.size': 'Size',\n 'drawing.width': 'Width',\n 'drawing.opacity': 'Opacity',\n 'drawing.transparency': 'Transparency',\n 'drawing.label': 'Label',\n 'drawing.labels': 'Labels',\n 'drawing.left': 'Left',\n 'drawing.center': 'Center',\n 'drawing.right': 'Right',\n 'drawing.up': 'Up',\n 'drawing.down': 'Down',\n 'drawing.rowVisible': '{name} visible',\n 'drawing.leftEnd': 'Left end',\n 'drawing.rightEnd': 'Right end',\n 'drawing.lineEndNormal': 'Normal',\n 'drawing.lineEndArrow': 'Arrow',\n 'drawing.increase': 'Increase',\n 'drawing.decrease': 'Decrease',\n 'drawing.rangeFrom': 'From',\n 'drawing.rangeTo': 'To',\n 'drawing.pickColor': 'Pick a color',\n 'drawing.extend': 'Extend',\n 'drawing.extendNone': 'Don\\'t extend',\n 'drawing.extendLeft': 'Extend left',\n 'drawing.extendRight': 'Extend right',\n 'drawing.extendBoth': 'Extend both',\n 'drawing.extendLines': 'Extend lines',\n 'drawing.middlePoint': 'Middle point',\n 'drawing.middleLine': 'Middle line',\n 'drawing.priceLabel': 'Price label',\n 'drawing.priceLabels': 'Price labels',\n 'drawing.timeLabel': 'Time label',\n 'drawing.rowStyle': 'Style',\n 'drawing.variantOriginal': 'Original',\n 'drawing.variantSchiff': 'Schiff',\n 'drawing.variantModifiedSchiff': 'Modified Schiff',\n 'drawing.variantInside': 'Inside',\n 'drawing.sectionStats': 'Stats',\n 'drawing.priceChange': 'Price change',\n 'drawing.percentChange': 'Percent change',\n 'drawing.bars': 'Bars',\n 'drawing.dateTimeRange': 'Date/time range',\n 'drawing.volume': 'Volume',\n 'drawing.sectionInfo': 'Info',\n 'drawing.priceRange': 'Price range',\n 'drawing.barsRange': 'Bars range',\n 'drawing.angle': 'Angle',\n 'drawing.statsPosition': 'Stats position',\n 'drawing.direction': 'Direction',\n 'drawing.prices': 'Prices',\n 'drawing.levels': 'Levels',\n 'drawing.reverse': 'Reverse',\n 'drawing.fullCircles': 'Full circles',\n 'drawing.coeffsAsPercents': 'Coeffs as percents',\n 'drawing.glyph': 'Glyph',\n 'drawing.image': 'Image',\n 'drawing.replaceEllipsis': 'Replace...',\n 'drawing.chooseEllipsis': 'Choose...',\n 'drawing.link': 'Link',\n 'drawing.rowsLayout': 'Rows layout',\n 'drawing.rowsByNumber': 'Number of rows',\n 'drawing.ticksPerRow': 'Ticks per row',\n 'drawing.rowSize': 'Row size',\n 'drawing.upDown': 'Up/Down',\n 'drawing.total': 'Total',\n 'drawing.delta': 'Delta',\n 'drawing.valueAreaVolume': 'Value area volume',\n 'drawing.widthPercent': 'Width %',\n 'drawing.placement': 'Placement',\n 'drawing.upDownVolume': 'Up/Down volume',\n 'drawing.valueAreaUpDown': 'Value area up/down',\n 'drawing.pointOfControl': 'Point of control',\n 'drawing.valueAreaHigh': 'Value area high',\n 'drawing.valueAreaLow': 'Value area low',\n 'drawing.developingPoc': 'Developing PoC',\n 'drawing.developingVa': 'Developing VA',\n 'drawing.source': 'Source',\n 'drawing.mode': 'Mode',\n 'drawing.modeLineOpen': 'Line (Open)',\n 'drawing.modeLineHigh': 'Line (High)',\n 'drawing.modeLineLow': 'Line (Low)',\n 'drawing.modeLineClose': 'Line (Close)',\n 'drawing.modeLineHl2': 'Line (HL2)',\n 'drawing.mirrored': 'Mirrored',\n 'drawing.flipped': 'Flipped',\n 'drawing.target': 'Target',\n 'drawing.success': 'Success',\n 'drawing.failure': 'Failure',\n 'drawing.avgHl': 'Avg HL',\n 'drawing.variance': 'Variance',\n 'drawing.body': 'Body',\n 'drawing.borders': 'Borders',\n 'drawing.drawBorders': 'Draw borders',\n 'drawing.wick': 'Wick',\n 'drawing.drawWicks': 'Draw wicks',\n 'drawing.sectionDeviation': 'Deviation',\n 'drawing.upper': 'Upper',\n 'drawing.lower': 'Lower',\n 'drawing.useUpperDeviation': 'Use upper deviation',\n 'drawing.useLowerDeviation': 'Use lower deviation',\n 'drawing.risk': 'Risk',\n 'drawing.accountSize': 'Account size',\n 'drawing.lotSize': 'Lot size',\n 'drawing.leverage': 'Leverage',\n 'drawing.compactStatsMode': 'Compact stats mode',\n 'drawing.levelVisible': 'Level {value} visible',\n 'drawing.levelText': 'Level {value} text',\n 'drawing.removeLevel': 'Remove level {value}',\n 'drawing.addLevel': 'Add level',\n 'drawing.weight': 'Weight',\n 'drawing.bold': 'Bold',\n 'drawing.italic': 'Italic',\n 'drawing.addText': 'Add text',\n 'drawing.alignment': 'Alignment',\n 'drawing.textPlaceholder': 'Text',\n 'drawing.textEditor': 'Drawing text',\n 'drawing.headerRow': 'Header row',\n 'drawing.tableCell': 'Cell {row},{col}',\n 'drawing.addRow': 'Add row',\n 'drawing.removeRow': 'Remove row',\n 'drawing.addColumn': 'Add column',\n 'drawing.removeColumn': 'Remove column',\n 'drawing.coordBar': '#{n} (bar)',\n 'drawing.coordPriceBar': '#{n} (price, bar)',\n 'drawing.unitTicks': 'Ticks',\n 'drawing.unitSeconds': 'Seconds',\n 'drawing.unitMinutes': 'Minutes',\n 'drawing.unitHours': 'Hours',\n 'drawing.unitDays': 'Days',\n 'drawing.unitWeeks': 'Weeks',\n 'drawing.unitMonths': 'Months',\n 'drawing.intervalPinnedNote': 'A drawing stays on at least one interval, so it can always be reached again.',\n 'drawing.colorSwatch': 'Color {hex}',\n 'drawing.customColor': 'Custom color',\n 'drawing.saturationValue': 'Saturation and brightness',\n 'drawing.hue': 'Hue',\n 'drawing.hexColor': 'Hex color',\n 'drawing.add': 'Add',\n 'drawing.glyphPicker': 'Glyph picker',\n 'drawing.kindEmojis': 'Emojis',\n 'drawing.kindStickers': 'Stickers',\n 'drawing.kindIcons': 'Icons',\n 'drawing.recentlyUsed': 'Recently used',\n 'drawing.recentGlyph': 'Recent {glyph}',\n 'drawing.stickersSoon': 'No sticker set is installed.',\n 'drawing.glyphCatSmileys': 'Smileys & People',\n 'drawing.glyphCatNature': 'Animals & Nature',\n 'drawing.glyphCatFood': 'Food & Drink',\n 'drawing.glyphCatActivity': 'Activity',\n 'drawing.glyphCatTravel': 'Travel & Places',\n 'drawing.glyphCatObjects': 'Objects',\n 'drawing.glyphCatSymbols': 'Symbols',\n 'drawing.glyphCatFlags': 'Flags',\n 'drawing.glyphCatIconArrows': 'Arrows',\n 'drawing.glyphCatIconCurrency': 'Currency',\n 'drawing.glyphCatIconGestures': 'Gestures and smileys',\n 'drawing.glyphCatIconNature': 'Nature',\n 'drawing.glyphCatIconSpecial': 'Special',\n 'drawing.glyphCatIconSymbols': 'Symbols and flags',\n 'drawing.imageReading': 'Reading...',\n 'drawing.chooseImage': 'Choose image',\n 'drawing.imageFormats': 'JPG or PNG',\n 'drawing.imageMaxSize': 'Max size 2MB',\n 'drawing.imageDimensions': '{width} x {height}',\n 'drawing.imageErrorType': 'That file is not a JPG or PNG. Pick one of those two formats.',\n 'drawing.imageErrorSize': 'That image is {size}. The limit is 2MB.',\n 'drawing.imageErrorRead': 'That file could not be read. Try picking it again.',\n 'drawing.imageErrorDecode': 'That image could not be opened. It may be damaged.',\n}\n","import type { Translation } from '../runtime'\nimport type { command as source } from '../en/command'\n\nexport const command: Translation<typeof source> = {\n 'command.extension': 'Host command',\n 'command.viewReset': 'Reset view',\n 'command.viewGoLive': 'Go to the live edge',\n 'command.viewZoomIn': 'Zoom in',\n 'command.viewZoomOut': 'Zoom out',\n 'command.viewScrollLeft': 'Scroll back',\n 'command.viewScrollRight': 'Scroll forward',\n 'command.priceCopy': 'Copy price',\n 'command.symbolSet': 'Change symbol',\n 'command.styleCandles': 'Candles',\n 'command.styleHollow': 'Hollow candles',\n 'command.styleBars': 'Bars',\n 'command.styleLine': 'Line',\n 'command.styleArea': 'Area',\n 'command.styleBaseline': 'Baseline',\n 'command.styleStepline': 'Step line',\n 'command.appearanceApply': 'Chart appearance',\n 'command.appearanceReset': 'Reset defaults',\n 'command.scaleNormal': 'Regular price scale',\n 'command.scaleLog': 'Logarithmic price scale',\n 'command.scalePercent': 'Percentage price scale',\n 'command.scaleIndexed': 'Indexed price scale',\n 'command.historyUndo': 'Undo',\n 'command.historyRedo': 'Redo',\n 'command.indicatorAdd': 'Add indicator',\n 'command.indicatorUpdate': 'Update indicator',\n 'command.indicatorsRemoveAll': 'Remove indicators',\n 'command.indicatorRemove': 'Remove indicator',\n 'command.indicatorHide': 'Hide indicator',\n 'command.indicatorShow': 'Show indicator',\n 'command.drawingsRemoveAll': 'Remove drawings',\n 'command.drawingDeleteSelected': 'Delete selected drawing',\n 'command.drawingArm': 'Drawing tool',\n 'command.drawingCursor': 'Cursor mode',\n 'command.drawingMagnet': 'Magnet',\n 'command.drawingStayInMode': 'Stay in drawing mode',\n 'command.drawingLockAll': 'Lock all drawings',\n 'command.drawingHide': 'Hide drawings or indicators',\n 'command.drawingSync': 'Sync drawings across the layout',\n 'command.drawingRemoveLockedPolicy': 'Always remove locked drawings',\n 'command.drawingFavorite': 'Favorite drawing tool',\n 'command.drawingFavoritesBar': 'Favorite drawing tools toolbar',\n 'command.drawingStyle': 'Drawing style',\n 'command.drawingProps': 'Drawing properties',\n 'command.drawingLock': 'Lock drawing',\n 'command.drawingClone': 'Clone drawing',\n 'command.drawingCopy': 'Copy drawing',\n 'command.drawingPaste': 'Paste drawing',\n 'command.drawingBringToFront': 'Bring drawing to front',\n 'command.drawingSendToBack': 'Send drawing to back',\n 'command.drawingBringForward': 'Bring drawing forward',\n 'command.drawingSendBackward': 'Send drawing backward',\n 'command.drawingHideSelected': 'Hide drawing',\n 'command.drawingVisibility': 'Drawing visibility on intervals',\n 'command.drawingSettings': 'Drawing settings',\n 'command.drawingCommitEdit': 'Apply drawing settings',\n 'command.drawingPlaceImage': 'Place image',\n 'command.drawingTemplateApply': 'Apply drawing template',\n 'command.drawingTemplateSave': 'Save drawing template',\n 'command.drawingTemplateRemove': 'Remove drawing template',\n 'command.drawingTableAddRow': 'Add table row',\n 'command.drawingTableAddColumn': 'Add table column',\n 'command.drawingCancel': 'Cancel drawing',\n 'command.compareOpen': 'Compare or add symbol',\n 'command.compareAdd': 'Add comparison',\n 'command.compareRemove': 'Remove comparison',\n 'command.compareVisible': 'Show or hide a comparison',\n 'command.compareChangeSymbol': 'Change compared symbol',\n 'command.replayStart': 'Start bar replay',\n 'command.replayStartFirst': 'Start bar replay at the first available date',\n 'command.replayExit': 'Exit bar replay',\n 'command.replayPlay': 'Play replay',\n 'command.replayPause': 'Pause replay',\n 'command.replayStepForward': 'Step forward',\n 'command.replayStepBack': 'Step back',\n 'command.replayGoLive': 'Replay to the live edge',\n 'command.replaySpeed': 'Replay speed',\n 'command.replayInterval': 'Replay update interval',\n 'command.timeframeSet': 'Timeframe',\n 'command.subsessionRegular': 'Regular hours',\n 'command.subsessionExtended': 'Extended hours',\n 'command.rangeSet': 'Date range',\n 'command.timezoneSet': 'Timezone',\n 'command.themeLight': 'Light theme',\n 'command.themeDark': 'Dark theme',\n 'command.themeToggle': 'Switch theme',\n 'command.themeSet': 'Set theme',\n 'command.localeSet': 'Language',\n 'command.fullscreenEnter': 'Fullscreen',\n 'command.fullscreenExit': 'Exit fullscreen',\n 'command.fullscreenToggle': 'Toggle fullscreen',\n 'command.imageCapture': 'Capture image',\n 'command.imageDownload': 'Download image',\n 'command.dataDownload': 'Download chart data',\n 'command.imageCopy': 'Copy image',\n 'command.layoutArrangement': 'Layout',\n 'command.layoutActive': 'Active chart',\n 'command.layoutSync': 'Chart synchronization',\n 'command.layoutActivateNext': 'Next chart in layout',\n 'command.layoutActivatePrevious': 'Previous chart in layout',\n 'command.layoutMaximize': 'Maximize or restore the active chart',\n 'command.layoutSave': 'Save layout',\n 'command.layoutRename': 'Rename layout',\n 'command.layoutLoad': 'Open layout',\n 'command.layoutOpen': 'Open layout…',\n 'command.layoutDelete': 'Delete layout',\n 'command.layoutCreate': 'Create new layout',\n 'command.layoutAutosave': 'Autosave layout',\n}\n","import type { Translation } from '../runtime'\nimport type { chrome as source } from '../en/chrome'\n\nexport const chrome: Translation<typeof source> = {\n 'chrome.topBar': 'Chart toolbar',\n 'chrome.bottomBar': 'Chart footer',\n 'chrome.symbolSearch': 'Search symbol',\n 'chrome.compare': 'Compare or add symbol',\n 'chrome.chartStyle': 'Chart style',\n 'chrome.indicators': 'Indicators',\n 'chrome.replay': 'Bar replay',\n 'chrome.replayChip': 'Replay',\n 'chrome.image': 'Chart image',\n 'chrome.session': 'Trading session',\n 'chrome.sessionsHeading': 'Sessions',\n 'chrome.navigation': 'Chart navigation',\n 'chrome.activeChart': '{symbol}, {timeframe}',\n}\n","import type { Translation } from '../runtime'\nimport type { history as source } from '../en/history'\n\nexport const history: Translation<typeof source> = {\n 'history.undoNamed': 'Undo {change}',\n 'history.redoNamed': 'Redo {change}',\n 'history.changeSymbol': 'symbol change',\n 'history.changeTimeframe': 'timeframe change',\n 'history.changeChartStyle': 'chart style change',\n 'history.changePriceScale': 'price scale change',\n 'history.changeAppearance': 'appearance change',\n 'history.changeAddCompare': 'add comparison',\n 'history.changeRemoveCompare': 'remove comparison',\n 'history.changeCompare': 'comparison change',\n 'history.changeAddIndicator': 'add indicator',\n 'history.changeRemoveIndicator': 'remove indicator',\n 'history.changeIndicator': 'indicator change',\n 'history.changeAddDrawing': 'add drawing',\n 'history.changeRemoveDrawing': 'remove drawing',\n 'history.changeDrawing': 'drawing change',\n}\n","import type { Translation } from '../runtime'\nimport type { picker as source } from '../en/picker'\n\nexport const picker: Translation<typeof source> = {\n 'picker.title': 'Indicators',\n 'picker.search': 'Search indicators',\n 'picker.noMatches': 'No matching indicators.',\n 'picker.collections': 'Indicator collections',\n 'picker.personal': 'Personal',\n 'picker.builtin': 'Built-in',\n 'picker.favorites': 'Favorites',\n 'picker.thousands': ' K',\n 'picker.name': 'Name',\n 'picker.author': 'Author',\n 'picker.favorite': 'Favorite {name}',\n 'picker.unfavorite': 'Unfavorite {name}',\n 'picker.loading': 'Loading indicators…',\n 'picker.unavailable': 'Indicator content is unavailable. Try again.',\n 'picker.actionFailed': 'The action could not be completed. Try again.',\n 'picker.add': 'Add {name}',\n 'picker.notPermitted': '{name} is not available here',\n}\n","import type { Translation } from '../runtime'\nimport type { settings as source } from '../en/settings'\n\nexport const settings: Translation<typeof source> = {\n 'settings.menu': 'Chart settings',\n 'settings.sectionAppearance': 'Appearance',\n 'settings.background': 'Background',\n 'settings.upCandles': 'Up candles',\n 'settings.downCandles': 'Down candles',\n 'settings.upBorders': 'Up borders',\n 'settings.downBorders': 'Down borders',\n 'settings.upWicks': 'Up wicks',\n 'settings.downWicks': 'Down wicks',\n 'settings.sectionDisplay': 'Display',\n 'settings.gridLines': 'Grid lines',\n 'settings.sessionShading': 'Session shading',\n 'settings.sectionScale': 'Price scale',\n 'settings.sectionTheme': 'Theme',\n 'settings.indicatorTitle': '{name} settings',\n 'settings.tabInputs': 'Inputs',\n 'settings.tabStyle': 'Style',\n 'settings.tabVisibility': 'Visibility',\n 'settings.plots': 'Plots',\n 'settings.levels': 'Levels',\n 'settings.fills': 'Fills',\n 'settings.colorOf': '{name} color',\n 'settings.lineWidthOf': '{name} line width',\n 'settings.lineStyleOf': '{name} line style',\n 'settings.visibleOf': 'Show {name}',\n 'settings.lineStyleSolid': 'Solid',\n 'settings.lineStyleDashed': 'Dashed',\n 'settings.lineStyleDotted': 'Dotted',\n 'settings.precision': 'Precision',\n 'settings.precisionDefault': 'Default',\n 'settings.labelsOnPriceScale': 'Labels on price scale',\n 'settings.showIndicator': 'Show this indicator',\n}\n","import type { Translation } from '../runtime'\nimport type { toast as source } from '../en/toast'\n\nexport const toast: Translation<typeof source> = {\n 'toast.dismiss': 'Dismiss',\n 'toast.feedUnavailable': 'No data for {symbol} from this feed.',\n 'toast.feedNoData': 'No data for {symbol} yet.',\n 'toast.imageCopyFallback': 'Could not copy the image. Saved a file instead.',\n 'toast.imageFailed': 'Could not capture the chart image.',\n 'toast.indicatorsNotCarried': { one: '{count} indicator in this saved chart is not available here and was left out.', many: '{count} indicators in this saved chart are not available here and were left out.', other: '{count} indicators in this saved chart are not available here and were left out.' },\n}\n","import type { Translation } from '../runtime'\nimport type { en } from '../en'\nimport { legend } from './legend'\nimport { tools } from './tools'\nimport { menu } from './menu'\nimport { replay } from './replay'\nimport { inputs } from './inputs'\nimport { session } from './session'\nimport { layouts } from './layouts'\nimport { host } from './host'\nimport { indicators } from './indicators'\nimport { timeframe } from './timeframe'\nimport { timezone } from './timezone'\nimport { range } from './range'\nimport { status } from './status'\nimport { search } from './search'\nimport { drawing } from './drawing'\nimport { command } from './command'\nimport { chrome } from './chrome'\nimport { history } from './history'\nimport { picker } from './picker'\nimport { settings } from './settings'\nimport { toast } from './toast'\n\nconst dict: Translation<typeof en> = { ...legend, ...tools, ...menu, ...replay, ...inputs, ...session, ...layouts, ...host, ...indicators, ...timeframe, ...timezone, ...range, ...status, ...search, ...drawing, ...command, ...chrome, ...history, ...picker, ...settings, ...toast }\nexport default dict\n"],"mappings":"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","names":[]}
@@ -0,0 +1,172 @@
1
+ // src/drawings/document.ts
2
+ var DRAWING_CONTEXT_VERSION = 1;
3
+ var DRAWING_DOCUMENT_VERSION = 1;
4
+ function drawingContextKey(context) {
5
+ const parts = [String(context.version), context.kind];
6
+ if (context.kind === "chart-local") parts.push(context.layoutId, context.chartId);
7
+ else if (context.kind === "layout-shared") parts.push(context.layoutId);
8
+ parts.push(context.symbol);
9
+ return parts.join("\0");
10
+ }
11
+ var sameDrawingContext = (a, b) => drawingContextKey(a) === drawingContextKey(b);
12
+ function emptyDrawingDocument(context) {
13
+ return { version: DRAWING_DOCUMENT_VERSION, context, revision: 0, entries: [], groups: [], tombstones: [] };
14
+ }
15
+ var tombstoneKey = (kind, id) => `${kind}\0${id}`;
16
+ function mergeTombstones(a, b) {
17
+ const byKey = /* @__PURE__ */ new Map();
18
+ for (const stone of [...a, ...b]) {
19
+ const key = tombstoneKey(stone.kind, stone.id);
20
+ const held = byKey.get(key);
21
+ if (!held || stone.at > held.at) byKey.set(key, { kind: stone.kind, id: stone.id, at: stone.at });
22
+ }
23
+ return [...byKey.values()];
24
+ }
25
+ var buriedSet = (tombstones, kind) => new Set(tombstones.filter((stone) => stone.kind === kind).map((stone) => stone.id));
26
+ var drawingBuried = (document, kind, id) => document.tombstones.some((stone) => stone.kind === kind && stone.id === id);
27
+ function liveDrawingEntries(document) {
28
+ const buriedDrawings = buriedSet(document.tombstones, "drawing");
29
+ const groups = new Set(liveDrawingGroups(document).map((group) => group.id));
30
+ const out = [];
31
+ const seen = /* @__PURE__ */ new Set();
32
+ for (const entry of document.entries) {
33
+ if (buriedDrawings.has(entry.id) || seen.has(entry.id)) continue;
34
+ seen.add(entry.id);
35
+ out.push(entry.group !== void 0 && !groups.has(entry.group) ? omitGroup(entry) : entry);
36
+ }
37
+ return out;
38
+ }
39
+ var omitGroup = (entry) => {
40
+ const { group: _buried, ...rest } = entry;
41
+ return rest;
42
+ };
43
+ function liveDrawingGroups(document) {
44
+ const buriedGroups = buriedSet(document.tombstones, "group");
45
+ const buriedDrawings = buriedSet(document.tombstones, "drawing");
46
+ const present = new Set(document.entries.filter((entry) => !buriedDrawings.has(entry.id)).map((entry) => entry.id));
47
+ const out = [];
48
+ const seen = /* @__PURE__ */ new Set();
49
+ for (const group of document.groups) {
50
+ if (buriedGroups.has(group.id) || seen.has(group.id)) continue;
51
+ seen.add(group.id);
52
+ out.push({ ...group, members: group.members.filter((id) => present.has(id)) });
53
+ }
54
+ return out;
55
+ }
56
+ function reviseDrawingDocument(document, next) {
57
+ const revision = document.revision + 1;
58
+ const entries = next.entries ?? liveDrawingEntries(document);
59
+ const groups = next.groups ?? liveDrawingGroups(document);
60
+ const keptDrawings = new Set(entries.map((entry) => entry.id));
61
+ const keptGroups = new Set(groups.map((group) => group.id));
62
+ const buried = [];
63
+ for (const entry of liveDrawingEntries(document)) if (!keptDrawings.has(entry.id)) buried.push({ kind: "drawing", id: entry.id, at: revision });
64
+ for (const group of liveDrawingGroups(document)) if (!keptGroups.has(group.id)) buried.push({ kind: "group", id: group.id, at: revision });
65
+ return {
66
+ version: DRAWING_DOCUMENT_VERSION,
67
+ context: document.context,
68
+ revision,
69
+ entries: [...entries],
70
+ groups: [...groups],
71
+ tombstones: mergeTombstones(document.tombstones, buried)
72
+ };
73
+ }
74
+ function mergeDrawingDocuments(stored, mine) {
75
+ const tombstones = mergeTombstones(stored.tombstones, mine.tombstones);
76
+ const buriedDrawings = buriedSet(tombstones, "drawing");
77
+ const buriedGroups = buriedSet(tombstones, "group");
78
+ const entries = [];
79
+ const seen = /* @__PURE__ */ new Set();
80
+ for (const entry of [...stored.entries, ...mine.entries]) {
81
+ if (seen.has(entry.id) || buriedDrawings.has(entry.id)) continue;
82
+ seen.add(entry.id);
83
+ entries.push(entry.group !== void 0 && buriedGroups.has(entry.group) ? omitGroup(entry) : entry);
84
+ }
85
+ const groups = [];
86
+ const byId = /* @__PURE__ */ new Map();
87
+ for (const group of [...stored.groups, ...mine.groups]) {
88
+ if (buriedGroups.has(group.id)) continue;
89
+ const held = byId.get(group.id);
90
+ if (!held) {
91
+ const row = { ...group, members: [...group.members] };
92
+ byId.set(group.id, row);
93
+ groups.push(row);
94
+ continue;
95
+ }
96
+ for (const id of group.members) if (!held.members.includes(id)) held.members.push(id);
97
+ }
98
+ const present = new Set(entries.map((entry) => entry.id));
99
+ return {
100
+ version: DRAWING_DOCUMENT_VERSION,
101
+ context: stored.context,
102
+ revision: Math.max(stored.revision, mine.revision) + 1,
103
+ entries,
104
+ groups: groups.map((group) => ({ ...group, members: group.members.filter((id) => present.has(id)) })),
105
+ tombstones
106
+ };
107
+ }
108
+ var isRecord = (value) => typeof value === "object" && value !== null;
109
+ var entryOf = (value) => {
110
+ if (!isRecord(value)) return null;
111
+ const { id, source, pane, type, group } = value;
112
+ if (typeof id !== "string" || !id || typeof source !== "string" || typeof pane !== "string" || typeof type !== "string") return null;
113
+ return { id, source, pane, type, state: value.state, ...typeof group === "string" ? { group } : {} };
114
+ };
115
+ var groupOf = (value) => {
116
+ if (!isRecord(value)) return null;
117
+ const { id, name, members } = value;
118
+ if (typeof id !== "string" || !id || !Array.isArray(members)) return null;
119
+ return { id, ...typeof name === "string" ? { name } : {}, members: members.filter((m) => typeof m === "string") };
120
+ };
121
+ var contextOf = (value) => {
122
+ if (!isRecord(value) || value.version !== DRAWING_CONTEXT_VERSION) return null;
123
+ const { kind, symbol, layoutId, chartId } = value;
124
+ if (typeof symbol !== "string") return null;
125
+ if (kind === "symbol-global") return { version: DRAWING_CONTEXT_VERSION, kind, symbol };
126
+ if (typeof layoutId !== "string") return null;
127
+ if (kind === "layout-shared") return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, symbol };
128
+ if (kind === "chart-local" && typeof chartId === "string") return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, chartId, symbol };
129
+ return null;
130
+ };
131
+ var tombstoneOf = (value) => {
132
+ if (!isRecord(value)) return null;
133
+ const { kind, id, at } = value;
134
+ if (kind !== "drawing" && kind !== "group" || typeof id !== "string" || !id) return null;
135
+ return { kind, id, at: typeof at === "number" ? at : 0 };
136
+ };
137
+ function parseDrawingDocument(value, context) {
138
+ const raw = typeof value === "string" ? safeJson(value) : value;
139
+ if (!isRecord(raw) || raw.version !== DRAWING_DOCUMENT_VERSION) return emptyDrawingDocument(context);
140
+ const stated = contextOf(raw.context);
141
+ if (stated && !sameDrawingContext(stated, context)) return emptyDrawingDocument(context);
142
+ return {
143
+ version: DRAWING_DOCUMENT_VERSION,
144
+ context,
145
+ revision: typeof raw.revision === "number" && Number.isFinite(raw.revision) ? raw.revision : 0,
146
+ entries: Array.isArray(raw.entries) ? raw.entries.map(entryOf).filter((e) => e !== null) : [],
147
+ groups: Array.isArray(raw.groups) ? raw.groups.map(groupOf).filter((g) => g !== null) : [],
148
+ tombstones: Array.isArray(raw.tombstones) ? raw.tombstones.map(tombstoneOf).filter((t) => t !== null) : []
149
+ };
150
+ }
151
+ var safeJson = (text) => {
152
+ try {
153
+ return JSON.parse(text);
154
+ } catch {
155
+ return null;
156
+ }
157
+ };
158
+
159
+ export {
160
+ DRAWING_CONTEXT_VERSION,
161
+ DRAWING_DOCUMENT_VERSION,
162
+ drawingContextKey,
163
+ sameDrawingContext,
164
+ emptyDrawingDocument,
165
+ drawingBuried,
166
+ liveDrawingEntries,
167
+ liveDrawingGroups,
168
+ reviseDrawingDocument,
169
+ mergeDrawingDocuments,
170
+ parseDrawingDocument
171
+ };
172
+ //# sourceMappingURL=chunk-AKXIFHQN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/drawings/document.ts"],"sourcesContent":["// The drawings DOCUMENT: the pure rules over the drawing-resource contract's document shape.\n//\n// Nothing here touches a chart, a store or a clock. That is deliberate: what a document means when\n// two surfaces write it, what a deletion does to it, and which of its entries are live are exactly\n// the questions that go wrong in a persistence layer, and they are all decidable from two values.\n//\n// Three rules the module enforces:\n// - A deletion is a TOMBSTONE, never an omission. Two charts hold the same document; if a\n// deletion were just a shorter list, the other chart's copy would put the row back on the next\n// merge, and a drawing the trader deleted would return after a save, a reconnect or a reload.\n// - A merge is not a last-write-wins overwrite. The stored document is the other surface's work\n// and wins by identity and by order; this surface's own additions follow it. Neither side\n// loses a row it made, and neither side resurrects a row the other buried.\n// - Deleting a GROUP deletes the grouping, not the drawings. The members survive, ungrouped, and\n// the group id can never come back.\n//\n// The document's own SHAPE lives here too, beside the rules, because the two only make sense\n// together: the resource contract in `resources.ts` names this the drawings family's body.\n\n/* ── The drawing-resource context ───────────────────────────────────────────────────────────────\n Where a drawings document lives, as a discriminated, versioned context rather than a pair of\n loose fields. The kind IS the sharing rule, so a reader never infers one from which fields\n happen to be set:\n\n chart-local one chart of one layout, on one symbol. Nothing is shared.\n layout-shared every chart of one layout, on one symbol.\n symbol-global every chart the host mounts, on one symbol.\n\n `version` is the context's own format, not the document's: a store keys its rows by the whole\n context, so a later kind or field arrives as a different key rather than as a silently widened\n old one. */\n\nexport const DRAWING_CONTEXT_VERSION = 1\n\nexport type DrawingContextKind = 'chart-local' | 'layout-shared' | 'symbol-global'\n\n/** One chart of one layout, on one symbol. */\nexport interface ChartLocalDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'chart-local'\n /** The host's stable identity for the layout the chart is tiled in. */\n layoutId: string\n /** The chart's stable identity WITHIN that layout, so the document is found again after a\n * reload; a per-mount instance id would key a document nothing could ever read back. */\n chartId: string\n symbol: string\n}\n\n/** Every chart of one layout, on one symbol. */\nexport interface LayoutSharedDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'layout-shared'\n layoutId: string\n symbol: string\n}\n\n/** Every chart the host mounts, on one symbol. */\nexport interface SymbolGlobalDrawingContext {\n version: typeof DRAWING_CONTEXT_VERSION\n kind: 'symbol-global'\n symbol: string\n}\n\nexport type DrawingResourceContext = ChartLocalDrawingContext | LayoutSharedDrawingContext | SymbolGlobalDrawingContext\n\n/** The drawings document format. Bumping this is the only reason a reader ever branches. */\nexport const DRAWING_DOCUMENT_VERSION = 1\n\n/** One drawing in a document. The ENVELOPE is structured so a restore is validated without parsing\n * the drawing itself: the id is stable for the drawing's life, `source` names what owns it (the\n * main series, or an indicator's own source), `pane` names where it is drawn, and `type` is its\n * tool. `state` is the drawing's own serialized form and is opaque to the document, the store and\n * the transport. */\nexport interface DrawingEntry {\n id: string\n /** The owning source: `main` for the chart's main series, else an indicator instance's id. */\n source: string\n /** The pane the drawing is drawn in: `main` for the price pane, else the pane owner's id. */\n pane: string\n type: string\n /** Opaque: nothing between the layer and the backend reads it. */\n state: unknown\n /** The group this drawing belongs to, when it belongs to one. */\n group?: string\n}\n\n/** A group of drawings. Membership is ORDERED and holds drawing ids, so a group survives a round\n * trip with its order intact rather than being rebuilt from however a document happened to list\n * its entries. */\nexport interface DrawingGroup {\n id: string\n name?: string\n members: readonly string[]\n}\n\n/** A deletion, kept. A document that listed only what survives lets a concurrent save, a reconnect\n * or a reload resurrect what the trader deleted: the other side still holds the row and a merge\n * takes it back. A tombstone says the deletion happened, and at which document revision, so the\n * merge drops it instead. */\nexport interface DrawingTombstone {\n kind: 'drawing' | 'group'\n id: string\n /** The document revision the deletion was stamped at. */\n at: number\n}\n\n/** One context's drawings document. `revision` is the DOCUMENT's own counter, which orders\n * tombstones and detects a stale apply; it is not the store's `ResourceRef.revision`, which stays\n * opaque and is the store's alone. */\nexport interface DrawingsBody {\n version: typeof DRAWING_DOCUMENT_VERSION\n context: DrawingResourceContext\n revision: number\n entries: readonly DrawingEntry[]\n groups: readonly DrawingGroup[]\n tombstones: readonly DrawingTombstone[]\n}\n\n\n/** The canonical key for a drawing-resource context: equal contexts key equally, and no two\n * different contexts collide. The parts join on an escaped null, which no symbol, layout id or\n * chart id carries, so a symbol ending in a separator cannot spell another context's key. The\n * kind and version lead, so a later kind is a different key rather than a widened old one. */\nexport function drawingContextKey(context: DrawingResourceContext): string {\n const parts: string[] = [String(context.version), context.kind]\n if (context.kind === 'chart-local') parts.push(context.layoutId, context.chartId)\n else if (context.kind === 'layout-shared') parts.push(context.layoutId)\n parts.push(context.symbol)\n return parts.join('\\u0000')\n}\n\n/** Whether two contexts name the same document. */\nexport const sameDrawingContext = (a: DrawingResourceContext, b: DrawingResourceContext): boolean => drawingContextKey(a) === drawingContextKey(b)\n\n/** A document with nothing in it, at revision 0: what a context that has never been written reads\n * as, so every caller works over a document rather than over a null. */\nexport function emptyDrawingDocument(context: DrawingResourceContext): DrawingsBody {\n return { version: DRAWING_DOCUMENT_VERSION, context, revision: 0, entries: [], groups: [], tombstones: [] }\n}\n\nconst tombstoneKey = (kind: DrawingTombstone['kind'], id: string): string => `${kind}\\u0000${id}`\n\n/** The tombstones of both documents, one per (kind, id), each at the later revision it was seen at. */\nfunction mergeTombstones(a: readonly DrawingTombstone[], b: readonly DrawingTombstone[]): DrawingTombstone[] {\n const byKey = new Map<string, DrawingTombstone>()\n for (const stone of [...a, ...b]) {\n const key = tombstoneKey(stone.kind, stone.id)\n const held = byKey.get(key)\n if (!held || stone.at > held.at) byKey.set(key, { kind: stone.kind, id: stone.id, at: stone.at })\n }\n return [...byKey.values()]\n}\n\nconst buriedSet = (tombstones: readonly DrawingTombstone[], kind: DrawingTombstone['kind']): Set<string> =>\n new Set(tombstones.filter((stone) => stone.kind === kind).map((stone) => stone.id))\n\n/** Whether a document buries this id. Package-internal, beside the rules it serves: the layer asks\n * it to tell a live entry from one whose group is gone. */\nexport const drawingBuried = (document: DrawingsBody, kind: DrawingTombstone['kind'], id: string): boolean =>\n document.tombstones.some((stone) => stone.kind === kind && stone.id === id)\n\n/** The entries a document actually holds: nothing buried, no duplicate id, and no membership of a\n * group that is gone (the drawing survives, its grouping does not). */\nexport function liveDrawingEntries(document: DrawingsBody): DrawingEntry[] {\n const buriedDrawings = buriedSet(document.tombstones, 'drawing')\n const groups = new Set(liveDrawingGroups(document).map((group) => group.id))\n const out: DrawingEntry[] = []\n const seen = new Set<string>()\n for (const entry of document.entries) {\n if (buriedDrawings.has(entry.id) || seen.has(entry.id)) continue\n seen.add(entry.id)\n out.push(entry.group !== undefined && !groups.has(entry.group) ? omitGroup(entry) : entry)\n }\n return out\n}\n\nconst omitGroup = (entry: DrawingEntry): DrawingEntry => {\n const { group: _buried, ...rest } = entry\n return rest\n}\n\n/** The groups a document actually holds: nothing buried, no duplicate id, and no member that is\n * buried or absent, so a group never names a drawing that is not there. */\nexport function liveDrawingGroups(document: DrawingsBody): DrawingGroup[] {\n const buriedGroups = buriedSet(document.tombstones, 'group')\n const buriedDrawings = buriedSet(document.tombstones, 'drawing')\n const present = new Set(document.entries.filter((entry) => !buriedDrawings.has(entry.id)).map((entry) => entry.id))\n const out: DrawingGroup[] = []\n const seen = new Set<string>()\n for (const group of document.groups) {\n if (buriedGroups.has(group.id) || seen.has(group.id)) continue\n seen.add(group.id)\n out.push({ ...group, members: group.members.filter((id) => present.has(id)) })\n }\n return out\n}\n\n/** Replace what a document holds and stamp the difference. Every id the document held and the next\n * state does not is buried at the new revision; every id that arrives is kept in the order it\n * arrives in. One verb, one revision bump, so a save can never write entries at one revision and\n * groups at another. */\nexport function reviseDrawingDocument(\n document: DrawingsBody,\n next: { entries?: readonly DrawingEntry[]; groups?: readonly DrawingGroup[] },\n): DrawingsBody {\n const revision = document.revision + 1\n const entries = next.entries ?? liveDrawingEntries(document)\n const groups = next.groups ?? liveDrawingGroups(document)\n const keptDrawings = new Set(entries.map((entry) => entry.id))\n const keptGroups = new Set(groups.map((group) => group.id))\n const buried: DrawingTombstone[] = []\n for (const entry of liveDrawingEntries(document)) if (!keptDrawings.has(entry.id)) buried.push({ kind: 'drawing', id: entry.id, at: revision })\n for (const group of liveDrawingGroups(document)) if (!keptGroups.has(group.id)) buried.push({ kind: 'group', id: group.id, at: revision })\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context: document.context,\n revision,\n entries: [...entries],\n groups: [...groups],\n tombstones: mergeTombstones(document.tombstones, buried),\n }\n}\n\n/** Merge the document another surface wrote first with this surface's own. The stored rows win by\n * identity and keep the stored order, because they are what everyone else can already see; rows\n * only this surface holds follow, because they are work the other surface never saw. Every\n * deletion either side made survives the merge. The result's revision is past both, so the write\n * that carries it is the newer document by either side's counter. */\nexport function mergeDrawingDocuments(stored: DrawingsBody, mine: DrawingsBody): DrawingsBody {\n const tombstones = mergeTombstones(stored.tombstones, mine.tombstones)\n const buriedDrawings = buriedSet(tombstones, 'drawing')\n const buriedGroups = buriedSet(tombstones, 'group')\n\n const entries: DrawingEntry[] = []\n const seen = new Set<string>()\n for (const entry of [...stored.entries, ...mine.entries]) {\n if (seen.has(entry.id) || buriedDrawings.has(entry.id)) continue\n seen.add(entry.id)\n entries.push(entry.group !== undefined && buriedGroups.has(entry.group) ? omitGroup(entry) : entry)\n }\n\n const groups: DrawingGroup[] = []\n const byId = new Map<string, DrawingGroup>()\n for (const group of [...stored.groups, ...mine.groups]) {\n if (buriedGroups.has(group.id)) continue\n const held = byId.get(group.id)\n if (!held) {\n const row = { ...group, members: [...group.members] }\n byId.set(group.id, row)\n groups.push(row)\n continue\n }\n // One group written by both surfaces: the stored order stands and the members only this\n // surface knows about are appended, the same rule the entries follow.\n for (const id of group.members) if (!held.members.includes(id)) (held.members as string[]).push(id)\n }\n const present = new Set(entries.map((entry) => entry.id))\n\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context: stored.context,\n revision: Math.max(stored.revision, mine.revision) + 1,\n entries,\n groups: groups.map((group) => ({ ...group, members: group.members.filter((id) => present.has(id)) })),\n tombstones,\n }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null\n\nconst entryOf = (value: unknown): DrawingEntry | null => {\n if (!isRecord(value)) return null\n const { id, source, pane, type, group } = value\n if (typeof id !== 'string' || !id || typeof source !== 'string' || typeof pane !== 'string' || typeof type !== 'string') return null\n return { id, source, pane, type, state: value.state, ...(typeof group === 'string' ? { group } : {}) }\n}\n\nconst groupOf = (value: unknown): DrawingGroup | null => {\n if (!isRecord(value)) return null\n const { id, name, members } = value\n if (typeof id !== 'string' || !id || !Array.isArray(members)) return null\n return { id, ...(typeof name === 'string' ? { name } : {}), members: members.filter((m): m is string => typeof m === 'string') }\n}\n\n/** The context a payload states, when it states a whole one this build understands. */\nconst contextOf = (value: unknown): DrawingResourceContext | null => {\n if (!isRecord(value) || value.version !== DRAWING_CONTEXT_VERSION) return null\n const { kind, symbol, layoutId, chartId } = value\n if (typeof symbol !== 'string') return null\n if (kind === 'symbol-global') return { version: DRAWING_CONTEXT_VERSION, kind, symbol }\n if (typeof layoutId !== 'string') return null\n if (kind === 'layout-shared') return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, symbol }\n if (kind === 'chart-local' && typeof chartId === 'string') return { version: DRAWING_CONTEXT_VERSION, kind, layoutId, chartId, symbol }\n return null\n}\n\nconst tombstoneOf = (value: unknown): DrawingTombstone | null => {\n if (!isRecord(value)) return null\n const { kind, id, at } = value\n if ((kind !== 'drawing' && kind !== 'group') || typeof id !== 'string' || !id) return null\n return { kind, id, at: typeof at === 'number' ? at : 0 }\n}\n\n/** Read whatever a transport handed back as a document for this context. TOTAL: a null, a string, a\n * wrong version, a junk row or a whole junk body reads as the empty document, never a throw, so a\n * host can hand the chart what its backend returned without guarding it first. The context is the\n * caller's, not the payload's: a document is identified by where it was read from, and a body\n * claiming another context is not merged into this one. */\nexport function parseDrawingDocument(value: unknown, context: DrawingResourceContext): DrawingsBody {\n const raw: unknown = typeof value === 'string' ? safeJson(value) : value\n if (!isRecord(raw) || raw.version !== DRAWING_DOCUMENT_VERSION) return emptyDrawingDocument(context)\n const stated = contextOf(raw.context)\n if (stated && !sameDrawingContext(stated, context)) return emptyDrawingDocument(context)\n return {\n version: DRAWING_DOCUMENT_VERSION,\n context,\n revision: typeof raw.revision === 'number' && Number.isFinite(raw.revision) ? raw.revision : 0,\n entries: Array.isArray(raw.entries) ? raw.entries.map(entryOf).filter((e): e is DrawingEntry => e !== null) : [],\n groups: Array.isArray(raw.groups) ? raw.groups.map(groupOf).filter((g): g is DrawingGroup => g !== null) : [],\n tombstones: Array.isArray(raw.tombstones) ? raw.tombstones.map(tombstoneOf).filter((t): t is DrawingTombstone => t !== null) : [],\n }\n}\n\nconst safeJson = (text: string): unknown => {\n try {\n return JSON.parse(text)\n } catch {\n return null\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,107 @@
1
+ import {
2
+ drawingContextKey
3
+ } from "./chunk-AKXIFHQN.js";
4
+
5
+ // src/resources.ts
6
+ var ResourceAbortError = class extends Error {
7
+ name = "AbortError";
8
+ constructor(message = "the resource operation was aborted") {
9
+ super(message);
10
+ }
11
+ };
12
+ var aborted = (signal) => signal?.aborted ? Promise.reject(new ResourceAbortError()) : null;
13
+ var newId = () => typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `r${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
14
+ function memoryStore(metaOf, now) {
15
+ const rows = /* @__PURE__ */ new Map();
16
+ let counter = 0;
17
+ const nextRevision = () => `rev-${++counter}`;
18
+ const refOf = (record) => ({ id: record.id, revision: record.revision });
19
+ return {
20
+ list(signal) {
21
+ return aborted(signal) ?? Promise.resolve([...rows.values()].map(metaOf));
22
+ },
23
+ load(id, signal) {
24
+ const stop = aborted(signal);
25
+ if (stop) return stop;
26
+ const record = rows.get(id);
27
+ return Promise.resolve(record ? { ref: refOf(record), body: record.body } : null);
28
+ },
29
+ create(body, signal) {
30
+ const stop = aborted(signal);
31
+ if (stop) return stop;
32
+ const record = { id: newId(), revision: nextRevision(), body, updatedAt: now() };
33
+ rows.set(record.id, record);
34
+ const outcome = { kind: "ok", ref: refOf(record), value: metaOf(record) };
35
+ return Promise.resolve(outcome);
36
+ },
37
+ update(ref, body, signal) {
38
+ const stop = aborted(signal);
39
+ if (stop) return stop;
40
+ const record = rows.get(ref.id);
41
+ if (!record) return Promise.resolve({ kind: "not-found" });
42
+ if (record.revision !== ref.revision) return Promise.resolve({ kind: "conflict", current: refOf(record) });
43
+ record.body = body;
44
+ record.revision = nextRevision();
45
+ record.updatedAt = now();
46
+ const outcome = { kind: "ok", ref: refOf(record), value: metaOf(record) };
47
+ return Promise.resolve(outcome);
48
+ },
49
+ remove(ref, signal) {
50
+ const stop = aborted(signal);
51
+ if (stop) return stop;
52
+ const record = rows.get(ref.id);
53
+ if (!record) return Promise.resolve({ kind: "not-found" });
54
+ if (record.revision !== ref.revision) return Promise.resolve({ kind: "conflict", current: refOf(record) });
55
+ rows.delete(ref.id);
56
+ return Promise.resolve({ kind: "ok", ref: refOf(record) });
57
+ }
58
+ };
59
+ }
60
+ function memorySaveLoadAdapter(options) {
61
+ const now = options?.now ?? (() => Date.now());
62
+ const drawingStores = /* @__PURE__ */ new Map();
63
+ const templateStores = /* @__PURE__ */ new Map();
64
+ return {
65
+ charts: memoryStore(
66
+ (r) => ({ id: r.id, revision: r.revision, name: r.body.name, symbol: r.body.symbol, timeframe: r.body.timeframe, updatedAt: r.updatedAt }),
67
+ now
68
+ ),
69
+ layouts: memoryStore(
70
+ (r) => ({
71
+ id: r.id,
72
+ revision: r.revision,
73
+ name: r.body.name,
74
+ ...r.body.symbol === void 0 ? {} : { symbol: r.body.symbol },
75
+ ...r.body.timeframe === void 0 ? {} : { timeframe: r.body.timeframe },
76
+ updatedAt: r.updatedAt
77
+ }),
78
+ now
79
+ ),
80
+ drawings(context) {
81
+ const key = drawingContextKey(context);
82
+ let store = drawingStores.get(key);
83
+ if (!store) {
84
+ store = memoryStore((r) => ({ id: r.id, revision: r.revision, updatedAt: r.updatedAt }), now);
85
+ drawingStores.set(key, store);
86
+ }
87
+ return store;
88
+ },
89
+ templates(kind) {
90
+ let store = templateStores.get(kind);
91
+ if (!store) {
92
+ store = memoryStore(
93
+ (r) => ({ id: r.id, revision: r.revision, name: r.body.name, ...r.body.tool === void 0 ? {} : { tool: r.body.tool }, updatedAt: r.updatedAt }),
94
+ now
95
+ );
96
+ templateStores.set(kind, store);
97
+ }
98
+ return store;
99
+ }
100
+ };
101
+ }
102
+
103
+ export {
104
+ ResourceAbortError,
105
+ memorySaveLoadAdapter
106
+ };
107
+ //# sourceMappingURL=chunk-KFBQSPNA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/resources.ts"],"sourcesContent":["// SAVED RESOURCES — the revisioned, async persistence contract for the entities a chart names and\n// a user can lose: saved charts, layouts, drawing documents, and templates.\n//\n// The contract exists because a saved chart is shared, mutable, remote state. Two tabs, two\n// devices, or one slow save and one fast one all end at the same question: whose version wins?\n// A store that answers \"the last write\" silently destroys work. So every read hands back a\n// `ResourceRef` (a stable id plus an opaque revision token), every write states the revision it\n// believes it is replacing, and a write against a stale revision comes back as a typed `conflict`\n// carrying the current ref. The chart never resolves that by overwriting; it surfaces it.\n//\n// Three rules the shape enforces:\n// - The revision is OPAQUE. It is a token the host minted and the chart only ever echoes back.\n// No ordering, no arithmetic, no timestamp parsing; a host is free to use an ETag, a counter,\n// or a content hash.\n// - Every call takes an `AbortSignal`. A symbol switch, a closed dialog, or a fast retype must be\n// able to abandon in-flight work, and a late answer to an abandoned ask must never land.\n// - A successful write RETURNS the stored revision, so the caller's next write is conditional on\n// what the store actually holds rather than on what it hoped it wrote.\n//\n// A chart's, a layout's and a template's body is contractually OPAQUE to the store: no parsing, no\n// per-entity logic, so the chart can evolve those formats freely. The drawings family is the one\n// deliberate exception: its body is the structured document in `drawings/document.ts`, because\n// deletion tombstones, ordered groups and per-drawing ownership have to survive a merge between two\n// surfaces, and a merge cannot be performed over a string. Each drawing's own state stays opaque\n// inside its entry.\n//\n// Flat viewer preferences that need no entity identity are NOT here; they stay on `ChartStorage`,\n// the small settings port beside this one.\nimport type { DrawingResourceContext, DrawingsBody } from './drawings/document'\nimport { drawingContextKey } from './drawings/document'\n\n/** A resource's identity plus the exact version this reader saw. A write quotes it back. */\nexport interface ResourceRef {\n id: string\n /** Opaque to the chart: minted by the store, compared only for equality. */\n revision: string\n}\n\n/** What a write did. `ok` carries the ref the store now holds (and, where the store computes one,\n * the resulting metadata); `conflict` carries the ref that beat this write, so a caller can reload\n * and re-decide; `not-found` means the id is gone. */\nexport type WriteOutcome<T = void> =\n | { kind: 'ok'; ref: ResourceRef; value?: T }\n | { kind: 'conflict'; current: ResourceRef }\n | { kind: 'not-found' }\n\n/** One family of resources. `Meta` is the listing row a picker shows without fetching content\n * (it carries the row's ref, so a picker can delete or open a row without a second read); `Body`\n * is the stored document. */\nexport interface ResourceStore<Meta, Body> {\n /** Listing rows, metadata only. */\n list(signal?: AbortSignal): Promise<Meta[]>\n /** The stored document and the revision it was read at, or null when the id is unknown. */\n load(id: string, signal?: AbortSignal): Promise<{ ref: ResourceRef; body: Body } | null>\n /** Store a new document. The store mints the id; a create conflicts only where the store keys a\n * document by identity and one already stands there (a drawings context that holds a document, a\n * name already taken), and then it answers the ref that stands. */\n create(body: Body, signal?: AbortSignal): Promise<WriteOutcome<Meta>>\n /** Replace the document at `ref.id`, but only while it still stands at `ref.revision`. */\n update(ref: ResourceRef, body: Body, signal?: AbortSignal): Promise<WriteOutcome<Meta>>\n /** Delete the document at `ref.id`, but only while it still stands at `ref.revision`. */\n remove(ref: ResourceRef, signal?: AbortSignal): Promise<WriteOutcome<void>>\n}\n\n/** A saved chart's listing row. */\nexport interface ChartMeta extends ResourceRef {\n name: string\n symbol: string\n timeframe: string\n /** Last save, ms since epoch (server-stamped by real backends). */\n updatedAt: number\n}\n\n/** A saved chart. `content` is the chart's own serialized state, opaque to the store. */\nexport interface ChartBody {\n name: string\n symbol: string\n timeframe: string\n content: string\n}\n\n/** A saved multi-chart layout's listing row. `symbol` is the active chart's market as the chart\n * writes it (`symbolNames(...).mark`, such as `BTCUSDC`) and `timeframe` its timeframe token, both\n * as they stood at the last save, so a listing can say what each layout shows without opening it. A\n * store that does not keep them, or a layout saved before they were stated, leaves them out. */\nexport interface LayoutMeta extends ResourceRef {\n name: string\n symbol?: string\n timeframe?: string\n updatedAt: number\n}\n\n/** A saved multi-chart layout. `content` is the arrangement's serialized state, opaque to the store.\n * The widget states the listing's `symbol` and `timeframe` on every save; they are display text and\n * play no part in restoring the layout. */\nexport interface LayoutBody {\n name: string\n symbol?: string\n timeframe?: string\n content: string\n}\n\n/** A drawings document's listing row. A context holds at most one, so `list` returns zero rows or\n * one, and the ref is the store's handle on it. */\nexport interface DrawingsMeta extends ResourceRef {\n updatedAt: number\n}\n\nexport type TemplateKind = 'study' | 'drawing' | 'palette'\n\n/** A named template's listing row. `tool` scopes DRAWING templates to their tool (a trend-line\n * template is meaningless on a rectangle); study and palette templates carry no tool. */\nexport interface TemplateMeta extends ResourceRef {\n name: string\n tool?: string\n updatedAt: number\n}\n\nexport interface TemplateBody {\n name: string\n tool?: string\n content: string\n}\n\n/** The adapter a host implements: four resource families over one revisioned contract. Viewer\n * settings are deliberately absent; they belong to `ChartStorage`. */\nexport interface ChartSaveLoadAdapter {\n charts: ResourceStore<ChartMeta, ChartBody>\n layouts: ResourceStore<LayoutMeta, LayoutBody>\n /** The store for one drawing-resource context. Calling with an equal context returns an\n * equivalent store; `drawingContextKey` is the canonical way to compare two. */\n drawings(context: DrawingResourceContext): ResourceStore<DrawingsMeta, DrawingsBody>\n templates(kind: TemplateKind): ResourceStore<TemplateMeta, TemplateBody>\n}\n\n/** The error every store rejects with when its signal aborts. `name` is 'AbortError', which is what\n * callers branch on, and what `DOMException` uses, so a host may reject with either. */\nexport class ResourceAbortError extends Error {\n override readonly name = 'AbortError'\n constructor(message = 'the resource operation was aborted') {\n super(message)\n }\n}\n\n/* ── The in-memory reference implementation ────────────────────────────────────────────────────\n The shape's own proof and the fixture every consumer test mounts: revisions on every write,\n conflicts on a stale ref, not-found on a vanished id, and an abort that lands before any state\n changes. It persists nothing, so it is also the right adapter for SSR, an ephemeral embed, and\n the clean-room consumer. */\n\ninterface Record_<Body> {\n id: string\n revision: string\n body: Body\n updatedAt: number\n}\n\n/** An aborted signal REJECTS the returned promise rather than throwing out of the call, so every\n * caller handles abandonment on one path. */\nconst aborted = (signal: AbortSignal | undefined): Promise<never> | null =>\n signal?.aborted ? Promise.reject(new ResourceAbortError()) : null\n\nconst newId = (): string =>\n typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : `r${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`\n\n/** Options for {@link memorySaveLoadAdapter}: a clock, so a test can pin `updatedAt`. */\nexport interface MemoryResourcesOptions {\n now?: () => number\n}\n\nfunction memoryStore<Meta, Body>(\n metaOf: (record: Record_<Body>) => Meta,\n now: () => number,\n): ResourceStore<Meta, Body> {\n const rows = new Map<string, Record_<Body>>()\n let counter = 0\n const nextRevision = (): string => `rev-${++counter}`\n const refOf = (record: Record_<Body>): ResourceRef => ({ id: record.id, revision: record.revision })\n\n return {\n list(signal) {\n return aborted(signal) ?? Promise.resolve([...rows.values()].map(metaOf))\n },\n load(id, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record = rows.get(id)\n return Promise.resolve(record ? { ref: refOf(record), body: record.body } : null)\n },\n create(body, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record: Record_<Body> = { id: newId(), revision: nextRevision(), body, updatedAt: now() }\n rows.set(record.id, record)\n const outcome: WriteOutcome<Meta> = { kind: 'ok', ref: refOf(record), value: metaOf(record) }\n return Promise.resolve(outcome)\n },\n update(ref, body, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record = rows.get(ref.id)\n if (!record) return Promise.resolve<WriteOutcome<Meta>>({ kind: 'not-found' })\n if (record.revision !== ref.revision) return Promise.resolve<WriteOutcome<Meta>>({ kind: 'conflict', current: refOf(record) })\n record.body = body\n record.revision = nextRevision()\n record.updatedAt = now()\n const outcome: WriteOutcome<Meta> = { kind: 'ok', ref: refOf(record), value: metaOf(record) }\n return Promise.resolve(outcome)\n },\n remove(ref, signal) {\n const stop = aborted(signal)\n if (stop) return stop\n const record = rows.get(ref.id)\n if (!record) return Promise.resolve<WriteOutcome<void>>({ kind: 'not-found' })\n if (record.revision !== ref.revision) return Promise.resolve<WriteOutcome<void>>({ kind: 'conflict', current: refOf(record) })\n rows.delete(ref.id)\n return Promise.resolve<WriteOutcome<void>>({ kind: 'ok', ref: refOf(record) })\n },\n }\n}\n\n/** An in-memory {@link ChartSaveLoadAdapter}. Each drawing context and each template kind gets its\n * own store, created on first ask and kept, so two calls for one context see the same document. */\nexport function memorySaveLoadAdapter(options?: MemoryResourcesOptions): ChartSaveLoadAdapter {\n const now = options?.now ?? (() => Date.now())\n const drawingStores = new Map<string, ResourceStore<DrawingsMeta, DrawingsBody>>()\n const templateStores = new Map<TemplateKind, ResourceStore<TemplateMeta, TemplateBody>>()\n\n return {\n charts: memoryStore<ChartMeta, ChartBody>(\n (r) => ({ id: r.id, revision: r.revision, name: r.body.name, symbol: r.body.symbol, timeframe: r.body.timeframe, updatedAt: r.updatedAt }),\n now,\n ),\n layouts: memoryStore<LayoutMeta, LayoutBody>(\n (r) => ({\n id: r.id,\n revision: r.revision,\n name: r.body.name,\n ...(r.body.symbol === undefined ? {} : { symbol: r.body.symbol }),\n ...(r.body.timeframe === undefined ? {} : { timeframe: r.body.timeframe }),\n updatedAt: r.updatedAt,\n }),\n now,\n ),\n drawings(context) {\n const key = drawingContextKey(context)\n let store = drawingStores.get(key)\n if (!store) {\n store = memoryStore<DrawingsMeta, DrawingsBody>((r) => ({ id: r.id, revision: r.revision, updatedAt: r.updatedAt }), now)\n drawingStores.set(key, store)\n }\n return store\n },\n templates(kind) {\n let store = templateStores.get(kind)\n if (!store) {\n store = memoryStore<TemplateMeta, TemplateBody>(\n (r) => ({ id: r.id, revision: r.revision, name: r.body.name, ...(r.body.tool === undefined ? {} : { tool: r.body.tool }), updatedAt: r.updatedAt }),\n now,\n )\n templateStores.set(kind, store)\n }\n return store\n },\n }\n}\n"],"mappings":";;;;;AAyIO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC1B,OAAO;AAAA,EACzB,YAAY,UAAU,sCAAsC;AAC1D,UAAM,OAAO;AAAA,EACf;AACF;AAiBA,IAAM,UAAU,CAAC,WACf,QAAQ,UAAU,QAAQ,OAAO,IAAI,mBAAmB,CAAC,IAAI;AAE/D,IAAM,QAAQ,MACZ,OAAO,WAAW,eAAe,OAAO,aAAa,OAAO,WAAW,IAAI,IAAI,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAOjJ,SAAS,YACP,QACA,KAC2B;AAC3B,QAAM,OAAO,oBAAI,IAA2B;AAC5C,MAAI,UAAU;AACd,QAAM,eAAe,MAAc,OAAO,EAAE,OAAO;AACnD,QAAM,QAAQ,CAAC,YAAwC,EAAE,IAAI,OAAO,IAAI,UAAU,OAAO,SAAS;AAElG,SAAO;AAAA,IACL,KAAK,QAAQ;AACX,aAAO,QAAQ,MAAM,KAAK,QAAQ,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC;AAAA,IAC1E;AAAA,IACA,KAAK,IAAI,QAAQ;AACf,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAS,KAAK,IAAI,EAAE;AAC1B,aAAO,QAAQ,QAAQ,SAAS,EAAE,KAAK,MAAM,MAAM,GAAG,MAAM,OAAO,KAAK,IAAI,IAAI;AAAA,IAClF;AAAA,IACA,OAAO,MAAM,QAAQ;AACnB,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAwB,EAAE,IAAI,MAAM,GAAG,UAAU,aAAa,GAAG,MAAM,WAAW,IAAI,EAAE;AAC9F,WAAK,IAAI,OAAO,IAAI,MAAM;AAC1B,YAAM,UAA8B,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,GAAG,OAAO,OAAO,MAAM,EAAE;AAC5F,aAAO,QAAQ,QAAQ,OAAO;AAAA,IAChC;AAAA,IACA,OAAO,KAAK,MAAM,QAAQ;AACxB,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAS,KAAK,IAAI,IAAI,EAAE;AAC9B,UAAI,CAAC,OAAQ,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,CAAC;AAC7E,UAAI,OAAO,aAAa,IAAI,SAAU,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,SAAS,MAAM,MAAM,EAAE,CAAC;AAC7H,aAAO,OAAO;AACd,aAAO,WAAW,aAAa;AAC/B,aAAO,YAAY,IAAI;AACvB,YAAM,UAA8B,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,GAAG,OAAO,OAAO,MAAM,EAAE;AAC5F,aAAO,QAAQ,QAAQ,OAAO;AAAA,IAChC;AAAA,IACA,OAAO,KAAK,QAAQ;AAClB,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,QAAO;AACjB,YAAM,SAAS,KAAK,IAAI,IAAI,EAAE;AAC9B,UAAI,CAAC,OAAQ,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,CAAC;AAC7E,UAAI,OAAO,aAAa,IAAI,SAAU,QAAO,QAAQ,QAA4B,EAAE,MAAM,YAAY,SAAS,MAAM,MAAM,EAAE,CAAC;AAC7H,WAAK,OAAO,IAAI,EAAE;AAClB,aAAO,QAAQ,QAA4B,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,EAAE,CAAC;AAAA,IAC/E;AAAA,EACF;AACF;AAIO,SAAS,sBAAsB,SAAwD;AAC5F,QAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,IAAI;AAC5C,QAAM,gBAAgB,oBAAI,IAAuD;AACjF,QAAM,iBAAiB,oBAAI,IAA6D;AAExF,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,UAAU,MAAM,EAAE,KAAK,MAAM,QAAQ,EAAE,KAAK,QAAQ,WAAW,EAAE,KAAK,WAAW,WAAW,EAAE,UAAU;AAAA,MACxI;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,CAAC,OAAO;AAAA,QACN,IAAI,EAAE;AAAA,QACN,UAAU,EAAE;AAAA,QACZ,MAAM,EAAE,KAAK;AAAA,QACb,GAAI,EAAE,KAAK,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO;AAAA,QAC/D,GAAI,EAAE,KAAK,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,UAAU;AAAA,QACxE,WAAW,EAAE;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,SAAS;AAChB,YAAM,MAAM,kBAAkB,OAAO;AACrC,UAAI,QAAQ,cAAc,IAAI,GAAG;AACjC,UAAI,CAAC,OAAO;AACV,gBAAQ,YAAwC,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,UAAU,WAAW,EAAE,UAAU,IAAI,GAAG;AACxH,sBAAc,IAAI,KAAK,KAAK;AAAA,MAC9B;AACA,aAAO;AAAA,IACT;AAAA,IACA,UAAU,MAAM;AACd,UAAI,QAAQ,eAAe,IAAI,IAAI;AACnC,UAAI,CAAC,OAAO;AACV,gBAAQ;AAAA,UACN,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,UAAU,MAAM,EAAE,KAAK,MAAM,GAAI,EAAE,KAAK,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,KAAK,GAAI,WAAW,EAAE,UAAU;AAAA,UACjJ;AAAA,QACF;AACA,uBAAe,IAAI,MAAM,KAAK;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}