jfrery-zama commited on
Commit
cb10dda
·
unverified ·
1 Parent(s): 51280c3

chore: clean

Browse files
Files changed (3) hide show
  1. index.html +3 -3
  2. style.css +0 -28
  3. wasm-demo.js +42 -16
index.html CHANGED
@@ -361,9 +361,9 @@
361
  <!-- Hero -->
362
  <header class="hero" role="banner">
363
  <div class="hero-copy">
364
- <h1>Private Watermark Detection - Check if your text is AI Generated</h1>
365
  <div class="explanation-text">
366
- Private SynthID uses Google's SynthID technology to detect AI-generated text while preserving privacy through Fully Homomorphic Encryption (FHE). This means you can check if text was generated by AI without revealing the content to anyone. Learn more about <a href="https://deepmind.google/science/synthid/" target="_blank">SynthID</a> and <a href="https://www.zama.ai/" target="_blank">FHE applications</a>.
367
  </div>
368
  </div>
369
 
@@ -393,7 +393,7 @@ sequenceDiagram
393
 
394
  <!-- Wizard Steps -->
395
  <main>
396
- <h2 class="section-title">How it works</h2>
397
  <div class="cards-wrapper">
398
  <!-- 1 Keys -->
399
  <section class="card" aria-labelledby="step1">
 
361
  <!-- Hero -->
362
  <header class="hero" role="banner">
363
  <div class="hero-copy">
364
+ <h1>Private Watermark Detection - Check if your text contains watermarks</h1>
365
  <div class="explanation-text">
366
+ Private SynthID uses Google's SynthID technology to detect watermarks in AI-generated text while preserving privacy through Fully Homomorphic Encryption (FHE). This means you can check if text contains AI watermarks without revealing the content to anyone. Note that this only detects watermarked text - not all AI-generated text will be detected. Learn more about <a href="https://deepmind.google/science/synthid/" target="_blank">SynthID</a> and <a href="https://www.zama.ai/" target="_blank">FHE applications</a>.
367
  </div>
368
  </div>
369
 
 
393
 
394
  <!-- Wizard Steps -->
395
  <main>
396
+ <h2 class="section-title">How watermark detection works</h2>
397
  <div class="cards-wrapper">
398
  <!-- 1 Keys -->
399
  <section class="card" aria-labelledby="step1">
style.css DELETED
@@ -1,28 +0,0 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wasm-demo.js CHANGED
@@ -177,20 +177,46 @@ async function pollTaskStatus(currentTaskId, currentUid) {
177
  if (!statusResponse.ok) {
178
  const errorText = await statusResponse.text();
179
  console.error(`[Poll] Error fetching status: ${statusResponse.status} ${errorText}`);
180
- $('srvStatus').textContent = `Status check error: ${statusResponse.status}`;
181
  show('spin', false);
182
  return null;
183
  }
184
 
185
  const statusData = await statusResponse.json();
186
  console.log('[Poll] Task status:', statusData);
187
- $('srvStatus').textContent = `Status: ${statusData.status} - ${statusData.details}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
  if (statusData.status === 'success' || statusData.status === 'completed') {
190
  return statusData;
191
  } else if (['failure', 'revoked', 'unknown', 'error'].includes(statusData.status.toLowerCase())) {
192
  console.error('[Poll] Task failed or unrecoverable:', statusData);
193
- $('srvStatus').textContent = `Task failed: ${statusData.status}`;
194
  show('spin', false);
195
  return null;
196
  } else {
@@ -203,34 +229,35 @@ async function pollTaskStatus(currentTaskId, currentUid) {
203
  }
204
  } catch (e) {
205
  console.error('[Poll] Polling exception:', e);
206
- $('srvStatus').textContent = `Polling error: ${e.message}`;
207
  show('spin', false);
208
  return null;
209
  }
210
  }
211
 
212
  async function getTaskResult(currentTaskId, currentUid, taskName) {
213
- $('srvStatus').textContent = 'Fetching result...';
214
  try {
215
  const resultResponse = await fetch(`${SERVER}/get_task_result?task_name=${taskName}&task_id=${currentTaskId}&uid=${currentUid}`);
216
 
217
  if (!resultResponse.ok) {
218
  const errorText = await resultResponse.text();
219
- throw new Error(`Server /get_task_result error: ${resultResponse.status} ${errorText}`);
220
  }
221
 
222
  const resultArrayBuffer = await resultResponse.arrayBuffer();
223
  encServerResult = new Uint8Array(resultArrayBuffer);
224
 
225
  console.log(`[Main] Received encrypted result: ${encServerResult.length} bytes`);
226
- $('encResult').value = `(${encServerResult.length} B)`;
227
- $('srvStatus').textContent = `✓ result received (${((performance.now() - window.taskStartTime) / 1000).toFixed(2)}s total)`;
 
228
  enable('btnDecrypt');
229
 
230
  } catch (e) {
231
- const duration = window.taskStartTime ? ((performance.now() - window.taskStartTime) / 1000).toFixed(2) : 'N/A';
232
  console.error(`[Main] /get_task_result failed after ${duration}s:`, e);
233
- $('srvStatus').textContent = `Result fetch error: ${e.message} (${duration}s)`;
234
  } finally {
235
  show('spin', false);
236
  $('srvComputing').hidden = true;
@@ -249,8 +276,8 @@ $('btnSend').onclick = async () => {
249
 
250
  show('encIcon', false);
251
  show('spin', true);
252
- $('srvStatus').textContent = 'Submitting task…';
253
- $('srvComputing').hidden = true;
254
  window.taskStartTime = performance.now();
255
 
256
  try {
@@ -269,14 +296,13 @@ $('btnSend').onclick = async () => {
269
 
270
  if (!startTaskResponse.ok) {
271
  const errorText = await startTaskResponse.text();
272
- throw new Error(`Server /start_task error: ${startTaskResponse.status} ${errorText}`);
273
  }
274
 
275
  const { task_id: newTaskId } = await startTaskResponse.json();
276
  taskId = newTaskId;
277
  console.log('[Main] Task submitted to server. Task ID:', taskId);
278
- $('srvStatus').textContent = `Task submitted (ID: ${taskId.substring(0,8)}...). Polling status...`;
279
- $('srvComputing').hidden = false;
280
 
281
  pollTaskStatus(taskId, sessionUid).then(finalStatus => {
282
  if (finalStatus && (finalStatus.status === 'success' || finalStatus.status === 'completed')) {
@@ -287,7 +313,7 @@ $('btnSend').onclick = async () => {
287
  } catch (e) {
288
  const duration = ((performance.now() - window.taskStartTime) / 1000).toFixed(2);
289
  console.error(`[Main] Task submission failed after ${duration}s:`, e);
290
- $('srvStatus').textContent = `Task submission error: ${e.message} (${duration}s)`;
291
  show('spin', false);
292
  $('srvComputing').hidden = true;
293
  }
 
177
  if (!statusResponse.ok) {
178
  const errorText = await statusResponse.text();
179
  console.error(`[Poll] Error fetching status: ${statusResponse.status} ${errorText}`);
180
+ $('srvStatus').textContent = `Error checking status`;
181
  show('spin', false);
182
  return null;
183
  }
184
 
185
  const statusData = await statusResponse.json();
186
  console.log('[Poll] Task status:', statusData);
187
+
188
+ // Parse and display user-friendly status messages
189
+ let userMessage = '';
190
+ let showComputing = false;
191
+
192
+ if (statusData.status === 'queued') {
193
+ // Extract position from details if available
194
+ const positionMatch = statusData.details?.match(/Position:\s*(\d+)\/(\d+)/);
195
+ if (positionMatch) {
196
+ const [, position, total] = positionMatch;
197
+ userMessage = `Waiting in queue (${position} of ${total})`;
198
+ } else {
199
+ userMessage = 'Waiting in queue...';
200
+ }
201
+ } else if (statusData.status === 'processing' || statusData.status === 'running') {
202
+ userMessage = 'Processing your request...';
203
+ showComputing = true;
204
+ } else if (statusData.status === 'success' || statusData.status === 'completed') {
205
+ userMessage = 'Processing complete!';
206
+ } else if (['failure', 'revoked', 'unknown', 'error'].includes(statusData.status.toLowerCase())) {
207
+ userMessage = 'Task failed. Please try again.';
208
+ } else {
209
+ // Fallback for any other status
210
+ userMessage = `Status: ${statusData.status}`;
211
+ }
212
+
213
+ $('srvStatus').textContent = userMessage;
214
+ $('srvComputing').hidden = !showComputing;
215
 
216
  if (statusData.status === 'success' || statusData.status === 'completed') {
217
  return statusData;
218
  } else if (['failure', 'revoked', 'unknown', 'error'].includes(statusData.status.toLowerCase())) {
219
  console.error('[Poll] Task failed or unrecoverable:', statusData);
 
220
  show('spin', false);
221
  return null;
222
  } else {
 
229
  }
230
  } catch (e) {
231
  console.error('[Poll] Polling exception:', e);
232
+ $('srvStatus').textContent = 'Connection error. Please check your network.';
233
  show('spin', false);
234
  return null;
235
  }
236
  }
237
 
238
  async function getTaskResult(currentTaskId, currentUid, taskName) {
239
+ $('srvStatus').textContent = 'Retrieving results...';
240
  try {
241
  const resultResponse = await fetch(`${SERVER}/get_task_result?task_name=${taskName}&task_id=${currentTaskId}&uid=${currentUid}`);
242
 
243
  if (!resultResponse.ok) {
244
  const errorText = await resultResponse.text();
245
+ throw new Error(`Failed to get results`);
246
  }
247
 
248
  const resultArrayBuffer = await resultResponse.arrayBuffer();
249
  encServerResult = new Uint8Array(resultArrayBuffer);
250
 
251
  console.log(`[Main] Received encrypted result: ${encServerResult.length} bytes`);
252
+ $('encResult').value = `Encrypted result (${encServerResult.length} bytes)`;
253
+ const duration = ((performance.now() - window.taskStartTime) / 1000).toFixed(1);
254
+ $('srvStatus').textContent = `✓ Complete! (${duration}s)`;
255
  enable('btnDecrypt');
256
 
257
  } catch (e) {
258
+ const duration = window.taskStartTime ? ((performance.now() - window.taskStartTime) / 1000).toFixed(1) : 'N/A';
259
  console.error(`[Main] /get_task_result failed after ${duration}s:`, e);
260
+ $('srvStatus').textContent = 'Failed to retrieve results. Please try again.';
261
  } finally {
262
  show('spin', false);
263
  $('srvComputing').hidden = true;
 
276
 
277
  show('encIcon', false);
278
  show('spin', true);
279
+ $('srvStatus').textContent = 'Sending encrypted data...';
280
+ $('srvComputing').hidden = true; // Ensure it's hidden initially
281
  window.taskStartTime = performance.now();
282
 
283
  try {
 
296
 
297
  if (!startTaskResponse.ok) {
298
  const errorText = await startTaskResponse.text();
299
+ throw new Error(`Server error: ${startTaskResponse.status}`);
300
  }
301
 
302
  const { task_id: newTaskId } = await startTaskResponse.json();
303
  taskId = newTaskId;
304
  console.log('[Main] Task submitted to server. Task ID:', taskId);
305
+ $('srvStatus').textContent = 'Request submitted. Checking status...';
 
306
 
307
  pollTaskStatus(taskId, sessionUid).then(finalStatus => {
308
  if (finalStatus && (finalStatus.status === 'success' || finalStatus.status === 'completed')) {
 
313
  } catch (e) {
314
  const duration = ((performance.now() - window.taskStartTime) / 1000).toFixed(2);
315
  console.error(`[Main] Task submission failed after ${duration}s:`, e);
316
+ $('srvStatus').textContent = 'Failed to submit request. Please try again.';
317
  show('spin', false);
318
  $('srvComputing').hidden = true;
319
  }