mirror of
https://github.com/forkless/Piperless.git
synced 2026-08-17 01:01:48 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a748c79298 |
@@ -0,0 +1,11 @@
|
||||
# Project Structure (Auto-generated)
|
||||
|
||||
> This file was automatically generated by DeepSeek TUI.
|
||||
> You can edit or delete it at any time.
|
||||
|
||||
**Summary:** Unknown project type
|
||||
|
||||
**Tree:**
|
||||
```
|
||||
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
# Build artifacts
|
||||
build/
|
||||
*.zip
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -0,0 +1,19 @@
|
||||
# Project Instructions
|
||||
|
||||
This file provides context for AI assistants working on this project.
|
||||
|
||||
## Project Type: Unknown
|
||||
|
||||
<!-- Add build/test commands here -->
|
||||
|
||||
|
||||
## Guidelines
|
||||
|
||||
- Follow existing code style and patterns
|
||||
- Write tests for new functionality
|
||||
- Keep changes focused and atomic
|
||||
- Document public APIs
|
||||
|
||||
## Important Notes
|
||||
|
||||
<!-- Add project-specific notes here -->
|
||||
@@ -1,79 +0,0 @@
|
||||
# Security Audit — Piperless v1.1.3
|
||||
|
||||
**Audit date:** 2026-05-10
|
||||
**Scope:** All 8 PHP classes (`includes/*.php`), plus `uninstall.php`
|
||||
**Findings:** 1 (fixed). Open: 0
|
||||
**Auditor:** DeepSeek V4 Pro (systematic automated review)
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
29 categories reviewed. One logic-level bug found and fixed mid-session (settings data loss on partial form save). Zero outstanding security vulnerabilities — critical, high, medium, or low.
|
||||
|
||||
|
||||
## Results
|
||||
|
||||
| # | Category | Finding | Notes |
|
||||
|---|----------|---------|-------|
|
||||
| 1 | Command injection | ✅ Pass | 30+ `escapeshellarg()` calls. Zero `escapeshellcmd()`. |
|
||||
| 2 | SQL injection | ✅ Pass | Single `$wpdb->get_results()` uses `$wpdb->prepare()` with `%s`. |
|
||||
| 3 | XSS (frontend player) | ✅ Pass | `esc_attr()`, `esc_html()`, `esc_url()` on all outputs. |
|
||||
| 4 | XSS (admin panel) | ✅ Pass | Voice dropdown pre-rendered with `esc_attr`/`esc_html`. Field values escaped. |
|
||||
| 5 | XSS (Gutenberg sidebar) | ✅ Pass | REST responses sanitized via `sanitize_text_field()`. |
|
||||
| 6 | AJAX authorization | ✅ Pass | All 10 handlers check `manage_options` capability. |
|
||||
| 7 | REST authorization | ✅ Pass | `current_user_can('edit_post', $post_id)` on generate/status/remove. |
|
||||
| 8 | Post meta auth | ✅ Pass | 11 `register_post_meta()` calls have `current_user_can` auth callback. |
|
||||
| 9 | Nonce verification | ✅ Pass | All 11 AJAX endpoints call `check_ajax_referer()`. |
|
||||
| 10 | Rate limiting | ✅ Pass | Transient-based per-IP on audio proxy. Configurable 1–600 req/min. |
|
||||
| 11 | Cache key validation | ✅ Pass | Regex `^[a-zA-Z0-9_-]+$` on proxy endpoint + AJAX delete handler. |
|
||||
| 12 | Path traversal | ✅ Pass | Cache keys regex-validated. Model paths stripped to basename in REST. |
|
||||
| 13 | Concurrency mutex | ✅ Pass | Transient-based, 5-min TTL, released on success and failure paths. |
|
||||
| 14 | Process timeout | ✅ Pass | `set_time_limit()` guard on Piper calls; restored in `finally` block. |
|
||||
| 15 | Log file security | ✅ Pass | `chmod 0600` after every write. |
|
||||
| 16 | Settings sanitization (partial saves) | 🔧 Fixed | Logs tab save wiped all settings. Fixed with `array_merge($existing, $input)`. |
|
||||
| 17 | CSS sanitization | ✅ Pass | `sanitize_css()` strips `url()`, `expression()`, `@import`, `behavior:`, `-moz-binding`. |
|
||||
| 18 | Input validation (Piper) | ✅ Pass | Model paths checked with `file_exists()`. Quality parameter enum-validated. |
|
||||
| 19 | Input validation (voice aliases) | ✅ Pass | `sanitize_text_field()` on both keys and values. |
|
||||
| 20 | Directory creation | ✅ Pass | `wp_mkdir_p()` used; validates under `WP_CONTENT_DIR`. |
|
||||
| 21 | File write safety | ✅ Pass | `error_clear_last()` before every `@file_put_contents()`. |
|
||||
| 22 | open_basedir awareness | ✅ Pass | String-prefix matching before any `is_dir()`/`file_exists()` call. |
|
||||
| 23 | Cron job safety | ✅ Pass | `wp_schedule_single_event()` with deduplication check. |
|
||||
| 24 | Uninstall cleanliness | ✅ Pass | Options and post meta cleaned; cron hook deregistered. |
|
||||
| 25 | Error handling | ✅ Pass | All `exec()` calls check return codes. Temp files cleaned with `@unlink`. |
|
||||
| 26 | Activation safety | ✅ Pass | PHP/WordPress version check only. No destructive operations. |
|
||||
| 27 | Sensitive data exposure | ✅ Pass | No API keys, passwords, or credentials stored or logged. |
|
||||
| 28 | File permissions | ✅ Pass | Cache directory created with proper permissions. Log `chmod 0600`. |
|
||||
| 29 | HTTP security headers | ✅ Pass | `Content-Range`, `Accept-Ranges: bytes`, `Cache-Control: public, max-age=86400`. |
|
||||
|
||||
|
||||
## Legend
|
||||
|
||||
| Symbol | Meaning |
|
||||
|--------|---------|
|
||||
| ✅ Pass | No vulnerability found |
|
||||
| 🔧 Fixed | Bug found and resolved |
|
||||
|
||||
|
||||
## Defense-in-Depth Layers
|
||||
|
||||
Piperless shells out to the Piper TTS engine and ffmpeg — both system binaries. The security model is built around controlling this boundary:
|
||||
|
||||
1. **Input layer:** All user input — POST params, REST params, cache keys, model paths — is validated before touching the filesystem or shell.
|
||||
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.
|
||||
|
||||
|
||||
## Audit Methodology
|
||||
|
||||
Each PHP file was reviewed against all 29 categories. The review examined:
|
||||
|
||||
- Every `exec()`, `proc_open()`, `shell_exec()` call path
|
||||
- Every `echo`, `printf`, direct HTML output
|
||||
- Every `$_POST`, `$_GET`, `$_SERVER`, `get_param()` access point
|
||||
- Every `file_exists()`, `is_dir()`, `fopen()`, `file_put_contents()` call
|
||||
- Every `wpdb` query and `maybe_unserialize()` usage
|
||||
- Every `add_action`, `register_post_meta`, `register_rest_route` registration
|
||||
|
||||
The audit was performed programmatically by scanning source files for known vulnerability patterns, then reviewed manually for false positives and context.
|
||||
@@ -2,41 +2,6 @@
|
||||
|
||||
All notable changes to the Piperless WordPress plugin.
|
||||
|
||||
## [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
|
||||
|
||||
- **Player not rendering for logged-out users** — removed `in_the_loop()` guard from `maybe_prepend_player()`. Some themes override `in_the_loop()` in non-admin contexts, causing the player HTML to be suppressed for logged-out visitors. `is_main_query()` is retained as the sole duplicate-check guard.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Audio Format field moved above MP3 Bitrate** — the Piper tab now shows Audio Format first, then the relevant bitrate selectors.
|
||||
|
||||
## [1.1.0] — 2026-05-10
|
||||
|
||||
### Added
|
||||
|
||||
- **Opus audio format** — new "Audio Format" selector (MP3 / Opus) in the Piper tab. Opus encodes with `libopus` (`-application voip`) for better quality at lower bitrates. Separate bitrate selector for Opus: 24k (standard), 16k (compact), 12k (minimal). Cache key includes format so switching regenerates files.
|
||||
- **Gutenberg sidebar format support** — preview player uses `<source>` with explicit `type="audio/ogg"` for Opus files. Format tracked in `_piperless_audio_format` post meta and returned in REST responses.
|
||||
- **ffprobe-based duration detection** — for MP3 and Opus files, uses `find_ffprobe()` (same directory as resolved ffmpeg) to read exact duration. Falls back to WAV header calculation.
|
||||
- **Cache entry deletion clears post meta** — deleting an entry now removes all related meta fields from the owning post.
|
||||
- **Server-side cache sorting** — Size and Created columns now sort the entire dataset before pagination, not just the current page.
|
||||
- **Professional pagination** — Previous/Next/First/Last buttons, smart page numbers with ellipsis, "X items" count, placed at both top and bottom of the cache browser.
|
||||
|
||||
### Changed
|
||||
|
||||
- **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.
|
||||
|
||||
## [1.0.0] — 2026-05-09
|
||||
|
||||
### Added
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
> **Transparency note:** Piperless was developed using AI-assisted CLI tools (DeepSeek V4 Pro). Every line of code, security review, and translation was generated through prompt-driven development — then reviewed, tested, and hardened by a human. This weekend project started out of curiosity for what AI technology can do. Total development cost: one working day and less than the price of a cup of coffee in AI tokens.
|
||||
|
||||
---
|
||||
|
||||
## What It Does
|
||||
|
||||
@@ -15,21 +16,23 @@ Piperless converts every published post into a natural-sounding audio transcript
|
||||
- **Commuting** readers can consume posts as audio
|
||||
- **Non-native speakers** benefit from hearing correct pronunciation
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- **Automatic generation** — optionally generate audio when a post is published. No per-post action required.
|
||||
- **6 player themes** — Classic, Minimal, Modern Dark, Ron Burgundy, Dan Rather Blue, and Custom CSS. Match your brand.
|
||||
- **6 player themes** — Classic, Minimal, Modern Dark, NewsViews, NewsViews Classic, and Custom CSS. Match your brand.
|
||||
- **Per-post overrides** — customize voice, language, quality, player style, and placement for individual posts via the Gutenberg sidebar.
|
||||
- **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.
|
||||
- **8 admin languages** — Dutch, German, French, Spanish, Chinese (Simplified), Japanese, Brazilian Portuguese, and Italian translations included.
|
||||
|
||||
---
|
||||
|
||||
## Why the Excerpt Matters
|
||||
|
||||
@@ -43,6 +46,7 @@ Piperless solves this by **using the WordPress excerpt field first**. Write a cl
|
||||
|
||||
**Pro tip:** Think of the excerpt as your "audio script." It doesn't replace the post — it's the version that sounds natural when read aloud.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -57,6 +61,7 @@ Piperless solves this by **using the WordPress excerpt field first**. Write a cl
|
||||
|
||||
**Piperless will not work on shared hosting.** It requires shell access to install Piper and the ability to run system binaries via `proc_open`.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -103,6 +108,7 @@ Go to **Settings → Piperless** and set:
|
||||
|
||||
Open any post in the block editor. In the Piperless sidebar panel, click **Generate Audio**. The audio player will appear in your post automatically based on your placement settings.
|
||||
|
||||
---
|
||||
|
||||
## Admin Panel
|
||||
|
||||
@@ -116,8 +122,10 @@ 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 |
|
||||
| **Help** | Usage instructions and ffmpeg notes |
|
||||
| **About** | Version and contact information |
|
||||
|
||||
---
|
||||
|
||||
## Player Themes
|
||||
|
||||
@@ -126,14 +134,15 @@ Six built-in themes plus unlimited custom CSS:
|
||||
| Theme | Description |
|
||||
|-------|-------------|
|
||||
| **Classic** | Blue accent, clean borders |
|
||||
| **Minimal** | Clean, understated |
|
||||
| **Modern Dark** | Dark background |
|
||||
| **Ron Burgundy** | Bold burgundy |
|
||||
| **Dan Rather Blue** | Classic navy |
|
||||
| **Minimal** | Dark text, no border decoration |
|
||||
| **Modern Dark** | Blue accent on dark background |
|
||||
| **NewsViews** | Burgundy accent (#B31942) |
|
||||
| **NewsViews Classic** | Navy accent (#233452) |
|
||||
| **Custom CSS** | Full control — base theme with your own styles |
|
||||
|
||||
Each theme is a standalone CSS file. Switch themes instantly from the Styling tab.
|
||||
|
||||
---
|
||||
|
||||
## Accessibility
|
||||
|
||||
@@ -144,6 +153,7 @@ Piperless was built with accessibility in mind:
|
||||
- **Keyboard navigation** — player is a navigable region
|
||||
- **Content-as-transcript** — since the audio is generated from the post text, the text itself serves as the transcript for WCAG compliance
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
@@ -158,8 +168,9 @@ Piperless shells out to system binaries. It was built with defense-in-depth from
|
||||
- **Process isolation** — `set_time_limit()` guards with configurable timeouts
|
||||
- **open_basedir aware** — string-prefix matching before any filesystem call to prevent hangs
|
||||
|
||||
Comprehensive review: **29/29 categories cleared. 1 logic bug found and fixed. Zero open findings.** [See full audit →](AUDIT.md)
|
||||
Comprehensive review: **29/29 categories cleared. Zero critical, zero high, zero medium findings.**
|
||||
|
||||
---
|
||||
|
||||
## Translation
|
||||
|
||||
@@ -167,17 +178,18 @@ 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.
|
||||
|
||||
---
|
||||
|
||||
## Filters & Hooks
|
||||
|
||||
@@ -193,6 +205,7 @@ The admin panel, Gutenberg sidebar, and frontend player are fully translated. Se
|
||||
- `[piperless_player]` — render the audio player for the current post
|
||||
- `[piperless_player post_id="123"]` — render the player for a specific post
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
@@ -210,30 +223,15 @@ includes/
|
||||
└── 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.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT-licensed. Piperless is free and open-source. Piper TTS is also MIT-licensed. Voice models vary — check individual model licenses.
|
||||
|
||||
---
|
||||
|
||||
## Links
|
||||
|
||||
|
||||
@@ -255,11 +255,6 @@
|
||||
color: #50575e;
|
||||
}
|
||||
|
||||
.piperless-cache-badge--opus {
|
||||
background: #e3f2fd;
|
||||
color: #1565c0;
|
||||
}
|
||||
|
||||
.piperless-cache-badge--orphan {
|
||||
background: #fcf0f1;
|
||||
color: #b32d2e;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Piperless Player — Dan Rather Blue Theme
|
||||
* Piperless Player — NewsViews Classic Theme
|
||||
*
|
||||
* Based on the Ron Burgundy style with #233452 replacing the burgundy accent.
|
||||
* Based on the NewsViews style with #233452 replacing the burgundy accent.
|
||||
*/
|
||||
|
||||
.piperless-player--newsviews-classic {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Piperless Player — Ron Burgundy Theme
|
||||
* Piperless Player — NewsViews Theme
|
||||
*
|
||||
* Based on the Classic style with #B31942 replacing the blue accent.
|
||||
*/
|
||||
|
||||
+32
-66
@@ -214,54 +214,6 @@
|
||||
let cacheSortKey = 'created';
|
||||
let cacheSortAsc = false;
|
||||
|
||||
/**
|
||||
* Build WordPress-style pagination bar with Previous / Next buttons
|
||||
* and page numbers. Renders a full .tablenav div.
|
||||
*
|
||||
* @param {number} current Current page.
|
||||
* @param {number} totalPages Total pages.
|
||||
* @param {number} totalItems Total items.
|
||||
* @return {string} HTML string, or empty string if only one page.
|
||||
*/
|
||||
function buildPaginationHtml( current, totalPages, totalItems ) {
|
||||
if ( totalPages <= 1 ) return '';
|
||||
|
||||
var html = '<div class="tablenav top" style="display:flex;align-items:center;justify-content:flex-end;gap:12px;margin-bottom:8px;">';
|
||||
html += '<div class="tablenav-pages" style="display:flex;align-items:center;gap:4px;">';
|
||||
html += '<span class="displaying-num" style="margin-right:8px;">' + totalItems + ' items</span>';
|
||||
|
||||
// First page button.
|
||||
html += '<a href="#" class="first-page button piperless-cache-page' + ( current === 1 ? ' disabled' : '' ) + '" data-page="1" aria-label="First page">«</a>';
|
||||
// Previous button.
|
||||
html += '<a href="#" class="prev-page button piperless-cache-page' + ( current === 1 ? ' disabled' : '' ) + '" data-page="' + ( current - 1 ) + '" aria-label="Previous page">‹</a>';
|
||||
|
||||
// Page numbers.
|
||||
html += '<span class="paging-input" style="display:flex;align-items:center;gap:2px;">';
|
||||
for ( var i = 1; i <= totalPages; i++ ) {
|
||||
if ( Math.abs( i - current ) <= 2 || i === 1 || i === totalPages ) {
|
||||
if ( i === current ) {
|
||||
html += '<span class="tablenav-paging-text"><strong>' + i + '</strong></span>';
|
||||
} else {
|
||||
html += '<a href="#" class="piperless-cache-page" data-page="' + i + '" style="text-decoration:none;padding:0 4px;">' + i + '</a>';
|
||||
}
|
||||
} else if ( i === 2 && current > 4 ) {
|
||||
html += '<span class="tablenav-paging-text">…</span>';
|
||||
} else if ( i === totalPages - 1 && current < totalPages - 3 ) {
|
||||
html += '<span class="tablenav-paging-text">…</span>';
|
||||
}
|
||||
}
|
||||
html += '</span>';
|
||||
|
||||
// Next button.
|
||||
html += '<a href="#" class="next-page button piperless-cache-page' + ( current === totalPages ? ' disabled' : '' ) + '" data-page="' + ( current + 1 ) + '" aria-label="Next page">›</a>';
|
||||
// Last page button.
|
||||
html += '<a href="#" class="last-page button piperless-cache-page' + ( current === totalPages ? ' disabled' : '' ) + '" data-page="' + totalPages + '" aria-label="Last page">»</a>';
|
||||
|
||||
html += '</div></div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function loadCacheBrowser( page ) {
|
||||
const $browser = $( '#piperless-cache-browser' );
|
||||
$browser.html( '<p>' + 'Loading…' + '</p>' );
|
||||
@@ -271,8 +223,6 @@
|
||||
nonce: admin.nonce,
|
||||
page: page || 1,
|
||||
per_page: 15,
|
||||
sort_by: cacheSortKey,
|
||||
sort_order: cacheSortAsc ? 'asc' : 'desc',
|
||||
} ).done( function ( resp ) {
|
||||
if ( ! resp.success || ! resp.data ) {
|
||||
$browser.html( '<p>Failed to load cache entries.</p>' );
|
||||
@@ -286,12 +236,6 @@
|
||||
if ( d.total === 0 ) {
|
||||
html = '<p>No cached audio files.</p>';
|
||||
} else {
|
||||
// ── Pagination bar (top) ──
|
||||
var paginationHtml = buildPaginationHtml( cachePage, d.pages, d.total );
|
||||
if ( paginationHtml ) {
|
||||
html += paginationHtml;
|
||||
}
|
||||
|
||||
html += '<table class="wp-list-table widefat fixed striped">';
|
||||
html += '<thead><tr>';
|
||||
html += '<th><input type="checkbox" class="piperless-select-all"></th>';
|
||||
@@ -301,7 +245,23 @@
|
||||
html += '<th>Format</th><th>Model</th><th>Shortcode</th><th>Status</th><th>Actions</th>';
|
||||
html += '</tr></thead><tbody>';
|
||||
|
||||
d.entries.forEach( function ( entry ) {
|
||||
// Apply client-side sort if active.
|
||||
let entries = d.entries;
|
||||
if ( cacheSortKey === 'size' ) {
|
||||
entries = entries.slice().sort( function ( a, b ) {
|
||||
return cacheSortAsc
|
||||
? ( a.size_bytes || 0 ) - ( b.size_bytes || 0 )
|
||||
: ( b.size_bytes || 0 ) - ( a.size_bytes || 0 );
|
||||
} );
|
||||
} else if ( cacheSortKey === 'created' ) {
|
||||
entries = entries.slice().sort( function ( a, b ) {
|
||||
const da = a.created || '';
|
||||
const db = b.created || '';
|
||||
return cacheSortAsc ? da.localeCompare( db ) : db.localeCompare( da );
|
||||
} );
|
||||
}
|
||||
|
||||
entries.forEach( function ( entry ) {
|
||||
const sizeKB = ( entry.size_bytes / 1024 ).toFixed( 1 );
|
||||
const postIdCell = entry.post_id
|
||||
? '<a href="' + entry.edit_url + '">#' + entry.post_id + '</a>'
|
||||
@@ -312,12 +272,9 @@
|
||||
const bitrateSuffix = entry.bitrate ? ' · ' + entry.bitrate : '';
|
||||
const formatBadge = entry.orphaned
|
||||
? '<span class="piperless-cache-badge piperless-cache-badge--orphan">—</span>'
|
||||
: ( entry.has_opus
|
||||
? '<span class="piperless-cache-badge piperless-cache-badge--opus">Opus' + bitrateSuffix + '</span>'
|
||||
: ( entry.has_mp3
|
||||
? '<span class="piperless-cache-badge piperless-cache-badge--ok">MP3' + bitrateSuffix + '</span>'
|
||||
: '<span class="piperless-cache-badge piperless-cache-badge--wav">WAV only</span>'
|
||||
)
|
||||
: ( entry.has_mp3
|
||||
? '<span class="piperless-cache-badge piperless-cache-badge--ok">MP3' + bitrateSuffix + '</span>'
|
||||
: '<span class="piperless-cache-badge piperless-cache-badge--wav">WAV only</span>'
|
||||
);
|
||||
const statusBadge = entry.enabled
|
||||
? '<span class="piperless-cache-badge piperless-cache-badge--ok">Enabled</span>'
|
||||
@@ -343,9 +300,18 @@
|
||||
|
||||
html += '</tbody></table>';
|
||||
|
||||
// ── Pagination bar (bottom) ──
|
||||
if ( paginationHtml ) {
|
||||
html += paginationHtml;
|
||||
// Pagination.
|
||||
if ( d.pages > 1 ) {
|
||||
html += '<div class="tablenav"><div class="tablenav-pages">';
|
||||
html += '<span class="displaying-num">' + d.total + ' items</span>';
|
||||
for ( let i = 1; i <= d.pages; i++ ) {
|
||||
if ( i === cachePage ) {
|
||||
html += '<span class="page-numbers current">' + i + '</span>';
|
||||
} else {
|
||||
html += '<a href="#" class="page-numbers piperless-cache-page" data-page="' + i + '">' + i + '</a>';
|
||||
}
|
||||
}
|
||||
html += '</div></div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-13
@@ -53,7 +53,6 @@
|
||||
|
||||
const [ generating, setGenerating ] = useState( false );
|
||||
const [ audioUrl, setAudioUrl ] = useState( null );
|
||||
const [ audioFormat, setAudioFormat ] = useState( 'mp3' );
|
||||
const [ audioDuration, setAudioDuration ] = useState( null );
|
||||
const [ models, setModels ] = useState( [] );
|
||||
const [ voices, setVoices ] = useState( [] );
|
||||
@@ -71,7 +70,6 @@
|
||||
.then( function ( data ) {
|
||||
if ( data.has_audio ) {
|
||||
setAudioUrl( data.url );
|
||||
setAudioFormat( data.format || 'mp3' );
|
||||
setAudioDuration( data.duration );
|
||||
}
|
||||
} )
|
||||
@@ -110,7 +108,6 @@
|
||||
} )
|
||||
.then( function ( data ) {
|
||||
setAudioUrl( data.url );
|
||||
setAudioFormat( data.format || 'mp3' );
|
||||
setAudioDuration( data.duration );
|
||||
setGenerating( false );
|
||||
createNotice( 'success', piperlessEditor.i18n.success, {
|
||||
@@ -246,7 +243,7 @@
|
||||
placeholder: '1.0',
|
||||
value: postMeta._piperless_length_scale || '',
|
||||
onChange: function ( val ) { updateMeta( '_piperless_length_scale', val ); },
|
||||
} ),
|
||||
} )
|
||||
),
|
||||
// ── Display Settings ────────────────────────────────────────
|
||||
createElement(
|
||||
@@ -260,8 +257,8 @@
|
||||
{ value: 'classic', label: 'Classic' },
|
||||
{ value: 'minimal', label: 'Minimal' },
|
||||
{ value: 'dark', label: 'Modern Dark' },
|
||||
{ value: 'newsviews', label: 'Ron Burgundy' },
|
||||
{ value: 'newsviews-classic', label: 'Dan Rather Blue' },
|
||||
{ value: 'newsviews', label: 'NewsViews' },
|
||||
{ value: 'newsviews-classic', label: 'NewsViews Classic' },
|
||||
],
|
||||
onChange: function ( val ) { updateMeta( '_piperless_style', val ); },
|
||||
} ),
|
||||
@@ -286,14 +283,9 @@
|
||||
? createElement( 'div', null,
|
||||
createElement( 'audio', {
|
||||
controls: true,
|
||||
src: audioUrl,
|
||||
style: { width: '100%', marginBottom: '8px' },
|
||||
},
|
||||
createElement( 'source', {
|
||||
src: audioUrl,
|
||||
type: audioFormat === 'opus' ? 'audio/ogg' : 'audio/mpeg',
|
||||
} ),
|
||||
piperlessEditor.i18n.noAudio
|
||||
),
|
||||
}, piperlessEditor.i18n.noAudio ),
|
||||
audioDuration && createElement( 'p', {
|
||||
style: { color: '#757575', fontSize: '12px' },
|
||||
}, piperlessEditor.i18n.duration + ' ' + formatDuration( audioDuration ) )
|
||||
|
||||
@@ -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 |
+9
-29
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Piperless v1.1.3 — Developer Documentation</title>
|
||||
<title>Piperless v1.0.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.3</h2>
|
||||
<h2>Piperless 1.0.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.3 · Generated 2026-05-11</p>
|
||||
<p>WordPress Plugin — Audio Transcripts via Piper TTS · v1.0.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>
|
||||
@@ -324,11 +324,11 @@ based on the <code>?tab=</code> query parameter. Custom field types (<code>mode
|
||||
<h4>Themes</h4>
|
||||
<table>
|
||||
<tr><th>CSS Class</th><th>Name</th><th>Accent</th></tr>
|
||||
<tr><td>piperless-player--classic</td><td>Classic</td><td>Blue accent, clean borders</td></tr>
|
||||
<tr><td>piperless-player--minimal</td><td>Minimal</td><td>Clean, understated</td></tr>
|
||||
<tr><td>piperless-player--dark</td><td>Modern Dark</td><td>Dark background</td></tr>
|
||||
<tr><td>piperless-player--newsviews</td><td>Ron Burgundy</td><td>Bold burgundy</td></tr>
|
||||
<tr><td>piperless-player--newsviews-classic</td><td>Dan Rather Blue</td><td>Classic navy</td></tr>
|
||||
<tr><td>piperless-player--classic</td><td>Classic</td><td>#2271b1 (blue)</td></tr>
|
||||
<tr><td>piperless-player--minimal</td><td>Minimal</td><td>#333333 (dark gray), no border</td></tr>
|
||||
<tr><td>piperless-player--dark</td><td>Modern Dark</td><td>#2271b1 on dark bg</td></tr>
|
||||
<tr><td>piperless-player--newsviews</td><td>NewsViews</td><td>#B31942 (burgundy)</td></tr>
|
||||
<tr><td>piperless-player--newsviews-classic</td><td>NewsViews Classic</td><td>#233452 (navy)</td></tr>
|
||||
<tr><td>—</td><td>Custom CSS</td><td>User-defined via textarea (sanitized)</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -396,8 +396,6 @@ for deterministic attribution.
|
||||
|
||||
<h2 id="security">Security Model</h2>
|
||||
|
||||
<p><strong>Comprehensive security audit:</strong> 29/29 categories cleared, 1 finding fixed, zero open. <a href="AUDIT.md">Read the full audit →</a></p>
|
||||
|
||||
<h4>Command Execution</h4>
|
||||
<ul>
|
||||
<li>All binary/model paths use <code>escapeshellarg()</code> — zero <code>escapeshellcmd()</code> calls</li>
|
||||
@@ -438,24 +436,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>
|
||||
|
||||
@@ -79,14 +79,11 @@ class Cache_Manager {
|
||||
* @param string $quality Quality tier.
|
||||
* @return string SHA-256 hash.
|
||||
*/
|
||||
public function cache_key( string $text, string $model, string $language, string $quality, string $bitrate = '', string $format = 'mp3' ): string {
|
||||
public function cache_key( string $text, string $model, string $language, string $quality, string $bitrate = '' ): string {
|
||||
$seed = $text . '|' . $model . '|' . $language . '|' . $quality;
|
||||
if ( '' !== $bitrate ) {
|
||||
$seed .= '|br:' . $bitrate;
|
||||
}
|
||||
if ( '' !== $format ) {
|
||||
$seed .= '|fmt:' . $format;
|
||||
}
|
||||
return hash( 'sha256', $seed );
|
||||
}
|
||||
|
||||
@@ -97,12 +94,7 @@ class Cache_Manager {
|
||||
* @return bool
|
||||
*/
|
||||
public function exists( string $cache_key ): bool {
|
||||
$settings = get_option( 'piperless_settings', [] );
|
||||
$format = $settings['piper_audio_format'] ?? 'mp3';
|
||||
return file_exists( $this->file_path( $cache_key, $format ) )
|
||||
|| file_exists( $this->file_path( $cache_key, 'mp3' ) )
|
||||
|| file_exists( $this->file_path( $cache_key, 'opus' ) )
|
||||
|| file_exists( $this->cache_dir . '/' . $cache_key . '.wav' );
|
||||
return file_exists( $this->file_path( $cache_key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,8 +103,8 @@ class Cache_Manager {
|
||||
* @param string $cache_key Cache key.
|
||||
* @return string
|
||||
*/
|
||||
public function file_path( string $cache_key, string $format = 'mp3' ): string {
|
||||
return $this->cache_dir . '/' . $cache_key . '.' . $format;
|
||||
public function file_path( string $cache_key ): string {
|
||||
return $this->cache_dir . '/' . $cache_key . '.mp3';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,13 +127,9 @@ class Cache_Manager {
|
||||
public function put( string $cache_key, string $data ): bool {
|
||||
$settings = get_option( 'piperless_settings', [] );
|
||||
$ffmpeg = $this->find_ffmpeg();
|
||||
$format = $settings['piper_audio_format'] ?? 'mp3';
|
||||
$bitrate = ( 'opus' === $format )
|
||||
? ( $settings['piper_opus_bitrate'] ?? '24k' )
|
||||
: ( $settings['piper_mp3_bitrate'] ?? '32k' );
|
||||
|
||||
if ( null !== $ffmpeg ) {
|
||||
// Write WAV to temp, convert to selected format.
|
||||
// Write WAV to temp, convert to MP3, store MP3.
|
||||
$wav_tmp = tempnam( sys_get_temp_dir(), 'piperless_' ) . '.wav';
|
||||
|
||||
error_clear_last();
|
||||
@@ -151,41 +139,30 @@ class Cache_Manager {
|
||||
return false;
|
||||
}
|
||||
|
||||
$out_path = $this->file_path( $cache_key, $format );
|
||||
|
||||
if ( 'opus' === $format ) {
|
||||
$cmd = sprintf(
|
||||
'%s -i %s -c:a libopus -b:a %s -ac 1 -application voip -y %s 2>&1',
|
||||
escapeshellarg( $ffmpeg ),
|
||||
escapeshellarg( $wav_tmp ),
|
||||
escapeshellarg( $bitrate ),
|
||||
escapeshellarg( $out_path )
|
||||
);
|
||||
} else {
|
||||
$cmd = sprintf(
|
||||
'%s -i %s -codec:a libmp3lame -b:a %s -ac 1 -y %s 2>&1',
|
||||
escapeshellarg( $ffmpeg ),
|
||||
escapeshellarg( $wav_tmp ),
|
||||
escapeshellarg( $bitrate ),
|
||||
escapeshellarg( $out_path )
|
||||
);
|
||||
}
|
||||
$mp3_path = $this->file_path( $cache_key );
|
||||
$bitrate = $settings['piper_mp3_bitrate'] ?? '32k';
|
||||
$cmd = sprintf(
|
||||
'%s -i %s -codec:a libmp3lame -b:a %s -ac 1 -y %s 2>&1',
|
||||
escapeshellarg( $ffmpeg ),
|
||||
escapeshellarg( $wav_tmp ),
|
||||
escapeshellarg( $bitrate ),
|
||||
escapeshellarg( $mp3_path )
|
||||
);
|
||||
|
||||
$output = [];
|
||||
$ret = 0;
|
||||
exec( $cmd, $output, $ret );
|
||||
@unlink( $wav_tmp );
|
||||
|
||||
if ( 0 === $ret && file_exists( $out_path ) && filesize( $out_path ) > 0 ) {
|
||||
$format_label = strtoupper( $format );
|
||||
$this->logger->info( "Cached {$format_label}: {key} ({size} bytes)", [
|
||||
if ( 0 === $ret && file_exists( $mp3_path ) && filesize( $mp3_path ) > 0 ) {
|
||||
$this->logger->info( 'Cached MP3: {key} ({size} bytes)', [
|
||||
'key' => $cache_key,
|
||||
'size' => filesize( $out_path ),
|
||||
'size' => filesize( $mp3_path ),
|
||||
] );
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->logger->error( "ffmpeg {$format} conversion failed for {key}, code {code}", [
|
||||
$this->logger->error( 'ffmpeg conversion failed for {key}, code {code}', [
|
||||
'key' => $cache_key,
|
||||
'code' => $ret,
|
||||
] );
|
||||
@@ -238,7 +215,7 @@ class Cache_Manager {
|
||||
$deleted = false;
|
||||
|
||||
// Delete MP3.
|
||||
$mp3_path = $this->file_path( $cache_key, 'mp3' );
|
||||
$mp3_path = $this->file_path( $cache_key );
|
||||
if ( file_exists( $mp3_path ) ) {
|
||||
if ( @unlink( $mp3_path ) ) {
|
||||
$deleted = true;
|
||||
@@ -247,14 +224,6 @@ class Cache_Manager {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete Opus.
|
||||
$opus_path = $this->file_path( $cache_key, 'opus' );
|
||||
if ( file_exists( $opus_path ) ) {
|
||||
if ( @unlink( $opus_path ) ) {
|
||||
$deleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Also delete legacy WAV.
|
||||
$wav_path = $this->cache_dir . '/' . $cache_key . '.wav';
|
||||
if ( file_exists( $wav_path ) ) {
|
||||
@@ -294,14 +263,6 @@ class Cache_Manager {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete Opus files.
|
||||
$opus_files = glob( $this->cache_dir . '/*.opus' );
|
||||
if ( false !== $opus_files ) {
|
||||
foreach ( $opus_files as $file ) {
|
||||
if ( @unlink( $file ) ) { $count++; }
|
||||
}
|
||||
}
|
||||
|
||||
// Also clean up any legacy WAV files.
|
||||
$wav_files = glob( $this->cache_dir . '/*.wav' );
|
||||
if ( false !== $wav_files ) {
|
||||
@@ -353,12 +314,16 @@ class Cache_Manager {
|
||||
// "orphaned audio" in the user-facing sense.
|
||||
$preview_patterns = [ 'model_preview_*', 'piperless_test_preview*' ];
|
||||
foreach ( $preview_patterns as $pattern ) {
|
||||
foreach ( [ '.mp3', '.opus', '.wav' ] as $ext ) {
|
||||
$matches = glob( $this->cache_dir . '/' . $pattern . $ext );
|
||||
if ( false !== $matches ) {
|
||||
foreach ( $matches as $file ) {
|
||||
@unlink( $file );
|
||||
}
|
||||
$preview_files = glob( $this->cache_dir . '/' . $pattern . '.mp3' );
|
||||
if ( false !== $preview_files ) {
|
||||
foreach ( $preview_files as $file ) {
|
||||
@unlink( $file );
|
||||
}
|
||||
}
|
||||
$preview_wavs = glob( $this->cache_dir . '/' . $pattern . '.wav' );
|
||||
if ( false !== $preview_wavs ) {
|
||||
foreach ( $preview_wavs as $file ) {
|
||||
@unlink( $file );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,13 +347,12 @@ class Cache_Manager {
|
||||
|
||||
$all_files = array_merge(
|
||||
(array) glob( $this->cache_dir . '/*.mp3' ),
|
||||
(array) glob( $this->cache_dir . '/*.opus' ),
|
||||
(array) glob( $this->cache_dir . '/*.wav' )
|
||||
);
|
||||
|
||||
foreach ( $all_files as $file ) {
|
||||
$key = basename( $file );
|
||||
$key = str_replace( [ '.mp3', '.opus', '.wav' ], '', $key );
|
||||
$key = str_replace( [ '.mp3', '.wav' ], '', $key );
|
||||
if ( str_starts_with( $key, 'model_preview_' ) || str_starts_with( $key, 'piperless_test_preview' ) ) {
|
||||
continue;
|
||||
}
|
||||
@@ -420,7 +384,7 @@ class Cache_Manager {
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function find_ffmpeg(): ?string {
|
||||
private function find_ffmpeg(): ?string {
|
||||
static $cached = null;
|
||||
static $resolved_path = null;
|
||||
|
||||
@@ -476,7 +440,7 @@ class Cache_Manager {
|
||||
* @param int $per_page Entries per page.
|
||||
* @return array{entries:array,total:int,pages:int}
|
||||
*/
|
||||
public function get_entries( int $page = 1, int $per_page = 20, string $sort_by = 'created', bool $sort_asc = false ): array {
|
||||
public function get_entries( int $page = 1, int $per_page = 20 ): array {
|
||||
if ( ! is_dir( $this->cache_dir ) ) {
|
||||
return [ 'entries' => [], 'total' => 0, 'pages' => 0 ];
|
||||
}
|
||||
@@ -516,10 +480,9 @@ class Cache_Manager {
|
||||
)
|
||||
);
|
||||
|
||||
// Scan MP3, Opus, and legacy WAV files.
|
||||
// Scan both MP3 and legacy WAV files.
|
||||
$all_files = array_merge(
|
||||
(array) glob( $this->cache_dir . '/*.mp3' ),
|
||||
(array) glob( $this->cache_dir . '/*.opus' ),
|
||||
(array) glob( $this->cache_dir . '/*.wav' )
|
||||
);
|
||||
|
||||
@@ -550,10 +513,9 @@ class Cache_Manager {
|
||||
$size_bytes = filesize( $path );
|
||||
$is_mp3 = ( 'mp3' === $ext );
|
||||
|
||||
// Check for companion formats.
|
||||
$has_mp3 = $is_mp3 || file_exists( $this->cache_dir . '/' . $key . '.mp3' );
|
||||
$has_opus = ( 'opus' === $ext ) || file_exists( $this->cache_dir . '/' . $key . '.opus' );
|
||||
$has_wav = file_exists( $this->cache_dir . '/' . $key . '.wav' );
|
||||
// Check for the companion format.
|
||||
$has_mp3 = $is_mp3 || file_exists( $this->cache_dir . '/' . $key . '.mp3' );
|
||||
$has_wav = ( ! $is_mp3 ) || file_exists( $this->cache_dir . '/' . $key . '.wav' );
|
||||
|
||||
// Check if this entry is the active audio for its post.
|
||||
$enabled = false;
|
||||
@@ -571,9 +533,7 @@ class Cache_Manager {
|
||||
'filename' => basename( $path ),
|
||||
'size_bytes' => $size_bytes,
|
||||
'has_mp3' => $has_mp3,
|
||||
'has_opus' => $has_opus,
|
||||
'bitrate' => $has_opus ? ( $settings['piper_opus_bitrate'] ?? '24k' )
|
||||
: ( $has_mp3 ? ( $settings['piper_mp3_bitrate'] ?? '32k' ) : '' ),
|
||||
'bitrate' => $has_mp3 ? ( $settings['piper_mp3_bitrate'] ?? '32k' ) : '',
|
||||
'created' => $mtime ? gmdate( 'Y-m-d H:i', $mtime ) : '',
|
||||
'enabled' => $enabled,
|
||||
'model' => $model,
|
||||
@@ -585,21 +545,6 @@ class Cache_Manager {
|
||||
];
|
||||
}
|
||||
|
||||
// ── Sort before pagination ──────────────────────────────
|
||||
if ( 'size' === $sort_by ) {
|
||||
usort( $entries, function ( $a, $b ) use ( $sort_asc ) {
|
||||
return $sort_asc
|
||||
? ( ( $a['size_bytes'] ?? 0 ) <=> ( $b['size_bytes'] ?? 0 ) )
|
||||
: ( ( $b['size_bytes'] ?? 0 ) <=> ( $a['size_bytes'] ?? 0 ) );
|
||||
} );
|
||||
} else {
|
||||
usort( $entries, function ( $a, $b ) use ( $sort_asc ) {
|
||||
return $sort_asc
|
||||
? ( $a['created'] ?? '' ) <=> ( $b['created'] ?? '' )
|
||||
: ( $b['created'] ?? '' ) <=> ( $a['created'] ?? '' );
|
||||
} );
|
||||
}
|
||||
|
||||
$total = count( $entries );
|
||||
$pages = (int) ceil( $total / max( 1, $per_page ) );
|
||||
$page = max( 1, min( $page, max( 1, $pages ) ) );
|
||||
|
||||
@@ -365,7 +365,6 @@ class Gutenberg {
|
||||
return rest_ensure_response( [
|
||||
'url' => $result['url'],
|
||||
'duration' => get_post_meta( $post_id, '_piperless_duration', true ),
|
||||
'format' => get_post_meta( $post_id, '_piperless_audio_format', true ) ?: 'mp3',
|
||||
] );
|
||||
}
|
||||
|
||||
@@ -505,25 +504,16 @@ class Gutenberg {
|
||||
|
||||
set_transient( $rate_key, $rate_count + 1, 60 );
|
||||
|
||||
// Try configured format first, then MP3, then Opus, fall back to WAV.
|
||||
$settings = get_option( 'piperless_settings', [] );
|
||||
$audio_format = $settings['piper_audio_format'] ?? 'mp3';
|
||||
// Try MP3 first (canonical format).
|
||||
$mp3_path = $this->cache->file_path( $cache_key );
|
||||
|
||||
// Try the configured format.
|
||||
$format_path = $this->cache->file_path( $cache_key, $audio_format );
|
||||
if ( file_exists( $format_path ) ) {
|
||||
return $this->stream_file( $format_path, 'opus' === $audio_format ? 'audio/ogg' : 'audio/mpeg' );
|
||||
}
|
||||
|
||||
// Try the other format.
|
||||
$alt_format = ( 'opus' === $audio_format ) ? 'mp3' : 'opus';
|
||||
$alt_path = $this->cache->file_path( $cache_key, $alt_format );
|
||||
if ( file_exists( $alt_path ) ) {
|
||||
return $this->stream_file( $alt_path, 'opus' === $alt_format ? 'audio/ogg' : 'audio/mpeg' );
|
||||
if ( file_exists( $mp3_path ) ) {
|
||||
return $this->stream_file( $mp3_path, 'audio/mpeg' );
|
||||
}
|
||||
|
||||
// Fall back to legacy WAV.
|
||||
$wav_path = $this->cache->dir() . '/' . $cache_key . '.wav';
|
||||
|
||||
if ( ! file_exists( $wav_path ) ) {
|
||||
return new \WP_Error( 'not_found', __( 'Audio file not found.', 'piperless' ), [ 'status' => 404 ] );
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
*
|
||||
* ## Player style
|
||||
*
|
||||
* Six themes are available (Classic, Minimal, Modern Dark, Ron Burgundy,
|
||||
* Dan Rather Blue, Custom CSS). The theme class is applied as
|
||||
* Six themes are available (Classic, Minimal, Modern Dark, NewsViews,
|
||||
* NewsViews Classic, Custom CSS). The theme class is applied as
|
||||
* piperless-player--<style> on the container div. Per-post override
|
||||
* via _piperless_style meta.
|
||||
*
|
||||
@@ -67,7 +67,7 @@ class Player {
|
||||
*/
|
||||
public function maybe_prepend_player( string $content ): string {
|
||||
// Only on singular views.
|
||||
if ( ! is_singular() || ! is_main_query() ) {
|
||||
if ( ! is_singular() || ! in_the_loop() || ! is_main_query() ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,19 +185,7 @@ class Settings {
|
||||
], $this->page_slug_piper );
|
||||
|
||||
$this->add_field( 'piper_ffmpeg_binary', __( 'FFmpeg Binary Path', 'piperless' ), 'text', 'piperless_piper_section', [
|
||||
'description' => __( 'Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty.', 'piperless' ),
|
||||
], $this->page_slug_piper );
|
||||
|
||||
$this->add_field( 'piper_ffprobe_binary', __( 'FFprobe Binary Path', 'piperless' ), 'text', 'piperless_piper_section', [
|
||||
'description' => __( 'Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty.', 'piperless' ),
|
||||
], $this->page_slug_piper );
|
||||
|
||||
$this->add_field( 'piper_audio_format', __( 'Audio Format', 'piperless' ), 'select', 'piperless_piper_section', [
|
||||
'description' => __( 'Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.', 'piperless' ),
|
||||
'options' => [
|
||||
'mp3' => 'MP3',
|
||||
'opus' => 'Opus',
|
||||
],
|
||||
'description' => __( 'Absolute path to ffmpeg for MP3 conversion. Auto-detected from common paths if left empty.', 'piperless' ),
|
||||
], $this->page_slug_piper );
|
||||
|
||||
$this->add_field( 'piper_mp3_bitrate', __( 'MP3 Bitrate', 'piperless' ), 'select', 'piperless_piper_section', [
|
||||
@@ -208,15 +196,6 @@ class Settings {
|
||||
],
|
||||
], $this->page_slug_piper );
|
||||
|
||||
$this->add_field( 'piper_opus_bitrate', __( 'Opus Bitrate', 'piperless' ), 'select', 'piperless_piper_section', [
|
||||
'description' => __( 'Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.', 'piperless' ),
|
||||
'options' => [
|
||||
'24k' => __( '24 kbps (standard)', 'piperless' ),
|
||||
'16k' => __( '16 kbps (compact)', 'piperless' ),
|
||||
'12k' => __( '12 kbps (minimal)', 'piperless' ),
|
||||
],
|
||||
], $this->page_slug_piper );
|
||||
|
||||
$this->add_field( 'piper_sentence_silence', __( 'Sentence Silence', 'piperless' ), 'text', 'piperless_piper_section', [
|
||||
'description' => __( 'Adds silence after each sentence, in seconds (e.g. 0.2, 0.5). Leave empty for Piper default. Applies to Standard mode only.', 'piperless' ),
|
||||
], $this->page_slug_piper );
|
||||
@@ -282,8 +261,8 @@ class Settings {
|
||||
'classic' => __( 'Classic', 'piperless' ),
|
||||
'minimal' => __( 'Minimal', 'piperless' ),
|
||||
'dark' => __( 'Modern Dark', 'piperless' ),
|
||||
'newsviews' => __( 'Ron Burgundy', 'piperless' ),
|
||||
'newsviews-classic' => __( 'Dan Rather Blue', 'piperless' ),
|
||||
'newsviews' => __( 'NewsViews', 'piperless' ),
|
||||
'newsviews-classic' => __( 'NewsViews Classic', 'piperless' ),
|
||||
'---' => '──────────',
|
||||
'custom' => __( 'Custom CSS', 'piperless' ),
|
||||
],
|
||||
@@ -464,11 +443,7 @@ class Settings {
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function sanitize_settings( array $input ): array {
|
||||
// Merge with existing settings so standalone forms (e.g., Logs tab)
|
||||
// don't wipe unrelated fields.
|
||||
$existing = get_option( 'piperless_settings', [] );
|
||||
$input = array_merge( $existing, $input );
|
||||
$clean = [];
|
||||
$clean = [];
|
||||
|
||||
$clean['piper_binary'] = sanitize_text_field( $input['piper_binary'] ?? '' );
|
||||
$clean['models_directory'] = sanitize_text_field( $input['models_directory'] ?? '' );
|
||||
@@ -477,12 +452,7 @@ class Settings {
|
||||
$clean['default_language'] = sanitize_text_field( $input['default_language'] ?? 'en_US' );
|
||||
$clean['default_quality'] = sanitize_text_field( $input['default_quality'] ?? 'medium' );
|
||||
$clean['piper_ffmpeg_binary'] = sanitize_text_field( $input['piper_ffmpeg_binary'] ?? '' );
|
||||
$clean['piper_ffprobe_binary'] = sanitize_text_field( $input['piper_ffprobe_binary'] ?? '' );
|
||||
$clean['piper_mp3_bitrate'] = sanitize_text_field( $input['piper_mp3_bitrate'] ?? '32k' );
|
||||
$clean['piper_audio_format'] = in_array( $input['piper_audio_format'] ?? 'mp3', [ 'mp3', 'opus' ], true )
|
||||
? $input['piper_audio_format'] : 'mp3';
|
||||
$clean['piper_opus_bitrate'] = in_array( $input['piper_opus_bitrate'] ?? '24k', [ '24k', '16k', '12k' ], true )
|
||||
? $input['piper_opus_bitrate'] : '24k';
|
||||
$clean['piper_sentence_silence'] = sanitize_text_field( $input['piper_sentence_silence'] ?? '' );
|
||||
$clean['piper_length_scale'] = sanitize_text_field( $input['piper_length_scale'] ?? '' );
|
||||
$clean['player_style'] = sanitize_text_field( $input['player_style'] ?? 'classic' );
|
||||
@@ -569,6 +539,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,12 +607,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"><?php esc_html_e( 'GitHub Repository', 'piperless' ); ?></a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://buymeacoffee.com/forkless" target="_blank"><?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>
|
||||
@@ -895,10 +863,8 @@ class Settings {
|
||||
|
||||
$page = max( 1, (int) ( $_POST['page'] ?? 1 ) );
|
||||
$per_page = max( 5, min( 50, (int) ( $_POST['per_page'] ?? 20 ) ) );
|
||||
$sort_by = in_array( $_POST['sort_by'] ?? 'created', [ 'created', 'size' ], true ) ? $_POST['sort_by'] : 'created';
|
||||
$sort_asc = ( 'asc' === ( $_POST['sort_order'] ?? 'desc' ) );
|
||||
|
||||
wp_send_json_success( $this->cache->get_entries( $page, $per_page, $sort_by, $sort_asc ) );
|
||||
wp_send_json_success( $this->cache->get_entries( $page, $per_page ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -918,36 +884,6 @@ class Settings {
|
||||
}
|
||||
|
||||
$deleted = $this->cache->delete_entry( $key );
|
||||
|
||||
// Clear post meta if this entry was linked to a post.
|
||||
if ( $deleted ) {
|
||||
global $wpdb;
|
||||
$rows = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s",
|
||||
'_piperless_cache_key'
|
||||
) );
|
||||
|
||||
foreach ( $rows as $row ) {
|
||||
$keys = maybe_unserialize( $row->meta_value );
|
||||
$owns = false;
|
||||
if ( is_array( $keys ) ) {
|
||||
$owns = array_key_exists( $key, $keys );
|
||||
} elseif ( is_string( $keys ) ) {
|
||||
$owns = ( $keys === $key );
|
||||
}
|
||||
|
||||
if ( $owns ) {
|
||||
delete_post_meta( (int) $row->post_id, '_piperless_audio_url' );
|
||||
delete_post_meta( (int) $row->post_id, '_piperless_cache_key' );
|
||||
delete_post_meta( (int) $row->post_id, '_piperless_duration' );
|
||||
delete_post_meta( (int) $row->post_id, '_piperless_model_name' );
|
||||
delete_post_meta( (int) $row->post_id, '_piperless_generated_at' );
|
||||
delete_post_meta( (int) $row->post_id, '_piperless_audio_format' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success( [ 'deleted' => $deleted ] );
|
||||
}
|
||||
|
||||
|
||||
@@ -132,11 +132,9 @@ class Transcriber {
|
||||
return $this->error( __( 'No text content available for this post.', 'piperless' ) );
|
||||
}
|
||||
|
||||
// Cache key (includes bitrate and format so changing them regenerates files).
|
||||
$settings_cache = get_option( 'piperless_settings', [] );
|
||||
$bitrate = $settings_cache['piper_mp3_bitrate'] ?? '32k';
|
||||
$audio_format = $settings_cache['piper_audio_format'] ?? 'mp3';
|
||||
$cache_key = $this->cache->cache_key( $text, $model, $language, $quality, $bitrate, $audio_format );
|
||||
// Cache key (includes bitrate so changing it regenerates files).
|
||||
$bitrate = get_option( 'piperless_settings', [] )['piper_mp3_bitrate'] ?? '32k';
|
||||
$cache_key = $this->cache->cache_key( $text, $model, $language, $quality, $bitrate );
|
||||
|
||||
// Store cache key in post meta before generation so it is tracked.
|
||||
$model_basename = basename( $model, '.onnx' );
|
||||
@@ -213,14 +211,11 @@ class Transcriber {
|
||||
$duration = get_post_meta( $post_id, '_piperless_duration', true );
|
||||
$cache_key = get_post_meta( $post_id, '_piperless_cache_key', true );
|
||||
|
||||
$format = get_post_meta( $post_id, '_piperless_audio_format', true );
|
||||
|
||||
return [
|
||||
'has_audio' => ! empty( $url ),
|
||||
'url' => $url ?: null,
|
||||
'duration' => $duration ? (float) $duration : null,
|
||||
'cache_key' => $cache_key ?: null,
|
||||
'format' => $format ?: 'mp3',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -381,10 +376,6 @@ class Transcriber {
|
||||
update_post_meta( $post_id, '_piperless_duration', $duration );
|
||||
update_post_meta( $post_id, '_piperless_generated_at', current_time( 'mysql', true ) );
|
||||
|
||||
// Store the audio format for the sidebar preview player.
|
||||
$settings = get_option( 'piperless_settings', [] );
|
||||
update_post_meta( $post_id, '_piperless_audio_format', $settings['piper_audio_format'] ?? 'mp3' );
|
||||
|
||||
if ( '' !== $model_basename ) {
|
||||
update_post_meta( $post_id, '_piperless_model_name', $model_basename );
|
||||
}
|
||||
@@ -397,37 +388,15 @@ class Transcriber {
|
||||
* @return float Duration in seconds.
|
||||
*/
|
||||
public function wav_duration( string $cache_key ): float {
|
||||
// Try compressed formats first via ffprobe.
|
||||
$settings = get_option( 'piperless_settings', [] );
|
||||
$format = $settings['piper_audio_format'] ?? 'mp3';
|
||||
$path = $this->cache->file_path( $cache_key, $format );
|
||||
if ( file_exists( $path ) ) {
|
||||
$dur = $this->ffprobe_duration( $path );
|
||||
if ( $dur > 0.0 ) {
|
||||
return $dur;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to WAV header reading.
|
||||
$file_path = $this->cache->file_path( $cache_key, 'mp3' );
|
||||
if ( ! file_exists( $file_path ) ) {
|
||||
$file_path = $this->cache->file_path( $cache_key, 'opus' );
|
||||
}
|
||||
$file_path = $this->cache->file_path( $cache_key );
|
||||
if ( ! file_exists( $file_path ) ) {
|
||||
// Try legacy WAV path.
|
||||
$file_path = $this->cache->dir() . '/' . $cache_key . '.wav';
|
||||
}
|
||||
if ( ! file_exists( $file_path ) ) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// If not WAV, try ffprobe.
|
||||
if ( ! str_ends_with( $file_path, '.wav' ) ) {
|
||||
$dur = $this->ffprobe_duration( $file_path );
|
||||
if ( $dur > 0.0 ) {
|
||||
return $dur;
|
||||
}
|
||||
}
|
||||
|
||||
$fp = @fopen( $file_path, 'rb' );
|
||||
if ( false === $fp ) {
|
||||
return 0.0;
|
||||
@@ -486,83 +455,4 @@ class Transcriber {
|
||||
'error' => $message,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get audio duration using ffprobe.
|
||||
*
|
||||
* @param string $file_path Absolute path to the audio file.
|
||||
* @return float Duration in seconds, or 0.0 on failure.
|
||||
*/
|
||||
private function ffprobe_duration( string $file_path ): float {
|
||||
$ffprobe = $this->find_ffprobe();
|
||||
if ( null === $ffprobe ) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$cmd = sprintf(
|
||||
'%s -v error -show_entries format=duration -of csv=p=0 %s 2>&1',
|
||||
escapeshellarg( $ffprobe ),
|
||||
escapeshellarg( $file_path )
|
||||
);
|
||||
|
||||
$output = [];
|
||||
$ret = 0;
|
||||
exec( $cmd, $output, $ret );
|
||||
|
||||
if ( 0 !== $ret || empty( $output ) ) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return (float) trim( $output[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find ffprobe binary on the system.
|
||||
*
|
||||
* @return string|null Absolute path, or null.
|
||||
*/
|
||||
private function find_ffprobe(): ?string {
|
||||
static $cached = null;
|
||||
static $resolved = null;
|
||||
|
||||
if ( null !== $cached ) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
$cached = true;
|
||||
$settings = get_option( 'piperless_settings', [] );
|
||||
$custom = $settings['piper_ffprobe_binary'] ?? '';
|
||||
|
||||
// 1. Try the configured ffprobe path.
|
||||
if ( '' !== $custom ) {
|
||||
if ( @file_exists( $custom ) && @is_executable( $custom ) ) {
|
||||
$resolved = $custom;
|
||||
return $resolved;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Try the same directory as resolved ffmpeg.
|
||||
$ffmpeg_path = $this->cache->find_ffmpeg();
|
||||
if ( null !== $ffmpeg_path ) {
|
||||
$candidate = dirname( $ffmpeg_path ) . '/ffprobe';
|
||||
if ( @is_executable( $candidate ) ) {
|
||||
$resolved = $candidate;
|
||||
return $resolved;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback: common paths extended via filter.
|
||||
$candidates = apply_filters(
|
||||
'piperless_ffprobe_paths',
|
||||
[ '/usr/bin/ffprobe', '/usr/local/bin/ffprobe', '/opt/bin/ffprobe' ]
|
||||
);
|
||||
foreach ( $candidates as $candidate ) {
|
||||
if ( @is_executable( $candidate ) ) {
|
||||
$resolved = $candidate;
|
||||
return $resolved;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"_meta": {
|
||||
"locale": "de_DE",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"generated": "2026-05-09",
|
||||
"total_strings": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "Cache-Verwaltung",
|
||||
"Cache flushed.": "Cache geleert.",
|
||||
"Choose a visual theme for the audio player.": "Wähle ein visuelles Thema für den Audioplayer.",
|
||||
"Chunk Silence": "Pausenlänge",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Segmentiert — Text vorab an Satzgrenzen aufteilen",
|
||||
"Classic": "Klassisch",
|
||||
"Clear Log": "Log löschen",
|
||||
"Clear Orphaned Audio": "Verwaiste Audiodateien löschen",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "Minimaler Schweregrad für die Protokollierung.",
|
||||
"Models Directory": "Modelle-Verzeichnis",
|
||||
"Modern Dark": "Modern Dunkel",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "Kein passendes Piper-Stimmenmodell gefunden. Überprüfe dein Modelle-Verzeichnis.",
|
||||
"No text content available for this post.": "Kein Textinhalt für diesen Beitrag verfügbar.",
|
||||
"Orphaned files cleared.": "Verwaiste Dateien gelöscht.",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "Beitrag nicht gefunden.",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "Vorschau, wie der gewählte Player-Stil mit einem Beispiel-Audioclip aussieht.",
|
||||
"Quality tier override": "Qualitätsstufen-Überschreibung",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "Roh-Modus sendet Text direkt an Piper. Segmentiert-Modus teilt Text zunächst in Sätze auf.",
|
||||
"Raw — send text as-is to Piper": "Roh — Text unverändert an Piper senden",
|
||||
"Refresh Log": "Protokoll aktualisieren",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Sekunden Stille zwischen Satzblöcken im Segmentiert-Modus. Standard: 2.0. Bereich: 0.5–5.0.",
|
||||
"Show Duration": "Dauer anzeigen",
|
||||
"Skip Embedded Content": "Eingebettete Inhalte überspringen",
|
||||
"Styling": "Styling",
|
||||
"Test Connection": "Verbindung testen",
|
||||
"Testing…": "Teste…",
|
||||
"Text Processing": "Textverarbeitung",
|
||||
"This will delete cache files not referenced by any post.": "Dies löscht Cache-Dateien, die keinem Beitrag zugeordnet sind.",
|
||||
"Too many requests. Please try again later.": "Zu viele Anfragen. Bitte versuche es später erneut.",
|
||||
"Unsupported post type.": "Nicht unterstützter Beitragstyp.",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "Beim Zurückfallen auf den Beitragstext (kein Auszug) Text aus eingebetteten Blöcken wie YouTube, Twitter und Drittanbieter-Einbettungen überspringen.",
|
||||
"Where to insert the audio player relative to the post content.": "Wo der Audioplayer relativ zum Beitragsinhalt eingefügt werden soll.",
|
||||
"You do not have permission to edit this post.": "Du hast keine Berechtigung, diesen Beitrag zu bearbeiten.",
|
||||
"Your browser does not support the audio element.": "Dein Browser unterstützt das Audio-Element nicht.",
|
||||
"Audio Format": "Audioformat",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "Ausgabe-Audioformat. MP3 wird universell unterstützt. Opus bietet bessere Qualität bei gleicher Bitrate, hat aber eingeschränktere Browser-Unterstützung.",
|
||||
"Opus Bitrate": "Opus-Bitrate",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Bitrate für Opus-Kodierung. Opus erreicht gute Qualität bei viel niedrigeren Bitraten als MP3. Mono-Ausgabe.",
|
||||
"24 kbps (standard)": "24 kbps (Standard)",
|
||||
"16 kbps (compact)": "16 kbps (Kompakt)",
|
||||
"12 kbps (minimal)": "12 kbps (Minimal)",
|
||||
"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"
|
||||
"Your browser does not support the audio element.": "Dein Browser unterstützt das Audio-Element nicht."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-09 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: German <LL@li.org>\n"
|
||||
"Language: de_DE\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "Cache geleert."
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "Wähle ein visuelles Thema für den Audioplayer."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "Pausenlänge"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Segmentiert — Text vorab an Satzgrenzen aufteilen"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "Klassisch"
|
||||
@@ -236,6 +228,10 @@ msgstr "Modelle-Verzeichnis"
|
||||
msgid "Modern Dark"
|
||||
msgstr "Modern Dunkel"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "Kein passendes Piper-Stimmenmodell gefunden. Überprüfe dein Modelle-Verzeichnis."
|
||||
@@ -368,22 +364,10 @@ msgstr "Vorschau, wie der gewählte Player-Stil mit einem Beispiel-Audioclip aus
|
||||
msgid "Quality tier override"
|
||||
msgstr "Qualitätsstufen-Überschreibung"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "Roh-Modus sendet Text direkt an Piper. Segmentiert-Modus teilt Text zunächst in Sätze auf."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Roh — Text unverändert an Piper senden"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "Protokoll aktualisieren"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Sekunden Stille zwischen Satzblöcken im Segmentiert-Modus. Standard: 2.0. Bereich: 0.5–5.0."
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "Dauer anzeigen"
|
||||
@@ -404,10 +388,6 @@ msgstr "Verbindung testen"
|
||||
msgid "Testing…"
|
||||
msgstr "Teste…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "Textverarbeitung"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "Dies löscht Cache-Dateien, die keinem Beitrag zugeordnet sind."
|
||||
@@ -444,43 +424,3 @@ msgstr "Du hast keine Berechtigung, diesen Beitrag zu bearbeiten."
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "Dein Browser unterstützt das Audio-Element nicht."
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "Audioformat"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "Ausgabe-Audioformat. MP3 wird universell unterstützt. Opus bietet bessere Qualität bei gleicher Bitrate, hat aber eingeschränktere Browser-Unterstützung."
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Opus-Bitrate"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Bitrate für Opus-Kodierung. Opus erreicht gute Qualität bei viel niedrigeren Bitraten als MP3. Mono-Ausgabe."
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps (Standard)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps (Kompakt)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps (Minimal)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "FFprobe-Binärpfad"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "Absoluter Pfad zur ffprobe-Binärdatei für die Erkennung der Audiodauer. Automatische Erkennung aus dem ffmpeg-Verzeichnis, wenn leer."
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "Absoluter Pfad zur ffmpeg-Binärdatei für MP3/Opus-Konvertierung. Automatische Erkennung aus üblichen Pfaden, wenn leer."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "Dan Rather Blue"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHub-Repository"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "Kauf mir einen Kaffee"
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"_meta": {
|
||||
"locale": "es_ES",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"generated": "2026-05-09",
|
||||
"total_strings": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "Gestión de caché",
|
||||
"Cache flushed.": "Caché vaciada.",
|
||||
"Choose a visual theme for the audio player.": "Elige un tema visual para el reproductor de audio.",
|
||||
"Chunk Silence": "Silencio entre frases",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Segmentado — dividir texto en oraciones",
|
||||
"Classic": "Clásico",
|
||||
"Clear Log": "Limpiar registro",
|
||||
"Clear Orphaned Audio": "Eliminar audio huérfano",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "Gravedad mínima para registrar en el log.",
|
||||
"Models Directory": "Directorio de modelos",
|
||||
"Modern Dark": "Oscuro moderno",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "No se encontró un modelo de voz Piper adecuado. Revisa tu directorio de modelos.",
|
||||
"No text content available for this post.": "No hay contenido de texto disponible para esta entrada.",
|
||||
"Orphaned files cleared.": "Archivos huérfanos eliminados.",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "Entrada no encontrada.",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "Vista previa de cómo se ve el estilo de reproductor seleccionado con un clip de audio de muestra.",
|
||||
"Quality tier override": "Anulación de nivel de calidad",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "El modo Crudo envía el texto directamente a Piper. El modo Segmentado divide el texto en oraciones.",
|
||||
"Raw — send text as-is to Piper": "Crudo — enviar texto tal cual a Piper",
|
||||
"Refresh Log": "Actualizar registro",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Segundos de silencio insertados entre bloques de oraciones en modo Segmentado. Predeterminado: 2.0. Rango: 0.5–5.0.",
|
||||
"Show Duration": "Mostrar duración",
|
||||
"Skip Embedded Content": "Omitir contenido incrustado",
|
||||
"Styling": "Estilo",
|
||||
"Test Connection": "Probar conexión",
|
||||
"Testing…": "Probando…",
|
||||
"Text Processing": "Procesamiento de texto",
|
||||
"This will delete cache files not referenced by any post.": "Esto eliminará los archivos de caché no referenciados por ninguna entrada.",
|
||||
"Too many requests. Please try again later.": "Demasiadas solicitudes. Por favor inténtalo de nuevo más tarde.",
|
||||
"Unsupported post type.": "Tipo de entrada no soportado.",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "Al recurrir al cuerpo del artículo (sin extracto), omitir el texto de bloques incrustados como YouTube, Twitter e integraciones de terceros.",
|
||||
"Where to insert the audio player relative to the post content.": "Dónde insertar el reproductor de audio en relación con el contenido de la entrada.",
|
||||
"You do not have permission to edit this post.": "No tienes permiso para editar este artículo.",
|
||||
"Your browser does not support the audio element.": "Tu navegador no soporta el elemento de audio.",
|
||||
"Audio Format": "Formato de audio",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "Formato de audio de salida. MP3 es compatible universalmente. Opus ofrece mejor calidad a la misma tasa de bits pero tiene un soporte de navegador más limitado.",
|
||||
"Opus Bitrate": "Bitrate de Opus",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Bitrate para codificación Opus. Opus logra buena calidad a tasas de bits mucho más bajas que MP3. Salida mono.",
|
||||
"24 kbps (standard)": "24 kbps (estándar)",
|
||||
"16 kbps (compact)": "16 kbps (compacto)",
|
||||
"12 kbps (minimal)": "12 kbps (mínimo)",
|
||||
"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é"
|
||||
"Your browser does not support the audio element.": "Tu navegador no soporta el elemento de audio."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-09 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish <LL@li.org>\n"
|
||||
"Language: es_ES\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "Caché vaciada."
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "Elige un tema visual para el reproductor de audio."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "Silencio entre frases"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Segmentado — dividir texto en oraciones"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "Clásico"
|
||||
@@ -236,6 +228,10 @@ msgstr "Directorio de modelos"
|
||||
msgid "Modern Dark"
|
||||
msgstr "Oscuro moderno"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "No se encontró un modelo de voz Piper adecuado. Revisa tu directorio de modelos."
|
||||
@@ -368,22 +364,10 @@ msgstr "Vista previa de cómo se ve el estilo de reproductor seleccionado con un
|
||||
msgid "Quality tier override"
|
||||
msgstr "Anulación de nivel de calidad"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "El modo Crudo envía el texto directamente a Piper. El modo Segmentado divide el texto en oraciones."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Crudo — enviar texto tal cual a Piper"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "Actualizar registro"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Segundos de silencio insertados entre bloques de oraciones en modo Segmentado. Predeterminado: 2.0. Rango: 0.5–5.0."
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "Mostrar duración"
|
||||
@@ -404,10 +388,6 @@ msgstr "Probar conexión"
|
||||
msgid "Testing…"
|
||||
msgstr "Probando…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "Procesamiento de texto"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "Esto eliminará los archivos de caché no referenciados por ninguna entrada."
|
||||
@@ -444,43 +424,3 @@ msgstr "No tienes permiso para editar este artículo."
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "Tu navegador no soporta el elemento de audio."
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "Formato de audio"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "Formato de audio de salida. MP3 es compatible universalmente. Opus ofrece mejor calidad a la misma tasa de bits pero tiene un soporte de navegador más limitado."
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Bitrate de Opus"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Bitrate para codificación Opus. Opus logra buena calidad a tasas de bits mucho más bajas que MP3. Salida mono."
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps (estándar)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps (compacto)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps (mínimo)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "Ruta del binario FFprobe"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "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."
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "Ruta absoluta al binario ffmpeg para la conversión MP3/Opus. Se detecta automáticamente si se deja vacío."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
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é"
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"_meta": {
|
||||
"locale": "fr_FR",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"generated": "2026-05-09",
|
||||
"total_strings": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "Gestion du cache",
|
||||
"Cache flushed.": "Cache vidé.",
|
||||
"Choose a visual theme for the audio player.": "Choisissez un thème visuel pour le lecteur audio.",
|
||||
"Chunk Silence": "Silence entre phrases",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Segmenté — prédécouper le texte aux limites de phrase",
|
||||
"Classic": "Classique",
|
||||
"Clear Log": "Effacer le journal",
|
||||
"Clear Orphaned Audio": "Supprimer les audios orphelins",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "Sévérité minimale à enregistrer dans le journal.",
|
||||
"Models Directory": "Répertoire des modèles",
|
||||
"Modern Dark": "Sombre moderne",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "Aucun modèle de voix Piper approprié trouvé. Vérifiez votre répertoire de modèles.",
|
||||
"No text content available for this post.": "Aucun contenu texte disponible pour cet article.",
|
||||
"Orphaned files cleared.": "Fichiers orphelins supprimés.",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "Article introuvable.",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "Aperçu du style de lecteur sélectionné avec un extrait audio d'exemple.",
|
||||
"Quality tier override": "Remplacement du niveau de qualité",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "Le mode Brut envoie le texte directement à Piper. Le mode Segmenté divise d'abord le texte en phrases.",
|
||||
"Raw — send text as-is to Piper": "Brut — envoyer le texte tel quel à Piper",
|
||||
"Refresh Log": "Actualiser le journal",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Secondes de silence insérées entre les blocs de phrases en mode Segmenté. Défaut : 2.0. Plage : 0.5–5.0.",
|
||||
"Show Duration": "Afficher la durée",
|
||||
"Skip Embedded Content": "Ignorer le contenu intégré",
|
||||
"Styling": "Style",
|
||||
"Test Connection": "Tester la connexion",
|
||||
"Testing…": "Test en cours…",
|
||||
"Text Processing": "Traitement du texte",
|
||||
"This will delete cache files not referenced by any post.": "Cela supprimera les fichiers cache non référencés par un article.",
|
||||
"Too many requests. Please try again later.": "Trop de requêtes. Veuillez réessayer plus tard.",
|
||||
"Unsupported post type.": "Type d'article non pris en charge.",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "Lors du repli sur le corps de l'article (pas d'extrait), ignorer le texte des blocs intégrés comme YouTube, Twitter et les intégrations tierces.",
|
||||
"Where to insert the audio player relative to the post content.": "Où insérer le lecteur audio par rapport au contenu de l'article.",
|
||||
"You do not have permission to edit this post.": "Vous n'avez pas l'autorisation de modifier cet article.",
|
||||
"Your browser does not support the audio element.": "Votre navigateur ne prend pas en charge l'élément audio.",
|
||||
"Audio Format": "Format audio",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "Format audio de sortie. Le MP3 est universellement pris en charge. L'Opus offre une meilleure qualité au même débit mais a une compatibilité navigateur plus limitée.",
|
||||
"Opus Bitrate": "Débit Opus",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Débit pour l'encodage Opus. Opus atteint une bonne qualité à des débits bien inférieurs au MP3. Sortie mono.",
|
||||
"24 kbps (standard)": "24 kbps (standard)",
|
||||
"16 kbps (compact)": "16 kbps (compact)",
|
||||
"12 kbps (minimal)": "12 kbps (minimal)",
|
||||
"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é"
|
||||
"Your browser does not support the audio element.": "Votre navigateur ne prend pas en charge l'élément audio."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-09 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: French <LL@li.org>\n"
|
||||
"Language: fr_FR\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "Cache vidé."
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "Choisissez un thème visuel pour le lecteur audio."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "Silence entre phrases"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Segmenté — prédécouper le texte aux limites de phrase"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "Classique"
|
||||
@@ -236,6 +228,10 @@ msgstr "Répertoire des modèles"
|
||||
msgid "Modern Dark"
|
||||
msgstr "Sombre moderne"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "Aucun modèle de voix Piper approprié trouvé. Vérifiez votre répertoire de modèles."
|
||||
@@ -368,22 +364,10 @@ msgstr "Aperçu du style de lecteur sélectionné avec un extrait audio d'exempl
|
||||
msgid "Quality tier override"
|
||||
msgstr "Remplacement du niveau de qualité"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "Le mode Brut envoie le texte directement à Piper. Le mode Segmenté divise d'abord le texte en phrases."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Brut — envoyer le texte tel quel à Piper"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "Actualiser le journal"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Secondes de silence insérées entre les blocs de phrases en mode Segmenté. Défaut : 2.0. Plage : 0.5–5.0."
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "Afficher la durée"
|
||||
@@ -404,10 +388,6 @@ msgstr "Tester la connexion"
|
||||
msgid "Testing…"
|
||||
msgstr "Test en cours…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "Traitement du texte"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "Cela supprimera les fichiers cache non référencés par un article."
|
||||
@@ -444,43 +424,3 @@ msgstr "Vous n'avez pas l'autorisation de modifier cet article."
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "Votre navigateur ne prend pas en charge l'élément audio."
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "Format audio"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "Format audio de sortie. Le MP3 est universellement pris en charge. L'Opus offre une meilleure qualité au même débit mais a une compatibilité navigateur plus limitée."
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Débit Opus"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Débit pour l'encodage Opus. Opus atteint une bonne qualité à des débits bien inférieurs au MP3. Sortie mono."
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps (standard)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps (compact)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps (minimal)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "Chemin du binaire FFprobe"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "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."
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "Chemin absolu vers le binaire ffmpeg pour la conversion MP3/Opus. Auto-détecté depuis les chemins courants si laissé vide."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
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": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "Gestione cache",
|
||||
"Cache flushed.": "Cache svuotata.",
|
||||
"Choose a visual theme for the audio player.": "Scegli un tema visivo per il lettore audio.",
|
||||
"Chunk Silence": "Silenzio tra frasi",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Segmentato — pre-dividi il testo ai confini delle frasi",
|
||||
"Classic": "Classico",
|
||||
"Clear Log": "Cancella log",
|
||||
"Clear Orphaned Audio": "Rimuovi audio orfani",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "Livello di gravità minimo da registrare nel log.",
|
||||
"Models Directory": "Directory dei modelli",
|
||||
"Modern Dark": "Modern Dark",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "Nessun modello vocale Piper adatto trovato. Controlla la directory dei modelli.",
|
||||
"No text content available for this post.": "Nessun contenuto testuale disponibile per questo post.",
|
||||
"Orphaned files cleared.": "File orfani eliminati.",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "Post non trovato.",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "Anteprima di come appare lo stile del player selezionato con un clip audio di esempio.",
|
||||
"Quality tier override": "Override del livello di qualità",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "La modalità Greggio passa il testo direttamente a Piper. La modalità Segmentato divide prima il testo in frasi.",
|
||||
"Raw — send text as-is to Piper": "Greggio — invia il testo così com'è a Piper",
|
||||
"Refresh Log": "Aggiorna log",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Secondi di silenzio inseriti tra i blocchi di frasi in modalità Segmentato. Predefinito: 2.0. Intervallo: 0.5–5.0.",
|
||||
"Show Duration": "Mostra durata",
|
||||
"Skip Embedded Content": "Salta contenuti incorporati",
|
||||
"Styling": "Stile",
|
||||
"Test Connection": "Test connessione",
|
||||
"Testing…": "Test in corso…",
|
||||
"Text Processing": "Elaborazione del testo",
|
||||
"This will delete cache files not referenced by any post.": "Questo eliminerà i file di cache non referenziati da alcun post.",
|
||||
"Too many requests. Please try again later.": "Troppe richieste. Riprova più tardi.",
|
||||
"Unsupported post type.": "Tipo di post non supportato.",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "Quando si utilizza il corpo del post come fallback (nessun estratto), salta il testo da blocchi incorporati come YouTube, Twitter e embed di terze parti.",
|
||||
"Where to insert the audio player relative to the post content.": "Dove inserire il player audio rispetto al contenuto del post.",
|
||||
"You do not have permission to edit this post.": "Non hai il permesso di modificare questo post.",
|
||||
"Your browser does not support the audio element.": "Il tuo browser non supporta l'elemento audio.",
|
||||
"Audio Format": "Formato audio",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "Formato audio in uscita. L'MP3 è universalmente supportato. L'Opus offre una qualità migliore allo stesso bitrate ma ha un supporto browser più limitato.",
|
||||
"Opus Bitrate": "Bitrate Opus",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Bitrate per la codifica Opus. Opus raggiunge una buona qualità a bitrate molto più bassi dell'MP3. Uscita mono.",
|
||||
"24 kbps (standard)": "24 kbps (standard)",
|
||||
"16 kbps (compact)": "16 kbps (compatto)",
|
||||
"12 kbps (minimal)": "12 kbps (minimo)",
|
||||
"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è"
|
||||
"Your browser does not support the audio element.": "Il tuo browser non supporta l'elemento audio."
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: it <LL@li.org>\n"
|
||||
"Language: it_IT\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "Cache svuotata."
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "Scegli un tema visivo per il lettore audio."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "Silenzio tra frasi"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Segmentato — pre-dividi il testo ai confini delle frasi"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "Classico"
|
||||
@@ -236,6 +228,10 @@ msgstr "Directory dei modelli"
|
||||
msgid "Modern Dark"
|
||||
msgstr "Modern Dark"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "Nessun modello vocale Piper adatto trovato. Controlla la directory dei modelli."
|
||||
@@ -368,22 +364,10 @@ msgstr "Anteprima di come appare lo stile del player selezionato con un clip aud
|
||||
msgid "Quality tier override"
|
||||
msgstr "Override del livello di qualità"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "La modalità Greggio passa il testo direttamente a Piper. La modalità Segmentato divide prima il testo in frasi."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Greggio — invia il testo così com'è a Piper"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "Aggiorna log"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Secondi di silenzio inseriti tra i blocchi di frasi in modalità Segmentato. Predefinito: 2.0. Intervallo: 0.5–5.0."
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "Mostra durata"
|
||||
@@ -404,10 +388,6 @@ msgstr "Test connessione"
|
||||
msgid "Testing…"
|
||||
msgstr "Test in corso…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "Elaborazione del testo"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "Questo eliminerà i file di cache non referenziati da alcun post."
|
||||
@@ -444,43 +424,3 @@ msgstr "Non hai il permesso di modificare questo post."
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "Il tuo browser non supporta l'elemento audio."
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "Formato audio"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "Formato audio in uscita. L'MP3 è universalmente supportato. L'Opus offre una qualità migliore allo stesso bitrate ma ha un supporto browser più limitato."
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Bitrate Opus"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Bitrate per la codifica Opus. Opus raggiunge una buona qualità a bitrate molto più bassi dell'MP3. Uscita mono."
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps (standard)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps (compatto)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps (minimo)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "Percorso binario FFprobe"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "Percorso assoluto al binario ffprobe per il rilevamento della durata audio. Rilevato automaticamente dalla directory ffmpeg se lasciato vuoto."
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "Percorso assoluto al binario ffmpeg per la conversione MP3/Opus. Rilevato automaticamente se lasciato vuoto."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
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": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "キャッシュ管理",
|
||||
"Cache flushed.": "キャッシュをフラッシュしました。",
|
||||
"Choose a visual theme for the audio player.": "オーディオプレーヤーのビジュアルテーマを選択してください。",
|
||||
"Chunk Silence": "チャンク間の無音",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Chunked — 文の区切りでテキストを分割",
|
||||
"Classic": "クラシック",
|
||||
"Clear Log": "ログをクリア",
|
||||
"Clear Orphaned Audio": "孤立したオーディオをクリア",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "ログに記録する最小の重要度。",
|
||||
"Models Directory": "モデルディレクトリ",
|
||||
"Modern Dark": "モダンダーク",
|
||||
"NewsViews Classic": "ニュースビュークラシック",
|
||||
"No suitable Piper voice model found. Check your models directory.": "適切なPiper音声モデルが見つかりません。モデルディレクトリを確認してください。",
|
||||
"No text content available for this post.": "この投稿にはテキストコンテンツがありません。",
|
||||
"Orphaned files cleared.": "孤立ファイルをクリアしました。",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "投稿が見つかりません。",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "選択したプレイヤースタイルがサンプルオーディオクリップでどのように見えるかプレビューします。",
|
||||
"Quality tier override": "品質ティアの上書き",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "Rawモードはテキストを直接Piperに渡します。Chunkedモードは最初にテキストを文に分割します。",
|
||||
"Raw — send text as-is to Piper": "Raw — テキストをそのままPiperに送信",
|
||||
"Refresh Log": "ログの更新",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Chunkedモードで文チャンク間に挿入される無音の秒数。デフォルト: 2.0。範囲: 0.5–5.0。",
|
||||
"Show Duration": "再生時間を表示",
|
||||
"Skip Embedded Content": "埋め込みコンテンツをスキップ",
|
||||
"Styling": "スタイリング",
|
||||
"Test Connection": "接続テスト",
|
||||
"Testing…": "テスト中…",
|
||||
"Text Processing": "テキスト処理",
|
||||
"This will delete cache files not referenced by any post.": "これにより、どの投稿からも参照されていないキャッシュファイルが削除されます。",
|
||||
"Too many requests. Please try again later.": "リクエストが多すぎます。後でもう一度お試しください。",
|
||||
"Unsupported post type.": "サポートされていない投稿タイプです。",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "抜粋がない場合に投稿本文にフォールバックする際、YouTube、Twitter、サードパーティの埋め込みブロックのテキストをスキップします。",
|
||||
"Where to insert the audio player relative to the post content.": "投稿コンテンツに対するオーディオプレーヤーの挿入位置。",
|
||||
"You do not have permission to edit this post.": "この投稿を編集する権限がありません。",
|
||||
"Your browser does not support the audio element.": "お使いのブラウザはオーディオ要素をサポートしていません。",
|
||||
"Audio Format": "オーディオフォーマット",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "出力オーディオフォーマット。MP3は普遍的にサポートされています。Opusは同じビットレートでより高品質ですが、ブラウザのサポートは限定的です。",
|
||||
"Opus Bitrate": "Opusビットレート",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Opusエンコーディングのビットレート。OpusはMP3よりはるかに低いビットレートで良好な品質を実現します。モノラル出力。",
|
||||
"24 kbps (standard)": "24 kbps(標準)",
|
||||
"16 kbps (compact)": "16 kbps(コンパクト)",
|
||||
"12 kbps (minimal)": "12 kbps(最小)",
|
||||
"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": "コーヒーを奢ってください"
|
||||
"Your browser does not support the audio element.": "お使いのブラウザはオーディオ要素をサポートしていません。"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Japanese <LL@li.org>\n"
|
||||
"Language: ja\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "キャッシュをフラッシュしました。"
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "オーディオプレーヤーのビジュアルテーマを選択してください。"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "チャンク間の無音"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Chunked — 文の区切りでテキストを分割"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "クラシック"
|
||||
@@ -236,6 +228,10 @@ msgstr "モデルディレクトリ"
|
||||
msgid "Modern Dark"
|
||||
msgstr "モダンダーク"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "ニュースビュークラシック"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "適切なPiper音声モデルが見つかりません。モデルディレクトリを確認してください。"
|
||||
@@ -368,22 +364,10 @@ msgstr "選択したプレイヤースタイルがサンプルオーディオク
|
||||
msgid "Quality tier override"
|
||||
msgstr "品質ティアの上書き"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "Rawモードはテキストを直接Piperに渡します。Chunkedモードは最初にテキストを文に分割します。"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Raw — テキストをそのままPiperに送信"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "ログの更新"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Chunkedモードで文チャンク間に挿入される無音の秒数。デフォルト: 2.0。範囲: 0.5–5.0。"
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "再生時間を表示"
|
||||
@@ -404,10 +388,6 @@ msgstr "接続テスト"
|
||||
msgid "Testing…"
|
||||
msgstr "テスト中…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "テキスト処理"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "これにより、どの投稿からも参照されていないキャッシュファイルが削除されます。"
|
||||
@@ -444,43 +424,3 @@ msgstr "この投稿を編集する権限がありません。"
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "お使いのブラウザはオーディオ要素をサポートしていません。"
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "オーディオフォーマット"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "出力オーディオフォーマット。MP3は普遍的にサポートされています。Opusは同じビットレートでより高品質ですが、ブラウザのサポートは限定的です。"
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Opusビットレート"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Opusエンコーディングのビットレート。OpusはMP3よりはるかに低いビットレートで良好な品質を実現します。モノラル出力。"
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps(標準)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps(コンパクト)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps(最小)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "FFprobeバイナリパス"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "音声の長さ検出用ffprobeバイナリへの絶対パス。空の場合はffmpegディレクトリから自動検出されます。"
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "MP3/Opus変換用ffmpegバイナリへの絶対パス。空の場合は自動検出されます。"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "ダン・ラザー・ブルー"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHubリポジトリ"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "コーヒーを奢ってください"
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"_meta": {
|
||||
"locale": "nl_NL",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"generated": "2026-05-09",
|
||||
"total_strings": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "Cachebeheer",
|
||||
"Cache flushed.": "Cache geleegd.",
|
||||
"Choose a visual theme for the audio player.": "Kies een visueel thema voor de audiospeler.",
|
||||
"Chunk Silence": "Pauzelengte",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Gesegmenteerd — splits tekst vooraf op zinsgrenzen",
|
||||
"Classic": "Klassiek",
|
||||
"Clear Log": "Log wissen",
|
||||
"Clear Orphaned Audio": "Verweesde audio wissen",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "Minimale ernst om in het log vast te leggen.",
|
||||
"Models Directory": "Modellenmap",
|
||||
"Modern Dark": "Modern Donker",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "Geen geschikt Piper stemmodel gevonden. Controleer je modellenmap.",
|
||||
"No text content available for this post.": "Geen tekstinhoud beschikbaar voor dit bericht.",
|
||||
"Orphaned files cleared.": "Verweesde bestanden gewist.",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "Bericht niet gevonden.",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "Bekijk hoe de geselecteerde spelerstijl eruitziet met een voorbeeld-audiofragment.",
|
||||
"Quality tier override": "Kwaliteitsniveau overschrijven",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "Ruwe modus stuurt tekst direct naar Piper. Gesegmenteerde modus splitst tekst eerst in zinnen.",
|
||||
"Raw — send text as-is to Piper": "Ruw — stuur tekst ongewijzigd naar Piper",
|
||||
"Refresh Log": "Log vernieuwen",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Seconden stilte tussen zinsblokken in Gesegmenteerde modus. Standaard: 2.0. Bereik: 0.5–5.0.",
|
||||
"Show Duration": "Toon duur",
|
||||
"Skip Embedded Content": "Ingesloten inhoud overslaan",
|
||||
"Styling": "Vormgeving",
|
||||
"Test Connection": "Verbinding testen",
|
||||
"Testing…": "Testen…",
|
||||
"Text Processing": "Tekstverwerking",
|
||||
"This will delete cache files not referenced by any post.": "Hiermee worden cachebestanden verwijderd die niet aan een bericht zijn gekoppeld.",
|
||||
"Too many requests. Please try again later.": "Te veel verzoeken. Probeer het later opnieuw.",
|
||||
"Unsupported post type.": "Niet-ondersteund berichttype.",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "Bij terugvallen op berichtinhoud (geen samenvatting), tekst van ingesloten blokken zoals YouTube, Twitter en embeds van derden overslaan.",
|
||||
"Where to insert the audio player relative to the post content.": "Waar de audiospeler moet worden ingevoegd ten opzichte van de berichtinhoud.",
|
||||
"You do not have permission to edit this post.": "Je hebt geen rechten om dit bericht te bewerken.",
|
||||
"Your browser does not support the audio element.": "Je browser ondersteunt het audio-element niet.",
|
||||
"Audio Format": "Audioformaat",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "Uitvoer audioformaat. MP3 wordt universeel ondersteund. Opus biedt betere kwaliteit bij dezelfde bitrate maar heeft beperktere browserondersteuning.",
|
||||
"Opus Bitrate": "Opus-bitrate",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Bitrate voor Opus-codering. Opus bereikt goede kwaliteit bij veel lagere bitrates dan MP3. Mono-uitvoer.",
|
||||
"24 kbps (standard)": "24 kbps (standaard)",
|
||||
"16 kbps (compact)": "16 kbps (compact)",
|
||||
"12 kbps (minimal)": "12 kbps (minimaal)",
|
||||
"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"
|
||||
"Your browser does not support the audio element.": "Je browser ondersteunt het audio-element niet."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-09 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Dutch <LL@li.org>\n"
|
||||
"Language: nl_NL\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "Cache geleegd."
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "Kies een visueel thema voor de audiospeler."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "Pauzelengte"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Gesegmenteerd — splits tekst vooraf op zinsgrenzen"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "Klassiek"
|
||||
@@ -236,6 +228,10 @@ msgstr "Modellenmap"
|
||||
msgid "Modern Dark"
|
||||
msgstr "Modern Donker"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "Geen geschikt Piper stemmodel gevonden. Controleer je modellenmap."
|
||||
@@ -368,22 +364,10 @@ msgstr "Bekijk hoe de geselecteerde spelerstijl eruitziet met een voorbeeld-audi
|
||||
msgid "Quality tier override"
|
||||
msgstr "Kwaliteitsniveau overschrijven"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "Ruwe modus stuurt tekst direct naar Piper. Gesegmenteerde modus splitst tekst eerst in zinnen."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Ruw — stuur tekst ongewijzigd naar Piper"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "Log vernieuwen"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Seconden stilte tussen zinsblokken in Gesegmenteerde modus. Standaard: 2.0. Bereik: 0.5–5.0."
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "Toon duur"
|
||||
@@ -404,10 +388,6 @@ msgstr "Verbinding testen"
|
||||
msgid "Testing…"
|
||||
msgstr "Testen…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "Tekstverwerking"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "Hiermee worden cachebestanden verwijderd die niet aan een bericht zijn gekoppeld."
|
||||
@@ -444,43 +424,3 @@ msgstr "Je hebt geen rechten om dit bericht te bewerken."
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "Je browser ondersteunt het audio-element niet."
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "Audioformaat"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "Uitvoer audioformaat. MP3 wordt universeel ondersteund. Opus biedt betere kwaliteit bij dezelfde bitrate maar heeft beperktere browserondersteuning."
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Opus-bitrate"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Bitrate voor Opus-codering. Opus bereikt goede kwaliteit bij veel lagere bitrates dan MP3. Mono-uitvoer."
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps (standaard)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps (compact)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps (minimaal)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "FFprobe-binair pad"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "Absoluut pad naar de ffprobe binary voor audioduurdetectie. Automatisch gedetecteerd vanuit de ffmpeg-directory, indien leeg gelaten."
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "Absoluut pad naar de ffmpeg binary voor MP3/Opus-conversie. Automatisch gedetecteerd als leeg gelaten."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
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": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "Gerenciamento de Cache",
|
||||
"Cache flushed.": "Cache limpo.",
|
||||
"Choose a visual theme for the audio player.": "Escolha um tema visual para o reprodutor de áudio.",
|
||||
"Chunk Silence": "Silêncio entre frases",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "Segmentado — pré-dividir texto nos limites das frases",
|
||||
"Classic": "Clássico",
|
||||
"Clear Log": "Limpar Log",
|
||||
"Clear Orphaned Audio": "Limpar Áudio Órfão",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "Severidade mínima para registrar no log.",
|
||||
"Models Directory": "Diretório de Modelos",
|
||||
"Modern Dark": "Modern Dark",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "Nenhum modelo de voz Piper adequado encontrado. Verifique seu diretório de modelos.",
|
||||
"No text content available for this post.": "Nenhum conteúdo de texto disponível para esta publicação.",
|
||||
"Orphaned files cleared.": "Arquivos órfãos limpos.",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "Post não encontrado.",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "Visualize como o estilo de player selecionado fica com um clipe de áudio de exemplo.",
|
||||
"Quality tier override": "Substituição de nível de qualidade",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "O modo Bruto envia o texto diretamente para o Piper. O modo Segmentado divide o texto em frases.",
|
||||
"Raw — send text as-is to Piper": "Bruto — enviar texto como está para o Piper",
|
||||
"Refresh Log": "Atualizar Log",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "Segundos de silêncio inseridos entre blocos de frases no modo Segmentado. Padrão: 2.0. Intervalo: 0.5–5.0.",
|
||||
"Show Duration": "Mostrar Duração",
|
||||
"Skip Embedded Content": "Pular Conteúdo Incorporado",
|
||||
"Styling": "Estilização",
|
||||
"Test Connection": "Testar Conexão",
|
||||
"Testing…": "Testando…",
|
||||
"Text Processing": "Processamento de texto",
|
||||
"This will delete cache files not referenced by any post.": "Isso excluirá arquivos de cache não referenciados por nenhum post.",
|
||||
"Too many requests. Please try again later.": "Muitas solicitações. Tente novamente mais tarde.",
|
||||
"Unsupported post type.": "Tipo de post não suportado.",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "Ao recorrer ao corpo do post (sem resumo), pular texto de blocos incorporados como YouTube, Twitter e embeds de terceiros.",
|
||||
"Where to insert the audio player relative to the post content.": "Onde inserir o player de áudio em relação ao conteúdo do post.",
|
||||
"You do not have permission to edit this post.": "Você não tem permissão para editar este post.",
|
||||
"Your browser does not support the audio element.": "Seu navegador não suporta o elemento de áudio.",
|
||||
"Audio Format": "Formato de áudio",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "Formato de áudio de saída. MP3 é universalmente suportado. Opus oferece melhor qualidade na mesma taxa de bits, mas tem suporte de navegador mais limitado.",
|
||||
"Opus Bitrate": "Bitrate do Opus",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Bitrate para codificação Opus. O Opus alcança boa qualidade em taxas de bits muito mais baixas que o MP3. Saída mono.",
|
||||
"24 kbps (standard)": "24 kbps (padrão)",
|
||||
"16 kbps (compact)": "16 kbps (compacto)",
|
||||
"12 kbps (minimal)": "12 kbps (mínimo)",
|
||||
"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é"
|
||||
"Your browser does not support the audio element.": "Seu navegador não suporta o elemento de áudio."
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-10 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: pt <LL@li.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "Cache limpo."
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "Escolha um tema visual para o reprodutor de áudio."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "Silêncio entre frases"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "Segmentado — pré-dividir texto nos limites das frases"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "Clássico"
|
||||
@@ -236,6 +228,10 @@ msgstr "Diretório de Modelos"
|
||||
msgid "Modern Dark"
|
||||
msgstr "Modern Dark"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "Nenhum modelo de voz Piper adequado encontrado. Verifique seu diretório de modelos."
|
||||
@@ -368,22 +364,10 @@ msgstr "Visualize como o estilo de player selecionado fica com um clipe de áudi
|
||||
msgid "Quality tier override"
|
||||
msgstr "Substituição de nível de qualidade"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "O modo Bruto envia o texto diretamente para o Piper. O modo Segmentado divide o texto em frases."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "Bruto — enviar texto como está para o Piper"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "Atualizar Log"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "Segundos de silêncio inseridos entre blocos de frases no modo Segmentado. Padrão: 2.0. Intervalo: 0.5–5.0."
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "Mostrar Duração"
|
||||
@@ -404,10 +388,6 @@ msgstr "Testar Conexão"
|
||||
msgid "Testing…"
|
||||
msgstr "Testando…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "Processamento de texto"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "Isso excluirá arquivos de cache não referenciados por nenhum post."
|
||||
@@ -444,43 +424,3 @@ msgstr "Você não tem permissão para editar este post."
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "Seu navegador não suporta o elemento de áudio."
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "Formato de áudio"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "Formato de áudio de saída. MP3 é universalmente suportado. Opus oferece melhor qualidade na mesma taxa de bits, mas tem suporte de navegador mais limitado."
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Bitrate do Opus"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Bitrate para codificação Opus. O Opus alcança boa qualidade em taxas de bits muito mais baixas que o MP3. Saída mono."
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps (padrão)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps (compacto)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps (mínimo)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "Caminho do binário FFprobe"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "Caminho absoluto para o binário ffprobe para detecção de duração do áudio. Detectado automaticamente do diretório ffmpeg se deixado vazio."
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "Caminho absoluto para o binário ffmpeg para conversão MP3/Opus. Detectado automaticamente se deixado vazio."
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
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é"
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"_meta": {
|
||||
"locale": "zh_CN",
|
||||
"source": "translations.json",
|
||||
"generated": "2026-05-10",
|
||||
"total_strings": 120,
|
||||
"translated": 120,
|
||||
"generated": "2026-05-09",
|
||||
"total_strings": 102,
|
||||
"translated": 102,
|
||||
"locked": false
|
||||
},
|
||||
"strings": {
|
||||
@@ -23,8 +23,6 @@
|
||||
"Cache Management": "缓存管理",
|
||||
"Cache flushed.": "缓存已清空。",
|
||||
"Choose a visual theme for the audio player.": "为音频播放器选择一个视觉主题。",
|
||||
"Chunk Silence": "块间静音",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "分块 — 在句子边界预先分割文本",
|
||||
"Classic": "经典",
|
||||
"Clear Log": "清除日志",
|
||||
"Clear Orphaned Audio": "清除孤立音频",
|
||||
@@ -63,6 +61,7 @@
|
||||
"Minimum severity to record in the log.": "记录到日志的最低严重程度。",
|
||||
"Models Directory": "模型目录",
|
||||
"Modern Dark": "现代深色",
|
||||
"NewsViews Classic": "NewsViews Classic",
|
||||
"No suitable Piper voice model found. Check your models directory.": "未找到合适的 Piper 声音模型。请检查您的模型目录。",
|
||||
"No text content available for this post.": "此文章没有可用的文本内容。",
|
||||
"Orphaned files cleared.": "孤立文件已清除。",
|
||||
@@ -96,16 +95,12 @@
|
||||
"Post not found.": "未找到文章。",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "使用示例音频片段预览所选播放器样式的效果。",
|
||||
"Quality tier override": "质量级别覆盖",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "原始模式直接将文本传递给 Piper。分块模式先将文本分割成句子。",
|
||||
"Raw — send text as-is to Piper": "原始 — 直接将文本发送给 Piper",
|
||||
"Refresh Log": "刷新日志",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "分块模式下句子块之间插入的静音秒数。默认:2.0。范围:0.5–5.0。",
|
||||
"Show Duration": "显示时长",
|
||||
"Skip Embedded Content": "跳过嵌入内容",
|
||||
"Styling": "样式",
|
||||
"Test Connection": "测试连接",
|
||||
"Testing…": "正在测试…",
|
||||
"Text Processing": "文本处理",
|
||||
"This will delete cache files not referenced by any post.": "这将删除未被任何文章引用的缓存文件。",
|
||||
"Too many requests. Please try again later.": "请求过多。请稍后再试。",
|
||||
"Unsupported post type.": "不支持的文章类型。",
|
||||
@@ -114,19 +109,6 @@
|
||||
"When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds.": "当回退到文章正文(无摘要)时,跳过 YouTube、Twitter 和第三方嵌入等嵌入块中的文本。",
|
||||
"Where to insert the audio player relative to the post content.": "音频播放器相对于文章内容的插入位置。",
|
||||
"You do not have permission to edit this post.": "您没有编辑此文章的权限。",
|
||||
"Your browser does not support the audio element.": "您的浏览器不支持音频元素。",
|
||||
"Audio Format": "音频格式",
|
||||
"Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support.": "输出音频格式。MP3 被普遍支持。Opus 在相同比特率下提供更好的质量,但浏览器支持较窄。",
|
||||
"Opus Bitrate": "Opus 比特率",
|
||||
"Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output.": "Opus 编码的比特率。Opus 在比 MP3 低得多的比特率下仍能实现良好的质量。单声道输出。",
|
||||
"24 kbps (standard)": "24 kbps(标准)",
|
||||
"16 kbps (compact)": "16 kbps(紧凑)",
|
||||
"12 kbps (minimal)": "12 kbps(最小)",
|
||||
"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": "请我喝杯咖啡"
|
||||
"Your browser does not support the audio element.": "您的浏览器不支持音频元素。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: Piperless 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/example/piperless/issues\n"
|
||||
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-11 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-05-09 00:00+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: zh <LL@li.org>\n"
|
||||
"Language: zh_CN\n"
|
||||
@@ -76,14 +76,6 @@ msgstr "缓存已清空。"
|
||||
msgid "Choose a visual theme for the audio player."
|
||||
msgstr "为音频播放器选择一个视觉主题。"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr "块间静音"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr "分块 — 在句子边界预先分割文本"
|
||||
|
||||
#: includes/class-settings.php:385
|
||||
msgid "Classic"
|
||||
msgstr "经典"
|
||||
@@ -236,6 +228,10 @@ msgstr "模型目录"
|
||||
msgid "Modern Dark"
|
||||
msgstr "现代深色"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "NewsViews Classic"
|
||||
msgstr "NewsViews Classic"
|
||||
|
||||
#: includes/class-transcriber.php:83
|
||||
msgid "No suitable Piper voice model found. Check your models directory."
|
||||
msgstr "未找到合适的 Piper 声音模型。请检查您的模型目录。"
|
||||
@@ -368,22 +364,10 @@ msgstr "使用示例音频片段预览所选播放器样式的效果。"
|
||||
msgid "Quality tier override"
|
||||
msgstr "质量级别覆盖"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr "原始模式直接将文本传递给 Piper。分块模式先将文本分割成句子。"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr "原始 — 直接将文本发送给 Piper"
|
||||
|
||||
#: includes/class-settings.php:607
|
||||
msgid "Refresh Log"
|
||||
msgstr "刷新日志"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr "分块模式下句子块之间插入的静音秒数。默认:2.0。范围:0.5–5.0。"
|
||||
|
||||
#: includes/class-settings.php:405
|
||||
msgid "Show Duration"
|
||||
msgstr "显示时长"
|
||||
@@ -404,10 +388,6 @@ msgstr "测试连接"
|
||||
msgid "Testing…"
|
||||
msgstr "正在测试…"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr "文本处理"
|
||||
|
||||
#: includes/class-settings.php:649
|
||||
msgid "This will delete cache files not referenced by any post."
|
||||
msgstr "这将删除未被任何文章引用的缓存文件。"
|
||||
@@ -444,43 +424,3 @@ msgstr "您没有编辑此文章的权限。"
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr "您的浏览器不支持音频元素。"
|
||||
|
||||
msgid "Audio Format"
|
||||
msgstr "音频格式"
|
||||
|
||||
msgid "Output audio format. MP3 is universally supported. Opus offers better quality at the same bitrate but has narrower browser support."
|
||||
msgstr "输出音频格式。MP3 被普遍支持。Opus 在相同比特率下提供更好的质量,但浏览器支持较窄。"
|
||||
|
||||
msgid "Opus Bitrate"
|
||||
msgstr "Opus 比特率"
|
||||
|
||||
msgid "Bitrate for Opus encoding. Opus achieves good quality at much lower bitrates than MP3. Mono output."
|
||||
msgstr "Opus 编码的比特率。Opus 在比 MP3 低得多的比特率下仍能实现良好的质量。单声道输出。"
|
||||
|
||||
msgid "24 kbps (standard)"
|
||||
msgstr "24 kbps(标准)"
|
||||
|
||||
msgid "16 kbps (compact)"
|
||||
msgstr "16 kbps(紧凑)"
|
||||
|
||||
msgid "12 kbps (minimal)"
|
||||
msgstr "12 kbps(最小)"
|
||||
|
||||
msgid "FFprobe Binary Path"
|
||||
msgstr "FFprobe 二进制文件路径"
|
||||
|
||||
msgid "Absolute path to the ffprobe binary for audio duration detection. Auto-detected from the ffmpeg directory if left empty."
|
||||
msgstr "ffprobe 二进制文件的绝对路径,用于音频时长检测。留空则从 ffmpeg 目录自动检测。"
|
||||
|
||||
msgid "Absolute path to the ffmpeg binary for MP3/Opus conversion. Auto-detected from common paths if left empty."
|
||||
msgstr "ffmpeg 二进制文件的绝对路径,用于 MP3/Opus 转换。留空则自动检测。"
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Dan Rather Blue"
|
||||
msgstr "丹·拉瑟蓝"
|
||||
|
||||
msgid "GitHub Repository"
|
||||
msgstr "GitHub 仓库"
|
||||
|
||||
msgid "Buy me a coffee"
|
||||
msgstr "请我喝杯咖啡"
|
||||
|
||||
|
||||
+1
-25
@@ -149,30 +149,6 @@ msgstr ""
|
||||
msgid "When falling back to post body (no excerpt), skip text from embedded blocks like YouTube, Twitter, and third-party embeds."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Text Processing"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw — send text as-is to Piper"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunked — pre-split text at sentence boundaries for better pacing"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Chunk Silence"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:378
|
||||
msgid "Audio Player Settings"
|
||||
msgstr ""
|
||||
@@ -242,7 +218,7 @@ msgid "Above & below content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-settings.php:now
|
||||
msgid "Dan Rather Blue"
|
||||
msgid "NewsViews Classic"
|
||||
msgstr ""
|
||||
|
||||
#: assets/js/gutenberg.js
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
"Cache Management": "",
|
||||
"Cache flushed.": "",
|
||||
"Choose a visual theme for the audio player.": "",
|
||||
"Chunk Silence": "",
|
||||
"Chunked — pre-split text at sentence boundaries for better pacing": "",
|
||||
"Classic": "",
|
||||
"Clear Log": "",
|
||||
"Clear Orphaned Audio": "",
|
||||
@@ -90,16 +88,12 @@
|
||||
"Post not found.": "",
|
||||
"Preview how the selected player style looks with a sample audio clip.": "",
|
||||
"Quality tier override": "",
|
||||
"Raw mode passes text directly to Piper. Chunked mode splits text into sentences first, avoiding false breaks on abbreviations and decimals while improving sentence pacing.": "",
|
||||
"Raw — send text as-is to Piper": "",
|
||||
"Refresh Log": "",
|
||||
"Seconds of silence inserted between sentence chunks when Text Processing is set to Chunked. Default: 2.0. Range: 0.5–5.0.": "",
|
||||
"Show Duration": "",
|
||||
"Skip Embedded Content": "",
|
||||
"Styling": "",
|
||||
"Test Connection": "",
|
||||
"Testing…": "",
|
||||
"Text Processing": "",
|
||||
"This will delete cache files not referenced by any post.": "",
|
||||
"Too many requests. Please try again later.": "",
|
||||
"Unsupported post type.": "",
|
||||
|
||||
+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.2
|
||||
* Version: 1.0.0
|
||||
* Requires at least: 6.0
|
||||
* Requires PHP: 8.0
|
||||
* Author: Forkless
|
||||
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
}
|
||||
|
||||
// ── Constants ────────────────────────────────────────────────────────────────
|
||||
define( 'PIPERLESS_VERSION', '1.1.3' );
|
||||
define( 'PIPERLESS_VERSION', '1.0.0' );
|
||||
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