six-degrees 0.4.8 → 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 (239) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/routes-manifest.json +6 -0
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  12. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.rsc +13 -13
  15. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  17. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +2 -1
  23. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/company-scores/route.js +2 -1
  25. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/scraper/route.js +2 -2
  39. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/settings/route.js +3 -2
  41. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +2 -1
  43. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +2 -1
  45. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/social/messages/route/app-paths-manifest.json +3 -0
  48. package/.next/standalone/.next/server/app/api/social/messages/route/build-manifest.json +12 -0
  49. package/.next/standalone/.next/server/app/api/social/messages/route/server-reference-manifest.json +4 -0
  50. package/.next/standalone/.next/server/app/api/social/messages/route.js +9 -0
  51. package/.next/standalone/.next/server/app/api/social/messages/route.js.map +5 -0
  52. package/.next/standalone/.next/server/app/api/social/messages/route.js.nft.json +1 -0
  53. package/.next/standalone/.next/server/app/api/social/messages/route_client-reference-manifest.js +3 -0
  54. package/.next/standalone/.next/server/app/api/social/route.js +4 -2
  55. package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
  63. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/import.html +1 -1
  65. package/.next/standalone/.next/server/app/import.rsc +15 -15
  66. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +15 -15
  67. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
  68. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +14 -14
  69. package/.next/standalone/.next/server/app/index.html +1 -1
  70. package/.next/standalone/.next/server/app/index.rsc +15 -15
  71. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  72. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  73. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  74. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/launch.html +2 -2
  77. package/.next/standalone/.next/server/app/launch.rsc +15 -15
  78. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +15 -15
  79. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
  80. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +14 -14
  81. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/paths.html +1 -1
  86. package/.next/standalone/.next/server/app/paths.rsc +15 -15
  87. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +15 -15
  88. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
  89. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +14 -14
  90. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/profile.html +1 -1
  93. package/.next/standalone/.next/server/app/profile.rsc +15 -15
  94. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +15 -15
  95. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
  96. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +14 -14
  97. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/queue.html +1 -1
  100. package/.next/standalone/.next/server/app/queue.rsc +15 -15
  101. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +15 -15
  102. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
  103. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +14 -14
  104. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/scores.html +1 -1
  107. package/.next/standalone/.next/server/app/scores.rsc +15 -15
  108. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +15 -15
  109. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
  110. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +14 -14
  111. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/settings.html +1 -1
  114. package/.next/standalone/.next/server/app/settings.rsc +15 -15
  115. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +15 -15
  116. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  117. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +14 -14
  118. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  119. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/setup.html +1 -1
  121. package/.next/standalone/.next/server/app/setup.rsc +15 -15
  122. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +15 -15
  123. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  124. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +14 -14
  125. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  126. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/social.html +1 -1
  128. package/.next/standalone/.next/server/app/social.rsc +15 -15
  129. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +15 -15
  130. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
  131. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +14 -14
  132. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  133. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06mi9k2._.js +3 -0
  134. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08f5awg._.js +8 -0
  135. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bat8nx._.js +1 -1
  136. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17hjtzl._.js +8 -0
  137. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20tmem7._.js +1 -1
  138. package/.next/standalone/.next/server/chunks/_0ea9qwy._.js +3 -0
  139. package/.next/standalone/.next/server/chunks/_1_fynia._.js +6 -6
  140. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  141. package/.next/standalone/.next/server/chunks/_1xh07bp._.js +1 -1
  142. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_social_messages_route_actions_0skh09r.js +3 -0
  143. package/.next/standalone/.next/server/chunks/lib_18cr1gi._.js +8 -0
  144. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +1 -1
  145. package/.next/standalone/.next/server/chunks/lib_rpc_03i8xef.js +1 -1
  146. package/.next/standalone/.next/server/chunks/lib_rpc_08fc3rp.js +1 -1
  147. package/.next/standalone/.next/server/chunks/lib_rpc_08r2t_q.js +1 -1
  148. package/.next/standalone/.next/server/chunks/lib_rpc_0btpv1t.js +1 -1
  149. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +5 -5
  150. package/.next/standalone/.next/server/chunks/lib_rpc_0cm2ev3.js +1 -1
  151. package/.next/standalone/.next/server/chunks/lib_rpc_0iovswz.js +1 -1
  152. package/.next/standalone/.next/server/chunks/lib_rpc_0is8flp.js +1 -1
  153. package/.next/standalone/.next/server/chunks/lib_rpc_0v8ajtd.js +1 -1
  154. package/.next/standalone/.next/server/chunks/lib_rpc_0xgmvvt.js +1 -1
  155. package/.next/standalone/.next/server/chunks/lib_rpc_144mzbf.js +1 -1
  156. package/.next/standalone/.next/server/chunks/lib_rpc_1bggi0n.js +1 -1
  157. package/.next/standalone/.next/server/chunks/lib_rpc_1dkcu9f.js +1 -1
  158. package/.next/standalone/.next/server/chunks/lib_rpc_1o0jb6w.js +1 -1
  159. package/.next/standalone/.next/server/chunks/lib_scoring_1-e4ur0.js +3 -0
  160. package/.next/standalone/.next/server/chunks/node_modules_next_1zc5q0a._.js +1 -1
  161. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1feicqq._.js → [root-of-the-server]__0qdeuyo._.js} +1 -1
  162. package/.next/standalone/.next/server/chunks/ssr/_0c_y09g._.js +3 -0
  163. package/.next/standalone/.next/server/chunks/ssr/_0ezj4e0._.js +1 -1
  164. package/.next/standalone/.next/server/chunks/ssr/{_1mj739k._.js → _0l8cxmo._.js} +2 -2
  165. package/.next/standalone/.next/server/chunks/ssr/_1errbuf._.js +3 -0
  166. package/.next/standalone/.next/server/chunks/ssr/{_0wxbq78._.js → app_components_19c2d9c._.js} +2 -2
  167. package/.next/standalone/.next/server/chunks/ssr/app_components_ui_0pdmz2z.js +3 -0
  168. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +1 -1
  169. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
  170. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +1 -1
  171. package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +3 -0
  172. package/.next/standalone/.next/server/chunks/ssr/{node_modules_1wax83z._.js → node_modules_0h91jdk._.js} +2 -2
  173. package/.next/standalone/.next/server/chunks/ssr/{node_modules_1nkgb45._.js → node_modules_1f8t_rp._.js} +1 -1
  174. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  175. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  176. package/.next/standalone/.next/server/pages/404.html +1 -1
  177. package/.next/standalone/.next/server/pages/500.html +1 -1
  178. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  179. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  180. package/.next/standalone/.next/static/chunks/07dyt47mp4s9-.js +1 -0
  181. package/.next/standalone/.next/static/chunks/{3q3pmt5vv-4pi.js → 160wjb73ddwqd.js} +1 -1
  182. package/.next/standalone/.next/static/chunks/{1z-zp93cyoxvz.js → 1c_n0973t07l0.js} +1 -1
  183. package/.next/standalone/.next/static/chunks/{0bo1dxn5gwzpk.css → 1xptlvtcz6654.css} +1 -1
  184. package/.next/standalone/.next/static/chunks/{2_wcobfqry2uj.js → 206rm6j42gl_a.js} +1 -1
  185. package/.next/standalone/.next/static/chunks/2coxzjm_k6ilr.js +1 -0
  186. package/.next/{static/chunks/0g_p4p7oci18u.js → standalone/.next/static/chunks/2kfhc58df2xyo.js} +1 -1
  187. package/.next/standalone/.next/static/chunks/2pw6_osz1n_te.js +1 -0
  188. package/.next/standalone/.next/static/chunks/{38wwtni5e1ec1.js → 39hr8d-b2ibtw.js} +1 -1
  189. package/.next/standalone/CHANGELOG.md +48 -0
  190. package/.next/standalone/app/api/social/messages/route.js +130 -0
  191. package/.next/standalone/app/api/social/route.js +89 -47
  192. package/.next/standalone/app/components/GalaxyLab.js +4 -1
  193. package/.next/standalone/app/components/ScanStatusBar.js +112 -50
  194. package/.next/standalone/app/components/settings/DataSection.js +2 -1
  195. package/.next/standalone/app/globals.css +4 -0
  196. package/.next/standalone/app/setup/page.js +4 -3
  197. package/.next/standalone/app/social/Conversations.js +246 -0
  198. package/.next/standalone/app/social/page.js +88 -9
  199. package/.next/standalone/lib/galaxy-lab.js +6 -1
  200. package/.next/standalone/lib/island.js +36 -0
  201. package/.next/standalone/lib/linkedin-export.js +175 -5
  202. package/.next/standalone/lib/social-store.js +73 -0
  203. package/.next/standalone/package-lock.json +2 -2
  204. package/.next/standalone/package.json +1 -1
  205. package/.next/standalone/scripts/scrape.py +156 -23
  206. package/.next/static/chunks/07dyt47mp4s9-.js +1 -0
  207. package/.next/static/chunks/{3q3pmt5vv-4pi.js → 160wjb73ddwqd.js} +1 -1
  208. package/.next/static/chunks/{1z-zp93cyoxvz.js → 1c_n0973t07l0.js} +1 -1
  209. package/.next/static/chunks/{0bo1dxn5gwzpk.css → 1xptlvtcz6654.css} +1 -1
  210. package/.next/static/chunks/{2_wcobfqry2uj.js → 206rm6j42gl_a.js} +1 -1
  211. package/.next/static/chunks/2coxzjm_k6ilr.js +1 -0
  212. package/.next/{standalone/.next/static/chunks/0g_p4p7oci18u.js → static/chunks/2kfhc58df2xyo.js} +1 -1
  213. package/.next/static/chunks/2pw6_osz1n_te.js +1 -0
  214. package/.next/static/chunks/{38wwtni5e1ec1.js → 39hr8d-b2ibtw.js} +1 -1
  215. package/CHANGELOG.md +48 -0
  216. package/lib/galaxy-lab.js +6 -1
  217. package/lib/island.js +36 -0
  218. package/lib/linkedin-export.js +175 -5
  219. package/lib/social-store.js +73 -0
  220. package/package.json +1 -1
  221. package/scripts/scrape.py +156 -23
  222. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17kn1mk._.js +0 -8
  223. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1dmc7-t._.js +0 -8
  224. package/.next/standalone/.next/server/chunks/ssr/_005q9n1._.js +0 -3
  225. package/.next/standalone/.next/server/chunks/ssr/_217nddo._.js +0 -3
  226. package/.next/standalone/.next/server/chunks/ssr/app_0i3fw_m._.js +0 -3
  227. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_client_components_server-async-storage_0t1dato.js +0 -3
  228. package/.next/standalone/.next/static/chunks/0y1yms5kez2f3.js +0 -1
  229. package/.next/standalone/.next/static/chunks/14m1zu-8warte.js +0 -1
  230. package/.next/standalone/.next/static/chunks/15qbli9udo0vh.js +0 -1
  231. package/.next/static/chunks/0y1yms5kez2f3.js +0 -1
  232. package/.next/static/chunks/14m1zu-8warte.js +0 -1
  233. package/.next/static/chunks/15qbli9udo0vh.js +0 -1
  234. /package/.next/standalone/.next/static/{T0eWMsKjgSiPnmx1E0q3G → 7zWJnSkfSoRhRsqY6ZKtD}/_buildManifest.js +0 -0
  235. /package/.next/standalone/.next/static/{T0eWMsKjgSiPnmx1E0q3G → 7zWJnSkfSoRhRsqY6ZKtD}/_clientMiddlewareManifest.js +0 -0
  236. /package/.next/standalone/.next/static/{T0eWMsKjgSiPnmx1E0q3G → 7zWJnSkfSoRhRsqY6ZKtD}/_ssgManifest.js +0 -0
  237. /package/.next/static/{T0eWMsKjgSiPnmx1E0q3G → 7zWJnSkfSoRhRsqY6ZKtD}/_buildManifest.js +0 -0
  238. /package/.next/static/{T0eWMsKjgSiPnmx1E0q3G → 7zWJnSkfSoRhRsqY6ZKtD}/_clientMiddlewareManifest.js +0 -0
  239. /package/.next/static/{T0eWMsKjgSiPnmx1E0q3G → 7zWJnSkfSoRhRsqY6ZKtD}/_ssgManifest.js +0 -0
package/scripts/scrape.py CHANGED
@@ -59,7 +59,7 @@ _ENV_LOCAL = _load_env_local()
59
59
  # a server they don't control.
60
60
  APP_URL = os.getenv("APP_URL", "http://localhost:3000")
61
61
  MESSAGING_URL = "https://www.linkedin.com/messaging/"
62
- MESSAGE_SCROLLS = 6 # scrolls down the conversation list, a few seconds apart
62
+ MESSAGE_SCROLLS = 15
63
63
 
64
64
  CONNECTIONS_URL = "https://www.linkedin.com/mynetwork/invite-connect/connections/"
65
65
 
@@ -330,7 +330,7 @@ def ensure_logged_in(page, timeout_s=LOGIN_WAIT_SECONDS, log_fn=None, stop_on_ch
330
330
  if stop_on_checkpoint and signed_out:
331
331
  reason = "a security check" if wall == "checkpoint" else "being signed out"
332
332
  _keep_pushback_evidence(page, reason)
333
- set_cooldown(seconds=DAY_SECONDS, reason=f"LinkedIn pushed back: {reason}")
333
+ set_cooldown(seconds=AUTO_PUSHBACK_REST if EXPERIMENT["on"] else DAY_SECONDS, reason=f"LinkedIn pushed back: {reason}")
334
334
  raise LinkedInPushedBack(0, reason)
335
335
 
336
336
  if _has_session_cookie(context) and not _looks_logged_out(page) and not wall:
@@ -1282,10 +1282,17 @@ LEGACY_PAGES_READ = 10 # how far every read before 0.1.6 went, at mos
1282
1282
  # A sitting of SESSION_PAGES searches, then a long rest; searches only in the
1283
1283
  # daytime on this computer's clock; and at the daily budget it waits for the
1284
1284
  # budget to free up instead of stopping. Pages are saved one at a time.
1285
+ #
1286
+ # Its own ceilings sit under whatever budget is set on the Scan page: the account
1287
+ # restricted on 2026-09-28 did 373 searches in 24 hours with the budget raised to
1288
+ # 500. Auto scan stays far below that however high the budget is set.
1285
1289
  EXPERIMENT = {"on": False, "pages": 0, "wire": 0}
1286
- SESSION_PAGES = 10 # searches in one sitting
1287
- SESSION_REST = 45 * 60 # the rest after each sitting
1288
- DRIP_HOURS = (9, 19) # searches only from 09:00 to 19:00, local time
1290
+ SESSION_PAGES = 8 # searches in one sitting
1291
+ SESSION_REST = 60 * 60 # the rest after each sitting
1292
+ DRIP_HOURS = (9, 18) # searches only from 09:00 to 18:00, local time
1293
+ AUTO_DAY_CAP = 40 # at most this many searches in any 24 hours
1294
+ AUTO_WEEK_CAP = 200 # and this many in any 7 days
1295
+ AUTO_PUSHBACK_REST = 2 * 24 * 3600 # after any LinkedIn check, nothing for two days
1289
1296
  WIRE_SAMPLES = 5 # raw LinkedIn responses kept per run, for research
1290
1297
 
1291
1298
 
@@ -1899,6 +1906,18 @@ def voyager_total(payload):
1899
1906
  return None
1900
1907
 
1901
1908
 
1909
+ _WORDS = {"body", "text", "subject", "attributedBody", "snippet", "messages", "headline", "firstName", "lastName", "rootUrl", "artifacts", "sponsoredPreviewText", "customPronoun", "advertiserLabel"}
1910
+
1911
+
1912
+ def _redact_words(x):
1913
+ """A copy of a LinkedIn response with every piece of writing and every name removed."""
1914
+ if isinstance(x, dict):
1915
+ return {k: ("<removed>" if k in _WORDS else _redact_words(v)) for k, v in x.items()}
1916
+ if isinstance(x, list):
1917
+ return [_redact_words(v) for v in x]
1918
+ return x
1919
+
1920
+
1902
1921
  def _wire_sample(data, prefix="search"):
1903
1922
  if EXPERIMENT["wire"] >= WIRE_SAMPLES:
1904
1923
  return
@@ -1908,6 +1927,10 @@ def _wire_sample(data, prefix="search"):
1908
1927
  return
1909
1928
  folder = _home() / "wire-samples"
1910
1929
  folder.mkdir(parents=True, exist_ok=True)
1930
+ if prefix == "messages":
1931
+ # Messaging responses carry what people wrote, and their names: a sample
1932
+ # keeps only the shape (keys, links, dates, counts), never the words.
1933
+ raw = json.dumps(_redact_words(data))
1911
1934
  (folder / f"{prefix}-{int(time.time() * 1000)}.json").write_text(raw)
1912
1935
  EXPERIMENT["wire"] += 1
1913
1936
  except Exception:
@@ -1948,14 +1971,51 @@ def _wire_merge(page, profile_url, page_results):
1948
1971
  return page_results
1949
1972
 
1950
1973
 
1951
- _PROFILE_LINK = re.compile(r"https://www\\.linkedin\\.com/in/[^/?#\\s\"']+")
1974
+ _PROFILE_LINK = re.compile(r"https://www\.linkedin\.com/in/[^/?#\s\"']+")
1975
+
1976
+
1977
+ def _dig(x, *keys):
1978
+ """x[k1][k2]..., or None as soon as a step isn't there."""
1979
+ for k in keys:
1980
+ if not isinstance(x, dict):
1981
+ return None
1982
+ x = x.get(k)
1983
+ return x
1984
+
1985
+
1986
+ def _link_key(link):
1987
+ """A profile link as the messages sync compares them: no query, one closing slash."""
1988
+ return link.split("?")[0].rstrip("/") + "/" if isinstance(link, str) and "/in/" in link else None
1952
1989
 
1953
1990
 
1954
1991
  def voyager_conversations(payload):
1955
1992
  """Conversations in a LinkedIn messaging response (experimental): per conversation,
1956
- everyone in it (profile links), when it was last active, and unread messages.
1957
- Anything with a lastActivityAt and participants, wherever it sits. Never the text."""
1993
+ everyone in it (profile links), when it was last active, unread messages, its link,
1994
+ whether it's a group, and the newest message LinkedIn sent along with it (when,
1995
+ from whom, and its words). Anything with a lastActivityAt and participants,
1996
+ wherever it sits. The words are handed to the app only while Keep my messages is
1997
+ on there (sync_messages); a wire sample never has them (_redact_words)."""
1958
1998
  out = []
1999
+ names = {}
2000
+
2001
+ def text_of(v):
2002
+ return v.get("text", "") if isinstance(v, dict) else (v if isinstance(v, str) else "")
2003
+
2004
+ def latest_of(x):
2005
+ # conversation.messages.elements[]: body.text, deliveredAt, and who sent it
2006
+ # (actor.participantType.member.profileUrl, the same /in/ACoA... link the
2007
+ # participants have, so it tells you from them).
2008
+ msgs = x.get("messages")
2009
+ elements = msgs.get("elements") if isinstance(msgs, dict) else msgs
2010
+ best = None
2011
+ for m in elements if isinstance(elements, list) else []:
2012
+ t = _dig(m, "deliveredAt")
2013
+ if not isinstance(t, (int, float)) or t < 1e12 or (best and t <= best["t"]):
2014
+ continue
2015
+ text = text_of(_dig(m, "body")).strip()
2016
+ best = {"t": int(t), "from": _link_key(_dig(m, "actor", "participantType", "member", "profileUrl")),
2017
+ "text": text or None}
2018
+ return best
1959
2019
 
1960
2020
  def people(x):
1961
2021
  found = set()
@@ -1966,6 +2026,14 @@ def voyager_conversations(payload):
1966
2026
  pid = v.get("publicIdentifier")
1967
2027
  if isinstance(pid, str) and pid and pid != "UNKNOWN":
1968
2028
  found.add(f"https://www.linkedin.com/in/{pid}/")
2029
+ # Messaging gives a member's link as /in/ACoA… (their member id), not
2030
+ # the /in/name link your connections list has, so their name comes
2031
+ # along to match them up (the app keeps the match, not the name).
2032
+ key = _link_key(v.get("profileUrl"))
2033
+ if key:
2034
+ name = f"{text_of(v.get('firstName'))} {text_of(v.get('lastName'))}".strip()
2035
+ if name:
2036
+ names[key] = name
1969
2037
  stack.extend(v.values())
1970
2038
  elif isinstance(v, list):
1971
2039
  stack.extend(v)
@@ -1984,7 +2052,13 @@ def voyager_conversations(payload):
1984
2052
  who |= people(v)
1985
2053
  if who:
1986
2054
  unread = x.get("unreadCount")
1987
- out.append({"people": sorted(who), "at": int(at), "unread": int(unread) if isinstance(unread, (int, float)) else None})
2055
+ link = x.get("conversationUrl")
2056
+ group = x.get("groupChat")
2057
+ out.append({"people": sorted(who), "at": int(at), "unread": int(unread) if isinstance(unread, (int, float)) else None,
2058
+ "names": {u: names[u] for u in who if u in names},
2059
+ "url": link if isinstance(link, str) and link.startswith("https://www.linkedin.com/messaging/") else None,
2060
+ "group": group if isinstance(group, bool) else None,
2061
+ "latest": latest_of(x)})
1988
2062
  for v in x.values():
1989
2063
  walk(v)
1990
2064
  elif isinstance(x, list):
@@ -1997,8 +2071,9 @@ def voyager_conversations(payload):
1997
2071
  def sync_messages(headless=False):
1998
2072
  """Experimental: read your LinkedIn messages list once, for the Social tab. Opens
1999
2073
  Messaging in your own Chrome, scrolls the list a few times, and keeps from LinkedIn's
2000
- own data only who each 1:1 conversation is with, when it was last active and whether
2001
- it has unread messages. No search budget; no message text is read or kept."""
2074
+ own data who each 1:1 conversation is with, when it was last active, whether it has
2075
+ unread messages, its link and who wrote last. The newest message's words go to the
2076
+ app only while Keep my messages is on there. No search budget."""
2002
2077
  from playwright.sync_api import sync_playwright
2003
2078
  kept = []
2004
2079
  with sync_playwright() as p:
@@ -2021,7 +2096,12 @@ def sync_messages(headless=False):
2021
2096
  if stop_requested() or _window_closed(page):
2022
2097
  break
2023
2098
  try:
2024
- page.evaluate("""() => { const l = document.querySelector('.msg-conversations-container__conversations-list, [class*="conversations-list"]');
2099
+ # The list scrolls inside its own panel, not the window: find the panel
2100
+ # that holds the conversation links and scroll that to its end.
2101
+ page.evaluate("""() => {
2102
+ let l = document.querySelector('.msg-conversations-container__conversations-list, [class*="conversations-list"]');
2103
+ const a = document.querySelector('a[href*="/messaging/thread/"], li[class*="conversation-listitem"]');
2104
+ for (let e = a; !l && e; e = e.parentElement) if (e.scrollHeight > e.clientHeight + 20) l = e;
2025
2105
  if (l) l.scrollTop = l.scrollHeight; }""")
2026
2106
  except Exception:
2027
2107
  pass
@@ -2036,7 +2116,35 @@ def sync_messages(headless=False):
2036
2116
  _wire_sample(data, prefix="messages")
2037
2117
  convos.extend(voyager_conversations(data))
2038
2118
  browser.close()
2039
- # You are the one in the most conversations; keep the 1:1 ones.
2119
+ _me, people = live_people(convos)
2120
+ print(f" Found {len(convos)} conversations in LinkedIn's data, {len(people)} with one person.")
2121
+ # The newest message's words go to the app only if Keep my messages is on
2122
+ # there. The app checks too; this way they don't even leave the scanner.
2123
+ keep = False
2124
+ try:
2125
+ r = requests.get(f"{APP_URL}/api/social", headers=app_headers(json_body=False), timeout=15)
2126
+ keep = r.ok and ((r.json() or {}).get("social") or {}).get("keepMessages") is True
2127
+ except Exception:
2128
+ pass
2129
+ if not keep:
2130
+ for v in people.values():
2131
+ if v.get("preview"):
2132
+ v["preview"]["text"] = None
2133
+ try:
2134
+ r = requests.put(f"{APP_URL}/api/social", json={"live": people}, headers=app_headers(), timeout=30)
2135
+ got = r.json() if r.ok else {}
2136
+ matched, unmatched = got.get("people", 0), got.get("unmatched", 0)
2137
+ print(f" Saved for the Social tab: {matched} matched to your connections, {unmatched} not.")
2138
+ except Exception as e:
2139
+ print(f" Couldn't save them: {e}")
2140
+
2141
+
2142
+ def live_people(convos):
2143
+ """The messages sync's conversations, per person: you are the one in the most
2144
+ conversations, and only the 1:1 ones are kept. For each person, their newest
2145
+ conversation's last activity, unread count, name (for the app to match them to
2146
+ a connection; it keeps the match, not the name), link, who wrote last and the
2147
+ newest message. Returns (you, {profile link: ...})."""
2040
2148
  counts = {}
2041
2149
  for c in convos:
2042
2150
  for u in c["people"]:
@@ -2045,17 +2153,23 @@ def sync_messages(headless=False):
2045
2153
  people = {}
2046
2154
  for c in convos:
2047
2155
  others = [u for u in c["people"] if u != me]
2048
- if len(others) != 1:
2156
+ if len(others) != 1 or c.get("group") is True:
2049
2157
  continue
2050
2158
  cur = people.get(others[0])
2051
- if not cur or c["at"] > cur["last"]:
2052
- people[others[0]] = {"last": c["at"], "unread": c["unread"]}
2053
- print(f" Found {len(convos)} conversations in LinkedIn's data, {len(people)} with one person.")
2054
- try:
2055
- requests.put(f"{APP_URL}/api/social", json={"live": people}, headers=app_headers(), timeout=30)
2056
- print(" Saved for the Social tab.")
2057
- except Exception as e:
2058
- print(f" Couldn't save them: {e}")
2159
+ if cur and c["at"] <= cur["last"]:
2160
+ continue
2161
+ entry = {"last": c["at"], "unread": c["unread"], "name": c.get("names", {}).get(others[0]),
2162
+ "threadUrl": c.get("url"), "lastFromThem": None, "preview": None}
2163
+ latest = c.get("latest")
2164
+ # Who sent it is known only when their link is one of the two in the
2165
+ # conversation; a link in some other form says nothing either way.
2166
+ sender = latest.get("from") if latest else None
2167
+ if sender in (me, others[0]):
2168
+ from_me = sender == me
2169
+ entry["lastFromThem"] = not from_me
2170
+ entry["preview"] = {"t": latest["t"], "fromMe": from_me, "text": latest.get("text")}
2171
+ people[others[0]] = entry
2172
+ return me, people
2059
2173
 
2060
2174
 
2061
2175
  def _drip_wait(label, seconds):
@@ -2095,9 +2209,28 @@ def _drip_before_search():
2095
2209
  if not _drip_wait("Today's searches are used", _seconds_until_search_frees()):
2096
2210
  return False
2097
2211
  continue
2212
+ wait = _auto_ceiling_wait()
2213
+ if wait:
2214
+ label, seconds = wait
2215
+ if not _drip_wait(label, seconds):
2216
+ return False
2217
+ continue
2098
2218
  return True
2099
2219
 
2100
2220
 
2221
+ def _auto_ceiling_wait(now=None):
2222
+ """Auto scan's own ceilings (AUTO_DAY_CAP in 24 hours, AUTO_WEEK_CAP in 7 days):
2223
+ None to go ahead, or (why, seconds until the oldest counted search drops out)."""
2224
+ now = now if now is not None else time.time()
2225
+ searches = sorted(t for t in _read_activity()["searches"] if now - 7 * DAY_SECONDS < t <= now)
2226
+ day = [t for t in searches if now - DAY_SECONDS < t]
2227
+ if len(day) >= AUTO_DAY_CAP:
2228
+ return (f"Auto scan's {AUTO_DAY_CAP} searches for today are used", day[-AUTO_DAY_CAP] + DAY_SECONDS - now + 5)
2229
+ if len(searches) >= AUTO_WEEK_CAP:
2230
+ return (f"Auto scan's {AUTO_WEEK_CAP} searches for this week are used", searches[-AUTO_WEEK_CAP] + 7 * DAY_SECONDS - now + 5)
2231
+ return None
2232
+
2233
+
2101
2234
  def interruptible_sleep(seconds, on_tick=None, step=5):
2102
2235
  """Sleep, but notice a stop request. Returns False if we were interrupted."""
2103
2236
  waited = 0
@@ -4073,7 +4206,7 @@ Examples:
4073
4206
  parser.add_argument("--rescrape", type=str, help="Delete + re-scrape a bridge's cluster from scratch")
4074
4207
  parser.add_argument("--company", type=str, help="Scan everyone the app can see at one company")
4075
4208
  parser.add_argument("--messages", action="store_true",
4076
- help="Experimental: read your messages list once for the Social tab (who, when, unread; never text)")
4209
+ help="Experimental: read your messages list once for the Social tab (who, when, unread; the newest message's words only if Keep my messages is on)")
4077
4210
  parser.add_argument("--experimental", action="store_true",
4078
4211
  help="Auto-Bridge, experimental: all-day pacing (sittings, rests, daytime only, "
4079
4212
  "waits for the daily budget) and reading LinkedIn's own data beside the page text")
@@ -1,8 +0,0 @@
1
- module.exports=[70406,(e,r,n)=>{r.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},18622,(e,r,n)=>{r.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},56704,(e,r,n)=>{r.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},32319,(e,r,n)=>{r.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},59043,(e,r,n)=>{r.exports=e.x("next/dist/server/runtime-reacts.external.js",()=>require("next/dist/server/runtime-reacts.external.js"))},93695,(e,r,n)=>{r.exports=e.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},74533,(e,r,n)=>{r.exports=e.x("node:child_process",()=>require("node:child_process"))},66680,(e,r,n)=>{r.exports=e.x("node:crypto",()=>require("node:crypto"))},2157,(e,r,n)=>{r.exports=e.x("node:fs",()=>require("node:fs"))},12714,(e,r,n)=>{r.exports=e.x("node:fs/promises",()=>require("node:fs/promises"))},60526,(e,r,n)=>{r.exports=e.x("node:os",()=>require("node:os"))},50227,(e,r,n)=>{r.exports=e.x("node:path",()=>require("node:path"))},81111,(e,r,n)=>{r.exports=e.x("node:stream",()=>require("node:stream"))},88602,e=>{"use strict";var r=e.i(88431);e.s(["networkCounts",0,function(e){let n=Object.fromEntries((0,r.getDb)().prepare("SELECT degree, COUNT(*) AS n FROM linkedin_connections WHERE user_id = ? GROUP BY degree").all(e).map(e=>[e.degree,e.n]));return{first:n[1]||0,second:n[2]||0,third:n[3]||0}},"resolveProfile",0,function({create:e=!0}={}){let[n]=(0,r.getDb)().prepare(`
2
- SELECT u.*,
3
- (SELECT COUNT(*) FROM linkedin_connections c WHERE c.user_id = u.id) AS connections
4
- FROM users u
5
- ORDER BY connections DESC, u.created_at ASC, u.rowid ASC
6
- `).all().map(e=>(0,r.decodeRow)("users",e));if(n)return n;if(!e)return null;let t=(0,r.newId)();return(0,r.getDb)().prepare("INSERT INTO users (id, name) VALUES (?, ?)").run(t,"You"),{...(0,r.decodeRow)("users",(0,r.getDb)().prepare("SELECT * FROM users WHERE id = ?").get(t)),connections:0}}])},12506,1348,e=>{"use strict";e.s(["compareVersions",0,function(e,r){let n=e=>String(e||"").replace(/^v/i,"").split(/[-+]/)[0].split(".").map(e=>Number.parseInt(e,10)||0),t=n(e),s=n(r);for(let e=0;e<Math.max(t.length,s.length);e++){let r=(t[e]||0)-(s[e]||0);if(0!==r)return r>0?1:-1}return 0},"installKind",0,function(e=process.env,r=""){return["mac-app","source","npm"].includes(e.SIX_DEGREES_INSTALL)?e.SIX_DEGREES_INSTALL:/\.app\/Contents\/Resources/.test(r||"")?"mac-app":"npm"},"repoSlug",0,function(e){let r=("string"==typeof e?e:e?.url||"").match(/github\.com[/:]([^/]+)\/([^/.#?]+)/);return r?`${r[1]}/${r[2]}`:null},"updateCommand",0,function(e,r,{dataDir:n}={}){if("mac-app"===e)return`curl -fsSL https://raw.githubusercontent.com/${r}/main/install.sh | bash`;if("source"===e)return"git pull && npm ci && npm run build && npm run start:packaged";let t=n&&`'${String(n).replace(/'/g,"'\\''")}'`;return t?`npx six-degrees@latest --data-dir ${t}`:"npx six-degrees@latest"}],12506);let r=Symbol.for("six-degrees.scan-state");function n(){let e=globalThis[r];return e?.running!==!0?null:"string"==typeof e.action&&e.action?e.action:"scan"}function t(e){switch(e){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"}}e.s(["busyRefusal",0,function(e,r=n()){return r?`${t(r)}. ${e}`:null},"registerScanState",0,function(e){return globalThis[r]||(globalThis[r]=e),globalThis[r]},"runningNow",0,t,"scannerJob",0,n],1348)}];
7
-
8
- //# sourceMappingURL=%5Broot-of-the-server%5D__17kn1mk._.js.map
@@ -1,8 +0,0 @@
1
- module.exports=[70406,(e,t,r)=>{t.exports=e.x("next/dist/compiled/@opentelemetry/api",()=>require("next/dist/compiled/@opentelemetry/api"))},18622,(e,t,r)=>{t.exports=e.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},56704,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},32319,(e,t,r)=>{t.exports=e.x("next/dist/server/app-render/work-unit-async-storage.external.js",()=>require("next/dist/server/app-render/work-unit-async-storage.external.js"))},59043,(e,t,r)=>{t.exports=e.x("next/dist/server/runtime-reacts.external.js",()=>require("next/dist/server/runtime-reacts.external.js"))},93695,(e,t,r)=>{t.exports=e.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},74533,(e,t,r)=>{t.exports=e.x("node:child_process",()=>require("node:child_process"))},66680,(e,t,r)=>{t.exports=e.x("node:crypto",()=>require("node:crypto"))},2157,(e,t,r)=>{t.exports=e.x("node:fs",()=>require("node:fs"))},12714,(e,t,r)=>{t.exports=e.x("node:fs/promises",()=>require("node:fs/promises"))},60526,(e,t,r)=>{t.exports=e.x("node:os",()=>require("node:os"))},50227,(e,t,r)=>{t.exports=e.x("node:path",()=>require("node:path"))},81111,(e,t,r)=>{t.exports=e.x("node:stream",()=>require("node:stream"))},10960,e=>{"use strict";var t=e.i(2157),r=e.i(50227),n=e.i(60526);function s(){for(let e of[process.env.SIX_DEGREES_ROOT,process.cwd(),r.default.join(process.cwd(),".."),r.default.join(process.cwd(),"..","..")].filter(Boolean))if((0,t.existsSync)(r.default.join(e,"scripts","scrape.py")))return e;return null}e.s(["dataDir",0,function(){return process.env.SIX_DEGREES_HOME||r.default.join(n.default.homedir(),".six-degrees")},"isGitCheckout",0,function(){let e=s();return!!(e&&(0,t.existsSync)(r.default.join(e,".git")))},"projectRoot",0,s])},88602,e=>{"use strict";var t=e.i(88431);e.s(["networkCounts",0,function(e){let r=Object.fromEntries((0,t.getDb)().prepare("SELECT degree, COUNT(*) AS n FROM linkedin_connections WHERE user_id = ? GROUP BY degree").all(e).map(e=>[e.degree,e.n]));return{first:r[1]||0,second:r[2]||0,third:r[3]||0}},"resolveProfile",0,function({create:e=!0}={}){let[r]=(0,t.getDb)().prepare(`
2
- SELECT u.*,
3
- (SELECT COUNT(*) FROM linkedin_connections c WHERE c.user_id = u.id) AS connections
4
- FROM users u
5
- ORDER BY connections DESC, u.created_at ASC, u.rowid ASC
6
- `).all().map(e=>(0,t.decodeRow)("users",e));if(r)return r;if(!e)return null;let n=(0,t.newId)();return(0,t.getDb)().prepare("INSERT INTO users (id, name) VALUES (?, ?)").run(n,"You"),{...(0,t.decodeRow)("users",(0,t.getDb)().prepare("SELECT * FROM users WHERE id = ?").get(n)),connections:0}}])},12506,1348,e=>{"use strict";e.s(["compareVersions",0,function(e,t){let r=e=>String(e||"").replace(/^v/i,"").split(/[-+]/)[0].split(".").map(e=>Number.parseInt(e,10)||0),n=r(e),s=r(t);for(let e=0;e<Math.max(n.length,s.length);e++){let t=(n[e]||0)-(s[e]||0);if(0!==t)return t>0?1:-1}return 0},"installKind",0,function(e=process.env,t=""){return["mac-app","source","npm"].includes(e.SIX_DEGREES_INSTALL)?e.SIX_DEGREES_INSTALL:/\.app\/Contents\/Resources/.test(t||"")?"mac-app":"npm"},"repoSlug",0,function(e){let t=("string"==typeof e?e:e?.url||"").match(/github\.com[/:]([^/]+)\/([^/.#?]+)/);return t?`${t[1]}/${t[2]}`:null},"updateCommand",0,function(e,t,{dataDir:r}={}){if("mac-app"===e)return`curl -fsSL https://raw.githubusercontent.com/${t}/main/install.sh | bash`;if("source"===e)return"git pull && npm ci && npm run build && npm run start:packaged";let n=r&&`'${String(r).replace(/'/g,"'\\''")}'`;return n?`npx six-degrees@latest --data-dir ${n}`:"npx six-degrees@latest"}],12506);let t=Symbol.for("six-degrees.scan-state");function r(){let e=globalThis[t];return e?.running!==!0?null:"string"==typeof e.action&&e.action?e.action:"scan"}function n(e){switch(e){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"}}e.s(["busyRefusal",0,function(e,t=r()){return t?`${n(t)}. ${e}`:null},"registerScanState",0,function(e){return globalThis[t]||(globalThis[t]=e),globalThis[t]},"runningNow",0,n,"scannerJob",0,r],1348)},98199,e=>{"use strict";var t=e.i(50227),r=e.i(12506);let n="Six Degrees.app",s="SHA256SUMS",i=Object.freeze({apiBase:"https://api.github.com",downloadBase:"https://github.com"}),o=(e,t)=>({refusal:{code:e,message:t}}),a={arm64:"Apple Silicon",x64:"Intel"},l={0x1000007:"x64",0x100000c:"arm64"};e.s(["APP_BUNDLE_NAME",0,n,"BUNDLE_ID",0,"com.blakeburford.sixdegrees","CHIP_LABEL",0,a,"GITHUB",0,i,"UPDATE_HANDOFF_EXIT_CODE",0,76,"chipOf",0,function({sysctlArm64:e,processArch:t}={}){return"1"===String(e??"").trim()||"arm64"===t?"arm64":"x64"},"digestsMatch",0,function(e,t){let r=String(e||"").toLowerCase(),n=String(t||"").toLowerCase();return/^[0-9a-f]{64}$/.test(r)&&r===n},"foreignAppProcesses",0,function(e,{bundles:t=[],uid:r}){let n=t.filter(Boolean).map(e=>`${e}/Contents/`);if(!n.length||!Number.isInteger(r))return[];let s=[];for(let t of String(e||"").split("\n")){let e=t.match(/^\s*(\d+)\s+(\d+)\s+(.+)$/);e&&Number(e[1])!==r&&n.some(t=>e[3].startsWith(t))&&s.push(Number(e[2]))}return s},"helperArgs",0,function({target:e,staged:t,keepDir:r,statusFile:n,from:s,to:i,pids:o=[],waitSeconds:a=30,logFile:l,work:u,relaunch:d=[],confirmFile:p,confirmWaitSeconds:c=600}){let f=["--target",e,"--staged",t,"--keep",r,"--status",n,"--from",s,"--to",i,"--wait",String(a)];for(let e of o)Number.isInteger(e)&&e>1&&f.push("--pid",String(e));return p&&f.push("--confirm",p,"--confirm-wait",String(c)),l&&f.push("--log",l),u&&f.push("--work",u),[...f,"--",...d]},"installerTarget",0,function({applicationsWritable:e=!0,home:r=""}={}){return e?t.default.join("/Applications",n):t.default.join(r,"Applications",n)},"lastUpdateReport",0,function(e,{runningVersion:t,now:s=Date.now(),maxAgeDays:i=7}={}){if(!e||"object"!=typeof e||"string"!=typeof e.to)return null;let o=Date.parse(e.at);if(!Number.isFinite(o)||s-o>864e5*i)return null;let a=e.to,l="string"==typeof e.reason&&e.reason.trim()?e.reason.trim().replace(/\.$/,""):null,u={at:new Date(o).toISOString(),from:e.from||null,to:a,previous:"string"==typeof e.previous?e.previous:null},d=t?(0,r.compareVersions)(t,a):null,p=`The update to ${a} didn't finish${l?`: ${l}`:""}.`;switch(e.outcome){case"installed":case"started":if(0===d)return{...u,tone:"ok",text:`Updated to ${a}.`};if(d>0)return null;if("installed"===e.outcome)return{...u,tone:"bad",text:`Version ${a} was installed, but this copy is ${t}. If you have two copies of Six Degrees, open the one in Applications.`};return{...u,tone:"bad",text:`The update to ${a} didn't finish, and it didn't say why.${e.log?` Its log is ${e.log}.`:""}`};case"not-applied":if(null!==d&&d>=0)return null;return{...u,tone:"bad",text:`${p} Nothing was changed.`};case"rolled-back":if(null!==d&&d>=0)return null;return{...u,tone:"bad",text:`${p} Your previous version was put back.`};case"failed":if(null!==d&&d>=0)return null;return{...u,tone:"bad",text:`${p}${e.previous?` Your previous version is safe, in a hidden folder: ${e.previous}. To use it again, rename it to ${n} (in Finder, Shift-Command-. shows hidden files). Or install the newest version: Check for updates, below.`:""}`};default:return null}},"leftoversBeside",0,function(e,t){let r=`.${t}.`,n=[];for(let t of e){if("string"!=typeof t||!t.startsWith(r))continue;let e=t.slice(r.length);if("incoming"===e){n.push({name:t,kind:"incoming",pid:null});continue}let s=e.match(/^(previous|failed)-(\d+)(?:-\d+)?$/);s&&n.push({name:t,kind:s[1],pid:Number(s[2])})}return n},"machoArchs",0,function(e){let t=new Set;if(!e||e.length<8)return t;let r=e=>{l[e>>>0]&&t.add(l[e>>>0])},n=e.readUInt32LE(0);if(0xfeedfacf===n||0xfeedface===n)return r(e.readUInt32LE(4)),t;let s=e.readUInt32BE(0);if(0xcafebabe===s||0xcafebabf===s){let n=e.readUInt32BE(4),i=0xcafebabf===s?32:20;if(n<1||n>16)return t;for(let t=0;t<n;t++){let n=8+t*i;if(n+4>e.length)break;r(e.readUInt32BE(n))}}return t},"parseSha256Sums",0,function(e){let t=new Map;for(let r of String(e||"").split("\n")){let e=r.replace(/\r$/,"").match(/^([0-9a-fA-F]{64}) [ *](.+)$/);if(!e)continue;let[,n,s]=e,i=n.toLowerCase();t.has(s)&&t.get(s)!==i?t.set(s,null):t.set(s,i)}return t},"planFromRelease",0,function(e,{currentVersion:t,chip:n,slug:l,downloadBase:u=i.downloadBase}){if(!e||"object"!=typeof e||!e.tag_name)return o("no-release","GitHub did not describe a release.");let d=String(e.tag_name),p=d.replace(/^v/i,"");if(e.draft||e.prerelease||p.includes("-"))return o("prerelease",`Version ${p} is a test version, so it isn't installed from here.`);if(!/^\d+(\.\d+){1,3}$/.test(p))return o("bad-version",`GitHub's newest release has a version this app doesn't understand (${d}).`);if(0>=(0,r.compareVersions)(p,t))return o("not-newer",`You already have ${t}, and the newest version is ${p}.`);let c=Array.isArray(e.assets)?e.assets:[],f=e=>c.find(t=>t&&t.name===e)||null,m=f(`Six-Degrees-${p}-${n}.dmg`);if(!m)return o("no-download",`Version ${p} has no download for this Mac (${a[n]||n}).`);let g=f(s);if(!g)return o("no-checksums",`Version ${p} was published without its checksum file (${s}), so its download can't be checked.`);let h=`${u}/${l}/releases/download/${encodeURIComponent(d)}/`;for(let e of[m,g])if(e.browser_download_url!==h+encodeURIComponent(e.name))return o("unexpected-address",`GitHub listed ${e.name} at an unexpected address, so it wasn't downloaded.`);let x=Number(m.size)>0?Number(m.size):null;return x&&x>0x40000000?o("too-large",`The download for version ${p} is unexpectedly large, so it wasn't downloaded.`):{plan:{version:p,tag:d,notes:"string"==typeof e.html_url?e.html_url:null,dmg:{name:m.name,url:m.browser_download_url,size:x},sums:{name:g.name,url:g.browser_download_url}}}},"relaunchArgs",0,function({dataDir:e}={}){let r=["--after-update"];return e&&r.push("--data-dir",t.default.resolve(e)),r},"releaseSource",0,function(e={}){let t=e?.SIX_DEGREES_TEST_RELEASES;if(!t)return{...i,test:!1};let r=null;try{r=new URL(String(t))}catch{}return!r||"http:"!==r.protocol||"127.0.0.1"!==r.hostname||""===r.port||"/"!==r.pathname||r.search||r.hash||r.username||r.password?{...i,test:!1}:{apiBase:r.origin,downloadBase:r.origin,test:!0}},"stagingPath",0,function(e){return t.default.join(t.default.dirname(e),`.${t.default.basename(e)}.incoming`)},"terminalFallback",0,function({bundle:e,refusalCode:t=null,installsTo:r,dataDir:n=null}){if("data-inside-app"===t||"database-elsewhere"===t||"not-owner"===t&&e===r)return null;let s=n?{dataDir:n}:{};return e&&e===r?{mode:"replace",...s}:{mode:"elsewhere",installsTo:r,...s}},"versionAtLeast",0,function(e,t){return(0,r.compareVersions)(e,t)>=0}])}];
7
-
8
- //# sourceMappingURL=%5Broot-of-the-server%5D__1dmc7-t._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[66537,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(38246),e=a.i(37732),f=a.i(7846);let g={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"};a.s(["default",0,function(){let a,h,[i,j]=(0,c.useState)(()=>(0,e.scannerNow)()),[k,l]=(0,c.useState)(!1),m=(0,c.useSyncExternalStore)(f.watchAllDay,f.allDayNow,()=>!1);(0,c.useEffect)(()=>(0,e.watchScanner)(()=>{let a=(0,e.scannerNow)();j(a),a.running||l(!1)}),[]);let n={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 m?(0,b.jsxs)("div",{role:"status",style:{...n,opacity:.55,border:"1px solid rgba(255,255,255,0.1)"},children:[(0,b.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:"#556",flexShrink:0}}),(0,b.jsx)("b",{style:{color:"#b8c4c4"},children:"Auto scan"}),(0,b.jsx)("span",{style:{color:"#8b9a9a"},children:"ready · press Auto scan beside Scan to start"})]}):null;let o=i.progress,p=o?.kind==="batch"&&o.total?`${o.current||o.done||0} of ${o.total}`:o?.kind==="walk"&&o.total?`${(o.done||0).toLocaleString()} of ${o.total.toLocaleString()} read`:o?.kind==="saving"?"saving":null,q=i.budget,r=[...i.log||[]].reverse().find(a=>a&&a.trim())?.trim();return(0,b.jsxs)("div",{role:"status","aria-live":"polite",style:{...n,border:"1px solid rgba(0,255,136,0.25)"},children:[(0,b.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:"#00ff88",flexShrink:0}}),(0,b.jsx)("b",{style:{color:"#fff"},children:g[i.action]||"Scanning"}),i.target?.name&&(0,b.jsx)("span",{children:i.target.name}),p&&(0,b.jsx)("span",{style:{color:"#8b9a9a"},children:p}),q&&(0,b.jsxs)("span",{style:{color:(a=q.searches,(h=q.cap)?a/h>=.9?"#ff6b6b":a/h>=.6?"#FFD700":"#00ff88":"#8b9a9a")},title:"Searches on your LinkedIn account in the last 24 hours, and your daily budget",children:[q.searches,q.cap?` of ${q.cap}`:""," searches today"]}),r&&(0,b.jsx)("span",{style:{color:"#667",flex:"0 1 240px",minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},title:r,children:r}),(0,b.jsx)(d.default,{href:"/setup",style:{color:"#3498DB",textDecoration:"none"},children:"Details"}),(0,b.jsx)("button",{onClick:async()=>{l(!0);try{await (0,e.stopScrape)()}catch{l(!1)}},disabled:k,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:k?"default":"pointer",background:"rgba(255,107,107,0.12)",color:"#ff9b9b",border:"1px solid rgba(255,107,107,0.35)"},children:k?"Stopping…":"Stop"})]})}])},59617,a=>{"use strict";var b=a.i(72131),c=a.i(37732),d=a.i(58834);let e=!1;a.s(["default",0,function(){return(0,b.useEffect)(()=>{if(d.IS_DEMO||e)return;let a=()=>{};return fetch("/api/social").then(a=>a.json()).then(({social:b})=>{if(!b?.autoSync||e)return;let d=b.liveAt?Date.parse(b.liveAt):0,f=new Date().getHours();Date.now()-d<864e5||f<9||f>=19||(a=(0,c.watchScanner)(()=>{let b=(0,c.scannerNow)();b.known&&!e&&(e=!0,a(),b.running||(0,c.beginScrape)("messages").catch(()=>{}))}))}).catch(()=>{}),()=>a()},[]),null}])},17372,a=>{"use strict";var b=a.i(87924),c=a.i(72131);a.s(["default",0,function(){let[a,d]=(0,c.useState)(null);return((0,c.useEffect)(()=>{let a=!0;return fetch("/api/update").then(a=>a.json()).then(b=>{a&&b?.restartNeeded&&d(b)}).catch(()=>{}),()=>{a=!1}},[]),a)?(0,b.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,b.jsxs)("span",{children:["You have newer code on disk (",a.sha,") than this server is running (",a.bootSha,"). Restart it to see the changes — ",(0,b.jsx)("code",{style:{background:"rgba(0,0,0,0.16)",padding:"1px 6px",borderRadius:4},children:"Ctrl-C"})," in the terminal, then ",(0,b.jsx)("code",{style:{background:"rgba(0,0,0,0.16)",padding:"1px 6px",borderRadius:4},children:"npm run dev"}),"."]}),(0,b.jsx)("button",{onClick:()=>d(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}])},75857,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(73167),e=a.i(58834),f=a.i(42510);let g=(0,c.createContext)({userId:null,userName:null,userProfile:null,ready:!1});a.s(["default",0,function({children:a}){let[h,i]=(0,c.useState)(null),[j,k]=(0,c.useState)(null),[l,m]=(0,c.useState)(null),[n,o]=(0,c.useState)(!1);return(0,c.useEffect)(()=>{if(e.IS_DEMO){i(e.DEMO_USER.id),k(e.DEMO_USER.name),m({name:e.DEMO_USER.name,headline:e.DEMO_USER.headline,role:"",company:"",industry:"",sectors:[],goals:[],linkedin_url:""}),o(!0);return}if((0,f.hasCsvNetwork)()){i(f.CSV_USER.id),k(f.CSV_USER.name),m({name:f.CSV_USER.name,headline:"Imported from your LinkedIn CSV",role:"",company:"",industry:"",sectors:[],goals:[],linkedin_url:""}),o(!0);return}fetch("/api/users?me=1").then(a=>a.json()).then(a=>{let b=a.user;if(!b)throw Error("no profile");(0,d.setUser)(b.id,b.name),i(b.id),k(b.name),m({name:b.name,headline:b.headline||"",role:b.role||"",company:b.company||"",industry:b.industry||"",sectors:b.sectors||[],goals:b.goals||[],linkedin_url:b.linkedin_url||""})}).catch(()=>{(0,d.hasUser)()&&(i((0,d.getUserId)()),k((0,d.getUserName)()))}).finally(()=>o(!0))},[]),(0,b.jsx)(g.Provider,{value:{userId:h,userName:j,userProfile:l,ready:n,login:(a,b)=>{(0,d.setUser)(a,b),i(a),k(b),fetch(`/api/users?id=${a}`).then(a=>a.json()).then(a=>{a.user&&m({name:a.user.name,headline:a.user.headline||"",role:a.user.role||"",company:a.user.company||"",industry:a.user.industry||"",sectors:a.user.sectors||[],goals:a.user.goals||[],linkedin_url:a.user.linkedin_url||""})}).catch(()=>{})}},children:a})},"useUser",0,function(){return(0,c.useContext)(g)}])},58834,a=>{"use strict";var b=a.i(42510);let c="true"===process.env.NEXT_PUBLIC_DEMO_MODE,d=null;async function e(){if(d)return d;let a=await fetch("/demo-data.json",{cache:"no-cache"});if(!a.ok)throw Error("demo-data.json not found — run: node scripts/gen-synthetic.mjs");let b=await a.json();return d={degree1:b.degree1||[],degree2:b.degree2||[]}}async function f(){let a=await e();return(0,b.saveSessionNetwork)({degree1:a.degree1,degree2:a.degree2,source:"sample"}),{degree1:a.degree1.length,degree2:a.degree2.length}}a.s(["DEMO_USER",0,{id:"synthetic-demo-user",name:"You",headline:"Sample network"},"IS_DEMO",0,c,"loadDemoNetwork",0,e,"loadSampleIntoSession",0,f])},7846,a=>{"use strict";var b=a.i(37732);let c=(a,b)=>{try{let c=localStorage.getItem(a);return null===c?b:JSON.parse(c)}catch{return b}};a.s(["allDayNow",0,function(){try{return"true"===localStorage.getItem("six-degrees-experimental-auto")}catch{return!1}},"startAutoScan",0,function(){let a=c("six-degrees-bridge-order","newest");return(0,b.beginScrape)("auto-bridge",{experimental:!0,maxBridges:10,order:a,tiers:"score"===a?["S","A"]:[],maxPages:c("six-degrees-bridge-pages-v2",100),deeper:c("six-degrees-bridge-finish",!0)})},"watchAllDay",0,function(a){return window.addEventListener("storage",a),window.addEventListener("six-degrees:experimental",a),()=>{window.removeEventListener("storage",a),window.removeEventListener("six-degrees:experimental",a)}}])},37732,a=>{"use strict";async function b(){let a=await fetch("/api/scraper");if(!a.ok)throw Error("Could not reach the app.");return a.json()}async function c(a,b,d={}){let e=await fetch("/api/scraper",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:a,...b?{name:b}:{},...d})}),f=await e.json().catch(()=>({}));if(!e.ok)throw Error(f.error||"Could not start the scanner.");return f}async function d(a){let b=await fetch(`/api/scraper?resume=${encodeURIComponent(a)}`);return b.ok?(await b.json()).resume??null:null}Symbol.for("six-degrees.scan-state");let e=Object.freeze({skips:[],read:[]});async function f(){try{let a=await fetch("/api/scraper?reach=1");if(!a.ok)return e;let b=await a.json();return{skips:Array.isArray(b.skips)?b.skips:[],read:Array.isArray(b.read)?b.read:[]}}catch{return e}}async function g(a){let b=await fetch(`/api/scraper?person=${encodeURIComponent(a)}`);return b.ok?b.json():{person:null}}async function h(){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:[]}),j=new Set,k=i,l=JSON.stringify(k),m=null,n=null,o=0,p=!1,q=new Set;function r(a){let b=JSON.stringify(a);if(b!==l)for(let c of(l=b,k=Object.freeze(a),[...j]))c()}async function s(){(!("u">typeof document&&document.hidden)||k.running)&&await function(){if(n&&n.epoch===o)return n.promise;let a=o,b=fetch("/api/scraper?job=1").then(a=>a.ok?a.json():null).then(b=>{a===o&&function(a){if(!a||"object"!=typeof a)return;let b=!0===a.running;b&&null!=a.startedAt&&q.add(a.startedAt);let c=(Array.isArray(a.recent)?a.recent:[]).filter(a=>q.has(a.startedAt)).map(c=>({...c,log:!b&&c.startedAt===a.startedAt&&Array.isArray(a.log)?a.log:[]}));r({known:!0,running:b||p,pending:p&&!b,action:b?a.action??null:p?k.action:null,target:b?a.target??null:p?k.target:null,startedAt:b?a.startedAt??null:null,progress:b?a.progress??null:null,budget:b?a.budget??null:null,log:b&&Array.isArray(a.log)?a.log:[],finished:c})}(b)}).catch(()=>{}).finally(()=>{n?.promise===b&&(n=null)});return n={epoch:a,promise:b},b}(),clearTimeout(m),m=j.size?setTimeout(s,k.running?1500:5e3):null}function t(a){return j.add(a),1===j.size&&s(),()=>{j.delete(a),j.size||(clearTimeout(m),m=null)}}async function u(a,{name:b,id:d,onLog:e,...f}={}){let g;o++,p=!0,r({...k,known:!0,running:!0,pending:!0,action:a,target:b||d?{id:d??null,name:b??null}:null,startedAt:null,progress:null,log:[]});try{let e=!1;try{e=!0===JSON.parse(localStorage.getItem("six-degrees-hide-chrome")||"false")}catch{}g=await c(a,b,{...d?{id:d}:{},...e?{headless:!0}:{},...f})}catch(a){throw p=!1,o++,k.pending&&r({...k,running:!1,pending:!1,action:null,target:null,log:[]}),s(),a}p=!1,o++;let h=g?.startedAt??null;null!=h&&q.add(h);let i=new Promise(a=>{let b=t(()=>{k.running&&k.startedAt===h&&e?.(k.log);let c=null==h?k.running?null:{exitCode:null,failure:null,log:[]}:k.finished.find(a=>a.startedAt===h);c&&(b(),c.log.length&&e?.(c.log),a(c))});s()});return{startedAt:h,ended:i}}function v(a){return!!a?.target&&["bridge","rescrape","resume"].includes(a.action)}a.s(["NO_SCAN_NOTES",0,e,"SCANNER_UNKNOWN",0,i,"beginScrape",0,u,"busyReason",0,function(a=k){if(!a?.running)return null;let b=a.target?.name;switch(a.action){case"bridge":case"rescrape":case"resume":return b?`${b}’s circle is being scanned`:"A circle is being scanned";case"company":return b?`${b} 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(a.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,v,"loadScanNotes",0,f,"notReadyMessage",0,function(a){if(!a)return"Could not reach the app.";let b=a.checks||{};return b.scriptsFound?b.dependencies?b.chrome?null:"Google Chrome is not installed.":b.python||b.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,g,"resumePoint",0,d,"runScrape",0,function(a,b={}){return u(a,b).then(a=>a.ended)},"scannerNow",0,function(){return k},"scansCircleOf",0,function(a,b){if(!v(a)||!b)return!1;let{id:c,name:d}=a.target;return c&&b.id?c===b.id:!!d&&d===b.name},"scraperStatus",0,b,"stopScrape",0,h,"watchScanner",0,t],37732)}];
2
-
3
- //# sourceMappingURL=_005q9n1._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[36839,a=>{"use strict";var b=a.i(87924),c=a.i(75857);a.s(["default",0,function({children:a}){let{userId:d,ready:e}=(0,c.useUser)();return e&&d?a:(0,b.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:e?(0,b.jsxs)("div",{style:{maxWidth:420},children:[(0,b.jsx)("div",{style:{fontSize:18,fontWeight:700,marginBottom:8},children:"Can’t reach Six Degrees’ local server"}),(0,b.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,b.jsx)("div",{style:{fontSize:18,fontWeight:600},children:"Loading…"})})}])},76892,24475,a=>{"use strict";var b=a.i(72131),c=a.i(90231);let d=Object.freeze({known:!1,sent:new Set,mine:new Map,version:0}),e=new Set,f=d,g=null,h=new Map;function i(a=f.sent,b=f.known){for(let c of(f=Object.freeze({known:b,sent:a,mine:new Map(h),version:f.version+1}),[...e]))c()}function j(a){return e.add(a),g||f.known||(g=fetch("/api/outreach").then(a=>a.ok?a.json():null).then(a=>{a&&i(new Set((a.pending||[]).map(c.keyFor)),!0)}).catch(()=>{}).finally(()=>{g=null})),()=>e.delete(a)}function k(){return f}async function l(a){let b=await fetch("/api/outreach",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),c=await b.json().catch(()=>({}));if(!b.ok)throw Error(c.error||"Could not save that.");return c}async function m(a,{bridgeId:b}={}){let d=(0,c.keyFor)(a),e=h.has(d)?h.get(d):void 0;h.set(d,!0),i();try{return await l({action:"mark-sent",connectionId:a.id,profileUrl:a.profile_url,bridgeId:b})}catch(a){throw void 0===e?h.delete(d):h.set(d,e),i(),a}}async function n(a){let b=(0,c.keyFor)(a),d=h.has(b)?h.get(b):void 0;h.set(b,!1),i();try{return await l({action:"undo",connectionId:a.id,profileUrl:a.profile_url})}catch(a){throw void 0===d?h.delete(b):h.set(b,d),i(),a}}a.s(["REQUESTS_UNKNOWN",0,d,"hasRequest",0,function(a,b=f){if(!a)return!1;let d=(0,c.keyFor)(a);return b.mine.has(d)?b.mine.get(d):b.known?b.sent.has(d):"pending"===a.unlock_status||"sent"===a.outreach_status},"markRequested",0,m,"requestCount",0,function(a=f){let b=new Set(a.known?a.sent:[]);for(let[c,d]of a.mine)d?b.add(c):b.delete(c);return b.size},"requestsNow",0,k,"undoRequest",0,n,"watchRequests",0,j],24475),a.s(["default",0,function(){return(0,b.useSyncExternalStore)(j,k,()=>d)}],76892)},45889,a=>{"use strict";var b=a.i(90231);function c(a=[],d=[]){let e=new Set((d||[]).map(b.keyFor)),f=new Map;for(let c of a||[]){let a=c?.source_connection_id;if(null==a)continue;let d=(0,b.keyFor)(c);if(e.has(d))continue;let g=f.get(d);g||f.set(d,g=new Set),g.add(a)}let g=new Map;for(let a of f.values())for(let b of a){let c=g.get(b)||{reach:0,only:0,total:0};c.reach+=1/a.size,c.total+=1,1===a.size&&(c.only+=1),g.set(b,c)}return g}a.s(["bridgeOverlap",0,function(a=[],d=[]){let e=c(a,d),f=new Set((d||[]).map(b.keyFor)),g=new Map;for(let c of a||[]){let a=c?.source_connection_id;if(null==a)continue;let d=(0,b.keyFor)(c);if(f.has(d))continue;let e=g.get(d);e||g.set(d,e=new Set),e.add(a)}let h=new Map;for(let a of g.values()){if(a.size<2)continue;let b=[...a];for(let a=0;a<b.length;a++)for(let c=a+1;c<b.length;c++){let d=b[a]<b[c]?`${b[a]}|${b[c]}`:`${b[c]}|${b[a]}`;h.set(d,(h.get(d)||0)+1)}}let i=new Map;for(let[a,b]of h){let[c,d]=a.split("|"),f=e.get(c).total+e.get(d).total-b,g=f?b/f:0;for(let[a,e]of[[c,d],[d,c]]){let c=i.get(a);(!c||g>c.share)&&i.set(a,{with:e,share:g,shared:b})}}return i},"exclusiveReach",0,c,"redundancy",0,function(a=[],b=[]){let d=c(a,b),e=0,f=0;for(let a of d.values())e+=a.reach,f+=a.only;return e?1-f/e:0}])},1328,76433,a=>{"use strict";var b=a.i(90231),c=a.i(42510);function d(a){let b=String(a||"").trim();if(!b)return null;let c=b.match(/^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})(?::(\d{2}))?(?:\s*UTC)?$/);if(c)return Date.UTC(+c[1],c[2]-1,+c[3],+c[4],+c[5],+(c[6]||0));if(c=b.match(/^(\d{1,2})\/(\d{1,2})\/(\d{2,4}),?\s+(\d{1,2}):(\d{2})\s*(AM|PM)?$/i)){let a=100>+c[3]?2e3+ +c[3]:+c[3],b=c[4]%12;return"PM"===(c[6]||"").toUpperCase()&&(b+=12),Date.UTC(a,c[1]-1,+c[2],b,+c[5])}if(c=b.match(/^([A-Za-z]{3,9})\s+(\d{4})$/)){let a=Date.parse(`1 ${c[1]} ${c[2]} UTC`);return Number.isNaN(a)?null:a}let d=Date.parse(/\d{4}$/.test(b)?`${b} UTC`:b);return Number.isNaN(d)?null:d}let e=a=>(0,b.keyFor)({profile_url:a});function f(a,b){if(!a||!a.total)return"never";let c=b-a.last;return c<=2592e6||a.recent>=3?"warm":c<=31536e6?"cool":"dormant"}a.s(["careerChapters",0,function(a=[],b=[],c=Date.now()){let f=a.map(a=>({company:a["company name"]||"",title:a.title||"",from:d(a["started on"]),to:d(a["finished on"])})).filter(a=>a.company&&null!=a.from).sort((a,b)=>a.from-b.from),g=b.map(a=>({url:e(a.url||a.profile_url),t:d(a["connected on"]||a.connected_on)})).filter(a=>null!=a.t);return f.map(a=>{let b=a.to??c,d=g.filter(c=>c.t>=a.from&&c.t<b);return{...a,to:a.to,made:d.length,people:d.map(a=>a.url)}})},"invitationSplit",0,function(a=[]){let b=0,c=0;for(let d of a){let a=String(d.direction||"").toUpperCase();"INCOMING"===a?b+=1:"OUTGOING"===a&&(c+=1)}return{incoming:b,outgoing:c,total:b+c}},"messageStats",0,function(a=[]){let b=new Map,c=new Map;for(let f of a){let a=e(f["sender profile url"]),g=f["conversation id"];if(!g||!a)continue;let h=String(f["recipient profile urls"]||"").split(/[,;\s]+/).filter(Boolean).map(e),i=d(f.date);if(null==i)continue;b.has(g)||b.set(g,{people:new Set,msgs:[]});let j=b.get(g);j.people.add(a),h.forEach(a=>j.people.add(a)),j.msgs.push({from:a,t:i}),c.has(a)||c.set(a,new Set),c.get(a).add(g)}let f=null;for(let[a,b]of c)(!f||b.size>c.get(f).size)&&(f=a);let g=0,h=new Map;for(let a of b.values()){let b=[...a.people].filter(a=>a!==f);if(1!==b.length||!a.people.has(f))continue;let c=b[0],d=h.get(c)||{last:0,lastFromThem:!1,total:0,times:[]};for(let b of a.msgs)d.total+=1,d.times.push(b.t),b.t>=d.last&&(d.last=b.t,d.lastFromThem=b.from!==f),b.t>g&&(g=b.t);h.set(c,d)}for(let a of h.values())a.recent=a.times.filter(a=>a>g-7776e6).length,delete a.times;return{self:f,asOf:g||null,people:h}},"postingEffect",0,function(a=[],b=[]){let c=a.map(a=>({t:d(a.date),link:a.sharelink||a["share link"]||""})).filter(a=>null!=a.t).sort((a,b)=>a.t-b.t),e=b.map(a=>d(a["connected on"]||a.connected_on)).filter(a=>null!=a).sort((a,b)=>a-b);if(!e.length)return{posts:[],usualWeek:0,afterPosts:0};let f=Math.max(6048e5,e[e.length-1]-e[0]),g=e.length/f*6048e5,h=c.map(a=>({...a,week:e.filter(b=>b>=a.t&&b<a.t+6048e5).length})),i=h.length?h.reduce((a,b)=>a+b.week,0)/h.length:0;return{posts:h,usualWeek:g,afterPosts:i}},"readTable",0,function(a,b){let d=(0,c.parseCsv)(String(a||"")),e=d.findIndex(a=>a.some(a=>a.trim().toLowerCase()===b.toLowerCase()));if(e<0)return[];let f=d[e].map(a=>a.trim().toLowerCase());return d.slice(e+1).filter(a=>a.some(a=>a.trim())).map(a=>Object.fromEntries(f.map((b,c)=>[b,(a[c]??"").trim()])))},"repliesWaiting",0,function(a){let b=[];for(let[c,d]of a.people){let e=a.asOf-d.last;d.lastFromThem&&e>=2592e5&&e<=2592e6&&b.push({url:c,days:Math.round(e/864e5),total:d.total})}return b.sort((a,b)=>a.days-b.days)},"warmthOf",0,f],76433);let g="six-degrees-galaxy-lab",h="six-degrees-galaxy-layouts",i=Object.freeze({on:!1,gravity:0,rings:1,push:15,pull:1,distance:1,dotSize:1,lines:1,sizeBy:"power",names:"key",branch:!0,colourBy:"tier",speed:15,loop:!1,labels:!0}),j=["gravity","rings","push","pull","distance","dotSize","lines","sizeBy","names","branch","colourBy","speed","loop"],k=Object.freeze({gravity:.25,rings:0,push:25,pull:2.5,distance:.35,sizeBy:"reach"}),l=new Set,m=null;function n(){return m||(m=function(){try{let a=JSON.parse(localStorage.getItem(g)||"null");return a&&"object"==typeof a?{...i,...a}:i}catch{return i}}()),m}function o(a){m=null===a?{...i,on:n().on,labels:n().labels}:{...n(),...a};try{localStorage.setItem(g,JSON.stringify(m))}catch{}l.forEach(a=>a())}let p=null,q=new Set;function r(){if(!p){try{p=JSON.parse(localStorage.getItem(h)||"[]")}catch{p=[]}Array.isArray(p)||(p=[])}return p}function s(a){p=a;try{localStorage.setItem(h,JSON.stringify(a))}catch{}q.forEach(a=>a())}let t=new Set,u={at:null,playing:!1,min:null,max:null,of:0,find:"",fly:0,found:0,social:void 0},v=null;function w(a){let b={...u,...a};Object.keys(a).every(a=>Object.is(b[a],u[a]))||(u=b,t.forEach(a=>a()))}function x(){cancelAnimationFrame(v),v=null,w({playing:!1})}let y=null;function z(a){let c=new Map;for(let[d,e]of Object.entries(a?.people||{}))c.set((0,b.keyFor)({profile_url:d}),{...e});for(let[d,e]of Object.entries(a?.live||{})){let a=(0,b.keyFor)({profile_url:d}),f=c.get(a)||{total:0,recent:0};e.last&&(!f.last||e.last>f.last)&&(f.last=e.last),f.unread=e.unread,f.total=Math.max(f.total||0,1),c.set(a,f)}let d=Math.max(a?.asOf||0,a?.liveAt&&Date.parse(a.liveAt)||0);for(let a of c.values())(a.last||0)>d&&(d=a.last);return{merged:c,asOf:d,chapters:a?.chapters||[],posts:a?.posts?.posts||[]}}let A={1:"#4FC3F7",2:"#BA68C8",3:"#FFB74D"},B=["#FF6B6B","#4ECDC4","#FFD93D","#A29BFE","#00B894","#FD79A8","#74B9FF","#E17055"],C={warm:"#FF7043",cool:"#4FC3F7",dormant:"#8D6E63",never:"#546E7A"},D="#4a5568",E=a=>String(a||"").trim().toLowerCase();a.s(["CLUSTERS",0,k,"LAB_DEFAULTS",0,i,"applyLayout",0,function(a){let b=r().find(b=>b.name===a);b&&o(Object.fromEntries(j.filter(a=>a in b.settings).map(a=>[a,b.settings[a]])))},"bornTimes",0,function(a,b){let c=new Map(a.map(a=>[a.id,a])),d=new Map,e=(a,f=0)=>{if(d.has(a.id))return d.get(a.id);let g=-1/0,h=b.get(a.id);if(1===a.degree||null==h||f>6){let b=a.connected_date?Date.parse(a.connected_date):NaN;g=Number.isNaN(b)?-1/0:b}return null!=h&&c.has(h)&&f<=6&&(g=Math.max(g,e(c.get(h),f+1))),d.set(a.id,g),g};return a.map(a=>e(a))},"chapterAt",0,function(a,b){let c=null;for(let d of a?.chapters||[])Number.isFinite(d.from)&&d.from<=b&&(!c||d.from>c.from)&&(c=d);return c&&(!Number.isFinite(c.to)||c.to>b)?c:null},"clockNow",0,()=>u,"colourScheme",0,function(a,c,d,e){if("degree"===a)return{of:a=>A[Math.min(a.degree||1,3)],legend:[["1st",A[1]],["2nd",A[2]],["3rd+",A[3]]]};if("company"===a){let a=new Map;for(let b of c){let c=E(b.company);if(!c)continue;let d=a.get(c)||{name:String(b.company).trim(),n:0};d.n+=1,a.set(c,d)}let b=[...a.entries()].filter(([,a])=>a.n>1).sort((a,b)=>b[1].n-a[1].n).slice(0,B.length),d=new Map(b.map(([a],b)=>[a,B[b]]));return{of:a=>d.get(E(a.company))||D,legend:[...b.map(([,a],b)=>[a.name,B[b]]),["Other",D]]}}return"warmth"===a&&e?{of:a=>1===(a.degree||1)?C[f(e.merged.get((0,b.keyFor)(a)),e.asOf)]:"#2d3748",legend:[["Warm",C.warm],["Cool",C.cool],["Dormant",C.dormant],["Never messaged",C.never]]}:{of:a=>d[a.tier]||"#666",legend:Object.entries(d)}},"effectiveLab",0,a=>a.on?a:a.labels===i.labels?i:{...i,labels:a.labels},"findMatches",0,function(a,b){let c=String(b||"").trim().toLowerCase();if(c.length<2)return null;let d=new Set;for(let b of a)[b.name,b.company,b.role,b.headline].some(a=>a&&String(a).toLowerCase().includes(c))&&d.add(b.id);return d},"forgetLayout",0,function(a){s(r().filter(b=>b.name!==a))},"labNow",0,n,"layoutsNow",0,r,"loadSocial",0,function(){return y||(y=fetch("/api/social").then(a=>a.ok?a.json():{}).then(a=>{w({social:a.social?z(a.social):null})}).catch(()=>w({social:null}))),y},"mergeSocial",0,z,"milestones",0,function(a){let b=[];for(let c of a?.chapters||[])Number.isFinite(c.from)&&b.push({t:c.from,kind:"job",label:c.company});for(let c of a?.posts||[])Number.isFinite(c.t)&&b.push({t:c.t,kind:"post",label:"You posted"});return b.sort((a,b)=>a.t-b.t)},"pause",0,x,"play",0,function a(){if(null==u.min||null==u.max||u.max<=u.min)return;let b=u.max-u.min,c=1e3*Math.max(1,Number(n().speed)||15),d=null==u.at||u.at>=u.max?u.min:u.at,e=performance.now()-(d-u.min)/b*c;w({at:d,playing:!0});let f=d=>{let g=Math.min(u.max,u.min+(d-e)/c*b);if(w({at:g}),g>=u.max){v=null,w({playing:!1}),n().loop&&setTimeout(()=>{v||u.at!==u.max||(w({at:u.min}),a())},1200);return}v=requestAnimationFrame(f)};cancelAnimationFrame(v),v=requestAnimationFrame(f)},"reachCounts",0,function(a,b){let c=new Map(a.map(a=>[a.id,0]));for(let d of a){let a=b.get(d.id);for(let d=0;null!=a&&d<7;d++)c.set(a,(c.get(a)||0)+1),a=b.get(a)}return c},"saveLayout",0,function(a){let b=String(a||"").trim().slice(0,40);if(!b)return;let c=n(),d=Object.fromEntries(j.map(a=>[a,c[a]]));s([...r().filter(a=>a.name!==b),{name:b,settings:d}])},"setClock",0,w,"setLab",0,o,"stopReplay",0,function(){x(),w({at:null})},"watchClock",0,function(a){return t.add(a),()=>t.delete(a)},"watchLab",0,function(a){l.add(a);let b=b=>{b.key===g&&(m=null,a())};return window.addEventListener("storage",b),()=>{l.delete(a),window.removeEventListener("storage",b)}},"watchLayouts",0,function(a){return q.add(a),()=>q.delete(a)}],1328)},23310,a=>{"use strict";async function b(a){let b=a?`/api/network?userId=${encodeURIComponent(a)}`:"/api/network",c=await fetch(b);if(!c.ok)throw Error(`Failed to load network (${c.status})`);let d=await c.json();return{degree1:d.degree1||[],degree2:d.degree2||[],degree3:d.degree3||[],ties:Number(d.ties)||0}}a.s(["loadNetwork",0,b])},56377,a=>{"use strict";let b=/^[A-Za-z0-9_-]+\.(webp|jpg|jpeg|png)$/,c="/avatars/";a.s(["localPhoto",0,function(a){return"string"==typeof a&&a.startsWith(c)&&b.test(a.slice(c.length))?a:null}])},91443,a=>{"use strict";var b=a.i(90231);function c(a,c){return a?c.scanned.has(a.id)||a.profile_url&&c.read?.has((0,b.keyFor)(a))?"scanned":a.profile_url&&c.hidden.has((0,b.keyFor)(a))?"hidden":"todo":"todo"}function d(a,b){if(!a||1!==a.degree||null==a.unlocked_from_bridge_id)return null;let d=c(a,b);return"todo"===d?"ready":d}a.s(["circleScanCost",0,function(a=100){let b=Math.max(1,Math.min(100,Math.round(a)||100));return{profileViews:1,searches:b,minutes:b>=100?55:Math.max(5,Math.round(.55*b))}},"circleState",0,c,"reachIndex",0,function(a=[],c=[],d={}){let e=new Set;for(let a of c||[])a?.source_connection_id!=null&&e.add(a.source_connection_id);let f=new Set;for(let a of d?.skips||[])a?.profileUrl&&f.add((0,b.keyFor)({profile_url:a.profileUrl}));let g=new Set;for(let a of d?.read||[])a&&g.add((0,b.keyFor)({profile_url:a}));let h=new Map;for(let[a,c]of Object.entries(d?.lists||{}))a&&c&&h.set((0,b.keyFor)({profile_url:a}),c);let i=new Map;for(let b of a||[]){let a=b?.unlocked_from_bridge_id;if(null==a||1!==b.degree)continue;let c=i.get(a);c||i.set(a,c=[]),c.push(b)}return{scanned:e,read:g,hidden:f,reachedFrom:i,lists:h}},"reachState",0,d,"readyByCircle",0,function(a){let b=new Map;for(let[c,e]of a.reachedFrom){let f=e.filter(b=>"ready"===d(b,a)).length;f&&b.set(c,f)}return b},"readyToScan",0,function(a,c){return(a||[]).filter(a=>"ready"===d(a,c)).sort(b.compareBridges)},"scanBars",0,function(a,d){let e=c(a,d),f=a?.profile_url?d.lists?.get((0,b.keyFor)(a)):null;return"hidden"===e?null:f?f.more?f.total?Math.max(1,Math.min(4,Math.round(5*Math.min(1,10*f.pages/f.total)))):2:5:"scanned"===e?2:null}])},90231,a=>{"use strict";var b=a.i(56377);let c={S:0,A:1,B:2,C:3,D:4};function d(a){let b=parseFloat(a?.power_score);return Number.isFinite(b)?b:0}function e(a){return Math.round(10*d(a))/10}function f(a){return String(a?.profile_url||"").split(/[?#]/)[0].replace(/\/+$/,"")||`id:${a?.id}`}let g=(a,b)=>String(a??"").localeCompare(String(b??""),void 0,{numeric:!0});function h(a,b){return(c[a.tier]??9)-(c[b.tier]??9)||d(b)-d(a)||String(a.name||"").localeCompare(String(b.name||""))||g(a.id,b.id)}function i(a,b){return a.bridge&&b.bridge?h(a.bridge,b.bridge):a.bridge?-1:b.bridge?1:g(a.id,b.id)}function j(a,b){return b.score-a.score||b.waysIn-a.waysIn||i(a.routes[0]||k,b.routes[0]||k)||String(a.person.name||"").localeCompare(String(b.person.name||""))||(a.key<b.key?-1:+(a.key>b.key))}let k={id:null,bridge:null};function l(a){let b=String(a||"").trim().split(/\s+/).filter(Boolean);return b.length<2?b[0]||"":`${b[0]} ${b[b.length-1].charAt(0)}.`}function m(a,b){let c=String(a||"");return b<=1?c?"…":"":c.length>b?`${c.slice(0,b-1)}…`:c}a.s(["TIERS",0,["S","A","B","C","D"],"compareBridges",0,h,"compareWaysIn",0,function(a,b){return b.waysIn-a.waysIn||j(a,b)},"keyFor",0,f,"routeIndex",0,function(a=[]){let b=new Map;for(let c of a||[]){let a=f(c),d=b.get(a);d||(d=new Set,b.set(a,d)),d.add(c.source_connection_id??null)}return b},"routesFor",0,function(a,b,c){return a?[...b?.get(f(a))??(null!=a.source_connection_id?new Set([a.source_connection_id]):new Set)].map(a=>({id:a,bridge:c?.get(a)??null})).sort(i):[]},"score",0,d,"score1",0,e,"separationPeople",0,function(a=[],c=[]){let d=new Map;for(let a of c||[])d.set(a.id,a);let h=new Map,k=new Map;for(let c of a||[]){let a=f(c);k.set(c.id,a);let d=h.get(a);d?function(a,c){let d=e(a)-e(c);if(d)return d>0;let f=!!(0,b.localPhoto)(a.profile_image_url);return!!(0,b.localPhoto)(c.profile_image_url)!==f?f:0>g(a.id,c.id)}(c,d.person)&&(d.person=c):(d={key:a,person:c,rowIds:[],routeIds:new Set},h.set(a,d)),d.rowIds.push(c.id),d.routeIds.add(c.source_connection_id??null)}let l={people:h.size,byTier:{S:0,A:0,B:0,C:0,D:0},multi:0,bridges:0,unresolvedIds:0,peopleOnlyUnresolved:0,onlyUnresolvedVia:0},m=new Set,n=new Set,o=new Set,p=[];for(let a of h.values()){let b=[...a.routeIds].map(a=>({id:a,bridge:d.get(a)??null}));b.sort(i);let c=b.filter(a=>a.bridge);for(let a of b)(a.bridge?m:n).add(a.id);if(!c.length)for(let a of(l.peopleOnlyUnresolved++,b))o.add(a.id);let{person:f}=a,g=f.tier;void 0!==l.byTier[g]&&l.byTier[g]++,b.length>1&&l.multi++,p.push({key:a.key,person:f,score:e(f),tier:g,routes:b,waysIn:b.length,rowIds:a.rowIds,haystack:[f.name,f.headline,f.company,f.role,...c.map(a=>a.bridge.name)].filter(Boolean).join("\n").toLowerCase(),rank:0,tied:!1})}return l.bridges=m.size,l.unresolvedIds=n.size,l.onlyUnresolvedVia=o.size,p.sort(j),function(a){for(let b=0;b<a.length;b++){let c=a[b],d=a[b-1],e=d&&d.score===c.score&&d.waysIn===c.waysIn;c.rank=e?d.rank:b+1,e&&(c.tied=!0,d.tied=!0)}}(p),{people:p,rowToKey:k,summary:l}},"shortName",0,l,"summitLayout",0,function(a=[],b=800,c=!1){let d=c?36:26,e=Math.round(.42*b),f=Math.round(.58*b),g=a.map((a,c)=>{var e;return{key:a.key,p:a,x:f,y:16+c*d,r:(e=a.waysIn)>=4?8.5:3===e?7:2===e?5.5:4,label:m(`#${a.rank}${a.tied?"=":""} ${a.person.name||""}`,Math.floor((b-f-60)/6.2))}}),i=new Map,j="\0unresolved";for(let a of g)for(let b of a.p.routes){let c=b.bridge?b.id:j,d=i.get(c);d||(d={id:b.bridge?b.id:null,bridge:b.bridge,unresolved:!b.bridge,ys:[],count:0},i.set(c,d)),d.count++,d.ys.push(a.y)}let k=[...i.values()].map(a=>({...a,bary:a.ys.reduce((a,b)=>a+b,0)/a.ys.length}));k.sort((a,b)=>a.bary-b.bary||a.unresolved-b.unresolved||(a.bridge&&b.bridge?h(a.bridge,b.bridge):0));let n=g.length?g[g.length-1].y:16,o=k.length>1?Math.max(18,(n-16)/(k.length-1)):0,p=Math.max(4,Math.floor((e-10-42)/6));k.forEach((a,b)=>{if(a.x=e,a.y=1===k.length?(16+n)/2:16+b*o,a.r=5,a.unresolved)a.label=m(`can't be named (${a.count})`,p);else{let b=a.bridge.name||"";a.label=b.length<=p?b:m(l(b),p)}delete a.ys});let q=new Map(k.map(a=>[a.unresolved?j:a.id,a])),r=[];for(let a of g){let b=new Set;a.p.routes.forEach((c,d)=>{let e=c.bridge?c.id:j;if(b.has(e))return;b.add(e);let f=q.get(e);r.push({key:a.key,bridgeId:f.id,primary:0===d&&!f.unresolved,unresolved:f.unresolved,tier:f.bridge?.tier??null,x1:f.x,y1:f.y,x2:a.x,y2:a.y})})}let s=Math.max(n,k.length?k[k.length-1].y:0),t=g.length?Math.ceil(s+16):0,u={x:20,y:g.length?(16+Math.max(n,s))/2:16,r:14},v=k.map(a=>({id:a.id,x1:u.x,y1:u.y,x2:a.x,y2:a.y}));return{width:b,height:t,you:u,people:g,bridges:k,links:r,spokes:v}}])},76939,a=>{"use strict";a.s(["TIER_COLORS",0,{S:"#f6c344",A:"#a78bfa",B:"#60a5fa",C:"#94a3b8",D:"#6b7280"},"TIER_COLORS_CLASSIC",0,{S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"},"TIER_ORDER",0,["S","A","B","C","D"],"TIER_RING_RADIUS",0,{S:150,A:230,B:310,C:390,D:470},"initialsFor",0,function(a){let b=String(a||"").trim().split(/\s+/).filter(Boolean);return 0===b.length?"?":(b[0].charAt(0)+(b.length>1?b[b.length-1].charAt(0):"")).toUpperCase()}])},69789,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={actionAsyncStorage:function(){return f.actionAsyncStorage},workAsyncStorage:function(){return g.workAsyncStorage},workUnitAsyncStorage:function(){return h.workUnitAsyncStorage}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});let f=a.r(20635),g=a.r(56704),h=a.r(32319);("function"==typeof c.default||"object"==typeof c.default&&null!==c.default)&&void 0===c.default.__esModule&&(Object.defineProperty(c.default,"__esModule",{value:!0}),Object.assign(c.default,c),b.exports=c.default)}];
2
-
3
- //# sourceMappingURL=_217nddo._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[16874,a=>{"use strict";var b=a.i(87924);let c="1px solid rgba(255,255,255,0.1)";function d({children:a,style:c}){return(0,b.jsx)("div",{style:{fontSize:13.5,color:"#8b9a9a",lineHeight:1.6,marginTop:4,...c},children:a})}a.s(["Body",0,d,"Btn",0,function({children:a,onClick:d,disabled:e,primary:f,tone:g,type:h="button"}){return(0,b.jsx)("button",{type:h,onClick:d,disabled:e,style:{padding:"9px 18px",borderRadius:7,fontSize:13.5,fontWeight:650,color:e?"#667":"#fff",border:c,background:e?"rgba(255,255,255,0.05)":"bad"===g?"rgba(255,80,80,0.15)":f?"linear-gradient(135deg, #9B59B6, #3498DB)":"rgba(255,255,255,0.08)",cursor:e?"not-allowed":"pointer"},children:a})},"FONT",0,'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',"LINE",0,c,"Mono",0,function({children:a}){return(0,b.jsx)("code",{style:{background:"rgba(255,255,255,0.08)",padding:"1px 5px",borderRadius:4,wordBreak:"break-all"},children:a})},"Section",0,function({id:a,title:e,intro:f,children:g}){return(0,b.jsxs)("section",{id:a,style:{padding:"24px 0",borderBottom:c,scrollMarginTop:16},children:[(0,b.jsx)("h2",{style:{fontSize:16,fontWeight:650,margin:"0 0 6px"},children:e}),f&&(0,b.jsx)(d,{style:{marginTop:0,marginBottom:12},children:f}),g]})},"Status",0,function({children:a,tone:c}){return(0,b.jsxs)("div",{role:"status",style:{marginTop:10,padding:"10px 14px",borderRadius:8,fontSize:13.5,lineHeight:1.6,color:"ok"===c?"#00ff88":"bad"===c?"#ff7676":"#e8e8ee",background:"ok"===c?"rgba(0,255,136,0.08)":"bad"===c?"rgba(255,80,80,0.08)":"rgba(255,255,255,0.05)",border:`1px solid ${"ok"===c?"rgba(0,255,136,0.3)":"bad"===c?"rgba(255,80,80,0.3)":"rgba(255,255,255,0.12)"}`},children:["ok"===c&&"✓ ",a]})}])},56395,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(38246),e=a.i(36839),f=a.i(75857),g=a.i(23310),h=a.i(76433),i=a.i(1328),j=a.i(90231),k=a.i(37732),l=a.i(16874),m=a.i(58834);let n={S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"},o={warm:["Warm","#ff9f43"],cool:["Cool","#3498DB"],dormant:["Dormant","#8899aa"],never:["Never messaged","#556"]},p={"connections.csv":"first name","messages.csv":"conversation id","invitations.csv":"direction","positions.csv":"company name","shares.csv":"date"},q=a=>a?new Date(a).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"}):"";function r(){let{userId:a}=(0,f.useUser)(),[e,r]=(0,c.useState)(void 0),[s,t]=(0,c.useState)(null),[u,v]=(0,c.useState)(!1),[w,x]=(0,c.useState)(null),[y,z]=(0,c.useState)(!1),[A,B]=(0,c.useState)(()=>(0,k.scannerNow)()),C=()=>fetch("/api/social").then(a=>a.json()).then(a=>r(a.social||null)).catch(()=>r(null));(0,c.useEffect)(()=>{C()},[]),(0,c.useEffect)(()=>(0,k.watchScanner)(()=>B((0,k.scannerNow)())),[]),(0,c.useEffect)(()=>{if(!a)return;let b=!0;return(0,g.loadNetwork)(a).then(a=>{b&&t(a)}).catch(()=>{}),()=>{b=!1}},[a]);let D=(0,c.useMemo)(()=>{let a=new Map;for(let b of[...s?.degree1||[],...s?.degree2||[]])a.has((0,j.keyFor)(b))||a.set((0,j.keyFor)(b),b);return a},[s]);async function E(a){z(!0),x(null);try{let b={};for(let c of Array.from(a||[])){let a=c.name.toLowerCase();p[a]&&!b[a]&&(b[a]=(0,h.readTable)(await c.text(),p[a]))}if(!Object.keys(b).length)throw Error("That folder doesn’t have LinkedIn’s export files in it (Connections.csv, messages.csv and so on).");let c=b["connections.csv"]||[],d=b["messages.csv"]?(0,h.messageStats)(b["messages.csv"]):{asOf:null,people:new Map},e={};for(let[a,b]of d.people)e[a]={last:b.last,lastFromThem:b.lastFromThem,total:b.total,recent:b.recent};if(u)for(let a of c){let b=a["email address"];if(!b)continue;let c=(0,j.keyFor)({profile_url:a.url});e[c]={...e[c]||{},email:b}}let f=d.asOf||Date.now(),g={asOf:f,people:e,chapters:(0,h.careerChapters)(b["positions.csv"]||[],c,f),posts:b["shares.csv"]?(0,h.postingEffect)(b["shares.csv"],c):null,invites:b["invitations.csv"]?(0,h.invitationSplit)(b["invitations.csv"]):null,emails:u},i=await fetch("/api/social",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)});if(!i.ok)throw Error((await i.json().catch(()=>({}))).error||"It couldn’t be saved.");x({good:!0,text:`Read ${Object.keys(b).length} of LinkedIn’s files: ${d.people.size.toLocaleString()} people you’ve messaged one to one.`}),await C()}catch(a){x({good:!1,text:a.message})}finally{z(!1)}}async function F(){x(null);try{let a=await (0,k.runScrape)("messages");x(a?.exitCode===0?{good:!0,text:"Your messages list is read."}:{good:!1,text:"The sync stopped before it finished. The Scan page has the log."}),await C()}catch(a){x({good:!1,text:a.message})}}async function G(a){await fetch("/api/social",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({autoSync:a})}),C()}async function H(){await fetch("/api/social",{method:"DELETE"}),x({good:!0,text:"Forgotten. Nothing from your export or messages is kept here now."}),C()}let{merged:I,asOf:J}=(0,c.useMemo)(()=>(0,i.mergeSocial)(e),[e]),K=(0,c.useMemo)(()=>{let a={warm:0,cool:0,dormant:0,never:0};for(let b of s?.degree1||[])a[(0,h.warmthOf)(I.get((0,j.keyFor)(b)),J)]+=1;return a},[s,I,J]),L=(0,c.useMemo)(()=>{let a={asOf:J,people:new Map([...I].filter(([,a])=>null!=a.lastFromThem))},b=(0,h.repliesWaiting)(a).map(a=>({...a,person:D.get(a.url)}));for(let[a,c]of I)c.unread>0&&!b.some(b=>b.url===a)&&b.push({url:a,unread:c.unread,person:D.get(a)});let c=a=>({S:0,A:1})[a.person?.tier]??2;return b.sort((a,b)=>c(a)-c(b)||(a.days??0)-(b.days??0)).slice(0,15)},[I,J,D]);if(m.IS_DEMO)return(0,b.jsx)("div",{style:{minHeight:"100vh",background:"#0a0a1a",color:"#aaa",padding:40,fontFamily:l.FONT},children:"Not part of the demo."});let M=A?.running,N={padding:"12px 14px",borderRadius:8,border:l.LINE,background:"rgba(255,255,255,0.03)",marginTop:10},O={fontSize:16,margin:"24px 0 6px"};return(0,b.jsxs)("div",{style:{minHeight:"100vh",background:"#0a0a1a",color:"#fff",fontFamily:l.FONT},children:[(0,b.jsxs)("header",{style:{padding:"16px 24px",borderBottom:l.LINE,display:"flex",alignItems:"center",gap:16},children:[(0,b.jsx)(d.default,{href:"/",style:{color:"#888",textDecoration:"none",fontSize:13,fontWeight:600,padding:"6px 14px",borderRadius:6,background:"rgba(255,255,255,0.06)",border:l.LINE},children:"← Back to Map"}),(0,b.jsxs)("h1",{style:{fontSize:22,fontWeight:700,margin:0,color:"#FFD700"},children:["Social ",(0,b.jsx)("span",{style:{fontSize:12,color:"#8b9a9a",fontWeight:600},children:"experimental"})]})]}),(0,b.jsxs)("main",{style:{maxWidth:980,margin:"0 auto",padding:"8px 24px 64px"},children:[(0,b.jsx)(l.Body,{style:{marginTop:16},children:"Who you’re warm with, who’s waiting on a reply, and how each chapter of your career built your network, from your own LinkedIn data. Only dates, who wrote last and counts are kept on this computer, never what a message says."}),(0,b.jsx)("h2",{style:O,children:"Your LinkedIn export"}),(0,b.jsxs)("div",{style:N,children:[(0,b.jsxs)(l.Body,{style:{margin:0},children:["On LinkedIn: ",(0,b.jsx)("i",{children:"Settings → Data privacy → Get a copy of your data"}),", pick the larger archive, and unzip the file it emails you. Then choose that folder here. It’s read in this window; nothing goes to LinkedIn."]}),(0,b.jsxs)("label",{style:{display:"flex",gap:8,alignItems:"flex-start",fontSize:12.5,color:"#b8c4c4",marginTop:10},children:[(0,b.jsx)("input",{type:"checkbox",checked:u,onChange:a=>v(a.target.checked),style:{marginTop:3}}),(0,b.jsx)("span",{children:"Also keep email addresses from it, on this computer only, for one-click email."})]}),(0,b.jsxs)("div",{style:{marginTop:10,display:"flex",gap:10,alignItems:"center",flexWrap:"wrap"},children:[(0,b.jsxs)("label",{style:{padding:"7px 14px",borderRadius:8,background:"rgba(52,152,219,0.18)",color:"#cfe6f7",cursor:y?"default":"pointer",fontSize:13},children:[y?"Reading…":e?"Choose a newer export":"Choose the export folder",(0,b.jsx)("input",{type:"file",webkitdirectory:"",directory:"",multiple:!0,disabled:y,style:{display:"none"},onChange:a=>E(a.target.files)})]}),e&&(0,b.jsxs)("span",{style:{fontSize:12,color:"#8b9a9a"},children:["From an export up to ",q(e.asOf),e.liveAt?` \xb7 messages synced ${q(Date.parse(e.liveAt))}`:""]}),e&&(0,b.jsx)("button",{onClick:H,style:{background:"none",border:"none",color:"#ff9b9b",cursor:"pointer",fontSize:12},children:"Forget it"})]})]}),(0,b.jsxs)("h2",{style:O,children:["Live messages sync ",(0,b.jsx)("span",{style:{fontSize:11,color:"#FFD700"},children:"experimental"})]}),(0,b.jsxs)("div",{style:N,children:[(0,b.jsx)(l.Body,{style:{margin:0},children:"Reads your messages list once, in your own Chrome: who each one-to-one conversation is with, when it was last active and whether it’s unread. It uses no search budget and never opens or keeps a message’s text."}),(0,b.jsxs)("div",{style:{marginTop:10,display:"flex",gap:12,alignItems:"center",flexWrap:"wrap"},children:[(0,b.jsx)("button",{onClick:F,disabled:M,style:{padding:"7px 14px",borderRadius:8,border:"none",background:M?"#333":"rgba(0,255,136,0.15)",color:M?"#777":"#00ff88",cursor:M?"default":"pointer",fontSize:13},children:M?"The scanner is busy":"Sync messages now"}),(0,b.jsxs)("label",{style:{display:"flex",gap:6,alignItems:"center",fontSize:12.5,color:"#b8c4c4"},children:[(0,b.jsx)("input",{type:"checkbox",checked:e?.autoSync===!0,onChange:a=>G(a.target.checked)}),"Once a day while the app is open (daytime only)"]})]})]}),w&&(0,b.jsx)("div",{style:{marginTop:10,fontSize:13,color:w.good?"#00ff88":"#ff9b9b"},children:w.text}),e&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("h2",{style:O,children:"Warmth"}),(0,b.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(160px, 1fr))",gap:10},children:Object.entries(o).map(([a,[c,d]])=>(0,b.jsxs)("div",{style:{...N,marginTop:0},children:[(0,b.jsx)("div",{style:{fontSize:22,fontWeight:700,color:d},children:(K[a]||0).toLocaleString()}),(0,b.jsx)("div",{style:{fontSize:12.5,color:"#b8c4c4"},children:c})]},a))}),(0,b.jsx)("div",{style:{fontSize:11.5,color:"#778",marginTop:6},children:"Of your connections. Warm: messaged in the last 30 days, or 3+ messages in 90. Cool: within a year. Dormant: longer ago."}),(0,b.jsx)("h2",{style:O,children:"Waiting on you"}),(0,b.jsxs)("div",{style:{...N,padding:0},children:[0===L.length&&(0,b.jsx)("div",{style:{padding:12,fontSize:13,color:"#8b9a9a"},children:"No one is waiting on a reply."}),L.map(a=>(0,b.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"8px 14px",borderBottom:"1px solid rgba(255,255,255,0.04)",fontSize:13},children:[(0,b.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:n[a.person?.tier]||"#556",flexShrink:0}}),(0,b.jsxs)("span",{style:{flex:1,minWidth:0},children:[(0,b.jsx)("b",{children:a.person?.name||String(a.url||"").replace(/\/+$/,"").split("/").pop()}),a.person?.company?(0,b.jsxs)("span",{style:{color:"#8b9a9a"},children:[" · ",a.person.company]}):null]}),(0,b.jsx)("span",{style:{color:"#b8c4c4"},children:a.unread?`${a.unread} unread`:`wrote ${a.days} days before your export`}),(0,b.jsx)("a",{href:a.url,target:"_blank",rel:"noreferrer",style:{color:"#3498DB",textDecoration:"none"},children:"Open ↗"})]},a.url))]}),e.chapters?.length>0&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("h2",{style:O,children:"Career chapters"}),(0,b.jsx)("div",{style:{...N,padding:0},children:e.chapters.map(a=>{let c=(a.people||[]).filter(a=>["warm","cool"].includes((0,h.warmthOf)(I.get((0,j.keyFor)({profile_url:a})),J))).length;return(0,b.jsxs)("div",{style:{display:"flex",gap:10,padding:"8px 14px",borderBottom:"1px solid rgba(255,255,255,0.04)",fontSize:13,alignItems:"baseline"},children:[(0,b.jsxs)("span",{style:{flex:1},children:[(0,b.jsx)("b",{children:a.company})," ",(0,b.jsxs)("span",{style:{color:"#8b9a9a"},children:[a.title," · ",new Date(a.from).getFullYear(),"–",a.to?new Date(a.to).getFullYear():"now"]})]}),(0,b.jsxs)("span",{style:{color:"#b8c4c4"},children:[a.made.toLocaleString()," connections made"]}),(0,b.jsx)("span",{style:{color:"#ff9f43",minWidth:90,textAlign:"right"},children:a.made?`${Math.round(100*c/a.made)}% still in touch`:""})]},`${a.company}-${a.from}`)})})]}),e.posts?.posts?.length>0&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("h2",{style:O,children:"Does posting work?"}),(0,b.jsxs)("div",{style:N,children:[(0,b.jsxs)("div",{style:{fontSize:13},children:["In the week after a post you made ",(0,b.jsx)("b",{children:e.posts.afterPosts.toFixed(1)})," new connections on average; a usual week, ",(0,b.jsx)("b",{children:e.posts.usualWeek.toFixed(1)}),"."]}),(0,b.jsx)("div",{style:{fontSize:11.5,color:"#778",marginTop:4},children:"What came after a post, not proof it came from it."}),[...e.posts.posts].sort((a,b)=>b.week-a.week).slice(0,3).map(a=>(0,b.jsxs)("div",{style:{fontSize:12.5,color:"#b8c4c4",marginTop:6},children:[q(a.t),": ",a.week," new connections that week ",a.link?(0,b.jsx)("a",{href:a.link,target:"_blank",rel:"noreferrer",style:{color:"#3498DB",textDecoration:"none"},children:"Post ↗"}):null]},a.t))]})]}),e.invites?.total>0&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("h2",{style:O,children:"Who reaches out"}),(0,b.jsx)("div",{style:N,children:(0,b.jsxs)("span",{style:{fontSize:13},children:[e.invites.incoming.toLocaleString()," requests came to you and you sent ",e.invites.outgoing.toLocaleString()," ","(",Math.round(100*e.invites.incoming/e.invites.total),"% came to you), as far as your export shows."]})})]})]})]})]})}a.s(["default",0,function(){return(0,b.jsx)(e.default,{children:(0,b.jsx)(r,{})})}])}];
2
-
3
- //# sourceMappingURL=app_0i3fw_m._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[69789,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={actionAsyncStorage:function(){return f.actionAsyncStorage},workAsyncStorage:function(){return g.workAsyncStorage},workUnitAsyncStorage:function(){return h.workUnitAsyncStorage}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});let f=a.r(20635),g=a.r(56704),h=a.r(32319);("function"==typeof c.default||"object"==typeof c.default&&null!==c.default)&&void 0===c.default.__esModule&&(Object.defineProperty(c.default,"__esModule",{value:!0}),Object.assign(c.default,c),b.exports=c.default)}];
2
-
3
- //# sourceMappingURL=node_modules_next_dist_client_components_server-async-storage_0t1dato.js.map
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,2776,e=>{"use strict";var t=e.i(43476),n=e.i(15812);e.s(["default",0,function({children:e}){let{userId:r,ready:o}=(0,n.useUser)();return o&&r?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:o?(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…"})})}])},8819,e=>{"use strict";var t=e.i(43476);let n="1px solid rgba(255,255,255,0.1)";function r({children:e,style:n}){return(0,t.jsx)("div",{style:{fontSize:13.5,color:"#8b9a9a",lineHeight:1.6,marginTop:4,...n},children:e})}e.s(["Body",0,r,"Btn",0,function({children:e,onClick:r,disabled:o,primary:a,tone:l,type:i="button"}){return(0,t.jsx)("button",{type:i,onClick:r,disabled:o,style:{padding:"9px 18px",borderRadius:7,fontSize:13.5,fontWeight:650,color:o?"#667":"#fff",border:n,background:o?"rgba(255,255,255,0.05)":"bad"===l?"rgba(255,80,80,0.15)":a?"linear-gradient(135deg, #9B59B6, #3498DB)":"rgba(255,255,255,0.08)",cursor:o?"not-allowed":"pointer"},children:e})},"FONT",0,'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',"LINE",0,n,"Mono",0,function({children:e}){return(0,t.jsx)("code",{style:{background:"rgba(255,255,255,0.08)",padding:"1px 5px",borderRadius:4,wordBreak:"break-all"},children:e})},"Section",0,function({id:e,title:o,intro:a,children:l}){return(0,t.jsxs)("section",{id:e,style:{padding:"24px 0",borderBottom:n,scrollMarginTop:16},children:[(0,t.jsx)("h2",{style:{fontSize:16,fontWeight:650,margin:"0 0 6px"},children:o}),a&&(0,t.jsx)(r,{style:{marginTop:0,marginBottom:12},children:a}),l]})},"Status",0,function({children:e,tone:n}){return(0,t.jsxs)("div",{role:"status",style:{marginTop:10,padding:"10px 14px",borderRadius:8,fontSize:13.5,lineHeight:1.6,color:"ok"===n?"#00ff88":"bad"===n?"#ff7676":"#e8e8ee",background:"ok"===n?"rgba(0,255,136,0.08)":"bad"===n?"rgba(255,80,80,0.08)":"rgba(255,255,255,0.05)",border:`1px solid ${"ok"===n?"rgba(0,255,136,0.3)":"bad"===n?"rgba(255,80,80,0.3)":"rgba(255,255,255,0.12)"}`},children:["ok"===n&&"✓ ",e]})}])},60451,e=>{"use strict";var t=e.i(43476),n=e.i(71645),r=e.i(22016),o=e.i(2776),a=e.i(15812),l=e.i(19821),i=e.i(84278),s=e.i(39160),d=e.i(7214),c=e.i(40996),u=e.i(8819),p=e.i(64745);let f={S:"#FFD700",A:"#9B59B6",B:"#3498DB",C:"#95A5A6",D:"#BDC3C7"},g={warm:["Warm","#ff9f43"],cool:["Cool","#3498DB"],dormant:["Dormant","#8899aa"],never:["Never messaged","#556"]},h={"connections.csv":"first name","messages.csv":"conversation id","invitations.csv":"direction","positions.csv":"company name","shares.csv":"date"},m=e=>e?new Date(e).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"}):"";function y(){let{userId:e}=(0,a.useUser)(),[o,y]=(0,n.useState)(void 0),[x,b]=(0,n.useState)(null),[w,v]=(0,n.useState)(!1),[S,j]=(0,n.useState)(null),[k,F]=(0,n.useState)(!1),[C,I]=(0,n.useState)(()=>(0,c.scannerNow)()),T=()=>fetch("/api/social").then(e=>e.json()).then(e=>y(e.social||null)).catch(()=>y(null));(0,n.useEffect)(()=>{T()},[]),(0,n.useEffect)(()=>(0,c.watchScanner)(()=>I((0,c.scannerNow)())),[]),(0,n.useEffect)(()=>{if(!e)return;let t=!0;return(0,l.loadNetwork)(e).then(e=>{t&&b(e)}).catch(()=>{}),()=>{t=!1}},[e]);let M=(0,n.useMemo)(()=>{let e=new Map;for(let t of[...x?.degree1||[],...x?.degree2||[]])e.has((0,d.keyFor)(t))||e.set((0,d.keyFor)(t),t);return e},[x]);async function B(e){F(!0),j(null);try{let t={};for(let n of Array.from(e||[])){let e=n.name.toLowerCase();h[e]&&!t[e]&&(t[e]=(0,i.readTable)(await n.text(),h[e]))}if(!Object.keys(t).length)throw Error("That folder doesn’t have LinkedIn’s export files in it (Connections.csv, messages.csv and so on).");let n=t["connections.csv"]||[],r=t["messages.csv"]?(0,i.messageStats)(t["messages.csv"]):{asOf:null,people:new Map},o={};for(let[e,t]of r.people)o[e]={last:t.last,lastFromThem:t.lastFromThem,total:t.total,recent:t.recent};if(w)for(let e of n){let t=e["email address"];if(!t)continue;let n=(0,d.keyFor)({profile_url:e.url});o[n]={...o[n]||{},email:t}}let a=r.asOf||Date.now(),l={asOf:a,people:o,chapters:(0,i.careerChapters)(t["positions.csv"]||[],n,a),posts:t["shares.csv"]?(0,i.postingEffect)(t["shares.csv"],n):null,invites:t["invitations.csv"]?(0,i.invitationSplit)(t["invitations.csv"]):null,emails:w},s=await fetch("/api/social",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(!s.ok)throw Error((await s.json().catch(()=>({}))).error||"It couldn’t be saved.");j({good:!0,text:`Read ${Object.keys(t).length} of LinkedIn’s files: ${r.people.size.toLocaleString()} people you’ve messaged one to one.`}),await T()}catch(e){j({good:!1,text:e.message})}finally{F(!1)}}async function N(){j(null);try{let e=await (0,c.runScrape)("messages");j(e?.exitCode===0?{good:!0,text:"Your messages list is read."}:{good:!1,text:"The sync stopped before it finished. The Scan page has the log."}),await T()}catch(e){j({good:!1,text:e.message})}}async function O(e){await fetch("/api/social",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({autoSync:e})}),T()}async function z(){await fetch("/api/social",{method:"DELETE"}),j({good:!0,text:"Forgotten. Nothing from your export or messages is kept here now."}),T()}let{merged:D,asOf:L}=(0,n.useMemo)(()=>(0,s.mergeSocial)(o),[o]),A=(0,n.useMemo)(()=>{let e={warm:0,cool:0,dormant:0,never:0};for(let t of x?.degree1||[])e[(0,i.warmthOf)(D.get((0,d.keyFor)(t)),L)]+=1;return e},[x,D,L]),E=(0,n.useMemo)(()=>{let e={asOf:L,people:new Map([...D].filter(([,e])=>null!=e.lastFromThem))},t=(0,i.repliesWaiting)(e).map(e=>({...e,person:M.get(e.url)}));for(let[e,n]of D)n.unread>0&&!t.some(t=>t.url===e)&&t.push({url:e,unread:n.unread,person:M.get(e)});let n=e=>({S:0,A:1})[e.person?.tier]??2;return t.sort((e,t)=>n(e)-n(t)||(e.days??0)-(t.days??0)).slice(0,15)},[D,L,M]);if(p.IS_DEMO)return(0,t.jsx)("div",{style:{minHeight:"100vh",background:"#0a0a1a",color:"#aaa",padding:40,fontFamily:u.FONT},children:"Not part of the demo."});let $=C?.running,_={padding:"12px 14px",borderRadius:8,border:u.LINE,background:"rgba(255,255,255,0.03)",marginTop:10},W={fontSize:16,margin:"24px 0 6px"};return(0,t.jsxs)("div",{style:{minHeight:"100vh",background:"#0a0a1a",color:"#fff",fontFamily:u.FONT},children:[(0,t.jsxs)("header",{style:{padding:"16px 24px",borderBottom:u.LINE,display:"flex",alignItems:"center",gap:16},children:[(0,t.jsx)(r.default,{href:"/",style:{color:"#888",textDecoration:"none",fontSize:13,fontWeight:600,padding:"6px 14px",borderRadius:6,background:"rgba(255,255,255,0.06)",border:u.LINE},children:"← Back to Map"}),(0,t.jsxs)("h1",{style:{fontSize:22,fontWeight:700,margin:0,color:"#FFD700"},children:["Social ",(0,t.jsx)("span",{style:{fontSize:12,color:"#8b9a9a",fontWeight:600},children:"experimental"})]})]}),(0,t.jsxs)("main",{style:{maxWidth:980,margin:"0 auto",padding:"8px 24px 64px"},children:[(0,t.jsx)(u.Body,{style:{marginTop:16},children:"Who you’re warm with, who’s waiting on a reply, and how each chapter of your career built your network, from your own LinkedIn data. Only dates, who wrote last and counts are kept on this computer, never what a message says."}),(0,t.jsx)("h2",{style:W,children:"Your LinkedIn export"}),(0,t.jsxs)("div",{style:_,children:[(0,t.jsxs)(u.Body,{style:{margin:0},children:["On LinkedIn: ",(0,t.jsx)("i",{children:"Settings → Data privacy → Get a copy of your data"}),", pick the larger archive, and unzip the file it emails you. Then choose that folder here. It’s read in this window; nothing goes to LinkedIn."]}),(0,t.jsxs)("label",{style:{display:"flex",gap:8,alignItems:"flex-start",fontSize:12.5,color:"#b8c4c4",marginTop:10},children:[(0,t.jsx)("input",{type:"checkbox",checked:w,onChange:e=>v(e.target.checked),style:{marginTop:3}}),(0,t.jsx)("span",{children:"Also keep email addresses from it, on this computer only, for one-click email."})]}),(0,t.jsxs)("div",{style:{marginTop:10,display:"flex",gap:10,alignItems:"center",flexWrap:"wrap"},children:[(0,t.jsxs)("label",{style:{padding:"7px 14px",borderRadius:8,background:"rgba(52,152,219,0.18)",color:"#cfe6f7",cursor:k?"default":"pointer",fontSize:13},children:[k?"Reading…":o?"Choose a newer export":"Choose the export folder",(0,t.jsx)("input",{type:"file",webkitdirectory:"",directory:"",multiple:!0,disabled:k,style:{display:"none"},onChange:e=>B(e.target.files)})]}),o&&(0,t.jsxs)("span",{style:{fontSize:12,color:"#8b9a9a"},children:["From an export up to ",m(o.asOf),o.liveAt?` \xb7 messages synced ${m(Date.parse(o.liveAt))}`:""]}),o&&(0,t.jsx)("button",{onClick:z,style:{background:"none",border:"none",color:"#ff9b9b",cursor:"pointer",fontSize:12},children:"Forget it"})]})]}),(0,t.jsxs)("h2",{style:W,children:["Live messages sync ",(0,t.jsx)("span",{style:{fontSize:11,color:"#FFD700"},children:"experimental"})]}),(0,t.jsxs)("div",{style:_,children:[(0,t.jsx)(u.Body,{style:{margin:0},children:"Reads your messages list once, in your own Chrome: who each one-to-one conversation is with, when it was last active and whether it’s unread. It uses no search budget and never opens or keeps a message’s text."}),(0,t.jsxs)("div",{style:{marginTop:10,display:"flex",gap:12,alignItems:"center",flexWrap:"wrap"},children:[(0,t.jsx)("button",{onClick:N,disabled:$,style:{padding:"7px 14px",borderRadius:8,border:"none",background:$?"#333":"rgba(0,255,136,0.15)",color:$?"#777":"#00ff88",cursor:$?"default":"pointer",fontSize:13},children:$?"The scanner is busy":"Sync messages now"}),(0,t.jsxs)("label",{style:{display:"flex",gap:6,alignItems:"center",fontSize:12.5,color:"#b8c4c4"},children:[(0,t.jsx)("input",{type:"checkbox",checked:o?.autoSync===!0,onChange:e=>O(e.target.checked)}),"Once a day while the app is open (daytime only)"]})]})]}),S&&(0,t.jsx)("div",{style:{marginTop:10,fontSize:13,color:S.good?"#00ff88":"#ff9b9b"},children:S.text}),o&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h2",{style:W,children:"Warmth"}),(0,t.jsx)("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(160px, 1fr))",gap:10},children:Object.entries(g).map(([e,[n,r]])=>(0,t.jsxs)("div",{style:{..._,marginTop:0},children:[(0,t.jsx)("div",{style:{fontSize:22,fontWeight:700,color:r},children:(A[e]||0).toLocaleString()}),(0,t.jsx)("div",{style:{fontSize:12.5,color:"#b8c4c4"},children:n})]},e))}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#778",marginTop:6},children:"Of your connections. Warm: messaged in the last 30 days, or 3+ messages in 90. Cool: within a year. Dormant: longer ago."}),(0,t.jsx)("h2",{style:W,children:"Waiting on you"}),(0,t.jsxs)("div",{style:{..._,padding:0},children:[0===E.length&&(0,t.jsx)("div",{style:{padding:12,fontSize:13,color:"#8b9a9a"},children:"No one is waiting on a reply."}),E.map(e=>(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"8px 14px",borderBottom:"1px solid rgba(255,255,255,0.04)",fontSize:13},children:[(0,t.jsx)("span",{style:{width:8,height:8,borderRadius:"50%",background:f[e.person?.tier]||"#556",flexShrink:0}}),(0,t.jsxs)("span",{style:{flex:1,minWidth:0},children:[(0,t.jsx)("b",{children:e.person?.name||String(e.url||"").replace(/\/+$/,"").split("/").pop()}),e.person?.company?(0,t.jsxs)("span",{style:{color:"#8b9a9a"},children:[" · ",e.person.company]}):null]}),(0,t.jsx)("span",{style:{color:"#b8c4c4"},children:e.unread?`${e.unread} unread`:`wrote ${e.days} days before your export`}),(0,t.jsx)("a",{href:e.url,target:"_blank",rel:"noreferrer",style:{color:"#3498DB",textDecoration:"none"},children:"Open ↗"})]},e.url))]}),o.chapters?.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h2",{style:W,children:"Career chapters"}),(0,t.jsx)("div",{style:{..._,padding:0},children:o.chapters.map(e=>{let n=(e.people||[]).filter(e=>["warm","cool"].includes((0,i.warmthOf)(D.get((0,d.keyFor)({profile_url:e})),L))).length;return(0,t.jsxs)("div",{style:{display:"flex",gap:10,padding:"8px 14px",borderBottom:"1px solid rgba(255,255,255,0.04)",fontSize:13,alignItems:"baseline"},children:[(0,t.jsxs)("span",{style:{flex:1},children:[(0,t.jsx)("b",{children:e.company})," ",(0,t.jsxs)("span",{style:{color:"#8b9a9a"},children:[e.title," · ",new Date(e.from).getFullYear(),"–",e.to?new Date(e.to).getFullYear():"now"]})]}),(0,t.jsxs)("span",{style:{color:"#b8c4c4"},children:[e.made.toLocaleString()," connections made"]}),(0,t.jsx)("span",{style:{color:"#ff9f43",minWidth:90,textAlign:"right"},children:e.made?`${Math.round(100*n/e.made)}% still in touch`:""})]},`${e.company}-${e.from}`)})})]}),o.posts?.posts?.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h2",{style:W,children:"Does posting work?"}),(0,t.jsxs)("div",{style:_,children:[(0,t.jsxs)("div",{style:{fontSize:13},children:["In the week after a post you made ",(0,t.jsx)("b",{children:o.posts.afterPosts.toFixed(1)})," new connections on average; a usual week, ",(0,t.jsx)("b",{children:o.posts.usualWeek.toFixed(1)}),"."]}),(0,t.jsx)("div",{style:{fontSize:11.5,color:"#778",marginTop:4},children:"What came after a post, not proof it came from it."}),[...o.posts.posts].sort((e,t)=>t.week-e.week).slice(0,3).map(e=>(0,t.jsxs)("div",{style:{fontSize:12.5,color:"#b8c4c4",marginTop:6},children:[m(e.t),": ",e.week," new connections that week ",e.link?(0,t.jsx)("a",{href:e.link,target:"_blank",rel:"noreferrer",style:{color:"#3498DB",textDecoration:"none"},children:"Post ↗"}):null]},e.t))]})]}),o.invites?.total>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("h2",{style:W,children:"Who reaches out"}),(0,t.jsx)("div",{style:_,children:(0,t.jsxs)("span",{style:{fontSize:13},children:[o.invites.incoming.toLocaleString()," requests came to you and you sent ",o.invites.outgoing.toLocaleString()," ","(",Math.round(100*o.invites.incoming/o.invites.total),"% came to you), as far as your export shows."]})})]})]})]})]})}e.s(["default",0,function(){return(0,t.jsx)(o.default,{children:(0,t.jsx)(y,{})})}])},39160,84278,e=>{"use strict";var t=e.i(7214),n=e.i(7837);function r(e){let t=String(e||"").trim();if(!t)return null;let n=t.match(/^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2})(?::(\d{2}))?(?:\s*UTC)?$/);if(n)return Date.UTC(+n[1],n[2]-1,+n[3],+n[4],+n[5],+(n[6]||0));if(n=t.match(/^(\d{1,2})\/(\d{1,2})\/(\d{2,4}),?\s+(\d{1,2}):(\d{2})\s*(AM|PM)?$/i)){let e=100>+n[3]?2e3+ +n[3]:+n[3],t=n[4]%12;return"PM"===(n[6]||"").toUpperCase()&&(t+=12),Date.UTC(e,n[1]-1,+n[2],t,+n[5])}if(n=t.match(/^([A-Za-z]{3,9})\s+(\d{4})$/)){let e=Date.parse(`1 ${n[1]} ${n[2]} UTC`);return Number.isNaN(e)?null:e}let r=Date.parse(/\d{4}$/.test(t)?`${t} UTC`:t);return Number.isNaN(r)?null:r}let o=e=>(0,t.keyFor)({profile_url:e});function a(e,t){if(!e||!e.total)return"never";let n=t-e.last;return n<=2592e6||e.recent>=3?"warm":n<=31536e6?"cool":"dormant"}e.s(["careerChapters",0,function(e=[],t=[],n=Date.now()){let a=e.map(e=>({company:e["company name"]||"",title:e.title||"",from:r(e["started on"]),to:r(e["finished on"])})).filter(e=>e.company&&null!=e.from).sort((e,t)=>e.from-t.from),l=t.map(e=>({url:o(e.url||e.profile_url),t:r(e["connected on"]||e.connected_on)})).filter(e=>null!=e.t);return a.map(e=>{let t=e.to??n,r=l.filter(n=>n.t>=e.from&&n.t<t);return{...e,to:e.to,made:r.length,people:r.map(e=>e.url)}})},"invitationSplit",0,function(e=[]){let t=0,n=0;for(let r of e){let e=String(r.direction||"").toUpperCase();"INCOMING"===e?t+=1:"OUTGOING"===e&&(n+=1)}return{incoming:t,outgoing:n,total:t+n}},"messageStats",0,function(e=[]){let t=new Map,n=new Map;for(let a of e){let e=o(a["sender profile url"]),l=a["conversation id"];if(!l||!e)continue;let i=String(a["recipient profile urls"]||"").split(/[,;\s]+/).filter(Boolean).map(o),s=r(a.date);if(null==s)continue;t.has(l)||t.set(l,{people:new Set,msgs:[]});let d=t.get(l);d.people.add(e),i.forEach(e=>d.people.add(e)),d.msgs.push({from:e,t:s}),n.has(e)||n.set(e,new Set),n.get(e).add(l)}let a=null;for(let[e,t]of n)(!a||t.size>n.get(a).size)&&(a=e);let l=0,i=new Map;for(let e of t.values()){let t=[...e.people].filter(e=>e!==a);if(1!==t.length||!e.people.has(a))continue;let n=t[0],r=i.get(n)||{last:0,lastFromThem:!1,total:0,times:[]};for(let t of e.msgs)r.total+=1,r.times.push(t.t),t.t>=r.last&&(r.last=t.t,r.lastFromThem=t.from!==a),t.t>l&&(l=t.t);i.set(n,r)}for(let e of i.values())e.recent=e.times.filter(e=>e>l-7776e6).length,delete e.times;return{self:a,asOf:l||null,people:i}},"postingEffect",0,function(e=[],t=[]){let n=e.map(e=>({t:r(e.date),link:e.sharelink||e["share link"]||""})).filter(e=>null!=e.t).sort((e,t)=>e.t-t.t),o=t.map(e=>r(e["connected on"]||e.connected_on)).filter(e=>null!=e).sort((e,t)=>e-t);if(!o.length)return{posts:[],usualWeek:0,afterPosts:0};let a=Math.max(6048e5,o[o.length-1]-o[0]),l=o.length/a*6048e5,i=n.map(e=>({...e,week:o.filter(t=>t>=e.t&&t<e.t+6048e5).length})),s=i.length?i.reduce((e,t)=>e+t.week,0)/i.length:0;return{posts:i,usualWeek:l,afterPosts:s}},"readTable",0,function(e,t){let r=(0,n.parseCsv)(String(e||"")),o=r.findIndex(e=>e.some(e=>e.trim().toLowerCase()===t.toLowerCase()));if(o<0)return[];let a=r[o].map(e=>e.trim().toLowerCase());return r.slice(o+1).filter(e=>e.some(e=>e.trim())).map(e=>Object.fromEntries(a.map((t,n)=>[t,(e[n]??"").trim()])))},"repliesWaiting",0,function(e){let t=[];for(let[n,r]of e.people){let o=e.asOf-r.last;r.lastFromThem&&o>=2592e5&&o<=2592e6&&t.push({url:n,days:Math.round(o/864e5),total:r.total})}return t.sort((e,t)=>e.days-t.days)},"warmthOf",0,a],84278);let l="six-degrees-galaxy-lab",i="six-degrees-galaxy-layouts",s=Object.freeze({on:!1,gravity:0,rings:1,push:15,pull:1,distance:1,dotSize:1,lines:1,sizeBy:"power",names:"key",branch:!0,colourBy:"tier",speed:15,loop:!1,labels:!0}),d=["gravity","rings","push","pull","distance","dotSize","lines","sizeBy","names","branch","colourBy","speed","loop"],c=Object.freeze({gravity:.25,rings:0,push:25,pull:2.5,distance:.35,sizeBy:"reach"}),u=new Set,p=null;function f(){return p||(p=function(){try{let e=JSON.parse(localStorage.getItem(l)||"null");return e&&"object"==typeof e?{...s,...e}:s}catch{return s}}()),p}function g(e){p=null===e?{...s,on:f().on,labels:f().labels}:{...f(),...e};try{localStorage.setItem(l,JSON.stringify(p))}catch{}u.forEach(e=>e())}let h=null,m=new Set;function y(){if(!h){try{h=JSON.parse(localStorage.getItem(i)||"[]")}catch{h=[]}Array.isArray(h)||(h=[])}return h}function x(e){h=e;try{localStorage.setItem(i,JSON.stringify(e))}catch{}m.forEach(e=>e())}let b=new Set,w={at:null,playing:!1,min:null,max:null,of:0,find:"",fly:0,found:0,social:void 0},v=null;function S(e){let t={...w,...e};Object.keys(e).every(e=>Object.is(t[e],w[e]))||(w=t,b.forEach(e=>e()))}function j(){cancelAnimationFrame(v),v=null,S({playing:!1})}let k=null;function F(e){let n=new Map;for(let[r,o]of Object.entries(e?.people||{}))n.set((0,t.keyFor)({profile_url:r}),{...o});for(let[r,o]of Object.entries(e?.live||{})){let e=(0,t.keyFor)({profile_url:r}),a=n.get(e)||{total:0,recent:0};o.last&&(!a.last||o.last>a.last)&&(a.last=o.last),a.unread=o.unread,a.total=Math.max(a.total||0,1),n.set(e,a)}let r=Math.max(e?.asOf||0,e?.liveAt&&Date.parse(e.liveAt)||0);for(let e of n.values())(e.last||0)>r&&(r=e.last);return{merged:n,asOf:r,chapters:e?.chapters||[],posts:e?.posts?.posts||[]}}let C={1:"#4FC3F7",2:"#BA68C8",3:"#FFB74D"},I=["#FF6B6B","#4ECDC4","#FFD93D","#A29BFE","#00B894","#FD79A8","#74B9FF","#E17055"],T={warm:"#FF7043",cool:"#4FC3F7",dormant:"#8D6E63",never:"#546E7A"},M="#4a5568",B=e=>String(e||"").trim().toLowerCase();e.s(["CLUSTERS",0,c,"LAB_DEFAULTS",0,s,"applyLayout",0,function(e){let t=y().find(t=>t.name===e);t&&g(Object.fromEntries(d.filter(e=>e in t.settings).map(e=>[e,t.settings[e]])))},"bornTimes",0,function(e,t){let n=new Map(e.map(e=>[e.id,e])),r=new Map,o=(e,a=0)=>{if(r.has(e.id))return r.get(e.id);let l=-1/0,i=t.get(e.id);if(1===e.degree||null==i||a>6){let t=e.connected_date?Date.parse(e.connected_date):NaN;l=Number.isNaN(t)?-1/0:t}return null!=i&&n.has(i)&&a<=6&&(l=Math.max(l,o(n.get(i),a+1))),r.set(e.id,l),l};return e.map(e=>o(e))},"chapterAt",0,function(e,t){let n=null;for(let r of e?.chapters||[])Number.isFinite(r.from)&&r.from<=t&&(!n||r.from>n.from)&&(n=r);return n&&(!Number.isFinite(n.to)||n.to>t)?n:null},"clockNow",0,()=>w,"colourScheme",0,function(e,n,r,o){if("degree"===e)return{of:e=>C[Math.min(e.degree||1,3)],legend:[["1st",C[1]],["2nd",C[2]],["3rd+",C[3]]]};if("company"===e){let e=new Map;for(let t of n){let n=B(t.company);if(!n)continue;let r=e.get(n)||{name:String(t.company).trim(),n:0};r.n+=1,e.set(n,r)}let t=[...e.entries()].filter(([,e])=>e.n>1).sort((e,t)=>t[1].n-e[1].n).slice(0,I.length),r=new Map(t.map(([e],t)=>[e,I[t]]));return{of:e=>r.get(B(e.company))||M,legend:[...t.map(([,e],t)=>[e.name,I[t]]),["Other",M]]}}return"warmth"===e&&o?{of:e=>1===(e.degree||1)?T[a(o.merged.get((0,t.keyFor)(e)),o.asOf)]:"#2d3748",legend:[["Warm",T.warm],["Cool",T.cool],["Dormant",T.dormant],["Never messaged",T.never]]}:{of:e=>r[e.tier]||"#666",legend:Object.entries(r)}},"effectiveLab",0,e=>e.on?e:e.labels===s.labels?s:{...s,labels:e.labels},"findMatches",0,function(e,t){let n=String(t||"").trim().toLowerCase();if(n.length<2)return null;let r=new Set;for(let t of e)[t.name,t.company,t.role,t.headline].some(e=>e&&String(e).toLowerCase().includes(n))&&r.add(t.id);return r},"forgetLayout",0,function(e){x(y().filter(t=>t.name!==e))},"labNow",0,f,"layoutsNow",0,y,"loadSocial",0,function(){return k||(k=fetch("/api/social").then(e=>e.ok?e.json():{}).then(e=>{S({social:e.social?F(e.social):null})}).catch(()=>S({social:null}))),k},"mergeSocial",0,F,"milestones",0,function(e){let t=[];for(let n of e?.chapters||[])Number.isFinite(n.from)&&t.push({t:n.from,kind:"job",label:n.company});for(let n of e?.posts||[])Number.isFinite(n.t)&&t.push({t:n.t,kind:"post",label:"You posted"});return t.sort((e,t)=>e.t-t.t)},"pause",0,j,"play",0,function e(){if(null==w.min||null==w.max||w.max<=w.min)return;let t=w.max-w.min,n=1e3*Math.max(1,Number(f().speed)||15),r=null==w.at||w.at>=w.max?w.min:w.at,o=performance.now()-(r-w.min)/t*n;S({at:r,playing:!0});let a=r=>{let l=Math.min(w.max,w.min+(r-o)/n*t);if(S({at:l}),l>=w.max){v=null,S({playing:!1}),f().loop&&setTimeout(()=>{v||w.at!==w.max||(S({at:w.min}),e())},1200);return}v=requestAnimationFrame(a)};cancelAnimationFrame(v),v=requestAnimationFrame(a)},"reachCounts",0,function(e,t){let n=new Map(e.map(e=>[e.id,0]));for(let r of e){let e=t.get(r.id);for(let r=0;null!=e&&r<7;r++)n.set(e,(n.get(e)||0)+1),e=t.get(e)}return n},"saveLayout",0,function(e){let t=String(e||"").trim().slice(0,40);if(!t)return;let n=f(),r=Object.fromEntries(d.map(e=>[e,n[e]]));x([...y().filter(e=>e.name!==t),{name:t,settings:r}])},"setClock",0,S,"setLab",0,g,"stopReplay",0,function(){j(),S({at:null})},"watchClock",0,function(e){return b.add(e),()=>b.delete(e)},"watchLab",0,function(e){u.add(e);let t=t=>{t.key===l&&(p=null,e())};return window.addEventListener("storage",t),()=>{u.delete(e),window.removeEventListener("storage",t)}},"watchLayouts",0,function(e){return m.add(e),()=>m.delete(e)}],39160)},19821,e=>{"use strict";async function t(e){let t=e?`/api/network?userId=${encodeURIComponent(e)}`:"/api/network",n=await fetch(t);if(!n.ok)throw Error(`Failed to load network (${n.status})`);let r=await n.json();return{degree1:r.degree1||[],degree2:r.degree2||[],degree3:r.degree3||[],ties:Number(r.ties)||0}}e.s(["loadNetwork",0,t])},36774,e=>{"use strict";let t=/^[A-Za-z0-9_-]+\.(webp|jpg|jpeg|png)$/,n="/avatars/";e.s(["localPhoto",0,function(e){return"string"==typeof e&&e.startsWith(n)&&t.test(e.slice(n.length))?e:null}])},7214,e=>{"use strict";var t=e.i(36774);let n={S:0,A:1,B:2,C:3,D:4};function r(e){let t=parseFloat(e?.power_score);return Number.isFinite(t)?t:0}function o(e){return Math.round(10*r(e))/10}function a(e){return String(e?.profile_url||"").split(/[?#]/)[0].replace(/\/+$/,"")||`id:${e?.id}`}let l=(e,t)=>String(e??"").localeCompare(String(t??""),void 0,{numeric:!0});function i(e,t){return(n[e.tier]??9)-(n[t.tier]??9)||r(t)-r(e)||String(e.name||"").localeCompare(String(t.name||""))||l(e.id,t.id)}function s(e,t){return e.bridge&&t.bridge?i(e.bridge,t.bridge):e.bridge?-1:t.bridge?1:l(e.id,t.id)}function d(e,t){return t.score-e.score||t.waysIn-e.waysIn||s(e.routes[0]||c,t.routes[0]||c)||String(e.person.name||"").localeCompare(String(t.person.name||""))||(e.key<t.key?-1:+(e.key>t.key))}let c={id:null,bridge:null};function u(e){let t=String(e||"").trim().split(/\s+/).filter(Boolean);return t.length<2?t[0]||"":`${t[0]} ${t[t.length-1].charAt(0)}.`}function p(e,t){let n=String(e||"");return t<=1?n?"…":"":n.length>t?`${n.slice(0,t-1)}…`:n}e.s(["TIERS",0,["S","A","B","C","D"],"compareBridges",0,i,"compareWaysIn",0,function(e,t){return t.waysIn-e.waysIn||d(e,t)},"keyFor",0,a,"routeIndex",0,function(e=[]){let t=new Map;for(let n of e||[]){let e=a(n),r=t.get(e);r||(r=new Set,t.set(e,r)),r.add(n.source_connection_id??null)}return t},"routesFor",0,function(e,t,n){return e?[...t?.get(a(e))??(null!=e.source_connection_id?new Set([e.source_connection_id]):new Set)].map(e=>({id:e,bridge:n?.get(e)??null})).sort(s):[]},"score",0,r,"score1",0,o,"separationPeople",0,function(e=[],n=[]){let r=new Map;for(let e of n||[])r.set(e.id,e);let i=new Map,c=new Map;for(let n of e||[]){let e=a(n);c.set(n.id,e);let r=i.get(e);r?function(e,n){let r=o(e)-o(n);if(r)return r>0;let a=!!(0,t.localPhoto)(e.profile_image_url);return!!(0,t.localPhoto)(n.profile_image_url)!==a?a:0>l(e.id,n.id)}(n,r.person)&&(r.person=n):(r={key:e,person:n,rowIds:[],routeIds:new Set},i.set(e,r)),r.rowIds.push(n.id),r.routeIds.add(n.source_connection_id??null)}let u={people:i.size,byTier:{S:0,A:0,B:0,C:0,D:0},multi:0,bridges:0,unresolvedIds:0,peopleOnlyUnresolved:0,onlyUnresolvedVia:0},p=new Set,f=new Set,g=new Set,h=[];for(let e of i.values()){let t=[...e.routeIds].map(e=>({id:e,bridge:r.get(e)??null}));t.sort(s);let n=t.filter(e=>e.bridge);for(let e of t)(e.bridge?p:f).add(e.id);if(!n.length)for(let e of(u.peopleOnlyUnresolved++,t))g.add(e.id);let{person:a}=e,l=a.tier;void 0!==u.byTier[l]&&u.byTier[l]++,t.length>1&&u.multi++,h.push({key:e.key,person:a,score:o(a),tier:l,routes:t,waysIn:t.length,rowIds:e.rowIds,haystack:[a.name,a.headline,a.company,a.role,...n.map(e=>e.bridge.name)].filter(Boolean).join("\n").toLowerCase(),rank:0,tied:!1})}return u.bridges=p.size,u.unresolvedIds=f.size,u.onlyUnresolvedVia=g.size,h.sort(d),function(e){for(let t=0;t<e.length;t++){let n=e[t],r=e[t-1],o=r&&r.score===n.score&&r.waysIn===n.waysIn;n.rank=o?r.rank:t+1,o&&(n.tied=!0,r.tied=!0)}}(h),{people:h,rowToKey:c,summary:u}},"shortName",0,u,"summitLayout",0,function(e=[],t=800,n=!1){let r=n?36:26,o=Math.round(.42*t),a=Math.round(.58*t),l=e.map((e,n)=>{var o;return{key:e.key,p:e,x:a,y:16+n*r,r:(o=e.waysIn)>=4?8.5:3===o?7:2===o?5.5:4,label:p(`#${e.rank}${e.tied?"=":""} ${e.person.name||""}`,Math.floor((t-a-60)/6.2))}}),s=new Map,d="\0unresolved";for(let e of l)for(let t of e.p.routes){let n=t.bridge?t.id:d,r=s.get(n);r||(r={id:t.bridge?t.id:null,bridge:t.bridge,unresolved:!t.bridge,ys:[],count:0},s.set(n,r)),r.count++,r.ys.push(e.y)}let c=[...s.values()].map(e=>({...e,bary:e.ys.reduce((e,t)=>e+t,0)/e.ys.length}));c.sort((e,t)=>e.bary-t.bary||e.unresolved-t.unresolved||(e.bridge&&t.bridge?i(e.bridge,t.bridge):0));let f=l.length?l[l.length-1].y:16,g=c.length>1?Math.max(18,(f-16)/(c.length-1)):0,h=Math.max(4,Math.floor((o-10-42)/6));c.forEach((e,t)=>{if(e.x=o,e.y=1===c.length?(16+f)/2:16+t*g,e.r=5,e.unresolved)e.label=p(`can't be named (${e.count})`,h);else{let t=e.bridge.name||"";e.label=t.length<=h?t:p(u(t),h)}delete e.ys});let m=new Map(c.map(e=>[e.unresolved?d:e.id,e])),y=[];for(let e of l){let t=new Set;e.p.routes.forEach((n,r)=>{let o=n.bridge?n.id:d;if(t.has(o))return;t.add(o);let a=m.get(o);y.push({key:e.key,bridgeId:a.id,primary:0===r&&!a.unresolved,unresolved:a.unresolved,tier:a.bridge?.tier??null,x1:a.x,y1:a.y,x2:e.x,y2:e.y})})}let x=Math.max(f,c.length?c[c.length-1].y:0),b=l.length?Math.ceil(x+16):0,w={x:20,y:l.length?(16+Math.max(f,x))/2:16,r:14},v=c.map(e=>({id:e.id,x1:w.x,y1:w.y,x2:e.x,y2:e.y}));return{width:t,height:b,you:w,people:l,bridges:c,links:y,spokes:v}}])}]);