diff --git a/AUDIO_PLAYBACK_TESTING.md b/AUDIO_PLAYBACK_TESTING.md new file mode 100644 index 0000000..cbbc67b --- /dev/null +++ b/AUDIO_PLAYBACK_TESTING.md @@ -0,0 +1,156 @@ +# Testing Lua audio playback + +This guide tests issue #315 with a real WAV or MP3. The examples use the +T-Deck environment and the provided `scripts/audio_test.lua` app. + +## Build and flash + +Build and upload the branch as usual: + +```sh +pio run -e LilyGo_TDeck_companion_radio_touch +pio run -e LilyGo_TDeck_companion_radio_touch -t upload +``` + +Keep the serial monitor available for `[LUAAPP]` or storage errors: + +```sh +pio device monitor -b 115200 +``` + +## Quick MP3 test from SD + +1. Use a FAT32 SD card and create these paths on it: + + ```text + /Music/test.mp3 + /meshcomod/apps/audio_test.lua + ``` + +2. Copy `scripts/audio_test.lua` from this repository to the second path. Rename + your MP3 to `test.mp3`, or edit `SD_PATH` near the top of the Lua file. +3. Insert the card before boot, then reboot the T-Deck. +4. Enable **Settings > Sound** and set volume above zero. +5. Open **Apps > audio_test**. The screen should report + `audio=true`, `wav=true`, and `mp3=true`. +6. Press **Play**. Expected status: + + ```text + State: playing + Source: sd Format: mp3 + ``` + +7. Exercise **Pause**, **Resume**, and **Stop**. Pressing **Play** while already + playing must restart/replace the current track without overlapping it. +8. Start playback and leave the app. Audio must stop immediately when the app + closes. + +The direct SD API used by the test is: + +```lua +local ok, err = wada.audio.play("sd:/Music/test.mp3") +``` + +`sd:` paths are absolute from the physical card root. Empty segments, +backslashes, trailing slashes, `.` and `..` are rejected. + +## Test app-local/internal storage + +A plain filename is resolved inside the current app's private directory. For +`audio_test.lua`, the logical files are: + +```text +/apps/audio_test.lua +/apps/audio_test.d/test.mp3 +``` + +On T-Deck and Pager, internal app storage is SPIFFS. The least destructive way +to populate it is the repository's serial uploader: + +1. Power off, remove the SD card, and reboot. This forces T-Deck app storage to + the internal SPIFFS backend. +2. Make a short internal-storage fixture. T-Deck has a 3.375 MB SPIFFS partition + shared with settings and history, so use the full song for SD testing and a + small clip here: + + ```sh + ffmpeg -y -i "/path/to/your/file.mp3" \ + -t 10 -ac 1 -ar 22050 -b:a 48k \ + /tmp/wadamesh-audio-test.mp3 + ``` + +3. Find the serial port with `pio device list`. +4. Install `pyserial` once if needed: + + ```sh + python3 -m pip install pyserial + ``` + +5. Upload the app and short MP3. Replace the port as needed: + + ```sh + python3 scripts/sideload_app.py \ + --port /dev/cu.usbmodem101 \ + --remote /apps/audio_test.lua \ + scripts/audio_test.lua + + python3 scripts/sideload_app.py \ + --port /dev/cu.usbmodem101 \ + --remote /apps/audio_test.d/test.mp3 \ + --reboot \ + /tmp/wadamesh-audio-test.mp3 + ``` + +6. Open **Apps > audio_test** after reboot. With no card inserted, the app + selects `test.mp3`; press **Play**. +7. Expected status is `Source: app Format: mp3`. + +The app-local API is simply: + +```lua +local ok, err = wada.audio.play("test.mp3") +``` + +Tanmatsu uses internal FFat and T-Display P4 uses internal LittleFS. The same +serial destination `/apps/audio_test.d/test.mp3` follows the active internal +backend, so no Lua code changes are needed. Direct `sd:` playback is shown only +when `wada.sys.caps().audio_sd` is true. + +Do not use `uploadfs` on a device with data you need to keep: a filesystem-image +upload replaces the internal storage partition, including settings and history. + +## Error and lifecycle checks + +- Disable Sound, then press **Play**: expect `Command: muted`. +- Rename the file or remove the card: expect `not found` or `no sd`. +- Try a non-WAV/MP3 extension: expect `unsupported format`. +- Remove the card during SD playback only after the baseline test. Playback must + enter `error` or stop without rebooting; reinserting the card should allow a + later play after the normal SD recovery delay. +- Receive a mesh notification during playback: it must not start a second audio + stream over the media track. +- Repeatedly open/play/close the app: each close must release the worker, codec, + amplifier, file handle, and storage lease. + +## Host decoder regression test + +The standalone test validates the pinned decoder and the same rolling 16 KB +input algorithm used by firmware: + +```sh +c++ -std=c++17 -O2 test/test_minimp3_decoder.cpp -o /tmp/test_minimp3_decoder +/tmp/test_minimp3_decoder /path/to/your/file.mp3 +``` + +A successful run prints decoded frames, samples per channel, sample rate, +channels, and bitrate changes. The implementation has also been checked with +CBR, VBR, leading ID3v2, trailing ID3v1, and trailing APEv2 metadata. + +## Supported formats + +- WAV: PCM, 16-bit, mono or stereo, 8-48 kHz. +- MP3: MPEG Layer III, mono or stereo, 8-48 kHz, CBR or VBR, with common ID3 and + APEv2 metadata. + +Stereo is downmixed to the device's mono speaker path. `status()` reports +`stopped`, `playing`, `paused`, `ended`, or `error`. diff --git a/DEVICES.md b/DEVICES.md index 3b937cf..e10a096 100644 --- a/DEVICES.md +++ b/DEVICES.md @@ -16,13 +16,17 @@ USB) and the [GitHub releases](https://github.com/ALLFATHER-BV/wadamesh/releases | LilyGo T-Lora Pager | ESP32-S3, LR1121 or SX1262 | 2.33" IPS LCD, 480x222 (no touch), QWERTY + rotary encoder | Web flasher (pick the build matching your radio) | Beta (new in beta_45) | Fully supported; keyboard-first navigation, microSD, map tile packs | | Heltec V4-R8 + Expansion Kit V2 | ESP32-S3 (8 MB octal PSRAM), SX1262 | 2.4" touch (CHSC6x) | Web flasher | Beta (new in beta_45) | As the V4 plus microSD and the Expansion Kit sensors; buzzer supported | | LilyGo T-Display P4 | ESP32-P4 + ESP32-C6, SX1262 | AMOLED or TFT-LCD, touch | Web flasher (AMOLED) or the .bin for the LCD SKU | Beta (new in beta_45) | Two screen SKUs; fuel-gauge battery reporting, full TX power | -| Attaky Mesh Series | ESP32-S3, SX1262 | Touch display | Web flasher | Beta (new in beta_47) | Community port by attakygit (#158/#169); detachable keyboard supported | +| Attaky Mesh Series | ESP32-S3, SX1262 | Touch display + front D-pad | Web flasher | Beta (new in beta_47) | Community port by attakygit (#158/#169); detachable keyboard supported; the front D-pad + SELECT navigate the UI | ## Feature notes per board - **T-Deck**: the everything device: touch, physical keyboard, trackball cursor or d-pad navigation, microSD (deep 5000-message chat history, map tile packs, data storage), GPS on the Plus, notification sounds through the I2S speaker. + Tap Sym or Alt for one symbol, or double-tap either to lock the symbol layer; + this needs [LilyGO keyboard-controller firmware with raw matrix mode](https://github.com/Xinyuan-LilyGO/T-Deck/tree/master/examples/Keyboard_ESP32C3) + (June 2025 or newer). Older controller firmware keeps normal typing and + reports the unavailable latch mode on Serial. - **Heltec V4 + TFT**: touch UI with the on-screen keyboard; the optional Expansion Kit adds environment sensors (home-screen chart) and a piezo buzzer. V4.3 boards get the switchable high-gain receive LNA toggle. @@ -33,6 +37,8 @@ USB) and the [GitHub releases](https://github.com/ALLFATHER-BV/wadamesh/releases - **T-Lora Pager**: no touchscreen at all — the QWERTY keyboard and the rotary encoder drive everything (Alt+turn free-scrolls a page; see [TLORA_PAGER_SHORTCUTS.md](TLORA_PAGER_SHORTCUTS.md) for the full key map). + Tap Fn/Alt for one symbol or double-tap it to lock the symbol layer; physical + hold combinations keep their existing behavior. GPS, microSD, keyboard backlight, lock screen and notification sound through the onboard codec and amp all work. Two builds, one per radio: LR1121 and SX1262 — flashing the wrong one leaves you with no radio, so check the label diff --git a/NOTICE b/NOTICE index e5b4be9..711abdc 100644 --- a/NOTICE +++ b/NOTICE @@ -54,6 +54,13 @@ ed25519 (bundled in lib/ed25519) Orson Peters / orlp — public domain (Creative Commons Zero / zlib) https://github.com/orlp/ed25519 +minimp3 (bundled in lib/minimp3) + lieff/minimp3 contributors — CC0 1.0 Universal + https://github.com/lieff/minimp3 + Pinned at ea99364f61c14656440e8d77e9c233ccf3124633. The bundled header has + a small opt-in scratch-storage hook so the decoder workspace can live in + PSRAM; default upstream behavior is unchanged when that hook is not used. + AsyncElegantOTA (vendored in arch/esp32/AsyncElegantOTA) Copyright (c) Ayush Sharma — MIT License diff --git a/README.md b/README.md index 60ea0cd..2946c56 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ the transports, …) are dropped from the lib via `-DMC_VENDORED_TOUCH_APP` so t aren't compiled twice. The build is byte-identical to the original in-tree meshcomod firmware. +Lua apps use the on-device SDK described in [LUA_APPS.md](LUA_APPS.md). For +WAV/MP3 playback, including a ready-to-sideload transport test app and exact SD +and internal-storage paths, see [AUDIO_PLAYBACK_TESTING.md](AUDIO_PLAYBACK_TESTING.md). + ## Build [PlatformIO](https://platformio.org/) pulls the core fork and all libraries diff --git a/TLORA_PAGER_PORT.md b/TLORA_PAGER_PORT.md index 08c1d8e..89916f2 100644 --- a/TLORA_PAGER_PORT.md +++ b/TLORA_PAGER_PORT.md @@ -225,8 +225,8 @@ WASD-panning). `updatePagerAltShiftChord()` toggles Caps Lock ONLY while a text field is actually being edited (same "ta" derivation `handleHwKey()`'s TLORA_PAGER branch already uses to tell a bound-but-unfocused field apart from one - actually being edited), and jumps straight to Home (`navGoToMainTab`) - everywhere else. + actually being edited), and is a no-op everywhere else. Alt+Backspace is + the context-independent Home shortcut. 3. **@-mention contact picker made encoder-navigable** (commit `57802eb`) — the same unreachable-without-touch problem the accent box had, fixed the same way (`mentionNavRestyle()`/`mentionNavConfirm()` mirror @@ -622,9 +622,9 @@ existing boards. Notes: `pagerKeyboardConsumeAltShiftChord()`; `UITask.cpp`'s `updatePagerAltShiftChord()` toggles persistent Caps Lock ONLY while a text field is actually being edited (same "ta" derivation as `handleHwKey()`'s - TLORA_PAGER branch), and jumps straight Home (`navGoToMainTab`) everywhere - else — toggling Caps Lock with no field to see it change in was reported as - surprising/purposeless outside of typing. + TLORA_PAGER branch), and is a no-op everywhere else — toggling Caps Lock + with no field to see it change in was reported as surprising/purposeless + outside of typing. Alt+Backspace owns the Home shortcut. See `PagerKeyboard.cpp`'s matrix-legend comment for the one documented edge case (Alt+Shift+O or Alt+Shift+L all three held phantom-ghosts a stray 'q'/'a' — a diode-less-matrix limitation, not a bug, and not the @@ -751,7 +751,7 @@ existing boards. Notes: | Accent-variant popup keyboard nav | Fn+Space arms it; encoder walks variants; encoder click/Enter confirms; Backspace cancels (`s_accentnav_active`/`accentNavRestyle()`/`accentNavConfirm()`) | medium | done | | @-mention picker keyboard nav | Auto-arms the instant the list appears (no Fn+Space needed); same encoder walk/confirm/cancel as the accent popup (`s_mentionnav_active`/`mentionNavRestyle()`/`mentionNavConfirm()`) | medium | done | | Encoder short click on a focused bubble | Mirrors keyboard Enter — opens the same action menu instead of a plain ENTER a bubble doesn't react to | small | done | -| Fn+Shift chord effect | Toggles Caps Lock while editing a text field; jumps to Home (`navGoToMainTab`) everywhere else — `PagerKeyboard.cpp` only reports the chord, `UITask.cpp` decides the effect | small | done | +| Fn+Shift chord effect | Toggles Caps Lock while editing a text field; no-op everywhere else. Fn+Backspace jumps Home — `PagerKeyboard.cpp` only reports the chords, `UITask.cpp` decides the effects | small | done | | Map pan (WASD) + slider nudge (Q/E) | WASD pans the Map tab (`mapNudge()`, shared with Tanmatsu's Ctrl+Arrow); Q/E adjust a focused slider (moved off D/F to avoid colliding with WASD) | small | done | | App-drawer tile focus highlight | `NAV_ACCENTFOCUS_FLAG` makes `navFocusCb` use the tile's own accent tint instead of the generic white reverse-fill, on every board | small | done | | SX1262-variant env | `tlora_pager_sx1262_companion_radio_touch` — same board/pins, `CustomSX1262`/`CustomSX1262Wrapper` instead of the LR1121 classes | medium | done (worklist ⑩) | diff --git a/TLORA_PAGER_SHORTCUTS.md b/TLORA_PAGER_SHORTCUTS.md index 0b4abe3..3519edf 100644 --- a/TLORA_PAGER_SHORTCUTS.md +++ b/TLORA_PAGER_SHORTCUTS.md @@ -40,7 +40,7 @@ while editing a text field, where the keys type normally. | Gesture | Action | Keyboard equivalent | |---|---|---| -| Turn | Move focus to the next/previous item on screen | **Fn (Alt) tapped alone** moves forward one step (NEXT only — no keyboard way to go backward) | +| Turn | Move focus to the next/previous item on screen | none — encoder only | | Short click | Select / confirm the focused item | **Enter** | | Hold ~1 s, then release | **Back**: closes a popup → closes an open chat → goes Home → Esc (whichever applies first) | **Backspace held ~1 s** | | **Fn (Alt) + turn**, on a main tab | Move between the 5 main tabs (Mail / Contacts / Home / Map / Settings) | **M / C / H / A / S** jumps directly | @@ -93,29 +93,19 @@ text box → Send**, in that order, in both directions — nothing is skipped. Turning past the △ chip (toward the messages) always jumps straight to the newest message, regardless of channel or DM. -### Backspace and Fn (Alt) — leaving vs. catching up +### Backspace — catching up -These two keys are your shortcuts in and out of "reading mode" on this -screen, and they do different things depending on whether you've got unread -messages: +**Backspace (tap)** jumps to whichever message needs your attention: -- **Fn (Alt) tapped alone** — jumps straight to the **newest** message and - moves focus into the text box, ready to type a reply. This is the - deliberate "I'm done reading, let me respond" gesture — it works regardless - of where your focus currently is in the chat. -- **Backspace (tap)** — jumps to whichever message needs your attention: - - If there are unread messages, it jumps to the first one — right below the - **"NEW ----"** divider — and selects it, so you can then turn forward - through your unread messages in order, oldest-of-the-unread first. - - If nothing is unread, it jumps to the newest message instead (same - destination as Fn+Alt, but leaves focus on the message itself rather than - the text box). +- If there are unread messages, it jumps to the first one — right below the + **"NEW ----"** divider — and selects it, so you can then turn forward + through your unread messages in order, oldest-of-the-unread first. +- If nothing is unread, it jumps to the newest message instead (same + destination, with focus left on the message). Backspace's override above only applies while you're inside an open chat and *not* actively editing the text box — the usual rule from the top of this guide; with a field focused, Backspace deletes a character as normal. -Fn (Alt) tap's override fires the same way whether or not the text box -already has focus, since landing there is the whole point of the gesture. ## Keyboard layout @@ -128,7 +118,9 @@ a s d f g h j k l [Enter] [Space] ``` -Hold **Fn (Alt)** for numbers/symbols instead: +Hold **Fn (Alt)** for numbers/symbols, or tap it once to apply this layer to +the next key only. Double-tap Fn to lock the symbol layer; tap it again to +return to letters. ``` 1 2 3 4 5 6 7 8 9 0 @@ -162,7 +154,7 @@ Hold **Fn (Alt)** for numbers/symbols instead: | **Space** (tap) | Types a space | — | | **Space** (double-tap, within 250 ms) | Switches between English and your configured secondary keyboard layout | — | | **Space** (hold ~1 s) | — | Locks the screen (shows a "Locking…" progress bar; tapping any key cancels) | -| **Fn (Alt)** tapped alone (press+release, nothing else) | — | Moves focus to the next field/item — a keyboard-only substitute for a turn of the encoder. In an open chat: jumps to the newest message and focuses the text box instead — see [Chat screen](#chat-screen) | +| **Fn (Alt)** (tap / double-tap) | Next key uses symbols / lock symbols until tapped again | Same | The **BOOT** button (top of the device) instantly wakes the screen from idle-dim. It does *not* unlock a screen you've manually locked with the @@ -249,13 +241,14 @@ that changes keyboard language. | Input | Action | |---|---| | M / C / H / A / S (top-level main screens only) | Open Mail / Contacts / Home / Map / Settings | -| Turn encoder (or Fn tap = NEXT only) | Move focus | +| Turn encoder | Move focus | | Turn, at the loaded edge of a chat | Load more history, keep moving — only exits the list at the true oldest/newest message | | Click encoder (or Enter) | Select / confirm | | Hold encoder ~1s (or hold Backspace ~1s) | Back | | Fn + turn (main tab) | Switch tabs | | Fn + turn (page/chat) | Scroll | -| Fn tap alone | Next field (in a chat: jump to newest message + focus the text box) | +| Fn tap alone | Use the symbol layer for the next key | +| Fn double-tap | Lock the symbol layer; tap Fn again to unlock | | Hold Shift + letter | Momentary uppercase | | Fn + Shift (editing a field) | Toggle Caps Lock | | Fn + Shift (not editing a field) | Nothing | diff --git a/deploy/apps/README.md b/deploy/apps/README.md index 6e9b046..751dcfb 100644 --- a/deploy/apps/README.md +++ b/deploy/apps/README.md @@ -16,8 +16,10 @@ One Lua file plus a small manifest. Apps talk to the firmware through the `wada. API — `wada.ui` (widgets, colours, a text prompt), `wada.sys`, `wada.store` (persistence), `wada.timer`, and on the larger boards `wada.fs`, `wada.net`, `wada.crypto` and the writable half of `wada.mesh`. Supported boards also expose -read-only SD directory metadata through `wada.sd`; file contents and writes stay -inaccessible. There is no general-purpose filesystem or network access; the API +asynchronous WAV/MP3 playback through `wada.audio`; plain filenames come from the +app sandbox on internal flash, SD, or SD_MMC. Read-only physical-SD directory +metadata is available through `wada.sd`, and direct card playback uses an explicit +`sd:/...` path. There is no general-purpose filesystem or network access; the API is the whole surface, which is what makes reviewing tractable. It is documented at [wadamesh.com/sdk.html](https://wadamesh.com/sdk.html). diff --git a/deploy/apps/apps.json b/deploy/apps/apps.json index ee2da03..9e6b97d 100644 --- a/deploy/apps/apps.json +++ b/deploy/apps/apps.json @@ -21,8 +21,8 @@ { "id": "sdktest", "name": "SDK Test", - "ver": "1.6", - "desc": "Developer tool. Checks the extended Lua SDK on this board: capabilities, clock, battery, GPS, private file access, read-only SD listing, crypto against published RFC vectors, channel discovery, and buttons that TRANSMIT test messages." + "ver": "1.7", + "desc": "Developer tool. Checks the extended Lua SDK on this board: capabilities, clock, battery, GPS, private file access, audio API, read-only SD listing, crypto against published RFC vectors, channel discovery, and buttons that TRANSMIT test messages." }, { "id": "2048", @@ -33,14 +33,16 @@ { "id": "wardrive", "name": "Wardrive", - "ver": "1.0", - "desc": "LoRa coverage survey. Probes every 20s and logs each reply with GPS position, altitude and BOTH link directions (how well you heard them, how well they heard you) to a CSV. Reference app for wada.mesh.discover." + "ver": "1.1", + "desc": "LoRa coverage survey. Probes every 20s and logs each reply with GPS position, altitude and BOTH link directions (how well you heard them, how well they heard you) to a CSV. Reference app for wada.mesh.discover.", + "requires": "sdk_ext" }, { "id": "nearby", "name": "Nearby", "ver": "1.0", - "desc": "Your contacts on a real map, sorted by distance, with bearing and a live frame counter. Reference app for wada.map, wada.ui.list, wada.geo and app.on_packet." + "desc": "Your contacts on a real map, sorted by distance, with bearing and a live frame counter. Reference app for wada.map, wada.ui.list, wada.geo and app.on_packet.", + "requires": "sdk_ext" }, { "id": "gpscompass", diff --git a/deploy/apps/lang/18/bg.lang b/deploy/apps/lang/21/bg.lang similarity index 97% rename from deploy/apps/lang/18/bg.lang rename to deploy/apps/lang/21/bg.lang index 92bcace..cca93b6 100644 --- a/deploy/apps/lang/18/bg.lang +++ b/deploy/apps/lang/21/bg.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: bg -# ver: 18 +# ver: 21 # name: Български # base: bg (device behind) (устройството изостава) @@ -184,6 +184,7 @@ Contact added Контактът е добавен Contact deleted Контактът е изтрит Contact gone Контактът изчезна Contact missing Контактът липсва +Contact shared Контактът е споделен Contacts Контакти Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контактите са във вътрешната памет - SD картата не се монтира при старт. Постави картата отново и рестартирай. Contacts are on internal flash. Контактите са във вътрешната памет. @@ -778,6 +779,8 @@ Settings Настройки Setup complete Настройката е готова Share QR Сподели QR Share channel Сподели канала +Share contact Сподели контакт +Share failed Споделянето неуспешно Share location in advert Споделяй местоположението в advert Share secret Сподели ключа Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Споделете 32-символната тайна, за да се присъединят други. Празно = случайна. @@ -826,7 +829,7 @@ TCP on TCP вкл TOUCH BETA TOUCH BETA TX TX Tab hotkeys — tap a row, then press a key Клавиши за раздела — докосни ред, после натисни клавиш -Tap Use to switch - the device reboots to apply. Натиснете „Избери“, за да превключите — устройството ще се рестартира. +Tap Use to switch - the device reboots to apply. Натиснете "Избери", за да превключите — устройството ще се рестартира. Tap Use to switch - the device reboots to apply. Language files live in /lang on the storage; edit them or add your own. Докосни «Избери» за смяна - устройството се рестартира. Езиковите файлове са в /lang в паметта; редактирай ги или добави свои. Tap a language; the device reboots to apply. Изберете език; устройството ще се рестартира. Taste the rainbow! Вкуси дъгата! @@ -977,8 +980,6 @@ tap to exit full screen докоснете за изход от цял екра zoom мащаб zoom %d мащаб %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. усилвател ~17 dB за тихи/отдалечени места; изключи в шумни. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/de.lang b/deploy/apps/lang/21/de.lang similarity index 97% rename from deploy/apps/lang/18/de.lang rename to deploy/apps/lang/21/de.lang index 60d5b56..58690f9 100644 --- a/deploy/apps/lang/18/de.lang +++ b/deploy/apps/lang/21/de.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: de -# ver: 18 +# ver: 21 # name: Deutsch # base: de (device behind) (Gerät geht nach) @@ -184,6 +184,7 @@ Contact added Kontakt hinzugefügt Contact deleted Kontakt gelöscht Contact gone Kontakt weg Contact missing Kontakt fehlt +Contact shared Kontakt geteilt Contacts Kontakte Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Kontakte liegen im internen Flash - die SD-Karte wurde beim Start nicht eingebunden. Karte neu einsetzen und neu starten. Contacts are on internal flash. Kontakte liegen im internen Flash. @@ -452,7 +453,6 @@ Login OK (perms %u) Anmeldung OK (Rechte %u) Login failed Anmeldung fehlgeschlagen Logs Protokolle Longitude Längengrad -Lua Store Lua Store MHz MHz MQTT bridge MQTT-Brücke Map Karte @@ -694,7 +694,7 @@ SD card remounted SD-Karte neu eingebunden SD card removed SD-Karte entfernt SD data is unavailable - contacts and channels cannot be saved until the card is reinserted. SD-Daten nicht verfügbar – Kontakte und Kanäle können erst nach Einsetzen der Karte gespeichert werden. SD data is unavailable - identity, settings, contacts and channels cannot be saved until the card is reinserted. SD-Daten nicht verfügbar – Identität, Einstellungen, Kontakte und Kanäle können erst nach Einsetzen der Karte gespeichert werden. -SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. SD-Datenübertragung unvollständig. Identität und Einstellungen bleiben intern; „Interne Daten auf SD kopieren“ zum erneuten Versuch verwenden. +SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. SD-Datenübertragung unvollständig. Identität und Einstellungen bleiben intern; "Interne Daten auf SD kopieren" zum erneuten Versuch verwenden. SD download failed: %s SD-Download fehlgeschlagen: %s SD formatted - %s (MESHCOMOD) SD formatiert - %s (MESHCOMOD) SD is busy - close tools and retry SD ist belegt – Tools schließen und erneut versuchen @@ -778,6 +778,8 @@ Settings Einstellungen Setup complete Einrichtung abgeschlossen Share QR QR teilen Share channel Kanal teilen +Share contact Kontakt teilen +Share failed Teilen fehlgeschlagen Share location in advert Standort im Advert teilen Share secret Geheimnis teilen Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Teilen Sie das 32-Zeichen-Geheimnis, damit andere beitreten. Leer lassen für ein zufälliges. @@ -797,7 +799,6 @@ Sleep ready Bereit zum Schlafen Slot %d cleared Slot %d gelöscht Slot empty Slot leer Small\nMedium\nLarge Klein\nMittel\nGroß -Snake Snake Snake — swipe or roll the trackball Snake — wischen oder Trackball rollen Sort Sortieren Sound Ton @@ -805,7 +806,6 @@ Sound off Ton aus Sound on Ton ein Sound: %s Ton: %s Start time Startzeit -Status Status Step 1 of 3 Schritt 1 von 3 Step 2 of 3 Schritt 2 von 3 Step 3 of 3 Schritt 3 von 3 @@ -818,7 +818,6 @@ Streams the device screen as a live picture you tap to control. Heavier; the pan Switch Wechseln Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot. Auf die externe Antenne wechseln?\n\nErst sicherstellen, dass wirklich eine Antenne an der Buchse steckt. Senden ohne Antenne kann das Funkmodul beschädigen.\n\nFällt bei jedem Neustart auf die interne Antenne zurück. Sync clock from system Uhr synchronisieren -System System System info Systeminfo TCP %s BLE %s\nWS clients %d GPS %s Buzzer %s TCP %s BLE %s\nWS-Clients %d GPS %s Summer %s TCP off TCP aus @@ -977,8 +976,6 @@ tap to exit full screen tippen zum Verlassen des Vollbilds zoom Zoom zoom %d Zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ~17 dB Verstärker für ruhige/abgelegene Gebiete; in lauten Zonen aus. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +997,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1010,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1036,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1044,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1053,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1065,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1082,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/el.lang b/deploy/apps/lang/21/el.lang similarity index 97% rename from deploy/apps/lang/18/el.lang rename to deploy/apps/lang/21/el.lang index 203ba0b..44c66c8 100644 --- a/deploy/apps/lang/18/el.lang +++ b/deploy/apps/lang/21/el.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: el -# ver: 18 +# ver: 21 # name: Ελληνικά # base: el (device behind) (συσκευή πίσω) @@ -184,6 +184,7 @@ Contact added Η επαφή προστέθηκε Contact deleted Η επαφή διαγράφηκε Contact gone Η επαφή χάθηκε Contact missing Η επαφή λείπει +Contact shared Η επαφή κοινοποιήθηκε Contacts Επαφές Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Οι επαφές είναι στην εσωτερική μνήμη - η κάρτα SD δεν προσαρτήθηκε στην εκκίνηση. Επανατοποθετήστε την και επανεκκινήστε. Contacts are on internal flash. Οι επαφές είναι στην εσωτερική μνήμη. @@ -778,6 +779,8 @@ Settings Ρυθμίσεις Setup complete Η ρύθμιση ολοκληρώθηκε Share QR Κοινοποίηση QR Share channel Κοινή χρήση καναλιού +Share contact Κοινοποίηση επαφής +Share failed Αποτυχία κοινοποίησης Share location in advert Κοινή χρήση θέσης στο advert Share secret Κοινοποίηση μυστικού Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Μοιραστείτε το μυστικό 32 χαρακτήρων για να συμμετάσχουν άλλοι. Κενό = τυχαίο. @@ -977,8 +980,6 @@ tap to exit full screen πατήστε για έξοδο από πλήρη οθ zoom ζουμ zoom %d ζουμ %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ενισχυτής ~17 dB για ήσυχες/απομακρυσμένες περιοχές· κλείστε σε θορυβώδεις. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/es.lang b/deploy/apps/lang/21/es.lang similarity index 97% rename from deploy/apps/lang/18/es.lang rename to deploy/apps/lang/21/es.lang index fe56063..c7b8bab 100644 --- a/deploy/apps/lang/18/es.lang +++ b/deploy/apps/lang/21/es.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: es -# ver: 18 +# ver: 21 # name: Español # base: es (device behind) (dispositivo atrasado) @@ -184,6 +184,7 @@ Contact added Contacto añadido Contact deleted Contacto eliminado Contact gone Contacto perdido Contact missing Falta el contacto +Contact shared Contacto compartido Contacts Contactos Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Los contactos están en memoria interna - la tarjeta SD no se montó al arrancar. Reinserta la tarjeta y reinicia. Contacts are on internal flash. Los contactos están en la memoria interna. @@ -778,6 +779,8 @@ Settings Ajustes Setup complete Configuración completa Share QR Compartir QR Share channel Compartir canal +Share contact Compartir contacto +Share failed Error al compartir Share location in advert Compartir ubicación en anuncio Share secret Compartir secreto Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Comparte el secreto de 32 caracteres para que otros se unan. Déjalo vacío para uno aleatorio. @@ -977,8 +980,6 @@ tap to exit full screen toca para salir de pantalla completa zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. amplificador ~17 dB para zonas tranquilas/remotas; apaga en zonas ruidosas. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/fr.lang b/deploy/apps/lang/21/fr.lang similarity index 97% rename from deploy/apps/lang/18/fr.lang rename to deploy/apps/lang/21/fr.lang index 7d5a664..cb92be8 100644 --- a/deploy/apps/lang/18/fr.lang +++ b/deploy/apps/lang/21/fr.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: fr -# ver: 18 +# ver: 21 # name: Français # base: fr (device behind) (appareil en retard) @@ -184,6 +184,7 @@ Contact added Contact ajouté Contact deleted Contact supprimé Contact gone Contact perdu Contact missing Contact manquant +Contact shared Contact partagé Contacts Contacts Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Les contacts sont en mémoire interne - la carte SD ne s'est pas montée au démarrage. Réinsérez la carte et redémarrez. Contacts are on internal flash. Les contacts sont sur la mémoire interne. @@ -452,7 +453,6 @@ Login OK (perms %u) Connexion OK (perms %u) Login failed Échec de connexion Logs Journaux Longitude Longitude -Lua Store Lua Store MHz MHz MQTT bridge Pont MQTT Map Carte @@ -778,6 +778,8 @@ Settings Paramètres Setup complete Configuration terminée Share QR Partager le QR Share channel Partager le canal +Share contact Partager le contact +Share failed Échec du partage Share location in advert Partager la position dans l'annonce Share secret Partager le secret Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Partagez le secret de 32 caractères pour que d'autres rejoignent. Laissez vide pour un aléatoire. @@ -977,8 +979,6 @@ tap to exit full screen toucher pour quitter le plein écran zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ampli ~17 dB pour zones calmes/isolées ; désactiver en zone bruyante. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1000,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1013,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1039,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1047,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1056,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1068,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1085,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/hu.lang b/deploy/apps/lang/21/hu.lang similarity index 96% rename from deploy/apps/lang/18/hu.lang rename to deploy/apps/lang/21/hu.lang index 84dfac7..5f6dddd 100644 --- a/deploy/apps/lang/18/hu.lang +++ b/deploy/apps/lang/21/hu.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: hu -# ver: 18 +# ver: 21 # name: Magyar # base: hu (device behind) (készülék hátulján) @@ -186,6 +186,7 @@ Contact added Névjegy hozzáadva Contact deleted Névjegy törölve Contact gone Eltűnt névjegy Contact missing Hiányzó névjegy +Contact shared Névjegy megosztva Contacts Névjegyek Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. A névjegyek a belső tárolón vannak - az SD-kártya nem csatolódott induláskor. Helyezd be újra a kártyát, és indítsd újra. Contacts are on internal flash. A névjegyek a belső tárolón vannak. @@ -400,7 +401,7 @@ Join a private channel Belépés priváthoz Join hashtag channel Csatlakozz # csatornához Join network Csatlakozás a hálózathoz Join private channel Csatlakozz privát csatornához -Join the public channel Csatlakozás a nyilvános csatornához +Join the public channel Belépés a nyilvánoshoz Joined %.40s Csatlakozott %.40s alatt Keep per chat (messages) Megőrzés csevegésenként (üzenet) Key already in use Kulcs már hozzárendelve @@ -413,7 +414,7 @@ Keyboard nav: WASDZ on Billentyűzet navigáció: WASDZ bekapcsolva Keyboard nav: off Billentyűzetnavigáció: kikapcsolva Keyboard navigation Billentyűzetnavigáció Keys Kulcsok -Known regions Known regions +Known regions Ismert régiók LOS → %s Rálátás → %s Landscape (desktop) Fekvő (asztali) Landscape set - applies when remote mode starts. Fekvő beállítva - a távoli mód indulásakor lép életbe. @@ -471,7 +472,7 @@ Map — no tile pack on SPIFFS yet.\n\nUpload a tile pack to /tiles///. Map — set your location\nin Settings → Profile to\nshow the map here. Térkép – a Beállítások → Profil menüpontban állítsd be a tartózkodási helyedet, hogy itt jelenjen meg a térkép. Mark all chats and channels as read? Az összes csevegést és csatornát megjelölöd olvasottként? Mark as read Olvasottnak jelöl -Mark read Mark read +Mark read Olvasott Marked read Olvasottként megjelölve Max hops (0..64) Max ugrások (0-64) Max zoom for this pack Maximális zoom ehhez a csomaghoz @@ -703,7 +704,7 @@ SD card remounted SD kártya újracsatolva SD card removed SD-kártya eltávolítva SD data is unavailable - contacts and channels cannot be saved until the card is reinserted. Az SD-kártya adatai nem érhetők el – a névjegyek és a csatornák nem menthetők a kártya újbóli behelyezéséig. SD data is unavailable - identity, settings, contacts and channels cannot be saved until the card is reinserted. Az SD-kártya adatai nem érhetők el – az azonosító, a beállítások, a névjegyek és a csatornák nem menthetők a kártya újbóli behelyezéséig. -SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. Az SD-kártya adatainak áthelyezése nem teljes. Az azonosító és a beállítások továbbra is a belső tárhelyen vannak; a folytatáshoz használd a „Belső adatok másolása SD-kártyára” lehetőséget. +SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. Az SD-kártya adatainak áthelyezése nem teljes. Az azonosító és a beállítások továbbra is a belső tárhelyen vannak; a folytatáshoz használd a "Belső adatok másolása SD-kártyára" lehetőséget. SD download failed: %s SD-letöltés sikertelen: %s SD formatted - %s (MESHCOMOD) SD formázás - %s (MESHCOMOD) SD is busy - close tools and retry Az SD-kártya foglalt – zárd be az eszközöket, majd próbáld újra. @@ -791,6 +792,8 @@ Settings Beállítások Setup complete Beállítás kész Share QR QR megosztása Share channel Csatorna megosztása +Share contact Névjegy megosztása +Share failed Megosztás sikertelen Share location in advert Helyszín megosztása a hirdetésben Share secret Titok megosztása Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Oszd meg a 32 karakteres titkot, hogy mások is csatlakozhassanak. Hagyd üresen a titkot, hogy véletlenszerű titkos kódot generálj. @@ -812,7 +815,6 @@ Sleep ready Készen áll az alvásra Slot %d cleared %d hely kiürítve Slot empty Üres hely Small\nMedium\nLarge Kicsi\nKözepes\nNagy -Snake Snake Snake — swipe or roll the trackball Kígyó – pöccintsd vagy görgesd a görgetőgolyót Sort Sort Sound Hang @@ -897,7 +899,7 @@ Turn this on, then open the address below in any web browser on the same Wi-Fi - Type Tipus Type a URL, then Go Írj be egy URL-t, majd Mehet Type a message... Írj be egy üzenetet... -Type a new 6-digit code · applies after a reboot Írjon be egy új 6 jegyű kódot · újraindítás után érvényes +Type a new 6-digit code · applies after a reboot Írjon be egy 6 jegyű kódot · újraindítás után él Type your network name — or switch to Wi-Fi in Settings to scan Írd be a hálózatod nevét – vagy válts Wi-Fi-re a beállításokban a kereséshez UI size (restart to apply) UI mérete (újraindítás az alkalmazáshoz) UI size saved — restart to apply UI mérete mentve – indítsa újra a programot az alkalmazáshoz @@ -997,8 +999,6 @@ tap to exit full screen koppintson a teljes képernyős kilépéshez zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ~17 dB erősítővel csendes/távoli helyeken; zajos helyeken kapcsold ki. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope Hatókör another region másik régió my region saját régió @@ -1065,11 +1065,10 @@ sensors érzékelők Auto-add on for %s — new %s land in Contacts automatically. Automatikus hozzáadás bekapcsolva: %s — az új %s automatikusan a Névjegyek közé kerülnek. Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed under the Open Database License (ODbL).\n\n Térkép adatok © OpenStreetMap közreműködői.\nopenstreetmap.org/copyright\nAz Open Database License (ODbL) licenc alatt.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Térkép stílus © OpenTopoMap (CC-BY-SA) — opentopomap.org\nTérkép adatok © OpenStreetMap közreműködői (ODbL) + SRTM.\n\n -How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. A csempék működése:\nA térkép 256×256 képpontos „slippy” csempékből épül fel. Csak a megtekintett területhez szükséges csempék töltődnek le — nincs tömeges előzetes letöltés.\n\nMivel az eszköz nem támogatja a HTTPS-t (a Wi-Fi elindítása után nincs elegendő heap memória), és a JPEG képek dekódolása sokkal kevesebb erőforrást igényel, mint a PNG-é, a csempék a wadamesh proxyn keresztül érkeznek: a proxy HTTPS-en keresztül lekéri a forrásból a PNG-t egy azonosító User-Agent használatával, JPEG formátumba kódolja át, majd eltárolja a gyorsítótárban. Az eszköz ezután minden csempét a saját flash memóriájában is eltárol, így egy csempét csak egyszer kell letölteni.\n\nAz Options → Reload tiles lehetőséggel újra letöltheted a jelenleg megtekintett terület csempéit, ha valamelyik hibásan jelenik meg. +How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. A csempék működése:\nA térkép 256×256 képpontos "slippy" csempékből épül fel. Csak a megtekintett területhez szükséges csempék töltődnek le — nincs tömeges előzetes letöltés.\n\nMivel az eszköz nem támogatja a HTTPS-t (a Wi-Fi elindítása után nincs elegendő heap memória), és a JPEG képek dekódolása sokkal kevesebb erőforrást igényel, mint a PNG-é, a csempék a wadamesh proxyn keresztül érkeznek: a proxy HTTPS-en keresztül lekéri a forrásból a PNG-t egy azonosító User-Agent használatával, JPEG formátumba kódolja át, majd eltárolja a gyorsítótárban. Az eszköz ezután minden csempét a saját flash memóriájában is eltárol, így egy csempét csak egyszer kell letölteni.\n\nAz Options → Reload tiles lehetőséggel újra letöltheted a jelenleg megtekintett terület csempéit, ha valamelyik hibásan jelenik meg. "%s" wants to send discovery probes.\n\nEach probe asks every node in range to reply, so it uses airtime on the whole local mesh, not just yours.\n\nNothing is sent under your name and no message is transmitted. "%s" felfedezési probe-ok küldését kéri.\n\nMinden probe válaszra kéri a hatótávolságon belüli node-okat, ezért a teljes helyi mesh hálózat airtime-ját használja, nem csak a tiédet.\n\nSemmi sem kerül elküldésre a nevedben, és üzenet sem kerül továbbításra. ? ? Auth failed Auth failed -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Csak közvetlen (0-hop) @@ -1078,16 +1077,12 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Szöveg megadása Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... Link lost Link lost MESH MESH Name (A-Z) Név (A–Z) Nearest first Legközelebbi elöl -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Legutóbbi üzenet Reload tiles in view Csempék újratöltése Repeaters Repeaters @@ -1098,13 +1093,8 @@ Show contacts Névjegyek megjelenítése Show coordinates Koordináták Show tile z/x/y Csempe z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Csempe hiba keret -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite tap to cycle off / on / auto tap to cycle off / on / auto #7A7F87 Scanning… nothing has answered yet# #7A7F87 Scanning… nothing has answered yet# Export crash report (%uK) Hibajelentés exportálása (%uK) @@ -1116,3 +1106,27 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. A beta_%d telepítése?\nEz leminősíti a firmware-t és újraindul. +Other (hidden) network… Other (hidden) network… +Paused Paused +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal (stale) Jel (elavult) +nothing heard yet Még semmi hír. +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/it.lang b/deploy/apps/lang/21/it.lang similarity index 97% rename from deploy/apps/lang/18/it.lang rename to deploy/apps/lang/21/it.lang index e0350d1..f5cc517 100644 --- a/deploy/apps/lang/18/it.lang +++ b/deploy/apps/lang/21/it.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: it -# ver: 18 +# ver: 21 # name: Italiano # base: it (device behind) (dispositivo indietro) @@ -184,6 +184,7 @@ Contact added Contatto aggiunto Contact deleted Contatto eliminato Contact gone Contatto perso Contact missing Contatto mancante +Contact shared Contatto condiviso Contacts Contatti Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. I contatti sono sulla memoria interna - la scheda SD non si è montata all'avvio. Reinserisci la scheda e riavvia. Contacts are on internal flash. I contatti sono sulla memoria interna. @@ -452,7 +453,6 @@ Login OK (perms %u) Accesso OK (permessi %u) Login failed Accesso non riuscito Logs Log Longitude Longitudine -Lua Store Lua Store MHz MHz MQTT bridge Ponte MQTT Map Mappa @@ -778,6 +778,8 @@ Settings Impostazioni Setup complete Configurazione completata Share QR Condividi QR Share channel Condividi canale +Share contact Condividi contatto +Share failed Condivisione non riuscita Share location in advert Condividi posizione in advert Share secret Condividi segreto Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Condividi il segreto di 32 caratteri per far unire altri. Lascia vuoto per uno casuale. @@ -977,8 +979,6 @@ tap to exit full screen tocca per uscire da schermo intero zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ampli ~17 dB per zone tranquille/remote; spegni in zone rumorose. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1000,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1013,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1039,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1047,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1056,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1068,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1085,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/nl.lang b/deploy/apps/lang/21/nl.lang similarity index 97% rename from deploy/apps/lang/18/nl.lang rename to deploy/apps/lang/21/nl.lang index a7f4f93..a2f82b6 100644 --- a/deploy/apps/lang/18/nl.lang +++ b/deploy/apps/lang/21/nl.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: nl -# ver: 18 +# ver: 21 # name: Nederlands # base: nl (device behind) (apparaat loopt achter) @@ -184,6 +184,7 @@ Contact added Contact toegevoegd Contact deleted Contact verwijderd Contact gone Contact weg Contact missing Contact ontbreekt +Contact shared Contact gedeeld Contacts Contacten Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Contacten staan op intern flash - de SD-kaart is bij het opstarten niet gekoppeld. Plaats de kaart opnieuw en herstart. Contacts are on internal flash. Contacten staan op intern flashgeheugen. @@ -452,7 +453,6 @@ Login OK (perms %u) Inloggen OK (rechten %u) Login failed Inloggen mislukt Logs Logboeken Longitude Lengtegraad -Lua Store Lua Store MHz MHz MQTT bridge MQTT-brug Map Kaart @@ -778,6 +778,8 @@ Settings Instellingen Setup complete Installatie voltooid Share QR QR delen Share channel Kanaal delen +Share contact Contact delen +Share failed Delen mislukt Share location in advert Locatie delen in advert Share secret Geheim delen Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Deel het 32-teken geheim zodat anderen kunnen deelnemen. Leeg laten voor een willekeurig geheim. @@ -797,7 +799,6 @@ Sleep ready Klaar voor slaap Slot %d cleared Slot %d gewist Slot empty Slot leeg Small\nMedium\nLarge Klein\nMiddel\nGroot -Snake Snake Snake — swipe or roll the trackball Snake — veeg of rol de trackball Sort Sorteer Sound Geluid @@ -805,7 +806,6 @@ Sound off Geluid uit Sound on Geluid aan Sound: %s Geluid: %s Start time Starttijd -Status Status Step 1 of 3 Stap 1 van 3 Step 2 of 3 Stap 2 van 3 Step 3 of 3 Stap 3 van 3 @@ -977,8 +977,6 @@ tap to exit full screen tik om volledig scherm te verlaten zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ~17 dB versterker voor stille/afgelegen gebieden; uit in drukke plekken. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +998,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1011,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1037,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1045,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1054,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1066,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1083,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/pt-br.lang b/deploy/apps/lang/21/pt-br.lang similarity index 97% rename from deploy/apps/lang/18/pt-br.lang rename to deploy/apps/lang/21/pt-br.lang index e39cb21..cb0a884 100644 --- a/deploy/apps/lang/18/pt-br.lang +++ b/deploy/apps/lang/21/pt-br.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: pt-br -# ver: 18 +# ver: 21 # name: Português (BR) # base: pt-br (device behind) (dispositivo atrasado) @@ -184,6 +184,7 @@ Contact added Contato adicionado Contact deleted Contato excluído Contact gone Contato sumiu Contact missing Contato ausente +Contact shared Contato compartilhado Contacts Contatos Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Os contatos estão na memória interna - o cartão SD não montou na inicialização. Recoloque o cartão e reinicie. Contacts are on internal flash. Os contatos estão na memória interna. @@ -778,6 +779,8 @@ Settings Ajustes Setup complete Configuração concluída Share QR Compartilhar QR Share channel Compartilhar canal +Share contact Compartilhar contato +Share failed Falha ao compartilhar Share location in advert Compartilhar local no advert Share secret Compartilhar segredo Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Compartilhe o segredo de 32 caracteres para outros entrarem. Deixe vazio para gerar um aleatório. @@ -805,7 +808,6 @@ Sound off Som desligado Sound on Som ligado Sound: %s Som: %s Start time Hora de início -Status Status Step 1 of 3 Passo 1 de 3 Step 2 of 3 Passo 2 de 3 Step 3 of 3 Passo 3 de 3 @@ -977,8 +979,6 @@ tap to exit full screen toque para sair da tela cheia zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. amplificador ~17 dB para áreas silenciosas/remotas; desligue em locais ruidosos. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1000,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1013,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1039,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1047,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1056,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1068,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1085,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/ro.lang b/deploy/apps/lang/21/ro.lang similarity index 97% rename from deploy/apps/lang/18/ro.lang rename to deploy/apps/lang/21/ro.lang index 6967b9d..6f56119 100644 --- a/deploy/apps/lang/18/ro.lang +++ b/deploy/apps/lang/21/ro.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: ro -# ver: 18 +# ver: 21 # name: Română # base: ro (device behind) (dispozitiv în urmă) @@ -184,6 +184,7 @@ Contact added Contact adăugat Contact deleted Contact şters Contact gone Contact dispărut Contact missing Contact lipsă +Contact shared Contact partajat Contacts Contacte Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Contactele sunt pe memoria internă - cardul SD nu s-a montat la pornire. Reaşază cardul şi reporneşte. Contacts are on internal flash. Contactele sunt pe memoria internă. @@ -778,6 +779,8 @@ Settings Setări Setup complete Configurare finalizată Share QR Partajează QR Share channel Partajează canalul +Share contact Partajează contactul +Share failed Partajare eşuată Share location in advert Partajează locaţia în advert Share secret Partajează secretul Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Partajează secretul de 32 caractere ca să poată intra şi alţii. Lasă secretul gol pentru a genera unul aleatoriu. @@ -978,7 +981,6 @@ zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. amplificator ~17 dB pentru zone liniştite/izolate; opreşte-l în locuri zgomotoase. © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1002,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1015,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1041,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1049,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1058,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1070,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1087,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/ru.lang b/deploy/apps/lang/21/ru.lang similarity index 97% rename from deploy/apps/lang/18/ru.lang rename to deploy/apps/lang/21/ru.lang index ceb1ec3..8c2f272 100644 --- a/deploy/apps/lang/18/ru.lang +++ b/deploy/apps/lang/21/ru.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: ru -# ver: 18 +# ver: 21 # name: Русский # base: ru (device behind) (устройство отстаёт) @@ -184,6 +184,7 @@ Contact added Контакт добавлен Contact deleted Контакт удалён Contact gone Контакт пропал Contact missing Контакт отсутствует +Contact shared Контакт отправлен Contacts Контакты Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакты во внутренней памяти - SD-карта не смонтировалась при загрузке. Переустановите карту и перезагрузитесь. Contacts are on internal flash. Контакты во внутренней памяти. @@ -778,6 +779,8 @@ Settings Настройки Setup complete Настройка завершена Share QR Поделиться QR Share channel Поделиться каналом +Share contact Поделиться контактом +Share failed Не удалось отправить контакт Share location in advert Делиться местоположением в advert Share secret Поделиться ключом Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поделитесь секретом из 32 символов, чтобы другие присоединились. Пусто = случайный. @@ -977,8 +980,6 @@ tap to exit full screen нажмите для выхода из полноэкр zoom масштаб zoom %d масштаб %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. усилитель ~17 дБ для тихих/удалённых мест; выключайте в шумных. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/sr.lang b/deploy/apps/lang/21/sr.lang similarity index 97% rename from deploy/apps/lang/18/sr.lang rename to deploy/apps/lang/21/sr.lang index 0aab3e1..8e7267b 100644 --- a/deploy/apps/lang/18/sr.lang +++ b/deploy/apps/lang/21/sr.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: sr -# ver: 18 +# ver: 21 # name: Српски # base: sr (device behind) (уређај касни) @@ -184,6 +184,7 @@ Contact added Контакт додат Contact deleted Контакт обрисан Contact gone Контакт нестао Contact missing Контакт недостаје +Contact shared Контакт подељен Contacts Контакти Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакти су у унутрашњој меморији - SD картица се није монтирала при покретању. Поново убаци картицу и рестартуј. Contacts are on internal flash. Контакти су у унутрашњој меморији. @@ -778,6 +779,8 @@ Settings Подешавања Setup complete Подешавање завршено Share QR Подели QR Share channel Подели канал +Share contact Подели контакт +Share failed Дељење није успело Share location in advert Дели локацију у advert-у Share secret Подели тајну Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поделите тајну од 32 знака да се други придруже. Празно = насумична. @@ -826,7 +829,7 @@ TCP on TCP укљ TOUCH BETA TOUCH BETA TX TX Tab hotkeys — tap a row, then press a key Пречице картице — додирни ред, па притисни тастер -Tap Use to switch - the device reboots to apply. Додирните „Користи“ да промените — уређај ће се поново покренути. +Tap Use to switch - the device reboots to apply. Додирните "Користи" да промените — уређај ће се поново покренути. Tap Use to switch - the device reboots to apply. Language files live in /lang on the storage; edit them or add your own. Додирни «Користи» за промену - уређај се поново покреће. Датотеке језика су у /lang на меморији; уреди их или додај своје. Tap a language; the device reboots to apply. Изаберите језик; уређај ће се рестартовати. Taste the rainbow! Окуси дугу! @@ -977,8 +980,6 @@ tap to exit full screen додирните за излаз из целог ек zoom зум zoom %d зум %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. појачало ~17 dB за тиха/удаљена места; искључи у бучним. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/18/uk.lang b/deploy/apps/lang/21/uk.lang similarity index 97% rename from deploy/apps/lang/18/uk.lang rename to deploy/apps/lang/21/uk.lang index 4ebd00f..10d5f67 100644 --- a/deploy/apps/lang/18/uk.lang +++ b/deploy/apps/lang/21/uk.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: uk -# ver: 18 +# ver: 21 # name: Українська # base: uk (device behind) (пристрій відстає) @@ -184,6 +184,7 @@ Contact added Контакт додано Contact deleted Контакт видалено Contact gone Контакт зник Contact missing Контакт відсутній +Contact shared Контакт надіслано Contacts Контакти Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакти у внутрішній пам'яті - SD-карта не змонтувалася під час завантаження. Переставте картку і перезавантажте. Contacts are on internal flash. Контакти у внутрішній пам'яті. @@ -778,6 +779,8 @@ Settings Налаштування Setup complete Налаштування завершено Share QR Поділитися QR Share channel Поділитися каналом +Share contact Поділитися контактом +Share failed Не вдалося надіслати контакт Share location in advert Ділитися місцезнаходженням в advert Share secret Поділитися ключем Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поділіться секретом із 32 символів, щоб інші приєдналися. Порожньо = випадковий. @@ -977,8 +980,6 @@ tap to exit full screen торкніться, щоб вийти з повное zoom масштаб zoom %d масштаб %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. підсилювач ~17 дБ для тихих/віддалених місць; вимикайте в галасливих. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/bg.lang b/deploy/apps/lang/bg.lang index 92bcace..cca93b6 100644 --- a/deploy/apps/lang/bg.lang +++ b/deploy/apps/lang/bg.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: bg -# ver: 18 +# ver: 21 # name: Български # base: bg (device behind) (устройството изостава) @@ -184,6 +184,7 @@ Contact added Контактът е добавен Contact deleted Контактът е изтрит Contact gone Контактът изчезна Contact missing Контактът липсва +Contact shared Контактът е споделен Contacts Контакти Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контактите са във вътрешната памет - SD картата не се монтира при старт. Постави картата отново и рестартирай. Contacts are on internal flash. Контактите са във вътрешната памет. @@ -778,6 +779,8 @@ Settings Настройки Setup complete Настройката е готова Share QR Сподели QR Share channel Сподели канала +Share contact Сподели контакт +Share failed Споделянето неуспешно Share location in advert Споделяй местоположението в advert Share secret Сподели ключа Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Споделете 32-символната тайна, за да се присъединят други. Празно = случайна. @@ -826,7 +829,7 @@ TCP on TCP вкл TOUCH BETA TOUCH BETA TX TX Tab hotkeys — tap a row, then press a key Клавиши за раздела — докосни ред, после натисни клавиш -Tap Use to switch - the device reboots to apply. Натиснете „Избери“, за да превключите — устройството ще се рестартира. +Tap Use to switch - the device reboots to apply. Натиснете "Избери", за да превключите — устройството ще се рестартира. Tap Use to switch - the device reboots to apply. Language files live in /lang on the storage; edit them or add your own. Докосни «Избери» за смяна - устройството се рестартира. Езиковите файлове са в /lang в паметта; редактирай ги или добави свои. Tap a language; the device reboots to apply. Изберете език; устройството ще се рестартира. Taste the rainbow! Вкуси дъгата! @@ -977,8 +980,6 @@ tap to exit full screen докоснете за изход от цял екра zoom мащаб zoom %d мащаб %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. усилвател ~17 dB за тихи/отдалечени места; изключи в шумни. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/de.lang b/deploy/apps/lang/de.lang index 60d5b56..58690f9 100644 --- a/deploy/apps/lang/de.lang +++ b/deploy/apps/lang/de.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: de -# ver: 18 +# ver: 21 # name: Deutsch # base: de (device behind) (Gerät geht nach) @@ -184,6 +184,7 @@ Contact added Kontakt hinzugefügt Contact deleted Kontakt gelöscht Contact gone Kontakt weg Contact missing Kontakt fehlt +Contact shared Kontakt geteilt Contacts Kontakte Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Kontakte liegen im internen Flash - die SD-Karte wurde beim Start nicht eingebunden. Karte neu einsetzen und neu starten. Contacts are on internal flash. Kontakte liegen im internen Flash. @@ -452,7 +453,6 @@ Login OK (perms %u) Anmeldung OK (Rechte %u) Login failed Anmeldung fehlgeschlagen Logs Protokolle Longitude Längengrad -Lua Store Lua Store MHz MHz MQTT bridge MQTT-Brücke Map Karte @@ -694,7 +694,7 @@ SD card remounted SD-Karte neu eingebunden SD card removed SD-Karte entfernt SD data is unavailable - contacts and channels cannot be saved until the card is reinserted. SD-Daten nicht verfügbar – Kontakte und Kanäle können erst nach Einsetzen der Karte gespeichert werden. SD data is unavailable - identity, settings, contacts and channels cannot be saved until the card is reinserted. SD-Daten nicht verfügbar – Identität, Einstellungen, Kontakte und Kanäle können erst nach Einsetzen der Karte gespeichert werden. -SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. SD-Datenübertragung unvollständig. Identität und Einstellungen bleiben intern; „Interne Daten auf SD kopieren“ zum erneuten Versuch verwenden. +SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. SD-Datenübertragung unvollständig. Identität und Einstellungen bleiben intern; "Interne Daten auf SD kopieren" zum erneuten Versuch verwenden. SD download failed: %s SD-Download fehlgeschlagen: %s SD formatted - %s (MESHCOMOD) SD formatiert - %s (MESHCOMOD) SD is busy - close tools and retry SD ist belegt – Tools schließen und erneut versuchen @@ -778,6 +778,8 @@ Settings Einstellungen Setup complete Einrichtung abgeschlossen Share QR QR teilen Share channel Kanal teilen +Share contact Kontakt teilen +Share failed Teilen fehlgeschlagen Share location in advert Standort im Advert teilen Share secret Geheimnis teilen Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Teilen Sie das 32-Zeichen-Geheimnis, damit andere beitreten. Leer lassen für ein zufälliges. @@ -797,7 +799,6 @@ Sleep ready Bereit zum Schlafen Slot %d cleared Slot %d gelöscht Slot empty Slot leer Small\nMedium\nLarge Klein\nMittel\nGroß -Snake Snake Snake — swipe or roll the trackball Snake — wischen oder Trackball rollen Sort Sortieren Sound Ton @@ -805,7 +806,6 @@ Sound off Ton aus Sound on Ton ein Sound: %s Ton: %s Start time Startzeit -Status Status Step 1 of 3 Schritt 1 von 3 Step 2 of 3 Schritt 2 von 3 Step 3 of 3 Schritt 3 von 3 @@ -818,7 +818,6 @@ Streams the device screen as a live picture you tap to control. Heavier; the pan Switch Wechseln Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot. Auf die externe Antenne wechseln?\n\nErst sicherstellen, dass wirklich eine Antenne an der Buchse steckt. Senden ohne Antenne kann das Funkmodul beschädigen.\n\nFällt bei jedem Neustart auf die interne Antenne zurück. Sync clock from system Uhr synchronisieren -System System System info Systeminfo TCP %s BLE %s\nWS clients %d GPS %s Buzzer %s TCP %s BLE %s\nWS-Clients %d GPS %s Summer %s TCP off TCP aus @@ -977,8 +976,6 @@ tap to exit full screen tippen zum Verlassen des Vollbilds zoom Zoom zoom %d Zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ~17 dB Verstärker für ruhige/abgelegene Gebiete; in lauten Zonen aus. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +997,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1010,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1036,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1044,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1053,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1065,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1082,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/el.lang b/deploy/apps/lang/el.lang index 203ba0b..44c66c8 100644 --- a/deploy/apps/lang/el.lang +++ b/deploy/apps/lang/el.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: el -# ver: 18 +# ver: 21 # name: Ελληνικά # base: el (device behind) (συσκευή πίσω) @@ -184,6 +184,7 @@ Contact added Η επαφή προστέθηκε Contact deleted Η επαφή διαγράφηκε Contact gone Η επαφή χάθηκε Contact missing Η επαφή λείπει +Contact shared Η επαφή κοινοποιήθηκε Contacts Επαφές Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Οι επαφές είναι στην εσωτερική μνήμη - η κάρτα SD δεν προσαρτήθηκε στην εκκίνηση. Επανατοποθετήστε την και επανεκκινήστε. Contacts are on internal flash. Οι επαφές είναι στην εσωτερική μνήμη. @@ -778,6 +779,8 @@ Settings Ρυθμίσεις Setup complete Η ρύθμιση ολοκληρώθηκε Share QR Κοινοποίηση QR Share channel Κοινή χρήση καναλιού +Share contact Κοινοποίηση επαφής +Share failed Αποτυχία κοινοποίησης Share location in advert Κοινή χρήση θέσης στο advert Share secret Κοινοποίηση μυστικού Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Μοιραστείτε το μυστικό 32 χαρακτήρων για να συμμετάσχουν άλλοι. Κενό = τυχαίο. @@ -977,8 +980,6 @@ tap to exit full screen πατήστε για έξοδο από πλήρη οθ zoom ζουμ zoom %d ζουμ %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ενισχυτής ~17 dB για ήσυχες/απομακρυσμένες περιοχές· κλείστε σε θορυβώδεις. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/es.lang b/deploy/apps/lang/es.lang index fe56063..c7b8bab 100644 --- a/deploy/apps/lang/es.lang +++ b/deploy/apps/lang/es.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: es -# ver: 18 +# ver: 21 # name: Español # base: es (device behind) (dispositivo atrasado) @@ -184,6 +184,7 @@ Contact added Contacto añadido Contact deleted Contacto eliminado Contact gone Contacto perdido Contact missing Falta el contacto +Contact shared Contacto compartido Contacts Contactos Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Los contactos están en memoria interna - la tarjeta SD no se montó al arrancar. Reinserta la tarjeta y reinicia. Contacts are on internal flash. Los contactos están en la memoria interna. @@ -778,6 +779,8 @@ Settings Ajustes Setup complete Configuración completa Share QR Compartir QR Share channel Compartir canal +Share contact Compartir contacto +Share failed Error al compartir Share location in advert Compartir ubicación en anuncio Share secret Compartir secreto Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Comparte el secreto de 32 caracteres para que otros se unan. Déjalo vacío para uno aleatorio. @@ -977,8 +980,6 @@ tap to exit full screen toca para salir de pantalla completa zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. amplificador ~17 dB para zonas tranquilas/remotas; apaga en zonas ruidosas. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/fr.lang b/deploy/apps/lang/fr.lang index 7d5a664..cb92be8 100644 --- a/deploy/apps/lang/fr.lang +++ b/deploy/apps/lang/fr.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: fr -# ver: 18 +# ver: 21 # name: Français # base: fr (device behind) (appareil en retard) @@ -184,6 +184,7 @@ Contact added Contact ajouté Contact deleted Contact supprimé Contact gone Contact perdu Contact missing Contact manquant +Contact shared Contact partagé Contacts Contacts Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Les contacts sont en mémoire interne - la carte SD ne s'est pas montée au démarrage. Réinsérez la carte et redémarrez. Contacts are on internal flash. Les contacts sont sur la mémoire interne. @@ -452,7 +453,6 @@ Login OK (perms %u) Connexion OK (perms %u) Login failed Échec de connexion Logs Journaux Longitude Longitude -Lua Store Lua Store MHz MHz MQTT bridge Pont MQTT Map Carte @@ -778,6 +778,8 @@ Settings Paramètres Setup complete Configuration terminée Share QR Partager le QR Share channel Partager le canal +Share contact Partager le contact +Share failed Échec du partage Share location in advert Partager la position dans l'annonce Share secret Partager le secret Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Partagez le secret de 32 caractères pour que d'autres rejoignent. Laissez vide pour un aléatoire. @@ -977,8 +979,6 @@ tap to exit full screen toucher pour quitter le plein écran zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ampli ~17 dB pour zones calmes/isolées ; désactiver en zone bruyante. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1000,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1013,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1039,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1047,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1056,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1068,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1085,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/hu.lang b/deploy/apps/lang/hu.lang index 84dfac7..5f6dddd 100644 --- a/deploy/apps/lang/hu.lang +++ b/deploy/apps/lang/hu.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: hu -# ver: 18 +# ver: 21 # name: Magyar # base: hu (device behind) (készülék hátulján) @@ -186,6 +186,7 @@ Contact added Névjegy hozzáadva Contact deleted Névjegy törölve Contact gone Eltűnt névjegy Contact missing Hiányzó névjegy +Contact shared Névjegy megosztva Contacts Névjegyek Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. A névjegyek a belső tárolón vannak - az SD-kártya nem csatolódott induláskor. Helyezd be újra a kártyát, és indítsd újra. Contacts are on internal flash. A névjegyek a belső tárolón vannak. @@ -400,7 +401,7 @@ Join a private channel Belépés priváthoz Join hashtag channel Csatlakozz # csatornához Join network Csatlakozás a hálózathoz Join private channel Csatlakozz privát csatornához -Join the public channel Csatlakozás a nyilvános csatornához +Join the public channel Belépés a nyilvánoshoz Joined %.40s Csatlakozott %.40s alatt Keep per chat (messages) Megőrzés csevegésenként (üzenet) Key already in use Kulcs már hozzárendelve @@ -413,7 +414,7 @@ Keyboard nav: WASDZ on Billentyűzet navigáció: WASDZ bekapcsolva Keyboard nav: off Billentyűzetnavigáció: kikapcsolva Keyboard navigation Billentyűzetnavigáció Keys Kulcsok -Known regions Known regions +Known regions Ismert régiók LOS → %s Rálátás → %s Landscape (desktop) Fekvő (asztali) Landscape set - applies when remote mode starts. Fekvő beállítva - a távoli mód indulásakor lép életbe. @@ -471,7 +472,7 @@ Map — no tile pack on SPIFFS yet.\n\nUpload a tile pack to /tiles///. Map — set your location\nin Settings → Profile to\nshow the map here. Térkép – a Beállítások → Profil menüpontban állítsd be a tartózkodási helyedet, hogy itt jelenjen meg a térkép. Mark all chats and channels as read? Az összes csevegést és csatornát megjelölöd olvasottként? Mark as read Olvasottnak jelöl -Mark read Mark read +Mark read Olvasott Marked read Olvasottként megjelölve Max hops (0..64) Max ugrások (0-64) Max zoom for this pack Maximális zoom ehhez a csomaghoz @@ -703,7 +704,7 @@ SD card remounted SD kártya újracsatolva SD card removed SD-kártya eltávolítva SD data is unavailable - contacts and channels cannot be saved until the card is reinserted. Az SD-kártya adatai nem érhetők el – a névjegyek és a csatornák nem menthetők a kártya újbóli behelyezéséig. SD data is unavailable - identity, settings, contacts and channels cannot be saved until the card is reinserted. Az SD-kártya adatai nem érhetők el – az azonosító, a beállítások, a névjegyek és a csatornák nem menthetők a kártya újbóli behelyezéséig. -SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. Az SD-kártya adatainak áthelyezése nem teljes. Az azonosító és a beállítások továbbra is a belső tárhelyen vannak; a folytatáshoz használd a „Belső adatok másolása SD-kártyára” lehetőséget. +SD data migration is incomplete. Identity and settings remain internal; use Copy internal data to SD to retry. Az SD-kártya adatainak áthelyezése nem teljes. Az azonosító és a beállítások továbbra is a belső tárhelyen vannak; a folytatáshoz használd a "Belső adatok másolása SD-kártyára" lehetőséget. SD download failed: %s SD-letöltés sikertelen: %s SD formatted - %s (MESHCOMOD) SD formázás - %s (MESHCOMOD) SD is busy - close tools and retry Az SD-kártya foglalt – zárd be az eszközöket, majd próbáld újra. @@ -791,6 +792,8 @@ Settings Beállítások Setup complete Beállítás kész Share QR QR megosztása Share channel Csatorna megosztása +Share contact Névjegy megosztása +Share failed Megosztás sikertelen Share location in advert Helyszín megosztása a hirdetésben Share secret Titok megosztása Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Oszd meg a 32 karakteres titkot, hogy mások is csatlakozhassanak. Hagyd üresen a titkot, hogy véletlenszerű titkos kódot generálj. @@ -812,7 +815,6 @@ Sleep ready Készen áll az alvásra Slot %d cleared %d hely kiürítve Slot empty Üres hely Small\nMedium\nLarge Kicsi\nKözepes\nNagy -Snake Snake Snake — swipe or roll the trackball Kígyó – pöccintsd vagy görgesd a görgetőgolyót Sort Sort Sound Hang @@ -897,7 +899,7 @@ Turn this on, then open the address below in any web browser on the same Wi-Fi - Type Tipus Type a URL, then Go Írj be egy URL-t, majd Mehet Type a message... Írj be egy üzenetet... -Type a new 6-digit code · applies after a reboot Írjon be egy új 6 jegyű kódot · újraindítás után érvényes +Type a new 6-digit code · applies after a reboot Írjon be egy 6 jegyű kódot · újraindítás után él Type your network name — or switch to Wi-Fi in Settings to scan Írd be a hálózatod nevét – vagy válts Wi-Fi-re a beállításokban a kereséshez UI size (restart to apply) UI mérete (újraindítás az alkalmazáshoz) UI size saved — restart to apply UI mérete mentve – indítsa újra a programot az alkalmazáshoz @@ -997,8 +999,6 @@ tap to exit full screen koppintson a teljes képernyős kilépéshez zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ~17 dB erősítővel csendes/távoli helyeken; zajos helyeken kapcsold ki. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope Hatókör another region másik régió my region saját régió @@ -1065,11 +1065,10 @@ sensors érzékelők Auto-add on for %s — new %s land in Contacts automatically. Automatikus hozzáadás bekapcsolva: %s — az új %s automatikusan a Névjegyek közé kerülnek. Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed under the Open Database License (ODbL).\n\n Térkép adatok © OpenStreetMap közreműködői.\nopenstreetmap.org/copyright\nAz Open Database License (ODbL) licenc alatt.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Térkép stílus © OpenTopoMap (CC-BY-SA) — opentopomap.org\nTérkép adatok © OpenStreetMap közreműködői (ODbL) + SRTM.\n\n -How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. A csempék működése:\nA térkép 256×256 képpontos „slippy” csempékből épül fel. Csak a megtekintett területhez szükséges csempék töltődnek le — nincs tömeges előzetes letöltés.\n\nMivel az eszköz nem támogatja a HTTPS-t (a Wi-Fi elindítása után nincs elegendő heap memória), és a JPEG képek dekódolása sokkal kevesebb erőforrást igényel, mint a PNG-é, a csempék a wadamesh proxyn keresztül érkeznek: a proxy HTTPS-en keresztül lekéri a forrásból a PNG-t egy azonosító User-Agent használatával, JPEG formátumba kódolja át, majd eltárolja a gyorsítótárban. Az eszköz ezután minden csempét a saját flash memóriájában is eltárol, így egy csempét csak egyszer kell letölteni.\n\nAz Options → Reload tiles lehetőséggel újra letöltheted a jelenleg megtekintett terület csempéit, ha valamelyik hibásan jelenik meg. +How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. A csempék működése:\nA térkép 256×256 képpontos "slippy" csempékből épül fel. Csak a megtekintett területhez szükséges csempék töltődnek le — nincs tömeges előzetes letöltés.\n\nMivel az eszköz nem támogatja a HTTPS-t (a Wi-Fi elindítása után nincs elegendő heap memória), és a JPEG képek dekódolása sokkal kevesebb erőforrást igényel, mint a PNG-é, a csempék a wadamesh proxyn keresztül érkeznek: a proxy HTTPS-en keresztül lekéri a forrásból a PNG-t egy azonosító User-Agent használatával, JPEG formátumba kódolja át, majd eltárolja a gyorsítótárban. Az eszköz ezután minden csempét a saját flash memóriájában is eltárol, így egy csempét csak egyszer kell letölteni.\n\nAz Options → Reload tiles lehetőséggel újra letöltheted a jelenleg megtekintett terület csempéit, ha valamelyik hibásan jelenik meg. "%s" wants to send discovery probes.\n\nEach probe asks every node in range to reply, so it uses airtime on the whole local mesh, not just yours.\n\nNothing is sent under your name and no message is transmitted. "%s" felfedezési probe-ok küldését kéri.\n\nMinden probe válaszra kéri a hatótávolságon belüli node-okat, ezért a teljes helyi mesh hálózat airtime-ját használja, nem csak a tiédet.\n\nSemmi sem kerül elküldésre a nevedben, és üzenet sem kerül továbbításra. ? ? Auth failed Auth failed -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Csak közvetlen (0-hop) @@ -1078,16 +1077,12 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Szöveg megadása Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... Link lost Link lost MESH MESH Name (A-Z) Név (A–Z) Nearest first Legközelebbi elöl -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Legutóbbi üzenet Reload tiles in view Csempék újratöltése Repeaters Repeaters @@ -1098,13 +1093,8 @@ Show contacts Névjegyek megjelenítése Show coordinates Koordináták Show tile z/x/y Csempe z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Csempe hiba keret -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite tap to cycle off / on / auto tap to cycle off / on / auto #7A7F87 Scanning… nothing has answered yet# #7A7F87 Scanning… nothing has answered yet# Export crash report (%uK) Hibajelentés exportálása (%uK) @@ -1116,3 +1106,27 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. A beta_%d telepítése?\nEz leminősíti a firmware-t és újraindul. +Other (hidden) network… Other (hidden) network… +Paused Paused +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal (stale) Jel (elavult) +nothing heard yet Még semmi hír. +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/it.lang b/deploy/apps/lang/it.lang index e0350d1..f5cc517 100644 --- a/deploy/apps/lang/it.lang +++ b/deploy/apps/lang/it.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: it -# ver: 18 +# ver: 21 # name: Italiano # base: it (device behind) (dispositivo indietro) @@ -184,6 +184,7 @@ Contact added Contatto aggiunto Contact deleted Contatto eliminato Contact gone Contatto perso Contact missing Contatto mancante +Contact shared Contatto condiviso Contacts Contatti Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. I contatti sono sulla memoria interna - la scheda SD non si è montata all'avvio. Reinserisci la scheda e riavvia. Contacts are on internal flash. I contatti sono sulla memoria interna. @@ -452,7 +453,6 @@ Login OK (perms %u) Accesso OK (permessi %u) Login failed Accesso non riuscito Logs Log Longitude Longitudine -Lua Store Lua Store MHz MHz MQTT bridge Ponte MQTT Map Mappa @@ -778,6 +778,8 @@ Settings Impostazioni Setup complete Configurazione completata Share QR Condividi QR Share channel Condividi canale +Share contact Condividi contatto +Share failed Condivisione non riuscita Share location in advert Condividi posizione in advert Share secret Condividi segreto Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Condividi il segreto di 32 caratteri per far unire altri. Lascia vuoto per uno casuale. @@ -977,8 +979,6 @@ tap to exit full screen tocca per uscire da schermo intero zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ampli ~17 dB per zone tranquille/remote; spegni in zone rumorose. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1000,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1013,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1039,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1047,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1056,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1068,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1085,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/nl.lang b/deploy/apps/lang/nl.lang index a7f4f93..a2f82b6 100644 --- a/deploy/apps/lang/nl.lang +++ b/deploy/apps/lang/nl.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: nl -# ver: 18 +# ver: 21 # name: Nederlands # base: nl (device behind) (apparaat loopt achter) @@ -184,6 +184,7 @@ Contact added Contact toegevoegd Contact deleted Contact verwijderd Contact gone Contact weg Contact missing Contact ontbreekt +Contact shared Contact gedeeld Contacts Contacten Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Contacten staan op intern flash - de SD-kaart is bij het opstarten niet gekoppeld. Plaats de kaart opnieuw en herstart. Contacts are on internal flash. Contacten staan op intern flashgeheugen. @@ -452,7 +453,6 @@ Login OK (perms %u) Inloggen OK (rechten %u) Login failed Inloggen mislukt Logs Logboeken Longitude Lengtegraad -Lua Store Lua Store MHz MHz MQTT bridge MQTT-brug Map Kaart @@ -778,6 +778,8 @@ Settings Instellingen Setup complete Installatie voltooid Share QR QR delen Share channel Kanaal delen +Share contact Contact delen +Share failed Delen mislukt Share location in advert Locatie delen in advert Share secret Geheim delen Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Deel het 32-teken geheim zodat anderen kunnen deelnemen. Leeg laten voor een willekeurig geheim. @@ -797,7 +799,6 @@ Sleep ready Klaar voor slaap Slot %d cleared Slot %d gewist Slot empty Slot leeg Small\nMedium\nLarge Klein\nMiddel\nGroot -Snake Snake Snake — swipe or roll the trackball Snake — veeg of rol de trackball Sort Sorteer Sound Geluid @@ -805,7 +806,6 @@ Sound off Geluid uit Sound on Geluid aan Sound: %s Geluid: %s Start time Starttijd -Status Status Step 1 of 3 Stap 1 van 3 Step 2 of 3 Stap 2 van 3 Step 3 of 3 Stap 3 van 3 @@ -977,8 +977,6 @@ tap to exit full screen tik om volledig scherm te verlaten zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. ~17 dB versterker voor stille/afgelegen gebieden; uit in drukke plekken. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +998,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1011,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1037,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1045,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1054,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1066,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1083,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/pt-br.lang b/deploy/apps/lang/pt-br.lang index e39cb21..cb0a884 100644 --- a/deploy/apps/lang/pt-br.lang +++ b/deploy/apps/lang/pt-br.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: pt-br -# ver: 18 +# ver: 21 # name: Português (BR) # base: pt-br (device behind) (dispositivo atrasado) @@ -184,6 +184,7 @@ Contact added Contato adicionado Contact deleted Contato excluído Contact gone Contato sumiu Contact missing Contato ausente +Contact shared Contato compartilhado Contacts Contatos Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Os contatos estão na memória interna - o cartão SD não montou na inicialização. Recoloque o cartão e reinicie. Contacts are on internal flash. Os contatos estão na memória interna. @@ -778,6 +779,8 @@ Settings Ajustes Setup complete Configuração concluída Share QR Compartilhar QR Share channel Compartilhar canal +Share contact Compartilhar contato +Share failed Falha ao compartilhar Share location in advert Compartilhar local no advert Share secret Compartilhar segredo Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Compartilhe o segredo de 32 caracteres para outros entrarem. Deixe vazio para gerar um aleatório. @@ -805,7 +808,6 @@ Sound off Som desligado Sound on Som ligado Sound: %s Som: %s Start time Hora de início -Status Status Step 1 of 3 Passo 1 de 3 Step 2 of 3 Passo 2 de 3 Step 3 of 3 Passo 3 de 3 @@ -977,8 +979,6 @@ tap to exit full screen toque para sair da tela cheia zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. amplificador ~17 dB para áreas silenciosas/remotas; desligue em locais ruidosos. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1000,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1013,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1039,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1047,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1056,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1068,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1085,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/ro.lang b/deploy/apps/lang/ro.lang index 6967b9d..6f56119 100644 --- a/deploy/apps/lang/ro.lang +++ b/deploy/apps/lang/ro.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: ro -# ver: 18 +# ver: 21 # name: Română # base: ro (device behind) (dispozitiv în urmă) @@ -184,6 +184,7 @@ Contact added Contact adăugat Contact deleted Contact şters Contact gone Contact dispărut Contact missing Contact lipsă +Contact shared Contact partajat Contacts Contacte Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Contactele sunt pe memoria internă - cardul SD nu s-a montat la pornire. Reaşază cardul şi reporneşte. Contacts are on internal flash. Contactele sunt pe memoria internă. @@ -778,6 +779,8 @@ Settings Setări Setup complete Configurare finalizată Share QR Partajează QR Share channel Partajează canalul +Share contact Partajează contactul +Share failed Partajare eşuată Share location in advert Partajează locaţia în advert Share secret Partajează secretul Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Partajează secretul de 32 caractere ca să poată intra şi alţii. Lasă secretul gol pentru a genera unul aleatoriu. @@ -978,7 +981,6 @@ zoom zoom zoom %d zoom %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. amplificator ~17 dB pentru zone liniştite/izolate; opreşte-l în locuri zgomotoase. © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1002,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1015,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1041,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1049,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1058,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1070,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1087,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/ru.lang b/deploy/apps/lang/ru.lang index ceb1ec3..8c2f272 100644 --- a/deploy/apps/lang/ru.lang +++ b/deploy/apps/lang/ru.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: ru -# ver: 18 +# ver: 21 # name: Русский # base: ru (device behind) (устройство отстаёт) @@ -184,6 +184,7 @@ Contact added Контакт добавлен Contact deleted Контакт удалён Contact gone Контакт пропал Contact missing Контакт отсутствует +Contact shared Контакт отправлен Contacts Контакты Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакты во внутренней памяти - SD-карта не смонтировалась при загрузке. Переустановите карту и перезагрузитесь. Contacts are on internal flash. Контакты во внутренней памяти. @@ -778,6 +779,8 @@ Settings Настройки Setup complete Настройка завершена Share QR Поделиться QR Share channel Поделиться каналом +Share contact Поделиться контактом +Share failed Не удалось отправить контакт Share location in advert Делиться местоположением в advert Share secret Поделиться ключом Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поделитесь секретом из 32 символов, чтобы другие присоединились. Пусто = случайный. @@ -977,8 +980,6 @@ tap to exit full screen нажмите для выхода из полноэкр zoom масштаб zoom %d масштаб %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. усилитель ~17 дБ для тихих/удалённых мест; выключайте в шумных. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/sr.lang b/deploy/apps/lang/sr.lang index 0aab3e1..8e7267b 100644 --- a/deploy/apps/lang/sr.lang +++ b/deploy/apps/lang/sr.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: sr -# ver: 18 +# ver: 21 # name: Српски # base: sr (device behind) (уређај касни) @@ -184,6 +184,7 @@ Contact added Контакт додат Contact deleted Контакт обрисан Contact gone Контакт нестао Contact missing Контакт недостаје +Contact shared Контакт подељен Contacts Контакти Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакти су у унутрашњој меморији - SD картица се није монтирала при покретању. Поново убаци картицу и рестартуј. Contacts are on internal flash. Контакти су у унутрашњој меморији. @@ -778,6 +779,8 @@ Settings Подешавања Setup complete Подешавање завршено Share QR Подели QR Share channel Подели канал +Share contact Подели контакт +Share failed Дељење није успело Share location in advert Дели локацију у advert-у Share secret Подели тајну Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поделите тајну од 32 знака да се други придруже. Празно = насумична. @@ -826,7 +829,7 @@ TCP on TCP укљ TOUCH BETA TOUCH BETA TX TX Tab hotkeys — tap a row, then press a key Пречице картице — додирни ред, па притисни тастер -Tap Use to switch - the device reboots to apply. Додирните „Користи“ да промените — уређај ће се поново покренути. +Tap Use to switch - the device reboots to apply. Додирните "Користи" да промените — уређај ће се поново покренути. Tap Use to switch - the device reboots to apply. Language files live in /lang on the storage; edit them or add your own. Додирни «Користи» за промену - уређај се поново покреће. Датотеке језика су у /lang на меморији; уреди их или додај своје. Tap a language; the device reboots to apply. Изаберите језик; уређај ће се рестартовати. Taste the rainbow! Окуси дугу! @@ -977,8 +980,6 @@ tap to exit full screen додирните за излаз из целог ек zoom зум zoom %d зум %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. појачало ~17 dB за тиха/удаљена места; искључи у бучним. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/lang/uk.lang b/deploy/apps/lang/uk.lang index 4ebd00f..10d5f67 100644 --- a/deploy/apps/lang/uk.lang +++ b/deploy/apps/lang/uk.lang @@ -1,7 +1,7 @@ # wadamesh language file # canonical source - translators: edit this file and PR it # code: uk -# ver: 18 +# ver: 21 # name: Українська # base: uk (device behind) (пристрій відстає) @@ -184,6 +184,7 @@ Contact added Контакт додано Contact deleted Контакт видалено Contact gone Контакт зник Contact missing Контакт відсутній +Contact shared Контакт надіслано Contacts Контакти Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакти у внутрішній пам'яті - SD-карта не змонтувалася під час завантаження. Переставте картку і перезавантажте. Contacts are on internal flash. Контакти у внутрішній пам'яті. @@ -778,6 +779,8 @@ Settings Налаштування Setup complete Налаштування завершено Share QR Поділитися QR Share channel Поділитися каналом +Share contact Поділитися контактом +Share failed Не вдалося надіслати контакт Share location in advert Ділитися місцезнаходженням в advert Share secret Поділитися ключем Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поділіться секретом із 32 символів, щоб інші приєдналися. Порожньо = випадковий. @@ -977,8 +980,6 @@ tap to exit full screen торкніться, щоб вийти з повное zoom масштаб zoom %d масштаб %d ~17 dB amp for quiet/remote areas; turn off in noisy spots. підсилювач ~17 дБ для тихих/віддалених місць; вимикайте в галасливих. -© OpenStreetMap © OpenStreetMap -© OpenTopoMap © OpenTopoMap Scope another region my region @@ -1000,7 +1001,6 @@ Overwrite oldest non-favorite 1-character messages will be shown 1-character messages will be shown All All Allow Allow -Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Apps that may send messages on the mesh. Anything they send goes out under your node name and cannot be told apart from a message you typed. Turn one off to take the permission back. Ignore 1-character messages Ignore 1-character messages Join w/ password Join w/ password Location no longer shared Location no longer shared @@ -1014,9 +1014,7 @@ Never\nChosen contacts only\nAnyone who asks Never\nChosen contacts only\nAnyone No apps installed. No apps installed. No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) No reply. Path hash is %u bytes;\nolder repeaters drop those.\nTry 1 byte (Settings > Radio & Mesh) Not supported on this board Not supported on this board -Read incoming messages Read incoming messages Reconnected to %.40s Reconnected to %.40s -Send messages as me Send messages as me Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Sent only when that contact asks, encrypted to them. Nothing is broadcast. Needs "Answer telemetry requests" on. Pick contacts in a contact's menu. Server has forgotten you.\nJoin with the room password. Server has forgotten you.\nJoin with the room password. Share my loc Share my loc @@ -1042,7 +1040,6 @@ App permissions App permissions About / credits About / credits Auth failed Auth failed Auto-add on for %s — new %s land in Contacts automatically. Auto-add on for %s — new %s land in Contacts automatically. -Batteryactivityon Batteryactivityon Console mode Console mode Console mode (experimental) Console mode (experimental) Direct (0-hop) only Direct (0-hop) only @@ -1051,8 +1048,6 @@ EXPERIMENTAL. Boots into a text console with no graphical interface: type comman Enter text Enter text Entering console mode - rebooting... Entering console mode - rebooting... Favorite Favorite -Geblokkeerde gebruikers Geblokkeerde gebruikers -Hide system filesShow system files Hide system filesShow system files How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. How tiles work:\nThe map is built from 256×256 "slippy" tiles. Only the tiles for the area you're viewing are fetched — there is no bulk pre-download.\n\nBecause this device can't do HTTPS (not enough heap after Wi-Fi starts) and decodes JPEG far more cheaply than PNG, tiles come from the wadamesh proxy: it fetches the upstream PNG over HTTPS with an identifying User-Agent, re-encodes it as JPEG, and caches it. Your device then caches each tile to its own flash, so a tile is only downloaded once.\n\nUse Options → Reload tiles to re-download the tiles currently in view if one looks corrupted. Init… Init… Leaving console mode - rebooting... Leaving console mode - rebooting... @@ -1062,8 +1057,6 @@ Map data © OpenStreetMap contributors.\nopenstreetmap.org/copyright\nLicensed u Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Map style © OpenTopoMap (CC-BY-SA) — opentopomap.org\nMap data © OpenStreetMap contributors (ODbL) + SRTM.\n\n Name (A-Z) Name (A-Z) Nearest first Nearest first -Other networksNetworks Other networksNetworks -Paste (move)Paste (copy) Paste (move)Paste (copy) Recent message Recent message Reload tiles in view Reload tiles in view Repeaters Repeaters @@ -1076,13 +1069,8 @@ Show contacts Show contacts Show coordinates Show coordinates Show tile z/x/y Show tile z/x/y Starting… Starting… -Stop sharing loc Share my loc Stop sharing loc Share my loc -Supprimer Supprimer -Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Switch to the external antenna?\n\nMake sure an antenna is actually connected to the external antenna socket first. Transmitting with nothing attached can damage the radio.\n\nResets to the on-board antenna on every reboot.Turn on legacy per-transmit switching?\n\nDiagnostic mode, for comparison only. It transmits on the on-board antenna and listens on the external one, so your outbound signal will be much weaker than your inbound.\n\nResets to the on-board antenna on every reboot. Text console (experimental) Text console (experimental) Tile debug overlay Tile debug overlay -Unblock Block Unblock Block -Unfav Favorite Unfav Favorite chats chats repeaters repeaters rooms rooms @@ -1098,3 +1086,30 @@ channel busy %.1f%% channel busy %.1f%% sampling... sampling... teal = now blue = average teal = now blue = average window restarted window restarted +Filter Filter +Hide system files Hide system files +Networks Networks +Other networks Other networks +Show system files Show system files +Unfav Unfav +Firmware beta_%d\nChecking for updates over Wi-Fi… Firmware beta_%d\nChecking for updates over Wi-Fi… +Install beta_%d?\nThis downgrades the firmware and reboots. Install beta_%d?\nThis downgrades the firmware and reboots. +Other (hidden) network… Other (hidden) network… +Paused Paused +Scan again Scan again +At a glance At a glance +At a glance disabled At a glance disabled +At a glance enabled At a glance enabled +At a glance while locked At a glance while locked +Glance only shows when unlocked Glance only shows when unlocked +Glance shows message previews\nwhile the screen is locked Glance shows message previews\nwhile the screen is locked +Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction +N/A N/A +This board cannot run this app. This board cannot run this app. +Signal Signal +Signal (stale) Signal (stale) +nothing heard yet nothing heard yet +Detecting the keyboard protocol Detecting the keyboard protocol +Older keyboard protocol Older keyboard protocol +Using the older keyboard protocol Using the older keyboard protocol +turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching diff --git a/deploy/apps/langs.json b/deploy/apps/langs.json index 76bba5e..27d413b 100644 --- a/deploy/apps/langs.json +++ b/deploy/apps/langs.json @@ -3,67 +3,67 @@ { "code": "bg", "name": "Български", - "ver": "18" + "ver": "21" }, { "code": "de", "name": "Deutsch", - "ver": "18" + "ver": "21" }, { "code": "el", "name": "Ελληνικά", - "ver": "18" + "ver": "21" }, { "code": "es", "name": "Español", - "ver": "18" + "ver": "21" }, { "code": "fr", "name": "Français", - "ver": "18" + "ver": "21" }, { "code": "hu", "name": "Magyar", - "ver": "18" + "ver": "21" }, { "code": "it", "name": "Italiano", - "ver": "18" + "ver": "21" }, { "code": "nl", "name": "Nederlands", - "ver": "18" + "ver": "21" }, { "code": "pt-br", "name": "Português (BR)", - "ver": "18" + "ver": "21" }, { "code": "ro", "name": "Română", - "ver": "18" + "ver": "21" }, { "code": "ru", "name": "Русский", - "ver": "18" + "ver": "21" }, { "code": "sr", "name": "Српски", - "ver": "18" + "ver": "21" }, { "code": "uk", "name": "Українська", - "ver": "18" + "ver": "21" } ] } diff --git a/deploy/apps/sdktest/1.7/sdktest.json b/deploy/apps/sdktest/1.7/sdktest.json new file mode 100644 index 0000000..aa4e24e --- /dev/null +++ b/deploy/apps/sdktest/1.7/sdktest.json @@ -0,0 +1 @@ +{"id":"sdktest","name":"SDK Test","ver":"1.7","desc":"Developer tool. Checks the extended Lua SDK on this board: capabilities, clock, battery, GPS, private files, audio API, read-only SD listing, crypto vectors, packet identity, channels, and opt-in transmit calls."} diff --git a/deploy/apps/sdktest/1.7/sdktest.lua b/deploy/apps/sdktest/1.7/sdktest.lua new file mode 100644 index 0000000..94b64da --- /dev/null +++ b/deploy/apps/sdktest/1.7/sdktest.lua @@ -0,0 +1,293 @@ +-- SDK self-test. Exercises the extended SDK so the results can be read off the +-- screen instead of inferred from a build log. Published to the store as a +-- developer/bench tool. +-- +-- 1.2 adds wada.crypto (checked against published RFC vectors, so a PASS here is +-- real evidence and not just "it returned something"), wada.mesh.channels, and +-- wada.mesh.send_dm. +-- 1.3 adds the discovery surface (wada.mesh.discover / discovered), packet +-- identity in rx_log, exact micro-degree coordinates, wada.ui.input and the +-- windowed wada.fs.read. +-- 1.6 adds wada.sd.list: capability reporting, traversal rejection, root +-- metadata, and a nested directory listing when the card contains one. +-- 1.7 adds storage-neutral wada.audio capability and API-shape checks. Playback +-- stays manual so opening the bench test never emits sound unexpectedly. +-- 1.5 uses wada.ui.text_lines() to measure instead of estimating, where the +-- firmware has it. That call was added because of the 1.3 bug below: an app +-- could ask how tall a line is but not how wide, so laying out rows meant +-- guessing whether text would wrap. Falls back to the 1.4 estimate on older +-- firmware, so it still lays out correctly there. +-- 1.4 fixes rows drawing on top of one another. label:width() turns wrapping +-- on, so any line wider than the screen became two lines while the caller still +-- advanced by one, and the next row landed on top. Reported with a photo of the +-- channels line sitting across the contacts line. row() now owns the cursor and +-- advances by the height the text actually needs. +local ui, sys, store, timer = wada.ui, wada.sys, wada.store, wada.timer +local C = ui.colors + +local app = {} +local rows, keyline, sendline, dmline, msgline = {}, nil, nil, nil, nil +local discline, inputline = nil, nil +local W = 300 + +-- row() owns the vertical cursor. Every caller used to pass a y and then add a +-- hand-picked constant, which is only correct while the text fits on one line. +-- An app cannot measure rendered text, so the wrapped line count is estimated +-- from a deliberately pessimistic character width: over-estimating costs a +-- little whitespace, under-estimating overlaps the next row. +local LH, GAP = 14, 3 +local cy = 4 +local function row(text, color, extra_gap) + local l = ui.label(text, 6, cy, 12, color or C.text) + l:width(W - 12) + rows[#rows + 1] = l + local n + if ui.text_lines then + n = ui.text_lines(tostring(text), W - 12, 12) -- measured: exact + else + local cpl = math.max(16, (W - 12) // 7) -- older firmware: estimate + n = 0 + for seg in (tostring(text) .. "\n"):gmatch("(.-)\n") do + n = n + math.max(1, math.ceil(#seg / cpl)) + end + end + cy = cy + math.max(1, n or 1) * LH + GAP + (extra_gap or 0) + return l +end +local function yn(v) return v and "yes" or "NO" end + +function app.on_open(w, h) + W = w or 300 + ui.scroll(true) + cy = 4 + local y + + local c = sys.caps() + row("caps: sdk_ext=" .. yn(c.sdk_ext) .. " kbd=" .. yn(c.keyboard) .. + " touch=" .. yn(c.touch) .. " sd=" .. yn(c.sd), C.accent) + row("caps: sd_list=" .. yn(c.sd_list) .. " discover=" .. yn(c.discover) .. + " input=" .. yn(c.input) .. + " rx_identity=" .. yn(c.rx_identity), C.accent) + row("caps: audio=" .. yn(c.audio) .. " wav=" .. yn(c.audio_wav) .. + " mp3=" .. yn(c.audio_mp3) .. " audio_sd=" .. yn(c.audio_sd), C.accent) + if c.audio then + local api_ok = wada.audio and type(wada.audio.play) == "function" and + type(wada.audio.pause) == "function" and + type(wada.audio.resume) == "function" and + type(wada.audio.stop) == "function" and + type(wada.audio.status) == "function" + local status = api_ok and wada.audio.status() or nil + api_ok = api_ok and type(status) == "table" and type(status.state) == "string" + row("wada.audio API: " .. (api_ok and ("PASS (" .. status.state .. ")") or "FAIL"), + api_ok and C.good or C.bad) + else + row("wada.audio: unavailable on this board", C.sub) + end + row("layout: " .. (ui.text_lines and "measured (ui.text_lines)" or "estimated (older firmware)"), + ui.text_lines and C.good or C.sub) + -- crypto: published test vectors, so this is checkable rather than merely alive + if wada.crypto then + local hex = wada.crypto.hex + local k20 = string.rep(string.char(0x0b), 20) + local checks = { + { "sha256('abc')", hex(wada.crypto.sha256("abc")), + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" }, + { "sha1('abc')", hex(wada.crypto.sha1("abc")), + "a9993e364706816aba3e25717850c26c9cd0d89d" }, + { "hmac_sha1 RFC2202#1", hex(wada.crypto.hmac_sha1(k20, "Hi There")), + "b617318655057264e28bc0b6fb378c8ef146be00" }, + { "hmac_sha256 RFC4231#1", hex(wada.crypto.hmac_sha256(k20, "Hi There")), + "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7" }, + } + local allok = true + for _, t in ipairs(checks) do + local ok = (t[2] == t[3]) + if not ok then allok = false end + row("crypto " .. t[1] .. ": " .. (ok and "PASS" or ("FAIL got " .. tostring(t[2]):sub(1, 16))), + ok and C.good or C.bad) + end + -- The point of having it in C: this loop would blow the instruction budget in Lua. + local t0 = sys.millis() + for _ = 1, 200 do wada.crypto.hmac_sha1(k20, "Hi There") end + row(string.format("crypto: 200 x hmac_sha1 in %d ms%s", sys.millis() - t0, + allok and "" or " (VECTORS FAILED)"), allok and C.good or C.bad) + else + row("wada.crypto: MISSING", C.bad) + end + + -- channel discovery + local chans = wada.mesh.channels and wada.mesh.channels() or nil + if chans then + local names = table.concat(chans, ", ") + row("channels(): " .. #chans .. " " .. names:sub(1, 60), C.text) + else + row("wada.mesh.channels: MISSING", C.bad) + end + + if not c.sdk_ext then + row("extended SDK is OFF on this board - stopping here.", C.sub) + return + end + + -- contacts, so send_dm has a target to name. 1.3 also checks the pubkey field. + local cts = wada.mesh.contacts() + local first = cts[1] and cts[1].name or nil + row("contacts: " .. #cts .. (first and (" first=" .. first) or ""), C.text) + if cts[1] then + local pk = cts[1].pubkey + row("contacts[1].pubkey: " .. tostring(pk) .. + (type(pk) == "string" and #pk == 8 and " PASS" or " FAIL"), + (type(pk) == "string" and #pk == 8) and C.good or C.bad) + end + + local me = wada.mesh.self() + row("self: " .. tostring(me.name) .. " pubkey=" .. tostring(me.pubkey), C.text) + -- Exact coordinates. Lua's floats here are 32-bit, so an app that logs a track + -- must use the _e6 integers; this proves they are present and consistent. + local fix = sys.gps() + if fix then + local drift = math.abs(fix.lat_e6 / 1e6 - fix.lat) + row(string.format("gps: %d,%d e6 alt %dm %d sats drift %.6f %s", + fix.lat_e6, fix.lon_e6, fix.alt_m or 0, fix.sats, drift, + drift < 0.001 and "PASS" or "FAIL"), drift < 0.001 and C.good or C.bad) + else + row("gps: no fix (normal indoors)", C.sub) + end + + -- rx_log identity: adverts carry a real public key, addressed frames carry + -- one-byte hashes, everything else carries nothing. All three are correct. + local log = wada.mesh.rx_log() + local withpk, withsrc = 0, 0 + for _, r in ipairs(log) do + if r.pubkey then withpk = withpk + 1 end + if r.src then withsrc = withsrc + 1 end + end + row(string.format("rx_log: %d frames, %d with a pubkey (adverts), %d with src/dst", + #log, withpk, withsrc), #log > 0 and C.text or C.sub) + -- fs: windowed read. Writes once (the 1/sec limit means one write per open). + if wada.fs then + local probe = "0123456789abcdef" + wada.fs.write("sdktest.bin", probe) + local part, total = wada.fs.read("sdktest.bin", 4, 4) + local ok = (part == "4567" and total == #probe) + row("fs.read(name,4,4): " .. tostring(part) .. " total=" .. tostring(total) .. + (ok and " PASS" or " FAIL"), ok and C.good or C.bad) + end + + -- Physical SD listing is read-only and independently feature-detected. A + -- supported board with no inserted card is a normal bench state, not a test + -- failure; API shape and path rejection can still be checked separately. + if c.sd_list then + if not wada.sd or not wada.sd.list then + row("wada.sd.list: MISSING despite caps", C.bad) + else + local guard_ok, guard_failure = true, nil + local bad_paths = { "/..", "/.", "/a/../b", "/a//b", "/a/", "relative", "/a\\b" } + for _, path in ipairs(bad_paths) do + local rejected, baderr = wada.sd.list(path) + if rejected ~= nil or baderr ~= "bad path" then + guard_ok = false + guard_failure = path .. " -> " .. tostring(baderr) + break + end + end + row("sd traversal guard: " .. (guard_ok and "PASS" or ("FAIL " .. guard_failure)), + guard_ok and C.good or C.bad) + + local entries, err = wada.sd.list("/") + if not entries then + local note = err == "busy" and " (retry later)" or " (no readable card)" + row("sd.list('/'): " .. tostring(err) .. note, C.sub) + else + local metadata_ok, first_dir = true, nil + for _, entry in ipairs(entries) do + if type(entry.name) ~= "string" or + (entry.type ~= "file" and entry.type ~= "dir") or + type(entry.size) ~= "number" or type(entry.mtime) ~= "number" then + metadata_ok = false + end + if not first_dir and entry.type == "dir" then first_dir = entry.name end + end + row("sd.list('/'): " .. #entries .. " entries, metadata " .. + (metadata_ok and "PASS" or "FAIL") .. + (entries.truncated and " (truncated)" or ""), + metadata_ok and C.good or C.bad) + if first_dir then + local nested, nested_err = wada.sd.list("/" .. first_dir) + row("sd.list('/" .. first_dir .. "'): " .. + (nested and (#nested .. " entries PASS") or ("FAIL " .. tostring(nested_err))), + nested and C.good or C.bad) + else + row("sd nested listing: no directory on card to test", C.sub) + end + end + end + else + row("wada.sd.list: unavailable on this board", C.sub) + end + + sendline = row("mesh.send: not tried yet", C.sub) + dmline = row("mesh.send_dm: not tried yet", C.sub) + msgline = row("on_message: waiting (needs the read permissions)", C.sub) + y = cy + 4 + ui.button("Send to Public", 6, y, 120, 30, function() + local ok, err = wada.mesh.send("Public", "wadamesh SDK self-test") + sendline:set("mesh.send: " .. tostring(ok) .. " " .. tostring(err)) + sendline:color(ok and C.good or C.bad) + end) + ui.button("DM first contact", 132, y, 130, 30, function() + if not first then dmline:set("mesh.send_dm: no contacts to target"); dmline:color(C.bad); return end + local ok, err = wada.mesh.send_dm(first, "wadamesh SDK self-test (DM)") + dmline:set("mesh.send_dm -> " .. first .. ": " .. tostring(ok) .. " " .. tostring(err)) + dmline:color(ok and C.good or C.bad) + end) + cy = y + 38 + discline = row("mesh.discover: not tried yet", C.sub) + inputline = row("ui.input: not tried yet", C.sub) + -- Probing TRANSMITS and makes every neighbour reply, so it is a button, not + -- something this app does on open. + y = cy + 4 + ui.button("Probe", 6, y, 90, 30, function() + local tag, err = wada.mesh.discover() + if not tag then + discline:set("mesh.discover: " .. tostring(err)); discline:color(C.bad); return + end + discline:set("mesh.discover: sent, waiting for replies..."); discline:color(C.text) + end) + ui.button("Results", 102, y, 90, 30, function() + local hits = wada.mesh.discovered() + if #hits == 0 then + discline:set("discovered(): nothing yet - probe, then wait a few seconds") + discline:color(C.sub); return + end + local h = hits[1] + discline:set(string.format("discovered(): %d first %s snr %.1f/%.1f %s", + #hits, h.name or h.pubkey, h.snr, h.their_snr, h.direct and "direct" or (h.hops .. "h"))) + discline:color(C.good) + end) + y = y + 34 + ui.button("Beep", 6, y, 70, 30, function() sys.beep() end) + ui.button("Input", 82, y, 90, 30, function() + ui.input("Type anything", "hello", function(text) + inputline:set("ui.input -> " .. (text and ("'" .. text .. "'") or "cancelled")) + inputline:color(text and C.good or C.sub) + end) + end) +end + +function app.on_input(ev) + if ev.type == "key" and keyline then + keyline:set("keys: got '" .. tostring(ev.key) .. "'") + keyline:color(C.good) + end +end + +-- Proves the kind field and that DMs/rooms reach an app at all, not just channels. +function app.on_message(m) + if not msgline then return end + msgline:set("on_message: kind=" .. tostring(m.kind) .. " from=" .. tostring(m.sender) .. + " ch=" .. tostring(m.channel) .. " text=" .. tostring(m.text):sub(1, 20)) + msgline:color(C.good) +end + +return app diff --git a/deploy/apps/wardrive/1.1/wardrive.json b/deploy/apps/wardrive/1.1/wardrive.json new file mode 100644 index 0000000..d467e18 --- /dev/null +++ b/deploy/apps/wardrive/1.1/wardrive.json @@ -0,0 +1 @@ +{"id":"wardrive","name":"Wardrive","ver":"1.1","desc":"LoRa coverage survey. Probes every 20s, logs each reply with GPS position, altitude and BOTH link directions to a CSV you can pull off the device. Reference app for wada.mesh.discover."} \ No newline at end of file diff --git a/deploy/apps/wardrive/1.1/wardrive.lua b/deploy/apps/wardrive/1.1/wardrive.lua new file mode 100644 index 0000000..a2f8377 --- /dev/null +++ b/deploy/apps/wardrive/1.1/wardrive.lua @@ -0,0 +1,216 @@ +-- Wardrive (Lua) — a LoRa coverage survey that logs to a CSV you can pull off +-- the device afterwards. +-- +-- Reference app for the discovery half of the SDK. It works the way a survey +-- has to work: it PROBES rather than listens. A probe is a zero-hop request +-- that every node in earshot answers, so a reply proves the link works from +-- exactly where you are standing. Listening only ever tells you what happened +-- to transmit while you were there, which is a different and much weaker claim. +-- +-- Each reply carries both directions of the link: how well we heard them, and +-- how well they heard us. They are rarely equal, and the asymmetry is the point +-- -- "I can hear the repeater but it cannot hear me" is not the same fact as +-- "no coverage", and only a probe reveals it. +local ui, sys, mesh, fs, timer = wada.ui, wada.sys, wada.mesh, wada.fs, wada.timer +local C = ui.colors +local app = {} + +local SWEEP_MS = 20000 -- above the 15 s floor the firmware enforces on probes +local HARVEST_MS = 4000 -- replies land over the few seconds after a probe +local TYPE = { [1]="chat", [2]="repeater", [3]="room", [4]="sensor" } + +local run, running, samples, sweeps, last_err = "run", false, 0, 0, nil +local node_count = 0 +local phase, phase_at = "idle", 0 +local hdr, gps_lbl, stat_lbl, rows = nil, nil, nil, {} +local nodes = {} -- pubkey -> { name, type, best, worst, seen } +local pending = {} -- lines waiting on the 1 write/sec limit + +local function logname() return run .. ".csv" end + +-- Return at most max_bytes without splitting a UTF-8 sequence. The row's +-- fixed-width columns are byte-budgeted, not character-budgeted; a raw +-- string.sub(1, 14) cut Ouderkerk + sun + VS16 inside the final codepoint and +-- left LVGL unable to advance through the label (#323, same class as #223). +local function utf8_prefix_bytes(text, max_bytes) + local offset, last, length = 1, 0, #text + while offset <= length and offset <= max_bytes do + local first = text:byte(offset) + local width = first <= 0x7F and 1 + or (first >= 0xC2 and first <= 0xDF and 2) + or (first >= 0xE0 and first <= 0xEF and 3) + or (first >= 0xF0 and first <= 0xF4 and 4) or 0 + if width == 0 or offset + width - 1 > length or offset + width - 1 > max_bytes then break end + local valid = true + for i = 2, width do + local byte = text:byte(offset + i - 1) + if byte < 0x80 or byte > 0xBF then valid = false; break end + end + local second = width > 1 and text:byte(offset + 1) or 0 + if (first == 0xE0 and second < 0xA0) or (first == 0xED and second > 0x9F) or + (first == 0xF0 and second < 0x90) or (first == 0xF4 and second > 0x8F) then valid = false end + if not valid then break end + last = offset + width - 1 + offset = last + 1 + end + return text:sub(1, last) +end + +-- Lua here is built with 32-bit floats, so fix.lat is good to about a metre and +-- no better. fix.lat_e6 is the same reading as an exact integer in +-- micro-degrees, which is what belongs in a log: a survey you plot months later +-- should not carry rounding the device never had. +local HEADER = "epoch,lat_e6,lon_e6,alt_m,pubkey,name,type,rssi,snr,their_snr,hops" +local wrote_header = false + +-- The filesystem allows one write a second. Sweeps produce a burst of rows, so +-- they queue here and drain a chunk per tick instead of being dropped. +local function flush() + if #pending == 0 then return end + local chunk = table.concat(pending, "\n") .. "\n" + if not wrote_header then chunk = HEADER .. "\n" .. chunk end + local ok = fs.append(logname(), chunk) + if ok then pending, wrote_header = {}, true end +end + +local function record(fix, hit) + local key = hit.pubkey + local n = nodes[key] + if not n then + n = { name = hit.name or key, type = hit.type, best = hit.snr, worst = hit.snr, seen = 0 } + nodes[key] = n + node_count = node_count + 1 + end + if hit.snr > n.best then n.best = hit.snr end + if hit.snr < n.worst then n.worst = hit.snr end + n.seen = n.seen + 1 + if hit.name then n.name = hit.name end + + samples = samples + 1 + pending[#pending + 1] = string.format("%d,%d,%d,%d,%s,%s,%d,%d,%.2f,%.2f,%d", + fix.time or sys.epoch(), fix.lat_e6, fix.lon_e6, fix.alt_m or 0, + key, (hit.name or ""):gsub(",", " "), hit.type, + hit.rssi, hit.snr, hit.their_snr, hit.hops) +end + +local function sweep() + local tag, err = mesh.discover() -- every node type + if not tag then last_err = err; return false end + last_err = nil + sweeps = sweeps + 1 + return true +end + +local function harvest() + local fix = sys.gps() + if not fix then + -- No fix means the sample cannot be placed, so it is discarded rather than + -- logged at 0,0. A survey file with phantom points at Null Island is worse + -- than a shorter one. + mesh.discover_clear() + return + end + for _, hit in ipairs(mesh.discovered()) do record(fix, hit) end + mesh.discover_clear() -- next sample must not inherit this one +end + +local function redraw() + local fix = sys.gps() + if fix then + gps_lbl:set(string.format("%.5f, %.5f %dm %d sats", fix.lat, fix.lon, fix.alt_m or 0, fix.sats)) + gps_lbl:color(C.good) + else + gps_lbl:set("waiting for a GPS fix - samples are discarded until then") + gps_lbl:color(C.bad) + end + + local state = running and (phase == "probe" and "listening..." or "sweeping") or "stopped" + stat_lbl:set(string.format("%s | %s | %d sweeps, %d samples, %d nodes%s", + run, state, sweeps, samples, node_count, + last_err and (" [" .. last_err .. "]") or "")) + stat_lbl:color(last_err and C.bad or C.accent) + + local list = {} + for key, n in pairs(nodes) do list[#list + 1] = { key = key, n = n } end + table.sort(list, function(a, b) return a.n.best > b.n.best end) + for i = 1, #rows do + local e = list[i] + if e then + rows[i]:set(string.format("%-14s %-8s best %5.1f worst %5.1f x%d", + utf8_prefix_bytes(e.n.name, 14), TYPE[e.n.type] or "?", e.n.best, e.n.worst, e.n.seen)) + rows[i]:color(e.n.best > 0 and C.good or C.text) + else + rows[i]:set(i == 1 and "nothing has answered a probe yet" or "") + rows[i]:color(C.sub) + end + end +end + +function app.on_open(w, h) + if not sys.caps().discover then + ui.label("This board does not carry the extended SDK,", 6, 8, 12, C.bad) + ui.label("so it cannot send discovery probes.", 6, 26, 12, C.bad) + return + end + ui.scroll(true) + local LH = ui.text_h(12) + local y = 4 + + hdr = ui.label("LoRa coverage survey", 4, y, 12, C.accent); hdr:width(w - 10); y = y + LH + 3 + gps_lbl = ui.label("", 4, y, 12, C.sub); gps_lbl:width(w - 10); y = y + LH + 3 + stat_lbl = ui.label("", 4, y, 12, C.text); stat_lbl:width(w - 10); y = y + LH * 2 + 5 + + local bw = math.min(96, (w - 20) // 3) + ui.button("Start", 4, y, bw, 32, function() + running = not running + if running then phase, phase_at = "idle", 0 end + sys.toast(running and "Survey running" or "Survey stopped", 1200) + end) + ui.button("Name", 8 + bw, y, bw, 32, function() + ui.input("Name this run", run, function(text) + if text then + run = text:gsub("[^%w%-_]", "_") + wrote_header = false -- a new file needs its own header row + sys.toast("Logging to " .. logname(), 1500) + end + end) + end) + ui.button("Reset", 12 + bw * 2, y, bw, 32, function() + nodes, samples, sweeps, pending, node_count = {}, 0, 0, {}, 0 + mesh.discover_clear() + fs.remove(logname()) + wrote_header = false + sys.toast("Cleared " .. logname(), 1200) + end) + y = y + 38 + + ui.label("strongest first", 4, y, 12, C.sub); y = y + LH + 2 + for i = 1, 12 do + rows[i] = ui.label("", 4, y, 12, C.text); rows[i]:width(w - 10); y = y + LH + 2 + end + + redraw() + timer.every(1000) +end + +function app.on_tick() + if running then + local now = sys.millis() + if phase == "idle" or (phase == "wait" and now - phase_at >= SWEEP_MS) then + -- A refused or rate-limited probe backs off a full sweep interval. Retrying + -- every tick would re-enter the permission path once a second for nothing. + phase, phase_at = sweep() and "probe" or "wait", now + elseif phase == "probe" and now - phase_at >= HARVEST_MS then + harvest() + phase = "wait" -- phase_at stays at the probe time, so sweeps stay on cadence + end + end + flush() + redraw() +end + +function app.on_close() + flush() -- one last drain; anything queued would otherwise be lost +end + +return app diff --git a/deploy/site/sdk.html b/deploy/site/sdk.html index 6e66ce6..0defa3b 100644 --- a/deploy/site/sdk.html +++ b/deploy/site/sdk.html @@ -141,6 +141,7 @@ wada.net wada.store wada.fs + wada.audio wada.sd wada.sys wada.timer @@ -237,6 +238,7 @@ return app wada.ui.button(text, x, y, w, h, fn)A tappable button at x, y sized w × h; fn is called with no arguments. wada.ui.text_w(text [, size])Rendered width of text in pixels, for the given size class. wada.ui.text_lines(text, width [, size])How many lines text wraps to inside width. Counts explicit newlines too. Use this when you lay out your own rows. label:width() turns wrapping on, so a line longer than the screen becomes two while a fixed y step still advances by one, and the next row is drawn on top of it. This is the single most common way an app's layout goes wrong; it happened to the SDK Test app's channel list. + wada.ui.clear()Remove every widget from the app's page, leaving the page itself. This is how you build an app with more than one screen: clear, then create the next screen's widgets in the same place you built the first. Any handle you still hold from before the clear is dead — calling a method on it does nothing rather than crashing, but it will not come back, so re-create and re-assign. Older firmware has no ui.clear: write local clear = ui.clear or function() end if you need to run on both. wada.ui.list(x, y, w, h)A scrollable list of selectable rows — the "pick one of N" widget. Methods: add(text [, fn]) returning the row index, set(i, text), color(i, c), select(i) (highlights and scrolls it into view), selected(), count(), clear(), pos(x, y). Rows are real buttons, so keyboard and trackball navigation walks them on touchless boards without you doing anything. wada.ui.input(title, initial, cb)A modal text field. cb(text) on OK, cb(nil) on cancel or on the dialog being closed any other way — exactly one call, always, so an app that disabled itself while waiting always gets to re-enable. Uses the firmware's own dialog and keyboard, so it behaves identically on a touchscreen, on the Tanmatsu's physical keyboard and on a trackball board. One prompt at a time. wada.ui.canvas(w, h)A drawing surface. See the canvas methods below. @@ -291,7 +293,8 @@ return app

wada.mesh

- + + @@ -409,7 +412,7 @@ end
wada.mesh.contacts()Array of {name, pubkey, type, ago_s, lat, lon, lat_e6, lon_e6}. pubkey is the first 4 bytes as 8 hex characters — the same short form the rest of the interface uses, and what lines a contact up with a discovery hit.
wada.mesh.contacts([offset], [limit])Array of {name, pubkey, type, ago_s, lat, lon, lat_e6, lon_e6}. pubkey is the first 4 bytes as 8 hex characters — the same short form the rest of the interface uses, and what lines a contact up with a discovery hit. Returns at most limit entries (default 100, maximum 250) starting at offset, because every entry is an eight-field table and building thousands in one call would exhaust the app heap. On a device with more contacts than that, page through them: ask for 100, then 100 from offset 100, and so on.
wada.mesh.contact_count()How many contacts the device holds, so you can page through contacts() without calling it repeatedly to find where the list ends.
wada.mesh.rx_log()Recent packets, newest first: {ago_ms, type, rssi, snr, hops, route, len}, plus whatever identity the frame actually carried — see below. The RF Monitor feed.
wada.mesh.stats(){rssi, noise, rx_air_s, tx_air_s, rx_pkts, rx_err, tx_budget_ms, rx_events, rx_dropped, tx_pkts, freq, bw, sf, duty_pct}.
wada.mesh.self()This node: {name, pubkey, lat, lon, lat_e6, lon_e6}.

http:// only, both of them. On-device TLS is not workable at the heap these boards have left once Wi-Fi has associated, so there is no https to offer; put a proxy in front if you need it. One request in flight at a time per app.

The fetch is asynchronous and runs on the firmware's existing network worker, so it does not block the UI. Your callback runs on the UI thread once the body is in memory.

-

Plain HTTP only, and that is not an oversight. After Wi-Fi associates there is not enough free internal memory on the smaller boards for a TLS handshake — mbedTLS wants around 30 KB and roughly 5 KB is free. If you need an HTTPS source, put a small proxy in front of it, the way the map tiles do. Responses are capped (64 KB by default).

+

Plain HTTP only, and that is not an oversight. After Wi-Fi associates there is not enough free internal memory on the smaller boards for a TLS handshake — mbedTLS wants around 30 KB and roughly 5 KB is free. If you need an HTTPS source, put a small proxy in front of it, the way the map tiles do. Responses are capped (192 KB by default).

@@ -441,6 +444,24 @@ end +
+

wada.audio audio

+
+

Asynchronous audio playback from the current app's private storage. A plain name such as track.wav resolves inside the same app folder as wada.fs, whether that folder lives on internal flash, SD, or SD_MMC. Check wada.sys.caps().audio and audio_wav before using it.

+ + + + + + + +
CallReturns / does
wada.audio.play(name)Starts or replaces playback and returns true, or nil, error. Plain names use app-private storage. On boards with caps().audio_sd, sd:/Music/track.wav reads directly from the physical card.
wada.audio.pause()Pauses an active track. Returns whether the command was accepted.
wada.audio.resume()Resumes a paused track. Returns whether the command was accepted.
wada.audio.stop()Stops the active track. Returns whether the command was accepted.
wada.audio.status(){state, path, source, format, error}. State is stopped, playing, paused, ended, or error; error is present only after a playback failure.
+

Supported formats are PCM WAV (16-bit mono or stereo at 8–48 kHz) and MPEG Layer III MP3, including CBR, VBR, and ID3-tagged files. Stereo is mixed to mono on the device. Check audio_wav or audio_mp3 rather than assuming a format exists on older firmware.

+

Playback follows the user's Sound switch and volume, never blocks the Lua callback, and stops automatically when the app closes. A second play() replaces the current track. Playlist ordering belongs to the app, so there are no ambiguous host-side next() or previous() calls.

+

Plain names follow the same sandbox rules as wada.fs. Explicit sd: paths follow wada.sd path validation. Expected errors include bad path, no storage, no sd, not found, busy, muted, and unsupported format.

+
+
+

wada.sd sd_list

@@ -466,7 +487,7 @@ end wada.sys.datetime(){year, month, day, hour, min, sec, wday} in local time. wday is 0 for Sunday. wada.sys.tr(s)Translate s through the device's active language, using the same table the firmware's own interface uses. Returns s unchanged when there is no translation, so it is always safe to wrap a string. Add your keys to deploy/apps/lang/<code>.lang alongside the firmware's. Older firmware has no sys.tr: write local tr = sys.tr or function(x) return x end and call tr(). wada.sys.beep()Short beep on boards with a buzzer; silent elsewhere, and silent when the user has sound off. - wada.sys.caps(){sdk_ext, keyboard, touch, sd, sd_list, compass, accel, discover, input, rx_identity, list, packets, sensors, map, measure}. Check sdk_ext before using anything marked ext below, and sd_list before using wada.sd. The rest are feature flags for calls added after the extended SDK first shipped, so an app can degrade on older firmware instead of erroring. + wada.sys.caps(){sdk_ext, keyboard, touch, sd, sd_list, audio, audio_wav, audio_mp3, audio_sd, compass, accel, discover, input, rx_identity, list, packets, sensors, map, measure}. Check sdk_ext before using anything marked ext, sd_list before using wada.sd, and audio plus the format flag before using wada.audio. audio_sd means direct sd: paths are available; plain audio names use app storage and do not require it. wada.sys.battery() ext{mv, pct, charging}. wada.sys.env() sensors{temp_c, humidity, pressure_hpa, alt_m}, or nil. A field is present only when the hardware actually reported it, so you can tell "no humidity sensor" from "0% humidity". Gated on caps().sensors — does this board have the sensor rail — and not on sdk_ext, which is a memory gate. Those are different questions: the plain Heltec V4 has the Expansion Kit but not the extended SDK, and most boards with the extended SDK have no sensors at all. wada.sys.gps() ext{lat, lon, lat_e6, lon_e6, sats, alt_m, time, speed_kmh, course}, or nil with no fix — which is the normal indoor case, so handle it. lat_e6/lon_e6 are exact micro-degrees; lat/lon are single-precision floats, so log the integers. alt_m is metres. time is satellite time, absent until the receiver has decoded the date. speed_kmh and course (degrees clockwise from north) appear only on boards whose GPS provider reports them, and course only while actually moving — a stationary receiver has no course, so it is absent rather than 0. Treat those last three as optional. @@ -587,7 +608,7 @@ end

Apps run in a restricted environment. These are removed: io, os, require, dofile, and loading new chunks at runtime. Available: math, string, table, and the usual pairs, ipairs, select, pcall, tostring, tonumber.

Memory comes from a capped pool in PSRAM, so an app that allocates without bound fails its own allocation rather than starving the radio or the UI. There is an instruction budget on every callback for the same reason.

-

The extended calls are not on every board. Anything marked ext above — wada.fs, wada.mesh.send, wada.mesh.send_dm, wada.mesh.discover, sys.battery, sys.gps — needs a board with the memory to carry it, so the Heltec V4 keeps its RAM for the mesh instead. Call wada.sys.caps().sdk_ext and degrade gracefully rather than assuming. wada.sd additionally needs a physical card interface, reported by caps().sd_list.

+

The extended calls are not on every board. Anything marked ext above — wada.fs, wada.mesh.send, wada.mesh.send_dm, wada.mesh.discover, sys.battery, sys.gps — needs a board with the memory to carry it, so the Heltec V4 keeps its RAM for the mesh instead. Call wada.sys.caps().sdk_ext and degrade gracefully rather than assuming. wada.sd additionally needs a physical card interface, reported by caps().sd_list. wada.audio instead follows caps().audio: storage may be internal, but the device still needs a stream-capable speaker path.

Rate limits are part of the contract, not a rainy-day guard: wada.fs writes are about one per second with a 32 KB file cap, and wada.mesh.send has a 5 second floor and a 180-character limit. They return false, "too fast" rather than throwing, and hitting them is expected — handle it.

None of this makes a hostile app safe, which is why the catalog is curated. It makes an honest app that has a bug survivable: it gets closed, and the device keeps carrying traffic.

diff --git a/include/lv_conf.h b/include/lv_conf.h index 4c330f7..8808621 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -61,6 +61,13 @@ #define LV_FONT_MONTSERRAT_20 1 #define LV_FONT_MONTSERRAT_24 1 #endif +/* T-Deck-only, unrelated to the Large/Huge UI-scale block above: an experiment + * to shrink the "at a glance" notification's message body from 28px to 20px + * on this board only (see atGlanceEnsureFont() in UITask.cpp). Easy to revert + * by dropping this block + the T-Deck branch in atGlanceEnsureFont(). */ +#if defined(HAS_TDECK_GT911) +#define LV_FONT_MONTSERRAT_20 1 +#endif /* 28 px Montserrat for the boot splash title — keeps the rest of the UI on * the smaller fonts so the .data cost stays modest. */ #define LV_FONT_MONTSERRAT_28 1 diff --git a/include/lv_conf_m9.h b/include/lv_conf_m9.h new file mode 100644 index 0000000..db9237a --- /dev/null +++ b/include/lv_conf_m9.h @@ -0,0 +1,25 @@ +#pragma once + +// M9-specific LVGL config wrapper. +// +// Why this exists: +// - LVGL 8.4's lv_hal_indev.h unconditionally defines LV_INDEV_DEF_SCROLL_*. +// - Our shared lv_conf defines LV_INDEV_DEF_SCROLL_LIMIT for touch tuning, and +// M9's build flags define LV_INDEV_DEF_SCROLL_THROW. That combination emits +// macro-redefinition warnings, even though M9 has no touch input path. +// +// For M9, include the shared project LV config, then drop touch-scroll tuning +// macros so LVGL's keypad-only defaults can apply without warnings. +#ifndef LV_CONF_H +#define LV_CONF_H +#endif + +#include "lv_conf.h" + +#ifdef LV_INDEV_DEF_SCROLL_LIMIT +#undef LV_INDEV_DEF_SCROLL_LIMIT +#endif + +#ifdef LV_INDEV_DEF_SCROLL_THROW +#undef LV_INDEV_DEF_SCROLL_THROW +#endif diff --git a/lib/minimp3/LICENSE b/lib/minimp3/LICENSE new file mode 100644 index 0000000..2c4afab --- /dev/null +++ b/lib/minimp3/LICENSE @@ -0,0 +1,117 @@ +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + + diff --git a/lib/minimp3/README.md b/lib/minimp3/README.md new file mode 100644 index 0000000..7fbdc38 --- /dev/null +++ b/lib/minimp3/README.md @@ -0,0 +1,16 @@ +# minimp3 + +This directory vendors `minimp3.h` from +[lieff/minimp3](https://github.com/lieff/minimp3) at commit +`ea99364f61c14656440e8d77e9c233ccf3124633` under CC0-1.0. + +Pinned upstream and local file hashes: + +- upstream `minimp3.h`: `57e437c5c1f0e8b243885d3929c8973b5e6c778451e0100ab4251d19915cb3ad` +- local `minimp3.h` with the hook below: `3f59a7f29de636ca0db0aab8a5b86739c43ac8bf9ac902010e7220f783c0ae0a` +- `LICENSE`: `6a1ee543e5282cd9061881edf462e6fdab181f328da71fc2c9a6950a80e94d01` + +Wadamesh adds one opt-in `MINIMP3_SCRATCH` hook around the decoder's local +scratch object. The Lua audio worker uses it to place the roughly 16 KB decoder +workspace in PSRAM instead of its FreeRTOS task stack. Builds that do not define +the hook retain upstream behavior. diff --git a/lib/minimp3/minimp3.h b/lib/minimp3/minimp3.h new file mode 100644 index 0000000..ffab423 --- /dev/null +++ b/lib/minimp3/minimp3.h @@ -0,0 +1,1872 @@ +#ifndef MINIMP3_H +#define MINIMP3_H +/* + https://github.com/lieff/minimp3 + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. + This software is distributed without any warranty. + See . +*/ +#include + +#define MINIMP3_MAX_SAMPLES_PER_FRAME (1152*2) + +typedef struct +{ + int frame_bytes, frame_offset, channels, hz, layer, bitrate_kbps; +} mp3dec_frame_info_t; + +typedef struct +{ + float mdct_overlap[2][9*32], qmf_state[15*2*32]; + int reserv, free_format_bytes; + unsigned char header[4], reserv_buf[511]; +} mp3dec_t; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void mp3dec_init(mp3dec_t *dec); +#ifndef MINIMP3_FLOAT_OUTPUT +typedef int16_t mp3d_sample_t; +#else /* MINIMP3_FLOAT_OUTPUT */ +typedef float mp3d_sample_t; +void mp3dec_f32_to_s16(const float *in, int16_t *out, int num_samples); +#endif /* MINIMP3_FLOAT_OUTPUT */ +int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* MINIMP3_H */ +#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_IMPLEMENTATION_GUARD) +#define _MINIMP3_IMPLEMENTATION_GUARD + +#include +#include + +#define MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ +#ifndef MAX_FRAME_SYNC_MATCHES +#define MAX_FRAME_SYNC_MATCHES 10 +#endif /* MAX_FRAME_SYNC_MATCHES */ + +#define MAX_L3_FRAME_PAYLOAD_BYTES MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ + +#define MAX_BITRESERVOIR_BYTES 511 +#define SHORT_BLOCK_TYPE 2 +#define STOP_BLOCK_TYPE 3 +#define MODE_MONO 3 +#define MODE_JOINT_STEREO 1 +#define HDR_SIZE 4 +#define HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0) +#define HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60) +#define HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0) +#define HDR_IS_CRC(h) (!((h[1]) & 1)) +#define HDR_TEST_PADDING(h) ((h[2]) & 0x2) +#define HDR_TEST_MPEG1(h) ((h[1]) & 0x8) +#define HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10) +#define HDR_TEST_I_STEREO(h) ((h[3]) & 0x10) +#define HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20) +#define HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3) +#define HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3) +#define HDR_GET_LAYER(h) (((h[1]) >> 1) & 3) +#define HDR_GET_BITRATE(h) ((h[2]) >> 4) +#define HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3) +#define HDR_GET_MY_SAMPLE_RATE(h) (HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3) +#define HDR_IS_FRAME_576(h) ((h[1] & 14) == 2) +#define HDR_IS_LAYER_1(h) ((h[1] & 6) == 6) + +#define BITS_DEQUANTIZER_OUT -1 +#define MAX_SCF (255 + BITS_DEQUANTIZER_OUT*4 - 210) +#define MAX_SCFI ((MAX_SCF + 3) & ~3) + +#define MINIMP3_MIN(a, b) ((a) > (b) ? (b) : (a)) +#define MINIMP3_MAX(a, b) ((a) < (b) ? (b) : (a)) + +#if !defined(MINIMP3_NO_SIMD) + +#if !defined(MINIMP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64)) +/* x64 always have SSE2, arm64 always have neon, no need for generic code */ +#define MINIMP3_ONLY_SIMD +#endif /* SIMD checks... */ + +#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__)) +#if defined(_MSC_VER) +#include +#endif /* defined(_MSC_VER) */ +#include +#define HAVE_SSE 1 +#define HAVE_SIMD 1 +#define VSTORE _mm_storeu_ps +#define VLD _mm_loadu_ps +#define VSET _mm_set1_ps +#define VADD _mm_add_ps +#define VSUB _mm_sub_ps +#define VMUL _mm_mul_ps +#define VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y)) +#define VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y)) +#define VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) +#define VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) +typedef __m128 f4; +#if defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) +#define minimp3_cpuid __cpuid +#else /* defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) */ +static __inline__ __attribute__((always_inline)) void minimp3_cpuid(int CPUInfo[], const int InfoType) +{ +#if defined(__PIC__) + __asm__ __volatile__( +#if defined(__x86_64__) + "push %%rbx\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + "pop %%rbx\n" +#else /* defined(__x86_64__) */ + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" +#endif /* defined(__x86_64__) */ + : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#else /* defined(__PIC__) */ + __asm__ __volatile__( + "cpuid" + : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#endif /* defined(__PIC__)*/ +} +#endif /* defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) */ +static int have_simd(void) +{ +#ifdef MINIMP3_ONLY_SIMD + return 1; +#else /* MINIMP3_ONLY_SIMD */ + static int g_have_simd; + int CPUInfo[4]; +#ifdef MINIMP3_TEST + static int g_counter; + if (g_counter++ > 100) + return 0; +#endif /* MINIMP3_TEST */ + if (g_have_simd) + goto end; + minimp3_cpuid(CPUInfo, 0); + g_have_simd = 1; + if (CPUInfo[0] > 0) + { + minimp3_cpuid(CPUInfo, 1); + g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */ + } +end: + return g_have_simd - 1; +#endif /* MINIMP3_ONLY_SIMD */ +} +#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) +#include +#define HAVE_SSE 0 +#define HAVE_SIMD 1 +#define VSTORE vst1q_f32 +#define VLD vld1q_f32 +#define VSET vmovq_n_f32 +#define VADD vaddq_f32 +#define VSUB vsubq_f32 +#define VMUL vmulq_f32 +#define VMAC(a, x, y) vmlaq_f32(a, x, y) +#define VMSB(a, x, y) vmlsq_f32(a, x, y) +#define VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s)) +#define VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x))) +typedef float32x4_t f4; +static int have_simd() +{ /* TODO: detect neon for !MINIMP3_ONLY_SIMD */ + return 1; +} +#else /* SIMD checks... */ +#define HAVE_SSE 0 +#define HAVE_SIMD 0 +#ifdef MINIMP3_ONLY_SIMD +#error MINIMP3_ONLY_SIMD used, but SSE/NEON not enabled +#endif /* MINIMP3_ONLY_SIMD */ +#endif /* SIMD checks... */ +#else /* !defined(MINIMP3_NO_SIMD) */ +#define HAVE_SIMD 0 +#endif /* !defined(MINIMP3_NO_SIMD) */ + +#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__) +#define HAVE_ARMV6 1 +static __inline__ __attribute__((always_inline)) int32_t minimp3_clip_int16_arm(int32_t a) +{ + int32_t x = 0; + __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a)); + return x; +} +#else +#define HAVE_ARMV6 0 +#endif + +typedef struct +{ + const uint8_t *buf; + int pos, limit; +} bs_t; + +typedef struct +{ + float scf[3*64]; + uint8_t total_bands, stereo_bands, bitalloc[64], scfcod[64]; +} L12_scale_info; + +typedef struct +{ + uint8_t tab_offset, code_tab_width, band_count; +} L12_subband_alloc_t; + +typedef struct +{ + const uint8_t *sfbtab; + uint16_t part_23_length, big_values, scalefac_compress; + uint8_t global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; + uint8_t table_select[3], region_count[3], subblock_gain[3]; + uint8_t preflag, scalefac_scale, count1_table, scfsi; +} L3_gr_info_t; + +typedef struct +{ + bs_t bs; + uint8_t maindata[MAX_BITRESERVOIR_BYTES + MAX_L3_FRAME_PAYLOAD_BYTES]; + L3_gr_info_t gr_info[4]; + float grbuf[2][576], scf[40], syn[18 + 15][2*32]; + uint8_t ist_pos[2][39]; +} mp3dec_scratch_t; + +static void bs_init(bs_t *bs, const uint8_t *data, int bytes) +{ + bs->buf = data; + bs->pos = 0; + bs->limit = bytes*8; +} + +static uint32_t get_bits(bs_t *bs, int n) +{ + uint32_t next, cache = 0, s = bs->pos & 7; + int shl = n + s; + const uint8_t *p = bs->buf + (bs->pos >> 3); + if ((bs->pos += n) > bs->limit) + return 0; + next = *p++ & (255 >> s); + while ((shl -= 8) > 0) + { + cache |= next << shl; + next = *p++; + } + return cache | (next >> -shl); +} + +static int hdr_valid(const uint8_t *h) +{ + return h[0] == 0xff && + ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) && + (HDR_GET_LAYER(h) != 0) && + (HDR_GET_BITRATE(h) != 15) && + (HDR_GET_SAMPLE_RATE(h) != 3); +} + +static int hdr_compare(const uint8_t *h1, const uint8_t *h2) +{ + return hdr_valid(h2) && + ((h1[1] ^ h2[1]) & 0xFE) == 0 && + ((h1[2] ^ h2[2]) & 0x0C) == 0 && + !(HDR_IS_FREE_FORMAT(h1) ^ HDR_IS_FREE_FORMAT(h2)); +} + +static unsigned hdr_bitrate_kbps(const uint8_t *h) +{ + static const uint8_t halfrate[2][3][15] = { + { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } }, + { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } }, + }; + return 2*halfrate[!!HDR_TEST_MPEG1(h)][HDR_GET_LAYER(h) - 1][HDR_GET_BITRATE(h)]; +} + +static unsigned hdr_sample_rate_hz(const uint8_t *h) +{ + static const unsigned g_hz[3] = { 44100, 48000, 32000 }; + return g_hz[HDR_GET_SAMPLE_RATE(h)] >> (int)!HDR_TEST_MPEG1(h) >> (int)!HDR_TEST_NOT_MPEG25(h); +} + +static unsigned hdr_frame_samples(const uint8_t *h) +{ + return HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)HDR_IS_FRAME_576(h)); +} + +static int hdr_frame_bytes(const uint8_t *h, int free_format_size) +{ + int frame_bytes = hdr_frame_samples(h)*hdr_bitrate_kbps(h)*125/hdr_sample_rate_hz(h); + if (HDR_IS_LAYER_1(h)) + { + frame_bytes &= ~3; /* slot align */ + } + return frame_bytes ? frame_bytes : free_format_size; +} + +static int hdr_padding(const uint8_t *h) +{ + return HDR_TEST_PADDING(h) ? (HDR_IS_LAYER_1(h) ? 4 : 1) : 0; +} + +#ifndef MINIMP3_ONLY_MP3 +static const L12_subband_alloc_t *L12_subband_alloc_table(const uint8_t *hdr, L12_scale_info *sci) +{ + const L12_subband_alloc_t *alloc; + int mode = HDR_GET_STEREO_MODE(hdr); + int nbands, stereo_bands = (mode == MODE_MONO) ? 0 : (mode == MODE_JOINT_STEREO) ? (HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32; + + if (HDR_IS_LAYER_1(hdr)) + { + static const L12_subband_alloc_t g_alloc_L1[] = { { 76, 4, 32 } }; + alloc = g_alloc_L1; + nbands = 32; + } else if (!HDR_TEST_MPEG1(hdr)) + { + static const L12_subband_alloc_t g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } }; + alloc = g_alloc_L2M2; + nbands = 30; + } else + { + static const L12_subband_alloc_t g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } }; + int sample_rate_idx = HDR_GET_SAMPLE_RATE(hdr); + unsigned kbps = hdr_bitrate_kbps(hdr) >> (int)(mode != MODE_MONO); + if (!kbps) /* free-format */ + { + kbps = 192; + } + + alloc = g_alloc_L2M1; + nbands = 27; + if (kbps < 56) + { + static const L12_subband_alloc_t g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } }; + alloc = g_alloc_L2M1_lowrate; + nbands = sample_rate_idx == 2 ? 12 : 8; + } else if (kbps >= 96 && sample_rate_idx != 1) + { + nbands = 30; + } + } + + sci->total_bands = (uint8_t)nbands; + sci->stereo_bands = (uint8_t)MINIMP3_MIN(stereo_bands, nbands); + + return alloc; +} + +static void L12_read_scalefactors(bs_t *bs, uint8_t *pba, uint8_t *scfcod, int bands, float *scf) +{ + static const float g_deq_L12[18*3] = { +#define DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x + DQ(3),DQ(7),DQ(15),DQ(31),DQ(63),DQ(127),DQ(255),DQ(511),DQ(1023),DQ(2047),DQ(4095),DQ(8191),DQ(16383),DQ(32767),DQ(65535),DQ(3),DQ(5),DQ(9) + }; + int i, m; + for (i = 0; i < bands; i++) + { + float s = 0; + int ba = *pba++; + int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0; + for (m = 4; m; m >>= 1) + { + if (mask & m) + { + int b = get_bits(bs, 6); + s = g_deq_L12[ba*3 - 6 + b % 3]*(1 << 21 >> b/3); + } + *scf++ = s; + } + } +} + +static void L12_read_scale_info(const uint8_t *hdr, bs_t *bs, L12_scale_info *sci) +{ + static const uint8_t g_bitalloc_code_tab[] = { + 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16, + 0,17,18, 3,19,4,5,16, + 0,17,18,16, + 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14, + 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16 + }; + const L12_subband_alloc_t *subband_alloc = L12_subband_alloc_table(hdr, sci); + + int i, k = 0, ba_bits = 0; + const uint8_t *ba_code_tab = g_bitalloc_code_tab; + + for (i = 0; i < sci->total_bands; i++) + { + uint8_t ba; + if (i == k) + { + k += subband_alloc->band_count; + ba_bits = subband_alloc->code_tab_width; + ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset; + subband_alloc++; + } + ba = ba_code_tab[get_bits(bs, ba_bits)]; + sci->bitalloc[2*i] = ba; + if (i < sci->stereo_bands) + { + ba = ba_code_tab[get_bits(bs, ba_bits)]; + } + sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0; + } + + for (i = 0; i < 2*sci->total_bands; i++) + { + sci->scfcod[i] = sci->bitalloc[i] ? HDR_IS_LAYER_1(hdr) ? 2 : get_bits(bs, 2) : 6; + } + + L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf); + + for (i = sci->stereo_bands; i < sci->total_bands; i++) + { + sci->bitalloc[2*i + 1] = 0; + } +} + +static int L12_dequantize_granule(float *grbuf, bs_t *bs, L12_scale_info *sci, int group_size) +{ + int i, j, k, choff = 576; + for (j = 0; j < 4; j++) + { + float *dst = grbuf + group_size*j; + for (i = 0; i < 2*sci->total_bands; i++) + { + int ba = sci->bitalloc[i]; + if (ba != 0) + { + if (ba < 17) + { + int half = (1 << (ba - 1)) - 1; + for (k = 0; k < group_size; k++) + { + dst[k] = (float)((int)get_bits(bs, ba) - half); + } + } else + { + unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */ + unsigned code = get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */ + for (k = 0; k < group_size; k++, code /= mod) + { + dst[k] = (float)((int)(code % mod - mod/2)); + } + } + } + dst += choff; + choff = 18 - choff; + } + } + return group_size*4; +} + +static void L12_apply_scf_384(L12_scale_info *sci, const float *scf, float *dst) +{ + int i, k; + memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); + for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6) + { + for (k = 0; k < 12; k++) + { + dst[k + 0] *= scf[0]; + dst[k + 576] *= scf[3]; + } + } +} +#endif /* MINIMP3_ONLY_MP3 */ + +static int L3_read_side_info(bs_t *bs, L3_gr_info_t *gr, const uint8_t *hdr) +{ + static const uint8_t g_scf_long[8][23] = { + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 }, + { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 }, + { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 } + }; + static const uint8_t g_scf_short[8][40] = { + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + static const uint8_t g_scf_mixed[8][40] = { + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + + unsigned tables, scfsi = 0; + int main_data_begin, part_23_sum = 0; + int sr_idx = HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0); + int gr_count = HDR_IS_MONO(hdr) ? 1 : 2; + + if (HDR_TEST_MPEG1(hdr)) + { + gr_count *= 2; + main_data_begin = get_bits(bs, 9); + scfsi = get_bits(bs, 7 + gr_count); + } else + { + main_data_begin = get_bits(bs, 8 + gr_count) >> gr_count; + } + + do + { + if (HDR_IS_MONO(hdr)) + { + scfsi <<= 4; + } + gr->part_23_length = (uint16_t)get_bits(bs, 12); + part_23_sum += gr->part_23_length; + gr->big_values = (uint16_t)get_bits(bs, 9); + if (gr->big_values > 288) + { + return -1; + } + gr->global_gain = (uint8_t)get_bits(bs, 8); + gr->scalefac_compress = (uint16_t)get_bits(bs, HDR_TEST_MPEG1(hdr) ? 4 : 9); + gr->sfbtab = g_scf_long[sr_idx]; + gr->n_long_sfb = 22; + gr->n_short_sfb = 0; + if (get_bits(bs, 1)) + { + gr->block_type = (uint8_t)get_bits(bs, 2); + if (!gr->block_type) + { + return -1; + } + gr->mixed_block_flag = (uint8_t)get_bits(bs, 1); + gr->region_count[0] = 7; + gr->region_count[1] = 255; + if (gr->block_type == SHORT_BLOCK_TYPE) + { + scfsi &= 0x0F0F; + if (!gr->mixed_block_flag) + { + gr->region_count[0] = 8; + gr->sfbtab = g_scf_short[sr_idx]; + gr->n_long_sfb = 0; + gr->n_short_sfb = 39; + } else + { + gr->sfbtab = g_scf_mixed[sr_idx]; + gr->n_long_sfb = HDR_TEST_MPEG1(hdr) ? 8 : 6; + gr->n_short_sfb = 30; + } + } + tables = get_bits(bs, 10); + tables <<= 5; + gr->subblock_gain[0] = (uint8_t)get_bits(bs, 3); + gr->subblock_gain[1] = (uint8_t)get_bits(bs, 3); + gr->subblock_gain[2] = (uint8_t)get_bits(bs, 3); + } else + { + gr->block_type = 0; + gr->mixed_block_flag = 0; + tables = get_bits(bs, 15); + gr->region_count[0] = (uint8_t)get_bits(bs, 4); + gr->region_count[1] = (uint8_t)get_bits(bs, 3); + gr->region_count[2] = 255; + } + gr->table_select[0] = (uint8_t)(tables >> 10); + gr->table_select[1] = (uint8_t)((tables >> 5) & 31); + gr->table_select[2] = (uint8_t)((tables) & 31); + gr->preflag = HDR_TEST_MPEG1(hdr) ? get_bits(bs, 1) : (gr->scalefac_compress >= 500); + gr->scalefac_scale = (uint8_t)get_bits(bs, 1); + gr->count1_table = (uint8_t)get_bits(bs, 1); + gr->scfsi = (uint8_t)((scfsi >> 12) & 15); + scfsi <<= 4; + gr++; + } while(--gr_count); + + if (part_23_sum + bs->pos > bs->limit + main_data_begin*8) + { + return -1; + } + + return main_data_begin; +} + +static void L3_read_scalefactors(uint8_t *scf, uint8_t *ist_pos, const uint8_t *scf_size, const uint8_t *scf_count, bs_t *bitbuf, int scfsi) +{ + int i, k; + for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2) + { + int cnt = scf_count[i]; + if (scfsi & 8) + { + memcpy(scf, ist_pos, cnt); + } else + { + int bits = scf_size[i]; + if (!bits) + { + memset(scf, 0, cnt); + memset(ist_pos, 0, cnt); + } else + { + int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1; + for (k = 0; k < cnt; k++) + { + int s = get_bits(bitbuf, bits); + ist_pos[k] = (s == max_scf ? -1 : s); + scf[k] = s; + } + } + } + ist_pos += cnt; + scf += cnt; + } + scf[0] = scf[1] = scf[2] = 0; +} + +static float L3_ldexp_q2(float y, int exp_q2) +{ + static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f }; + int e; + do + { + e = MINIMP3_MIN(30*4, exp_q2); + y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2)); + } while ((exp_q2 -= e) > 0); + return y; +} + +static void L3_decode_scalefactors(const uint8_t *hdr, uint8_t *ist_pos, bs_t *bs, const L3_gr_info_t *gr, float *scf, int ch) +{ + static const uint8_t g_scf_partitions[3][28] = { + { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 }, + { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 }, + { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 } + }; + const uint8_t *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb]; + uint8_t scf_size[4], iscf[40]; + int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi; + float gain; + + if (HDR_TEST_MPEG1(hdr)) + { + static const uint8_t g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 }; + int part = g_scfc_decode[gr->scalefac_compress]; + scf_size[1] = scf_size[0] = (uint8_t)(part >> 2); + scf_size[3] = scf_size[2] = (uint8_t)(part & 3); + } else + { + static const uint8_t g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 }; + int k, modprod, sfc, ist = HDR_TEST_I_STEREO(hdr) && ch; + sfc = gr->scalefac_compress >> ist; + for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4) + { + for (modprod = 1, i = 3; i >= 0; i--) + { + scf_size[i] = (uint8_t)(sfc / modprod % g_mod[k + i]); + modprod *= g_mod[k + i]; + } + } + scf_partition += k; + scfsi = -16; + } + L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi); + + if (gr->n_short_sfb) + { + int sh = 3 - scf_shift; + for (i = 0; i < gr->n_short_sfb; i += 3) + { + iscf[gr->n_long_sfb + i + 0] += gr->subblock_gain[0] << sh; + iscf[gr->n_long_sfb + i + 1] += gr->subblock_gain[1] << sh; + iscf[gr->n_long_sfb + i + 2] += gr->subblock_gain[2] << sh; + } + } else if (gr->preflag) + { + static const uint8_t g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 }; + for (i = 0; i < 10; i++) + { + iscf[11 + i] += g_preamp[i]; + } + } + + gain_exp = gr->global_gain + BITS_DEQUANTIZER_OUT*4 - 210 - (HDR_IS_MS_STEREO(hdr) ? 2 : 0); + gain = L3_ldexp_q2(1 << (MAX_SCFI/4), MAX_SCFI - gain_exp); + for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++) + { + scf[i] = L3_ldexp_q2(gain, iscf[i] << scf_shift); + } +} + +static const float g_pow43[129 + 16] = { + 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f, + 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f +}; + +static float L3_pow_43(int x) +{ + float frac; + int sign, mult = 256; + + if (x < 129) + { + return g_pow43[16 + x]; + } + + if (x < 1024) + { + mult = 16; + x <<= 3; + } + + sign = 2*x & 64; + frac = (float)((x & 63) - sign) / ((x & ~63) + sign); + return g_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult; +} + +static void L3_huffman(float *dst, bs_t *bs, const L3_gr_info_t *gr_info, const float *scf, int layer3gr_limit) +{ + static const int16_t tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, + -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288, + -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288, + -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258, + -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259, + -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258, + -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258, + -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259, + -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258, + -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290, + -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259, + -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258, + -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259, + -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258, + -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 }; + static const uint8_t tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205 }; + static const uint8_t tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 }; + static const int16_t tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 }; + static const uint8_t g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 }; + +#define PEEK_BITS(n) (bs_cache >> (32 - n)) +#define FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); } +#define CHECK_BITS while (bs_sh >= 0) { bs_cache |= (uint32_t)*bs_next_ptr++ << bs_sh; bs_sh -= 8; } +#define BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh) + + float one = 0.0f; + int ireg = 0, big_val_cnt = gr_info->big_values; + const uint8_t *sfb = gr_info->sfbtab; + const uint8_t *bs_next_ptr = bs->buf + bs->pos/8; + uint32_t bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7); + int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8; + bs_next_ptr += 4; + + while (big_val_cnt > 0) + { + int tab_num = gr_info->table_select[ireg]; + int sfb_cnt = gr_info->region_count[ireg++]; + const int16_t *codebook = tabs + tabindex[tab_num]; + int linbits = g_linbits[tab_num]; + if (linbits) + { + do + { + np = *sfb++ / 2; + pairs_to_decode = MINIMP3_MIN(big_val_cnt, np); + one = *scf++; + do + { + int j, w = 5; + int leaf = codebook[PEEK_BITS(w)]; + while (leaf < 0) + { + FLUSH_BITS(w); + w = leaf & 7; + leaf = codebook[PEEK_BITS(w) - (leaf >> 3)]; + } + FLUSH_BITS(leaf >> 8); + + for (j = 0; j < 2; j++, dst++, leaf >>= 4) + { + int lsb = leaf & 0x0F; + if (lsb == 15) + { + lsb += PEEK_BITS(linbits); + FLUSH_BITS(linbits); + CHECK_BITS; + *dst = one*L3_pow_43(lsb)*((int32_t)bs_cache < 0 ? -1: 1); + } else + { + *dst = g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; + } + FLUSH_BITS(lsb ? 1 : 0); + } + CHECK_BITS; + } while (--pairs_to_decode); + } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); + } else + { + do + { + np = *sfb++ / 2; + pairs_to_decode = MINIMP3_MIN(big_val_cnt, np); + one = *scf++; + do + { + int j, w = 5; + int leaf = codebook[PEEK_BITS(w)]; + while (leaf < 0) + { + FLUSH_BITS(w); + w = leaf & 7; + leaf = codebook[PEEK_BITS(w) - (leaf >> 3)]; + } + FLUSH_BITS(leaf >> 8); + + for (j = 0; j < 2; j++, dst++, leaf >>= 4) + { + int lsb = leaf & 0x0F; + *dst = g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; + FLUSH_BITS(lsb ? 1 : 0); + } + CHECK_BITS; + } while (--pairs_to_decode); + } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); + } + } + + for (np = 1 - big_val_cnt;; dst += 4) + { + const uint8_t *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32; + int leaf = codebook_count1[PEEK_BITS(4)]; + if (!(leaf & 8)) + { + leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))]; + } + FLUSH_BITS(leaf & 7); + if (BSPOS > layer3gr_limit) + { + break; + } +#define RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; } +#define DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((int32_t)bs_cache < 0) ? -one : one; FLUSH_BITS(1) } + RELOAD_SCALEFACTOR; + DEQ_COUNT1(0); + DEQ_COUNT1(1); + RELOAD_SCALEFACTOR; + DEQ_COUNT1(2); + DEQ_COUNT1(3); + CHECK_BITS; + } + + bs->pos = layer3gr_limit; +} + +static void L3_midside_stereo(float *left, int n) +{ + int i = 0; + float *right = left + 576; +#if HAVE_SIMD + if (have_simd()) + { + for (; i < n - 3; i += 4) + { + f4 vl = VLD(left + i); + f4 vr = VLD(right + i); + VSTORE(left + i, VADD(vl, vr)); + VSTORE(right + i, VSUB(vl, vr)); + } +#ifdef __GNUC__ + /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc. + * For more info see: https://github.com/lieff/minimp3/issues/88 + */ + if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0) + return; +#endif + } +#endif /* HAVE_SIMD */ + for (; i < n; i++) + { + float a = left[i]; + float b = right[i]; + left[i] = a + b; + right[i] = a - b; + } +} + +static void L3_intensity_stereo_band(float *left, int n, float kl, float kr) +{ + int i; + for (i = 0; i < n; i++) + { + left[i + 576] = left[i]*kr; + left[i] = left[i]*kl; + } +} + +static void L3_stereo_top_band(const float *right, const uint8_t *sfb, int nbands, int max_band[3]) +{ + int i, k; + + max_band[0] = max_band[1] = max_band[2] = -1; + + for (i = 0; i < nbands; i++) + { + for (k = 0; k < sfb[i]; k += 2) + { + if (right[k] != 0 || right[k + 1] != 0) + { + max_band[i % 3] = i; + break; + } + } + right += sfb[i]; + } +} + +static void L3_stereo_process(float *left, const uint8_t *ist_pos, const uint8_t *sfb, const uint8_t *hdr, int max_band[3], int mpeg2_sh) +{ + static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 }; + unsigned i, max_pos = HDR_TEST_MPEG1(hdr) ? 7 : 64; + + for (i = 0; sfb[i]; i++) + { + unsigned ipos = ist_pos[i]; + if ((int)i > max_band[i % 3] && ipos < max_pos) + { + float kl, kr, s = HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1; + if (HDR_TEST_MPEG1(hdr)) + { + kl = g_pan[2*ipos]; + kr = g_pan[2*ipos + 1]; + } else + { + kl = 1; + kr = L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh); + if (ipos & 1) + { + kl = kr; + kr = 1; + } + } + L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s); + } else if (HDR_TEST_MS_STEREO(hdr)) + { + L3_midside_stereo(left, sfb[i]); + } + left += sfb[i]; + } +} + +static void L3_intensity_stereo(float *left, uint8_t *ist_pos, const L3_gr_info_t *gr, const uint8_t *hdr) +{ + int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb; + int i, max_blocks = gr->n_short_sfb ? 3 : 1; + + L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band); + if (gr->n_long_sfb) + { + max_band[0] = max_band[1] = max_band[2] = MINIMP3_MAX(MINIMP3_MAX(max_band[0], max_band[1]), max_band[2]); + } + for (i = 0; i < max_blocks; i++) + { + int default_pos = HDR_TEST_MPEG1(hdr) ? 3 : 0; + int itop = n_sfb - max_blocks + i; + int prev = itop - max_blocks; + ist_pos[itop] = max_band[i] >= prev ? default_pos : ist_pos[prev]; + } + L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1); +} + +static void L3_reorder(float *grbuf, float *scratch, const uint8_t *sfb) +{ + int i, len; + float *src = grbuf, *dst = scratch; + + for (;0 != (len = *sfb); sfb += 3, src += 2*len) + { + for (i = 0; i < len; i++, src++) + { + *dst++ = src[0*len]; + *dst++ = src[1*len]; + *dst++ = src[2*len]; + } + } + memcpy(grbuf, scratch, (dst - scratch)*sizeof(float)); +} + +static void L3_antialias(float *grbuf, int nbands) +{ + static const float g_aa[2][8] = { + {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f}, + {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f} + }; + + for (; nbands > 0; nbands--, grbuf += 18) + { + int i = 0; +#if HAVE_SIMD + if (have_simd()) for (; i < 8; i += 4) + { + f4 vu = VLD(grbuf + 18 + i); + f4 vd = VLD(grbuf + 14 - i); + f4 vc0 = VLD(g_aa[0] + i); + f4 vc1 = VLD(g_aa[1] + i); + vd = VREV(vd); + VSTORE(grbuf + 18 + i, VSUB(VMUL(vu, vc0), VMUL(vd, vc1))); + vd = VADD(VMUL(vu, vc1), VMUL(vd, vc0)); + VSTORE(grbuf + 14 - i, VREV(vd)); + } +#endif /* HAVE_SIMD */ +#ifndef MINIMP3_ONLY_SIMD + for(; i < 8; i++) + { + float u = grbuf[18 + i]; + float d = grbuf[17 - i]; + grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i]; + grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i]; + } +#endif /* MINIMP3_ONLY_SIMD */ + } +} + +static void L3_dct3_9(float *y) +{ + float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4; + + s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8]; + t0 = s0 + s6*0.5f; + s0 -= s6; + t4 = (s4 + s2)*0.93969262f; + t2 = (s8 + s2)*0.76604444f; + s6 = (s4 - s8)*0.17364818f; + s4 += s8 - s2; + + s2 = s0 - s4*0.5f; + y[4] = s4 + s0; + s8 = t0 - t2 + s6; + s0 = t0 - t4 + t2; + s4 = t0 + t4 - s6; + + s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7]; + + s3 *= 0.86602540f; + t0 = (s5 + s1)*0.98480775f; + t4 = (s5 - s7)*0.34202014f; + t2 = (s1 + s7)*0.64278761f; + s1 = (s1 - s5 - s7)*0.86602540f; + + s5 = t0 - s3 - t2; + s7 = t4 - s3 - t0; + s3 = t4 + s3 - t2; + + y[0] = s4 - s7; + y[1] = s2 + s1; + y[2] = s0 - s3; + y[3] = s8 + s5; + y[5] = s8 - s5; + y[6] = s0 + s3; + y[7] = s2 - s1; + y[8] = s4 + s7; +} + +static void L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands) +{ + int i, j; + static const float g_twid9[18] = { + 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f + }; + + for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9) + { + float co[9], si[9]; + co[0] = -grbuf[0]; + si[0] = grbuf[17]; + for (i = 0; i < 4; i++) + { + si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2]; + co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2]; + si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3]; + co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]); + } + L3_dct3_9(co); + L3_dct3_9(si); + + si[1] = -si[1]; + si[3] = -si[3]; + si[5] = -si[5]; + si[7] = -si[7]; + + i = 0; + +#if HAVE_SIMD + if (have_simd()) for (; i < 8; i += 4) + { + f4 vovl = VLD(overlap + i); + f4 vc = VLD(co + i); + f4 vs = VLD(si + i); + f4 vr0 = VLD(g_twid9 + i); + f4 vr1 = VLD(g_twid9 + 9 + i); + f4 vw0 = VLD(window + i); + f4 vw1 = VLD(window + 9 + i); + f4 vsum = VADD(VMUL(vc, vr1), VMUL(vs, vr0)); + VSTORE(overlap + i, VSUB(VMUL(vc, vr0), VMUL(vs, vr1))); + VSTORE(grbuf + i, VSUB(VMUL(vovl, vw0), VMUL(vsum, vw1))); + vsum = VADD(VMUL(vovl, vw1), VMUL(vsum, vw0)); + VSTORE(grbuf + 14 - i, VREV(vsum)); + } +#endif /* HAVE_SIMD */ + for (; i < 9; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i]; + overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i]; + grbuf[i] = ovl*window[0 + i] - sum*window[9 + i]; + grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i]; + } + } +} + +static void L3_idct3(float x0, float x1, float x2, float *dst) +{ + float m1 = x1*0.86602540f; + float a1 = x0 - x2*0.5f; + dst[1] = x0 + x2; + dst[0] = a1 + m1; + dst[2] = a1 - m1; +} + +static void L3_imdct12(float *x, float *dst, float *overlap) +{ + static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f }; + float co[3], si[3]; + int i; + + L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co); + L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si); + si[1] = -si[1]; + + for (i = 0; i < 3; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i]; + overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i]; + dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i]; + dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i]; + } +} + +static void L3_imdct_short(float *grbuf, float *overlap, int nbands) +{ + for (;nbands > 0; nbands--, overlap += 9, grbuf += 18) + { + float tmp[18]; + memcpy(tmp, grbuf, sizeof(tmp)); + memcpy(grbuf, overlap, 6*sizeof(float)); + L3_imdct12(tmp, grbuf + 6, overlap + 6); + L3_imdct12(tmp + 1, grbuf + 12, overlap + 6); + L3_imdct12(tmp + 2, overlap, overlap + 6); + } +} + +static void L3_change_sign(float *grbuf) +{ + int b, i; + for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36) + for (i = 1; i < 18; i += 2) + grbuf[i] = -grbuf[i]; +} + +static void L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands) +{ + static const float g_mdct_window[2][18] = { + { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f }, + { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f } + }; + if (n_long_bands) + { + L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands); + grbuf += 18*n_long_bands; + overlap += 9*n_long_bands; + } + if (block_type == SHORT_BLOCK_TYPE) + L3_imdct_short(grbuf, overlap, 32 - n_long_bands); + else + L3_imdct36(grbuf, overlap, g_mdct_window[block_type == STOP_BLOCK_TYPE], 32 - n_long_bands); +} + +static void L3_save_reservoir(mp3dec_t *h, mp3dec_scratch_t *s) +{ + int pos = (s->bs.pos + 7)/8u; + int remains = s->bs.limit/8u - pos; + if (remains > MAX_BITRESERVOIR_BYTES) + { + pos += remains - MAX_BITRESERVOIR_BYTES; + remains = MAX_BITRESERVOIR_BYTES; + } + if (remains > 0) + { + memmove(h->reserv_buf, s->maindata + pos, remains); + } + h->reserv = remains; +} + +static int L3_restore_reservoir(mp3dec_t *h, bs_t *bs, mp3dec_scratch_t *s, int main_data_begin) +{ + int frame_bytes = (bs->limit - bs->pos)/8; + int bytes_have = MINIMP3_MIN(h->reserv, main_data_begin); + memcpy(s->maindata, h->reserv_buf + MINIMP3_MAX(0, h->reserv - main_data_begin), MINIMP3_MIN(h->reserv, main_data_begin)); + memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); + bs_init(&s->bs, s->maindata, bytes_have + frame_bytes); + return h->reserv >= main_data_begin; +} + +static void L3_decode(mp3dec_t *h, mp3dec_scratch_t *s, L3_gr_info_t *gr_info, int nch) +{ + int ch; + + for (ch = 0; ch < nch; ch++) + { + int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length; + L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch); + L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit); + } + + if (HDR_TEST_I_STEREO(h->header)) + { + L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header); + } else if (HDR_IS_MS_STEREO(h->header)) + { + L3_midside_stereo(s->grbuf[0], 576); + } + + for (ch = 0; ch < nch; ch++, gr_info++) + { + int aa_bands = 31; + int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(HDR_GET_MY_SAMPLE_RATE(h->header) == 2); + + if (gr_info->n_short_sfb) + { + aa_bands = n_long_bands - 1; + L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb); + } + + L3_antialias(s->grbuf[ch], aa_bands); + L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands); + L3_change_sign(s->grbuf[ch]); + } +} + +static void mp3d_DCT_II(float *grbuf, int n) +{ + static const float g_sec[24] = { + 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f + }; + int i, k = 0; +#if HAVE_SIMD + if (have_simd()) for (; k < n; k += 4) + { + f4 t[4][8], *x; + float *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + f4 x0 = VLD(&y[i*18]); + f4 x1 = VLD(&y[(15 - i)*18]); + f4 x2 = VLD(&y[(16 + i)*18]); + f4 x3 = VLD(&y[(31 - i)*18]); + f4 t0 = VADD(x0, x3); + f4 t1 = VADD(x1, x2); + f4 t2 = VMUL_S(VSUB(x1, x2), g_sec[3*i + 0]); + f4 t3 = VMUL_S(VSUB(x0, x3), g_sec[3*i + 1]); + x[0] = VADD(t0, t1); + x[8] = VMUL_S(VSUB(t0, t1), g_sec[3*i + 2]); + x[16] = VADD(t3, t2); + x[24] = VMUL_S(VSUB(t3, t2), g_sec[3*i + 2]); + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = VSUB(x0, x7); x0 = VADD(x0, x7); + x7 = VSUB(x1, x6); x1 = VADD(x1, x6); + x6 = VSUB(x2, x5); x2 = VADD(x2, x5); + x5 = VSUB(x3, x4); x3 = VADD(x3, x4); + x4 = VSUB(x0, x3); x0 = VADD(x0, x3); + x3 = VSUB(x1, x2); x1 = VADD(x1, x2); + x[0] = VADD(x0, x1); + x[4] = VMUL_S(VSUB(x0, x1), 0.70710677f); + x5 = VADD(x5, x6); + x6 = VMUL_S(VADD(x6, x7), 0.70710677f); + x7 = VADD(x7, xt); + x3 = VMUL_S(VADD(x3, x4), 0.70710677f); + x5 = VSUB(x5, VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */ + x7 = VADD(x7, VMUL_S(x5, 0.382683432f)); + x5 = VSUB(x5, VMUL_S(x7, 0.198912367f)); + x0 = VSUB(xt, x6); xt = VADD(xt, x6); + x[1] = VMUL_S(VADD(xt, x7), 0.50979561f); + x[2] = VMUL_S(VADD(x4, x3), 0.54119611f); + x[3] = VMUL_S(VSUB(x0, x5), 0.60134488f); + x[5] = VMUL_S(VADD(x0, x5), 0.89997619f); + x[6] = VMUL_S(VSUB(x4, x3), 1.30656302f); + x[7] = VMUL_S(VSUB(xt, x7), 2.56291556f); + } + + if (k > n - 3) + { +#if HAVE_SSE +#define VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v) +#else /* HAVE_SSE */ +#define VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v)) +#endif /* HAVE_SSE */ + for (i = 0; i < 7; i++, y += 4*18) + { + f4 s = VADD(t[3][i], t[3][i + 1]); + VSAVE2(0, t[0][i]); + VSAVE2(1, VADD(t[2][i], s)); + VSAVE2(2, VADD(t[1][i], t[1][i + 1])); + VSAVE2(3, VADD(t[2][1 + i], s)); + } + VSAVE2(0, t[0][7]); + VSAVE2(1, VADD(t[2][7], t[3][7])); + VSAVE2(2, t[1][7]); + VSAVE2(3, t[3][7]); + } else + { +#define VSAVE4(i, v) VSTORE(&y[i*18], v) + for (i = 0; i < 7; i++, y += 4*18) + { + f4 s = VADD(t[3][i], t[3][i + 1]); + VSAVE4(0, t[0][i]); + VSAVE4(1, VADD(t[2][i], s)); + VSAVE4(2, VADD(t[1][i], t[1][i + 1])); + VSAVE4(3, VADD(t[2][1 + i], s)); + } + VSAVE4(0, t[0][7]); + VSAVE4(1, VADD(t[2][7], t[3][7])); + VSAVE4(2, t[1][7]); + VSAVE4(3, t[3][7]); + } + } else +#endif /* HAVE_SIMD */ +#ifdef MINIMP3_ONLY_SIMD + {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */ +#else /* MINIMP3_ONLY_SIMD */ + for (; k < n; k++) + { + float t[4][8], *x, *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + float x0 = y[i*18]; + float x1 = y[(15 - i)*18]; + float x2 = y[(16 + i)*18]; + float x3 = y[(31 - i)*18]; + float t0 = x0 + x3; + float t1 = x1 + x2; + float t2 = (x1 - x2)*g_sec[3*i + 0]; + float t3 = (x0 - x3)*g_sec[3*i + 1]; + x[0] = t0 + t1; + x[8] = (t0 - t1)*g_sec[3*i + 2]; + x[16] = t3 + t2; + x[24] = (t3 - t2)*g_sec[3*i + 2]; + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = x0 - x7; x0 += x7; + x7 = x1 - x6; x1 += x6; + x6 = x2 - x5; x2 += x5; + x5 = x3 - x4; x3 += x4; + x4 = x0 - x3; x0 += x3; + x3 = x1 - x2; x1 += x2; + x[0] = x0 + x1; + x[4] = (x0 - x1)*0.70710677f; + x5 = x5 + x6; + x6 = (x6 + x7)*0.70710677f; + x7 = x7 + xt; + x3 = (x3 + x4)*0.70710677f; + x5 -= x7*0.198912367f; /* rotate by PI/8 */ + x7 += x5*0.382683432f; + x5 -= x7*0.198912367f; + x0 = xt - x6; xt += x6; + x[1] = (xt + x7)*0.50979561f; + x[2] = (x4 + x3)*0.54119611f; + x[3] = (x0 - x5)*0.60134488f; + x[5] = (x0 + x5)*0.89997619f; + x[6] = (x4 - x3)*1.30656302f; + x[7] = (xt - x7)*2.56291556f; + + } + for (i = 0; i < 7; i++, y += 4*18) + { + y[0*18] = t[0][i]; + y[1*18] = t[2][i] + t[3][i] + t[3][i + 1]; + y[2*18] = t[1][i] + t[1][i + 1]; + y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1]; + } + y[0*18] = t[0][7]; + y[1*18] = t[2][7] + t[3][7]; + y[2*18] = t[1][7]; + y[3*18] = t[3][7]; + } +#endif /* MINIMP3_ONLY_SIMD */ +} + +#ifndef MINIMP3_FLOAT_OUTPUT +static int16_t mp3d_scale_pcm(float sample) +{ +#if HAVE_ARMV6 + int32_t s32 = (int32_t)(sample + .5f); + s32 -= (s32 < 0); + int16_t s = (int16_t)minimp3_clip_int16_arm(s32); +#else + if (sample >= 32766.5) return (int16_t) 32767; + if (sample <= -32767.5) return (int16_t)-32768; + int16_t s = (int16_t)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ +#endif + return s; +} +#else /* MINIMP3_FLOAT_OUTPUT */ +static float mp3d_scale_pcm(float sample) +{ + return sample*(1.f/32768.f); +} +#endif /* MINIMP3_FLOAT_OUTPUT */ + +static void mp3d_synth_pair(mp3d_sample_t *pcm, int nch, const float *z) +{ + float a; + a = (z[14*64] - z[ 0]) * 29; + a += (z[ 1*64] + z[13*64]) * 213; + a += (z[12*64] - z[ 2*64]) * 459; + a += (z[ 3*64] + z[11*64]) * 2037; + a += (z[10*64] - z[ 4*64]) * 5153; + a += (z[ 5*64] + z[ 9*64]) * 6574; + a += (z[ 8*64] - z[ 6*64]) * 37489; + a += z[ 7*64] * 75038; + pcm[0] = mp3d_scale_pcm(a); + + z += 2; + a = z[14*64] * 104; + a += z[12*64] * 1567; + a += z[10*64] * 9727; + a += z[ 8*64] * 64019; + a += z[ 6*64] * -9975; + a += z[ 4*64] * -45; + a += z[ 2*64] * 146; + a += z[ 0*64] * -5; + pcm[16*nch] = mp3d_scale_pcm(a); +} + +static void mp3d_synth(float *xl, mp3d_sample_t *dstl, int nch, float *lins) +{ + int i; + float *xr = xl + 576*(nch - 1); + mp3d_sample_t *dstr = dstl + (nch - 1); + + static const float g_win[] = { + -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992, + -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856, + -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630, + -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313, + -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908, + -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415, + -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835, + -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169, + -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420, + -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590, + -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679, + -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692, + -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629, + -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494, + -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290 + }; + float *zlin = lins + 15*64; + const float *w = g_win; + + zlin[4*15] = xl[18*16]; + zlin[4*15 + 1] = xr[18*16]; + zlin[4*15 + 2] = xl[0]; + zlin[4*15 + 3] = xr[0]; + + zlin[4*31] = xl[1 + 18*16]; + zlin[4*31 + 1] = xr[1 + 18*16]; + zlin[4*31 + 2] = xl[1]; + zlin[4*31 + 3] = xr[1]; + + mp3d_synth_pair(dstr, nch, lins + 4*15 + 1); + mp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1); + mp3d_synth_pair(dstl, nch, lins + 4*15); + mp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64); + +#if HAVE_SIMD + if (have_simd()) for (i = 14; i >= 0; i--) + { +#define VLOAD(k) f4 w0 = VSET(*w++); f4 w1 = VSET(*w++); f4 vz = VLD(&zlin[4*i - 64*k]); f4 vy = VLD(&zlin[4*i - 64*(15 - k)]); +#define V0(k) { VLOAD(k) b = VADD(VMUL(vz, w1), VMUL(vy, w0)) ; a = VSUB(VMUL(vz, w0), VMUL(vy, w1)); } +#define V1(k) { VLOAD(k) b = VADD(b, VADD(VMUL(vz, w1), VMUL(vy, w0))); a = VADD(a, VSUB(VMUL(vz, w0), VMUL(vy, w1))); } +#define V2(k) { VLOAD(k) b = VADD(b, VADD(VMUL(vz, w1), VMUL(vy, w0))); a = VADD(a, VSUB(VMUL(vy, w1), VMUL(vz, w0))); } + f4 a, b; + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*i + 64] = xl[1 + 18*(1 + i)]; + zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)]; + zlin[4*i - 64 + 2] = xl[18*(1 + i)]; + zlin[4*i - 64 + 3] = xr[18*(1 + i)]; + + V0(0) V2(1) V1(2) V2(3) V1(4) V2(5) V1(6) V2(7) + + { +#ifndef MINIMP3_FLOAT_OUTPUT +#if HAVE_SSE + static const f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; + static const f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); + dstr[(15 - i)*nch] = _mm_extract_epi16(pcm8, 1); + dstr[(17 + i)*nch] = _mm_extract_epi16(pcm8, 5); + dstl[(15 - i)*nch] = _mm_extract_epi16(pcm8, 0); + dstl[(17 + i)*nch] = _mm_extract_epi16(pcm8, 4); + dstr[(47 - i)*nch] = _mm_extract_epi16(pcm8, 3); + dstr[(49 + i)*nch] = _mm_extract_epi16(pcm8, 7); + dstl[(47 - i)*nch] = _mm_extract_epi16(pcm8, 2); + dstl[(49 + i)*nch] = _mm_extract_epi16(pcm8, 6); +#else /* HAVE_SSE */ + int16x4_t pcma, pcmb; + a = VADD(a, VSET(0.5f)); + b = VADD(b, VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, VSET(0))))); + vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1); + vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1); + vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0); + vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0); + vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3); + vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3); + vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2); + vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); +#endif /* HAVE_SSE */ + +#else /* MINIMP3_FLOAT_OUTPUT */ + + static const f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; + a = VMUL(a, g_scale); + b = VMUL(b, g_scale); +#if HAVE_SSE + _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2))); +#else /* HAVE_SSE */ + vst1q_lane_f32(dstr + (15 - i)*nch, a, 1); + vst1q_lane_f32(dstr + (17 + i)*nch, b, 1); + vst1q_lane_f32(dstl + (15 - i)*nch, a, 0); + vst1q_lane_f32(dstl + (17 + i)*nch, b, 0); + vst1q_lane_f32(dstr + (47 - i)*nch, a, 3); + vst1q_lane_f32(dstr + (49 + i)*nch, b, 3); + vst1q_lane_f32(dstl + (47 - i)*nch, a, 2); + vst1q_lane_f32(dstl + (49 + i)*nch, b, 2); +#endif /* HAVE_SSE */ +#endif /* MINIMP3_FLOAT_OUTPUT */ + } + } else +#endif /* HAVE_SIMD */ +#ifdef MINIMP3_ONLY_SIMD + {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */ +#else /* MINIMP3_ONLY_SIMD */ + for (i = 14; i >= 0; i--) + { +#define LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64]; +#define S0(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; } +#define S1(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; } +#define S2(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; } + float a[4], b[4]; + + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*(i + 16)] = xl[1 + 18*(1 + i)]; + zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)]; + zlin[4*(i - 16) + 2] = xl[18*(1 + i)]; + zlin[4*(i - 16) + 3] = xr[18*(1 + i)]; + + S0(0) S2(1) S1(2) S2(3) S1(4) S2(5) S1(6) S2(7) + + dstr[(15 - i)*nch] = mp3d_scale_pcm(a[1]); + dstr[(17 + i)*nch] = mp3d_scale_pcm(b[1]); + dstl[(15 - i)*nch] = mp3d_scale_pcm(a[0]); + dstl[(17 + i)*nch] = mp3d_scale_pcm(b[0]); + dstr[(47 - i)*nch] = mp3d_scale_pcm(a[3]); + dstr[(49 + i)*nch] = mp3d_scale_pcm(b[3]); + dstl[(47 - i)*nch] = mp3d_scale_pcm(a[2]); + dstl[(49 + i)*nch] = mp3d_scale_pcm(b[2]); + } +#endif /* MINIMP3_ONLY_SIMD */ +} + +static void mp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, mp3d_sample_t *pcm, float *lins) +{ + int i; + for (i = 0; i < nch; i++) + { + mp3d_DCT_II(grbuf + 576*i, nbands); + } + + memcpy(lins, qmf_state, sizeof(float)*15*64); + + for (i = 0; i < nbands; i += 2) + { + mp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64); + } +#ifndef MINIMP3_NONSTANDARD_BUT_LOGICAL + if (nch == 1) + { + for (i = 0; i < 15*64; i += 2) + { + qmf_state[i] = lins[nbands*64 + i]; + } + } else +#endif /* MINIMP3_NONSTANDARD_BUT_LOGICAL */ + { + memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64); + } +} + +static int mp3d_match_frame(const uint8_t *hdr, int mp3_bytes, int frame_bytes) +{ + int i, nmatch; + for (i = 0, nmatch = 0; nmatch < MAX_FRAME_SYNC_MATCHES; nmatch++) + { + i += hdr_frame_bytes(hdr + i, frame_bytes) + hdr_padding(hdr + i); + if (i + HDR_SIZE > mp3_bytes) + return nmatch > 0; + if (!hdr_compare(hdr, hdr + i)) + return 0; + } + return 1; +} + +static int mp3d_find_frame(const uint8_t *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes) +{ + int i, k; + for (i = 0; i < mp3_bytes - HDR_SIZE; i++, mp3++) + { + if (hdr_valid(mp3)) + { + int frame_bytes = hdr_frame_bytes(mp3, *free_format_bytes); + int frame_and_padding = frame_bytes + hdr_padding(mp3); + + for (k = HDR_SIZE; !frame_bytes && k < MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - HDR_SIZE; k++) + { + if (hdr_compare(mp3, mp3 + k)) + { + int fb = k - hdr_padding(mp3); + int nextfb = fb + hdr_padding(mp3 + k); + if (i + k + nextfb + HDR_SIZE > mp3_bytes || !hdr_compare(mp3, mp3 + k + nextfb)) + continue; + frame_and_padding = k; + frame_bytes = fb; + *free_format_bytes = fb; + } + } + if ((frame_bytes && i + frame_and_padding <= mp3_bytes && + mp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) || + (!i && frame_and_padding == mp3_bytes)) + { + *ptr_frame_bytes = frame_and_padding; + return i; + } + *free_format_bytes = 0; + } + } + *ptr_frame_bytes = 0; + return mp3_bytes; +} + +void mp3dec_init(mp3dec_t *dec) +{ + dec->header[0] = 0; +} + +int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info) +{ + int i = 0, igr, frame_size = 0, success = 1; + const uint8_t *hdr; + bs_t bs_frame[1]; +#ifdef MINIMP3_SCRATCH +#define scratch (*MINIMP3_SCRATCH) +#else + mp3dec_scratch_t scratch; +#endif + + if (mp3_bytes > 4 && dec->header[0] == 0xff && hdr_compare(dec->header, mp3)) + { + frame_size = hdr_frame_bytes(mp3, dec->free_format_bytes) + hdr_padding(mp3); + if (frame_size != mp3_bytes && (frame_size + HDR_SIZE > mp3_bytes || !hdr_compare(mp3, mp3 + frame_size))) + { + frame_size = 0; + } + } + if (!frame_size) + { + memset(dec, 0, sizeof(mp3dec_t)); + i = mp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size); + if (!frame_size || i + frame_size > mp3_bytes) + { + info->frame_bytes = i; + return 0; + } + } + + hdr = mp3 + i; + memcpy(dec->header, hdr, HDR_SIZE); + info->frame_bytes = i + frame_size; + info->frame_offset = i; + info->channels = HDR_IS_MONO(hdr) ? 1 : 2; + info->hz = hdr_sample_rate_hz(hdr); + info->layer = 4 - HDR_GET_LAYER(hdr); + info->bitrate_kbps = hdr_bitrate_kbps(hdr); + + if (!pcm) + { + return hdr_frame_samples(hdr); + } + + bs_init(bs_frame, hdr + HDR_SIZE, frame_size - HDR_SIZE); + if (HDR_IS_CRC(hdr)) + { + get_bits(bs_frame, 16); + } + + if (info->layer == 3) + { + int main_data_begin = L3_read_side_info(bs_frame, scratch.gr_info, hdr); + if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) + { + mp3dec_init(dec); + return 0; + } + success = L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + if (success) + { + for (igr = 0; igr < (HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm += 576*info->channels) + { + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); + mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, pcm, scratch.syn[0]); + } + } + L3_save_reservoir(dec, &scratch); + } else + { +#ifdef MINIMP3_ONLY_MP3 + return 0; +#else /* MINIMP3_ONLY_MP3 */ + L12_scale_info sci[1]; + L12_read_scale_info(hdr, bs_frame, sci); + + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + for (i = 0, igr = 0; igr < 3; igr++) + { + if (12 == (i += L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + { + i = 0; + L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); + mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, pcm, scratch.syn[0]); + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + pcm += 384*info->channels; + } + if (bs_frame->pos > bs_frame->limit) + { + mp3dec_init(dec); + return 0; + } + } +#endif /* MINIMP3_ONLY_MP3 */ + } +#ifdef MINIMP3_SCRATCH +#undef scratch +#endif + return success*hdr_frame_samples(dec->header); +} + +#ifdef MINIMP3_FLOAT_OUTPUT +void mp3dec_f32_to_s16(const float *in, int16_t *out, int num_samples) +{ + int i = 0; +#if HAVE_SIMD + int aligned_count = num_samples & ~7; + for(; i < aligned_count; i += 8) + { + static const f4 g_scale = { 32768.0f, 32768.0f, 32768.0f, 32768.0f }; + f4 a = VMUL(VLD(&in[i ]), g_scale); + f4 b = VMUL(VLD(&in[i+4]), g_scale); +#if HAVE_SSE + static const f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; + static const f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); + out[i ] = _mm_extract_epi16(pcm8, 0); + out[i+1] = _mm_extract_epi16(pcm8, 1); + out[i+2] = _mm_extract_epi16(pcm8, 2); + out[i+3] = _mm_extract_epi16(pcm8, 3); + out[i+4] = _mm_extract_epi16(pcm8, 4); + out[i+5] = _mm_extract_epi16(pcm8, 5); + out[i+6] = _mm_extract_epi16(pcm8, 6); + out[i+7] = _mm_extract_epi16(pcm8, 7); +#else /* HAVE_SSE */ + int16x4_t pcma, pcmb; + a = VADD(a, VSET(0.5f)); + b = VADD(b, VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, VSET(0))))); + vst1_lane_s16(out+i , pcma, 0); + vst1_lane_s16(out+i+1, pcma, 1); + vst1_lane_s16(out+i+2, pcma, 2); + vst1_lane_s16(out+i+3, pcma, 3); + vst1_lane_s16(out+i+4, pcmb, 0); + vst1_lane_s16(out+i+5, pcmb, 1); + vst1_lane_s16(out+i+6, pcmb, 2); + vst1_lane_s16(out+i+7, pcmb, 3); +#endif /* HAVE_SSE */ + } +#endif /* HAVE_SIMD */ + for(; i < num_samples; i++) + { + float sample = in[i] * 32768.0f; + if (sample >= 32766.5) + out[i] = (int16_t) 32767; + else if (sample <= -32767.5) + out[i] = (int16_t)-32768; + else + { + int16_t s = (int16_t)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ + out[i] = s; + } + } +} +#endif /* MINIMP3_FLOAT_OUTPUT */ +#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_IMPLEMENTATION_GUARD */ diff --git a/platformio.ini b/platformio.ini index bca1f26..7d4dd3c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -613,6 +613,15 @@ build_flags = -D HAS_TDECK_GT911=1 -D HAS_TDECK_TRACKBALL=1 -D HAS_TDECK_KEYBOARD=1 + ; Forced here (not just in lv_conf.h) because .pio/libdeps//MeshCore/include/lv_conf.h + ; -- a stale snapshot vendored by the pinned core tag -- sits earlier in the -I search + ; order than this repo's own include/lv_conf.h, so LV_CONF_INCLUDE_SIMPLE's quoted + ; #include "lv_conf.h" silently resolves to that stale copy for src/ compiles (though + ; library .c files, e.g. lvgl's own, still see the right one -- inconsistent per TU). A + ; -D here is immune to that: it's set before any header is processed and isn't + ; overridden by a plain #define. Only 20px is forced, for the "at a glance" experiment + ; below (atGlanceEnsureFont() in UITask.cpp) -- not 18/24, which this board doesn't use. + -D LV_FONT_MONTSERRAT_20=1 -D ENABLE_ADVERT_ON_BOOT=0 -D PIN_TB_UP=15 -D PIN_TB_DOWN=3 @@ -765,9 +774,20 @@ build_flags = -D ENV_INCLUDE_VL53L0X=0 -D ENV_INCLUDE_BME680=0 -D ENV_INCLUDE_BMP085=0 - -D PIN_GPS_RX=18 - -D PIN_GPS_TX=17 + ; NAMING TRAP (same one as the V4-R8 and Pager envs above): the core calls + ; Serial1.setPins(PIN_GPS_TX, PIN_GPS_RX) and Arduino's setPins() takes + ; (rxPin, txPin) -- so PIN_GPS_TX is the pin WE RECEIVE ON, and PIN_GPS_RX is + ; the pin we transmit on. These were 18/17 (copied from the Attaky env during + ; bring-up, never checked against this board), which left the UART listening on + ; GPIO17 while the module talks on GPIO18 -- GPS never produced a fix. + ; Confirmed by SQUARE_GPS_PROBE: NMEA on GPIO18 at 9600 (9 sats in view), + ; GPIO17 silent at 9600/38400/115200. + -D PIN_GPS_TX=18 + -D PIN_GPS_RX=17 -D GPS_BAUD_RATE=9600 + ; TEMP DIAGNOSTIC, disarmed now that the wiring is confirmed. Uncomment to + ; re-run the pin/baud sweep; the block it gates lives in src/main.cpp. + ; -D SQUARE_GPS_PROBE=1 -D PIN_BOARD_SDA=47 -D PIN_BOARD_SCL=48 -D PIN_USER_BTN=0 @@ -1296,13 +1316,17 @@ board_build.partitions = variants/thinknode_m9/partitions_m9_touch.csv ; DriveDiosInSleepMode (0x012A, FW 0x0308+) with CMD_PERR -> begin() = -706. ; The pre-script makes RadioLib's config() skip it on old FW (idempotent, ; per-env libdeps copy). See scripts/build/patch_radiolib_lr11x0.py. -extra_scripts = pre:scripts/build/pre_gen_baked.py, pre:scripts/inject_wifi_env.py, pre:scripts/build/patch_radiolib_lr11x0.py, merge-bin.py +extra_scripts = pre:scripts/build/pre_gen_baked.py, pre:scripts/inject_wifi_env.py, pre:scripts/build/patch_radiolib_lr11x0.py, pre:scripts/build/patch_meshcore_rv3028_define.py, merge-bin.py + +build_unflags = + -std=gnu++11 + -std=gnu++14 build_flags = ; 1.17 core: ESP32Board.cpp includes -> MicroNMEALocationProvider.h (header-only ; provider), so MicroNMEA never chains into the core lib's LDF scope -- hand it the path. -I"${platformio.libdeps_dir}/${this.__env__}/MicroNMEA/src" - -Wno-deprecated-declarations -Wno-unused-parameter -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1 + -Wno-deprecated-declarations -Wno-unused-parameter -Wno-cpp -Wno-overflow -Wno-return-type -std=gnu++17 -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1 -D MC_VENDORED_TOUCH_APP -D LORA_FREQ=869.618 -D LORA_BW=62.5 @@ -1484,9 +1508,8 @@ build_flags = -D HAS_TOUCH_UI=1 -D FIRMWARE_OTA_ENV='"ThinkNode_M9_companion_radio_touch"' -D ENABLE_ADVERT_ON_BOOT=0 - -D LV_CONF_PATH=lv_conf.h + -D LV_CONF_PATH=lv_conf_m9.h -D LV_CONF_INCLUDE_SIMPLE=1 - -D LV_INDEV_DEF_SCROLL_THROW=7 -D MAX_CONTACTS=2000 -D MAX_GROUP_CHANNELS=40 -D DISPLAY_CLASS=ST7789LCDDisplay diff --git a/release-notes/beta_70.txt b/release-notes/beta_70.txt new file mode 100644 index 0000000..c713bbc --- /dev/null +++ b/release-notes/beta_70.txt @@ -0,0 +1,39 @@ +# beta_70 - test build. Stable stays beta_65. +# One user-facing note per non-blank, non-# line; # lines are section comments. + +# --- The crash on the regions screen ------------------------------------------------------ +Adding or removing known regions and then leaving that screen crashed the device. If you have been unable to get out of Radio & mesh without resetting, this was why. +The cause was general, not specific to regions: when a text field is destroyed, the interface library sends it one last "you lost focus" event, and seven fields in the firmware save their value on losing focus. So a field was reading and rewriting itself from inside its own destructor. All seven now ignore a blur that is really a deletion. +Found by decoding the core dump attached to the report, against a rebuilt beta_69 image. Thank you for sending it. + +# --- Translations: undoing damage we caused ------------------------------------------------ +Language file v18 contained keys that do not exist anywhere in the firmware. Entries like "Paste (move)Paste (copy)" and "Unblock Block" were two separate buttons glued into one, and one entry was a Dutch phrase that appears only inside a source-code comment. +That was a bug in the tool that decides which text belongs in a language file, introduced in the last release. It has been fixed twice over: it no longer joins the two halves of a choice into one entry, and it no longer reads text out of comments. +202 invented entries are gone from all thirteen files. Nothing a translator had actually translated was touched. +The curly quotes in the Hungarian map credits showed as empty boxes because no bundled font contains them. Replaced with straight quotes. +Five more strings are translatable: the Wi-Fi rescan and hidden-network rows, the update check, and the downgrade prompt. +Language files are at v19. v18 is withdrawn. + +# --- The Store stops offering apps your board cannot run ----------------------------------- +Wardrive and Nearby need the extended SDK, which the Heltec V4 does not have. The Store offered both anyway, so the most common board in the mesh could download, install and open two apps that then refused to work, with no warning. Apps can now say what they need, and the Store says so on the row instead. + +# --- Community work, by Michael A. Cojocari (@oumike) --------------------------------------- +Lua apps can play WAV and MP3 audio, from the SD card or from memory. +@-mention autocomplete in the device chat and the web interface, suggesting people whose adverts this device actually heard rather than everyone in your contacts. +Symbol and alt keys latch: tap once for the next key, tap twice to lock the layer until you tap again. No more holding a modifier down. +The web reader opens a home page from the SD card if you put one there, so a device with no internet still has somewhere to start. +Wardrive no longer stops when a node name contains an emoji. Names are cut on character boundaries now, and text coming from an app is checked before it reaches the screen. +Screenshots from the Control Center on the ThinkNode M9 and both T-Lora Pagers, with a timer for immediate, 3-second or 10-second capture. +The M9's Home key works while you are typing in a text field, and the built-in Snake starts from the first direction you press. +Tapping a chat composer that is already focused reopens the on-screen keyboard instead of doing nothing. + +# --- Community work, by Tesso M Costa (@codemonkeybr) -------------------------------------- +A new "At a glance" notification style: when a message arrives while the screen is dimmed, it shows a short preview without fully waking the device or lighting the keyboard. Optional, and it can be limited to when the device is unlocked. + +# --- Also fixed ----------------------------------------------------------------------------- +Granting an app permission could silently take a permission away from a different app. The switches packed the app's position and the permission into too few bits, so "Send discovery probes" wrote the wrong app's record, marking an app you never touched as refused. That is why apps reported "permission denied" with every permission granted. + +# --- For testers ------------------------------------------------------------------------------ +The regions crash is the fix most worth confirming: add and remove a few known regions, leave the screen, and check the device stays up. +If you translate, your language file is clean again but has more untranslated entries than before, because strings that were previously invisible to the checker are now listed. +Console mode is still an early preview and has not changed this release. diff --git a/release-notes/beta_71.txt b/release-notes/beta_71.txt new file mode 100644 index 0000000..1ddb87d --- /dev/null +++ b/release-notes/beta_71.txt @@ -0,0 +1,14 @@ +# beta_71 - test build. Stable stays beta_65. +# One user-facing note per non-blank, non-# line; # lines are section comments. + +# --- For people writing Lua apps ------------------------------------------------------------ +Apps can clear their page. There was no way to remove the widgets an app had already created, so anything with a second screen drew it on top of the first. wada.ui.clear() takes the page back to empty, and any widget you were still holding from before the clear becomes inert rather than dangerous. +Apps can reach all your contacts. The list stopped at 100, and it only ever looked at the first 200 in the first place, so on a device with a lot of contacts most of them were unreachable and nothing said so. wada.mesh.contacts() now takes an offset and a limit, and wada.mesh.contact_count() tells an app how many there are to page through. +Apps can be three times larger. The limit was 64 KB, which an ordinary program can reach. It is 192 KB now. + +# --- T-Deck keyboard --------------------------------------------------------------------------- +Modifier latching could fail to turn on even with the right keyboard firmware installed. The firmware asked the keyboard what it was capable of exactly once, on the first read after boot, and the first read after boot is the one most likely to come back garbled because the keyboard controller is still starting. One bad answer meant no latching for the rest of the session, and rebooting simply asked again at the same unlucky moment. It now keeps asking for a second and a half before giving up, and says what it actually saw when it does. + +# --- For testers --------------------------------------------------------------------------------- +This is a small drop on top of beta_70, which carried the fix for the crash when leaving the known-regions screen. If you have not tried that yet, it is still the thing most worth confirming: add and remove a few regions, leave the screen, check the device stays up. +If your screen is not going to sleep, we are still investigating (issue 333) and it is not fixed here. diff --git a/release-notes/beta_72.txt b/release-notes/beta_72.txt new file mode 100644 index 0000000..eeace99 --- /dev/null +++ b/release-notes/beta_72.txt @@ -0,0 +1,18 @@ +# beta_72 - test build. Stable stays beta_65. +# One user-facing note per non-blank, non-# line; # lines are section comments. + +# --- Two things broken in the last two betas ------------------------------------------------ +Console mode could be entered on a board that had no way to type into it. On the ThinkNode M9 it painted the prompt, showed the line telling you to type 'ui' to get back, and accepted nothing: a power cycle and the reset button both returned straight to it. The M9's keyboard now works in the console, and any board without a console keyboard no longer offers the mode at all. The T-Lora Pager was one setting away from the same state and no longer shows the option either. +Accent popups stopped appearing for anyone typing on a physical keyboard, and the setting to turn them on and off did nothing. The accent box and the new @-mention picker share one piece of code, and when the mention work went in the accent half was dropped from the path a physical keyboard uses. Touchscreen typing was unaffected, which is why it looked like a settings problem. + +# --- New ---------------------------------------------------------------------------------------- +Share a contact with whoever is next to you. The contact menu has a Share entry that re-broadcasts that contact so nodes in direct range can add them. It is deliberately direct-range only: putting someone else's node on the whole mesh is a lot of airtime for a packet nobody asked for. +The signal card is translatable. Signal, Signal (stale) and "nothing heard yet" were never wired for translation, so that card stayed English in every language while the same words were translated everywhere else. + +# --- Fixed -------------------------------------------------------------------------------------- +The T-Deck reported a full battery as 4.09 V. The conversion from the board's voltage divider was slightly off, so every T-Deck read low. + +# --- For testers ------------------------------------------------------------------------------ +If you are on a ThinkNode M9 or a T-Lora Pager, update before touching console mode. On those boards the previous two releases could leave you unable to get out. +If your M9 is already stuck: hold BOOT, tap RESET, release BOOT, then flash normally. The device is fine, it just has to be flashed from the bootloader rather than from the running app, which is why a normal reflash reported a failure. +Still open and not fixed here: a screen that will not stay dark after a manual lock (issue 333). We are narrowing it down. diff --git a/release-notes/beta_73.txt b/release-notes/beta_73.txt new file mode 100644 index 0000000..ebf67d7 --- /dev/null +++ b/release-notes/beta_73.txt @@ -0,0 +1,17 @@ +# beta_73 - test build. Stable stays beta_65. +# One user-facing note per non-blank, non-# line; # lines are section comments. + +# --- Older T-Decks could not be typed on ------------------------------------------------------ +If your T-Deck types the wrong letters, this release fixes it. Pressing "a" produced "q " and "m" produced "qa ", which made the keyboard unusable for writing, navigating or locking the screen. +It affects the older T-Deck keyboards, the ones without the controllable backlight, and it started in beta_70. The firmware asks the keyboard at startup whether it speaks the newer protocol that modifier latching needs, and an older keyboard's answer looked enough like a yes to be taken as one. Everything typed after that was read the wrong way round. +Nothing can tell the two keyboards apart while nobody is typing, so the firmware now simply corrects itself: the first letter you press is unmistakably a character rather than a key-position report, and it switches to the older protocol on the spot and delivers that letter. You lose modifier latching, which your keyboard cannot do anyway, and you get a working keyboard. +Newer keyboards are unaffected and keep latching. +The beta_72 change that was meant to make this detection more reliable made it worse, because it gave an older keyboard more chances to look like a newer one. + +# --- Translations --------------------------------------------------------------------------------- +Two Hungarian strings: "Mark read", which had never been translated, and a shorter wording for joining the public channel so it fits its button. These are already on devices, since language files publish separately from the firmware. + +# --- For testers ------------------------------------------------------------------------------- +If your keyboard was typing nonsense, you should be able to install this normally rather than needing a cable. +A reminder that two settings control whether an arriving message lights a dark or locked screen, and they are separate: Message flash wakes the screen, and At a glance draws the preview text on it. Both are in Options, Display. Turning off At a glance alone will not stop the screen lighting up. +Still open and not fixed here: a map that renders nothing after beta_71, a screen that will not stay dark after a manual lock, and a web flasher that hangs at "wrapping up" on the T-Display P4. diff --git a/release-notes/beta_74.txt b/release-notes/beta_74.txt new file mode 100644 index 0000000..074956f --- /dev/null +++ b/release-notes/beta_74.txt @@ -0,0 +1,25 @@ +# beta_74 - test build. Stable stays beta_65. +# One user-facing note per non-blank, non-# line; # lines are section comments. + +# --- If your T-Deck types the wrong letters ----------------------------------------------- +There is now a switch that fixes it, and you can reach it without typing: Settings, Keyboard, "Older keyboard protocol". It skips the automatic detection and uses the protocol every T-Deck keyboard understands. +This exists because the detection cannot always be certain, and when it gets it wrong the keyboard types the wrong letters, so any fix that needs you to type is not a fix. The switch is operated by touch and applies immediately, with no reboot. +Turning it on costs modifier latching, which a keyboard that needs the switch cannot do anyway. +The automatic detection is unchanged and still the default. If beta_73 fixed your keyboard, nothing here changes for you. + +# --- Web settings could quietly change your radio ------------------------------------------ +The remote web page showed a bandwidth of 62.5 as 62, and pressing Apply sent 62 back to the device. Opening the page and applying anything reconfigured the radio onto a bandwidth the mesh was not using. Both halves of that are fixed: the device now sends the fraction, and the form accepts it. + +# --- Keyboard --------------------------------------------------------------------------------- +Shift latches like the symbol and alt keys do: tap once for the next letter, tap twice to lock until you tap again. No more holding shift down while reaching for a key. +The Attaky Mesh Deck's front D-pad and SELECT button work now. The board has nine buttons and only the power button did anything. + +# --- Reading a route ------------------------------------------------------------------------ +Each hop in a message route shows its path prefix next to the repeater name. When a repeater is named misleadingly, or two share a name, the prefix is the part that still identifies it, which is exactly when you are looking at a route. + +# --- Translations --------------------------------------------------------------------------------- +"Known regions" and the Bluetooth pairing hint are translatable and translated into Hungarian. + +# --- For testers ------------------------------------------------------------------------------ +Still open and not fixed here: a map that renders nothing since beta_71, a screen that will not stay dark after a manual lock, the web flasher hanging at "wrapping up" on the T-Display P4, and an M9 that reports no SD card when formatting. +A reminder that two separate settings control whether an arriving message lights a dark screen. "Flash on new message" is in Settings, Keyboard, and it is the one that wakes the screen. "At a glance" is in Settings, Display, and it draws the preview text. Turning off the second one alone will not stop the screen lighting up. diff --git a/scripts/audio_test.lua b/scripts/audio_test.lua new file mode 100644 index 0000000..c539d3a --- /dev/null +++ b/scripts/audio_test.lua @@ -0,0 +1,104 @@ +-- Manual WAV/MP3 transport test for wada.audio. +-- SD test file: /Music/test.mp3 +-- App-local file: /apps/audio_test.d/test.mp3 on the active app storage. +local ui, sys, timer = wada.ui, wada.sys, wada.timer +local audio = wada.audio +local C = ui.colors + +local SD_PATH = "sd:/Music/test.mp3" +local APP_PATH = "test.mp3" + +local app = {} +local source = APP_PATH +local source_line, state_line, detail_line, command_line + +local function show_command(ok, err) + command_line:set(ok and "Command: accepted" or ("Command: " .. tostring(err or "rejected"))) + command_line:color(ok and C.good or C.bad) +end + +local function refresh() + if not audio then return end + local status = audio.status() + state_line:set("State: " .. tostring(status.state)) + state_line:color(status.state == "error" and C.bad or + status.state == "playing" and C.good or C.text) + local detail = "Source: " .. tostring(status.source or "-") .. + " Format: " .. tostring(status.format or "-") + if status.error then detail = detail .. " Error: " .. tostring(status.error) end + detail_line:set(detail) + detail_line:color(status.error and C.bad or C.sub) +end + +function app.on_open(w, h) + local caps = sys.caps() + source = APP_PATH + if caps.audio_sd and wada.sd and wada.sd.list then + local entries = wada.sd.list("/") + if entries then source = SD_PATH end + end + + ui.label("Audio playback test", 6, 4, 14, C.accent) + ui.label("audio=" .. tostring(caps.audio) .. + " wav=" .. tostring(caps.audio_wav) .. + " mp3=" .. tostring(caps.audio_mp3), 6, 24, 12, C.sub) + source_line = ui.label("File: " .. source, 6, 44, 12, C.text) + source_line:width(w - 12) + state_line = ui.label("State: stopped", 6, 64, 12, C.text) + detail_line = ui.label("Source: - Format: -", 6, 82, 12, C.sub) + detail_line:width(w - 12) + command_line = ui.label("Command: ready", 6, 100, 12, C.sub) + command_line:width(w - 12) + + if not caps.audio or not audio then + command_line:set("Command: wada.audio unavailable") + command_line:color(C.bad) + return + end + + local gap = 5 + local button_w = math.max(54, (w - 12 - gap * 3) // 4) + local x = 6 + ui.button("Play", x, 116, button_w, 30, function() + local ok, err = audio.play(source) + show_command(ok, err) + refresh() + end) + x = x + button_w + gap + ui.button("Pause", x, 116, button_w, 30, function() + show_command(audio.pause()) + refresh() + end) + x = x + button_w + gap + ui.button("Resume", x, 116, button_w, 30, function() + show_command(audio.resume()) + refresh() + end) + x = x + button_w + gap + ui.button("Stop", x, 116, button_w, 30, function() + show_command(audio.stop()) + refresh() + end) + + if caps.audio_sd then + ui.button("Switch SD / app storage", 6, 150, math.min(w - 12, 190), 26, function() + source = source == SD_PATH and APP_PATH or SD_PATH + source_line:set("File: " .. source) + command_line:set("Command: source changed") + command_line:color(C.sub) + end) + end + + timer.every(200) + refresh() +end + +function app.on_tick() + refresh() +end + +function app.on_close() + if audio then audio.stop() end +end + +return app diff --git a/scripts/build-all-targets.sh b/scripts/build-all-targets.sh new file mode 100755 index 0000000..cff052a --- /dev/null +++ b/scripts/build-all-targets.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +# wadamesh: compile every board this repo can produce firmware for. Builds only — +# nothing is flashed, uploaded or published. +# +# WHY THIS SCRIPT EXISTS: "does it still build?" spans two toolchains. The eight +# S3/PIO boards come from platformio.ini, but the Tanmatsu and the T-Display P4 +# are standalone ESP-IDF apps with their own build.sh wrappers, and release.sh +# says so in a comment while building only the PlatformIO half. So a change that +# broke an IDF-only board was invisible until someone cut a release by hand. This +# builds all ten, keeps going after a failure, and prints one table at the end. +# +# Usage: +# scripts/build-all-targets.sh # everything it can build here +# scripts/build-all-targets.sh --list # show the targets, build nothing +# scripts/build-all-targets.sh --pio # PlatformIO boards only +# scripts/build-all-targets.sh --idf # Tanmatsu + T-Display P4 only +# scripts/build-all-targets.sh --fail-fast # stop at the first failure +# scripts/build-all-targets.sh -- -v # pass the rest through to pio run +# +# Optional: +# PIO=/path/to/pio # override the PlatformIO executable (default: on PATH) +# +# The PlatformIO env list is read from platformio.ini rather than hard-coded, so +# adding a board to that file is enough — this cannot drift out of step with it. +# +# Exit status is 0 only when every target that ran succeeded. Skipped IDF targets +# (toolchain not installed on this machine) are reported as SKIP and do NOT fail +# the run — see the note printed at the end for how to enable them. +set -uo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$ROOT" + +PIO="${PIO:-$(command -v pio || true)}" +LOGDIR="$ROOT/out/build-logs" + +DO_PIO=1; DO_IDF=1; LIST_ONLY=0; FAIL_FAST=0; PASSTHRU=() +while [ $# -gt 0 ]; do + case "$1" in + --list) LIST_ONLY=1 ;; + --pio) DO_IDF=0 ;; + --idf) DO_PIO=0 ;; + --fail-fast) FAIL_FAST=1 ;; + --) shift; PASSTHRU=("$@"); break ;; + -h|--help) sed -n '2,28p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) echo "unknown option: $1 (try --help)" >&2; exit 2 ;; + esac + shift +done + +# --- Target inventory ---------------------------------------------------------- +# PlatformIO envs, in platformio.ini order. Every [env:NAME] is a board we ship. +PIO_ENVS=() +while IFS= read -r e; do PIO_ENVS+=("$e"); done < <(sed -n 's/^\[env:\(.*\)\]$/\1/p' platformio.ini) + +# The two ESP-IDF apps. Each is /build.sh, which needs a project-local +# ESP-IDF 5.5.1; the P4 reuses the Tanmatsu's via symlinks, so one check covers +# both. Absent toolchain = SKIP, not failure: a laptop with only PlatformIO +# installed should still be able to run this and get the eight boards checked. +IDF_DIRS=(tanmatsu tdisplay_p4) +idf_available() { [ -f "$ROOT/tanmatsu/esp-idf/export.sh" ]; } + +if [ "$LIST_ONLY" = 1 ]; then + echo "PlatformIO targets (${#PIO_ENVS[@]}):" + for e in "${PIO_ENVS[@]}"; do echo " $e"; done + echo "ESP-IDF targets (${#IDF_DIRS[@]}):" + for d in "${IDF_DIRS[@]}"; do + idf_available && echo " $d" || echo " $d (toolchain not installed here - would SKIP)" + done + exit 0 +fi + +[ "$DO_PIO" = 1 ] && [ -z "$PIO" ] && { echo "ERROR: no 'pio' on PATH - set PIO=/path/to/pio" >&2; exit 1; } + +mkdir -p "$LOGDIR" +NAMES=(); RESULTS=(); TIMES=(); FAILED=0 + +# run_target