Maximumm commited on
Commit
61ba591
Β·
verified Β·
1 Parent(s): 53c3393

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ hero/HERO_burgundy-gold_nanobanana.jpeg filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .DS_Store
README.md CHANGED
@@ -1,13 +1,59 @@
1
  ---
2
  title: All The Best
3
- emoji: πŸ“‰
4
- colorFrom: green
5
- colorTo: blue
6
  sdk: gradio
7
  sdk_version: 6.26.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: All The Best
3
+ emoji: 🍫
4
+ colorFrom: gray
5
+ colorTo: gray
6
  sdk: gradio
7
  sdk_version: 6.26.0
 
8
  app_file: app.py
9
  pinned: false
10
+ license: apache-2.0
11
+ short_description: Dead Hugging Face Spaces rendered as boxes of chocolates
12
  ---
13
 
14
+ # All The Best
15
+
16
+ Dead Hugging Face Spaces rendered as boxes of chocolates. Each box is generated
17
+ from the Space's own data β€” its colours, commit log, dependencies and final
18
+ commit date β€” through six sequential image-to-image passes on
19
+ Qwen-Image-Edit-2511.
20
+
21
+ The interest is in the text: how much printed detail survives across a chain of
22
+ edits, and what has to be explicitly named to stop it being overwritten.
23
+
24
+ An experiment by Max Fowler.
25
+
26
+ ## How a box is derived
27
+
28
+ | Box element | Space data |
29
+ |---|---|
30
+ | Ink | `colorFrom` / `colorTo` |
31
+ | Best before | last commit date |
32
+ | Flavour guide (insert card) | commit messages, oldest first |
33
+ | Ingredients line | `requirements.txt` |
34
+ | Format | commit count |
35
+ | Batch | final commit hash |
36
+ | Barcode | repo id |
37
+
38
+ The moulded smiling face is fixed. It is the same in every box.
39
+
40
+ ## Passes
41
+
42
+ Run in the order established by the prompt ladder, each naming the elements
43
+ that must survive:
44
+
45
+ 1. repaint
46
+ 2. best before
47
+ 3. ingredients line
48
+ 4. insert card
49
+ 5. product name β€” gold script
50
+ 6. chocolates
51
+
52
+ ## Running
53
+
54
+ `STUB_MODEL = True` in `app.py` runs the whole app without touching the GPU β€”
55
+ live data, no generation. Flip it to `False` and uncomment the torch block in
56
+ `requirements.txt` to generate for real.
57
+
58
+ Boxes are cached to a Dataset repo, one per Space, and served from there
59
+ afterwards. Set `ARCHIVE_REPO` and a write-scoped `HF_TOKEN` in Space secrets.
app.py ADDED
@@ -0,0 +1,496 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ALL THE BEST β€” an experiment by Max Fowler
3
+
4
+ Dead Hugging Face Spaces rendered as boxes of chocolates. Each box is generated
5
+ from the Space's own data through six sequential image-to-image passes on
6
+ Qwen-Image-Edit-2511.
7
+
8
+ STUB_MODEL = True runs the whole app without touching the GPU.
9
+ """
10
+
11
+ import io
12
+ import json
13
+ import os
14
+ import time
15
+ import datetime as dt
16
+
17
+ import gradio as gr
18
+ from PIL import Image
19
+ from huggingface_hub import HfApi, hf_hub_download, upload_file
20
+
21
+ # ─────────────────────────────────────────────────────────────────────
22
+ # Config
23
+ # ─────────────────────────────────────────────────────────────────────
24
+
25
+ STUB_MODEL = True # flip when ready to spend quota
26
+ MODEL_ID = "Qwen/Qwen-Image-Edit-2511"
27
+ LIGHTNING_ID = "lightx2v/Qwen-Image-Edit-2511-Lightning"
28
+ LIGHTNING_4 = "Qwen-Image-Edit-2511-Lightning-4steps-V1.0-bf16.safetensors"
29
+ LIGHTNING_8 = "Qwen-Image-Edit-2511-Lightning-8steps-V1.0-bf16.safetensors"
30
+
31
+ STEPS = 4 # 4 or 8 β€” the ladder decides
32
+ HERO_PATH = "hero/HERO_burgundy-gold_nanobanana.jpeg"
33
+ ARCHIVE_REPO = os.environ.get("ARCHIVE_REPO", "") # "you/all-the-best-archive"
34
+ HF_TOKEN = os.environ.get("HF_TOKEN", "")
35
+ ON_SPACE = bool(os.environ.get("SPACE_ID")) # sign-in only exists on a Space
36
+
37
+ api = HfApi(token=HF_TOKEN or None)
38
+
39
+ DEAD = {"PAUSED", "STOPPED", "RUNTIME_ERROR", "BUILD_ERROR",
40
+ "CONFIG_ERROR", "NO_APP_FILE", "SLEEPING"}
41
+
42
+ INK = {"red": "deep red", "yellow": "golden yellow", "green": "deep green",
43
+ "blue": "deep blue", "indigo": "indigo", "purple": "aubergine purple",
44
+ "pink": "dusty pink", "gray": "slate grey"}
45
+
46
+ SWATCH = {"red": "#A8342A", "yellow": "#C8952B", "green": "#2F6B3C", "blue": "#2B4A8C",
47
+ "indigo": "#3B357E", "purple": "#5C3566", "pink": "#B06A80", "gray": "#6E6A62"}
48
+
49
+
50
+ def format_for(n):
51
+ if n <= 3:
52
+ return "slim sleeve"
53
+ if n <= 12:
54
+ return "standard assortment"
55
+ if n <= 30:
56
+ return "deep assortment"
57
+ return "catering slab"
58
+
59
+
60
+ # ─────────────────────────────────────────────────────────────────────
61
+ # Data β€” straight from the Hub, server side
62
+ # ─────────────────────────────────────────────────────────────────────
63
+
64
+ def _card(obj):
65
+ """card_data may be a dict, a CardData object, or None."""
66
+ card = getattr(obj, "card_data", None)
67
+ if card is None:
68
+ return {}
69
+ if isinstance(card, dict):
70
+ return card
71
+ to_dict = getattr(card, "to_dict", None)
72
+ if callable(to_dict):
73
+ return to_dict()
74
+ return dict(getattr(card, "__dict__", {}) or {})
75
+
76
+
77
+ def _stage(obj):
78
+ rt = getattr(obj, "runtime", None)
79
+ if isinstance(rt, dict):
80
+ return rt.get("stage")
81
+ return getattr(rt, "stage", None)
82
+
83
+
84
+ def list_dead(account):
85
+ rows = []
86
+ for s in api.list_spaces(author=account,
87
+ expand=["runtime", "cardData", "lastModified", "likes"]):
88
+ st = _stage(s)
89
+ if st not in DEAD:
90
+ continue
91
+ card = _card(s)
92
+ rows.append({
93
+ "id": s.id,
94
+ "name": s.id.split("/")[1],
95
+ "stage": st,
96
+ "moved": str(getattr(s, "last_modified", ""))[:10],
97
+ "likes": getattr(s, "likes", 0) or 0,
98
+ "emoji": card.get("emoji") or "",
99
+ })
100
+ rows.sort(key=lambda r: r["moved"], reverse=True)
101
+ return rows
102
+
103
+
104
+ def get_grave(repo_id):
105
+ info = api.space_info(repo_id)
106
+ try:
107
+ commits = api.list_repo_commits(repo_id, repo_type="space")
108
+ except Exception:
109
+ commits = []
110
+ try:
111
+ reqs = open(hf_hub_download(repo_id, "requirements.txt", repo_type="space",
112
+ token=HF_TOKEN or None)).read()
113
+ except Exception:
114
+ reqs = ""
115
+ return info, commits, reqs
116
+
117
+
118
+ def to_spec(info, commits, reqs):
119
+ card = _card(info)
120
+
121
+ msgs = [c.title.split("\n")[0].strip() for c in commits if getattr(c, "title", "")]
122
+ chron = list(reversed(msgs)) # oldest first = flavour guide
123
+ last = commits[0] if commits else None
124
+
125
+ ingredients = [l.split("@")[0].split(";")[0].strip()
126
+ for l in (reqs or "").splitlines()
127
+ if l.strip() and not l.strip().startswith("#")]
128
+
129
+ frm = card.get("colorFrom") or "gray"
130
+ to = card.get("colorTo") or "gray"
131
+
132
+ if last is not None and getattr(last, "created_at", None):
133
+ best_before = last.created_at.strftime("%d %b %Y").upper()
134
+ else:
135
+ best_before = str(getattr(info, "last_modified", ""))[:10]
136
+
137
+ return {
138
+ "repo": info.id,
139
+ "title": card.get("title") or info.id.split("/")[1],
140
+ "author": info.id.split("/")[0],
141
+ "emoji": card.get("emoji") or "",
142
+ "ink_from": frm,
143
+ "ink_to": to,
144
+ "monochrome": frm == to,
145
+ "pieces": len(chron),
146
+ "format": format_for(len(chron)),
147
+ "flavour_guide": chron,
148
+ "ingredients": ingredients,
149
+ "best_before": best_before,
150
+ "batch": (getattr(last, "commit_id", "") or "")[:7],
151
+ "stage": _stage(info) or "UNKNOWN",
152
+ "barcode": info.id,
153
+ }
154
+
155
+
156
+ # ─────────────────────────────────────────────────────────────────────
157
+ # The six passes β€” ladder order, verbatim where the ladder settled them
158
+ # ─────────────────────────────────────────────────────────────────────
159
+
160
+ def ink_clause(s):
161
+ a = INK.get(s["ink_from"], "slate grey")
162
+ b = INK.get(s["ink_to"], "slate grey")
163
+ if s["monochrome"]:
164
+ return f"Repaint the box in {a}, lid and base the same single colour."
165
+ return f"Repaint the box in {a} and {b}."
166
+
167
+
168
+ def build_chain(s):
169
+ """[(short label, prompt)] in the order the ladder proved works."""
170
+ date = s["best_before"]
171
+ ings = ", ".join(s["ingredients"][:4]).upper()
172
+ guide = ", ".join(f'"{m}"' for m in s["flavour_guide"][:7])
173
+
174
+ return [
175
+ (f'repaint β€” {s["ink_from"]}' + (", monochrome" if s["monochrome"] else ""),
176
+ f"image_1 is the box to edit. image_2 is a style reference only and must not "
177
+ f"appear in the output. {ink_clause(s)} Following the same layout of printed "
178
+ f"areas as image_2. Keep the box construction, gold ornament, camera angle and "
179
+ f"tray unchanged. Matte uncoated finish, soft diffuse light, no glossy "
180
+ f"highlights. Output only the box from image_1."),
181
+
182
+ (f"best before β€” {date}",
183
+ f'image_1 is the box. Print the text "BEST BEFORE {date}" in small dot-matrix '
184
+ f"characters in the lower right corner of the lid. Keep everything else unchanged."),
185
+
186
+ ("ingredients line",
187
+ f'image_1 is the box. Keep the existing "BEST BEFORE {date}" text exactly where '
188
+ f'it is. Add a second line of text below it reading "INGREDIENTS: {ings}" in '
189
+ f"small sans-serif capitals. Keep everything else unchanged."),
190
+
191
+ (f'insert card β€” {min(7, len(s["flavour_guide"]))} lines',
192
+ f"image_1 is the box. Place a small printed card resting inside the lid, listing "
193
+ f"in a single column of fine type: {guide}. Keep everything else unchanged."),
194
+
195
+ ("product name β€” gold script",
196
+ f'image_1 is the box. Print the product name "{s["title"]}" in the centre of the '
197
+ f"lid in ornate 1970s gold script lettering with a fine gold underline flourish. "
198
+ f'Keep the existing "BEST BEFORE" text, the ingredients line and the printed card '
199
+ f"exactly as they are. Keep everything else unchanged."),
200
+
201
+ ("chocolates",
202
+ "image_1 is the box. Fill the tray cups with round milk chocolates, each with a "
203
+ "simple smiling face pressed into the surface as a shallow relief. Uniform, "
204
+ "identical, factory-moulded. Keep the existing text, the printed card and "
205
+ "everything else unchanged."),
206
+ ]
207
+
208
+
209
+ # ─────────────────────────────────────────────────────────────────────
210
+ # Model
211
+ # ─────────────────────────────────────────────────────────────────────
212
+
213
+ PIPE = None
214
+
215
+ if not STUB_MODEL:
216
+ import torch
217
+ import spaces
218
+ from diffusers import QwenImageEditPlusPipeline
219
+
220
+ def _pipe():
221
+ global PIPE
222
+ if PIPE is None:
223
+ PIPE = QwenImageEditPlusPipeline.from_pretrained(
224
+ MODEL_ID, torch_dtype=torch.bfloat16).to("cuda")
225
+ PIPE.load_lora_weights(
226
+ LIGHTNING_ID, weight_name=LIGHTNING_4 if STEPS <= 4 else LIGHTNING_8)
227
+ PIPE.fuse_lora()
228
+ PIPE.set_progress_bar_config(disable=True)
229
+ return PIPE
230
+
231
+ @spaces.GPU(duration=25)
232
+ def run_pass(images, prompt):
233
+ return _pipe()(image=images, prompt=prompt, num_inference_steps=STEPS,
234
+ true_cfg_scale=1.0, negative_prompt=" ").images[0]
235
+ else:
236
+ def run_pass(images, prompt):
237
+ time.sleep(0.5)
238
+ return images[0]
239
+
240
+
241
+ # ────────────────────────────────��────────────────────────────────────
242
+ # Archive β€” generate once per space, hold indefinitely
243
+ # ─────────────────────────────────────────────────────────────────────
244
+
245
+ def _key(repo_id):
246
+ return f"boxes/{repo_id.replace('/', '__')}.png"
247
+
248
+
249
+ def from_archive(repo_id):
250
+ if not ARCHIVE_REPO:
251
+ return None
252
+ try:
253
+ return Image.open(hf_hub_download(ARCHIVE_REPO, _key(repo_id),
254
+ repo_type="dataset",
255
+ token=HF_TOKEN or None))
256
+ except Exception:
257
+ return None
258
+
259
+
260
+ def to_archive(repo_id, image, spec):
261
+ if not (ARCHIVE_REPO and HF_TOKEN):
262
+ return
263
+ buf = io.BytesIO()
264
+ image.save(buf, format="PNG")
265
+ upload_file(path_or_fileobj=buf.getvalue(), path_in_repo=_key(repo_id),
266
+ repo_id=ARCHIVE_REPO, repo_type="dataset", token=HF_TOKEN)
267
+ meta = dict(spec, produced=dt.datetime.utcnow().isoformat(timespec="seconds"))
268
+ upload_file(path_or_fileobj=json.dumps(meta, indent=2).encode(),
269
+ path_in_repo=f"specs/{repo_id.replace('/', '__')}.json",
270
+ repo_id=ARCHIVE_REPO, repo_type="dataset", token=HF_TOKEN)
271
+
272
+
273
+ # ─────────────────────────────────────────────────────────────────────
274
+ # HTML fragments
275
+ # ─────────────────────────────────────────────────────────────────────
276
+
277
+ def esc(t):
278
+ return str(t).replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
279
+
280
+
281
+ def summary(s):
282
+ ink = (f'<span class="sw" style="background:{SWATCH.get(s["ink_from"], "#6E6A62")}">'
283
+ f'</span>{esc(s["ink_from"])}')
284
+ if not s["monochrome"]:
285
+ ink += (f' <span class="sw" style="background:'
286
+ f'{SWATCH.get(s["ink_to"], "#6E6A62")}"></span>{esc(s["ink_to"])}')
287
+ return (f'<p class="sum">{ink} &nbsp;Β·&nbsp; {esc(s["format"])} &nbsp;Β·&nbsp; '
288
+ f'{s["pieces"]} pieces &nbsp;Β·&nbsp; best before {esc(s["best_before"])} '
289
+ f'&nbsp;Β·&nbsp; batch {esc(s["batch"])}</p>')
290
+
291
+
292
+ def log_html(lines):
293
+ body = "".join(
294
+ f'<div class="l {c}"><span class="t">{esc(t)}</span>'
295
+ f'<span class="s">{esc(m)}</span></div>' for t, m, c in lines)
296
+ return f'<div class="log">{body}</div>'
297
+
298
+
299
+ # ─────────────────────────────────────────────────────────────────────
300
+ # Flow
301
+ # ─────────────────────────────────────────────────────────────────────
302
+
303
+ S = {}
304
+
305
+
306
+ def search(account):
307
+ account = (account or "").strip()
308
+ if not account:
309
+ return gr.update(choices=[], value=None), '<p class="note">Enter an account.</p>'
310
+ try:
311
+ rows = list_dead(account)
312
+ except Exception as e:
313
+ return gr.update(choices=[], value=None), \
314
+ f'<p class="note err">Could not read account. {esc(e)}</p>'
315
+ if not rows:
316
+ return gr.update(choices=[], value=None), \
317
+ '<p class="note">No dead spaces on this account.</p>'
318
+ choices = [f'{r["name"]} Β· {r["stage"]} Β· {r["moved"]}' for r in rows]
319
+ S["map"] = dict(zip(choices, [r["id"] for r in rows]))
320
+ return (gr.update(choices=choices, value=None),
321
+ f'<p class="note">{len(rows)} dead</p>')
322
+
323
+
324
+ def select(label):
325
+ if not label:
326
+ return "", gr.update(interactive=False)
327
+ spec = to_spec(*get_grave(S["map"][label]))
328
+ S["spec"] = spec
329
+ return summary(spec), gr.update(interactive=True)
330
+
331
+
332
+ def generate(profile: gr.OAuthProfile | None = None):
333
+ spec = S.get("spec")
334
+ if spec is None:
335
+ yield gr.update(), '<p class="note">Select a space first.</p>'
336
+ return
337
+ if ON_SPACE and profile is None:
338
+ yield gr.update(), ('<p class="note err">Sign in to generate. '
339
+ 'Passes run against your own ZeroGPU allowance.</p>')
340
+ return
341
+
342
+ t0 = time.time()
343
+ lines = []
344
+
345
+ def stamp():
346
+ return f"{time.time() - t0:.1f}s"
347
+
348
+ held = from_archive(spec["repo"])
349
+ if held is not None:
350
+ lines.append((stamp(), "cached β€” issued from archive", "ok"))
351
+ yield gr.update(value=held), log_html(lines)
352
+ return
353
+
354
+ hero = Image.open(HERO_PATH).convert("RGB")
355
+ img = hero
356
+ lines.append((stamp(), f"hero loaded Β· {hero.width}Γ—{hero.height}", "ok"))
357
+ yield gr.update(), log_html(lines)
358
+
359
+ for i, (label, prompt) in enumerate(build_chain(spec), 1):
360
+ lines.append(("…", f"{i} Β· {label}", "run"))
361
+ yield gr.update(), log_html(lines)
362
+ img = run_pass([img, hero], prompt)
363
+ lines[-1] = (stamp(), f"{i} Β· {label}", "ok")
364
+ yield gr.update(value=img), log_html(lines)
365
+
366
+ if ARCHIVE_REPO and HF_TOKEN:
367
+ try:
368
+ to_archive(spec["repo"], img, spec)
369
+ lines.append((stamp(), "archived", "ok"))
370
+ except Exception:
371
+ lines.append((stamp(), "archive write failed β€” not retained", "err"))
372
+ else:
373
+ lines.append((stamp(), "no archive configured β€” not retained", "err"))
374
+ yield gr.update(value=img), log_html(lines)
375
+
376
+
377
+ # ─────────────────────────────────────────────────────────────────────
378
+ # Interface
379
+ # ─────────────────────────────────────────────────────────────────────
380
+
381
+ HEAD = """
382
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
383
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet">
384
+ """
385
+
386
+ CSS = """
387
+ :root{
388
+ --bg:#0D0F0E; --panel:#141816; --panel-2:#1B201D;
389
+ --border:#2A312C; --border-hi:#3C453E;
390
+ --fg:#CBD3CC; --dim:#77837A;
391
+ --amber:#E0A33E; --amber-dim:#8A6725; --alert:#C9553D;
392
+ }
393
+ .gradio-container{
394
+ background:var(--bg)!important; color:var(--fg)!important;
395
+ font-family:'IBM Plex Sans',system-ui,sans-serif!important;
396
+ max-width:1280px!important; margin:0 auto!important; font-size:14px;
397
+ }
398
+ .gradio-container .block,.gradio-container .form{
399
+ background:var(--panel)!important; border:1px solid var(--border)!important;
400
+ border-radius:8px!important; box-shadow:none!important;
401
+ }
402
+ footer{display:none!important}
403
+
404
+ #head .intro{color:var(--dim); max-width:78ch; margin:2px 0 4px;
405
+ line-height:1.6; font-size:13.5px}
406
+
407
+ label span,.gradio-container label{color:var(--dim)!important; font-size:11px!important;
408
+ letter-spacing:.06em}
409
+ input[type=text],textarea,select,.gradio-container input{
410
+ background:var(--panel-2)!important; border:1px solid var(--border-hi)!important;
411
+ color:var(--fg)!important; border-radius:6px!important;
412
+ font-family:'IBM Plex Mono',monospace!important; font-size:13px!important;
413
+ }
414
+ input[type=text]:focus{outline:2px solid var(--amber)!important}
415
+ button.primary{background:var(--amber)!important; color:#14100A!important;
416
+ border:0!important; font-weight:600!important; border-radius:6px!important}
417
+ button.primary:hover{background:#F0B44E!important}
418
+ button.secondary{background:var(--panel-2)!important; color:var(--fg)!important;
419
+ border:1px solid var(--border-hi)!important; border-radius:6px!important}
420
+ button:disabled{background:var(--panel-2)!important; color:var(--dim)!important}
421
+
422
+ table{width:100%; border-collapse:collapse;
423
+ font-family:'IBM Plex Mono',monospace; font-size:12.5px}
424
+ th{text-align:left; font-weight:500; color:var(--dim); font-size:10.5px;
425
+ letter-spacing:.08em; text-transform:uppercase; padding:6px 10px 6px 0;
426
+ border-bottom:1px solid var(--border-hi)}
427
+ td{padding:7px 10px 7px 0; border-bottom:1px solid var(--border); vertical-align:top}
428
+ tr:last-child td{border-bottom:0}
429
+ tbody tr:hover td{background:var(--panel-2)}
430
+ .num{text-align:right; padding-right:0!important; color:var(--dim)}
431
+ .stage{color:var(--alert)}
432
+ .dim{color:var(--dim)}
433
+ table.spec th{width:150px; text-transform:none; letter-spacing:0; font-size:12.5px;
434
+ border-bottom:1px solid var(--border); padding:7px 12px 7px 0}
435
+ .sw{display:inline-block; width:9px; height:9px; margin-right:6px;
436
+ border:1px solid var(--border-hi)}
437
+
438
+ .sum{font-family:'IBM Plex Mono',monospace; font-size:12px; color:var(--dim);
439
+ margin:2px 0 0; line-height:1.9}
440
+ .note{color:var(--dim); font-size:12.5px; margin:6px 0 0}
441
+ .note.err{color:var(--alert)}
442
+
443
+ .log{font-family:'IBM Plex Mono',monospace; font-size:12.5px; min-height:150px}
444
+ .log .l{padding:2.5px 0; color:var(--dim); display:flex; gap:12px}
445
+ .log .l .t{color:var(--border-hi); flex:0 0 52px}
446
+ .log .l.ok .s{color:var(--fg)}
447
+ .log .l.run .s{color:var(--amber)}
448
+ .log .l.err .s{color:var(--alert)}
449
+ @media (prefers-reduced-motion:reduce){*{transition:none!important}}
450
+ """
451
+
452
+ with gr.Blocks(title="All The Best") as demo:
453
+
454
+ gr.HTML("""
455
+ <div id="head">
456
+ <p class="intro">Dead Hugging Face Spaces rendered as boxes of chocolates.
457
+ Each box is generated from the Space's own data β€” its colours, commit log,
458
+ dependencies and final commit date β€” through six sequential image-to-image
459
+ passes on Qwen-Image-Edit-2511. The interest is in the text: how much printed
460
+ detail survives across a chain of edits, and what has to be explicitly named
461
+ to stop it being overwritten.</p>
462
+ </div>""")
463
+
464
+ with gr.Row(equal_height=False):
465
+
466
+ # ── left: pick a space ─��──────────────────────────────────
467
+ with gr.Column(scale=4):
468
+ with gr.Row():
469
+ account = gr.Textbox(label="Account", value="jbilcke-hf", scale=3)
470
+ find = gr.Button("Search", variant="primary", scale=1)
471
+
472
+ space = gr.Dropdown(label="Dead space", choices=[], interactive=True)
473
+ info = gr.HTML()
474
+
475
+ with gr.Row():
476
+ if ON_SPACE:
477
+ login = gr.LoginButton(scale=1)
478
+ go = gr.Button("Generate box Β· 6 passes", variant="primary",
479
+ interactive=False, scale=2)
480
+
481
+ # ── right: the box ────────────────────────────────────────
482
+ with gr.Column(scale=6):
483
+ box = gr.Image(label="Box", height=430, show_label=False)
484
+ log_out = gr.HTML(
485
+ f'<div class="log"><div class="l"><span class="t">β€”</span>'
486
+ f'<span class="s">qwen-image-edit-2511 Β· {STEPS}-step Β· '
487
+ f'{"stub" if STUB_MODEL else "live"}</span></div></div>')
488
+
489
+ find.click(search, account, [space, info])
490
+ account.submit(search, account, [space, info])
491
+ space.change(select, space, [info, go])
492
+ go.click(generate, None, [box, log_out])
493
+
494
+ if __name__ == "__main__":
495
+ # Gradio 6 takes theme/css/head at launch, not on Blocks.
496
+ demo.launch(theme=gr.themes.Base(), css=CSS, head=HEAD)
hero/HERO_burgundy-gold_nanobanana.jpeg ADDED

Git LFS Details

  • SHA256: 9aecd412953702afb1a40d876a0e4a4ec2b39f02a4f3e329974038c43c8be0cc
  • Pointer size: 131 Bytes
  • Size of remote file: 756 kB
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=6.0
2
+ huggingface_hub>=0.28
3
+ Pillow
4
+ # --- uncomment when STUB_MODEL = False ---
5
+ # torch
6
+ # diffusers @ git+https://github.com/huggingface/diffusers
7
+ # transformers
8
+ # accelerate
9
+ # peft
10
+ # spaces