pull main
This commit is contained in:
commit
80e426570e
|
|
@ -10,9 +10,13 @@ RUN npm install -g pnpm
|
|||
# Membuat direktori aplikasi dan mengatur sebagai working directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
|
||||
# Menyalin file penting terlebih dahulu untuk caching
|
||||
COPY package.json ./
|
||||
|
||||
# Menyalin direktori ckeditor5 jika diperlukan
|
||||
COPY vendor/ckeditor5 ./vendor/ckeditor5
|
||||
|
||||
# Install dependencies
|
||||
RUN pnpm install
|
||||
# RUN pnpm install --frozen-lockfile
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export async function generateMetadata({ params }: any): Promise<Metadata> {
|
|||
openGraph: {
|
||||
title: image?.title,
|
||||
description: image?.description,
|
||||
images: [`${image?.thumbnailLink}`],
|
||||
images: [`${image?.smallThumbnailLink}`],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export async function generateMetadata({ params }: any): Promise<Metadata> {
|
|||
openGraph: {
|
||||
title: video?.title,
|
||||
description: video?.description,
|
||||
videos: [`${video?.thumbnailLink}`],
|
||||
videos: [`${video?.smallThumbnailLink}`],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ type AuthStep = "login" | "email-setup" | "otp";
|
|||
|
||||
const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => {
|
||||
const [currentStep, setCurrentStep] = useState<AuthStep>("login");
|
||||
const [loginCredentials, setLoginCredentials] = useState<LoginFormData | null>(null);
|
||||
const [loginCredentials, setLoginCredentials] =
|
||||
useState<LoginFormData | null>(null);
|
||||
const { validateEmail } = useEmailValidation();
|
||||
const { login } = useAuth();
|
||||
|
||||
|
|
@ -23,6 +24,9 @@ const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => {
|
|||
try {
|
||||
const result = await validateEmail(data);
|
||||
switch (result) {
|
||||
case "skip":
|
||||
handleOTPSuccess();
|
||||
break;
|
||||
case "setup":
|
||||
setCurrentStep("email-setup");
|
||||
break;
|
||||
|
|
@ -112,11 +116,7 @@ const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => {
|
|||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthLayout>
|
||||
{renderCurrentStep()}
|
||||
</AuthLayout>
|
||||
);
|
||||
return <AuthLayout>{renderCurrentStep()}</AuthLayout>;
|
||||
};
|
||||
|
||||
export default AuthPage;
|
||||
|
|
|
|||
|
|
@ -1,105 +1,41 @@
|
|||
import React, { useRef, useEffect, useState, useCallback } from "react";
|
||||
import { Editor } from "@tinymce/tinymce-react";
|
||||
// components/custom-editor.js
|
||||
|
||||
import React from "react";
|
||||
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
||||
import Editor from "ckeditor5-custom-build";
|
||||
|
||||
function CustomEditor(props) {
|
||||
const editorRef = useRef(null);
|
||||
const [isEditorReady, setIsEditorReady] = useState(false);
|
||||
const [currentContent, setCurrentContent] = useState(props.initialData || "");
|
||||
|
||||
// Handle editor initialization
|
||||
const handleInit = useCallback((evt, editor) => {
|
||||
editorRef.current = editor;
|
||||
setIsEditorReady(true);
|
||||
|
||||
// Set initial content immediately when editor is ready
|
||||
if (currentContent) {
|
||||
editor.setContent(currentContent);
|
||||
}
|
||||
|
||||
// Simple onChange handler
|
||||
editor.on('change', () => {
|
||||
const content = editor.getContent();
|
||||
setCurrentContent(content);
|
||||
if (props.onChange) {
|
||||
props.onChange(content);
|
||||
}
|
||||
});
|
||||
}, [currentContent, props.onChange]);
|
||||
|
||||
// Watch for changes in initialData prop
|
||||
useEffect(() => {
|
||||
if (props.initialData !== currentContent) {
|
||||
setCurrentContent(props.initialData || "");
|
||||
|
||||
// Update editor content if editor is ready
|
||||
if (editorRef.current && isEditorReady) {
|
||||
editorRef.current.setContent(props.initialData || "");
|
||||
}
|
||||
}
|
||||
}, [props.initialData, currentContent, isEditorReady]);
|
||||
|
||||
// Handle initial data when editor becomes ready
|
||||
useEffect(() => {
|
||||
if (isEditorReady && currentContent && editorRef.current) {
|
||||
editorRef.current.setContent(currentContent);
|
||||
}
|
||||
}, [isEditorReady, currentContent]);
|
||||
|
||||
return (
|
||||
<Editor
|
||||
onInit={handleInit}
|
||||
apiKey={process.env.NEXT_PUBLIC_TINYMCE_API_KEY}
|
||||
init={{
|
||||
height: 400,
|
||||
menubar: false,
|
||||
plugins: [
|
||||
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
|
||||
'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
|
||||
'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount'
|
||||
<CKEditor
|
||||
editor={Editor}
|
||||
data={props.initialData}
|
||||
onChange={(event, editor) => {
|
||||
const data = editor.getData();
|
||||
console.log({ event, editor, data });
|
||||
props.onChange(data);
|
||||
}}
|
||||
config={{
|
||||
toolbar: [
|
||||
"heading",
|
||||
"fontsize",
|
||||
"bold",
|
||||
"italic",
|
||||
"link",
|
||||
"numberedList",
|
||||
"bulletedList",
|
||||
"undo",
|
||||
"redo",
|
||||
"alignment",
|
||||
"outdent",
|
||||
"indent",
|
||||
"blockQuote",
|
||||
"insertTable",
|
||||
"codeBlock",
|
||||
"sourceEditing",
|
||||
],
|
||||
toolbar: 'undo redo | blocks | ' +
|
||||
'bold italic forecolor | alignleft aligncenter ' +
|
||||
'alignright alignjustify | bullist numlist outdent indent | ' +
|
||||
'removeformat | table | code | help',
|
||||
content_style: `
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
.mce-content-body {
|
||||
padding: 16px;
|
||||
min-height: 368px;
|
||||
}
|
||||
`,
|
||||
placeholder: 'Start typing...',
|
||||
branding: false,
|
||||
elementpath: false,
|
||||
resize: false,
|
||||
statusbar: false,
|
||||
auto_focus: false,
|
||||
forced_root_block: 'p',
|
||||
entity_encoding: 'raw',
|
||||
verify_html: false,
|
||||
cleanup: false,
|
||||
cleanup_on_startup: false,
|
||||
auto_resize: false,
|
||||
paste_as_text: false,
|
||||
paste_enable_default_filters: true,
|
||||
paste_word_valid_elements: 'b,strong,i,em,h1,h2,h3,h4,h5,h6',
|
||||
paste_retain_style_properties: 'color background-color font-size font-weight',
|
||||
mobile: {
|
||||
theme: 'silver',
|
||||
plugins: ['lists', 'autolink', 'link', 'image', 'table'],
|
||||
toolbar: 'bold italic | bullist numlist | link image'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default CustomEditor;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,119 +1,16 @@
|
|||
import React, { useRef } from "react";
|
||||
import { Editor } from "@tinymce/tinymce-react";
|
||||
import React from "react";
|
||||
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
||||
import Editor from "ckeditor5-custom-build";
|
||||
|
||||
function ViewEditor(props) {
|
||||
const editorRef = useRef(null);
|
||||
|
||||
const handleInit = (evt, editor) => {
|
||||
editorRef.current = editor;
|
||||
|
||||
// Disable all editing capabilities
|
||||
editor.on('keydown keyup keypress input', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
editor.on('paste', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
editor.on('drop', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Disable mouse events that might allow editing
|
||||
editor.on('mousedown mousemove mouseup click dblclick', (e) => {
|
||||
if (e.target.closest('.mce-content-body')) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Editor
|
||||
onInit={handleInit}
|
||||
initialValue={props.initialData || ''}
|
||||
apiKey={process.env.NEXT_PUBLIC_TINYMCE_API_KEY}
|
||||
init={{
|
||||
height: props.height || 400,
|
||||
menubar: false,
|
||||
toolbar: false, // No toolbar for read-only mode
|
||||
plugins: [
|
||||
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap',
|
||||
'anchor', 'searchreplace', 'visualblocks', 'code',
|
||||
'insertdatetime', 'media', 'table'
|
||||
],
|
||||
content_style: `
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.mce-content-body {
|
||||
padding: 16px;
|
||||
min-height: ${(props.height || 400) - 32}px;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.mce-content-body * {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
`,
|
||||
readonly: true,
|
||||
branding: false,
|
||||
elementpath: false,
|
||||
resize: false,
|
||||
statusbar: false,
|
||||
// Minimal settings to prevent cursor jumping
|
||||
auto_focus: false,
|
||||
forced_root_block: 'p',
|
||||
entity_encoding: 'raw',
|
||||
// Disable problematic features
|
||||
verify_html: false,
|
||||
cleanup: false,
|
||||
cleanup_on_startup: false,
|
||||
auto_resize: false,
|
||||
// Performance optimizations for read-only
|
||||
cache_suffix: '?v=1.0',
|
||||
browser_spellcheck: false,
|
||||
gecko_spellcheck: false,
|
||||
// Disable editing features
|
||||
paste_as_text: true,
|
||||
paste_enable_default_filters: false,
|
||||
paste_word_valid_elements: false,
|
||||
paste_retain_style_properties: false,
|
||||
// Additional read-only settings
|
||||
contextmenu: false,
|
||||
selection: false,
|
||||
// Disable all editing
|
||||
object_resizing: false,
|
||||
element_format: 'html',
|
||||
// Mobile support
|
||||
mobile: {
|
||||
theme: 'silver',
|
||||
plugins: ['lists', 'autolink', 'link', 'image', 'table'],
|
||||
toolbar: false
|
||||
}
|
||||
<CKEditor
|
||||
editor={Editor}
|
||||
data={props.initialData}
|
||||
disabled={true}
|
||||
config={{
|
||||
// toolbar: [],
|
||||
isReadOnly: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import { getCsrfToken } from "@/service/auth";
|
|||
import { Link } from "@/i18n/routing";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useParams } from "next/navigation";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
interface FileWithPreview extends File {
|
||||
preview: string;
|
||||
|
|
@ -543,7 +544,7 @@ export default function FormAudio() {
|
|||
} = {
|
||||
...data,
|
||||
title: finalTitle,
|
||||
description: finalDescription,
|
||||
description: htmlToString(finalDescription),
|
||||
htmlDescription: finalDescription,
|
||||
fileTypeId,
|
||||
categoryId: selectedCategory,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import { getCsrfToken } from "@/service/auth";
|
|||
import { Upload } from "tus-js-client";
|
||||
import { useTranslations } from "next-intl";
|
||||
import dynamic from "next/dynamic";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
const audioSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -348,7 +349,7 @@ export default function FormAudioUpdate() {
|
|||
...data,
|
||||
id: detail?.id,
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
description: htmlToString(data.description),
|
||||
htmlDescription: data.description,
|
||||
fileTypeId,
|
||||
categoryId: selectedTarget,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ import { Link } from "@/i18n/routing";
|
|||
import { request } from "http";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import { toast } from "sonner";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
interface FileWithPreview extends File {
|
||||
preview: string;
|
||||
|
|
@ -564,7 +565,7 @@ export default function FormImage() {
|
|||
} = {
|
||||
...data,
|
||||
title: finalTitle,
|
||||
description: finalDescription,
|
||||
description: htmlToString(finalDescription),
|
||||
htmlDescription: finalDescription,
|
||||
fileTypeId,
|
||||
categoryId: selectedCategory,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import { error, loading } from "@/lib/swal";
|
|||
import { getCsrfToken } from "@/service/auth";
|
||||
import { Upload } from "tus-js-client";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
const imageSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -328,7 +329,7 @@ export default function FormImageUpdate() {
|
|||
...data,
|
||||
id: detail?.id,
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
description: htmlToString(data.description),
|
||||
htmlDescription: data.description,
|
||||
fileTypeId,
|
||||
categoryId: selectedTarget,
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ import { Checkbox } from "@/components/ui/checkbox";
|
|||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
|
||||
// Icons
|
||||
import {
|
||||
AlertCircle,
|
||||
FileText,
|
||||
Image,
|
||||
Loader2,
|
||||
Save,
|
||||
Trash2,
|
||||
import {
|
||||
AlertCircle,
|
||||
FileText,
|
||||
Image,
|
||||
Loader2,
|
||||
Save,
|
||||
Trash2,
|
||||
Edit3,
|
||||
Globe,
|
||||
Users,
|
||||
|
|
@ -42,7 +42,7 @@ import {
|
|||
Eye,
|
||||
Settings,
|
||||
CheckCircle,
|
||||
XCircle
|
||||
XCircle,
|
||||
} from "lucide-react";
|
||||
|
||||
// Swiper
|
||||
|
|
@ -62,10 +62,7 @@ import {
|
|||
getTagsBySubCategoryId,
|
||||
listEnableCategory,
|
||||
} from "@/service/content/content";
|
||||
import {
|
||||
generateDataRewrite,
|
||||
getDetailArticle,
|
||||
} from "@/service/content/ai";
|
||||
import { generateDataRewrite, getDetailArticle } from "@/service/content/ai";
|
||||
|
||||
// Utils
|
||||
import { getCookiesDecrypt } from "@/lib/utils";
|
||||
|
|
@ -150,14 +147,14 @@ const PLACEMENT_OPTIONS = [
|
|||
// Dynamic imports
|
||||
const CustomEditor = dynamic(
|
||||
() => import("@/components/editor/custom-editor"),
|
||||
{
|
||||
{
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<div className="flex items-center justify-center h-32 border rounded-md bg-muted/50">
|
||||
<Loader2 className="h-6 w-6 animate-spin" />
|
||||
<span className="ml-2">Loading editor...</span>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -190,24 +187,31 @@ export default function FormConvertSPIT() {
|
|||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
const [detail, setDetail] = useState<Detail | null>(null);
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(null);
|
||||
const [selectedFileType, setSelectedFileType] = useState<"original" | "rewrite">("original");
|
||||
const [selectedWritingStyle, setSelectedWritingStyle] = useState("professional");
|
||||
const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(
|
||||
null
|
||||
);
|
||||
const [selectedFileType, setSelectedFileType] = useState<
|
||||
"original" | "rewrite"
|
||||
>("original");
|
||||
const [selectedWritingStyle, setSelectedWritingStyle] =
|
||||
useState("professional");
|
||||
const [showRewriteEditor, setShowRewriteEditor] = useState(false);
|
||||
const [isGeneratingRewrite, setIsGeneratingRewrite] = useState(false);
|
||||
const [isLoadingRewrite, setIsLoadingRewrite] = useState(false);
|
||||
|
||||
|
||||
// Media state
|
||||
const [detailThumb, setDetailThumb] = useState<string[]>([]);
|
||||
const [thumbsSwiper, setThumbsSwiper] = useState<any>(null);
|
||||
const [files, setFiles] = useState<FileType[]>([]);
|
||||
const [filePlacements, setFilePlacements] = useState<string[][]>([]);
|
||||
|
||||
|
||||
// Content rewrite state
|
||||
const [articleIds, setArticleIds] = useState<string[]>([]);
|
||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(null);
|
||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
||||
null
|
||||
);
|
||||
const [articleBody, setArticleBody] = useState<string>("");
|
||||
|
||||
|
||||
// Form data state
|
||||
const [tags, setTags] = useState<string[]>([]);
|
||||
const [publishedFor, setPublishedFor] = useState<string[]>([]);
|
||||
|
|
@ -262,7 +266,7 @@ export default function FormConvertSPIT() {
|
|||
// Auto-select "Pers Rilis" category if schedule type is 3
|
||||
const scheduleId = Cookies.get("scheduleId");
|
||||
const scheduleType = Cookies.get("scheduleType");
|
||||
|
||||
|
||||
if (scheduleId && scheduleType === "3") {
|
||||
const persRilisCategory = categories.find((cat: Category) =>
|
||||
cat.name.toLowerCase().includes("pers rilis")
|
||||
|
|
@ -281,7 +285,7 @@ export default function FormConvertSPIT() {
|
|||
try {
|
||||
const response = await getTagsBySubCategoryId(categoryId);
|
||||
if (response?.data?.data?.length > 0) {
|
||||
const tagsMerge = [...tags, response?.data?.data]
|
||||
const tagsMerge = [...tags, response?.data?.data];
|
||||
setTags(tagsMerge);
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -293,7 +297,7 @@ export default function FormConvertSPIT() {
|
|||
try {
|
||||
const response = await detailSPIT(id);
|
||||
const details = response?.data?.data;
|
||||
|
||||
|
||||
if (!details) {
|
||||
throw new Error("Detail not found");
|
||||
}
|
||||
|
|
@ -301,11 +305,11 @@ export default function FormConvertSPIT() {
|
|||
setDetail(details);
|
||||
setFiles(details.contentList || []);
|
||||
setDetailThumb(
|
||||
(details.contentList || []).map((file: FileType) =>
|
||||
file.contentFile || "default-image.jpg"
|
||||
(details.contentList || []).map(
|
||||
(file: FileType) => file.contentFile || "default-image.jpg"
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Initialize file placements
|
||||
const fileCount = details.contentList?.length || 0;
|
||||
setFilePlacements(Array(fileCount).fill([]));
|
||||
|
|
@ -314,7 +318,10 @@ export default function FormConvertSPIT() {
|
|||
setValue("contentTitle", details.contentTitle || "");
|
||||
setValue("contentDescription", details.contentDescription || "");
|
||||
setValue("contentCreator", details.contentCreator || "");
|
||||
setValue("contentRewriteDescription", details.contentRewriteDescription || "");
|
||||
setValue(
|
||||
"contentRewriteDescription",
|
||||
details.contentRewriteDescription || ""
|
||||
);
|
||||
|
||||
// Set category
|
||||
if (details.categoryId) {
|
||||
|
|
@ -324,7 +331,9 @@ export default function FormConvertSPIT() {
|
|||
|
||||
// Set tags
|
||||
if (details.contentTag) {
|
||||
const initialTags = details.contentTag.split(",").map((tag: string) => tag.trim());
|
||||
const initialTags = details.contentTag
|
||||
.split(",")
|
||||
.map((tag: string) => tag.trim());
|
||||
setTags(initialTags);
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -365,13 +374,13 @@ export default function FormConvertSPIT() {
|
|||
};
|
||||
|
||||
const response = await generateDataRewrite(request);
|
||||
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
|
||||
const newArticleId = response?.data?.data?.id;
|
||||
setArticleIds(prev => {
|
||||
setArticleIds((prev) => {
|
||||
const updated = [...prev];
|
||||
if (updated.length < 3) {
|
||||
updated.push(newArticleId);
|
||||
|
|
@ -405,23 +414,26 @@ export default function FormConvertSPIT() {
|
|||
try {
|
||||
setIsLoadingRewrite(true);
|
||||
setSelectedArticleId(articleId);
|
||||
|
||||
|
||||
let retryCount = 0;
|
||||
const maxRetries = 20;
|
||||
|
||||
|
||||
while (retryCount < maxRetries) {
|
||||
const response = await getDetailArticle(articleId);
|
||||
const articleData = response?.data?.data;
|
||||
|
||||
if (articleData?.status === 2) {
|
||||
const cleanArticleBody = articleData.articleBody?.replace(/<img[^>]*>/g, "");
|
||||
const cleanArticleBody = articleData.articleBody?.replace(
|
||||
/<img[^>]*>/g,
|
||||
""
|
||||
);
|
||||
setArticleBody(cleanArticleBody || "");
|
||||
setValue("contentRewriteDescription", cleanArticleBody || "");
|
||||
break;
|
||||
}
|
||||
|
||||
retryCount++;
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
}
|
||||
|
||||
if (retryCount >= maxRetries) {
|
||||
|
|
@ -444,40 +456,46 @@ export default function FormConvertSPIT() {
|
|||
if (e.key === "Enter" && inputRef.current?.value.trim()) {
|
||||
e.preventDefault();
|
||||
const newTag = inputRef.current.value.trim();
|
||||
|
||||
|
||||
if (!tags.includes(newTag)) {
|
||||
setTags(prev => [...prev, newTag]);
|
||||
setTags((prev) => [...prev, newTag]);
|
||||
}
|
||||
|
||||
|
||||
inputRef.current.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveTag = (index: number) => {
|
||||
setTags(prev => prev.filter((_, i) => i !== index));
|
||||
setTags((prev) => prev.filter((_, i) => i !== index));
|
||||
};
|
||||
|
||||
const handlePublishTargetChange = (optionId: string) => {
|
||||
if (optionId === "all") {
|
||||
setPublishedFor(prev =>
|
||||
prev.length === PUBLISH_OPTIONS.filter(opt => opt.id !== "all").length
|
||||
? []
|
||||
: PUBLISH_OPTIONS.filter(opt => opt.id !== "all").map(opt => opt.id)
|
||||
setPublishedFor((prev) =>
|
||||
prev.length === PUBLISH_OPTIONS.filter((opt) => opt.id !== "all").length
|
||||
? []
|
||||
: PUBLISH_OPTIONS.filter((opt) => opt.id !== "all").map(
|
||||
(opt) => opt.id
|
||||
)
|
||||
);
|
||||
} else {
|
||||
setPublishedFor(prev =>
|
||||
prev.includes(optionId)
|
||||
? prev.filter(id => id !== optionId && id !== "all")
|
||||
: [...prev.filter(id => id !== "all"), optionId]
|
||||
setPublishedFor((prev) =>
|
||||
prev.includes(optionId)
|
||||
? prev.filter((id) => id !== optionId && id !== "all")
|
||||
: [...prev.filter((id) => id !== "all"), optionId]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFilePlacementChange = (fileIndex: number, placement: string, checked: boolean) => {
|
||||
setFilePlacements(prev => {
|
||||
const handleFilePlacementChange = (
|
||||
fileIndex: number,
|
||||
placement: string,
|
||||
checked: boolean
|
||||
) => {
|
||||
setFilePlacements((prev) => {
|
||||
const updated = [...prev];
|
||||
const currentPlacements = updated[fileIndex] || [];
|
||||
|
||||
|
||||
if (checked) {
|
||||
if (placement === "all") {
|
||||
updated[fileIndex] = ["all", "mabes", "polda", "international"];
|
||||
|
|
@ -492,25 +510,27 @@ export default function FormConvertSPIT() {
|
|||
if (placement === "all") {
|
||||
updated[fileIndex] = [];
|
||||
} else {
|
||||
const newPlacements = currentPlacements.filter(p => p !== placement);
|
||||
const newPlacements = currentPlacements.filter(
|
||||
(p) => p !== placement
|
||||
);
|
||||
if (newPlacements.length === 3 && newPlacements.includes("all")) {
|
||||
updated[fileIndex] = newPlacements.filter(p => p !== "all");
|
||||
updated[fileIndex] = newPlacements.filter((p) => p !== "all");
|
||||
} else {
|
||||
updated[fileIndex] = newPlacements;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return updated;
|
||||
});
|
||||
};
|
||||
|
||||
const handleSelectAllPlacements = (placement: string, checked: boolean) => {
|
||||
setFilePlacements(prev =>
|
||||
prev.map(filePlacements =>
|
||||
checked
|
||||
setFilePlacements((prev) =>
|
||||
prev.map((filePlacements) =>
|
||||
checked
|
||||
? Array.from(new Set([...filePlacements, placement]))
|
||||
: filePlacements.filter(p => p !== placement)
|
||||
: filePlacements.filter((p) => p !== placement)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
@ -520,7 +540,7 @@ export default function FormConvertSPIT() {
|
|||
console.log("filePlacements : ", filePlacements);
|
||||
for (let i = 0; i < filePlacements.length; i++) {
|
||||
if (filePlacements[i].length > 0) {
|
||||
const placements = filePlacements[i];
|
||||
const placements = filePlacements[i];
|
||||
placementData.push({
|
||||
mediaFileId: files[i].contentId,
|
||||
placements: placements.join(","),
|
||||
|
|
@ -530,15 +550,38 @@ export default function FormConvertSPIT() {
|
|||
return placementData;
|
||||
};
|
||||
|
||||
const checkPlacement = (data: any) => {
|
||||
let temp = true;
|
||||
for (const element of data) {
|
||||
if (element.length < 1) {
|
||||
temp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
};
|
||||
|
||||
// Form submission
|
||||
const onSubmit = async (data: FormData) => {
|
||||
if (!checkPlacement(filePlacements)) {
|
||||
error("Select File Placement");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (publishedFor.length < 1) {
|
||||
error("Select Publish Target");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsSaving(true);
|
||||
|
||||
const description = selectedFileType === "original"
|
||||
? data.contentDescription
|
||||
: data.contentRewriteDescription;
|
||||
|
||||
|
||||
const description =
|
||||
selectedFileType === "original"
|
||||
? data.contentDescription
|
||||
: data.contentRewriteDescription;
|
||||
|
||||
const requestData = {
|
||||
spitId: id,
|
||||
title: data.contentTitle,
|
||||
|
|
@ -552,7 +595,7 @@ export default function FormConvertSPIT() {
|
|||
};
|
||||
|
||||
await convertSPIT(requestData);
|
||||
|
||||
|
||||
MySwal.fire({
|
||||
title: "Success",
|
||||
text: "Data saved successfully",
|
||||
|
|
@ -590,7 +633,7 @@ export default function FormConvertSPIT() {
|
|||
try {
|
||||
setIsDeleting(true);
|
||||
await deleteSPIT(id);
|
||||
|
||||
|
||||
MySwal.fire({
|
||||
title: "Success",
|
||||
text: "Content deleted successfully",
|
||||
|
|
@ -630,17 +673,15 @@ export default function FormConvertSPIT() {
|
|||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold tracking-tight">SPIT Convert Form</h1>
|
||||
<h1 className="text-3xl font-bold tracking-tight">
|
||||
SPIT Convert Form
|
||||
</h1>
|
||||
<p className="text-muted-foreground">
|
||||
Convert and manage your SPIT content
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<Button variant="outline" size="sm" onClick={() => router.back()}>
|
||||
<XCircle className="h-4 w-4 mr-2" />
|
||||
Cancel
|
||||
</Button>
|
||||
|
|
@ -734,7 +775,9 @@ export default function FormConvertSPIT() {
|
|||
<CardContent className="space-y-4">
|
||||
<RadioGroup
|
||||
value={selectedFileType}
|
||||
onValueChange={(value: "original" | "rewrite") => setSelectedFileType(value)}
|
||||
onValueChange={(value: "original" | "rewrite") =>
|
||||
setSelectedFileType(value)
|
||||
}
|
||||
className="grid grid-cols-2 gap-4"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
|
|
@ -789,7 +832,9 @@ export default function FormConvertSPIT() {
|
|||
<Button
|
||||
type="button"
|
||||
onClick={handleRewriteClick}
|
||||
disabled={isGeneratingRewrite || !detail?.contentDescription}
|
||||
disabled={
|
||||
isGeneratingRewrite || !detail?.contentDescription
|
||||
}
|
||||
className="bg-blue-600 hover:bg-blue-700"
|
||||
>
|
||||
{isGeneratingRewrite ? (
|
||||
|
|
@ -809,14 +854,19 @@ export default function FormConvertSPIT() {
|
|||
<Button
|
||||
key={articleId}
|
||||
type="button"
|
||||
variant={selectedArticleId === articleId ? "default" : "outline"}
|
||||
variant={
|
||||
selectedArticleId === articleId
|
||||
? "default"
|
||||
: "outline"
|
||||
}
|
||||
size="sm"
|
||||
onClick={() => handleArticleSelect(articleId)}
|
||||
disabled={isLoadingRewrite}
|
||||
>
|
||||
{isLoadingRewrite && selectedArticleId === articleId && (
|
||||
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||
)}
|
||||
{isLoadingRewrite &&
|
||||
selectedArticleId === articleId && (
|
||||
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
||||
)}
|
||||
Narrative {index + 1}
|
||||
</Button>
|
||||
))}
|
||||
|
|
@ -870,7 +920,7 @@ export default function FormConvertSPIT() {
|
|||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
|
||||
|
||||
<Swiper
|
||||
onSwiper={setThumbsSwiper}
|
||||
slidesPerView={8}
|
||||
|
|
@ -906,14 +956,23 @@ export default function FormConvertSPIT() {
|
|||
{files.length > 1 && (
|
||||
<div className="flex flex-wrap gap-4 p-4 bg-muted/50 rounded-lg">
|
||||
{PLACEMENT_OPTIONS.map((option) => (
|
||||
<div key={option.value} className="flex items-center space-x-2">
|
||||
<div
|
||||
key={option.value}
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<Checkbox
|
||||
id={`select-all-${option.value}`}
|
||||
onCheckedChange={(checked) =>
|
||||
handleSelectAllPlacements(option.value, Boolean(checked))
|
||||
handleSelectAllPlacements(
|
||||
option.value,
|
||||
Boolean(checked)
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Label htmlFor={`select-all-${option.value}`} className="text-sm">
|
||||
<Label
|
||||
htmlFor={`select-all-${option.value}`}
|
||||
className="text-sm"
|
||||
>
|
||||
All {option.label}
|
||||
</Label>
|
||||
</div>
|
||||
|
|
@ -936,12 +995,21 @@ export default function FormConvertSPIT() {
|
|||
<p className="font-medium text-sm">{file.fileName}</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{PLACEMENT_OPTIONS.map((option) => (
|
||||
<div key={option.value} className="flex items-center space-x-2">
|
||||
<div
|
||||
key={option.value}
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<Checkbox
|
||||
id={`${file.contentId}-${option.value}`}
|
||||
checked={filePlacements[index]?.includes(option.value)}
|
||||
checked={filePlacements[index]?.includes(
|
||||
option.value
|
||||
)}
|
||||
onCheckedChange={(checked) =>
|
||||
handleFilePlacementChange(index, option.value, Boolean(checked))
|
||||
handleFilePlacementChange(
|
||||
index,
|
||||
option.value,
|
||||
Boolean(checked)
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Label
|
||||
|
|
@ -1067,10 +1135,14 @@ export default function FormConvertSPIT() {
|
|||
id={option.id}
|
||||
checked={
|
||||
option.id === "all"
|
||||
? publishedFor.length === PUBLISH_OPTIONS.filter(opt => opt.id !== "all").length
|
||||
? publishedFor.length ===
|
||||
PUBLISH_OPTIONS.filter((opt) => opt.id !== "all")
|
||||
.length
|
||||
: publishedFor.includes(option.id)
|
||||
}
|
||||
onCheckedChange={() => handlePublishTargetChange(option.id)}
|
||||
onCheckedChange={() =>
|
||||
handlePublishTargetChange(option.id)
|
||||
}
|
||||
/>
|
||||
<Label htmlFor={option.id} className="text-sm">
|
||||
{option.label}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import dynamic from "next/dynamic";
|
|||
import { getCsrfToken } from "@/service/auth";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
interface FileWithPreview extends File {
|
||||
preview: string;
|
||||
|
|
@ -573,7 +574,7 @@ export default function FormTeks() {
|
|||
} = {
|
||||
...data,
|
||||
title: finalTitle,
|
||||
description: finalDescription,
|
||||
description: htmlToString(finalDescription),
|
||||
htmlDescription: finalDescription,
|
||||
fileTypeId,
|
||||
categoryId: selectedCategory,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import { Upload } from "tus-js-client";
|
|||
import { getCsrfToken } from "@/service/auth";
|
||||
import { useTranslations } from "next-intl";
|
||||
import dynamic from "next/dynamic";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
const teksSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -337,7 +338,7 @@ export default function FormTeksUpdate() {
|
|||
...data,
|
||||
id: detail?.id,
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
description: htmlToString(data.description),
|
||||
htmlDescription: data.description,
|
||||
fileTypeId,
|
||||
categoryId: selectedTarget,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import {
|
|||
Legend,
|
||||
ChartOptions,
|
||||
} from "chart.js";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
ChartJS.register(ArcElement, Tooltip, Legend);
|
||||
const imageSchema = z.object({
|
||||
|
|
@ -349,7 +350,7 @@ export default function FormTeksSeo() {
|
|||
...data,
|
||||
id: detail?.id,
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
description: htmlToString(data.description),
|
||||
htmlDescription: data.description,
|
||||
fileTypeId,
|
||||
categoryId: selectedTarget,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import dynamic from "next/dynamic";
|
|||
import { getCsrfToken } from "@/service/auth";
|
||||
import { Link } from "@/i18n/routing";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
const CustomEditor = dynamic(
|
||||
() => {
|
||||
|
|
@ -559,7 +560,7 @@ export default function FormVideo() {
|
|||
} = {
|
||||
...data,
|
||||
title: finalTitle,
|
||||
description: finalDescription,
|
||||
description: htmlToString(finalDescription),
|
||||
htmlDescription: finalDescription,
|
||||
fileTypeId,
|
||||
categoryId: selectedCategory,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import { getCsrfToken } from "@/service/auth";
|
|||
import { error, loading } from "@/lib/swal";
|
||||
import { useTranslations } from "next-intl";
|
||||
import dynamic from "next/dynamic";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
|
||||
const videoSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -418,7 +419,7 @@ export default function FormVideoUpdate() {
|
|||
...data,
|
||||
id: detail?.id,
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
description: htmlToString(data.description),
|
||||
htmlDescription: data.description,
|
||||
fileTypeId,
|
||||
categoryId: selectedTarget,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use client";
|
||||
|
||||
import { useLocale } from "next-intl";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useParams, useSearchParams } from "next/navigation";
|
||||
import { locales } from "@/config";
|
||||
import { usePathname, useRouter } from "@/i18n/routing";
|
||||
|
||||
|
|
@ -33,13 +33,22 @@ export default function LocalSwitcher() {
|
|||
const params = useParams();
|
||||
const localActive = useLocale() || "in";
|
||||
const [selectedLang, setSelectedLang] = useState<string>("");
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
const storedLang = getLanguage();
|
||||
let joinParam = "";
|
||||
if (searchParams) {
|
||||
joinParam = Array.from(searchParams.entries())
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join("&");
|
||||
}
|
||||
|
||||
if (pathname.includes("polda")){
|
||||
if (pathname.includes("polda")) {
|
||||
startTransition(() => {
|
||||
router.replace(pathname, { locale: "in" });
|
||||
router.replace(pathname + joinParam === "" ? "" : `?${joinParam}`, {
|
||||
locale: "in",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
if (!storedLang) {
|
||||
|
|
@ -47,16 +56,20 @@ export default function LocalSwitcher() {
|
|||
setSelectedLang("in");
|
||||
|
||||
startTransition(() => {
|
||||
router.replace(pathname, { locale: "in" });
|
||||
router.replace(pathname + joinParam === "" ? "" : `?${joinParam}`, {
|
||||
locale: "in",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setSelectedLang(storedLang);
|
||||
startTransition(() => {
|
||||
router.replace(pathname, { locale: storedLang });
|
||||
router.replace(pathname + joinParam === "" ? "" : `?${joinParam}`, {
|
||||
locale: storedLang,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
}, [searchParams]);
|
||||
|
||||
const onSelectChange = (nextLocale: string) => {
|
||||
setLanguage(nextLocale);
|
||||
|
|
|
|||
|
|
@ -3,33 +3,33 @@
|
|||
import { useState, useCallback, useEffect } from "react";
|
||||
import { useRouter } from "@/components/navigation";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
LoginFormData,
|
||||
ProfileData,
|
||||
AuthState,
|
||||
import {
|
||||
LoginFormData,
|
||||
ProfileData,
|
||||
AuthState,
|
||||
AuthContextType,
|
||||
EmailValidationData,
|
||||
OTPData
|
||||
OTPData,
|
||||
} from "@/types/auth";
|
||||
import {
|
||||
login,
|
||||
getProfile,
|
||||
postEmailValidation,
|
||||
postSetupEmail,
|
||||
verifyOTPByUsername,
|
||||
doLogin
|
||||
import {
|
||||
login,
|
||||
getProfile,
|
||||
postEmailValidation,
|
||||
postSetupEmail,
|
||||
verifyOTPByUsername,
|
||||
doLogin,
|
||||
} from "@/service/auth";
|
||||
import {
|
||||
setAuthCookies,
|
||||
setProfileCookies,
|
||||
clearAllCookies,
|
||||
isUserEligible,
|
||||
import {
|
||||
setAuthCookies,
|
||||
setProfileCookies,
|
||||
clearAllCookies,
|
||||
isUserEligible,
|
||||
isProtectedRole,
|
||||
getNavigationPath,
|
||||
showAuthError,
|
||||
showAuthSuccess,
|
||||
loginRateLimiter,
|
||||
AUTH_CONSTANTS
|
||||
AUTH_CONSTANTS,
|
||||
} from "@/lib/auth-utils";
|
||||
import { warning } from "@/lib/swal";
|
||||
|
||||
|
|
@ -46,108 +46,114 @@ export const useAuth = (): AuthContextType => {
|
|||
useEffect(() => {
|
||||
const checkAuth = async () => {
|
||||
try {
|
||||
setState(prev => ({ ...prev, loading: true }));
|
||||
setState((prev) => ({ ...prev, loading: true }));
|
||||
// Add logic to check if user is authenticated
|
||||
// This could check for valid tokens, etc.
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
isAuthenticated: false,
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
isAuthenticated: false,
|
||||
user: null,
|
||||
error: "Authentication check failed"
|
||||
error: "Authentication check failed",
|
||||
}));
|
||||
} finally {
|
||||
setState(prev => ({ ...prev, loading: false }));
|
||||
setState((prev) => ({ ...prev, loading: false }));
|
||||
}
|
||||
};
|
||||
|
||||
checkAuth();
|
||||
}, []);
|
||||
|
||||
const login = useCallback(async (credentials: LoginFormData): Promise<void> => {
|
||||
try {
|
||||
setState(prev => ({ ...prev, loading: true, error: null }));
|
||||
const login = useCallback(
|
||||
async (credentials: LoginFormData): Promise<void> => {
|
||||
try {
|
||||
setState((prev) => ({ ...prev, loading: true, error: null }));
|
||||
|
||||
// Check rate limiting
|
||||
if (!loginRateLimiter.canAttempt(credentials.username)) {
|
||||
const remainingTime = loginRateLimiter.getRemainingTime(credentials.username);
|
||||
const minutes = Math.ceil(remainingTime / (60 * 1000));
|
||||
throw new Error(`Too many login attempts. Please try again in ${minutes} minutes.`);
|
||||
// Check rate limiting
|
||||
if (!loginRateLimiter.canAttempt(credentials.username)) {
|
||||
const remainingTime = loginRateLimiter.getRemainingTime(
|
||||
credentials.username
|
||||
);
|
||||
const minutes = Math.ceil(remainingTime / (60 * 1000));
|
||||
throw new Error(
|
||||
`Too many login attempts. Please try again in ${minutes} minutes.`
|
||||
);
|
||||
}
|
||||
|
||||
// Attempt login
|
||||
const response = await doLogin({
|
||||
...credentials,
|
||||
grantType: AUTH_CONSTANTS.GRANT_TYPE,
|
||||
clientId: AUTH_CONSTANTS.CLIENT_ID,
|
||||
});
|
||||
|
||||
if (response?.error) {
|
||||
loginRateLimiter.recordAttempt(credentials.username);
|
||||
throw new Error("Invalid username or password");
|
||||
}
|
||||
|
||||
const { access_token, refresh_token } = response?.data || {};
|
||||
|
||||
if (!access_token || !refresh_token) {
|
||||
throw new Error("Invalid response from server");
|
||||
}
|
||||
|
||||
// Set auth cookies
|
||||
setAuthCookies(access_token, refresh_token);
|
||||
|
||||
// Get user profile
|
||||
const profileResponse = await getProfile(access_token);
|
||||
const profile: ProfileData = profileResponse?.data?.data;
|
||||
|
||||
if (!profile) {
|
||||
throw new Error("Failed to fetch user profile");
|
||||
}
|
||||
|
||||
// Validate user eligibility
|
||||
// if (!isUserEligible(profile)) {
|
||||
// clearAllCookies();
|
||||
// warning(
|
||||
// "Akun Anda tidak dapat digunakan untuk masuk ke MediaHub Polri",
|
||||
// "/auth"
|
||||
// );
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Set profile cookies
|
||||
setProfileCookies(profile);
|
||||
|
||||
// Reset rate limiter on successful login
|
||||
loginRateLimiter.resetAttempts(credentials.username);
|
||||
|
||||
// Navigate based on user role
|
||||
const navigationPath = getNavigationPath(
|
||||
profile.roleId,
|
||||
profile.userLevel?.id,
|
||||
profile.userLevel?.parentLevelId
|
||||
);
|
||||
|
||||
// Update state
|
||||
setState({
|
||||
isAuthenticated: true,
|
||||
user: profile,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
|
||||
// Navigate to appropriate dashboard
|
||||
window.location.href = navigationPath;
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "Login failed";
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
error: errorMessage,
|
||||
}));
|
||||
showAuthError(error, "Login failed");
|
||||
}
|
||||
|
||||
// Attempt login
|
||||
const response = await doLogin({
|
||||
...credentials,
|
||||
grantType: AUTH_CONSTANTS.GRANT_TYPE,
|
||||
clientId: AUTH_CONSTANTS.CLIENT_ID,
|
||||
});
|
||||
|
||||
if (response?.error) {
|
||||
loginRateLimiter.recordAttempt(credentials.username);
|
||||
throw new Error("Invalid username or password");
|
||||
}
|
||||
|
||||
const { access_token, refresh_token } = response?.data || {};
|
||||
|
||||
if (!access_token || !refresh_token) {
|
||||
throw new Error("Invalid response from server");
|
||||
}
|
||||
|
||||
// Set auth cookies
|
||||
setAuthCookies(access_token, refresh_token);
|
||||
|
||||
// Get user profile
|
||||
const profileResponse = await getProfile(access_token);
|
||||
const profile: ProfileData = profileResponse?.data?.data;
|
||||
|
||||
if (!profile) {
|
||||
throw new Error("Failed to fetch user profile");
|
||||
}
|
||||
|
||||
// Validate user eligibility
|
||||
// if (!isUserEligible(profile)) {
|
||||
// clearAllCookies();
|
||||
// warning(
|
||||
// "Akun Anda tidak dapat digunakan untuk masuk ke MediaHub Polri",
|
||||
// "/auth"
|
||||
// );
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Set profile cookies
|
||||
setProfileCookies(profile);
|
||||
|
||||
// Reset rate limiter on successful login
|
||||
loginRateLimiter.resetAttempts(credentials.username);
|
||||
|
||||
// Navigate based on user role
|
||||
const navigationPath = getNavigationPath(
|
||||
profile.roleId,
|
||||
profile.userLevel?.id,
|
||||
profile.userLevel?.parentLevelId
|
||||
);
|
||||
|
||||
// Update state
|
||||
setState({
|
||||
isAuthenticated: true,
|
||||
user: profile,
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
|
||||
// Navigate to appropriate dashboard
|
||||
window.location.href = navigationPath;
|
||||
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "Login failed";
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
loading: false,
|
||||
error: errorMessage
|
||||
}));
|
||||
showAuthError(error, "Login failed");
|
||||
}
|
||||
}, [router]);
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
const logout = useCallback((): void => {
|
||||
clearAllCookies();
|
||||
|
|
@ -162,13 +168,13 @@ export const useAuth = (): AuthContextType => {
|
|||
|
||||
const refreshToken = useCallback(async (): Promise<void> => {
|
||||
try {
|
||||
setState(prev => ({ ...prev, loading: true }));
|
||||
setState((prev) => ({ ...prev, loading: true }));
|
||||
// Add token refresh logic here
|
||||
// This would typically call an API to refresh the access token
|
||||
} catch (error) {
|
||||
logout();
|
||||
} finally {
|
||||
setState(prev => ({ ...prev, loading: false }));
|
||||
setState((prev) => ({ ...prev, loading: false }));
|
||||
}
|
||||
}, [logout]);
|
||||
|
||||
|
|
@ -185,38 +191,43 @@ export const useEmailValidation = () => {
|
|||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const validateEmail = useCallback(async (credentials: LoginFormData): Promise<string> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const validateEmail = useCallback(
|
||||
async (credentials: LoginFormData): Promise<string> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const response = await postEmailValidation(credentials);
|
||||
const response = await postEmailValidation(credentials);
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response?.message || "Email validation failed");
|
||||
if (response?.error) {
|
||||
throw new Error(response?.message || "Email validation failed");
|
||||
}
|
||||
|
||||
const message = response?.data?.message;
|
||||
|
||||
switch (message) {
|
||||
case "Continue to setup email":
|
||||
return "setup";
|
||||
case "Email is valid and OTP has been sent":
|
||||
return "otp";
|
||||
case "Username & password valid":
|
||||
return "success";
|
||||
case "Skip to login":
|
||||
return "skip";
|
||||
default:
|
||||
return "login";
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "Email validation failed";
|
||||
setError(errorMessage);
|
||||
showAuthError(error, "Email validation failed");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const message = response?.data?.message;
|
||||
|
||||
switch (message) {
|
||||
case "Continue to setup email":
|
||||
return "setup";
|
||||
case "Email is valid and OTP has been sent":
|
||||
return "otp";
|
||||
case "Username & password valid":
|
||||
return "success";
|
||||
default:
|
||||
return "login";
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "Email validation failed";
|
||||
setError(errorMessage);
|
||||
showAuthError(error, "Email validation failed");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return {
|
||||
validateEmail,
|
||||
|
|
@ -230,46 +241,49 @@ export const useEmailSetup = () => {
|
|||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const setupEmail = useCallback(async (
|
||||
credentials: LoginFormData,
|
||||
emailData: EmailValidationData
|
||||
): Promise<string> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const setupEmail = useCallback(
|
||||
async (
|
||||
credentials: LoginFormData,
|
||||
emailData: EmailValidationData
|
||||
): Promise<string> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const data = {
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
oldEmail: emailData.oldEmail,
|
||||
newEmail: emailData.newEmail,
|
||||
};
|
||||
const data = {
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
oldEmail: emailData.oldEmail,
|
||||
newEmail: emailData.newEmail,
|
||||
};
|
||||
|
||||
const response = await postSetupEmail(data);
|
||||
const response = await postSetupEmail(data);
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.message || "Email setup failed");
|
||||
if (response?.error) {
|
||||
throw new Error(response.message || "Email setup failed");
|
||||
}
|
||||
|
||||
const message = response?.data?.message;
|
||||
|
||||
switch (message) {
|
||||
case "Email is valid and OTP has been sent":
|
||||
return "otp";
|
||||
case "The old email is not same":
|
||||
throw new Error("Email is invalid");
|
||||
default:
|
||||
return "success";
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "Email setup failed";
|
||||
setError(errorMessage);
|
||||
showAuthError(error, "Email setup failed");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const message = response?.data?.message;
|
||||
|
||||
switch (message) {
|
||||
case "Email is valid and OTP has been sent":
|
||||
return "otp";
|
||||
case "The old email is not same":
|
||||
throw new Error("Email is invalid");
|
||||
default:
|
||||
return "success";
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "Email setup failed";
|
||||
setError(errorMessage);
|
||||
showAuthError(error, "Email setup failed");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return {
|
||||
setupEmail,
|
||||
|
|
@ -283,38 +297,38 @@ export const useOTPVerification = () => {
|
|||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const verifyOTP = useCallback(async (
|
||||
username: string,
|
||||
otp: string
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const verifyOTP = useCallback(
|
||||
async (username: string, otp: string): Promise<boolean> => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
if (otp.length !== 6) {
|
||||
throw new Error("OTP must be exactly 6 digits");
|
||||
if (otp.length !== 6) {
|
||||
throw new Error("OTP must be exactly 6 digits");
|
||||
}
|
||||
|
||||
const response = await verifyOTPByUsername(username, otp);
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.message || "OTP verification failed");
|
||||
}
|
||||
|
||||
return response?.message === "success";
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "OTP verification failed";
|
||||
setError(errorMessage);
|
||||
showAuthError(error, "OTP verification failed");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const response = await verifyOTPByUsername(username, otp);
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.message || "OTP verification failed");
|
||||
}
|
||||
|
||||
return response?.message === "success";
|
||||
} catch (error: any) {
|
||||
const errorMessage = error?.message || "OTP verification failed";
|
||||
setError(errorMessage);
|
||||
showAuthError(error, "OTP verification failed");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return {
|
||||
verifyOTP,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,10 +17,10 @@
|
|||
"lighthouse": "lighthouse http://localhost:3000 --output=json --output-path=./lighthouse-report.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ckeditor/ckeditor5-react": "^6.2.0",
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dschoon/react-waves": "^4.0.3",
|
||||
"@emoji-mart/data": "^1.2.1",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@fullcalendar/core": "^6.1.15",
|
||||
|
|
@ -78,6 +78,7 @@
|
|||
"apexcharts": "^4.7.0",
|
||||
"axios": "^1.7.8",
|
||||
"chart.js": "^4.5.0",
|
||||
"ckeditor5-custom-build": "file:vendor/ckeditor5",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"cleave.js": "^1.6.0",
|
||||
"clsx": "^2.1.1",
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ export async function getDetail(slug: string) {
|
|||
|
||||
export async function getDetailMetaData(slug: string) {
|
||||
return await httpGetInterceptorForMetadata(
|
||||
`media/public?slug=${slug}&state=mabes`
|
||||
`media/public?slug=${slug}&state=mabes&isSummary=true`
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
Software License Agreement
|
||||
==========================
|
||||
|
||||
Copyright (c) 2014-2024, CKSource Holding sp. z o.o. All rights reserved.
|
||||
|
||||
Online builder code samples are licensed under the terms of the MIT License (see Appendix A):
|
||||
|
||||
http://en.wikipedia.org/wiki/MIT_License
|
||||
|
||||
CKEditor 5 collaboration features are only available under a commercial license. [Contact us](https://ckeditor.com/contact/) for more details.
|
||||
|
||||
Free 30-days trials of CKEditor 5 collaboration features are available:
|
||||
* https://ckeditor.com/collaboration/ - Real-time collaboration (with all features).
|
||||
* https://ckeditor.com/collaboration/comments/ - Inline comments feature (without real-time collaborative editing).
|
||||
* https://ckeditor.com/collaboration/track-changes/ - Track changes feature (without real-time collaborative editing).
|
||||
|
||||
Trademarks
|
||||
----------
|
||||
|
||||
CKEditor is a trademark of CKSource Holding sp. z o.o. All other brand
|
||||
and product names are trademarks, registered trademarks or service
|
||||
marks of their respective holders.
|
||||
|
||||
---
|
||||
|
||||
Appendix A: The MIT License
|
||||
---------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2024, CKSource Holding sp. z o.o.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
# CKEditor 5 editor generated with the online builder
|
||||
|
||||
This repository presents a CKEditor 5 editor build generated by the [Online builder tool](https://ckeditor.com/ckeditor-5/online-builder)
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Open the `sample/index.html` page in the browser.
|
||||
|
||||
2. Fill the prompt with the license key. If you do not have the license key yet [contact us](https://ckeditor.com/contact/).
|
||||
|
||||
## Configuring build
|
||||
|
||||
Changes like changing toolbar items, changing order of icons or customizing plugin configurations should be relatively easy to make. Open the `sample/index.html` file and edit the script that initialized the CKEditor 5. Save the file and refresh the browser. That's all.
|
||||
|
||||
*Note:* If you have any problems with browser caching use the `Ctrl + R` or `Cmd + R` shortcut depending on your system.
|
||||
|
||||
However if you want to remove or add a plugin to the build you need to follow the next step of this guide.
|
||||
|
||||
Note that it is also possible to go back to the [Online builder tool](https://ckeditor.com/ckeditor-5/online-builder) and pick other set of plugins. But we encourage you to try the harder way and to learn the principles of Node.js and CKEditor 5 ecosystems that will allow you to do more cool things in the future!
|
||||
|
||||
### Installation
|
||||
|
||||
In order to rebuild the application you need to install all dependencies first. To do it, open the terminal in the project directory and type:
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Make sure that you have the `node` and `npm` installed first. If not, then follow the instructions on the [Node.js documentation page](https://nodejs.org/en/).
|
||||
|
||||
### Adding or removing plugins
|
||||
|
||||
Now you can install additional plugin in the build. Just follow the [Adding a plugin to an editor tutorial](https://ckeditor.com/docs/ckeditor5/latest/installation/plugins/installing-plugins.html#adding-a-plugin-to-an-editor)
|
||||
|
||||
### Rebuilding editor
|
||||
|
||||
If you have already done the [Installation](#installation) and [Adding or removing plugins](#adding-or-removing-plugins) steps, you're ready to rebuild the editor by running the following command:
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
This will build the CKEditor 5 to the `build` directory. You can open your browser and you should be able to see the changes you've made in the code. If not, then try to refresh also the browser cache by typing `Ctrl + R` or `Cmd + R` depending on your system.
|
||||
|
||||
## What's next?
|
||||
|
||||
Follow the guides available on https://ckeditor.com/docs/ckeditor5/latest/framework/index.html and enjoy the document editing.
|
||||
|
||||
## FAQ
|
||||
| Where is the place to report bugs and feature requests?
|
||||
|
||||
You can create an issue on https://github.com/ckeditor/ckeditor5/issues including the build id - `yt1k3s5kie6c-kuy63vghjub2`. Make sure that the question / problem is unique, please look for a possibly asked questions in the search box. Duplicates will be closed.
|
||||
|
||||
| Where can I learn more about the CKEditor 5 framework?
|
||||
|
||||
Here: https://ckeditor.com/docs/ckeditor5/latest/framework/
|
||||
|
||||
| Is it possible to use online builder with common frameworks like React, Vue or Angular?
|
||||
|
||||
Not yet, but it these integrations will be available at some point in the future.
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* @license Copyright (c) 2014-2024, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';
|
||||
import { Alignment } from '@ckeditor/ckeditor5-alignment';
|
||||
import { Autoformat } from '@ckeditor/ckeditor5-autoformat';
|
||||
import { Bold, Italic } from '@ckeditor/ckeditor5-basic-styles';
|
||||
import { BlockQuote } from '@ckeditor/ckeditor5-block-quote';
|
||||
import { CloudServices } from '@ckeditor/ckeditor5-cloud-services';
|
||||
import { CodeBlock } from '@ckeditor/ckeditor5-code-block';
|
||||
import type { EditorConfig } from '@ckeditor/ckeditor5-core';
|
||||
import { Essentials } from '@ckeditor/ckeditor5-essentials';
|
||||
import { FontSize } from '@ckeditor/ckeditor5-font';
|
||||
import { Heading } from '@ckeditor/ckeditor5-heading';
|
||||
import { Image, ImageCaption, ImageInsert, ImageStyle, ImageToolbar, ImageUpload } from '@ckeditor/ckeditor5-image';
|
||||
import { Indent } from '@ckeditor/ckeditor5-indent';
|
||||
import { Link } from '@ckeditor/ckeditor5-link';
|
||||
import { List } from '@ckeditor/ckeditor5-list';
|
||||
import { MediaEmbed } from '@ckeditor/ckeditor5-media-embed';
|
||||
import { Paragraph } from '@ckeditor/ckeditor5-paragraph';
|
||||
import { PasteFromOffice } from '@ckeditor/ckeditor5-paste-from-office';
|
||||
import { SourceEditing } from '@ckeditor/ckeditor5-source-editing';
|
||||
import { Table, TableToolbar } from '@ckeditor/ckeditor5-table';
|
||||
import { TextTransformation } from '@ckeditor/ckeditor5-typing';
|
||||
import { Undo } from '@ckeditor/ckeditor5-undo';
|
||||
import { SimpleUploadAdapter } from '@ckeditor/ckeditor5-upload';
|
||||
declare class Editor extends ClassicEditor {
|
||||
static builtinPlugins: (typeof Alignment | typeof Autoformat | typeof BlockQuote | typeof Bold | typeof CloudServices | typeof CodeBlock | typeof Essentials | typeof FontSize | typeof Heading | typeof Image | typeof ImageCaption | typeof ImageInsert | typeof ImageStyle | typeof ImageToolbar | typeof ImageUpload | typeof Indent | typeof Italic | typeof Link | typeof List | typeof MediaEmbed | typeof Paragraph | typeof PasteFromOffice | typeof SimpleUploadAdapter | typeof SourceEditing | typeof Table | typeof TableToolbar | typeof TextTransformation | typeof Undo)[];
|
||||
static defaultConfig: EditorConfig;
|
||||
}
|
||||
export default Editor;
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"ckeditor.js","mappings":";;;;AAAA","sources":["webpack://ClassicEditor/webpack/universalModuleDefinition"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClassicEditor\"] = factory();\n\telse\n\t\troot[\"ClassicEditor\"] = factory();\n})(self, () => {\nreturn "],"names":[],"sourceRoot":""}
|
||||
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["af"]=e["af"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 van %1",Accept:"",Accessibility:"","Accessibility help":"","Align center":"Belyn in die middel","Align left":"Belyn links","Align right":"Belyn regs",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"","Block quote":"Verwysingsaanhaling",Blue:"",Bold:"Vet","Bold text":"",Cancel:"Kanselleer",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Bronkode","Code block":"","Content editing keystrokes":"","Dim grey":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Insert code block":"Voeg bronkodeblok in",Italic:"Kursief","Italic text":"",Justify:"Belyn beide kante","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"Wysig",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"","Plain text":"Gewone skrif","Press %0 for help.":"",Previous:"",Purple:"",Red:"","Remove color":"Verwyder kleur","Restore default":"Herstel verstek","Rich Text Editor":"",Save:"Stoor","Show more items":"Wys meer items",Strikethrough:"Deurstreep","Strikethrough text":"",Subscript:"Onderskrif",Superscript:"Boskrif","Text alignment":"Teksbelyning","Text alignment toolbar":"Teksbelyning nutsbank","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Turquoise:"",Underline:"Onderstreep","Underline text":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"",Yellow:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["ast"]=e["ast"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Bold:"Negrina","Bold text":"","Break text":"","Bulleted List":"Llista con viñetes","Bulleted list styles toolbar":"",Cancel:"Encaboxar","Caption for image: %0":"","Caption for the image":"","Centered image":"","Change image text alternative":"",Circle:"",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"","Content editing keystrokes":"","Create link":"",Decimal:"","Decimal with leading zero":"","Decrease list item indent":"","Dim grey":"",Disc:"",Downloadable:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter image caption":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Full size image":"Imaxen a tamañu completu",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Image from computer":"","Image resize list":"","Image toolbar":"","image widget":"complementu d'imaxen","In line":"","Increase list item indent":"",Insert:"","Insert image":"","Insert image via URL":"","Invalid start index value.":"",Italic:"Cursiva","Italic text":"","Keystrokes that can be used in a list":"","Left aligned image":"","Light blue":"","Light green":"","Light grey":"",Link:"Enllazar","Link image":"","Link URL":"URL del enllaz","List properties":"","Lower-latin":"","Lower–roman":"",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of a link":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Numbered List":"Llista numberada","Numbered list styles toolbar":"","Open in a new tab":"","Open link in new tab":"","Open the accessibility help dialog":"",Orange:"",Original:"","Press %0 for help.":"",Previous:"",Purple:"",Red:"",Redo:"Refacer","Remove color":"","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"","Reversed order":"","Rich Text Editor":"Editor de testu arriquecíu","Right aligned image":"",Save:"Guardar","Show more items":"","Side image":"Imaxen llateral",Square:"","Start at":"","Start index must be greater than 0.":"",Strikethrough:"","Strikethrough text":"",Subscript:"",Superscript:"","Text alternative":"","These keyboard shortcuts allow for quick access to content editing features.":"","This link has no URL":"","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lower–latin list style":"","Toggle the lower–roman list style":"","Toggle the square list style":"","Toggle the upper–latin list style":"","Toggle the upper–roman list style":"",Turquoise:"",Underline:"","Underline text":"",Undo:"Desfacer",Unlink:"Desenllazar",Update:"","Update image URL":"","Upload failed":"","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["bs"]=e["bs"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 od %1",Accept:"",Accessibility:"","Accessibility help":"","Align center":"Centrirati","Align left":"Lijevo poravnanje","Align right":"Desno poravnanje",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Big:"",Black:"","Block quote":"Citat",Blue:"",Bold:"Podebljano","Bold text":"","Break text":"",Cancel:"Poništi","Caption for image: %0":"","Caption for the image":"","Centered image":"Centrirana slika","Change image text alternative":"Promijeni ALT atribut za sliku","Choose heading":"Odaberi naslov",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Kod","Code block":"","Content editing keystrokes":"",Default:"Zadani","Dim grey":"","Document colors":"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter image caption":"Unesi naziv slike","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Font Background Color":"Boja pozadine","Font Color":"Boja","Font Family":"Font","Font Size":"Veličina fonta","Full size image":"",Green:"",Grey:"",Heading:"Naslov","Heading 1":"Naslov 1","Heading 2":"Naslov 2","Heading 3":"Naslov 3","Heading 4":"Naslov 4","Heading 5":"Naslov 5","Heading 6":"Naslov 6","Help Contents. To close this dialog press ESC.":"",HEX:"",Huge:"","Image from computer":"","Image resize list":"Lista veličina slike","Image toolbar":"","image widget":"","In line":"",Insert:"Umetni","Insert code block":"Umetni kod blok","Insert image":"Umetni sliku","Insert image via URL":"Umetni sliku preko URLa",Italic:"Zakrivljeno","Italic text":"",Justify:"","Left aligned image":"Lijevo poravnata slika","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"Uredi",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"Umetni",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"",Original:"Original",Paragraph:"Paragraf","Plain text":"Tekst","Press %0 for help.":"",Previous:"",Purple:"",Red:"","Remove color":"Ukloni boju","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"Promijeni veličinu slike","Resize image to %0":"","Resize image to the original size":"Postavi originalnu veličinu slike","Restore default":"Vrati na zadano","Rich Text Editor":"","Right aligned image":"Desno poravnata slika",Save:"Sačuvaj","Show more items":"Prikaži više stavki","Side image":"",Small:"",Strikethrough:"Precrtano","Strikethrough text":"",Subscript:"",Superscript:"","Text alignment":"Poravnanje teksta","Text alignment toolbar":"Traka za poravnanje teksta","Text alternative":"ALT atribut","These keyboard shortcuts allow for quick access to content editing features.":"",Tiny:"","Toggle caption off":"","Toggle caption on":"",Turquoise:"","Type or paste your content here.":"Unesite ili zalijepite vaš sadržaj ovdje","Type your title":"Unesite naslov",Underline:"Podcrtano","Underline text":"",Update:"Ažuriraj","Update image URL":"Ažuriraj URL slike","Upload failed":"Učitavanje slike nije uspjelo","Upload from computer":"","Upload image from computer":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Wrap text":"Prelomi tekst",Yellow:""});t.getPluralForm=function(e){return e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["eo"]=e["eo"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"",Blue:"",Bold:"grasa","Bold text":"","Break text":"","Bulleted List":"Bula Listo","Bulleted list styles toolbar":"",Cancel:"Nuligi","Caption for image: %0":"","Caption for the image":"","Centered image":"","Change image text alternative":"Ŝanĝu la alternativan tekston de la bildo","Choose heading":"Elektu ĉapon",Circle:"",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"","Content editing keystrokes":"","Create link":"",Decimal:"","Decimal with leading zero":"","Decrease list item indent":"","Dim grey":"",Disc:"",Downloadable:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter image caption":"Skribu klarigon pri la bildo","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Full size image":"Bildo kun reala dimensio",Green:"",Grey:"",Heading:"Ĉapo","Heading 1":"Ĉapo 1","Heading 2":"Ĉapo 2","Heading 3":"Ĉapo 3","Heading 4":"","Heading 5":"","Heading 6":"","Help Contents. To close this dialog press ESC.":"",HEX:"","Image from computer":"","Image resize list":"","Image toolbar":"","image widget":"bilda fenestraĵo","In line":"","Increase list item indent":"",Insert:"","Insert image":"Enmetu bildon","Insert image via URL":"","Invalid start index value.":"",Italic:"kursiva","Italic text":"","Keystrokes that can be used in a list":"","Left aligned image":"","Light blue":"","Light green":"","Light grey":"",Link:"Ligilo","Link image":"","Link URL":"URL de la ligilo","List properties":"","Lower-latin":"","Lower–roman":"",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of a link":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Numbered List":"Numerita Listo","Numbered list styles toolbar":"","Open in a new tab":"","Open link in new tab":"","Open the accessibility help dialog":"",Orange:"",Original:"",Paragraph:"Paragrafo","Press %0 for help.":"",Previous:"",Purple:"",Red:"",Redo:"Refari","Remove color":"","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"","Reversed order":"","Rich Text Editor":"Redaktilo de Riĉa Teksto","Right aligned image":"",Save:"Konservi","Show more items":"","Side image":"Flanka biildo",Square:"","Start at":"","Start index must be greater than 0.":"",Strikethrough:"","Strikethrough text":"",Subscript:"",Superscript:"","Text alternative":"Alternativa teksto","These keyboard shortcuts allow for quick access to content editing features.":"","This link has no URL":"","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lower–latin list style":"","Toggle the lower–roman list style":"","Toggle the square list style":"","Toggle the upper–latin list style":"","Toggle the upper–roman list style":"",Turquoise:"","Type or paste your content here.":"","Type your title":"",Underline:"","Underline text":"",Undo:"Malfari",Unlink:"Malligi",Update:"","Update image URL":"","Upload failed":"","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["es-co"]=e["es-co"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 de %1",Accept:"",Accessibility:"","Accessibility help":"","Align center":"Centrar","Align left":"Alinear a la izquierda","Align right":"Alinear a la derecha",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Big:"Grande",Black:"","Block quote":"Cita de bloque",Blue:"",Bold:"Negrita","Bold text":"","Break text":"",Cancel:"Cancelar","Caption for image: %0":"","Caption for the image":"","Centered image":"","Change image text alternative":"",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Código","Code block":"","Content editing keystrokes":"","Copy selected content":"Copiar contenido seleccionado",Default:"Por defecto","Dim grey":"","Document colors":"Colores del documento","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter image caption":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Font Background Color":"Color de fondo de fuente","Font Color":"Color de fuente","Font Family":"Familia de fuente","Font Size":"Tamaño de fuente","Full size image":"",Green:"",Grey:"","Help Contents. To close this dialog press ESC.":"",HEX:"",Huge:"Enorme","Image from computer":"","Image resize list":"","Image toolbar":"","image widget":"","In line":"",Insert:"Insertar","Insert code block":"Insertar bloque de código","Insert image":"","Insert image via URL":"",Italic:"Cursiva","Italic text":"Texto en cursiva",Justify:"Justificar","Left aligned image":"","Light blue":"","Light green":"","Light grey":"",MENU_BAR_MENU_EDIT:"Editar",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"Insertar",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Open the accessibility help dialog":"",Orange:"",Original:"","Paste content":"Pegar contenido","Paste content as plain text":"Pegar contenido como texto plano","Plain text":"Texto plano","Press %0 for help.":"",Previous:"",Purple:"",Red:"","Remove color":"Quitar color","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"Restaurar valores predeterminados","Revert autoformatting action":"Revertir la acción de formato automático","Rich Text Editor":"","Right aligned image":"",Save:"Guardar","Show more items":"Mostrar más elementos","Side image":"",Small:"Pequeña",Strikethrough:"Tachado","Strikethrough text":"",Subscript:"Subíndice",Superscript:"Superíndice","Text alignment":"Alineación de texto","Text alignment toolbar":"Herramientas de alineación de texto","Text alternative":"","These keyboard shortcuts allow for quick access to content editing features.":"",Tiny:"Diminuta","Toggle caption off":"","Toggle caption on":"",Turquoise:"",Underline:"Subrayado","Underline text":"",Update:"","Update image URL":"","Upload failed":"","Upload from computer":"","Upload image from computer":"","Upload in progress":"Carga en progreso","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return e==1?0:e!=0&&e%1e6==0?1:2}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["eu"]=e["eu"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Black:"","Block quote":"Aipua",Blue:"",Bold:"Lodia","Bold text":"","Break text":"","Bulleted List":"Buletdun zerrenda","Bulleted list styles toolbar":"",Cancel:"Utzi","Caption for image: %0":"","Caption for the image":"","Centered image":"Zentratutako irudia","Change image text alternative":"Aldatu irudiaren ordezko testua","Choose heading":"Aukeratu izenburua",Circle:"",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Kodea","Content editing keystrokes":"","Create link":"",Decimal:"","Decimal with leading zero":"","Decrease list item indent":"","Dim grey":"",Disc:"",Downloadable:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Edit link":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter image caption":"Sartu irudiaren epigrafea","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Full size image":"Tamaina osoko irudia",Green:"",Grey:"",Heading:"Izenburua","Heading 1":"Izenburua 1","Heading 2":"Izenburua 2","Heading 3":"Izenburua 3","Heading 4":"","Heading 5":"","Heading 6":"","Help Contents. To close this dialog press ESC.":"",HEX:"","Image from computer":"","Image resize list":"","Image toolbar":"","image widget":"irudi widgeta","In line":"","Increase list item indent":"",Insert:"","Insert image":"Txertatu irudia","Insert image via URL":"","Invalid start index value.":"",Italic:"Etzana","Italic text":"","Keystrokes that can be used in a list":"","Left aligned image":"Ezkerrean lerrokatutako irudia","Light blue":"","Light green":"","Light grey":"",Link:"Esteka","Link image":"","Link URL":"Estekaren URLa","List properties":"","Lower-latin":"","Lower–roman":"",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of a link":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Numbered List":"Zenbakidun zerrenda","Numbered list styles toolbar":"","Open in a new tab":"","Open link in new tab":"","Open the accessibility help dialog":"",Orange:"",Original:"",Paragraph:"Paragrafoa","Press %0 for help.":"",Previous:"",Purple:"",Red:"",Redo:"Berregin","Remove color":"","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"","Reversed order":"","Rich Text Editor":"Testu aberastuaren editorea","Right aligned image":"Eskuinean lerrokatutako irudia",Save:"Gorde","Show more items":"","Side image":"Alboko irudia",Square:"","Start at":"","Start index must be greater than 0.":"",Strikethrough:"","Strikethrough text":"",Subscript:"",Superscript:"","Text alternative":"Ordezko testua","These keyboard shortcuts allow for quick access to content editing features.":"","This link has no URL":"","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lower–latin list style":"","Toggle the lower–roman list style":"","Toggle the square list style":"","Toggle the upper–latin list style":"","Toggle the upper–roman list style":"",Turquoise:"","Type or paste your content here.":"","Type your title":"",Underline:"Azpimarra","Underline text":"",Undo:"Desegin",Unlink:"Desestekatu",Update:"","Update image URL":"","Upload failed":"Kargatzeak huts egin du","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["gu"]=e["gu"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"","Block quote":" વિચાર ટાંકો",Bold:"ઘાટુ - બોલ્ડ્","Bold text":"",Cancel:"",Clear:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"","Content editing keystrokes":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Italic:"ત્રાંસુ - ઇટલિક્","Italic text":"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"","Open the accessibility help dialog":"","Remove color":"","Restore default":"",Save:"","Show more items":"",Strikethrough:"","Strikethrough text":"",Subscript:"",Superscript:"","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Underline:"નીચે લિટી - અન્ડરલાઇન્","Underline text":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["hy"]=e["hy"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"","Align cell text to the bottom":"","Align cell text to the center":"","Align cell text to the left":"","Align cell text to the middle":"","Align cell text to the right":"","Align cell text to the top":"","Align table to the left":"","Align table to the right":"",Alignment:"",Background:"",Bold:"Թավագիր","Bold text":"",Border:"",Cancel:"Չեղարկել","Cell properties":"","Center table":"","Choose heading":"",Clear:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Կոդ",Color:"","Color picker":"",Column:"Սյունակ","Content editing keystrokes":"","Create link":"",Dashed:"","Delete column":"","Delete row":"",Dimensions:"",Dotted:"",Double:"",Downloadable:"","Edit link":"Խմբագրել հղումը","Enter table caption":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Groove:"","Header column":"","Header row":"",Heading:"","Heading 1":"Վերնագիր 1","Heading 2":"Վերնագիր 2","Heading 3":"Վերնագիր 3","Heading 4":"","Heading 5":"","Heading 6":"",Height:"","Horizontal text alignment toolbar":"","Insert a new table row (when in the last cell of a table)":"","Insert column left":"","Insert column right":"","Insert row above":"","Insert row below":"","Insert table":"",Inset:"",Italic:"Շեղագիր","Italic text":"","Justify cell text":"","Keystrokes that can be used in a table cell":"",Link:"Հղում","Link image":"","Link URL":"","Merge cell down":"","Merge cell left":"","Merge cell right":"","Merge cell up":"","Merge cells":"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of a link":"","Move out of an inline code style":"","Move the selection to the next cell":"","Move the selection to the previous cell":"","Navigate through the table":"","Navigate through the toolbar or menu bar":"",None:"","Open in a new tab":"","Open link in new tab":"","Open the accessibility help dialog":"",Outset:"",Padding:"",Paragraph:"","Remove color":"","Restore default":"",Ridge:"",Row:"",Save:"","Select column":"","Select row":"","Show more items":"",Solid:"","Split cell horizontally":"","Split cell vertically":"",Strikethrough:"Գծանշել","Strikethrough text":"",Style:"",Subscript:"Ենթատեքստ",Superscript:"Գերագիր",Table:"","Table alignment toolbar":"","Table cell text alignment":"","Table properties":"","Table toolbar":"",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':"",'The value is invalid. Try "10px" or "2em" or simply "2".':"","These keyboard shortcuts allow for quick access to content editing features.":"","This link has no URL":"","Toggle caption off":"","Toggle caption on":"","Type or paste your content here.":"","Type your title":"",Underline:"Ընդգծել","Underline text":"",Unlink:"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"","Vertical text alignment toolbar":"",Width:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["jv"]=e["jv"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"%0 saking %1",Accept:"",Accessibility:"","Accessibility help":"","Align center":"Rata tengah","Align left":"Rata kiwa","Align right":"Rata tengen",Aquamarine:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Big:"Ageng",Black:"",Blue:"",Bold:"Kandhel","Bold text":"","Break text":"","Bulleted List":"","Bulleted list styles toolbar":"",Cancel:"Batal","Caption for image: %0":"","Caption for the image":"","Centered image":"Gambar ing tengah","Change image text alternative":"","Choose heading":"",Circle:"Bunder",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Kode","Code block":"","Content editing keystrokes":"",Decimal:"","Decimal with leading zero":"","Decrease list item indent":"",Default:"Default","Dim grey":"",Disc:"Kaset","Document colors":"Warni dokumen","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter image caption":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Font Background Color":"Warni Latar Aksara","Font Color":"Warni aksara","Font Family":"Jinising Aksara","Font Size":"Ukuran aksara","Full size image":"Gambar ukuran kebak",Green:"",Grey:"",Heading:"","Heading 1":"","Heading 2":"","Heading 3":"","Heading 4":"","Heading 5":"","Heading 6":"","Help Contents. To close this dialog press ESC.":"",HEX:"",Huge:"Langkung ageng","Image from computer":"","Image resize list":"","Image toolbar":"","image widget":"","In line":"","Increase list item indent":"",Insert:"Tambah","Insert code block":"","Insert image":"Tambahaken gambar","Insert image via URL":"Tambah gambar saking URL","Invalid start index value.":"",Italic:"Miring","Italic text":"",Justify:"Rata kiwa tengen","Keystrokes that can be used in a list":"","Left aligned image":"Gambar ing kiwa","Light blue":"","Light green":"","Light grey":"","List properties":"","Lower-latin":"","Lower–roman":"",MENU_BAR_MENU_EDIT:"Ebah",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"Tambah",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"","Numbered List":"","Numbered list styles toolbar":"","Open the accessibility help dialog":"",Orange:"",Original:"Asli",Paragraph:"","Plain text":"Seratan biasa","Press %0 for help.":"",Previous:"",Purple:"",Red:"","Remove color":"Busek warni","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"Mangsulaken default","Reversed order":"Dipunwangsul","Rich Text Editor":"","Right aligned image":"Gambar ing tengen",Save:"Rimat","Show more items":"Tampilaken langkung kathah","Side image":"",Small:"Alit",Square:"Kotak","Start at":"Wiwit saking","Start index must be greater than 0.":"",Strikethrough:"Seratan dicoret","Strikethrough text":"",Subscript:"",Superscript:"","Text alignment":"Perataan seratan","Text alignment toolbar":"","Text alternative":"","These keyboard shortcuts allow for quick access to content editing features.":"",Tiny:"Langkung alit","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lower–latin list style":"","Toggle the lower–roman list style":"","Toggle the square list style":"","Toggle the upper–latin list style":"","Toggle the upper–roman list style":"",Turquoise:"","Type or paste your content here.":"Serataken utawi nyukani babagan ing ngriki","Type your title":"Serataken irah-irahan",Underline:"Garis ngandhap","Underline text":"",Update:"","Update image URL":"","Upload failed":"","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"",White:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return 0}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
|
|
@ -0,0 +1 @@
|
|||
(function(n){const t=n["kk"]=n["kk"]||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Ортадан туралау","Align left":"Солға туралау","Align right":"Оңға туралау",Justify:"","Text alignment":"Мәтінді туралау","Text alignment toolbar":"Мәтінді туралау құралдар тақтасы"});t.getPluralForm=function(n){return n!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["oc"]=e["oc"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"",Bold:"Gras","Bold text":"",Cancel:"Anullar",Clear:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"","Content editing keystrokes":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"",Italic:"Italica","Italic text":"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"","Open the accessibility help dialog":"","Remove color":"","Restore default":"",Save:"Enregistrar","Show more items":"",Strikethrough:"","Strikethrough text":"",Subscript:"",Superscript:"","These keyboard shortcuts allow for quick access to content editing features.":"","Toggle caption off":"","Toggle caption on":"",Underline:"","Underline text":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":""});t.getPluralForm=function(e){return e>1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["si"]=e["si"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"",Bold:"තදකුරු","Bold text":"","Break text":"","Bulleted List":"බුලටිත ලැයිස්තුව","Bulleted list styles toolbar":"",Cancel:"","Caption for image: %0":"","Caption for the image":"","Centered image":"","Change image text alternative":"",Circle:"",Clear:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"","Content editing keystrokes":"",Decimal:"","Decimal with leading zero":"","Decrease list item indent":"",Disc:"","Enter image caption":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Full size image":"","Image from computer":"","Image resize list":"","Image toolbar":"","image widget":"","In line":"","Increase list item indent":"",Insert:"","Insert image":"පින්තූරය ඇතුල් කරන්න","Insert image via URL":"","Invalid start index value.":"",Italic:"ඇලකුරු","Italic text":"","Keystrokes that can be used in a list":"","Left aligned image":"","List properties":"","Lower-latin":"","Lower–roman":"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Navigate through the toolbar or menu bar":"","Numbered List":"අංකිත ලැයිස්තුව","Numbered list styles toolbar":"","Open the accessibility help dialog":"",Original:"",Redo:"නැවත කරන්න","Remove color":"","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"","Reversed order":"","Right aligned image":"",Save:"","Show more items":"","Side image":"",Square:"","Start at":"","Start index must be greater than 0.":"",Strikethrough:"","Strikethrough text":"",Subscript:"",Superscript:"","Text alternative":"","These keyboard shortcuts allow for quick access to content editing features.":"","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lower–latin list style":"","Toggle the lower–roman list style":"","Toggle the square list style":"","Toggle the upper–latin list style":"","Toggle the upper–roman list style":"",Underline:"","Underline text":"",Undo:"අහෝසි කරන්න",Update:"","Update image URL":"","Upload failed":"උඩුගත කිරීම අසාර්ථක විය","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"","Wrap text":""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
(function(e){const t=e["sl"]=e["sl"]||{};t.dictionary=Object.assign(t.dictionary||{},{"(may require <kbd>Fn</kbd>)":"","%0 of %1":"",Accept:"",Accessibility:"","Accessibility help":"","Align cell text to the bottom":"","Align cell text to the center":"","Align cell text to the left":"","Align cell text to the middle":"","Align cell text to the right":"","Align cell text to the top":"","Align center":"Sredinska poravnava","Align left":"Poravnava levo","Align right":"Poravnava desno","Align table to the left":"","Align table to the right":"",Alignment:"",Aquamarine:"Akvamarin",Background:"","Below, you can find a list of keyboard shortcuts that can be used in the editor.":"",Big:"Veliko",Black:"Črna","Block quote":"Blokiraj citat",Blue:"Modra",Bold:"Krepko","Bold text":"",Border:"",Cancel:"Prekliči","Cell properties":"","Center table":"","Choose heading":"Izberi naslov",Clear:"","Click to edit block":"",Close:"","Close contextual balloons, dropdowns, and dialogs":"",Code:"Koda",Color:"","Color picker":"",Column:"","Content editing keystrokes":"",Dashed:"",Default:"Privzeto","Delete column":"","Delete row":"","Dim grey":"Temno siva",Dimensions:"","Document colors":"Barve dokumenta",Dotted:"",Double:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor menu bar":"","Editor toolbar":"","Enter table caption":"","Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.":"","Font Background Color":"Barva ozadja pisave","Font Color":"Barva pisave","Font Family":"Vrsta oz. tip pisave","Font Size":"Velikost pisave",Green:"Zelena",Grey:"Siva",Groove:"","Header column":"","Header row":"",Heading:"Naslov","Heading 1":"Naslov 1","Heading 2":"Naslov 2","Heading 3":"Naslov 3","Heading 4":"Naslov 4","Heading 5":"Naslov 5","Heading 6":"Naslov 6",Height:"","Help Contents. To close this dialog press ESC.":"",HEX:"","Horizontal text alignment toolbar":"",Huge:"Ogromno","Insert a new table row (when in the last cell of a table)":"","Insert column left":"","Insert column right":"","Insert row above":"","Insert row below":"","Insert table":"Vstavi tabelo",Inset:"",Italic:"Poševno","Italic text":"",Justify:"Postavi na sredino","Justify cell text":"","Keystrokes that can be used in a table cell":"","Light blue":"Svetlo modra","Light green":"Svetlo zelena","Light grey":"Svetlo siva",MENU_BAR_MENU_EDIT:"",MENU_BAR_MENU_FILE:"",MENU_BAR_MENU_FONT:"",MENU_BAR_MENU_FORMAT:"",MENU_BAR_MENU_HELP:"",MENU_BAR_MENU_INSERT:"",MENU_BAR_MENU_TEXT:"",MENU_BAR_MENU_TOOLS:"",MENU_BAR_MENU_VIEW:"","Merge cell down":"","Merge cell left":"","Merge cell right":"","Merge cell up":"","Merge cells":"","Move focus between form fields (inputs, buttons, etc.)":"","Move focus in and out of an active dialog window":"","Move focus to the menu bar, navigate between menu bars":"","Move focus to the toolbar, navigate between toolbars":"","Move out of an inline code style":"","Move the selection to the next cell":"","Move the selection to the previous cell":"","Navigate through the table":"","Navigate through the toolbar or menu bar":"",Next:"","No results found":"","No searchable items":"",None:"","Open the accessibility help dialog":"",Orange:"Oranžna",Outset:"",Padding:"",Paragraph:"Odstavek","Press %0 for help.":"",Previous:"",Purple:"Vijolična",Red:"Rdeča","Remove color":"Odstrani barvo","Restore default":"","Rich Text Editor":"",Ridge:"",Row:"",Save:"Shrani","Select column":"","Select row":"","Show more items":"",Small:"Majhna",Solid:"","Split cell horizontally":"","Split cell vertically":"",Strikethrough:"Prečrtano","Strikethrough text":"",Style:"",Subscript:"Naročnik",Superscript:"Nadpis",Table:"","Table alignment toolbar":"","Table cell text alignment":"","Table properties":"","Table toolbar":"","Text alignment":"Poravnava besedila","Text alignment toolbar":"Orodna vrstica besedila",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':"",'The value is invalid. Try "10px" or "2em" or simply "2".':"","These keyboard shortcuts allow for quick access to content editing features.":"",Tiny:"Drobna","Toggle caption off":"","Toggle caption on":"",Turquoise:"Turkizna","Type or paste your content here.":"Vnesi ali prilepi vsebino","Type your title":"Vnesi naslov",Underline:"Podčrtaj","Underline text":"","Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.":"","User interface and content navigation keystrokes":"","Vertical text alignment toolbar":"",White:"Bela",Width:"",Yellow:"Rumena"});t.getPluralForm=function(e){return e%100==1?0:e%100==2?1:e%100==3||e%100==4?2:3}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
||||
else
|
||||
exec node "$basedir/../typescript/bin/tsc" "$@"
|
||||
fi
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\typescript\bin\tsc" %*
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue