@jant/core 0.3.39 → 1.0.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 (1162) hide show
  1. package/README.md +21 -33
  2. package/bin/commands/assets/upload.js +247 -0
  3. package/bin/commands/collections.js +268 -0
  4. package/bin/commands/import-site.js +1169 -343
  5. package/bin/commands/media.js +302 -0
  6. package/bin/commands/migrate-text-attachments.js +183 -0
  7. package/bin/commands/migrate.js +263 -2
  8. package/bin/commands/posts.js +262 -0
  9. package/bin/commands/search.js +53 -0
  10. package/bin/commands/settings.js +93 -0
  11. package/bin/commands/site/export.js +34 -33
  12. package/bin/commands/site/{localize-media.js → pull-media.js} +17 -17
  13. package/bin/lib/d1-query.js +15 -3
  14. package/bin/lib/http-api.js +223 -0
  15. package/bin/lib/media-upload.js +206 -0
  16. package/bin/lib/migration-runner.js +64 -0
  17. package/bin/lib/runtime-target.js +7 -2
  18. package/bin/lib/site-media-parser.js +71 -16
  19. package/bin/lib/site-pull-media.js +698 -0
  20. package/bin/lib/site-snapshot.js +0 -1
  21. package/dist/app-B5db9mS0.js +5 -0
  22. package/dist/{app-BfoG98VD.js → app-CwCepTko.js} +23938 -23014
  23. package/dist/client/.vite/manifest.json +3485 -0
  24. package/dist/client/_assets/chunks/02611a045a7fe83a12014e3debc9f731-BqEDtwXC.woff2 +0 -0
  25. package/dist/client/_assets/chunks/033466ef683afe931f7f520cfb42d928-BluLHEh9.woff2 +0 -0
  26. package/dist/client/_assets/chunks/04b8bde59cff68eeee74fb1914eb09c7-D5j2CLTt.woff2 +0 -0
  27. package/dist/client/_assets/chunks/057a6a98bda7fe57105ddaa99ec82015-DY_AoijT.woff2 +0 -0
  28. package/dist/client/_assets/chunks/05ac821472e235943ed1435e4bb8ecad-CUm8GiH6.woff2 +0 -0
  29. package/dist/client/_assets/chunks/05da12edb9d52210581dc6ec4541031f-BXAOx2XP.woff2 +0 -0
  30. package/dist/client/_assets/chunks/074c1f8483d5a4d8c45c8c5f3e4cbb32-CDqdMQm8.woff2 +0 -0
  31. package/dist/client/_assets/chunks/0968e4861204b51f62a2f8e9f15dd5e0-D5tLgF_8.woff2 +0 -0
  32. package/dist/client/_assets/chunks/0acd1fe2b2ea1ad1bfee7ae1fa139d27-BKK1m412.woff2 +0 -0
  33. package/dist/client/_assets/chunks/0c2ab6b295e55f356f8020d4e7747522-CkCQjQw3.woff2 +0 -0
  34. package/dist/client/_assets/chunks/0c5f9492af03a4fa42c784de94649de1-CQlJqksa.woff2 +0 -0
  35. package/dist/client/_assets/chunks/0d5dec931dc885f07fe5cd5af8bed675-C74x-U_U.woff2 +0 -0
  36. package/dist/client/_assets/chunks/0d9a936885a4c39077438effd3779cbd-Bw0fYF4S.woff2 +0 -0
  37. package/dist/client/_assets/chunks/0e645da524f7cfc0e8c3c03fb2b08428-BVeI_5Th.woff2 +0 -0
  38. package/dist/client/_assets/chunks/0f5e1a18987dbc84ca05188c129e1936-B6_lZ6fE.woff2 +0 -0
  39. package/dist/client/_assets/chunks/1076f0f6f66d28d7a2f16427faad4413-ubiXnD1P.woff2 +0 -0
  40. package/dist/client/_assets/chunks/112743a4ab5fdd1498dfdf2b11336380-B5FzQxTK.woff2 +0 -0
  41. package/dist/client/_assets/chunks/1211f03d3ff5759a702631445793f60e-DDcSiyCt.woff2 +0 -0
  42. package/dist/client/_assets/chunks/12ef1ba76bd20b004b865266a1aa70b3-BwmaD87S.woff2 +0 -0
  43. package/dist/client/_assets/chunks/135e83b403475c5dc9e49b43501a5b84-C5mE_KZS.woff2 +0 -0
  44. package/dist/client/_assets/chunks/1380210a722ac9aeef54005ad7b015c9-CjA-MP82.woff2 +0 -0
  45. package/dist/client/_assets/chunks/13b2c53b30e6a3e4de7132dbc18dbdfc-B9WOB7kv.woff2 +0 -0
  46. package/dist/client/_assets/chunks/147b24c2f08d03bbed30887d4cb3311c-IeeFCJ13.woff2 +0 -0
  47. package/dist/client/_assets/chunks/152395634a207579552f8cb54db88599-C2y2JyNZ.woff2 +0 -0
  48. package/dist/client/_assets/chunks/15d95680dc31cc6ce20e0a5464106dc4-CpD8dqRm.woff2 +0 -0
  49. package/dist/client/_assets/chunks/16663e567f81f4725a1522f37e18f71f-BNoxS9pQ.woff2 +0 -0
  50. package/dist/client/_assets/chunks/1733f27476507ca68b68a803bc533cc2-DXL-14Ug.woff2 +0 -0
  51. package/dist/client/_assets/chunks/17c7f5d0a45e92ede0e5dec3a2c77efa-CNj3jQMl.woff2 +0 -0
  52. package/dist/client/_assets/chunks/1824321da801e6257b902f3d1d09054c-D4dgdyWB.woff2 +0 -0
  53. package/dist/client/_assets/chunks/188c2db794f3dd7a45889ddbc81da9bb-C9NbUBBO.woff2 +0 -0
  54. package/dist/client/_assets/chunks/1a08931435f885e707edb85978ea3bb6-BOiP2u7G.woff2 +0 -0
  55. package/dist/client/_assets/chunks/1a3a92c7c060a71a6c35819b9ebcdbb9-DFfonQfz.woff2 +0 -0
  56. package/dist/client/_assets/chunks/1be602ad456b0d75902d352116cb35fd-Bc-XQtQh.woff2 +0 -0
  57. package/dist/client/_assets/chunks/1cf737900dd49c2e88f1b3221a82a602-CfTmnns3.woff2 +0 -0
  58. package/dist/client/_assets/chunks/1fba7ec0e412e911bf31841de5a8a4e4-18ELMbFF.woff2 +0 -0
  59. package/dist/client/_assets/chunks/233d3a685ee18276b319363474599d47-BaFdJ0-G.woff2 +0 -0
  60. package/dist/client/_assets/chunks/2612c60f9dc5459ac42763591240a1d6-CTD69cq1.woff2 +0 -0
  61. package/dist/client/_assets/chunks/284b53bbefb06924cf236d24c8ed5641-CPDiuOv6.woff2 +0 -0
  62. package/dist/client/_assets/chunks/28a97af9ab9d38983d20f39ff09840e1-mFqcT3Jw.woff2 +0 -0
  63. package/dist/client/_assets/chunks/2a56eaf19d1d38a6b57e2a388f733676-CU52qBlE.woff2 +0 -0
  64. package/dist/client/_assets/chunks/2ab8cf1f23a5ac7939a7876054e711a7-B4T3dK7A.woff2 +0 -0
  65. package/dist/client/_assets/chunks/2abfbab82b6a7c04426afc054d2464da-D5PIIHde.woff2 +0 -0
  66. package/dist/client/_assets/chunks/2bfaadaf3479c72286248e6de0be0ec9-DEpU6O74.woff2 +0 -0
  67. package/dist/client/_assets/chunks/2c8c55e4cec85ce77e95cac9d330f5cf-BCTA96EZ.woff2 +0 -0
  68. package/dist/client/_assets/chunks/2e6f4bb71ef6b38765d51acc5a79f638-Mbs6PECD.woff2 +0 -0
  69. package/dist/client/_assets/chunks/2ed9981d2e8983365bd051159b976b6d-D8gg6NWM.woff2 +0 -0
  70. package/dist/client/_assets/chunks/2f4c633e923ba30c6ba376367379fc91-CIJCFztv.woff2 +0 -0
  71. package/dist/client/_assets/chunks/31194d303a67561926a544ed0e072aee-w3-eGYAi.woff2 +0 -0
  72. package/dist/client/_assets/chunks/31a197213ae61d7043c81013f52d10d6-DXZrrkJP.woff2 +0 -0
  73. package/dist/client/_assets/chunks/349965eee0a9b6c984a319ab96a4ece9-DByAVmXw.woff2 +0 -0
  74. package/dist/client/_assets/chunks/34e6750e00c3a911ef87dc66b336594d-DNbWesOu.woff2 +0 -0
  75. package/dist/client/_assets/chunks/3623d96698132c61e861f984ce11cc23-jqV9ErzX.woff2 +0 -0
  76. package/dist/client/_assets/chunks/36cda3eae13370b934bba4429fab9078-BPDcUlw9.woff2 +0 -0
  77. package/dist/client/_assets/chunks/36f3df4730cfca4fc77fe52b52e6a126-BwK10NC0.woff2 +0 -0
  78. package/dist/client/_assets/chunks/37887deb7a9c466cf2af6ee7ff372ea6-BrAerJB1.woff2 +0 -0
  79. package/dist/client/_assets/chunks/37dbd564820cce2f7b3331e442da0df3-Cql2kzIi.woff2 +0 -0
  80. package/dist/client/_assets/chunks/37dc8505b20b37a2477a9121b16d44a7-CoXw6XWV.woff2 +0 -0
  81. package/dist/client/_assets/chunks/39211b02f24c69cbd1b54f6d41b01933-4Xu7vvnq.woff2 +0 -0
  82. package/dist/client/_assets/chunks/3aa13f1843d7c8fa16109b6395a9a29d-BQFZUc3B.woff2 +0 -0
  83. package/dist/client/_assets/chunks/3aba89c4d4281553078de4622b498cbb-8QS1zDYk.woff2 +0 -0
  84. package/dist/client/_assets/chunks/3ac0a07878cacdc98bb889f40f5970d3-C-BaM6-y.woff2 +0 -0
  85. package/dist/client/_assets/chunks/3d88558097559d775231194d43745ba7-CR2aqGC7.woff2 +0 -0
  86. package/dist/client/_assets/chunks/3dc3e8c35524cad2d1236f3393104ccf-9sqBsF7B.woff2 +0 -0
  87. package/dist/client/_assets/chunks/3e24063b19abd2b051af986a6870046d-TlweM3SW.woff2 +0 -0
  88. package/dist/client/_assets/chunks/3e2c06bdd9dcab29aeaeb0cfb7fa608a-BaqU-dIt.woff2 +0 -0
  89. package/dist/client/_assets/chunks/424123f9371ba357087363263eeafcda-C8SVfEJi.woff2 +0 -0
  90. package/dist/client/_assets/chunks/43b3bbf43055c3e65db9cdf2c5b18c1c-CbHx6-Ki.woff2 +0 -0
  91. package/dist/client/_assets/chunks/4410f876d27c9821839474b6b1059fd7-ClYz91aY.woff2 +0 -0
  92. package/dist/client/_assets/chunks/44704471b60c18b3ecec5300a88f1102-DDmmy6-m.woff2 +0 -0
  93. package/dist/client/_assets/chunks/45140742dfa8686b58db2899ce89f89a-D5IMMzDM.woff2 +0 -0
  94. package/dist/client/_assets/chunks/46604090efbb99c2db1800928af0a239-JX2fpYX_.woff2 +0 -0
  95. package/dist/client/_assets/chunks/46998df85d31e629c0142f0556f5e7c5-BIkNG9Wh.woff2 +0 -0
  96. package/dist/client/_assets/chunks/469d2754e315e77270c12fa0ab28026c-D-y-vsfA.woff2 +0 -0
  97. package/dist/client/_assets/chunks/479329a39a3eb6c0047e6b0981919855-vZKCRx42.woff2 +0 -0
  98. package/dist/client/_assets/chunks/491bbba374093fff045f55803a22bfef-DSQXiDCd.woff2 +0 -0
  99. package/dist/client/_assets/chunks/49902f1c41b281f8eb3771abdd4dccb8-DxVxNg2W.woff2 +0 -0
  100. package/dist/client/_assets/chunks/4c0760284569b87d8f2290c324953973-Bqd-TKHH.woff2 +0 -0
  101. package/dist/client/_assets/chunks/4cba92c942694bdc479bc54101bb1aa4-BrfsrgrC.woff2 +0 -0
  102. package/dist/client/_assets/chunks/4d38e56738156625329d93bd5c8cc74a-DONkMP0y.woff2 +0 -0
  103. package/dist/client/_assets/chunks/4db4f31a16965baa42cb7dad667a8f04-Dt1Cy4gr.woff2 +0 -0
  104. package/dist/client/_assets/chunks/4e7d263c30bb48604069a3b4404d4eeb-DNPCkvKD.woff2 +0 -0
  105. package/dist/client/_assets/chunks/5279c7e465d9871edf51fd02e691eee7-CKhyhvVf.woff2 +0 -0
  106. package/dist/client/_assets/chunks/527ff336279465617aafbafe1a830632-CC3lv4pm.woff2 +0 -0
  107. package/dist/client/_assets/chunks/54bfdb6f21f9d6191e5100580239e14f-PGlqYvgl.woff2 +0 -0
  108. package/dist/client/_assets/chunks/56b40518ea0608e62826bd44ee27f5f9-BD9F9Oss.woff2 +0 -0
  109. package/dist/client/_assets/chunks/56be5e32fd01668fe5ba814d94905839-CSyFA-9l.woff2 +0 -0
  110. package/dist/client/_assets/chunks/572b9e28f1e6d89b765a16d809db84a1-BIYMjzEa.woff2 +0 -0
  111. package/dist/client/_assets/chunks/57e9a86651366c1ba299e47aa7e358c2-BHuZXB4W.woff2 +0 -0
  112. package/dist/client/_assets/chunks/57f89adeae55aa7fe2add3fc1801ce03-Cy3PNrfx.woff2 +0 -0
  113. package/dist/client/_assets/chunks/5921cef36750ff6092d94b83a802823b-hF-uymTh.woff2 +0 -0
  114. package/dist/client/_assets/chunks/59e95d8b5332dcdae894a19946ab767d-ClRfsjWZ.woff2 +0 -0
  115. package/dist/client/_assets/chunks/5acc7f736217259db79a42bf44241c48-FYQUuFOM.woff2 +0 -0
  116. package/dist/client/_assets/chunks/5c05f8b75c9d7f25b3c04ca711cf43b3-D-YWPkSq.woff2 +0 -0
  117. package/dist/client/_assets/chunks/5df9ce98c75f8c50fb4fff7f01a23925-DgoCENyW.woff2 +0 -0
  118. package/dist/client/_assets/chunks/5e0124c7265f1b4cf0fc797b94efbebc-BTBNHsSB.woff2 +0 -0
  119. package/dist/client/_assets/chunks/5ec349ff62b9ee5fe0c6dae867704dc4-B4dezhrz.woff2 +0 -0
  120. package/dist/client/_assets/chunks/60020a830d809c26970cf8e48ba1eeda-B6FDTSik.woff2 +0 -0
  121. package/dist/client/_assets/chunks/601f812e8b1eafecd5ba585a6a6d7962-gIVBlUU9.woff2 +0 -0
  122. package/dist/client/_assets/chunks/6025ddaf99d86cc8bfd781006b19fbd6-CS-ze337.woff2 +0 -0
  123. package/dist/client/_assets/chunks/60bcfa3ea7446eb42394aab02d28be40-C-PQfCu3.woff2 +0 -0
  124. package/dist/client/_assets/chunks/60f6e28b3f0400b0e8fe32c3c7116102-Dag9L2qU.woff2 +0 -0
  125. package/dist/client/_assets/chunks/615a7e0d63f257109d599b2a1977de68-D6Y93yoG.woff2 +0 -0
  126. package/dist/client/_assets/chunks/615b38e0b5bb3ea68426f44f47706e6f-B5yzIIer.woff2 +0 -0
  127. package/dist/client/_assets/chunks/61a2c80d0c924d5a6187c02e8d1d1642-BY3MmHbZ.woff2 +0 -0
  128. package/dist/client/_assets/chunks/62fc94f8d4c5a750b7f25e7387539910-3ql2_WDK.woff2 +0 -0
  129. package/dist/client/_assets/chunks/639c7c6b0b0c27c738702741cfa4b8c0-BCD3OGri.woff2 +0 -0
  130. package/dist/client/_assets/chunks/63fafcb069520613d0ea35ad3e6b1e42-DP0Rrj4o.woff2 +0 -0
  131. package/dist/client/_assets/chunks/64a404d675f1d726f0891b7a80794595-DU3L0I9s.woff2 +0 -0
  132. package/dist/client/_assets/chunks/65a60d87c64228d258a123cbe85f5f31-B4kbf-79.woff2 +0 -0
  133. package/dist/client/_assets/chunks/65e9c4585d71bf48a5c62f367010da16-CvzgzReN.woff2 +0 -0
  134. package/dist/client/_assets/chunks/68a3a4bf337f8a0722be76676e20b850-Dnaw8EPD.woff2 +0 -0
  135. package/dist/client/_assets/chunks/6968e889e18891d912809fe484c2e745-Bj1m5e0s.woff2 +0 -0
  136. package/dist/client/_assets/chunks/6abdd163d2c4b85698db8aa1ce149361-B5FVGJuo.woff2 +0 -0
  137. package/dist/client/_assets/chunks/6b75213eb0be40ce84241eb2bb438a2e-CqHmF-NR.woff2 +0 -0
  138. package/dist/client/_assets/chunks/70714891ad3fbfc3d5f10a8669dacc5a-BWk5nLFN.woff2 +0 -0
  139. package/dist/client/_assets/chunks/7158022889c6c177062ac85036e7af10-B3D4K22n.woff2 +0 -0
  140. package/dist/client/_assets/chunks/73b794d885b88f7befb7ea8ab1780a15-D0ZehnEI.woff2 +0 -0
  141. package/dist/client/_assets/chunks/743f290baf027d4626a86e22f3d44600-DDTDQdRC.woff2 +0 -0
  142. package/dist/client/_assets/chunks/7520ca6ca8c60eb1e62d50e71c8d30f1-CVRaGu2G.woff2 +0 -0
  143. package/dist/client/_assets/chunks/757019c01c5e2c2b0f54293cea3b5636-BTovUnoH.woff2 +0 -0
  144. package/dist/client/_assets/chunks/759a647b77791b1e98f99bc0ab5317a7-CrK6FIFz.woff2 +0 -0
  145. package/dist/client/_assets/chunks/761d84afca8d7f34eebefe538adba827-DRbiVuwX.woff2 +0 -0
  146. package/dist/client/_assets/chunks/76e07530323418ec723c5d7634c9bcca-DGtVJTTH.woff2 +0 -0
  147. package/dist/client/_assets/chunks/76e51630143b95b6322ef93ad330da7a-D-kV82C_.woff2 +0 -0
  148. package/dist/client/_assets/chunks/76f117a3baacda304a71965a17266a13-DFfvsFUm.woff2 +0 -0
  149. package/dist/client/_assets/chunks/773819b7b9b8fd404a929867c0fd677e-Bu1xCMZb.woff2 +0 -0
  150. package/dist/client/_assets/chunks/77747f17625a259fb405b7bbdd84ac4b-o_vNfh-6.woff2 +0 -0
  151. package/dist/client/_assets/chunks/7817dd16805145d8538ad57590f69f5a-DguSUP3O.woff2 +0 -0
  152. package/dist/client/_assets/chunks/788498548ddfb710d6ef3c7bff79fa97-3ffoQfRd.woff2 +0 -0
  153. package/dist/client/_assets/chunks/78ea6c40923ce95367e3517dd1e5a849-DvLDRhX9.woff2 +0 -0
  154. package/dist/client/_assets/chunks/79aa7c8c842c4a27cf57c0a3a1ffca5a-sDoCeoKI.woff2 +0 -0
  155. package/dist/client/_assets/chunks/7b59f0ec7792b18458dc5a361e37884c-DWvxkKmT.woff2 +0 -0
  156. package/dist/client/_assets/chunks/7c3945788a689a69356c1a622d69d48b-1JjIpss2.woff2 +0 -0
  157. package/dist/client/_assets/chunks/7cc72fd2c9105560422b6a67c6162945-Co3AF5_G.woff2 +0 -0
  158. package/dist/client/_assets/chunks/7d0ea0690e432462f4d05a23d720ec19-Dx7DK4C3.woff2 +0 -0
  159. package/dist/client/_assets/chunks/7dffa5c1bec57e0903fd62357401ff1a-DuQHmiiN.woff2 +0 -0
  160. package/dist/client/_assets/chunks/7e38ca789a9e76ac91d9256374e154f0-BtETgGRe.woff2 +0 -0
  161. package/dist/client/_assets/chunks/7f9a6c9286b68de9c72b0024f7beeb40-JpXdo4FC.woff2 +0 -0
  162. package/dist/client/_assets/chunks/815a0b797465190f60d8b1a04656c42e-Spzo94nU.woff2 +0 -0
  163. package/dist/client/_assets/chunks/823d1bb11097331238d103c7f72138dc-CGN6m2VF.woff2 +0 -0
  164. package/dist/client/_assets/chunks/82f6ccc063960eed1cdfd1d61ada8862-CsmAqx2a.woff2 +0 -0
  165. package/dist/client/_assets/chunks/835b6505bb9eea9678925a1fa885353d-C6mSBwUc.woff2 +0 -0
  166. package/dist/client/_assets/chunks/845b4b67564d62cf5cad242f7ac08ea5-DnvzrloJ.woff2 +0 -0
  167. package/dist/client/_assets/chunks/84c8e7bc0931008ed91f44ed12dfea94-C2Hvhh-b.woff2 +0 -0
  168. package/dist/client/_assets/chunks/8726558cf297cbda831cc19514897205-gSFV1vW0.woff2 +0 -0
  169. package/dist/client/_assets/chunks/8855472f3c02f6c7ebb3216617ebe4af-C1JsWVqq.woff2 +0 -0
  170. package/dist/client/_assets/chunks/887a11290ba78b1e66c6d2f67043005e-L_A1f5Fz.woff2 +0 -0
  171. package/dist/client/_assets/chunks/888ba53510213d5d1f6a7deb60e569b6-OP8E-ELN.woff2 +0 -0
  172. package/dist/client/_assets/chunks/88db1d042074fb6e66821ffc10941930-kZ6K3e62.woff2 +0 -0
  173. package/dist/client/_assets/chunks/892aa49b2529c89bb4076d4aa51fe30f-Bw0_Km2A.woff2 +0 -0
  174. package/dist/client/_assets/chunks/8b5c9ef81159f31d2ab35f45ca4373e0-Djw95sKC.woff2 +0 -0
  175. package/dist/client/_assets/chunks/8b91c7c2ed390f1278b9befa3aa87233-B2C3iFbQ.woff2 +0 -0
  176. package/dist/client/_assets/chunks/8dc18c0cebe6aa4bf4c45dbb831048ab-bUlANLit.woff2 +0 -0
  177. package/dist/client/_assets/chunks/8e231d707f0c4f8e3cde90a6b52a79aa-CvwbWlul.woff2 +0 -0
  178. package/dist/client/_assets/chunks/8fb45117a62d92dce44a80f0b729ead5-Djr4-o5-.woff2 +0 -0
  179. package/dist/client/_assets/chunks/9064c12fd72c7aba235d8c3881755b91-BnguxT-p.woff2 +0 -0
  180. package/dist/client/_assets/chunks/90b7848e9b1623b77bdcf155e90b839c-CFvPRnoM.woff2 +0 -0
  181. package/dist/client/_assets/chunks/911b9e53e9814de2998c60bf3115f560-DmPmj635.woff2 +0 -0
  182. package/dist/client/_assets/chunks/919a879bd2d580d8491a31a449390689-BY2w-8_Y.woff2 +0 -0
  183. package/dist/client/_assets/chunks/91da6cb174bebfb96976e2f1316be2fe-DztAJb6W.woff2 +0 -0
  184. package/dist/client/_assets/chunks/92fdc376bce277874e75db666f175b44-DJUnHEIN.woff2 +0 -0
  185. package/dist/client/_assets/chunks/930a23430f0eb64480d7fe5f82834e21-2VrDPT7E.woff2 +0 -0
  186. package/dist/client/_assets/chunks/934dfdbed2bb2c4b6129199d699a34fa-CtpHsjRD.woff2 +0 -0
  187. package/dist/client/_assets/chunks/93bed0e5f2dd5a21cf73304fcfbc149d-DJiaETX7.woff2 +0 -0
  188. package/dist/client/_assets/chunks/93f3ea6918533d96d9c252378b9a4af0-D-FJaGi-.woff2 +0 -0
  189. package/dist/client/_assets/chunks/95a0951d2a2722ff773a1a45e8c474d6-DuZg-BpP.woff2 +0 -0
  190. package/dist/client/_assets/chunks/95ff41191c76ef893ac70a1043e95e44-C08QDbJO.woff2 +0 -0
  191. package/dist/client/_assets/chunks/96c75862c8cec51a7c05ff025fea86cd-DBnRwCuW.woff2 +0 -0
  192. package/dist/client/_assets/chunks/97d7a17234f2b5030ae9697ae00aded2-CkUSaB-p.woff2 +0 -0
  193. package/dist/client/_assets/chunks/982cd1765ca6bbb3e6547e47834d5148-DkIybx1r.woff2 +0 -0
  194. package/dist/client/_assets/chunks/985d4d41afa0934a4eb2de35473fb9a2-CF7rgJMw.woff2 +0 -0
  195. package/dist/client/_assets/chunks/995c4fda62d25c3b79dd5987737df6ae-CY5ri8HW.woff2 +0 -0
  196. package/dist/client/_assets/chunks/9b0c3caac458c7bc9c9133e40405ddea-DhPrYOcz.woff2 +0 -0
  197. package/dist/client/_assets/chunks/9b21e8244f5930c48ad5073f83777b6c-CuE9-r-r.woff2 +0 -0
  198. package/dist/client/_assets/chunks/9bb38fd05201de666b88b82d56a386f7-nMl6lB8X.woff2 +0 -0
  199. package/dist/client/_assets/chunks/9d0afa53dc2f92ba42024f55f11f6779-Bozpx8bL.woff2 +0 -0
  200. package/dist/client/_assets/chunks/9e13a47242926f1cd7d68c08d9ef8889-DwKQjc8M.woff2 +0 -0
  201. package/dist/client/_assets/chunks/9eff2ab2a9d2ced47ab761bf6fdb11ec-D86-Zm1H.woff2 +0 -0
  202. package/dist/client/_assets/chunks/9f1963fe8d4d6878d717d872a8f3fdb5-DxjITUFq.woff2 +0 -0
  203. package/dist/client/_assets/chunks/9f3bdab4025dc7c5ba1a5871e62e8918-BqxDEFLJ.woff2 +0 -0
  204. package/dist/client/_assets/chunks/9fce02d1a09f464c36c9fcfb14a354c5-F2tMAB_j.woff2 +0 -0
  205. package/dist/client/_assets/chunks/a00e94d4f04df6aa659db9c4954c7efe-CRBKCj_3.woff2 +0 -0
  206. package/dist/client/_assets/chunks/a0a6755c7e3f9e4cf03387027dd9f16c-BAyRqF2w.woff2 +0 -0
  207. package/dist/client/_assets/chunks/a0d00fe4816c95a8c7dffd445ef00b03-CxcTiRLJ.woff2 +0 -0
  208. package/dist/client/_assets/chunks/a0f199077fa1a33bc2a1e01c64de7fe6-IdgVJmZD.woff2 +0 -0
  209. package/dist/client/_assets/chunks/a2b0597837e382aca19919c4b74e58c8-7iVOBjzI.woff2 +0 -0
  210. package/dist/client/_assets/chunks/a373e85c96aa0dc303092429fb837e51-Dvmw8mbX.woff2 +0 -0
  211. package/dist/client/_assets/chunks/a379ada89abd750c587ded29f77e731c-CgPBsEsv.woff2 +0 -0
  212. package/dist/client/_assets/chunks/a4475c442c6b259354c9eda62e64e7df-TZ0c8vK-.woff2 +0 -0
  213. package/dist/client/_assets/chunks/a48be56ce5d3a99dc8f8331398004412-BR_ixH1W.woff2 +0 -0
  214. package/dist/client/_assets/chunks/a4a39b5f048671aa37c2b2a9581ab08a-EDfDYsUd.woff2 +0 -0
  215. package/dist/client/_assets/chunks/a534449d67561ac9b06489f64e57ad98-C355TCrD.woff2 +0 -0
  216. package/dist/client/_assets/chunks/a6e044424780a57610833cc856c15bf5-x1b8FE4H.woff2 +0 -0
  217. package/dist/client/_assets/chunks/a7c35e42a659347e490c3cb7983b2e7f-BWpA0-oz.woff2 +0 -0
  218. package/dist/client/_assets/chunks/a7c58070d68dc1724e9d4e781afb78db-ql27pT-6.woff2 +0 -0
  219. package/dist/client/_assets/chunks/a806759e72987951d6d08b7cbdf36a1b-TvLDwB_u.woff2 +0 -0
  220. package/dist/client/_assets/chunks/a88481ec8bc7be11cb66e46781a79bb9-Ck-r_sGx.woff2 +0 -0
  221. package/dist/client/_assets/chunks/a919a8c6fec6d7e8bb21177965f2e9d7-CC5uWzwd.woff2 +0 -0
  222. package/dist/client/_assets/chunks/a9a016d4a93409f65278327e8a8bb38d-dylrNwF8.woff2 +0 -0
  223. package/dist/client/_assets/chunks/aa662092cf249707123ca4d575e2764b-CSxNsTUL.woff2 +0 -0
  224. package/dist/client/_assets/chunks/aae1eda193285ab817a2d1b408440326-CjyjBoRm.woff2 +0 -0
  225. package/dist/client/_assets/chunks/ab92d41062a7644faa45f50bf384454a-Cq0X8a9H.woff2 +0 -0
  226. package/dist/client/_assets/chunks/accc43762ad05edfbff66ba1380d192a-B5jIykaZ.woff2 +0 -0
  227. package/dist/client/_assets/chunks/ad47bcd6d4663026d648c132d969318d-BYdIbDge.woff2 +0 -0
  228. package/dist/client/_assets/chunks/ad67113f88b59582991cb0c5d33ea19f-DOH1vcIZ.woff2 +0 -0
  229. package/dist/client/_assets/chunks/adb6e613fb99c6dd660b727101f554a8-DJDw_ZZK.woff2 +0 -0
  230. package/dist/client/_assets/chunks/adc4a98a89870ef984ee8f4b57c8a3a5-D30vw26R.woff2 +0 -0
  231. package/dist/client/_assets/chunks/af57a2e8c72f9ba0efb1af771d32c124-D5Zwq9pS.woff2 +0 -0
  232. package/dist/client/_assets/chunks/b0ae5f374e43dac992a4a5d334cebc0b-Ccoi4dPt.woff2 +0 -0
  233. package/dist/client/_assets/chunks/b0cb664cb2e1371efda8943c0b7dcd1c-YzGFnelF.woff2 +0 -0
  234. package/dist/client/_assets/chunks/b0d1cdced482352cf0d3ae58638aacb9-IunWfc6R.woff2 +0 -0
  235. package/dist/client/_assets/chunks/b12379ab782468d725519cd07a7d15bc-IjbydKs2.woff2 +0 -0
  236. package/dist/client/_assets/chunks/b320f5d185b2cff933ac549c184031c5-IYnPrIz4.woff2 +0 -0
  237. package/dist/client/_assets/chunks/b326a8a9c33b554db570da94f60bc380-B6dzaCQg.woff2 +0 -0
  238. package/dist/client/_assets/chunks/b55486f8a459c838fe329d4e79a8c211-DW8q7oGV.woff2 +0 -0
  239. package/dist/client/_assets/chunks/b6117ff2993b11bb1fdc7ea3588a010c-JoMYL5W_.woff2 +0 -0
  240. package/dist/client/_assets/chunks/b61982951bd51b724143c30dfaaa9fe9-D3KhBKl6.woff2 +0 -0
  241. package/dist/client/_assets/chunks/b91234c10fd8b8c8abc88e03afe66a1f-BABNh2la.woff2 +0 -0
  242. package/dist/client/_assets/chunks/b9317198f118a1dfd8ddf2b82ec028f3-CiMecxeH.woff2 +0 -0
  243. package/dist/client/_assets/chunks/ba825ae79b1a6f7e0cce5215fcb5c96f-B6EWU_D5.woff2 +0 -0
  244. package/dist/client/_assets/chunks/ba9c59d7dfa4494db1bb764ada81467d-D0yPcC1m.woff2 +0 -0
  245. package/dist/client/_assets/chunks/bab547459d514f46206e340c4bb2dc88-YnBqlGhw.woff2 +0 -0
  246. package/dist/client/_assets/chunks/bb0b15492b8cdbbec57c0bcfa0aa9241-BjIFbEsN.woff2 +0 -0
  247. package/dist/client/_assets/chunks/bc6183ac08f0fac78c46f80c10cf7c92-B81nbRb3.woff2 +0 -0
  248. package/dist/client/_assets/chunks/bc8ccea5abf6598cf3cfa97eb59804bb-B_7IbluG.woff2 +0 -0
  249. package/dist/client/_assets/chunks/bc95a792cbca6639214c9b0da13392ff-CHQe0E-D.woff2 +0 -0
  250. package/dist/client/_assets/chunks/bcc39eda837bb7a7a3d37c8c60fffb81-CGd1Zk6S.woff2 +0 -0
  251. package/dist/client/_assets/chunks/bcfa62f35731856246c146d3a6932bf3-DMDq6w4v.woff2 +0 -0
  252. package/dist/client/_assets/chunks/bd73264d7f98776708d5d6f3c9b78fcc-d9QWWMym.woff2 +0 -0
  253. package/dist/client/_assets/chunks/bed610b217d500f5975cfc9fe6157570-B5t7s1bw.woff2 +0 -0
  254. package/dist/client/_assets/chunks/bedc74b423b7293b6ad0bdecc61c42cc-4Nnh7peP.woff2 +0 -0
  255. package/dist/client/_assets/chunks/bf8901f8f11d4f433ea17dabc9370ea6-B8dkfvGn.woff2 +0 -0
  256. package/dist/client/_assets/chunks/bfb00d4a4c48661bd0be99f300a0faae-OxsWZ7l-.woff2 +0 -0
  257. package/dist/client/_assets/chunks/c0098958e20db68cab90097b5e62516f-VpjQo3vV.woff2 +0 -0
  258. package/dist/client/_assets/chunks/c063897793f593eb26d6ff7b7baaba18-BWeJJ1sH.woff2 +0 -0
  259. package/dist/client/_assets/chunks/c1b0df29ae41d764904df84e9ac83d1e-D1N934vs.woff2 +0 -0
  260. package/dist/client/_assets/chunks/c4143bb9f2fe77b6ccf20088a8904650-nHfYM24e.woff2 +0 -0
  261. package/dist/client/_assets/chunks/c42c67070cfe99cf823df92d81c7fa6e-B_a405Ez.woff2 +0 -0
  262. package/dist/client/_assets/chunks/c4bfaa5e50798246e3770718b7a7c84a-B-r6Y_o0.woff2 +0 -0
  263. package/dist/client/_assets/chunks/c4d749e45ecd5a5aed5a0bb3ebfd355d-CkqE1fRi.woff2 +0 -0
  264. package/dist/client/_assets/chunks/c6c2971ad1f3221f6cf84028aa0f477e-D7BZGIcY.woff2 +0 -0
  265. package/dist/client/_assets/chunks/c7ff3f6bbdcd5f604b7343602ab904df-Bq7UjVrZ.woff2 +0 -0
  266. package/dist/client/_assets/chunks/c84598999133455503042e06f4ab79cb-DIXndJX3.woff2 +0 -0
  267. package/dist/client/_assets/chunks/c945c62368357d05a53206620460fb30-82gFEf6n.woff2 +0 -0
  268. package/dist/client/_assets/chunks/c96d83978add28b356c22c4c84916733-BL4VaPIE.woff2 +0 -0
  269. package/dist/client/_assets/chunks/c97f41eef722121d86f55d553c056a39-CjejgQO2.woff2 +0 -0
  270. package/dist/client/_assets/chunks/ca62704509932d3232d62918de97af3f-CKWF-3mX.woff2 +0 -0
  271. package/dist/client/_assets/chunks/ca9a533988d7019597a60d4e17127e0c-ClZ6ygZM.woff2 +0 -0
  272. package/dist/client/_assets/chunks/cb7ccd6494256f7a2977b7c2b0225592-Cxp8XObm.woff2 +0 -0
  273. package/dist/client/_assets/chunks/ce022e18a1377ac509443c3c3790b431-DpH0t6Tn.woff2 +0 -0
  274. package/dist/client/_assets/chunks/ce41d70ce6a069a498525c9e15c45cf2-DGtgv-_b.woff2 +0 -0
  275. package/dist/client/_assets/chunks/cf2b28f90f47276f7e2688a65e88a101-LVbNkXHj.woff2 +0 -0
  276. package/dist/client/_assets/chunks/cf9cffe56636322f62b40d61130fbc5e-DNCBMqAo.woff2 +0 -0
  277. package/dist/client/_assets/chunks/d1f064825fa5784b5c930652bd831cce-BU6qwjp8.woff2 +0 -0
  278. package/dist/client/_assets/chunks/d20d8944bc0b85f5b2aae4b24f343516-oY9l-NmC.woff2 +0 -0
  279. package/dist/client/_assets/chunks/d2faabcedd19f016e7b21bce073c0ec8-Dv6eFCf5.woff2 +0 -0
  280. package/dist/client/_assets/chunks/d320171e57480510f87dbbc7d5264b0a-CcCfjaFX.woff2 +0 -0
  281. package/dist/client/_assets/chunks/d36644d6502527e1fff205d0c7eca434-kVBj8zy_.woff2 +0 -0
  282. package/dist/client/_assets/chunks/d3a72a99d365dddfbca8d017a8011368-Bgdmhl3M.woff2 +0 -0
  283. package/dist/client/_assets/chunks/d40ab99c7a38026f411c8f112f742b48-D7Nm7fg6.woff2 +0 -0
  284. package/dist/client/_assets/chunks/d42aafa0f246ad3b4c16fe96d3a3a432-CRxTqZXU.woff2 +0 -0
  285. package/dist/client/_assets/chunks/d4aaf23c13ae808a4bed617afd13aa07-d_T1SKe9.woff2 +0 -0
  286. package/dist/client/_assets/chunks/d509ee5c8241bc7c3de2039d75564fa5-BpNFD9JE.woff2 +0 -0
  287. package/dist/client/_assets/chunks/d675d717cd329bfd4c0524f76ae1579c-Bd5_ctoQ.woff2 +0 -0
  288. package/dist/client/_assets/chunks/d689b1861d7e4377dd72ad3013482612-jPsVOU3F.woff2 +0 -0
  289. package/dist/client/_assets/chunks/d6bb686bddfbe8f38a36a68e609a8667-C_QduS-X.woff2 +0 -0
  290. package/dist/client/_assets/chunks/d9020ff69a83b2a6ee1f42ae480f7db0-DLBUPMCe.woff2 +0 -0
  291. package/dist/client/_assets/chunks/d9047070d72a816b3dba9d40c2d85e69-LTQ42vEp.woff2 +0 -0
  292. package/dist/client/_assets/chunks/da04549f3f4ed28076b01b8cd710d313-CDXOeduw.woff2 +0 -0
  293. package/dist/client/_assets/chunks/da7af303f8c645f9a9dbae0e6e32dd35-DCkS2jqi.woff2 +0 -0
  294. package/dist/client/_assets/chunks/da90a9012ab2d98f759e3fa0820ef502-D0D9d1zg.woff2 +0 -0
  295. package/dist/client/_assets/chunks/dc6e234ded795e91f76d6647f628fbf0-IkooXcRh.woff2 +0 -0
  296. package/dist/client/_assets/chunks/dc8f6256445e68199540be9ade33529f-umb5tWbZ.woff2 +0 -0
  297. package/dist/client/_assets/chunks/dd0cfdfdac0866e66d587e2b5a9e9961-bl4ozE0c.woff2 +0 -0
  298. package/dist/client/_assets/chunks/de304c8a02e45ded4f8dcc479d167198-ClRu89-4.woff2 +0 -0
  299. package/dist/client/_assets/chunks/df10d94bea357a43313e20da5d84bd30-CmAgh2oA.woff2 +0 -0
  300. package/dist/client/_assets/chunks/df9568257eb29b156449fdd4bec5ec76-BMz6aLRr.woff2 +0 -0
  301. package/dist/client/_assets/chunks/e067cd0ed76c90cd0a93c9339253f20b-6RxCQ4jy.woff2 +0 -0
  302. package/dist/client/_assets/chunks/e08b07772e7bed3cec2832d43f7fd339-CQCkeKsr.woff2 +0 -0
  303. package/dist/client/_assets/chunks/e12150d5a39b30be8f567968c7a527b0-DjdoWzeQ.woff2 +0 -0
  304. package/dist/client/_assets/chunks/e34b2b141e472dc776c86fdf8eea23b0-Cjk7H-Ev.woff2 +0 -0
  305. package/dist/client/_assets/chunks/e444fd88f1390636e603d0d681538ac8-Bx7CPOZh.woff2 +0 -0
  306. package/dist/client/_assets/chunks/e53fcb2381eee345db4f6f973dd95a3e-DmkkCUWz.woff2 +0 -0
  307. package/dist/client/_assets/chunks/e5bd313ef81f687d398aacb11cec3069-CwBEbcji.woff2 +0 -0
  308. package/dist/client/_assets/chunks/e79898628283edc27180fc39d0d769c1-By2pplQz.woff2 +0 -0
  309. package/dist/client/_assets/chunks/e8c15be62faf978d208925e79ea6a10d-Ct5M9lTP.woff2 +0 -0
  310. package/dist/client/_assets/chunks/e8c364c16daa04835bf32d293d2598db-3v4Tut_d.woff2 +0 -0
  311. package/dist/client/_assets/chunks/e91c4d941ed9f5c2f3e27f205a3a225e-BwOJ2Lst.woff2 +0 -0
  312. package/dist/client/_assets/chunks/e9c566be7a5d38a9085225f7372bc82b-BCtnCVML.woff2 +0 -0
  313. package/dist/client/_assets/chunks/e9ebc567a711eeb29019ddae3e0ce7fe-CnNhV49O.woff2 +0 -0
  314. package/dist/client/_assets/chunks/eaf332445a40942928e5f5750c1c3116-qZ5LSRrj.woff2 +0 -0
  315. package/dist/client/_assets/chunks/eb5afb3d952b8593782caec6026514b6-BXugZF2T.woff2 +0 -0
  316. package/dist/client/_assets/chunks/ec86e23683052da5cfdc3b77641bd15a-BeLcbcRc.woff2 +0 -0
  317. package/dist/client/_assets/chunks/ecb8875a56c7b038b35432fda41ae128-BVqgNf1o.woff2 +0 -0
  318. package/dist/client/_assets/chunks/eda1b0cb6d1719dd9bedcf3216a9e8de-BJTfLL5z.woff2 +0 -0
  319. package/dist/client/_assets/chunks/edd6a4f608d04fc0351d7688cfc321e4-d3V4U40c.woff2 +0 -0
  320. package/dist/client/_assets/chunks/ee6fce20b420a480714607c66d7f97e5-DEtC-G5G.woff2 +0 -0
  321. package/dist/client/_assets/chunks/eee3836d6ac17ebb2c450bbcbc9db121-C5a2TZjQ.woff2 +0 -0
  322. package/dist/client/_assets/chunks/et-book-bold-line-figures-BFJr2_zv.woff +0 -0
  323. package/dist/client/_assets/chunks/et-book-display-italic-old-style-figures-CoeRJAe8.woff +0 -0
  324. package/dist/client/_assets/chunks/et-book-roman-line-figures-CaA40oOf.woff +0 -0
  325. package/dist/client/_assets/chunks/f1661731474b78bdf81114daf10b254f-KnMKX_U3.woff2 +0 -0
  326. package/dist/client/_assets/chunks/f2c58dee206ba9355046fc23d05491f7-Cm4tCWav.woff2 +0 -0
  327. package/dist/client/_assets/chunks/f50ac27ea4358d67fdda403c2bb52467-WCfYHde1.woff2 +0 -0
  328. package/dist/client/_assets/chunks/f55334112f8e8be82d65db29887a663f-vDq1zH8k.woff2 +0 -0
  329. package/dist/client/_assets/chunks/f5738255e92d8dd34a46d1bcdf4c4074-tpghTzL1.woff2 +0 -0
  330. package/dist/client/_assets/chunks/f740e93f3c0277ecc616594103bca683-C4BgW_ko.woff2 +0 -0
  331. package/dist/client/_assets/chunks/f7633b5af033d76ff2fb3c3c266d77c5-BCkrZxwO.woff2 +0 -0
  332. package/dist/client/_assets/chunks/f7d8468cba2335a83ee414ea68291bab-CVnotkZU.woff2 +0 -0
  333. package/dist/client/_assets/chunks/f91cd722855f4269256eae1187df64ec-DJlAx1A_.woff2 +0 -0
  334. package/dist/client/_assets/chunks/f9695c6c4df2bf6bc03045ff79d4f01f-DDaYGYHT.woff2 +0 -0
  335. package/dist/client/_assets/chunks/fa6e58ce4b52695e7ae19bbea6336ec8-B30jEpze.woff2 +0 -0
  336. package/dist/client/_assets/chunks/fada6eaa68ff8816afe43d2a36c5423e-DlGAWNPb.woff2 +0 -0
  337. package/dist/client/_assets/chunks/fbcc4bf5367218951172bdee6f77d7a6-Dax2VSCd.woff2 +0 -0
  338. package/dist/client/_assets/chunks/fc895f5ce66b656f4a933097bf2a8775-DjjysNdf.woff2 +0 -0
  339. package/dist/client/_assets/chunks/fc9ae5b600fb711f2d67e93ce768cba4-D1lx7LBz.woff2 +0 -0
  340. package/dist/client/_assets/chunks/fca6720fd14c467d29a90f18ef3859b9-B3btrwq3.woff2 +0 -0
  341. package/dist/client/_assets/chunks/fd1bb507bcbf04856eeb7f7fd47ea579-NR1nGJTt.woff2 +0 -0
  342. package/dist/client/_assets/chunks/fd1bceb55d3e0183ac2454b8532fec7d-D3t-v6nn.woff2 +0 -0
  343. package/dist/client/_assets/chunks/fd2069e6e8588c70b4f11364093b81f2-BoXhYVgw.woff2 +0 -0
  344. package/dist/client/_assets/chunks/{url-CG0eolsk.js → url-pLre2DM_.js} +1 -1
  345. package/dist/client/_assets/client-C_kImWZj.css +2 -0
  346. package/dist/client/_assets/client-D95FNDg5.js +272 -0
  347. package/dist/client/_assets/client-auth-BRFl5zQA.js +4547 -0
  348. package/dist/client/_assets/client-cjk-jp-DZwrTzQC.css +1 -0
  349. package/dist/client/_assets/client-cjk-kr-_3ZNI2ZP.css +1 -0
  350. package/dist/env-wCpMcNXs.js +252 -0
  351. package/dist/github-api-CficQztC.js +176 -0
  352. package/dist/github-app-F4qZ05xk.js +275 -0
  353. package/dist/github-sync-zohnA9qv.js +4696 -0
  354. package/dist/index.js +88 -2
  355. package/dist/node.js +71 -30
  356. package/dist/url-FvvgARU9.js +305 -0
  357. package/package.json +16 -12
  358. package/src/__tests__/bin/content-cli.test.ts +179 -0
  359. package/src/__tests__/bin/media-cli.test.ts +192 -0
  360. package/src/__tests__/export-hugo-build.test.ts +178 -0
  361. package/src/__tests__/export-import-roundtrip.test.ts +265 -0
  362. package/src/__tests__/export-service.test.ts +763 -510
  363. package/src/__tests__/helpers/export-fixtures.ts +108 -0
  364. package/src/__tests__/import-site-command.test.ts +358 -350
  365. package/src/__tests__/site-pull-media.test.ts +256 -0
  366. package/src/app.tsx +65 -13
  367. package/src/client/__tests__/collection-form-bridge.test.ts +87 -7
  368. package/src/client/__tests__/collection-page-actions.test.ts +4 -4
  369. package/src/client/__tests__/collection-picker-order.test.ts +53 -0
  370. package/src/client/__tests__/collection-sort-menu.test.ts +2 -2
  371. package/src/client/__tests__/compose-bridge.test.ts +305 -13
  372. package/src/client/__tests__/compose-launch.test.ts +120 -0
  373. package/src/client/__tests__/compose-shortcuts.test.ts +141 -0
  374. package/src/client/__tests__/feed-video-player.test.ts +44 -0
  375. package/src/client/__tests__/site-header-nav.test.ts +250 -0
  376. package/src/client/__tests__/sortable-list.test.ts +6 -2
  377. package/src/client/__tests__/thread-context.test.ts +117 -0
  378. package/src/client/collection-form-bridge.ts +109 -4
  379. package/src/client/collection-page-actions.ts +3 -1
  380. package/src/client/collection-picker-order.ts +104 -0
  381. package/src/client/components/__tests__/{jant-collection-sidebar.test.ts → jant-collection-directory.test.ts} +145 -8
  382. package/src/client/components/__tests__/jant-collection-form.test.ts +40 -18
  383. package/src/client/components/__tests__/jant-compose-dialog.test.ts +1285 -66
  384. package/src/client/components/__tests__/jant-compose-editor.test.ts +254 -19
  385. package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +127 -1
  386. package/src/client/components/__tests__/jant-media-lightbox.test.ts +237 -0
  387. package/src/client/components/__tests__/jant-nav-manager.test.ts +326 -0
  388. package/src/client/components/__tests__/jant-post-menu.test.ts +372 -2
  389. package/src/client/components/__tests__/jant-settings-avatar.test.ts +61 -5
  390. package/src/client/components/__tests__/jant-settings-general.test.ts +29 -28
  391. package/src/client/components/__tests__/jant-text-preview.test.ts +206 -0
  392. package/src/client/components/collection-manager-types.ts +18 -1
  393. package/src/client/components/compose-types.ts +48 -0
  394. package/src/client/components/jant-collection-directory.ts +1448 -0
  395. package/src/client/components/jant-collection-form.ts +65 -15
  396. package/src/client/components/jant-command-palette.ts +544 -0
  397. package/src/client/components/jant-compose-dialog.ts +2490 -375
  398. package/src/client/components/jant-compose-editor.ts +420 -75
  399. package/src/client/components/jant-compose-fullscreen.ts +59 -8
  400. package/src/client/components/jant-media-lightbox.ts +373 -18
  401. package/src/client/components/jant-nav-manager.ts +624 -286
  402. package/src/client/components/jant-post-menu.ts +451 -126
  403. package/src/client/components/jant-repo-picker-types.ts +39 -0
  404. package/src/client/components/jant-repo-picker.ts +799 -0
  405. package/src/client/components/jant-settings-avatar.ts +16 -2
  406. package/src/client/components/jant-settings-general.ts +137 -35
  407. package/src/client/components/jant-text-preview.ts +239 -55
  408. package/src/client/components/nav-manager-types.ts +25 -9
  409. package/src/client/components/settings-types.ts +13 -2
  410. package/src/client/compose-bridge.ts +428 -68
  411. package/src/client/compose-launch.ts +41 -4
  412. package/src/client/compose-shortcuts.ts +77 -5
  413. package/src/client/feed-video-player.ts +374 -0
  414. package/src/client/image-processor.ts +53 -127
  415. package/src/client/media-lightbox-events.ts +1 -0
  416. package/src/client/media-scroll-hint.ts +66 -0
  417. package/src/client/multipart-upload.ts +4 -1
  418. package/src/client/palette-shortcuts.ts +35 -0
  419. package/src/client/search-rank.ts +74 -0
  420. package/src/client/settings-bridge.ts +7 -0
  421. package/src/client/site-header-nav.d.ts +1 -0
  422. package/src/client/site-header-nav.js +139 -51
  423. package/src/client/sortable-list.ts +2 -0
  424. package/src/client/thread-context.ts +54 -11
  425. package/src/client/tiptap/__tests__/block-insertion.test.ts +65 -0
  426. package/src/client/tiptap/__tests__/footnotes.test.ts +692 -0
  427. package/src/client/tiptap/__tests__/link-toolbar.test.ts +120 -4
  428. package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +48 -0
  429. package/src/client/tiptap/block-insertion.ts +36 -0
  430. package/src/client/tiptap/bubble-menu.ts +34 -4
  431. package/src/client/tiptap/create-editor.ts +49 -30
  432. package/src/client/tiptap/embed-dialog.ts +301 -0
  433. package/src/client/tiptap/embed-node.ts +373 -0
  434. package/src/client/tiptap/embed-paste.ts +91 -0
  435. package/src/client/tiptap/extensions.ts +77 -28
  436. package/src/client/tiptap/footnotes.ts +718 -0
  437. package/src/client/tiptap/html-block-node.ts +222 -0
  438. package/src/client/tiptap/image-node.ts +49 -6
  439. package/src/client/tiptap/inline-image-upload.ts +200 -40
  440. package/src/client/tiptap/link-input-rules.ts +50 -16
  441. package/src/client/tiptap/link-toolbar.ts +156 -133
  442. package/src/client/tiptap/markdown-clipboard.ts +120 -0
  443. package/src/client/tiptap/more-break.ts +36 -3
  444. package/src/client/tiptap/paste-media.ts +6 -0
  445. package/src/client/tiptap/slash-commands.ts +167 -14
  446. package/src/client/tiptap/tab-indent.ts +184 -0
  447. package/src/client/tiptap/toolbar-mode.ts +15 -2
  448. package/src/client/tiptap/wrapping-input-rules.ts +102 -0
  449. package/src/client/types/sortablejs.d.ts +9 -1
  450. package/src/client/upload-session.ts +2 -1
  451. package/src/client/video-processor.ts +177 -20
  452. package/src/client-auth.ts +9 -1
  453. package/src/client-site.ts +15 -0
  454. package/src/client.ts +2 -0
  455. package/src/db/__tests__/demo-canonical-snapshot.test.ts +1 -1
  456. package/src/db/__tests__/migration-rehearsal.test.ts +5 -1
  457. package/src/db/__tests__/migrations.test.ts +25 -2
  458. package/src/db/backfills/0001_strip_collection_path_c_prefix.sql +11 -0
  459. package/src/db/backfills/0002_strip_collection_path_c_prefix_fix.sql +12 -0
  460. package/src/db/backfills/0003_clear_system_nav_default_labels.sql +15 -0
  461. package/src/db/dialect.ts +40 -0
  462. package/src/db/migrations/0005_busy_the_phantom.sql +39 -0
  463. package/src/db/migrations/0006_adorable_magdalene.sql +3 -0
  464. package/src/db/migrations/0007_unusual_warstar.sql +1 -0
  465. package/src/db/migrations/0008_nasty_lockheed.sql +1 -0
  466. package/src/db/migrations/0009_clear_fixer.sql +31 -0
  467. package/src/db/migrations/0010_futuristic_preak.sql +31 -0
  468. package/src/db/migrations/0011_bizarre_smasher.sql +30 -0
  469. package/src/db/migrations/0012_furry_thena.sql +52 -0
  470. package/src/db/migrations/0013_mixed_lightspeed.sql +39 -0
  471. package/src/db/migrations/0014_high_the_santerians.sql +41 -0
  472. package/src/db/migrations/0015_skinny_shinobi_shaw.sql +1 -0
  473. package/src/db/migrations/0016_remarkable_nicolaos.sql +17 -0
  474. package/src/db/migrations/0017_powerful_moonstone.sql +14 -0
  475. package/src/db/migrations/meta/0005_snapshot.json +1904 -0
  476. package/src/db/migrations/meta/0006_snapshot.json +1925 -0
  477. package/src/db/migrations/meta/0007_snapshot.json +1933 -0
  478. package/src/db/migrations/meta/0008_snapshot.json +1940 -0
  479. package/src/db/migrations/meta/0009_snapshot.json +1952 -0
  480. package/src/db/migrations/meta/0010_snapshot.json +1952 -0
  481. package/src/db/migrations/meta/0011_snapshot.json +1948 -0
  482. package/src/db/migrations/meta/0012_snapshot.json +1955 -0
  483. package/src/db/migrations/meta/0013_snapshot.json +1977 -0
  484. package/src/db/migrations/meta/0014_snapshot.json +1988 -0
  485. package/src/db/migrations/meta/0015_snapshot.json +1995 -0
  486. package/src/db/migrations/meta/0016_snapshot.json +2104 -0
  487. package/src/db/migrations/meta/0017_snapshot.json +2188 -0
  488. package/src/db/migrations/meta/_journal.json +92 -1
  489. package/src/db/migrations/pg/0003_motionless_norrin_radd.sql +21 -0
  490. package/src/db/migrations/pg/0004_nervous_captain_midlands.sql +3 -0
  491. package/src/db/migrations/pg/0005_romantic_mesmero.sql +1 -0
  492. package/src/db/migrations/pg/0006_perpetual_bruce_banner.sql +1 -0
  493. package/src/db/migrations/pg/0007_nav_item_placement.sql +1 -0
  494. package/src/db/migrations/pg/0008_yielding_frightful_four.sql +3 -0
  495. package/src/db/migrations/pg/0009_outstanding_ogun.sql +1 -0
  496. package/src/db/migrations/pg/0010_overjoyed_gertrude_yorkes.sql +28 -0
  497. package/src/db/migrations/pg/0011_fixed_hulk.sql +19 -0
  498. package/src/db/migrations/pg/0012_cute_shockwave.sql +2 -0
  499. package/src/db/migrations/pg/0013_bizarre_obadiah_stane.sql +1 -0
  500. package/src/db/migrations/pg/0014_tearful_grim_reaper.sql +16 -0
  501. package/src/db/migrations/pg/0015_daffy_mikhail_rasputin.sql +14 -0
  502. package/src/db/migrations/pg/meta/0003_snapshot.json +2482 -0
  503. package/src/db/migrations/pg/meta/0004_snapshot.json +2500 -0
  504. package/src/db/migrations/pg/meta/0005_snapshot.json +2507 -0
  505. package/src/db/migrations/pg/meta/0006_snapshot.json +2513 -0
  506. package/src/db/migrations/pg/meta/0008_snapshot.json +2524 -0
  507. package/src/db/migrations/pg/meta/0009_snapshot.json +2520 -0
  508. package/src/db/migrations/pg/meta/0010_snapshot.json +2526 -0
  509. package/src/db/migrations/pg/meta/0011_snapshot.json +2563 -0
  510. package/src/db/migrations/pg/meta/0012_snapshot.json +2573 -0
  511. package/src/db/migrations/pg/meta/0013_snapshot.json +2579 -0
  512. package/src/db/migrations/pg/meta/0014_snapshot.json +2702 -0
  513. package/src/db/migrations/pg/meta/0015_snapshot.json +2803 -0
  514. package/src/db/migrations/pg/meta/_journal.json +92 -1
  515. package/src/db/pg/__tests__/node.test.ts +38 -0
  516. package/src/db/pg/node.ts +149 -0
  517. package/src/db/pg/schema.ts +130 -12
  518. package/src/db/rehearsal-fixtures/demo-current.sql +47 -3
  519. package/src/db/schema.ts +139 -12
  520. package/src/i18n/Trans.tsx +3 -3
  521. package/src/i18n/__tests__/context.test.tsx +9 -6
  522. package/src/i18n/__tests__/detect.test.ts +65 -48
  523. package/src/i18n/__tests__/fallback.test.ts +40 -0
  524. package/src/i18n/__tests__/message-placeholders.test.ts +43 -0
  525. package/src/i18n/__tests__/middleware.test.ts +83 -0
  526. package/src/i18n/context.tsx +9 -44
  527. package/src/i18n/detect.ts +95 -28
  528. package/src/i18n/i18n.ts +41 -17
  529. package/src/i18n/index.ts +7 -5
  530. package/src/i18n/locales/{en.po → public/en.po} +298 -1151
  531. package/src/i18n/locales/public/en.ts +1 -0
  532. package/src/i18n/locales/public/zh-Hans.po +2327 -0
  533. package/src/i18n/locales/public/zh-Hans.ts +1 -0
  534. package/src/i18n/locales/public/zh-Hant.po +2327 -0
  535. package/src/i18n/locales/public/zh-Hant.ts +1 -0
  536. package/src/i18n/locales/settings/en.po +1622 -0
  537. package/src/i18n/locales/settings/en.ts +1 -0
  538. package/src/i18n/locales/settings/zh-Hans.po +1622 -0
  539. package/src/i18n/locales/settings/zh-Hans.ts +1 -0
  540. package/src/i18n/locales/settings/zh-Hant.po +1622 -0
  541. package/src/i18n/locales/settings/zh-Hant.ts +1 -0
  542. package/src/i18n/middleware.ts +37 -24
  543. package/src/index.ts +4 -5
  544. package/src/lib/__tests__/collection-groups.test.ts +80 -0
  545. package/src/lib/__tests__/constants.test.ts +1 -1
  546. package/src/lib/__tests__/csp-builder.test.ts +68 -0
  547. package/src/lib/__tests__/display-text.test.ts +27 -0
  548. package/src/lib/__tests__/embed-providers.test.ts +104 -0
  549. package/src/lib/__tests__/embed-render.test.ts +60 -0
  550. package/src/lib/__tests__/feed.test.ts +125 -63
  551. package/src/lib/__tests__/hosted-signin.test.ts +11 -2
  552. package/src/lib/__tests__/markdown-roundtrip-embed.test.ts +88 -0
  553. package/src/lib/__tests__/markdown-to-tiptap.test.ts +59 -0
  554. package/src/lib/__tests__/markdown.test.ts +47 -5
  555. package/src/lib/__tests__/navigation.test.ts +148 -0
  556. package/src/lib/__tests__/post-display.test.ts +3 -2
  557. package/src/lib/__tests__/post-meta.test.ts +3 -0
  558. package/src/lib/__tests__/resolve-config.test.ts +30 -25
  559. package/src/lib/__tests__/schemas.test.ts +35 -0
  560. package/src/lib/__tests__/slug-format.test.ts +8 -0
  561. package/src/lib/__tests__/summary.test.ts +400 -1
  562. package/src/lib/__tests__/theme.test.ts +41 -2
  563. package/src/lib/__tests__/timeline.test.ts +114 -26
  564. package/src/lib/__tests__/tiptap-render.test.ts +224 -0
  565. package/src/lib/__tests__/tiptap-to-markdown.test.ts +51 -0
  566. package/src/lib/__tests__/video-playback.test.ts +48 -0
  567. package/src/lib/__tests__/view.test.ts +115 -8
  568. package/src/lib/__tests__/worker-response-cache.test.ts +311 -0
  569. package/src/lib/__tests__/youtube.test.ts +99 -0
  570. package/src/lib/api-media.ts +55 -0
  571. package/src/lib/api-posts.ts +99 -0
  572. package/src/lib/api-search.ts +47 -0
  573. package/src/lib/api-settings.ts +122 -0
  574. package/src/lib/asset-path.ts +20 -2
  575. package/src/lib/collection-groups.ts +70 -0
  576. package/src/lib/collection-paths.ts +40 -0
  577. package/src/lib/constants.ts +3 -4
  578. package/src/lib/csp-builder.ts +99 -0
  579. package/src/lib/decorative-quote-mark.ts +11 -0
  580. package/src/lib/display-text.ts +56 -0
  581. package/src/lib/embed-providers.ts +289 -0
  582. package/src/lib/embed-render.ts +151 -0
  583. package/src/lib/env.ts +70 -1
  584. package/src/lib/excerpt.ts +11 -2
  585. package/src/lib/feed.ts +89 -66
  586. package/src/lib/footnotes.ts +146 -0
  587. package/src/lib/github-api.ts +423 -0
  588. package/src/lib/github-app-state.ts +135 -0
  589. package/src/lib/github-app.ts +487 -0
  590. package/src/lib/github-sync-queue-handler.ts +69 -0
  591. package/src/lib/github-sync-site-config.ts +57 -0
  592. package/src/lib/github-sync-trigger.ts +199 -0
  593. package/src/lib/github-sync-worker.ts +72 -0
  594. package/src/lib/hosted-signin.ts +1 -1
  595. package/src/lib/hugo-markdown.ts +255 -0
  596. package/src/lib/job-queue-cf.ts +18 -0
  597. package/src/lib/job-queue-db.ts +149 -0
  598. package/src/lib/job-queue.ts +35 -0
  599. package/src/lib/markdown-manager.ts +864 -0
  600. package/src/lib/markdown-to-tiptap.ts +4 -323
  601. package/src/lib/markdown.ts +16 -24
  602. package/src/lib/media-helpers.ts +1 -0
  603. package/src/lib/navigation.ts +40 -8
  604. package/src/lib/post-display.ts +10 -22
  605. package/src/lib/public-storage.ts +6 -1
  606. package/src/lib/render.tsx +5 -2
  607. package/src/lib/resolve-config.ts +23 -11
  608. package/src/lib/rich-image.ts +89 -0
  609. package/src/lib/schemas.ts +186 -12
  610. package/src/lib/slug-format.ts +8 -0
  611. package/src/lib/summary.ts +125 -18
  612. package/src/lib/theme.ts +119 -0
  613. package/src/lib/timeline.ts +91 -63
  614. package/src/lib/tiptap-render.ts +265 -126
  615. package/src/lib/tiptap-to-markdown.ts +6 -329
  616. package/src/lib/upload.ts +97 -6
  617. package/src/lib/version.ts +18 -0
  618. package/src/lib/video-playback.ts +73 -0
  619. package/src/lib/view.ts +130 -90
  620. package/src/lib/webhook-signature.ts +65 -0
  621. package/src/lib/worker-response-cache.ts +220 -0
  622. package/src/lib/youtube.ts +119 -0
  623. package/src/middleware/__tests__/onboarding.test.ts +3 -3
  624. package/src/middleware/__tests__/secure-headers.test.ts +28 -1
  625. package/src/middleware/config.ts +7 -10
  626. package/src/middleware/cors.ts +49 -0
  627. package/src/middleware/secure-headers.ts +45 -55
  628. package/src/node/__tests__/cli-migrate.test.ts +111 -0
  629. package/src/node/__tests__/cli-runtime-target.test.ts +1 -1
  630. package/src/node/__tests__/cli-site-token-env.test.ts +2 -2
  631. package/src/preset.css +316 -12
  632. package/src/routes/__tests__/compose.test.ts +3 -1
  633. package/src/routes/api/__tests__/collections.test.ts +81 -27
  634. package/src/routes/api/__tests__/mcp.test.ts +389 -0
  635. package/src/routes/api/__tests__/nav-items.test.ts +163 -2
  636. package/src/routes/api/__tests__/posts.test.ts +190 -0
  637. package/src/routes/api/__tests__/settings.test.ts +99 -3
  638. package/src/routes/api/__tests__/upload-multipart.test.ts +10 -2
  639. package/src/routes/api/__tests__/upload.test.ts +132 -0
  640. package/src/routes/api/__tests__/uploads.test.ts +5 -3
  641. package/src/routes/api/collections.ts +67 -26
  642. package/src/routes/api/custom-urls.ts +1 -0
  643. package/src/routes/api/export.ts +8 -4
  644. package/src/routes/api/github-sync.tsx +445 -0
  645. package/src/routes/api/internal/__tests__/sites.test.ts +45 -2
  646. package/src/routes/api/internal/sites.ts +2 -0
  647. package/src/routes/api/internal/text-attachments.ts +60 -0
  648. package/src/routes/api/internal/uploads.ts +5 -1
  649. package/src/routes/api/mcp.ts +30 -0
  650. package/src/routes/api/nav-items.ts +30 -11
  651. package/src/routes/api/palette.ts +17 -0
  652. package/src/routes/api/posts.ts +37 -106
  653. package/src/routes/api/public/__tests__/posts.test.ts +372 -0
  654. package/src/routes/api/public/posts.ts +302 -0
  655. package/src/routes/api/search.ts +1 -47
  656. package/src/routes/api/settings.ts +44 -58
  657. package/src/routes/api/upload-multipart.ts +15 -5
  658. package/src/routes/api/upload.ts +62 -49
  659. package/src/routes/api/uploads.ts +1 -0
  660. package/src/routes/auth/__tests__/hosted-sso.test.ts +33 -0
  661. package/src/routes/auth/__tests__/setup.test.ts +29 -4
  662. package/src/routes/auth/hosted-sso-expired-page.tsx +89 -0
  663. package/src/routes/auth/hosted-sso.ts +42 -1
  664. package/src/routes/auth/reset.tsx +46 -32
  665. package/src/routes/auth/setup.tsx +53 -43
  666. package/src/routes/auth/signin.tsx +34 -24
  667. package/src/routes/compose.tsx +114 -1
  668. package/src/routes/dash/__tests__/font-theme.test.ts +6 -27
  669. package/src/routes/dash/__tests__/settings-avatar.test.ts +2 -3
  670. package/src/routes/dash/custom-urls.tsx +250 -112
  671. package/src/routes/dash/settings.tsx +1163 -70
  672. package/src/routes/feed/__tests__/{rss.test.ts → feed.test.ts} +62 -123
  673. package/src/routes/feed/feed.ts +386 -0
  674. package/src/routes/feed/manifest.ts +67 -0
  675. package/src/routes/feed/sitemap.ts +11 -2
  676. package/src/routes/pages/__tests__/collection-routing.test.ts +176 -0
  677. package/src/routes/pages/__tests__/collections.test.ts +2 -3
  678. package/src/routes/pages/__tests__/featured.test.ts +2 -3
  679. package/src/routes/pages/archive.tsx +523 -127
  680. package/src/routes/pages/collection.tsx +265 -59
  681. package/src/routes/pages/collections.tsx +5 -1
  682. package/src/routes/pages/home.tsx +2 -2
  683. package/src/routes/pages/latest.tsx +3 -3
  684. package/src/routes/pages/page.tsx +221 -3
  685. package/src/routes/pages/partials.tsx +5 -0
  686. package/src/routes/pages/search.tsx +17 -1
  687. package/src/routes/pages/theme-sample.tsx +1 -2
  688. package/src/runtime/__tests__/node.test.ts +1 -1
  689. package/src/runtime/__tests__/readiness.test.ts +89 -0
  690. package/src/runtime/readiness.ts +129 -0
  691. package/src/runtime/site.ts +9 -1
  692. package/src/services/__tests__/collection.test.ts +181 -53
  693. package/src/services/__tests__/github-app-installations.test.ts +181 -0
  694. package/src/services/__tests__/github-sync-classify.test.ts +189 -0
  695. package/src/services/__tests__/github-sync-push.test.ts +159 -0
  696. package/src/services/__tests__/media.test.ts +444 -7
  697. package/src/services/__tests__/navigation.test.ts +271 -14
  698. package/src/services/__tests__/post-timeline.test.ts +85 -17
  699. package/src/services/__tests__/post.test.ts +118 -10
  700. package/src/services/__tests__/settings.test.ts +43 -21
  701. package/src/services/auth.ts +2 -2
  702. package/src/services/bootstrap.ts +10 -7
  703. package/src/services/collection.ts +644 -191
  704. package/src/services/custom-url.ts +34 -7
  705. package/src/services/export-theme/assets/client-site.css +2 -0
  706. package/src/services/export-theme/assets/client-site.js +145 -0
  707. package/src/services/export-theme/layouts/_default/alias.html +49 -0
  708. package/src/services/export-theme/layouts/_default/baseof.html +21 -0
  709. package/src/services/export-theme/layouts/_default/list.html +104 -0
  710. package/src/services/export-theme/layouts/_default/rss.xml +160 -0
  711. package/src/services/export-theme/layouts/_default/single.html +15 -0
  712. package/src/services/export-theme/layouts/archive/list.html +31 -0
  713. package/src/services/export-theme/layouts/collection/single.html +19 -0
  714. package/src/services/export-theme/layouts/collections/list.html +111 -0
  715. package/src/services/export-theme/layouts/featured/list.html +28 -0
  716. package/src/services/export-theme/layouts/index.html +41 -0
  717. package/src/services/export-theme/layouts/partials/feed-post-content.xml +107 -0
  718. package/src/services/export-theme/layouts/partials/footer.html +32 -0
  719. package/src/services/export-theme/layouts/partials/head.html +52 -0
  720. package/src/services/export-theme/layouts/partials/header.html +115 -0
  721. package/src/services/export-theme/layouts/partials/media-gallery.html +246 -0
  722. package/src/services/export-theme/layouts/partials/pagination.html +55 -0
  723. package/src/services/export-theme/layouts/partials/post-card.html +127 -0
  724. package/src/services/export-theme/layouts/partials/reply.html +91 -0
  725. package/src/services/export-theme/layouts/partials/thread-preview.html +82 -0
  726. package/src/services/export-theme/layouts/post/list.html +129 -0
  727. package/src/services/export-theme/styles/main.css +1981 -0
  728. package/src/services/export-theme/theme.toml +12 -0
  729. package/src/services/export.ts +1365 -2412
  730. package/src/services/github-app-installations.ts +302 -0
  731. package/src/services/github-sync.ts +769 -0
  732. package/src/services/index.ts +15 -0
  733. package/src/services/mcp.ts +1324 -0
  734. package/src/services/media.ts +336 -25
  735. package/src/services/navigation.ts +115 -23
  736. package/src/services/path.ts +129 -28
  737. package/src/services/post.ts +779 -207
  738. package/src/services/search.ts +3 -0
  739. package/src/services/settings.ts +29 -15
  740. package/src/services/site-admin.ts +26 -6
  741. package/src/services/upload-session.ts +69 -34
  742. package/src/style-cjk-jp.css +3 -0
  743. package/src/style-cjk-kr.css +3 -0
  744. package/src/styles/components.css +160 -59
  745. package/src/styles/fonts/et-book/et-book-bold-line-figures.woff +0 -0
  746. package/src/styles/fonts/et-book/et-book-display-italic-old-style-figures.woff +0 -0
  747. package/src/styles/fonts/et-book/et-book-roman-line-figures.woff +0 -0
  748. package/src/styles/fonts/et-book.css +31 -0
  749. package/src/styles/fonts/latin.css +1 -0
  750. package/src/styles/fonts/noto-serif-jp/400/057a6a98bda7fe57105ddaa99ec82015.woff2 +0 -0
  751. package/src/styles/fonts/noto-serif-jp/400/0acd1fe2b2ea1ad1bfee7ae1fa139d27.woff2 +0 -0
  752. package/src/styles/fonts/noto-serif-jp/400/0c2ab6b295e55f356f8020d4e7747522.woff2 +0 -0
  753. package/src/styles/fonts/noto-serif-jp/400/0c5f9492af03a4fa42c784de94649de1.woff2 +0 -0
  754. package/src/styles/fonts/noto-serif-jp/400/0d9a936885a4c39077438effd3779cbd.woff2 +0 -0
  755. package/src/styles/fonts/noto-serif-jp/400/0e645da524f7cfc0e8c3c03fb2b08428.woff2 +0 -0
  756. package/src/styles/fonts/noto-serif-jp/400/135e83b403475c5dc9e49b43501a5b84.woff2 +0 -0
  757. package/src/styles/fonts/noto-serif-jp/400/13b2c53b30e6a3e4de7132dbc18dbdfc.woff2 +0 -0
  758. package/src/styles/fonts/noto-serif-jp/400/15d95680dc31cc6ce20e0a5464106dc4.woff2 +0 -0
  759. package/src/styles/fonts/noto-serif-jp/400/1733f27476507ca68b68a803bc533cc2.woff2 +0 -0
  760. package/src/styles/fonts/noto-serif-jp/400/188c2db794f3dd7a45889ddbc81da9bb.woff2 +0 -0
  761. package/src/styles/fonts/noto-serif-jp/400/1cf737900dd49c2e88f1b3221a82a602.woff2 +0 -0
  762. package/src/styles/fonts/noto-serif-jp/400/233d3a685ee18276b319363474599d47.woff2 +0 -0
  763. package/src/styles/fonts/noto-serif-jp/400/284b53bbefb06924cf236d24c8ed5641.woff2 +0 -0
  764. package/src/styles/fonts/noto-serif-jp/400/2a56eaf19d1d38a6b57e2a388f733676.woff2 +0 -0
  765. package/src/styles/fonts/noto-serif-jp/400/2abfbab82b6a7c04426afc054d2464da.woff2 +0 -0
  766. package/src/styles/fonts/noto-serif-jp/400/2e6f4bb71ef6b38765d51acc5a79f638.woff2 +0 -0
  767. package/src/styles/fonts/noto-serif-jp/400/31194d303a67561926a544ed0e072aee.woff2 +0 -0
  768. package/src/styles/fonts/noto-serif-jp/400/3623d96698132c61e861f984ce11cc23.woff2 +0 -0
  769. package/src/styles/fonts/noto-serif-jp/400/39211b02f24c69cbd1b54f6d41b01933.woff2 +0 -0
  770. package/src/styles/fonts/noto-serif-jp/400/3e24063b19abd2b051af986a6870046d.woff2 +0 -0
  771. package/src/styles/fonts/noto-serif-jp/400/4410f876d27c9821839474b6b1059fd7.woff2 +0 -0
  772. package/src/styles/fonts/noto-serif-jp/400/479329a39a3eb6c0047e6b0981919855.woff2 +0 -0
  773. package/src/styles/fonts/noto-serif-jp/400/527ff336279465617aafbafe1a830632.woff2 +0 -0
  774. package/src/styles/fonts/noto-serif-jp/400/56b40518ea0608e62826bd44ee27f5f9.woff2 +0 -0
  775. package/src/styles/fonts/noto-serif-jp/400/5acc7f736217259db79a42bf44241c48.woff2 +0 -0
  776. package/src/styles/fonts/noto-serif-jp/400/5c05f8b75c9d7f25b3c04ca711cf43b3.woff2 +0 -0
  777. package/src/styles/fonts/noto-serif-jp/400/5e0124c7265f1b4cf0fc797b94efbebc.woff2 +0 -0
  778. package/src/styles/fonts/noto-serif-jp/400/615a7e0d63f257109d599b2a1977de68.woff2 +0 -0
  779. package/src/styles/fonts/noto-serif-jp/400/61a2c80d0c924d5a6187c02e8d1d1642.woff2 +0 -0
  780. package/src/styles/fonts/noto-serif-jp/400/62fc94f8d4c5a750b7f25e7387539910.woff2 +0 -0
  781. package/src/styles/fonts/noto-serif-jp/400/639c7c6b0b0c27c738702741cfa4b8c0.woff2 +0 -0
  782. package/src/styles/fonts/noto-serif-jp/400/68a3a4bf337f8a0722be76676e20b850.woff2 +0 -0
  783. package/src/styles/fonts/noto-serif-jp/400/6abdd163d2c4b85698db8aa1ce149361.woff2 +0 -0
  784. package/src/styles/fonts/noto-serif-jp/400/73b794d885b88f7befb7ea8ab1780a15.woff2 +0 -0
  785. package/src/styles/fonts/noto-serif-jp/400/743f290baf027d4626a86e22f3d44600.woff2 +0 -0
  786. package/src/styles/fonts/noto-serif-jp/400/757019c01c5e2c2b0f54293cea3b5636.woff2 +0 -0
  787. package/src/styles/fonts/noto-serif-jp/400/76f117a3baacda304a71965a17266a13.woff2 +0 -0
  788. package/src/styles/fonts/noto-serif-jp/400/77747f17625a259fb405b7bbdd84ac4b.woff2 +0 -0
  789. package/src/styles/fonts/noto-serif-jp/400/788498548ddfb710d6ef3c7bff79fa97.woff2 +0 -0
  790. package/src/styles/fonts/noto-serif-jp/400/78ea6c40923ce95367e3517dd1e5a849.woff2 +0 -0
  791. package/src/styles/fonts/noto-serif-jp/400/7f9a6c9286b68de9c72b0024f7beeb40.woff2 +0 -0
  792. package/src/styles/fonts/noto-serif-jp/400/823d1bb11097331238d103c7f72138dc.woff2 +0 -0
  793. package/src/styles/fonts/noto-serif-jp/400/888ba53510213d5d1f6a7deb60e569b6.woff2 +0 -0
  794. package/src/styles/fonts/noto-serif-jp/400/892aa49b2529c89bb4076d4aa51fe30f.woff2 +0 -0
  795. package/src/styles/fonts/noto-serif-jp/400/95ff41191c76ef893ac70a1043e95e44.woff2 +0 -0
  796. package/src/styles/fonts/noto-serif-jp/400/96c75862c8cec51a7c05ff025fea86cd.woff2 +0 -0
  797. package/src/styles/fonts/noto-serif-jp/400/9b21e8244f5930c48ad5073f83777b6c.woff2 +0 -0
  798. package/src/styles/fonts/noto-serif-jp/400/9fce02d1a09f464c36c9fcfb14a354c5.woff2 +0 -0
  799. package/src/styles/fonts/noto-serif-jp/400/a0a6755c7e3f9e4cf03387027dd9f16c.woff2 +0 -0
  800. package/src/styles/fonts/noto-serif-jp/400/a4475c442c6b259354c9eda62e64e7df.woff2 +0 -0
  801. package/src/styles/fonts/noto-serif-jp/400/a4a39b5f048671aa37c2b2a9581ab08a.woff2 +0 -0
  802. package/src/styles/fonts/noto-serif-jp/400/a534449d67561ac9b06489f64e57ad98.woff2 +0 -0
  803. package/src/styles/fonts/noto-serif-jp/400/a919a8c6fec6d7e8bb21177965f2e9d7.woff2 +0 -0
  804. package/src/styles/fonts/noto-serif-jp/400/ad67113f88b59582991cb0c5d33ea19f.woff2 +0 -0
  805. package/src/styles/fonts/noto-serif-jp/400/adb6e613fb99c6dd660b727101f554a8.woff2 +0 -0
  806. package/src/styles/fonts/noto-serif-jp/400/adc4a98a89870ef984ee8f4b57c8a3a5.woff2 +0 -0
  807. package/src/styles/fonts/noto-serif-jp/400/b12379ab782468d725519cd07a7d15bc.woff2 +0 -0
  808. package/src/styles/fonts/noto-serif-jp/400/b55486f8a459c838fe329d4e79a8c211.woff2 +0 -0
  809. package/src/styles/fonts/noto-serif-jp/400/bb0b15492b8cdbbec57c0bcfa0aa9241.woff2 +0 -0
  810. package/src/styles/fonts/noto-serif-jp/400/bedc74b423b7293b6ad0bdecc61c42cc.woff2 +0 -0
  811. package/src/styles/fonts/noto-serif-jp/400/bfb00d4a4c48661bd0be99f300a0faae.woff2 +0 -0
  812. package/src/styles/fonts/noto-serif-jp/400/c1b0df29ae41d764904df84e9ac83d1e.woff2 +0 -0
  813. package/src/styles/fonts/noto-serif-jp/400/c42c67070cfe99cf823df92d81c7fa6e.woff2 +0 -0
  814. package/src/styles/fonts/noto-serif-jp/400/c4d749e45ecd5a5aed5a0bb3ebfd355d.woff2 +0 -0
  815. package/src/styles/fonts/noto-serif-jp/400/c96d83978add28b356c22c4c84916733.woff2 +0 -0
  816. package/src/styles/fonts/noto-serif-jp/400/cb7ccd6494256f7a2977b7c2b0225592.woff2 +0 -0
  817. package/src/styles/fonts/noto-serif-jp/400/ce41d70ce6a069a498525c9e15c45cf2.woff2 +0 -0
  818. package/src/styles/fonts/noto-serif-jp/400/d509ee5c8241bc7c3de2039d75564fa5.woff2 +0 -0
  819. package/src/styles/fonts/noto-serif-jp/400/d675d717cd329bfd4c0524f76ae1579c.woff2 +0 -0
  820. package/src/styles/fonts/noto-serif-jp/400/dc8f6256445e68199540be9ade33529f.woff2 +0 -0
  821. package/src/styles/fonts/noto-serif-jp/400/e8c15be62faf978d208925e79ea6a10d.woff2 +0 -0
  822. package/src/styles/fonts/noto-serif-jp/400/e91c4d941ed9f5c2f3e27f205a3a225e.woff2 +0 -0
  823. package/src/styles/fonts/noto-serif-jp/400/e9c566be7a5d38a9085225f7372bc82b.woff2 +0 -0
  824. package/src/styles/fonts/noto-serif-jp/400/e9ebc567a711eeb29019ddae3e0ce7fe.woff2 +0 -0
  825. package/src/styles/fonts/noto-serif-jp/400/ecb8875a56c7b038b35432fda41ae128.woff2 +0 -0
  826. package/src/styles/fonts/noto-serif-jp/400/f1661731474b78bdf81114daf10b254f.woff2 +0 -0
  827. package/src/styles/fonts/noto-serif-jp/400/f2c58dee206ba9355046fc23d05491f7.woff2 +0 -0
  828. package/src/styles/fonts/noto-serif-jp/400/f50ac27ea4358d67fdda403c2bb52467.woff2 +0 -0
  829. package/src/styles/fonts/noto-serif-jp/400/f55334112f8e8be82d65db29887a663f.woff2 +0 -0
  830. package/src/styles/fonts/noto-serif-jp/400/f740e93f3c0277ecc616594103bca683.woff2 +0 -0
  831. package/src/styles/fonts/noto-serif-jp/400/f7633b5af033d76ff2fb3c3c266d77c5.woff2 +0 -0
  832. package/src/styles/fonts/noto-serif-jp/400/f7d8468cba2335a83ee414ea68291bab.woff2 +0 -0
  833. package/src/styles/fonts/noto-serif-jp/400/fc9ae5b600fb711f2d67e93ce768cba4.woff2 +0 -0
  834. package/src/styles/fonts/noto-serif-jp/400/fd1bceb55d3e0183ac2454b8532fec7d.woff2 +0 -0
  835. package/src/styles/fonts/noto-serif-jp/700/02611a045a7fe83a12014e3debc9f731.woff2 +0 -0
  836. package/src/styles/fonts/noto-serif-jp/700/0f5e1a18987dbc84ca05188c129e1936.woff2 +0 -0
  837. package/src/styles/fonts/noto-serif-jp/700/112743a4ab5fdd1498dfdf2b11336380.woff2 +0 -0
  838. package/src/styles/fonts/noto-serif-jp/700/1211f03d3ff5759a702631445793f60e.woff2 +0 -0
  839. package/src/styles/fonts/noto-serif-jp/700/147b24c2f08d03bbed30887d4cb3311c.woff2 +0 -0
  840. package/src/styles/fonts/noto-serif-jp/700/16663e567f81f4725a1522f37e18f71f.woff2 +0 -0
  841. package/src/styles/fonts/noto-serif-jp/700/1824321da801e6257b902f3d1d09054c.woff2 +0 -0
  842. package/src/styles/fonts/noto-serif-jp/700/1a3a92c7c060a71a6c35819b9ebcdbb9.woff2 +0 -0
  843. package/src/styles/fonts/noto-serif-jp/700/1fba7ec0e412e911bf31841de5a8a4e4.woff2 +0 -0
  844. package/src/styles/fonts/noto-serif-jp/700/28a97af9ab9d38983d20f39ff09840e1.woff2 +0 -0
  845. package/src/styles/fonts/noto-serif-jp/700/2bfaadaf3479c72286248e6de0be0ec9.woff2 +0 -0
  846. package/src/styles/fonts/noto-serif-jp/700/2c8c55e4cec85ce77e95cac9d330f5cf.woff2 +0 -0
  847. package/src/styles/fonts/noto-serif-jp/700/2ed9981d2e8983365bd051159b976b6d.woff2 +0 -0
  848. package/src/styles/fonts/noto-serif-jp/700/2f4c633e923ba30c6ba376367379fc91.woff2 +0 -0
  849. package/src/styles/fonts/noto-serif-jp/700/349965eee0a9b6c984a319ab96a4ece9.woff2 +0 -0
  850. package/src/styles/fonts/noto-serif-jp/700/36cda3eae13370b934bba4429fab9078.woff2 +0 -0
  851. package/src/styles/fonts/noto-serif-jp/700/3aa13f1843d7c8fa16109b6395a9a29d.woff2 +0 -0
  852. package/src/styles/fonts/noto-serif-jp/700/3e2c06bdd9dcab29aeaeb0cfb7fa608a.woff2 +0 -0
  853. package/src/styles/fonts/noto-serif-jp/700/424123f9371ba357087363263eeafcda.woff2 +0 -0
  854. package/src/styles/fonts/noto-serif-jp/700/43b3bbf43055c3e65db9cdf2c5b18c1c.woff2 +0 -0
  855. package/src/styles/fonts/noto-serif-jp/700/44704471b60c18b3ecec5300a88f1102.woff2 +0 -0
  856. package/src/styles/fonts/noto-serif-jp/700/46604090efbb99c2db1800928af0a239.woff2 +0 -0
  857. package/src/styles/fonts/noto-serif-jp/700/46998df85d31e629c0142f0556f5e7c5.woff2 +0 -0
  858. package/src/styles/fonts/noto-serif-jp/700/49902f1c41b281f8eb3771abdd4dccb8.woff2 +0 -0
  859. package/src/styles/fonts/noto-serif-jp/700/4db4f31a16965baa42cb7dad667a8f04.woff2 +0 -0
  860. package/src/styles/fonts/noto-serif-jp/700/572b9e28f1e6d89b765a16d809db84a1.woff2 +0 -0
  861. package/src/styles/fonts/noto-serif-jp/700/5921cef36750ff6092d94b83a802823b.woff2 +0 -0
  862. package/src/styles/fonts/noto-serif-jp/700/59e95d8b5332dcdae894a19946ab767d.woff2 +0 -0
  863. package/src/styles/fonts/noto-serif-jp/700/5ec349ff62b9ee5fe0c6dae867704dc4.woff2 +0 -0
  864. package/src/styles/fonts/noto-serif-jp/700/601f812e8b1eafecd5ba585a6a6d7962.woff2 +0 -0
  865. package/src/styles/fonts/noto-serif-jp/700/6025ddaf99d86cc8bfd781006b19fbd6.woff2 +0 -0
  866. package/src/styles/fonts/noto-serif-jp/700/60f6e28b3f0400b0e8fe32c3c7116102.woff2 +0 -0
  867. package/src/styles/fonts/noto-serif-jp/700/64a404d675f1d726f0891b7a80794595.woff2 +0 -0
  868. package/src/styles/fonts/noto-serif-jp/700/7158022889c6c177062ac85036e7af10.woff2 +0 -0
  869. package/src/styles/fonts/noto-serif-jp/700/7e38ca789a9e76ac91d9256374e154f0.woff2 +0 -0
  870. package/src/styles/fonts/noto-serif-jp/700/815a0b797465190f60d8b1a04656c42e.woff2 +0 -0
  871. package/src/styles/fonts/noto-serif-jp/700/8726558cf297cbda831cc19514897205.woff2 +0 -0
  872. package/src/styles/fonts/noto-serif-jp/700/8855472f3c02f6c7ebb3216617ebe4af.woff2 +0 -0
  873. package/src/styles/fonts/noto-serif-jp/700/8e231d707f0c4f8e3cde90a6b52a79aa.woff2 +0 -0
  874. package/src/styles/fonts/noto-serif-jp/700/9064c12fd72c7aba235d8c3881755b91.woff2 +0 -0
  875. package/src/styles/fonts/noto-serif-jp/700/911b9e53e9814de2998c60bf3115f560.woff2 +0 -0
  876. package/src/styles/fonts/noto-serif-jp/700/92fdc376bce277874e75db666f175b44.woff2 +0 -0
  877. package/src/styles/fonts/noto-serif-jp/700/930a23430f0eb64480d7fe5f82834e21.woff2 +0 -0
  878. package/src/styles/fonts/noto-serif-jp/700/93bed0e5f2dd5a21cf73304fcfbc149d.woff2 +0 -0
  879. package/src/styles/fonts/noto-serif-jp/700/93f3ea6918533d96d9c252378b9a4af0.woff2 +0 -0
  880. package/src/styles/fonts/noto-serif-jp/700/95a0951d2a2722ff773a1a45e8c474d6.woff2 +0 -0
  881. package/src/styles/fonts/noto-serif-jp/700/982cd1765ca6bbb3e6547e47834d5148.woff2 +0 -0
  882. package/src/styles/fonts/noto-serif-jp/700/9b0c3caac458c7bc9c9133e40405ddea.woff2 +0 -0
  883. package/src/styles/fonts/noto-serif-jp/700/9f3bdab4025dc7c5ba1a5871e62e8918.woff2 +0 -0
  884. package/src/styles/fonts/noto-serif-jp/700/a00e94d4f04df6aa659db9c4954c7efe.woff2 +0 -0
  885. package/src/styles/fonts/noto-serif-jp/700/a2b0597837e382aca19919c4b74e58c8.woff2 +0 -0
  886. package/src/styles/fonts/noto-serif-jp/700/a373e85c96aa0dc303092429fb837e51.woff2 +0 -0
  887. package/src/styles/fonts/noto-serif-jp/700/a6e044424780a57610833cc856c15bf5.woff2 +0 -0
  888. package/src/styles/fonts/noto-serif-jp/700/a7c58070d68dc1724e9d4e781afb78db.woff2 +0 -0
  889. package/src/styles/fonts/noto-serif-jp/700/accc43762ad05edfbff66ba1380d192a.woff2 +0 -0
  890. package/src/styles/fonts/noto-serif-jp/700/ad47bcd6d4663026d648c132d969318d.woff2 +0 -0
  891. package/src/styles/fonts/noto-serif-jp/700/af57a2e8c72f9ba0efb1af771d32c124.woff2 +0 -0
  892. package/src/styles/fonts/noto-serif-jp/700/b0ae5f374e43dac992a4a5d334cebc0b.woff2 +0 -0
  893. package/src/styles/fonts/noto-serif-jp/700/b91234c10fd8b8c8abc88e03afe66a1f.woff2 +0 -0
  894. package/src/styles/fonts/noto-serif-jp/700/b9317198f118a1dfd8ddf2b82ec028f3.woff2 +0 -0
  895. package/src/styles/fonts/noto-serif-jp/700/ba825ae79b1a6f7e0cce5215fcb5c96f.woff2 +0 -0
  896. package/src/styles/fonts/noto-serif-jp/700/bc6183ac08f0fac78c46f80c10cf7c92.woff2 +0 -0
  897. package/src/styles/fonts/noto-serif-jp/700/bc8ccea5abf6598cf3cfa97eb59804bb.woff2 +0 -0
  898. package/src/styles/fonts/noto-serif-jp/700/bc95a792cbca6639214c9b0da13392ff.woff2 +0 -0
  899. package/src/styles/fonts/noto-serif-jp/700/bcfa62f35731856246c146d3a6932bf3.woff2 +0 -0
  900. package/src/styles/fonts/noto-serif-jp/700/c063897793f593eb26d6ff7b7baaba18.woff2 +0 -0
  901. package/src/styles/fonts/noto-serif-jp/700/c6c2971ad1f3221f6cf84028aa0f477e.woff2 +0 -0
  902. package/src/styles/fonts/noto-serif-jp/700/c97f41eef722121d86f55d553c056a39.woff2 +0 -0
  903. package/src/styles/fonts/noto-serif-jp/700/ca62704509932d3232d62918de97af3f.woff2 +0 -0
  904. package/src/styles/fonts/noto-serif-jp/700/d1f064825fa5784b5c930652bd831cce.woff2 +0 -0
  905. package/src/styles/fonts/noto-serif-jp/700/d2faabcedd19f016e7b21bce073c0ec8.woff2 +0 -0
  906. package/src/styles/fonts/noto-serif-jp/700/d320171e57480510f87dbbc7d5264b0a.woff2 +0 -0
  907. package/src/styles/fonts/noto-serif-jp/700/d3a72a99d365dddfbca8d017a8011368.woff2 +0 -0
  908. package/src/styles/fonts/noto-serif-jp/700/d42aafa0f246ad3b4c16fe96d3a3a432.woff2 +0 -0
  909. package/src/styles/fonts/noto-serif-jp/700/d4aaf23c13ae808a4bed617afd13aa07.woff2 +0 -0
  910. package/src/styles/fonts/noto-serif-jp/700/d6bb686bddfbe8f38a36a68e609a8667.woff2 +0 -0
  911. package/src/styles/fonts/noto-serif-jp/700/d9020ff69a83b2a6ee1f42ae480f7db0.woff2 +0 -0
  912. package/src/styles/fonts/noto-serif-jp/700/da90a9012ab2d98f759e3fa0820ef502.woff2 +0 -0
  913. package/src/styles/fonts/noto-serif-jp/700/df10d94bea357a43313e20da5d84bd30.woff2 +0 -0
  914. package/src/styles/fonts/noto-serif-jp/700/e34b2b141e472dc776c86fdf8eea23b0.woff2 +0 -0
  915. package/src/styles/fonts/noto-serif-jp/700/e444fd88f1390636e603d0d681538ac8.woff2 +0 -0
  916. package/src/styles/fonts/noto-serif-jp/700/e79898628283edc27180fc39d0d769c1.woff2 +0 -0
  917. package/src/styles/fonts/noto-serif-jp/700/eaf332445a40942928e5f5750c1c3116.woff2 +0 -0
  918. package/src/styles/fonts/noto-serif-jp/700/f91cd722855f4269256eae1187df64ec.woff2 +0 -0
  919. package/src/styles/fonts/noto-serif-jp/700/fc895f5ce66b656f4a933097bf2a8775.woff2 +0 -0
  920. package/src/styles/fonts/noto-serif-jp/700/fca6720fd14c467d29a90f18ef3859b9.woff2 +0 -0
  921. package/src/styles/fonts/noto-serif-jp/700/fd1bb507bcbf04856eeb7f7fd47ea579.woff2 +0 -0
  922. package/src/styles/fonts/noto-serif-jp/noto-serif-jp.css +3349 -0
  923. package/src/styles/fonts/noto-serif-kr/400/033466ef683afe931f7f520cfb42d928.woff2 +0 -0
  924. package/src/styles/fonts/noto-serif-kr/400/05da12edb9d52210581dc6ec4541031f.woff2 +0 -0
  925. package/src/styles/fonts/noto-serif-kr/400/0968e4861204b51f62a2f8e9f15dd5e0.woff2 +0 -0
  926. package/src/styles/fonts/noto-serif-kr/400/0d5dec931dc885f07fe5cd5af8bed675.woff2 +0 -0
  927. package/src/styles/fonts/noto-serif-kr/400/1076f0f6f66d28d7a2f16427faad4413.woff2 +0 -0
  928. package/src/styles/fonts/noto-serif-kr/400/12ef1ba76bd20b004b865266a1aa70b3.woff2 +0 -0
  929. package/src/styles/fonts/noto-serif-kr/400/152395634a207579552f8cb54db88599.woff2 +0 -0
  930. package/src/styles/fonts/noto-serif-kr/400/1a08931435f885e707edb85978ea3bb6.woff2 +0 -0
  931. package/src/styles/fonts/noto-serif-kr/400/31a197213ae61d7043c81013f52d10d6.woff2 +0 -0
  932. package/src/styles/fonts/noto-serif-kr/400/37dbd564820cce2f7b3331e442da0df3.woff2 +0 -0
  933. package/src/styles/fonts/noto-serif-kr/400/37dc8505b20b37a2477a9121b16d44a7.woff2 +0 -0
  934. package/src/styles/fonts/noto-serif-kr/400/3ac0a07878cacdc98bb889f40f5970d3.woff2 +0 -0
  935. package/src/styles/fonts/noto-serif-kr/400/491bbba374093fff045f55803a22bfef.woff2 +0 -0
  936. package/src/styles/fonts/noto-serif-kr/400/4d38e56738156625329d93bd5c8cc74a.woff2 +0 -0
  937. package/src/styles/fonts/noto-serif-kr/400/57e9a86651366c1ba299e47aa7e358c2.woff2 +0 -0
  938. package/src/styles/fonts/noto-serif-kr/400/57f89adeae55aa7fe2add3fc1801ce03.woff2 +0 -0
  939. package/src/styles/fonts/noto-serif-kr/400/5df9ce98c75f8c50fb4fff7f01a23925.woff2 +0 -0
  940. package/src/styles/fonts/noto-serif-kr/400/60020a830d809c26970cf8e48ba1eeda.woff2 +0 -0
  941. package/src/styles/fonts/noto-serif-kr/400/60bcfa3ea7446eb42394aab02d28be40.woff2 +0 -0
  942. package/src/styles/fonts/noto-serif-kr/400/63fafcb069520613d0ea35ad3e6b1e42.woff2 +0 -0
  943. package/src/styles/fonts/noto-serif-kr/400/65a60d87c64228d258a123cbe85f5f31.woff2 +0 -0
  944. package/src/styles/fonts/noto-serif-kr/400/6968e889e18891d912809fe484c2e745.woff2 +0 -0
  945. package/src/styles/fonts/noto-serif-kr/400/70714891ad3fbfc3d5f10a8669dacc5a.woff2 +0 -0
  946. package/src/styles/fonts/noto-serif-kr/400/761d84afca8d7f34eebefe538adba827.woff2 +0 -0
  947. package/src/styles/fonts/noto-serif-kr/400/76e07530323418ec723c5d7634c9bcca.woff2 +0 -0
  948. package/src/styles/fonts/noto-serif-kr/400/773819b7b9b8fd404a929867c0fd677e.woff2 +0 -0
  949. package/src/styles/fonts/noto-serif-kr/400/7817dd16805145d8538ad57590f69f5a.woff2 +0 -0
  950. package/src/styles/fonts/noto-serif-kr/400/7b59f0ec7792b18458dc5a361e37884c.woff2 +0 -0
  951. package/src/styles/fonts/noto-serif-kr/400/7c3945788a689a69356c1a622d69d48b.woff2 +0 -0
  952. package/src/styles/fonts/noto-serif-kr/400/835b6505bb9eea9678925a1fa885353d.woff2 +0 -0
  953. package/src/styles/fonts/noto-serif-kr/400/8b5c9ef81159f31d2ab35f45ca4373e0.woff2 +0 -0
  954. package/src/styles/fonts/noto-serif-kr/400/8b91c7c2ed390f1278b9befa3aa87233.woff2 +0 -0
  955. package/src/styles/fonts/noto-serif-kr/400/8fb45117a62d92dce44a80f0b729ead5.woff2 +0 -0
  956. package/src/styles/fonts/noto-serif-kr/400/90b7848e9b1623b77bdcf155e90b839c.woff2 +0 -0
  957. package/src/styles/fonts/noto-serif-kr/400/985d4d41afa0934a4eb2de35473fb9a2.woff2 +0 -0
  958. package/src/styles/fonts/noto-serif-kr/400/9bb38fd05201de666b88b82d56a386f7.woff2 +0 -0
  959. package/src/styles/fonts/noto-serif-kr/400/9eff2ab2a9d2ced47ab761bf6fdb11ec.woff2 +0 -0
  960. package/src/styles/fonts/noto-serif-kr/400/9f1963fe8d4d6878d717d872a8f3fdb5.woff2 +0 -0
  961. package/src/styles/fonts/noto-serif-kr/400/a0d00fe4816c95a8c7dffd445ef00b03.woff2 +0 -0
  962. package/src/styles/fonts/noto-serif-kr/400/a0f199077fa1a33bc2a1e01c64de7fe6.woff2 +0 -0
  963. package/src/styles/fonts/noto-serif-kr/400/a7c35e42a659347e490c3cb7983b2e7f.woff2 +0 -0
  964. package/src/styles/fonts/noto-serif-kr/400/aa662092cf249707123ca4d575e2764b.woff2 +0 -0
  965. package/src/styles/fonts/noto-serif-kr/400/aae1eda193285ab817a2d1b408440326.woff2 +0 -0
  966. package/src/styles/fonts/noto-serif-kr/400/b0cb664cb2e1371efda8943c0b7dcd1c.woff2 +0 -0
  967. package/src/styles/fonts/noto-serif-kr/400/b0d1cdced482352cf0d3ae58638aacb9.woff2 +0 -0
  968. package/src/styles/fonts/noto-serif-kr/400/b320f5d185b2cff933ac549c184031c5.woff2 +0 -0
  969. package/src/styles/fonts/noto-serif-kr/400/ba9c59d7dfa4494db1bb764ada81467d.woff2 +0 -0
  970. package/src/styles/fonts/noto-serif-kr/400/bab547459d514f46206e340c4bb2dc88.woff2 +0 -0
  971. package/src/styles/fonts/noto-serif-kr/400/bcc39eda837bb7a7a3d37c8c60fffb81.woff2 +0 -0
  972. package/src/styles/fonts/noto-serif-kr/400/bd73264d7f98776708d5d6f3c9b78fcc.woff2 +0 -0
  973. package/src/styles/fonts/noto-serif-kr/400/bed610b217d500f5975cfc9fe6157570.woff2 +0 -0
  974. package/src/styles/fonts/noto-serif-kr/400/bf8901f8f11d4f433ea17dabc9370ea6.woff2 +0 -0
  975. package/src/styles/fonts/noto-serif-kr/400/c4143bb9f2fe77b6ccf20088a8904650.woff2 +0 -0
  976. package/src/styles/fonts/noto-serif-kr/400/c7ff3f6bbdcd5f604b7343602ab904df.woff2 +0 -0
  977. package/src/styles/fonts/noto-serif-kr/400/c945c62368357d05a53206620460fb30.woff2 +0 -0
  978. package/src/styles/fonts/noto-serif-kr/400/ce022e18a1377ac509443c3c3790b431.woff2 +0 -0
  979. package/src/styles/fonts/noto-serif-kr/400/cf9cffe56636322f62b40d61130fbc5e.woff2 +0 -0
  980. package/src/styles/fonts/noto-serif-kr/400/d20d8944bc0b85f5b2aae4b24f343516.woff2 +0 -0
  981. package/src/styles/fonts/noto-serif-kr/400/d36644d6502527e1fff205d0c7eca434.woff2 +0 -0
  982. package/src/styles/fonts/noto-serif-kr/400/d40ab99c7a38026f411c8f112f742b48.woff2 +0 -0
  983. package/src/styles/fonts/noto-serif-kr/400/dc6e234ded795e91f76d6647f628fbf0.woff2 +0 -0
  984. package/src/styles/fonts/noto-serif-kr/400/dd0cfdfdac0866e66d587e2b5a9e9961.woff2 +0 -0
  985. package/src/styles/fonts/noto-serif-kr/400/de304c8a02e45ded4f8dcc479d167198.woff2 +0 -0
  986. package/src/styles/fonts/noto-serif-kr/400/e8c364c16daa04835bf32d293d2598db.woff2 +0 -0
  987. package/src/styles/fonts/noto-serif-kr/400/ec86e23683052da5cfdc3b77641bd15a.woff2 +0 -0
  988. package/src/styles/fonts/noto-serif-kr/400/eda1b0cb6d1719dd9bedcf3216a9e8de.woff2 +0 -0
  989. package/src/styles/fonts/noto-serif-kr/400/ee6fce20b420a480714607c66d7f97e5.woff2 +0 -0
  990. package/src/styles/fonts/noto-serif-kr/400/eee3836d6ac17ebb2c450bbcbc9db121.woff2 +0 -0
  991. package/src/styles/fonts/noto-serif-kr/400/f5738255e92d8dd34a46d1bcdf4c4074.woff2 +0 -0
  992. package/src/styles/fonts/noto-serif-kr/400/fa6e58ce4b52695e7ae19bbea6336ec8.woff2 +0 -0
  993. package/src/styles/fonts/noto-serif-kr/400/fd2069e6e8588c70b4f11364093b81f2.woff2 +0 -0
  994. package/src/styles/fonts/noto-serif-kr/700/04b8bde59cff68eeee74fb1914eb09c7.woff2 +0 -0
  995. package/src/styles/fonts/noto-serif-kr/700/05ac821472e235943ed1435e4bb8ecad.woff2 +0 -0
  996. package/src/styles/fonts/noto-serif-kr/700/074c1f8483d5a4d8c45c8c5f3e4cbb32.woff2 +0 -0
  997. package/src/styles/fonts/noto-serif-kr/700/1380210a722ac9aeef54005ad7b015c9.woff2 +0 -0
  998. package/src/styles/fonts/noto-serif-kr/700/17c7f5d0a45e92ede0e5dec3a2c77efa.woff2 +0 -0
  999. package/src/styles/fonts/noto-serif-kr/700/1be602ad456b0d75902d352116cb35fd.woff2 +0 -0
  1000. package/src/styles/fonts/noto-serif-kr/700/2612c60f9dc5459ac42763591240a1d6.woff2 +0 -0
  1001. package/src/styles/fonts/noto-serif-kr/700/2ab8cf1f23a5ac7939a7876054e711a7.woff2 +0 -0
  1002. package/src/styles/fonts/noto-serif-kr/700/34e6750e00c3a911ef87dc66b336594d.woff2 +0 -0
  1003. package/src/styles/fonts/noto-serif-kr/700/36f3df4730cfca4fc77fe52b52e6a126.woff2 +0 -0
  1004. package/src/styles/fonts/noto-serif-kr/700/37887deb7a9c466cf2af6ee7ff372ea6.woff2 +0 -0
  1005. package/src/styles/fonts/noto-serif-kr/700/3aba89c4d4281553078de4622b498cbb.woff2 +0 -0
  1006. package/src/styles/fonts/noto-serif-kr/700/3d88558097559d775231194d43745ba7.woff2 +0 -0
  1007. package/src/styles/fonts/noto-serif-kr/700/3dc3e8c35524cad2d1236f3393104ccf.woff2 +0 -0
  1008. package/src/styles/fonts/noto-serif-kr/700/45140742dfa8686b58db2899ce89f89a.woff2 +0 -0
  1009. package/src/styles/fonts/noto-serif-kr/700/469d2754e315e77270c12fa0ab28026c.woff2 +0 -0
  1010. package/src/styles/fonts/noto-serif-kr/700/4c0760284569b87d8f2290c324953973.woff2 +0 -0
  1011. package/src/styles/fonts/noto-serif-kr/700/4cba92c942694bdc479bc54101bb1aa4.woff2 +0 -0
  1012. package/src/styles/fonts/noto-serif-kr/700/4e7d263c30bb48604069a3b4404d4eeb.woff2 +0 -0
  1013. package/src/styles/fonts/noto-serif-kr/700/5279c7e465d9871edf51fd02e691eee7.woff2 +0 -0
  1014. package/src/styles/fonts/noto-serif-kr/700/54bfdb6f21f9d6191e5100580239e14f.woff2 +0 -0
  1015. package/src/styles/fonts/noto-serif-kr/700/56be5e32fd01668fe5ba814d94905839.woff2 +0 -0
  1016. package/src/styles/fonts/noto-serif-kr/700/615b38e0b5bb3ea68426f44f47706e6f.woff2 +0 -0
  1017. package/src/styles/fonts/noto-serif-kr/700/65e9c4585d71bf48a5c62f367010da16.woff2 +0 -0
  1018. package/src/styles/fonts/noto-serif-kr/700/6b75213eb0be40ce84241eb2bb438a2e.woff2 +0 -0
  1019. package/src/styles/fonts/noto-serif-kr/700/7520ca6ca8c60eb1e62d50e71c8d30f1.woff2 +0 -0
  1020. package/src/styles/fonts/noto-serif-kr/700/759a647b77791b1e98f99bc0ab5317a7.woff2 +0 -0
  1021. package/src/styles/fonts/noto-serif-kr/700/76e51630143b95b6322ef93ad330da7a.woff2 +0 -0
  1022. package/src/styles/fonts/noto-serif-kr/700/79aa7c8c842c4a27cf57c0a3a1ffca5a.woff2 +0 -0
  1023. package/src/styles/fonts/noto-serif-kr/700/7cc72fd2c9105560422b6a67c6162945.woff2 +0 -0
  1024. package/src/styles/fonts/noto-serif-kr/700/7d0ea0690e432462f4d05a23d720ec19.woff2 +0 -0
  1025. package/src/styles/fonts/noto-serif-kr/700/7dffa5c1bec57e0903fd62357401ff1a.woff2 +0 -0
  1026. package/src/styles/fonts/noto-serif-kr/700/82f6ccc063960eed1cdfd1d61ada8862.woff2 +0 -0
  1027. package/src/styles/fonts/noto-serif-kr/700/845b4b67564d62cf5cad242f7ac08ea5.woff2 +0 -0
  1028. package/src/styles/fonts/noto-serif-kr/700/84c8e7bc0931008ed91f44ed12dfea94.woff2 +0 -0
  1029. package/src/styles/fonts/noto-serif-kr/700/887a11290ba78b1e66c6d2f67043005e.woff2 +0 -0
  1030. package/src/styles/fonts/noto-serif-kr/700/88db1d042074fb6e66821ffc10941930.woff2 +0 -0
  1031. package/src/styles/fonts/noto-serif-kr/700/8dc18c0cebe6aa4bf4c45dbb831048ab.woff2 +0 -0
  1032. package/src/styles/fonts/noto-serif-kr/700/919a879bd2d580d8491a31a449390689.woff2 +0 -0
  1033. package/src/styles/fonts/noto-serif-kr/700/91da6cb174bebfb96976e2f1316be2fe.woff2 +0 -0
  1034. package/src/styles/fonts/noto-serif-kr/700/934dfdbed2bb2c4b6129199d699a34fa.woff2 +0 -0
  1035. package/src/styles/fonts/noto-serif-kr/700/97d7a17234f2b5030ae9697ae00aded2.woff2 +0 -0
  1036. package/src/styles/fonts/noto-serif-kr/700/995c4fda62d25c3b79dd5987737df6ae.woff2 +0 -0
  1037. package/src/styles/fonts/noto-serif-kr/700/9d0afa53dc2f92ba42024f55f11f6779.woff2 +0 -0
  1038. package/src/styles/fonts/noto-serif-kr/700/9e13a47242926f1cd7d68c08d9ef8889.woff2 +0 -0
  1039. package/src/styles/fonts/noto-serif-kr/700/a379ada89abd750c587ded29f77e731c.woff2 +0 -0
  1040. package/src/styles/fonts/noto-serif-kr/700/a48be56ce5d3a99dc8f8331398004412.woff2 +0 -0
  1041. package/src/styles/fonts/noto-serif-kr/700/a806759e72987951d6d08b7cbdf36a1b.woff2 +0 -0
  1042. package/src/styles/fonts/noto-serif-kr/700/a88481ec8bc7be11cb66e46781a79bb9.woff2 +0 -0
  1043. package/src/styles/fonts/noto-serif-kr/700/a9a016d4a93409f65278327e8a8bb38d.woff2 +0 -0
  1044. package/src/styles/fonts/noto-serif-kr/700/ab92d41062a7644faa45f50bf384454a.woff2 +0 -0
  1045. package/src/styles/fonts/noto-serif-kr/700/b326a8a9c33b554db570da94f60bc380.woff2 +0 -0
  1046. package/src/styles/fonts/noto-serif-kr/700/b6117ff2993b11bb1fdc7ea3588a010c.woff2 +0 -0
  1047. package/src/styles/fonts/noto-serif-kr/700/b61982951bd51b724143c30dfaaa9fe9.woff2 +0 -0
  1048. package/src/styles/fonts/noto-serif-kr/700/c0098958e20db68cab90097b5e62516f.woff2 +0 -0
  1049. package/src/styles/fonts/noto-serif-kr/700/c4bfaa5e50798246e3770718b7a7c84a.woff2 +0 -0
  1050. package/src/styles/fonts/noto-serif-kr/700/c84598999133455503042e06f4ab79cb.woff2 +0 -0
  1051. package/src/styles/fonts/noto-serif-kr/700/ca9a533988d7019597a60d4e17127e0c.woff2 +0 -0
  1052. package/src/styles/fonts/noto-serif-kr/700/cf2b28f90f47276f7e2688a65e88a101.woff2 +0 -0
  1053. package/src/styles/fonts/noto-serif-kr/700/d689b1861d7e4377dd72ad3013482612.woff2 +0 -0
  1054. package/src/styles/fonts/noto-serif-kr/700/d9047070d72a816b3dba9d40c2d85e69.woff2 +0 -0
  1055. package/src/styles/fonts/noto-serif-kr/700/da04549f3f4ed28076b01b8cd710d313.woff2 +0 -0
  1056. package/src/styles/fonts/noto-serif-kr/700/da7af303f8c645f9a9dbae0e6e32dd35.woff2 +0 -0
  1057. package/src/styles/fonts/noto-serif-kr/700/df9568257eb29b156449fdd4bec5ec76.woff2 +0 -0
  1058. package/src/styles/fonts/noto-serif-kr/700/e067cd0ed76c90cd0a93c9339253f20b.woff2 +0 -0
  1059. package/src/styles/fonts/noto-serif-kr/700/e08b07772e7bed3cec2832d43f7fd339.woff2 +0 -0
  1060. package/src/styles/fonts/noto-serif-kr/700/e12150d5a39b30be8f567968c7a527b0.woff2 +0 -0
  1061. package/src/styles/fonts/noto-serif-kr/700/e53fcb2381eee345db4f6f973dd95a3e.woff2 +0 -0
  1062. package/src/styles/fonts/noto-serif-kr/700/e5bd313ef81f687d398aacb11cec3069.woff2 +0 -0
  1063. package/src/styles/fonts/noto-serif-kr/700/eb5afb3d952b8593782caec6026514b6.woff2 +0 -0
  1064. package/src/styles/fonts/noto-serif-kr/700/edd6a4f608d04fc0351d7688cfc321e4.woff2 +0 -0
  1065. package/src/styles/fonts/noto-serif-kr/700/f9695c6c4df2bf6bc03045ff79d4f01f.woff2 +0 -0
  1066. package/src/styles/fonts/noto-serif-kr/700/fada6eaa68ff8816afe43d2a36c5423e.woff2 +0 -0
  1067. package/src/styles/fonts/noto-serif-kr/700/fbcc4bf5367218951172bdee6f77d7a6.woff2 +0 -0
  1068. package/src/styles/fonts/noto-serif-kr/noto-serif-kr.css +2601 -0
  1069. package/src/styles/site-media.css +823 -0
  1070. package/src/styles/tokens.css +292 -21
  1071. package/src/styles/ui.css +4217 -1869
  1072. package/src/types/bindings.ts +3 -1
  1073. package/src/types/config.ts +139 -9
  1074. package/src/types/constants.ts +46 -11
  1075. package/src/types/entities.ts +24 -8
  1076. package/src/types/operations.ts +80 -1
  1077. package/src/types/props.ts +12 -3
  1078. package/src/types/raw-assets.d.ts +39 -0
  1079. package/src/types/views.ts +28 -7
  1080. package/src/ui/__tests__/color-themes.test.ts +7 -40
  1081. package/src/ui/__tests__/font-themes.test.ts +30 -11
  1082. package/src/ui/color-themes.ts +311 -270
  1083. package/src/ui/compose/ComposeDialog.tsx +712 -394
  1084. package/src/ui/compose/ComposePrompt.tsx +15 -10
  1085. package/src/ui/dash/ActionButtons.tsx +27 -18
  1086. package/src/ui/dash/DangerZone.tsx +15 -10
  1087. package/src/ui/dash/FormatBadge.tsx +21 -8
  1088. package/src/ui/dash/StatusBadge.tsx +33 -22
  1089. package/src/ui/dash/appearance/AdvancedContent.tsx +44 -30
  1090. package/src/ui/dash/appearance/CodeInjectionContent.tsx +164 -0
  1091. package/src/ui/dash/appearance/ColorThemeContent.tsx +127 -160
  1092. package/src/ui/dash/appearance/FontThemeContent.tsx +20 -15
  1093. package/src/ui/dash/appearance/NavigationContent.tsx +368 -225
  1094. package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +54 -0
  1095. package/src/ui/dash/settings/AccountContent.tsx +34 -23
  1096. package/src/ui/dash/settings/AccountMenuContent.tsx +226 -137
  1097. package/src/ui/dash/settings/ApiTokensContent.tsx +122 -79
  1098. package/src/ui/dash/settings/AvatarContent.tsx +73 -45
  1099. package/src/ui/dash/settings/DeleteAccountContent.tsx +106 -66
  1100. package/src/ui/dash/settings/GeneralContent.tsx +274 -157
  1101. package/src/ui/dash/settings/GitHubSyncContent.tsx +558 -0
  1102. package/src/ui/dash/settings/SessionsContent.tsx +79 -38
  1103. package/src/ui/dash/settings/SettingsRootContent.tsx +209 -109
  1104. package/src/ui/dash/settings/__tests__/AccountMenuContent.test.tsx +67 -0
  1105. package/src/ui/dash/settings/__tests__/GeneralContent.test.tsx +75 -0
  1106. package/src/ui/feed/CuratedThreadPreview.tsx +24 -14
  1107. package/src/ui/feed/LinkCard.tsx +116 -84
  1108. package/src/ui/feed/LinkPreview.tsx +75 -0
  1109. package/src/ui/feed/NoteCard.tsx +60 -16
  1110. package/src/ui/feed/PostStatusBadges.tsx +15 -0
  1111. package/src/ui/feed/QuoteCard.tsx +10 -3
  1112. package/src/ui/feed/ThreadPreview.tsx +62 -36
  1113. package/src/ui/feed/TimelineFeed.tsx +2 -1
  1114. package/src/ui/feed/__tests__/thread-preview.test.ts +220 -11
  1115. package/src/ui/feed/__tests__/timeline-cards.test.ts +186 -5
  1116. package/src/ui/feed/thread-preview-state.ts +23 -10
  1117. package/src/ui/font-themes.ts +57 -97
  1118. package/src/ui/layouts/BaseLayout.tsx +221 -136
  1119. package/src/ui/layouts/SiteLayout.tsx +431 -143
  1120. package/src/ui/layouts/__tests__/BaseLayout.test.tsx +76 -6
  1121. package/src/ui/layouts/__tests__/SiteLayout.test.tsx +76 -0
  1122. package/src/ui/pages/ArchivePage.tsx +320 -207
  1123. package/src/ui/pages/BrandPage.tsx +499 -341
  1124. package/src/ui/pages/CollectionEditorPage.tsx +50 -30
  1125. package/src/ui/pages/CollectionPage.tsx +201 -61
  1126. package/src/ui/pages/CollectionsPage.tsx +27 -18
  1127. package/src/ui/pages/ComposePage.tsx +15 -10
  1128. package/src/ui/pages/FeaturedPage.tsx +16 -11
  1129. package/src/ui/pages/HomePage.tsx +15 -10
  1130. package/src/ui/pages/PostPage.tsx +5 -1
  1131. package/src/ui/pages/SearchPage.tsx +93 -43
  1132. package/src/ui/pages/ThemeSamplePage.tsx +758 -520
  1133. package/src/ui/pages/__tests__/ArchivePage.test.tsx +72 -0
  1134. package/src/ui/shared/CollectionDirectory.tsx +232 -37
  1135. package/src/ui/shared/CollectionsManager.tsx +155 -75
  1136. package/src/ui/shared/DecorativeQuoteMark.tsx +12 -9
  1137. package/src/ui/shared/MediaGallery.tsx +350 -256
  1138. package/src/ui/shared/Pagination.tsx +36 -25
  1139. package/src/ui/shared/PostFooter.tsx +139 -96
  1140. package/src/ui/shared/__tests__/media-gallery.test.ts +27 -0
  1141. package/src/ui/shared/__tests__/navigation-labels.test.ts +79 -28
  1142. package/src/ui/shared/__tests__/post-footer.test.ts +42 -17
  1143. package/src/ui/shared/collection-management-labels.ts +109 -33
  1144. package/src/ui/shared/navigation-labels.ts +78 -8
  1145. package/bin/lib/site-localize-media.js +0 -427
  1146. package/dist/client/_assets/client-auth.js +0 -3251
  1147. package/dist/client/_assets/client.css +0 -2
  1148. package/dist/client/_assets/client.js +0 -380
  1149. package/src/__tests__/site-localize-media.test.ts +0 -150
  1150. package/src/client/components/jant-collection-sidebar.ts +0 -803
  1151. package/src/i18n/locales/en.ts +0 -1
  1152. package/src/i18n/locales/zh-Hans.po +0 -3183
  1153. package/src/i18n/locales/zh-Hans.ts +0 -1
  1154. package/src/i18n/locales/zh-Hant.po +0 -3183
  1155. package/src/i18n/locales/zh-Hant.ts +0 -1
  1156. package/src/routes/feed/rss.ts +0 -216
  1157. package/src/types/lingui-react-macro.d.ts +0 -34
  1158. /package/dist/client/_assets/chunks/{heic-to-XcUDQvtx.js → heic-to-DUUaO23q.js} +0 -0
  1159. /package/dist/client/_assets/chunks/{module-ChVQstFd.js → module-DcsAZQZ_.js} +0 -0
  1160. /package/dist/client/_assets/chunks/{native-CR5HLOyf.js → native-DpcrFAPh.js} +0 -0
  1161. /package/dist/client/_assets/{client-cjk.css → client-cjk-B7Z0snDu.css} +0 -0
  1162. /package/dist/client/_assets/{client-cjk-tc.css → client-cjk-tc-BesJYrb2.css} +0 -0
@@ -2,7 +2,8 @@
2
2
  * Collection Service (v2)
3
3
  *
4
4
  * Manages collections. Posts belong to collections via post_collections junction table (M:N).
5
- * Sidebar ordering is managed through the collection_directory_item table with fractional indexing.
5
+ * Collection directory ordering is managed through the collection_directory_item
6
+ * table with fractional indexing.
6
7
  */
7
8
 
8
9
  import { eq, asc, sql, and, inArray, desc } from "drizzle-orm";
@@ -22,22 +23,28 @@ import { now } from "../lib/time.js";
22
23
  import type {
23
24
  Collection,
24
25
  CollectionDirectoryCollection,
26
+ CollectionDirectoryEntry,
27
+ CollectionDirectoryEntryType,
25
28
  CollectionDirectoryItem,
26
29
  CollectionsDirectoryData,
27
- SidebarItem,
28
- SidebarItemType,
29
30
  CreateCollection,
31
+ CreateCollectionDirectoryEntry,
30
32
  UpdateCollection,
31
- UpdateSidebarItem,
33
+ UpdateCollectionDirectoryEntry,
32
34
  CollectionSortOrder,
33
35
  } from "../types.js";
34
- import { ConflictError } from "../lib/errors.js";
36
+ import { ConflictError, ValidationError } from "../lib/errors.js";
35
37
  import {
36
38
  createPathService,
37
39
  toCollectionPath,
38
40
  type PathService,
39
41
  } from "./path.js";
42
+ import { getCollectionPagePath } from "../lib/collection-paths.js";
40
43
  import {
44
+ CreateCollectionDirectoryItemSchema,
45
+ CollectionDirectoryLabelSchema,
46
+ CollectionDirectoryLinkLabelSchema,
47
+ CollectionDirectoryLinkUrlSchema,
41
48
  CollectionDescriptionValueSchema,
42
49
  CollectionSlugSchema,
43
50
  CollectionTitleSchema,
@@ -46,27 +53,42 @@ import {
46
53
 
47
54
  const POSITION_RETRY_ATTEMPTS = 5;
48
55
 
49
- function isUniqueConstraintError(err: unknown): boolean {
50
- let current: unknown = err;
51
- while (current) {
52
- const msg = String(current);
53
- if (
54
- msg.includes("UNIQUE constraint") ||
55
- msg.includes("SQLITE_CONSTRAINT")
56
- ) {
57
- return true;
58
- }
59
- current =
60
- current instanceof Error && current.cause !== current
61
- ? current.cause
62
- : undefined;
56
+ // Re-export shared constraint detection — see db/dialect.ts
57
+ import { isUniqueConstraintError } from "../db/dialect.js";
58
+
59
+ export interface ResolvedCollectionSelection {
60
+ collections: Collection[];
61
+ slugs: string[];
62
+ slugExpression: string;
63
+ }
64
+
65
+ function parseCollectionSelectionSlugs(
66
+ slugExpression: string,
67
+ ): string[] | null {
68
+ const parts = slugExpression.split("+");
69
+ if (parts.length === 0) return null;
70
+
71
+ const seen = new Set<string>();
72
+ const slugs: string[] = [];
73
+
74
+ for (const part of parts) {
75
+ const slug = part.trim();
76
+ if (!slug) return null;
77
+ if (seen.has(slug)) continue;
78
+ seen.add(slug);
79
+ slugs.push(slug);
63
80
  }
64
- return false;
81
+
82
+ return slugs.length > 0 ? slugs : null;
65
83
  }
66
84
 
67
85
  export interface CollectionService {
68
86
  getById(id: string): Promise<Collection | null>;
69
87
  getBySlug(slug: string): Promise<Collection | null>;
88
+ getBySlugs(slugs: string[]): Promise<Collection[]>;
89
+ resolveSelection(
90
+ slugExpression: string,
91
+ ): Promise<ResolvedCollectionSelection | null>;
70
92
  list(): Promise<Collection[]>;
71
93
  listDirectoryData(): Promise<CollectionsDirectoryData>;
72
94
  /** List collections sorted by most recent post addition (for compose dialog) */
@@ -74,39 +96,99 @@ export interface CollectionService {
74
96
  create(data: CreateCollection): Promise<Collection>;
75
97
  update(id: string, data: UpdateCollection): Promise<Collection | null>;
76
98
  delete(id: string): Promise<boolean>;
77
- /** List all sidebar items ordered by position */
78
- listSidebarItems(): Promise<SidebarItem[]>;
79
- /** Create a sidebar item (collection or divider) */
80
- createSidebarItem(
81
- type: SidebarItemType,
82
- collectionId?: string,
83
- label?: string | null,
84
- ): Promise<SidebarItem>;
85
- /** Delete a sidebar item by ID */
86
- deleteSidebarItem(id: string): Promise<boolean>;
87
- /** Update a sidebar item */
88
- updateSidebarItem(
99
+ /** List all collection directory items ordered by position */
100
+ listDirectoryItems(): Promise<CollectionDirectoryEntry[]>;
101
+ /** Create a collection directory item (collection, divider, or link) */
102
+ createDirectoryItem(
103
+ data: CreateCollectionDirectoryEntry,
104
+ ): Promise<CollectionDirectoryEntry>;
105
+ /** Delete a collection directory item by ID */
106
+ deleteDirectoryItem(id: string): Promise<boolean>;
107
+ /** Update a collection directory item */
108
+ updateDirectoryItem(
89
109
  id: string,
90
- data: UpdateSidebarItem,
91
- ): Promise<SidebarItem | null>;
92
- /** Move a sidebar item between two neighbors */
93
- moveSidebarItem(
110
+ data: UpdateCollectionDirectoryEntry,
111
+ ): Promise<CollectionDirectoryEntry | null>;
112
+ /** Move a collection directory item between two neighbors */
113
+ moveDirectoryItem(
94
114
  id: string,
95
115
  after: string | null,
96
116
  before: string | null,
97
- ): Promise<SidebarItem | null>;
117
+ ): Promise<CollectionDirectoryEntry | null>;
98
118
  /** Get post count per collection */
99
119
  getPostCounts(): Promise<Map<string, number>>;
100
- /** Add a post to a collection */
101
- addPost(collectionId: string, postId: string): Promise<void>;
120
+ /**
121
+ * Add a post to a collection. Optional metadata lets the caller set the
122
+ * per-row `createdAt` / `position` / `pinnedAt` explicitly; omitted
123
+ * fields default to `now()` / append-at-end / `null`.
124
+ */
125
+ addPost(
126
+ collectionId: string,
127
+ postId: string,
128
+ opts?: {
129
+ createdAt?: number;
130
+ position?: number;
131
+ pinnedAt?: number | null;
132
+ },
133
+ ): Promise<void>;
134
+ /**
135
+ * Replace all collection memberships of a post in one transaction,
136
+ * preserving each entry's `createdAt` / `position` / `pinnedAt`.
137
+ * Used by the Hugo import path so round-tripping through
138
+ * `jant site export | jant site import` is lossless.
139
+ */
140
+ syncPostCollectionsWithMeta(
141
+ postId: string,
142
+ entries: {
143
+ collectionId: string;
144
+ createdAt?: number;
145
+ position?: number;
146
+ pinnedAt?: number | null;
147
+ }[],
148
+ ): Promise<void>;
102
149
  /** Remove a post from a collection */
103
150
  removePost(collectionId: string, postId: string): Promise<void>;
151
+ /** Pin a post within a collection */
152
+ pinPost(collectionId: string, postId: string): Promise<void>;
153
+ /** Unpin a post within a collection */
154
+ unpinPost(collectionId: string, postId: string): Promise<void>;
155
+ /** Get pinned post IDs for given collections */
156
+ getPinnedPostIds(collectionIds: string[]): Promise<Set<string>>;
104
157
  /** Get all collections a post belongs to */
105
158
  getCollectionsByPostId(postId: string): Promise<Collection[]>;
106
159
  /** Batch get collections for multiple posts */
107
160
  getCollectionsByPostIds(
108
161
  postIds: string[],
109
162
  ): Promise<Map<string, Collection[]>>;
163
+ /**
164
+ * Batch get the set of collection IDs each post is pinned in.
165
+ *
166
+ * Used by the Hugo export to surface per-collection pins so the static
167
+ * collection page can sort pinned posts to the top, mirroring the live
168
+ * site behavior.
169
+ */
170
+ getCollectionPinsByPostIds(
171
+ postIds: string[],
172
+ ): Promise<Map<string, Set<string>>>;
173
+ /**
174
+ * Batch fetch the full per-entry collection metadata for each post: the
175
+ * `createdAt` timestamp, `position`, and per-collection `pinnedAt`.
176
+ *
177
+ * Used by the Hugo export to emit lossless `collections` front-matter
178
+ * entries so round-tripping through `jant site export | jant site import`
179
+ * preserves per-entry state.
180
+ */
181
+ getCollectionEntriesByPostIds(postIds: string[]): Promise<
182
+ Map<
183
+ string,
184
+ {
185
+ collectionId: string;
186
+ createdAt: number;
187
+ position: number;
188
+ pinnedAt: number | null;
189
+ }[]
190
+ >
191
+ >;
110
192
  /** Get all post IDs in a collection */
111
193
  getPostIds(collectionId: string): Promise<string[]>;
112
194
  /** Sync a post's collection memberships (replace all with given IDs) */
@@ -124,9 +206,10 @@ export function createCollectionService(
124
206
  const {
125
207
  collections,
126
208
  pathRegistry,
127
- collectionDirectoryItems: sidebarItems,
209
+ collectionDirectoryItems: directoryItemsTable,
128
210
  postCollections,
129
211
  posts,
212
+ navItems,
130
213
  } = databaseSchema;
131
214
  const usesBatchWrites = !supportsDrizzleTransaction(db, databaseDialect);
132
215
 
@@ -184,45 +267,100 @@ export function createCollectionService(
184
267
  };
185
268
  }
186
269
 
187
- function toSidebarItem(row: typeof sidebarItems.$inferSelect): SidebarItem {
270
+ function toDirectoryItem(
271
+ row: typeof directoryItemsTable.$inferSelect,
272
+ ): CollectionDirectoryEntry {
188
273
  return {
189
274
  id: row.id,
190
275
  siteId: row.siteId,
191
- type: row.type as SidebarItemType,
276
+ type: row.type as CollectionDirectoryEntryType,
192
277
  collectionId: row.collectionId,
193
278
  label: row.label,
279
+ url: row.url,
280
+ description: row.description,
194
281
  position: row.position,
195
282
  createdAt: row.createdAt,
196
283
  updatedAt: row.updatedAt,
197
284
  };
198
285
  }
199
286
 
200
- function normalizeSidebarLabel(label?: string | null): string | null {
201
- const trimmed = label?.trim();
287
+ function normalizeDirectoryLabel(label?: string | null): string | null {
288
+ if (label === null) return null;
289
+ if (label === undefined) return null;
290
+
291
+ const trimmed = parseValidated(CollectionDirectoryLabelSchema, label);
202
292
  return trimmed ? trimmed : null;
203
293
  }
204
294
 
205
- async function getLastSidebarPosition(): Promise<string | null> {
295
+ function normalizeDirectoryLinkLabel(label: string): string {
296
+ return parseValidated(CollectionDirectoryLinkLabelSchema, label);
297
+ }
298
+
299
+ function normalizeDirectoryUrl(url: string): string {
300
+ return parseValidated(CollectionDirectoryLinkUrlSchema, url);
301
+ }
302
+
303
+ function normalizeDirectoryDescription(
304
+ description?: string | null,
305
+ ): string | null {
306
+ if (description === null || description === undefined) return null;
307
+ const trimmed = parseValidated(
308
+ CollectionDescriptionValueSchema,
309
+ description,
310
+ );
311
+ return trimmed || null;
312
+ }
313
+
314
+ function normalizeCreateDirectoryItemInput(
315
+ data: CreateCollectionDirectoryEntry,
316
+ ): CreateCollectionDirectoryEntry {
317
+ if (data.type === "collection") {
318
+ return data;
319
+ }
320
+
321
+ const normalized = parseValidated(
322
+ CreateCollectionDirectoryItemSchema,
323
+ data,
324
+ );
325
+ if (normalized.type === "divider") {
326
+ return {
327
+ type: "divider",
328
+ label: normalizeDirectoryLabel(normalized.label),
329
+ };
330
+ }
331
+
332
+ return {
333
+ type: "link",
334
+ label: normalizeDirectoryLinkLabel(normalized.label),
335
+ url: normalizeDirectoryUrl(normalized.url),
336
+ description: normalizeDirectoryDescription(normalized.description),
337
+ };
338
+ }
339
+
340
+ async function getLastDirectoryPosition(): Promise<string | null> {
206
341
  const rows = await db
207
- .select({ position: sidebarItems.position })
208
- .from(sidebarItems)
209
- .where(eq(sidebarItems.siteId, siteId))
210
- .orderBy(sql`${sidebarItems.position} DESC`)
342
+ .select({ position: directoryItemsTable.position })
343
+ .from(directoryItemsTable)
344
+ .where(eq(directoryItemsTable.siteId, siteId))
345
+ .orderBy(sql`${directoryItemsTable.position} DESC`)
211
346
  .limit(1);
212
347
  return rows[0]?.position ?? null;
213
348
  }
214
349
 
215
- async function listOrderedSidebarPositions(excludeId?: string) {
350
+ async function listOrderedDirectoryPositions(excludeId?: string) {
216
351
  const rows = await db
217
- .select({ id: sidebarItems.id, position: sidebarItems.position })
218
- .from(sidebarItems)
219
- .where(eq(sidebarItems.siteId, siteId))
220
- .orderBy(asc(sidebarItems.position));
352
+ .select({
353
+ id: directoryItemsTable.id,
354
+ position: directoryItemsTable.position,
355
+ })
356
+ .from(directoryItemsTable)
357
+ .where(eq(directoryItemsTable.siteId, siteId))
358
+ .orderBy(asc(directoryItemsTable.position));
221
359
  return excludeId ? rows.filter((row) => row.id !== excludeId) : rows;
222
360
  }
223
361
 
224
- async function getAppendSidebarPosition(): Promise<string> {
225
- const lastPos = await getLastSidebarPosition();
362
+ async function getAppendDirectoryPosition(): Promise<string> {
363
+ const lastPos = await getLastDirectoryPosition();
226
364
  return generateKeyBetween(lastPos, null);
227
365
  }
228
366
 
@@ -235,12 +373,12 @@ export function createCollectionService(
235
373
  return rows.length > 0;
236
374
  }
237
375
 
238
- async function getSidebarMovePosition(
376
+ async function getDirectoryMovePosition(
239
377
  id: string,
240
378
  afterId: string | null,
241
379
  beforeId: string | null,
242
380
  ): Promise<string> {
243
- const rows = await listOrderedSidebarPositions(id);
381
+ const rows = await listOrderedDirectoryPositions(id);
244
382
  const afterIndex = afterId
245
383
  ? rows.findIndex((row) => row.id === afterId)
246
384
  : -1;
@@ -288,29 +426,15 @@ export function createCollectionService(
288
426
  .filter((row): row is Collection => row !== null);
289
427
  }
290
428
 
291
- async function getPostCollectionIds(postId: string): Promise<string[]> {
292
- const rows = await db
293
- .select({ collectionId: postCollections.collectionId })
294
- .from(postCollections)
295
- .where(
296
- and(
297
- eq(postCollections.siteId, siteId),
298
- eq(postCollections.postId, postId),
299
- ),
300
- );
301
-
302
- return rows.map((row) => row.collectionId);
303
- }
304
-
305
429
  async function listDirectoryCollections(): Promise<
306
430
  CollectionDirectoryCollection[]
307
431
  > {
308
432
  const postCount = sql<number>`
309
- COUNT(
433
+ CAST(COUNT(
310
434
  CASE
311
435
  WHEN ${posts.id} IS NOT NULL AND ${posts.deletedAt} IS NULL THEN 1
312
436
  END
313
- )
437
+ ) AS INTEGER)
314
438
  `.as("post_count");
315
439
  const recentActivityAt = sql<number | null>`
316
440
  MAX(
@@ -369,7 +493,7 @@ export function createCollectionService(
369
493
 
370
494
  function buildDirectoryItems(
371
495
  directoryCollections: CollectionDirectoryCollection[],
372
- orderedSidebarItems: SidebarItem[],
496
+ orderedDirectoryItems: CollectionDirectoryEntry[],
373
497
  ): CollectionDirectoryItem[] {
374
498
  const collectionMap = new Map(
375
499
  directoryCollections.map((collection) => [collection.id, collection]),
@@ -377,7 +501,7 @@ export function createCollectionService(
377
501
  const seenCollections = new Set<string>();
378
502
  const items: CollectionDirectoryItem[] = [];
379
503
 
380
- for (const item of orderedSidebarItems) {
504
+ for (const item of orderedDirectoryItems) {
381
505
  if (item.type === "divider") {
382
506
  items.push({
383
507
  id: item.id,
@@ -387,6 +511,18 @@ export function createCollectionService(
387
511
  continue;
388
512
  }
389
513
 
514
+ if (item.type === "link") {
515
+ if (!item.label || !item.url) continue;
516
+ items.push({
517
+ id: item.id,
518
+ type: "link",
519
+ label: item.label,
520
+ url: item.url,
521
+ description: item.description,
522
+ });
523
+ continue;
524
+ }
525
+
390
526
  const collection = item.collectionId
391
527
  ? collectionMap.get(item.collectionId)
392
528
  : undefined;
@@ -430,6 +566,31 @@ export function createCollectionService(
430
566
  return this.getById(resolved.collectionId);
431
567
  },
432
568
 
569
+ async getBySlugs(slugs) {
570
+ if (slugs.length === 0) return [];
571
+
572
+ const collections = await Promise.all(
573
+ slugs.map((slug) => this.getBySlug(slug)),
574
+ );
575
+ return collections.filter(
576
+ (collection): collection is Collection => collection !== null,
577
+ );
578
+ },
579
+
580
+ async resolveSelection(slugExpression) {
581
+ const slugs = parseCollectionSelectionSlugs(slugExpression);
582
+ if (!slugs) return null;
583
+
584
+ const collections = await this.getBySlugs(slugs);
585
+ if (collections.length !== slugs.length) return null;
586
+
587
+ return {
588
+ collections,
589
+ slugs,
590
+ slugExpression: slugs.join("+"),
591
+ };
592
+ },
593
+
433
594
  async list() {
434
595
  const rows = await db
435
596
  .select()
@@ -440,15 +601,15 @@ export function createCollectionService(
440
601
  },
441
602
 
442
603
  async listDirectoryData() {
443
- const [directoryCollections, orderedSidebarItems] = await Promise.all([
604
+ const [directoryCollections, orderedDirectoryItems] = await Promise.all([
444
605
  listDirectoryCollections(),
445
- this.listSidebarItems(),
606
+ this.listDirectoryItems(),
446
607
  ]);
447
608
 
448
609
  return {
449
610
  collections: directoryCollections,
450
- items: buildDirectoryItems(directoryCollections, orderedSidebarItems),
451
- sidebarItems: orderedSidebarItems,
611
+ items: buildDirectoryItems(directoryCollections, orderedDirectoryItems),
612
+ directoryItems: orderedDirectoryItems,
452
613
  };
453
614
  },
454
615
 
@@ -468,7 +629,10 @@ export function createCollectionService(
468
629
  )
469
630
  .where(eq(collections.siteId, siteId))
470
631
  .groupBy(collections.id)
471
- .orderBy(desc(sql`last_added_at`), desc(collections.createdAt));
632
+ .orderBy(
633
+ desc(sql`COALESCE(MAX(${postCollections.createdAt}), 0)`),
634
+ desc(collections.createdAt),
635
+ );
472
636
  return hydrateCollections(rows.map((row) => row.collection));
473
637
  },
474
638
 
@@ -480,7 +644,7 @@ export function createCollectionService(
480
644
 
481
645
  for (let attempt = 0; attempt < POSITION_RETRY_ATTEMPTS; attempt += 1) {
482
646
  try {
483
- const position = await getAppendSidebarPosition();
647
+ const position = await getAppendDirectoryPosition();
484
648
  if (usesBatchWrites) {
485
649
  const writeQueries = [
486
650
  db.insert(collections).values({
@@ -504,11 +668,13 @@ export function createCollectionService(
504
668
  createdAt: timestamp,
505
669
  updatedAt: timestamp,
506
670
  }),
507
- db.insert(sidebarItems).values({
671
+ db.insert(directoryItemsTable).values({
508
672
  id: createEntityId("collectionDirectoryItem"),
509
673
  siteId,
510
674
  type: "collection",
511
675
  collectionId: id,
676
+ label: null,
677
+ url: null,
512
678
  position,
513
679
  createdAt: timestamp,
514
680
  updatedAt: timestamp,
@@ -546,11 +712,13 @@ export function createCollectionService(
546
712
  updatedAt: timestamp,
547
713
  });
548
714
 
549
- await tx.insert(sidebarItems).values({
715
+ await tx.insert(directoryItemsTable).values({
550
716
  id: createEntityId("collectionDirectoryItem"),
551
717
  siteId,
552
718
  type: "collection",
553
719
  collectionId: id,
720
+ label: null,
721
+ url: null,
554
722
  position,
555
723
  createdAt: timestamp,
556
724
  updatedAt: timestamp,
@@ -580,7 +748,7 @@ export function createCollectionService(
580
748
  }
581
749
  }
582
750
 
583
- throw new Error("Failed to assign a unique sidebar item position");
751
+ throw new Error("Failed to assign a unique directory item position");
584
752
  },
585
753
 
586
754
  async update(id, data) {
@@ -605,6 +773,22 @@ export function createCollectionService(
605
773
  }
606
774
 
607
775
  const timestamp = now();
776
+
777
+ // Update nav item URLs when the collection slug changes
778
+ if (
779
+ normalizedData.slug !== undefined &&
780
+ normalizedData.slug !== existing.slug
781
+ ) {
782
+ await db
783
+ .update(navItems)
784
+ .set({
785
+ url: getCollectionPagePath(normalizedData.slug),
786
+ updatedAt: timestamp,
787
+ })
788
+ .where(
789
+ and(eq(navItems.siteId, siteId), eq(navItems.collectionId, id)),
790
+ );
791
+ }
608
792
  const updates: Partial<typeof collections.$inferInsert> = {
609
793
  updatedAt: timestamp,
610
794
  };
@@ -638,13 +822,16 @@ export function createCollectionService(
638
822
  ),
639
823
  );
640
824
  await db
641
- .delete(sidebarItems)
825
+ .delete(directoryItemsTable)
642
826
  .where(
643
827
  and(
644
- eq(sidebarItems.siteId, siteId),
645
- eq(sidebarItems.collectionId, id),
828
+ eq(directoryItemsTable.siteId, siteId),
829
+ eq(directoryItemsTable.collectionId, id),
646
830
  ),
647
831
  );
832
+ await db
833
+ .delete(navItems)
834
+ .where(and(eq(navItems.siteId, siteId), eq(navItems.collectionId, id)));
648
835
  const result = await db
649
836
  .delete(collections)
650
837
  .where(and(eq(collections.siteId, siteId), eq(collections.id, id)))
@@ -652,57 +839,73 @@ export function createCollectionService(
652
839
  return result.length > 0;
653
840
  },
654
841
 
655
- async listSidebarItems() {
842
+ async listDirectoryItems() {
656
843
  const rows = await db
657
844
  .select()
658
- .from(sidebarItems)
659
- .where(eq(sidebarItems.siteId, siteId))
660
- .orderBy(asc(sidebarItems.position));
661
- return rows.map(toSidebarItem);
845
+ .from(directoryItemsTable)
846
+ .where(eq(directoryItemsTable.siteId, siteId))
847
+ .orderBy(asc(directoryItemsTable.position));
848
+ return rows.map(toDirectoryItem);
662
849
  },
663
850
 
664
- async createSidebarItem(type, collectionId, label) {
851
+ async createDirectoryItem(data) {
852
+ const normalizedData = normalizeCreateDirectoryItemInput(data);
665
853
  const id = createEntityId("collectionDirectoryItem");
666
854
  const timestamp = now();
667
- const normalizedLabel =
668
- type === "divider" ? normalizeSidebarLabel(label) : null;
669
855
 
670
856
  for (let attempt = 0; attempt < POSITION_RETRY_ATTEMPTS; attempt += 1) {
671
857
  try {
672
858
  const result = await db
673
- .insert(sidebarItems)
859
+ .insert(directoryItemsTable)
674
860
  .values({
675
861
  id,
676
862
  siteId,
677
- type,
678
- collectionId: collectionId ?? null,
679
- label: normalizedLabel,
680
- position: await getAppendSidebarPosition(),
863
+ type: normalizedData.type,
864
+ collectionId:
865
+ normalizedData.type === "collection"
866
+ ? normalizedData.collectionId
867
+ : null,
868
+ label:
869
+ normalizedData.type === "divider"
870
+ ? (normalizedData.label ?? null)
871
+ : normalizedData.type === "link"
872
+ ? normalizedData.label
873
+ : null,
874
+ url: normalizedData.type === "link" ? normalizedData.url : null,
875
+ description:
876
+ normalizedData.type === "link"
877
+ ? (normalizedData.description ?? null)
878
+ : null,
879
+ position: await getAppendDirectoryPosition(),
681
880
  createdAt: timestamp,
682
881
  updatedAt: timestamp,
683
882
  })
684
883
  .returning();
685
884
 
686
885
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- DB insert with .returning() always returns inserted row
687
- return toSidebarItem(result[0]!);
886
+ return toDirectoryItem(result[0]!);
688
887
  } catch (err) {
689
888
  if (
690
- type === "collection" &&
691
- collectionId &&
889
+ normalizedData.type === "collection" &&
692
890
  isUniqueConstraintError(err)
693
891
  ) {
694
892
  const existing = await db
695
- .select({ id: sidebarItems.id })
696
- .from(sidebarItems)
893
+ .select({ id: directoryItemsTable.id })
894
+ .from(directoryItemsTable)
697
895
  .where(
698
896
  and(
699
- eq(sidebarItems.siteId, siteId),
700
- eq(sidebarItems.collectionId, collectionId),
897
+ eq(directoryItemsTable.siteId, siteId),
898
+ eq(
899
+ directoryItemsTable.collectionId,
900
+ normalizedData.collectionId,
901
+ ),
701
902
  ),
702
903
  )
703
904
  .limit(1);
704
905
  if (existing.length > 0) {
705
- throw new ConflictError("Collection is already in the sidebar.");
906
+ throw new ConflictError(
907
+ "Collection is already in the directory.",
908
+ );
706
909
  }
707
910
  }
708
911
  if (
@@ -714,48 +917,96 @@ export function createCollectionService(
714
917
  }
715
918
  }
716
919
 
717
- throw new Error("Failed to assign a unique sidebar item position");
920
+ throw new Error("Failed to assign a unique directory item position");
718
921
  },
719
922
 
720
- async deleteSidebarItem(id) {
923
+ async deleteDirectoryItem(id) {
721
924
  const result = await db
722
- .delete(sidebarItems)
723
- .where(and(eq(sidebarItems.siteId, siteId), eq(sidebarItems.id, id)))
925
+ .delete(directoryItemsTable)
926
+ .where(
927
+ and(
928
+ eq(directoryItemsTable.siteId, siteId),
929
+ eq(directoryItemsTable.id, id),
930
+ ),
931
+ )
724
932
  .returning();
725
933
  return result.length > 0;
726
934
  },
727
935
 
728
- async updateSidebarItem(id, data) {
936
+ async updateDirectoryItem(id, data) {
729
937
  const existing = await db
730
938
  .select()
731
- .from(sidebarItems)
732
- .where(and(eq(sidebarItems.siteId, siteId), eq(sidebarItems.id, id)))
939
+ .from(directoryItemsTable)
940
+ .where(
941
+ and(
942
+ eq(directoryItemsTable.siteId, siteId),
943
+ eq(directoryItemsTable.id, id),
944
+ ),
945
+ )
733
946
  .limit(1);
734
947
  const item = existing[0];
735
948
  if (!item) return null;
736
949
 
737
- if (data.label === undefined) {
738
- return toSidebarItem(item);
950
+ if (
951
+ data.label === undefined &&
952
+ data.url === undefined &&
953
+ data.description === undefined
954
+ ) {
955
+ return toDirectoryItem(item);
956
+ }
957
+
958
+ let nextLabel = item.label;
959
+ let nextUrl = item.url;
960
+ let nextDescription = item.description;
961
+
962
+ if (item.type === "divider" && data.label !== undefined) {
963
+ nextLabel = normalizeDirectoryLabel(data.label);
964
+ }
965
+
966
+ if (item.type === "link") {
967
+ if (data.label !== undefined) {
968
+ if (data.label === null) {
969
+ throw new ValidationError("Link label is required.");
970
+ }
971
+ nextLabel = normalizeDirectoryLinkLabel(data.label);
972
+ }
973
+ if (data.url !== undefined) {
974
+ nextUrl = normalizeDirectoryUrl(data.url);
975
+ }
976
+ if (data.description !== undefined) {
977
+ nextDescription = normalizeDirectoryDescription(data.description);
978
+ }
739
979
  }
740
980
 
741
981
  const result = await db
742
- .update(sidebarItems)
982
+ .update(directoryItemsTable)
743
983
  .set({
744
- label:
745
- item.type === "divider" ? normalizeSidebarLabel(data.label) : null,
984
+ label: item.type === "collection" ? null : nextLabel,
985
+ url: item.type === "link" ? nextUrl : null,
986
+ description: item.type === "link" ? nextDescription : null,
746
987
  updatedAt: now(),
747
988
  })
748
- .where(and(eq(sidebarItems.siteId, siteId), eq(sidebarItems.id, id)))
989
+ .where(
990
+ and(
991
+ eq(directoryItemsTable.siteId, siteId),
992
+ eq(directoryItemsTable.id, id),
993
+ ),
994
+ )
749
995
  .returning();
750
996
 
751
- return result[0] ? toSidebarItem(result[0]) : null;
997
+ return result[0] ? toDirectoryItem(result[0]) : null;
752
998
  },
753
999
 
754
- async moveSidebarItem(id, afterId, beforeId) {
1000
+ async moveDirectoryItem(id, afterId, beforeId) {
755
1001
  const items = await db
756
1002
  .select()
757
- .from(sidebarItems)
758
- .where(and(eq(sidebarItems.siteId, siteId), eq(sidebarItems.id, id)))
1003
+ .from(directoryItemsTable)
1004
+ .where(
1005
+ and(
1006
+ eq(directoryItemsTable.siteId, siteId),
1007
+ eq(directoryItemsTable.id, id),
1008
+ ),
1009
+ )
759
1010
  .limit(1);
760
1011
  if (!items[0]) return null;
761
1012
 
@@ -763,17 +1014,20 @@ export function createCollectionService(
763
1014
  for (let attempt = 0; attempt < POSITION_RETRY_ATTEMPTS; attempt += 1) {
764
1015
  try {
765
1016
  const result = await db
766
- .update(sidebarItems)
1017
+ .update(directoryItemsTable)
767
1018
  .set({
768
- position: await getSidebarMovePosition(id, afterId, beforeId),
1019
+ position: await getDirectoryMovePosition(id, afterId, beforeId),
769
1020
  updatedAt: timestamp,
770
1021
  })
771
1022
  .where(
772
- and(eq(sidebarItems.siteId, siteId), eq(sidebarItems.id, id)),
1023
+ and(
1024
+ eq(directoryItemsTable.siteId, siteId),
1025
+ eq(directoryItemsTable.id, id),
1026
+ ),
773
1027
  )
774
1028
  .returning();
775
1029
 
776
- return result[0] ? toSidebarItem(result[0]) : null;
1030
+ return result[0] ? toDirectoryItem(result[0]) : null;
777
1031
  } catch (err) {
778
1032
  if (
779
1033
  !isUniqueConstraintError(err) ||
@@ -784,14 +1038,14 @@ export function createCollectionService(
784
1038
  }
785
1039
  }
786
1040
 
787
- throw new Error("Failed to assign a unique sidebar item position");
1041
+ throw new Error("Failed to assign a unique directory item position");
788
1042
  },
789
1043
 
790
1044
  async getPostCounts() {
791
1045
  const rows = await db
792
1046
  .select({
793
1047
  collectionId: postCollections.collectionId,
794
- count: sql<number>`count(*)`.as("count"),
1048
+ count: sql<number>`CAST(count(*) AS INTEGER)`.as("count"),
795
1049
  })
796
1050
  .from(postCollections)
797
1051
  .innerJoin(
@@ -808,13 +1062,97 @@ export function createCollectionService(
808
1062
  return counts;
809
1063
  },
810
1064
 
811
- async addPost(collectionId, postId) {
1065
+ async addPost(collectionId, postId, opts) {
1066
+ const [maxRow] = await db
1067
+ .select({
1068
+ maxPos: sql<number>`COALESCE(MAX(${postCollections.position}), -1)`,
1069
+ })
1070
+ .from(postCollections)
1071
+ .where(
1072
+ and(
1073
+ eq(postCollections.siteId, siteId),
1074
+ eq(postCollections.postId, postId),
1075
+ ),
1076
+ );
1077
+ const nextPosition = (maxRow?.maxPos ?? -1) + 1;
812
1078
  await db
813
1079
  .insert(postCollections)
814
- .values({ siteId, postId, collectionId, createdAt: now() })
1080
+ .values({
1081
+ siteId,
1082
+ postId,
1083
+ collectionId,
1084
+ createdAt: opts?.createdAt ?? now(),
1085
+ position: opts?.position ?? nextPosition,
1086
+ pinnedAt: opts?.pinnedAt ?? null,
1087
+ })
815
1088
  .onConflictDoNothing();
816
1089
  },
817
1090
 
1091
+ async syncPostCollectionsWithMeta(postId, entries) {
1092
+ const seen = new Set<string>();
1093
+ const timestamp = now();
1094
+ const insertValues: {
1095
+ siteId: string;
1096
+ postId: string;
1097
+ collectionId: string;
1098
+ createdAt: number;
1099
+ position: number;
1100
+ pinnedAt: number | null;
1101
+ }[] = [];
1102
+ let fallbackPosition = 0;
1103
+ for (const entry of entries) {
1104
+ if (seen.has(entry.collectionId)) continue;
1105
+ seen.add(entry.collectionId);
1106
+ insertValues.push({
1107
+ siteId,
1108
+ postId,
1109
+ collectionId: entry.collectionId,
1110
+ createdAt: entry.createdAt ?? timestamp,
1111
+ position: entry.position ?? fallbackPosition,
1112
+ pinnedAt: entry.pinnedAt ?? null,
1113
+ });
1114
+ fallbackPosition++;
1115
+ }
1116
+
1117
+ const deleteQuery = db
1118
+ .delete(postCollections)
1119
+ .where(
1120
+ and(
1121
+ eq(postCollections.siteId, siteId),
1122
+ eq(postCollections.postId, postId),
1123
+ ),
1124
+ );
1125
+
1126
+ if (usesBatchWrites) {
1127
+ const writeQueries = [];
1128
+ writeQueries.push(deleteQuery);
1129
+ if (insertValues.length > 0) {
1130
+ writeQueries.push(db.insert(postCollections).values(insertValues));
1131
+ }
1132
+ await db.batch(
1133
+ writeQueries as [
1134
+ (typeof writeQueries)[number],
1135
+ ...(typeof writeQueries)[number][],
1136
+ ],
1137
+ );
1138
+ return;
1139
+ }
1140
+
1141
+ await db.transaction(async (tx) => {
1142
+ await tx
1143
+ .delete(postCollections)
1144
+ .where(
1145
+ and(
1146
+ eq(postCollections.siteId, siteId),
1147
+ eq(postCollections.postId, postId),
1148
+ ),
1149
+ );
1150
+ if (insertValues.length > 0) {
1151
+ await tx.insert(postCollections).values(insertValues);
1152
+ }
1153
+ });
1154
+ },
1155
+
818
1156
  async removePost(collectionId, postId) {
819
1157
  await db
820
1158
  .delete(postCollections)
@@ -827,6 +1165,47 @@ export function createCollectionService(
827
1165
  );
828
1166
  },
829
1167
 
1168
+ async pinPost(collectionId, postId) {
1169
+ await db
1170
+ .update(postCollections)
1171
+ .set({ pinnedAt: now() })
1172
+ .where(
1173
+ and(
1174
+ eq(postCollections.siteId, siteId),
1175
+ eq(postCollections.postId, postId),
1176
+ eq(postCollections.collectionId, collectionId),
1177
+ ),
1178
+ );
1179
+ },
1180
+
1181
+ async unpinPost(collectionId, postId) {
1182
+ await db
1183
+ .update(postCollections)
1184
+ .set({ pinnedAt: null })
1185
+ .where(
1186
+ and(
1187
+ eq(postCollections.siteId, siteId),
1188
+ eq(postCollections.postId, postId),
1189
+ eq(postCollections.collectionId, collectionId),
1190
+ ),
1191
+ );
1192
+ },
1193
+
1194
+ async getPinnedPostIds(collectionIds) {
1195
+ if (collectionIds.length === 0) return new Set<string>();
1196
+ const rows = await db
1197
+ .select({ postId: postCollections.postId })
1198
+ .from(postCollections)
1199
+ .where(
1200
+ and(
1201
+ eq(postCollections.siteId, siteId),
1202
+ inArray(postCollections.collectionId, collectionIds),
1203
+ sql`${postCollections.pinnedAt} IS NOT NULL`,
1204
+ ),
1205
+ );
1206
+ return new Set(rows.map((r) => r.postId));
1207
+ },
1208
+
830
1209
  async getCollectionsByPostId(postId) {
831
1210
  const rows = await db
832
1211
  .select({ collection: collections })
@@ -842,7 +1221,7 @@ export function createCollectionService(
842
1221
  eq(postCollections.postId, postId),
843
1222
  ),
844
1223
  )
845
- .orderBy(asc(collections.createdAt));
1224
+ .orderBy(asc(postCollections.position), asc(postCollections.createdAt));
846
1225
 
847
1226
  return hydrateCollections(rows.map((row) => row.collection));
848
1227
  },
@@ -869,7 +1248,10 @@ export function createCollectionService(
869
1248
  inArray(postCollections.postId, chunk),
870
1249
  ),
871
1250
  )
872
- .orderBy(asc(collections.createdAt)),
1251
+ .orderBy(
1252
+ asc(postCollections.position),
1253
+ asc(postCollections.createdAt),
1254
+ ),
873
1255
  );
874
1256
 
875
1257
  const collectionRows = rows.map((row) => row.collection);
@@ -888,6 +1270,35 @@ export function createCollectionService(
888
1270
  return result;
889
1271
  },
890
1272
 
1273
+ async getCollectionPinsByPostIds(postIds) {
1274
+ const result = new Map<string, Set<string>>();
1275
+ if (postIds.length === 0) return result;
1276
+
1277
+ const rows = await batchQueryRows(postIds, (chunk) =>
1278
+ db
1279
+ .select({
1280
+ postId: postCollections.postId,
1281
+ collectionId: postCollections.collectionId,
1282
+ })
1283
+ .from(postCollections)
1284
+ .where(
1285
+ and(
1286
+ eq(postCollections.siteId, siteId),
1287
+ inArray(postCollections.postId, chunk),
1288
+ sql`${postCollections.pinnedAt} IS NOT NULL`,
1289
+ ),
1290
+ ),
1291
+ );
1292
+
1293
+ for (const row of rows) {
1294
+ const existing = result.get(row.postId) ?? new Set<string>();
1295
+ existing.add(row.collectionId);
1296
+ result.set(row.postId, existing);
1297
+ }
1298
+
1299
+ return result;
1300
+ },
1301
+
891
1302
  async getPostIds(collectionId) {
892
1303
  const rows = await db
893
1304
  .select({ postId: postCollections.postId })
@@ -902,49 +1313,103 @@ export function createCollectionService(
902
1313
  return rows.map((row) => row.postId);
903
1314
  },
904
1315
 
1316
+ async getCollectionEntriesByPostIds(postIds) {
1317
+ const result = new Map<
1318
+ string,
1319
+ {
1320
+ collectionId: string;
1321
+ createdAt: number;
1322
+ position: number;
1323
+ pinnedAt: number | null;
1324
+ }[]
1325
+ >();
1326
+ if (postIds.length === 0) return result;
1327
+
1328
+ const rows = await batchQueryRows(postIds, (chunk) =>
1329
+ db
1330
+ .select({
1331
+ postId: postCollections.postId,
1332
+ collectionId: postCollections.collectionId,
1333
+ createdAt: postCollections.createdAt,
1334
+ position: postCollections.position,
1335
+ pinnedAt: postCollections.pinnedAt,
1336
+ })
1337
+ .from(postCollections)
1338
+ .where(
1339
+ and(
1340
+ eq(postCollections.siteId, siteId),
1341
+ inArray(postCollections.postId, chunk),
1342
+ ),
1343
+ )
1344
+ .orderBy(
1345
+ asc(postCollections.position),
1346
+ asc(postCollections.createdAt),
1347
+ ),
1348
+ );
1349
+
1350
+ for (const row of rows) {
1351
+ const existing = result.get(row.postId) ?? [];
1352
+ existing.push({
1353
+ collectionId: row.collectionId,
1354
+ createdAt: row.createdAt,
1355
+ position: row.position,
1356
+ pinnedAt: row.pinnedAt,
1357
+ });
1358
+ result.set(row.postId, existing);
1359
+ }
1360
+
1361
+ return result;
1362
+ },
1363
+
905
1364
  async syncPostCollections(postId, collectionIds) {
906
1365
  const nextCollectionIds = [...new Set(collectionIds)];
907
- const existingCollectionIds = await getPostCollectionIds(postId);
908
- const existingIds = new Set(existingCollectionIds);
909
- const nextIds = new Set(nextCollectionIds);
910
- const removedIds = existingCollectionIds.filter((id) => !nextIds.has(id));
911
- const addedIds = nextCollectionIds.filter((id) => !existingIds.has(id));
912
1366
 
913
- if (removedIds.length === 0 && addedIds.length === 0) {
1367
+ // Fetch existing rows to preserve createdAt for retained collections
1368
+ const existingRows = await db
1369
+ .select({
1370
+ collectionId: postCollections.collectionId,
1371
+ createdAt: postCollections.createdAt,
1372
+ })
1373
+ .from(postCollections)
1374
+ .where(
1375
+ and(
1376
+ eq(postCollections.siteId, siteId),
1377
+ eq(postCollections.postId, postId),
1378
+ ),
1379
+ );
1380
+
1381
+ if (existingRows.length === 0 && nextCollectionIds.length === 0) {
914
1382
  return;
915
1383
  }
916
1384
 
1385
+ const existingTimestamps = new Map(
1386
+ existingRows.map((r) => [r.collectionId, r.createdAt]),
1387
+ );
1388
+ const timestamp = now();
1389
+ const insertValues = nextCollectionIds.map((collectionId, index) => ({
1390
+ siteId,
1391
+ postId,
1392
+ collectionId,
1393
+ createdAt: existingTimestamps.get(collectionId) ?? timestamp,
1394
+ position: index,
1395
+ }));
1396
+
1397
+ // Delete all and re-insert to preserve user-specified ordering
1398
+ const deleteQuery = db
1399
+ .delete(postCollections)
1400
+ .where(
1401
+ and(
1402
+ eq(postCollections.siteId, siteId),
1403
+ eq(postCollections.postId, postId),
1404
+ ),
1405
+ );
1406
+
917
1407
  if (usesBatchWrites) {
918
1408
  const writeQueries = [];
919
-
920
- if (removedIds.length > 0) {
921
- writeQueries.push(
922
- db
923
- .delete(postCollections)
924
- .where(
925
- and(
926
- eq(postCollections.siteId, siteId),
927
- eq(postCollections.postId, postId),
928
- inArray(postCollections.collectionId, removedIds),
929
- ),
930
- ),
931
- );
932
- }
933
-
934
- if (addedIds.length > 0) {
935
- const timestamp = now();
936
- writeQueries.push(
937
- db.insert(postCollections).values(
938
- addedIds.map((collectionId) => ({
939
- siteId,
940
- postId,
941
- collectionId,
942
- createdAt: timestamp,
943
- })),
944
- ),
945
- );
1409
+ writeQueries.push(deleteQuery);
1410
+ if (insertValues.length > 0) {
1411
+ writeQueries.push(db.insert(postCollections).values(insertValues));
946
1412
  }
947
-
948
1413
  await db.batch(
949
1414
  writeQueries as [
950
1415
  (typeof writeQueries)[number],
@@ -955,28 +1420,16 @@ export function createCollectionService(
955
1420
  }
956
1421
 
957
1422
  await db.transaction(async (tx) => {
958
- if (removedIds.length > 0) {
959
- await tx
960
- .delete(postCollections)
961
- .where(
962
- and(
963
- eq(postCollections.siteId, siteId),
964
- eq(postCollections.postId, postId),
965
- inArray(postCollections.collectionId, removedIds),
966
- ),
967
- );
968
- }
969
-
970
- if (addedIds.length > 0) {
971
- const timestamp = now();
972
- await tx.insert(postCollections).values(
973
- addedIds.map((collectionId) => ({
974
- siteId,
975
- postId,
976
- collectionId,
977
- createdAt: timestamp,
978
- })),
1423
+ await tx
1424
+ .delete(postCollections)
1425
+ .where(
1426
+ and(
1427
+ eq(postCollections.siteId, siteId),
1428
+ eq(postCollections.postId, postId),
1429
+ ),
979
1430
  );
1431
+ if (insertValues.length > 0) {
1432
+ await tx.insert(postCollections).values(insertValues);
980
1433
  }
981
1434
  });
982
1435
  },