memi-board 0.52.2 → 0.52.3

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 (40) hide show
  1. package/dist/{ar-BVwpedHS.js → ar-3hd6xh6U.js} +3 -1
  2. package/dist/ar-3hd6xh6U.js.map +1 -0
  3. package/dist/{commentImages-D_JJnuoj.js → commentImages-4IOk2u0O.js} +11 -10
  4. package/dist/commentImages-4IOk2u0O.js.map +1 -0
  5. package/dist/composables/useMemiBoardComments.d.ts +1 -0
  6. package/dist/composables/useMemiBoardWritingAssistant.d.ts +1 -1
  7. package/dist/{de-K2gYwR8U.js → de-DXtmk-4H.js} +3 -1
  8. package/dist/de-DXtmk-4H.js.map +1 -0
  9. package/dist/{en-DSCLJyUd.js → en-CyZH4Ct1.js} +2 -1
  10. package/dist/en-CyZH4Ct1.js.map +1 -0
  11. package/dist/{es-1P1miLJH.js → es-BtRbHicT.js} +3 -1
  12. package/dist/es-BtRbHicT.js.map +1 -0
  13. package/dist/{fr-cDQCmNSc.js → fr-vnizG3rD.js} +3 -1
  14. package/dist/fr-vnizG3rD.js.map +1 -0
  15. package/dist/{id-BzDIqeZ4.js → id-Cf8yw8n_.js} +3 -1
  16. package/dist/id-Cf8yw8n_.js.map +1 -0
  17. package/dist/index.js +422 -397
  18. package/dist/index.js.map +1 -1
  19. package/dist/{ja-B2wxHGCr.js → ja-D-Nrtjk-.js} +3 -1
  20. package/dist/ja-D-Nrtjk-.js.map +1 -0
  21. package/dist/{pt-BCY3OODD.js → pt-CSsshr7u.js} +3 -1
  22. package/dist/pt-CSsshr7u.js.map +1 -0
  23. package/dist/runtime/components/CommentForm.vue +10 -1
  24. package/dist/runtime/components/Editor.vue +15 -9
  25. package/dist/storage.js +1 -1
  26. package/dist/{zh-Y824rwR6.js → zh-BzrsqVN2.js} +3 -1
  27. package/dist/zh-BzrsqVN2.js.map +1 -0
  28. package/docs/firestore.rules.example +3 -3
  29. package/docs/host-integration.md +13 -0
  30. package/package.json +1 -1
  31. package/dist/ar-BVwpedHS.js.map +0 -1
  32. package/dist/commentImages-D_JJnuoj.js.map +0 -1
  33. package/dist/de-K2gYwR8U.js.map +0 -1
  34. package/dist/en-DSCLJyUd.js.map +0 -1
  35. package/dist/es-1P1miLJH.js.map +0 -1
  36. package/dist/fr-cDQCmNSc.js.map +0 -1
  37. package/dist/id-BzDIqeZ4.js.map +0 -1
  38. package/dist/ja-B2wxHGCr.js.map +0 -1
  39. package/dist/pt-BCY3OODD.js.map +0 -1
  40. package/dist/zh-Y824rwR6.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as l, K as u, L as d, M as f, N as p, O as m, P as h, R as g, S as _, T as v, U as y, V as b, W as x, X as S, Y as C, Z as w, _ as T, a as E, b as D, c as O, d as k, f as ee, g as A, h as te, j as ne, k as re, l as ie, m as j, o as ae, p as oe, q as se, r as ce, s as M, t as le, u as ue, v as de, w as N, x as fe, y as P, z as pe } from "./commentImages-D_JJnuoj.js";
2
- import { computed as F, onScopeDispose as I, reactive as me, readonly as he, ref as L, toValue as R, watch as z } from "vue";
3
- import { collection as ge, deleteDoc as _e, deleteField as ve, doc as ye, documentId as B, endAt as be, endBefore as xe, getDoc as Se, getDocFromServer as Ce, getDocs as V, getDocsFromServer as we, increment as Te, limit as H, limitToLast as Ee, onSnapshot as U, orderBy as W, query as G, runTransaction as De, serverTimestamp as K, setDoc as q, startAfter as J, updateDoc as Y, where as X, writeBatch as Oe } from "firebase/firestore";
1
+ import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as l, K as u, L as d, M as f, N as p, O as m, P as h, R as g, S as _, T as v, U as y, V as b, W as x, X as S, Y as C, Z as w, _ as T, a as E, b as D, c as ee, d as O, f as k, g as A, h as j, j as te, k as ne, l as re, m as M, o as ie, p as ae, q as oe, r as se, s as N, t as ce, u as le, v as ue, w as P, x as de, y as F, z as fe } from "./commentImages-4IOk2u0O.js";
2
+ import { computed as I, onScopeDispose as L, reactive as pe, readonly as me, ref as R, toValue as z, watch as B } from "vue";
3
+ import { collection as he, deleteDoc as ge, deleteField as _e, doc as ve, documentId as V, endAt as ye, endBefore as be, getDoc as xe, getDocFromServer as Se, getDocs as H, getDocsFromServer as Ce, increment as we, limit as U, limitToLast as Te, onSnapshot as W, orderBy as G, query as K, runTransaction as Ee, serverTimestamp as q, setDoc as De, startAfter as J, updateDoc as Y, where as X, writeBatch as Oe } from "firebase/firestore";
4
4
  import { useCollection as ke, useCurrentUser as Ae, useDocument as je, useFirebaseApp as Me, useFirebaseAuth as Ne, useFirestore as Z } from "vuefire";
5
5
  import { GoogleAuthProvider as Pe, OAuthProvider as Fe, createUserWithEmailAndPassword as Ie, getAuth as Le, signInWithEmailAndPassword as Re, signInWithPopup as ze, signOut as Be, updateProfile as Ve } from "firebase/auth";
6
6
  import { deleteObject as He, getMetadata as Ue, getStorage as We, list as Ge, listAll as Ke, ref as qe } from "firebase/storage";
7
7
  import { GoogleAIBackend as Je, Schema as Ye, getAI as Xe, getGenerativeModel as Ze } from "firebase/ai";
8
8
  //#region src/utils/boardSeo.ts
9
9
  function Qe(e, t) {
10
- return !e || e === "전체" || e === j(t, "seo.allCategory");
10
+ return !e || e === "전체" || e === M(t, "seo.allCategory");
11
11
  }
12
12
  function $e(e) {
13
13
  if (typeof e != "string") return null;
@@ -37,23 +37,23 @@ function tt(e, t, n = "") {
37
37
  return i ? /^https?:\/\//i.test(i) ? i : `${r}${i.startsWith("/") ? i : `/${i}`}` : n ? tt(n, t) : r;
38
38
  }
39
39
  function nt(e, t, n, r, i) {
40
- let a = r?.trim().slice(0, 40), o = e.trim() || a || j(i, "seo.photo"), s = t?.trim(), c = n.trim() || "Board";
40
+ let a = r?.trim().slice(0, 40), o = e.trim() || a || M(i, "seo.photo"), s = t?.trim(), c = n.trim() || "Board";
41
41
  return s ? `${o} · ${s} | ${c}` : `${o} | ${c}`;
42
42
  }
43
43
  function rt(e, t) {
44
44
  let n = [];
45
- return e.summary?.trim() ? n.push(e.summary.trim().slice(0, 140)) : n.push(j(t, "seo.postDescriptionFallback")), e.categoryLabel?.trim() && n.push(e.categoryLabel.trim()), e.authorName?.trim() && n.push(e.authorName.trim()), n.join(" · ").slice(0, 200);
45
+ return e.summary?.trim() ? n.push(e.summary.trim().slice(0, 140)) : n.push(M(t, "seo.postDescriptionFallback")), e.categoryLabel?.trim() && n.push(e.categoryLabel.trim()), e.authorName?.trim() && n.push(e.authorName.trim()), n.join(" · ").slice(0, 200);
46
46
  }
47
47
  function it(e, t, n) {
48
48
  let r = t.trim() || "Board", i = e?.trim();
49
- return Qe(i, n) ? j(n, "seo.listTitleAll", { site: r }) : j(n, "seo.listTitle", {
49
+ return Qe(i, n) ? M(n, "seo.listTitleAll", { site: r }) : M(n, "seo.listTitle", {
50
50
  name: i,
51
51
  site: r
52
52
  });
53
53
  }
54
54
  function at(e, t) {
55
55
  if (e.description?.trim()) return e.description.trim().slice(0, 200);
56
- let n = e.categoryLabel?.trim(), r = Qe(n, t) ? j(t, "seo.listDescriptionAll") : j(t, "seo.listDescription", { name: n }), i = (e.recentTitles || []).filter(Boolean).slice(0, 3);
56
+ let n = e.categoryLabel?.trim(), r = Qe(n, t) ? M(t, "seo.listDescriptionAll") : M(t, "seo.listDescription", { name: n }), i = (e.recentTitles || []).filter(Boolean).slice(0, 3);
57
57
  return i.length ? `${r} ${i.map((e) => `「${e}」`).join(" ")}`.slice(0, 200) : r.slice(0, 200);
58
58
  }
59
59
  function ot(e) {
@@ -82,7 +82,7 @@ function Q(e) {
82
82
  if (!e || typeof e != "object") return;
83
83
  let t = {};
84
84
  for (let [n, r] of Object.entries(e)) {
85
- let e = P(n);
85
+ let e = F(n);
86
86
  if (!e || !r || typeof r != "object") continue;
87
87
  let i = {};
88
88
  for (let [e, t] of Object.entries(r)) typeof t == "string" && t.trim() && (i[e] = t.trim());
@@ -92,14 +92,14 @@ function Q(e) {
92
92
  }
93
93
  function ut(e) {
94
94
  if (!e || typeof e != "object") return;
95
- let t = e, n = {}, r = P(t.locale);
95
+ let t = e, n = {}, r = F(t.locale);
96
96
  r && (n.locale = r);
97
97
  for (let e of st) typeof t[e] == "string" && (n[e] = t[e]);
98
98
  return Object.keys(n).length ? n : void 0;
99
99
  }
100
100
  function dt(e) {
101
101
  if (!e || typeof e != "object") return;
102
- let t = e, n = {}, r = P(t.locale);
102
+ let t = e, n = {}, r = F(t.locale);
103
103
  return r && (n.locale = r), typeof t.hash == "string" && t.hash && (n.hash = t.hash), n.locale || n.hash ? n : void 0;
104
104
  }
105
105
  function ft(e, t, n) {
@@ -122,7 +122,7 @@ function ft(e, t, n) {
122
122
  }), r;
123
123
  }
124
124
  function pt(e) {
125
- let t = new Set((e?.translationLocales ?? []).map((e) => P(e)).filter((e) => !!e)), n = T.map((e) => e.code);
125
+ let t = new Set((e?.translationLocales ?? []).map((e) => F(e)).filter((e) => !!e)), n = T.map((e) => e.code);
126
126
  return t.size ? n.filter((e) => t.has(e)) : n;
127
127
  }
128
128
  function mt(e) {
@@ -135,7 +135,7 @@ function ht(e, t, n = T.map((e) => e.code)) {
135
135
  }
136
136
  function gt(e, t, r, i, a) {
137
137
  if (!n()) return i;
138
- let o = P(t), s = P(a);
138
+ let o = F(t), s = F(a);
139
139
  if (!o || s && o === s) return i;
140
140
  let c = lt(e?.[o], r);
141
141
  if (c) return c;
@@ -170,12 +170,12 @@ function St(e, t) {
170
170
  function Ct() {
171
171
  return {
172
172
  db: Z(),
173
- paths: N()
173
+ paths: P()
174
174
  };
175
175
  }
176
176
  async function wt(e, t, n) {
177
177
  try {
178
- let r = await Se(w(e.db, e.paths, t));
178
+ let r = await xe(w(e.db, e.paths, t));
179
179
  if (!r.exists()) return {
180
180
  label: t,
181
181
  description: "",
@@ -208,11 +208,11 @@ async function Et(e, t, n, r) {
208
208
  let i = e.trim(), a = t.trim();
209
209
  if (!i || !a) return null;
210
210
  let s = n ?? Ct();
211
- s.paths = C(s.paths), r && await oe(r);
211
+ s.paths = C(s.paths), r && await ae(r);
212
212
  let c = await wt(s, i, r);
213
213
  if (c.hidden) return null;
214
214
  try {
215
- let e = (await V(G(o(s.db, s.paths), X("boardId", "==", i), X("slug", "==", a), X("listed", "==", !0), X("isPublished", "==", !0), H(1)))).docs[0];
215
+ let e = (await H(K(o(s.db, s.paths), X("boardId", "==", i), X("slug", "==", a), X("listed", "==", !0), X("isPublished", "==", !0), U(1)))).docs[0];
216
216
  if (!e) return null;
217
217
  let t = e.data() ?? {}, n = typeof t.title == "string" ? t.title : "", l = typeof t.summary == "string" ? t.summary : "", u = Q(t.i18n), d = ut(t.i18nSource), f = vt({
218
218
  title: n,
@@ -239,7 +239,7 @@ async function Et(e, t, n, r) {
239
239
  }
240
240
  }
241
241
  async function Dt(e, t, n) {
242
- n && await oe(n);
242
+ n && await ae(n);
243
243
  let r = e?.trim() || null, i = t ?? Ct();
244
244
  if (i.paths = C(i.paths), r) {
245
245
  let e = await wt(i, r, n);
@@ -256,7 +256,7 @@ async function Dt(e, t, n) {
256
256
  kind: "category",
257
257
  category: r,
258
258
  categoryLabel: e.label,
259
- description: e.description || j(n, "seo.boardDescription", { name: e.label }),
259
+ description: e.description || M(n, "seo.boardDescription", { name: e.label }),
260
260
  ogImage: a,
261
261
  recentTitles: t
262
262
  };
@@ -264,8 +264,8 @@ async function Dt(e, t, n) {
264
264
  return {
265
265
  kind: "all",
266
266
  category: null,
267
- categoryLabel: j(n, "seo.allCategory"),
268
- description: j(n, "seo.allDescription"),
267
+ categoryLabel: M(n, "seo.allCategory"),
268
+ description: M(n, "seo.allDescription"),
269
269
  ogImage: null,
270
270
  recentTitles: []
271
271
  };
@@ -273,7 +273,7 @@ async function Dt(e, t, n) {
273
273
  async function Ot(e, t, n) {
274
274
  let r = [], i = null;
275
275
  try {
276
- let a = await V(G(o(e.db, e.paths), X("boardId", "==", t), X("listed", "==", !0), X("isPublished", "==", !0), W("createdAt", "desc"), H(12)));
276
+ let a = await H(K(o(e.db, e.paths), X("boardId", "==", t), X("listed", "==", !0), X("isPublished", "==", !0), G("createdAt", "desc"), U(12)));
277
277
  for (let e of a.docs) {
278
278
  let t = e.data() ?? {}, a = vt({
279
279
  title: typeof t.title == "string" ? t.title : "",
@@ -337,10 +337,10 @@ function zt(e, t, n = Date.now(), r = 10, i = It) {
337
337
  }
338
338
  function Bt(e, t = Date.now(), n) {
339
339
  let r = Math.max(0, e - t), i = Math.ceil(r / 36e5);
340
- if (i <= 0) return j(n, "moderationStrike.liftSoon");
341
- if (i < 24) return j(n, "moderationStrike.liftInHours", { hours: i });
340
+ if (i <= 0) return M(n, "moderationStrike.liftSoon");
341
+ if (i < 24) return M(n, "moderationStrike.liftInHours", { hours: i });
342
342
  let a = Math.floor(i / 24), o = i % 24;
343
- return o === 0 ? j(n, "moderationStrike.liftInDays", { days: a }) : j(n, "moderationStrike.liftInDaysHours", {
343
+ return o === 0 ? M(n, "moderationStrike.liftInDays", { days: a }) : M(n, "moderationStrike.liftInDaysHours", {
344
344
  days: a,
345
345
  hours: o
346
346
  });
@@ -361,15 +361,15 @@ var Ht = "__MEMI_BOARD_AUTH_STATE__";
361
361
  function Ut() {
362
362
  let e = globalThis;
363
363
  return e[Ht] || (e[Ht] = {
364
- role: L("user"),
365
- rolePending: L(!0),
366
- rawBlockCount: L(0),
367
- blockAtMs: L(null),
364
+ role: R("user"),
365
+ rolePending: R(!0),
366
+ rawBlockCount: R(0),
367
+ blockAtMs: R(null),
368
368
  watchStarted: !1
369
369
  }), e[Ht];
370
370
  }
371
371
  function Wt() {
372
- let e = v(), { t, locale: n } = M(), r = Ut(), i = Z(), o = Ne(), s = Ae(), { role: c, rolePending: l, rawBlockCount: u, blockAtMs: d } = r;
372
+ let e = v(), { t, locale: n } = N(), r = Ut(), i = Z(), o = Ne(), s = Ae(), { role: c, rolePending: l, rawBlockCount: u, blockAtMs: d } = r;
373
373
  function f() {
374
374
  let t = e.moderation?.blockBanThreshold;
375
375
  return t === 0 ? 0 : typeof t == "number" && t > 0 ? Math.floor(t) : 10;
@@ -379,7 +379,7 @@ function Wt() {
379
379
  return typeof t == "number" && t > 0 ? t : It;
380
380
  }
381
381
  function m(e) {
382
- return h(i, N(), e);
382
+ return h(i, P(), e);
383
383
  }
384
384
  function g(e) {
385
385
  if (c.value = [
@@ -395,22 +395,22 @@ function Wt() {
395
395
  u.value = Math.max(0, Math.floor(Number(e.moderationBlockCount) || 0)), d.value = Vt(e.moderationBlockAt);
396
396
  }
397
397
  async function _(e) {
398
- let t = m(e.uid), n = a(i, N(), e.uid), r = await Se(t);
399
- if (!r.exists()) return await Promise.all([q(t, {
398
+ let t = m(e.uid), n = a(i, P(), e.uid), r = await xe(t);
399
+ if (!r.exists()) return await Promise.all([De(t, {
400
400
  role: "user",
401
401
  displayName: e.displayName,
402
402
  photoURL: e.photoURL,
403
- joinedAt: K(),
404
- lastVisitAt: K(),
405
- updatedAt: K()
406
- }), q(n, { email: e.email })]), g({ moderationBlockCount: 0 }), "user";
403
+ joinedAt: q(),
404
+ lastVisitAt: q(),
405
+ updatedAt: q()
406
+ }), De(n, { email: e.email })]), g({ moderationBlockCount: 0 }), "user";
407
407
  let o = r.data();
408
408
  g(o);
409
409
  let s = typeof o.displayName == "string" && o.displayName.trim(), c = typeof o.photoURL == "string" && o.photoURL.trim(), l = {
410
- lastVisitAt: K(),
411
- updatedAt: K()
410
+ lastVisitAt: q(),
411
+ updatedAt: q()
412
412
  };
413
- return !s && e.displayName && (l.displayName = e.displayName), !c && e.photoURL && (l.photoURL = e.photoURL), await Promise.all([Y(t, l), q(n, { email: e.email }, { merge: !0 })]), [
413
+ return !s && e.displayName && (l.displayName = e.displayName), !c && e.photoURL && (l.photoURL = e.photoURL), await Promise.all([Y(t, l), De(n, { email: e.email }, { merge: !0 })]), [
414
414
  "owner",
415
415
  "admin",
416
416
  "manager",
@@ -424,10 +424,10 @@ function Wt() {
424
424
  g(void 0);
425
425
  return;
426
426
  }
427
- let t = await Se(m(e));
427
+ let t = await xe(m(e));
428
428
  g(t.exists() ? t.data() : void 0);
429
429
  }
430
- r.watchStarted || (r.watchStarted = !0, z(s, async (e) => {
430
+ r.watchStarted || (r.watchStarted = !0, B(s, async (e) => {
431
431
  if (l.value = !0, !e) {
432
432
  c.value = "user", g(void 0), l.value = !1;
433
433
  return;
@@ -440,37 +440,37 @@ function Wt() {
440
440
  l.value = !1;
441
441
  }
442
442
  }, { immediate: !0 }));
443
- let b = F(() => !!s.value), x = F(() => c.value === "owner"), S = F(() => c.value === "manager"), C = F(() => x.value || c.value === "admin"), w = F(() => S.value || c.value === "staff"), T = F(() => C.value || w.value), E = F(() => Lt(u.value, d.value, Date.now(), p())), D = F(() => {
443
+ let b = I(() => !!s.value), x = I(() => c.value === "owner"), S = I(() => c.value === "manager"), C = I(() => x.value || c.value === "admin"), w = I(() => S.value || c.value === "staff"), T = I(() => C.value || w.value), E = I(() => Lt(u.value, d.value, Date.now(), p())), D = I(() => {
444
444
  let e = f();
445
445
  return e <= 0 ? !1 : zt(u.value, d.value, Date.now(), e, p());
446
- }), O = F(() => {
446
+ }), ee = I(() => {
447
447
  let e = f();
448
448
  if (e <= 0) return null;
449
449
  let t = Rt(u.value, d.value, Date.now(), e, p());
450
450
  return t == null ? null : Bt(t, Date.now(), n.value);
451
- }), k = F(() => {
451
+ }), O = I(() => {
452
452
  if (!D.value) return null;
453
- let e = O.value;
453
+ let e = ee.value;
454
454
  return e ? t("auth.writeRestrictedUntil", { until: e }) : t("auth.writeRestricted");
455
455
  });
456
- async function ee() {
456
+ async function k() {
457
457
  let e = s.value?.uid, r = f();
458
458
  if (!e || r <= 0) return {
459
459
  effectiveCount: 0,
460
460
  restricted: !1,
461
461
  messageSuffix: ""
462
462
  };
463
- let i = m(e), a = await Se(i);
463
+ let i = m(e), a = await xe(i);
464
464
  a.exists() ? await Y(i, {
465
- moderationBlockCount: Te(1),
466
- moderationBlockAt: K(),
467
- updatedAt: K()
468
- }) : await q(i, {
465
+ moderationBlockCount: we(1),
466
+ moderationBlockAt: q(),
467
+ updatedAt: q()
468
+ }) : await De(i, {
469
469
  role: "user",
470
470
  displayName: s.value?.displayName ?? null,
471
471
  moderationBlockCount: 1,
472
- moderationBlockAt: K(),
473
- updatedAt: K()
472
+ moderationBlockAt: q(),
473
+ updatedAt: q()
474
474
  });
475
475
  let o = (a.exists() ? Math.max(0, Math.floor(Number(a.data().moderationBlockCount) || 0)) : 0) + 1, c = Date.now();
476
476
  u.value = o, d.value = c;
@@ -495,64 +495,64 @@ function Wt() {
495
495
  if (!o) throw Error(t("auth.notInitialized"));
496
496
  return o;
497
497
  }
498
- async function te() {
498
+ async function j() {
499
499
  return ze(A(), new Pe());
500
500
  }
501
- async function ne() {
501
+ async function te() {
502
502
  let e = new Fe("apple.com");
503
503
  return e.addScope("email"), e.addScope("name"), ze(A(), e);
504
504
  }
505
- async function re(e, t) {
505
+ async function ne(e, t) {
506
506
  return Re(A(), e, t);
507
507
  }
508
- async function ie(e, t, n) {
508
+ async function re(e, t, n) {
509
509
  let r = await Ie(A(), e, t);
510
510
  return n && await Ve(r.user, { displayName: n }), r;
511
511
  }
512
- async function j() {
512
+ async function M() {
513
513
  await Be(A());
514
514
  }
515
- function ae(e) {
515
+ function ie(e) {
516
516
  return At(s.value?.uid, C.value, w.value, e ? Pt(e) : void 0);
517
517
  }
518
- function oe(e) {
518
+ function ae(e) {
519
519
  return s.value ? C.value ? !0 : S.value && !!e && (Pt(e)?.allowedManagerUids ?? []).includes(s.value.uid) : !1;
520
520
  }
521
- function se(e) {
522
- return b.value && (s.value?.uid === e.authorUid || ae(e.boardId));
521
+ function oe(e) {
522
+ return b.value && (s.value?.uid === e.authorUid || ie(e.boardId));
523
523
  }
524
- function ce(e) {
524
+ function se(e) {
525
525
  return b.value && s.value?.uid === e.authorUid;
526
526
  }
527
- function le(e) {
528
- return b.value && (s.value?.uid === e.authorUid || ae(e.boardId));
527
+ function ce(e) {
528
+ return b.value && (s.value?.uid === e.authorUid || ie(e.boardId));
529
529
  }
530
530
  return {
531
531
  user: s,
532
532
  role: c,
533
533
  isOwner: x,
534
534
  isManager: S,
535
- canConfigureBoard: oe,
535
+ canConfigureBoard: ae,
536
536
  isSignedIn: b,
537
537
  isAdmin: C,
538
538
  isStaff: w,
539
539
  canManageContent: T,
540
- canManageBoard: ae,
540
+ canManageBoard: ie,
541
541
  rolePending: l,
542
542
  moderationBlockCount: E,
543
543
  isWriteRestricted: D,
544
- restrictedUntilLabel: O,
545
- restrictedMessage: k,
546
- signInWithGoogle: te,
547
- signInWithApple: ne,
548
- signInWithEmail: re,
549
- signUpWithEmail: ie,
550
- signOut: j,
551
- canEdit: se,
552
- canDelete: se,
553
- canEditComment: ce,
554
- canDeleteComment: le,
555
- recordContentModerationBlock: ee,
544
+ restrictedUntilLabel: ee,
545
+ restrictedMessage: O,
546
+ signInWithGoogle: j,
547
+ signInWithApple: te,
548
+ signInWithEmail: ne,
549
+ signUpWithEmail: re,
550
+ signOut: M,
551
+ canEdit: oe,
552
+ canDelete: oe,
553
+ canEditComment: se,
554
+ canDeleteComment: ce,
555
+ recordContentModerationBlock: k,
556
556
  refreshBoardUser: y
557
557
  };
558
558
  }
@@ -581,7 +581,7 @@ function Jt(e) {
581
581
  //#region src/utils/findReadablePost.ts
582
582
  async function Yt(e, t, n, r, i, a) {
583
583
  let s = [X("boardId", "==", n), X("slug", "==", r)];
584
- return a ? (await V(G(o(e, t), ...s, H(1)))).docs[0] : (await Promise.all([V(G(o(e, t), ...s, X("listed", "==", !0), X("isPublished", "==", !0), H(1))), ...i ? [V(G(o(e, t), ...s, X("authorUid", "==", i), H(1)))] : []])).flatMap((e) => e.docs)[0];
584
+ return a ? (await H(K(o(e, t), ...s, U(1)))).docs[0] : (await Promise.all([H(K(o(e, t), ...s, X("listed", "==", !0), X("isPublished", "==", !0), U(1))), ...i ? [H(K(o(e, t), ...s, X("authorUid", "==", i), U(1)))] : []])).flatMap((e) => e.docs)[0];
585
585
  }
586
586
  //#endregion
587
587
  //#region src/utils/extractEditorImageUrls.ts
@@ -620,27 +620,27 @@ async function en(e, t) {
620
620
  }
621
621
  var tn = 450;
622
622
  async function nn(e, t, n) {
623
- return (await V(G(g(e, t), X("postId", "==", n)))).docs.flatMap((e) => le(e.data().images, `${x(t, n)}/comment-images/`));
623
+ return (await H(K(g(e, t), X("postId", "==", n)))).docs.flatMap((e) => ce(e.data().images, `${x(t, n)}/comment-images/`));
624
624
  }
625
625
  async function rn(e, t) {
626
626
  let n = [...new Set([...t].filter(Boolean))];
627
627
  await Promise.all(n.map((t) => He(qe(e, t)).catch(() => {})));
628
628
  }
629
629
  async function an(e, t) {
630
- let n = await V(t);
630
+ let n = await H(t);
631
631
  for (let t = 0; t < n.docs.length; t += tn) {
632
632
  let r = Oe(e);
633
633
  n.docs.slice(t, t + tn).forEach((e) => r.delete(e.ref)), await r.commit();
634
634
  }
635
635
  }
636
636
  async function on(e, t, n) {
637
- await an(e, G(b(e, t), X("postId", "==", n)));
637
+ await an(e, K(b(e, t), X("postId", "==", n)));
638
638
  }
639
639
  async function sn(e, t, n) {
640
- await an(e, G(b(e, t), X("commentId", "==", n), X("target", "==", "comment")));
640
+ await an(e, K(b(e, t), X("commentId", "==", n), X("target", "==", "comment")));
641
641
  }
642
642
  async function cn(e, t, n, r) {
643
- let i = y(e, n, r), a = s(e, n, r), [o, c] = await Promise.all([Se(i), Se(a)]);
643
+ let i = y(e, n, r), a = s(e, n, r), [o, c] = await Promise.all([xe(i), xe(a)]);
644
644
  if (!o.exists()) return;
645
645
  let l = o.data(), u = c.exists() ? String(c.data().content ?? "") : "", d = await nn(e, n, r), f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set();
646
646
  for (let e of l.attachments ?? []) {
@@ -662,7 +662,7 @@ async function cn(e, t, n, r) {
662
662
  }
663
663
  await en(t, x(n, r));
664
664
  for (let e of p) await en(t, x(n, e));
665
- await rn(t, d), await rn(t, f), await an(e, G(g(e, n), X("postId", "==", r))), await on(e, n, r), await _e(a), await _e(i);
665
+ await rn(t, d), await rn(t, f), await an(e, K(g(e, n), X("postId", "==", r))), await on(e, n, r), await ge(a), await ge(i);
666
666
  }
667
667
  //#endregion
668
668
  //#region src/utils/postBody.ts
@@ -719,7 +719,7 @@ function vn(e) {
719
719
  async function yn(e, t, n, r) {
720
720
  let i;
721
721
  for (;;) {
722
- let a = await V(G(t, X("boardId", "==", n), W("__name__"), ...i ? [J(i)] : [], H(400)));
722
+ let a = await H(K(t, X("boardId", "==", n), G("__name__"), ...i ? [J(i)] : [], U(400)));
723
723
  if (a.empty) break;
724
724
  let o = Oe(e), s = 0;
725
725
  for (let e of a.docs) e.data().listed !== r && (o.update(e.ref, { listed: r }), s++);
@@ -731,7 +731,7 @@ async function bn(e, t, n, r) {
731
731
  }
732
732
  async function xn(e, t, n, r) {
733
733
  let i = w(e, t, n), a = vn(r.visibility);
734
- await De(e, async (e) => {
734
+ await Ee(e, async (e) => {
735
735
  let t = await e.get(i), n = t.data(), o = n?.visibilityTransition || "";
736
736
  if (o && o !== a) throw Error("Finish the pending visibility change before changing it again.");
737
737
  return !t.exists() || !o && vn(n?.visibility) === a ? (e.set(i, r, { merge: !0 }), !1) : (e.set(i, {
@@ -739,12 +739,12 @@ async function xn(e, t, n, r) {
739
739
  visibility: a === "public" ? "public" : vn(n?.visibility),
740
740
  visibilityTransition: a
741
741
  }, { merge: !0 }), !0);
742
- }) && (await bn(e, t, n, a !== "hidden"), await De(e, async (e) => {
742
+ }) && (await bn(e, t, n, a !== "hidden"), await Ee(e, async (e) => {
743
743
  if ((await e.get(i)).data()?.visibilityTransition !== a) throw Error("The visibility transition changed. Reload and retry.");
744
744
  e.update(i, {
745
745
  visibility: a,
746
746
  visibilityTransition: "",
747
- updatedAt: K()
747
+ updatedAt: q()
748
748
  });
749
749
  }));
750
750
  }
@@ -763,7 +763,7 @@ var Sn = "당신은 게시판 콘텐츠를 심사하는 엄격한 모더레이
763
763
  id: "Indonesian"
764
764
  };
765
765
  function wn(e) {
766
- let t = Cn[e] ?? "English", n = de(e).name;
766
+ let t = Cn[e] ?? "English", n = ue(e).name;
767
767
  return t === n ? t : `${t} (${n})`;
768
768
  }
769
769
  function Tn(e) {
@@ -813,18 +813,18 @@ var kn = {
813
813
  none: ""
814
814
  };
815
815
  function An(e, t = "ko") {
816
- return !e || e === "none" ? "" : e in kn ? j(t, `moderationPrompt.categories.${e}`) : e;
816
+ return !e || e === "none" ? "" : e in kn ? M(t, `moderationPrompt.categories.${e}`) : e;
817
817
  }
818
818
  function jn(e) {
819
819
  let t = e.locale ?? "ko";
820
820
  if (e.via === "local" && e.localHit) {
821
821
  let n = e.localHit.trim();
822
- return n.length > 0 && n.length <= 12 ? j(t, "moderationPrompt.localHit", { hit: n }) : j(t, "moderationPrompt.localGeneric");
822
+ return n.length > 0 && n.length <= 12 ? M(t, "moderationPrompt.localHit", { hit: n }) : M(t, "moderationPrompt.localGeneric");
823
823
  }
824
824
  let n = (e.reason || "").trim();
825
825
  if (n) return n;
826
826
  let r = e.category ? An(e.category, t) : "";
827
- return r ? j(t, "moderationPrompt.categoryBlocked", { category: r }) : j(t, "moderationPrompt.genericBlocked");
827
+ return r ? M(t, "moderationPrompt.categoryBlocked", { category: r }) : M(t, "moderationPrompt.genericBlocked");
828
828
  }
829
829
  var Mn = [
830
830
  "씨발",
@@ -934,7 +934,7 @@ function Un() {
934
934
  responseMimeType: "application/json",
935
935
  responseSchema: Ye.object({ properties: { locale: Ye.enumString({ enum: T.map((e) => e.code) }) } })
936
936
  }
937
- }).generateContent(JSON.stringify({ text: n.slice(0, Rn) })), In), a = P(JSON.parse(i.response.text())?.locale);
937
+ }).generateContent(JSON.stringify({ text: n.slice(0, Rn) })), In), a = F(JSON.parse(i.response.text())?.locale);
938
938
  if (!a) throw Error("Could not identify the original language. Please try translating again.");
939
939
  return a;
940
940
  }
@@ -1080,7 +1080,7 @@ function qn(e, t, n) {
1080
1080
  commentWriteRole: t.commentWriteRole ?? "user",
1081
1081
  allowedStaffUids: Array.isArray(t.allowedStaffUids) ? t.allowedStaffUids : [],
1082
1082
  allowedManagerUids: Array.isArray(t.allowedManagerUids) ? t.allowedManagerUids : [],
1083
- locale: P(t.locale) ?? "",
1083
+ locale: F(t.locale) ?? "",
1084
1084
  autoTranslate: t.autoTranslate === !0,
1085
1085
  autoTranslatePosts: t.autoTranslatePosts === !0,
1086
1086
  translationLocales: mt(t.translationLocales),
@@ -1089,7 +1089,7 @@ function qn(e, t, n) {
1089
1089
  };
1090
1090
  }
1091
1091
  function Jn() {
1092
- let e = () => N(), t = Z(), r = Me(), { isSignedIn: i, isAdmin: a, isStaff: s, user: c } = Wt(), { t: l, locale: u } = M(), { translateEntries: d } = Un(), f = F(() => G(S(t, e()), W("order", "asc"))), { data: m, pending: h } = ke(f, { ssrKey: p(e(), "boards") }), g = F(() => m.value.map((e, t) => qn(e.id, e, t))), _ = g, v = F(() => g.value.filter((e) => e.visibility !== "hidden")), y = v;
1092
+ let e = () => P(), t = Z(), r = Me(), { isSignedIn: i, isAdmin: a, isStaff: s, user: c } = Wt(), { t: l, locale: u } = N(), { translateEntries: d } = Un(), f = I(() => K(S(t, e()), G("order", "asc"))), { data: m, pending: h } = ke(f, { ssrKey: p(e(), "boards") }), g = I(() => m.value.map((e, t) => qn(e.id, e, t))), _ = g, v = I(() => g.value.filter((e) => e.visibility !== "hidden")), y = v;
1093
1093
  function b(e, t) {
1094
1094
  if (!e) return;
1095
1095
  let n = g.value.find((t) => t.id === e);
@@ -1105,20 +1105,20 @@ function Jn() {
1105
1105
  function D(e) {
1106
1106
  return e ? g.value.find((t) => t.id === e)?.visibility ?? "public" : "public";
1107
1107
  }
1108
- let O = D;
1109
- function k(e) {
1108
+ let ee = D;
1109
+ function O(e) {
1110
1110
  return D(e) === "hidden";
1111
1111
  }
1112
- let ee = k;
1112
+ let k = O;
1113
1113
  function A(e) {
1114
1114
  if (e) return g.value.find((t) => t.id === e);
1115
1115
  }
1116
1116
  Nt((e) => A(e));
1117
- function te(e) {
1117
+ function j(e) {
1118
1118
  return At(c.value?.uid, a.value, s.value, e ? A(e) : void 0);
1119
1119
  }
1120
- let ne = F(() => g.value.filter((e) => te(e.id)));
1121
- function re(e, t) {
1120
+ let te = I(() => g.value.filter((e) => j(e.id)));
1121
+ function ne(e, t) {
1122
1122
  return {
1123
1123
  label: e.label.trim(),
1124
1124
  description: (e.description ?? "").trim(),
@@ -1129,17 +1129,17 @@ function Jn() {
1129
1129
  commentWriteRole: e.commentWriteRole ?? "user",
1130
1130
  allowedStaffUids: e.allowedStaffUids ?? [],
1131
1131
  allowedManagerUids: e.allowedManagerUids ?? [],
1132
- locale: P(e.locale) ?? "",
1132
+ locale: F(e.locale) ?? "",
1133
1133
  autoTranslate: e.autoTranslate === !0,
1134
1134
  autoTranslatePosts: e.autoTranslatePosts === !0,
1135
1135
  translationLocales: mt(e.translationLocales),
1136
1136
  ...e.i18n ? { i18n: e.i18n } : {},
1137
1137
  ...e.i18nSource ? { i18nSource: e.i18nSource } : {},
1138
1138
  order: t,
1139
- updatedAt: K()
1139
+ updatedAt: q()
1140
1140
  };
1141
1141
  }
1142
- async function ie(e) {
1142
+ async function re(e) {
1143
1143
  if (!n()) return e;
1144
1144
  let t = e.label.trim(), r = (e.description ?? "").trim();
1145
1145
  if (!t) return e;
@@ -1176,40 +1176,40 @@ function Jn() {
1176
1176
  }
1177
1177
  };
1178
1178
  }
1179
- async function j(n, r = n.order ?? 0) {
1179
+ async function M(n, r = n.order ?? 0) {
1180
1180
  if (!i.value) throw Error(l("boardSettings.signInRequired"));
1181
1181
  let a = n.id.trim(), o = n.label.trim();
1182
1182
  if (!a || !o) throw Error(l("boardSettings.idAndNameRequired"));
1183
- let s = Kn(n.visibility), c = re({
1183
+ let s = Kn(n.visibility), c = ne({
1184
1184
  ...n,
1185
1185
  label: o,
1186
1186
  visibility: s
1187
1187
  }, r);
1188
1188
  await xn(t, e(), a, c);
1189
1189
  }
1190
- let ae = j;
1191
- async function oe(e) {
1190
+ let ie = M;
1191
+ async function ae(e) {
1192
1192
  if (!i.value) throw Error(l("boardSettings.signInRequired"));
1193
1193
  for (let t of e) if (!t.id.trim() || !t.label.trim()) throw Error(l("boardSettings.idAndNameRequired"));
1194
- for (let [t, n] of e.entries()) await j(n, t);
1194
+ for (let [t, n] of e.entries()) await M(n, t);
1195
1195
  }
1196
- let se = oe;
1197
- async function ce(n) {
1196
+ let oe = ae;
1197
+ async function se(n) {
1198
1198
  if (!i.value) throw Error(l("boardSettings.signInRequired"));
1199
1199
  let a = n.trim();
1200
1200
  if (!a) throw Error(l("boardSettings.deleteIdRequired"));
1201
1201
  for (;;) {
1202
- let n = await V(G(o(t, e()), X("boardId", "==", a), H(25)));
1202
+ let n = await H(K(o(t, e()), X("boardId", "==", a), U(25)));
1203
1203
  if (n.empty) break;
1204
1204
  for (let i of n.docs) await cn(t, We(r), e(), i.id);
1205
1205
  }
1206
- await _e(w(t, e(), n));
1206
+ await ge(w(t, e(), n));
1207
1207
  }
1208
- let le = ce;
1209
- async function ue() {
1208
+ let ce = se;
1209
+ async function le() {
1210
1210
  return Promise.resolve();
1211
1211
  }
1212
- async function de(e) {
1212
+ async function ue(e) {
1213
1213
  let t = e.trim();
1214
1214
  if (!t) throw Error(l("boardSettings.nameRequired"));
1215
1215
  if (!i.value) throw Error(l("boardSettings.signInRequired"));
@@ -1217,7 +1217,7 @@ function Jn() {
1217
1217
  if (n) return n.id;
1218
1218
  let r = E(t) || `board-${Date.now()}`, a = r, o = 2, s = new Set(g.value.map((e) => e.id));
1219
1219
  for (; s.has(a);) a = `${r}-${o++}`;
1220
- return await j({
1220
+ return await M({
1221
1221
  id: a,
1222
1222
  label: t,
1223
1223
  visibility: "public",
@@ -1234,27 +1234,27 @@ function Jn() {
1234
1234
  boardLabel: b,
1235
1235
  boardDescription: C,
1236
1236
  boardVisibility: D,
1237
- isBoardHidden: k,
1237
+ isBoardHidden: O,
1238
1238
  getBoard: A,
1239
- canManageBoard: te,
1240
- managedBoards: ne,
1239
+ canManageBoard: j,
1240
+ managedBoards: te,
1241
1241
  categories: _,
1242
1242
  publicCategories: y,
1243
1243
  categoryLabel: x,
1244
1244
  categoryDescription: T,
1245
- categoryVisibility: O,
1246
- isCategoryHidden: ee,
1245
+ categoryVisibility: ee,
1246
+ isCategoryHidden: k,
1247
1247
  settingsPending: h,
1248
- ensureSettings: ue,
1249
- addBoard: de,
1250
- addCategory: de,
1251
- saveBoard: j,
1252
- saveCategory: ae,
1253
- translateBoard: ie,
1254
- saveBoards: oe,
1255
- saveCategories: se,
1256
- deleteBoard: ce,
1257
- deleteCategory: le,
1248
+ ensureSettings: le,
1249
+ addBoard: ue,
1250
+ addCategory: ue,
1251
+ saveBoard: M,
1252
+ saveCategory: ie,
1253
+ translateBoard: re,
1254
+ saveBoards: ae,
1255
+ saveCategories: oe,
1256
+ deleteBoard: se,
1257
+ deleteCategory: ce,
1258
1258
  DEFAULT_BOARDS: Wn,
1259
1259
  DEFAULT_CATEGORIES: Gn
1260
1260
  };
@@ -1268,12 +1268,12 @@ function Xn(e) {
1268
1268
  return t === "permission-denied" || t === "firestore/permission-denied";
1269
1269
  }
1270
1270
  function Zn(e, t) {
1271
- let n = R(e)?.trim();
1272
- if (!n) throw Error(j(t, "posts.boardIdRequired"));
1271
+ let n = z(e)?.trim();
1272
+ if (!n) throw Error(M(t, "posts.boardIdRequired"));
1273
1273
  return n;
1274
1274
  }
1275
1275
  function Qn(e) {
1276
- let t = Z(), n = Me(), { isBoardHidden: r, getBoard: i } = Jn(), { user: a, canManageBoard: c } = Wt(), { t: l, locale: u } = M(), d = () => N(), f = () => Zn(e, u.value), p = () => o(t, d()), m = (e) => y(t, d(), e), h = (e) => s(t, d(), e);
1276
+ let t = Z(), n = Me(), { isBoardHidden: r, getBoard: i } = Jn(), { user: a, canManageBoard: c } = Wt(), { t: l, locale: u } = N(), d = () => P(), f = () => Zn(e, u.value), p = () => o(t, d()), m = (e) => y(t, d(), e), h = (e) => s(t, d(), e);
1277
1277
  function g(e, t, n) {
1278
1278
  return {
1279
1279
  id: e,
@@ -1301,15 +1301,15 @@ function Qn(e) {
1301
1301
  if (!e.title?.trim()) throw Error(l("posts.titleRequired"));
1302
1302
  }
1303
1303
  function x() {
1304
- return ye(p()).id;
1304
+ return ve(p()).id;
1305
1305
  }
1306
1306
  function S(e) {
1307
1307
  return Yt(t, d(), f(), e, a.value?.uid, c(f()));
1308
1308
  }
1309
1309
  async function C(e = {}) {
1310
1310
  let t = e.pageSize ?? 20, n = [X("boardId", "==", f()), X("isPublished", "==", !0)];
1311
- e.publicOnly !== !1 && n.push(X("listed", "==", !0)), n.push(W("createdAt", "desc")), e.cursor && n.push(J(e.cursor)), n.push(H(t + 1));
1312
- let r = await V(G(p(), ...n)), i = r.docs.slice(0, t);
1311
+ e.publicOnly !== !1 && n.push(X("listed", "==", !0)), n.push(G("createdAt", "desc")), e.cursor && n.push(J(e.cursor)), n.push(U(t + 1));
1312
+ let r = await H(K(p(), ...n)), i = r.docs.slice(0, t);
1313
1313
  return {
1314
1314
  posts: i.map((e) => ({
1315
1315
  id: e.id,
@@ -1320,7 +1320,7 @@ function Qn(e) {
1320
1320
  };
1321
1321
  }
1322
1322
  async function w(e) {
1323
- let [t, n] = await Promise.all([Se(m(e)), Se(h(e))]);
1323
+ let [t, n] = await Promise.all([xe(m(e)), xe(h(e))]);
1324
1324
  return t.exists() ? g(t.id, t.data(), n.exists() ? n.data() : void 0) : null;
1325
1325
  }
1326
1326
  async function T(e) {
@@ -1346,7 +1346,7 @@ function Qn(e) {
1346
1346
  };
1347
1347
  }
1348
1348
  }
1349
- async function O(e) {
1349
+ async function ee(e) {
1350
1350
  let t = e.trim(), n = Yn.get(`${f()}/${t}`);
1351
1351
  if (n) return {
1352
1352
  status: "ok",
@@ -1365,10 +1365,10 @@ function Qn(e) {
1365
1365
  };
1366
1366
  }
1367
1367
  }
1368
- async function k(e) {
1368
+ async function O(e) {
1369
1369
  return `${E(e.trim()) || "post"}-${x()}`;
1370
1370
  }
1371
- async function ee(e) {
1371
+ async function k(e) {
1372
1372
  if (!e.createdAt) return {
1373
1373
  previous: null,
1374
1374
  next: null
@@ -1378,8 +1378,8 @@ function Qn(e) {
1378
1378
  X("boardId", "==", f()),
1379
1379
  X("isPublished", "==", !0),
1380
1380
  ...e.listed === !1 ? [] : [X("listed", "==", !0)],
1381
- W("createdAt", "desc")
1382
- ], [n, r] = await Promise.all([V(G(p(), ...t, J(e.createdAt), H(1))), V(G(p(), ...t, xe(e.createdAt), Ee(1)))]), i = (e) => {
1381
+ G("createdAt", "desc")
1382
+ ], [n, r] = await Promise.all([H(K(p(), ...t, J(e.createdAt), U(1))), H(K(p(), ...t, be(e.createdAt), Te(1)))]), i = (e) => {
1383
1383
  let t = e.docs[0];
1384
1384
  return t ? {
1385
1385
  id: t.id,
@@ -1400,7 +1400,7 @@ function Qn(e) {
1400
1400
  async function A(e) {
1401
1401
  b(e);
1402
1402
  let n = e.postId || x(), r = v(), i, a;
1403
- r ? (i = n, a = un(e.content)) : (a = e.title.trim(), i = e.slug?.trim() || await k(a));
1403
+ r ? (i = n, a = un(e.content)) : (a = e.title.trim(), i = e.slug?.trim() || await O(a));
1404
1404
  let o = _n(e.content, e.attachments), s = _(), c = Oe(t);
1405
1405
  return c.set(m(n), {
1406
1406
  boardId: f(),
@@ -1419,8 +1419,8 @@ function Qn(e) {
1419
1419
  authorPhoto: e.authorPhoto,
1420
1420
  moderationStatus: "approved",
1421
1421
  moderationModel: e.moderationModel ?? null,
1422
- createdAt: K(),
1423
- updatedAt: K(),
1422
+ createdAt: q(),
1423
+ updatedAt: q(),
1424
1424
  ...e.translations ? {
1425
1425
  i18n: e.translations.i18n,
1426
1426
  i18nSource: e.translations.i18nSource
@@ -1433,63 +1433,63 @@ function Qn(e) {
1433
1433
  } : {}
1434
1434
  }), await c.commit(), Yn.set(`${f()}/${i}`, n), i;
1435
1435
  }
1436
- async function te(e, t) {
1436
+ async function j(e, t) {
1437
1437
  b(t);
1438
1438
  let n = v() ? un(t.content) : t.title.trim(), r = _n(t.content, t.attachments), i = _();
1439
1439
  await Promise.all([Y(m(e), {
1440
1440
  title: n,
1441
1441
  ...r,
1442
- previewImage: r.previewImage ? r.previewImage : ve(),
1443
- videoUrl: r.videoUrl ? r.videoUrl : ve(),
1442
+ previewImage: r.previewImage ? r.previewImage : _e(),
1443
+ videoUrl: r.videoUrl ? r.videoUrl : _e(),
1444
1444
  tags: t.tags ?? [],
1445
1445
  listed: i,
1446
1446
  attachments: t.attachments ?? [],
1447
- updatedAt: K(),
1447
+ updatedAt: q(),
1448
1448
  ...t.translations ? {
1449
1449
  i18n: t.translations.i18n,
1450
1450
  i18nSource: t.translations.i18nSource
1451
1451
  } : {}
1452
- }), q(h(e), {
1452
+ }), De(h(e), {
1453
1453
  content: t.content,
1454
1454
  ...t.translations ? t.translations.contentI18n ? {
1455
1455
  i18n: t.translations.contentI18n,
1456
1456
  i18nSource: t.translations.contentI18nSource
1457
1457
  } : {
1458
- i18n: ve(),
1459
- i18nSource: ve()
1458
+ i18n: _e(),
1459
+ i18nSource: _e()
1460
1460
  } : {}
1461
1461
  }, { merge: !0 })]);
1462
1462
  }
1463
- async function ne(e, t) {
1463
+ async function te(e, t) {
1464
1464
  D(), await Promise.all([Y(m(e), {
1465
1465
  i18n: t.i18n,
1466
1466
  i18nSource: t.i18nSource,
1467
- updatedAt: K()
1468
- }), q(h(e), t.contentI18n ? {
1467
+ updatedAt: q()
1468
+ }), De(h(e), t.contentI18n ? {
1469
1469
  i18n: t.contentI18n,
1470
1470
  i18nSource: t.contentI18nSource
1471
1471
  } : {
1472
- i18n: ve(),
1473
- i18nSource: ve()
1472
+ i18n: _e(),
1473
+ i18nSource: _e()
1474
1474
  }, { merge: !0 })]);
1475
1475
  }
1476
- async function re(e) {
1476
+ async function ne(e) {
1477
1477
  await Y(m(e), {
1478
1478
  isPublished: !0,
1479
- publishedAt: K(),
1480
- updatedAt: K()
1479
+ publishedAt: q(),
1480
+ updatedAt: q()
1481
1481
  });
1482
1482
  }
1483
- async function ie(e, t) {
1483
+ async function re(e, t) {
1484
1484
  await Y(m(e), t ? {
1485
1485
  pinned: !0,
1486
- pinnedAt: K()
1486
+ pinnedAt: q()
1487
1487
  } : {
1488
- pinned: ve(),
1489
- pinnedAt: ve()
1488
+ pinned: _e(),
1489
+ pinnedAt: _e()
1490
1490
  });
1491
1491
  }
1492
- async function j(e) {
1492
+ async function M(e) {
1493
1493
  await cn(t, We(n), d(), e);
1494
1494
  for (let [t, n] of Yn) n === e && Yn.delete(t);
1495
1495
  }
@@ -1498,24 +1498,24 @@ function Qn(e) {
1498
1498
  getPosts: C,
1499
1499
  getPost: w,
1500
1500
  getPostBySlug: T,
1501
- resolvePostIdBySlug: O,
1502
- resolveUniqueSlug: k,
1503
- getAdjacentPosts: ee,
1501
+ resolvePostIdBySlug: ee,
1502
+ resolveUniqueSlug: O,
1503
+ getAdjacentPosts: k,
1504
1504
  createPost: A,
1505
- updatePost: te,
1506
- savePostTranslations: ne,
1507
- publishPost: re,
1508
- setPostPinned: ie,
1509
- deletePost: j
1505
+ updatePost: j,
1506
+ savePostTranslations: te,
1507
+ publishPost: ne,
1508
+ setPostPinned: re,
1509
+ deletePost: M
1510
1510
  };
1511
1511
  }
1512
1512
  var $n = 10, er = 10;
1513
1513
  function tr(e, t = {}) {
1514
- let n = Z(), { isAdmin: r, user: i, canManageBoard: a } = Wt(), s = () => N(), c = t.pageSize ?? $n, l = F(() => i.value?.uid ?? ""), u = F(() => Zn(e)), d = () => o(n, s()), f = F(() => t.publicOnly === void 0 ? !(r.value || a(u.value)) : typeof t.publicOnly == "boolean" ? t.publicOnly : t.publicOnly.value), p = L([]), m = L([]), h = L([]), g = L([]), _ = L(!0), v = L(!0), y = L(!0), b = L(!1), x = L(""), S = null, C = null, w, T, E;
1514
+ let n = Z(), { isAdmin: r, user: i, canManageBoard: a } = Wt(), s = () => P(), c = t.pageSize ?? $n, l = I(() => i.value?.uid ?? ""), u = I(() => Zn(e)), d = () => o(n, s()), f = I(() => t.publicOnly === void 0 ? !(r.value || a(u.value)) : typeof t.publicOnly == "boolean" ? t.publicOnly : t.publicOnly.value), p = R([]), m = R([]), h = R([]), g = R([]), _ = R(!0), v = R(!0), y = R(!0), b = R(!1), x = R(""), S = null, C = null, w, T, E;
1515
1515
  function D(e) {
1516
1516
  return e.createdAt?.toMillis?.() ?? 0;
1517
1517
  }
1518
- let O = F(() => {
1518
+ let ee = I(() => {
1519
1519
  let e = new Set(g.value.map((e) => e.id)), t = /* @__PURE__ */ new Map();
1520
1520
  for (let n of [
1521
1521
  ...m.value,
@@ -1524,12 +1524,12 @@ function tr(e, t = {}) {
1524
1524
  ]) n.id && !e.has(n.id) && t.set(n.id, n);
1525
1525
  return [...t.values()].sort((e, t) => D(t) - D(e) || String(t.id).localeCompare(String(e.id)));
1526
1526
  });
1527
- function k() {
1527
+ function O() {
1528
1528
  let e = [X("boardId", "==", u.value), X("isPublished", "==", !0)];
1529
1529
  return f.value && e.push(X("listed", "==", !0)), e;
1530
1530
  }
1531
- function ee() {
1532
- w?.(), w = U(G(d(), ...k(), W("createdAt", "desc"), W(B(), "desc"), H(c)), (e) => {
1531
+ function k() {
1532
+ w?.(), w = W(K(d(), ...O(), G("createdAt", "desc"), G(V(), "desc"), U(c)), (e) => {
1533
1533
  p.value = e.docs.map((e) => ({
1534
1534
  id: e.id,
1535
1535
  ...e.data()
@@ -1539,7 +1539,7 @@ function tr(e, t = {}) {
1539
1539
  });
1540
1540
  }
1541
1541
  function A() {
1542
- E?.(), E = U(G(d(), ...k(), X("pinned", "==", !0), W("pinnedAt", "desc"), H(er)), (e) => {
1542
+ E?.(), E = W(K(d(), ...O(), X("pinned", "==", !0), G("pinnedAt", "desc"), U(er)), (e) => {
1543
1543
  g.value = e.docs.map((e) => ({
1544
1544
  id: e.id,
1545
1545
  ...e.data()
@@ -1548,14 +1548,14 @@ function tr(e, t = {}) {
1548
1548
  console.error("[memi-board:postList] notice onSnapshot failed", e), g.value = [], _.value = !1;
1549
1549
  });
1550
1550
  }
1551
- function te() {
1551
+ function j() {
1552
1552
  T?.();
1553
1553
  let e = l.value;
1554
1554
  if (!e) {
1555
1555
  h.value = [];
1556
1556
  return;
1557
1557
  }
1558
- T = U(G(d(), X("boardId", "==", u.value), X("authorUid", "==", e), X("isPublished", "==", !1), W("createdAt", "desc"), H(20)), (e) => {
1558
+ T = W(K(d(), X("boardId", "==", u.value), X("authorUid", "==", e), X("isPublished", "==", !1), G("createdAt", "desc"), U(20)), (e) => {
1559
1559
  h.value = e.docs.map((e) => ({
1560
1560
  id: e.id,
1561
1561
  ...e.data()
@@ -1564,17 +1564,17 @@ function tr(e, t = {}) {
1564
1564
  console.error("[memi-board:postList] own draft onSnapshot failed", e);
1565
1565
  });
1566
1566
  }
1567
- async function ne() {
1567
+ async function te() {
1568
1568
  if (!(b.value || !y.value || v.value)) {
1569
1569
  b.value = !0, x.value = "";
1570
1570
  try {
1571
1571
  let e = C ?? S, t = [
1572
- ...k(),
1573
- W("createdAt", "desc"),
1574
- W(B(), "desc"),
1572
+ ...O(),
1573
+ G("createdAt", "desc"),
1574
+ G(V(), "desc"),
1575
1575
  ...e ? [J(e)] : [],
1576
- H(c + 1)
1577
- ], n = await V(G(d(), ...t)), r = n.docs.slice(0, c), i = r.map((e) => ({
1576
+ U(c + 1)
1577
+ ], n = await H(K(d(), ...t)), r = n.docs.slice(0, c), i = r.map((e) => ({
1578
1578
  id: e.id,
1579
1579
  ...e.data()
1580
1580
  })), a = new Set([...m.value, ...p.value].map((e) => e.id));
@@ -1586,29 +1586,29 @@ function tr(e, t = {}) {
1586
1586
  }
1587
1587
  }
1588
1588
  }
1589
- function re() {
1590
- w?.(), p.value = [], m.value = [], S = null, C = null, y.value = !0, x.value = "", v.value = !0, g.value = [], _.value = !0, ee(), A(), te();
1589
+ function ne() {
1590
+ w?.(), p.value = [], m.value = [], S = null, C = null, y.value = !0, x.value = "", v.value = !0, g.value = [], _.value = !0, k(), A(), j();
1591
1591
  }
1592
- return z([
1592
+ return B([
1593
1593
  u,
1594
1594
  f,
1595
1595
  l
1596
- ], re, { immediate: !0 }), I(() => {
1596
+ ], ne, { immediate: !0 }), L(() => {
1597
1597
  w?.(), E?.(), T?.();
1598
1598
  }), {
1599
- posts: O,
1599
+ posts: ee,
1600
1600
  notices: g,
1601
- postsPending: F(() => v.value || _.value),
1601
+ postsPending: I(() => v.value || _.value),
1602
1602
  hasMore: y,
1603
1603
  loadingMore: b,
1604
1604
  loadError: x,
1605
- loadMore: ne
1605
+ loadMore: te
1606
1606
  };
1607
1607
  }
1608
1608
  function nr(e, t) {
1609
- let n = Z(), r = () => N(), i = F(() => Zn(e)), a = F(() => typeof t == "string" ? t : t.value), o = F(() => y(n, r(), a.value)), c = F(() => s(n, r(), a.value)), { data: l, pending: u } = je(o), { data: d, pending: f } = je(c);
1609
+ let n = Z(), r = () => P(), i = I(() => Zn(e)), a = I(() => typeof t == "string" ? t : t.value), o = I(() => y(n, r(), a.value)), c = I(() => s(n, r(), a.value)), { data: l, pending: u } = je(o), { data: d, pending: f } = je(c);
1610
1610
  return {
1611
- post: F(() => {
1611
+ post: I(() => {
1612
1612
  if (!l.value || l.value.boardId !== i.value) return null;
1613
1613
  let e = d.value;
1614
1614
  return {
@@ -1621,14 +1621,14 @@ function nr(e, t) {
1621
1621
  contentI18nSource: dt(e?.i18nSource)
1622
1622
  };
1623
1623
  }),
1624
- pending: F(() => u.value || f.value)
1624
+ pending: I(() => u.value || f.value)
1625
1625
  };
1626
1626
  }
1627
1627
  //#endregion
1628
1628
  //#region src/composables/useMemiBoardUserPosts.ts
1629
1629
  var rr = 10;
1630
1630
  function ir(e, t = {}) {
1631
- let n = Z(), r = () => N(), i = () => o(n, r()), a = t.pageSize ?? rr, s = F(() => R(e)?.trim() || ""), c = L([]), l = L([]), u = L(!0), d = L(!0), f = L(!1), p = L(""), m = null, h = null, g;
1631
+ let n = Z(), r = () => P(), i = () => o(n, r()), a = t.pageSize ?? rr, s = I(() => z(e)?.trim() || ""), c = R([]), l = R([]), u = R(!0), d = R(!0), f = R(!1), p = R(""), m = null, h = null, g;
1632
1632
  function _(e) {
1633
1633
  return {
1634
1634
  id: e.id,
@@ -1638,7 +1638,7 @@ function ir(e, t = {}) {
1638
1638
  function v(e) {
1639
1639
  return e.createdAt?.toMillis?.() ?? 0;
1640
1640
  }
1641
- let y = F(() => {
1641
+ let y = I(() => {
1642
1642
  let e = /* @__PURE__ */ new Map();
1643
1643
  for (let t of [...l.value, ...c.value]) t.id && e.set(t.id, t);
1644
1644
  return [...e.values()].sort((e, t) => v(t) - v(e) || String(t.id).localeCompare(String(e.id)));
@@ -1655,7 +1655,7 @@ function ir(e, t = {}) {
1655
1655
  u.value = !1;
1656
1656
  return;
1657
1657
  }
1658
- g = U(G(i(), ...b(), W("createdAt", "desc"), W(B(), "desc"), H(a)), (e) => {
1658
+ g = W(K(i(), ...b(), G("createdAt", "desc"), G(V(), "desc"), U(a)), (e) => {
1659
1659
  c.value = e.docs.map(_), m = e.docs.at(-1) ?? null, h || (d.value = e.docs.length >= a), u.value = !1;
1660
1660
  }, (e) => {
1661
1661
  console.error("[memi-board:userPosts] onSnapshot failed", e), p.value = e.message || String(e), u.value = !1;
@@ -1667,11 +1667,11 @@ function ir(e, t = {}) {
1667
1667
  try {
1668
1668
  let e = h ?? m, t = [
1669
1669
  ...b(),
1670
- W("createdAt", "desc"),
1671
- W(B(), "desc"),
1670
+ G("createdAt", "desc"),
1671
+ G(V(), "desc"),
1672
1672
  ...e ? [J(e)] : [],
1673
- H(a + 1)
1674
- ], n = await V(G(i(), ...t)), r = n.docs.slice(0, a), o = r.map(_), s = new Set([...l.value, ...c.value].map((e) => e.id));
1673
+ U(a + 1)
1674
+ ], n = await H(K(i(), ...t)), r = n.docs.slice(0, a), o = r.map(_), s = new Set([...l.value, ...c.value].map((e) => e.id));
1675
1675
  l.value.push(...o.filter((e) => !s.has(e.id))), h = r.at(-1) ?? h, d.value = n.docs.length > a;
1676
1676
  } catch (e) {
1677
1677
  p.value = e.message || String(e), console.error("[memi-board:userPosts] loadMore failed", e);
@@ -1683,7 +1683,7 @@ function ir(e, t = {}) {
1683
1683
  function C() {
1684
1684
  g?.(), c.value = [], l.value = [], m = null, h = null, d.value = !0, p.value = "", u.value = !0, x();
1685
1685
  }
1686
- return z(s, C, { immediate: !0 }), I(() => g?.()), {
1686
+ return B(s, C, { immediate: !0 }), L(() => g?.()), {
1687
1687
  posts: y,
1688
1688
  postsPending: u,
1689
1689
  hasMore: d,
@@ -1696,7 +1696,7 @@ function ir(e, t = {}) {
1696
1696
  //#region src/composables/useMemiBoardUserComments.ts
1697
1697
  var ar = 10;
1698
1698
  function or(e, t = {}) {
1699
- let n = Z(), r = () => N(), i = () => g(n, r()), a = t.pageSize ?? ar, o = F(() => R(e)?.trim() || ""), s = L([]), c = L([]), l = L(!0), u = L(!0), d = L(!1), f = L(""), p = null, m = null, h;
1699
+ let n = Z(), r = () => P(), i = () => g(n, r()), a = t.pageSize ?? ar, o = I(() => z(e)?.trim() || ""), s = R([]), c = R([]), l = R(!0), u = R(!0), d = R(!1), f = R(""), p = null, m = null, h;
1700
1700
  function _(e) {
1701
1701
  return {
1702
1702
  id: e.id,
@@ -1706,7 +1706,7 @@ function or(e, t = {}) {
1706
1706
  function v(e) {
1707
1707
  return e.createdAt?.toMillis?.() ?? 0;
1708
1708
  }
1709
- let y = F(() => {
1709
+ let y = I(() => {
1710
1710
  let e = /* @__PURE__ */ new Map();
1711
1711
  for (let t of [...c.value, ...s.value]) t.id && e.set(t.id, t);
1712
1712
  return [...e.values()].sort((e, t) => v(t) - v(e) || String(t.id).localeCompare(String(e.id)));
@@ -1719,7 +1719,7 @@ function or(e, t = {}) {
1719
1719
  l.value = !1;
1720
1720
  return;
1721
1721
  }
1722
- h = U(G(i(), ...b(), W("createdAt", "desc"), W(B(), "desc"), H(a)), (e) => {
1722
+ h = W(K(i(), ...b(), G("createdAt", "desc"), G(V(), "desc"), U(a)), (e) => {
1723
1723
  s.value = e.docs.map(_), p = e.docs.at(-1) ?? null, m || (u.value = e.docs.length >= a), l.value = !1;
1724
1724
  }, (e) => {
1725
1725
  console.error("[memi-board:userComments] onSnapshot failed", e), f.value = e.message || String(e), l.value = !1;
@@ -1731,11 +1731,11 @@ function or(e, t = {}) {
1731
1731
  try {
1732
1732
  let e = m ?? p, t = [
1733
1733
  ...b(),
1734
- W("createdAt", "desc"),
1735
- W(B(), "desc"),
1734
+ G("createdAt", "desc"),
1735
+ G(V(), "desc"),
1736
1736
  ...e ? [J(e)] : [],
1737
- H(a + 1)
1738
- ], n = await V(G(i(), ...t)), r = n.docs.slice(0, a), o = r.map(_), l = new Set([...c.value, ...s.value].map((e) => e.id));
1737
+ U(a + 1)
1738
+ ], n = await H(K(i(), ...t)), r = n.docs.slice(0, a), o = r.map(_), l = new Set([...c.value, ...s.value].map((e) => e.id));
1739
1739
  c.value.push(...o.filter((e) => !l.has(e.id))), m = r.at(-1) ?? m, u.value = n.docs.length > a;
1740
1740
  } catch (e) {
1741
1741
  f.value = e.message || String(e), console.error("[memi-board:userComments] loadMore failed", e);
@@ -1747,7 +1747,7 @@ function or(e, t = {}) {
1747
1747
  function C() {
1748
1748
  h?.(), s.value = [], c.value = [], p = null, m = null, u.value = !0, f.value = "", l.value = !0, x();
1749
1749
  }
1750
- return z(o, C, { immediate: !0 }), I(() => h?.()), {
1750
+ return B(o, C, { immediate: !0 }), L(() => h?.()), {
1751
1751
  comments: y,
1752
1752
  commentsPending: l,
1753
1753
  hasMore: u,
@@ -1760,10 +1760,10 @@ function or(e, t = {}) {
1760
1760
  //#region src/composables/useMemiBoardCommentFeed.ts
1761
1761
  var sr = 10;
1762
1762
  function cr(e = "latest", t = {}) {
1763
- let n = Z(), r = () => N(), i = () => g(n, r()), a = F(() => {
1764
- let e = Math.floor(Number(R(t.pageSize)));
1763
+ let n = Z(), r = () => P(), i = () => g(n, r()), a = I(() => {
1764
+ let e = Math.floor(Number(z(t.pageSize)));
1765
1765
  return Number.isFinite(e) && e > 0 ? e : sr;
1766
- }), o = F(() => R(e) === "likes" ? "likes" : "latest"), s = L([]), c = L([]), l = L(!0), u = L(!0), d = L(!1), f = L(""), p = null, m = null, h;
1766
+ }), o = I(() => z(e) === "likes" ? "likes" : "latest"), s = R([]), c = R([]), l = R(!0), u = R(!0), d = R(!1), f = R(""), p = null, m = null, h;
1767
1767
  function _(e) {
1768
1768
  return {
1769
1769
  id: e.id,
@@ -1780,7 +1780,7 @@ function cr(e = "latest", t = {}) {
1780
1780
  }
1781
1781
  return v(t) - v(e) || String(t.id).localeCompare(String(e.id));
1782
1782
  }
1783
- let b = F(() => {
1783
+ let b = I(() => {
1784
1784
  let e = /* @__PURE__ */ new Map();
1785
1785
  for (let t of [...c.value, ...s.value]) t.id && e.set(t.id, t);
1786
1786
  return [...e.values()].sort(y);
@@ -1788,17 +1788,17 @@ function cr(e = "latest", t = {}) {
1788
1788
  function x() {
1789
1789
  return o.value === "likes" ? [
1790
1790
  X("listed", "==", !0),
1791
- W("likeCount", "desc"),
1792
- W("createdAt", "desc"),
1793
- W(B(), "desc")
1791
+ G("likeCount", "desc"),
1792
+ G("createdAt", "desc"),
1793
+ G(V(), "desc")
1794
1794
  ] : [
1795
1795
  X("listed", "==", !0),
1796
- W("createdAt", "desc"),
1797
- W(B(), "desc")
1796
+ G("createdAt", "desc"),
1797
+ G(V(), "desc")
1798
1798
  ];
1799
1799
  }
1800
1800
  function S() {
1801
- h?.(), h = U(G(i(), ...x(), H(a.value)), (e) => {
1801
+ h?.(), h = W(K(i(), ...x(), U(a.value)), (e) => {
1802
1802
  s.value = e.docs.map(_), p = e.docs.at(-1) ?? null, m || (u.value = e.docs.length >= a.value), l.value = !1;
1803
1803
  }, (e) => {
1804
1804
  console.error("[memi-board:commentFeed] onSnapshot failed", e), f.value = e.message || String(e), l.value = !1;
@@ -1808,7 +1808,7 @@ function cr(e = "latest", t = {}) {
1808
1808
  if (!(d.value || !u.value || l.value)) {
1809
1809
  d.value = !0, f.value = "";
1810
1810
  try {
1811
- let e = m ?? p, t = await V(G(i(), ...x(), ...e ? [J(e)] : [], H(a.value + 1))), n = t.docs.slice(0, a.value), r = n.map(_), o = new Set([...c.value, ...s.value].map((e) => e.id));
1811
+ let e = m ?? p, t = await H(K(i(), ...x(), ...e ? [J(e)] : [], U(a.value + 1))), n = t.docs.slice(0, a.value), r = n.map(_), o = new Set([...c.value, ...s.value].map((e) => e.id));
1812
1812
  c.value.push(...r.filter((e) => !o.has(e.id))), m = n.at(-1) ?? m, u.value = t.docs.length > a.value;
1813
1813
  } catch (e) {
1814
1814
  f.value = e.message || String(e), console.error("[memi-board:commentFeed] loadMore failed", e);
@@ -1820,7 +1820,7 @@ function cr(e = "latest", t = {}) {
1820
1820
  function w() {
1821
1821
  h?.(), s.value = [], c.value = [], p = null, m = null, u.value = !0, f.value = "", l.value = !0, S();
1822
1822
  }
1823
- return z([o, a], w, { immediate: !0 }), I(() => h?.()), {
1823
+ return B([o, a], w, { immediate: !0 }), L(() => h?.()), {
1824
1824
  comments: b,
1825
1825
  commentsPending: l,
1826
1826
  hasMore: u,
@@ -1835,7 +1835,7 @@ function cr(e = "latest", t = {}) {
1835
1835
  var lr = 100, ur = /* @__PURE__ */ new Map();
1836
1836
  function $(e) {
1837
1837
  let t = ur.get(e);
1838
- return t || (t = me({
1838
+ return t || (t = pe({
1839
1839
  text: "",
1840
1840
  sentiment: null,
1841
1841
  loaded: !1,
@@ -1845,22 +1845,22 @@ function $(e) {
1845
1845
  }), ur.set(e, t)), t;
1846
1846
  }
1847
1847
  function dr(e) {
1848
- let t = Z(), n = () => N(), { user: r } = Wt(), { t: i, formatNumber: a } = M(), o = F(() => R(e)), s = F(() => `${r.value?.uid ?? ""}:${o.value}`), c = F(() => {
1848
+ let t = Z(), n = () => P(), { user: r } = Wt(), { t: i, formatNumber: a } = N(), o = I(() => z(e)), s = I(() => `${r.value?.uid ?? ""}:${o.value}`), c = I(() => {
1849
1849
  let e = r.value?.uid, i = o.value;
1850
1850
  return !e || !i ? null : f(t, n(), e, i);
1851
- }), l = F({
1851
+ }), l = I({
1852
1852
  get: () => $(s.value).text,
1853
1853
  set: (e) => {
1854
1854
  $(s.value).text = e;
1855
1855
  }
1856
- }), u = F(() => $(s.value).sentiment), d = F(() => $(s.value).loaded), p = F(() => $(s.value).pending), m = F(() => $(s.value).saving), h = F(() => $(s.value).error);
1856
+ }), u = I(() => $(s.value).sentiment), d = I(() => $(s.value).loaded), p = I(() => $(s.value).pending), m = I(() => $(s.value).saving), h = I(() => $(s.value).error);
1857
1857
  async function g() {
1858
1858
  let e = c.value;
1859
1859
  if (!e) return;
1860
1860
  let t = $(s.value);
1861
1861
  t.pending = !0, t.error = "";
1862
1862
  try {
1863
- let n = (await Se(e)).data();
1863
+ let n = (await xe(e)).data();
1864
1864
  t.text = n ? n.text ?? "" : "", t.sentiment = n ? n.sentiment ?? null : null, t.loaded = !0;
1865
1865
  } catch (e) {
1866
1866
  t.error = e.message || String(e), console.error("[memi-board:authorMemo] load failed", e);
@@ -1876,10 +1876,10 @@ function dr(e) {
1876
1876
  let o = $(s.value);
1877
1877
  o.saving = !0, o.error = "";
1878
1878
  try {
1879
- await q(n, {
1879
+ await De(n, {
1880
1880
  text: r,
1881
1881
  sentiment: t,
1882
- updatedAt: K()
1882
+ updatedAt: q()
1883
1883
  }), o.text = r, o.sentiment = t, o.loaded = !0;
1884
1884
  } catch (e) {
1885
1885
  throw o.error = e.message || String(e), console.error("[memi-board:authorMemo] save failed", e), e;
@@ -1893,7 +1893,7 @@ function dr(e) {
1893
1893
  let t = $(s.value);
1894
1894
  t.saving = !0, t.error = "";
1895
1895
  try {
1896
- await _e(e), t.text = "", t.sentiment = null, t.loaded = !0;
1896
+ await ge(e), t.text = "", t.sentiment = null, t.loaded = !0;
1897
1897
  } catch (e) {
1898
1898
  throw t.error = e.message || String(e), console.error("[memi-board:authorMemo] remove failed", e), e;
1899
1899
  } finally {
@@ -1914,7 +1914,7 @@ function dr(e) {
1914
1914
  }
1915
1915
  //#endregion
1916
1916
  //#region src/composables/useMemiBoardWritingAssistant.ts
1917
- var fr = 10, pr = 864e5, mr = 200, hr = {
1917
+ var fr = 20, pr = 864e5, mr = 200, hr = {
1918
1918
  proofread: "맞춤법, 띄어쓰기, 문법 오류만 고쳐라. 의미와 말투는 바꾸지 마라.",
1919
1919
  polish: "뜻과 작성자의 말투를 유지하면서 더 자연스럽고 읽기 좋은 문장으로 다듬어라.",
1920
1920
  continue: "앞의 맥락과 말투에 맞는 내용을 과장 없이 한두 문단 이어서 작성하라.",
@@ -1952,7 +1952,7 @@ function yr(e) {
1952
1952
  return !e || typeof e != "object" ? null : "toMillis" in e && typeof e.toMillis == "function" ? e.toMillis() : null;
1953
1953
  }
1954
1954
  function br(e = {}) {
1955
- let t = M(), n = F(() => P(R(e.locale)) ?? t.locale.value), r = (e, t) => j(n.value, e, t), i = Me(), a = Z(), o = Ae(), s = v(), { translateEntries: c, translateHtml: l, detectSourceLocale: u } = Un();
1955
+ let t = N(), n = I(() => F(z(e.locale)) ?? t.locale.value), r = (e, t) => M(n.value, e, t), i = Me(), a = Z(), o = Ae(), s = v(), { translateEntries: c, translateHtml: l, detectSourceLocale: u } = Un();
1956
1956
  function d(e, t) {
1957
1957
  let n = yr(e.aiWritingWindowAt), r = n != null && t - n < pr, i = Math.max(0, Math.floor(Number(e.aiWritingCount) || 0)), a = Math.max(0, Math.floor(Number(e.aiWritingPending) || 0));
1958
1958
  return {
@@ -1965,35 +1965,35 @@ function br(e = {}) {
1965
1965
  function f(e, t) {
1966
1966
  let n = e + pr, i = Math.max(1, Math.ceil((n - t) / 36e5));
1967
1967
  return Error(r("writingAssistant.dailyLimit", {
1968
- limit: 10,
1968
+ limit: 20,
1969
1969
  hours: i
1970
1970
  }));
1971
1971
  }
1972
1972
  async function p(e) {
1973
1973
  let t = o.value?.uid;
1974
1974
  if (!t) throw Error(r("writingAssistant.loginRequired"));
1975
- await De(a, async (n) => {
1976
- let i = h(a, N(), t), o = await n.get(i);
1975
+ await Ee(a, async (n) => {
1976
+ let i = h(a, P(), t), o = await n.get(i);
1977
1977
  if (!o.exists()) throw Error(r("writingAssistant.userMissing"));
1978
1978
  let s = o.data(), c = e(d(s, Date.now()), s);
1979
1979
  c && n.update(i, {
1980
1980
  ...c,
1981
- updatedAt: K()
1981
+ updatedAt: q()
1982
1982
  });
1983
1983
  });
1984
1984
  }
1985
1985
  async function m() {
1986
1986
  await p((e) => {
1987
- if (e.active && e.windowAt != null && e.count + e.pending >= 10) throw f(e.windowAt, Date.now());
1987
+ if (e.active && e.windowAt != null && e.count + e.pending >= 20) throw f(e.windowAt, Date.now());
1988
1988
  return e.active ? { aiWritingPending: e.pending + 1 } : {
1989
1989
  aiWritingCount: 0,
1990
1990
  aiWritingPending: 1,
1991
- aiWritingWindowAt: K()
1991
+ aiWritingWindowAt: q()
1992
1992
  };
1993
1993
  });
1994
1994
  }
1995
1995
  async function g() {
1996
- await p((e) => !e.active || e.pending < 1 || e.count >= 10 ? null : {
1996
+ await p((e) => !e.active || e.pending < 1 || e.count >= 20 ? null : {
1997
1997
  aiWritingCount: e.count + 1,
1998
1998
  aiWritingPending: e.pending - 1
1999
1999
  });
@@ -2088,7 +2088,7 @@ function br(e = {}) {
2088
2088
  if (s) {
2089
2089
  let e = {};
2090
2090
  for (let [t, n] of Object.entries(m)) {
2091
- let r = P(t);
2091
+ let r = F(t);
2092
2092
  r && typeof n == "string" && n.trim() && (e[r] = { content: n.trim() });
2093
2093
  }
2094
2094
  let t = ft(d, { content: a }, e);
@@ -2135,7 +2135,7 @@ function br(e = {}) {
2135
2135
  //#endregion
2136
2136
  //#region src/utils/subscribeCommentRange.ts
2137
2137
  function xr(e, t, n, r, i, a) {
2138
- return U(G(g(e, t), X("postId", "==", n), ...r.rootId ? [X("rootId", "==", r.rootId), X("isReply", "==", !0)] : [X("parentId", "==", null)], W("createdAt", "asc"), W(B(), "asc"), ...r.hasMore && r.cursor ? [be(r.cursor)] : []), (e) => i(e.docs.map((e) => ({
2138
+ return W(K(g(e, t), X("postId", "==", n), ...r.rootId ? [X("rootId", "==", r.rootId), X("isReply", "==", !0)] : [X("parentId", "==", null)], G("createdAt", "asc"), G(V(), "asc"), ...r.hasMore && r.cursor ? [ye(r.cursor)] : []), (e) => i(e.docs.map((e) => ({
2139
2139
  ...e.data(),
2140
2140
  id: e.id
2141
2141
  }))), a);
@@ -2150,107 +2150,115 @@ function Tr(e, { t, formatNumber: n }) {
2150
2150
  return r;
2151
2151
  }
2152
2152
  function Er(e, t, r = {}) {
2153
- let i = Z(), a = Me(), o = () => N(), { isBoardHidden: s, getBoard: c } = Jn(), { translateComment: l } = br(), u;
2154
- async function f(e, t) {
2155
- return n() ? t?.i18nSource.body === e ? t : c(_.value)?.autoTranslatePosts === !0 ? (u?.i18nSource.body !== e && (u = await l({
2156
- body: e,
2157
- targets: pt(c(_.value))
2158
- })), u) : {} : {};
2159
- }
2160
- let p = M(), { t: m } = p, h = () => g(i, o()), _ = F(() => R(e)), v = F(() => R(t)), b = () => !s(_.value), S = L([]), C = L(r.subscribe !== !1), w = L([]), T = L(!1), E = L(r.subscribe !== !1), D = L(r.subscribe !== !1), O = null, k = 0, ee = 0, A;
2153
+ let i = Z(), a = Me(), o = () => P(), { isBoardHidden: s, getBoard: c } = Jn(), { translateComment: l } = br(), u, f = R(!1);
2154
+ async function p(e, t) {
2155
+ if (f.value = !1, !n()) return {};
2156
+ if (t?.i18nSource.body === e) return t;
2157
+ if (c(v.value)?.autoTranslatePosts !== !0) return {};
2158
+ if (u?.i18nSource.body !== e) try {
2159
+ u = await l({
2160
+ body: e,
2161
+ targets: pt(c(v.value))
2162
+ });
2163
+ } catch (e) {
2164
+ return import.meta.dev && console.warn("[memi-board] comment auto-translation skipped", e), f.value = !0, {};
2165
+ }
2166
+ return u;
2167
+ }
2168
+ let m = N(), { t: h } = m, _ = () => g(i, o()), v = I(() => z(e)), b = I(() => z(t)), S = () => !s(v.value), C = R([]), w = R(r.subscribe !== !1), T = R([]), E = R(!1), D = R(r.subscribe !== !1), ee = R(r.subscribe !== !1), O = null, k = 0, A = 0, j;
2161
2169
  function te(e) {
2162
2170
  return e.createdAt?.toMillis?.() ?? 0;
2163
2171
  }
2164
- let ne = F(() => {
2172
+ let ne = I(() => {
2165
2173
  let e = /* @__PURE__ */ new Map();
2166
- for (let t of [...S.value, ...w.value]) t.id && e.set(t.id, t);
2174
+ for (let t of [...C.value, ...T.value]) t.id && e.set(t.id, t);
2167
2175
  return [...e.values()].sort((e, t) => te(e) - te(t) || String(e.id).localeCompare(String(t.id)));
2168
2176
  });
2169
- z([v, _], async ([e]) => {
2177
+ B([b, v], async ([e]) => {
2170
2178
  let t = ++k;
2171
- if (ee++, T.value = !1, w.value = [], S.value = [], O = null, A?.(), A = void 0, E.value = r.subscribe !== !1, r.subscribe !== !1) {
2172
- C.value = !0, D.value = !0;
2179
+ if (A++, E.value = !1, T.value = [], C.value = [], O = null, j?.(), j = void 0, D.value = r.subscribe !== !1, r.subscribe !== !1) {
2180
+ w.value = !0, ee.value = !0;
2173
2181
  try {
2174
- let n = V(G(h(), X("postId", "==", e), W("createdAt", "desc"), W(B(), "desc")));
2182
+ let n = H(K(_(), X("postId", "==", e), G("createdAt", "desc"), G(V(), "desc")));
2175
2183
  if (await Promise.all([n.then((e) => {
2176
2184
  if (t !== k) return;
2177
2185
  let n = e.docs.map((e) => ({
2178
2186
  id: e.id,
2179
2187
  ...e.data()
2180
2188
  }));
2181
- S.value = n.filter((e) => e.parentId === void 0);
2182
- }), ie()]), t !== k) return;
2189
+ C.value = n.filter((e) => e.parentId === void 0);
2190
+ }), M()]), t !== k) return;
2183
2191
  } finally {
2184
- t === k && (C.value = !1, D.value = !1);
2192
+ t === k && (w.value = !1, ee.value = !1);
2185
2193
  }
2186
2194
  }
2187
2195
  }, { immediate: !0 });
2188
2196
  function re() {
2189
- A?.();
2190
- let e = ++ee;
2191
- A = xr(i, o(), v.value, {
2197
+ j?.();
2198
+ let e = ++A;
2199
+ j = xr(i, o(), b.value, {
2192
2200
  cursor: O,
2193
- hasMore: E.value
2201
+ hasMore: D.value
2194
2202
  }, (t) => {
2195
- e === ee && (w.value = t);
2203
+ e === A && (T.value = t);
2196
2204
  }, (e) => {
2197
2205
  console.error("[memi-board:comments] onSnapshot failed", e);
2198
2206
  });
2199
2207
  }
2200
- async function ie() {
2201
- if (T.value || !E.value) return;
2208
+ async function M() {
2209
+ if (E.value || !D.value) return;
2202
2210
  let e = k;
2203
- T.value = !0;
2211
+ E.value = !0;
2204
2212
  try {
2205
2213
  let t = [
2206
- X("postId", "==", v.value),
2214
+ X("postId", "==", b.value),
2207
2215
  X("parentId", "==", null),
2208
- W("createdAt", "asc"),
2209
- W(B(), "asc"),
2216
+ G("createdAt", "asc"),
2217
+ G(V(), "asc"),
2210
2218
  ...O ? [J(O)] : [],
2211
- H(11)
2212
- ], n = await V(G(h(), ...t));
2219
+ U(11)
2220
+ ], n = await H(K(_(), ...t));
2213
2221
  if (e !== k) return;
2214
2222
  let r = n.docs.slice(0, Sr), i = r.map((e) => ({
2215
2223
  id: e.id,
2216
2224
  ...e.data()
2217
- })), a = new Set(w.value.map((e) => e.id));
2218
- w.value.push(...i.filter((e) => !a.has(e.id))), O = r.at(-1) ?? O, E.value = n.size > Sr, re();
2225
+ })), a = new Set(T.value.map((e) => e.id));
2226
+ T.value.push(...i.filter((e) => !a.has(e.id))), O = r.at(-1) ?? O, D.value = n.size > Sr, re();
2219
2227
  } finally {
2220
- e === k && (T.value = !1);
2228
+ e === k && (E.value = !1);
2221
2229
  }
2222
2230
  }
2223
- I(() => {
2224
- k++, ee++, A?.();
2231
+ L(() => {
2232
+ k++, A++, j?.();
2225
2233
  });
2226
- function j() {
2227
- return ye(h()).id;
2234
+ function ie() {
2235
+ return ve(_()).id;
2228
2236
  }
2229
2237
  function ae(e) {
2230
- if (!e) return ye(h());
2231
- if (!/^[A-Za-z0-9]{10,128}$/.test(e)) throw Error(m("commentForm.uploadFailed"));
2238
+ if (!e) return ve(_());
2239
+ if (!/^[A-Za-z0-9]{10,128}$/.test(e)) throw Error(h("commentForm.uploadFailed"));
2232
2240
  return d(i, o(), e);
2233
2241
  }
2234
2242
  function oe(e, t) {
2235
- let n = `${x(o(), v.value)}/comment-images/${e}/`;
2236
- return ce(t).filter((e) => e.path.startsWith(n));
2243
+ let n = `${x(o(), b.value)}/comment-images/${e}/`;
2244
+ return se(t).filter((e) => e.path.startsWith(n));
2237
2245
  }
2238
- async function se(e, t) {
2239
- let n = oe(t, e.images), r = Tr(e.body, p);
2246
+ async function le(e, t) {
2247
+ let n = oe(t, e.images), r = Tr(e.body, m);
2240
2248
  return {
2241
- postId: v.value,
2242
- boardId: _.value,
2243
- listed: b(),
2249
+ postId: b.value,
2250
+ boardId: v.value,
2251
+ listed: S(),
2244
2252
  body: r,
2245
- ...await f(r, e.translations),
2253
+ ...await p(r, e.translations),
2246
2254
  authorUid: e.authorUid,
2247
2255
  authorName: e.authorName,
2248
2256
  authorPhoto: e.authorPhoto,
2249
2257
  moderationStatus: "approved",
2250
2258
  replyCount: 0,
2251
2259
  likeCount: 0,
2252
- createdAt: K(),
2253
- updatedAt: K(),
2260
+ createdAt: q(),
2261
+ updatedAt: q(),
2254
2262
  ...n.length ? { images: n } : {}
2255
2263
  };
2256
2264
  }
@@ -2262,75 +2270,76 @@ function Er(e, t, r = {}) {
2262
2270
  async function de(e) {
2263
2271
  let t = Oe(i), n = ae(e.id);
2264
2272
  t.set(n, {
2265
- ...await se(e, n.id),
2273
+ ...await le(e, n.id),
2266
2274
  parentId: null,
2267
2275
  rootId: n.id,
2268
2276
  depth: 0,
2269
2277
  replyToUid: null,
2270
2278
  replyToName: null,
2271
2279
  isReply: !1
2272
- }), t.update(y(i, o(), v.value), { commentCount: Te(1) }), await t.commit();
2280
+ }), t.update(y(i, o(), b.value), { commentCount: we(1) }), await t.commit();
2273
2281
  }
2274
- async function fe(e) {
2275
- if (!e.parent.id) throw Error(m("comments.replyTargetNotFound"));
2282
+ async function F(e) {
2283
+ if (!e.parent.id) throw Error(h("comments.replyTargetNotFound"));
2276
2284
  let t = Oe(i), n = ae(e.id), r = e.parent.parentId == null ? e.parent.id : e.parent.rootId;
2277
- if (!r) throw Error(m("comments.threadNotFound"));
2285
+ if (!r) throw Error(h("comments.threadNotFound"));
2278
2286
  let a = Math.min((e.parent.depth ?? 0) + 1, 2);
2279
2287
  t.set(n, {
2280
- ...await se(e, n.id),
2288
+ ...await le(e, n.id),
2281
2289
  parentId: e.parent.id,
2282
2290
  rootId: r,
2283
2291
  depth: a,
2284
2292
  replyToUid: e.parent.authorUid,
2285
2293
  replyToName: e.parent.authorName,
2286
2294
  isReply: !0
2287
- }), t.update(d(i, o(), r), { replyCount: Te(1) }), t.update(y(i, o(), v.value), { commentCount: Te(1) }), await t.commit();
2295
+ }), t.update(d(i, o(), r), { replyCount: we(1) }), t.update(y(i, o(), b.value), { commentCount: we(1) }), await t.commit();
2288
2296
  }
2289
- async function P(e) {
2297
+ async function fe(e) {
2290
2298
  if (!e.id) return;
2291
- if (e.parentId == null && (e.replyCount ?? 0) > 0) throw Error(m("comments.hasRepliesCannotDelete"));
2292
- let t = le(e.images, `${x(o(), v.value)}/comment-images/${e.id}/`);
2299
+ if (e.parentId == null && (e.replyCount ?? 0) > 0) throw Error(h("comments.hasRepliesCannotDelete"));
2300
+ let t = ce(e.images, `${x(o(), b.value)}/comment-images/${e.id}/`);
2293
2301
  await sn(i, o(), e.id);
2294
2302
  let n = Oe(i);
2295
- n.delete(d(i, o(), e.id)), e.parentId && e.rootId && n.update(d(i, o(), e.rootId), { replyCount: Te(-1) }), n.update(y(i, o(), v.value), { commentCount: Te(-1) }), await n.commit(), await ue(t), w.value = w.value.filter((t) => t.id !== e.id), S.value = S.value.filter((t) => t.id !== e.id);
2303
+ n.delete(d(i, o(), e.id)), e.parentId && e.rootId && n.update(d(i, o(), e.rootId), { replyCount: we(-1) }), n.update(y(i, o(), b.value), { commentCount: we(-1) }), await n.commit(), await ue(t), T.value = T.value.filter((t) => t.id !== e.id), C.value = C.value.filter((t) => t.id !== e.id);
2296
2304
  }
2297
2305
  async function pe(e, t, n, r) {
2298
- let a = Tr(t, p), s = {
2306
+ let a = Tr(t, m), s = {
2299
2307
  body: a,
2300
- updatedAt: K()
2308
+ updatedAt: q()
2301
2309
  };
2302
2310
  if (n !== void 0) {
2303
2311
  let t = oe(e, n);
2304
- s.images = t.length ? t : ve();
2312
+ s.images = t.length ? t : _e();
2305
2313
  }
2306
2314
  await Y(d(i, o(), e), {
2307
2315
  ...s,
2308
- ...await f(a, r)
2316
+ ...await p(a, r)
2309
2317
  });
2310
2318
  }
2311
2319
  async function me(e, t, n) {
2312
2320
  await Y(d(i, o(), e), {
2313
2321
  isBlinded: t,
2314
- moderatedAt: K(),
2322
+ moderatedAt: q(),
2315
2323
  moderatedBy: n
2316
2324
  });
2317
2325
  }
2318
2326
  return {
2319
2327
  comments: ne,
2320
- commentsPending: F(() => D.value || C.value),
2321
- hasMore: E,
2322
- loadingMore: T,
2323
- loadMore: ie,
2324
- newCommentId: j,
2328
+ commentsPending: I(() => ee.value || w.value),
2329
+ hasMore: D,
2330
+ loadingMore: E,
2331
+ loadMore: M,
2332
+ newCommentId: ie,
2333
+ translationSkipped: f,
2325
2334
  addComment: de,
2326
- addReply: fe,
2335
+ addReply: F,
2327
2336
  updateComment: pe,
2328
2337
  setCommentBlinded: me,
2329
- deleteComment: P
2338
+ deleteComment: fe
2330
2339
  };
2331
2340
  }
2332
2341
  function Dr(e, t, n) {
2333
- let r = Z(), i = () => N(), a = () => g(r, i()), o = t.trim(), s = L([]), c = L(!1), l = L(!1), u = L(!0), d = null, f, p = 0, m = 0;
2342
+ let r = Z(), i = () => P(), a = () => g(r, i()), o = t.trim(), s = R([]), c = R(!1), l = R(!1), u = R(!0), d = null, f, p = 0, m = 0;
2334
2343
  function h(e) {
2335
2344
  return e.sort((e, t) => (e.createdAt?.toMillis?.() ?? 0) - (t.createdAt?.toMillis?.() ?? 0) || String(e.id).localeCompare(String(t.id)));
2336
2345
  }
@@ -2356,11 +2365,11 @@ function Dr(e, t, n) {
2356
2365
  X("postId", "==", o),
2357
2366
  X("rootId", "==", n),
2358
2367
  X("isReply", "==", !0),
2359
- W("createdAt", "asc"),
2360
- W(B(), "asc"),
2368
+ G("createdAt", "asc"),
2369
+ G(V(), "asc"),
2361
2370
  ...d ? [J(d)] : [],
2362
- H(6)
2363
- ], r = await V(G(a(), ...t));
2371
+ U(6)
2372
+ ], r = await H(K(a(), ...t));
2364
2373
  if (e !== p) return;
2365
2374
  let i = new Set(s.value.map((e) => e.id)), c = r.docs.slice(0, Cr), f = c.map((e) => ({
2366
2375
  id: e.id,
@@ -2377,7 +2386,7 @@ function Dr(e, t, n) {
2377
2386
  async function b() {
2378
2387
  y(), await v();
2379
2388
  }
2380
- return I(() => {
2389
+ return L(() => {
2381
2390
  p++, m++, f?.();
2382
2391
  }), {
2383
2392
  replies: s,
@@ -2391,21 +2400,21 @@ function Dr(e, t, n) {
2391
2400
  //#endregion
2392
2401
  //#region src/composables/useMemiBoardLikes.ts
2393
2402
  function Or(e, t) {
2394
- let n = () => N(), r = Z(), i = Ae(), { t: a } = M(), o = L(!1), s = L(!1), c;
2403
+ let n = () => P(), r = Z(), i = Ae(), { t: a } = N(), o = R(!1), s = R(!1), c;
2395
2404
  function l(e) {
2396
- return pe(r, n(), t, e);
2405
+ return fe(r, n(), t, e);
2397
2406
  }
2398
- z(i, (e) => {
2407
+ B(i, (e) => {
2399
2408
  if (c?.(), c = void 0, !e) {
2400
2409
  o.value = !1;
2401
2410
  return;
2402
2411
  }
2403
- c = U(l(e.uid), (e) => {
2412
+ c = W(l(e.uid), (e) => {
2404
2413
  o.value = e.exists();
2405
2414
  }, (e) => {
2406
2415
  console.error("[memi-board:likes] onSnapshot failed", e);
2407
2416
  });
2408
- }, { immediate: !0 }), I(() => c?.());
2417
+ }, { immediate: !0 }), L(() => c?.());
2409
2418
  async function u() {
2410
2419
  let c = i.value?.uid;
2411
2420
  if (!c) throw Error(a("likes.signInRequired"));
@@ -2413,12 +2422,12 @@ function Or(e, t) {
2413
2422
  s.value = !0;
2414
2423
  try {
2415
2424
  let i = l(c), a = y(r, n(), t);
2416
- return await De(r, async (n) => (await n.get(i)).exists() ? (n.delete(i), n.update(a, { likeCount: Te(-1) }), !1) : (n.set(i, {
2425
+ return await Ee(r, async (n) => (await n.get(i)).exists() ? (n.delete(i), n.update(a, { likeCount: we(-1) }), !1) : (n.set(i, {
2417
2426
  uid: c,
2418
2427
  postId: t,
2419
2428
  boardId: e,
2420
- createdAt: K()
2421
- }), n.update(a, { likeCount: Te(1) }), !0));
2429
+ createdAt: q()
2430
+ }), n.update(a, { likeCount: we(1) }), !0));
2422
2431
  } finally {
2423
2432
  s.value = !1;
2424
2433
  }
@@ -2431,9 +2440,9 @@ function Or(e, t) {
2431
2440
  }
2432
2441
  var kr = Symbol.for("memi-board:comment-likes");
2433
2442
  function Ar(e, t) {
2434
- let n = () => N(), r = Z(), i = Ae(), { t: a } = M(), o = F(() => R(e)), s = F(() => R(t)), c = L(/* @__PURE__ */ new Set()), l = L(null), u;
2435
- z([i, s], ([e, t]) => {
2436
- u?.(), u = void 0, c.value = /* @__PURE__ */ new Set(), e && t && (u = U(G(b(r, n()), X("uid", "==", e.uid), X("postId", "==", t), X("target", "==", "comment")), (e) => {
2443
+ let n = () => P(), r = Z(), i = Ae(), { t: a } = N(), o = I(() => z(e)), s = I(() => z(t)), c = R(/* @__PURE__ */ new Set()), l = R(null), u;
2444
+ B([i, s], ([e, t]) => {
2445
+ u?.(), u = void 0, c.value = /* @__PURE__ */ new Set(), e && t && (u = W(K(b(r, n()), X("uid", "==", e.uid), X("postId", "==", t), X("target", "==", "comment")), (e) => {
2437
2446
  let t = /* @__PURE__ */ new Set();
2438
2447
  for (let n of e.docs) {
2439
2448
  let e = n.data().commentId;
@@ -2443,7 +2452,7 @@ function Ar(e, t) {
2443
2452
  }, (e) => {
2444
2453
  console.error("[memi-board:comment-likes] onSnapshot failed", e);
2445
2454
  }));
2446
- }, { immediate: !0 }), I(() => u?.());
2455
+ }, { immediate: !0 }), L(() => u?.());
2447
2456
  function f(e) {
2448
2457
  return !!e && c.value.has(e);
2449
2458
  }
@@ -2457,7 +2466,7 @@ function Ar(e, t) {
2457
2466
  if (l.value) return f(e);
2458
2467
  l.value = e;
2459
2468
  try {
2460
- let i = pe(r, n(), e, t), l = d(r, n(), e), u = await De(r, async (n) => {
2469
+ let i = fe(r, n(), e, t), l = d(r, n(), e), u = await Ee(r, async (n) => {
2461
2470
  let r = await n.get(i), c = await n.get(l);
2462
2471
  if (!c.exists()) throw Error(a("likes.commentNotFound"));
2463
2472
  let u = Number(c.data()?.likeCount ?? 0);
@@ -2467,7 +2476,7 @@ function Ar(e, t) {
2467
2476
  boardId: o.value,
2468
2477
  commentId: e,
2469
2478
  target: "comment",
2470
- createdAt: K()
2479
+ createdAt: q()
2471
2480
  }), n.update(l, { likeCount: u + 1 }), !0);
2472
2481
  }), f = new Set(c.value);
2473
2482
  return u ? f.add(e) : f.delete(e), c.value = f, u;
@@ -2506,21 +2515,21 @@ var jr = 200, Mr = [
2506
2515
  }
2507
2516
  ];
2508
2517
  function Nr(e, t) {
2509
- return Mr.some((t) => t.value === e) ? j(t, `reports.reason.${e}`) : e || j(t, "reports.fallbackLabel");
2518
+ return Mr.some((t) => t.value === e) ? M(t, `reports.reason.${e}`) : e || M(t, "reports.fallbackLabel");
2510
2519
  }
2511
2520
  function Pr(e, t) {
2512
- let n = () => N(), r = Z(), i = Ae(), { t: a } = M(), o = L(!1), s = L(!1), c;
2513
- z(i, (e) => {
2521
+ let n = () => P(), r = Z(), i = Ae(), { t: a } = N(), o = R(!1), s = R(!1), c;
2522
+ B(i, (e) => {
2514
2523
  if (c?.(), c = void 0, !e) {
2515
2524
  o.value = !1;
2516
2525
  return;
2517
2526
  }
2518
- c = U(u(r, n(), t, e.uid), (e) => {
2527
+ c = W(u(r, n(), t, e.uid), (e) => {
2519
2528
  o.value = e.exists();
2520
2529
  }, (e) => {
2521
2530
  console.error("[memi-board:reports] onSnapshot failed", e);
2522
2531
  });
2523
- }, { immediate: !0 }), I(() => c?.());
2532
+ }, { immediate: !0 }), L(() => c?.());
2524
2533
  async function l(c) {
2525
2534
  let l = i.value?.uid;
2526
2535
  if (!l) throw Error(a("reports.signInRequired"));
@@ -2532,7 +2541,7 @@ function Pr(e, t) {
2532
2541
  if (f.length > 200) throw Error(a("reports.detailTooLong", { max: 200 }));
2533
2542
  s.value = !0;
2534
2543
  try {
2535
- await q(u(r, n(), t, l), {
2544
+ await De(u(r, n(), t, l), {
2536
2545
  uid: l,
2537
2546
  target: "post",
2538
2547
  postId: t,
@@ -2543,7 +2552,7 @@ function Pr(e, t) {
2543
2552
  postTitle: (c.postTitle || "").trim().slice(0, 200),
2544
2553
  authorUid: c.authorUid || "",
2545
2554
  authorName: c.authorName ?? null,
2546
- createdAt: K()
2555
+ createdAt: q()
2547
2556
  }), o.value = !0;
2548
2557
  } finally {
2549
2558
  s.value = !1;
@@ -2557,7 +2566,7 @@ function Pr(e, t) {
2557
2566
  }
2558
2567
  var Fr = 20;
2559
2568
  function Ir(e = {}) {
2560
- let t = () => N(), n = Z(), { isAdmin: r, canManageContent: i, canManageBoard: a } = Wt(), o = e.pageSize ?? Fr, s = F(() => R(e.boardId)?.trim() || ""), c = L([]), d = L(!0), f = L(!1), p = L(!1), m = L(""), h = null, g;
2569
+ let t = () => P(), n = Z(), { isAdmin: r, canManageContent: i, canManageBoard: a } = Wt(), o = e.pageSize ?? Fr, s = I(() => z(e.boardId)?.trim() || ""), c = R([]), d = R(!0), f = R(!1), p = R(!1), m = R(""), h = null, g;
2561
2570
  function _(e) {
2562
2571
  return {
2563
2572
  id: e.id,
@@ -2571,18 +2580,18 @@ function Ir(e = {}) {
2571
2580
  }
2572
2581
  d.value = !0;
2573
2582
  let e = s.value ? [X("status", "==", "open"), X("boardId", "==", s.value)] : [X("status", "==", "open"), X("target", "==", "post")];
2574
- g = U(G(l(n, t()), ...e, W("createdAt", "desc"), W(B(), "desc"), H(o)), (e) => {
2583
+ g = W(K(l(n, t()), ...e, G("createdAt", "desc"), G(V(), "desc"), U(o)), (e) => {
2575
2584
  c.value = e.docs.map(_).filter((e) => a(e.boardId)), h = e.docs.at(-1) ?? null, p.value = e.docs.length >= o, d.value = !1;
2576
2585
  }, (e) => {
2577
2586
  console.error("[memi-board:report-queue] onSnapshot failed", e), m.value = e.message || String(e), d.value = !1;
2578
2587
  });
2579
2588
  }
2580
- z([i, s], v, { immediate: !0 }), I(() => g?.());
2589
+ B([i, s], v, { immediate: !0 }), L(() => g?.());
2581
2590
  async function y() {
2582
2591
  if (!f.value && p.value && h && i.value) {
2583
2592
  f.value = !0, m.value = "";
2584
2593
  try {
2585
- let e = s.value ? [X("status", "==", "open"), X("boardId", "==", s.value)] : [X("status", "==", "open"), X("target", "==", "post")], r = await V(G(l(n, t()), ...e, W("createdAt", "desc"), W(B(), "desc"), J(h), H(o + 1))), i = r.docs.slice(0, o), u = new Set(c.value.map((e) => e.id));
2594
+ let e = s.value ? [X("status", "==", "open"), X("boardId", "==", s.value)] : [X("status", "==", "open"), X("target", "==", "post")], r = await H(K(l(n, t()), ...e, G("createdAt", "desc"), G(V(), "desc"), J(h), U(o + 1))), i = r.docs.slice(0, o), u = new Set(c.value.map((e) => e.id));
2586
2595
  c.value.push(...i.map(_).filter((e) => !u.has(e.id) && a(e.boardId))), h = i.at(-1) ?? h, p.value = r.docs.length > o;
2587
2596
  } catch (e) {
2588
2597
  m.value = e.message || String(e);
@@ -2594,7 +2603,7 @@ function Ir(e = {}) {
2594
2603
  async function b(e, r) {
2595
2604
  e.id && a(e.boardId) && await Y(u(n, t(), e.postId, e.uid), {
2596
2605
  status: r,
2597
- reviewedAt: K(),
2606
+ reviewedAt: q(),
2598
2607
  reviewedBy: Ae().value?.uid || ""
2599
2608
  });
2600
2609
  }
@@ -2612,7 +2621,7 @@ function Ir(e = {}) {
2612
2621
  //#endregion
2613
2622
  //#region src/composables/useMemiBoardViews.ts
2614
2623
  function Lr() {
2615
- let e = () => N(), t = Z();
2624
+ let e = () => P(), t = Z();
2616
2625
  function n(t, n) {
2617
2626
  let { postsCollection: r } = e();
2618
2627
  return `memi-board:viewed:${r}:${t}:${n}`;
@@ -2635,7 +2644,7 @@ function Lr() {
2635
2644
  if (s && c && !r(s, c)) {
2636
2645
  i(s, c);
2637
2646
  try {
2638
- await Y(y(t, e(), c), { viewCount: Te(1) });
2647
+ await Y(y(t, e(), c), { viewCount: we(1) });
2639
2648
  } catch (e) {
2640
2649
  try {
2641
2650
  sessionStorage.removeItem(n(s, c));
@@ -2658,7 +2667,7 @@ var Rr = {
2658
2667
  via: "empty"
2659
2668
  };
2660
2669
  function zr(e = {}) {
2661
- let t = M(), n = F(() => P(R(e.locale)) ?? t.locale.value), r = v().moderation ?? {}, i = Me(), a = (e) => j(n.value, e), { isWriteRestricted: o, restrictedMessage: s, recordContentModerationBlock: c } = Wt(), l = Nn([...Mn, ...r.localBlocklist ?? []]);
2670
+ let t = N(), n = I(() => F(z(e.locale)) ?? t.locale.value), r = v().moderation ?? {}, i = Me(), a = (e) => M(n.value, e), { isWriteRestricted: o, restrictedMessage: s, recordContentModerationBlock: c } = Wt(), l = Nn([...Mn, ...r.localBlocklist ?? []]);
2662
2671
  function u(e) {
2663
2672
  let t = e.match(l);
2664
2673
  return t ? {
@@ -2817,16 +2826,16 @@ var Br = [
2817
2826
  "user"
2818
2827
  ].map((e) => ({
2819
2828
  value: e,
2820
- label: j("ko", `common.role.${e}`),
2821
- description: j("ko", `boardUsers.roleDescription.${e}`)
2829
+ label: M("ko", `common.role.${e}`),
2830
+ description: M("ko", `boardUsers.roleDescription.${e}`)
2822
2831
  }));
2823
2832
  function Vr(e = {}) {
2824
- let t = () => N(), n = Z(), { t: r } = M(), i = F(() => R(e.enabled) ?? !0 ? c(n, t()) : null), a = ke(i, { ssrKey: p(t(), "users-management") });
2833
+ let t = () => P(), n = Z(), { t: r } = N(), i = I(() => z(e.enabled) ?? !0 ? c(n, t()) : null), a = ke(i, { ssrKey: p(t(), "users-management") });
2825
2834
  async function o(e, i) {
2826
2835
  if (!Br.some((e) => e.value === i)) throw Error(r("boardUsers.unsupportedRole"));
2827
2836
  await Y(h(n, t(), e), {
2828
2837
  role: i,
2829
- updatedAt: K()
2838
+ updatedAt: q()
2830
2839
  });
2831
2840
  }
2832
2841
  return {
@@ -2838,7 +2847,7 @@ function Vr(e = {}) {
2838
2847
  //#endregion
2839
2848
  //#region src/composables/useMemiBoardUserProfile.ts
2840
2849
  function Hr(e) {
2841
- let t = Z(), n = () => N(), r = F(() => R(e)), i = F(() => {
2850
+ let t = Z(), n = () => P(), r = I(() => z(e)), i = I(() => {
2842
2851
  let e = r.value;
2843
2852
  return e ? h(t, n(), e) : null;
2844
2853
  }), { data: a, pending: o } = je(i);
@@ -2863,25 +2872,25 @@ function Wr(e) {
2863
2872
  return [
2864
2873
  {
2865
2874
  value: "list",
2866
- label: j(e, "sectionUtil.kind.list")
2875
+ label: M(e, "sectionUtil.kind.list")
2867
2876
  },
2868
2877
  {
2869
2878
  value: "post",
2870
- label: j(e, "sectionUtil.kind.post")
2879
+ label: M(e, "sectionUtil.kind.post")
2871
2880
  },
2872
2881
  {
2873
2882
  value: "comments",
2874
- label: j(e, "sectionUtil.kind.comments")
2883
+ label: M(e, "sectionUtil.kind.comments")
2875
2884
  }
2876
2885
  ];
2877
2886
  }
2878
2887
  function Gr(e) {
2879
2888
  return [{
2880
2889
  value: "latest",
2881
- label: j(e, "sectionUtil.sort.latest")
2890
+ label: M(e, "sectionUtil.sort.latest")
2882
2891
  }, {
2883
2892
  value: "likes",
2884
- label: j(e, "sectionUtil.sort.likes")
2893
+ label: M(e, "sectionUtil.sort.likes")
2885
2894
  }];
2886
2895
  }
2887
2896
  var Kr = Wr("ko"), qr = Gr("ko");
@@ -2924,13 +2933,13 @@ function ni(e) {
2924
2933
  return e.previewImage || e.attachments?.find((e) => e.type.startsWith("image/"))?.url;
2925
2934
  }
2926
2935
  function ri(e, t) {
2927
- return vt(e, t).trim() || yt(e, t).trim() || j(t, "sectionUtil.untitledPost");
2936
+ return vt(e, t).trim() || yt(e, t).trim() || M(t, "sectionUtil.untitledPost");
2928
2937
  }
2929
2938
  function ii(e) {
2930
2939
  return e === "image" || e === "video" ? "media" : "list";
2931
2940
  }
2932
2941
  function ai(e, t) {
2933
- return j(t, ii(e) === "media" ? "sectionUtil.view.media" : "sectionUtil.view.list");
2942
+ return M(t, ii(e) === "media" ? "sectionUtil.view.media" : "sectionUtil.view.list");
2934
2943
  }
2935
2944
  function oi(e, t) {
2936
2945
  return e ? t(e)?.listView ?? "default" : "default";
@@ -2973,7 +2982,7 @@ function mi(e, t) {
2973
2982
  return r;
2974
2983
  }
2975
2984
  function hi(e, t) {
2976
- return j(t, "sections.defaultTitle", { n: e + 1 });
2985
+ return M(t, "sections.defaultTitle", { n: e + 1 });
2977
2986
  }
2978
2987
  function gi(e, t, n) {
2979
2988
  let r = di(e), i = Yr(r, e.count), a = Q(e.i18n), o = ut(e.i18nSource);
@@ -2994,7 +3003,7 @@ function gi(e, t, n) {
2994
3003
  };
2995
3004
  }
2996
3005
  function _i() {
2997
- let { locale: e } = M(), { translateEntries: t } = Un(), r = Z(), i = ye(r, "settings", "homeLayout"), { data: a, pending: o } = je(i), s = F(() => (Array.isArray(a.value?.blocks) ? a.value.blocks : ci).map((t, n) => gi(t, n, e.value)));
3006
+ let { locale: e } = N(), { translateEntries: t } = Un(), r = Z(), i = ve(r, "settings", "homeLayout"), { data: a, pending: o } = je(i), s = I(() => (Array.isArray(a.value?.blocks) ? a.value.blocks : ci).map((t, n) => gi(t, n, e.value)));
2998
3007
  async function c(r) {
2999
3008
  if (!n()) return r;
3000
3009
  let i = e.value, a = r.filter((e) => {
@@ -3050,10 +3059,10 @@ function _i() {
3050
3059
  } catch (e) {
3051
3060
  console.warn("[memi-board] section translation skipped", e);
3052
3061
  }
3053
- await q(i, {
3062
+ await De(i, {
3054
3063
  columns: 12,
3055
3064
  blocks: t.map((e, t) => l(e, t)),
3056
- updatedAt: K()
3065
+ updatedAt: q()
3057
3066
  });
3058
3067
  }
3059
3068
  return {
@@ -3061,7 +3070,7 @@ function _i() {
3061
3070
  pending: o,
3062
3071
  sections: s,
3063
3072
  blocks: s,
3064
- hasSavedLayout: F(() => Array.isArray(a.value?.blocks)),
3073
+ hasSavedLayout: I(() => Array.isArray(a.value?.blocks)),
3065
3074
  saveSections: u,
3066
3075
  saveBlocks: u
3067
3076
  };
@@ -3069,20 +3078,20 @@ function _i() {
3069
3078
  //#endregion
3070
3079
  //#region src/composables/useMemiBoardMiniPosts.ts
3071
3080
  function vi(e, t) {
3072
- let n = Z(), r = () => N(), i = R(e)?.trim() || "all", a = F(() => {
3073
- let i = Math.max(1, Math.floor(Number(R(t)) || 5)), a = R(e)?.trim() || "", s = [X("isPublished", "==", !0), X("listed", "==", !0)];
3074
- return a && s.unshift(X("boardId", "==", a)), G(o(n, r()), ...s, W("createdAt", "desc"), H(i));
3081
+ let n = Z(), r = () => P(), i = z(e)?.trim() || "all", a = I(() => {
3082
+ let i = Math.max(1, Math.floor(Number(z(t)) || 5)), a = z(e)?.trim() || "", s = [X("isPublished", "==", !0), X("listed", "==", !0)];
3083
+ return a && s.unshift(X("boardId", "==", a)), K(o(n, r()), ...s, G("createdAt", "desc"), U(i));
3075
3084
  }), { data: s, pending: c, error: l } = ke(a, { ssrKey: p(r(), `mini-list/${i}`) });
3076
3085
  return {
3077
- posts: F(() => s.value ?? []),
3086
+ posts: I(() => s.value ?? []),
3078
3087
  pending: c,
3079
3088
  error: l
3080
3089
  };
3081
3090
  }
3082
3091
  function yi(e) {
3083
- let t = Z(), n = () => N(), r = F(() => [...new Set(R(e).map((e) => e.trim()).filter(Boolean))].slice(0, 10)), i = r.value.join(",") || "none", a = F(() => r.value.length ? G(o(t, n()), X(B(), "in", r.value)) : null), { data: s, pending: c, error: l } = ke(a, { ssrKey: p(n(), `mini-picked/${i}`) });
3092
+ let t = Z(), n = () => P(), r = I(() => [...new Set(z(e).map((e) => e.trim()).filter(Boolean))].slice(0, 10)), i = r.value.join(",") || "none", a = I(() => r.value.length ? K(o(t, n()), X(V(), "in", r.value)) : null), { data: s, pending: c, error: l } = ke(a, { ssrKey: p(n(), `mini-picked/${i}`) });
3084
3093
  return {
3085
- posts: F(() => {
3094
+ posts: I(() => {
3086
3095
  let e = new Map((s.value ?? []).map((e) => [e.id, e])), t = [];
3087
3096
  for (let n of r.value) {
3088
3097
  let r = e.get(n);
@@ -3097,6 +3106,22 @@ function yi(e) {
3097
3106
  //#endregion
3098
3107
  //#region src/data/versionHistory.ts
3099
3108
  var bi = [
3109
+ {
3110
+ version: "0.52.3",
3111
+ date: "2026-10-30",
3112
+ highlights: [
3113
+ "AI 글쓰기 도우미를 하루 20회까지 쓸 수 있어요",
3114
+ "자동 번역이 실패하거나 한도를 넘어도 글과 댓글은 원문으로 저장돼요",
3115
+ "한도 안내가 10개 언어로 보여요"
3116
+ ],
3117
+ highlightsEn: [
3118
+ "The AI writing assistant can now be used up to 20 times a day",
3119
+ "Posts and comments are saved with the original text even when automatic translation fails or the limit is reached",
3120
+ "The daily limit message now appears in all 10 languages"
3121
+ ],
3122
+ note: "호스트 Firestore 규칙의 AI 사용 한도도 20으로 바꿔 배포해야 해요.",
3123
+ noteEn: "Update the AI usage limit in the host Firestore rules to 20 and deploy them."
3124
+ },
3100
3125
  {
3101
3126
  version: "0.52.2",
3102
3127
  date: "2026-10-30",
@@ -3737,11 +3762,11 @@ function Di(e, t, n) {
3737
3762
  //#endregion
3738
3763
  //#region src/composables/useMemiBoardCleanup.ts
3739
3764
  function Oi() {
3740
- let e = Z(), t = Me(), { isAdmin: n, rolePending: r } = Wt(), { t: i } = M(), a = L([]), o = L(!1), s = L(!1), c = L(""), l = L(""), u = [], d = "", f = /* @__PURE__ */ new Map();
3765
+ let e = Z(), t = Me(), { isAdmin: n, rolePending: r } = Wt(), { t: i } = N(), a = R([]), o = R(!1), s = R(!1), c = R(""), l = R(""), u = [], d = "", f = /* @__PURE__ */ new Map();
3741
3766
  function p() {
3742
3767
  let e = Le(t).currentUser?.uid;
3743
3768
  if (!e) throw Error(i("settings.noAccess"));
3744
- return JSON.stringify([e, N()]);
3769
+ return JSON.stringify([e, P()]);
3745
3770
  }
3746
3771
  function m(e) {
3747
3772
  if (h(), p() !== e) throw Error(i("settings.cleanup.contextChanged"));
@@ -3750,10 +3775,10 @@ function Oi() {
3750
3775
  if (!n.value || r.value || !Le(t).currentUser) throw Error(i("settings.noAccess"));
3751
3776
  }
3752
3777
  async function g() {
3753
- let t = N(), [n, r, i] = await Promise.all([
3754
- we(ge(e, t.postsCollection)),
3755
- we(ge(e, t.commentsCollection)),
3756
- we(ge(e, t.likesCollection))
3778
+ let t = P(), [n, r, i] = await Promise.all([
3779
+ Ce(he(e, t.postsCollection)),
3780
+ Ce(he(e, t.commentsCollection)),
3781
+ Ce(he(e, t.likesCollection))
3757
3782
  ]), a = /* @__PURE__ */ new Set();
3758
3783
  function o(e) {
3759
3784
  if (typeof e == "string") {
@@ -3767,7 +3792,7 @@ function Oi() {
3767
3792
  } else Array.isArray(e) ? e.forEach(o) : e && typeof e == "object" && Object.getPrototypeOf(e) === Object.prototype && Object.values(e).forEach(o);
3768
3793
  }
3769
3794
  n.docs.forEach((e) => o(e.data())), r.docs.forEach((e) => o(e.data()));
3770
- for (let e of n.docs) (await we(ge(e.ref, "body"))).docs.forEach((e) => o(e.data()));
3795
+ for (let e of n.docs) (await Ce(he(e.ref, "body"))).docs.forEach((e) => o(e.data()));
3771
3796
  for (let e of [...a]) {
3772
3797
  let t = e.match(/^(.*\/images\/)([^/]+)\.[^/.]+$/);
3773
3798
  t && a.add(`${t[1]}thumbnails/${t[2]}.jpg`);
@@ -3849,20 +3874,20 @@ function Oi() {
3849
3874
  if (n.kind === "file") {
3850
3875
  if (!Ei(n.path, o.cfg.postsCollection)) throw Error("Invalid cleanup path");
3851
3876
  let r = We(t), a = qe(r, n.path), [s, c, l] = await Promise.all([
3852
- Ce(ye(e, o.cfg.postsCollection, n.postId)),
3853
- n.commentId ? Ce(ye(e, o.cfg.commentsCollection, n.commentId)) : null,
3877
+ Se(ve(e, o.cfg.postsCollection, n.postId)),
3878
+ n.commentId ? Se(ve(e, o.cfg.commentsCollection, n.commentId)) : null,
3854
3879
  Ue(a)
3855
3880
  ]);
3856
3881
  m(d), l.generation === f.get(n.path) && !o.referenced.has(n.path) && Ti(l.updated, Date.now()) && (!s.exists() || n.commentId && !c?.exists()) && (await He(a), i = !0);
3857
3882
  } else {
3858
3883
  let t = n.kind;
3859
3884
  if (!Di(n.path, t, o.cfg)) throw Error("Invalid cleanup path");
3860
- i = await De(e, async (r) => {
3861
- let i = await r.get(ye(e, n.path));
3885
+ i = await Ee(e, async (r) => {
3886
+ let i = await r.get(ve(e, n.path));
3862
3887
  if (!i.exists()) return !0;
3863
3888
  let a = i.data();
3864
3889
  if (typeof a.postId != "string" || !a.postId || a.postId.includes("/")) return !1;
3865
- let s = await r.get(ye(e, o.cfg.postsCollection, a.postId)), c = n.kind === "like" && a.target === "comment" && typeof a.commentId == "string" && a.commentId && !a.commentId.includes("/") ? await r.get(ye(e, o.cfg.commentsCollection, a.commentId)) : null;
3890
+ let s = await r.get(ve(e, o.cfg.postsCollection, a.postId)), c = n.kind === "like" && a.target === "comment" && typeof a.commentId == "string" && a.commentId && !a.commentId.includes("/") ? await r.get(ve(e, o.cfg.commentsCollection, a.commentId)) : null;
3866
3891
  return wi(t, a, new Set(s.exists() ? [a.postId] : []), new Set(c?.exists() ? [a.commentId] : [])) ? (m(d), r.delete(i.ref), !0) : !1;
3867
3892
  });
3868
3893
  }
@@ -3883,16 +3908,16 @@ function Oi() {
3883
3908
  }
3884
3909
  }
3885
3910
  return {
3886
- items: he(a),
3887
- busy: he(o),
3888
- scanned: he(s),
3889
- error: he(c),
3890
- result: he(l),
3911
+ items: me(a),
3912
+ busy: me(o),
3913
+ scanned: me(s),
3914
+ error: me(c),
3915
+ result: me(l),
3891
3916
  scan: _,
3892
3917
  remove: v
3893
3918
  };
3894
3919
  }
3895
3920
  //#endregion
3896
- export { lr as AUTHOR_MEMO_MAX_LENGTH, Ur as BOARD_SECTION_COLS, Kr as BOARD_SECTION_KINDS, qr as BOARD_SECTION_SORTS, Br as BOARD_USER_ROLES, wr as COMMENT_BODY_MAX_LENGTH, It as DEFAULT_BLOCK_BAN_DECAY_MS, Ft as DEFAULT_BLOCK_BAN_THRESHOLD, Wn as DEFAULT_BOARDS, Gn as DEFAULT_CATEGORIES, i as DEFAULT_COMMENTS_COLLECTION, r as DEFAULT_LIKES_COLLECTION, te as DEFAULT_MEMI_BOARD_LOCALE, m as DEFAULT_POSTS_COLLECTION, re as DEFAULT_REPORTS_COLLECTION, e as DEFAULT_SETTINGS_COLLECTION, ne as DEFAULT_USERS_COLLECTION, A as FALLBACK_MEMI_BOARD_LOCALE, Rn as HTML_MAX_CHARS, T as MEMI_BOARD_LOCALES, jr as REPORT_DETAIL_MAX_LENGTH, Mr as REPORT_REASONS, fr as WRITING_ASSISTANT_DAILY_LIMIT, $e as asHttpUrl, xt as boardCopyIsTranslated, at as boardListOgDescription, it as boardListOgTitle, rt as boardPostOgDescription, nt as boardPostOgTitle, Wr as boardSectionKinds, Gr as boardSectionSorts, p as boardSsrKey, pt as boardTranslationLocales, h as boardUserDoc, c as boardUsersCol, _n as buildPostPreview, At as canManageBoardByRole, jt as canWriteCommentByRole, Yr as clampSectionCount, d as commentDoc, g as commentsCol, fe as configureMemiBoard, ht as coversLocales, Jr as defaultSectionCount, St as displayCommentBody, bt as displayPostContent, yt as displayPostSummary, vt as displayPostTitle, _t as displayStoredField, Lt as effectiveModerationBlockCount, Xt as extractEditorImageUrls, Dt as fetchPublicListForSeo, Et as fetchPublicPostForSeo, O as formatDate, ie as formatFullDate, ue as formatRelativeDate, Bt as formatRestrictedUntilLabel, k as formatTimestampDetails, fn as hasBodyImage, dn as hasBodyText, ct as hashText, Jt as imeSafeSubmitClick, qt as imeSafeSubmitPointerDown, kt as isAssignedStaff, pn as isContentEmpty, Xn as isFirestorePermissionDenied, _ as isMemiBoardI18nEnabled, ee as isMemiBoardLocaleLoaded, n as isMemiBoardTranslationEnabled, zt as isModerationWriteRestricted, pe as likeDoc, t as likeDocId, b as likesCol, oe as loadMemiBoardLocale, gt as localizedText, kr as memiBoardCommentLikesKey, ae as memiBoardHostLocaleKey, de as memiBoardLocaleInfo, ft as mergeSourceFields, oi as miniBoardView, ti as miniCommentLink, ei as miniMoreLink, ni as miniPostImage, $r as miniPostLink, ri as miniPostTitle, si as miniPostsView, ii as miniViewGroup, ai as miniViewLabel, Rt as moderationWriteRestrictedUntilMs, ot as normalizeBasePath, gi as normalizeBoardSection, P as normalizeMemiBoardLocale, Xr as pairSectionCols, ln as plainTextFromHtml, s as postBodyDoc, y as postDoc, Qt as postNamespaceFromStoragePath, x as postStorageFolder, o as postsCol, ut as readI18nSource, Q as readLocalizedFields, Ci as renderMarkdownToHtml, u as reportDoc, se as reportDocId, Nr as reportReasonLabel, l as reportsCol, C as resolveBoardPathConfig, Ct as resolvePublicSeoDb, Zr as sectionColClass, Qr as sectionMinHeight, S as settingsCol, w as settingsDoc, E as slugify, Zt as storagePathFromDownloadUrl, un as titleFromBody, tt as toAbsoluteUrl, et as toBoardOgImageUrl, j as translate, N as useBoardPathConfig, Wt as useMemiBoardAuth, dr as useMemiBoardAuthorMemo, Un as useMemiBoardAutoTranslate, Oi as useMemiBoardCleanup, cr as useMemiBoardCommentFeed, Ar as useMemiBoardCommentLikes, Er as useMemiBoardComments, v as useMemiBoardConfig, M as useMemiBoardI18n, Or as useMemiBoardLikes, vi as useMemiBoardMiniLatest, yi as useMemiBoardMiniPicked, zr as useMemiBoardModeration, nr as useMemiBoardPost, tr as useMemiBoardPostList, Qn as useMemiBoardPosts, Dr as useMemiBoardReplies, Ir as useMemiBoardReportQueue, Pr as useMemiBoardReports, _i as useMemiBoardSections, Jn as useMemiBoardSettings, or as useMemiBoardUserComments, ir as useMemiBoardUserPosts, Hr as useMemiBoardUserProfile, Vr as useMemiBoardUsers, Lr as useMemiBoardViews, br as useMemiBoardWritingAssistant, bi as versionHistory, gn as videoListCoverUrl, hn as youtubeId };
3921
+ export { lr as AUTHOR_MEMO_MAX_LENGTH, Ur as BOARD_SECTION_COLS, Kr as BOARD_SECTION_KINDS, qr as BOARD_SECTION_SORTS, Br as BOARD_USER_ROLES, wr as COMMENT_BODY_MAX_LENGTH, It as DEFAULT_BLOCK_BAN_DECAY_MS, Ft as DEFAULT_BLOCK_BAN_THRESHOLD, Wn as DEFAULT_BOARDS, Gn as DEFAULT_CATEGORIES, i as DEFAULT_COMMENTS_COLLECTION, r as DEFAULT_LIKES_COLLECTION, j as DEFAULT_MEMI_BOARD_LOCALE, m as DEFAULT_POSTS_COLLECTION, ne as DEFAULT_REPORTS_COLLECTION, e as DEFAULT_SETTINGS_COLLECTION, te as DEFAULT_USERS_COLLECTION, A as FALLBACK_MEMI_BOARD_LOCALE, Rn as HTML_MAX_CHARS, T as MEMI_BOARD_LOCALES, jr as REPORT_DETAIL_MAX_LENGTH, Mr as REPORT_REASONS, fr as WRITING_ASSISTANT_DAILY_LIMIT, $e as asHttpUrl, xt as boardCopyIsTranslated, at as boardListOgDescription, it as boardListOgTitle, rt as boardPostOgDescription, nt as boardPostOgTitle, Wr as boardSectionKinds, Gr as boardSectionSorts, p as boardSsrKey, pt as boardTranslationLocales, h as boardUserDoc, c as boardUsersCol, _n as buildPostPreview, At as canManageBoardByRole, jt as canWriteCommentByRole, Yr as clampSectionCount, d as commentDoc, g as commentsCol, de as configureMemiBoard, ht as coversLocales, Jr as defaultSectionCount, St as displayCommentBody, bt as displayPostContent, yt as displayPostSummary, vt as displayPostTitle, _t as displayStoredField, Lt as effectiveModerationBlockCount, Xt as extractEditorImageUrls, Dt as fetchPublicListForSeo, Et as fetchPublicPostForSeo, ee as formatDate, re as formatFullDate, le as formatRelativeDate, Bt as formatRestrictedUntilLabel, O as formatTimestampDetails, fn as hasBodyImage, dn as hasBodyText, ct as hashText, Jt as imeSafeSubmitClick, qt as imeSafeSubmitPointerDown, kt as isAssignedStaff, pn as isContentEmpty, Xn as isFirestorePermissionDenied, _ as isMemiBoardI18nEnabled, k as isMemiBoardLocaleLoaded, n as isMemiBoardTranslationEnabled, zt as isModerationWriteRestricted, fe as likeDoc, t as likeDocId, b as likesCol, ae as loadMemiBoardLocale, gt as localizedText, kr as memiBoardCommentLikesKey, ie as memiBoardHostLocaleKey, ue as memiBoardLocaleInfo, ft as mergeSourceFields, oi as miniBoardView, ti as miniCommentLink, ei as miniMoreLink, ni as miniPostImage, $r as miniPostLink, ri as miniPostTitle, si as miniPostsView, ii as miniViewGroup, ai as miniViewLabel, Rt as moderationWriteRestrictedUntilMs, ot as normalizeBasePath, gi as normalizeBoardSection, F as normalizeMemiBoardLocale, Xr as pairSectionCols, ln as plainTextFromHtml, s as postBodyDoc, y as postDoc, Qt as postNamespaceFromStoragePath, x as postStorageFolder, o as postsCol, ut as readI18nSource, Q as readLocalizedFields, Ci as renderMarkdownToHtml, u as reportDoc, oe as reportDocId, Nr as reportReasonLabel, l as reportsCol, C as resolveBoardPathConfig, Ct as resolvePublicSeoDb, Zr as sectionColClass, Qr as sectionMinHeight, S as settingsCol, w as settingsDoc, E as slugify, Zt as storagePathFromDownloadUrl, un as titleFromBody, tt as toAbsoluteUrl, et as toBoardOgImageUrl, M as translate, P as useBoardPathConfig, Wt as useMemiBoardAuth, dr as useMemiBoardAuthorMemo, Un as useMemiBoardAutoTranslate, Oi as useMemiBoardCleanup, cr as useMemiBoardCommentFeed, Ar as useMemiBoardCommentLikes, Er as useMemiBoardComments, v as useMemiBoardConfig, N as useMemiBoardI18n, Or as useMemiBoardLikes, vi as useMemiBoardMiniLatest, yi as useMemiBoardMiniPicked, zr as useMemiBoardModeration, nr as useMemiBoardPost, tr as useMemiBoardPostList, Qn as useMemiBoardPosts, Dr as useMemiBoardReplies, Ir as useMemiBoardReportQueue, Pr as useMemiBoardReports, _i as useMemiBoardSections, Jn as useMemiBoardSettings, or as useMemiBoardUserComments, ir as useMemiBoardUserPosts, Hr as useMemiBoardUserProfile, Vr as useMemiBoardUsers, Lr as useMemiBoardViews, br as useMemiBoardWritingAssistant, bi as versionHistory, gn as videoListCoverUrl, hn as youtubeId };
3897
3922
 
3898
3923
  //# sourceMappingURL=index.js.map