six-degrees 0.4.6 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.rsc +2 -2
  7. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  9. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.rsc +13 -13
  14. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  15. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +11 -11
  16. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/favicon.ico.body +0 -0
  48. package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/import.html +1 -1
  51. package/.next/standalone/.next/server/app/import.rsc +15 -15
  52. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +15 -15
  53. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +1 -1
  54. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +13 -13
  55. package/.next/standalone/.next/server/app/index.html +1 -1
  56. package/.next/standalone/.next/server/app/index.rsc +15 -15
  57. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  58. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  59. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  60. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/launch.html +2 -2
  63. package/.next/standalone/.next/server/app/launch.rsc +15 -15
  64. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +15 -15
  65. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +13 -13
  67. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/paths.html +1 -1
  72. package/.next/standalone/.next/server/app/paths.rsc +15 -15
  73. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +15 -15
  74. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +1 -1
  75. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +13 -13
  76. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/profile.html +1 -1
  79. package/.next/standalone/.next/server/app/profile.rsc +15 -15
  80. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +15 -15
  81. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +1 -1
  82. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +13 -13
  83. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/queue.html +1 -1
  86. package/.next/standalone/.next/server/app/queue.rsc +15 -15
  87. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +15 -15
  88. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +1 -1
  89. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +13 -13
  90. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/scores.html +1 -1
  93. package/.next/standalone/.next/server/app/scores.rsc +15 -15
  94. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +15 -15
  95. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +1 -1
  96. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +13 -13
  97. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/settings.html +1 -1
  100. package/.next/standalone/.next/server/app/settings.rsc +15 -15
  101. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +15 -15
  102. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  103. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +13 -13
  104. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/setup.html +1 -1
  107. package/.next/standalone/.next/server/app/setup.rsc +15 -15
  108. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +15 -15
  109. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +1 -1
  110. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +13 -13
  111. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/social.html +1 -1
  114. package/.next/standalone/.next/server/app/social.rsc +15 -15
  115. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +15 -15
  116. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +1 -1
  117. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +13 -13
  118. package/.next/standalone/.next/server/chunks/_1_fynia._.js +1 -1
  119. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  120. package/.next/standalone/.next/server/chunks/_1mxn_lb._.js +1 -1
  121. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +1 -1
  122. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +5 -5
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00d8snt._.js +1 -1
  124. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00g61b8._.js +1 -1
  125. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08lf3gy._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ho-u0w._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ze473p._.js +1 -1
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1194jps._.js +1 -1
  130. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1cnxxc9._.js +1 -1
  131. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jeztd-._.js +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ll97ry._.js +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m0255u._.js +1 -1
  134. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1w9z0zv._.js +1 -1
  135. package/.next/standalone/.next/server/chunks/ssr/_005q9n1._.js +1 -1
  136. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +1 -1
  137. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +1 -1
  138. package/.next/standalone/.next/server/chunks/ssr/lib_0i8v-s3._.js +1 -1
  139. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  140. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  141. package/.next/standalone/.next/server/pages/404.html +1 -1
  142. package/.next/standalone/.next/server/pages/500.html +1 -1
  143. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  145. package/.next/standalone/.next/static/chunks/15qbli9udo0vh.js +1 -0
  146. package/.next/{static/chunks/2_zu7rmb8flzl.js → standalone/.next/static/chunks/1z-zp93cyoxvz.js} +1 -1
  147. package/.next/standalone/.next/static/chunks/24tvdun1cb3g1.js +1 -0
  148. package/.next/standalone/.next/static/chunks/3q3pmt5vv-4pi.js +6 -0
  149. package/.next/standalone/.next/static/media/favicon.23vm2o6v3er2z.ico +0 -0
  150. package/.next/standalone/CHANGELOG.md +42 -0
  151. package/.next/standalone/CONTRIBUTING.md +5 -0
  152. package/.next/standalone/README.md +168 -56
  153. package/.next/standalone/app/api/scraper/route.js +3 -0
  154. package/.next/standalone/app/favicon.ico +0 -0
  155. package/.next/standalone/app/paths/page.js +25 -18
  156. package/.next/standalone/app/setup/page.js +18 -0
  157. package/.next/standalone/lib/scoring.js +42 -1
  158. package/.next/standalone/lib/scraper-client.js +5 -1
  159. package/.next/standalone/package-lock.json +2 -2
  160. package/.next/standalone/package.json +1 -1
  161. package/.next/standalone/scripts/build-site.mjs +537 -0
  162. package/.next/standalone/scripts/site-markdown.mjs +188 -0
  163. package/.next/standalone/scripts/site-news.mjs +311 -0
  164. package/.next/static/chunks/15qbli9udo0vh.js +1 -0
  165. package/.next/{standalone/.next/static/chunks/2_zu7rmb8flzl.js → static/chunks/1z-zp93cyoxvz.js} +1 -1
  166. package/.next/static/chunks/24tvdun1cb3g1.js +1 -0
  167. package/.next/static/chunks/3q3pmt5vv-4pi.js +6 -0
  168. package/.next/static/media/favicon.23vm2o6v3er2z.ico +0 -0
  169. package/CHANGELOG.md +42 -0
  170. package/README.md +168 -56
  171. package/lib/scoring.js +42 -1
  172. package/lib/scraper-client.js +5 -1
  173. package/package.json +1 -1
  174. package/.next/standalone/.next/static/chunks/04a3zockahetx.js +0 -1
  175. package/.next/standalone/.next/static/chunks/24m745q_85u34.js +0 -6
  176. package/.next/standalone/.next/static/chunks/3p_pwu5gx2i9h.js +0 -1
  177. package/.next/standalone/.next/static/media/favicon.0zdzw5kurn8m-.ico +0 -0
  178. package/.next/static/chunks/04a3zockahetx.js +0 -1
  179. package/.next/static/chunks/24m745q_85u34.js +0 -6
  180. package/.next/static/chunks/3p_pwu5gx2i9h.js +0 -1
  181. package/.next/static/media/favicon.0zdzw5kurn8m-.ico +0 -0
  182. /package/.next/standalone/.next/static/{-QUFjmCQWXW5PCoTA1G12 → T0eWMsKjgSiPnmx1E0q3G}/_buildManifest.js +0 -0
  183. /package/.next/standalone/.next/static/{-QUFjmCQWXW5PCoTA1G12 → T0eWMsKjgSiPnmx1E0q3G}/_clientMiddlewareManifest.js +0 -0
  184. /package/.next/standalone/.next/static/{-QUFjmCQWXW5PCoTA1G12 → T0eWMsKjgSiPnmx1E0q3G}/_ssgManifest.js +0 -0
  185. /package/.next/static/{-QUFjmCQWXW5PCoTA1G12 → T0eWMsKjgSiPnmx1E0q3G}/_buildManifest.js +0 -0
  186. /package/.next/static/{-QUFjmCQWXW5PCoTA1G12 → T0eWMsKjgSiPnmx1E0q3G}/_clientMiddlewareManifest.js +0 -0
  187. /package/.next/static/{-QUFjmCQWXW5PCoTA1G12 → T0eWMsKjgSiPnmx1E0q3G}/_ssgManifest.js +0 -0
@@ -0,0 +1,188 @@
1
+ // A small Markdown renderer for the website's blog posts, pages and release notes.
2
+ // No dependencies, on purpose: the site builds with nothing but Node. It covers
3
+ // what the posts and CHANGELOG.md use, and nothing more:
4
+ //
5
+ // # to ####### headings (with an id from their text), paragraphs, blank-line breaks
6
+ // - and 1. lists, nested by two spaces, with continuation lines
7
+ // > block quotes, ``` fenced code, --- rules, | tables |
8
+ // **bold**, *italic*, `code`, [links](url), ![images](src "caption")
9
+ //
10
+ // Raw HTML is escaped, never passed through: a post can't inject markup or script.
11
+
12
+ export const escapeHtml = (s) => String(s)
13
+ .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
14
+
15
+ /** "What it does, for you!" → "what-it-does-for-you" */
16
+ export function slugify(text) {
17
+ return String(text).toLowerCase()
18
+ .replace(/<[^>]+>/g, '')
19
+ .replace(/&[a-z]+;/g, '')
20
+ .replace(/[^a-z0-9\s-]/g, '')
21
+ .trim().replace(/\s+/g, '-').replace(/-+/g, '-');
22
+ }
23
+
24
+ const safeUrl = (url) => (/^(https?:|mailto:|\/|#|\.\.?\/)/i.test(url) || !/^[a-z]+:/i.test(url) ? url : '#');
25
+
26
+ /** Inline marks, on text that is escaped first. */
27
+ export function inline(md) {
28
+ let s = escapeHtml(md);
29
+ const codes = [];
30
+ s = s.replace(/`([^`]+)`/g, (_, c) => { codes.push(c); return `\u0000${codes.length - 1}\u0000`; });
31
+ s = s.replace(/!\[([^\]]*)\]\(([^)\s]+)(?:\s+&quot;([^&]*)&quot;)?\)/g,
32
+ (_, alt, src) => `<img src="${safeUrl(src)}" alt="${alt}" loading="lazy">`);
33
+ s = s.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_, text, url) => `<a href="${safeUrl(url)}">${text}</a>`);
34
+ s = s.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
35
+ s = s.replace(/(^|[^\w*])\*(?!\s)(.+?)\*(?!\w)/g, '$1<em>$2</em>');
36
+ s = s.replace(/\u0000(\d+)\u0000/g, (_, i) => `<code>${codes[Number(i)]}</code>`);
37
+ return s;
38
+ }
39
+
40
+ /**
41
+ * Front matter between --- lines: `key: value`, with [a, b] lists. Returns
42
+ * { data, body }. A file without it is all body.
43
+ */
44
+ export function frontMatter(text) {
45
+ const m = text.match(/^---\n([\s\S]*?)\n---\n?/);
46
+ if (!m) return { data: {}, body: text };
47
+ const data = {};
48
+ for (const line of m[1].split('\n')) {
49
+ const kv = line.match(/^([A-Za-z][\w-]*):\s*(.*)$/);
50
+ if (!kv) continue;
51
+ let v = kv[2].trim();
52
+ if (/^\[.*\]$/.test(v)) v = v.slice(1, -1).split(',').map((x) => x.trim().replace(/^["']|["']$/g, '')).filter(Boolean);
53
+ else v = v.replace(/^["'](.*)["']$/, '$1');
54
+ data[kv[1]] = v;
55
+ }
56
+ return { data, body: text.slice(m[0].length) };
57
+ }
58
+
59
+ /** The same, for an HTML page whose first thing is a <!-- key: value --> comment. */
60
+ export function htmlFrontMatter(text) {
61
+ const m = text.match(/^<!--\n([\s\S]*?)\n-->\n?/);
62
+ if (!m) return { data: {}, body: text };
63
+ return { data: frontMatter(`---\n${m[1]}\n---\n`).data, body: text.slice(m[0].length) };
64
+ }
65
+
66
+ function table(lines) {
67
+ const cells = (l) => l.trim().replace(/^\||\|$/g, '').split('|').map((c) => c.trim());
68
+ const head = cells(lines[0]);
69
+ const rows = lines.slice(2).map(cells);
70
+ return `<div class="table-wrap prose-table"><table>\n<thead><tr>${head.map((h) => `<th scope="col">${inline(h)}</th>`).join('')}</tr></thead>\n<tbody>\n${
71
+ rows.map((r) => `<tr>${r.map((c, i) => (i === 0 ? `<th scope="row">${inline(c)}</th>` : `<td>${inline(c)}</td>`)).join('')}</tr>`).join('\n')
72
+ }\n</tbody></table></div>`;
73
+ }
74
+
75
+ /**
76
+ * Lists: items start with "- " or "1. " at an indent; deeper indents nest. An
77
+ * item's text, its sub-lists and any later paragraphs stay in their order.
78
+ */
79
+ function list(lines, start) {
80
+ const indentOf = (l) => l.match(/^(\s*)/)[1].length;
81
+ const base = indentOf(lines[start]);
82
+ const ordered = /^\s*\d+\.\s/.test(lines[start]);
83
+ const items = [];
84
+ let i = start;
85
+ let gap = false; // a blank line: the next text inside this item is a new paragraph
86
+ while (i < lines.length) {
87
+ const l = lines[i];
88
+ if (!l.trim()) {
89
+ // A blank line inside a list continues it only if an indented line follows.
90
+ const next = lines[i + 1];
91
+ if (next && indentOf(next) > base && next.trim()) { gap = true; i += 1; continue; }
92
+ break;
93
+ }
94
+ const ind = indentOf(l);
95
+ const bullet = l.match(/^\s*(?:[-*]|\d+\.)\s+(.*)$/);
96
+ if (ind === base && bullet) { items.push({ parts: [bullet[1]] }); gap = false; i += 1; continue; }
97
+ if (ind < base || (!bullet && ind === base) || !items.length) break;
98
+ const parts = items.at(-1).parts;
99
+ if (bullet && ind > base) {
100
+ const [html, next] = list(lines, i);
101
+ parts.push({ html });
102
+ gap = false;
103
+ i = next;
104
+ continue;
105
+ }
106
+ if (gap || typeof parts.at(-1) !== 'string') parts.push(l.trim());
107
+ else parts[parts.length - 1] += ` ${l.trim()}`;
108
+ gap = false;
109
+ i += 1;
110
+ }
111
+ const tag = ordered ? 'ol' : 'ul';
112
+ const li = (it) => it.parts.map((p, n) => (typeof p !== 'string' ? p.html : n === 0 ? inline(p) : `<p>${inline(p)}</p>`)).join('');
113
+ const html = `<${tag}>\n${items.map((it) => `<li>${li(it)}</li>`).join('\n')}\n</${tag}>`;
114
+ return [html, i];
115
+ }
116
+
117
+ /**
118
+ * Markdown → HTML. `headingOffset` shifts heading levels (1 makes # an <h2>),
119
+ * `ids` adds an id to each heading.
120
+ */
121
+ export function markdown(md, { headingOffset = 0, ids = true } = {}) {
122
+ const lines = md.replace(/\r\n/g, '\n').split('\n');
123
+ const out = [];
124
+ let i = 0;
125
+ while (i < lines.length) {
126
+ const l = lines[i];
127
+ if (!l.trim()) { i += 1; continue; }
128
+ const fence = l.match(/^```(\w*)/);
129
+ if (fence) {
130
+ const code = [];
131
+ i += 1;
132
+ while (i < lines.length && !/^```/.test(lines[i])) code.push(lines[i++]);
133
+ i += 1;
134
+ out.push(`<pre><code${fence[1] ? ` class="lang-${fence[1]}"` : ''}>${escapeHtml(code.join('\n'))}</code></pre>`);
135
+ continue;
136
+ }
137
+ const h = l.match(/^(#{1,6})\s+(.*)$/);
138
+ if (h) {
139
+ const level = Math.min(6, h[1].length + headingOffset);
140
+ const html = inline(h[2]);
141
+ out.push(`<h${level}${ids ? ` id="${slugify(h[2])}"` : ''}>${html}</h${level}>`);
142
+ i += 1;
143
+ continue;
144
+ }
145
+ if (/^(-{3,}|\*{3,})\s*$/.test(l)) { out.push('<hr>'); i += 1; continue; }
146
+ if (/^\s*(?:[-*]|\d+\.)\s+/.test(l)) {
147
+ const [html, next] = list(lines, i);
148
+ out.push(html);
149
+ i = next;
150
+ continue;
151
+ }
152
+ if (/^>\s?/.test(l)) {
153
+ const q = [];
154
+ while (i < lines.length && /^>\s?/.test(lines[i])) q.push(lines[i++].replace(/^>\s?/, ''));
155
+ out.push(`<blockquote>${markdown(q.join('\n'), { headingOffset, ids: false })}</blockquote>`);
156
+ continue;
157
+ }
158
+ if (/^\|.*\|\s*$/.test(l) && /^\|?\s*:?-{2,}/.test(lines[i + 1] || '')) {
159
+ const t = [];
160
+ while (i < lines.length && /^\|.*\|\s*$/.test(lines[i])) t.push(lines[i++]);
161
+ out.push(table(t));
162
+ continue;
163
+ }
164
+ const img = l.match(/^!\[([^\]]*)\]\(([^)\s]+)(?:\s+"([^"]*)")?\)\s*$/);
165
+ if (img) {
166
+ out.push(`<figure><img src="${escapeHtml(safeUrl(img[2]))}" alt="${escapeHtml(img[1])}" loading="lazy">${img[3] ? `<figcaption>${inline(img[3])}</figcaption>` : ''}</figure>`);
167
+ i += 1;
168
+ continue;
169
+ }
170
+ const para = [];
171
+ while (i < lines.length && lines[i].trim() && !/^(#{1,6}\s|```|>\s?|\s*(?:[-*]|\d+\.)\s+|\|)/.test(lines[i])) para.push(lines[i++].trim());
172
+ if (!para.length) { para.push(lines[i++].trim()); }
173
+ out.push(`<p>${inline(para.join(' '))}</p>`);
174
+ }
175
+ return out.join('\n');
176
+ }
177
+
178
+ /** Plain words from Markdown, for descriptions and feeds. */
179
+ export function plainText(md) {
180
+ return md
181
+ .replace(/!\[[^\]]*\]\([^)]+\)/g, '')
182
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
183
+ .replace(/\*\*(.+?)\*\*/g, '$1')
184
+ .replace(/(^|[^\w*])\*(?!\s)(.+?)\*(?!\w)/g, '$1$2')
185
+ .replace(/`([^`]+)`/g, '$1')
186
+ .replace(/\s+/g, ' ')
187
+ .trim();
188
+ }
@@ -0,0 +1,311 @@
1
+ // The website's numbers and news, from files in this repository: used by
2
+ // scripts/build-site.mjs, which builds the site (see site/README.md).
3
+ //
4
+ // Where each number comes from, so every one of them can be checked:
5
+ // - releases, their dates, what each changed: CHANGELOG.md's "## [x.y.z] - date"
6
+ // headings and the top-level bullets under their "### Added/Changed/…" headings.
7
+ // A pre-release (x.y.z-beta.n) is folded into the full release it became;
8
+ // one that hasn't become a full release yet isn't counted.
9
+ // - tests: every line starting "test(" in tests/*.test.mjs, which is what
10
+ // `npm test` counts.
11
+ // - the sample network: public/demo-data.json, the invented network that ships
12
+ // with the app (read only; scripts/gen-synthetic.mjs makes it).
13
+ //
14
+ // In site/index.html each generated part sits between <!-- gen:NAME --> and
15
+ // <!-- /gen:NAME -->; everything else on the page is written by hand.
16
+
17
+ import { readFileSync, readdirSync } from 'node:fs';
18
+ import path from 'node:path';
19
+
20
+ const REPO_URL = 'https://github.com/blakeb056/six-degrees';
21
+ const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
22
+ 'August', 'September', 'October', 'November', 'December'];
23
+ const KINDS = ['added', 'changed', 'fixed', 'removed', 'security', 'deprecated'];
24
+ // Which bullets make the headline: new things first, then changes, then fixes.
25
+ const LEAD_ORDER = ['added', 'changed', 'fixed', 'security', 'removed', 'deprecated'];
26
+ export const NEWS_POSTS = 4;
27
+
28
+ const escapeHtml = (s) => String(s)
29
+ .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
30
+
31
+ /** "2026-09-29" → "29 September 2026". */
32
+ export function longDate(iso) {
33
+ const [y, m, d] = iso.split('-').map(Number);
34
+ return `${d} ${MONTHS[m - 1]} ${y}`;
35
+ }
36
+
37
+ /** Markdown inline marks and links dropped: plain words. */
38
+ export function plainText(md) {
39
+ return md
40
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
41
+ .replace(/\*\*(.+?)\*\*/g, '$1')
42
+ .replace(/(^|[^\w*])\*(?!\s)(.+?)\*(?!\w)/g, '$1$2')
43
+ .replace(/`([^`]+)`/g, '$1')
44
+ .replace(/\s+/g, ' ')
45
+ .trim();
46
+ }
47
+
48
+ /**
49
+ * A bullet's bold lead-in ("**Names on or off** for the Galaxy" → "Names on or
50
+ * off"), tidied for a headline: no trailing full stop or colon, and a bracket
51
+ * kept only when it says the thing is experimental. Null when it has none.
52
+ */
53
+ export function leadOf(bullet) {
54
+ const m = bullet.match(/^\*\*(.+?)\*\*/);
55
+ if (!m) return null;
56
+ let lead = plainText(m[1]);
57
+ lead = lead.replace(/\s*\(([^)]*)\)/g, (_, inner) => (/experimental/i.test(inner) ? ' (experimental)' : ''));
58
+ return lead.replace(/[\s.:,;]+$/, '').trim() || null;
59
+ }
60
+
61
+ /**
62
+ * CHANGELOG.md as releases, newest first:
63
+ * { version, date, prerelease, intro, bullets: [{ kind, text }] }
64
+ * Only "## [x.y.z] - YYYY-MM-DD" headings count ("Unreleased" has no date).
65
+ */
66
+ export function parseChangelog(md) {
67
+ const releases = [];
68
+ let release = null;
69
+ let kind = null;
70
+ let bullet = null;
71
+ const end = () => { bullet = null; };
72
+ for (const line of md.split('\n')) {
73
+ const head = line.match(/^## \[(\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?)\] - (\d{4}-\d{2}-\d{2})/);
74
+ if (head) {
75
+ release = { version: head[1], date: head[2], prerelease: head[1].includes('-'), intro: '', bullets: [], body: '' };
76
+ releases.push(release);
77
+ kind = null;
78
+ end();
79
+ continue;
80
+ }
81
+ if (/^## /.test(line)) { release = null; kind = null; end(); continue; }
82
+ if (!release) continue;
83
+ release.body += `${line}\n`;
84
+ const sub = line.match(/^### (\w+)/);
85
+ if (sub) { kind = sub[1].toLowerCase(); end(); continue; }
86
+ if (!kind) {
87
+ if (line.trim()) release.intro = `${release.intro} ${line.trim()}`.trim();
88
+ continue;
89
+ }
90
+ if (/^- /.test(line)) {
91
+ bullet = { kind, text: line.slice(2).trim() };
92
+ release.bullets.push(bullet);
93
+ } else if (bullet && /^\s+\S/.test(line) && !/^\s+- /.test(line)) {
94
+ bullet.text += ` ${line.trim()}`;
95
+ } else if (/^\S/.test(line)) {
96
+ end();
97
+ }
98
+ }
99
+ return releases;
100
+ }
101
+
102
+ /**
103
+ * Full releases, newest first, each with its pre-releases folded in (what
104
+ * 0.4.0-beta.1 added shipped to everyone in 0.4.0). A pre-release that hasn't
105
+ * become a full release yet is left out: the site describes full releases.
106
+ */
107
+ export function fullReleases(releases) {
108
+ const full = releases.filter((r) => !r.prerelease).map((r) => ({ ...r, betas: [] }));
109
+ const byVersion = new Map(full.map((r) => [r.version, r]));
110
+ for (const r of releases) {
111
+ if (!r.prerelease) continue;
112
+ const parent = byVersion.get(r.version.split('-')[0]);
113
+ if (parent) parent.betas.push(r);
114
+ }
115
+ return full;
116
+ }
117
+
118
+ /** How many top-level bullets a release (and its betas) has of each kind. */
119
+ export function changeCounts(release) {
120
+ const counts = {};
121
+ for (const b of [release, ...(release.betas || [])].flatMap((r) => r.bullets)) {
122
+ const k = KINDS.includes(b.kind) ? b.kind : 'changed';
123
+ counts[k] = (counts[k] || 0) + 1;
124
+ }
125
+ return counts;
126
+ }
127
+
128
+ /** A post's headline and up to three more highlights, from bold lead-ins. */
129
+ export function highlights(release, more = 3) {
130
+ const all = [release, ...(release.betas || [])].flatMap((r) => r.bullets);
131
+ const ordered = LEAD_ORDER.flatMap((k) => all.filter((b) => b.kind === k));
132
+ const leads = [...new Set(ordered.map((b) => leadOf(b.text)).filter(Boolean))];
133
+ let title = leads.shift();
134
+ if (!title) {
135
+ const first = ordered[0] ? plainText(ordered[0].text) : `Six Degrees ${release.version}`;
136
+ title = first.length > 90 ? `${first.slice(0, 90).replace(/\s+\S*$/, '')}…` : first.replace(/[.:]$/, '');
137
+ }
138
+ return { title, more: leads.slice(0, more) };
139
+ }
140
+
141
+ const releaseUrl = (version) => `${REPO_URL}/releases/tag/v${version}`;
142
+
143
+ function chips(counts) {
144
+ const items = KINDS.filter((k) => counts[k]).map((k) => `<li class="k-${k}">${counts[k]} ${k}</li>`);
145
+ return `<ul class="chips" aria-label="What changed">${items.join('')}</ul>`;
146
+ }
147
+
148
+ export function newsHtml(full, count = NEWS_POSTS) {
149
+ const posts = full.slice(0, count).map((r, i) => {
150
+ const { title, more } = highlights(r);
151
+ const also = more.length ? `\n <p class="post-more">Also: ${more.map(escapeHtml).join(' · ')}</p>` : '';
152
+ const latest = i === 0 ? '<span class="tag latest">Latest</span>' : '';
153
+ return ` <article class="post${i === 0 ? ' featured' : ''}">
154
+ <p class="post-meta"><time datetime="${r.date}">${longDate(r.date)}</time><span class="tag">v${escapeHtml(r.version)}</span>${latest}</p>
155
+ <h3><a href="${releaseUrl(r.version)}">${escapeHtml(title)}</a></h3>${also}
156
+ ${chips(changeCounts(r))}
157
+ <a class="more" href="${releaseUrl(r.version)}">Release notes<span class="sr-only"> for ${escapeHtml(r.version)}</span> →</a>
158
+ </article>`;
159
+ });
160
+ return `\n${posts.join('\n')}\n `;
161
+ }
162
+
163
+ const round = (n) => Math.round(n * 100) / 100;
164
+
165
+ /**
166
+ * Columns of stacked bars as an SVG that stretches to its box (no text inside,
167
+ * so nothing distorts), each column with a tooltip. The labels are HTML beside it.
168
+ */
169
+ export function columnSvg(columns, { label, max = Math.max(1, ...columns.map((c) => c.parts.reduce((s, p) => s + p.value, 0))) } = {}) {
170
+ const H = 100;
171
+ const step = 10;
172
+ const barW = 7;
173
+ const bars = columns.map((c, i) => {
174
+ let below = 0;
175
+ const x = round(i * step + (step - barW) / 2);
176
+ const rects = c.parts.filter((p) => p.value > 0).map((p) => {
177
+ const top = Math.max(0, H - ((below + p.value) / max) * H);
178
+ const bottom = H - (below / max) * H;
179
+ below += p.value;
180
+ return `<rect class="${p.cls}" x="${x}" y="${round(top)}" width="${barW}" height="${round(bottom - top)}"/>`;
181
+ }).join('');
182
+ return `<g><title>${escapeHtml(c.title)}</title>${rects}</g>`;
183
+ }).join('');
184
+ return `<svg class="bars" viewBox="0 0 ${columns.length * step} ${H}" preserveAspectRatio="none" role="img" aria-label="${escapeHtml(label)}">${bars}</svg>`;
185
+ }
186
+
187
+ function labelRow(labels) {
188
+ return `<ol class="bar-labels" aria-hidden="true">${labels.map((l) => `<li>${l ? escapeHtml(l) : ''}</li>`).join('')}</ol>`;
189
+ }
190
+
191
+ /** Every full release, oldest to newest, by how many changes of each kind. */
192
+ export function releaseChartHtml(full) {
193
+ const oldestFirst = [...full].reverse();
194
+ const columns = oldestFirst.map((r) => {
195
+ const c = changeCounts(r);
196
+ const total = KINDS.reduce((s, k) => s + (c[k] || 0), 0);
197
+ const parts = KINDS.map((k) => ({ value: c[k] || 0, cls: `k-${k}` }));
198
+ const said = KINDS.filter((k) => c[k]).map((k) => `${c[k]} ${k}`).join(', ');
199
+ return { parts, title: `${r.version} · ${longDate(r.date)}: ${total} changes (${said})` };
200
+ });
201
+ const total = full.reduce((s, r) => s + Object.values(changeCounts(r)).reduce((a, b) => a + b, 0), 0);
202
+ // The first and the newest only: at phone width the columns are too narrow to name more.
203
+ const labels = oldestFirst.map((r, i) => (i === 0 || i === oldestFirst.length - 1 ? `${r.version} · ${longDate(r.date).replace(/ (\w{3})\w* \d{4}$/, ' $1')}` : ''));
204
+ const svg = columnSvg(columns, {
205
+ label: `Changes per release, ${oldestFirst.length} releases from ${oldestFirst[0].version} to ${full[0].version}, ${total} in all`,
206
+ });
207
+ return `\n ${svg}\n ${labelRow(labels)}\n `;
208
+ }
209
+
210
+ /** The sample network's shape: who's two steps away, and through how many of your connections. */
211
+ export function sampleStats(data) {
212
+ const byPerson = new Map();
213
+ for (const p of data.degree2 || []) {
214
+ const key = p.profile_url || p.id || p.name;
215
+ if (!byPerson.has(key)) byPerson.set(key, new Set());
216
+ byPerson.get(key).add(p.source_connection_id);
217
+ }
218
+ const ways = { one: 0, two: 0, more: 0 };
219
+ const only = new Map(); // connection → people only they reach
220
+ for (const sources of byPerson.values()) {
221
+ if (sources.size === 1) {
222
+ ways.one += 1;
223
+ const [via] = sources;
224
+ only.set(via, (only.get(via) || 0) + 1);
225
+ } else if (sources.size === 2) ways.two += 1;
226
+ else ways.more += 1;
227
+ }
228
+ const bridges = new Set((data.degree2 || []).map((p) => p.source_connection_id)).size;
229
+ return {
230
+ connections: (data.degree1 || []).length,
231
+ degree2: byPerson.size,
232
+ bridges,
233
+ ways,
234
+ exclusive: [...only.values()].sort((a, b) => b - a),
235
+ };
236
+ }
237
+
238
+ export function exclusiveChartHtml(s) {
239
+ const columns = s.exclusive.map((n, i) => ({
240
+ parts: [{ value: n, cls: i === 0 ? 'k-top' : 'k-bridge' }],
241
+ title: `Connection ${i + 1}: ${n} people only they reach`,
242
+ }));
243
+ const svg = columnSvg(columns, {
244
+ label: `The ${s.exclusive.length} connections with a scanned circle in the sample network, by how many people only they reach: from ${s.exclusive[0]} down to ${s.exclusive.at(-1)}`,
245
+ });
246
+ return `\n ${svg}\n ${labelRow(s.exclusive.map(String))}\n `;
247
+ }
248
+
249
+ export function waysBarHtml(s) {
250
+ const total = s.degree2 || 1;
251
+ const parts = [['one', 'k-one'], ['two', 'k-two'], ['more', 'k-more']];
252
+ let x = 0;
253
+ const rects = parts.map(([k, cls]) => {
254
+ const w = round((s.ways[k] / total) * 100);
255
+ const r = `<rect class="${cls}" x="${round(x)}" y="0" width="${w}" height="10"/>`;
256
+ x += w;
257
+ return r;
258
+ }).join('');
259
+ const label = `Of ${s.degree2} people two steps away: ${s.ways.one} through one connection only, ${s.ways.two} through two, ${s.ways.more} through three or more`;
260
+ return `<svg class="stack" viewBox="0 0 100 10" preserveAspectRatio="none" role="img" aria-label="${label}">${rects}</svg>`;
261
+ }
262
+
263
+ /** Every test the suite runs: node:test's test( calls, one per line, in tests/*.test.mjs. */
264
+ export function countTests(testsDir) {
265
+ let n = 0;
266
+ for (const f of readdirSync(testsDir)) {
267
+ if (!f.endsWith('.test.mjs')) continue;
268
+ n += (readFileSync(path.join(testsDir, f), 'utf8').match(/^test\(/gm) || []).length;
269
+ }
270
+ return n;
271
+ }
272
+
273
+ const thousands = (n) => n.toLocaleString('en-US');
274
+ const percent = (a, b) => `${Math.round((a / b) * 100)}%`;
275
+
276
+ /** Everything the page's <!-- gen:NAME --> slots get, by name. */
277
+ export function generate({ changelog, testCount, sample }) {
278
+ const full = fullReleases(parseChangelog(changelog));
279
+ if (!full.length) throw new Error('CHANGELOG.md has no "## [x.y.z] - YYYY-MM-DD" release heading.');
280
+ const latest = full[0];
281
+ const first = full.at(-1);
282
+ const s = sampleStats(sample);
283
+ return {
284
+ 'latest-version': escapeHtml(latest.version),
285
+ 'latest-date': `<time datetime="${latest.date}">${longDate(latest.date)}</time>`,
286
+ 'release-count': String(full.length),
287
+ 'first-release': `<time datetime="${first.date}">${longDate(first.date)}</time>`,
288
+ 'change-count': thousands(full.reduce((sum, r) => sum + Object.values(changeCounts(r)).reduce((a, b) => a + b, 0), 0)),
289
+ 'test-count': thousands(testCount),
290
+ news: newsHtml(full),
291
+ 'release-chart': releaseChartHtml(full),
292
+ 'sample-connections': thousands(s.connections),
293
+ 'sample-degree2': thousands(s.degree2),
294
+ 'sample-bridges': String(s.bridges),
295
+ 'sample-one-way': thousands(s.ways.one),
296
+ 'sample-one-way-share': percent(s.ways.one, s.degree2),
297
+ 'sample-two-way': thousands(s.ways.two),
298
+ 'sample-more-way': thousands(s.ways.more),
299
+ 'sample-top-exclusive': String(s.exclusive[0] ?? 0),
300
+ 'sample-ways-bar': waysBarHtml(s),
301
+ 'sample-exclusive-chart': exclusiveChartHtml(s),
302
+ };
303
+ }
304
+
305
+ /** The page with every gen slot filled; throws on a slot nothing fills. */
306
+ export function fill(html, values) {
307
+ return html.replace(/<!-- gen:([a-z0-9-]+) -->([\s\S]*?)<!-- \/gen:\1 -->/g, (_, name) => {
308
+ if (!(name in values)) throw new Error(`a page has a slot nothing fills: gen:${name}`);
309
+ return `<!-- gen:${name} -->${values[name]}<!-- /gen:${name} -->`;
310
+ });
311
+ }
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,40643,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(22016),a=e.i(40996),o=e.i(68792);let l={full:"Scanning your network",refresh:"Checking for new connections",bridge:"Scanning a circle",resume:"Carrying on with a circle","resume-all":"Carrying on with circles","auto-bridge":"Auto-Bridge","auto-bridge-retry":"Auto-Bridge",rescrape:"Re-scanning a circle",login:"Signing in to LinkedIn",setup:"Setting up the scanner",company:"Scanning a company",photos:"Saving photos",messages:"Reading your messages list"};e.s(["default",0,function(){let e,u,[i,s]=(0,r.useState)(()=>(0,a.scannerNow)()),[c,d]=(0,r.useState)(!1),f=(0,r.useSyncExternalStore)(o.watchAllDay,o.allDayNow,()=>!1);(0,r.useEffect)(()=>(0,a.watchScanner)(()=>{let e=(0,a.scannerNow)();s(e),e.running||d(!1)}),[]);let p={position:"fixed",left:"50%",top:"var(--scan-bar-top, 94px)",transform:"translateX(-50%)",zIndex:60,maxWidth:"calc(100vw - 32px)",display:"flex",alignItems:"center",gap:12,flexWrap:"nowrap",whiteSpace:"nowrap",padding:"8px 12px",borderRadius:12,fontSize:12,color:"#cfd8d8",background:"rgba(14,16,32,0.94)"};if(!i?.running)return f?(0,t.jsxs)("div",{role:"status",style:{...p,opacity:.55,border:"1px solid rgba(255,255,255,0.1)"},children:[(0,t.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:"#556",flexShrink:0}}),(0,t.jsx)("b",{style:{color:"#b8c4c4"},children:"Auto scan"}),(0,t.jsx)("span",{style:{color:"#8b9a9a"},children:"ready · press Auto scan beside Scan to start"})]}):null;let h=i.progress,g=h?.kind==="batch"&&h.total?`${h.current||h.done||0} of ${h.total}`:h?.kind==="walk"&&h.total?`${(h.done||0).toLocaleString()} of ${h.total.toLocaleString()} read`:h?.kind==="saving"?"saving":null,y=i.budget,m=[...i.log||[]].reverse().find(e=>e&&e.trim())?.trim();return(0,t.jsxs)("div",{role:"status","aria-live":"polite",style:{...p,border:"1px solid rgba(0,255,136,0.25)"},children:[(0,t.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:"#00ff88",flexShrink:0}}),(0,t.jsx)("b",{style:{color:"#fff"},children:l[i.action]||"Scanning"}),i.target?.name&&(0,t.jsx)("span",{children:i.target.name}),g&&(0,t.jsx)("span",{style:{color:"#8b9a9a"},children:g}),y&&(0,t.jsxs)("span",{style:{color:(e=y.searches,(u=y.cap)?e/u>=.9?"#ff6b6b":e/u>=.6?"#FFD700":"#00ff88":"#8b9a9a")},title:"Searches on your LinkedIn account in the last 24 hours, and your daily budget",children:[y.searches,y.cap?` of ${y.cap}`:""," searches today"]}),m&&(0,t.jsx)("span",{style:{color:"#667",flex:"0 1 240px",minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:m,children:m}),(0,t.jsx)(n.default,{href:"/setup",style:{color:"#3498DB",textDecoration:"none"},children:"Details"}),(0,t.jsx)("button",{onClick:async()=>{d(!0);try{await (0,a.stopScrape)()}catch{d(!1)}},disabled:c,title:"Stops after saving what's been read; Resume on the Scan page carries on from the same page",style:{padding:"4px 10px",borderRadius:8,fontSize:12,cursor:c?"default":"pointer",background:"rgba(255,107,107,0.12)",color:"#ff9b9b",border:"1px solid rgba(255,107,107,0.35)"},children:c?"Stopping…":"Stop"})]})}])},87915,e=>{"use strict";var t=e.i(71645),r=e.i(40996),n=e.i(64745);let a=!1;e.s(["default",0,function(){return(0,t.useEffect)(()=>{if(n.IS_DEMO||a)return;let e=()=>{};return fetch("/api/social").then(e=>e.json()).then(({social:t})=>{if(!t?.autoSync||a)return;let n=t.liveAt?Date.parse(t.liveAt):0,o=new Date().getHours();Date.now()-n<864e5||o<9||o>=19||(e=(0,r.watchScanner)(()=>{let t=(0,r.scannerNow)();t.known&&!a&&(a=!0,e(),t.running||(0,r.beginScrape)("messages").catch(()=>{}))}))}).catch(()=>{}),()=>e()},[]),null}])},37711,e=>{"use strict";var t=e.i(43476),r=e.i(71645);e.s(["default",0,function(){let[e,n]=(0,r.useState)(null);return((0,r.useEffect)(()=>{let e=!0;return fetch("/api/update").then(e=>e.json()).then(t=>{e&&t?.restartNeeded&&n(t)}).catch(()=>{}),()=>{e=!1}},[]),e)?(0,t.jsxs)("div",{role:"status",style:{position:"fixed",left:0,right:0,bottom:0,zIndex:9999,background:"linear-gradient(90deg, #FFD700, #FF6B35)",color:"#1a1200",padding:"9px 16px",fontSize:13,fontWeight:600,lineHeight:1.5,display:"flex",alignItems:"center",justifyContent:"center",gap:10,flexWrap:"wrap",textAlign:"center"},children:[(0,t.jsxs)("span",{children:["You have newer code on disk (",e.sha,") than this server is running (",e.bootSha,"). Restart it to see the changes — ",(0,t.jsx)("code",{style:{background:"rgba(0,0,0,0.16)",padding:"1px 6px",borderRadius:4},children:"Ctrl-C"})," in the terminal, then ",(0,t.jsx)("code",{style:{background:"rgba(0,0,0,0.16)",padding:"1px 6px",borderRadius:4},children:"npm run dev"}),"."]}),(0,t.jsx)("button",{onClick:()=>n(null),style:{border:"none",background:"rgba(0,0,0,0.18)",color:"#1a1200",borderRadius:6,padding:"3px 10px",fontWeight:700,cursor:"pointer"},children:"Dismiss"})]}):null}])},15812,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(65084),a=e.i(64745),o=e.i(7837);let l=(0,r.createContext)({userId:null,userName:null,userProfile:null,ready:!1});e.s(["default",0,function({children:e}){let[u,i]=(0,r.useState)(null),[s,c]=(0,r.useState)(null),[d,f]=(0,r.useState)(null),[p,h]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{if(a.IS_DEMO){i(a.DEMO_USER.id),c(a.DEMO_USER.name),f({name:a.DEMO_USER.name,headline:a.DEMO_USER.headline,role:"",company:"",industry:"",sectors:[],goals:[],linkedin_url:""}),h(!0);return}if((0,o.hasCsvNetwork)()){i(o.CSV_USER.id),c(o.CSV_USER.name),f({name:o.CSV_USER.name,headline:"Imported from your LinkedIn CSV",role:"",company:"",industry:"",sectors:[],goals:[],linkedin_url:""}),h(!0);return}fetch("/api/users?me=1").then(e=>e.json()).then(e=>{let t=e.user;if(!t)throw Error("no profile");(0,n.setUser)(t.id,t.name),i(t.id),c(t.name),f({name:t.name,headline:t.headline||"",role:t.role||"",company:t.company||"",industry:t.industry||"",sectors:t.sectors||[],goals:t.goals||[],linkedin_url:t.linkedin_url||""})}).catch(()=>{(0,n.hasUser)()&&(i((0,n.getUserId)()),c((0,n.getUserName)()))}).finally(()=>h(!0))},[]),(0,t.jsx)(l.Provider,{value:{userId:u,userName:s,userProfile:d,ready:p,login:(e,t)=>{(0,n.setUser)(e,t),i(e),c(t),fetch(`/api/users?id=${e}`).then(e=>e.json()).then(e=>{e.user&&f({name:e.user.name,headline:e.user.headline||"",role:e.user.role||"",company:e.user.company||"",industry:e.user.industry||"",sectors:e.user.sectors||[],goals:e.user.goals||[],linkedin_url:e.user.linkedin_url||""})}).catch(()=>{})}},children:e})},"useUser",0,function(){return(0,r.useContext)(l)}])},64745,e=>{"use strict";var t=e.i(47167),r=e.i(7837);let n="true"===t.default.env.NEXT_PUBLIC_DEMO_MODE,a=null;async function o(){if(a)return a;let e=await fetch("/demo-data.json",{cache:"no-cache"});if(!e.ok)throw Error("demo-data.json not found — run: node scripts/gen-synthetic.mjs");let t=await e.json();return a={degree1:t.degree1||[],degree2:t.degree2||[]}}async function l(){let e=await o();return(0,r.saveSessionNetwork)({degree1:e.degree1,degree2:e.degree2,source:"sample"}),{degree1:e.degree1.length,degree2:e.degree2.length}}e.s(["DEMO_USER",0,{id:"synthetic-demo-user",name:"You",headline:"Sample network"},"IS_DEMO",0,n,"loadDemoNetwork",0,o,"loadSampleIntoSession",0,l])},68792,e=>{"use strict";var t=e.i(40996);let r=(e,t)=>{try{let r=localStorage.getItem(e);return null===r?t:JSON.parse(r)}catch{return t}};e.s(["allDayNow",0,function(){try{return"true"===localStorage.getItem("six-degrees-experimental-auto")}catch{return!1}},"startAutoScan",0,function(){let e=r("six-degrees-bridge-order","newest");return(0,t.beginScrape)("auto-bridge",{experimental:!0,maxBridges:10,order:e,tiers:"score"===e?["S","A"]:[],maxPages:r("six-degrees-bridge-pages-v2",100),deeper:r("six-degrees-bridge-finish",!0)})},"watchAllDay",0,function(e){return window.addEventListener("storage",e),window.addEventListener("six-degrees:experimental",e),()=>{window.removeEventListener("storage",e),window.removeEventListener("six-degrees:experimental",e)}}])},40996,e=>{"use strict";async function t(){let e=await fetch("/api/scraper");if(!e.ok)throw Error("Could not reach the app.");return e.json()}async function r(e,t,n={}){let a=await fetch("/api/scraper",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:e,...t?{name:t}:{},...n})}),o=await a.json().catch(()=>({}));if(!a.ok)throw Error(o.error||"Could not start the scanner.");return o}async function n(e){let t=await fetch(`/api/scraper?resume=${encodeURIComponent(e)}`);return t.ok?(await t.json()).resume??null:null}Symbol.for("six-degrees.scan-state");let a=Object.freeze({skips:[],read:[]});async function o(){try{let e=await fetch("/api/scraper?reach=1");if(!e.ok)return a;let t=await e.json();return{skips:Array.isArray(t.skips)?t.skips:[],read:Array.isArray(t.read)?t.read:[]}}catch{return a}}async function l(e){let t=await fetch(`/api/scraper?person=${encodeURIComponent(e)}`);return t.ok?t.json():{person:null}}async function u(){await fetch("/api/scraper",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"cancel"})})}let i=Object.freeze({known:!1,running:!1,pending:!1,action:null,target:null,startedAt:null,progress:null,log:[],finished:[]}),s=new Set,c=i,d=JSON.stringify(c),f=null,p=null,h=0,g=!1,y=new Set;function m(e){let t=JSON.stringify(e);if(t!==d)for(let r of(d=t,c=Object.freeze(e),[...s]))r()}async function b(){(!("u">typeof document&&document.hidden)||c.running)&&await function(){if(p&&p.epoch===h)return p.promise;let e=h,t=fetch("/api/scraper?job=1").then(e=>e.ok?e.json():null).then(t=>{e===h&&function(e){if(!e||"object"!=typeof e)return;let t=!0===e.running;t&&null!=e.startedAt&&y.add(e.startedAt);let r=(Array.isArray(e.recent)?e.recent:[]).filter(e=>y.has(e.startedAt)).map(r=>({...r,log:!t&&r.startedAt===e.startedAt&&Array.isArray(e.log)?e.log:[]}));m({known:!0,running:t||g,pending:g&&!t,action:t?e.action??null:g?c.action:null,target:t?e.target??null:g?c.target:null,startedAt:t?e.startedAt??null:null,progress:t?e.progress??null:null,budget:t?e.budget??null:null,log:t&&Array.isArray(e.log)?e.log:[],finished:r})}(t)}).catch(()=>{}).finally(()=>{p?.promise===t&&(p=null)});return p={epoch:e,promise:t},t}(),clearTimeout(f),f=s.size?setTimeout(b,c.running?1500:5e3):null}function v(e){return s.add(e),1===s.size&&b(),()=>{s.delete(e),s.size||(clearTimeout(f),f=null)}}async function _(e,{name:t,id:n,onLog:a,...o}={}){let l;h++,g=!0,m({...c,known:!0,running:!0,pending:!0,action:e,target:t||n?{id:n??null,name:t??null}:null,startedAt:null,progress:null,log:[]});try{let a=!1;try{a=!0===JSON.parse(localStorage.getItem("six-degrees-hide-chrome")||"false")}catch{}l=await r(e,t,{...n?{id:n}:{},...a?{headless:!0}:{},...o})}catch(e){throw g=!1,h++,c.pending&&m({...c,running:!1,pending:!1,action:null,target:null,log:[]}),b(),e}g=!1,h++;let u=l?.startedAt??null;null!=u&&y.add(u);let i=new Promise(e=>{let t=v(()=>{c.running&&c.startedAt===u&&a?.(c.log);let r=null==u?c.running?null:{exitCode:null,failure:null,log:[]}:c.finished.find(e=>e.startedAt===u);r&&(t(),r.log.length&&a?.(r.log),e(r))});b()});return{startedAt:u,ended:i}}function S(e){return!!e?.target&&["bridge","rescrape","resume"].includes(e.action)}e.s(["NO_SCAN_NOTES",0,a,"SCANNER_UNKNOWN",0,i,"beginScrape",0,_,"busyReason",0,function(e=c){if(!e?.running)return null;let t=e.target?.name;switch(e.action){case"bridge":case"rescrape":case"resume":return t?`${t}’s circle is being scanned`:"A circle is being scanned";case"company":return t?`${t} is being scanned`:"A company is being scanned";case"auto-bridge":case"auto-bridge-retry":case"resume-all":return"Your bridges are being mapped, one by one";case"full":case"refresh":return"Your own connections are being scanned";default:switch(e.action){case"install":return"The scanner's packages are being installed";case"setup":return"The scanner is being set up";case"login":return"The LinkedIn sign-in window is open";case"photos":return"Profile photos are being saved";default:return"A scan is running"}}},"isCircleScan",0,S,"loadScanNotes",0,o,"notReadyMessage",0,function(e){if(!e)return"Could not reach the app.";let t=e.checks||{};return t.scriptsFound?t.dependencies?t.chrome?null:"Google Chrome is not installed.":t.python||t.download?"The scanner is not set up yet — open Scan to set it up.":"No Python 3.10 to 3.14 is installed on this machine.":"The scanner files are missing from this install."},"pickedPerson",0,l,"resumePoint",0,n,"runScrape",0,function(e,t={}){return _(e,t).then(e=>e.ended)},"scannerNow",0,function(){return c},"scansCircleOf",0,function(e,t){if(!S(e)||!t)return!1;let{id:r,name:n}=e.target;return r&&t.id?r===t.id:!!n&&n===t.name},"scraperStatus",0,t,"stopScrape",0,u,"watchScanner",0,v],40996)},22016,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={default:function(){return m},useLinkStatus:function(){return v}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(90809),l=e.r(43476),u=o._(e.r(71645)),i=e.r(95057),s=e.r(8372),c=e.r(18581),d=e.r(18967),f=e.r(5550),p=e.r(88540),h=e.r(91949),g=e.r(73668),y=e.r(9396);function m(t){var r;let n,a,o,[m,v]=(0,u.useOptimistic)(h.IDLE_LINK_STATUS),_=(0,u.useRef)(null),{href:S,as:j,children:x,prefetch:P=null,passHref:O,replace:C,shallow:w,scroll:E,onClick:R,onMouseEnter:T,onTouchStart:N,legacyBehavior:A=!1,onNavigate:k,transitionTypes:M,ref:D,unstable_dynamicOnHover:F,...L}=t;n=x,A&&("string"==typeof n||"number"==typeof n)&&(n=(0,l.jsx)("a",{children:n}));let I=u.default.useContext(s.AppRouterContext),U=!1!==P,B=!1===P?"none":!0===P?"full":"auto",$="none"!==B?"auto"===B?y.FetchStrategy.PPR:y.FetchStrategy.Full:y.FetchStrategy.PPR,H="string"==typeof(r=j||S)?r:(0,i.formatUrl)(r);if(A){if(n?.$$typeof===Symbol.for("react.lazy"))throw Object.defineProperty(Error("`<Link legacyBehavior>` received a direct child that is either a Server Component, or JSX that was loaded with React.lazy(). This is not supported. Either remove legacyBehavior, or make the direct child a Client Component that renders the Link's `<a>` tag."),"__NEXT_ERROR_CODE",{value:"E863",enumerable:!1,configurable:!0});a=u.default.Children.only(n)}let z=A?a&&"object"==typeof a&&a.ref:D,V,K=u.default.useCallback(e=>(null!==I&&(_.current=(0,h.mountLinkInstance)(e,H,I,$,U,v,V)),()=>{_.current&&((0,h.unmountLinkForCurrentNavigation)(_.current),_.current=null),(0,h.unmountPrefetchableInstance)(e)}),[U,H,I,$,v,V]),W={ref:(0,c.useMergedRef)(K,z),onClick(t){A||"function"!=typeof R||R(t),A&&a.props&&"function"==typeof a.props.onClick&&a.props.onClick(t),!I||t.defaultPrevented||function(t,r,n,a,o,l,i,s="none"){if("u">typeof window){let c,{nodeName:d}=t.currentTarget;if("A"===d.toUpperCase()&&((c=t.currentTarget.getAttribute("target"))&&"_self"!==c||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.nativeEvent&&2===t.nativeEvent.which)||t.currentTarget.hasAttribute("download"))return;if(!(0,g.isLocalURL)(r)){a&&(t.preventDefault(),location.replace(r));return}if(t.preventDefault(),l){let e=!1;if(l({preventDefault:()=>{e=!0}}),e)return}let{dispatchNavigateAction:f}=e.r(99781);u.default.startTransition(()=>{f(r,a?"replace":"push",!1===o?p.ScrollBehavior.NoScroll:p.ScrollBehavior.Default,n.current,i,s)})}}(t,H,_,C,E,k,M,B)},onMouseEnter(e){A||"function"!=typeof T||T(e),A&&a.props&&"function"==typeof a.props.onMouseEnter&&a.props.onMouseEnter(e),I&&U&&(0,h.onNavigationIntent)(e.currentTarget,!0===F)},onTouchStart:function(e){A||"function"!=typeof N||N(e),A&&a.props&&"function"==typeof a.props.onTouchStart&&a.props.onTouchStart(e),I&&U&&(0,h.onNavigationIntent)(e.currentTarget,!0===F)}};return(0,d.isAbsoluteUrl)(H)?W.href=H:A&&!O&&("a"!==a.type||"href"in a.props)||(W.href=(0,f.addBasePath)(H)),o=A?u.default.cloneElement(a,W):(0,l.jsx)("a",{...L,...W,children:n}),(0,l.jsx)(b.Provider,{value:m,children:o})}let b=(0,u.createContext)(h.IDLE_LINK_STATUS),v=()=>(0,u.useContext)(b);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},28298,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useRouterBFCache",{enumerable:!0,get:function(){return a}});let n=e.r(71645);function a(e,t,r){let[a,o]=(0,n.useState)(()=>({tree:e,cacheNode:t,stateKey:r,next:null}));if(a.tree===e)return a;let l={tree:e,cacheNode:t,stateKey:r,next:null},u=1,i=a,s=l;for(;null!==i&&u<1;){if(i.stateKey===r){s.next=i.next;break}{u++;let e={tree:i.tree,cacheNode:i.cacheNode,stateKey:i.stateKey,next:null};s.next=e,s=e}i=i.next}return o(l),l}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},47257,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientPageRoot",{enumerable:!0,get:function(){return s}});let n=e.r(43476),a=e.r(8372),o=e.r(71645),l=e.r(33906),u=e.r(61994),i=e.r(15783);function s({Component:e,serverProvidedParams:t}){let r,c;if(null!==t)r=t.searchParams,c=t.params;else{let e=(0,o.use)(a.LayoutRouterContext);c=null!==e?e.parentParams:{},r=(0,l.urlSearchParamsToParsedUrlQuery)((0,o.use)(u.SearchParamsContext))}let d=(0,i.createClientSearchParams)(r),f=(0,i.createClientParams)(c);return(0,n.jsx)(e,{params:f,searchParams:d})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},92825,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientSegmentRoot",{enumerable:!0,get:function(){return u}});let n=e.r(43476),a=e.r(8372),o=e.r(71645),l=e.r(15783);function u({Component:e,slots:t,serverProvidedParams:r}){let i;if(null!==r)i=r.params;else{let e=(0,o.use)(a.LayoutRouterContext);i=null!==e?e.parentParams:{}}let s=(0,l.createClientParams)(i);return(0,n.jsx)(e,{...t,params:s})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},68017,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"HTTPAccessFallbackBoundary",{enumerable:!0,get:function(){return c}});let n=e.r(90809),a=e.r(43476),o=n._(e.r(71645)),l=e.r(90373),u=e.r(54394),i=e.r(8372);class s extends o.default.Component{constructor(e){super(e),this.state={triggeredStatus:void 0,previousPathname:e.pathname}}componentDidCatch(){}static getDerivedStateFromError(e){if((0,u.isHTTPAccessFallbackError)(e))return{triggeredStatus:(0,u.getAccessFallbackHTTPStatus)(e)};throw e}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.triggeredStatus?{triggeredStatus:void 0,previousPathname:e.pathname}:{triggeredStatus:t.triggeredStatus,previousPathname:e.pathname}}render(){let{notFound:e,forbidden:t,unauthorized:r,children:n}=this.props,{triggeredStatus:o}=this.state,l={[u.HTTPAccessErrorStatus.NOT_FOUND]:e,[u.HTTPAccessErrorStatus.FORBIDDEN]:t,[u.HTTPAccessErrorStatus.UNAUTHORIZED]:r};if(o){let i=o===u.HTTPAccessErrorStatus.NOT_FOUND&&e,s=o===u.HTTPAccessErrorStatus.FORBIDDEN&&t,c=o===u.HTTPAccessErrorStatus.UNAUTHORIZED&&r;return i||s||c?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("meta",{name:"robots",content:"noindex"}),!1,l[o]]}):n}return n}}function c({notFound:e,forbidden:t,unauthorized:r,children:n}){let u=(0,l.useUntrackedPathname)(),d=(0,o.useContext)(i.MissingSlotContext);return e||t||r?(0,a.jsx)(s,{pathname:u,notFound:e,forbidden:t,unauthorized:r,missingSlots:d,children:n}):(0,a.jsx)(a.Fragment,{children:n})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},22976,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return o},PlaceValidationBoundaryBelowThisLevel:function(){return l},RenderValidationBoundaryAtThisLevel:function(){return u},SlotMarker:function(){return i}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=null,l=null,u=null,i=null;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},77694,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return o.InstantValidationBoundaryContext},PlaceValidationBoundaryBelowThisLevel:function(){return o.PlaceValidationBoundaryBelowThisLevel},RenderValidationBoundaryAtThisLevel:function(){return o.RenderValidationBoundaryAtThisLevel},SlotMarker:function(){return o.SlotMarker}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(22976);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},39756,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={LoadingBoundaryProvider:function(){return O},default:function(){return w}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(55682),l=e.r(90809),u=e.r(43476),i=l._(e.r(71645)),s=o._(e.r(74080)),c=e.r(8372),d=e.r(1244),f=e.r(72383),p=e.r(91915),h=e.r(58442),g=e.r(68017);e.r(77694);let y=e.r(70725),m=e.r(28298);e.r(74180);let b=e.r(61994),v=e.r(33906),_=e.r(95871);s.default.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function S(e,t,r){let n=e.getClientRects();if(0===n.length)return 0;let a=1/0;for(let e=0;e<n.length;e++){let t=n[e];t.top<a&&(a=t.top)}return a>=r()&&a<=t?1:2}i.default.Component;let j=function(e){let t=i.default.useRef(null);return(0,i.useLayoutEffect)(()=>{let{focusAndScrollRef:r,cacheNode:n}=e,a=r.forceScroll?r.scrollRef:n.scrollRef;if(null===a||!a.current)return;let o=null,l=r.hashFragment;if(l){var u;if(null===(o="top"===(u=l)?document.body:document.getElementById(u)??document.getElementsByName(u)[0]??null)){a.current=!1,r.onlyHashChange=!1,r.hashFragment=null;return}}else o=t.current;if(null===o)return;let i=!1;(0,p.disableSmoothScrollDuringRouteTransition)(()=>{let e=document.documentElement,t=null,r=null,n=null,u=()=>{var r,a;let o,l;return null===n&&(r=e,a=t,n=!Number.isFinite(l=Number.parseFloat(o=getComputedStyle(r).scrollPaddingTop))||l<0?0:o.endsWith("px")?l:o.endsWith("%")?l/100*a:0),n};(l||(t=e.clientHeight,0!==(r=S(o,t,u))))&&((i=!0,a.current=!1,l)?o.scrollIntoView():1!==r&&(e.scrollTop=0,2===S(o,t,u)&&o.scrollIntoView()))},{dontForceLayout:!0,onlyHashChange:r.onlyHashChange}),i&&(r.onlyHashChange=!1,r.hashFragment=null)},void 0),(0,u.jsx)(i.Fragment,{ref:t,children:e.children})};function x({children:e,cacheNode:t}){let r=(0,i.useContext)(c.GlobalLayoutRouterContext);if(!r)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});return(0,u.jsx)(j,{focusAndScrollRef:r.focusAndScrollRef,cacheNode:t,children:e})}function P({tree:e,segmentPath:t,debugNameContext:r,cacheNode:n,params:a,url:o,isActive:l}){let s,f=(0,i.useContext)(c.GlobalLayoutRouterContext);if((0,i.useContext)(b.NavigationPromisesContext),!f)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});let p=null!==n?n:(0,i.use)(d.unresolvedThenable),h=null!==p.prefetchRsc?p.prefetchRsc:p.rsc,g=(0,i.useDeferredValue)(p.rsc,h);if((0,_.isDeferredRsc)(g)){let e=(0,i.use)(g);null===e&&(0,i.use)(d.unresolvedThenable),s=e}else null===g&&(0,i.use)(d.unresolvedThenable),s=g;let y=s;return(0,u.jsx)(c.LayoutRouterContext.Provider,{value:{parentTree:e,parentCacheNode:p,parentSegmentPath:t,parentParams:a,parentLoadingData:null,debugNameContext:r,url:o,isActive:l},children:y})}function O({loading:e,children:t}){let r=(0,i.use)(c.LayoutRouterContext);return null===r?t:(0,u.jsx)(c.LayoutRouterContext.Provider,{value:{parentTree:r.parentTree,parentCacheNode:r.parentCacheNode,parentSegmentPath:r.parentSegmentPath,parentParams:r.parentParams,parentLoadingData:e,debugNameContext:r.debugNameContext,url:r.url,isActive:r.isActive},children:t})}function C({name:e,loading:t,children:r}){if(null!==t){let n=t[0],a=t[1],o=t[2];return(0,u.jsx)(i.Suspense,{name:e,fallback:(0,u.jsxs)(u.Fragment,{children:[a,o,n]}),children:r})}return(0,u.jsx)(u.Fragment,{children:r})}function w({parallelRouterKey:e,error:t,errorStyles:r,errorScripts:n,templateStyles:a,templateScripts:o,template:l,notFound:s,forbidden:p,unauthorized:b,segmentViewBoundaries:_}){let S=(0,i.useContext)(c.LayoutRouterContext);if(!S)throw Object.defineProperty(Error("invariant expected layout router to be mounted"),"__NEXT_ERROR_CODE",{value:"E56",enumerable:!1,configurable:!0});let{parentTree:j,parentCacheNode:O,parentSegmentPath:E,parentParams:R,parentLoadingData:T,url:N,isActive:A,debugNameContext:k}=S,M=j[0],D=null===E?[e]:E.concat([M,e]),F=j[1][e],L=O.slots;(void 0===F||null===L)&&(0,i.use)(d.unresolvedThenable);let I=F[0],U=L[e]??null,B=(0,y.createRouterCacheKey)(I,!0),$=(0,m.useRouterBFCache)(F,U,B),H=[];do{let e=$.tree,i=$.cacheNode,d=$.stateKey,y=e[0],m=R;if(Array.isArray(y)){let e=y[0],t=y[1],r=y[2],n=(0,v.getParamValueFromCacheKey)(t,r);null!==n&&(m={...R,[e]:n})}let _=function(e){if("/"===e)return"/";if("string"==typeof e)if("(__SLOT__)"===e)return;else return e+"/";return e[1]+"/"}(y),S=_??k,j=void 0===_?void 0:k,O=(0,u.jsxs)(x,{cacheNode:i,children:[(0,u.jsx)(f.ErrorBoundary,{errorComponent:t,errorStyles:r,errorScripts:n,children:(0,u.jsx)(C,{name:j,loading:T,children:(0,u.jsx)(g.HTTPAccessFallbackBoundary,{notFound:s,forbidden:p,unauthorized:b,children:(0,u.jsxs)(h.RedirectBoundary,{children:[(0,u.jsx)(P,{url:N,tree:e,params:m,cacheNode:i,segmentPath:D,debugNameContext:S,isActive:A&&d===B}),null]})})})}),null]}),w=(0,u.jsxs)(c.TemplateContext.Provider,{value:O,children:[a,o,l]},d);H.push(w),$=$.next}while(null!==$)return H}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},37457,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return u}});let n=e.r(90809),a=e.r(43476),o=n._(e.r(71645)),l=e.r(8372);function u(){let e=(0,o.useContext)(l.TemplateContext);return(0,a.jsx)(a.Fragment,{children:e})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},6831,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return a}});let n=new WeakMap;function a(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},97689,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(6831).createRenderParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},93504,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return a}});let n=new WeakMap;function a(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},66996,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(93504).createRenderSearchParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},15783,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={createClientParams:function(){return o.createRenderParamsFromClient},createClientSearchParams:function(){return l.createRenderSearchParamsFromClient}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(97689),l=e.r(66996);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},18581,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useMergedRef",{enumerable:!0,get:function(){return a}});let n=e.r(71645);function a(e,t){let r=(0,n.useRef)(null),a=(0,n.useRef)(null);return(0,n.useCallback)(n=>{if(null===n){let e=r.current;e&&(r.current=null,e());let t=a.current;t&&(a.current=null,t())}else e&&(r.current=o(e,n)),t&&(a.current=o(t,n))},[e,t])}function o(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let r=e(t);return"function"==typeof r?r:()=>e(null)}}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},18967,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={DecodeError:function(){return m},MiddlewareNotFoundError:function(){return S},MissingStaticPage:function(){return _},NormalizeError:function(){return b},PageNotFoundError:function(){return v},SP:function(){return g},ST:function(){return y},WEB_VITALS:function(){return o},execOnce:function(){return l},getDisplayName:function(){return d},getLocationOrigin:function(){return s},getURL:function(){return c},isAbsoluteUrl:function(){return i},isResSent:function(){return f},loadGetInitialProps:function(){return h},normalizeRepeatedSlashes:function(){return p},stringifyError:function(){return j}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=["CLS","FCP","FID","INP","LCP","TTFB"];function l(e){let t,r=!1;return(...n)=>(r||(r=!0,t=e(...n)),t)}let u=/^[a-zA-Z][a-zA-Z\d+\-.]*?:/,i=e=>{let t=e.charCodeAt(0);return!!(t>=65&&t<=90||t>=97&&t<=122)&&u.test(e)};function s(){let{protocol:e,hostname:t,port:r}=window.location;return`${e}//${t}${r?":"+r:""}`}function c(){let{href:e}=window.location,t=s();return e.substring(t.length)}function d(e){return"string"==typeof e?e:e.displayName||e.name||"Unknown"}function f(e){return e.finished||e.headersSent}function p(e){let t=e.split("?");return t[0].replace(/\\/g,"/").replace(/\/\/+/g,"/")+(t[1]?`?${t.slice(1).join("?")}`:"")}async function h(e,t){let r=t.res||t.ctx&&t.ctx.res;if(!e.getInitialProps)return t.ctx&&t.Component?{pageProps:await h(t.Component,t.ctx)}:{};let n=await e.getInitialProps(t);if(r&&f(r))return n;if(!n)throw Object.defineProperty(Error(`"${d(e)}.getInitialProps()" should resolve to an object. But found "${n}" instead.`),"__NEXT_ERROR_CODE",{value:"E1025",enumerable:!1,configurable:!0});return n}let g="u">typeof performance,y=g&&["mark","measure","getEntriesByName"].every(e=>"function"==typeof performance[e]);class m extends Error{}class b extends Error{}class v extends Error{constructor(e){super(),this.code="ENOENT",this.name="PageNotFoundError",this.message=`Cannot find module for page: ${e}`}}class _ extends Error{constructor(e,t){super(),this.message=`Failed to load static file for page: ${e} ${t}`}}class S extends Error{constructor(){super(),this.code="ENOENT",this.message="Cannot find the middleware module"}}function j(e){return JSON.stringify({message:e.message,stack:e.stack})}},27201,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"IconMark",{enumerable:!0,get:function(){return a}});let n=e.r(43476),a=()=>"u">typeof window?null:(0,n.jsx)("meta",{name:"«nxt-icon»"})},91915,(e,t,r)=>{"use strict";function n(e,t={}){if(t.onlyHashChange)return void e();let r=document.documentElement;if("smooth"!==r.dataset.scrollBehavior)return void e();let a=r.style.scrollBehavior;r.style.scrollBehavior="auto",t.dontForceLayout||r.getClientRects(),e(),r.style.scrollBehavior=a}e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"disableSmoothScrollDuringRouteTransition",{enumerable:!0,get:function(){return n}})},73668,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"isLocalURL",{enumerable:!0,get:function(){return o}});let n=e.r(18967),a=e.r(52817);function o(e){if(!(0,n.isAbsoluteUrl)(e))return!0;try{let t=(0,n.getLocationOrigin)(),r=new URL(e,t);return r.origin===t&&(0,a.hasBasePath)(r.pathname)}catch(e){return!1}}},98183,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={assign:function(){return i},searchParamsToUrlQuery:function(){return o},urlQueryToSearchParams:function(){return u}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});function o(e){let t={};for(let[r,n]of e.entries()){let e=t[r];void 0===e?t[r]=n:Array.isArray(e)?e.push(n):t[r]=[e,n]}return t}function l(e){return"string"==typeof e?e:("number"!=typeof e||isNaN(e))&&"boolean"!=typeof e?"":String(e)}function u(e){let t=new URLSearchParams;for(let[r,n]of Object.entries(e))if(Array.isArray(n))for(let e of n)t.append(r,l(e));else t.set(r,l(n));return t}function i(e,...t){for(let r of t){for(let t of r.keys())e.delete(t);for(let[t,n]of r.entries())e.append(t,n)}return e}},95057,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={formatUrl:function(){return u},formatWithValidation:function(){return s},urlObjectKeys:function(){return i}};for(var a in n)Object.defineProperty(r,a,{enumerable:!0,get:n[a]});let o=e.r(90809)._(e.r(98183)),l=/https?|ftp|gopher|file/;function u(e){let{auth:t,hostname:r}=e,n=e.protocol||"",a=e.pathname||"",u=e.hash||"",i=e.query||"",s=!1;t=t?encodeURIComponent(t).replace(/%3A/i,":")+"@":"",e.host?s=t+e.host:r&&(s=t+(~r.indexOf(":")?`[${r}]`:r),e.port&&(s+=":"+e.port)),i&&"object"==typeof i&&(i=String(o.urlQueryToSearchParams(i)));let c=e.search||i&&`?${i}`||"";return n&&!n.endsWith(":")&&(n+=":"),e.slashes||(!n||l.test(n))&&!1!==s?(s="//"+(s||""),a&&"/"!==a[0]&&(a="/"+a)):s||(s=""),u&&"#"!==u[0]&&(u="#"+u),c&&"?"!==c[0]&&(c="?"+c),a=a.replace(/[?#]/g,encodeURIComponent),c=c.replace("#","%23"),`${n}${s}${a}${c}${u}`}let i=["auth","hash","host","hostname","href","path","pathname","port","protocol","query","search","slashes"];function s(e){return u(e)}}]);