six-degrees 0.6.0 → 0.7.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 (557) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +3 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +14 -14
  5. package/.next/standalone/.next/routes-manifest.json +18 -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 +2 -2
  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 +4 -2
  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/launch/page.js +1 -1
  115. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/launch.html +2 -2
  118. package/.next/standalone/.next/server/app/launch.rsc +32 -24
  119. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +32 -24
  120. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
  121. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +23 -18
  122. package/.next/standalone/.next/server/app/page.js +1 -1
  123. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/paths/page.js +1 -1
  126. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  127. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/paths.html +1 -1
  129. package/.next/standalone/.next/server/app/paths.rsc +32 -24
  130. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +32 -24
  131. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
  132. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +21 -18
  133. package/.next/standalone/.next/server/app/profile/page.js +1 -1
  134. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  135. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/profile.html +1 -1
  137. package/.next/standalone/.next/server/app/profile.rsc +32 -24
  138. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +32 -24
  139. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
  140. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +23 -18
  141. package/.next/standalone/.next/server/app/queue/page.js +1 -1
  142. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  143. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/queue.html +1 -1
  145. package/.next/standalone/.next/server/app/queue.rsc +32 -24
  146. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +32 -24
  147. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
  148. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +20 -18
  149. package/.next/standalone/.next/server/app/scores/page.js +1 -1
  150. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  151. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/scores.html +1 -1
  153. package/.next/standalone/.next/server/app/scores.rsc +32 -24
  154. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +32 -24
  155. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
  156. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +23 -18
  157. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  158. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  159. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  160. package/.next/standalone/.next/server/app/settings.html +1 -1
  161. package/.next/standalone/.next/server/app/settings.rsc +32 -24
  162. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +32 -24
  163. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  164. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +20 -18
  165. package/.next/standalone/.next/server/app/setup/page.js +1 -1
  166. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  167. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  168. package/.next/standalone/.next/server/app/setup.html +1 -1
  169. package/.next/standalone/.next/server/app/setup.rsc +32 -24
  170. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +32 -24
  171. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  172. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +21 -18
  173. package/.next/standalone/.next/server/app/social/page.js +1 -1
  174. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  175. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/social.html +1 -1
  177. package/.next/standalone/.next/server/app/social.rsc +32 -24
  178. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +32 -24
  179. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
  180. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +23 -18
  181. package/.next/standalone/.next/server/app-paths-manifest.json +3 -0
  182. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +1 -1
  183. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05_3-22._.js +1 -1
  184. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__15wc9e-._.js → [root-of-the-server]__063s0x7._.js} +2 -2
  185. package/.next/standalone/.next/server/chunks/[root-of-the-server]__066rab1._.js +7 -0
  186. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
  187. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__13dx4sd._.js → [root-of-the-server]__0_4y8z7._.js} +3 -3
  188. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +1 -1
  189. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +1 -1
  190. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fooke1._.js +7 -0
  191. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
  192. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +1 -1
  193. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +1 -1
  194. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +1 -1
  195. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t6y79e._.js +7 -0
  196. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x29muh._.js +7 -0
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +1 -1
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +1 -1
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +1 -1
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +1 -1
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a_6x37._.js +8 -0
  203. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an_8pa._.js +7 -0
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +1 -1
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ducpz2._.js +3 -0
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +1 -1
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +1 -1
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +1 -1
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tir0vc._.js +1 -1
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xhyinn._.js +3 -0
  212. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20rwfdw._.js +1 -1
  213. package/.next/standalone/.next/server/chunks/_02twlca._.js +1 -1
  214. package/.next/standalone/.next/server/chunks/_072jl0y._.js +1 -1
  215. package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +1 -1
  216. package/.next/standalone/.next/server/chunks/_0sqqpzb._.js +3 -0
  217. package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -7
  218. package/.next/standalone/.next/server/chunks/_1fn30_l._.js +1 -1
  219. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  220. package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
  221. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_backup_route_actions_0zoj04p.js +3 -0
  222. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_csv_route_actions_0l6m7lg.js +3 -0
  223. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restore_route_actions_0-b05bv.js +3 -0
  224. package/.next/standalone/.next/server/chunks/lib_02iz_9q._.js +4 -0
  225. package/.next/standalone/.next/server/chunks/lib_05agvk3._.js +4 -0
  226. package/.next/standalone/.next/server/chunks/lib_0v84u66._.js +4 -0
  227. package/.next/standalone/.next/server/chunks/lib_db-client_0_dch35.js +174 -0
  228. package/.next/standalone/.next/server/chunks/lib_linkedin-export_12imqxg.js +1 -1
  229. package/.next/standalone/.next/server/chunks/lib_rpc_005abye.js +3 -0
  230. package/.next/standalone/.next/server/chunks/lib_rpc_0b17r6v.js +3 -0
  231. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +7 -0
  232. package/.next/standalone/.next/server/chunks/lib_rpc_0doq0t-.js +3 -0
  233. package/.next/standalone/.next/server/chunks/lib_rpc_0fd2rlw.js +3 -0
  234. package/.next/standalone/.next/server/chunks/lib_rpc_0is4qoc.js +3 -0
  235. package/.next/standalone/.next/server/chunks/lib_rpc_0jnfp2e.js +3 -0
  236. package/.next/standalone/.next/server/chunks/lib_rpc_0nef_n7.js +3 -0
  237. package/.next/standalone/.next/server/chunks/lib_rpc_0plrzra.js +3 -0
  238. package/.next/standalone/.next/server/chunks/lib_rpc_13a4m0c.js +3 -0
  239. package/.next/standalone/.next/server/chunks/lib_rpc_1if17c-.js +3 -0
  240. package/.next/standalone/.next/server/chunks/lib_rpc_1j-zw7v.js +3 -0
  241. package/.next/standalone/.next/server/chunks/lib_rpc_1sngt-q.js +3 -0
  242. package/.next/standalone/.next/server/chunks/lib_rpc_1v2sgme.js +3 -0
  243. package/.next/standalone/.next/server/chunks/lib_rpc_1vh-tgx.js +3 -0
  244. package/.next/standalone/.next/server/chunks/lib_rpc_1zaubz7.js +3 -0
  245. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qd8pzm._.js +3 -0
  246. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qdeuyo._.js → [root-of-the-server]__1-012q1._.js} +2 -2
  247. package/.next/standalone/.next/server/chunks/ssr/_01o3i5y._.js +7 -0
  248. package/.next/standalone/.next/server/chunks/ssr/_02sband._.js +7 -0
  249. package/.next/standalone/.next/server/chunks/ssr/_06rgzfh._.js +3 -0
  250. package/.next/standalone/.next/server/chunks/ssr/_07zb7lu._.js +3 -0
  251. package/.next/standalone/.next/server/chunks/ssr/_0_79idq._.js +3 -0
  252. package/.next/standalone/.next/server/chunks/ssr/_0gy11ar._.js +3 -0
  253. package/.next/standalone/.next/server/chunks/ssr/_0hb-dhy._.js +3 -0
  254. package/.next/standalone/.next/server/chunks/ssr/_14nxd3q._.js +3 -0
  255. package/.next/standalone/.next/server/chunks/ssr/_189g8lg._.js +3 -0
  256. package/.next/standalone/.next/server/chunks/ssr/_1f_n00p._.js +1 -1
  257. package/.next/standalone/.next/server/chunks/ssr/_1fm1ih_._.js +2 -2
  258. package/.next/standalone/.next/server/chunks/ssr/_1k2nmbw._.js +2 -2
  259. package/.next/standalone/.next/server/chunks/ssr/_1k9qfsk._.js +3 -0
  260. package/.next/standalone/.next/server/chunks/ssr/app_141w189._.js +1 -1
  261. package/.next/standalone/.next/server/chunks/ssr/app_components_0t908t-._.js +1 -1
  262. package/.next/standalone/.next/server/chunks/ssr/app_components_0uuff77._.js +25 -2
  263. package/.next/standalone/.next/server/chunks/ssr/app_components_1j3q-h5._.js +25 -2
  264. package/.next/standalone/.next/server/chunks/ssr/app_components_CompanyScores_1g0mytz.js +1 -1
  265. package/.next/standalone/.next/server/chunks/ssr/app_import_page_1fmu6_l.js +1 -1
  266. package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +1 -1
  267. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +25 -13
  268. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +2 -2
  269. package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
  270. package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +11 -11
  271. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
  272. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +12 -13
  273. package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
  274. package/.next/standalone/.next/server/chunks/ssr/{lib_1c4ieuw._.js → lib_csv_1ttiu_h.js} +2 -2
  275. package/.next/standalone/.next/server/chunks/ssr/lib_galaxy-lab_108_lu-.js +1 -1
  276. package/.next/standalone/.next/server/chunks/ssr/lib_separation_1305zsx.js +3 -0
  277. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +1 -1
  278. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  279. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  280. package/.next/standalone/.next/server/pages/404.html +1 -1
  281. package/.next/standalone/.next/server/pages/500.html +1 -1
  282. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  283. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  284. package/.next/standalone/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  285. package/.next/standalone/.next/static/chunks/03-demj2iy-0p.js +44 -0
  286. package/.next/standalone/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  287. package/.next/standalone/.next/static/chunks/0an_b6zi1r_qq.js +5 -0
  288. package/.next/standalone/.next/static/chunks/0e3g0sil79cus.js +21 -0
  289. package/.next/standalone/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  290. package/.next/standalone/.next/static/chunks/0p3g5tfostsep.js +7 -0
  291. package/.next/standalone/.next/static/chunks/0zd0t7e60bn4z.js +1 -0
  292. package/.next/standalone/.next/static/chunks/163b-20vwa06i.js +34 -0
  293. package/.next/standalone/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  294. package/.next/standalone/.next/static/chunks/1pa-2v1ajvrko.js +1 -0
  295. package/.next/standalone/.next/static/chunks/1qbjermbf68xj.js +1 -0
  296. package/.next/standalone/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  297. package/.next/standalone/.next/static/chunks/23_1z47al92nz.js +57 -0
  298. package/.next/standalone/.next/static/chunks/260bomtr214m8.js +34 -0
  299. package/.next/standalone/.next/static/chunks/2eo9pqq9gay3r.js +34 -0
  300. package/.next/standalone/.next/static/chunks/2xk2ra4piiuod.js +34 -0
  301. package/.next/standalone/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  302. package/.next/standalone/.next/static/chunks/2zf4jmz9l3li2.js +1 -0
  303. package/.next/standalone/.next/static/chunks/34g73qhayuevu.js +1 -0
  304. package/.next/standalone/.next/static/chunks/3b0-14cxqsprt.js +1 -0
  305. package/.next/standalone/.next/static/chunks/3jarus1_38s2z.js +1 -0
  306. package/.next/standalone/.next/static/chunks/3ssu341hav_sq.css +3 -0
  307. package/.next/standalone/.next/static/chunks/3v1qd3sqhqn0d.js +1 -0
  308. package/.next/standalone/.next/static/chunks/43pg2sursiypz.js +1 -0
  309. package/.next/standalone/.next/static/chunks/44yn0tcd9dfk3.js +1 -0
  310. package/.next/standalone/CHANGELOG.md +143 -0
  311. package/.next/standalone/README.md +71 -49
  312. package/.next/standalone/SECURITY.md +17 -11
  313. package/.next/standalone/app/api/data/backup/route.js +25 -0
  314. package/.next/standalone/app/api/data/csv/route.js +74 -0
  315. package/.next/standalone/app/api/data/export/route.js +1 -1
  316. package/.next/standalone/app/api/data/restore/route.js +48 -0
  317. package/.next/standalone/app/api/data/reveal/route.js +19 -6
  318. package/.next/standalone/app/api/data/route.js +15 -4
  319. package/.next/standalone/app/api/ingest/route.js +1 -1
  320. package/.next/standalone/app/api/queue/route.js +1 -1
  321. package/.next/standalone/app/api/scraper/route.js +120 -32
  322. package/.next/standalone/app/api/social/crm/route.js +2 -1
  323. package/.next/standalone/app/components/AppHeader.js +20 -16
  324. package/.next/standalone/app/components/AppTabs.js +8 -8
  325. package/.next/standalone/app/components/AutoScanButton.js +2 -2
  326. package/.next/standalone/app/components/Avatar.js +1 -1
  327. package/.next/standalone/app/components/ChainView.js +184 -112
  328. package/.next/standalone/app/components/CirclePanel.js +16 -16
  329. package/.next/standalone/app/components/ClusterSpinner.js +64 -0
  330. package/.next/standalone/app/components/CompanyScores.js +20 -20
  331. package/.next/standalone/app/components/EmptyState.js +39 -18
  332. package/.next/standalone/app/components/FieldStep.js +15 -13
  333. package/.next/standalone/app/components/FilterPanel.js +17 -17
  334. package/.next/standalone/app/components/ForceGraph.js +49 -14
  335. package/.next/standalone/app/components/GalaxyLab.js +33 -33
  336. package/.next/standalone/app/components/GridView.js +18 -18
  337. package/.next/standalone/app/components/LegacyScoresCard.js +10 -11
  338. package/.next/standalone/app/components/LinkedInLimits.js +24 -19
  339. package/.next/standalone/app/components/LiquidGlass.js +99 -0
  340. package/.next/standalone/app/components/ListView.js +20 -20
  341. package/.next/standalone/app/components/MapControls.js +5 -5
  342. package/.next/standalone/app/components/MappingProgress.js +16 -16
  343. package/.next/standalone/app/components/NoteDetail.js +13 -13
  344. package/.next/standalone/app/components/OnboardingGate.js +4 -4
  345. package/.next/standalone/app/components/OutlinkQuest.js +25 -25
  346. package/.next/standalone/app/components/PathsAnalyzer.js +37 -36
  347. package/.next/standalone/app/components/PeopleMap.js +21 -21
  348. package/.next/standalone/app/components/RingsView.js +11 -11
  349. package/.next/standalone/app/components/ScanRadar.js +84 -39
  350. package/.next/standalone/app/components/ScanStatusBar.js +22 -18
  351. package/.next/standalone/app/components/ScanTrail.js +8 -5
  352. package/.next/standalone/app/components/SeparationView.js +168 -104
  353. package/.next/standalone/app/components/Sidebar.js +161 -161
  354. package/.next/standalone/app/components/StaleServerBanner.js +4 -4
  355. package/.next/standalone/app/components/TheirCircle.js +26 -26
  356. package/.next/standalone/app/components/ThemeDefs.js +42 -0
  357. package/.next/standalone/app/components/ThemeLoader.js +20 -1
  358. package/.next/standalone/app/components/UpdatePanel.js +22 -22
  359. package/.next/standalone/app/components/UserProvider.js +22 -15
  360. package/.next/standalone/app/components/settings/AppearanceSection.js +47 -24
  361. package/.next/standalone/app/components/settings/DataSection.js +276 -109
  362. package/.next/standalone/app/components/settings/NetworkHealthSection.js +13 -13
  363. package/.next/standalone/app/components/settings/SectorPicker.js +12 -12
  364. package/.next/standalone/app/components/settings/SectorSection.js +13 -14
  365. package/.next/standalone/app/components/settings/TierSection.js +9 -9
  366. package/.next/standalone/app/components/settings/TitleSection.js +11 -11
  367. package/.next/standalone/app/components/settings/UsageSection.js +313 -0
  368. package/.next/standalone/app/components/ui.js +8 -8
  369. package/.next/standalone/app/globals.css +159 -2
  370. package/.next/standalone/app/import/page.js +94 -38
  371. package/.next/standalone/app/launch/page.js +5 -5
  372. package/.next/standalone/app/layout.js +6 -2
  373. package/.next/standalone/app/page.js +53 -37
  374. package/.next/standalone/app/paths/page.js +63 -63
  375. package/.next/standalone/app/profile/page.js +58 -58
  376. package/.next/standalone/app/queue/page.js +54 -54
  377. package/.next/standalone/app/scores/page.js +2 -2
  378. package/.next/standalone/app/settings/page.js +16 -13
  379. package/.next/standalone/app/setup/page.js +221 -125
  380. package/.next/standalone/app/social/Crm.js +63 -62
  381. package/.next/standalone/app/social/SocialHub.js +22 -22
  382. package/.next/standalone/app/social/Thread.js +7 -7
  383. package/.next/standalone/app/social/page.js +2 -2
  384. package/.next/standalone/lib/backups.js +458 -0
  385. package/.next/standalone/lib/chain-layout.js +32 -0
  386. package/.next/standalone/lib/csv-store.js +131 -0
  387. package/.next/standalone/lib/csv.js +137 -39
  388. package/.next/standalone/lib/data-folder.js +19 -3
  389. package/.next/standalone/lib/data-import.js +5 -2
  390. package/.next/standalone/lib/db-client.js +78 -20
  391. package/.next/standalone/lib/demo.js +5 -4
  392. package/.next/standalone/lib/galaxy-export.js +9 -2
  393. package/.next/standalone/lib/galaxy-lab.js +19 -5
  394. package/.next/standalone/lib/galaxy-layouts.js +43 -0
  395. package/.next/standalone/lib/gate.js +10 -4
  396. package/.next/standalone/lib/ingest.js +1 -1
  397. package/.next/standalone/lib/linkedin-limits.js +212 -11
  398. package/.next/standalone/lib/liquid-glass.js +59 -0
  399. package/.next/standalone/lib/notifications.js +13 -0
  400. package/.next/standalone/lib/scan-pace.js +11 -0
  401. package/.next/standalone/lib/scan-progress.js +20 -0
  402. package/.next/standalone/lib/scan-risk.js +44 -0
  403. package/.next/standalone/lib/scanner-setup.js +97 -15
  404. package/.next/standalone/lib/scraper-client.js +17 -3
  405. package/.next/standalone/lib/search-risk.js +7 -3
  406. package/.next/standalone/lib/settings-client.js +5 -3
  407. package/.next/standalone/lib/settings.js +10 -0
  408. package/.next/standalone/lib/social-store.js +3 -2
  409. package/.next/standalone/lib/synced-setting.js +46 -0
  410. package/.next/standalone/lib/theme-store.js +42 -10
  411. package/.next/standalone/lib/themes.js +111 -21
  412. package/.next/standalone/lib/usage.js +195 -0
  413. package/.next/standalone/package-lock.json +2 -2
  414. package/.next/standalone/package.json +1 -1
  415. package/.next/standalone/scripts/scrape.py +26 -2
  416. package/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  417. package/.next/static/chunks/03-demj2iy-0p.js +44 -0
  418. package/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  419. package/.next/static/chunks/0an_b6zi1r_qq.js +5 -0
  420. package/.next/static/chunks/0e3g0sil79cus.js +21 -0
  421. package/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  422. package/.next/static/chunks/0p3g5tfostsep.js +7 -0
  423. package/.next/static/chunks/0zd0t7e60bn4z.js +1 -0
  424. package/.next/static/chunks/163b-20vwa06i.js +34 -0
  425. package/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  426. package/.next/static/chunks/1pa-2v1ajvrko.js +1 -0
  427. package/.next/static/chunks/1qbjermbf68xj.js +1 -0
  428. package/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  429. package/.next/static/chunks/23_1z47al92nz.js +57 -0
  430. package/.next/static/chunks/260bomtr214m8.js +34 -0
  431. package/.next/static/chunks/2eo9pqq9gay3r.js +34 -0
  432. package/.next/static/chunks/2xk2ra4piiuod.js +34 -0
  433. package/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  434. package/.next/static/chunks/2zf4jmz9l3li2.js +1 -0
  435. package/.next/static/chunks/34g73qhayuevu.js +1 -0
  436. package/.next/static/chunks/3b0-14cxqsprt.js +1 -0
  437. package/.next/static/chunks/3jarus1_38s2z.js +1 -0
  438. package/.next/static/chunks/3ssu341hav_sq.css +3 -0
  439. package/.next/static/chunks/3v1qd3sqhqn0d.js +1 -0
  440. package/.next/static/chunks/43pg2sursiypz.js +1 -0
  441. package/.next/static/chunks/44yn0tcd9dfk3.js +1 -0
  442. package/CHANGELOG.md +143 -0
  443. package/README.md +71 -49
  444. package/SECURITY.md +17 -11
  445. package/lib/backups.js +458 -0
  446. package/lib/chain-layout.js +32 -0
  447. package/lib/csv-store.js +131 -0
  448. package/lib/csv.js +137 -39
  449. package/lib/data-folder.js +19 -3
  450. package/lib/data-import.js +5 -2
  451. package/lib/db-client.js +78 -20
  452. package/lib/demo.js +5 -4
  453. package/lib/galaxy-export.js +9 -2
  454. package/lib/galaxy-lab.js +19 -5
  455. package/lib/galaxy-layouts.js +43 -0
  456. package/lib/gate.js +10 -4
  457. package/lib/ingest.js +1 -1
  458. package/lib/linkedin-limits.js +212 -11
  459. package/lib/liquid-glass.js +59 -0
  460. package/lib/notifications.js +13 -0
  461. package/lib/scan-pace.js +11 -0
  462. package/lib/scan-progress.js +20 -0
  463. package/lib/scan-risk.js +44 -0
  464. package/lib/scanner-setup.js +97 -15
  465. package/lib/scraper-client.js +17 -3
  466. package/lib/search-risk.js +7 -3
  467. package/lib/settings-client.js +5 -3
  468. package/lib/settings.js +10 -0
  469. package/lib/social-store.js +3 -2
  470. package/lib/synced-setting.js +46 -0
  471. package/lib/theme-store.js +42 -10
  472. package/lib/themes.js +111 -21
  473. package/lib/usage.js +195 -0
  474. package/package.json +1 -1
  475. package/scripts/scrape.py +26 -2
  476. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +0 -3
  477. package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +0 -3
  478. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +0 -3
  479. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +0 -3
  480. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +0 -3
  481. package/.next/standalone/.next/server/chunks/lib_0851sk0._.js +0 -8
  482. package/.next/standalone/.next/server/chunks/lib_1q7p2ro._.js +0 -8
  483. package/.next/standalone/.next/server/chunks/lib_1r6l86l._.js +0 -8
  484. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +0 -174
  485. package/.next/standalone/.next/server/chunks/lib_rpc_04s8mzr.js +0 -3
  486. package/.next/standalone/.next/server/chunks/lib_rpc_053z7as.js +0 -3
  487. package/.next/standalone/.next/server/chunks/lib_rpc_0b_-2te.js +0 -3
  488. package/.next/standalone/.next/server/chunks/lib_rpc_0dhbxdm.js +0 -3
  489. package/.next/standalone/.next/server/chunks/lib_rpc_0dxlk31.js +0 -3
  490. package/.next/standalone/.next/server/chunks/lib_rpc_0f8b-qc.js +0 -3
  491. package/.next/standalone/.next/server/chunks/lib_rpc_0pzie7_.js +0 -3
  492. package/.next/standalone/.next/server/chunks/lib_rpc_0r76fq_.js +0 -3
  493. package/.next/standalone/.next/server/chunks/lib_rpc_0ut7pjp.js +0 -3
  494. package/.next/standalone/.next/server/chunks/lib_rpc_15zyqaz.js +0 -3
  495. package/.next/standalone/.next/server/chunks/lib_rpc_18zpjtq.js +0 -3
  496. package/.next/standalone/.next/server/chunks/lib_rpc_1a8xkiz.js +0 -3
  497. package/.next/standalone/.next/server/chunks/lib_rpc_1e_55xo.js +0 -3
  498. package/.next/standalone/.next/server/chunks/lib_rpc_1oxfd1_.js +0 -3
  499. package/.next/standalone/.next/server/chunks/lib_rpc_1s0lod0.js +0 -3
  500. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08oxiqh._.js +0 -3
  501. package/.next/standalone/.next/server/chunks/ssr/_03l7vge._.js +0 -3
  502. package/.next/standalone/.next/server/chunks/ssr/_08g31gm._.js +0 -3
  503. package/.next/standalone/.next/server/chunks/ssr/_0gk_ofx._.js +0 -3
  504. package/.next/standalone/.next/server/chunks/ssr/_0nwsf93._.js +0 -3
  505. package/.next/standalone/.next/server/chunks/ssr/_0vho1lb._.js +0 -3
  506. package/.next/standalone/.next/server/chunks/ssr/_1-658fq._.js +0 -3
  507. package/.next/standalone/.next/server/chunks/ssr/_1bc46kz._.js +0 -3
  508. package/.next/standalone/.next/server/chunks/ssr/_2105jz8._.js +0 -3
  509. package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.js +0 -3
  510. package/.next/standalone/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  511. package/.next/standalone/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  512. package/.next/standalone/.next/static/chunks/0i02yxppzds1o.js +0 -1
  513. package/.next/standalone/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  514. package/.next/standalone/.next/static/chunks/0oyslj62jkubd.js +0 -1
  515. package/.next/standalone/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  516. package/.next/standalone/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  517. package/.next/standalone/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  518. package/.next/standalone/.next/static/chunks/172e10mi-tpo_.js +0 -34
  519. package/.next/standalone/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  520. package/.next/standalone/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  521. package/.next/standalone/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  522. package/.next/standalone/.next/static/chunks/1m3017gp790pw.js +0 -45
  523. package/.next/standalone/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  524. package/.next/standalone/.next/static/chunks/2-ch9rm27eril.js +0 -11
  525. package/.next/standalone/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  526. package/.next/standalone/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  527. package/.next/standalone/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  528. package/.next/standalone/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  529. package/.next/standalone/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  530. package/.next/standalone/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  531. package/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  532. package/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  533. package/.next/static/chunks/0i02yxppzds1o.js +0 -1
  534. package/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  535. package/.next/static/chunks/0oyslj62jkubd.js +0 -1
  536. package/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  537. package/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  538. package/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  539. package/.next/static/chunks/172e10mi-tpo_.js +0 -34
  540. package/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  541. package/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  542. package/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  543. package/.next/static/chunks/1m3017gp790pw.js +0 -45
  544. package/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  545. package/.next/static/chunks/2-ch9rm27eril.js +0 -11
  546. package/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  547. package/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  548. package/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  549. package/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  550. package/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  551. package/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  552. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_buildManifest.js +0 -0
  553. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_clientMiddlewareManifest.js +0 -0
  554. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_ssgManifest.js +0 -0
  555. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_buildManifest.js +0 -0
  556. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_clientMiddlewareManifest.js +0 -0
  557. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → ZVpLBK-2vpllv2HxOFs2d}/_ssgManifest.js +0 -0
@@ -3,13 +3,15 @@
3
3
  import { useCallback, useEffect, useRef, useState } from 'react';
4
4
  import { Section, Body, Mono, Status, Btn, LINE } from '../ui';
5
5
 
6
- // Settings → Your data: where the network is kept, what it takes up, and how to
7
- // carry it to another computer. The server does the work (app/api/data/…,
8
- // lib/data-export.js, lib/data-import.js); this section only asks, on a click.
6
+ // Settings → Your data: where the network is kept, what it takes up, its
7
+ // backups, and how to carry it to another computer. The server does the work
8
+ // (app/api/data/…, lib/backups.js, lib/data-export.js, lib/data-import.js);
9
+ // this section only asks, on a click.
9
10
  //
10
- // An import is checked and staged by its click, then replaces the network the
11
- // next time Six Degrees starts, after a copy of what was here is kept. So the
12
- // last word this section says about an import is always how to restart.
11
+ // An import, and a restore from a backup (which is an import of it), is
12
+ // checked and staged by its click, then replaces the network the next time Six
13
+ // Degrees starts, after a copy of what was here is kept. So the last word this
14
+ // section says about either is always how to restart.
13
15
 
14
16
  const MB = 1024 * 1024;
15
17
  const DAY_MS = 24 * 3600 * 1000;
@@ -32,15 +34,23 @@ function when(value, withTime = true) {
32
34
  return d.toLocaleString(undefined, withTime ? { dateStyle: 'medium', timeStyle: 'short' } : { dateStyle: 'medium' });
33
35
  }
34
36
 
35
- // The README's steps for putting back what an import replaced. A link the
36
- // person clicks (it opens in their browser), never a request the page makes.
37
- const UNDO_HELP = 'https://github.com/blakeb056/six-degrees#undo-an-import';
37
+ /** What a backup is, in a few words (lib/backups.js describeBackups). */
38
+ function backupLabel(b) {
39
+ if (b.kind === 'daily') return 'Daily';
40
+ if (b.kind === 'before-update') return b.version ? `Before version ${b.version}` : 'Before a new version';
41
+ if (b.kind === 'before-import') return 'Before an import or a restore';
42
+ return b.byHand ? 'Put here by hand' : 'Made by you';
43
+ }
38
44
 
39
- const BACKUP_KIND = {
40
- auto: 'before a new version',
41
- import: 'before an import',
42
- manual: 'made by hand',
43
- };
45
+ /** What is in it, when that isn't the whole network with its photos. */
46
+ function backupHolds(b) {
47
+ if (!b.restorable) return 'not a backup Six Degrees can restore';
48
+ if (b.format === 'sixdegrees') return 'network, photos and files';
49
+ if (b.withFiles) return 'network, with its photos and files beside it';
50
+ if (b.kind === 'before-update') return 'network only (made before backups had photos)';
51
+ if (b.kind === 'before-import') return 'network only (it had no photos or files to keep)';
52
+ return 'network only';
53
+ }
44
54
 
45
55
  /** The server's answer, or an Error carrying its message (and its data, for the caller). */
46
56
  async function answer(res, fallback) {
@@ -50,24 +60,94 @@ async function answer(res, fallback) {
50
60
  }
51
61
 
52
62
  const row = { display: 'flex', gap: 10, marginTop: 12, flexWrap: 'wrap', alignItems: 'center' };
53
- const small = { fontSize: 12, color: '#667', marginTop: 10 };
54
- const subhead = { fontSize: 14, fontWeight: 650, margin: '26px 0 4px', color: '#e8e8ee' };
55
- const check = { display: 'flex', gap: 8, alignItems: 'flex-start', marginTop: 12, fontSize: 13, color: '#c8d0d0', lineHeight: 1.5, cursor: 'pointer' };
63
+ const small = { fontSize: 12, color: 'var(--sd-fg-4, #667)', marginTop: 10 };
64
+ const subhead = { fontSize: 14, fontWeight: 650, margin: '26px 0 4px', color: 'var(--sd-fg-1, #e8e8ee)' };
65
+ const check = { display: 'flex', gap: 8, alignItems: 'flex-start', marginTop: 12, fontSize: 13, color: 'var(--sd-fg-2, #c8d0d0)', lineHeight: 1.5, cursor: 'pointer' };
56
66
 
57
67
  function Fact({ label, children }) {
58
68
  return (
59
69
  <div style={{ display: 'flex', gap: 12, justifyContent: 'space-between', padding: '7px 0', borderTop: LINE, fontSize: 13.5 }}>
60
- <span style={{ color: '#8b9a9a' }}>{label}</span>
61
- <span style={{ color: '#e8e8ee', textAlign: 'right' }}>{children}</span>
70
+ <span style={{ color: 'var(--sd-fg-3, #8b9a9a)' }}>{label}</span>
71
+ <span style={{ color: 'var(--sd-fg-1, #e8e8ee)', textAlign: 'right' }}>{children}</span>
62
72
  </div>
63
73
  );
64
74
  }
65
75
 
66
- function UndoLink() {
76
+ /** The newest backup's line: when, and whether it passed the importer's checks. */
77
+ function LastBackup({ status }) {
78
+ const last = status?.last;
79
+ const failed = status?.failed;
80
+ // A backup that couldn't be made after the newest one that was: that comes first (TRAPS §7).
81
+ const failedSince = failed && (!last || Date.parse(failed.at) > Date.parse(last.at));
67
82
  return (
68
- <a href={UNDO_HELP} target="_blank" rel="noreferrer" style={{ color: 'inherit', textDecoration: 'underline' }}>
69
- Undo an import
70
- </a>
83
+ <>
84
+ {failedSince && (
85
+ <Status tone="bad">
86
+ The last backup didn’t work ({when(failed.at)}): {failed.message.replace(/\.$/, '')}.
87
+ {!last && ' There’s no backup yet.'}
88
+ </Status>
89
+ )}
90
+ {last ? (
91
+ last.verified ? (
92
+ <Status tone={failedSince ? undefined : 'ok'}>
93
+ Last backup: {when(last.at)}, verified{last.people != null ? ` (${people(last.people)})` : ''}.
94
+ </Status>
95
+ ) : (
96
+ <Status tone="bad">
97
+ Last backup: {when(last.at)}, but it didn’t pass its check, so it can’t be restored: {last.problem}
98
+ {' '}Click Back up now to make a new one.
99
+ </Status>
100
+ )
101
+ ) : !failedSince && (
102
+ <Status>No backup yet. One is made each day Six Degrees is open with a network in it.</Status>
103
+ )}
104
+ </>
105
+ );
106
+ }
107
+
108
+ /** An import or a restore that waits for the next start, and how to restart. */
109
+ function Pending({ pending, info, busy, restarting, onRestart, onCancel }) {
110
+ const what = pending.restoredFrom
111
+ ? <>The backup <Mono>{pending.restoredFrom}</Mono></>
112
+ : <>The network in the copy{pending.exportedAt ? ` saved ${when(pending.exportedAt, false)}` : ''}</>;
113
+ return (
114
+ <Status>
115
+ <div style={{ fontWeight: 650 }}>{pending.restoredFrom ? 'A restore is waiting to finish.' : 'An import is waiting to finish.'}</div>
116
+ <div>
117
+ {what}
118
+ {' '}({people(pending.people)}{pending.photos ? `, ${plural(pending.photos, 'photo')}` : ''}
119
+ {pending.fromVersion ? `, from Six Degrees ${pending.fromVersion}` : ''})
120
+ {pending.replacedPeople > 0
121
+ ? ` replaces the ${people(pending.replacedPeople)} here the next time Six Degrees starts. A copy of what’s here now is kept in backups first, so it can be undone.`
122
+ : ' becomes the network here the next time Six Degrees starts.'}
123
+ {' '}Your LinkedIn search budget and any pause on scanning are kept.
124
+ </div>
125
+ {pending.error && (
126
+ <div style={{ color: 'var(--sd-red, #ff7676)', marginTop: 6 }}>
127
+ The last try stopped: {pending.error.replace(/\.$/, '')}. It tries again the next time Six Degrees starts.
128
+ </div>
129
+ )}
130
+ {restarting ? (
131
+ <div style={{ marginTop: 8 }}>Restarting… this page comes back in a few seconds.</div>
132
+ ) : (
133
+ <>
134
+ <div style={{ marginTop: 8 }}>{info.restart.how}</div>
135
+ {info.restart.command && <div style={{ marginTop: 6 }}><Mono>{info.restart.command}</Mono></div>}
136
+ <div style={row}>
137
+ {info.restart.canRestart && (
138
+ <Btn primary onClick={onRestart} disabled={!!busy}>
139
+ {busy === 'restart' ? 'Restarting…' : 'Restart now'}
140
+ </Btn>
141
+ )}
142
+ {!pending.started && (
143
+ <Btn onClick={onCancel} disabled={!!busy}>
144
+ {busy === 'cancel' ? 'Cancelling…' : pending.restoredFrom ? 'Cancel the restore' : 'Cancel the import'}
145
+ </Btn>
146
+ )}
147
+ </div>
148
+ </>
149
+ )}
150
+ </Status>
71
151
  );
72
152
  }
73
153
 
@@ -76,6 +156,9 @@ export default function DataSection() {
76
156
  const [loadError, setLoadError] = useState(null);
77
157
  const [busy, setBusy] = useState(null);
78
158
  const [folderNote, setFolderNote] = useState(null);
159
+ const [backupNote, setBackupNote] = useState(null);
160
+ const [rowNote, setRowNote] = useState(null);
161
+ const [confirming, setConfirming] = useState(null);
79
162
  const [exportNote, setExportNote] = useState(null);
80
163
  const [importNote, setImportNote] = useState(null);
81
164
  const [photos, setPhotos] = useState(true);
@@ -131,6 +214,61 @@ export default function DataSection() {
131
214
  }
132
215
  }
133
216
 
217
+ async function backUpNow() {
218
+ setBusy('backup');
219
+ setBackupNote(null);
220
+ setRowNote(null);
221
+ try {
222
+ const d = await answer(await fetch('/api/data/backup', { method: 'POST' }), 'The backup could not be made.');
223
+ await load();
224
+ const b = d.backup;
225
+ setBackupNote({
226
+ tone: 'ok',
227
+ text: `Backed up ${people(b.people)}${b.photos ? ` and ${plural(b.photos, 'photo')}` : ''} (${size(b.bytes)}), and checked it. This one stays until you delete it.`,
228
+ });
229
+ } catch (e) {
230
+ await load();
231
+ setBackupNote({ tone: 'bad', text: e.message });
232
+ } finally {
233
+ setBusy(null);
234
+ }
235
+ }
236
+
237
+ // The server opens it (the page has no way to reach Finder itself). Where it
238
+ // can't (no file browser on this computer), the answer names the file.
239
+ async function revealBackup(name) {
240
+ setBusy(`reveal:${name}`);
241
+ setRowNote(null);
242
+ try {
243
+ await answer(await fetch('/api/data/reveal', {
244
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ backup: name }),
245
+ }), 'The backup could not be shown.');
246
+ } catch (e) {
247
+ setRowNote({ name, tone: 'bad', text: e.message });
248
+ } finally {
249
+ setBusy(null);
250
+ }
251
+ }
252
+
253
+ async function restoreBackup(name) {
254
+ setBusy(`restore:${name}`);
255
+ setRowNote(null);
256
+ setBackupNote(null);
257
+ try {
258
+ await answer(await fetch('/api/data/restore', {
259
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, replace: info.people }),
260
+ }), 'The backup could not be restored.');
261
+ setConfirming(null);
262
+ await load();
263
+ } catch (e) {
264
+ // The network changed since this page asked: show the new count to agree to.
265
+ if (e.data?.needsConfirm) await load();
266
+ setRowNote({ name, tone: 'bad', text: e.message });
267
+ } finally {
268
+ setBusy(null);
269
+ }
270
+ }
271
+
134
272
  async function exportNow() {
135
273
  setBusy('export');
136
274
  setExportNote(null);
@@ -140,7 +278,7 @@ export default function DataSection() {
140
278
  headers: { 'Content-Type': 'application/json' },
141
279
  body: JSON.stringify({ photos, social }),
142
280
  });
143
- if (!res.ok) await answer(res, 'The copy could not be made.');
281
+ if (!res.ok) await answer(res, 'The backup file could not be made.');
144
282
  const blob = await res.blob();
145
283
  const name = /filename="([^"]+)"/.exec(res.headers.get('content-disposition') || '')?.[1] || 'Six Degrees backup.sixdegrees';
146
284
  const url = URL.createObjectURL(blob);
@@ -182,7 +320,7 @@ export default function DataSection() {
182
320
  try {
183
321
  const headers = { 'Content-Type': 'application/octet-stream', 'X-Six-Degrees-Size': String(file.size) };
184
322
  if (info.people > 0) headers['X-Six-Degrees-Replace'] = String(info.people);
185
- await answer(await fetch('/api/data/import', { method: 'POST', headers, body: file }), 'The file could not be imported.');
323
+ await answer(await fetch('/api/data/import', { method: 'POST', headers, body: file }), 'The file could not be restored.');
186
324
  setFile(null);
187
325
  setConfirmed(false);
188
326
  if (picker.current) picker.current.value = '';
@@ -202,14 +340,17 @@ export default function DataSection() {
202
340
  async function cancelImport() {
203
341
  setBusy('cancel');
204
342
  setImportNote(null);
343
+ setBackupNote(null);
344
+ // A restore's answer goes where it was asked for, under Backups.
345
+ const say = info.pending?.restoredFrom ? setBackupNote : setImportNote;
205
346
  try {
206
- await answer(await fetch('/api/data/import', { method: 'DELETE' }), 'The import could not be cancelled.');
347
+ await answer(await fetch('/api/data/import', { method: 'DELETE' }), 'It could not be cancelled.');
207
348
  // Read the folder again first, so "Cancelled" never shows beside a
208
349
  // waiting import that is already gone.
209
350
  await load();
210
- setImportNote({ tone: 'ok', text: 'Cancelled. The network here stays as it is.' });
351
+ say({ tone: 'ok', text: 'Cancelled. The network here stays as it is.' });
211
352
  } catch (e) {
212
- setImportNote({ tone: 'bad', text: e.message });
353
+ say({ tone: 'bad', text: e.message });
213
354
  } finally {
214
355
  setBusy(null);
215
356
  }
@@ -236,7 +377,7 @@ export default function DataSection() {
236
377
  await wait(1000);
237
378
  }
238
379
  setRestarting(false);
239
- setImportNote({ tone: 'bad', text: 'Six Degrees didn’t come back. Quit it and open it again: the import finishes as it starts.' });
380
+ setImportNote({ tone: 'bad', text: 'Six Degrees didn’t come back. Quit it and open it again: it finishes as it starts.' });
240
381
  } catch (e) {
241
382
  setImportNote({ tone: 'bad', text: e.message });
242
383
  } finally {
@@ -257,9 +398,15 @@ export default function DataSection() {
257
398
  const inCopy = info.photosInCopy || info.photos;
258
399
  const backups = info.backups || [];
259
400
  const backupBytes = backups.reduce((n, b) => n + (b.bytes || 0), 0);
401
+ const status = info.backupStatus || {};
402
+ const keep = status.keep || {};
260
403
  const tooBig = Boolean(file && file.size > info.maxImportBytes);
261
404
  const replaces = info.people > 0;
262
405
  const last = info.lastImport;
406
+ const finder = info.platform === 'darwin' ? 'Show in Finder' : 'Show in folder';
407
+ const pendingBox = pending && (
408
+ <Pending pending={pending} info={info} busy={busy} restarting={restarting} onRestart={restartNow} onCancel={cancelImport} />
409
+ );
263
410
 
264
411
  return (
265
412
  <Section
@@ -285,37 +432,89 @@ export default function DataSection() {
285
432
  </Fact>
286
433
  </div>
287
434
 
435
+ <h3 style={subhead}>Backups</h3>
436
+ <LastBackup status={status} />
437
+ <div style={row}>
438
+ <Btn onClick={backUpNow} disabled={!!busy || restarting || info.people === 0}>
439
+ {busy === 'backup' ? 'Backing up…' : 'Back up now'}
440
+ </Btn>
441
+ {info.people === 0 && <span style={{ fontSize: 13, color: 'var(--sd-fg-3, #8b9a9a)' }}>There’s no network here to back up yet.</span>}
442
+ </div>
443
+ {backupNote && <Status tone={backupNote.tone}>{backupNote.text}</Status>}
444
+ {pending?.restoredFrom && pendingBox}
445
+ <Body style={small}>
446
+ Each backup is your whole network with its photos, your settings and the scanner’s notes, checked as it’s
447
+ made. Six Degrees makes one each day it’s open and before a new version first opens your data. It keeps the
448
+ last {keep.daily ?? 7} daily backups, {keep['before-update'] ?? 3} from before new versions, and
449
+ {' '}{keep['before-import'] ?? 3} from before an import or a restore (those for at least {status.floorDays ?? 30} days).
450
+ Backups you make with Back up now stay until you delete them. The Social tab’s messages and notes are never
451
+ in them, so deleting those there deletes them everywhere. Backups are on this computer only, so to keep one safe
452
+ if the computer is lost, copy it somewhere else.
453
+ </Body>
454
+
288
455
  {backups.length > 0 && (
289
- <details style={{ marginTop: 10, fontSize: 13, color: '#8b9a9a' }}>
290
- <summary style={{ cursor: 'pointer' }}>The backups</summary>
291
- <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) auto auto', gap: '6px 14px', marginTop: 8 }}>
292
- {backups.map((b) => (
293
- <div key={b.name} style={{ display: 'contents' }}>
294
- <span style={{ wordBreak: 'break-all', color: '#c8d0d0' }}>
295
- {b.name}{b.folder ? '/' : ''}
296
- <span style={{ color: '#667' }}> · {b.folder ? 'its photos and files' : BACKUP_KIND[b.kind] || b.kind}</span>
297
- </span>
298
- <span>{when(b.modifiedAt)}</span>
299
- <span style={{ textAlign: 'right' }}>{size(b.bytes)}</span>
300
- </div>
301
- ))}
456
+ <details style={{ marginTop: 10, fontSize: 13, color: 'var(--sd-fg-3, #8b9a9a)' }}>
457
+ <summary style={{ cursor: 'pointer' }}>The backups ({count(backups.length)})</summary>
458
+ <div style={{ marginTop: 6 }}>
459
+ {backups.map((b) => {
460
+ const asking = confirming === b.name;
461
+ const note = rowNote?.name === b.name ? rowNote : null;
462
+ return (
463
+ <div key={b.name} style={{ padding: '10px 0', borderTop: LINE }}>
464
+ <div style={{ display: 'flex', gap: 10, justifyContent: 'space-between', flexWrap: 'wrap' }}>
465
+ <span style={{ color: 'var(--sd-fg-1, #e8e8ee)', fontWeight: 600 }}>
466
+ {backupLabel(b)} <span style={{ fontWeight: 400, color: 'var(--sd-fg-3, #8b9a9a)' }}>· {when(b.at)}</span>
467
+ </span>
468
+ <span>{size(b.bytes)}</span>
469
+ </div>
470
+ <div style={{ fontSize: 12, color: 'var(--sd-fg-4, #667)', marginTop: 2 }}>
471
+ {/* Only the file name may break anywhere: it has no spaces, and a phone is narrower than it. */}
472
+ <span style={{ wordBreak: 'break-all' }}>{b.name}{b.folder ? '/' : ''}</span> · {backupHolds(b)}
473
+ </div>
474
+ {asking ? (
475
+ <Status>
476
+ {replaces
477
+ ? `Replace the ${people(info.people)} here with the network in this backup?`
478
+ : 'Restore the network in this backup?'}
479
+ {' '}It’s checked first, and finishes when Six Degrees restarts. What’s here now is kept in backups
480
+ first, so this can be undone. Your LinkedIn search budget and any pause on scanning are kept.
481
+ {b.format === 'database' && !b.withFiles && ' This backup holds the network only, so the photos and the scanner’s notes here now stay with it.'}
482
+ <div style={row}>
483
+ <Btn primary onClick={() => restoreBackup(b.name)} disabled={!!busy}>
484
+ {busy === `restore:${b.name}` ? 'Checking the backup…' : 'Restore it'}
485
+ </Btn>
486
+ <Btn onClick={() => { setConfirming(null); setRowNote(null); }} disabled={busy === `restore:${b.name}`}>Cancel</Btn>
487
+ </div>
488
+ </Status>
489
+ ) : (
490
+ <div style={{ ...row, marginTop: 8 }}>
491
+ {b.restorable && (
492
+ <Btn onClick={() => { setConfirming(b.name); setRowNote(null); }} disabled={!!busy || restarting || Boolean(pending)}>
493
+ Restore
494
+ </Btn>
495
+ )}
496
+ <Btn onClick={() => revealBackup(b.name)} disabled={busy === `reveal:${b.name}`}>
497
+ {busy === `reveal:${b.name}` ? 'Opening…' : finder}
498
+ </Btn>
499
+ </div>
500
+ )}
501
+ {note && <Status tone={note.tone}>{note.text}</Status>}
502
+ </div>
503
+ );
504
+ })}
302
505
  </div>
303
506
  </details>
304
507
  )}
305
- <Body style={small}>
306
- Backups are copies of your network from before a new version or an import. The newest five from new
307
- versions are kept; copies from before an import stay until you delete them.
308
- </Body>
309
508
  <Body style={small}>
310
509
  The folder can’t be moved from here. A database that a sync service (iCloud Drive, Dropbox) copies while
311
510
  it’s open can be damaged, and this folder also holds your LinkedIn sign-in, which should never be synced.
312
- To use your network on another computer, save a copy below and import it there.
511
+ To use your network on another computer, export a backup file below and restore it there.
313
512
  </Body>
314
513
 
315
514
  <h3 style={subhead}>Move your network to another computer</h3>
316
515
  <Body>
317
- Save a copy here, then on the new computer install Six Degrees, open Settings → Your data and import the
318
- copy. Sign in to LinkedIn again there before you scan: your sign-in never goes into a copy.
516
+ Export a backup file here, then on the new computer install Six Degrees, open Settings → Your data and
517
+ restore from it. Sign in to LinkedIn again there before you scan: your sign-in never goes into a backup.
319
518
  </Body>
320
519
  <label style={check}>
321
520
  <input type="checkbox" checked={photos} onChange={(e) => setPhotos(e.target.checked)} style={{ marginTop: 3 }} />
@@ -334,73 +533,37 @@ export default function DataSection() {
334
533
  </label>
335
534
  <div style={row}>
336
535
  <Btn primary onClick={exportNow} disabled={!!busy || restarting || info.people === 0}>
337
- {busy === 'export' ? 'Saving…' : 'Save a copy of my network'}
536
+ {busy === 'export' ? 'Saving…' : 'Export backup file…'}
338
537
  </Btn>
339
- {info.people === 0 && <span style={{ fontSize: 13, color: '#8b9a9a' }}>There’s no network here to save yet.</span>}
538
+ {info.people === 0 && <span style={{ fontSize: 13, color: 'var(--sd-fg-3, #8b9a9a)' }}>There’s no network here to save yet.</span>}
340
539
  </div>
341
540
  {exportNote && <Status tone={exportNote.tone}>{exportNote.text}</Status>}
342
541
  <Body style={small}>
343
- The copy holds the names, headlines and photos of the people in your network. Keep it private: don’t
344
- post it or share it, and delete it once it has been imported. A network opened from a LinkedIn CSV lives
345
- only in its browser tab, so it isn’t in the copy; import the CSV again on the new computer. With the
346
- Social tab included, the copy also holds your CRM notes and any messages you keep, so it&rsquo;s as private
542
+ The file holds the names, headlines and photos of the people in your network. Keep it private: don’t
543
+ post it or share it, and delete it once it has been restored. A LinkedIn CSV import kept on this computer
544
+ goes into the file too, and opens on the new one. With the
545
+ Social tab included, the file also holds your CRM notes and any messages you keep, so it&rsquo;s as private
347
546
  as your inbox.
348
547
  </Body>
349
548
 
350
549
  <h3 style={subhead}>Bring in a network from another computer</h3>
351
- {pending ? (
352
- <Status>
353
- <div style={{ fontWeight: 650 }}>An import is waiting to finish.</div>
354
- <div>
355
- The network in the copy{pending.exportedAt ? ` saved ${when(pending.exportedAt, false)}` : ''}
356
- {' '}({people(pending.people)}{pending.photos ? `, ${plural(pending.photos, 'photo')}` : ''}
357
- {pending.fromVersion ? `, from Six Degrees ${pending.fromVersion}` : ''})
358
- {pending.replacedPeople > 0
359
- ? ` replaces the ${people(pending.replacedPeople)} here the next time Six Degrees starts. A copy of what’s here now is kept in backups first, so the import can be undone.`
360
- : ' becomes the network here the next time Six Degrees starts.'}
361
- {' '}Your LinkedIn search budget and any pause on scanning are kept.
362
- </div>
363
- {pending.error && (
364
- <div style={{ color: '#ff7676', marginTop: 6 }}>
365
- The last try stopped: {pending.error.replace(/\.$/, '')}. It tries again the next time Six Degrees starts.
366
- </div>
367
- )}
368
- {restarting ? (
369
- <div style={{ marginTop: 8 }}>Restarting… this page comes back in a few seconds.</div>
370
- ) : (
371
- <>
372
- <div style={{ marginTop: 8 }}>{info.restart.how}</div>
373
- {info.restart.command && <div style={{ marginTop: 6 }}><Mono>{info.restart.command}</Mono></div>}
374
- <div style={row}>
375
- {info.restart.canRestart && (
376
- <Btn primary onClick={restartNow} disabled={!!busy}>
377
- {busy === 'restart' ? 'Restarting…' : 'Restart now'}
378
- </Btn>
379
- )}
380
- {!pending.started && (
381
- <Btn onClick={cancelImport} disabled={!!busy}>
382
- {busy === 'cancel' ? 'Cancelling…' : 'Cancel the import'}
383
- </Btn>
384
- )}
385
- </div>
386
- </>
387
- )}
388
- </Status>
550
+ {pending && !pending.restoredFrom ? pendingBox : pending ? (
551
+ <Body>A restore is waiting to finish (under Backups, above). Restart, or cancel it, before restoring anything else.</Body>
389
552
  ) : (
390
553
  <>
391
554
  <Body>
392
- Pick the copy you saved on the other computer (a .sixdegrees file). It replaces the network here; the
393
- two networks are never merged. Your LinkedIn search budget and any pause on scanning are kept, with the
394
- other computer’s searches added.
555
+ Pick the backup file you exported on the other computer (a .sixdegrees file). It replaces the network
556
+ here; the two networks are never merged. Your LinkedIn search budget and any pause on scanning are kept,
557
+ with the other computer’s searches added.
395
558
  </Body>
396
559
  <input ref={picker} type="file" accept=".sixdegrees" onChange={choose} style={{ display: 'none' }} />
397
560
  <div style={row}>
398
- <Btn onClick={() => picker.current?.click()} disabled={!!busy}>Choose a file…</Btn>
399
- {file && <span style={{ fontSize: 13, color: '#c8d0d0', wordBreak: 'break-all' }}>{file.name} · {size(file.size)}</span>}
561
+ <Btn onClick={() => picker.current?.click()} disabled={!!busy}>Restore from a file…</Btn>
562
+ {file && <span style={{ fontSize: 13, color: 'var(--sd-fg-2, #c8d0d0)', wordBreak: 'break-all' }}>{file.name} · {size(file.size)}</span>}
400
563
  </div>
401
564
  {tooBig && (
402
565
  <Status tone="bad">
403
- That file is {size(file.size)}. This copy can import files up to {size(info.maxImportBytes)}.
566
+ That file is {size(file.size)}. This copy can restore files up to {size(info.maxImportBytes)}.
404
567
  </Status>
405
568
  )}
406
569
  {file && replaces && !tooBig && (
@@ -412,11 +575,13 @@ export default function DataSection() {
412
575
  </span>
413
576
  </label>
414
577
  )}
415
- <div style={row}>
416
- <Btn primary onClick={importNow} disabled={!file || tooBig || (replaces && !confirmed) || !!busy}>
417
- {busy === 'import' ? 'Checking the file…' : 'Import'}
418
- </Btn>
419
- </div>
578
+ {file && (
579
+ <div style={row}>
580
+ <Btn primary onClick={importNow} disabled={tooBig || (replaces && !confirmed) || !!busy}>
581
+ {busy === 'import' ? 'Checking the file…' : 'Restore'}
582
+ </Btn>
583
+ </div>
584
+ )}
420
585
  </>
421
586
  )}
422
587
  {importNote && <Status tone={importNote.tone}>{importNote.text}</Status>}
@@ -424,21 +589,23 @@ export default function DataSection() {
424
589
  {last && !pending && (
425
590
  info.importIsRecent ? (
426
591
  <Status tone="ok">
427
- Imported {when(last.appliedAt)}: {people(last.people)}
428
- {last.exportedAt ? ` from the copy saved ${when(last.exportedAt, false)}` : ''}.
592
+ {last.restoredFrom ? 'Restored' : 'Imported'} {when(last.appliedAt)}: {people(last.people)}
593
+ {last.restoredFrom
594
+ ? <> from the backup <Mono>{last.restoredFrom}</Mono></>
595
+ : last.exportedAt ? ` from the copy saved ${when(last.exportedAt, false)}` : ''}.
429
596
  {last.keptDatabase && (
430
597
  <>
431
598
  {' '}What was here before is kept in <Mono>{last.keptDatabase}</Mono>
432
599
  {last.keptFiles ? ', with its photos and files beside it' : ''}.
433
600
  {last.keptAsIs && ' It couldn’t be read, so it was kept exactly as it was.'}
434
- {' '}To go back to it, see <UndoLink />.
601
+ {' '}To go back to it, restore it from the backups above.
435
602
  </>
436
603
  )}
437
604
  </Status>
438
605
  ) : (
439
606
  <Body style={small}>
440
- Last import: {when(last.appliedAt)} ({people(last.people)}).
441
- {last.keptDatabase && <> What was here before is kept in <Mono>{last.keptDatabase}</Mono> (<UndoLink />).</>}
607
+ Last {last.restoredFrom ? 'restore' : 'import'}: {when(last.appliedAt)} ({people(last.people)}).
608
+ {last.keptDatabase && <> What was here before is kept in <Mono>{last.keptDatabase}</Mono>, under Backups above.</>}
442
609
  </Body>
443
610
  )
444
611
  )}
@@ -29,7 +29,7 @@ export default function NetworkHealthSection() {
29
29
  return () => { live = false; };
30
30
  }, [userId]);
31
31
 
32
- const box = { padding: '12px 14px', borderRadius: 8, border: LINE, background: 'rgba(255,255,255,0.03)' };
32
+ const box = { padding: '12px 14px', borderRadius: 8, border: LINE, background: 'rgba(var(--sd-ink, 255, 255, 255), 0.03)' };
33
33
  return (
34
34
  <section id="health" style={{ marginTop: 20 }}>
35
35
  <h2 style={{ fontSize: 16, margin: '0 0 6px' }}>Network health</h2>
@@ -41,22 +41,22 @@ export default function NetworkHealthSection() {
41
41
  {health && health.circles > 0 && (
42
42
  <>
43
43
  {health.early && (
44
- <div style={{ fontSize: 12.5, color: '#FFD700', margin: '4px 0 10px' }}>
44
+ <div style={{ fontSize: 12.5, color: 'var(--sd-gold, #FFD700)', margin: '4px 0 10px' }}>
45
45
  An early estimate: {health.circles} {health.circles === 1 ? 'circle' : 'circles'} scanned. These get sharper as you scan more.
46
46
  </div>
47
47
  )}
48
48
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }}>
49
49
  <div style={box}>
50
50
  <div style={{ fontSize: 22, fontWeight: 700 }}>{pct(health.twoWays)}</div>
51
- <div style={{ fontSize: 12.5, color: '#b8c4c4' }}>of your 2nd degree you reach two or more ways</div>
52
- <div style={{ fontSize: 11.5, color: '#778', marginTop: 4 }}>Higher is safer: lose one connection and they&rsquo;re still reachable.</div>
51
+ <div style={{ fontSize: 12.5, color: 'var(--sd-fg-2, #b8c4c4)' }}>of your 2nd degree you reach two or more ways</div>
52
+ <div style={{ fontSize: 11.5, color: 'var(--sd-fg-4, #778)', marginTop: 4 }}>Higher is safer: lose one connection and they&rsquo;re still reachable.</div>
53
53
  </div>
54
54
  <div style={box}>
55
55
  <div style={{ fontSize: 22, fontWeight: 700 }}>{Math.round(health.effective.size).toLocaleString()}</div>
56
- <div style={{ fontSize: 12.5, color: '#b8c4c4' }}>
56
+ <div style={{ fontSize: 12.5, color: 'var(--sd-fg-2, #b8c4c4)' }}>
57
57
  effective reach of your {health.effective.n.toLocaleString()} connections ({pct(health.effective.efficiency)} non-overlapping)
58
58
  </div>
59
- <div style={{ fontSize: 11.5, color: '#778', marginTop: 4 }}>
59
+ <div style={{ fontSize: 11.5, color: 'var(--sd-fg-4, #778)', marginTop: 4 }}>
60
60
  From {health.effective.ties.toLocaleString()} {health.effective.ties === 1 ? 'tie' : 'ties'} between your connections seen in circle scans so far,
61
61
  so it can only come down as you scan more.
62
62
  </div>
@@ -64,17 +64,17 @@ export default function NetworkHealthSection() {
64
64
  </div>
65
65
  {health.top.length > 0 && (
66
66
  <div style={{ ...box, marginTop: 10, padding: 0 }}>
67
- <div style={{ padding: '10px 14px', fontSize: 12.5, color: '#b8c4c4', borderBottom: LINE }}>Your connections who reach the most people no one else does</div>
67
+ <div style={{ padding: '10px 14px', fontSize: 12.5, color: 'var(--sd-fg-2, #b8c4c4)', borderBottom: LINE }}>Your connections who reach the most people no one else does</div>
68
68
  {health.top.map((b, k) => (
69
- <div key={b.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 14px', borderBottom: k < health.top.length - 1 ? '1px solid rgba(255,255,255,0.04)' : 'none', fontSize: 13 }}>
70
- <span style={{ width: 22, color: '#778' }}>#{k + 1}</span>
69
+ <div key={b.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 14px', borderBottom: k < health.top.length - 1 ? '1px solid rgba(var(--sd-ink, 255, 255, 255), 0.04)' : 'none', fontSize: 13 }}>
70
+ <span style={{ width: 22, color: 'var(--sd-fg-4, #778)' }}>#{k + 1}</span>
71
71
  <span style={{ width: 8, height: 8, borderRadius: '50%', background: TIER[b.tier] || '#667', flexShrink: 0 }} />
72
72
  <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
73
- <b>{b.name}</b>{b.company ? <span style={{ color: '#8b9a9a' }}> · {b.company}</span> : null}
73
+ <b>{b.name}</b>{b.company ? <span style={{ color: 'var(--sd-fg-3, #8b9a9a)' }}> · {b.company}</span> : null}
74
74
  </span>
75
- <span style={{ color: '#b8c4c4', whiteSpace: 'nowrap' }}>{b.circle.toLocaleString()} in circle</span>
76
- <span style={{ color: '#00ff88', whiteSpace: 'nowrap' }}>{b.only.toLocaleString()} only them ({pct(b.share)})</span>
77
- <Link href={`/?chain=${encodeURIComponent(b.id)}`} style={{ color: '#3498DB', textDecoration: 'none', whiteSpace: 'nowrap' }}>Explore →</Link>
75
+ <span style={{ color: 'var(--sd-fg-2, #b8c4c4)', whiteSpace: 'nowrap' }}>{b.circle.toLocaleString()} in circle</span>
76
+ <span style={{ color: 'var(--sd-green, #00ff88)', whiteSpace: 'nowrap' }}>{b.only.toLocaleString()} only them ({pct(b.share)})</span>
77
+ <Link href={`/?chain=${encodeURIComponent(b.id)}`} style={{ color: 'var(--sd-blue, #3498DB)', textDecoration: 'none', whiteSpace: 'nowrap' }}>Explore →</Link>
78
78
  </div>
79
79
  ))}
80
80
  </div>