@tienne/gestalt 0.90.1 → 0.91.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/dist/package.json +1 -1
- package/dist/plugin/skills/architecture/SKILL.md +12 -1
- package/dist/src/architecture/compare-layout.d.ts.map +1 -1
- package/dist/src/architecture/compare-layout.js +1 -0
- package/dist/src/architecture/compare-layout.js.map +1 -1
- package/dist/src/architecture/dataflow-layout.d.ts.map +1 -1
- package/dist/src/architecture/dataflow-layout.js +1 -0
- package/dist/src/architecture/dataflow-layout.js.map +1 -1
- package/dist/src/architecture/drilldown.d.ts.map +1 -1
- package/dist/src/architecture/drilldown.js +1 -0
- package/dist/src/architecture/drilldown.js.map +1 -1
- package/dist/src/architecture/html-client.d.ts +5 -0
- package/dist/src/architecture/html-client.d.ts.map +1 -1
- package/dist/src/architecture/html-client.js +120 -12
- package/dist/src/architecture/html-client.js.map +1 -1
- package/dist/src/architecture/html-renderer.d.ts.map +1 -1
- package/dist/src/architecture/html-renderer.js +21 -7
- package/dist/src/architecture/html-renderer.js.map +1 -1
- package/dist/src/architecture/html-theme.d.ts.map +1 -1
- package/dist/src/architecture/html-theme.js +8 -1
- package/dist/src/architecture/html-theme.js.map +1 -1
- package/dist/src/architecture/kind-text.d.ts +10 -0
- package/dist/src/architecture/kind-text.d.ts.map +1 -1
- package/dist/src/architecture/kind-text.js +17 -0
- package/dist/src/architecture/kind-text.js.map +1 -1
- package/dist/src/architecture/layout.d.ts +5 -0
- package/dist/src/architecture/layout.d.ts.map +1 -1
- package/dist/src/architecture/layout.js +14 -3
- package/dist/src/architecture/layout.js.map +1 -1
- package/dist/src/architecture/packs/data.d.ts +14 -0
- package/dist/src/architecture/packs/data.d.ts.map +1 -1
- package/dist/src/architecture/packs/data.js +11 -7
- package/dist/src/architecture/packs/data.js.map +1 -1
- package/dist/src/architecture/packs/generic.d.ts +7 -0
- package/dist/src/architecture/packs/generic.d.ts.map +1 -1
- package/dist/src/architecture/packs/generic.js +13 -6
- package/dist/src/architecture/packs/generic.js.map +1 -1
- package/dist/src/architecture/packs/harness.d.ts +10 -0
- package/dist/src/architecture/packs/harness.d.ts.map +1 -1
- package/dist/src/architecture/packs/harness.js +18 -6
- package/dist/src/architecture/packs/harness.js.map +1 -1
- package/dist/src/architecture/packs/index.d.ts +110 -0
- package/dist/src/architecture/packs/index.d.ts.map +1 -1
- package/dist/src/architecture/packs/infra.d.ts +10 -0
- package/dist/src/architecture/packs/infra.d.ts.map +1 -1
- package/dist/src/architecture/packs/infra.js +9 -4
- package/dist/src/architecture/packs/infra.js.map +1 -1
- package/dist/src/architecture/packs/knowledge.d.ts +8 -0
- package/dist/src/architecture/packs/knowledge.d.ts.map +1 -1
- package/dist/src/architecture/packs/knowledge.js +8 -4
- package/dist/src/architecture/packs/knowledge.js.map +1 -1
- package/dist/src/architecture/packs/process.d.ts +10 -0
- package/dist/src/architecture/packs/process.d.ts.map +1 -1
- package/dist/src/architecture/packs/process.js +14 -5
- package/dist/src/architecture/packs/process.js.map +1 -1
- package/dist/src/architecture/packs/types.d.ts +6 -0
- package/dist/src/architecture/packs/types.d.ts.map +1 -1
- package/dist/src/architecture/packs/web-product.d.ts +51 -0
- package/dist/src/architecture/packs/web-product.d.ts.map +1 -1
- package/dist/src/architecture/packs/web-product.js +94 -33
- package/dist/src/architecture/packs/web-product.js.map +1 -1
- package/dist/src/architecture/sequence-layout.d.ts.map +1 -1
- package/dist/src/architecture/sequence-layout.js +1 -0
- package/dist/src/architecture/sequence-layout.js.map +1 -1
- package/dist/src/architecture/types.d.ts +2 -0
- package/dist/src/architecture/types.d.ts.map +1 -1
- package/dist/src/architecture/types.js +4 -0
- package/dist/src/architecture/types.js.map +1 -1
- package/dist/src/architecture/validator.d.ts +7 -0
- package/dist/src/architecture/validator.d.ts.map +1 -1
- package/dist/src/architecture/validator.js +18 -1
- package/dist/src/architecture/validator.js.map +1 -1
- package/dist/src/mcp/tools/architecture-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/architecture-passthrough.js +3 -1
- package/dist/src/mcp/tools/architecture-passthrough.js.map +1 -1
- package/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- package/plugin/mcp.json +1 -1
- package/plugin/skills/architecture/SKILL.md +12 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BAND_LINE_X, BAND_LINE_Y, BAND_TITLE_HALF, BAND_TITLE_X } from './canvas-geometry.js';
|
|
2
2
|
import { FOCUS_SOURCE } from './focus.js';
|
|
3
3
|
import { PRODUCT_COLORS } from './html-theme.js';
|
|
4
|
-
import { FRAME_PAD } from './layout.js';
|
|
4
|
+
import { FRAME_PAD, NODE_DESC_LINE } from './layout.js';
|
|
5
5
|
// component는 칩 글자를 노드의 displayKind에서, 색과 아이콘은 renderClass에서 가져온다. types.ts의 displayKindOf, chipTextOverride와 같은 규칙이다.
|
|
6
6
|
// 이 조각은 component를 쓸 수 있는 어휘에만 싣는다. 늘 실으면 component가 없는 그림의 바이트까지 바뀐다
|
|
7
7
|
const COMPONENT_DKIND = "n.kind === 'component' ? 'cx_' + (n.renderClass || 'service') : ";
|
|
@@ -226,8 +226,12 @@ export function renderClientScript(c) {
|
|
|
226
226
|
var MICRO_HOSTS = {};
|
|
227
227
|
(data.microHosts || []).forEach(function (id) { MICRO_HOSTS[id] = true; });
|
|
228
228
|
var KIND_TEXT = ${JSON.stringify(c.kindText)};
|
|
229
|
+
var KIND_ABOUT = ${JSON.stringify(c.kindAbout)};
|
|
229
230
|
var EVIDENCE_TEXT = ${JSON.stringify(c.evidenceText)};
|
|
230
231
|
var LANE_TITLE = ${JSON.stringify(c.laneTitles)};
|
|
232
|
+
var LANE_ABOUT = ${JSON.stringify(c.laneAbout)};
|
|
233
|
+
var STAGE_LANE_ABOUT = ${JSON.stringify(c.stageLaneAbout)};
|
|
234
|
+
var NODE_DESC_LINE = ${NODE_DESC_LINE};
|
|
231
235
|
var GUESS = ${JSON.stringify(c.inferredBadge)};
|
|
232
236
|
var PLATFORM_CHIP = ${JSON.stringify(c.platformChip)};
|
|
233
237
|
var PLATFORM_NAME = ${JSON.stringify(c.platformName)};
|
|
@@ -526,6 +530,86 @@ ${FOCUS_SOURCE}
|
|
|
526
530
|
panel.appendChild(body);
|
|
527
531
|
openDrawer();
|
|
528
532
|
}
|
|
533
|
+
// 환경 필터로 숨긴 카드는 화면에 없으니 목록에서도 뺀다
|
|
534
|
+
function connectionList(body, id, incoming) {
|
|
535
|
+
var list = data.edges.filter(function (e) {
|
|
536
|
+
var other = incoming ? e.from : e.to;
|
|
537
|
+
return (incoming ? e.to : e.from) === id && other !== id && !envHidden(other);
|
|
538
|
+
});
|
|
539
|
+
if (!list.length) return;
|
|
540
|
+
body.appendChild(el('h3', null, (incoming ? '들어오는 연결 ' : '나가는 연결 ') + list.length + '개'));
|
|
541
|
+
var otherOf = {};
|
|
542
|
+
list.forEach(function (e) { otherOf[e.id] = incoming ? e.from : e.to; });
|
|
543
|
+
refButtons(body, list.map(function (e) { return e.id; }), function (eid) { goToNode(otherOf[eid]); },
|
|
544
|
+
function (eid) { return 'i-' + dkind(nodes[otherOf[eid]]); },
|
|
545
|
+
function (eid) { return label(otherOf[eid]) + ' (' + kindText(edges[eid].kind) + ')'; });
|
|
546
|
+
}
|
|
547
|
+
// 선은 레벨 엣지에서 먼저 찾는다. 포함 선은 드릴다운이 만든 것이라 IR 엣지 표에 없다
|
|
548
|
+
function edgeOf(id) {
|
|
549
|
+
var level = levels[levelIdOf(active)];
|
|
550
|
+
return (level && level.edgeById[id]) || edges[id] || null;
|
|
551
|
+
}
|
|
552
|
+
function renderEdgePanel(g) {
|
|
553
|
+
var id = g.getAttribute('data-link-id');
|
|
554
|
+
var e = edgeOf(id);
|
|
555
|
+
if (!e) return;
|
|
556
|
+
var ir = edges[id];
|
|
557
|
+
active.querySelectorAll('.node.selected').forEach(function (x) { x.classList.remove('selected'); });
|
|
558
|
+
lightLink(active, g);
|
|
559
|
+
returnFocus = g;
|
|
560
|
+
selectedId = null;
|
|
561
|
+
syncFocusBtn();
|
|
562
|
+
panel.textContent = '';
|
|
563
|
+
panel.appendChild(panelHead('flow', 'u-link', kindText(e.kind), '', label(e.from) + ' → ' + label(e.to)));
|
|
564
|
+
var body = el('div', 'dr-body');
|
|
565
|
+
if (KIND_ABOUT[e.kind]) body.appendChild(el('p', 'desc', KIND_ABOUT[e.kind]));
|
|
566
|
+
var facts = el('ul', 'facts');
|
|
567
|
+
if (e.kind !== 'contains') factRow(facts, '선', e.lineStyle === 'dashed' ? '점선 (문서나 사람 말로만 확인)' : '실선 (코드나 스펙으로 확인)');
|
|
568
|
+
if (g.classList.contains('x-account')) factRow(facts, '계정', '계정을 넘는 연결이에요');
|
|
569
|
+
if (ir && ir.actions && ir.actions.length) factRow(facts, 'action', ir.actions.join(', '));
|
|
570
|
+
if (facts.childNodes.length) body.appendChild(facts);
|
|
571
|
+
body.appendChild(el('h3', null, '양 끝'));
|
|
572
|
+
refButtons(body, [e.from, e.to], goToNode, function (nid) { return 'i-' + dkind(nodes[nid]); }, label);
|
|
573
|
+
if (ir) evidenceList(body, ir.evidence);
|
|
574
|
+
else body.appendChild(el('p', 'desc', 'parent로 정한 포함 관계라 따로 근거가 없어요.'));
|
|
575
|
+
panel.appendChild(body);
|
|
576
|
+
openDrawer();
|
|
577
|
+
}
|
|
578
|
+
// 레인 제목과 rect.lane은 같은 순서로 그려진다. 포커스 화면과 환경 필터가 같은 짝짓기를 쓴다
|
|
579
|
+
function laneCards(t) {
|
|
580
|
+
var sec = t.parentNode;
|
|
581
|
+
var titles = Array.prototype.slice.call(sec.querySelectorAll('.lane-title'));
|
|
582
|
+
var r = sec.querySelectorAll('rect.lane')[titles.indexOf(t)];
|
|
583
|
+
if (!r) return [];
|
|
584
|
+
var x = parseFloat(r.getAttribute('x'));
|
|
585
|
+
var w = parseFloat(r.getAttribute('width'));
|
|
586
|
+
var ids = [];
|
|
587
|
+
sec.querySelectorAll('.node').forEach(function (c) {
|
|
588
|
+
var left = parseFloat(c.style.left);
|
|
589
|
+
if (left >= x && left < x + w && !c.classList.contains('env-off')) ids.push(c.getAttribute('data-node-id'));
|
|
590
|
+
});
|
|
591
|
+
return ids;
|
|
592
|
+
}
|
|
593
|
+
function laneAria(title, count) { return title + ' 레인, 카드 ' + count + '개'; }
|
|
594
|
+
function renderLanePanel(t) {
|
|
595
|
+
var laneId = t.getAttribute('data-lane-id') || '';
|
|
596
|
+
var title = t.firstChild ? t.firstChild.textContent : '';
|
|
597
|
+
var ids = laneCards(t);
|
|
598
|
+
active.querySelectorAll('.node.selected').forEach(function (x) { x.classList.remove('selected'); });
|
|
599
|
+
clearLit(active);
|
|
600
|
+
returnFocus = t;
|
|
601
|
+
selectedId = null;
|
|
602
|
+
syncFocusBtn();
|
|
603
|
+
panel.textContent = '';
|
|
604
|
+
panel.appendChild(panelHead('flow', 'u-legend', '레인', '', title));
|
|
605
|
+
var body = el('div', 'dr-body');
|
|
606
|
+
var about = laneId.indexOf('stage:') === 0 ? STAGE_LANE_ABOUT : LANE_ABOUT[laneId];
|
|
607
|
+
if (about) body.appendChild(el('p', 'desc', about));
|
|
608
|
+
body.appendChild(el('h3', null, '이 칸의 카드 ' + ids.length + '개'));
|
|
609
|
+
if (ids.length) refButtons(body, ids, focusCard, function (nid) { return 'i-' + dkind(nodes[nid]); }, label);
|
|
610
|
+
panel.appendChild(body);
|
|
611
|
+
openDrawer();
|
|
612
|
+
}
|
|
529
613
|
function renderPanel(id) {
|
|
530
614
|
if (isStep(id)) { renderStepPanel(id); return; }
|
|
531
615
|
var n = nodes[id];
|
|
@@ -573,6 +657,11 @@ ${FOCUS_SOURCE}
|
|
|
573
657
|
body.appendChild(actions);
|
|
574
658
|
}
|
|
575
659
|
if (n.description) body.appendChild(el('p', 'desc', n.description));
|
|
660
|
+
var about = KIND_ABOUT[dkind(n)];
|
|
661
|
+
if (about) {
|
|
662
|
+
body.appendChild(el('h3', null, '이 종류는'));
|
|
663
|
+
body.appendChild(el('p', 'desc', about));
|
|
664
|
+
}
|
|
576
665
|
renderFacts(n, body);${c.docs ? '\n renderDoc(n, body);' : ''}
|
|
577
666
|
if (flowsBySvc[id]) {
|
|
578
667
|
body.appendChild(el('h3', null, '흐름 ' + flowsBySvc[id].length + '개'));
|
|
@@ -582,6 +671,8 @@ ${FOCUS_SOURCE}
|
|
|
582
671
|
body.appendChild(el('h3', null, '이 항목이 나오는 흐름 단계 ' + stepsByRef[id].length + '개'));
|
|
583
672
|
refButtons(body, stepsByRef[id], goToNode, function () { return 'u-flow'; }, function (sid) { return stepFlow[sid].title + ' › ' + label(sid); });
|
|
584
673
|
}
|
|
674
|
+
connectionList(body, id, true);
|
|
675
|
+
connectionList(body, id, false);
|
|
585
676
|
body.appendChild(el('h3', null, '출처 ' + n.evidence.length + '개'));
|
|
586
677
|
var ul = el('ul', 'evidence');
|
|
587
678
|
n.evidence.forEach(function (ev) { ul.appendChild(renderEvidence(ev)); });
|
|
@@ -873,6 +964,10 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
873
964
|
if (link) { activateBundle(link); return; }
|
|
874
965
|
var ft = e.target.closest('.link.flow-t');
|
|
875
966
|
if (ft) { activateTransition(ft); return; }
|
|
967
|
+
var edge = e.target.closest('.link[data-link-id]');
|
|
968
|
+
if (edge) { renderEdgePanel(edge); return; }
|
|
969
|
+
var lane = e.target.closest('.lane-title[data-lane-id]');
|
|
970
|
+
if (lane) { renderLanePanel(lane); return; }
|
|
876
971
|
if (drawerOpen()) closeDrawer(false);
|
|
877
972
|
});
|
|
878
973
|
stage.addEventListener('dblclick', function (e) {
|
|
@@ -889,7 +984,11 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
889
984
|
var link = e.target.closest('.link.bundle');
|
|
890
985
|
if (link) { e.preventDefault(); activateBundle(link); return; }
|
|
891
986
|
var ft = e.target.closest('.link.flow-t');
|
|
892
|
-
if (ft) { e.preventDefault(); activateTransition(ft); }
|
|
987
|
+
if (ft) { e.preventDefault(); activateTransition(ft); return; }
|
|
988
|
+
var edge = e.target.closest('.link[data-link-id]');
|
|
989
|
+
if (edge) { e.preventDefault(); renderEdgePanel(edge); return; }
|
|
990
|
+
var lane = e.target.closest('.lane-title[data-lane-id]');
|
|
991
|
+
if (lane) { e.preventDefault(); renderLanePanel(lane); }
|
|
893
992
|
});
|
|
894
993
|
|
|
895
994
|
// 위치 표시
|
|
@@ -1094,9 +1193,12 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
1094
1193
|
if (c < 800) return 'db_table';
|
|
1095
1194
|
return '';
|
|
1096
1195
|
}
|
|
1196
|
+
// types.ts의 hasCardDescription, layout.ts의 measureNode와 같은 판정이다
|
|
1197
|
+
function hasDesc(n) { return !!(n && n.description && n.description.trim()); }
|
|
1097
1198
|
function cardHeight(id) {
|
|
1098
1199
|
var f = services[id];
|
|
1099
|
-
|
|
1200
|
+
var base = (nodes[id] && nodes[id].displayName) || (f && (f.prodDomain || f.platforms.length > 0)) ? 60 : 48;
|
|
1201
|
+
return base + (hasDesc(nodes[id]) ? NODE_DESC_LINE : 0);
|
|
1100
1202
|
}
|
|
1101
1203
|
function platformChips(id, parent) {
|
|
1102
1204
|
var f = services[id];
|
|
@@ -1141,7 +1243,8 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
1141
1243
|
platformChips(id, l2);
|
|
1142
1244
|
d.appendChild(l2);
|
|
1143
1245
|
} else if (sub) d.appendChild(sub);
|
|
1144
|
-
|
|
1246
|
+
if (hasDesc(n)) d.appendChild(el('span', 'ds', n.description));
|
|
1247
|
+
d.title = (n && n.displayName ? n.displayName + (guess ? ' (' + GUESS + ')' : '') + '\\n' + n.label : label(id)) + (hasDesc(n) ? '\\n' + n.description : '');
|
|
1145
1248
|
d.setAttribute('aria-label', label(id) + ', ' + kindText(kind));
|
|
1146
1249
|
if (enterMap[id]) {
|
|
1147
1250
|
var more = el('span', 'go', '›');
|
|
@@ -1250,12 +1353,10 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
1250
1353
|
var xa = nodes[e.from] && nodes[e.to] && nodes[e.from].account && nodes[e.to].account && nodes[e.from].account !== nodes[e.to].account;
|
|
1251
1354
|
var g = svgEl('g', { 'class': (bundle ? 'link bundle' : 'link e-' + e.kind) + (xa ? ' x-account' : ''), 'data-from': e.from, 'data-to': e.to });
|
|
1252
1355
|
var name = bundle ? label(e.from) + ' → ' + label(e.to) + ' ' + e.count + '개'${c.mixedBundles ? MIXED_NOTE : ''} : kindText(e.kind) + ': ' + label(e.from) + ' → ' + label(e.to);
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
g.setAttribute('aria-label', name);
|
|
1258
|
-
}
|
|
1356
|
+
g.setAttribute(bundle ? 'data-bundle-id' : 'data-link-id', e.id);
|
|
1357
|
+
g.setAttribute('tabindex', '0');
|
|
1358
|
+
g.setAttribute('role', 'button');
|
|
1359
|
+
g.setAttribute('aria-label', name);
|
|
1259
1360
|
var t = svgEl('title', {});
|
|
1260
1361
|
t.textContent = name;
|
|
1261
1362
|
g.appendChild(t);
|
|
@@ -1283,6 +1384,12 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
1283
1384
|
if (!l.title) return;
|
|
1284
1385
|
var title = el('div', 'lane-title', l.title);
|
|
1285
1386
|
title.appendChild(el('span', 'n', String(l.count)));
|
|
1387
|
+
if (l.id) {
|
|
1388
|
+
title.setAttribute('data-lane-id', l.id);
|
|
1389
|
+
title.setAttribute('role', 'button');
|
|
1390
|
+
title.tabIndex = 0;
|
|
1391
|
+
title.setAttribute('aria-label', laneAria(l.title, l.count));
|
|
1392
|
+
}
|
|
1286
1393
|
title.style.left = l.x + 'px';
|
|
1287
1394
|
title.style.top = '22px';
|
|
1288
1395
|
title.style.width = l.width + 'px';
|
|
@@ -1348,7 +1455,7 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
1348
1455
|
pos: pos,
|
|
1349
1456
|
edges: list.map(function (e) { return { id: e.id, from: e.from, to: e.to, kind: e.kind, count: 1, lineStyle: e.lineStyle }; }),
|
|
1350
1457
|
lanes: lanes.map(function (l) {
|
|
1351
|
-
return { x: l.left - LANE_PAD, width: l.right - l.left + LANE_PAD * 2, title: LANE_TITLE[l.id] || '', count: l.count };
|
|
1458
|
+
return { x: l.left - LANE_PAD, width: l.right - l.left + LANE_PAD * 2, id: l.id, title: LANE_TITLE[l.id] || '', count: l.count };
|
|
1352
1459
|
}),
|
|
1353
1460
|
width: x + NODE_W + LANE_PAD + PAD_X,
|
|
1354
1461
|
height: PAD_TOP + maxH + PAD_BOTTOM,
|
|
@@ -1495,7 +1602,7 @@ ${c.views ? VIEW_FUNCS : ''}${c.docs ? DOC_FUNCS : ''} stage.addEventListener('
|
|
|
1495
1602
|
Object.keys(pos).forEach(function (id) { if (pos[id].x >= x && pos[id].x < x + w) n += 1; });
|
|
1496
1603
|
if (!n) return;
|
|
1497
1604
|
var t = titles[i];
|
|
1498
|
-
lanes.push({ x: x, width: w, title: t ? t.firstChild.textContent : '', count: n });
|
|
1605
|
+
lanes.push({ id: t ? t.getAttribute('data-lane-id') : null, x: x, width: w, title: t ? t.firstChild.textContent : '', count: n });
|
|
1499
1606
|
});
|
|
1500
1607
|
var cards = cardMap(src);
|
|
1501
1608
|
src.hidden = true;
|
|
@@ -1782,6 +1889,7 @@ ${c.views ? VIEW_POP : ''} // 흐름 단추는 서비스 아래 레벨에서만
|
|
|
1782
1889
|
t.classList.toggle('env-off', n === 0);
|
|
1783
1890
|
var count = t.querySelector('.n');
|
|
1784
1891
|
if (count) count.textContent = n;
|
|
1892
|
+
if (t.hasAttribute('data-lane-id')) t.setAttribute('aria-label', laneAria(t.firstChild.textContent, n));
|
|
1785
1893
|
});
|
|
1786
1894
|
}
|
|
1787
1895
|
// 고른 환경은 주소 해시 뒤 ?env=prod,dev로 싣는다. 주소를 보내면 받은 사람도 같은 환경으로 본다.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-client.js","sourceRoot":"","sources":["../../../src/architecture/html-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAe,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"html-client.js","sourceRoot":"","sources":["../../../src/architecture/html-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../../src/architecture/html-renderer.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../../src/architecture/html-renderer.ts"],"names":[],"mappings":"AAWA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA4BnG,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AAsBrB,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEpF,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AA+ED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAetD;AA2VD,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEjE;AAwmCD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,WAAW,EACtB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,6BAA6B,GAClC,MAAM,CAkBR;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,WAAW,EACtB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,6BAA6B,GAClC,MAAM,CAuIR"}
|
|
@@ -2,7 +2,7 @@ import { BAND_LINE_X, BAND_LINE_Y, BAND_TITLE_HALF, BAND_TITLE_X, CANVAS_PAD_TOP
|
|
|
2
2
|
import { flowCountByService, ROOT_LEVEL_ID } from './drilldown.js';
|
|
3
3
|
import { renderClientScript, THEME_BOOT_SCRIPT } from './html-client.js';
|
|
4
4
|
import { datastoreEngine, iconUse, PRODUCT_COLORS, renderCss, renderIconSprite, VIEW_CSS, DOC_CSS, } from './html-theme.js';
|
|
5
|
-
import { LANE_TITLES, flowBadgeText, MICRO_HOST_SHORT, NODE_KIND_SHORT, PLATFORM_CHIP_TEXT, PLATFORM_NAME, WEB_HOSTING_CHIP_TEXT, WEB_HOSTING_NAME, platformChipText, platformName, } from './kind-text.js';
|
|
5
|
+
import { EDGE_KIND_ABOUT, LANE_ABOUT, LANE_TITLES, NODE_KIND_ABOUT, STAGE_LANE_ABOUT, flowBadgeText, MICRO_HOST_SHORT, NODE_KIND_SHORT, PLATFORM_CHIP_TEXT, PLATFORM_NAME, WEB_HOSTING_CHIP_TEXT, WEB_HOSTING_NAME, platformChipText, platformName, } from './kind-text.js';
|
|
6
6
|
import { compareEnvironment, FLAT_BACKWARD_EDGE_KINDS, textUnits, } from './layout.js';
|
|
7
7
|
import { indexMicroApps } from './micro-app.js';
|
|
8
8
|
import { ALL_PACKS_VOCABULARY, irVocabulary } from './packs/index.js';
|
|
@@ -11,7 +11,7 @@ import { computeCompareLayout } from './compare-layout.js';
|
|
|
11
11
|
import { computeDataflowLayout } from './dataflow-layout.js';
|
|
12
12
|
import { computeSequenceLayout } from './sequence-layout.js';
|
|
13
13
|
import { computeServiceFacts } from './service-facts.js';
|
|
14
|
-
import { chipTextOverride, displayKindOf } from './types.js';
|
|
14
|
+
import { chipTextOverride, displayKindOf, hasCardDescription } from './types.js';
|
|
15
15
|
import { maskSharedText, redactForSharing } from './validator.js';
|
|
16
16
|
const DASHED_PATTERN = '6 4';
|
|
17
17
|
const INFERRED_BADGE = '추정';
|
|
@@ -60,8 +60,8 @@ const FLOW_TEXT = {
|
|
|
60
60
|
person: '사람',
|
|
61
61
|
system: '시스템',
|
|
62
62
|
};
|
|
63
|
-
const HINT_DRILL = '
|
|
64
|
-
const HINT_FLAT = '
|
|
63
|
+
const HINT_DRILL = '카드나 선, 칸 제목을 누르면 설명과 출처가 보여요. 더블클릭하거나 상세보기를 누르면 한 단계 안으로 들어가고 뒤로가기로 돌아와요. 전체 화면에서 Shift나 ⌘를 누른 채 두 항목을 고르면 그 사이 경로를 보여줘요.';
|
|
64
|
+
const HINT_FLAT = '카드나 선, 칸 제목을 누르면 설명과 출처가 보여요. 끌어서 옮기고 ⌘나 Ctrl을 누른 채 휠을 굴리면 크게 볼 수 있어요.';
|
|
65
65
|
function compareStr(a, b) {
|
|
66
66
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
67
67
|
}
|
|
@@ -260,9 +260,14 @@ function docCoverBadge(cover) {
|
|
|
260
260
|
: '') +
|
|
261
261
|
owner);
|
|
262
262
|
}
|
|
263
|
+
/** 레인 제목의 aria-label. 클라이언트가 환경 필터로 수를 바꿀 때도 같은 꼴로 다시 단다 */
|
|
264
|
+
function laneAria(title, count) {
|
|
265
|
+
return `${title} 레인, 카드 ${count}개`;
|
|
266
|
+
}
|
|
263
267
|
function renderCard(node, box, enterable, focus, facts, band, micro, flows = 0, products = [], productIds = [], cover, where) {
|
|
264
268
|
const name = nodeName(node);
|
|
265
269
|
const guess = isGuess(node);
|
|
270
|
+
const desc = hasCardDescription(node.description);
|
|
266
271
|
const platforms = facts?.platforms.map((p) => platformName(p, facts.webHosting)) ?? [];
|
|
267
272
|
const dk = displayKindOf(node);
|
|
268
273
|
const cls = ['node', `k-${dk}`];
|
|
@@ -279,7 +284,8 @@ function renderCard(node, box, enterable, focus, facts, band, micro, flows = 0,
|
|
|
279
284
|
const tooltip = (node.displayName === undefined
|
|
280
285
|
? node.label
|
|
281
286
|
: `${node.displayName}${guess ? ` (${INFERRED_BADGE})` : ''}\n${node.label}`) +
|
|
282
|
-
(facts?.prodDomain !== undefined ? `\n${facts.prodDomain}` : '')
|
|
287
|
+
(facts?.prodDomain !== undefined ? `\n${facts.prodDomain}` : '') +
|
|
288
|
+
(desc ? `\n${node.description}` : '');
|
|
283
289
|
const subText = where !== undefined
|
|
284
290
|
? `<span class="tc">${escapeHtml(where)}</span>`
|
|
285
291
|
: facts?.prodDomain !== undefined
|
|
@@ -307,6 +313,7 @@ function renderCard(node, box, enterable, focus, facts, band, micro, flows = 0,
|
|
|
307
313
|
docCoverBadge(cover) +
|
|
308
314
|
`</span>` +
|
|
309
315
|
second +
|
|
316
|
+
(desc ? `<span class="ds">${escapeHtml(node.description)}</span>` : '') +
|
|
310
317
|
(enterable ? '<span class="go" aria-hidden="true">›</span>' : '') +
|
|
311
318
|
(products.length > 1 ? renderProductBricks(products, productIds, box.width) : '') +
|
|
312
319
|
`</div>`);
|
|
@@ -372,7 +379,7 @@ function renderLink(edge, route, labelOf, crossAccount) {
|
|
|
372
379
|
`${renderPill(edge.count, route.mid, edge.inferred !== undefined)}</g>`);
|
|
373
380
|
}
|
|
374
381
|
const name = `${EDGE_KIND_TEXT[edge.kind]}: ${labelOf(edge.from)} → ${labelOf(edge.to)}${xaText}`;
|
|
375
|
-
return (`<g class="link e-${edge.kind}${xa}" ${ends}><title>${escapeHtml(name)}</title>${hit}` +
|
|
382
|
+
return (`<g class="link e-${edge.kind}${xa}" ${ends} data-link-id="${escapeHtml(edge.id)}" tabindex="0" role="button" aria-label="${escapeHtml(name)}"><title>${escapeHtml(name)}</title>${hit}` +
|
|
376
383
|
`<path class="edge" data-edge-id="${escapeHtml(edge.id)}" d="${route.d}" stroke-width="${width}"${dash}/>${tip}</g>`);
|
|
377
384
|
}
|
|
378
385
|
const VIEW_SHAPE_NAME = {
|
|
@@ -469,7 +476,8 @@ function renderLevelSection(spec) {
|
|
|
469
476
|
`height="${round2(height - LANE_INSET_Y * 2)}" rx="14"/>`)
|
|
470
477
|
.join('');
|
|
471
478
|
const laneTitles = layout.lanes
|
|
472
|
-
.map((l) => `<div class="lane-title"
|
|
479
|
+
.map((l) => `<div class="lane-title" data-lane-id="${escapeHtml(l.id)}" role="button" tabindex="0" aria-label="${escapeHtml(laneAria(l.title, l.count))}" ` +
|
|
480
|
+
`style="left:${round2(l.x + CANVAS_PAD_X)}px;top:${LANE_INSET_Y + 10}px;width:${l.width}px">` +
|
|
473
481
|
`${escapeHtml(l.title)}<span class="n">${l.count}</span></div>`)
|
|
474
482
|
.join('');
|
|
475
483
|
const { regionRects, regionTitles } = renderBands(layout, width);
|
|
@@ -1062,8 +1070,14 @@ function clientScriptFor(vocab, rootFlows, views, mixedBundles) {
|
|
|
1062
1070
|
...pick(NODE_KIND_TEXT, Object.keys(vocab.looks)),
|
|
1063
1071
|
...pick(EDGE_KIND_TEXT, [...Object.keys(vocab.edgeKinds), 'contains']),
|
|
1064
1072
|
},
|
|
1073
|
+
kindAbout: {
|
|
1074
|
+
...pick(NODE_KIND_ABOUT, Object.keys(vocab.looks)),
|
|
1075
|
+
...pick(EDGE_KIND_ABOUT, [...Object.keys(vocab.edgeKinds), 'contains']),
|
|
1076
|
+
},
|
|
1065
1077
|
evidenceText: EVIDENCE_TYPE_TEXT,
|
|
1066
1078
|
laneTitles: pick(LANE_TITLES, Object.keys(vocab.lanes)),
|
|
1079
|
+
laneAbout: pick(LANE_ABOUT, Object.keys(vocab.lanes)),
|
|
1080
|
+
stageLaneAbout: STAGE_LANE_ABOUT,
|
|
1067
1081
|
inferredBadge: INFERRED_BADGE,
|
|
1068
1082
|
platformChip: PLATFORM_CHIP_TEXT,
|
|
1069
1083
|
platformName: PLATFORM_NAME,
|