six-degrees 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +4 -0
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +42 -14
- package/.next/standalone/.next/routes-manifest.json +24 -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 +26 -18
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +26 -18
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +25 -16
- 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 +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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +3 -3
- 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 +3 -3
- 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 +2 -2
- package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/backup/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/backup/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/backup/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/backup/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/backup/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/backup/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/backup/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/csv/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/csv/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/csv/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/csv/route.js +8 -0
- package/.next/standalone/.next/server/app/api/data/csv/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/csv/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/csv/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/export/route.js +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 +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 +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/restore/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/restore/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/restore/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/restore/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/restore/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/restore/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/restore/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route.js +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 +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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/network/route.js +2 -2
- package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/outreach/route.js +3 -3
- package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/queue/route.js +2 -2
- package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js +5 -3
- package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/route.js +3 -3
- 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 +3 -3
- 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 +3 -3
- 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 +2 -2
- package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/crm/route.js +1 -1
- package/.next/standalone/.next/server/app/api/social/crm/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/messages/route.js +1 -1
- package/.next/standalone/.next/server/app/api/social/messages/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/route.js +2 -2
- package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/unlock/route.js +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js +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 +32 -24
- package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +32 -24
- 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 +23 -18
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +29 -22
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +20 -15
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +29 -22
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/insights/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/insights/page/build-manifest.json +20 -0
- package/.next/standalone/.next/server/app/insights/page/next-font-manifest.json +11 -0
- package/.next/standalone/.next/server/app/insights/page/react-loadable-manifest.json +1 -0
- package/.next/standalone/.next/server/app/insights/page/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/insights/page.js +13 -0
- package/.next/standalone/.next/server/app/insights/page.js.map +5 -0
- package/.next/standalone/.next/server/app/insights/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/insights/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/insights.html +1 -0
- package/.next/standalone/.next/server/app/insights.meta +26 -0
- package/.next/standalone/.next/server/app/insights.rsc +35 -0
- package/.next/standalone/.next/server/app/insights.segments/_full.segment.rsc +35 -0
- package/.next/standalone/.next/server/app/insights.segments/_tree.segment.rsc +4 -0
- package/.next/standalone/.next/server/app/insights.segments/insights/__PAGE__.segment.rsc +33 -0
- 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 +32 -24
- package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +32 -24
- 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 +23 -18
- 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 +32 -24
- package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +32 -24
- 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 +21 -18
- 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 +32 -24
- package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +32 -24
- 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 +23 -18
- 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 +32 -24
- package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +32 -24
- 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 +21 -18
- 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 +32 -24
- package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +32 -24
- 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 +23 -18
- 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 +32 -24
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +32 -24
- 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 +20 -18
- 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 +32 -24
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +32 -24
- 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 +21 -18
- package/.next/standalone/.next/server/app/social/page.js +1 -1
- package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/social.html +1 -1
- package/.next/standalone/.next/server/app/social.rsc +32 -24
- package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +23 -18
- package/.next/standalone/.next/server/app-paths-manifest.json +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05_3-22._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__066rab1._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fooke1._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__15wc9e-._.js → [root-of-the-server]__0r-0t-9._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ra6xyg._.js +15 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__20rwfdw._.js → [root-of-the-server]__0rcpjad._.js} +6 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t6y79e._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x29muh._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a_6x37._.js +8 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an_8pa._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ducpz2._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tir0vc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xhyinn._.js +3 -0
- package/.next/standalone/.next/server/chunks/_072jl0y._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0sqqpzb._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -7
- package/.next/standalone/.next/server/chunks/_1fn30_l._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_backup_route_actions_0zoj04p.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_csv_route_actions_0l6m7lg.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restore_route_actions_0-b05bv.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_02iz_9q._.js +4 -0
- package/.next/standalone/.next/server/chunks/lib_05agvk3._.js +4 -0
- package/.next/standalone/.next/server/chunks/lib_0v84u66._.js +4 -0
- package/.next/standalone/.next/server/chunks/lib_db-client_0_dch35.js +174 -0
- package/.next/standalone/.next/server/chunks/lib_linkedin-export_12imqxg.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_rpc_00nndai.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_03ibb-x.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_03ri3ji.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_078ce48.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0a69mgr.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +7 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0cej3t8.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0cmh4g6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0nx2_pc.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0r79-w1.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0t552z6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0yx8ynd.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_12p-o9-.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1466dnb.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1sryxv6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1trn-x5.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1ygu_mv.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0egamyq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qd8pzm._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qdeuyo._.js → [root-of-the-server]__1-012q1._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_04am_h8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_06rgzfh._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_07zb7lu._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0_79idq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0gds903._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0hb-dhy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0klqt9z._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_14jak5s._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/_14nxd3q._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1cj2yog._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1fm1ih_._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1hdqw0-._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/_1k2nmbw._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1r62six._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_insights_page_actions_0-0tf75.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_141w189._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_0uuff77._.js +25 -2
- package/.next/standalone/.next/server/chunks/ssr/app_components_1j3q-h5._.js +25 -2
- package/.next/standalone/.next/server/chunks/ssr/app_components_CompanyScores_1g0mytz.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_ui_0pdmz2z.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_import_page_1fmu6_l.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_insights_page_1d_chja.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +26 -14
- package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +11 -11
- package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +12 -13
- package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_1c4ieuw._.js → lib_csv_1ttiu_h.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/lib_galaxy-lab_108_lu-.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_separation_1305zsx.js +3 -0
- package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +1 -1
- 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/02wnf8dkxegxg.js +34 -0
- package/.next/standalone/.next/static/chunks/03-_esd2x_yk6.js +1 -0
- package/.next/standalone/.next/static/chunks/03-demj2iy-0p.js +44 -0
- package/.next/standalone/.next/static/chunks/0838_s6w-i_ik.js +1 -0
- package/.next/standalone/.next/static/chunks/0_1r-3csplxnj.js +1 -0
- package/.next/standalone/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
- package/.next/standalone/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
- package/.next/standalone/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
- package/.next/standalone/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
- package/.next/standalone/.next/static/chunks/112mv-com-mqa.js +21 -0
- package/.next/standalone/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
- package/.next/standalone/.next/static/chunks/1cmphb3kh2ers.css +3 -0
- package/.next/standalone/.next/static/chunks/1d8yv3k_atka7.js +1 -0
- package/.next/standalone/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
- package/.next/standalone/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
- package/.next/standalone/.next/static/chunks/23hc51oa4vkhc.js +5 -0
- package/.next/standalone/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
- package/.next/standalone/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
- package/.next/standalone/.next/static/chunks/2w-y83mjlpnse.js +1 -0
- package/.next/standalone/.next/static/chunks/2ws1xf293j-tm.js +5 -0
- package/.next/standalone/.next/static/chunks/2z1-q0_vunbql.js +2 -0
- package/.next/standalone/.next/static/chunks/34g73qhayuevu.js +1 -0
- package/.next/standalone/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
- package/.next/standalone/.next/static/chunks/3opgg1efrx8q6.js +1 -0
- package/.next/standalone/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
- package/.next/standalone/.next/static/chunks/3y40z6of3r9py.js +1 -0
- package/.next/standalone/.next/static/chunks/403dpflln8ah5.js +1 -0
- package/.next/standalone/.next/static/chunks/43pg2sursiypz.js +1 -0
- package/.next/standalone/CHANGELOG.md +203 -0
- package/.next/standalone/README.md +96 -50
- package/.next/standalone/SECURITY.md +25 -11
- package/.next/standalone/app/api/data/backup/route.js +25 -0
- package/.next/standalone/app/api/data/csv/route.js +74 -0
- package/.next/standalone/app/api/data/export/route.js +1 -1
- package/.next/standalone/app/api/data/restore/route.js +48 -0
- package/.next/standalone/app/api/data/reveal/route.js +19 -6
- package/.next/standalone/app/api/data/route.js +15 -4
- package/.next/standalone/app/api/ingest/route.js +1 -1
- package/.next/standalone/app/api/outreach/route.js +13 -73
- package/.next/standalone/app/api/queue/route.js +1 -1
- package/.next/standalone/app/api/scraper/route.js +217 -36
- package/.next/standalone/app/api/social/crm/route.js +2 -1
- package/.next/standalone/app/components/AppHeader.js +41 -21
- package/.next/standalone/app/components/AppTabs.js +12 -8
- package/.next/standalone/app/components/AutoConnect.js +286 -0
- package/.next/standalone/app/components/AutoScanButton.js +2 -2
- package/.next/standalone/app/components/Avatar.js +1 -1
- package/.next/standalone/app/components/ChainView.js +258 -113
- package/.next/standalone/app/components/CirclePanel.js +16 -16
- package/.next/standalone/app/components/ClusterSpinner.js +64 -0
- package/.next/standalone/app/components/CompanyScores.js +20 -20
- package/.next/standalone/app/components/EmptyState.js +39 -18
- package/.next/standalone/app/components/FieldStep.js +15 -13
- package/.next/standalone/app/components/FilterPanel.js +25 -18
- package/.next/standalone/app/components/ForceGraph.js +49 -14
- package/.next/standalone/app/components/GalaxyLab.js +33 -33
- package/.next/standalone/app/components/GridView.js +18 -18
- package/.next/standalone/app/components/LegacyScoresCard.js +10 -11
- package/.next/standalone/app/components/LinkedInLimits.js +57 -27
- package/.next/standalone/app/components/LiquidGlass.js +99 -0
- package/.next/standalone/app/components/ListView.js +20 -20
- package/.next/standalone/app/components/MapControls.js +5 -5
- package/.next/standalone/app/components/MappingProgress.js +16 -16
- package/.next/standalone/app/components/NoteDetail.js +13 -13
- package/.next/standalone/app/components/OnboardingGate.js +4 -4
- package/.next/standalone/app/components/OutlinkQuest.js +56 -35
- package/.next/standalone/app/components/PathsAnalyzer.js +37 -36
- package/.next/standalone/app/components/PeopleMap.js +21 -21
- package/.next/standalone/app/components/RingsView.js +11 -11
- package/.next/standalone/app/components/ScanRadar.js +84 -39
- package/.next/standalone/app/components/ScanStatusBar.js +40 -21
- package/.next/standalone/app/components/ScanTrail.js +21 -8
- package/.next/standalone/app/components/SeparationView.js +172 -124
- package/.next/standalone/app/components/Sidebar.js +308 -199
- package/.next/standalone/app/components/StaleServerBanner.js +4 -4
- package/.next/standalone/app/components/TheirCircle.js +26 -26
- package/.next/standalone/app/components/ThemeDefs.js +42 -0
- package/.next/standalone/app/components/ThemeLoader.js +20 -1
- package/.next/standalone/app/components/UpdatePanel.js +22 -22
- package/.next/standalone/app/components/UserProvider.js +22 -15
- package/.next/standalone/app/components/insights/Boards.js +275 -0
- package/.next/standalone/app/components/insights/PeopleView.js +266 -0
- package/.next/standalone/app/components/insights/Rail.js +156 -0
- package/.next/standalone/app/components/insights/Report.js +382 -0
- package/.next/standalone/app/components/insights/parts.js +239 -0
- package/.next/standalone/app/components/settings/AppearanceSection.js +47 -24
- package/.next/standalone/app/components/settings/DataSection.js +276 -109
- package/.next/standalone/app/components/settings/NetworkHealthSection.js +13 -13
- package/.next/standalone/app/components/settings/SectorPicker.js +12 -12
- package/.next/standalone/app/components/settings/SectorSection.js +13 -14
- package/.next/standalone/app/components/settings/TierSection.js +9 -9
- package/.next/standalone/app/components/settings/TitleSection.js +11 -11
- package/.next/standalone/app/components/settings/UsageSection.js +360 -0
- package/.next/standalone/app/components/ui.js +8 -8
- package/.next/standalone/app/globals.css +161 -5
- package/.next/standalone/app/import/page.js +94 -38
- package/.next/standalone/app/insights/page.js +220 -0
- package/.next/standalone/app/launch/page.js +5 -5
- package/.next/standalone/app/layout.js +6 -2
- package/.next/standalone/app/page.js +53 -53
- package/.next/standalone/app/paths/page.js +63 -63
- package/.next/standalone/app/profile/page.js +58 -58
- package/.next/standalone/app/queue/page.js +84 -72
- package/.next/standalone/app/scores/page.js +2 -2
- package/.next/standalone/app/settings/page.js +16 -13
- package/.next/standalone/app/setup/page.js +236 -133
- package/.next/standalone/app/social/Crm.js +63 -62
- package/.next/standalone/app/social/SocialHub.js +22 -22
- package/.next/standalone/app/social/Thread.js +7 -7
- package/.next/standalone/app/social/page.js +2 -2
- package/.next/standalone/lib/auto-connect.js +145 -0
- package/.next/standalone/lib/backups.js +458 -0
- package/.next/standalone/lib/chain-layout.js +32 -0
- package/.next/standalone/lib/companies.js +1 -1
- package/.next/standalone/lib/csv-store.js +131 -0
- package/.next/standalone/lib/csv.js +137 -39
- package/.next/standalone/lib/data-folder.js +19 -3
- package/.next/standalone/lib/data-import.js +5 -2
- package/.next/standalone/lib/db-client.js +78 -20
- package/.next/standalone/lib/demo.js +5 -4
- package/.next/standalone/lib/galaxy-export.js +9 -2
- package/.next/standalone/lib/galaxy-lab.js +19 -5
- package/.next/standalone/lib/galaxy-layouts.js +43 -0
- package/.next/standalone/lib/gate.js +10 -4
- package/.next/standalone/lib/in-progress.js +46 -0
- package/.next/standalone/lib/ingest.js +1 -1
- package/.next/standalone/lib/insights-board.js +613 -0
- package/.next/standalone/lib/linkedin-limits.js +240 -14
- package/.next/standalone/lib/liquid-glass.js +59 -0
- package/.next/standalone/lib/notifications.js +13 -0
- package/.next/standalone/lib/requests-client.js +10 -0
- package/.next/standalone/lib/requests.js +124 -0
- package/.next/standalone/lib/scan-pace.js +11 -0
- package/.next/standalone/lib/scan-progress.js +20 -0
- package/.next/standalone/lib/scan-risk.js +44 -0
- package/.next/standalone/lib/scan-state.js +1 -0
- package/.next/standalone/lib/scanner-setup.js +97 -15
- package/.next/standalone/lib/scraper-client.js +35 -8
- package/.next/standalone/lib/search-risk.js +7 -3
- package/.next/standalone/lib/settings-client.js +5 -3
- package/.next/standalone/lib/settings.js +13 -0
- package/.next/standalone/lib/social-store.js +3 -2
- package/.next/standalone/lib/synced-setting.js +46 -0
- package/.next/standalone/lib/theme-store.js +42 -10
- package/.next/standalone/lib/themes.js +111 -21
- package/.next/standalone/lib/usage.js +200 -0
- package/.next/standalone/package-lock.json +2 -2
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/scrape.py +595 -11
- package/.next/static/chunks/02wnf8dkxegxg.js +34 -0
- package/.next/static/chunks/03-_esd2x_yk6.js +1 -0
- package/.next/static/chunks/03-demj2iy-0p.js +44 -0
- package/.next/static/chunks/0838_s6w-i_ik.js +1 -0
- package/.next/static/chunks/0_1r-3csplxnj.js +1 -0
- package/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
- package/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
- package/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
- package/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
- package/.next/static/chunks/112mv-com-mqa.js +21 -0
- package/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
- package/.next/static/chunks/1cmphb3kh2ers.css +3 -0
- package/.next/static/chunks/1d8yv3k_atka7.js +1 -0
- package/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
- package/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
- package/.next/static/chunks/23hc51oa4vkhc.js +5 -0
- package/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
- package/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
- package/.next/static/chunks/2w-y83mjlpnse.js +1 -0
- package/.next/static/chunks/2ws1xf293j-tm.js +5 -0
- package/.next/static/chunks/2z1-q0_vunbql.js +2 -0
- package/.next/static/chunks/34g73qhayuevu.js +1 -0
- package/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
- package/.next/static/chunks/3opgg1efrx8q6.js +1 -0
- package/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
- package/.next/static/chunks/3y40z6of3r9py.js +1 -0
- package/.next/static/chunks/403dpflln8ah5.js +1 -0
- package/.next/static/chunks/43pg2sursiypz.js +1 -0
- package/CHANGELOG.md +203 -0
- package/README.md +96 -50
- package/SECURITY.md +25 -11
- package/lib/auto-connect.js +145 -0
- package/lib/backups.js +458 -0
- package/lib/chain-layout.js +32 -0
- package/lib/companies.js +1 -1
- package/lib/csv-store.js +131 -0
- package/lib/csv.js +137 -39
- package/lib/data-folder.js +19 -3
- package/lib/data-import.js +5 -2
- package/lib/db-client.js +78 -20
- package/lib/demo.js +5 -4
- package/lib/galaxy-export.js +9 -2
- package/lib/galaxy-lab.js +19 -5
- package/lib/galaxy-layouts.js +43 -0
- package/lib/gate.js +10 -4
- package/lib/in-progress.js +46 -0
- package/lib/ingest.js +1 -1
- package/lib/insights-board.js +613 -0
- package/lib/linkedin-limits.js +240 -14
- package/lib/liquid-glass.js +59 -0
- package/lib/notifications.js +13 -0
- package/lib/requests-client.js +10 -0
- package/lib/requests.js +124 -0
- package/lib/scan-pace.js +11 -0
- package/lib/scan-progress.js +20 -0
- package/lib/scan-risk.js +44 -0
- package/lib/scan-state.js +1 -0
- package/lib/scanner-setup.js +97 -15
- package/lib/scraper-client.js +35 -8
- package/lib/search-risk.js +7 -3
- package/lib/settings-client.js +5 -3
- package/lib/settings.js +13 -0
- package/lib/social-store.js +3 -2
- package/lib/synced-setting.js +46 -0
- package/lib/theme-store.js +42 -10
- package/lib/themes.js +111 -21
- package/lib/usage.js +200 -0
- package/package.json +1 -1
- package/scripts/scrape.py +595 -11
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13dx4sd._.js +0 -8
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +0 -3
- package/.next/standalone/.next/server/chunks/_02twlca._.js +0 -10
- package/.next/standalone/.next/server/chunks/lib_0851sk0._.js +0 -8
- package/.next/standalone/.next/server/chunks/lib_1q7p2ro._.js +0 -8
- package/.next/standalone/.next/server/chunks/lib_1r6l86l._.js +0 -8
- package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +0 -174
- package/.next/standalone/.next/server/chunks/lib_rpc_04s8mzr.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_053z7as.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0b_-2te.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0dhbxdm.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0dxlk31.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0f8b-qc.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0pzie7_.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0r76fq_.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0ut7pjp.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_15zyqaz.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_18zpjtq.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1a8xkiz.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1e_55xo.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1oxfd1_.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1s0lod0.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08oxiqh._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_03l7vge._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_08g31gm._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0gk_ofx._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0nwsf93._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0vho1lb._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1-658fq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1bc46kz._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1f_n00p._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_2105jz8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_components_0t908t-._.js +0 -3
- package/.next/standalone/.next/static/chunks/02pq76u7y4v9-.js +0 -22
- package/.next/standalone/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
- package/.next/standalone/.next/static/chunks/0i02yxppzds1o.js +0 -1
- package/.next/standalone/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
- package/.next/standalone/.next/static/chunks/0oyslj62jkubd.js +0 -1
- package/.next/standalone/.next/static/chunks/0vo-l8hxneba6.css +0 -3
- package/.next/standalone/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
- package/.next/standalone/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
- package/.next/standalone/.next/static/chunks/172e10mi-tpo_.js +0 -34
- package/.next/standalone/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
- package/.next/standalone/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
- package/.next/standalone/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
- package/.next/standalone/.next/static/chunks/1m3017gp790pw.js +0 -45
- package/.next/standalone/.next/static/chunks/1t20e8u0st7ep.js +0 -1
- package/.next/standalone/.next/static/chunks/2-ch9rm27eril.js +0 -11
- package/.next/standalone/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
- package/.next/standalone/.next/static/chunks/3bp284gjf7dyq.js +0 -1
- package/.next/standalone/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
- package/.next/standalone/.next/static/chunks/3l4t8je6iguzc.js +0 -1
- package/.next/standalone/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
- package/.next/standalone/.next/static/chunks/42m0bqr8pbovz.js +0 -11
- package/.next/static/chunks/02pq76u7y4v9-.js +0 -22
- package/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
- package/.next/static/chunks/0i02yxppzds1o.js +0 -1
- package/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
- package/.next/static/chunks/0oyslj62jkubd.js +0 -1
- package/.next/static/chunks/0vo-l8hxneba6.css +0 -3
- package/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
- package/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
- package/.next/static/chunks/172e10mi-tpo_.js +0 -34
- package/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
- package/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
- package/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
- package/.next/static/chunks/1m3017gp790pw.js +0 -45
- package/.next/static/chunks/1t20e8u0st7ep.js +0 -1
- package/.next/static/chunks/2-ch9rm27eril.js +0 -11
- package/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
- package/.next/static/chunks/3bp284gjf7dyq.js +0 -1
- package/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
- package/.next/static/chunks/3l4t8je6iguzc.js +0 -1
- package/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
- package/.next/static/chunks/42m0bqr8pbovz.js +0 -11
- /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
- /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
- /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
|
@@ -35,12 +35,15 @@ import { useRouter } from 'next/navigation';
|
|
|
35
35
|
import { circleIndex, MAX_DEGREE } from '../../lib/circle';
|
|
36
36
|
import { localPhoto } from '../../lib/photos';
|
|
37
37
|
import { reachIndex, reachState, circleState, readyByCircle, circleScanCost, scanBars } from '../../lib/reach';
|
|
38
|
+
import { stoppedLine } from '../../lib/in-progress';
|
|
38
39
|
import { reachSegments, RING } from '../../lib/dot-rings';
|
|
39
|
-
import { ringLayout, chainTree, dotRadius, previewBand, tierBandLayout } from '../../lib/chain-layout';
|
|
40
|
+
import { ringLayout, chainTree, dotRadius, previewBand, tierBandLayout, circleActivity } from '../../lib/chain-layout';
|
|
41
|
+
import { noteCircle } from '../../lib/notifications';
|
|
42
|
+
import { useUser } from './UserProvider';
|
|
40
43
|
import { redundancy } from '../../lib/brokerage';
|
|
41
44
|
import { keyFor, score } from '../../lib/separation';
|
|
42
45
|
import { hasRequest } from '../../lib/requests-client';
|
|
43
|
-
import { watchScanner, scannerNow, isCircleScan } from '../../lib/scraper-client';
|
|
46
|
+
import { watchScanner, scannerNow, isCircleScan, beginScrape, scraperStatus, notReadyMessage, busyReason, resumePoint } from '../../lib/scraper-client';
|
|
44
47
|
import useRequests from './useRequests';
|
|
45
48
|
import { TIER_COLORS } from '../../lib/themes';
|
|
46
49
|
|
|
@@ -175,6 +178,17 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
175
178
|
const index = useMemo(() => circleIndex(all1, all2), [all1, all2]);
|
|
176
179
|
const reach = useMemo(() => reachIndex(all1, all2, scanNotes), [all1, all2, scanNotes]);
|
|
177
180
|
const readyCount = useMemo(() => readyByCircle(reach), [reach]);
|
|
181
|
+
// The notifications, by the circle each is about: the busiest circles go on the inner ring.
|
|
182
|
+
const { userId } = useUser();
|
|
183
|
+
const [notes, setNotes] = useState([]);
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if (!userId) return undefined;
|
|
186
|
+
let live = true;
|
|
187
|
+
fetch(`/api/notifications?userId=${encodeURIComponent(userId)}`).then((r) => r.json())
|
|
188
|
+
.then((d) => { if (live) setNotes((d.notifications || []).map((n) => ({ circle: noteCircle(n), seen: !!n.seen }))); })
|
|
189
|
+
.catch(() => {});
|
|
190
|
+
return () => { live = false; };
|
|
191
|
+
}, [userId]);
|
|
178
192
|
const twoWays = useMemo(() => redundancy(fullDegree2 || degree2, fullDegree1 || connections), [fullDegree2, degree2, fullDegree1, connections]);
|
|
179
193
|
const rowById = useMemo(() => {
|
|
180
194
|
const m = new Map();
|
|
@@ -240,7 +254,12 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
240
254
|
}
|
|
241
255
|
return withCircle.has(b.unlocked_from_bridge_id);
|
|
242
256
|
};
|
|
243
|
-
|
|
257
|
+
// The inner ring holds the circles with the most going on (lib/chain-layout.js
|
|
258
|
+
// circleActivity): notifications about them, people in them ready to scan,
|
|
259
|
+
// clusters formed from them since. The biggest first among the rest.
|
|
260
|
+
const activity = circleActivity(bridges, { notes, ready: readyCount, chained });
|
|
261
|
+
const roots = bridges.filter((b) => !linked(b))
|
|
262
|
+
.sort((a, b) => activity.get(b.id).score - activity.get(a.id).score);
|
|
244
263
|
// Bridges round you: one ring while they fit, more once there are many, each
|
|
245
264
|
// ring far enough from the last for the names under it.
|
|
246
265
|
const bridgeLayout = ringLayout(roots.length, {
|
|
@@ -248,7 +267,7 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
248
267
|
});
|
|
249
268
|
const bridgePos = roots.map((b, i) => {
|
|
250
269
|
const p = bridgeLayout.points[i];
|
|
251
|
-
return { ...b, x: cx + p.x, y: cy + p.y, angle: p.angle, clusterSize: (bridgeMap[b.id] || []).length, chains: chained.get(b.id) || 0 };
|
|
270
|
+
return { ...b, x: cx + p.x, y: cy + p.y, angle: p.angle, clusterSize: (bridgeMap[b.id] || []).length, chains: chained.get(b.id) || 0, activity: activity.get(b.id) };
|
|
252
271
|
});
|
|
253
272
|
// More than one ring: the counts under each name wait for a hover.
|
|
254
273
|
const crowded = bridgeLayout.rings.length > 1;
|
|
@@ -339,8 +358,8 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
339
358
|
|
|
340
359
|
{/* Their circle, previewed on hover, in a wedge that grows rows as it fills */}
|
|
341
360
|
{hovBridge && (
|
|
342
|
-
<CirclePreview bridge={hovBridge} members={membersOf(hovBridge, index)} reach={reach}
|
|
343
|
-
cx={cx} cy={cy} maxR={maxR} still={still} band={band} />
|
|
361
|
+
<CirclePreview key={hovBridge.id} bridge={hovBridge} members={membersOf(hovBridge, index)} reach={reach}
|
|
362
|
+
cx={cx} cy={cy} maxR={maxR} still={still} band={band} circleOf={(id) => bridgeMap[id] || []} />
|
|
344
363
|
)}
|
|
345
364
|
|
|
346
365
|
{/* Bridge nodes — hover to preview their circle, click to open it */}
|
|
@@ -357,7 +376,7 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
357
376
|
style={{ cursor: 'pointer' }}>
|
|
358
377
|
<title>{bridgeTitle(b, ready, scanBars(b, reach))}</title>
|
|
359
378
|
{/* Glow */}
|
|
360
|
-
<circle cx={b.x} cy={b.y} r={isHov ? 21 : 18} fill={`${TIER_COLORS[b.tier]}${isHov ? '14' : '08'}`} />
|
|
379
|
+
<circle className="sd-dot" cx={b.x} cy={b.y} r={isHov ? 21 : 18} fill={`${TIER_COLORS[b.tier]}${isHov ? '14' : '08'}`} />
|
|
361
380
|
{/* The ring, tight on the dot: one bar for each person you added through
|
|
362
381
|
this circle. Orange: scanned since, with a cluster of their own.
|
|
363
382
|
Green: ready for a scan. Nobody yet: one faint line. */}
|
|
@@ -371,9 +390,9 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
371
390
|
))}
|
|
372
391
|
</g>
|
|
373
392
|
{/* Node */}
|
|
374
|
-
<circle cx={b.x} cy={b.y} r={isHov ? 13 : 11}
|
|
393
|
+
<circle className="sd-dot" cx={b.x} cy={b.y} r={isHov ? 13 : 11}
|
|
375
394
|
fill={localPhoto(b.profile_image_url) ? '#1a1a2e' : TIER_COLORS[b.tier]}
|
|
376
|
-
stroke={isHov ? '#fff' : TIER_COLORS[b.tier]}
|
|
395
|
+
stroke={isHov ? 'var(--sd-fg-1, #fff)' : TIER_COLORS[b.tier]}
|
|
377
396
|
strokeWidth={isHov ? 2.5 : 2} />
|
|
378
397
|
{/* Photo */}
|
|
379
398
|
{localPhoto(b.profile_image_url) && (
|
|
@@ -384,22 +403,30 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
384
403
|
</>
|
|
385
404
|
)}
|
|
386
405
|
{!localPhoto(b.profile_image_url) && (
|
|
387
|
-
<text x={b.x} y={b.y + 4} textAnchor="middle" fill={b.tier === 'S' ? '#000' : '#fff'}
|
|
406
|
+
<text x={b.x} y={b.y + 4} textAnchor="middle" fill={b.tier === 'S' ? '#000' : 'var(--sd-fg-1, #fff)'}
|
|
388
407
|
fontSize={11} fontWeight={700}>{b.name?.charAt(0)}</text>
|
|
389
408
|
)}
|
|
390
|
-
{/*
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
409
|
+
{/* The circle's notifications, top right (Blake, 2026-10-02: "the circle degree
|
|
410
|
+
outline on the top right with the number of notifications for that cluster"):
|
|
411
|
+
new notifications about it and the people in it ready to scan. Gold when
|
|
412
|
+
there's news, green when it's only people ready. */}
|
|
413
|
+
{(() => {
|
|
414
|
+
const news = (b.activity?.unread || 0) + ready;
|
|
415
|
+
if (!news) return null;
|
|
416
|
+
const tone = b.activity?.unread ? 'var(--sd-gold, #FFD700)' : 'var(--sd-green, #00ff88)'; // deeper on a light look
|
|
417
|
+
return (
|
|
418
|
+
<g pointerEvents="none">
|
|
419
|
+
<circle cx={b.x + 14} cy={b.y - 14} r={6} fill="var(--sd-bg)" stroke={tone} strokeWidth={1.2} />
|
|
420
|
+
<text x={b.x + 14} y={b.y - 11.4} textAnchor="middle" fill={tone} fontSize={news > 9 ? 6 : 7} fontWeight={800}>{news > 99 ? '99+' : news}</text>
|
|
421
|
+
</g>
|
|
422
|
+
);
|
|
423
|
+
})()}
|
|
397
424
|
{/* Name + count */}
|
|
398
|
-
<text x={b.x} y={b.y + (isHov ? 24 : 22)} textAnchor="middle" fill="#fff" fontSize={9} fontWeight={600}>
|
|
425
|
+
<text x={b.x} y={b.y + (isHov ? 24 : 22)} textAnchor="middle" fill="var(--sd-fg-1, #fff)" fontSize={9} fontWeight={600}>
|
|
399
426
|
{b.name?.split(' ')[0]}
|
|
400
427
|
</text>
|
|
401
428
|
{(!crowded || isHov) && (
|
|
402
|
-
<text x={b.x} y={b.y + (isHov ? 34 : 32)} textAnchor="middle" fill={isHov ? '#bbb' : '#888'} fontSize={7}>
|
|
429
|
+
<text x={b.x} y={b.y + (isHov ? 34 : 32)} textAnchor="middle" fill={isHov ? 'var(--sd-fg-2, #bbb)' : 'var(--sd-fg-3, #888)'} fontSize={7}>
|
|
403
430
|
{b.clusterSize} · {sCount > 0 ? sCount + 'S ' : ''}{aCount > 0 ? aCount + 'A' : ''}
|
|
404
431
|
</text>
|
|
405
432
|
)}
|
|
@@ -409,7 +436,7 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
409
436
|
|
|
410
437
|
{/* Center: YOU */}
|
|
411
438
|
<circle cx={cx} cy={cy} r={22} fill="var(--sd-bg)" stroke="#FFD700" strokeWidth={3} />
|
|
412
|
-
<text x={cx} y={cy + 4} textAnchor="middle" fill="#FFD700" fontSize={11} fontWeight={800}>
|
|
439
|
+
<text x={cx} y={cy + 4} textAnchor="middle" fill="var(--sd-gold, #FFD700)" fontSize={11} fontWeight={800}>
|
|
413
440
|
{userName?.split(' ')[0] || 'YOU'}
|
|
414
441
|
</text>
|
|
415
442
|
</g>
|
|
@@ -422,41 +449,35 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
422
449
|
onOut={() => setZoom(z => Math.max(0.4, (z ?? homeZoom) - 0.3))}
|
|
423
450
|
/>
|
|
424
451
|
|
|
425
|
-
{/* Depth tracker
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
452
|
+
{/* Depth tracker: just the dots, no box (Blake, 2026-10-03: the box grew with
|
|
453
|
+
a theme's font and stopped fitting; "just have the dots there instead so
|
|
454
|
+
its more clean looking"). What they add up to is the tooltip. */}
|
|
455
|
+
<div
|
|
456
|
+
title={[
|
|
457
|
+
`${roots.length} bridges${bridges.length > roots.length ? ` + ${bridges.length - roots.length} along their chains` : ''} · ${d2S} S + ${d2A} A at 2nd degree`,
|
|
458
|
+
twoWays > 0 ? `${Math.round(twoWays * 100)}% of your 2nd degree you reach two or more ways` : null,
|
|
459
|
+
'The inner ring: the circles with the most going on (notifications, people ready to scan, clusters formed since)',
|
|
460
|
+
'Click a bridge to open their circle, then anyone in it to open theirs',
|
|
461
|
+
].filter(Boolean).join('\n')}
|
|
462
|
+
style={{ position: 'absolute', bottom: 16, left: 16, display: 'flex', alignItems: 'flex-end', gap: 12 }}>
|
|
463
|
+
{[1, 2, 3, 4, 5, 6].map((d) => {
|
|
464
|
+
const lit = d <= 2;
|
|
465
|
+
const n = d === 1 ? connections.length : d === 2 ? totalD2 : null;
|
|
466
|
+
return (
|
|
467
|
+
<div key={d} title={lit ? `${d === 1 ? '1st degree: your bridges' : '2nd degree: the people in their circles'} (${n.toLocaleString('en-US')})` : `${d}th degree: further along a chain, as your scans reach it`}
|
|
468
|
+
style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
|
|
469
|
+
<span className={lit ? 'sd-dot-html' : undefined} style={{
|
|
470
|
+
width: 11, height: 11, borderRadius: '50%',
|
|
471
|
+
background: lit ? DEGREE_COLORS[d] : 'transparent',
|
|
472
|
+
border: lit ? 'none' : '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.22)',
|
|
473
|
+
boxShadow: lit ? `0 0 8px ${DEGREE_COLORS[d]}80` : 'none',
|
|
474
|
+
}} />
|
|
475
|
+
<span style={{ fontSize: 9.5, fontWeight: 700, color: lit ? 'var(--sd-fg-2, #c8cdd8)' : 'var(--sd-fg-5, #556)', fontVariantNumeric: 'tabular-nums', textShadow: HALO_TEXT }}>
|
|
476
|
+
{lit ? n.toLocaleString('en-US') : `D${d}`}
|
|
477
|
+
</span>
|
|
447
478
|
</div>
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
<div style={{ fontSize: 9, color: '#555', marginTop: 8 }}>
|
|
451
|
-
{roots.length} bridges{bridges.length > roots.length ? ` + ${bridges.length - roots.length} along their chains` : ''} · {d2S} S + {d2A} A at 2nd degree
|
|
452
|
-
</div>
|
|
453
|
-
{twoWays > 0 && (
|
|
454
|
-
<div style={{ fontSize: 9, color: '#555', marginTop: 4 }}
|
|
455
|
-
title="The share of everyone you reach through a circle that more than one of your connections reaches">
|
|
456
|
-
{Math.round(twoWays * 100)}% of your 2nd degree you reach two or more ways
|
|
457
|
-
</div>
|
|
458
|
-
)}
|
|
459
|
-
<div style={{ fontSize: 8, color: '#444', marginTop: 4 }}>Click a bridge to open their circle, then anyone in it to open theirs</div>
|
|
479
|
+
);
|
|
480
|
+
})}
|
|
460
481
|
</div>
|
|
461
482
|
</div>
|
|
462
483
|
);
|
|
@@ -465,6 +486,8 @@ export default function ChainView({ connections, degree2 = [], onSelect, userNam
|
|
|
465
486
|
/** What a bridge's ring and number mean, in words, for its tooltip. */
|
|
466
487
|
function bridgeTitle(b, ready, bars) {
|
|
467
488
|
const parts = [];
|
|
489
|
+
const notes = b.activity?.notes || 0;
|
|
490
|
+
if (notes) parts.push(`${notes} notification${notes === 1 ? '' : 's'} about their circle${b.activity.unread ? `, ${b.activity.unread} new` : ''}`);
|
|
468
491
|
if (ready) parts.push(`${ready} in ${firstName(b)}’s circle ${ready === 1 ? 'is' : 'are'} ready for a scan`);
|
|
469
492
|
if (b.chains) parts.push(`${b.chains} scanned since, with ${b.chains === 1 ? 'a cluster' : 'clusters'} of their own`);
|
|
470
493
|
if (bars != null) parts.push(bars === 5 ? 'their whole list is scanned' : `about ${bars * 20}% of their list is scanned`);
|
|
@@ -472,7 +495,34 @@ function bridgeTitle(b, ready, bars) {
|
|
|
472
495
|
}
|
|
473
496
|
|
|
474
497
|
/** A bridge's circle on hover: the people you reached through it first, then their S, A and B. */
|
|
475
|
-
|
|
498
|
+
// The preview grows out of the bridge when you hover it (Blake, 2026-10-03: "the
|
|
499
|
+
// d2,3,4 clusters emerging out of the circle in the preview to show the grow but
|
|
500
|
+
// make it quick and snappy"): their circle's people shoot out to their places,
|
|
501
|
+
// then anyone among them whose own circle is scanned sprouts it (3rd degree),
|
|
502
|
+
// then theirs (4th). Under half a second in all; still with Reduce Motion.
|
|
503
|
+
const PREVIEW_CSS = `
|
|
504
|
+
@keyframes pvEmerge { from { transform: translate(var(--fx), var(--fy)) scale(0.2); opacity: 0; } 55% { opacity: 1; } to { transform: none; opacity: 1; } }
|
|
505
|
+
@keyframes pvFade { from { opacity: 0; } }
|
|
506
|
+
.pv-dot { transform-box: fill-box; transform-origin: center; animation: pvEmerge .24s cubic-bezier(.2,.9,.3,1.25) both; animation-delay: var(--d, 0ms); }
|
|
507
|
+
.pv-d3 { animation-duration: .22s; animation-delay: calc(150ms + var(--d, 0ms)); }
|
|
508
|
+
.pv-d4 { animation-duration: .2s; animation-delay: calc(270ms + var(--d, 0ms)); }
|
|
509
|
+
.pv-line { animation: pvFade .3s ease-out both; animation-delay: var(--d, 0ms); }
|
|
510
|
+
@media (prefers-reduced-motion: reduce) { .pv-dot, .pv-line { animation: none; } }
|
|
511
|
+
`;
|
|
512
|
+
const SPROUT = 14; // the most of a circle's own circle drawn round them
|
|
513
|
+
const SPROUT_4 = 8;
|
|
514
|
+
|
|
515
|
+
/** Where someone's own circle sprouts round their dot: an arc facing away from the middle. */
|
|
516
|
+
function sprout(n, x, y, cx, cy, r) {
|
|
517
|
+
const out = Math.atan2(y - cy, x - cx);
|
|
518
|
+
const spread = Math.min(Math.PI * 1.1, 0.5 + n * 0.16);
|
|
519
|
+
return Array.from({ length: n }, (_, i) => {
|
|
520
|
+
const a = out - spread / 2 + (n === 1 ? spread / 2 : (i * spread) / (n - 1));
|
|
521
|
+
return { x: x + Math.cos(a) * r, y: y + Math.sin(a) * r };
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function CirclePreview({ bridge, members, reach, cx, cy, maxR, still, band, circleOf = () => [] }) {
|
|
476
526
|
const shown = members.filter((m) => m.degree === 1 || m.tier === 'S' || m.tier === 'A' || m.tier === 'B');
|
|
477
527
|
// Beyond every ring of bridges (lib/chain-layout.js previewBand).
|
|
478
528
|
const { inner, outer } = band;
|
|
@@ -480,8 +530,12 @@ function CirclePreview({ bridge, members, reach, cx, cy, maxR, still, band }) {
|
|
|
480
530
|
const layout = ringLayout(shown.length, {
|
|
481
531
|
inner, outer, spacing: 11, minSpacing: 3.5, start: bridge.angle - sweep / 2, sweep,
|
|
482
532
|
});
|
|
533
|
+
// Spread the start of each dot over a tenth of a second, wherever it sits.
|
|
534
|
+
const stagger = (j) => `${Math.round((j / Math.max(1, shown.length)) * 110)}ms`;
|
|
535
|
+
const from = (x, y, ox, oy) => ({ '--fx': `${(ox - x).toFixed(1)}px`, '--fy': `${(oy - y).toFixed(1)}px` });
|
|
483
536
|
return (
|
|
484
537
|
<g>
|
|
538
|
+
<style>{PREVIEW_CSS}</style>
|
|
485
539
|
<circle cx={cx} cy={cy} r={inner} fill="none" stroke={`${DEGREE_COLORS[2]}06`} strokeWidth={1} />
|
|
486
540
|
{shown.map((d2, j) => {
|
|
487
541
|
const p = layout.points[j];
|
|
@@ -490,21 +544,44 @@ function CirclePreview({ bridge, members, reach, cx, cy, maxR, still, band }) {
|
|
|
490
544
|
const state = reachState(d2, reach);
|
|
491
545
|
const nr = Math.min(dotRadius(layout.spacing, d2.tier), 5) * (state ? 1.3 : 1);
|
|
492
546
|
const color = state === 'hidden' ? HIDDEN : TIER_COLORS[d2.tier] || '#555';
|
|
547
|
+
// Their own circle, if it's scanned: the 3rd degree, and inside it the 4th.
|
|
548
|
+
const own = d2.degree === 1 ? circleOf(d2.id) : [];
|
|
549
|
+
const third = own.slice(0, SPROUT);
|
|
550
|
+
const thirdAt = sprout(third.length, x2, y2, cx, cy, nr + 9);
|
|
493
551
|
return (
|
|
494
552
|
<g key={'pv-' + d2.id}>
|
|
495
553
|
{(state || shown.length <= 40) && (
|
|
496
|
-
<line x1={bridge.x} y1={bridge.y} x2={x2} y2={y2}
|
|
554
|
+
<line className="pv-line" style={{ '--d': stagger(j) }} x1={bridge.x} y1={bridge.y} x2={x2} y2={y2}
|
|
497
555
|
stroke={state ? GREEN : color} strokeWidth={0.5} strokeOpacity={state ? 0.35 : 0.15} />
|
|
498
556
|
)}
|
|
499
|
-
{
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
{
|
|
506
|
-
|
|
507
|
-
|
|
557
|
+
<g className="pv-dot" style={{ '--d': stagger(j), ...from(x2, y2, bridge.x, bridge.y) }}>
|
|
558
|
+
{state === 'ready' && <Halo x={x2} y={y2} r={nr * 2.3} still={still} />}
|
|
559
|
+
<circle className="sd-dot" cx={x2} cy={y2} r={nr}
|
|
560
|
+
fill={color} fillOpacity={state ? 0.95 : 0.45}
|
|
561
|
+
stroke={state && state !== 'hidden' ? GREEN : color} strokeWidth={state ? 1 : 0.5} strokeOpacity={state ? 1 : 0.25} />
|
|
562
|
+
{(d2.tier === 'S' || state) && shown.length <= 60 && (
|
|
563
|
+
<text x={x2} y={y2 + nr + 9} textAnchor="middle" fill={state && state !== 'hidden' ? GREEN : 'var(--sd-fg-3, #aaa)'} fontSize={7}>
|
|
564
|
+
{firstName(d2)}
|
|
565
|
+
</text>
|
|
566
|
+
)}
|
|
567
|
+
</g>
|
|
568
|
+
{third.map((k, i) => {
|
|
569
|
+
const t = thirdAt[i];
|
|
570
|
+
const fourth = k.degree === 1 ? circleOf(k.id).slice(0, SPROUT_4) : [];
|
|
571
|
+
const fourthAt = sprout(fourth.length, t.x, t.y, x2, y2, 6);
|
|
572
|
+
return (
|
|
573
|
+
<g key={'p3-' + k.id}>
|
|
574
|
+
<line className="pv-line" style={{ '--d': `calc(150ms + ${stagger(j)})` }} x1={x2} y1={y2} x2={t.x} y2={t.y}
|
|
575
|
+
stroke={TIER_COLORS[k.tier] || '#555'} strokeWidth={0.4} strokeOpacity={0.3} />
|
|
576
|
+
<circle className="pv-dot pv-d3" style={{ '--d': `${i * 8}ms`, ...from(t.x, t.y, x2, y2) }}
|
|
577
|
+
cx={t.x} cy={t.y} r={1.8} fill={TIER_COLORS[k.tier] || '#555'} fillOpacity={0.85} />
|
|
578
|
+
{fourth.map((f, q) => (
|
|
579
|
+
<circle key={'p4-' + f.id} className="pv-dot pv-d4" style={{ '--d': `${q * 6}ms`, ...from(fourthAt[q].x, fourthAt[q].y, t.x, t.y) }}
|
|
580
|
+
cx={fourthAt[q].x} cy={fourthAt[q].y} r={1.1} fill={TIER_COLORS[f.tier] || '#555'} fillOpacity={0.75} />
|
|
581
|
+
))}
|
|
582
|
+
</g>
|
|
583
|
+
);
|
|
584
|
+
})}
|
|
508
585
|
</g>
|
|
509
586
|
);
|
|
510
587
|
})}
|
|
@@ -527,7 +604,7 @@ function Lock({ x, y, s }) {
|
|
|
527
604
|
return (
|
|
528
605
|
<g transform={`translate(${x} ${y}) scale(${s})`} pointerEvents="none">
|
|
529
606
|
<path d="M-1.9 -0.6 V-1.8 A1.9 1.9 0 0 1 1.9 -1.8 V-0.6" fill="none" stroke="#d6d6de" strokeWidth={0.9} />
|
|
530
|
-
<rect x={-2.6} y={-0.7} width={5.2} height={3.9} rx={0.8} fill="#d6d6de" />
|
|
607
|
+
<rect x={-2.6} y={-0.7} width={5.2} height={3.9} rx={0.8} fill="var(--sd-fg-2, #d6d6de)" />
|
|
531
608
|
</g>
|
|
532
609
|
);
|
|
533
610
|
}
|
|
@@ -535,7 +612,7 @@ function Lock({ x, y, s }) {
|
|
|
535
612
|
function ZoomButtons({ onIn, onReset, onOut }) {
|
|
536
613
|
const round = (dim) => ({
|
|
537
614
|
width: 32, height: 32, borderRadius: '50%', border: 'none', cursor: 'pointer',
|
|
538
|
-
background: dim ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.1)', color: dim ? '#666' : '#fff',
|
|
615
|
+
background: dim ? 'rgba(var(--sd-ink, 255, 255, 255), 0.06)' : 'rgba(var(--sd-ink, 255, 255, 255), 0.1)', color: dim ? 'var(--sd-fg-4, #666)' : 'var(--sd-fg-1, #fff)',
|
|
539
616
|
fontSize: dim ? 10 : 18, fontWeight: 700,
|
|
540
617
|
display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(8px)',
|
|
541
618
|
});
|
|
@@ -683,7 +760,7 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
683
760
|
<circle cx={p.x} cy={p.y} r={r * 1.2} fill="none" stroke={color} strokeWidth={Math.max(0.6, r * 0.45)}
|
|
684
761
|
strokeDasharray={`${Math.max(0.8, r * 0.55)} ${Math.max(0.6, r * 0.45)}`} />
|
|
685
762
|
) : (
|
|
686
|
-
<circle cx={p.x} cy={p.y} r={r} fill={color} fillOpacity={f.reached ? 1 : 0.85}
|
|
763
|
+
<circle className="sd-dot" cx={p.x} cy={p.y} r={r} fill={color} fillOpacity={f.reached ? 1 : 0.85}
|
|
687
764
|
stroke={f.reached && f.reached !== 'hidden' ? GREEN : 'none'} strokeWidth={f.reached ? Math.max(0.8, r * 0.3) : 0} />
|
|
688
765
|
)}
|
|
689
766
|
{f.reached === 'hidden' && <Lock x={p.x} y={p.y - r * 0.1} s={r / 4.2} />}
|
|
@@ -692,7 +769,7 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
692
769
|
)}
|
|
693
770
|
{(f.reached || (roomy && row.tier === 'S')) && (
|
|
694
771
|
<text x={p.x} y={above ? p.y - r - 4 / k : p.y + r + 10 / k} textAnchor="middle" fontSize={8.5 / k} fontWeight={f.reached ? 700 : 400}
|
|
695
|
-
fill={f.reached === 'hidden' ? '#999' : f.reached ? GREEN : '#aaa'} pointerEvents="none"
|
|
772
|
+
fill={f.reached === 'hidden' ? 'var(--sd-fg-3, #999)' : f.reached ? GREEN : 'var(--sd-fg-3, #aaa)'} pointerEvents="none"
|
|
696
773
|
stroke="var(--sd-bg)" strokeWidth={2.4 / k} paintOrder="stroke">
|
|
697
774
|
{firstName(row)}
|
|
698
775
|
</text>
|
|
@@ -794,7 +871,7 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
794
871
|
{/* A faint band behind each tier's dots, in its colour */}
|
|
795
872
|
{layout.bands.map((band) => (
|
|
796
873
|
<circle key={band.tier} r={(band.inner + band.outer) / 2} fill="none"
|
|
797
|
-
stroke={TIER_COLORS[band.tier] || '#555'} strokeOpacity={0.07}
|
|
874
|
+
stroke={TIER_COLORS[band.tier] || 'var(--sd-fg-5, #555)'} strokeOpacity={0.07}
|
|
798
875
|
strokeWidth={Math.max(1 / k, band.outer - band.inner + layout.spacing)} pointerEvents="none" />
|
|
799
876
|
))}
|
|
800
877
|
{dots}
|
|
@@ -813,17 +890,17 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
813
890
|
<circle r={c.radius} fill="var(--sd-bg)" fillOpacity={0.9} stroke={color} strokeOpacity={lit ? 0.7 : 0.25} strokeWidth={1 / k} />
|
|
814
891
|
{/* Their people, each joined to the middle of the cluster */}
|
|
815
892
|
{clusterPaths(c).map(([tier, { spokes }]) => (
|
|
816
|
-
<path key={'s' + tier} d={spokes} fill="none" stroke={TIER_COLORS[tier] || '#555'}
|
|
893
|
+
<path key={'s' + tier} d={spokes} fill="none" stroke={TIER_COLORS[tier] || 'var(--sd-fg-5, #555)'}
|
|
817
894
|
strokeWidth={0.7} strokeOpacity={lit ? 0.6 : 0.38} />
|
|
818
895
|
))}
|
|
819
896
|
{clusterPaths(c).map(([tier, { dots: d }]) => (
|
|
820
|
-
<path key={tier} d={d} fill={TIER_COLORS[tier] || '#555'} fillOpacity={lit ? 1 : 0.9} />
|
|
897
|
+
<path className="sd-dot" key={tier} d={d} fill={TIER_COLORS[tier] || 'var(--sd-fg-5, #555)'} fillOpacity={lit ? 1 : 0.9} />
|
|
821
898
|
))}
|
|
822
|
-
<circle r={LINK_HUB} fill={color} stroke={hovLink === j ? '#fff' : 'var(--sd-bg)'} strokeWidth={1.5} />
|
|
899
|
+
<circle className="sd-dot" r={LINK_HUB} fill={color} stroke={hovLink === j ? 'var(--sd-fg-1, #fff)' : 'var(--sd-bg)'} strokeWidth={1.5} />
|
|
823
900
|
{row.id === scanningId && (
|
|
824
901
|
<circle r={c.radius + 4} fill="none" stroke={DEGREE_COLORS[3]} strokeWidth={1 / k} strokeDasharray={`${3 / k} ${2 / k}`} />
|
|
825
902
|
)}
|
|
826
|
-
<text y={c.radius + 12 / k} textAnchor="middle" fill="#fff" fontSize={10 / k} fontWeight={700}
|
|
903
|
+
<text y={c.radius + 12 / k} textAnchor="middle" fill="var(--sd-fg-1, #fff)" fontSize={10 / k} fontWeight={700}
|
|
827
904
|
stroke="var(--sd-bg)" strokeWidth={2.4 / k} paintOrder="stroke">{firstName(row)}’s circle</text>
|
|
828
905
|
<text y={c.radius + 23 / k} textAnchor="middle" fill={color} fontSize={8 / k}
|
|
829
906
|
stroke="var(--sd-bg)" strokeWidth={2.4 / k} paintOrder="stroke">
|
|
@@ -856,7 +933,7 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
856
933
|
{seg(o, o.r + 1, p, LINK_HUB + 1, 'b')}
|
|
857
934
|
{/* Their own dot inside the cluster they were met through */}
|
|
858
935
|
{o.inCluster && (
|
|
859
|
-
<circle cx={o.x} cy={o.y} r={o.r} fill={TIER_COLORS[link.row.tier] || '#555'} stroke={GREEN} strokeWidth={1.4} />
|
|
936
|
+
<circle className="sd-dot" cx={o.x} cy={o.y} r={o.r} fill={TIER_COLORS[link.row.tier] || 'var(--sd-fg-5, #555)'} stroke={GREEN} strokeWidth={1.4} />
|
|
860
937
|
)}
|
|
861
938
|
</g>
|
|
862
939
|
);
|
|
@@ -864,25 +941,25 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
864
941
|
{/* The one under the pointer, on top */}
|
|
865
942
|
{hp && (
|
|
866
943
|
<>
|
|
867
|
-
<line x1={0} y1={0} x2={hp.x} y2={hp.y} stroke={TIER_COLORS[hovered.tier] || '#888'} strokeWidth={1.6 / k} strokeOpacity={0.8} />
|
|
944
|
+
<line x1={0} y1={0} x2={hp.x} y2={hp.y} stroke={TIER_COLORS[hovered.tier] || 'var(--sd-fg-3, #888)'} strokeWidth={1.6 / k} strokeOpacity={0.8} />
|
|
868
945
|
<circle cx={hp.x} cy={hp.y} r={dotRadius(layout.spacing, hovered.tier) * (facts[hover].reached ? 1.4 : 1) + 2 / k}
|
|
869
946
|
fill="none" stroke="#fff" strokeWidth={1.6 / k} />
|
|
870
947
|
</>
|
|
871
948
|
)}
|
|
872
949
|
{/* The person in the middle, with the halo if their own circle is ready to scan */}
|
|
873
950
|
{reachState(person, reach) === 'ready' && <Halo x={0} y={0} r={40} still={still} />}
|
|
874
|
-
<circle r={28} fill="var(--sd-bg)" stroke={TIER_COLORS[person.tier] || '#888'} strokeWidth={hover === 'center' ? 4 : 3} filter="url(#focusGlow)" />
|
|
951
|
+
<circle r={28} fill="var(--sd-bg)" stroke={TIER_COLORS[person.tier] || 'var(--sd-fg-3, #888)'} strokeWidth={hover === 'center' ? 4 : 3} filter="url(#focusGlow)" />
|
|
875
952
|
{localPhoto(person.profile_image_url) ? (
|
|
876
953
|
<>
|
|
877
954
|
<clipPath id="focus-clip"><circle r={24} /></clipPath>
|
|
878
955
|
<image href={localPhoto(person.profile_image_url)} x={-24} y={-24} width={48} height={48} clipPath="url(#focus-clip)" />
|
|
879
956
|
</>
|
|
880
957
|
) : (
|
|
881
|
-
<text y={5} textAnchor="middle" fill={TIER_COLORS[person.tier] || '#888'} fontSize={16} fontWeight={800}>
|
|
958
|
+
<text y={5} textAnchor="middle" fill={TIER_COLORS[person.tier] || 'var(--sd-fg-3, #888)'} fontSize={16} fontWeight={800}>
|
|
882
959
|
{person.name?.charAt(0)}
|
|
883
960
|
</text>
|
|
884
961
|
)}
|
|
885
|
-
<text y={40} textAnchor="middle" fill="#fff" fontSize={11} fontWeight={700} pointerEvents="none">{person.name}</text>
|
|
962
|
+
<text y={40} textAnchor="middle" fill="var(--sd-fg-1, #fff)" fontSize={11} fontWeight={700} pointerEvents="none">{person.name}</text>
|
|
886
963
|
</g>
|
|
887
964
|
{hovered && (
|
|
888
965
|
<Tip x={cx + view.x + hp.x * k} y={cy + view.y + hp.y * k} w={dims.w}
|
|
@@ -908,28 +985,28 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
908
985
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', pointerEvents: 'auto' }}>
|
|
909
986
|
<button type="button" onClick={() => onBack(depth - 1)} style={{
|
|
910
987
|
padding: '8px 16px', borderRadius: 8, border: 'none', cursor: 'pointer',
|
|
911
|
-
background: 'rgba(255,255,255,0.1)', color: '#ddd', fontSize: 12, fontWeight: 700,
|
|
988
|
+
background: 'rgba(var(--sd-ink, 255, 255, 255), 0.1)', color: 'var(--sd-fg-1, #ddd)', fontSize: 12, fontWeight: 700,
|
|
912
989
|
}}>
|
|
913
990
|
← {depth === 1 ? 'All bridges' : `${firstName(trail[depth - 2])}’s circle`}
|
|
914
991
|
</button>
|
|
915
|
-
<nav aria-label="Trail" style={{ fontSize: 11, color: '#777', display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
992
|
+
<nav aria-label="Trail" style={{ fontSize: 11, color: 'var(--sd-fg-4, #777)', display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
|
|
916
993
|
<button type="button" onClick={() => onBack(0)} style={crumb}>All bridges</button>
|
|
917
994
|
{trail.map((row, i) => (
|
|
918
995
|
<span key={row.id} style={{ display: 'inline-flex', gap: 6, alignItems: 'center' }}>
|
|
919
996
|
<span aria-hidden="true">›</span>
|
|
920
997
|
{i === depth - 1
|
|
921
|
-
? <span style={{ color: '#fff', fontWeight: 700 }}>{row.name}</span>
|
|
998
|
+
? <span style={{ color: 'var(--sd-fg-1, #fff)', fontWeight: 700 }}>{row.name}</span>
|
|
922
999
|
: <button type="button" onClick={() => onBack(i + 1)} style={crumb}>{row.name}</button>}
|
|
923
1000
|
</span>
|
|
924
1001
|
))}
|
|
925
1002
|
</nav>
|
|
926
1003
|
</div>
|
|
927
|
-
<div style={{ fontSize: 11, color: '#999' }}>
|
|
1004
|
+
<div style={{ fontSize: 11, color: 'var(--sd-fg-3, #999)' }}>
|
|
928
1005
|
{firstName(person)}’s circle · {members.length.toLocaleString('en-US')} {members.length === 1 ? 'person' : 'people'}
|
|
929
1006
|
{' · '}{ordinal(depth + 1)} degree{depth > 1 ? ', counted along this chain' : ''}
|
|
930
1007
|
</div>
|
|
931
1008
|
{scanningThem && members.length > 0 && (
|
|
932
|
-
<div role="status" style={{ ...note, borderColor: 'rgba(52,152,219,0.4)', color: '#cfe6f7' }}>
|
|
1009
|
+
<div role="status" style={{ ...note, borderColor: 'rgba(52,152,219,0.4)', color: 'var(--sd-fg-1, #cfe6f7)' }}>
|
|
933
1010
|
Scanning {firstName(person)}’s circle now. More people appear here as it saves, every 10 pages.
|
|
934
1011
|
</div>
|
|
935
1012
|
)}
|
|
@@ -940,30 +1017,23 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
940
1017
|
scanning={scanningThem} canScan={canScan} onSelect={onSelect} top={cy + 64} />
|
|
941
1018
|
)}
|
|
942
1019
|
|
|
943
|
-
{/* What's in this circle */}
|
|
1020
|
+
{/* What's in this circle: dots and counts, no box, as the depth tracker */}
|
|
944
1021
|
{members.length > 0 && (
|
|
945
|
-
<div
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1022
|
+
<div title={`Click anyone for their circle${ready > 0 && canScan ? ', or someone ready to scan theirs' : ''} · drag to move · scroll to zoom`}
|
|
1023
|
+
style={{
|
|
1024
|
+
position: 'absolute', bottom: 18, left: 18, maxWidth: 'calc(100% - 110px)',
|
|
1025
|
+
display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: '6px 14px',
|
|
1026
|
+
fontSize: 10.5, color: 'var(--sd-fg-3, #aab)', textShadow: HALO_TEXT,
|
|
1027
|
+
}}>
|
|
951
1028
|
{byTier.map(([t, n]) => (
|
|
952
|
-
<
|
|
953
|
-
<
|
|
954
|
-
<span style={{ color: TIER_COLORS[t], fontWeight:
|
|
955
|
-
<span>{n.toLocaleString('en-US')}</span>
|
|
956
|
-
</
|
|
1029
|
+
<span key={t} style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
|
|
1030
|
+
<span className="sd-dot-html" style={{ width: 8, height: 8, borderRadius: '50%', background: TIER_COLORS[t], boxShadow: `0 0 6px ${TIER_COLORS[t]}66` }} />
|
|
1031
|
+
<span style={{ color: TIER_COLORS[t], fontWeight: 700 }}>{t}</span>
|
|
1032
|
+
<span style={{ fontVariantNumeric: 'tabular-nums' }}>{n.toLocaleString('en-US')}</span>
|
|
1033
|
+
</span>
|
|
957
1034
|
))}
|
|
958
|
-
{
|
|
959
|
-
|
|
960
|
-
{added > 0 && <div><span style={{ color: GREEN }}>● </span>you added {added}{ready ? `, ${ready} ready to scan` : ''}{hidden ? `, ${hidden} hidden` : ''}</div>}
|
|
961
|
-
{asked > 0 && <div><span style={{ color: '#FFD700' }}>◌ </span>{asked} {asked === 1 ? 'request' : 'requests'} out</div>}
|
|
962
|
-
</div>
|
|
963
|
-
)}
|
|
964
|
-
<div style={{ marginTop: 6, color: '#555' }}>
|
|
965
|
-
Click anyone for their circle{ready > 0 && canScan ? ', or someone ready to scan theirs' : ''} · drag to move · scroll to zoom
|
|
966
|
-
</div>
|
|
1035
|
+
{added > 0 && <span><span style={{ color: GREEN }}>●</span> you added {added}{ready ? `, ${ready} ready to scan` : ''}{hidden ? `, ${hidden} hidden` : ''}</span>}
|
|
1036
|
+
{asked > 0 && <span><span style={{ color: 'var(--sd-gold, #FFD700)' }}>◌</span> {asked} {asked === 1 ? 'request' : 'requests'} out</span>}
|
|
967
1037
|
</div>
|
|
968
1038
|
)}
|
|
969
1039
|
|
|
@@ -972,6 +1042,9 @@ function CircleFocus({ trail, index, reach, dims, requests, scanningId, still, c
|
|
|
972
1042
|
);
|
|
973
1043
|
}
|
|
974
1044
|
|
|
1045
|
+
// Words over the map without a box: a soft halo in the theme's background (lib/themes.js).
|
|
1046
|
+
const HALO_TEXT = '0 0 3px var(--sd-bg), 0 0 6px var(--sd-bg), 0 0 1px var(--sd-bg)';
|
|
1047
|
+
|
|
975
1048
|
// A link's cluster draws at most this many of their people; the count beside it is the whole circle.
|
|
976
1049
|
const LINK_DOTS = 290;
|
|
977
1050
|
// The middle of a cluster, where its first ring starts, and a link's own dot inside one.
|
|
@@ -1019,10 +1092,10 @@ function Tip({ x, y, w, lines, accent }) {
|
|
|
1019
1092
|
const top = Math.max(6, y - height - 12);
|
|
1020
1093
|
return (
|
|
1021
1094
|
<g pointerEvents="none">
|
|
1022
|
-
<rect x={left} y={top} width={width} height={height} rx={6} fill="rgba(0,0,0,0.92)" stroke={accent || '#555'} strokeWidth={0.6} />
|
|
1095
|
+
<rect x={left} y={top} width={width} height={height} rx={6} fill="var(--sd-surface, rgba(0,0,0,0.92))" stroke={accent || 'var(--sd-fg-5, #555)'} strokeWidth={0.6} />
|
|
1023
1096
|
{lines.map((line, i) => (
|
|
1024
1097
|
<text key={i} x={left + width / 2} y={top + 16 + i * 12} textAnchor="middle"
|
|
1025
|
-
fill={i === 0 ? '#fff' : i === 2 ? accent || '#aaa' : '#999'} fontSize={i === 0 ? 10.5 : 9} fontWeight={i === 0 ? 700 : 400}>
|
|
1098
|
+
fill={i === 0 ? 'var(--sd-fg-1, #fff)' : i === 2 ? accent || 'var(--sd-fg-3, #aaa)' : 'var(--sd-fg-3, #999)'} fontSize={i === 0 ? 10.5 : 9} fontWeight={i === 0 ? 700 : 400}>
|
|
1026
1099
|
{line}
|
|
1027
1100
|
</text>
|
|
1028
1101
|
))}
|
|
@@ -1039,6 +1112,17 @@ function EmptyCircle({ person, depth, reach, requests, scanning, canScan, onSele
|
|
|
1039
1112
|
const next = ordinal(depth + 1);
|
|
1040
1113
|
const yours = person.degree === 1;
|
|
1041
1114
|
const state = yours ? circleState(person, reach) : null;
|
|
1115
|
+
// Read partway with nothing saved yet (everyone on those pages was already
|
|
1116
|
+
// yours): that isn't a list that has been read, so it says it stopped, with
|
|
1117
|
+
// the card's Resume (Blake, 2026-10-03: "the ones they stopped and would like
|
|
1118
|
+
// to resume"). Where it stopped is the card's own answer, asked of the server
|
|
1119
|
+
// (GET /api/scraper?resume=<id>): the map's scan notes don't say how far a
|
|
1120
|
+
// list got. Undefined while it's asked.
|
|
1121
|
+
const stopped = useStoppedAt(state === 'scanned' && !scanning ? person.id : null);
|
|
1122
|
+
// Why Resume didn't start, kept here: a start greys this to "Scanning…" for a
|
|
1123
|
+
// moment even when it's refused, and the button's own state would go with it.
|
|
1124
|
+
const [problem, setProblem] = useState(null);
|
|
1125
|
+
if (state === 'scanned' && !scanning && stopped === undefined) return null; // never "has been read" by mistake
|
|
1042
1126
|
const cost = circleScanCost();
|
|
1043
1127
|
let title;
|
|
1044
1128
|
let body;
|
|
@@ -1046,6 +1130,10 @@ function EmptyCircle({ person, depth, reach, requests, scanning, canScan, onSele
|
|
|
1046
1130
|
if (scanning) {
|
|
1047
1131
|
title = `Scanning ${first}’s circle now`;
|
|
1048
1132
|
body = 'Their people appear here as the scan saves them, every 10 pages.';
|
|
1133
|
+
} else if (stopped) {
|
|
1134
|
+
title = `${first}’s scan stopped partway`;
|
|
1135
|
+
body = `${stoppedLine(stopped)}. Everyone on those pages was already one of your connections, so nobody new is here yet. Resume carries on from page ${stopped.nextPage}.`;
|
|
1136
|
+
if (canScan) action = <ResumeHere person={person} stopped={stopped} problem={problem} setProblem={setProblem} />;
|
|
1049
1137
|
} else if (state === 'hidden') {
|
|
1050
1138
|
title = `${first} keeps their connections hidden`;
|
|
1051
1139
|
body = 'LinkedIn doesn’t show their list, so there is no circle to scan.';
|
|
@@ -1059,7 +1147,7 @@ function EmptyCircle({ person, depth, reach, requests, scanning, canScan, onSele
|
|
|
1059
1147
|
action = (
|
|
1060
1148
|
<>
|
|
1061
1149
|
<Link href={scanPageFor(person)} style={primary}>Scan {first}’s circle →</Link>
|
|
1062
|
-
<div style={{ fontSize: 10.5, color: '#888', marginTop: 8 }}>
|
|
1150
|
+
<div style={{ fontSize: 10.5, color: 'var(--sd-fg-3, #888)', marginTop: 8 }}>
|
|
1063
1151
|
{cost.profileViews} profile view, then one LinkedIn search per page of their list (up to {cost.searches}, about {cost.minutes} min).
|
|
1064
1152
|
It starts only once you confirm it on the Scan page.
|
|
1065
1153
|
</div>
|
|
@@ -1077,21 +1165,78 @@ function EmptyCircle({ person, depth, reach, requests, scanning, canScan, onSele
|
|
|
1077
1165
|
return (
|
|
1078
1166
|
<div role="status" style={{
|
|
1079
1167
|
position: 'absolute', left: '50%', top, transform: 'translateX(-50%)', width: 'min(360px, calc(100% - 32px))',
|
|
1080
|
-
background: 'color-mix(in srgb, var(--sd-bg) 94%, transparent)', border: `1px solid ${state === 'hidden' ? 'rgba(255,255,255,0.12)' : 'rgba(0,255,136,0.25)'}`,
|
|
1168
|
+
background: 'color-mix(in srgb, var(--sd-bg) 94%, transparent)', border: `1px solid ${state === 'hidden' ? 'rgba(var(--sd-ink, 255, 255, 255), 0.12)' : stopped && !scanning ? 'rgba(255,215,0,0.4)' : 'rgba(0,255,136,0.25)'}`,
|
|
1081
1169
|
borderRadius: 12, padding: '14px 16px', textAlign: 'center',
|
|
1082
1170
|
}}>
|
|
1083
|
-
<div style={{ fontSize: 13, fontWeight: 800, color: state === 'hidden' ? '#aaa' : '#fff', marginBottom: 6 }}>
|
|
1171
|
+
<div style={{ fontSize: 13, fontWeight: 800, color: state === 'hidden' ? 'var(--sd-fg-3, #aaa)' : 'var(--sd-fg-1, #fff)', marginBottom: 6 }}>
|
|
1084
1172
|
{state === 'hidden' && <span aria-hidden="true">🔒 </span>}{title}
|
|
1085
1173
|
</div>
|
|
1086
|
-
<div style={{ fontSize: 11.5, color: '#9aa', lineHeight: 1.55, marginBottom: action ? 12 : 0 }}>{body}</div>
|
|
1174
|
+
<div style={{ fontSize: 11.5, color: 'var(--sd-fg-3, #9aa)', lineHeight: 1.55, marginBottom: action ? 12 : 0 }}>{body}</div>
|
|
1087
1175
|
{action}
|
|
1088
1176
|
</div>
|
|
1089
1177
|
);
|
|
1090
1178
|
}
|
|
1091
1179
|
|
|
1180
|
+
/**
|
|
1181
|
+
* Where Resume would carry on with one of your connections ({ nextPage,
|
|
1182
|
+
* pagesRead }), null when there's nothing to carry on with, undefined while
|
|
1183
|
+
* it's asked; and never asked for null. Asked again whenever `id` comes back,
|
|
1184
|
+
* as it does when a scan of theirs ends.
|
|
1185
|
+
*/
|
|
1186
|
+
function useStoppedAt(id) {
|
|
1187
|
+
const [got, setGot] = useState({ id: null, resume: undefined });
|
|
1188
|
+
useEffect(() => {
|
|
1189
|
+
if (!id) return undefined;
|
|
1190
|
+
let live = true;
|
|
1191
|
+
resumePoint(id).then((r) => { if (live) setGot({ id, resume: r }); }, () => { if (live) setGot({ id, resume: null }); });
|
|
1192
|
+
return () => { live = false; };
|
|
1193
|
+
}, [id]);
|
|
1194
|
+
if (!id) return null;
|
|
1195
|
+
return got.id === id ? got.resume : undefined;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Resume for a circle that stopped partway, from the map: what the card's
|
|
1200
|
+
* Resume does (Sidebar.js CreateClusterCard), the same check first, carrying on
|
|
1201
|
+
* from the page it stopped at, never page 1 again. Once it starts, the empty
|
|
1202
|
+
* circle says it's being scanned. Greyed out, saying why, while another scan runs.
|
|
1203
|
+
*/
|
|
1204
|
+
function ResumeHere({ person, stopped, problem, setProblem }) {
|
|
1205
|
+
const busy = useSyncExternalStore(watchScanner, () => busyReason(scannerNow()), () => null);
|
|
1206
|
+
const [checking, setChecking] = useState(false);
|
|
1207
|
+
async function go() {
|
|
1208
|
+
setProblem(null);
|
|
1209
|
+
setChecking(true);
|
|
1210
|
+
const blocked = notReadyMessage(await scraperStatus().catch(() => null));
|
|
1211
|
+
setChecking(false);
|
|
1212
|
+
if (blocked) {
|
|
1213
|
+
setProblem(`${blocked} Open the Scan page to finish setting the scanner up.`);
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
try {
|
|
1217
|
+
await beginScrape('resume', { id: person.id });
|
|
1218
|
+
} catch (e) {
|
|
1219
|
+
setProblem(e.message || 'Could not start the scan.');
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
const off = Boolean(busy) || checking;
|
|
1223
|
+
return (
|
|
1224
|
+
<>
|
|
1225
|
+
<button type="button" onClick={go} disabled={off} style={{
|
|
1226
|
+
...primary, border: 'none', cursor: off ? 'not-allowed' : 'pointer', opacity: off ? 0.45 : 1,
|
|
1227
|
+
}}>Resume from page {stopped.nextPage}</button>
|
|
1228
|
+
{(busy || problem) && (
|
|
1229
|
+
<div style={{ fontSize: 10.5, color: problem ? '#ff8080' : 'var(--sd-fg-3, #888)', marginTop: 8 }}>
|
|
1230
|
+
{problem || `${busy}. One scan at a time: this one can start when it finishes.`}
|
|
1231
|
+
</div>
|
|
1232
|
+
)}
|
|
1233
|
+
</>
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1092
1237
|
const crumb = { background: 'none', border: 'none', color: '#8fb8d6', fontSize: 11, fontWeight: 600, cursor: 'pointer', padding: 0 };
|
|
1093
1238
|
const note = {
|
|
1094
|
-
fontSize: 11, padding: '6px 10px', borderRadius: 8, border: '1px solid', background: 'rgba(0,0,0,0.6)', pointerEvents: 'auto',
|
|
1239
|
+
fontSize: 11, padding: '6px 10px', borderRadius: 8, border: '1px solid', background: 'rgba(var(--sd-shade, 0, 0, 0), 0.6)', pointerEvents: 'auto',
|
|
1095
1240
|
};
|
|
1096
1241
|
const primary = {
|
|
1097
1242
|
display: 'inline-block', padding: '9px 16px', borderRadius: 8, textDecoration: 'none', fontSize: 12.5, fontWeight: 800,
|
|
@@ -1099,5 +1244,5 @@ const primary = {
|
|
|
1099
1244
|
};
|
|
1100
1245
|
const secondary = {
|
|
1101
1246
|
padding: '8px 14px', borderRadius: 8, cursor: 'pointer', fontSize: 12, fontWeight: 700,
|
|
1102
|
-
border: '1px solid rgba(255,255,255,0.18)', background: 'rgba(255,255,255,0.06)', color: '#ddd',
|
|
1247
|
+
border: '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.18)', background: 'rgba(var(--sd-ink, 255, 255, 255), 0.06)', color: 'var(--sd-fg-1, #ddd)',
|
|
1103
1248
|
};
|