six-degrees 0.4.9 → 0.4.10

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 (181) 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.html +1 -1
  5. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  10. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.rsc +13 -13
  13. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  14. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  15. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  16. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/social/messages/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/import/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/import.html +1 -1
  49. package/.next/standalone/.next/server/app/import.rsc +15 -15
  50. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +15 -15
  51. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
  52. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +14 -14
  53. package/.next/standalone/.next/server/app/index.html +1 -1
  54. package/.next/standalone/.next/server/app/index.rsc +15 -15
  55. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  56. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  57. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/launch.html +2 -2
  61. package/.next/standalone/.next/server/app/launch.rsc +15 -15
  62. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +15 -15
  63. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
  64. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +14 -14
  65. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/paths.html +1 -1
  70. package/.next/standalone/.next/server/app/paths.rsc +15 -15
  71. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +15 -15
  72. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
  73. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +14 -14
  74. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/profile.html +1 -1
  77. package/.next/standalone/.next/server/app/profile.rsc +15 -15
  78. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +15 -15
  79. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
  80. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +14 -14
  81. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/queue.html +1 -1
  84. package/.next/standalone/.next/server/app/queue.rsc +15 -15
  85. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +15 -15
  86. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
  87. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +14 -14
  88. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/scores.html +1 -1
  91. package/.next/standalone/.next/server/app/scores.rsc +15 -15
  92. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +15 -15
  93. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
  94. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +14 -14
  95. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  96. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/settings.html +1 -1
  98. package/.next/standalone/.next/server/app/settings.rsc +15 -15
  99. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +15 -15
  100. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  101. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +14 -14
  102. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/setup.html +1 -1
  105. package/.next/standalone/.next/server/app/setup.rsc +15 -15
  106. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +15 -15
  107. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  108. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +14 -14
  109. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  110. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/app/social.html +1 -1
  112. package/.next/standalone/.next/server/app/social.rsc +15 -15
  113. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +15 -15
  114. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
  115. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +14 -14
  116. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  117. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/_0c_y09g._.js +1 -1
  119. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +1 -1
  121. package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
  122. package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +1 -1
  123. package/.next/standalone/.next/server/chunks/ssr/app_scores_page_09wepvv.js +1 -1
  124. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
  125. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
  127. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  128. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  129. package/.next/standalone/.next/server/pages/404.html +1 -1
  130. package/.next/standalone/.next/server/pages/500.html +1 -1
  131. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  133. package/.next/standalone/.next/static/chunks/07dyt47mp4s9-.js +1 -0
  134. package/.next/standalone/.next/static/chunks/0a5iadnmt9u9k.js +1 -0
  135. package/.next/standalone/.next/static/chunks/{054zdthcnyd2h.js → 160wjb73ddwqd.js} +1 -1
  136. package/.next/standalone/.next/static/chunks/{04bbi55urkrd6.js → 1c_n0973t07l0.js} +1 -1
  137. package/.next/{static/chunks/0bo1dxn5gwzpk.css → standalone/.next/static/chunks/1xptlvtcz6654.css} +1 -1
  138. package/.next/standalone/.next/static/chunks/{3z-swu5pet507.js → 206rm6j42gl_a.js} +1 -1
  139. package/.next/{static/chunks/1_mohm2643nxp.js → standalone/.next/static/chunks/236f0jtp68j_h.js} +1 -1
  140. package/.next/standalone/.next/static/chunks/2coxzjm_k6ilr.js +1 -0
  141. package/.next/standalone/.next/static/chunks/{38wwtni5e1ec1.js → 39hr8d-b2ibtw.js} +1 -1
  142. package/.next/{static/chunks/1z_rt4jteewqp.js → standalone/.next/static/chunks/3zw8bv7-mc4n6.js} +1 -1
  143. package/.next/standalone/CHANGELOG.md +9 -0
  144. package/.next/standalone/app/components/GalaxyLab.js +4 -1
  145. package/.next/standalone/app/components/ScanStatusBar.js +96 -71
  146. package/.next/standalone/app/globals.css +4 -0
  147. package/.next/standalone/app/paths/page.js +0 -2
  148. package/.next/standalone/app/profile/page.js +0 -2
  149. package/.next/standalone/app/queue/page.js +0 -2
  150. package/.next/standalone/app/scores/page.js +0 -2
  151. package/.next/standalone/app/settings/page.js +0 -2
  152. package/.next/standalone/app/setup/page.js +0 -2
  153. package/.next/standalone/app/social/page.js +0 -2
  154. package/.next/standalone/lib/island.js +36 -0
  155. package/.next/standalone/package-lock.json +2 -2
  156. package/.next/standalone/package.json +1 -1
  157. package/.next/static/chunks/07dyt47mp4s9-.js +1 -0
  158. package/.next/static/chunks/0a5iadnmt9u9k.js +1 -0
  159. package/.next/static/chunks/{054zdthcnyd2h.js → 160wjb73ddwqd.js} +1 -1
  160. package/.next/static/chunks/{04bbi55urkrd6.js → 1c_n0973t07l0.js} +1 -1
  161. package/.next/{standalone/.next/static/chunks/0bo1dxn5gwzpk.css → static/chunks/1xptlvtcz6654.css} +1 -1
  162. package/.next/static/chunks/{3z-swu5pet507.js → 206rm6j42gl_a.js} +1 -1
  163. package/.next/{standalone/.next/static/chunks/1_mohm2643nxp.js → static/chunks/236f0jtp68j_h.js} +1 -1
  164. package/.next/static/chunks/2coxzjm_k6ilr.js +1 -0
  165. package/.next/static/chunks/{38wwtni5e1ec1.js → 39hr8d-b2ibtw.js} +1 -1
  166. package/.next/{standalone/.next/static/chunks/1z_rt4jteewqp.js → static/chunks/3zw8bv7-mc4n6.js} +1 -1
  167. package/CHANGELOG.md +9 -0
  168. package/lib/island.js +36 -0
  169. package/package.json +1 -1
  170. package/.next/standalone/.next/static/chunks/2bftn9gubwf0w.js +0 -1
  171. package/.next/standalone/.next/static/chunks/39csdcx7yv227.js +0 -1
  172. package/.next/standalone/.next/static/chunks/3yzlf70j5t0-o.js +0 -1
  173. package/.next/static/chunks/2bftn9gubwf0w.js +0 -1
  174. package/.next/static/chunks/39csdcx7yv227.js +0 -1
  175. package/.next/static/chunks/3yzlf70j5t0-o.js +0 -1
  176. /package/.next/standalone/.next/static/{yPlsfKhdS8MMtyXF7twSZ → 7zWJnSkfSoRhRsqY6ZKtD}/_buildManifest.js +0 -0
  177. /package/.next/standalone/.next/static/{yPlsfKhdS8MMtyXF7twSZ → 7zWJnSkfSoRhRsqY6ZKtD}/_clientMiddlewareManifest.js +0 -0
  178. /package/.next/standalone/.next/static/{yPlsfKhdS8MMtyXF7twSZ → 7zWJnSkfSoRhRsqY6ZKtD}/_ssgManifest.js +0 -0
  179. /package/.next/static/{yPlsfKhdS8MMtyXF7twSZ → 7zWJnSkfSoRhRsqY6ZKtD}/_buildManifest.js +0 -0
  180. /package/.next/static/{yPlsfKhdS8MMtyXF7twSZ → 7zWJnSkfSoRhRsqY6ZKtD}/_clientMiddlewareManifest.js +0 -0
  181. /package/.next/static/{yPlsfKhdS8MMtyXF7twSZ → 7zWJnSkfSoRhRsqY6ZKtD}/_ssgManifest.js +0 -0
@@ -1,4 +1,4 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,2776,e=>{"use strict";var t=e.i(43476),r=e.i(15812);e.s(["default",0,function({children:e}){let{userId:n,ready:i}=(0,r.useUser)();return i&&n?e:(0,t.jsx)("div",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#0a0a1a",color:"#fff",padding:24,textAlign:"center",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'},children:i?(0,t.jsxs)("div",{style:{maxWidth:420},children:[(0,t.jsx)("div",{style:{fontSize:18,fontWeight:700,marginBottom:8},children:"Can’t reach Six Degrees’ local server"}),(0,t.jsx)("div",{style:{color:"#888",fontSize:14,lineHeight:1.6},children:"The page loaded but the app behind it is not answering. If you started it from a terminal, check that window for an error, then reload this page."})]}):(0,t.jsx)("div",{style:{fontSize:18,fontWeight:600},children:"Loading…"})})}])},28867,86106,e=>{"use strict";var t=e.i(71645),r=e.i(7214);let n=Object.freeze({known:!1,sent:new Set,mine:new Map,version:0}),i=new Set,o=n,l=null,s=new Map;function d(e=o.sent,t=o.known){for(let r of(o=Object.freeze({known:t,sent:e,mine:new Map(s),version:o.version+1}),[...i]))r()}function a(e){return i.add(e),l||o.known||(l=fetch("/api/outreach").then(e=>e.ok?e.json():null).then(e=>{e&&d(new Set((e.pending||[]).map(r.keyFor)),!0)}).catch(()=>{}).finally(()=>{l=null})),()=>i.delete(e)}function c(){return o}async function g(e){let t=await fetch("/api/outreach",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),r=await t.json().catch(()=>({}));if(!t.ok)throw Error(r.error||"Could not save that.");return r}async function p(e,{bridgeId:t}={}){let n=(0,r.keyFor)(e),i=s.has(n)?s.get(n):void 0;s.set(n,!0),d();try{return await g({action:"mark-sent",connectionId:e.id,profileUrl:e.profile_url,bridgeId:t})}catch(e){throw void 0===i?s.delete(n):s.set(n,i),d(),e}}async function h(e){let t=(0,r.keyFor)(e),n=s.has(t)?s.get(t):void 0;s.set(t,!1),d();try{return await g({action:"undo",connectionId:e.id,profileUrl:e.profile_url})}catch(e){throw void 0===n?s.delete(t):s.set(t,n),d(),e}}e.s(["REQUESTS_UNKNOWN",0,n,"hasRequest",0,function(e,t=o){if(!e)return!1;let n=(0,r.keyFor)(e);return t.mine.has(n)?t.mine.get(n):t.known?t.sent.has(n):"pending"===e.unlock_status||"sent"===e.outreach_status},"markRequested",0,p,"requestCount",0,function(e=o){let t=new Set(e.known?e.sent:[]);for(let[r,n]of e.mine)n?t.add(r):t.delete(r);return t.size},"requestsNow",0,c,"undoRequest",0,h,"watchRequests",0,a],86106),e.s(["default",0,function(){return(0,t.useSyncExternalStore)(a,c,()=>n)}],28867)},77305,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(19821),i=e.i(64745),o=e.i(22016),l=e.i(48235);let s={S:25,A:15,B:10,C:5,D:2},d={S:100,A:60,B:35,C:15,D:5};var a=e.i(5258),c=e.i(36774);let g={S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"},p="1px solid rgba(255,255,255,0.1)";function h({person:e,size:r=36,ring:n}){let i=g[e?.tier]||"#667";return(0,t.jsxs)("div",{style:{position:"relative",width:r,height:r,flexShrink:0},children:[(0,t.jsx)("div",{style:{width:r,height:r,borderRadius:"50%",background:i,color:e?.tier==="S"?"#000":"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:.34*r,fontWeight:800,border:`2px solid ${n||i}`},children:(0,a.initialsFor)(e?.name||"?")}),(0,c.localPhoto)(e?.profile_image_url)&&(0,t.jsx)("img",{src:(0,c.localPhoto)(e.profile_image_url),alt:"",onError:e=>{e.currentTarget.style.display="none"},style:{position:"absolute",inset:0,width:r,height:r,borderRadius:"50%",objectFit:"cover",border:`2px solid ${n||i}`}})]})}function f({progress:e,size:r=86,color:n="#FF6B35",children:i}){let o=r/2-5,l=2*Math.PI*o;return(0,t.jsxs)("div",{style:{position:"relative",width:r,height:r},children:[(0,t.jsxs)("svg",{width:r,height:r,style:{position:"absolute",inset:0,transform:"rotate(-90deg)"},children:[(0,t.jsx)("circle",{cx:r/2,cy:r/2,r:o,fill:"none",stroke:"rgba(255,255,255,0.08)",strokeWidth:5}),(0,t.jsx)("circle",{cx:r/2,cy:r/2,r:o,fill:"none",stroke:n,strokeWidth:5,strokeLinecap:"round",strokeDasharray:`${l*Math.min(1,e)} ${l}`,style:{transition:"stroke-dasharray 0.5s ease"}})]}),(0,t.jsx)("div",{style:{position:"absolute",inset:9,display:"flex",alignItems:"center",justifyContent:"center"},children:i})]})}function u({recs:e,sentIds:n,added:i,mappedIds:a,reach:c,onSend:y,onUndo:m}){let S=(0,r.useMemo)(()=>(function({recs:e=[],sentIds:t=new Set,added:r=[],mappedIds:n=new Set,reach:i=null}){var o;let a,c,g,p=new Map,h=new Set;for(let t of[...e].sort((e,t)=>(t.priority||0)-(e.priority||0))){if(!t.bridge)continue;let e=`${t.bridge.id}|${t.profile_url||t.id}`;if(h.has(e))continue;h.add(e);let r=p.get(t.bridge.id);r||(r={bridge:t.bridge,people:[]},p.set(t.bridge.id,r)),r.people.push(t)}let f=new Map;for(let e of r){let t=e.unlocked_from_bridge_id;t&&f.set(t,[...f.get(t)||[],e])}let u=[],x=0,b=0;for(let{bridge:e,people:r}of p.values()){let n=r.filter(e=>t.has(e.id)),i=f.get(e.id)||[];b+=n.length,x+=n.reduce((e,t)=>e+(s[t.tier]||2),0),x+=i.reduce((e,t)=>e+(d[t.tier]||5),0);let o=Math.ceil(r.length/5)||1,l=0;for(;l<o-1&&r.slice(5*l,(l+1)*5).every(e=>t.has(e.id));)l++;let a=r.slice(5*l,(l+1)*5),c=a.filter(e=>t.has(e.id)).length,g=c===a.length&&l===o-1;u.push({bridge:e,people:r,stage:l+1,stages:o,targets:a,done:c,progress:a.length?c/a.length:1,complete:g,sent:n.length,added:i,value:a.filter(e=>!t.has(e.id)).reduce((e,t)=>e+(t.priority||0),0),open:{S:a.filter(e=>"S"===e.tier&&!t.has(e.id)).length,A:a.filter(e=>"A"===e.tier&&!t.has(e.id)).length}})}u.sort((e,t)=>e.complete-t.complete||(t.progress>0&&t.progress<1)-(e.progress>0&&e.progress<1)||t.progress-e.progress||t.value-e.value);let y=u.filter(e=>!e.complete).flatMap(e=>e.targets.filter(e=>!t.has(e.id)).map(t=>({person:t,cluster:e,score:(t.priority||0)*(1+.6*e.progress)}))).sort((e,t)=>t.score-e.score),m=new Set,S=[];for(let e of y){let t=e.person.profile_url||e.person.id;if(!m.has(t)&&(m.add(t),S.push(e),3===S.length))break}let k=r.filter(e=>e.unlocked_from_bridge_id).length;return{clusters:u,nextMoves:S,points:x,level:(c=((a=Math.floor(Math.sqrt(Math.max(0,o=x)/40))+1)-1)**2*40,g=a**2*40,{level:a,floor:c,next:g,progress:(o-c)/(g-c)}),sentTotal:b,addedTotal:k,newDoors:r.filter(e=>e.unlocked_from_bridge_id&&"todo"===(0,l.circleState)(e,i||{scanned:n,hidden:new Set})),clearedStages:u.reduce((e,t)=>e+(t.stage-1)+ +!!t.complete,0)}})({recs:e,sentIds:n,added:i,mappedIds:a,reach:c}),[e,n,i,a,c]),[k,j]=(0,r.useState)(null),[v,w]=(0,r.useState)(null),{level:_}=S;async function F(e,t){await y(e);let r=t.done+1,n=String(t.bridge.name||"").split(/[\s,]+/)[0];w(r>=t.targets.length?`+${s[e.tier]||2} \xb7 Stage ${t.stage} of ${n}'s circle cleared — the next 5 are up`:`+${s[e.tier]||2} \xb7 ${n}'s circle ${r}/${t.targets.length}`),setTimeout(()=>w(null),3500)}let z=S.clusters.find(e=>e.bridge.id===k);return(0,t.jsxs)("div",{style:{maxWidth:1100,margin:"0 auto",padding:"16px 20px 60px"},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:16,alignItems:"center",flexWrap:"wrap",padding:16,borderRadius:12,border:p,background:"linear-gradient(135deg, rgba(255,107,53,0.10), rgba(155,89,182,0.08))"},children:[(0,t.jsxs)("div",{style:{width:64,height:64,borderRadius:16,background:"linear-gradient(135deg, #FFD700, #FF6B35)",color:"#000",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[(0,t.jsx)("div",{style:{fontSize:10,fontWeight:800},children:"LEVEL"}),(0,t.jsx)("div",{style:{fontSize:26,fontWeight:900,lineHeight:1},children:_.level})]}),(0,t.jsxs)("div",{style:{flex:1,minWidth:220},children:[(0,t.jsxs)("div",{style:{fontSize:13,color:"#dfe6e9"},children:[(0,t.jsx)("b",{children:S.points})," points · ",(0,t.jsx)("b",{children:_.next-S.points})," to level ",_.level+1]}),(0,t.jsx)("div",{style:{height:8,borderRadius:4,background:"rgba(255,255,255,0.08)",marginTop:6,overflow:"hidden"},children:(0,t.jsx)("div",{style:{height:"100%",width:`${Math.round(100*_.progress)}%`,background:"linear-gradient(90deg, #FFD700, #FF6B35)",transition:"width 0.5s"}})}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#8b9a9a",marginTop:6},children:"Points come from invites you send and people who accept — not from browsing."})]}),[[S.sentTotal,"invites sent"],[S.addedTotal,"people added"],[S.clearedStages,"stages cleared"]].map(([e,r])=>(0,t.jsxs)("div",{style:{textAlign:"center",minWidth:80},children:[(0,t.jsx)("div",{style:{fontSize:24,fontWeight:900},children:e}),(0,t.jsx)("div",{style:{fontSize:11,color:"#8b9a9a"},children:r})]},r))]}),S.newDoors.length>0&&(0,t.jsxs)("div",{style:{marginTop:12,padding:"10px 14px",borderRadius:10,border:"1px solid rgba(0,255,136,0.3)",background:"rgba(0,255,136,0.06)",fontSize:13},children:["🚪 ",(0,t.jsxs)("b",{children:[S.newDoors.length," new ",1===S.newDoors.length?"door":"doors",":"]})," people you added through a circle, whose own circle isn’t mapped yet. That’s the next degree. ",(0,t.jsx)(o.default,{href:"/setup",style:{color:"#00ff88"},children:"Map them on the Scan page →"})]}),S.nextMoves.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h3",{style:{margin:"22px 0 10px",fontSize:15},children:"Next best moves"}),(0,t.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(300px, 1fr))",gap:12},children:S.nextMoves.map(({person:e,cluster:r},n)=>(0,t.jsxs)("div",{style:{padding:14,borderRadius:12,border:`1px solid ${g[e.tier]}55`,background:"rgba(255,255,255,0.03)",position:"relative"},children:[(0,t.jsxs)("div",{style:{position:"absolute",top:10,right:12,fontSize:11,fontWeight:800,color:"#FF6B35"},children:["#",n+1]}),(0,t.jsxs)("div",{style:{display:"flex",gap:10,alignItems:"center"},children:[(0,t.jsx)(h,{person:e,size:44}),(0,t.jsxs)("div",{style:{minWidth:0},children:[(0,t.jsx)("div",{style:{fontWeight:700,fontSize:14},children:e.name}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#8b9a9a",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:220},children:e.headline})]})]}),(0,t.jsxs)("div",{style:{fontSize:11.5,color:"#aab7b7",margin:"10px 0"},children:["via ",(0,t.jsx)("b",{style:{color:g[r.bridge.tier]},children:r.bridge.name})," · their circle ",r.done,"/",r.targets.length," this stage"]}),(0,t.jsxs)("div",{style:{display:"flex",gap:8},children:[e.profile_url&&(0,t.jsx)("a",{href:e.profile_url,target:"_blank",rel:"noopener noreferrer",style:b,children:"Open on LinkedIn"}),(0,t.jsxs)("button",{onClick:()=>F(e,r),style:x,children:["I sent an invite · +",s[e.tier]||2]})]})]},e.id))})]}),(0,t.jsx)("h3",{style:{margin:"26px 0 4px",fontSize:15},children:"Circles to work through"}),(0,t.jsxs)("div",{style:{fontSize:12,color:"#8b9a9a",marginBottom:12},children:["Each is one of your connections and the best people they know, ",5," at a time. Fill the ring to clear a stage."]}),(0,t.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(190px, 1fr))",gap:12},children:S.clusters.map(e=>{let r=k===e.bridge.id;return(0,t.jsxs)("button",{onClick:()=>j(r?null:e.bridge.id),style:{padding:12,borderRadius:12,cursor:"pointer",textAlign:"center",color:"#fff",border:r?"1px solid #FF6B35":p,background:e.complete?"rgba(0,255,136,0.06)":"rgba(255,255,255,0.03)",display:"flex",flexDirection:"column",alignItems:"center",gap:6},children:[(0,t.jsx)(f,{progress:e.progress,color:e.complete?"#00ff88":"#FF6B35",children:(0,t.jsx)(h,{person:e.bridge,size:60})}),(0,t.jsx)("div",{style:{fontWeight:700,fontSize:13,maxWidth:170,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.bridge.name}),(0,t.jsx)("div",{style:{fontSize:11,color:e.complete?"#00ff88":"#aab7b7"},children:e.complete?"Circle cleared":`Stage ${e.stage} of ${e.stages} \xb7 ${e.done}/${e.targets.length}`}),(0,t.jsx)("div",{style:{display:"flex",gap:4},children:e.targets.map(e=>(0,t.jsx)("span",{title:e.name,style:{width:12,height:12,borderRadius:"50%",border:`2px solid ${g[e.tier]||"#667"}`,background:n.has(e.id)?g[e.tier]||"#667":"transparent"}},e.id))}),(0,t.jsxs)("div",{style:{fontSize:10.5,color:"#778"},children:[e.open.S?`${e.open.S} S \xb7 `:"",e.open.A?`${e.open.A} A \xb7 `:"",e.people.length," worth adding",e.added.length?` \xb7 ★ ${e.added.length} added`:""]})]},e.bridge.id)})}),z&&(0,t.jsxs)("div",{style:{marginTop:14,padding:16,borderRadius:12,border:"1px solid rgba(255,107,53,0.4)",background:"rgba(255,107,53,0.05)"},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:10},children:[(0,t.jsx)(h,{person:z.bridge,size:40}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{fontWeight:800},children:[z.bridge.name,"’s circle · stage ",z.stage," of ",z.stages]}),(0,t.jsxs)("div",{style:{fontSize:12,color:"#aab7b7"},children:["Ask ",z.bridge.name?.split(" ")[0]," for an intro, or invite them directly. Mark each one when it’s sent."]})]})]}),z.targets.map(e=>{let r=n.has(e.id);return(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"8px 0",borderTop:"1px solid rgba(255,255,255,0.05)"},children:[(0,t.jsx)(h,{person:e,size:34,ring:r?"#00ff88":void 0}),(0,t.jsxs)("div",{style:{flex:1,minWidth:0},children:[(0,t.jsxs)("div",{style:{fontWeight:600,fontSize:13},children:[e.name," ",(0,t.jsx)("span",{style:{color:g[e.tier],fontSize:11},children:e.tier})]}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#8b9a9a",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.headline})]}),e.profile_url&&(0,t.jsx)("a",{href:e.profile_url,target:"_blank",rel:"noopener noreferrer",style:b,children:"LinkedIn"}),r?(0,t.jsx)("button",{onClick:()=>m(e),style:{...b,color:"#00ff88"},children:"Sent ✓ (undo)"}):(0,t.jsxs)("button",{onClick:()=>F(e,z),style:x,children:["Sent · +",s[e.tier]||2]})]},e.id)}),z.added.length>0&&(0,t.jsxs)("div",{style:{marginTop:10,fontSize:12,color:"#00ff88"},children:["★ Added from this circle: ",z.added.map(e=>e.name).join(", ")]})]}),v&&(0,t.jsx)("div",{role:"status",style:{position:"fixed",bottom:24,left:"50%",transform:"translateX(-50%)",padding:"10px 18px",borderRadius:24,background:"linear-gradient(135deg, #FFD700, #FF6B35)",color:"#000",fontWeight:800,fontSize:13,boxShadow:"0 8px 30px rgba(0,0,0,0.5)",zIndex:50},children:v})]})}let x={padding:"7px 12px",borderRadius:8,border:"none",cursor:"pointer",fontWeight:800,fontSize:12,background:"linear-gradient(135deg, #FF6B35, #FFD700)",color:"#000"},b={padding:"7px 12px",borderRadius:8,border:p,cursor:"pointer",fontWeight:600,fontSize:12,background:"rgba(255,255,255,0.05)",color:"#dfe6e9",textDecoration:"none"};var y=e.i(2776),m=e.i(15812),S=e.i(90179),k=e.i(28867),j=e.i(86106),v=e.i(7214),w=e.i(40996);let _={S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"};function F(){let{userId:e,userProfile:s}=(0,m.useUser)(),d=s?.sectors||[],[a,g]=(0,r.useState)([]),[p,h]=(0,r.useState)(!0),[f,x]=(0,r.useState)("all"),[b,y]=(0,r.useState)(new Set),F=(0,k.default)(),[z,B]=(0,r.useState)([]),[C,R]=(0,r.useState)({}),[I,W]=(0,r.useState)("quest"),[A,$]=(0,r.useState)([]),[M,D]=(0,r.useState)(()=>new Set),[T,O]=(0,r.useState)(null),[E,P]=(0,r.useState)(null),[U,L]=(0,r.useState)(()=>{{let e=new URLSearchParams(window.location.search);if(e.get("groupBy"))return e.get("groupBy")}return"bridge"});(0,r.useEffect)(()=>{{let e=new URLSearchParams(window.location.search).get("bridge");e&&P(e)}},[]),(0,r.useEffect)(()=>{!i.IS_DEMO&&e&&t();async function t(){let[t,r,i]=await Promise.all([(0,n.loadNetwork)(e),fetch(`/api/outreach?userId=${e}`).then(e=>e.json()).catch(()=>({pending:[]})),(0,w.loadScanNotes)()]),o=t.degree1,s=t.degree2;$(o.filter(e=>e.unlocked_from_bridge_id)),D(new Set(s.map(e=>e.source_connection_id).filter(Boolean))),O((0,l.reachIndex)(o,s,i));let a=new Set(o.map(e=>e.profile_url)),c={};o.forEach(e=>{c[e.id]=e}),B(r.pending||[]),R(c),g(s.filter(e=>("S"===e.tier||"A"===e.tier||"B"===e.tier)&&!a.has(e.profile_url)).map(e=>{let t,r,n=c[e.source_connection_id],i=(t=parseFloat(e.power_score)||0,r=(e.headline||"").toLowerCase(),(0,S.rowCompanyScore)(e)>=S.TOP_COMPANY&&(t+=1),(d||[]).forEach(e=>{r.includes(e.toLowerCase())&&(t+=.5)}),"S"===e.tier?t*=1.5:"A"===e.tier&&(t*=1.2),t),o="S"===e.tier?50:"A"===e.tier?25:10;return{...e,bridge:n,priority:i,xp:o}}).sort((e,t)=>t.priority-e.priority)),h(!1)}},[e]);let q=(0,r.useMemo)(()=>new Set([...z,...a].filter(e=>(0,j.hasRequest)(e,F)).map(e=>e.id)),[z,a,F]),N=(0,r.useMemo)(()=>{let e=new Set,t=[];for(let r of[...z,...a]){let n=(0,v.keyFor)(r);!e.has(n)&&(0,j.hasRequest)(r,F)&&(e.add(n),t.push({...r,bridge:C[r.source_connection_id]||r.bridge||null}))}return t},[z,a,F,C]);if(i.IS_DEMO)return(0,t.jsxs)("div",{style:{minHeight:"100vh",background:"#0a0a1a",color:"rgba(255,255,255,0.7)",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:10,textAlign:"center",padding:24},children:[(0,t.jsx)("h2",{style:{margin:0,fontSize:18,fontWeight:700,color:"#fff"},children:"Not part of the demo"}),(0,t.jsx)("div",{style:{fontSize:13},children:"The public demo includes the Network Circle and Degrees views only."}),(0,t.jsx)(o.default,{href:"/",style:{fontSize:12,color:"rgba(255,255,255,0.5)",textDecoration:"none"},children:"← Back to the network"})]});let H="all"===f?a:a.filter(e=>e.tier===f);E&&(H=H.filter(e=>e.bridge?.id===E));let V={S:0,A:0,B:0};a.forEach(e=>{void 0!==V[e.tier]&&V[e.tier]++});let Y={};H.forEach(e=>{let t;Y[t="bridge"===U?e.bridge?.id||"unknown":"company"===U?(e.company||"Unknown").trim()||"Unknown":e.tier]||(Y[t]=[]),Y[t].push(e)});let K={S:0,A:1,B:2},G=Object.entries(Y).sort((e,t)=>{if("tier"===U)return(K[e[0]]||9)-(K[t[0]]||9);if("bridge"===U){let r=e[1][0]?.bridge,n=t[1][0]?.bridge,i=K[r?.tier]??9,o=K[n?.tier]??9;if(i!==o)return i-o}return t[1].length-e[1].length});function X(e){y(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r})}return p?(0,t.jsx)("div",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#0a0a1a",color:"#fff"},children:"Loading..."}):(0,t.jsxs)("div",{style:{height:"100vh",background:"#0a0a1a",color:"#fff",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',display:"flex",flexDirection:"column",overflow:"hidden"},children:[(0,t.jsxs)("header",{style:{padding:"14px 24px",borderBottom:"1px solid rgba(255,255,255,0.1)",flexShrink:0},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:10},children:[(0,t.jsxs)(o.default,{href:"/",style:{display:"flex",alignItems:"center",gap:6,color:"#888",textDecoration:"none",fontSize:13,fontWeight:600,padding:"6px 14px",borderRadius:6,background:"rgba(255,255,255,0.06)",border:"1px solid rgba(255,255,255,0.1)"},children:[(0,t.jsx)("span",{style:{fontSize:16},children:"←"})," Map"]}),(0,t.jsx)("h1",{style:{fontSize:20,fontWeight:700,margin:0,background:"linear-gradient(135deg, #FF6B35, #FFD700)",WebkitBackgroundClip:"text",WebkitTextFillColor:"transparent"},children:"Outlink"}),(0,t.jsxs)("div",{style:{display:"flex",gap:2,background:"rgba(255,255,255,0.06)",borderRadius:6,padding:2},children:[(0,t.jsx)("button",{onClick:()=>W("quest"),style:{padding:"5px 12px",borderRadius:4,border:"none",fontSize:11,fontWeight:700,cursor:"pointer",background:"quest"===I?"linear-gradient(135deg, #FFD700, #FF6B35)":"transparent",color:"quest"===I?"#000":"#FFD700"},children:"Circles"}),(0,t.jsxs)("button",{onClick:()=>W("recs"),style:{padding:"5px 12px",borderRadius:4,border:"none",fontSize:11,fontWeight:600,cursor:"pointer",background:"recs"===I?"#fff":"transparent",color:"recs"===I?"#000":"#888"},children:["To Add (",a.length,")"]}),(0,t.jsxs)("button",{onClick:()=>W("pending"),style:{padding:"5px 12px",borderRadius:4,border:"none",fontSize:11,fontWeight:600,cursor:"pointer",background:"pending"===I?"linear-gradient(135deg, #FF6B35, #FFD700)":"transparent",color:"pending"===I?"#000":"#FF6B35"},children:["Pending (",N.length,")"]})]}),(0,t.jsx)("div",{style:{marginLeft:"auto",display:"flex",gap:6},children:"recs"===I&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{onClick:()=>L("tier"),style:{padding:"4px 10px",borderRadius:4,border:"none",fontSize:10,fontWeight:600,cursor:"pointer",background:"tier"===U?"rgba(255,255,255,0.15)":"rgba(255,255,255,0.05)",color:"tier"===U?"#fff":"#666"},children:"By Tier"}),(0,t.jsx)("button",{onClick:()=>L("bridge"),style:{padding:"4px 10px",borderRadius:4,border:"none",fontSize:10,fontWeight:600,cursor:"pointer",background:"bridge"===U?"rgba(255,255,255,0.15)":"rgba(255,255,255,0.05)",color:"bridge"===U?"#fff":"#666"},children:"By Bridge"}),(0,t.jsx)("button",{onClick:()=>L("company"),style:{padding:"4px 10px",borderRadius:4,border:"none",fontSize:10,fontWeight:600,cursor:"pointer",background:"company"===U?"rgba(255,255,255,0.15)":"rgba(255,255,255,0.05)",color:"company"===U?"#fff":"#666"},children:"By Company"})]})})]}),(0,t.jsx)("div",{style:{display:"quest"===I?"none":"flex",gap:6},children:[{k:"all",l:`All (${a.length})`},{k:"S",l:`S (${V.S})`,c:_.S},{k:"A",l:`A (${V.A})`,c:_.A},{k:"B",l:`B (${V.B})`,c:_.B}].map(e=>(0,t.jsx)("button",{onClick:()=>x(e.k),style:{padding:"4px 12px",borderRadius:16,border:"none",fontSize:11,fontWeight:600,cursor:"pointer",background:f===e.k?e.c||"#fff":"rgba(255,255,255,0.06)",color:f===e.k?"#000":e.c||"#888"},children:e.l},e.k))})]}),(0,t.jsx)("div",{id:"scan-bar-slot"}),"recs"===I&&b.size>0&&(0,t.jsxs)("div",{style:{padding:"10px 24px",background:"rgba(255,215,0,0.08)",borderBottom:"1px solid rgba(255,215,0,0.2)",display:"flex",alignItems:"center",gap:12,flexShrink:0},children:[(0,t.jsxs)("span",{style:{fontSize:12,color:"#FFD700",fontWeight:600},children:[b.size," selected"]}),(0,t.jsxs)("button",{onClick:function(){let e=H.filter(e=>b.has(e.id));if(0===e.length)return;if(1===e.length)return void window.open(e[0].profile_url,"_blank");let t=new Blob([`<!DOCTYPE html><html><head><title>Outlink — ${e.length} profiles</title>
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,2776,e=>{"use strict";var t=e.i(43476),r=e.i(15812);e.s(["default",0,function({children:e}){let{userId:n,ready:i}=(0,r.useUser)();return i&&n?e:(0,t.jsx)("div",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#0a0a1a",color:"#fff",padding:24,textAlign:"center",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'},children:i?(0,t.jsxs)("div",{style:{maxWidth:420},children:[(0,t.jsx)("div",{style:{fontSize:18,fontWeight:700,marginBottom:8},children:"Can’t reach Six Degrees’ local server"}),(0,t.jsx)("div",{style:{color:"#888",fontSize:14,lineHeight:1.6},children:"The page loaded but the app behind it is not answering. If you started it from a terminal, check that window for an error, then reload this page."})]}):(0,t.jsx)("div",{style:{fontSize:18,fontWeight:600},children:"Loading…"})})}])},28867,86106,e=>{"use strict";var t=e.i(71645),r=e.i(7214);let n=Object.freeze({known:!1,sent:new Set,mine:new Map,version:0}),i=new Set,o=n,l=null,s=new Map;function d(e=o.sent,t=o.known){for(let r of(o=Object.freeze({known:t,sent:e,mine:new Map(s),version:o.version+1}),[...i]))r()}function a(e){return i.add(e),l||o.known||(l=fetch("/api/outreach").then(e=>e.ok?e.json():null).then(e=>{e&&d(new Set((e.pending||[]).map(r.keyFor)),!0)}).catch(()=>{}).finally(()=>{l=null})),()=>i.delete(e)}function c(){return o}async function g(e){let t=await fetch("/api/outreach",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),r=await t.json().catch(()=>({}));if(!t.ok)throw Error(r.error||"Could not save that.");return r}async function p(e,{bridgeId:t}={}){let n=(0,r.keyFor)(e),i=s.has(n)?s.get(n):void 0;s.set(n,!0),d();try{return await g({action:"mark-sent",connectionId:e.id,profileUrl:e.profile_url,bridgeId:t})}catch(e){throw void 0===i?s.delete(n):s.set(n,i),d(),e}}async function h(e){let t=(0,r.keyFor)(e),n=s.has(t)?s.get(t):void 0;s.set(t,!1),d();try{return await g({action:"undo",connectionId:e.id,profileUrl:e.profile_url})}catch(e){throw void 0===n?s.delete(t):s.set(t,n),d(),e}}e.s(["REQUESTS_UNKNOWN",0,n,"hasRequest",0,function(e,t=o){if(!e)return!1;let n=(0,r.keyFor)(e);return t.mine.has(n)?t.mine.get(n):t.known?t.sent.has(n):"pending"===e.unlock_status||"sent"===e.outreach_status},"markRequested",0,p,"requestCount",0,function(e=o){let t=new Set(e.known?e.sent:[]);for(let[r,n]of e.mine)n?t.add(r):t.delete(r);return t.size},"requestsNow",0,c,"undoRequest",0,h,"watchRequests",0,a],86106),e.s(["default",0,function(){return(0,t.useSyncExternalStore)(a,c,()=>n)}],28867)},77305,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(19821),i=e.i(64745),o=e.i(22016),l=e.i(48235);let s={S:25,A:15,B:10,C:5,D:2},d={S:100,A:60,B:35,C:15,D:5};var a=e.i(5258),c=e.i(36774);let g={S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"},p="1px solid rgba(255,255,255,0.1)";function h({person:e,size:r=36,ring:n}){let i=g[e?.tier]||"#667";return(0,t.jsxs)("div",{style:{position:"relative",width:r,height:r,flexShrink:0},children:[(0,t.jsx)("div",{style:{width:r,height:r,borderRadius:"50%",background:i,color:e?.tier==="S"?"#000":"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:.34*r,fontWeight:800,border:`2px solid ${n||i}`},children:(0,a.initialsFor)(e?.name||"?")}),(0,c.localPhoto)(e?.profile_image_url)&&(0,t.jsx)("img",{src:(0,c.localPhoto)(e.profile_image_url),alt:"",onError:e=>{e.currentTarget.style.display="none"},style:{position:"absolute",inset:0,width:r,height:r,borderRadius:"50%",objectFit:"cover",border:`2px solid ${n||i}`}})]})}function f({progress:e,size:r=86,color:n="#FF6B35",children:i}){let o=r/2-5,l=2*Math.PI*o;return(0,t.jsxs)("div",{style:{position:"relative",width:r,height:r},children:[(0,t.jsxs)("svg",{width:r,height:r,style:{position:"absolute",inset:0,transform:"rotate(-90deg)"},children:[(0,t.jsx)("circle",{cx:r/2,cy:r/2,r:o,fill:"none",stroke:"rgba(255,255,255,0.08)",strokeWidth:5}),(0,t.jsx)("circle",{cx:r/2,cy:r/2,r:o,fill:"none",stroke:n,strokeWidth:5,strokeLinecap:"round",strokeDasharray:`${l*Math.min(1,e)} ${l}`,style:{transition:"stroke-dasharray 0.5s ease"}})]}),(0,t.jsx)("div",{style:{position:"absolute",inset:9,display:"flex",alignItems:"center",justifyContent:"center"},children:i})]})}function u({recs:e,sentIds:n,added:i,mappedIds:a,reach:c,onSend:y,onUndo:m}){let S=(0,r.useMemo)(()=>(function({recs:e=[],sentIds:t=new Set,added:r=[],mappedIds:n=new Set,reach:i=null}){var o;let a,c,g,p=new Map,h=new Set;for(let t of[...e].sort((e,t)=>(t.priority||0)-(e.priority||0))){if(!t.bridge)continue;let e=`${t.bridge.id}|${t.profile_url||t.id}`;if(h.has(e))continue;h.add(e);let r=p.get(t.bridge.id);r||(r={bridge:t.bridge,people:[]},p.set(t.bridge.id,r)),r.people.push(t)}let f=new Map;for(let e of r){let t=e.unlocked_from_bridge_id;t&&f.set(t,[...f.get(t)||[],e])}let u=[],x=0,b=0;for(let{bridge:e,people:r}of p.values()){let n=r.filter(e=>t.has(e.id)),i=f.get(e.id)||[];b+=n.length,x+=n.reduce((e,t)=>e+(s[t.tier]||2),0),x+=i.reduce((e,t)=>e+(d[t.tier]||5),0);let o=Math.ceil(r.length/5)||1,l=0;for(;l<o-1&&r.slice(5*l,(l+1)*5).every(e=>t.has(e.id));)l++;let a=r.slice(5*l,(l+1)*5),c=a.filter(e=>t.has(e.id)).length,g=c===a.length&&l===o-1;u.push({bridge:e,people:r,stage:l+1,stages:o,targets:a,done:c,progress:a.length?c/a.length:1,complete:g,sent:n.length,added:i,value:a.filter(e=>!t.has(e.id)).reduce((e,t)=>e+(t.priority||0),0),open:{S:a.filter(e=>"S"===e.tier&&!t.has(e.id)).length,A:a.filter(e=>"A"===e.tier&&!t.has(e.id)).length}})}u.sort((e,t)=>e.complete-t.complete||(t.progress>0&&t.progress<1)-(e.progress>0&&e.progress<1)||t.progress-e.progress||t.value-e.value);let y=u.filter(e=>!e.complete).flatMap(e=>e.targets.filter(e=>!t.has(e.id)).map(t=>({person:t,cluster:e,score:(t.priority||0)*(1+.6*e.progress)}))).sort((e,t)=>t.score-e.score),m=new Set,S=[];for(let e of y){let t=e.person.profile_url||e.person.id;if(!m.has(t)&&(m.add(t),S.push(e),3===S.length))break}let k=r.filter(e=>e.unlocked_from_bridge_id).length;return{clusters:u,nextMoves:S,points:x,level:(c=((a=Math.floor(Math.sqrt(Math.max(0,o=x)/40))+1)-1)**2*40,g=a**2*40,{level:a,floor:c,next:g,progress:(o-c)/(g-c)}),sentTotal:b,addedTotal:k,newDoors:r.filter(e=>e.unlocked_from_bridge_id&&"todo"===(0,l.circleState)(e,i||{scanned:n,hidden:new Set})),clearedStages:u.reduce((e,t)=>e+(t.stage-1)+ +!!t.complete,0)}})({recs:e,sentIds:n,added:i,mappedIds:a,reach:c}),[e,n,i,a,c]),[k,j]=(0,r.useState)(null),[v,w]=(0,r.useState)(null),{level:_}=S;async function F(e,t){await y(e);let r=t.done+1,n=String(t.bridge.name||"").split(/[\s,]+/)[0];w(r>=t.targets.length?`+${s[e.tier]||2} \xb7 Stage ${t.stage} of ${n}'s circle cleared — the next 5 are up`:`+${s[e.tier]||2} \xb7 ${n}'s circle ${r}/${t.targets.length}`),setTimeout(()=>w(null),3500)}let z=S.clusters.find(e=>e.bridge.id===k);return(0,t.jsxs)("div",{style:{maxWidth:1100,margin:"0 auto",padding:"16px 20px 60px"},children:[(0,t.jsxs)("div",{style:{display:"flex",gap:16,alignItems:"center",flexWrap:"wrap",padding:16,borderRadius:12,border:p,background:"linear-gradient(135deg, rgba(255,107,53,0.10), rgba(155,89,182,0.08))"},children:[(0,t.jsxs)("div",{style:{width:64,height:64,borderRadius:16,background:"linear-gradient(135deg, #FFD700, #FF6B35)",color:"#000",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[(0,t.jsx)("div",{style:{fontSize:10,fontWeight:800},children:"LEVEL"}),(0,t.jsx)("div",{style:{fontSize:26,fontWeight:900,lineHeight:1},children:_.level})]}),(0,t.jsxs)("div",{style:{flex:1,minWidth:220},children:[(0,t.jsxs)("div",{style:{fontSize:13,color:"#dfe6e9"},children:[(0,t.jsx)("b",{children:S.points})," points · ",(0,t.jsx)("b",{children:_.next-S.points})," to level ",_.level+1]}),(0,t.jsx)("div",{style:{height:8,borderRadius:4,background:"rgba(255,255,255,0.08)",marginTop:6,overflow:"hidden"},children:(0,t.jsx)("div",{style:{height:"100%",width:`${Math.round(100*_.progress)}%`,background:"linear-gradient(90deg, #FFD700, #FF6B35)",transition:"width 0.5s"}})}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#8b9a9a",marginTop:6},children:"Points come from invites you send and people who accept — not from browsing."})]}),[[S.sentTotal,"invites sent"],[S.addedTotal,"people added"],[S.clearedStages,"stages cleared"]].map(([e,r])=>(0,t.jsxs)("div",{style:{textAlign:"center",minWidth:80},children:[(0,t.jsx)("div",{style:{fontSize:24,fontWeight:900},children:e}),(0,t.jsx)("div",{style:{fontSize:11,color:"#8b9a9a"},children:r})]},r))]}),S.newDoors.length>0&&(0,t.jsxs)("div",{style:{marginTop:12,padding:"10px 14px",borderRadius:10,border:"1px solid rgba(0,255,136,0.3)",background:"rgba(0,255,136,0.06)",fontSize:13},children:["🚪 ",(0,t.jsxs)("b",{children:[S.newDoors.length," new ",1===S.newDoors.length?"door":"doors",":"]})," people you added through a circle, whose own circle isn’t mapped yet. That’s the next degree. ",(0,t.jsx)(o.default,{href:"/setup",style:{color:"#00ff88"},children:"Map them on the Scan page →"})]}),S.nextMoves.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h3",{style:{margin:"22px 0 10px",fontSize:15},children:"Next best moves"}),(0,t.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(300px, 1fr))",gap:12},children:S.nextMoves.map(({person:e,cluster:r},n)=>(0,t.jsxs)("div",{style:{padding:14,borderRadius:12,border:`1px solid ${g[e.tier]}55`,background:"rgba(255,255,255,0.03)",position:"relative"},children:[(0,t.jsxs)("div",{style:{position:"absolute",top:10,right:12,fontSize:11,fontWeight:800,color:"#FF6B35"},children:["#",n+1]}),(0,t.jsxs)("div",{style:{display:"flex",gap:10,alignItems:"center"},children:[(0,t.jsx)(h,{person:e,size:44}),(0,t.jsxs)("div",{style:{minWidth:0},children:[(0,t.jsx)("div",{style:{fontWeight:700,fontSize:14},children:e.name}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#8b9a9a",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:220},children:e.headline})]})]}),(0,t.jsxs)("div",{style:{fontSize:11.5,color:"#aab7b7",margin:"10px 0"},children:["via ",(0,t.jsx)("b",{style:{color:g[r.bridge.tier]},children:r.bridge.name})," · their circle ",r.done,"/",r.targets.length," this stage"]}),(0,t.jsxs)("div",{style:{display:"flex",gap:8},children:[e.profile_url&&(0,t.jsx)("a",{href:e.profile_url,target:"_blank",rel:"noopener noreferrer",style:b,children:"Open on LinkedIn"}),(0,t.jsxs)("button",{onClick:()=>F(e,r),style:x,children:["I sent an invite · +",s[e.tier]||2]})]})]},e.id))})]}),(0,t.jsx)("h3",{style:{margin:"26px 0 4px",fontSize:15},children:"Circles to work through"}),(0,t.jsxs)("div",{style:{fontSize:12,color:"#8b9a9a",marginBottom:12},children:["Each is one of your connections and the best people they know, ",5," at a time. Fill the ring to clear a stage."]}),(0,t.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(190px, 1fr))",gap:12},children:S.clusters.map(e=>{let r=k===e.bridge.id;return(0,t.jsxs)("button",{onClick:()=>j(r?null:e.bridge.id),style:{padding:12,borderRadius:12,cursor:"pointer",textAlign:"center",color:"#fff",border:r?"1px solid #FF6B35":p,background:e.complete?"rgba(0,255,136,0.06)":"rgba(255,255,255,0.03)",display:"flex",flexDirection:"column",alignItems:"center",gap:6},children:[(0,t.jsx)(f,{progress:e.progress,color:e.complete?"#00ff88":"#FF6B35",children:(0,t.jsx)(h,{person:e.bridge,size:60})}),(0,t.jsx)("div",{style:{fontWeight:700,fontSize:13,maxWidth:170,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.bridge.name}),(0,t.jsx)("div",{style:{fontSize:11,color:e.complete?"#00ff88":"#aab7b7"},children:e.complete?"Circle cleared":`Stage ${e.stage} of ${e.stages} \xb7 ${e.done}/${e.targets.length}`}),(0,t.jsx)("div",{style:{display:"flex",gap:4},children:e.targets.map(e=>(0,t.jsx)("span",{title:e.name,style:{width:12,height:12,borderRadius:"50%",border:`2px solid ${g[e.tier]||"#667"}`,background:n.has(e.id)?g[e.tier]||"#667":"transparent"}},e.id))}),(0,t.jsxs)("div",{style:{fontSize:10.5,color:"#778"},children:[e.open.S?`${e.open.S} S \xb7 `:"",e.open.A?`${e.open.A} A \xb7 `:"",e.people.length," worth adding",e.added.length?` \xb7 ★ ${e.added.length} added`:""]})]},e.bridge.id)})}),z&&(0,t.jsxs)("div",{style:{marginTop:14,padding:16,borderRadius:12,border:"1px solid rgba(255,107,53,0.4)",background:"rgba(255,107,53,0.05)"},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:10},children:[(0,t.jsx)(h,{person:z.bridge,size:40}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{style:{fontWeight:800},children:[z.bridge.name,"’s circle · stage ",z.stage," of ",z.stages]}),(0,t.jsxs)("div",{style:{fontSize:12,color:"#aab7b7"},children:["Ask ",z.bridge.name?.split(" ")[0]," for an intro, or invite them directly. Mark each one when it’s sent."]})]})]}),z.targets.map(e=>{let r=n.has(e.id);return(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"8px 0",borderTop:"1px solid rgba(255,255,255,0.05)"},children:[(0,t.jsx)(h,{person:e,size:34,ring:r?"#00ff88":void 0}),(0,t.jsxs)("div",{style:{flex:1,minWidth:0},children:[(0,t.jsxs)("div",{style:{fontWeight:600,fontSize:13},children:[e.name," ",(0,t.jsx)("span",{style:{color:g[e.tier],fontSize:11},children:e.tier})]}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#8b9a9a",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.headline})]}),e.profile_url&&(0,t.jsx)("a",{href:e.profile_url,target:"_blank",rel:"noopener noreferrer",style:b,children:"LinkedIn"}),r?(0,t.jsx)("button",{onClick:()=>m(e),style:{...b,color:"#00ff88"},children:"Sent ✓ (undo)"}):(0,t.jsxs)("button",{onClick:()=>F(e,z),style:x,children:["Sent · +",s[e.tier]||2]})]},e.id)}),z.added.length>0&&(0,t.jsxs)("div",{style:{marginTop:10,fontSize:12,color:"#00ff88"},children:["★ Added from this circle: ",z.added.map(e=>e.name).join(", ")]})]}),v&&(0,t.jsx)("div",{role:"status",style:{position:"fixed",bottom:24,left:"50%",transform:"translateX(-50%)",padding:"10px 18px",borderRadius:24,background:"linear-gradient(135deg, #FFD700, #FF6B35)",color:"#000",fontWeight:800,fontSize:13,boxShadow:"0 8px 30px rgba(0,0,0,0.5)",zIndex:50},children:v})]})}let x={padding:"7px 12px",borderRadius:8,border:"none",cursor:"pointer",fontWeight:800,fontSize:12,background:"linear-gradient(135deg, #FF6B35, #FFD700)",color:"#000"},b={padding:"7px 12px",borderRadius:8,border:p,cursor:"pointer",fontWeight:600,fontSize:12,background:"rgba(255,255,255,0.05)",color:"#dfe6e9",textDecoration:"none"};var y=e.i(2776),m=e.i(15812),S=e.i(90179),k=e.i(28867),j=e.i(86106),v=e.i(7214),w=e.i(40996);let _={S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"};function F(){let{userId:e,userProfile:s}=(0,m.useUser)(),d=s?.sectors||[],[a,g]=(0,r.useState)([]),[p,h]=(0,r.useState)(!0),[f,x]=(0,r.useState)("all"),[b,y]=(0,r.useState)(new Set),F=(0,k.default)(),[z,B]=(0,r.useState)([]),[C,R]=(0,r.useState)({}),[I,W]=(0,r.useState)("quest"),[A,$]=(0,r.useState)([]),[M,D]=(0,r.useState)(()=>new Set),[T,O]=(0,r.useState)(null),[E,P]=(0,r.useState)(null),[U,L]=(0,r.useState)(()=>{{let e=new URLSearchParams(window.location.search);if(e.get("groupBy"))return e.get("groupBy")}return"bridge"});(0,r.useEffect)(()=>{{let e=new URLSearchParams(window.location.search).get("bridge");e&&P(e)}},[]),(0,r.useEffect)(()=>{!i.IS_DEMO&&e&&t();async function t(){let[t,r,i]=await Promise.all([(0,n.loadNetwork)(e),fetch(`/api/outreach?userId=${e}`).then(e=>e.json()).catch(()=>({pending:[]})),(0,w.loadScanNotes)()]),o=t.degree1,s=t.degree2;$(o.filter(e=>e.unlocked_from_bridge_id)),D(new Set(s.map(e=>e.source_connection_id).filter(Boolean))),O((0,l.reachIndex)(o,s,i));let a=new Set(o.map(e=>e.profile_url)),c={};o.forEach(e=>{c[e.id]=e}),B(r.pending||[]),R(c),g(s.filter(e=>("S"===e.tier||"A"===e.tier||"B"===e.tier)&&!a.has(e.profile_url)).map(e=>{let t,r,n=c[e.source_connection_id],i=(t=parseFloat(e.power_score)||0,r=(e.headline||"").toLowerCase(),(0,S.rowCompanyScore)(e)>=S.TOP_COMPANY&&(t+=1),(d||[]).forEach(e=>{r.includes(e.toLowerCase())&&(t+=.5)}),"S"===e.tier?t*=1.5:"A"===e.tier&&(t*=1.2),t),o="S"===e.tier?50:"A"===e.tier?25:10;return{...e,bridge:n,priority:i,xp:o}}).sort((e,t)=>t.priority-e.priority)),h(!1)}},[e]);let q=(0,r.useMemo)(()=>new Set([...z,...a].filter(e=>(0,j.hasRequest)(e,F)).map(e=>e.id)),[z,a,F]),N=(0,r.useMemo)(()=>{let e=new Set,t=[];for(let r of[...z,...a]){let n=(0,v.keyFor)(r);!e.has(n)&&(0,j.hasRequest)(r,F)&&(e.add(n),t.push({...r,bridge:C[r.source_connection_id]||r.bridge||null}))}return t},[z,a,F,C]);if(i.IS_DEMO)return(0,t.jsxs)("div",{style:{minHeight:"100vh",background:"#0a0a1a",color:"rgba(255,255,255,0.7)",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:10,textAlign:"center",padding:24},children:[(0,t.jsx)("h2",{style:{margin:0,fontSize:18,fontWeight:700,color:"#fff"},children:"Not part of the demo"}),(0,t.jsx)("div",{style:{fontSize:13},children:"The public demo includes the Network Circle and Degrees views only."}),(0,t.jsx)(o.default,{href:"/",style:{fontSize:12,color:"rgba(255,255,255,0.5)",textDecoration:"none"},children:"← Back to the network"})]});let H="all"===f?a:a.filter(e=>e.tier===f);E&&(H=H.filter(e=>e.bridge?.id===E));let V={S:0,A:0,B:0};a.forEach(e=>{void 0!==V[e.tier]&&V[e.tier]++});let Y={};H.forEach(e=>{let t;Y[t="bridge"===U?e.bridge?.id||"unknown":"company"===U?(e.company||"Unknown").trim()||"Unknown":e.tier]||(Y[t]=[]),Y[t].push(e)});let K={S:0,A:1,B:2},G=Object.entries(Y).sort((e,t)=>{if("tier"===U)return(K[e[0]]||9)-(K[t[0]]||9);if("bridge"===U){let r=e[1][0]?.bridge,n=t[1][0]?.bridge,i=K[r?.tier]??9,o=K[n?.tier]??9;if(i!==o)return i-o}return t[1].length-e[1].length});function X(e){y(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r})}return p?(0,t.jsx)("div",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#0a0a1a",color:"#fff"},children:"Loading..."}):(0,t.jsxs)("div",{style:{height:"100vh",background:"#0a0a1a",color:"#fff",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',display:"flex",flexDirection:"column",overflow:"hidden"},children:[(0,t.jsxs)("header",{style:{padding:"14px 24px",borderBottom:"1px solid rgba(255,255,255,0.1)",flexShrink:0},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:10},children:[(0,t.jsxs)(o.default,{href:"/",style:{display:"flex",alignItems:"center",gap:6,color:"#888",textDecoration:"none",fontSize:13,fontWeight:600,padding:"6px 14px",borderRadius:6,background:"rgba(255,255,255,0.06)",border:"1px solid rgba(255,255,255,0.1)"},children:[(0,t.jsx)("span",{style:{fontSize:16},children:"←"})," Map"]}),(0,t.jsx)("h1",{style:{fontSize:20,fontWeight:700,margin:0,background:"linear-gradient(135deg, #FF6B35, #FFD700)",WebkitBackgroundClip:"text",WebkitTextFillColor:"transparent"},children:"Outlink"}),(0,t.jsxs)("div",{style:{display:"flex",gap:2,background:"rgba(255,255,255,0.06)",borderRadius:6,padding:2},children:[(0,t.jsx)("button",{onClick:()=>W("quest"),style:{padding:"5px 12px",borderRadius:4,border:"none",fontSize:11,fontWeight:700,cursor:"pointer",background:"quest"===I?"linear-gradient(135deg, #FFD700, #FF6B35)":"transparent",color:"quest"===I?"#000":"#FFD700"},children:"Circles"}),(0,t.jsxs)("button",{onClick:()=>W("recs"),style:{padding:"5px 12px",borderRadius:4,border:"none",fontSize:11,fontWeight:600,cursor:"pointer",background:"recs"===I?"#fff":"transparent",color:"recs"===I?"#000":"#888"},children:["To Add (",a.length,")"]}),(0,t.jsxs)("button",{onClick:()=>W("pending"),style:{padding:"5px 12px",borderRadius:4,border:"none",fontSize:11,fontWeight:600,cursor:"pointer",background:"pending"===I?"linear-gradient(135deg, #FF6B35, #FFD700)":"transparent",color:"pending"===I?"#000":"#FF6B35"},children:["Pending (",N.length,")"]})]}),(0,t.jsx)("div",{style:{marginLeft:"auto",display:"flex",gap:6},children:"recs"===I&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{onClick:()=>L("tier"),style:{padding:"4px 10px",borderRadius:4,border:"none",fontSize:10,fontWeight:600,cursor:"pointer",background:"tier"===U?"rgba(255,255,255,0.15)":"rgba(255,255,255,0.05)",color:"tier"===U?"#fff":"#666"},children:"By Tier"}),(0,t.jsx)("button",{onClick:()=>L("bridge"),style:{padding:"4px 10px",borderRadius:4,border:"none",fontSize:10,fontWeight:600,cursor:"pointer",background:"bridge"===U?"rgba(255,255,255,0.15)":"rgba(255,255,255,0.05)",color:"bridge"===U?"#fff":"#666"},children:"By Bridge"}),(0,t.jsx)("button",{onClick:()=>L("company"),style:{padding:"4px 10px",borderRadius:4,border:"none",fontSize:10,fontWeight:600,cursor:"pointer",background:"company"===U?"rgba(255,255,255,0.15)":"rgba(255,255,255,0.05)",color:"company"===U?"#fff":"#666"},children:"By Company"})]})})]}),(0,t.jsx)("div",{style:{display:"quest"===I?"none":"flex",gap:6},children:[{k:"all",l:`All (${a.length})`},{k:"S",l:`S (${V.S})`,c:_.S},{k:"A",l:`A (${V.A})`,c:_.A},{k:"B",l:`B (${V.B})`,c:_.B}].map(e=>(0,t.jsx)("button",{onClick:()=>x(e.k),style:{padding:"4px 12px",borderRadius:16,border:"none",fontSize:11,fontWeight:600,cursor:"pointer",background:f===e.k?e.c||"#fff":"rgba(255,255,255,0.06)",color:f===e.k?"#000":e.c||"#888"},children:e.l},e.k))})]}),"recs"===I&&b.size>0&&(0,t.jsxs)("div",{style:{padding:"10px 24px",background:"rgba(255,215,0,0.08)",borderBottom:"1px solid rgba(255,215,0,0.2)",display:"flex",alignItems:"center",gap:12,flexShrink:0},children:[(0,t.jsxs)("span",{style:{fontSize:12,color:"#FFD700",fontWeight:600},children:[b.size," selected"]}),(0,t.jsxs)("button",{onClick:function(){let e=H.filter(e=>b.has(e.id));if(0===e.length)return;if(1===e.length)return void window.open(e[0].profile_url,"_blank");let t=new Blob([`<!DOCTYPE html><html><head><title>Outlink — ${e.length} profiles</title>
2
2
  <style>body{background:#0a0a1a;color:#fff;font-family:-apple-system,sans-serif;padding:24px;margin:0}
3
3
  h2{color:#FFD700;margin-bottom:4px}p{color:#888;font-size:13px;margin-bottom:16px}
4
4
  .btn{display:block;padding:12px 16px;margin-bottom:6px;background:rgba(255,255,255,0.06);
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.10] - 2026-09-29
10
+
11
+ ### Changed
12
+ - **The scan status bar is now a notch.** A small pill hangs from the bottom of the header,
13
+ centred, on every page. It shows nothing while nothing runs, only a tiny dimmed *Auto scan*
14
+ while the all-day mode waits, and while a scan runs, what it's doing with a thin progress
15
+ line. Hover or click to open it: who, today's searches, the latest line, *Details* and
16
+ *Stop*. Other long jobs show there too, starting with recording the Galaxy's replay.
17
+
9
18
  ## [0.4.9] - 2026-09-29
10
19
 
11
20
  ### Added
@@ -12,6 +12,7 @@ import {
12
12
  layoutsNow, watchLayouts, saveLayout, applyLayout, forgetLayout, milestones,
13
13
  } from '../../lib/galaxy-lab';
14
14
  import { savePicture, recordReplay, canRecord } from '../../lib/galaxy-export';
15
+ import { showActivity } from '../../lib/island';
15
16
 
16
17
  const noLayouts = [];
17
18
 
@@ -89,7 +90,9 @@ export default function GalaxyLab() {
89
90
  const run = async (what, job) => {
90
91
  setBusy(what);
91
92
  setNote(null);
92
- try { await job(); } catch (e) { setNote(e.message || 'That didn’t work.'); } finally { setBusy(null); }
93
+ // A recording runs for the whole replay: the notch under the header shows it.
94
+ const done = what === 'video' ? showActivity({ id: 'replay-video', label: 'Recording the replay', detail: 'The video saves when it ends' }) : () => {};
95
+ try { await job(); } catch (e) { setNote(e.message || 'That didn’t work.'); } finally { setBusy(null); done(); }
93
96
  };
94
97
  const canReplay = clock.min != null && clock.max != null && clock.max > clock.min;
95
98
  const preset = FORCES.every((f) => lab[f.key] === LAB_DEFAULTS[f.key]) ? 'rings'
@@ -1,18 +1,21 @@
1
1
  'use client';
2
2
 
3
- // The scan status bar: while a scan runs, every page shows what it's doing,
4
- // for whom, how far it's got, and today's LinkedIn budget, with Stop. Stop
5
- // saves what was read, and the Scan page's Resume carries on from that page.
6
- // It sits just under the header's tabs (Network Circle, Degrees…), on every
7
- // page, the Scan page too (Blake, 2026-09-29). It only reports: the
8
- // pacing and the caps live in the scanner (scripts/scrape.py, lib/linkedin-limits.js).
3
+ // The notch: a small pill hanging from the bottom of the header, centred, on
4
+ // every page (Blake, 2026-09-29: "a notch ui of the thing scanning"). It stays
5
+ // out of the way: nothing at all while nothing runs; a tiny dimmed "Auto scan"
6
+ // when the all-day mode is on but idle; while a scan runs, what it's doing and
7
+ // how far it's got. Hover or click it to open it: who, today's LinkedIn budget,
8
+ // the latest line, Details and Stop. Stop saves what was read, and the Scan
9
+ // page's Resume carries on from that page. Other long jobs can show here too
10
+ // (lib/island.js). It only reports: the pacing and the caps live in the scanner
11
+ // (scripts/scrape.py, lib/linkedin-limits.js).
9
12
 
10
13
  import { useEffect, useState, useSyncExternalStore } from 'react';
11
- import { createPortal } from 'react-dom';
12
14
  import { usePathname } from 'next/navigation';
13
15
  import Link from 'next/link';
14
16
  import { watchScanner, scannerNow, stopScrape } from '../../lib/scraper-client';
15
17
  import { watchAllDay, allDayNow } from '../../lib/experimental-client';
18
+ import { watchActivities, activitiesNow, noActivities } from '../../lib/island';
16
19
 
17
20
  const WHAT = {
18
21
  full: 'Scanning your network',
@@ -36,33 +39,35 @@ const tone = (used, cap) => (!cap ? '#8b9a9a' : used / cap >= 0.9 ? '#ff6b6b' :
36
39
  export default function ScanStatusBar() {
37
40
  const [job, setJob] = useState(() => scannerNow());
38
41
  const [stopping, setStopping] = useState(false);
39
- // The Scan page's experimental all-day Auto-Bridge switch: with it on, the bar
40
- // stays under the tabs even while nothing runs, so you can see the mode is on.
42
+ const [open, setOpen] = useState(false);
43
+ const [pinned, setPinned] = useState(false);
41
44
  const allDay = useSyncExternalStore(watchAllDay, allDayNow, () => false);
42
- // Where it sits: in the page's own slot under its header when the page has one
43
- // (it then pushes the page down rather than covering it), otherwise fixed just
44
- // under the header's buttons, measured, since a header can wrap to two rows.
45
+ const others = useSyncExternalStore(watchActivities, activitiesNow, noActivities);
46
+ useEffect(() => watchScanner(() => {
47
+ const now = scannerNow();
48
+ setJob(now);
49
+ if (!now.running) setStopping(false);
50
+ }), []);
51
+
52
+ // Hangs from the header's bottom edge, measured: the header can load late,
53
+ // be swapped for a new one, or wrap to two rows.
45
54
  const pathname = usePathname();
46
- const [spot, setSpot] = useState({ slot: null, top: null });
55
+ const [top, setTop] = useState(null);
47
56
  useEffect(() => {
48
- // The header can load late or be swapped for a new one (a page that shows
49
- // "Loading…" first), so it's found again whenever the page's elements change,
50
- // and its size is watched for a wrap to two rows.
51
57
  let header = null;
52
58
  let ro = null;
53
59
  let queued = 0;
54
60
  const measure = () => {
55
61
  queued = 0;
56
- const slot = document.getElementById('scan-bar-slot');
57
- const now = slot ? null : document.querySelector('header');
62
+ const now = document.querySelector('header');
58
63
  if (now !== header) {
59
64
  ro?.disconnect();
60
65
  ro = null;
61
66
  header = now;
62
67
  if (header) { ro = new ResizeObserver(later); ro.observe(header); }
63
68
  }
64
- const top = header ? Math.round(header.getBoundingClientRect().bottom) + 6 : null;
65
- setSpot((was) => (was.slot === slot && was.top === top ? was : { slot, top }));
69
+ const at = header ? Math.round(header.getBoundingClientRect().bottom) : null;
70
+ setTop((was) => (was === at ? was : at));
66
71
  };
67
72
  const later = () => { if (!queued) queued = requestAnimationFrame(measure); };
68
73
  later();
@@ -71,63 +76,83 @@ export default function ScanStatusBar() {
71
76
  window.addEventListener('resize', later);
72
77
  return () => { cancelAnimationFrame(queued); ro?.disconnect(); mo.disconnect(); window.removeEventListener('resize', later); };
73
78
  }, [pathname]);
74
- useEffect(() => watchScanner(() => {
75
- const now = scannerNow();
76
- setJob(now);
77
- if (!now.running) setStopping(false);
78
- }), []);
79
- const place = {
80
- ...(spot.slot
81
- ? { position: 'relative', margin: '8px auto 12px', width: 'fit-content' }
82
- : { position: 'fixed', left: '50%', top: spot.top != null ? spot.top : 'var(--scan-bar-top, 94px)', transform: 'translateX(-50%)', zIndex: 60 }),
83
- maxWidth: 'calc(100vw - 32px)', display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'nowrap', whiteSpace: 'nowrap',
84
- padding: '8px 12px', borderRadius: 12, fontSize: 12, color: '#cfd8d8', background: 'rgba(14,16,32,0.94)',
85
- };
86
- const put = (bar) => (spot.slot && document.body.contains(spot.slot) ? createPortal(bar, spot.slot) : bar);
87
- if (!job?.running) {
88
- if (!allDay) return null;
89
- return put(
90
- <div role="status" style={{ ...place, opacity: 0.55, border: '1px solid rgba(255,255,255,0.1)' }}>
91
- <span style={{ width: 8, height: 8, borderRadius: '50%', background: '#556', flexShrink: 0 }} />
92
- <b style={{ color: '#b8c4c4' }}>Auto scan</b>
93
- <span style={{ color: '#8b9a9a' }}>ready · press Auto scan beside Scan to start</span>
94
- </div>
95
- );
96
- }
97
79
 
98
- const p = job.progress;
80
+ const running = !!job?.running;
81
+ const other = others[others.length - 1] || null;
82
+ if (!running && !other && !allDay) return null;
83
+
84
+ const p = job?.progress;
99
85
  const step = p?.kind === 'batch' && p.total ? `${p.current || p.done || 0} of ${p.total}`
100
- : p?.kind === 'walk' && p.total ? `${(p.done || 0).toLocaleString()} of ${p.total.toLocaleString()} read`
86
+ : p?.kind === 'walk' && p.total ? `${(p.done || 0).toLocaleString()} of ${p.total.toLocaleString()}`
101
87
  : p?.kind === 'saving' ? 'saving' : null;
102
- const b = job.budget;
103
- const last = [...(job.log || [])].reverse().find((l) => l && l.trim())?.trim();
88
+ const fraction = p?.total ? Math.min(1, (p.current || p.done || 0) / p.total) : other?.progress ?? null;
89
+ const b = job?.budget;
90
+ const last = running ? [...(job.log || [])].reverse().find((l) => l && l.trim())?.trim() : null;
91
+ const expanded = open || pinned;
104
92
 
105
- return put(
106
- <div role="status" aria-live="polite" style={{ ...place, border: '1px solid rgba(0,255,136,0.25)' }}>
107
- <span style={{ width: 8, height: 8, borderRadius: '50%', background: '#00ff88', flexShrink: 0 }} />
108
- <b style={{ color: '#fff' }}>{WHAT[job.action] || 'Scanning'}</b>
109
- {job.target?.name && <span>{job.target.name}</span>}
110
- {step && <span style={{ color: '#8b9a9a' }}>{step}</span>}
111
- {b && (
112
- <span style={{ color: tone(b.searches, b.cap) }} title="Searches on your LinkedIn account in the last 24 hours, and your daily budget">
113
- {b.searches}{b.cap ? ` of ${b.cap}` : ''} searches today
114
- </span>
93
+ // What the pill says, smallest first.
94
+ const dot = running ? '#00ff88' : other ? (other.tone === 'warn' ? '#FFD700' : '#3498DB') : '#556';
95
+ const label = running ? (WHAT[job.action] || 'Scanning') : other ? other.label : 'Auto scan';
96
+ const short = running ? step : other ? other.detail : null;
97
+
98
+ return (
99
+ <div
100
+ role="status"
101
+ aria-live="polite"
102
+ onMouseEnter={() => setOpen(true)}
103
+ onMouseLeave={() => setOpen(false)}
104
+ style={{
105
+ position: 'fixed', left: '50%', top: top ?? 'var(--scan-bar-top, 94px)', transform: 'translateX(-50%)', zIndex: 60,
106
+ maxWidth: 'calc(100vw - 32px)', minWidth: running || other ? 180 : 0,
107
+ padding: expanded ? '8px 14px 10px' : '4px 12px 6px',
108
+ borderRadius: '0 0 16px 16px', borderTop: 'none',
109
+ border: `1px solid ${running ? 'rgba(0,255,136,0.25)' : 'rgba(255,255,255,0.1)'}`,
110
+ background: 'rgba(8,10,22,0.96)', color: '#cfd8d8', fontSize: 12,
111
+ opacity: running || other || expanded ? 1 : 0.55,
112
+ boxShadow: running ? '0 6px 20px rgba(0,0,0,0.35)' : 'none',
113
+ transition: 'padding 0.18s ease, opacity 0.18s ease',
114
+ }}
115
+ >
116
+ <button
117
+ onClick={() => setPinned((v) => !v)}
118
+ aria-expanded={expanded}
119
+ title={expanded ? 'Close' : 'Open'}
120
+ style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%', background: 'none', border: 'none', color: 'inherit', font: 'inherit', cursor: 'pointer', padding: 0, whiteSpace: 'nowrap' }}
121
+ >
122
+ <span className={running ? 'notch-pulse' : undefined} style={{ width: 7, height: 7, borderRadius: '50%', background: dot, flexShrink: 0 }} />
123
+ <b style={{ color: running || other ? '#fff' : '#b8c4c4', fontWeight: 600 }}>{label}</b>
124
+ {short && <span style={{ color: '#8b9a9a' }}>{short}</span>}
125
+ {!running && !other && expanded && <span style={{ color: '#8b9a9a' }}>ready · press Auto scan beside Scan to start</span>}
126
+ </button>
127
+ {fraction != null && (
128
+ <div style={{ height: 2, marginTop: 5, borderRadius: 2, background: 'rgba(255,255,255,0.08)', overflow: 'hidden' }}>
129
+ <div style={{ width: `${Math.round(fraction * 100)}%`, height: '100%', background: running ? '#00ff88' : '#3498DB', transition: 'width 0.4s ease' }} />
130
+ </div>
115
131
  )}
116
- {last && (
117
- <span style={{ color: '#667', flex: '0 1 240px', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={last}>
118
- {last}
119
- </span>
132
+ {expanded && running && (
133
+ <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 8, flexWrap: 'wrap' }}>
134
+ {job.target?.name && <span>{job.target.name}</span>}
135
+ {b && (
136
+ <span style={{ color: tone(b.searches, b.cap) }} title="Searches on your LinkedIn account in the last 24 hours, and your daily budget">
137
+ {b.searches}{b.cap ? ` of ${b.cap}` : ''} searches today
138
+ </span>
139
+ )}
140
+ {last && (
141
+ <span style={{ color: '#667', maxWidth: 280, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={last}>{last}</span>
142
+ )}
143
+ <Link href="/setup" style={{ color: '#3498DB', textDecoration: 'none' }}>Details</Link>
144
+ <button
145
+ onClick={async () => { setStopping(true); try { await stopScrape(); } catch { setStopping(false); } }}
146
+ disabled={stopping}
147
+ title="Stops after saving what's been read; Resume on the Scan page carries on from the same page"
148
+ style={{
149
+ padding: '3px 10px', borderRadius: 8, fontSize: 12, cursor: stopping ? 'default' : 'pointer',
150
+ background: 'rgba(255,107,107,0.12)', color: '#ff9b9b', border: '1px solid rgba(255,107,107,0.35)',
151
+ }}
152
+ >{stopping ? 'Stopping…' : 'Stop'}</button>
153
+ </div>
120
154
  )}
121
- <Link href="/setup" style={{ color: '#3498DB', textDecoration: 'none' }}>Details</Link>
122
- <button
123
- onClick={async () => { setStopping(true); try { await stopScrape(); } catch { setStopping(false); } }}
124
- disabled={stopping}
125
- title="Stops after saving what's been read; Resume on the Scan page carries on from the same page"
126
- style={{
127
- padding: '4px 10px', borderRadius: 8, fontSize: 12, cursor: stopping ? 'default' : 'pointer',
128
- background: 'rgba(255,107,107,0.12)', color: '#ff9b9b', border: '1px solid rgba(255,107,107,0.35)',
129
- }}
130
- >{stopping ? 'Stopping…' : 'Stop'}</button>
155
+ {expanded && !running && other?.detail && <div style={{ marginTop: 6, color: '#8b9a9a' }}>{other.detail}</div>}
131
156
  </div>
132
157
  );
133
158
  }
@@ -42,3 +42,7 @@ html:has([data-field-question]) {
42
42
  /* Where the scan status bar sits: just under the header (app/components/ScanStatusBar.js). */
43
43
  :root { --scan-bar-top: 94px; }
44
44
  @media (max-width: 767px) { :root { --scan-bar-top: 66px; } }
45
+
46
+ /* The notch's running dot (app/components/ScanStatusBar.js). */
47
+ @keyframes notch-pulse { 50% { opacity: 0.35; } }
48
+ @media (prefers-reduced-motion: no-preference) { .notch-pulse { animation: notch-pulse 1.6s ease-in-out infinite; } }
@@ -302,8 +302,6 @@ function PathsInner() {
302
302
  )}
303
303
  </div>
304
304
  </header>
305
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
306
- <div id="scan-bar-slot" />
307
305
 
308
306
  {!selectedCompany && tab !== 'companies' ? (
309
307
  <PathsAnalyzer d1={d1Data} d2={d2Data} d3={d3Data} tab={tab}
@@ -164,8 +164,6 @@ function ProfileInner() {
164
164
  WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent',
165
165
  }}>Profile</h1>
166
166
  </header>
167
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
168
- <div id="scan-bar-slot" />
169
167
 
170
168
  <div style={{ flex: 1, overflow: 'auto', padding: '30px 20px' }}>
171
169
  <div style={{ maxWidth: 700, margin: '0 auto' }}>
@@ -301,8 +301,6 @@ function QueueInner() {
301
301
  ))}
302
302
  </div>
303
303
  </header>
304
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
305
- <div id="scan-bar-slot" />
306
304
 
307
305
  {/* Batch action bar — recs view only */}
308
306
  {view === 'recs' && selected.size > 0 && (
@@ -56,8 +56,6 @@ function ScoresInner() {
56
56
  WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent',
57
57
  }}>Scores</h1>
58
58
  </header>
59
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
60
- <div id="scan-bar-slot" />
61
59
  <main style={{ maxWidth: 980, margin: '0 auto', padding: '8px 24px 64px' }}>
62
60
  <Body style={{ marginTop: 16 }}>
63
61
  How someone&rsquo;s power score is worked out, and the three things you can change about it:{' '}
@@ -73,8 +73,6 @@ function SettingsInner() {
73
73
  WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent',
74
74
  }}>Settings</h1>
75
75
  </header>
76
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
77
- <div id="scan-bar-slot" />
78
76
 
79
77
  <main style={{ maxWidth: 720, margin: '0 auto', padding: '8px 24px 64px' }}>
80
78
  {error && <Body style={{ color: '#ff7676', marginTop: 16 }}>{error}</Body>}
@@ -203,8 +203,6 @@ function SetupInner() {
203
203
  WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent',
204
204
  }}>Scan your network</h1>
205
205
  </header>
206
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
207
- <div id="scan-bar-slot" />
208
206
 
209
207
  <div style={{ maxWidth: 720, margin: '0 auto', padding: '32px 24px 64px' }}>
210
208
 
@@ -226,8 +226,6 @@ function SocialInner() {
226
226
  <Link href="/" style={{ color: '#888', textDecoration: 'none', fontSize: 13, fontWeight: 600, padding: '6px 14px', borderRadius: 6, background: 'rgba(255,255,255,0.06)', border: LINE }}>← Back to Map</Link>
227
227
  <h1 style={{ fontSize: 22, fontWeight: 700, margin: 0, color: '#FFD700' }}>Social <span style={{ fontSize: 12, color: '#8b9a9a', fontWeight: 600 }}>experimental</span></h1>
228
228
  </header>
229
- {/* The scan status bar sits here, under the header's buttons (ScanStatusBar.js). */}
230
- <div id="scan-bar-slot" />
231
229
  <main style={{ maxWidth: 980, margin: '0 auto', padding: '8px 24px 64px' }}>
232
230
  <Body style={{ marginTop: 16 }}>
233
231
  Who you&rsquo;re warm with, who&rsquo;s waiting on a reply, and how each chapter of your career built your network,
@@ -0,0 +1,36 @@
1
+ // The notch (app/components/ScanStatusBar.js): one small pill hanging under the
2
+ // header that shows what the app is doing. The scanner shows there on its own;
3
+ // anything else that runs for a while (a replay being recorded, an import) can
4
+ // show there too, through this list.
5
+ //
6
+ // const done = showActivity({ id: 'replay', label: 'Recording the replay', detail: '12 s' });
7
+ // … later: done();
8
+ //
9
+ // An activity is { id, label, detail?, progress? (0–1), tone? ('run' | 'idle' | 'warn') }.
10
+ // Showing the same id again replaces it. The list only changes when something
11
+ // in it does, as useSyncExternalStore needs.
12
+
13
+ const listeners = new Set();
14
+ let activities = [];
15
+
16
+ export const activitiesNow = () => activities;
17
+ const EMPTY = [];
18
+ export const noActivities = () => EMPTY;
19
+
20
+ export function watchActivities(f) {
21
+ listeners.add(f);
22
+ return () => listeners.delete(f);
23
+ }
24
+
25
+ export function showActivity(a) {
26
+ if (!a?.id) return () => {};
27
+ activities = [...activities.filter((x) => x.id !== a.id), a];
28
+ listeners.forEach((f) => f());
29
+ return () => clearActivity(a.id);
30
+ }
31
+
32
+ export function clearActivity(id) {
33
+ if (!activities.some((x) => x.id === id)) return;
34
+ activities = activities.filter((x) => x.id !== id);
35
+ listeners.forEach((f) => f());
36
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "six-degrees",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "six-degrees",
9
- "version": "0.4.9",
9
+ "version": "0.4.10",
10
10
  "license": "MIT",
11
11
  "os": [
12
12
  "darwin",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "six-degrees",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "description": "Map your professional network as a galaxy — leverage tiers, bridges into new circles, and the shortest path to anyone. Runs locally on your own data.",
5
5
  "license": "MIT",
6
6
  "author": "Blake Burford",