six-degrees 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +3 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +41 -13
- package/.next/standalone/.next/routes-manifest.json +12 -0
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +19 -17
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +19 -17
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +15 -13
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/social/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/social/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/social/route.js +8 -0
- package/.next/standalone/.next/server/app/api/social/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/social/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page.js +1 -1
- package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/import.html +1 -1
- package/.next/standalone/.next/server/app/import.rsc +23 -21
- package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +21 -19
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +21 -19
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/launch/page.js +1 -1
- package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/launch.html +2 -2
- package/.next/standalone/.next/server/app/launch.rsc +23 -21
- package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/page.js +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/paths/page.js +1 -1
- package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/paths.html +1 -1
- package/.next/standalone/.next/server/app/paths.rsc +23 -21
- package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/profile/page.js +1 -1
- package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/profile.html +1 -1
- package/.next/standalone/.next/server/app/profile.rsc +23 -21
- package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/queue/page.js +1 -1
- package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/queue.html +1 -1
- package/.next/standalone/.next/server/app/queue.rsc +23 -21
- package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/scores/page.js +1 -1
- package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/scores.html +1 -1
- package/.next/standalone/.next/server/app/scores.rsc +23 -21
- package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/settings/page.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +23 -21
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/setup/page.js +1 -1
- package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +23 -21
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +23 -21
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +17 -15
- package/.next/standalone/.next/server/app/social/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/social/page/build-manifest.json +20 -0
- package/.next/standalone/.next/server/app/social/page/next-font-manifest.json +11 -0
- package/.next/standalone/.next/server/app/social/page/react-loadable-manifest.json +1 -0
- package/.next/standalone/.next/server/app/social/page/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/social/page.js +13 -0
- package/.next/standalone/.next/server/app/social/page.js.map +5 -0
- package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/social.html +1 -0
- package/.next/standalone/.next/server/app/social.meta +26 -0
- package/.next/standalone/.next/server/app/social.rsc +26 -0
- package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +26 -0
- package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +4 -0
- package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +30 -0
- package/.next/standalone/.next/server/app-paths-manifest.json +3 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__17kn1mk._.js +8 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0uag-k5._.js → [root-of-the-server]__1dmc7-t._.js} +1 -1
- package/.next/standalone/.next/server/chunks/_1_fynia._.js +5 -5
- package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1xh07bp._.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_social_route_actions_1_3c6qn.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__16hs8kw._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1feicqq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jeztd-._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_005q9n1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_08_03wh._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_08cfj2b._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0j4-lc3._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0hw_qnj._.js → _0wxbq78._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0xkur4p._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_15x6q32._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_1cyxocj._.js → _1ap1tu_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1mj739k._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_social_page_actions_176i1kl.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +3 -3
- package/.next/standalone/.next/server/chunks/ssr/app_scores_page_09wepvv.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_0i8v-s3._.js +3 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/next-font-manifest.js +1 -1
- package/.next/standalone/.next/server/next-font-manifest.json +4 -0
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/prefetch-hints.json +14 -0
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/04a3zockahetx.js +1 -0
- package/.next/standalone/.next/static/chunks/0a5iadnmt9u9k.js +1 -0
- package/.next/standalone/.next/static/chunks/{2p6o90z0vgcwr.css → 0bo1dxn5gwzpk.css} +1 -1
- package/.next/standalone/.next/static/chunks/0g_p4p7oci18u.js +1 -0
- package/.next/standalone/.next/static/chunks/{0ax_9zzboyv6d.js → 17-rhp8sg4m1b.js} +2 -2
- package/.next/standalone/.next/static/chunks/1ra4cwcp75tfa.js +1 -0
- package/.next/standalone/.next/static/chunks/236f0jtp68j_h.js +1 -0
- package/.next/standalone/.next/static/chunks/24m745q_85u34.js +6 -0
- package/.next/standalone/.next/static/chunks/2_wcobfqry2uj.js +1 -0
- package/.next/standalone/.next/static/chunks/2dwtoszeq91us.js +1 -0
- package/.next/standalone/.next/static/chunks/2hvcevue9aro4.js +1 -0
- package/.next/standalone/.next/static/chunks/2uo9i03_05rqi.js +18 -0
- package/.next/standalone/.next/static/chunks/3p_pwu5gx2i9h.js +1 -0
- package/.next/standalone/.next/static/chunks/3yc3rzp4dxvyo.js +1 -0
- package/.next/standalone/.next/static/chunks/3zw8bv7-mc4n6.js +33 -0
- package/.next/standalone/CHANGELOG.md +63 -0
- package/.next/standalone/app/api/network/route.js +11 -0
- package/.next/standalone/app/api/scraper/route.js +19 -0
- package/.next/standalone/app/api/social/route.js +96 -0
- package/.next/standalone/app/components/AutoScanButton.js +41 -0
- package/.next/standalone/app/components/ChainView.js +7 -0
- package/.next/standalone/app/components/FilterPanel.js +37 -5
- package/.next/standalone/app/components/OrbitGraph.js +17 -4
- package/.next/standalone/app/components/ScanStatusBar.js +96 -0
- package/.next/standalone/app/components/SeparationView.js +9 -1
- package/.next/standalone/app/components/Sidebar.js +88 -26
- package/.next/standalone/app/components/SocialAutoSync.js +34 -0
- package/.next/standalone/app/components/settings/NetworkHealthSection.js +85 -0
- package/.next/standalone/app/globals.css +4 -0
- package/.next/standalone/app/layout.js +6 -0
- package/.next/standalone/app/page.js +37 -4
- package/.next/standalone/app/scores/page.js +3 -0
- package/.next/standalone/app/setup/page.js +13 -1
- package/.next/standalone/app/social/page.js +293 -0
- package/.next/standalone/lib/experimental-client.js +38 -0
- package/.next/standalone/lib/insights.js +54 -0
- package/.next/standalone/lib/linkedin-export.js +156 -0
- package/.next/standalone/lib/network-health.js +42 -0
- package/.next/standalone/lib/network.js +1 -0
- package/.next/standalone/lib/scraper-client.js +1 -0
- package/.next/standalone/package-lock.json +2 -2
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/scrape.py +335 -5
- package/.next/static/chunks/04a3zockahetx.js +1 -0
- package/.next/static/chunks/0a5iadnmt9u9k.js +1 -0
- package/.next/static/chunks/{2p6o90z0vgcwr.css → 0bo1dxn5gwzpk.css} +1 -1
- package/.next/static/chunks/0g_p4p7oci18u.js +1 -0
- package/.next/static/chunks/{0ax_9zzboyv6d.js → 17-rhp8sg4m1b.js} +2 -2
- package/.next/static/chunks/1ra4cwcp75tfa.js +1 -0
- package/.next/static/chunks/236f0jtp68j_h.js +1 -0
- package/.next/static/chunks/24m745q_85u34.js +6 -0
- package/.next/static/chunks/2_wcobfqry2uj.js +1 -0
- package/.next/static/chunks/2dwtoszeq91us.js +1 -0
- package/.next/static/chunks/2hvcevue9aro4.js +1 -0
- package/.next/static/chunks/2uo9i03_05rqi.js +18 -0
- package/.next/static/chunks/3p_pwu5gx2i9h.js +1 -0
- package/.next/static/chunks/3yc3rzp4dxvyo.js +1 -0
- package/.next/static/chunks/3zw8bv7-mc4n6.js +33 -0
- package/CHANGELOG.md +63 -0
- package/lib/experimental-client.js +38 -0
- package/lib/insights.js +54 -0
- package/lib/linkedin-export.js +156 -0
- package/lib/network-health.js +42 -0
- package/lib/network.js +1 -0
- package/lib/scraper-client.js +1 -0
- package/package.json +1 -1
- package/scripts/scrape.py +335 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h1_f_2._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19ip1qq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_06w_gl4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_13kzrwv._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_15xuwkv._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1hgd5dp._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1vpfyd-._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_20w06i-._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/lib_1bn38gs._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_1f8t_rp._.js +0 -23
- package/.next/standalone/.next/static/chunks/049vavjsmqgmn.js +0 -33
- package/.next/standalone/.next/static/chunks/0cuuo2jwc9h94.js +0 -1
- package/.next/standalone/.next/static/chunks/0ljxa-wk_iu__.js +0 -18
- package/.next/standalone/.next/static/chunks/0mp9b72fm-jp6.js +0 -6
- package/.next/standalone/.next/static/chunks/1pre1cotntk6-.js +0 -1
- package/.next/standalone/.next/static/chunks/22x2_r768-u5i.js +0 -1
- package/.next/standalone/.next/static/chunks/28bu26ausqzmn.js +0 -1
- package/.next/standalone/.next/static/chunks/2jz311xl1pp_8.js +0 -1
- package/.next/standalone/.next/static/chunks/2ot61qsv6_0eq.js +0 -1
- package/.next/standalone/.next/static/chunks/2xjho0lroiwlq.js +0 -1
- package/.next/standalone/.next/static/chunks/3zs_6-nn0dapb.js +0 -1
- package/.next/static/chunks/049vavjsmqgmn.js +0 -33
- package/.next/static/chunks/0cuuo2jwc9h94.js +0 -1
- package/.next/static/chunks/0ljxa-wk_iu__.js +0 -18
- package/.next/static/chunks/0mp9b72fm-jp6.js +0 -6
- package/.next/static/chunks/1pre1cotntk6-.js +0 -1
- package/.next/static/chunks/22x2_r768-u5i.js +0 -1
- package/.next/static/chunks/28bu26ausqzmn.js +0 -1
- package/.next/static/chunks/2jz311xl1pp_8.js +0 -1
- package/.next/static/chunks/2ot61qsv6_0eq.js +0 -1
- package/.next/static/chunks/2xjho0lroiwlq.js +0 -1
- package/.next/static/chunks/3zs_6-nn0dapb.js +0 -1
- /package/.next/standalone/.next/static/{wGVrXBkFLmEB4snfhtOcO → VE8LeJXfD2H0_OgJxuJcm}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{wGVrXBkFLmEB4snfhtOcO → VE8LeJXfD2H0_OgJxuJcm}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{wGVrXBkFLmEB4snfhtOcO → VE8LeJXfD2H0_OgJxuJcm}/_ssgManifest.js +0 -0
- /package/.next/static/{wGVrXBkFLmEB4snfhtOcO → VE8LeJXfD2H0_OgJxuJcm}/_buildManifest.js +0 -0
- /package/.next/static/{wGVrXBkFLmEB4snfhtOcO → VE8LeJXfD2H0_OgJxuJcm}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{wGVrXBkFLmEB4snfhtOcO → VE8LeJXfD2H0_OgJxuJcm}/_ssgManifest.js +0 -0
package/scripts/scrape.py
CHANGED
|
@@ -27,11 +27,12 @@ in one session — LinkedIn detects automation and flags your account.
|
|
|
27
27
|
import argparse
|
|
28
28
|
import json
|
|
29
29
|
import os
|
|
30
|
+
import re
|
|
30
31
|
import signal
|
|
31
32
|
import sys
|
|
32
33
|
import time
|
|
33
34
|
import requests
|
|
34
|
-
from datetime import datetime
|
|
35
|
+
from datetime import datetime, timedelta
|
|
35
36
|
from pathlib import Path
|
|
36
37
|
from urllib.parse import parse_qs, urlparse
|
|
37
38
|
|
|
@@ -57,6 +58,8 @@ _ENV_LOCAL = _load_env_local()
|
|
|
57
58
|
# default to somebody else's deployment — that would send a user's network to
|
|
58
59
|
# a server they don't control.
|
|
59
60
|
APP_URL = os.getenv("APP_URL", "http://localhost:3000")
|
|
61
|
+
MESSAGING_URL = "https://www.linkedin.com/messaging/"
|
|
62
|
+
MESSAGE_SCROLLS = 6 # scrolls down the conversation list, a few seconds apart
|
|
60
63
|
|
|
61
64
|
CONNECTIONS_URL = "https://www.linkedin.com/mynetwork/invite-connect/connections/"
|
|
62
65
|
|
|
@@ -1274,6 +1277,17 @@ PAGE_PAUSE = 20 # seconds before each next page of results
|
|
|
1274
1277
|
CHUNK_COOLDOWN = 60 # extra seconds after every SAVE_EVERY_PAGES pages
|
|
1275
1278
|
LEGACY_PAGES_READ = 10 # how far every read before 0.1.6 went, at most
|
|
1276
1279
|
|
|
1280
|
+
# Experimental all-day pacing for Auto-Bridge (--experimental; item 44, Graph
|
|
1281
|
+
# Study §8). Openly slow, never disguised: fixed waits, no random "human" timing.
|
|
1282
|
+
# A sitting of SESSION_PAGES searches, then a long rest; searches only in the
|
|
1283
|
+
# daytime on this computer's clock; and at the daily budget it waits for the
|
|
1284
|
+
# budget to free up instead of stopping. Pages are saved one at a time.
|
|
1285
|
+
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
|
|
1289
|
+
WIRE_SAMPLES = 5 # raw LinkedIn responses kept per run, for research
|
|
1290
|
+
|
|
1277
1291
|
|
|
1278
1292
|
# Someone whose connections are hidden can never produce a 2nd-degree row. The
|
|
1279
1293
|
# "who still needs bridging" query is "everyone with no 2nd-degree rows", so
|
|
@@ -1787,6 +1801,303 @@ def stop_requested():
|
|
|
1787
1801
|
return _stop_requested
|
|
1788
1802
|
|
|
1789
1803
|
|
|
1804
|
+
# LinkedIn's own data (experimental, with --experimental). While a circle is
|
|
1805
|
+
# read, the responses the browser already gets from LinkedIn's own API are kept
|
|
1806
|
+
# and read for the same people the page shows: the same traffic, no extra
|
|
1807
|
+
# requests. The page text stays in charge. This fills blanks for people both
|
|
1808
|
+
# found and gives the list's real total; people only in LinkedIn's data are
|
|
1809
|
+
# logged, not added, since a results page can carry other boxes ("People you
|
|
1810
|
+
# may know"). Each page logs how the two compare, and a few raw responses are
|
|
1811
|
+
# kept in the data folder (wire-samples/) to tune it from real ones.
|
|
1812
|
+
_WIRE = {"page": None, "responses": []}
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
def _wire_tap(page):
|
|
1816
|
+
if _WIRE["page"] is page:
|
|
1817
|
+
return
|
|
1818
|
+
_WIRE["page"], _WIRE["responses"] = page, []
|
|
1819
|
+
|
|
1820
|
+
def keep(response):
|
|
1821
|
+
url = response.url
|
|
1822
|
+
if "/voyager/api/" in url and ("search" in url.lower() or "graphql" in url):
|
|
1823
|
+
_WIRE["responses"].append(response)
|
|
1824
|
+
page.on("response", keep)
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
def mutual_count_text(text):
|
|
1828
|
+
"""LinkedIn's mutual line as a number, as the page reader's mutualCount reads it; None otherwise."""
|
|
1829
|
+
line = re.sub(r"\s+", " ", str(text or "")).strip()
|
|
1830
|
+
if not re.search(r"\bmutual connections?$", line, re.I) or len(line) > 300:
|
|
1831
|
+
return None
|
|
1832
|
+
num = lambda v: int(str(v).replace(",", ""))
|
|
1833
|
+
names = lambda v: len([p for p in re.split(r"\s*,\s*|\s+and\s+", v) if p])
|
|
1834
|
+
m = re.match(r"^([\d,]+) mutual connections?$", line, re.I)
|
|
1835
|
+
if m:
|
|
1836
|
+
return num(m.group(1))
|
|
1837
|
+
m = re.match(r"^(.*?)\s*\band ([\d,]+) others? mutual connections?$", line, re.I)
|
|
1838
|
+
if m:
|
|
1839
|
+
return max(1, names(m.group(1))) + num(m.group(2))
|
|
1840
|
+
if re.search(r"\bis a mutual connection$", line, re.I):
|
|
1841
|
+
return 1
|
|
1842
|
+
m = re.match(r"^(.+?)\s+are mutual connections$", line, re.I)
|
|
1843
|
+
return names(m.group(1)) if m else None
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
def voyager_people(payload):
|
|
1847
|
+
"""Everyone in a LinkedIn API response who looks like a search result: anything with a
|
|
1848
|
+
title and a link to a profile, wherever it sits in the response."""
|
|
1849
|
+
out, seen = [], set()
|
|
1850
|
+
text = lambda v: (v.get("text") if isinstance(v, dict) else v if isinstance(v, str) else "") or ""
|
|
1851
|
+
|
|
1852
|
+
def photo(x):
|
|
1853
|
+
try:
|
|
1854
|
+
for a in (x.get("image") or {}).get("attributes") or []:
|
|
1855
|
+
vi = ((a.get("detailData") or {}).get("nonEntityProfilePicture") or {}).get("vectorImage") or a.get("vectorImage")
|
|
1856
|
+
if vi and vi.get("rootUrl") and vi.get("artifacts"):
|
|
1857
|
+
best = max(vi["artifacts"], key=lambda f: f.get("width") or 0)
|
|
1858
|
+
return vi["rootUrl"] + (best.get("fileIdentifyingUrlPathSegment") or "")
|
|
1859
|
+
except Exception:
|
|
1860
|
+
pass
|
|
1861
|
+
return ""
|
|
1862
|
+
|
|
1863
|
+
def walk(x):
|
|
1864
|
+
if isinstance(x, dict):
|
|
1865
|
+
nav = x.get("navigationUrl")
|
|
1866
|
+
if isinstance(nav, str) and "/in/" in nav and isinstance(x.get("title"), dict):
|
|
1867
|
+
url = nav.split("?")[0].split("#")[0].rstrip("/") + "/"
|
|
1868
|
+
name = text(x.get("title")).strip()
|
|
1869
|
+
if name and name != "LinkedIn Member" and url not in seen:
|
|
1870
|
+
seen.add(url)
|
|
1871
|
+
mutual = None
|
|
1872
|
+
for ins in x.get("insightsResolutionResults") or []:
|
|
1873
|
+
mutual = mutual_count_text(text(((ins or {}).get("simpleInsight") or {}).get("title")))
|
|
1874
|
+
if mutual:
|
|
1875
|
+
break
|
|
1876
|
+
out.append({"name": name, "headline": text(x.get("primarySubtitle")).strip(),
|
|
1877
|
+
"profileUrl": url, "imageUrl": photo(x), "mutualCount": mutual})
|
|
1878
|
+
for v in x.values():
|
|
1879
|
+
walk(v)
|
|
1880
|
+
elif isinstance(x, list):
|
|
1881
|
+
for v in x:
|
|
1882
|
+
walk(v)
|
|
1883
|
+
walk(payload)
|
|
1884
|
+
return out
|
|
1885
|
+
|
|
1886
|
+
|
|
1887
|
+
def voyager_total(payload):
|
|
1888
|
+
"""The list's length, when a response says it (totalResultCount); None otherwise."""
|
|
1889
|
+
stack = [payload]
|
|
1890
|
+
while stack:
|
|
1891
|
+
x = stack.pop()
|
|
1892
|
+
if isinstance(x, dict):
|
|
1893
|
+
v = x.get("totalResultCount")
|
|
1894
|
+
if isinstance(v, int) and v > 0:
|
|
1895
|
+
return v
|
|
1896
|
+
stack.extend(x.values())
|
|
1897
|
+
elif isinstance(x, list):
|
|
1898
|
+
stack.extend(x)
|
|
1899
|
+
return None
|
|
1900
|
+
|
|
1901
|
+
|
|
1902
|
+
def _wire_sample(data, prefix="search"):
|
|
1903
|
+
if EXPERIMENT["wire"] >= WIRE_SAMPLES:
|
|
1904
|
+
return
|
|
1905
|
+
try:
|
|
1906
|
+
raw = json.dumps(data)
|
|
1907
|
+
if len(raw) > 500_000:
|
|
1908
|
+
return
|
|
1909
|
+
folder = _home() / "wire-samples"
|
|
1910
|
+
folder.mkdir(parents=True, exist_ok=True)
|
|
1911
|
+
(folder / f"{prefix}-{int(time.time() * 1000)}.json").write_text(raw)
|
|
1912
|
+
EXPERIMENT["wire"] += 1
|
|
1913
|
+
except Exception:
|
|
1914
|
+
pass
|
|
1915
|
+
|
|
1916
|
+
|
|
1917
|
+
def _wire_merge(page, profile_url, page_results):
|
|
1918
|
+
"""Fill blanks in this page's people from LinkedIn's own data, and log how the two compare."""
|
|
1919
|
+
got, _WIRE["responses"] = _WIRE["responses"], []
|
|
1920
|
+
people, total = [], None
|
|
1921
|
+
for response in got:
|
|
1922
|
+
try:
|
|
1923
|
+
data = response.json()
|
|
1924
|
+
except Exception:
|
|
1925
|
+
continue
|
|
1926
|
+
_wire_sample(data)
|
|
1927
|
+
people.extend(voyager_people(data))
|
|
1928
|
+
total = total or voyager_total(data)
|
|
1929
|
+
if total:
|
|
1930
|
+
_LIST_TOTALS[profile_url] = int(total)
|
|
1931
|
+
own = (profile_url or "").rstrip("/").split("/")[-1]
|
|
1932
|
+
by_url = {c.get("profileUrl"): c for c in page_results}
|
|
1933
|
+
only_wire = 0
|
|
1934
|
+
for w in people:
|
|
1935
|
+
if own and own in w["profileUrl"]:
|
|
1936
|
+
continue
|
|
1937
|
+
c = by_url.get(w["profileUrl"])
|
|
1938
|
+
if c is None:
|
|
1939
|
+
only_wire += 1
|
|
1940
|
+
continue
|
|
1941
|
+
for k in ("name", "headline", "imageUrl"):
|
|
1942
|
+
if not c.get(k) and w.get(k):
|
|
1943
|
+
c[k] = w[k]
|
|
1944
|
+
if c.get("mutualCount") is None and w.get("mutualCount") is not None:
|
|
1945
|
+
c["mutualCount"] = w["mutualCount"]
|
|
1946
|
+
print(f" LinkedIn's own data: {len(people)} people, {only_wire} not in the page text"
|
|
1947
|
+
+ (f", list of about {total:,}" if total else ""), flush=True)
|
|
1948
|
+
return page_results
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
_PROFILE_LINK = re.compile(r"https://www\\.linkedin\\.com/in/[^/?#\\s\"']+")
|
|
1952
|
+
|
|
1953
|
+
|
|
1954
|
+
def voyager_conversations(payload):
|
|
1955
|
+
"""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."""
|
|
1958
|
+
out = []
|
|
1959
|
+
|
|
1960
|
+
def people(x):
|
|
1961
|
+
found = set()
|
|
1962
|
+
stack = [x]
|
|
1963
|
+
while stack:
|
|
1964
|
+
v = stack.pop()
|
|
1965
|
+
if isinstance(v, dict):
|
|
1966
|
+
pid = v.get("publicIdentifier")
|
|
1967
|
+
if isinstance(pid, str) and pid and pid != "UNKNOWN":
|
|
1968
|
+
found.add(f"https://www.linkedin.com/in/{pid}/")
|
|
1969
|
+
stack.extend(v.values())
|
|
1970
|
+
elif isinstance(v, list):
|
|
1971
|
+
stack.extend(v)
|
|
1972
|
+
elif isinstance(v, str):
|
|
1973
|
+
for m in _PROFILE_LINK.findall(v):
|
|
1974
|
+
found.add(m.rstrip("/") + "/")
|
|
1975
|
+
return found
|
|
1976
|
+
|
|
1977
|
+
def walk(x):
|
|
1978
|
+
if isinstance(x, dict):
|
|
1979
|
+
at = x.get("lastActivityAt")
|
|
1980
|
+
parts = [v for k, v in x.items() if "participant" in k.lower()]
|
|
1981
|
+
if isinstance(at, (int, float)) and at > 1e12 and parts:
|
|
1982
|
+
who = set()
|
|
1983
|
+
for v in parts:
|
|
1984
|
+
who |= people(v)
|
|
1985
|
+
if who:
|
|
1986
|
+
unread = x.get("unreadCount")
|
|
1987
|
+
out.append({"people": sorted(who), "at": int(at), "unread": int(unread) if isinstance(unread, (int, float)) else None})
|
|
1988
|
+
for v in x.values():
|
|
1989
|
+
walk(v)
|
|
1990
|
+
elif isinstance(x, list):
|
|
1991
|
+
for v in x:
|
|
1992
|
+
walk(v)
|
|
1993
|
+
walk(payload)
|
|
1994
|
+
return out
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
def sync_messages(headless=False):
|
|
1998
|
+
"""Experimental: read your LinkedIn messages list once, for the Social tab. Opens
|
|
1999
|
+
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."""
|
|
2002
|
+
from playwright.sync_api import sync_playwright
|
|
2003
|
+
kept = []
|
|
2004
|
+
with sync_playwright() as p:
|
|
2005
|
+
browser = p.chromium.launch_persistent_context(
|
|
2006
|
+
user_data_dir=get_scraper_profile_path(), headless=headless, channel="chrome",
|
|
2007
|
+
args=["--disable-blink-features=AutomationControlled"], timeout=120000)
|
|
2008
|
+
page = browser.pages[0] if browser.pages else browser.new_page()
|
|
2009
|
+
page.set_default_timeout(120000)
|
|
2010
|
+
if not ensure_logged_in(page):
|
|
2011
|
+
browser.close()
|
|
2012
|
+
return
|
|
2013
|
+
page.on("response", lambda r: kept.append(r) if "/voyager/api/" in r.url and "messag" in r.url.lower() else None)
|
|
2014
|
+
print("Opening your messages list...")
|
|
2015
|
+
try:
|
|
2016
|
+
page.goto(MESSAGING_URL, wait_until="domcontentloaded")
|
|
2017
|
+
except Exception:
|
|
2018
|
+
pass
|
|
2019
|
+
time.sleep(6)
|
|
2020
|
+
for i in range(MESSAGE_SCROLLS):
|
|
2021
|
+
if stop_requested() or _window_closed(page):
|
|
2022
|
+
break
|
|
2023
|
+
try:
|
|
2024
|
+
page.evaluate("""() => { const l = document.querySelector('.msg-conversations-container__conversations-list, [class*="conversations-list"]');
|
|
2025
|
+
if (l) l.scrollTop = l.scrollHeight; }""")
|
|
2026
|
+
except Exception:
|
|
2027
|
+
pass
|
|
2028
|
+
print(f" Reading the list ({i + 1} of {MESSAGE_SCROLLS})...", flush=True)
|
|
2029
|
+
time.sleep(4)
|
|
2030
|
+
convos = []
|
|
2031
|
+
for r in kept:
|
|
2032
|
+
try:
|
|
2033
|
+
data = r.json()
|
|
2034
|
+
except Exception:
|
|
2035
|
+
continue
|
|
2036
|
+
_wire_sample(data, prefix="messages")
|
|
2037
|
+
convos.extend(voyager_conversations(data))
|
|
2038
|
+
browser.close()
|
|
2039
|
+
# You are the one in the most conversations; keep the 1:1 ones.
|
|
2040
|
+
counts = {}
|
|
2041
|
+
for c in convos:
|
|
2042
|
+
for u in c["people"]:
|
|
2043
|
+
counts[u] = counts.get(u, 0) + 1
|
|
2044
|
+
me = max(counts, key=counts.get) if counts else None
|
|
2045
|
+
people = {}
|
|
2046
|
+
for c in convos:
|
|
2047
|
+
others = [u for u in c["people"] if u != me]
|
|
2048
|
+
if len(others) != 1:
|
|
2049
|
+
continue
|
|
2050
|
+
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}")
|
|
2059
|
+
|
|
2060
|
+
|
|
2061
|
+
def _drip_wait(label, seconds):
|
|
2062
|
+
"""Wait `seconds` for an experimental rest, saying when it ends, a line a minute. False if stopped."""
|
|
2063
|
+
seconds = max(1, int(seconds))
|
|
2064
|
+
until = datetime.fromtimestamp(time.time() + seconds).strftime("%H:%M")
|
|
2065
|
+
print(f" {label}. Carrying on at {until}.", flush=True)
|
|
2066
|
+
return interruptible_sleep(seconds, on_tick=lambda left: print(f" {label}: {max(1, left // 60)} min to go", flush=True), step=60)
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
def _seconds_until_search_frees(now=None):
|
|
2070
|
+
"""How long until the oldest search in the last 24 hours drops out of the daily budget."""
|
|
2071
|
+
now = now if now is not None else time.time()
|
|
2072
|
+
recent = sorted(t for t in _read_activity()["searches"] if now - DAY_SECONDS < t <= now)
|
|
2073
|
+
return (recent[0] + DAY_SECONDS - now + 5) if recent else 5
|
|
2074
|
+
|
|
2075
|
+
|
|
2076
|
+
def _drip_before_search():
|
|
2077
|
+
"""Experimental pacing, before a search: rest after a sitting, sleep through the
|
|
2078
|
+
night, and wait for a used daily budget to free up. True to go ahead, False if stopped."""
|
|
2079
|
+
while True:
|
|
2080
|
+
if EXPERIMENT["pages"] >= SESSION_PAGES:
|
|
2081
|
+
EXPERIMENT["pages"] = 0
|
|
2082
|
+
if not _drip_wait(f"Resting after {SESSION_PAGES} pages", SESSION_REST):
|
|
2083
|
+
return False
|
|
2084
|
+
continue
|
|
2085
|
+
now = datetime.fromtimestamp(time.time())
|
|
2086
|
+
if not (DRIP_HOURS[0] <= now.hour < DRIP_HOURS[1]):
|
|
2087
|
+
start = now.replace(hour=DRIP_HOURS[0], minute=0, second=0, microsecond=0)
|
|
2088
|
+
if now.hour >= DRIP_HOURS[1]:
|
|
2089
|
+
start += timedelta(days=1)
|
|
2090
|
+
if not _drip_wait("Resting overnight", (start - now).total_seconds()):
|
|
2091
|
+
return False
|
|
2092
|
+
continue
|
|
2093
|
+
left, kind = searches_left()
|
|
2094
|
+
if left <= 0 and kind == "daily":
|
|
2095
|
+
if not _drip_wait("Today's searches are used", _seconds_until_search_frees()):
|
|
2096
|
+
return False
|
|
2097
|
+
continue
|
|
2098
|
+
return True
|
|
2099
|
+
|
|
2100
|
+
|
|
1790
2101
|
def interruptible_sleep(seconds, on_tick=None, step=5):
|
|
1791
2102
|
"""Sleep, but notice a stop request. Returns False if we were interrupted."""
|
|
1792
2103
|
waited = 0
|
|
@@ -2402,6 +2713,12 @@ def _scrape_one_bridge(page, bridge_name, bridge_id, profile_url, max_pages=LINK
|
|
|
2402
2713
|
# 1st, 2nd and 3rd+ — all of them; the app drops your own connections when
|
|
2403
2714
|
# it saves. It used to be announced as a "3rd+ filter", which it never was.
|
|
2404
2715
|
search_url = f"https://www.linkedin.com/search/results/people/?network=%5B%22F%22%2C%22S%22%2C%22O%22%5D&connectionOf=%5B%22{urn}%22%5D"
|
|
2716
|
+
if EXPERIMENT["on"] and not _drip_before_search():
|
|
2717
|
+
reach["more"] = True
|
|
2718
|
+
print(" Stopped before their list opened; the next run carries on from there.")
|
|
2719
|
+
return [], "stopped", reach
|
|
2720
|
+
if EXPERIMENT["on"]:
|
|
2721
|
+
_wire_tap(page)
|
|
2405
2722
|
left, kind = searches_left()
|
|
2406
2723
|
if left <= 0:
|
|
2407
2724
|
reach["budget"] = kind
|
|
@@ -2547,6 +2864,9 @@ def _scrape_one_bridge(page, bridge_name, bridge_id, profile_url, max_pages=LINK
|
|
|
2547
2864
|
break
|
|
2548
2865
|
|
|
2549
2866
|
page_results = [c for c in page_results if slug not in c.get("profileUrl", "")]
|
|
2867
|
+
if EXPERIMENT["on"]:
|
|
2868
|
+
page_results = _wire_merge(page, profile_url, page_results)
|
|
2869
|
+
EXPERIMENT["pages"] += 1
|
|
2550
2870
|
chunk.extend(page_results)
|
|
2551
2871
|
chunk_pages += 1
|
|
2552
2872
|
reach["last"] = pg
|
|
@@ -2569,7 +2889,7 @@ def _scrape_one_bridge(page, bridge_name, bridge_id, profile_url, max_pages=LINK
|
|
|
2569
2889
|
# own path: through the page-limit branch, a missing Next button would
|
|
2570
2890
|
# have marked the list finished.
|
|
2571
2891
|
left, kind = searches_left()
|
|
2572
|
-
if left <= 0:
|
|
2892
|
+
if left <= 0 and not (EXPERIMENT["on"] and kind == "daily"):
|
|
2573
2893
|
# Looking for Next costs nothing. No Next on a live page of results
|
|
2574
2894
|
# means the list is finished — not paused at the next page forever.
|
|
2575
2895
|
if _find_next(page) is None and not _window_closed(page) and _result_links(page):
|
|
@@ -2582,10 +2902,10 @@ def _scrape_one_bridge(page, bridge_name, bridge_id, profile_url, max_pages=LINK
|
|
|
2582
2902
|
|
|
2583
2903
|
# Rest before the next search, and longer after every SAVE_EVERY_PAGES.
|
|
2584
2904
|
rest = PAGE_PAUSE
|
|
2585
|
-
if (pg - start_page + 1) % SAVE_EVERY_PAGES == 0:
|
|
2905
|
+
if not EXPERIMENT["on"] and (pg - start_page + 1) % SAVE_EVERY_PAGES == 0:
|
|
2586
2906
|
rest += CHUNK_COOLDOWN
|
|
2587
2907
|
print(f" {SAVE_EVERY_PAGES} pages read; resting {rest}s before the next search.")
|
|
2588
|
-
if not interruptible_sleep(rest) or _window_closed(page):
|
|
2908
|
+
if not interruptible_sleep(rest) or _window_closed(page) or (EXPERIMENT["on"] and not _drip_before_search()):
|
|
2589
2909
|
reach["more"] = True
|
|
2590
2910
|
print(f" Stopped before page {pg + 1}; the next run carries on from there.")
|
|
2591
2911
|
break
|
|
@@ -2610,7 +2930,7 @@ def _scrape_one_bridge(page, bridge_name, bridge_id, profile_url, max_pages=LINK
|
|
|
2610
2930
|
|
|
2611
2931
|
# Save as it goes, so a stop, a crash or the search limit costs at most
|
|
2612
2932
|
# the last few pages rather than the whole list.
|
|
2613
|
-
if on_save and chunk_pages >= SAVE_EVERY_PAGES:
|
|
2933
|
+
if on_save and chunk_pages >= (1 if EXPERIMENT["on"] else SAVE_EVERY_PAGES):
|
|
2614
2934
|
on_save(_dedupe(chunk), reach["last"], True, reach["urn"])
|
|
2615
2935
|
chunk, chunk_pages = [], 0
|
|
2616
2936
|
|
|
@@ -3752,6 +4072,11 @@ Examples:
|
|
|
3752
4072
|
parser.add_argument("--bridge", type=str, help="Name of one bridge person to scrape")
|
|
3753
4073
|
parser.add_argument("--rescrape", type=str, help="Delete + re-scrape a bridge's cluster from scratch")
|
|
3754
4074
|
parser.add_argument("--company", type=str, help="Scan everyone the app can see at one company")
|
|
4075
|
+
parser.add_argument("--messages", action="store_true",
|
|
4076
|
+
help="Experimental: read your messages list once for the Social tab (who, when, unread; never text)")
|
|
4077
|
+
parser.add_argument("--experimental", action="store_true",
|
|
4078
|
+
help="Auto-Bridge, experimental: all-day pacing (sittings, rests, daytime only, "
|
|
4079
|
+
"waits for the daily budget) and reading LinkedIn's own data beside the page text")
|
|
3755
4080
|
parser.add_argument("--auto-bridge", action="store_true",
|
|
3756
4081
|
help="Map every bridge in turn, highest tier first")
|
|
3757
4082
|
parser.add_argument("--retry-private", action="store_true",
|
|
@@ -3783,6 +4108,9 @@ Examples:
|
|
|
3783
4108
|
"(every scan also does this at its end)")
|
|
3784
4109
|
parser.add_argument("--headless", action="store_true", help="Run browser in headless mode")
|
|
3785
4110
|
args = parser.parse_args()
|
|
4111
|
+
if getattr(args, "experimental", False):
|
|
4112
|
+
EXPERIMENT["on"] = True
|
|
4113
|
+
print("Experimental Auto-Bridge: all-day pacing, and LinkedIn's own data read beside the page text.")
|
|
3786
4114
|
args.max_pages = max(1, min(LINKEDIN_MAX_PAGES, args.max_pages))
|
|
3787
4115
|
|
|
3788
4116
|
# A failed save ends the run with its reason, not a traceback (TRAPS §32).
|
|
@@ -3843,6 +4171,8 @@ Examples:
|
|
|
3843
4171
|
only_unfinished=args.only_unfinished)
|
|
3844
4172
|
done = sum(1 for r in results if r.get("status") == "done")
|
|
3845
4173
|
print(f"\nDone. {done}/{len(results)} bridges mapped.")
|
|
4174
|
+
elif args.messages:
|
|
4175
|
+
sync_messages(headless=args.headless)
|
|
3846
4176
|
elif args.search:
|
|
3847
4177
|
scrape_full(headless=args.headless)
|
|
3848
4178
|
elif args.full:
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
module.exports=[9272,a=>{a.v({className:"geist_2ae47f08-module__h69qWW__className",variable:"geist_2ae47f08-module__h69qWW__variable"})},79474,a=>{a.v({className:"geist_mono_eb58308d-module__w_p2Lq__className",variable:"geist_mono_eb58308d-module__w_p2Lq__variable"})},61143,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/app/components/StaleServerBanner.js from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/StaleServerBanner.js","default")},42041,a=>{"use strict";var b=a.i(61143);a.n(b)},62925,a=>{"use strict";var b=a.i(7997),c=a.i(9272);let d={className:c.default.className,style:{fontFamily:"'Geist', 'Geist Fallback'",fontStyle:"normal"}};null!=c.default.variable&&(d.variable=c.default.variable);var e=a.i(79474);let f={className:e.default.className,style:{fontFamily:"'Geist Mono', 'Geist Mono Fallback'",fontStyle:"normal"}};null!=e.default.variable&&(f.variable=e.default.variable);var g=a.i(68354),h=a.i(42041);a.s(["default",0,function({children:a}){return(0,b.jsx)("html",{lang:"en",className:`${d.variable} ${f.variable}`,children:(0,b.jsx)("body",{style:{margin:0,padding:0,background:"#0a0a1a"},children:(0,b.jsxs)(g.default,{children:[a,(0,b.jsx)(h.default,{})]})})})},"metadata",0,{title:"Six Degrees",description:"Maps your LinkedIn network: who you know, who they know, and the shortest path to someone you haven't met. Runs on your own computer; nothing is uploaded.",viewport:"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}],62925)},19325,function(a){a.n(a.i(62925))},69067,a=>{"use strict";a.s(["default",()=>c,"useUser",()=>d]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/app/components/UserProvider.js from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/UserProvider.js","default"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call useUser() from the server but useUser is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/UserProvider.js","useUser")},68354,a=>{"use strict";var b=a.i(69067);a.n(b)}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%5D__0h1_f_2._.js.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
module.exports=[18622,(a,b,c)=>{b.exports=a.x("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js",()=>require("next/dist/compiled/next-server/app-page-turbo.runtime.prod.js"))},20635,(a,b,c)=>{b.exports=a.x("next/dist/server/app-render/action-async-storage.external.js",()=>require("next/dist/server/app-render/action-async-storage.external.js"))},24725,(a,b,c)=>{b.exports=a.x("next/dist/server/app-render/after-task-async-storage.external.js",()=>require("next/dist/server/app-render/after-task-async-storage.external.js"))},43285,(a,b,c)=>{b.exports=a.x("next/dist/server/app-render/dynamic-access-async-storage.external.js",()=>require("next/dist/server/app-render/dynamic-access-async-storage.external.js"))},56704,(a,b,c)=>{b.exports=a.x("next/dist/server/app-render/work-async-storage.external.js",()=>require("next/dist/server/app-render/work-async-storage.external.js"))},32319,(a,b,c)=>{b.exports=a.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,(a,b,c)=>{b.exports=a.x("next/dist/server/runtime-reacts.external.js",()=>require("next/dist/server/runtime-reacts.external.js"))},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,58834,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(73167),e=a.i(42510);let f="true"===process.env.NEXT_PUBLIC_DEMO_MODE,g={id:"synthetic-demo-user",name:"You",headline:"Sample network"},h=null;async function i(){if(h)return h;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 h={degree1:b.degree1||[],degree2:b.degree2||[]}}async function j(){let a=await i();return(0,e.saveSessionNetwork)({degree1:a.degree1,degree2:a.degree2,source:"sample"}),{degree1:a.degree1.length,degree2:a.degree2.length}}a.s(["DEMO_USER",0,g,"IS_DEMO",0,f,"loadDemoNetwork",0,i,"loadSampleIntoSession",0,j],58834);let k=(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,l]=(0,c.useState)(null),[m,n]=(0,c.useState)(null),[o,p]=(0,c.useState)(!1);return(0,c.useEffect)(()=>{if(f){i(g.id),l(g.name),n({name:g.name,headline:g.headline,role:"",company:"",industry:"",sectors:[],goals:[],linkedin_url:""}),p(!0);return}if((0,e.hasCsvNetwork)()){i(e.CSV_USER.id),l(e.CSV_USER.name),n({name:e.CSV_USER.name,headline:"Imported from your LinkedIn CSV",role:"",company:"",industry:"",sectors:[],goals:[],linkedin_url:""}),p(!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),l(b.name),n({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)()),l((0,d.getUserName)()))}).finally(()=>p(!0))},[]),(0,b.jsx)(k.Provider,{value:{userId:h,userName:j,userProfile:m,ready:o,login:(a,b)=>{(0,d.setUser)(a,b),i(a),l(b),fetch(`/api/users?id=${a}`).then(a=>a.json()).then(a=>{a.user&&n({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)(k)}],75857)},42602,(a,b,c)=>{"use strict";b.exports=a.r(18622)},9270,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored.contexts.AppRouterContext},36313,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored.contexts.HooksClientContext},18341,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored.contexts.ServerInsertedHtml},35112,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored["react-ssr"].ReactDOM},87924,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored["react-ssr"].ReactJsxRuntime},38783,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored["react-ssr"].ReactServerDOMTurbopackClient},72131,(a,b,c)=>{"use strict";b.exports=a.r(42602).vendored["react-ssr"].React}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%5D__19ip1qq._.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]})}])},9282,a=>{"use strict";var b=a.i(30889);function c(a){let c=(0,b.readTitle)(a);return{key:c.key,label:c.label,level:c.level}}function d(a){return(0,b.currentCompany)(a)}let e=[{key:"defense",label:"Government, Defense & Aerospace",color:"#7f8c8d",words:/\b(government|federal|state of|county|city of|defen[cs]e|army|navy|air force|marine corps|military|dod|nasa|aerospace|lockheed|northrop|boeing|raytheon|l3harris|leidos|blue origin|spacex|public sector)\b/i},{key:"finance",label:"Finance & Investing",color:"#2ecc71",words:/\b(bank|banking|capital|ventures?|vc|investments?|investor|fund|private equity|growth equity|asset management|wealth|trading|trader|hedge|crypto|blockchain|web3|defi|fintech|stripe|coinbase|blackrock|robinhood|goldman|morgan stanley|jpmorgan|chase|bny|mellon|wells fargo|citi|citigroup|capital one|fidelity|vanguard|schwab|visa|mastercard|amex|american express|paypal|insurance|accounting|cpa|financial)\b/i},{key:"health",label:"Healthcare & Biotech",color:"#e74c3c",words:/\b(health|healthcare|medical|medicine|hospital|clinic|pharma|pharmaceutical|biotech|nurse|nursing|physician|doctor|dental|therapy|therapist|wellness)\b/i},{key:"education",label:"Education",color:"#f1c40f",words:/\b(university|college|school|education|student|professor|teacher|academy|phd|faculty|alumni)\b/i},{key:"media",label:"Marketing & Media",color:"#e67e22",words:/\b(marketing|brand|branding|advertising|agency|media|content|social media|creative|creator|influencer|pr|public relations|communications|tiktok|pinterest|youtube|growth marketing)\b/i},{key:"entertainment",label:"Entertainment & Gaming",color:"#9b59b6",words:/\b(entertainment|film|movie|music|records|gaming|games?|esports|studio|studios|netflix|disney|spotify|hollywood|theater|theatre|sports)\b/i},{key:"tech",label:"Tech, Software & AI",color:"#3498db",words:/\b(software|saas|engineer|engineering|developer|tech|technology|technologies|ai|artificial intelligence|machine learning|ml|data|cloud|cyber|security|devops|product manager|google|microsoft|apple|meta|amazon|nvidia|openai|anthropic|palantir|salesforce|oracle|ibm|intel|app|apps|startup|platform|labs?)\b/i},{key:"consulting",label:"Consulting, Legal & Services",color:"#1abc9c",words:/\b(consulting|consultant|consultancy|deloitte|accenture|mckinsey|kpmg|pwc|ey|bain|bcg|legal|law|lawyer|attorney|paralegal|recruiting|recruiter|staffing|talent)\b/i},{key:"realestate",label:"Real Estate & Construction",color:"#d35400",words:/\b(real estate|realtor|realty|property|properties|construction|architecture|architect|mortgage|homes|housing|builders?)\b/i},{key:"consumer",label:"Retail, Consumer & Hospitality",color:"#ff79c6",words:/\b(retail|e-?commerce|shopify|consumer|cpg|fashion|apparel|beauty|cosmetics|food|beverage|restaurant|hospitality|hotel|travel|tourism|coca-cola|nike|store|shop)\b/i},{key:"industry",label:"Manufacturing, Energy & Logistics",color:"#95a5a6",words:/\b(manufacturing|energy|oil|gas|solar|utilities|automotive|tesla|siemens|ge|general electric|honeywell|3m|logistics|supply chain|shipping|freight|fedex|ups|industrial|mining|chemicals?)\b/i},{key:"nonprofit",label:"Nonprofit & Community",color:"#bdc3c7",words:/\b(nonprofit|non-profit|foundation|charity|ngo|church|ministry|volunteer)\b/i}],f={key:"unknown",label:"Unclear",color:"#555c66"},g=Object.fromEntries([...e,f].map(a=>[a.key,a])),h=a=>g[a]||f;function i(a,b){for(let c of[a,b]){if(!c)continue;let a=e.find(a=>a.words.test(c));if(a)return a}return f}let j=(a,b)=>i(a,b).key,k=a=>c(a).level>=4;a.s(["INDUSTRIES",0,e,"UNKNOWN_INDUSTRY",0,f,"buildCompanyIndex",0,function(a=[]){let c=new Map,d=a=>(c.has(a)||c.set(a,(0,b.rolesWithCompanies)(a)),c.get(a)),{industries:e}=(0,b.networkCompanies)(a,{industryOf:j,rolesOf:d}),f=new Map;for(let b of a){let a=b.profile_url||`id:${b.id}`,c=f.get(a);(!c||(b.degree||9)<(c.degree||9))&&f.set(a,b)}let g=new Map;for(let a of f.values()){let b=d(a).find(a=>!a.former)?.company;if(!b)continue;let c=g.get(b);c||(c={name:b,people:[],d1:0,d2:0,d3:0,S:0,A:0,senior:0},g.set(b,c)),c.people.push(a),1===a.degree?c.d1++:2===a.degree?c.d2++:c.d3++,"S"===a.tier&&c.S++,"A"===a.tier&&c.A++,k(a.headline)&&c.senior++}for(let a of g.values())a.industry=h(e.get(a.name));return g},"companyLinks",0,function(a=[],b=[]){let c=new Map;for(let b of a){let a=d(b);a&&c.set(b.id,a)}let e=new Map;for(let a of b){let b=c.get(a.source_connection_id),f=d(a);if(!b||!f||b===f)continue;let[g,h]=b<f?[b,f]:[f,b],i=`${g}\u0000${h}`,j=e.get(i);j||(j={a:g,b:h,weight:0,via:new Set},e.set(i,j)),j.weight++,j.via.add(a.source_connection_id)}return[...e.values()]},"companyOf",0,d,"getSeniority",0,c,"industryByKey",0,h,"industryOf",0,i,"isSenior",0,k,"waysInto",0,function(a,b=[],c=[]){let e=b.filter(b=>d(b)===a),f=new Map;for(let b of c)d(b)===a&&f.set(b.source_connection_id,(f.get(b.source_connection_id)||0)+1);let g=new Map(b.map(a=>[a.id,a]));return{direct:e,bridges:[...f.entries()].map(([a,b])=>({bridge:g.get(a),n:b})).filter(a=>a.bridge).sort((a,b)=>b.n-a.n||(Number(b.bridge.power_score)||0)-(Number(a.bridge.power_score)||0))}}])},54919,a=>{"use strict";var b=a.i(9282);let c=new Map(b.INDUSTRIES.map(a=>[a.key,a.color])),d=new Map([...b.INDUSTRIES.map(a=>[a.key,Object.freeze({key:a.key,label:a.label,color:a.color,group:a.key,kind:"industry"})]),...Object.entries({software:["Software & SaaS","tech","function"],"ai-data":["AI & Data","tech","function"],cybersecurity:["Cybersecurity","tech","function"],telecom:["Telecom","tech","industry"],fintech:["Fintech & Payments","finance","industry"],banking:["Banking & Lending","finance","industry"],"vc-pe":["Venture Capital & Private Equity","finance","industry"],wealth:["Wealth & Asset Management","finance","industry"],insurance:["Insurance","finance","industry"],accounting:["Accounting & Tax","finance","function"],crypto:["Crypto & Web3","finance","industry"],hospitals:["Hospitals & Clinics","health","industry"],dental:["Dental","health","industry"],"pharma-biotech":["Pharma & Biotech","health","industry"],"medical-devices":["Medical Devices","health","industry"],"mental-health":["Mental Health","health","industry"],"fitness-wellness":["Fitness & Wellness","health","industry"],veterinary:["Veterinary & Animal Care","health","industry"],k12:["K-12 Education","education","industry"],"higher-ed":["Higher Education","education","industry"],"marketing-advertising":["Marketing & Advertising","media","function"],"pr-comms":["PR & Communications","media","function"],"media-publishing":["Media & Publishing","media","industry"],"creator-economy":["Creator Economy","media","industry"],"film-tv-music":["Film, TV & Music","entertainment","industry"],"gaming-esports":["Gaming & Esports","entertainment","industry"],sports:["Sports","entertainment","industry"],"ecommerce-retail":["E-commerce & Retail","consumer","industry"],"consumer-goods":["Consumer Goods","consumer","industry"],restaurants:["Restaurants & Food Service","consumer","industry"],"hospitality-travel":["Hospitality & Travel","consumer","industry"],"beauty-personal-care":["Beauty & Personal Care","consumer","industry"],logistics:["Logistics & Supply Chain","industry","industry"],manufacturing:["Manufacturing","industry","industry"],energy:["Energy & Utilities","industry","industry"],automotive:["Automotive","industry","industry"],agriculture:["Agriculture & Farming","industry","industry"],"aerospace-defense":["Aerospace & Defense","defense","industry"],military:["Military","defense","industry"],government:["Government & Public Sector","defense","industry"],legal:["Legal","consulting","function"],"management-consulting":["Management Consulting","consulting","function"],"hr-recruiting":["HR & Recruiting","consulting","function"],"security-services":["Security Services","consulting","function"],"real-estate":["Real Estate","realestate","industry"],"construction-trades":["Construction & Trades","realestate","industry"],charities:["Nonprofits & Charities","nonprofit","industry"],"social-work":["Social Work & Human Services","nonprofit","industry"],faith:["Faith & Ministry","nonprofit","industry"]}).map(([a,[d,e,f]])=>[a,Object.freeze({key:a,label:d,color:c.get(e)||b.UNKNOWN_INDUSTRY.color,group:e,kind:f})])]);a.s(["sectorByKey",0,function(a){return d.get(a)||{key:a,label:b.UNKNOWN_INDUSTRY.label,color:b.UNKNOWN_INDUSTRY.color,group:null,kind:null}}])}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=_06w_gl4._.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…"})})}])},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||[]}}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}])},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,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{g=await c(a,b,{...d?{id:d}:{},...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)},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=_13kzrwv._.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)},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||[]}}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,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}function n(a,b){return a?b.scanned.has(a.id)||a.profile_url&&b.read?.has(f(a))?"scanned":a.profile_url&&b.hidden.has(f(a))?"hidden":"todo":"todo"}function o(a,b){if(!a||1!==a.degree||null==a.unlocked_from_bridge_id)return null;let c=n(a,b);return"todo"===c?"ready":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}}],90231),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,n,"reachIndex",0,function(a=[],b=[],c={}){let d=new Set;for(let a of b||[])a?.source_connection_id!=null&&d.add(a.source_connection_id);let e=new Set;for(let a of c?.skips||[])a?.profileUrl&&e.add(f({profile_url:a.profileUrl}));let g=new Set;for(let a of c?.read||[])a&&g.add(f({profile_url:a}));let h=new Map;for(let[a,b]of Object.entries(c?.lists||{}))a&&b&&h.set(f({profile_url:a}),b);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:d,read:g,hidden:e,reachedFrom:i,lists:h}},"reachState",0,o,"readyByCircle",0,function(a){let b=new Map;for(let[c,d]of a.reachedFrom){let e=d.filter(b=>"ready"===o(b,a)).length;e&&b.set(c,e)}return b},"readyToScan",0,function(a,b){return(a||[]).filter(a=>"ready"===o(a,b)).sort(h)},"scanBars",0,function(a,b){let c=n(a,b),d=a?.profile_url?b.lists?.get(f(a)):null;return"hidden"===c?null:d?d.more?d.total?Math.max(1,Math.min(4,Math.round(5*Math.min(1,10*d.pages/d.total)))):2:5:"scanned"===c?2:null}],91443)},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,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{g=await c(a,b,{...d?{id:d}:{},...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)},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()}])}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=_15xuwkv._.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…"})})}])},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,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}function n(a,b){return a?b.scanned.has(a.id)||a.profile_url&&b.read?.has(f(a))?"scanned":a.profile_url&&b.hidden.has(f(a))?"hidden":"todo":"todo"}function o(a,b){if(!a||1!==a.degree||null==a.unlocked_from_bridge_id)return null;let c=n(a,b);return"todo"===c?"ready":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}}],90231),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,n,"reachIndex",0,function(a=[],b=[],c={}){let d=new Set;for(let a of b||[])a?.source_connection_id!=null&&d.add(a.source_connection_id);let e=new Set;for(let a of c?.skips||[])a?.profileUrl&&e.add(f({profile_url:a.profileUrl}));let g=new Set;for(let a of c?.read||[])a&&g.add(f({profile_url:a}));let h=new Map;for(let[a,b]of Object.entries(c?.lists||{}))a&&b&&h.set(f({profile_url:a}),b);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:d,read:g,hidden:e,reachedFrom:i,lists:h}},"reachState",0,o,"readyByCircle",0,function(a){let b=new Map;for(let[c,d]of a.reachedFrom){let e=d.filter(b=>"ready"===o(b,a)).length;e&&b.set(c,e)}return b},"readyToScan",0,function(a,b){return(a||[]).filter(a=>"ready"===o(a,b)).sort(h)},"scanBars",0,function(a,b){let c=n(a,b),d=a?.profile_url?b.lists?.get(f(a)):null;return"hidden"===c?null:d?d.more?d.total?Math.max(1,Math.min(4,Math.round(5*Math.min(1,10*d.pages/d.total)))):2:5:"scanned"===c?2:null}],91443)},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,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{g=await c(a,b,{...d?{id:d}:{},...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)},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=_1hgd5dp._.js.map
|