1 line
84 KiB
JavaScript
1 line
84 KiB
JavaScript
(()=>{const e="plotdirector.word.projectId",t="plotdirector.word.bookId",n="plotdirector.word.activeTab",r={documentGuid:"plotdirector.word.documentGuid",bookId:"plotdirector.word.boundBookId",projectId:"plotdirector.word.boundProjectId",bindingVersion:"plotdirector.word.bindingVersion"},o=new Set(["scene","links","structure","diagnostics"]),a=document.querySelector(".word-companion-shell"),c=document.querySelector(".word-companion-tabs"),i=[...document.querySelectorAll("[data-tab-button]")],s=[...document.querySelectorAll("[data-tab-panel]")],d=document.querySelector("[data-first-run-wizard]"),l=document.querySelector("[data-first-run-project-select]"),u=document.querySelector("[data-first-run-book-select]"),p=document.querySelector("[data-first-run-new-book-title]"),h=document.querySelector("[data-first-run-create-book]"),m=document.querySelector("[data-first-run-scan]"),y=document.querySelector("[data-first-run-cancel]"),g=document.querySelector("[data-first-run-status]"),f=document.querySelector("[data-first-run-summary]"),w=document.querySelector("[data-first-run-character-section]"),I=document.querySelector("[data-first-run-character-status]"),S=document.querySelector("[data-first-run-character-candidates]"),b=document.querySelector("[data-first-run-character-actions]"),C=document.querySelector("[data-first-run-create-characters]"),k=document.querySelector("[data-first-run-skip-characters]"),v=document.querySelector("[data-first-run-continue]"),x=document.querySelector("[data-first-run-import-actions]"),N=document.querySelector("[data-first-run-import]"),E=document.querySelector("[data-first-run-import-cancel]"),L=document.querySelector("[data-first-run-replace-dialog]"),P=document.querySelector("[data-first-run-replace-confirm]"),D=document.querySelector("[data-first-run-replace-cancel]"),q=document.querySelector("[data-unlink-word-document-dialog]"),A=document.querySelector("[data-unlink-word-document-confirm]"),$=document.querySelector("[data-unlink-word-document-cancel]"),T=document.querySelector("[data-office-status]"),j=document.querySelector("[data-connection-status]"),W=document.querySelector("[data-summary-connection]"),R=document.querySelector("[data-summary-project]"),U=document.querySelector("[data-summary-book]"),M=document.querySelector("[data-project-select]"),O=document.querySelector("[data-book-select]"),B=document.querySelector("[data-project-message]"),G=document.querySelector("[data-book-message]"),H=document.querySelector("[data-refresh-current-scene]"),F=document.querySelector("[data-refresh-document]"),V=document.querySelector("[data-current-chapter]"),Y=document.querySelector("[data-current-scene]"),J=document.querySelector("[data-current-word-count]"),_=document.querySelector("[data-scene-tracking-status]"),z=document.querySelector("[data-document-message]"),K=document.querySelector("[data-sync-note]"),Q=document.querySelector("[data-document-outline]"),X=document.querySelector("[data-analyse-manuscript-structure]"),Z=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]"),oe=document.querySelector("[data-anchor-status]"),ae=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-unlink-word-document]"),le=document.querySelector("[data-plotdirector-scene-details]"),ue=document.querySelector("[data-plotdirector-scene-title]"),pe=document.querySelector("[data-plotdirector-revision-status]"),he=document.querySelector("[data-plotdirector-estimated-words]"),me=document.querySelector("[data-plotdirector-actual-words]"),ye=document.querySelector("[data-plotdirector-blocked-status]"),ge=document.querySelector("[data-plotdirector-blocked-reason-row]"),fe=document.querySelector("[data-plotdirector-blocked-reason]"),we=document.querySelector("[data-runtime-last-sync]"),Ie=document.querySelector("[data-sync-scene-progress]"),Se=document.querySelector("[data-sync-word-count]"),be=document.querySelector("[data-sync-plotdirector-count]"),Ce=document.querySelector("[data-sync-last-synced]"),ke=document.querySelector("[data-sync-status]"),ve=document.querySelector("[data-writing-brief-block]"),xe=document.querySelector("[data-writing-brief]"),Ne=document.querySelector("[data-plotdirector-link-groups]"),Ee=document.querySelector("[data-character-chips]"),Le=document.querySelector("[data-asset-chips]"),Pe=(document.querySelector("[data-location-chips]"),document.querySelector("[data-primary-location-select]")),De=document.querySelector("[data-save-scene-links]"),qe=document.querySelector("[data-scene-links-status]"),Ae=document.querySelector("[data-links-editing-scene]"),$e=document.querySelector("[data-chapter-create-link]"),Te=document.querySelector("[data-chapter-create-link-chapter]"),je=document.querySelector("[data-create-plotdirector-chapter]"),We=document.querySelector("[data-link-existing-chapter]"),Re=document.querySelector("[data-chapter-create-link-status]"),Ue=document.querySelector("[data-scene-create-link]"),Me=document.querySelector("[data-create-link-chapter]"),Oe=document.querySelector("[data-create-link-scene]"),Be=document.querySelector("[data-create-plotdirector-scene]"),Ge=document.querySelector("[data-link-existing-scene]"),He=document.querySelector("[data-create-link-status]"),Fe=document.querySelector("[data-link-existing-dialog]"),Ve=document.querySelector("[data-link-scene-search]"),Ye=document.querySelector("[data-link-scene-options]"),Je=document.querySelector("[data-link-selected-scene]"),_e=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]"),et=document.querySelector("[data-create-dialog-cancel]"),tt=document.querySelector("[data-link-existing-chapter-dialog]"),nt=document.querySelector("[data-link-chapter-search]"),rt=document.querySelector("[data-link-chapter-options]"),ot=document.querySelector("[data-link-selected-chapter]"),at=document.querySelector("[data-link-chapter-dialog-cancel]"),ct=document.querySelector("[data-link-chapter-dialog-status]"),it=document.querySelector("[data-create-chapter-dialog]"),st=document.querySelector("[data-create-chapter-dialog-chapter]"),dt=document.querySelector("[data-create-chapter-dialog-book]"),lt=document.querySelector("[data-create-chapter-dialog-confirm]"),ut=document.querySelector("[data-create-chapter-dialog-cancel]"),pt=document.querySelector("[data-apply-structure-sync-dialog]"),ht=document.querySelector("[data-apply-structure-sync-summary]"),mt=document.querySelector("[data-apply-structure-sync-confirm]"),yt=document.querySelector("[data-apply-structure-sync-cancel]"),gt=document.querySelector("[data-resolve-project-id]"),ft=document.querySelector("[data-resolve-project-title]"),wt=document.querySelector("[data-resolve-book-id]"),It=document.querySelector("[data-resolve-book-title]"),St=document.querySelector("[data-resolve-detected-chapter]"),bt=document.querySelector("[data-resolve-detected-scene]"),Ct=document.querySelector("[data-resolve-request-chapter]"),kt=document.querySelector("[data-resolve-request-scene]"),vt=document.querySelector("[data-resolve-result]"),xt=document.querySelector("[data-resolve-chapter-id]"),Nt=document.querySelector("[data-resolve-scene-id]"),Et=document.querySelector("[data-run-diagnostics]"),Lt=document.querySelector("[data-diagnostic-host]"),Pt=document.querySelector("[data-diagnostic-platform]"),Dt=document.querySelector("[data-diagnostic-ready]"),qt=document.querySelector("[data-diagnostic-word-api]"),At=document.querySelector("[data-diagnostic-last-scan]"),$t=document.querySelector("[data-diagnostic-last-error]"),Tt=document.querySelector("[data-diagnostic-anchor-type]"),jt=document.querySelector("[data-diagnostic-stored-scene-id]"),Wt=document.querySelector("[data-diagnostic-stored-chapter-id]"),Rt=document.querySelector("[data-diagnostic-resolution-method]"),Ut=document.querySelector("[data-diagnostic-paragraphs]"),Mt=document.querySelector("[data-diagnostic-heading1]"),Ot=document.querySelector("[data-diagnostic-heading2]"),Bt="true"===a?.dataset.authenticated;let Gt=[],Ht=[],Ft=!1,Vt=!1,Yt="Unknown",Jt="Unknown",_t="",zt="",Kt=null,Qt=null,Xt=null,Zt=null,en=null,tn=null,nn="",rn="Title Match",on=!1,an=[],cn=null,sn=null,dn=[],ln=null,un=null,pn=null,hn=null,mn=null,yn=null,gn=null,fn=null,wn=null,In=null,Sn=[],bn=!1,Cn=!1,kn=0,vn=!1,xn=!1,Nn=!1,En=null,Ln="Manual",Pn=!1,Dn=null,qn=!1,An=0,$n=!1,Tn=0,jn=null;const Wn=1200;let Rn=!1,Un=!1,Mn=null,On=!1,Bn=!1,Gn=null,Hn=null,Fn=null,Vn=!1,Yn=!1,Jn=null,_n="",zn=[],Kn=null,Qn="",Xn=null,Zn="",er=[],tr=null,nr="",rr=null,or="",ar=[],cr=null,ir="",sr="",dr="",lr="",ur=0,pr={characters:[],assets:[],locations:[],primaryLocationId:null};const hr=e=>{const t=Date.now();t-ur<1e3||(ur=t,console.debug(`[Word Companion Runtime] ${e}`))},mr=e=>{console.debug(`[Word Companion Timing] ${e}`)},yr=e=>{T&&(T.textContent=e)},gr=(e,t=!0)=>{const r=o.has(e)&&i.some(t=>t.dataset.tabButton===e)?e:"scene";for(const e of i){const t=e.dataset.tabButton===r;e.classList.toggle("is-active",t),e.setAttribute("aria-selected",t?"true":"false")}for(const e of s){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)},fr=()=>{const e=(e=>{try{return window.localStorage.getItem(e)||""}catch{return""}})(n);gr(o.has(e)?e:"scene",!1)},wr=e=>{j&&(j.textContent=e),W&&(W.textContent=e)},Ir=e=>{B&&(B.textContent=e)},Sr=e=>{G&&(G.textContent=e)},br=e=>{z&&(z.textContent=e)},Cr=e=>{re&&(re.textContent=e)},kr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("anchorType")&&mo(Tt,Br(e.anchorType)),t("storedSceneId")&&mo(jt,Br(e.storedSceneId)),t("storedChapterId")&&mo(Wt,Br(e.storedChapterId)),t("resolutionMethod")&&mo(Rt,Br(e.resolutionMethod))},vr=()=>{const e=vo(),t=Number.isInteger(en)&&en>0&&Zt===en,n=!Number.isInteger(tn)||tn<=0||Xt===tn,r=t&&n;mo(oe,r?"Attached to PlotDirector":"Not attached"),mo(ae,e?.bookId?String(e.bookId):"-"),mo(ce,Number.isInteger(tn)&&tn>0?String(tn):"-"),mo(ie,Number.isInteger(en)&&en>0?String(en):"-"),se&&(se.disabled=!en||r&&!on,se.textContent=Zt&&!r?"Reattach PlotDirector IDs":"Attach PlotDirector IDs"),kr({anchorType:rn||"Title Match",storedSceneId:Zt,storedChapterId:Xt,resolutionMethod:nn})},xr=(e,t,n,r=null,o=null,a=null)=>{const c=e||"",i=t||"",s=Number.isInteger(n)?n:null,d=Number.isInteger(a)&&a>0?a:null,l=Number.isInteger(r)&&r>0?r:null,u=Number.isInteger(o)&&o>0?o:null,p=_t===c&&zt===i&&Kt===s&&Qt===d&&Xt===l&&Zt===u;_t=e||"",zt=t||"",Kt=Number.isInteger(n)?n:null,Qt=Number.isInteger(a)&&a>0?a:null,Xt=Number.isInteger(r)&&r>0?r:null,Zt=Number.isInteger(o)&&o>0?o:null,p||(V&&(V.textContent=e||"Not detected"),Y&&(Y.textContent=t||"Not detected"),J&&(J.textContent=Number.isInteger(n)?String(n):"-"),mo(Se,Number.isInteger(n)?String(n):"-"),vr())},Nr=()=>{Mn&&(window.clearTimeout(Mn),Mn=null)},Er=(e,t)=>{e&&(e.hidden=t)},Lr=()=>{Er(de,!hn)},Pr=e=>{mo(ke,e)},Dr=e=>{mo(ee,e)},qr=(e="Select a project and book to analyse manuscript structure.")=>{if(pn=null,te){te.innerHTML="";const e=document.createElement("p");e.textContent="No preview generated.",te.append(e)}Dr(e),$r()},Ar=(e=pn)=>((e=pn)=>Zo.flatMap(t=>Array.isArray(e?.[t.key])?e[t.key]:[]))(e).filter(e=>"couldLink"===e.category||"wouldCreateChapters"===e.category||"wouldCreateScenes"===e.category),$r=()=>{Z&&(Z.disabled=Nn||0===Ar().length)},Tr=()=>{X&&(X.disabled=Nn||!ko()||!vo()),$r()},jr=()=>{Ae&&(Ae.textContent=en?`Editing links for: ${dr||zt||"Current scene"}`:"Link a PlotDirector scene first.")},Wr=()=>{const e=Pn||!en,t=e||!tn||On;Ie&&(Ie.disabled=t),De&&(De.disabled=e),Pe&&(Pe.disabled=e);for(const t of[Ee,Le])for(const n of t?[...t.querySelectorAll("input[type='checkbox']")]:[])n.disabled=e},Rr=e=>{"Live"!==e&&"Manual"!==e||(Ln=e),mo(_,e||Ln||"Manual")},Ur=(e,t="")=>{Pn=!!e,Pn&&(Nr(),Ja()),mo(_,Pn?"Stale":Ln),Wr(),t&&(br(t),Yr(t))},Mr=(e,t=null,n="")=>{en=Number.isInteger(e)&&e>0?e:null,tn=Number.isInteger(t)&&t>0?t:null,nn=n||"",en!==Gn&&(Hn=null),en||(Nr(),Ja()),Wr(),Pr(Pn?"Refresh Current Scene before syncing.":en?"Ready to sync.":"No resolved PlotDirector scene."),Yr(Pn?"Refresh Current Scene before saving.":en?"Ready to save.":"Link a PlotDirector scene first."),jr(),vr()},Or=e=>{H&&(H.disabled=e,H.textContent=e?"Refreshing...":"Refresh Current Scene")},Br=e=>null==e||""===e?"-":String(e),Gr=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"})}`},Hr=e=>{mn=e||null;const t=mn?.lastSyncUtc||mn?.manuscriptDocument?.lastSyncUtc;mo(we,Gr(t)),mo(Ce,Gr(t))},Fr=()=>{yn=null,gn=null,fn=null,Tn+=1,jn=null,_a(),za(),Ka(),Hr(null)},Vr=()=>{gn=null,fn=null},Yr=e=>{mo(qe,e)},Jr=e=>{mo(He,e)},_r=e=>{mo(Re,e)},zr=()=>!!vo()&&!!_t&&!tn,Kr=()=>!!vo()&&!!zt&&Number.isInteger(tn)&&tn>0,Qr=()=>{Er($e,!0),_r(""),je&&(je.disabled=!0,je.textContent="Create Chapter in PlotDirector"),We&&(We.disabled=!0,We.textContent="Link to Existing Chapter")},Xr=(e="")=>{mo(Te,Br(_t)),Er($e,!1),_r(e);const t=zr();je&&(je.disabled=!t,je.textContent="Create Chapter in PlotDirector"),We&&(We.disabled=!t,We.textContent="Link to Existing Chapter")},Zr=()=>{Er(Ue,!0),Jr(""),Be&&(Be.disabled=!0,Be.textContent="Create Scene in PlotDirector"),Ge&&(Ge.disabled=!0,Ge.textContent="Link to Existing Scene")},eo=(e="")=>{mo(Me,Br(_t)),mo(Oe,Br(zt)),Er(Ue,!1),Jr(e);const t=Kr();Be&&(Be.disabled=!t,Be.textContent="Create Scene in PlotDirector"),Ge&&(Ge.disabled=!t,Ge.textContent="Link to Existing Scene")},to=e=>{Cr(e),Er(le,!0),Er(ve,!0),Er(Ne,!1),Qr(),Zr(),nn="",dr="",lr="",rn=Zt?"SceneID Anchor":Xt?"ChapterID Anchor":"Title Match",on=!1,pr={characters:[],assets:[],locations:[],primaryLocationId:null},ro(Ee,[],"character"),ro(Le,[],"asset"),oo([],null,!1),Mr(null),mo(be,"-"),mo(ue,"-"),mo(pe,"-"),mo(he,"-"),mo(me,"-"),mo(ye,"-"),mo(fe,"-"),Er(ge,!0),vr(),jr()},no=(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,ro=(e,t,n,r=!1)=>{if(!e)return;e.innerHTML="";const o=Array.isArray(t)?t:[];if(0===o.length){const t=document.createElement("p");return t.className="word-companion-empty-list",t.textContent="None",void e.append(t)}for(const t of o){const o=Number.parseInt(no(t,n),10);if(!Number.isInteger(o)||o<=0)continue;const a=document.createElement("label");a.className="word-companion-check-item";const c=document.createElement("input");c.type="checkbox",c.value=String(o),c.checked=!!t.linked,c.disabled=!r;const i=document.createElement("span");i.textContent=t.name||"Unnamed",a.append(c,i),e.append(a)}},oo=(e,t,n=!1)=>{if(!Pe)return;Pe.innerHTML="";const r=document.createElement("option");r.value="",r.textContent="None",Pe.append(r);const o=Number.parseInt(t||"",10);for(const t of Array.isArray(e)?e:[]){const e=Number.parseInt(no(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===o,Pe.append(n)}Pe.disabled=!n},ao=e=>String(e||"").trim().replace(/\s+/g," "),co=(e,t)=>{const n=ao(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 ao(n.replace(r,""))||n},io=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("projectId")&&mo(gt,Br(e.projectId)),t("projectTitle")&&mo(ft,Br(e.projectTitle)),t("bookId")&&mo(wt,Br(e.bookId)),t("bookTitle")&&mo(It,Br(e.bookTitle)),t("detectedChapter")&&mo(St,Br(e.detectedChapter)),t("detectedScene")&&mo(bt,Br(e.detectedScene)),t("requestChapter")&&mo(Ct,Br(e.requestChapter)),t("requestScene")&&mo(kt,Br(e.requestScene)),t("result")&&mo(vt,Br(e.result)),t("chapterId")&&mo(xt,Br(e.chapterId)),t("sceneId")&&mo(Nt,Br(e.sceneId))},so=async e=>{if(fn===e&&Array.isArray(gn?.chapters))return gn.chapters;const t=await xa(`/api/word-companion/books/${e}/structure`);return fn=e,gn=t||null,Array.isArray(t?.chapters)?t.chapters:[]},lo=async e=>{const t=await xa(`/api/word-companion/books/${e}/chapters`);return Array.isArray(t?.chapters)?t.chapters:[]},uo=e=>{if(Number.isInteger(tn)&&tn>0){const t=e.find(e=>e.chapterId===tn);if(t)return t}const t=co(_t,"chapter").toLocaleLowerCase();return t&&e.find(e=>co(e.title,"chapter").toLocaleLowerCase()===t)||null},po=async()=>{const e=vo();return e?uo(await so(e.bookId)):null},ho=async(e,t,n,r,o)=>{const a=await xa(`/api/word-companion/scenes/${t}/companion`);try{a.revisionStatus=await(async(e,t)=>{const n=await xa(`/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{a.revisionStatus=""}var c;rn=o||"Title Match",on=!1,Ur(!1),Cr("Linked to PlotDirector"),br(""),Qr(),Zr(),Mr(t,n,r),c=a,dr=c?.sceneTitle||zt||"",lr=c?.chapterTitle||_t||"",mo(ue,Br(c?.sceneTitle)),mo(pe,Br(c?.revisionStatus||c?.revisionStatusName||"Not provided")),mo(he,Br(c?.estimatedWords)),mo(me,Br(c?.actualWords)),mo(be,Br(c?.actualWords)),mo(ye,c?.blocked?"Blocked":"Not blocked"),c?.blockedReason?(mo(fe,c.blockedReason),Er(ge,!1)):(mo(fe,"-"),Er(ge,!0)),xe&&(xe.textContent=c?.writingBrief||"No writing brief has been added for this scene."),pr={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},ro(Ee,pr.characters,"character",!!en&&!Pn),ro(Le,pr.assets,"asset",!!en&&!Pn),oo(pr.locations,pr.primaryLocationId,!!en&&!Pn),jr(),Yr(Pn?"Refresh Current Scene before saving.":en?"Ready to save.":"No resolved PlotDirector scene."),Er(le,!1),Er(ve,!1),Er(Ne,!1),La(t,n),Ya(),rc()},mo=(e,t)=>{if(e){const n=null==t?"":String(t);e.textContent!==n&&(e.textContent=n)}},yo=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("host")&&mo(Lt,e.host),t("platform")&&mo(Pt,e.platform),t("ready")&&mo(Dt,e.ready),t("wordApi")&&mo(qt,e.wordApi),t("lastScan")&&mo(At,e.lastScan),t("lastError")&&mo($t,e.lastError),t("paragraphs")&&mo(Ut,e.paragraphs),t("heading1")&&mo(Mt,e.heading1),t("heading2")&&mo(Ot,e.heading2)},go=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)},fo=async()=>{if(!window.Office||"function"!=typeof window.Office.onReady)return Ft=!1,Vt=!1,Yt="Unavailable",Jt="Unavailable",yo({host:Yt,platform:Jt,ready:"No",wordApi:"No"}),null;const e=await window.Office.onReady();return Ft=!0,Yt=e?.host||"Unknown",Jt=e?.platform||"Unknown",Vt=!!window.Word&&!!window.Office.HostType&&e?.host===window.Office.HostType.Word,yo({host:Yt,platform:Jt,ready:"Yes",wordApi:Vt?"Yes":"No"}),e},wo=e=>{try{const t=window.localStorage.getItem(e),n=Number.parseInt(t||"",10);return Number.isInteger(n)&&n>0?n:null}catch{return null}},Io=(e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}},So=(e,t)=>{if(!e)return;e.innerHTML="";const n=document.createElement("option");n.value="",n.textContent=t,e.append(n),e.disabled=!0},bo=(e,t,n,r,o)=>{if(!e)return;e.innerHTML="";const a=document.createElement("option");a.value="",a.textContent=t,e.append(a);for(const t of n){const n=document.createElement("option");n.value=String(t[r]),n.textContent=t[o],e.append(n)}e.disabled=0===n.length},Co=e=>{const t=String(e?.title||"").trim(),n=String(e?.subtitle||"").trim();return n?`${t}: ${n}`:t},ko=()=>{const e=Number.parseInt(M?.value||"",10);return Gt.find(t=>t.projectId===e)||null},vo=()=>{const e=Number.parseInt(O?.value||"",10);return Ht.find(t=>t.bookId===e)||null},xo=()=>{const e=Number.parseInt(l?.value||"",10);return Gt.find(t=>t.projectId===e)||null},No=()=>{const e=Number.parseInt(u?.value||"",10);return Ht.find(t=>t.bookId===e)||null},Eo=e=>mo(g,e),Lo=()=>{const e=xo(),t=No(),n=Cn&&Date.now()-kn>=750;m&&(m.disabled=!e||!t||vn),h&&(h.disabled=!e||!String(p?.value||"").trim()||vn),N&&(N.disabled=!wn?.canImport||!In||vn),C&&(C.disabled=!n||xn||0===Ao().length)},Po=e=>{Er(d,!e),Er(c,e),Lr();for(const t of s)Er(t,!!e||"scene"!==t.dataset.tabPanel&&!t.classList.contains("is-active"));e||fr()},Do=()=>{if(!l)return;if(0===Gt.length)return void So(l,"No projects available.");bo(l,"Choose a project",Gt,"projectId","title");const e=Number.parseInt(M?.value||"",10);Number.isInteger(e)&&e>0&&(l.value=String(e))},qo=(e="Select a Project and Book to begin.")=>{wn=null,In=null,Sn=[],bn=!1,Cn=!1,kn=0,Er(f,!0),Er(x,!0),Er(w,!0),Er(b,!0),f&&(f.innerHTML=""),S&&(S.innerHTML=""),mo(I,""),Eo(e),Lo()},Ao=()=>S?[...S.querySelectorAll("input[type='checkbox']:checked")].map(e=>String(e.value||"").trim()).filter(Boolean):[],$o=e=>{if(Sn=Array.isArray(e)?e:[],w&&S){if(S.innerHTML="",Er(w,!1),Er(b,!bn||0===Sn.length),Er(C,!1),Er(k,!1),Er(v,!0),0===Sn.length)return mo(I,"No likely major characters found."),void Lo();mo(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",Lo);const r=document.createElement("strong");r.textContent=e.text||"";const o=document.createElement("em"),a=String(e.reason||"").trim();o.textContent=a?`${Number(e.mentionCount||0).toLocaleString()} mentions · ${a}`:`${Number(e.mentionCount||0).toLocaleString()} mentions`;const c=document.createElement("span");c.className="word-companion-character-candidate-text",c.append(r,o),t.append(n,c),S.append(t)}Lo()}},To=()=>{const e=window.Office?.context?.document?.settings;if(!e)return null;const t=String(e.get(r.documentGuid)||"").trim(),n=Number.parseInt(e.get(r.bookId)||"",10),o=Number.parseInt(e.get(r.projectId)||"",10),a=Number.parseInt(e.get(r.bindingVersion)||"",10);return!t||!Number.isInteger(n)||n<=0||!Number.isInteger(o)||o<=0?null:{documentGuid:t,bookId:n,projectId:o,bindingVersion:Number.isInteger(a)&&a>0?a:1}},jo=()=>new Promise((e,t)=>{const n=window.Office?.context?.document?.settings;if(n){for(const e of Object.values(r))"function"==typeof n.remove?n.remove(e):n.set(e,"");n.saveAsync(n=>{n.status===window.Office.AsyncResultStatus.Succeeded?e():t(n.error||new Error("Unable to remove Word document metadata."))})}else t(new Error("Word document settings are unavailable."))}),Wo=()=>hn?.documentGuid?hn.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)),Ro=()=>hn?.documentGuid||To()?.documentGuid||"",Uo=()=>{const e=ko(),t=vo();R&&(R.textContent=e?.title||"(Not connected)"),U&&(U.textContent=t?Co(t):"(Not connected)"),K&&(K.textContent=t?"":"Select a PlotDirector book before refreshing."),Tr()},Mo=e=>String(e?.styleBuiltIn||e?.style||"").replace(/\s+/g,"").toLowerCase(),Oo=(e,t)=>{const n=Mo(e);return n===`heading${t}`||n.endsWith(`.heading${t}`)||n.includes(`heading${t}`)},Bo=e=>String(e||"").trim().split(/\s+/).filter(Boolean).length,Go=(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},Ho=e=>{try{return Array.isArray(e?.contentControls?.items)?e.contentControls.items:[]}catch(e){return console.warn("Word paragraph content controls were not available.",e),[]}},Fo=(e,t)=>{const n=Ho(e);for(const e of n){const n=Go(e.tag,t);if(n)return n}return null},Vo=(e,t)=>{const n=[];let r=0,o=0,a=null,c=null;e.forEach((e,t)=>{const i=String(e.text||"").trim();if(i){if(Oo(e,1))return r+=1,a={index:n.length+1,paragraphIndex:t,title:i,anchorId:Fo(e,"PD-CHAPTER"),scenes:[]},n.push(a),void(c=null);if(Oo(e,2)){if(o+=1,!a)return;return c={index:a.scenes.length+1,paragraphIndex:t,title:i,anchorId:Fo(e,"PD-SCENE"),wordCount:0},void a.scenes.push(c)}c&&(c.wordCount+=Bo(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()&&Mo(t)===Mo(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:o}},Yo=new Set(["***","###"]),Jo=(e,t)=>{const n=String(e?.text||"").trim();return{index:t,text:n,styleBuiltIn:e?.styleBuiltIn||"",style:e?.style||"",wordCount:Bo(n),chapterAnchorId:null,sceneAnchorId:null}},_o=(e,t)=>{e&&(e.endParagraphIndex=t)},zo=(e,t)=>{e&&(e.endParagraphIndex=t,_o(e.scenes.at(-1),t))},Ko=(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()&&Mo(e)===Mo(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]},Qo=e=>{if(!yn)return!1;const t=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.chapters.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(yn,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!==yn.currentChapter?.startParagraphIndex||n?.startParagraphIndex!==yn.currentScene?.startParagraphIndex||t?.anchorId!==yn.currentChapter?.anchorId||n?.anchorId!==yn.currentScene?.anchorId;return yn.currentParagraphIndex=e,yn.currentChapter=t,yn.currentScene=n,!!r&&(xr(t?.title,n?.title,n?.wordCount,t?.anchorId,n?.anchorId,t?.index),r)},Xo=e=>{if(!Q)return;if(Q.innerHTML="",0===e.chapters.length){const e=document.createElement("p");return e.textContent="No chapters detected. Use Heading 1 for chapter titles.",void Q.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.",Q.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)}Q.append(e)}},Zo=[{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"}],ea={alreadyLinked:"Already Linked",couldLink:"Could Link",wouldCreateChapter:"Would Create Chapter",wouldCreateScene:"Would Create Scene",manualReview:"Manual Review Required"},ta={alreadyLinked:"✓",couldLink:"~",wouldCreateChapter:"+",wouldCreateScene:"+",manualReview:"?"},na=(e,t)=>co(e,t).toLocaleLowerCase(),ra=({category:e,action:t,type:n,wordTitle:r,match:o="",anchorStatus:a="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:o,anchorStatus:a,matches:c,pdChapter:i,pdScene:s,wordChapter:d,wordScene:l,parentItem:u,result:"Pending",error:""}),oa=(e,t)=>{Array.isArray(e[t.category])&&e[t.category].push(t)},aa=e=>Array.isArray(e?.scenes)?e.scenes:[],ca=(e,t,n)=>{const r=e.anchorId?`PD-CHAPTER-${e.anchorId}`:"None";if(e.anchorId){const o=t.find(t=>t.chapterId===e.anchorId);if(o){const t=ra({category:"alreadyLinked",action:"alreadyLinked",type:"Chapter",wordTitle:e.title,match:`Chapter ${o.chapterId}: ${o.title}`,anchorStatus:r,pdChapter:o,wordChapter:e});return oa(n,t),t}const a=ra({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:`${r} not found`,matches:[],pdChapter:null,wordChapter:e});return oa(n,a),a}const o=t.filter(t=>na(t.title,"chapter")===na(e.title,"chapter"));if(1===o.length){const t=ra({category:"couldLink",action:"couldLink",type:"Chapter",wordTitle:e.title,match:`Chapter ${o[0].chapterId}: ${o[0].title}`,anchorStatus:r,pdChapter:o[0],wordChapter:e});return oa(n,t),t}if(o.length>1){const t=ra({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:r,matches:o.map(e=>`Chapter ${e.chapterId}: ${e.title}`),pdChapter:null,wordChapter:e});return oa(n,t),t}const a=ra({category:"wouldCreateChapters",action:"wouldCreateChapter",type:"Chapter",wordTitle:e.title,anchorStatus:r,pdChapter:null,wordChapter:e});return oa(n,a),a},ia=(e,t,n,r)=>{const o=e.anchorId?`PD-SCENE-${e.anchorId}`:"None";if(e.anchorId){const a=((e,t)=>{for(const n of e){const e=aa(n).find(e=>e.sceneId===t);if(e)return{chapter:n,scene:e}}return null})(n,e.anchorId);return a?void oa(r,ra({category:"alreadyLinked",action:"alreadyLinked",type:"Scene",wordTitle:e.title,match:`Scene ${a.scene.sceneId}: ${a.scene.title}`,anchorStatus:o,pdChapter:a.chapter,pdScene:a.scene,wordChapter:t?.wordChapter,wordScene:e,parentItem:t})):void oa(r,ra({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:`${o} not found`,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}))}if(!t?.pdChapter&&"manualReview"===t?.category)return void oa(r,ra({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:o,matches:["Parent chapter requires manual review."],wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));if(!t?.pdChapter)return void oa(r,ra({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:o,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));const a=aa(t.pdChapter).filter(t=>na(t.title,"scene")===na(e.title,"scene"));1!==a.length?a.length>1?oa(r,ra({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:o,matches:a.map(e=>`Scene ${e.sceneId}: ${e.title}`),wordChapter:t.wordChapter,wordScene:e,parentItem:t})):oa(r,ra({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:o,pdChapter:t.pdChapter,wordChapter:t.wordChapter,wordScene:e,parentItem:t})):oa(r,ra({category:"couldLink",action:"couldLink",type:"Scene",wordTitle:e.title,match:`Scene ${a[0].sceneId}: ${a[0].title}`,anchorStatus:o,pdChapter:t.pdChapter,pdScene:a[0],wordChapter:t.wordChapter,wordScene:e,parentItem:t}))},sa=e=>{const t=document.createElement("article");t.className="word-companion-preview-item";const n=document.createElement("strong");n.textContent=`${ta[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 o=document.createElement("ul");for(const t of e.matches){const e=document.createElement("li");e.textContent=t,o.append(e)}n.append(o),t.append(n)}const o=document.createElement("span");if(o.textContent=`Action: ${ea[e.action]||e.action}`,t.append(o),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},da=e=>{if(te){te.innerHTML="";for(const t of Zo){const n=document.createElement("section");n.className="word-companion-preview-group";const r=document.createElement("strong");r.textContent=t.title,n.append(r);const o=Array.isArray(e?.[t.key])?e[t.key]:[];if(0===o.length){const e=document.createElement("p");e.className="word-companion-empty-list",e.textContent="None",n.append(e)}else for(const e of o)n.append(sa(e));te.append(n)}$r()}},la=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)(Oo(e,1)||Oo(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=Vo(t.items,n.items);return r.bodyParagraphs=t.items,r},ua=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 o=((e,t)=>{const n=e.map(Jo),r=[];let o=0,a=0,c=null,i=null,s=0;const d=(e,t=null,n=null)=>c?(_o(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&&(Oo(e,1)?(zo(c,e.index-1),o+=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&&Yo.has(e.text)?(a+=1,d(e)):(c.wordCount+=e.wordCount,i&&(i.wordCount+=e.wordCount),s+=e.wordCount)));return zo(c,n.length-1),{paragraphs:n,chapters:r,usesExplicitScenes:!!t,paragraphCount:n.length,heading1Count:o,heading2Count:a,documentWordCount:s,currentParagraphIndex:null,currentChapter:null,currentScene:null}})(n.items,t),a=Ko(o,r.items);return yn=o,Qo(a),hr("Cache rebuilt."),o},pa=()=>window.performance&&"function"==typeof window.performance.now?window.performance.now():Date.now(),ha=e=>!!e&&!e.stale&&e.generation===Tn&&e.documentGuid===Ro()&&e.sceneId===en,ma=async(e={})=>{const t=!!e.includeSelection,n=!1!==e.updateDisplay,r=Tn,o=pa(),a=ko(),c=vo(),i=yn?.currentScene;if(!i||!Number.isInteger(i.startParagraphIndex)||!Number.isInteger(i.endParagraphIndex))return null;if(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return null;const s=pa(),d=await window.Word.run(async e=>{const n=e.document.body.paragraphs;n.load("text");let r=null;return t&&(r=e.document.getSelection().paragraphs,r.load("text,styleBuiltIn,style")),await e.sync(),{bodyTexts:n.items.map(e=>String(e.text||"")),selectionParagraphs:t&&r?r.items.map(e=>({text:String(e.text||""),styleBuiltIn:e.styleBuiltIn,style:e.style})):[]}}),l=Math.round(pa()-s);if(r!==Tn)return mr(`Office snapshot: ${l}ms stale`),{stale:!0,generation:r};let u=!1;if(t){const e=Ko(yn,d.selectionParagraphs);u=Qo(e)}const p=yn?.currentScene;if(!p||!Number.isInteger(p.startParagraphIndex)||!Number.isInteger(p.endParagraphIndex))return null;const h=[];let m=0;const y=Math.min(p.endParagraphIndex,d.bodyTexts.length-1),g=yn.currentChapter?.startParagraphIndex;for(let e=p.startParagraphIndex;e<=y;e+=1){const t=String(d.bodyTexts[e]||"").trim();t&&!Yo.has(t)&&e!==g&&(h.push(t),m+=Bo(t))}p.wordCount=m,n&&xr(yn.currentChapter?.title,p.title,m,yn.currentChapter?.anchorId,p.anchorId,yn.currentChapter?.index);const f={documentGuid:Ro(),projectId:a?.projectId||null,bookId:c?.bookId||null,chapterId:tn,sceneId:en,chapterTitle:yn.currentChapter?.title||"",sceneTitle:p.title||"",sceneText:h.join("\n"),wordCount:m,selectionSignature:`${yn.currentParagraphIndex??-1}:${p.startParagraphIndex}:${p.endParagraphIndex}`,selectionChanged:u,generation:r};return jn=f,mr(`Office snapshot: ${l}ms; scene words: ${m}; total snapshot: ${Math.round(pa()-o)}ms`),f},ya=async()=>ha(jn)?jn:await ma(),ga=async()=>{if(br(""),!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return xr(null,null,null),br("Word document access is unavailable."),yo({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;F&&(F.disabled=!0,F.textContent="Scanning..."),br("Scanning document structure...");try{const e=await window.Word.run(async e=>{const t=vo();return t?await ua(e,!!t.usesExplicitScenes):(yn=null,await la(e))});return yn||xr(e.currentChapter?.title,e.currentScene?.title,e.currentScene?.wordCount,e.currentChapter?.anchorId,e.currentScene?.anchorId,e.currentChapter?.index),to("Not detected"),Xo(e),br(""),yo({lastScan:"Success",lastError:"-",paragraphs:String(e.paragraphCount),heading1:String(e.heading1Count),heading2:String(e.heading2Count)}),!0}catch(e){const t=go(e);return console.error("Unable to scan the Word document.",e),xr(null,null,null),br(`Unable to scan the Word document: ${t}`),yo({lastScan:"Failure",lastError:t}),!1}finally{F&&(F.disabled=!1,F.textContent="Refresh Document Structure")}},fa=async()=>{const e=vo();if(!ko()||!e)return Dr("Select a project and book to analyse manuscript structure."),!1;if(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return Dr("Word document access is unavailable."),yo({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;X&&(X.disabled=!0,X.textContent="Analysing..."),Dr("Analysing manuscript structure...");try{const t=await window.Word.run(async e=>await la(e)),n=await xa(`/api/word-companion/books/${e.bookId}/structure`);return xr(t.currentChapter?.title,t.currentScene?.title,t.currentScene?.wordCount,t.currentChapter?.anchorId,t.currentScene?.anchorId,t.currentChapter?.index),Xo(t),pn=((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=ca(t,r,n);for(const o of aa(t))ia(o,e,r,n)}return n})(t,n),da(pn),Dr("Preview generated. No changes have been applied."),yo({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),Dr("Unable to analyse manuscript structure."),yo({lastScan:"Failure",lastError:go(e)}),!1}finally{X&&(X.textContent="Analyse Manuscript Structure",Tr())}},wa=e=>{En&&(En(e),En=null),pt?.close?pt.close():pt&&(pt.hidden=!0)},Ia=()=>{const e=((e=pn)=>{const t=Ar(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(!ht)return;ht.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)}ht.append(n)})(e),pt?new Promise(e=>{En=e,pt.showModal?pt.showModal():pt.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.`))},Sa=(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,Ca=e=>Number.isInteger(e?.wordScene?.index)&&e.wordScene.index>0?10*e.wordScene.index:null,ka=async(e,t)=>{const n=await Na(`/api/word-companion/books/${e}/chapters`,{title:ao(t.wordTitle),sortOrder:ba(t)});if(!n?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");Vr(),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 Na(`/api/word-companion/books/${e}/chapters/${n.chapterId}/scenes`,{sceneTitle:ao(t.wordTitle),sortOrder:Ca(t)});if(!r?.sceneId)throw new Error("Scene creation did not return a scene ID.");Vr(),t.pdChapter=n,t.pdScene={sceneId:r.sceneId,title:t.wordTitle,sortOrder:Ca(t)||0},t.match=`Scene ${t.pdScene.sceneId}: ${t.pdScene.title}`},xa=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()},Na=(e,t)=>xa(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),Ea=async(e="")=>{Cn=!1,kn=0,Sn=[],S&&(S.innerHTML=""),Er(w,!0),Po(!1),Eo(""),Er(b,!0),e&&br(e);const t=await Pa();e&&t&&_t&&br(e)},La=async(e=en,t=tn)=>{const n=ko(),r=vo(),o=Ro(),a=Number.parseInt(e||"",10),c=Number.parseInt(t||"",10);if(!n||!r||!o||!Number.isInteger(a)||a<=0||!Number.isInteger(c)||c<=0)return;const i=`${n.projectId}:${r.bookId}:${a}`;if(sr!==i){sr=i;try{await Na("/api/word-companion/runtime/current-scene",{documentGuid:o,projectId:n.projectId,bookId:r.bookId,chapterId:c,sceneId:a}),hr("Current scene follow event sent.")}catch(e){sr="",console.debug("Unable to notify PlotDirector of current scene.",e)}}},Pa=async()=>{const e=vo();if(!(e&&Ft&&Vt&&window.Word&&"function"==typeof window.Word.run))return!1;br("Reading manuscript position...");try{Vr(),await Promise.all([Qa(!0),Xa(!0),Za(!0)]),await so(e.bookId);const t=await window.Word.run(async t=>await ua(t,!!e.usesExplicitScenes));return Xo(t),yo({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),_t?(zt?await ac():await oc(),Ur(!1),Rr("Live"),br(""),!0):(to("Not detected"),Ur(!1),Rr("Live"),br("Manuscript linked. Click inside a chapter to show the current scene."),!0)}catch(e){return console.error("Unable to initialise bound manuscript runtime.",e),yn=null,Rr("Manual"),br(`Unable to read manuscript position: ${go(e)}`),yo({lastScan:"Failure",lastError:go(e)}),!1}},Da=async n=>{hn=null,sc(),Nr(),Fr(),to("Not detected"),Rr("Manual"),wr("Connected"),Io(e,null),Io(t,null),M&&(M.value=""),So(O,"Select a project first"),Do(),l&&(l.value=""),So(u,"Select a project first"),qo(n||"Select a Project and Book to begin."),br(n||"Manuscript unlinked."),Pr("No resolved PlotDirector scene."),Po(!0),Lr()},qa=e=>e?[...e.querySelectorAll("input[type='checkbox']:checked")].map(e=>Number.parseInt(e.value||"",10)).filter(e=>Number.isInteger(e)&&e>0):[],Aa=()=>{const e=Number.parseInt(Pe?.value||"",10);return Number.isInteger(e)&&e>0?e:null},$a=(e,t,n,r)=>{const o=((e,t)=>Ho(e).find(e=>Go(e.tag,t))||null)(e,r),a=o||e.getRange().insertContentControl();return a.title=t,a.tag=n,a.appearance="Hidden",a},Ta=async(e="PlotDirector IDs attached successfully.")=>{if(!en||!tn)return br("No resolved PlotDirector scene."),!1;if((Zt&&Zt!==en||Xt&&Xt!==tn)&&!window.confirm("This scene is already linked. Replace the existing PlotDirector link?"))return!1;if(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return br("Word document access is unavailable."),!1;se&&(se.disabled=!0,se.textContent="Attaching...");try{return await window.Word.run(async e=>{const t=await la(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.");$a(n,"PlotDirector Chapter",`PD-CHAPTER-${tn}`,"PD-CHAPTER"),$a(r,"PlotDirector Scene",`PD-SCENE-${en}`,"PD-SCENE"),await e.sync()}),Xt=tn,Zt=en,on=!1,rn="SceneID Anchor",nn="Anchor",br(e),yo({lastError:"-"}),vr(),!0}catch(e){return console.error("Unable to attach PlotDirector IDs.",e),br("Unable to attach PlotDirector IDs."),yo({lastError:go(e)}),vr(),!1}finally{se&&(se.textContent=Zt===en?"Attach PlotDirector IDs":"Reattach PlotDirector IDs",vr())}},ja=async e=>{if(!tn)return _r("No resolved PlotDirector chapter."),!1;if(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return _r("Word document access is unavailable."),!1;try{return await window.Word.run(async e=>{const t=await la(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.");$a(n,"PlotDirector Chapter",`PD-CHAPTER-${tn}`,"PD-CHAPTER"),await e.sync()}),Xt=tn,on=!1,rn="ChapterID Anchor",nn="Chapter anchor",_r(e),br(e),yo({lastError:"-"}),vr(),!0}catch(e){return console.error("Unable to attach PlotDirector chapter ID.",e),_r("Unable to attach PlotDirector chapter ID."),yo({lastError:go(e)}),vr(),!1}},Wa=async e=>{Qr(),await ac(),br(e),_r(e)},Ra=e=>{un&&(un(e),un=null),it?.close?it.close():it&&(it.hidden=!0)},Ua=()=>{if(!rt)return;const e=ao(nt?.value||"").toLocaleLowerCase(),t=dn.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(rt.innerHTML="",ln=null,ot&&(ot.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No chapters found.",void rt.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",()=>{ln=t,ot&&(ot.disabled=!1)});const o=document.createElement("span");o.textContent=e.title||"Untitled chapter",n.append(r,o),rt.append(n)}},Ma=()=>{tt?.close?tt.close():tt&&(tt.hidden=!0)},Oa=async(e,t,n)=>{const r=vo();if(!r)return Jr("Select a PlotDirector book first."),!1;await ho(r.bookId,e,t,"Manual link","Title Match");return!!await Ta(n)&&(Jr(n),Zr(),!0)},Ba=e=>{sn&&(sn(e),sn=null),Ke?.close?Ke.close():Ke&&(Ke.hidden=!0)},Ga=()=>{if(!Ye)return;const e=ao(Ve?.value||"").toLocaleLowerCase(),t=an.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(Ye.innerHTML="",cn=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 Ye.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",()=>{cn=t,Je&&(Je.disabled=!1)});const o=document.createElement("span");o.textContent=e.title||"Untitled scene",n.append(r,o),Ye.append(n)}},Ha=()=>{Fe?.close?Fe.close():Fe&&(Fe.hidden=!0)},Fa=()=>{On=!1,Wr(),Bn&&(Bn=!1,Ya(1e3))},Va=async(e={})=>{const t=e.source||"manual",n=pa();if(!en)return void Pr("No resolved PlotDirector scene.");if(!tn)return void Pr("No resolved PlotDirector chapter.");if(Pn)return void Pr("Refresh Current Scene before syncing.");const r=vo(),o=Ro();if(!r||!o)return void Pr("Bound manuscript metadata is unavailable.");if(On)return Bn=!0,void hr("Scene sync deferred; sync already running.");Nr(),On=!0,Bn=!1;let a=e.snapshot||null;try{a=ha(a)?a:await ya()}catch(e){return Pr("Sync failed"),yo({lastError:go(e)}),hr("Scene sync failed."),void Fa()}if(!ha(a))return Pr("Waiting for typing to pause"),hr("Scene sync skipped (stale snapshot)."),void Fa();const c=a.wordCount;if(!Number.isInteger(c)||c<0)return Pr("Sync failed"),hr("Scene sync failed."),void Fa();if(Gn===a.sceneId&&Hn===c)return Pr("Synced"),hr("Sync skipped (count unchanged)."),void Fa();hr("Scene word count changed."),Ie&&(Ie.disabled=!0,Ie.textContent="Syncing..."),Pr("Syncing..."),hr(`Scene sync started (${t}).`);try{const e=pa(),t=await Na("/api/word-companion/runtime/scene-word-count",{documentGuid:a.documentGuid||o,bookId:a.bookId||r.bookId,chapterId:a.chapterId,sceneId:a.sceneId,wordCount:c});if(mr(`Word count sync API: ${Math.round(pa()-e)}ms`),!ha(a))return void hr("Scene sync result ignored (stale snapshot).");const i=t?.actualWords??c,s=new Date;Gn=a.sceneId,Hn=i,mo(be,Br(i)),mo(me,Br(i)),mo(Ce,Gr(s)),mo(we,Gr(s)),Pr("Synced"),hr("Scene sync succeeded."),mr(`Total word count sync: ${Math.round(pa()-n)}ms`)}catch(e){Pr("Sync failed"),yo({lastError:go(e)}),hr("Scene sync failed.")}finally{Ie&&(Ie.textContent="Sync Current Scene"),Fa()}},Ya=(e=4e3)=>{Nr(),en&&tn&&!Pn&&!On&&(Mn=window.setTimeout(()=>{Mn=null,Va({source:"automatic"})},e))},Ja=()=>{Fn&&(window.clearTimeout(Fn),Fn=null)},_a=()=>{Jn=null,_n="",zn=[],Kn=null,Qn="",Ja()},za=()=>{Xn=null,Zn="",er=[],tr=null,nr=""},Ka=()=>{rr=null,or="",ar=[],cr=null,ir=""},Qa=async(e=!1)=>{const t=ko(),n=Ro();if(!t||!n)return zn=[],[];if(!e&&Jn===t.projectId&&_n===n&&zn.length>0)return zn;const r=await xa(`/api/word-companion/runtime/characters?projectId=${encodeURIComponent(t.projectId)}&documentGuid=${encodeURIComponent(n)}`);return Jn=t.projectId,_n=n,zn=Array.isArray(r?.characters)?r.characters:[],hr("Character alias cache refreshed."),zn},Xa=async(e=!1)=>{const t=ko(),n=Ro();if(!t||!n)return er=[],[];if(!e&&Xn===t.projectId&&Zn===n&&er.length>0)return er;const r=await xa(`/api/word-companion/runtime/assets?projectId=${encodeURIComponent(t.projectId)}&documentGuid=${encodeURIComponent(n)}`);return Xn=t.projectId,Zn=n,er=Array.isArray(r?.assets)?r.assets:[],hr(`Asset cache loaded: ${er.length} aliases.`),er},Za=async(e=!1)=>{const t=ko(),n=Ro();if(!t||!n)return ar=[],[];if(!e&&rr===t.projectId&&or===n&&ar.length>0)return ar;const r=await xa(`/api/word-companion/runtime/locations?projectId=${encodeURIComponent(t.projectId)}&documentGuid=${encodeURIComponent(n)}`);return rr=t.projectId,or=n,ar=Array.isArray(r?.locations)?r.locations:[],hr(`Location cache loaded: ${ar.length} aliases.`),ar},ec=(e,t)=>{const n=String(t||"").trim();if(!n)return!1;const r=(o=n,String(o||"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).replace(/\s+/g,"\\s+");var o;return new RegExp(`(^|[^\\p{L}\\p{N}_])${r}(?=$|[^\\p{L}\\p{N}_])`,"iu").test(e)},tc=e=>{if(e?.excludeFromCompanionDetection)return!1;const t=Number.parseInt(e?.detectionPriority||"0",10);return n=e?.matchText,String(n||"").trim().split(/\s+/).filter(Boolean).length>=2||Number.isInteger(t)&&t>=75;var n},nc=async()=>{if(Fn=null,!en||Pn||!Ro())return;if(Vn)return Yn=!0,void hr("Character suggestion detection deferred; detection already running.");Vn=!0,Yn=!1;const e=pa();try{const t=await ya();if(!ha(t))return void hr("Runtime suggestions skipped (stale snapshot).");const[n,r,o]=await Promise.all([Qa(),Xa(),Za()]);if(!ha(t))return void hr("Runtime suggestions skipped after cache load (stale snapshot).");const a=t.sceneText||"",c=pa(),i=((e,t)=>{if(!e||!Array.isArray(t)||0===t.length)return[];const n=new Map;for(const r of t){const t=Number.parseInt(r.characterId||"",10);!Number.isInteger(t)||t<=0||n.has(t)||ec(e,r.matchText)&&n.set(t,r.name||r.matchText||"Character")}return[...n.entries()].map(([e,t])=>({characterId:e,name:t}))})(a,n);mr(`Character detection: ${Math.round(pa()-c)}ms`);const s=i.map(e=>e.characterId),d=s.slice().sort((e,t)=>e-t).join(","),l=pa(),u=((e,t)=>{if(!e||!Array.isArray(t)||0===t.length)return[];const n=new Map;for(const r of t){const t=Number.parseInt(r.assetId||"",10);!Number.isInteger(t)||t<=0||n.has(t)||ec(e,r.matchText)&&n.set(t,r.name||r.matchText||"Asset")}return[...n.entries()].map(([e,t])=>({assetId:e,name:t}))})(a,r);mr(`Asset detection: ${Math.round(pa()-l)}ms`);const p=u.map(e=>e.assetId),h=p.slice().sort((e,t)=>e-t).join(","),m=pa(),y=((e,t)=>{if(!e||!Array.isArray(t)||0===t.length)return[];const n=new Map;for(const r of t){const t=Number.parseInt(r.locationId||"",10);!Number.isInteger(t)||t<=0||n.has(t)||!tc(r)||ec(e,r.matchText)&&n.set(t,r.name||r.matchText||"Location")}return[...n.entries()].map(([e,t])=>({locationId:e,name:t}))})(a,o);mr(`Location detection: ${Math.round(pa()-m)}ms`);const g=y.map(e=>e.locationId),f=g.slice().sort((e,t)=>e-t).join(",");if(!d||Kn===en&&Qn===d)hr("Character suggestions skipped.");else{if(!ha(t))return void hr("Character suggestions skipped before submit (stale snapshot).");const e=pa(),n=await Na("/api/word-companion/runtime/character-suggestions",{documentGuid:t.documentGuid,sceneId:t.sceneId,characterIds:s});if(mr(`Character suggestion API: ${Math.round(pa()-e)}ms`),!ha(t))return void hr("Character suggestion result ignored (stale snapshot).");if(Kn=t.sceneId,Qn=d,(n?.createdCount||0)>0){const e=i.slice(0,3).map(e=>e.name).join(", "),t=i.length>3?" +"+(i.length-3):"";br(e?`Characters detected: ${e}${t}`:n.message)}hr(n?.message||"Character suggestions submitted.")}if(!h||tr===en&&nr===h)hr("Asset suggestions skipped.");else{if(!ha(t))return void hr("Asset suggestions skipped before submit (stale snapshot).");hr(`Asset matches found: ${u.map(e=>e.name).join(", ")}`);const e=pa(),n=await Na("/api/word-companion/runtime/asset-suggestions",{documentGuid:t.documentGuid,sceneId:t.sceneId,assetIds:p});if(mr(`Asset suggestion API: ${Math.round(pa()-e)}ms`),!ha(t))return void hr("Asset suggestion result ignored (stale snapshot).");if(tr=t.sceneId,nr=h,(n?.createdCount||0)>0){const e=u.slice(0,3).map(e=>e.name).join(", "),t=u.length>3?" +"+(u.length-3):"";br(e?`Assets detected: ${e}${t}`:n.message)}hr(n?.message||"Asset suggestions submitted.")}if(!f||cr===en&&ir===f)hr("Location suggestions skipped.");else{if(!ha(t))return void hr("Location suggestions skipped before submit (stale snapshot).");hr(`Location matches found: ${y.map(e=>e.name).join(", ")}`);const e=pa(),n=await Na("/api/word-companion/runtime/location-suggestions",{documentGuid:t.documentGuid,sceneId:t.sceneId,locationIds:g});if(mr(`Location suggestion API: ${Math.round(pa()-e)}ms`),!ha(t))return void hr("Location suggestion result ignored (stale snapshot).");if(cr=t.sceneId,ir=f,(n?.createdCount||0)>0){const e=y.slice(0,3).map(e=>e.name).join(", "),t=y.length>3?" +"+(y.length-3):"";br(e?`Locations detected: ${e}${t}`:n.message)}hr(n?.message||"Location suggestions submitted.")}mr(`Total suggestion pass: ${Math.round(pa()-e)}ms`)}catch(e){console.error("Unable to detect runtime suggestions.",e),yo({lastError:go(e)})}finally{Vn=!1,Yn&&(Yn=!1,rc(1500))}},rc=(e=2500)=>{Ja(),!en||Pn||Vn?Vn&&(Yn=!0):Fn=window.setTimeout(()=>{nc()},e)},oc=async()=>{const e=ko(),t=vo(),n=co(_t,"chapter");if(io({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?Co(t):void 0,detectedChapter:_t,detectedScene:zt,requestChapter:n,requestScene:"",result:"Not run",chapterId:null,sceneId:null}),!t)return to("Not detected"),br("Select a PlotDirector book first."),!1;if(!_t)return to("Not detected"),br("No chapter detected in Word. Use Heading 1 for chapters."),!1;to("Not detected");try{const e=await lo(t.bookId),r=Xt?e.find(e=>e.chapterId===Xt):null,o=n.toLocaleLowerCase(),a=o?e.find(e=>co(e.title,"chapter").toLocaleLowerCase()===o):null,c=r||a;return c?(Qr(),Mr(null,c.chapterId,r?"Chapter anchor":"Chapter title"),rn=r?"ChapterID Anchor":"Title Match",Cr("Chapter linked to PlotDirector"),br("No scene detected in Word. Use Heading 2 for scenes."),io({result:"Chapter matched",chapterId:c.chapterId,sceneId:null}),!0):(Mr(null),Cr("Chapter not found in PlotDirector."),br("Chapter not found in PlotDirector."),io({result:"Chapter not matched",chapterId:null,sceneId:null}),Xr("Chapter not found in PlotDirector."),!1)}catch(e){return to("Not found in PlotDirector"),yo({lastError:go(e)}),br("Unable to load PlotDirector chapter data."),!1}},ac=async()=>{const e=ko(),t=vo(),n=co(_t,"chapter"),r=co(zt,"scene");if(io({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?Co(t):void 0,detectedChapter:_t,detectedScene:zt,requestChapter:n,requestScene:r,result:"Not run",chapterId:null,sceneId:null}),kr({anchorType:Zt?"SceneID Anchor":Xt?"ChapterID Anchor":"Title Match",storedSceneId:Zt,storedChapterId:Xt,resolutionMethod:"-"}),!t)return to("Not detected"),br("Select a PlotDirector book first."),io({result:"Error"}),!1;if(!_t||!zt)return to("Not detected"),br("No scene detected in Word. Use Heading 2 for scenes."),io({result:"Error"}),!1;ne&&(ne.disabled=!0,ne.textContent="Refreshing...");const o=()=>{ne&&(ne.disabled=!1,ne.textContent="Refresh PlotDirector Scene")};to("Not detected"),br("Resolving PlotDirector scene...");try{if(Zt){const e=await(async(e,t)=>{const n=await xa(`/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 io({result:"Matched",chapterId:e.chapter.chapterId,sceneId:e.scene.sceneId}),await ho(t.bookId,e.scene.sceneId,e.chapter.chapterId,"Anchor","SceneID Anchor"),!0;on=!0,rn="SceneID Anchor",Cr("Not found in PlotDirector"),br("Stored PlotDirector ID is invalid."),io({result:"Error",chapterId:Xt,sceneId:Zt}),kr({anchorType:"SceneID Anchor",storedSceneId:Zt,storedChapterId:Xt,resolutionMethod:"Anchor"})}if(Xt){const e=(await so(t.bookId)).find(e=>e.chapterId===Xt),n=e?(Array.isArray(e.scenes)?e.scenes:[]).find(e=>co(e.title,"scene").toLocaleLowerCase()===r.toLocaleLowerCase()):null;if(n)return io({result:"Matched",chapterId:e.chapterId,sceneId:n.sceneId}),await ho(t.bookId,n.sceneId,e.chapterId,"Anchor","ChapterID Anchor"),!0;e&&!Zt?(rn="ChapterID Anchor",Mr(null,Xt,"Chapter anchor"),io({result:"Chapter matched",chapterId:Xt,sceneId:null})):Zt||(rn="ChapterID Anchor",io({result:"Chapter anchor not found",chapterId:Xt,sceneId:null}))}const e=await Na(`/api/word-companion/books/${t.bookId}/resolve-scene`,{chapterTitle:n,sceneTitle:r});if(!e?.matched||!e.sceneId){const t=on,n=Number.parseInt(e?.chapterId||"",10),r=Number.isInteger(tn)&&tn>0?tn:null,a=Number.isInteger(n)&&n>0?n:r,c=!!e?.chapterMatched||!!a;return to("Not found in PlotDirector"),on=t,c&&(Mr(null,a,a===r?"Chapter anchor":"Chapter title"),Cr("Scene not found in PlotDirector.")),br(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."),io({result:"Not matched",chapterId:c?a:e?.chapterId,sceneId:e?.sceneId}),t||(c?(Qr(),eo("Scene not found in PlotDirector.")):(Zr(),Xr("Chapter not found in PlotDirector."))),o(),!1}const a=on;return io({result:a?"Matched by title fallback":"Matched",chapterId:e.chapterId,sceneId:e.sceneId}),await ho(t.bookId,e.sceneId,e.chapterId,a?"Title fallback":"Title","Title Match"),a&&(on=!0,br("Stored PlotDirector ID is invalid."),vr()),!0}catch(e){const t=on;return yo({lastError:go(e)}),to("Not found in PlotDirector"),on=t,br(t?"Stored PlotDirector ID is invalid.":"Unable to load PlotDirector scene data."),io({result:"Error"}),!1}finally{o()}},cc=async()=>{if(Dn=null,Un)return $n=!0,void hr("Runtime update deferred; update already running.");if(!Bt||!vo())return qn=!1,void hr("Runtime update skipped.");if(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return qn=!1,Rr("Manual"),void br("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");if(!yn)return qn=!1,Rr("Manual"),void br("Document structure is not cached yet. Use Refresh Current Scene.");const e=Date.now()-An;if(qn&&e<Wn)return hr("Runtime update skipped (typing active)."),void ic(Wn-e);Un=!0,qn=!1,$n=!1,Rr("Updating..."),hr("Runtime update executed.");try{const e=await ma({includeSelection:!0});if(!ha(e))return Rr("Waiting for typing to pause"),void hr("Runtime update skipped (stale snapshot).");if(!!!e.selectionChanged)return Ur(!1),Rr("Current scene updated"),Ya(),void rc();zt?await ac():await oc(),Ur(!1),Rr("Current scene updated"),br("Current scene updated."),Ya(),rc()}catch(e){console.error("Unable to refresh current scene from Word selection.",e),yo({lastError:go(e)}),Ur(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving.")}finally{Un=!1,($n||qn)&&($n=!1,ic(Wn))}},ic=(e=1200)=>{Dn&&window.clearTimeout(Dn),Dn=window.setTimeout(cc,Math.max(0,e)),Rr("Waiting for typing to pause"),hr("Runtime update scheduled.")},sc=()=>{Dn&&(window.clearTimeout(Dn),Dn=null),qn=!1,$n=!1},dc=()=>{((e="selection",t=1200)=>{if(qn=!0,An=Date.now(),Tn+=1,jn=null,Nr(),Ja(),On&&(Bn=!0),Vn&&(Yn=!0),hr(`${e} changed.`),Un)return $n=!0,void Rr("Waiting for typing to pause");ic(t)})("Selection")},lc=()=>{if(Rn&&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:dc}),Rn=!1}catch(e){console.warn("Unable to remove Word selection tracking handler.",e)}},uc=async(e,n)=>{if(yn=null,Vr(),!e)return Ht=[],So(O,"Select a project first"),So(u,"Select a project first"),Sr(""),Io(t,null),Uo(),to("Not detected"),void qr();So(O,"Loading books..."),Sr(""),to("Not detected"),qr("Select a book to analyse manuscript structure.");try{const r=await xa(`/api/word-companion/projects/${e}/books`);if(Ht=Array.isArray(r.books)?r.books:[],0===Ht.length)return So(O,"No books available."),So(u,"No books available."),Sr("No books available."),Io(t,null),Uo(),void qo("No books available.");bo(O,"Choose a book",Ht.map(e=>({...e,displayTitle:Co(e)})),"bookId","displayTitle");const o=Ht.find(e=>e.bookId===n);o&&O?(O.value=String(o.bookId),Io(t,o.bookId)):Io(t,null),((e=null)=>{if(!u)return;if(0===Ht.length)return void So(u,"No books available.");bo(u,"Choose a book",Ht.map(e=>({...e,displayTitle:Co(e)})),"bookId","displayTitle");const t=e||Number.parseInt(O?.value||"",10),n=Ht.find(e=>e.bookId===t);n&&(u.value=String(n.bookId)),Lo()})(o?.bookId||n),Uo(),to((vo(),"Not detected")),qr(vo()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),qo(No()?"Ready to scan manuscript structure.":"Select a Book to begin.")}catch{Ht=[],So(O,"Unable to load books."),So(u,"Unable to load books."),Sr("Unable to load books."),Io(t,null),Uo(),to("Not detected"),qr("Unable to load books."),qo("Unable to load books.")}};for(const e of i)e.addEventListener("click",()=>gr(e.dataset.tabButton));fr(),M?.addEventListener("change",async()=>{const n=Number.parseInt(M.value||"",10);Fr(),l&&Number.isInteger(n)&&n>0&&(l.value=String(n)),Io(e,Number.isInteger(n)&&n>0?n:null),Io(t,null),to("Not detected"),qr(),qo("Select a Book to begin."),await uc(n,null)}),O?.addEventListener("change",()=>{const e=Number.parseInt(O.value||"",10);Fr(),Io(t,Number.isInteger(e)&&e>0?e:null),u&&Number.isInteger(e)&&e>0&&(u.value=String(e)),Uo(),to("Not detected"),qr(vo()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),qo(No()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),l?.addEventListener("change",async()=>{const n=Number.parseInt(l.value||"",10);Fr(),M&&Number.isInteger(n)&&n>0&&(M.value=String(n)),Io(e,Number.isInteger(n)&&n>0?n:null),Io(t,null),qo("Select a Book to begin."),await uc(n,null)}),u?.addEventListener("change",()=>{const e=Number.parseInt(u.value||"",10);Fr(),O&&Number.isInteger(e)&&e>0&&(O.value=String(e)),Io(t,Number.isInteger(e)&&e>0?e:null),Uo(),qo(No()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),p?.addEventListener("input",Lo),h?.addEventListener("click",async()=>{const e=xo(),t=String(p?.value||"").trim();if(e&&t){h.disabled=!0,Eo("Creating Book...");try{const n=await Na(`/api/word-companion/projects/${e.projectId}/books`,{title:t});p&&(p.value=""),M&&(M.value=String(e.projectId)),await uc(e.projectId,n.bookId),u&&(u.value=String(n.bookId)),Eo("Ready to scan manuscript structure.")}catch(e){console.error("Unable to create Book from Word Companion.",e),Eo(`Unable to create Book: ${go(e)}`)}finally{Lo()}}else Lo()}),m?.addEventListener("click",async()=>{const e=xo(),t=No();if(e&&t)if(Ft&&Vt&&window.Word&&"function"==typeof window.Word.run){m&&(m.disabled=!0,m.textContent="Scanning..."),Eo("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,o=null,a=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),Oo(e,1))return r={title:d,sortOrder:10*(n.length+1),wordCount:0,scenes:[]},n.push(r),o=s(),void(a+=Bo(d));if(!r||!o)return;if(t&&i.has(d))return void(o=s());const l=Bo(d);r.wordCount+=l,o.wordCount+=l,a+=l}),{chapters:n,chapterCount:n.length,sceneCount:n.reduce((e,t)=>e+t.scenes.length,0),wordCount:a,documentText:c.join("\n")}})(n.items,!!t.usesExplicitScenes)});In=n,bn=!1;const r=await Na("/api/word-companion/manuscript/analyse",{projectId:e.projectId,bookId:t.bookId,documentGuid:Wo(),chapterCount:n.chapterCount,sceneCount:n.sceneCount,wordCount:n.wordCount});wn=r,(e=>{if(!f)return;f.innerHTML="";const t=document.createElement("strong");t.textContent="Manuscript Analysis",f.append(t);const n=document.createElement("dl"),r=[["Project",e.projectTitle],["Book",Co({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 o=document.createElement("dd");o.textContent=t||"-",n.append(r,o)}f.append(n),Er(f,!1),Er(x,!1),Eo(e.message||"Preview generated."),Lo()})(r);try{const t=await Na("/api/word-companion/manuscript/discover-characters",{projectId:e.projectId,documentText:n.documentText||""});Sn=Array.isArray(t?.candidates)?t.candidates:[],Er(w,!0),Er(b,!0)}catch(e){console.error("Unable to discover character candidates.",e),Sn=[],Er(w,!0),Er(b,!0)}yo({lastScan:"Success",lastError:"-",paragraphs:"-",heading1:String(n.chapterCount),heading2:"-"})}catch(e){console.error("Unable to scan manuscript for first-run import.",e),qo(`Unable to scan manuscript: ${go(e)}`),yo({lastScan:"Failure",lastError:go(e)})}finally{m&&(m.textContent="Scan Manuscript"),Lo()}}else qo("Word document access is unavailable.");else qo("Select a Project and Book to begin.")}),N?.addEventListener("click",async()=>{const n=xo(),o=No();if(!(n&&o&&In&&wn?.canImport))return void Lo();let a=!1;if(!wn.requiresReplaceConfirmation||(a=await new Promise(e=>{if(!L||"function"!=typeof L.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=>{P?.removeEventListener("click",n),D?.removeEventListener("click",r),L?.removeEventListener("cancel",o),L?.close(),e(t)},n=()=>t(!0),r=()=>t(!1),o=e=>{e.preventDefault(),t(!1)};P?.addEventListener("click",n),D?.addEventListener("click",r),L?.addEventListener("cancel",o),L.showModal()}),a)){vn=!0,Lo(),Eo("Importing manuscript structure...");try{const i=Wo(),s=await Na("/api/word-companion/manuscript/import",{projectId:n.projectId,bookId:o.bookId,documentGuid:i,bindingVersion:1,replacePlanned:a,chapters:In.chapters});if(!s.imported)return wn={...wn,canImport:!s.requiresReplaceConfirmation,requiresReplaceConfirmation:!!s.requiresReplaceConfirmation,message:s.message||wn.message},Eo(s.message||"Import was not completed."),void Lo();const d=s.manuscriptDocument;await(c={documentGuid:d?.documentGuid||i,bookId:s.bookId,projectId:s.projectId,bindingVersion:d?.bindingVersion||1},new Promise((e,t)=>{const n=window.Office?.context?.document?.settings;n?(n.set(r.documentGuid,c.documentGuid),n.set(r.bookId,String(c.bookId)),n.set(r.projectId,String(c.projectId)),n.set(r.bindingVersion,String(c.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."))})),hn={documentGuid:d?.documentGuid||i,bookId:s.bookId,projectId:s.projectId,bindingVersion:d?.bindingVersion||1},Io(e,s.projectId),Io(t,s.bookId),M&&(M.value=String(s.projectId));const l=Sn;await uc(s.projectId,s.bookId),wr("Connected"),bn=!0,Cn=l.length>0,kn=Cn?Date.now():0,Sn=l,l.length>0?(Po(!0),$o(l),Er(x,!0),Er(b,!1),Eo(s.message||"Manuscript structure imported."),br(s.message||"Manuscript structure imported."),window.setTimeout(Lo,750)):await Ea(s.message||"Manuscript structure imported.")}catch(e){console.error("Unable to import manuscript structure.",e),Eo(`Unable to import manuscript: ${go(e)}`)}finally{vn=!1,Lo()}var c}else Eo("Import cancelled.")}),C?.addEventListener("click",async()=>{const e=xo()||ko(),t=Ao();if(!Cn||Date.now()-kn<750||!e||0===t.length)Lo();else{xn=!0,Lo(),mo(I,"Creating selected characters...");try{const n=await Na("/api/word-companion/manuscript/create-discovered-characters",{projectId:e.projectId,candidateNames:t});br(n.message||"Characters created."),mo(I,`${n.createdCount||0} created, ${n.skippedCount||0} already existed.`),await Ea(n.message||"Characters created.")}catch(e){console.error("Unable to create discovered characters.",e),mo(I,`Unable to create characters: ${go(e)}`)}finally{xn=!1,Lo()}}}),k?.addEventListener("click",()=>Ea("Character creation skipped.")),v?.addEventListener("click",()=>Ea()),y?.addEventListener("click",()=>Po(!1)),E?.addEventListener("click",()=>qo("Import cancelled.")),F?.addEventListener("click",ga),X?.addEventListener("click",fa),Z?.addEventListener("click",async()=>{const e=vo();if(!e||0===Ar().length||Nn)return void $r();if(!await Ia())return;Nn=!0,Tr(),Dr("Applying structure sync...");const t={createdChapters:0,createdScenes:0,linkedChapters:0,linkedScenes:0,skipped:Array.isArray(pn?.manualReview)?pn.manualReview.length:0,failed:0},n=Ar().filter(e=>"couldLink"===e.category&&"Chapter"===e.type),r=Ar().filter(e=>"wouldCreateChapters"===e.category),o=Ar().filter(e=>"couldLink"===e.category&&"Scene"===e.type),a=Ar().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(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)throw new Error("Word document access is unavailable.");await window.Word.run(async t=>{const n=await la(t),r="Chapter"===e.type?e.wordChapter:e.wordScene,o=Number.isInteger(r?.paragraphIndex)?n.bodyParagraphs[r.paragraphIndex]:null;if(!o)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.");$a(o,"PlotDirector Chapter",`PD-CHAPTER-${t}`,"PD-CHAPTER")}else{const t=e.pdScene?.sceneId;if(!t)throw new Error("Scene ID is not available.");$a(o,"PlotDirector Scene",`PD-SCENE-${t}`,"PD-SCENE")}await t.sync()})})(e),Sa(e,"Success"),t[n]+=1}catch(n){Sa(e,"Failed",go(n)),t.failed+=1}};try{for(const e of n)s(e,"linkedChapters");for(const n of r)try{await ka(e.bookId,n),s(n,"createdChapters")}catch(e){Sa(n,"Failed",go(e)),t.failed+=1}for(const e of o)s(e,"linkedScenes");for(const n of a)try{await va(e.bookId,n),s(n,"createdScenes")}catch(e){Sa(n,"Failed",go(e)),t.failed+=1}for(const e of c)await d(e.item,e.counterName);for(const e of pn.manualReview||[])Sa(e,"Skipped");da(pn),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),Dr(i)}finally{Nn=!1,Tr(),i&&(Vr(),await fa(),Dr(`${i} Preview refreshed.`))}}),mt?.addEventListener("click",()=>wa(!0)),yt?.addEventListener("click",()=>wa(!1)),pt?.addEventListener("cancel",e=>{e.preventDefault(),wa(!1)}),ne?.addEventListener("click",ac),H?.addEventListener("click",async()=>{if(!vo())return br("Select a PlotDirector book first."),void to("Not detected");sc(),Or(!0),Rr("Updating...");try{await Promise.all([Qa(!0),Xa(!0),Za(!0)]);if(!await ga())return;if(Ur(!1),!zt)return await oc(),void Rr("Current scene updated");await ac(),Rr("Current scene updated")}finally{Or(!1)}}),Ie?.addEventListener("click",()=>Va({source:"manual"})),De?.addEventListener("click",async()=>{if(en)if(!Pn&&await(async()=>{if(!en)return!1;if(!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return Ur(!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 la(e)),t=e.currentChapter?.title||"",n=e.currentScene?.title||"",r=e.currentScene?.anchorId||null,o=e.currentChapter?.anchorId||null,a=Number.isInteger(r)&&r===en,c=Number.isInteger(o)&&o===tn,i=co(n,"scene").toLocaleLowerCase()===co(dr||zt,"scene").toLocaleLowerCase(),s=co(t,"chapter").toLocaleLowerCase()===co(lr||_t,"chapter").toLocaleLowerCase();return a||i&&(c||s)?(Ur(!1),!0):(Ur(!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),yo({lastError:go(e)}),Ur(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1}})()){De&&(De.disabled=!0,De.textContent="Saving...");try{await(e=`/api/word-companion/scenes/${en}/links`,t={characterIds:qa(Ee),assetIds:qa(Le),locationIds:[],primaryLocationId:Aa()},xa(e,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})),(()=>{const e=new Set(qa(Ee)),t=new Set(qa(Le));pr={characters:pr.characters.map(t=>({...t,linked:e.has(Number.parseInt(no(t,"character"),10))})),assets:pr.assets.map(e=>({...e,linked:t.has(Number.parseInt(no(e,"asset"),10))})),locations:pr.locations,primaryLocationId:Aa()}})(),Yr("Scene links saved successfully."),yo({lastError:"-"})}catch(e){Yr("Unable to save scene links."),yo({lastError:go(e)})}finally{De&&(De.disabled=!en||Pn,De.textContent="Save Scene Links")}var e,t}else Yr("The Word cursor is now in a different scene. Refresh Current Scene before saving.");else Yr("Link a PlotDirector scene first.")}),se?.addEventListener("click",async()=>{await Ta()}),de?.addEventListener("click",async()=>{console.debug("Word Companion unlink clicked"),br("Preparing to unlink manuscript...");const e=(()=>{const e=hn||To();if(e)return e;const t=mn?.manuscriptDocument?.documentGuid||"",n=Number.parseInt(mn?.bookId||"",10),r=Number.parseInt(mn?.projectId||"",10);return t&&Number.isInteger(n)&&n>0&&Number.isInteger(r)&&r>0?{documentGuid:t,bookId:n,projectId:r,bindingVersion:Number.parseInt(mn?.manuscriptDocument?.bindingVersion||"",10)||1}:null})();if(!e)return void br("This Word document is not linked.");if(!e.documentGuid||!Number.isInteger(e.bookId)||e.bookId<=0)return void br("Unable to unlink: bound document metadata is incomplete.");if(await new Promise(e=>{if(!q||"function"!=typeof q.showModal)return void e(window.confirm("This will remove PlotDirector binding metadata from this Word document.\n\nIf PlotDirector is reachable, it will also unlink this Book in PlotDirector.\n\nYour manuscript text will not be changed.\n\nContinue?"));const t=t=>{A?.removeEventListener("click",n),$?.removeEventListener("click",r),q?.removeEventListener("cancel",o),q?.close(),e(t)},n=()=>t(!0),r=()=>t(!1),o=e=>{e.preventDefault(),t(!1)};A?.addEventListener("click",n),$?.addEventListener("click",r),q?.addEventListener("cancel",o),q.showModal()})){br("Unlinking manuscript..."),de&&(de.disabled=!0,de.textContent="Unlinking...");try{await Na("/api/word-companion/manuscript/unlink",{documentGuid:e.documentGuid,bookId:e.bookId}),await jo(),await Da("Manuscript unlinked.")}catch(e){console.error("Unable to unlink manuscript binding.",e),br("Unable to unlink from PlotDirector.");if(window.confirm("PlotDirector could not be updated, but you can still remove the binding from this Word document.\n\nYou may need to unlink the Book manually in PlotDirector later.\n\nRemove binding from this Word document only?"))try{await jo(),await Da("Word metadata removed. Unlink the Book manually in PlotDirector if it still shows as linked.")}catch(e){console.error("Unable to remove Word document metadata.",e),br(`Unable to remove Word metadata: ${go(e)}`)}else br(`Unable to unlink manuscript: ${go(e)}`)}finally{de&&(de.disabled=!1,de.textContent="Unlink this Word document"),Lr()}}else br("Unlink cancelled.")}),je?.addEventListener("click",async()=>{const e=vo();if(!e||!_t||tn)return void Xr("Chapter not found in PlotDirector.");const t=ao(_t),n=await((e,t)=>(mo(st,`"${e}"`),mo(dt,`"${t}"`),it?new Promise(e=>{un=e,it.showModal?it.showModal():it.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector chapter:\n\n"${e}"\n\nin book:\n\n"${t}"\n\n?`))))(t,Co(e)||"selected book");if(n){je&&(je.disabled=!0,je.textContent="Creating...");try{const n=Number.isInteger(Qt)&&Qt>0?10*Qt:null,r=await Na(`/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.");Vr(),Mr(null,r.chapterId,"Manual chapter link");if(!await ja("Chapter created and linked successfully."))return;await Wa("Chapter created and linked successfully.")}catch(e){_r("Unable to create chapter."),yo({lastError:go(e)})}finally{je&&(je.disabled=!zr(),je.textContent="Create Chapter in PlotDirector")}}}),We?.addEventListener("click",async()=>{const e=vo();if(e&&_t&&!tn){We&&(We.disabled=!0,We.textContent="Loading...");try{dn=await lo(e.bookId),ln=null,nt&&(nt.value=""),mo(ct,""),Ua(),tt?.showModal?tt.showModal():tt&&(tt.hidden=!1)}catch(e){_r("Unable to load chapters."),yo({lastError:go(e)})}finally{We&&(We.disabled=!zr(),We.textContent="Link to Existing Chapter")}}else Xr("Chapter not found in PlotDirector.")}),nt?.addEventListener("input",Ua),ot?.addEventListener("click",async()=>{const e=dn.find(e=>e.chapterId===ln);if(e){ot&&(ot.disabled=!0,ot.textContent="Linking...");try{Mr(null,e.chapterId,"Manual chapter link");if(!await ja("Chapter linked successfully."))return;Ma(),await Wa("Chapter linked successfully.")}catch(e){mo(ct,"Unable to link chapter."),_r("Unable to link chapter."),yo({lastError:go(e)})}finally{ot&&(ot.disabled=!ln,ot.textContent="Link Chapter")}}else mo(ct,"Select a chapter.")}),at?.addEventListener("click",Ma),lt?.addEventListener("click",()=>Ra(!0)),ut?.addEventListener("click",()=>Ra(!1)),it?.addEventListener("cancel",e=>{e.preventDefault(),Ra(!1)}),Be?.addEventListener("click",async()=>{const e=vo();if(!e||!zt)return void eo("Scene not found in PlotDirector.");const t=co(zt,"scene"),n=co(_t,"chapter"),r=await((e,t)=>(mo(Qe,`"${e}"`),mo(Xe,`"${t}"`),Ke?new Promise(e=>{sn=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){Be&&(Be.disabled=!0,Be.textContent="Creating...");try{const n=await po();if(!n)return void eo("This chapter does not exist in PlotDirector. Create or link the chapter first.");const r=await Na(`/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.");Vr(),await Oa(r.sceneId,r.chapterId,"Scene created and linked successfully.")}catch(e){Jr("Unable to create scene."),yo({lastError:go(e)})}finally{Be&&(Be.disabled=!Kr(),Be.textContent="Create Scene in PlotDirector")}}}),Ge?.addEventListener("click",async()=>{const e=vo();if(e&&zt){Ge&&(Ge.disabled=!0,Ge.textContent="Loading...");try{const t=await so(e.bookId),n=uo(t);if(!n)return void eo("This chapter does not exist in PlotDirector. Create or link the chapter first.");an=Array.isArray(n.scenes)?n.scenes:[],cn=null,Ve&&(Ve.value=""),mo(ze,""),Ga(),Fe?.showModal?Fe.showModal():Fe&&(Fe.hidden=!1)}catch(e){Jr("Unable to load scenes."),yo({lastError:go(e)})}finally{Ge&&(Ge.disabled=!Kr(),Ge.textContent="Link to Existing Scene")}}else eo("Scene not found in PlotDirector.")}),Ve?.addEventListener("input",Ga),Je?.addEventListener("click",async()=>{const e=vo(),t=an.find(e=>e.sceneId===cn);if(e&&t){Je&&(Je.disabled=!0,Je.textContent="Linking...");try{const e=await po();if(!e)throw new Error("This chapter does not exist in PlotDirector. Create or link the chapter first.");Ha(),await Oa(t.sceneId,e.chapterId,"Scene linked successfully.")}catch(e){mo(ze,"Unable to link scene."),Jr("Unable to link scene."),yo({lastError:go(e)})}finally{Je&&(Je.disabled=!cn,Je.textContent="Link Scene")}}else mo(ze,"Select a scene.")}),_e?.addEventListener("click",Ha),Ze?.addEventListener("click",()=>Ba(!0)),et?.addEventListener("click",()=>Ba(!1)),Ke?.addEventListener("cancel",e=>{e.preventDefault(),Ba(!1)}),Et?.addEventListener("click",async()=>{Et&&(Et.disabled=!0,Et.textContent="Running...");try{if(await fo(),!Ft||!Vt||!window.Word||"function"!=typeof window.Word.run)return void yo({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});yo({lastScan:"Success",lastError:"-",paragraphs:String(e)})}catch(e){console.error("Word Companion diagnostics failed.",e);const t=go(e);yo({lastScan:"Failure",lastError:t}),br(`Unable to scan the Word document: ${t}`)}finally{Et&&(Et.disabled=!1,Et.textContent="Run Diagnostics")}});const pc=Bt?(async()=>{So(M,"Loading projects..."),So(O,"Select a project first"),So(l,"Loading projects..."),So(u,"Select a project first"),Ir(""),Sr("");try{const n=await xa("/api/word-companion/projects");if(Gt=Array.isArray(n.projects)?n.projects:[],0===Gt.length)return So(M,"No projects available."),So(l,"No projects available."),Ir("No projects available."),Io(e,null),Io(t,null),Uo(),void qo("No projects available.");bo(M,"Choose a project",Gt,"projectId","title"),Do();const r=wo(e),o=Gt.find(e=>e.projectId===r);o&&M?(M.value=String(o.projectId),l&&(l.value=String(o.projectId)),Io(e,o.projectId),await uc(o.projectId,wo(t))):(Io(e,null),Io(t,null),Uo(),qo("Select a Project and Book to begin."))}catch{Gt=[],Ht=[],So(M,"Unable to connect to PlotDirector."),So(O,"Select a project first"),So(l,"Unable to connect to PlotDirector."),So(u,"Select a project first"),wr("Unable to connect to PlotDirector."),Ir("Unable to connect to PlotDirector."),Io(e,null),Io(t,null),Uo(),qo("Unable to connect to PlotDirector.")}})():Promise.resolve();if(Bt||(So(M,"Please sign in to PlotDirector."),So(O,"Please sign in to PlotDirector."),So(l,"Please sign in to PlotDirector."),So(u,"Please sign in to PlotDirector."),Uo()),!window.Office||"function"!=typeof window.Office.onReady)return yr("Word Companion ready"),br("Word document access is unavailable."),Rr("Manual"),void yo({host:"Unavailable",platform:"Unavailable",ready:"No",wordApi:"No"});fo().then(async()=>{yr("Word Companion ready"),await pc,await(async()=>{if(!Bt||!Vt)return void Po(!1);const n=To();if(n)try{const r=await xa(`/api/word-companion/runtime/book/${n.bookId}?documentGuid=${encodeURIComponent(n.documentGuid)}`),o=r?.manuscriptDocument;if(r?.bookId===n.bookId&&r?.projectId===n.projectId&&o&&String(o.documentGuid).toLowerCase()===n.documentGuid.toLowerCase())return hn=n,Hr(r),Io(e,r.projectId),Io(t,r.bookId),M&&(M.value=String(r.projectId)),await uc(r.projectId,r.bookId),Po(!1),wr("Connected"),Sr("Bound manuscript detected."),void await Pa()}catch{}hn=null,Fr(),Do(),xo()?await uc(xo().projectId,null):So(u,"Select a project first"),qo("Select a Project and Book to begin."),Po(!0)})(),Vt?(()=>{if(Bt){if(!window.Office?.context?.document||"function"!=typeof window.Office.context.document.addHandlerAsync||!window.Office?.EventType?.DocumentSelectionChanged)return Rr("Manual"),void br("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");try{window.Office.context.document.addHandlerAsync(window.Office.EventType.DocumentSelectionChanged,dc,e=>{e?.status===window.Office.AsyncResultStatus.Succeeded?(Rn=!0,Rr("Live")):(Rr("Manual"),br("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene."))}),window.addEventListener("beforeunload",lc)}catch(e){console.warn("Unable to register Word selection tracking handler.",e),Rr("Manual"),br("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.")}}})():(br("Word document access is unavailable."),Rr("Manual"))}).catch(e=>{console.error("Office readiness check failed.",e),wr("Unable to connect to PlotDirector."),yr("Word Companion unavailable"),br("Word document access is unavailable."),yo({ready:"No",wordApi:"No",lastScan:"Failure"})})})(); |