@mneme-ai/xray 2.179.0 → 2.181.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/index.d.ts CHANGED
@@ -16,7 +16,7 @@ export { xrayGauntlet, type XRayGauntlet } from "./gauntlet.js";
16
16
  export { isAllowedPublicUrl, isSafeBranch } from "./clone.js";
17
17
  export { listRemoteBranches, remoteRef, reportDelta, trackerTick, trackGauntlet, type RemoteBranch, type ReportDelta, type Drift, type TrackState, type TickResult } from "./track.js";
18
18
  export { TrackerHub, trackId, hubGauntlet, verifyWebhookSig, type SseSink, type BuildFn, type RefFn, type TrackRecord, type HistoryEntry } from "./tracker_server.js";
19
- export { buildRiskMap, riskMapGauntlet, MAP_W, MAP_H, MAP_CAP, type RiskMap, type RiskNode, type RiskEdge } from "./riskmap.js";
19
+ export { buildRiskMap, buildBlastRadius, riskMapGauntlet, MAP_W, MAP_H, MAP_CAP, type RiskMap, type RiskNode, type RiskEdge, type BlastTarget, type BlastPartner } from "./riskmap.js";
20
20
  export { defaultFetcher, type MetaFetcher } from "./battery/deps.js";
21
21
  export { publishReport, type PublishResult } from "./publish.js";
22
22
  export { createXRayServer } from "./server.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACvL,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACtK,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAChI,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACvL,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACtK,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACvL,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ export { xrayGauntlet } from "./gauntlet.js";
16
16
  export { isAllowedPublicUrl, isSafeBranch } from "./clone.js";
17
17
  export { listRemoteBranches, remoteRef, reportDelta, trackerTick, trackGauntlet } from "./track.js";
18
18
  export { TrackerHub, trackId, hubGauntlet, verifyWebhookSig } from "./tracker_server.js";
19
- export { buildRiskMap, riskMapGauntlet, MAP_W, MAP_H, MAP_CAP } from "./riskmap.js";
19
+ export { buildRiskMap, buildBlastRadius, riskMapGauntlet, MAP_W, MAP_H, MAP_CAP } from "./riskmap.js";
20
20
  export { defaultFetcher } from "./battery/deps.js";
21
21
  export { publishReport } from "./publish.js";
22
22
  export { createXRayServer } from "./server.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAqB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAoB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAqB,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAqF,MAAM,YAAY,CAAC;AACvL,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAA+E,MAAM,qBAAqB,CAAC;AACtK,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAA8C,MAAM,cAAc,CAAC;AAChI,OAAO,EAAE,cAAc,EAAoB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAkC,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAqB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAoB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAqB,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAqF,MAAM,YAAY,CAAC;AACvL,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAA+E,MAAM,qBAAqB,CAAC;AACtK,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAmF,MAAM,cAAc,CAAC;AACvL,OAAO,EAAE,cAAc,EAAoB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAkC,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/riskmap.d.ts CHANGED
@@ -45,6 +45,21 @@ export declare const MAP_W = 960, MAP_H = 520, MAP_CAP = 22;
45
45
  export declare const nodeRadius: (size: number) => number;
46
46
  /** Build the deterministic risk constellation from a signed report. Total. */
47
47
  export declare function buildRiskMap(report: unknown): RiskMap;
48
+ export interface BlastPartner {
49
+ file: string;
50
+ confidence: number;
51
+ coChanges: number;
52
+ hidden: boolean;
53
+ }
54
+ export interface BlastTarget {
55
+ file: string;
56
+ reach: number;
57
+ partners: BlastPartner[];
58
+ }
59
+ export declare function buildBlastRadius(report: unknown, maxTargets?: number, maxPartners?: number): {
60
+ targets: BlastTarget[];
61
+ note: string;
62
+ };
48
63
  export interface GauntletCheck {
49
64
  name: string;
50
65
  pass: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"riskmap.d.ts","sourceRoot":"","sources":["../src/riskmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,QAAQ;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACpJ,MAAM,WAAW,QAAQ;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;AACnF,MAAM,WAAW,OAAO;IAAG,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAEtH,eAAO,MAAM,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,OAAO,KAAK,CAAC;AACpD,6EAA6E;AAC7E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MAAqC,CAAC;AAKhF,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAkDrD;AAGD,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC9E,MAAM,WAAW,eAAe;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CAAE;AAgB/F,wBAAgB,eAAe,CAAC,UAAU,SAAU,GAAG,eAAe,CA0BrE"}
1
+ {"version":3,"file":"riskmap.d.ts","sourceRoot":"","sources":["../src/riskmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,QAAQ;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACpJ,MAAM,WAAW,QAAQ;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;AACnF,MAAM,WAAW,OAAO;IAAG,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAEtH,eAAO,MAAM,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,OAAO,KAAK,CAAC;AACpD,6EAA6E;AAC7E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MAAqC,CAAC;AAKhF,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAkDrD;AAMD,MAAM,WAAW,YAAY;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;AACtG,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE;AAEtF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,SAAI,EAAE,WAAW,SAAI,GAAG;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAuB3H;AAGD,MAAM,WAAW,aAAa;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC9E,MAAM,WAAW,eAAe;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CAAE;AAgB/F,wBAAgB,eAAe,CAAC,UAAU,SAAU,GAAG,eAAe,CAiCrE"}
package/dist/riskmap.js CHANGED
@@ -89,6 +89,35 @@ export function buildRiskMap(report) {
89
89
  const maxRisk = nodes.reduce((m, n) => Math.max(m, n.risk), 0);
90
90
  return { nodes, edges, maxRisk, W: MAP_W, H: MAP_H, note: nodes.length ? `${nodes.length} flagged file(s), ${edges.length} coupling link(s)` : "no per-file risk signals in this repo" };
91
91
  }
92
+ export function buildBlastRadius(report, maxTargets = 6, maxPartners = 5) {
93
+ const r = (report && typeof report === "object" ? report : {});
94
+ const cp = (r["coupling"] || {});
95
+ const pairs = (Array.isArray(cp["pairs"]) ? cp["pairs"] : []);
96
+ const adj = new Map();
97
+ const add = (from, to, conf, co, hidden) => {
98
+ if (!from || !to || from === to)
99
+ return;
100
+ if (!adj.has(from))
101
+ adj.set(from, []);
102
+ adj.get(from).push({ file: to, confidence: conf, coChanges: co, hidden });
103
+ };
104
+ for (const p of pairs) {
105
+ const a = str(p?.["a"]), b = str(p?.["b"]);
106
+ if (!a || !b)
107
+ continue;
108
+ const conf = clamp(num(p?.["confidence"]), 0, 1), co = num(p?.["coChanges"]), hidden = !!p?.["hidden"];
109
+ add(a, b, conf, co, hidden);
110
+ add(b, a, conf, co, hidden);
111
+ }
112
+ const targets = [...adj.entries()].map(([file, ps]) => {
113
+ ps.sort((x, y) => (y.confidence - x.confidence) || (y.coChanges - x.coChanges) || x.file.localeCompare(y.file));
114
+ const reach = ps.reduce((s, x) => s + x.confidence, 0);
115
+ return { file, reach, partners: ps.slice(0, maxPartners) };
116
+ });
117
+ targets.sort((a, b) => (b.reach - a.reach) || (b.partners.length - a.partners.length) || a.file.localeCompare(b.file));
118
+ const top = targets.slice(0, maxTargets);
119
+ return { targets: top, note: top.length ? `${top.length} file(s) with historical change-coupling` : "no temporal coupling measured (files change independently)" };
120
+ }
92
121
  /** seeded LCG → deterministic, reproducible "random" reports for the stress test */
93
122
  function lcg(seed) { let s = seed >>> 0; return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; }
94
123
  function randomReport(rnd) {
@@ -103,11 +132,12 @@ function randomReport(rnd) {
103
132
  }
104
133
  export function riskMapGauntlet(iterations = 100_000) {
105
134
  const rnd = lcg(1234567);
106
- let threw = 0, badCoord = 0, badRange = 0, badEdge = 0, overCap = 0;
135
+ let threw = 0, badCoord = 0, badRange = 0, badEdge = 0, overCap = 0, badBlast = 0;
107
136
  for (let i = 0; i < iterations; i++) {
137
+ const rep = randomReport(rnd);
108
138
  let m;
109
139
  try {
110
- m = buildRiskMap(randomReport(rnd));
140
+ m = buildRiskMap(rep);
111
141
  }
112
142
  catch {
113
143
  threw++;
@@ -124,17 +154,32 @@ export function riskMapGauntlet(iterations = 100_000) {
124
154
  for (const e of m.edges)
125
155
  if (e.a < 0 || e.b < 0 || e.a >= m.nodes.length || e.b >= m.nodes.length || e.a === e.b)
126
156
  badEdge++;
157
+ // BLAST RADIUS stressed on the same random report
158
+ try {
159
+ const br = buildBlastRadius(rep);
160
+ for (const t of br.targets) {
161
+ if (typeof t.file !== "string" || !t.file)
162
+ badBlast++;
163
+ for (const p of t.partners)
164
+ if (!(p.confidence >= 0 && p.confidence <= 1) || typeof p.file !== "string" || p.file === t.file)
165
+ badBlast++;
166
+ }
167
+ }
168
+ catch {
169
+ threw++;
170
+ }
127
171
  }
128
- // determinism: a fixed report renders identically twice
172
+ // determinism: a fixed report renders identically twice (map + blast)
129
173
  const fixed = randomReport(lcg(42));
130
- const det = JSON.stringify(buildRiskMap(fixed)) === JSON.stringify(buildRiskMap(fixed));
174
+ const det = JSON.stringify(buildRiskMap(fixed)) === JSON.stringify(buildRiskMap(fixed)) && JSON.stringify(buildBlastRadius(fixed)) === JSON.stringify(buildBlastRadius(fixed));
131
175
  const checks = [
132
176
  { name: "TOTAL", pass: threw === 0, detail: `0 throws over ${iterations.toLocaleString()} random reports (got ${threw})` },
133
177
  { name: "COORDS-IN-BOX", pass: badCoord === 0, detail: `every node coordinate finite + inside ${MAP_W}×${MAP_H} (violations ${badCoord})` },
134
178
  { name: "RANGE-0-1", pass: badRange === 0, detail: `risk + size always in [0,1] (violations ${badRange})` },
135
179
  { name: "EDGES-VALID", pass: badEdge === 0, detail: `every edge references two distinct existing nodes (violations ${badEdge})` },
136
180
  { name: "CAP", pass: overCap === 0, detail: `node count never exceeds ${MAP_CAP} (violations ${overCap})` },
137
- { name: "DETERMINISTIC", pass: det, detail: "same report byte-identical map" },
181
+ { name: "BLAST-VALID", pass: badBlast === 0, detail: `blast-radius partners valid (conf∈[0,1], distinct files) (violations ${badBlast})` },
182
+ { name: "DETERMINISTIC", pass: det, detail: "same report → byte-identical map + blast" },
138
183
  ];
139
184
  const passed = checks.filter((c) => c.pass).length;
140
185
  return { score: Math.round((passed / checks.length) * 100), iterations, checks };
@@ -1 +1 @@
1
- {"version":3,"file":"riskmap.js","sourceRoot":"","sources":["../src/riskmap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"riskmap.js","sourceRoot":"","sources":["../src/riskmap.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mneme-ai/xray",
3
- "version": "2.179.0",
3
+ "version": "2.181.0",
4
4
  "description": "Mneme Repo X-Ray — a signed, raw-free, deterministic X-Ray of any repo. Every number is reproducible from git/AST/metadata and sealed with an offline-verifiable NOTARY receipt. No source code ever leaves the machine; no LLM guesses anything.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/public/card.js CHANGED
@@ -136,16 +136,40 @@
136
136
  const nodeSvg = nodes.map((n) => { const R = n.r, col = riskColor(n.risk), showLabel = n.i < 9 || n.risk >= 0.65; const lbl = esc(base(n.file)).slice(0, 24) + (n.ownerPct >= 0.5 ? ` · ${Math.round(n.ownerPct * 100)}%` : ""); const lw = lbl.length * 6.4 + 14, ly = n.y + R + 7;
137
137
  return `<g><circle cx="${n.x}" cy="${n.y}" r="${(R + 11).toFixed(1)}" fill="${col}" opacity="0.12"/><circle cx="${n.x}" cy="${n.y}" r="${R.toFixed(1)}" fill="${col}" opacity="0.95"/><circle cx="${(n.x - R * 0.3).toFixed(1)}" cy="${(n.y - R * 0.32).toFixed(1)}" r="${(R * 0.52).toFixed(1)}" fill="#ffffff" opacity="0.22"/><circle cx="${n.x}" cy="${n.y}" r="${R.toFixed(1)}" fill="none" stroke="#ffffff" stroke-width="1.6" opacity="0.7"/>${showLabel ? `<g><rect x="${(n.x - lw / 2).toFixed(1)}" y="${ly.toFixed(1)}" width="${lw.toFixed(1)}" height="19" rx="9.5" fill="#ffffff" opacity="0.92" stroke="#ececef"/><text x="${n.x}" y="${(ly + 13).toFixed(1)}" text-anchor="middle" font-size="11.5" fill="#33333b" font-family="ui-monospace,Menlo,monospace">${lbl}</text></g>` : ""}</g>`; }).join("");
138
138
  const owned = nodes.filter((n) => n.risk >= 0.6).length;
139
+ // TOP key-person risks as WORDS (the part a CEO/dev reads) — concrete + actionable
140
+ const topRisk = nodes.filter((n) => n.risk >= 0.5).slice(0, 6);
141
+ const riskList = topRisk.length ? `<div class="rmlist"><div class="rmlt">⚠️ Top key-person risks — fix these first</div>${topRisk.map((n) => `<div class="rmli"><span class="rmdot" style="background:${riskColor(n.risk)}"></span><b>${esc(base(n.file))}</b><span class="rmwhy">one author owns <b>${Math.round(n.ownerPct * 100)}%</b> of its history — add a reviewer / write docs before they leave</span></div>`).join("")}</div>` : `<div class="rmlist rmok">✓ No single-owner files — knowledge is well spread across the team.</div>`;
139
142
  return `<div class="riskmap">
140
- <div class="rmhead">🗺 Risk map — <b>if an owner leaves, the red files lose their only expert</b></div>
141
- <div class="rmsub">${nodes.length} flagged file(s) · ${edges.length} coupling link(s)${owned ? ` · <b style="color:#be123c">${owned} single-owner hotspot${owned > 1 ? "s" : ""}</b>` : ""} colour = key-person risk · size = churn · line = files that change together. Every node is verbatim from the signed report.</div>
142
- <svg class="rmsvg" viewBox="0 0 ${W} ${H}" preserveAspectRatio="xMidYMid meet" role="img" aria-label="repository risk map">${edgeSvg}${nodeSvg}</svg>
143
- <div class="rmleg"><span><i style="background:#16a34a"></i>shared / low risk</span><span><i style="background:#d97706"></i>concentrated</span><span><i style="background:#e11d48"></i>single-owner (key-person)</span><span><i class="dash"></i>hidden cross-dir coupling</span></div>
143
+ <div class="rmhead">🗺 Risk map — <b>who holds the keys, and what breaks if they leave</b></div>
144
+ <div class="rmsub"><b>How to read:</b> each circle is a file · <b>red</b> = only one person knows it (key-person risk) · <b>bigger</b> = changes more often · <b>lines</b> = files that always change together. Click the map to enlarge. Every value is verbatim from the signed report — no AI guessed it.</div>
145
+ <div class="rmsvgwrap rmzoom" title="click to enlarge"><svg class="rmsvg" viewBox="0 0 ${W} ${H}" preserveAspectRatio="xMidYMid meet" role="img" aria-label="repository risk map">${edgeSvg}${nodeSvg}</svg><span class="rmexpand">⤢ enlarge</span></div>
146
+ <div class="rmleg"><span><i style="background:#16a34a"></i>shared / safe</span><span><i style="background:#d97706"></i>concentrated</span><span><i style="background:#e11d48"></i>single-owner</span><span><i class="dash"></i>hidden cross-dir coupling</span><span class="rmsummary">${nodes.length} files · ${edges.length} links${owned ? ` · <b style="color:#be123c">${owned} single-owner</b>` : ""}</span></div>
147
+ ${riskList}
148
+ </div>`;
149
+ }
150
+
151
+ // BLAST RADIUS — mirrors packages/xray/src/riskmap.ts buildBlastRadius (tested + 100k).
152
+ // "When you changed A, these changed too N% of the time" — measured history, verbatim.
153
+ function blastRadiusHTML(r) {
154
+ const strv = (x) => (typeof x === "string" ? x : ""), num = (x) => (Number.isFinite(Number(x)) ? Number(x) : 0);
155
+ const pairs = ((r.coupling || {}).pairs) || []; const adj = new Map();
156
+ const add = (f, t, c, co, h) => { if (!f || !t || f === t) return; if (!adj.has(f)) adj.set(f, []); adj.get(f).push({ file: t, c: Math.min(1, Math.max(0, c)), co, h }); };
157
+ pairs.forEach((p) => { const a = strv(p && p.a), b = strv(p && p.b); if (!a || !b) return; const c = num(p.confidence), co = num(p.coChanges), h = !!(p && p.hidden); add(a, b, c, co, h); add(b, a, c, co, h); });
158
+ if (!adj.size) return "";
159
+ const base = (f) => { const x = String(f).split("/"); return x[x.length - 1]; };
160
+ let targets = [...adj.entries()].map(([file, ps]) => { ps.sort((x, y) => y.c - x.c || x.file.localeCompare(y.file)); return { file, reach: ps.reduce((s, x) => s + x.c, 0), partners: ps.slice(0, 5) }; });
161
+ targets.sort((a, b) => b.reach - a.reach || a.file.localeCompare(b.file));
162
+ targets = targets.slice(0, 6);
163
+ return `<div class="blast">
164
+ <div class="blhead">💥 Change impact — <b>edit one file, what historically moves with it</b></div>
165
+ <div class="blsub">Measured from git history (not a prediction): when these files changed, their partners changed too. Review them together to avoid surprise breakage.</div>
166
+ ${targets.map((t) => `<div class="blrow"><span class="blf">✏️ ${esc(base(t.file))}</span><span class="blarrow">→</span><span class="blp">${t.partners.map((p) => `<span class="blpill${p.h ? " hidden" : ""}">${esc(base(p.file))} <b>${Math.round(p.c * 100)}%</b></span>`).join("")}</span></div>`).join("")}
144
167
  </div>`;
145
168
  }
146
169
 
147
170
  function xrayCardHTML(signed, opts) {
148
171
  opts = opts || {};
172
+ g.__lastSigned = signed; // stash for the "Verify signature" proof button
149
173
  const r = signed.report, s = r.summary;
150
174
  const dep = r.deps, sec = r.secrets, bf = r.busFactor, age = r.age, cx = r.complexity;
151
175
  const verified = signed.receipt ? '<span class="verified"><span class="dot"></span>Ed25519 — verifies offline</span>' : "unsigned";
@@ -187,12 +211,12 @@
187
211
  <div class="vrlist">${vd.risks.map((k) => `<div class="vr"><span class="vrg">${k.icon} ${k.g}</span><span class="vrt">${k.t}</span></div>`).join("")}</div></details>` : ""}
188
212
  </div>
189
213
  ${riskMapHTML(r)}
214
+ ${blastRadiusHTML(r)}
190
215
  <div class="membrane">
191
- <div class="mp"><span class="mpk">① CAPABILITY</span><span class="mpv">${s.signalsRun} deterministic signals · ${(sec.filesScanned || 0).toLocaleString()} files scanned</span></div>
192
- <div class="mp"><span class="mpk">② ATTENTION</span><span class="mpv">${tri.length ? `${tri.length} signal(s) need attention` : `all signals clear`}</span></div>
193
- <div class="mp"><span class="mpk">③ HALLUCINATION</span><span class="mpv"><span class="hdot"></span><b>0</b> — every number from real git/code${verified ? ", signed" : ""}</span></div>
216
+ <div class="mp"><span class="mpk">CAPABILITY</span><span class="mpv">${s.signalsRun} deterministic signals · ${(sec.filesScanned || 0).toLocaleString()} files scanned</span></div>
217
+ <div class="mp"><span class="mpk">ATTENTION</span><span class="mpv">${tri.length ? `${tri.length} signal(s) need attention` : `all signals clear`}</span></div>
194
218
  </div>
195
- <div class="trustbar"><span class="htext"><b>Every figure is computed from git, code &amp; package metadata not one guessed by an AI.</b> Re-run this commit identical numbers${verified ? ` · <b>signed</b>, verifies offline with the embedded public key` : ""}.</span></div>
219
+ <div class="trustbar"><span class="hdot"></span><div class="htext"><b>Reproducible not hallucinated.</b> An LLM is random (different every run); X-Ray is plain code reading git, so re-running this commit gives the <b>byte-identical</b> result — that's why nothing here is AI-guessed. ${verified ? `Fingerprint <code class="fp">${esc(String(r.fingerprint).slice(0, 16))}…</code> · <button class="verifybtn" type="button" data-verify>Verify signature ↗</button>` : ""}</div></div>
196
220
  ${tri.length ? `<div class="triage">
197
221
  <div class="triage-h">🔺 Needs attention (${tri.length}) <span class="triage-sub">— curated &amp; severity-ranked; every line is traceable to its source</span></div>
198
222
  ${tri.map((t) => `<div class="ti ${t.sev}"><span class="ti-sev">${t.sev}</span><div class="ti-body"><div class="ti-f"><b>${esc(t.s)}</b> — ${esc(t.f)}</div><div class="ti-p">↳ ${esc(t.p)}</div></div></div>`).join("")}
@@ -212,5 +236,39 @@
212
236
  </div>`;
213
237
  }
214
238
 
215
- g.MnemeXRay = { xrayCardHTML, gradeClass: gC, esc };
239
+ g.MnemeXRay = { xrayCardHTML, gradeClass: gC, esc, riskMapHTML };
240
+
241
+ // CLICK-TO-ENLARGE the risk map — one delegated listener (works on every page that
242
+ // loads card.js, every browser, mobile). Builds a responsive modal on first open.
243
+ if (typeof document !== "undefined" && !g.__rmZoomBound) {
244
+ g.__rmZoomBound = true;
245
+ const close = () => { const m = document.getElementById("rmmodal"); if (m) m.style.display = "none"; };
246
+ document.addEventListener("click", (ev) => {
247
+ const t = ev.target;
248
+ if (t && t.closest && t.closest(".rmmodal-close")) { close(); return; }
249
+ if (t && t.id === "rmmodal") { close(); return; }
250
+ const z = t && t.closest && t.closest(".rmzoom");
251
+ if (z) {
252
+ const svg = z.querySelector("svg"); if (!svg) return;
253
+ let m = document.getElementById("rmmodal");
254
+ if (!m) { m = document.createElement("div"); m.id = "rmmodal"; m.className = "rmmodal"; document.body.appendChild(m); }
255
+ m.innerHTML = `<div class="rmmodal-box"><div class="rmmodal-bar"><b>🗺 Risk map</b> — red = single-owner (key-person risk) · size = churn · line = files that change together<button class="rmmodal-close" aria-label="close">✕</button></div><div class="rmmodal-svg">${svg.outerHTML}</div></div>`;
256
+ m.style.display = "flex";
257
+ }
258
+ });
259
+ document.addEventListener("keydown", (ev) => { if (ev.key === "Escape") close(); });
260
+ // "Verify signature" — re-checks the Ed25519 receipt via /api/verify (the proof a
261
+ // skeptic can run themselves). Honest: a genuine report verifies; a tampered one fails.
262
+ document.addEventListener("click", async (ev) => {
263
+ const b = ev.target && ev.target.closest && ev.target.closest("[data-verify]");
264
+ if (!b || !g.__lastSigned) return;
265
+ const old = b.textContent; b.textContent = "verifying…"; b.disabled = true;
266
+ try {
267
+ const res = await fetch("/api/verify", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(g.__lastSigned) });
268
+ const v = await res.json();
269
+ b.textContent = v && v.valid ? "✓ signature valid (verified offline-style)" : "✗ " + ((v && v.reason) || "invalid");
270
+ b.style.color = v && v.valid ? "#15803d" : "#be123c";
271
+ } catch { b.textContent = old; b.disabled = false; }
272
+ });
273
+ }
216
274
  })(window);
package/public/index.html CHANGED
@@ -96,10 +96,35 @@
96
96
  .riskmap .rmleg span{display:inline-flex;align-items:center;gap:6px}
97
97
  .riskmap .rmleg i{width:11px;height:11px;border-radius:50%;display:inline-block}
98
98
  .riskmap .rmleg i.dash{width:18px;height:0;border-radius:0;border-top:2px dashed #e11d48}
99
+ .riskmap .rmsummary{margin-left:auto;color:#8b8f98}
100
+ .riskmap .rmsvgwrap{position:relative;cursor:zoom-in}
101
+ .riskmap .rmexpand{position:absolute;top:10px;right:12px;font-size:11px;color:#5b6068;background:#fff;border:1px solid #ececef;border-radius:8px;padding:3px 9px;opacity:.85}
102
+ .riskmap .rmlist{margin-top:14px;border-top:1px solid #eef0f2;padding-top:12px}
103
+ .riskmap .rmlt{font-size:12.5px;font-weight:680;color:#be123c;margin-bottom:8px}
104
+ .riskmap .rmok{color:#15803d;font-weight:560;font-size:13px;border:0;padding-top:0}
105
+ .riskmap .rmli{display:flex;align-items:baseline;gap:9px;padding:6px 0;font-size:13px;flex-wrap:wrap}
106
+ .riskmap .rmdot{width:10px;height:10px;border-radius:50%;flex-shrink:0;align-self:center}
107
+ .riskmap .rmli b{color:#0b0b0f;font-family:ui-monospace,Menlo,monospace}
108
+ .riskmap .rmwhy{color:#5b6068}
109
+ .rmmodal{display:none;position:fixed;inset:0;z-index:9999;background:rgba(11,11,20,.62);align-items:center;justify-content:center;padding:16px}
110
+ .rmmodal-box{background:#fff;border-radius:16px;max-width:1100px;width:100%;max-height:92vh;overflow:auto;box-shadow:0 24px 80px rgba(0,0,0,.4)}
111
+ .rmmodal-bar{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid #eef0f2;font-size:13px;color:#5b6068;position:sticky;top:0;background:#fff}
112
+ .rmmodal-close{margin-left:auto;width:34px;height:34px;border:1px solid #ececef;background:#fff;border-radius:9px;cursor:pointer;font-size:15px;flex-shrink:0}
113
+ .rmmodal-svg{padding:14px}.rmmodal-svg svg{width:100%;height:auto}
114
+ .blast{padding:16px 30px;border-bottom:1px solid #eef0f2}
115
+ .blast .blhead{font-size:14.5px;color:#0b0b0f}.blast .blsub{font-size:11.5px;color:#8b8f98;margin:4px 0 12px;line-height:1.5}
116
+ .blast .blrow{display:flex;align-items:baseline;gap:8px;padding:7px 0;border-top:1px solid #f3f3f5;font-size:13px;flex-wrap:wrap}
117
+ .blast .blf{font-family:ui-monospace,Menlo,monospace;font-weight:600;color:#0b0b0f;flex-shrink:0}
118
+ .blast .blarrow{color:#aeb2ba}
119
+ .blast .blp{display:flex;gap:6px;flex-wrap:wrap}
120
+ .blast .blpill{font-size:11.5px;background:#eef0ff;color:#3a3df0;border-radius:20px;padding:2px 9px;font-family:ui-monospace,Menlo,monospace}
121
+ .blast .blpill.hidden{background:#fff1f3;color:#be123c}
99
122
  .trustbar{display:flex;align-items:center;gap:14px;padding:13px 30px;background:#f0fdf4;border-bottom:1px solid #dcfce7;flex-wrap:wrap}
100
123
  .hgauge{display:inline-flex;align-items:center;gap:8px;font-weight:680;color:#15803d;font-size:14px;white-space:nowrap}
101
124
  .hdot{width:10px;height:10px;border-radius:50%;background:#16a34a;box-shadow:0 0 0 4px rgba(22,163,74,.16)}
102
125
  .htext{font-size:12.5px;color:#3f6b4e;line-height:1.5}.htext b{color:#14532d;font-weight:640}
126
+ .htext .fp{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;background:#dcfce7;border-radius:6px;padding:1px 6px;color:#14532d}
127
+ .verifybtn{font-size:11.5px;border:1px solid #86c79b;background:#fff;color:#15803d;border-radius:8px;padding:2px 9px;cursor:pointer;font-weight:560}.verifybtn:hover{background:#f0fdf4}
103
128
  .membrane{display:flex;border-bottom:1px solid #eef0f2;background:#fafbfc;flex-wrap:wrap}
104
129
  .mp{flex:1;min-width:180px;padding:11px 18px;border-right:1px solid #eef0f2;display:flex;flex-direction:column;gap:3px}.mp:last-child{border-right:0}
105
130
  .mpk{font-size:10.5px;letter-spacing:.06em;color:#8a909a;font-weight:700}
@@ -49,10 +49,35 @@
49
49
  .riskmap .rmleg span{display:inline-flex;align-items:center;gap:6px}
50
50
  .riskmap .rmleg i{width:11px;height:11px;border-radius:50%;display:inline-block}
51
51
  .riskmap .rmleg i.dash{width:18px;height:0;border-radius:0;border-top:2px dashed #e11d48}
52
+ .riskmap .rmsummary{margin-left:auto;color:#8b8f98}
53
+ .riskmap .rmsvgwrap{position:relative;cursor:zoom-in}
54
+ .riskmap .rmexpand{position:absolute;top:10px;right:12px;font-size:11px;color:#5b6068;background:#fff;border:1px solid #ececef;border-radius:8px;padding:3px 9px;opacity:.85}
55
+ .riskmap .rmlist{margin-top:14px;border-top:1px solid #eef0f2;padding-top:12px}
56
+ .riskmap .rmlt{font-size:12.5px;font-weight:680;color:#be123c;margin-bottom:8px}
57
+ .riskmap .rmok{color:#15803d;font-weight:560;font-size:13px;border:0;padding-top:0}
58
+ .riskmap .rmli{display:flex;align-items:baseline;gap:9px;padding:6px 0;font-size:13px;flex-wrap:wrap}
59
+ .riskmap .rmdot{width:10px;height:10px;border-radius:50%;flex-shrink:0;align-self:center}
60
+ .riskmap .rmli b{color:#0b0b0f;font-family:ui-monospace,Menlo,monospace}
61
+ .riskmap .rmwhy{color:#5b6068}
62
+ .rmmodal{display:none;position:fixed;inset:0;z-index:9999;background:rgba(11,11,20,.62);align-items:center;justify-content:center;padding:16px}
63
+ .rmmodal-box{background:#fff;border-radius:16px;max-width:1100px;width:100%;max-height:92vh;overflow:auto;box-shadow:0 24px 80px rgba(0,0,0,.4)}
64
+ .rmmodal-bar{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid #eef0f2;font-size:13px;color:#5b6068;position:sticky;top:0;background:#fff}
65
+ .rmmodal-close{margin-left:auto;width:34px;height:34px;border:1px solid #ececef;background:#fff;border-radius:9px;cursor:pointer;font-size:15px;flex-shrink:0}
66
+ .rmmodal-svg{padding:14px}.rmmodal-svg svg{width:100%;height:auto}
67
+ .blast{padding:16px 30px;border-bottom:1px solid #eef0f2}
68
+ .blast .blhead{font-size:14.5px;color:#0b0b0f}.blast .blsub{font-size:11.5px;color:#8b8f98;margin:4px 0 12px;line-height:1.5}
69
+ .blast .blrow{display:flex;align-items:baseline;gap:8px;padding:7px 0;border-top:1px solid #f3f3f5;font-size:13px;flex-wrap:wrap}
70
+ .blast .blf{font-family:ui-monospace,Menlo,monospace;font-weight:600;color:#0b0b0f;flex-shrink:0}
71
+ .blast .blarrow{color:#aeb2ba}
72
+ .blast .blp{display:flex;gap:6px;flex-wrap:wrap}
73
+ .blast .blpill{font-size:11.5px;background:#eef0ff;color:#3a3df0;border-radius:20px;padding:2px 9px;font-family:ui-monospace,Menlo,monospace}
74
+ .blast .blpill.hidden{background:#fff1f3;color:#be123c}
52
75
  .trustbar{display:flex;align-items:center;gap:14px;padding:13px 30px;background:#f0fdf4;border-bottom:1px solid #dcfce7;flex-wrap:wrap}
53
76
  .hgauge{display:inline-flex;align-items:center;gap:8px;font-weight:680;color:#15803d;font-size:14px}
54
77
  .hdot{width:10px;height:10px;border-radius:50%;background:#16a34a;box-shadow:0 0 0 4px rgba(22,163,74,.16)}
55
78
  .htext{font-size:12.5px;color:#3f6b4e;line-height:1.5}.htext b{color:#14532d;font-weight:640}
79
+ .htext .fp{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;background:#dcfce7;border-radius:6px;padding:1px 6px;color:#14532d}
80
+ .verifybtn{font-size:11.5px;border:1px solid #86c79b;background:#fff;color:#15803d;border-radius:8px;padding:2px 9px;cursor:pointer;font-weight:560}.verifybtn:hover{background:#f0fdf4}
56
81
  .membrane{display:flex;border-bottom:1px solid #eef0f2;background:#fafbfc}
57
82
  .mp{flex:1;padding:11px 18px;border-right:1px solid #eef0f2;display:flex;flex-direction:column;gap:3px}.mp:last-child{border-right:0}
58
83
  .mpk{font-size:10.5px;letter-spacing:.06em;color:#8a909a;font-weight:700}