media:cpp globs, cache
@ -60,6 +60,36 @@ FetchContent_Declare(
|
||||
|
||||
FetchContent_MakeAvailable(cli11 asio nlohmann_json cpp_httplib)
|
||||
|
||||
# PicoSHA2 — header-only SHA256 for cache keys.
|
||||
FetchContent_Declare(
|
||||
picosha2
|
||||
GIT_REPOSITORY https://github.com/okdshin/PicoSHA2.git
|
||||
GIT_TAG master
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_GetProperties(picosha2)
|
||||
if(NOT picosha2_POPULATED)
|
||||
FetchContent_Populate(picosha2)
|
||||
endif()
|
||||
|
||||
# p-ranav/glob — same as packages/kbot/cpp (glob / rglob for **).
|
||||
FetchContent_Declare(
|
||||
pranav_glob
|
||||
GIT_REPOSITORY https://github.com/p-ranav/glob.git
|
||||
GIT_TAG master
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_GetProperties(pranav_glob)
|
||||
if(NOT pranav_glob_POPULATED)
|
||||
FetchContent_Populate(pranav_glob)
|
||||
endif()
|
||||
add_library(pranav_glob STATIC ${pranav_glob_SOURCE_DIR}/source/glob.cpp)
|
||||
target_include_directories(pranav_glob PUBLIC ${pranav_glob_SOURCE_DIR}/include)
|
||||
target_compile_features(pranav_glob PUBLIC cxx_std_17)
|
||||
if(MSVC)
|
||||
target_compile_options(pranav_glob PRIVATE /permissive-)
|
||||
endif()
|
||||
|
||||
# laserpants/dotenv-cpp — load .env (same pattern as packages/kbot/cpp).
|
||||
FetchContent_Declare(
|
||||
laserpants_dotenv
|
||||
@ -79,6 +109,8 @@ find_package(Vips REQUIRED)
|
||||
|
||||
add_executable(media-img
|
||||
src/main.cpp
|
||||
src/core/cache.cpp
|
||||
src/core/glob_paths.cpp
|
||||
src/core/resize.cpp
|
||||
src/http/serve.cpp
|
||||
src/ipc/ipc_serve.cpp
|
||||
@ -87,6 +119,7 @@ add_executable(media-img
|
||||
target_include_directories(media-img PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
${asio_SOURCE_DIR}/asio/include
|
||||
${picosha2_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(media-img PRIVATE
|
||||
@ -107,6 +140,7 @@ target_link_libraries(media-img PRIVATE
|
||||
nlohmann_json::nlohmann_json
|
||||
httplib::httplib
|
||||
laserpants::dotenv
|
||||
pranav_glob
|
||||
Vips::vips
|
||||
)
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ CMake-based **`media-img`** binary: **CLI**, **HTTP REST** (`serve`), and **line
|
||||
| CMake | ≥ 3.20 |
|
||||
| C++ compiler | C++17 |
|
||||
| **libvips** | **Required** — pkg-config (Unix) or `third_party/vips-dev-*` / `VIPS_ROOT` (Windows) |
|
||||
| Git | For `FetchContent` (CLI11, Asio, httplib, json, dotenv) |
|
||||
| Git | For `FetchContent` (CLI11, Asio, httplib, json, dotenv, [p-ranav/glob](https://github.com/p-ranav/glob), [PicoSHA2](https://github.com/okdshin/PicoSHA2) for cache keys) |
|
||||
| Node.js | Optional — `npm run test:media` (Node 18+) |
|
||||
|
||||
### Installing libvips
|
||||
@ -79,9 +79,104 @@ Sharp wraps libvips: **decode → process → encode**. We do the same with `vip
|
||||
| `flip` / `flop` | `flip` / `flop` | |
|
||||
| Letterbox | `background` | `#rrggbb` for `contain` |
|
||||
|
||||
**REST** `POST /v1/resize` accepts the same keys as columns in the table (plus `input`, `output` paths).
|
||||
**REST** `POST /v1/resize` and **IPC** use the same JSON keys as the table, plus the fields in the **“Batch paths & cache”** section below.
|
||||
|
||||
**IPC** sends one JSON object per line with the same keys.
|
||||
---
|
||||
|
||||
## Batch paths & cache: globs, variables, caching
|
||||
|
||||
Use this when **one** `resize` invocation (CLI, or a single REST/IPC request) should match **many** inputs or build **per-file** output paths. See also [docs/Examples.md](../docs/Examples.md) (TypeScript / Sharp reference).
|
||||
|
||||
### Summary
|
||||
|
||||
| Topic | What it does |
|
||||
|-------|----------------|
|
||||
| **Input glob** | `*` / `?` / `**` in `input` expand to a list of files ([p-ranav/glob](https://github.com/p-ranav/glob)). |
|
||||
| **Destination variables** | `output` may contain `${SRC_DIR}`, `${SRC_NAME}`, `${SRC_FILE_EXT}` (or `&{…}`) — expanded **per matched input**. |
|
||||
| **expand_glob** | JSON `false`: treat `input` / `output` as literal paths (no glob expansion). Templates still apply if `output` contains `${SRC_` / `&{SRC_`. |
|
||||
| **Output cache** | SHA-256 key from input path + size + mtime + options; default dir `<cwd>/cache/images/`. |
|
||||
|
||||
**Not supported in C++:** Bash **extglob** (e.g. `*.+(jpg)`). Use `*.jpg`, `**/*.jpg`, or separate runs. **Bare** `{SRC_NAME}` without `$` / `&` is not a placeholder — use `${SRC_NAME}` or `&{SRC_NAME}`.
|
||||
|
||||
### Input globs
|
||||
|
||||
- **Syntax:** `*`, `?`, and `**` for recursion. Paths are resolved from the current working directory unless absolute.
|
||||
- **Multiple files → directory output:** `output` must be an **existing** directory, **or** a **new** directory given with a **trailing** `/` or `\` (parent dirs are created).
|
||||
- **Single file** from a literal path or a glob that matches one file: `output` can be a full file path, or a directory (trailing sep) to keep the original filename.
|
||||
|
||||
**CLI:** use positional `input`/`output` or `--src` / `--dst` together.
|
||||
|
||||
```bash
|
||||
./dist/media-img resize './photos/**/*.jpg' ./out/
|
||||
./dist/media-img resize --src './shots/*.png' --dst ./thumbs/
|
||||
```
|
||||
|
||||
**JSON:** same strings in `"input"` and `"output"`. When `expand_glob` is true (default), glob expansion runs when the pattern contains `*`, `?`, or `**`.
|
||||
|
||||
### Destination variables (`${SRC_*}` / `&{SRC_*}`)
|
||||
|
||||
Placeholders are expanded **after** inputs are resolved (glob or single file). Each output path is built from the **absolute** input file for that row.
|
||||
|
||||
| Placeholder | Meaning |
|
||||
|-------------|---------|
|
||||
| **SRC_DIR** | Parent directory of the current input (generic path, `/` separators). |
|
||||
| **SRC_NAME** | Filename **stem** without extension (`photo` for `photo.JPG`). |
|
||||
| **SRC_FILE_EXT** | Extension **with** leading dot (e.g. `.jpg`), or empty if none. |
|
||||
|
||||
Use cases: write beside each source (`${SRC_DIR}/out/${SRC_NAME}.webp`), suffix stems (`${SRC_NAME}_thumb.jpg`), or change extension via `format` / path.
|
||||
|
||||
```bash
|
||||
./dist/media-img resize --src ./photo.jpg --dst '${SRC_DIR}/${SRC_NAME}_medium.jpg' --max-width 800
|
||||
./dist/media-img resize --src './shots/*.jpg' --dst '${SRC_DIR}/${SRC_NAME}.webp' --max-width 1920
|
||||
```
|
||||
|
||||
**REST / IPC** — same strings in JSON (escape quotes in shell as needed):
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:8080/v1/resize \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"input":"/data/in.png","output":"/out/${SRC_NAME}_thumb.webp","max_width":256}'
|
||||
```
|
||||
|
||||
**Responses:** `{"ok":true}` for a single output; if more than one file is produced, `{"ok":true,"count":N,"outputs":["..."]}`.
|
||||
|
||||
### JSON reference (batch + cache)
|
||||
|
||||
| Field | Type | Default | Purpose |
|
||||
|-------|------|---------|---------|
|
||||
| `input` | string | required | Source path or glob. |
|
||||
| `output` | string | required | File path, directory, or template with `${SRC_*}` / `&{SRC_*}`. |
|
||||
| `expand_glob` | bool | `true` | If `false`, no glob expansion; paths are literal. |
|
||||
| `cache` | bool | `true` (or server default from `serve` / `ipc` flags) | Enable/disable cache for this request. |
|
||||
| `cache_dir` | string | empty → `<cwd>/cache/images` (or server `--cache-dir`) | Root directory for cached blobs. |
|
||||
|
||||
All **resize** options (`max_width`, `fit`, …) participate in the same JSON body.
|
||||
|
||||
### Output cache
|
||||
|
||||
- **Default:** caching is **on**; root dir **`cache/images`** under the process **current working directory** (override with `--cache-dir` or JSON `cache_dir`).
|
||||
- **Key:** **SHA-256** (PicoSHA2) over canonical input path, file size, modification time, and a stable encoding of **all** resize options — change any of these and you get a miss.
|
||||
- **Storage:** `<cache_dir>/XX/<hex>` (two-letter shard).
|
||||
- **Hit:** copy cached bytes to `output`; **libvips is not initialized** for that job.
|
||||
- **Miss:** run resize, then **best-effort** store into cache (failure to store does not fail the request).
|
||||
|
||||
**CLI (`resize`):** `--no-cache`, `--cache-dir <path>`.
|
||||
|
||||
**`serve` / `ipc`:** same flags set **defaults** for requests that omit `cache` / `cache_dir`. Per-request JSON can still set `"cache": true` or `"cache_dir": "/path"` to override.
|
||||
|
||||
**Batch + cache:** glob batches run **sequentially** (one file after another); each file may hit or miss the cache independently.
|
||||
|
||||
### `serve` example with cache and glob
|
||||
|
||||
```bash
|
||||
./dist/media-img serve --host 127.0.0.1 -p 8080 --cache-dir /var/cache/media-img
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:8080/v1/resize \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"input":"/data/in/*.jpg","output":"/data/out/","max_width":400,"cache":true,"cache_dir":"/var/cache/media-img"}'
|
||||
```
|
||||
|
||||
## Concurrency
|
||||
|
||||
@ -174,14 +269,18 @@ curl -s -X POST http://127.0.0.1:8080/v1/resize \
|
||||
-d '{"input":"/path/in.png","output":"/path/out.webp","max_width":400,"quality":80}'
|
||||
```
|
||||
|
||||
Optional: `"cache":false`, `"expand_glob":false`, `"cache_dir":"..."` — see **Batch paths & cache** above.
|
||||
|
||||
### `ipc` — one JSON line per connection (TCP; Unix socket on Linux/macOS)
|
||||
|
||||
```bash
|
||||
./dist/media-img ipc --host 127.0.0.1 -p 9333
|
||||
./dist/media-img ipc --host 127.0.0.1 -p 9333 --cache-dir ./cache/images
|
||||
# elsewhere: send a single line, read one line back, e.g.
|
||||
# {"input":"/tmp/a.jpg","output":"/tmp/b.webp","max_width":320,"format":"webp"}
|
||||
# {"input":"/tmp/a.jpg","output":"/tmp/b.webp","max_width":320,"format":"webp","cache":true}
|
||||
```
|
||||
|
||||
Same JSON fields as REST (`input`, `output`, globs, `expand_glob`, `cache`, `cache_dir`, resize options).
|
||||
|
||||
### `kbot` — forward to another binary (optional)
|
||||
|
||||
Requires **`KBOT_EXE`** pointing at the kbot executable; remaining args are passed through.
|
||||
@ -199,6 +298,8 @@ npm run test:media
|
||||
|
||||
Requires a built `dist/media-img` **linked against libvips** and fixture PNGs (`npm run generate:assets` if missing).
|
||||
|
||||
The suite covers **REST**, **IPC (TCP)**, optional **Unix socket** on non-Windows, **destination templates** (`npm run test:media:templates`), and **recursive glob + `${SRC_DIR}` / `${SRC_NAME}`** (`npm run test:media:glob` — outputs under `tests/assets/glob-in/**/out/`, gitignored, for manual inspection).
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](LICENSE) in this directory when present.
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
# Media image service (C++) — rollout plan
|
||||
|
||||
## Goals
|
||||
|
||||
- **CLI**: resize files on disk (batch-friendly, scripts).
|
||||
- **REST**: HTTP server for resize jobs (Node or other clients).
|
||||
- **IPC**: async socket server — **Unix domain socket** on Linux/macOS; **TCP loopback** on Windows (Asio does not ship portable UDS on Windows; optional **named pipe** phase later).
|
||||
|
||||
## Dependencies (CMake / FetchContent)
|
||||
|
||||
| Component | Choice | Notes |
|
||||
|-----------|--------|--------|
|
||||
| CLI | [CLI11](https://github.com/CLIUtils/CLI11) | Same pattern as `kbot/cpp`. |
|
||||
| Async I/O | [Asio](https://think-async.com/Asio/) (standalone) | UDS + accept loop; no Boost linkage. |
|
||||
| HTTP | [cpp-httplib](https://github.com/yhirose/cpp-httplib) | Header-only REST; good for a dedicated worker. |
|
||||
| JSON | [nlohmann/json](https://github.com/nlohmann/json) | Request/response bodies. |
|
||||
| Images (v1) | [stb](https://github.com/nothings/stb) | No system install; PNG/JPEG in-tree. |
|
||||
| Images (later) | **libvips** | Optional `find_package` / vcpkg when you need parity with Sharp speed/quality. |
|
||||
|
||||
## Phases
|
||||
|
||||
### Phase 0 — Scaffold (this PR)
|
||||
|
||||
- CMake presets `dev` / `release`, output `dist/media-img(.exe)`.
|
||||
- `npm run build:release` green on Windows MSVC.
|
||||
|
||||
### Phase 1 — Core + CLI
|
||||
|
||||
- `resize` command: input path, output path, max width/height, format (png/jpeg).
|
||||
- Single-threaded; deterministic errors to stderr.
|
||||
|
||||
### Phase 2 — REST
|
||||
|
||||
- `serve --bind --port`: `GET /health`, `POST /v1/resize` (JSON with paths or raw body + query params — v1 uses file paths for simplicity).
|
||||
|
||||
### Phase 3 — IPC
|
||||
|
||||
- `ipc --listen <path|host:port>`: line-delimited or length-prefixed JSON requests (documented in `docs/ipc-protocol.md` stub).
|
||||
- Linux: Unix socket. Windows: TCP `127.0.0.1:<port>` (or named pipe in a follow-up).
|
||||
|
||||
### Phase 4 — Production hardening
|
||||
|
||||
- Optional libvips backend behind `MEDIA_USE_VIPS`.
|
||||
- Worker pool, request limits, metrics.
|
||||
- CI: Linux + Windows matrix.
|
||||
|
||||
## npm scripts
|
||||
|
||||
- `npm run build:release` — configure + build Release.
|
||||
- `npm run run` — `dist/media-img --help`.
|
||||
BIN
packages/media/cpp/cache/images/00/005790ced6597aef81d01d2addbad574b3b545a7d82e104715c952a40ed22c99
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/media/cpp/cache/images/00/0087635e962c75857a3b1f450655bf6c07e7911e71d90196ea8b1add284a1cf8
vendored
Normal file
|
After Width: | Height: | Size: 727 B |
BIN
packages/media/cpp/cache/images/01/01759d578fd3575efb0df8c6e6f643a580c2e5e63bbfaa97489b1c6ea76e98bb
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/media/cpp/cache/images/01/01f40f430d0ff8b0c16d522f573209b6b5f7f97106188d9c14f57f6f60bbcd70
vendored
Normal file
|
After Width: | Height: | Size: 723 B |
BIN
packages/media/cpp/cache/images/02/0258a6361b9f0b789b8eb050921afb07dad08c48e95afb134f00df299eda94ef
vendored
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
packages/media/cpp/cache/images/04/04e1395ca2a8c84708d173f658ad2c2d236a3d6b730fd8c94ffcfb81f30e708b
vendored
Normal file
|
After Width: | Height: | Size: 714 B |
BIN
packages/media/cpp/cache/images/05/050c2cf80708c6a3876ed86bac40ec554d9d3f71d30567b6b769b78425b1ad2f
vendored
Normal file
|
After Width: | Height: | Size: 746 B |
BIN
packages/media/cpp/cache/images/07/07459a43ef692c109a29bd0e58d9120a249132fbf826c9027c7dbaebc418e3a7
vendored
Normal file
|
After Width: | Height: | Size: 707 B |
BIN
packages/media/cpp/cache/images/07/0753cb440c0d371c8d2fd3869cd5a51d976295433ef6028d2ce9c8cd8b8390f1
vendored
Normal file
|
After Width: | Height: | Size: 771 B |
BIN
packages/media/cpp/cache/images/07/07b8cfbcd822edbe2e721549d319a9bcaabd6c98829a13832dfa95f69225e930
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/0a/0a81c9fad0398b1e13b4524ad6450c9884a9b25b193bf5e450ecaea3d9e71115
vendored
Normal file
|
After Width: | Height: | Size: 666 B |
BIN
packages/media/cpp/cache/images/0a/0aed912bc0ccff6841644b0a8d9e94893682511644f1ed297396f44090af4f84
vendored
Normal file
|
After Width: | Height: | Size: 748 B |
BIN
packages/media/cpp/cache/images/0c/0c461c12da982822607459f30cdc3c76c19758d8a95801c70d0b8a240af92e31
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/0d/0d188d061c354aea1e02c6fc6134f5c35222636cda511f19bf4862d909776934
vendored
Normal file
|
After Width: | Height: | Size: 694 B |
BIN
packages/media/cpp/cache/images/0d/0dfb3249ad37196dcef3be680940509221814ba22e08942a00f4e14a37a5639c
vendored
Normal file
|
After Width: | Height: | Size: 677 B |
BIN
packages/media/cpp/cache/images/0e/0e013d2fd19b2ab21ecbe4c497924952b941f1cf4264f49a9d21a28aae363340
vendored
Normal file
|
After Width: | Height: | Size: 716 B |
BIN
packages/media/cpp/cache/images/0f/0f8bddc1f12252d78b7fe2671dca4733595d12208c08a0c1b369cd8b877d1180
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/media/cpp/cache/images/10/10bef2088a3683216c40ac68c626d84a6a0ecf27e0bed15de125681d084c7605
vendored
Normal file
|
After Width: | Height: | Size: 720 B |
BIN
packages/media/cpp/cache/images/12/12c703785e24aa598af7e08f8c151f647834b14cdea6b743c80cd29f2b08309e
vendored
Normal file
|
After Width: | Height: | Size: 695 B |
BIN
packages/media/cpp/cache/images/12/12d8c1dada66775311b4fb6b730fde7cba91c6a0a9e3e8980686b2c98e3e2111
vendored
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
packages/media/cpp/cache/images/12/12fab9e8d620afc4a45c613de013b7cb8391229222e8ab5193d8144e3fb73109
vendored
Normal file
|
After Width: | Height: | Size: 682 B |
BIN
packages/media/cpp/cache/images/13/13ea0681e7cecd842f5436d4c92fce2a983b71b59f6af5d517fd5b03e9d7a4fd
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/14/140dd182742694f46e1879f99fddd45594dfa6a7d846a617668cce18939cef3a
vendored
Normal file
|
After Width: | Height: | Size: 697 B |
BIN
packages/media/cpp/cache/images/14/144f25dab17dff1f7a94a0ce0b74b1c3787c6a480113da9848f7d0697aa4ac3f
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/15/1510c3d5fd494f802f49ab63840872b855148dc393900f3e5824146932709ec3
vendored
Normal file
|
After Width: | Height: | Size: 680 B |
BIN
packages/media/cpp/cache/images/15/15268845b87528318c43659af8f56e8459b13101be3a1087a65f235dfa9902c1
vendored
Normal file
|
After Width: | Height: | Size: 693 B |
BIN
packages/media/cpp/cache/images/15/1572a5eb3227e6b184e1f3d33766a79808296f548aa79b3f0679bfd13e254ebf
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/15/15f73115f4bf7abe19d8d1b5957e65ad4c8fee904c7f9547c9db33c5c287cf0f
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/15/15f79154ff845554279e4e0cb3fd085f84077df7caf5af753202e0b7a9cf5446
vendored
Normal file
|
After Width: | Height: | Size: 660 B |
BIN
packages/media/cpp/cache/images/18/181924777df58295b68a5f94baed60edd23c841f1c887c7e25407bd385fd1406
vendored
Normal file
|
After Width: | Height: | Size: 691 B |
BIN
packages/media/cpp/cache/images/18/189881b68eb28347a7685a531a7a590429e3681d725e4dce68daff775f4fb6c2
vendored
Normal file
|
After Width: | Height: | Size: 717 B |
BIN
packages/media/cpp/cache/images/18/18b2b80786b801e68b0a746383066489254ee9fff8687b76f7584b324ea767ba
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/19/19cb568d994f22bea84c5c7297e960ef614adb59a8ad2bc8cabf7cadbe8a96dd
vendored
Normal file
|
After Width: | Height: | Size: 756 B |
BIN
packages/media/cpp/cache/images/1a/1af9dfda72578c678e5df5bbb8eefb6c71b6e84bf4387cc8b4b2111ee03e5578
vendored
Normal file
|
After Width: | Height: | Size: 693 B |
BIN
packages/media/cpp/cache/images/1b/1b543faca1e2c10b1daf8b5506735c5ef26a5362d02dcbd0735ecdb6d1d05c3d
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/1c/1cf5ccaa4761739cc9afb229b180eb360623188b96a69844da08a66144bb65da
vendored
Normal file
|
After Width: | Height: | Size: 669 B |
BIN
packages/media/cpp/cache/images/1d/1deb9e593ca7b849ee769b83a32b12cae1d554e283808f81b84bb5aadddf842b
vendored
Normal file
|
After Width: | Height: | Size: 680 B |
BIN
packages/media/cpp/cache/images/1e/1eb201f9ce6eeff0c78fc3fb545a70e50bd8b6d475766cf2051726bea7c017c1
vendored
Normal file
|
After Width: | Height: | Size: 696 B |
BIN
packages/media/cpp/cache/images/1e/1eeaff6ad98b68e2d59caf9ae69d0e3e881de45d82dacad7a4032293bfa01b8d
vendored
Normal file
|
After Width: | Height: | Size: 662 B |
BIN
packages/media/cpp/cache/images/20/20c018bc27398d85dc3782ab9b2447a4f2ede4698220b7a09ef48d01e5fb5583
vendored
Normal file
|
After Width: | Height: | Size: 706 B |
BIN
packages/media/cpp/cache/images/21/217a8d0d2f72e354956c8b55541c0c6720a5af2b7c872437521a726e1ad25ead
vendored
Normal file
|
After Width: | Height: | Size: 724 B |
BIN
packages/media/cpp/cache/images/21/21ca9f94bb37acd37381e23491ae8dce9f27704bbf67bc0f93098b495dce2c4b
vendored
Normal file
|
After Width: | Height: | Size: 688 B |
BIN
packages/media/cpp/cache/images/22/22b435dcd5a6bf20c40e61ee033bcfd2ca269b341b9250000f4b0cd8fb8de64d
vendored
Normal file
|
After Width: | Height: | Size: 671 B |
BIN
packages/media/cpp/cache/images/23/2300b581bec307711b85cb2bd9e93b7412e2dbb35228bb323a01e295aa7f02bf
vendored
Normal file
|
After Width: | Height: | Size: 646 B |
BIN
packages/media/cpp/cache/images/24/24c99cfb50da4bcbbc52fdd2be27cea7ec91c5b6ccb9d349176385db1acdf72c
vendored
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
packages/media/cpp/cache/images/25/25a9da917141a9e316b9705e2b80922bd689243200a12b4b8a8604567623dfa3
vendored
Normal file
|
After Width: | Height: | Size: 696 B |
BIN
packages/media/cpp/cache/images/25/25d0fd5579af67038ec0d48cc87fa018b39be147c10a38b2910d1fe4270abaf0
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/26/26e4f6d0d168ebe125223a6a96c7b55c149137c80db69a8c4fff30b5da803703
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
packages/media/cpp/cache/images/27/270491d587cb05c26c7c712e75d63cb03de54d54a185c720ed44dd9776078a54
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/27/2740a6f92116f6457637d0aed6a9f1ff4777070d9cf75aa4bd038f97f5051333
vendored
Normal file
|
After Width: | Height: | Size: 739 B |
BIN
packages/media/cpp/cache/images/27/278a3ef76fa6a8cf305f06f665fde6645e0a4a00339972313712d0441e785e55
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/media/cpp/cache/images/28/2844edf5cff39406ea66e4a22d12a4b5848d970b5720ac0bf0268f1fb4b87171
vendored
Normal file
|
After Width: | Height: | Size: 671 B |
BIN
packages/media/cpp/cache/images/28/28aebbf93681f636f2c2b395359dd4b116a36cf504563ea706920b74d4835340
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/28/28d001026135db40073f77c50c9b55f0ed6c06de45e1f4259d6c4a1a9d055bef
vendored
Normal file
|
After Width: | Height: | Size: 678 B |
BIN
packages/media/cpp/cache/images/28/28e59f343d6210812d12de74ae2d64008e8733964b7beb6a0e59e5f25682fc12
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/2a/2a429330af11b919a1a938457e33e55e322ea7f8ad25a44dbb21bdba7dcd723e
vendored
Normal file
|
After Width: | Height: | Size: 683 B |
BIN
packages/media/cpp/cache/images/2a/2a85da5ebc8901da3bf3aec3ce333b01d1f0e665848302467488dc019a556194
vendored
Normal file
|
After Width: | Height: | Size: 662 B |
BIN
packages/media/cpp/cache/images/2b/2b21853c26392b359e589d2e0144654f22e5a30bb92650b2b5d1bb02ca25724f
vendored
Normal file
|
After Width: | Height: | Size: 652 B |
BIN
packages/media/cpp/cache/images/2c/2c0eb596ab02e59edef4708e7864bf554f7f797edac1309c4af0bc0eb33a60c8
vendored
Normal file
|
After Width: | Height: | Size: 670 B |
BIN
packages/media/cpp/cache/images/2c/2c4b576fc6bbb9ed212637ac20b7a4f6f3f3c3db19605817c957528a62ddd24a
vendored
Normal file
|
After Width: | Height: | Size: 693 B |
BIN
packages/media/cpp/cache/images/2c/2c7b0f692da91b670afbacf2783a1426c14e634c67b9d77f7decb98b5e3f1034
vendored
Normal file
|
After Width: | Height: | Size: 659 B |
BIN
packages/media/cpp/cache/images/2c/2ca69f182724d48eb1a22b4e842ab49d0f120166c53eb67fdbcd4c7ed2b7d22f
vendored
Normal file
|
After Width: | Height: | Size: 666 B |
BIN
packages/media/cpp/cache/images/2d/2d582e51bed0a7dcef69daedbbf34a455ba7b813917e1af7e1cfca7ea14b2969
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/2d/2d7bf40c7687e047c026acb7dc8d2ee4e7280382efe2567e91fdf3a129aef585
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/media/cpp/cache/images/2d/2d984b0f351a8f1d54d9f592810d176803429df2a2884ada4aeea40051edecac
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/2d/2d9ee71c3de50a72c82bead8d1e03b94071caad7fc4c780ec12b4fa5d869b731
vendored
Normal file
|
After Width: | Height: | Size: 751 B |
BIN
packages/media/cpp/cache/images/31/3141182647d8eb30d8e77c30c2c27e725a0a95ad95c5eec8380c07e4276634c0
vendored
Normal file
|
After Width: | Height: | Size: 681 B |
BIN
packages/media/cpp/cache/images/31/319d3dae2bffcf7ba1e635a9adf8d5753f0624f68c12001a59eda56d01b1b6ef
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/33/3360f2201479c42ba54f35d04e727a900b24d61a70629ebe72c72f8e8c66ff14
vendored
Normal file
|
After Width: | Height: | Size: 672 B |
BIN
packages/media/cpp/cache/images/34/341774500a932936588430d31665c7c7b5818f97e2bc78f7fe9c0400f597f5c1
vendored
Normal file
|
After Width: | Height: | Size: 717 B |
BIN
packages/media/cpp/cache/images/34/344dd3d2fba317426a9d2ddea41e336475663ae9a65337c9627e0c2ff3a1ffc2
vendored
Normal file
|
After Width: | Height: | Size: 721 B |
BIN
packages/media/cpp/cache/images/34/34a36e6850c8adc6cf04865cd9e2eb006851e6187685f97d30b6d9190760c66d
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/35/35100bf1e725168293126c49c52c0fb4311f1ff68d96973acaec7c6ce72dcb5b
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
packages/media/cpp/cache/images/35/353897cbd4578a02a2381a4d66d9367d7af61f1662792a611264db55cd3c3e55
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/35/35b010d0d8dc6419b575d76454d9cf94bde6c736ee86d56788588ad10cba1937
vendored
Normal file
|
After Width: | Height: | Size: 485 B |
BIN
packages/media/cpp/cache/images/35/35fc45f1b991c71400754b1726ea119493ca931abd04527f47ff04fc1a29afb7
vendored
Normal file
|
After Width: | Height: | Size: 672 B |
BIN
packages/media/cpp/cache/images/36/362c5b7dc39cb792f9593399fd75e048f0d0d70c04cc5019f01eb8f5a0f01c48
vendored
Normal file
|
After Width: | Height: | Size: 727 B |
BIN
packages/media/cpp/cache/images/36/36549d8454f2adecc88cd0e9822a84e22714477224068a05f375626da0fd99bf
vendored
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
packages/media/cpp/cache/images/36/36efdd2106a35737073009c44aeb42f4c4af2699086a6007ab9d900c408f605e
vendored
Normal file
|
After Width: | Height: | Size: 643 B |
BIN
packages/media/cpp/cache/images/37/3712e9f4c60f209a5f3db6e8cb43e4cea21faa8b1b863bfa75578490c7f2ec52
vendored
Normal file
|
After Width: | Height: | Size: 682 B |
BIN
packages/media/cpp/cache/images/37/37153ed044e44f962f0b05bdaad334a033b88d74342f5eee0bd41e47cf2a6e8c
vendored
Normal file
|
After Width: | Height: | Size: 727 B |
BIN
packages/media/cpp/cache/images/37/37fe78745dbe37b44877c9e672e3602311fdfa9e372cc1b637f271fdbea69618
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/38/38756f350c35cda53874389e1b24b549abd133f9c860ee3869007aaa92a38b2c
vendored
Normal file
|
After Width: | Height: | Size: 679 B |
BIN
packages/media/cpp/cache/images/39/39150543d901a0e9298488a227be7228680e3ccea678e57aa798ad3055af7193
vendored
Normal file
|
After Width: | Height: | Size: 751 B |
BIN
packages/media/cpp/cache/images/3b/3b2fd504841a78c438ca13f1e2643a4d30d41537ab5cb30f4453ebe30b230634
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/3c/3cfde0b83ef6a71fae80ba00144974fb1eca111472c12ae7bfa26e4cf51f206c
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
packages/media/cpp/cache/images/3f/3f0d38c39e5883b3c3fb5088076df430a90c862bcc8965308ac52b7750bb8320
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/3f/3f137a9287939275dbd59ecc0a82276e94674fb0816de42a2e47870b568cf0bc
vendored
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
packages/media/cpp/cache/images/3f/3f2953ef26d07989838c69c1818e5c41d94866f3aee5a89278e35fa1e269817b
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/41/4175244b907c6c8c83d8f87592337a79beaa3009d5e0d9d5c111763305d95dc7
vendored
Normal file
|
After Width: | Height: | Size: 702 B |
BIN
packages/media/cpp/cache/images/41/41f054bcb6dc7d0a26a4f7fefc37c4dbaaf452cb86a185b92504a9bc30913856
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/media/cpp/cache/images/43/437779e2708fc1c616e08039de950752c000dad327f197ed07083606c108691a
vendored
Normal file
|
After Width: | Height: | Size: 667 B |
BIN
packages/media/cpp/cache/images/43/438defe7599d44c6e6f855984751c2047ad2c3121c14d84b602a0ccd87855ee8
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/media/cpp/cache/images/44/445b017201086df8ecacefee00da806949c6e3f0eed69bc8bfd4f25b991a8ef7
vendored
Normal file
|
After Width: | Height: | Size: 761 B |
BIN
packages/media/cpp/cache/images/45/45fa4d31416d719833ecc372f3cb37168b8faff895a8f84c49ea2aaede694cd2
vendored
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
packages/media/cpp/cache/images/46/46bb950a35cbd7029c5fd455cd980aca7d80295c1f8c0e6df393c2a42ae34118
vendored
Normal file
|
After Width: | Height: | Size: 685 B |
BIN
packages/media/cpp/cache/images/47/471a65a608dd5b04467f9633ccc61466757d46d13fca2e0daff0c56a55c0e3e6
vendored
Normal file
|
After Width: | Height: | Size: 694 B |