Files changed (1) hide show
  1. app.py +247 -260
app.py CHANGED
@@ -1,128 +1,200 @@
1
- import gradio as gr
2
- import numpy as np
3
  import random
4
- # Import spaces BEFORE torch and diffusers to avoid CUDA initialization error
5
- import spaces
 
 
 
 
 
 
 
 
 
 
 
6
  import torch
7
  from diffusers import DiffusionPipeline
8
 
9
- # Basic settings
10
- dtype = torch.bfloat16
11
- device = "cuda" if torch.cuda.is_available() else "cpu"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- # Load model (FLUX.1-schnell)
14
- pipe = DiffusionPipeline.from_pretrained(
15
- "black-forest-labs/FLUX.1-schnell",
16
- torch_dtype=dtype
17
- ).to(device)
 
 
 
 
 
 
 
 
18
 
19
- MAX_SEED = np.iinfo(np.int32).max
20
- MAX_IMAGE_SIZE = 2048
 
 
 
 
 
21
 
22
- @spaces.GPU()
23
- def generate_image(prompt, seed, randomize_seed, width, height, steps, guidance_scale):
24
- if randomize_seed:
25
- seed = random.randint(0, MAX_SEED)
26
- generator = torch.Generator(device).manual_seed(seed)
27
- image = pipe(
28
- prompt=prompt,
29
- width=width,
30
- height=height,
31
- num_inference_steps=steps,
32
- generator=generator,
33
- guidance_scale=guidance_scale
34
- ).images[0]
35
- return image, seed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  def set_prompt(example_text):
38
  return example_text
39
 
40
- # Updated example prompts per tab with richer details:
 
 
41
  example_prompts = {
42
- "Product Design": [
43
- """A sleek industrial design concept for a coffee machine:
44
- - Curved metallic body with minimal bezel
45
- - Touchscreen panel for settings
46
- - Modern matte black finish
47
- - Hand-drawn concept sketch style"""
48
  ],
49
- "Mindmap": [
50
- """A handrawn colorful mind map diagram, educational style, vibrant colors, clear hierarchy, golden ratio layout.
51
  KNOWLEDGE
52
- โ”œโ”€โ”€ ACQUISITION [Brain with Lightning ~60px]
53
- โ”‚ โ”œโ”€โ”€ READING [Open Book with Glow]
54
- โ”‚ โ”œโ”€โ”€ PRACTICE [Hands-on Tools]
55
- โ”‚ โ””โ”€โ”€ OBSERVATION [Eye with Magnifier]
56
- โ”œโ”€โ”€ PROCESSING [Gear Network ~50px]
57
- โ”‚ โ”œโ”€โ”€ ANALYSIS [Graph Trending Up]
58
- โ”‚ โ””โ”€โ”€ SYNTHESIS [Puzzle Pieces]
59
- โ”œโ”€โ”€ RETENTION [Memory Chip ~45px]
60
- โ”‚ โ”œโ”€โ”€ SHORT-TERM [Quick Flash]
61
- โ”‚ โ””โ”€โ”€ LONG-TERM [Solid Archive]
62
  โ””โ”€โ”€ APPLICATION
63
- โ”œโ”€โ”€ CREATION [Artist Palette]
64
- โ””โ”€โ”€ INNOVATION [Lightbulb Constellation]"""
65
  ],
66
- "Mockup": [
67
- """A clean hand-drawn style wireframe for a mobile banking app:
68
- - Title screen with logo
69
- - Login screen (username, password, login button)
70
- - Dashboard with 3 main sections (balance, transactions, quick actions)
71
- - Bottom navigation bar (home, transfers, profile)"""
72
  ],
73
- "Infographic": [
74
- """A sophisticated flat-style infographic for a multinational corporation's annual report:
75
- - Title: "Global Renewable Energy Trends 2025"
76
- - Subtitle: "Market Share and Growth Analysis"
77
- - Visual Elements:
78
- - Multi-segmented bar charts comparing Solar, Wind, and Hydro energy production across regions
79
- - Pie chart displaying overall energy distribution: Solar (45%), Wind (30%), Hydro (25%)
80
- - Trend lines indicating year-over-year growth
81
- - Icons: Sleek, minimalist representations of a sun, wind turbine, and water droplet
82
- - Layout: Clean, grid-based design with ample white space and pastel accents for a modern corporate look
83
- - Annotations: Brief, impactful data callouts highlighting key performance indicators and future forecasts"""
84
  ],
85
- "Diagram": [
86
- """A detailed hand-drawn diagram illustrating an end-to-end business workflow:
87
- - Title: "Integrated Business Process Diagram"
88
- - Components:
89
- - Market Analysis: Research phase with data charts and competitor mapping
90
- - Strategy Development: Ideation stage with brainstorming clouds and key focus areas
91
- - Product Design: Concept sketches with iterative feedback loops
92
- - Implementation: Process flow with timeline markers and resource allocation icons
93
- - Post-Launch Review: Feedback, metrics, and continuous improvement cycles
94
- - Visual Elements:
95
- - Clear, directional arrows connecting each phase
96
- - Iconography for each component (e.g., magnifying glass, lightbulb, gear, checklist)
97
- - Style: Vibrant, educational yet professional, balancing detailed annotations with visual simplicity
98
- - Layout: Structured with a clear hierarchy and color-coded sections to differentiate process stages"""
99
  ],
100
- "Flowchart": [
101
- """A hand-drawn style flowchart, vibrant colors, minimalistic icons.
102
  BUSINESS WORKFLOW
103
- โ”œโ”€โ”€ START [Green Button ~40px]
104
- โ”‚ โ”œโ”€โ”€ COLLECT REQUIREMENTS [Folder Icon]
105
- โ”‚ โ””โ”€โ”€ ANALYZE DATA [Chart Icon]
106
- โ”œโ”€โ”€ IMPLEMENTATION [Coding Symbol ~50px]
107
- โ”‚ โ”œโ”€โ”€ FRONTEND [Browser Icon]
108
- โ”‚ โ””โ”€โ”€ BACKEND [Server Icon]
109
- โ”œโ”€โ”€ TEST & INTEGRATION [Gear Icon ~45px]
110
- โ””โ”€โ”€ DEPLOY
111
- โ””โ”€โ”€ END [Checkered Flag ~40px]"""
112
  ]
113
  }
114
 
115
- # CSS style: fixed container width, visible overflow, and preventing examples from expanding the layout
 
 
116
  css = """
117
- * {
118
- box-sizing: border-box;
119
- }
120
  body {
121
  background: linear-gradient(135deg, #667eea, #764ba2);
122
- font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
123
- color: #333;
124
- margin: 0;
125
- padding: 0;
126
  }
127
  .gradio-container {
128
  background: rgba(255, 255, 255, 0.95);
@@ -131,200 +203,115 @@ body {
131
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
132
  margin: 40px auto;
133
  width: 1200px;
134
- overflow: visible !important; /* ensure sidebar isn't clipped */
135
  }
136
  .sidebar {
137
  background: rgba(255, 255, 255, 0.98);
138
  border-radius: 10px;
139
  padding: 20px;
140
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
141
- position: relative;
142
- z-index: 10; /* bring sidebar above container edges */
143
  overflow: visible !important;
144
  }
145
  button, .btn {
146
  background: linear-gradient(90deg, #ff8a00, #e52e71);
147
- border: none;
148
- color: #fff;
149
- padding: 12px 24px;
150
- text-transform: uppercase;
151
- font-weight: bold;
152
- letter-spacing: 1px;
153
- border-radius: 5px;
154
- cursor: pointer;
155
  transition: transform 0.2s ease-in-out;
156
  }
157
- button:hover, .btn:hover {
158
- transform: scale(1.05);
159
- }
160
- .example-accordion {
161
- width: 100% !important;
162
- max-width: 100% !important;
163
- }
164
- .example-accordion button {
165
- width: auto !important;
166
- white-space: normal !important;
167
- }
168
  """
169
 
170
- with gr.Blocks(css=css, title="Workflow Canvas") as demo:
171
  gr.Markdown(
172
  """
173
  <div style="text-align:center;">
174
- <h1>Workflow Canvas</h1>
175
- <p>Generate design concepts and workflow diagrams for your business needs using our multi-tab interface.</p>
176
- <p><strong>community:</strong> <a href="https://discord.gg/openfreeai" target="_blank">https://discord.gg/openfreeai</a></p>
177
  </div>
178
  """
179
  )
180
  gr.HTML(
181
  """<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fginigen-Workflow-Canvas.hf.space">
182
- <img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fginigen-Workflow-Canvas.hf.space&countColor=%23263759" alt="Visitor Badge"/>
183
  </a>"""
184
  )
185
-
186
  with gr.Row():
187
- # Left sidebar: Common generation parameters
188
  with gr.Column(scale=2, elem_classes="sidebar"):
189
- gr.Markdown("### Generation Parameters")
190
- seed_slider = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=42)
191
- randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
192
- width_slider = gr.Slider(label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
193
- height_slider = gr.Slider(label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
194
- steps_slider = gr.Slider(label="Inference Steps", minimum=1, maximum=50, step=1, value=20)
195
- guidance_slider = gr.Slider(label="Guidance Scale", minimum=0.0, maximum=15.0, step=0.5, value=7.5)
196
-
197
- # Main area: Tabbed interface with updated tab order:
198
- # 1: Product Design, 2: Mindmap, 3: Mockup, 4: Infographic, 5: Diagram, 6: Flowchart
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  with gr.Column(scale=8):
200
  with gr.Tabs():
201
- # Tab 1: Product Design
202
- with gr.Tab("Product Design"):
203
- pd_prompt = gr.Textbox(
204
- label="Product Design Prompt",
205
- placeholder="Enter a product design concept...",
206
- lines=5,
207
- value=example_prompts["Product Design"][0]
208
- )
209
- pd_generate = gr.Button("Generate Product Design")
210
- pd_image = gr.Image(label="Generated Product Design", value="w1.webp")
211
- with gr.Accordion("Example Prompts", open=True, elem_classes="example-accordion"):
212
- for ex in example_prompts["Product Design"]:
213
- gr.Button(ex, variant="secondary").click(fn=lambda ex=ex: set_prompt(ex), outputs=pd_prompt)
214
-
215
- # Tab 2: Mindmap
216
- with gr.Tab("Mindmap"):
217
- mindmap_prompt = gr.Textbox(
218
- label="Mindmap Prompt",
219
- placeholder="Enter a mind map description...",
220
- lines=5,
221
- value=example_prompts["Mindmap"][0]
222
- )
223
- mindmap_generate = gr.Button("Generate Mindmap")
224
- mindmap_image = gr.Image(label="Generated Mindmap", value="w6.webp")
225
- with gr.Accordion("Example Prompts", open=True, elem_classes="example-accordion"):
226
- for ex in example_prompts["Mindmap"]:
227
- gr.Button(ex, variant="secondary").click(fn=lambda ex=ex: set_prompt(ex), outputs=mindmap_prompt)
228
-
229
- # Tab 3: Mockup
230
- with gr.Tab("Mockup"):
231
- mock_prompt = gr.Textbox(
232
- label="Mockup Prompt",
233
- placeholder="Enter a mockup description...",
234
- lines=5,
235
- value=example_prompts["Mockup"][0]
236
- )
237
- mock_generate = gr.Button("Generate Mockup")
238
- mock_image = gr.Image(label="Generated Mockup", value="w2.webp")
239
- with gr.Accordion("Example Prompts", open=True, elem_classes="example-accordion"):
240
- for ex in example_prompts["Mockup"]:
241
- gr.Button(ex, variant="secondary").click(fn=lambda ex=ex: set_prompt(ex), outputs=mock_prompt)
242
-
243
- # Tab 4: Infographic
244
- with gr.Tab("Infographic"):
245
- info_prompt = gr.Textbox(
246
- label="Infographic Prompt",
247
- placeholder="Enter an infographic description...",
248
- lines=5,
249
- value=example_prompts["Infographic"][0]
250
- )
251
- info_generate = gr.Button("Generate Infographic")
252
- info_image = gr.Image(label="Generated Infographic", value="w3.webp")
253
- with gr.Accordion("Example Prompts", open=True, elem_classes="example-accordion"):
254
- for ex in example_prompts["Infographic"]:
255
- gr.Button(ex, variant="secondary").click(fn=lambda ex=ex: set_prompt(ex), outputs=info_prompt)
256
-
257
- # Tab 5: Diagram
258
- with gr.Tab("Diagram"):
259
- diag_prompt = gr.Textbox(
260
- label="Diagram Prompt",
261
- placeholder="Enter a diagram description...",
262
- lines=5,
263
- value=example_prompts["Diagram"][0]
264
- )
265
- diag_generate = gr.Button("Generate Diagram")
266
- diag_image = gr.Image(label="Generated Diagram", value="w4.webp")
267
- with gr.Accordion("Example Prompts", open=True, elem_classes="example-accordion"):
268
- for ex in example_prompts["Diagram"]:
269
- gr.Button(ex, variant="secondary").click(fn=lambda ex=ex: set_prompt(ex), outputs=diag_prompt)
270
-
271
- # Tab 6: Flowchart
272
- with gr.Tab("Flowchart"):
273
- flow_prompt = gr.Textbox(
274
- label="Flowchart Prompt",
275
- placeholder="Enter a flowchart description...",
276
- lines=5,
277
- value=example_prompts["Flowchart"][0]
278
- )
279
- flow_generate = gr.Button("Generate Flowchart")
280
- flow_image = gr.Image(label="Generated Flowchart", value="w5.webp")
281
- with gr.Accordion("Example Prompts", open=True, elem_classes="example-accordion"):
282
- for ex in example_prompts["Flowchart"]:
283
- gr.Button(ex, variant="secondary").click(fn=lambda ex=ex: set_prompt(ex), outputs=flow_prompt)
284
-
285
- # Bind events for generation buttons
286
- pd_generate.click(
287
- fn=generate_image,
288
- inputs=[pd_prompt, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
289
- outputs=[pd_image, seed_slider]
290
- )
291
-
292
- mindmap_generate.click(
293
- fn=generate_image,
294
- inputs=[mindmap_prompt, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
295
- outputs=[mindmap_image, seed_slider]
296
- )
297
-
298
- mock_generate.click(
299
- fn=generate_image,
300
- inputs=[mock_prompt, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
301
- outputs=[mock_image, seed_slider]
302
- )
303
-
304
- info_generate.click(
305
- fn=generate_image,
306
- inputs=[info_prompt, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
307
- outputs=[info_image, seed_slider]
308
- )
309
-
310
- diag_generate.click(
311
- fn=generate_image,
312
- inputs=[diag_prompt, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
313
- outputs=[diag_image, seed_slider]
314
- )
315
-
316
- flow_generate.click(
317
- fn=generate_image,
318
- inputs=[flow_prompt, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
319
- outputs=[flow_image, seed_slider]
320
- )
321
 
322
  if __name__ == "__main__":
323
- demo.queue()
324
  demo.launch(
325
  server_name="0.0.0.0",
326
  server_port=7860,
327
  share=False,
328
  show_error=True,
329
  debug=True
330
- )
 
1
+ import os
 
2
  import random
3
+ import numpy as np
4
+ import gradio as gr
5
+
6
+ # --- Hugging Face Spaces ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(์—†์–ด๋„ ๋™์ž‘ํ•˜๋„๋ก ๋Œ€์ฒด) ---
7
+ try:
8
+ import spaces
9
+ GPU_DECORATOR = spaces.GPU
10
+ except Exception:
11
+ def GPU_DECORATOR(*args, **kwargs):
12
+ def _wrap(fn):
13
+ return fn
14
+ return _wrap
15
+
16
  import torch
17
  from diffusers import DiffusionPipeline
18
 
19
+ # -----------------------
20
+ # ์žฅ์น˜/์ •๋ฐ€๋„ ์ž๋™ ์„ ํƒ
21
+ # -----------------------
22
+ def select_device_dtype():
23
+ if torch.cuda.is_available():
24
+ device = "cuda"
25
+ dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16
26
+ else:
27
+ device = "cpu"
28
+ dtype = torch.float32
29
+ return device, dtype
30
+
31
+ device, dtype = select_device_dtype()
32
+ if device == "cuda":
33
+ torch.backends.cuda.matmul.allow_tf32 = True
34
+
35
+ # ์ œํ•œ๊ฐ’
36
+ MAX_SEED = np.iinfo(np.uint32).max
37
+ MAX_SIDE = 2048
38
+ MAX_TOTAL_PIXELS = 2_359_296 # ํ•ด์ƒ๋„ ์ด ํ”ฝ์…€ ๊ฐ€๋“œ(์•ฝ 2.36MP)
39
+
40
+ # -----------------------
41
+ # ๋ชจ๋ธ ๋กœ๋“œ (FLUX.1-schnell)
42
+ # -----------------------
43
+ MODEL_ID = "black-forest-labs/FLUX.1-schnell"
44
+ pipe = DiffusionPipeline.from_pretrained(MODEL_ID, torch_dtype=dtype).to(device)
45
+ if hasattr(pipe, "enable_vae_slicing"):
46
+ pipe.enable_vae_slicing()
47
+ if hasattr(pipe, "enable_vae_tiling"):
48
+ pipe.enable_vae_tiling()
49
 
50
+ # -----------------------
51
+ # ์œ ํ‹ธ
52
+ # -----------------------
53
+ def _clamp_hw(width: int, height: int):
54
+ width = int(max(256, min(int(width), MAX_SIDE)))
55
+ height = int(max(256, min(int(height), MAX_SIDE)))
56
+ if width * height > MAX_TOTAL_PIXELS:
57
+ scale = (MAX_TOTAL_PIXELS / (width * height)) ** 0.5
58
+ width = int((width * scale) // 32 * 32)
59
+ height = int((height * scale) // 32 * 32)
60
+ width = max(256, min(width, MAX_SIDE))
61
+ height = max(256, min(height, MAX_SIDE))
62
+ return width, height
63
 
64
+ def _validate_params(prompt: str, steps: int, guidance: float):
65
+ if not prompt or not prompt.strip():
66
+ raise ValueError("ํ”„๋กฌํ”„ํŠธ๊ฐ€ ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.")
67
+ if not (1 <= steps <= 50):
68
+ raise ValueError("์ถ”๋ก  ์Šคํ…์€ 1~50 ๋ฒ”์œ„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
69
+ if not (0.0 <= guidance <= 20.0):
70
+ raise ValueError("๊ฐ€์ด๋˜์Šค ์Šค์ผ€์ผ์€ 0.0~20.0 ๋ฒ”์œ„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
71
 
72
+ # -----------------------
73
+ # ์ƒ์„ฑ ํ•จ์ˆ˜
74
+ # -----------------------
75
+ @GPU_DECORATOR()
76
+ def generate_image(prompt, seed, randomize_seed, width, height, steps, guidance_scale, progress=gr.Progress(track_tqdm=True)):
77
+ try:
78
+ prompt = prompt.strip()
79
+ _validate_params(prompt, steps, guidance_scale)
80
+
81
+ if randomize_seed:
82
+ seed = random.randint(0, MAX_SEED)
83
+ generator = torch.Generator(device=device).manual_seed(int(seed))
84
+
85
+ width, height = _clamp_hw(width, height)
86
+
87
+ progress(0.1, desc="์ดˆ๊ธฐํ™” ์ค‘โ€ฆ")
88
+ if device == "cuda":
89
+ autocast_ctx = torch.autocast(device_type="cuda", dtype=dtype)
90
+ elif device == "cpu":
91
+ autocast_ctx = torch.autocast(device_type="cpu", dtype=dtype) if dtype != torch.float32 else torch.no_grad()
92
+ else:
93
+ autocast_ctx = torch.no_grad()
94
+
95
+ with autocast_ctx:
96
+ progress(0.4, desc="์ด๋ฏธ์ง€ ์ƒ์„ฑ ์ค‘โ€ฆ")
97
+ out = pipe(
98
+ prompt=prompt,
99
+ width=int(width),
100
+ height=int(height),
101
+ num_inference_steps=int(steps),
102
+ generator=generator,
103
+ guidance_scale=float(guidance_scale)
104
+ )
105
+ image = out.images[0]
106
+
107
+ progress(1.0, desc="์™„๋ฃŒ")
108
+ return image, int(seed)
109
+ except Exception as e:
110
+ gr.Error(f"์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜: {type(e).__name__}: {e}")
111
+ return None, int(seed)
112
 
113
  def set_prompt(example_text):
114
  return example_text
115
 
116
+ # -----------------------
117
+ # ํ•œ๊ธ€ ์˜ˆ์‹œ ํ”„๋กฌํ”„ํŠธ
118
+ # -----------------------
119
  example_prompts = {
120
+ "์ œํ’ˆ ๋””์ž์ธ": [
121
+ """์Šฌ๋ฆญํ•œ ์ธ๋”์ŠคํŠธ๋ฆฌ์–ผ ์Šคํƒ€์ผ์˜ ์ปคํ”ผ๋จธ์‹  ์ปจ์…‰ ์Šค์ผ€์น˜:
122
+ - ๊ณก์„ ํ˜• ๋ฉ”ํƒˆ ๋ฐ”๋””, ๋ฒ ์ ค ์ตœ์†Œํ™”
123
+ - ์„ค์ •์šฉ ํ„ฐ์น˜์Šคํฌ๋ฆฐ ํŒจ๋„
124
+ - ๋ชจ๋˜ํ•œ ๋งคํŠธ ๋ธ”๋ž™ ๋งˆ๊ฐ
125
+ - ์†๊ทธ๋ฆผ(์Šค์ผ€์น˜) ์ปจ์…‰ ์•„ํŠธ ์Šคํƒ€์ผ"""
126
  ],
127
+ "๋งˆ์ธ๋“œ๋งต": [
128
+ """์†๊ทธ๋ฆผ ์Šคํƒ€์ผ์˜ ๋‹ค์ฑ„๋กœ์šด ๋งˆ์ธ๋“œ๋งต, ๊ต์œก์šฉ, ์ƒ๋™๊ฐ ์žˆ๋Š” ์ƒ‰๊ฐ, ๋ช…ํ™•ํ•œ ๊ณ„์ธต ๊ตฌ์กฐ, ํ™ฉ๊ธˆ๋น„ ๋ ˆ์ด์•„์›ƒ.
129
  KNOWLEDGE
130
+ โ”œโ”€โ”€ ACQUISITION [๋ฒˆ๊ฐœ๊ฐ€ ์นœ ๋‡Œ ~60px]
131
+ โ”‚ โ”œโ”€โ”€ READING [๋น›๋‚˜๋Š” ํŽผ์นœ ์ฑ…]
132
+ โ”‚ โ”œโ”€โ”€ PRACTICE [๊ณต๊ตฌ ์•„์ด์ฝ˜]
133
+ โ”‚ โ””โ”€โ”€ OBSERVATION [ํ™•๋Œ€๊ฒฝ ๋“  ๋ˆˆ]
134
+ โ”œโ”€โ”€ PROCESSING [๊ธฐ์–ด ๋„คํŠธ์›Œํฌ ~50px]
135
+ โ”‚ โ”œโ”€โ”€ ANALYSIS [์ƒ์Šน ๊ทธ๋ž˜ํ”„]
136
+ โ”‚ โ””โ”€โ”€ SYNTHESIS [ํผ์ฆ ์กฐ๊ฐ]
137
+ โ”œโ”€โ”€ RETENTION [๋ฉ”๋ชจ๋ฆฌ ์นฉ ~45px]
138
+ โ”‚ โ”œโ”€โ”€ SHORT-TERM [๋ฒˆ์ฉ์ž„]
139
+ โ”‚ โ””โ”€โ”€ LONG-TERM [๊ฒฌ๊ณ ํ•œ ์•„์นด์ด๋ธŒ]
140
  โ””โ”€โ”€ APPLICATION
141
+ โ”œโ”€โ”€ CREATION [ํŒ”๋ ˆํŠธ]
142
+ โ””โ”€โ”€ INNOVATION [๋ณ„์ž๋ฆฌ ์ „๊ตฌ]"""
143
  ],
144
+ "๋ชฉ์—…": [
145
+ """์†๊ทธ๋ฆผ ์™€์ด์–ดํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ์˜ ๋ชจ๋ฐ”์ผ ๋ฑ…ํ‚น ์•ฑ ๋ชฉ์—…:
146
+ - ๋กœ๊ณ ๊ฐ€ ์žˆ๋Š” ํƒ€์ดํ‹€ ํ™”๋ฉด
147
+ - ๋กœ๊ทธ์ธ(์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ)
148
+ - ๋Œ€์‹œ๋ณด๋“œ 3๊ฐœ ์„น์…˜(์ž”์•ก, ๊ฑฐ๋ž˜๋‚ด์—ญ, ๋น ๋ฅธ ์‹คํ–‰)
149
+ - ํ•˜๋‹จ ๋‚ด๋น„๊ฒŒ์ด์…˜(ํ™ˆ, ์ด์ฒด, ํ”„๋กœํ•„)"""
150
  ],
151
+ "์ธํฌ๊ทธ๋ž˜ํ”ฝ": [
152
+ """๋Œ€๊ธฐ์—… ์—ฐ์ฐจ๋ณด๊ณ ์„œ์šฉ ํ”Œ๋žซ ์Šคํƒ€์ผ ์ธํฌ๊ทธ๋ž˜ํ”ฝ:
153
+ - ์ œ๋ชฉ: "Global Renewable Energy Trends 2025"
154
+ - ๋ถ€์ œ: "์‹œ์žฅ์ ์œ ์œจ๊ณผ ์„ฑ์žฅ๋ถ„์„"
155
+ - ์‹œ๊ฐ ์š”์†Œ:
156
+ - ์ง€์—ญ๋ณ„ ํƒœ์–‘๊ด‘ยทํ’๋ ฅยท์ˆ˜๋ ฅ ์ƒ์‚ฐ๋Ÿ‰ ๋ง‰๋Œ€๊ทธ๋ž˜ํ”„
157
+ - ์—๋„ˆ์ง€ ๋น„์ค‘ ํŒŒ์ด์ฐจํŠธ: ํƒœ์–‘๊ด‘(45%)ยทํ’๋ ฅ(30%)ยท์ˆ˜๋ ฅ(25%)
158
+ - ์—ฐ๋„๋ณ„ ์„ฑ์žฅ ์ถ”์„ธ์„ 
159
+ - ์•„์ด์ฝ˜: ๋ฏธ๋‹ˆ๋ฉ€ ํƒœ์–‘, ํ’๋ ฅ ํ„ฐ๋นˆ, ๋ฌผ๋ฐฉ์šธ
160
+ - ๋ ˆ์ด์•„์›ƒ: ๊ทธ๋ฆฌ๋“œ ๊ธฐ๋ฐ˜, ํŒŒ์Šคํ…” ํฌ์ธํŠธ, ํ™”์ดํŠธ ์ŠคํŽ˜์ด์Šค ์ถฉ๋ถ„
161
+ - ์ฃผ์„: KPI ํ•ต์‹ฌ ์ˆ˜์น˜ ๋ฐ ์ „๋ง ์ฝœ์•„์›ƒ"""
162
  ],
163
+ "๋‹ค์ด์–ด๊ทธ๋žจ": [
164
+ """์—”๋“œํˆฌ์—”๋“œ ๋น„์ฆˆ๋‹ˆ์Šค ์›Œํฌํ”Œ๋กœ ๋‹ค์ด์–ด๊ทธ๋žจ(์†๊ทธ๋ฆผ, ๊ต์œก์ ยท์ „๋ฌธ์ ):
165
+ - ์ œ๋ชฉ: "ํ†ตํ•ฉ ๋น„์ฆˆ๋‹ˆ์Šค ํ”„๋กœ์„ธ์Šค"
166
+ - ๊ตฌ์„ฑ:
167
+ - ์‹œ์žฅ๋ถ„์„(์ฐจํŠธ, ๊ฒฝ์Ÿ์ž ๋งต)
168
+ - ์ „๋žต์ˆ˜๋ฆฝ(๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ ํด๋ผ์šฐ๋“œ, ํ•ต์‹ฌ ํฌ์ปค์Šค)
169
+ - ์ œํ’ˆ์„ค๊ณ„(์Šค์ผ€์น˜, ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„)
170
+ - ๊ตฌํ˜„(ํƒ€์ž„๋ผ์ธ ๋งˆ์ปค, ๋ฆฌ์†Œ์Šค ์•„์ด์ฝ˜)
171
+ - ์ถœ์‹œ ํ›„ ๋ฆฌ๋ทฐ(์ง€ํ‘œ, ์ง€์† ๊ฐœ์„ )
172
+ - ๋ช…ํ™•ํ•œ ๋ฐฉํ–ฅ ํ™”์‚ดํ‘œ, ์ƒ‰์ƒ์œผ๋กœ ๋‹จ๊ณ„ ๊ตฌ๋ถ„"""
 
 
 
 
173
  ],
174
+ "ํ”Œ๋กœ์šฐ์ฐจํŠธ": [
175
+ """์†๊ทธ๋ฆผ ์Šคํƒ€์ผ ํ”Œ๋กœ์šฐ์ฐจํŠธ, ์„ ๋ช…ํ•œ ์ƒ‰, ๋ฏธ๋‹ˆ๋ฉ€ ์•„์ด์ฝ˜.
176
  BUSINESS WORKFLOW
177
+ โ”œโ”€โ”€ ์‹œ์ž‘ [์ดˆ๋ก ๋ฒ„ํŠผ ~40px]
178
+ โ”‚ โ”œโ”€โ”€ ์š”๊ตฌ์‚ฌํ•ญ ์ˆ˜์ง‘ [ํด๋” ์•„์ด์ฝ˜]
179
+ โ”‚ โ””โ”€โ”€ ๋ฐ์ดํ„ฐ ๋ถ„์„ [์ฐจํŠธ ์•„์ด์ฝ˜]
180
+ โ”œโ”€โ”€ ๊ตฌํ˜„ [์ฝ”๋”ฉ ์‹ฌ๋ณผ ~50px]
181
+ โ”‚ โ”œโ”€โ”€ ํ”„๋ก ํŠธ์—”๋“œ [๋ธŒ๋ผ์šฐ์ € ์•„์ด์ฝ˜]
182
+ โ”‚ โ””โ”€โ”€ ๋ฐฑ์—”๋“œ [์„œ๋ฒ„ ์•„์ด์ฝ˜]
183
+ โ”œโ”€โ”€ ํ…Œ์ŠคํŠธ & ํ†ตํ•ฉ [๊ธฐ์–ด ์•„์ด์ฝ˜ ~45px]
184
+ โ””โ”€โ”€ ๋ฐฐํฌ
185
+ โ””โ”€โ”€ ์ข…๋ฃŒ [์ฒด์ปค๊ธฐ ๊นƒ๋ฐœ ~40px]"""
186
  ]
187
  }
188
 
189
+ # -----------------------
190
+ # Gradio UI (ํ•œ๊ตญ์–ด)
191
+ # -----------------------
192
  css = """
193
+ * { box-sizing: border-box; }
 
 
194
  body {
195
  background: linear-gradient(135deg, #667eea, #764ba2);
196
+ font-family: 'Pretendard', 'Apple SD Gothic Neo', 'Noto Sans KR', 'Helvetica Neue', Arial, sans-serif;
197
+ color: #333; margin: 0; padding: 0;
 
 
198
  }
199
  .gradio-container {
200
  background: rgba(255, 255, 255, 0.95);
 
203
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
204
  margin: 40px auto;
205
  width: 1200px;
206
+ overflow: visible !important;
207
  }
208
  .sidebar {
209
  background: rgba(255, 255, 255, 0.98);
210
  border-radius: 10px;
211
  padding: 20px;
212
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
213
+ position: relative; z-index: 10;
 
214
  overflow: visible !important;
215
  }
216
  button, .btn {
217
  background: linear-gradient(90deg, #ff8a00, #e52e71);
218
+ border: none; color: #fff;
219
+ padding: 12px 24px; text-transform: uppercase;
220
+ font-weight: bold; letter-spacing: 1px;
221
+ border-radius: 5px; cursor: pointer;
 
 
 
 
222
  transition: transform 0.2s ease-in-out;
223
  }
224
+ button:hover, .btn:hover { transform: scale(1.05); }
225
+ .example-accordion { width: 100% !important; max-width: 100% !important; }
226
+ .example-accordion button { width: auto !important; white-space: normal !important; }
 
 
 
 
 
 
 
 
227
  """
228
 
229
+ with gr.Blocks(css=css, title="์›Œํฌํ”Œ๋กœ ์บ”๋ฒ„์Šค") as demo:
230
  gr.Markdown(
231
  """
232
  <div style="text-align:center;">
233
+ <h1>์›Œํฌํ”Œ๋กœ ์บ”๋ฒ„์Šค</h1>
234
+ <p>์—ฌ๋Ÿฌ ํƒญ์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค์— ํ•„์š”ํ•œ ๋””์ž์ธ ์ปจ์…‰๊ณผ ์›Œํฌํ”Œ๋กœ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ƒ์„ฑํ•ด ๋ณด์„ธ์š”.</p>
235
+ <p><strong>์ปค๋ฎค๋‹ˆํ‹ฐ:</strong> <a href="https://discord.gg/openfreeai" target="_blank">https://discord.gg/openfreeai</a></p>
236
  </div>
237
  """
238
  )
239
  gr.HTML(
240
  """<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fginigen-Workflow-Canvas.hf.space">
241
+ <img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fginigen-Workflow-Canvas.hf.space&countColor=%23263759" alt="๋ฐฉ๋ฌธ์ž ๋ฐฐ์ง€"/>
242
  </a>"""
243
  )
244
+
245
  with gr.Row():
246
+ # ์™ผ์ชฝ ์‚ฌ์ด๋“œ๋ฐ”: ๊ณตํ†ต ํŒŒ๋ผ๋ฏธํ„ฐ
247
  with gr.Column(scale=2, elem_classes="sidebar"):
248
+ gr.Markdown("### ์ƒ์„ฑ ํŒŒ๋ผ๋ฏธํ„ฐ")
249
+
250
+ size_preset = gr.Dropdown(
251
+ label="ํ•ด์ƒ๋„ ํ”„๋ฆฌ์…‹",
252
+ choices=[
253
+ "1024x1024", "1536x1024", "1024x1536",
254
+ "1344x1344", "1536x1536", "1920x1080", "1080x1920"
255
+ ],
256
+ value="1024x1024"
257
+ )
258
+ width_slider = gr.Slider(label="๊ฐ€๋กœ ํ•ด์ƒ๋„(px)", minimum=256, maximum=MAX_SIDE, step=32, value=1024)
259
+ height_slider = gr.Slider(label="์„ธ๋กœ ํ•ด์ƒ๋„(px)", minimum=256, maximum=MAX_SIDE, step=32, value=1024)
260
+
261
+ def apply_preset(preset):
262
+ w, h = map(int, preset.split("x"))
263
+ w, h = _clamp_hw(w, h)
264
+ return w, h
265
+ size_preset.change(fn=apply_preset, inputs=size_preset, outputs=[width_slider, height_slider])
266
+
267
+ seed_slider = gr.Slider(label="์‹œ๋“œ(Seed)", minimum=0, maximum=int(MAX_SEED), step=1, value=42)
268
+ randomize_seed = gr.Checkbox(label="์‹œ๋“œ ๋žœ๋ค", value=True)
269
+
270
+ def toggle_seed(disable):
271
+ return gr.update(interactive=not disable)
272
+ randomize_seed.change(fn=toggle_seed, inputs=randomize_seed, outputs=seed_slider)
273
+
274
+ steps_slider = gr.Slider(label="์ถ”๋ก  ์Šคํ…", minimum=1, maximum=50, step=1, value=20)
275
+ guidance_slider = gr.Slider(label="๊ฐ€์ด๋˜์Šค ์Šค์ผ€์ผ", minimum=0.0, maximum=20.0, step=0.5, value=7.5)
276
+
277
+ # ๋ฉ”์ธ: ํƒญ UI
278
  with gr.Column(scale=8):
279
  with gr.Tabs():
280
+ def build_tab(tab_title, ex_key, placeholder_text):
281
+ with gr.Tab(tab_title):
282
+ tb = gr.Textbox(
283
+ label=f"{tab_title} ํ”„๋กฌํ”„ํŠธ",
284
+ placeholder=placeholder_text,
285
+ lines=5,
286
+ value=example_prompts[ex_key][0]
287
+ )
288
+ btn = gr.Button(f"{tab_title} ์ƒ์„ฑ")
289
+ img = gr.Image(label=f"{tab_title} ๊ฒฐ๊ณผ", type="pil", value=None, height=512)
290
+ with gr.Accordion("์˜ˆ์‹œ ํ”„๋กฌํ”„ํŠธ", open=True, elem_classes="example-accordion"):
291
+ for ex in example_prompts[ex_key]:
292
+ gr.Button(ex, variant="secondary").click(
293
+ fn=lambda ex=ex: set_prompt(ex),
294
+ outputs=tb
295
+ )
296
+ btn.click(
297
+ fn=generate_image,
298
+ inputs=[tb, seed_slider, randomize_seed, width_slider, height_slider, steps_slider, guidance_slider],
299
+ outputs=[img, seed_slider]
300
+ )
301
+
302
+ build_tab("์ œํ’ˆ ๋””์ž์ธ", "์ œํ’ˆ ๋””์ž์ธ", "์ œํ’ˆ ๋””์ž์ธ ์ปจ์…‰์„ ์ž…๋ ฅํ•˜์„ธ์š”โ€ฆ")
303
+ build_tab("๋งˆ์ธ๋“œ๋งต", "๋งˆ์ธ๋“œ๋งต", "๋งˆ์ธ๋“œ๋งต ์„ค๋ช…์„ ์ž…๋ ฅํ•˜์„ธ์š”โ€ฆ")
304
+ build_tab("๋ชฉ์—…", "๋ชฉ์—…", "์•ฑ/์›น ๋ชฉ์—… ์„ค๏ฟฝ๏ฟฝ๏ฟฝ์„ ์ž…๋ ฅํ•˜์„ธ์š”โ€ฆ")
305
+ build_tab("์ธํฌ๊ทธ๋ž˜ํ”ฝ", "์ธํฌ๊ทธ๋ž˜ํ”ฝ", "์ธํฌ๊ทธ๋ž˜ํ”ฝ ์„ค๋ช…์„ ์ž…๋ ฅํ•˜์„ธ์š”โ€ฆ")
306
+ build_tab("๋‹ค์ด์–ด๊ทธ๋žจ", "๋‹ค์ด์–ด๊ทธ๋žจ", "๋‹ค์ด์–ด๊ทธ๋žจ ์„ค๋ช…์„ ์ž…๋ ฅํ•˜์„ธ์š”โ€ฆ")
307
+ build_tab("ํ”Œ๋กœ์šฐ์ฐจํŠธ", "ํ”Œ๋กœ์šฐ์ฐจํŠธ", "ํ”Œ๋กœ์šฐ์ฐจํŠธ ์„ค๋ช…์„ ์ž…๋ ฅํ•˜์„ธ์š”โ€ฆ")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
  if __name__ == "__main__":
310
+ demo.queue(concurrency_count=2, max_size=32)
311
  demo.launch(
312
  server_name="0.0.0.0",
313
  server_port=7860,
314
  share=False,
315
  show_error=True,
316
  debug=True
317
+ )