Compare commits

..

18 Commits

Author SHA1 Message Date
Austin Mroz
510c6c4cec Add test 2026-05-25 20:54:56 -07:00
Austin Mroz
0132e462c8 Update image batch calculations 2026-05-25 18:03:03 -07:00
imick-io
08ee925811 theme-aware favicon for light and dark mode (#12457)
## Summary

Serve separate SVG favicons via prefers-color-scheme so the icon stays
legible against both light and dark browser chrome. Drop the
unreferenced favicon.svg / favicon.png; keep favicon.ico as the legacy
fallback.

## Changes

- What: apps/website/src/layouts/BaseLayout.astro now links
favicon-light.svg and favicon-dark.svg gated on prefers-color-scheme,
with favicon.ico retained as the legacy fallback. Unreferenced
favicon.svg / favicon.png removed from apps/website/public/.

## Review Focus

- Naming convention: favicon-light.svg is the asset served in light mode
(dark-backgrounded icon for contrast against light chrome);
favicon-dark.svg is served in dark mode. Confirm this matches
expectation.
- Safari fallback: older Safari versions ignore prefers-color-scheme on
<link rel="icon"> and will fall through to favicon.ico — that file is
unchanged and should look acceptable in both modes.

## Screenshots

Dark mode:
<img width="224" height="30" alt="image"
src="https://github.com/user-attachments/assets/5fa3c620-0021-4c90-bc18-013cd6ef45cf"
/>

Light mode:
<img width="227" height="28" alt="image"
src="https://github.com/user-attachments/assets/54a130e1-f976-46e8-b047-e27efe22e479"
/>
2026-05-25 19:20:41 +00:00
AustinMroz
fb5b4a62ba Fix mask editor sometimes showing wrong image (#12413)
Mask editor checks `node.images` to determine the image which is edited.
If the user generates an output image in litegraph mode, swaps to vue
mode, then generates a new image, the mask editor will incorrectly
display the image last shown in litegraph mode.

This is resolved by having `syncLegacyNodeImgs` also synchronize node
outputs to `node.images`.
2026-05-25 18:37:10 +00:00
pythongosssss
cb62604d21 feat: map more custom node loaders to asset picker (#12340)
## Summary

Updates the following node mappings to show the new model picker dialog:
- DynamiCrafterModelLoader > checkpoints
(d312c62982/nodes.py (L367))
- DynamiCrafterCNLoader > controlnet
(d312c62982/nodes.py (L217))
- MelBandRoFormerModelLoader > diffusion_models
(92c86854e6/nodes.py (L31))
- INPAINT_LoadFooocusInpaint > inpaint (head + patch inputs)
(b32f293d3f/nodes.py (L129))
- AILab_QwenVL_Advanced > LLM/Qwen-VL/* (10 variants) ( "model_name":
"Pick the Qwen-VL checkpoint. First run downloads weights into
models/LLM/Qwen-VL, so leave disk space.",)

## Changes

- **What**:  Add custom node mappings

## Review Focus

## Screenshots (if applicable)

<!-- Add screenshots or video recording to help explain your changes -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-12340-feat-map-more-custom-node-loaders-to-asset-picker-3656d73d365081929c0dc9179a9e9c67)
by [Unito](https://www.unito.io)
2026-05-25 18:35:53 +00:00
Terry Jia
d02c5d374f chore: tidy up retain-view-on-reload follow-ups (#12441)
## Summary
Drop a no-op cn() wrapper on the static camera-switch icon and trim the
two over-long comments around setRetainViewOnReload / _loadModelInternal
down to one line each.
2026-05-25 17:20:08 +00:00
jaeone94
c0ef283a05 General execution error messaging (#12448)
## Summary

This PR builds on the error catalog display resolver foundation from
#12402 and adds the first broader catalog pass for general
execution-related messaging. The goal is to keep the raw API contract
intact (`message` / `details`) while adding resolved display fields that
the UI can prefer when catalog copy exists.

The main functional sample in this PR is validation error messaging. It
expands the resolver beyond `required_input_missing` so common node
validation failures can show friendlier titles, grouped messages, detail
copy, item labels, and toast copy without overwriting the original
backend payload.

## What changed

- Added catalog copy for known node validation errors:
  - `required_input_missing` as `missing_connection`
  - `bad_linked_input`
  - `return_type_mismatch`
  - `invalid_input_type`
  - `value_smaller_than_min`
  - `value_bigger_than_max`
  - `value_not_in_list`
  - `custom_validation_failed`
  - `exception_during_inner_validation`
  - `exception_during_validation`
  - `dependency_cycle`
- Added an `image_not_loaded` validation override for
`custom_validation_failed` messages that indicate invalid image files or
directory paths.
- Added value-aware validation details when Core provides structured
`extra_info`, including received values, expected/received types, and
min/max bounds.
- Added prompt-level catalog handling for known prompt errors that
already have stable types/copy, including missing node type, prompt
output validation, image download, and OOM prompt errors.
- Preserved runtime execution errors as raw API copy for now, so
service-level or actionable runtime failures are not hidden behind
generic catalog text before targeted runtime handling lands.
- Added/updated English `errorCatalog` i18n keys for the new validation
and prompt catalog copy.
- Added resolver and grouping tests for the new catalog paths, raw
fallback behavior, runtime raw preservation, prompt copy, and
image-not-loaded detection.

## Screenshots (diff)
### Before  
<img width="371" height="346" alt="Old_1"
src="https://github.com/user-attachments/assets/bd474869-7428-4f68-a067-bb412aa95d3b"
/>
<img width="373" height="296" alt="Old_2"
src="https://github.com/user-attachments/assets/fc393792-dc6d-46fb-b7df-20290b35e30e"
/>
<img width="370" height="292" alt="Old_3"
src="https://github.com/user-attachments/assets/bcb867ea-12ba-49b7-887a-ce06afa60475"
/>
<img width="370" height="269" alt="Old_4"
src="https://github.com/user-attachments/assets/05caeff8-2597-4c95-97cf-2736825b85f3"
/>
<img width="371" height="292" alt="Old_5"
src="https://github.com/user-attachments/assets/dd58113e-5953-4701-b597-d59cb6e124e9"
/>
<img width="373" height="282" alt="Old_6"
src="https://github.com/user-attachments/assets/60fb02c0-4ed6-4734-926c-f8a20f0aeb1c"
/>
<img width="371" height="279" alt="Old_7"
src="https://github.com/user-attachments/assets/a3453b5c-c779-4f43-af27-97cc9a083480"
/>
<img width="370" height="292" alt="Old_8"
src="https://github.com/user-attachments/assets/59d08636-c1b3-4cde-a340-befb48726ee8"
/>
<img width="371" height="276" alt="Old_9"
src="https://github.com/user-attachments/assets/7a94465b-ed5c-4ad9-a40a-cfe3c08d3dc7"
/>
<img width="368" height="279" alt="Old_10"
src="https://github.com/user-attachments/assets/3f791ff3-e3e3-4cb7-aab1-640ec1cee751"
/>
<img width="370" height="276" alt="Old_11"
src="https://github.com/user-attachments/assets/9c0f28c2-4f60-4f38-b3c4-5560609e329e"
/>
<img width="370" height="279" alt="Old_12"
src="https://github.com/user-attachments/assets/4b61545e-db7e-4512-b300-e883ab37f347"
/>

### After
<img width="426" height="301" alt="New_1"
src="https://github.com/user-attachments/assets/9874c036-2b3d-4b7c-ac3d-cb9c396c597f"
/>
<img width="421" height="301" alt="New_2"
src="https://github.com/user-attachments/assets/38cd0f35-53a4-490a-b47f-da21eaa44fc8"
/>
<img width="418" height="347" alt="New_3"
src="https://github.com/user-attachments/assets/db5ab3cc-f246-407d-b80b-9ad92c95c7ad"
/>
<img width="425" height="327" alt="New_4"
src="https://github.com/user-attachments/assets/4333c2b8-3077-4122-9719-21d56a7b2230"
/>
<img width="424" height="325" alt="New_5"
src="https://github.com/user-attachments/assets/6616d61f-fa90-4d2f-b8fd-50ac5a3f32cb"
/>
<img width="423" height="326" alt="New_6"
src="https://github.com/user-attachments/assets/02a4f97a-708e-4c00-b061-d8e4dcaacd8f"
/>
<img width="424" height="323" alt="New_7"
src="https://github.com/user-attachments/assets/9d1e96c9-69de-4e26-a152-1a101675c5eb"
/>
<img width="425" height="327" alt="New_8"
src="https://github.com/user-attachments/assets/ffa66faf-1a33-43a3-b604-25352195f28c"
/>
<img width="425" height="323" alt="New_9"
src="https://github.com/user-attachments/assets/f7eb5f0c-4d0c-4f1b-aa3d-30358fbc9943"
/>
<img width="423" height="328" alt="New_10"
src="https://github.com/user-attachments/assets/72665c97-ec61-4e5a-b702-379baf919822"
/>
<img width="423" height="351" alt="New_11"
src="https://github.com/user-attachments/assets/c5376f02-7a62-42e6-9cda-e50ab6d41b04"
/>
<img width="425" height="326" alt="New_12"
src="https://github.com/user-attachments/assets/413df105-dc7e-4289-90b0-30ecaa417c84"
/>


## Intentional boundaries


This PR does not add targeted runtime/cloud-specific message matching
yet. Runtime execution errors still use the original exception message
and traceback in the error panel. This is intentional because
cloud/service runtime errors can include actionable strings such as
auth, payment, rate limit, timeout, moderation, or infrastructure
failures, and collapsing those too early would make the UX worse.

This PR also does not change the overlay or right-side panel design. It
only prepares and fills resolved display fields so the next stacked PRs
can consume them with much less plumbing.

## Follow-up PR plan

- Add targeted runtime/cloud-specific messaging for high-volume errors
such as credits, timeouts, disallowed content, rate limit,
sign-in/payment requirements, and server crash style failures.
- Revisit runtime execution grouping once runtime catalog IDs are
explicit enough to group by message category rather than node class or
raw exception text.
- Update the error overlay to use single-error toast title/message
fields and multi-error aggregate copy.
- Update the right-side error panel design, including item labels such
as `Node name - input/widget name`.
- Consider splitting `errorMessageResolver.ts` by error family
(`validation`, `prompt`, `runtime`, `cloud-specific`) before adding more
runtime-specific rules.

## Validation

- `pnpm exec vitest run
src/platform/errorCatalog/errorMessageResolver.test.ts
src/components/rightSidePanel/errors/useErrorGroups.test.ts`
- `pnpm typecheck`
- Commit hooks ran staged formatting, lint fixes, and `pnpm typecheck`.
- Push hook ran `knip --cache`; it completed with an existing tag-hint
warning for `src/scripts/metadata/flac.ts`.
2026-05-25 12:54:47 +00:00
Dante
d405002127 fix(widgets): collapse duplicate COLOR widget rendering on Color to RGB Int (FE-842) (#12447)
## Summary

Fix the duplicate \`<WidgetColorPicker>\` rendering on the \`Color to
RGB Int\` node (and any other COLOR-using V3 node that the runtime
double-registers a widget for).
<img width="480" alt="after-fix-dedupe-proof"
src="https://github.com/user-attachments/assets/5c801806-ed5d-493f-92b6-e0b99dd8e408"
/>

## Changes

- **What**:
- \`useProcessedWidgets.getWidgetIdentity\`: fall back to the host
\`nodeId\` parameter for the dedupe identity root when neither
\`storeNodeId/widget.nodeId\` nor \`sourceExecutionId\` is set. Normal
root-graph widgets now dedupe identically to promoted/execution-scoped
widgets, so any duplicate same-name+same-type widget collapses to one
render. \`sourceExecutionId\` precedence is preserved.
- \`useColorWidget\`: read top-level \`default\` from the V2 spec (falls
back to nested \`options.default\` for hand-authored V2 specs), and
short-circuit if a same-name color widget already exists on
\`node.widgets\` so a second \`addWidget('color', …)\` call from
upstream hooks (or a \`configure\` round-trip) no longer duplicates the
row.
- **Tests**:
- New \`useColorWidget.test.ts\` covers top-level default,
nested-options fallback, no-default fallback, and the idempotency guard.
- \`useProcessedWidgets.test.ts\` gets a regression case for two
identical color widgets on the same node collapsing to one render, plus
an updated \`getWidgetIdentity\` case for the host-nodeId fallback.

## Review Focus

- \`getWidgetIdentity\` precedence change. The fallback only fires when
none of \`storeNodeId\`, \`widget.nodeId\`, or \`sourceExecutionId\` are
present, so promoted/exec-scoped widgets (incl. the \"unresolved
same-name promoted entries distinct by source execution identity\"
\`NodeWidgets\` test) are unaffected.
- \`useColorWidget\` idempotency guard is defensive — the root cause of
the second \`addWidget\` call (cloud-only hook or persisted
\`info.widgets\` configure round-trip) is not in this diff; that's
tracked separately.

Fixes
[FE-842](https://linear.app/comfyorg/issue/FE-842/color-to-rgb-int-node-shows-duplicate-color-widgets)
2026-05-25 11:33:58 +00:00
pythongosssss
abd233d10d feat: default search to essentials when graph is empty (#12377)
## Summary

Currently, when opening node search on an empty graph, the default view
shows "Most Relevant" nodes, which includes nodes like CLIP and VAE. For
users building from scratch, these nodes are not necessarily the most
helpful starting point.

## Changes

- **What**: 
- Update default mode to Essentials when graph is empty

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-12377-feat-default-search-to-essentials-when-graph-is-empty-3666d73d3650816d9d5ae3ed602a30ec)
by [Unito](https://www.unito.io)
2026-05-25 09:35:52 +00:00
Comfy Org PR Bot
e1049a99a3 1.46.1 (#12445)
Patch version increment to 1.46.1

**Base branch:** `main`

---------

Co-authored-by: christian-byrne <72887196+christian-byrne@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
2026-05-25 01:33:11 +00:00
Jukka Seppänen
3da6e1766e feat: optional retain camera view on Load3D model reload (#12440)
When comparing outputs from 3D generations, it's very hard to see small
differences since the camera always resets. This adds an option to lock
the camera, so only the model refreshes.

## Summary

Adds an opt-in per-node toggle that preserves the current camera view
(position, target, zoom, camera type) across model loads in Load3D /
Load3DAnimation nodes, instead of resetting to default framing.

## Changes

- **What**: New `retainViewOnReload?: boolean` field on `CameraConfig`,
a `Load3d.setRetainViewOnReload()` setter wired through the existing
`useLoad3d` camera-config watcher, capture/restore logic in
`Load3d._loadModelInternal`, and a lock-icon toggle button in
`CameraControls.vue` below the FOV slider. Preference persists via the
existing `node.properties['Camera Config']` mechanism.

## Review Focus

- **First-load semantics**: retain only kicks in once a model has
successfully loaded at least once (`hasLoadedModel` flag), so the
default `setupForModel` framing wins on a fresh node. `clearModel()`
resets the flag so the next load also reframes.
- **Restore order vs. `SceneModelManager.setupModel`**: the scene model
manager unconditionally calls `setupForModel` during a load, which
clobbers the camera. The restore in `_loadModelInternal` runs *after*
the load completes, on top of that framing.
- **Camera-type mismatch**: if the saved state's `cameraType` differs
from the currently active camera, `toggleCamera()` runs before
`setCameraState()` so the perspective/orthographic camera being restored
is actually the active one. Covered by a dedicated test.
- **Scope**: only wired through `useLoad3d` (LiteGraph node controls).
The full-page viewer (`useLoad3dViewer` / `ViewerCameraControls`) is
deliberately not extended — the modal is mostly a one-shot
view-and-close flow, so retain there would add surface area for an
uncommon use case.
- **Failed loads**: `hasLoadedModel` only flips inside `if
(modelManager.currentModel)`, so a load that produces no model leaves
the flag where it was. Captured camera state is still applied on top,
which effectively no-ops since nothing reset it.


## Video


https://github.com/user-attachments/assets/880d6ad1-28a9-4413-83a3-8323d05d904a
2026-05-23 08:47:30 -04:00
Comfy Org PR Bot
52830a9e73 1.46.0 (#12439)
Minor version increment to 1.46.0

**Base branch:** `main`

---------

Co-authored-by: dante01yoon <6510430+dante01yoon@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
2026-05-23 18:16:38 +09:00
Comfy Org PR Bot
1cd98e8ab2 1.45.14 (#12432)
Patch version increment to 1.45.14

**Base branch:** `main`

---------

Co-authored-by: christian-byrne <72887196+christian-byrne@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
2026-05-23 02:36:28 +00:00
jaeone94
654a7d6904 Add error catalog display resolver (#12402)
## Summary

This PR introduces the frontend error catalog display resolver as the
foundation for the DES-220 / FE-816 error messaging work.

The main goal is to create a single FE boundary where raw Core/Cloud
error payloads can be converted into human-friendly display fields,
while preserving the original API contract fields (`message` and
`details`) unchanged. UI components can now prefer resolved display copy
when it exists and fall back to the raw API copy otherwise.

As a small concrete sample, this PR implements the first cataloged
validation error:

- `required_input_missing` is resolved as the `missing_connection`
catalog item.
- Panel title: `Missing connection`
- Panel message: `Required input slots have no connection feeding them.`
- Detail/item copy can include the node and input name, e.g. `KSampler
is missing a required input: model` and `KSampler - model`.
- Single-error toast/overlay-oriented fields are added to the data model
for follow-up UI work, but this PR does not redesign the overlay.

## What This PR Targets

This PR is intentionally scoped as the skeleton PR for the error catalog
UX system.

It adds:

- A new resolver module under `src/platform/errorCatalog`.
- Shared resolved display fields:
  - `catalogId`
  - `displayTitle`
  - `displayMessage`
  - `displayDetails`
  - `displayItemLabel`
  - `toastTitle`
  - `toastMessage`
- A resolver entry point for run-time workflow errors:
  - node validation errors
  - execution/runtime errors
  - prompt errors
- A resolver entry point for pre-run missing-resource groups:
  - missing node packs
  - swap nodes
  - missing models
  - missing media
- Error group wiring so `useErrorGroups` resolves display copy in one
place instead of making UI components own message decisions.
- The first real validation rule for `required_input_missing` / Missing
connection.
- The existing prompt error copy moved into the
`errorCatalog.promptErrors` namespace in `src/locales/en/main.json`.
- Tests covering the resolver, grouping behavior, panel rendering,
prompt error copy, missing group copy, and fallback behavior.

## What This PR Deliberately Does Not Target

This PR avoids the larger UX and product behavior changes so the
foundation can land separately.

It does not:

- Redesign the error overlay.
- Redesign the right-side error panel.
- Change the shape of Core/Cloud API error payloads.
- Replace raw `message` / `details`; those remain intact for
API-contract alignment and technical debugging.
- Re-group execution errors by final message type yet.
- Add special runtime error messaging for credits, timeouts, content
policy, OOM, or rate limits.
- Render the new `displayItemLabel` everywhere it will eventually be
useful.

## User-Facing Behavior

Most behavior is preserved.

The main visible change is for missing required input validation errors.
Those now display as Missing connection copy instead of exposing the raw
validation message directly.

Prompt errors should keep the same user-facing wording as before, but
the source of that wording now lives under the error catalog namespace.

Missing node/model/media/swap-node groups still preserve the existing
titles, counts, and friendly messages, but their display copy now flows
through the same resolver boundary.

Execution/runtime errors receive catalog fields for future toast/overlay
usage, but the current runtime overlay path intentionally keeps the raw
technical error copy until the overlay redesign PR decides how to
consume the new fields.

## Screenshots 
Before
<img width="505" height="266" alt="스크린샷 2026-05-22 오후 2 15 27"
src="https://github.com/user-attachments/assets/09e8eb31-dca4-42d8-8237-9474cb71a14c"
/>
<img width="463" height="317" alt="스크린샷 2026-05-22 오후 2 16 09"
src="https://github.com/user-attachments/assets/c0a0159e-5bd9-4b3f-9c21-c0040373fbca"
/>

After
<img width="482" height="297" alt="스크린샷 2026-05-22 오후 2 14 25"
src="https://github.com/user-attachments/assets/4ca10bf0-29d2-4b65-940e-0d78db3fd278"
/>
<img width="460" height="194" alt="스크린샷 2026-05-22 오후 2 16 55"
src="https://github.com/user-attachments/assets/20848054-5012-4dd3-b903-ef8c920f70c8"
/>


## Follow-Up PR Plan

This PR is the first stacked PR in the error catalog work. Follow-up PRs
are expected to build on this foundation in roughly this order:

1. Expand general execution error messaging.
- Add broader validation error handling beyond `required_input_missing`,
including list/range/value validation cases.
   - Add general runtime execution messaging.
- Continue migrating prompt error display decisions into the catalog
resolver.

2. Add special runtime error messaging.
   - Credits / insufficient credits.
   - Timeout.
   - Content not allowed / blocked content.
   - Server crash.
   - Out of memory.
   - Rate limiting.
   - Other high-volume Cloud-only runtime failures from DES-220.

3. Re-group execution errors by message/catalog type.
- Move away from grouping primarily by node class when the cataloged
error type is the more useful user-facing grouping key.
   - Keep raw technical details available inside cards/logs.

4. Update the error overlay behavior.
   - Use `toastTitle` and `toastMessage` for single-error cases.
   - Use aggregate copy such as "N errors found" for multi-error cases.
   - Add node navigation affordances where appropriate.

5. Update the right-side error panel design.
   - Render resolved item labels such as `Node name - Input name`.
   - Align expanded card details and logs with the new design.
   - Preserve copy/debug affordances for technical details.

6. Fold in related missing media/model/node messaging improvements.
- FE-583 should become a child/follow-up issue in this stack for
improving missing image/media messaging.

## Validation

- `pnpm format`
- `pnpm lint`
- `pnpm typecheck`
- `pnpm test:unit`
- Targeted resolver/grouping tests during review iterations
- `pnpm knip`

`pnpm knip` passes with only the pre-existing tag hint:

`Unused tag in src/scripts/metadata/flac.ts: getFromFlacBuffer →
@knipIgnoreUnusedButUsedByCustomNodes`
2026-05-23 01:31:29 +00:00
imick-io
eeeacc9b03 feat(website): constrain sections to max-w-9xl on wide screens (#12428)
Add max-w-9xl mx-auto to section/container wrappers across the website
so layout stays centered and capped at 96rem on screens wider than
1536px.

## Summary

<!-- One sentence describing what changed and why. -->

## Changes

- **What**: <!-- Core functionality added/modified -->
- **Breaking**: <!-- Any breaking changes (if none, remove this line)
-->
- **Dependencies**: <!-- New dependencies (if none, remove this line)
-->

## Review Focus

<!-- Critical design decisions or edge cases that need attention -->

<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->

## Screenshots (if applicable)

<!-- Add screenshots or video recording to help explain your changes -->

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 21:36:29 +00:00
Terry Jia
f744a4f1f8 chore: gitignore .nx daemon workspace data (#12427)
## Summary
add .nx to gitignore as it causes some workspace-cache now
2026-05-22 19:45:44 +00:00
Terry Jia
0588ca45b3 test: remove stale primevue mocks from load3d tests (#12350)
## Summary
The load3d components no longer import primevue/select or
primevue/checkbox, so the vi.mock blocks targeting them had no effect.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-12350-test-remove-stale-primevue-mocks-from-load3d-tests-3666d73d365081f692dbe91e16d594c3)
by [Unito](https://www.unito.io)
2026-05-22 19:32:18 +00:00
Daxiong (Lin)
60ce0ee0c3 Add png and ico favicon for comfy.org (#12426) 2026-05-22 11:55:41 -07:00
238 changed files with 6935 additions and 834 deletions

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@ yarn.lock
node_modules
.pnpm-store
.nx
dist
dist-ssr
*.local

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,4 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" rx="12" fill="#F0EFED"/>
<path d="M31.0126 30.4797C31.0576 30.3275 31.0822 30.1671 31.0822 29.9985C31.0822 29.0649 30.3294 28.3081 29.4006 28.3081H21.8643C21.4593 28.3122 21.1279 27.9832 21.1279 27.576C21.1279 27.5019 21.1401 27.432 21.1565 27.3662L23.1858 20.259C23.2717 19.9465 23.5581 19.7161 23.8936 19.7161L31.4586 19.7079C33.0542 19.7079 34.4003 18.6262 34.8053 17.1497L35.9427 13.1889C35.9795 13.0491 36 12.8969 36 12.7447C36 11.8152 35.2513 11.0625 34.3266 11.0625H25.1742C23.5868 11.0625 22.2448 12.136 21.8316 13.5961L21.0624 16.2983C20.9724 16.6068 20.6901 16.833 20.3546 16.833H18.1575C16.5823 16.833 15.2526 17.8859 14.8271 19.3295L12.0614 29.0402C12.0205 29.1841 12 29.3404 12 29.4967C12 30.4304 12.7528 31.1871 13.6816 31.1871H15.8418C16.2468 31.1871 16.5782 31.5162 16.5782 31.9275C16.5782 31.9974 16.5701 32.0673 16.5496 32.1331L15.7845 34.8107C15.7477 34.9546 15.7232 35.1027 15.7232 35.2549C15.7232 36.1844 16.4719 36.937 17.3965 36.937L26.553 36.9288C28.1446 36.9288 29.4865 35.8512 29.8957 34.3829L31.0085 30.4838L31.0126 30.4797Z" fill="#211927"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,11 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3062_2148)">
<path d="M36.8451 0H11.1549C4.99423 0 0 4.99423 0 11.1549V36.8451C0 43.0058 4.99423 48 11.1549 48H36.8451C43.0058 48 48 43.0058 48 36.8451V11.1549C48 4.99423 43.0058 0 36.8451 0Z" fill="#211927"/>
<path d="M31.0126 30.48C31.0576 30.3278 31.0822 30.1674 31.0822 29.9987C31.0822 29.0651 30.3294 28.3083 29.4006 28.3083H21.8643C21.4592 28.3124 21.1278 27.9834 21.1278 27.5762C21.1278 27.5022 21.1401 27.4323 21.1565 27.3665L23.1858 20.2593C23.2718 19.9467 23.5581 19.7164 23.8936 19.7164L31.4586 19.7082C33.0542 19.7082 34.4001 18.6264 34.8054 17.1499L35.9429 13.1891C35.9794 13.0493 36 12.8971 36 12.7449C36 11.8154 35.2513 11.0627 34.3268 11.0627H25.1742C23.5868 11.0627 22.2448 12.1362 21.8316 13.5963L21.0624 16.2985C20.9724 16.607 20.6901 16.8332 20.3546 16.8332H18.1575C16.5823 16.8332 15.2526 17.8861 14.8271 19.3298L12.0614 29.0404C12.0205 29.1844 12 29.3407 12 29.4969C12 30.4306 12.7528 31.1874 13.6816 31.1874H15.8418C16.2469 31.1874 16.5783 31.5164 16.5783 31.9277C16.5783 31.9976 16.5701 32.0675 16.5496 32.1334L15.7845 34.8109C15.7477 34.9549 15.7231 35.1029 15.7231 35.255C15.7231 36.1846 16.4719 36.9374 17.3965 36.9374L26.553 36.929C28.1446 36.929 29.4865 35.8513 29.8957 34.3833L31.0085 30.4841L31.0126 30.48Z" fill="#F2FF59"/>
</g>
<defs>
<clipPath id="clip0_3062_2148">
<rect width="48" height="48" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,14 +0,0 @@
<svg width="48" height="48" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #000000; }
.fg { fill: #F2FF59; }
@media (prefers-color-scheme: dark) {
.bg { fill: #F2FF59; }
.fg { fill: #000000; }
}
</style>
<circle class="bg" cx="24" cy="24" r="24"/>
<g transform="translate(7.8 6.72) scale(0.72)">
<path class="fg" d="M35.6487 36.021C35.733 35.7387 35.7791 35.4411 35.7791 35.1283C35.7791 33.3963 34.3675 31.9924 32.6262 31.9924H18.4956C17.7361 32 17.1147 31.3896 17.1147 30.6342C17.1147 30.4969 17.1377 30.3672 17.1684 30.2451L20.9734 17.0606C21.1345 16.4807 21.6715 16.0534 22.3005 16.0534L36.4848 16.0382C39.4766 16.0382 42.0005 14.0315 42.76 11.2923L44.8926 3.94468C44.9616 3.68526 45 3.40296 45 3.12065C45 1.39628 43.5961 0 41.8624 0L24.7017 0C21.7252 0 19.209 1.99142 18.4342 4.70005L16.992 9.71292C16.8232 10.2852 16.2939 10.7048 15.6648 10.7048H11.5453C8.59189 10.7048 6.0987 12.6581 5.30089 15.3362L0.11507 33.3505C0.0383566 33.6175 0 33.9075 0 34.1974C0 35.9294 1.41152 37.3333 3.15292 37.3333H7.20338C7.96284 37.3333 8.58421 37.9437 8.58421 38.7067C8.58421 38.8364 8.56887 38.9661 8.53051 39.0882L7.09598 44.0553C7.02694 44.3224 6.98091 44.597 6.98091 44.8794C6.98091 46.6037 8.38476 48 10.1185 48L27.2869 47.9847C30.2711 47.9847 32.7873 45.9857 33.5544 43.2618L35.641 36.0286L35.6487 36.021Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -10,7 +10,7 @@ const { locale = 'en' } = defineProps<{ locale?: Locale }>()
</script>
<template>
<section class="px-6 py-24 lg:px-20 lg:py-32">
<section class="max-w-9xl mx-auto px-6 py-24 lg:px-20 lg:py-32">
<GlassCard
class="mx-auto mt-20 flex flex-col gap-12 lg:flex-row lg:items-stretch lg:gap-8"
>

View File

@@ -74,7 +74,7 @@ useHeroAnimation({
</div>
<!-- Video -->
<div ref="videoRef" class="px-4 pb-20 lg:px-20 lg:pb-40">
<div ref="videoRef" class="max-w-9xl mx-auto px-4 pb-20 lg:px-20 lg:pb-40">
<VideoPlayer
src="https://media.comfy.org/website/about/co-founders.webm"
poster="https://media.comfy.org/website/about/co-founders-poster.webp"

View File

@@ -33,7 +33,7 @@ const values: {
</script>
<template>
<section class="px-6 py-24 lg:px-20 lg:py-32">
<section class="max-w-9xl mx-auto px-6 py-24 lg:px-20 lg:py-32">
<div class="mx-auto max-w-5xl text-center">
<SectionLabel>
{{ t('about.values.label', locale) }}

View File

@@ -16,7 +16,7 @@ const investors = [
</script>
<template>
<section class="px-6 py-24 lg:px-20 lg:py-32">
<section class="max-w-9xl mx-auto px-6 py-24 lg:px-20 lg:py-32">
<div class="mx-auto text-center">
<span
class="text-primary-comfy-yellow text-xs font-semibold tracking-widest uppercase"

View File

@@ -14,7 +14,7 @@ const reasons: TranslationKey[] = [
</script>
<template>
<section class="px-6 py-24 lg:px-20 lg:py-32">
<section class="max-w-9xl mx-auto px-6 py-24 lg:px-20 lg:py-32">
<WireNodeLayout :reasons right-card-padding="p-6" :locale="locale">
<template #right-card>
<img

View File

@@ -41,7 +41,7 @@ function toggle(index: number) {
</script>
<template>
<section class="px-4 py-24 md:px-20 md:py-40">
<section class="max-w-9xl mx-auto px-4 py-24 md:px-20 md:py-40">
<div class="flex flex-col gap-6 md:flex-row md:gap-16">
<!-- Left heading -->
<div

View File

@@ -46,7 +46,9 @@ const cards = excludeProduct
</script>
<template>
<section class="bg-primary-comfy-ink px-0 py-20 lg:px-20 lg:py-24">
<section
class="bg-primary-comfy-ink max-w-9xl mx-auto px-0 py-20 lg:px-20 lg:py-24"
>
<!-- Header -->
<div class="flex flex-col items-center px-4 text-center">
<SectionLabel v-if="labelKey">

View File

@@ -45,11 +45,11 @@ const progressPercent = computed(() => `${progress.value * 100}%`)
</script>
<template>
<section class="px-6 py-16 lg:px-16 lg:py-24">
<section class="max-w-9xl mx-auto px-6 py-16 lg:px-16 lg:py-24">
<!-- Scrollable track -->
<div
ref="trackRef"
class="scrollbar-none flex snap-x snap-mandatory gap-12 overflow-x-auto lg:gap-20"
class="flex snap-x snap-mandatory scrollbar-none gap-12 overflow-x-auto lg:gap-20"
>
<div
v-for="(fb, i) in feedbacks"

View File

@@ -72,7 +72,7 @@ function handleLogoLoad() {
</div>
<!-- Video -->
<div ref="videoRef" class="px-4 pb-20 lg:px-20 lg:pb-40">
<div ref="videoRef" class="max-w-9xl mx-auto px-4 pb-20 lg:px-20 lg:pb-40">
<VideoPlayer
src="https://media.comfy.org/website/customers/blackmath/video.webm"
poster="https://media.comfy.org/website/customers/blackmath/poster.webp"

View File

@@ -10,7 +10,7 @@ const prefix = locale === 'zh-CN' ? '/zh-CN' : ''
<template>
<section
class="grid grid-cols-1 gap-6 px-6 py-16 lg:grid-cols-2 lg:px-16 lg:py-24"
class="max-w-9xl mx-auto grid grid-cols-1 gap-6 px-6 py-16 lg:grid-cols-2 lg:px-16 lg:py-24"
>
<a
v-for="story in customerStories"

View File

@@ -7,7 +7,7 @@ const { locale = 'en' } = defineProps<{ locale?: Locale }>()
</script>
<template>
<section class="px-6 py-16 lg:px-20 lg:py-40">
<section class="max-w-9xl mx-auto px-6 py-16 lg:px-20 lg:py-40">
<VideoPlayer
src="https://media.comfy.org/website/customers/silverside/video.webm"
poster="https://media.comfy.org/website/customers/silverside/poster.webp"

View File

@@ -7,7 +7,7 @@ const { locale = 'en' } = defineProps<{ locale?: Locale }>()
<template>
<section
class="flex flex-col items-center px-4 pt-16 pb-24 text-center lg:px-20 lg:pt-20 lg:pb-40"
class="max-w-9xl mx-auto flex flex-col items-center px-4 pt-16 pb-24 text-center lg:px-20 lg:pt-20 lg:pb-40"
>
<span
class="text-primary-comfy-yellow text-sm font-bold tracking-widest uppercase"

View File

@@ -223,7 +223,10 @@ while (idx < items.length) {
</script>
<template>
<section data-testid="gallery-grid" class="px-4 pb-20 lg:px-20">
<section
data-testid="gallery-grid"
class="max-w-9xl mx-auto px-4 pb-20 lg:px-20"
>
<!-- Desktop grid -->
<div
class="rounded-5xl bg-transparency-white-t4 hidden flex-col gap-2 p-2 lg:flex"

View File

@@ -8,7 +8,9 @@ const { locale = 'en' } = defineProps<{ locale?: Locale }>()
</script>
<template>
<section class="flex flex-col items-center px-6 pt-36 pb-16 text-center">
<section
class="max-w-9xl mx-auto flex flex-col items-center px-6 pt-36 pb-16 text-center"
>
<SectionLabel>
{{ t('gallery.label', locale) }}
</SectionLabel>

View File

@@ -15,7 +15,7 @@ const row2 = [
<template>
<section
class="bg-primary-comfy-ink flex flex-col items-center px-4 py-24 lg:px-6 lg:py-32"
class="bg-primary-comfy-ink max-w-9xl mx-auto flex flex-col items-center px-4 py-24 lg:px-6 lg:py-32"
>
<!-- Node rows -->
<div

View File

@@ -12,7 +12,9 @@ const routes = getRoutes(locale)
</script>
<template>
<section class="bg-primary-comfy-ink px-4 py-20 lg:px-20 lg:py-24">
<section
class="bg-primary-comfy-ink max-w-9xl mx-auto px-4 py-20 lg:px-20 lg:py-24"
>
<GlassCard
class="flex flex-col gap-12 lg:flex-row lg:items-stretch lg:gap-8"
>

View File

@@ -36,7 +36,9 @@ const steps = [
</script>
<template>
<section class="bg-primary-comfy-ink px-4 py-20 lg:px-20 lg:py-24">
<section
class="bg-primary-comfy-ink max-w-9xl mx-auto px-4 py-20 lg:px-20 lg:py-24"
>
<div class="flex flex-col gap-12 lg:flex-row lg:gap-8">
<!-- Left heading -->
<div

View File

@@ -15,7 +15,7 @@ const { loaded: logoLoaded } = useHeroLogo(logoContainer)
<template>
<section
class="relative flex min-h-auto flex-col lg:flex-row lg:items-center"
class="max-w-9xl relative mx-auto flex min-h-auto flex-col lg:flex-row lg:items-center"
>
<div
ref="logoContainer"

View File

@@ -55,7 +55,10 @@ watch(activeIndex, (current, previous) => {
</script>
<template>
<section ref="sectionRef" class="px-4 py-20 lg:px-20 lg:py-24">
<section
ref="sectionRef"
class="max-w-9xl mx-auto px-4 py-20 lg:px-20 lg:py-24"
>
<!-- Section header -->
<div class="flex flex-col items-center text-center">
<NodeBadge :segments="badgeSegments" segment-class="" />

View File

@@ -121,7 +121,7 @@ const activePlanIndex = ref(0)
</script>
<template>
<section class="px-4 py-16 lg:px-20 lg:py-14">
<section class="max-w-9xl mx-auto px-4 py-16 lg:px-20 lg:py-14">
<!-- Header -->
<div class="mx-auto mb-8 max-w-3xl text-center lg:mb-10">
<h1
@@ -135,7 +135,7 @@ const activePlanIndex = ref(0)
</div>
<!-- Mobile plan tabs -->
<div class="scrollbar-none mb-6 flex gap-2 overflow-x-auto lg:hidden">
<div class="mb-6 flex scrollbar-none gap-2 overflow-x-auto lg:hidden">
<button
v-for="(plan, index) in plans"
:key="plan.id"

View File

@@ -60,7 +60,7 @@ const features: IncludedFeature[] = [
</script>
<template>
<section class="px-4 py-16 lg:px-20 lg:py-24">
<section class="max-w-9xl mx-auto px-4 py-16 lg:px-20 lg:py-24">
<div class="mx-auto w-full lg:grid lg:grid-cols-[280px_1fr] lg:gap-x-16">
<!-- Heading -->
<div

View File

@@ -25,7 +25,7 @@ const cards = [
</script>
<template>
<section class="px-4 pt-24 lg:px-20 lg:pt-40">
<section class="max-w-9xl mx-auto px-4 pt-24 lg:px-20 lg:pt-40">
<h2
class="text-primary-comfy-canvas text-3.5xl/tight mx-auto max-w-3xl text-center font-light lg:text-5xl/tight"
>

View File

@@ -10,7 +10,7 @@ const { locale = 'en' } = defineProps<{ locale?: Locale }>()
<template>
<section
class="bg-transparency-white-t4 rounded-5xl mx-4 mt-4 mb-24 p-2 lg:mx-20 lg:mt-8 lg:mb-40"
class="bg-transparency-white-t4 rounded-5xl max-w-9xl mx-auto mt-4 mb-24 p-2 px-4 lg:mt-8 lg:mb-40 lg:px-20"
>
<div
class="bg-primary-comfy-yellow flex flex-col gap-24 rounded-4xl p-8 lg:flex-row lg:items-end lg:justify-between"

View File

@@ -442,7 +442,7 @@ onBeforeUnmount(() => {
</script>
<template>
<section class="px-4 py-24 lg:px-20">
<section class="max-w-9xl mx-auto px-4 py-24 lg:px-20">
<GlassCard
class="flex flex-col gap-8 lg:flex-row lg:items-stretch lg:gap-16"
>

View File

@@ -10,7 +10,7 @@ const { locale = 'en' } = defineProps<{ locale?: Locale }>()
</script>
<template>
<section class="px-4 py-24 lg:px-20 lg:py-40">
<section class="max-w-9xl mx-auto px-4 py-24 lg:px-20 lg:py-40">
<div
class="bg-transparency-white-t4 rounded-5xl flex flex-col-reverse items-stretch gap-10 p-2 lg:flex-row lg:gap-8"
>

View File

@@ -77,7 +77,9 @@ function getCardClass(layoutClass: string): string {
</script>
<template>
<section class="bg-primary-comfy-ink px-4 py-24 lg:px-20 lg:py-40">
<section
class="bg-primary-comfy-ink max-w-9xl mx-auto px-4 py-24 lg:px-20 lg:py-40"
>
<div class="mx-auto flex w-full max-w-7xl flex-col items-center">
<p
class="text-primary-comfy-yellow text-center text-sm font-bold tracking-widest uppercase"

View File

@@ -11,7 +11,7 @@ defineProps<{
</script>
<template>
<section class="px-4 py-24 lg:px-20">
<section class="max-w-9xl mx-auto px-4 py-24 lg:px-20">
<SectionHeader>
{{ heading }}
<template v-if="subtitle" #subtitle>

View File

@@ -22,7 +22,7 @@ defineProps<{
</script>
<template>
<section class="px-4 py-24 lg:px-20">
<section class="max-w-9xl mx-auto px-4 py-24 lg:px-20">
<SectionHeader>
{{ heading }}
<template #subtitle>

View File

@@ -29,7 +29,7 @@ const {
<template>
<section
class="flex flex-col gap-4 px-4 py-24 lg:flex-row lg:gap-16 lg:px-20 lg:py-40"
class="max-w-9xl mx-auto flex flex-col gap-4 px-4 py-24 lg:flex-row lg:gap-16 lg:px-20 lg:py-40"
>
<!-- Left heading -->
<div

View File

@@ -71,7 +71,20 @@ const websiteJsonLd = {
{noindex && <meta name="robots" content="noindex, nofollow" />}
<title>{title}</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link
rel="icon"
href="/favicon-light.svg"
type="image/svg+xml"
media="(prefers-color-scheme: light)"
/>
<link
rel="icon"
href="/favicon-dark.svg"
type="image/svg+xml"
media="(prefers-color-scheme: dark)"
/>
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="canonical" href={canonicalURL.href} />
<link rel="preconnect" href="https://www.googletagmanager.com" />
<link rel="dns-prefetch" href="https://www.googletagmanager.com" />

View File

@@ -51,6 +51,20 @@ export class FeatureFlagHelper {
})
}
async setServerFlags(flags: Record<string, unknown>): Promise<void> {
await this.page.evaluate((flagMap: Record<string, unknown>) => {
const api = window.app!.api
api.serverFeatureFlags.value = {
...api.serverFeatureFlags.value,
...flagMap
}
}, flags)
}
async setServerFlag(name: string, value: unknown): Promise<void> {
await this.setServerFlags({ [name]: value })
}
/**
* Mock server feature flags via route interception on /api/features.
*/

View File

@@ -128,7 +128,8 @@ export const TestIds = {
pinIndicator: 'node-pin-indicator',
innerWrapper: 'node-inner-wrapper',
mainImage: 'main-image',
slotConnectionDot: 'slot-connection-dot'
slotConnectionDot: 'slot-connection-dot',
imageGrid: 'image-grid'
},
selectionToolbox: {
root: 'selection-toolbox',

View File

@@ -15,7 +15,9 @@ export class VueNodeFixture {
public readonly root: Locator
public readonly widgets: Locator
public readonly imagePreview: Locator
public readonly imageGrid: Locator
public readonly content: Locator
public readonly resize: { br: Locator }
constructor(private readonly locator: Locator) {
this.header = locator.locator('[data-testid^="node-header-"]')
@@ -28,7 +30,9 @@ export class VueNodeFixture {
this.root = locator
this.widgets = this.locator.locator('.lg-node-widget')
this.imagePreview = locator.locator('.image-preview')
this.imageGrid = locator.getByTestId(TestIds.node.imageGrid)
this.content = locator.locator('.lg-node-content')
this.resize = { br: locator.getByRole('button', { name: 'bottom-right' }) }
}
async getTitle(): Promise<string> {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Some files were not shown because too many files have changed in this diff Show More