@bongos/core 1.21.6 → 1.21.8

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.
@@ -0,0 +1,364 @@
1
+ // modules/hall-ui/public/street.js — THE STREET, wired (task 1004525, goal
2
+ // 1000125, R03).
3
+ //
4
+ // street-draw.js computes the street as data; this file reads the feeds, hands
5
+ // them to GovStreet.streetModel(), and turns its lists into DOM: SVG paths for
6
+ // the road and the buildings, a span per crate, a name and state line per
7
+ // building, a bracket per group, an <a> door per building and district, a
8
+ // <button> per pin, and an <a> per reading. It owns the light/dark switch, the
9
+ // artboard's fit to the stage, the address (#building= / #district=), and the
10
+ // short matter card a pin opens. No innerHTML anywhere: every node is created,
11
+ // and every docket string lands as text or an attribute.
12
+ //
13
+ // THE FEEDS (all GETs, all gated server-side):
14
+ // /api/bongos/government/docket buildings, pins, lines, readings (task 1004523)
15
+ // /api/bongos/goals the open goals: one district each
16
+ // /api/bongos/goals/rollups each goal's task counts: its buildings
17
+ // /api/bongos/builders/<viewer>/earnings your share this month (after the docket names the viewer)
18
+ // A feed that fails leaves its part out (no pins, no districts, "—" for the
19
+ // share) and the page says the docket could not be read; it never draws sample data.
20
+ //
21
+ // THE SWITCH. The hall's own preference ('hall-theme', else the OS) and the
22
+ // hall's own attribute (html[data-theme]), shared with the city and every
23
+ // hall page. The drawing's faces are drawing data in the mode, so a toggle
24
+ // redraws the street from the last feeds (no refetch).
25
+ //
26
+ // MOTION is CSS only (street.css); nothing here animates. The scale write on
27
+ // resize is layout, not motion.
28
+
29
+ (function () {
30
+ 'use strict';
31
+ var S = window.GovStreet;
32
+ var SVG_NS = 'http://www.w3.org/2000/svg';
33
+ var THEME_KEY = 'hall-theme';
34
+ var SUN = 'M7 1.5V3M7 11v1.5M1.5 7H3M11 7h1.5M3.1 3.1l1 1M9.9 9.9l1 1M3.1 10.9l1-1M9.9 4.1l1-1M9.5 7A2.5 2.5 0 1 1 4.5 7A2.5 2.5 0 1 1 9.5 7Z';
35
+ var MOON = 'M11.5 8.6A5 5 0 0 1 5.4 2.5A5 5 0 1 0 11.5 8.6Z';
36
+ var FEEDS = {
37
+ docket: '/api/bongos/government/docket',
38
+ goals: '/api/bongos/goals',
39
+ rollups: '/api/bongos/goals/rollups',
40
+ earnings: function (id) { return '/api/bongos/builders/' + encodeURIComponent(id) + '/earnings'; },
41
+ };
42
+ // The artboard's street band: the prototype's 900-high board less its 64 px
43
+ // header and 128 px footer, which this page lays out as real rows.
44
+ var BAND_TOP = 64, BAND_H = 708;
45
+ var CARD_W = 390;
46
+
47
+ var $ = function (id) { return document.getElementById(id); };
48
+ var media = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
49
+ var data = { docket: null, goals: [], rollups: [], earnings: null, loaded: false };
50
+ var view = { open: null, opener: null, model: null, scale: 1, mode: null };
51
+
52
+ // ---------- light / dark ----------
53
+ var chosen = null;
54
+ function storedTheme() {
55
+ try { var v = window.localStorage.getItem(THEME_KEY); if (v === 'dark' || v === 'light') return v; } catch (_) { /* blocked */ }
56
+ return chosen;
57
+ }
58
+ function effectiveTheme() { return storedTheme() || (media && media.matches ? 'dark' : 'light'); }
59
+ function paintSwitch(t) {
60
+ var btn = $('streetMode');
61
+ var label = t === 'dark' ? 'Switch to light mode' : 'Switch to dark mode';
62
+ if (btn) { btn.setAttribute('aria-label', label); btn.setAttribute('title', label); }
63
+ var icon = $('streetModeIcon');
64
+ if (icon) icon.setAttribute('d', t === 'dark' ? SUN : MOON);
65
+ var word = $('streetModeWord');
66
+ if (word) word.textContent = t === 'dark' ? 'light' : 'dark';
67
+ }
68
+ function applyTheme() {
69
+ var t = effectiveTheme();
70
+ document.documentElement.setAttribute('data-theme', t);
71
+ paintSwitch(t);
72
+ return t;
73
+ }
74
+ function toggleTheme() {
75
+ var next = effectiveTheme() === 'dark' ? 'light' : 'dark';
76
+ chosen = next;
77
+ try { window.localStorage.setItem(THEME_KEY, next); } catch (_) { /* private mode: this page only */ }
78
+ applyTheme();
79
+ draw();
80
+ }
81
+ function currentMode() {
82
+ var t = document.documentElement.getAttribute('data-theme');
83
+ return t === 'light' || t === 'dark' ? t : effectiveTheme();
84
+ }
85
+
86
+ // ---------- the address ----------
87
+ function here() { return S.parseHash(window.location && window.location.hash); }
88
+
89
+ // ---------- fit the artboard's street band to the stage ----------
90
+ // 1440 x 708 at scale 1 is the prototype exactly. A wider or taller stage
91
+ // grows it, a smaller one shrinks it; a phone keeps it near full size and the
92
+ // street scrolls sideways inside its window, so a pin stays a pin.
93
+ function fit() {
94
+ var win = $('streetWindow'), sizer = $('streetSizer'), board = $('streetBoard');
95
+ if (!win || !sizer || !board) return;
96
+ var W = view.model ? view.model.width : S.ARTBOARD_W;
97
+ var cw = win.clientWidth || window.innerWidth || 1440, ch = win.clientHeight || 708;
98
+ var s = Math.min(cw / W, ch / BAND_H);
99
+ if (cw / W < 0.6) s = Math.min(1, ch / BAND_H);
100
+ s = Math.max(0.4, Math.round(s * 1000) / 1000);
101
+ view.scale = s;
102
+ sizer.style.width = Math.round(W * s) + 'px';
103
+ sizer.style.height = Math.round(BAND_H * s) + 'px';
104
+ board.style.width = W + 'px';
105
+ board.style.setProperty('--street-scale', String(s));
106
+ var svg = $('streetSvg');
107
+ if (svg) { svg.setAttribute('width', String(W)); svg.setAttribute('viewBox', '0 0 ' + W + ' 900'); }
108
+ placeCard();
109
+ }
110
+
111
+ // ---------- the feeds ----------
112
+ function getJson(url) {
113
+ return fetch(url, { credentials: 'same-origin', headers: { accept: 'application/json' } })
114
+ .then(function (r) { return r && r.ok ? r.json() : null; })
115
+ .catch(function () { return null; });
116
+ }
117
+ function load() {
118
+ return Promise.all([getJson(FEEDS.docket), getJson(FEEDS.goals), getJson(FEEDS.rollups)]).then(function (res) {
119
+ data.docket = res[0] && Array.isArray(res[0].matters) ? res[0] : null;
120
+ data.goals = res[1] && Array.isArray(res[1].goals) ? res[1].goals : [];
121
+ data.rollups = res[2] && Array.isArray(res[2].rollups) ? res[2].rollups : [];
122
+ data.loaded = true;
123
+ draw();
124
+ var viewer = data.docket && data.docket.viewer && data.docket.viewer.id;
125
+ if (viewer == null) return null;
126
+ return getJson(FEEDS.earnings(viewer)).then(function (e) {
127
+ data.earnings = e && Array.isArray(e.days) ? e : null;
128
+ draw();
129
+ });
130
+ });
131
+ }
132
+
133
+ // ---------- drawing ----------
134
+ function clear(el) { while (el && el.firstChild) el.removeChild(el.firstChild); }
135
+ function pathEl(p) {
136
+ var el = document.createElementNS(SVG_NS, 'path');
137
+ el.setAttribute('d', p.d);
138
+ el.setAttribute('fill', p.f);
139
+ el.setAttribute('stroke', p.s);
140
+ if (p.dash && p.dash !== 'none') el.setAttribute('stroke-dasharray', p.dash);
141
+ el.setAttribute('stroke-width', String(p.w || 1));
142
+ return el;
143
+ }
144
+ function node(tag, cls, text) {
145
+ var el = document.createElement(tag);
146
+ if (cls) el.className = cls;
147
+ if (text != null) el.textContent = String(text);
148
+ return el;
149
+ }
150
+ function at(el, x, y, w, h) {
151
+ el.style.left = x + 'px';
152
+ el.style.top = y + 'px';
153
+ if (w != null) el.style.width = w + 'px';
154
+ if (h != null) el.style.height = h + 'px';
155
+ return el;
156
+ }
157
+
158
+ function drawPin(p) {
159
+ var el = node('button', 'street-pin street-pin--' + p.state);
160
+ el.setAttribute('type', 'button');
161
+ el.setAttribute('aria-label', p.aria);
162
+ el.setAttribute('aria-expanded', view.open === p.key ? 'true' : 'false');
163
+ el.setAttribute('aria-controls', 'streetCard');
164
+ el.setAttribute('data-matter', p.key);
165
+ el.setAttribute('data-building', p.building);
166
+ at(el, p.x, p.y, 110, p.h);
167
+ var label = node('span', 'street-pin__label', p.label);
168
+ label.setAttribute('title', p.label);
169
+ el.appendChild(label);
170
+ var head = node('span', 'street-pin__head');
171
+ if (p.state === 'needs') head.appendChild(node('span', 'street-pin__ring'));
172
+ if (p.isCount) head.appendChild(node('span', 'street-pin__count', p.count));
173
+ else {
174
+ var svg = document.createElementNS(SVG_NS, 'svg');
175
+ svg.setAttribute('width', '18');
176
+ svg.setAttribute('height', '18');
177
+ svg.setAttribute('aria-hidden', 'true');
178
+ var fill = document.createElementNS(SVG_NS, 'path');
179
+ fill.setAttribute('d', p.gf || '');
180
+ var line = document.createElementNS(SVG_NS, 'path');
181
+ line.setAttribute('d', p.gl || '');
182
+ svg.appendChild(fill);
183
+ svg.appendChild(line);
184
+ head.appendChild(svg);
185
+ }
186
+ el.appendChild(head);
187
+ el.appendChild(node('span', 'street-pin__stem'));
188
+ el.addEventListener('click', function () { openCard(p.key, el); });
189
+ return el;
190
+ }
191
+
192
+ function drawSign(sg) {
193
+ var a = node('a', 'street-sign' + (sg.hot ? ' street-sign--hot' : '') + (sg.here ? ' street-sign--here' : ''));
194
+ a.setAttribute('href', sg.href);
195
+ a.setAttribute('aria-label', sg.aria);
196
+ a.setAttribute('data-reading', sg.key);
197
+ if (sg.here) a.setAttribute('aria-current', 'location');
198
+ var top = node('span', 'street-sign__top');
199
+ top.appendChild(node('span', 'street-sign__dot'));
200
+ top.appendChild(node('span', 'street-label', sg.label));
201
+ a.appendChild(top);
202
+ a.appendChild(node('span', 'street-sign__figure', sg.figure));
203
+ a.appendChild(node('span', 'street-sign__line', sg.line));
204
+ return a;
205
+ }
206
+
207
+ function draw() {
208
+ var mode = currentMode();
209
+ view.mode = mode;
210
+ paintSwitch(mode);
211
+ var m = S.streetModel({ docket: data.docket, goals: data.goals, rollups: data.rollups, earnings: data.earnings, mode: mode, now: Date.now(), here: here() });
212
+ view.model = m;
213
+ var flat = $('streetFlat'), blds = $('streetBlds');
214
+ clear(flat); clear(blds);
215
+ m.flat.forEach(function (p) { flat.appendChild(pathEl(p)); });
216
+ m.blds.forEach(function (b) {
217
+ var g = document.createElementNS(SVG_NS, 'g');
218
+ g.setAttribute('data-key', b.key);
219
+ b.polys.forEach(function (p) { g.appendChild(pathEl(p)); });
220
+ blds.appendChild(g);
221
+ });
222
+
223
+ var crates = $('streetCrates'); clear(crates);
224
+ m.crates.forEach(function (c) { crates.appendChild(at(node('span', 'street-crate'), c.x, c.y)); });
225
+
226
+ var cols = $('streetCols'); clear(cols);
227
+ m.cols.forEach(function (c) {
228
+ var el = at(node('div', 'street-col'), c.x, 596, c.w);
229
+ var name = node('span', 'street-col__name' + (c.strong ? ' street-col__name--strong' : ''), c.name);
230
+ name.setAttribute('title', c.title);
231
+ el.appendChild(name);
232
+ el.appendChild(node('span', 'street-col__state', c.state));
233
+ cols.appendChild(el);
234
+ });
235
+
236
+ var groups = $('streetGroups'); clear(groups);
237
+ m.groups.forEach(function (g) {
238
+ var el = at(node('div', 'street-group'), g.x, 650, g.w);
239
+ el.appendChild(node('span', 'street-group__bracket'));
240
+ el.appendChild(node('span', 'street-label', g.name));
241
+ groups.appendChild(el);
242
+ });
243
+
244
+ var doors = $('streetDoors'); clear(doors);
245
+ m.doors.forEach(function (d) {
246
+ var a = at(node('a', 'street-door' + (d.here ? ' street-door--here' : '')), d.x, d.y, d.w, d.h);
247
+ a.setAttribute('href', d.href);
248
+ a.setAttribute('aria-label', d.aria);
249
+ a.setAttribute('data-door', d.key);
250
+ if (d.here) a.setAttribute('aria-current', 'location');
251
+ doors.appendChild(a);
252
+ });
253
+
254
+ var pins = $('streetPins'); clear(pins);
255
+ m.pins.forEach(function (p) { pins.appendChild(drawPin(p)); });
256
+
257
+ var signs = $('streetSigns'); clear(signs);
258
+ m.signs.forEach(function (sg) { signs.appendChild(drawSign(sg)); });
259
+
260
+ var hint = $('streetHint');
261
+ if (hint) { hint.textContent = m.hint; hint.hidden = !m.hint || !!view.open; }
262
+ var eve = $('streetEvening');
263
+ if (eve) eve.hidden = !(m.evening && !view.open);
264
+ var eveLine = $('streetEveningLine');
265
+ if (eveLine) eveLine.textContent = m.eveningLine;
266
+
267
+ $('hudNeeds').textContent = m.hud.needs;
268
+ $('hudMoving').textContent = m.hud.moving;
269
+ $('hudShare').textContent = m.hud.share;
270
+ var dot = $('hudDot');
271
+ if (dot) dot.className = 'street-hud__dot' + (m.hud.hot ? ' street-hud__dot--hot' : '');
272
+ var board = $('streetBoard');
273
+ if (board) board.setAttribute('aria-label', data.loaded ? m.label : 'The street, reading the docket');
274
+ var home = $('streetHome');
275
+ if (home) home.setAttribute('href', S.HOME_HREF);
276
+
277
+ fit();
278
+ if (view.open) fillCard();
279
+ return m;
280
+ }
281
+
282
+ // ---------- the short matter card ----------
283
+ function fillCard() {
284
+ var cv = S.cardFor(data.docket, view.open, Date.now());
285
+ if (!cv) { closeCard(false); return null; }
286
+ $('streetCardWhere').textContent = cv.where;
287
+ $('streetCardWhen').textContent = cv.when;
288
+ $('streetCardTitle').textContent = cv.title;
289
+ var meta = $('streetCardMeta');
290
+ var metaText = [cv.proposer, cv.tally].filter(Boolean).join(' · ');
291
+ meta.textContent = metaText;
292
+ meta.hidden = !metaText;
293
+ var lines = $('streetCardLines');
294
+ clear(lines);
295
+ cv.lines.forEach(function (t) { lines.appendChild(node('li', '', t)); });
296
+ lines.hidden = !cv.lines.length;
297
+ $('streetCardResult').textContent = cv.result;
298
+ var open = $('streetCardOpen');
299
+ if (cv.href) open.setAttribute('href', cv.href);
300
+ open.hidden = !cv.href;
301
+ placeCard();
302
+ return cv;
303
+ }
304
+ function placeCard() {
305
+ var card = $('streetCard');
306
+ if (!card || !view.open || !view.model) return;
307
+ var pin = null;
308
+ view.model.pins.forEach(function (p) { if (p.key === view.open) pin = p; });
309
+ var win = $('streetWindow'), sizer = $('streetSizer');
310
+ var stageW = (card.parentNode && card.parentNode.clientWidth) || window.innerWidth || 1440;
311
+ var originX = (sizer && sizer.offsetLeft != null ? sizer.offsetLeft : 0) - (win && win.scrollLeft ? win.scrollLeft : 0);
312
+ var cx = pin ? originX + (pin.x + 55) * view.scale : stageW / 2;
313
+ var x = Math.max(16, Math.min(stageW - CARD_W - 16, Math.round(cx - CARD_W / 2)));
314
+ card.style.setProperty('--street-card-x', x + 'px');
315
+ }
316
+ function openCard(key, opener) {
317
+ view.open = key;
318
+ view.opener = opener || null;
319
+ var card = $('streetCard');
320
+ if (!fillCard()) return;
321
+ card.hidden = false;
322
+ draw();
323
+ var close = $('streetCardClose');
324
+ if (close && close.focus) close.focus();
325
+ }
326
+ function closeCard(restore) {
327
+ var was = view.opener;
328
+ view.open = null;
329
+ view.opener = null;
330
+ var card = $('streetCard');
331
+ if (card) card.hidden = true;
332
+ draw();
333
+ // The pins were redrawn, so focus goes back to the new button for the same matter.
334
+ if (restore !== false && was && was.getAttribute) {
335
+ var key = was.getAttribute('data-matter');
336
+ var pins = $('streetPins').children || [];
337
+ for (var i = 0; i < pins.length; i++) {
338
+ if (pins[i].getAttribute('data-matter') === key) { if (pins[i].focus) pins[i].focus(); break; }
339
+ }
340
+ }
341
+ }
342
+ function onKey(e) {
343
+ if (e.key === 'Escape' && view.open) { e.preventDefault(); closeCard(true); }
344
+ }
345
+
346
+ function boot() {
347
+ var btn = $('streetMode');
348
+ if (btn) btn.addEventListener('click', toggleTheme);
349
+ var close = $('streetCardClose');
350
+ if (close) close.addEventListener('click', function () { closeCard(true); });
351
+ window.addEventListener('keydown', onKey);
352
+ window.addEventListener('resize', fit);
353
+ window.addEventListener('hashchange', function () { draw(); });
354
+ var win = $('streetWindow');
355
+ if (win) win.addEventListener('scroll', placeCard);
356
+ if (media && media.addEventListener) media.addEventListener('change', function () { if (!storedTheme()) { applyTheme(); draw(); } });
357
+ applyTheme();
358
+ draw();
359
+ return load();
360
+ }
361
+
362
+ window.GovStreetPage = { boot: boot, draw: draw, load: load, fit: fit, openCard: openCard, closeCard: closeCard, FEEDS: FEEDS, THEME_KEY: THEME_KEY };
363
+ window.GovStreetPage.ready = boot();
364
+ }());
@@ -0,0 +1,43 @@
1
+ {
2
+ "_": "THE STREET (task 1004525, goal 1000125) through modules/ui-design/kit/render.js. The page draws GET /government/docket, GET /goals, GET /goals/rollups and the viewer's GET /builders/:id/earnings; against the kit's own stub none exists, so every state renders the bare street (the nine civic buildings, no districts, no pins) with the readings saying the docket could not be read: a real state the floors must hold in. To look at the populated street, run it against the hall-preview harness, whose government__docket.json fixture carries the reference design's seven sample matters (3 need you, 2 moving, 2 settled) and whose goals fixtures carry the open goals:\n\n node scripts/hall-preview/server.js --port 4625 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/street.states.json --base-in http://localhost:4625 --base-out http://localhost:4625\n\nThe page follows the OS mode until the switch is pressed (then the hall's own 'hall-theme' preference), so the kit's dark/light emulation renders both modes.",
3
+ "page": "/builders/street",
4
+ "surface": "hall-ui",
5
+ "stub": { "prefix": "/builders/" },
6
+ "modeQuery": false,
7
+ "ignoreRequests": ["/api/(gds|bongos)/", "fonts\\.g(oogleapis|static)\\.com"],
8
+ "ignoreConsole": ["/api/(gds|bongos)/", "\\b401\\b", "\\b403\\b", "\\b404\\b", "Unauthorized", "Forbidden", "Not Found", "load failed", "fonts\\.g(oogleapis|static)\\.com"],
9
+ "states": {
10
+ "street": {
11
+ "auth": true,
12
+ "_": "The street: the header, the buildings in the order work moves with their names, state lines and group brackets, the pins, and the six readings.",
13
+ "actions": [["wait", 900]],
14
+ "expect": { "visible": ["#streetBoard", "#streetSigns", "#streetMode", "#streetHome"], "href": [["#streetHome", "/builders/city"]] }
15
+ },
16
+ "card": {
17
+ "auth": true,
18
+ "_": "A pin pressed: the matter's short card over the street.",
19
+ "actions": [["wait", 900], ["click", ".street-pin"], ["wait", 400]],
20
+ "expect": { "visible": ["#streetCard", "#streetCardClose"] }
21
+ },
22
+ "switched": {
23
+ "auth": true,
24
+ "_": "The light/dark switch pressed once: the other mode, the street redrawn in it.",
25
+ "actions": [["wait", 600], ["click", "#streetMode"], ["wait", 400]],
26
+ "expect": { "visible": ["#streetBoard", "#streetSigns"] }
27
+ },
28
+ "here": {
29
+ "auth": true,
30
+ "_": "Arrived through a door: the address names the Charter, so its door and the readings that open it are marked.",
31
+ "url": "/builders/street#building=charter",
32
+ "actions": [["wait", 900]],
33
+ "expect": { "visible": ["#streetBoard"] }
34
+ },
35
+ "focus": {
36
+ "auth": true,
37
+ "_": "Keyboard: the wordmark back to the city focused, its ring drawn.",
38
+ "actions": [["wait", 600], ["focus", "#streetHome"], ["wait", 100]],
39
+ "expect": { "activeId": "streetHome" }
40
+ }
41
+ },
42
+ "reducedMotion": { "auth": true, "actions": [["wait", 600]] }
43
+ }
@@ -0,0 +1,14 @@
1
+ # The Governor City's street — /street, the six readings, and the doors to the interiors (task 1004525)
2
+
3
+ **R03 of goal 1000125.** Built 1:1 on the street view of the reference design [`docs/design/mocks/governor-city/Street.dc.html`](../../../docs/design/mocks/governor-city/README.md): one front-on row in the order work moves under five group brackets, a name and one state line under every building, pins with their labels always showing, work queued at Review as crates by its door, the header (wordmark back to the city, needs you, moving, your share this month, the light/dark switch) and the six readings along the bottom. The home city (`/city`, task 1004524) links here from start governing.
4
+
5
+ Files: `street-draw.js` (the prototype's front-on kit and street layout, verbatim, as pure data: `window.GovStreet`, node-require-safe), `street.js` (the page: feeds, nodes, the switch, the address, the short card) and `street.css` (the template's styles on the hall's tokens). It reuses `city-draw.js` for the decision glyphs, the seeded random and `rulesAtWork`, which the city now also uses to light the Rules band.
6
+
7
+ What it settled:
8
+
9
+ - **Standalone, like the city.** No hall sidebar or top bar; it is the second entry in `tests/hall_audit.mjs`'s `STANDALONE_EXEMPT`, with the city's reason. It still loads `style.css` and reads and writes the hall's own `hall-theme`.
10
+ - **The artboard is the street band.** The prototype's 1440 x 900 board less its 64 px header and 128 px footer, which the page lays out as real rows; `street.js` scales the 1440 x 708 band to the window, and on a phone keeps it near full size and lets the street scroll sideways inside its own window, so a pin stays a pin. The header fits the 80 px top-bar floor at 390 and 320 by going to two rows, its three figures as their own sideways strip.
11
+ - **Real data where the prototype had samples.** One district per open goal (up to eight plots; past that seven stand and the eighth is a staked lot that opens the goals page), each goal's tasks drawn in proportion (built, scaffold, the prototype's `ready` slab), Review held while any source that stands in it can be read, its open matters as crates and the dashed "waiting for a tester" count pin, a reading off drawn as a dash and its reason. The full list is the header of `street-draw.js`.
12
+ - **Every building and district is a door** to `/street#building=<key>` or `/street#district=<goal id>`, where task 1004526 builds the interiors; until then the street marks the building the address names. A pin opens the matter's short card (task 1004528 makes it act); its link is offered only for an on-site path.
13
+
14
+ Tests: `tests/hall_street.mjs` holds the kit, the row, the pins, the doors and the crates equal to the prototype by running its own `Component` class beside `street-draw.js` in both modes, then the docket rules and the page itself in a vm. The states file is `public/street.states.json`; render it against the hall-preview harness, whose `government__docket.json` fixture carries the seven sample matters.
@@ -0,0 +1,216 @@
1
+ {
2
+ "_": "The create wizard done panel once the hall answers (task 1004503): the same walk as projects.states.json in-new-done, with the instance list aliased so the project just filed (id 102) is live and verified up. The invite box opens only now; in-new-done in the main file pictures it shut while the project is set up. Rendered by name: node modules/ui-design/kit/render.js --states modules/public-landing/public/projects-hall-live.states.json",
3
+ "page": "/projects",
4
+ "surface": "public-landing",
5
+ "modes": [
6
+ "dark"
7
+ ],
8
+ "modeQuery": false,
9
+ "stub": {
10
+ "fixtures": {
11
+ "provisioning-instances": "provisioning-instances-hall-live"
12
+ }
13
+ },
14
+ "ignoreRequests": [
15
+ "/api/(gds|bongos)/me$",
16
+ "/my-projects",
17
+ "/provisioning/onboard-plan",
18
+ "/env-manifest$"
19
+ ],
20
+ "ignoreConsole": [
21
+ "/api/(gds|bongos)/me",
22
+ "\\b401\\b",
23
+ "\\b404\\b",
24
+ "Unauthorized"
25
+ ],
26
+ "states": {
27
+ "in-new-done-live": {
28
+ "auth": true,
29
+ "url": "/projects?view=new",
30
+ "actions": [
31
+ [
32
+ "wait",
33
+ 600
34
+ ],
35
+ [
36
+ "click",
37
+ "#termsAck"
38
+ ],
39
+ [
40
+ "wait",
41
+ 100
42
+ ],
43
+ [
44
+ "click",
45
+ "#wizStart"
46
+ ],
47
+ [
48
+ "wait",
49
+ 400
50
+ ],
51
+ [
52
+ "fill",
53
+ "#newName",
54
+ "Mercury"
55
+ ],
56
+ [
57
+ "click",
58
+ "#typeCards .tpill[data-type=\"game\"]"
59
+ ],
60
+ [
61
+ "fill",
62
+ "#f-desc",
63
+ "A co-op farming game where the seasons never repeat."
64
+ ],
65
+ [
66
+ "click",
67
+ "#panel-what button[type=submit]"
68
+ ],
69
+ [
70
+ "wait",
71
+ 400
72
+ ],
73
+ [
74
+ "select",
75
+ "#physCountry",
76
+ "US"
77
+ ],
78
+ [
79
+ "wait",
80
+ 100
81
+ ],
82
+ [
83
+ "click",
84
+ "[data-phys=\"builder_geography\"][data-val=\"global\"]"
85
+ ],
86
+ [
87
+ "click",
88
+ "[data-phys=\"minors_on_board\"][data-val=\"false\"]"
89
+ ],
90
+ [
91
+ "click",
92
+ "[data-phys=\"entity\"][data-val=\"intent-solo\"]"
93
+ ],
94
+ [
95
+ "click",
96
+ "#physNext"
97
+ ],
98
+ [
99
+ "wait",
100
+ 700
101
+ ],
102
+ [
103
+ "click",
104
+ "#reviewRows .setRow[data-row=\"code\"] [data-row-ok]"
105
+ ],
106
+ [
107
+ "wait",
108
+ 200
109
+ ],
110
+ [
111
+ "click",
112
+ "#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"
113
+ ],
114
+ [
115
+ "wait",
116
+ 200
117
+ ],
118
+ [
119
+ "fill",
120
+ "#f-slug",
121
+ "mercury"
122
+ ],
123
+ [
124
+ "wait",
125
+ 900
126
+ ],
127
+ [
128
+ "fill",
129
+ "#f-domain",
130
+ "mercury.example.com"
131
+ ],
132
+ [
133
+ "wait",
134
+ 200
135
+ ],
136
+ [
137
+ "click",
138
+ "#reviewRows .setRow[data-row=\"address\"] [data-row-use]"
139
+ ],
140
+ [
141
+ "wait",
142
+ 200
143
+ ],
144
+ [
145
+ "click",
146
+ "#reviewRows .setRow[data-row=\"app\"] [data-row-ok]"
147
+ ],
148
+ [
149
+ "wait",
150
+ 150
151
+ ],
152
+ [
153
+ "click",
154
+ "#reviewRows .setRow[data-row=\"extras\"] [data-row-ok]"
155
+ ],
156
+ [
157
+ "wait",
158
+ 150
159
+ ],
160
+ [
161
+ "click",
162
+ "#reviewRows .setRow[data-row=\"team\"] [data-row-ok]"
163
+ ],
164
+ [
165
+ "wait",
166
+ 150
167
+ ],
168
+ [
169
+ "click",
170
+ "#reviewRows .setRow[data-row=\"run\"] [data-row-ok]"
171
+ ],
172
+ [
173
+ "wait",
174
+ 200
175
+ ],
176
+ [
177
+ "click",
178
+ "#reviewGo"
179
+ ],
180
+ [
181
+ "wait",
182
+ 500
183
+ ],
184
+ [
185
+ "click",
186
+ "#doCreate"
187
+ ],
188
+ [
189
+ "wait",
190
+ 1500
191
+ ],
192
+ [
193
+ "wait",
194
+ 6000
195
+ ]
196
+ ],
197
+ "expect": {
198
+ "visible": [
199
+ "#panel-done",
200
+ "#wizInvite",
201
+ "#wizInviteWho"
202
+ ],
203
+ "text": [
204
+ [
205
+ "#done-h",
206
+ "Mercury is alive."
207
+ ]
208
+ ]
209
+ }
210
+ }
211
+ },
212
+ "ignoreControls": [
213
+ ".skip",
214
+ ".vh"
215
+ ]
216
+ }