mirror of
https://github.com/forkless/Piperless.git
synced 2026-08-17 09:09:49 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
976df843f1 | ||
|
|
3ba494ece6 | ||
|
|
41f451c5d5 | ||
|
|
e361d73af7 | ||
|
|
06c85b6dd9 | ||
|
|
0f59e47d6b | ||
|
|
2f01f17f36 | ||
|
|
8e8251f403 | ||
|
|
fa4ceb85e4 | ||
|
|
daacb1bbf8 | ||
|
|
38e7108d73 | ||
|
|
5754a54f6d | ||
|
|
945f701550 | ||
|
|
ecdaecc5a0 | ||
|
|
916a8a4396 | ||
|
|
a748c79298 |
@@ -0,0 +1,9 @@
|
||||
# Build artifacts
|
||||
build/
|
||||
*.zip
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.deepseek/
|
||||
AGENTS.md
|
||||
@@ -1,4 +1,4 @@
|
||||
# Security Audit — Piperless v1.1.3
|
||||
# Security Audit — Piperless v1.1.0
|
||||
|
||||
**Audit date:** 2026-05-10
|
||||
**Scope:** All 8 PHP classes (`includes/*.php`), plus `uninstall.php`
|
||||
@@ -62,7 +62,7 @@ Piperless shells out to the Piper TTS engine and ffmpeg — both system binaries
|
||||
2. **Authorization layer:** Every admin action checks capabilities. Every post-specific action checks ownership. Public endpoints (audio proxy) use rate limiting instead.
|
||||
3. **Shell boundary:** `escapeshellarg()` wraps every argument passed to `exec()`, `proc_open()`, and `proc_close()`. No string concatenation into shell commands anywhere.
|
||||
4. **Output layer:** All HTML output goes through WordPress escaping functions. REST responses use `sanitize_text_field()`. Player attributes use `esc_attr()` and `esc_url()`.
|
||||
5. **Failure safety:** Every execution path has a fallback. Failed MP3 or Opus conversion stores WAV. Failed ffprobe reads the WAV header. Failed temp writes clean up. Mutexes release in all branches.
|
||||
5. **Failure safety:** Every execution path has a fallback. Failed MP3 conversion stores WAV. Failed ffprobe reads the WAV header. Failed temp writes clean up. Mutexes release in all branches.
|
||||
|
||||
|
||||
## Audit Methodology
|
||||
|
||||
+1
-22
@@ -2,27 +2,6 @@
|
||||
|
||||
All notable changes to the Piperless WordPress plugin.
|
||||
|
||||
## [1.1.4] — 2026-05-12
|
||||
|
||||
### Added
|
||||
|
||||
- **Dashboard widget** — new "Piperless — Audio Storage" widget on the WordPress admin dashboard (togglable via Screen Options). Shows Opus/MP3/WAV file counts and total sizes in a card grid, published posts without audio transcripts with a quick "View posts" link, and server disk usage with a horizontal usage bar and percentage indicator.
|
||||
|
||||
### Changed
|
||||
|
||||
- **About tab** — SVG icons now appear inline before the GitHub Repository and Buy Me a Coffee links for a polished look.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Dashboard TypeError** — `human_size()` parameter changed from `int` to `float` to handle `disk_free_space()` return type.
|
||||
|
||||
## [1.1.3] — 2026-05-11
|
||||
|
||||
### Changed
|
||||
|
||||
- **About tab** — removed Help tab, added GitHub Repository and Buy Me a Coffee links with official SVG icons
|
||||
- **Style descriptions** — cleaned hex color codes from all player theme descriptions
|
||||
|
||||
## [1.1.1] — 2026-05-10
|
||||
|
||||
### Fixed
|
||||
@@ -49,7 +28,7 @@ All notable changes to the Piperless WordPress plugin.
|
||||
- **FFmpeg Binaries Path** — field renamed from "FFmpeg Binary Path" to reflect that the directory is used for the full toolchain (ffmpeg, ffprobe). Description updated to mention MP3/Opus.
|
||||
- **Cache scanning includes `.opus`** — all cache methods (`get_entries`, `clear`, `delete`, `stats`, `clear_orphans`) now handle `.opus` alongside `.mp3` and `.wav`.
|
||||
- **Opus cache badge** — blue badge (#1565c0) in the cache browser Format column.
|
||||
- **Translations** — all 8 locales at 118/118 strings.
|
||||
- **Translations** — all 8 locales at 117/117 strings.
|
||||
|
||||
## [1.0.0] — 2026-05-09
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ all: translations
|
||||
# ── Build ────────────────────────────────────────────────────────────────────
|
||||
build:
|
||||
@echo "=== Building Piperless ==="
|
||||
./tools/build.sh
|
||||
./build.sh
|
||||
|
||||
# ── Translations ─────────────────────────────────────────────────────────────
|
||||
translations:
|
||||
@@ -85,6 +85,5 @@ help:
|
||||
@echo " make check-translations Validate translation integrity & lock state"
|
||||
@echo " make json2po Convert all locale JSON files → .po files"
|
||||
@echo " make build Create distribution ZIP via build.sh"
|
||||
@echo " make release Build, tag, push, and upload a GitHub release"
|
||||
@echo " make clean Remove build artifacts"
|
||||
@echo ""
|
||||
|
||||
@@ -11,6 +11,7 @@ Piperless converts every published post into a natural-sounding audio transcript
|
||||
|
||||
- **Visually impaired** readers can listen instead of read
|
||||
- **Dyslexic** readers get an alternative format
|
||||
- **Low-literacy** audiences can access your content
|
||||
- **Commuting** readers can consume posts as audio
|
||||
- **Non-native speakers** benefit from hearing correct pronunciation
|
||||
|
||||
@@ -23,11 +24,10 @@ Piperless converts every published post into a natural-sounding audio transcript
|
||||
- **Content-addressed caching** — identical text + voice + language always produces the same audio file. Never regenerate the same content twice.
|
||||
- **Multi-language** — Piper supports 20+ languages. Install the voice models you need and Piperless auto-discovers them.
|
||||
- **Voice aliases** — rename technical model names like `en_US-lessac-low` to "American Female" in your admin panel.
|
||||
- **MP3 & Opus encoding** — auto-converts Piper's WAV output to MP3 or Opus using ffmpeg. Opus offers better quality at lower bitrates. Falls back to WAV if ffmpeg is unavailable.
|
||||
- **MP3 conversion** — auto-converts Piper's WAV output to compact MP3 using ffmpeg (optional, falls back to WAV).
|
||||
- **Smart text extraction** — uses the post excerpt when available to avoid reading embedded content (YouTube, Twitter, third-party embeds), decimal numbers, and other artifacts that produce garbled speech. Falls back to the full post body when no excerpt is set.
|
||||
- **No external services** — Piper runs on your server. Text never leaves your infrastructure. GDPR-compliant by architecture.
|
||||
- **Production-hardened** — 29/29 security audit clearance. Rate limiting, authorization layering, process timeout guards, open_basedir aware.
|
||||
- **Dashboard widget** — at-a-glance storage stats on the WordPress dashboard (togglable via Screen Options). File counts and sizes by audio format, posts awaiting transcription, and disk usage bar.
|
||||
- **8 admin languages** — Dutch, German, French, Spanish, Chinese (Simplified), Japanese, Brazilian Portuguese, and Italian translations included.
|
||||
|
||||
|
||||
@@ -116,8 +116,8 @@ Piperless adds a settings page under **Settings → Piperless** with 8 tabs:
|
||||
| **Performance** | Piper process timeout (30–3600s), audio endpoint rate limiting |
|
||||
| **Cache Management** | Stats, cache browser, clear orphaned files, flush entire cache |
|
||||
| **Logs** | Logging level configuration, live log viewer, clear log |
|
||||
| **About** | Version, GitHub repository, and support links |
|
||||
| **Dashboard** | WordPress admin dashboard widget with audio storage stats and disk usage |
|
||||
| **Help** | Usage instructions and ffmpeg notes |
|
||||
| **About** | Version and contact information |
|
||||
|
||||
|
||||
## Player Themes
|
||||
@@ -168,14 +168,14 @@ Piperless ships with complete translations for:
|
||||
|
||||
| Language | Locale | Coverage |
|
||||
|----------|--------|----------|
|
||||
| Dutch | nl_NL | 120/120 |
|
||||
| German | de_DE | 120/120 |
|
||||
| French | fr_FR | 120/120 |
|
||||
| Spanish | es_ES | 120/120 |
|
||||
| Chinese (Simplified) | zh_CN | 120/120 |
|
||||
| Japanese | ja | 120/120 |
|
||||
| Portuguese (Brazil) | pt_BR | 120/120 |
|
||||
| Italian | it_IT | 120/120 |
|
||||
| Dutch | nl_NL | 102/102 |
|
||||
| German | de_DE | 102/102 |
|
||||
| French | fr_FR | 102/102 |
|
||||
| Spanish | es_ES | 102/102 |
|
||||
| Chinese (Simplified) | zh_CN | 102/102 |
|
||||
| Japanese | ja | 102/102 |
|
||||
| Portuguese (Brazil) | pt_BR | 102/102 |
|
||||
| Italian | it_IT | 102/102 |
|
||||
|
||||
The admin panel, Gutenberg sidebar, and frontend player are fully translated. See `languages/` for `.po` and `.mo` files.
|
||||
|
||||
@@ -207,28 +207,10 @@ includes/
|
||||
├── class-cache-manager.php # Content-addressed file cache, MP3 conversion
|
||||
├── class-gutenberg.php # Block editor sidebar, REST API endpoints
|
||||
├── class-settings.php # Admin panel (8 tabs), AJAX handlers
|
||||
├── class-dashboard.php # Dashboard widget with file stats and disk usage
|
||||
├── class-player.php # Frontend HTML5 player (6 themes)
|
||||
└── class-logger.php # PSR-3 logger with dual-channel fallback
|
||||
```
|
||||
|
||||
### Build & Tooling
|
||||
|
||||
The `Makefile` wraps the build and translation toolchain:
|
||||
|
||||
```
|
||||
make build → Create piperless-X.Y.Z.zip
|
||||
make translations → Extract .pot → JSON, sync to all locales
|
||||
make json2po → Convert JSON translations back to .po/.mo
|
||||
make check-translations → Validate translation integrity
|
||||
make lock-translations → Lock all locales for translation work
|
||||
make unlock-translations → Release all translation locks
|
||||
make translation-status → Show lock/completion for each locale
|
||||
make clean → Remove build artifacts
|
||||
```
|
||||
|
||||
All tools run as standalone shell scripts in `tools/` — the Makefile is a convenience wrapper.
|
||||
|
||||
See `doc/index.html` for full developer documentation with architecture diagram, method tables, and security model.
|
||||
|
||||
|
||||
|
||||
@@ -236,18 +236,6 @@
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
.piperless-about-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.piperless-about-link-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Cache browser badges */
|
||||
.piperless-cache-badge {
|
||||
display: inline-block;
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* Piperless Dashboard Widget Styles
|
||||
*
|
||||
* Card-based layout for the WordPress admin dashboard widget
|
||||
* showing audio storage stats at a glance.
|
||||
*
|
||||
* @package Piperless
|
||||
*/
|
||||
|
||||
/* ── Dashboard container ───────────────────────────────────────────────── */
|
||||
.piperless-dashboard {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.piperless-dash-empty {
|
||||
color: #757575;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ── Stat cards grid ───────────────────────────────────────────────────── */
|
||||
.piperless-dash-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.piperless-dash-card {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-left: 4px solid var(--card-accent);
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.piperless-dash-card-value {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
.piperless-dash-card-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: #646970;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.piperless-dash-card-sub {
|
||||
font-size: 12px;
|
||||
color: #757575;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* ── Info rows ─────────────────────────────────────────────────────────── */
|
||||
.piperless-dash-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.piperless-dash-info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.piperless-dash-info-text {
|
||||
flex: 1;
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
.piperless-dash-info-link {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
text-decoration: none;
|
||||
color: #2271b1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.piperless-dash-info-link:hover {
|
||||
color: #135e96;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ── Color highlights per info row ─────────────────────────────────────── */
|
||||
.piperless-dash-info-posts {
|
||||
border-left: 4px solid #dba617;
|
||||
}
|
||||
|
||||
.piperless-dash-info-storage {
|
||||
border-left: 4px solid #2271b1;
|
||||
}
|
||||
|
||||
/* ── Storage usage bar ─────────────────────────────────────────────────── */
|
||||
.piperless-dash-info-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.piperless-dash-bar {
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background: #dcdcde;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.piperless-dash-bar-fill {
|
||||
height: 100%;
|
||||
background: #2271b1;
|
||||
border-radius: 3px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.piperless-dash-bar-label {
|
||||
font-size: 11px;
|
||||
color: #757575;
|
||||
}
|
||||
@@ -1,501 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
|
||||
<g id="watermark_1_">
|
||||
<g>
|
||||
<g id="watermark" style="opacity:0.61;">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#FFFFFF;" points="213.765,461.172 208.204,474.017 205.268,474.017 199.726,461.172 202.938,461.172
|
||||
206.846,470.347 210.81,461.172 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M223.507,469.741h-7.469c0.275,1.23,1.321,1.982,2.826,1.982c1.046,0,1.798-0.312,2.477-0.954
|
||||
l1.523,1.651c-0.917,1.046-2.294,1.597-4.074,1.597c-3.413,0-5.634-2.147-5.634-5.083c0-2.954,2.257-5.083,5.267-5.083
|
||||
c2.899,0,5.138,1.945,5.138,5.12C223.562,469.191,223.526,469.503,223.507,469.741 M216.002,468.071h4.863
|
||||
c-0.202-1.248-1.138-2.055-2.422-2.055C217.139,466.016,216.204,466.805,216.002,468.071"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M224.735,468.934c0-2.973,2.294-5.083,5.505-5.083c2.074,0,3.707,0.899,4.423,2.514
|
||||
l-2.22,1.193c-0.532-0.936-1.321-1.358-2.221-1.358c-1.45,0-2.587,1.009-2.587,2.734c0,1.725,1.138,2.734,2.587,2.734
|
||||
c0.899,0,1.688-0.404,2.221-1.358l2.22,1.211c-0.716,1.578-2.349,2.495-4.423,2.495
|
||||
C227.029,474.017,224.735,471.907,224.735,468.934"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M242.828,473.393c-0.587,0.422-1.45,0.624-2.331,0.624c-2.33,0-3.688-1.193-3.688-3.542
|
||||
v-4.055h-1.523v-2.202h1.523v-2.404h2.863v2.404h2.459v2.202h-2.459v4.019c0,0.844,0.458,1.303,1.229,1.303
|
||||
c0.422,0,0.844-0.128,1.156-0.367L242.828,473.393z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M262.474,463.997v2.643c-0.238-0.018-0.422-0.037-0.642-0.037
|
||||
c-1.578,0-2.624,0.862-2.624,2.753v4.661h-2.863v-9.873h2.734v1.303C259.776,464.493,260.951,463.997,262.474,463.997"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M263.299,472.53l1.009-2.239c1.083,0.789,2.697,1.339,4.239,1.339
|
||||
c1.762,0,2.477-0.587,2.477-1.376c0-2.404-7.469-0.752-7.469-5.524c0-2.184,1.762-4,5.413-4c1.615,0,3.267,0.385,4.459,1.138
|
||||
l-0.918,2.257c-1.193-0.679-2.422-1.009-3.56-1.009c-1.761,0-2.44,0.66-2.44,1.468c0,2.367,7.468,0.734,7.468,5.45
|
||||
c0,2.147-1.78,3.982-5.45,3.982C266.492,474.017,264.437,473.411,263.299,472.53"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M285.428,469.741h-7.469c0.275,1.23,1.321,1.982,2.826,1.982c1.046,0,1.798-0.312,2.477-0.954
|
||||
l1.523,1.651c-0.918,1.046-2.294,1.597-4.074,1.597c-3.413,0-5.634-2.147-5.634-5.083c0-2.954,2.257-5.083,5.267-5.083
|
||||
c2.9,0,5.138,1.945,5.138,5.12C285.484,469.191,285.447,469.503,285.428,469.741 M277.923,468.071h4.863
|
||||
c-0.202-1.248-1.138-2.055-2.422-2.055C279.061,466.016,278.125,466.805,277.923,468.071"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M297.007,469.741h-7.469c0.275,1.23,1.321,1.982,2.826,1.982c1.046,0,1.798-0.312,2.477-0.954
|
||||
l1.523,1.651c-0.918,1.046-2.294,1.597-4.074,1.597c-3.413,0-5.634-2.147-5.634-5.083c0-2.954,2.257-5.083,5.267-5.083
|
||||
c2.899,0,5.138,1.945,5.138,5.12C297.062,469.191,297.025,469.503,297.007,469.741 M289.501,468.071h4.863
|
||||
c-0.202-1.248-1.138-2.055-2.422-2.055C290.639,466.016,289.703,466.805,289.501,468.071"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon style="fill:#FFFFFF;" points="303.208,470.145 301.831,471.503 301.831,474.017 298.969,474.017 298.969,460.401
|
||||
301.831,460.401 301.831,468.108 306.016,464.144 309.429,464.144 305.318,468.328 309.796,474.017 306.327,474.017 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M256.601,475.359L256.601,475.359l-2.86-2.86c-0.435,0.508-0.953,0.943-1.534,1.284
|
||||
c-0.092,0.069-0.186,0.136-0.283,0.199l3.027,3.027c0.456,0.456,1.195,0.456,1.65,0
|
||||
C257.057,476.554,257.057,475.815,256.601,475.359"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M249.984,463.244c0.221-0.173,0.495-0.281,0.797-0.281c0.042,0,0.083,0.002,0.124,0.006
|
||||
c-0.214-0.156-0.478-0.249-0.764-0.249c-0.395,0-0.744,0.18-0.981,0.458c-0.051,0-0.1,0.006-0.151,0.008
|
||||
c0.039-0.077,0.064-0.162,0.064-0.255c0-0.234-0.143-0.434-0.346-0.519c0.087,0.126,0.138,0.279,0.138,0.445
|
||||
c0,0.122-0.031,0.237-0.081,0.341c-2.811,0.201-5.03,2.539-5.03,5.4c0,2.993,2.426,5.42,5.42,5.42
|
||||
c2.993,0,5.42-2.426,5.42-5.42C254.595,465.879,252.593,463.635,249.984,463.244 M247.983,464.656
|
||||
c0.435,0,0.844,0.112,1.199,0.309c0.374-0.245,0.82-0.387,1.299-0.387c0.711,0,1.348,0.312,1.784,0.806
|
||||
c-0.435-0.379-1.004-0.61-1.627-0.61c-0.449,0-0.87,0.12-1.234,0.329c-0.079,0.046-0.156,0.096-0.229,0.15
|
||||
c-0.065-0.048-0.133-0.093-0.204-0.134c-0.369-0.219-0.8-0.344-1.26-0.344c-0.3,0-0.588,0.054-0.854,0.152
|
||||
C247.196,464.754,247.578,464.656,247.983,464.656 M251.772,469.098c0.115,0.305,0.181,0.634,0.181,0.979
|
||||
c0,1.534-1.244,2.777-2.778,2.777c-1.534,0-2.777-1.243-2.777-2.777c0-0.345,0.066-0.674,0.181-0.979
|
||||
c-0.62-0.382-1.035-1.064-1.035-1.846c0-1.197,0.971-2.168,2.168-2.168c0.565,0,1.078,0.218,1.463,0.572
|
||||
c0.386-0.354,0.899-0.572,1.464-0.572c1.197,0,2.168,0.971,2.168,2.168C252.807,468.034,252.392,468.716,251.772,469.098"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M251.666,467.061c0,0.497-0.404,0.901-0.901,0.901c-0.497,0-0.901-0.404-0.901-0.901
|
||||
s0.404-0.901,0.901-0.901c0.101,0,0.197,0.017,0.287,0.047c-0.03,0.062-0.045,0.132-0.045,0.204
|
||||
c0,0.273,0.221,0.494,0.494,0.494c0.05,0,0.099-0.008,0.146-0.022C251.66,466.941,251.666,467,251.666,467.061"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M248.255,467.061c0,0.376-0.305,0.681-0.681,0.681c-0.376,0-0.681-0.305-0.681-0.681
|
||||
s0.305-0.681,0.681-0.681c0.076,0,0.149,0.013,0.217,0.035c-0.023,0.047-0.034,0.1-0.034,0.155
|
||||
c0,0.206,0.167,0.374,0.374,0.374c0.038,0,0.075-0.006,0.11-0.017C248.25,466.97,248.255,467.015,248.255,467.061"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="242.908" y="467.83" style="fill:#FFFFFF;" width="0.616" height="0.616"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="254.827" y="467.83" style="fill:#FFFFFF;" width="0.616" height="0.616"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M255.205,468.082h-0.14c0-3.248-2.642-5.89-5.89-5.89c-3.248,0-5.89,2.642-5.89,5.89h-0.14
|
||||
c0-1.611,0.627-3.125,1.766-4.264c1.139-1.139,2.653-1.766,4.264-1.766c1.611,0,3.125,0.627,4.264,1.766
|
||||
C254.578,464.957,255.205,466.471,255.205,468.082"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="248.868" y="461.814" style="fill:#FFFFFF;" width="0.616" height="0.616"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="244.95" y="462.052" style="fill:#FFFFFF;" width="8.45" height="0.14"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M245.174,462.15c0,0.108-0.088,0.196-0.196,0.196c-0.108,0-0.196-0.088-0.196-0.196
|
||||
c0-0.108,0.088-0.196,0.196-0.196C245.086,461.954,245.174,462.042,245.174,462.15"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M253.596,462.15c0,0.108-0.088,0.196-0.196,0.196c-0.108,0-0.196-0.088-0.196-0.196
|
||||
c0-0.108,0.088-0.196,0.196-0.196C253.509,461.954,253.596,462.042,253.596,462.15"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M314.356,473.409c0,1.559-2.364,1.559-2.364,0C311.993,471.851,314.356,471.851,314.356,473.409
|
||||
z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M161.739,466.549l1.772,6.088l1.855-6.088h2.215l-2.823,8.14h-2.33l-0.837-2.396l-0.722-2.708
|
||||
l-0.722,2.708l-0.837,2.396h-2.33l-2.839-8.14h2.231l1.855,6.088l1.756-6.088H161.739z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M176.713,466.549l1.772,6.088l1.855-6.088h2.215l-2.823,8.14h-2.33l-0.837-2.396l-0.722-2.708
|
||||
l-0.722,2.708l-0.837,2.396h-2.33l-2.839-8.14h2.231l1.855,6.088l1.756-6.088H176.713z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M191.687,466.549l1.772,6.088l1.855-6.088h2.215l-2.823,8.14h-2.33l-0.837-2.396l-0.722-2.708
|
||||
l-0.722,2.708l-0.837,2.396h-2.33l-2.839-8.14h2.231l1.855,6.088l1.756-6.088H191.687z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M200.908,473.52c0,1.559-2.364,1.559-2.364,0C198.545,471.962,200.908,471.962,200.908,473.52z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M322.71,473.409c-0.935,0.919-1.919,1.28-3.117,1.28c-2.346,0-4.3-1.411-4.3-4.282
|
||||
s1.953-4.284,4.3-4.284c1.149,0,2.035,0.329,2.921,1.199l-1.264,1.329c-0.476-0.428-1.066-0.64-1.623-0.64
|
||||
c-1.346,0-2.33,0.985-2.33,2.396c0,1.542,1.05,2.362,2.297,2.362c0.64,0,1.28-0.18,1.772-0.672L322.71,473.409z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M331.805,470.472c0,2.33-1.591,4.217-4.217,4.217c-2.626,0-4.201-1.887-4.201-4.217
|
||||
c0-2.314,1.609-4.217,4.185-4.217C330.149,466.255,331.805,468.158,331.805,470.472z M325.389,470.472
|
||||
c0,1.231,0.739,2.38,2.199,2.38c1.46,0,2.199-1.149,2.199-2.38c0-1.215-0.854-2.396-2.199-2.396
|
||||
C326.144,468.077,325.389,469.258,325.389,470.472z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M338.572,474.689v-4.332c0-1.068-0.559-2.035-1.658-2.035c-1.082,0-1.722,0.967-1.722,2.035
|
||||
v4.332h-2.003v-8.107h1.855l0.148,0.985c0.426-0.82,1.362-1.116,2.133-1.116c0.969,0,1.937,0.394,2.396,1.51
|
||||
c0.723-1.149,1.658-1.478,2.708-1.478c2.297,0,3.43,1.412,3.43,3.84v4.365h-2.003v-4.365c0-1.066-0.442-1.97-1.526-1.97
|
||||
c-1.082,0-1.756,0.935-1.756,2.003v4.332H338.572z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g style="opacity:0.61;">
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M345.988,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
|
||||
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
|
||||
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
|
||||
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
|
||||
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
|
||||
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
|
||||
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
|
||||
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C346.003,438.696,346.005,434.997,345.988,431.299z
|
||||
M317.537,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
|
||||
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
|
||||
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
|
||||
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
|
||||
C316.987,417.166,316.991,417.162,317.537,417.162z M340.822,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
|
||||
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
|
||||
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
|
||||
C341.375,451.574,341.37,451.579,340.822,451.579z"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="327.418" y="417.053" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="325.662" y="418.107" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="327.418" y="419.161" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="325.662" y="420.215" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="327.418" y="421.269" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="325.662" y="422.323" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="327.418" y="423.378" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="325.662" y="424.432" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="327.418" y="425.486" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="325.662" y="426.54" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="327.418" y="427.594" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="325.662" y="428.648" style="fill:#FFFFFF;" width="1.757" height="1.054"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M187.637,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
|
||||
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
|
||||
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
|
||||
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
|
||||
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
|
||||
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
|
||||
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
|
||||
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C187.652,438.696,187.655,434.997,187.637,431.299z
|
||||
M159.187,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
|
||||
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
|
||||
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
|
||||
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
|
||||
C158.636,417.166,158.64,417.162,159.187,417.162z M182.472,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
|
||||
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
|
||||
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
|
||||
C183.024,451.574,183.019,451.579,182.472,451.579z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M159.779,440.669v-7.897h2.779c0.375,0,0.726,0.061,1.053,0.182
|
||||
c0.327,0.121,0.612,0.292,0.855,0.513c0.242,0.221,0.434,0.483,0.573,0.789c0.14,0.305,0.21,0.642,0.21,1.009
|
||||
c0,0.375-0.07,0.715-0.21,1.02c-0.14,0.305-0.331,0.568-0.573,0.789c-0.243,0.221-0.528,0.392-0.855,0.513
|
||||
c-0.327,0.121-0.678,0.182-1.053,0.182h-1.29v2.901H159.779z M162.58,436.356c0.39,0,0.684-0.111,0.882-0.331
|
||||
c0.199-0.22,0.298-0.474,0.298-0.761c0-0.14-0.024-0.276-0.072-0.408c-0.048-0.132-0.121-0.248-0.221-0.347
|
||||
c-0.099-0.099-0.223-0.178-0.37-0.237c-0.147-0.059-0.32-0.089-0.518-0.089h-1.312v2.173H162.58z"/>
|
||||
<path style="fill:#FFFFFF;" d="M166.308,432.771h1.731l3.177,5.294h0.088l-0.088-1.522v-3.772h1.478v7.897h-1.566l-3.353-5.592
|
||||
h-0.088l0.088,1.522v4.07h-1.467V432.771z"/>
|
||||
<path style="fill:#FFFFFF;" d="M177.922,436.334h3.872c0.022,0.089,0.04,0.195,0.055,0.32c0.014,0.125,0.022,0.25,0.022,0.375
|
||||
c0,0.507-0.077,0.985-0.231,1.434c-0.154,0.449-0.397,0.849-0.728,1.202c-0.353,0.375-0.776,0.666-1.268,0.871
|
||||
c-0.493,0.206-1.055,0.309-1.688,0.309c-0.574,0-1.114-0.103-1.622-0.309c-0.507-0.206-0.948-0.492-1.323-0.86
|
||||
c-0.375-0.367-0.673-0.803-0.894-1.307c-0.221-0.504-0.331-1.053-0.331-1.649c0-0.595,0.11-1.145,0.331-1.649
|
||||
c0.221-0.504,0.518-0.939,0.894-1.307c0.375-0.367,0.816-0.654,1.323-0.86c0.507-0.206,1.048-0.309,1.622-0.309
|
||||
c0.64,0,1.211,0.11,1.715,0.331c0.504,0.221,0.935,0.526,1.296,0.915l-1.025,1.004c-0.258-0.272-0.544-0.48-0.861-0.623
|
||||
c-0.316-0.143-0.695-0.215-1.136-0.215c-0.361,0-0.703,0.065-1.026,0.193c-0.324,0.129-0.607,0.311-0.85,0.546
|
||||
c-0.242,0.235-0.436,0.52-0.579,0.855c-0.143,0.335-0.215,0.708-0.215,1.119c0,0.412,0.072,0.785,0.215,1.12
|
||||
c0.143,0.335,0.338,0.62,0.584,0.855c0.246,0.235,0.531,0.418,0.855,0.546c0.323,0.129,0.669,0.193,1.037,0.193
|
||||
c0.419,0,0.773-0.061,1.064-0.182c0.29-0.121,0.538-0.278,0.744-0.469c0.148-0.132,0.275-0.3,0.381-0.502
|
||||
c0.106-0.202,0.189-0.428,0.248-0.678h-2.482V436.334z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M224.019,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
|
||||
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
|
||||
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
|
||||
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
|
||||
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
|
||||
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
|
||||
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
|
||||
c0.271-0.002,0.541,0.008,0.809-0.058c0.997-0.246,1.69-1.044,1.694-2.069C224.034,438.696,224.036,434.997,224.019,431.299z
|
||||
M195.568,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
|
||||
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
|
||||
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
|
||||
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
|
||||
C195.018,417.166,195.022,417.162,195.568,417.162z M218.854,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
|
||||
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
|
||||
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
|
||||
C219.406,451.574,219.401,451.579,218.854,451.579z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M205.111,432.771h1.699l2.967,7.897h-1.644l-0.651-1.886h-3.044l-0.651,1.886h-1.643
|
||||
L205.111,432.771z M206.997,437.415l-0.706-1.974l-0.287-0.96h-0.088l-0.287,0.96l-0.706,1.974H206.997z"/>
|
||||
<path style="fill:#FFFFFF;" d="M211.331,434.536c-0.125,0-0.245-0.024-0.359-0.072c-0.114-0.048-0.213-0.114-0.298-0.199
|
||||
c-0.084-0.084-0.151-0.182-0.198-0.292c-0.048-0.11-0.072-0.232-0.072-0.364s0.024-0.254,0.072-0.364
|
||||
c0.048-0.11,0.114-0.208,0.198-0.292c0.084-0.084,0.184-0.151,0.298-0.198c0.114-0.048,0.233-0.072,0.359-0.072
|
||||
c0.257,0,0.478,0.09,0.662,0.27c0.184,0.181,0.276,0.399,0.276,0.656s-0.092,0.476-0.276,0.656
|
||||
C211.809,434.446,211.589,434.536,211.331,434.536z M210.615,440.669v-5.404h1.445v5.404H210.615z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M261.044,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
|
||||
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
|
||||
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
|
||||
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
|
||||
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
|
||||
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
|
||||
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
|
||||
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C261.059,438.696,261.061,434.997,261.044,431.299z
|
||||
M232.593,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
|
||||
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
|
||||
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
|
||||
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
|
||||
C232.042,417.166,232.047,417.162,232.593,417.162z M255.878,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
|
||||
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
|
||||
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.002,1.997,0.001,3.994,0,5.991
|
||||
C256.431,451.574,256.426,451.579,255.878,451.579z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M236.361,440.845c-0.338,0-0.662-0.048-0.971-0.143c-0.309-0.095-0.592-0.239-0.849-0.43
|
||||
c-0.257-0.191-0.481-0.425-0.673-0.7c-0.191-0.276-0.342-0.597-0.452-0.965l1.401-0.551c0.103,0.397,0.283,0.726,0.54,0.987
|
||||
c0.257,0.261,0.596,0.392,1.015,0.392c0.154,0,0.303-0.02,0.447-0.061c0.143-0.04,0.272-0.099,0.386-0.176
|
||||
s0.204-0.175,0.27-0.292c0.066-0.118,0.099-0.254,0.099-0.408c0-0.147-0.026-0.279-0.077-0.397
|
||||
c-0.051-0.117-0.138-0.227-0.259-0.331c-0.121-0.103-0.28-0.202-0.475-0.298c-0.195-0.095-0.435-0.195-0.722-0.298l-0.485-0.176
|
||||
c-0.213-0.073-0.429-0.173-0.645-0.298c-0.217-0.125-0.413-0.276-0.59-0.452c-0.177-0.176-0.322-0.384-0.436-0.623
|
||||
c-0.114-0.239-0.171-0.509-0.171-0.81c0-0.309,0.06-0.597,0.182-0.866c0.121-0.268,0.294-0.503,0.518-0.706
|
||||
c0.224-0.202,0.492-0.36,0.805-0.474s0.66-0.171,1.042-0.171c0.397,0,0.74,0.053,1.031,0.16
|
||||
c0.291,0.107,0.537,0.243,0.739,0.408c0.202,0.165,0.366,0.348,0.491,0.546c0.125,0.199,0.217,0.386,0.276,0.563l-1.312,0.551
|
||||
c-0.074-0.221-0.208-0.419-0.402-0.596c-0.195-0.176-0.462-0.265-0.8-0.265c-0.324,0-0.592,0.075-0.805,0.226
|
||||
c-0.213,0.151-0.32,0.348-0.32,0.59c0,0.235,0.103,0.436,0.309,0.601c0.206,0.165,0.533,0.325,0.982,0.48l0.497,0.165
|
||||
c0.316,0.111,0.605,0.237,0.866,0.381c0.261,0.143,0.485,0.314,0.673,0.513c0.187,0.199,0.331,0.425,0.43,0.678
|
||||
c0.1,0.254,0.149,0.546,0.149,0.877c0,0.412-0.083,0.767-0.248,1.064c-0.165,0.298-0.377,0.542-0.634,0.734
|
||||
c-0.258,0.191-0.548,0.335-0.872,0.43C236.986,440.797,236.67,440.845,236.361,440.845z"/>
|
||||
<path style="fill:#FFFFFF;" d="M239.516,432.771h1.61l1.633,4.754l0.287,1.015h0.088l0.309-1.015l1.699-4.754h1.61l-2.879,7.897
|
||||
h-1.566L239.516,432.771z"/>
|
||||
<path style="fill:#FFFFFF;" d="M251.097,436.334h3.871c0.022,0.089,0.04,0.195,0.055,0.32c0.015,0.125,0.023,0.25,0.023,0.375
|
||||
c0,0.507-0.078,0.985-0.232,1.434c-0.154,0.449-0.397,0.849-0.728,1.202c-0.353,0.375-0.775,0.666-1.268,0.871
|
||||
c-0.493,0.206-1.055,0.309-1.688,0.309c-0.574,0-1.114-0.103-1.621-0.309c-0.507-0.206-0.949-0.492-1.324-0.86
|
||||
c-0.375-0.367-0.673-0.803-0.894-1.307c-0.22-0.504-0.331-1.053-0.331-1.649c0-0.595,0.11-1.145,0.331-1.649
|
||||
c0.221-0.504,0.518-0.939,0.894-1.307c0.375-0.367,0.816-0.654,1.324-0.86c0.507-0.206,1.047-0.309,1.621-0.309
|
||||
c0.64,0,1.211,0.11,1.715,0.331c0.504,0.221,0.936,0.526,1.296,0.915l-1.026,1.004c-0.257-0.272-0.544-0.48-0.861-0.623
|
||||
c-0.316-0.143-0.694-0.215-1.136-0.215c-0.36,0-0.702,0.065-1.026,0.193c-0.323,0.129-0.607,0.311-0.849,0.546
|
||||
c-0.243,0.235-0.436,0.52-0.579,0.855c-0.143,0.335-0.215,0.708-0.215,1.119c0,0.412,0.072,0.785,0.215,1.12
|
||||
c0.143,0.335,0.338,0.62,0.585,0.855c0.246,0.235,0.531,0.418,0.854,0.546c0.324,0.129,0.669,0.193,1.037,0.193
|
||||
c0.419,0,0.774-0.061,1.064-0.182c0.29-0.121,0.539-0.278,0.745-0.469c0.147-0.132,0.274-0.3,0.38-0.502
|
||||
c0.107-0.202,0.189-0.428,0.248-0.678h-2.482V436.334z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M297.3,431.299c-0.006-1.224-0.959-2.121-2.189-2.14c-0.924-0.014-0.832,0.12-0.834-0.867
|
||||
c-0.003-1.097-0.007-2.194,0.003-3.292c0.003-0.379-0.112-0.691-0.362-0.976c-2.342-2.668-4.678-5.342-7.019-8.011
|
||||
c-0.12-0.137-0.275-0.244-0.414-0.366c-6.214,0-12.427,0-18.641,0c-0.794,0.293-1.14,0.868-1.138,1.709
|
||||
c0.01,3.748,0.004,7.496,0.004,11.243c0,0.556-0.003,0.589-0.55,0.551c-1.497-0.102-2.516,0.986-2.497,2.492
|
||||
c0.044,3.476,0.013,6.953,0.014,10.429c0.001,1.58,0.867,2.443,2.45,2.449c0.582,0.002,0.582,0.002,0.582,0.6
|
||||
c0,2.219-0.001,4.438,0.001,6.657c0.001,1.192,0.58,1.771,1.768,1.771c8.013,0.001,16.027,0.001,24.04,0
|
||||
c1.168,0,1.755-0.583,1.757-1.745c0.002-2.256,0-4.512,0.001-6.768c0-0.512,0.002-0.511,0.52-0.515
|
||||
c0.271-0.002,0.541,0.008,0.809-0.058c0.996-0.246,1.69-1.044,1.694-2.069C297.315,438.696,297.318,434.997,297.3,431.299z
|
||||
M268.85,417.162c5.337,0,10.674,0,16.01,0c0.548,0,0.554,0.007,0.554,0.561c0.001,2.243-0.001,4.486,0.001,6.73
|
||||
c0.001,0.811,0.249,1.059,1.06,1.059c1.91,0.001,3.821,0,5.731,0.001c0.458,0,0.479,0.021,0.481,0.483
|
||||
c0.003,0.887,0.002,1.775,0,2.662c-0.001,0.477-0.024,0.498-0.504,0.499c-3.895,0.001-7.79,0-11.684,0
|
||||
c-3.882,0-7.765,0-11.647,0c-0.55,0-0.552-0.001-0.552-0.561c-0.001-3.624-0.001-7.247,0-10.871
|
||||
C268.299,417.166,268.303,417.162,268.85,417.162z M292.135,451.579c-3.883,0.001-7.766,0-11.65,0c-3.871,0-7.742,0-11.613,0
|
||||
c-0.572,0-0.574-0.002-0.574-0.579c-0.001-1.997-0.001-3.994,0.001-5.991c0-0.464,0.023-0.486,0.478-0.487
|
||||
c7.803-0.001,15.607-0.001,23.41,0c0.478,0,0.499,0.02,0.499,0.503c0.001,1.997,0.001,3.994,0,5.991
|
||||
C292.687,451.574,292.682,451.579,292.135,451.579z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M272.966,434.183v1.831h3.165v1.412h-3.165v1.831h3.518v1.412h-5.007v-7.897h5.007v1.412H272.966
|
||||
z"/>
|
||||
<path style="fill:#FFFFFF;" d="M277.852,440.669v-7.897h2.779c0.375,0,0.726,0.061,1.053,0.182
|
||||
c0.327,0.121,0.612,0.292,0.855,0.513c0.243,0.221,0.434,0.483,0.574,0.789c0.14,0.305,0.209,0.642,0.209,1.009
|
||||
c0,0.375-0.07,0.715-0.209,1.02c-0.14,0.305-0.331,0.568-0.574,0.789c-0.243,0.221-0.528,0.392-0.855,0.513
|
||||
c-0.327,0.121-0.678,0.182-1.053,0.182h-1.29v2.901H277.852z M280.653,436.356c0.389,0,0.684-0.111,0.882-0.331
|
||||
c0.199-0.22,0.298-0.474,0.298-0.761c0-0.14-0.024-0.276-0.072-0.408c-0.048-0.132-0.121-0.248-0.221-0.347
|
||||
c-0.099-0.099-0.222-0.178-0.37-0.237c-0.147-0.059-0.32-0.089-0.518-0.089h-1.312v2.173H280.653z"/>
|
||||
<path style="fill:#FFFFFF;" d="M286.797,440.845c-0.338,0-0.662-0.048-0.971-0.143c-0.309-0.095-0.592-0.239-0.849-0.43
|
||||
c-0.257-0.191-0.482-0.425-0.673-0.7c-0.191-0.276-0.342-0.597-0.452-0.965l1.401-0.551c0.103,0.397,0.283,0.726,0.541,0.987
|
||||
c0.257,0.261,0.595,0.392,1.015,0.392c0.154,0,0.303-0.02,0.447-0.061c0.143-0.04,0.272-0.099,0.386-0.176
|
||||
c0.114-0.077,0.204-0.175,0.27-0.292c0.066-0.118,0.1-0.254,0.1-0.408c0-0.147-0.026-0.279-0.077-0.397
|
||||
c-0.051-0.117-0.138-0.227-0.259-0.331c-0.121-0.103-0.279-0.202-0.474-0.298c-0.195-0.095-0.436-0.195-0.723-0.298
|
||||
l-0.485-0.176c-0.213-0.073-0.428-0.173-0.645-0.298c-0.217-0.125-0.414-0.276-0.59-0.452c-0.176-0.176-0.322-0.384-0.436-0.623
|
||||
c-0.114-0.239-0.171-0.509-0.171-0.81c0-0.309,0.061-0.597,0.182-0.866c0.121-0.268,0.294-0.503,0.518-0.706
|
||||
c0.224-0.202,0.493-0.36,0.805-0.474c0.312-0.114,0.66-0.171,1.042-0.171c0.397,0,0.741,0.053,1.031,0.16
|
||||
c0.29,0.107,0.537,0.243,0.739,0.408c0.202,0.165,0.365,0.348,0.491,0.546c0.125,0.199,0.217,0.386,0.276,0.563l-1.312,0.551
|
||||
c-0.074-0.221-0.208-0.419-0.403-0.596c-0.195-0.176-0.462-0.265-0.799-0.265c-0.324,0-0.592,0.075-0.805,0.226
|
||||
c-0.213,0.151-0.32,0.348-0.32,0.59c0,0.235,0.103,0.436,0.309,0.601c0.206,0.165,0.533,0.325,0.982,0.48l0.496,0.165
|
||||
c0.316,0.111,0.605,0.237,0.866,0.381c0.261,0.143,0.485,0.314,0.673,0.513c0.187,0.199,0.331,0.425,0.43,0.678
|
||||
c0.099,0.254,0.149,0.546,0.149,0.877c0,0.412-0.083,0.767-0.248,1.064c-0.165,0.298-0.377,0.542-0.634,0.734
|
||||
c-0.258,0.191-0.548,0.335-0.872,0.43C287.422,440.797,287.105,440.845,286.797,440.845z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M321.394,439.168l4.004-4.985h-3.827v-1.412h5.559v1.5l-3.96,4.985h4.004v1.412h-5.779V439.168z"
|
||||
/>
|
||||
<path style="fill:#FFFFFF;" d="M328.409,432.771h1.489v7.897h-1.489V432.771z"/>
|
||||
<path style="fill:#FFFFFF;" d="M331.486,440.669v-7.897h2.779c0.375,0,0.726,0.061,1.053,0.182
|
||||
c0.327,0.121,0.612,0.292,0.855,0.513s0.434,0.483,0.574,0.789c0.14,0.305,0.209,0.642,0.209,1.009
|
||||
c0,0.375-0.07,0.715-0.209,1.02c-0.14,0.305-0.331,0.568-0.574,0.789c-0.243,0.221-0.528,0.392-0.855,0.513
|
||||
c-0.327,0.121-0.678,0.182-1.053,0.182h-1.29v2.901H331.486z M334.288,436.356c0.389,0,0.684-0.111,0.882-0.331
|
||||
c0.199-0.22,0.298-0.474,0.298-0.761c0-0.14-0.024-0.276-0.072-0.408c-0.048-0.132-0.121-0.248-0.221-0.347
|
||||
c-0.099-0.099-0.222-0.178-0.37-0.237c-0.147-0.059-0.32-0.089-0.518-0.089h-1.312v2.173H334.288z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g style="opacity:0.61;">
|
||||
<path style="fill:#FFFFFF;" d="M300.133,433.27h9.067v2.242h-9.067V433.27z M300.133,437.136h9.067v2.243h-9.067V437.136z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g style="opacity:0.61;">
|
||||
<path style="fill:#FFFFFF;" d="M156.756,478.878h1.607c1.263,0,2.114,0.812,2.114,1.974c0,1.161-0.851,1.973-2.114,1.973h-1.607
|
||||
V478.878z M158.34,482.464c1.049,0,1.725-0.665,1.725-1.612c0-0.947-0.677-1.613-1.725-1.613h-1.167v3.225H158.34z"/>
|
||||
<path style="fill:#FFFFFF;" d="M165.139,480.851c0-1.15,0.879-2.007,2.075-2.007c1.184,0,2.069,0.851,2.069,2.007
|
||||
c0,1.156-0.885,2.007-2.069,2.007C166.019,482.858,165.139,482.002,165.139,480.851z M168.866,480.851
|
||||
c0-0.942-0.705-1.635-1.652-1.635c-0.953,0-1.663,0.693-1.663,1.635c0,0.941,0.71,1.635,1.663,1.635
|
||||
C168.162,482.486,168.866,481.793,168.866,480.851z"/>
|
||||
<path style="fill:#FFFFFF;" d="M179.596,478.878l-1.331,3.947h-0.44l-1.156-3.366l-1.161,3.366h-0.434l-1.331-3.947h0.429
|
||||
l1.139,3.394l1.178-3.394h0.389l1.161,3.411l1.156-3.411H179.596z"/>
|
||||
<path style="fill:#FFFFFF;" d="M187.731,478.878v3.947h-0.344l-2.537-3.202v3.202h-0.417v-3.947h0.344l2.543,3.203v-3.203H187.731
|
||||
z"/>
|
||||
<path style="fill:#FFFFFF;" d="M193.093,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
|
||||
<path style="fill:#FFFFFF;" d="M200.061,480.851c0-1.15,0.879-2.007,2.075-2.007c1.184,0,2.069,0.851,2.069,2.007
|
||||
c0,1.156-0.885,2.007-2.069,2.007C200.941,482.858,200.061,482.002,200.061,480.851z M203.788,480.851
|
||||
c0-0.942-0.705-1.635-1.652-1.635c-0.953,0-1.663,0.693-1.663,1.635c0,0.941,0.71,1.635,1.663,1.635
|
||||
C203.083,482.486,203.788,481.793,203.788,480.851z"/>
|
||||
<path style="fill:#FFFFFF;" d="M211.636,481.77h-2.199l-0.474,1.054h-0.434l1.804-3.947h0.412l1.804,3.947h-0.44L211.636,481.77z
|
||||
M211.484,481.432l-0.947-2.12l-0.947,2.12H211.484z"/>
|
||||
<path style="fill:#FFFFFF;" d="M217.28,478.878h1.607c1.263,0,2.114,0.812,2.114,1.974c0,1.161-0.851,1.973-2.114,1.973h-1.607
|
||||
V478.878z M218.864,482.464c1.049,0,1.725-0.665,1.725-1.612c0-0.947-0.677-1.613-1.725-1.613h-1.167v3.225H218.864z"/>
|
||||
<path style="fill:#FFFFFF;" d="M234.041,481.77h-2.199l-0.474,1.054h-0.434l1.804-3.947h0.412l1.804,3.947h-0.44L234.041,481.77z
|
||||
M233.889,481.432l-0.947-2.12l-0.947,2.12H233.889z"/>
|
||||
<path style="fill:#FFFFFF;" d="M239.685,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
|
||||
<path style="fill:#FFFFFF;" d="M247.082,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
|
||||
<path style="fill:#FFFFFF;" d="M260.449,479.239v1.551h2.041v0.361h-2.041v1.675h-0.417v-3.947h2.706v0.361H260.449z"/>
|
||||
<path style="fill:#FFFFFF;" d="M267.678,478.878h0.417v3.947h-0.417V478.878z"/>
|
||||
<path style="fill:#FFFFFF;" d="M273.456,478.878h0.417v3.586h2.21v0.361h-2.627V478.878z"/>
|
||||
<path style="fill:#FFFFFF;" d="M283.644,482.464v0.361h-2.791v-3.947h2.706v0.361h-2.289v1.404h2.041v0.355h-2.041v1.466H283.644z
|
||||
"/>
|
||||
<path style="fill:#FFFFFF;" d="M294.672,479.239v1.551h2.041v0.361h-2.041v1.675h-0.417v-3.947h2.706v0.361H294.672z"/>
|
||||
<path style="fill:#FFFFFF;" d="M301.5,480.851c0-1.15,0.879-2.007,2.075-2.007c1.184,0,2.069,0.851,2.069,2.007
|
||||
c0,1.156-0.885,2.007-2.069,2.007C302.379,482.858,301.5,482.002,301.5,480.851z M305.226,480.851
|
||||
c0-0.942-0.705-1.635-1.652-1.635c-0.953,0-1.663,0.693-1.663,1.635c0,0.941,0.71,1.635,1.663,1.635
|
||||
C304.522,482.486,305.226,481.793,305.226,480.851z"/>
|
||||
<path style="fill:#FFFFFF;" d="M313.351,482.825l-0.902-1.269c-0.102,0.011-0.203,0.017-0.316,0.017h-1.06v1.252h-0.417v-3.947
|
||||
h1.477c1.004,0,1.613,0.507,1.613,1.353c0,0.62-0.327,1.054-0.902,1.24l0.964,1.353H313.351z M313.328,480.231
|
||||
c0-0.632-0.417-0.992-1.207-0.992h-1.048v1.979h1.048C312.911,481.218,313.328,480.851,313.328,480.231z"/>
|
||||
<path style="fill:#FFFFFF;" d="M322.907,478.878v3.947h-0.4v-3.158l-1.551,2.656h-0.197l-1.551-2.639v3.14h-0.4v-3.947h0.344
|
||||
l1.714,2.926l1.697-2.926H322.907z"/>
|
||||
<path style="fill:#FFFFFF;" d="M330.744,481.77h-2.199l-0.473,1.054h-0.434l1.804-3.947h0.411l1.804,3.947h-0.44L330.744,481.77z
|
||||
M330.592,481.432l-0.947-2.12l-0.947,2.12H330.592z"/>
|
||||
<path style="fill:#FFFFFF;" d="M336.957,479.239h-1.387v-0.361h3.192v0.361h-1.387v3.586h-0.417V479.239z"/>
|
||||
<path style="fill:#FFFFFF;" d="M343.063,482.346l0.164-0.321c0.282,0.276,0.784,0.479,1.302,0.479c0.739,0,1.06-0.31,1.06-0.699
|
||||
c0-1.083-2.43-0.417-2.43-1.877c0-0.581,0.451-1.083,1.455-1.083c0.446,0,0.908,0.13,1.224,0.35l-0.141,0.333
|
||||
c-0.338-0.22-0.733-0.327-1.083-0.327c-0.722,0-1.043,0.321-1.043,0.716c0,1.083,2.43,0.429,2.43,1.866
|
||||
c0,0.581-0.462,1.077-1.472,1.077C343.937,482.858,343.356,482.65,343.063,482.346z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M372.927,129.733l-0.308-0.182l-0.714-0.218C372.192,129.576,372.552,129.717,372.927,129.733z"/>
|
||||
<path d="M377.441,161.889l-0.345,0.097L377.441,161.889z"/>
|
||||
<path d="M373.01,129.512c-0.035-0.005-0.071-0.013-0.105-0.025c-0.001,0.023-0.001,0.047,0,0.07
|
||||
C372.944,129.552,372.98,129.537,373.01,129.512z"/>
|
||||
<path d="M377.134,161.713l0.521-0.297l0.193-0.109l0.176-0.188C377.693,161.263,377.392,161.464,377.134,161.713z"/>
|
||||
<path d="M373.796,130.364l-0.508-0.484l-0.345-0.188C373.128,130.02,373.434,130.261,373.796,130.364z"/>
|
||||
<path d="M245.83,442.334c-0.407,0.176-0.763,0.45-1.036,0.799l0.32-0.206C245.333,442.728,245.642,442.491,245.83,442.334z"/>
|
||||
<path d="M320.198,427.707c0-0.461-0.224-0.375-0.169,1.259c0-0.133,0.054-0.266,0.079-0.392
|
||||
C320.137,428.282,320.161,427.997,320.198,427.707z"/>
|
||||
<path d="M312.48,442.334c-0.407,0.176-0.763,0.45-1.036,0.799l0.322-0.206C311.984,442.728,312.292,442.491,312.48,442.334z"/>
|
||||
<path d="M193.525,445.867c-0.308-0.268-0.686-0.444-1.09-0.508c0.327,0.158,0.654,0.315,0.872,0.436L193.525,445.867z"/>
|
||||
<path d="M181.804,434.564c-0.048-0.476-0.195-0.938-0.43-1.356c0.167,0.434,0.306,0.879,0.418,1.332L181.804,434.564z"/>
|
||||
<path style="fill:#FCDB2B;" d="M260.848,232.808c-16.163,6.92-34.507,14.766-58.281,14.766c-9.945-0.021-19.842-1.385-29.422-4.057
|
||||
l16.442,168.812c0.582,7.056,3.796,13.634,9.005,18.43c5.208,4.796,12.03,7.458,19.11,7.456c0,0,23.313,1.21,31.092,1.21
|
||||
c8.374,0,33.478-1.21,33.478-1.21c7.08,0,13.899-2.663,19.106-7.458c5.207-4.796,8.421-11.374,9.002-18.429l17.611-186.544
|
||||
c-7.87-2.688-15.813-4.473-24.767-4.473C287.739,221.305,275.261,226.639,260.848,232.808z"/>
|
||||
<path d="M122.222,160.915l0.279,0.26l0.182,0.109C122.542,161.146,122.388,161.022,122.222,160.915z"/>
|
||||
<path d="M404.039,145.275l-2.475-12.489c-2.222-11.206-7.265-21.794-18.767-25.844c-3.687-1.295-7.87-1.852-10.697-4.534
|
||||
c-2.827-2.682-3.663-6.847-4.317-10.709c-1.21-7.089-2.348-14.184-3.59-21.261c-1.071-6.084-1.919-12.919-4.711-18.501
|
||||
c-3.632-7.495-11.169-11.878-18.664-14.777c-3.84-1.434-7.759-2.646-11.738-3.632c-18.725-4.94-38.412-6.756-57.675-7.791
|
||||
c-23.122-1.276-46.305-0.891-69.372,1.15c-17.169,1.562-35.252,3.451-51.567,9.39c-5.963,2.173-12.108,4.782-16.642,9.389
|
||||
c-5.564,5.66-7.38,14.414-3.317,21.473c2.888,5.013,7.779,8.554,12.967,10.897c6.758,3.019,13.815,5.316,21.055,6.853
|
||||
c20.159,4.456,41.039,6.205,61.635,6.95c22.827,0.921,45.691,0.175,68.409-2.234c5.617-0.617,11.226-1.358,16.824-2.222
|
||||
c6.593-1.011,10.824-9.632,8.88-15.637c-2.324-7.18-8.572-9.965-15.637-8.881c-1.041,0.164-2.076,0.315-3.117,0.466l-0.751,0.109
|
||||
c-2.394,0.303-4.787,0.585-7.181,0.848c-4.943,0.533-9.9,0.969-14.868,1.308c-11.127,0.775-22.284,1.132-33.436,1.15
|
||||
c-10.957,0-21.92-0.309-32.854-1.029c-4.988-0.327-9.965-0.743-14.929-1.247c-2.258-0.236-4.51-0.484-6.762-0.763l-2.143-0.272
|
||||
l-0.466-0.067l-2.222-0.321c-4.54-0.684-9.081-1.471-13.573-2.422c-0.453-0.101-0.859-0.353-1.149-0.715s-0.449-0.813-0.449-1.277
|
||||
c0-0.464,0.158-0.915,0.449-1.277c0.291-0.362,0.696-0.614,1.149-0.715h0.085c3.893-0.829,7.816-1.538,11.751-2.155
|
||||
c1.312-0.206,2.627-0.408,3.947-0.605h0.036c2.464-0.163,4.94-0.605,7.392-0.896c21.332-2.219,42.791-2.975,64.225-2.264
|
||||
c10.407,0.303,20.807,0.914,31.165,1.968c2.227,0.23,4.444,0.472,6.66,0.745c0.848,0.103,1.701,0.224,2.554,0.327l1.719,0.248
|
||||
c5.012,0.747,9.999,1.653,14.96,2.718c7.349,1.598,16.787,2.119,20.056,10.171c1.041,2.555,1.513,5.394,2.088,8.076l0.732,3.42
|
||||
c0.02,0.061,0.033,0.124,0.042,0.188c1.732,8.072,3.465,16.144,5.201,24.215c0.126,0.596,0.13,1.212,0.008,1.81
|
||||
c-0.121,0.597-0.365,1.164-0.714,1.663c-0.35,0.499-0.799,0.921-1.319,1.239c-0.521,0.318-1.101,0.526-1.705,0.609h-0.049
|
||||
l-1.059,0.145l-1.047,0.139c-3.317,0.432-6.639,0.835-9.964,1.211c-6.551,0.747-13.111,1.392-19.681,1.937
|
||||
c-13.057,1.086-26.138,1.798-39.248,2.137c-6.679,0.177-13.356,0.26-20.031,0.248c-26.572-0.021-53.118-1.565-79.512-4.625
|
||||
c-2.857-0.339-5.715-0.702-8.572-1.072c2.216,0.285-1.61-0.218-2.385-0.327c-1.816-0.254-3.632-0.519-5.449-0.793
|
||||
c-6.096-0.914-12.156-2.04-18.24-3.027c-7.356-1.211-14.39-0.605-21.043,3.027c-5.461,2.989-9.881,7.571-12.671,13.137
|
||||
c-2.87,5.933-3.723,12.392-5.007,18.767c-1.283,6.375-3.281,13.234-2.524,19.778c1.628,14.124,11.502,25.602,25.705,28.169
|
||||
c13.361,2.422,26.794,4.382,40.264,6.053c52.913,6.481,106.368,7.255,159.447,2.313c4.322-0.403,8.639-0.844,12.949-1.319
|
||||
c1.347-0.148,2.709,0.007,3.987,0.454c1.278,0.446,2.441,1.173,3.402,2.128c0.961,0.954,1.697,2.112,2.152,3.386
|
||||
c0.457,1.276,0.621,2.637,0.483,3.985l-1.344,13.063c-2.708,26.4-5.415,52.797-8.124,79.191c-2.824,27.719-5.669,55.435-8.53,83.15
|
||||
c-0.807,7.805-1.614,15.61-2.422,23.411c-0.774,7.682-0.883,15.607-2.343,23.198c-2.299,11.939-10.382,19.269-22.175,21.952
|
||||
c-10.805,2.458-21.841,3.749-32.921,3.85c-12.284,0.067-24.561-0.478-36.843-0.412c-13.113,0.074-29.174-1.138-39.296-10.896
|
||||
c-8.893-8.572-10.122-21.994-11.333-33.599c-1.614-15.365-3.215-30.728-4.801-46.088l-8.899-85.414l-5.757-55.267
|
||||
c-0.097-0.913-0.194-1.815-0.285-2.735c-0.69-6.593-5.358-13.046-12.713-12.714c-6.296,0.28-13.452,5.631-12.713,12.714
|
||||
l4.268,40.972l8.827,84.753c2.514,24.075,5.023,48.153,7.525,72.235c0.484,4.613,0.938,9.239,1.447,13.852
|
||||
c2.767,25.208,22.018,38.792,45.858,42.62c13.924,2.239,28.187,2.7,42.316,2.929c18.114,0.29,36.407,0.987,54.225-2.294
|
||||
c26.401-4.843,46.209-22.473,49.036-49.817c0.807-7.895,1.614-15.791,2.422-23.689c2.684-26.12,5.364-52.243,8.039-78.367
|
||||
l8.754-85.36l4.014-39.12c0.199-1.94,1.02-3.763,2.336-5.201c1.316-1.438,3.062-2.414,4.977-2.784
|
||||
c7.549-1.471,14.766-3.983,20.135-9.728C405.359,169.225,407.06,157.298,404.039,145.275z M120.058,153.714
|
||||
c0.115-0.054-0.097,0.933-0.188,1.392C119.852,154.411,119.889,153.793,120.058,153.714z M120.791,159.381
|
||||
c0.061-0.043,0.242,0.199,0.43,0.49c-0.285-0.266-0.466-0.466-0.436-0.49H120.791z M121.511,160.331
|
||||
C121.771,160.774,121.911,161.052,121.511,160.331L121.511,160.331z M122.958,161.506h0.036c0,0.042,0.067,0.084,0.091,0.127
|
||||
c-0.04-0.047-0.085-0.089-0.133-0.127H122.958z M376.324,159.75c-2.712,2.579-6.797,3.777-10.836,4.377
|
||||
c-45.283,6.72-91.225,10.122-137.005,8.62c-32.763-1.12-65.182-4.758-97.618-9.341c-3.178-0.448-6.623-1.029-8.808-3.372
|
||||
c-4.117-4.419-2.095-13.319-1.023-18.658c0.981-4.892,2.857-11.412,8.675-12.108c9.081-1.065,19.627,2.767,28.611,4.129
|
||||
c10.816,1.651,21.673,2.972,32.57,3.965c46.506,4.238,93.793,3.578,140.093-2.621c8.439-1.134,16.847-2.452,25.226-3.953
|
||||
c7.464-1.338,15.741-3.85,20.251,3.881c3.094,5.267,3.506,12.313,3.027,18.264c-0.147,2.593-1.28,5.032-3.166,6.817H376.324z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 39 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" transform="scale(64)" fill="#1B1F23"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 968 B |
@@ -13,19 +13,18 @@ set -euo pipefail
|
||||
|
||||
PLUGIN_SLUG="piperless"
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
PROJECT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
|
||||
|
||||
# ── Read version from plugin header ───────────────────────────────────────
|
||||
VERSION=$( grep -oP '^\s*\*\s*Version:\s*\K[0-9.]+' "${PROJECT_DIR}/${PLUGIN_SLUG}.php" | head -1 )
|
||||
VERSION=$( grep -oP '^\s*\*\s*Version:\s*\K[0-9.]+' "${SCRIPT_DIR}/${PLUGIN_SLUG}.php" | head -1 )
|
||||
|
||||
if [[ -z "${VERSION}" ]]; then
|
||||
echo "Error: could not determine plugin version from ${PLUGIN_SLUG}.php"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BUILD_DIR="${PROJECT_DIR}/build"
|
||||
BUILD_DIR="${SCRIPT_DIR}/build"
|
||||
STAGING="${BUILD_DIR}/${PLUGIN_SLUG}"
|
||||
ZIP_FILE="${PROJECT_DIR}/${PLUGIN_SLUG}-${VERSION}.zip"
|
||||
ZIP_FILE="${SCRIPT_DIR}/${PLUGIN_SLUG}-${VERSION}.zip"
|
||||
|
||||
echo "=== Piperless Build Script ==="
|
||||
echo "Version: ${VERSION}"
|
||||
@@ -50,7 +49,7 @@ INCLUDE=(
|
||||
)
|
||||
|
||||
for item in "${INCLUDE[@]}"; do
|
||||
src="${PROJECT_DIR}/${item}"
|
||||
src="${SCRIPT_DIR}/${item}"
|
||||
if [[ -e "${src}" ]]; then
|
||||
cp -r "${src}" "${STAGING}/"
|
||||
else
|
||||
@@ -68,7 +67,7 @@ find "${STAGING}" -name '*.map' -delete
|
||||
echo "Creating ZIP archive…"
|
||||
cd "${BUILD_DIR}"
|
||||
zip -r "${ZIP_FILE}" "${PLUGIN_SLUG}" > /dev/null
|
||||
cd "${PROJECT_DIR}"
|
||||
cd "${SCRIPT_DIR}"
|
||||
|
||||
# ── Verify ────────────────────────────────────────────────────────────────
|
||||
ZIP_SIZE=$( du -h "${ZIP_FILE}" | cut -f1 )
|
||||
+4
-22
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Piperless v1.1.4 — Developer Documentation</title>
|
||||
<title>Piperless v1.1.0 — Developer Documentation</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #ffffff;
|
||||
@@ -55,7 +55,7 @@ td:first-child { font-family: "SF Mono", Monaco, monospace; font-size: 13px; }
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<h2>Piperless 1.1.4</h2>
|
||||
<h2>Piperless 1.1.0</h2>
|
||||
<a href="#overview">Overview</a>
|
||||
<a href="#architecture">Architecture</a>
|
||||
<a href="#plugin">Plugin (Orchestrator)</a>
|
||||
@@ -74,7 +74,7 @@ td:first-child { font-family: "SF Mono", Monaco, monospace; font-size: 13px; }
|
||||
<main>
|
||||
|
||||
<h1>Piperless</h1>
|
||||
<p>WordPress Plugin — Audio Transcripts via Piper TTS · v1.1.4 · Generated 2026-05-11</p>
|
||||
<p>WordPress Plugin — Audio Transcripts via Piper TTS · v1.1.0 · Generated 2026-05-09</p>
|
||||
|
||||
<h2 id="overview">Overview</h2>
|
||||
<p>
|
||||
@@ -90,7 +90,7 @@ HTML5 audio player on the frontend.
|
||||
<li>8 PHP classes, ~4,000 lines</li>
|
||||
<li>7 admin panel tabs, 4 REST API endpoints</li>
|
||||
<li>6 player themes + Custom CSS</li>
|
||||
<li>8 complete translations — DE, FR, ES, IT, JA, NL, PT, ZH (118 strings each)</li>
|
||||
<li>Full nl_NL translation (98 strings)</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="architecture">Architecture</h2>
|
||||
@@ -438,24 +438,6 @@ for deterministic attribution.
|
||||
<li>@ suppression on filesystem calls with error_clear_last() + log_last_error() for diagnostics</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="build">Build & Tooling</h2>
|
||||
|
||||
<p>The <code>Makefile</code> wraps the build and translation toolchain:</p>
|
||||
|
||||
<table>
|
||||
<tr><th>Command</th><th>Action</th></tr>
|
||||
<tr><td><code>make build</code></td><td>Create piperless-X.Y.Z.zip</td></tr>
|
||||
<tr><td><code>make translations</code></td><td>Extract .pot → JSON, sync to all locales</td></tr>
|
||||
<tr><td><code>make json2po</code></td><td>Convert JSON translations back to .po/.mo</td></tr>
|
||||
<tr><td><code>make check-translations</code></td><td>Validate translation integrity</td></tr>
|
||||
<tr><td><code>make lock-translations</code></td><td>Lock all locales for translation work</td></tr>
|
||||
<tr><td><code>make unlock-translations</code></td><td>Release all translation locks</td></tr>
|
||||
<tr><td><code>make translation-status</code></td><td>Show lock/completion for each locale</td></tr>
|
||||
<tr><td><code>make clean</code></td><td>Remove build artifacts</td></tr>
|
||||
</table>
|
||||
|
||||
<p>All tools run as standalone shell scripts in <code>tools/</code> — the Makefile is a convenience wrapper.</p>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Dashboard widget — audio storage at a glance.
|
||||
*
|
||||
* @package Piperless
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Piperless;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard widget.
|
||||
*
|
||||
* Registers a WordPress dashboard widget (togglable via Screen Options)
|
||||
* that shows:
|
||||
*
|
||||
* - Counts and total size of WAV, MP3, and Opus files in the cache
|
||||
* - Number of published posts without an audio transcript
|
||||
* - Available disk space on the server
|
||||
*
|
||||
* @since 1.1.4
|
||||
*/
|
||||
class Dashboard {
|
||||
|
||||
/** @var Logger */
|
||||
private Logger $logger;
|
||||
|
||||
/** @var Cache_Manager */
|
||||
private Cache_Manager $cache;
|
||||
|
||||
/** @var string Widget slug. */
|
||||
private string $widget_id = 'piperless_dashboard';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Logger $logger Logger.
|
||||
* @param Cache_Manager $cache Cache manager.
|
||||
*/
|
||||
public function __construct( Logger $logger, Cache_Manager $cache ) {
|
||||
$this->logger = $logger;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*/
|
||||
public function init(): void {
|
||||
add_action( 'wp_dashboard_setup', [ $this, 'register_widget' ] );
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_styles' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the dashboard widget.
|
||||
*/
|
||||
public function register_widget(): void {
|
||||
wp_add_dashboard_widget(
|
||||
$this->widget_id,
|
||||
__( 'Piperless — Audio Storage', 'piperless' ),
|
||||
[ $this, 'render' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the dashboard widget.
|
||||
*/
|
||||
public function render(): void {
|
||||
$file_stats = $this->get_file_stats();
|
||||
$without = $this->get_posts_without_audio();
|
||||
$disk = $this->get_disk_usage();
|
||||
$total_files = ( $file_stats['mp3']['count'] ?? 0 )
|
||||
+ ( $file_stats['wav']['count'] ?? 0 )
|
||||
+ ( $file_stats['opus']['count'] ?? 0 );
|
||||
?>
|
||||
|
||||
<div class="piperless-dashboard">
|
||||
<?php if ( 0 === $total_files ) : ?>
|
||||
<p class="piperless-dash-empty"><?php esc_html_e( 'No audio files generated yet. Publish a post or generate audio from the editor sidebar.', 'piperless' ); ?></p>
|
||||
<?php else : ?>
|
||||
<div class="piperless-dash-grid">
|
||||
<?php $this->render_file_card(
|
||||
__( 'Opus', 'piperless' ),
|
||||
$file_stats['opus'] ?? [ 'count' => 0, 'bytes' => 0 ],
|
||||
'#1565c0'
|
||||
); ?>
|
||||
<?php $this->render_file_card(
|
||||
__( 'MP3', 'piperless' ),
|
||||
$file_stats['mp3'] ?? [ 'count' => 0, 'bytes' => 0 ],
|
||||
'#008a20'
|
||||
); ?>
|
||||
<?php $this->render_file_card(
|
||||
__( 'WAV', 'piperless' ),
|
||||
$file_stats['wav'] ?? [ 'count' => 0, 'bytes' => 0 ],
|
||||
'#f56e28'
|
||||
); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="piperless-dash-info">
|
||||
<div class="piperless-dash-info-item piperless-dash-info-posts">
|
||||
<span class="piperless-dash-info-text">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of posts without audio */
|
||||
esc_html( _n(
|
||||
'%d post without an audio transcript.',
|
||||
'%d posts without an audio transcript.',
|
||||
$without,
|
||||
'piperless'
|
||||
) ),
|
||||
$without
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php if ( $without > 0 ) : ?>
|
||||
<a href="<?php echo esc_url( admin_url( 'edit.php?post_type=post' ) ); ?>" class="piperless-dash-info-link">
|
||||
<?php esc_html_e( 'View posts', 'piperless' ); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="piperless-dash-info-item piperless-dash-info-storage">
|
||||
<div class="piperless-dash-info-body">
|
||||
<span class="piperless-dash-info-text">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: free space, 2: total space */
|
||||
esc_html__( 'Server storage: %1$s free of %2$s', 'piperless' ),
|
||||
esc_html( $this->human_size( $disk['free'] ) ),
|
||||
esc_html( $this->human_size( $disk['total'] ) )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<div class="piperless-dash-bar">
|
||||
<div class="piperless-dash-bar-fill" style="width:<?php echo esc_attr( (string) round( $disk['pct'] ) ); ?>%;"></div>
|
||||
</div>
|
||||
<span class="piperless-dash-bar-label">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: percentage used */
|
||||
esc_html__( '%s%% used', 'piperless' ),
|
||||
esc_html( (string) round( $disk['pct'] ) )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single file-type stat card.
|
||||
*
|
||||
* @param string $label e.g. "MP3".
|
||||
* @param array $stats ['count' => int, 'bytes' => int].
|
||||
* @param string $color Accent color hex.
|
||||
*/
|
||||
private function render_file_card( string $label, array $stats, string $color ): void {
|
||||
$count = $stats['count'] ?? 0;
|
||||
$size = $this->human_size( $stats['bytes'] ?? 0 );
|
||||
?>
|
||||
<div class="piperless-dash-card" style="--card-accent: <?php echo esc_attr( $color ); ?>;">
|
||||
<div class="piperless-dash-card-value"><?php echo esc_html( (string) $count ); ?></div>
|
||||
<div class="piperless-dash-card-label"><?php echo esc_html( $label ); ?></div>
|
||||
<div class="piperless-dash-card-sub"><?php echo esc_html( $size ); ?></div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the cache directory and return per-format file counts and byte totals.
|
||||
*
|
||||
* @return array<string,array{count:int,bytes:int}>
|
||||
*/
|
||||
private function get_file_stats(): array {
|
||||
$cache_dir = $this->cache->dir();
|
||||
$stats = [
|
||||
'mp3' => [ 'count' => 0, 'bytes' => 0 ],
|
||||
'wav' => [ 'count' => 0, 'bytes' => 0 ],
|
||||
'opus' => [ 'count' => 0, 'bytes' => 0 ],
|
||||
];
|
||||
|
||||
if ( ! is_dir( $cache_dir ) ) {
|
||||
return $stats;
|
||||
}
|
||||
|
||||
foreach ( [ 'mp3', 'wav', 'opus' ] as $ext ) {
|
||||
$files = (array) glob( $cache_dir . '/*.' . $ext );
|
||||
foreach ( $files as $file ) {
|
||||
$size = @filesize( $file );
|
||||
if ( false !== $size ) {
|
||||
$stats[ $ext ]['count']++;
|
||||
$stats[ $ext ]['bytes'] += $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count published posts / pages without an audio transcript.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function get_posts_without_audio(): int {
|
||||
global $wpdb;
|
||||
|
||||
$types = $this->supported_post_types();
|
||||
$placeholders = implode( ',', array_fill( 0, count( $types ), '%s' ) );
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*)
|
||||
FROM {$wpdb->posts} p
|
||||
WHERE p.post_type IN ( {$placeholders} )
|
||||
AND p.post_status = 'publish'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM {$wpdb->postmeta} pm
|
||||
WHERE pm.post_id = p.ID
|
||||
AND pm.meta_key = '_piperless_audio_url'
|
||||
AND pm.meta_value != ''
|
||||
)",
|
||||
...$types
|
||||
)
|
||||
);
|
||||
|
||||
return (int) $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get disk usage stats for the uploads directory volume.
|
||||
*
|
||||
* @return array{total:float,free:float,used:float,pct:float}
|
||||
*/
|
||||
private function get_disk_usage(): array {
|
||||
$dir = $this->cache->dir();
|
||||
|
||||
// Walk up until we find a directory that exists.
|
||||
while ( ! is_dir( $dir ) && '/' !== $dir ) {
|
||||
$dir = dirname( $dir );
|
||||
}
|
||||
|
||||
$total = @disk_total_space( $dir );
|
||||
$free = @disk_free_space( $dir );
|
||||
|
||||
$fallback = [ 'total' => 0.0, 'free' => 0.0, 'used' => 0.0, 'pct' => 0.0 ];
|
||||
|
||||
if ( false === $total || null === $total || false === $free || null === $free || $total <= 0.0 ) {
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
$used = $total - $free;
|
||||
$pct = ( $used / $total ) * 100.0;
|
||||
|
||||
return [
|
||||
'total' => (float) $total,
|
||||
'free' => (float) $free,
|
||||
'used' => (float) $used,
|
||||
'pct' => (float) $pct,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Format bytes as a human-readable string.
|
||||
*
|
||||
* @param float $bytes Raw byte count.
|
||||
* @return string e.g. "24.5 MB"
|
||||
*/
|
||||
private function human_size( float $bytes ): string {
|
||||
if ( $bytes <= 0.0 ) {
|
||||
return '0 B';
|
||||
}
|
||||
|
||||
$units = [ 'B', 'KB', 'MB', 'GB', 'TB' ];
|
||||
$exp = (int) floor( log( $bytes, 1024 ) );
|
||||
$exp = min( $exp, count( $units ) - 1 );
|
||||
|
||||
$val = $bytes / ( 1024 ** $exp );
|
||||
|
||||
return round( $val, 1 ) . ' ' . $units[ $exp ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue dashboard-specific styles on the dashboard page only.
|
||||
*
|
||||
* @param string $hook_suffix Current admin page hook.
|
||||
*/
|
||||
public function enqueue_styles( string $hook_suffix ): void {
|
||||
if ( 'index.php' !== $hook_suffix ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_style(
|
||||
'piperless-dashboard',
|
||||
PIPERLESS_PLUGIN_URL . 'assets/css/dashboard.css',
|
||||
[],
|
||||
PIPERLESS_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported post types for audio transcripts.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function supported_post_types(): array {
|
||||
$types = apply_filters( 'piperless_post_types', [ 'post', 'page' ] );
|
||||
return is_array( $types ) ? $types : [ 'post' ];
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,6 @@ class Plugin {
|
||||
/** @var Gutenberg */
|
||||
private Gutenberg $gutenberg;
|
||||
|
||||
/** @var Dashboard */
|
||||
private Dashboard $dashboard;
|
||||
|
||||
/**
|
||||
* Private constructor — use ::instance().
|
||||
*/
|
||||
@@ -71,7 +68,6 @@ class Plugin {
|
||||
$this->transcriber = new Transcriber( $this->logger, $this->piper, $this->cache_manager );
|
||||
$this->player = new Player( $this->logger );
|
||||
$this->gutenberg = new Gutenberg( $this->logger, $this->transcriber, $this->cache_manager );
|
||||
$this->dashboard = new Dashboard( $this->logger, $this->cache_manager );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +89,6 @@ class Plugin {
|
||||
$this->settings->init();
|
||||
$this->gutenberg->init();
|
||||
$this->player->init();
|
||||
$this->dashboard->init();
|
||||
|
||||
// Auto-generate on publish.
|
||||
add_action( 'transition_post_status', [ $this, 'maybe_auto_generate' ], 10, 3 );
|
||||
|
||||
@@ -569,6 +569,10 @@ class Settings {
|
||||
class="nav-tab <?php echo 'logs' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'Logs', 'piperless' ); ?>
|
||||
</a>
|
||||
<a href="?page=<?php echo esc_attr( $this->page_slug ); ?>&tab=help"
|
||||
class="nav-tab <?php echo 'help' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'Help', 'piperless' ); ?>
|
||||
</a>
|
||||
<a href="?page=<?php echo esc_attr( $this->page_slug ); ?>&tab=about"
|
||||
class="nav-tab <?php echo 'about' === $active_tab ? 'nav-tab-active' : ''; ?>">
|
||||
<?php esc_html_e( 'About', 'piperless' ); ?>
|
||||
@@ -633,18 +637,6 @@ class Settings {
|
||||
<p class="piperless-about-blurb">
|
||||
<?php esc_html_e( 'Piperless turns your WordPress posts into audio transcripts. Developed by Forkless, it makes your content accessible, engaging, and easy to listen to. Quick setup, high-quality speech, and seamless integration.', 'piperless' ); ?>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://github.com/forkless/Piperless" target="_blank" class="piperless-about-link">
|
||||
<img src="<?php echo esc_url( PIPERLESS_PLUGIN_URL . 'assets/svg/github.svg' ); ?>" class="piperless-about-link-icon" alt="" aria-hidden="true" width="18" height="18">
|
||||
<?php esc_html_e( 'GitHub Repository', 'piperless' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://buymeacoffee.com/forkless" target="_blank" class="piperless-about-link">
|
||||
<img src="<?php echo esc_url( PIPERLESS_PLUGIN_URL . 'assets/svg/coffee.svg' ); ?>" class="piperless-about-link-icon" alt="" aria-hidden="true" width="18" height="18">
|
||||
<?php esc_html_e( 'Buy me a coffee', 'piperless' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
<p class="piperless-about-contact">
|
||||
<?php esc_html_e( 'Questions? Contact the developers at', 'piperless' ); ?>
|
||||
<a href="mailto:devs@forkless.com">devs@forkless.com</a>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "de_DE",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "FFprobe-Binärpfad",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Absoluter Pfad zur ffprobe-Binärdatei für die Erkennung der Audiodauer. Automatische Erkennung aus dem ffmpeg-Verzeichnis, wenn leer.",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Absoluter Pfad zur ffmpeg-Binärdatei für MP3/Opus-Konvertierung. Automatische Erkennung aus üblichen Pfaden, wenn leer.",
|
||||
"Dan Rather Blue": "Dan Rather Blue",
|
||||
"GitHub Repository": "GitHub-Repository",
|
||||
"Buy me a coffee": "Kauf mir einen Kaffee"
|
||||
"Dan Rather Blue": "Dan Rather Blue"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "Absoluter Pfad zur ffmpeg-Binärdatei für MP3/Opus-Konvertierung. Autom
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHub-Repository"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Kauf mir einen Kaffee"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "es_ES",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "Ruta del binario FFprobe",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Ruta absoluta al binario ffprobe para la detección de la duración del audio. Se detecta automáticamente desde el directorio ffmpeg si se deja vacío.",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Ruta absoluta al binario ffmpeg para la conversión MP3/Opus. Se detecta automáticamente si se deja vacío.",
|
||||
"Dan Rather Blue": "Dan Rather Blue",
|
||||
"GitHub Repository": "Repositorio GitHub",
|
||||
"Buy me a coffee": "Invítame a un café"
|
||||
"Dan Rather Blue": "Dan Rather Blue"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "Ruta absoluta al binario ffmpeg para la conversión MP3/Opus. Se detecta
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "Repositorio GitHub"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Invítame a un café"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "fr_FR",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "Chemin du binaire FFprobe",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Chemin absolu vers le binaire ffprobe pour la détection de la durée audio. Auto-détecté depuis le répertoire ffmpeg si laissé vide.",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Chemin absolu vers le binaire ffmpeg pour la conversion MP3/Opus. Auto-détecté depuis les chemins courants si laissé vide.",
|
||||
"Dan Rather Blue": "Dan Rather Blue",
|
||||
"GitHub Repository": "Dépôt GitHub",
|
||||
"Buy me a coffee": "Offrez-moi un café"
|
||||
"Dan Rather Blue": "Dan Rather Blue"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "Chemin absolu vers le binaire ffmpeg pour la conversion MP3/Opus. Auto-d
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "Dépôt GitHub"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Offrez-moi un café"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "it_IT",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "Percorso binario FFprobe",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Percorso assoluto al binario ffprobe per il rilevamento della durata audio. Rilevato automaticamente dalla directory ffmpeg se lasciato vuoto.",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Percorso assoluto al binario ffmpeg per la conversione MP3/Opus. Rilevato automaticamente se lasciato vuoto.",
|
||||
"Dan Rather Blue": "Dan Rather Blue",
|
||||
"GitHub Repository": "Repository GitHub",
|
||||
"Buy me a coffee": "Offrimi un caffè"
|
||||
"Dan Rather Blue": "Dan Rather Blue"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "Percorso assoluto al binario ffmpeg per la conversione MP3/Opus. Rilevat
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "Repository GitHub"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Offrimi un caffè"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "ja",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "FFprobeバイナリパス",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "音声の長さ検出用ffprobeバイナリへの絶対パス。空の場合はffmpegディレクトリから自動検出されます。",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "MP3/Opus変換用ffmpegバイナリへの絶対パス。空の場合は自動検出されます。",
|
||||
"Dan Rather Blue": "ダン・ラザー・ブルー",
|
||||
"GitHub Repository": "GitHubリポジトリ",
|
||||
"Buy me a coffee": "コーヒーを奢ってください"
|
||||
"Dan Rather Blue": "ダン・ラザー・ブルー"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "MP3/Opus変換用ffmpegバイナリへの絶対パス。空の場合は
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "ダン・ラザー・ブルー"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHubリポジトリ"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "コーヒーを奢ってください"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "nl_NL",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "FFprobe-binair pad",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Absoluut pad naar de ffprobe binary voor audioduurdetectie. Automatisch gedetecteerd vanuit de ffmpeg-directory, indien leeg gelaten.",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Absoluut pad naar de ffmpeg binary voor MP3/Opus-conversie. Automatisch gedetecteerd als leeg gelaten.",
|
||||
"Dan Rather Blue": "Dan Rather Blue",
|
||||
"GitHub Repository": "GitHub-repository",
|
||||
"Buy me a coffee": "Koop een kop koffie voor me"
|
||||
"Dan Rather Blue": "Dan Rather Blue"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "Absoluut pad naar de ffmpeg binary voor MP3/Opus-conversie. Automatisch
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHub-repository"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Koop een kop koffie voor me"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "pt_BR",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "Caminho do binário FFprobe",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "Caminho absoluto para o binário ffprobe para detecção de duração do áudio. Detectado automaticamente do diretório ffmpeg se deixado vazio.",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "Caminho absoluto para o binário ffmpeg para conversão MP3/Opus. Detectado automaticamente se deixado vazio.",
|
||||
"Dan Rather Blue": "Dan Rather Blue",
|
||||
"GitHub Repository": "Repositório GitHub",
|
||||
"Buy me a coffee": "Me pague um café"
|
||||
"Dan Rather Blue": "Dan Rather Blue"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "Caminho absoluto para o binário ffmpeg para conversão MP3/Opus. Detect
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "Repositório GitHub"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Me pague um café"
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"locale": "zh_CN",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"total_strings": 118,
|
||||
"translated": 118,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -125,8 +125,6 @@
|
||||
"FFprobe Binary Path": "FFprobe 二进制文件路径",
|
||||
"Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.": "ffprobe 二进制文件的绝对路径,用于音频时长检测。留空则从 ffmpeg 目录自动检测。",
|
||||
"Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.": "ffmpeg 二进制文件的绝对路径,用于 MP3/Opus 转换。留空则自动检测。",
|
||||
"Dan Rather Blue": "丹·拉瑟蓝",
|
||||
"GitHub Repository": "GitHub 仓库",
|
||||
"Buy me a coffee": "请我喝杯咖啡"
|
||||
"Dan Rather Blue": "丹·拉瑟蓝"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -478,9 +478,3 @@ msgstr "ffmpeg 二进制文件的绝对路径,用于 MP3/Opus 转换。留空
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "丹·拉瑟蓝"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHub 仓库"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "请我喝杯咖啡"
|
||||
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: Piperless — Audio Transcripts
|
||||
* Plugin URI: https://forkless.com
|
||||
* Description: Generate audio transcripts of WordPress posts using Piper TTS. Customizable players, caching, and full Gutenberg integration.
|
||||
* Version: 1.1.4
|
||||
* Version: 1.1.2
|
||||
* Requires at least: 6.0
|
||||
* Requires PHP: 8.0
|
||||
* Author: Forkless
|
||||
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
}
|
||||
|
||||
// ── Constants ────────────────────────────────────────────────────────────────
|
||||
define( 'PIPERLESS_VERSION', '1.1.4' );
|
||||
define( 'PIPERLESS_VERSION', '1.1.2' );
|
||||
define( 'PIPERLESS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||
define( 'PIPERLESS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||
define( 'PIPERLESS_PLUGIN_FILE', __FILE__ );
|
||||
|
||||
Reference in New Issue
Block a user