memi-board 0.60.0 → 0.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/{ar-CiZZkAEi.js → ar-B6HWpN6c.js} +12 -1
- package/dist/ar-B6HWpN6c.js.map +1 -0
- package/dist/{commentImages-Cu3UUpeR.js → commentImages-DZBDCMWH.js} +91 -71
- package/dist/commentImages-DZBDCMWH.js.map +1 -0
- package/dist/composables/useMemiBoardReports.d.ts +127 -1
- package/dist/{de-BmsTyFa1.js → de-CDaEV4cd.js} +12 -1
- package/dist/de-CDaEV4cd.js.map +1 -0
- package/dist/{en-Bizi62l1.js → en-lbbULqlq.js} +12 -1
- package/dist/en-lbbULqlq.js.map +1 -0
- package/dist/{es-wYEC2eO3.js → es-D8LzeTe0.js} +12 -1
- package/dist/es-D8LzeTe0.js.map +1 -0
- package/dist/{fr-C_ThACcX.js → fr-CQDZqx5d.js} +12 -1
- package/dist/fr-CQDZqx5d.js.map +1 -0
- package/dist/{id-CHzZpyk8.js → id-CIaQbTzK.js} +12 -1
- package/dist/id-CIaQbTzK.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1046 -954
- package/dist/index.js.map +1 -1
- package/dist/{ja-CvlMTefX.js → ja-B2iAAzYv.js} +12 -1
- package/dist/ja-B2iAAzYv.js.map +1 -0
- package/dist/{pt-DKsrQ_yb.js → pt-CXAWS0Km.js} +12 -1
- package/dist/pt-CXAWS0Km.js.map +1 -0
- package/dist/runtime/components/CommentItem.vue +11 -1
- package/dist/runtime/components/CommentReportButton.vue +91 -0
- package/dist/runtime/components/ReportButton.vue +12 -67
- package/dist/runtime/components/ReportList.vue +25 -5
- package/dist/runtime/components/ReportModalBody.vue +88 -0
- package/dist/storage.js +36 -36
- package/dist/types.d.ts +9 -2
- package/dist/utils/boardPaths.d.ts +5 -0
- package/dist/{zh-DiiqT_vJ.js → zh-ByjHExJt.js} +12 -1
- package/dist/zh-ByjHExJt.js.map +1 -0
- package/docs/firestore.rules.example +30 -9
- package/package.json +1 -1
- package/dist/ar-CiZZkAEi.js.map +0 -1
- package/dist/commentImages-Cu3UUpeR.js.map +0 -1
- package/dist/de-BmsTyFa1.js.map +0 -1
- package/dist/en-Bizi62l1.js.map +0 -1
- package/dist/es-wYEC2eO3.js.map +0 -1
- package/dist/fr-C_ThACcX.js.map +0 -1
- package/dist/id-CHzZpyk8.js.map +0 -1
- package/dist/ja-CvlMTefX.js.map +0 -1
- package/dist/pt-DKsrQ_yb.js.map +0 -1
- package/dist/zh-DiiqT_vJ.js.map +0 -1
package/README.md
CHANGED
|
@@ -812,4 +812,12 @@ Reporters can reopen the report button to read the current status, review time a
|
|
|
812
812
|
|
|
813
813
|
Deploy the report section in `docs/firestore.rules.example` before enabling these controls. Review records add optional `reviewedByName` and `reviewNote` fields; older client decisions without these fields remain compatible. Custom callers must pass a nonblank reason to `dismissReport(report, note)` / `actionReport(report, note)`.
|
|
814
814
|
|
|
815
|
+
#### Comment reports
|
|
816
|
+
|
|
817
|
+
Signed-in users can report other people's comments from the flag button on each comment, using the same reasons as post reports. A comment report is stored in the same reports collection at `c_{commentId}_{uid}` with `target: 'comment'`, `commentId`, and a `commentExcerpt` (up to 200 characters) so staff can still review it after the comment is deleted. The button reads the report status on click instead of subscribing per comment.
|
|
818
|
+
|
|
819
|
+
`MemiBoardReportList` shows a Post/Comment badge and the comment excerpt. When `getPostLink` is set, comment reports link to `#memi-comment-{commentId}` on the post. Marking a comment report reviewed offers a checkbox that also blinds the comment in the same transaction (`actionReport(report, note, { blindComment: true })`).
|
|
820
|
+
|
|
821
|
+
Rules: merge the whole `memiBoardReports` block from `docs/firestore.rules.example`, including the `isValidPostReport` and `isValidCommentReport` functions, then run `firebase deploy --only firestore:rules`. The comment branch checks that the comment exists, belongs to the same post, is not pending deletion, and was not written by the reporter. Until the rules are deployed, comment report submissions are denied. No index change is required.
|
|
822
|
+
|
|
815
823
|
Comment blind/restore is a separate manager action, not a user report. Its in-page confirmation preserves the requested action while saving and displays errors in the dialog. Updated comment rules prevent authors from changing `isBlinded`, `moderatedAt`, or `moderatedBy`; managers must use their own UID and a server timestamp. Blinding changes presentation and retains the original document; it is not deletion or a data-access boundary.
|
|
@@ -461,6 +461,7 @@ var e = {
|
|
|
461
461
|
bioPlaceholder: "عرّف الآخرين بنفسك"
|
|
462
462
|
},
|
|
463
463
|
reportButton: {
|
|
464
|
+
commentTitle: "الإبلاغ عن التعليق",
|
|
464
465
|
failed: "تعذّر إرسال البلاغ.",
|
|
465
466
|
reported: "تم الإبلاغ",
|
|
466
467
|
title: "الإبلاغ عن المنشور",
|
|
@@ -485,6 +486,14 @@ var e = {
|
|
|
485
486
|
detailRequired: "التفاصيل (مطلوبة عند اختيار أخرى)"
|
|
486
487
|
},
|
|
487
488
|
reportList: {
|
|
489
|
+
target: {
|
|
490
|
+
post: "منشور",
|
|
491
|
+
comment: "تعليق"
|
|
492
|
+
},
|
|
493
|
+
deletedComment: "نص التعليق غير متاح",
|
|
494
|
+
blindComment: "إخفاء هذا التعليق أيضًا",
|
|
495
|
+
blindCommentHint: "يخفي التعليق عن الجميع. يمكن للفريق استعادته من التعليق.",
|
|
496
|
+
commentActionHint: "يغيّر حالة البلاغ فقط. لا يخفي التعليق ولا يحذفه.",
|
|
488
497
|
staffOnly: "يمكن لفريق العمل فقط عرض البلاغات.",
|
|
489
498
|
loadFailed: "تعذّر تحميل القائمة: {error}",
|
|
490
499
|
empty: "لا توجد بلاغات معلّقة.",
|
|
@@ -509,6 +518,8 @@ var e = {
|
|
|
509
518
|
actionFailed: "تعذرت المعالجة. حاول مجددًا."
|
|
510
519
|
},
|
|
511
520
|
reports: {
|
|
521
|
+
cannotReportOwnComment: "لا يمكنك الإبلاغ عن تعليقك.",
|
|
522
|
+
alreadyReportedComment: "لقد أبلغت عن هذا التعليق بالفعل.",
|
|
512
523
|
reason: {
|
|
513
524
|
spam: "رسائل مزعجة / إعلانات",
|
|
514
525
|
abuse: "إساءة / كراهية / تحرّش",
|
|
@@ -804,4 +815,4 @@ var e = {
|
|
|
804
815
|
//#endregion
|
|
805
816
|
export { e as default };
|
|
806
817
|
|
|
807
|
-
//# sourceMappingURL=ar-
|
|
818
|
+
//# sourceMappingURL=ar-B6HWpN6c.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ar-B6HWpN6c.js","names":[],"sources":["../src/i18n/messages/ar.ts"],"sourcesContent":["import type { MemiBoardMessages } from '../translate'\n\n/** 짧은 화면 문구만 번역한다. 빠진 키는 en → ko 순으로 폴백된다. */\nconst messages: MemiBoardMessages = {\n attachments: {\n attach: 'إرفاق ملفات ({count} / {max})',\n dropOrClick: 'أفلت الملفات هنا أو انقر للإضافة',\n uploading: 'جارٍ رفع الملفات…',\n maxFiles: 'يمكنك إرفاق {max} ملفات كحد أقصى.',\n },\n auth: {\n writeRestricted: 'تم تقييد النشر والتعليق مؤقتًا بسبب تكرار تحذيرات المحتوى.',\n strikeSuffix: ' (تحذير {count}/{threshold})',\n strikeRestricted: ' عند بلوغ {count} تحذيرات سيتم تقييد النشر والتعليق.',\n notInitialized: '[memi-board] لم تتم تهيئة Firebase Auth.',\n },\n authorMemo: {\n tooLong: 'يمكن أن تصل الملاحظة إلى {max} حرف كحد أقصى.',\n },\n authorMenu: {\n menu: 'قائمة الكاتب',\n viewProfile: 'عرض الملف الشخصي',\n viewPosts: 'عرض المنشورات',\n viewComments: 'عرض التعليقات',\n memoAriaLabel: 'ملاحظة عن هذا الكاتب',\n memoTitle: 'ملاحظة خاصة',\n memoPlaceholder: 'دوِّن شيئًا عن هذا الكاتب…',\n bad: 'سيئ',\n good: 'جيد',\n },\n avatarCropModal: {\n title: 'قص صورة الملف الشخصي',\n description: 'تُعرض بشكل مربع (1:1). اضبط المنطقة لتناسبها.',\n confirm: 'قص ورفع',\n },\n boardSettings: {\n signInRequired: 'يُرجى تسجيل الدخول.',\n idAndNameRequired: 'يُرجى إدخال معرّف اللوحة واسمها.',\n deleteIdRequired: 'يلزم معرّف اللوحة لحذفها.',\n nameRequired: 'يُرجى إدخال اسم اللوحة.',\n },\n boardUsers: {\n unsupportedRole: 'دور غير مدعوم.',\n roleDescription: {\n admin: 'يدير أدوار المستخدمين وإعدادات اللوحة وكل المحتوى.',\n user: 'يمكنه كتابة المنشورات والتعليقات، وتعديل أو حذف محتواه فقط.',\n },\n },\n commentFeed: {\n empty: 'لا توجد تعليقات بعد.',\n emptyLiked: 'لا توجد تعليقات حصلت على إعجاب بعد.',\n loadFailed: 'تعذّر تحميل القائمة: {error}',\n blinded: 'أخفى المشرف هذا التعليق.',\n },\n commentForm: {\n translationSkipped: 'تم نشر التعليق دون ترجمة. يمكنك ترجمته لاحقًا من نموذج التعديل.',\n hiddenBoardDenied: 'في اللوحات المخفية، يمكن لفريق العمل المعيَّن فقط التعليق.',\n denied: 'ليس لديك إذن بالتعليق في هذه اللوحة.',\n signInRequired: 'يُرجى تسجيل الدخول.',\n writeRestricted: 'تم تقييد النشر مؤقتًا بسبب تكرار تحذيرات المحتوى.',\n moderationBlocked: 'يحتوي هذا على محتوى لا يمكن نشره.',\n replyTo: 'الرد على {name}',\n placeholder: 'اكتب تعليقًا',\n submitReply: 'رد',\n submit: 'تعليق',\n signInToComment: 'سجّل الدخول لكتابة تعليق.',\n attachHint: 'أسقط صورة هنا أو انقر لاختيار واحدة.',\n attachNote: 'jpg وpng وgif وwebp. يتم تصغير الصور الكبيرة إلى 5MB أو أقل.',\n removeImage: 'إزالة الصورة المرفقة',\n imageOnly: 'يمكن إرفاق صور jpg وpng وgif وwebp فقط.',\n uploadFailed: 'تعذر رفع الصورة.',\n uploading: 'جارٍ رفع الصورة…',\n },\n commentItem: {\n editRestricted: 'تم تقييد تعديل التعليقات مؤقتًا.',\n moderationBlocked: 'يحتوي هذا على محتوى لا يمكن نشره.',\n editFailed: 'تعذّر تعديل التعليق.',\n blindFailed: 'تعذّر تغيير حالة الإخفاء.',\n likeFailed: 'تعذّرت معالجة الإعجاب.',\n blinded: 'أخفى المشرف هذا التعليق.',\n attachedImage: 'صورة مرفقة بالتعليق',\n edit: 'تعديل التعليق',\n blind: 'إخفاء التعليق',\n unblind: 'إظهار التعليق',\n delete: 'حذف التعليق',\n },\n commentList: {\n loading: 'جارٍ تحميل التعليقات',\n empty: 'لا توجد تعليقات بعد.',\n loadMore: 'المزيد من التعليقات',\n loadingMore: 'جارٍ تحميل المزيد من التعليقات',\n },\n commentThread: {\n deleteConfirm: 'هل تريد حذف هذا التعليق؟',\n deleteFailed: 'تعذّر حذف التعليق.',\n hideReplies: 'إخفاء الردود',\n showReplies: 'الردود ({count})',\n loadMoreReplies: 'المزيد من الردود',\n },\n comments: {\n bodyRequired: 'يُرجى إدخال تعليق.',\n bodyTooLong: 'يمكن أن يصل التعليق إلى {max} حرف كحد أقصى.',\n replyTargetNotFound: 'تعذّر العثور على التعليق الذي تردّ عليه.',\n threadNotFound: 'تعذّر العثور على سلسلة التعليقات.',\n hasRepliesCannotDelete: 'لا يمكن حذف التعليقات التي لها ردود حاليًا.',\n },\n common: {\n action: {\n zoomIn: \"تكبير\",\n zoomOut: \"تصغير\",\n fitImage: \"ملاءمة الشاشة\",\n originalImage: \"الحجم الأصلي (100٪)\",\n cancel: 'إلغاء',\n save: 'حفظ',\n saved: 'تم الحفظ',\n edit: 'تعديل',\n delete: 'حذف',\n confirm: 'موافق',\n close: 'إغلاق',\n add: 'إضافة',\n more: 'المزيد',\n prev: 'السابق',\n next: 'التالي',\n retry: 'إعادة المحاولة',\n reply: 'رد',\n like: 'إعجاب',\n unlike: 'إلغاء الإعجاب',\n share: 'مشاركة',\n report: 'إبلاغ',\n signIn: 'تسجيل الدخول',\n signOut: 'تسجيل الخروج',\n write: 'كتابة',\n toTop: 'للأعلى',\n },\n label: {\n imageControls: \"أدوات تكبير الصورة\",\n anonymous: 'مجهول',\n user: 'مستخدم',\n image: 'صورة',\n draft: 'مسودة',\n loading: 'جارٍ التحميل…',\n viewCount: '{count} مشاهدة',\n },\n role: {\n admin: 'مشرف',\n staff: 'فريق العمل',\n user: 'مستخدم',\n },\n date: {\n justNow: 'الآن',\n fewSecondsAgo: 'قبل بضع ثوانٍ',\n checking: 'جارٍ التحقق من الوقت',\n createdAt: 'تاريخ الإنشاء: {time}',\n updatedAt: 'تاريخ التعديل: {time}',\n },\n },\n detail: {\n deleteConfirm: 'هل تريد حذف هذا المنشور؟ لا يمكن التراجع عن ذلك.',\n notFound: 'لم يتم العثور على المنشور.',\n draftPreview: 'معاينة غير منشورة',\n tag: 'وسم',\n draftNotice: 'لم يُنشر هذا المنشور بعد. لا يمكن لأحد غيرك رؤيته حتى تنشره.',\n publish: 'نشر',\n notice: 'إعلان',\n pin: 'تثبيت كإعلان',\n unpin: 'إلغاء الإعلان',\n backToList: 'العودة إلى القائمة',\n postNav: 'التنقل بين المنشورات',\n list: 'القائمة',\n comments: 'التعليقات',\n },\n editor: {\n titleOptionalPlaceholder: 'العنوان (اتركه فارغًا ليكتب الذكاء الاصطناعي عنوانًا)',\n titleAiNotice: 'كتب الذكاء الاصطناعي عنوانًا من نصك. احفظه إن أعجبك أو عدّله أولًا.',\n translateView: {\n title: 'معاينة الترجمة: {language}',\n notSaved: 'لم يتم الحفظ. هذه معاينة فقط.',\n },\n titlePlaceholder: 'العنوان',\n contentPlaceholder: 'اكتب شيئًا… اكتب / لفتح قائمة الكتل.',\n contentGuide: 'اكتب شيئًا…\\n· اسحب ملف صورة وأفلته هنا لرفعه.\\n· الصق صورة منسوخة (Ctrl/⌘+V) لرفعها فورًا.\\n· اكتب / لفتح قائمة الكتل: العناوين والقوائم والاقتباسات وغيرها.\\n· الصق رابط YouTube لتضمين الفيديو.',\n imageContentPlaceholder: 'اكتب شيئًا…',\n tagsPlaceholder: 'اكتب وسمًا واضغط Enter',\n pinNotice: 'تثبيت كإعلان',\n submitEdit: 'حفظ التغييرات',\n submitNext: 'التالي: معاينة',\n apply: 'تطبيق',\n imageOptimizing: 'جارٍ تحسين الصورة ورفعها…',\n cover: {\n imageLink: 'رابط الصورة',\n addPhoto: 'إضافة صور',\n alt: 'صورة {n}',\n representative: 'الغلاف',\n setRepresentative: 'تعيين كغلاف',\n setRepresentativeAria: 'تعيين الصورة {n} كغلاف',\n remove: 'إزالة الصورة',\n add: 'إضافة',\n uploading: 'جارٍ الرفع…',\n dropOrClick: 'أفلت الصور هنا أو انقر للإضافة',\n emptyHint: 'يمكن اختيار عدة صور · اختر الغلاف بعد الرفع · اسحب لإعادة الترتيب',\n uploadTitle: 'رفع',\n },\n uploadFailed: 'فشل الرفع',\n aiAssistant: 'مساعد الكتابة بالذكاء الاصطناعي',\n insertBlock: 'إدراج كتلة',\n blockMenu: 'قائمة الكتل',\n imageDialog: {\n title: 'إضافة صورة',\n chooseFile: 'اختيار صورة من جهازك',\n orLink: 'أو رابط صورة',\n urlLabel: 'URL الصورة',\n previewAlt: 'معاينة صورة خارجية',\n addLink: 'إضافة الرابط',\n },\n customDialog: {\n title: 'إعادة الصياغة بأسلوب مخصص',\n label: 'كيف تريد إعادة صياغته؟',\n help: 'مثال: بأسلوب ودّي / بأسلوب رسمي / كنقاط موجزة',\n placeholder: 'بأسلوب ودّي',\n },\n aiPreview: {\n title: 'مراجعة نتيجة AI',\n currentTitle: 'العنوان الحالي',\n newTitle: 'العنوان الجديد',\n currentContent: 'المحتوى الحالي',\n appendedContent: 'المحتوى المضاف',\n before: 'قبل',\n after: 'بعد',\n },\n menu: {\n ai: 'AI',\n aiContinue: 'المتابعة باستخدام AI',\n style: 'النمط',\n insert: 'إدراج',\n paragraph: 'فقرة',\n heading1: 'عنوان 1',\n heading2: 'عنوان 2',\n heading3: 'عنوان 3',\n bulletList: 'قائمة نقطية',\n orderedList: 'قائمة مرقّمة',\n blockquote: 'اقتباس',\n codeBlock: 'كتلة برمجية',\n horizontalRule: 'فاصل',\n image: 'صورة',\n turnInto: 'تحويل إلى',\n resetFormatting: 'إعادة تعيين التنسيق',\n duplicate: 'تكرار',\n moveUp: 'نقل للأعلى',\n moveDown: 'نقل للأسفل',\n delete: 'حذف',\n },\n toolbar: {\n link: 'رابط',\n image: 'صورة',\n format: 'التنسيق',\n bold: 'غامق',\n italic: 'مائل',\n underline: 'تسطير',\n strike: 'يتوسطه خط',\n title: 'العنوان',\n heading: 'عنوان',\n subheading: 'عنوان فرعي',\n body: 'النص',\n mono: 'أحادي المسافة',\n bulletList: 'قائمة نقطية',\n orderedList: 'قائمة مرقّمة',\n blockquote: 'اقتباس',\n codeBlock: 'كتلة برمجية',\n horizontalRule: 'فاصل',\n clearFormatting: 'مسح التنسيق',\n undo: 'تراجع',\n redo: 'إعادة',\n },\n ai: {\n translateView: 'عرض الترجمة',\n translateAll: 'ترجمة وحفظ بـ {count} لغات',\n proofread: 'تدقيق الإملاء',\n polish: 'تحسين الصياغة',\n continue: 'متابعة الكتابة',\n summarize: 'تلخيص موجز',\n translateEn: 'الترجمة إلى الإنجليزية',\n translateKo: 'الترجمة إلى الكورية',\n translateEmpty: 'أدخل عنوانًا أو نصًا للترجمة أولًا.',\n title: 'إنشاء عنوان من النص',\n custom: 'إعادة الصياغة بأسلوب مخصص…',\n failed: 'فشلت مهمة AI. يُرجى المحاولة مرة أخرى.',\n },\n youtubePrompt: 'أدخل رابط YouTube.',\n errors: {\n coverMax: 'يمكنك رفع {max} صور كحد أقصى.',\n imageUrlRequired: 'أدخل URL الصورة.',\n imageUrlInvalid: 'أدخل URL صالحًا للصورة.',\n imageUrlHttps: 'يُسمح فقط بعناوين URL للصور التي تبدأ بـ HTTPS.',\n imageUrlCredentials: 'لا يُسمح بعناوين URL التي تحتوي على بيانات تسجيل الدخول.',\n imageTimeout: 'يستغرق تحميل الصورة وقتًا طويلًا جدًا.',\n imageNotDisplayable: 'لا يمكن عرض هذه الصورة.',\n editorNotReady: 'المحرر غير جاهز. يُرجى المحاولة مرة أخرى.',\n imageLinkFailed: 'تعذّرت إضافة رابط الصورة.',\n imageOnly: 'يمكن رفع ملفات الصور فقط.',\n imageTooLarge: 'يجب ألا يتجاوز حجم الصورة الأصلية {mb}MB.',\n imageUploadFailed: 'فشل رفع الصورة.',\n pasteAsFile: 'الصق الصور كملفات أو اسحبها إلى المنطقة أعلاه.',\n postNotFound: 'لم يتم العثور على المنشور.',\n loadPermission: 'ليس لديك إذن بتحميل هذا المنشور. تأكد من تسجيل الدخول.',\n loadFailed: 'تعذّر تحميل المنشور: {message}',\n titleRequired: 'أدخل عنوانًا.',\n photoRequired: 'ارفع صورة واحدة على الأقل.',\n bodyRequired: 'اكتب نصًا أو أرفق صورة.',\n signInRequired: 'يلزم تسجيل الدخول.',\n boardMissing: 'لم يتم تحديد لوحة.',\n writeRestricted: 'تم تقييد النشر والتعليق مؤقتًا بسبب تكرار تحذيرات المحتوى.',\n moderationBlocked: 'يحتوي هذا على محتوى لا يمكن نشره.',\n },\n hint: {\n titling: 'جارٍ إنشاء العنوان…',\n reviewing: 'جارٍ مراجعة المحتوى…',\n saving: 'جارٍ الحفظ…',\n },\n },\n footer: {\n introduction: \"يعتمد memi-board على Nuxt 4 وVue 3 وTypeScript. وتجمع Nuxt UI وFirebase المنشورات والتعليقات والمحادثات في مكان واحد.\",\n eyebrow: \"مساحة للحوار\",\n tagline: \"مجتمعات صغيرة. قصص مشتركة.\",\n detail: \"التعريف المفصّل\",\n links: \"الروابط والتواصل\",\n email: \"البريد الإلكتروني\",\n credit: \"من تطوير memi\",\n feedback: \"أرسل ملاحظاتك\",\n feedbackSubject: \"ملاحظات memi-board\",\n feedbackBody: \"الملاحظات:\\n\",\n siteEyebrow: \"خدمات تستخدم memi-board\",\n changelog: \"سجل التغييرات\",\n info: {\n title: \"memi-board\",\n about: \"حول memi-board\",\n sites: \"أمثلة الاستخدام\",\n history: 'سجل الإصدارات',\n },\n sites: {\n description: \"خدمات تستخدم memi-board لمشاركة المنشورات والمحادثات.\",\n memi: \"مساحة للتطوير وقصص الحياة اليومية\",\n waiting: \"خدمة انتظار بسيطة عبر رمز QR\",\n track: \"تتبع GPS لتسجيل مسارات التنقل\",\n loop: \"تسجيل حركة المركبات وحلول المستشعرات\",\n safe: \"توصيل وإعداد جهاز منع الخلط بين الدواسات\",\n inviteTitle: \"هل تستخدمه أنت أيضًا؟\",\n invite: \"أخبرنا بعنوان موقعك.\",\n inviteSite: \"اتركه على memi.dev\",\n inviteOr: \"أو\",\n inviteSubject: \"نستخدم memi-board\",\n inviteBody: \"عنوان الموقع:\\n\",\n },\n stack: {\n ui: 'الواجهة والتجربة',\n data: 'البيانات وتسجيل الدخول',\n writing: 'الكتابة والأدوات المساعدة',\n },\n },\n likes: {\n signInRequired: 'يُرجى تسجيل الدخول.',\n commentNotFound: 'لم يتم العثور على التعليق.',\n },\n list: {\n boardInfo: {\n creator: 'أنشأه',\n managers: 'المديرون',\n staff: 'الموظفون',\n },\n commentCount: '{count} تعليقات',\n settings: 'الإعدادات',\n loadFailed: 'تعذّر تحميل القائمة: {error}',\n empty: 'لا توجد منشورات بعد.',\n notice: 'إعلان',\n photo: 'صورة',\n likeCount: 'الإعجابات {count}',\n info: {\n title: 'معلومات اللوحة',\n about: 'عن هذه اللوحة',\n history: 'سجل الإصدارات',\n },\n stack: {\n framework: 'إطار العمل واللغة',\n ui: 'الواجهة والتنسيق',\n backend: 'الخلفية والبيانات',\n },\n tech: {\n nuxt: 'إطار عمل SSR مبني على Vue',\n vue: 'Composition API · script setup',\n typescript: 'أنواع آمنة للبيانات والمكونات',\n nuxtUi: 'واجهة اللوحة والنماذج والنوافذ المنبثقة',\n tailwind: 'متجاوب · أنماط فاتحة/داكنة',\n lucide: 'أيقونات خفيفة ومتناسقة',\n dayjs: 'تواريخ وأوقات نسبية سهلة القراءة',\n firestore: 'قاعدة بيانات فورية للمنشورات والتعليقات',\n auth: 'تسجيل دخول وأذونات آمنة',\n storage: 'تخزين الصور والمرفقات',\n vuefire: 'ربط فوري بين Nuxt وFirebase',\n },\n },\n listViewSwitch: {\n card: 'بطاقة',\n default: 'افتراضي',\n dense: 'مضغوط',\n video: 'فيديو',\n },\n miniComments: {\n empty: 'لا توجد تعليقات بعد.',\n blinded: 'أخفى المشرف هذا التعليق.',\n },\n miniList: {\n empty: 'لا توجد منشورات بعد.',\n },\n miniPicker: {\n selectedCount: 'المحدد {count} / {max}',\n layoutHint: 'من 2 فأكثر تُعرض كشريط دوّار، و4 كشبكة',\n searchPlaceholder: 'البحث في العناوين',\n loading: 'جارٍ تحميل المنشورات…',\n noMore: 'لا توجد منشورات أخرى للاختيار.',\n },\n miniPost: {\n empty: 'لم يتم اختيار منشورات.',\n },\n moderation: {\n writeRestricted: 'تم تقييد النشر والتعليق مؤقتًا بسبب تكرار تحذيرات المحتوى.',\n },\n moderationPrompt: {\n localHit: 'لا يُسمح بتعبيرات مثل «{hit}». يُرجى إعادة الصياغة.',\n localGeneric: 'يحتوي هذا على ألفاظ نابية، لذا لا يمكن نشره. يُرجى إعادة الصياغة.',\n genericBlocked: 'يحتوي هذا على محتوى لا يمكن نشره. يُرجى تعديله.',\n categories: {\n abuse: 'ألفاظ نابية أو إهانات',\n spam: 'رسائل مزعجة أو إعلانات',\n adult: 'محتوى جنسي أو للبالغين',\n violence: 'عنف أو تهديدات',\n other: 'محتوى غير لائق',\n },\n },\n moderationStrike: {\n liftSoon: 'يُرفع قريبًا',\n liftInHours: 'يُرفع بعد {hours} ساعة تقريبًا',\n liftInDays: 'يُرفع بعد {days} يوم تقريبًا',\n liftInDaysHours: 'يُرفع بعد {days} يوم و{hours} ساعة تقريبًا',\n },\n posts: {\n boardIdRequired: '[memi-board] boardId مطلوب.',\n photoRequired: 'يُرجى إضافة صورة.',\n bodyRequired: 'يُرجى إدخال نص أو إرفاق صورة.',\n titleRequired: 'يُرجى إدخال عنوان.',\n },\n profile: {\n stats: {\n posts: '{count} منشورات',\n comments: '{count} تعليقات',\n aiUsage: 'استخدام الذكاء الاصطناعي {used} / {limit}',\n aiUsageResets: 'استخدام الذكاء الاصطناعي {used} / {limit} · يُعاد التعيين بعد {hours} ساعة',\n warnings: '{count} تحذيرات',\n },\n notFound: 'لم يتم العثور على المستخدم.',\n noName: 'بلا اسم',\n joined: 'انضم {time}',\n lastVisit: 'آخر ظهور {time}',\n },\n profileEditModal: {\n imageOnly: 'يمكن اختيار ملفات الصور فقط.',\n nameRequired: 'يُرجى إدخال اسم.',\n saveFailed: 'تعذّر حفظ الملف الشخصي.',\n title: 'تعديل الملف الشخصي',\n changePhoto: 'تغيير الصورة',\n name: 'الاسم',\n bio: 'نبذة',\n bioPlaceholder: 'عرّف الآخرين بنفسك',\n },\n reportButton: {\n commentTitle: 'الإبلاغ عن التعليق',\n failed: 'تعذّر إرسال البلاغ.',\n reported: 'تم الإبلاغ',\n title: 'الإبلاغ عن المنشور',\n done: 'تم استلام البلاغ. سيراجعه فريق العمل.',\n reason: 'السبب',\n detailPlaceholder: 'التفاصيل (اختياري)',\n submit: 'إبلاغ',\n\n \"status\": {\n \"open\": \"تم الاستلام\",\n \"dismissed\": \"مرفوض\",\n \"actioned\": \"اكتملت المراجعة\"\n },\n \"resultTitle\": \"حالة البلاغ\",\n \"result\": {\n \"open\": \"تم استلام بلاغك وهو بانتظار المراجعة.\",\n \"dismissed\": \"لم تجد المراجعة مخالفة.\",\n \"actioned\": \"اكتملت المراجعة. راجع السبب أدناه.\"\n },\n \"reviewedAt\": \"وقت المراجعة\",\n \"reviewNote\": \"سبب القرار\",\n \"noNote\": \"لا يوجد سبب مسجل لهذا السجل القديم.\",\n \"detailRequired\": \"التفاصيل (مطلوبة عند اختيار أخرى)\",\n },\n reportList: {\n target: {\n post: 'منشور',\n comment: 'تعليق',\n },\n deletedComment: 'نص التعليق غير متاح',\n blindComment: 'إخفاء هذا التعليق أيضًا',\n blindCommentHint: 'يخفي التعليق عن الجميع. يمكن للفريق استعادته من التعليق.',\n commentActionHint: 'يغيّر حالة البلاغ فقط. لا يخفي التعليق ولا يحذفه.',\n staffOnly: 'يمكن لفريق العمل فقط عرض البلاغات.',\n loadFailed: 'تعذّر تحميل القائمة: {error}',\n empty: 'لا توجد بلاغات معلّقة.',\n untitled: 'منشور بلا عنوان',\n author: 'بواسطة {name}',\n dismiss: 'رفض',\n\n \"tabs\": {\n \"open\": \"قيد الانتظار\",\n \"processed\": \"سجل المراجعات\"\n },\n \"filterLabel\": \"تصفية البلاغات\",\n \"orderHint\": \"الأحدث استلامًا أولًا.\",\n \"historyEmpty\": \"لا يوجد سجل مراجعات.\",\n \"confirm\": \"وضع علامة تمت المراجعة\",\n \"dismissTitle\": \"رفض البلاغ\",\n \"resolveTitle\": \"إكمال المراجعة\",\n \"actionHint\": \"يغير حالة البلاغ فقط، ولا يخفي المنشور أو يحذفه.\",\n \"publicNote\": \"هذا السبب ظاهر أيضًا لمقدّم البلاغ.\",\n \"reviewer\": \"المراجع\",\n \"reviewNote\": \"سبب القرار\",\n \"unknownReviewer\": \"مراجع غير معروف\",\n \"actionFailed\": \"تعذرت المعالجة. حاول مجددًا.\",\n },\n reports: {\n cannotReportOwnComment: 'لا يمكنك الإبلاغ عن تعليقك.',\n alreadyReportedComment: 'لقد أبلغت عن هذا التعليق بالفعل.',\n reason: {\n spam: 'رسائل مزعجة / إعلانات',\n abuse: 'إساءة / كراهية / تحرّش',\n adult: 'محتوى جنسي',\n illegal: 'محتوى غير قانوني',\n other: 'أخرى',\n },\n fallbackLabel: 'بلاغ',\n signInRequired: 'يُرجى تسجيل الدخول.',\n cannotReportOwn: 'لا يمكنك الإبلاغ عن منشورك.',\n reasonRequired: 'يُرجى اختيار سبب.',\n detailTooLong: 'يمكن أن تصل التفاصيل إلى {max} حرف كحد أقصى.',\n\n \"otherDetailRequired\": \"أدخل التفاصيل عند اختيار أخرى.\",\n \"reviewNoteRequired\": \"أدخل سبب القرار.\",\n \"alreadyReviewed\": \"تمت مراجعة هذا البلاغ مسبقًا. راجع القائمة.\",\n \"manageRequired\": \"ليست لديك صلاحية مراجعة هذا البلاغ.\",\n \"alreadyReported\": \"لقد أبلغت عن هذا المنشور مسبقًا.\",\n \"statusLoadFailed\": \"تعذر تحميل الحالة. حدّث الصفحة.\",\n },\n sectionUtil: {\n kind: {\n list: 'قائمة المنشورات',\n post: 'منشورات',\n comments: 'تعليقات',\n },\n sort: {\n latest: 'الأحدث',\n likes: 'الأكثر إعجابًا',\n },\n untitledPost: 'منشور',\n view: {\n media: 'الوسائط',\n list: 'قائمة',\n },\n },\n sections: {\n defaultTitle: 'القسم {n}',\n },\n seo: {\n allCategory: 'الكل',\n boardDescription: 'لوحة {name}',\n allDescription: 'اللوحة — الإعلانات وأخبار المجتمع.',\n postFallbackTitle: 'منشور | {site}',\n postFallbackDescription: 'اللوحة',\n photo: 'صورة',\n postDescriptionFallback: 'منشور في اللوحة',\n listTitle: '{name} | {site}',\n listTitleAll: 'اللوحة | {site}',\n listDescription: '{name} — تابع أحدث المنشورات.',\n listDescriptionAll: 'اللوحة — إعلانات وقصص.',\n },\n settings: {\n aiTitle: {\n label: 'كتابة العناوين بالذكاء الاصطناعي',\n help: 'عند ترك عنوان المنشور الجديد فارغًا، يكتب الذكاء الاصطناعي عنوانًا من النص (أو من أول صورة إن لم يوجد نص). تُرسل الصور إلى Google AI لهذا الغرض فقط. أوقفه لإلزام كتابة العنوان ولإيقاف إرسال الصور.',\n },\n site: {\n apply: 'تطبيق',\n applied: 'تم التطبيق.',\n title: 'الإعدادات العامة',\n help: 'تُطبَّق على الموقع كله، وتتغلّب على إعدادات التطبيق المضيف، وتسري فور تغييرها.',\n ai: { label: 'استخدام ميزات الذكاء الاصطناعي', help: 'أوقفه إذا تعذّر استخدام الذكاء الاصطناعي، مثلًا بسبب التكلفة. يوقف الترجمة ومساعد الكتابة وعناوين الذكاء الاصطناعي والإشراف بالذكاء الاصطناعي، ولن تُرسل الصور إليه. يستمر عمل فحص الكلمات المحظورة.' },\n i18n: { label: 'استخدام التدويل', help: 'عند إيقافه تُثبَّت كل الشاشات على اللغة المختارة أدناه وتتوقف الترجمة. لا تُحذف الترجمات المحفوظة.' },\n locales: { label: 'اللغات المتاحة', help: 'تُترجم اللغات الـ {count} المختارة فقط وتظهر في قائمة اللغات. لا تُنشأ ترجمات جديدة للغات غير المختارة، ولا تُحذف الترجمات المحفوظة.' },\n locale: { label: 'اللغة الافتراضية', help: 'اللغة المستخدمة عندما لا يحدد التطبيق المضيف لغة.', fixedLabel: 'اللغة الثابتة', fixedHelp: 'تُعرض كل الشاشات بهذه اللغة.' },\n },\n i18nBoard: {\n label: 'التدويل',\n help: 'عند التفعيل تُترجم تلقائيًا إلى {count} لغات اسم اللوحة ووصفها والمنشورات والتعليقات الجديدة وتُحفظ معها. عند الإيقاف يُعرض النص الأصلي فقط.',\n existing: 'ترجمة المنشورات الحالية أيضًا',\n },\n about: {\n label: 'إظهار About memi-board',\n help: 'يعرض رابط About memi-board ونافذته في أسفل كل شاشة لوحة. أوقفه لإخفائه في الموقع كله.',\n },\n postTranslations: {\n label: 'ترجمة المنشورات الحالية',\n help: 'يبحث عن المنشورات التي ترجمتها مفقودة أو لم تعد تطابق الأصل، ثم يترجمها ويحفظها دفعة واحدة. استخدمه للوحات التي أُوقفت فيها الترجمة التلقائية أو لاستكمال المنشورات التي فاتتها الترجمة. لا يستهلك حصة الذكاء الاصطناعي اليومية.',\n scan: 'البحث عن منشورات للترجمة',\n run: 'ترجمة {count} منشورات',\n confirm: 'سيتم ترجمة {count} منشورات وحفظها مع استدعاء الذكاء الاصطناعي لكل منها. هل تتابع؟',\n progress: 'جارٍ الترجمة… اكتمل {done}، فشل {failed}',\n allDone: 'جميع المنشورات المنشورة وعددها {total} ترجماتها محدّثة.',\n found: '{count} من أصل {total} منشورات منشورة تحتاج إلى ترجمة.',\n failed: 'تعذّرت ترجمة {count} منشورات. ابحث مرة أخرى وأعد المحاولة.',\n },\n loading: 'جارٍ تحميل الإعدادات…',\n noAccess: 'ليس لديك صلاحية الوصول',\n notFound: {\n title: 'لم يتم العثور على اللوحة',\n checkAddress: 'يُرجى التحقق من العنوان.',\n checkBoardAddress: 'يُرجى التحقق من عنوان اللوحة.',\n },\n newBoard: {\n title: 'هذه اللوحة غير موجودة بعد',\n description: 'املأ البيانات أدناه واحفظها لإنشائها بهذا المعرّف.',\n },\n noLabel: 'بلا تسمية',\n option: {\n default: 'قياسي',\n },\n id: {\n label: 'معرّف الفئة',\n help: 'يُستخدم في URL والبيانات',\n },\n writeRole: {\n label: 'من يمكنه النشر',\n help: 'الحد الأدنى من الدور المطلوب للنشر في هذه الفئة',\n helpShort: 'الحد الأدنى من الدور المطلوب للنشر',\n options: {\n user: 'المستخدمون فما فوق',\n staff: 'فريق العمل فما فوق',\n admin: 'المشرفون فقط',\n },\n },\n commentWriteRole: {\n label: 'من يمكنه التعليق',\n help: 'الحد الأدنى من الدور المطلوب للتعليق في هذه الفئة',\n helpShort: 'الحد الأدنى من الدور المطلوب للتعليق',\n hiddenFixed: 'فريق العمل المعيَّن فقط (ثابت للوحات المخفية)',\n },\n staff: {\n label: 'فريق العمل المعيَّن',\n help: 'يمكن لفريق العمل المحدد فقط إعداد هذه اللوحة وإدارتها. اتركه فارغًا ليقتصر الأمر على المشرفين',\n placeholder: 'المشرفون فقط (دون تعيين فريق عمل)',\n },\n label: {\n label: 'الاسم المعروض',\n help: 'الاسم الذي يراه المستخدمون',\n },\n description: {\n label: 'الوصف',\n help: 'يظهر أعلى اللوحة وفي أماكن أخرى',\n placeholder: 'وصف قصير لهذه اللوحة (اختياري)',\n },\n visibility: {\n label: 'الظهور',\n options: {\n public: {\n label: 'ظاهرة',\n description: 'تظهر في القائمة الكاملة وعوامل التصفية',\n },\n hidden: {\n label: 'مخفية',\n description: 'يوميات أو خاصة. يمكن لفريق العمل المعيَّن فقط التعليق',\n },\n },\n },\n listView: {\n label: 'عرض القائمة',\n help: 'طريقة عرض قائمة المنشورات',\n options: {\n card: 'بطاقة',\n dense: 'مضغوط',\n video: 'فيديو',\n },\n },\n editorType: {\n label: 'نموذج النشر',\n help: 'طريقة كتابة المنشورات',\n options: {\n default: 'كتابة عنوان ونص',\n image: 'إضافة عدة صور وصورة غلاف',\n },\n },\n bulk: {\n title: 'تطبيق على كل اللوحات',\n apply: 'تطبيق على {count} لوحات',\n applyShort: 'تطبيق',\n confirmTitle: 'تطبيق على كل اللوحات',\n translateUntranslated: 'ترجمة اللوحات غير المترجمة ({count})',\n },\n translationLocales: {\n label: 'لغات الترجمة',\n },\n locale: {\n label: 'لغة اللوحة',\n auto: 'تلقائي (حسب لغة الموقع)',\n },\n autoTranslate: {\n action: \"ترجمة إلى {count} لغات\",\n manualHelp: \"ترجم اسم العرض والوصف معًا، ثم اضغط على حفظ للتطبيق.\",\n pending: \"الترجمات إلى {count} لغات جاهزة. اضغط على حفظ للتطبيق.\",\n manualFailed: \"فشلت الترجمة. تم الاحتفاظ بالنص. يرجى المحاولة مرة أخرى.\",\n label: 'الترجمة إلى {count} لغات عند الحفظ',\n help: 'عند التشغيل تُترجم الاسم والوصف إلى {count} لغات. عند الإيقاف لا تُترجم. لا تُعاد ترجمة النص إذا لم يتغير.',\n failed: 'حُفظت الإعدادات، لكن فشلت الترجمة إلى {count} لغات. احفظ مرة أخرى.',\n ready: 'الاسم والوصف محفوظان بـ {count} لغات.',\n },\n action: {\n moveDown: 'للأسفل',\n goToBoard: 'الانتقال إلى اللوحة',\n deleteBoard: 'حذف اللوحة',\n create: 'إنشاء',\n },\n newCategoryPlaceholder: 'اسم الفئة الجديدة',\n savedCategory: 'تم حفظ الفئة «{label}».',\n savedSettings: 'تم حفظ إعدادات اللوحة.',\n created: 'تم إنشاء اللوحة.',\n error: {\n orderFailed: 'تعذّر حفظ ترتيب الفئات.',\n deleteFailed: 'تعذّر حذف اللوحة وبياناتها.',\n saveFailed: 'تعذّر حفظ إعدادات اللوحة.',\n deleteAllFailed: 'تعذّر حذف بيانات اللوحة.',\n },\n danger: {\n title: 'منطقة الخطر',\n confirmLabel: 'اكتب «{phrase}» للتأكيد',\n phrase: 'حذف بيانات اللوحة',\n button: 'حذف كل البيانات',\n done: 'تم حذف كل بيانات اللوحة.',\n },\n },\n shareButton: {\n copied: 'تم نسخ الرابط',\n },\n signIn: {\n withGoogle: 'تسجيل الدخول باستخدام Google',\n withApple: 'تسجيل الدخول باستخدام Apple',\n or: 'أو',\n name: 'الاسم',\n email: 'البريد الإلكتروني',\n password: 'كلمة المرور',\n signUp: 'إنشاء حساب',\n toSignUp: 'ليس لديك حساب؟ أنشئ حسابًا',\n toSignIn: 'لديك حساب بالفعل؟ سجّل الدخول',\n },\n storage: {\n sourceTooLarge: 'يجب ألا يتجاوز حجم الصورة الأصلية {max}MB.',\n imageOnly: 'يمكن رفع ملفات الصور فقط.',\n canvasUnavailable: 'Canvas غير متاح',\n compressFailed: 'فشل الضغط',\n loadFailed: 'فشل تحميل الصورة',\n },\n swipeHint: {\n title: 'جرّب السحب يمينًا أو يسارًا',\n description: 'اسحب لليسار للمنشور التالي، ولليمين للمنشور السابق.',\n },\n userCommentList: {\n loadFailed: 'تعذّر تحميل القائمة: {error}',\n empty: 'لا توجد تعليقات بعد.',\n blinded: 'أخفى المشرف هذا التعليق.',\n likes: 'الإعجابات {count}',\n },\n userPostList: {\n loadFailed: 'تعذّر تحميل القائمة: {error}',\n empty: 'لا توجد منشورات بعد.',\n },\n users: {\n changeRoleFailed: 'تعذّر تغيير الدور.',\n loading: 'جارٍ تحميل المستخدمين…',\n noPermission: {\n title: 'لا توجد صلاحية',\n description: 'يمكن لمشرفي اللوحة فقط إدارة أدوار المستخدمين.',\n },\n empty: 'لم يسجّل أي مستخدم الدخول إلى اللوحة بعد.',\n noName: 'بلا اسم',\n moderationWarnings: 'تحذيرات المحتوى: {count}',\n },\n writingAssistant: {\n dailyLimit: 'يمكن استخدام مساعد الكتابة بالذكاء الاصطناعي حتى {limit} مرة في اليوم. حاول مرة أخرى بعد حوالي {hours} ساعة.',\n loginRequired: 'سجّل الدخول لاستخدام مساعد الكتابة بالذكاء الاصطناعي.',\n userMissing: 'تعذّر التحقق من معلومات المستخدم. يُرجى المحاولة مرة أخرى.',\n contentRequired: 'أدخل أولًا محتوى ليعمل عليه AI.',\n customRequired: 'أدخل تعليمات لطريقة إعادة الصياغة.',\n emptyResult: 'لم يتمكن AI من إنتاج نتيجة. يُرجى المحاولة مرة أخرى.',\n translateEmpty: 'أدخل عنوانًا أو نصًا للترجمة أولًا.',\n translateTooLong: 'لا يمكن حفظ نص أطول من {limit} حرفًا بـ {count} لغات. اختصره ثم أعد المحاولة.',\n translateIncomplete: 'عادت بعض اللغات فارغة. يُرجى المحاولة مرة أخرى.',\n failed: 'فشلت مهمة AI. يُرجى المحاولة مرة أخرى.',\n actions: {\n proofread: 'تدقيق الإملاء',\n polish: 'تحسين الجمل',\n continue: 'متابعة الكتابة',\n summarize: 'تلخيص',\n translateEn: 'الترجمة إلى الإنجليزية',\n translateKo: 'الترجمة إلى الكورية',\n translateAll: 'ترجمة وحفظ بـ {count} لغات',\n translateSaved: 'تم الحفظ بـ {count} لغات. يرى القارئ ترجمة لغته.',\n translatePending: 'ترجمات {count} لغات جاهزة. تُحفظ مع المنشور.',\n translateEmpty: 'أدخل عنوانًا أو نصًا للترجمة أولًا.',\n title: 'إنشاء عنوان من النص',\n custom: 'إعادة الصياغة بأسلوب مخصص…',\n },\n },\n}\n\nexport default messages\n"],"mappings":"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GAA+B;EACzK;EACA,WAAW;GACT,OAAO;GACP,MAAM;GACN,UAAU;EACZ;EACA,OAAO;GACL,OAAO;GACP,MAAM;EACR;EACA,kBAAkB;GAChB,OAAO;GACP,MAAM;GACN,MAAM;GACN,KAAK;GACL,SAAS;GACT,UAAU;GACV,SAAS;GACT,OAAO;GACP,QAAQ;EACV;EACA,SAAS;EACT,UAAU;EACV,UAAU;GACR,OAAO;GACP,cAAc;GACd,mBAAmB;EACrB;EACA,UAAU;GACR,OAAO;GACP,aAAa;EACf;EACA,SAAS;EACT,QAAQ,EACN,SAAS,QACX;EACA,IAAI;GACF,OAAO;GACP,MAAM;EACR;EACA,WAAW;GACT,OAAO;GACP,MAAM;GACN,WAAW;GACX,SAAS;IACP,MAAM;IACN,OAAO;IACP,OAAO;GACT;EACF;EACA,kBAAkB;GAChB,OAAO;GACP,MAAM;GACN,WAAW;GACX,aAAa;EACf;EACA,OAAO;GACL,OAAO;GACP,MAAM;GACN,aAAa;EACf;EACA,OAAO;GACL,OAAO;GACP,MAAM;EACR;EACA,aAAa;GACX,OAAO;GACP,MAAM;GACN,aAAa;EACf;EACA,YAAY;GACV,OAAO;GACP,SAAS;IACP,QAAQ;KACN,OAAO;KACP,aAAa;IACf;IACA,QAAQ;KACN,OAAO;KACP,aAAa;IACf;GACF;EACF;EACA,UAAU;GACR,OAAO;GACP,MAAM;GACN,SAAS;IACP,MAAM;IACN,OAAO;IACP,OAAO;GACT;EACF;EACA,YAAY;GACV,OAAO;GACP,MAAM;GACN,SAAS;IACP,SAAS;IACT,OAAO;GACT;EACF;EACA,MAAM;GACJ,OAAO;GACP,OAAO;GACP,YAAY;GACZ,cAAc;GACd,uBAAuB;EACzB;EACA,oBAAoB,EAClB,OAAO,eACT;EACA,QAAQ;GACN,OAAO;GACP,MAAM;EACR;EACA,eAAe;GACb,QAAQ;GACR,YAAY;GACZ,SAAS;GACT,cAAc;GACd,OAAO;GACP,MAAM;GACN,QAAQ;GACR,OAAO;EACT;EACA,QAAQ;GACN,UAAU;GACV,WAAW;GACX,aAAa;GACb,QAAQ;EACV;EACA,wBAAwB;EACxB,eAAe;EACf,eAAe;EACf,SAAS;EACT,OAAO;GACL,aAAa;GACb,cAAc;GACd,YAAY;GACZ,iBAAiB;EACnB;EACA,QAAQ;GACN,OAAO;GACP,cAAc;GACd,QAAQ;GACR,QAAQ;GACR,MAAM;EACR;CACF;CACA,aAAa,EACX,QAAQ,gBACV;CACA,QAAQ;EACN,YAAY;EACZ,WAAW;EACX,IAAI;EACJ,MAAM;EACN,OAAO;EACP,UAAU;EACV,QAAQ;EACR,UAAU;EACV,UAAU;CACZ;CACA,SAAS;EACP,gBAAgB;EAChB,WAAW;EACX,mBAAmB;EACnB,gBAAgB;EAChB,YAAY;CACd;CACA,WAAW;EACT,OAAO;EACP,aAAa;CACf;CACA,iBAAiB;EACf,YAAY;EACZ,OAAO;EACP,SAAS;EACT,OAAO;CACT;CACA,cAAc;EACZ,YAAY;EACZ,OAAO;CACT;CACA,OAAO;EACL,kBAAkB;EAClB,SAAS;EACT,cAAc;GACZ,OAAO;GACP,aAAa;EACf;EACA,OAAO;EACP,QAAQ;EACR,oBAAoB;CACtB;CACA,kBAAkB;EAChB,YAAY;EACZ,eAAe;EACf,aAAa;EACb,iBAAiB;EACjB,gBAAgB;EAChB,aAAa;EACb,gBAAgB;EAChB,kBAAkB;EAClB,qBAAqB;EACrB,QAAQ;EACR,SAAS;GACP,WAAW;GACX,QAAQ;GACR,UAAU;GACV,WAAW;GACX,aAAa;GACb,aAAa;GACb,cAAc;GACd,gBAAgB;GAChB,kBAAkB;GAClB,gBAAgB;GAChB,OAAO;GACP,QAAQ;EACV;CACF;AACF"}
|
|
@@ -84,69 +84,78 @@ function C(e) {
|
|
|
84
84
|
usersCollection: e.usersCollection?.trim() || "memiBoardUsers"
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
-
function
|
|
87
|
+
function te(e, t) {
|
|
88
88
|
return l(e, t.settingsCollection);
|
|
89
89
|
}
|
|
90
|
-
function
|
|
90
|
+
function ne(e, t, n) {
|
|
91
91
|
return u(e, t.settingsCollection, n);
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function re(e, t) {
|
|
94
94
|
return l(e, t.postsCollection);
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function ie(e, t, n) {
|
|
97
97
|
return u(e, t.postsCollection, n);
|
|
98
98
|
}
|
|
99
|
-
function
|
|
99
|
+
function ae(e, t, n) {
|
|
100
100
|
return u(e, t.postsCollection, n, "body", "main");
|
|
101
101
|
}
|
|
102
|
-
function
|
|
102
|
+
function oe(e, t) {
|
|
103
103
|
return l(e, t.commentsCollection);
|
|
104
104
|
}
|
|
105
|
-
function
|
|
105
|
+
function se(e, t, n) {
|
|
106
106
|
return u(e, t.commentsCollection, n);
|
|
107
107
|
}
|
|
108
|
-
function
|
|
108
|
+
function ce(e, t) {
|
|
109
109
|
return l(e, t.likesCollection);
|
|
110
110
|
}
|
|
111
|
-
function
|
|
111
|
+
function w(e, t) {
|
|
112
112
|
return `${e}_${t}`;
|
|
113
113
|
}
|
|
114
|
-
function
|
|
115
|
-
return u(e, t.likesCollection,
|
|
114
|
+
function T(e, t, n, r) {
|
|
115
|
+
return u(e, t.likesCollection, w(n, r));
|
|
116
116
|
}
|
|
117
|
-
function
|
|
117
|
+
function le(e, t) {
|
|
118
118
|
return l(e, t.reportsCollection);
|
|
119
119
|
}
|
|
120
|
-
function
|
|
120
|
+
function E(e, t) {
|
|
121
121
|
return `${e}_${t}`;
|
|
122
122
|
}
|
|
123
|
-
function
|
|
124
|
-
return u(e, t.reportsCollection,
|
|
123
|
+
function D(e, t, n, r) {
|
|
124
|
+
return u(e, t.reportsCollection, E(n, r));
|
|
125
125
|
}
|
|
126
126
|
function O(e, t) {
|
|
127
|
+
return `c_${e}_${t}`;
|
|
128
|
+
}
|
|
129
|
+
function k(e, t, n, r) {
|
|
130
|
+
return u(e, t.reportsCollection, O(n, r));
|
|
131
|
+
}
|
|
132
|
+
function ue(e, t, n) {
|
|
133
|
+
return u(e, t.reportsCollection, n);
|
|
134
|
+
}
|
|
135
|
+
function de(e, t) {
|
|
127
136
|
return l(e, t.usersCollection);
|
|
128
137
|
}
|
|
129
|
-
function
|
|
138
|
+
function fe(e, t, n) {
|
|
130
139
|
return u(e, t.usersCollection, n);
|
|
131
140
|
}
|
|
132
|
-
function
|
|
141
|
+
function pe(e, t, n) {
|
|
133
142
|
return u(e, t.usersCollection, n, "private", "info");
|
|
134
143
|
}
|
|
135
|
-
function
|
|
144
|
+
function me(e, t, n, r) {
|
|
136
145
|
return u(e, t.usersCollection, n, "memos", r);
|
|
137
146
|
}
|
|
138
|
-
function
|
|
147
|
+
function he(e, t) {
|
|
139
148
|
return `${e.postsCollection}/${t}`;
|
|
140
149
|
}
|
|
141
|
-
function
|
|
150
|
+
function ge(e, t) {
|
|
142
151
|
return `${e.postsCollection}/${e.usersCollection}/${t}`;
|
|
143
152
|
}
|
|
144
153
|
//#endregion
|
|
145
154
|
//#region src/config.ts
|
|
146
|
-
var
|
|
147
|
-
function
|
|
155
|
+
var A = "__MEMI_BOARD_CONFIG__";
|
|
156
|
+
function j() {
|
|
148
157
|
let e = globalThis;
|
|
149
|
-
return e[
|
|
158
|
+
return e[A] || (e[A] = o({
|
|
150
159
|
postsCollection: _,
|
|
151
160
|
commentsCollection: v,
|
|
152
161
|
likesCollection: y,
|
|
@@ -170,10 +179,10 @@ function M() {
|
|
|
170
179
|
defaultOgImage: "",
|
|
171
180
|
basePath: "/board"
|
|
172
181
|
}
|
|
173
|
-
})), e[
|
|
182
|
+
})), e[A];
|
|
174
183
|
}
|
|
175
|
-
function
|
|
176
|
-
let t =
|
|
184
|
+
function _e(e) {
|
|
185
|
+
let t = j();
|
|
177
186
|
e.postsCollection != null && e.postsCollection !== "" && (t.postsCollection = e.postsCollection.trim()), e.commentsCollection != null && e.commentsCollection !== "" && (t.commentsCollection = e.commentsCollection.trim()), e.likesCollection != null && e.likesCollection !== "" && (t.likesCollection = e.likesCollection.trim()), e.reportsCollection != null && e.reportsCollection !== "" && (t.reportsCollection = e.reportsCollection.trim()), e.settingsCollection != null && e.settingsCollection !== "" && (t.settingsCollection = e.settingsCollection.trim()), e.usersCollection != null && e.usersCollection !== "" && (t.usersCollection = e.usersCollection.trim()), e.auth && Object.assign(t.auth, e.auth), e.moderation && Object.assign(t.moderation, e.moderation), e.seo && Object.assign(t.seo, e.seo), e.i18n && (t.i18n = {
|
|
178
187
|
...t.i18n,
|
|
179
188
|
...e.i18n
|
|
@@ -185,49 +194,49 @@ function pe(e) {
|
|
|
185
194
|
...e.bannerGeneration
|
|
186
195
|
}), e.roleLabels && (t.roleLabels = { ...e.roleLabels }), e.locale && (t.locale = e.locale);
|
|
187
196
|
}
|
|
197
|
+
function M() {
|
|
198
|
+
return j();
|
|
199
|
+
}
|
|
188
200
|
function N() {
|
|
189
|
-
return M();
|
|
201
|
+
return M().site?.disableAi !== !0;
|
|
190
202
|
}
|
|
191
203
|
function P() {
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
function me() {
|
|
195
|
-
if (!P()) throw Object.assign(/* @__PURE__ */ Error("AI features are disabled for this board service."), { code: "memi-board/ai-disabled" });
|
|
204
|
+
if (!N()) throw Object.assign(/* @__PURE__ */ Error("AI features are disabled for this board service."), { code: "memi-board/ai-disabled" });
|
|
196
205
|
}
|
|
197
206
|
function F() {
|
|
198
|
-
let e =
|
|
207
|
+
let e = M();
|
|
199
208
|
return e.site?.disableI18n !== !0 && e.i18n?.enabled !== !1;
|
|
200
209
|
}
|
|
201
210
|
function I() {
|
|
202
|
-
return
|
|
211
|
+
return N() && F() && M().translation?.enabled !== !1;
|
|
203
212
|
}
|
|
204
213
|
function L() {
|
|
205
|
-
let e = d.map((e) => e.code), t =
|
|
214
|
+
let e = d.map((e) => e.code), t = M().site?.locales;
|
|
206
215
|
if (!F() || !t?.length) return e;
|
|
207
216
|
let n = new Set(t.map((e) => h(e)).filter(Boolean)), r = e.filter((e) => n.has(e));
|
|
208
217
|
return r.length ? r : e;
|
|
209
218
|
}
|
|
210
219
|
function R() {
|
|
211
|
-
let e =
|
|
220
|
+
let e = M(), t = e.site?.locale || e.locale, n = L(), r = h(t);
|
|
212
221
|
return n.length === d.length || r && n.includes(r) ? t : n[0];
|
|
213
222
|
}
|
|
214
|
-
function
|
|
215
|
-
|
|
223
|
+
function ve(e) {
|
|
224
|
+
M().site = {
|
|
216
225
|
disableAi: e?.disableAi === !0,
|
|
217
226
|
disableI18n: e?.disableI18n === !0,
|
|
218
227
|
locale: typeof e?.locale == "string" && e.locale ? e.locale : void 0,
|
|
219
228
|
locales: Array.isArray(e?.locales) ? e.locales.filter((e) => typeof e == "string") : void 0
|
|
220
229
|
};
|
|
221
230
|
}
|
|
222
|
-
function
|
|
231
|
+
function z() {
|
|
223
232
|
if (!I()) throw Object.assign(/* @__PURE__ */ Error("Content translation is disabled for this board service."), { code: "memi-board/translation-disabled" });
|
|
224
233
|
}
|
|
225
|
-
function
|
|
226
|
-
return C(
|
|
234
|
+
function ye() {
|
|
235
|
+
return C(M());
|
|
227
236
|
}
|
|
228
237
|
//#endregion
|
|
229
238
|
//#region src/i18n/messages/ko/index.ts
|
|
230
|
-
var
|
|
239
|
+
var be = {
|
|
231
240
|
accountDeletion: {
|
|
232
241
|
title: "회원 탈퇴",
|
|
233
242
|
intro: "계정과 개인정보를 삭제하려면 탈퇴를 진행해 주세요.",
|
|
@@ -773,6 +782,7 @@ var _e = {
|
|
|
773
782
|
bioPlaceholder: "나를 소개해 보세요"
|
|
774
783
|
},
|
|
775
784
|
reportButton: {
|
|
785
|
+
commentTitle: "댓글 신고",
|
|
776
786
|
failed: "신고하지 못했습니다.",
|
|
777
787
|
reported: "신고함",
|
|
778
788
|
title: "게시물 신고",
|
|
@@ -797,6 +807,14 @@ var _e = {
|
|
|
797
807
|
detailRequired: "자세한 내용 (기타 사유는 필수)"
|
|
798
808
|
},
|
|
799
809
|
reportList: {
|
|
810
|
+
target: {
|
|
811
|
+
post: "글",
|
|
812
|
+
comment: "댓글"
|
|
813
|
+
},
|
|
814
|
+
deletedComment: "댓글 내용 없음",
|
|
815
|
+
blindComment: "이 댓글도 블라인드 처리",
|
|
816
|
+
blindCommentHint: "모든 사용자에게 댓글을 가립니다. 스태프가 댓글에서 다시 해제할 수 있습니다.",
|
|
817
|
+
commentActionHint: "이 처리는 신고 상태만 변경합니다. 댓글을 숨기거나 삭제하지 않습니다.",
|
|
800
818
|
staffOnly: "스태프만 신고 목록을 볼 수 있습니다.",
|
|
801
819
|
loadFailed: "목록을 불러오지 못했습니다: {error}",
|
|
802
820
|
empty: "대기 중인 신고가 없습니다.",
|
|
@@ -821,6 +839,8 @@ var _e = {
|
|
|
821
839
|
actionFailed: "처리하지 못했습니다. 다시 시도해 주세요."
|
|
822
840
|
},
|
|
823
841
|
reports: {
|
|
842
|
+
cannotReportOwnComment: "자신의 댓글은 신고할 수 없습니다.",
|
|
843
|
+
alreadyReportedComment: "이미 신고한 댓글입니다.",
|
|
824
844
|
reason: {
|
|
825
845
|
spam: "스팸·광고",
|
|
826
846
|
abuse: "욕설·혐오·괴롭힘",
|
|
@@ -1223,28 +1243,28 @@ var _e = {
|
|
|
1223
1243
|
custom: "커스텀 스타일로 바꾸기…"
|
|
1224
1244
|
}
|
|
1225
1245
|
}
|
|
1226
|
-
},
|
|
1227
|
-
en: () => import("./en-
|
|
1228
|
-
ja: () => import("./ja-
|
|
1229
|
-
de: () => import("./de-
|
|
1230
|
-
fr: () => import("./fr-
|
|
1231
|
-
es: () => import("./es-
|
|
1232
|
-
pt: () => import("./pt-
|
|
1233
|
-
zh: () => import("./zh-
|
|
1234
|
-
ar: () => import("./ar-
|
|
1235
|
-
id: () => import("./id-
|
|
1246
|
+
}, xe = {
|
|
1247
|
+
en: () => import("./en-lbbULqlq.js"),
|
|
1248
|
+
ja: () => import("./ja-B2iAAzYv.js"),
|
|
1249
|
+
de: () => import("./de-CDaEV4cd.js"),
|
|
1250
|
+
fr: () => import("./fr-CQDZqx5d.js"),
|
|
1251
|
+
es: () => import("./es-D8LzeTe0.js"),
|
|
1252
|
+
pt: () => import("./pt-CXAWS0Km.js"),
|
|
1253
|
+
zh: () => import("./zh-ByjHExJt.js"),
|
|
1254
|
+
ar: () => import("./ar-B6HWpN6c.js"),
|
|
1255
|
+
id: () => import("./id-CIaQbTzK.js")
|
|
1236
1256
|
}, B = "__MEMI_BOARD_I18N__";
|
|
1237
1257
|
function V() {
|
|
1238
1258
|
let e = globalThis;
|
|
1239
1259
|
return e[B] ??= {
|
|
1240
|
-
messages: { ko:
|
|
1260
|
+
messages: { ko: be },
|
|
1241
1261
|
pending: {},
|
|
1242
1262
|
version: s(0)
|
|
1243
1263
|
}, e[B];
|
|
1244
1264
|
}
|
|
1245
1265
|
function H(e) {
|
|
1246
1266
|
let t = V();
|
|
1247
|
-
return t.messages[e] || e === "ko" ? Promise.resolve() : (t.pending[e] ??=
|
|
1267
|
+
return t.messages[e] || e === "ko" ? Promise.resolve() : (t.pending[e] ??= xe[e]().then((n) => {
|
|
1248
1268
|
t.messages[e] = n.default, t.version.value++;
|
|
1249
1269
|
}).catch((n) => {
|
|
1250
1270
|
delete t.pending[e], console.warn(`[memi-board] failed to load locale "${e}"`, n);
|
|
@@ -1253,7 +1273,7 @@ function H(e) {
|
|
|
1253
1273
|
function U(e) {
|
|
1254
1274
|
return e === "ko" ? Promise.resolve() : Promise.all([H(e), H("en")]).then(() => void 0);
|
|
1255
1275
|
}
|
|
1256
|
-
function
|
|
1276
|
+
function Se(e) {
|
|
1257
1277
|
return !!V().messages[e];
|
|
1258
1278
|
}
|
|
1259
1279
|
function W(e, t) {
|
|
@@ -1264,7 +1284,7 @@ function W(e, t) {
|
|
|
1264
1284
|
}
|
|
1265
1285
|
return typeof n == "string" ? n : void 0;
|
|
1266
1286
|
}
|
|
1267
|
-
function
|
|
1287
|
+
function Ce(e, t) {
|
|
1268
1288
|
return t ? e.replace(/\{(\w+)\}/g, (e, n) => {
|
|
1269
1289
|
let r = t[n];
|
|
1270
1290
|
return r == null ? e : String(r);
|
|
@@ -1274,7 +1294,7 @@ function G(e, t, n) {
|
|
|
1274
1294
|
let r = V();
|
|
1275
1295
|
r.version.value;
|
|
1276
1296
|
let i = e ?? "ko", a = W(r.messages[i], t) ?? (i === "ko" ? void 0 : W(r.messages.en, t)) ?? W(r.messages.ko, t);
|
|
1277
|
-
return a == null ? t :
|
|
1297
|
+
return a == null ? t : Ce(a, n);
|
|
1278
1298
|
}
|
|
1279
1299
|
//#endregion
|
|
1280
1300
|
//#region src/utils/formatDate.ts
|
|
@@ -1284,13 +1304,13 @@ function K(e) {
|
|
|
1284
1304
|
function q(e, t) {
|
|
1285
1305
|
return e?.toDate ? e.toDate().toLocaleDateString(K(t)) : "";
|
|
1286
1306
|
}
|
|
1287
|
-
var
|
|
1307
|
+
var we = 60, J = 3600, Te = 24 * J;
|
|
1288
1308
|
function Y(e, t = Date.now(), n) {
|
|
1289
1309
|
if (!e?.toDate) return G(n, "common.date.justNow");
|
|
1290
1310
|
let r = Math.max(0, Math.round((t - e.toDate().getTime()) / 1e3));
|
|
1291
1311
|
if (r < 45) return G(n, "common.date.fewSecondsAgo");
|
|
1292
|
-
let i = new Intl.RelativeTimeFormat(K(n), { numeric: "always" }), a = r /
|
|
1293
|
-
return r < 90 ? i.format(-1, "minute") : r < 2700 ? i.format(-Math.round(r /
|
|
1312
|
+
let i = new Intl.RelativeTimeFormat(K(n), { numeric: "always" }), a = r / Te;
|
|
1313
|
+
return r < 90 ? i.format(-1, "minute") : r < 2700 ? i.format(-Math.round(r / we), "minute") : r < 5400 ? i.format(-1, "hour") : r < 22 * J ? i.format(-Math.round(r / J), "hour") : r < 36 * J ? i.format(-1, "day") : a < 26 ? i.format(-Math.round(a), "day") : a < 46 ? i.format(-1, "month") : a < 320 ? i.format(-Math.round(a / 30.4), "month") : a < 548 ? i.format(-1, "year") : i.format(-Math.round(a / 365), "year");
|
|
1294
1314
|
}
|
|
1295
1315
|
function X(e, t) {
|
|
1296
1316
|
return e?.toDate ? new Intl.DateTimeFormat(K(t), {
|
|
@@ -1310,8 +1330,8 @@ function Z(e, t, n) {
|
|
|
1310
1330
|
//#endregion
|
|
1311
1331
|
//#region src/i18n/useMemiBoardI18n.ts
|
|
1312
1332
|
var Q = "memiBoard:hostLocale", $ = Symbol("memiBoard:boardLocale");
|
|
1313
|
-
function
|
|
1314
|
-
let s = n(), l = s ? r($, null) : null, u = s ? r(Q, null) : null, d =
|
|
1333
|
+
function Ee(o = {}) {
|
|
1334
|
+
let s = n(), l = s ? r($, null) : null, u = s ? r(Q, null) : null, d = M(), f = e(F), p = e(I), m = e(N), _ = e(() => f.value ? h(c(o.boardLocale)) ?? l?.value ?? h(c(u)) ?? h(R()) ?? "ko" : h(R()) ?? "ko");
|
|
1315
1335
|
o.boardLocale !== void 0 && s && a($, _), ee(_, (e) => void U(e), { immediate: !0 }), t() && i(() => U(_.value));
|
|
1316
1336
|
let v = e(() => g(_.value));
|
|
1317
1337
|
return {
|
|
@@ -1334,24 +1354,24 @@ function Ce(o = {}) {
|
|
|
1334
1354
|
}
|
|
1335
1355
|
//#endregion
|
|
1336
1356
|
//#region src/utils/slugify.ts
|
|
1337
|
-
var
|
|
1338
|
-
function
|
|
1357
|
+
var De = 40;
|
|
1358
|
+
function Oe(e) {
|
|
1339
1359
|
return e.trim().replace(/\s+/g, "-").replace(/[^a-zA-Z0-9가-힣ㄱ-ㅎㅏ-ㅣ-]/g, "").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
|
|
1340
1360
|
}
|
|
1341
|
-
function
|
|
1361
|
+
function ke(e, t = 60) {
|
|
1342
1362
|
return e.replace(/[^a-zA-Z0-9가-힣ㄱ-ㅎ._-]/g, "-").slice(0, t);
|
|
1343
1363
|
}
|
|
1344
1364
|
//#endregion
|
|
1345
1365
|
//#region src/utils/commentImages.ts
|
|
1346
|
-
var
|
|
1366
|
+
var Ae = /* @__PURE__ */ new Set([
|
|
1347
1367
|
"image/jpeg",
|
|
1348
1368
|
"image/png",
|
|
1349
1369
|
"image/gif",
|
|
1350
1370
|
"image/webp"
|
|
1351
1371
|
]);
|
|
1352
|
-
function
|
|
1372
|
+
function je(e) {
|
|
1353
1373
|
let t = (e.type || "").toLowerCase();
|
|
1354
|
-
if (
|
|
1374
|
+
if (Ae.has(t)) return !0;
|
|
1355
1375
|
let n = e.name.toLowerCase();
|
|
1356
1376
|
return [
|
|
1357
1377
|
".jpg",
|
|
@@ -1361,7 +1381,7 @@ function Oe(e) {
|
|
|
1361
1381
|
".webp"
|
|
1362
1382
|
].some((e) => n.endsWith(e));
|
|
1363
1383
|
}
|
|
1364
|
-
function
|
|
1384
|
+
function Me(e) {
|
|
1365
1385
|
if (!e?.length) return [];
|
|
1366
1386
|
for (let t of e) if (t?.name && t.url?.startsWith("https://") && t.path && !t.path.includes("..") && t.type?.startsWith("image/") && !(!Number.isFinite(t.size) || t.size <= 0)) return [{
|
|
1367
1387
|
name: t.name.slice(0, 200),
|
|
@@ -1372,7 +1392,7 @@ function ke(e) {
|
|
|
1372
1392
|
}];
|
|
1373
1393
|
return [];
|
|
1374
1394
|
}
|
|
1375
|
-
function
|
|
1395
|
+
function Ne(e, t) {
|
|
1376
1396
|
let n = t.endsWith("/") ? t : `${t}/`;
|
|
1377
1397
|
if (!Array.isArray(e)) return [];
|
|
1378
1398
|
let r = /* @__PURE__ */ new Set();
|
|
@@ -1384,6 +1404,6 @@ function Ae(e, t) {
|
|
|
1384
1404
|
return [...r];
|
|
1385
1405
|
}
|
|
1386
1406
|
//#endregion
|
|
1387
|
-
export {
|
|
1407
|
+
export { C as $, b as A, O as B, R as C, v as D, M as E, fe as F, ae as G, T as H, pe as I, re as J, ie as K, de as L, S as M, me as N, y as O, ge as P, le as Q, se as R, I as S, ye as T, w as U, oe as V, ce as W, ue as X, D as Y, E as Z, P as _, ke as a, g as at, N as b, Ee as c, Y as d, te as et, Z as f, ve as g, G as h, De as i, d as it, x as j, _ as k, q as l, U as m, je as n, f as nt, Oe as o, h as ot, Se as p, he as q, Me as r, p as rt, Q as s, Ne as t, ne as tt, X as u, z as v, L as w, F as x, _e as y, k as z };
|
|
1388
1408
|
|
|
1389
|
-
//# sourceMappingURL=commentImages-
|
|
1409
|
+
//# sourceMappingURL=commentImages-DZBDCMWH.js.map
|