| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| <title>Arabic PDF Reader</title> |
| <link rel="stylesheet" href="/static/styles.css?v=20260607-recommended-labels" /> |
| </head> |
| <body> |
| <main class="app-shell"> |
| <section class="topbar"> |
| <div> |
| <p class="eyebrow">Arabic audio reader</p> |
| <h1>Arabic PDF Reader</h1> |
| </div> |
| <button id="logoutButton" class="quiet-button hidden" type="button" aria-label="Log out" title="Log out"> |
| <span aria-hidden="true">←</span> |
| <span>Log out</span> |
| </button> |
| </section> |
|
|
| <section id="loginPanel" class="panel login-panel"> |
| <div class="panel-heading"> |
| <span class="step-mark" aria-hidden="true">1</span> |
| <div> |
| <p class="eyebrow">Private access</p> |
| <h2>Enter your code</h2> |
| </div> |
| </div> |
| <form id="loginForm" class="stack"> |
| <label for="codeInput">Access code</label> |
| <div class="inline"> |
| <input id="codeInput" name="code" type="password" autocomplete="current-password" required /> |
| <button type="submit"> |
| <span aria-hidden="true">OK</span> |
| <span>Unlock</span> |
| </button> |
| </div> |
| <p id="loginError" class="error" role="alert"></p> |
| </form> |
| </section> |
|
|
| <section id="workspace" class="workspace hidden"> |
| <section class="panel upload-panel"> |
| <div class="panel-heading"> |
| <span class="step-mark" aria-hidden="true">2</span> |
| <div> |
| <p class="eyebrow">Choose document</p> |
| <h2>Upload Arabic PDF</h2> |
| </div> |
| </div> |
| <div id="engineNotice" class="engine-notice" role="status"> |
| Checking voice. |
| </div> |
| <div class="field-group"> |
| <label for="voiceSelect">Voice</label> |
| <select id="voiceSelect" name="voice"></select> |
| </div> |
| <div class="field-group"> |
| <label for="speedSelect">Speed</label> |
| <select id="speedSelect" name="speed"> |
| <option value="1">Normal</option> |
| <option value="1.15">Faster</option> |
| <option value="0.9">Slower</option> |
| </select> |
| </div> |
| <div class="field-group"> |
| <label for="ocrModeSelect">Text quality</label> |
| <select id="ocrModeSelect" name="ocrMode"> |
| <option value="tesseract">1. Tesseract Arabic - Best readable</option> |
| <option value="tesseract-fast">2. Tesseract Arabic - Faster readable</option> |
| <option value="paddleocr">3. PaddleOCR Arabic - Faster fallback</option> |
| <option value="arabic">Arabic OCR comparison - slower</option> |
| <option value="arabic-max">Maximum Arabic OCR - slower</option> |
| <option value="qari-ocr">QARI Arabic books (best)</option> |
| <option value="tawkeed-ocr">Tawkeed Arabic OCR</option> |
| <option value="katib-ocr">KATIB Arabic OCR (lighter)</option> |
| <option value="arabic-qwen-ocr">Arabic-Qwen OCR</option> |
| <option value="arabic-glm-ocr">Arabic-GLM OCR v2</option> |
| <option value="baseer-ocr">Baseer Arabic OCR</option> |
| <option value="best">Best scan test</option> |
| <option value="paddleocr-vl">PaddleOCR-VL heavy</option> |
| <option value="surya">Surya heavy OCR</option> |
| <option value="easyocr">General Arabic OCR</option> |
| <option value="auto">Auto fallback</option> |
| </select> |
| </div> |
| <div class="field-group"> |
| <label for="pageLimitSelect">Pages</label> |
| <select id="pageLimitSelect" name="pageLimit"> |
| <option value="5">Quick test</option> |
| <option value="0">Full book</option> |
| <option value="10">Longer test</option> |
| </select> |
| </div> |
| <form id="uploadForm" class="dropzone"> |
| <input id="pdfInput" name="pdf" type="file" accept="application/pdf,.pdf" required /> |
| <label for="pdfInput"> |
| <span class="file-icon" aria-hidden="true">PDF</span> |
| <span class="drop-title">Choose PDF</span> |
| <span id="fileName">No file selected</span> |
| </label> |
| <button id="createButton" type="submit"> |
| <span aria-hidden="true">Play</span> |
| <span>Create Audio</span> |
| </button> |
| </form> |
| <p id="uploadError" class="error" role="alert"></p> |
| </section> |
|
|
| <section class="panel status-panel"> |
| <div class="status-header"> |
| <div> |
| <p class="eyebrow">Listen</p> |
| <h2 id="jobTitle">Ready when you are</h2> |
| </div> |
| <span id="jobState" class="badge">Idle</span> |
| </div> |
| <div class="progress-summary"> |
| <span id="stageLabel">Waiting</span> |
| <span id="progressPercent">0%</span> |
| </div> |
| <div class="meter" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"> |
| <span id="progressBar"></span> |
| </div> |
| <div class="stage-detail" aria-live="polite"> |
| <span id="stagePhaseLabel">Current step</span> |
| <strong id="stageDetailTitle">Waiting</strong> |
| <small id="stageDetailText">Choose a PDF, then create the audio.</small> |
| <div id="stageItemProgress" class="stage-item-progress hidden"> |
| <div> |
| <span id="stageItemLabel">Progress</span> |
| <strong id="stageItemValue">0 of 0</strong> |
| </div> |
| <div class="stage-item-meter" aria-hidden="true"><span id="stageItemBar"></span></div> |
| </div> |
| <small id="stageMetaText" class="stage-meta">Waiting for a PDF.</small> |
| </div> |
| <ol id="stageList" class="stage-list" aria-label="Job steps"></ol> |
| <p id="jobMessage">Choose a PDF, then create the audio.</p> |
| <p id="qualityHint" class="quality-hint hidden"></p> |
| <dl class="stats"> |
| <div><dt>Pages</dt><dd id="pagesValue">0</dd></div> |
| <div><dt>Characters</dt><dd id="charactersValue">0</dd></div> |
| <div><dt>Engine</dt><dd id="engineValue">-</dd></div> |
| <div><dt>Text</dt><dd id="extractionValue">-</dd></div> |
| <div><dt>Quality</dt><dd id="qualityValue">-</dd></div> |
| <div><dt>Audio</dt><dd id="audioFormatValue">-</dd></div> |
| </dl> |
| <div id="audioPanel" class="audio-panel hidden"> |
| <audio id="audioPlayer" controls></audio> |
| <a id="downloadLink" class="download-button" href="#"> |
| <span aria-hidden="true">Save</span> |
| <span>Download Audio</span> |
| </a> |
| </div> |
| <div id="browserSpeechPanel" class="browser-speech-panel hidden"> |
| <p id="browserSpeechMessage">Browser read-aloud is ready.</p> |
| <div class="browser-speech-actions"> |
| <button id="browserSpeakButton" type="button"> |
| <span aria-hidden="true">Play</span> |
| <span>Read aloud</span> |
| </button> |
| <button id="browserStopButton" class="quiet-button" type="button">Stop</button> |
| </div> |
| </div> |
| <section id="historyPanel" class="history-panel hidden" aria-live="polite"> |
| <h3>Recent audio</h3> |
| <ul id="historyList"></ul> |
| </section> |
| </section> |
| </section> |
| </main> |
| <script type="module" src="/static/app.js?v=20260607-recommended-labels"></script> |
| </body> |
| </html> |
|
|