@tokamak-private-dapps/private-state-cli 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +109 -38
- package/cli-assistant.html +11 -5
- package/commands/account.mjs +39 -0
- package/commands/channel.mjs +58 -0
- package/commands/index.mjs +62 -0
- package/commands/investigator.mjs +11 -0
- package/commands/notes.mjs +34 -0
- package/commands/system.mjs +49 -0
- package/commands/wallet.mjs +80 -0
- package/investigator/README.md +16 -6
- package/investigator/app.js +612 -17
- package/investigator/index.html +153 -90
- package/investigator/styles.css +277 -28
- package/lib/private-state-cli-command-registry.mjs +102 -30
- package/lib/private-state-runtime-management.mjs +294 -25
- package/lib/runtime.mjs +11572 -0
- package/package.json +2 -1
- package/private-state-bridge-cli.mjs +2 -11269
package/investigator/index.html
CHANGED
|
@@ -27,90 +27,136 @@
|
|
|
27
27
|
spending keys, wallet secrets, or account private keys.
|
|
28
28
|
</section>
|
|
29
29
|
|
|
30
|
-
<section class="grid">
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<input name="creationTx" autocomplete="off" placeholder="0x...">
|
|
44
|
-
</label>
|
|
45
|
-
<label>
|
|
46
|
-
Spend tx
|
|
47
|
-
<input name="spendTx" autocomplete="off" placeholder="0x...">
|
|
48
|
-
</label>
|
|
49
|
-
<div class="two-col">
|
|
50
|
-
<label>
|
|
51
|
-
Created from block
|
|
52
|
-
<input name="createdFrom" inputmode="numeric" autocomplete="off">
|
|
30
|
+
<section id="summaryCards" class="summary-grid" aria-live="polite"></section>
|
|
31
|
+
|
|
32
|
+
<section class="workspace">
|
|
33
|
+
<form id="filters" class="panel scope-panel">
|
|
34
|
+
<div class="panel-head">
|
|
35
|
+
<h2>Disclosure Request</h2>
|
|
36
|
+
<button id="applyFilters" type="button">Apply</button>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div class="purpose-grid" role="radiogroup" aria-label="Disclosure request type">
|
|
40
|
+
<label class="purpose-card">
|
|
41
|
+
<input name="purpose" type="radio" value="overview" checked>
|
|
42
|
+
<span>Full graph view</span>
|
|
53
43
|
</label>
|
|
54
|
-
<label>
|
|
55
|
-
|
|
56
|
-
<
|
|
44
|
+
<label class="purpose-card">
|
|
45
|
+
<input name="purpose" type="radio" value="receipt">
|
|
46
|
+
<span>Specific note receipt</span>
|
|
47
|
+
</label>
|
|
48
|
+
<label class="purpose-card">
|
|
49
|
+
<input name="purpose" type="radio" value="spend">
|
|
50
|
+
<span>Specific note use</span>
|
|
51
|
+
</label>
|
|
52
|
+
<label class="purpose-card">
|
|
53
|
+
<input name="purpose" type="radio" value="transaction">
|
|
54
|
+
<span>Transaction linkage</span>
|
|
55
|
+
</label>
|
|
56
|
+
<label class="purpose-card">
|
|
57
|
+
<input name="purpose" type="radio" value="range">
|
|
58
|
+
<span>Period receipts</span>
|
|
59
|
+
</label>
|
|
60
|
+
<label class="purpose-card">
|
|
61
|
+
<input name="purpose" type="radio" value="counterparty">
|
|
62
|
+
<span>Counterparty subset</span>
|
|
63
|
+
</label>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div class="form-section">
|
|
67
|
+
<h3>Request Inputs</h3>
|
|
68
|
+
<label data-purpose-field="receipt spend">
|
|
69
|
+
Commitment contains
|
|
70
|
+
<input name="commitment" autocomplete="off" placeholder="0x...">
|
|
71
|
+
</label>
|
|
72
|
+
<label data-purpose-field="spend">
|
|
73
|
+
Nullifier contains
|
|
74
|
+
<input name="nullifier" autocomplete="off" placeholder="0x...">
|
|
75
|
+
</label>
|
|
76
|
+
<label data-purpose-field="receipt transaction">
|
|
77
|
+
Creation tx
|
|
78
|
+
<input name="creationTx" autocomplete="off" placeholder="0x...">
|
|
79
|
+
</label>
|
|
80
|
+
<label data-purpose-field="spend transaction">
|
|
81
|
+
Spend tx
|
|
82
|
+
<input name="spendTx" autocomplete="off" placeholder="0x...">
|
|
83
|
+
</label>
|
|
84
|
+
<div class="two-col" data-purpose-field="range">
|
|
85
|
+
<label>
|
|
86
|
+
Created from block
|
|
87
|
+
<input name="createdFrom" inputmode="numeric" autocomplete="off">
|
|
88
|
+
</label>
|
|
89
|
+
<label>
|
|
90
|
+
Created to block
|
|
91
|
+
<input name="createdTo" inputmode="numeric" autocomplete="off">
|
|
92
|
+
</label>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="two-col" data-purpose-field="range spend">
|
|
95
|
+
<label>
|
|
96
|
+
Spent from block
|
|
97
|
+
<input name="spentFrom" inputmode="numeric" autocomplete="off">
|
|
98
|
+
</label>
|
|
99
|
+
<label>
|
|
100
|
+
Spent to block
|
|
101
|
+
<input name="spentTo" inputmode="numeric" autocomplete="off">
|
|
102
|
+
</label>
|
|
103
|
+
</div>
|
|
104
|
+
<label data-purpose-field="counterparty">
|
|
105
|
+
Counterparty L2 address
|
|
106
|
+
<input name="counterparty" autocomplete="off" placeholder="0x...">
|
|
57
107
|
</label>
|
|
58
108
|
</div>
|
|
109
|
+
|
|
110
|
+
<details class="advanced-filters">
|
|
111
|
+
<summary>Advanced filters</summary>
|
|
112
|
+
<div class="two-col">
|
|
113
|
+
<label>
|
|
114
|
+
Status
|
|
115
|
+
<select name="status">
|
|
116
|
+
<option value="">Any</option>
|
|
117
|
+
<option value="unused">Unused</option>
|
|
118
|
+
<option value="spent">Spent</option>
|
|
119
|
+
</select>
|
|
120
|
+
</label>
|
|
121
|
+
<label>
|
|
122
|
+
Direction
|
|
123
|
+
<select name="direction">
|
|
124
|
+
<option value="">Any</option>
|
|
125
|
+
<option value="self-mint">Self mint</option>
|
|
126
|
+
<option value="sent">Sent</option>
|
|
127
|
+
<option value="received">Received</option>
|
|
128
|
+
<option value="unknown">Unknown</option>
|
|
129
|
+
</select>
|
|
130
|
+
</label>
|
|
131
|
+
</div>
|
|
132
|
+
</details>
|
|
133
|
+
</form>
|
|
134
|
+
|
|
135
|
+
<form id="packageForm" class="panel package-panel">
|
|
136
|
+
<div class="panel-head">
|
|
137
|
+
<h2>Export Package</h2>
|
|
138
|
+
<button id="buildPackage" type="button" disabled>Build disclosure ZIP</button>
|
|
139
|
+
</div>
|
|
59
140
|
<div class="two-col">
|
|
60
141
|
<label>
|
|
61
|
-
|
|
62
|
-
<input name="
|
|
142
|
+
Case ID
|
|
143
|
+
<input name="caseId" autocomplete="off" placeholder="exchange-case-001">
|
|
63
144
|
</label>
|
|
64
145
|
<label>
|
|
65
|
-
|
|
66
|
-
<input name="
|
|
146
|
+
Requesting party
|
|
147
|
+
<input name="requestingParty" autocomplete="off" placeholder="Exchange or investigator name">
|
|
67
148
|
</label>
|
|
68
149
|
</div>
|
|
69
150
|
<div class="two-col">
|
|
70
151
|
<label>
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
<option value="">Any</option>
|
|
74
|
-
<option value="unused">Unused</option>
|
|
75
|
-
<option value="spent">Spent</option>
|
|
76
|
-
</select>
|
|
152
|
+
Bridge deposit tx
|
|
153
|
+
<input name="bridgeDepositTx" autocomplete="off" placeholder="0x...">
|
|
77
154
|
</label>
|
|
78
155
|
<label>
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
<option value="">Any</option>
|
|
82
|
-
<option value="self-mint">Self mint</option>
|
|
83
|
-
<option value="sent">Sent</option>
|
|
84
|
-
<option value="received">Received</option>
|
|
85
|
-
<option value="unknown">Unknown</option>
|
|
86
|
-
</select>
|
|
156
|
+
Withdraw or claim tx
|
|
157
|
+
<input name="withdrawTx" autocomplete="off" placeholder="0x...">
|
|
87
158
|
</label>
|
|
88
159
|
</div>
|
|
89
|
-
<label>
|
|
90
|
-
Counterparty L2 address
|
|
91
|
-
<input name="counterparty" autocomplete="off" placeholder="0x...">
|
|
92
|
-
</label>
|
|
93
|
-
<button id="applyFilters" type="button">Apply filters</button>
|
|
94
|
-
</form>
|
|
95
|
-
|
|
96
|
-
<form id="packageForm" class="panel">
|
|
97
|
-
<h2>Package Metadata</h2>
|
|
98
|
-
<label>
|
|
99
|
-
Case ID
|
|
100
|
-
<input name="caseId" autocomplete="off" placeholder="exchange-case-001">
|
|
101
|
-
</label>
|
|
102
|
-
<label>
|
|
103
|
-
Requesting party
|
|
104
|
-
<input name="requestingParty" autocomplete="off" placeholder="Exchange or investigator name">
|
|
105
|
-
</label>
|
|
106
|
-
<label>
|
|
107
|
-
Bridge deposit tx
|
|
108
|
-
<input name="bridgeDepositTx" autocomplete="off" placeholder="0x...">
|
|
109
|
-
</label>
|
|
110
|
-
<label>
|
|
111
|
-
Withdraw or claim tx
|
|
112
|
-
<input name="withdrawTx" autocomplete="off" placeholder="0x...">
|
|
113
|
-
</label>
|
|
114
160
|
<fieldset>
|
|
115
161
|
<legend>Disclosure intents</legend>
|
|
116
162
|
<label><input name="intent" type="checkbox" value="note-receipt" checked> Note receipt</label>
|
|
@@ -122,37 +168,54 @@
|
|
|
122
168
|
</fieldset>
|
|
123
169
|
<label>
|
|
124
170
|
User statement
|
|
125
|
-
<textarea name="statement" rows="
|
|
171
|
+
<textarea name="statement" rows="4" placeholder="Optional explanation included in the disclosure package."></textarea>
|
|
126
172
|
</label>
|
|
127
|
-
<button id="buildPackage" type="button" disabled>Build disclosure ZIP</button>
|
|
128
173
|
</form>
|
|
129
174
|
</section>
|
|
130
175
|
|
|
131
176
|
<section class="panel">
|
|
132
|
-
<div class="
|
|
133
|
-
<
|
|
177
|
+
<div class="result-header">
|
|
178
|
+
<div>
|
|
179
|
+
<h2>Results</h2>
|
|
180
|
+
<div id="status" class="status">Load a raw evidence ZIP to begin.</div>
|
|
181
|
+
</div>
|
|
134
182
|
<div class="actions">
|
|
183
|
+
<button id="exportAscii" type="button" disabled>Export ASCII-art</button>
|
|
135
184
|
<button id="selectAll" type="button" disabled>Select all</button>
|
|
136
185
|
<button id="selectNone" type="button" disabled>Select none</button>
|
|
137
186
|
</div>
|
|
138
187
|
</div>
|
|
139
|
-
|
|
140
|
-
<div class="
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
<
|
|
155
|
-
|
|
188
|
+
|
|
189
|
+
<div class="tabs" role="tablist" aria-label="Result views">
|
|
190
|
+
<button id="graphTab" class="tab is-active" type="button" data-result-tab="graph">Graph</button>
|
|
191
|
+
<button id="notesTab" class="tab" type="button" data-result-tab="notes">Notes</button>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div id="graphPanel" class="result-panel is-active">
|
|
195
|
+
<div id="graphViewport" class="graph-viewport">
|
|
196
|
+
<svg id="graphSvg" class="graph-svg" role="img" aria-label="Note linkage graph"></svg>
|
|
197
|
+
<div id="nodeDetail" class="node-detail is-hidden"></div>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<div id="notesPanel" class="result-panel">
|
|
202
|
+
<div class="table-wrap">
|
|
203
|
+
<table>
|
|
204
|
+
<thead>
|
|
205
|
+
<tr>
|
|
206
|
+
<th>Use</th>
|
|
207
|
+
<th>Commitment</th>
|
|
208
|
+
<th>Value</th>
|
|
209
|
+
<th>Status</th>
|
|
210
|
+
<th>Created</th>
|
|
211
|
+
<th>Spent</th>
|
|
212
|
+
<th>Direction</th>
|
|
213
|
+
<th>Counterparty</th>
|
|
214
|
+
</tr>
|
|
215
|
+
</thead>
|
|
216
|
+
<tbody id="noteRows"></tbody>
|
|
217
|
+
</table>
|
|
218
|
+
</div>
|
|
156
219
|
</div>
|
|
157
220
|
</section>
|
|
158
221
|
</main>
|
package/investigator/styles.css
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
color-scheme: light;
|
|
3
|
-
--bg: #
|
|
3
|
+
--bg: #f4f6f8;
|
|
4
4
|
--panel: #ffffff;
|
|
5
|
-
--text: #
|
|
6
|
-
--muted: #
|
|
7
|
-
--line: #
|
|
8
|
-
--
|
|
9
|
-
--accent
|
|
10
|
-
--
|
|
11
|
-
--
|
|
5
|
+
--text: #17202a;
|
|
6
|
+
--muted: #647184;
|
|
7
|
+
--line: #d5dce6;
|
|
8
|
+
--soft-line: #e7ebf0;
|
|
9
|
+
--accent: #0b6f8f;
|
|
10
|
+
--accent-dark: #084f66;
|
|
11
|
+
--accent-soft: #e5f4f8;
|
|
12
|
+
--green: #2f855a;
|
|
13
|
+
--orange: #b26a00;
|
|
14
|
+
--warn-bg: #fff7dd;
|
|
15
|
+
--warn-line: #dfbd52;
|
|
16
|
+
--shadow: 0 12px 28px rgba(23, 32, 42, 0.12);
|
|
12
17
|
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
13
18
|
}
|
|
14
19
|
|
|
@@ -23,21 +28,33 @@ body {
|
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
.app {
|
|
26
|
-
max-width:
|
|
31
|
+
max-width: 1360px;
|
|
27
32
|
margin: 0 auto;
|
|
28
33
|
padding: 24px;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
.toolbar
|
|
36
|
+
.toolbar,
|
|
37
|
+
.result-header,
|
|
38
|
+
.panel-head,
|
|
39
|
+
.actions {
|
|
32
40
|
display: flex;
|
|
33
41
|
align-items: center;
|
|
42
|
+
gap: 14px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.toolbar,
|
|
46
|
+
.result-header,
|
|
47
|
+
.panel-head {
|
|
34
48
|
justify-content: space-between;
|
|
35
|
-
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.toolbar {
|
|
36
52
|
margin-bottom: 16px;
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
h1,
|
|
40
|
-
h2
|
|
56
|
+
h2,
|
|
57
|
+
h3 {
|
|
41
58
|
margin: 0;
|
|
42
59
|
letter-spacing: 0;
|
|
43
60
|
}
|
|
@@ -52,6 +69,14 @@ h2 {
|
|
|
52
69
|
line-height: 1.3;
|
|
53
70
|
}
|
|
54
71
|
|
|
72
|
+
h3 {
|
|
73
|
+
color: var(--muted);
|
|
74
|
+
font-size: 13px;
|
|
75
|
+
font-weight: 700;
|
|
76
|
+
line-height: 1.3;
|
|
77
|
+
text-transform: uppercase;
|
|
78
|
+
}
|
|
79
|
+
|
|
55
80
|
p {
|
|
56
81
|
margin: 8px 0 0;
|
|
57
82
|
color: var(--muted);
|
|
@@ -65,7 +90,7 @@ button {
|
|
|
65
90
|
border-radius: 6px;
|
|
66
91
|
padding: 10px 14px;
|
|
67
92
|
font-size: 14px;
|
|
68
|
-
font-weight:
|
|
93
|
+
font-weight: 700;
|
|
69
94
|
cursor: pointer;
|
|
70
95
|
white-space: nowrap;
|
|
71
96
|
}
|
|
@@ -85,18 +110,51 @@ button:hover:not(:disabled),
|
|
|
85
110
|
background: var(--accent-dark);
|
|
86
111
|
}
|
|
87
112
|
|
|
113
|
+
button.secondary {
|
|
114
|
+
border-color: var(--line);
|
|
115
|
+
background: #fff;
|
|
116
|
+
color: var(--text);
|
|
117
|
+
}
|
|
118
|
+
|
|
88
119
|
.warning {
|
|
89
120
|
border: 1px solid var(--warn-line);
|
|
90
121
|
background: var(--warn-bg);
|
|
91
122
|
border-radius: 8px;
|
|
92
123
|
padding: 14px 16px;
|
|
93
|
-
margin-bottom:
|
|
124
|
+
margin-bottom: 16px;
|
|
94
125
|
line-height: 1.5;
|
|
95
126
|
}
|
|
96
127
|
|
|
97
|
-
.grid {
|
|
128
|
+
.summary-grid {
|
|
129
|
+
display: grid;
|
|
130
|
+
grid-template-columns: repeat(5, minmax(0, 1fr));
|
|
131
|
+
gap: 10px;
|
|
132
|
+
margin-bottom: 16px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.summary-card {
|
|
136
|
+
border: 1px solid var(--line);
|
|
137
|
+
background: var(--panel);
|
|
138
|
+
border-radius: 8px;
|
|
139
|
+
padding: 12px;
|
|
140
|
+
min-width: 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.summary-card span {
|
|
144
|
+
display: block;
|
|
145
|
+
color: var(--muted);
|
|
146
|
+
font-size: 12px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.summary-card strong {
|
|
150
|
+
display: block;
|
|
151
|
+
margin-top: 4px;
|
|
152
|
+
overflow-wrap: anywhere;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.workspace {
|
|
98
156
|
display: grid;
|
|
99
|
-
grid-template-columns: minmax(
|
|
157
|
+
grid-template-columns: minmax(320px, 0.8fr) minmax(420px, 1.2fr);
|
|
100
158
|
gap: 16px;
|
|
101
159
|
margin-bottom: 16px;
|
|
102
160
|
}
|
|
@@ -108,7 +166,9 @@ button:hover:not(:disabled),
|
|
|
108
166
|
padding: 16px;
|
|
109
167
|
}
|
|
110
168
|
|
|
111
|
-
form
|
|
169
|
+
form,
|
|
170
|
+
.form-section,
|
|
171
|
+
.package-panel {
|
|
112
172
|
display: grid;
|
|
113
173
|
gap: 12px;
|
|
114
174
|
}
|
|
@@ -170,30 +230,210 @@ legend {
|
|
|
170
230
|
gap: 10px;
|
|
171
231
|
}
|
|
172
232
|
|
|
173
|
-
.
|
|
233
|
+
.purpose-grid {
|
|
234
|
+
display: grid;
|
|
235
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
236
|
+
gap: 8px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.purpose-card {
|
|
174
240
|
display: flex;
|
|
175
|
-
justify-content: space-between;
|
|
176
241
|
align-items: center;
|
|
177
|
-
gap:
|
|
242
|
+
gap: 8px;
|
|
243
|
+
min-height: 42px;
|
|
244
|
+
border: 1px solid var(--line);
|
|
245
|
+
border-radius: 8px;
|
|
246
|
+
padding: 9px 10px;
|
|
247
|
+
color: var(--text);
|
|
248
|
+
cursor: pointer;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.purpose-card:has(input:checked) {
|
|
252
|
+
border-color: var(--accent);
|
|
253
|
+
background: var(--accent-soft);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.purpose-card input {
|
|
257
|
+
width: auto;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.advanced-filters {
|
|
261
|
+
border-top: 1px solid var(--soft-line);
|
|
262
|
+
padding-top: 10px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.advanced-filters summary {
|
|
266
|
+
color: var(--muted);
|
|
267
|
+
cursor: pointer;
|
|
268
|
+
font-weight: 700;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.advanced-filters[open] summary {
|
|
178
272
|
margin-bottom: 10px;
|
|
179
273
|
}
|
|
180
274
|
|
|
181
|
-
.
|
|
275
|
+
.status {
|
|
276
|
+
min-height: 22px;
|
|
277
|
+
margin-top: 4px;
|
|
278
|
+
color: var(--muted);
|
|
279
|
+
font-size: 14px;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.tabs {
|
|
182
283
|
display: flex;
|
|
183
284
|
gap: 8px;
|
|
285
|
+
border-bottom: 1px solid var(--line);
|
|
286
|
+
margin-top: 12px;
|
|
184
287
|
}
|
|
185
288
|
|
|
186
|
-
.
|
|
187
|
-
|
|
188
|
-
|
|
289
|
+
.tab {
|
|
290
|
+
border: 0;
|
|
291
|
+
border-bottom: 3px solid transparent;
|
|
292
|
+
background: transparent;
|
|
189
293
|
color: var(--muted);
|
|
294
|
+
border-radius: 0;
|
|
295
|
+
padding: 10px 4px 9px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.tab:hover,
|
|
299
|
+
.tab.is-active {
|
|
300
|
+
background: transparent;
|
|
301
|
+
color: var(--text);
|
|
302
|
+
border-bottom-color: var(--accent);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.result-panel {
|
|
306
|
+
display: none;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.result-panel.is-active {
|
|
310
|
+
display: block;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.graph-viewport {
|
|
314
|
+
position: relative;
|
|
315
|
+
min-height: 520px;
|
|
316
|
+
margin-top: 14px;
|
|
317
|
+
border: 1px solid var(--line);
|
|
318
|
+
border-radius: 8px;
|
|
319
|
+
overflow: auto;
|
|
320
|
+
background:
|
|
321
|
+
linear-gradient(#eef2f6 1px, transparent 1px),
|
|
322
|
+
linear-gradient(90deg, #eef2f6 1px, transparent 1px),
|
|
323
|
+
#fbfcfe;
|
|
324
|
+
background-size: 28px 28px;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.graph-svg {
|
|
328
|
+
display: block;
|
|
329
|
+
min-width: 100%;
|
|
330
|
+
min-height: 520px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.graph-edge {
|
|
334
|
+
fill: none;
|
|
335
|
+
stroke: #7c8794;
|
|
336
|
+
stroke-width: 1.8;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.graph-edge.local {
|
|
340
|
+
stroke: var(--accent);
|
|
341
|
+
stroke-width: 2.2;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.graph-edge.external-in {
|
|
345
|
+
stroke: var(--green);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.graph-edge.external-out {
|
|
349
|
+
stroke: var(--orange);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.edge-arrow {
|
|
353
|
+
fill: currentColor;
|
|
354
|
+
color: #7c8794;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.edge-label,
|
|
358
|
+
.graph-empty {
|
|
359
|
+
fill: var(--muted);
|
|
360
|
+
font-size: 12px;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.graph-node {
|
|
364
|
+
cursor: pointer;
|
|
365
|
+
outline: none;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.graph-node rect {
|
|
369
|
+
fill: #fff;
|
|
370
|
+
stroke: var(--line);
|
|
371
|
+
stroke-width: 1.5;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.graph-node:hover rect,
|
|
375
|
+
.graph-node:focus rect {
|
|
376
|
+
stroke: var(--accent);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.graph-node.is-selected rect {
|
|
380
|
+
fill: var(--accent-soft);
|
|
381
|
+
stroke: var(--accent);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.node-label {
|
|
385
|
+
fill: var(--text);
|
|
190
386
|
font-size: 14px;
|
|
387
|
+
font-weight: 800;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.node-value {
|
|
391
|
+
fill: var(--muted);
|
|
392
|
+
font-size: 12px;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.node-detail {
|
|
396
|
+
position: absolute;
|
|
397
|
+
z-index: 3;
|
|
398
|
+
width: min(360px, calc(100% - 32px));
|
|
399
|
+
border: 1px solid var(--line);
|
|
400
|
+
border-radius: 8px;
|
|
401
|
+
background: #fff;
|
|
402
|
+
box-shadow: var(--shadow);
|
|
403
|
+
padding: 12px;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.node-detail.is-hidden {
|
|
407
|
+
display: none;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.detail-title {
|
|
411
|
+
margin-bottom: 8px;
|
|
412
|
+
font-weight: 800;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.detail-rows {
|
|
416
|
+
display: grid;
|
|
417
|
+
grid-template-columns: 86px minmax(0, 1fr);
|
|
418
|
+
gap: 6px 10px;
|
|
419
|
+
margin: 0 0 12px;
|
|
420
|
+
font-size: 12px;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.detail-rows dt {
|
|
424
|
+
color: var(--muted);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.detail-rows dd {
|
|
428
|
+
margin: 0;
|
|
429
|
+
overflow-wrap: anywhere;
|
|
191
430
|
}
|
|
192
431
|
|
|
193
432
|
.table-wrap {
|
|
194
433
|
overflow: auto;
|
|
195
434
|
border: 1px solid var(--line);
|
|
196
435
|
border-radius: 8px;
|
|
436
|
+
margin-top: 14px;
|
|
197
437
|
}
|
|
198
438
|
|
|
199
439
|
table {
|
|
@@ -231,19 +471,28 @@ tr:last-child td {
|
|
|
231
471
|
color: var(--muted);
|
|
232
472
|
}
|
|
233
473
|
|
|
234
|
-
@media (max-width:
|
|
474
|
+
@media (max-width: 980px) {
|
|
235
475
|
.app {
|
|
236
476
|
padding: 16px;
|
|
237
477
|
}
|
|
238
478
|
|
|
239
479
|
.toolbar,
|
|
240
|
-
.
|
|
241
|
-
|
|
480
|
+
.result-header,
|
|
481
|
+
.panel-head,
|
|
482
|
+
.workspace {
|
|
242
483
|
display: grid;
|
|
484
|
+
grid-template-columns: 1fr;
|
|
243
485
|
}
|
|
244
486
|
|
|
487
|
+
.summary-grid,
|
|
488
|
+
.workspace,
|
|
245
489
|
fieldset,
|
|
246
|
-
.two-col
|
|
490
|
+
.two-col,
|
|
491
|
+
.purpose-grid {
|
|
247
492
|
grid-template-columns: 1fr;
|
|
248
493
|
}
|
|
494
|
+
|
|
495
|
+
.actions {
|
|
496
|
+
flex-wrap: wrap;
|
|
497
|
+
}
|
|
249
498
|
}
|