youiyoux 0.1.2 → 0.1.4

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 (212) hide show
  1. package/README.md +10 -0
  2. package/dist/chunks/{chunk-S7UV34H5.js → chunk-42YJX3W5.js} +1 -3
  3. package/dist/chunks/{chunk-FUB7B3VK.js → chunk-4BBYLTZX.js} +10 -10
  4. package/dist/chunks/chunk-52KOKYY6.js +8710 -0
  5. package/dist/chunks/chunk-FJZFCAL5.js +129 -0
  6. package/dist/chunks/chunk-FVVL5JCY.js +24 -0
  7. package/dist/chunks/{chunk-UHPK62Q5.js → chunk-M5XZWCPS.js} +240 -60
  8. package/dist/chunks/{chunk-ZLRFD5JI.js → chunk-NYDJYMID.js} +263 -16
  9. package/dist/chunks/{src-7ENJHYG4.js → chunk-RDTHHRZN.js} +319 -165
  10. package/dist/chunks/{chunk-E4HNK7VF.js → chunk-WNTS7ZO4.js} +1 -1
  11. package/dist/chunks/chunk-XAEMVEYX.js +188 -0
  12. package/dist/chunks/{chunk-CLNMVQZJ.js → chunk-YFCMTTXS.js} +708 -494
  13. package/dist/chunks/chunk-YJ7WMBTT.js +13761 -0
  14. package/dist/chunks/src-5IP4NGKT.js +115 -0
  15. package/dist/chunks/src-6CJR547Y.js +124 -0
  16. package/dist/chunks/{src-WQWYJ6IQ.js → src-BPETAFLW.js} +175 -76
  17. package/dist/chunks/{src-B742AYFC.js → src-LLV7IY6W.js} +55 -16
  18. package/dist/chunks/src-RHNZELGE.js +306 -0
  19. package/dist/chunks/{src-4KFNL3MY.js → src-SFKFERZ2.js} +18 -8
  20. package/dist/chunks/{src-VEHGMKYV.js → src-VL2ZYO6X.js} +4 -4
  21. package/dist/hub/assets/Badge-CUJUit4d.js +1 -0
  22. package/dist/hub/assets/CandidatePanel-CnbK4S0j.js +1 -0
  23. package/dist/hub/assets/CatalogScreen-B5OVL-AR.js +1 -0
  24. package/dist/hub/assets/ChangesScreen-GwGqJwxN.js +1 -0
  25. package/dist/hub/assets/CheatSheet-BLSOq-xa.js +1 -0
  26. package/dist/hub/assets/CodeBlock-CsiGFgvI.js +1 -0
  27. package/dist/hub/assets/CommandPalette-CAWQfdXJ.js +1 -0
  28. package/dist/hub/assets/CopyButton-DE8drl4P.js +1 -0
  29. package/dist/hub/assets/Disclosure-B1kTgPgk.js +1 -0
  30. package/dist/hub/assets/DiscoverScreen-Tl_Z6mgY.js +2 -0
  31. package/dist/hub/assets/DraftEditor-yIDapXTs.js +5 -0
  32. package/dist/hub/assets/Field-LwrJXoOs.js +1 -0
  33. package/dist/hub/assets/GapsScreen-DXZAlm6v.js +1 -0
  34. package/dist/hub/assets/HomeScreen-CEpiVhOa.js +1 -0
  35. package/dist/hub/assets/InventoryScreen-CEG3Pmw_.js +1 -0
  36. package/dist/hub/assets/KindIcon-BJ6bz-ny.js +1 -0
  37. package/dist/hub/assets/LibraryScreen-IaVnxrX9.js +1 -0
  38. package/dist/hub/assets/LicenceBadge-CLCUMMHE.js +1 -0
  39. package/dist/hub/assets/Opened-DJyf4Hnj.js +1 -0
  40. package/dist/hub/assets/Preview-C069zVMP.js +1 -0
  41. package/dist/hub/assets/RuleDetail-B4g2-TRe.js +3 -0
  42. package/dist/hub/assets/RulesScreen-CAaXIWjO.js +3 -0
  43. package/dist/hub/assets/ScreenImage-DcI7_G3O.js +1 -0
  44. package/dist/hub/assets/ScreensScreen-DwczCjZD.js +1 -0
  45. package/dist/hub/assets/SearchField-DaCpNAj6.js +1 -0
  46. package/dist/hub/assets/Section-BTnvUq_W.js +1 -0
  47. package/dist/hub/assets/Segmented-Dzi1x49S.js +1 -0
  48. package/dist/hub/assets/ServiceDown-Bv-BPXro.js +1 -0
  49. package/dist/hub/assets/SpecimenCapture-DlsjshVE.js +1 -0
  50. package/dist/hub/assets/Specimens-C-lHp7sr.js +2 -0
  51. package/dist/hub/assets/StackScreen-DkmELsqR.js +1 -0
  52. package/dist/hub/assets/StubScreens-Bt7lWLVK.js +1 -0
  53. package/dist/hub/assets/StyleScreen-tq1tbRBo.js +1 -0
  54. package/dist/hub/assets/Swatch-KDz4qxdM.js +1 -0
  55. package/dist/hub/assets/Tabs-1QQDS0I6.js +1 -0
  56. package/dist/hub/assets/TokenDetail-DvCw6GqC.js +1 -0
  57. package/dist/hub/assets/TokenValue-CsPRc2ai.js +1 -0
  58. package/dist/hub/assets/TokensScreen-DoENV8Xy.js +1 -0
  59. package/dist/hub/assets/arrow-right-DcbNDzqs.js +1 -0
  60. package/dist/hub/assets/bot-B3gC9oUR.js +1 -0
  61. package/dist/hub/assets/button-6mvMVtpb.js +1 -0
  62. package/dist/hub/assets/button.demo-DuU0DQbv.js +1 -0
  63. package/dist/hub/assets/card.demo-CufAxMAA.js +1 -0
  64. package/dist/hub/assets/chevron-down-CzN07vMi.js +1 -0
  65. package/dist/hub/assets/circle-alert-DT2LC4yf.js +1 -0
  66. package/dist/hub/assets/circle-check-DkwBMT62.js +1 -0
  67. package/dist/hub/assets/client-D7whEyep.js +1 -0
  68. package/dist/hub/assets/clsx-DB0hHKMi.js +1 -0
  69. package/dist/hub/assets/compass-BkKOZPYe.js +1 -0
  70. package/dist/hub/assets/contrast-BkNHUAPa.js +1 -0
  71. package/dist/hub/assets/createLucideIcon-CGDJWtKO.js +1 -0
  72. package/dist/hub/assets/discover-XjJEViwk.js +1 -0
  73. package/dist/hub/assets/dist-BYQYaPBV.js +1 -0
  74. package/dist/hub/assets/dist-Bk4srtDn.js +41 -0
  75. package/dist/hub/assets/dist-BogNzeK9.js +1 -0
  76. package/dist/hub/assets/dist-D0z7Bvsy.js +1 -0
  77. package/dist/hub/assets/download-BQI-Si9R.js +1 -0
  78. package/dist/hub/assets/engine-CMmt9yEz.js +1 -0
  79. package/dist/hub/assets/esm-NPpg23M8.js +1 -0
  80. package/dist/hub/assets/family-tiles-CyTdy_cP.js +1 -0
  81. package/dist/hub/assets/format-DxAYNTN_.js +1 -0
  82. package/dist/hub/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  83. package/dist/hub/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  84. package/dist/hub/assets/geist-latin-core-vkBVTr4s.woff2 +0 -0
  85. package/dist/hub/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  86. package/dist/hub/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  87. package/dist/hub/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  88. package/dist/hub/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  89. package/dist/hub/assets/geist-mono-latin-core-DccGGzmg.woff2 +0 -0
  90. package/dist/hub/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  91. package/dist/hub/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  92. package/dist/hub/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  93. package/dist/hub/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  94. package/dist/hub/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  95. package/dist/hub/assets/git-pull-request-arrow-RqUUIRCU.js +1 -0
  96. package/dist/hub/assets/input.demo-238gqWpz.js +1 -0
  97. package/dist/hub/assets/inventory-BI8QBdar.js +1 -0
  98. package/dist/hub/assets/inventory-source-lZYzcA8O.js +1 -0
  99. package/dist/hub/assets/jsx-runtime-D6zNwnaE.js +9 -0
  100. package/dist/hub/assets/layers-DfzdK_wG.js +1 -0
  101. package/dist/hub/assets/layout-grid-xFY9L9Oc.js +1 -0
  102. package/dist/hub/assets/library-W5R8GwvG.js +1 -0
  103. package/dist/hub/assets/main-7snyIdoi.css +2 -0
  104. package/dist/hub/assets/main-B9CIkk5m.js +2 -0
  105. package/dist/hub/assets/minus-BDifFhOo.js +1 -0
  106. package/dist/hub/assets/monitor-X_lELkcU.js +1 -0
  107. package/dist/hub/assets/mouse-pointer-click-CVJ6hWg8.js +1 -0
  108. package/dist/hub/assets/paintbrush-DOkEgSTO.js +1 -0
  109. package/dist/hub/assets/plural-BbGQPQKA.js +1 -0
  110. package/dist/hub/assets/preview-BA8CPsKb.css +2 -0
  111. package/dist/hub/assets/preview-DUm13vr1.js +3 -0
  112. package/dist/hub/assets/protocol-caP6umNL.js +1 -0
  113. package/dist/hub/assets/react-DB-4Zxce.js +1 -0
  114. package/dist/hub/assets/shield-check-0ka0kQct.js +1 -0
  115. package/dist/hub/assets/trash-B7aEfJps.js +1 -0
  116. package/dist/hub/assets/triangle-alert-Dkdi9eDR.js +1 -0
  117. package/dist/hub/assets/try-live-zX3CSd3P.js +1 -0
  118. package/dist/hub/assets/utils-BoaXfs8y.js +1 -0
  119. package/dist/hub/assets/values-DzxR_TlI.js +1 -0
  120. package/dist/hub/assets/worker-Bh-wSp42.js +1 -0
  121. package/dist/hub/assets/workflow-jpV8wh-U.js +1 -0
  122. package/dist/hub/assets/x-MLbFVa4v.js +1 -0
  123. package/dist/hub/favicon.svg +1 -0
  124. package/dist/hub/index.html +35 -0
  125. package/dist/hub/kit/candidates.json +1 -0
  126. package/dist/hub/kit/chunks/chunk-2NYFUOIV.js +14 -0
  127. package/dist/hub/kit/chunks/chunk-DCANE7XH.js +1 -0
  128. package/dist/hub/kit/chunks/chunk-FTGHCY4I.js +14 -0
  129. package/dist/hub/kit/chunks/chunk-IBF3UTJF.js +33 -0
  130. package/dist/hub/kit/chunks/chunk-LLXY4VSH.js +1 -0
  131. package/dist/hub/kit/chunks/chunk-PUPZMW4P.js +14 -0
  132. package/dist/hub/kit/chunks/chunk-PWLNZQET.js +1 -0
  133. package/dist/hub/kit/chunks/chunk-ULXWVOKJ.js +1 -0
  134. package/dist/hub/kit/chunks/chunk-WM4BGGMK.js +1 -0
  135. package/dist/hub/kit/chunks/chunk-ZQUNRK72.js +1 -0
  136. package/dist/hub/kit/class-variance-authority.js +1 -0
  137. package/dist/hub/kit/clsx.js +1 -0
  138. package/dist/hub/kit/fonts/geist-cyrillic-ext-wght-normal.woff2 +0 -0
  139. package/dist/hub/kit/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
  140. package/dist/hub/kit/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  141. package/dist/hub/kit/fonts/geist-latin-wght-normal.woff2 +0 -0
  142. package/dist/hub/kit/fonts/geist-vietnamese-wght-normal.woff2 +0 -0
  143. package/dist/hub/kit/frame.css.src +73 -0
  144. package/dist/hub/kit/frame.js +2 -0
  145. package/dist/hub/kit/lucide-react.js +1878 -0
  146. package/dist/hub/kit/preview.html +13 -0
  147. package/dist/hub/kit/radix-ui-react-dialog.js +41 -0
  148. package/dist/hub/kit/radix-ui-react-label.js +1 -0
  149. package/dist/hub/kit/radix-ui-react-separator.js +1 -0
  150. package/dist/hub/kit/radix-ui-react-slot.js +1 -0
  151. package/dist/hub/kit/radix-ui-react-switch.js +1 -0
  152. package/dist/hub/kit/radix-ui-react-tabs.js +1 -0
  153. package/dist/hub/kit/react-dom-client.js +1 -0
  154. package/dist/hub/kit/react-dom.js +1 -0
  155. package/dist/hub/kit/react-jsx-runtime.js +1 -0
  156. package/dist/hub/kit/react.js +1 -0
  157. package/dist/hub/kit/tailwind-merge.js +1 -0
  158. package/dist/hub/kit/tailwindcss/index.css +950 -0
  159. package/dist/hub/kit/tailwindcss/preflight.css +398 -0
  160. package/dist/hub/kit/tailwindcss/theme.css +510 -0
  161. package/dist/hub/kit/tailwindcss/utilities.css +1 -0
  162. package/dist/hub-demo/frame/button.demo.js +1 -0
  163. package/dist/hub-demo/frame/card.demo.js +1 -0
  164. package/dist/hub-demo/frame/demos.js +6 -0
  165. package/dist/hub-demo/frame/frame.css +770 -0
  166. package/dist/hub-demo/frame/input.demo.js +1 -0
  167. package/dist/hub-demo/preview/components/button.demo.tsx +47 -0
  168. package/dist/hub-demo/preview/components/button.tsx +31 -0
  169. package/dist/hub-demo/preview/components/card.demo.tsx +26 -0
  170. package/dist/hub-demo/preview/components/card.tsx +20 -0
  171. package/dist/hub-demo/preview/components/input.demo.tsx +39 -0
  172. package/dist/hub-demo/preview/components/input.tsx +19 -0
  173. package/dist/hub-demo/preview/components/utils.ts +5 -0
  174. package/dist/hub-demo/preview/system.css +161 -0
  175. package/dist/hub-demo/public/data/demo-app.usage.bedd9c82fe.json +1 -0
  176. package/dist/hub-demo/public/data/demo.catalog.a605de2281.json +1 -0
  177. package/dist/hub-demo/public/data/gaps.129a93538d.json +1 -0
  178. package/dist/hub-demo/public/data/inventory.165a4f6408.json +1 -0
  179. package/dist/hub-demo/public/data/inventory.console.badge.ad0238784e.json +1 -0
  180. package/dist/hub-demo/public/data/inventory.console.button.3249daff35.json +1 -0
  181. package/dist/hub-demo/public/data/inventory.console.card.9ea88708ac.json +1 -0
  182. package/dist/hub-demo/public/data/inventory.console.dialog.8b6574d93a.json +1 -0
  183. package/dist/hub-demo/public/data/inventory.console.input.bdffb756a7.json +1 -0
  184. package/dist/hub-demo/public/data/inventory.console.link-as-button.1ce7faa1f3.json +1 -0
  185. package/dist/hub-demo/public/data/inventory.console.tabs.813e694c44.json +1 -0
  186. package/dist/hub-demo/public/data/inventory.extras.e5d06c6ff4.json +1 -0
  187. package/dist/hub-demo/public/data/inventory.site.badge.047a68f644.json +1 -0
  188. package/dist/hub-demo/public/data/inventory.site.button.720938384e.json +1 -0
  189. package/dist/hub-demo/public/data/inventory.site.card.d8df5f6873.json +1 -0
  190. package/dist/hub-demo/public/data/inventory.site.link-as-button.9c1f8a55bf.json +1 -0
  191. package/dist/hub-demo/public/data/inventory.site.tabs.59bd0200b9.json +1 -0
  192. package/dist/hub-demo/public/data/manifest.json +39 -0
  193. package/dist/hub-demo/public/data/specimens.console.dark.046471907d.css +786 -0
  194. package/dist/hub-demo/public/data/specimens.console.light.aaffa2d213.css +786 -0
  195. package/dist/hub-demo/public/data/specimens.site.dark.94a6706908.css +92 -0
  196. package/dist/hub-demo/public/data/specimens.site.light.3ddbc8d28d.css +92 -0
  197. package/dist/hub-demo/public/previews/button.dark.webp +0 -0
  198. package/dist/hub-demo/public/previews/button.light.webp +0 -0
  199. package/dist/hub-demo/public/previews/card.dark.webp +0 -0
  200. package/dist/hub-demo/public/previews/card.light.webp +0 -0
  201. package/dist/hub-demo/public/previews/input.dark.webp +0 -0
  202. package/dist/hub-demo/public/previews/input.light.webp +0 -0
  203. package/dist/hub-previews.js +173 -0
  204. package/dist/hub-server.js +6329 -0
  205. package/dist/hub-snapshot.js +573 -0
  206. package/dist/schema/youi.gaps.schema.json +235 -0
  207. package/dist/schema/youi.request.schema.json +229 -0
  208. package/dist/tailwind-worker.js +3 -3
  209. package/dist/youi.js +10 -8
  210. package/dist/youiyoux.js +10 -8
  211. package/package.json +4 -4
  212. package/dist/chunks/chunk-3ZHGONNA.js +0 -21797
@@ -0,0 +1,92 @@
1
+ /* src/styles/ui.css */
2
+ /* The site's kit: one BEM block per element, modifiers with --. */
3
+ :root {
4
+ --ui-radius: 8px;
5
+ --ui-control-height: 32px;
6
+ --ui-space: 4px;
7
+ }
8
+
9
+ .ui-button {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ height: var(--ui-control-height);
13
+ padding: 0 calc(var(--ui-space) * 3);
14
+ border-radius: var(--ui-radius);
15
+ font-size: 0.875rem;
16
+ font-weight: 500;
17
+ }
18
+
19
+ .ui-button--sm {
20
+ height: 28px;
21
+ padding: 0 10px;
22
+ }
23
+
24
+ .ui-button:is(:hover, .youi-state-hover, .youi-state-hover *) {
25
+ background: #f4f4f5;
26
+ }
27
+
28
+ @media (max-width: 640px) {
29
+ .ui-button {
30
+ height: 40px;
31
+ }
32
+ }
33
+
34
+ .ui-badge {
35
+ display: inline-flex;
36
+ height: 20px;
37
+ padding: 0 8px;
38
+ border-radius: 999px;
39
+ font-size: 12px;
40
+ font-weight: 500;
41
+ }
42
+
43
+ .ui-card {
44
+ padding: 24px;
45
+ border-radius: 12px;
46
+ border: 1px solid #e4e4e7;
47
+ }
48
+
49
+ .ui-tabs {
50
+ display: flex;
51
+ gap: 4px;
52
+ padding: 4px;
53
+ border-radius: 10px;
54
+ }
55
+
56
+ .ui-tab {
57
+ height: 28px;
58
+ padding: 0 12px;
59
+ border-radius: var(--ui-radius);
60
+ font-size: 14px;
61
+ font-weight: 500;
62
+ }
63
+
64
+ .ui-tab--active {
65
+ background: #fff;
66
+ }
67
+
68
+ /* src/styles/marketing.css */
69
+ /* The marketing pages' own styles: a plain .badge, with no kit prefix. */
70
+ .badge {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ height: 20px;
74
+ padding: 0 8px;
75
+ border-radius: 9999px;
76
+ font-size: 12px;
77
+ font-weight: 500;
78
+ }
79
+
80
+ .badge--muted {
81
+ opacity: 0.7;
82
+ }
83
+
84
+ /* Named like an element, but sets no shape: not a kit member. */
85
+ .tag-list {
86
+ display: flex;
87
+ gap: 8px;
88
+ }
89
+
90
+ :root { color-scheme: dark; }
91
+
92
+ /* youi-states: forced-state twins */
@@ -0,0 +1,92 @@
1
+ /* src/styles/ui.css */
2
+ /* The site's kit: one BEM block per element, modifiers with --. */
3
+ :root {
4
+ --ui-radius: 8px;
5
+ --ui-control-height: 32px;
6
+ --ui-space: 4px;
7
+ }
8
+
9
+ .ui-button {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ height: var(--ui-control-height);
13
+ padding: 0 calc(var(--ui-space) * 3);
14
+ border-radius: var(--ui-radius);
15
+ font-size: 0.875rem;
16
+ font-weight: 500;
17
+ }
18
+
19
+ .ui-button--sm {
20
+ height: 28px;
21
+ padding: 0 10px;
22
+ }
23
+
24
+ .ui-button:is(:hover, .youi-state-hover, .youi-state-hover *) {
25
+ background: #f4f4f5;
26
+ }
27
+
28
+ @media (max-width: 640px) {
29
+ .ui-button {
30
+ height: 40px;
31
+ }
32
+ }
33
+
34
+ .ui-badge {
35
+ display: inline-flex;
36
+ height: 20px;
37
+ padding: 0 8px;
38
+ border-radius: 999px;
39
+ font-size: 12px;
40
+ font-weight: 500;
41
+ }
42
+
43
+ .ui-card {
44
+ padding: 24px;
45
+ border-radius: 12px;
46
+ border: 1px solid #e4e4e7;
47
+ }
48
+
49
+ .ui-tabs {
50
+ display: flex;
51
+ gap: 4px;
52
+ padding: 4px;
53
+ border-radius: 10px;
54
+ }
55
+
56
+ .ui-tab {
57
+ height: 28px;
58
+ padding: 0 12px;
59
+ border-radius: var(--ui-radius);
60
+ font-size: 14px;
61
+ font-weight: 500;
62
+ }
63
+
64
+ .ui-tab--active {
65
+ background: #fff;
66
+ }
67
+
68
+ /* src/styles/marketing.css */
69
+ /* The marketing pages' own styles: a plain .badge, with no kit prefix. */
70
+ .badge {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ height: 20px;
74
+ padding: 0 8px;
75
+ border-radius: 9999px;
76
+ font-size: 12px;
77
+ font-weight: 500;
78
+ }
79
+
80
+ .badge--muted {
81
+ opacity: 0.7;
82
+ }
83
+
84
+ /* Named like an element, but sets no shape: not a kit member. */
85
+ .tag-list {
86
+ display: flex;
87
+ gap: 8px;
88
+ }
89
+
90
+ :root { color-scheme: light; }
91
+
92
+ /* youi-states: forced-state twins */
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __youiRequire } from "node:module"; import { dirname as __youiDir } from "node:path"; import { fileURLToPath as __youiPath } from "node:url"; const require = __youiRequire(import.meta.url); const __youiDirname = __youiDir(__youiPath(import.meta.url));
3
+ import {
4
+ launchBrowser
5
+ } from "./chunks/chunk-4BBYLTZX.js";
6
+ import {
7
+ discoverCacheDir,
8
+ loadIndex
9
+ } from "./chunks/chunk-M5XZWCPS.js";
10
+ import {
11
+ THUMBS_PATH,
12
+ THUMB_SCHEMES,
13
+ needsCapture,
14
+ prunePictures,
15
+ readThumbIndex,
16
+ selectCandidates,
17
+ thumbsDir,
18
+ writeThumbIndex
19
+ } from "./chunks/chunk-FJZFCAL5.js";
20
+ import "./chunks/chunk-XAEMVEYX.js";
21
+ import "./chunks/chunk-FVVL5JCY.js";
22
+ import "./chunks/chunk-NYDJYMID.js";
23
+ import "./chunks/chunk-WNTS7ZO4.js";
24
+
25
+ // ../../apps/web/scripts/capture-discover-thumbs.ts
26
+ import { createHash } from "node:crypto";
27
+ import { mkdir, rename, writeFile } from "node:fs/promises";
28
+ import { join, resolve } from "node:path";
29
+ import { parseArgs } from "node:util";
30
+ var DRAW_TIMEOUT_MS = 9e4;
31
+ var SETTLE_MS = 300;
32
+ var INSET = 8;
33
+ var WEBP_QUALITY = 0.86;
34
+ var BLANK_SHARE = 2e-3;
35
+ var SCALE = 2;
36
+ async function writeBytes(file, bytes) {
37
+ const temporary = `${file}.${process.pid}.tmp`;
38
+ await writeFile(temporary, bytes);
39
+ await rename(temporary, file);
40
+ }
41
+ async function webp(page, png) {
42
+ const { url, share } = await page.evaluate(
43
+ async ({ data, quality }) => {
44
+ const image = new Image();
45
+ image.src = `data:image/png;base64,${data}`;
46
+ await image.decode();
47
+ const canvas = document.createElement("canvas");
48
+ canvas.width = image.naturalWidth;
49
+ canvas.height = image.naturalHeight;
50
+ const context = canvas.getContext("2d");
51
+ context.drawImage(image, 0, 0);
52
+ const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
53
+ let away = 0;
54
+ for (let i = 0; i < pixels.length; i += 4) if (Math.abs(pixels[i] - pixels[0]) + Math.abs(pixels[i + 1] - pixels[1]) + Math.abs(pixels[i + 2] - pixels[2]) > 24) away++;
55
+ return { url: canvas.toDataURL("image/webp", quality), share: away / (pixels.length / 4) };
56
+ },
57
+ { data: png.toString("base64"), quality: WEBP_QUALITY }
58
+ );
59
+ if (!url.startsWith("data:image/webp;base64,")) throw new Error("this Chromium cannot encode WebP");
60
+ return { bytes: Buffer.from(url.slice("data:image/webp;base64,".length), "base64"), blank: share < BLANK_SHARE };
61
+ }
62
+ async function photograph(page, hub, id, project) {
63
+ await page.goto(`${hub}/discover/specimen?id=${encodeURIComponent(id)}&project=${encodeURIComponent(project)}`);
64
+ const settled = page.locator(`[data-capture="${id}"][data-capture-state="ready"] [data-capture-stage] iframe[data-placed], [data-capture-state="failed"]`).first();
65
+ try {
66
+ await settled.waitFor({ timeout: DRAW_TIMEOUT_MS });
67
+ await page.waitForFunction(() => document.querySelector('[data-capture-state="failed"]') || document.querySelectorAll("[data-capture-stage] iframe[data-placed]").length === 2, void 0, { timeout: DRAW_TIMEOUT_MS });
68
+ } catch {
69
+ return { status: "failed", reason: `It did not draw within ${DRAW_TIMEOUT_MS / 1e3}s` };
70
+ }
71
+ await page.waitForTimeout(SETTLE_MS);
72
+ const failed = page.locator('[data-capture-state="failed"]');
73
+ if (await failed.count()) return { status: "failed", reason: (await failed.first().getAttribute("data-capture-reason") ?? "It could not be drawn").replace(/\.$/, "") };
74
+ const shots = {};
75
+ let size = { width: 0, height: 0 };
76
+ for (const scheme of THUMB_SCHEMES) {
77
+ const box = await page.locator(`[data-capture-stage="${scheme}"]`).boundingBox();
78
+ if (!box) return { status: "failed", reason: "Its stage was not on the page" };
79
+ const clip = { x: box.x + INSET, y: box.y + INSET, width: box.width - 2 * INSET, height: box.height - 2 * INSET };
80
+ const shot = await webp(page, await page.screenshot({ clip }));
81
+ if (shot.blank) return { status: "failed", reason: "It draws nothing visible on its own (it may need data, a size or a parent)" };
82
+ shots[scheme] = shot.bytes;
83
+ size = { width: Math.round(clip.width * SCALE), height: Math.round(clip.height * SCALE) };
84
+ }
85
+ return { status: "drawn", light: shots.light, dark: shots.dark, ...size };
86
+ }
87
+ async function main() {
88
+ const { values } = parseArgs({ options: { hub: { type: "string" }, registry: { type: "string" }, role: { type: "string" }, limit: { type: "string" }, force: { type: "boolean", default: false }, cache: { type: "string" } } });
89
+ const hub = (values.hub ?? "http://localhost:5173").replace(/\/+$/, "");
90
+ const cache = resolve(discoverCacheDir(values.cache));
91
+ const limit = values.limit === void 0 ? null : Number(values.limit);
92
+ if (limit !== null && (!Number.isSafeInteger(limit) || limit <= 0)) throw new Error("--limit takes a whole number above 0");
93
+ const answer = await fetch(`${hub}${THUMBS_PATH}`).then(
94
+ async (res) => ({ ok: res.ok, body: await res.json().catch(() => null) }),
95
+ () => null
96
+ );
97
+ if (!answer) {
98
+ process.stderr.write(`\u2716 no hub answers at ${hub}: start one on your project with \`youiyoux ui --project <dir>\` (it says its port), then run this again
99
+ `);
100
+ return 1;
101
+ }
102
+ if (!answer.ok || !answer.body?.project) {
103
+ process.stderr.write(`\u2716 ${answer.body?.error ?? `the hub at ${hub} cannot serve Discover previews`}
104
+ `);
105
+ return 1;
106
+ }
107
+ const project = answer.body.project;
108
+ const listings = selectCandidates((await loadIndex(cache)).entries, { registry: values.registry ?? null, role: values.role ?? null, limit });
109
+ let index = readThumbIndex(cache, project);
110
+ const todo = listings.filter((e) => needsCapture(index, e.id, e.provenance.sha256, values.force));
111
+ process.stdout.write(`Photographing ${todo.length} of ${listings.length} candidates in ${project}'s theme (${listings.length - todo.length} already current)
112
+ `);
113
+ const dir = thumbsDir(cache, project);
114
+ await mkdir(dir, { recursive: true });
115
+ const offsite = [];
116
+ const browser = await launchBrowser(process.env.YOUI_CHROMIUM, { purpose: { what: "Discover previews", command: "youiyoux discover previews" } });
117
+ let drawn = 0;
118
+ let failed = 0;
119
+ try {
120
+ const context = await browser.newContext({ viewport: { width: 1200, height: 800 }, deviceScaleFactor: SCALE, reducedMotion: "reduce" });
121
+ const host = new URL(hub).host;
122
+ await context.route("**/*", (route) => {
123
+ const url = new URL(route.request().url());
124
+ if (url.host === host || url.protocol === "data:" || url.protocol === "blob:" || url.protocol === "about:") return route.continue();
125
+ offsite.push(url.href);
126
+ return route.abort();
127
+ });
128
+ const page = await context.newPage();
129
+ for (const entry of todo) {
130
+ const sha = entry.provenance.sha256;
131
+ const outcome = await photograph(page, hub, entry.id, project);
132
+ const items = { ...index.items };
133
+ const failures = { ...index.failed };
134
+ const at = (/* @__PURE__ */ new Date()).toISOString();
135
+ if (outcome.status === "drawn") {
136
+ const key = createHash("sha256").update(outcome.light).update(outcome.dark).digest("hex").slice(0, 16);
137
+ await writeBytes(join(dir, `${key}.light.webp`), outcome.light);
138
+ await writeBytes(join(dir, `${key}.dark.webp`), outcome.dark);
139
+ items[entry.id] = { sha, key, width: outcome.width, height: outcome.height, capturedAt: at };
140
+ delete failures[entry.id];
141
+ drawn++;
142
+ process.stdout.write(` \u2713 ${entry.source.ref}
143
+ `);
144
+ } else {
145
+ delete items[entry.id];
146
+ failures[entry.id] = { sha, reason: outcome.reason, at };
147
+ failed++;
148
+ process.stdout.write(` \u2013 ${entry.source.ref}: ${outcome.reason}
149
+ `);
150
+ }
151
+ index = { ...index, items, failed: failures };
152
+ await writeThumbIndex(cache, index);
153
+ }
154
+ } finally {
155
+ await browser.close();
156
+ }
157
+ const current = new Map((await loadIndex(cache)).entries.map((e) => [e.id, e.provenance?.sha256]));
158
+ index = { ...index, items: Object.fromEntries(Object.entries(index.items).filter(([id, t]) => current.get(id) === t.sha)), failed: Object.fromEntries(Object.entries(index.failed).filter(([id, f]) => current.get(id) === f.sha)) };
159
+ await writeThumbIndex(cache, index);
160
+ const pruned = await prunePictures(cache, index);
161
+ process.stdout.write(`${drawn} photographed, ${failed} could not be drawn on their own${pruned ? `, ${pruned} old pictures removed` : ""} \u2192 ${dir}
162
+ `);
163
+ if (offsite.length) process.stdout.write(`${offsite.length} requests to other hosts were blocked (${[...new Set(offsite.map((u) => new URL(u).host))].slice(0, 5).join(", ")})
164
+ `);
165
+ process.stdout.write(`Next: open ${hub}/discover?view=gallery
166
+ `);
167
+ return 0;
168
+ }
169
+ process.exitCode = await main().catch((error) => {
170
+ process.stderr.write(`\u2716 ${error instanceof Error ? error.message : String(error)}
171
+ `);
172
+ return 1;
173
+ });