1const e=document.getElementById("dropzone"),u=document.getElementById("dropzone-file-input");if(e&&u){let s=function(){d&&(i+=(r-i)*.08,a+=(n-a)*.08,e.style.setProperty("--mouse-x",`${i}px`),e.style.setProperty("--mouse-y",`${a}px`),f=requestAnimationFrame(s))};e.addEventListener("click",()=>{u.click()}),u.addEventListener("change",()=>{const t=u.files;t&&t.length>0&&y(t[0])}),e.addEventListener("dragover",t=>{t.preventDefault(),e.classList.add("dragover")}),e.addEventListener("dragleave",()=>{e.classList.remove("dragover")}),e.addEventListener("drop",t=>{t.preventDefault(),e.classList.remove("dragover");const o=t.dataTransfer?.files;if(o&&o.length>0){const c=o[0];c.name.toLowerCase().endsWith(".pdf")||c.type==="application/pdf"?y(c):alert("Please upload a PDF file.")}});let i=0,a=0,r=0,n=0,d=!1,f=0;e.addEventListener("mouseenter",t=>{d=!0;const o=e.getBoundingClientRect();r=t.clientX-o.left,n=t.clientY-o.top,i=r,a=n,cancelAnimationFrame(f),s()}),e.addEventListener("mousemove",t=>{const o=e.getBoundingClientRect();r=t.clientX-o.left,n=t.clientY-o.top}),e.addEventListener("mouseleave",()=>{d=!1,cancelAnimationFrame(f)});const l=document.createElement("div");l.id="window-drag-overlay",Object.assign(l.style,{position:"fixed",inset:"0",zIndex:"99999",backgroundColor:"rgba(21, 34, 27, 0.88)",backdropFilter:"blur(12px)",webkitBackdropFilter:"blur(12px)",display:"none",alignItems:"center",justifyContent:"center",color:"#ffffff",transition:"opacity 0.25s cubic-bezier(0.25, 0.8, 0.25, 1)",opacity:"0",pointerEvents:"none"}),l.innerHTML=` 2 <div style=" 3 border: 1.5px dashed rgba(80, 184, 108, 0.5); 4 border-radius: 28px; 5 padding: 48px 32px; 6 text-align: center; 7 max-width: 440px; 8 width: 90%; 9 display: flex; 10 flex-direction: column; 11 align-items: center; 12 gap: 20px; 13 background: rgba(15, 27, 35, 0.7); 14 box-shadow: 0 30px 70px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05); 15 "> 16 <div style=" 17 width: 72px; 18 height: 72px; 19 background: rgba(80, 184, 108, 0.12); 20 border: 1px solid rgba(80, 184, 108, 0.3); 21 border-radius: 20px; 22 display: flex; 23 align-items: center; 24 justify-content: center; 25 font-size: 32px; 26 animation: floatDoc 2.4s ease-in-out infinite; 27 ">ð</div> 28 <div style="display: flex; flex-direction: column; gap: 6px;"> 29 <strong style=" 30 font-size: 1.45rem; 31 font-family: 'Iowan Old Style', Georgia, serif; 32 font-weight: 700; 33 color: #eaf8ee; 34 ">Drop your PDF anywhere</strong> 35 <span style=" 36 font-size: 0.92rem; 37 color: #a5d6a7; 38 font-weight: 500; 39 opacity: 0.9; 40 ">to load it directly into the secure local workspace</span> 41 </div> 42 </div> 43 `,document.body.appendChild(l);let p=0;window.addEventListener("dragenter",t=>{const o=t.dataTransfer?.types;o&&Array.from(o).includes("Files")&&(t.preventDefault(),p++,p===1&&(l.style.display="flex",l.offsetHeight,l.style.opacity="1"))}),window.addEventListener("dragover",t=>{t.preventDefault()}),window.addEventListener("dragleave",t=>{p--,p===0&&(l.style.opacity="0",setTimeout(()=>{p===0&&(l.style.display="none")},250))}),window.addEventListener("drop",t=>{t.preventDefault(),p=0,l.style.opacity="0",l.style.display="none";const o=t.dataTransfer?.files;if(o&&o.length>0){const c=o[0];c.name.toLowerCase().endsWith(".pdf")||c.type==="application/pdf"?y(c):alert("Please upload a PDF file.")}})}async function y(s){if(e){e.classList.add("uploading");const i=e.querySelector(".dropzone-title"),a=e.querySelector(".dropzone-subtitle");i&&(i.textContent="Loading file..."),a&&(a.textContent=s.name)}try{await g(s);const i=e?.getAttribute("data-app-url")||"/app/studio";window.location.href=i}catch(i){console.error("File transfer failed, trying sessionStorage fallback",i);try{const a=new FileReader;a.onload=r=>{const n=r.target?.result;if(n){sessionStorage.setItem("localpdf_transfer_file",JSON.stringify({name:s.name,type:s.type,dataUrl:n}));const d=e?.getAttribute("data-app-url")||"/app/studio";window.location.href=d}},a.readAsDataURL(s)}catch(a){if(console.error("Fallback failed",a),alert("Could not load file. Please try again."),e){e.classList.remove("uploading");const r=e.querySelector(".dropzone-title"),n=e.querySelector(".dropzone-subtitle");r&&(r.textContent="Drag & drop your PDF here"),n&&(n.textContent="or click to choose file")}}}}function g(s){return new Promise((i,a)=>{const r=indexedDB.open("localpdf-transfer",1);r.onupgradeneeded=()=>{const n=r.result;n.objectStoreNames.contains("transfer-files")||n.createObjectStore("transfer-files",{keyPath:"id"})},r.onsuccess=()=>{const n=r.result,d=n.transaction("transfer-files","readwrite");d.objectStore("transfer-files").put({id:"pending",blob:s,name:s.name,type:s.type,timestamp:Date.now()}),d.oncomplete=()=>{n.close(),i()},d.onerror=()=>{n.close(),a(d.error)}},r.onerror=()=>{a(r.error)}})}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.