1 line
72 KiB
JavaScript
1 line
72 KiB
JavaScript
(()=>{const e="plotdirector.word.projectId",t="plotdirector.word.bookId",n="plotdirector.word.activeTab",r="plotdirector.word.documentGuid",a="plotdirector.word.boundBookId",o="plotdirector.word.boundProjectId",c="plotdirector.word.bindingVersion",i=new Set(["scene","links","structure","diagnostics"]),s=document.querySelector(".word-companion-shell"),d=document.querySelector(".word-companion-tabs"),l=[...document.querySelectorAll("[data-tab-button]")],u=[...document.querySelectorAll("[data-tab-panel]")],p=document.querySelector("[data-first-run-wizard]"),h=document.querySelector("[data-first-run-project-select]"),m=document.querySelector("[data-first-run-book-select]"),y=document.querySelector("[data-first-run-new-book-title]"),w=document.querySelector("[data-first-run-create-book]"),f=document.querySelector("[data-first-run-scan]"),g=document.querySelector("[data-first-run-cancel]"),S=document.querySelector("[data-first-run-status]"),C=document.querySelector("[data-first-run-summary]"),b=document.querySelector("[data-first-run-character-section]"),I=document.querySelector("[data-first-run-character-status]"),k=document.querySelector("[data-first-run-character-candidates]"),v=document.querySelector("[data-first-run-character-actions]"),x=document.querySelector("[data-first-run-create-characters]"),E=document.querySelector("[data-first-run-skip-characters]"),N=document.querySelector("[data-first-run-continue]"),L=document.querySelector("[data-first-run-import-actions]"),q=document.querySelector("[data-first-run-import]"),P=document.querySelector("[data-first-run-import-cancel]"),D=document.querySelector("[data-first-run-replace-dialog]"),A=document.querySelector("[data-first-run-replace-confirm]"),T=document.querySelector("[data-first-run-replace-cancel]"),$=document.querySelector("[data-office-status]"),j=document.querySelector("[data-connection-status]"),R=document.querySelector("[data-summary-connection]"),W=document.querySelector("[data-summary-project]"),U=document.querySelector("[data-summary-book]"),M=document.querySelector("[data-project-select]"),O=document.querySelector("[data-book-select]"),H=document.querySelector("[data-project-message]"),B=document.querySelector("[data-book-message]"),G=document.querySelector("[data-refresh-current-scene]"),F=document.querySelector("[data-refresh-document]"),V=document.querySelector("[data-current-chapter]"),J=document.querySelector("[data-current-scene]"),Y=document.querySelector("[data-current-word-count]"),z=document.querySelector("[data-scene-tracking-status]"),K=document.querySelector("[data-document-message]"),Q=document.querySelector("[data-sync-note]"),X=document.querySelector("[data-document-outline]"),Z=document.querySelector("[data-analyse-manuscript-structure]"),_=document.querySelector("[data-apply-structure-sync]"),ee=document.querySelector("[data-structure-preview-status]"),te=document.querySelector("[data-structure-preview-results]"),ne=document.querySelector("[data-refresh-plotdirector-scene]"),re=document.querySelector("[data-plotdirector-scene-status]"),ae=document.querySelector("[data-anchor-status]"),oe=document.querySelector("[data-anchor-book-id]"),ce=document.querySelector("[data-anchor-chapter-id]"),ie=document.querySelector("[data-anchor-scene-id]"),se=document.querySelector("[data-attach-plotdirector-ids]"),de=document.querySelector("[data-plotdirector-scene-details]"),le=document.querySelector("[data-plotdirector-scene-title]"),ue=document.querySelector("[data-plotdirector-revision-status]"),pe=document.querySelector("[data-plotdirector-estimated-words]"),he=document.querySelector("[data-plotdirector-actual-words]"),me=document.querySelector("[data-plotdirector-blocked-status]"),ye=document.querySelector("[data-plotdirector-blocked-reason-row]"),we=document.querySelector("[data-plotdirector-blocked-reason]"),fe=document.querySelector("[data-runtime-last-sync]"),ge=document.querySelector("[data-sync-scene-progress]"),Se=document.querySelector("[data-sync-word-count]"),Ce=document.querySelector("[data-sync-plotdirector-count]"),be=document.querySelector("[data-sync-last-synced]"),Ie=document.querySelector("[data-sync-status]"),ke=document.querySelector("[data-writing-brief-block]"),ve=document.querySelector("[data-writing-brief]"),xe=document.querySelector("[data-plotdirector-link-groups]"),Ee=document.querySelector("[data-character-chips]"),Ne=document.querySelector("[data-asset-chips]"),Le=(document.querySelector("[data-location-chips]"),document.querySelector("[data-primary-location-select]")),qe=document.querySelector("[data-save-scene-links]"),Pe=document.querySelector("[data-scene-links-status]"),De=document.querySelector("[data-links-editing-scene]"),Ae=document.querySelector("[data-chapter-create-link]"),Te=document.querySelector("[data-chapter-create-link-chapter]"),$e=document.querySelector("[data-create-plotdirector-chapter]"),je=document.querySelector("[data-link-existing-chapter]"),Re=document.querySelector("[data-chapter-create-link-status]"),We=document.querySelector("[data-scene-create-link]"),Ue=document.querySelector("[data-create-link-chapter]"),Me=document.querySelector("[data-create-link-scene]"),Oe=document.querySelector("[data-create-plotdirector-scene]"),He=document.querySelector("[data-link-existing-scene]"),Be=document.querySelector("[data-create-link-status]"),Ge=document.querySelector("[data-link-existing-dialog]"),Fe=document.querySelector("[data-link-scene-search]"),Ve=document.querySelector("[data-link-scene-options]"),Je=document.querySelector("[data-link-selected-scene]"),Ye=document.querySelector("[data-link-dialog-cancel]"),ze=document.querySelector("[data-link-dialog-status]"),Ke=document.querySelector("[data-create-scene-dialog]"),Qe=document.querySelector("[data-create-dialog-scene]"),Xe=document.querySelector("[data-create-dialog-chapter]"),Ze=document.querySelector("[data-create-dialog-confirm]"),_e=document.querySelector("[data-create-dialog-cancel]"),et=document.querySelector("[data-link-existing-chapter-dialog]"),tt=document.querySelector("[data-link-chapter-search]"),nt=document.querySelector("[data-link-chapter-options]"),rt=document.querySelector("[data-link-selected-chapter]"),at=document.querySelector("[data-link-chapter-dialog-cancel]"),ot=document.querySelector("[data-link-chapter-dialog-status]"),ct=document.querySelector("[data-create-chapter-dialog]"),it=document.querySelector("[data-create-chapter-dialog-chapter]"),st=document.querySelector("[data-create-chapter-dialog-book]"),dt=document.querySelector("[data-create-chapter-dialog-confirm]"),lt=document.querySelector("[data-create-chapter-dialog-cancel]"),ut=document.querySelector("[data-apply-structure-sync-dialog]"),pt=document.querySelector("[data-apply-structure-sync-summary]"),ht=document.querySelector("[data-apply-structure-sync-confirm]"),mt=document.querySelector("[data-apply-structure-sync-cancel]"),yt=document.querySelector("[data-resolve-project-id]"),wt=document.querySelector("[data-resolve-project-title]"),ft=document.querySelector("[data-resolve-book-id]"),gt=document.querySelector("[data-resolve-book-title]"),St=document.querySelector("[data-resolve-detected-chapter]"),Ct=document.querySelector("[data-resolve-detected-scene]"),bt=document.querySelector("[data-resolve-request-chapter]"),It=document.querySelector("[data-resolve-request-scene]"),kt=document.querySelector("[data-resolve-result]"),vt=document.querySelector("[data-resolve-chapter-id]"),xt=document.querySelector("[data-resolve-scene-id]"),Et=document.querySelector("[data-run-diagnostics]"),Nt=document.querySelector("[data-diagnostic-host]"),Lt=document.querySelector("[data-diagnostic-platform]"),qt=document.querySelector("[data-diagnostic-ready]"),Pt=document.querySelector("[data-diagnostic-word-api]"),Dt=document.querySelector("[data-diagnostic-last-scan]"),At=document.querySelector("[data-diagnostic-last-error]"),Tt=document.querySelector("[data-diagnostic-anchor-type]"),$t=document.querySelector("[data-diagnostic-stored-scene-id]"),jt=document.querySelector("[data-diagnostic-stored-chapter-id]"),Rt=document.querySelector("[data-diagnostic-resolution-method]"),Wt=document.querySelector("[data-diagnostic-paragraphs]"),Ut=document.querySelector("[data-diagnostic-heading1]"),Mt=document.querySelector("[data-diagnostic-heading2]"),Ot="true"===s?.dataset.authenticated;let Ht=[],Bt=[],Gt=!1,Ft=!1,Vt="Unknown",Jt="Unknown",Yt="",zt="",Kt=null,Qt=null,Xt=null,Zt=null,_t=null,en=null,tn="",nn="Title Match",rn=!1,an=[],on=null,cn=null,sn=[],dn=null,ln=null,un=null,pn=null,hn=null,mn=null,yn=null,wn=null,fn=null,gn=null,Sn=[],Cn=!1,bn=!1,In=0,kn=!1,vn=!1,xn=!1,En=null,Nn="Manual",Ln=!1,qn=null,Pn=!1,Dn=0;const An=1800;let Tn=!1,$n=!1,jn=null,Rn=!1,Wn=null,Un=null,Mn="",On="",Hn=0,Bn={characters:[],assets:[],locations:[],primaryLocationId:null};const Gn=e=>{const t=Date.now();t-Hn<1e3||(Hn=t,console.debug(`[Word Companion Runtime] ${e}`))},Fn=e=>{$&&($.textContent=e)},Vn=(e,t=!0)=>{const r=i.has(e)&&l.some(t=>t.dataset.tabButton===e)?e:"scene";for(const e of l){const t=e.dataset.tabButton===r;e.classList.toggle("is-active",t),e.setAttribute("aria-selected",t?"true":"false")}for(const e of u){const t=e.dataset.tabPanel===r;e.classList.toggle("is-active",t),e.hidden=!t}t&&((e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}})(n,r)},Jn=()=>{const e=(e=>{try{return window.localStorage.getItem(e)||""}catch{return""}})(n);Vn(i.has(e)?e:"scene",!1)},Yn=e=>{j&&(j.textContent=e),R&&(R.textContent=e)},zn=e=>{H&&(H.textContent=e)},Kn=e=>{B&&(B.textContent=e)},Qn=e=>{K&&(K.textContent=e)},Xn=e=>{re&&(re.textContent=e)},Zn=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("anchorType")&&Hr(Tt,yr(e.anchorType)),t("storedSceneId")&&Hr($t,yr(e.storedSceneId)),t("storedChapterId")&&Hr(jt,yr(e.storedChapterId)),t("resolutionMethod")&&Hr(Rt,yr(e.resolutionMethod))},_n=()=>{const e=Xr(),t=Number.isInteger(_t)&&_t>0&&Zt===_t,n=!Number.isInteger(en)||en<=0||Xt===en,r=t&&n;Hr(ae,r?"Attached to PlotDirector":"Not attached"),Hr(oe,e?.bookId?String(e.bookId):"-"),Hr(ce,Number.isInteger(en)&&en>0?String(en):"-"),Hr(ie,Number.isInteger(_t)&&_t>0?String(_t):"-"),se&&(se.disabled=!_t||r&&!rn,se.textContent=Zt&&!r?"Reattach PlotDirector IDs":"Attach PlotDirector IDs"),Zn({anchorType:nn||"Title Match",storedSceneId:Zt,storedChapterId:Xt,resolutionMethod:tn})},er=(e,t,n,r=null,a=null,o=null)=>{const c=e||"",i=t||"",s=Number.isInteger(n)?n:null,d=Number.isInteger(o)&&o>0?o:null,l=Number.isInteger(r)&&r>0?r:null,u=Number.isInteger(a)&&a>0?a:null,p=Yt===c&&zt===i&&Kt===s&&Qt===d&&Xt===l&&Zt===u;Yt=e||"",zt=t||"",Kt=Number.isInteger(n)?n:null,Qt=Number.isInteger(o)&&o>0?o:null,Xt=Number.isInteger(r)&&r>0?r:null,Zt=Number.isInteger(a)&&a>0?a:null,p||(V&&(V.textContent=e||"Not detected"),J&&(J.textContent=t||"Not detected"),Y&&(Y.textContent=Number.isInteger(n)?String(n):"-"),Hr(Se,Number.isInteger(n)?String(n):"-"),_n())},tr=()=>{jn&&(window.clearTimeout(jn),jn=null)},nr=(e,t)=>{e&&(e.hidden=t)},rr=e=>{Hr(Ie,e)},ar=e=>{Hr(ee,e)},or=(e="Select a project and book to analyse manuscript structure.")=>{if(un=null,te){te.innerHTML="";const e=document.createElement("p");e.textContent="No preview generated.",te.append(e)}ar(e),ir()},cr=(e=un)=>((e=un)=>va.flatMap(t=>Array.isArray(e?.[t.key])?e[t.key]:[]))(e).filter(e=>"couldLink"===e.category||"wouldCreateChapters"===e.category||"wouldCreateScenes"===e.category),ir=()=>{_&&(_.disabled=xn||0===cr().length)},sr=()=>{Z&&(Z.disabled=xn||!Qr()||!Xr()),ir()},dr=()=>{De&&(De.textContent=_t?`Editing links for: ${Mn||zt||"Current scene"}`:"Link a PlotDirector scene first.")},lr=()=>{const e=Ln||!_t,t=e||!en||Rn;ge&&(ge.disabled=t),qe&&(qe.disabled=e),Le&&(Le.disabled=e);for(const t of[Ee,Ne])for(const n of t?[...t.querySelectorAll("input[type='checkbox']")]:[])n.disabled=e},ur=e=>{"Live"!==e&&"Manual"!==e||(Nn=e),Hr(z,e||Nn||"Manual")},pr=(e,t="")=>{Ln=!!e,Ln&&tr(),Hr(z,Ln?"Stale":Nn),lr(),t&&(Qn(t),Cr(t))},hr=(e,t=null,n="")=>{_t=Number.isInteger(e)&&e>0?e:null,en=Number.isInteger(t)&&t>0?t:null,tn=n||"",_t!==Wn&&(Un=null),_t||tr(),lr(),rr(Ln?"Refresh Current Scene before syncing.":_t?"Ready to sync.":"No resolved PlotDirector scene."),Cr(Ln?"Refresh Current Scene before saving.":_t?"Ready to save.":"Link a PlotDirector scene first."),dr(),_n()},mr=e=>{G&&(G.disabled=e,G.textContent=e?"Refreshing...":"Refresh Current Scene")},yr=e=>null==e||""===e?"-":String(e),wr=e=>{if(!e)return"-";const t=e instanceof Date?e:new Date(e);if(Number.isNaN(t.getTime()))return"-";const n=new Date;return`Last synced: ${t.toDateString()===n.toDateString()?"Today":t.toLocaleDateString()} ${t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}`},fr=e=>{hn=e||null;const t=hn?.lastSyncUtc||hn?.manuscriptDocument?.lastSyncUtc;Hr(fe,wr(t)),Hr(be,wr(t))},gr=()=>{mn=null,yn=null,wn=null,fr(null)},Sr=()=>{yn=null,wn=null},Cr=e=>{Hr(Pe,e)},br=e=>{Hr(Be,e)},Ir=e=>{Hr(Re,e)},kr=()=>!!Xr()&&!!Yt&&!en,vr=()=>!!Xr()&&!!zt&&Number.isInteger(en)&&en>0,xr=()=>{nr(Ae,!0),Ir(""),$e&&($e.disabled=!0,$e.textContent="Create Chapter in PlotDirector"),je&&(je.disabled=!0,je.textContent="Link to Existing Chapter")},Er=(e="")=>{Hr(Te,yr(Yt)),nr(Ae,!1),Ir(e);const t=kr();$e&&($e.disabled=!t,$e.textContent="Create Chapter in PlotDirector"),je&&(je.disabled=!t,je.textContent="Link to Existing Chapter")},Nr=()=>{nr(We,!0),br(""),Oe&&(Oe.disabled=!0,Oe.textContent="Create Scene in PlotDirector"),He&&(He.disabled=!0,He.textContent="Link to Existing Scene")},Lr=(e="")=>{Hr(Ue,yr(Yt)),Hr(Me,yr(zt)),nr(We,!1),br(e);const t=vr();Oe&&(Oe.disabled=!t,Oe.textContent="Create Scene in PlotDirector"),He&&(He.disabled=!t,He.textContent="Link to Existing Scene")},qr=e=>{Xn(e),nr(de,!0),nr(ke,!0),nr(xe,!1),xr(),Nr(),tn="",Mn="",On="",nn=Zt?"SceneID Anchor":Xt?"ChapterID Anchor":"Title Match",rn=!1,Bn={characters:[],assets:[],locations:[],primaryLocationId:null},Dr(Ee,[],"character"),Dr(Ne,[],"asset"),Ar([],null,!1),hr(null),Hr(Ce,"-"),Hr(le,"-"),Hr(ue,"-"),Hr(pe,"-"),Hr(he,"-"),Hr(me,"-"),Hr(we,"-"),nr(ye,!0),_n(),dr()},Pr=(e,t)=>"asset"===t?e?.assetId||e?.AssetId||e?.storyAssetId||e?.StoryAssetId||0:"location"===t?e?.locationId||e?.LocationId||0:e?.characterId||e?.CharacterId||0,Dr=(e,t,n,r=!1)=>{if(!e)return;e.innerHTML="";const a=Array.isArray(t)?t:[];if(0===a.length){const t=document.createElement("p");return t.className="word-companion-empty-list",t.textContent="None",void e.append(t)}for(const t of a){const a=Number.parseInt(Pr(t,n),10);if(!Number.isInteger(a)||a<=0)continue;const o=document.createElement("label");o.className="word-companion-check-item";const c=document.createElement("input");c.type="checkbox",c.value=String(a),c.checked=!!t.linked,c.disabled=!r;const i=document.createElement("span");i.textContent=t.name||"Unnamed",o.append(c,i),e.append(o)}},Ar=(e,t,n=!1)=>{if(!Le)return;Le.innerHTML="";const r=document.createElement("option");r.value="",r.textContent="None",Le.append(r);const a=Number.parseInt(t||"",10);for(const t of Array.isArray(e)?e:[]){const e=Number.parseInt(Pr(t,"location"),10);if(!Number.isInteger(e)||e<=0)continue;const n=document.createElement("option");n.value=String(e),n.textContent=t.name||"Unnamed",n.selected=e===a,Le.append(n)}Le.disabled=!n},Tr=e=>String(e||"").trim().replace(/\s+/g," "),$r=(e,t)=>{const n=Tr(e);if(!n)return"";const r=new RegExp(`^${"scene"===t?"scene":"chapter"}\\s+(?:\\d+|[ivxlcdm]+|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)\\s*(?::|-|\\u2013|\\u2014)\\s*`,"i");return Tr(n.replace(r,""))||n},jr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("projectId")&&Hr(yt,yr(e.projectId)),t("projectTitle")&&Hr(wt,yr(e.projectTitle)),t("bookId")&&Hr(ft,yr(e.bookId)),t("bookTitle")&&Hr(gt,yr(e.bookTitle)),t("detectedChapter")&&Hr(St,yr(e.detectedChapter)),t("detectedScene")&&Hr(Ct,yr(e.detectedScene)),t("requestChapter")&&Hr(bt,yr(e.requestChapter)),t("requestScene")&&Hr(It,yr(e.requestScene)),t("result")&&Hr(kt,yr(e.result)),t("chapterId")&&Hr(vt,yr(e.chapterId)),t("sceneId")&&Hr(xt,yr(e.sceneId))},Rr=async e=>{if(wn===e&&Array.isArray(yn?.chapters))return yn.chapters;const t=await Ja(`/api/word-companion/books/${e}/structure`);return wn=e,yn=t||null,Array.isArray(t?.chapters)?t.chapters:[]},Wr=async e=>{const t=await Ja(`/api/word-companion/books/${e}/chapters`);return Array.isArray(t?.chapters)?t.chapters:[]},Ur=e=>{if(Number.isInteger(en)&&en>0){const t=e.find(e=>e.chapterId===en);if(t)return t}const t=$r(Yt,"chapter").toLocaleLowerCase();return t&&e.find(e=>$r(e.title,"chapter").toLocaleLowerCase()===t)||null},Mr=async()=>{const e=Xr();return e?Ur(await Rr(e.bookId)):null},Or=async(e,t,n,r,a)=>{const o=await Ja(`/api/word-companion/scenes/${t}/companion`);try{o.revisionStatus=await(async(e,t)=>{const n=await Ja(`/api/word-companion/books/${e}/structure`),r=Array.isArray(n?.chapters)?n.chapters:[];for(const e of r){const n=(Array.isArray(e.scenes)?e.scenes:[]).find(e=>e.sceneId===t);if(n)return n.revisionStatus||""}return""})(e,t)}catch{o.revisionStatus=""}var c;nn=a||"Title Match",rn=!1,pr(!1),Xn("Linked to PlotDirector"),Qn(""),xr(),Nr(),hr(t,n,r),c=o,Mn=c?.sceneTitle||zt||"",On=c?.chapterTitle||Yt||"",Hr(le,yr(c?.sceneTitle)),Hr(ue,yr(c?.revisionStatus||c?.revisionStatusName||"Not provided")),Hr(pe,yr(c?.estimatedWords)),Hr(he,yr(c?.actualWords)),Hr(Ce,yr(c?.actualWords)),Hr(me,c?.blocked?"Blocked":"Not blocked"),c?.blockedReason?(Hr(we,c.blockedReason),nr(ye,!1)):(Hr(we,"-"),nr(ye,!0)),ve&&(ve.textContent=c?.writingBrief||"No writing brief has been added for this scene."),Bn={characters:Array.isArray(c?.characters)?c.characters:[],assets:Array.isArray(c?.assets)?c.assets:[],locations:Array.isArray(c?.locations)?c.locations:[],primaryLocationId:c?.primaryLocationId??null},Dr(Ee,Bn.characters,"character",!!_t&&!Ln),Dr(Ne,Bn.assets,"asset",!!_t&&!Ln),Ar(Bn.locations,Bn.primaryLocationId,!!_t&&!Ln),dr(),Cr(Ln?"Refresh Current Scene before saving.":_t?"Ready to save.":"No resolved PlotDirector scene."),nr(de,!1),nr(ke,!1),nr(xe,!1),uo()},Hr=(e,t)=>{if(e){const n=null==t?"":String(t);e.textContent!==n&&(e.textContent=n)}},Br=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("host")&&Hr(Nt,e.host),t("platform")&&Hr(Lt,e.platform),t("ready")&&Hr(qt,e.ready),t("wordApi")&&Hr(Pt,e.wordApi),t("lastScan")&&Hr(Dt,e.lastScan),t("lastError")&&Hr(At,e.lastError),t("paragraphs")&&Hr(Wt,e.paragraphs),t("heading1")&&Hr(Ut,e.heading1),t("heading2")&&Hr(Mt,e.heading2)},Gr=e=>{const t=[];return e?.name&&t.push(e.name),e?.code&&e.code!==e.name&&t.push(e.code),e?.message&&t.push(e.message),e?.debugInfo?.errorLocation&&t.push(`Location: ${e.debugInfo.errorLocation}`),t.length>0?t.join(": "):String(e)},Fr=async()=>{if(!window.Office||"function"!=typeof window.Office.onReady)return Gt=!1,Ft=!1,Vt="Unavailable",Jt="Unavailable",Br({host:Vt,platform:Jt,ready:"No",wordApi:"No"}),null;const e=await window.Office.onReady();return Gt=!0,Vt=e?.host||"Unknown",Jt=e?.platform||"Unknown",Ft=!!window.Word&&!!window.Office.HostType&&e?.host===window.Office.HostType.Word,Br({host:Vt,platform:Jt,ready:"Yes",wordApi:Ft?"Yes":"No"}),e},Vr=e=>{try{const t=window.localStorage.getItem(e),n=Number.parseInt(t||"",10);return Number.isInteger(n)&&n>0?n:null}catch{return null}},Jr=(e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}},Yr=(e,t)=>{if(!e)return;e.innerHTML="";const n=document.createElement("option");n.value="",n.textContent=t,e.append(n),e.disabled=!0},zr=(e,t,n,r,a)=>{if(!e)return;e.innerHTML="";const o=document.createElement("option");o.value="",o.textContent=t,e.append(o);for(const t of n){const n=document.createElement("option");n.value=String(t[r]),n.textContent=t[a],e.append(n)}e.disabled=0===n.length},Kr=e=>{const t=String(e?.title||"").trim(),n=String(e?.subtitle||"").trim();return n?`${t}: ${n}`:t},Qr=()=>{const e=Number.parseInt(M?.value||"",10);return Ht.find(t=>t.projectId===e)||null},Xr=()=>{const e=Number.parseInt(O?.value||"",10);return Bt.find(t=>t.bookId===e)||null},Zr=()=>{const e=Number.parseInt(h?.value||"",10);return Ht.find(t=>t.projectId===e)||null},_r=()=>{const e=Number.parseInt(m?.value||"",10);return Bt.find(t=>t.bookId===e)||null},ea=e=>Hr(S,e),ta=()=>{const e=Zr(),t=_r(),n=bn&&Date.now()-In>=750;f&&(f.disabled=!e||!t||kn),w&&(w.disabled=!e||!String(y?.value||"").trim()||kn),q&&(q.disabled=!fn?.canImport||!gn||kn),x&&(x.disabled=!n||vn||0===oa().length)},na=e=>{nr(p,!e),nr(d,e);for(const t of u)nr(t,!!e||"scene"!==t.dataset.tabPanel&&!t.classList.contains("is-active"));e||Jn()},ra=()=>{if(!h)return;if(0===Ht.length)return void Yr(h,"No projects available.");zr(h,"Choose a project",Ht,"projectId","title");const e=Number.parseInt(M?.value||"",10);Number.isInteger(e)&&e>0&&(h.value=String(e))},aa=(e="Select a Project and Book to begin.")=>{fn=null,gn=null,Sn=[],Cn=!1,bn=!1,In=0,nr(C,!0),nr(L,!0),nr(b,!0),nr(v,!0),C&&(C.innerHTML=""),k&&(k.innerHTML=""),Hr(I,""),ea(e),ta()},oa=()=>k?[...k.querySelectorAll("input[type='checkbox']:checked")].map(e=>String(e.value||"").trim()).filter(Boolean):[],ca=e=>{if(Sn=Array.isArray(e)?e:[],b&&k){if(k.innerHTML="",nr(b,!1),nr(v,!Cn||0===Sn.length),nr(x,!1),nr(E,!1),nr(N,!0),0===Sn.length)return Hr(I,"No likely major characters found."),void ta();Hr(I,`${Sn.length} likely major characters found.`);for(const e of Sn){const t=document.createElement("label");t.className="word-companion-character-candidate";const n=document.createElement("input");n.type="checkbox",n.value=e.text||"",n.checked="high"===String(e.confidence||"").trim().toLowerCase(),n.addEventListener("change",ta);const r=document.createElement("strong");r.textContent=e.text||"";const a=document.createElement("em"),o=String(e.reason||"").trim();a.textContent=o?`${Number(e.mentionCount||0).toLocaleString()} mentions · ${o}`:`${Number(e.mentionCount||0).toLocaleString()} mentions`;const c=document.createElement("span");c.className="word-companion-character-candidate-text",c.append(r,a),t.append(n,c),k.append(t)}ta()}},ia=()=>{const e=window.Office?.context?.document?.settings;if(!e)return null;const t=String(e.get(r)||"").trim(),n=Number.parseInt(e.get(a)||"",10),i=Number.parseInt(e.get(o)||"",10),s=Number.parseInt(e.get(c)||"",10);return!t||!Number.isInteger(n)||n<=0||!Number.isInteger(i)||i<=0?null:{documentGuid:t,bookId:n,projectId:i,bindingVersion:Number.isInteger(s)&&s>0?s:1}},sa=()=>pn?.documentGuid?pn.documentGuid:window.crypto?.randomUUID?window.crypto.randomUUID():"10000000-1000-4000-8000-100000000000".replace(/[018]/g,e=>(Number(e)^16*Math.random()>>Number(e)/4).toString(16)),da=()=>{const e=Qr(),t=Xr();W&&(W.textContent=e?.title||"(Not connected)"),U&&(U.textContent=t?Kr(t):"(Not connected)"),Q&&(Q.textContent=t?"":"Select a PlotDirector book before refreshing."),sr()},la=e=>String(e?.styleBuiltIn||e?.style||"").replace(/\s+/g,"").toLowerCase(),ua=(e,t)=>{const n=la(e);return n===`heading${t}`||n.endsWith(`.heading${t}`)||n.includes(`heading${t}`)},pa=e=>String(e||"").trim().split(/\s+/).filter(Boolean).length,ha=(e,t)=>{const n=String(e||"").match(new RegExp(`^${t}-(\\d+)$`,"i"));if(!n)return null;const r=Number.parseInt(n[1],10);return Number.isInteger(r)&&r>0?r:null},ma=e=>{try{return Array.isArray(e?.contentControls?.items)?e.contentControls.items:[]}catch(e){return console.warn("Word paragraph content controls were not available.",e),[]}},ya=(e,t)=>{const n=ma(e);for(const e of n){const n=ha(e.tag,t);if(n)return n}return null},wa=(e,t)=>{const n=[];let r=0,a=0,o=null,c=null;e.forEach((e,t)=>{const i=String(e.text||"").trim();if(i){if(ua(e,1))return r+=1,o={index:n.length+1,paragraphIndex:t,title:i,anchorId:ya(e,"PD-CHAPTER"),scenes:[]},n.push(o),void(c=null);if(ua(e,2)){if(a+=1,!o)return;return c={index:o.scenes.length+1,paragraphIndex:t,title:i,anchorId:ya(e,"PD-SCENE"),wordCount:0},void o.scenes.push(c)}c&&(c.wordCount+=pa(i))}});const i=t.find(e=>String(e.text||"").trim()),s=i?e.findIndex(e=>{return t=e,n=i,String(t?.text||"").trim()===String(n?.text||"").trim()&&la(t)===la(n);var t,n}):-1,d=s>=0&&n.filter(e=>e.paragraphIndex<=s).at(-1)||null,l=d&&s>=0&&d.scenes.filter(e=>e.paragraphIndex<=s).at(-1)||null;return{chapters:n,currentChapter:d,currentScene:l,paragraphCount:e.length,heading1Count:r,heading2Count:a}},fa=new Set(["***","###"]),ga=(e,t)=>{const n=String(e?.text||"").trim();return{index:t,text:n,styleBuiltIn:e?.styleBuiltIn||"",style:e?.style||"",wordCount:pa(n),chapterAnchorId:null,sceneAnchorId:null}},Sa=(e,t)=>{e&&(e.endParagraphIndex=t)},Ca=(e,t)=>{e&&(e.endParagraphIndex=t,Sa(e.scenes.at(-1),t))},ba=(e,t)=>{const n=(t||[]).find(e=>String(e.text||"").trim());if(!e||!n)return e?.currentParagraphIndex??-1;const r=e.paragraphs.filter(e=>((e,t)=>String(e?.text||"").trim()===String(t?.text||"").trim()&&la(e)===la(t))(e,n)).map(e=>e.index);return 0===r.length?e.currentParagraphIndex??-1:Number.isInteger(e.currentParagraphIndex)?r.reduce((t,n)=>Math.abs(n-e.currentParagraphIndex)<Math.abs(t-e.currentParagraphIndex)?n:t,r[0]):r[0]},Ia=e=>{if(!mn)return!1;const t=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.chapters.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(mn,e),n=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.scenes.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(t,e),r=t?.startParagraphIndex!==mn.currentChapter?.startParagraphIndex||n?.startParagraphIndex!==mn.currentScene?.startParagraphIndex||t?.anchorId!==mn.currentChapter?.anchorId||n?.anchorId!==mn.currentScene?.anchorId;return mn.currentParagraphIndex=e,mn.currentChapter=t,mn.currentScene=n,!!r&&(er(t?.title,n?.title,n?.wordCount,t?.anchorId,n?.anchorId,t?.index),r)},ka=e=>{if(!X)return;if(X.innerHTML="",0===e.chapters.length){const e=document.createElement("p");return e.textContent="No chapters detected. Use Heading 1 for chapter titles.",void X.append(e)}if(!e.chapters.some(e=>e.scenes.length>0)){const e=document.createElement("p");e.textContent="No scenes detected. Use Heading 2 for scene titles.",X.append(e)}for(const t of e.chapters){const e=document.createElement("div");e.className="word-companion-outline-chapter";const n=document.createElement("strong");if(n.textContent=t.title,e.append(n),t.scenes.length>0){const n=document.createElement("ul");for(const e of t.scenes){const t=document.createElement("li");t.textContent=e.title,n.append(t)}e.append(n)}X.append(e)}},va=[{key:"alreadyLinked",title:"Already Linked"},{key:"couldLink",title:"Could Link"},{key:"wouldCreateChapters",title:"Would Create Chapters"},{key:"wouldCreateScenes",title:"Would Create Scenes"},{key:"manualReview",title:"Manual Review Required"}],xa={alreadyLinked:"Already Linked",couldLink:"Could Link",wouldCreateChapter:"Would Create Chapter",wouldCreateScene:"Would Create Scene",manualReview:"Manual Review Required"},Ea={alreadyLinked:"✓",couldLink:"~",wouldCreateChapter:"+",wouldCreateScene:"+",manualReview:"?"},Na=(e,t)=>$r(e,t).toLocaleLowerCase(),La=({category:e,action:t,type:n,wordTitle:r,match:a="",anchorStatus:o="None",matches:c=[],pdChapter:i=null,pdScene:s=null,wordChapter:d=null,wordScene:l=null,parentItem:u=null})=>({id:`${n}-${d?.index||0}-${l?.index||0}-${d?.paragraphIndex??l?.paragraphIndex??0}`,category:e,action:t,type:n,wordTitle:r,match:a,anchorStatus:o,matches:c,pdChapter:i,pdScene:s,wordChapter:d,wordScene:l,parentItem:u,result:"Pending",error:""}),qa=(e,t)=>{Array.isArray(e[t.category])&&e[t.category].push(t)},Pa=e=>Array.isArray(e?.scenes)?e.scenes:[],Da=(e,t,n)=>{const r=e.anchorId?`PD-CHAPTER-${e.anchorId}`:"None";if(e.anchorId){const a=t.find(t=>t.chapterId===e.anchorId);if(a){const t=La({category:"alreadyLinked",action:"alreadyLinked",type:"Chapter",wordTitle:e.title,match:`Chapter ${a.chapterId}: ${a.title}`,anchorStatus:r,pdChapter:a,wordChapter:e});return qa(n,t),t}const o=La({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:`${r} not found`,matches:[],pdChapter:null,wordChapter:e});return qa(n,o),o}const a=t.filter(t=>Na(t.title,"chapter")===Na(e.title,"chapter"));if(1===a.length){const t=La({category:"couldLink",action:"couldLink",type:"Chapter",wordTitle:e.title,match:`Chapter ${a[0].chapterId}: ${a[0].title}`,anchorStatus:r,pdChapter:a[0],wordChapter:e});return qa(n,t),t}if(a.length>1){const t=La({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:r,matches:a.map(e=>`Chapter ${e.chapterId}: ${e.title}`),pdChapter:null,wordChapter:e});return qa(n,t),t}const o=La({category:"wouldCreateChapters",action:"wouldCreateChapter",type:"Chapter",wordTitle:e.title,anchorStatus:r,pdChapter:null,wordChapter:e});return qa(n,o),o},Aa=(e,t,n,r)=>{const a=e.anchorId?`PD-SCENE-${e.anchorId}`:"None";if(e.anchorId){const o=((e,t)=>{for(const n of e){const e=Pa(n).find(e=>e.sceneId===t);if(e)return{chapter:n,scene:e}}return null})(n,e.anchorId);return o?void qa(r,La({category:"alreadyLinked",action:"alreadyLinked",type:"Scene",wordTitle:e.title,match:`Scene ${o.scene.sceneId}: ${o.scene.title}`,anchorStatus:a,pdChapter:o.chapter,pdScene:o.scene,wordChapter:t?.wordChapter,wordScene:e,parentItem:t})):void qa(r,La({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:`${a} not found`,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}))}if(!t?.pdChapter&&"manualReview"===t?.category)return void qa(r,La({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:a,matches:["Parent chapter requires manual review."],wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));if(!t?.pdChapter)return void qa(r,La({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:a,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));const o=Pa(t.pdChapter).filter(t=>Na(t.title,"scene")===Na(e.title,"scene"));1!==o.length?o.length>1?qa(r,La({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:a,matches:o.map(e=>`Scene ${e.sceneId}: ${e.title}`),wordChapter:t.wordChapter,wordScene:e,parentItem:t})):qa(r,La({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:a,pdChapter:t.pdChapter,wordChapter:t.wordChapter,wordScene:e,parentItem:t})):qa(r,La({category:"couldLink",action:"couldLink",type:"Scene",wordTitle:e.title,match:`Scene ${o[0].sceneId}: ${o[0].title}`,anchorStatus:a,pdChapter:t.pdChapter,pdScene:o[0],wordChapter:t.wordChapter,wordScene:e,parentItem:t}))},Ta=e=>{const t=document.createElement("article");t.className="word-companion-preview-item";const n=document.createElement("strong");n.textContent=`${Ea[e.action]||""} ${e.type}: ${e.wordTitle}`,t.append(n);const r=document.createElement("span");if(r.textContent=`Anchor: ${e.anchorStatus||"None"}`,t.append(r),e.match){const n=document.createElement("span");n.textContent=`Match: ${e.match}`,t.append(n)}if(Array.isArray(e.matches)&&e.matches.length>0){const n=document.createElement("div");n.className="word-companion-preview-matches";const r=document.createElement("span");r.textContent="Matches:",n.append(r);const a=document.createElement("ul");for(const t of e.matches){const e=document.createElement("li");e.textContent=t,a.append(e)}n.append(a),t.append(n)}const a=document.createElement("span");if(a.textContent=`Action: ${xa[e.action]||e.action}`,t.append(a),e.result&&"Pending"!==e.result){const n=document.createElement("span");n.textContent=e.error?`Result: ${e.result} - ${e.error}`:`Result: ${e.result}`,t.append(n)}return t},$a=e=>{if(te){te.innerHTML="";for(const t of va){const n=document.createElement("section");n.className="word-companion-preview-group";const r=document.createElement("strong");r.textContent=t.title,n.append(r);const a=Array.isArray(e?.[t.key])?e[t.key]:[];if(0===a.length){const e=document.createElement("p");e.className="word-companion-empty-list",e.textContent="None",n.append(e)}else for(const e of a)n.append(Ta(e));te.append(n)}ir()}},ja=async e=>{const t=e.document.body.paragraphs,n=e.document.getSelection().paragraphs;t.load("text,styleBuiltIn,style"),n.load("text,styleBuiltIn,style"),await e.sync();try{for(const e of t.items)(ua(e,1)||ua(e,2))&&e.contentControls.load("items/tag,title");await e.sync()}catch(e){console.warn("Unable to load Word heading content controls. Continuing without PlotDirector anchors.",e)}const r=wa(t.items,n.items);return r.bodyParagraphs=t.items,r},Ra=async(e,t)=>{const n=e.document.body.paragraphs,r=e.document.getSelection().paragraphs;n.load("text,styleBuiltIn,style"),r.load("text,styleBuiltIn,style"),await e.sync();const a=((e,t)=>{const n=e.map(ga),r=[];let a=0,o=0,c=null,i=null,s=0;const d=(e,t=null,n=null)=>c?(Sa(i,e.index-1),i={index:c.scenes.length+1,paragraphIndex:e.index,startParagraphIndex:e.index,endParagraphIndex:e.index,title:t||`Scene ${c.scenes.length+1}`,anchorId:n,wordCount:0},c.scenes.push(i),i):null;for(const e of n)e.text&&(ua(e,1)?(Ca(c,e.index-1),a+=1,c={index:r.length+1,paragraphIndex:e.index,startParagraphIndex:e.index,endParagraphIndex:e.index,title:e.text,anchorId:e.chapterAnchorId,wordCount:0,scenes:[]},r.push(c),i=null,d(e,"Scene 1",e.sceneAnchorId),s+=e.wordCount):c&&(t&&fa.has(e.text)?(o+=1,d(e)):(c.wordCount+=e.wordCount,i&&(i.wordCount+=e.wordCount),s+=e.wordCount)));return Ca(c,n.length-1),{paragraphs:n,chapters:r,usesExplicitScenes:!!t,paragraphCount:n.length,heading1Count:a,heading2Count:o,documentWordCount:s,currentParagraphIndex:null,currentChapter:null,currentScene:null}})(n.items,t),o=ba(a,r.items);return mn=a,Ia(o),Gn("Cache rebuilt."),a},Wa=async()=>{if(Qn(""),!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return er(null,null,null),Qn("Word document access is unavailable."),Br({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;F&&(F.disabled=!0,F.textContent="Scanning..."),Qn("Scanning document structure...");try{const e=await window.Word.run(async e=>{const t=Xr();return t?await Ra(e,!!t.usesExplicitScenes):(mn=null,await ja(e))});return mn||er(e.currentChapter?.title,e.currentScene?.title,e.currentScene?.wordCount,e.currentChapter?.anchorId,e.currentScene?.anchorId,e.currentChapter?.index),qr("Not detected"),ka(e),Qn(""),Br({lastScan:"Success",lastError:"-",paragraphs:String(e.paragraphCount),heading1:String(e.heading1Count),heading2:String(e.heading2Count)}),!0}catch(e){const t=Gr(e);return console.error("Unable to scan the Word document.",e),er(null,null,null),Qn(`Unable to scan the Word document: ${t}`),Br({lastScan:"Failure",lastError:t}),!1}finally{F&&(F.disabled=!1,F.textContent="Refresh Document Structure")}},Ua=async()=>{const e=Xr();if(!Qr()||!e)return ar("Select a project and book to analyse manuscript structure."),!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return ar("Word document access is unavailable."),Br({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;Z&&(Z.disabled=!0,Z.textContent="Analysing..."),ar("Analysing manuscript structure...");try{const t=await window.Word.run(async e=>await ja(e)),n=await Ja(`/api/word-companion/books/${e.bookId}/structure`);return er(t.currentChapter?.title,t.currentScene?.title,t.currentScene?.wordCount,t.currentChapter?.anchorId,t.currentScene?.anchorId,t.currentChapter?.index),ka(t),un=((e,t)=>{const n={alreadyLinked:[],couldLink:[],wouldCreateChapters:[],wouldCreateScenes:[],manualReview:[]},r=Array.isArray(t?.chapters)?t.chapters:[];for(const t of Array.isArray(e?.chapters)?e.chapters:[]){const e=Da(t,r,n);for(const a of Pa(t))Aa(a,e,r,n)}return n})(t,n),$a(un),ar("Preview generated. No changes have been applied."),Br({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),!0}catch(e){return console.error("Unable to analyse manuscript structure.",e),ar("Unable to analyse manuscript structure."),Br({lastScan:"Failure",lastError:Gr(e)}),!1}finally{Z&&(Z.textContent="Analyse Manuscript Structure",sr())}},Ma=e=>{En&&(En(e),En=null),ut?.close?ut.close():ut&&(ut.hidden=!0)},Oa=()=>{const e=((e=un)=>{const t=cr(e);return{linkChapters:t.filter(e=>"couldLink"===e.category&&"Chapter"===e.type).length,linkScenes:t.filter(e=>"couldLink"===e.category&&"Scene"===e.type).length,createChapters:t.filter(e=>"wouldCreateChapters"===e.category).length,createScenes:t.filter(e=>"wouldCreateScenes"===e.category).length,manualReview:Array.isArray(e?.manualReview)?e.manualReview.length:0}})();return(e=>{if(!pt)return;pt.innerHTML="";const t=[`Link ${e.linkChapters+e.linkScenes} chapters/scenes`,`Create ${e.createChapters} chapters`,`Create ${e.createScenes} scenes`],n=document.createElement("ul");for(const e of t){const t=document.createElement("li");t.textContent=e,n.append(t)}pt.append(n)})(e),ut?new Promise(e=>{En=e,ut.showModal?ut.showModal():ut.hidden=!1}):Promise.resolve(window.confirm(`Apply Structure Sync?\n\nThis will:\n\n- Link ${e.linkChapters+e.linkScenes} chapters/scenes\n- Create ${e.createChapters} chapters\n- Create ${e.createScenes} scenes\n\nManual review items will be skipped.`))},Ha=(e,t,n="")=>{e.result=t,e.error=n},Ba=e=>Number.isInteger(e?.wordChapter?.index)&&e.wordChapter.index>0?10*e.wordChapter.index:null,Ga=e=>Number.isInteger(e?.wordScene?.index)&&e.wordScene.index>0?10*e.wordScene.index:null,Fa=async(e,t)=>{const n=await Ya(`/api/word-companion/books/${e}/chapters`,{title:Tr(t.wordTitle),sortOrder:Ba(t)});if(!n?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");Sr(),t.pdChapter={chapterId:n.chapterId,title:n.title||t.wordTitle,sortOrder:n.sortOrder||Ba(t)||0,scenes:[]},t.match=`Chapter ${t.pdChapter.chapterId}: ${t.pdChapter.title}`},Va=async(e,t)=>{const n=t.pdChapter||t.parentItem?.pdChapter;if(!n?.chapterId)throw new Error("Scene parent chapter is not available.");const r=await Ya(`/api/word-companion/books/${e}/chapters/${n.chapterId}/scenes`,{sceneTitle:Tr(t.wordTitle),sortOrder:Ga(t)});if(!r?.sceneId)throw new Error("Scene creation did not return a scene ID.");Sr(),t.pdChapter=n,t.pdScene={sceneId:r.sceneId,title:t.wordTitle,sortOrder:Ga(t)||0},t.match=`Scene ${t.pdScene.sceneId}: ${t.pdScene.title}`},Ja=async(e,t={})=>{const n=await window.fetch(e,{credentials:"same-origin",...t,headers:{Accept:"application/json",...t.headers||{}}});if(!n.ok)throw new Error(`Request failed: ${n.status}`);return await n.json()},Ya=(e,t)=>Ja(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),za=async(e="")=>{bn=!1,In=0,Sn=[],k&&(k.innerHTML=""),nr(b,!0),na(!1),ea(""),nr(v,!0),e&&Qn(e);const t=await Ka();e&&t&&Yt&&Qn(e)},Ka=async()=>{const e=Xr();if(!(e&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run))return!1;Qn("Reading manuscript position...");try{Sr(),await Rr(e.bookId);const t=await window.Word.run(async t=>await Ra(t,!!e.usesExplicitScenes));return ka(t),Br({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),Yt?(zt?await ho():await po(),pr(!1),ur("Live"),Qn(""),!0):(qr("Not detected"),pr(!1),ur("Live"),Qn("Manuscript linked. Click inside a chapter to show the current scene."),!0)}catch(e){return console.error("Unable to initialise bound manuscript runtime.",e),mn=null,ur("Manual"),Qn(`Unable to read manuscript position: ${Gr(e)}`),Br({lastScan:"Failure",lastError:Gr(e)}),!1}},Qa=e=>e?[...e.querySelectorAll("input[type='checkbox']:checked")].map(e=>Number.parseInt(e.value||"",10)).filter(e=>Number.isInteger(e)&&e>0):[],Xa=()=>{const e=Number.parseInt(Le?.value||"",10);return Number.isInteger(e)&&e>0?e:null},Za=(e,t,n,r)=>{const a=((e,t)=>ma(e).find(e=>ha(e.tag,t))||null)(e,r),o=a||e.getRange().insertContentControl();return o.title=t,o.tag=n,o.appearance="Hidden",o},_a=async(e="PlotDirector IDs attached successfully.")=>{if(!_t||!en)return Qn("No resolved PlotDirector scene."),!1;if((Zt&&Zt!==_t||Xt&&Xt!==en)&&!window.confirm("This scene is already linked. Replace the existing PlotDirector link?"))return!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return Qn("Word document access is unavailable."),!1;se&&(se.disabled=!0,se.textContent="Attaching...");try{return await window.Word.run(async e=>{const t=await ja(e);if(!t.currentChapter||!t.currentScene)throw new Error("No scene detected in Word. Use Heading 2 for scenes.");const n=t.bodyParagraphs[t.currentChapter.paragraphIndex],r=t.bodyParagraphs[t.currentScene.paragraphIndex];if(!n||!r)throw new Error("Unable to locate the current Word headings.");Za(n,"PlotDirector Chapter",`PD-CHAPTER-${en}`,"PD-CHAPTER"),Za(r,"PlotDirector Scene",`PD-SCENE-${_t}`,"PD-SCENE"),await e.sync()}),Xt=en,Zt=_t,rn=!1,nn="SceneID Anchor",tn="Anchor",Qn(e),Br({lastError:"-"}),_n(),!0}catch(e){return console.error("Unable to attach PlotDirector IDs.",e),Qn("Unable to attach PlotDirector IDs."),Br({lastError:Gr(e)}),_n(),!1}finally{se&&(se.textContent=Zt===_t?"Attach PlotDirector IDs":"Reattach PlotDirector IDs",_n())}},eo=async e=>{if(!en)return Ir("No resolved PlotDirector chapter."),!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return Ir("Word document access is unavailable."),!1;try{return await window.Word.run(async e=>{const t=await ja(e);if(!t.currentChapter)throw new Error("No chapter detected in Word. Use Heading 1 for chapters.");const n=t.bodyParagraphs[t.currentChapter.paragraphIndex];if(!n)throw new Error("Unable to locate the current Word chapter heading.");Za(n,"PlotDirector Chapter",`PD-CHAPTER-${en}`,"PD-CHAPTER"),await e.sync()}),Xt=en,rn=!1,nn="ChapterID Anchor",tn="Chapter anchor",Ir(e),Qn(e),Br({lastError:"-"}),_n(),!0}catch(e){return console.error("Unable to attach PlotDirector chapter ID.",e),Ir("Unable to attach PlotDirector chapter ID."),Br({lastError:Gr(e)}),_n(),!1}},to=async e=>{xr(),await ho(),Qn(e),Ir(e)},no=e=>{ln&&(ln(e),ln=null),ct?.close?ct.close():ct&&(ct.hidden=!0)},ro=()=>{if(!nt)return;const e=Tr(tt?.value||"").toLocaleLowerCase(),t=sn.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(nt.innerHTML="",dn=null,rt&&(rt.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No chapters found.",void nt.append(e)}for(const e of t){const t=Number.parseInt(e.chapterId||"",10);if(!Number.isInteger(t)||t<=0)continue;const n=document.createElement("label");n.className="word-companion-scene-option";const r=document.createElement("input");r.type="radio",r.name="word-companion-link-chapter",r.value=String(t),r.addEventListener("change",()=>{dn=t,rt&&(rt.disabled=!1)});const a=document.createElement("span");a.textContent=e.title||"Untitled chapter",n.append(r,a),nt.append(n)}},ao=()=>{et?.close?et.close():et&&(et.hidden=!0)},oo=async(e,t,n)=>{const r=Xr();if(!r)return br("Select a PlotDirector book first."),!1;await Or(r.bookId,e,t,"Manual link","Title Match");return!!await _a(n)&&(br(n),Nr(),!0)},co=e=>{cn&&(cn(e),cn=null),Ke?.close?Ke.close():Ke&&(Ke.hidden=!0)},io=()=>{if(!Ve)return;const e=Tr(Fe?.value||"").toLocaleLowerCase(),t=an.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(Ve.innerHTML="",on=null,Je&&(Je.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No scenes found.",void Ve.append(e)}for(const e of t){const t=Number.parseInt(e.sceneId||"",10);if(!Number.isInteger(t)||t<=0)continue;const n=document.createElement("label");n.className="word-companion-scene-option";const r=document.createElement("input");r.type="radio",r.name="word-companion-link-scene",r.value=String(t),r.addEventListener("change",()=>{on=t,Je&&(Je.disabled=!1)});const a=document.createElement("span");a.textContent=e.title||"Untitled scene",n.append(r,a),Ve.append(n)}},so=()=>{Ge?.close?Ge.close():Ge&&(Ge.hidden=!0)},lo=async()=>{if(!_t)return void rr("No resolved PlotDirector scene.");if(!en)return void rr("No resolved PlotDirector chapter.");if(Ln)return void rr("Refresh Current Scene before syncing.");const e=Xr(),t=pn?.documentGuid||ia()?.documentGuid||"";if(!e||!t)return void rr("Bound manuscript metadata is unavailable.");if(Rn)return;tr(),Rn=!0;let n=Kt;try{n=await(async()=>{const e=mn?.currentScene;return e&&Number.isInteger(e.startParagraphIndex)&&Number.isInteger(e.endParagraphIndex)&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run?await window.Word.run(async t=>{const n=t.document.body.paragraphs;n.load("text"),await t.sync();let r=0;const a=Math.min(e.endParagraphIndex,n.items.length-1),o=mn.currentChapter?.startParagraphIndex;for(let t=e.startParagraphIndex;t<=a;t+=1){const e=String(n.items[t]?.text||"").trim();e&&!fa.has(e)&&t!==o&&(r+=pa(e))}return e.wordCount=r,er(mn.currentChapter?.title,e.title,r,mn.currentChapter?.anchorId,e.anchorId,mn.currentChapter?.index),r}):Kt})()}catch(e){return rr("Sync failed"),Br({lastError:Gr(e)}),Rn=!1,void lr()}if(!Number.isInteger(n)||n<0)return rr("Sync failed"),Rn=!1,void lr();if(Wn===_t&&Un===n)return rr("Synced"),Rn=!1,void lr();ge&&(ge.disabled=!0,ge.textContent="Syncing..."),rr("Syncing...");try{const r=await Ya("/api/word-companion/runtime/scene-word-count",{documentGuid:t,bookId:e.bookId,chapterId:en,sceneId:_t,wordCount:n}),a=r?.actualWords??n,o=new Date;Wn=_t,Un=a,Hr(Ce,yr(a)),Hr(he,yr(a)),Hr(be,wr(o)),Hr(fe,wr(o)),rr("Synced")}catch(e){rr("Sync failed"),Br({lastError:Gr(e)})}finally{Rn=!1,ge&&(ge.textContent="Sync Current Scene"),lr()}},uo=(e=4e3)=>{tr(),_t&&en&&!Ln&&!Rn&&(jn=window.setTimeout(()=>{jn=null,lo()},e))},po=async()=>{const e=Qr(),t=Xr(),n=$r(Yt,"chapter");if(jr({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?Kr(t):void 0,detectedChapter:Yt,detectedScene:zt,requestChapter:n,requestScene:"",result:"Not run",chapterId:null,sceneId:null}),!t)return qr("Not detected"),Qn("Select a PlotDirector book first."),!1;if(!Yt)return qr("Not detected"),Qn("No chapter detected in Word. Use Heading 1 for chapters."),!1;qr("Not detected");try{const e=await Wr(t.bookId),r=Xt?e.find(e=>e.chapterId===Xt):null,a=n.toLocaleLowerCase(),o=a?e.find(e=>$r(e.title,"chapter").toLocaleLowerCase()===a):null,c=r||o;return c?(xr(),hr(null,c.chapterId,r?"Chapter anchor":"Chapter title"),nn=r?"ChapterID Anchor":"Title Match",Xn("Chapter linked to PlotDirector"),Qn("No scene detected in Word. Use Heading 2 for scenes."),jr({result:"Chapter matched",chapterId:c.chapterId,sceneId:null}),!0):(hr(null),Xn("Chapter not found in PlotDirector."),Qn("Chapter not found in PlotDirector."),jr({result:"Chapter not matched",chapterId:null,sceneId:null}),Er("Chapter not found in PlotDirector."),!1)}catch(e){return qr("Not found in PlotDirector"),Br({lastError:Gr(e)}),Qn("Unable to load PlotDirector chapter data."),!1}},ho=async()=>{const e=Qr(),t=Xr(),n=$r(Yt,"chapter"),r=$r(zt,"scene");if(jr({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?Kr(t):void 0,detectedChapter:Yt,detectedScene:zt,requestChapter:n,requestScene:r,result:"Not run",chapterId:null,sceneId:null}),Zn({anchorType:Zt?"SceneID Anchor":Xt?"ChapterID Anchor":"Title Match",storedSceneId:Zt,storedChapterId:Xt,resolutionMethod:"-"}),!t)return qr("Not detected"),Qn("Select a PlotDirector book first."),jr({result:"Error"}),!1;if(!Yt||!zt)return qr("Not detected"),Qn("No scene detected in Word. Use Heading 2 for scenes."),jr({result:"Error"}),!1;ne&&(ne.disabled=!0,ne.textContent="Refreshing...");const a=()=>{ne&&(ne.disabled=!1,ne.textContent="Refresh PlotDirector Scene")};qr("Not detected"),Qn("Resolving PlotDirector scene...");try{if(Zt){const e=await(async(e,t)=>{const n=await Ja(`/api/word-companion/books/${e}/structure`),r=Array.isArray(n?.chapters)?n.chapters:[];for(const e of r){const n=Array.isArray(e.scenes)?e.scenes:[];for(const r of n)if(t(e,r))return{chapter:e,scene:r}}return null})(t.bookId,(e,t)=>t.sceneId===Zt);if(e)return jr({result:"Matched",chapterId:e.chapter.chapterId,sceneId:e.scene.sceneId}),await Or(t.bookId,e.scene.sceneId,e.chapter.chapterId,"Anchor","SceneID Anchor"),!0;rn=!0,nn="SceneID Anchor",Xn("Not found in PlotDirector"),Qn("Stored PlotDirector ID is invalid."),jr({result:"Error",chapterId:Xt,sceneId:Zt}),Zn({anchorType:"SceneID Anchor",storedSceneId:Zt,storedChapterId:Xt,resolutionMethod:"Anchor"})}if(Xt){const e=(await Rr(t.bookId)).find(e=>e.chapterId===Xt),n=e?(Array.isArray(e.scenes)?e.scenes:[]).find(e=>$r(e.title,"scene").toLocaleLowerCase()===r.toLocaleLowerCase()):null;if(n)return jr({result:"Matched",chapterId:e.chapterId,sceneId:n.sceneId}),await Or(t.bookId,n.sceneId,e.chapterId,"Anchor","ChapterID Anchor"),!0;e&&!Zt?(nn="ChapterID Anchor",hr(null,Xt,"Chapter anchor"),jr({result:"Chapter matched",chapterId:Xt,sceneId:null})):Zt||(nn="ChapterID Anchor",jr({result:"Chapter anchor not found",chapterId:Xt,sceneId:null}))}const e=await Ya(`/api/word-companion/books/${t.bookId}/resolve-scene`,{chapterTitle:n,sceneTitle:r});if(!e?.matched||!e.sceneId){const t=rn,n=Number.parseInt(e?.chapterId||"",10),r=Number.isInteger(en)&&en>0?en:null,o=Number.isInteger(n)&&n>0?n:r,c=!!e?.chapterMatched||!!o;return qr("Not found in PlotDirector"),rn=t,c&&(hr(null,o,o===r?"Chapter anchor":"Chapter title"),Xn("Scene not found in PlotDirector.")),Qn(t?"Stored PlotDirector ID is invalid.":c?"Scene not found in PlotDirector.":"This chapter does not exist in PlotDirector. Create or link the chapter first."),jr({result:"Not matched",chapterId:c?o:e?.chapterId,sceneId:e?.sceneId}),t||(c?(xr(),Lr("Scene not found in PlotDirector.")):(Nr(),Er("Chapter not found in PlotDirector."))),a(),!1}const o=rn;return jr({result:o?"Matched by title fallback":"Matched",chapterId:e.chapterId,sceneId:e.sceneId}),await Or(t.bookId,e.sceneId,e.chapterId,o?"Title fallback":"Title","Title Match"),o&&(rn=!0,Qn("Stored PlotDirector ID is invalid."),_n()),!0}catch(e){const t=rn;return Br({lastError:Gr(e)}),qr("Not found in PlotDirector"),rn=t,Qn(t?"Stored PlotDirector ID is invalid.":"Unable to load PlotDirector scene data."),jr({result:"Error"}),!1}finally{a()}},mo=async()=>{if(qn=null,$n||!Ot||!Xr())return void Gn("Runtime update skipped.");if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return ur("Manual"),void Qn("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");if(!mn)return ur("Manual"),void Qn("Document structure is not cached yet. Use Refresh Current Scene.");const e=Date.now()-Dn;if(Pn&&e<An)return Gn("Runtime update skipped (typing active)."),void yo(An-e);$n=!0,Pn=!1,ur("Live"),Gn("Runtime update executed.");try{const e=await window.Word.run(async e=>await(async e=>{const t=e.document.getSelection().paragraphs;return t.load("text,styleBuiltIn,style"),await e.sync(),t.items})(e)),t=ba(mn,e);if(!Ia(t))return pr(!1),ur("Live"),void uo();zt?await ho():await po(),pr(!1),ur("Live"),Qn(""),uo()}catch(e){console.error("Unable to refresh current scene from Word selection.",e),Br({lastError:Gr(e)}),pr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving.")}finally{$n=!1}},yo=(e=1800)=>{qn&&window.clearTimeout(qn),qn=window.setTimeout(mo,Math.max(0,e)),Gn("Runtime update scheduled.")},wo=()=>{Pn=!0,Dn=Date.now(),tr(),Gn("Selection changed."),yo()},fo=()=>{if(Tn&&window.Office?.context?.document&&"function"==typeof window.Office.context.document.removeHandlerAsync&&window.Office?.EventType?.DocumentSelectionChanged)try{window.Office.context.document.removeHandlerAsync(window.Office.EventType.DocumentSelectionChanged,{handler:wo}),Tn=!1}catch(e){console.warn("Unable to remove Word selection tracking handler.",e)}},go=async(e,n)=>{if(mn=null,Sr(),!e)return Bt=[],Yr(O,"Select a project first"),Yr(m,"Select a project first"),Kn(""),Jr(t,null),da(),qr("Not detected"),void or();Yr(O,"Loading books..."),Kn(""),qr("Not detected"),or("Select a book to analyse manuscript structure.");try{const r=await Ja(`/api/word-companion/projects/${e}/books`);if(Bt=Array.isArray(r.books)?r.books:[],0===Bt.length)return Yr(O,"No books available."),Yr(m,"No books available."),Kn("No books available."),Jr(t,null),da(),void aa("No books available.");zr(O,"Choose a book",Bt.map(e=>({...e,displayTitle:Kr(e)})),"bookId","displayTitle");const a=Bt.find(e=>e.bookId===n);a&&O?(O.value=String(a.bookId),Jr(t,a.bookId)):Jr(t,null),((e=null)=>{if(!m)return;if(0===Bt.length)return void Yr(m,"No books available.");zr(m,"Choose a book",Bt.map(e=>({...e,displayTitle:Kr(e)})),"bookId","displayTitle");const t=e||Number.parseInt(O?.value||"",10),n=Bt.find(e=>e.bookId===t);n&&(m.value=String(n.bookId)),ta()})(a?.bookId||n),da(),qr((Xr(),"Not detected")),or(Xr()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),aa(_r()?"Ready to scan manuscript structure.":"Select a Book to begin.")}catch{Bt=[],Yr(O,"Unable to load books."),Yr(m,"Unable to load books."),Kn("Unable to load books."),Jr(t,null),da(),qr("Not detected"),or("Unable to load books."),aa("Unable to load books.")}};for(const e of l)e.addEventListener("click",()=>Vn(e.dataset.tabButton));Jn(),M?.addEventListener("change",async()=>{const n=Number.parseInt(M.value||"",10);gr(),h&&Number.isInteger(n)&&n>0&&(h.value=String(n)),Jr(e,Number.isInteger(n)&&n>0?n:null),Jr(t,null),qr("Not detected"),or(),aa("Select a Book to begin."),await go(n,null)}),O?.addEventListener("change",()=>{const e=Number.parseInt(O.value||"",10);gr(),Jr(t,Number.isInteger(e)&&e>0?e:null),m&&Number.isInteger(e)&&e>0&&(m.value=String(e)),da(),qr("Not detected"),or(Xr()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),aa(_r()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),h?.addEventListener("change",async()=>{const n=Number.parseInt(h.value||"",10);gr(),M&&Number.isInteger(n)&&n>0&&(M.value=String(n)),Jr(e,Number.isInteger(n)&&n>0?n:null),Jr(t,null),aa("Select a Book to begin."),await go(n,null)}),m?.addEventListener("change",()=>{const e=Number.parseInt(m.value||"",10);gr(),O&&Number.isInteger(e)&&e>0&&(O.value=String(e)),Jr(t,Number.isInteger(e)&&e>0?e:null),da(),aa(_r()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),y?.addEventListener("input",ta),w?.addEventListener("click",async()=>{const e=Zr(),t=String(y?.value||"").trim();if(e&&t){w.disabled=!0,ea("Creating Book...");try{const n=await Ya(`/api/word-companion/projects/${e.projectId}/books`,{title:t});y&&(y.value=""),M&&(M.value=String(e.projectId)),await go(e.projectId,n.bookId),m&&(m.value=String(n.bookId)),ea("Ready to scan manuscript structure.")}catch(e){console.error("Unable to create Book from Word Companion.",e),ea(`Unable to create Book: ${Gr(e)}`)}finally{ta()}}else ta()}),f?.addEventListener("click",async()=>{const e=Zr(),t=_r();if(e&&t)if(Gt&&Ft&&window.Word&&"function"==typeof window.Word.run){f&&(f.disabled=!0,f.textContent="Scanning..."),ea("Scanning manuscript structure...");try{const n=await window.Word.run(async e=>{const n=e.document.body.paragraphs;return n.load("text,styleBuiltIn,style"),await e.sync(),((e,t)=>{const n=[];let r=null,a=null,o=0;const c=[],i=new Set(["***","###"]),s=()=>{if(!r)return null;const e={title:`Scene ${r.scenes.length+1}`,sortOrder:10*(r.scenes.length+1),wordCount:0};return r.scenes.push(e),e};return e.forEach(e=>{const d=String(e.text||"").trim();if(!d)return;if(c.push(d),ua(e,1))return r={title:d,sortOrder:10*(n.length+1),wordCount:0,scenes:[]},n.push(r),a=s(),void(o+=pa(d));if(!r||!a)return;if(t&&i.has(d))return void(a=s());const l=pa(d);r.wordCount+=l,a.wordCount+=l,o+=l}),{chapters:n,chapterCount:n.length,sceneCount:n.reduce((e,t)=>e+t.scenes.length,0),wordCount:o,documentText:c.join("\n")}})(n.items,!!t.usesExplicitScenes)});gn=n,Cn=!1;const r=await Ya("/api/word-companion/manuscript/analyse",{projectId:e.projectId,bookId:t.bookId,documentGuid:sa(),chapterCount:n.chapterCount,sceneCount:n.sceneCount,wordCount:n.wordCount});fn=r,(e=>{if(!C)return;C.innerHTML="";const t=document.createElement("strong");t.textContent="Manuscript Analysis",C.append(t);const n=document.createElement("dl"),r=[["Project",e.projectTitle],["Book",Kr({title:e.bookTitle,subtitle:e.bookSubtitle})],["Chapters",Number(e.chapterCount||0).toLocaleString()],["Scenes",Number(e.sceneCount||0).toLocaleString()],["Words",Number(e.wordCount||0).toLocaleString()]];for(const[e,t]of r){const r=document.createElement("dt");r.textContent=e;const a=document.createElement("dd");a.textContent=t||"-",n.append(r,a)}C.append(n),nr(C,!1),nr(L,!1),ea(e.message||"Preview generated."),ta()})(r);try{const t=await Ya("/api/word-companion/manuscript/discover-characters",{projectId:e.projectId,documentText:n.documentText||""});Sn=Array.isArray(t?.candidates)?t.candidates:[],nr(b,!0),nr(v,!0)}catch(e){console.error("Unable to discover character candidates.",e),Sn=[],nr(b,!0),nr(v,!0)}Br({lastScan:"Success",lastError:"-",paragraphs:"-",heading1:String(n.chapterCount),heading2:"-"})}catch(e){console.error("Unable to scan manuscript for first-run import.",e),aa(`Unable to scan manuscript: ${Gr(e)}`),Br({lastScan:"Failure",lastError:Gr(e)})}finally{f&&(f.textContent="Scan Manuscript"),ta()}}else aa("Word document access is unavailable.");else aa("Select a Project and Book to begin.")}),q?.addEventListener("click",async()=>{const n=Zr(),i=_r();if(!(n&&i&&gn&&fn?.canImport))return void ta();let s=!1;if(!fn.requiresReplaceConfirmation||(s=await new Promise(e=>{if(!D||"function"!=typeof D.showModal)return void e(window.confirm("This Book already contains planned chapters and scenes.\n\nImporting this manuscript will replace the planned structure.\n\nContinue?"));const t=t=>{A?.removeEventListener("click",n),T?.removeEventListener("click",r),D?.removeEventListener("cancel",a),D?.close(),e(t)},n=()=>t(!0),r=()=>t(!1),a=e=>{e.preventDefault(),t(!1)};A?.addEventListener("click",n),T?.addEventListener("click",r),D?.addEventListener("cancel",a),D.showModal()}),s)){kn=!0,ta(),ea("Importing manuscript structure...");try{const l=sa(),u=await Ya("/api/word-companion/manuscript/import",{projectId:n.projectId,bookId:i.bookId,documentGuid:l,bindingVersion:1,replacePlanned:s,chapters:gn.chapters});if(!u.imported)return fn={...fn,canImport:!u.requiresReplaceConfirmation,requiresReplaceConfirmation:!!u.requiresReplaceConfirmation,message:u.message||fn.message},ea(u.message||"Import was not completed."),void ta();const p=u.manuscriptDocument;await(d={documentGuid:p?.documentGuid||l,bookId:u.bookId,projectId:u.projectId,bindingVersion:p?.bindingVersion||1},new Promise((e,t)=>{const n=window.Office?.context?.document?.settings;n?(n.set(r,d.documentGuid),n.set(a,String(d.bookId)),n.set(o,String(d.projectId)),n.set(c,String(d.bindingVersion||1)),n.saveAsync(n=>{n.status===window.Office.AsyncResultStatus.Succeeded?e():t(n.error||new Error("Unable to save Word document metadata."))})):t(new Error("Word document settings are unavailable."))})),pn={documentGuid:p?.documentGuid||l,bookId:u.bookId,projectId:u.projectId,bindingVersion:p?.bindingVersion||1},Jr(e,u.projectId),Jr(t,u.bookId),M&&(M.value=String(u.projectId));const h=Sn;await go(u.projectId,u.bookId),Yn("Connected"),Cn=!0,bn=h.length>0,In=bn?Date.now():0,Sn=h,h.length>0?(na(!0),ca(h),nr(L,!0),nr(v,!1),ea(u.message||"Manuscript structure imported."),Qn(u.message||"Manuscript structure imported."),window.setTimeout(ta,750)):await za(u.message||"Manuscript structure imported.")}catch(e){console.error("Unable to import manuscript structure.",e),ea(`Unable to import manuscript: ${Gr(e)}`)}finally{kn=!1,ta()}var d}else ea("Import cancelled.")}),x?.addEventListener("click",async()=>{const e=Zr()||Qr(),t=oa();if(!bn||Date.now()-In<750||!e||0===t.length)ta();else{vn=!0,ta(),Hr(I,"Creating selected characters...");try{const n=await Ya("/api/word-companion/manuscript/create-discovered-characters",{projectId:e.projectId,candidateNames:t});Qn(n.message||"Characters created."),Hr(I,`${n.createdCount||0} created, ${n.skippedCount||0} already existed.`),await za(n.message||"Characters created.")}catch(e){console.error("Unable to create discovered characters.",e),Hr(I,`Unable to create characters: ${Gr(e)}`)}finally{vn=!1,ta()}}}),E?.addEventListener("click",()=>za("Character creation skipped.")),N?.addEventListener("click",()=>za()),g?.addEventListener("click",()=>na(!1)),P?.addEventListener("click",()=>aa("Import cancelled.")),F?.addEventListener("click",Wa),Z?.addEventListener("click",Ua),_?.addEventListener("click",async()=>{const e=Xr();if(!e||0===cr().length||xn)return void ir();if(!await Oa())return;xn=!0,sr(),ar("Applying structure sync...");const t={createdChapters:0,createdScenes:0,linkedChapters:0,linkedScenes:0,skipped:Array.isArray(un?.manualReview)?un.manualReview.length:0,failed:0},n=cr().filter(e=>"couldLink"===e.category&&"Chapter"===e.type),r=cr().filter(e=>"wouldCreateChapters"===e.category),a=cr().filter(e=>"couldLink"===e.category&&"Scene"===e.type),o=cr().filter(e=>"wouldCreateScenes"===e.category),c=[];let i="";const s=(e,t)=>{c.push({item:e,counterName:t})},d=async(e,n)=>{try{await(async e=>{if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)throw new Error("Word document access is unavailable.");await window.Word.run(async t=>{const n=await ja(t),r="Chapter"===e.type?e.wordChapter:e.wordScene,a=Number.isInteger(r?.paragraphIndex)?n.bodyParagraphs[r.paragraphIndex]:null;if(!a)throw new Error("Unable to locate the Word heading.");if("Chapter"===e.type){const t=e.pdChapter?.chapterId;if(!t)throw new Error("Chapter ID is not available.");Za(a,"PlotDirector Chapter",`PD-CHAPTER-${t}`,"PD-CHAPTER")}else{const t=e.pdScene?.sceneId;if(!t)throw new Error("Scene ID is not available.");Za(a,"PlotDirector Scene",`PD-SCENE-${t}`,"PD-SCENE")}await t.sync()})})(e),Ha(e,"Success"),t[n]+=1}catch(n){Ha(e,"Failed",Gr(n)),t.failed+=1}};try{for(const e of n)s(e,"linkedChapters");for(const n of r)try{await Fa(e.bookId,n),s(n,"createdChapters")}catch(e){Ha(n,"Failed",Gr(e)),t.failed+=1}for(const e of a)s(e,"linkedScenes");for(const n of o)try{await Va(e.bookId,n),s(n,"createdScenes")}catch(e){Ha(n,"Failed",Gr(e)),t.failed+=1}for(const e of c)await d(e.item,e.counterName);for(const e of un.manualReview||[])Ha(e,"Skipped");$a(un),i=(e=>`Structure Sync Complete. Created: ${e.createdChapters} Chapters, ${e.createdScenes} Scenes. Linked: ${e.linkedChapters} Chapters, ${e.linkedScenes} Scenes. Skipped: ${e.skipped} Manual Review items. Failed: ${e.failed} Items.`)(t),ar(i)}finally{xn=!1,sr(),i&&(Sr(),await Ua(),ar(`${i} Preview refreshed.`))}}),ht?.addEventListener("click",()=>Ma(!0)),mt?.addEventListener("click",()=>Ma(!1)),ut?.addEventListener("cancel",e=>{e.preventDefault(),Ma(!1)}),ne?.addEventListener("click",ho),G?.addEventListener("click",async()=>{if(!Xr())return Qn("Select a PlotDirector book first."),void qr("Not detected");mr(!0);try{if(!await Wa())return;if(pr(!1),!zt)return void await po();await ho()}finally{mr(!1)}}),ge?.addEventListener("click",lo),qe?.addEventListener("click",async()=>{if(_t)if(!Ln&&await(async()=>{if(!_t)return!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return pr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1;try{const e=await window.Word.run(async e=>await ja(e)),t=e.currentChapter?.title||"",n=e.currentScene?.title||"",r=e.currentScene?.anchorId||null,a=e.currentChapter?.anchorId||null,o=Number.isInteger(r)&&r===_t,c=Number.isInteger(a)&&a===en,i=$r(n,"scene").toLocaleLowerCase()===$r(Mn||zt,"scene").toLocaleLowerCase(),s=$r(t,"chapter").toLocaleLowerCase()===$r(On||Yt,"chapter").toLocaleLowerCase();return o||i&&(c||s)?(pr(!1),!0):(pr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1)}catch(e){return console.error("Unable to verify current Word scene before saving.",e),Br({lastError:Gr(e)}),pr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1}})()){qe&&(qe.disabled=!0,qe.textContent="Saving...");try{await(e=`/api/word-companion/scenes/${_t}/links`,t={characterIds:Qa(Ee),assetIds:Qa(Ne),locationIds:[],primaryLocationId:Xa()},Ja(e,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})),(()=>{const e=new Set(Qa(Ee)),t=new Set(Qa(Ne));Bn={characters:Bn.characters.map(t=>({...t,linked:e.has(Number.parseInt(Pr(t,"character"),10))})),assets:Bn.assets.map(e=>({...e,linked:t.has(Number.parseInt(Pr(e,"asset"),10))})),locations:Bn.locations,primaryLocationId:Xa()}})(),Cr("Scene links saved successfully."),Br({lastError:"-"})}catch(e){Cr("Unable to save scene links."),Br({lastError:Gr(e)})}finally{qe&&(qe.disabled=!_t||Ln,qe.textContent="Save Scene Links")}var e,t}else Cr("The Word cursor is now in a different scene. Refresh Current Scene before saving.");else Cr("Link a PlotDirector scene first.")}),se?.addEventListener("click",async()=>{await _a()}),$e?.addEventListener("click",async()=>{const e=Xr();if(!e||!Yt||en)return void Er("Chapter not found in PlotDirector.");const t=Tr(Yt),n=await((e,t)=>(Hr(it,`"${e}"`),Hr(st,`"${t}"`),ct?new Promise(e=>{ln=e,ct.showModal?ct.showModal():ct.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector chapter:\n\n"${e}"\n\nin book:\n\n"${t}"\n\n?`))))(t,Kr(e)||"selected book");if(n){$e&&($e.disabled=!0,$e.textContent="Creating...");try{const n=Number.isInteger(Qt)&&Qt>0?10*Qt:null,r=await Ya(`/api/word-companion/books/${e.bookId}/chapters`,{title:t,sortOrder:n});if(!r?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");Sr(),hr(null,r.chapterId,"Manual chapter link");if(!await eo("Chapter created and linked successfully."))return;await to("Chapter created and linked successfully.")}catch(e){Ir("Unable to create chapter."),Br({lastError:Gr(e)})}finally{$e&&($e.disabled=!kr(),$e.textContent="Create Chapter in PlotDirector")}}}),je?.addEventListener("click",async()=>{const e=Xr();if(e&&Yt&&!en){je&&(je.disabled=!0,je.textContent="Loading...");try{sn=await Wr(e.bookId),dn=null,tt&&(tt.value=""),Hr(ot,""),ro(),et?.showModal?et.showModal():et&&(et.hidden=!1)}catch(e){Ir("Unable to load chapters."),Br({lastError:Gr(e)})}finally{je&&(je.disabled=!kr(),je.textContent="Link to Existing Chapter")}}else Er("Chapter not found in PlotDirector.")}),tt?.addEventListener("input",ro),rt?.addEventListener("click",async()=>{const e=sn.find(e=>e.chapterId===dn);if(e){rt&&(rt.disabled=!0,rt.textContent="Linking...");try{hr(null,e.chapterId,"Manual chapter link");if(!await eo("Chapter linked successfully."))return;ao(),await to("Chapter linked successfully.")}catch(e){Hr(ot,"Unable to link chapter."),Ir("Unable to link chapter."),Br({lastError:Gr(e)})}finally{rt&&(rt.disabled=!dn,rt.textContent="Link Chapter")}}else Hr(ot,"Select a chapter.")}),at?.addEventListener("click",ao),dt?.addEventListener("click",()=>no(!0)),lt?.addEventListener("click",()=>no(!1)),ct?.addEventListener("cancel",e=>{e.preventDefault(),no(!1)}),Oe?.addEventListener("click",async()=>{const e=Xr();if(!e||!zt)return void Lr("Scene not found in PlotDirector.");const t=$r(zt,"scene"),n=$r(Yt,"chapter"),r=await((e,t)=>(Hr(Qe,`"${e}"`),Hr(Xe,`"${t}"`),Ke?new Promise(e=>{cn=e,Ke.showModal?Ke.showModal():Ke.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector scene:\n\n"${e}"\n\nwithin chapter:\n\n"${t}"\n\n?`))))(t,n);if(r){Oe&&(Oe.disabled=!0,Oe.textContent="Creating...");try{const n=await Mr();if(!n)return void Lr("This chapter does not exist in PlotDirector. Create or link the chapter first.");const r=await Ya(`/api/word-companion/books/${e.bookId}/chapters/${n.chapterId}/scenes`,{sceneTitle:t});if(!r?.sceneId||!r?.chapterId)throw new Error("Scene creation did not return a scene ID.");Sr(),await oo(r.sceneId,r.chapterId,"Scene created and linked successfully.")}catch(e){br("Unable to create scene."),Br({lastError:Gr(e)})}finally{Oe&&(Oe.disabled=!vr(),Oe.textContent="Create Scene in PlotDirector")}}}),He?.addEventListener("click",async()=>{const e=Xr();if(e&&zt){He&&(He.disabled=!0,He.textContent="Loading...");try{const t=await Rr(e.bookId),n=Ur(t);if(!n)return void Lr("This chapter does not exist in PlotDirector. Create or link the chapter first.");an=Array.isArray(n.scenes)?n.scenes:[],on=null,Fe&&(Fe.value=""),Hr(ze,""),io(),Ge?.showModal?Ge.showModal():Ge&&(Ge.hidden=!1)}catch(e){br("Unable to load scenes."),Br({lastError:Gr(e)})}finally{He&&(He.disabled=!vr(),He.textContent="Link to Existing Scene")}}else Lr("Scene not found in PlotDirector.")}),Fe?.addEventListener("input",io),Je?.addEventListener("click",async()=>{const e=Xr(),t=an.find(e=>e.sceneId===on);if(e&&t){Je&&(Je.disabled=!0,Je.textContent="Linking...");try{const e=await Mr();if(!e)throw new Error("This chapter does not exist in PlotDirector. Create or link the chapter first.");so(),await oo(t.sceneId,e.chapterId,"Scene linked successfully.")}catch(e){Hr(ze,"Unable to link scene."),br("Unable to link scene."),Br({lastError:Gr(e)})}finally{Je&&(Je.disabled=!on,Je.textContent="Link Scene")}}else Hr(ze,"Select a scene.")}),Ye?.addEventListener("click",so),Ze?.addEventListener("click",()=>co(!0)),_e?.addEventListener("click",()=>co(!1)),Ke?.addEventListener("cancel",e=>{e.preventDefault(),co(!1)}),Et?.addEventListener("click",async()=>{Et&&(Et.disabled=!0,Et.textContent="Running...");try{if(await Fr(),!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return void Br({lastScan:"Failure",lastError:"Word document access is unavailable.",paragraphs:"-",heading1:"-",heading2:"-"});const e=await window.Word.run(async e=>{const t=e.document.body.paragraphs;return t.load("items"),await e.sync(),t.items.length});Br({lastScan:"Success",lastError:"-",paragraphs:String(e)})}catch(e){console.error("Word Companion diagnostics failed.",e);const t=Gr(e);Br({lastScan:"Failure",lastError:t}),Qn(`Unable to scan the Word document: ${t}`)}finally{Et&&(Et.disabled=!1,Et.textContent="Run Diagnostics")}});const So=Ot?(async()=>{Yr(M,"Loading projects..."),Yr(O,"Select a project first"),Yr(h,"Loading projects..."),Yr(m,"Select a project first"),zn(""),Kn("");try{const n=await Ja("/api/word-companion/projects");if(Ht=Array.isArray(n.projects)?n.projects:[],0===Ht.length)return Yr(M,"No projects available."),Yr(h,"No projects available."),zn("No projects available."),Jr(e,null),Jr(t,null),da(),void aa("No projects available.");zr(M,"Choose a project",Ht,"projectId","title"),ra();const r=Vr(e),a=Ht.find(e=>e.projectId===r);a&&M?(M.value=String(a.projectId),h&&(h.value=String(a.projectId)),Jr(e,a.projectId),await go(a.projectId,Vr(t))):(Jr(e,null),Jr(t,null),da(),aa("Select a Project and Book to begin."))}catch{Ht=[],Bt=[],Yr(M,"Unable to connect to PlotDirector."),Yr(O,"Select a project first"),Yr(h,"Unable to connect to PlotDirector."),Yr(m,"Select a project first"),Yn("Unable to connect to PlotDirector."),zn("Unable to connect to PlotDirector."),Jr(e,null),Jr(t,null),da(),aa("Unable to connect to PlotDirector.")}})():Promise.resolve();if(Ot||(Yr(M,"Please sign in to PlotDirector."),Yr(O,"Please sign in to PlotDirector."),Yr(h,"Please sign in to PlotDirector."),Yr(m,"Please sign in to PlotDirector."),da()),!window.Office||"function"!=typeof window.Office.onReady)return Fn("Word Companion ready"),Qn("Word document access is unavailable."),ur("Manual"),void Br({host:"Unavailable",platform:"Unavailable",ready:"No",wordApi:"No"});Fr().then(async()=>{Fn("Word Companion ready"),await So,await(async()=>{if(!Ot||!Ft)return void na(!1);const n=ia();if(n)try{const r=await Ja(`/api/word-companion/runtime/book/${n.bookId}?documentGuid=${encodeURIComponent(n.documentGuid)}`),a=r?.manuscriptDocument;if(r?.bookId===n.bookId&&r?.projectId===n.projectId&&a&&String(a.documentGuid).toLowerCase()===n.documentGuid.toLowerCase())return pn=n,fr(r),Jr(e,r.projectId),Jr(t,r.bookId),M&&(M.value=String(r.projectId)),await go(r.projectId,r.bookId),na(!1),Yn("Connected"),Kn("Bound manuscript detected."),void await Ka()}catch{}pn=null,gr(),ra(),Zr()?await go(Zr().projectId,null):Yr(m,"Select a project first"),aa("Select a Project and Book to begin."),na(!0)})(),Ft?(()=>{if(Ot){if(!window.Office?.context?.document||"function"!=typeof window.Office.context.document.addHandlerAsync||!window.Office?.EventType?.DocumentSelectionChanged)return ur("Manual"),void Qn("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");try{window.Office.context.document.addHandlerAsync(window.Office.EventType.DocumentSelectionChanged,wo,e=>{e?.status===window.Office.AsyncResultStatus.Succeeded?(Tn=!0,ur("Live")):(ur("Manual"),Qn("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene."))}),window.addEventListener("beforeunload",fo)}catch(e){console.warn("Unable to register Word selection tracking handler.",e),ur("Manual"),Qn("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.")}}})():(Qn("Word document access is unavailable."),ur("Manual"))}).catch(e=>{console.error("Office readiness check failed.",e),Yn("Unable to connect to PlotDirector."),Fn("Word Companion unavailable"),Qn("Word document access is unavailable."),Br({ready:"No",wordApi:"No",lastScan:"Failure"})})})(); |