@bongos/core 1.25.3 → 1.25.5
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/.bongos-core.json +72 -47
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -0
- package/clients/bongos-client/index.cjs +4 -0
- package/clients/bongos-client/index.d.ts +8 -0
- package/clients/bongos-client/index.mjs +4 -0
- package/docs/api/openapi.json +185 -3
- package/docs/api-reference.md +5 -3
- package/docs/copy-inventory.md +17 -18
- package/docs/copy-registry.json +44 -43
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-readings.json +43 -43
- package/modules/hall-ui/public/builders.js +3 -27
- package/modules/hall-ui/public/hall-render.js +5 -119
- package/modules/hall-ui/public/hall-widgets.js +3 -3
- package/modules/hall-ui/public/index.html +0 -7
- package/modules/hall-ui/public/shell-game.js +22 -4
- package/modules/hall-ui/public/style.css +3 -73
- package/modules/hall-ui/public/visor.css +31 -1
- package/modules/hall-ui/public/visor.js +53 -3
- package/modules/hall-ui/records/home-reshuffle.md +1 -1
- package/modules/hall-ui/records/visor.md +10 -0
- package/modules/provisioning/migrations/provisioning_037_update_subscribed.sql +21 -0
- package/modules/provisioning/module.json +1 -0
- package/modules/provisioning/routes/provisioning.js +4 -0
- package/modules/provisioning/routes/update-subscription.js +51 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +16 -0
- package/scripts/bongos/update-channel.js +27 -4
- package/scripts/bongos/update-sweep.js +17 -3
- package/src/bongos/api-errors.js +2 -0
- package/src/bongos/db.js +43 -0
- package/src/bongos/route-rank-check.js +1 -0
- package/src/bongos/routes/builders.js +37 -0
- package/src/module-api.js +1 -1
- package/tests/builder_card_requirement.mjs +75 -0
- package/tests/hall_board_world.mjs +7 -35
- package/tests/hall_home_ships_bounded.mjs +11 -27
- package/tests/hall_landing_boot.mjs +7 -8
- package/tests/hall_nav.mjs +2 -2
- package/tests/hall_visor.mjs +9 -2
- package/tests/hall_visor_profile.mjs +150 -0
- package/tests/leaderboard_roles.mjs +3 -17
- package/tests/provisioning_update_subscription_route.mjs +141 -0
- package/tests/update_channel_db.mjs +24 -0
package/docs/page-readings.json
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
"adr": "0341 D3",
|
|
6
6
|
"reread": "node scripts/bongos/page-reader.js --stale",
|
|
7
7
|
"how": ["Generated by node scripts/bongos/page-reader.js (BV2.TW04, task 1004315; ADR 0341 D3). Do not hand-edit.","One entry per page of docs/page-inventory.json. Lines are in page order: the default state first, and a line only another state shows sits where that state shows it, with its state named.","placement: placed = a docs/copy-registry.json row renders it (file, line, string_id); shared = shell text every page of the surface carries (top bar, sidebar, footer), with its row when the registry has one; unplaced = the registry cannot place it (a rewrite becomes an engineer task, ADR 0341 D4).","text keeps {…} where the registry row has a hole, or where a value the page read from its API was filled in. A string that is only such data is counted under omitted.data, not listed.","reading_hash is over the non-shared lines (key, section, text); files_hash is over the page's inventory files. --check compares files_hash only and never opens a browser.","Rendered through the hall-preview harness (hall) and the ui-design kit stub (landing, status), at 1280x800 with the clock pinned, so a reading is the fixture world's page."],
|
|
8
|
-
"counts": {"pages":45,"lines":4411,"placed":1638,"shared":369,"unplaced":2404,"omitted_data":
|
|
8
|
+
"counts": {"pages":45,"lines":4411,"placed":1638,"shared":369,"unplaced":2404,"omitted_data":2980},
|
|
9
9
|
"pages": [
|
|
10
10
|
{
|
|
11
11
|
"id": "builders:ai-studio",
|
|
12
12
|
"surface": "builders",
|
|
13
13
|
"title": "Studio",
|
|
14
14
|
"states_read": ["pick","describe","make","waiting","result","result-own","failed","balance","balance-all","out"],
|
|
15
|
-
"files_hash": "
|
|
15
|
+
"files_hash": "5b785de6639c8ec5",
|
|
16
16
|
"reading_hash": "d9e0e85bcee4aff4",
|
|
17
17
|
"counts": {"lines":106,"placed":41,"shared":7,"unplaced":58},
|
|
18
18
|
"omitted": {"data":17},
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"surface": "builders",
|
|
132
132
|
"title": "Repo Atlas",
|
|
133
133
|
"states_read": ["map","truth","detail","index","out"],
|
|
134
|
-
"files_hash": "
|
|
134
|
+
"files_hash": "76f3f9d62c147df5",
|
|
135
135
|
"reading_hash": "6934dead335b2507",
|
|
136
136
|
"counts": {"lines":25,"placed":14,"shared":7,"unplaced":4},
|
|
137
137
|
"omitted": {"data":5},
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
"surface": "builders",
|
|
170
170
|
"title": "Blockers",
|
|
171
171
|
"states_read": ["default"],
|
|
172
|
-
"files_hash": "
|
|
172
|
+
"files_hash": "8492188331702a2f",
|
|
173
173
|
"reading_hash": "60d73d854ced958a",
|
|
174
174
|
"counts": {"lines":36,"placed":17,"shared":7,"unplaced":12},
|
|
175
175
|
"omitted": {"data":51},
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
"surface": "builders",
|
|
219
219
|
"title": "Board Room",
|
|
220
220
|
"states_read": ["room","out","sitting-meta","objection-form"],
|
|
221
|
-
"files_hash": "
|
|
221
|
+
"files_hash": "4218d029418aa874",
|
|
222
222
|
"reading_hash": "0260b797b8dc1526",
|
|
223
223
|
"counts": {"lines":52,"placed":21,"shared":7,"unplaced":24},
|
|
224
224
|
"omitted": {"data":17},
|
|
@@ -283,7 +283,7 @@
|
|
|
283
283
|
"surface": "builders",
|
|
284
284
|
"title": "The city",
|
|
285
285
|
"states_read": ["city","fullscreen","focus","pins","living","card","card-ask"],
|
|
286
|
-
"files_hash": "
|
|
286
|
+
"files_hash": "3a16e78aaab2e893",
|
|
287
287
|
"reading_hash": "277096d903879a57",
|
|
288
288
|
"counts": {"lines":26,"placed":9,"shared":6,"unplaced":11},
|
|
289
289
|
"omitted": {"data":7},
|
|
@@ -322,7 +322,7 @@
|
|
|
322
322
|
"surface": "builders",
|
|
323
323
|
"title": "Collab",
|
|
324
324
|
"states_read": ["board","out"],
|
|
325
|
-
"files_hash": "
|
|
325
|
+
"files_hash": "9e9d0d3b86089631",
|
|
326
326
|
"reading_hash": "e6452bf92231656f",
|
|
327
327
|
"counts": {"lines":82,"placed":36,"shared":6,"unplaced":40},
|
|
328
328
|
"omitted": {"data":23},
|
|
@@ -417,7 +417,7 @@
|
|
|
417
417
|
"surface": "builders",
|
|
418
418
|
"title": "Commands",
|
|
419
419
|
"states_read": ["in","out"],
|
|
420
|
-
"files_hash": "
|
|
420
|
+
"files_hash": "14d04212aba71360",
|
|
421
421
|
"reading_hash": "ecc452689a8ee9d7",
|
|
422
422
|
"counts": {"lines":71,"placed":49,"shared":7,"unplaced":15},
|
|
423
423
|
"omitted": {"data":177},
|
|
@@ -501,7 +501,7 @@
|
|
|
501
501
|
"surface": "builders",
|
|
502
502
|
"title": "Copy desk",
|
|
503
503
|
"states_read": ["queue","out","search","composer","closer","proposer"],
|
|
504
|
-
"files_hash": "
|
|
504
|
+
"files_hash": "498777214970f599",
|
|
505
505
|
"reading_hash": "3819ef6fa8f6fb7c",
|
|
506
506
|
"counts": {"lines":72,"placed":36,"shared":7,"unplaced":29},
|
|
507
507
|
"omitted": {"data":94},
|
|
@@ -586,7 +586,7 @@
|
|
|
586
586
|
"surface": "builders",
|
|
587
587
|
"title": "Deploy",
|
|
588
588
|
"states_read": ["work","out"],
|
|
589
|
-
"files_hash": "
|
|
589
|
+
"files_hash": "d93352de799f272f",
|
|
590
590
|
"reading_hash": "3770e8b2fa56bee1",
|
|
591
591
|
"counts": {"lines":14,"placed":5,"shared":7,"unplaced":2},
|
|
592
592
|
"omitted": {"data":5},
|
|
@@ -613,7 +613,7 @@
|
|
|
613
613
|
"surface": "builders",
|
|
614
614
|
"title": "The sky",
|
|
615
615
|
"states_read": ["tour","sky","wells","ledger","full","full-back","out"],
|
|
616
|
-
"files_hash": "
|
|
616
|
+
"files_hash": "50735ca110164fe8",
|
|
617
617
|
"reading_hash": "4a879397a84631e3",
|
|
618
618
|
"counts": {"lines":50,"placed":25,"shared":6,"unplaced":19},
|
|
619
619
|
"omitted": {"data":10},
|
|
@@ -676,7 +676,7 @@
|
|
|
676
676
|
"surface": "builders",
|
|
677
677
|
"title": "Goals",
|
|
678
678
|
"states_read": ["list","filters","cards","detail","dependencies","out","uat","uat-panel","author"],
|
|
679
|
-
"files_hash": "
|
|
679
|
+
"files_hash": "23bb6e3ad6306135",
|
|
680
680
|
"reading_hash": "13a5d07b3804b627",
|
|
681
681
|
"counts": {"lines":187,"placed":61,"shared":7,"unplaced":119},
|
|
682
682
|
"omitted": {"data":315},
|
|
@@ -776,7 +776,7 @@
|
|
|
776
776
|
{"key":"L0092","section":"Tasks","text":"{…} (high → low)","placement":"unplaced","state":"detail"},
|
|
777
777
|
{"key":"L0093","section":"Tasks","text":"minutes (low → high)","placement":"unplaced","state":"detail"},
|
|
778
778
|
{"key":"L0094","section":"Tasks","text":"priority (P0 first)","placement":"unplaced","state":"detail"},
|
|
779
|
-
{"key":"L0095","section":"Tasks","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":
|
|
779
|
+
{"key":"L0095","section":"Tasks","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":460,"string_id":"4d8ee7d68974","state":"detail"},
|
|
780
780
|
{"key":"L0096","section":"Tasks","text":"status","placement":"unplaced","state":"detail"},
|
|
781
781
|
{"key":"L0097","section":"Tasks","text":"Filters","placement":"unplaced","state":"detail"},
|
|
782
782
|
{"key":"L0098","section":"Tasks","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"detail","occurrences":3},
|
|
@@ -876,7 +876,7 @@
|
|
|
876
876
|
"surface": "builders",
|
|
877
877
|
"title": "Government",
|
|
878
878
|
"states_read": ["constitution","out","permissions","board","constitution-tab"],
|
|
879
|
-
"files_hash": "
|
|
879
|
+
"files_hash": "d168f2cd8aa66e32",
|
|
880
880
|
"reading_hash": "37c6878d60447fd6",
|
|
881
881
|
"counts": {"lines":65,"placed":27,"shared":7,"unplaced":31},
|
|
882
882
|
"omitted": {"data":276},
|
|
@@ -954,16 +954,16 @@
|
|
|
954
954
|
"surface": "builders",
|
|
955
955
|
"title": "Builders' Hall",
|
|
956
956
|
"states_read": ["home","out","founding","genesis","decide","demo","votes"],
|
|
957
|
-
"files_hash": "
|
|
958
|
-
"reading_hash": "
|
|
957
|
+
"files_hash": "730694ff18f4468d",
|
|
958
|
+
"reading_hash": "177d0c13a53c0491",
|
|
959
959
|
"counts": {"lines":32,"placed":12,"shared":8,"unplaced":12},
|
|
960
|
-
"omitted": {"data":
|
|
960
|
+
"omitted": {"data":4},
|
|
961
961
|
"notes": ["founding: an action failed (page.focus: Timeout 6000ms exceeded.); read as it stood"],
|
|
962
962
|
"lines": [
|
|
963
963
|
{"key":"L0001","section":"skip link","text":"Skip to content","placement":"shared","file":"modules/hall-ui/public/shell.js","line":814,"string_id":"87cee78ca134"},
|
|
964
964
|
{"key":"L0002","section":"top bar","text":"Home","placement":"shared"},
|
|
965
965
|
{"key":"L0003","section":"top bar","text":"Update","placement":"shared"},
|
|
966
|
-
{"key":"L0004","section":"top bar","text":"Welcome back, {…}.","placement":"shared","file":"modules/hall-ui/public/hall-render.js","line":
|
|
966
|
+
{"key":"L0004","section":"top bar","text":"Welcome back, {…}.","placement":"shared","file":"modules/hall-ui/public/hall-render.js","line":442,"string_id":"0658f0358ffd"},
|
|
967
967
|
{"key":"L0005","section":"top bar","text":"Jump to…","placement":"shared","file":"modules/hall-ui/public/shell.js","line":536,"string_id":"eba610d25523"},
|
|
968
968
|
{"key":"L0006","section":"top bar","text":"Ctrl K","placement":"shared"},
|
|
969
969
|
{"key":"L0007","section":"top bar","text":"Artist","placement":"shared"},
|
|
@@ -973,11 +973,11 @@
|
|
|
973
973
|
{"key":"L0011","section":"Good morning, {…}","text":"Oct","placement":"unplaced"},
|
|
974
974
|
{"key":"L0012","section":"Good morning, {…}","text":"Live","placement":"unplaced"},
|
|
975
975
|
{"key":"L0013","section":"Needs your attention13","text":"Needs your attention","placement":"placed","file":"modules/hall-ui/public/goal-inbox.js","line":580,"string_id":"7def635421ea"},
|
|
976
|
-
{"key":"L0014","section":"Needs your attention13","text":"From the system","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":
|
|
976
|
+
{"key":"L0014","section":"Needs your attention13","text":"From the system","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":495,"string_id":"d32c5e058d1e"},
|
|
977
977
|
{"key":"L0015","section":"Needs your attention13","text":"Ideas awaiting triage","placement":"placed","file":"modules/hall-ui/public/builders.js","line":320,"string_id":"e181637c5a5e"},
|
|
978
978
|
{"key":"L0016","section":"Needs your attention13","text":"Requires project {…} fix","placement":"unplaced"},
|
|
979
979
|
{"key":"L0017","section":"footer","text":"Sign out","placement":"shared","file":"modules/hall-ui/public/shell.js","line":514,"string_id":"1883ad7f07fc"},
|
|
980
|
-
{"key":"L0018","section":"Needs your attention13","text":"core 1.25.
|
|
980
|
+
{"key":"L0018","section":"Needs your attention13","text":"core 1.25.2","placement":"unplaced"},
|
|
981
981
|
{"key":"L0019","section":"Needs your attention13","text":"Skip","placement":"unplaced"},
|
|
982
982
|
{"key":"L0020","section":"Needs your attention13","text":"Built on","placement":"placed","file":"modules/hall-ui/public/welcome-boot.js","line":183,"string_id":"fef59346ffee"},
|
|
983
983
|
{"key":"L0021","section":"Needs your attention13","text":"cloudbongos.com","placement":"unplaced"},
|
|
@@ -999,7 +999,7 @@
|
|
|
999
999
|
"surface": "builders",
|
|
1000
1000
|
"title": "Idea",
|
|
1001
1001
|
"states_read": ["record","missing"],
|
|
1002
|
-
"files_hash": "
|
|
1002
|
+
"files_hash": "02820c742a0bceb9",
|
|
1003
1003
|
"reading_hash": "f7d644748c87e426",
|
|
1004
1004
|
"counts": {"lines":52,"placed":25,"shared":8,"unplaced":19},
|
|
1005
1005
|
"omitted": {"data":25},
|
|
@@ -1064,7 +1064,7 @@
|
|
|
1064
1064
|
"surface": "builders",
|
|
1065
1065
|
"title": "Ideas",
|
|
1066
1066
|
"states_read": ["compose","full","develop"],
|
|
1067
|
-
"files_hash": "
|
|
1067
|
+
"files_hash": "59688a8b224ba2ec",
|
|
1068
1068
|
"reading_hash": "a62c05dcef3bf87f",
|
|
1069
1069
|
"counts": {"lines":68,"placed":34,"shared":7,"unplaced":27},
|
|
1070
1070
|
"omitted": {"data":118},
|
|
@@ -1145,7 +1145,7 @@
|
|
|
1145
1145
|
"surface": "builders",
|
|
1146
1146
|
"title": "Market Watch",
|
|
1147
1147
|
"states_read": ["desk","settings","out"],
|
|
1148
|
-
"files_hash": "
|
|
1148
|
+
"files_hash": "377ad66b86dfdd0b",
|
|
1149
1149
|
"reading_hash": "30512dda207b5ea6",
|
|
1150
1150
|
"counts": {"lines":23,"placed":11,"shared":7,"unplaced":5},
|
|
1151
1151
|
"omitted": {"data":5},
|
|
@@ -1181,7 +1181,7 @@
|
|
|
1181
1181
|
"surface": "builders",
|
|
1182
1182
|
"title": "Market Watch",
|
|
1183
1183
|
"states_read": ["dossier","out","propose","correct","filtered"],
|
|
1184
|
-
"files_hash": "
|
|
1184
|
+
"files_hash": "bb602ff95badc43c",
|
|
1185
1185
|
"reading_hash": "129bff28c4e4ed6d",
|
|
1186
1186
|
"counts": {"lines":24,"placed":12,"shared":7,"unplaced":5},
|
|
1187
1187
|
"omitted": {"data":5},
|
|
@@ -1218,7 +1218,7 @@
|
|
|
1218
1218
|
"surface": "builders",
|
|
1219
1219
|
"title": "Market Watch rules",
|
|
1220
1220
|
"states_read": ["in","scoring","names","propose","out"],
|
|
1221
|
-
"files_hash": "
|
|
1221
|
+
"files_hash": "6c2edc411eed69bc",
|
|
1222
1222
|
"reading_hash": "ca0c62e8dce51c8b",
|
|
1223
1223
|
"counts": {"lines":36,"placed":12,"shared":7,"unplaced":17},
|
|
1224
1224
|
"omitted": {"data":20},
|
|
@@ -1267,7 +1267,7 @@
|
|
|
1267
1267
|
"surface": "builders",
|
|
1268
1268
|
"title": "Modules",
|
|
1269
1269
|
"states_read": ["browse","search-empty","lens","details","out"],
|
|
1270
|
-
"files_hash": "
|
|
1270
|
+
"files_hash": "61872edf35808d71",
|
|
1271
1271
|
"reading_hash": "6a12e9306bba5622",
|
|
1272
1272
|
"counts": {"lines":59,"placed":29,"shared":7,"unplaced":23},
|
|
1273
1273
|
"omitted": {"data":107},
|
|
@@ -1339,7 +1339,7 @@
|
|
|
1339
1339
|
"surface": "builders",
|
|
1340
1340
|
"title": "Money",
|
|
1341
1341
|
"states_read": ["money","hosting","out"],
|
|
1342
|
-
"files_hash": "
|
|
1342
|
+
"files_hash": "cbce1cf96f277a69",
|
|
1343
1343
|
"reading_hash": "e355d5466b123e07",
|
|
1344
1344
|
"counts": {"lines":83,"placed":28,"shared":7,"unplaced":48},
|
|
1345
1345
|
"omitted": {"data":27},
|
|
@@ -1435,7 +1435,7 @@
|
|
|
1435
1435
|
"surface": "builders",
|
|
1436
1436
|
"title": "My agents",
|
|
1437
1437
|
"states_read": ["desk","factory","saved","what-it-knows","speciality-walk","speciality-forms","nobody"],
|
|
1438
|
-
"files_hash": "
|
|
1438
|
+
"files_hash": "d3dbce13a5390286",
|
|
1439
1439
|
"reading_hash": "5347e0496b38727d",
|
|
1440
1440
|
"counts": {"lines":100,"placed":33,"shared":7,"unplaced":60},
|
|
1441
1441
|
"omitted": {"data":38},
|
|
@@ -1548,7 +1548,7 @@
|
|
|
1548
1548
|
"surface": "builders",
|
|
1549
1549
|
"title": "Primer",
|
|
1550
1550
|
"states_read": ["in","toc-open","jump","out"],
|
|
1551
|
-
"files_hash": "
|
|
1551
|
+
"files_hash": "df4ef875bc5238b7",
|
|
1552
1552
|
"reading_hash": "85790bd421e5c387",
|
|
1553
1553
|
"counts": {"lines":487,"placed":57,"shared":7,"unplaced":423},
|
|
1554
1554
|
"omitted": {"data":18},
|
|
@@ -1689,7 +1689,7 @@
|
|
|
1689
1689
|
{"key":"L0133","section":"The rank ladder","text":"automatically after your 3rd shipped task","placement":"unplaced"},
|
|
1690
1690
|
{"key":"L0134","section":"The rank ladder","text":"— no one has to promote you.","placement":"unplaced"},
|
|
1691
1691
|
{"key":"L0135","section":"The rank ladder","text":"any","placement":"unplaced"},
|
|
1692
|
-
{"key":"L0136","section":"The rank ladder","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":
|
|
1692
|
+
{"key":"L0136","section":"The rank ladder","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":460,"string_id":"4d8ee7d68974"},
|
|
1693
1693
|
{"key":"L0137","section":"The rank ladder","text":"Metic","placement":"unplaced"},
|
|
1694
1694
|
{"key":"L0138","section":"The rank ladder","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","occurrences":2},
|
|
1695
1695
|
{"key":"L0139","section":"The rank ladder","text":"Archon","placement":"unplaced"},
|
|
@@ -2048,7 +2048,7 @@
|
|
|
2048
2048
|
"surface": "builders",
|
|
2049
2049
|
"title": "Profile",
|
|
2050
2050
|
"states_read": ["own","works","activity","yours","activity-artist","activity-artist-ideas","other","artist","artist-ideas","out"],
|
|
2051
|
-
"files_hash": "
|
|
2051
|
+
"files_hash": "412b85b0c70da301",
|
|
2052
2052
|
"reading_hash": "3ff8d703d17e8c2a",
|
|
2053
2053
|
"counts": {"lines":232,"placed":84,"shared":7,"unplaced":141},
|
|
2054
2054
|
"omitted": {"data":263},
|
|
@@ -2293,7 +2293,7 @@
|
|
|
2293
2293
|
"surface": "builders",
|
|
2294
2294
|
"title": "Project settings",
|
|
2295
2295
|
"states_read": ["default"],
|
|
2296
|
-
"files_hash": "
|
|
2296
|
+
"files_hash": "4f917ac224479a34",
|
|
2297
2297
|
"reading_hash": "283df27d0d5bfc1b",
|
|
2298
2298
|
"counts": {"lines":43,"placed":25,"shared":7,"unplaced":11},
|
|
2299
2299
|
"omitted": {"data":33},
|
|
@@ -2349,7 +2349,7 @@
|
|
|
2349
2349
|
"surface": "builders",
|
|
2350
2350
|
"title": "Builders",
|
|
2351
2351
|
"states_read": ["roster","artists","search","out"],
|
|
2352
|
-
"files_hash": "
|
|
2352
|
+
"files_hash": "337395b2465f66fc",
|
|
2353
2353
|
"reading_hash": "665ac2e36339f5d3",
|
|
2354
2354
|
"counts": {"lines":56,"placed":17,"shared":7,"unplaced":32},
|
|
2355
2355
|
"omitted": {"data":137},
|
|
@@ -2418,7 +2418,7 @@
|
|
|
2418
2418
|
"surface": "builders",
|
|
2419
2419
|
"title": "Options",
|
|
2420
2420
|
"states_read": ["account","access","preferences","install-reports","sound","update"],
|
|
2421
|
-
"files_hash": "
|
|
2421
|
+
"files_hash": "77001d9bd6423a92",
|
|
2422
2422
|
"reading_hash": "898a13fda24c3c90",
|
|
2423
2423
|
"counts": {"lines":162,"placed":104,"shared":7,"unplaced":51},
|
|
2424
2424
|
"omitted": {"data":23},
|
|
@@ -2593,7 +2593,7 @@
|
|
|
2593
2593
|
"surface": "builders",
|
|
2594
2594
|
"title": "The street",
|
|
2595
2595
|
"states_read": ["street","fullscreen","card","focus","here","inside-rules","inside-disputes","inside-people","inside-planning","inside-automation","inside-review","inside-release","inside-treasury","floor","amend","district","desk","desk-facts","desk-quiet","desk-people-builders","desk-people-tier","desk-disputes","desk-automation-goals","desk-release-core","desk-rules","desk-rules-category","desk-planning-priorities","desk-planning-ideas","desk-planning-blockers","pins","pins-pager","living","deck","deck-treasury","sitting","object","voted","admission","settled","blocker","blocker-more","report","report-more","core","core-more","recheck","recheck-more","idea","idea-more","queue","queue-more","automation","automation-more"],
|
|
2596
|
-
"files_hash": "
|
|
2596
|
+
"files_hash": "8cd0e137ff9ec280",
|
|
2597
2597
|
"reading_hash": "e788e6bf4be8d68c",
|
|
2598
2598
|
"counts": {"lines":325,"placed":54,"shared":6,"unplaced":265},
|
|
2599
2599
|
"omitted": {"data":240},
|
|
@@ -2766,7 +2766,7 @@
|
|
|
2766
2766
|
{"key":"L0165","section":"{…} reports","text":"5 matters on the docket · 20 on the {…}","placement":"unplaced","state":"inside-disputes"},
|
|
2767
2767
|
{"key":"L0166","section":"{…} reports","text":"aug","placement":"unplaced","state":"inside-disputes"},
|
|
2768
2768
|
{"key":"L0167","section":"{…} reports","text":"jun","placement":"unplaced","state":"inside-disputes"},
|
|
2769
|
-
{"key":"L0168","section":"{…} reports","text":"confirmed","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":
|
|
2769
|
+
{"key":"L0168","section":"{…} reports","text":"confirmed","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":465,"string_id":"d427d9dab01c","state":"inside-disputes"},
|
|
2770
2770
|
{"key":"L0169","section":"{…} reports","text":"{…} you","placement":"unplaced","state":"inside-disputes","occurrences":3},
|
|
2771
2771
|
{"key":"L0170","section":"{…} reports","text":"Builders hall · this session","placement":"placed","file":"modules/hall-ui/public/craft-mode.js","line":746,"string_id":"fd1903586e8e","state":"inside-disputes"},
|
|
2772
2772
|
{"key":"L0171","section":"{…}","text":"the law book","placement":"unplaced","state":"inside-rules"},
|
|
@@ -2931,7 +2931,7 @@
|
|
|
2931
2931
|
"surface": "builders",
|
|
2932
2932
|
"title": "Studio",
|
|
2933
2933
|
"states_read": ["home","out","flow","flow-pick","status","words-offer","words-edit","reviews","full","full-back","approvals","approvals-before","approvals-phone","approvals-note","approved","sent-back","approvals-page"],
|
|
2934
|
-
"files_hash": "
|
|
2934
|
+
"files_hash": "3378703eddb55c9f",
|
|
2935
2935
|
"reading_hash": "c4e3b4188c1db755",
|
|
2936
2936
|
"counts": {"lines":51,"placed":29,"shared":7,"unplaced":15},
|
|
2937
2937
|
"omitted": {"data":23},
|
|
@@ -2995,7 +2995,7 @@
|
|
|
2995
2995
|
"surface": "builders",
|
|
2996
2996
|
"title": "Task",
|
|
2997
2997
|
"states_read": ["record","from-goal","missing"],
|
|
2998
|
-
"files_hash": "
|
|
2998
|
+
"files_hash": "ddaf83cea69ef7e7",
|
|
2999
2999
|
"reading_hash": "8dd803b6934e6388",
|
|
3000
3000
|
"counts": {"lines":151,"placed":46,"shared":9,"unplaced":96},
|
|
3001
3001
|
"omitted": {"data":111},
|
|
@@ -3159,7 +3159,7 @@
|
|
|
3159
3159
|
"surface": "builders",
|
|
3160
3160
|
"title": "Your thinking",
|
|
3161
3161
|
"states_read": ["tour","sky","list","simple","full-idea","full","full-list","full-back","out"],
|
|
3162
|
-
"files_hash": "
|
|
3162
|
+
"files_hash": "63660aafe0fd02da",
|
|
3163
3163
|
"reading_hash": "b73f848b46b0f9b8",
|
|
3164
3164
|
"counts": {"lines":50,"placed":25,"shared":6,"unplaced":19},
|
|
3165
3165
|
"omitted": {"data":10},
|
|
@@ -3222,7 +3222,7 @@
|
|
|
3222
3222
|
"surface": "builders",
|
|
3223
3223
|
"title": "Tweak a page",
|
|
3224
3224
|
"states_read": ["doc","typed","chrome","submitted","picking","out"],
|
|
3225
|
-
"files_hash": "
|
|
3225
|
+
"files_hash": "e1bf8da355d6cfb7",
|
|
3226
3226
|
"reading_hash": "f521f8d9a7147557",
|
|
3227
3227
|
"counts": {"lines":26,"placed":18,"shared":2,"unplaced":6},
|
|
3228
3228
|
"omitted": {"data":19},
|
|
@@ -3261,7 +3261,7 @@
|
|
|
3261
3261
|
"surface": "builders",
|
|
3262
3262
|
"title": "Watch",
|
|
3263
3263
|
"states_read": ["board","out","operations","security","sessions","autobongos"],
|
|
3264
|
-
"files_hash": "
|
|
3264
|
+
"files_hash": "293ae9537963df09",
|
|
3265
3265
|
"reading_hash": "1961a0c06b9d8477",
|
|
3266
3266
|
"counts": {"lines":72,"placed":33,"shared":7,"unplaced":32},
|
|
3267
3267
|
"omitted": {"data":52},
|
|
@@ -3346,7 +3346,7 @@
|
|
|
3346
3346
|
"surface": "builders",
|
|
3347
3347
|
"title": "Tasks",
|
|
3348
3348
|
"states_read": ["ready","in-progress","backlog","completed","filters-open","out","founding"],
|
|
3349
|
-
"files_hash": "
|
|
3349
|
+
"files_hash": "8fee1f62e3f188bc",
|
|
3350
3350
|
"reading_hash": "e9b412d1ec59ceee",
|
|
3351
3351
|
"counts": {"lines":122,"placed":49,"shared":7,"unplaced":66},
|
|
3352
3352
|
"omitted": {"data":323},
|
|
@@ -3405,7 +3405,7 @@
|
|
|
3405
3405
|
{"key":"L0051","section":"page top","text":"{…} (high → low)","placement":"unplaced"},
|
|
3406
3406
|
{"key":"L0052","section":"page top","text":"minutes (low → high)","placement":"unplaced"},
|
|
3407
3407
|
{"key":"L0053","section":"page top","text":"priority (P0 first)","placement":"unplaced"},
|
|
3408
|
-
{"key":"L0054","section":"page top","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":
|
|
3408
|
+
{"key":"L0054","section":"page top","text":"task {…}","placement":"placed","file":"modules/hall-ui/public/hall-render.js","line":460,"string_id":"4d8ee7d68974"},
|
|
3409
3409
|
{"key":"L0055","section":"page top","text":"stalest first (untouched longest)","placement":"unplaced"},
|
|
3410
3410
|
{"key":"L0056","section":"page top","text":"Version","placement":"unplaced"},
|
|
3411
3411
|
{"key":"L0057","section":"page top","text":"— any —","placement":"unplaced","occurrences":2},
|
|
@@ -416,32 +416,8 @@
|
|
|
416
416
|
canTriage = ['metic', 'archon'].includes(normalizeRank(me.builder?.rank));
|
|
417
417
|
loadTriageInbox();
|
|
418
418
|
|
|
419
|
-
//
|
|
420
|
-
//
|
|
421
|
-
// #726: the per-skill model picker (Voices) moved to /builders/settings,
|
|
422
|
-
// so the hall no longer fetches /me/skill-prefs here.
|
|
423
|
-
const [ships, lb] = await Promise.allSettled([
|
|
424
|
-
// task 1004854: Home's newest few + a count — never the whole history
|
|
425
|
-
// (the Profile page's Works ledger reads that, since task 1005050).
|
|
426
|
-
getJSON(`${API}/me/recent-ships?limit=${HOME_SHIPS_LIMIT}`),
|
|
427
|
-
getJSON(`${API}/public/leaderboard`), // task 1004437: the list with each builder's roles
|
|
428
|
-
]);
|
|
429
|
-
|
|
430
|
-
// Only the Standing chip's shipped count reads this; a failure leaves its dash.
|
|
431
|
-
if (ships.status === 'fulfilled') setRecentShips(ships.value);
|
|
432
|
-
|
|
433
|
-
if (lb.status === 'fulfilled') {
|
|
434
|
-
lbState.rows = lb.value.leaderboard || [];
|
|
435
|
-
// #757: the Standing card painted before the Roll loaded, so re-render it
|
|
436
|
-
// now that lbState.rows exists — this is when its "#N on the Roll" stat
|
|
437
|
-
// can resolve.
|
|
438
|
-
if (lastMeState && lastMeState.builder) renderProfile(lastMeState.builder);
|
|
439
|
-
} else {
|
|
440
|
-
// The Roll’s rows only feed the Standing card’s "#N" stat now — the table
|
|
441
|
-
// itself is /roster (task 1003441) — so a failed fetch degrades that one
|
|
442
|
-
// stat rather than blanking a panel this page no longer has.
|
|
443
|
-
lbState.rows = [];
|
|
444
|
-
}
|
|
419
|
+
// The Standing chip's shipped count and leaderboard place (Home's last two
|
|
420
|
+
// fetches here) went with the chip in task 1005249; the Profile page has both.
|
|
445
421
|
}
|
|
446
422
|
|
|
447
423
|
function wireEvents() {
|
|
@@ -549,7 +525,7 @@
|
|
|
549
525
|
// reads what this page holds NOW rather than what it held at boot. Everything
|
|
550
526
|
// else is stable for the life of the page. This call sits AFTER every
|
|
551
527
|
// declaration it passes — moving it earlier is a temporal-dead-zone crash.
|
|
552
|
-
const {
|
|
528
|
+
const { mountHallWidgets, renderGreeting, renderLanding, renderSessionRefused, renderNav, renderProfile } = window.OTBHallRender({
|
|
553
529
|
API, RANK_ORDER, api, brandWorld, curLabel, normalizeRank, postJSON, rankLabel, rankWeight, toast,
|
|
554
530
|
get lastCostState() { return lastCostState; },
|
|
555
531
|
get lastKarmaState() { return lastKarmaState; },
|
|
@@ -413,20 +413,14 @@
|
|
|
413
413
|
});
|
|
414
414
|
}
|
|
415
415
|
// renderProfile(builder) — the Home surfaces fed by the /me payload: the
|
|
416
|
-
//
|
|
417
|
-
//
|
|
418
|
-
// your
|
|
416
|
+
// welcome line and the system notices. The Standing chip that sat top right
|
|
417
|
+
// went in task 1005249: in game mode the visor's own you-block shows your
|
|
418
|
+
// details on hover and opens your profile (visor.js); the Profile page has
|
|
419
|
+
// the rest.
|
|
419
420
|
function renderProfile(builder) {
|
|
420
421
|
const cost = ctx.lastCostState;
|
|
421
422
|
const needs = ctx.lastNeedsState;
|
|
422
423
|
const rebase = ctx.lastRebaseState;
|
|
423
|
-
const prefs = Array.isArray(builder.preferred_disciplines) ? builder.preferred_disciplines : [];
|
|
424
|
-
|
|
425
|
-
// #757: this builder's place on the Roll. Null until the leaderboard rows
|
|
426
|
-
// load (they're fetched async after the card's first paint; the card
|
|
427
|
-
// re-renders once they arrive) — when null the stat simply omits.
|
|
428
|
-
const rollPlace = leaderboardPlace(builder.github_login);
|
|
429
|
-
const karmaTotal = Number(builder.karma) || 0;
|
|
430
424
|
|
|
431
425
|
// The highest-priority `needs` item that isn't satisfied (ADR 0073); Home's
|
|
432
426
|
// attention cards carry it (renderSystemNotices, below).
|
|
@@ -448,64 +442,9 @@
|
|
|
448
442
|
welcomeLine.textContent = `Welcome back, ${builder.display_name || builder.github_login || 'builder'}.`;
|
|
449
443
|
}
|
|
450
444
|
|
|
451
|
-
// task 1723: the Home dashboard mirrors — quick-stat tiles + the standing
|
|
452
|
-
// summary card — are fed from the same /me payload. All writes are guarded:
|
|
453
|
-
// the widgets are registry-owned and a module could unregister them.
|
|
454
|
-
const setText = (id, text) => {
|
|
455
|
-
const el = document.getElementById(id);
|
|
456
|
-
if (el) el.textContent = text;
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
// task 1003464: the Home card as the mock draws it — an identity LINE and a
|
|
460
|
-
// three-row fact ledger. The mock repeats Credits and the place even though
|
|
461
|
-
// the stat band above carries both; the card is built as approved, all three
|
|
462
|
-
// rows, because that content is also what makes it end level with Goals.
|
|
463
|
-
// The notices that used to stack in here are inbox lines now.
|
|
464
|
-
const homeStanding = document.getElementById('home-standing-body');
|
|
465
|
-
if (homeStanding) {
|
|
466
|
-
const place = rollPlace ? `${ordinal(rollPlace.place)} of ${fmtNum(rollPlace.total)}` : '—';
|
|
467
|
-
homeStanding.innerHTML = `
|
|
468
|
-
<div class="home-who">
|
|
469
|
-
${builder.avatar_url
|
|
470
|
-
? `<img class="home-who__avatar" src="${escapeHtml(builder.avatar_url)}" alt="">`
|
|
471
|
-
: '<span class="home-who__avatar" aria-hidden="true"></span>'}
|
|
472
|
-
<div class="home-who__meta">
|
|
473
|
-
<p class="home-who__name">${escapeHtml(builder.display_name || builder.github_login || 'Builder')}</p>
|
|
474
|
-
<p class="home-who__handle">@${escapeHtml(builder.github_login || 'unknown')}</p>
|
|
475
|
-
</div>
|
|
476
|
-
<span class="home-who__rank">${builder.rank ? renderRankBadge(normalizeRank(builder.rank), { tip: false }) : ''}</span>
|
|
477
|
-
</div>
|
|
478
|
-
<div class="hall-standing__more">
|
|
479
|
-
<dl class="home-facts home-facts--grid">
|
|
480
|
-
<div><dt>${escapeHtml(curLabel(true))}</dt><dd>${fmtNum(builder.total_credits)}</dd></div>
|
|
481
|
-
<div><dt>Karma</dt><dd>${fmtNum(karmaTotal)}</dd></div>
|
|
482
|
-
<div><dt>Shipped</dt><dd id="standing-shipped">${shipState.seen ? fmtNum(shipState.total) : '—'}</dd></div>
|
|
483
|
-
<div><dt>Leaderboard place</dt><dd>${place}${rolePlaceText(rollPlace) ? `<span title="Your place among the ${rollPlace.role.total} builders shown as ${ROLE_AS[rollPlace.role.craft]}, ranked by the ${curLabel()} that role earned."> · ${rolePlaceText(rollPlace)}</span>` : ''}</dd></div>
|
|
484
|
-
</dl>
|
|
485
|
-
<dl class="home-facts">
|
|
486
|
-
<div><dt>Preferred work</dt><dd>${prefs.length ? escapeHtml(prefs.join(', ')) : PREFS_EMPTY}</dd></div>
|
|
487
|
-
</dl>
|
|
488
|
-
${builder.id != null ? `<p class="card-foot"><a href="/profile?id=${encodeURIComponent(builder.id)}">View full profile →</a></p>` : ''}
|
|
489
|
-
</div>
|
|
490
|
-
`;
|
|
491
|
-
}
|
|
492
|
-
// task 1004774: Standing is the page-head chip now, not a Home card. The
|
|
493
|
-
// who-line above IS the chip: at rest it shows the avatar and rank, and on
|
|
494
|
-
// hover it widens left to show the name while .hall-standing__more drops down.
|
|
495
|
-
const standingChip = document.getElementById('hall-standing');
|
|
496
|
-
if (standingChip && !ctx.newcomerGated) standingChip.hidden = false;
|
|
497
445
|
renderSystemNotices({ rebaseTasks, need, actionNeeds, cost });
|
|
498
446
|
}
|
|
499
447
|
|
|
500
|
-
// The ONE string for "no preferred work chosen" — the mock's copy.
|
|
501
|
-
const PREFS_EMPTY = 'Not set yet';
|
|
502
|
-
|
|
503
|
-
const ordinal = (n) => {
|
|
504
|
-
const v = Number(n) || 0;
|
|
505
|
-
const s = (v % 100 >= 11 && v % 100 <= 13) ? 'th' : ({ 1: 'st', 2: 'nd', 3: 'rd' }[v % 10] || 'th');
|
|
506
|
-
return `${v}${s}`;
|
|
507
|
-
};
|
|
508
|
-
|
|
509
448
|
// task 1003464: the three system notices as inbox LINES on Home (the
|
|
510
449
|
// placement rule in modules/hall-ui/CLAUDE.md: an action awaiting the builder
|
|
511
450
|
// is a line item in Needs-attention, never a card). Only what awaits the
|
|
@@ -568,59 +507,6 @@
|
|
|
568
507
|
h1.textContent = `${greetingWord(new Date().getHours())}, ${builder.display_name || builder.github_login || 'builder'}`;
|
|
569
508
|
}
|
|
570
509
|
}
|
|
571
|
-
|
|
572
|
-
// server's `total` — on every load AND every live refresh. The count rides the
|
|
573
|
-
// Standing chip's card. The whole ledger was Accomplishments', which folded into
|
|
574
|
-
// the Profile page in task 1005050 (its Works ledger reads its own record).
|
|
575
|
-
const HOME_SHIPS_LIMIT = 5;
|
|
576
|
-
const shipState = { recent: [], total: 0, seen: false };
|
|
577
|
-
function setRecentShips(payload) {
|
|
578
|
-
shipState.recent = (payload && payload.ships) || [];
|
|
579
|
-
shipState.total = Number.isFinite(payload && payload.total) ? payload.total : shipState.recent.length;
|
|
580
|
-
shipState.seen = true;
|
|
581
|
-
renderRecentShips();
|
|
582
|
-
}
|
|
583
|
-
function renderRecentShips() {
|
|
584
|
-
// task 1004774: the Standing hover card carries the shipped count.
|
|
585
|
-
const standingShipped = document.getElementById('standing-shipped');
|
|
586
|
-
if (standingShipped) standingShipped.textContent = fmtNum(shipState.total);
|
|
587
|
-
}
|
|
588
|
-
// The Roll’s rows, kept ONLY for leaderboardPlace() below — the Standing
|
|
589
|
-
// card’s "#N on the leaderboard" stat. sortBy/sortDir went to /roster with
|
|
590
|
-
// the table (task 1003441); nothing on this page sorts them any more.
|
|
591
|
-
const lbState = { rows: [] };
|
|
592
|
-
function leaderboardPlace(login) {
|
|
593
|
-
const rows = Array.isArray(lbState.rows) ? lbState.rows : [];
|
|
594
|
-
if (!rows.length || !login) return null;
|
|
595
|
-
const ranked = [...rows].sort(
|
|
596
|
-
(a, b) => (Number(b.total_credits) || 0) - (Number(a.total_credits) || 0),
|
|
597
|
-
);
|
|
598
|
-
const idx = ranked.findIndex((r) => r.github_login === login);
|
|
599
|
-
if (idx === -1) return null;
|
|
600
|
-
// task 1004437: the place inside the builder's MAIN role too, the roster's
|
|
601
|
-
// role toggle read the same way (credits earned in that craft, among the
|
|
602
|
-
// builders it is shown for), so an artist's card can say where they stand
|
|
603
|
-
// as an artist and not only beside every engineer's session pay.
|
|
604
|
-
const me = ranked[idx];
|
|
605
|
-
const main = me.roles && me.roles.main;
|
|
606
|
-
let role = null;
|
|
607
|
-
if (main && me.roles.credits_by_craft) {
|
|
608
|
-
const credit = (r) => Number(r.roles && r.roles.credits_by_craft && r.roles.credits_by_craft[main]) || 0;
|
|
609
|
-
const peers = ranked.filter((r) => r.roles && Array.isArray(r.roles.shown) && r.roles.shown.includes(main));
|
|
610
|
-
const order = peers.map((r, i) => ({ r, i })).sort((a, b) => (credit(b.r) - credit(a.r)) || (a.i - b.i));
|
|
611
|
-
const at = order.findIndex((x) => x.r === me);
|
|
612
|
-
if (at !== -1) role = { craft: main, place: at + 1, total: peers.length };
|
|
613
|
-
}
|
|
614
|
-
return { place: idx + 1, total: ranked.length, role };
|
|
615
|
-
}
|
|
616
|
-
const ROLE_AS = { artisan: 'an artisan', artist: 'an artist' };
|
|
617
|
-
// "#2 as an artist" — only when it says something the overall place does not.
|
|
618
|
-
function rolePlaceText(p) {
|
|
619
|
-
if (!p || !p.role || !ROLE_AS[p.role.craft] || p.role.place === p.place) return '';
|
|
620
|
-
return `#${p.role.place} as ${ROLE_AS[p.role.craft]}`;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return { lbState, mountHallWidgets, renderGreeting, renderLanding, renderSessionRefused, renderNav, renderProfile, renderRecentShips, HOME_SHIPS_LIMIT, setRecentShips, shipState };
|
|
510
|
+
return { mountHallWidgets, renderGreeting, renderLanding, renderSessionRefused, renderNav, renderProfile };
|
|
625
511
|
};
|
|
626
512
|
})();
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
// (task 1005054: the quick-stats strip and the version tab left Home. The
|
|
48
48
|
// zone they held, home-stats, is the project city's — home-city.js.)
|
|
49
49
|
|
|
50
|
-
// (task 1004774
|
|
51
|
-
//
|
|
52
|
-
//
|
|
50
|
+
// (task 1004774 moved the Standing summary off Home's cards into a chip at the
|
|
51
|
+
// top right of the page head; task 1005249 removed that chip. Your details
|
|
52
|
+
// are the visor's you-block on hover, and the Profile page.)
|
|
53
53
|
|
|
54
54
|
// (Goals — goals.js registers itself into the other half of the Home band.)
|
|
55
55
|
|
|
@@ -54,13 +54,6 @@
|
|
|
54
54
|
is the board's own (.page-head--board). -->
|
|
55
55
|
<div class="page-head page-head--board page-head--hall">
|
|
56
56
|
<h1 id="hall-h1" class="page-head__h">Builders' Hall</h1>
|
|
57
|
-
<!-- task 1004774: Standing left the Home band for this chip. At rest it
|
|
58
|
-
shows the avatar and rank. On hover or keyboard focus the chip itself
|
|
59
|
-
widens to the left into the top of the card, and only the facts below
|
|
60
|
-
drop down (#home-standing-body, filled by hall-render.js renderProfile). -->
|
|
61
|
-
<div class="hall-standing" id="hall-standing" hidden tabindex="0" aria-label="Your standing">
|
|
62
|
-
<div class="hall-standing__card" id="home-standing-body"></div>
|
|
63
|
-
</div>
|
|
64
57
|
</div>
|
|
65
58
|
|
|
66
59
|
<!-- BV1.R75 (ADR 0062 §4): hall widgets are NOT hardcoded here. Every widget
|