├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── CB-manifest.json ├── CB-worker.js ├── README.md ├── README.txt ├── assets ├── .htaccess ├── ADM-category.js ├── ADM-classified-images.js ├── ADM-classified.js ├── ADM-images.css ├── ADM-images.js ├── ADM-login.js ├── ADM-settings.js ├── ADM-users.js ├── PAGE-activate.js ├── PAGE-cb.js ├── PAGE-classified.css ├── PAGE-classified.js ├── PAGE-forgot.js ├── PAGE-login.js ├── PAGE-myaccount.js ├── PAGE-register.js ├── PAGE-show.js ├── acct.webp ├── bootstrap.bundle.min.js ├── bootstrap.bundle.min.js.map ├── bootstrap.min.css ├── bootstrap.min.css.map ├── cover.webp ├── favicon.png ├── forgot.webp ├── head-classiphpied.webp ├── html2pdf.bundle.min.js ├── ico-512.png ├── login.webp ├── maticon.woff2 ├── noimg.webp ├── ss-classi-1.png ├── ss-classi-2.png ├── ss-classi-3.png ├── ss-classi-4.png ├── ss-classi-5.png ├── ss-classi-6.png ├── tinymce │ ├── CHANGELOG.md │ ├── icons │ │ └── default │ │ │ └── icons.min.js │ ├── langs │ │ └── README.md │ ├── license.txt │ ├── models │ │ └── dom │ │ │ └── model.min.js │ ├── plugins │ │ ├── advlist │ │ │ └── plugin.min.js │ │ ├── anchor │ │ │ └── plugin.min.js │ │ ├── autolink │ │ │ └── plugin.min.js │ │ ├── autoresize │ │ │ └── plugin.min.js │ │ ├── autosave │ │ │ └── plugin.min.js │ │ ├── charmap │ │ │ └── plugin.min.js │ │ ├── code │ │ │ └── plugin.min.js │ │ ├── codesample │ │ │ └── plugin.min.js │ │ ├── directionality │ │ │ └── plugin.min.js │ │ ├── emoticons │ │ │ ├── js │ │ │ │ ├── emojiimages.js │ │ │ │ ├── emojiimages.min.js │ │ │ │ ├── emojis.js │ │ │ │ └── emojis.min.js │ │ │ └── plugin.min.js │ │ ├── fullscreen │ │ │ └── plugin.min.js │ │ ├── help │ │ │ └── plugin.min.js │ │ ├── image │ │ │ └── plugin.min.js │ │ ├── importcss │ │ │ └── plugin.min.js │ │ ├── insertdatetime │ │ │ └── plugin.min.js │ │ ├── link │ │ │ └── plugin.min.js │ │ ├── lists │ │ │ └── plugin.min.js │ │ ├── media │ │ │ └── plugin.min.js │ │ ├── nonbreaking │ │ │ └── plugin.min.js │ │ ├── pagebreak │ │ │ └── plugin.min.js │ │ ├── preview │ │ │ └── plugin.min.js │ │ ├── quickbars │ │ │ └── plugin.min.js │ │ ├── save │ │ │ └── plugin.min.js │ │ ├── searchreplace │ │ │ └── plugin.min.js │ │ ├── table │ │ │ └── plugin.min.js │ │ ├── template │ │ │ └── plugin.min.js │ │ ├── visualblocks │ │ │ └── plugin.min.js │ │ ├── visualchars │ │ │ └── plugin.min.js │ │ └── wordcount │ │ │ └── plugin.min.js │ ├── skins │ │ ├── content │ │ │ ├── dark │ │ │ │ └── content.min.css │ │ │ ├── default │ │ │ │ └── content.min.css │ │ │ ├── document │ │ │ │ └── content.min.css │ │ │ ├── tinymce-5-dark │ │ │ │ └── content.min.css │ │ │ ├── tinymce-5 │ │ │ │ └── content.min.css │ │ │ └── writer │ │ │ │ └── content.min.css │ │ └── ui │ │ │ ├── oxide-dark │ │ │ ├── content.inline.min.css │ │ │ ├── content.min.css │ │ │ ├── skin.min.css │ │ │ └── skin.shadowdom.min.css │ │ │ ├── oxide │ │ │ ├── content.inline.min.css │ │ │ ├── content.min.css │ │ │ ├── skin.min.css │ │ │ └── skin.shadowdom.min.css │ │ │ ├── tinymce-5-dark │ │ │ ├── content.inline.min.css │ │ │ ├── content.min.css │ │ │ ├── skin.min.css │ │ │ └── skin.shadowdom.min.css │ │ │ └── tinymce-5 │ │ │ ├── content.inline.min.css │ │ │ ├── content.min.css │ │ │ ├── skin.min.css │ │ │ └── skin.shadowdom.min.css │ ├── themes │ │ └── silver │ │ │ └── theme.min.js │ ├── tinymce.d.ts │ └── tinymce.min.js └── uploads │ ├── classiphpied-1.webp │ ├── classiphpied-2.webp │ ├── classiphpied-3.webp │ ├── classiphpied-4.webp │ ├── classiphpied-5.webp │ └── classiphpied-6.webp ├── index.php ├── lib ├── .htaccess ├── API-category.php ├── API-classified.php ├── API-images.php ├── API-session.php ├── API-settings.php ├── API-users.php ├── CORE-Config.php ├── CORE-Go.php ├── CORE-Install.php ├── HOOK-API-CORS.php ├── HOOK-Routes.php ├── HOOK-SESS-Load.php ├── HOOK-SESS-Save.php ├── LIB-Category.php ├── LIB-Classified.php ├── LIB-Core.php ├── LIB-DB.php ├── LIB-Forgot.php ├── LIB-Images.php ├── LIB-Mail.php ├── LIB-Page.php ├── LIB-Report.php ├── LIB-Route.php ├── LIB-Session.php ├── LIB-Settings.php ├── LIB-Users.php ├── SQL-Classiphpied-1.sql ├── SQL-DUMMY.sql └── jwt │ ├── autoload.php │ ├── composer │ ├── ClassLoader.php │ ├── InstalledVersions.php │ ├── LICENSE │ ├── autoload_classmap.php │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_real.php │ ├── autoload_static.php │ ├── installed.json │ ├── installed.php │ └── platform_check.php │ └── firebase │ └── php-jwt │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── composer.json │ └── src │ ├── BeforeValidException.php │ ├── CachedKeySet.php │ ├── ExpiredException.php │ ├── JWK.php │ ├── JWT.php │ ├── Key.php │ └── SignatureInvalidException.php └── pages ├── .htaccess ├── ADM-about.php ├── ADM-cat-form.php ├── ADM-cat-list.php ├── ADM-category.php ├── ADM-check.php ├── ADM-cla-form.php ├── ADM-cla-images.php ├── ADM-cla-list.php ├── ADM-home.php ├── ADM-images.php ├── ADM-img-list.php ├── ADM-login.php ├── ADM-reports.php ├── ADM-settings.php ├── ADM-users-form.php ├── ADM-users-list.php ├── ADM-users.php ├── MAIL-activate.php ├── MAIL-forgot-a.php ├── MAIL-forgot-b.php ├── PAGE-404.php ├── PAGE-activate.php ├── PAGE-categories.php ├── PAGE-category.php ├── PAGE-cla-list.php ├── PAGE-forgot.php ├── PAGE-home.php ├── PAGE-login.php ├── PAGE-myaccount.php ├── PAGE-register.php ├── PAGE-show.php ├── REPORT-loader.php ├── TEMPLATE-ADM-bottom.php ├── TEMPLATE-ADM-top.php ├── TEMPLATE-bottom.php └── TEMPLATE-top.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: @code-boxx 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /CB-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "ClassiPHPied", 3 | "name": "ClassiPHPied", 4 | "icons": [{ 5 | "src": "assets/favicon.png", 6 | "sizes": "64x64", 7 | "type": "image/png" 8 | }, { 9 | "src": "assets/ico-512.png", 10 | "sizes": "512x512", 11 | "type": "image/png" 12 | }], 13 | "start_url": "/", 14 | "scope": "/", 15 | "background_color": "white", 16 | "theme_color": "white", 17 | "display": "standalone" 18 | } -------------------------------------------------------------------------------- /CB-worker.js: -------------------------------------------------------------------------------- 1 | // (A) CREATE/INSTALL CACHE 2 | self.addEventListener("install", evt => { 3 | self.skipWaiting(); 4 | evt.waitUntil( 5 | caches.open("Classiphpied") 6 | .then(cache => cache.addAll([ 7 | // (A1) BOOTSTRAP 8 | "assets/bootstrap.bundle.min.js", 9 | "assets/bootstrap.bundle.min.js.map", 10 | "assets/bootstrap.min.css", 11 | "assets/bootstrap.min.css.map", 12 | // (A2) ICONS + IMAGES 13 | "assets/favicon.png", 14 | "assets/ico-512.png", 15 | "assets/acct.webp", 16 | "assets/forgot.webp", 17 | "assets/login.webp", 18 | // (A3) COMMON INTERFACE 19 | "CB-manifest.json", 20 | "assets/PAGE-cb.js", 21 | "assets/maticon.woff2", 22 | // (A4) PAGES 23 | "assets/ADM-category.js", 24 | "assets/ADM-classified.js", 25 | "assets/ADM-classified-images.js", 26 | "assets/ADM-images.css", 27 | "assets/ADM-images.js", 28 | "assets/ADM-settings.js", 29 | "assets/ADM-users.js", 30 | "assets/PAGE-activate.js", 31 | "assets/PAGE-classified.css", 32 | "assets/PAGE-classified.js", 33 | "assets/PAGE-forgot.js", 34 | "assets/PAGE-login.js", 35 | "assets/PAGE-myaccount.js", 36 | "assets/PAGE-register.js", 37 | "assets/PAGE-show.js" 38 | ])) 39 | .catch(err => console.error(err)) 40 | ); 41 | }); 42 | 43 | // (B) CLAIM CONTROL INSTANTLY 44 | self.addEventListener("activate", evt => self.clients.claim()); 45 | 46 | // (C) LOAD FROM CACHE FIRST, FALLBACK TO NETWORK IF NOT FOUND 47 | self.addEventListener("fetch", evt => evt.respondWith( 48 | caches.match(evt.request).then(res => res || fetch(evt.request)) 49 | )); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CLASSIPHPIED 2 | ClassiPHPied is a simple PHP Classified Ads System. This is not a "we have a load of features, but you won't even use half of them" kind of system. Just a basic one, with the essentials to help you get started quickly – Be it for a small business, or expanding on top of it. 3 |

4 | 5 | ## :white_check_mark: FEATURES 6 | 1) Users management. 7 | 2) Ads management. 8 | 3) Images management. 9 | 4) Installable progressive web app. 10 |

11 | 12 | ## :camera: SCREENSHOTS 13 |

14 | 15 | 16 | 17 | 18 | 19 | 20 |

21 |

22 | 23 | ## :ballot_box_with_check: REQUIREMENTS 24 | 1) LAMP/WAMP/MAMP/XAMPP 25 | 2) Apache Mod Rewrite 26 | 3) PHP MYSQL PDO Extension 27 | 4) At least PHP 8.0 28 |

29 | 30 | ## :floppy_disk: INSTALLATION 31 | Just access `http://your-site.com/` in your browser and walk through the installer. The admin panel can be accessed from `http://your-site.com/admin`. 32 |

33 | 34 | ## :bulb: DOCUMENTATION & FRAMEWORKS 35 | 1) Visit https://code-boxx.com/classiphpied-php-classified-system/ for the full documentation! 36 | 2) Built on [Bootstrap](https://getbootstrap.com/), [Material Icons](https://fonts.google.com/icons), [TinyMCE](https://www.tiny.cloud/), [PHP-JWT](https://github.com/firebase/php-jwt), [HTML2PDF](https://ekoopmans.github.io/html2pdf.js/), and [Core Boxx](https://code-boxx.com/core-boxx-php-framework/). 37 |

38 | 39 | ## :star: SUPPORT 40 | Like this project? Just give it a star. That will indirectly help grow my blog a little bit. :wink: 41 |

42 | 43 | ## :newspaper: LICENSE 44 | Copyright by Code Boxx 45 | 46 | Permission is hereby granted, free of charge, to any person obtaining a copy 47 | of this software and associated documentation files (the "Software"), to deal 48 | in the Software without restriction, including without limitation the rights 49 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 50 | copies of the Software, and to permit persons to whom the Software is 51 | furnished to do so, subject to the following conditions: 52 | 53 | The above copyright notice and this permission notice shall be included in all 54 | copies or substantial portions of the Software. 55 | 56 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 58 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 59 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 60 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 61 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 62 | SOFTWARE. -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2 | LICENSE 3 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 4 | 5 | Copyright by Code Boxx 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | 26 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 27 | MORE 28 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 29 | Please visit https://code-boxx.com/ for more! -------------------------------------------------------------------------------- /assets/.htaccess: -------------------------------------------------------------------------------- 1 | Options -Indexes -------------------------------------------------------------------------------- /assets/ADM-category.js: -------------------------------------------------------------------------------- 1 | var cat = { 2 | // (A) SHOW ALL CATEGORIES 3 | pg : 1, // current page 4 | find : "", // current search 5 | list : () => { 6 | cb.page(1); 7 | cb.load({ 8 | page : "admin/cat/list", target : "cat-list", 9 | data : { 10 | page : cat.pg, 11 | search : cat.find 12 | } 13 | }); 14 | }, 15 | 16 | // (B) GO TO PAGE 17 | // pg : int, page number 18 | goToPage : pg => { if (pg!=cat.pg) { 19 | cat.pg = pg; 20 | cat.list(); 21 | }}, 22 | 23 | // (C) SEARCH CATEGORIES 24 | search : () => { 25 | cat.find = document.getElementById("cat-search").value; 26 | cat.pg = 1; 27 | cat.list(); 28 | return false; 29 | }, 30 | 31 | // (D) SHOW ADD/EDIT DOCKET 32 | // id : category ID, for edit only 33 | addEdit : id => cb.load({ 34 | page : "admin/cat/form", target : "cb-page-2", 35 | data : { id : id ? id : "" }, 36 | onload : () => cb.page(2) 37 | }), 38 | 39 | // (E) SAVE CATEGORY 40 | save : () => { 41 | // (E1) GET DATA 42 | var data = { 43 | name : document.getElementById("cat_name").value, 44 | desc : document.getElementById("cat_desc").value, 45 | parent : document.getElementById("cat_parent").value 46 | }; 47 | var id = document.getElementById("cat_id").value; 48 | if (id!="") { data.id = id; } 49 | 50 | // (E2) AJAX 51 | cb.api({ 52 | mod : "category", act : "save", 53 | data : data, 54 | passmsg : "Category Saved", 55 | onpass : cat.list 56 | }); 57 | return false; 58 | }, 59 | 60 | // (F) DELETE CATEGORY 61 | // id : int, category ID 62 | // confirm : boolean, confirmed delete 63 | del : id => cb.modal("Are you sure?", "All child categories will revert to root.", () => cb.api({ 64 | mod : "category", act : "del", 65 | data : { id : id }, 66 | passmsg : "Category Deleted", 67 | onpass : cat.list 68 | })) 69 | }; 70 | window.addEventListener("load", cat.list); -------------------------------------------------------------------------------- /assets/ADM-classified-images.js: -------------------------------------------------------------------------------- 1 | var img = { 2 | // (A) INITIALIZE & SETUP IMAGE PICKER 3 | loaded : false, // already initialized? 4 | slot : 0, // current selected slot 5 | init : slot => { 6 | img.slot = slot; 7 | if (img.loaded) { cb.page(3); img.list(); } 8 | else { 9 | cb.load({ 10 | page : "admin/cla/images", target : "cb-page-3", 11 | onload : () => { 12 | img.loaded = true; 13 | cb.page(3); 14 | img.list(); 15 | } 16 | }); 17 | } 18 | }, 19 | 20 | // (B) LOAD IMAGES 21 | pg : 1, // current page 22 | find : "", // current search 23 | list : () => cb.load({ 24 | page : "admin/img/list", target : "img-list", 25 | data : { 26 | page : img.pg, 27 | search : img.find, 28 | pick : true 29 | } 30 | }), 31 | 32 | // (C) GO TO PAGE 33 | // pg : int, page number 34 | goToPage : pg => { if (pg!=img.pg) { 35 | img.pg = pg; 36 | img.list(); 37 | }}, 38 | 39 | // (D) SEARCH IMAGE 40 | search : () => { 41 | img.find = document.getElementById("img-search").value; 42 | img.pg = 1; 43 | img.list(); 44 | return false; 45 | }, 46 | 47 | // (E) PICK IMAGE 48 | pick : i => { 49 | // (E1) BACK TO FORM 50 | cb.page(2); 51 | 52 | // (E2) CREATE NEW IMAGE TAG 53 | var slot = img.slot, 54 | wrap = document.getElementById("cla_img_" + img.slot), 55 | nimg = document.createElement("img"); 56 | nimg.src = cbhost.uploads + i; 57 | nimg.className = "thumb cla-img"; 58 | nimg.onclick = () => { img.remove(slot); }; 59 | wrap.innerHTML = ""; 60 | wrap.appendChild(nimg); 61 | }, 62 | 63 | // (F) REMOVE IMAGE 64 | // slot : image slot number 65 | remove : slot => { 66 | var wrap = document.getElementById("cla_img_" + slot), 67 | nbtn = document.createElement("button"); 68 | nbtn.className = "cla-img btn btn-primary btn-sm w-100"; 69 | nbtn.type = "button"; 70 | nbtn.innerHTML = "Choose an image"; 71 | nbtn.onclick = () => { img.init(slot); }; 72 | wrap.innerHTML = ""; 73 | wrap.appendChild(nbtn); 74 | } 75 | }; -------------------------------------------------------------------------------- /assets/ADM-classified.js: -------------------------------------------------------------------------------- 1 | var cla = { 2 | // (A) SHOW ALL CLASSIFIED ADS 3 | pg : 1, // current page 4 | find : "", // current search 5 | id : "", // current category 6 | list : () => { 7 | cb.page(1); 8 | cb.load({ 9 | page : "admin/cla/list", target : "cla-list", 10 | data : { 11 | page : cla.pg, 12 | id : cla.id, 13 | search : cla.find 14 | } 15 | }); 16 | }, 17 | 18 | // (B) GO TO PAGE 19 | // pg : int, page number 20 | goToPage : pg => { if (pg!=cla.pg) { 21 | cla.pg = pg; 22 | cla.list(); 23 | }}, 24 | 25 | // (C) SEARCH CLASSIFIEDS 26 | search : () => { 27 | cla.find = document.getElementById("cla-search").value; 28 | cla.id = document.getElementById("cla-cat").value; 29 | cla.pg = 1; 30 | cla.list(); 31 | return false; 32 | }, 33 | 34 | // (D) SHOW ADD/EDIT DOCKET 35 | // id : classified ID, for edit only 36 | addEdit : id => cb.load({ 37 | page : "admin/cla/form", target : "cb-page-2", 38 | data : { id : id ? id : "" }, 39 | onload : () => { 40 | cb.page(2); 41 | tinymce.remove(); 42 | tinymce.init({ 43 | selector : "#cla_text", 44 | menubar : false, 45 | plugins: "lists link", 46 | toolbar: "bold italic underline | forecolor | bullist numlist | alignleft aligncenter alignright alignjustify | link" 47 | }); 48 | } 49 | }), 50 | 51 | // (E) SAVE CLASSIFIED AD 52 | save : () => { 53 | // (E1) MANUAL CHECK TINYMCE TEXT (HTML REQUIRED DOES NOT WORK) 54 | var text = tinymce.get("cla_text").getContent(); 55 | if (text=="") { 56 | cb.modal("Error", "Please fill in the classified text."); 57 | return false; 58 | } 59 | 60 | // (E2) GET DATA 61 | var data = { 62 | cat : document.getElementById("cla_cat").value, 63 | title : document.getElementById("cla_title").value, 64 | summary : document.getElementById("cla_summary").value, 65 | end : document.getElementById("cla_end").value, 66 | text : text, 67 | images : [], 68 | person : document.getElementById("cla_person").value, 69 | email : document.getElementById("cla_email").value, 70 | tel : document.getElementById("cla_tel").value 71 | }; 72 | var id = document.getElementById("cla_id").value; 73 | if (id!="") { data.id = id; } 74 | 75 | // (E3) GET IMAGES 76 | var images = document.querySelectorAll(".cla-img"); 77 | for (let i of images) { 78 | if (i.nodeName=="IMG") { 79 | data.images.push(i.src.replace(/^.*[\\\/]/, "")); 80 | } else { 81 | data.images.push(false); 82 | } 83 | } 84 | data.images = JSON.stringify(data.images); 85 | 86 | // (E3) AJAX 87 | cb.api({ 88 | mod : "classified", act : "save", 89 | data : data, 90 | passmsg : "Classified Ad Saved", 91 | onpass : cla.list 92 | }); 93 | return false; 94 | }, 95 | 96 | // (F) DELETE CLASSIFIED AD 97 | // id : int, classified ID 98 | // confirm : boolean, confirmed delete 99 | del : id => cb.modal("Please confirm", "Delete this entry?", () => cb.api({ 100 | mod : "classified", act : "del", 101 | data : { id: id }, 102 | passmsg : "Classified Ad Deleted", 103 | onpass : cla.list 104 | })) 105 | }; 106 | window.addEventListener("load", cla.list); -------------------------------------------------------------------------------- /assets/ADM-images.css: -------------------------------------------------------------------------------- 1 | img.thumb { 2 | width: 100%; 3 | height: 200px; 4 | object-fit: cover; 5 | } 6 | #img-list .pagination { 7 | margin-top: 10px !important; 8 | } -------------------------------------------------------------------------------- /assets/ADM-images.js: -------------------------------------------------------------------------------- 1 | var img = { 2 | // (A) SHOW ALL IMAGES 3 | pg : 1, // current page 4 | find : "", // current search 5 | list : () => { 6 | cb.page(1); 7 | cb.load({ 8 | page : "admin/img/list", 9 | target : "img-list", 10 | data : { 11 | page : img.pg, 12 | search : img.find 13 | } 14 | }); 15 | }, 16 | 17 | // (B) GO TO PAGE 18 | // pg : int, page number 19 | goToPage : pg => { if (pg!=img.pg) { 20 | img.pg = pg; 21 | img.list(); 22 | }}, 23 | 24 | // (C) SEARCH IMAGE 25 | search : () => { 26 | img.find = document.getElementById("img-search").value; 27 | img.pg = 1; 28 | img.list(); 29 | return false; 30 | }, 31 | 32 | // (D) COPY LINK 33 | // i : image file 34 | copy : i => { 35 | navigator.clipboard.writeText(cbhost.uploads + i) 36 | .then( 37 | () => cb.toast(1, "Success", "Link copied"), 38 | () => cb.toast(0, "Failed", "No permission to access clipboard") 39 | ) 40 | .catch(err => console.error(err)); 41 | }, 42 | 43 | // (E) DELETE IMAGE 44 | // i : image file 45 | // confirm : boolean, confirmed delete 46 | del : i => cb.modal("Please confirm", "Delete image?", () => cb.api({ 47 | mod : "images", act : "del", 48 | data : { file: i }, 49 | passmsg : "Image Deleted", 50 | onpass : img.list 51 | })), 52 | 53 | // (F) UPLOAD IMAGE (ONE AT A TIME) 54 | // i : current upload file number (none to start new upload session) 55 | upqueue : { 56 | list : null, // upload list 57 | now : 0, // current file 58 | all : 0 // all files 59 | }, 60 | upload : i => { 61 | // (F1) NEW UPLOAD 62 | if (i==undefined) { 63 | cb.loading(1); 64 | var field = document.getElementById("img-up"); 65 | img.upqueue.list = field.files; 66 | img.upqueue.now = 0; 67 | img.upqueue.all = field.files.length; 68 | img.upload(img.upqueue.now); 69 | return false; 70 | } 71 | 72 | // (F2) PROCEED AJAX UPLOAD 73 | else { 74 | cb.api({ 75 | mod : "images", act : "upload", 76 | data : { "upfile": img.upqueue.list[img.upqueue.now] }, 77 | loading : false, 78 | passmsg : "Image Uploaded", 79 | onpass : () => { 80 | img.upqueue.now++; 81 | if (img.upqueue.now == img.upqueue.all) { 82 | cb.loading(0); 83 | document.getElementById("img-up").value = ""; 84 | img.list(); 85 | } else { 86 | img.upload(img.upqueue.now); 87 | } 88 | }, 89 | onfail : () => { 90 | cb.loading(0); 91 | document.getElementById("img-up").value = ""; 92 | img.list(); 93 | } 94 | }); 95 | } 96 | } 97 | }; 98 | window.addEventListener("load", img.list); -------------------------------------------------------------------------------- /assets/ADM-login.js: -------------------------------------------------------------------------------- 1 | function login () { 2 | cb.api({ 3 | mod : "session", act : "login", 4 | data : { 5 | email : document.getElementById("login-email").value, 6 | password : document.getElementById("login-pass").value 7 | }, 8 | passmsg : false, 9 | onpass : () => location.href = cbhost.admin 10 | }); 11 | return false; 12 | } -------------------------------------------------------------------------------- /assets/ADM-settings.js: -------------------------------------------------------------------------------- 1 | function save () { 2 | // (A) GET ALL DATA 3 | let data = {}; 4 | for (let i of document.querySelectorAll("#set-list input[type=text]")) { 5 | data[i.name] = i.value; 6 | } 7 | 8 | // (B) API CALL 9 | cb.api({ 10 | mod : "settings", act : "save", 11 | data : { settings : JSON.stringify(data) }, 12 | passmsg : "Settings Saved" 13 | }); 14 | return false; 15 | } -------------------------------------------------------------------------------- /assets/ADM-users.js: -------------------------------------------------------------------------------- 1 | var usr = { 2 | // (A) SHOW ALL USERS 3 | pg : 1, // current page 4 | find : "", // current search 5 | list : () => { 6 | cb.page(1); 7 | cb.load({ 8 | page : "admin/users/list", target : "user-list", 9 | data : { 10 | page : usr.pg, 11 | search : usr.find 12 | } 13 | }); 14 | }, 15 | 16 | // (B) GO TO PAGE 17 | // pg : int, page number 18 | goToPage : pg => { if (pg!=usr.pg) { 19 | usr.pg = pg; 20 | usr.list(); 21 | }}, 22 | 23 | // (C) SEARCH USER 24 | search : () => { 25 | usr.find = document.getElementById("user-search").value; 26 | usr.pg = 1; 27 | usr.list(); 28 | return false; 29 | }, 30 | 31 | // (D) SHOW ADD/EDIT DOCKET 32 | // id : user ID, for edit only 33 | addEdit : id => cb.load({ 34 | page : "admin/users/form", target : "cb-page-2", 35 | data : { id : id ? id : "" }, 36 | onload : () => cb.page(2) 37 | }), 38 | 39 | // (E) SAVE USER 40 | save : () => { 41 | // (E1) GET DATA 42 | var data = { 43 | name : document.getElementById("user_name").value, 44 | email : document.getElementById("user_email").value, 45 | password : document.getElementById("user_password").value 46 | }; 47 | var id = document.getElementById("user_id").value; 48 | if (id!="") { data.id = id; } 49 | 50 | // (E2) PASSWORD STRENGTH 51 | if (!cb.checker(data.password)) { 52 | cb.modal("Error", "Password must be at least 8 characters alphanumeric"); 53 | return false; 54 | } 55 | 56 | // (E3) AJAX 57 | cb.api({ 58 | mod : "users", act : "save", 59 | data : data, 60 | passmsg : "User Saved", 61 | onpass : usr.list 62 | }); 63 | return false; 64 | }, 65 | 66 | // (F) DELETE USER 67 | // id : int, user ID 68 | // confirm : boolean, confirmed delete 69 | del : id => cb.modal("Please confirm", "Delete user?", () => cb.api({ 70 | mod : "users", act : "del", 71 | data : { id: id }, 72 | passmsg : "User Deleted", 73 | onpass : usr.list 74 | })) 75 | }; 76 | window.addEventListener("load", usr.list); -------------------------------------------------------------------------------- /assets/PAGE-activate.js: -------------------------------------------------------------------------------- 1 | function activate () { 2 | cb.api({ 3 | mod : "session", act : "activate", 4 | data : { 5 | id : document.getElementById("activate-email").value 6 | }, 7 | passmsg : false, 8 | onpass : () => cb.modal("Sent", "Please click on the activation link in your email.") 9 | }); 10 | return false; 11 | } -------------------------------------------------------------------------------- /assets/PAGE-classified.css: -------------------------------------------------------------------------------- 1 | #cla-head { 2 | height: 350px; 3 | background-size: cover; 4 | background-position: center; 5 | } 6 | #cla-head form { 7 | width: 90%; bottom: 20px; left: 5%; 8 | padding: 10px; border-radius: 10px; 9 | background: rgba(0, 0, 0, 0.35); 10 | } 11 | #cla-list { align-items: stretch; } 12 | .card { height: 100%; } 13 | img.thumb, img.caroimg { object-fit: cover; } 14 | img.thumb { height: 200px; } 15 | img.caroimg { width: 100%; height: 300px; } 16 | #cla-list .pagination { margin-top: 10px !important; } -------------------------------------------------------------------------------- /assets/PAGE-classified.js: -------------------------------------------------------------------------------- 1 | var cla = { 2 | // (A) SHOW ALL CLASSIFIED ADS 3 | pg : 1, // current page 4 | find : "", // current search 5 | id : "", // current category 6 | list : () => cb.load({ 7 | page : "cla/list", target : "cla-list", 8 | data : { 9 | page : cla.pg, 10 | id : cla.id, 11 | search : cla.find 12 | } 13 | }), 14 | 15 | // (B) GO TO PAGE 16 | // pg : int, page number 17 | goToPage : pg => { if (pg!=cla.pg) { 18 | cla.pg = pg; 19 | cla.list(); 20 | }}, 21 | 22 | // (C) SEARCH CLASSIFIEDS 23 | search : () => { 24 | cla.find = document.getElementById("cla-search").value; 25 | cla.id = document.getElementById("cla-cat").value; 26 | cla.pg = 1; 27 | cla.list(); 28 | return false; 29 | } 30 | }; 31 | window.addEventListener("load", cla.list); -------------------------------------------------------------------------------- /assets/PAGE-forgot.js: -------------------------------------------------------------------------------- 1 | function forgot () { 2 | cb.api({ 3 | mod : "session", act : "forgotA", 4 | data : { email : document.getElementById("forgot-email").value }, 5 | passmsg : false, 6 | onpass : () => cb.modal("Reset Link Sent", "Click on the reset link in your email.") 7 | }); 8 | return false; 9 | } -------------------------------------------------------------------------------- /assets/PAGE-login.js: -------------------------------------------------------------------------------- 1 | function login () { 2 | cb.api({ 3 | mod : "session", act : "login", 4 | data : { 5 | email : document.getElementById("login-email").value, 6 | password : document.getElementById("login-pass").value 7 | }, 8 | passmsg : false, 9 | onpass : () => location.href = cbhost.base 10 | }); 11 | return false; 12 | } -------------------------------------------------------------------------------- /assets/PAGE-myaccount.js: -------------------------------------------------------------------------------- 1 | function save () { 2 | // (A) GET DATA 3 | var data = { 4 | name : document.getElementById("user-name").value, 5 | cpass : document.getElementById("user-cpass").value, 6 | pass : document.getElementById("user-npass").value 7 | }; 8 | 9 | // (B) PASSWORD CHECK 10 | if (data.pass != document.getElementById("user-ncpass").value) { 11 | cb.modal("Please Check", "Passwords do not match."); 12 | return false; 13 | } 14 | 15 | // (C) PASSWORD STRENGTH 16 | if (!cb.checker(data.pass)) { 17 | cb.modal("Please Check", "Password must be at least 8 characters, alphanumeric."); 18 | return false; 19 | } 20 | // @T 21 | // (D) API CALL 22 | cb.api({ 23 | mod : "session", act : "update", 24 | data : data, 25 | passmsg : "Account Updated", 26 | onpass : () => { 27 | document.getElementById("user-cpass").value = ""; 28 | document.getElementById("user-npass").value = ""; 29 | document.getElementById("user-ncpass").value = ""; 30 | } 31 | }); 32 | return false; 33 | } -------------------------------------------------------------------------------- /assets/PAGE-register.js: -------------------------------------------------------------------------------- 1 | function register () { 2 | // (A) PASSWORD CHECK 3 | let pass = document.getElementById("reg-pass").value, 4 | cpass = document.getElementById("reg-cpass").value; 5 | if (pass!=cpass) { 6 | cb.modal("Opps", "Passwords do not match!"); 7 | return false; 8 | } 9 | 10 | // (B) PASSWORD STRENGTH 11 | if (!cb.checker(pass)) { 12 | cb.modal("Opps", "Password must be at least 8 characters alphanumeric."); 13 | return false; 14 | } 15 | 16 | // (C) CALL API 17 | cb.api({ 18 | mod : "session", act : "register", 19 | data : { 20 | name : document.getElementById("reg-name").value, 21 | email : document.getElementById("reg-email").value, 22 | password : pass 23 | }, 24 | passmsg : false, 25 | onpass : () => cb.modal("One More Step", "Please click on the activation link in your email.") 26 | }); 27 | return false; 28 | } -------------------------------------------------------------------------------- /assets/PAGE-show.js: -------------------------------------------------------------------------------- 1 | var show = { 2 | // (A) INITIALIZE 3 | init : () => { if (navigator.share) { 4 | document.getElementById("ad-share").classList.remove("d-none"); 5 | }}, 6 | 7 | // (B) DOWNLOAD IN PDF 8 | pdf : () => { 9 | if (typeof html2pdf == "undefined") { 10 | cb.loading(1); 11 | let s = document.createElement("script"); 12 | s.src = cbhost.assets + "html2pdf.bundle.min.js"; 13 | s.onload = () => { 14 | cb.loading(0); 15 | show.pdf(); 16 | }; 17 | document.head.appendChild(s); 18 | } else { 19 | html2pdf(document.getElementById("cb-page-1")); 20 | } 21 | }, 22 | 23 | // (C) PRINT PAGE 24 | print : () => window.print(), 25 | 26 | // (D) SHARE PAGE 27 | share : () => navigator.share({ 28 | title: document.title, 29 | text: document.querySelector("meta[name=description]").content, 30 | url: window.location.href 31 | }) 32 | }; 33 | window.addEventListener("load", show.init); -------------------------------------------------------------------------------- /assets/acct.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/acct.webp -------------------------------------------------------------------------------- /assets/cover.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/cover.webp -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/favicon.png -------------------------------------------------------------------------------- /assets/forgot.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/forgot.webp -------------------------------------------------------------------------------- /assets/head-classiphpied.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/head-classiphpied.webp -------------------------------------------------------------------------------- /assets/ico-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ico-512.png -------------------------------------------------------------------------------- /assets/login.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/login.webp -------------------------------------------------------------------------------- /assets/maticon.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/maticon.woff2 -------------------------------------------------------------------------------- /assets/noimg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/noimg.webp -------------------------------------------------------------------------------- /assets/ss-classi-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ss-classi-1.png -------------------------------------------------------------------------------- /assets/ss-classi-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ss-classi-2.png -------------------------------------------------------------------------------- /assets/ss-classi-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ss-classi-3.png -------------------------------------------------------------------------------- /assets/ss-classi-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ss-classi-4.png -------------------------------------------------------------------------------- /assets/ss-classi-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ss-classi-5.png -------------------------------------------------------------------------------- /assets/ss-classi-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-boxx/ClassiPHPied/64466b4963b690137129b474be175196dd8b9ad0/assets/ss-classi-6.png -------------------------------------------------------------------------------- /assets/tinymce/langs/README.md: -------------------------------------------------------------------------------- 1 | This is where language files should be placed. 2 | 3 | Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ 4 | -------------------------------------------------------------------------------- /assets/tinymce/license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/tinymce/plugins/advlist/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);var o=tinymce.util.Tools.resolve("tinymce.util.Tools");class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=t=>e=>i(e)&&t.test(e.nodeName),d=u(/^(OL|UL|DL)$/),g=u(/^(TH|TD)$/),h=t=>l(t)||"default"===t?"":t,c=(t,e)=>s=>{const r=r=>{s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;ee.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r.parents,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)})(t,r.element))};return t.on("NodeChange",r),()=>t.off("NodeChange",r)},m=(t,s,r,n,l,i)=>{i.length>1?((t,s,r,n,l,i)=>{t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(o.map(i,(t=>{const e="OL"===l?"num":"bull",s="disc"===t||"decimal"===t?"default":t,r=h(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return a.from(s)})(t);return s.map((t=>e===t)).getOr(!1)},onSetup:c(t,l)})})(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:c(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,h(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{m(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),m(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the Advanced List plugin.")}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/anchor/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=("allow_html_in_named_anchor",e=>e.options.get("allow_html_in_named_anchor"));const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/autolink/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e));const l=(void 0,e=>undefined===e);const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]"))return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),h=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),w=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),h);if(!w)return null;let v=w.container;const _=k.backwards(w.container,w.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),h),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(w.container,w.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=$.length&&b.substr(0,0+$.length)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/autoresize/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),s=o("min_height"),i=o("max_height"),n=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),l=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},g=(e,t,o,s)=>{var i;const n=parseInt(null!==(i=e.getStyle(t,o,s))&&void 0!==i?i:"",10);return isNaN(n)?0:n},a=(e,o,r,c)=>{var d;const f=e.dom,u=e.getDoc();if(!u)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void l(e,!0);const m=u.documentElement,h=c?c():n(e),p=null!==(d=s(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=g(f,m,"margin-top",!0),v=g(f,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+h;C<0&&(C=0);const b=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+b>p&&(y=C+b);const w=i(e);if(w&&y>w?(y=w,l(e,!0)):l(e,!1),y!==o.get()){const s=y-o.get();if(f.setStyle(e.getContainer(),"height",y+"px"),o.set(y),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&s<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(e=>{let t=0;return{get:()=>t,set:e=>{t=e}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{let s,i,l=()=>r(e);e.on("init",(i=>{s=0;const r=n(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,i,l),s+=1})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{if(1===s)i=e.getContainer().offsetHeight,a(e,o,t,l),s+=1;else if(2===s){const t=i0):l,s+=1}else a(e,o,t,l)}))})(e,o)}}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/autosave/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=("string",t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t));const r=(void 0,t=>undefined===t);var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},g=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},y=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{e.setEnabled(f(t));const r=()=>e.setEnabled(f(t));return t.on("StoreDraft RestoreDraft RemoveDraft",r),()=>t.off("StoreDraft RestoreDraft RemoveDraft",r)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{g(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{y(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&y(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>g(t),restoreDraft:()=>y(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/code/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/directionality/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=(!1,()=>false);class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(9),p=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},w=i(Element.prototype.attachShadow)&&i(Node.prototype.getRootNode)?t=>d(t.dom.getRootNode()):t=>v(t)?t:d(t.dom.ownerDocument),N=t=>d(t.dom.host),b=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=w(t);return p(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=b,i=N,t=>r(i(t))));var r,i},S=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||b(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",A=(t,e)=>((t,o)=>((t,e)=>{const o=[];for(let r=0,n=t.length;r{const o=t.length,r=new Array(o);for(let n=0;nh(t,e))))(t),T=("li",t=>g(t)&&"li"===t.dom.nodeName.toLowerCase());const C=(t,e)=>{const n=t.selection.getSelectedBlocks();n.length>0&&(u(n,(t=>{const n=d(t),c=T(n),m=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(n,c);var f;(f=m,(t=>a.from(t.dom.parentNode).map(d))(f).filter(g)).each((t=>{if(S(t)!==e?((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(m,"dir",e):S(m)!==e&&y(m,"dir"),c){const t=A(m,"li[dir]");u(t,(t=>y(t,"dir")))}}))})),t.nodeChanged())},D=(t,e)=>o=>{const r=t=>{const r=d(t.element);o.setActive(S(r)===e)};return t.on("NodeChange",r),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{C(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{C(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:D(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:D(t,"rtl")})})(t)}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/emoticons/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>t===e,o=e(null),n=e(void 0),s=()=>{},r=()=>!1;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return null==t?a.none():a.some(t)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const i=(t,e)=>{const o=t.length,n=new Array(o);for(let s=0;s{let e=t;return{get:()=>e,set:t=>{e=t}}},c=Object.keys,u=Object.hasOwnProperty,g=(t,e)=>{const o=c(t);for(let n=0,s=o.length;nu.call(t,e),h=(d=(t,e)=>e,(...t)=>{if(0===t.length)throw new Error("Can't merge zero objects");const e={};for(let o=0;o{const t=(t=>{const e=l(a.none()),o=()=>e.get().each(t);return{clear:()=>{o(),e.set(a.none())},isSet:()=>e.get().isSome(),get:()=>e.get(),set:t=>{o(),e.set(a.some(t))}}})(s);return{...t,on:e=>t.get().each(e)}},v=(t,e,o=0,s)=>{const r=t.indexOf(e,o);return-1!==r&&(!!n(s)||r+e.length<=s)};var y=tinymce.util.Tools.resolve("tinymce.Resource");const f=t=>e=>e.options.get(t),b=f("emoticons_database"),w=f("emoticons_database_url"),_=f("emoticons_database_id"),j=f("emoticons_append"),C=f("emoticons_images_url"),k="All",A={symbols:"Symbols",people:"People",animals_and_nature:"Animals and Nature",food_and_drink:"Food and Drink",activity:"Activity",travel_and_places:"Travel and Places",objects:"Objects",flags:"Flags",user:"User Defined"},O=(t,e)=>m(t,e)?t[e]:e,x=t=>{const e=j(t);return o=t=>({keywords:[],category:"user",...t}),((t,e)=>{const o={};return g(t,((t,n)=>{const s=e(t,n);o[s.k]=s.v})),o})(e,((t,e)=>({k:e,v:o(t)})));var o},L=(t,e)=>v(t.title.toLowerCase(),e)||((t,o)=>{for(let o=0,s=t.length;o{const n=[],s=e.toLowerCase(),a=o.fold((()=>r),(t=>e=>e>=t));for(let o=0;o{const n={pattern:"",results:T(e.listAll(),"",a.some(300))},s=l(k),r=((t,e)=>{let n=null;const s=()=>{o(n)||(clearTimeout(n),n=null)};return{cancel:s,throttle:(...e)=>{s(),n=setTimeout((()=>{n=null,t.apply(null,e)}),200)}}})((t=>{(t=>{const o=t.getData(),n=s.get(),r=e.listCategory(n),i=T(r,o.pattern,n===k?a.some(300):a.none());t.setData({results:i})})(t)})),c={label:"Search",type:"input",name:D},u={type:"collection",name:"results"},g=()=>({title:"Emojis",size:"normal",body:{type:"tabpanel",tabs:i(e.listCategories(),(t=>({title:t,name:t,items:[c,u]})))},initialData:n,onTabChange:(t,e)=>{s.set(e.newTabName),r.throttle(t)},onChange:r.throttle,onAction:(e,o)=>{"results"===o.name&&(((t,e)=>{t.insertContent(e)})(t,o.value),e.close())},buttons:[{type:"cancel",text:"Close",primary:!0}]}),m=t.windowManager.open(g());m.focus(D),e.hasLoaded()||(m.block("Loading emojis..."),e.waitForLoad().then((()=>{m.redial(g()),r.throttle(m),m.focus(D),m.unblock()})).catch((t=>{m.redial({title:"Emojis",body:{type:"panel",items:[{type:"alertbanner",level:"error",icon:"warning",text:"Could not load emojis"}]},buttons:[{type:"cancel",text:"Close",primary:!0}],initialData:{pattern:"",results:[]}}),m.focus(D),m.unblock()})))};t.add("emoticons",((t,e)=>{((t,e)=>{const o=t.options.register;o("emoticons_database",{processor:"string",default:"emojis"}),o("emoticons_database_url",{processor:"string",default:`${e}/js/${b(t)}${t.suffix}.js`}),o("emoticons_database_id",{processor:"string",default:"tinymce.plugins.emoticons"}),o("emoticons_append",{processor:"object",default:{}}),o("emoticons_images_url",{processor:"string",default:"https://twemoji.maxcdn.com/v/13.0.1/72x72/"})})(t,e);const o=((t,e,o)=>{const n=p(),s=p(),r=C(t),i=t=>{return o="=o.length&&e.substr(0,0+o.length)===o?t.char.replace(/src="([^"]+)"/,((t,e)=>`src="${r}${e}"`)):t.char;var e,o};t.on("init",(()=>{y.load(o,e).then((e=>{const o=x(t);(t=>{const e={},o=[];g(t,((t,n)=>{const s={title:n,keywords:t.keywords,char:i(t),category:O(A,t.category)},r=void 0!==e[s.category]?e[s.category]:[];e[s.category]=r.concat([s]),o.push(s)})),n.set(e),s.set(o)})(h(e,o))}),(t=>{console.log(`Failed to load emojis: ${t}`),n.set({}),s.set([])}))}));const l=()=>s.get().getOr([]),u=()=>n.isSet()&&s.isSet();return{listCategories:()=>[k].concat(c(n.get().getOr({}))),hasLoaded:u,waitForLoad:()=>u()?Promise.resolve(!0):new Promise(((t,o)=>{let n=15;const s=setInterval((()=>{u()?(clearInterval(s),t(!0)):(n--,n<0&&(console.log("Could not load emojis from url: "+e),clearInterval(s),o(!1)))}),100)})),listAll:l,listCategory:t=>t===k?l():n.get().bind((e=>a.from(e[t]))).getOr([])}})(t,w(t),_(t));((t,e)=>{t.addCommand("mceEmoticons",(()=>E(t,e)))})(t,o),(t=>{const e=()=>t.execCommand("mceEmoticons");t.ui.registry.addButton("emoticons",{tooltip:"Emojis",icon:"emoji",onAction:e}),t.ui.registry.addMenuItem("emoticons",{text:"Emojis...",icon:"emoji",onAction:e})})(t),((t,e)=>{t.ui.registry.addAutocompleter("emoticons",{trigger:":",columns:"auto",minChars:2,fetch:(t,o)=>e.waitForLoad().then((()=>{const n=e.listAll();return T(n,t,a.some(o))})),onAction:(e,o,n)=>{t.selection.setRng(o),t.insertContent(n),e.hide()}})})(t,o),(t=>{t.on("PreInit",(()=>{t.parser.addAttributeFilter("data-emoticon",(t=>{((t,e)=>{for(let e=0,n=t.length;et=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=("function",e=>"function"==typeof e);var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),_=p("importcss_file_filter"),g=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),w=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s{const s=e.length,r=new Array(s);for(let o=0;oa.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=g(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/";return t===o+"/content"+(e.inline?".inline":"")+".min.css"||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(_(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),w(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/insertdatetime/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),r=t("insertdatetime_timeformat"),n=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)){const a=d(e,t);let r;r=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const n=e.dom.getParent(e.selection.getStart(),"time");n?((e,t,a,r)=>{const n=e.dom.create("time",{datetime:a},r);e.dom.replace(n,t),e.selection.select(n,!0),e.selection.collapse(!1)})(e,n,r,a):e.insertContent('")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,r)=>{u(e,null!=r?r:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:r(e))}))})(e),(e=>{const t=n(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=n(e);return t.length>0?t[0]:r(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)}});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)})))})})(e)}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/nonbreaking/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=n=>e=>typeof e===n,a=e("boolean"),o=e("number"),t=n=>e=>e.options.get(n),i=t("nonbreaking_force_tab"),r=t("nonbreaking_wrap"),s=(n,e)=>{let a="";for(let o=0;o{const a=r(n)||n.plugins.visualchars?`${s(" ",e)}`:s(" ",e);n.undoManager.transact((()=>n.insertContent(a)))};var l=tinymce.util.Tools.resolve("tinymce.util.VK");n.add("nonbreaking",(n=>{(n=>{const e=n.options.register;e("nonbreaking_force_tab",{processor:n=>a(n)?{value:n?3:0,valid:!0}:o(n)?{value:n,valid:!0}:{valid:!1,message:"Must be a boolean or number."},default:!1}),e("nonbreaking_wrap",{processor:"boolean",default:!0})})(n),(n=>{n.addCommand("mceNonBreaking",(()=>{c(n,1)}))})(n),(n=>{const e=()=>n.execCommand("mceNonBreaking");n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:e}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:e})})(n),(n=>{const e=i(n);e>0&&n.on("keydown",(a=>{if(a.keyCode===l.TAB&&!a.isDefaultPrevented()){if(a.shiftKey)return;a.preventDefault(),a.stopImmediatePropagation(),c(n,e)}}))})(n)}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/pagebreak/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env");const t=e=>a=>a.options.get(e),r=t("pagebreak_separator"),n=t("pagebreak_split_block"),o="mce-pagebreak",s=e=>{const t=``;return e?`

${t}

`:t};e.add("pagebreak",(e=>{(e=>{const a=e.options.register;a("pagebreak_separator",{processor:"string",default:"\x3c!-- pagebreak --\x3e"}),a("pagebreak_split_block",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mcePageBreak",(()=>{e.insertContent(s(n(e)))}))})(e),(e=>{const a=()=>e.execCommand("mcePageBreak");e.ui.registry.addButton("pagebreak",{icon:"page-break",tooltip:"Page break",onAction:a}),e.ui.registry.addMenuItem("pagebreak",{text:"Page break",icon:"page-break",onAction:a})})(e),(e=>{const a=r(e),t=()=>n(e),c=new RegExp(a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,(e=>"\\"+e)),"gi");e.on("BeforeSetContent",(e=>{e.content=e.content.replace(c,s(t()))})),e.on("PreInit",(()=>{e.serializer.addNodeFilter("img",(r=>{let n,s,c=r.length;for(;c--;)if(n=r[c],s=n.attr("class"),s&&-1!==s.indexOf(o)){const r=n.parent;if(r&&e.schema.getBlockElements()[r.name]&&t()){r.type=3,r.value=a,r.raw=!0,n.remove();continue}n.type=3,n.value=a,n.raw=!0}}))}))})(e),(e=>{e.on("ResolveName",(a=>{"IMG"===a.target.nodeName&&e.dom.hasClass(a.target,o)&&(a.name="pagebreak")}))})(e)}))}(); -------------------------------------------------------------------------------- /assets/tinymce/plugins/preview/plugin.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TinyMCE version 6.4.1 (2023-03-29) 3 | */ 4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>t=>t.options.get(e),i=n("content_style"),s=n("content_css_cors"),c=n("body_class"),r=n("body_id");e.add("preview",(e=>{(e=>{e.addCommand("mcePreview",(()=>{(e=>{const n=(e=>{var n;let l="";const a=e.dom.encode,d=null!==(n=i(e))&&void 0!==n?n:"";l+='';const m=s(e)?' crossorigin="anonymous"':"";o.each(e.contentCSS,(t=>{l+='"})),d&&(l+='");const y=r(e),u=c(e),v='