six-degrees 0.4.0-beta.1 → 0.4.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/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +5 -5
- package/.next/standalone/.next/required-server-files.json +6 -1
- package/.next/standalone/.next/routes-manifest.json +12 -1
- 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.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 +11 -11
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +10 -10
- 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 +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bridges/route.js +1 -1
- package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bulk-import/route.js +1 -1
- package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/connections/route.js +1 -1
- package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js +1 -1
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/route.js +1 -1
- package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/network/route.js +1 -1
- package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/outreach/route.js +1 -1
- package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/queue/route.js +1 -1
- package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/setup-profile/route.js +1 -1
- package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/unlock/route.js +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/users/route.js +1 -1
- package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page.js.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 +13 -13
- package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +13 -13
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 +13 -13
- package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- 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.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 +13 -13
- package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- 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 +13 -13
- package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- 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 +13 -13
- package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- 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 +13 -13
- package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- 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 +13 -13
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- 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 +13 -13
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +13 -13
- 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 +12 -12
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +1 -1
- 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]__0i5hdu4._.js → [root-of-the-server]__03ydxxh._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0rc27za._.js → [root-of-the-server]__0bat8nx._.js} +2 -2
- 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]__0ljcioj._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__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]__0t3v1a1._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uag-k5._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0um1uey._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
- 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]__14ou7j5._.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]__16iu0hv._.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]__1bbcwub._.js +2 -2
- 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]__1kbl21f._.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]__1rphsdk._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -6
- 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/lib_db-client_15le7cw.js +12 -8
- package/.next/standalone/.next/server/chunks/{lib_rpc_02ndsg2.js → lib_rpc_03i8xef.js} +1 -1
- package/.next/standalone/.next/server/chunks/{lib_rpc_08q5vp6.js → lib_rpc_08fc3rp.js} +1 -1
- package/.next/standalone/.next/server/chunks/{lib_rpc_00tx2sm.js → lib_rpc_08r2t_q.js} +1 -1
- package/.next/standalone/.next/server/chunks/{lib_rpc_02-qa4d.js → lib_rpc_0btpv1t.js} +1 -1
- package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +5 -5
- package/.next/standalone/.next/server/chunks/lib_rpc_0cm2ev3.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0iovswz.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0is8flp.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0v8ajtd.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0xgmvvt.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_144mzbf.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1bggi0n.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1dkcu9f.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1o0jb6w.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_01f38ty._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_06w_gl4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0hw_qnj._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_13kzrwv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_15xuwkv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1gpbbw9._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1hgd5dp._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0cu6-an._.js → _1vpfyd-._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_20w06i-._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.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 +11 -9
- package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +1 -1
- 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 +5 -5
- package/.next/standalone/.next/server/chunks/ssr/app_scores_page_09wepvv.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/lib_1bn38gs._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_client_components_server-async-storage_0t1dato.js +3 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- 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/0ax_9zzboyv6d.js +44 -0
- package/.next/standalone/.next/static/chunks/0cuuo2jwc9h94.js +1 -0
- package/.next/standalone/.next/static/chunks/0l1568qff0efj.js +1 -0
- package/.next/standalone/.next/static/chunks/0muwt9bykzr-1.js +1 -0
- package/.next/standalone/.next/static/chunks/0w76iraw7ij3k.js +18 -0
- package/.next/standalone/.next/static/chunks/135n87ydxjrra.js +2 -0
- package/.next/standalone/.next/static/chunks/18xu0fbgo_qz-.js +1 -0
- package/.next/standalone/.next/static/chunks/28bu26ausqzmn.js +1 -0
- package/.next/standalone/.next/static/chunks/{40nvbgfn7-072.css → 2p6o90z0vgcwr.css} +1 -1
- package/.next/standalone/.next/static/chunks/2pnbm1z6j7xab.js +1 -0
- package/.next/standalone/.next/static/chunks/2xjho0lroiwlq.js +1 -0
- package/.next/standalone/.next/static/chunks/3e8zg6ctvvb8p.js +33 -0
- package/.next/standalone/.next/static/chunks/3qh78g2aqhprd.js +2 -0
- package/.next/standalone/CHANGELOG.md +152 -0
- package/.next/standalone/CONTRIBUTING.md +15 -4
- package/.next/standalone/README.md +21 -15
- package/.next/standalone/SECURITY.md +10 -0
- package/.next/standalone/app/api/ingest/route.js +6 -1
- package/.next/standalone/app/api/scraper/route.js +79 -11
- package/.next/standalone/app/api/update-images/route.js +41 -7
- package/.next/standalone/app/avatars/[file]/route.js +6 -1
- package/.next/standalone/app/components/Avatar.js +5 -2
- package/.next/standalone/app/components/ChainView.js +659 -469
- package/.next/standalone/app/components/EmptyState.js +1 -1
- package/.next/standalone/app/components/FieldStep.js +94 -0
- package/.next/standalone/app/components/ForceGraph.js +183 -768
- package/.next/standalone/app/components/GridView.js +9 -7
- package/.next/standalone/app/components/LinkedInLimits.js +22 -7
- package/.next/standalone/app/components/ListView.js +6 -4
- package/.next/standalone/app/components/MappingProgress.js +5 -6
- package/.next/standalone/app/components/OnboardingGate.js +1 -1
- package/.next/standalone/app/components/OrbitGraph.js +3 -1
- package/.next/standalone/app/components/OutlinkQuest.js +5 -4
- package/.next/standalone/app/components/RingsView.js +9 -8
- package/.next/standalone/app/components/Sidebar.js +172 -112
- package/.next/standalone/app/components/TheirCircle.js +18 -11
- package/.next/standalone/app/components/settings/SectorPicker.js +202 -0
- package/.next/standalone/app/components/settings/SectorSection.js +17 -191
- package/.next/standalone/app/components/settings/TierSection.js +7 -12
- package/.next/standalone/app/components/views.js +2 -2
- package/.next/standalone/app/globals.css +7 -0
- package/.next/standalone/app/launch/page.js +2 -2
- package/.next/standalone/app/page.js +130 -25
- package/.next/standalone/app/paths/page.js +3 -2
- package/.next/standalone/app/queue/page.js +18 -10
- package/.next/standalone/app/setup/page.js +423 -260
- package/.next/standalone/db/schema.js +1 -1
- package/.next/standalone/eslint.config.mjs +3 -3
- package/.next/standalone/install.sh +3 -3
- package/.next/standalone/lib/chain-layout.js +139 -0
- package/.next/standalone/lib/csv.js +4 -6
- package/.next/standalone/lib/data-export.js +2 -1
- package/.next/standalone/lib/data-folder.js +4 -2
- package/.next/standalone/lib/galaxy.js +12 -0
- package/.next/standalone/lib/ingest.js +15 -8
- package/.next/standalone/lib/linkedin-limits.js +30 -8
- package/.next/standalone/lib/photos.js +47 -0
- package/.next/standalone/lib/quest.js +8 -3
- package/.next/standalone/lib/reach.js +113 -0
- package/.next/standalone/lib/scan-state.js +1 -0
- package/.next/standalone/lib/scanner-setup.js +20 -1
- package/.next/standalone/lib/scoring.js +769 -18
- package/.next/standalone/lib/scraper-client.js +27 -0
- package/.next/standalone/lib/sector-focus.js +13 -0
- package/.next/standalone/lib/separation.js +4 -2
- package/.next/standalone/lib/settings-client.js +21 -0
- package/.next/standalone/lib/settings.js +3 -1
- package/.next/standalone/next.config.mjs +25 -3
- package/.next/standalone/package-lock.json +2 -2
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/build-app.mjs +11 -2
- package/.next/standalone/scripts/check-node.mjs +1 -1
- package/.next/standalone/scripts/image_store.py +77 -21
- package/.next/standalone/scripts/scrape.py +243 -29
- package/.next/standalone/server.js +1 -1
- package/.next/static/chunks/0ax_9zzboyv6d.js +44 -0
- package/.next/static/chunks/0cuuo2jwc9h94.js +1 -0
- package/.next/static/chunks/0l1568qff0efj.js +1 -0
- package/.next/static/chunks/0muwt9bykzr-1.js +1 -0
- package/.next/static/chunks/0w76iraw7ij3k.js +18 -0
- package/.next/static/chunks/135n87ydxjrra.js +2 -0
- package/.next/static/chunks/18xu0fbgo_qz-.js +1 -0
- package/.next/static/chunks/28bu26ausqzmn.js +1 -0
- package/.next/static/chunks/{40nvbgfn7-072.css → 2p6o90z0vgcwr.css} +1 -1
- package/.next/static/chunks/2pnbm1z6j7xab.js +1 -0
- package/.next/static/chunks/2xjho0lroiwlq.js +1 -0
- package/.next/static/chunks/3e8zg6ctvvb8p.js +33 -0
- package/.next/static/chunks/3qh78g2aqhprd.js +2 -0
- package/CHANGELOG.md +152 -0
- package/README.md +21 -15
- package/SECURITY.md +10 -0
- package/db/schema.js +1 -1
- package/lib/chain-layout.js +139 -0
- package/lib/csv.js +4 -6
- package/lib/data-export.js +2 -1
- package/lib/data-folder.js +4 -2
- package/lib/galaxy.js +12 -0
- package/lib/ingest.js +15 -8
- package/lib/linkedin-limits.js +30 -8
- package/lib/photos.js +47 -0
- package/lib/quest.js +8 -3
- package/lib/reach.js +113 -0
- package/lib/scan-state.js +1 -0
- package/lib/scanner-setup.js +20 -1
- package/lib/scoring.js +769 -18
- package/lib/scraper-client.js +27 -0
- package/lib/sector-focus.js +13 -0
- package/lib/separation.js +4 -2
- package/lib/settings-client.js +21 -0
- package/lib/settings.js +3 -1
- package/package.json +1 -1
- package/scripts/check-node.mjs +1 -1
- package/scripts/image_store.py +77 -21
- package/scripts/scrape.py +243 -29
- package/.next/standalone/.next/server/chunks/lib_rpc_0_8i3ft.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0huvw-3.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0ip2vdh.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0yi9xvd.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1jyhd0o.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1kn59-i.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1q2jkza.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1vpm1sk.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1x6p_31.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0223v9s._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0bcf13g._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0wxbq78._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0z88zcl._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1-87bs1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_17gui6a._.js +0 -3
- package/.next/standalone/.next/static/chunks/0_yurn4q91vq8.js +0 -16
- package/.next/standalone/.next/static/chunks/0d_mh-06srh2k.js +0 -1
- package/.next/standalone/.next/static/chunks/0x3oadfikvb1c.js +0 -1
- package/.next/standalone/.next/static/chunks/1d5hl1io798n2.js +0 -1
- package/.next/standalone/.next/static/chunks/1qt67cvj9sjwi.js +0 -1
- package/.next/standalone/.next/static/chunks/1roznk7hkjes1.js +0 -44
- package/.next/standalone/.next/static/chunks/2_bf2n4gstad9.js +0 -33
- package/.next/standalone/.next/static/chunks/36gbwek52x_w-.js +0 -2
- package/.next/standalone/.next/static/chunks/3a55suosthntc.js +0 -1
- package/.next/standalone/.next/static/chunks/3fq1zq-6cfwbc.js +0 -1
- package/.next/standalone/.next/static/chunks/3nbnio971zlji.js +0 -2
- package/.next/standalone/.next/static/chunks/3s6awp3qq9s7w.js +0 -1
- package/.next/static/chunks/0_yurn4q91vq8.js +0 -16
- package/.next/static/chunks/0d_mh-06srh2k.js +0 -1
- package/.next/static/chunks/0x3oadfikvb1c.js +0 -1
- package/.next/static/chunks/1d5hl1io798n2.js +0 -1
- package/.next/static/chunks/1qt67cvj9sjwi.js +0 -1
- package/.next/static/chunks/1roznk7hkjes1.js +0 -44
- package/.next/static/chunks/2_bf2n4gstad9.js +0 -33
- package/.next/static/chunks/36gbwek52x_w-.js +0 -2
- package/.next/static/chunks/3a55suosthntc.js +0 -1
- package/.next/static/chunks/3fq1zq-6cfwbc.js +0 -1
- package/.next/static/chunks/3nbnio971zlji.js +0 -2
- package/.next/static/chunks/3s6awp3qq9s7w.js +0 -1
- /package/.next/standalone/.next/static/{NnWlxbDF24KhrU1eHiEnv → WseE_5HuU-1q0ywC9CP3U}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{NnWlxbDF24KhrU1eHiEnv → WseE_5HuU-1q0ywC9CP3U}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{NnWlxbDF24KhrU1eHiEnv → WseE_5HuU-1q0ywC9CP3U}/_ssgManifest.js +0 -0
- /package/.next/static/{NnWlxbDF24KhrU1eHiEnv → WseE_5HuU-1q0ywC9CP3U}/_buildManifest.js +0 -0
- /package/.next/static/{NnWlxbDF24KhrU1eHiEnv → WseE_5HuU-1q0ywC9CP3U}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{NnWlxbDF24KhrU1eHiEnv → WseE_5HuU-1q0ywC9CP3U}/_ssgManifest.js +0 -0
package/lib/photos.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Profile photos are shown from this computer only.
|
|
2
|
+
//
|
|
3
|
+
// The scanner saves each photo into the data folder as it reads it
|
|
4
|
+
// (scripts/image_store.py), and the row points at the saved file,
|
|
5
|
+
// `/avatars/<name>`, which app/avatars/[file] serves. A row can also hold a
|
|
6
|
+
// link: LinkedIn's own, which older versions stored until the scanner replaced
|
|
7
|
+
// it, and which a copy of a network made by one carries too. A page never loads
|
|
8
|
+
// a link: it would contact LinkedIn while someone is only looking at their map,
|
|
9
|
+
// and the app goes online only when you act. That person shows initials until
|
|
10
|
+
// the photo is saved, at the next scan or with Save photos on the Scan page.
|
|
11
|
+
// The Content-Security-Policy in next.config.mjs holds the same line in the
|
|
12
|
+
// browser.
|
|
13
|
+
//
|
|
14
|
+
// No imports, so the views and the server share it: every view and the routes
|
|
15
|
+
// that store photos check with localPhoto, and the /avatars route serves the
|
|
16
|
+
// names AVATAR_FILE allows.
|
|
17
|
+
|
|
18
|
+
/** A photo the /avatars route serves: a plain file name, no folders. The route uses this same pattern. */
|
|
19
|
+
export const AVATAR_FILE = /^[A-Za-z0-9_-]+\.(webp|jpg|jpeg|png)$/;
|
|
20
|
+
|
|
21
|
+
const PREFIX = '/avatars/';
|
|
22
|
+
|
|
23
|
+
/** The photo to show for a row's `profile_image_url`: its saved file's path, or null. */
|
|
24
|
+
export function localPhoto(url) {
|
|
25
|
+
if (typeof url !== 'string' || !url.startsWith(PREFIX)) return null;
|
|
26
|
+
return AVATAR_FILE.test(url.slice(PREFIX.length)) ? url : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The photos still kept as links, one per person and link:
|
|
31
|
+
* [{ profileUrl, imageUrl }]. `db` is an open node:sqlite database. The
|
|
32
|
+
* scanner saves each (`GET /api/update-images`), or forgets the link on a
|
|
33
|
+
* definite no, so a link is tried until there's an answer.
|
|
34
|
+
*/
|
|
35
|
+
export function waitingPhotos(db) {
|
|
36
|
+
return db.prepare(`SELECT DISTINCT profile_url AS profileUrl, profile_image_url AS imageUrl
|
|
37
|
+
FROM linkedin_connections
|
|
38
|
+
WHERE profile_image_url IS NOT NULL AND profile_image_url <> ''
|
|
39
|
+
AND substr(profile_image_url, 1, 9) <> '/avatars/'
|
|
40
|
+
ORDER BY profile_url`).all()
|
|
41
|
+
.filter((r) => r.profileUrl && !localPhoto(r.imageUrl));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** How many people have a photo waiting to be saved. */
|
|
45
|
+
export function waitingPhotoCount(db) {
|
|
46
|
+
return new Set(waitingPhotos(db).map((r) => r.profileUrl)).size;
|
|
47
|
+
}
|
package/lib/quest.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
// sent, people who actually joined your network), never from browsing.
|
|
10
10
|
// Plain functions; tests/quest.test.mjs.
|
|
11
11
|
|
|
12
|
+
import { circleState } from './reach.js';
|
|
13
|
+
|
|
12
14
|
export const STAGE_SIZE = 5;
|
|
13
15
|
export const XP_SEND = { S: 25, A: 15, B: 10, C: 5, D: 2 };
|
|
14
16
|
export const XP_ADDED = { S: 100, A: 60, B: 35, C: 15, D: 5 };
|
|
@@ -26,8 +28,9 @@ export function levelFor(points) {
|
|
|
26
28
|
* @param sentIds ids marked "invite sent"
|
|
27
29
|
* @param added 1st-degree people who came through a cluster (unlocked_from_bridge_id set)
|
|
28
30
|
* @param mappedIds ids of 1st-degree people whose own circle is mapped
|
|
31
|
+
* @param reach lib/reach.js reachIndex(), which also knows hidden lists; mappedIds stands in without it
|
|
29
32
|
*/
|
|
30
|
-
export function buildQuest({ recs = [], sentIds = new Set(), added = [], mappedIds = new Set() }) {
|
|
33
|
+
export function buildQuest({ recs = [], sentIds = new Set(), added = [], mappedIds = new Set(), reach = null }) {
|
|
31
34
|
const byBridge = new Map();
|
|
32
35
|
const seen = new Set();
|
|
33
36
|
for (const r of [...recs].sort((a, b) => (b.priority || 0) - (a.priority || 0))) {
|
|
@@ -112,8 +115,10 @@ export function buildQuest({ recs = [], sentIds = new Set(), added = [], mappedI
|
|
|
112
115
|
level: levelFor(points),
|
|
113
116
|
sentTotal,
|
|
114
117
|
addedTotal,
|
|
115
|
-
// People you've added whose own circle
|
|
116
|
-
|
|
118
|
+
// People you've added whose own circle can be scanned: the next degree.
|
|
119
|
+
// Hidden lists aren't doors (lib/reach.js, the rule Bridge Chains uses).
|
|
120
|
+
newDoors: added.filter((a) => a.unlocked_from_bridge_id
|
|
121
|
+
&& circleState(a, reach || { scanned: mappedIds, hidden: new Set() }) === 'todo'),
|
|
117
122
|
clearedStages: clusters.reduce((s, c) => s + (c.stage - 1) + (c.complete ? 1 : 0), 0),
|
|
118
123
|
};
|
|
119
124
|
}
|
package/lib/reach.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Who you reached through a circle, and whether their own circle is next.
|
|
2
|
+
//
|
|
3
|
+
// Blake, 2026-09-25: "i would like to sigingy if a orb in the 2nd degree is
|
|
4
|
+
// added already so it shows they are ready for a 2nd degree scan to get the 3rd
|
|
5
|
+
// degree so it needs to be intuitive with the orb glowing".
|
|
6
|
+
//
|
|
7
|
+
// "Ready" is one rule, kept here once. It used to live in three slightly
|
|
8
|
+
// different copies (Outlink's new doors, the profile page's mapping bar and the
|
|
9
|
+
// Degrees panel's Auto-Bridge Next), and only one of them knew about hidden
|
|
10
|
+
// lists. Someone is ready for a circle scan when all of these are true:
|
|
11
|
+
// - they're your connection now (degree 1);
|
|
12
|
+
// - they came to you through a circle: unlocked_from_bridge_id, which
|
|
13
|
+
// lib/promote.js keeps when it clears source_connection_id, and which a
|
|
14
|
+
// request sent from the app sets to the circle you asked through;
|
|
15
|
+
// - their own circle hasn't been scanned: nobody in it is saved, and the
|
|
16
|
+
// scanner has no note of reading it (bridge-progress.json);
|
|
17
|
+
// - their list isn't known to be hidden (bridge-skips.json).
|
|
18
|
+
// A glow that fired on hidden lists would teach you to ignore it, so a hidden
|
|
19
|
+
// list is its own state, never "ready".
|
|
20
|
+
//
|
|
21
|
+
// Plain functions, no React; tests/reach.test.mjs.
|
|
22
|
+
|
|
23
|
+
import { keyFor, compareBridges } from './separation.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* What the rules read, built once per load.
|
|
27
|
+
*
|
|
28
|
+
* @param connections 1st-degree rows
|
|
29
|
+
* @param degree2 2nd-degree rows: whose circle each sits in
|
|
30
|
+
* @param notes what the scanner noted, from /api/scraper?reach=1:
|
|
31
|
+
* { skips: [{ profileUrl }] (hidden lists), read: [profileUrl] (lists it has read) }
|
|
32
|
+
* @returns {{ scanned: Set, read: Set, hidden: Set, reachedFrom: Map }}
|
|
33
|
+
* `reachedFrom` is circle id → the connections you reached through it.
|
|
34
|
+
*/
|
|
35
|
+
export function reachIndex(connections = [], degree2 = [], notes = {}) {
|
|
36
|
+
const scanned = new Set();
|
|
37
|
+
for (const row of degree2 || []) {
|
|
38
|
+
if (row?.source_connection_id != null) scanned.add(row.source_connection_id);
|
|
39
|
+
}
|
|
40
|
+
const hidden = new Set();
|
|
41
|
+
for (const s of notes?.skips || []) {
|
|
42
|
+
if (s?.profileUrl) hidden.add(keyFor({ profile_url: s.profileUrl }));
|
|
43
|
+
}
|
|
44
|
+
const read = new Set();
|
|
45
|
+
for (const url of notes?.read || []) {
|
|
46
|
+
if (url) read.add(keyFor({ profile_url: url }));
|
|
47
|
+
}
|
|
48
|
+
const reachedFrom = new Map();
|
|
49
|
+
for (const row of connections || []) {
|
|
50
|
+
const from = row?.unlocked_from_bridge_id;
|
|
51
|
+
if (from == null || row.degree !== 1) continue;
|
|
52
|
+
let list = reachedFrom.get(from);
|
|
53
|
+
if (!list) reachedFrom.set(from, (list = []));
|
|
54
|
+
list.push(row);
|
|
55
|
+
}
|
|
56
|
+
return { scanned, read, hidden, reachedFrom };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Their own circle: 'scanned' (someone in it is saved, or the scanner read
|
|
61
|
+
* their list and everyone on it was already yours), 'hidden' (they keep their
|
|
62
|
+
* connections private) or 'todo'.
|
|
63
|
+
*/
|
|
64
|
+
export function circleState(person, reach) {
|
|
65
|
+
if (!person) return 'todo';
|
|
66
|
+
if (reach.scanned.has(person.id)) return 'scanned';
|
|
67
|
+
if (person.profile_url && reach.read?.has(keyFor(person))) return 'scanned';
|
|
68
|
+
if (person.profile_url && reach.hidden.has(keyFor(person))) return 'hidden';
|
|
69
|
+
return 'todo';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* For someone you reached through a circle: 'ready' (their circle can be
|
|
74
|
+
* scanned next), 'hidden' or 'scanned'. Null for anyone else: people who were
|
|
75
|
+
* always your connections, and 2nd-degree rows (a request sent from the app
|
|
76
|
+
* marks those with the circle it asked through, but they aren't yours yet).
|
|
77
|
+
*/
|
|
78
|
+
export function reachState(person, reach) {
|
|
79
|
+
if (!person || person.degree !== 1 || person.unlocked_from_bridge_id == null) return null;
|
|
80
|
+
const state = circleState(person, reach);
|
|
81
|
+
return state === 'todo' ? 'ready' : state;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Everyone ready for a circle scan, strongest first. */
|
|
85
|
+
export function readyToScan(connections, reach) {
|
|
86
|
+
return (connections || []).filter((c) => reachState(c, reach) === 'ready').sort(compareBridges);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** How many people you reached through each circle are ready, by circle id. */
|
|
90
|
+
export function readyByCircle(reach) {
|
|
91
|
+
const out = new Map();
|
|
92
|
+
for (const [from, people] of reach.reachedFrom) {
|
|
93
|
+
const n = people.filter((p) => reachState(p, reach) === 'ready').length;
|
|
94
|
+
if (n) out.set(from, n);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* What scanning one circle asks of LinkedIn: one profile view to find their
|
|
101
|
+
* list, then a search for every page of it, `pages` at most (LinkedIn shows
|
|
102
|
+
* 100). About 0.55 minutes a page with the scanner's rests (20 s before each
|
|
103
|
+
* page, a minute more after every 10), so about 55 minutes for a whole list.
|
|
104
|
+
* The Scan page and the Degrees panel both say it from here.
|
|
105
|
+
*/
|
|
106
|
+
export function circleScanCost(pages = 100) {
|
|
107
|
+
const searches = Math.max(1, Math.min(100, Math.round(pages) || 100));
|
|
108
|
+
return {
|
|
109
|
+
profileViews: 1,
|
|
110
|
+
searches,
|
|
111
|
+
minutes: searches >= 100 ? 55 : Math.max(5, Math.round(searches * 0.55)),
|
|
112
|
+
};
|
|
113
|
+
}
|
package/lib/scan-state.js
CHANGED
|
@@ -40,6 +40,7 @@ export function runningNow(job) {
|
|
|
40
40
|
case 'install': return 'The scanner\'s packages are being installed';
|
|
41
41
|
case 'setup': return 'The scanner is being set up';
|
|
42
42
|
case 'login': return 'The LinkedIn sign-in window is open';
|
|
43
|
+
case 'photos': return 'Profile photos are being saved';
|
|
43
44
|
default: return 'A scan is running';
|
|
44
45
|
}
|
|
45
46
|
}
|
package/lib/scanner-setup.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// What the Scan page's first step says and offers, from the checks GET
|
|
2
|
-
// /api/scraper reports (app/api/scraper/route.js, lib/scanner-python.js)
|
|
2
|
+
// /api/scraper reports (app/api/scraper/route.js, lib/scanner-python.js), and
|
|
3
|
+
// whether it asks for your field before that (askForField).
|
|
3
4
|
// Plain data in, plain data out: the page draws it, and
|
|
4
5
|
// tests/scanner-setup.test.mjs checks every state without a browser. No Node
|
|
5
6
|
// imports here; the page runs in the browser.
|
|
@@ -102,3 +103,21 @@ function stepOnly(status) {
|
|
|
102
103
|
button: null,
|
|
103
104
|
};
|
|
104
105
|
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Whether the Scan page asks for your field first (app/components/FieldStep.js):
|
|
109
|
+
* once, before the first scan. Never to someone who already has a network, has
|
|
110
|
+
* picked a sector (Scores → Your sector), or answered or skipped the question
|
|
111
|
+
* before (`fieldAsked`). `status` is GET /api/scraper's answer (null while it
|
|
112
|
+
* loads), `settings` GET /api/settings' `settings` (undefined while it loads,
|
|
113
|
+
* null when it couldn't be read). null means not known yet: the page waits,
|
|
114
|
+
* rather than show the steps and then swap them for the question.
|
|
115
|
+
*/
|
|
116
|
+
export function askForField(status, settings) {
|
|
117
|
+
if (!status) return null;
|
|
118
|
+
const n = status.network;
|
|
119
|
+
// No counts means the app couldn't be asked; a scan running is past asking.
|
|
120
|
+
if (!n || n.first || n.second || n.third || status.running) return false;
|
|
121
|
+
if (settings === undefined) return null;
|
|
122
|
+
return Boolean(settings && !settings.fieldAsked && !settings.sectorFocus?.sectors?.length);
|
|
123
|
+
}
|