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
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { db as supabase } from '../../../lib/db';
|
|
2
1
|
import { getDb, decodeRow } from '../../../lib/db-client';
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
XP_SEND, XP_ACCEPT, awardXP, whose, copiesOf, inList, bestTier, markSent,
|
|
4
|
+
} from '../../../lib/requests';
|
|
4
5
|
|
|
5
6
|
// Requests you've sent, kept per PERSON.
|
|
6
7
|
//
|
|
@@ -13,56 +14,8 @@ import { resolveProfile } from '../../../lib/profile';
|
|
|
13
14
|
// asked through is kept (so once they accept, their card and circle say who
|
|
14
15
|
// introduced you: lib/promote.js keeps it), XP comes once per person, and Undo
|
|
15
16
|
// takes back all of it. lib/requests-client.js is the one way the pages call this.
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
const XP_SEND = { S: 25, A: 15, B: 10, C: 5, D: 2 };
|
|
19
|
-
const XP_ACCEPT = { S: 100, A: 60, B: 35, C: 15, D: 5 };
|
|
20
|
-
const TIER_ORDER = ['S', 'A', 'B', 'C', 'D'];
|
|
21
|
-
|
|
22
|
-
async function awardXP(userId, amount) {
|
|
23
|
-
if (!userId || !amount) return;
|
|
24
|
-
// Upsert: create if not exists, change if exists. Never below zero: an Undo
|
|
25
|
-
// takes back what a send gave, including sends from before sends gave any.
|
|
26
|
-
const { data: existing } = await supabase.from('user_stats').select('xp').eq('id', userId).single();
|
|
27
|
-
if (existing) {
|
|
28
|
-
await supabase.from('user_stats').update({ xp: Math.max(0, (existing.xp || 0) + amount) }).eq('id', userId);
|
|
29
|
-
} else if (amount > 0) {
|
|
30
|
-
await supabase.from('user_stats').insert([{ id: userId, xp: amount, level: 1 }]).catch(() => {});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** The profile a request belongs to: the one sent, else this machine's. */
|
|
35
|
-
function whose(userId) {
|
|
36
|
-
if (userId) return String(userId);
|
|
37
|
-
try { return resolveProfile({ create: false })?.id || null; } catch { return null; }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Every copy of one person: by the clicked row's profile URL, or the URL given. */
|
|
41
|
-
function copiesOf(db, { connectionId, profileUrl, userId }) {
|
|
42
|
-
let url = profileUrl ? String(profileUrl) : null;
|
|
43
|
-
let user = userId ? String(userId) : null;
|
|
44
|
-
let clicked = null;
|
|
45
|
-
if (connectionId != null) {
|
|
46
|
-
clicked = db.prepare('SELECT id, profile_url, user_id FROM linkedin_connections WHERE id = ?').get(String(connectionId)) || null;
|
|
47
|
-
if (clicked) {
|
|
48
|
-
url = clicked.profile_url || url;
|
|
49
|
-
user = user || clicked.user_id || null;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
const cols = 'id, degree, tier, outreach_status, unlock_status, unlocked_from_bridge_id';
|
|
53
|
-
let rows = [];
|
|
54
|
-
if (url) {
|
|
55
|
-
rows = user
|
|
56
|
-
? db.prepare(`SELECT ${cols} FROM linkedin_connections WHERE profile_url = ? AND user_id = ?`).all(url, user)
|
|
57
|
-
: db.prepare(`SELECT ${cols} FROM linkedin_connections WHERE profile_url = ?`).all(url);
|
|
58
|
-
} else if (clicked) {
|
|
59
|
-
rows = db.prepare(`SELECT ${cols} FROM linkedin_connections WHERE id = ?`).all(clicked.id);
|
|
60
|
-
}
|
|
61
|
-
return { url, user, rows };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const inList = (ids) => ids.map(() => '?').join(', ');
|
|
65
|
-
const bestTier = (rows) => TIER_ORDER.find((t) => rows.some((r) => r.tier === t)) || 'D';
|
|
17
|
+
// The marking itself is lib/requests.js markSent, which Auto's sends use too
|
|
18
|
+
// (app/api/scraper/route.js).
|
|
66
19
|
|
|
67
20
|
export async function POST(request) {
|
|
68
21
|
try {
|
|
@@ -72,33 +25,20 @@ export async function POST(request) {
|
|
|
72
25
|
return Response.json({ error: 'Unknown action' }, { status: 400 });
|
|
73
26
|
}
|
|
74
27
|
const db = getDb();
|
|
28
|
+
|
|
29
|
+
if (action === 'mark-sent') {
|
|
30
|
+
const { saved, xp, already } = await markSent(db, { connectionId, profileUrl, userId, bridgeId });
|
|
31
|
+
// Nobody on file (the sample network lives in the browser): nothing to keep.
|
|
32
|
+
if (!saved) return Response.json({ success: true, saved: 0, xp: 0 });
|
|
33
|
+
return Response.json({ success: true, saved, xp, already });
|
|
34
|
+
}
|
|
35
|
+
|
|
75
36
|
const { user, rows } = copiesOf(db, { connectionId, profileUrl, userId });
|
|
76
37
|
// Nobody on file (the sample network lives in the browser): nothing to keep.
|
|
77
38
|
if (!rows.length) return Response.json({ success: true, saved: 0, xp: 0 });
|
|
78
39
|
const ids = rows.map((r) => r.id);
|
|
79
40
|
const now = new Date().toISOString();
|
|
80
41
|
|
|
81
|
-
if (action === 'mark-sent') {
|
|
82
|
-
const already = rows.some((r) => r.outreach_status === 'sent' || r.outreach_status === 'accepted');
|
|
83
|
-
db.prepare(`UPDATE linkedin_connections SET outreach_status = 'sent', updated_at = ?
|
|
84
|
-
WHERE id IN (${inList(ids)}) AND (outreach_status IS NULL OR outreach_status NOT IN ('sent', 'accepted'))`).run(now, ...ids);
|
|
85
|
-
db.prepare(`UPDATE linkedin_connections SET unlock_status = 'pending', updated_at = ?
|
|
86
|
-
WHERE id IN (${inList(ids)}) AND (unlock_status IS NULL OR unlock_status = 'locked')`).run(now, ...ids);
|
|
87
|
-
// Who you asked through: one of your own connections, or nothing.
|
|
88
|
-
if (bridgeId != null) {
|
|
89
|
-
const bridge = db.prepare(
|
|
90
|
-
`SELECT id, name FROM linkedin_connections WHERE id = ? AND degree = 1${user ? ' AND user_id = ?' : ''}`,
|
|
91
|
-
).get(...[String(bridgeId), ...(user ? [user] : [])]);
|
|
92
|
-
if (bridge) {
|
|
93
|
-
db.prepare(`UPDATE linkedin_connections SET unlocked_from_bridge_id = ?, unlocked_from_name = ?, updated_at = ?
|
|
94
|
-
WHERE id IN (${inList(ids)}) AND degree = 2 AND unlocked_from_bridge_id IS NULL`).run(bridge.id, bridge.name, now, ...ids);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const xp = already ? 0 : XP_SEND[bestTier(rows)] || 2;
|
|
98
|
-
await awardXP(whose(user), xp);
|
|
99
|
-
return Response.json({ success: true, saved: ids.length, xp, already });
|
|
100
|
-
}
|
|
101
|
-
|
|
102
42
|
if (action === 'mark-accepted') {
|
|
103
43
|
db.prepare(`UPDATE linkedin_connections SET outreach_status = 'accepted', updated_at = ? WHERE id IN (${inList(ids)})`).run(now, ...ids);
|
|
104
44
|
return Response.json({ success: true, saved: ids.length, xp: 0, accepts: XP_ACCEPT[bestTier(rows)] || 5 });
|
|
@@ -59,7 +59,7 @@ export async function POST(request) {
|
|
|
59
59
|
await supabase.from('notifications').insert([{
|
|
60
60
|
type: 'connection_accepted',
|
|
61
61
|
title: `${item.name} accepted!`,
|
|
62
|
-
message: `+${item.xp_reward} XP
|
|
62
|
+
message: `+${item.xp_reward} XP · Ready to scan their cluster`,
|
|
63
63
|
icon: '🎉',
|
|
64
64
|
}]);
|
|
65
65
|
}
|
|
@@ -3,16 +3,21 @@ import { existsSync, readFileSync, mkdirSync, mkdtempSync, rmSync } from 'node:f
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { projectRoot, dataDir } from '../../../lib/paths';
|
|
5
5
|
import { resolveProfile, networkCounts } from '../../../lib/profile';
|
|
6
|
-
import { scanProgress } from '../../../lib/scan-progress';
|
|
7
|
-
import { linkedinState, writeLimits, liftCooldown } from '../../../lib/linkedin-limits';
|
|
6
|
+
import { scanProgress, mappingNow } from '../../../lib/scan-progress';
|
|
7
|
+
import { linkedinState, linkedinUsage, writeLimits, liftCooldown } from '../../../lib/linkedin-limits';
|
|
8
8
|
import { pausedList, readProgress, readUnclear } from '../../../lib/paused';
|
|
9
|
-
import { getDb } from '../../../lib/db-client';
|
|
9
|
+
import { getDb, backUpDailyIfDue } from '../../../lib/db-client';
|
|
10
10
|
import { db as notesDb } from '../../../lib/db';
|
|
11
11
|
import { scanDoneNotification } from '../../../lib/notifications';
|
|
12
|
-
import { registerScanState } from '../../../lib/scan-state';
|
|
12
|
+
import { registerScanState, runningNow } from '../../../lib/scan-state';
|
|
13
13
|
import { pendingImport } from '../../../lib/data-import';
|
|
14
14
|
import { waitingPhotoCount } from '../../../lib/photos';
|
|
15
|
+
import { readSettings } from '../../../lib/settings';
|
|
16
|
+
import { riskAccepted, touchesLinkedIn, RISK_REFUSAL } from '../../../lib/scan-risk';
|
|
15
17
|
import { reachIndex, circleState } from '../../../lib/reach';
|
|
18
|
+
import { chromeInstalled, signedInFrom, SIGNED_IN_FILE, CHROME_REFUSAL } from '../../../lib/scanner-setup';
|
|
19
|
+
import { AUTO_REFUSAL, connectResultIn, connectMarks, inviteRefusal, personRefusal } from '../../../lib/auto-connect';
|
|
20
|
+
import { markSentRows, awardXP, whose, requestStanding } from '../../../lib/requests';
|
|
16
21
|
import {
|
|
17
22
|
pythonLooker, thisHostKey, scannerCommand, installSteps, downloadedPython, downloadVerified,
|
|
18
23
|
placeDownloadedPython, sweepSetupLeftovers, megabytes, SETUP_WORK_PREFIX, ScannerSetupError,
|
|
@@ -47,6 +52,9 @@ const state = registerScanState({
|
|
|
47
52
|
stderrTail: [],
|
|
48
53
|
failure: null, // the last lines of stderr from a run that failed — its reason
|
|
49
54
|
pages: 0, // pages the running scan has read: the dots along the header's line (app/components/ScanTrail.js)
|
|
55
|
+
found: [], // how many people each of those pages found: the Scan page's cluster (app/components/ScanRadar.js)
|
|
56
|
+
invitee: null, // Auto's person: { id, name, profileUrl, userId, bridgeId }, looked up here (connectTarget)
|
|
57
|
+
outcome: null, // how Auto's request went: the scanner's "Connect result: …" line (lib/auto-connect.js)
|
|
50
58
|
});
|
|
51
59
|
|
|
52
60
|
// A page read, as scripts/scrape.py prints it: " Page 3... " as a circle or a
|
|
@@ -54,6 +62,10 @@ const state = registerScanState({
|
|
|
54
62
|
// people of your own connections list. Counted as the lines arrive, since the
|
|
55
63
|
// log only keeps its last MAX_LOG lines.
|
|
56
64
|
const PAGE_READ = /^\s*Page \d+\.\.\.|\d+\s*\/\s*\d+\s+collected/;
|
|
65
|
+
// What a page found, which the scanner prints after "Page N... " once it's read:
|
|
66
|
+
// "10 found (total: 30)" in a circle, "7 found (2 with images)" for a company.
|
|
67
|
+
const PAGE_FOUND = /(\d+) found \((?:total: \d+|\d+ with images)\)/;
|
|
68
|
+
const MAX_PAGES_KEPT = 400;
|
|
57
69
|
|
|
58
70
|
/** Stop the running job without orphaning the browser it opened.
|
|
59
71
|
*
|
|
@@ -83,7 +95,7 @@ function stopChild() {
|
|
|
83
95
|
spawn('taskkill', ['/pid', String(pid), '/T'], { stdio: 'ignore', windowsHide: true }).on('error', () => {});
|
|
84
96
|
setTimeout(() => {
|
|
85
97
|
if (state.child && state.child.pid === pid) {
|
|
86
|
-
push('Still running
|
|
98
|
+
push('Still running. Forcing it to stop.');
|
|
87
99
|
spawn('taskkill', ['/pid', String(pid), '/T', '/F'], { stdio: 'ignore', windowsHide: true }).on('error', () => {});
|
|
88
100
|
}
|
|
89
101
|
}, 5000);
|
|
@@ -94,7 +106,7 @@ function stopChild() {
|
|
|
94
106
|
|
|
95
107
|
setTimeout(() => {
|
|
96
108
|
if (state.child && state.child.pid === pid) {
|
|
97
|
-
push('Still running
|
|
109
|
+
push('Still running. Forcing it to stop.');
|
|
98
110
|
try { process.kill(-pid, 'SIGKILL'); }
|
|
99
111
|
catch { try { child.kill('SIGKILL'); } catch {} }
|
|
100
112
|
}
|
|
@@ -106,7 +118,17 @@ function push(line) {
|
|
|
106
118
|
const t = part.replace(/\s+$/, '');
|
|
107
119
|
if (!t) continue;
|
|
108
120
|
state.log.push(t);
|
|
109
|
-
if (PAGE_READ.test(t))
|
|
121
|
+
if (PAGE_READ.test(t)) {
|
|
122
|
+
state.pages += 1;
|
|
123
|
+
// Fifty of your own list at a time; a page's count comes on its next line.
|
|
124
|
+
state.found.push(/collected/.test(t) ? 50 : 0);
|
|
125
|
+
if (state.found.length > MAX_PAGES_KEPT) state.found.splice(0, state.found.length - MAX_PAGES_KEPT);
|
|
126
|
+
}
|
|
127
|
+
const got = t.match(PAGE_FOUND);
|
|
128
|
+
if (got && state.found.length) state.found[state.found.length - 1] = Number(got[1]);
|
|
129
|
+
// Auto's one line saying how the request went (scrape.py main, --connect).
|
|
130
|
+
const result = state.action === 'connect' && connectResultIn(t);
|
|
131
|
+
if (result) state.outcome = result;
|
|
110
132
|
}
|
|
111
133
|
if (state.log.length > MAX_LOG) state.log.splice(0, state.log.length - MAX_LOG);
|
|
112
134
|
}
|
|
@@ -208,12 +230,12 @@ function pickedPerson(id) {
|
|
|
208
230
|
}
|
|
209
231
|
}
|
|
210
232
|
|
|
211
|
-
// The
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
// running job
|
|
215
|
-
// every call: the page polls every 1.5 s,
|
|
216
|
-
// 4 s looks stuck.
|
|
233
|
+
// The look for a Python spawns processes, so it is cached for a few seconds,
|
|
234
|
+
// and callers that arrive while a look is under way share it rather than each
|
|
235
|
+
// starting their own Pythons. Everything else (Chrome and signed in, which are
|
|
236
|
+
// file checks; the running job, its log, how far it has got; the counts) is
|
|
237
|
+
// read fresh on every call: the page polls every 1.5 s, a progress bar that
|
|
238
|
+
// moves every 4 s looks stuck, and step 1 ticks the moment Chrome is installed.
|
|
217
239
|
let cached = { at: 0, value: null };
|
|
218
240
|
let looking = null;
|
|
219
241
|
let lookGeneration = 0;
|
|
@@ -251,26 +273,38 @@ async function look() {
|
|
|
251
273
|
host: hostOnce(),
|
|
252
274
|
});
|
|
253
275
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
process.platform === 'darwin' ? existsSync('/Applications/Google Chrome.app')
|
|
257
|
-
: process.platform === 'linux' ? existsSync('/opt/google/chrome/chrome')
|
|
258
|
-
: process.platform === 'win32' ? windowsChrome()
|
|
259
|
-
: true; // elsewhere Playwright resolves the channel itself
|
|
276
|
+
return { root, python };
|
|
277
|
+
}
|
|
260
278
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
279
|
+
/** Google Chrome, where Playwright's "chrome" channel looks (lib/scanner-setup.js). A file check, so cheap enough for every POST. */
|
|
280
|
+
function chromeHere() {
|
|
281
|
+
return chromeInstalled({ platform: process.platform, env: process.env, exists: existsSync });
|
|
282
|
+
}
|
|
264
283
|
|
|
265
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Signed in to LinkedIn in the scanner's Chrome: the scanner's own note once
|
|
286
|
+
* it has confirmed the session (lib/scanner-setup.js signedInFrom). A folder
|
|
287
|
+
* from before the note goes by Chrome's cookie file, as it always did; Windows'
|
|
288
|
+
* Chrome keeps that one folder down, in Default\Network.
|
|
289
|
+
*/
|
|
290
|
+
function signedIn() {
|
|
291
|
+
const data = dataDir();
|
|
292
|
+
let note = null;
|
|
293
|
+
try { note = JSON.parse(readFileSync(path.join(data, SIGNED_IN_FILE), 'utf8')); } catch { /* none yet, or unreadable: the old check */ }
|
|
294
|
+
const profile = path.join(data, 'chrome-profile', 'Default');
|
|
295
|
+
return signedInFrom({
|
|
296
|
+
note,
|
|
297
|
+
profile: existsSync(path.join(data, 'chrome-profile')),
|
|
298
|
+
cookies: existsSync(path.join(profile, 'Cookies')) || existsSync(path.join(profile, 'Network', 'Cookies')),
|
|
299
|
+
});
|
|
266
300
|
}
|
|
267
301
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
302
|
+
// The "I understand" before the first scan: given on the Scan page, or implied by
|
|
303
|
+
// the scanner's own Chrome profile, which only a scan before it could have made.
|
|
304
|
+
function scanRisk() {
|
|
305
|
+
let acceptedAt = null;
|
|
306
|
+
try { acceptedAt = readSettings(getDb()).scanRiskAccepted; } catch { /* unreadable: ask */ }
|
|
307
|
+
return riskAccepted({ acceptedAt, scannedBefore: existsSync(path.join(dataDir(), 'chrome-profile')) });
|
|
274
308
|
}
|
|
275
309
|
|
|
276
310
|
function machineChecks() {
|
|
@@ -309,6 +343,7 @@ function paused(userId) {
|
|
|
309
343
|
|
|
310
344
|
async function status() {
|
|
311
345
|
const m = await machineChecks();
|
|
346
|
+
const chrome = chromeHere();
|
|
312
347
|
|
|
313
348
|
// How much is already mapped, by degree, so the page can mark the scan step
|
|
314
349
|
// done and offer the way to the galaxy instead of leaving someone on a form.
|
|
@@ -325,7 +360,9 @@ async function status() {
|
|
|
325
360
|
|
|
326
361
|
const py = m.python;
|
|
327
362
|
return {
|
|
328
|
-
ready: Boolean(m.root && py.run &&
|
|
363
|
+
ready: Boolean(m.root && py.run && chrome),
|
|
364
|
+
// Whose circle is being read now, for the Scan page's "Watch it fill in".
|
|
365
|
+
mapping: mappingWho(me?.id),
|
|
329
366
|
checks: {
|
|
330
367
|
scriptsFound: Boolean(m.root),
|
|
331
368
|
// A Python that runs the scanner, or one Install can build its environment from.
|
|
@@ -344,8 +381,10 @@ async function status() {
|
|
|
344
381
|
systemPython: py.systemFound,
|
|
345
382
|
// What "Set up the scanner" would download, when there is nothing to install from.
|
|
346
383
|
download: py.download ? { version: py.download.version, size: py.download.size, from: 'github.com' } : null,
|
|
347
|
-
chrome
|
|
348
|
-
signedIn:
|
|
384
|
+
chrome,
|
|
385
|
+
signedIn: signedIn(),
|
|
386
|
+
// The one-time "I understand" before the first scan (lib/scan-risk.js).
|
|
387
|
+
riskAccepted: scanRisk(),
|
|
349
388
|
},
|
|
350
389
|
network,
|
|
351
390
|
photosWaiting,
|
|
@@ -356,6 +395,28 @@ async function status() {
|
|
|
356
395
|
};
|
|
357
396
|
}
|
|
358
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Whose circle the running scan is reading: { id, name } of one of your
|
|
400
|
+
* connections, or null. A scan of one person knows its target; a batch (Map
|
|
401
|
+
* 2nd degree, every paused list) prints each person's name as it starts
|
|
402
|
+
* (lib/scan-progress.js mappingNow), found here among your connections. Two
|
|
403
|
+
* with that name can't be told apart that way, so neither is named.
|
|
404
|
+
*/
|
|
405
|
+
function mappingWho(userId) {
|
|
406
|
+
if (!state.running) return null;
|
|
407
|
+
if (state.target?.id && ['bridge', 'rescrape', 'resume'].includes(state.action)) return { id: state.target.id, name: state.target.name };
|
|
408
|
+
const name = mappingNow(state.log, state.action);
|
|
409
|
+
if (!name || !userId) return null;
|
|
410
|
+
try {
|
|
411
|
+
const rows = getDb().prepare(
|
|
412
|
+
'SELECT id FROM linkedin_connections WHERE user_id = ? AND degree = 1 AND name = ? LIMIT 2',
|
|
413
|
+
).all(userId, name);
|
|
414
|
+
return rows.length === 1 ? { id: rows[0].id, name } : null;
|
|
415
|
+
} catch {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
359
420
|
/**
|
|
360
421
|
* The running job alone, from memory: no checks, no database. Every Scan
|
|
361
422
|
* button in the app asks this (lib/scraper-client.js watchScanner), every few
|
|
@@ -375,6 +436,7 @@ function job() {
|
|
|
375
436
|
failure: state.running ? null : state.failure,
|
|
376
437
|
progress: state.running ? scanProgress(state.log, state.action) : null,
|
|
377
438
|
pages: state.running ? state.pages : 0,
|
|
439
|
+
found: state.running ? state.found : [],
|
|
378
440
|
log: state.log.slice(-120),
|
|
379
441
|
recent: state.recent,
|
|
380
442
|
budget: state.running ? budgetNow() : null,
|
|
@@ -425,6 +487,16 @@ export async function GET(request) {
|
|
|
425
487
|
if (q.has('job')) return Response.json(job());
|
|
426
488
|
if (q.has('resume')) return Response.json({ resume: resumePoint(q.get('resume')) });
|
|
427
489
|
if (q.has('reach')) return Response.json(scanNotes());
|
|
490
|
+
// Settings → LinkedIn usage: the scanner's record of searches, profile views
|
|
491
|
+
// and pauses, counted (lib/linkedin-limits.js linkedinUsage). Reads only; no
|
|
492
|
+
// checks, no Python, nothing written.
|
|
493
|
+
if (q.has('usage')) {
|
|
494
|
+
try {
|
|
495
|
+
return Response.json(linkedinUsage(dataDir()));
|
|
496
|
+
} catch {
|
|
497
|
+
return Response.json({ error: 'The record of LinkedIn searches on this computer could not be read.' }, { status: 500 });
|
|
498
|
+
}
|
|
499
|
+
}
|
|
428
500
|
if (q.has('person')) return Response.json(pickedPerson(q.get('person')));
|
|
429
501
|
return Response.json(await status());
|
|
430
502
|
}
|
|
@@ -464,8 +536,48 @@ const ACTIONS = {
|
|
|
464
536
|
// 1,000 conversations at most), for the Social tab's "Read my whole history".
|
|
465
537
|
'messages-full': { flag: '--messages --full-history', label: 'Reading your whole messages history' },
|
|
466
538
|
photos: { flag: '--save-photos', label: 'Saving profile photos to this computer' },
|
|
539
|
+
// Auto (Blake, 2026-10-03): one connection request, without a note, to one
|
|
540
|
+
// person pressed on a card. By id, looked up here (connectTarget); the URL
|
|
541
|
+
// and name that reach the command line come from the database, never the page.
|
|
542
|
+
connect: { flag: '--connect', label: 'Sending a connection request to' },
|
|
467
543
|
};
|
|
468
544
|
|
|
545
|
+
/**
|
|
546
|
+
* Auto's person, by id: { person: { id, name, profileUrl, userId, bridgeId } },
|
|
547
|
+
* or why not: { error, status }. Anyone in your network on this computer with a
|
|
548
|
+
* LinkedIn profile who isn't already one of your connections (no copy of them
|
|
549
|
+
* at degree 1) and has no request out. The URL is checked like every other
|
|
550
|
+
* that reaches a command line.
|
|
551
|
+
*/
|
|
552
|
+
function connectTarget(id) {
|
|
553
|
+
try {
|
|
554
|
+
const me = resolveProfile({ create: false });
|
|
555
|
+
const db = getDb();
|
|
556
|
+
const row = me && db.prepare(
|
|
557
|
+
'SELECT id, name, degree, profile_url, source_connection_id FROM linkedin_connections WHERE id = ? AND user_id = ?',
|
|
558
|
+
).get(String(id ?? ''), me.id);
|
|
559
|
+
if (!row) return personRefusal(null);
|
|
560
|
+
const why = personRefusal(row, requestStanding(db, { profileUrl: row.profile_url, userId: me.id }));
|
|
561
|
+
if (why) return why;
|
|
562
|
+
const profileUrl = cleanProfileUrl(row.profile_url);
|
|
563
|
+
if (!profileUrl) return { status: 400, error: `${row.name || 'Their'} LinkedIn profile address on file can’t be used.` };
|
|
564
|
+
return {
|
|
565
|
+
person: {
|
|
566
|
+
id: row.id, name: cleanName(row.name) || null, profileUrl, userId: me.id,
|
|
567
|
+
// Who you'd be asking through: the connection whose circle they're in.
|
|
568
|
+
bridgeId: row.degree === 2 ? row.source_connection_id ?? null : null,
|
|
569
|
+
},
|
|
570
|
+
};
|
|
571
|
+
} catch {
|
|
572
|
+
return personRefusal(null);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** Auto's one-time yes (lib/auto-connect.js), given on the page that first offers it. */
|
|
577
|
+
function autoAccepted() {
|
|
578
|
+
try { return Boolean(readSettings(getDb()).autoConnectAccepted); } catch { return false; }
|
|
579
|
+
}
|
|
580
|
+
|
|
469
581
|
/** Only a plain linkedin.com/in/ profile URL becomes an argument. */
|
|
470
582
|
function cleanProfileUrl(raw) {
|
|
471
583
|
const url = String(raw ?? '').trim();
|
|
@@ -586,6 +698,26 @@ export async function POST(request) {
|
|
|
586
698
|
if (!Object.hasOwn(ACTIONS, action)) {
|
|
587
699
|
return Response.json({ error: `Unknown action '${action}'` }, { status: 400 });
|
|
588
700
|
}
|
|
701
|
+
// Auto: who, by id, and whether a request can go to them at all, before
|
|
702
|
+
// anything else is asked. Then its own one-time yes (the page asks it).
|
|
703
|
+
let invitee = null;
|
|
704
|
+
if (action === 'connect') {
|
|
705
|
+
const found = connectTarget(body.id);
|
|
706
|
+
if (found.error) return Response.json({ error: found.error }, { status: found.status });
|
|
707
|
+
invitee = found.person;
|
|
708
|
+
if (!autoAccepted()) return Response.json({ error: AUTO_REFUSAL, needsAutoAcceptance: true }, { status: 409 });
|
|
709
|
+
}
|
|
710
|
+
// Nothing opens LinkedIn before the one-time "I understand" on the Scan page,
|
|
711
|
+
// whichever button asked (lib/scan-risk.js).
|
|
712
|
+
if (touchesLinkedIn(action) && !scanRisk()) {
|
|
713
|
+
return Response.json({ error: RISK_REFUSAL, needsRiskAcceptance: true }, { status: 409 });
|
|
714
|
+
}
|
|
715
|
+
// Nor without Google Chrome, which the scanner drives: the Scan page's step 1
|
|
716
|
+
// says so in the same words, and every other button is told here, before
|
|
717
|
+
// anything starts, rather than by a Playwright error at the end of a log.
|
|
718
|
+
if (touchesLinkedIn(action) && !chromeHere()) {
|
|
719
|
+
return Response.json({ error: CHROME_REFUSAL, needsChrome: true }, { status: 409 });
|
|
720
|
+
}
|
|
589
721
|
|
|
590
722
|
const spec = ACTIONS[action];
|
|
591
723
|
const maxBridges = Number.isInteger(body.maxBridges) && body.maxBridges > 0
|
|
@@ -631,12 +763,14 @@ export async function POST(request) {
|
|
|
631
763
|
// never reaches the command line (a name or the URL looked up for it does),
|
|
632
764
|
// and anything not shaped like one of our ids is dropped.
|
|
633
765
|
const hintId = typeof body.id === 'string' && /^[\w-]{1,64}$/.test(body.id) ? body.id : null;
|
|
634
|
-
const target =
|
|
766
|
+
const target = invitee ? { id: invitee.id, name: invitee.name }
|
|
767
|
+
: name || profileUrl ? { id: hintId, name: name || person?.name || null } : null;
|
|
635
768
|
// Nothing that searches LinkedIn starts during a cooldown; the scanner checks
|
|
636
769
|
// too, this just says so before a process is spawned.
|
|
637
770
|
// The 1st-degree scans aren't searches, but they open LinkedIn with automation too.
|
|
771
|
+
// Auto's request too: a pause after LinkedIn pushed back holds everything.
|
|
638
772
|
const searches = spec.searches || action.startsWith('auto-bridge')
|
|
639
|
-
|| ['bridge', 'rescrape', 'company', 'full', 'refresh'].includes(action);
|
|
773
|
+
|| ['bridge', 'rescrape', 'company', 'full', 'refresh', 'connect'].includes(action);
|
|
640
774
|
// A staged import replaces the network at the next start, so anything scanned
|
|
641
775
|
// now would land in the copy that is about to be set aside. Setting the
|
|
642
776
|
// scanner up touches no network data.
|
|
@@ -645,9 +779,17 @@ export async function POST(request) {
|
|
|
645
779
|
}
|
|
646
780
|
const cooldown = linkedinState(dataDir()).cooldown;
|
|
647
781
|
if (searches && cooldown) {
|
|
648
|
-
return Response.json({ error: `Scanning is paused until ${new Date(cooldown.until).toLocaleString()}
|
|
782
|
+
return Response.json({ error: `Scanning is paused until ${new Date(cooldown.until).toLocaleString()}: ${cooldown.reason}.`, cooldown }, { status: 409 });
|
|
783
|
+
}
|
|
784
|
+
// Auto's caps (15 in any 24 hours, 80 in any 7 days) and the profile view it
|
|
785
|
+
// takes, said before a process starts; the scanner checks them again.
|
|
786
|
+
if (invitee) {
|
|
787
|
+
const capped = inviteRefusal(linkedinState(dataDir()));
|
|
788
|
+
if (capped) return Response.json({ error: capped }, { status: 409 });
|
|
649
789
|
}
|
|
650
790
|
if (state.running) {
|
|
791
|
+
// One thing at a time: Auto waits for a scan like any other job.
|
|
792
|
+
if (invitee) return Response.json({ error: `${runningNow(state.action)}. Press Auto again once it has finished.`, action: state.action }, { status: 409 });
|
|
651
793
|
return Response.json({ error: 'Something is already running.', action: state.action }, { status: 409 });
|
|
652
794
|
}
|
|
653
795
|
|
|
@@ -683,7 +825,8 @@ export async function POST(request) {
|
|
|
683
825
|
// "-" can then never be read as a flag of its own. Anyone found by
|
|
684
826
|
// id is --bridge-url, which carries on where their last read stopped
|
|
685
827
|
// unless told to start at page 1.
|
|
686
|
-
...(
|
|
828
|
+
...(invitee ? [`--connect=${invitee.profileUrl}`, ...(invitee.name ? [`--connect-name=${invitee.name}`] : [])]
|
|
829
|
+
: name ? [`${spec.flag}=${name}`] : profileUrl ? [`--bridge-url=${profileUrl}`] : spec.flag.split(' ')),
|
|
687
830
|
...(profileUrl && action === 'bridge' && !deeper ? ['--from-start'] : []),
|
|
688
831
|
...(maxBridges && (action.startsWith('auto-bridge') || action === 'resume-all') ? [`--max-bridges=${maxBridges}`] : []),
|
|
689
832
|
...(tiers.length && action.startsWith('auto-bridge') ? [`--tiers=${tiers.join(',')}`] : []),
|
|
@@ -714,8 +857,11 @@ export async function POST(request) {
|
|
|
714
857
|
state.startedAt = Date.now();
|
|
715
858
|
state.log = [spec.label + (target?.name ? ` ${target.name}…` : '…')];
|
|
716
859
|
state.pages = 0;
|
|
860
|
+
state.found = [];
|
|
717
861
|
state.stderrTail = [];
|
|
718
862
|
state.failure = null;
|
|
863
|
+
state.invitee = invitee;
|
|
864
|
+
state.outcome = null;
|
|
719
865
|
forgetChecks();
|
|
720
866
|
|
|
721
867
|
// Name the profile outright. The scraper would otherwise ask the app which one
|
|
@@ -733,7 +879,29 @@ export async function POST(request) {
|
|
|
733
879
|
SIX_DEGREES_FROM_APP: '1',
|
|
734
880
|
};
|
|
735
881
|
|
|
882
|
+
/**
|
|
883
|
+
* Auto: a request LinkedIn showed as pending (or one already pending there)
|
|
884
|
+
* is marked as sent through the same store as the Connect button
|
|
885
|
+
* (lib/requests.js), before the job is seen to end, so every view that looks
|
|
886
|
+
* next finds it; its XP follows. Anything else marks nothing (TRAPS §7).
|
|
887
|
+
*/
|
|
888
|
+
function markAutoSent() {
|
|
889
|
+
const who = state.invitee;
|
|
890
|
+
if (state.action !== 'connect' || !who || who.marked || !connectMarks(state.outcome)) return;
|
|
891
|
+
who.marked = true;
|
|
892
|
+
try {
|
|
893
|
+
const { saved, xp, user } = markSentRows(getDb(), {
|
|
894
|
+
connectionId: who.id, profileUrl: who.profileUrl, userId: who.userId, bridgeId: who.bridgeId,
|
|
895
|
+
});
|
|
896
|
+
if (saved) Promise.resolve(awardXP(whose(user), xp)).catch(() => {});
|
|
897
|
+
push('Marked as sent in Six Degrees.');
|
|
898
|
+
} catch (err) {
|
|
899
|
+
push(`Sent on LinkedIn, but it couldn’t be marked as sent here: ${err.message}`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
736
903
|
function finish(code) {
|
|
904
|
+
markAutoSent();
|
|
737
905
|
// A failure must say why. stderr is filtered while running because pip and
|
|
738
906
|
// Playwright are noisy there, and that filter once swallowed the only line
|
|
739
907
|
// explaining a failed scan, leaving just "exit 1". On a failure, show the
|
|
@@ -757,6 +925,8 @@ export async function POST(request) {
|
|
|
757
925
|
state.exitCode = code;
|
|
758
926
|
state.recent = [{
|
|
759
927
|
action: state.action, target: state.target, startedAt: state.startedAt, exitCode: code, failure: state.failure,
|
|
928
|
+
// How Auto's request went, for the button that started it (lib/auto-connect.js connectOutcome).
|
|
929
|
+
...(state.action === 'connect' ? { outcome: state.outcome } : {}),
|
|
760
930
|
}, ...state.recent].slice(0, 5);
|
|
761
931
|
// A scan that finished leaves a notification ("Scan done: …"); a stop or a failure doesn't.
|
|
762
932
|
const done = scanDoneNotification({ action: state.action, target: state.target, exitCode: code, stopped, log: state.log.slice(-12), userId: profileId || null });
|
|
@@ -766,6 +936,17 @@ export async function POST(request) {
|
|
|
766
936
|
try { cleanup(); } catch { /* swept at the next setup (sweepSetupLeftovers) */ }
|
|
767
937
|
}
|
|
768
938
|
forgetChecks();
|
|
939
|
+
// The daily backup, once a scan may have changed the network (lib/backups.js):
|
|
940
|
+
// checked here and when the server starts, never on a timer. Setting the
|
|
941
|
+
// scanner up and signing in change nothing in it.
|
|
942
|
+
if (!['install', 'setup', 'login'].includes(state.action)) {
|
|
943
|
+
try {
|
|
944
|
+
const daily = backUpDailyIfDue();
|
|
945
|
+
if (daily) push('Made today’s backup of your network (Settings → Your data).');
|
|
946
|
+
} catch (err) {
|
|
947
|
+
push(`Today’s backup couldn’t be made: ${err.message}`);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
769
950
|
}
|
|
770
951
|
|
|
771
952
|
function runStep(i) {
|
|
@@ -5,7 +5,8 @@ import { socialFiles, readJson, writeJsonAtomic } from '../../../../lib/social-s
|
|
|
5
5
|
// The Social tab's CRM: your own stage, tags, notes and next follow-up for each
|
|
6
6
|
// person, in crm-<profile>.json in the data folder (lib/social-crm.js has the
|
|
7
7
|
// shape). Yours, so always kept, whatever Keep my messages says; never sent
|
|
8
|
-
// anywhere,
|
|
8
|
+
// anywhere, never in Six Degrees' own backups (lib/backups.js BACKUP_SOCIAL),
|
|
9
|
+
// and in "Export backup file…" only when its Social box is ticked.
|
|
9
10
|
//
|
|
10
11
|
// GET the whole store
|
|
11
12
|
// PATCH { key, set: { stage?, tags?, notes?, followUp? } } one person's
|