├── .github ├── FUNDING.yml └── workflows │ ├── build.yml │ └── docc.yml ├── .gitignore ├── .swiftlint.yml ├── LICENSE ├── Package.swift ├── README.md ├── RELEASE_NOTES.md ├── Resources ├── Icon.png ├── Logo.jpg └── Preview.jpg ├── Sources └── StandardButtons │ ├── Resources │ └── Localizable.xcstrings │ ├── StandardButtonType.swift │ └── StandardButtons.docc │ ├── Resources │ ├── Icon.png │ ├── Logo.png │ └── Preview.jpg │ └── StandardButtons.md ├── Tests └── StandardButtonsTests │ └── StandardButtonsTests.swift ├── package_version.sh └── scripts ├── build.sh ├── chmod.sh ├── docc.sh ├── framework.sh ├── git_default_branch.sh ├── package_docc.sh ├── package_framework.sh ├── package_name.sh ├── package_version.sh ├── sync_from.sh ├── test.sh ├── version.sh ├── version_bump.sh ├── version_number.sh ├── version_validate_git.sh └── version_validate_target.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [danielsaidi] 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This workflow builds and tests the project. 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift 3 | 4 | name: Build Runner 5 | 6 | on: 7 | push: 8 | branches: ["main"] 9 | pull_request: 10 | branches: ["main"] 11 | 12 | jobs: 13 | build: 14 | runs-on: macos-15 15 | steps: 16 | - uses: actions/checkout@v3 17 | - uses: maxim-lobanov/setup-xcode@v1 18 | with: 19 | xcode-version: latest-stable 20 | - name: Build all platforms 21 | run: bash scripts/build.sh ${{ github.event.repository.name }} 22 | - name: Test iOS 23 | run: bash scripts/test.sh ${{ github.event.repository.name }} 24 | -------------------------------------------------------------------------------- /.github/workflows/docc.yml: -------------------------------------------------------------------------------- 1 | # This workflow builds publish DocC docs to GitHub Pages. 2 | # Source: https://maxxfrazer.medium.com/deploying-docc-with-github-actions-218c5ca6cad5 3 | # Sample: https://github.com/AgoraIO-Community/VideoUIKit-iOS/blob/main/.github/workflows/deploy_docs.yml 4 | 5 | name: DocC Runner 6 | 7 | on: 8 | push: 9 | branches: ["main"] 10 | 11 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | # Allow one concurrent deployment 18 | concurrency: 19 | group: "pages" 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | deploy: 24 | environment: 25 | name: github-pages 26 | url: ${{ steps.deployment.outputs.page_url }} 27 | runs-on: macos-15 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | - id: pages 32 | name: Setup Pages 33 | uses: actions/configure-pages@v4 34 | - name: Select Xcode version 35 | uses: maxim-lobanov/setup-xcode@v1 36 | with: 37 | xcode-version: latest-stable 38 | - name: Build DocC 39 | run: bash scripts/docc.sh ${{ github.event.repository.name }} 40 | - name: Upload artifact 41 | uses: actions/upload-pages-artifact@v3 42 | with: 43 | path: '.build/docs-iOS' 44 | - id: deployment 45 | name: Deploy to GitHub Pages 46 | uses: actions/deploy-pages@v4 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPM defaults 2 | .DS_Store 3 | /.build 4 | /Packages 5 | .swiftpm/ 6 | xcuserdata/ 7 | DerivedData/ 8 | 9 | **/*.xcuserstate -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - file_length 3 | - identifier_name 4 | - trailing_whitespace 5 | - vertical_whitespace 6 | 7 | included: 8 | - Sources 9 | - Tests 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Daniel Saidi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 6.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "StandardButtons", 7 | defaultLocalization: "en", 8 | platforms: [ 9 | .iOS(.v15), 10 | .tvOS(.v15), 11 | .watchOS(.v8), 12 | .macOS(.v12), 13 | .visionOS(.v1) 14 | ], 15 | products: [ 16 | .library( 17 | name: "StandardButtons", 18 | targets: ["StandardButtons"] 19 | ) 20 | ], 21 | targets: [ 22 | .target( 23 | name: "StandardButtons", 24 | resources: [.process("Resources")] 25 | ), 26 | .testTarget( 27 | name: "StandardButtonsTests", 28 | dependencies: ["StandardButtons"] 29 | ) 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Project Icon 3 |

4 | 5 |

6 | Version 7 | Swift 6.0 8 | Documentation 9 | MIT License 10 | Sponsor my work 11 |

12 | 13 | 14 | # StandardButtons 15 | 16 | StandardButtons is a SwiftUI library that lets you create standard button types, with localized titles, icons & roles. 17 | 18 |

19 | StandardButtons preview 20 |

21 | 22 | StandardButtons defines **110** standard button types, like ``.add``, ``.delete``, ``.edit``, ``.done``, etc. Each button type has a localized ``.title``, an ``.image``, a ``.role``, and an optional ``.keyboardShortcut``. 23 | 24 | 25 | 26 | ## Installation 27 | 28 | StandardButtons can be installed with the Swift Package Manager: 29 | 30 | ``` 31 | https://github.com/danielsaidi/StandardButtons.git 32 | ``` 33 | 34 | 35 | ## Support My Work 36 | 37 | You can [become a sponsor][Sponsors] to help me dedicate more time on my various [open-source tools][OpenSource]. Every contribution, no matter the size, makes a real difference in keeping these tools free and actively developed. 38 | 39 | 40 | 41 | ## Getting Started 42 | 43 | With StandardButtons, just `import StandardButtons` and use `Button(_:action:)` to create a standard button: 44 | 45 | ```swift 46 | Button(.add) { 47 | // Add your custom add logic here 48 | } 49 | ``` 50 | 51 | The code above will render a regular SwiftUI ``Button`` and works on all major Apple platforms (iOS, macOS, tvOS, watchOS, visionOS). 52 | 53 | 54 | 55 | ## Localization 56 | 57 | This library is localized in the following languages: 58 | 59 | * 🇺🇸 English (US) 60 | * 🇫🇷 French 61 | * 🇬🇪 Georgian 62 | * 🇩🇪 German 63 | * 🇪🇸 Spanish 64 | * 🇸🇪 Swedish 65 | 66 | You can add more locales to the `Localizable.xcstrings` file in the `Resources` folder. 67 | 68 | 69 | 70 | ## Documentation 71 | 72 | The online [documentation][Documentation] has more information, articles, code examples, etc. 73 | 74 | 75 | 76 | ## Demo Application 77 | 78 | This repository will get a demo app after it reaches 100 stars. 79 | 80 | 81 | 82 | ## Contact 83 | 84 | Feel free to reach out if you have questions, or want to contribute in any way: 85 | 86 | * Website: [danielsaidi.com][Website] 87 | * E-mail: [daniel.saidi@gmail.com][Email] 88 | * Bluesky: [@danielsaidi@bsky.social][Bluesky] 89 | * Mastodon: [@danielsaidi@mastodon.social][Mastodon] 90 | 91 | 92 | 93 | ## License 94 | 95 | StandardButtons is available under the MIT license. See the [LICENSE][License] file for more info. 96 | 97 | 98 | 99 | [Email]: mailto:daniel.saidi@gmail.com 100 | [Website]: https://danielsaidi.com 101 | [GitHub]: https://github.com/danielsaidi 102 | [OpenSource]: https://danielsaidi.com/opensource 103 | [Sponsors]: https://github.com/sponsors/danielsaidi 104 | 105 | [Bluesky]: https://bsky.app/profile/danielsaidi.bsky.social 106 | [Mastodon]: https://mastodon.social/@danielsaidi 107 | [Twitter]: https://twitter.com/danielsaidi 108 | 109 | [Documentation]: https://danielsaidi.github.io/StandardButtons 110 | [License]: https://github.com/danielsaidi/StandardButtons/blob/master/LICENSE 111 | -------------------------------------------------------------------------------- /RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | StandardButtons will use semver after 1.0. 4 | 5 | Until then, breaking changes can happen in any version, and deprecated features may be removed in any minor version bump. 6 | 7 | 8 | ## 0.4.1 9 | 10 | This version adds support for French. 11 | 12 | ### 🌐 New Localization 13 | 14 | * 🇫🇷 French, thanks to [@Dean151](https://github.com/Dean151). 15 | 16 | 17 | ## 0.4 18 | 19 | This version adds support for Georgian. 20 | 21 | ### 🌐 New Localization 22 | 23 | * 🇬🇪 Georgian, thanks to [@desp0o](https://github.com/desp0o). 24 | 25 | 26 | ## 0.3 27 | 28 | This version supports 110 standard button types and adds support for German and Spanish. 29 | 30 | ### ✨ Features 31 | 32 | * This version adds MANY new standard button types. 33 | 34 | ### 🌐 New Localization 35 | 36 | * 🇩🇪 German, thanks to [@nidegen](https://github.com/nidegen). 37 | * 🇪🇸 Spanish. 38 | 39 | 40 | ## 0.2 41 | 42 | This version renames the library to `StandardButtons`. 43 | 44 | 45 | ## 0.1 46 | 47 | This version adds a new `StandardButtonType`. 48 | 49 | You can use this with the `Button` initializer, to create a standard button. 50 | -------------------------------------------------------------------------------- /Resources/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielsaidi/StandardButtons/c8d133ed236c64a0b147688c582497c936f33160/Resources/Icon.png -------------------------------------------------------------------------------- /Resources/Logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielsaidi/StandardButtons/c8d133ed236c64a0b147688c582497c936f33160/Resources/Logo.jpg -------------------------------------------------------------------------------- /Resources/Preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielsaidi/StandardButtons/c8d133ed236c64a0b147688c582497c936f33160/Resources/Preview.jpg -------------------------------------------------------------------------------- /Sources/StandardButtons/Resources/Localizable.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "Button.Add" : { 5 | "localizations" : { 6 | "de" : { 7 | "stringUnit" : { 8 | "state" : "translated", 9 | "value" : "Hinzufügen" 10 | } 11 | }, 12 | "en" : { 13 | "stringUnit" : { 14 | "state" : "translated", 15 | "value" : "Add" 16 | } 17 | }, 18 | "es" : { 19 | "stringUnit" : { 20 | "state" : "translated", 21 | "value" : "Añadir" 22 | } 23 | }, 24 | "fr" : { 25 | "stringUnit" : { 26 | "state" : "translated", 27 | "value" : "Ajouter" 28 | } 29 | }, 30 | "ka" : { 31 | "stringUnit" : { 32 | "state" : "translated", 33 | "value" : "დამატება" 34 | } 35 | }, 36 | "sv" : { 37 | "stringUnit" : { 38 | "state" : "translated", 39 | "value" : "Lägg till" 40 | } 41 | } 42 | } 43 | }, 44 | "Button.Apply" : { 45 | "localizations" : { 46 | "de" : { 47 | "stringUnit" : { 48 | "state" : "translated", 49 | "value" : "Anwenden" 50 | } 51 | }, 52 | "en" : { 53 | "stringUnit" : { 54 | "state" : "translated", 55 | "value" : "Apply" 56 | } 57 | }, 58 | "es" : { 59 | "stringUnit" : { 60 | "state" : "translated", 61 | "value" : "Aplicar" 62 | } 63 | }, 64 | "fr" : { 65 | "stringUnit" : { 66 | "state" : "translated", 67 | "value" : "Appliquer" 68 | } 69 | }, 70 | "ka" : { 71 | "stringUnit" : { 72 | "state" : "translated", 73 | "value" : "დათანხმება" 74 | } 75 | }, 76 | "sv" : { 77 | "stringUnit" : { 78 | "state" : "translated", 79 | "value" : "Tillämpa" 80 | } 81 | } 82 | } 83 | }, 84 | "Button.Archive" : { 85 | "localizations" : { 86 | "de" : { 87 | "stringUnit" : { 88 | "state" : "translated", 89 | "value" : "Archivieren" 90 | } 91 | }, 92 | "en" : { 93 | "stringUnit" : { 94 | "state" : "translated", 95 | "value" : "Archive" 96 | } 97 | }, 98 | "es" : { 99 | "stringUnit" : { 100 | "state" : "translated", 101 | "value" : "Archivar" 102 | } 103 | }, 104 | "fr" : { 105 | "stringUnit" : { 106 | "state" : "translated", 107 | "value" : "Archiver" 108 | } 109 | }, 110 | "ka" : { 111 | "stringUnit" : { 112 | "state" : "translated", 113 | "value" : "არქივი" 114 | } 115 | }, 116 | "sv" : { 117 | "stringUnit" : { 118 | "state" : "translated", 119 | "value" : "Arkivera" 120 | } 121 | } 122 | } 123 | }, 124 | "Button.Attach" : { 125 | "localizations" : { 126 | "de" : { 127 | "stringUnit" : { 128 | "state" : "translated", 129 | "value" : "Anhängen" 130 | } 131 | }, 132 | "en" : { 133 | "stringUnit" : { 134 | "state" : "translated", 135 | "value" : "Attach" 136 | } 137 | }, 138 | "es" : { 139 | "stringUnit" : { 140 | "state" : "translated", 141 | "value" : "Adjuntar" 142 | } 143 | }, 144 | "fr" : { 145 | "stringUnit" : { 146 | "state" : "translated", 147 | "value" : "Attacher" 148 | } 149 | }, 150 | "ka" : { 151 | "stringUnit" : { 152 | "state" : "translated", 153 | "value" : "მიმაგრება" 154 | } 155 | }, 156 | "sv" : { 157 | "stringUnit" : { 158 | "state" : "translated", 159 | "value" : "Bifoga" 160 | } 161 | } 162 | } 163 | }, 164 | "Button.Back" : { 165 | "localizations" : { 166 | "de" : { 167 | "stringUnit" : { 168 | "state" : "translated", 169 | "value" : "Zurück" 170 | } 171 | }, 172 | "en" : { 173 | "stringUnit" : { 174 | "state" : "translated", 175 | "value" : "Back" 176 | } 177 | }, 178 | "es" : { 179 | "stringUnit" : { 180 | "state" : "translated", 181 | "value" : "Atrás" 182 | } 183 | }, 184 | "fr" : { 185 | "stringUnit" : { 186 | "state" : "translated", 187 | "value" : "Retour" 188 | } 189 | }, 190 | "ka" : { 191 | "stringUnit" : { 192 | "state" : "translated", 193 | "value" : "უკან" 194 | } 195 | }, 196 | "sv" : { 197 | "stringUnit" : { 198 | "state" : "translated", 199 | "value" : "Tillbaka" 200 | } 201 | } 202 | } 203 | }, 204 | "Button.Bookmark" : { 205 | "localizations" : { 206 | "de" : { 207 | "stringUnit" : { 208 | "state" : "translated", 209 | "value" : "Lesezeichen" 210 | } 211 | }, 212 | "en" : { 213 | "stringUnit" : { 214 | "state" : "translated", 215 | "value" : "Bookmark" 216 | } 217 | }, 218 | "es" : { 219 | "stringUnit" : { 220 | "state" : "translated", 221 | "value" : "Marcar" 222 | } 223 | }, 224 | "fr" : { 225 | "stringUnit" : { 226 | "state" : "translated", 227 | "value" : "Marque page" 228 | } 229 | }, 230 | "ka" : { 231 | "stringUnit" : { 232 | "state" : "translated", 233 | "value" : "ჩანიშნვა" 234 | } 235 | }, 236 | "sv" : { 237 | "stringUnit" : { 238 | "state" : "translated", 239 | "value" : "Bokmärke" 240 | } 241 | } 242 | } 243 | }, 244 | "Button.Browse" : { 245 | "localizations" : { 246 | "de" : { 247 | "stringUnit" : { 248 | "state" : "translated", 249 | "value" : "Durchsuchen" 250 | } 251 | }, 252 | "en" : { 253 | "stringUnit" : { 254 | "state" : "translated", 255 | "value" : "Browse" 256 | } 257 | }, 258 | "es" : { 259 | "stringUnit" : { 260 | "state" : "translated", 261 | "value" : "Explorar" 262 | } 263 | }, 264 | "fr" : { 265 | "stringUnit" : { 266 | "state" : "translated", 267 | "value" : "Parcourir" 268 | } 269 | }, 270 | "ka" : { 271 | "stringUnit" : { 272 | "state" : "translated", 273 | "value" : "დათვალიერება" 274 | } 275 | }, 276 | "sv" : { 277 | "stringUnit" : { 278 | "state" : "translated", 279 | "value" : "Bläddra" 280 | } 281 | } 282 | } 283 | }, 284 | "Button.Call" : { 285 | "localizations" : { 286 | "de" : { 287 | "stringUnit" : { 288 | "state" : "translated", 289 | "value" : "Anrufen" 290 | } 291 | }, 292 | "en" : { 293 | "stringUnit" : { 294 | "state" : "translated", 295 | "value" : "Call" 296 | } 297 | }, 298 | "es" : { 299 | "stringUnit" : { 300 | "state" : "translated", 301 | "value" : "Llamar" 302 | } 303 | }, 304 | "fr" : { 305 | "stringUnit" : { 306 | "state" : "translated", 307 | "value" : "Appeler" 308 | } 309 | }, 310 | "ka" : { 311 | "stringUnit" : { 312 | "state" : "translated", 313 | "value" : "დარეკვა" 314 | } 315 | }, 316 | "sv" : { 317 | "stringUnit" : { 318 | "state" : "translated", 319 | "value" : "Ring upp" 320 | } 321 | } 322 | } 323 | }, 324 | "Button.Cancel" : { 325 | "localizations" : { 326 | "de" : { 327 | "stringUnit" : { 328 | "state" : "translated", 329 | "value" : "Abbrechen" 330 | } 331 | }, 332 | "en" : { 333 | "stringUnit" : { 334 | "state" : "translated", 335 | "value" : "Cancel" 336 | } 337 | }, 338 | "es" : { 339 | "stringUnit" : { 340 | "state" : "translated", 341 | "value" : "Cancelar" 342 | } 343 | }, 344 | "fr" : { 345 | "stringUnit" : { 346 | "state" : "translated", 347 | "value" : "Annuler" 348 | } 349 | }, 350 | "ka" : { 351 | "stringUnit" : { 352 | "state" : "translated", 353 | "value" : "გაუქმება" 354 | } 355 | }, 356 | "sv" : { 357 | "stringUnit" : { 358 | "state" : "translated", 359 | "value" : "Avbryt" 360 | } 361 | } 362 | } 363 | }, 364 | "Button.Close" : { 365 | "localizations" : { 366 | "de" : { 367 | "stringUnit" : { 368 | "state" : "translated", 369 | "value" : "Schliessen" 370 | } 371 | }, 372 | "en" : { 373 | "stringUnit" : { 374 | "state" : "translated", 375 | "value" : "Close" 376 | } 377 | }, 378 | "es" : { 379 | "stringUnit" : { 380 | "state" : "translated", 381 | "value" : "Cerrar" 382 | } 383 | }, 384 | "fr" : { 385 | "stringUnit" : { 386 | "state" : "translated", 387 | "value" : "Fermer" 388 | } 389 | }, 390 | "ka" : { 391 | "stringUnit" : { 392 | "state" : "translated", 393 | "value" : "დახურვა" 394 | } 395 | }, 396 | "sv" : { 397 | "stringUnit" : { 398 | "state" : "translated", 399 | "value" : "Stäng" 400 | } 401 | } 402 | } 403 | }, 404 | "Button.Collapse" : { 405 | "localizations" : { 406 | "de" : { 407 | "stringUnit" : { 408 | "state" : "translated", 409 | "value" : "Einklappen" 410 | } 411 | }, 412 | "en" : { 413 | "stringUnit" : { 414 | "state" : "translated", 415 | "value" : "Collapse" 416 | } 417 | }, 418 | "es" : { 419 | "stringUnit" : { 420 | "state" : "translated", 421 | "value" : "Contraer" 422 | } 423 | }, 424 | "fr" : { 425 | "stringUnit" : { 426 | "state" : "translated", 427 | "value" : "Réduire" 428 | } 429 | }, 430 | "ka" : { 431 | "stringUnit" : { 432 | "state" : "translated", 433 | "value" : "ჩაკეცვა" 434 | } 435 | }, 436 | "sv" : { 437 | "stringUnit" : { 438 | "state" : "translated", 439 | "value" : "Komprimera" 440 | } 441 | } 442 | } 443 | }, 444 | "Button.Confirm" : { 445 | "localizations" : { 446 | "de" : { 447 | "stringUnit" : { 448 | "state" : "translated", 449 | "value" : "Bestätigen" 450 | } 451 | }, 452 | "en" : { 453 | "stringUnit" : { 454 | "state" : "translated", 455 | "value" : "Confirm" 456 | } 457 | }, 458 | "es" : { 459 | "stringUnit" : { 460 | "state" : "translated", 461 | "value" : "Confirmar" 462 | } 463 | }, 464 | "fr" : { 465 | "stringUnit" : { 466 | "state" : "translated", 467 | "value" : "Confirmer" 468 | } 469 | }, 470 | "ka" : { 471 | "stringUnit" : { 472 | "state" : "translated", 473 | "value" : "დადასტურება" 474 | } 475 | }, 476 | "sv" : { 477 | "stringUnit" : { 478 | "state" : "translated", 479 | "value" : "Bekräfta" 480 | } 481 | } 482 | } 483 | }, 484 | "Button.Connect" : { 485 | "localizations" : { 486 | "de" : { 487 | "stringUnit" : { 488 | "state" : "translated", 489 | "value" : "Verbinden" 490 | } 491 | }, 492 | "en" : { 493 | "stringUnit" : { 494 | "state" : "translated", 495 | "value" : "Connect" 496 | } 497 | }, 498 | "es" : { 499 | "stringUnit" : { 500 | "state" : "translated", 501 | "value" : "Conectar" 502 | } 503 | }, 504 | "fr" : { 505 | "stringUnit" : { 506 | "state" : "translated", 507 | "value" : "Connexion" 508 | } 509 | }, 510 | "ka" : { 511 | "stringUnit" : { 512 | "state" : "translated", 513 | "value" : "დაკავშირება" 514 | } 515 | }, 516 | "sv" : { 517 | "stringUnit" : { 518 | "state" : "translated", 519 | "value" : "Anslut" 520 | } 521 | } 522 | } 523 | }, 524 | "Button.Copy" : { 525 | "localizations" : { 526 | "de" : { 527 | "stringUnit" : { 528 | "state" : "translated", 529 | "value" : "Kopieren" 530 | } 531 | }, 532 | "en" : { 533 | "stringUnit" : { 534 | "state" : "translated", 535 | "value" : "Copy" 536 | } 537 | }, 538 | "es" : { 539 | "stringUnit" : { 540 | "state" : "translated", 541 | "value" : "Copiar" 542 | } 543 | }, 544 | "fr" : { 545 | "stringUnit" : { 546 | "state" : "translated", 547 | "value" : "Copier" 548 | } 549 | }, 550 | "ka" : { 551 | "stringUnit" : { 552 | "state" : "translated", 553 | "value" : "დაკოპირება" 554 | } 555 | }, 556 | "sv" : { 557 | "stringUnit" : { 558 | "state" : "translated", 559 | "value" : "Kopiera" 560 | } 561 | } 562 | } 563 | }, 564 | "Button.Create" : { 565 | "localizations" : { 566 | "de" : { 567 | "stringUnit" : { 568 | "state" : "translated", 569 | "value" : "Erstellen" 570 | } 571 | }, 572 | "en" : { 573 | "stringUnit" : { 574 | "state" : "translated", 575 | "value" : "Create" 576 | } 577 | }, 578 | "es" : { 579 | "stringUnit" : { 580 | "state" : "translated", 581 | "value" : "Crear" 582 | } 583 | }, 584 | "fr" : { 585 | "stringUnit" : { 586 | "state" : "translated", 587 | "value" : "Créer" 588 | } 589 | }, 590 | "ka" : { 591 | "stringUnit" : { 592 | "state" : "translated", 593 | "value" : "შექმნა" 594 | } 595 | }, 596 | "sv" : { 597 | "stringUnit" : { 598 | "state" : "translated", 599 | "value" : "Skapa" 600 | } 601 | } 602 | } 603 | }, 604 | "Button.Customize" : { 605 | "localizations" : { 606 | "de" : { 607 | "stringUnit" : { 608 | "state" : "translated", 609 | "value" : "Anpassen" 610 | } 611 | }, 612 | "en" : { 613 | "stringUnit" : { 614 | "state" : "translated", 615 | "value" : "Customize" 616 | } 617 | }, 618 | "es" : { 619 | "stringUnit" : { 620 | "state" : "translated", 621 | "value" : "Personalizar" 622 | } 623 | }, 624 | "fr" : { 625 | "stringUnit" : { 626 | "state" : "translated", 627 | "value" : "Personnaliser" 628 | } 629 | }, 630 | "ka" : { 631 | "stringUnit" : { 632 | "state" : "translated", 633 | "value" : "მორგება" 634 | } 635 | }, 636 | "sv" : { 637 | "stringUnit" : { 638 | "state" : "translated", 639 | "value" : "Anpassa" 640 | } 641 | } 642 | } 643 | }, 644 | "Button.Delete" : { 645 | "localizations" : { 646 | "de" : { 647 | "stringUnit" : { 648 | "state" : "translated", 649 | "value" : "Löschen" 650 | } 651 | }, 652 | "en" : { 653 | "stringUnit" : { 654 | "state" : "translated", 655 | "value" : "Delete" 656 | } 657 | }, 658 | "es" : { 659 | "stringUnit" : { 660 | "state" : "translated", 661 | "value" : "Eliminar" 662 | } 663 | }, 664 | "fr" : { 665 | "stringUnit" : { 666 | "state" : "translated", 667 | "value" : "Supprimer" 668 | } 669 | }, 670 | "ka" : { 671 | "stringUnit" : { 672 | "state" : "translated", 673 | "value" : "წაშლა" 674 | } 675 | }, 676 | "sv" : { 677 | "stringUnit" : { 678 | "state" : "translated", 679 | "value" : "Ta bort" 680 | } 681 | } 682 | } 683 | }, 684 | "Button.Deselect" : { 685 | "localizations" : { 686 | "de" : { 687 | "stringUnit" : { 688 | "state" : "translated", 689 | "value" : "Abwählen" 690 | } 691 | }, 692 | "en" : { 693 | "stringUnit" : { 694 | "state" : "translated", 695 | "value" : "Deselect" 696 | } 697 | }, 698 | "es" : { 699 | "stringUnit" : { 700 | "state" : "translated", 701 | "value" : "Deseleccionar" 702 | } 703 | }, 704 | "fr" : { 705 | "stringUnit" : { 706 | "state" : "translated", 707 | "value" : "Désélectionner" 708 | } 709 | }, 710 | "ka" : { 711 | "stringUnit" : { 712 | "state" : "translated", 713 | "value" : "მონიშნულის გაუქმება" 714 | } 715 | }, 716 | "sv" : { 717 | "stringUnit" : { 718 | "state" : "translated", 719 | "value" : "Avmarkera" 720 | } 721 | } 722 | } 723 | }, 724 | "Button.Disconnect" : { 725 | "localizations" : { 726 | "de" : { 727 | "stringUnit" : { 728 | "state" : "translated", 729 | "value" : "Trennen" 730 | } 731 | }, 732 | "en" : { 733 | "stringUnit" : { 734 | "state" : "translated", 735 | "value" : "Disconnect" 736 | } 737 | }, 738 | "es" : { 739 | "stringUnit" : { 740 | "state" : "translated", 741 | "value" : "Desconectar" 742 | } 743 | }, 744 | "fr" : { 745 | "stringUnit" : { 746 | "state" : "translated", 747 | "value" : "Déconnexion" 748 | } 749 | }, 750 | "ka" : { 751 | "stringUnit" : { 752 | "state" : "translated", 753 | "value" : "კავშირის შეწყვეტ" 754 | } 755 | }, 756 | "sv" : { 757 | "stringUnit" : { 758 | "state" : "translated", 759 | "value" : "Koppla från" 760 | } 761 | } 762 | } 763 | }, 764 | "Button.Dismiss" : { 765 | "localizations" : { 766 | "de" : { 767 | "stringUnit" : { 768 | "state" : "translated", 769 | "value" : "Verwerfen" 770 | } 771 | }, 772 | "en" : { 773 | "stringUnit" : { 774 | "state" : "translated", 775 | "value" : "Dismiss" 776 | } 777 | }, 778 | "es" : { 779 | "stringUnit" : { 780 | "state" : "translated", 781 | "value" : "Descartar" 782 | } 783 | }, 784 | "fr" : { 785 | "stringUnit" : { 786 | "state" : "translated", 787 | "value" : "Fermer" 788 | } 789 | }, 790 | "ka" : { 791 | "stringUnit" : { 792 | "state" : "translated", 793 | "value" : "გაუქმება" 794 | } 795 | }, 796 | "sv" : { 797 | "stringUnit" : { 798 | "state" : "translated", 799 | "value" : "Avfärda" 800 | } 801 | } 802 | } 803 | }, 804 | "Button.Done" : { 805 | "localizations" : { 806 | "de" : { 807 | "stringUnit" : { 808 | "state" : "translated", 809 | "value" : "Fertig" 810 | } 811 | }, 812 | "en" : { 813 | "stringUnit" : { 814 | "state" : "translated", 815 | "value" : "Done" 816 | } 817 | }, 818 | "es" : { 819 | "stringUnit" : { 820 | "state" : "translated", 821 | "value" : "Listo" 822 | } 823 | }, 824 | "fr" : { 825 | "stringUnit" : { 826 | "state" : "translated", 827 | "value" : "OK" 828 | } 829 | }, 830 | "ka" : { 831 | "stringUnit" : { 832 | "state" : "translated", 833 | "value" : "დასრულება" 834 | } 835 | }, 836 | "sv" : { 837 | "stringUnit" : { 838 | "state" : "translated", 839 | "value" : "Klar" 840 | } 841 | } 842 | } 843 | }, 844 | "Button.Download" : { 845 | "localizations" : { 846 | "de" : { 847 | "stringUnit" : { 848 | "state" : "translated", 849 | "value" : "Herunterladen" 850 | } 851 | }, 852 | "en" : { 853 | "stringUnit" : { 854 | "state" : "translated", 855 | "value" : "Download" 856 | } 857 | }, 858 | "es" : { 859 | "stringUnit" : { 860 | "state" : "translated", 861 | "value" : "Descargar" 862 | } 863 | }, 864 | "fr" : { 865 | "stringUnit" : { 866 | "state" : "translated", 867 | "value" : "Télécharger" 868 | } 869 | }, 870 | "ka" : { 871 | "stringUnit" : { 872 | "state" : "translated", 873 | "value" : "გადმოწერა" 874 | } 875 | }, 876 | "sv" : { 877 | "stringUnit" : { 878 | "state" : "translated", 879 | "value" : "Ladda ner" 880 | } 881 | } 882 | } 883 | }, 884 | "Button.Downloaded" : { 885 | "localizations" : { 886 | "de" : { 887 | "stringUnit" : { 888 | "state" : "translated", 889 | "value" : "Heruntergeladen" 890 | } 891 | }, 892 | "en" : { 893 | "stringUnit" : { 894 | "state" : "translated", 895 | "value" : "Downloaded" 896 | } 897 | }, 898 | "es" : { 899 | "stringUnit" : { 900 | "state" : "translated", 901 | "value" : "Descargado" 902 | } 903 | }, 904 | "fr" : { 905 | "stringUnit" : { 906 | "state" : "translated", 907 | "value" : "Téléchargé" 908 | } 909 | }, 910 | "ka" : { 911 | "stringUnit" : { 912 | "state" : "translated", 913 | "value" : "გადმოწერილია" 914 | } 915 | }, 916 | "sv" : { 917 | "stringUnit" : { 918 | "state" : "translated", 919 | "value" : "Nedladdad" 920 | } 921 | } 922 | } 923 | }, 924 | "Button.Edit" : { 925 | "localizations" : { 926 | "de" : { 927 | "stringUnit" : { 928 | "state" : "translated", 929 | "value" : "Bearbeiten" 930 | } 931 | }, 932 | "en" : { 933 | "stringUnit" : { 934 | "state" : "translated", 935 | "value" : "Edit" 936 | } 937 | }, 938 | "es" : { 939 | "stringUnit" : { 940 | "state" : "translated", 941 | "value" : "Editar" 942 | } 943 | }, 944 | "fr" : { 945 | "stringUnit" : { 946 | "state" : "translated", 947 | "value" : "Modifier" 948 | } 949 | }, 950 | "ka" : { 951 | "stringUnit" : { 952 | "state" : "translated", 953 | "value" : "ჩასწორება" 954 | } 955 | }, 956 | "sv" : { 957 | "stringUnit" : { 958 | "state" : "translated", 959 | "value" : "Ändra" 960 | } 961 | } 962 | } 963 | }, 964 | "Button.Email" : { 965 | "localizations" : { 966 | "de" : { 967 | "stringUnit" : { 968 | "state" : "translated", 969 | "value" : "Email" 970 | } 971 | }, 972 | "en" : { 973 | "stringUnit" : { 974 | "state" : "translated", 975 | "value" : "Email" 976 | } 977 | }, 978 | "es" : { 979 | "stringUnit" : { 980 | "state" : "translated", 981 | "value" : "Correo electrónico" 982 | } 983 | }, 984 | "fr" : { 985 | "stringUnit" : { 986 | "state" : "translated", 987 | "value" : "Email" 988 | } 989 | }, 990 | "ka" : { 991 | "stringUnit" : { 992 | "state" : "translated", 993 | "value" : "ელ. ფოსტა" 994 | } 995 | }, 996 | "sv" : { 997 | "stringUnit" : { 998 | "state" : "translated", 999 | "value" : "E-post" 1000 | } 1001 | } 1002 | } 1003 | }, 1004 | "Button.End" : { 1005 | "localizations" : { 1006 | "de" : { 1007 | "stringUnit" : { 1008 | "state" : "translated", 1009 | "value" : "Beenden" 1010 | } 1011 | }, 1012 | "en" : { 1013 | "stringUnit" : { 1014 | "state" : "translated", 1015 | "value" : "End" 1016 | } 1017 | }, 1018 | "es" : { 1019 | "stringUnit" : { 1020 | "state" : "translated", 1021 | "value" : "Finalizar" 1022 | } 1023 | }, 1024 | "fr" : { 1025 | "stringUnit" : { 1026 | "state" : "translated", 1027 | "value" : "Finir" 1028 | } 1029 | }, 1030 | "ka" : { 1031 | "stringUnit" : { 1032 | "state" : "translated", 1033 | "value" : "დასრულება" 1034 | } 1035 | }, 1036 | "sv" : { 1037 | "stringUnit" : { 1038 | "state" : "translated", 1039 | "value" : "Avsluta" 1040 | } 1041 | } 1042 | } 1043 | }, 1044 | "Button.Enter" : { 1045 | "localizations" : { 1046 | "de" : { 1047 | "stringUnit" : { 1048 | "state" : "translated", 1049 | "value" : "Eingeben" 1050 | } 1051 | }, 1052 | "en" : { 1053 | "stringUnit" : { 1054 | "state" : "translated", 1055 | "value" : "Enter" 1056 | } 1057 | }, 1058 | "es" : { 1059 | "stringUnit" : { 1060 | "state" : "translated", 1061 | "value" : "Ingresar" 1062 | } 1063 | }, 1064 | "fr" : { 1065 | "stringUnit" : { 1066 | "state" : "translated", 1067 | "value" : "Entrer" 1068 | } 1069 | }, 1070 | "ka" : { 1071 | "stringUnit" : { 1072 | "state" : "translated", 1073 | "value" : "შეყვანა" 1074 | } 1075 | }, 1076 | "sv" : { 1077 | "stringUnit" : { 1078 | "state" : "translated", 1079 | "value" : "Ange" 1080 | } 1081 | } 1082 | } 1083 | }, 1084 | "Button.Execute" : { 1085 | "localizations" : { 1086 | "de" : { 1087 | "stringUnit" : { 1088 | "state" : "translated", 1089 | "value" : "Ausführen" 1090 | } 1091 | }, 1092 | "en" : { 1093 | "stringUnit" : { 1094 | "state" : "translated", 1095 | "value" : "Execute" 1096 | } 1097 | }, 1098 | "es" : { 1099 | "stringUnit" : { 1100 | "state" : "translated", 1101 | "value" : "Ejecutar" 1102 | } 1103 | }, 1104 | "fr" : { 1105 | "stringUnit" : { 1106 | "state" : "translated", 1107 | "value" : "Exécuter" 1108 | } 1109 | }, 1110 | "ka" : { 1111 | "stringUnit" : { 1112 | "state" : "translated", 1113 | "value" : "შესრულება" 1114 | } 1115 | }, 1116 | "sv" : { 1117 | "stringUnit" : { 1118 | "state" : "translated", 1119 | "value" : "Utför" 1120 | } 1121 | } 1122 | } 1123 | }, 1124 | "Button.Exit" : { 1125 | "localizations" : { 1126 | "de" : { 1127 | "stringUnit" : { 1128 | "state" : "translated", 1129 | "value" : "Verlassen" 1130 | } 1131 | }, 1132 | "en" : { 1133 | "stringUnit" : { 1134 | "state" : "translated", 1135 | "value" : "Exit" 1136 | } 1137 | }, 1138 | "es" : { 1139 | "stringUnit" : { 1140 | "state" : "translated", 1141 | "value" : "Salir" 1142 | } 1143 | }, 1144 | "fr" : { 1145 | "stringUnit" : { 1146 | "state" : "translated", 1147 | "value" : "Sortir" 1148 | } 1149 | }, 1150 | "ka" : { 1151 | "stringUnit" : { 1152 | "state" : "translated", 1153 | "value" : "გამოსვლა" 1154 | } 1155 | }, 1156 | "sv" : { 1157 | "stringUnit" : { 1158 | "state" : "translated", 1159 | "value" : "Avsluta" 1160 | } 1161 | } 1162 | } 1163 | }, 1164 | "Button.Expand" : { 1165 | "localizations" : { 1166 | "de" : { 1167 | "stringUnit" : { 1168 | "state" : "translated", 1169 | "value" : "Erweitern" 1170 | } 1171 | }, 1172 | "en" : { 1173 | "stringUnit" : { 1174 | "state" : "translated", 1175 | "value" : "Expand" 1176 | } 1177 | }, 1178 | "es" : { 1179 | "stringUnit" : { 1180 | "state" : "translated", 1181 | "value" : "Expandir" 1182 | } 1183 | }, 1184 | "fr" : { 1185 | "stringUnit" : { 1186 | "state" : "translated", 1187 | "value" : "Agrandir" 1188 | } 1189 | }, 1190 | "ka" : { 1191 | "stringUnit" : { 1192 | "state" : "translated", 1193 | "value" : "გაშლა" 1194 | } 1195 | }, 1196 | "sv" : { 1197 | "stringUnit" : { 1198 | "state" : "translated", 1199 | "value" : "Expandera" 1200 | } 1201 | } 1202 | } 1203 | }, 1204 | "Button.Export" : { 1205 | "localizations" : { 1206 | "de" : { 1207 | "stringUnit" : { 1208 | "state" : "translated", 1209 | "value" : "Exportieren" 1210 | } 1211 | }, 1212 | "en" : { 1213 | "stringUnit" : { 1214 | "state" : "translated", 1215 | "value" : "Export" 1216 | } 1217 | }, 1218 | "es" : { 1219 | "stringUnit" : { 1220 | "state" : "translated", 1221 | "value" : "Exportar" 1222 | } 1223 | }, 1224 | "fr" : { 1225 | "stringUnit" : { 1226 | "state" : "translated", 1227 | "value" : "Exporter" 1228 | } 1229 | }, 1230 | "ka" : { 1231 | "stringUnit" : { 1232 | "state" : "translated", 1233 | "value" : "ექსპორტი" 1234 | } 1235 | }, 1236 | "sv" : { 1237 | "stringUnit" : { 1238 | "state" : "translated", 1239 | "value" : "Exportera" 1240 | } 1241 | } 1242 | } 1243 | }, 1244 | "Button.Favorite" : { 1245 | "localizations" : { 1246 | "de" : { 1247 | "stringUnit" : { 1248 | "state" : "translated", 1249 | "value" : "Favorisieren" 1250 | } 1251 | }, 1252 | "en" : { 1253 | "stringUnit" : { 1254 | "state" : "translated", 1255 | "value" : "Favorite" 1256 | } 1257 | }, 1258 | "es" : { 1259 | "stringUnit" : { 1260 | "state" : "translated", 1261 | "value" : "Favorito" 1262 | } 1263 | }, 1264 | "fr" : { 1265 | "stringUnit" : { 1266 | "state" : "translated", 1267 | "value" : "Ajouter aux favoris" 1268 | } 1269 | }, 1270 | "ka" : { 1271 | "stringUnit" : { 1272 | "state" : "translated", 1273 | "value" : "რჩეული" 1274 | } 1275 | }, 1276 | "sv" : { 1277 | "stringUnit" : { 1278 | "state" : "translated", 1279 | "value" : "Favorit" 1280 | } 1281 | } 1282 | } 1283 | }, 1284 | "Button.Filter" : { 1285 | "localizations" : { 1286 | "de" : { 1287 | "stringUnit" : { 1288 | "state" : "translated", 1289 | "value" : "Filtern" 1290 | } 1291 | }, 1292 | "en" : { 1293 | "stringUnit" : { 1294 | "state" : "translated", 1295 | "value" : "Filter" 1296 | } 1297 | }, 1298 | "es" : { 1299 | "stringUnit" : { 1300 | "state" : "translated", 1301 | "value" : "Filtrar" 1302 | } 1303 | }, 1304 | "fr" : { 1305 | "stringUnit" : { 1306 | "state" : "translated", 1307 | "value" : "Filtrer" 1308 | } 1309 | }, 1310 | "ka" : { 1311 | "stringUnit" : { 1312 | "state" : "translated", 1313 | "value" : "ფილტრი" 1314 | } 1315 | }, 1316 | "sv" : { 1317 | "stringUnit" : { 1318 | "state" : "translated", 1319 | "value" : "Filtrera" 1320 | } 1321 | } 1322 | } 1323 | }, 1324 | "Button.Forward" : { 1325 | "localizations" : { 1326 | "de" : { 1327 | "stringUnit" : { 1328 | "state" : "translated", 1329 | "value" : "Weiterleiten" 1330 | } 1331 | }, 1332 | "en" : { 1333 | "stringUnit" : { 1334 | "state" : "translated", 1335 | "value" : "Forward" 1336 | } 1337 | }, 1338 | "es" : { 1339 | "stringUnit" : { 1340 | "state" : "translated", 1341 | "value" : "Reenviar" 1342 | } 1343 | }, 1344 | "fr" : { 1345 | "stringUnit" : { 1346 | "state" : "translated", 1347 | "value" : "Suivant" 1348 | } 1349 | }, 1350 | "ka" : { 1351 | "stringUnit" : { 1352 | "state" : "translated", 1353 | "value" : "გადაგზავნა" 1354 | } 1355 | }, 1356 | "sv" : { 1357 | "stringUnit" : { 1358 | "state" : "translated", 1359 | "value" : "Vidarebefordra" 1360 | } 1361 | } 1362 | } 1363 | }, 1364 | "Button.Help" : { 1365 | "localizations" : { 1366 | "de" : { 1367 | "stringUnit" : { 1368 | "state" : "translated", 1369 | "value" : "Hilfe" 1370 | } 1371 | }, 1372 | "en" : { 1373 | "stringUnit" : { 1374 | "state" : "translated", 1375 | "value" : "Help" 1376 | } 1377 | }, 1378 | "es" : { 1379 | "stringUnit" : { 1380 | "state" : "translated", 1381 | "value" : "Ayuda" 1382 | } 1383 | }, 1384 | "fr" : { 1385 | "stringUnit" : { 1386 | "state" : "translated", 1387 | "value" : "Aide" 1388 | } 1389 | }, 1390 | "ka" : { 1391 | "stringUnit" : { 1392 | "state" : "translated", 1393 | "value" : "დახმარება" 1394 | } 1395 | }, 1396 | "sv" : { 1397 | "stringUnit" : { 1398 | "state" : "translated", 1399 | "value" : "Hjälp" 1400 | } 1401 | } 1402 | } 1403 | }, 1404 | "Button.Hide" : { 1405 | "localizations" : { 1406 | "de" : { 1407 | "stringUnit" : { 1408 | "state" : "translated", 1409 | "value" : "Ausblenden" 1410 | } 1411 | }, 1412 | "en" : { 1413 | "stringUnit" : { 1414 | "state" : "translated", 1415 | "value" : "Hide" 1416 | } 1417 | }, 1418 | "es" : { 1419 | "stringUnit" : { 1420 | "state" : "translated", 1421 | "value" : "Ocultar" 1422 | } 1423 | }, 1424 | "fr" : { 1425 | "stringUnit" : { 1426 | "state" : "translated", 1427 | "value" : "Cacher" 1428 | } 1429 | }, 1430 | "ka" : { 1431 | "stringUnit" : { 1432 | "state" : "translated", 1433 | "value" : "დამალვა" 1434 | } 1435 | }, 1436 | "sv" : { 1437 | "stringUnit" : { 1438 | "state" : "translated", 1439 | "value" : "Dölj" 1440 | } 1441 | } 1442 | } 1443 | }, 1444 | "Button.Import" : { 1445 | "localizations" : { 1446 | "de" : { 1447 | "stringUnit" : { 1448 | "state" : "translated", 1449 | "value" : "Importieren" 1450 | } 1451 | }, 1452 | "en" : { 1453 | "stringUnit" : { 1454 | "state" : "translated", 1455 | "value" : "Import" 1456 | } 1457 | }, 1458 | "es" : { 1459 | "stringUnit" : { 1460 | "state" : "translated", 1461 | "value" : "Importar" 1462 | } 1463 | }, 1464 | "fr" : { 1465 | "stringUnit" : { 1466 | "state" : "translated", 1467 | "value" : "Importer" 1468 | } 1469 | }, 1470 | "ka" : { 1471 | "stringUnit" : { 1472 | "state" : "translated", 1473 | "value" : "იმპორტი" 1474 | } 1475 | }, 1476 | "sv" : { 1477 | "stringUnit" : { 1478 | "state" : "translated", 1479 | "value" : "Importera" 1480 | } 1481 | } 1482 | } 1483 | }, 1484 | "Button.Info" : { 1485 | "localizations" : { 1486 | "de" : { 1487 | "stringUnit" : { 1488 | "state" : "translated", 1489 | "value" : "Info" 1490 | } 1491 | }, 1492 | "en" : { 1493 | "stringUnit" : { 1494 | "state" : "translated", 1495 | "value" : "Info" 1496 | } 1497 | }, 1498 | "es" : { 1499 | "stringUnit" : { 1500 | "state" : "translated", 1501 | "value" : "Información" 1502 | } 1503 | }, 1504 | "fr" : { 1505 | "stringUnit" : { 1506 | "state" : "translated", 1507 | "value" : "Infos" 1508 | } 1509 | }, 1510 | "ka" : { 1511 | "stringUnit" : { 1512 | "state" : "translated", 1513 | "value" : "ინფო" 1514 | } 1515 | }, 1516 | "sv" : { 1517 | "stringUnit" : { 1518 | "state" : "translated", 1519 | "value" : "Info" 1520 | } 1521 | } 1522 | } 1523 | }, 1524 | "Button.Install" : { 1525 | "localizations" : { 1526 | "de" : { 1527 | "stringUnit" : { 1528 | "state" : "translated", 1529 | "value" : "Installieren" 1530 | } 1531 | }, 1532 | "en" : { 1533 | "stringUnit" : { 1534 | "state" : "translated", 1535 | "value" : "Install" 1536 | } 1537 | }, 1538 | "es" : { 1539 | "stringUnit" : { 1540 | "state" : "translated", 1541 | "value" : "Instalar" 1542 | } 1543 | }, 1544 | "fr" : { 1545 | "stringUnit" : { 1546 | "state" : "translated", 1547 | "value" : "Installer" 1548 | } 1549 | }, 1550 | "ka" : { 1551 | "stringUnit" : { 1552 | "state" : "translated", 1553 | "value" : "დაყენება" 1554 | } 1555 | }, 1556 | "sv" : { 1557 | "stringUnit" : { 1558 | "state" : "translated", 1559 | "value" : "Installera" 1560 | } 1561 | } 1562 | } 1563 | }, 1564 | "Button.Like" : { 1565 | "localizations" : { 1566 | "de" : { 1567 | "stringUnit" : { 1568 | "state" : "translated", 1569 | "value" : "Like" 1570 | } 1571 | }, 1572 | "en" : { 1573 | "stringUnit" : { 1574 | "state" : "translated", 1575 | "value" : "Like" 1576 | } 1577 | }, 1578 | "es" : { 1579 | "stringUnit" : { 1580 | "state" : "translated", 1581 | "value" : "Me gusta" 1582 | } 1583 | }, 1584 | "fr" : { 1585 | "stringUnit" : { 1586 | "state" : "translated", 1587 | "value" : "J’aime" 1588 | } 1589 | }, 1590 | "ka" : { 1591 | "stringUnit" : { 1592 | "state" : "translated", 1593 | "value" : "მოწონება" 1594 | } 1595 | }, 1596 | "sv" : { 1597 | "stringUnit" : { 1598 | "state" : "translated", 1599 | "value" : "Gilla" 1600 | } 1601 | } 1602 | } 1603 | }, 1604 | "Button.Load" : { 1605 | "localizations" : { 1606 | "de" : { 1607 | "stringUnit" : { 1608 | "state" : "translated", 1609 | "value" : "Laden" 1610 | } 1611 | }, 1612 | "en" : { 1613 | "stringUnit" : { 1614 | "state" : "translated", 1615 | "value" : "Load" 1616 | } 1617 | }, 1618 | "es" : { 1619 | "stringUnit" : { 1620 | "state" : "translated", 1621 | "value" : "Cargar" 1622 | } 1623 | }, 1624 | "fr" : { 1625 | "stringUnit" : { 1626 | "state" : "translated", 1627 | "value" : "Charger" 1628 | } 1629 | }, 1630 | "ka" : { 1631 | "stringUnit" : { 1632 | "state" : "translated", 1633 | "value" : "ჩატვირთვა" 1634 | } 1635 | }, 1636 | "sv" : { 1637 | "stringUnit" : { 1638 | "state" : "translated", 1639 | "value" : "Ladda" 1640 | } 1641 | } 1642 | } 1643 | }, 1644 | "Button.Lock" : { 1645 | "localizations" : { 1646 | "de" : { 1647 | "stringUnit" : { 1648 | "state" : "translated", 1649 | "value" : "Sperren" 1650 | } 1651 | }, 1652 | "en" : { 1653 | "stringUnit" : { 1654 | "state" : "translated", 1655 | "value" : "Lock" 1656 | } 1657 | }, 1658 | "es" : { 1659 | "stringUnit" : { 1660 | "state" : "translated", 1661 | "value" : "Bloquear" 1662 | } 1663 | }, 1664 | "fr" : { 1665 | "stringUnit" : { 1666 | "state" : "translated", 1667 | "value" : "Verrouiller" 1668 | } 1669 | }, 1670 | "ka" : { 1671 | "stringUnit" : { 1672 | "state" : "translated", 1673 | "value" : "ჩაკეტვა" 1674 | } 1675 | }, 1676 | "sv" : { 1677 | "stringUnit" : { 1678 | "state" : "translated", 1679 | "value" : "Lås" 1680 | } 1681 | } 1682 | } 1683 | }, 1684 | "Button.Login" : { 1685 | "localizations" : { 1686 | "de" : { 1687 | "stringUnit" : { 1688 | "state" : "translated", 1689 | "value" : "Anmelden" 1690 | } 1691 | }, 1692 | "en" : { 1693 | "stringUnit" : { 1694 | "state" : "translated", 1695 | "value" : "Login" 1696 | } 1697 | }, 1698 | "es" : { 1699 | "stringUnit" : { 1700 | "state" : "translated", 1701 | "value" : "Iniciar sesión" 1702 | } 1703 | }, 1704 | "fr" : { 1705 | "stringUnit" : { 1706 | "state" : "translated", 1707 | "value" : "Se connecter" 1708 | } 1709 | }, 1710 | "ka" : { 1711 | "stringUnit" : { 1712 | "state" : "translated", 1713 | "value" : "ავტორიზაცია" 1714 | } 1715 | }, 1716 | "sv" : { 1717 | "stringUnit" : { 1718 | "state" : "translated", 1719 | "value" : "Logga in" 1720 | } 1721 | } 1722 | } 1723 | }, 1724 | "Button.Logout" : { 1725 | "localizations" : { 1726 | "de" : { 1727 | "stringUnit" : { 1728 | "state" : "translated", 1729 | "value" : "Abmelden" 1730 | } 1731 | }, 1732 | "en" : { 1733 | "stringUnit" : { 1734 | "state" : "translated", 1735 | "value" : "Logout" 1736 | } 1737 | }, 1738 | "es" : { 1739 | "stringUnit" : { 1740 | "state" : "translated", 1741 | "value" : "Cerrar sesión" 1742 | } 1743 | }, 1744 | "fr" : { 1745 | "stringUnit" : { 1746 | "state" : "translated", 1747 | "value" : "Se déconnecter" 1748 | } 1749 | }, 1750 | "ka" : { 1751 | "stringUnit" : { 1752 | "state" : "translated", 1753 | "value" : "გამოსვლა" 1754 | } 1755 | }, 1756 | "sv" : { 1757 | "stringUnit" : { 1758 | "state" : "translated", 1759 | "value" : "Logga ut" 1760 | } 1761 | } 1762 | } 1763 | }, 1764 | "Button.Menu" : { 1765 | "localizations" : { 1766 | "de" : { 1767 | "stringUnit" : { 1768 | "state" : "translated", 1769 | "value" : "Menü" 1770 | } 1771 | }, 1772 | "en" : { 1773 | "stringUnit" : { 1774 | "state" : "translated", 1775 | "value" : "Menu" 1776 | } 1777 | }, 1778 | "es" : { 1779 | "stringUnit" : { 1780 | "state" : "translated", 1781 | "value" : "Menú" 1782 | } 1783 | }, 1784 | "fr" : { 1785 | "stringUnit" : { 1786 | "state" : "translated", 1787 | "value" : "Menu" 1788 | } 1789 | }, 1790 | "ka" : { 1791 | "stringUnit" : { 1792 | "state" : "translated", 1793 | "value" : "მენიუ" 1794 | } 1795 | }, 1796 | "sv" : { 1797 | "stringUnit" : { 1798 | "state" : "translated", 1799 | "value" : "Meny" 1800 | } 1801 | } 1802 | } 1803 | }, 1804 | "Button.Minimize" : { 1805 | "localizations" : { 1806 | "de" : { 1807 | "stringUnit" : { 1808 | "state" : "translated", 1809 | "value" : "Minimieren" 1810 | } 1811 | }, 1812 | "en" : { 1813 | "stringUnit" : { 1814 | "state" : "translated", 1815 | "value" : "Minimize" 1816 | } 1817 | }, 1818 | "es" : { 1819 | "stringUnit" : { 1820 | "state" : "translated", 1821 | "value" : "Minimizar" 1822 | } 1823 | }, 1824 | "fr" : { 1825 | "stringUnit" : { 1826 | "state" : "translated", 1827 | "value" : "Minimiser" 1828 | } 1829 | }, 1830 | "ka" : { 1831 | "stringUnit" : { 1832 | "state" : "translated", 1833 | "value" : "ჩაკეცვა" 1834 | } 1835 | }, 1836 | "sv" : { 1837 | "stringUnit" : { 1838 | "state" : "translated", 1839 | "value" : "Minimera" 1840 | } 1841 | } 1842 | } 1843 | }, 1844 | "Button.Mute" : { 1845 | "localizations" : { 1846 | "de" : { 1847 | "stringUnit" : { 1848 | "state" : "translated", 1849 | "value" : "Stummschalten" 1850 | } 1851 | }, 1852 | "en" : { 1853 | "stringUnit" : { 1854 | "state" : "translated", 1855 | "value" : "Mute" 1856 | } 1857 | }, 1858 | "es" : { 1859 | "stringUnit" : { 1860 | "state" : "translated", 1861 | "value" : "Silenciar" 1862 | } 1863 | }, 1864 | "fr" : { 1865 | "stringUnit" : { 1866 | "state" : "translated", 1867 | "value" : "Muet" 1868 | } 1869 | }, 1870 | "ka" : { 1871 | "stringUnit" : { 1872 | "state" : "translated", 1873 | "value" : "გაჩუმება" 1874 | } 1875 | }, 1876 | "sv" : { 1877 | "stringUnit" : { 1878 | "state" : "translated", 1879 | "value" : "Stäng av ljud" 1880 | } 1881 | } 1882 | } 1883 | }, 1884 | "Button.New" : { 1885 | "localizations" : { 1886 | "de" : { 1887 | "stringUnit" : { 1888 | "state" : "translated", 1889 | "value" : "Neu" 1890 | } 1891 | }, 1892 | "en" : { 1893 | "stringUnit" : { 1894 | "state" : "translated", 1895 | "value" : "New" 1896 | } 1897 | }, 1898 | "es" : { 1899 | "stringUnit" : { 1900 | "state" : "translated", 1901 | "value" : "Nuevo" 1902 | } 1903 | }, 1904 | "fr" : { 1905 | "stringUnit" : { 1906 | "state" : "translated", 1907 | "value" : "Nouveau" 1908 | } 1909 | }, 1910 | "ka" : { 1911 | "stringUnit" : { 1912 | "state" : "translated", 1913 | "value" : "ახალი" 1914 | } 1915 | }, 1916 | "sv" : { 1917 | "stringUnit" : { 1918 | "state" : "translated", 1919 | "value" : "Ny" 1920 | } 1921 | } 1922 | } 1923 | }, 1924 | "Button.Next" : { 1925 | "localizations" : { 1926 | "de" : { 1927 | "stringUnit" : { 1928 | "state" : "translated", 1929 | "value" : "Weiter" 1930 | } 1931 | }, 1932 | "en" : { 1933 | "stringUnit" : { 1934 | "state" : "translated", 1935 | "value" : "Next" 1936 | } 1937 | }, 1938 | "es" : { 1939 | "stringUnit" : { 1940 | "state" : "translated", 1941 | "value" : "Siguiente" 1942 | } 1943 | }, 1944 | "fr" : { 1945 | "stringUnit" : { 1946 | "state" : "translated", 1947 | "value" : "Suivant" 1948 | } 1949 | }, 1950 | "ka" : { 1951 | "stringUnit" : { 1952 | "state" : "translated", 1953 | "value" : "შემდეგი" 1954 | } 1955 | }, 1956 | "sv" : { 1957 | "stringUnit" : { 1958 | "state" : "translated", 1959 | "value" : "Nästa" 1960 | } 1961 | } 1962 | } 1963 | }, 1964 | "Button.No" : { 1965 | "extractionState" : "stale", 1966 | "localizations" : { 1967 | "de" : { 1968 | "stringUnit" : { 1969 | "state" : "translated", 1970 | "value" : "Nein" 1971 | } 1972 | }, 1973 | "en" : { 1974 | "stringUnit" : { 1975 | "state" : "translated", 1976 | "value" : "No" 1977 | } 1978 | }, 1979 | "es" : { 1980 | "stringUnit" : { 1981 | "state" : "translated", 1982 | "value" : "No" 1983 | } 1984 | }, 1985 | "fr" : { 1986 | "stringUnit" : { 1987 | "state" : "translated", 1988 | "value" : "Non" 1989 | } 1990 | }, 1991 | "ka" : { 1992 | "stringUnit" : { 1993 | "state" : "translated", 1994 | "value" : "არა" 1995 | } 1996 | }, 1997 | "sv" : { 1998 | "stringUnit" : { 1999 | "state" : "translated", 2000 | "value" : "Nej" 2001 | } 2002 | } 2003 | } 2004 | }, 2005 | "Button.OK" : { 2006 | "localizations" : { 2007 | "de" : { 2008 | "stringUnit" : { 2009 | "state" : "translated", 2010 | "value" : "OK" 2011 | } 2012 | }, 2013 | "en" : { 2014 | "stringUnit" : { 2015 | "state" : "translated", 2016 | "value" : "OK" 2017 | } 2018 | }, 2019 | "es" : { 2020 | "stringUnit" : { 2021 | "state" : "translated", 2022 | "value" : "OK" 2023 | } 2024 | }, 2025 | "fr" : { 2026 | "stringUnit" : { 2027 | "state" : "translated", 2028 | "value" : "OK" 2029 | } 2030 | }, 2031 | "ka" : { 2032 | "stringUnit" : { 2033 | "state" : "translated", 2034 | "value" : "OK" 2035 | } 2036 | }, 2037 | "sv" : { 2038 | "stringUnit" : { 2039 | "state" : "translated", 2040 | "value" : "OK" 2041 | } 2042 | } 2043 | } 2044 | }, 2045 | "Button.Open" : { 2046 | "localizations" : { 2047 | "de" : { 2048 | "stringUnit" : { 2049 | "state" : "translated", 2050 | "value" : "Öffnen" 2051 | } 2052 | }, 2053 | "en" : { 2054 | "stringUnit" : { 2055 | "state" : "translated", 2056 | "value" : "Open" 2057 | } 2058 | }, 2059 | "es" : { 2060 | "stringUnit" : { 2061 | "state" : "translated", 2062 | "value" : "Abrir" 2063 | } 2064 | }, 2065 | "fr" : { 2066 | "stringUnit" : { 2067 | "state" : "translated", 2068 | "value" : "Ouvrir" 2069 | } 2070 | }, 2071 | "ka" : { 2072 | "stringUnit" : { 2073 | "state" : "translated", 2074 | "value" : "გახსნა" 2075 | } 2076 | }, 2077 | "sv" : { 2078 | "stringUnit" : { 2079 | "state" : "translated", 2080 | "value" : "Öppna" 2081 | } 2082 | } 2083 | } 2084 | }, 2085 | "Button.Paste" : { 2086 | "localizations" : { 2087 | "de" : { 2088 | "stringUnit" : { 2089 | "state" : "translated", 2090 | "value" : "Einfügen" 2091 | } 2092 | }, 2093 | "en" : { 2094 | "stringUnit" : { 2095 | "state" : "translated", 2096 | "value" : "Paste" 2097 | } 2098 | }, 2099 | "es" : { 2100 | "stringUnit" : { 2101 | "state" : "translated", 2102 | "value" : "Pegar" 2103 | } 2104 | }, 2105 | "fr" : { 2106 | "stringUnit" : { 2107 | "state" : "translated", 2108 | "value" : "Coller" 2109 | } 2110 | }, 2111 | "ka" : { 2112 | "stringUnit" : { 2113 | "state" : "translated", 2114 | "value" : "ჩასმა" 2115 | } 2116 | }, 2117 | "sv" : { 2118 | "stringUnit" : { 2119 | "state" : "translated", 2120 | "value" : "Klistra in" 2121 | } 2122 | } 2123 | } 2124 | }, 2125 | "Button.Pause" : { 2126 | "localizations" : { 2127 | "de" : { 2128 | "stringUnit" : { 2129 | "state" : "translated", 2130 | "value" : "Pause" 2131 | } 2132 | }, 2133 | "en" : { 2134 | "stringUnit" : { 2135 | "state" : "translated", 2136 | "value" : "Pause" 2137 | } 2138 | }, 2139 | "es" : { 2140 | "stringUnit" : { 2141 | "state" : "translated", 2142 | "value" : "Pausar" 2143 | } 2144 | }, 2145 | "fr" : { 2146 | "stringUnit" : { 2147 | "state" : "translated", 2148 | "value" : "Pause" 2149 | } 2150 | }, 2151 | "ka" : { 2152 | "stringUnit" : { 2153 | "state" : "translated", 2154 | "value" : "შეჩერება" 2155 | } 2156 | }, 2157 | "sv" : { 2158 | "stringUnit" : { 2159 | "state" : "translated", 2160 | "value" : "Pausa" 2161 | } 2162 | } 2163 | } 2164 | }, 2165 | "Button.Pin" : { 2166 | "localizations" : { 2167 | "de" : { 2168 | "stringUnit" : { 2169 | "state" : "translated", 2170 | "value" : "Anheften" 2171 | } 2172 | }, 2173 | "en" : { 2174 | "stringUnit" : { 2175 | "state" : "translated", 2176 | "value" : "Pin" 2177 | } 2178 | }, 2179 | "es" : { 2180 | "stringUnit" : { 2181 | "state" : "translated", 2182 | "value" : "Fijar" 2183 | } 2184 | }, 2185 | "fr" : { 2186 | "stringUnit" : { 2187 | "state" : "translated", 2188 | "value" : "Marquer" 2189 | } 2190 | }, 2191 | "ka" : { 2192 | "stringUnit" : { 2193 | "state" : "translated", 2194 | "value" : "პინი" 2195 | } 2196 | }, 2197 | "sv" : { 2198 | "stringUnit" : { 2199 | "state" : "translated", 2200 | "value" : "Fäst" 2201 | } 2202 | } 2203 | } 2204 | }, 2205 | "Button.Play" : { 2206 | "localizations" : { 2207 | "de" : { 2208 | "stringUnit" : { 2209 | "state" : "translated", 2210 | "value" : "Abspielen" 2211 | } 2212 | }, 2213 | "en" : { 2214 | "stringUnit" : { 2215 | "state" : "translated", 2216 | "value" : "Play" 2217 | } 2218 | }, 2219 | "es" : { 2220 | "stringUnit" : { 2221 | "state" : "translated", 2222 | "value" : "Reproducir" 2223 | } 2224 | }, 2225 | "fr" : { 2226 | "stringUnit" : { 2227 | "state" : "translated", 2228 | "value" : "Lecture" 2229 | } 2230 | }, 2231 | "ka" : { 2232 | "stringUnit" : { 2233 | "state" : "translated", 2234 | "value" : "თამაში" 2235 | } 2236 | }, 2237 | "sv" : { 2238 | "stringUnit" : { 2239 | "state" : "translated", 2240 | "value" : "Spela" 2241 | } 2242 | } 2243 | } 2244 | }, 2245 | "Button.Post" : { 2246 | "localizations" : { 2247 | "de" : { 2248 | "stringUnit" : { 2249 | "state" : "translated", 2250 | "value" : "Veröffentlichen" 2251 | } 2252 | }, 2253 | "en" : { 2254 | "stringUnit" : { 2255 | "state" : "translated", 2256 | "value" : "Post" 2257 | } 2258 | }, 2259 | "es" : { 2260 | "stringUnit" : { 2261 | "state" : "translated", 2262 | "value" : "Publicar" 2263 | } 2264 | }, 2265 | "fr" : { 2266 | "stringUnit" : { 2267 | "state" : "translated", 2268 | "value" : "Publier" 2269 | } 2270 | }, 2271 | "ka" : { 2272 | "stringUnit" : { 2273 | "state" : "translated", 2274 | "value" : "დაპოსტვა" 2275 | } 2276 | }, 2277 | "sv" : { 2278 | "stringUnit" : { 2279 | "state" : "translated", 2280 | "value" : "Publicera" 2281 | } 2282 | } 2283 | } 2284 | }, 2285 | "Button.Preview" : { 2286 | "localizations" : { 2287 | "de" : { 2288 | "stringUnit" : { 2289 | "state" : "translated", 2290 | "value" : "Vorschau" 2291 | } 2292 | }, 2293 | "en" : { 2294 | "stringUnit" : { 2295 | "state" : "translated", 2296 | "value" : "Preview" 2297 | } 2298 | }, 2299 | "es" : { 2300 | "stringUnit" : { 2301 | "state" : "translated", 2302 | "value" : "Vista previa" 2303 | } 2304 | }, 2305 | "fr" : { 2306 | "stringUnit" : { 2307 | "state" : "translated", 2308 | "value" : "Aperçu" 2309 | } 2310 | }, 2311 | "ka" : { 2312 | "stringUnit" : { 2313 | "state" : "translated", 2314 | "value" : "გადახედვა" 2315 | } 2316 | }, 2317 | "sv" : { 2318 | "stringUnit" : { 2319 | "state" : "translated", 2320 | "value" : "Förhandsgranska" 2321 | } 2322 | } 2323 | } 2324 | }, 2325 | "Button.Previous" : { 2326 | "localizations" : { 2327 | "de" : { 2328 | "stringUnit" : { 2329 | "state" : "translated", 2330 | "value" : "Zurück" 2331 | } 2332 | }, 2333 | "en" : { 2334 | "stringUnit" : { 2335 | "state" : "translated", 2336 | "value" : "Previous" 2337 | } 2338 | }, 2339 | "es" : { 2340 | "stringUnit" : { 2341 | "state" : "translated", 2342 | "value" : "Anterior" 2343 | } 2344 | }, 2345 | "fr" : { 2346 | "stringUnit" : { 2347 | "state" : "translated", 2348 | "value" : "Précédent" 2349 | } 2350 | }, 2351 | "ka" : { 2352 | "stringUnit" : { 2353 | "state" : "translated", 2354 | "value" : "წინა" 2355 | } 2356 | }, 2357 | "sv" : { 2358 | "stringUnit" : { 2359 | "state" : "translated", 2360 | "value" : "Föregående" 2361 | } 2362 | } 2363 | } 2364 | }, 2365 | "Button.Print" : { 2366 | "localizations" : { 2367 | "de" : { 2368 | "stringUnit" : { 2369 | "state" : "translated", 2370 | "value" : "Drucken" 2371 | } 2372 | }, 2373 | "en" : { 2374 | "stringUnit" : { 2375 | "state" : "translated", 2376 | "value" : "Print" 2377 | } 2378 | }, 2379 | "es" : { 2380 | "stringUnit" : { 2381 | "state" : "translated", 2382 | "value" : "Imprimir" 2383 | } 2384 | }, 2385 | "fr" : { 2386 | "stringUnit" : { 2387 | "state" : "translated", 2388 | "value" : "Imprimer" 2389 | } 2390 | }, 2391 | "ka" : { 2392 | "stringUnit" : { 2393 | "state" : "translated", 2394 | "value" : "დაპრინტვა" 2395 | } 2396 | }, 2397 | "sv" : { 2398 | "stringUnit" : { 2399 | "state" : "translated", 2400 | "value" : "Skriv ut" 2401 | } 2402 | } 2403 | } 2404 | }, 2405 | "Button.Proceed" : { 2406 | "localizations" : { 2407 | "de" : { 2408 | "stringUnit" : { 2409 | "state" : "translated", 2410 | "value" : "Fortfahren" 2411 | } 2412 | }, 2413 | "en" : { 2414 | "stringUnit" : { 2415 | "state" : "translated", 2416 | "value" : "Proceed" 2417 | } 2418 | }, 2419 | "es" : { 2420 | "stringUnit" : { 2421 | "state" : "translated", 2422 | "value" : "Continuar" 2423 | } 2424 | }, 2425 | "fr" : { 2426 | "stringUnit" : { 2427 | "state" : "translated", 2428 | "value" : "Poursuivre" 2429 | } 2430 | }, 2431 | "ka" : { 2432 | "stringUnit" : { 2433 | "state" : "translated", 2434 | "value" : "პროცესშია" 2435 | } 2436 | }, 2437 | "sv" : { 2438 | "stringUnit" : { 2439 | "state" : "translated", 2440 | "value" : "Fortsätt" 2441 | } 2442 | } 2443 | } 2444 | }, 2445 | "Button.Purchase" : { 2446 | "localizations" : { 2447 | "de" : { 2448 | "stringUnit" : { 2449 | "state" : "translated", 2450 | "value" : "Kaufen" 2451 | } 2452 | }, 2453 | "en" : { 2454 | "stringUnit" : { 2455 | "state" : "translated", 2456 | "value" : "Purchase" 2457 | } 2458 | }, 2459 | "es" : { 2460 | "stringUnit" : { 2461 | "state" : "translated", 2462 | "value" : "Comprar" 2463 | } 2464 | }, 2465 | "fr" : { 2466 | "stringUnit" : { 2467 | "state" : "translated", 2468 | "value" : "Acheter" 2469 | } 2470 | }, 2471 | "ka" : { 2472 | "stringUnit" : { 2473 | "state" : "translated", 2474 | "value" : "შესყიდვა" 2475 | } 2476 | }, 2477 | "sv" : { 2478 | "stringUnit" : { 2479 | "state" : "translated", 2480 | "value" : "Köp" 2481 | } 2482 | } 2483 | } 2484 | }, 2485 | "Button.Rate" : { 2486 | "localizations" : { 2487 | "de" : { 2488 | "stringUnit" : { 2489 | "state" : "translated", 2490 | "value" : "Bewerten" 2491 | } 2492 | }, 2493 | "en" : { 2494 | "stringUnit" : { 2495 | "state" : "translated", 2496 | "value" : "Rate" 2497 | } 2498 | }, 2499 | "es" : { 2500 | "stringUnit" : { 2501 | "state" : "translated", 2502 | "value" : "Valorar" 2503 | } 2504 | }, 2505 | "fr" : { 2506 | "stringUnit" : { 2507 | "state" : "translated", 2508 | "value" : "Noter" 2509 | } 2510 | }, 2511 | "ka" : { 2512 | "stringUnit" : { 2513 | "state" : "translated", 2514 | "value" : "შეფასება" 2515 | } 2516 | }, 2517 | "sv" : { 2518 | "stringUnit" : { 2519 | "state" : "translated", 2520 | "value" : "Betygsätt" 2521 | } 2522 | } 2523 | } 2524 | }, 2525 | "Button.Record" : { 2526 | "localizations" : { 2527 | "de" : { 2528 | "stringUnit" : { 2529 | "state" : "translated", 2530 | "value" : "Aufnehmen" 2531 | } 2532 | }, 2533 | "en" : { 2534 | "stringUnit" : { 2535 | "state" : "translated", 2536 | "value" : "Record" 2537 | } 2538 | }, 2539 | "es" : { 2540 | "stringUnit" : { 2541 | "state" : "translated", 2542 | "value" : "Grabar" 2543 | } 2544 | }, 2545 | "fr" : { 2546 | "stringUnit" : { 2547 | "state" : "translated", 2548 | "value" : "Enregistrer" 2549 | } 2550 | }, 2551 | "ka" : { 2552 | "stringUnit" : { 2553 | "state" : "translated", 2554 | "value" : "ჩაწერა" 2555 | } 2556 | }, 2557 | "sv" : { 2558 | "stringUnit" : { 2559 | "state" : "translated", 2560 | "value" : "Spela in" 2561 | } 2562 | } 2563 | } 2564 | }, 2565 | "Button.Redo" : { 2566 | "localizations" : { 2567 | "de" : { 2568 | "stringUnit" : { 2569 | "state" : "translated", 2570 | "value" : "Wiederherstellen" 2571 | } 2572 | }, 2573 | "en" : { 2574 | "stringUnit" : { 2575 | "state" : "translated", 2576 | "value" : "Redo" 2577 | } 2578 | }, 2579 | "es" : { 2580 | "stringUnit" : { 2581 | "state" : "translated", 2582 | "value" : "Rehacer" 2583 | } 2584 | }, 2585 | "fr" : { 2586 | "stringUnit" : { 2587 | "state" : "translated", 2588 | "value" : "Refaire" 2589 | } 2590 | }, 2591 | "ka" : { 2592 | "stringUnit" : { 2593 | "state" : "translated", 2594 | "value" : "წინსვლა" 2595 | } 2596 | }, 2597 | "sv" : { 2598 | "stringUnit" : { 2599 | "state" : "translated", 2600 | "value" : "Gör om" 2601 | } 2602 | } 2603 | } 2604 | }, 2605 | "Button.Refresh" : { 2606 | "localizations" : { 2607 | "de" : { 2608 | "stringUnit" : { 2609 | "state" : "translated", 2610 | "value" : "Aktualisieren" 2611 | } 2612 | }, 2613 | "en" : { 2614 | "stringUnit" : { 2615 | "state" : "translated", 2616 | "value" : "Refresh" 2617 | } 2618 | }, 2619 | "es" : { 2620 | "stringUnit" : { 2621 | "state" : "translated", 2622 | "value" : "Actualizar" 2623 | } 2624 | }, 2625 | "fr" : { 2626 | "stringUnit" : { 2627 | "state" : "translated", 2628 | "value" : "Rafraîchir" 2629 | } 2630 | }, 2631 | "ka" : { 2632 | "stringUnit" : { 2633 | "state" : "translated", 2634 | "value" : "განახლება" 2635 | } 2636 | }, 2637 | "sv" : { 2638 | "stringUnit" : { 2639 | "state" : "translated", 2640 | "value" : "Uppdatera" 2641 | } 2642 | } 2643 | } 2644 | }, 2645 | "Button.Reject" : { 2646 | "localizations" : { 2647 | "de" : { 2648 | "stringUnit" : { 2649 | "state" : "translated", 2650 | "value" : "Ablehnen" 2651 | } 2652 | }, 2653 | "en" : { 2654 | "stringUnit" : { 2655 | "state" : "translated", 2656 | "value" : "Reject" 2657 | } 2658 | }, 2659 | "es" : { 2660 | "stringUnit" : { 2661 | "state" : "translated", 2662 | "value" : "Rechazar" 2663 | } 2664 | }, 2665 | "fr" : { 2666 | "stringUnit" : { 2667 | "state" : "translated", 2668 | "value" : "Rejeter" 2669 | } 2670 | }, 2671 | "ka" : { 2672 | "stringUnit" : { 2673 | "state" : "translated", 2674 | "value" : "უარყოფა" 2675 | } 2676 | }, 2677 | "sv" : { 2678 | "stringUnit" : { 2679 | "state" : "translated", 2680 | "value" : "Avvisa" 2681 | } 2682 | } 2683 | } 2684 | }, 2685 | "Button.Reload" : { 2686 | "localizations" : { 2687 | "de" : { 2688 | "stringUnit" : { 2689 | "state" : "translated", 2690 | "value" : "Neu laden" 2691 | } 2692 | }, 2693 | "en" : { 2694 | "stringUnit" : { 2695 | "state" : "translated", 2696 | "value" : "Reload" 2697 | } 2698 | }, 2699 | "es" : { 2700 | "stringUnit" : { 2701 | "state" : "translated", 2702 | "value" : "Recargar" 2703 | } 2704 | }, 2705 | "fr" : { 2706 | "stringUnit" : { 2707 | "state" : "translated", 2708 | "value" : "Recharger" 2709 | } 2710 | }, 2711 | "ka" : { 2712 | "stringUnit" : { 2713 | "state" : "translated", 2714 | "value" : "ჩატვირთვა" 2715 | } 2716 | }, 2717 | "sv" : { 2718 | "stringUnit" : { 2719 | "state" : "translated", 2720 | "value" : "Ladda om" 2721 | } 2722 | } 2723 | } 2724 | }, 2725 | "Button.Remove" : { 2726 | "localizations" : { 2727 | "de" : { 2728 | "stringUnit" : { 2729 | "state" : "translated", 2730 | "value" : "Entfernen" 2731 | } 2732 | }, 2733 | "en" : { 2734 | "stringUnit" : { 2735 | "state" : "translated", 2736 | "value" : "Remove" 2737 | } 2738 | }, 2739 | "es" : { 2740 | "stringUnit" : { 2741 | "state" : "translated", 2742 | "value" : "Quitar" 2743 | } 2744 | }, 2745 | "fr" : { 2746 | "stringUnit" : { 2747 | "state" : "translated", 2748 | "value" : "Retirer" 2749 | } 2750 | }, 2751 | "ka" : { 2752 | "stringUnit" : { 2753 | "state" : "translated", 2754 | "value" : "წაშლა" 2755 | } 2756 | }, 2757 | "sv" : { 2758 | "stringUnit" : { 2759 | "state" : "translated", 2760 | "value" : "Ta bort" 2761 | } 2762 | } 2763 | } 2764 | }, 2765 | "Button.RemoveFavorite" : { 2766 | "localizations" : { 2767 | "de" : { 2768 | "stringUnit" : { 2769 | "state" : "translated", 2770 | "value" : "Favorit entfernen" 2771 | } 2772 | }, 2773 | "en" : { 2774 | "stringUnit" : { 2775 | "state" : "translated", 2776 | "value" : "Remove Favorite" 2777 | } 2778 | }, 2779 | "es" : { 2780 | "stringUnit" : { 2781 | "state" : "translated", 2782 | "value" : "Quitar favorito" 2783 | } 2784 | }, 2785 | "fr" : { 2786 | "stringUnit" : { 2787 | "state" : "translated", 2788 | "value" : "Retirer des favoris" 2789 | } 2790 | }, 2791 | "ka" : { 2792 | "stringUnit" : { 2793 | "state" : "translated", 2794 | "value" : "რჩეულებიდან წაშლა" 2795 | } 2796 | }, 2797 | "sv" : { 2798 | "stringUnit" : { 2799 | "state" : "translated", 2800 | "value" : "Ta bort favorit" 2801 | } 2802 | } 2803 | } 2804 | }, 2805 | "Button.RemoveLike" : { 2806 | "localizations" : { 2807 | "de" : { 2808 | "stringUnit" : { 2809 | "state" : "translated", 2810 | "value" : "Like entfernen" 2811 | } 2812 | }, 2813 | "en" : { 2814 | "stringUnit" : { 2815 | "state" : "translated", 2816 | "value" : "Remove Like" 2817 | } 2818 | }, 2819 | "es" : { 2820 | "stringUnit" : { 2821 | "state" : "translated", 2822 | "value" : "Quitar me gusta" 2823 | } 2824 | }, 2825 | "fr" : { 2826 | "stringUnit" : { 2827 | "state" : "translated", 2828 | "value" : "Je n’aime plus" 2829 | } 2830 | }, 2831 | "ka" : { 2832 | "stringUnit" : { 2833 | "state" : "translated", 2834 | "value" : "მოწონების გაუქმება" 2835 | } 2836 | }, 2837 | "sv" : { 2838 | "stringUnit" : { 2839 | "state" : "translated", 2840 | "value" : "Ta bort gilla" 2841 | } 2842 | } 2843 | } 2844 | }, 2845 | "Button.Rename" : { 2846 | "localizations" : { 2847 | "de" : { 2848 | "stringUnit" : { 2849 | "state" : "translated", 2850 | "value" : "Umbenennen" 2851 | } 2852 | }, 2853 | "en" : { 2854 | "stringUnit" : { 2855 | "state" : "translated", 2856 | "value" : "Rename" 2857 | } 2858 | }, 2859 | "es" : { 2860 | "stringUnit" : { 2861 | "state" : "translated", 2862 | "value" : "Renombrar" 2863 | } 2864 | }, 2865 | "fr" : { 2866 | "stringUnit" : { 2867 | "state" : "translated", 2868 | "value" : "Renommer" 2869 | } 2870 | }, 2871 | "ka" : { 2872 | "stringUnit" : { 2873 | "state" : "translated", 2874 | "value" : "გადარქმევა" 2875 | } 2876 | }, 2877 | "sv" : { 2878 | "stringUnit" : { 2879 | "state" : "translated", 2880 | "value" : "Byt namn" 2881 | } 2882 | } 2883 | } 2884 | }, 2885 | "Button.Reply" : { 2886 | "localizations" : { 2887 | "de" : { 2888 | "stringUnit" : { 2889 | "state" : "translated", 2890 | "value" : "Antworten" 2891 | } 2892 | }, 2893 | "en" : { 2894 | "stringUnit" : { 2895 | "state" : "translated", 2896 | "value" : "Reply" 2897 | } 2898 | }, 2899 | "es" : { 2900 | "stringUnit" : { 2901 | "state" : "translated", 2902 | "value" : "Responder" 2903 | } 2904 | }, 2905 | "fr" : { 2906 | "stringUnit" : { 2907 | "state" : "translated", 2908 | "value" : "Répondre" 2909 | } 2910 | }, 2911 | "ka" : { 2912 | "stringUnit" : { 2913 | "state" : "translated", 2914 | "value" : "პასუხი" 2915 | } 2916 | }, 2917 | "sv" : { 2918 | "stringUnit" : { 2919 | "state" : "translated", 2920 | "value" : "Svara" 2921 | } 2922 | } 2923 | } 2924 | }, 2925 | "Button.Report" : { 2926 | "localizations" : { 2927 | "de" : { 2928 | "stringUnit" : { 2929 | "state" : "translated", 2930 | "value" : "Melden" 2931 | } 2932 | }, 2933 | "en" : { 2934 | "stringUnit" : { 2935 | "state" : "translated", 2936 | "value" : "Report" 2937 | } 2938 | }, 2939 | "es" : { 2940 | "stringUnit" : { 2941 | "state" : "translated", 2942 | "value" : "Reportar" 2943 | } 2944 | }, 2945 | "fr" : { 2946 | "stringUnit" : { 2947 | "state" : "translated", 2948 | "value" : "Signaler" 2949 | } 2950 | }, 2951 | "ka" : { 2952 | "stringUnit" : { 2953 | "state" : "translated", 2954 | "value" : "რეპორტი" 2955 | } 2956 | }, 2957 | "sv" : { 2958 | "stringUnit" : { 2959 | "state" : "translated", 2960 | "value" : "Rapportera" 2961 | } 2962 | } 2963 | } 2964 | }, 2965 | "Button.Reset" : { 2966 | "localizations" : { 2967 | "de" : { 2968 | "stringUnit" : { 2969 | "state" : "translated", 2970 | "value" : "Zurücksetzen" 2971 | } 2972 | }, 2973 | "en" : { 2974 | "stringUnit" : { 2975 | "state" : "translated", 2976 | "value" : "Reset" 2977 | } 2978 | }, 2979 | "es" : { 2980 | "stringUnit" : { 2981 | "state" : "translated", 2982 | "value" : "Restablecer" 2983 | } 2984 | }, 2985 | "fr" : { 2986 | "stringUnit" : { 2987 | "state" : "translated", 2988 | "value" : "Réinitialiser" 2989 | } 2990 | }, 2991 | "ka" : { 2992 | "stringUnit" : { 2993 | "state" : "translated", 2994 | "value" : "გადატვირთვა" 2995 | } 2996 | }, 2997 | "sv" : { 2998 | "stringUnit" : { 2999 | "state" : "translated", 3000 | "value" : "Återställ" 3001 | } 3002 | } 3003 | } 3004 | }, 3005 | "Button.Resize" : { 3006 | "localizations" : { 3007 | "de" : { 3008 | "stringUnit" : { 3009 | "state" : "translated", 3010 | "value" : "Größe ändern" 3011 | } 3012 | }, 3013 | "en" : { 3014 | "stringUnit" : { 3015 | "state" : "translated", 3016 | "value" : "Resize" 3017 | } 3018 | }, 3019 | "es" : { 3020 | "stringUnit" : { 3021 | "state" : "translated", 3022 | "value" : "Redimensionar" 3023 | } 3024 | }, 3025 | "fr" : { 3026 | "stringUnit" : { 3027 | "state" : "translated", 3028 | "value" : "Redimensionner" 3029 | } 3030 | }, 3031 | "ka" : { 3032 | "stringUnit" : { 3033 | "state" : "translated", 3034 | "value" : "ზომის შეცვლა" 3035 | } 3036 | }, 3037 | "sv" : { 3038 | "stringUnit" : { 3039 | "state" : "translated", 3040 | "value" : "Ändra storlek" 3041 | } 3042 | } 3043 | } 3044 | }, 3045 | "Button.Restart" : { 3046 | "localizations" : { 3047 | "de" : { 3048 | "stringUnit" : { 3049 | "state" : "translated", 3050 | "value" : "Neu starten" 3051 | } 3052 | }, 3053 | "en" : { 3054 | "stringUnit" : { 3055 | "state" : "translated", 3056 | "value" : "Restart" 3057 | } 3058 | }, 3059 | "es" : { 3060 | "stringUnit" : { 3061 | "state" : "translated", 3062 | "value" : "Reiniciar" 3063 | } 3064 | }, 3065 | "fr" : { 3066 | "stringUnit" : { 3067 | "state" : "translated", 3068 | "value" : "Recommencer" 3069 | } 3070 | }, 3071 | "ka" : { 3072 | "stringUnit" : { 3073 | "state" : "translated", 3074 | "value" : "გადატვირთვა" 3075 | } 3076 | }, 3077 | "sv" : { 3078 | "stringUnit" : { 3079 | "state" : "translated", 3080 | "value" : "Starta om" 3081 | } 3082 | } 3083 | } 3084 | }, 3085 | "Button.Restore" : { 3086 | "localizations" : { 3087 | "de" : { 3088 | "stringUnit" : { 3089 | "state" : "translated", 3090 | "value" : "Wiederherstellen" 3091 | } 3092 | }, 3093 | "en" : { 3094 | "stringUnit" : { 3095 | "state" : "translated", 3096 | "value" : "Restore" 3097 | } 3098 | }, 3099 | "es" : { 3100 | "stringUnit" : { 3101 | "state" : "translated", 3102 | "value" : "Restaurar" 3103 | } 3104 | }, 3105 | "fr" : { 3106 | "stringUnit" : { 3107 | "state" : "translated", 3108 | "value" : "Restaurer" 3109 | } 3110 | }, 3111 | "ka" : { 3112 | "stringUnit" : { 3113 | "state" : "translated", 3114 | "value" : "აღდგენა" 3115 | } 3116 | }, 3117 | "sv" : { 3118 | "stringUnit" : { 3119 | "state" : "translated", 3120 | "value" : "Återställ" 3121 | } 3122 | } 3123 | } 3124 | }, 3125 | "Button.Resume" : { 3126 | "localizations" : { 3127 | "de" : { 3128 | "stringUnit" : { 3129 | "state" : "translated", 3130 | "value" : "Fortsetzen" 3131 | } 3132 | }, 3133 | "en" : { 3134 | "stringUnit" : { 3135 | "state" : "translated", 3136 | "value" : "Resume" 3137 | } 3138 | }, 3139 | "es" : { 3140 | "stringUnit" : { 3141 | "state" : "translated", 3142 | "value" : "Reanudar" 3143 | } 3144 | }, 3145 | "fr" : { 3146 | "stringUnit" : { 3147 | "state" : "translated", 3148 | "value" : "Reprendre" 3149 | } 3150 | }, 3151 | "ka" : { 3152 | "stringUnit" : { 3153 | "state" : "translated", 3154 | "value" : "გაგრძელება" 3155 | } 3156 | }, 3157 | "sv" : { 3158 | "stringUnit" : { 3159 | "state" : "translated", 3160 | "value" : "Återuppta" 3161 | } 3162 | } 3163 | } 3164 | }, 3165 | "Button.Retry" : { 3166 | "localizations" : { 3167 | "de" : { 3168 | "stringUnit" : { 3169 | "state" : "translated", 3170 | "value" : "Wiederholen" 3171 | } 3172 | }, 3173 | "en" : { 3174 | "stringUnit" : { 3175 | "state" : "translated", 3176 | "value" : "Retry" 3177 | } 3178 | }, 3179 | "es" : { 3180 | "stringUnit" : { 3181 | "state" : "translated", 3182 | "value" : "Reintentar" 3183 | } 3184 | }, 3185 | "fr" : { 3186 | "stringUnit" : { 3187 | "state" : "translated", 3188 | "value" : "Réessayer" 3189 | } 3190 | }, 3191 | "ka" : { 3192 | "stringUnit" : { 3193 | "state" : "translated", 3194 | "value" : "ახლიდან ცდა" 3195 | } 3196 | }, 3197 | "sv" : { 3198 | "stringUnit" : { 3199 | "state" : "translated", 3200 | "value" : "Försök igen" 3201 | } 3202 | } 3203 | } 3204 | }, 3205 | "Button.Return" : { 3206 | "localizations" : { 3207 | "de" : { 3208 | "stringUnit" : { 3209 | "state" : "translated", 3210 | "value" : "Zurückkehren" 3211 | } 3212 | }, 3213 | "en" : { 3214 | "stringUnit" : { 3215 | "state" : "translated", 3216 | "value" : "Return" 3217 | } 3218 | }, 3219 | "es" : { 3220 | "stringUnit" : { 3221 | "state" : "translated", 3222 | "value" : "Volver" 3223 | } 3224 | }, 3225 | "fr" : { 3226 | "stringUnit" : { 3227 | "state" : "translated", 3228 | "value" : "Retour" 3229 | } 3230 | }, 3231 | "ka" : { 3232 | "stringUnit" : { 3233 | "state" : "translated", 3234 | "value" : "დაბრუნება" 3235 | } 3236 | }, 3237 | "sv" : { 3238 | "stringUnit" : { 3239 | "state" : "translated", 3240 | "value" : "Återgå" 3241 | } 3242 | } 3243 | } 3244 | }, 3245 | "Button.Save" : { 3246 | "localizations" : { 3247 | "de" : { 3248 | "stringUnit" : { 3249 | "state" : "translated", 3250 | "value" : "Speichern" 3251 | } 3252 | }, 3253 | "en" : { 3254 | "stringUnit" : { 3255 | "state" : "translated", 3256 | "value" : "Save" 3257 | } 3258 | }, 3259 | "es" : { 3260 | "stringUnit" : { 3261 | "state" : "translated", 3262 | "value" : "Guardar" 3263 | } 3264 | }, 3265 | "fr" : { 3266 | "stringUnit" : { 3267 | "state" : "translated", 3268 | "value" : "Enregistrer" 3269 | } 3270 | }, 3271 | "ka" : { 3272 | "stringUnit" : { 3273 | "state" : "translated", 3274 | "value" : "შენახვა" 3275 | } 3276 | }, 3277 | "sv" : { 3278 | "stringUnit" : { 3279 | "state" : "translated", 3280 | "value" : "Spara" 3281 | } 3282 | } 3283 | } 3284 | }, 3285 | "Button.Search" : { 3286 | "localizations" : { 3287 | "de" : { 3288 | "stringUnit" : { 3289 | "state" : "translated", 3290 | "value" : "Suchen" 3291 | } 3292 | }, 3293 | "en" : { 3294 | "stringUnit" : { 3295 | "state" : "translated", 3296 | "value" : "Search" 3297 | } 3298 | }, 3299 | "es" : { 3300 | "stringUnit" : { 3301 | "state" : "translated", 3302 | "value" : "Buscar" 3303 | } 3304 | }, 3305 | "fr" : { 3306 | "stringUnit" : { 3307 | "state" : "translated", 3308 | "value" : "Rechercher" 3309 | } 3310 | }, 3311 | "ka" : { 3312 | "stringUnit" : { 3313 | "state" : "translated", 3314 | "value" : "ძებნა" 3315 | } 3316 | }, 3317 | "sv" : { 3318 | "stringUnit" : { 3319 | "state" : "translated", 3320 | "value" : "Sök" 3321 | } 3322 | } 3323 | } 3324 | }, 3325 | "Button.Select" : { 3326 | "localizations" : { 3327 | "de" : { 3328 | "stringUnit" : { 3329 | "state" : "translated", 3330 | "value" : "Auswählen" 3331 | } 3332 | }, 3333 | "en" : { 3334 | "stringUnit" : { 3335 | "state" : "translated", 3336 | "value" : "Select" 3337 | } 3338 | }, 3339 | "es" : { 3340 | "stringUnit" : { 3341 | "state" : "translated", 3342 | "value" : "Seleccionar" 3343 | } 3344 | }, 3345 | "fr" : { 3346 | "stringUnit" : { 3347 | "state" : "translated", 3348 | "value" : "Sélectionner" 3349 | } 3350 | }, 3351 | "ka" : { 3352 | "stringUnit" : { 3353 | "state" : "translated", 3354 | "value" : "მონიშვნა" 3355 | } 3356 | }, 3357 | "sv" : { 3358 | "stringUnit" : { 3359 | "state" : "translated", 3360 | "value" : "Välj" 3361 | } 3362 | } 3363 | } 3364 | }, 3365 | "Button.Send" : { 3366 | "localizations" : { 3367 | "de" : { 3368 | "stringUnit" : { 3369 | "state" : "translated", 3370 | "value" : "Senden" 3371 | } 3372 | }, 3373 | "en" : { 3374 | "stringUnit" : { 3375 | "state" : "translated", 3376 | "value" : "Send" 3377 | } 3378 | }, 3379 | "es" : { 3380 | "stringUnit" : { 3381 | "state" : "translated", 3382 | "value" : "Enviar" 3383 | } 3384 | }, 3385 | "fr" : { 3386 | "stringUnit" : { 3387 | "state" : "translated", 3388 | "value" : "Envoyer" 3389 | } 3390 | }, 3391 | "ka" : { 3392 | "stringUnit" : { 3393 | "state" : "translated", 3394 | "value" : "გაგზავნა" 3395 | } 3396 | }, 3397 | "sv" : { 3398 | "stringUnit" : { 3399 | "state" : "translated", 3400 | "value" : "Skicka" 3401 | } 3402 | } 3403 | } 3404 | }, 3405 | "Button.Settings" : { 3406 | "localizations" : { 3407 | "de" : { 3408 | "stringUnit" : { 3409 | "state" : "translated", 3410 | "value" : "Einstellungen" 3411 | } 3412 | }, 3413 | "en" : { 3414 | "stringUnit" : { 3415 | "state" : "translated", 3416 | "value" : "Settings" 3417 | } 3418 | }, 3419 | "es" : { 3420 | "stringUnit" : { 3421 | "state" : "translated", 3422 | "value" : "Configuración" 3423 | } 3424 | }, 3425 | "fr" : { 3426 | "stringUnit" : { 3427 | "state" : "translated", 3428 | "value" : "Réglages" 3429 | } 3430 | }, 3431 | "ka" : { 3432 | "stringUnit" : { 3433 | "state" : "translated", 3434 | "value" : "პარამეტრები" 3435 | } 3436 | }, 3437 | "sv" : { 3438 | "stringUnit" : { 3439 | "state" : "translated", 3440 | "value" : "Inställningar" 3441 | } 3442 | } 3443 | } 3444 | }, 3445 | "Button.Share" : { 3446 | "localizations" : { 3447 | "de" : { 3448 | "stringUnit" : { 3449 | "state" : "translated", 3450 | "value" : "Teilen" 3451 | } 3452 | }, 3453 | "en" : { 3454 | "stringUnit" : { 3455 | "state" : "translated", 3456 | "value" : "Share" 3457 | } 3458 | }, 3459 | "es" : { 3460 | "stringUnit" : { 3461 | "state" : "translated", 3462 | "value" : "Compartir" 3463 | } 3464 | }, 3465 | "fr" : { 3466 | "stringUnit" : { 3467 | "state" : "translated", 3468 | "value" : "Partager" 3469 | } 3470 | }, 3471 | "ka" : { 3472 | "stringUnit" : { 3473 | "state" : "translated", 3474 | "value" : "გაზიარება" 3475 | } 3476 | }, 3477 | "sv" : { 3478 | "stringUnit" : { 3479 | "state" : "translated", 3480 | "value" : "Dela" 3481 | } 3482 | } 3483 | } 3484 | }, 3485 | "Button.Show" : { 3486 | "localizations" : { 3487 | "de" : { 3488 | "stringUnit" : { 3489 | "state" : "translated", 3490 | "value" : "Anzeigen" 3491 | } 3492 | }, 3493 | "en" : { 3494 | "stringUnit" : { 3495 | "state" : "translated", 3496 | "value" : "Show" 3497 | } 3498 | }, 3499 | "es" : { 3500 | "stringUnit" : { 3501 | "state" : "translated", 3502 | "value" : "Mostrar" 3503 | } 3504 | }, 3505 | "fr" : { 3506 | "stringUnit" : { 3507 | "state" : "translated", 3508 | "value" : "Voir" 3509 | } 3510 | }, 3511 | "ka" : { 3512 | "stringUnit" : { 3513 | "state" : "translated", 3514 | "value" : "ჩვენება" 3515 | } 3516 | }, 3517 | "sv" : { 3518 | "stringUnit" : { 3519 | "state" : "translated", 3520 | "value" : "Visa" 3521 | } 3522 | } 3523 | } 3524 | }, 3525 | "Button.Shuffle" : { 3526 | "localizations" : { 3527 | "de" : { 3528 | "stringUnit" : { 3529 | "state" : "translated", 3530 | "value" : "Mischen" 3531 | } 3532 | }, 3533 | "en" : { 3534 | "stringUnit" : { 3535 | "state" : "translated", 3536 | "value" : "Shuffle" 3537 | } 3538 | }, 3539 | "es" : { 3540 | "stringUnit" : { 3541 | "state" : "translated", 3542 | "value" : "Aleatorio" 3543 | } 3544 | }, 3545 | "fr" : { 3546 | "stringUnit" : { 3547 | "state" : "translated", 3548 | "value" : "Mélanger" 3549 | } 3550 | }, 3551 | "ka" : { 3552 | "stringUnit" : { 3553 | "state" : "translated", 3554 | "value" : "შაფლი" 3555 | } 3556 | }, 3557 | "sv" : { 3558 | "stringUnit" : { 3559 | "state" : "translated", 3560 | "value" : "Blanda" 3561 | } 3562 | } 3563 | } 3564 | }, 3565 | "Button.Sign" : { 3566 | "localizations" : { 3567 | "de" : { 3568 | "stringUnit" : { 3569 | "state" : "translated", 3570 | "value" : "Unterzeichnen" 3571 | } 3572 | }, 3573 | "en" : { 3574 | "stringUnit" : { 3575 | "state" : "translated", 3576 | "value" : "Sign" 3577 | } 3578 | }, 3579 | "es" : { 3580 | "stringUnit" : { 3581 | "state" : "translated", 3582 | "value" : "Firmar" 3583 | } 3584 | }, 3585 | "fr" : { 3586 | "stringUnit" : { 3587 | "state" : "translated", 3588 | "value" : "Signer" 3589 | } 3590 | }, 3591 | "ka" : { 3592 | "stringUnit" : { 3593 | "state" : "translated", 3594 | "value" : "შესვლა" 3595 | } 3596 | }, 3597 | "sv" : { 3598 | "stringUnit" : { 3599 | "state" : "translated", 3600 | "value" : "Signera" 3601 | } 3602 | } 3603 | } 3604 | }, 3605 | "Button.Skip" : { 3606 | "localizations" : { 3607 | "de" : { 3608 | "stringUnit" : { 3609 | "state" : "translated", 3610 | "value" : "Überspringen" 3611 | } 3612 | }, 3613 | "en" : { 3614 | "stringUnit" : { 3615 | "state" : "translated", 3616 | "value" : "Skip" 3617 | } 3618 | }, 3619 | "es" : { 3620 | "stringUnit" : { 3621 | "state" : "translated", 3622 | "value" : "Omitir" 3623 | } 3624 | }, 3625 | "fr" : { 3626 | "stringUnit" : { 3627 | "state" : "translated", 3628 | "value" : "Passer" 3629 | } 3630 | }, 3631 | "ka" : { 3632 | "stringUnit" : { 3633 | "state" : "translated", 3634 | "value" : "გამოტოვება" 3635 | } 3636 | }, 3637 | "sv" : { 3638 | "stringUnit" : { 3639 | "state" : "translated", 3640 | "value" : "Hoppa över" 3641 | } 3642 | } 3643 | } 3644 | }, 3645 | "Button.Sort" : { 3646 | "localizations" : { 3647 | "de" : { 3648 | "stringUnit" : { 3649 | "state" : "translated", 3650 | "value" : "Sortieren" 3651 | } 3652 | }, 3653 | "en" : { 3654 | "stringUnit" : { 3655 | "state" : "translated", 3656 | "value" : "Sort" 3657 | } 3658 | }, 3659 | "es" : { 3660 | "stringUnit" : { 3661 | "state" : "translated", 3662 | "value" : "Ordenar" 3663 | } 3664 | }, 3665 | "fr" : { 3666 | "stringUnit" : { 3667 | "state" : "translated", 3668 | "value" : "Trier" 3669 | } 3670 | }, 3671 | "ka" : { 3672 | "stringUnit" : { 3673 | "state" : "translated", 3674 | "value" : "სორტირება" 3675 | } 3676 | }, 3677 | "sv" : { 3678 | "stringUnit" : { 3679 | "state" : "translated", 3680 | "value" : "Sortera" 3681 | } 3682 | } 3683 | } 3684 | }, 3685 | "Button.Start" : { 3686 | "localizations" : { 3687 | "de" : { 3688 | "stringUnit" : { 3689 | "state" : "translated", 3690 | "value" : "Starten" 3691 | } 3692 | }, 3693 | "en" : { 3694 | "stringUnit" : { 3695 | "state" : "translated", 3696 | "value" : "Start" 3697 | } 3698 | }, 3699 | "es" : { 3700 | "stringUnit" : { 3701 | "state" : "translated", 3702 | "value" : "Iniciar" 3703 | } 3704 | }, 3705 | "fr" : { 3706 | "stringUnit" : { 3707 | "state" : "translated", 3708 | "value" : "Commencer" 3709 | } 3710 | }, 3711 | "ka" : { 3712 | "stringUnit" : { 3713 | "state" : "translated", 3714 | "value" : "დაწება" 3715 | } 3716 | }, 3717 | "sv" : { 3718 | "stringUnit" : { 3719 | "state" : "translated", 3720 | "value" : "Starta" 3721 | } 3722 | } 3723 | } 3724 | }, 3725 | "Button.Stop" : { 3726 | "localizations" : { 3727 | "de" : { 3728 | "stringUnit" : { 3729 | "state" : "translated", 3730 | "value" : "Stoppen" 3731 | } 3732 | }, 3733 | "en" : { 3734 | "stringUnit" : { 3735 | "state" : "translated", 3736 | "value" : "Stop" 3737 | } 3738 | }, 3739 | "es" : { 3740 | "stringUnit" : { 3741 | "state" : "translated", 3742 | "value" : "Detener" 3743 | } 3744 | }, 3745 | "fr" : { 3746 | "stringUnit" : { 3747 | "state" : "translated", 3748 | "value" : "Arrêter" 3749 | } 3750 | }, 3751 | "ka" : { 3752 | "stringUnit" : { 3753 | "state" : "translated", 3754 | "value" : "გაჩერება" 3755 | } 3756 | }, 3757 | "sv" : { 3758 | "stringUnit" : { 3759 | "state" : "translated", 3760 | "value" : "Stoppa" 3761 | } 3762 | } 3763 | } 3764 | }, 3765 | "Button.Submit" : { 3766 | "localizations" : { 3767 | "de" : { 3768 | "stringUnit" : { 3769 | "state" : "translated", 3770 | "value" : "Absenden" 3771 | } 3772 | }, 3773 | "en" : { 3774 | "stringUnit" : { 3775 | "state" : "translated", 3776 | "value" : "Submit" 3777 | } 3778 | }, 3779 | "es" : { 3780 | "stringUnit" : { 3781 | "state" : "translated", 3782 | "value" : "Enviar" 3783 | } 3784 | }, 3785 | "fr" : { 3786 | "stringUnit" : { 3787 | "state" : "translated", 3788 | "value" : "Envoyer" 3789 | } 3790 | }, 3791 | "ka" : { 3792 | "stringUnit" : { 3793 | "state" : "translated", 3794 | "value" : "გაგზავნა" 3795 | } 3796 | }, 3797 | "sv" : { 3798 | "stringUnit" : { 3799 | "state" : "translated", 3800 | "value" : "Skicka in" 3801 | } 3802 | } 3803 | } 3804 | }, 3805 | "Button.Subscribe" : { 3806 | "localizations" : { 3807 | "de" : { 3808 | "stringUnit" : { 3809 | "state" : "translated", 3810 | "value" : "Abonnieren" 3811 | } 3812 | }, 3813 | "en" : { 3814 | "stringUnit" : { 3815 | "state" : "translated", 3816 | "value" : "Subscribe" 3817 | } 3818 | }, 3819 | "es" : { 3820 | "stringUnit" : { 3821 | "state" : "translated", 3822 | "value" : "Suscribirse" 3823 | } 3824 | }, 3825 | "fr" : { 3826 | "stringUnit" : { 3827 | "state" : "translated", 3828 | "value" : "S'abonner" 3829 | } 3830 | }, 3831 | "ka" : { 3832 | "stringUnit" : { 3833 | "state" : "translated", 3834 | "value" : "გამოწერა" 3835 | } 3836 | }, 3837 | "sv" : { 3838 | "stringUnit" : { 3839 | "state" : "translated", 3840 | "value" : "Prenumerera" 3841 | } 3842 | } 3843 | } 3844 | }, 3845 | "Button.Sync" : { 3846 | "localizations" : { 3847 | "de" : { 3848 | "stringUnit" : { 3849 | "state" : "translated", 3850 | "value" : "Synchronisieren" 3851 | } 3852 | }, 3853 | "en" : { 3854 | "stringUnit" : { 3855 | "state" : "translated", 3856 | "value" : "Sync" 3857 | } 3858 | }, 3859 | "es" : { 3860 | "stringUnit" : { 3861 | "state" : "translated", 3862 | "value" : "Sincronizar" 3863 | } 3864 | }, 3865 | "fr" : { 3866 | "stringUnit" : { 3867 | "state" : "translated", 3868 | "value" : "Synchroniser" 3869 | } 3870 | }, 3871 | "ka" : { 3872 | "stringUnit" : { 3873 | "state" : "translated", 3874 | "value" : "სინქი" 3875 | } 3876 | }, 3877 | "sv" : { 3878 | "stringUnit" : { 3879 | "state" : "translated", 3880 | "value" : "Synkronisera" 3881 | } 3882 | } 3883 | } 3884 | }, 3885 | "Button.Tag" : { 3886 | "localizations" : { 3887 | "de" : { 3888 | "stringUnit" : { 3889 | "state" : "translated", 3890 | "value" : "Markieren" 3891 | } 3892 | }, 3893 | "en" : { 3894 | "stringUnit" : { 3895 | "state" : "translated", 3896 | "value" : "Tag" 3897 | } 3898 | }, 3899 | "es" : { 3900 | "stringUnit" : { 3901 | "state" : "translated", 3902 | "value" : "Etiquetar" 3903 | } 3904 | }, 3905 | "fr" : { 3906 | "stringUnit" : { 3907 | "state" : "translated", 3908 | "value" : "Tagger" 3909 | } 3910 | }, 3911 | "ka" : { 3912 | "stringUnit" : { 3913 | "state" : "translated", 3914 | "value" : "ტეგი" 3915 | } 3916 | }, 3917 | "sv" : { 3918 | "stringUnit" : { 3919 | "state" : "translated", 3920 | "value" : "Tagga" 3921 | } 3922 | } 3923 | } 3924 | }, 3925 | "Button.Translate" : { 3926 | "localizations" : { 3927 | "de" : { 3928 | "stringUnit" : { 3929 | "state" : "translated", 3930 | "value" : "Übersetzen" 3931 | } 3932 | }, 3933 | "en" : { 3934 | "stringUnit" : { 3935 | "state" : "translated", 3936 | "value" : "Translate" 3937 | } 3938 | }, 3939 | "es" : { 3940 | "stringUnit" : { 3941 | "state" : "translated", 3942 | "value" : "Traducir" 3943 | } 3944 | }, 3945 | "fr" : { 3946 | "stringUnit" : { 3947 | "state" : "translated", 3948 | "value" : "Traduire" 3949 | } 3950 | }, 3951 | "ka" : { 3952 | "stringUnit" : { 3953 | "state" : "translated", 3954 | "value" : "თარგმნა" 3955 | } 3956 | }, 3957 | "sv" : { 3958 | "stringUnit" : { 3959 | "state" : "translated", 3960 | "value" : "Översätt" 3961 | } 3962 | } 3963 | } 3964 | }, 3965 | "Button.Undo" : { 3966 | "localizations" : { 3967 | "de" : { 3968 | "stringUnit" : { 3969 | "state" : "translated", 3970 | "value" : "Rückgängig" 3971 | } 3972 | }, 3973 | "en" : { 3974 | "stringUnit" : { 3975 | "state" : "translated", 3976 | "value" : "Undo" 3977 | } 3978 | }, 3979 | "es" : { 3980 | "stringUnit" : { 3981 | "state" : "translated", 3982 | "value" : "Deshacer" 3983 | } 3984 | }, 3985 | "fr" : { 3986 | "stringUnit" : { 3987 | "state" : "translated", 3988 | "value" : "Défaire" 3989 | } 3990 | }, 3991 | "ka" : { 3992 | "stringUnit" : { 3993 | "state" : "translated", 3994 | "value" : "უკუსვლა" 3995 | } 3996 | }, 3997 | "sv" : { 3998 | "stringUnit" : { 3999 | "state" : "translated", 4000 | "value" : "Ångra" 4001 | } 4002 | } 4003 | } 4004 | }, 4005 | "Button.Unlike" : { 4006 | "localizations" : { 4007 | "de" : { 4008 | "stringUnit" : { 4009 | "state" : "translated", 4010 | "value" : "Gefällt mir nicht mehr" 4011 | } 4012 | }, 4013 | "en" : { 4014 | "stringUnit" : { 4015 | "state" : "translated", 4016 | "value" : "Unlike" 4017 | } 4018 | }, 4019 | "es" : { 4020 | "stringUnit" : { 4021 | "state" : "translated", 4022 | "value" : "Ya no me gusta" 4023 | } 4024 | }, 4025 | "fr" : { 4026 | "stringUnit" : { 4027 | "state" : "translated", 4028 | "value" : "Je n’aime pas" 4029 | } 4030 | }, 4031 | "ka" : { 4032 | "stringUnit" : { 4033 | "state" : "translated", 4034 | "value" : "მოწონების გაუქმება" 4035 | } 4036 | }, 4037 | "sv" : { 4038 | "stringUnit" : { 4039 | "state" : "translated", 4040 | "value" : "Ogilla" 4041 | } 4042 | } 4043 | } 4044 | }, 4045 | "Button.Unlock" : { 4046 | "localizations" : { 4047 | "de" : { 4048 | "stringUnit" : { 4049 | "state" : "translated", 4050 | "value" : "Entsperren" 4051 | } 4052 | }, 4053 | "en" : { 4054 | "stringUnit" : { 4055 | "state" : "translated", 4056 | "value" : "Unlock" 4057 | } 4058 | }, 4059 | "es" : { 4060 | "stringUnit" : { 4061 | "state" : "translated", 4062 | "value" : "Desbloquear" 4063 | } 4064 | }, 4065 | "fr" : { 4066 | "stringUnit" : { 4067 | "state" : "translated", 4068 | "value" : "Déverrouiller" 4069 | } 4070 | }, 4071 | "ka" : { 4072 | "stringUnit" : { 4073 | "state" : "translated", 4074 | "value" : "გახსნა" 4075 | } 4076 | }, 4077 | "sv" : { 4078 | "stringUnit" : { 4079 | "state" : "translated", 4080 | "value" : "Lås upp" 4081 | } 4082 | } 4083 | } 4084 | }, 4085 | "Button.Unmute" : { 4086 | "localizations" : { 4087 | "de" : { 4088 | "stringUnit" : { 4089 | "state" : "translated", 4090 | "value" : "Stummschaltung aufheben" 4091 | } 4092 | }, 4093 | "en" : { 4094 | "stringUnit" : { 4095 | "state" : "translated", 4096 | "value" : "Unmute" 4097 | } 4098 | }, 4099 | "es" : { 4100 | "stringUnit" : { 4101 | "state" : "translated", 4102 | "value" : "Activar sonido" 4103 | } 4104 | }, 4105 | "fr" : { 4106 | "stringUnit" : { 4107 | "state" : "translated", 4108 | "value" : "Rétablir le son" 4109 | } 4110 | }, 4111 | "ka" : { 4112 | "stringUnit" : { 4113 | "state" : "translated", 4114 | "value" : "ხმის ჩართვა" 4115 | } 4116 | }, 4117 | "sv" : { 4118 | "stringUnit" : { 4119 | "state" : "translated", 4120 | "value" : "Sätt på ljud" 4121 | } 4122 | } 4123 | } 4124 | }, 4125 | "Button.Unsubscribe" : { 4126 | "localizations" : { 4127 | "de" : { 4128 | "stringUnit" : { 4129 | "state" : "translated", 4130 | "value" : "Abbestellen" 4131 | } 4132 | }, 4133 | "en" : { 4134 | "stringUnit" : { 4135 | "state" : "translated", 4136 | "value" : "Unsubscribe" 4137 | } 4138 | }, 4139 | "es" : { 4140 | "stringUnit" : { 4141 | "state" : "translated", 4142 | "value" : "Cancelar suscripción" 4143 | } 4144 | }, 4145 | "fr" : { 4146 | "stringUnit" : { 4147 | "state" : "translated", 4148 | "value" : "Se désabonner" 4149 | } 4150 | }, 4151 | "ka" : { 4152 | "stringUnit" : { 4153 | "state" : "translated", 4154 | "value" : "გამოწერის გაუქმება" 4155 | } 4156 | }, 4157 | "sv" : { 4158 | "stringUnit" : { 4159 | "state" : "translated", 4160 | "value" : "Avsluta prenumeration" 4161 | } 4162 | } 4163 | } 4164 | }, 4165 | "Button.Update" : { 4166 | "localizations" : { 4167 | "de" : { 4168 | "stringUnit" : { 4169 | "state" : "translated", 4170 | "value" : "Aktualisieren" 4171 | } 4172 | }, 4173 | "en" : { 4174 | "stringUnit" : { 4175 | "state" : "translated", 4176 | "value" : "Update" 4177 | } 4178 | }, 4179 | "es" : { 4180 | "stringUnit" : { 4181 | "state" : "translated", 4182 | "value" : "Actualizar" 4183 | } 4184 | }, 4185 | "fr" : { 4186 | "stringUnit" : { 4187 | "state" : "translated", 4188 | "value" : "Mettre à jour" 4189 | } 4190 | }, 4191 | "ka" : { 4192 | "stringUnit" : { 4193 | "state" : "translated", 4194 | "value" : "განახლება" 4195 | } 4196 | }, 4197 | "sv" : { 4198 | "stringUnit" : { 4199 | "state" : "translated", 4200 | "value" : "Uppdatera" 4201 | } 4202 | } 4203 | } 4204 | }, 4205 | "Button.Upload" : { 4206 | "localizations" : { 4207 | "de" : { 4208 | "stringUnit" : { 4209 | "state" : "translated", 4210 | "value" : "Hochladen" 4211 | } 4212 | }, 4213 | "en" : { 4214 | "stringUnit" : { 4215 | "state" : "translated", 4216 | "value" : "Upload" 4217 | } 4218 | }, 4219 | "es" : { 4220 | "stringUnit" : { 4221 | "state" : "translated", 4222 | "value" : "Subir" 4223 | } 4224 | }, 4225 | "fr" : { 4226 | "stringUnit" : { 4227 | "state" : "translated", 4228 | "value" : "Téléverser" 4229 | } 4230 | }, 4231 | "ka" : { 4232 | "stringUnit" : { 4233 | "state" : "translated", 4234 | "value" : "ატვირთვა" 4235 | } 4236 | }, 4237 | "sv" : { 4238 | "stringUnit" : { 4239 | "state" : "translated", 4240 | "value" : "Ladda upp" 4241 | } 4242 | } 4243 | } 4244 | }, 4245 | "Button.Verify" : { 4246 | "localizations" : { 4247 | "de" : { 4248 | "stringUnit" : { 4249 | "state" : "translated", 4250 | "value" : "Verifizieren" 4251 | } 4252 | }, 4253 | "en" : { 4254 | "stringUnit" : { 4255 | "state" : "translated", 4256 | "value" : "Verify" 4257 | } 4258 | }, 4259 | "es" : { 4260 | "stringUnit" : { 4261 | "state" : "translated", 4262 | "value" : "Verificar" 4263 | } 4264 | }, 4265 | "fr" : { 4266 | "stringUnit" : { 4267 | "state" : "translated", 4268 | "value" : "Vérifier" 4269 | } 4270 | }, 4271 | "ka" : { 4272 | "stringUnit" : { 4273 | "state" : "translated", 4274 | "value" : "ვერიფიკაცია" 4275 | } 4276 | }, 4277 | "sv" : { 4278 | "stringUnit" : { 4279 | "state" : "translated", 4280 | "value" : "Verifiera" 4281 | } 4282 | } 4283 | } 4284 | }, 4285 | "Button.View" : { 4286 | "localizations" : { 4287 | "de" : { 4288 | "stringUnit" : { 4289 | "state" : "translated", 4290 | "value" : "Ansehen" 4291 | } 4292 | }, 4293 | "en" : { 4294 | "stringUnit" : { 4295 | "state" : "translated", 4296 | "value" : "View" 4297 | } 4298 | }, 4299 | "es" : { 4300 | "stringUnit" : { 4301 | "state" : "translated", 4302 | "value" : "Ver" 4303 | } 4304 | }, 4305 | "fr" : { 4306 | "stringUnit" : { 4307 | "state" : "translated", 4308 | "value" : "Voir" 4309 | } 4310 | }, 4311 | "ka" : { 4312 | "stringUnit" : { 4313 | "state" : "translated", 4314 | "value" : "ნახვა" 4315 | } 4316 | }, 4317 | "sv" : { 4318 | "stringUnit" : { 4319 | "state" : "translated", 4320 | "value" : "Visa" 4321 | } 4322 | } 4323 | } 4324 | }, 4325 | "Button.Zoom" : { 4326 | "localizations" : { 4327 | "de" : { 4328 | "stringUnit" : { 4329 | "state" : "translated", 4330 | "value" : "Zoomen" 4331 | } 4332 | }, 4333 | "en" : { 4334 | "stringUnit" : { 4335 | "state" : "translated", 4336 | "value" : "Zoom" 4337 | } 4338 | }, 4339 | "es" : { 4340 | "stringUnit" : { 4341 | "state" : "translated", 4342 | "value" : "Zoom" 4343 | } 4344 | }, 4345 | "fr" : { 4346 | "stringUnit" : { 4347 | "state" : "translated", 4348 | "value" : "Zoom" 4349 | } 4350 | }, 4351 | "ka" : { 4352 | "stringUnit" : { 4353 | "state" : "translated", 4354 | "value" : "ფოკუსი" 4355 | } 4356 | }, 4357 | "sv" : { 4358 | "stringUnit" : { 4359 | "state" : "translated", 4360 | "value" : "Zooma" 4361 | } 4362 | } 4363 | } 4364 | }, 4365 | "Button.ZoomIn" : { 4366 | "localizations" : { 4367 | "de" : { 4368 | "stringUnit" : { 4369 | "state" : "translated", 4370 | "value" : "Vergrößern" 4371 | } 4372 | }, 4373 | "en" : { 4374 | "stringUnit" : { 4375 | "state" : "translated", 4376 | "value" : "Zoom In" 4377 | } 4378 | }, 4379 | "es" : { 4380 | "stringUnit" : { 4381 | "state" : "translated", 4382 | "value" : "Acercar" 4383 | } 4384 | }, 4385 | "fr" : { 4386 | "stringUnit" : { 4387 | "state" : "translated", 4388 | "value" : "Zoomer" 4389 | } 4390 | }, 4391 | "ka" : { 4392 | "stringUnit" : { 4393 | "state" : "translated", 4394 | "value" : "მიახლოება" 4395 | } 4396 | }, 4397 | "sv" : { 4398 | "stringUnit" : { 4399 | "state" : "translated", 4400 | "value" : "Zooma in" 4401 | } 4402 | } 4403 | } 4404 | }, 4405 | "Button.ZoomOut" : { 4406 | "localizations" : { 4407 | "de" : { 4408 | "stringUnit" : { 4409 | "state" : "translated", 4410 | "value" : "Verkleinern" 4411 | } 4412 | }, 4413 | "en" : { 4414 | "stringUnit" : { 4415 | "state" : "translated", 4416 | "value" : "Zoom Out" 4417 | } 4418 | }, 4419 | "es" : { 4420 | "stringUnit" : { 4421 | "state" : "translated", 4422 | "value" : "Alejar" 4423 | } 4424 | }, 4425 | "fr" : { 4426 | "stringUnit" : { 4427 | "state" : "translated", 4428 | "value" : "Dézoomer" 4429 | } 4430 | }, 4431 | "ka" : { 4432 | "stringUnit" : { 4433 | "state" : "translated", 4434 | "value" : "დაშორება" 4435 | } 4436 | }, 4437 | "sv" : { 4438 | "stringUnit" : { 4439 | "state" : "translated", 4440 | "value" : "Zooma ut" 4441 | } 4442 | } 4443 | } 4444 | } 4445 | }, 4446 | "version" : "1.0" 4447 | } -------------------------------------------------------------------------------- /Sources/StandardButtons/StandardButtonType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StandardButtonType.swift 3 | // SwiftUIKit 4 | // 5 | // Created by Daniel Saidi on 2024-04-30. 6 | // Copyright © 2024-2025 Daniel Saidi. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | /// This enum defines standard button types. 12 | /// 13 | /// Each button type defines a localized title, an image, as 14 | /// well as a button role, and an optional keyboard shortcut. 15 | public enum StandardButtonType: String, CaseIterable, Identifiable, Sendable { 16 | case add, apply, archive, attach, 17 | back, bookmark, browse, 18 | cancel, call, close, collapse, confirm, copy, connect, create, customize, 19 | delete, deselect, disconnect, dismiss, done, download, downloaded, 20 | edit, email, end, enter, execute, exit, expand, export, 21 | favorite, filter, forward, 22 | help, hide, 23 | `import`, info, install, 24 | like, load, lock, login, logout, 25 | menu, minimize, mute, 26 | new, next, 27 | ok, open, 28 | paste, pause, pin, play, post, preview, previous, print, proceed, purchase, 29 | rate, record, redo, refresh, reject, reload, remove, removeFavorite, removeLike, rename, 30 | reply, report, reset, resize, restart, restore, resume, retry, `return`, 31 | save, search, select, send, settings, share, show, shuffle, sign, skip, sort, start, 32 | stop, submit, subscribe, sync, 33 | tag, translate, 34 | undo, unlike, unlock, unmute, unsubscribe, update, upload, 35 | verify, view, 36 | zoom, zoomIn, zoomOut 37 | } 38 | 39 | public extension Button { 40 | 41 | /// Create a ``StandardButtonType``-based button. 42 | init( 43 | _ type: StandardButtonType, 44 | action: @escaping () -> Void 45 | ) where Label == SwiftUI.Label { 46 | self.init( 47 | role: type.role, 48 | action: action 49 | ) { 50 | Label( 51 | title: { Text(type.title, bundle: .module) }, 52 | icon: { type.image } 53 | ) 54 | } 55 | } 56 | } 57 | 58 | public extension StandardButtonType { 59 | 60 | /// A button to toggle a downloaded state. 61 | static func toggleDownload(isDownloaded: Bool) -> StandardButtonType { 62 | isDownloaded ? .downloaded : .download 63 | } 64 | 65 | /// A button to toggle a favorite state. 66 | static func toggleFavorite(isFavorite: Bool) -> StandardButtonType { 67 | isFavorite ? .removeFavorite : .favorite 68 | } 69 | 70 | /// A button to toggle a liked state. 71 | static func toggleLike(isLiked: Bool) -> StandardButtonType { 72 | isLiked ? .removeLike : .like 73 | } 74 | 75 | /// A button to toggle a selected state. 76 | static func toggleSelect(isSelected: Bool) -> StandardButtonType { 77 | isSelected ? .deselect : .select 78 | } 79 | } 80 | 81 | public extension StandardButtonType { 82 | 83 | /// The button type's unique ID. 84 | var id: String { rawValue } 85 | 86 | /// The image to use for the button type. 87 | var image: Image { .init(systemName: imageName) } 88 | 89 | /// The image name to use for the button type. 90 | var imageName: String { 91 | switch self { 92 | case .add: "plus" 93 | case .apply: "checkmark.circle" 94 | case .archive: "archivebox" 95 | case .attach: "paperclip" 96 | case .back: "chevron.backward" 97 | case .bookmark: "bookmark" 98 | case .browse: "folder" 99 | case .call: "phone" 100 | case .cancel: "xmark" 101 | case .close: "xmark.circle" 102 | case .collapse: "chevron.up" 103 | case .confirm: "checkmark.circle" 104 | case .connect: "link" 105 | case .copy: "doc.on.doc" 106 | case .create: "plus.circle" 107 | case .customize: "slider.horizontal.3" 108 | case .delete: "trash" 109 | case .deselect: "checkmark.circle.fill" 110 | case .disconnect: "link.badge.minus" 111 | case .dismiss: "xmark" 112 | case .done: "checkmark" 113 | case .download: "arrow.down.circle" 114 | case .downloaded: "arrow.down.circle.fill" 115 | case .edit: "pencil" 116 | case .email: "envelope" 117 | case .end: "stop.circle" 118 | case .enter: "return" 119 | case .execute: "play.circle" 120 | case .exit: "rectangle.portrait.and.arrow.right" 121 | case .expand: "chevron.down" 122 | case .export: "square.and.arrow.up" 123 | case .favorite: "star" 124 | case .filter: "line.3.horizontal.decrease.circle" 125 | case .forward: "chevron.forward" 126 | case .help: "questionmark.circle" 127 | case .hide: "eye.slash" 128 | case .import: "square.and.arrow.down" 129 | case .info: "info.circle" 130 | case .install: "arrow.down.app" 131 | case .like: "heart" 132 | case .load: "arrow.clockwise" 133 | case .lock: "lock" 134 | case .login: "person.crop.circle" 135 | case .logout: "rectangle.portrait.and.arrow.forward" 136 | case .menu: "list.bullet" 137 | case .minimize: "minus.circle" 138 | case .mute: "speaker.slash" 139 | case .new: "plus" 140 | case .next: "arrow.right" 141 | case .ok: "checkmark" 142 | case .open: "folder" 143 | case .paste: "clipboard" 144 | case .pause: "pause.circle" 145 | case .pin: "pin" 146 | case .play: "play.circle" 147 | case .post: "paperplane" 148 | case .preview: "eye" 149 | case .previous: "arrow.left" 150 | case .print: "printer" 151 | case .proceed: "arrow.right.circle" 152 | case .purchase: "cart" 153 | case .rate: "star" 154 | case .record: "record.circle" 155 | case .redo: "arrow.clockwise" 156 | case .refresh: "arrow.clockwise" 157 | case .reject: "xmark.circle" 158 | case .reload: "arrow.clockwise.circle" 159 | case .remove: "trash" 160 | case .removeFavorite: "star.fill" 161 | case .removeLike: "heart.fill" 162 | case .rename: "pencil" 163 | case .reply: "arrowshape.turn.up.left" 164 | case .report: "flag" 165 | case .reset: "arrow.counterclockwise" 166 | case .resize: "arrow.up.left.and.arrow.down.right" 167 | case .restart: "arrow.counterclockwise.circle" 168 | case .restore: "arrow.uturn.backward" 169 | case .resume: "play.circle" 170 | case .retry: "arrow.clockwise" 171 | case .return: "arrowshape.turn.up.left" 172 | case .save: "checkmark" 173 | case .search: "magnifyingglass" 174 | case .select: "checkmark.circle" 175 | case .send: "paperplane" 176 | case .settings: "gearshape" 177 | case .share: "square.and.arrow.up" 178 | case .show: "eye" 179 | case .shuffle: "shuffle" 180 | case .sign: "signature" 181 | case .skip: "forward" 182 | case .sort: "arrow.up.arrow.down" 183 | case .start: "play" 184 | case .stop: "stop.circle" 185 | case .submit: "paperplane" 186 | case .subscribe: "bell" 187 | case .sync: "arrow.triangle.2.circlepath" 188 | case .tag: "tag" 189 | case .translate: "character.bubble" 190 | case .undo: "arrow.uturn.backward" 191 | case .unlike: "hand.thumbsdown" 192 | case .unlock: "lock.open" 193 | case .unmute: "speaker.wave.2" 194 | case .unsubscribe: "bell.slash" 195 | case .update: "arrow.triangle.2.circlepath" 196 | case .upload: "arrow.up.circle" 197 | case .verify: "checkmark.shield" 198 | case .view: "eye" 199 | case .zoom: "magnifyingglass" 200 | case .zoomIn: "plus.magnifyingglass" 201 | case .zoomOut: "minus.magnifyingglass" 202 | } 203 | } 204 | 205 | #if os(iOS) || os(macOS) || os(visionOS) 206 | /// A keyboard shortcut for the the button type, if any. 207 | var keyboardShortcut: (key: KeyEquivalent, modifiers: EventModifiers?)? { 208 | switch self { 209 | case .add: ("a", .command) 210 | case .cancel: (.escape, nil) 211 | case .close: (.escape, nil) 212 | case .done: (.return, .command) 213 | case .edit: ("e", .command) 214 | case .save: ("s", .command) 215 | case .search: ("f", .command) 216 | default: nil 217 | } 218 | } 219 | #endif 220 | 221 | /// The button role to use for the button type. 222 | var role: ButtonRole? { 223 | switch self { 224 | case .back: .cancel 225 | case .cancel: .cancel 226 | case .delete: .destructive 227 | case .exit: .cancel 228 | default: nil 229 | } 230 | } 231 | 232 | /// The title to use for the button type. 233 | var title: LocalizedStringKey { 234 | switch self { 235 | case .add: "Button.Add" 236 | case .apply: "Button.Apply" 237 | case .archive: "Button.Archive" 238 | case .attach: "Button.Attach" 239 | case .back: "Button.Back" 240 | case .bookmark: "Button.Bookmark" 241 | case .browse: "Button.Browse" 242 | case .call: "Button.Call" 243 | case .cancel: "Button.Cancel" 244 | case .close: "Button.Close" 245 | case .collapse: "Button.Collapse" 246 | case .confirm: "Button.Confirm" 247 | case .connect: "Button.Connect" 248 | case .copy: "Button.Copy" 249 | case .create: "Button.Create" 250 | case .customize: "Button.Customize" 251 | case .delete: "Button.Delete" 252 | case .deselect: "Button.Deselect" 253 | case .disconnect: "Button.Disconnect" 254 | case .dismiss: "Button.Dismiss" 255 | case .done: "Button.Done" 256 | case .download: "Button.Download" 257 | case .downloaded: "Button.Downloaded" 258 | case .edit: "Button.Edit" 259 | case .email: "Button.Email" 260 | case .end: "Button.End" 261 | case .enter: "Button.Enter" 262 | case .execute: "Button.Execute" 263 | case .exit: "Button.Exit" 264 | case .expand: "Button.Expand" 265 | case .export: "Button.Export" 266 | case .favorite: "Button.Favorite" 267 | case .filter: "Button.Filter" 268 | case .forward: "Button.Forward" 269 | case .help: "Button.Help" 270 | case .hide: "Button.Hide" 271 | case .import: "Button.Import" 272 | case .info: "Button.Info" 273 | case .install: "Button.Install" 274 | case .like: "Button.Like" 275 | case .load: "Button.Load" 276 | case .lock: "Button.Lock" 277 | case .login: "Button.Login" 278 | case .logout: "Button.Logout" 279 | case .menu: "Button.Menu" 280 | case .minimize: "Button.Minimize" 281 | case .mute: "Button.Mute" 282 | case .new: "Button.New" 283 | case .next: "Button.Next" 284 | case .ok: "Button.OK" 285 | case .open: "Button.Open" 286 | case .paste: "Button.Paste" 287 | case .pause: "Button.Pause" 288 | case .pin: "Button.Pin" 289 | case .play: "Button.Play" 290 | case .post: "Button.Post" 291 | case .preview: "Button.Preview" 292 | case .previous: "Button.Previous" 293 | case .print: "Button.Print" 294 | case .proceed: "Button.Proceed" 295 | case .purchase: "Button.Purchase" 296 | case .rate: "Button.Rate" 297 | case .record: "Button.Record" 298 | case .redo: "Button.Redo" 299 | case .refresh: "Button.Refresh" 300 | case .reject: "Button.Reject" 301 | case .reload: "Button.Reload" 302 | case .remove: "Button.Remove" 303 | case .removeFavorite: "Button.RemoveFavorite" 304 | case .removeLike: "Button.RemoveLike" 305 | case .rename: "Button.Rename" 306 | case .reply: "Button.Reply" 307 | case .report: "Button.Report" 308 | case .reset: "Button.Reset" 309 | case .resize: "Button.Resize" 310 | case .restart: "Button.Restart" 311 | case .restore: "Button.Restore" 312 | case .resume: "Button.Resume" 313 | case .retry: "Button.Retry" 314 | case .return: "Button.Return" 315 | case .save: "Button.Save" 316 | case .search: "Button.Search" 317 | case .select: "Button.Select" 318 | case .send: "Button.Send" 319 | case .settings: "Button.Settings" 320 | case .share: "Button.Share" 321 | case .show: "Button.Show" 322 | case .shuffle: "Button.Shuffle" 323 | case .sign: "Button.Sign" 324 | case .skip: "Button.Skip" 325 | case .sort: "Button.Sort" 326 | case .start: "Button.Start" 327 | case .stop: "Button.Stop" 328 | case .submit: "Button.Submit" 329 | case .subscribe: "Button.Subscribe" 330 | case .sync: "Button.Sync" 331 | case .tag: "Button.Tag" 332 | case .translate: "Button.Translate" 333 | case .undo: "Button.Undo" 334 | case .unlike: "Button.Unlike" 335 | case .unlock: "Button.Unlock" 336 | case .unmute: "Button.Unmute" 337 | case .unsubscribe: "Button.Unsubscribe" 338 | case .update: "Button.Update" 339 | case .upload: "Button.Upload" 340 | case .verify: "Button.Verify" 341 | case .view: "Button.View" 342 | case .zoom: "Button.Zoom" 343 | case .zoomIn: "Button.ZoomIn" 344 | case .zoomOut: "Button.ZoomOut" 345 | } 346 | } 347 | } 348 | 349 | public extension View { 350 | 351 | @ViewBuilder 352 | /// Apply a keyboard shortcut for a certain button type. 353 | func keyboardShortcut( 354 | _ button: StandardButtonType 355 | ) -> some View { 356 | #if os(iOS) || os(macOS) || os(visionOS) 357 | if let shortcut = button.keyboardShortcut { 358 | if let modifiers = shortcut.modifiers { 359 | self.keyboardShortcut(shortcut.key, modifiers: modifiers) 360 | } else { 361 | self.keyboardShortcut(shortcut.key) 362 | } 363 | } else { 364 | self 365 | } 366 | #else 367 | self 368 | #endif 369 | } 370 | } 371 | 372 | struct MyLabelStyle: LabelStyle { 373 | 374 | func makeBody(configuration: Configuration) -> some View { 375 | VStack(spacing: 5) { 376 | configuration.icon.font(.headline) 377 | configuration.title.font(.footnote) 378 | } 379 | } 380 | } 381 | 382 | 383 | #Preview { 384 | 385 | @ViewBuilder 386 | @MainActor 387 | func buttons() -> some View { 388 | Section { 389 | ForEach(StandardButtonType.allCases) { type in 390 | Button(type) { print(type.title) } 391 | } 392 | } 393 | Section { 394 | Button(.toggleFavorite(isFavorite: false)) {} 395 | Button(.toggleFavorite(isFavorite: true)) {} 396 | Button(.toggleLike(isLiked: false)) {} 397 | Button(.toggleLike(isLiked: true)) {} 398 | Button(.toggleSelect(isSelected: false)) {} 399 | Button(.toggleSelect(isSelected: true)) {} 400 | } 401 | } 402 | 403 | return List { 404 | buttons().labelStyle(.titleAndIcon) 405 | } 406 | .toolbar { 407 | ToolbarItemGroup { 408 | buttons() 409 | } 410 | } 411 | } 412 | -------------------------------------------------------------------------------- /Sources/StandardButtons/StandardButtons.docc/Resources/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielsaidi/StandardButtons/c8d133ed236c64a0b147688c582497c936f33160/Sources/StandardButtons/StandardButtons.docc/Resources/Icon.png -------------------------------------------------------------------------------- /Sources/StandardButtons/StandardButtons.docc/Resources/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielsaidi/StandardButtons/c8d133ed236c64a0b147688c582497c936f33160/Sources/StandardButtons/StandardButtons.docc/Resources/Logo.png -------------------------------------------------------------------------------- /Sources/StandardButtons/StandardButtons.docc/Resources/Preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielsaidi/StandardButtons/c8d133ed236c64a0b147688c582497c936f33160/Sources/StandardButtons/StandardButtons.docc/Resources/Preview.jpg -------------------------------------------------------------------------------- /Sources/StandardButtons/StandardButtons.docc/StandardButtons.md: -------------------------------------------------------------------------------- 1 | # ``StandardButtons`` 2 | 3 | StandardButtons is a SwiftUI library that makes it easy to create standard button types. 4 | 5 | 6 | ## Overview 7 | 8 | ![Library logotype](Logo.png) 9 | 10 | StandardButtons is a SwiftUI library that lets you create standard button types, with localized titles, icons, roles and keyboard shortcuts. 11 | 12 | StandardButtons defines **110** standard button types, like ``StandardButtonType/add``, ``StandardButtonType/delete``, ``StandardButtonType/edit``, ``StandardButtonType/done``, etc. Each button type has a localized ``StandardButtonType/title``, an ``StandardButtonType/image``, and a ``StandardButtonType/role``, as well as an optional ``StandardButtonType/keyboardShortcut``. 13 | 14 | 15 | ## Installation 16 | 17 | StandardButtons can be installed with the Swift Package Manager: 18 | 19 | ``` 20 | https://github.com/danielsaidi/StandardButtons.git 21 | ``` 22 | 23 | 24 | ## Support My Work 25 | 26 | You can [become a sponsor][Sponsors] to help me dedicate more time on my various [open-source tools][OpenSource]. Every contribution, no matter the size, makes a real difference in keeping these tools free and actively developed. 27 | 28 | 29 | 30 | ## Getting started 31 | 32 | With StandardButtons, just `import StandardButtons` and use ``SwiftUI/Button``. ``SwiftUI/Button/init(_:action:)`` to create a standard button view: 33 | 34 | ```swift 35 | Button(.add) { 36 | // Add your custom add logic here 37 | } 38 | ``` 39 | 40 | The code above will render a regular SwiftUI ``SwiftUI/Button`` and works on all major Apple platforms (iOS, macOS, tvOS, watchOS, visionOS). 41 | 42 | 43 | 44 | ## Localization 45 | 46 | This library is localized in the following languages: 47 | 48 | * 🇺🇸 English (US) 49 | * 🇫🇷 French 50 | * 🇬🇪 Georgian 51 | * 🇩🇪 German 52 | * 🇪🇸 Spanish 53 | * 🇸🇪 Swedish 54 | 55 | You can add more locales to the `Localizable.xcstrings` file in the `Resources` folder. 56 | 57 | 58 | 59 | ## Repository 60 | 61 | For more information, source code, etc., visit the [project repository][Repository]. 62 | 63 | 64 | 65 | ## License 66 | 67 | StandardButtons is available under the MIT license. 68 | 69 | 70 | 71 | ## Topics 72 | 73 | ### Essentials 74 | 75 | - ``StandardButtonType`` 76 | 77 | 78 | 79 | [Repository]: https://github.com/danielsaidi/StandardButtons 80 | 81 | [Email]: mailto:daniel.saidi@gmail.com 82 | [Website]: https://danielsaidi.com 83 | [GitHub]: https://github.com/danielsaidi 84 | [OpenSource]: https://danielsaidi.com/opensource 85 | [Sponsors]: https://github.com/sponsors/danielsaidi 86 | -------------------------------------------------------------------------------- /Tests/StandardButtonsTests/StandardButtonsTests.swift: -------------------------------------------------------------------------------- 1 | import Testing 2 | @testable import StandardButtons 3 | 4 | func assertImage( 5 | for type: StandardButtonType, 6 | _ expectedName: String 7 | ) throws { 8 | #expect(type.imageName == expectedName) 9 | } 10 | 11 | @Test func standardButtonTypeDefinesCorrectNumberOfTypes() async throws { 12 | #expect(StandardButtonType.allCases.count == 110) 13 | } 14 | 15 | @Test func standardButtonTypeDefinesImage() async throws { 16 | try assertImage(for: .add, "plus") 17 | try assertImage(for: .removeLike, "heart.fill") 18 | try assertImage(for: .save, "checkmark") 19 | try assertImage(for: .search, "magnifyingglass") 20 | try assertImage(for: .select, "checkmark.circle") 21 | try assertImage(for: .share, "square.and.arrow.up") 22 | } 23 | -------------------------------------------------------------------------------- /package_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script creates a new project version for the current project. 5 | # You can customize this to fit your project when you copy these scripts. 6 | # You can pass in a custom branch if you don't want to use the default one. 7 | 8 | SCRIPT="scripts/package_version.sh" 9 | chmod +x $SCRIPT 10 | bash $SCRIPT 11 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script builds a for all provided . 5 | # This script targets iOS, macOS, tvOS, watchOS, and xrOS by default. 6 | # You can pass in a list of if you want to customize the build. 7 | 8 | # Usage: 9 | # build.sh [ default:iOS macOS tvOS watchOS xrOS] 10 | # e.g. `bash scripts/build.sh MyTarget iOS macOS` 11 | 12 | # Exit immediately if a command exits with a non-zero status 13 | set -e 14 | 15 | # Verify that all required arguments are provided 16 | if [ $# -eq 0 ]; then 17 | echo "Error: This script requires at least one argument" 18 | echo "Usage: $0 [ default:iOS macOS tvOS watchOS xrOS]" 19 | echo "For instance: $0 MyTarget iOS macOS" 20 | exit 1 21 | fi 22 | 23 | # Define argument variables 24 | TARGET=$1 25 | 26 | # Remove TARGET from arguments list 27 | shift 28 | 29 | # Define platforms variable 30 | if [ $# -eq 0 ]; then 31 | set -- iOS macOS tvOS watchOS xrOS 32 | fi 33 | PLATFORMS=$@ 34 | 35 | # A function that builds $TARGET for a specific platform 36 | build_platform() { 37 | 38 | # Define a local $PLATFORM variable 39 | local PLATFORM=$1 40 | 41 | # Build $TARGET for the $PLATFORM 42 | echo "Building $TARGET for $PLATFORM..." 43 | if ! xcodebuild -scheme $TARGET -derivedDataPath .build -destination generic/platform=$PLATFORM; then 44 | echo "Failed to build $TARGET for $PLATFORM" 45 | return 1 46 | fi 47 | 48 | # Complete successfully 49 | echo "Successfully built $TARGET for $PLATFORM" 50 | } 51 | 52 | # Start script 53 | echo "" 54 | echo "Building $TARGET for [$PLATFORMS]..." 55 | echo "" 56 | 57 | # Loop through all platforms and call the build function 58 | for PLATFORM in $PLATFORMS; do 59 | if ! build_platform "$PLATFORM"; then 60 | exit 1 61 | fi 62 | done 63 | 64 | # Complete successfully 65 | echo "" 66 | echo "Building $TARGET completed successfully!" 67 | echo "" 68 | -------------------------------------------------------------------------------- /scripts/chmod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script makes all scripts in this folder executable. 5 | 6 | # Usage: 7 | # scripts_chmod.sh 8 | # e.g. `bash scripts/chmod.sh` 9 | 10 | # Exit immediately if a command exits with a non-zero status 11 | set -e 12 | 13 | # Use the script folder to refer to other scripts. 14 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 15 | 16 | # Find all .sh files in the FOLDER except chmod.sh 17 | find "$FOLDER" -name "*.sh" ! -name "chmod.sh" -type f | while read -r script; do 18 | chmod +x "$script" 19 | done 20 | -------------------------------------------------------------------------------- /scripts/docc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script builds DocC for a and certain . 5 | # This script targets iOS, macOS, tvOS, watchOS, and xrOS by default. 6 | # You can pass in a list of if you want to customize the build. 7 | # The documentation ends up in to .build/docs-. 8 | 9 | # Usage: 10 | # docc.sh [ default:iOS macOS tvOS watchOS xrOS] 11 | # e.g. `bash scripts/docc.sh MyTarget iOS macOS` 12 | 13 | # Exit immediately if a command exits with a non-zero status 14 | set -e 15 | 16 | # Fail if any command in a pipeline fails 17 | set -o pipefail 18 | 19 | # Verify that all required arguments are provided 20 | if [ $# -eq 0 ]; then 21 | echo "Error: This script requires at least one argument" 22 | echo "Usage: $0 [ default:iOS macOS tvOS watchOS xrOS]" 23 | echo "For instance: $0 MyTarget iOS macOS" 24 | exit 1 25 | fi 26 | 27 | # Define argument variables 28 | TARGET=$1 29 | TARGET_LOWERCASED=$(echo "$1" | tr '[:upper:]' '[:lower:]') 30 | 31 | # Remove TARGET from arguments list 32 | shift 33 | 34 | # Define platforms variable 35 | if [ $# -eq 0 ]; then 36 | set -- iOS macOS tvOS watchOS xrOS 37 | fi 38 | PLATFORMS=$@ 39 | 40 | # Prepare the package for DocC 41 | swift package resolve; 42 | 43 | # A function that builds $TARGET for a specific platform 44 | build_platform() { 45 | 46 | # Define a local $PLATFORM variable and set an exit code 47 | local PLATFORM=$1 48 | local EXIT_CODE=0 49 | 50 | # Define the build folder name, based on the $PLATFORM 51 | case $PLATFORM in 52 | "iOS") 53 | DEBUG_PATH="Debug-iphoneos" 54 | ;; 55 | "macOS") 56 | DEBUG_PATH="Debug" 57 | ;; 58 | "tvOS") 59 | DEBUG_PATH="Debug-appletvos" 60 | ;; 61 | "watchOS") 62 | DEBUG_PATH="Debug-watchos" 63 | ;; 64 | "xrOS") 65 | DEBUG_PATH="Debug-xros" 66 | ;; 67 | *) 68 | echo "Error: Unsupported platform '$PLATFORM'" 69 | exit 1 70 | ;; 71 | esac 72 | 73 | # Build $TARGET docs for the $PLATFORM 74 | echo "Building $TARGET docs for $PLATFORM..." 75 | if ! xcodebuild docbuild -scheme $TARGET -derivedDataPath .build/docbuild -destination "generic/platform=$PLATFORM"; then 76 | echo "Error: Failed to build documentation for $PLATFORM" >&2 77 | return 1 78 | fi 79 | 80 | # Transform docs for static hosting 81 | if ! $(xcrun --find docc) process-archive \ 82 | transform-for-static-hosting .build/docbuild/Build/Products/$DEBUG_PATH/$TARGET.doccarchive \ 83 | --output-path .build/docs-$PLATFORM \ 84 | --hosting-base-path "$TARGET"; then 85 | echo "Error: Failed to transform documentation for $PLATFORM" >&2 86 | return 1 87 | fi 88 | 89 | # Inject a root redirect script on the root page 90 | echo "" > .build/docs-$PLATFORM/index.html; 91 | 92 | # Complete successfully 93 | echo "Successfully built $TARGET docs for $PLATFORM" 94 | return 0 95 | } 96 | 97 | # Start script 98 | echo "" 99 | echo "Building $TARGET docs for [$PLATFORMS]..." 100 | echo "" 101 | 102 | # Loop through all platforms and call the build function 103 | for PLATFORM in $PLATFORMS; do 104 | if ! build_platform "$PLATFORM"; then 105 | exit 1 106 | fi 107 | done 108 | 109 | # Complete successfully 110 | echo "" 111 | echo "Building $TARGET docs completed successfully!" 112 | echo "" 113 | -------------------------------------------------------------------------------- /scripts/framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script builds DocC for a and certain . 5 | # This script targets iOS, macOS, tvOS, watchOS, and xrOS by default. 6 | # You can pass in a list of if you want to customize the build. 7 | 8 | # Important: 9 | # This script doesn't work on packages, only on .xcproj projects that generate a framework. 10 | 11 | # Usage: 12 | # framework.sh [ default:iOS macOS tvOS watchOS xrOS] 13 | # e.g. `bash scripts/framework.sh MyTarget iOS macOS` 14 | 15 | # Exit immediately if a command exits with a non-zero status 16 | set -e 17 | 18 | # Verify that all required arguments are provided 19 | if [ $# -eq 0 ]; then 20 | echo "Error: This script requires exactly one argument" 21 | echo "Usage: $0 " 22 | exit 1 23 | fi 24 | 25 | # Define argument variables 26 | TARGET=$1 27 | 28 | # Remove TARGET from arguments list 29 | shift 30 | 31 | # Define platforms variable 32 | if [ $# -eq 0 ]; then 33 | set -- iOS macOS tvOS watchOS xrOS 34 | fi 35 | PLATFORMS=$@ 36 | 37 | # Define local variables 38 | BUILD_FOLDER=.build 39 | BUILD_FOLDER_ARCHIVES=.build/framework_archives 40 | BUILD_FILE=$BUILD_FOLDER/$TARGET.xcframework 41 | BUILD_ZIP=$BUILD_FOLDER/$TARGET.zip 42 | 43 | # Start script 44 | echo "" 45 | echo "Building $TARGET XCFramework for [$PLATFORMS]..." 46 | echo "" 47 | 48 | # Delete old builds 49 | echo "Cleaning old builds..." 50 | rm -rf $BUILD_ZIP 51 | rm -rf $BUILD_FILE 52 | rm -rf $BUILD_FOLDER_ARCHIVES 53 | 54 | 55 | # Generate XCArchive files for all platforms 56 | echo "Generating XCArchives..." 57 | 58 | # Initialize the xcframework command 59 | XCFRAMEWORK_CMD="xcodebuild -create-xcframework" 60 | 61 | # Build iOS archives and append to the xcframework command 62 | if [[ " ${PLATFORMS[@]} " =~ " iOS " ]]; then 63 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=iOS" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-iOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 64 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=iOS Simulator" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-iOS-Sim SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 65 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-iOS.xcarchive/Products/Library/Frameworks/$TARGET.framework" 66 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-iOS-Sim.xcarchive/Products/Library/Frameworks/$TARGET.framework" 67 | fi 68 | 69 | # Build iOS archive and append to the xcframework command 70 | if [[ " ${PLATFORMS[@]} " =~ " macOS " ]]; then 71 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=macOS" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-macOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 72 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-macOS.xcarchive/Products/Library/Frameworks/$TARGET.framework" 73 | fi 74 | 75 | # Build tvOS archives and append to the xcframework command 76 | if [[ " ${PLATFORMS[@]} " =~ " tvOS " ]]; then 77 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=tvOS" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-tvOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 78 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=tvOS Simulator" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-tvOS-Sim SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 79 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-tvOS.xcarchive/Products/Library/Frameworks/$TARGET.framework" 80 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-tvOS-Sim.xcarchive/Products/Library/Frameworks/$TARGET.framework" 81 | fi 82 | 83 | # Build watchOS archives and append to the xcframework command 84 | if [[ " ${PLATFORMS[@]} " =~ " watchOS " ]]; then 85 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=watchOS" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-watchOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 86 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=watchOS Simulator" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-watchOS-Sim SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 87 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-watchOS.xcarchive/Products/Library/Frameworks/$TARGET.framework" 88 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-watchOS-Sim.xcarchive/Products/Library/Frameworks/$TARGET.framework" 89 | fi 90 | 91 | # Build xrOS archives and append to the xcframework command 92 | if [[ " ${PLATFORMS[@]} " =~ " xrOS " ]]; then 93 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=xrOS" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-xrOS SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 94 | xcodebuild archive -scheme $TARGET -configuration Release -destination "generic/platform=xrOS Simulator" -archivePath $BUILD_FOLDER_ARCHIVES/$TARGET-xrOS-Sim SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES 95 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-xrOS.xcarchive/Products/Library/Frameworks/$TARGET.framework" 96 | XCFRAMEWORK_CMD+=" -framework $BUILD_FOLDER_ARCHIVES/$TARGET-xrOS-Sim.xcarchive/Products/Library/Frameworks/$TARGET.framework" 97 | fi 98 | 99 | # Genererate XCFramework 100 | echo "Generating XCFramework..." 101 | XCFRAMEWORK_CMD+=" -output $BUILD_FILE" 102 | eval "$XCFRAMEWORK_CMD" 103 | 104 | # Genererate iOS XCFramework zip 105 | echo "Generating XCFramework zip..." 106 | zip -r $BUILD_ZIP $BUILD_FILE 107 | echo "" 108 | echo "***** CHECKSUM *****" 109 | swift package compute-checksum $BUILD_ZIP 110 | echo "********************" 111 | echo "" 112 | 113 | # Complete successfully 114 | echo "" 115 | echo "$TARGET XCFramework created successfully!" 116 | echo "" 117 | -------------------------------------------------------------------------------- /scripts/git_default_branch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script echos the default git branch name. 5 | 6 | # Usage: 7 | # git_default_branch.sh 8 | # e.g. `bash scripts/git_default_branch.sh` 9 | 10 | BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') 11 | echo $BRANCH 12 | -------------------------------------------------------------------------------- /scripts/package_docc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script builds DocC documentation for `Package.swift`. 5 | # This script targets iOS by default, but you can pass in custom . 6 | 7 | # Usage: 8 | # package_docc.sh [ default:iOS] 9 | # e.g. `bash scripts/package_docc.sh iOS macOS` 10 | 11 | # Exit immediately if a command exits with non-zero status 12 | set -e 13 | 14 | # Use the script folder to refer to other scripts. 15 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 16 | SCRIPT_PACKAGE_NAME="$FOLDER/package_name.sh" 17 | SCRIPT_DOCC="$FOLDER/docc.sh" 18 | 19 | # Define platforms variable 20 | if [ $# -eq 0 ]; then 21 | set -- iOS 22 | fi 23 | PLATFORMS=$@ 24 | 25 | # Get package name 26 | PACKAGE_NAME=$("$SCRIPT_PACKAGE_NAME") || { echo "Failed to get package name"; exit 1; } 27 | 28 | # Build package documentation 29 | bash $SCRIPT_DOCC $PACKAGE_NAME $PLATFORMS || { echo "DocC script failed"; exit 1; } 30 | -------------------------------------------------------------------------------- /scripts/package_framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script generates an XCFramework for `Package.swift`. 5 | # This script targets iOS by default, but you can pass in custom . 6 | 7 | # Usage: 8 | # package_framework.sh [ default:iOS] 9 | # e.g. `bash scripts/package_framework.sh iOS macOS` 10 | 11 | # Exit immediately if a command exits with non-zero status 12 | set -e 13 | 14 | # Use the script folder to refer to other scripts. 15 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 16 | SCRIPT_PACKAGE_NAME="$FOLDER/package_name.sh" 17 | SCRIPT_FRAMEWORK="$FOLDER/framework.sh" 18 | 19 | # Define platforms variable 20 | if [ $# -eq 0 ]; then 21 | set -- iOS 22 | fi 23 | PLATFORMS=$@ 24 | 25 | # Get package name 26 | PACKAGE_NAME=$("$SCRIPT_PACKAGE_NAME") || { echo "Failed to get package name"; exit 1; } 27 | 28 | # Build package framework 29 | bash $SCRIPT_FRAMEWORK $PACKAGE_NAME $PLATFORMS 30 | -------------------------------------------------------------------------------- /scripts/package_name.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script finds the main target name in `Package.swift`. 5 | 6 | # Usage: 7 | # package_name.sh 8 | # e.g. `bash scripts/package_name.sh` 9 | 10 | # Exit immediately if a command exits with non-zero status 11 | set -e 12 | 13 | # Check that a Package.swift file exists 14 | if [ ! -f "Package.swift" ]; then 15 | echo "Error: Package.swift not found in current directory" 16 | exit 1 17 | fi 18 | 19 | # Using grep and sed to extract the package name 20 | # 1. grep finds the line containing "name:" 21 | # 2. sed extracts the text between quotes 22 | package_name=$(grep -m 1 'name:.*"' Package.swift | sed -n 's/.*name:[[:space:]]*"\([^"]*\)".*/\1/p') 23 | 24 | if [ -z "$package_name" ]; then 25 | echo "Error: Could not find package name in Package.swift" 26 | exit 1 27 | else 28 | echo "$package_name" 29 | fi 30 | -------------------------------------------------------------------------------- /scripts/package_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script creates a new version for `Package.swift`. 5 | # You can pass in a to validate any non-main branch. 6 | 7 | # Usage: 8 | # package_version.sh 9 | # e.g. `bash scripts/package_version.sh master` 10 | 11 | # Exit immediately if a command exits with non-zero status 12 | set -e 13 | 14 | # Use the script folder to refer to other scripts. 15 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 16 | SCRIPT_BRANCH_NAME="$FOLDER/git_default_branch.sh" 17 | SCRIPT_PACKAGE_NAME="$FOLDER/package_name.sh" 18 | SCRIPT_VERSION="$FOLDER/version.sh" 19 | 20 | # Get branch name 21 | DEFAULT_BRANCH=$("$SCRIPT_BRANCH_NAME") || { echo "Failed to get branch name"; exit 1; } 22 | BRANCH_NAME=${1:-$DEFAULT_BRANCH} 23 | 24 | # Get package name 25 | PACKAGE_NAME=$("$SCRIPT_PACKAGE_NAME") || { echo "Failed to get package name"; exit 1; } 26 | 27 | # Build package version 28 | bash $SCRIPT_VERSION $PACKAGE_NAME $BRANCH_NAME 29 | -------------------------------------------------------------------------------- /scripts/sync_from.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script syncs Swift Package Scripts from a . 5 | # This script will overwrite the existing "scripts" folder. 6 | # Only pass in the full path to a Swift Package Scripts root. 7 | 8 | # Usage: 9 | # package_name.sh 10 | # e.g. `bash sync_from.sh ../SwiftPackageScripts` 11 | 12 | # Define argument variables 13 | SOURCE=$1 14 | 15 | # Define variables 16 | FOLDER="scripts/" 17 | SOURCE_FOLDER="$SOURCE/$FOLDER" 18 | 19 | # Start script 20 | echo "" 21 | echo "Syncing scripts from $SOURCE_FOLDER..." 22 | echo "" 23 | 24 | # Remove existing folder 25 | rm -rf $FOLDER 26 | 27 | # Copy folder 28 | cp -r "$SOURCE_FOLDER/" "$FOLDER/" 29 | 30 | # Complete successfully 31 | echo "" 32 | echo "Script syncing from $SOURCE_FOLDER completed successfully!" 33 | echo "" 34 | -------------------------------------------------------------------------------- /scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script tests a for all provided . 5 | 6 | # Usage: 7 | # test.sh [ default:iOS macOS tvOS watchOS xrOS] 8 | # e.g. `bash scripts/test.sh MyTarget iOS macOS` 9 | 10 | # Exit immediately if a command exits with a non-zero status 11 | set -e 12 | 13 | # Verify that all required arguments are provided 14 | if [ $# -eq 0 ]; then 15 | echo "Error: This script requires at least one argument" 16 | echo "Usage: $0 [ default:iOS macOS tvOS watchOS xrOS]" 17 | echo "For instance: $0 MyTarget iOS macOS" 18 | exit 1 19 | fi 20 | 21 | # Define argument variables 22 | TARGET=$1 23 | 24 | # Remove TARGET from arguments list 25 | shift 26 | 27 | # Define platforms variable 28 | if [ $# -eq 0 ]; then 29 | set -- iOS macOS tvOS watchOS xrOS 30 | fi 31 | PLATFORMS=$@ 32 | 33 | # Start script 34 | echo "" 35 | echo "Testing $TARGET for [$PLATFORMS]..." 36 | echo "" 37 | 38 | # A function that gets the latest simulator for a certain OS. 39 | get_latest_simulator() { 40 | local PLATFORM=$1 41 | local SIMULATOR_TYPE 42 | 43 | case $PLATFORM in 44 | "iOS") 45 | SIMULATOR_TYPE="iPhone" 46 | ;; 47 | "tvOS") 48 | SIMULATOR_TYPE="Apple TV" 49 | ;; 50 | "watchOS") 51 | SIMULATOR_TYPE="Apple Watch" 52 | ;; 53 | "xrOS") 54 | SIMULATOR_TYPE="Apple Vision" 55 | ;; 56 | *) 57 | echo "Error: Unsupported platform for simulator '$PLATFORM'" 58 | return 1 59 | ;; 60 | esac 61 | 62 | # Get the latest simulator for the platform 63 | xcrun simctl list devices available | grep "$SIMULATOR_TYPE" | tail -1 | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/' 64 | } 65 | 66 | # A function that tests $TARGET for a specific platform 67 | test_platform() { 68 | 69 | # Define a local $PLATFORM variable 70 | local PLATFORM="${1//_/ }" 71 | 72 | # Define the destination, based on the $PLATFORM 73 | case $PLATFORM in 74 | "iOS"|"tvOS"|"watchOS"|"xrOS") 75 | local SIMULATOR_UDID=$(get_latest_simulator "$PLATFORM") 76 | if [ -z "$SIMULATOR_UDID" ]; then 77 | echo "Error: No simulator found for $PLATFORM" 78 | return 1 79 | fi 80 | DESTINATION="id=$SIMULATOR_UDID" 81 | ;; 82 | "macOS") 83 | DESTINATION="platform=macOS" 84 | ;; 85 | *) 86 | echo "Error: Unsupported platform '$PLATFORM'" 87 | return 1 88 | ;; 89 | esac 90 | 91 | # Test $TARGET for the $DESTINATION 92 | echo "Testing $TARGET for $PLATFORM..." 93 | xcodebuild test -scheme $TARGET -derivedDataPath .build -destination "$DESTINATION" -enableCodeCoverage YES 94 | local TEST_RESULT=$? 95 | 96 | if [[ $TEST_RESULT -ne 0 ]]; then 97 | return $TEST_RESULT 98 | fi 99 | 100 | # Complete successfully 101 | echo "Successfully tested $TARGET for $PLATFORM" 102 | return 0 103 | } 104 | 105 | # Loop through all platforms and call the test function 106 | for PLATFORM in $PLATFORMS; do 107 | if ! test_platform "$PLATFORM"; then 108 | exit 1 109 | fi 110 | done 111 | 112 | # Complete successfully 113 | echo "" 114 | echo "Testing $TARGET completed successfully!" 115 | echo "" 116 | -------------------------------------------------------------------------------- /scripts/version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script creates a new version for the provided and . 5 | # This script targets iOS, macOS, tvOS, watchOS, and xrOS by default. 6 | # You can pass in a list of if you want to customize the build. 7 | 8 | # Usage: 9 | # version.sh [ default:iOS macOS tvOS watchOS xrOS]" 10 | # e.g. `scripts/version.sh MyTarget master iOS macOS` 11 | 12 | # This script will: 13 | # * Call version_validate_git.sh to validate the git repo. 14 | # * Call version_validate_target to run tests, swiftlint, etc. 15 | # * Call version_bump.sh if all validation steps above passed. 16 | 17 | # Exit immediately if a command exits with a non-zero status 18 | set -e 19 | 20 | # Verify that all required arguments are provided 21 | if [ $# -lt 2 ]; then 22 | echo "Error: This script requires at least two arguments" 23 | echo "Usage: $0 [ default:iOS macOS tvOS watchOS xrOS]" 24 | echo "For instance: $0 MyTarget master iOS macOS" 25 | exit 1 26 | fi 27 | 28 | # Define argument variables 29 | TARGET=$1 30 | BRANCH=${2:-main} 31 | 32 | # Remove TARGET and BRANCH from arguments list 33 | shift 34 | shift 35 | 36 | # Read platform arguments or use default value 37 | if [ $# -eq 0 ]; then 38 | set -- iOS macOS tvOS watchOS xrOS 39 | fi 40 | 41 | # Use the script folder to refer to other scripts. 42 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 43 | SCRIPT_VALIDATE_GIT="$FOLDER/version_validate_git.sh" 44 | SCRIPT_VALIDATE_TARGET="$FOLDER/version_validate_target.sh" 45 | SCRIPT_VERSION_BUMP="$FOLDER/version_bump.sh" 46 | 47 | # A function that run a certain script and checks for errors 48 | run_script() { 49 | local script="$1" 50 | shift # Remove the first argument (the script path) 51 | 52 | if [ ! -f "$script" ]; then 53 | echo "Error: Script not found: $script" 54 | exit 1 55 | fi 56 | 57 | chmod +x "$script" 58 | if ! "$script" "$@"; then 59 | echo "Error: Script $script failed" 60 | exit 1 61 | fi 62 | } 63 | 64 | # Start script 65 | echo "" 66 | echo "Creating a new version for $TARGET on the $BRANCH branch..." 67 | echo "" 68 | 69 | # Validate git and project 70 | echo "Validating..." 71 | run_script "$SCRIPT_VALIDATE_GIT" "$BRANCH" 72 | run_script "$SCRIPT_VALIDATE_TARGET" "$TARGET" 73 | 74 | # Bump version 75 | echo "Bumping version..." 76 | run_script "$SCRIPT_VERSION_BUMP" 77 | 78 | # Complete successfully 79 | echo "" 80 | echo "Version created successfully!" 81 | echo "" 82 | -------------------------------------------------------------------------------- /scripts/version_bump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script bumps the project version number. 5 | # You can append --no-semver to disable semantic version validation. 6 | 7 | # Usage: 8 | # version_bump.sh [--no-semver] 9 | # e.g. `bash scripts/version_bump.sh` 10 | # e.g. `bash scripts/version_bump.sh --no-semver` 11 | 12 | # Exit immediately if a command exits with a non-zero status 13 | set -e 14 | 15 | # Use the script folder to refer to other scripts. 16 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 17 | SCRIPT_VERSION_NUMBER="$FOLDER/version_number.sh" 18 | 19 | 20 | # Parse --no-semver argument 21 | VALIDATE_SEMVER=true 22 | for arg in "$@"; do 23 | case $arg in 24 | --no-semver) 25 | VALIDATE_SEMVER=false 26 | shift # Remove --no-semver from processing 27 | ;; 28 | esac 29 | done 30 | 31 | # Start script 32 | echo "" 33 | echo "Bumping version number..." 34 | echo "" 35 | 36 | # Get the latest version 37 | VERSION=$($SCRIPT_VERSION_NUMBER) 38 | if [ $? -ne 0 ]; then 39 | echo "Failed to get the latest version" 40 | exit 1 41 | fi 42 | 43 | # Print the current version 44 | echo "The current version is: $VERSION" 45 | 46 | # Function to validate semver format, including optional -rc. suffix 47 | validate_semver() { 48 | if [ "$VALIDATE_SEMVER" = false ]; then 49 | return 0 50 | fi 51 | 52 | if [[ $1 =~ ^v?[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then 53 | return 0 54 | else 55 | return 1 56 | fi 57 | } 58 | 59 | # Prompt user for new version 60 | while true; do 61 | read -p "Enter the new version number: " NEW_VERSION 62 | 63 | # Validate the version number to ensure that it's a semver version 64 | if validate_semver "$NEW_VERSION"; then 65 | break 66 | else 67 | echo "Invalid version format. Please use semver format (e.g., 1.2.3, v1.2.3, 1.2.3-rc.1, etc.)." 68 | exit 1 69 | fi 70 | done 71 | 72 | # Push the new tag 73 | git push -u origin HEAD 74 | git tag $NEW_VERSION 75 | git push --tags 76 | 77 | # Complete successfully 78 | echo "" 79 | echo "Version tag pushed successfully!" 80 | echo "" 81 | -------------------------------------------------------------------------------- /scripts/version_number.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script returns the latest project version. 5 | 6 | # Usage: 7 | # version_number.sh 8 | # e.g. `bash scripts/version_number.sh` 9 | 10 | # Exit immediately if a command exits with a non-zero status 11 | set -e 12 | 13 | # Check if the current directory is a Git repository 14 | if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then 15 | echo "Error: Not a Git repository" 16 | exit 1 17 | fi 18 | 19 | # Fetch all tags 20 | git fetch --tags > /dev/null 2>&1 21 | 22 | # Get the latest semver tag 23 | latest_version=$(git tag -l --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1) 24 | 25 | # Check if we found a version tag 26 | if [ -z "$latest_version" ]; then 27 | echo "Error: No semver tags found in this repository" >&2 28 | exit 1 29 | fi 30 | 31 | # Print the latest version 32 | echo "$latest_version" 33 | -------------------------------------------------------------------------------- /scripts/version_validate_git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script validates the Git repository for release. 5 | # You can pass in a to validate any non-main branch. 6 | 7 | # Usage: 8 | # version_validate_git.sh " 9 | # e.g. `bash scripts/version_validate_git.sh master` 10 | 11 | # This script will: 12 | # * Validate that the script is run within a git repository. 13 | # * Validate that the git repository doesn't have any uncommitted changes. 14 | # * Validate that the current git branch matches the provided one. 15 | 16 | # Exit immediately if a command exits with a non-zero status 17 | set -e 18 | 19 | # Verify that all required arguments are provided 20 | if [ $# -eq 0 ]; then 21 | echo "Error: This script requires exactly one argument" 22 | echo "Usage: $0 " 23 | exit 1 24 | fi 25 | 26 | # Create local argument variables. 27 | BRANCH=$1 28 | 29 | # Start script 30 | echo "" 31 | echo "Validating git repository..." 32 | echo "" 33 | 34 | # Check if the current directory is a Git repository 35 | if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then 36 | echo "Error: Not a Git repository" 37 | exit 1 38 | fi 39 | 40 | # Check for uncommitted changes 41 | if [ -n "$(git status --porcelain)" ]; then 42 | echo "Error: Git repository is dirty. There are uncommitted changes." 43 | exit 1 44 | fi 45 | 46 | # Verify that we're on the correct branch 47 | current_branch=$(git rev-parse --abbrev-ref HEAD) 48 | if [ "$current_branch" != "$BRANCH" ]; then 49 | echo "Error: Not on the specified branch. Current branch is $current_branch, expected $1." 50 | exit 1 51 | fi 52 | 53 | # The Git repository validation succeeded. 54 | echo "" 55 | echo "Git repository validated successfully!" 56 | echo "" 57 | -------------------------------------------------------------------------------- /scripts/version_validate_target.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Documentation: 4 | # This script validates a for release. 5 | # This script targets iOS, macOS, tvOS, watchOS, and xrOS by default. 6 | # You can pass in a list of if you want to customize the build. 7 | 8 | # Usage: 9 | # version_validate_target.sh [ default:iOS macOS tvOS watchOS xrOS]" 10 | # e.g. `bash scripts/version_validate_target.sh iOS macOS` 11 | 12 | # This script will: 13 | # * Validate that swiftlint passes. 14 | # * Validate that all unit tests passes for all . 15 | 16 | # Exit immediately if a command exits with a non-zero status 17 | set -e 18 | 19 | # Verify that all requires at least one argument" 20 | if [ $# -eq 0 ]; then 21 | echo "Error: This script requires at least one argument" 22 | echo "Usage: $0 [ default:iOS macOS tvOS watchOS xrOS]" 23 | exit 1 24 | fi 25 | 26 | # Create local argument variables. 27 | TARGET=$1 28 | 29 | # Remove TARGET from arguments list 30 | shift 31 | 32 | # Define platforms variable 33 | if [ $# -eq 0 ]; then 34 | set -- iOS macOS tvOS watchOS xrOS 35 | fi 36 | PLATFORMS=$@ 37 | 38 | # Use the script folder to refer to other scripts. 39 | FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 40 | SCRIPT_TEST="$FOLDER/test.sh" 41 | 42 | # A function that run a certain script and checks for errors 43 | run_script() { 44 | local script="$1" 45 | shift # Remove the first argument (script path) from the argument list 46 | 47 | if [ ! -f "$script" ]; then 48 | echo "Error: Script not found: $script" 49 | exit 1 50 | fi 51 | 52 | chmod +x "$script" 53 | if ! "$script" "$@"; then 54 | echo "Error: Script $script failed" 55 | exit 1 56 | fi 57 | } 58 | 59 | # Start script 60 | echo "" 61 | echo "Validating project..." 62 | echo "" 63 | 64 | # Run SwiftLint 65 | echo "Running SwiftLint" 66 | if ! swiftlint --strict; then 67 | echo "Error: SwiftLint failed" 68 | exit 1 69 | fi 70 | 71 | # Run unit tests 72 | echo "Testing..." 73 | run_script "$SCRIPT_TEST" "$TARGET" "$PLATFORMS" 74 | 75 | # Complete successfully 76 | echo "" 77 | echo "Project successfully validated!" 78 | echo "" 79 | --------------------------------------------------------------------------------