saliseabeali commited on
Commit
c1bb16b
·
verified ·
1 Parent(s): d1be5b0

Upload script.js

Browse files
Files changed (1) hide show
  1. script.js +774 -0
script.js ADDED
@@ -0,0 +1,774 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const promptInput = document.getElementById('promptInput');
2
+ const negativePromptInput = document.getElementById('negativePromptInput');
3
+ const seedInput = document.getElementById('seedInput');
4
+ const styleSelect = document.getElementById('styleSelect');
5
+ const renderQualitySelect = document.getElementById('renderQualitySelect');
6
+ const lightingSelect = document.getElementById('lightingSelect');
7
+ const controlNetSelect = document.getElementById('controlNetSelect');
8
+ const anatomyControlSelect = document.getElementById('anatomyControlSelect');
9
+ const generateButton = document.getElementById('generateButton');
10
+ const generatedImage = document.getElementById('generatedImage');
11
+ const loadingIndicator = document.getElementById('loading');
12
+ const technicalExplanation = document.querySelector('.technical-explanation');
13
+
14
+ // Prompt Enhancer Module
15
+ const promptEnhancerModule = {
16
+ enhancements: {
17
+ "a cat": "a photorealistic fluffy white cat sitting on a windowsill, soft light, shallow depth of field, 4k resolution",
18
+ "a fox": "a majestic red fox standing in a misty forest, golden hour lighting, detailed fur, realistic anatomy, 8k resolution",
19
+ "a landscape": "a breathtaking mountain landscape with vibrant colors, sunrise lighting, crisp details, epic panoramic view, high resolution"
20
+ },
21
+
22
+ enhance: async function(originalPrompt) {
23
+ // First, use the new advanced prompt engineering module
24
+ const semanticAnalysis = await promptEngineeringModule.analyzeAndCorrectPrompt(originalPrompt);
25
+
26
+ // Then enhance with style and quality details
27
+ const enhancedPrompt = promptEngineeringModule.enhancePrompt(semanticAnalysis, {
28
+ style: styleSelect.value,
29
+ renderQuality: renderQualitySelect.value,
30
+ lighting: lightingSelect.value
31
+ });
32
+
33
+ return enhancedPrompt;
34
+ }
35
+ };
36
+
37
+ // Advanced Prompt Engineering Module
38
+ const promptEngineeringModule = {
39
+ // Enhanced prompt generation with more specific details
40
+ enhancePrompt: function(originalPrompt, options = {}) {
41
+ const {
42
+ style = 'default',
43
+ renderQuality = 'standard',
44
+ lighting = 'default',
45
+ detailLevel = 'high'
46
+ } = options;
47
+
48
+ const styleMap = {
49
+ 'default': '',
50
+ 'photorealistic': 'photorealistic, high detail, sharp focus',
51
+ 'anime': 'anime style, clean lines, vibrant colors',
52
+ 'digital-art': 'digital art, crisp edges, stylized',
53
+ 'studio-ghibli': 'Studio Ghibli style, soft colors, whimsical',
54
+ 'oil-painting': 'oil painting texture, rich brush strokes',
55
+ 'realistic': 'hyper-realistic, ultra-detailed',
56
+ 'dreamscape': 'surreal, dreamy, soft focus'
57
+ };
58
+
59
+ const lightingMap = {
60
+ 'default': '',
61
+ 'cinematic': 'cinematic lighting, dramatic shadows',
62
+ 'soft': 'soft, diffused light, gentle shadows',
63
+ 'dramatic': 'high contrast, strong directional light',
64
+ 'sunset': 'golden hour, warm tones, long shadows'
65
+ };
66
+
67
+ const qualityMap = {
68
+ 'standard': '512x512 resolution',
69
+ 'high': '768x768 resolution, enhanced details',
70
+ 'ultra': '1024x1024 resolution, maximum detail',
71
+ '4k': '2048x2048 resolution, ultra high quality'
72
+ };
73
+
74
+ const detailLevelMap = {
75
+ 'low': 'basic shapes, minimal detail',
76
+ 'medium': 'clear definition, moderate detail',
77
+ 'high': 'intricate details, sharp edges, textural complexity'
78
+ };
79
+
80
+ // Combine enhanced prompt with style and quality specifications
81
+ const enhancedPrompt = [
82
+ originalPrompt,
83
+ styleMap[style],
84
+ lightingMap[lighting],
85
+ qualityMap[renderQuality],
86
+ `${detailLevelMap[detailLevel]}, precise composition`
87
+ ].filter(Boolean).join(', ');
88
+
89
+ return enhancedPrompt;
90
+ },
91
+
92
+ // Advanced semantic analysis and prompt correction
93
+ analyzeAndCorrectPrompt: async function(prompt) {
94
+ try {
95
+ const completion = await websim.chat.completions.create({
96
+ messages: [
97
+ {
98
+ role: "system",
99
+ content: `You are an expert prompt engineer for AI image generation.
100
+ Analyze the given prompt and:
101
+ 1. Improve clarity and specificity
102
+ 2. Add missing descriptive details
103
+ 3. Ensure semantic consistency
104
+ 4. Optimize for better image generation`
105
+ },
106
+ {
107
+ role: "user",
108
+ content: prompt
109
+ }
110
+ ]
111
+ });
112
+
113
+ return completion.content || prompt;
114
+ } catch (error) {
115
+ console.warn("Prompt analysis fallback triggered:", error);
116
+ return prompt;
117
+ }
118
+ }
119
+ };
120
+
121
+ // Semantic Consistency Check Module
122
+ const semanticConsistencyModule = {
123
+ checks: [
124
+ {
125
+ name: "Anatomical Consistency",
126
+ check: async (prompt, imageUrl) => {
127
+ try {
128
+ const result = await websim.chat.completions.create({
129
+ messages: [
130
+ {
131
+ role: "system",
132
+ content: "Analyze the image for anatomical correctness based on the prompt. Report any inconsistencies concisely."
133
+ },
134
+ {
135
+ role: "user",
136
+ content: [
137
+ { type: "text", text: `Check anatomical correctness for prompt: ${prompt}` },
138
+ { type: "image_url", image_url: { url: imageUrl } }
139
+ ]
140
+ }
141
+ ]
142
+ });
143
+ return `Anatomical Check: ${result.content}`;
144
+ } catch (error) {
145
+ console.error("Anatomical consistency check failed:", error);
146
+ return `Anatomical Check: Error performing check - ${error.message}`;
147
+ }
148
+ }
149
+ },
150
+ {
151
+ name: "Prompt Adherence Check",
152
+ check: async (prompt, imageUrl) => {
153
+ try {
154
+ const result = await websim.chat.completions.create({
155
+ messages: [
156
+ {
157
+ role: "system",
158
+ content: "Compare the image against the provided prompt. Summarize how well the image matches the key elements of the prompt."
159
+ },
160
+ {
161
+ role: "user",
162
+ content: [
163
+ { type: "text", text: `Check adherence to prompt: ${prompt}` },
164
+ { type: "image_url", image_url: { url: imageUrl } }
165
+ ]
166
+ }
167
+ ]
168
+ });
169
+ return `Prompt Adherence: ${result.content}`;
170
+ } catch (error) {
171
+ console.error("Prompt adherence check failed:", error);
172
+ return `Prompt Adherence: Error performing check - ${error.message}`;
173
+ }
174
+ }
175
+ },
176
+ {
177
+ name: "Negative Prompt Check",
178
+ check: async (prompt, negativePrompt, imageUrl) => {
179
+ if (!negativePrompt || negativePrompt.trim() === '') {
180
+ return "Negative Prompt Check: No negative prompt provided.";
181
+ }
182
+ try {
183
+ const result = await websim.chat.completions.create({
184
+ messages: [
185
+ {
186
+ role: "system",
187
+ content: "Analyze the image to see if it contains elements explicitly mentioned in the negative prompt."
188
+ },
189
+ {
190
+ role: "user",
191
+ content: [
192
+ { type: "text", text: `Check negative prompt: ${prompt} with negative prompt: ${negativePrompt}` },
193
+ { type: "image_url", image_url: { url: imageUrl } }
194
+ ]
195
+ }
196
+ ]
197
+ });
198
+ return `Negative Prompt Check: ${result.content}`;
199
+ } catch (error) {
200
+ console.error("Negative prompt check failed:", error);
201
+ return `Negative Prompt Check: Error performing check - ${error.message}`;
202
+ }
203
+ }
204
+ }
205
+ ],
206
+
207
+ performChecks: async function(prompt, negativePrompt, imageUrl) {
208
+ const results = [];
209
+ // Clear previous results while checks are running
210
+ const semanticCheckList = document.getElementById('semanticCheckList');
211
+ if (semanticCheckList) {
212
+ semanticCheckList.innerHTML = '<li>Running semantic checks...</li>';
213
+ }
214
+
215
+ for (let check of this.checks) {
216
+ let checkResult;
217
+ if (check.name === "Negative Prompt Check") {
218
+ checkResult = await check.check(prompt, negativePrompt, imageUrl);
219
+ } else {
220
+ checkResult = await check.check(prompt, imageUrl);
221
+ }
222
+ results.push(checkResult);
223
+ }
224
+ return results;
225
+ }
226
+ };
227
+
228
+ // Layered Generation Module (basic placeholder)
229
+ const layeredGenerationModule = {
230
+ generateLayered: async function(prompt) {
231
+ // Placeholder for future implementation
232
+ console.log("Layered generation for:", prompt);
233
+ return null;
234
+ }
235
+ };
236
+
237
+ const styleMap = {
238
+ 'default': {
239
+ prompt_prefix: '',
240
+ model: 'stable-diffusion-xl',
241
+ sampler: 'Euler a'
242
+ },
243
+ 'photorealistic': {
244
+ prompt_prefix: 'highly detailed photorealistic, sharp focus, natural lighting',
245
+ model: 'realistic-vision-v5',
246
+ sampler: 'DPM++ 2M Karras'
247
+ },
248
+ 'anime': {
249
+ prompt_prefix: 'anime style, clean lines, vibrant colors, sharp details, kyoto animation aesthetic',
250
+ model: 'deliberate-v2',
251
+ sampler: 'Euler a'
252
+ },
253
+ 'digital-art': {
254
+ prompt_prefix: 'digital illustration, crisp edges, stylized, graphic novel aesthetic, high contrast',
255
+ model: 'dreamshaper-v8',
256
+ sampler: 'DDIM'
257
+ },
258
+ 'studio-ghibli': {
259
+ prompt_prefix: 'Studio Ghibli style, soft color palette, whimsical, hand-drawn texture, Miyazaki-inspired',
260
+ model: 'ghibli-diffusion',
261
+ sampler: 'Euler'
262
+ },
263
+ 'oil-painting': {
264
+ prompt_prefix: 'oil painting texture, rich brush strokes, impasto technique, canvas-like rendering',
265
+ model: 'anything-v5',
266
+ sampler: 'DPM++ SDE Karras'
267
+ },
268
+ 'realistic': {
269
+ prompt_prefix: 'ultra-realistic, hyper-detailed, natural textures, precise anatomical accuracy',
270
+ model: 'realistic-vision-v5',
271
+ sampler: 'DPM++ 2M Karras'
272
+ },
273
+ 'dreamscape': {
274
+ prompt_prefix: 'surreal, dreamy atmosphere, soft focus, ethereal lighting, blended reality',
275
+ model: 'stable-diffusion-xl',
276
+ sampler: 'Euler a'
277
+ }
278
+ };
279
+
280
+ function mapRenderQuality(quality) {
281
+ const qualityMap = {
282
+ "standard": {
283
+ width: 512,
284
+ height: 512,
285
+ description: "Standard Quality (512x512)"
286
+ },
287
+ "high": {
288
+ width: 768,
289
+ height: 768,
290
+ description: "High Quality (768x768)"
291
+ },
292
+ "ultra": {
293
+ width: 1024,
294
+ height: 1024,
295
+ description: "Ultra HD (1024x1024)"
296
+ },
297
+ "4k": {
298
+ width: 2048,
299
+ height: 2048,
300
+ description: "4K Ultra-Detailed (2048x2048)"
301
+ }
302
+ };
303
+ return qualityMap[quality] || qualityMap["standard"];
304
+ }
305
+
306
+ // Advanced Face Generation Module
307
+ const faceGenerationModule = {
308
+ // Advanced prompt engineering for high-quality face generation
309
+ enhanceFacePrompt: function(basePrompt, options = {}) {
310
+ const {
311
+ faceQuality = 'high',
312
+ symmetry = true,
313
+ style = 'photorealistic'
314
+ } = options;
315
+
316
+ const qualityPrefixes = {
317
+ 'low': 'basic face details',
318
+ 'medium': 'clear facial features, moderate detail',
319
+ 'high': 'perfect symmetrical face, high resolution, soft studio lighting, crisp details',
320
+ 'ultra': 'hyper-realistic face, professional DSLR photo quality, cinematic lighting, intricate skin texture'
321
+ };
322
+
323
+ const stylePrefixes = {
324
+ 'photorealistic': 'DSLR photo style, natural skin tones, precise facial structure',
325
+ 'anime': 'anime style, clean lines, large expressive eyes',
326
+ 'artistic': 'stylized face, painterly details, soft color palette',
327
+ 'sketch': 'pencil sketch style, delicate line work'
328
+ };
329
+
330
+ const symmetryPrefix = symmetry ? 'perfectly symmetrical, ' : '';
331
+
332
+ const enhancedPrompt = [
333
+ basePrompt,
334
+ symmetryPrefix,
335
+ qualityPrefixes[faceQuality],
336
+ stylePrefixes[style]
337
+ ].filter(Boolean).join(', ');
338
+
339
+ return enhancedPrompt;
340
+ },
341
+
342
+ // Advanced face correction using AI techniques
343
+ correctFace: async function(imageUrl) {
344
+ try {
345
+ // Simulate using GFPGAN or CodeFormer for face enhancement
346
+ const result = await websim.chat.completions.create({
347
+ messages: [
348
+ {
349
+ role: "system",
350
+ content: "Analyze and correct facial details in the image. Improve symmetry, skin texture, and overall facial structure. Provide a URL to the corrected image or indicate if no correction was needed."
351
+ },
352
+ {
353
+ role: "user",
354
+ content: [
355
+ { type: "text", text: "Enhance facial details" },
356
+ { type: "image_url", image_url: { url: imageUrl } }
357
+ ]
358
+ }
359
+ ]
360
+ });
361
+
362
+ try {
363
+ const response = JSON.parse(result.content);
364
+ if (response && response.url) {
365
+ console.log("Face correction applied. New image URL:", response.url);
366
+ return response.url;
367
+ } else {
368
+ console.log("Face correction analysis:", result.content);
369
+ return imageUrl;
370
+ }
371
+ } catch (e) {
372
+ console.log("Face correction analysis (non-JSON response):", result.content);
373
+ return imageUrl;
374
+ }
375
+
376
+ } catch (error) {
377
+ console.error("Face correction failed:", error);
378
+ return null;
379
+ }
380
+ },
381
+
382
+ // Advanced semantic face analysis
383
+ analyzeFace: async function(imageUrl) {
384
+ try {
385
+ const result = await websim.chat.completions.create({
386
+ messages: [
387
+ {
388
+ role: "system",
389
+ content: `Perform comprehensive face analysis:
390
+ 1. Check facial symmetry
391
+ 2. Verify anatomical correctness
392
+ 3. Assess style adherence
393
+ 4. Detect any artifacts or inconsistencies
394
+ 5. Provide a concise summary.`
395
+ },
396
+ {
397
+ role: "user",
398
+ content: [
399
+ { type: "text", text: "Analyze face in image" },
400
+ { type: "image_url", image_url: { url: imageUrl } }
401
+ ]
402
+ }
403
+ ]
404
+ });
405
+
406
+ return result.content;
407
+ } catch (error) {
408
+ console.error("Face analysis failed:", error);
409
+ return null;
410
+ }
411
+ }
412
+ };
413
+
414
+ async function generateImage(prompt, options = {}) {
415
+ const {
416
+ negativePrompt = '',
417
+ seed,
418
+ style = 'default',
419
+ renderQuality = 'standard',
420
+ lighting,
421
+ controlNetMode,
422
+ faceQuality,
423
+ faceStyle,
424
+ symmetry,
425
+ perspective,
426
+ objectPlacement,
427
+ lightSource,
428
+ depthPerception,
429
+ cfgScale,
430
+ steps
431
+ } = options;
432
+
433
+ // Get style-specific configuration
434
+ const styleConfig = styleMap[style] || styleMap['default'];
435
+
436
+ // Combine style-specific prefix with original prompt
437
+ let enhancedPrompt = `${styleConfig.prompt_prefix}, ${prompt}`;
438
+
439
+ // If face generation is detected, enhance the prompt
440
+ const isFacePrompt = prompt.toLowerCase().includes('face') ||
441
+ prompt.toLowerCase().includes('portrait');
442
+
443
+ if (isFacePrompt) {
444
+ enhancedPrompt = faceGenerationModule.enhanceFacePrompt(enhancedPrompt, {
445
+ faceQuality: faceQuality || 'high',
446
+ symmetry: symmetry !== false,
447
+ style: faceStyle || 'photorealistic'
448
+ });
449
+ }
450
+
451
+ // Enhanced Perspective Mapping
452
+ const perspectiveMap = {
453
+ 'front-view': 'viewed straight on, front perspective',
454
+ 'side-view': 'side angle view, profile perspective',
455
+ 'overhead': 'viewed from above, overhead perspective',
456
+ 'diagonal': 'diagonal angle, dynamic perspective',
457
+ 'tilted-view': 'slightly tilted view, subtle angle'
458
+ };
459
+
460
+ const objectPlacementMap = {
461
+ 'balanced': 'balanced composition, symmetric arrangement',
462
+ 'asymmetric': 'asymmetric layout, dynamic positioning',
463
+ 'rule-of-thirds': 'following rule of thirds, strategic placement',
464
+ 'centered': 'centered focal point, symmetrical design'
465
+ };
466
+
467
+ const lightSourceMap = {
468
+ 'left-side': 'light source from left side, creating defined shadows',
469
+ 'right-side': 'light source from right side, dramatic shadowing',
470
+ 'top-down': 'overhead lighting, creating vertical shadows',
471
+ 'diagonal': 'diagonal light, creating depth and dimension',
472
+ 'backlighting': 'backlight effect, silhouette and rim lighting',
473
+ 'soft-ambient': 'soft, diffused ambient lighting'
474
+ };
475
+
476
+ const depthPerceptionMap = {
477
+ 'shallow-depth': 'shallow depth of field, soft background blur',
478
+ 'deep-depth': 'deep depth of field, entire scene in focus',
479
+ 'layered-focus': 'layered focus, multiple depth levels',
480
+ 'foreground-emphasis': 'foreground elements sharply focused'
481
+ };
482
+
483
+ // Enhance prompt with perspective and composition details
484
+ if (perspective) {
485
+ enhancedPrompt += `, ${perspectiveMap[perspective]}`;
486
+ }
487
+
488
+ if (objectPlacement) {
489
+ enhancedPrompt += `, ${objectPlacementMap[objectPlacement]}`;
490
+ }
491
+
492
+ if (lightSource) {
493
+ enhancedPrompt += `, ${lightSourceMap[lightSource]}`;
494
+ }
495
+
496
+ if (depthPerception) {
497
+ enhancedPrompt += `, ${depthPerceptionMap[depthPerception]}`;
498
+ }
499
+
500
+ // Use the enhanced mapRenderQuality function
501
+ const qualitySettings = mapRenderQuality(renderQuality);
502
+
503
+ try {
504
+ const result = await websim.imageGen({
505
+ prompt: enhancedPrompt,
506
+ negative_prompt: getCombinedNegativePrompt(negativePrompt),
507
+ seed: seed,
508
+ style: style === 'default' ? undefined : style,
509
+ width: qualitySettings.width,
510
+ height: qualitySettings.height,
511
+ lighting: lighting === 'default' ? undefined : lighting,
512
+ controlnet_mode: controlNetMode === 'none' ? undefined : controlNetMode,
513
+ sampler: styleConfig.sampler,
514
+ model: styleConfig.model,
515
+ cfg_scale: cfgScale,
516
+ steps: steps,
517
+ perspective: perspective,
518
+ object_placement: objectPlacement,
519
+ light_source: lightSource,
520
+ depth_perception: depthPerception
521
+ });
522
+
523
+ console.log(`Generating image with ${qualitySettings.description}`);
524
+
525
+ // Post-generation face correction
526
+ if (isFacePrompt && result.url) {
527
+ const correctedImageUrl = await faceGenerationModule.correctFace(result.url);
528
+ result.url = correctedImageUrl || result.url;
529
+
530
+ // Optional face analysis
531
+ const faceAnalysis = await faceGenerationModule.analyzeFace(result.url);
532
+ console.log("Face Analysis:", faceAnalysis);
533
+ }
534
+
535
+ return result;
536
+ } catch (error) {
537
+ console.error("Advanced Image Generation Error:", error);
538
+ throw error;
539
+ }
540
+ }
541
+
542
+ function getCombinedNegativePrompt(userNegativePrompt) {
543
+ const baseAnatomyPreventionPrompts = [
544
+ "deformed anatomy",
545
+ "extra limbs",
546
+ "duplicate body parts",
547
+ "unnatural proportions",
548
+ "malformed features",
549
+ "unrealistic anatomy",
550
+ "missing limbs",
551
+ "mutated",
552
+ "twisted",
553
+ "bad eyes",
554
+ "extra fingers",
555
+ "missing fingers"
556
+ ];
557
+
558
+ const baseQualityPreventions = [
559
+ "low quality",
560
+ "blurry",
561
+ "watermark",
562
+ "text",
563
+ "disfigured",
564
+ "ugly",
565
+ "nonsensical",
566
+ "bad composition",
567
+ "poorly drawn",
568
+ "sketch",
569
+ "noise",
570
+ "grainy"
571
+ ];
572
+
573
+ const textSpecificPreventions = [
574
+ "unreadable text",
575
+ "gibberish",
576
+ "nonsense text",
577
+ "broken letters",
578
+ "random symbols"
579
+ ];
580
+
581
+ let combinedPrompts = [...baseAnatomyPreventionPrompts, ...baseQualityPreventions, ...textSpecificPreventions];
582
+
583
+ if (userNegativePrompt) {
584
+ combinedPrompts = combinedPrompts.concat(userNegativePrompt.split(',').map(p => p.trim()));
585
+ }
586
+
587
+ const uniquePrompts = [...new Set(combinedPrompts)].filter(p => p !== '');
588
+
589
+ return uniquePrompts.join(", ");
590
+ }
591
+
592
+ async function performSemanticChecks(prompt, imageUrl) {
593
+ const semanticCheckList = document.getElementById('semanticCheckList');
594
+ semanticCheckList.innerHTML = '<li>Running advanced semantic checks...</li>';
595
+
596
+ try {
597
+ const result = await websim.chat.completions.create({
598
+ messages: [
599
+ {
600
+ role: "system",
601
+ content: `Perform a comprehensive semantic analysis of the image:
602
+ 1. Check anatomical correctness
603
+ 2. Verify prompt adherence
604
+ 3. Detect any inconsistencies or artifacts
605
+ 4. Suggest potential improvements`
606
+ },
607
+ {
608
+ role: "user",
609
+ content: [
610
+ { type: "text", text: `Analyze image generated from prompt: ${prompt}` },
611
+ { type: "image_url", image_url: { url: imageUrl } }
612
+ ]
613
+ }
614
+ ]
615
+ });
616
+
617
+ semanticCheckList.innerHTML = result.content
618
+ .split('\n')
619
+ .map(line => `<li>${line}</li>`)
620
+ .join('');
621
+ } catch (error) {
622
+ console.error("Advanced Semantic Check Failed:", error);
623
+ semanticCheckList.innerHTML = `<li>Advanced semantic check failed: ${error.message}</li>`;
624
+ }
625
+ }
626
+
627
+ const faceQualitySelect = document.createElement('select');
628
+ faceQualitySelect.id = 'faceQualitySelect';
629
+ faceQualitySelect.innerHTML = `
630
+ <option value="low">Basic Quality</option>
631
+ <option value="medium">Medium Quality</option>
632
+ <option value="high" selected>High Quality</option>
633
+ <option value="ultra">Ultra Quality</option>
634
+ `;
635
+
636
+ const faceStyleSelect = document.createElement('select');
637
+ faceStyleSelect.id = 'faceStyleSelect';
638
+ faceStyleSelect.innerHTML = `
639
+ <option value="photorealistic" selected>Photorealistic</option>
640
+ <option value="anime">Anime Style</option>
641
+ <option value="artistic">Artistic</option>
642
+ <option value="sketch">Sketch Style</option>
643
+ `;
644
+
645
+ const perspectiveSelect = document.createElement('select');
646
+ perspectiveSelect.id = 'perspectiveSelect';
647
+ perspectiveSelect.innerHTML = `
648
+ <option value="front-view">Front View</option>
649
+ <option value="side-view">Side View</option>
650
+ <option value="overhead">Overhead View</option>
651
+ <option value="diagonal">Diagonal View</option>
652
+ <option value="tilted-view">Tilted View</option>
653
+ `;
654
+
655
+ const objectPlacementSelect = document.createElement('select');
656
+ objectPlacementSelect.id = 'objectPlacementSelect';
657
+ objectPlacementSelect.innerHTML = `
658
+ <option value="balanced">Balanced Composition</option>
659
+ <option value="asymmetric">Asymmetric Layout</option>
660
+ <option value="rule-of-thirds">Rule of Thirds</option>
661
+ <option value="centered">Centered Focal Point</option>
662
+ `;
663
+
664
+ const lightSourceSelect = document.createElement('select');
665
+ lightSourceSelect.id = 'lightSourceSelect';
666
+ lightSourceSelect.innerHTML = `
667
+ <option value="left-side">Left Side Lighting</option>
668
+ <option value="right-side">Right Side Lighting</option>
669
+ <option value="top-down">Top-Down Lighting</option>
670
+ <option value="diagonal">Diagonal Lighting</option>
671
+ <option value="backlighting">Backlighting</option>
672
+ <option value="soft-ambient">Soft Ambient Lighting</option>
673
+ `;
674
+
675
+ const depthPerceptionSelect = document.createElement('select');
676
+ depthPerceptionSelect.id = 'depthPerceptionSelect';
677
+ depthPerceptionSelect.innerHTML = `
678
+ <option value="shallow-depth">Shallow Depth of Field</option>
679
+ <option value="deep-depth">Deep Depth of Field</option>
680
+ <option value="layered-focus">Layered Focus</option>
681
+ <option value="foreground-emphasis">Foreground Emphasis</option>
682
+ `;
683
+
684
+ document.querySelector('.style-grid').appendChild(
685
+ createControlGroup('🖼️ Face Quality:', faceQualitySelect)
686
+ );
687
+ document.querySelector('.style-grid').appendChild(
688
+ createControlGroup('🎨 Face Style:', faceStyleSelect)
689
+ );
690
+ document.querySelector('.style-grid').appendChild(
691
+ createControlGroup('📸 Perspective:', perspectiveSelect)
692
+ );
693
+ document.querySelector('.style-grid').appendChild(
694
+ createControlGroup('🖌️ Object Placement:', objectPlacementSelect)
695
+ );
696
+ document.querySelector('.style-grid').appendChild(
697
+ createControlGroup('💡 Light Source:', lightSourceSelect)
698
+ );
699
+ document.querySelector('.style-grid').appendChild(
700
+ createControlGroup('🔍 Depth Perception:', depthPerceptionSelect)
701
+ );
702
+
703
+ function createControlGroup(labelText, selectElement) {
704
+ const container = document.createElement('div');
705
+ container.className = 'style-item';
706
+
707
+ const label = document.createElement('label');
708
+ label.textContent = labelText;
709
+
710
+ container.appendChild(label);
711
+ container.appendChild(selectElement);
712
+
713
+ return container;
714
+ }
715
+
716
+ generateButton.addEventListener('click', async () => {
717
+ const userPrompt = promptInput.value.trim();
718
+
719
+ if (!userPrompt) {
720
+ alert('Please enter a prompt to generate an image!');
721
+ return;
722
+ }
723
+
724
+ // Show loading indicator
725
+ loadingIndicator.classList.remove('hidden');
726
+ // Hide previous image
727
+ generatedImage.src = "";
728
+ // Clear previous semantic check results
729
+ const semanticCheckList = document.getElementById('semanticCheckList');
730
+ if (semanticCheckList) {
731
+ semanticCheckList.innerHTML = '';
732
+ }
733
+ document.getElementById('semanticCheckResult').classList.add('hidden');
734
+
735
+
736
+ try {
737
+ // Enhanced image generation with more control
738
+ const imageGenerationOptions = {
739
+ negativePrompt: negativePromptInput.value.trim(),
740
+ seed: seedInput.value ? parseInt(seedInput.value, 10) : undefined,
741
+ style: styleSelect.value,
742
+ renderQuality: renderQualitySelect.value,
743
+ lighting: lightingSelect.value,
744
+ controlNetMode: controlNetSelect.value,
745
+ faceQuality: faceQualitySelect.value,
746
+ faceStyle: faceStyleSelect.value,
747
+ symmetry: true,
748
+ perspective: perspectiveSelect.value,
749
+ objectPlacement: objectPlacementSelect.value,
750
+ lightSource: lightSourceSelect.value,
751
+ depthPerception: depthPerceptionSelect.value,
752
+ cfgScale: parseFloat(document.getElementById('cfgScaleInput').value),
753
+ steps: parseInt(document.getElementById('stepsInput').value, 10)
754
+ };
755
+
756
+ const result = await generateImage(userPrompt, imageGenerationOptions);
757
+
758
+ if (result && result.url) {
759
+ generatedImage.src = result.url;
760
+
761
+ // Additional semantic checks and enhancements
762
+ // Show semantic check results panel
763
+ document.getElementById('semanticCheckResult').classList.remove('hidden');
764
+ await performSemanticChecks(userPrompt, result.url);
765
+ }
766
+ } catch (error) {
767
+ console.error("Image Generation Process Failed:", error);
768
+ alert("Image generation failed: " + error.message);
769
+ generatedImage.src = "";
770
+ } finally {
771
+ // Hide loading indicator
772
+ loadingIndicator.classList.add('hidden');
773
+ }
774
+ });