From 4bf6e82f828438623128072936693b0afa0045f3 Mon Sep 17 00:00:00 2001 From: Victor Phan Date: Sat, 1 Aug 2026 09:27:13 +0700 Subject: [PATCH] feat: integrate CKEditor layout plugins and add supporting import utilities --- ...hìn - Sứ mệnh - Giá trị cốt lõi của UMC.html | 14 +- convert_tam_nhin.py | 167 +++ node_modules/.package-lock.json | 1034 +++++++++++++++- package-lock.json | 1036 ++++++++++++++++- package.json | 2 + .../static/js/manage/editor-plugins/flex.js | 591 ++++++++++ .../static/js/manage/editor-plugins/grid.js | 487 ++++++++ .../templates/manage/pages/form.html | 2 + .../src/main/resources/templates/page.html | 207 +++- tam_nhin_su_menh_import.json | 27 + 10 files changed, 3515 insertions(+), 52 deletions(-) create mode 100644 convert_tam_nhin.py create mode 100644 sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/flex.js create mode 100644 sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/grid.js create mode 100644 tam_nhin_su_menh_import.json diff --git a/BV_DHYD_HCM/Tầm nhìn - Sứ mệnh - Giá trị cốt lõi của UMC.html b/BV_DHYD_HCM/Tầm nhìn - Sứ mệnh - Giá trị cốt lõi của UMC.html index 19347c20..4fab7988 100644 --- a/BV_DHYD_HCM/Tầm nhìn - Sứ mệnh - Giá trị cốt lõi của UMC.html +++ b/BV_DHYD_HCM/Tầm nhìn - Sứ mệnh - Giá trị cốt lõi của UMC.html @@ -1,8 +1,8 @@ -Tầm nhìn - Sứ mệnh - Giá trị cốt lõi của UMC
Tầm nhìn - Sứ mệnh - Giá trị cốt lõi của UMC
tòa nhà trường viện làm mờbanner-mobile-4
tòa nhà trường viện làm mờbanner-mobile-4

TẦM NHÌN

Trở thành bệnh viện đại học dẫn đầu Việt Nam đạt chuẩn quốc tế

mission
vision

SỨ MỆNH

Mang đến giải pháp chăm sóc sức khỏe tối ưu từ sự tích hợp giữa điều trị, nghiên cứu và đào tạo @@ -14,14 +14,14 @@ TP. Hồ Chí Minh

Đơn vị hợp tác
Phòng khám Bệnh viện Đại học Y Dược 1
20-22 Dương Quang Trung, Phường Hòa Hưng, TP. Hồ Chí Minh
Hotline: 1900 6923
Copyright ©2025. Bệnh viện Đại học Y Dược TP. Hồ Chí Minh. - Đã đăng ký bản quyền.
Bộ Công Thương
\ No newline at end of file + \ No newline at end of file diff --git a/convert_tam_nhin.py b/convert_tam_nhin.py new file mode 100644 index 00000000..ae51c0ab --- /dev/null +++ b/convert_tam_nhin.py @@ -0,0 +1,167 @@ +import json +import oracledb + +# Construct the Editor.js JSON structure using raw HTML blocks matching ckeditor5-layout schema +json_data = { + "time": 1700000000000, + "blocks": [ + { + "type": "stickyNav", + "data": { + "title": "Tầm nhìn - Sứ mệnh", + "bgColor": "#ffffff", + "items": [ + {"label": "Giới thiệu tổng quan", "link": "/page/gioi-thieu-tong-quan"}, + {"label": "Lịch sử hình thành", "link": "/page/lich-su-hinh-thanh"}, + {"label": "Tầm nhìn - Sứ mệnh - Giá trị cốt lõi", "link": "/page/tam-nhin-su-menh-gia-tri-cot-loi"}, + {"label": "Ban lãnh đạo", "link": "/page/doi-ngu-lanh-dao"}, + {"label": "Các đơn vị", "link": "/page/cac-don-vi"}, + {"label": "Thành tựu và giải thưởng", "link": "/page/thanh-tuu-va-giai-thuong"} + ] + } + }, + { + "type": "raw", + "data": { + "html": """ +
+ +
+
+ +
+
+
+

TẦM NHÌN

+
+
+

Trở thành bệnh viện đại học dẫn đầu Việt Nam đạt chuẩn quốc tế

+
+
+
+
+ +
+
+ vision +
+
+
+
+
+""", + "stretched": True + } + }, + { + "type": "raw", + "data": { + "html": """ +
+
+
+ +
+
+
+ mission +
+
+
+ +
+
+
+

SỨ MỆNH

+
+
+

Mang đến giải pháp chăm sóc sức khỏe tối ưu từ sự tích hợp giữa điều trị, nghiên cứu và đào tạo

+
+
+
+
+
+""", + "stretched": True + } + }, + { + "type": "raw", + "data": { + "html": """ +
+
+

Giá trị cốt lõi

+ +
+ +
+
+
+ Tiên phong +
+

Tiên phong

+

Phát triển và ứng dụng kỹ thuật tiên tiến vào điều trị, giảng dạy, nghiên cứu

+
+
+ + +
+
+
+ Thấu hiểu +
+

Thấu hiểu

+

Nỗi đau thể xác và tinh thần của người bệnh để đưa ra giải pháp điều trị tối ưu

+
+
+ + +
+
+
+ Chuẩn mực +
+

Chuẩn mực

+

Về y đức và học thuật của người thầy giáo – thầy thuốc

+
+
+ + +
+
+
+ An toàn +
+

An toàn

+

Cho người bệnh, nhân viên y tế và cộng đồng

+
+
+
+
+
+""", + "stretched": True + } + } + ], + "version": "2.30.8" +} + +json_string = json.dumps(json_data, ensure_ascii=False, indent=2) + +with open("tam_nhin_su_menh_import.json", "w", encoding="utf-8") as f: + f.write(json_string) + +print("Generated tam_nhin_su_menh_import.json successfully!") + +# Automatically attempt to update local Oracle Database +try: + conn = oracledb.connect(user='sisvietnam', password='sisvietnam', dsn='localhost:1521/sisvietnam') + cursor = conn.cursor() + cursor.execute("UPDATE sis_page SET content = :content WHERE slug = 'tam-nhin-su-menh-gia-tri-cot-loi'", content=json_string) + conn.commit() + print("Updated database table 'sis_page' for slug 'tam-nhin-su-menh-gia-tri-cot-loi' with layout JSON blocks!") + conn.close() +except Exception as e: + print("DB Update bypassed or failed:", e) diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 88f38d98..375fbb0c 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -1,8 +1,1024 @@ { - "name": "website_sisvietnam.vn", + "name": "sisvietnamvn_01", "lockfileVersion": 3, "requires": true, "packages": { + "node_modules/@ckeditor/ckeditor5-clipboard": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-29.2.0.tgz", + "integrity": "sha512-LT0EKQI4SF/m4+1h27wxXi7F6ounVnKzVComdQM/1Ev8nGFP2fD3RSBGmOSfUAl3w1XCiJSqjIm/AUp7D15qig==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0", + "lodash-es": "^4.17.11" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-core": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-15.0.0.tgz", + "integrity": "sha512-hZ0Bljc3zAzZjn1XDaPQc+ryTx103QnzFdFxRD6iPHCGhEG4iMiA9tP7yf6yQxZzewv6desAEqVK9gHCFaRxww==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^15.0.0", + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-engine": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-15.0.0.tgz", + "integrity": "sha512-6CGzfXmK/tw/fKdXqfp+azpu4fycbrTHKAHmj68we2opGWLvEpuuS/p0g39+PcrMNPYRIVjq+id2676Q6+QZrw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-29.2.0.tgz", + "integrity": "sha512-SSzUZ6iTI1Tymgvol/3HEdsOoMnu6GRl0wdBUizMBqP6SkCLU6t+Zdayz/aRNnU9slLXl0pJyz/aD9jR0N6gKg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-29.2.0.tgz", + "integrity": "sha512-SiitWURZBn08ZW3UGyaOqqThIHhMRew87PGVGUlYZH+xh9trTG9uxSYUBImX4W7K/m/zdgyL2u5akjWLV81y/g==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-29.2.0.tgz", + "integrity": "sha512-GqUQKnNcuT2yQPiZMvOhX4k6bpFsSpUU8wPIt5m991fzO0KcCV42fYFElse9/kajiTn7X4RfybQxIw0abS2ttw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-29.2.0.tgz", + "integrity": "sha512-Kb+GLR4SlIpvvDINLv+0GmPATlIAIqSHPcBwP7xQUQzhYGgJQXDTexcKI/Lx/mbgXE8mNz1QxUzUtB4od/6Wsw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-ui": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-15.0.0.tgz", + "integrity": "sha512-+gTXxYveLcaYewey2xolqfcIOCSP3AJk45KMG+3GtU2r2JedPMGgbR/DwqdTuY4xxrRNLbPC9Mi9e+19cXcJbQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^15.0.0", + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-29.2.0.tgz", + "integrity": "sha512-ADhs5qgou5jG/fW0tMzxeUwVuuNHUpqjLjM2rIjq6Gsb7RlpfhpmZxq6vEKMYfqc1C375fTGA+1kM7KInNU2Cw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-29.2.0.tgz", + "integrity": "sha512-w7J1a3HaveOyBZHO4V/XODs2EsJNJkFJS75I3A3P82tBPb1T5gHOtZADQ4SI9kFnLo1CzLq6jU0YeSCwXETy3w==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-utils": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-15.0.0.tgz", + "integrity": "sha512-eAUYjFusNuj2N8NqGbquMOnSv4wjcO2TuipCP1Rao/FHWX6h+PWBhxnD3J9igRQRvLePYbtQAUAvLeD846JA0A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "ckeditor5": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-widget": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-15.0.0.tgz", + "integrity": "sha512-3kRw02xuJwLFJqbycD3FJhoOalUbRvTSO9dzfTav/21g7vHiDdyKWlhDqP1kISm3N/VRhkP72k3vN4TlnPSraQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^15.0.0", + "@ckeditor/ckeditor5-engine": "^15.0.0", + "@ckeditor/ckeditor5-ui": "^15.0.0", + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@packaged-ui/ckeditor5-layout": { + "version": "0.2.0", + "resolved": "git+ssh://git@github.com/packaged-ui/ckeditor5-layout.git#e5a94c9f6ff6ba3aeeb2e948bae3426bb8688bd0", + "license": "MIT", + "dependencies": { + "@ckeditor/ckeditor5-core": "^15", + "@ckeditor/ckeditor5-ui": "^15", + "@ckeditor/ckeditor5-widget": "^15" + } + }, + "node_modules/@visao/ckeditor5-flex-layout": { + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/@visao/ckeditor5-flex-layout/-/ckeditor5-flex-layout-29.1.0.tgz", + "integrity": "sha512-GyvCREIYdUFeZ/xorzN7+KY7tniSi2phGByvopNKBTG4k0WfHz579vzi7uKxuAHaKdAyLzNzuMjlSAg78NATGQ==", + "license": "MIT", + "dependencies": { + "@ckeditor/ckeditor5-ui": "^29.1.0", + "ckeditor5": "^29.1.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -51,6 +1067,16 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/ckeditor5": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-15.0.0.tgz", + "integrity": "sha512-LVrey6xTa+Sm2CvYaicPbW51/fV19fd9EFkhERSvskTSyKelvzLwBlug0PYHS8JFnrdBWjQf5bbdggzFZyVt2w==", + "license": "GPL-2.0-or-later", + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -202,6 +1228,12 @@ "node": ">=0.10.0" } }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", diff --git a/package-lock.json b/package-lock.json index bbb476a1..80841225 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,1031 @@ { - "name": "website_sisvietnam.vn", + "name": "sisvietnamvn_01", "lockfileVersion": 3, "requires": true, "packages": { "": { "dependencies": { + "@packaged-ui/ckeditor5-layout": "github:packaged-ui/ckeditor5-layout", + "@visao/ckeditor5-flex-layout": "^29.1.0", "cheerio": "^1.2.0" } }, + "node_modules/@ckeditor/ckeditor5-clipboard": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-29.2.0.tgz", + "integrity": "sha512-LT0EKQI4SF/m4+1h27wxXi7F6ounVnKzVComdQM/1Ev8nGFP2fD3RSBGmOSfUAl3w1XCiJSqjIm/AUp7D15qig==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0", + "lodash-es": "^4.17.11" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-clipboard/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-core": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-15.0.0.tgz", + "integrity": "sha512-hZ0Bljc3zAzZjn1XDaPQc+ryTx103QnzFdFxRD6iPHCGhEG4iMiA9tP7yf6yQxZzewv6desAEqVK9gHCFaRxww==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^15.0.0", + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-engine": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-15.0.0.tgz", + "integrity": "sha512-6CGzfXmK/tw/fKdXqfp+azpu4fycbrTHKAHmj68we2opGWLvEpuuS/p0g39+PcrMNPYRIVjq+id2676Q6+QZrw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-29.2.0.tgz", + "integrity": "sha512-SSzUZ6iTI1Tymgvol/3HEdsOoMnu6GRl0wdBUizMBqP6SkCLU6t+Zdayz/aRNnU9slLXl0pJyz/aD9jR0N6gKg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-enter/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-29.2.0.tgz", + "integrity": "sha512-SiitWURZBn08ZW3UGyaOqqThIHhMRew87PGVGUlYZH+xh9trTG9uxSYUBImX4W7K/m/zdgyL2u5akjWLV81y/g==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-paragraph/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-29.2.0.tgz", + "integrity": "sha512-GqUQKnNcuT2yQPiZMvOhX4k6bpFsSpUU8wPIt5m991fzO0KcCV42fYFElse9/kajiTn7X4RfybQxIw0abS2ttw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-select-all/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-29.2.0.tgz", + "integrity": "sha512-Kb+GLR4SlIpvvDINLv+0GmPATlIAIqSHPcBwP7xQUQzhYGgJQXDTexcKI/Lx/mbgXE8mNz1QxUzUtB4od/6Wsw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-typing/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-ui": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-15.0.0.tgz", + "integrity": "sha512-+gTXxYveLcaYewey2xolqfcIOCSP3AJk45KMG+3GtU2r2JedPMGgbR/DwqdTuY4xxrRNLbPC9Mi9e+19cXcJbQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^15.0.0", + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-29.2.0.tgz", + "integrity": "sha512-ADhs5qgou5jG/fW0tMzxeUwVuuNHUpqjLjM2rIjq6Gsb7RlpfhpmZxq6vEKMYfqc1C375fTGA+1kM7KInNU2Cw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-undo/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-29.2.0.tgz", + "integrity": "sha512-w7J1a3HaveOyBZHO4V/XODs2EsJNJkFJS75I3A3P82tBPb1T5gHOtZADQ4SI9kFnLo1CzLq6jU0YeSCwXETy3w==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-upload/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-utils": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-15.0.0.tgz", + "integrity": "sha512-eAUYjFusNuj2N8NqGbquMOnSv4wjcO2TuipCP1Rao/FHWX6h+PWBhxnD3J9igRQRvLePYbtQAUAvLeD846JA0A==", + "license": "GPL-2.0-or-later", + "dependencies": { + "ckeditor5": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@ckeditor/ckeditor5-widget": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-15.0.0.tgz", + "integrity": "sha512-3kRw02xuJwLFJqbycD3FJhoOalUbRvTSO9dzfTav/21g7vHiDdyKWlhDqP1kISm3N/VRhkP72k3vN4TlnPSraQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^15.0.0", + "@ckeditor/ckeditor5-engine": "^15.0.0", + "@ckeditor/ckeditor5-ui": "^15.0.0", + "@ckeditor/ckeditor5-utils": "^15.0.0", + "lodash-es": "^4.17.10" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@packaged-ui/ckeditor5-layout": { + "version": "0.2.0", + "resolved": "git+ssh://git@github.com/packaged-ui/ckeditor5-layout.git#e5a94c9f6ff6ba3aeeb2e948bae3426bb8688bd0", + "license": "MIT", + "dependencies": { + "@ckeditor/ckeditor5-core": "^15", + "@ckeditor/ckeditor5-ui": "^15", + "@ckeditor/ckeditor5-widget": "^15" + } + }, + "node_modules/@visao/ckeditor5-flex-layout": { + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/@visao/ckeditor5-flex-layout/-/ckeditor5-flex-layout-29.1.0.tgz", + "integrity": "sha512-GyvCREIYdUFeZ/xorzN7+KY7tniSi2phGByvopNKBTG4k0WfHz579vzi7uKxuAHaKdAyLzNzuMjlSAg78NATGQ==", + "license": "MIT", + "dependencies": { + "@ckeditor/ckeditor5-ui": "^29.1.0", + "ckeditor5": "^29.1.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-core": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-29.2.0.tgz", + "integrity": "sha512-uHLKkbVGRpDkx4y2MYfjfqh2sFrwsKVXwoZ5pflQ0biutwpoeGdwY9rLYeBMI8h8V37M97yVc9UBYSnuDAE5SA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-engine": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-29.2.0.tgz", + "integrity": "sha512-+YJ5xOpBdT2TsLMm29E9pev5ivQYmQq9GvoNXGGhDi+hbP9cV4itJPMjXKZsQpcitBtDwAwsKjwxi6G8TbKglA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-ui": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-29.2.0.tgz", + "integrity": "sha512-jxoXDF7QwFOG7OCifYX2yrNb2PNsBhrMnBSxtWGWjMS9c39QXTUBIuzTXcYPOAOVCxzTpZ+yNxuSmJ9eHe8jMg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-utils": "^29.2.0", + "ckeditor5": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-utils": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-29.2.0.tgz", + "integrity": "sha512-aTbahSk2W7HTc4g9yggWCYpLcHkJ60mffFAXzt8TPeSDJ3obW/9DoDPz5gwLnCArmmuYFDJf9UOaTpEO6GwwAQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/@ckeditor/ckeditor5-widget": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-29.2.0.tgz", + "integrity": "sha512-DuxtXLhQ4jo5471aW9NidzNi/ZU0hIqQOa64Hg18NvLsdqw23mt/yMWgDrxBykygMRdyOQze7EubmhQDbZa95Q==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, + "node_modules/@visao/ckeditor5-flex-layout/node_modules/ckeditor5": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-29.2.0.tgz", + "integrity": "sha512-S0nNmgLbf/Z23bXeuKIe2KeTyWuz7Pt/SnQy13baqAGoBJblBFVG9fdylS7GxCaJmPqJE0dT4RN9rni0LvgGyg==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ckeditor/ckeditor5-clipboard": "^29.2.0", + "@ckeditor/ckeditor5-core": "^29.2.0", + "@ckeditor/ckeditor5-engine": "^29.2.0", + "@ckeditor/ckeditor5-enter": "^29.2.0", + "@ckeditor/ckeditor5-paragraph": "^29.2.0", + "@ckeditor/ckeditor5-select-all": "^29.2.0", + "@ckeditor/ckeditor5-typing": "^29.2.0", + "@ckeditor/ckeditor5-ui": "^29.2.0", + "@ckeditor/ckeditor5-undo": "^29.2.0", + "@ckeditor/ckeditor5-upload": "^29.2.0", + "@ckeditor/ckeditor5-utils": "^29.2.0", + "@ckeditor/ckeditor5-widget": "^29.2.0" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.7.1" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -56,6 +1074,16 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/ckeditor5": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-15.0.0.tgz", + "integrity": "sha512-LVrey6xTa+Sm2CvYaicPbW51/fV19fd9EFkhERSvskTSyKelvzLwBlug0PYHS8JFnrdBWjQf5bbdggzFZyVt2w==", + "license": "GPL-2.0-or-later", + "engines": { + "node": ">=8.0.0", + "npm": ">=5.7.1" + } + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -207,6 +1235,12 @@ "node": ">=0.10.0" } }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", diff --git a/package.json b/package.json index e05af119..807828aa 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { "dependencies": { + "@packaged-ui/ckeditor5-layout": "github:packaged-ui/ckeditor5-layout", + "@visao/ckeditor5-flex-layout": "^29.1.0", "cheerio": "^1.2.0" } } diff --git a/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/flex.js b/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/flex.js new file mode 100644 index 00000000..7dfc4d74 --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/flex.js @@ -0,0 +1,591 @@ +/** + * Flex block tool for Editor.js. + * Allows users to create highly custom Flexbox layouts with alignment, direction, gaps, and custom column items. + * Supports instantiating other registered plugins inside columns dynamically. + */ +class FlexTool { + static get toolbox() { + return { + title: 'Flex Layout', + icon: '' + }; + } + + constructor({ data, api, readOnly }) { + this.api = api; + this.readOnly = readOnly; + this.data = { + cols: parseInt(data.cols) || 2, + direction: data.direction || 'row', + justify: data.justify || 'start', + align: data.align || 'stretch', + gap: data.gap || '3' // standard Bootstrap gap level + }; + this.activeInstances = {}; + + // Load items content dynamically + for (let i = 1; i <= 12; i++) { + this.data[`type${i}`] = data[`type${i}`] || 'html'; + this.data[`col${i}`] = data[`col${i}`] || ''; + this.data[`imgUrl${i}`] = data[`imgUrl${i}`] || ''; + this.data[`ytUrl${i}`] = data[`ytUrl${i}`] || ''; + this.data[`accTitle${i}`] = data[`accTitle${i}`] || ''; + this.data[`accContent${i}`] = data[`accContent${i}`] || ''; + this.data[`class${i}`] = data[`class${i}`] || ''; + this.data[`id${i}`] = data[`id${i}`] || ''; + this.data[`width${i}`] = parseInt(data[`width${i}`]) || 0; // 0 means auto + } + this.wrapper = undefined; + } + + render() { + this.wrapper = document.createElement('div'); + this.wrapper.className = 'p-3 bg-light border rounded mb-3 ce-flex-tool-wrapper'; + this.wrapper.style.fontFamily = 'inherit'; + + const title = document.createElement('div'); + title.className = 'font-weight-bold text-primary small mb-3'; + title.innerHTML = ' Custom Flexbox Layout Builder'; + this.wrapper.appendChild(title); + + // Container Flex Settings Row + const settingsRow = document.createElement('div'); + settingsRow.className = 'form-row mb-3 pb-3 border-bottom'; + + // 1. Direction + const dirCol = document.createElement('div'); + dirCol.className = 'col-md-3 col-sm-6 mb-2'; + dirCol.innerHTML = ''; + const dirSelect = document.createElement('select'); + dirSelect.className = 'custom-select custom-select-sm'; + const dirOpts = [ + { val: 'row', lbl: 'Row' }, + { val: 'row-reverse', lbl: 'Row Reverse' }, + { val: 'column', lbl: 'Column' }, + { val: 'column-reverse', lbl: 'Column Reverse' } + ]; + dirOpts.forEach(o => { + const opt = document.createElement('option'); + opt.value = o.val; + opt.innerText = o.lbl; + opt.selected = this.data.direction === o.val; + dirSelect.appendChild(opt); + }); + dirSelect.addEventListener('change', (e) => this.data.direction = e.target.value); + dirCol.appendChild(dirSelect); + settingsRow.appendChild(dirCol); + + // 2. Justify Content + const justifyCol = document.createElement('div'); + justifyCol.className = 'col-md-3 col-sm-6 mb-2'; + justifyCol.innerHTML = ''; + const justifySelect = document.createElement('select'); + justifySelect.className = 'custom-select custom-select-sm'; + const justifyOpts = [ + { val: 'start', lbl: 'Start' }, + { val: 'center', lbl: 'Center' }, + { val: 'end', lbl: 'End' }, + { val: 'between', lbl: 'Space Between' }, + { val: 'around', lbl: 'Space Around' }, + { val: 'evenly', lbl: 'Space Evenly' } + ]; + justifyOpts.forEach(o => { + const opt = document.createElement('option'); + opt.value = o.val; + opt.innerText = o.lbl; + opt.selected = this.data.justify === o.val; + justifySelect.appendChild(opt); + }); + justifySelect.addEventListener('change', (e) => this.data.justify = e.target.value); + justifyCol.appendChild(justifySelect); + settingsRow.appendChild(justifyCol); + + // 3. Align Items + const alignCol = document.createElement('div'); + alignCol.className = 'col-md-3 col-sm-6 mb-2'; + alignCol.innerHTML = ''; + const alignSelect = document.createElement('select'); + alignSelect.className = 'custom-select custom-select-sm'; + const alignOpts = [ + { val: 'stretch', lbl: 'Stretch' }, + { val: 'start', lbl: 'Start' }, + { val: 'center', lbl: 'Center' }, + { val: 'end', lbl: 'End' } + ]; + alignOpts.forEach(o => { + const opt = document.createElement('option'); + opt.value = o.val; + opt.innerText = o.lbl; + opt.selected = this.data.align === o.val; + alignSelect.appendChild(opt); + }); + alignSelect.addEventListener('change', (e) => this.data.align = e.target.value); + alignCol.appendChild(alignSelect); + settingsRow.appendChild(alignCol); + + // 4. Gap Level + const gapCol = document.createElement('div'); + gapCol.className = 'col-md-3 col-sm-6 mb-2'; + gapCol.innerHTML = ''; + const gapSelect = document.createElement('select'); + gapSelect.className = 'custom-select custom-select-sm'; + const gapOpts = [ + { val: '0', lbl: 'None' }, + { val: '1', lbl: 'Extra Small' }, + { val: '2', lbl: 'Small' }, + { val: '3', lbl: 'Medium' }, + { val: '4', lbl: 'Large' }, + { val: '5', lbl: 'Extra Large' } + ]; + gapOpts.forEach(o => { + const opt = document.createElement('option'); + opt.value = o.val; + opt.innerText = o.lbl; + opt.selected = this.data.gap === o.val; + gapSelect.appendChild(opt); + }); + gapSelect.addEventListener('change', (e) => this.data.gap = e.target.value); + gapCol.appendChild(gapSelect); + settingsRow.appendChild(gapCol); + + this.wrapper.appendChild(settingsRow); + + // Layout Columns Number Input + const countGroup = document.createElement('div'); + countGroup.className = 'form-group mb-3'; + countGroup.innerHTML = ''; + + const input = document.createElement('input'); + input.type = 'number'; + input.className = 'form-control form-control-sm'; + input.style.width = '100px'; + input.min = '1'; + input.max = '12'; + input.value = this.data.cols; + if (this.readOnly) input.disabled = true; + + input.addEventListener('input', (e) => { + let val = parseInt(e.target.value) || 2; + if (val < 1) val = 1; + if (val > 12) val = 12; + this.data.cols = val; + this._renderColumnInputs(); + }); + + countGroup.appendChild(input); + this.wrapper.appendChild(countGroup); + + // Columns inputs container + this.inputsContainer = document.createElement('div'); + this.wrapper.appendChild(this.inputsContainer); + + this._renderColumnInputs(); + + return this.wrapper; + } + + _renderColumnInputs() { + this.inputsContainer.innerHTML = ''; + + const row = document.createElement('div'); + row.className = 'row'; + + const count = this.data.cols; + const colWidthClass = count === 1 ? 'col-12' : (count === 2 ? 'col-md-6' : (count === 3 ? 'col-md-4' : (count === 4 ? 'col-md-3' : 'col-md'))); + + for (let i = 1; i <= count; i++) { + const colDiv = document.createElement('div'); + colDiv.className = `${colWidthClass} mb-3 p-2 border rounded bg-white`; + colDiv.style.boxShadow = '0 1px 3px rgba(0,0,0,0.05)'; + + const headerRow = document.createElement('div'); + headerRow.className = 'd-flex justify-content-between align-items-center mb-2 pb-1 border-bottom'; + + const label = document.createElement('label'); + label.className = 'small font-weight-bold text-dark mb-0'; + label.innerText = `Item ${i}`; + headerRow.appendChild(label); + + const controlsWrapper = document.createElement('div'); + controlsWrapper.className = 'd-flex align-items-center gap-1'; + + // Width Selector + const widthSelect = document.createElement('select'); + widthSelect.className = 'custom-select custom-select-sm mr-1'; + widthSelect.style.width = '75px'; + if (this.readOnly) widthSelect.disabled = true; + + const widthOpts = [ + { val: 0, lbl: 'Auto' }, + { val: 1, lbl: '1/12' }, + { val: 2, lbl: '2/12' }, + { val: 3, lbl: '3/12' }, + { val: 4, lbl: '4/12' }, + { val: 5, lbl: '5/12' }, + { val: 6, lbl: '6/12' }, + { val: 7, lbl: '7/12' }, + { val: 8, lbl: '8/12' }, + { val: 9, lbl: '9/12' }, + { val: 10, lbl: '10/12' }, + { val: 11, lbl: '11/12' }, + { val: 12, lbl: '12/12' } + ]; + + widthOpts.forEach(o => { + const opt = document.createElement('option'); + opt.value = o.val; + opt.innerText = o.lbl; + opt.selected = this.data[`width${i}`] === o.val; + widthSelect.appendChild(opt); + }); + + widthSelect.addEventListener('change', (e) => { + this.data[`width${i}`] = parseInt(e.target.value) || 0; + }); + + controlsWrapper.appendChild(widthSelect); + + // Column Type Select (Built-ins + Registered plugins dynamically) + const typeSelect = document.createElement('select'); + typeSelect.className = 'custom-select custom-select-sm'; + typeSelect.style.width = '100px'; + if (this.readOnly) typeSelect.disabled = true; + + const types = [ + { value: 'html', label: 'HTML/Text' }, + { value: 'image', label: 'Image' }, + { value: 'youtube', label: 'YouTube' }, + { value: 'accordion', label: 'Accordion' } + ]; + + if (window.SISEditorPlugins) { + Object.keys(window.SISEditorPlugins).forEach(key => { + // Avoid self-nesting flex to prevent recursion issues + if (key !== 'flex' && !types.some(t => t.value === key)) { + types.push({ value: key, label: `[Plugin] ${key}` }); + } + }); + } + + types.forEach(t => { + const opt = document.createElement('option'); + opt.value = t.value; + opt.innerText = t.label; + opt.selected = this.data[`type${i}`] === t.value; + typeSelect.appendChild(opt); + }); + + const contentDiv = document.createElement('div'); + + typeSelect.addEventListener('change', (e) => { + this.data[`type${i}`] = e.target.value; + this._renderTypeSpecificInput(i, contentDiv); + }); + + controlsWrapper.appendChild(typeSelect); + headerRow.appendChild(controlsWrapper); + colDiv.appendChild(headerRow); + colDiv.appendChild(contentDiv); + row.appendChild(colDiv); + + this._renderTypeSpecificInput(i, contentDiv); + } + + this.inputsContainer.appendChild(row); + } + + _renderTypeSpecificInput(i, container) { + container.innerHTML = ''; + + // Remove tracking of previous instance + if (this.activeInstances[i]) { + delete this.activeInstances[i]; + } + + const typeContainer = document.createElement('div'); + typeContainer.className = 'mb-3'; + container.appendChild(typeContainer); + + const type = this.data[`type${i}`]; + + // Check if type is a dynamic editor plugin registered in window.SISEditorPlugins + if (window.SISEditorPlugins && window.SISEditorPlugins[type]) { + try { + const pluginClass = window.SISEditorPlugins[type].class; + let parsedData = {}; + if (this.data[`col${i}`]) { + try { + parsedData = typeof this.data[`col${i}`] === 'string' ? JSON.parse(this.data[`col${i}`]) : this.data[`col${i}`]; + } catch (e) { + parsedData = { html: this.data[`col${i}`] }; // fallback + } + } + const instance = new pluginClass({ + data: parsedData, + api: this.api, + readOnly: this.readOnly + }); + this.activeInstances[i] = instance; + + const element = instance.render(); + typeContainer.appendChild(element); + } catch (err) { + console.error(`Failed to render plugin ${type} inside FlexTool:`, err); + typeContainer.innerHTML = `
Error loading plugin ${type}
`; + } + } else if (type === 'html') { + const textarea = document.createElement('textarea'); + textarea.className = 'form-control form-control-sm'; + textarea.style.minHeight = '140px'; + textarea.style.fontSize = '12px'; + textarea.placeholder = `HTML / Text for Item ${i}...`; + textarea.value = typeof this.data[`col${i}`] === 'object' ? JSON.stringify(this.data[`col${i}`]) : this.data[`col${i}`] || ''; + if (this.readOnly) textarea.disabled = true; + + textarea.addEventListener('input', (e) => { + this.data[`col${i}`] = e.target.value; + }); + typeContainer.appendChild(textarea); + + } else if (type === 'image') { + const inputGroup = document.createElement('div'); + inputGroup.className = 'input-group input-group-sm mb-2'; + + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'form-control form-control-sm'; + input.placeholder = 'Paste image URL here...'; + input.value = this.data[`imgUrl${i}`] || ''; + if (this.readOnly) input.disabled = true; + + const appendDiv = document.createElement('div'); + appendDiv.className = 'input-group-append'; + + const chooseBtn = document.createElement('button'); + chooseBtn.type = 'button'; + chooseBtn.className = 'btn btn-outline-secondary'; + chooseBtn.innerText = 'Choose'; + if (this.readOnly) chooseBtn.disabled = true; + chooseBtn.addEventListener('click', () => { + if (typeof openMediaPickerModal === 'function') { + openMediaPickerModal((selectedUrl) => { + input.value = selectedUrl; + this.data[`imgUrl${i}`] = selectedUrl; + previewImg.src = selectedUrl; + previewBox.style.display = 'block'; + }); + } else { + alert('Media Picker modal helper is not loaded.'); + } + }); + + const uploadBtn = document.createElement('button'); + uploadBtn.type = 'button'; + uploadBtn.className = 'btn btn-outline-primary'; + uploadBtn.innerText = 'Upload'; + if (this.readOnly) uploadBtn.disabled = true; + + const fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = 'image/*'; + fileInput.style.display = 'none'; + + uploadBtn.addEventListener('click', () => fileInput.click()); + fileInput.addEventListener('change', async (e) => { + const file = e.target.files[0]; + if (!file) return; + + const formData = new FormData(); + formData.append('image', file); + + uploadBtn.disabled = true; + uploadBtn.innerText = '...'; + + try { + const response = await fetch('/api/manage/media/upload', { + method: 'POST', + body: formData + }); + const result = await response.json(); + if (result.success && result.file && result.file.url) { + const url = result.file.url; + input.value = url; + this.data[`imgUrl${i}`] = url; + previewImg.src = url; + previewBox.style.display = 'block'; + } else { + alert('Upload failed: ' + (result.message || 'Unknown error')); + } + } catch (err) { + console.error(err); + alert('Upload error occurred.'); + } finally { + uploadBtn.disabled = false; + uploadBtn.innerText = 'Upload'; + } + }); + + appendDiv.appendChild(chooseBtn); + appendDiv.appendChild(uploadBtn); + inputGroup.appendChild(input); + inputGroup.appendChild(appendDiv); + typeContainer.appendChild(inputGroup); + typeContainer.appendChild(fileInput); + + const previewBox = document.createElement('div'); + previewBox.className = 'border rounded p-1 text-center bg-light'; + previewBox.style.display = this.data[`imgUrl${i}`] ? 'block' : 'none'; + previewBox.style.maxHeight = '150px'; + previewBox.style.overflow = 'hidden'; + + const previewImg = document.createElement('img'); + previewImg.src = this.data[`imgUrl${i}`] || ''; + previewImg.style.maxWidth = '100%'; + previewImg.style.maxHeight = '140px'; + previewImg.style.objectFit = 'contain'; + + previewBox.appendChild(previewImg); + typeContainer.appendChild(previewBox); + + input.addEventListener('input', (e) => { + const val = e.target.value.trim(); + this.data[`imgUrl${i}`] = val; + if (val) { + previewImg.src = val; + previewBox.style.display = 'block'; + } else { + previewBox.style.display = 'none'; + } + }); + + } else if (type === 'youtube') { + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'form-control form-control-sm mb-2'; + input.placeholder = 'Paste YouTube video URL...'; + input.value = this.data[`ytUrl${i}`] || ''; + if (this.readOnly) input.disabled = true; + + const preview = document.createElement('div'); + preview.className = 'small text-muted p-2 bg-light border rounded'; + preview.innerText = 'Format: https://www.youtube.com/watch?v=XXXXXX'; + + input.addEventListener('input', (e) => { + this.data[`ytUrl${i}`] = e.target.value.trim(); + }); + + typeContainer.appendChild(input); + typeContainer.appendChild(preview); + + } else if (type === 'accordion') { + const titleInput = document.createElement('input'); + titleInput.type = 'text'; + titleInput.className = 'form-control form-control-sm mb-2'; + titleInput.placeholder = 'Accordion Title...'; + titleInput.value = this.data[`accTitle${i}`] || ''; + if (this.readOnly) titleInput.disabled = true; + + const contentTextarea = document.createElement('textarea'); + contentTextarea.className = 'form-control form-control-sm'; + contentTextarea.style.minHeight = '90px'; + contentTextarea.style.fontSize = '12px'; + contentTextarea.placeholder = 'Accordion Body HTML...'; + contentTextarea.value = this.data[`accContent${i}`] || ''; + if (this.readOnly) contentTextarea.disabled = true; + + titleInput.addEventListener('input', (e) => { + this.data[`accTitle${i}`] = e.target.value; + }); + contentTextarea.addEventListener('input', (e) => { + this.data[`accContent${i}`] = e.target.value; + }); + + typeContainer.appendChild(titleInput); + typeContainer.appendChild(contentTextarea); + } + + // Advanced Settings (ID and Class) + const advancedHeader = document.createElement('div'); + advancedHeader.className = 'font-weight-bold text-muted small mb-2'; + advancedHeader.style.fontSize = '10px'; + advancedHeader.innerText = 'ADVANCED SETTINGS'; + container.appendChild(advancedHeader); + + const advRow = document.createElement('div'); + advRow.className = 'form-row'; + + const classCol = document.createElement('div'); + classCol.className = 'col'; + const classInput = document.createElement('input'); + classInput.type = 'text'; + classInput.className = 'form-control form-control-sm'; + classInput.style.fontSize = '11px'; + classInput.placeholder = 'CSS Class(es)...'; + classInput.value = this.data[`class${i}`] || ''; + if (this.readOnly) classInput.disabled = true; + classInput.addEventListener('input', (e) => { + this.data[`class${i}`] = e.target.value.trim(); + }); + classCol.appendChild(classInput); + + const idCol = document.createElement('div'); + idCol.className = 'col'; + const idInput = document.createElement('input'); + idInput.type = 'text'; + idInput.className = 'form-control form-control-sm'; + idInput.style.fontSize = '11px'; + idInput.placeholder = 'HTML ID...'; + idInput.value = this.data[`id${i}`] || ''; + if (this.readOnly) idInput.disabled = true; + idInput.addEventListener('input', (e) => { + this.data[`id${i}`] = e.target.value.trim(); + }); + idCol.appendChild(idInput); + + advRow.appendChild(classCol); + advRow.appendChild(idCol); + container.appendChild(advRow); + } + + save(blockContent) { + const savedData = { + cols: this.data.cols, + direction: this.data.direction, + justify: this.data.justify, + align: this.data.align, + gap: this.data.gap + }; + for (let i = 1; i <= this.data.cols; i++) { + const type = this.data[`type${i}`] || 'html'; + savedData[`type${i}`] = type; + + // If it is a dynamically nested plugin, save its output data + if (this.activeInstances[i]) { + try { + const pluginData = this.activeInstances[i].save(); + savedData[`col${i}`] = pluginData; + } catch (e) { + console.error(`Failed to save plugin ${type} inside FlexTool:`, e); + savedData[`col${i}`] = this.data[`col${i}`]; + } + } else { + savedData[`col${i}`] = this.data[`col${i}`] || ''; + } + + savedData[`imgUrl${i}`] = this.data[`imgUrl${i}`] || ''; + savedData[`ytUrl${i}`] = this.data[`ytUrl${i}`] || ''; + savedData[`accTitle${i}`] = this.data[`accTitle${i}`] || ''; + savedData[`accContent${i}`] = this.data[`accContent${i}`] || ''; + savedData[`class${i}`] = this.data[`class${i}`] || ''; + savedData[`id${i}`] = this.data[`id${i}`] || ''; + savedData[`width${i}`] = this.data[`width${i}`] || 0; + } + return savedData; + } +} + +// Register the plugin globally +window.SISEditorPlugins = window.SISEditorPlugins || {}; +window.SISEditorPlugins['flex'] = { + class: FlexTool +}; diff --git a/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/grid.js b/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/grid.js new file mode 100644 index 00000000..f7522e2d --- /dev/null +++ b/sisvietnamvn_main/src/main/resources/static/js/manage/editor-plugins/grid.js @@ -0,0 +1,487 @@ +/** + * Grid block tool for Editor.js. + * Allows users to create responsive layouts with any number of columns and choose different content types, manual widths, + * and dynamically instantiates other registered editor plugins inside columns. + */ +class GridTool { + static get toolbox() { + return { + title: 'Grid / Columns', + icon: '' + }; + } + + constructor({ data, api, readOnly }) { + this.api = api; + this.readOnly = readOnly; + this.data = { + cols: parseInt(data.cols) || 2 + }; + this.activeInstances = {}; + + // Load column contents dynamically + for (let i = 1; i <= 12; i++) { + this.data[`type${i}`] = data[`type${i}`] || 'html'; + this.data[`col${i}`] = data[`col${i}`] || ''; + this.data[`imgUrl${i}`] = data[`imgUrl${i}`] || ''; + this.data[`ytUrl${i}`] = data[`ytUrl${i}`] || ''; + this.data[`accTitle${i}`] = data[`accTitle${i}`] || ''; + this.data[`accContent${i}`] = data[`accContent${i}`] || ''; + this.data[`class${i}`] = data[`class${i}`] || ''; + this.data[`id${i}`] = data[`id${i}`] || ''; + this.data[`width${i}`] = parseInt(data[`width${i}`]) || 0; // 0 means auto + } + this.wrapper = undefined; + } + + render() { + this.wrapper = document.createElement('div'); + this.wrapper.className = 'p-3 bg-light border rounded mb-3 ce-grid-tool-wrapper'; + this.wrapper.style.fontFamily = 'inherit'; + + const title = document.createElement('div'); + title.className = 'font-weight-bold text-primary small mb-3'; + title.innerHTML = ' Multi-Column Grid Layout'; + this.wrapper.appendChild(title); + + // Layout Columns Number Input + const selectorGroup = document.createElement('div'); + selectorGroup.className = 'form-group mb-3'; + + const label = document.createElement('label'); + label.className = 'small font-weight-bold text-secondary mb-1 d-block'; + label.innerText = 'Number of Columns (1 - 12)'; + selectorGroup.appendChild(label); + + const input = document.createElement('input'); + input.type = 'number'; + input.className = 'form-control form-control-sm'; + input.style.width = '100px'; + input.min = '1'; + input.max = '12'; + input.value = this.data.cols; + if (this.readOnly) input.disabled = true; + + input.addEventListener('input', (e) => { + let val = parseInt(e.target.value) || 2; + if (val < 1) val = 1; + if (val > 12) val = 12; + this.data.cols = val; + this._renderColumnInputs(); + }); + + selectorGroup.appendChild(input); + this.wrapper.appendChild(selectorGroup); + + // Columns inputs container + this.inputsContainer = document.createElement('div'); + this.wrapper.appendChild(this.inputsContainer); + + this._renderColumnInputs(); + + return this.wrapper; + } + + _renderColumnInputs() { + this.inputsContainer.innerHTML = ''; + + const row = document.createElement('div'); + row.className = 'row'; + + const count = this.data.cols; + const colWidthClass = count === 1 ? 'col-12' : (count === 2 ? 'col-md-6' : (count === 3 ? 'col-md-4' : (count === 4 ? 'col-md-3' : 'col-md'))); + + for (let i = 1; i <= count; i++) { + const colDiv = document.createElement('div'); + colDiv.className = `${colWidthClass} mb-3 p-2 border rounded bg-white`; + colDiv.style.boxShadow = '0 1px 3px rgba(0,0,0,0.05)'; + + const headerRow = document.createElement('div'); + headerRow.className = 'd-flex justify-content-between align-items-center mb-2 pb-1 border-bottom'; + + const label = document.createElement('label'); + label.className = 'small font-weight-bold text-dark mb-0'; + label.innerText = `Col ${i}`; + headerRow.appendChild(label); + + const controlsWrapper = document.createElement('div'); + controlsWrapper.className = 'd-flex align-items-center gap-1'; + + // Width Selector + const widthSelect = document.createElement('select'); + widthSelect.className = 'custom-select custom-select-sm mr-1'; + widthSelect.style.width = '75px'; + if (this.readOnly) widthSelect.disabled = true; + + const widthOpts = [ + { val: 0, lbl: 'Auto' }, + { val: 1, lbl: '1/12' }, + { val: 2, lbl: '2/12' }, + { val: 3, lbl: '3/12' }, + { val: 4, lbl: '4/12' }, + { val: 5, lbl: '5/12' }, + { val: 6, lbl: '6/12' }, + { val: 7, lbl: '7/12' }, + { val: 8, lbl: '8/12' }, + { val: 9, lbl: '9/12' }, + { val: 10, lbl: '10/12' }, + { val: 11, lbl: '11/12' }, + { val: 12, lbl: '12/12' } + ]; + + widthOpts.forEach(o => { + const opt = document.createElement('option'); + opt.value = o.val; + opt.innerText = o.lbl; + opt.selected = this.data[`width${i}`] === o.val; + widthSelect.appendChild(opt); + }); + + widthSelect.addEventListener('change', (e) => { + this.data[`width${i}`] = parseInt(e.target.value) || 0; + }); + + controlsWrapper.appendChild(widthSelect); + + // Column Type Select (Built-ins + Registered plugins dynamically) + const typeSelect = document.createElement('select'); + typeSelect.className = 'custom-select custom-select-sm'; + typeSelect.style.width = '100px'; + if (this.readOnly) typeSelect.disabled = true; + + // Base types + const types = [ + { value: 'html', label: 'HTML/Text' }, + { value: 'image', label: 'Image' }, + { value: 'youtube', label: 'YouTube' }, + { value: 'accordion', label: 'Accordion' } + ]; + + // Dynamically add other registered plugins from window.SISEditorPlugins + if (window.SISEditorPlugins) { + Object.keys(window.SISEditorPlugins).forEach(key => { + // Avoid self-nesting grid to prevent recursion issues + if (key !== 'grid' && !types.some(t => t.value === key)) { + types.push({ value: key, label: `[Plugin] ${key}` }); + } + }); + } + + types.forEach(t => { + const opt = document.createElement('option'); + opt.value = t.value; + opt.innerText = t.label; + opt.selected = this.data[`type${i}`] === t.value; + typeSelect.appendChild(opt); + }); + + const contentDiv = document.createElement('div'); + + typeSelect.addEventListener('change', (e) => { + this.data[`type${i}`] = e.target.value; + this._renderTypeSpecificInput(i, contentDiv); + }); + + controlsWrapper.appendChild(typeSelect); + headerRow.appendChild(controlsWrapper); + colDiv.appendChild(headerRow); + colDiv.appendChild(contentDiv); + row.appendChild(colDiv); + + this._renderTypeSpecificInput(i, contentDiv); + } + + this.inputsContainer.appendChild(row); + } + + _renderTypeSpecificInput(i, container) { + container.innerHTML = ''; + + // Remove tracking of previous instance + if (this.activeInstances[i]) { + delete this.activeInstances[i]; + } + + const typeContainer = document.createElement('div'); + typeContainer.className = 'mb-3'; + container.appendChild(typeContainer); + + const type = this.data[`type${i}`]; + + // Check if type is a dynamic editor plugin registered in window.SISEditorPlugins + if (window.SISEditorPlugins && window.SISEditorPlugins[type]) { + try { + const pluginClass = window.SISEditorPlugins[type].class; + let parsedData = {}; + if (this.data[`col${i}`]) { + try { + parsedData = typeof this.data[`col${i}`] === 'string' ? JSON.parse(this.data[`col${i}`]) : this.data[`col${i}`]; + } catch (e) { + parsedData = { html: this.data[`col${i}`] }; // fallback + } + } + const instance = new pluginClass({ + data: parsedData, + api: this.api, + readOnly: this.readOnly + }); + this.activeInstances[i] = instance; + + const element = instance.render(); + typeContainer.appendChild(element); + } catch (err) { + console.error(`Failed to render plugin ${type} inside GridTool:`, err); + typeContainer.innerHTML = `
Error loading plugin ${type}
`; + } + } else if (type === 'html') { + const textarea = document.createElement('textarea'); + textarea.className = 'form-control form-control-sm'; + textarea.style.minHeight = '140px'; + textarea.style.fontSize = '12px'; + textarea.placeholder = `HTML / Text for Column ${i}...`; + textarea.value = typeof this.data[`col${i}`] === 'object' ? JSON.stringify(this.data[`col${i}`]) : this.data[`col${i}`] || ''; + if (this.readOnly) textarea.disabled = true; + + textarea.addEventListener('input', (e) => { + this.data[`col${i}`] = e.target.value; + }); + typeContainer.appendChild(textarea); + + } else if (type === 'image') { + const inputGroup = document.createElement('div'); + inputGroup.className = 'input-group input-group-sm mb-2'; + + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'form-control form-control-sm'; + input.placeholder = 'Paste image URL here...'; + input.value = this.data[`imgUrl${i}`] || ''; + if (this.readOnly) input.disabled = true; + + const appendDiv = document.createElement('div'); + appendDiv.className = 'input-group-append'; + + const chooseBtn = document.createElement('button'); + chooseBtn.type = 'button'; + chooseBtn.className = 'btn btn-outline-secondary'; + chooseBtn.innerText = 'Choose'; + if (this.readOnly) chooseBtn.disabled = true; + chooseBtn.addEventListener('click', () => { + if (typeof openMediaPickerModal === 'function') { + openMediaPickerModal((selectedUrl) => { + input.value = selectedUrl; + this.data[`imgUrl${i}`] = selectedUrl; + previewImg.src = selectedUrl; + previewBox.style.display = 'block'; + }); + } else { + alert('Media Picker modal helper is not loaded.'); + } + }); + + const uploadBtn = document.createElement('button'); + uploadBtn.type = 'button'; + uploadBtn.className = 'btn btn-outline-primary'; + uploadBtn.innerText = 'Upload'; + if (this.readOnly) uploadBtn.disabled = true; + + const fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = 'image/*'; + fileInput.style.display = 'none'; + + uploadBtn.addEventListener('click', () => fileInput.click()); + fileInput.addEventListener('change', async (e) => { + const file = e.target.files[0]; + if (!file) return; + + const formData = new FormData(); + formData.append('image', file); + + uploadBtn.disabled = true; + uploadBtn.innerText = '...'; + + try { + const response = await fetch('/api/manage/media/upload', { + method: 'POST', + body: formData + }); + const result = await response.json(); + if (result.success && result.file && result.file.url) { + const url = result.file.url; + input.value = url; + this.data[`imgUrl${i}`] = url; + previewImg.src = url; + previewBox.style.display = 'block'; + } else { + alert('Upload failed: ' + (result.message || 'Unknown error')); + } + } catch (err) { + console.error(err); + alert('Upload error occurred.'); + } finally { + uploadBtn.disabled = false; + uploadBtn.innerText = 'Upload'; + } + }); + + appendDiv.appendChild(chooseBtn); + appendDiv.appendChild(uploadBtn); + inputGroup.appendChild(input); + inputGroup.appendChild(appendDiv); + typeContainer.appendChild(inputGroup); + typeContainer.appendChild(fileInput); + + const previewBox = document.createElement('div'); + previewBox.className = 'border rounded p-1 text-center bg-light'; + previewBox.style.display = this.data[`imgUrl${i}`] ? 'block' : 'none'; + previewBox.style.maxHeight = '150px'; + previewBox.style.overflow = 'hidden'; + + const previewImg = document.createElement('img'); + previewImg.src = this.data[`imgUrl${i}`] || ''; + previewImg.style.maxWidth = '100%'; + previewImg.style.maxHeight = '140px'; + previewImg.style.objectFit = 'contain'; + + previewBox.appendChild(previewImg); + typeContainer.appendChild(previewBox); + + input.addEventListener('input', (e) => { + const val = e.target.value.trim(); + this.data[`imgUrl${i}`] = val; + if (val) { + previewImg.src = val; + previewBox.style.display = 'block'; + } else { + previewBox.style.display = 'none'; + } + }); + + } else if (type === 'youtube') { + const input = document.createElement('input'); + input.type = 'text'; + input.className = 'form-control form-control-sm mb-2'; + input.placeholder = 'Paste YouTube video URL...'; + input.value = this.data[`ytUrl${i}`] || ''; + if (this.readOnly) input.disabled = true; + + const preview = document.createElement('div'); + preview.className = 'small text-muted p-2 bg-light border rounded'; + preview.innerText = 'Format: https://www.youtube.com/watch?v=XXXXXX'; + + input.addEventListener('input', (e) => { + this.data[`ytUrl${i}`] = e.target.value.trim(); + }); + + typeContainer.appendChild(input); + typeContainer.appendChild(preview); + + } else if (type === 'accordion') { + const titleInput = document.createElement('input'); + titleInput.type = 'text'; + titleInput.className = 'form-control form-control-sm mb-2'; + titleInput.placeholder = 'Accordion Title...'; + titleInput.value = this.data[`accTitle${i}`] || ''; + if (this.readOnly) titleInput.disabled = true; + + const contentTextarea = document.createElement('textarea'); + contentTextarea.className = 'form-control form-control-sm'; + contentTextarea.style.minHeight = '90px'; + contentTextarea.style.fontSize = '12px'; + contentTextarea.placeholder = 'Accordion Body HTML...'; + contentTextarea.value = this.data[`accContent${i}`] || ''; + if (this.readOnly) contentTextarea.disabled = true; + + titleInput.addEventListener('input', (e) => { + this.data[`accTitle${i}`] = e.target.value; + }); + contentTextarea.addEventListener('input', (e) => { + this.data[`accContent${i}`] = e.target.value; + }); + + typeContainer.appendChild(titleInput); + typeContainer.appendChild(contentTextarea); + } + + // Advanced Settings (ID and Class) + const advancedHeader = document.createElement('div'); + advancedHeader.className = 'font-weight-bold text-muted small mb-2'; + advancedHeader.style.fontSize = '10px'; + advancedHeader.innerText = 'ADVANCED SETTINGS'; + container.appendChild(advancedHeader); + + const advRow = document.createElement('div'); + advRow.className = 'form-row'; + + const classCol = document.createElement('div'); + classCol.className = 'col'; + const classInput = document.createElement('input'); + classInput.type = 'text'; + classInput.className = 'form-control form-control-sm'; + classInput.style.fontSize = '11px'; + classInput.placeholder = 'CSS Class(es)...'; + classInput.value = this.data[`class${i}`] || ''; + if (this.readOnly) classInput.disabled = true; + classInput.addEventListener('input', (e) => { + this.data[`class${i}`] = e.target.value.trim(); + }); + classCol.appendChild(classInput); + + const idCol = document.createElement('div'); + idCol.className = 'col'; + const idInput = document.createElement('input'); + idInput.type = 'text'; + idInput.className = 'form-control form-control-sm'; + idInput.style.fontSize = '11px'; + idInput.placeholder = 'HTML ID...'; + idInput.value = this.data[`id${i}`] || ''; + if (this.readOnly) idInput.disabled = true; + idInput.addEventListener('input', (e) => { + this.data[`id${i}`] = e.target.value.trim(); + }); + idCol.appendChild(idInput); + + advRow.appendChild(classCol); + advRow.appendChild(idCol); + container.appendChild(advRow); + } + + save(blockContent) { + const savedData = { + cols: this.data.cols + }; + for (let i = 1; i <= this.data.cols; i++) { + const type = this.data[`type${i}`] || 'html'; + savedData[`type${i}`] = type; + + // If it is a dynamically nested plugin, save its output data + if (this.activeInstances[i]) { + try { + const pluginData = this.activeInstances[i].save(); + savedData[`col${i}`] = pluginData; + } catch (e) { + console.error(`Failed to save plugin ${type} inside GridTool:`, e); + savedData[`col${i}`] = this.data[`col${i}`]; + } + } else { + savedData[`col${i}`] = this.data[`col${i}`] || ''; + } + + savedData[`imgUrl${i}`] = this.data[`imgUrl${i}`] || ''; + savedData[`ytUrl${i}`] = this.data[`ytUrl${i}`] || ''; + savedData[`accTitle${i}`] = this.data[`accTitle${i}`] || ''; + savedData[`accContent${i}`] = this.data[`accContent${i}`] || ''; + savedData[`class${i}`] = this.data[`class${i}`] || ''; + savedData[`id${i}`] = this.data[`id${i}`] || ''; + savedData[`width${i}`] = this.data[`width${i}`] || 0; + } + return savedData; + } +} + +// Register the plugin globally +window.SISEditorPlugins = window.SISEditorPlugins || {}; +window.SISEditorPlugins['grid'] = { + class: GridTool +}; diff --git a/sisvietnamvn_main/src/main/resources/templates/manage/pages/form.html b/sisvietnamvn_main/src/main/resources/templates/manage/pages/form.html index 9b79b55e..c1c6f13c 100644 --- a/sisvietnamvn_main/src/main/resources/templates/manage/pages/form.html +++ b/sisvietnamvn_main/src/main/resources/templates/manage/pages/form.html @@ -429,6 +429,8 @@ + + diff --git a/sisvietnamvn_main/src/main/resources/templates/page.html b/sisvietnamvn_main/src/main/resources/templates/page.html index 32a03a62..226efec0 100644 --- a/sisvietnamvn_main/src/main/resources/templates/page.html +++ b/sisvietnamvn_main/src/main/resources/templates/page.html @@ -290,57 +290,178 @@ Timeline Image -
-
+
- + + + +
+
+ +
+
+
+
+
+
+
+ + + +
+
+ +
+
+
+
+
+
+
+ + + + + + + + +
+ Grid Image +
+
+ + + +
+
+
+ + + + +
+
+
+
+ + + +
+ + Accordion Title + +
+
+
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+
+
+
+ Timeline Image +
+
+
+
+
+
+
+
+