six-degrees 0.4.0-beta.1 → 0.4.1
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 +14 -14
- 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/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +2 -2
- 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 +2 -2
- 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 +12 -12
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
- 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/favicon.ico/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/favicon.ico.body +0 -0
- 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 +14 -14
- package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +14 -14
- 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 +14 -14
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +14 -14
- 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]__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/{[root-of-the-server]__0i5hdu4._.js → [root-of-the-server]__20tmem7._.js} +2 -2
- 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/_1mxn_lb._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +26 -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/[root-of-the-server]__00d8snt._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00g61b8._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08lf3gy._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ho-u0w._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ze473p._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1194jps._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1cnxxc9._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ll97ry._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m0255u._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1w9z0zv._.js +1 -1
- 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 +6 -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/10784r7w7t5gw.js +18 -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/2p5yt1o9tnxjn.js +2 -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/3ol1xux1-ofm4.js +6 -0
- package/.next/standalone/.next/static/chunks/3zs_6-nn0dapb.js +1 -0
- package/.next/standalone/.next/static/media/favicon.0zdzw5kurn8m-.ico +0 -0
- package/.next/standalone/CHANGELOG.md +211 -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/admin-delete/route.js +3 -0
- package/.next/standalone/app/api/ingest/route.js +19 -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 +713 -469
- package/.next/standalone/app/components/EmptyState.js +1 -1
- package/.next/standalone/app/components/FieldStep.js +94 -0
- package/.next/standalone/app/components/FilterPanel.js +37 -1
- package/.next/standalone/app/components/ForceGraph.js +228 -774
- package/.next/standalone/app/components/GridView.js +9 -7
- package/.next/standalone/app/components/LinkedInLimits.js +40 -8
- 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 +209 -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 +6 -4
- package/.next/standalone/app/favicon.ico +0 -0
- package/.next/standalone/app/globals.css +7 -0
- package/.next/standalone/app/launch/page.js +2 -2
- package/.next/standalone/app/page.js +153 -31
- package/.next/standalone/app/paths/page.js +11 -3
- package/.next/standalone/app/queue/page.js +18 -10
- package/.next/standalone/app/setup/page.js +423 -260
- package/.next/standalone/db/schema.js +15 -1
- package/.next/standalone/eslint.config.mjs +3 -3
- package/.next/standalone/install.sh +3 -3
- package/.next/standalone/lib/brokerage.js +94 -0
- package/.next/standalone/lib/chain-layout.js +228 -0
- package/.next/standalone/lib/circle.js +23 -4
- 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/degrees.js +30 -0
- package/.next/standalone/lib/galaxy.js +12 -0
- package/.next/standalone/lib/ingest.js +18 -11
- package/.next/standalone/lib/linkedin-limits.js +35 -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/search-risk.js +38 -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/lib/ties.js +23 -0
- 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 +271 -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/10784r7w7t5gw.js +18 -0
- package/.next/static/chunks/18xu0fbgo_qz-.js +1 -0
- package/.next/static/chunks/28bu26ausqzmn.js +1 -0
- package/.next/static/chunks/2p5yt1o9tnxjn.js +2 -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/3ol1xux1-ofm4.js +6 -0
- package/.next/static/chunks/3zs_6-nn0dapb.js +1 -0
- package/.next/static/media/favicon.0zdzw5kurn8m-.ico +0 -0
- package/CHANGELOG.md +211 -0
- package/README.md +21 -15
- package/SECURITY.md +10 -0
- package/db/schema.js +15 -1
- package/lib/brokerage.js +94 -0
- package/lib/chain-layout.js +228 -0
- package/lib/circle.js +23 -4
- package/lib/csv.js +4 -6
- package/lib/data-export.js +2 -1
- package/lib/data-folder.js +4 -2
- package/lib/degrees.js +30 -0
- package/lib/galaxy.js +12 -0
- package/lib/ingest.js +18 -11
- package/lib/linkedin-limits.js +35 -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/search-risk.js +38 -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/lib/ties.js +23 -0
- package/package.json +1 -1
- package/scripts/check-node.mjs +1 -1
- package/scripts/image_store.py +77 -21
- package/scripts/scrape.py +271 -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/standalone/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
- 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/static/media/favicon.2vob68tjqpejf.ico +0 -0
- /package/.next/standalone/.next/static/{NnWlxbDF24KhrU1eHiEnv → LlDgA9g8ToBkDLlo9Qtov}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{NnWlxbDF24KhrU1eHiEnv → LlDgA9g8ToBkDLlo9Qtov}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{NnWlxbDF24KhrU1eHiEnv → LlDgA9g8ToBkDLlo9Qtov}/_ssgManifest.js +0 -0
- /package/.next/static/{NnWlxbDF24KhrU1eHiEnv → LlDgA9g8ToBkDLlo9Qtov}/_buildManifest.js +0 -0
- /package/.next/static/{NnWlxbDF24KhrU1eHiEnv → LlDgA9g8ToBkDLlo9Qtov}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{NnWlxbDF24KhrU1eHiEnv → LlDgA9g8ToBkDLlo9Qtov}/_ssgManifest.js +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { localPhoto } from '../../lib/photos';
|
|
4
|
+
|
|
3
5
|
const TIER_COLORS = { S: '#FFD700', A: '#9B59B6', B: '#3498DB', C: '#95A5A6', D: '#BDC3C7' };
|
|
4
6
|
const TIERS = ['S', 'A', 'B', 'C', 'D'];
|
|
5
7
|
|
|
@@ -38,8 +40,8 @@ export default function GridView({ connections, degree2 = [], onSelect, mode })
|
|
|
38
40
|
onMouseLeave={e => e.currentTarget.style.background = 'rgba(255,255,255,0.03)'}
|
|
39
41
|
>
|
|
40
42
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
|
|
41
|
-
{cl.bridge.profile_image_url ? (
|
|
42
|
-
<img src={cl.bridge.profile_image_url} alt="" style={{
|
|
43
|
+
{localPhoto(cl.bridge.profile_image_url) ? (
|
|
44
|
+
<img src={localPhoto(cl.bridge.profile_image_url)} alt="" style={{
|
|
43
45
|
width: 40, height: 40, borderRadius: '50%', objectFit: 'cover',
|
|
44
46
|
border: `2px solid ${TIER_COLORS[cl.bridge.tier]}`,
|
|
45
47
|
}} onError={e => { e.target.style.display = 'none'; }} />
|
|
@@ -67,13 +69,13 @@ export default function GridView({ connections, degree2 = [], onSelect, mode })
|
|
|
67
69
|
{cl.members.slice(0, 8).map((m, i) => (
|
|
68
70
|
<div key={m.id} style={{
|
|
69
71
|
width: 22, height: 22, borderRadius: '50%', fontSize: 8, fontWeight: 700,
|
|
70
|
-
background: m.profile_image_url ? 'transparent' : (TIER_COLORS[m.tier] || '#333'),
|
|
72
|
+
background: localPhoto(m.profile_image_url) ? 'transparent' : (TIER_COLORS[m.tier] || '#333'),
|
|
71
73
|
color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
72
74
|
border: '2px solid #0a0a1a', marginLeft: i > 0 ? -6 : 0, position: 'relative', zIndex: 8 - i,
|
|
73
75
|
overflow: 'hidden',
|
|
74
76
|
}}>
|
|
75
|
-
{m.profile_image_url ? (
|
|
76
|
-
<img src={m.profile_image_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
|
|
77
|
+
{localPhoto(m.profile_image_url) ? (
|
|
78
|
+
<img src={localPhoto(m.profile_image_url)} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
|
|
77
79
|
) : m.name?.charAt(0)}
|
|
78
80
|
</div>
|
|
79
81
|
))}
|
|
@@ -131,8 +133,8 @@ export default function GridView({ connections, degree2 = [], onSelect, mode })
|
|
|
131
133
|
onMouseLeave={e => e.currentTarget.style.background = 'rgba(255,255,255,0.03)'}
|
|
132
134
|
>
|
|
133
135
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
134
|
-
{c.profile_image_url ? (
|
|
135
|
-
<img src={c.profile_image_url} alt="" style={{
|
|
136
|
+
{localPhoto(c.profile_image_url) ? (
|
|
137
|
+
<img src={localPhoto(c.profile_image_url)} alt="" style={{
|
|
136
138
|
width: 32, height: 32, borderRadius: '50%', objectFit: 'cover',
|
|
137
139
|
border: `2px solid ${TIER_COLORS[tier]}`,
|
|
138
140
|
}} onError={e => { e.target.style.display = 'none'; }} />
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
// The Scan page's view of what LinkedIn allows: the search budget
|
|
4
|
-
// lock, and everyone whose list was only partly
|
|
5
|
-
// TRAPS §35. The numbers come from
|
|
6
|
-
// lib/paused.js), which reads the same
|
|
3
|
+
// The Scan page's view of what LinkedIn allows: the search budget and the cap
|
|
4
|
+
// on profile views, the cooldown lock, and everyone whose list was only partly
|
|
5
|
+
// read, with a way back into each. TRAPS §16, §35. The numbers come from
|
|
6
|
+
// /api/scraper (lib/linkedin-limits.js, lib/paused.js), which reads the same
|
|
7
|
+
// files the scanner writes.
|
|
7
8
|
|
|
8
9
|
import { useState } from 'react';
|
|
10
|
+
import { limitQuestion, limitNote, SAFE_LIMITS } from '../../lib/search-risk';
|
|
9
11
|
|
|
10
12
|
const LINE = '1px solid rgba(255,255,255,0.1)';
|
|
11
13
|
const TIER = { S: '#FFD700', A: '#9B59B6', B: '#3498DB', C: '#95A5A6', D: '#BDC3C7' };
|
|
12
14
|
const DAILY = [25, 50, 100, 200, 500];
|
|
13
15
|
const MONTHLY = [100, 250, 500, 1000, 0];
|
|
16
|
+
const PROFILES = [10, 25, 50, 100];
|
|
14
17
|
|
|
15
18
|
const when = (ms) => new Date(ms).toLocaleString(undefined, { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' });
|
|
16
19
|
const day = (ms) => new Date(ms).toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
|
@@ -55,6 +58,15 @@ export function BudgetBox({ li, onSetLimits, disabled }) {
|
|
|
55
58
|
if (!li) return null;
|
|
56
59
|
const { limits } = li;
|
|
57
60
|
const today = li.unreadable ? '?' : li.searchesToday;
|
|
61
|
+
const views = li.unreadable ? '?' : li.profilesToday;
|
|
62
|
+
const set = (change) => onSetLimits({ ...limits, ...change });
|
|
63
|
+
// A budget past what LinkedIn has put up with is asked about first (lib/search-risk.js).
|
|
64
|
+
const ask = (change) => {
|
|
65
|
+
const q = limitQuestion(limits, { ...limits, ...change });
|
|
66
|
+
if (q && !window.confirm(q)) return;
|
|
67
|
+
set(change);
|
|
68
|
+
};
|
|
69
|
+
const note = limitNote(limits);
|
|
58
70
|
return (
|
|
59
71
|
<div style={{ padding: '12px 14px', borderRadius: 8, border: LINE, background: 'rgba(255,255,255,0.03)', fontSize: 12.5, color: '#b8c4c4' }}>
|
|
60
72
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(210px, 1fr))', gap: 14 }}>
|
|
@@ -66,22 +78,42 @@ export function BudgetBox({ li, onSetLimits, disabled }) {
|
|
|
66
78
|
<div><b style={{ color: '#fff' }}>{li.searchesMonth}</b> of {limits.monthly || 'no limit'} this month · resets {day(li.monthResets)}</div>
|
|
67
79
|
<Bar used={li.searchesMonth} cap={limits.monthly} />
|
|
68
80
|
</div>
|
|
81
|
+
<div>
|
|
82
|
+
<div><b style={{ color: '#fff' }}>{views}</b> of {limits.profiles} profile views today</div>
|
|
83
|
+
<Bar used={li.unreadable ? limits.profiles : li.profilesToday} cap={limits.profiles} />
|
|
84
|
+
</div>
|
|
69
85
|
</div>
|
|
70
86
|
<div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap', marginTop: 10 }}>
|
|
71
87
|
<span>Budget:</span>
|
|
72
|
-
<select value={limits.daily} disabled={disabled} onChange={(e) =>
|
|
88
|
+
<select value={limits.daily} disabled={disabled} onChange={(e) => ask({ daily: Number(e.target.value) })} style={sel}>
|
|
73
89
|
{DAILY.map((n) => <option key={n} value={n}>{n} a day</option>)}
|
|
74
90
|
</select>
|
|
75
|
-
<select value={limits.monthly} disabled={disabled} onChange={(e) =>
|
|
91
|
+
<select value={limits.monthly} disabled={disabled} onChange={(e) => ask({ monthly: Number(e.target.value) })} style={sel}>
|
|
76
92
|
{MONTHLY.map((n) => <option key={n} value={n}>{n ? `${n} a month` : 'no monthly cap (Premium)'}</option>)}
|
|
77
93
|
</select>
|
|
78
|
-
<
|
|
94
|
+
<select value={limits.profiles} disabled={disabled} onChange={(e) => set({ profiles: Number(e.target.value) })} style={sel}>
|
|
95
|
+
{PROFILES.map((n) => <option key={n} value={n}>{n} profile views a day</option>)}
|
|
96
|
+
</select>
|
|
79
97
|
</div>
|
|
80
98
|
<div style={{ marginTop: 8, color: '#778', lineHeight: 1.6 }}>
|
|
81
99
|
Every page of someone’s connections is one search. LinkedIn limits a free account’s people
|
|
82
100
|
searches by the month (it doesn’t say how many; reports put it around 250–350), resetting on the 1st.
|
|
83
101
|
When a budget is used, a scan saves what it read and stops; the next one carries on from the same page.
|
|
84
|
-
|
|
102
|
+
</div>
|
|
103
|
+
{note && (
|
|
104
|
+
<div style={{ marginTop: 8, display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', color: '#FFD700', lineHeight: 1.6 }}>
|
|
105
|
+
<b style={{ flex: 1, minWidth: 200 }}>{note}</b>
|
|
106
|
+
<button
|
|
107
|
+
onClick={() => set(SAFE_LIMITS)}
|
|
108
|
+
disabled={disabled}
|
|
109
|
+
style={{ ...sel, cursor: disabled ? 'not-allowed' : 'pointer', color: '#FFD700', borderColor: 'rgba(255,215,0,0.4)' }}
|
|
110
|
+
>Back to {SAFE_LIMITS.daily} a day, {SAFE_LIMITS.monthly} a month</button>
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
<div style={{ marginTop: 6, color: '#778', lineHeight: 1.6 }}>
|
|
114
|
+
Each circle scan opens the person’s profile once, which is one profile view. Profile views are what
|
|
115
|
+
LinkedIn restricted an account for, after about 20 in an hour. The scanner opens at most one a minute, and
|
|
116
|
+
once today’s are used, a scan stops before the next profile and tries that person next time.
|
|
85
117
|
</div>
|
|
86
118
|
</div>
|
|
87
119
|
);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { localPhoto } from '../../lib/photos';
|
|
4
|
+
|
|
3
5
|
const TIER_COLORS = { S: '#FFD700', A: '#9B59B6', B: '#3498DB', C: '#95A5A6', D: '#BDC3C7' };
|
|
4
6
|
|
|
5
7
|
export default function ListView({ connections, degree2 = [], onSelect, mode }) {
|
|
@@ -47,8 +49,8 @@ export default function ListView({ connections, degree2 = [], onSelect, mode })
|
|
|
47
49
|
>
|
|
48
50
|
<span style={{ fontSize: 12, fontWeight: 700, color: '#444' }}>{i + 1}</span>
|
|
49
51
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
|
|
50
|
-
{cl.bridge.profile_image_url ? (
|
|
51
|
-
<img src={cl.bridge.profile_image_url} alt="" style={{
|
|
52
|
+
{localPhoto(cl.bridge.profile_image_url) ? (
|
|
53
|
+
<img src={localPhoto(cl.bridge.profile_image_url)} alt="" style={{
|
|
52
54
|
width: 28, height: 28, borderRadius: '50%', objectFit: 'cover', flexShrink: 0,
|
|
53
55
|
border: `2px solid ${TIER_COLORS[cl.bridge.tier]}`,
|
|
54
56
|
}} onError={e => { e.target.style.display = 'none'; }} />
|
|
@@ -113,8 +115,8 @@ export default function ListView({ connections, degree2 = [], onSelect, mode })
|
|
|
113
115
|
onMouseLeave={e => e.currentTarget.style.background = i < 3 ? `${TIER_COLORS[c.tier]}08` : 'transparent'}
|
|
114
116
|
>
|
|
115
117
|
<span style={{ fontSize: 12, fontWeight: 700, color: i < 3 ? TIER_COLORS[c.tier] : '#444' }}>{i + 1}</span>
|
|
116
|
-
{c.profile_image_url ? (
|
|
117
|
-
<img src={c.profile_image_url} alt="" style={{
|
|
118
|
+
{localPhoto(c.profile_image_url) ? (
|
|
119
|
+
<img src={localPhoto(c.profile_image_url)} alt="" style={{
|
|
118
120
|
width: 28, height: 28, borderRadius: '50%', objectFit: 'cover',
|
|
119
121
|
border: `2px solid ${TIER_COLORS[c.tier]}`,
|
|
120
122
|
}} onError={e => { e.target.style.display = 'none'; }} />
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { TIER_COLORS_CLASSIC as TIER_COLORS } from '../../lib/tiers';
|
|
4
|
+
import { reachIndex, circleState } from '../../lib/reach';
|
|
4
5
|
|
|
5
6
|
// How much of your 1st degree has had its circle opened.
|
|
6
7
|
//
|
|
@@ -19,13 +20,11 @@ const CARD = {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export function computeMapping(degree1 = [], degree2 = [], skips = []) {
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
// One rule for whose circle is open, hidden or still to do: lib/reach.js.
|
|
24
|
+
const reach = reachIndex(degree1, degree2, { skips });
|
|
25
25
|
const state = (c) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return 'todo';
|
|
26
|
+
const s = circleState(c, reach);
|
|
27
|
+
return s === 'scanned' ? 'mapped' : s;
|
|
29
28
|
};
|
|
30
29
|
|
|
31
30
|
const counts = { mapped: 0, hidden: 0, todo: 0 };
|
|
@@ -24,7 +24,7 @@ export default function OnboardingGate({ children }) {
|
|
|
24
24
|
) : (
|
|
25
25
|
<div style={{ maxWidth: 420 }}>
|
|
26
26
|
<div style={{ fontSize: 18, fontWeight: 700, marginBottom: 8 }}>
|
|
27
|
-
Can’t reach
|
|
27
|
+
Can’t reach Six Degrees’ local server
|
|
28
28
|
</div>
|
|
29
29
|
<div style={{ color: '#888', fontSize: 14, lineHeight: 1.6 }}>
|
|
30
30
|
The page loaded but the app behind it is not answering. If you started it
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
zoomTransform,
|
|
33
33
|
} from 'd3';
|
|
34
34
|
import { TIER_COLORS, TIER_ORDER, TIER_RING_RADIUS, initialsFor } from '../../lib/tiers';
|
|
35
|
+
import { localPhoto } from '../../lib/photos';
|
|
35
36
|
|
|
36
37
|
const GOLDEN_ANGLE = 2.399963;
|
|
37
38
|
const LABEL_ZOOM_THRESHOLD = 1.1;
|
|
@@ -374,7 +375,8 @@ const OrbitGraph = forwardRef(function OrbitGraph(
|
|
|
374
375
|
.attr('font-size', d.r * 0.8).attr('font-weight', 700)
|
|
375
376
|
.attr('fill', '#0b0b16').style('pointer-events', 'none');
|
|
376
377
|
|
|
377
|
-
|
|
378
|
+
// Only a photo saved on this computer (lib/photos.js).
|
|
379
|
+
const imageUrl = localPhoto(isUser ? userImage : conn?.profile_image_url);
|
|
378
380
|
if (imageUrl) {
|
|
379
381
|
const clipId = `og-clip-${safeId(d.id)}`;
|
|
380
382
|
defs.append('clipPath').attr('id', clipId).append('circle').attr('r', d.r);
|
|
@@ -11,6 +11,7 @@ import { useMemo, useState } from 'react';
|
|
|
11
11
|
import Link from 'next/link';
|
|
12
12
|
import { buildQuest, XP_SEND, STAGE_SIZE } from '../../lib/quest';
|
|
13
13
|
import { initialsFor } from '../../lib/tiers';
|
|
14
|
+
import { localPhoto } from '../../lib/photos';
|
|
14
15
|
|
|
15
16
|
const TIER = { S: '#FFD700', A: '#9B59B6', B: '#3498DB', C: '#95A5A6', D: '#BDC3C7' };
|
|
16
17
|
const LINE = '1px solid rgba(255,255,255,0.1)';
|
|
@@ -24,8 +25,8 @@ function Face({ person, size = 36, ring }) {
|
|
|
24
25
|
display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: size * 0.34, fontWeight: 800,
|
|
25
26
|
border: `2px solid ${ring || color}`,
|
|
26
27
|
}}>{initialsFor(person?.name || '?')}</div>
|
|
27
|
-
{person?.profile_image_url && (
|
|
28
|
-
<img src={person.profile_image_url} alt="" onError={(e) => { e.currentTarget.style.display = 'none'; }}
|
|
28
|
+
{localPhoto(person?.profile_image_url) && (
|
|
29
|
+
<img src={localPhoto(person.profile_image_url)} alt="" onError={(e) => { e.currentTarget.style.display = 'none'; }}
|
|
29
30
|
style={{ position: 'absolute', inset: 0, width: size, height: size, borderRadius: '50%', objectFit: 'cover', border: `2px solid ${ring || color}` }} />
|
|
30
31
|
)}
|
|
31
32
|
</div>
|
|
@@ -47,8 +48,8 @@ function Ring({ progress, size = 86, color = '#FF6B35', children }) {
|
|
|
47
48
|
);
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
export default function OutlinkQuest({ recs, sentIds, added, mappedIds, onSend, onUndo }) {
|
|
51
|
-
const quest = useMemo(() => buildQuest({ recs, sentIds, added, mappedIds }), [recs, sentIds, added, mappedIds]);
|
|
51
|
+
export default function OutlinkQuest({ recs, sentIds, added, mappedIds, reach, onSend, onUndo }) {
|
|
52
|
+
const quest = useMemo(() => buildQuest({ recs, sentIds, added, mappedIds, reach }), [recs, sentIds, added, mappedIds, reach]);
|
|
52
53
|
const [open, setOpen] = useState(null); // bridge id of the expanded cluster
|
|
53
54
|
const [toast, setToast] = useState(null);
|
|
54
55
|
const { level } = quest;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
+
import { localPhoto } from '../../lib/photos';
|
|
4
5
|
|
|
5
6
|
const TIER_COLORS = { S: '#FFD700', A: '#9B59B6', B: '#3498DB', C: '#95A5A6', D: '#BDC3C7' };
|
|
6
7
|
const TIERS = ['S', 'A', 'B', 'C', 'D'];
|
|
@@ -58,8 +59,8 @@ export default function RingsView({ connections, degree2 = [], onSelect, mode })
|
|
|
58
59
|
boxShadow: hoveredId === cl.bridge.id ? `0 0 20px ${TIER_COLORS[cl.bridge.tier]}60` : `0 0 10px ${TIER_COLORS[cl.bridge.tier]}20`,
|
|
59
60
|
transition: 'box-shadow 0.2s',
|
|
60
61
|
}}>
|
|
61
|
-
{cl.bridge.profile_image_url ? (
|
|
62
|
-
<img src={cl.bridge.profile_image_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
|
|
62
|
+
{localPhoto(cl.bridge.profile_image_url) ? (
|
|
63
|
+
<img src={localPhoto(cl.bridge.profile_image_url)} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
|
|
63
64
|
) : (
|
|
64
65
|
<div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
65
66
|
background: TIER_COLORS[cl.bridge.tier], color: cl.bridge.tier === 'S' ? '#000' : '#fff', fontSize: 20, fontWeight: 800 }}>
|
|
@@ -95,13 +96,13 @@ export default function RingsView({ connections, degree2 = [], onSelect, mode })
|
|
|
95
96
|
<div style={{
|
|
96
97
|
width: size, height: size, borderRadius: '50%',
|
|
97
98
|
border: `2px solid ${TIER_COLORS[tier]}`,
|
|
98
|
-
overflow: 'hidden', background: p.profile_image_url ? '#111' : TIER_COLORS[tier],
|
|
99
|
+
overflow: 'hidden', background: localPhoto(p.profile_image_url) ? '#111' : TIER_COLORS[tier],
|
|
99
100
|
transition: 'transform 0.15s, box-shadow 0.15s',
|
|
100
101
|
transform: isHov ? 'scale(1.3)' : 'scale(1)',
|
|
101
102
|
boxShadow: isHov ? `0 0 12px ${TIER_COLORS[tier]}60` : 'none',
|
|
102
103
|
}}>
|
|
103
|
-
{p.profile_image_url ? (
|
|
104
|
-
<img src={p.profile_image_url} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
|
104
|
+
{localPhoto(p.profile_image_url) ? (
|
|
105
|
+
<img src={localPhoto(p.profile_image_url)} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
|
105
106
|
onError={e => { e.target.style.display = 'none'; e.target.parentElement.style.background = TIER_COLORS[tier]; }} />
|
|
106
107
|
) : (
|
|
107
108
|
<span style={{ display: 'flex', width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center',
|
|
@@ -202,7 +203,7 @@ export default function RingsView({ connections, degree2 = [], onSelect, mode })
|
|
|
202
203
|
width: size, height: size, borderRadius: '50%',
|
|
203
204
|
border: `2px solid ${TIER_COLORS[tier]}`,
|
|
204
205
|
overflow: 'hidden',
|
|
205
|
-
background: c.profile_image_url ? '#111' : TIER_COLORS[tier],
|
|
206
|
+
background: localPhoto(c.profile_image_url) ? '#111' : TIER_COLORS[tier],
|
|
206
207
|
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
207
208
|
transition: 'transform 0.15s, box-shadow 0.15s',
|
|
208
209
|
transform: isHovered ? 'scale(1.3)' : 'scale(1)',
|
|
@@ -210,8 +211,8 @@ export default function RingsView({ connections, degree2 = [], onSelect, mode })
|
|
|
210
211
|
zIndex: isHovered ? 10 : 1,
|
|
211
212
|
position: 'relative',
|
|
212
213
|
}}>
|
|
213
|
-
{c.profile_image_url ? (
|
|
214
|
-
<img src={c.profile_image_url} alt="" style={{
|
|
214
|
+
{localPhoto(c.profile_image_url) ? (
|
|
215
|
+
<img src={localPhoto(c.profile_image_url)} alt="" style={{
|
|
215
216
|
width: '100%', height: '100%', objectFit: 'cover',
|
|
216
217
|
}} onError={e => {
|
|
217
218
|
e.target.style.display = 'none';
|