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.
Files changed (609) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +4 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +42 -14
  5. package/.next/standalone/.next/routes-manifest.json +24 -0
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  12. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.rsc +26 -18
  16. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +26 -18
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +25 -16
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/api/admin-delete/route.js +2 -2
  20. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/admin-update/route.js +2 -2
  22. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/bridges/route.js +2 -2
  24. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/bulk-import/route.js +2 -2
  26. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +3 -3
  28. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/company-scores/route.js +3 -3
  30. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/connections/route.js +2 -2
  32. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/data/backup/route/app-paths-manifest.json +3 -0
  34. package/.next/standalone/.next/server/app/api/data/backup/route/build-manifest.json +12 -0
  35. package/.next/standalone/.next/server/app/api/data/backup/route/server-reference-manifest.json +4 -0
  36. package/.next/standalone/.next/server/app/api/data/backup/route.js +7 -0
  37. package/.next/standalone/.next/server/app/api/data/backup/route.js.map +5 -0
  38. package/.next/standalone/.next/server/app/api/data/backup/route.js.nft.json +1 -0
  39. package/.next/standalone/.next/server/app/api/data/backup/route_client-reference-manifest.js +3 -0
  40. package/.next/standalone/.next/server/app/api/data/csv/route/app-paths-manifest.json +3 -0
  41. package/.next/standalone/.next/server/app/api/data/csv/route/build-manifest.json +12 -0
  42. package/.next/standalone/.next/server/app/api/data/csv/route/server-reference-manifest.json +4 -0
  43. package/.next/standalone/.next/server/app/api/data/csv/route.js +8 -0
  44. package/.next/standalone/.next/server/app/api/data/csv/route.js.map +5 -0
  45. package/.next/standalone/.next/server/app/api/data/csv/route.js.nft.json +1 -0
  46. package/.next/standalone/.next/server/app/api/data/csv/route_client-reference-manifest.js +3 -0
  47. package/.next/standalone/.next/server/app/api/data/export/route.js +1 -1
  48. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/data/import/route.js +1 -1
  50. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/data/restart/route.js +1 -1
  52. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/data/restore/route/app-paths-manifest.json +3 -0
  54. package/.next/standalone/.next/server/app/api/data/restore/route/build-manifest.json +12 -0
  55. package/.next/standalone/.next/server/app/api/data/restore/route/server-reference-manifest.json +4 -0
  56. package/.next/standalone/.next/server/app/api/data/restore/route.js +7 -0
  57. package/.next/standalone/.next/server/app/api/data/restore/route.js.map +5 -0
  58. package/.next/standalone/.next/server/app/api/data/restore/route.js.nft.json +1 -0
  59. package/.next/standalone/.next/server/app/api/data/restore/route_client-reference-manifest.js +3 -0
  60. package/.next/standalone/.next/server/app/api/data/reveal/route.js +1 -1
  61. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/api/data/route.js +1 -1
  63. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/api/delete-cluster/route.js +2 -2
  65. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/ingest/route.js +2 -2
  67. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/network/route.js +2 -2
  69. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/notifications/route.js +2 -2
  71. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/outreach/route.js +3 -3
  73. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/queue/route.js +2 -2
  75. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/api/scraper/route.js +5 -3
  77. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/settings/route.js +3 -3
  79. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +3 -3
  81. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +3 -3
  83. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/setup-profile/route.js +2 -2
  85. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/social/crm/route.js +1 -1
  87. package/.next/standalone/.next/server/app/api/social/crm/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/social/messages/route.js +1 -1
  89. package/.next/standalone/.next/server/app/api/social/messages/route.js.nft.json +1 -1
  90. package/.next/standalone/.next/server/app/api/social/route.js +2 -2
  91. package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
  92. package/.next/standalone/.next/server/app/api/unlock/route.js +2 -2
  93. package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/update-images/route.js +2 -2
  96. package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/users/route.js +2 -2
  98. package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/avatars/[file]/route.js +1 -1
  100. package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/import/page.js +1 -1
  102. package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/import.html +1 -1
  105. package/.next/standalone/.next/server/app/import.rsc +32 -24
  106. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +32 -24
  107. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
  108. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +23 -18
  109. package/.next/standalone/.next/server/app/index.html +1 -1
  110. package/.next/standalone/.next/server/app/index.rsc +29 -22
  111. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +20 -15
  112. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +29 -22
  113. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  114. package/.next/standalone/.next/server/app/insights/page/app-paths-manifest.json +3 -0
  115. package/.next/standalone/.next/server/app/insights/page/build-manifest.json +20 -0
  116. package/.next/standalone/.next/server/app/insights/page/next-font-manifest.json +11 -0
  117. package/.next/standalone/.next/server/app/insights/page/react-loadable-manifest.json +1 -0
  118. package/.next/standalone/.next/server/app/insights/page/server-reference-manifest.json +4 -0
  119. package/.next/standalone/.next/server/app/insights/page.js +13 -0
  120. package/.next/standalone/.next/server/app/insights/page.js.map +5 -0
  121. package/.next/standalone/.next/server/app/insights/page.js.nft.json +1 -0
  122. package/.next/standalone/.next/server/app/insights/page_client-reference-manifest.js +3 -0
  123. package/.next/standalone/.next/server/app/insights.html +1 -0
  124. package/.next/standalone/.next/server/app/insights.meta +26 -0
  125. package/.next/standalone/.next/server/app/insights.rsc +35 -0
  126. package/.next/standalone/.next/server/app/insights.segments/_full.segment.rsc +35 -0
  127. package/.next/standalone/.next/server/app/insights.segments/_tree.segment.rsc +4 -0
  128. package/.next/standalone/.next/server/app/insights.segments/insights/__PAGE__.segment.rsc +33 -0
  129. package/.next/standalone/.next/server/app/launch/page.js +1 -1
  130. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  131. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/launch.html +2 -2
  133. package/.next/standalone/.next/server/app/launch.rsc +32 -24
  134. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +32 -24
  135. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
  136. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +23 -18
  137. package/.next/standalone/.next/server/app/page.js +1 -1
  138. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  139. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/paths/page.js +1 -1
  141. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/paths.html +1 -1
  144. package/.next/standalone/.next/server/app/paths.rsc +32 -24
  145. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +32 -24
  146. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
  147. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +21 -18
  148. package/.next/standalone/.next/server/app/profile/page.js +1 -1
  149. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/profile.html +1 -1
  152. package/.next/standalone/.next/server/app/profile.rsc +32 -24
  153. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +32 -24
  154. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
  155. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +23 -18
  156. package/.next/standalone/.next/server/app/queue/page.js +1 -1
  157. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/queue.html +1 -1
  160. package/.next/standalone/.next/server/app/queue.rsc +32 -24
  161. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +32 -24
  162. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
  163. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +21 -18
  164. package/.next/standalone/.next/server/app/scores/page.js +1 -1
  165. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  167. package/.next/standalone/.next/server/app/scores.html +1 -1
  168. package/.next/standalone/.next/server/app/scores.rsc +32 -24
  169. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +32 -24
  170. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
  171. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +23 -18
  172. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  173. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  174. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  175. package/.next/standalone/.next/server/app/settings.html +1 -1
  176. package/.next/standalone/.next/server/app/settings.rsc +32 -24
  177. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +32 -24
  178. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  179. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +20 -18
  180. package/.next/standalone/.next/server/app/setup/page.js +1 -1
  181. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/setup.html +1 -1
  184. package/.next/standalone/.next/server/app/setup.rsc +32 -24
  185. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +32 -24
  186. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  187. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +21 -18
  188. package/.next/standalone/.next/server/app/social/page.js +1 -1
  189. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/social.html +1 -1
  192. package/.next/standalone/.next/server/app/social.rsc +32 -24
  193. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +32 -24
  194. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
  195. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +23 -18
  196. package/.next/standalone/.next/server/app-paths-manifest.json +4 -0
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +1 -1
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05_3-22._.js +1 -1
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__066rab1._.js +7 -0
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +1 -1
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +1 -1
  203. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fooke1._.js +7 -0
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +1 -1
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +1 -1
  207. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__15wc9e-._.js → [root-of-the-server]__0r-0t-9._.js} +2 -2
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ra6xyg._.js +15 -0
  209. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__20rwfdw._.js → [root-of-the-server]__0rcpjad._.js} +6 -3
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +1 -1
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t6y79e._.js +7 -0
  212. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
  213. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x29muh._.js +7 -0
  214. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +1 -1
  215. package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +1 -1
  216. package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +1 -1
  217. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +1 -1
  218. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a_6x37._.js +8 -0
  219. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an_8pa._.js +7 -0
  220. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +1 -1
  221. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ducpz2._.js +3 -0
  222. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +1 -1
  223. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +1 -1
  224. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +1 -1
  225. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tir0vc._.js +1 -1
  226. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
  227. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xhyinn._.js +3 -0
  228. package/.next/standalone/.next/server/chunks/_072jl0y._.js +1 -1
  229. package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +1 -1
  230. package/.next/standalone/.next/server/chunks/_0sqqpzb._.js +3 -0
  231. package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -7
  232. package/.next/standalone/.next/server/chunks/_1fn30_l._.js +1 -1
  233. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  234. package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
  235. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_backup_route_actions_0zoj04p.js +3 -0
  236. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_csv_route_actions_0l6m7lg.js +3 -0
  237. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restore_route_actions_0-b05bv.js +3 -0
  238. package/.next/standalone/.next/server/chunks/lib_02iz_9q._.js +4 -0
  239. package/.next/standalone/.next/server/chunks/lib_05agvk3._.js +4 -0
  240. package/.next/standalone/.next/server/chunks/lib_0v84u66._.js +4 -0
  241. package/.next/standalone/.next/server/chunks/lib_db-client_0_dch35.js +174 -0
  242. package/.next/standalone/.next/server/chunks/lib_linkedin-export_12imqxg.js +1 -1
  243. package/.next/standalone/.next/server/chunks/lib_rpc_00nndai.js +3 -0
  244. package/.next/standalone/.next/server/chunks/lib_rpc_03ibb-x.js +3 -0
  245. package/.next/standalone/.next/server/chunks/lib_rpc_03ri3ji.js +3 -0
  246. package/.next/standalone/.next/server/chunks/lib_rpc_078ce48.js +3 -0
  247. package/.next/standalone/.next/server/chunks/lib_rpc_0a69mgr.js +3 -0
  248. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +7 -0
  249. package/.next/standalone/.next/server/chunks/lib_rpc_0cej3t8.js +3 -0
  250. package/.next/standalone/.next/server/chunks/lib_rpc_0cmh4g6.js +3 -0
  251. package/.next/standalone/.next/server/chunks/lib_rpc_0nx2_pc.js +3 -0
  252. package/.next/standalone/.next/server/chunks/lib_rpc_0r79-w1.js +3 -0
  253. package/.next/standalone/.next/server/chunks/lib_rpc_0t552z6.js +3 -0
  254. package/.next/standalone/.next/server/chunks/lib_rpc_0yx8ynd.js +3 -0
  255. package/.next/standalone/.next/server/chunks/lib_rpc_12p-o9-.js +3 -0
  256. package/.next/standalone/.next/server/chunks/lib_rpc_1466dnb.js +3 -0
  257. package/.next/standalone/.next/server/chunks/lib_rpc_1sryxv6.js +3 -0
  258. package/.next/standalone/.next/server/chunks/lib_rpc_1trn-x5.js +3 -0
  259. package/.next/standalone/.next/server/chunks/lib_rpc_1ygu_mv.js +3 -0
  260. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0egamyq._.js +3 -0
  261. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qd8pzm._.js +3 -0
  262. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qdeuyo._.js → [root-of-the-server]__1-012q1._.js} +2 -2
  263. package/.next/standalone/.next/server/chunks/ssr/_04am_h8._.js +3 -0
  264. package/.next/standalone/.next/server/chunks/ssr/_06rgzfh._.js +3 -0
  265. package/.next/standalone/.next/server/chunks/ssr/_07zb7lu._.js +3 -0
  266. package/.next/standalone/.next/server/chunks/ssr/_0_79idq._.js +3 -0
  267. package/.next/standalone/.next/server/chunks/ssr/_0gds903._.js +3 -0
  268. package/.next/standalone/.next/server/chunks/ssr/_0hb-dhy._.js +3 -0
  269. package/.next/standalone/.next/server/chunks/ssr/_0klqt9z._.js +3 -0
  270. package/.next/standalone/.next/server/chunks/ssr/_14jak5s._.js +7 -0
  271. package/.next/standalone/.next/server/chunks/ssr/_14nxd3q._.js +3 -0
  272. package/.next/standalone/.next/server/chunks/ssr/_1cj2yog._.js +3 -0
  273. package/.next/standalone/.next/server/chunks/ssr/_1fm1ih_._.js +2 -2
  274. package/.next/standalone/.next/server/chunks/ssr/_1hdqw0-._.js +7 -0
  275. package/.next/standalone/.next/server/chunks/ssr/_1k2nmbw._.js +2 -2
  276. package/.next/standalone/.next/server/chunks/ssr/_1r62six._.js +7 -0
  277. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_insights_page_actions_0-0tf75.js +3 -0
  278. package/.next/standalone/.next/server/chunks/ssr/app_141w189._.js +1 -1
  279. package/.next/standalone/.next/server/chunks/ssr/app_components_0uuff77._.js +25 -2
  280. package/.next/standalone/.next/server/chunks/ssr/app_components_1j3q-h5._.js +25 -2
  281. package/.next/standalone/.next/server/chunks/ssr/app_components_CompanyScores_1g0mytz.js +1 -1
  282. package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.js +1 -1
  283. package/.next/standalone/.next/server/chunks/ssr/app_components_ui_0pdmz2z.js +3 -0
  284. package/.next/standalone/.next/server/chunks/ssr/app_import_page_1fmu6_l.js +1 -1
  285. package/.next/standalone/.next/server/chunks/ssr/app_insights_page_1d_chja.js +3 -0
  286. package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +1 -1
  287. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +26 -14
  288. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +2 -2
  289. package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
  290. package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +11 -11
  291. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
  292. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +12 -13
  293. package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
  294. package/.next/standalone/.next/server/chunks/ssr/{lib_1c4ieuw._.js → lib_csv_1ttiu_h.js} +2 -2
  295. package/.next/standalone/.next/server/chunks/ssr/lib_galaxy-lab_108_lu-.js +1 -1
  296. package/.next/standalone/.next/server/chunks/ssr/lib_separation_1305zsx.js +3 -0
  297. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +1 -1
  298. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  299. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  300. package/.next/standalone/.next/server/next-font-manifest.js +1 -1
  301. package/.next/standalone/.next/server/next-font-manifest.json +4 -0
  302. package/.next/standalone/.next/server/pages/404.html +1 -1
  303. package/.next/standalone/.next/server/pages/500.html +1 -1
  304. package/.next/standalone/.next/server/prefetch-hints.json +14 -0
  305. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  306. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  307. package/.next/standalone/.next/static/chunks/02wnf8dkxegxg.js +34 -0
  308. package/.next/standalone/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  309. package/.next/standalone/.next/static/chunks/03-demj2iy-0p.js +44 -0
  310. package/.next/standalone/.next/static/chunks/0838_s6w-i_ik.js +1 -0
  311. package/.next/standalone/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  312. package/.next/standalone/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
  313. package/.next/standalone/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  314. package/.next/standalone/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
  315. package/.next/standalone/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
  316. package/.next/standalone/.next/static/chunks/112mv-com-mqa.js +21 -0
  317. package/.next/standalone/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
  318. package/.next/standalone/.next/static/chunks/1cmphb3kh2ers.css +3 -0
  319. package/.next/standalone/.next/static/chunks/1d8yv3k_atka7.js +1 -0
  320. package/.next/standalone/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  321. package/.next/standalone/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  322. package/.next/standalone/.next/static/chunks/23hc51oa4vkhc.js +5 -0
  323. package/.next/standalone/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
  324. package/.next/standalone/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
  325. package/.next/standalone/.next/static/chunks/2w-y83mjlpnse.js +1 -0
  326. package/.next/standalone/.next/static/chunks/2ws1xf293j-tm.js +5 -0
  327. package/.next/standalone/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  328. package/.next/standalone/.next/static/chunks/34g73qhayuevu.js +1 -0
  329. package/.next/standalone/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
  330. package/.next/standalone/.next/static/chunks/3opgg1efrx8q6.js +1 -0
  331. package/.next/standalone/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
  332. package/.next/standalone/.next/static/chunks/3y40z6of3r9py.js +1 -0
  333. package/.next/standalone/.next/static/chunks/403dpflln8ah5.js +1 -0
  334. package/.next/standalone/.next/static/chunks/43pg2sursiypz.js +1 -0
  335. package/.next/standalone/CHANGELOG.md +203 -0
  336. package/.next/standalone/README.md +96 -50
  337. package/.next/standalone/SECURITY.md +25 -11
  338. package/.next/standalone/app/api/data/backup/route.js +25 -0
  339. package/.next/standalone/app/api/data/csv/route.js +74 -0
  340. package/.next/standalone/app/api/data/export/route.js +1 -1
  341. package/.next/standalone/app/api/data/restore/route.js +48 -0
  342. package/.next/standalone/app/api/data/reveal/route.js +19 -6
  343. package/.next/standalone/app/api/data/route.js +15 -4
  344. package/.next/standalone/app/api/ingest/route.js +1 -1
  345. package/.next/standalone/app/api/outreach/route.js +13 -73
  346. package/.next/standalone/app/api/queue/route.js +1 -1
  347. package/.next/standalone/app/api/scraper/route.js +217 -36
  348. package/.next/standalone/app/api/social/crm/route.js +2 -1
  349. package/.next/standalone/app/components/AppHeader.js +41 -21
  350. package/.next/standalone/app/components/AppTabs.js +12 -8
  351. package/.next/standalone/app/components/AutoConnect.js +286 -0
  352. package/.next/standalone/app/components/AutoScanButton.js +2 -2
  353. package/.next/standalone/app/components/Avatar.js +1 -1
  354. package/.next/standalone/app/components/ChainView.js +258 -113
  355. package/.next/standalone/app/components/CirclePanel.js +16 -16
  356. package/.next/standalone/app/components/ClusterSpinner.js +64 -0
  357. package/.next/standalone/app/components/CompanyScores.js +20 -20
  358. package/.next/standalone/app/components/EmptyState.js +39 -18
  359. package/.next/standalone/app/components/FieldStep.js +15 -13
  360. package/.next/standalone/app/components/FilterPanel.js +25 -18
  361. package/.next/standalone/app/components/ForceGraph.js +49 -14
  362. package/.next/standalone/app/components/GalaxyLab.js +33 -33
  363. package/.next/standalone/app/components/GridView.js +18 -18
  364. package/.next/standalone/app/components/LegacyScoresCard.js +10 -11
  365. package/.next/standalone/app/components/LinkedInLimits.js +57 -27
  366. package/.next/standalone/app/components/LiquidGlass.js +99 -0
  367. package/.next/standalone/app/components/ListView.js +20 -20
  368. package/.next/standalone/app/components/MapControls.js +5 -5
  369. package/.next/standalone/app/components/MappingProgress.js +16 -16
  370. package/.next/standalone/app/components/NoteDetail.js +13 -13
  371. package/.next/standalone/app/components/OnboardingGate.js +4 -4
  372. package/.next/standalone/app/components/OutlinkQuest.js +56 -35
  373. package/.next/standalone/app/components/PathsAnalyzer.js +37 -36
  374. package/.next/standalone/app/components/PeopleMap.js +21 -21
  375. package/.next/standalone/app/components/RingsView.js +11 -11
  376. package/.next/standalone/app/components/ScanRadar.js +84 -39
  377. package/.next/standalone/app/components/ScanStatusBar.js +40 -21
  378. package/.next/standalone/app/components/ScanTrail.js +21 -8
  379. package/.next/standalone/app/components/SeparationView.js +172 -124
  380. package/.next/standalone/app/components/Sidebar.js +308 -199
  381. package/.next/standalone/app/components/StaleServerBanner.js +4 -4
  382. package/.next/standalone/app/components/TheirCircle.js +26 -26
  383. package/.next/standalone/app/components/ThemeDefs.js +42 -0
  384. package/.next/standalone/app/components/ThemeLoader.js +20 -1
  385. package/.next/standalone/app/components/UpdatePanel.js +22 -22
  386. package/.next/standalone/app/components/UserProvider.js +22 -15
  387. package/.next/standalone/app/components/insights/Boards.js +275 -0
  388. package/.next/standalone/app/components/insights/PeopleView.js +266 -0
  389. package/.next/standalone/app/components/insights/Rail.js +156 -0
  390. package/.next/standalone/app/components/insights/Report.js +382 -0
  391. package/.next/standalone/app/components/insights/parts.js +239 -0
  392. package/.next/standalone/app/components/settings/AppearanceSection.js +47 -24
  393. package/.next/standalone/app/components/settings/DataSection.js +276 -109
  394. package/.next/standalone/app/components/settings/NetworkHealthSection.js +13 -13
  395. package/.next/standalone/app/components/settings/SectorPicker.js +12 -12
  396. package/.next/standalone/app/components/settings/SectorSection.js +13 -14
  397. package/.next/standalone/app/components/settings/TierSection.js +9 -9
  398. package/.next/standalone/app/components/settings/TitleSection.js +11 -11
  399. package/.next/standalone/app/components/settings/UsageSection.js +360 -0
  400. package/.next/standalone/app/components/ui.js +8 -8
  401. package/.next/standalone/app/globals.css +161 -5
  402. package/.next/standalone/app/import/page.js +94 -38
  403. package/.next/standalone/app/insights/page.js +220 -0
  404. package/.next/standalone/app/launch/page.js +5 -5
  405. package/.next/standalone/app/layout.js +6 -2
  406. package/.next/standalone/app/page.js +53 -53
  407. package/.next/standalone/app/paths/page.js +63 -63
  408. package/.next/standalone/app/profile/page.js +58 -58
  409. package/.next/standalone/app/queue/page.js +84 -72
  410. package/.next/standalone/app/scores/page.js +2 -2
  411. package/.next/standalone/app/settings/page.js +16 -13
  412. package/.next/standalone/app/setup/page.js +236 -133
  413. package/.next/standalone/app/social/Crm.js +63 -62
  414. package/.next/standalone/app/social/SocialHub.js +22 -22
  415. package/.next/standalone/app/social/Thread.js +7 -7
  416. package/.next/standalone/app/social/page.js +2 -2
  417. package/.next/standalone/lib/auto-connect.js +145 -0
  418. package/.next/standalone/lib/backups.js +458 -0
  419. package/.next/standalone/lib/chain-layout.js +32 -0
  420. package/.next/standalone/lib/companies.js +1 -1
  421. package/.next/standalone/lib/csv-store.js +131 -0
  422. package/.next/standalone/lib/csv.js +137 -39
  423. package/.next/standalone/lib/data-folder.js +19 -3
  424. package/.next/standalone/lib/data-import.js +5 -2
  425. package/.next/standalone/lib/db-client.js +78 -20
  426. package/.next/standalone/lib/demo.js +5 -4
  427. package/.next/standalone/lib/galaxy-export.js +9 -2
  428. package/.next/standalone/lib/galaxy-lab.js +19 -5
  429. package/.next/standalone/lib/galaxy-layouts.js +43 -0
  430. package/.next/standalone/lib/gate.js +10 -4
  431. package/.next/standalone/lib/in-progress.js +46 -0
  432. package/.next/standalone/lib/ingest.js +1 -1
  433. package/.next/standalone/lib/insights-board.js +613 -0
  434. package/.next/standalone/lib/linkedin-limits.js +240 -14
  435. package/.next/standalone/lib/liquid-glass.js +59 -0
  436. package/.next/standalone/lib/notifications.js +13 -0
  437. package/.next/standalone/lib/requests-client.js +10 -0
  438. package/.next/standalone/lib/requests.js +124 -0
  439. package/.next/standalone/lib/scan-pace.js +11 -0
  440. package/.next/standalone/lib/scan-progress.js +20 -0
  441. package/.next/standalone/lib/scan-risk.js +44 -0
  442. package/.next/standalone/lib/scan-state.js +1 -0
  443. package/.next/standalone/lib/scanner-setup.js +97 -15
  444. package/.next/standalone/lib/scraper-client.js +35 -8
  445. package/.next/standalone/lib/search-risk.js +7 -3
  446. package/.next/standalone/lib/settings-client.js +5 -3
  447. package/.next/standalone/lib/settings.js +13 -0
  448. package/.next/standalone/lib/social-store.js +3 -2
  449. package/.next/standalone/lib/synced-setting.js +46 -0
  450. package/.next/standalone/lib/theme-store.js +42 -10
  451. package/.next/standalone/lib/themes.js +111 -21
  452. package/.next/standalone/lib/usage.js +200 -0
  453. package/.next/standalone/package-lock.json +2 -2
  454. package/.next/standalone/package.json +1 -1
  455. package/.next/standalone/scripts/scrape.py +595 -11
  456. package/.next/static/chunks/02wnf8dkxegxg.js +34 -0
  457. package/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  458. package/.next/static/chunks/03-demj2iy-0p.js +44 -0
  459. package/.next/static/chunks/0838_s6w-i_ik.js +1 -0
  460. package/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  461. package/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
  462. package/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  463. package/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
  464. package/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
  465. package/.next/static/chunks/112mv-com-mqa.js +21 -0
  466. package/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
  467. package/.next/static/chunks/1cmphb3kh2ers.css +3 -0
  468. package/.next/static/chunks/1d8yv3k_atka7.js +1 -0
  469. package/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  470. package/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  471. package/.next/static/chunks/23hc51oa4vkhc.js +5 -0
  472. package/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
  473. package/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
  474. package/.next/static/chunks/2w-y83mjlpnse.js +1 -0
  475. package/.next/static/chunks/2ws1xf293j-tm.js +5 -0
  476. package/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  477. package/.next/static/chunks/34g73qhayuevu.js +1 -0
  478. package/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
  479. package/.next/static/chunks/3opgg1efrx8q6.js +1 -0
  480. package/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
  481. package/.next/static/chunks/3y40z6of3r9py.js +1 -0
  482. package/.next/static/chunks/403dpflln8ah5.js +1 -0
  483. package/.next/static/chunks/43pg2sursiypz.js +1 -0
  484. package/CHANGELOG.md +203 -0
  485. package/README.md +96 -50
  486. package/SECURITY.md +25 -11
  487. package/lib/auto-connect.js +145 -0
  488. package/lib/backups.js +458 -0
  489. package/lib/chain-layout.js +32 -0
  490. package/lib/companies.js +1 -1
  491. package/lib/csv-store.js +131 -0
  492. package/lib/csv.js +137 -39
  493. package/lib/data-folder.js +19 -3
  494. package/lib/data-import.js +5 -2
  495. package/lib/db-client.js +78 -20
  496. package/lib/demo.js +5 -4
  497. package/lib/galaxy-export.js +9 -2
  498. package/lib/galaxy-lab.js +19 -5
  499. package/lib/galaxy-layouts.js +43 -0
  500. package/lib/gate.js +10 -4
  501. package/lib/in-progress.js +46 -0
  502. package/lib/ingest.js +1 -1
  503. package/lib/insights-board.js +613 -0
  504. package/lib/linkedin-limits.js +240 -14
  505. package/lib/liquid-glass.js +59 -0
  506. package/lib/notifications.js +13 -0
  507. package/lib/requests-client.js +10 -0
  508. package/lib/requests.js +124 -0
  509. package/lib/scan-pace.js +11 -0
  510. package/lib/scan-progress.js +20 -0
  511. package/lib/scan-risk.js +44 -0
  512. package/lib/scan-state.js +1 -0
  513. package/lib/scanner-setup.js +97 -15
  514. package/lib/scraper-client.js +35 -8
  515. package/lib/search-risk.js +7 -3
  516. package/lib/settings-client.js +5 -3
  517. package/lib/settings.js +13 -0
  518. package/lib/social-store.js +3 -2
  519. package/lib/synced-setting.js +46 -0
  520. package/lib/theme-store.js +42 -10
  521. package/lib/themes.js +111 -21
  522. package/lib/usage.js +200 -0
  523. package/package.json +1 -1
  524. package/scripts/scrape.py +595 -11
  525. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +0 -3
  526. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13dx4sd._.js +0 -8
  527. package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +0 -3
  528. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +0 -3
  529. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +0 -3
  530. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +0 -3
  531. package/.next/standalone/.next/server/chunks/_02twlca._.js +0 -10
  532. package/.next/standalone/.next/server/chunks/lib_0851sk0._.js +0 -8
  533. package/.next/standalone/.next/server/chunks/lib_1q7p2ro._.js +0 -8
  534. package/.next/standalone/.next/server/chunks/lib_1r6l86l._.js +0 -8
  535. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +0 -174
  536. package/.next/standalone/.next/server/chunks/lib_rpc_04s8mzr.js +0 -3
  537. package/.next/standalone/.next/server/chunks/lib_rpc_053z7as.js +0 -3
  538. package/.next/standalone/.next/server/chunks/lib_rpc_0b_-2te.js +0 -3
  539. package/.next/standalone/.next/server/chunks/lib_rpc_0dhbxdm.js +0 -3
  540. package/.next/standalone/.next/server/chunks/lib_rpc_0dxlk31.js +0 -3
  541. package/.next/standalone/.next/server/chunks/lib_rpc_0f8b-qc.js +0 -3
  542. package/.next/standalone/.next/server/chunks/lib_rpc_0pzie7_.js +0 -3
  543. package/.next/standalone/.next/server/chunks/lib_rpc_0r76fq_.js +0 -3
  544. package/.next/standalone/.next/server/chunks/lib_rpc_0ut7pjp.js +0 -3
  545. package/.next/standalone/.next/server/chunks/lib_rpc_15zyqaz.js +0 -3
  546. package/.next/standalone/.next/server/chunks/lib_rpc_18zpjtq.js +0 -3
  547. package/.next/standalone/.next/server/chunks/lib_rpc_1a8xkiz.js +0 -3
  548. package/.next/standalone/.next/server/chunks/lib_rpc_1e_55xo.js +0 -3
  549. package/.next/standalone/.next/server/chunks/lib_rpc_1oxfd1_.js +0 -3
  550. package/.next/standalone/.next/server/chunks/lib_rpc_1s0lod0.js +0 -3
  551. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08oxiqh._.js +0 -3
  552. package/.next/standalone/.next/server/chunks/ssr/_03l7vge._.js +0 -3
  553. package/.next/standalone/.next/server/chunks/ssr/_08g31gm._.js +0 -3
  554. package/.next/standalone/.next/server/chunks/ssr/_0gk_ofx._.js +0 -3
  555. package/.next/standalone/.next/server/chunks/ssr/_0nwsf93._.js +0 -3
  556. package/.next/standalone/.next/server/chunks/ssr/_0vho1lb._.js +0 -3
  557. package/.next/standalone/.next/server/chunks/ssr/_1-658fq._.js +0 -3
  558. package/.next/standalone/.next/server/chunks/ssr/_1bc46kz._.js +0 -3
  559. package/.next/standalone/.next/server/chunks/ssr/_1f_n00p._.js +0 -3
  560. package/.next/standalone/.next/server/chunks/ssr/_2105jz8._.js +0 -3
  561. package/.next/standalone/.next/server/chunks/ssr/app_components_0t908t-._.js +0 -3
  562. package/.next/standalone/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  563. package/.next/standalone/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  564. package/.next/standalone/.next/static/chunks/0i02yxppzds1o.js +0 -1
  565. package/.next/standalone/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  566. package/.next/standalone/.next/static/chunks/0oyslj62jkubd.js +0 -1
  567. package/.next/standalone/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  568. package/.next/standalone/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  569. package/.next/standalone/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  570. package/.next/standalone/.next/static/chunks/172e10mi-tpo_.js +0 -34
  571. package/.next/standalone/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  572. package/.next/standalone/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  573. package/.next/standalone/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  574. package/.next/standalone/.next/static/chunks/1m3017gp790pw.js +0 -45
  575. package/.next/standalone/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  576. package/.next/standalone/.next/static/chunks/2-ch9rm27eril.js +0 -11
  577. package/.next/standalone/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  578. package/.next/standalone/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  579. package/.next/standalone/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  580. package/.next/standalone/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  581. package/.next/standalone/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  582. package/.next/standalone/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  583. package/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  584. package/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  585. package/.next/static/chunks/0i02yxppzds1o.js +0 -1
  586. package/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  587. package/.next/static/chunks/0oyslj62jkubd.js +0 -1
  588. package/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  589. package/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  590. package/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  591. package/.next/static/chunks/172e10mi-tpo_.js +0 -34
  592. package/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  593. package/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  594. package/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  595. package/.next/static/chunks/1m3017gp790pw.js +0 -45
  596. package/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  597. package/.next/static/chunks/2-ch9rm27eril.js +0 -11
  598. package/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  599. package/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  600. package/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  601. package/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  602. package/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  603. package/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  604. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
  605. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
  606. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
  607. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
  608. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
  609. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
@@ -0,0 +1,145 @@
1
+ // Auto: one connection request, sent for you from the scanner's Chrome.
2
+ //
3
+ // Blake, 2026-10-03: "auto add and basically adds the person for them in the
4
+ // card or wherever its available. now this will count in scans obviously for
5
+ // usage and one thing to prevent problems is that sometimes when adding it'll
6
+ // prompt the user to have a email from their work or to send a personal note
7
+ // if they have premium so if thats the case then have it close out of that in
8
+ // the scanner for adding but it should be seamless." Then: "i just want it next
9
+ // to connect button but say auto and makes it the better pick visually".
10
+ //
11
+ // That reverses the standing rule against automated LinkedIn actions, for this
12
+ // one action only: one press, one person. Never a batch, never on a timer. The
13
+ // scanner does the pressing (scripts/scrape.py --connect, connect_person); the
14
+ // app looks the person up by id and refuses before anything opens
15
+ // (app/api/scraper/route.js); this file holds what both sides must agree on:
16
+ // the caps, the result names the scanner prints, and the words the page shows.
17
+ //
18
+ // No Node imports: the page, the route and the tests all read it.
19
+
20
+ // Invitations in any 24 hours and in any 7 days (scripts/scrape.py
21
+ // INVITE_DAY_CAP, INVITE_WEEK_CAP; tests/auto-connect.test.mjs checks they
22
+ // match). LinkedIn doesn't publish its invitation limit; people commonly report
23
+ // about 100 a week, so the week stays well under that, and the day keeps a
24
+ // whole week from going in one sitting.
25
+ export const INVITE_CAPS = { day: 15, week: 80 };
26
+
27
+ // The weekly number people report, shown as a range people report, never as LinkedIn's.
28
+ export const REPORTED_WEEKLY_INVITES = 100;
29
+
30
+ export const AUTO_EXPLAIN = 'Sends the request for you from the scanner’s Chrome, without a note. Counts toward your LinkedIn usage.';
31
+
32
+ export const AUTO_CONFIRM = 'Auto sends connection requests from your LinkedIn account, one each time you press it. '
33
+ + 'LinkedIn limits how many invitations an account can send, and may restrict accounts that send many.';
34
+
35
+ // The server's answer until the one-time yes is given (the page then asks it).
36
+ export const AUTO_REFUSAL = 'Auto asks once before its first request. Press Auto again and confirm.';
37
+
38
+ /** When Auto's one-time question was answered yes (ISO time), or null. Saved in Settings (lib/settings.js). */
39
+ export const AUTO_ACCEPTED_SETTING = {
40
+ default: null,
41
+ parse(value) {
42
+ if (value === null) return null;
43
+ if (typeof value !== 'string' || Number.isNaN(Date.parse(value))) {
44
+ throw new Error('When Auto was first allowed is a date and time.');
45
+ }
46
+ return new Date(value).toISOString();
47
+ },
48
+ };
49
+
50
+ // The one line the scanner prints to say how a request went (scrape.py
51
+ // connect_result), read by the route as the job's log arrives.
52
+ export const CONNECT_RESULT = /^Connect result: ([a-z-]+)$/;
53
+
54
+ /** The result named on a log line, or null. */
55
+ export function connectResultIn(line) {
56
+ const m = String(line ?? '').trim().match(CONNECT_RESULT);
57
+ return m && Object.hasOwn(OUTCOMES, m[1]) ? m[1] : null;
58
+ }
59
+
60
+ const day = INVITE_CAPS.day;
61
+ const week = INVITE_CAPS.week;
62
+
63
+ // Every result the scanner can print (scrape.py CONNECT_RESULTS; the test
64
+ // checks both lists are the same). `marks`: the request is marked as sent here,
65
+ // everywhere at once. Only a send the profile then showed as Pending, or one
66
+ // that was already pending, does that; anything unclear does not (TRAPS §7).
67
+ export const OUTCOMES = {
68
+ sent: { ok: true, marks: true, text: 'Request sent' },
69
+ 'already-pending': { ok: true, marks: true, text: 'A request to them was already pending on LinkedIn, so nothing new was sent. It’s marked as sent here.' },
70
+ 'email-needed': { text: 'LinkedIn wants their email address before it sends this one. Use Connect to add them yourself.' },
71
+ 'no-connect': { text: 'LinkedIn shows no Connect for them here, only Follow or Message, or a request is already out. Nothing was sent.' },
72
+ 'not-sent': { text: 'LinkedIn asked something Auto doesn’t answer for you, so it closed that and sent nothing. Use Connect to add them yourself.' },
73
+ unclear: { text: 'Auto pressed Send but couldn’t see the request go through, so it isn’t marked as sent. Use Connect to check their profile.' },
74
+ 'not-loaded': { text: 'Their profile didn’t load, so nothing was sent. Try again in a while.' },
75
+ unavailable: { text: 'LinkedIn says their profile isn’t available, so nothing was sent.' },
76
+ 'linkedin-limit': { text: 'LinkedIn says this account has reached its invitation limit for now. Nothing was sent.' },
77
+ pushback: { text: 'LinkedIn pushed back, so scanning and Auto are paused for a day. Settings, LinkedIn usage says when it ends.' },
78
+ stopped: { text: 'Stopped before anything was sent.' },
79
+ 'not-signed-in': { text: 'LinkedIn isn’t signed in in the scanner’s Chrome. Sign in on the Scan page (step 2), then try again.' },
80
+ cooldown: { text: 'Scanning is paused after LinkedIn pushed back, and Auto waits with it. Nothing was sent.' },
81
+ 'invites-day': { text: `Auto has sent ${day} requests in the last 24 hours, its limit. Nothing was sent.` },
82
+ 'invites-week': { text: `Auto has sent ${week} requests in the last 7 days, its limit. Nothing was sent.` },
83
+ profiles: { text: 'Today’s profile views are used, and Auto opens their profile to send. Nothing was sent.' },
84
+ 'not-found': { text: 'That person isn’t in your network on this computer, so nothing was sent.' },
85
+ };
86
+
87
+ export const RESULT_NAMES = Object.keys(OUTCOMES);
88
+
89
+ /** Does this result mark the request as sent? */
90
+ export const connectMarks = (result) => Boolean(OUTCOMES[result]?.marks);
91
+
92
+ /**
93
+ * What the page says once an Auto job has ended: { result, ok, marks, text }.
94
+ * `end` is how the job ended (lib/scraper-client.js runScrape): its `outcome`
95
+ * (the route's reading of the result line), else its failure, else a plain
96
+ * "couldn't finish". Never says sent without the scanner saying so.
97
+ */
98
+ export function connectOutcome(end) {
99
+ const result = end?.outcome && Object.hasOwn(OUTCOMES, end.outcome) ? end.outcome : null;
100
+ if (result) {
101
+ const o = OUTCOMES[result];
102
+ return { result, ok: Boolean(o.ok), marks: Boolean(o.marks), text: o.text };
103
+ }
104
+ const why = Array.isArray(end?.failure) ? end.failure.filter(Boolean).slice(-2).join(' ') : '';
105
+ return {
106
+ result: null, ok: false, marks: false,
107
+ text: why ? `Auto couldn’t finish, and nothing is marked as sent: ${why}` : 'Auto couldn’t finish, and nothing is marked as sent.',
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Why the route won't start an Auto request because of a cap, or null.
113
+ * `li` is lib/linkedin-limits.js linkedinState: invitesToday, invitesWeek,
114
+ * invitesFreeAt / invitesWeekFreeAt (ms) and profilesLeftToday. `when` turns a
115
+ * time into words.
116
+ */
117
+ export function inviteRefusal(li, when = (ms) => new Date(ms).toLocaleString()) {
118
+ if (!li) return null;
119
+ if (li.unreadable) return 'The record of what Six Degrees has asked of LinkedIn couldn’t be read, so Auto waits until it can.';
120
+ if (li.invitesToday >= day) {
121
+ return `Auto has sent ${day} requests in the last 24 hours, its limit.${li.invitesFreeAt ? ` The next one frees up ${when(li.invitesFreeAt)}.` : ''}`;
122
+ }
123
+ if (li.invitesWeek >= week) {
124
+ return `Auto has sent ${week} requests in the last 7 days, its limit.${li.invitesWeekFreeAt ? ` The next one frees up ${when(li.invitesWeekFreeAt)}.` : ''}`;
125
+ }
126
+ if (li.profilesLeftToday === 0) {
127
+ return 'Today’s profile views are used, and Auto opens their profile to send the request. Try again once one frees up (Settings, LinkedIn usage).';
128
+ }
129
+ return null;
130
+ }
131
+
132
+ /**
133
+ * Why this person can't be sent a request from here, or null when they can.
134
+ * `person` is their row; `connected` is true when they're one of your own
135
+ * connections (any copy of them at degree 1); `requested` when a request to
136
+ * them is already out (any copy marked sent or pending).
137
+ */
138
+ export function personRefusal(person, { connected = false, requested = false, accepted = false } = {}) {
139
+ if (!person) return { status: 400, error: 'That person could not be found.' };
140
+ const name = person.name || 'They';
141
+ if (connected || accepted || person.degree === 1) return { status: 409, error: `${name} is already one of your connections.` };
142
+ if (requested) return { status: 409, error: `A request to ${name} is already out.` };
143
+ if (!person.profile_url) return { status: 400, error: `There is no LinkedIn profile on file for ${name}.` };
144
+ return null;
145
+ }
@@ -0,0 +1,458 @@
1
+ // Backups: copies of the whole network kept in backups/, so the app keeps
2
+ // working without anyone looking after it (Blake, 2026-10-03: proper backups
3
+ // of his connections and photos).
4
+ //
5
+ // No new format. A backup is a .sixdegrees file, the same one Settings →
6
+ // Your data exports (lib/data-export.js): the database (the settings in it),
7
+ // the photos of the people in it and the scanner's files, each file with its
8
+ // SHA-256. So a backup is checked by the same importer that would restore it
9
+ // (validateImport), and restoring one is an import of it (stageImport), with
10
+ // the same Restart now and the same copy of what was there kept first.
11
+ //
12
+ // Never the Social tab's files (BACKUP_SOCIAL). Its messages are kept only
13
+ // while Keep my messages is on, and Forget it deletes them and the numbers
14
+ // (lib/social-store.js): a copy made every day and kept for a week, or for
15
+ // good, would keep what Forget it promised to delete. An export still carries
16
+ // them when its box is ticked: someone chose that copy. Because a backup
17
+ // brings none, restoring one leaves this computer's Social files where they
18
+ // are (applyPendingImport steps them aside only for a copy that brings its own).
19
+ //
20
+ // Written aside as a hidden .partial, synced, checked, and only then renamed
21
+ // to its name (the vacuumCopy pattern, lib/data-import.js): a file with a
22
+ // backup's name is always a whole one that passed the importer's checks. A
23
+ // copy that fails its check is never kept under a backup's name, so it can
24
+ // never push a good one out of the rotation.
25
+ //
26
+ // When they are made: before a new version first opens the data
27
+ // (lib/db-client.js backupOnNewVersion), once a day, checked when the server
28
+ // starts and after each scan (no timers: nothing runs that nobody started),
29
+ // and when someone clicks Back up now. Which are kept is KEEP below.
30
+
31
+ import { DatabaseSync } from 'node:sqlite';
32
+ import {
33
+ rmSync, renameSync, mkdirSync, lstatSync, copyFileSync, mkdtempSync,
34
+ } from 'node:fs';
35
+ import path from 'node:path';
36
+ import { buildExport, countPeople, EXPORT_EXTENSION } from './data-export.js';
37
+ import { validateImport, stageImport, ImportError } from './data-import.js';
38
+ import {
39
+ listBackups, namesInFolder, IMPORT_BACKUP_PREFIX, UPLOAD_WORK_PREFIX, sweepLeftovers,
40
+ } from './data-folder.js';
41
+ import { runningNow } from './scan-state.js';
42
+ import { durable } from './durable.js';
43
+
44
+ /** The kinds makeBackup makes. A copy kept before an import is made by the import itself (applyPendingImport). */
45
+ export const MADE_KINDS = ['daily', 'before-update', 'manual'];
46
+
47
+ /**
48
+ * How many of each kind are kept, newest first. One made by hand (Back up
49
+ * now, or anything someone put in backups/ themselves) is never deleted.
50
+ */
51
+ export const KEEP = Object.freeze({ daily: 7, 'before-update': 3, 'before-import': 3 });
52
+
53
+ /**
54
+ * A copy kept before an import (or a restore) is the only way back from it, so
55
+ * it stays for at least this long however many imports follow.
56
+ */
57
+ export const IMPORT_FLOOR_MS = 30 * 24 * 3600 * 1000;
58
+
59
+ /** Whether a backup carries the Social tab's files: never (see the top of this file). */
60
+ export const BACKUP_SOCIAL = false;
61
+
62
+ /** A daily backup is made when the newest is at least this old. */
63
+ export const DAILY_EVERY_MS = 24 * 3600 * 1000;
64
+
65
+ /** backups/ names before this feature: the database alone, before a new version (lib/db-client.js). */
66
+ export const AUTO_BACKUP_PREFIX = 'auto-before-';
67
+
68
+ // A half-written backup a stopped server left: hidden, so no listing shows it,
69
+ // and swept once it is an hour old (never one a running backup is writing).
70
+ const PARTIAL = /^\..+\.partial(?:-journal)?$/;
71
+ const PARTIAL_AGE_MS = 3600 * 1000;
72
+
73
+ const STAMP = /(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z/;
74
+ const MADE = /^(daily|before-update|manual)-(.+)-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z)\.sixdegrees$/;
75
+ const SIDE = /^(.+\.sqlite)-(?:wal|shm|journal)$/;
76
+ const FILES = /^(.+)-files$/;
77
+
78
+ /** The time in a name, as every backup's name carries it (2026-10-03T14-05-09-123Z), or null. */
79
+ export function stampTime(name) {
80
+ const m = STAMP.exec(String(name));
81
+ if (!m) return null;
82
+ const t = Date.parse(`${m[1]}T${m[2]}:${m[3]}:${m[4]}.${m[5]}Z`);
83
+ return Number.isFinite(t) ? t : null;
84
+ }
85
+
86
+ const stampOf = (now) => now.toISOString().replace(/[:.]/g, '-');
87
+
88
+ /** "daily-0.7.0-2026-10-03T14-05-09-123Z.sixdegrees" */
89
+ export function backupName(kind, version, now = new Date()) {
90
+ return `${kind}-${version}-${stampOf(now)}${EXPORT_EXTENSION}`;
91
+ }
92
+
93
+ /** What one name in backups/ is: its kind, its format, and whether it can be restored. */
94
+ function describe(entry, autoPrefix) {
95
+ const { name } = entry;
96
+ const out = {
97
+ name,
98
+ kind: 'manual',
99
+ format: null, // 'sixdegrees' (photos and files inside) or 'database' (the database alone)
100
+ version: null,
101
+ restorable: false,
102
+ byHand: true, // put in backups/ by someone, not made by Six Degrees
103
+ withFiles: null, // the folder of photos and files kept beside a database copy
104
+ parts: [], // names that go with it: that folder, a -wal or -shm
105
+ bytes: entry.bytes,
106
+ modifiedAt: entry.modifiedAt,
107
+ at: stampTime(name) ?? entry.modifiedAt,
108
+ folder: entry.folder,
109
+ };
110
+ if (entry.folder) return out;
111
+ const made = MADE.exec(name);
112
+ if (made) {
113
+ Object.assign(out, { kind: made[1], version: made[2], format: 'sixdegrees', byHand: false });
114
+ } else if (name.startsWith(autoPrefix) && name.endsWith('.sqlite')) {
115
+ const rest = name.slice(autoPrefix.length, -'.sqlite'.length);
116
+ const at = STAMP.exec(rest);
117
+ Object.assign(out, {
118
+ kind: 'before-update', format: 'database', byHand: false,
119
+ version: at ? rest.slice(0, at.index).replace(/-$/, '') || null : null,
120
+ });
121
+ } else if (name.startsWith(IMPORT_BACKUP_PREFIX) && name.endsWith('.sqlite')) {
122
+ Object.assign(out, { kind: 'before-import', format: 'database', byHand: false });
123
+ } else if (name.endsWith(EXPORT_EXTENSION)) {
124
+ out.format = 'sixdegrees';
125
+ } else if (name.endsWith('.sqlite')) {
126
+ out.format = 'database';
127
+ }
128
+ out.restorable = out.format !== null;
129
+ return out;
130
+ }
131
+
132
+ /**
133
+ * Every backup in `folder`, newest first, as the Settings page lists them: a
134
+ * database copy with its -wal, -shm and its folder of photos and files is one
135
+ * backup. Names come from the folder's own listing (lib/data-folder.js
136
+ * listBackups), so nothing here is ever a path someone sent.
137
+ */
138
+ export function describeBackups(folder, { autoPrefix = AUTO_BACKUP_PREFIX } = {}) {
139
+ const raw = listBackups(folder, { autoPrefix });
140
+ const names = new Set(raw.map((b) => b.name));
141
+ const owners = new Map();
142
+ const extras = [];
143
+ for (const b of raw) {
144
+ const side = SIDE.exec(b.name);
145
+ if (!b.folder && side && names.has(side[1])) { extras.push([side[1], b]); continue; }
146
+ const files = FILES.exec(b.name);
147
+ if (b.folder && files && names.has(`${files[1]}.sqlite`)) { extras.push([`${files[1]}.sqlite`, b]); continue; }
148
+ owners.set(b.name, describe(b, autoPrefix));
149
+ }
150
+ for (const [owner, b] of extras) {
151
+ const o = owners.get(owner);
152
+ o.bytes += b.bytes || 0;
153
+ o.parts.push(b.name);
154
+ if (b.folder) o.withFiles = b.name;
155
+ }
156
+ return [...owners.values()].sort((a, b) => b.at - a.at || b.name.localeCompare(a.name));
157
+ }
158
+
159
+ /** Delete one backup and whatever goes with it. Only names from the listing. */
160
+ function removeBackup(folder, entry) {
161
+ for (const name of [...entry.parts, entry.name]) {
162
+ rmSync(path.join(folder, name), { recursive: true, force: true });
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Keep KEEP of each kind, newest first; never one made by hand; never a copy
168
+ * from before an import that is under 30 days old. Also sweeps half-written
169
+ * backups a stopped server left. @returns the names deleted.
170
+ */
171
+ export function rotateBackups(folder, { now = Date.now(), keep = KEEP, floorMs = IMPORT_FLOOR_MS, autoPrefix = AUTO_BACKUP_PREFIX } = {}) {
172
+ const at = now instanceof Date ? now.getTime() : now;
173
+ const all = describeBackups(folder, { autoPrefix });
174
+ const removed = [];
175
+ for (const [kind, n] of Object.entries(keep)) {
176
+ for (const entry of all.filter((e) => e.kind === kind && !e.byHand).slice(n)) {
177
+ if (kind === 'before-import' && at - entry.at < floorMs) continue;
178
+ removeBackup(folder, entry);
179
+ removed.push(entry.name);
180
+ }
181
+ }
182
+ for (const name of namesInFolder(folder)) {
183
+ if (!PARTIAL.test(name)) continue;
184
+ try {
185
+ if (at - lstatSync(path.join(folder, name)).mtimeMs >= PARTIAL_AGE_MS) rmSync(path.join(folder, name), { force: true });
186
+ } catch { /* gone already */ }
187
+ }
188
+ if (removed.length) durable.syncFolder(folder);
189
+ return removed;
190
+ }
191
+
192
+ // ── checking ─────────────────────────────────────────────────────────────────
193
+
194
+ // Checked once per file per server: a check reads every page and every photo,
195
+ // and the page asks often. The same file (name, size and time) gives the same
196
+ // answer; a file that changes on the disk is checked again. One map per
197
+ // process however the bundler splits route modules, like lib/scan-state.js.
198
+ const CHECKED = Symbol.for('six-degrees.backups-checked');
199
+ const FAILED = Symbol.for('six-degrees.backup-failed');
200
+ const checkedFiles = () => (globalThis[CHECKED] ||= new Map());
201
+
202
+ /** The importer's refusal, without the words that only fit an import. */
203
+ export function plainProblem(message) {
204
+ return String(message || 'it could not be read')
205
+ .replace(/,? so nothing was imported\..*$/s, '.')
206
+ .replace(/\s+Export it again on the other computer\.?$/, '');
207
+ }
208
+
209
+ /**
210
+ * Would this backup restore? The importer's own checks (validateImport): SQLite's
211
+ * integrity check, nothing an export never holds, every row count and every
212
+ * file's checksum against its manifest.
213
+ * @returns {{ ok: true, people, photos, exportedAt, fromVersion } | { ok: false, problem }}
214
+ */
215
+ export function checkBackup(file, { applySchema, schemaSql, appVersion }) {
216
+ try {
217
+ const info = validateImport(file, { applySchema, schemaSql, appVersion });
218
+ return { ok: true, ...info };
219
+ } catch (err) {
220
+ const problem = plainProblem(err instanceof ImportError ? err.message : `It could not be read (${err.message}).`);
221
+ return { ok: false, problem: problem.replace(/^This file/, 'This backup') };
222
+ }
223
+ }
224
+
225
+ function fileKey(file) {
226
+ try {
227
+ const s = lstatSync(file);
228
+ return s.isFile() ? `${file}|${s.size}|${s.mtimeMs}` : null;
229
+ } catch {
230
+ return null;
231
+ }
232
+ }
233
+
234
+ /** checkBackup, remembered for the same file. */
235
+ export function checkBackupOnce(file, opts) {
236
+ const key = fileKey(file);
237
+ if (!key) return { ok: false, problem: 'It is no longer there.' };
238
+ const memo = checkedFiles();
239
+ if (!memo.has(key)) memo.set(key, checkBackup(file, opts));
240
+ return memo.get(key);
241
+ }
242
+
243
+ /** The last backup that couldn't be made in this server, for the page; cleared by the next that works. */
244
+ export function backupFailure() {
245
+ return globalThis[FAILED] || null;
246
+ }
247
+
248
+ export function noteBackupFailure(kind, err, now = new Date()) {
249
+ globalThis[FAILED] = { kind, at: now.toISOString(), message: plainProblem(err?.message || String(err)) };
250
+ }
251
+
252
+ // ── making ───────────────────────────────────────────────────────────────────
253
+
254
+ /**
255
+ * Make a backup of the open database `db` and the data folder `dataDir` in
256
+ * `backupsDir`: the whole network as a .sixdegrees file, with every photo of
257
+ * someone in it and the scanner's files (not the Social tab's: BACKUP_SOCIAL).
258
+ *
259
+ * `appVersion` is the version making it (in its name); `dataVersion` the one
260
+ * whose data it holds (in its manifest), which differs only before an update:
261
+ * that copy holds the old version's data, so the old version can restore it.
262
+ *
263
+ * @returns {{ name, file, bytes, people, photos, kind, verified: true }}
264
+ * @throws when it can't be made or fails its check; nothing is left under a backup's name then.
265
+ */
266
+ export function makeBackup(kind, {
267
+ db, dataDir, backupsDir, appVersion, dataVersion = appVersion, schemaSql, applySchema, now = new Date(), rotate = true,
268
+ }) {
269
+ if (!MADE_KINDS.includes(kind)) throw new Error(`There is no kind of backup called '${kind}'.`);
270
+ mkdirSync(backupsDir, { recursive: true });
271
+ const name = backupName(kind, appVersion, now);
272
+ const file = path.join(backupsDir, name);
273
+ const partial = path.join(backupsDir, `.${name}.partial`);
274
+ const tidy = () => {
275
+ rmSync(partial, { force: true });
276
+ rmSync(`${partial}-journal`, { force: true });
277
+ };
278
+ tidy();
279
+ let made;
280
+ try {
281
+ made = buildExport(db, {
282
+ dir: dataDir, outFile: partial, includePhotos: true, includeSocial: BACKUP_SOCIAL, appVersion: dataVersion, schemaSql, now,
283
+ });
284
+ // SQLite doesn't sync what VACUUM INTO writes (lib/durable.js).
285
+ durable.syncFile(partial);
286
+ const check = checkBackup(partial, { applySchema, schemaSql, appVersion });
287
+ if (!check.ok) throw new Error(`the copy failed its check: ${check.problem}`);
288
+ renameSync(partial, file);
289
+ durable.syncFolder(backupsDir);
290
+ } catch (err) {
291
+ tidy();
292
+ throw err;
293
+ }
294
+ const key = fileKey(file);
295
+ if (key) checkedFiles().set(key, { ok: true, people: made.people, photos: made.photos });
296
+ globalThis[FAILED] = null;
297
+ if (rotate) {
298
+ // A backup that was made stays made, even if an old one can't be deleted.
299
+ try { rotateBackups(backupsDir, { now }); } catch { /* tried again after the next one */ }
300
+ }
301
+ return { name, file, kind, bytes: made.bytes, people: made.people, photos: made.photos, verified: true };
302
+ }
303
+
304
+ /** When was the newest daily backup made? null when there is none. */
305
+ export function newestDaily(backupsDir) {
306
+ return describeBackups(backupsDir).find((e) => e.kind === 'daily')?.at ?? null;
307
+ }
308
+
309
+ /**
310
+ * Is a daily backup due? When there is none, or the newest is a day old. One
311
+ * stamped more than a day ahead of now (the clock was changed) doesn't hold
312
+ * the next one back forever.
313
+ */
314
+ export function dailyDue(newest, now = Date.now()) {
315
+ if (newest == null) return true;
316
+ return now - newest >= DAILY_EVERY_MS || newest - now >= DAILY_EVERY_MS;
317
+ }
318
+
319
+ /**
320
+ * The daily backup, if one is due and there is a network to back up. Called
321
+ * when the server opens the database and after each scan. @returns the backup, or null.
322
+ */
323
+ export function dailyBackupIfDue(opts) {
324
+ const now = opts.now || new Date();
325
+ if (!dailyDue(newestDaily(opts.backupsDir), now.getTime())) return null;
326
+ if (countPeople(opts.db) === 0) return null;
327
+ try {
328
+ return makeBackup('daily', { ...opts, now });
329
+ } catch (err) {
330
+ noteBackupFailure('daily', err, now);
331
+ throw err;
332
+ }
333
+ }
334
+
335
+ // ── what the page shows ──────────────────────────────────────────────────────
336
+
337
+ /**
338
+ * The backups for the Settings page, newest first, and the newest restorable
339
+ * .sixdegrees backup checked (once per file per server): "Last backup: <time>,
340
+ * verified", or what is wrong with it (TRAPS §7: a damaged copy says so).
341
+ */
342
+ export function backupReport(backupsDir, { applySchema, schemaSql, appVersion }) {
343
+ const backups = describeBackups(backupsDir);
344
+ const newest = backups.find((e) => e.format === 'sixdegrees' && !e.byHand) || null;
345
+ let last = null;
346
+ if (newest) {
347
+ const check = checkBackupOnce(path.join(backupsDir, newest.name), { applySchema, schemaSql, appVersion });
348
+ last = {
349
+ name: newest.name,
350
+ kind: newest.kind,
351
+ at: new Date(newest.at).toISOString(),
352
+ verified: check.ok,
353
+ people: check.ok ? check.people ?? null : null,
354
+ problem: check.ok ? null : check.problem,
355
+ };
356
+ }
357
+ return { backups, last, failed: backupFailure(), keep: KEEP, floorDays: IMPORT_FLOOR_MS / (24 * 3600 * 1000) };
358
+ }
359
+
360
+ // ── restoring ────────────────────────────────────────────────────────────────
361
+
362
+ /**
363
+ * The checks before a restore, as an import makes them (lib/data-import.js
364
+ * importPreflight): nothing running, no import waiting, and a yes that names
365
+ * how many people it replaces. @returns an ImportError, or null to go ahead.
366
+ */
367
+ export function restorePreflight({ scanRunning, pending, currentPeople = 0, confirmedPeople }) {
368
+ if (scanRunning) {
369
+ return new ImportError(`${runningNow(scanRunning)}. Let it finish, or stop it on the Scan page, then restore.`, { status: 409 });
370
+ }
371
+ if (pending) {
372
+ return new ImportError('An import or a restore is already waiting to finish. Restart Six Degrees to finish it, or cancel it first.', { status: 409 });
373
+ }
374
+ if (currentPeople > 0 && confirmedPeople !== currentPeople) {
375
+ return new ImportError(
376
+ `This copy has ${currentPeople.toLocaleString('en-US')} people. Confirm that the backup replaces them.`,
377
+ { status: 409, needsConfirm: true, people: currentPeople },
378
+ );
379
+ }
380
+ return null;
381
+ }
382
+
383
+ /**
384
+ * The backup called `name`, only if it is one of the names backups/ holds now
385
+ * (lib/data-folder.js listBackups) and, unless `restorable` is false (Show in
386
+ * Finder), can be restored. Never a path: a name with a folder in it, "..", or
387
+ * anything the folder doesn't list is refused.
388
+ */
389
+ export function findBackup(backupsDir, name, { restorable = true } = {}) {
390
+ if (typeof name !== 'string' || !name || name !== path.basename(name) || name === '.' || name === '..'
391
+ || /[\\/\0]/.test(name)) {
392
+ return null;
393
+ }
394
+ if (!listBackups(backupsDir).some((b) => b.name === name)) return null;
395
+ return describeBackups(backupsDir).find((e) => e.name === name && (e.restorable || !restorable)) || null;
396
+ }
397
+
398
+ /**
399
+ * Stage a backup to replace the network at the next start: the same as an
400
+ * import (stageImport), from a copy of the backup in a private working folder,
401
+ * so the backup itself is never moved or changed. A database-only copy (from
402
+ * before this feature, or kept before an import) is made into a .sixdegrees
403
+ * file first, with the photos and files kept beside it, or, for one that has
404
+ * none, the photos and files here now.
405
+ * @returns what the page shows while it waits (READY).
406
+ * @throws ImportError, fit to show.
407
+ */
408
+ export function restoreBackup(name, {
409
+ dir, backupsDir, applySchema, schemaSql, appVersion, replacedPeople = 0, now = new Date(),
410
+ }) {
411
+ const entry = findBackup(backupsDir, name);
412
+ if (!entry) throw new ImportError('There is no backup by that name in the backups folder.', { status: 404 });
413
+ sweepLeftovers(dir);
414
+ const work = mkdtempSync(path.join(dir, UPLOAD_WORK_PREFIX));
415
+ try {
416
+ const upload = path.join(work, 'upload.sixdegrees');
417
+ const source = path.join(backupsDir, entry.name);
418
+ if (entry.format === 'sixdegrees') {
419
+ copyFileSync(source, upload);
420
+ } else {
421
+ // Read from a private copy: SQLite may write beside a database it opens,
422
+ // and nothing is ever written into backups/ by a restore.
423
+ const copy = path.join(work, 'backup.sqlite');
424
+ copyFileSync(source, copy);
425
+ let db;
426
+ try {
427
+ db = new DatabaseSync(copy);
428
+ } catch (err) {
429
+ throw new ImportError(`This backup couldn't be opened (${err.message}).`);
430
+ }
431
+ try {
432
+ // A copy kept before an import has the files that import stepped
433
+ // aside beside it, the Social tab's among them only if the import
434
+ // brought its own: undoing it puts them back. One with none beside it
435
+ // takes the photos and scanner files here now, and leaves the Social
436
+ // tab's where they are.
437
+ buildExport(db, {
438
+ dir: entry.withFiles ? path.join(backupsDir, entry.withFiles) : dir,
439
+ outFile: upload, includePhotos: true, includeSocial: Boolean(entry.withFiles), appVersion, schemaSql, now,
440
+ });
441
+ } catch (err) {
442
+ throw new ImportError(`This backup couldn't be read (${err.message}).`);
443
+ } finally {
444
+ db.close();
445
+ }
446
+ rmSync(copy, { force: true });
447
+ }
448
+ return stageImport(upload, {
449
+ dir, applySchema, schemaSql, appVersion, replacedPeople, now, restoredFrom: entry.name,
450
+ });
451
+ } catch (err) {
452
+ rmSync(work, { recursive: true, force: true });
453
+ if (err instanceof ImportError) {
454
+ throw new ImportError(plainProblem(err.message).replace(/^This file/, 'This backup'), { status: err.status, ...err.extra });
455
+ }
456
+ throw err;
457
+ }
458
+ }
@@ -296,3 +296,35 @@ function spread(wanted, sep) {
296
296
  seq.forEach((i, k) => { out[i] = placed[k]; });
297
297
  return out;
298
298
  }
299
+
300
+ /**
301
+ * How much is going on in each circle, for the order Bridge Chains rings them in:
302
+ * the busiest on the inner ring (Blake, 2026-10-03: "the inner most ring to have
303
+ * the clusters with the most amount of notifications ... a cluster that has been
304
+ * formed after scanning or if someone added back and is available to scan").
305
+ * Every notification about the circle counts, an unread one twice; so does each
306
+ * person in it who added you back and is ready to scan, and each cluster of
307
+ * their own that has formed from it since.
308
+ *
309
+ * @param {Array<{id: any}>} circles
310
+ * @param {{ notes?: Array<{circle: string|null, seen?: boolean}>, ready?: Map, chained?: Map }} facts
311
+ * @returns {Map<any, {score: number, notes: number, unread: number, ready: number, chains: number}>}
312
+ */
313
+ export function circleActivity(circles, { notes = [], ready = new Map(), chained = new Map() } = {}) {
314
+ const byCircle = new Map();
315
+ for (const n of notes) {
316
+ if (n?.circle == null) continue;
317
+ const c = byCircle.get(n.circle) || { notes: 0, unread: 0 };
318
+ c.notes += 1;
319
+ if (!n.seen) c.unread += 1;
320
+ byCircle.set(n.circle, c);
321
+ }
322
+ const out = new Map();
323
+ for (const b of circles) {
324
+ const n = byCircle.get(String(b.id)) || { notes: 0, unread: 0 };
325
+ const r = ready.get(b.id) || 0;
326
+ const ch = chained.get(b.id) || 0;
327
+ out.set(b.id, { score: n.notes + n.unread + r + ch, notes: n.notes, unread: n.unread, ready: r, chains: ch });
328
+ }
329
+ return out;
330
+ }
@@ -52,7 +52,7 @@ export const INDUSTRIES = [
52
52
  { key: 'realestate', label: 'Real Estate & Construction', color: '#d35400',
53
53
  words: /\b(real estate|realtor|realty|property|properties|construction|architecture|architect|mortgage|homes|housing|builders?)\b/i },
54
54
  { key: 'consumer', label: 'Retail, Consumer & Hospitality', color: '#ff79c6',
55
- words: /\b(retail|e-?commerce|shopify|consumer|cpg|fashion|apparel|beauty|cosmetics|food|beverage|restaurant|hospitality|hotel|travel|tourism|coca-cola|nike|store|shop)\b/i },
55
+ words: /\b(retail|e-?commerce|shopify|consumer|cpg|fashion|apparel|beauty|cosmetics|foods?|beverages?|restaurant|hospitality|hotel|travel|tourism|coca-cola|nike|store|shop)\b/i },
56
56
  { key: 'industry', label: 'Manufacturing, Energy & Logistics', color: '#95a5a6',
57
57
  words: /\b(manufacturing|energy|oil|gas|solar|utilities|automotive|tesla|siemens|ge|general electric|honeywell|3m|logistics|supply chain|shipping|freight|fedex|ups|industrial|mining|chemicals?)\b/i },
58
58
  { key: 'nonprofit', label: 'Nonprofit & Community', color: '#bdc3c7',