Files
Shaarli_bm_theme/shaarli-pro/dist/custom_views.min.js
T
bruno f753b27542
CI / build (push) Failing after 6m2s
Add asset pipeline and professionalize theme
Introduce a Node build system for minified CSS/JS with content hashes,
add PWA support, i18n helpers, accessibility improvements, and more
translatable strings. Move theme configuration from bookmarks to
localStorage, add Playwright tests, and set up CI workflows.
2026-08-09 09:25:03 -04:00

1 line
141 KiB
JavaScript

function renderMarkdown(t){return"undefined"!=typeof window&&"function"==typeof window.renderMarkdown?window.renderMarkdown(t):String(t||"").replace(/\n/g,"<br>")}function applyKeepNoteFormatting(t,e){if("undefined"!=typeof window&&"function"==typeof window.applyKeepNoteFormatting)return window.applyKeepNoteFormatting(t,e)}document.addEventListener("DOMContentLoaded",function(){const t=new URLSearchParams(window.location.search),e=t.get("searchtags")||t.get("searchTags")||"",o=window.location.pathname.match(/\/tag\/(.+)$/),n=(e+" "+(o?decodeURIComponent(o[1]):"")).toLowerCase().split(/[\s,]+/).filter(t=>t),a=!!document.querySelector('.sidebar-link[aria-label="Notes"].active, .header-nav-link[aria-label="Notes"].active, .sidebar-link[href*="searchtags=note"].active, .sidebar-link[href*="searchtags=shaarli-note"].active')||!!document.querySelector('.sidebar-link[aria-label="'+window.ShaarliProI18n.t("Notes")+'"].active, .header-nav-link[aria-label="'+window.ShaarliProI18n.t("Notes")+'"].active'),r=!!document.querySelector('.sidebar-link[aria-label="Mes tâches"].active, .header-nav-link[aria-label="Mes tâches"].active, .sidebar-link[href*="searchtags=shaarli-todo"].active, .sidebar-link[href*="searchtags=todo"].active')||!!document.querySelector('.sidebar-link[aria-label="'+window.ShaarliProI18n.t("My tasks")+'"].active, .header-nav-link[aria-label="'+window.ShaarliProI18n.t("My tasks")+'"].active'),i=!!document.querySelector('.sidebar-link[aria-label="Archive"].active, .header-nav-link[aria-label="Archive"].active, .sidebar-link[href*="searchtags=shaarli-archive"].active, .sidebar-link[href*="searchtags=shaarli-archiver"].active')||!!document.querySelector('.sidebar-link[aria-label="'+window.ShaarliProI18n.t("Archive")+'"].active, .header-nav-link[aria-label="'+window.ShaarliProI18n.t("Archive")+'"].active'),l=Array.from(document.querySelectorAll(".search-tag-chip")).map(t=>(t.textContent||"").trim().toLowerCase()),s=t=>"shaarli-archive"===t||"shaarli-archiver"===t,d=t=>"note"===t||"shaarli-note"===t||"#note"===t,c=t=>"todo"===t||"shaarli-todo"===t||"#todo"===t,u=n.some(d)||a||l.some(d),m=n.some(c)||r||l.some(c),p=n.some(s)||i||l.some(s),f=document.getElementById("links-list"),g=document.querySelector(".content-container"),h=()=>{try{document.body.classList.remove("view-todo","view-notes","view-archive")}catch(t){}const t=document.querySelector(".content-toolbar");t&&(t.style.display="");const e=document.getElementById("links-list");e&&(e.style.display=""),document.querySelectorAll(".notes-wrapper.todo-wrapper").forEach(t=>t.remove())};window.renderMarkdown=function(t){if(!t)return"";const e=String(t).replace(/\r\n?/g,"\n"),o=t=>String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),n=t=>String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),a=t=>{const e=String(t||"").trim();return e&&/^(https?:|mailto:|\/)/i.test(e)?e:""},r=t=>{let e=o(t||"");const r=[];return e=e.replace(/`([^`\n]+)`/g,(t,e)=>{const o=`__MD_CODE_${r.length}__`;return r.push(`<code>${e}</code>`),o}),e=e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(t,e,o)=>{const r=a(o);return r?`<img src="${n(r)}" alt="${n(e)}" loading="lazy" />`:t}),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(t,e,o)=>{const r=a(o);return r?`<a href="${n(r)}" target="_blank" rel="noopener noreferrer">${e}</a>`:t}),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/__(.+?)__/g,"<strong>$1</strong>"),e=e.replace(/~~(.+?)~~/g,"<del>$1</del>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/_(.+?)_/g,"<em>$1</em>"),e=e.replace(/&lt;u&gt;([\s\S]*?)&lt;\/u&gt;/g,"<u>$1</u>"),e=e.replace(/__MD_CODE_(\d+)__/g,(t,e)=>r[Number(e)]||""),e},i=e.split("\n"),l=[];let s=!1,d=!1,c=!1,u=!1,m="",p=[];const f=()=>{s&&(l.push("</ul>"),s=!1),d&&(l.push("</ol>"),d=!1),c&&(l.push("</ul>"),c=!1)};if(i.forEach(t=>{const e=t.trim(),a=e.match(/^```\s*([\w-]+)?\s*$/);if(a){if(f(),u){const t=m?` data-lang="${n(m)}"`:"";l.push(`<pre class="md-code-block"><code${t}>${o(p.join("\n"))}</code></pre>`),u=!1,m="",p=[]}else u=!0,m=a[1]||"",p=[];return}if(u)return void p.push(t);if(!e)return f(),void l.push('<div class="md-spacer"></div>');const i=t.match(/^\s*(#{1,6})\s+(.+)$/);if(i){f();const t=i[1].length;return void l.push(`<h${t}>${r(i[2])}</h${t}>`)}const g=t.match(/^\s*>\s?(.*)$/);if(g)return f(),void l.push(`<blockquote>${r(g[1])}</blockquote>`);const h=t.match(/^\s*[-*]\s+\[( |x|X)\]\s+(.+)$/);if(h){s&&(l.push("</ul>"),s=!1),d&&(l.push("</ol>"),d=!1),c||(l.push('<ul class="md-todo-list">'),c=!0);const t="x"===String(h[1]).toLowerCase();return void l.push(`<li class="md-todo-item${t?" is-checked":""}"><span class="md-todo-box" aria-hidden="true"><i class="mdi mdi-check"></i></span><span class="md-todo-text">${r(h[2])}</span></li>`)}const y=t.match(/^\s*\d+\.\s+(.+)$/);if(y)return s&&(l.push("</ul>"),s=!1),c&&(l.push("</ul>"),c=!1),d||(l.push("<ol>"),d=!0),void l.push(`<li>${r(y[1])}</li>`);const b=t.match(/^\s*[-*+]\s+(.+)$/);if(b)return d&&(l.push("</ol>"),d=!1),c&&(l.push("</ul>"),c=!1),s||(l.push("<ul>"),s=!0),void l.push(`<li>${r(b[1])}</li>`);f(),l.push(`<p>${r(t)}</p>`)}),u){const t=m?` data-lang="${n(m)}"`:"";l.push(`<pre class="md-code-block"><code${t}>${o(p.join("\n"))}</code></pre>`)}return f(),l.join("")},window.applyKeepNoteFormatting=function(t,e){if(!t||!e)return;const o=t.selectionStart||0,n=t.selectionEnd||0,a=String(t.value||""),r=a.slice(o,n),i=(e,o,n,r="end")=>{const i=a.slice(0,e)+n+a.slice(o);if(t.value=i,t.focus({preventScroll:!0}),"select"===r)t.setSelectionRange(e,e+n.length);else{const o=e+n.length;t.setSelectionRange(o,o)}},l=(e,i)=>{const l=r||"",s=`${e}${l}${i}`,d=a.slice(0,o)+s+a.slice(n);t.value=d;const c=o+e.length,u=c+l.length;t.focus({preventScroll:!0}),t.setSelectionRange(c,u)},s=e=>{const{lineStart:r,lineEnd:i}=(()=>{const t=a.slice(0,o),e=a.slice(n),r=t.lastIndexOf("\n")+1,i=e.indexOf("\n");return{lineStart:r,lineEnd:-1===i?a.length:n+i}})(),l=a.slice(r,i).split(/\r?\n/).map(e).join("\n"),s=a.slice(0,r)+l+a.slice(i);t.value=s,t.focus({preventScroll:!0}),t.setSelectionRange(r,r+l.length)};if("bold"===e)return l("**","**");if("italic"===e)return l("*","*");if("underline"===e)return l("<u>","</u>");if("strike"===e)return l("~~","~~");if("code"===e)return l("`","`");if("link"===e){const e=`[${r||"Texte du lien"}](https://)`;i(o,n,e);const a=o+e.length-1;return void t.setSelectionRange(a,a)}if("image"===e){const e=`![${r||"Description image"}](https://)`;i(o,n,e);const a=o+e.length-1;return void t.setSelectionRange(a,a)}if("quote"===e)return s(t=>t.startsWith("> ")?t:`> ${t}`);if("ul"===e)return s(t=>{const e=t.trim();return e?/^[-*+]\s+/.test(e)?t:`- ${e}`:"- "});if("ol"===e)return s((t,e)=>{const o=t.trim();return o?/^\d+\.\s+/.test(o)?t:`${e+1}. ${o}`:`${e+1}. `});if("todo"===e)return s(t=>{const e=t.trim();return e?/^[-*]\s+\[( |x|X)\]\s+/.test(e)?t:`- [ ] ${e}`:"- [ ] "});if("codeblock"===e){return void i(o,n,`\n\`\`\`\n${r||"code"}\n\`\`\`\n`,"select")}if("h1"===e||"h2"===e||"h3"===e||"p"===e){const t="h1"===e?"# ":"h2"===e?"## ":"h3"===e?"### ":"";return s(e=>{const o=e.replace(/^\s*(#{1,6}\s+)/,"");return t?t+o:o})}if("clear"===e){if(!r)return s(t=>t.replace(/^\s*(#{1,6}\s+)/,"").replace(/^\s*>\s?/,"").replace(/^\s*[-*+]\s+\[( |x|X)\]\s+/,"").replace(/^\s*[-*+]\s+/,"").replace(/^\s*\d+\.\s+/,"").replace(/\*\*(.*?)\*\*/g,"$1").replace(/__(.*?)__/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1"));const t=r.replace(/\*\*(.*?)\*\*/g,"$1").replace(/__(.*?)__/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1");i(o,n,t)}};const y=function(){if("function"==typeof initBookmarkPaletteButtons&&initBookmarkPaletteButtons(),"function"==typeof organizePinnedBookmarks&&window.requestAnimationFrame(organizePinnedBookmarks),"function"==typeof initPinnedItems&&initPinnedItems(),f&&g)if(m)try{initTodoView(f,g)}catch(t){console.error("[custom_views] Erreur lors de l'initialisation de la vue Todo:",t),h()}else if(u)try{initNoteView(f,g),"function"==typeof initTagDisplayAndRemoval&&initTagDisplayAndRemoval()}catch(t){console.error("[custom_views] Erreur lors de l'initialisation de la vue Note:",t),h()}else if(p)try{initArchiveView(f,g),"function"==typeof initTagDisplayAndRemoval&&initTagDisplayAndRemoval()}catch(t){console.error("[custom_views] Erreur lors de l'initialisation de la vue Archive:",t),h()}else"function"==typeof initTagDisplayAndRemoval&&initTagDisplayAndRemoval()};initThemeModeBackgroundSync(),"function"==typeof loadBackgroundOptions?loadBackgroundOptions().then(()=>{y()}).catch(t=>{console.error("Erreur lors du chargement des backgrounds:",t),y()}):y()});const NOTE_COLOR_OPTIONS=[{key:"default",label:window.ShaarliProI18n.t("Default"),light:"#f8fafc",dark:"#20293A"},{key:"red",label:window.ShaarliProI18n.t("Red"),light:"#f28b82",dark:"#9c2116"},{key:"orange",label:window.ShaarliProI18n.t("Orange"),light:"#fbbc04",dark:"#9c7a16"},{key:"yellow",label:window.ShaarliProI18n.t("Yellow"),light:"#fff475",dark:"#9c9116"},{key:"green",label:window.ShaarliProI18n.t("Green"),light:"#ccff90",dark:"#5e9c16"},{key:"teal",label:window.ShaarliProI18n.t("Mint"),light:"#a7ffeb",dark:"#169c7d"},{key:"blue",label:window.ShaarliProI18n.t("Light blue"),light:"#cbf0f8",dark:"#16849c"},{key:"darkblue",label:window.ShaarliProI18n.t("Blue"),light:"#aecbfa",dark:"#16499c"},{key:"purple",label:window.ShaarliProI18n.t("Purple"),light:"#d7aefb",dark:"#5d169c"},{key:"pink",label:window.ShaarliProI18n.t("Pink"),light:"#fdcfe8",dark:"#9c165f"},{key:"brown",label:window.ShaarliProI18n.t("Beige"),light:"#e6c9a8",dark:"#9c5d16"},{key:"grey",label:window.ShaarliProI18n.t("Gray"),light:"#e8eaed",dark:"#4e5764"},{key:"custom",label:window.ShaarliProI18n.t("Custom"),light:"#custom",dark:"#custom"}],NOTE_FILTER_OPTIONS=[{key:"none",label:window.ShaarliProI18n.t("None"),icon:"mdi-close-circle-outline"},{key:"glass",label:window.ShaarliProI18n.t("Glass"),icon:"mdi-blur"},{key:"vignette",label:window.ShaarliProI18n.t("Vignette"),icon:"mdi-vignette"},{key:"lined",label:window.ShaarliProI18n.t("Lined"),icon:"mdi-format-align-justify"},{key:"grid",label:window.ShaarliProI18n.t("Grid"),icon:"mdi-grid"},{key:"noise",label:window.ShaarliProI18n.t("Noise"),icon:"mdi-grain"},{key:"dots",label:window.ShaarliProI18n.t("Dots"),icon:"mdi-dots-grid"},{key:"stripes",label:window.ShaarliProI18n.t("Stripes"),icon:"mdi-slash-forward"}],NOTE_FONT_COLOR_OPTIONS=[{key:"auto",label:window.ShaarliProI18n.t("Auto"),value:"auto"},{key:"light",label:window.ShaarliProI18n.t("Light"),value:"#f5f7fb"},{key:"dark",label:window.ShaarliProI18n.t("Dark"),value:"#202124"},{key:"white",label:window.ShaarliProI18n.t("White"),value:"#ffffff"},{key:"black",label:window.ShaarliProI18n.t("Black"),value:"#000000"},{key:"custom",label:window.ShaarliProI18n.t("Custom"),value:"custom"}],NOTE_FONT_COLOR_TAG_PREFIX="font-",NOTE_COLOR_TAG_PREFIX="note-color-",NOTE_FILTER_TAG_PREFIX="notefilter-",NOTE_BACKGROUND_TAG_PREFIX="notebg-";function isTechnicalTag(t){if("string"!=typeof t)return!1;const e=t.trim().toLowerCase();if(!e)return!1;if("note"===e||"#note"===e)return!0;if("shaarli-note"===e)return!0;if("todo"===e||"#todo"===e)return!0;if("shaarli-todo"===e)return!0;if("shaarli-pin"===e)return!0;if("brain-dump"===e)return!0;if(e.startsWith("font-"))return!0;if(e.startsWith("note-color-"))return!0;if(e.startsWith("notefilter-"))return!0;if(e.startsWith("notebg-"))return!0;if(e.startsWith("notefilter-"))return!0;if(e.startsWith("notebg-"))return!0;if(e.startsWith("note-color-"))return!0;if(e.startsWith("note-")){const t=e.substring(5);if(NOTE_COLOR_OPTIONS.some(e=>e.key===t))return!0}return!1}function createTagPill({tag:t,onRemoveClass:e="tag-remove-btn",tagClass:o="tag-pill"}){const n=document.createElement("span");n.className=o,n.dataset.tag=t;const a=document.createElement("span");a.className=`${o}-text`,a.textContent=t,n.appendChild(a);if(!(!arguments[0]||!Object.prototype.hasOwnProperty.call(arguments[0],"canRemove")||!!arguments[0].canRemove))return n;const r=document.createElement("button");return r.type="button",r.className=e,r.dataset.tag=t,r.setAttribute("aria-label",`Supprimer le tag ${t}`),r.title=window.ShaarliProI18n.t("Delete"),r.innerHTML="&times;",n.appendChild(r),n}function removeTagFromEntity(t,e){return fetch(t).then(t=>t.text()).then(t=>{const o=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!o)throw new Error("Could not find edit form");const n=new URLSearchParams;o.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&n.append(t.name,t.value||"on"):t.name&&n.append(t.name,getFormFieldValue(t))});let a=(n.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());return a=a.filter(t=>t!==e),n.set("lf_tags",a.join(" ")),n.append("save_edit","1"),fetch(o.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to update tags");return t})}function deleteEntitySilently(t){return t&&"#"!==t?fetch(t).then(t=>{if(!t.ok)throw new Error("Delete request failed");return t}):Promise.reject("Invalid delete URL")}let tagDisplayRemovalInitialized=!1;function initTagDisplayAndRemoval(){tagDisplayRemovalInitialized||(document.querySelectorAll(".link-tag-list .link-tag").forEach(t=>{const e=(t.dataset.tag||t.textContent||"").trim();e&&("shaarli-pin"!==e?isTechnicalTag(e)&&t.classList.add("is-tech-tag"):t.classList.add("is-tech-tag"))}),document.addEventListener("click",function(t){const e=t.target.closest(".tag-remove-btn, .note-tag-remove-btn");if(!e)return;t.preventDefault(),t.stopPropagation();const o=(e.dataset.tag||"").trim();if(!o)return;const n=e.closest(".link-tag, .note-tag"),a=e.closest(".link-outer, .note-card, .note-modal");let r="";if(a&&a.classList.contains("note-card"))r=a.dataset.editUrl||"";else if(a&&a.classList.contains("note-modal"))r=a.dataset.editUrl||"";else{const t=a?a.querySelector(".link-actions"):null,e=t?t.querySelector('a[href*="admin/shaare"]'):null;r=e?e.href:""}r&&removeTagFromEntity(r,o).then(()=>{if(n&&n.remove(),a&&a.classList.contains("note-card")){let t=(a.dataset.tags||"").split("||").filter(t=>t);t=t.filter(t=>t!==o),a.dataset.tags=t.join("||");const e=getOpenModalOverlay(),n=getModalCurrentEntity(e);if(e&&n&&String(n.id)===String(a.dataset.id)){n.tags=(n.tags||[]).filter(t=>t!==o);renderModalTags(e.querySelector(".note-modal-tags"),n.tags)}}if(a&&a.classList.contains("note-modal")){let t=(a.dataset.tags||"").split("||").filter(t=>t);t=t.filter(t=>t!==o),a.dataset.tags=t.join("||");const e=getOpenModalOverlay(),n=getModalCurrentEntity(e);if(e&&n){n.tags=(n.tags||[]).filter(t=>t!==o);renderModalTags(e.querySelector(".note-modal-tags"),n.tags)}const r=a.dataset.noteId||a.dataset.todoId||(n&&n.id?String(n.id):""),i=r?document.querySelector(`.note-card[data-id="${r}"]`):null;if(i){const t=i.querySelector(`.note-tag[data-tag="${CSS.escape(o)}"]`);t&&t.remove();let e=(i.dataset.tags||"").split("||").filter(t=>t);e=e.filter(t=>t!==o),i.dataset.tags=e.join("||")}}}).catch(t=>{console.error("Error removing tag:",t),alert(window.ShaarliProI18n.t("Error removing tag."))})}),tagDisplayRemovalInitialized=!0)}function getOpenModalOverlay(){return document.querySelector(".note-modal-overlay.open")}function getModalCurrentEntity(t){return t&&(t.currentTodo||t.currentNote)||null}function resolveThemeAssetBasePath(){const t=Array.from(document.querySelectorAll('link[rel="stylesheet"]')).find(t=>t.href&&t.href.includes("/custom_views.css"));if(t&&t.href){const e=new URL(t.href,window.location.origin).pathname.replace(/\/css\/custom_views\.css$/,"");if(e)return e}const e=Array.from(document.querySelectorAll("script[src]")).find(t=>t.src&&t.src.includes("/custom_views.js"));if(e&&e.src){const t=new URL(e.src,window.location.origin).pathname.replace(/\/js\/custom_views\.js$/,"");if(t)return t}return window.shaarli&&"string"==typeof window.shaarli.assetPath&&""!==window.shaarli.assetPath.trim()?window.shaarli.assetPath.replace(/\/$/,""):"/tpl/shaarli-pro"}const NOTE_BACKGROUND_ASSET_ROOT=`${resolveThemeAssetBasePath().replace(/\/$/,"")}/img`;let NOTE_BACKGROUND_OPTIONS=[],isBackgroundOptionsLoaded=!1,backgroundOptionsLoadPromise=null;function organizePinnedBookmarks(){const t=document.getElementById("links-list");if(!t)return;const e=t.querySelector(".pinned-section-head"),o=t.querySelector(".normal-section-head"),n=t.querySelector(".compact-table-head");if(!e||!o||!n)return;const a=Array.from(t.getElementsByClassName("link-outer"));if(!a.length)return;const r=t=>{if(t.classList.contains("is-sticky")||t.classList.contains("is-pinned-tag"))return!0;const e=t.querySelectorAll(".link-tag-list a, .link-tag-list .link-tag-link, .note-tag");for(const t of e){if("shaarli-pin"===(t.textContent||"").trim().toLowerCase())return!0}return!1},i=a.filter(t=>r(t)),l=a.filter(t=>!r(t));t.classList.toggle("has-pinned",i.length>0),t.classList.toggle("has-normal",l.length>0);const s=document.createDocumentFragment();s.appendChild(e),i.forEach(t=>s.appendChild(t)),s.appendChild(o),s.appendChild(n),l.forEach(t=>s.appendChild(t)),t.replaceChildren(s)}function initPinnedBookmarksSeparation(){const t=document.getElementById("links-list");if(!t)return;organizePinnedBookmarks();["view-grid-btn","view-list-btn","view-compact-btn"].forEach(t=>{const e=document.getElementById(t);e&&e.addEventListener("click",()=>{window.requestAnimationFrame(organizePinnedBookmarks)})}),t.addEventListener("click",t=>{t.target.closest('a[href*="/pin?token="]')&&window.setTimeout(()=>{window.location.reload()},500)})}window.__shaarliCustomViewsVersion="1.0.5-inline-bg-manifest","undefined"!=typeof console&&console&&console.info,document.addEventListener("DOMContentLoaded",initPinnedBookmarksSeparation);const NOTE_BACKGROUND_MANIFEST_INLINE=[{key:"cafe",label:window.ShaarliProI18n.t("Coffee"),files:{light:"bg-light-cafe.jpg",dark:"bg-dark-cafe.jpg"}},{key:"codes",label:"Codes",files:{light:"bg-light-codes.jpg",dark:"bg-dark-codes.jpg"}},{key:"dune",label:"Dune",files:{light:"bg-light-dune.jpg",dark:"bg-dark-dune.jpg"}},{key:"feuille-ligne",label:"Feuille Ligne",files:{light:"bg-light-feuilleLigne.jpg",dark:"bg-dark-feuilleLigne.jpg"}},{key:"feuille-quadrillage",label:"Feuille Quadrillage",files:{light:"bg-light-feuilleQuadrille.jpg",dark:"bg-dark-feuilleQuadrille.jpg"}},{key:"fleurs",label:"Fleurs",files:{light:"bg-light-fleurs.jpg",dark:"bg-dark-fleurs.jpg"}},{key:"foret",label:window.ShaarliProI18n.t("Forest"),files:{light:"bg-light-foret.jpg",dark:"bg-dark-foret.jpg"}},{key:"grid",label:"Grid",files:{light:"bg-light-grid.jpg",dark:"bg-dark-grid.jpg"}},{key:"journal",label:"Journal",files:{light:"bg-light-journal.jpg",dark:"bg-dark-journal.jpg"}},{key:"lecture",label:"Lecture",files:{light:"bg-light-lecture.jpg",dark:"bg-dark-lecture.jpg"}},{key:"legumes",label:window.ShaarliProI18n.t("Vegetables"),files:{light:"bg-light-legumes.jpg",dark:"bg-dark-legumes.jpg"}},{key:"montagnes",label:"Montagnes",files:{light:"bg-light-montagnes.jpg",dark:"bg-dark-montagnes.jpg"}},{key:"ocean",label:window.ShaarliProI18n.t("Ocean"),files:{light:"bg-light-ocean.jpg",dark:"bg-dark-ocean.jpg"}},{key:"radio",label:"Radio",files:{light:"bg-light-radio.jpg",dark:"bg-dark-radio.jpg"}},{key:"sports",label:"Sports",files:{light:"bg-light-sports.jpg",dark:"bg-dark-sports.jpg"}},{key:"vague1",label:"Vague 1",files:{light:"bg-light-vague1.jpg",dark:"bg-dark-vague1.jpg"}},{key:"vague2",label:"Vague 2",files:{light:"bg-light-vague2.jpg",dark:"bg-dark-vague2.jpg"}},{key:"ville",label:"Ville",files:{light:"bg-light-ville.jpg",dark:"bg-dark-ville.jpg"}},{key:"voyage",label:"Voyage",files:{light:"bg-light-voyage.jpg",dark:"bg-dark-voyage.jpg"}}];function loadBackgroundOptions(){return isBackgroundOptionsLoaded?Promise.resolve(NOTE_BACKGROUND_OPTIONS):backgroundOptionsLoadPromise||(NOTE_BACKGROUND_OPTIONS=normalizeDynamicBackgroundOptions(NOTE_BACKGROUND_MANIFEST_INLINE),isBackgroundOptionsLoaded=!0,backgroundOptionsLoadPromise=Promise.resolve(NOTE_BACKGROUND_OPTIONS),backgroundOptionsLoadPromise)}function normalizeBackgroundKey(t){return"string"!=typeof t?"":t.trim().toLowerCase().replace(/[\s_]+/g,"-").replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function formatBackgroundLabel(t,e){return("string"==typeof t&&""!==t.trim()?t:e).replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/\s+/g," ").trim().split(" ").filter(t=>""!==t).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function getCurrentThemeMode(){return"dark"===document.documentElement.getAttribute("data-theme")?"dark":"light"}function getColorOption(t){const e="string"==typeof t?t.trim().toLowerCase():"";return NOTE_COLOR_OPTIONS.find(t=>t.key===e)||NOTE_COLOR_OPTIONS.find(t=>"default"===t.key)||null}function getThemeColorValue(t,e=getCurrentThemeMode()){if(!t||"object"!=typeof t)return"";const o="dark"===e?"dark":"light",n="string"==typeof t[o]?t[o].trim():"",a="string"==typeof t.light?t.light.trim():"",r="string"==typeof t.dark?t.dark.trim():"";return n||a||r}function parseHexColor(t){if("string"!=typeof t)return null;const e=t.trim(),o=/^#([0-9a-f]{3})$/i.exec(e);if(o)return{r:parseInt(o[1].charAt(0).repeat(2),16),g:parseInt(o[1].charAt(1).repeat(2),16),b:parseInt(o[1].charAt(2).repeat(2),16)};const n=/^#([0-9a-f]{6})$/i.exec(e);return n?{r:parseInt(n[1].slice(0,2),16),g:parseInt(n[1].slice(2,4),16),b:parseInt(n[1].slice(4,6),16)}:null}function getReadableForegroundForBackground(t,e=getCurrentThemeMode()){const o=parseHexColor(t);if(!o)return"dark"===e?"#e8eaed":"#202124";return(.299*o.r+.587*o.g+.114*o.b)/255>.56?"#202124":"#f5f7fb"}function normalizeDynamicBackgroundOptions(t){const e=Array.isArray(t)?t:t&&Array.isArray(t.backgrounds)?t.backgrounds:[],o={};return e.forEach(t=>{if(!t||"object"!=typeof t)return;const e=normalizeBackgroundKey("string"==typeof t.key?t.key:t.label||"");if(!e)return;const n=t.files&&"object"==typeof t.files?t.files:{},a="string"==typeof n.light?n.light.trim():"",r="string"==typeof n.dark?n.dark.trim():"";(a||r)&&(o[e]||(o[e]={key:e,label:formatBackgroundLabel(t.label||"",e),paths:{light:"",dark:""}}),a&&(o[e].paths.light=`note-bg-light/${a}`),r&&(o[e].paths.dark=`note-bg-dark/${r}`))}),Object.values(o).sort((t,e)=>t.label.localeCompare(e.label,"fr",{sensitivity:"base"}))}function getAvailableBackgroundOptionsForMode(t=getCurrentThemeMode()){const e="dark"===t?"dark":"light";return NOTE_BACKGROUND_OPTIONS.filter(t=>t.paths&&t.paths[e])}function getNoteBackgroundUrl(t,e=getCurrentThemeMode()){const o=normalizeBackgroundKey(t);if(!o)return"";const n=NOTE_BACKGROUND_OPTIONS.find(t=>t.key===o);if(!n||!n.paths)return"";const a="dark"===e?"dark":"light",r=n.paths[a]||"";return r?`${NOTE_BACKGROUND_ASSET_ROOT}/${r}`:""}function getElementVisualColor(t){if(!t)return"default";if("custom"===t.dataset.color&&t.dataset.customColor)return`custom:${t.dataset.customColor}`;const e=Array.from(t.classList).find(t=>t.startsWith("note-color-"));return e?e.replace("note-color-",""):t.dataset.color||"default"}function getElementVisualBackground(t){if(!t)return"none";return normalizeBackgroundKey(t.dataset.background||"")||"none"}function normalizeFilterKey(t){if("string"!=typeof t)return"none";const e=t.trim().toLowerCase();return NOTE_FILTER_OPTIONS.some(t=>t.key===e)?e:"none"}function getElementVisualFilter(t){return t?normalizeFilterKey(t.dataset.filter||""):"none"}function getElementVisualFontColor(t){return t&&t.dataset.fontColor||"auto"}function refreshNoteFilterVisuals(){document.querySelectorAll(".note-card, .note-modal, .link-outer, .note-input-container").forEach(t=>{applyNoteVisualState(t,{color:getElementVisualColor(t),filter:getElementVisualFilter(t),background:getElementVisualBackground(t),fontColor:getElementVisualFontColor(t)})})}function refreshBackgroundPalettes(){document.querySelectorAll(".note-card").forEach(t=>{const e=t.querySelector(".note-hover-actions .palette-popup");if(!e)return;const o=t.dataset.id||"";if(!o)return;const n=t.querySelector('.note-hover-actions a[href*="/admin/shaare/"], .note-hover-actions a[href*="do=editlink"], .note-hover-actions a[title="Edit"]');e.innerHTML=generatePaletteButtons({id:o,editUrl:n&&n.href?n.href:"#",color:getElementVisualColor(t),background:getElementVisualBackground(t)})}),document.querySelectorAll(".link-outer").forEach(t=>{const e=t.querySelector(".bookmark-palette .palette-popup");if(!e)return;const o=t.dataset.id||t.getAttribute("data-id")||t.id;if(!o)return;const n=t.querySelector(".link-actions"),a=n?n.querySelector('a[title=window.ShaarliProI18n.t("Edit")], a[aria-label="Modifier ce bookmark"], a[href*="/admin/shaare/"]'):null;e.innerHTML=generateBookmarkPaletteButtons(o,a&&a.href?a.href:"#",getElementVisualColor(t),getElementVisualBackground(t))});const t=getOpenModalOverlay(),e=getModalCurrentEntity(t);if(!t||!e)return;const o=t.querySelector(".note-modal");o&&(e.color=getElementVisualColor(o),e.background=getElementVisualBackground(o));const n=t.querySelector(".note-modal-palette");n&&(n.innerHTML=generateModalPaletteButtons(e))}function parseBackgroundManifestPayload(t){const e="string"==typeof t?t.trim():"";if(!e)return[];try{return JSON.parse(e)}catch(t){const o=e.indexOf("["),n=e.lastIndexOf("]");if(-1===o||-1===n||n<=o)throw t;const a=e.slice(o,n+1);return JSON.parse(a)}}let isThemeModeBackgroundSyncInitialized=!1;function initThemeModeBackgroundSync(){if(isThemeModeBackgroundSyncInitialized)return;const t=document.documentElement;if(!t)return;let e=getCurrentThemeMode();new MutationObserver(t=>{if(!t.some(t=>"data-theme"===t.attributeName))return;const o=getCurrentThemeMode();o!==e&&(e=o,refreshNoteFilterVisuals(),refreshBackgroundPalettes())}).observe(t,{attributes:!0,attributeFilter:["data-theme"]}),isThemeModeBackgroundSyncInitialized=!0}function positionPalettePopup(t){if(!t||!t.classList.contains("open"))return;t.classList.remove("open-down"),t.style.left="",t.style.right="";if(t.getBoundingClientRect().top<8){t.classList.add("open-down");t.getBoundingClientRect().bottom>window.innerHeight-8&&t.classList.remove("open-down")}let e=t.getBoundingClientRect();e.right>window.innerWidth-8&&(t.style.left="auto",t.style.right="0",e=t.getBoundingClientRect()),e.left<8&&(t.style.left="0",t.style.right="auto")}let backgroundStudioPanelInitialized=!1;function ensureBackgroundStudioPanel(){if(backgroundStudioPanelInitialized)return;if(document.getElementById("shaarli-bg-studio"))return void(backgroundStudioPanelInitialized=!0);const t=document.createElement("div");t.id="shaarli-bg-studio",t.className="bg-studio-panel",t.setAttribute("role","dialog"),t.setAttribute("aria-modal","false"),t.setAttribute("aria-hidden","true"),t.style.display="none",document.body.appendChild(t),t.addEventListener("click",t=>{const e=t.target.closest("button[data-bg-studio-action]");if(!e)return;const o=document.getElementById("shaarli-bg-studio");if(!o)return;const n=o.dataset.mode||"entity",a=o.dataset.entityId||"",r=o.dataset.editUrl||"",i=t=>{"function"==typeof o.__draftApply&&o.__draftApply(t)},l=e.dataset.bgStudioAction;if("close"!==l){if("set-color"===l){const t=e.dataset.colorKey||"default";return void("draft"===n?(o.dataset.color=t,i({color:t}),renderBackgroundStudioPanel(o)):"modal"===n?(setModalNoteColor(t),o.dataset.color=t,renderBackgroundStudioPanel(o)):(setNoteColor(a,t,r),o.dataset.color=t,renderBackgroundStudioPanel(o)))}if("set-background"===l){const t=e.dataset.bgKey||"none";return void("draft"===n?(o.dataset.background=t,i({background:t}),renderBackgroundStudioPanel(o)):"modal"===n?(setModalNoteBackground(t),o.dataset.background=t,renderBackgroundStudioPanel(o)):(setNoteBackground(a,t,r),o.dataset.background=t,renderBackgroundStudioPanel(o)))}if("set-filter"===l){const t=e.dataset.filter||"none",l=normalizeFilterKey(t||"")||"none";return void("draft"===n?(o.dataset.filter=l,i({filter:l}),renderBackgroundStudioPanel(o)):"modal"===n?(setModalNoteFilter(t),o.dataset.filter=l,renderBackgroundStudioPanel(o)):(setNoteFilter(a,t,r),o.dataset.filter=l,renderBackgroundStudioPanel(o)))}if("set-query"===l){o.dataset.query="",renderBackgroundStudioPanel(o);const t=o.querySelector(".bg-studio-search-input");return void(t&&t.focus())}if("set-defaults"!==l)if("reset-font-color"!==l)if("open-color-picker"!==l)if("open-font-color-picker"!==l){if("set-font-color"===l){const t=e.dataset.fontColorKey||"auto";return void("draft"===n?(o.dataset.fontColor=t,i({fontColor:t}),renderBackgroundStudioPanel(o)):"modal"===n?(setModalNoteFontColor(t),o.dataset.fontColor=t,renderBackgroundStudioPanel(o)):(setNoteFontColor(a,t,r),o.dataset.fontColor=t,renderBackgroundStudioPanel(o)))}}else openColorPickerPanel({mode:n,entityId:a,editUrl:r,type:"font"});else openColorPickerPanel({mode:n,entityId:a,editUrl:r,type:"background"});else"draft"===n?(o.dataset.fontColor="auto",i({fontColor:"auto"}),renderBackgroundStudioPanel(o)):"modal"===n?(setModalNoteFontColor("auto"),o.dataset.fontColor="auto",renderBackgroundStudioPanel(o)):(setNoteFontColor(a,"auto",r),o.dataset.fontColor="auto",renderBackgroundStudioPanel(o));else"draft"===n?(o.dataset.color="default",o.dataset.background="none",i({color:"default",background:"none"}),renderBackgroundStudioPanel(o)):"modal"===n?(setModalNoteColor("default"),o.dataset.color="default",o.dataset.background="none",renderBackgroundStudioPanel(o)):(setNoteColor(a,"default",r),o.dataset.color="default",o.dataset.background="none",renderBackgroundStudioPanel(o))}else closeBackgroundStudioPanel()}),t.addEventListener("keydown",e=>{const o=e.target&&e.target.closest?e.target.closest("button"):null;if(!o)return;if("Enter"===e.key||" "===e.key)return void((o.hasAttribute("data-bg-studio-action")||o.classList.contains("bg-studio-thumb")||o.classList.contains("bg-studio-swatch"))&&(e.preventDefault(),o.click()));const n=(t,e)=>{if(!t||0===t.length)return;const o=t[Math.max(0,Math.min(t.length-1,e))];o&&"function"==typeof o.focus&&o.focus()};if(o.classList.contains("bg-studio-thumb")){const a=Array.from(t.querySelectorAll(".bg-studio-gallery .bg-studio-thumb")),r=a.indexOf(o);if(-1===r)return;const i=2;return void("ArrowRight"===e.key?(e.preventDefault(),n(a,r+i)):"ArrowLeft"===e.key?(e.preventDefault(),n(a,r-i)):"ArrowDown"===e.key?(e.preventDefault(),n(a,r+1)):"ArrowUp"===e.key&&(e.preventDefault(),n(a,r-1)))}if(o.classList.contains("bg-studio-swatch")){const a=Array.from(t.querySelectorAll(".bg-studio-swatches .bg-studio-swatch")),r=a.indexOf(o);if(-1===r)return;return void("ArrowRight"===e.key?(e.preventDefault(),n(a,r+1)):"ArrowLeft"===e.key&&(e.preventDefault(),n(a,r-1)))}}),t.addEventListener("input",t=>{const e=t.target&&t.target.matches(".bg-studio-search-input")?t.target:null;if(!e)return;const o=document.getElementById("shaarli-bg-studio");o&&(o.dataset.query=e.value||"",window.clearTimeout(o.__searchTimer),o.__searchTimer=window.setTimeout(()=>{renderBackgroundStudioPanel(o)},150))}),backgroundStudioPanelInitialized=!0}function closeBackgroundStudioPanel(){const t=document.getElementById("shaarli-bg-studio");t&&(t.classList.remove("open"),t.style.display="none",t.setAttribute("aria-hidden","true"),t.__anchorEl=null)}function openBackgroundStudioPanel({anchorEl:t,mode:e,entityId:o,editUrl:n,currentColor:a,currentFilter:r,currentBackground:i,currentFontColor:l,title:s}){ensureBackgroundStudioPanel();const d=document.getElementById("shaarli-bg-studio");d&&(d.dataset.mode=e||"entity",d.dataset.entityId=o||"",d.dataset.editUrl=n||"",d.dataset.color=a||"default",d.dataset.filter=normalizeFilterKey(r||"")||"none",d.dataset.background=normalizeBackgroundKey(i||"")||"none",d.dataset.fontColor=l||d.dataset.fontColor||"auto",d.dataset.query=d.dataset.query||"",d.dataset.title=s||window.ShaarliProI18n.t("My images & colors"),d.__anchorEl=t||null,renderBackgroundStudioPanel(d),d.style.display="block",d.classList.add("open"),d.setAttribute("aria-hidden","false"),positionBackgroundStudioPanel(d,t),window.requestAnimationFrame(()=>{const t=d.querySelector(".bg-studio-search-input");t&&"function"==typeof t.focus&&(t.focus(),t.select())}))}function positionBackgroundStudioPanel(t,e){if(!t)return;const o=12,n=e&&e.getBoundingClientRect?e.getBoundingClientRect():null;t.style.left="",t.style.top="",t.style.right="",t.style.bottom="";const a=t.getBoundingClientRect(),r=n?n.top-a.height-10:o,i=n?n.left:o;let l=r;l<o&&(l=n?n.bottom+10:o);let s=i;s+a.width>window.innerWidth-o&&(s=window.innerWidth-o-a.width),s<o&&(s=o),l+a.height>window.innerHeight-o&&(l=window.innerHeight-o-a.height),l<o&&(l=o),t.style.left=`${Math.round(s)}px`,t.style.top=`${Math.round(l)}px`}function normalizeSearchText(t){return String(t||"").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").trim()}function categorizeBackgroundKey(t,e){const o=normalizeSearchText(`${t||""} ${e||""}`);return t&&"none"!==t?o.includes("degrade")||o.includes("gradient")?"gradient":o.includes("grid")||o.includes("quadrill")||o.includes("lign")||o.includes("feuille")?"grid":o.includes("damier")||o.includes("checker")||o.includes("texture")?"texture":"image":"solid"}function getBackgroundStudioItems(){return{colors:NOTE_COLOR_OPTIONS.map(t=>({type:"color",key:t.key,label:t.label,color:getThemeColorValue(t),keywords:[t.key,t.label]})),backgrounds:[{type:"background",category:"solid",key:"none",label:window.ShaarliProI18n.t("Solid color"),keywords:["none","sans image","solid","uni"]},...getAvailableBackgroundOptionsForMode().map(t=>({type:"background",category:categorizeBackgroundKey(t.key,t.label),key:t.key,label:t.label,url:getNoteBackgroundUrl(t.key),keywords:[t.key,t.label,"image","background"]}))]}}function renderBackgroundStudioPanel(t){if(!t)return;const e=document.activeElement,o=!!(e&&t.contains(e)&&e.classList&&e.classList.contains("bg-studio-search-input")),n=o&&"number"==typeof e.selectionStart?e.selectionStart:null,a=o&&"number"==typeof e.selectionEnd?e.selectionEnd:null,r=t.dataset.title||window.ShaarliProI18n.t("My images & colors"),i=t.dataset.color||"default",l="string"==typeof i&&i.startsWith("custom:"),s=t.dataset.filter||"none",d=t.dataset.fontColor||"auto",c=normalizeSearchText(t.dataset.query||""),{colors:u,backgrounds:m}=getBackgroundStudioItems(),p=m.filter(t=>{if(!c)return!0;return normalizeSearchText([t.label,t.key,"image","background"].join(" ")).includes(c)}).map(e=>{const o=t.dataset.background===e.key,n=`class="bg-studio-thumb ${o?"is-active":""}" type="button"`;return`<div class="bg-studio-tile">${"none"===e.key?`<button ${n} data-bg-studio-action="set-background" data-bg-key="none" title="${e.label}" aria-label="${e.label}" aria-pressed="${o}"><span class="bg-studio-thumb-solid"></span></button>`:`<button ${n} data-bg-studio-action="set-background" data-bg-key="${e.key}" title="${e.label}" aria-label="${e.label}" aria-pressed="${o}" style="background-image:url('${e.url||""}')"></button>`}<div class="bg-studio-thumb-label">${e.label}</div></div>`}).join(""),f=u.filter(t=>"default"!==t.key&&"custom"!==t.key).map(t=>{const e=i===t.key,o=t.color||"";return`<button class="bg-studio-swatch ${e?"is-active":""}" type="button" data-bg-studio-action="set-color" data-color-key="${t.key}" title="${o}" aria-label="${t.label}" aria-pressed="${e}" style="background-color:${o}"></button>`}).join("")+`<button class="bg-studio-swatch bg-studio-swatch-custom ${l?"is-active":""}" type="button" data-bg-studio-action="open-color-picker" title="${window.ShaarliProI18n.t("Custom color")}" aria-label="${window.ShaarliProI18n.t("Custom color")}" aria-pressed="${l}">\n <i class="mdi mdi-plus" aria-hidden="true"></i>\n </button>`,g="string"==typeof d&&d.startsWith("custom:"),h=NOTE_FONT_COLOR_OPTIONS.filter(t=>"custom"!==t.key).map(t=>{const e=d===t.key,o=t.value||"auto",n="auto"===o?"background: linear-gradient(135deg, #f5f7fb 50%, #202124 50%);":`background-color: ${o};`;return`<button class="bg-studio-swatch ${e?"is-active":""}" type="button" data-bg-studio-action="set-font-color" data-font-color-key="${t.key}" title="${t.label}" aria-label="${t.label}" aria-pressed="${e}" style="${n}"></button>`}).join("")+`<button class="bg-studio-swatch bg-studio-swatch-custom ${g?"is-active":""}" type="button" data-bg-studio-action="open-font-color-picker" title="${window.ShaarliProI18n.t("Custom font color")}" aria-label="${window.ShaarliProI18n.t("Custom font color")}" aria-pressed="${g}">\n <i class="mdi mdi-plus" aria-hidden="true"></i>\n </button>`,y=NOTE_FILTER_OPTIONS.map(t=>((t,e,o)=>{const n=s===t;return`<button class="bg-studio-filter-btn ${n?"is-active":""}" type="button" data-bg-studio-action="set-filter" data-filter="${t}" title="${o}" aria-label="${o}" aria-pressed="${n}"><i class="mdi ${e}" aria-hidden="true"></i></button>`})(t.key,t.icon,t.label)).join(""),b=!!(t.dataset.query||"").trim();if(t.innerHTML=`\n <div class="bg-studio-header">\n <div class="bg-studio-title">${r}</div>\n <button class="bg-studio-close" type="button" data-bg-studio-action="close" title=window.ShaarliProI18n.t("Close") aria-label=window.ShaarliProI18n.t("Close")><i class="mdi mdi-close" aria-hidden="true"></i></button>\n </div>\n <div class="bg-studio-gallery" role="list">${p}</div>\n <div class="bg-studio-rows">\n <div class="bg-studio-row">\n <div class="bg-studio-row-heading">\n <div class="bg-studio-row-label">Colors:</div>\n <button type="button" class="bg-studio-reset" data-bg-studio-action="set-defaults" title=window.ShaarliProI18n.t("Reset") aria-label=window.ShaarliProI18n.t("Reset")><i class="mdi mdi-refresh" aria-hidden="true"></i></button>\n </div>\n <div class="bg-studio-swatches" role="list">${f}</div>\n </div>\n <div class="bg-studio-row">\n <div class="bg-studio-row-heading">\n <div class="bg-studio-row-label">Font:</div>\n <button type="button" class="bg-studio-reset" data-bg-studio-action="reset-font-color" title=window.ShaarliProI18n.t("Reset") aria-label=window.ShaarliProI18n.t("Reset")><i class="mdi mdi-refresh" aria-hidden="true"></i></button>\n </div>\n <div class="bg-studio-swatches bg-studio-swatches-font" role="list">${h}</div>\n </div>\n <div class="bg-studio-row">\n <div class="bg-studio-row-label">Filtres:</div>\n <div class="bg-studio-filters">${y}</div>\n </div>\n </div>\n <div class="bg-studio-search">\n <i class="mdi mdi-magnify" aria-hidden="true"></i>\n <input class="bg-studio-search-input" type="search" placeholder=window.ShaarliProI18n.t("Search my images… (filter by color or filter)") value="${t.dataset.query||""}" />\n <button class="bg-studio-clear" type="button" data-bg-studio-action="set-query" title=window.ShaarliProI18n.t("Clear search") aria-label=window.ShaarliProI18n.t("Clear search") style="${b?"":"display:none"}"><i class="mdi mdi-close-circle-outline" aria-hidden="true"></i></button>\n </div>\n `,o){const e=t.querySelector(".bg-studio-search-input");if(e&&"function"==typeof e.focus&&(e.focus({preventScroll:!0}),"function"==typeof e.setSelectionRange)){const t=(e.value||"").length,o="number"==typeof n?Math.max(0,Math.min(t,n)):t,r="number"==typeof a?Math.max(0,Math.min(t,a)):t;try{e.setSelectionRange(o,r)}catch(t){}}}}function applyNoteVisualState(t,e){if(!t||!e)return;const o=e.color||"default",n="string"==typeof o&&o.startsWith("custom:"),a=n?o.substring(7):"",r=n?null:getColorOption(o),i=n?"custom":r?r.key:"default",l=n?a:getThemeColorValue(r),s=getReadableForegroundForBackground(l),d=normalizeFilterKey(e.filter||"none"),c=normalizeBackgroundKey(e.background||"")||"none",u=e.fontColor||"auto";if(Array.from(t.classList).forEach(e=>{e.startsWith("note-color-")&&t.classList.remove(e),e.startsWith("note-filter-")&&t.classList.remove(e)}),t.classList.add(`note-color-${i}`),"none"!==d&&t.classList.add(`note-filter-${d}`),l&&"default"!==i?(t.style.backgroundColor=l,t.style.removeProperty("border-color")):t.style.removeProperty("background-color"),s&&"default"!==i?t.style.setProperty("--note-card-fg",s):t.style.removeProperty("--note-card-fg"),u&&"auto"!==u){let e=null;if("string"==typeof u&&u.startsWith("custom:"))e=u.substring(7);else{const t=NOTE_FONT_COLOR_OPTIONS.find(t=>t.key===u);t&&t.value&&"auto"!==t.value&&(e=t.value)}e&&t.style.setProperty("--note-card-fg",e)}if(c&&"none"!==c){const e=getNoteBackgroundUrl(c);e?(t.classList.add("note-has-bg"),t.style.setProperty("--note-bg-image",`url('${e}')`),t.dataset.background=c):(t.classList.remove("note-has-bg"),t.style.removeProperty("--note-bg-image"),t.dataset.background="none")}else t.classList.remove("note-has-bg"),t.style.removeProperty("--note-bg-image"),t.dataset.background="none";t.dataset.color=i,t.dataset.customColor=n&&a?a:"",t.dataset.filter=d,t.dataset.fontColor=u}function extractNoteVisualStateFromTags(t){const e=Array.isArray(t)?t:[];let o="default";const n=e.find(t=>"string"==typeof t&&t.startsWith("note-color-"));if(n){const t=n.substring(11);/^[0-9A-Fa-f]{6}$/.test(t)?o=`custom:#${t.toUpperCase()}`:NOTE_COLOR_OPTIONS.some(e=>e.key===t)&&(o=t)}else{const t=e.find(t=>"string"==typeof t&&t.startsWith("note-custom-"));if(t){const e=t.substring(12);/^[0-9A-Fa-f]{6}$/.test(e)&&(o=`custom:#${e.toUpperCase()}`)}const n=e.find(t=>"string"==typeof t&&t.startsWith("note-"));if(n){const t=n.substring(5);NOTE_COLOR_OPTIONS.some(e=>e.key===t)&&(o=t)}}let a="none";const r=e.find(t=>"string"==typeof t&&t.startsWith("notefilter-"));if(r){const t=normalizeFilterKey(r.substring(11));t&&"none"!==t&&(a=t)}let i="none";const l=e.find(t=>"string"==typeof t&&t.startsWith("notebg-"));if(l){const t=normalizeBackgroundKey(l.substring(7));t&&(i=t)}let s="auto";const d=e.find(t=>"string"==typeof t&&t.startsWith("font-"));if(d){const t=d.substring(5),e=t.startsWith("#")?t:`#${t}`;/^#[0-9A-Fa-f]{6}$/.test(e)&&(s=`custom:${e.toUpperCase()}`)}return{color:o,filter:a,background:i,fontColor:s}}function initBookmarkPaletteButtons(){const t=Array.from(document.querySelectorAll(".link-outer"));0!==t.length&&(t.forEach(t=>{const e=t.dataset.id||t.getAttribute("data-id")||t.id;if(!e)return;const o=Array.from(t.querySelectorAll(".link-tag a")).map(t=>(t.textContent||"").trim()),{color:n,filter:a,background:r,fontColor:i}=extractNoteVisualStateFromTags(o);applyNoteVisualState(t,{color:n,filter:a,background:r,fontColor:i});const l=t.querySelector(".link-actions");if(!l)return;if(l.querySelector(".bookmark-palette"))return;const s=l.querySelector('a[title=window.ShaarliProI18n.t("Edit")], a[aria-label="Modifier ce bookmark"], a[href*="/admin/shaare/"]');if(!s||!s.href)return;const d=s.href,c=`bookmark-palette-${e}`,u=document.createElement("div");u.className="bookmark-palette",u.style.position="relative",u.innerHTML=`\n <button type="button" title=window.ShaarliProI18n.t("Color") aria-label=window.ShaarliProI18n.t("Color") id="${c}"><i class="mdi mdi-palette-outline" aria-hidden="true"></i></button>\n `;const m=Array.from(l.querySelectorAll('a[href*="/pin"], a[aria-label*=window.ShaarliProI18n.t("Pin")], a[title*=window.ShaarliProI18n.t("Pin")]'))[0];m&&m.parentNode===l?l.insertBefore(u,m):s&&s.parentNode===l?l.insertBefore(u,s.nextSibling):l.appendChild(u);const p=u.querySelector(`#${c}`);p&&p.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),openBackgroundStudioPanel({anchorEl:p,mode:"entity",entityId:e,editUrl:d,currentColor:getElementVisualColor(t),currentFilter:getElementVisualFilter(t),currentBackground:getElementVisualBackground(t),currentFontColor:getElementVisualFontColor(t),title:window.ShaarliProI18n.t("My images & colors")})})}),document.addEventListener("click",t=>{t.target.closest(".bookmark-palette")||t.target.closest("#shaarli-bg-studio")||closeBackgroundStudioPanel()}))}function generateBookmarkPaletteButtons(t,e,o,n){return generateUnifiedPaletteMenu({entityId:t,editUrl:e,currentColor:o,currentFilter:n,mode:"entity"})}function generateUnifiedPaletteMenu({entityId:t,editUrl:e,currentColor:o,currentFilter:n,mode:a}){const r=o||"default",i=normalizeFilterKey(n||"")||"none",l="modal"===a?t=>`setModalNoteColor('${t}')`:o=>`setNoteColor('${t}', '${o}', '${e}')`,s="modal"===a?t=>`setModalNoteFilter('${t}')`:o=>`setNoteFilter('${t}', '${o}', '${e}')`;return`\n <div class="palette-section">\n <div class="palette-section-title">Couleurs</div>\n <div class="palette-row palette-row-colors">${[`<button class="palette-btn palette-btn-default ${"default"===r?"is-active":""}" type="button" title="${window.ShaarliProI18n.t("Default")}" aria-label="${window.ShaarliProI18n.t("Default")}" aria-pressed="${"default"===r}" onclick="${l("default")}"><i class="mdi mdi-format-color-reset" aria-hidden="true"></i></button>`,...NOTE_COLOR_OPTIONS.filter(t=>"default"!==t.key).map(t=>{const e=getThemeColorValue(t);return`<button class="palette-btn note-color-${t.key} ${r===t.key?"is-active":""}" type="button" title="${t.label}" aria-label="${t.label}" aria-pressed="${r===t.key}" onclick="${l(t.key)}" style="background-color:${e}"></button>`})].join("")}</div>\n </div>\n <div class="palette-divider"></div>\n <div class="palette-section">\n <div class="palette-section-title">Filtres</div>\n <div class="palette-row palette-row-filters">${[`<button class="palette-btn palette-btn-filter-none ${"none"===i?"is-active":""}" type="button" title="Aucun" aria-label="Aucun" aria-pressed="${"none"===i}" onclick="${s("none")}"><i class="mdi mdi-close-circle-outline" aria-hidden="true"></i></button>`,...NOTE_FILTER_OPTIONS.filter(t=>"none"!==t.key).map(t=>`<button class="palette-btn palette-btn-filter ${i===t.key?"is-active":""}" type="button" title="${t.label}" aria-label="${t.label}" aria-pressed="${i===t.key}" onclick="${s(t.key)}"><i class="mdi ${t.icon}" aria-hidden="true"></i></button>`)].join("")}</div>\n </div>\n `}function syncNoteFromCardElement(t,e){if(!t||!e)return;const o=Array.from(e.classList).find(t=>t.startsWith("note-color-"));o&&(t.color=o.replace("note-color-","")||"default");const n=e.dataset.filter;t.filter=n&&"none"!==n?n:"none";const a=e.dataset.background;t.background=a&&"none"!==a?a:"none"}function initTodoView(t,e){document.body.classList.add("view-todo","view-notes");const o=document.querySelector(".content-toolbar");o&&(o.style.display="none");const n=document.createElement("div");n.className="notes-wrapper todo-wrapper";const a=document.createElement("div");a.className="notes-top-bar";const r=document.createElement("div");r.className="note-input-container todo-input-container";const i=()=>{r.classList.remove("is-editing","todo-draft-mode","is-enhanced"),applyNoteVisualState(r,{color:"default",filter:"none",background:"none",fontColor:"auto"}),r.innerHTML=`\n <div class="note-input-collapsed">\n <span class="note-input-placeholder">${window.ShaarliProI18n.t("Create a task...")}</span>\n <div class="note-input-actions">\n <button type="button" class="todo-open-draft-btn" title=window.ShaarliProI18n.t("Create a list")><i class="mdi mdi-check-circle-outline"></i></button>\n </div>\n </div>\n `;const t=r.querySelector(".note-input-collapsed"),e=r.querySelector(".todo-open-draft-btn"),o=()=>{r.classList.add("is-editing","todo-draft-mode"),r.innerHTML=`\n <div class="note-input-expanded todo-draft-expanded">\n <input type="text" class="note-input-title todo-draft-title" placeholder=window.ShaarliProI18n.t("List title") autocomplete="off" />\n <div class="todo-draft-list" role="list"></div>\n <button type="button" class="todo-draft-add-btn"><i class="mdi mdi-plus"></i> ${window.ShaarliProI18n.t("Add list item")}</button>\n <div class="note-input-expanded-actions">\n <div class="note-input-actions-left">\n <button type="button" class="note-input-palette-btn" title=window.ShaarliProI18n.t("Color")><i class="mdi mdi-palette-outline"></i></button>\n </div>\n <button type="button" class="note-input-close-btn">Fermer</button>\n </div>\n </div>\n `;const t=r.querySelector(".todo-draft-title"),e=r.querySelector(".todo-draft-list"),o=r.querySelector(".todo-draft-add-btn"),n=r.querySelector(".note-input-close-btn"),a=r.querySelector(".note-input-palette-btn");let l=!1,s=!1,d={color:"default",filter:"none",background:"none",fontColor:"auto"};applyNoteVisualState(r,d);const c=(t={text:"",checked:!1},o=!1)=>{if(!e)return null;const n=document.createElement("div");n.className="todo-draft-row",n.innerHTML=`\n <label class="todo-checklist-box" title=window.ShaarliProI18n.t("Mark as completed")>\n <input type="checkbox" class="todo-item-checkbox" ${t.checked?"checked":""} />\n <span class="todo-checklist-box-ui"></span>\n </label>\n <input type="text" class="todo-item-text" placeholder=window.ShaarliProI18n.t("List item") value="${escapeHtml(t.text||"")}" />\n <button type="button" class="todo-item-delete" title=window.ShaarliProI18n.t("Delete")><i class="mdi mdi-close"></i></button>\n `,e.appendChild(n);const a=n.querySelector(".todo-item-checkbox"),r=n.querySelector(".todo-item-text"),i=n.querySelector(".todo-item-delete"),s=()=>{n.classList.toggle("is-checked",!(!a||!a.checked))};return s(),a?.addEventListener("change",()=>{l=!0,s()}),r?.addEventListener("input",()=>{l=!0}),i?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),l=!0,n.remove(),e.querySelector(".todo-draft-row")||c({text:"",checked:!1},!0)}),o&&r&&r.focus({preventScroll:!0}),n};c({text:"",checked:!1},!1),o?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),l=!0,c({text:"",checked:!1},!0)}),t?.addEventListener("input",()=>{l=!0});const u=async()=>{if(s)return;const o=t&&"string"==typeof t.value?t.value.trim():"",n=e?Array.from(e.querySelectorAll(".todo-draft-row")).map(t=>{const e=t.querySelector(".todo-item-checkbox"),o=t.querySelector(".todo-item-text"),n=o&&"string"==typeof o.value?o.value.trim():"";return{checked:!(!e||!e.checked),text:n}}).filter(t=>t.text):[];if(!o&&0===n.length)return document.removeEventListener("pointerdown",m,!0),void i();if(!l)return document.removeEventListener("pointerdown",m,!0),void i();s=!0;try{await createNewTodoViaForm({title:o,items:n,visual:d}),window.location.reload()}catch(t){console.error("Error creating todo:",t),alert(window.ShaarliProI18n.t("Error creating todo.")),s=!1}};n?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),u()});const m=t=>{t.target&&t.target.closest&&t.target.closest("#shaarli-bg-studio")||t.target&&t.target.closest&&t.target.closest(".bg-studio-panel")||r.contains(t.target)||u()};document.addEventListener("pointerdown",m,!0),a?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),openBackgroundStudioPanel({anchorEl:a,mode:"draft",entityId:"draft-new-todo",editUrl:"",currentColor:d.color||"default",currentFilter:d.filter||"none",currentBackground:d.background||"none",currentFontColor:d.fontColor||"auto",title:window.ShaarliProI18n.t("My images & colors")});const e=document.getElementById("shaarli-bg-studio");e&&(e.__draftApply=t=>{d={...d,...t||{}},applyNoteVisualState(r,d)})}),t?.focus({preventScroll:!0})};t?.addEventListener("click",t=>{t.target.closest("button")||o()}),e?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),o()})};i(),a.appendChild(r);const l=document.createElement("div");l.className="notes-tools",l.innerHTML='\n <button class="icon-btn active" id="btn-view-grid" title=window.ShaarliProI18n.t("Grid view")><i class="mdi mdi-view-dashboard-outline"></i></button>\n <button class="icon-btn" id="btn-view-list" title=window.ShaarliProI18n.t("List view")><i class="mdi mdi-view-agenda-outline"></i></button>\n ',a.appendChild(l),n.appendChild(a);const s=document.createElement("div");s.className="notes-content-area";const d=Array.from(t.querySelectorAll(".link-outer")).map(t=>parseTodoFromLink(t)).filter(t=>t);n.appendChild(s),t.style.display="none",t.parentNode?t.parentNode.insertBefore(n,t):e.appendChild(n),renderTodos(s,d,"grid");const c=document.createElement("div");c.className="note-modal-overlay todo-modal-overlay",c.innerHTML=`\n <div class="note-modal note-color-default todo-modal">\n <div class="note-modal-header">\n <h2 class="note-title" id="todo-modal-title"></h2>\n <button type="button" class="note-modal-pin-toggle" id="todo-modal-pin" title=window.ShaarliProI18n.t("Pin")>\n <i class="mdi mdi-pin-outline"></i>\n </button>\n </div>\n <div class="note-modal-content">\n <div class="todo-checklist" id="todo-modal-checklist"></div>\n <button type="button" class="todo-add-item-btn" id="todo-modal-add-item"><i class="mdi mdi-plus"></i> ${window.ShaarliProI18n.t("Add list item")}</button>\n </div>\n <div class="note-modal-tags is-empty" id="todo-modal-tags"></div>\n <div class="note-modal-actions">\n <div class="note-modal-actions-left">\n <div class="note-modal-color-picker">\n <button type="button" id="todo-modal-color-btn" title=window.ShaarliProI18n.t("Color")><i class="mdi mdi-palette-outline"></i></button>\n <div class="palette-popup note-modal-palette" id="todo-modal-color-popup"></div>\n </div>\n <a href="#" id="todo-modal-edit" title=window.ShaarliProI18n.t("Edit")><i class="mdi mdi-pencil-outline"></i></a>\n <button type="button" id="todo-modal-delete" title=window.ShaarliProI18n.t("Delete")><i class="mdi mdi-delete-outline"></i></button>\n </div>\n <button type="button" class="note-modal-close-btn" id="todo-modal-close">Fermer</button>\n </div>\n </div>\n `,document.body.appendChild(c);const u=n.querySelector("#btn-view-grid"),m=n.querySelector("#btn-view-list");u.addEventListener("click",()=>{u.classList.add("active"),m.classList.remove("active"),renderTodos(s,d,"grid")}),m.addEventListener("click",()=>{m.classList.add("active"),u.classList.remove("active"),renderTodos(s,d,"list")}),c.querySelector("#todo-modal-close").addEventListener("click",()=>{c.classList.remove("open")}),c.addEventListener("click",t=>{t.target===c&&c.classList.remove("open")});const p=c.querySelector("#todo-modal-pin"),f=c.querySelector("#todo-modal-color-btn"),g=c.querySelector("#todo-modal-color-popup");f.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=c.querySelector(".note-modal");openBackgroundStudioPanel({anchorEl:f,mode:"modal",entityId:e&&e.dataset.todoId||"",editUrl:e&&e.dataset.editUrl||"",currentColor:e?getElementVisualColor(e):"default",currentFilter:e?getElementVisualFilter(e):"none",currentBackground:e?getElementVisualBackground(e):"none",currentFontColor:e?getElementVisualFontColor(e):"auto",title:window.ShaarliProI18n.t("My images & colors")})}),p.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=c.querySelector(".note-modal"),o=e.dataset.todoId,n=e.dataset.editUrl;if(!o||!n)return;togglePinTag(o,n,p);const a=p.classList.contains("active");let r=(e.dataset.tags||"").split("||").filter(t=>t);a?r.includes("shaarli-pin")||r.push("shaarli-pin"):r=r.filter(t=>"shaarli-pin"!==t),e.dataset.tags=r.join("||"),renderModalTags(c.querySelector("#todo-modal-tags"),r),c.currentTodo&&(c.currentTodo.isPinned=a,c.currentTodo.tags=r)}),c.querySelector("#todo-modal-delete").addEventListener("click",()=>{if(!confirm(window.ShaarliProI18n.t("Delete this task?")))return;const t=c.querySelector(".note-modal"),e=t.dataset.deleteUrl;t.dataset.todoId;e&&"#"!==e&&deleteEntitySilently(e).then(()=>{window.location.href="/?searchtags=todo"}).catch(t=>{console.error("Delete failed:",t),alert(window.ShaarliProI18n.t("Error deleting."))})}),c.addEventListener("click",t=>{t.target.closest(".note-modal-color-picker")||g.classList.remove("open")}),c.querySelector("#todo-modal-add-item").addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),c.currentTodo&&addTodoItem(c,c.currentTodo)}),"function"==typeof initTagDisplayAndRemoval&&initTagDisplayAndRemoval()}function parseTodoFromLink(t){if(!t)return null;const e=t.dataset.id,o=t.querySelector(".link-title"),n=o?o.textContent.trim():"",a=t.querySelector(".link-description"),r=a?a.innerHTML:"",i=a?a.textContent:"",l=[];t.querySelectorAll(".link-tag-list a").forEach(t=>{const e=(t.textContent||"").trim();e&&l.push(e)});const{color:s,filter:d,background:c,fontColor:u}=extractNoteVisualStateFromTags(l),m=l.filter(t=>!t.startsWith("note-color-")&&(!t.startsWith("note-custom-")&&(!t.startsWith("notefilter-")&&(!t.startsWith("notebg-")&&!t.startsWith("font-"))))),p=t.querySelector(".link-actions"),f=p&&p.querySelector('a[href*="admin/shaare"]')?p.querySelector('a[href*="admin/shaare"]').href:"#",g=p&&p.querySelector('a[href*="delete"]')?p.querySelector('a[href*="delete"]').href:"#",h=p&&p.querySelector('a[href*="pin"]')?p.querySelector('a[href*="pin"]').href:"#",y=m.includes("shaarli-pin"),b=extractChecklistItemsFromDescription(a,i),v=parseTodoMarkdown(i);return{id:e,title:n,descHtml:r,descText:i,items:b,_todoHeaderLines:v.headerLines,_todoFooterLines:v.footerLines,tags:m,color:s,filter:d,background:c,fontColor:u,editUrl:f,deleteUrl:g,pinUrl:h,isPinned:y}}function extractChecklistItemsFromDescription(t,e){const o=[];if(t){const e=Array.from(t.querySelectorAll('input[type="checkbox"]'));if(e.length>0)return e.forEach(t=>{const e=t.closest("li")||t.parentElement;let n="";if(e){const t=e.cloneNode(!0);t.querySelectorAll('input[type="checkbox"]').forEach(t=>t.remove()),n=(t.textContent||"").trim()}o.push({checked:!!t.checked,text:n})}),o}const n=String(e||"").split(/\r?\n/);return parseTodoMarkdown(t?t.innerHTML:n.join("\n")).items}function getFormFieldValue(t){if(!t)return"";if("TEXTAREA"===(t.tagName||"").toUpperCase()){const e="string"==typeof t.value?t.value:"";if(e&&""!==e.trim())return e;return"string"==typeof t.textContent?t.textContent:""}return t.value}async function fetchShaareFormBaseData(t){const e=await fetch(t,{credentials:"same-origin"}),o=await e.text(),n=(new DOMParser).parseFromString(o,"text/html").querySelector('form[name="linkform"]');if(!n)throw new Error("Could not find edit form");const a=new URLSearchParams;return n.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&a.append(t.name,t.value||"on"):t.name&&a.append(t.name,getFormFieldValue(t))}),{action:n.action,baseData:a}}async function createNewNoteViaForm({title:t,markdown:e,visual:o=null}){const n="undefined"!=typeof shaarli&&shaarli.basePath?shaarli.basePath:"",a=window.ShaarItRules?window.ShaarItRules.generateNoteUrl():"",r=`${n}/admin/shaare?post=${encodeURIComponent(a)}&tags=note`,{action:i,baseData:l}=await fetchShaareFormBaseData(r),s=new URLSearchParams(l.toString());s.set("lf_url",a),s.set("lf_title",t||""),s.set("lf_description",e||"");let d=(s.get("lf_tags")||"").trim().split(/[\s,]+/).filter(t=>""!==t.trim());if(d=d.filter(t=>"shaarli-todo"!==t),d.includes("note")||d.push("note"),d.includes("shaarli-note")||d.push("shaarli-note"),o){const t=o.color||"default",e=normalizeFilterKey(o.filter||"")||"none",n=normalizeBackgroundKey(o.background||"")||"none",a=o.fontColor||"auto";if(d=d.filter(t=>!t.startsWith("note-color-")),d=d.filter(t=>!t.startsWith("notefilter-")),d=d.filter(t=>!t.startsWith("notebg-")),d=d.filter(t=>!t.startsWith("font-")),t&&"default"!==t)if("string"==typeof t&&t.startsWith("custom:")){const e=t.substring(7).replace("#","");e&&d.push(`note-color-${e}`)}else d.push(`note-color-${t}`);if(e&&"none"!==e&&d.push(`notefilter-${e}`),n&&"none"!==n&&d.push(`notebg-${n}`),a&&"auto"!==a)if("string"==typeof a&&a.startsWith("custom:")){const t=a.substring(7).replace("#","");t&&d.push(`font-${t}`)}else{const t=NOTE_FONT_COLOR_OPTIONS.find(t=>t.key===a);t&&t.value&&"auto"!==t.value&&d.push(`font-${t.value.substring(1)}`)}}s.set("lf_tags",d.join(" ")),s.get("returnurl")||s.set("returnurl",window.location.href),s.append("save_edit","1");const c=await fetch(i,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()});if(!c.ok)throw new Error(`Failed to create note (status ${c.status})`)}async function createNewTodoViaForm({title:t,items:e=[],visual:o=null}){const n="undefined"!=typeof shaarli&&shaarli.basePath?shaarli.basePath:"",a=window.ShaarItRules?window.ShaarItRules.generateTodoUrl():"",r=`${n}/admin/shaare?post=${encodeURIComponent(a)}&tags=todo`,{action:i,baseData:l}=await fetchShaareFormBaseData(r),s=new URLSearchParams(l.toString());s.set("lf_url",a),s.set("lf_title",t||"");const d=(Array.isArray(e)?e:[]).map(t=>({checked:!(!t||!t.checked),text:String(t&&t.text||"").trim()})).filter(t=>t.text).map(t=>`- [${t.checked?"x":" "}] ${t.text}`).join("\n");s.set("lf_description",d);let c=(s.get("lf_tags")||"").trim().split(/[\s,]+/).filter(t=>""!==t.trim());if(c=c.filter(t=>"note"!==t&&"shaarli-note"!==t),c.includes("todo")||c.push("todo"),o){const t=o.color||"default",e=normalizeFilterKey(o.filter||"")||"none",n=normalizeBackgroundKey(o.background||"")||"none",a=o.fontColor||"auto";if(c=c.filter(t=>!t.startsWith("note-color-")),c=c.filter(t=>!t.startsWith("notefilter-")),c=c.filter(t=>!t.startsWith("notebg-")),c=c.filter(t=>!t.startsWith("font-")),t&&"default"!==t)if("string"==typeof t&&t.startsWith("custom:")){const e=t.substring(7).replace("#","");e&&c.push(`note-color-${e}`)}else c.push(`note-color-${t}`);if(e&&"none"!==e&&c.push(`notefilter-${e}`),n&&"none"!==n&&c.push(`notebg-${n}`),a&&"auto"!==a)if("string"==typeof a&&a.startsWith("custom:")){const t=a.substring(7).replace("#","");t&&c.push(`font-${t}`)}else{const t=NOTE_FONT_COLOR_OPTIONS.find(t=>t.key===a);t&&t.value&&"auto"!==t.value&&c.push(`font-${t.value.substring(1)}`)}}s.set("lf_tags",c.join(" ")),s.get("returnurl")||s.set("returnurl",window.location.href),s.append("save_edit","1");const u=await fetch(i,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()});if(!u.ok)throw new Error(`Failed to create todo (status ${u.status})`)}async function hydrateNoteFromEditForm(t){if(t&&t.editUrl&&"#"!==t.editUrl&&!t._noteHydrated)return t._noteHydratePromise||(t._noteHydratePromise=(async()=>{try{const{action:e,baseData:o}=await fetchShaareFormBaseData(t.editUrl);t._noteEditAction=e,t._noteEditBaseData=o,t._noteMarkdown=o.get("lf_description")||"",t._noteTitle=o.get("lf_title")||"",t._noteHydrated=!0}catch(t){console.error("Error hydrating note edit form:",t)}finally{t._noteHydratePromise=null}})()),t._noteHydratePromise}async function persistNoteChanges(t,{title:e,markdown:o},n=0){if(!t||!t.editUrl||"#"===t.editUrl)return;const a=async()=>{const{action:e,baseData:o}=await fetchShaareFormBaseData(t.editUrl);t._noteEditAction=e,t._noteEditBaseData=o};t._noteEditAction&&t._noteEditBaseData&&t._noteEditBaseData.get&&t._noteEditBaseData.get("token")||await a();const r=new URLSearchParams(t._noteEditBaseData.toString());r.set("lf_title",e||""),r.set("lf_description",o||"");let i=(r.get("lf_tags")||"").trim().split(/[\s,]+/).filter(t=>""!==t.trim());i=i.filter(t=>"shaarli-todo"!==t),i.includes("note")||i.push("note"),i.includes("shaarli-note")||i.push("shaarli-note"),r.set("lf_tags",i.join(" ")),r.append("save_edit","1");const l=await fetch(t._noteEditAction,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()});if(!l.ok){if(403===l.status&&n<1)return t._noteEditAction="",t._noteEditBaseData=null,await a(),persistNoteChanges(t,{title:e,markdown:o},n+1);throw new Error("Failed to save note")}}async function hydrateTodoFromEditForm(t){if(t&&t.editUrl&&"#"!==t.editUrl&&!t._todoHydrated)return t._todoHydratePromise||(t._todoHydratePromise=(async()=>{try{const e=await fetch(t.editUrl,{credentials:"same-origin"});if(!e.ok)return void console.error("Todo hydration failed (edit form fetch not ok).",{id:t&&t.id,url:t&&t.editUrl,status:e&&e.status});const o=await e.text(),n=new DOMParser,a=n.parseFromString(o,"text/html").querySelector('form[name="linkform"]');if(!a)return void console.error("Todo hydration failed (edit form not found).",{id:t&&t.id,url:t&&t.editUrl,status:e&&e.status});const r=new URLSearchParams;a.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&r.append(t.name,t.value||"on"):t.name&&r.append(t.name,getFormFieldValue(t))}),t._todoEditAction=a.action,t._todoEditBaseData=r;const i=parseTodoMarkdown(r.get("lf_description")||"");t._todoHeaderLines=i.headerLines,t._todoFooterLines=i.footerLines,t.items=i.items,updateTodoCardPreview(t),t._todoHydrated=!0}catch(t){console.error("Error hydrating todo markdown:",t)}finally{t._todoHydratePromise=null}})()),t._todoHydratePromise}function renderTodos(t,e,o){if(!t)return;t.innerHTML="",t.className="grid"===o?"notes-masonry":"notes-list-view";const n=(e||[]).slice();n.sort((t,e)=>{const o=(t.tags||[]).includes("shaarli-pin");return(e.tags||[]).includes("shaarli-pin")-o}),n.forEach(e=>{const n=document.createElement("div");n.className="note-card todo-card",n.dataset.id=e.id,n.dataset.editUrl=e.editUrl||"",n.dataset.tags=(e.tags||[]).filter(t=>t).join("||"),e._todoCardEl=n,applyNoteVisualState(n,e),"list"===o&&n.classList.add("list-mode"),n.addEventListener("click",t=>{t.target.closest("button")||t.target.closest("a")||t.target.closest(".note-hover-actions")||(syncNoteFromCardElement(e,n),openTodoModal(e))});const a=document.createElement("div");if(a.className="note-inner",e.title){const t=document.createElement("h3");t.className="note-title",t.textContent=e.title,a.appendChild(t)}const r=document.createElement("div");if(r.className="note-body todo-checklist-preview-wrap",r.innerHTML=buildTodoPreviewHtml(e.items||[]),a.appendChild(r),(e.tags||[]).length>0){const t=document.createElement("div");t.className="note-tags",e.tags.forEach(o=>{if(isTechnicalTag(o))return;const n=createTagPill({tag:o,onRemoveClass:"note-tag-remove-btn",tagClass:"note-tag",canRemove:!!e.editUrl&&"#"!==e.editUrl});t.appendChild(n)}),a.appendChild(t)}const i=document.createElement("div");i.className="note-hover-actions";const l=document.createElement("a");l.href=e.pinUrl,l.title=e.isPinned?"Unpin":"Pin",l.className="note-pin-corner "+(e.isPinned?"active":""),l.innerHTML=`<i class="mdi mdi-pin${e.isPinned?"":"-outline"}"></i>`,a.appendChild(l);const s=`palette-${e.id}`;i.innerHTML=`\n <div style="position:relative;">\n <button title=window.ShaarliProI18n.t("Color") id="${s}"><i class="mdi mdi-palette-outline"></i></button>\n </div>\n <div class="spacer"></div>\n <a href="${e.editUrl}" title=window.ShaarliProI18n.t("Edit")><i class="mdi mdi-pencil-outline"></i></a>\n <button title=window.ShaarliProI18n.t("Delete") class="todo-delete-btn"><i class="mdi mdi-delete-outline"></i></button>\n `;const d=i.querySelector(".todo-delete-btn");d?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),confirm(window.ShaarliProI18n.t("Delete this task?"))&&deleteEntitySilently(e.deleteUrl).then(()=>{window.location.href="/?searchtags=todo"}).catch(t=>{console.error("Delete failed:",t),alert(window.ShaarliProI18n.t("Error deleting."))})});const c=i.querySelector(`#${s}`);c.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),openBackgroundStudioPanel({anchorEl:c,mode:"entity",entityId:e.id,editUrl:e.editUrl,currentColor:getElementVisualColor(n),currentFilter:getElementVisualFilter(n),currentBackground:getElementVisualBackground(n),title:window.ShaarliProI18n.t("My images & colors")})}),a.appendChild(i),n.appendChild(a),t.appendChild(n),hydrateTodoFromEditForm(e)})}function buildTodoPreviewHtml(t){const e=Array.isArray(t)?t:[],o=e.slice(0,8),n=e.length>8;return`<ul class="todo-checklist-preview">${o.map(t=>`<li class="todo-checklist-preview-item${!!t.checked?" is-checked":""}"><span class="todo-checklist-preview-box"><i class="mdi mdi-check"></i></span><span class="todo-checklist-preview-text">${escapeHtml(String(t.text||""))}</span></li>`).join("")}${n?'<li class="todo-checklist-preview-more">...</li>':""}</ul>`}function escapeHtml(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;").replace(/'/g,"&#039;")}function parseTodoMarkdown(t){const e=String(t||"").replace(/<br\s*\/?\s*>/gi,"\n").replace(/<\/(p|div|li|h\d)\s*>/gi,"\n");let o=e;try{const t=document.createElement("div");t.innerHTML=e;const n=Array.from(t.querySelectorAll('input[type="checkbox"]'));if(n.length>0){const t=[];return n.forEach(e=>{const o=e.closest("li")||e.parentElement;let n="";if(o){const t=o.cloneNode(!0);t.querySelectorAll('input[type="checkbox"]').forEach(t=>t.remove()),n=(t.textContent||"").trim()}t.push({checked:!!e.checked,text:n})}),{headerLines:[],footerLines:[],items:t}}const a=Array.from(t.querySelectorAll("li"));if(a.length>0){const t=a.map(t=>({checked:!1,text:(t.textContent||"").trim()})).filter(t=>t.text);if(t.length>0)return{headerLines:[],footerLines:[],items:t}}o=t.textContent||e}catch(t){o=e}const n=o.split(/\r?\n/),a=[/^\s*[-*+]\s*\[([ xX])\]\s*(.*)$/,/^\s*\[([ xX])\]\s*(.*)$/,/^\s*☐\s*(.*)$/,/^\s*☑\s*(.*)$/];let r=-1,i=-1;const l=[];n.forEach((t,e)=>{let o=!1;for(let n=0;n<a.length;n++){const s=a[n],d=t.match(s);if(d){o=!0,-1===r&&(r=e),i=e,2===n?l.push({checked:!1,text:(d[1]||"").trim()}):3===n?l.push({checked:!0,text:(d[1]||"").trim()}):l.push({checked:"x"===String(d[1]||"").toLowerCase(),text:(d[2]||"").trim()});break}}});return{headerLines:-1===r?n.slice():n.slice(0,r),footerLines:-1===i?[]:n.slice(i+1),items:l}}function buildTodoMarkdown(t){const e=Array.isArray(t._todoHeaderLines)?t._todoHeaderLines:[],o=Array.isArray(t._todoFooterLines)?t._todoFooterLines:[],n=(Array.isArray(t.items)?t.items:[]).map(t=>`- [${t.checked?"x":" "}] ${String(t.text||"").trim()}`),a=[];return e.forEach(t=>a.push(t)),n.forEach(t=>a.push(t)),o.forEach(t=>a.push(t)),a.join("\n").replace(/\s+$/g,"")}function renderTodoModalChecklist(t,e){const o=t.querySelector("#todo-modal-checklist");if(!o)return;o.innerHTML="";(Array.isArray(e.items)?e.items:[]).forEach((n,a)=>{const r=document.createElement("div");r.className="todo-checklist-row",r.dataset.index=String(a),r.setAttribute("draggable","true"),r.classList.toggle("is-checked",!!n.checked),r.innerHTML=`\n <button type="button" class="todo-drag-handle" aria-label=window.ShaarliProI18n.t("Move")><i class="mdi mdi-dots-grid"></i></button>\n <label class="todo-checklist-box">\n <input type="checkbox" class="todo-item-checkbox" ${n.checked?"checked":""}>\n <span class="todo-checklist-box-ui"></span>\n </label>\n <input type="text" class="todo-item-text" value="${escapeHtml(n.text||"")}" placeholder="">\n <button type="button" class="todo-item-delete" aria-label=window.ShaarliProI18n.t("Delete")><i class="mdi mdi-close"></i></button>\n `;const i=r.querySelector(".todo-item-checkbox"),l=r.querySelector(".todo-item-text"),s=r.querySelector(".todo-item-delete");i.addEventListener("change",()=>{e.items[a].checked=i.checked,scheduleTodoSave(t,e),r.classList.toggle("is-checked",i.checked)}),l.addEventListener("input",()=>{e.items[a].text=l.value,scheduleTodoSave(t,e)}),s.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),e.items.splice(a,1),renderTodoModalChecklist(t,e),scheduleTodoSave(t,e)}),r.addEventListener("dragstart",t=>{r.classList.add("is-dragging"),t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("text/plain",String(a))}),r.addEventListener("dragend",()=>{r.classList.remove("is-dragging")}),o.appendChild(r)}),o.dataset.dndInit||(o.addEventListener("dragover",t=>{t.preventDefault();const e=o.querySelector(".todo-checklist-row.is-dragging");if(!e)return;const n=getDragAfterElement(o,t.clientY);null==n?o.appendChild(e):o.insertBefore(e,n)},{passive:!1}),o.addEventListener("drop",e=>{e.preventDefault();const n=t&&t.currentTodo?t.currentTodo:null;if(!n)return;const a=Array.from(o.querySelectorAll(".todo-checklist-row")),r=[];a.forEach(t=>{const e=Number(t.dataset.index);!Number.isNaN(e)&&n.items&&n.items[e]&&r.push(n.items[e])}),n.items=r,renderTodoModalChecklist(t,n),scheduleTodoSave(t,n)}),o.dataset.dndInit="1")}function getDragAfterElement(t,e){return[...t.querySelectorAll(".todo-checklist-row:not(.is-dragging)")].reduce((t,o)=>{const n=o.getBoundingClientRect(),a=e-n.top-n.height/2;return a<0&&a>t.offset?{offset:a,element:o}:t},{offset:Number.NEGATIVE_INFINITY,element:null}).element}async function openTodoModal(t){const e=document.querySelector(".todo-modal-overlay");if(!e)return;const o=e.querySelector(".note-modal"),n=e.querySelector("#todo-modal-title"),a=e.querySelector("#todo-modal-tags"),r=e.querySelector("#todo-modal-edit"),i=e.querySelector("#todo-modal-pin"),l=e.querySelector("#todo-modal-color-popup");e.currentTodo=t,o.className="note-modal todo-modal",applyNoteVisualState(o,t),o.dataset.todoId=t.id||"",o.dataset.editUrl=t.editUrl||"",o.dataset.deleteUrl=t.deleteUrl||"",o.dataset.background=t.background||"none";const s=(t.tags||[]).filter(t=>t&&!isTechnicalTag(t));o.dataset.tags=s.join("||"),n.textContent=t.title||window.ShaarliProI18n.t("Untitled"),renderModalTags(a,s),r&&(r.href=t.editUrl||"#"),l&&(l.innerHTML=generateUnifiedPaletteMenu({entityId:t&&t.id?t.id:"",editUrl:t&&t.editUrl?t.editUrl:"",currentColor:t&&t.color?t.color:"default",currentFilter:t&&t.filter?t.filter:"none",mode:"modal"}),l.classList.remove("open")),setModalPinButtonState(i,!!t.isPinned),e.classList.add("open"),renderTodoModalChecklist(e,t);const d=`${t.id}-${Date.now()}`;if(e._todoLoadKey=d,t.editUrl&&"#"!==t.editUrl)try{const o=await fetch(t.editUrl,{credentials:"same-origin"});if(!o.ok)return void console.error("Todo modal load failed (edit form fetch not ok).",{id:t&&t.id,url:t&&t.editUrl,status:o&&o.status});const n=await o.text();if(e._todoLoadKey!==d)return;const a=new DOMParser,r=a.parseFromString(n,"text/html").querySelector('form[name="linkform"]');if(!r)return void console.error("Todo modal load failed (edit form not found).",{id:t&&t.id,url:t&&t.editUrl,status:o&&o.status});const i=new URLSearchParams;r.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&i.append(t.name,t.value||"on"):t.name&&i.append(t.name,getFormFieldValue(t))}),t._todoEditAction=r.action,t._todoEditBaseData=i;const l=parseTodoMarkdown(i.get("lf_description")||"");t._todoHeaderLines=l.headerLines,t._todoFooterLines=l.footerLines,t.items=l.items,renderTodoModalChecklist(e,t)}catch(t){console.error("Error loading todo markdown:",t)}}function addTodoItem(t,e){e.items||(e.items=[]),e.items.push({checked:!1,text:""}),renderTodoModalChecklist(t,e);const o=t.querySelectorAll(".todo-item-text"),n=o&&o.length?o[o.length-1]:null;n&&n.focus(),scheduleTodoSave(t,e)}function scheduleTodoSave(t,e){t&&e&&(t._todoSaveTimer&&clearTimeout(t._todoSaveTimer),updateTodoCardPreview(e),t._todoSaveTimer=setTimeout(()=>{persistTodoChanges(e).catch(t=>{console.error("Error saving todo:",t),alert(window.ShaarliProI18n.t("Error saving todo.")+" "+window.ShaarliProI18n.t("Please refresh the page."))})},600))}function updateTodoCardPreview(t){if(!t||!t.id)return;let e=t._todoCardEl&&t._todoCardEl.isConnected?t._todoCardEl:null;if(e||(e=document.querySelector(`.note-card.todo-card[data-id="${String(t.id)}"]`)),!e){e=Array.from(document.querySelectorAll(".note-card.todo-card")).find(e=>String(e.dataset.id||"")===String(t.id))||null}if(!e)return;const o=e.querySelector(".todo-checklist-preview-wrap");o&&(o.innerHTML=buildTodoPreviewHtml(t.items||[]))}async function persistTodoChanges(t,e=0){if(!t||!t.editUrl||"#"===t.editUrl)return;const o=async()=>{const e=await fetch(t.editUrl,{credentials:"same-origin"}),o=await e.text(),n=(new DOMParser).parseFromString(o,"text/html").querySelector('form[name="linkform"]');if(!n)throw new Error("Could not find edit form");const a=new URLSearchParams;n.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&a.append(t.name,t.value||"on"):t.name&&a.append(t.name,getFormFieldValue(t))}),t._todoEditAction=n.action,t._todoEditBaseData=a;const r=parseTodoMarkdown(a.get("lf_description")||"");t._todoHeaderLines=r.headerLines,t._todoFooterLines=r.footerLines};t._todoEditAction&&t._todoEditBaseData&&t._todoEditBaseData.get&&t._todoEditBaseData.get("token")||await o();const n=buildTodoMarkdown(t),a=new URLSearchParams(t._todoEditBaseData.toString());a.set("lf_description",n);let r=(a.get("lf_tags")||"").trim().split(/[\s,]+/).filter(t=>""!==t.trim());r=r.filter(t=>"note"!==t&&"shaarli-note"!==t),r.includes("shaarli-todo")||r.push("shaarli-todo"),a.set("lf_tags",r.join(" ")),a.append("save_edit","1");const i=await fetch(t._todoEditAction,{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:a.toString()});if(!i.ok){if(403===i.status&&e<1)return t._todoEditAction="",t._todoEditBaseData=null,await o(),persistTodoChanges(t,e+1);throw new Error("Failed to save todo")}}function initNoteView(t,e){document.body.classList.add("view-notes");"undefined"!=typeof shaarli&&shaarli.basePath&&shaarli.basePath;const o=document.querySelector(".content-toolbar");o&&(o.style.display="none");const n=document.createElement("div");n.className="notes-wrapper";const a=document.createElement("div");a.className="notes-top-bar";const r=document.createElement("div");r.className="notes-top-bar-inner";const i=document.createElement("div");i.className="note-input-container";const l=()=>{i.classList.remove("is-editing","is-enhanced","todo-draft-mode"),applyNoteVisualState(i,{color:"default",filter:"none",background:"none",fontColor:"auto"}),i.innerHTML=`\n <div class="note-input-collapsed">\n <span class="note-input-placeholder">${window.ShaarliProI18n.t("Create a note...")}</span>\n <div class="note-input-actions note-input-type-actions">\n <button type="button" class="note-create-note-btn" title=window.ShaarliProI18n.t("Create a note")><i class="mdi mdi-note-outline"></i></button>\n </div>\n </div>\n `;const t=i.querySelector(".note-input-collapsed"),e=i.querySelector(".note-create-note-btn"),o=(t="note")=>{if("list"===t){i.classList.add("is-editing","todo-draft-mode"),i.innerHTML=`\n <div class="note-input-expanded todo-draft-expanded">\n <input type="text" class="note-input-title todo-draft-title" placeholder=window.ShaarliProI18n.t("List title") autocomplete="off" />\n <div class="todo-draft-list" role="list"></div>\n <button type="button" class="todo-draft-add-btn"><i class="mdi mdi-plus"></i> ${window.ShaarliProI18n.t("Add list item")}</button>\n <div class="note-input-expanded-actions">\n <div class="note-input-actions-left">\n <button type="button" class="note-input-palette-btn" title=window.ShaarliProI18n.t("Color")><i class="mdi mdi-palette-outline"></i></button>\n </div>\n <button type="button" class="note-input-close-btn">Fermer</button>\n </div>\n </div>\n `;const t=i.querySelector(".todo-draft-title"),e=i.querySelector(".todo-draft-list"),o=i.querySelector(".todo-draft-add-btn"),n=i.querySelector(".note-input-close-btn"),a=i.querySelector(".note-input-palette-btn");let r=!1,s=!1,d={color:"default",filter:"none",background:"none",fontColor:"auto"};applyNoteVisualState(i,d);const c=(t={text:"",checked:!1},o=!1)=>{if(!e)return null;const n=document.createElement("div");n.className="todo-draft-row",n.innerHTML=`\n <label class="todo-checklist-box" title=window.ShaarliProI18n.t("Mark as completed")>\n <input type="checkbox" class="todo-item-checkbox" ${t.checked?"checked":""} />\n <span class="todo-checklist-box-ui"></span>\n </label>\n <input type="text" class="todo-item-text" placeholder=window.ShaarliProI18n.t("List item") value="${escapeHtml(t.text||"")}" />\n <button type="button" class="todo-item-delete" title=window.ShaarliProI18n.t("Delete")><i class="mdi mdi-close"></i></button>\n `,e.appendChild(n);const a=n.querySelector(".todo-item-checkbox"),i=n.querySelector(".todo-item-text"),l=n.querySelector(".todo-item-delete"),s=()=>{n.classList.toggle("is-checked",!(!a||!a.checked))};return s(),a?.addEventListener("change",()=>{r=!0,s()}),i?.addEventListener("input",()=>{r=!0}),l?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),r=!0,n.remove(),e.querySelector(".todo-draft-row")||c({text:"",checked:!1},!0)}),o&&i&&i.focus({preventScroll:!0}),n},u=()=>e?Array.from(e.querySelectorAll(".todo-draft-row")).map(t=>{const e=t.querySelector(".todo-item-checkbox"),o=t.querySelector(".todo-item-text"),n=o&&"string"==typeof o.value?o.value.trim():"";return{checked:!(!e||!e.checked),text:n}}).filter(t=>t.text):[];c({text:"",checked:!1},!1),o?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),r=!0,c({text:"",checked:!1},!0)}),t?.addEventListener("input",()=>{r=!0});const m=async()=>{if(s)return;const e=t&&"string"==typeof t.value?t.value.trim():"",o=u();if(!e&&0===o.length)return document.removeEventListener("pointerdown",p,!0),void l();if(!r)return document.removeEventListener("pointerdown",p,!0),void l();s=!0;try{const t=o.map(t=>`- [${t.checked?"x":" "}] ${t.text}`).join("\n");await createNewNoteViaForm({title:e,markdown:t,visual:d}),window.location.reload()}catch(t){console.error("Error creating checklist note:",t),alert(window.ShaarliProI18n.t("Error creating checklist note.")),s=!1}};n?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),m()});const p=t=>{t.target&&t.target.closest&&t.target.closest("#shaarli-bg-studio")||t.target&&t.target.closest&&t.target.closest(".bg-studio-panel")||i.contains(t.target)||m()};return document.addEventListener("pointerdown",p,!0),a?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),openBackgroundStudioPanel({anchorEl:a,mode:"draft",entityId:"draft-new-todo-from-note",editUrl:"",currentColor:d.color||"default",currentFilter:d.filter||"none",currentBackground:d.background||"none",currentFontColor:d.fontColor||"auto",title:window.ShaarliProI18n.t("My images & colors")});const e=document.getElementById("shaarli-bg-studio");e&&(e.__draftApply=t=>{d={...d,...t||{}},applyNoteVisualState(i,d)})}),void t?.focus({preventScroll:!0})}i.classList.add("is-editing"),i.innerHTML='\n <div class="note-input-expanded">\n <input type="text" class="note-input-title" placeholder=window.ShaarliProI18n.t("Title") />\n <textarea class="note-input-description-source" rows="8" placeholder=window.ShaarliProI18n.t("Write your note in Markdown...")></textarea>\n <div class="note-formatting-bar" aria-hidden="true">\n <button type="button" class="note-format-btn" data-note-format="h1" title=window.ShaarliProI18n.t("Heading 1")>H1</button>\n <button type="button" class="note-format-btn" data-note-format="h2" title=window.ShaarliProI18n.t("Heading 2")>H2</button>\n <button type="button" class="note-format-btn" data-note-format="h3" title=window.ShaarliProI18n.t("Heading 3")>H3</button>\n <button type="button" class="note-format-btn" data-note-format="p" title=window.ShaarliProI18n.t("Text")>Aa</button>\n <span class="note-format-sep" aria-hidden="true"></span>\n <button type="button" class="note-format-btn" data-note-format="bold" title=window.ShaarliProI18n.t("Bold")><b>B</b></button>\n <button type="button" class="note-format-btn" data-note-format="italic" title=window.ShaarliProI18n.t("Italic")><i>I</i></button>\n <button type="button" class="note-format-btn" data-note-format="underline" title=window.ShaarliProI18n.t("Underline")><u>U</u></button>\n <button type="button" class="note-format-btn" data-note-format="strike" title=window.ShaarliProI18n.t("Strikethrough")><s>S</s></button>\n <button type="button" class="note-format-btn" data-note-format="code" title=window.ShaarliProI18n.t("Inline code")><i class="mdi mdi-code-tags"></i></button>\n <span class="note-format-sep" aria-hidden="true"></span>\n <button type="button" class="note-format-btn" data-note-format="ul" title=window.ShaarliProI18n.t("Bulleted list")><i class="mdi mdi-format-list-bulleted"></i></button>\n <button type="button" class="note-format-btn" data-note-format="ol" title=window.ShaarliProI18n.t("Numbered list")><i class="mdi mdi-format-list-numbered"></i></button>\n <button type="button" class="note-format-btn" data-note-format="todo" title=window.ShaarliProI18n.t("Checklist")><i class="mdi mdi-format-list-checks"></i></button>\n <button type="button" class="note-format-btn" data-note-format="quote" title=window.ShaarliProI18n.t("Quote")><i class="mdi mdi-format-quote-open"></i></button>\n <button type="button" class="note-format-btn" data-note-format="link" title=window.ShaarliProI18n.t("Link")><i class="mdi mdi-link-variant"></i></button>\n <button type="button" class="note-format-btn" data-note-format="image" title=window.ShaarliProI18n.t("Image")><i class="mdi mdi-image-outline"></i></button>\n <button type="button" class="note-format-btn" data-note-format="codeblock" title=window.ShaarliProI18n.t("Code block")><i class="mdi mdi-code-braces"></i></button>\n <button type="button" class="note-format-btn" data-note-format="clear" title=window.ShaarliProI18n.t("Clear formatting")>X</button>\n </div>\n <div class="note-input-expanded-actions">\n <div class="note-input-actions-left">\n <button type="button" class="note-input-format-btn" title=window.ShaarliProI18n.t("Formatting options")><i class="mdi mdi-format-text"></i></button>\n <button type="button" class="note-input-palette-btn" title=window.ShaarliProI18n.t("Color")><i class="mdi mdi-palette-outline"></i></button>\n </div>\n <button type="button" class="note-input-close-btn">Fermer</button>\n </div>\n </div>\n ';const e=i.querySelector(".note-input-title"),o=i.querySelector(".note-input-description-source"),n=i.querySelector(".note-input-close-btn"),a=i.querySelector(".note-input-palette-btn"),r=i.querySelector(".note-input-format-btn"),s=i.querySelector(".note-formatting-bar");let d=!1,c=!1,u={color:"default",filter:"none",background:"none",fontColor:"auto"};applyNoteVisualState(i,u);r?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=s&&s.classList.contains("open");var o;o=!e,s&&(o?(s.classList.add("open"),s.setAttribute("aria-hidden","false"),i.classList.add("show-formatting")):(s.classList.remove("open"),s.setAttribute("aria-hidden","true"),i.classList.remove("show-formatting")))}),i.querySelectorAll(".note-format-btn").forEach(t=>{t.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),o&&(applyKeepNoteFormatting(o,t.dataset.noteFormat||""),d=!0)})}),e?.addEventListener("input",()=>{d=!0}),o?.addEventListener("input",()=>{d=!0});const m=async()=>{if(c)return;const{title:t,markdown:n}={title:e&&"string"==typeof e.value?e.value.trim():"",markdown:o&&"string"==typeof o.value?o.value.trim():""};if(!t&&!n)return document.removeEventListener("pointerdown",p,!0),void l();if(!d)return document.removeEventListener("pointerdown",p,!0),void l();c=!0;try{await createNewNoteViaForm({title:t,markdown:n,visual:u}),window.location.reload()}catch(t){console.error("Error creating note:",t),alert(window.ShaarliProI18n.t("Error creating note.")),c=!1}};n?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),m()});const p=t=>{t.target&&t.target.closest&&t.target.closest("#shaarli-bg-studio")||t.target&&t.target.closest&&t.target.closest(".bg-studio-panel")||t.target&&t.target.closest&&t.target.closest(".note-formatting-bar")||i.contains(t.target)||m()};document.addEventListener("pointerdown",p,!0),a?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),openBackgroundStudioPanel({anchorEl:a,mode:"draft",entityId:"draft-new-note",editUrl:"",currentColor:u.color||"default",currentFilter:u.filter||"none",currentBackground:u.background||"none",currentFontColor:u.fontColor||"auto",title:window.ShaarliProI18n.t("My images & colors")});const e=document.getElementById("shaarli-bg-studio");e&&(e.__draftApply=t=>{u={...u,...t||{}},applyNoteVisualState(i,u)})}),e?.focus({preventScroll:!0})};t?.addEventListener("click",t=>{t.target.closest("button")||o("note")}),e?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),o("note")})};l(),r.appendChild(i),a.appendChild(r);const s=document.createElement("div");s.className="notes-tools",s.innerHTML='\n <button class="icon-btn active" id="btn-view-grid" title=window.ShaarliProI18n.t("Grid view")><i class="mdi mdi-view-dashboard-outline"></i></button>\n <button class="icon-btn" id="btn-view-list" title=window.ShaarliProI18n.t("List view")><i class="mdi mdi-view-agenda-outline"></i></button>\n ',a.appendChild(s),n.appendChild(a);const d=document.createElement("div");d.className="notes-content-area";const c=Array.from(t.querySelectorAll(".link-outer")).map(t=>parseNoteFromLink(t));renderNotes(d,c,"grid"),n.appendChild(d),t.style.display="none",t.parentNode?t.parentNode.insertBefore(n,t):e.appendChild(n);const u=window.location.hash;if(u&&u.startsWith("#open-note-")){const t=u.replace("#open-note-",""),e=c.find(e=>String(e.id)===String(t));e&&(history.replaceState(null,null,window.location.pathname+window.location.search),setTimeout(()=>{openNoteModal(e)},100))}const m=document.createElement("div");m.className="note-modal-overlay",m.innerHTML='\n <div class="note-modal" role="dialog" aria-modal="true">\n <div class="note-modal-header">\n <input type="text" class="note-title note-modal-title-input" id="note-modal-title" placeholder=window.ShaarliProI18n.t("Title") />\n <button type="button" class="note-modal-pin-toggle" id="note-modal-pin" title=window.ShaarliProI18n.t("Pin")>\n <i class="mdi mdi-pin-outline"></i>\n </button>\n </div>\n <div class="note-modal-content">\n <div class="note-modal-description-preview note-body" id="note-modal-description-preview" role="button" tabindex="0" aria-label=window.ShaarliProI18n.t("Click to edit")></div>\n <textarea class="note-modal-description-source" id="note-modal-description-source" rows="8"></textarea>\n <div class="note-formatting-bar" id="note-modal-formatting" aria-hidden="true">\n <button type="button" class="note-format-btn" data-note-format="h1" title=window.ShaarliProI18n.t("Heading 1")>H1</button>\n <button type="button" class="note-format-btn" data-note-format="h2" title=window.ShaarliProI18n.t("Heading 2")>H2</button>\n <button type="button" class="note-format-btn" data-note-format="h3" title=window.ShaarliProI18n.t("Heading 3")>H3</button>\n <button type="button" class="note-format-btn" data-note-format="p" title=window.ShaarliProI18n.t("Text")>Aa</button>\n <span class="note-format-sep" aria-hidden="true"></span>\n <button type="button" class="note-format-btn" data-note-format="bold" title=window.ShaarliProI18n.t("Bold")><b>B</b></button>\n <button type="button" class="note-format-btn" data-note-format="italic" title=window.ShaarliProI18n.t("Italic")><i>I</i></button>\n <button type="button" class="note-format-btn" data-note-format="underline" title=window.ShaarliProI18n.t("Underline")><u>U</u></button>\n <button type="button" class="note-format-btn" data-note-format="strike" title=window.ShaarliProI18n.t("Strikethrough")><s>S</s></button>\n <button type="button" class="note-format-btn" data-note-format="code" title=window.ShaarliProI18n.t("Inline code")><i class="mdi mdi-code-tags"></i></button>\n <span class="note-format-sep" aria-hidden="true"></span>\n <button type="button" class="note-format-btn" data-note-format="ul" title=window.ShaarliProI18n.t("Bulleted list")><i class="mdi mdi-format-list-bulleted"></i></button>\n <button type="button" class="note-format-btn" data-note-format="ol" title=window.ShaarliProI18n.t("Numbered list")><i class="mdi mdi-format-list-numbered"></i></button>\n <button type="button" class="note-format-btn" data-note-format="todo" title=window.ShaarliProI18n.t("Checklist")><i class="mdi mdi-format-list-checks"></i></button>\n <button type="button" class="note-format-btn" data-note-format="quote" title=window.ShaarliProI18n.t("Quote")><i class="mdi mdi-format-quote-open"></i></button>\n <button type="button" class="note-format-btn" data-note-format="link" title=window.ShaarliProI18n.t("Link")><i class="mdi mdi-link-variant"></i></button>\n <button type="button" class="note-format-btn" data-note-format="image" title=window.ShaarliProI18n.t("Image")><i class="mdi mdi-image-outline"></i></button>\n <button type="button" class="note-format-btn" data-note-format="codeblock" title=window.ShaarliProI18n.t("Code block")><i class="mdi mdi-code-braces"></i></button>\n <button type="button" class="note-format-btn" data-note-format="clear" title=window.ShaarliProI18n.t("Clear formatting")>X</button>\n </div>\n </div>\n <div class="note-modal-tags is-empty" id="note-modal-tags"></div>\n <div class="note-modal-actions">\n <div class="note-modal-actions-left">\n <div class="note-modal-color-picker">\n <button type="button" id="note-modal-color-btn" title=window.ShaarliProI18n.t("Color")><i class="mdi mdi-palette-outline"></i></button>\n <div class="palette-popup note-modal-palette" id="note-modal-color-popup"></div>\n </div>\n <button type="button" id="note-modal-format-btn" title=window.ShaarliProI18n.t("Formatting options")><i class="mdi mdi-format-text"></i></button>\n <button type="button" title=window.ShaarliProI18n.t("Reminder")><i class="mdi mdi-bell-outline"></i></button>\n <button type="button" title=window.ShaarliProI18n.t("Collaborator")><i class="mdi mdi-account-plus-outline"></i></button>\n <button type="button" title=window.ShaarliProI18n.t("Image")><i class="mdi mdi-image-outline"></i></button>\n <button type="button" id="note-modal-archive" title=window.ShaarliProI18n.t("Archive")><i class="mdi mdi-archive-arrow-down-outline"></i></button>\n <a href="#" id="note-modal-edit" title=window.ShaarliProI18n.t("Edit")><i class="mdi mdi-pencil-outline"></i></a>\n <button type="button" id="note-modal-delete" title=window.ShaarliProI18n.t("Delete")><i class="mdi mdi-delete-outline"></i></button>\n </div>\n <button type="button" class="note-modal-close-btn" id="note-modal-close">Fermer</button>\n </div>\n </div>\n ',document.body.appendChild(m);const p=n.querySelector("#btn-view-grid"),f=n.querySelector("#btn-view-list");p.addEventListener("click",()=>{p.classList.add("active"),f.classList.remove("active"),renderNotes(d,c,"grid")}),f.addEventListener("click",()=>{f.classList.add("active"),p.classList.remove("active"),renderNotes(d,c,"list")});const g=async()=>{try{await saveOpenNoteEditorModal(m),m.classList.remove("open"),document.body.classList.remove("note-modal-open")}catch(t){console.error("Error saving note from modal:",t),alert(window.ShaarliProI18n.t("Error saving note."))}};m.querySelector("#note-modal-close").addEventListener("click",t=>{t.preventDefault(),g()}),m.addEventListener("click",t=>{t.target===m&&g()}),m.querySelector("#note-modal-edit").addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=m.querySelector("#note-modal-title");e?.focus({preventScroll:!0})});const h=m.querySelector("#note-modal-pin"),y=m.querySelector("#note-modal-color-btn"),b=m.querySelector("#note-modal-color-popup");y.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=m.querySelector(".note-modal");openBackgroundStudioPanel({anchorEl:y,mode:"modal",entityId:e&&e.dataset.noteId||"",editUrl:e&&e.dataset.editUrl||"",currentColor:e?getElementVisualColor(e):"default",currentFilter:e?getElementVisualFilter(e):"none",currentBackground:e?getElementVisualBackground(e):"none",currentFontColor:e?getElementVisualFontColor(e):"auto",title:window.ShaarliProI18n.t("My images & colors")})}),h.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=m.querySelector(".note-modal"),o=e.dataset.noteId,n=e.dataset.editUrl;if(!o||!n)return;togglePinTag(o,n,h);const a=h.classList.contains("active");let r=(e.dataset.tags||"").split("||").filter(t=>t);a?r.includes("shaarli-pin")||r.push("shaarli-pin"):r=r.filter(t=>"shaarli-pin"!==t),e.dataset.tags=r.join("||"),renderModalTags(m.querySelector("#note-modal-tags"),r),m.currentNote&&(m.currentNote.isPinned=a,m.currentNote.tags=r)}),m.querySelector("#note-modal-delete").addEventListener("click",()=>{if(!confirm(window.ShaarliProI18n.t("Delete this note?")))return;const t=m.querySelector(".note-modal"),e=t.dataset.deleteUrl;t.dataset.noteId;e&&"#"!==e&&deleteEntitySilently(e).then(()=>{window.location.href="/?searchtags=note"}).catch(t=>{console.error("Delete failed:",t),alert(window.ShaarliProI18n.t("Error deleting."))})}),m.querySelector("#note-modal-archive").addEventListener("click",t=>{t.preventDefault();const e=m.querySelector(".note-modal"),o=e.dataset.noteId,n=e.dataset.editUrl;o&&n&&addTagToNote(n,"shaarli-archive").then(()=>{m.currentNote&&(m.currentNote.tags.includes("shaarli-archive")||m.currentNote.tags.push("shaarli-archive"));const t=document.querySelector(`.note-card[data-id="${o}"]`);t&&t.remove();const e=c.findIndex(t=>String(t.id)===String(o));e>-1&&c.splice(e,1),m.classList.remove("open"),document.body.classList.remove("note-modal-open")}).catch(t=>{console.error("Error archiving note:",t),alert(window.ShaarliProI18n.t("Error archiving note."))})}),m.addEventListener("click",t=>{t.target.closest(".note-modal-color-picker")||b.classList.remove("open")}),document.addEventListener("click",t=>{t.target.closest(".note-hover-actions .palette-popup")&&!t.target.closest('.note-hover-actions [id^="palette-"]')&&document.querySelectorAll(".note-hover-actions .palette-popup.open").forEach(t=>{t.classList.remove("open")})})}function initArchiveView(t,e){document.body.classList.add("view-notes","view-archive");const o=document.querySelector(".content-toolbar");o&&(o.style.display="none");const n=document.createElement("div");n.className="notes-wrapper archive-wrapper";const a=document.createElement("div");a.className="notes-top-bar archive-top-bar";const r=document.createElement("div");r.className="archive-title-container",r.innerHTML=`\n <h1 class="archive-title"><i class="mdi mdi-archive-arrow-down-outline"></i> Archive</h1>\n <p class="archive-subtitle">${window.ShaarliProI18n.t("Archived notes")}</p>\n `,a.appendChild(r);const i=document.createElement("div");i.className="notes-tools",i.innerHTML='\n <button class="icon-btn active" id="btn-view-grid" title=window.ShaarliProI18n.t("Grid view")><i class="mdi mdi-view-dashboard-outline"></i></button>\n <button class="icon-btn" id="btn-view-list" title=window.ShaarliProI18n.t("List view")><i class="mdi mdi-view-agenda-outline"></i></button>\n ',a.appendChild(i),n.appendChild(a);const l=document.createElement("div");l.className="notes-content-area";const s=Array.from(t.querySelectorAll(".link-outer")).map(t=>parseNoteFromLink(t)).filter(t=>(t.tags||[]).some(t=>"shaarli-archive"===t||"shaarli-archiver"===t));renderNotes(l,s,"grid",!0),n.appendChild(l),t.style.display="none",t.parentNode?t.parentNode.insertBefore(n,t):e.appendChild(n);const d=document.createElement("div");d.className="note-modal-overlay",d.innerHTML='\n <div class="note-modal note-color-default">\n <div class="note-modal-header">\n <h2 class="note-title" id="note-modal-title"></h2>\n <button type="button" class="note-modal-pin-toggle" id="note-modal-pin" title=window.ShaarliProI18n.t("Pin")>\n <i class="mdi mdi-pin-outline"></i>\n </button>\n </div>\n <div class="note-modal-content"></div>\n <div class="note-modal-tags is-empty" id="note-modal-tags"></div>\n <div class="note-modal-actions">\n <div class="note-modal-actions-left">\n <div class="note-modal-color-picker">\n <button type="button" id="note-modal-color-btn" title=window.ShaarliProI18n.t("Color")><i class="mdi mdi-palette-outline"></i></button>\n <div class="palette-popup note-modal-palette" id="note-modal-color-popup"></div>\n </div>\n <button type="button" title=window.ShaarliProI18n.t("Reminder")><i class="mdi mdi-bell-outline"></i></button>\n <button type="button" title=window.ShaarliProI18n.t("Collaborator")><i class="mdi mdi-account-plus-outline"></i></button>\n <button type="button" title=window.ShaarliProI18n.t("Image")><i class="mdi mdi-image-outline"></i></button>\n <button type="button" id="note-modal-unarchive" title=window.ShaarliProI18n.t("Unarchive")><i class="mdi mdi-archive-arrow-up-outline"></i></button>\n <a href="#" id="note-modal-edit" title=window.ShaarliProI18n.t("Edit")><i class="mdi mdi-pencil-outline"></i></a>\n <button type="button" id="note-modal-delete" title=window.ShaarliProI18n.t("Delete")><i class="mdi mdi-delete-outline"></i></button>\n </div>\n <button type="button" class="note-modal-close-btn" id="note-modal-close">Fermer</button>\n </div>\n </div>\n ',document.body.appendChild(d);const c=n.querySelector("#btn-view-grid"),u=n.querySelector("#btn-view-list");c.addEventListener("click",()=>{c.classList.add("active"),u.classList.remove("active"),renderNotes(l,s,"grid",!0)}),u.addEventListener("click",()=>{u.classList.add("active"),c.classList.remove("active"),renderNotes(l,s,"list",!0)}),d.querySelector("#note-modal-close").addEventListener("click",()=>{d.classList.remove("open")}),d.addEventListener("click",t=>{t.target===d&&d.classList.remove("open")});const m=d.querySelector("#note-modal-pin"),p=d.querySelector("#note-modal-color-btn"),f=d.querySelector("#note-modal-color-popup");p.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=d.querySelector(".note-modal");openBackgroundStudioPanel({anchorEl:p,mode:"modal",entityId:e&&e.dataset.noteId||"",editUrl:e&&e.dataset.editUrl||"",currentColor:e?getElementVisualColor(e):"default",currentFilter:e?getElementVisualFilter(e):"none",currentBackground:e?getElementVisualBackground(e):"none",currentFontColor:e?getElementVisualFontColor(e):"auto",title:window.ShaarliProI18n.t("My images & colors")})}),m.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const e=d.querySelector(".note-modal"),o=e.dataset.noteId,n=e.dataset.editUrl;if(!o||!n)return;togglePinTag(o,n,m);const a=m.classList.contains("active");let r=(e.dataset.tags||"").split("||").filter(t=>t);a?r.includes("shaarli-pin")||r.push("shaarli-pin"):r=r.filter(t=>"shaarli-pin"!==t),e.dataset.tags=r.join("||"),renderModalTags(d.querySelector("#note-modal-tags"),r),d.currentNote&&(d.currentNote.isPinned=a,d.currentNote.tags=r)}),d.querySelector("#note-modal-delete").addEventListener("click",()=>{if(!confirm(window.ShaarliProI18n.t("Delete this note?")))return;const t=d.querySelector(".note-modal"),e=t.dataset.deleteUrl;t.dataset.noteId;e&&"#"!==e&&deleteEntitySilently(e).then(()=>{window.location.href="/?searchtags=shaarli-archive"}).catch(t=>{console.error("Delete failed:",t),alert(window.ShaarliProI18n.t("Error deleting."))})}),d.querySelector("#note-modal-unarchive").addEventListener("click",t=>{t.preventDefault();const e=d.querySelector(".note-modal"),o=e.dataset.noteId,n=e.dataset.editUrl;o&&n&&removeTagFromEntity(n,"shaarli-archive").then(()=>{d.currentNote&&(d.currentNote.tags=(d.currentNote.tags||[]).filter(t=>"shaarli-archive"!==t));const t=document.querySelector(`.note-card[data-id="${o}"]`);t&&t.remove();const e=s.findIndex(t=>String(t.id)===String(o));e>-1&&s.splice(e,1),d.classList.remove("open")}).catch(t=>{console.error("Error unarchiving note:",t),alert(window.ShaarliProI18n.t("Error unarchiving note."))})}),d.addEventListener("click",t=>{t.target.closest(".note-modal-color-picker")||f.classList.remove("open")}),document.addEventListener("click",t=>{t.target.closest(".note-hover-actions .palette-popup")&&!t.target.closest('.note-hover-actions [id^="palette-"]')&&document.querySelectorAll(".note-hover-actions .palette-popup.open").forEach(t=>{t.classList.remove("open")})})}function parseNoteFromLink(t){const e=t.dataset.id,o=t.querySelector(".link-title"),n=o?o.textContent.trim():"",a=t.querySelector(".link-description"),r=a?a.innerHTML:"",i=a?a.textContent:"";let l=null;if(a){const t=a.querySelector("img");t&&(l=t.src)}const s=t.querySelector(".link-url"),d=s?s.textContent.trim():"",c=[];t.querySelectorAll(".link-tag-list a").forEach(t=>{const e=(t.textContent||"").trim();e&&c.push(e)});const{color:u,filter:m,background:p,fontColor:f}=extractNoteVisualStateFromTags(c),g=c.filter(t=>!t.startsWith("note-color-")&&(!t.startsWith("note-custom-")&&(!(t=>{if("string"!=typeof t)return!1;if(!t.startsWith("note-"))return!1;const e=t.substring(5);return NOTE_COLOR_OPTIONS.some(t=>t.key===e)})(t)&&(!t.startsWith("notefilter-")&&(!t.startsWith("notebg-")&&!t.startsWith("font-")))))),h=(g.includes("shaarli-pin"),t.querySelector(".link-actions")),y=h&&h.querySelector('a[href*="admin/shaare"]')?h.querySelector('a[href*="admin/shaare"]').href:"#",b=h&&h.querySelector('a[href*="delete"]')?h.querySelector('a[href*="delete"]').href:"#",v=h&&h.querySelector('a[href*="pin"]')?h.querySelector('a[href*="pin"]').href:"#",w=g.includes("shaarli-pin");return{id:e,title:n,descHtml:r,descText:i,coverImage:l,url:d,tags:g,color:u,filter:m,background:p,fontColor:f,editUrl:y,deleteUrl:b,pinUrl:v,isPinned:w}}function renderNotes(t,e,o,n=!1){let a;t.innerHTML="",t.className="grid"===o?"notes-masonry":"notes-list-view",a=n?e.filter(t=>(t.tags||[]).some(t=>"shaarli-archive"===t||"shaarli-archiver"===t)):e.filter(t=>!(t.tags||[]).some(t=>"shaarli-archive"===t||"shaarli-archiver"===t)),a.sort((t,e)=>{const o=t.tags.includes("shaarli-pin");return e.tags.includes("shaarli-pin")-o}),a.forEach(e=>{const a=document.createElement("div");if(a.className="note-card",a.dataset.id=e.id,a.dataset.editUrl=e.editUrl||"",a.dataset.tags=(e.tags||[]).filter(t=>t).join("||"),applyNoteVisualState(a,e),"list"===o&&a.classList.add("list-mode"),a.addEventListener("click",t=>{t.target.closest("button")||t.target.closest("a")||t.target.closest(".note-hover-actions")||(syncNoteFromCardElement(e,a),openNoteModal(e))}),e.coverImage&&"grid"===o){const t=document.createElement("div");t.className="note-cover",t.innerHTML=`<img src="${e.coverImage}" alt="Cover">`,a.appendChild(t)}const r=document.createElement("div");if(r.className="note-inner",e.title){const t=document.createElement("h3");t.className="note-title",t.textContent=e.title,r.appendChild(t)}if(e.descHtml||e.descText||e._noteMarkdown){const t=document.createElement("div");if(t.className="note-body",void 0!==e._noteMarkdown)t.innerHTML=renderMarkdown(e._noteMarkdown);else{const o=e.descText||"";o.trim().startsWith('<div class="markdown">')||o.trim().startsWith("<")?t.innerHTML=o:t.innerHTML=renderMarkdown(o)}r.appendChild(t)}if(e.tags.length>0){const t=document.createElement("div");t.className="note-tags",e.tags.forEach(o=>{if(isTechnicalTag(o))return;const n=createTagPill({tag:o,onRemoveClass:"note-tag-remove-btn",tagClass:"note-tag",canRemove:!!e.editUrl&&"#"!==e.editUrl});t.appendChild(n)}),r.appendChild(t)}const i=document.createElement("div");i.className="note-hover-actions";const l=document.createElement("a");l.href=e.pinUrl,l.title=e.isPinned?"Unpin":"Pin",l.className="note-pin-corner "+(e.isPinned?"active":""),l.innerHTML=`<i class="mdi mdi-pin${e.isPinned?"":"-outline"}"></i>`,r.appendChild(l);const s=`palette-${e.id}`,d=`archive-${e.id}`;i.innerHTML=`\n <button title=window.ShaarliProI18n.t("Reminder")><i class="mdi mdi-bell-outline"></i></button>\n <button title=window.ShaarliProI18n.t("Collaborator")><i class="mdi mdi-account-plus-outline"></i></button>\n <div style="position:relative;">\n <button title=window.ShaarliProI18n.t("Color") id="${s}"><i class="mdi mdi-palette-outline"></i></button>\n </div>\n <button title=window.ShaarliProI18n.t("Image")><i class="mdi mdi-image-outline"></i></button>\n <button title=window.ShaarliProI18n.t("Archive") id="${d}"><i class="mdi mdi-archive-arrow-down-outline"></i></button>\n <div class="spacer"></div>\n \x3c!-- Real Actions --\x3e\n <button type="button" class="note-open-editor-btn" title=window.ShaarliProI18n.t("Edit")><i class="mdi mdi-pencil-outline"></i></button>\n <button title=window.ShaarliProI18n.t("Delete") class="note-delete-btn"><i class="mdi mdi-delete-outline"></i></button>\n `;const c=i.querySelector(".note-delete-btn");c?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),confirm(window.ShaarliProI18n.t("Delete this note?"))&&deleteEntitySilently(e.deleteUrl).then(()=>{window.location.href=n?"/?searchtags=shaarli-archive":"/?searchtags=note"}).catch(t=>{console.error("Delete failed:",t),alert(window.ShaarliProI18n.t("Error deleting."))})});const u=i.querySelector(".note-open-editor-btn");u?.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),syncNoteFromCardElement(e,a),openNoteModal(e)});const m=i.querySelector(`#${s}`);m.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),openBackgroundStudioPanel({anchorEl:m,mode:"entity",entityId:e.id,editUrl:e.editUrl,currentColor:getElementVisualColor(a),currentFilter:getElementVisualFilter(a),currentBackground:getElementVisualBackground(a),title:window.ShaarliProI18n.t("My images & colors")})});i.querySelector(`#${d}`).addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),e.editUrl&&"#"!==e.editUrl&&addTagToNote(e.editUrl,"shaarli-archive").then(()=>{a.remove()}).catch(t=>{console.error("Error archiving note:",t),alert(window.ShaarliProI18n.t("Error archiving note."))})}),r.appendChild(i),a.appendChild(r),t.appendChild(a)})}function setModalPinButtonState(t,e){if(!t)return;t.classList.toggle("active",e),t.title=e?window.ShaarliProI18n.t("Unpin"):window.ShaarliProI18n.t("Pin");const o=t.querySelector("i");o&&(o.className="mdi "+(e?"mdi-pin":"mdi-pin-outline"))}function renderModalTags(t,e){if(!t)return;t.innerHTML="";const o=(e||[]).filter(t=>t&&!isTechnicalTag(t)),n=getModalCurrentEntity(t.closest(".note-modal-overlay")||getOpenModalOverlay()),a=!(!n||!n.editUrl||"#"===n.editUrl);0!==o.length?(t.classList.remove("is-empty"),o.forEach(e=>{const o=createTagPill({tag:e,onRemoveClass:"note-tag-remove-btn",tagClass:"note-tag",canRemove:a});t.appendChild(o)})):t.classList.add("is-empty")}function openNoteModal(t){const e=document.querySelector(".note-modal-overlay");if(!e)return;const o=e.querySelector(".note-modal"),n=e.querySelector("#note-modal-title"),a=e.querySelector("#note-modal-description-source"),r=e.querySelector("#note-modal-description-preview"),i=e.querySelector("#note-modal-tags"),l=e.querySelector("#note-modal-edit"),s=e.querySelector("#note-modal-pin"),d=e.querySelector("#note-modal-color-popup"),c=(e.querySelector("#note-modal-format-btn"),e.querySelector("#note-modal-formatting"),t=>{a&&r&&(t?(e.classList.add("note-modal-editing"),r.setAttribute("aria-hidden","true"),a.removeAttribute("aria-hidden")):(e.classList.remove("note-modal-editing"),r.setAttribute("aria-hidden","false"),a.setAttribute("aria-hidden","true")))});e.currentNote=t,o.className="note-modal",applyNoteVisualState(o,t),o.dataset.noteId=t.id||"",o.dataset.editUrl=t.editUrl||"",o.dataset.deleteUrl=t.deleteUrl||"",o.dataset.background=t.background||"none";const u=(t.tags||[]).filter(t=>t&&!isTechnicalTag(t));o.dataset.tags=u.join("||"),n&&(n.value=t.title||""),a&&(a.value=(t._noteMarkdown||t.descText||"").trim()),r&&(r.innerHTML=renderMarkdown((t._noteMarkdown||t.descText||"").trim())),c(!1),renderModalTags(i,u),l&&(l.href=t.editUrl||"#"),d&&(d.innerHTML=generateModalPaletteButtons(t),d.classList.remove("open")),setModalPinButtonState(s,!!t.isPinned),e._noteEditorState||(e._noteEditorState={hasChanges:!1,isSaving:!1,lastSavedTitle:"",lastSavedMarkdown:""});const m=e._noteEditorState;if(m.hasChanges=!1,m.lastSavedTitle=n&&"string"==typeof n.value?n.value.trim():"",m.lastSavedMarkdown=a&&"string"==typeof a.value?a.value.trim():"",!e._noteEditorBound){e._noteEditorBound=!0,n?.addEventListener("input",()=>{e._noteEditorState&&(e._noteEditorState.hasChanges=!0)}),a?.addEventListener("input",()=>{e._noteEditorState&&(e._noteEditorState.hasChanges=!0),r&&(r.innerHTML=renderMarkdown(a.value||""))}),r?.addEventListener("click",()=>{c(!0),a?.focus({preventScroll:!0})}),r?.addEventListener("keydown",t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),c(!0),a?.focus({preventScroll:!0}))}),a?.addEventListener("blur",()=>{c(!1)});const t=t=>{const o=e.querySelector("#note-modal-formatting");o&&(t?(o.classList.add("open"),o.setAttribute("aria-hidden","false"),e.classList.add("show-formatting")):(o.classList.remove("open"),o.setAttribute("aria-hidden","true"),e.classList.remove("show-formatting")))};e._setNoteModalFormattingVisible=t;const o=e.querySelector("#note-modal-format-btn");o?.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation();const n=e.querySelector("#note-modal-formatting"),a=n&&n.classList.contains("open");t(!a)}),e.querySelectorAll(".note-format-btn").forEach(t=>{t.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation();const n=e.querySelector("#note-modal-description-source");n&&(c(!0),applyKeepNoteFormatting(n,t.dataset.noteFormat||""),e._noteEditorState&&(e._noteEditorState.hasChanges=!0))})})}"function"==typeof e._setNoteModalFormattingVisible&&e._setNoteModalFormattingVisible(!1),hydrateNoteFromEditForm(t).then(()=>{e.currentNote===t&&(n&&t._noteTitle&&(n.value=t._noteTitle),a&&(a.value=(t._noteMarkdown||"").trim()),r&&(r.innerHTML=renderMarkdown(a?a.value:"")),c(!1),m.lastSavedTitle=n&&"string"==typeof n.value?n.value.trim():"",m.lastSavedMarkdown=a&&"string"==typeof a.value?a.value.trim():"")}),e.classList.add("open"),document.body.classList.add("note-modal-open"),n?.focus({preventScroll:!0})}async function saveOpenNoteEditorModal(t){if(!t||!t.currentNote)return;const e=t.currentNote,o=t.querySelector("#note-modal-title"),n=t.querySelector("#note-modal-description-source"),a=o&&"string"==typeof o.value?o.value.trim():"",r=n&&"string"==typeof n.value?n.value.trim():"",i=t._noteEditorState||{hasChanges:!1,isSaving:!1,lastSavedTitle:"",lastSavedMarkdown:""};if(!a&&!r)return;if(!(i.hasChanges||a!==(i.lastSavedTitle||"")||r!==(i.lastSavedMarkdown||""))||i.isSaving)return;i.isSaving=!0,t._noteEditorState=i,await hydrateNoteFromEditForm(e),await persistNoteChanges(e,{title:a,markdown:r}),e.title=a,e._noteTitle=a,e._noteMarkdown=r,e.descText=r;const l=document.querySelector(`.note-card[data-id="${CSS.escape(String(e.id))}"]`);if(l){const t=l.querySelector(".note-inner .note-title");t&&(t.textContent=a);const o=l.querySelector(".note-inner .note-body");o&&(o.innerHTML=renderMarkdown(r),e.descHtml=o.innerHTML)}i.lastSavedTitle=a,i.lastSavedMarkdown=r,i.hasChanges=!1,i.isSaving=!1}function generateModalPaletteButtons(t){return generateUnifiedPaletteMenu({entityId:t&&t.id?t.id:"",editUrl:t&&t.editUrl?t.editUrl:"",currentColor:t&&t.color?t.color:"default",currentFilter:t&&t.filter?t.filter:"none",mode:"modal"})}function generatePaletteButtons(t){return generateUnifiedPaletteMenu({entityId:t&&t.id?t.id:"",editUrl:t&&t.editUrl?t.editUrl:"",currentColor:t&&t.color?t.color:"default",currentFilter:t&&t.filter?t.filter:"none",mode:"entity"})}function addTagToNote(t,e){return fetch(t).then(t=>t.text()).then(t=>{const o=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!o)throw new Error("Could not find edit form");const n=new URLSearchParams;o.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&n.append(t.name,t.value||"on"):t.name&&n.append(t.name,getFormFieldValue(t))});let a=(n.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());return a.includes(e)||a.push(e),n.set("lf_tags",a.join(" ")),n.append("save_edit","1"),fetch(o.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to update tags");return t})}function initPinnedItems(){const t=document.querySelector(".links-list, .notes-masonry, .notes-list-view");if(!t)return;const e=Array.from(t.children),o=[];if(e.forEach(t=>{if(t.classList.contains("link-outer")||t.classList.contains("note-card")){let e=!1;t.innerHTML;const n=t.querySelectorAll(".link-tag-list a, .note-tag");for(let t of n)if("shaarli-pin"===t.textContent.trim()){e=!0;break}const a=t.querySelector(".mdi-pin-outline, .mdi-pin"),r=t.querySelector(".link-title, .note-title"),i=r?r.querySelector("i.mdi-pin"):null;if(e){if(o.push(t),t.classList.add("is-pinned-tag"),a&&(a.classList.remove("mdi-pin-outline"),a.classList.add("mdi-pin"),a.parentElement&&a.parentElement.classList.add("active")),r&&!i){const t=document.createElement("i");t.className="mdi mdi-pin",t.style.color="var(--primary)",t.style.marginRight="8px",r.prepend(t)}}else t.classList.remove("is-pinned-tag"),a&&(a.classList.remove("mdi-pin"),a.classList.add("mdi-pin-outline"),a.parentElement&&a.parentElement.classList.remove("active")),i&&i.remove()}}),t.classList.contains("links-list"))for(let e=o.length-1;e>=0;e--)t.prepend(o[e]);"function"==typeof organizePinnedBookmarks&&window.requestAnimationFrame(organizePinnedBookmarks),document.addEventListener("click",function(t){const e=t.target.closest('a[href*="do=pin"], .note-hover-actions a[href*="pin"], .note-pin-corner[href*="pin"], .link-actions a[href*="pin"]');if(e){t.preventDefault(),t.stopPropagation();const o=e.closest(".link-outer, .note-card"),n=o?o.dataset.id:null;let a=e.href.replace("do=pin","do=editlink").replace("pin","editlink");if(o){const t=o.querySelector('a[href*="edit_link"], a[href*="admin/shaare"]');t&&(a=t.href)}n&&a&&togglePinTag(n,a,e)}},{once:!1})}function togglePinTag(t,e,o){const n=o.querySelector("i");let a=!1;n&&(n.classList.contains("mdi-pin-outline")?(n.classList.remove("mdi-pin-outline"),n.classList.add("mdi-pin"),o.classList.add("active"),a=!0):(n.classList.remove("mdi-pin"),n.classList.add("mdi-pin-outline"),o.classList.remove("active"),a=!1));const r=o.closest(".link-outer, .note-card");if(r){r.classList.toggle("is-pinned-tag",a);const t=r.querySelector(".link-title, .note-title");if(t){let e=t.querySelector("i.mdi-pin");if(a){if(!e){const e=document.createElement("i");e.className="mdi mdi-pin",e.style.color="var(--primary)",e.style.marginRight="8px",t.prepend(e)}}else e&&e.remove()}let e=r.querySelector(".note-tags");if(e||(e=r.querySelector(".link-tag-list")),e){let t=null;const o=e.querySelectorAll("*");for(let e of o)if("shaarli-pin"===e.textContent.trim()){if(e.classList.contains("note-tag")){t=e;break}if("A"===e.tagName){t=e.parentElement.classList.contains("label-tag")?e.parentElement:e;break}}if(a){if(!t)if(r.classList.contains("note-card")){const t=document.createElement("span");t.className="note-tag",t.textContent="shaarli-pin",e.appendChild(t)}else{const t=document.createElement("span");t.className="link-tag";const o=document.createElement("a");o.href="?searchtags=shaarli-pin",o.textContent="shaarli-pin",t.appendChild(o),e.children.length>0&&e.appendChild(document.createTextNode(" ")),e.appendChild(t)}}else if(t){const e=t.previousSibling;t.remove(),e&&e.nodeType===Node.TEXT_NODE&&!e.textContent.trim()&&e.remove()}}}fetch(e).then(t=>t.text()).then(t=>{const e=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!e)throw new Error("Could not find edit form");const o=new URLSearchParams;e.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&o.append(t.name,t.value||"on"):t.name&&o.append(t.name,getFormFieldValue(t))});let n=(o.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());const r="shaarli-pin";return a?n.includes(r)||n.push(r):n=n.filter(t=>t!==r),o.set("lf_tags",n.join(" ")),o.append("save_edit","1"),fetch(e.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()})}).then(t=>{t.ok&&"function"==typeof organizePinnedBookmarks&&window.requestAnimationFrame(organizePinnedBookmarks)}).catch(t=>console.error(t))}window.setModalNoteColor=function(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);if(!e||!o)return;setNoteColor(o.id,t,o.editUrl),o.color=t;const n=e.querySelector(".note-modal");n&&applyNoteVisualState(n,o);const a=e.querySelector(".note-modal-palette");a&&(a.innerHTML=generateModalPaletteButtons(o),a.classList.add("open"),positionPalettePopup(a))},window.setModalNoteFontColor=function(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);if(!e||!o)return;setNoteFontColor(o.id,t,o.editUrl),o.fontColor=t;const n=e.querySelector(".note-modal");n&&applyNoteVisualState(n,o);const a=e.querySelector(".note-modal-palette");a&&(a.innerHTML=generateModalPaletteButtons(o),a.classList.add("open"),positionPalettePopup(a))},window.setModalNoteFilter=function(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);if(!e||!o)return;const n=normalizeFilterKey(t)||"none";setNoteFilter(o.id,n,o.editUrl),o.filter=n;const a=e.querySelector(".note-modal");a&&applyNoteVisualState(a,o);const r=e.querySelector(".note-modal-palette");r&&(r.innerHTML=generateModalPaletteButtons(o),r.classList.add("open"),positionPalettePopup(r))},window.setNoteColor=function(t,e,o){setNoteColorVisual(t,e);const n=document.querySelector(`.link-outer[data-id="${t}"]`);if(n){const e=n.querySelector(".bookmark-palette .palette-popup");if(e){const a=getElementVisualColor(n),r=getElementVisualFilter(n);e.innerHTML=generateBookmarkPaletteButtons(t,o,a,r)}}const a=getOpenModalOverlay(),r=getModalCurrentEntity(a);if(a&&r&&String(r.id)===String(t)){r.color=e;const t=a.querySelector(".note-modal");t&&applyNoteVisualState(t,r);const o=a.querySelector(".note-modal-palette");o&&(o.innerHTML=generateModalPaletteButtons(r))}fetch(o).then(t=>t.text()).then(t=>{const o=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!o)throw new Error("Could not find edit form");const n=new URLSearchParams;o.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&n.append(t.name,t.value||"on"):t.name&&n.append(t.name,getFormFieldValue(t))});let a=(n.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());if(a=a.filter(t=>!t.startsWith("note-color-")),a=a.filter(t=>!t.startsWith("note-custom-")),a=a.filter(t=>{if(!t.startsWith("note-"))return!0;const e=t.substring(5);return!NOTE_COLOR_OPTIONS.some(t=>t.key===e)}),"default"!==e)if("string"==typeof e&&e.startsWith("custom:")){const t=e.substring(7).replace("#","");a.push(`note-color-${t}`)}else a.push(`note-color-${e}`);return n.set("lf_tags",a.join(" ")),n.append("save_edit","1"),fetch(o.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to save color")}).catch(t=>{console.error("Error saving note color:",t),alert(window.ShaarliProI18n.t("Failed to save color.")+" "+window.ShaarliProI18n.t("Please refresh the page."))})},window.setNoteFilter=function(t,e,o){const n=normalizeFilterKey(e)||"none",a=document.querySelector(`.note-card[data-id="${t}"]`);if(a){const t=Array.from(a.classList).find(t=>t.startsWith("note-color-")),e=t?t.replace("note-color-",""):a.dataset.color||"default",o=getElementVisualBackground(a),r=getElementVisualFontColor(a);applyNoteVisualState(a,{color:e,filter:n,background:o,fontColor:r})}const r=document.querySelector(`.link-outer[data-id="${t}"]`);if(r){const e=Array.from(r.classList).find(t=>t.startsWith("note-color-")),a=e?e.replace("note-color-",""):r.dataset.color||"default",i=getElementVisualBackground(r),l=getElementVisualFontColor(r);applyNoteVisualState(r,{color:a,filter:n,background:i,fontColor:l});const s=r.querySelector(".bookmark-palette .palette-popup");s&&(s.innerHTML=generateBookmarkPaletteButtons(t,o,a,n))}const i=getOpenModalOverlay(),l=getModalCurrentEntity(i);if(i&&l&&String(l.id)===String(t)){l.filter=n;const t=i.querySelector(".note-modal");t&&applyNoteVisualState(t,l);const e=i.querySelector(".note-modal-palette");e&&(e.innerHTML=generateModalPaletteButtons(l))}fetch(o).then(t=>t.text()).then(t=>{const e=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!e)throw new Error("Could not find edit form");const o=new URLSearchParams;e.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&o.append(t.name,t.value||"on"):t.name&&o.append(t.name,getFormFieldValue(t))});let a=(o.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());return a=a.filter(t=>!t.startsWith("notefilter-")),n&&"none"!==n&&a.push(`notefilter-${n}`),o.set("lf_tags",a.join(" ")),o.append("save_edit","1"),fetch(e.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to save filter")}).catch(t=>{console.error("Error saving note filter:",t),alert(window.ShaarliProI18n.t("Failed to save filter.")+" "+window.ShaarliProI18n.t("Please refresh the page."))})},window.setNoteBackground=function(t,e,o){const n="none"===e?"none":normalizeBackgroundKey(e)||"none",a=document.querySelector(`.note-card[data-id="${t}"]`);if(a){const t=Array.from(a.classList).find(t=>t.startsWith("note-color-")),e=t?t.replace("note-color-",""):a.dataset.color||"default",o=a.dataset.filter||"none",r=getElementVisualFontColor(a);applyNoteVisualState(a,{color:e,filter:o,background:n,fontColor:r})}const r=document.querySelector(`.link-outer[data-id="${t}"]`);if(r){const t=Array.from(r.classList).find(t=>t.startsWith("note-color-")),e=t?t.replace("note-color-",""):r.dataset.color||"default",o=r.dataset.filter||"none",a=getElementVisualFontColor(r);applyNoteVisualState(r,{color:e,filter:o,background:n,fontColor:a})}const i=getOpenModalOverlay(),l=getModalCurrentEntity(i);if(i&&l&&String(l.id)===String(t)){l.background=n;const t=i.querySelector(".note-modal");t&&applyNoteVisualState(t,l);const e=i.querySelector(".note-modal-palette");e&&(e.innerHTML=generateModalPaletteButtons(l))}fetch(o).then(t=>t.text()).then(t=>{const e=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!e)throw new Error("Could not find edit form");const o=new URLSearchParams;e.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&o.append(t.name,t.value||"on"):t.name&&o.append(t.name,getFormFieldValue(t))});let a=(o.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());return a=a.filter(t=>!t.startsWith("notebg-")),n&&"none"!==n&&a.push(`notebg-${n}`),o.set("lf_tags",a.join(" ")),o.append("save_edit","1"),fetch(e.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:o.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to save background")}).catch(t=>{console.error("Error saving note background:",t),alert(window.ShaarliProI18n.t("Failed to save background.")+" "+window.ShaarliProI18n.t("Please refresh the page."))})},window.setModalNoteBackground=function(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);if(!e||!o)return;const n="none"===t?"none":normalizeBackgroundKey(t)||"none";setNoteBackground(o.id,n,o.editUrl),o.background=n;const a=e.querySelector(".note-modal");a&&applyNoteVisualState(a,o);const r=e.querySelector(".note-modal-palette");r&&(r.innerHTML=generateModalPaletteButtons(o),r.classList.add("open"),positionPalettePopup(r))};let colorPickerPanelInitialized=!1;function ensureColorPickerPanel(){if(colorPickerPanelInitialized)return;if(document.getElementById("shaarli-color-picker"))return void(colorPickerPanelInitialized=!0);const t=document.createElement("div");t.id="shaarli-color-picker",t.className="color-picker-panel",t.setAttribute("role","dialog"),t.setAttribute("aria-modal","false"),t.setAttribute("aria-hidden","true"),t.style.display="none",document.body.appendChild(t),document.addEventListener("click",t=>{const e=document.getElementById("shaarli-color-picker");e&&e.classList.contains("open")&&(t.target.closest("#shaarli-color-picker")||t.target.closest("#shaarli-bg-studio")||closeColorPickerPanel())}),document.addEventListener("keydown",t=>{if("Escape"!==t.key)return;const e=document.getElementById("shaarli-color-picker");e&&e.classList.contains("open")&&closeColorPickerPanel()}),colorPickerPanelInitialized=!0}function closeColorPickerPanel(){const t=document.getElementById("shaarli-color-picker");if(!t)return;const e=t.dataset.type||"background",o="1"===t.dataset.skipRestore,n=t.dataset.mode||"entity",a=t.dataset.entityId||"";if(!o&&"draft"===n)return t.dataset.skipRestore="0",t.classList.remove("open"),t.style.display="none",void t.setAttribute("aria-hidden","true");if(!o&&"font"===e){const e=t.dataset.prevFontColorKey||"auto";"modal"===n?setModalNoteFontColorVisual(e):setNoteFontColorVisual(a,e)}if(!o&&"background"===e){const e=t.dataset.prevColorKey||"default";"modal"===n?setModalNoteColorVisual(e):setNoteColorVisual(a,e)}t.dataset.skipRestore="0",t.classList.remove("open"),t.style.display="none",t.setAttribute("aria-hidden","true")}function openColorPickerPanel({mode:t,entityId:e,editUrl:o,type:n}){ensureColorPickerPanel();const a=document.getElementById("shaarli-color-picker");if(!a)return;a.dataset.mode=t||"entity",a.dataset.entityId=e||"",a.dataset.editUrl=o||"",a.dataset.type=n||"background";const r="dark"===getCurrentThemeMode()?"#20293A":"#ffffff";if("font"===(n||"background")){let o="auto";if("draft"===(t||"entity")){const t=document.getElementById("shaarli-bg-studio");o=t&&t.dataset.fontColor||"auto"}else if("modal"===(t||"entity")){const t=getOpenModalOverlay(),e=t?t.querySelector(".note-modal"):null;o=e&&e.dataset.fontColor?e.dataset.fontColor:"auto"}else{const t=document.querySelector(`.note-card[data-id="${e}"]`),n=document.querySelector(`.link-outer[data-id="${e}"]`);o=t&&t.dataset.fontColor?t.dataset.fontColor:n&&n.dataset.fontColor?n.dataset.fontColor:"auto"}a.dataset.prevFontColorKey=o}else a.dataset.prevFontColorKey="";if("background"===(n||"background")){let o="default";if("draft"===(t||"entity")){const t=document.getElementById("shaarli-bg-studio");t&&(o=t.dataset.color||"default")}else if("modal"===(t||"entity")){const t=getOpenModalOverlay(),e=t?t.querySelector(".note-modal"):null;if(e){const t="custom"===e.dataset.color,n=e.dataset.customColor||"";o=t&&n?`custom:${n}`:getElementVisualColor(e)}}else{const t=document.querySelector(`.note-card[data-id="${e}"]`),n=document.querySelector(`.link-outer[data-id="${e}"]`),a=t||n;if(a){const t="custom"===a.dataset.color,e=a.dataset.customColor||"";o=t&&e?`custom:${e}`:getElementVisualColor(a)}}a.dataset.prevColorKey=o}else a.dataset.prevColorKey="";a.innerHTML=`\n <div class="color-picker-header">\n <div class="color-picker-title">${"font"===n?"Couleur du texte":window.ShaarliProI18n.t("Custom color")}</div>\n <button class="color-picker-close" type="button" data-color-picker-action="close" title=window.ShaarliProI18n.t("Close") aria-label=window.ShaarliProI18n.t("Close")><i class="mdi mdi-close" aria-hidden="true"></i></button>\n </div>\n <div class="color-picker-body">\n <div class="color-picker-gradient">\n <div class="color-picker-gradient-inner" id="color-gradient">\n <div class="color-picker-cursor" id="color-cursor"></div>\n </div>\n </div>\n <div class="color-picker-hue">\n <input type="range" min="0" max="360" value="210" class="color-picker-hue-slider" id="hue-slider">\n </div>\n <div class="color-picker-preview-row">\n <div class="color-picker-preview" id="color-preview"></div>\n <div class="color-picker-inputs">\n <div class="color-picker-input-group">\n <label>Hex</label>\n <input type="text" id="hex-input" value="${r}" maxlength="7">\n </div>\n </div>\n </div>\n </div>\n <div class="color-picker-footer">\n <button type="button" class="color-picker-btn color-picker-btn-secondary" data-color-picker-action="close">Annuler</button>\n <button type="button" class="color-picker-btn color-picker-btn-primary" data-color-picker-action="apply">Appliquer</button>\n </div>\n `;let i=210,l=50,s=50,d=r;const c=a.querySelector("#color-gradient"),u=a.querySelector("#color-cursor"),m=a.querySelector("#hue-slider"),p=a.querySelector("#hex-input"),f=a.querySelector("#color-preview");function g(){if(d=function(t,e,o){const n=o*e,a=n*(1-Math.abs(t/60%2-1)),r=o-n;let i,l,s;t<60?(i=n,l=a,s=0):t<120?(i=a,l=n,s=0):t<180?(i=0,l=n,s=a):t<240?(i=0,l=a,s=n):t<300?(i=a,l=0,s=n):(i=n,l=0,s=a);const d=t=>Math.round(255*(t+r)).toString(16).padStart(2,"0");return`#${d(i)}${d(l)}${d(s)}`.toUpperCase()}(i,l/100,s/100),c.style.background=`linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, hsl(${i}, 100%, 50%))`,u.style.left=`${l}%`,u.style.top=100-s+"%",f.style.backgroundColor=d,p.value=d,"font"===(a.dataset.type||"background")){const t=`custom:${d}`,e=a.dataset.mode||"entity",o=a.dataset.entityId||"";if("draft"===e){const e=document.getElementById("shaarli-bg-studio");e&&"function"==typeof e.__draftApply&&e.__draftApply({fontColor:t})}else"modal"===e?setModalNoteFontColorVisual(t):setNoteFontColorVisual(o,t)}if("background"===(a.dataset.type||"background")){const t=`custom:${d}`,e=a.dataset.mode||"entity",o=a.dataset.entityId||"";if("draft"===e){const e=document.getElementById("shaarli-bg-studio");e&&"function"==typeof e.__draftApply&&e.__draftApply({color:t})}else"modal"===e?setModalNoteColorVisual(t):setNoteColorVisual(o,t)}}function h(t){const e=function(t){const e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);if(!e)return{h:0,s:0,v:0};const o=parseInt(e[1],16)/255,n=parseInt(e[2],16)/255,a=parseInt(e[3],16)/255,r=Math.max(o,n,a),i=r-Math.min(o,n,a);let l=0;return 0!==i&&(l=r===o?((n-a)/i+6)%6*60:r===n?60*((a-o)/i+2):60*((o-n)/i+4)),{h:l,s:0===r?0:i/r,v:r}}(t);i=e.h,l=100*e.s,s=100*e.v,m.value=i,g()}let y=!1;if(c.addEventListener("mousedown",t=>{y=!0;const e=c.getBoundingClientRect();l=Math.max(0,Math.min(100,(t.clientX-e.left)/e.width*100)),s=Math.max(0,Math.min(100,100-(t.clientY-e.top)/e.height*100)),g()}),document.addEventListener("mousemove",t=>{if(!y)return;const e=c.getBoundingClientRect();l=Math.max(0,Math.min(100,(t.clientX-e.left)/e.width*100)),s=Math.max(0,Math.min(100,100-(t.clientY-e.top)/e.height*100)),g()}),document.addEventListener("mouseup",()=>{y=!1}),m.addEventListener("input",t=>{i=parseInt(t.target.value),g()}),p.addEventListener("input",t=>{const e=t.target.value;/^#[0-9A-F]{6}$/i.test(e)&&h(e)}),"font"===(a.dataset.type||"background")){const t=a.dataset.prevFontColorKey||"auto";let e=r;if("string"==typeof t&&t.startsWith("custom:"))e=t.substring(7);else if("auto"!==t){const o=NOTE_FONT_COLOR_OPTIONS.find(e=>e.key===t);o&&o.value&&"auto"!==o.value&&(e=o.value)}h(e)}else if("background"===(a.dataset.type||"background")){const t=a.dataset.prevColorKey||"default";let e=r;"string"==typeof t&&t.startsWith("custom:")&&(e=t.substring(7)),h(e)}else h(r);a.style.display="block",a.style.visibility="hidden",positionColorPickerPanel(a,t),a.style.visibility="visible",a.classList.add("open"),a.setAttribute("aria-hidden","false")}function positionColorPickerPanel(t,e){if(!t)return;const o=document.getElementById("shaarli-bg-studio"),n=12;if(o&&o.classList.contains("open")){const e=o.getBoundingClientRect(),a=t.getBoundingClientRect(),r=Math.max(1,a.width),i=Math.max(1,a.height);let l=e.right+10,s=e.top;l+r>window.innerWidth-n&&(l=e.left-r-10),l<n&&(l=n),l+r>window.innerWidth-n&&(l=window.innerWidth-n-r),s+i>window.innerHeight-n&&(s=window.innerHeight-n-i),s<n&&(s=n),t.style.left=`${Math.round(l)}px`,t.style.top=`${Math.round(s)}px`,t.style.right="",t.style.bottom=""}else{const e=t.getBoundingClientRect(),o=Math.max(1,e.width),a=Math.max(1,e.height),r=Math.max(n,Math.min((window.innerWidth-o)/2,window.innerWidth-n-o)),i=Math.max(n,Math.min((window.innerHeight-a)/2,window.innerHeight-n-a));t.style.left=`${Math.round(r)}px`,t.style.top=`${Math.round(i)}px`}}function setNoteFontColorVisual(t,e){const o=document.querySelector(`.note-card[data-id="${t}"]`),n=document.querySelector(`.link-outer[data-id="${t}"]`);let a="auto";if("string"==typeof e&&e.startsWith("custom:"))a=e.substring(7);else if("auto"!==e){const t=NOTE_FONT_COLOR_OPTIONS.find(t=>t.key===e);a=t?t.value:"auto"}const r=t=>{t&&("auto"===a?t.style.removeProperty("--note-card-fg"):t.style.setProperty("--note-card-fg",a),t.dataset.fontColor=e)};r(o),r(n);const i=getOpenModalOverlay(),l=getModalCurrentEntity(i);if(i&&l&&String(l.id)===String(t)){r(i.querySelector(".note-modal"))}}function setModalNoteFontColorVisual(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);e&&o&&setNoteFontColorVisual(o.id,t)}function setNoteColorVisual(t,e){const o=document.querySelector(`.note-card[data-id="${t}"]`),n=document.querySelector(`.link-outer[data-id="${t}"]`),a=t=>{if(!t)return;const o={color:getElementVisualColor(t),filter:getElementVisualFilter(t),background:getElementVisualBackground(t),fontColor:getElementVisualFontColor(t)};if("string"==typeof e&&e.startsWith("custom:")){const o=e.substring(7);Array.from(t.classList).forEach(e=>{e.startsWith("note-color-")&&t.classList.remove(e)}),t.classList.add("note-color-custom"),t.style.backgroundColor=o,t.style.removeProperty("border-color"),t.dataset.color="custom",t.dataset.customColor=o;const n=getReadableForegroundForBackground(o);return void(n&&t.style.setProperty("--note-card-fg",n))}t.dataset.customColor="",applyNoteVisualState(t,{...o,color:e})};a(o),a(n);const r=getOpenModalOverlay(),i=getModalCurrentEntity(r);if(r&&i&&String(i.id)===String(t)){a(r.querySelector(".note-modal"))}}function setModalNoteColorVisual(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);e&&o&&setNoteColorVisual(o.id,t)}function setNoteFontColor(t,e,o){setNoteFontColorVisual(t,e),fetch(o).then(t=>t.text()).then(t=>{const o=(new DOMParser).parseFromString(t,"text/html").querySelector('form[name="linkform"]');if(!o)throw new Error("Could not find edit form");const n=new URLSearchParams;o.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&n.append(t.name,t.value||"on"):t.name&&n.append(t.name,getFormFieldValue(t))});let a=(n.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());if(a=a.filter(t=>!t.startsWith("font-")),"auto"!==e)if(e.startsWith("custom:"))a.push(`font-${e.substring(7).replace("#","")}`);else{const t=NOTE_FONT_COLOR_OPTIONS.find(t=>t.key===e);t&&"auto"!==t.value&&a.push(`font-${t.value.substring(1)}`)}return n.set("lf_tags",a.join(" ")),n.append("save_edit","1"),fetch(o.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to save font color")}).catch(t=>{console.error("Error saving note font color:",t)})}function setModalNoteFontColor(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);if(!e||!o)return;setNoteFontColor(o.id,t,o.editUrl),o.fontColor=t;const n=e.querySelector(".note-modal");if(n){let e="auto";if(String(t||"").startsWith("custom:"))e=String(t).substring(7);else if("auto"!==t){const o=NOTE_FONT_COLOR_OPTIONS.find(e=>e.key===t);e=o?o.value:"auto"}"auto"===e?n.style.removeProperty("--note-card-fg"):n.style.setProperty("--note-card-fg",e),n.dataset.fontColor=t}}function setModalCustomFontColor(t){setModalNoteFontColor(`custom:${t}`)}function setModalCustomNoteColor(t){const e=getOpenModalOverlay(),o=getModalCurrentEntity(e);if(!e||!o||!o.editUrl)return;const n=e.querySelector(".note-modal");n&&(n.style.backgroundColor=t,n.style.removeProperty("border-color"),n.dataset.color="custom",n.dataset.customColor=t),fetch(o.editUrl).then(t=>t.text()).then(e=>{const o=(new DOMParser).parseFromString(e,"text/html").querySelector('form[name="linkform"]');if(!o)throw new Error("Could not find edit form");const n=new URLSearchParams;o.querySelectorAll("input, textarea").forEach(t=>{"checkbox"===t.type?t.checked&&n.append(t.name,t.value||"on"):t.name&&n.append(t.name,getFormFieldValue(t))});let a=(n.get("lf_tags")||"").split(/[\s,]+/).filter(t=>""!==t.trim());a=a.filter(t=>!t.startsWith("note-color-")),a=a.filter(t=>!t.startsWith("note-custom-")),a=a.filter(t=>{if(!t.startsWith("note-"))return!0;const e=t.substring(5);return!NOTE_COLOR_OPTIONS.some(t=>t.key===e)});const r=t.replace("#","");return a.push(`note-color-${r}`),n.set("lf_tags",a.join(" ")),n.append("save_edit","1"),fetch(o.action,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()})}).then(t=>{if(!t.ok)throw new Error("Failed to save custom color")}).catch(t=>{console.error("Error saving custom color:",t)})}document.addEventListener("click",t=>{const e=t.target.closest("[data-color-picker-action]");if(!e)return;const o=document.getElementById("shaarli-color-picker");if(!o)return;const n=e.dataset.colorPickerAction;if("close"!==n){if("apply"===n){const t=o.dataset.mode||"entity",e=o.dataset.entityId||"",n=o.dataset.editUrl||"",a=o.dataset.type||"background",r=o.querySelector("#hex-input"),i=r?r.value:"#ffffff";if("draft"===t){const t=document.getElementById("shaarli-bg-studio");return t&&"function"==typeof t.__draftApply&&("font"===a?(t.dataset.fontColor=`custom:${i}`,t.__draftApply({fontColor:`custom:${i}`})):(t.dataset.color=`custom:${i}`,t.__draftApply({color:`custom:${i}`})),renderBackgroundStudioPanel(t)),o.dataset.skipRestore="1",void closeColorPickerPanel()}"font"===a?"modal"===t?setModalCustomFontColor(i):setNoteFontColor(e,`custom:${i}`,n):"modal"===t?setModalCustomNoteColor(i):setNoteColor(e,`custom:${i}`,n),o.dataset.skipRestore="1",closeColorPickerPanel()}}else closeColorPickerPanel()});