@tellegen/svelte 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +70 -0
  3. package/dist/Sparkline.svelte +100 -0
  4. package/dist/Sparkline.svelte.d.ts +8 -0
  5. package/dist/Sparkline.svelte.d.ts.map +1 -0
  6. package/dist/TellegenMap.svelte +1430 -0
  7. package/dist/TellegenMap.svelte.d.ts +14 -0
  8. package/dist/TellegenMap.svelte.d.ts.map +1 -0
  9. package/dist/TellegenProvider.svelte +38 -0
  10. package/dist/TellegenProvider.svelte.d.ts +9 -0
  11. package/dist/TellegenProvider.svelte.d.ts.map +1 -0
  12. package/dist/TellegenShell.svelte +126 -0
  13. package/dist/TellegenShell.svelte.d.ts +4 -0
  14. package/dist/TellegenShell.svelte.d.ts.map +1 -0
  15. package/dist/TellegenViewer.svelte +19 -0
  16. package/dist/TellegenViewer.svelte.d.ts +4 -0
  17. package/dist/TellegenViewer.svelte.d.ts.map +1 -0
  18. package/dist/api.d.ts +44 -0
  19. package/dist/api.d.ts.map +1 -0
  20. package/dist/api.js +137 -0
  21. package/dist/colors.d.ts +51 -0
  22. package/dist/colors.d.ts.map +1 -0
  23. package/dist/colors.js +140 -0
  24. package/dist/components/AppFooter.svelte +73 -0
  25. package/dist/components/AppFooter.svelte.d.ts +19 -0
  26. package/dist/components/AppFooter.svelte.d.ts.map +1 -0
  27. package/dist/components/AppHeader.svelte +405 -0
  28. package/dist/components/AppHeader.svelte.d.ts +4 -0
  29. package/dist/components/AppHeader.svelte.d.ts.map +1 -0
  30. package/dist/components/BindingLines.svelte +101 -0
  31. package/dist/components/BindingLines.svelte.d.ts +4 -0
  32. package/dist/components/BindingLines.svelte.d.ts.map +1 -0
  33. package/dist/components/BusPicker.svelte +227 -0
  34. package/dist/components/BusPicker.svelte.d.ts +4 -0
  35. package/dist/components/BusPicker.svelte.d.ts.map +1 -0
  36. package/dist/components/ControlPanel.svelte +154 -0
  37. package/dist/components/ControlPanel.svelte.d.ts +19 -0
  38. package/dist/components/ControlPanel.svelte.d.ts.map +1 -0
  39. package/dist/components/DemandSlider.svelte +271 -0
  40. package/dist/components/DemandSlider.svelte.d.ts +4 -0
  41. package/dist/components/DemandSlider.svelte.d.ts.map +1 -0
  42. package/dist/components/DisplayControls.svelte +81 -0
  43. package/dist/components/DisplayControls.svelte.d.ts +19 -0
  44. package/dist/components/DisplayControls.svelte.d.ts.map +1 -0
  45. package/dist/components/DropZone.svelte +46 -0
  46. package/dist/components/DropZone.svelte.d.ts +19 -0
  47. package/dist/components/DropZone.svelte.d.ts.map +1 -0
  48. package/dist/components/FormulationSelector.svelte +82 -0
  49. package/dist/components/FormulationSelector.svelte.d.ts +19 -0
  50. package/dist/components/FormulationSelector.svelte.d.ts.map +1 -0
  51. package/dist/components/LocalCaseDetails.svelte +253 -0
  52. package/dist/components/LocalCaseDetails.svelte.d.ts +4 -0
  53. package/dist/components/LocalCaseDetails.svelte.d.ts.map +1 -0
  54. package/dist/components/MulticonductorDetails.svelte +280 -0
  55. package/dist/components/MulticonductorDetails.svelte.d.ts +19 -0
  56. package/dist/components/MulticonductorDetails.svelte.d.ts.map +1 -0
  57. package/dist/components/NetworkStats.svelte +75 -0
  58. package/dist/components/NetworkStats.svelte.d.ts +19 -0
  59. package/dist/components/NetworkStats.svelte.d.ts.map +1 -0
  60. package/dist/components/PlacementCue.svelte +35 -0
  61. package/dist/components/PlacementCue.svelte.d.ts +19 -0
  62. package/dist/components/PlacementCue.svelte.d.ts.map +1 -0
  63. package/dist/components/RatingSlider.svelte +273 -0
  64. package/dist/components/RatingSlider.svelte.d.ts +4 -0
  65. package/dist/components/RatingSlider.svelte.d.ts.map +1 -0
  66. package/dist/components/RestoreDefaultsButton.svelte +34 -0
  67. package/dist/components/RestoreDefaultsButton.svelte.d.ts +19 -0
  68. package/dist/components/RestoreDefaultsButton.svelte.d.ts.map +1 -0
  69. package/dist/components/SensitivityReadout.svelte +126 -0
  70. package/dist/components/SensitivityReadout.svelte.d.ts +4 -0
  71. package/dist/components/SensitivityReadout.svelte.d.ts.map +1 -0
  72. package/dist/components/SizeLegend.svelte +55 -0
  73. package/dist/components/SizeLegend.svelte.d.ts +19 -0
  74. package/dist/components/SizeLegend.svelte.d.ts.map +1 -0
  75. package/dist/components/SolveCard.svelte +84 -0
  76. package/dist/components/SolveCard.svelte.d.ts +4 -0
  77. package/dist/components/SolveCard.svelte.d.ts.map +1 -0
  78. package/dist/components/TopMovers.svelte +68 -0
  79. package/dist/components/TopMovers.svelte.d.ts +19 -0
  80. package/dist/components/TopMovers.svelte.d.ts.map +1 -0
  81. package/dist/components.d.ts +19 -0
  82. package/dist/components.d.ts.map +1 -0
  83. package/dist/components.js +18 -0
  84. package/dist/context.svelte.d.ts +20 -0
  85. package/dist/context.svelte.d.ts.map +1 -0
  86. package/dist/context.svelte.js +43 -0
  87. package/dist/controller.svelte.d.ts +334 -0
  88. package/dist/controller.svelte.d.ts.map +1 -0
  89. package/dist/controller.svelte.js +2026 -0
  90. package/dist/display.d.ts +31 -0
  91. package/dist/display.d.ts.map +1 -0
  92. package/dist/display.js +63 -0
  93. package/dist/drop-classify.d.ts +48 -0
  94. package/dist/drop-classify.d.ts.map +1 -0
  95. package/dist/drop-classify.js +92 -0
  96. package/dist/format.d.ts +30 -0
  97. package/dist/format.d.ts.map +1 -0
  98. package/dist/format.js +49 -0
  99. package/dist/index.d.ts +21 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +12 -0
  102. package/dist/map.d.ts +9 -0
  103. package/dist/map.d.ts.map +1 -0
  104. package/dist/map.js +4 -0
  105. package/dist/multiconductor.d.ts +63 -0
  106. package/dist/multiconductor.d.ts.map +1 -0
  107. package/dist/multiconductor.js +255 -0
  108. package/dist/state.svelte.d.ts +258 -0
  109. package/dist/state.svelte.d.ts.map +1 -0
  110. package/dist/state.svelte.js +323 -0
  111. package/dist/study-package.d.ts +9 -0
  112. package/dist/study-package.d.ts.map +1 -0
  113. package/dist/study-package.js +17 -0
  114. package/dist/styles.css +393 -0
  115. package/dist/synthetic-layout.d.ts +12 -0
  116. package/dist/synthetic-layout.d.ts.map +1 -0
  117. package/dist/synthetic-layout.js +271 -0
  118. package/dist/types.d.ts +6 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +1 -0
  121. package/package.json +67 -0
@@ -0,0 +1,393 @@
1
+ /* tellegen design tokens: warm paper ground, burnt amber accent, the physics
2
+ owns all other saturation. */
3
+ :root {
4
+ --bg: #ece9e2;
5
+ --panel: rgba(252, 251, 247, 0.92);
6
+ --line: #d9d3c6;
7
+ --ink: #20242b;
8
+ --ink-dim: #6e7378;
9
+ --ink-faint: #989b92;
10
+ --accent: #b25e00;
11
+ --accent-bright: #ffb000;
12
+ --accent-soft: rgba(178, 94, 0, 0.1);
13
+ --red: #b3261e;
14
+ --pos: #762a83;
15
+ --neg: #1b7837;
16
+
17
+ --font-display: 'Bricolage Grotesque Variable', system-ui, sans-serif;
18
+ --font-mono: 'IBM Plex Mono', ui-monospace, monospace;
19
+
20
+ /* channel forms of the grounds, so scrims and shadows derive from one source */
21
+ --bg-rgb: 236 233 226;
22
+ --ink-rgb: 32 36 43;
23
+ --accent-rgb: 178 94 0;
24
+ --paper: #fcfbf7;
25
+ --paper-rgb: 252 251 247;
26
+
27
+ /* Semantic role + scale layer, kept as the target vocabulary for a future
28
+ migration. Most call sites still reference the raw primitives above and
29
+ hardcoded values; only a handful of these (e.g. --radius-xs, --shadow-thumb,
30
+ --dur-fast, --ease-out, the channel forms) are wired up so far. */
31
+ --surface-page: var(--bg);
32
+ --surface-panel: var(--panel);
33
+ --surface-chip: rgb(var(--paper-rgb) / 0.65);
34
+ --surface-control: rgb(var(--paper-rgb) / 0.55);
35
+ --border-default: var(--line);
36
+ --border-strong: var(--accent);
37
+ --text-primary: var(--ink);
38
+ /* --text-secondary/--text-tertiary/--text-accent are independent from
39
+ --ink-dim/--ink-faint/--accent (below) rather than aliased to them:
40
+ the primitives stay lighter/warmer for borders, focus rings, and
41
+ active-state indicators (3:1 or no minimum applies), while the
42
+ text-* tokens are tuned to clear WCAG AA 4.5:1 against --bg. */
43
+ --text-secondary: #4d5156;
44
+ --text-tertiary: #636657;
45
+ --text-accent: #8a4800;
46
+ --text-danger: var(--red);
47
+ --data-pos: var(--pos);
48
+ --data-neg: var(--neg);
49
+ --focus-ring: var(--accent);
50
+
51
+ /* type scale, anchored at the 15px body */
52
+ --fs-display-lg: 33px;
53
+ --fs-display: 22px;
54
+ --fs-title: 18px;
55
+ --fs-heading: 16px;
56
+ --fs-body: 15px;
57
+ --fs-data: 12.5px;
58
+ --fs-label: 12px;
59
+ --fs-control: 11px;
60
+ --fs-meta: 10px;
61
+ --fs-micro: 8.5px;
62
+ --lh-tight: 1.2;
63
+ --lh-snug: 1.35;
64
+ --lh-normal: 1.5;
65
+ --lh-relaxed: 1.55;
66
+
67
+ /* spacing scale */
68
+ --space-3xs: 2px;
69
+ --space-2xs: 4px;
70
+ --space-xs: 6px;
71
+ --space-sm: 8px;
72
+ --space-md: 10px;
73
+ --space-lg: 12px;
74
+ --space-xl: 16px;
75
+ --space-2xl: 20px;
76
+ --space-3xl: 24px;
77
+
78
+ /* radius and elevation */
79
+ --radius-xs: 2px;
80
+ --radius-sm: 3px;
81
+ --radius-full: 50%;
82
+ --elev-1: 0 2px 10px rgb(var(--ink-rgb) / 0.1);
83
+ --elev-2: 0 4px 24px rgb(var(--ink-rgb) / 0.08);
84
+ --shadow-thumb: 0 1px 4px rgb(var(--ink-rgb) / 0.3);
85
+ --inset-active: inset 0 -2px 0 var(--accent);
86
+
87
+ /* motion: durations and easings, zeroed under reduced-motion below */
88
+ --dur-fast: 0.15s;
89
+ --dur-med: 0.3s;
90
+ --dur-slow: 0.5s;
91
+ --delay-panel: 0.12s;
92
+ --delay-footer: 0.24s;
93
+ --dur-blink: 1.2s;
94
+ --dur-bob: 1.8s;
95
+ --ease-out: ease-out;
96
+ --ease-in-out: ease-in-out;
97
+ --ease-standard: ease;
98
+
99
+ /* z-index layers */
100
+ --z-chrome: 10;
101
+ --z-cue: 14;
102
+ --z-overlay: 20;
103
+ --z-grain: 9999;
104
+ }
105
+
106
+ * {
107
+ box-sizing: border-box;
108
+ }
109
+
110
+ html,
111
+ body {
112
+ margin: 0;
113
+ height: 100%;
114
+ background: var(--bg);
115
+ color: var(--ink);
116
+ font-family: var(--font-display);
117
+ font-size: 15px;
118
+ -webkit-font-smoothing: antialiased;
119
+ }
120
+
121
+ /* faint grain over everything; keeps flat panels from looking sterile */
122
+ body::after {
123
+ content: '';
124
+ position: fixed;
125
+ inset: 0;
126
+ pointer-events: none;
127
+ z-index: 9999;
128
+ opacity: 0.04;
129
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
130
+ }
131
+
132
+ .mono {
133
+ font-family: var(--font-mono);
134
+ font-variant-numeric: tabular-nums;
135
+ }
136
+
137
+ a {
138
+ color: var(--text-accent);
139
+ text-decoration: none;
140
+ }
141
+
142
+ /* chrome classes shared by more than one split component; kept global so Svelte
143
+ scoping does not drop them. Moved verbatim from the page <style>. */
144
+ .dim {
145
+ color: var(--text-secondary);
146
+ }
147
+
148
+ .arrow {
149
+ display: inline-block;
150
+ animation: bob 1.8s ease-in-out infinite alternate;
151
+ }
152
+
153
+ .sep {
154
+ width: 4px;
155
+ height: 4px;
156
+ margin: 0 10px;
157
+ background: var(--accent-bright);
158
+ opacity: 0.55;
159
+ transform: rotate(45deg);
160
+ }
161
+
162
+ @media (max-width: 760px) {
163
+ .sep {
164
+ margin: 0 8px;
165
+ }
166
+
167
+ .filedrop-ui {
168
+ display: none;
169
+ }
170
+ }
171
+
172
+ @media (hover: none), (pointer: coarse) {
173
+ .filedrop-ui {
174
+ display: none;
175
+ }
176
+ }
177
+
178
+ /* shared animations, global so split components can reference them */
179
+ @keyframes drop {
180
+ from {
181
+ opacity: 0;
182
+ transform: translateY(-8px);
183
+ }
184
+ }
185
+
186
+ @keyframes rise {
187
+ from {
188
+ opacity: 0;
189
+ transform: translateY(8px);
190
+ }
191
+ }
192
+
193
+ @keyframes blink {
194
+ 50% {
195
+ opacity: 0.35;
196
+ }
197
+ }
198
+
199
+ @keyframes bob {
200
+ to {
201
+ transform: translateY(2px);
202
+ }
203
+ }
204
+
205
+ @media (prefers-reduced-motion: reduce) {
206
+ :root {
207
+ --dur-fast: 0.01ms;
208
+ --dur-med: 0.01ms;
209
+ --dur-slow: 0.01ms;
210
+ --dur-blink: 0.01ms;
211
+ --dur-bob: 0.01ms;
212
+ --delay-panel: 0s;
213
+ --delay-footer: 0s;
214
+ }
215
+
216
+ .arrow {
217
+ animation: none;
218
+ }
219
+ }
220
+
221
+ /* control panel regions: classes used by more than one split region component
222
+ (NetworkStats, FormulationSelector, SensitivityReadout, DemandSlider,
223
+ TopMovers, DisplayControls, SizeLegend, LocalCaseDetails) plus ControlPanel
224
+ itself. Kept global so Svelte scoping does not drop them. Moved verbatim from
225
+ ControlPanel.svelte; the .mode / .display-mode / @media source order is
226
+ preserved so the cascade resolves exactly as before. */
227
+ .region {
228
+ font-size: 10px;
229
+ font-weight: 400;
230
+ color: var(--text-secondary);
231
+ text-transform: uppercase;
232
+ letter-spacing: 0;
233
+ margin-left: 4px;
234
+ }
235
+
236
+ .mode {
237
+ display: flex;
238
+ align-items: center;
239
+ gap: 10px;
240
+ font-size: 12px;
241
+ }
242
+
243
+ /* Kept global (not scoped into SensitivityReadout) so the @media (max-width: 760px)
244
+ `.mode button { margin-left: 0 }` override below wins by source order, as it did
245
+ before the component split. Scoping this would raise its specificity past that rule. */
246
+ .mode > button {
247
+ margin-left: auto;
248
+ font-size: 10.5px;
249
+ padding: 2px 7px;
250
+ background: none;
251
+ border: 1px solid var(--line);
252
+ border-radius: 2px;
253
+ color: var(--text-secondary);
254
+ cursor: pointer;
255
+ }
256
+
257
+ .mode > button:hover {
258
+ border-color: var(--accent);
259
+ color: var(--text-accent);
260
+ }
261
+
262
+ .display-mode {
263
+ gap: 8px;
264
+ }
265
+
266
+ .display-mode .segment button {
267
+ font-size: 11px;
268
+ padding: 2px 9px;
269
+ }
270
+
271
+ .small {
272
+ font-size: 12px;
273
+ line-height: 1.55;
274
+ }
275
+
276
+ .legend {
277
+ height: 6px;
278
+ border-radius: 3px;
279
+ margin-top: 6px;
280
+ }
281
+
282
+ .legend-labels {
283
+ display: flex;
284
+ justify-content: space-between;
285
+ font-size: 10.5px;
286
+ color: var(--text-tertiary);
287
+ margin-top: 4px;
288
+ }
289
+
290
+ .legend-labels.single {
291
+ justify-content: center;
292
+ text-align: center;
293
+ }
294
+
295
+ .hint-dot {
296
+ display: inline-grid;
297
+ place-items: center;
298
+ width: 15px;
299
+ height: 15px;
300
+ border: 1px solid var(--line);
301
+ border-radius: 999px;
302
+ color: var(--text-secondary);
303
+ background: var(--surface-control);
304
+ font-size: 10px;
305
+ line-height: 1;
306
+ cursor: help;
307
+ }
308
+
309
+ .segment {
310
+ display: inline-flex;
311
+ border: 1px solid var(--line);
312
+ border-radius: 2px;
313
+ overflow: hidden;
314
+ background: var(--surface-control);
315
+ }
316
+
317
+ .segment button {
318
+ padding: 2px 8px;
319
+ border: 0;
320
+ background: transparent;
321
+ color: var(--text-secondary);
322
+ font: inherit;
323
+ cursor: pointer;
324
+ }
325
+
326
+ .segment button + button {
327
+ border-left: 1px solid var(--line);
328
+ }
329
+
330
+ .segment button.active {
331
+ background: var(--accent-soft);
332
+ color: var(--text-accent);
333
+ }
334
+
335
+ .reset {
336
+ margin-top: 10px;
337
+ font-size: 10.5px;
338
+ padding: 3px 10px;
339
+ background: none;
340
+ border: 1px solid var(--line);
341
+ border-radius: 2px;
342
+ color: var(--text-secondary);
343
+ cursor: pointer;
344
+ }
345
+
346
+ .reset:hover {
347
+ border-color: var(--red);
348
+ color: var(--red);
349
+ }
350
+
351
+ .blink {
352
+ animation: blink 1.2s steps(2) infinite;
353
+ }
354
+
355
+ @media (max-width: 760px) {
356
+ .mode {
357
+ flex-wrap: wrap;
358
+ gap: 7px;
359
+ }
360
+
361
+ .mode button {
362
+ margin-left: 0;
363
+ }
364
+ }
365
+
366
+ /* Keyboard focus ring: one accent ring for every interactive element. */
367
+ :focus-visible {
368
+ outline: 2px solid var(--focus-ring);
369
+ outline-offset: 2px;
370
+ }
371
+
372
+ /* Coarse pointers: comfortable hit targets for the toggle and reset controls. */
373
+ @media (hover: none), (pointer: coarse) {
374
+ .segment button {
375
+ min-height: 36px;
376
+ }
377
+
378
+ .reset {
379
+ min-height: 36px;
380
+ }
381
+ }
382
+
383
+ /* Honor reduced-motion everywhere: collapse animations and transitions. */
384
+ @media (prefers-reduced-motion: reduce) {
385
+ *,
386
+ *::before,
387
+ *::after {
388
+ animation-duration: 0.01ms !important;
389
+ animation-iteration-count: 1 !important;
390
+ transition-duration: 0.01ms !important;
391
+ scroll-behavior: auto !important;
392
+ }
393
+ }
@@ -0,0 +1,12 @@
1
+ import type { NetworkBranch, NetworkBus } from './api.js';
2
+ import type { Topology } from '@tellegen/engine';
3
+ export interface PlacedNetwork {
4
+ buses: NetworkBus[];
5
+ branches: NetworkBranch[];
6
+ }
7
+ export interface PlacementCenter {
8
+ lon: number;
9
+ lat: number;
10
+ }
11
+ export declare function placeSyntheticTopology(topology: Topology, center: PlacementCenter): PlacedNetwork;
12
+ //# sourceMappingURL=synthetic-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthetic-layout.d.ts","sourceRoot":"","sources":["../src/lib/synthetic-layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACZ;AAKD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,GAAG,aAAa,CAuCjG"}
@@ -0,0 +1,271 @@
1
+ import { extent } from './format.js';
2
+ const ALL_PAIRS_LIMIT = 500;
3
+ export function placeSyntheticTopology(topology, center) {
4
+ const buses = [...topology.buses].sort((a, b) => a.id - b.id);
5
+ const index = new Map(buses.map((bus, i) => [bus.id, i]));
6
+ const edges = topology.branches
7
+ .filter((branch) => branch.status !== 0 && index.has(branch.from) && index.has(branch.to))
8
+ .map((branch) => [index.get(branch.from), index.get(branch.to)])
9
+ .filter(([from, to]) => from !== to);
10
+ const unit = forceLayout(buses.length, edges);
11
+ const span = Math.min(4.5, Math.max(0.32, Math.sqrt(Math.max(buses.length, 1)) * 0.08));
12
+ const lonScale = Math.max(Math.cos((center.lat * Math.PI) / 180), 0.25);
13
+ const latSpan = span;
14
+ const lonSpan = span / lonScale;
15
+ const coords = new Map();
16
+ for (let i = 0; i < buses.length; i++) {
17
+ const p = unit[i] ?? { x: 0.5, y: 0.5 };
18
+ coords.set(buses[i].id, [
19
+ center.lon + (p.x - 0.5) * lonSpan,
20
+ center.lat + (p.y - 0.5) * latSpan
21
+ ]);
22
+ }
23
+ return {
24
+ buses: buses.map((bus) => {
25
+ const [lon, lat] = coords.get(bus.id);
26
+ return { id: bus.id, uid: bus.uid, lon, lat, demand_mw: bus.demand_mw, gen_mw: bus.gen_mw };
27
+ }),
28
+ branches: topology.branches
29
+ .filter((branch) => coords.has(branch.from) && coords.has(branch.to))
30
+ .map((branch) => ({
31
+ id: branch.id,
32
+ uid: branch.uid,
33
+ from: branch.from,
34
+ to: branch.to,
35
+ rate_mw: branch.rate_mw,
36
+ status: branch.status,
37
+ path: [coords.get(branch.from), coords.get(branch.to)]
38
+ }))
39
+ };
40
+ }
41
+ function forceLayout(n, edges) {
42
+ if (n === 0)
43
+ return [];
44
+ if (n === 1)
45
+ return [{ x: 0.5, y: 0.5 }];
46
+ if (n > ALL_PAIRS_LIMIT)
47
+ return fastGraphLayout(n, edges);
48
+ const golden = Math.PI * (3 - Math.sqrt(5));
49
+ const pos = Array.from({ length: n }, (_, i) => {
50
+ const r = 0.44 * Math.sqrt((i + 0.5) / n);
51
+ const theta = i * golden;
52
+ return {
53
+ x: 0.5 + r * Math.cos(theta) + 1e-4 * Math.sin(0.7 * (i + 1)),
54
+ y: 0.5 + r * Math.sin(theta) + 1e-4 * Math.cos(1.3 * (i + 1))
55
+ };
56
+ });
57
+ const disp = Array.from({ length: n }, () => ({ x: 0, y: 0 }));
58
+ const k2 = 1 / n;
59
+ const k = Math.sqrt(k2);
60
+ const iters = n <= 120 ? 180 : n <= 500 ? 100 : 32;
61
+ for (let iter = 0; iter < iters; iter++) {
62
+ for (const d of disp) {
63
+ d.x = 0;
64
+ d.y = 0;
65
+ }
66
+ for (let i = 0; i < n; i++) {
67
+ for (let j = i + 1; j < n; j++) {
68
+ const dx = pos[i].x - pos[j].x;
69
+ const dy = pos[i].y - pos[j].y;
70
+ const f = k2 / (dx * dx + dy * dy + 1e-6);
71
+ disp[i].x += dx * f;
72
+ disp[i].y += dy * f;
73
+ disp[j].x -= dx * f;
74
+ disp[j].y -= dy * f;
75
+ }
76
+ }
77
+ for (const [i, j] of edges) {
78
+ const dx = pos[i].x - pos[j].x;
79
+ const dy = pos[i].y - pos[j].y;
80
+ const f = Math.sqrt(dx * dx + dy * dy) / k;
81
+ disp[i].x -= dx * f;
82
+ disp[i].y -= dy * f;
83
+ disp[j].x += dx * f;
84
+ disp[j].y += dy * f;
85
+ }
86
+ const t = 0.1 * (1 - iter / iters) + 1e-3;
87
+ for (let i = 0; i < n; i++) {
88
+ const d = Math.hypot(disp[i].x, disp[i].y) + 1e-9;
89
+ const s = Math.min(d, t) / d;
90
+ pos[i].x = clamp(pos[i].x + disp[i].x * s);
91
+ pos[i].y = clamp(pos[i].y + disp[i].y * s);
92
+ }
93
+ }
94
+ return normalize(pos);
95
+ }
96
+ function fastGraphLayout(n, edges) {
97
+ const adjacency = graph(n, edges);
98
+ const components = connectedComponents(adjacency);
99
+ const cols = Math.ceil(Math.sqrt(components.length));
100
+ const rows = Math.ceil(components.length / cols);
101
+ const pos = Array.from({ length: n }, () => ({ x: 0.5, y: 0.5 }));
102
+ const cellScale = 0.82 / Math.max(cols, rows);
103
+ for (let c = 0; c < components.length; c++) {
104
+ const nodes = components[c];
105
+ const local = componentLayout(nodes, adjacency);
106
+ const col = c % cols;
107
+ const row = Math.floor(c / cols);
108
+ const cx = (col + 0.5) / cols;
109
+ const cy = (row + 0.5) / rows;
110
+ for (const node of nodes) {
111
+ const p = local.get(node) ?? { x: 0.5, y: 0.5 };
112
+ pos[node] = {
113
+ x: cx + (p.x - 0.5) * cellScale,
114
+ y: cy + (p.y - 0.5) * cellScale
115
+ };
116
+ }
117
+ }
118
+ return normalize(pos);
119
+ }
120
+ function graph(n, edges) {
121
+ const adjacency = Array.from({ length: n }, () => []);
122
+ const seen = new Set();
123
+ for (const [from, to] of edges) {
124
+ if (from < 0 || to < 0 || from >= n || to >= n || from === to)
125
+ continue;
126
+ const a = Math.min(from, to);
127
+ const b = Math.max(from, to);
128
+ const key = a * n + b;
129
+ if (seen.has(key))
130
+ continue;
131
+ seen.add(key);
132
+ adjacency[a].push(b);
133
+ adjacency[b].push(a);
134
+ }
135
+ for (const neighbors of adjacency)
136
+ neighbors.sort((a, b) => a - b);
137
+ return adjacency;
138
+ }
139
+ function connectedComponents(adjacency) {
140
+ const seen = new Uint8Array(adjacency.length);
141
+ const components = [];
142
+ for (let start = 0; start < adjacency.length; start++) {
143
+ if (seen[start])
144
+ continue;
145
+ const nodes = [];
146
+ const stack = [start];
147
+ seen[start] = 1;
148
+ while (stack.length > 0) {
149
+ const node = stack.pop();
150
+ nodes.push(node);
151
+ for (const next of adjacency[node]) {
152
+ if (seen[next])
153
+ continue;
154
+ seen[next] = 1;
155
+ stack.push(next);
156
+ }
157
+ }
158
+ nodes.sort((a, b) => a - b);
159
+ components.push(nodes);
160
+ }
161
+ components.sort((a, b) => b.length - a.length || a[0] - b[0]);
162
+ return components;
163
+ }
164
+ function componentLayout(nodes, adjacency) {
165
+ if (nodes.length === 1)
166
+ return new Map([[nodes[0], { x: 0.5, y: 0.5 }]]);
167
+ const nodeToLocal = new Map(nodes.map((node, i) => [node, i]));
168
+ const seed = nodes.reduce((best, node) => adjacency[node].length > adjacency[best].length ||
169
+ (adjacency[node].length === adjacency[best].length && node < best)
170
+ ? node
171
+ : best);
172
+ const order = bfsOrder(seed, adjacency);
173
+ const golden = Math.PI * (3 - Math.sqrt(5));
174
+ const pos = Array.from({ length: nodes.length }, () => ({ x: 0.5, y: 0.5 }));
175
+ const initial = Array.from({ length: nodes.length }, () => ({ x: 0.5, y: 0.5 }));
176
+ for (let rank = 0; rank < order.length; rank++) {
177
+ const local = nodeToLocal.get(order[rank]);
178
+ if (local === undefined)
179
+ continue;
180
+ const r = 0.47 * Math.sqrt((rank + 0.5) / nodes.length);
181
+ const theta = rank * golden;
182
+ const p = {
183
+ x: 0.5 + r * Math.cos(theta),
184
+ y: 0.5 + r * Math.sin(theta)
185
+ };
186
+ pos[local] = { ...p };
187
+ initial[local] = p;
188
+ }
189
+ const localEdges = [];
190
+ for (const node of nodes) {
191
+ const a = nodeToLocal.get(node);
192
+ for (const next of adjacency[node]) {
193
+ if (next <= node)
194
+ continue;
195
+ const b = nodeToLocal.get(next);
196
+ if (b !== undefined)
197
+ localEdges.push([a, b]);
198
+ }
199
+ }
200
+ relaxEdges(pos, initial, localEdges);
201
+ const out = new Map();
202
+ const normalized = normalize(pos);
203
+ for (const [i, node] of nodes.entries())
204
+ out.set(node, normalized[i]);
205
+ return out;
206
+ }
207
+ function bfsOrder(seed, adjacency) {
208
+ const seen = new Uint8Array(adjacency.length);
209
+ const order = [];
210
+ const queue = [seed];
211
+ seen[seed] = 1;
212
+ for (let head = 0; head < queue.length; head++) {
213
+ const node = queue[head];
214
+ order.push(node);
215
+ for (const next of adjacency[node]) {
216
+ if (seen[next])
217
+ continue;
218
+ seen[next] = 1;
219
+ queue.push(next);
220
+ }
221
+ }
222
+ return order;
223
+ }
224
+ function relaxEdges(pos, initial, edges) {
225
+ const n = pos.length;
226
+ const disp = Array.from({ length: n }, () => ({ x: 0, y: 0 }));
227
+ const rest = Math.max(0.012, Math.min(0.06, 1.4 / Math.sqrt(n)));
228
+ const iters = n <= 2000 ? 72 : n <= 10000 ? 42 : 24;
229
+ for (let iter = 0; iter < iters; iter++) {
230
+ for (const d of disp) {
231
+ d.x = 0;
232
+ d.y = 0;
233
+ }
234
+ for (const [i, j] of edges) {
235
+ const dx = pos[j].x - pos[i].x;
236
+ const dy = pos[j].y - pos[i].y;
237
+ const dist = Math.hypot(dx, dy) + 1e-9;
238
+ const f = (dist - rest) * 0.045;
239
+ const fx = (dx / dist) * f;
240
+ const fy = (dy / dist) * f;
241
+ disp[i].x += fx;
242
+ disp[i].y += fy;
243
+ disp[j].x -= fx;
244
+ disp[j].y -= fy;
245
+ }
246
+ for (let i = 0; i < n; i++) {
247
+ disp[i].x += (initial[i].x - pos[i].x) * 0.012;
248
+ disp[i].y += (initial[i].y - pos[i].y) * 0.012;
249
+ }
250
+ const t = 0.055 * (1 - iter / iters) + 0.002;
251
+ for (let i = 0; i < n; i++) {
252
+ const d = Math.hypot(disp[i].x, disp[i].y) + 1e-9;
253
+ const s = Math.min(d, t) / d;
254
+ pos[i].x = clamp(pos[i].x + disp[i].x * s);
255
+ pos[i].y = clamp(pos[i].y + disp[i].y * s);
256
+ }
257
+ }
258
+ }
259
+ function normalize(pos) {
260
+ const { min: minX, max: maxX } = extent(pos.map((p) => p.x));
261
+ const { min: minY, max: maxY } = extent(pos.map((p) => p.y));
262
+ const sx = maxX - minX || 1;
263
+ const sy = maxY - minY || 1;
264
+ return pos.map((p) => ({
265
+ x: 0.04 + ((p.x - minX) / sx) * 0.92,
266
+ y: 0.04 + ((p.y - minY) / sy) * 0.92
267
+ }));
268
+ }
269
+ function clamp(v) {
270
+ return Math.max(0, Math.min(1, v));
271
+ }
@@ -0,0 +1,6 @@
1
+ export type { CaseSummary, DemandDeltas, Network, NetworkBranch, NetworkBus, SensitivityColumn, Solution, SolveIteration, SolveStreamHandlers } from './api.js';
2
+ export type { DisplayOption } from './display.js';
3
+ export type { PlacedNetwork, PlacementCenter } from './synthetic-layout.js';
4
+ export type { DemandRangeMode, DisplayMode, FallbackTarget, LocalCaseInit, LocalSubstations, SolvableCase, SolveBackend } from './state.svelte.js';
5
+ export type { AppliedGeoCase, CaseFileSummary, DisplayPreview, Formulation, GeoApplyReport, IngestedCase, ParsedGeoLayer, StampedLayoutCase, Topology, TopologyBranch, TopologyBus } from '@tellegen/engine';
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/lib/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,WAAW,EACX,YAAY,EACZ,OAAO,EACP,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,WAAW,EACX,MAAM,kBAAkB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};