|
|
var L=p,O=Symbol.for("react.element"),F=Symbol.for("react.fragment"),B=Object.prototype.hasOwnProperty,G=L.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,W={key:!0,ref:!0,__self:!0,__source:!0};function E(s,c,u){var r,t={},n=null,o=null;u!==void 0&&(n=""+u),c.key!==void 0&&(n=""+c.key),c.ref!==void 0&&(o=c.ref);for(r in c)B.call(c,r)&&!W.hasOwnProperty(r)&&(t[r]=c[r]);if(s&&s.defaultProps)for(r in c=s.defaultProps,c)t[r]===void 0&&(t[r]=c[r]);return{$$typeof:O,type:s,key:n,ref:o,props:t,_owner:G.current}}C.Fragment=F;C.jsx=E;C.jsxs=E;k.exports=C;var e=k.exports,T={},P=R;T.createRoot=P.createRoot,T.hydrateRoot=P.hydrateRoot;const M=({onTopicsChange:s,availableTopics:c=[],selectedTopics:u=[],customSentence:r="",onSentenceChange:t,multiTheme:n=!0,onMultiThemeChange:o})=>{const b=a=>{const v=u.includes(a)?u.filter(j=>j!==a):[...u,a];s(v)};return e.jsxs("div",{className:"topic-selector",children:[e.jsx("h3",{children:"Select Topics"}),e.jsx("div",{className:"topic-buttons",children:c.map(a=>e.jsx("button",{className:`topic-btn ${u.includes(a.name)?"selected":""}`,onClick:()=>b(a.name),children:a.name},a.id))}),e.jsxs("div",{className:"sentence-input-container",children:[e.jsx("label",{htmlFor:"custom-sentence",className:"sentence-label",children:"Custom Sentence (optional)"}),e.jsx("textarea",{id:"custom-sentence",className:"sentence-input",value:r,onChange:a=>t&&t(a.target.value),placeholder:"Enter a sentence to influence word selection...",rows:"3",maxLength:"200"}),e.jsxs("div",{className:"sentence-info",children:[e.jsxs("span",{className:"char-count",children:[r.length,"/200 characters"]}),r&&e.jsx("button",{type:"button",className:"clear-sentence-btn",onClick:()=>t&&t(""),title:"Clear sentence",children:"Clear"})]})]}),e.jsxs("div",{className:"multi-theme-toggle-container",children:[e.jsxs("label",{className:"multi-theme-toggle",children:[e.jsx("input",{type:"checkbox",checked:n,onChange:a=>o&&o(a.target.checked),className:"multi-theme-checkbox"}),e.jsx("span",{className:"multi-theme-label",children:"🎯 Use Multi-Theme Processing"})]}),e.jsx("p",{className:"multi-theme-description",children:n?"AI will process each theme separately and balance results":"AI will blend all themes into a single concept"})]}),e.jsxs("p",{className:"selected-count",children:[u.length," topic",u.length!==1?"s":""," selected"]})]})},U=({grid:s,clues:c,showSolution:u,onCellChange:r})=>{const[t,n]=p.useState({});p.useEffect(()=>{n({})},[s]);const o=(d,i,m)=>{const x=`${d}-${i}`,g={...t,[x]:m.toUpperCase()};n(g),r&&r(d,i,m)},b=(d,i)=>{if(u&&!a(d,i))return s[d][i];const m=`${d}-${i}`;return t[m]||""},a=(d,i)=>s[d][i]===".",v=(d,i)=>{if(!c)return null;const m=c.find(x=>x.position.row===d&&x.position.col===i);return m?m.number:null};if(!s||s.length===0)return e.jsx("div",{className:"puzzle-grid",children:"No puzzle loaded"});const j=s.length,y=s[0]?s[0].length:0;return e.jsx("div",{className:"puzzle-container",children:e.jsx("div",{className:"puzzle-grid",style:{gridTemplateColumns:`repeat(${y}, 35px)`,gridTemplateRows:`repeat(${j}, 35px)`},children:s.map((d,i)=>d.map((m,x)=>{const g=v(i,x);return a(i,x)?e.jsx("div",{className:"grid-cell empty-cell",style:{visibility:"hidden"}},`${i}-${x}`):e.jsxs("div",{className:"grid-cell white-cell",children:[g&&e.jsx("span",{className:"cell-number",children:g}),e.jsx("input",{type:"text",maxLength:"1",value:b(i,x),onChange:l=>o(i,x,l.target.value),className:`cell-input ${u?"solution-text":""}`,disabled:u})]},`${i}-${x}`)}))})})},q=({clues:s=[]})=>{const c=s.filter(t=>t.direction==="across"),u=s.filter(t=>t.direction==="down"),r=({title:t,clueList:n})=>e.jsxs("div",{className:"clue-section",children:[e.jsx("h4",{children:t}),e.jsx("ol",{children:n.map(o=>e.jsxs("li",{className:"clue-item",children:[e.jsx("span",{className:"clue-number",children:o.number}),e.jsx("span",{className:"clue-text",children:o.text})]},`${o.number}-${o.direction}`))})]});return e.jsxs("div",{className:"clue-list",children:[e.jsx(r,{title:"Across",clueList:c}),e.jsx(r,{title:"Down",clueList:u})]})},Y=({debugData:s})=>{const[c,u]=p.useState("overview"),[r,t]=p.useState("similarity"),[n,o]=p.useState("desc");if(!s||!s.enabled)return e.jsx("div",{className:"debug-tab",children:e.jsx("p",{children:"Debug data not available. Set ENABLE_DEBUG_TAB=true on the backend."})});const b=[{id:"overview",label:"Overview"},{id:"thematic-pool",label:"Thematic Pool"},{id:"candidates",label:"Candidates"},{id:"selection",label:"Selection"},{id:"selected",label:"Selected Words"}],a=()=>{var l,f,h;return e.jsxs("div",{className:"debug-section",children:[e.jsx("h3",{children:"Generation Parameters"}),e.jsxs("div",{className:"debug-grid",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"Topics:"})," ",s.generation_params.topics.join(", ")]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Difficulty:"})," ",s.generation_params.difficulty]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Requested Words:"})," ",s.generation_params.requested_words]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Thematic Pool Size:"})," ",s.generation_params.thematic_pool_size]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Min Similarity:"})," ",s.generation_params.min_similarity]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Multi-theme:"})," ",s.generation_params.multi_theme?"Yes":"No"]}),s.generation_params.custom_sentence&&e.jsxs("div",{children:[e.jsx("strong",{children:"Custom Sentence:"}),' "',s.generation_params.custom_sentence,'"']})]}),e.jsx("h3",{children:"Selection Algorithm"}),e.jsxs("div",{className:"debug-grid",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"Method:"})," ",s.selection_method]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Temperature:"})," ",s.selection_params.similarity_temperature]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Difficulty Weight:"})," ",s.selection_params.difficulty_weight]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Use Softmax:"})," ",s.selection_params.use_softmax_selection?"Yes":"No"]})]}),e.jsx("h3",{children:"Results Summary"}),e.jsxs("div",{className:"debug-grid",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"Thematic Pool:"})," ",((l=s.thematic_pool)==null?void 0:l.length)||0," words"]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Candidates:"})," ",((f=s.candidate_words)==null?void 0:f.length)||0," words"]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Selected:"})," ",((h=s.selected_words)==null?void 0:h.length)||0," words"]})]})]})},v=(l,f=!1)=>e.jsx("div",{className:"word-table-container",children:e.jsxs("table",{className:"word-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Word"}),e.jsx("th",{children:"Similarity"}),e.jsx("th",{children:"Percentile"}),e.jsx("th",{children:"Tier"}),f&&e.jsx("th",{children:"Clue"})]})}),e.jsx("tbody",{children:l.map((h,N)=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("strong",{children:h.word})}),e.jsx("td",{children:h.similarity.toFixed(3)}),e.jsx("td",{children:h.percentile.toFixed(3)}),e.jsx("td",{title:h.tier_description||h.tier,children:h.tier.replace("tier_","").replace("_"," ")}),f&&e.jsx("td",{children:h.clue})]},N))})]})}),j=l=>{r===l?o(n==="asc"?"desc":"asc"):(t(l),o(l==="word"?"asc":"desc"))},y=l=>r!==l?" ↕️":n==="asc"?" ▲":" ▼",d=()=>{const f=[...s.thematic_pool||[]].sort((h,N)=>{let w,S;switch(r){case"word":w=h.word.toLowerCase(),S=N.word.toLowerCase();break;case"similarity":w=h.similarity,S=N.similarity;break;case"percentile":w=h.percentile,S=N.percentile;break;default:w=h.similarity,S=N.similarity}return n==="asc"?w<S?-1:w>S?1:0:w>S?-1:w<S?1:0});return e.jsx("div",{className:"word-table-container",children:e.jsxs("table",{className:"word-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsxs("th",{onClick:()=>j("word"),style:{cursor:"pointer",userSelect:"none"},className:r==="word"?"sorted-column":"",children:["Word",y("word")]}),e.jsxs("th",{onClick:()=>j("similarity"),style:{cursor:"pointer",userSelect:"none"},className:r==="similarity"?"sorted-column":"",children:["Similarity",y("similarity")]}),e.jsxs("th",{onClick:()=>j("percentile"),style:{cursor:"pointer",userSelect:"none"},className:r==="percentile"?"sorted-column":"",children:["Percentile",y("percentile")]}),e.jsx("th",{children:"Tier"})]})}),e.jsx("tbody",{children:f.map((h,N)=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("strong",{children:h.word})}),e.jsx("td",{children:h.similarity.toFixed(3)}),e.jsx("td",{children:h.percentile.toFixed(3)}),e.jsx("td",{title:h.tier_description||h.tier,children:h.tier.replace("tier_","").replace("_"," ")})]},N))})]})})},i=()=>{const l=s.thematic_pool||[];return e.jsxs("div",{className:"debug-section",children:[e.jsxs("h3",{children:["Thematic Pool (",l.length," words)"]}),e.jsx("p",{children:"All words generated thematically. Click column headers to sort."}),d()]})},m=()=>{const l=s.candidate_words||[];return e.jsxs("div",{className:"debug-section",children:[e.jsxs("h3",{children:["Candidate Words (",l.length," words)"]}),e.jsx("p",{children:"Words that passed filtering and got clues generated."}),v(l,!0)]})},x=()=>e.jsxs("div",{className:"debug-section",children:[e.jsx("h3",{children:"Selection Process"}),e.jsxs("div",{className:"debug-grid",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"Algorithm:"})," ",s.selection_method]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Temperature:"})," ",s.selection_params.similarity_temperature," (lower = more deterministic)"]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Difficulty Weight:"})," ",s.selection_params.difficulty_weight," (balance between similarity and frequency)"]})]}),e.jsx("h4",{children:"How it works:"}),e.jsxs("ul",{children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Composite Score"})," = (1 - difficulty_weight) × similarity + difficulty_weight × frequency_alignment"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Frequency Alignment"}),": Gaussian distribution favoring target percentiles by difficulty"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Softmax Selection"}),": Probabilistic selection based on composite scores with temperature control"]})]}),e.jsx("h4",{children:"Difficulty Targets:"}),e.jsxs("ul",{children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Easy:"})," 90th percentile (common words like CAT, DOG)"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Medium:"})," 50th percentile (balanced selection)"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Hard:"})," 20th percentile (rare words like QUETZAL, PLATYPUS)"]})]})]}),g=()=>{const l=s.selected_words||[];return e.jsxs("div",{className:"debug-section",children:[e.jsxs("h3",{children:["Selected Words (",l.length," words)"]}),e.jsx("p",{children:"Final words chosen for crossword generation."}),v(l,!0)]})},z=()=>{switch(c){case"overview":return a();case"thematic-pool":return i();case"candidates":return m();case"selection":return x();case"selected":return g();default:return a()}};return e.jsxs("div",{className:"debug-tab",children:[e.jsx("div",{className:"debug-nav",children:b.map(l=>e.jsx("button",{className:`debug-nav-btn ${c===l.id?"active":""}`,onClick:()=>u(l.id),children:l.label},l.id))}),e.jsx("div",{className:"debug-content",children:z()})]})},H=({message:s="Generating puzzle..."})=>e.jsxs("div",{className:"loading-spinner",children:[e.jsx("div",{className:"spinner"}),e.jsx("p",{className:"loading-message",children:s})]}),J=()=>{const[s,c]=p.useState(null),[u,r]=p.useState(!1),[t,n]=p.useState(null),[o,b]=p.useState([]),a="",v=p.useCallback(async()=>{try{r(!0);const i=await fetch(`${a}/api/topics`);if(!i.ok)throw new Error("Failed to fetch topics");const m=await i.json();b(m)}catch(i){n(i.message)}finally{r(!1)}},[a]),j=p.useCallback(async(i,m="medium",x=!1,g="",z=!0)=>{try{r(!0),n(null);const l=await fetch(`${a}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({topics:i,difficulty:m,useAI:x,...g&&{customSentence:g},multiTheme:z})});if(!l.ok){const h=await l.json().catch(()=>({}));throw new Error(h.message||"Failed to generate puzzle")}const f=await l.json();return c(f),f}catch(l){return n(l.message),null}finally{r(!1)}},[a]),y=p.useCallback(async i=>{try{const m=await fetch(`${a}/api/validate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({puzzle:s,answers:i})});if(!m.ok)throw new Error("Failed to validate answers");return await m.json()}catch(m){return n(m.message),null}},[a,s]),d=p.useCallback(()=>{c(null),n(null)},[]);return{puzzle:s,loading:u,error:t,topics:o,fetchTopics:v,generatePuzzle:j,validateAnswers:y,resetPuzzle:d}};function V(){const[s,c]=p.useState([]),[u,r]=p.useState("medium"),[t,n]=p.useState(!1),[o,b]=p.useState(""),[a,v]=p.useState(!0),[j,y]=p.useState("puzzle"),{puzzle:d,loading:i,error:m,topics:x,fetchTopics:g,generatePuzzle:z,resetPuzzle:l}=J();p.useEffect(()=>{g()},[g]);const f=async()=>{if(s.length===0&&!o.trim()){alert("Please select at least one topic or provide a custom sentence");return}n(!1),await z(s,u,!1,o,a)},h=_=>{c(_)},N=_=>{b(_)},w=_=>{v(_)},S=()=>{l(),c([]),n(!1),r("medium"),b(""),v(!0),y("puzzle")},A=()=>{n(!0)};return e.jsxs("div",{className:"crossword-app",children:[e.jsxs("header",{className:"app-header",children:[e.jsx("h1",{className:"app-title",children:"Crossword Puzzle Generator"}),e.jsx("p",{children:"Select topics and generate your custom crossword puzzle!"})]}),e.jsx(M,{onTopicsChange:h,availableTopics:x,selectedTopics:s,customSentence:o,onSentenceChange:N,multiTheme:a,onMultiThemeChange:w}),e.jsxs("div",{className:"puzzle-controls",children:[e.jsxs("select",{value:u,onChange:_=>r(_.target.value),className:"control-btn",children:[e.jsx("option",{value:"easy",children:"Easy"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"hard",children:"Hard"})]}),e.jsx("button",{onClick:f,disabled:i||s.length===0&&!o.trim(),className:"control-btn generate-btn",children:i?"Generating...":"Generate Puzzle"}),e.jsx("button",{onClick:S,className:"control-btn reset-btn",children:"Reset"}),d&&!t&&e.jsx("button",{onClick:A,className:"control-btn reveal-btn",children:"Reveal Solution"})]}),m&&e.jsxs("div",{className:"error-message",children:["Error: ",m]}),i&&e.jsx(H,{}),d&&!i&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"tab-nav",children:[e.jsx("button",{className:`tab-btn ${j==="puzzle"?"active":""}`,onClick:()=>y("puzzle"),children:"Puzzle"}),d.debug&&e.jsx("button",{className:`tab-btn ${j==="debug"?"active":""}`,onClick:()=>y("debug"),children:"Debug"})]}),j==="puzzle"&&e.jsxs("div",{className:"puzzle-layout",children:[e.jsx(U,{grid:d.grid,clues:d.clues,showSolution:t}),e.jsx(q,{clues:d.clues})]}),j==="debug"&&d.debug&&e.jsx(Y,{debugData:d.debug})]}),!d&&!i&&!m&&e.jsx("div",{style:{textAlign:"center",padding:"40px",color:"#7f8c8d"},children:'Select topics and click "Generate Puzzle" to start!'})]})}T.createRoot(document.getElementById("root")).render(e.jsx($.StrictMode,{children:e.jsx(V,{})})); |