@fnndsc/argus 0.7.1 → 0.8.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 (47) hide show
  1. package/dist/assets/ChRISlogo-color-t-i99soF.svg +164 -0
  2. package/dist/assets/MesloLGS-NF-Bold-DbxbaV6p.ttf +0 -0
  3. package/dist/assets/MesloLGS-NF-Regular-DAUcZJjt.ttf +0 -0
  4. package/dist/assets/Settings-CMzJFOfL.js +4204 -0
  5. package/dist/assets/Texture-BDt8D144.js +204 -0
  6. package/dist/assets/_commonjsHelpers-CE1G-McA.js +1 -0
  7. package/dist/assets/addVolumesToViewports-BJ9Z0Fli.js +1 -0
  8. package/dist/assets/antonio-latin-400-normal-CZjzwNAN.woff2 +0 -0
  9. package/dist/assets/antonio-latin-700-normal-DSH-lEDG.woff2 +0 -0
  10. package/dist/assets/blosc-CrUiACa7.js +17 -0
  11. package/dist/assets/chakra-petch-latin-400-normal-SafcrIr2.woff2 +0 -0
  12. package/dist/assets/chakra-petch-latin-500-normal-BR1ody1F.woff2 +0 -0
  13. package/dist/assets/chakra-petch-latin-600-normal-DVQm9bgb.woff2 +0 -0
  14. package/dist/assets/chakra-petch-latin-700-normal-CnDBPjkL.woff2 +0 -0
  15. package/dist/assets/charlswasm_decode-BrO4esUm.wasm +0 -0
  16. package/dist/assets/chunk-INHXZS53-D3tQiqtZ.js +1 -0
  17. package/dist/assets/computeWorker-D8XJyv-f.js +4095 -0
  18. package/dist/assets/cornerstoneEngine-qc8bYyDr.js +2 -0
  19. package/dist/assets/dcmjs.es-DfWkgqfk.js +18 -0
  20. package/dist/assets/decodeImageFrameWorker-BtcTb_T6.js +5 -0
  21. package/dist/assets/index-10pyAQdJ.js +1 -0
  22. package/dist/assets/index-B4T3qklv.js +4146 -0
  23. package/dist/assets/index-BAUvhEVf.js +2 -0
  24. package/dist/assets/index-BSAANhUs.js +9 -0
  25. package/dist/assets/index-CH659Lsh.js +1 -0
  26. package/dist/assets/index-CIsP81Nj.js +1 -0
  27. package/dist/assets/index-CLU1nvoG.css +1 -0
  28. package/dist/assets/index-DqTe_N1t.js +320 -0
  29. package/dist/assets/index-zZYmeu9b.js +2456 -0
  30. package/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  31. package/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  32. package/dist/assets/jpeg-B-x1txLf.js +1 -0
  33. package/dist/assets/libjpegturbowasm_decode-7ZJ2wGuU.wasm +0 -0
  34. package/dist/assets/lossless-CyYqoyFe.js +1 -0
  35. package/dist/assets/lz4-B_Exjfmr.js +15 -0
  36. package/dist/assets/niivueEngine-Cm8JnIlj.js +2 -0
  37. package/dist/assets/openjpegwasm_decode-B3gWTHpv.wasm +0 -0
  38. package/dist/assets/openjphjs-B5O5ikHp.wasm +0 -0
  39. package/dist/assets/slabScene-Cj6qXA56.js +559 -0
  40. package/dist/assets/throttle-CjIII7Yf.js +1 -0
  41. package/dist/assets/zstd-u5eweWyS.js +15 -0
  42. package/dist/index.html +667 -0
  43. package/dist/sounds/arrive.wav +0 -0
  44. package/dist/sounds/press.wav +0 -0
  45. package/dist/sounds/refuse.wav +0 -0
  46. package/dist/sounds/retreat.wav +0 -0
  47. package/package.json +4 -3
@@ -0,0 +1,667 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <meta name="format-detection" content="telephone=no" />
7
+ <meta name="format-detection" content="date=no" />
8
+ <title>ARGUS</title>
9
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
+ <link
12
+ href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap"
13
+ rel="stylesheet"
14
+ />
15
+ <script type="module" crossorigin src="./assets/index-B4T3qklv.js"></script>
16
+ <link rel="stylesheet" crossorigin href="./assets/index-CLU1nvoG.css">
17
+ </head>
18
+ <body>
19
+ <!-- ARGUS's own four sounds, synthesised rather than borrowed
20
+ (scripts/sounds_make.mjs): a press acknowledged, a thing arriving,
21
+ a retreat, a refusal. -->
22
+ <!-- The four voices. The original TheLCARS.com beeps play when present
23
+ (materialized from the operator's LCARS-26.zip by
24
+ scripts/sounds_import.mjs into public/sounds/, gitignored because
25
+ the template's EULA forbids redistributing them); the synthesised
26
+ .wav is the committed fallback, so a clone without the zip still
27
+ answers a press. Served from public/ so the browser can fall from
28
+ one source to the next — a bundled import cannot. -->
29
+ <audio id="audio1" preload="auto"><source src="sounds/press.mp3" type="audio/mpeg" /><source src="sounds/press.wav" type="audio/wav" /></audio>
30
+ <audio id="audio2" preload="auto"><source src="sounds/arrive.mp3" type="audio/mpeg" /><source src="sounds/arrive.wav" type="audio/wav" /></audio>
31
+ <audio id="audio3" preload="auto"><source src="sounds/retreat.mp3" type="audio/mpeg" /><source src="sounds/retreat.wav" type="audio/wav" /></audio>
32
+ <audio id="audio4" preload="auto"><source src="sounds/refuse.mp3" type="audio/mpeg" /><source src="sounds/refuse.wav" type="audio/wav" /></audio>
33
+
34
+ <div id="attach-form" class="attach-overlay">
35
+ <div class="attach-card">
36
+ <h1>ARGUS</h1>
37
+ <p>Attach to a CALYPSO session. The daemon printed the token at launch.</p>
38
+ <input id="attach-token" type="password" placeholder="ATTACH TOKEN" autocomplete="off" />
39
+ <button id="attach-submit" type="button">ATTACH</button>
40
+ <p id="attach-error" class="attach-error"></p>
41
+ </div>
42
+ </div>
43
+
44
+ <div class="wrap-all">
45
+ <div class="wrap">
46
+ <div class="left-frame-top">
47
+ <button class="panel-1"><span class="brand-mark" aria-hidden="true"></span><span class="brand-label">ARGUS<span class="hop">&nbsp;WEB</span></span></button>
48
+ <button class="panel-2">02<span class="hop">-CALYPSO</span></button>
49
+ </div>
50
+ <div class="right-frame-top">
51
+ <div class="banner"><a href="">ARGUS</a> &bull; CALYPSO SESSION</div>
52
+ <div class="data-cascade-button-group">
53
+ <!-- The header pane: data-header on <body> picks the face.
54
+ Resting face: the pipeline DAG cycler (also 02-CALYPSO).
55
+ ARGUS WEB: live stats, controls, versions, credits. -->
56
+ <div class="header-face" id="header-dag">
57
+ <div id="pipeline-cycler"><span id="pipeline-cycler-name"></span></div>
58
+ <div id="header-dag-info">
59
+ <div class="header-controls">
60
+ <button id="audio-pill" class="audio-pill" title="audio on/off">AUDIO</button>
61
+ <button id="theme-pill" class="theme-pill" title="cycle the theme">LOWER DECKS</button>
62
+ </div>
63
+ <div id="about-rows"></div>
64
+ <footer class="about-footer">
65
+ Content &copy; 2026 FNNDSC &bull; ARGUS is part of the mise project, a ChRIS system interface.<br />
66
+ <!-- The following attribution must not be removed: -->
67
+ LCARS Inspired Website Template by <a href="https://www.thelcars.com">www.TheLCARS.com</a>,
68
+ adapted for ARGUS.
69
+ </footer>
70
+ </div>
71
+ </div>
72
+ <!-- The ARGUS WEB face: live telemetry. The INDEX instrument
73
+ heads it — index movement, read here: a quiet index says
74
+ CURRENT; a sweep, a feed's walk, or arrivals each take a
75
+ row with a bar while they move — and the cascade's labeled
76
+ rows follow. -->
77
+ <div class="header-face" id="header-telemetry"><div id="index-instrument"></div><div id="lane-instrument"></div></div>
78
+ </div>
79
+ <div class="bar-panel first-bar-panel">
80
+ <div class="bar-1"></div>
81
+ <div class="bar-2"></div>
82
+ <div class="bar-3"></div>
83
+ <div class="bar-4"></div>
84
+ <div class="bar-5"></div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ <div class="wrap" id="gap">
89
+ <div class="left-frame">
90
+ <div>
91
+ <button class="panel-3 domain-live" id="gutter-files" title="the console's browser: the workspace, following the session cwd">FILES<span class="hop">-01</span></button>
92
+ <button class="panel-4 domain-live" id="gutter-runs">RUNS<span class="hop">-02</span></button>
93
+ <button class="panel-5 domain-live" id="gutter-tools">PACS<span class="hop">-03</span></button>
94
+ <button class="panel-6 domain-inert">SOURCES<span class="hop">-04</span></button>
95
+ <button class="panel-console domain-live" id="gutter-console" title="summon the console">CONSOLE<span class="hop">-05</span></button>
96
+ <button class="panel-lang domain-live" id="lang-pill" title="the argus command line (Ctrl-B :)">LANG</button>
97
+ <div class="panel-spacer"></div>
98
+ </div>
99
+ <div>
100
+ <button class="panel-7 domain-live" id="gutter-panes" title="every pane you have moved away from, to bring back">PANES<span class="hop">-06</span></button>
101
+ </div>
102
+ </div>
103
+ <div class="right-frame">
104
+ <!-- The tactical drawer: the console unfurls from behind the
105
+ workspace lid (the bar-panel below), per the prototype's
106
+ interaction design. -->
107
+ <section id="drawer">
108
+ <div class="lcars-terminal-header-bar pane-handle" id="console-handle" title="console controls">
109
+ <div class="lcars-bar-horizontal">
110
+ <span class="lcars-title">CALYPSO CONSOLE</span>
111
+ <span class="lcars-terminal-status" id="drawer-status">MODE: [OFFLINE]</span>
112
+
113
+ </div>
114
+ <div class="lcars-bar-end bar-punctuation"></div>
115
+ </div>
116
+ <!-- The console is a pane that does not split: the same handle
117
+ and drawer as every pane, with only the verbs that apply —
118
+ no SPLIT (one session, one voice), hence no binding. -->
119
+ <div class="pane-drawer" id="console-drawer" hidden>
120
+ <span class="drawer-group drawer-structure">
121
+ <span class="drawer-label">CONSOLE</span>
122
+ <button class="pacs-capsule drawer-zoom" data-pane="console" title="zoom the console (Esc restores)">ZOOM</button>
123
+ <button class="pacs-capsule console-retract" title="retract the console (the lid reopens it)">CLOSE</button>
124
+ </span>
125
+ </div>
126
+ <div id="terminal"></div>
127
+ <div id="drawer-strip" title="drag to resize"></div>
128
+ </section>
129
+ <div class="bar-panel" id="drawer-toggle" title="open/close the console" role="button" tabindex="0">
130
+ <div class="bar-6"></div>
131
+ <div class="bar-7"></div>
132
+ <div class="bar-8"></div>
133
+ <div class="bar-9"></div>
134
+ <div class="bar-10"></div>
135
+ </div>
136
+ <main>
137
+ <div id="status-strip">
138
+ <span id="status-identity" class="readout">&mdash;</span>
139
+ <span id="status-jobs" class="readout">&mdash;</span>
140
+ <span id="status-activity" class="readout"></span>
141
+ <span id="status-latency" class="readout"></span>
142
+ <span id="status-mismatch" class="readout mismatch"></span>
143
+ <span id="status-host" class="readout lamp-host"></span>
144
+ <span id="status-lamp" class="readout lamp-offline">OFFLINE</span>
145
+ </div>
146
+ <!-- The layout root: the binary split tree renders here,
147
+ arranging the registered panes. Presets (the gutter) pick
148
+ the tree; context (a feed in view) can vary it. -->
149
+ <div id="layout-root"></div>
150
+ <!-- Pane templates: the registry stamps instances from these;
151
+ every instance is a long-lived mount the tree reparents.
152
+ At rest a pane shows only work and state: the machinery
153
+ (split, zoom, close, semantic children) lives in the pane
154
+ drawer behind the top border — click the header to open it.
155
+ Design record: docs/aegis.adoc. -->
156
+ <template id="tpl-pane-dag">
157
+ <div class="workspace-pane pane-dag">
158
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
159
+ <div class="lcars-bar-horizontal">
160
+ <span class="lcars-title dag-title">DAG</span>
161
+ <span class="pane-mode"></span>
162
+ <span class="pane-state"></span>
163
+ </div>
164
+ <div class="lcars-bar-end bar-punctuation"></div>
165
+ </div>
166
+ <div class="pane-drawer" hidden>
167
+ <!-- The drawer grammar (docs/aegis.adoc): shape the tile,
168
+ bind a neighbour. Two groups, two colors, identical on
169
+ every pane at every depth. The third group is gone from
170
+ a browser: what acts on the field moved to the frame
171
+ and what acts on a row moved to the row, since a
172
+ control lives where it acts. -->
173
+ <span class="drawer-group drawer-structure">
174
+ <span class="drawer-label">SPLIT</span>
175
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
176
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
177
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
178
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
179
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
180
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
181
+ </span>
182
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
183
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
184
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
185
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
186
+ </span>
187
+ <span class="drawer-group drawer-children"></span>
188
+ </div>
189
+ <div class="dag-canvas">
190
+ <!-- The field carries content only. Its frame is a rule
191
+ along the top turning through an elbow into a spine
192
+ down the right edge; the MODE FRAME's blocks slide in
193
+ against the spine when the spine is touched, and
194
+ retract when the field (or Esc) is — the header's own
195
+ retraction grammar at pane scale (docs/aegis.adoc:
196
+ field-is-content, frame-retracts-to-a-strip). -->
197
+ <span class="field-rule"></span>
198
+ <button class="mode-strip" title="display modes" aria-label="display modes"></button>
199
+ <span class="mode-elbow"></span>
200
+ <aside class="mode-frame">
201
+ <button class="strategy-pill dag-strategy" title="layout: ranked tiers or force molecule">RANKED</button>
202
+ <button class="strategy-pill dag-projection" title="projection: sculpted 3D or flat schematic">3D</button>
203
+ <button class="strategy-pill dag-pulse" title="replay execution as a dependency wave">PULSE OFF</button>
204
+ <button class="strategy-pill dag-scale" title="molecule node size: wall time or output bytes">TIME</button>
205
+ <button class="strategy-pill dag-census" title="projection density: semantic shape or full census (spectacle)">SHAPE</button>
206
+ <button class="strategy-pill dag-gravity" title="mass-weighted centering: the heaviest stage settles at the heart">GRAVITY OFF</button>
207
+ <button class="strategy-pill dag-hue" title="what colors a node: its status, or the compute resource it ran on">STATUS</button>
208
+ <span class="mode-fill"></span>
209
+ </aside>
210
+ <!-- Selection facts overlay the scene: the graph never
211
+ resizes when a node is indicated. -->
212
+ <div class="dag-facts"></div>
213
+ </div>
214
+ <!-- The roster host: the feed roster is a field of its own,
215
+ framed the same way, with FILTER as its one mode. -->
216
+ <div class="dag-roster">
217
+ <span class="field-rule"></span>
218
+ <button class="mode-strip" title="display modes" aria-label="display modes"></button>
219
+ <span class="mode-elbow"></span>
220
+ <aside class="mode-frame">
221
+ <button class="strategy-pill runs-filter" title="filter the roster (the bar reads FILTERED n/m)">FILTER OFF</button>
222
+ <span class="mode-fill"></span>
223
+ </aside>
224
+ <div class="dag-feedlist"></div>
225
+ </div>
226
+ <div class="dag-empty files-empty">NO FEED IN VIEW &mdash; PRESS RUNS-02, cd INTO A FEED, OR RUN `feed diagram &lt;feed&gt;`</div>
227
+ </div>
228
+ </template>
229
+ <template id="tpl-pane-files">
230
+ <div class="workspace-pane pane-files">
231
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
232
+ <div class="lcars-bar-horizontal">
233
+ <span class="lcars-title pane-title">WORKSPACE</span>
234
+ <span class="pane-mode"></span>
235
+ <span class="pane-state"></span>
236
+ </div>
237
+ <div class="lcars-bar-end bar-punctuation"></div>
238
+ </div>
239
+ <div class="pane-drawer" hidden>
240
+ <!-- The drawer grammar (docs/aegis.adoc): shape the tile,
241
+ bind a neighbour. Two groups, two colors, identical on
242
+ every pane at every depth. The third group is gone from
243
+ a browser: what acts on the field moved to the frame
244
+ and what acts on a row moved to the row, since a
245
+ control lives where it acts. -->
246
+ <span class="drawer-group drawer-structure">
247
+ <span class="drawer-label">SPLIT</span>
248
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
249
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
250
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
251
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
252
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
253
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
254
+ </span>
255
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
256
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
257
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
258
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
259
+ </span>
260
+ <span class="drawer-group drawer-children"></span>
261
+ </div>
262
+ <!-- The listing body: content only; the projection lives on
263
+ the mode frame at its right edge (a strip at rest). -->
264
+ <div class="files-body">
265
+ <span class="field-rule"></span>
266
+ <button class="mode-strip" title="display modes" aria-label="display modes"></button>
267
+ <span class="mode-elbow"></span>
268
+ <aside class="mode-frame">
269
+ <button class="strategy-pill files-view" title="projection: rows, cards, or previews">LIST</button>
270
+ <button class="strategy-pill files-filter" title="filter the listing (the bar reads FILTERED n/m)">FILTER OFF</button>
271
+ <!-- Where the field points is the field's own business,
272
+ so the two verbs that move it live on the frame with
273
+ the rest of what answers to the field (aegis.adoc:
274
+ a-control-lives-where-it-acts). -->
275
+ <button class="strategy-pill files-home" title="show the home directory">HOME</button>
276
+ <button class="strategy-pill files-back" title="return to the previous listing">BACK</button>
277
+ <!-- Two verbs that act on the PLACE rather than on a
278
+ row, so they ride the field's frame with the rest of
279
+ what answers to the field. They appear on a files
280
+ frame and nowhere else: there is no directory to
281
+ make in a list of feeds. -->
282
+ <button class="strategy-pill files-mkdir" title="make a directory in the listing on stage">MKDIR</button>
283
+ <button class="strategy-pill files-upload" title="put a local file into the listing on stage">UPLOAD</button>
284
+ <input class="files-upload-input" type="file" multiple hidden />
285
+ <!-- SELECT is a MODE: it changes what a click means, so
286
+ it is a block on the frame like every other mode.
287
+ The selection's own verbs ride the frame beneath
288
+ it, because a selection belongs to the field. -->
289
+ <button class="strategy-pill files-select rail-off" title="select rows instead of indicating them">SELECT OFF</button>
290
+ <span class="files-selection-bar listing-actions" hidden></span>
291
+ <!-- A pane has ONE frame, and its blocks answer to what
292
+ the field currently holds: a listing offers a
293
+ projection and a filter, a diagram offers the modes
294
+ a graph has. Offering LIST over a pipeline's DAG
295
+ was a control that could not act. -->
296
+ <button class="strategy-pill diagram-strategy" title="layout: ranked tiers or force molecule">RANKED</button>
297
+ <button class="strategy-pill diagram-projection" title="projection: sculpted 3D or flat schematic">3D</button>
298
+ <button class="strategy-pill diagram-pulse" title="replay the graph as a dependency wave (one pass)">PULSE</button>
299
+ <span class="mode-fill"></span>
300
+ </aside>
301
+ <section class="files-panel" aria-label="Files"></section>
302
+ </div>
303
+ </div>
304
+ </template>
305
+ <!-- The viewer pane: a slaved projection of its group's regard —
306
+ indicate a file or node anywhere in the group and it renders
307
+ here. -->
308
+ <template id="tpl-pane-view">
309
+ <div class="workspace-pane pane-view">
310
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
311
+ <div class="lcars-bar-horizontal">
312
+ <span class="lcars-title view-title">VIEWER</span>
313
+ </div>
314
+ <div class="lcars-bar-end bar-punctuation"></div>
315
+ </div>
316
+ <div class="pane-drawer" hidden>
317
+ <!-- The drawer grammar (docs/aegis.adoc): shape the tile,
318
+ bind a neighbour. Two groups, two colors, identical on
319
+ every pane at every depth. The third group is gone from
320
+ a browser: what acts on the field moved to the frame
321
+ and what acts on a row moved to the row, since a
322
+ control lives where it acts. -->
323
+ <span class="drawer-group drawer-structure">
324
+ <span class="drawer-label">SPLIT</span>
325
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
326
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
327
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
328
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
329
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
330
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
331
+ </span>
332
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
333
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
334
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
335
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
336
+ </span>
337
+ <span class="drawer-group drawer-children"></span>
338
+ </div>
339
+ <div class="view-body"></div>
340
+ </div>
341
+ </template>
342
+ <!-- The image pane: a series or a volume on a guest engine's
343
+ field, inside mise's frame. The field is foreign; the frame
344
+ is native (docs/aegis.adoc: an-instruments-field-is-foreign). -->
345
+ <template id="tpl-pane-image">
346
+ <div class="workspace-pane pane-image">
347
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
348
+ <div class="lcars-bar-horizontal">
349
+ <span class="lcars-title pane-title">IMAGE</span>
350
+ <span class="pane-mode"></span>
351
+ <span class="pane-state"></span>
352
+ </div>
353
+ <div class="lcars-bar-end bar-punctuation"></div>
354
+ </div>
355
+ <div class="pane-drawer" hidden>
356
+ <span class="drawer-group drawer-structure">
357
+ <span class="drawer-label">SPLIT</span>
358
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
359
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
360
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
361
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
362
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
363
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
364
+ </span>
365
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
366
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
367
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
368
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
369
+ </span>
370
+ <span class="drawer-group drawer-children"></span>
371
+ </div>
372
+ <div class="image-body">
373
+ <span class="field-rule"></span>
374
+ <button class="mode-strip" title="image modes" aria-label="image modes"></button>
375
+ <span class="mode-elbow"></span>
376
+ <aside class="mode-frame">
377
+ <!-- One block per library tool: the behaviour is the
378
+ engine's, the button is mise's. The active one is
379
+ lit; the rest recede. -->
380
+ <button class="strategy-pill image-tool" data-tool="wl" title="window and level on the primary button">W/L</button>
381
+ <button class="strategy-pill image-tool" data-tool="zoom" title="zoom on the primary button">ZOOM</button>
382
+ <button class="strategy-pill image-tool" data-tool="pan" title="pan on the primary button">PAN</button>
383
+ <button class="strategy-pill image-tool" data-tool="length" title="measure a length">LENGTH</button>
384
+ <button class="strategy-pill image-tool" data-tool="angle" title="measure an angle">ANGLE</button>
385
+ <button class="strategy-pill image-tool" data-tool="probe" title="read a voxel">PROBE</button>
386
+ <!-- One control per layout rather than one that
387
+ cycles: a cycling pill names where you are and
388
+ hides where you could go, so the 3D render was
389
+ reachable only by pressing SINGLE twice and the
390
+ pill still read SINGLE while MPR was building. -->
391
+ <button class="strategy-pill image-layout rail-off" data-layout="single" title="one plane, scrolled">SINGLE</button>
392
+ <button class="strategy-pill image-layout rail-off" data-layout="mpr" title="three linked planes, with a shared cursor">MPR</button>
393
+ <button class="strategy-pill image-layout rail-off" data-layout="3d" title="a 3D volume render">3D</button>
394
+ <button class="strategy-pill image-layout rail-off" data-layout="slab" title="a crisp slice sweeping through a ghost volume">SLAB</button>
395
+ <button class="strategy-pill image-colormap" title="colormap">GRAY</button>
396
+ <button class="strategy-pill image-preset" hidden title="the modality's window presets">PRESET</button>
397
+ <!-- A volume layout pulls every slice; over the guard
398
+ it waits here (series-loads-by-consent). -->
399
+ <button class="strategy-pill image-load" hidden title="fetch every slice for the waiting layout">LOAD</button>
400
+ <button class="strategy-pill image-save" title="save the measurements as a DICOM SR under ~/annotations">SAVE</button>
401
+ <button class="strategy-pill image-tags" title="the slice's tags, in a pane that follows this one">TAGS</button>
402
+ <!-- What a clinical viewer writes in the corners: who
403
+ this is, which study, which series, when. Off by
404
+ default, because the same pane is used where a
405
+ screen is shared. -->
406
+ <button class="strategy-pill image-overlay rail-off" title="the patient and study, written on the image">OVERLAY OFF</button>
407
+ <span class="image-focus strategy-pill rail-off" hidden title="the field holds the keyboard; Esc gives it back">FOCUS</span>
408
+ <span class="mode-fill"></span>
409
+ </aside>
410
+ <section class="image-field" aria-label="Image"></section>
411
+ </div>
412
+ </div>
413
+ </template>
414
+ <!-- The tags pane: a DICOM instance's elements as a listing that
415
+ follows the image pane's slice (docs/aegis.adoc:
416
+ tags-follow-the-image). -->
417
+ <template id="tpl-pane-tags">
418
+ <div class="workspace-pane pane-tags">
419
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
420
+ <div class="lcars-bar-horizontal">
421
+ <span class="lcars-title pane-title">TAGS</span>
422
+ <span class="pane-mode"></span>
423
+ <span class="pane-state"></span>
424
+ </div>
425
+ <div class="lcars-bar-end bar-punctuation"></div>
426
+ </div>
427
+ <div class="pane-drawer" hidden>
428
+ <span class="drawer-group drawer-structure">
429
+ <span class="drawer-label">SPLIT</span>
430
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
431
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
432
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
433
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
434
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
435
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
436
+ </span>
437
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
438
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
439
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
440
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
441
+ </span>
442
+ <span class="drawer-group drawer-children"></span>
443
+ </div>
444
+ <div class="tags-body">
445
+ <span class="field-rule"></span>
446
+ <button class="mode-strip" title="tag modes" aria-label="tag modes"></button>
447
+ <span class="mode-elbow"></span>
448
+ <aside class="mode-frame">
449
+ <button class="strategy-pill tags-filter" title="filter the tags (the bar reads FILTERED n/m)">FILTER OFF</button>
450
+ <!-- Identifying values are hidden until asked for: the
451
+ kernel flags them, the surface chooses. -->
452
+ <button class="strategy-pill tags-redact" title="hide or show identifying values">REDACT ON</button>
453
+ <span class="mode-fill"></span>
454
+ </aside>
455
+ <section class="tags-panel" aria-label="Tags"></section>
456
+ </div>
457
+ </div>
458
+ </template>
459
+ <!-- The empty pane: what a split creates. Its prompt is the pane
460
+ specifier — whatever command runs there claims the pane; the
461
+ capsules are shortcuts for the frequent. -->
462
+ <template id="tpl-pane-empty">
463
+ <div class="workspace-pane pane-empty">
464
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
465
+ <div class="lcars-bar-horizontal">
466
+ <span class="lcars-title pane-title">NEW PANE</span>
467
+ </div>
468
+ <div class="lcars-bar-end bar-punctuation"></div>
469
+ </div>
470
+ <div class="pane-drawer" hidden>
471
+ <!-- The drawer grammar (docs/aegis.adoc): shape the tile,
472
+ bind a neighbour. Two groups, two colors, identical on
473
+ every pane at every depth. The third group is gone from
474
+ a browser: what acts on the field moved to the frame
475
+ and what acts on a row moved to the row, since a
476
+ control lives where it acts. -->
477
+ <span class="drawer-group drawer-structure">
478
+ <span class="drawer-label">SPLIT</span>
479
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
480
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
481
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
482
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
483
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
484
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
485
+ </span>
486
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
487
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
488
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
489
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
490
+ </span>
491
+ <span class="drawer-group drawer-children"></span>
492
+ </div>
493
+ <div class="empty-shortcuts">
494
+ <button class="pacs-capsule empty-go-files">FILES</button>
495
+ <button class="pacs-capsule empty-go-dag">RUNS</button>
496
+ <button class="pacs-capsule empty-go-pacs">PACS</button>
497
+ </div>
498
+ <div class="empty-promptline">
499
+ <input class="empty-prompt" spellcheck="false" autocomplete="off"
500
+ placeholder="run a command to claim this pane &mdash; feed diagram feed_12, ls ~/feeds, pacs query ..." />
501
+ </div>
502
+ <div class="empty-result"></div>
503
+ </div>
504
+ </template>
505
+ <template id="tpl-pane-panes">
506
+ <div class="workspace-pane pane-panes">
507
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
508
+ <div class="lcars-bar-horizontal">
509
+ <span class="lcars-title pane-title">PANES</span>
510
+ <span class="pane-mode"></span>
511
+ <span class="pane-state"></span>
512
+ </div>
513
+ <div class="lcars-bar-end bar-punctuation"></div>
514
+ </div>
515
+ <div class="pane-drawer" hidden>
516
+ <span class="drawer-group drawer-structure">
517
+ <span class="drawer-label">SPLIT</span>
518
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
519
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
520
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
521
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
522
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
523
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
524
+ </span>
525
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
526
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
527
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
528
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
529
+ </span>
530
+ <span class="drawer-group drawer-children"></span>
531
+ </div>
532
+ <div class="panes-body">
533
+ <div class="panes-grid" aria-label="Panes you have moved away from"></div>
534
+ <div class="panes-empty" hidden>No panes set aside. Move away from a view and it waits here.</div>
535
+ </div>
536
+ </div>
537
+ </template>
538
+ <div class="workspace-pane" id="pacs-workspace">
539
+ <div class="lcars-terminal-header-bar files-header-bar pane-handle" title="pane controls">
540
+ <div class="lcars-bar-horizontal">
541
+ <span class="lcars-title" id="pacs-title">PACS QUERY / RETRIEVE</span>
542
+ <span class="pane-mode"></span>
543
+ <span class="pane-state"></span>
544
+ </div>
545
+ <div class="lcars-bar-end bar-punctuation" id="pacs-close"></div>
546
+ </div>
547
+ <div class="pane-drawer" hidden>
548
+ <span class="drawer-group drawer-structure">
549
+ <span class="drawer-label">SPLIT</span>
550
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="before" title="new pane opens left">LEFT</button>
551
+ <button class="pacs-capsule drawer-split" data-split="col" data-place="after" title="new pane opens right">RIGHT</button>
552
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="before" title="new pane opens above">ABOVE</button>
553
+ <button class="pacs-capsule drawer-split" data-split="row" data-place="after" title="new pane opens below">BELOW</button>
554
+ <button class="pacs-capsule drawer-zoom" data-pane="" title="zoom (Esc restores)">ZOOM</button>
555
+ <button class="pacs-capsule drawer-close" title="close pane">CLOSE</button>
556
+ </span>
557
+ <span class="drawer-group drawer-binding" role="radiogroup" title="what the next split creates">
558
+ <button class="pacs-capsule drawer-bind drawer-bind-selected" data-bind="unlinked">UNLINKED</button>
559
+ <button class="pacs-capsule drawer-bind" data-bind="fs">LINKED FS</button>
560
+ <button class="pacs-capsule drawer-bind" data-bind="viewer">LINKED VIEWER</button>
561
+ </span>
562
+ <span class="drawer-group drawer-children"></span>
563
+ </div>
564
+ <!-- The form stands on the STUDY grid, in the STUDY caps'
565
+ own order, so a term sits in the column it will fill.
566
+ STUDY has no field: the key reaches the PACS and the PACS
567
+ ignores it (docs/CUBE-gaps.adoc), and a control that does
568
+ nothing is worse than none. -->
569
+ <div id="pacs-form">
570
+ <span class="pacs-form-gutter"></span>
571
+ <label data-key="patient">PATIENT <input id="pacs-f-name" autocomplete="off" /></label>
572
+ <label data-key="mrn">MRN <input id="pacs-f-mrn" autocomplete="off" /></label>
573
+ <span class="pacs-form-blank" data-key="study" title="a PACS does not narrow on study description"></span>
574
+ <!-- PROGRESS is the expanse in the middle of every level, right
575
+ after the description; the form's cell over it carries
576
+ how-this-came-about, since an answer that was not fetched
577
+ now says when it was. The control that re-asks stands in
578
+ the verbs column at the end, where a row's verbs stand. -->
579
+ <span class="pacs-form-blank" data-key="progress">
580
+ <span id="pacs-provenance" class="pacs-provenance" hidden></span>
581
+ </span>
582
+ <label data-key="date">DATE <input id="pacs-f-date" placeholder="YYYYMMDD" autocomplete="off" /></label>
583
+ <label data-key="accession">ACCESSION <input id="pacs-f-accession" autocomplete="off" /></label>
584
+ <label data-key="modality">MODALITY <input id="pacs-f-modality" autocomplete="off" /></label>
585
+ <!-- SERVER is a choice, not a phrase, and LCARS has no
586
+ dropdown: the cell reads its own state and touching it
587
+ unfolds a strip of segments beneath the form — the
588
+ FILTER gesture, in the vocabulary the caps already
589
+ speak. -->
590
+ <span class="pacs-form-field" data-key="server">SERVER
591
+ <button id="pacs-f-server" class="pacs-server-cell" title="choose which PACS to ask (one moves the session, several fan out)">—</button>
592
+ </span>
593
+ <span class="pacs-form-blank" data-key="series"></span>
594
+ <button id="pacs-run" class="pacs-capsule">QUERY</button>
595
+ </div>
596
+ <!-- The strip has the pane's full width, so it carries far
597
+ more servers than capsules crammed into one grid track. -->
598
+ <div id="pacs-server-strip" class="pacs-server-strip" hidden></div>
599
+ <!-- ANON stands beside the line it changes, not beside the
600
+ MRN: a name, an accession and a date identify a person as
601
+ surely as a record number, and a pill against one field
602
+ would say otherwise. It reads its state the way FILTER
603
+ does, because it is the same gesture. -->
604
+ <div id="pacs-commandline">
605
+ <button id="pacs-anon" class="pacs-capsule pacs-capsule-off" title="stand in for what the answer says about a person, for demonstrating against a live PACS">ANON OFF</button>
606
+ <input id="pacs-command" spellcheck="false" autocomplete="off" placeholder="pacs query ..." />
607
+ <button id="pacs-reveal" class="pacs-capsule pacs-capsule-off" title="show what is typed" hidden>REVEAL</button>
608
+ <!-- The whole answer, beside the question that produced it.
609
+ It sat on the results frame, which is the CLOSED spine
610
+ until someone opens it — so the control was 22px of
611
+ clipped label and the operator reported it missing. A
612
+ control nobody can see is a control that is not there. -->
613
+ <button id="pacs-export" class="pacs-capsule" title="write the whole answer as CSV into ChRIS storage">EXPORT CSV</button>
614
+ </div>
615
+ <!-- The results are a framed field like the other listings:
616
+ a rule turning through an elbow into the spine, whose
617
+ mode frame carries FILTER. -->
618
+ <div class="pacs-listing">
619
+ <span class="field-rule"></span>
620
+ <button class="mode-strip" title="display modes" aria-label="display modes"></button>
621
+ <span class="mode-elbow"></span>
622
+ <aside class="mode-frame">
623
+ <button class="strategy-pill pacs-filter rail-off" title="filter the results (the bar reads FILTERED n/m)">FILTER OFF</button>
624
+ <span class="mode-fill"></span>
625
+ </aside>
626
+ <div id="pacs-results"></div>
627
+ </div>
628
+ <div id="pacs-gather">
629
+ <div class="pacs-gather-head">
630
+ <span class="pacs-gather-title">GATHER</span>
631
+ <input id="pacs-gather-name" placeholder="cohort name" autocomplete="off" />
632
+ <button id="pacs-gather-save" class="pacs-capsule" title="write ~/gather/&lt;name&gt; manifest">SAVE</button>
633
+ <!-- The cohort as a table a spreadsheet reads, named for
634
+ what it covers so it is not read as the whole answer.
635
+ It lands in CFS, not on the machine the browser
636
+ happens to be running on: the engine is elsewhere,
637
+ and a redirect would write somebody else's disk. -->
638
+ <button id="pacs-gather-export" class="pacs-capsule" title="write the gathered series as CSV into ChRIS storage">EXPORT GATHER CSV</button>
639
+ <!-- Where the table went, said by the pane that made it:
640
+ a readout, not a capsule, since it answers no press. -->
641
+ <span id="pacs-wrote" class="pacs-wrote" hidden></span>
642
+ <button id="pacs-gather-feed" class="pacs-capsule" title="create a feed rooted on the cohort">CREATE FEED</button>
643
+ </div>
644
+ <div id="pacs-gather-rows"></div>
645
+ </div>
646
+ </div>
647
+ </main>
648
+ </div>
649
+ </div>
650
+ </div>
651
+ <div class="headtrim"></div>
652
+ <div class="baseboard"></div>
653
+ <!-- The header's lid strip: appears when the header glides away; click
654
+ (or Esc) restores it. Same idiom as the console drawer's lid. -->
655
+ <div id="header-restore" title="restore header" role="button" tabindex="0"></div>
656
+ <!-- The argus command line: prefix-: in the tmux tradition. One line,
657
+ floating over the workspace; sentences run client-side, anything
658
+ else falls through to the session. -->
659
+ <div id="lang-palette" hidden>
660
+ <span class="lang-glyph">LANG&nbsp;:</span>
661
+ <input id="lang-input" type="text" autocomplete="off" spellcheck="false"
662
+ placeholder="pane split right &middot; view runs &middot; desktop save &hellip; (Tab completes, Esc closes)" />
663
+ <div id="lang-result"></div>
664
+ </div>
665
+
666
+ </body>
667
+ </html>