[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\njobs:\n  build:\n    environment:\n      LC_ALL: C.UTF-8\n      LANG: C.UTF-8\n    docker:\n      - image: cimg/base:2023.09\n    steps:\n      - checkout\n      - run:\n          name: Install Dependencies\n          command: |\n            sudo apt-get update\n            sudo apt-get -y install locales make\n            sudo apt-get -y install util-linux bsdmainutils gawk curl rlwrap emacs\n      - run:\n          name: Sanity Check\n          command: |\n            make test\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches:\n    - develop\n    - stable\n  pull_request:\n    branches:\n    - develop\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Install dependencies\n      run: |\n        sudo apt-get update\n        sudo apt-get -y install gawk curl rlwrap emacs\n    - name: Sanity check\n      run: |\n        make test\n"
  },
  {
    "path": ".gitignore",
    "content": "/_*\n/build\n/gh-pages\n/registry\n/wiki\n*.emacs*\n*.html\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"translate-shell.wiki\"]\n\tpath = wiki\n\turl = https://github.com/soimort/translate-shell.wiki.git\n"
  },
  {
    "path": ".travis.yml",
    "content": "os:\n  - linux\n  - osx\n\nbefore_install: |\n  if [[ \"$TRAVIS_OS_NAME\" == \"linux\" ]]; then sudo add-apt-repository ppa:schot/gawk -y; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"linux\" ]]; then sudo apt-get update -q; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"linux\" ]]; then sudo apt-get install gawk; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"linux\" ]]; then sudo apt-get install rlwrap; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"linux\" ]]; then sudo apt-get install emacs; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"osx\" ]]; then brew update; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"osx\" ]]; then brew install gawk; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"osx\" ]]; then brew install rlwrap; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"osx\" ]]; then brew install emacs; fi\n  if [[ \"$TRAVIS_OS_NAME\" == \"osx\" ]]; then brew install bash; fi\n\nscript: make check\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## How to Report an Issue\n\n1. For bugs and suggestions, please always **[report your issue on GitHub](https://github.com/soimort/translate-shell/issues)**.\n\n2. For bugs, make sure you can reproduce on **the latest stable version** before reporting.\n\n3. In your bug report, please include details such as:\n   * The exact command you entered, expected output and actual output\n   * The output of `trans -V` on your system\n\n## How to Send a Pull Request\n\n### Waiving Copyrights\n\nThis is a public domain software, which means the author(s) do not retain any copyright interest in this repository. By submitting a pull request, you (as a contributor) must agree that your code is also put into the public domain, as this software is.\n\n### Following the Coding Style\n\nPlease review the **[AWK style guide](https://github.com/soimort/translate-shell/wiki/AWK-Style-Guide)**.\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM alpine:latest\nMAINTAINER soimort\n\nRUN echo \"http://dl-cdn.alpinelinux.org/alpine/edge/testing\" >> /etc/apk/repositories \n\nRUN apk add bash gawk curl mplayer fribidi less hunspell wget \\\n    && wget git.io/trans \\\n    && chmod +x ./trans \\ \n    && mv ./trans /usr/local/bin/\nENTRYPOINT [\"trans\"]\nCMD [\"--help\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, compile, sell, or\ndistribute this software, either in source code form or as a compiled\nbinary, for any purpose, commercial or non-commercial, and by any\nmeans.\n\nIn jurisdictions that recognize copyright laws, the author or authors\nof this software dedicate any and all copyright interest in the\nsoftware to the public domain. We make this dedication for the benefit\nof the public at large and to the detriment of our heirs and\nsuccessors. We intend this dedication to be an overt act of\nrelinquishment in perpetuity of all present and future rights to this\nsoftware under copyright law.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\nFor more information, please refer to <http://unlicense.org/>\n"
  },
  {
    "path": "Makefile",
    "content": "NAME     = \"translate-shell\"\nCOMMAND  = trans\nBUILDDIR ?= build\nMANDIR   = man\n\nTARGET   ?= bash\nPREFIX   ?= /usr/local\n\n.PHONY: default clean build release grip test check install uninstall\n\ndefault: build\n\nclean:\n\t@gawk -f build.awk clean\n\nbuild:\n\t@gawk -f build.awk build -target=$(TARGET)\n\nrelease:\n\t@gawk -f build.awk build -target=$(TARGET) -type=release\n\ngrip:\n\t@gawk -f build.awk readme && grip\n\ntest: build\n\t@gawk -f test.awk\n\ncheck: test\n\t$(BUILDDIR)/$(COMMAND) -V\n\t[ \"`$(BUILDDIR)/$(COMMAND) -no-init -D -b 忍者`\" = 'ninja' ] &&\\\n\t[ \"`$(BUILDDIR)/$(COMMAND) -no-init -D -b -e bing 忍者`\" = 'ninja' ] #&&\\\n\t#[ \"`$(BUILDDIR)/$(COMMAND) -no-init -D -b -e yandex Ninja`\" = 'Ninja' ]\n\ninstall: build\n\t@mkdir -p $(DESTDIR)$(PREFIX)/bin &&\\\n\tinstall $(BUILDDIR)/$(COMMAND) $(DESTDIR)$(PREFIX)/bin/$(COMMAND) &&\\\n\tmkdir -p $(DESTDIR)$(PREFIX)/share/man/man1 &&\\\n\tinstall $(MANDIR)/$(COMMAND).1 $(DESTDIR)$(PREFIX)/share/man/man1/$(COMMAND).1 &&\\\n\techo \"[OK] $(NAME) installed.\"\n\nuninstall:\n\t@rm $(DESTDIR)$(PREFIX)/bin/$(COMMAND) $(DESTDIR)$(PREFIX)/share/man/man1/$(COMMAND).1 &&\\\n\techo \"[OK] $(NAME) uninstalled.\"\n"
  },
  {
    "path": "README.md",
    "content": "# Translate Shell\n\n[![Icon](https://raw.githubusercontent.com/soimort/translate-shell/gh-pages/images/icon.png)](https://www.soimort.org/translate-shell)\n[![CircleCI](https://circleci.com/gh/soimort/translate-shell.svg?style=svg)](https://circleci.com/gh/soimort/translate-shell)\n[![Actions](https://github.com/soimort/translate-shell/workflows/CI/badge.svg)](https://github.com/soimort/translate-shell/actions)\n[![Version](https://raw.githubusercontent.com/soimort/translate-shell/gh-pages/images/badge-release.png)](https://github.com/soimort/translate-shell/releases)\n[![Download](https://raw.githubusercontent.com/soimort/translate-shell/gh-pages/images/badge-download.png)](https://www.soimort.org/translate-shell/trans)\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/soimort/translate-shell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n**[Translate Shell](https://www.soimort.org/translate-shell)** (formerly _Google Translate CLI_) is a command-line translator powered by **[Google Translate](https://translate.google.com/)** (default), **[Bing Translator](https://www.bing.com/translator)**, **[Yandex.Translate](https://translate.yandex.com/)**, and **[Apertium](https://www.apertium.org/)**. It gives you easy access to one of these translation engines in your terminal:\n\n```\n$ trans 'Saluton, Mondo!'\nSaluton, Mondo!\n\nHello, World!\n\nTranslations of Saluton, Mondo!\n[ Esperanto -> English ]\nSaluton ,\n    Hello,\nMondo !\n    World!\n```\n\nBy default, translations with detailed explanations are shown. You can also translate the text briefly: (only the most relevant translation will be shown)\n\n```\n$ trans -brief 'Saluton, Mondo!'\nHello, World!\n```\n\n**Translate Shell** can also be used like an interactive shell; input the text to be translated line by line:\n\n```\n$ trans -shell -brief\n> Rien ne réussit comme le succès.\nNothing succeeds like success.\n> Was mich nicht umbringt, macht mich stärker.\nWhat does not kill me makes me stronger.\n> Юмор есть остроумие глубокого чувства.\nHumor has a deep sense of wit.\n> 學而不思則罔，思而不學則殆。\nLearning without thought is labor lost, thought without learning is perilous.\n> 幸福になるためには、人から愛されるのが一番の近道。\nIn order to be happy, the best way is to be loved by people.\n```\n\n## Prerequisites\n\n### System Requirements\n\n**Translate Shell** is known to work on many POSIX-compliant systems, including but not limited to:\n\n* GNU/Linux\n* macOS\n* *BSD\n* Android (through Termux)\n* Windows (through WSL, Cygwin, or MSYS2)\n\n### Dependencies\n\n* **[GNU Awk](https://www.gnu.org/software/gawk/)** (**gawk**) **4.0 or later**\n    * This program relies heavily on GNU extensions of the [AWK language](http://en.wikipedia.org/wiki/AWK), which are non-portable for other AWK implementations (e.g. nawk).\n    * How to get gawk:\n      * gawk comes with all GNU/Linux distributions.\n      * On FreeBSD, gawk is available in the ports.\n      * On macOS, gawk is available in MacPorts and Homebrew.\n    * Please note that gawk 5.2.0 has a [known bug](https://github.com/soimort/translate-shell/issues/463) -- update to gawk 5.2.1 instead.\n* **[GNU Bash](http://www.gnu.org/software/bash/)** or **[Zsh](http://www.zsh.org/)**\n    * You may use Translate Shell from any Unix shell of your choice (bash, zsh, ksh, tcsh, fish, etc.); however, the wrapper script requires either **bash** or **zsh** installed.\n\n### Recommended Dependencies\n\nThese dependencies are optional, but strongly recommended for full functionality:\n\n* **[curl](http://curl.haxx.se/)** with **OpenSSL** support\n* **[GNU FriBidi](http://fribidi.org/)**: _an implementation of the Unicode Bidirectional Algorithm (bidi)_\n    * required for displaying text in Right-to-Left scripts (e.g. Arabic, Hebrew)\n* **[mplayer](http://www.mplayerhq.hu/)**, **[mpv](http://mpv.io/)**, **[mpg123](http://mpg123.org/)**, or **[eSpeak](http://espeak.sourceforge.net/)**\n    * required for the Text-to-Speech functionality\n* **[less](http://www.greenwoodsoftware.com/less/)**, **[more](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html)** or **[most](http://www.jedsoft.org/most/)**\n    * required for terminal paging\n* **[rlwrap](http://utopia.knoware.nl/~hlub/uck/rlwrap/#rlwrap)**: *a GNU readline wrapper*\n    * required for readline-style editing and history in the interactive shell\n* **[aspell](http://aspell.net/)** or **[hunspell](http://hunspell.github.io/)**\n    * required for spell checking\n\n### Environment and Fonts\n\nIt is a must to have corresponding fonts for the language(s) / script(s) you wish to display in your terminal. See **[wiki: Writing Systems and Fonts](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts#unicode-fonts)** for more details on scripts and recommended Unicode fonts.\n\n## Try It Out!\n\nStart an interactive shell and translate anything you input into your native language: (in **bash** or **zsh**)\n\n    $ gawk -f <(curl -Ls --compressed https://git.io/translate) -- -shell\n\n(in **fish**)\n\n    $ gawk -f (curl -Ls --compressed https://git.io/translate | psub) -- -shell\n\n### Using Docker\n\nTo try out via [Docker](https://www.docker.com/), run:\n\n    $ docker pull soimort/translate-shell\n\nThen you may start an interactive shell from the Docker image for translating:\n\n    $ docker run -it soimort/translate-shell -shell\n\n## Installation\n\n### Option #1. Direct Download\n\nDownload [the self-contained executable](http://git.io/trans) and place it into your path. It's everything you need.\n\n    $ wget git.io/trans\n    $ chmod +x ./trans\n\nThere is a [GPG signature](https://www.soimort.org/translate-shell/trans.sig).\n\n### Option #2. From A Package Manager\n\n#### Using your favorite package manager\n\nSee **[wiki: Distros](https://github.com/soimort/translate-shell/wiki/Distros)** on how to install from a specific package manager on your distro.\n\n#### Using [Antigen](https://github.com/zsh-users/antigen) (for Zsh users)\n\nAdd the following line to your `.zshrc`:\n\n    antigen bundle soimort/translate-shell@develop\n\n### Option #3. From Git\n\n    $ git clone https://github.com/soimort/translate-shell\n    $ cd translate-shell/\n    $ make\n    $ [sudo] make install\n\nIn case you have only zsh but not bash in your system, build with:\n\n    $ make TARGET=zsh\n\nThe default `PREFIX` of installation is `/usr/local`. To install the program to somewhere else (e.g. `/usr`, `~/.local`), use:\n\n    $ [sudo] make PREFIX=/usr install\n\n## Getting Started by Examples\n\n### Translate a Word\n\n#### From any language to your language\n\nGoogle Translate can identify the language of the source text automatically, and Translate Shell by default translates the source text into the language of your `locale`.\n\n    $ trans vorto\n\n#### From any language to one or more specific languages\n\nTranslate a word into French:\n\n    $ trans :fr word\n\nTranslate a word into Chinese and Japanese: (use a plus sign \"`+`\" as the delimiter)\n\n    $ trans :zh+ja word\n\nAlternatively, equals sign (\"`=`\") can be used in place of the colon (\"`:`\"). Note that in some shells (e.g. zsh), equals signs may be interpreted differently, therefore the argument specifying languages needs to be protected:\n\n    $ trans {=zh+ja} word\n    $ trans '=zh+ja' word\n\nYou can also use the `-target` (`-t`) option to specify the target language(s):\n\n    $ trans -t zh+ja word\n\nWith the `-t` option, the name of the language may also be used instead of the language code:\n\n    $ trans -t japanese word\n    $ trans -t 日本語 word\n\n#### From a specific language\n\nGoogle Translate may wrongly identify the source text as some other language than you expected:\n\n    $ trans 手紙\n\nIn that case, you need to specify its language explicitly:\n\n    $ trans ja: 手紙\n    $ trans zh: 手紙\n\nYou can also use the `-source` (`-s`) option to specify the source language:\n\n    $ trans -s ja 手紙\n\n### Translate Multiple Words or a Phrase\n\nTranslate each word alone:\n\n    $ trans en:zh word processor\n\nPut words into one argument, and translate them as a whole:\n\n    $ trans en:zh \"word processor\"\n\n### Translate a Sentence\n\nTranslating a sentence is much the same like translating a phrase; you can just quote the sentence into one argument:\n\n    $ trans :zh \"To-morrow, and to-morrow, and to-morrow,\"\n    $ trans :zh 'To-morrow, and to-morrow, and to-morrow,'\n\nIt is also possible to translate multi-line sentences:\n\n    $ trans :zh \"Creeps in this petty pace from day to day,\n    > To the last syllable of recorded time;\n    > And all our yesterdays have lighted fools\n    > The way to dusty death.\"\n\nTo avoid punctuation marks (e.g. \"`!`\") or other special characters being interpreted by the shell, use *single quotes*:\n\n    $ trans :zh 'Out, out, brief candle!'\n\nThere are some cases though, you may still want to use *double quotes*: (e.g. the sentence contains a single quotation mark \"`'`\")\n\n    $ trans :zh \"Life's but a walking shadow, a poor player\"\n\nAlternatively, use the `-join-sentence` (`-j`) option to treat all arguments as one sentence so that quotes can be omitted:\n\n    $ trans -j :zh Life\\'s but a walking shadow, a poor player\n\n### Brief Mode\n\nBy default, Translate Shell displays translations in a verbose manner. If you prefer to see only the most relevant translation, there is a brief mode available using the `-brief` (`-b`) option:\n\n    $ trans -b :fr \"Saluton, Mondo\"\n\nIn brief mode, phonetic notation (if any) is not shown by default. To enable this, put an at sign \"`@`\" in front of the language code:\n\n    $ trans -b :@ja \"Saluton, Mondo\"\n\n### Dictionary Mode\n\nGoogle Translate can be used as a dictionary. When translating a word and the target language is the same as the source language, the dictionary entry of the word is shown:\n\n    $ trans :en word\n\nTo enable dictionary mode no matter whether the source language and the target language are identical, use the `-dictionary` (`-d`) option.\n\n    $ trans -d fr: mot\n\n**Note:** Not every language supported by Google Translate has provided dictionary data. See **[wiki: Languages](https://github.com/soimort/translate-shell/wiki/Languages)** to find out which language(s) has dictionary support.\n\n### Language Identification\n\nUse the `-identify` (`-id`) option to identify the language of the text:\n\n    $ trans -id 言葉\n\n### Text-to-Speech\n\nUse the `-play` (`-p`) option to listen to the translation:\n\n    $ trans -b -p :ja \"Saluton, Mondo\"\n\nUse the `-speak` (`-sp`) option to listen to the original text:\n\n    $ trans -sp \"你好，世界\"\n\n### Terminal Paging\n\nSometimes the content of translation can be too much for display in one screen. Use the `-view` (`-v`) option to view the translation in a terminal pager such as `less` or `more`:\n\n    $ trans -d -v word\n\n### Right-to-Left (RTL) Languages\n\n[Right-to-Left (RTL) languages](http://en.wikipedia.org/wiki/Right-to-left) are well supported via [GNU FriBidi](http://fribidi.org/).\n\nThe program will automatically adjust the screen width for padding when displaying right-to-left languages. Alternatively, you may use the `-width` (`-w`) option to specify the screen width:\n\n    $ trans -b -w 40 :he \"Saluton, Mondo\"\n\nSee **[wiki: Languages](https://github.com/soimort/translate-shell/wiki/Languages)** to find out which language(s) uses a Right-to-Left writing system.\n\n### Pipeline, Input and Output\n\nIf no source text is given in command-line arguments, the program will read from standard input, or from the file specified by the `-input` (`-i`) option:\n\n    $ echo \"Saluton, Mondo\" | trans -b :fr\n    $ trans -b -i input.txt :fr\n\nTranslations are written to standard output, or to the file specified by the `-output` (`-o`) option:\n\n    $ echo \"Saluton, Mondo\" | trans -b -o output.txt :fr\n\n### Translate a File\n\nInstead of using the `-input` option, a [file URI scheme](http://en.wikipedia.org/wiki/File_URI_scheme) (`file://` followed by the file name) can be used as a command-line argument:\n\n    $ trans :fr file://input.txt\n\n**Note**: Brief mode is used when translating from file URI schemes.\n\n### Translate a Web Page\n\nTo translate a web page, an http(s) URI scheme can be used as an argument:\n\n    $ trans :fr http://www.w3.org/\n\nA browser session will open for viewing the translation (via Google Translate's web interface). To specify your web browser of choice, use the `-browser` option:\n\n    $ trans -browser firefox :fr http://www.w3.org/\n\n### Language Details\n\nUse the `-linguist` (`-L`) option to view details of one or more languages:\n\n    $ trans -L fr\n    $ trans -L de+en\n\nSome basic information of the language will be displayed: its English name and endonym (language name in the language itself), language family, writing system, canonical Google Translate code and ISO 639-3 code.\n\n### Interactive Translate Shell (REPL)\n\nStart an interactive shell using the `-shell` (or `-interactive`, `-I`) option:\n\n    $ trans -shell\n\nYou may specify the source language and the target language(s) before starting an interactive shell:\n\n    $ trans -shell en:fr\n\nYou may also change these settings during an interactive session. See **[wiki: REPL](https://github.com/soimort/translate-shell/wiki/REPL)** for more advanced usage of the interactive Translate Shell.\n\n## Usage\n\nFor more details on command-line options, see the man page **[trans(1)](https://www.soimort.org/translate-shell/trans.1.html)** or use `trans -M` in a terminal.\n\n```\nUsage:  trans [OPTIONS] [SOURCES]:[TARGETS] [TEXT]...\n\nInformation options:\n    -V, -version\n        Print version and exit.\n    -H, -help\n        Print help message and exit.\n    -M, -man\n        Show man page and exit.\n    -T, -reference\n        Print reference table of languages (in endonyms) and codes, and exit.\n    -R, -reference-english\n        Print reference table of languages (in English names) and codes, and exit.\n    -S, -list-engines\n        List available translation engines and exit.\n    -list-languages\n        List all languages (in endonyms) and exit.\n    -list-languages-english\n        List all languages (in English names) and exit.\n    -list-codes\n        List all codes and exit.\n    -list-all\n        List all languages (endonyms and English names) and codes, and exit.\n    -L CODES, -linguist CODES\n        Print details of languages and exit.\n    -U, -upgrade\n        Check for upgrade of this program.\n\nTranslator options:\n    -e ENGINE, -engine ENGINE\n        Specify the translation engine to use.\n\nDisplay options:\n    -verbose\n        Verbose mode. (default)\n    -b, -brief\n        Brief mode.\n    -d, -dictionary\n        Dictionary mode.\n    -identify\n        Language identification.\n    -show-original Y/n\n        Show original text or not.\n    -show-original-phonetics Y/n\n        Show phonetic notation of original text or not.\n    -show-translation Y/n\n        Show translation or not.\n    -show-translation-phonetics Y/n\n        Show phonetic notation of translation or not.\n    -show-prompt-message Y/n\n        Show prompt message or not.\n    -show-languages Y/n\n        Show source and target languages or not.\n    -show-original-dictionary y/N\n        Show dictionary entry of original text or not.\n    -show-dictionary Y/n\n        Show dictionary entry of translation or not.\n    -show-alternatives Y/n\n        Show alternative translations or not.\n    -w NUM, -width NUM\n        Specify the screen width for padding.\n    -indent NUM\n        Specify the size of indent (number of spaces).\n    -theme FILENAME\n        Specify the theme to use.\n    -no-theme\n        Do not use any other theme than default.\n    -no-ansi\n        Do not use ANSI escape codes.\n    -no-autocorrect\n        Do not autocorrect. (if defaulted by the translation engine)\n    -no-bidi\n        Do not convert bidirectional texts.\n    -bidi\n        Always convert bidirectional texts.\n    -no-warn\n        Do not write warning messages to stderr.\n    -dump\n        Print raw API response instead.\n\nAudio options:\n    -p, -play\n        Listen to the translation.\n    -speak\n        Listen to the original text.\n    -n VOICE, -narrator VOICE\n        Specify the narrator, and listen to the translation.\n    -player PROGRAM\n        Specify the audio player to use, and listen to the translation.\n    -no-play\n        Do not listen to the translation.\n    -no-translate\n        Do not translate anything when using -speak.\n    -download-audio\n        Download the audio to the current directory.\n    -download-audio-as FILENAME\n        Download the audio to the specified file.\n\nTerminal paging and browsing options:\n    -v, -view\n        View the translation in a terminal pager.\n    -pager PROGRAM\n        Specify the terminal pager to use, and view the translation.\n    -no-view, -no-pager\n        Do not view the translation in a terminal pager.\n    -browser PROGRAM\n        Specify the web browser to use.\n    -no-browser\n        Do not open the web browser.\n\nNetworking options:\n    -x HOST:PORT, -proxy HOST:PORT\n        Use HTTP proxy on given port.\n    -u STRING, -user-agent STRING\n        Specify the User-Agent to identify as.\n    -4, -ipv4, -inet4-only\n        Connect only to IPv4 addresses.\n    -6, -ipv6, -inet6-only\n        Connect only to IPv6 addresses.\n\nInteractive shell options:\n    -I, -interactive, -shell\n        Start an interactive shell.\n    -E, -emacs\n        Start the GNU Emacs front-end for an interactive shell.\n    -no-rlwrap\n        Do not invoke rlwrap when starting an interactive shell.\n\nI/O options:\n    -i FILENAME, -input FILENAME\n        Specify the input file.\n    -o FILENAME, -output FILENAME\n        Specify the output file.\n\nLanguage preference options:\n    -hl CODE, -host CODE\n        Specify the host (interface) language.\n    -s CODES, -sl CODES, -source CODES, -from CODES\n        Specify the source language(s), joined by '+'.\n    -t CODES, -tl CODES, -target CODES, -to CODES\n        Specify the target language(s), joined by '+'.\n\nText preprocessing options:\n    -j, -join-sentence\n        Treat all arguments as one single sentence.\n\nOther options:\n    -no-init\n        Do not load any initialization script.\n\nSee the man page trans(1) for more information.\n```\n\n## Code List\n\nUse `trans -R` or `trans -T` to view the reference table in a terminal.\n\nFor more details on languages and corresponding codes, see **[wiki: Languages](https://github.com/soimort/translate-shell/wiki/Languages)**.\n\n| Language | Code | Language | Code | Language | Code |\n| :------: | :--: | :------: | :--: | :------: | :--: |\n| **[Afrikaans](http://en.wikipedia.org/wiki/ISO_639:afr)** <br/> **Afrikaans** | **`af`** | **[Hebrew](http://en.wikipedia.org/wiki/ISO_639:heb)** <br/> **עִבְרִית** | **`he`** | **[Portuguese (Brazilian)](http://en.wikipedia.org/wiki/ISO_639:por)** <br/> **Português Brasileiro** | **`pt-BR`** | \n| **[Albanian](http://en.wikipedia.org/wiki/ISO_639:sqi)** <br/> **Shqip** | **`sq`** | **[Hill Mari](http://en.wikipedia.org/wiki/ISO_639:mrj)** <br/> **Кырык мары** | **`mrj`** | **[Portuguese (European)](http://en.wikipedia.org/wiki/ISO_639:por)** <br/> **Português Europeu** | **`pt-PT`** | \n| **[Amharic](http://en.wikipedia.org/wiki/ISO_639:amh)** <br/> **አማርኛ** | **`am`** | **[Hindi](http://en.wikipedia.org/wiki/ISO_639:hin)** <br/> **हिन्दी** | **`hi`** | **[Punjabi](http://en.wikipedia.org/wiki/ISO_639:pan)** <br/> **ਪੰਜਾਬੀ** | **`pa`** | \n| **[Arabic](http://en.wikipedia.org/wiki/ISO_639:ara)** <br/> **العربية** | **`ar`** | **[Hmong](http://en.wikipedia.org/wiki/ISO_639:hmn)** <br/> **Hmoob** | **`hmn`** | **[Quechua](http://en.wikipedia.org/wiki/ISO_639:que)** <br/> **Runasimi** | **`qu`** | \n| **[Armenian](http://en.wikipedia.org/wiki/ISO_639:hye)** <br/> **Հայերեն** | **`hy`** | **[Hungarian](http://en.wikipedia.org/wiki/ISO_639:hun)** <br/> **Magyar** | **`hu`** | **[Querétaro Otomi](http://en.wikipedia.org/wiki/ISO_639:otq)** <br/> **Hñąñho** | **`otq`** | \n| **[Assamese](http://en.wikipedia.org/wiki/ISO_639:asm)** <br/> **অসমীয়া** | **`as`** | **[Icelandic](http://en.wikipedia.org/wiki/ISO_639:isl)** <br/> **Íslenska** | **`is`** | **[Romanian](http://en.wikipedia.org/wiki/ISO_639:ron)** <br/> **Română** | **`ro`** | \n| **[Aymara](http://en.wikipedia.org/wiki/ISO_639:aym)** <br/> **Aymar aru** | **`ay`** | **[Igbo](http://en.wikipedia.org/wiki/ISO_639:ibo)** <br/> **Igbo** | **`ig`** | **[Romansh](http://en.wikipedia.org/wiki/ISO_639:roh)** <br/> **Rumantsch** | **`rm`** | \n| **[Azerbaijani](http://en.wikipedia.org/wiki/ISO_639:aze)** <br/> **Azərbaycanca** | **`az`** | **[Ilocano](http://en.wikipedia.org/wiki/ISO_639:ilo)** <br/> **Ilokano** | **`ilo`** | **[Russian](http://en.wikipedia.org/wiki/ISO_639:rus)** <br/> **Русский** | **`ru`** | \n| **[Bambara](http://en.wikipedia.org/wiki/ISO_639:bam)** <br/> **Bamanankan** | **`bm`** | **[Indonesian](http://en.wikipedia.org/wiki/ISO_639:ind)** <br/> **Bahasa Indonesia** | **`id`** | **[Samoan](http://en.wikipedia.org/wiki/ISO_639:smo)** <br/> **Gagana Sāmoa** | **`sm`** | \n| **[Bashkir](http://en.wikipedia.org/wiki/ISO_639:bak)** <br/> **Башҡортса** | **`ba`** | **[Interlingue](http://en.wikipedia.org/wiki/ISO_639:ile)** <br/> **Interlingue** | **`ie`** | **[Sanskrit](http://en.wikipedia.org/wiki/ISO_639:san)** <br/> **संस्कृतम्** | **`sa`** | \n| **[Basque](http://en.wikipedia.org/wiki/ISO_639:eus)** <br/> **Euskara** | **`eu`** | **[Inuinnaqtun](http://en.wikipedia.org/wiki/ISO_639:ikt)** <br/> **Inuinnaqtun** | **`ikt`** | **[Scots Gaelic](http://en.wikipedia.org/wiki/ISO_639:gla)** <br/> **Gàidhlig** | **`gd`** | \n| **[Belarusian](http://en.wikipedia.org/wiki/ISO_639:bel)** <br/> **беларуская** | **`be`** | **[Inuktitut](http://en.wikipedia.org/wiki/ISO_639:iku)** <br/> **ᐃᓄᒃᑎᑐᑦ** | **`iu`** | **[Sepedi](http://en.wikipedia.org/wiki/ISO_639:nso)** <br/> **Sepedi** | **`nso`** | \n| **[Bengali](http://en.wikipedia.org/wiki/ISO_639:ben)** <br/> **বাংলা** | **`bn`** | **[Inuktitut (Latin)](http://en.wikipedia.org/wiki/ISO_639:iku)** <br/> **Inuktitut** | **`iu-Latn`** | **[Serbian (Cyrillic)](http://en.wikipedia.org/wiki/ISO_639:srp)** <br/> **Српски** | **`sr-Cyrl`** | \n| **[Bhojpuri](http://en.wikipedia.org/wiki/ISO_639:bho)** <br/> **भोजपुरी** | **`bho`** | **[Irish](http://en.wikipedia.org/wiki/ISO_639:gle)** <br/> **Gaeilge** | **`ga`** | **[Serbian (Latin)](http://en.wikipedia.org/wiki/ISO_639:srp)** <br/> **Srpski** | **`sr-Latn`** | \n| **[Bosnian](http://en.wikipedia.org/wiki/ISO_639:bos)** <br/> **Bosanski** | **`bs`** | **[Italian](http://en.wikipedia.org/wiki/ISO_639:ita)** <br/> **Italiano** | **`it`** | **[Sesotho](http://en.wikipedia.org/wiki/ISO_639:sot)** <br/> **Sesotho** | **`st`** | \n| **[Breton](http://en.wikipedia.org/wiki/ISO_639:bre)** <br/> **Brezhoneg** | **`br`** | **[Japanese](http://en.wikipedia.org/wiki/ISO_639:jpn)** <br/> **日本語** | **`ja`** | **[Setswana](http://en.wikipedia.org/wiki/ISO_639:tsn)** <br/> **Setswana** | **`tn`** | \n| **[Bulgarian](http://en.wikipedia.org/wiki/ISO_639:bul)** <br/> **български** | **`bg`** | **[Javanese](http://en.wikipedia.org/wiki/ISO_639:jav)** <br/> **Basa Jawa** | **`jv`** | **[Shona](http://en.wikipedia.org/wiki/ISO_639:sna)** <br/> **chiShona** | **`sn`** | \n| **[Cantonese](http://en.wikipedia.org/wiki/ISO_639:yue)** <br/> **粵語** | **`yue`** | **[Kannada](http://en.wikipedia.org/wiki/ISO_639:kan)** <br/> **ಕನ್ನಡ** | **`kn`** | **[Sindhi](http://en.wikipedia.org/wiki/ISO_639:snd)** <br/> **سنڌي** | **`sd`** | \n| **[Catalan](http://en.wikipedia.org/wiki/ISO_639:cat)** <br/> **Català** | **`ca`** | **[Kazakh](http://en.wikipedia.org/wiki/ISO_639:kaz)** <br/> **Қазақ тілі** | **`kk`** | **[Sinhala](http://en.wikipedia.org/wiki/ISO_639:sin)** <br/> **සිංහල** | **`si`** | \n| **[Cebuano](http://en.wikipedia.org/wiki/ISO_639:ceb)** <br/> **Cebuano** | **`ceb`** | **[Khmer](http://en.wikipedia.org/wiki/ISO_639:khm)** <br/> **ភាសាខ្មែរ** | **`km`** | **[Slovak](http://en.wikipedia.org/wiki/ISO_639:slk)** <br/> **Slovenčina** | **`sk`** | \n| **[Cherokee](http://en.wikipedia.org/wiki/ISO_639:chr)** <br/> **ᏣᎳᎩ** | **`chr`** | **[Kinyarwanda](http://en.wikipedia.org/wiki/ISO_639:kin)** <br/> **Ikinyarwanda** | **`rw`** | **[Slovenian](http://en.wikipedia.org/wiki/ISO_639:slv)** <br/> **Slovenščina** | **`sl`** | \n| **[Chichewa](http://en.wikipedia.org/wiki/ISO_639:nya)** <br/> **Nyanja** | **`ny`** | **[Klingon](http://en.wikipedia.org/wiki/ISO_639:tlh)** <br/> **tlhIngan Hol** | **`tlh-Latn`** | **[Somali](http://en.wikipedia.org/wiki/ISO_639:som)** <br/> **Soomaali** | **`so`** | \n| **[Chinese (Literary)](http://en.wikipedia.org/wiki/ISO_639:lzh)** <br/> **文言** | **`lzh`** | **[Konkani](http://en.wikipedia.org/wiki/ISO_639:gom)** <br/> **कोंकणी** | **`gom`** | **[Spanish](http://en.wikipedia.org/wiki/ISO_639:spa)** <br/> **Español** | **`es`** | \n| **[Chinese (Simplified)](http://en.wikipedia.org/wiki/ISO_639:zho)** <br/> **简体中文** | **`zh-CN`** | **[Korean](http://en.wikipedia.org/wiki/ISO_639:kor)** <br/> **한국어** | **`ko`** | **[Sundanese](http://en.wikipedia.org/wiki/ISO_639:sun)** <br/> **Basa Sunda** | **`su`** | \n| **[Chinese (Traditional)](http://en.wikipedia.org/wiki/ISO_639:zho)** <br/> **繁體中文** | **`zh-TW`** | **[Krio](http://en.wikipedia.org/wiki/ISO_639:kri)** <br/> **Krio** | **`kri`** | **[Swahili](http://en.wikipedia.org/wiki/ISO_639:swa)** <br/> **Kiswahili** | **`sw`** | \n| **[Chuvash](http://en.wikipedia.org/wiki/ISO_639:chv)** <br/> **Чӑвашла** | **`cv`** | **[Kurdish (Central)](http://en.wikipedia.org/wiki/ISO_639:ckb)** <br/> **سۆرانی** | **`ckb`** | **[Swedish](http://en.wikipedia.org/wiki/ISO_639:swe)** <br/> **Svenska** | **`sv`** | \n| **[Corsican](http://en.wikipedia.org/wiki/ISO_639:cos)** <br/> **Corsu** | **`co`** | **[Kurdish (Northern)](http://en.wikipedia.org/wiki/ISO_639:kmr)** <br/> **Kurmancî** | **`ku`** | **[Tahitian](http://en.wikipedia.org/wiki/ISO_639:tah)** <br/> **Reo Tahiti** | **`ty`** | \n| **[Croatian](http://en.wikipedia.org/wiki/ISO_639:hrv)** <br/> **Hrvatski** | **`hr`** | **[Kyrgyz](http://en.wikipedia.org/wiki/ISO_639:kir)** <br/> **Кыргызча** | **`ky`** | **[Tajik](http://en.wikipedia.org/wiki/ISO_639:tgk)** <br/> **Тоҷикӣ** | **`tg`** | \n| **[Czech](http://en.wikipedia.org/wiki/ISO_639:ces)** <br/> **Čeština** | **`cs`** | **[Lao](http://en.wikipedia.org/wiki/ISO_639:lao)** <br/> **ລາວ** | **`lo`** | **[Tamil](http://en.wikipedia.org/wiki/ISO_639:tam)** <br/> **தமிழ்** | **`ta`** | \n| **[Danish](http://en.wikipedia.org/wiki/ISO_639:dan)** <br/> **Dansk** | **`da`** | **[Latin](http://en.wikipedia.org/wiki/ISO_639:lat)** <br/> **Latina** | **`la`** | **[Tatar](http://en.wikipedia.org/wiki/ISO_639:tat)** <br/> **татарча** | **`tt`** | \n| **[Dari](http://en.wikipedia.org/wiki/ISO_639:prs)** <br/> **دری** | **`prs`** | **[Latvian](http://en.wikipedia.org/wiki/ISO_639:lav)** <br/> **Latviešu** | **`lv`** | **[Telugu](http://en.wikipedia.org/wiki/ISO_639:tel)** <br/> **తెలుగు** | **`te`** | \n| **[Dhivehi](http://en.wikipedia.org/wiki/ISO_639:div)** <br/> **ދިވެހި** | **`dv`** | **[Lingala](http://en.wikipedia.org/wiki/ISO_639:lin)** <br/> **Lingála** | **`ln`** | **[Thai](http://en.wikipedia.org/wiki/ISO_639:tha)** <br/> **ไทย** | **`th`** | \n| **[Dogri](http://en.wikipedia.org/wiki/ISO_639:doi)** <br/> **डोगरी** | **`doi`** | **[Lithuanian](http://en.wikipedia.org/wiki/ISO_639:lit)** <br/> **Lietuvių** | **`lt`** | **[Tibetan](http://en.wikipedia.org/wiki/ISO_639:bod)** <br/> **བོད་ཡིག** | **`bo`** | \n| **[Dutch](http://en.wikipedia.org/wiki/ISO_639:nld)** <br/> **Nederlands** | **`nl`** | **[Luganda](http://en.wikipedia.org/wiki/ISO_639:lug)** <br/> **Luganda** | **`lg`** | **[Tigrinya](http://en.wikipedia.org/wiki/ISO_639:tir)** <br/> **ትግርኛ** | **`ti`** | \n| **[Dzongkha](http://en.wikipedia.org/wiki/ISO_639:dzo)** <br/> **རྫོང་ཁ** | **`dz`** | **[Luxembourgish](http://en.wikipedia.org/wiki/ISO_639:ltz)** <br/> **Lëtzebuergesch** | **`lb`** | **[Tongan](http://en.wikipedia.org/wiki/ISO_639:ton)** <br/> **Lea faka-Tonga** | **`to`** | \n| **[Eastern Mari](http://en.wikipedia.org/wiki/ISO_639:mhr)** <br/> **Олык марий** | **`mhr`** | **[Macedonian](http://en.wikipedia.org/wiki/ISO_639:mkd)** <br/> **Македонски** | **`mk`** | **[Tsonga](http://en.wikipedia.org/wiki/ISO_639:tso)** <br/> **Xitsonga** | **`ts`** | \n| **[English](http://en.wikipedia.org/wiki/ISO_639:eng)** <br/> **English** | **`en`** | **[Maithili](http://en.wikipedia.org/wiki/ISO_639:mai)** <br/> **मैथिली** | **`mai`** | **[Turkish](http://en.wikipedia.org/wiki/ISO_639:tur)** <br/> **Türkçe** | **`tr`** | \n| **[Esperanto](http://en.wikipedia.org/wiki/ISO_639:epo)** <br/> **Esperanto** | **`eo`** | **[Malagasy](http://en.wikipedia.org/wiki/ISO_639:mlg)** <br/> **Malagasy** | **`mg`** | **[Turkmen](http://en.wikipedia.org/wiki/ISO_639:tuk)** <br/> **Türkmen** | **`tk`** | \n| **[Estonian](http://en.wikipedia.org/wiki/ISO_639:est)** <br/> **Eesti** | **`et`** | **[Malay](http://en.wikipedia.org/wiki/ISO_639:msa)** <br/> **Bahasa Melayu** | **`ms`** | **[Twi](http://en.wikipedia.org/wiki/ISO_639:twi)** <br/> **Twi** | **`tw`** | \n| **[Ewe](http://en.wikipedia.org/wiki/ISO_639:ewe)** <br/> **Eʋegbe** | **`ee`** | **[Malayalam](http://en.wikipedia.org/wiki/ISO_639:mal)** <br/> **മലയാളം** | **`ml`** | **[Udmurt](http://en.wikipedia.org/wiki/ISO_639:udm)** <br/> **Удмурт** | **`udm`** | \n| **[Faroese](http://en.wikipedia.org/wiki/ISO_639:fao)** <br/> **Føroyskt** | **`fo`** | **[Maltese](http://en.wikipedia.org/wiki/ISO_639:mlt)** <br/> **Malti** | **`mt`** | **[Ukrainian](http://en.wikipedia.org/wiki/ISO_639:ukr)** <br/> **Українська** | **`uk`** | \n| **[Fijian](http://en.wikipedia.org/wiki/ISO_639:fij)** <br/> **Vosa Vakaviti** | **`fj`** | **[Maori](http://en.wikipedia.org/wiki/ISO_639:mri)** <br/> **Māori** | **`mi`** | **[Upper Sorbian](http://en.wikipedia.org/wiki/ISO_639:hsb)** <br/> **Hornjoserbšćina** | **`hsb`** | \n| **[Filipino](http://en.wikipedia.org/wiki/ISO_639:fil)** <br/> **Filipino** | **`tl`** | **[Marathi](http://en.wikipedia.org/wiki/ISO_639:mar)** <br/> **मराठी** | **`mr`** | **[Urdu](http://en.wikipedia.org/wiki/ISO_639:urd)** <br/> **اُردُو** | **`ur`** | \n| **[Finnish](http://en.wikipedia.org/wiki/ISO_639:fin)** <br/> **Suomi** | **`fi`** | **[Meiteilon](http://en.wikipedia.org/wiki/ISO_639:mni)** <br/> **ꯃꯤꯇꯩꯂꯣꯟ** | **`mni-Mtei`** | **[Uyghur](http://en.wikipedia.org/wiki/ISO_639:uig)** <br/> **ئۇيغۇر تىلى** | **`ug`** | \n| **[French](http://en.wikipedia.org/wiki/ISO_639:fra)** <br/> **Français** | **`fr`** | **[Mizo](http://en.wikipedia.org/wiki/ISO_639:lus)** <br/> **Mizo ṭawng** | **`lus`** | **[Uzbek](http://en.wikipedia.org/wiki/ISO_639:uzb)** <br/> **Oʻzbek tili** | **`uz`** | \n| **[French (Canadian)](http://en.wikipedia.org/wiki/ISO_639:fra)** <br/> **Français canadien** | **`fr-CA`** | **[Mongolian](http://en.wikipedia.org/wiki/ISO_639:mon)** <br/> **Монгол** | **`mn`** | **[Vietnamese](http://en.wikipedia.org/wiki/ISO_639:vie)** <br/> **Tiếng Việt** | **`vi`** | \n| **[Frisian](http://en.wikipedia.org/wiki/ISO_639:fry)** <br/> **Frysk** | **`fy`** | **[Mongolian (Traditional)](http://en.wikipedia.org/wiki/ISO_639:mon)** <br/> **ᠮᠣᠩᠭᠣᠯ** | **`mn-Mong`** | **[Volapük](http://en.wikipedia.org/wiki/ISO_639:vol)** <br/> **Volapük** | **`vo`** | \n| **[Galician](http://en.wikipedia.org/wiki/ISO_639:glg)** <br/> **Galego** | **`gl`** | **[Myanmar](http://en.wikipedia.org/wiki/ISO_639:mya)** <br/> **မြန်မာစာ** | **`my`** | **[Welsh](http://en.wikipedia.org/wiki/ISO_639:cym)** <br/> **Cymraeg** | **`cy`** | \n| **[Georgian](http://en.wikipedia.org/wiki/ISO_639:kat)** <br/> **ქართული** | **`ka`** | **[Nepali](http://en.wikipedia.org/wiki/ISO_639:nep)** <br/> **नेपाली** | **`ne`** | **[Wolof](http://en.wikipedia.org/wiki/ISO_639:wol)** <br/> **Wollof** | **`wo`** | \n| **[German](http://en.wikipedia.org/wiki/ISO_639:deu)** <br/> **Deutsch** | **`de`** | **[Norwegian](http://en.wikipedia.org/wiki/ISO_639:nor)** <br/> **Norsk** | **`no`** | **[Xhosa](http://en.wikipedia.org/wiki/ISO_639:xho)** <br/> **isiXhosa** | **`xh`** | \n| **[Greek](http://en.wikipedia.org/wiki/ISO_639:ell)** <br/> **Ελληνικά** | **`el`** | **[Occitan](http://en.wikipedia.org/wiki/ISO_639:oci)** <br/> **Occitan** | **`oc`** | **[Yakut](http://en.wikipedia.org/wiki/ISO_639:sah)** <br/> **Sakha** | **`sah`** | \n| **[Greenlandic](http://en.wikipedia.org/wiki/ISO_639:kal)** <br/> **Kalaallisut** | **`kl`** | **[Odia](http://en.wikipedia.org/wiki/ISO_639:ori)** <br/> **ଓଡ଼ିଆ** | **`or`** | **[Yiddish](http://en.wikipedia.org/wiki/ISO_639:yid)** <br/> **ייִדיש** | **`yi`** | \n| **[Guarani](http://en.wikipedia.org/wiki/ISO_639:gug)** <br/> **Avañe'ẽ** | **`gn`** | **[Oromo](http://en.wikipedia.org/wiki/ISO_639:orm)** <br/> **Afaan Oromoo** | **`om`** | **[Yoruba](http://en.wikipedia.org/wiki/ISO_639:yor)** <br/> **Yorùbá** | **`yo`** | \n| **[Gujarati](http://en.wikipedia.org/wiki/ISO_639:guj)** <br/> **ગુજરાતી** | **`gu`** | **[Papiamento](http://en.wikipedia.org/wiki/ISO_639:pap)** <br/> **Papiamentu** | **`pap`** | **[Yucatec Maya](http://en.wikipedia.org/wiki/ISO_639:yua)** <br/> **Màaya T'àan** | **`yua`** | \n| **[Haitian Creole](http://en.wikipedia.org/wiki/ISO_639:hat)** <br/> **Kreyòl Ayisyen** | **`ht`** | **[Pashto](http://en.wikipedia.org/wiki/ISO_639:pus)** <br/> **پښتو** | **`ps`** | **[Zulu](http://en.wikipedia.org/wiki/ISO_639:zul)** <br/> **isiZulu** | **`zu`** | \n| **[Hausa](http://en.wikipedia.org/wiki/ISO_639:hau)** <br/> **Hausa** | **`ha`** | **[Persian](http://en.wikipedia.org/wiki/ISO_639:fas)** <br/> **فارسی** | **`fa`** | \n| **[Hawaiian](http://en.wikipedia.org/wiki/ISO_639:haw)** <br/> **ʻŌlelo Hawaiʻi** | **`haw`** | **[Polish](http://en.wikipedia.org/wiki/ISO_639:pol)** <br/> **Polski** | **`pl`** | \n\n\n## Wiki\n\nLists of all languages, writing systems and fonts for reference:\n\n* **[Languages](https://github.com/soimort/translate-shell/wiki/Languages)**\n* **[Writing Systems and Fonts](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts)**\n\nThe following pages demonstrate the advanced usage of **Translate Shell**:\n\n* **[REPL](https://github.com/soimort/translate-shell/wiki/REPL)**\n* **[Text Editor Integration](https://github.com/soimort/translate-shell/wiki/Text-Editor-Integration)**\n* **[Narrator Selection](https://github.com/soimort/translate-shell/wiki/Narrator-Selection)**\n* **[Configuration](https://github.com/soimort/translate-shell/wiki/Configuration)**\n* **[Themes](https://github.com/soimort/translate-shell/wiki/Themes)**\n* **[AppleScript](https://github.com/soimort/translate-shell/wiki/AppleScript)**\n\nFind out whether your Linux distribution has included **Translate Shell** in its official repository. If not, contribute one:\n\n* **[Distros](https://github.com/soimort/translate-shell/wiki/Distros)**\n\nFrequently Asked Questions, historical stuff, AWK coding style, etc.:\n\n* **[FAQ](https://github.com/soimort/translate-shell/wiki/FAQ)**\n* **[History](https://github.com/soimort/translate-shell/wiki/History)**\n* **[AWK Style Guide](https://github.com/soimort/translate-shell/wiki/AWK-Style-Guide)**\n\n## Reporting Bugs / Contributing\n\nPlease review the [guidelines for contributing](https://github.com/soimort/translate-shell/blob/stable/CONTRIBUTING.md) before reporting an issue or sending a pull request.\n\n## Licensing\n\nThis is free and unencumbered software released into the public domain. See **[LICENSE](https://github.com/soimort/translate-shell/blob/stable/LICENSE)** and **[WAIVER](https://github.com/soimort/translate-shell/blob/stable/WAIVER)** for details.\n"
  },
  {
    "path": "README.template.md",
    "content": "# Translate Shell\n\n[![Icon](https://raw.githubusercontent.com/soimort/translate-shell/gh-pages/images/icon.png)](https://www.soimort.org/translate-shell)\n[![CircleCI](https://circleci.com/gh/soimort/translate-shell.svg?style=svg)](https://circleci.com/gh/soimort/translate-shell)\n[![Actions](https://github.com/soimort/translate-shell/workflows/CI/badge.svg)](https://github.com/soimort/translate-shell/actions)\n[![Version](https://raw.githubusercontent.com/soimort/translate-shell/gh-pages/images/badge-release.png)](https://github.com/soimort/translate-shell/releases)\n[![Download](https://raw.githubusercontent.com/soimort/translate-shell/gh-pages/images/badge-download.png)](https://www.soimort.org/translate-shell/trans)\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/soimort/translate-shell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n**[Translate Shell](https://www.soimort.org/translate-shell)** (formerly _Google Translate CLI_) is a command-line translator powered by **[Google Translate](https://translate.google.com/)** (default), **[Bing Translator](https://www.bing.com/translator)**, **[Yandex.Translate](https://translate.yandex.com/)**, and **[Apertium](https://www.apertium.org/)**. It gives you easy access to one of these translation engines in your terminal:\n\n```\n$ trans 'Saluton, Mondo!'\nSaluton, Mondo!\n\nHello, World!\n\nTranslations of Saluton, Mondo!\n[ Esperanto -> English ]\nSaluton ,\n    Hello,\nMondo !\n    World!\n```\n\nBy default, translations with detailed explanations are shown. You can also translate the text briefly: (only the most relevant translation will be shown)\n\n```\n$ trans -brief 'Saluton, Mondo!'\nHello, World!\n```\n\n**Translate Shell** can also be used like an interactive shell; input the text to be translated line by line:\n\n```\n$ trans -shell -brief\n> Rien ne réussit comme le succès.\nNothing succeeds like success.\n> Was mich nicht umbringt, macht mich stärker.\nWhat does not kill me makes me stronger.\n> Юмор есть остроумие глубокого чувства.\nHumor has a deep sense of wit.\n> 學而不思則罔，思而不學則殆。\nLearning without thought is labor lost, thought without learning is perilous.\n> 幸福になるためには、人から愛されるのが一番の近道。\nIn order to be happy, the best way is to be loved by people.\n```\n\n## Prerequisites\n\n### System Requirements\n\n**Translate Shell** is known to work on many POSIX-compliant systems, including but not limited to:\n\n* GNU/Linux\n* macOS\n* *BSD\n* Android (through Termux)\n* Windows (through WSL, Cygwin, or MSYS2)\n\n### Dependencies\n\n* **[GNU Awk](https://www.gnu.org/software/gawk/)** (**gawk**) **4.0 or later**\n    * This program relies heavily on GNU extensions of the [AWK language](http://en.wikipedia.org/wiki/AWK), which are non-portable for other AWK implementations (e.g. nawk).\n    * How to get gawk:\n      * gawk comes with all GNU/Linux distributions.\n      * On FreeBSD, gawk is available in the ports.\n      * On macOS, gawk is available in MacPorts and Homebrew.\n    * Please note that gawk 5.2.0 has a [known bug](https://github.com/soimort/translate-shell/issues/463) -- update to gawk 5.2.1 instead.\n* **[GNU Bash](http://www.gnu.org/software/bash/)** or **[Zsh](http://www.zsh.org/)**\n    * You may use Translate Shell from any Unix shell of your choice (bash, zsh, ksh, tcsh, fish, etc.); however, the wrapper script requires either **bash** or **zsh** installed.\n\n### Recommended Dependencies\n\nThese dependencies are optional, but strongly recommended for full functionality:\n\n* **[curl](http://curl.haxx.se/)** with **OpenSSL** support\n* **[GNU FriBidi](http://fribidi.org/)**: _an implementation of the Unicode Bidirectional Algorithm (bidi)_\n    * required for displaying text in Right-to-Left scripts (e.g. Arabic, Hebrew)\n* **[mplayer](http://www.mplayerhq.hu/)**, **[mpv](http://mpv.io/)**, **[mpg123](http://mpg123.org/)**, or **[eSpeak](http://espeak.sourceforge.net/)**\n    * required for the Text-to-Speech functionality\n* **[less](http://www.greenwoodsoftware.com/less/)**, **[more](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html)** or **[most](http://www.jedsoft.org/most/)**\n    * required for terminal paging\n* **[rlwrap](http://utopia.knoware.nl/~hlub/uck/rlwrap/#rlwrap)**: *a GNU readline wrapper*\n    * required for readline-style editing and history in the interactive shell\n* **[aspell](http://aspell.net/)** or **[hunspell](http://hunspell.github.io/)**\n    * required for spell checking\n\n### Environment and Fonts\n\nIt is a must to have corresponding fonts for the language(s) / script(s) you wish to display in your terminal. See **[wiki: Writing Systems and Fonts](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts#unicode-fonts)** for more details on scripts and recommended Unicode fonts.\n\n## Try It Out!\n\nStart an interactive shell and translate anything you input into your native language: (in **bash** or **zsh**)\n\n    $ gawk -f <(curl -Ls --compressed https://git.io/translate) -- -shell\n\n(in **fish**)\n\n    $ gawk -f (curl -Ls --compressed https://git.io/translate | psub) -- -shell\n\n### Using Docker\n\nTo try out via [Docker](https://www.docker.com/), run:\n\n    $ docker pull soimort/translate-shell\n\nThen you may start an interactive shell from the Docker image for translating:\n\n    $ docker run -it soimort/translate-shell -shell\n\n## Installation\n\n### Option #1. Direct Download\n\nDownload [the self-contained executable](http://git.io/trans) and place it into your path. It's everything you need.\n\n    $ wget git.io/trans\n    $ chmod +x ./trans\n\nThere is a [GPG signature](https://www.soimort.org/translate-shell/trans.sig).\n\n### Option #2. From A Package Manager\n\n#### Using your favorite package manager\n\nSee **[wiki: Distros](https://github.com/soimort/translate-shell/wiki/Distros)** on how to install from a specific package manager on your distro.\n\n#### Using [Antigen](https://github.com/zsh-users/antigen) (for Zsh users)\n\nAdd the following line to your `.zshrc`:\n\n    antigen bundle soimort/translate-shell@develop\n\n### Option #3. From Git\n\n    $ git clone https://github.com/soimort/translate-shell\n    $ cd translate-shell/\n    $ make\n    $ [sudo] make install\n\nIn case you have only zsh but not bash in your system, build with:\n\n    $ make TARGET=zsh\n\nThe default `PREFIX` of installation is `/usr/local`. To install the program to somewhere else (e.g. `/usr`, `~/.local`), use:\n\n    $ [sudo] make PREFIX=/usr install\n\n## Getting Started by Examples\n\n### Translate a Word\n\n#### From any language to your language\n\nGoogle Translate can identify the language of the source text automatically, and Translate Shell by default translates the source text into the language of your `locale`.\n\n    $ trans vorto\n\n#### From any language to one or more specific languages\n\nTranslate a word into French:\n\n    $ trans :fr word\n\nTranslate a word into Chinese and Japanese: (use a plus sign \"`+`\" as the delimiter)\n\n    $ trans :zh+ja word\n\nAlternatively, equals sign (\"`=`\") can be used in place of the colon (\"`:`\"). Note that in some shells (e.g. zsh), equals signs may be interpreted differently, therefore the argument specifying languages needs to be protected:\n\n    $ trans {=zh+ja} word\n    $ trans '=zh+ja' word\n\nYou can also use the `-target` (`-t`) option to specify the target language(s):\n\n    $ trans -t zh+ja word\n\nWith the `-t` option, the name of the language may also be used instead of the language code:\n\n    $ trans -t japanese word\n    $ trans -t 日本語 word\n\n#### From a specific language\n\nGoogle Translate may wrongly identify the source text as some other language than you expected:\n\n    $ trans 手紙\n\nIn that case, you need to specify its language explicitly:\n\n    $ trans ja: 手紙\n    $ trans zh: 手紙\n\nYou can also use the `-source` (`-s`) option to specify the source language:\n\n    $ trans -s ja 手紙\n\n### Translate Multiple Words or a Phrase\n\nTranslate each word alone:\n\n    $ trans en:zh word processor\n\nPut words into one argument, and translate them as a whole:\n\n    $ trans en:zh \"word processor\"\n\n### Translate a Sentence\n\nTranslating a sentence is much the same like translating a phrase; you can just quote the sentence into one argument:\n\n    $ trans :zh \"To-morrow, and to-morrow, and to-morrow,\"\n    $ trans :zh 'To-morrow, and to-morrow, and to-morrow,'\n\nIt is also possible to translate multi-line sentences:\n\n    $ trans :zh \"Creeps in this petty pace from day to day,\n    > To the last syllable of recorded time;\n    > And all our yesterdays have lighted fools\n    > The way to dusty death.\"\n\nTo avoid punctuation marks (e.g. \"`!`\") or other special characters being interpreted by the shell, use *single quotes*:\n\n    $ trans :zh 'Out, out, brief candle!'\n\nThere are some cases though, you may still want to use *double quotes*: (e.g. the sentence contains a single quotation mark \"`'`\")\n\n    $ trans :zh \"Life's but a walking shadow, a poor player\"\n\nAlternatively, use the `-join-sentence` (`-j`) option to treat all arguments as one sentence so that quotes can be omitted:\n\n    $ trans -j :zh Life\\'s but a walking shadow, a poor player\n\n### Brief Mode\n\nBy default, Translate Shell displays translations in a verbose manner. If you prefer to see only the most relevant translation, there is a brief mode available using the `-brief` (`-b`) option:\n\n    $ trans -b :fr \"Saluton, Mondo\"\n\nIn brief mode, phonetic notation (if any) is not shown by default. To enable this, put an at sign \"`@`\" in front of the language code:\n\n    $ trans -b :@ja \"Saluton, Mondo\"\n\n### Dictionary Mode\n\nGoogle Translate can be used as a dictionary. When translating a word and the target language is the same as the source language, the dictionary entry of the word is shown:\n\n    $ trans :en word\n\nTo enable dictionary mode no matter whether the source language and the target language are identical, use the `-dictionary` (`-d`) option.\n\n    $ trans -d fr: mot\n\n**Note:** Not every language supported by Google Translate has provided dictionary data. See **[wiki: Languages](https://github.com/soimort/translate-shell/wiki/Languages)** to find out which language(s) has dictionary support.\n\n### Language Identification\n\nUse the `-identify` (`-id`) option to identify the language of the text:\n\n    $ trans -id 言葉\n\n### Text-to-Speech\n\nUse the `-play` (`-p`) option to listen to the translation:\n\n    $ trans -b -p :ja \"Saluton, Mondo\"\n\nUse the `-speak` (`-sp`) option to listen to the original text:\n\n    $ trans -sp \"你好，世界\"\n\n### Terminal Paging\n\nSometimes the content of translation can be too much for display in one screen. Use the `-view` (`-v`) option to view the translation in a terminal pager such as `less` or `more`:\n\n    $ trans -d -v word\n\n### Right-to-Left (RTL) Languages\n\n[Right-to-Left (RTL) languages](http://en.wikipedia.org/wiki/Right-to-left) are well supported via [GNU FriBidi](http://fribidi.org/).\n\nThe program will automatically adjust the screen width for padding when displaying right-to-left languages. Alternatively, you may use the `-width` (`-w`) option to specify the screen width:\n\n    $ trans -b -w 40 :he \"Saluton, Mondo\"\n\nSee **[wiki: Languages](https://github.com/soimort/translate-shell/wiki/Languages)** to find out which language(s) uses a Right-to-Left writing system.\n\n### Pipeline, Input and Output\n\nIf no source text is given in command-line arguments, the program will read from standard input, or from the file specified by the `-input` (`-i`) option:\n\n    $ echo \"Saluton, Mondo\" | trans -b :fr\n    $ trans -b -i input.txt :fr\n\nTranslations are written to standard output, or to the file specified by the `-output` (`-o`) option:\n\n    $ echo \"Saluton, Mondo\" | trans -b -o output.txt :fr\n\n### Translate a File\n\nInstead of using the `-input` option, a [file URI scheme](http://en.wikipedia.org/wiki/File_URI_scheme) (`file://` followed by the file name) can be used as a command-line argument:\n\n    $ trans :fr file://input.txt\n\n**Note**: Brief mode is used when translating from file URI schemes.\n\n### Translate a Web Page\n\nTo translate a web page, an http(s) URI scheme can be used as an argument:\n\n    $ trans :fr http://www.w3.org/\n\nA browser session will open for viewing the translation (via Google Translate's web interface). To specify your web browser of choice, use the `-browser` option:\n\n    $ trans -browser firefox :fr http://www.w3.org/\n\n### Language Details\n\nUse the `-linguist` (`-L`) option to view details of one or more languages:\n\n    $ trans -L fr\n    $ trans -L de+en\n\nSome basic information of the language will be displayed: its English name and endonym (language name in the language itself), language family, writing system, canonical Google Translate code and ISO 639-3 code.\n\n### Interactive Translate Shell (REPL)\n\nStart an interactive shell using the `-shell` (or `-interactive`, `-I`) option:\n\n    $ trans -shell\n\nYou may specify the source language and the target language(s) before starting an interactive shell:\n\n    $ trans -shell en:fr\n\nYou may also change these settings during an interactive session. See **[wiki: REPL](https://github.com/soimort/translate-shell/wiki/REPL)** for more advanced usage of the interactive Translate Shell.\n\n## Usage\n\nFor more details on command-line options, see the man page **[trans(1)](https://www.soimort.org/translate-shell/trans.1.html)** or use `trans -M` in a terminal.\n\n```\n$usage$\n```\n\n## Code List\n\nUse `trans -R` or `trans -T` to view the reference table in a terminal.\n\nFor more details on languages and corresponding codes, see **[wiki: Languages](https://github.com/soimort/translate-shell/wiki/Languages)**.\n\n$code-list$\n\n## Wiki\n\n$wiki-home$\n\n## Reporting Bugs / Contributing\n\nPlease review the [guidelines for contributing](https://github.com/soimort/translate-shell/blob/stable/CONTRIBUTING.md) before reporting an issue or sending a pull request.\n\n## Licensing\n\nThis is free and unencumbered software released into the public domain. See **[LICENSE](https://github.com/soimort/translate-shell/blob/stable/LICENSE)** and **[WAIVER](https://github.com/soimort/translate-shell/blob/stable/WAIVER)** for details.\n"
  },
  {
    "path": "WAIVER",
    "content": "# Copyright waiver for <https://github.com/soimort/translate-shell>\n\nI dedicate any and all copyright interest in this software to the\npublic domain. I make this dedication for the benefit of the public at\nlarge and to the detriment of my heirs and successors. I intend this\ndedication to be an overt act of relinquishment in perpetuity of all\npresent and future rights to this software under copyright law.\n\nTo the best of my knowledge and belief, my contributions are either\noriginally authored by me or are derived from prior works which I have\nverified are also in the public domain and are not subject to claims\nof copyright by other parties.\n\nTo the best of my knowledge and belief, no individual, business,\norganization, government, or other entity has any copyright interest\nin my contributions, and I affirm that I will not make contributions\nthat are otherwise encumbered.\n"
  },
  {
    "path": "build.awk",
    "content": "#!/usr/bin/gawk -f\n\n# Not all 4.x versions of gawk can handle @include without \".awk\" extension\n# But the build.awk script and the single build should support gawk 4.0+.\n@include \"include/Commons.awk\"\n@include \"include/Utils.awk\"\n@include \"include/LanguageData.awk\"\n@include \"include/LanguageHelper.awk\"\n@include \"metainfo.awk\"\n\nfunction init() {\n    BuildPath            = \"build/\"\n    Trans                = BuildPath Command\n    TransAwk             = Trans \".awk\"\n\n    ManPath              = \"man/\"\n    Man                  = ManPath Command \".1\"\n    ManTemplate          = Man \".template.md\"\n    ManMarkdown          = Man \".md\"\n    ManHtmlTemplate      = Man \".template.html\"\n    ManHtml              = Man \".html\"\n\n    PagesPath            = \"gh-pages/\"\n    BadgeDownload        = PagesPath \"images/badge-download\"\n    BadgeRelease         = PagesPath \"images/badge-release\"\n    Index                = PagesPath \"index.md\"\n\n    ReadmePath           = \"./\"\n    ReadmeTemplate       = ReadmePath \"README.template.md\"\n    Readme               = ReadmePath \"README.md\"\n\n    WikiPath             = \"wiki/\"\n    WikiHome             = WikiPath \"Home.md\"\n    WikiLanguages        = WikiPath \"Languages.md\"\n    WikiLanguagesHtml    = WikiLanguages \".html\"\n\n    RegistryPath         = \"registry/\"\n    MainRegistryTemplate = RegistryPath \"index.template.trans\"\n    MainRegistry         = RegistryPath \"index.trans\"\n}\n\nfunction man(    text) {\n    text = readFrom(ManTemplate)\n    gsub(/\\$Version\\$/, Version, text)\n    gsub(/\\$ReleaseDate\\$/, ReleaseDate, text)\n    writeTo(text, ManMarkdown)\n\n    if (fileExists(ManHtmlTemplate))\n        system(\"pandoc -s -f markdown-smart -t html --toc --toc-depth 1 --template \" ManHtmlTemplate \" \" ManMarkdown \" -o \" ManHtml)\n    return system(\"pandoc -s -f markdown-smart -t man \" ManMarkdown \" -o \" Man)\n}\n\nfunction readme(    code, col, cols, content, group, i, iso, j, num, r, rows, text) {\n    text = readFrom(ReadmeTemplate)\n\n    content = getOutput(\"gawk -f translate.awk -- -no-ansi -h\")\n    gsub(/\\$usage\\$/, content, text)\n\n    initBiDi(); initLocale()\n    # number of language codes with stable support\n    num = 0\n    for (code in Locale)\n        if (Locale[code][\"support\"] != \"unstable\")\n            num++\n    rows = int(num / 3) + (num % 3 ? 1 : 0)\n    cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR\n    i = 0\n    saveSortedIn = PROCINFO[\"sorted_in\"]\n    PROCINFO[\"sorted_in\"] = \"compName\"\n    for (code in Locale) {\n        # Ignore unstable languages\n        if (Locale[code][\"support\"] == \"unstable\") continue\n\n        col = int(i / rows)\n        append(cols[col], code)\n        i++\n    }\n    PROCINFO[\"sorted_in\"] = saveSortedIn\n    r = \"| Language | Code | Language | Code | Language | Code |\" RS \\\n        \"| :------: | :--: | :------: | :--: | :------: | :--: |\" RS\n    for (i = 0; i < rows; i++) {\n        r = r \"| \"\n        for (j = 0; j < 3; j++)\n            if (cols[j][i]) {\n                split(getISO(cols[j][i]), group, \"-\")\n                iso = group[1]\n\n                r = r \"**[\" getName(cols[j][i]) \"](\" \"http://en.wikipedia.org/wiki/ISO_639:\" iso \\\n                    \")** <br/> **\" getEndonym(cols[j][i]) \"** | **`\" cols[j][i] \"`** | \"\n            }\n        r = r RS\n    }\n    gsub(/\\$code-list\\$/, r, text)\n\n    content = readFrom(WikiHome)\n    gsub(/\\$wiki-home\\$/, content, text)\n\n    writeTo(text, Readme)\n    return 0\n}\n\nfunction wiki(    code, group, iso, language, saveSortedIn) {\n    initBiDi(); initLocale()\n\n    #print \"***\" length(Locale) \"*** *languages in total. \"\n    print \"*Generated from the source code of Translate Shell \" Version \".*\\n\" > WikiLanguages\n    print \"*Version: [English](https://github.com/soimort/translate-shell/wiki/Languages) \" \\\n        \"| [Chinese Simplified](https://github.com/soimort/translate-shell/wiki/Languages-%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29)*\\n\" > WikiLanguages\n    print \"| Code | Name | Family | [Writing system](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts) | Is [RTL](http://en.wikipedia.org/wiki/Right-to-left)? | Has dictionary? |\" > WikiLanguages\n    print \"| :--: | ---: | -----: | :------------: | :---------------------------------------------------: | :-------------: |\" > WikiLanguages\n    saveSortedIn = PROCINFO[\"sorted_in\"]\n    PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n    for (code in Locale) {\n        # Ignore unstable languages and non-languages\n        if (Locale[code][\"support\"] == \"unstable\") continue\n        if (Locale[code][\"status\"] == \"non-language\") continue\n\n        split(getISO(code), group, \"-\")\n        iso = group[1]\n        #split(getName(code), group, \" \")\n        #language = length(group) == 1 ? group[1] \"_language\" :\n        #    group[2] ~ /^\\(.*\\)$/ ? group[1] \"_language\" : join(group, \"_\")\n        print sprintf(\"| **`%s`** <br/> [`%s`](%s) | **[%s](%s)** <br/> **%s** | %s | `%s` | %s | %s |\",\n                      getCode(code), iso, \"http://www.ethnologue.com/language/\" iso,\n                      getName(code), \"http://en.wikipedia.org/wiki/ISO_639:\" iso, getEndonym(code),\n                      getFamily(code), getScript(code),\n                      isRTL(code) ? \"✓\" : NULLSTR,\n                      hasDictionary(code) ? \"✓\" : NULLSTR) > WikiLanguages\n    }\n    PROCINFO[\"sorted_in\"] = saveSortedIn\n\n    return system(\"pandoc -s -t html \" WikiLanguages \" -o \" WikiLanguagesHtml)\n}\n\nfunction doc() {\n    man()\n    readme()\n    wiki()\n    return 0\n}\n\nfunction readSqueezed(fileName, squeezed,    group, line, ret) {\n    if (fileName ~ /\\*$/ || fileName ~ /_$/) # glob simulation\n        return readSqueezed(fileName \".awk\", squeezed)\n\n    ret = NULLSTR\n    if (fileExists(fileName))\n        while (getline line < fileName) {\n            match(line, /^[[:space:]]*@include[[:space:]]*\"(.*)\"$/, group)\n            if (RSTART) { # @include\n                if (group[1] ~ /\\.awk$/)\n                    append(Includes, group[1])\n\n                if (ret) ret = ret RS\n                ret = ret readSqueezed(group[1], squeezed)\n            } else if (!squeezed || line = squeeze(line)) { # effective LOC\n                if (ret) ret = ret RS\n                ret = ret line\n            }\n        }\n    return ret\n}\n\nfunction build(target, type,    i, group, inline, line, temp) {\n    # Default target: bash\n    if (!target) target = \"bash\"\n\n    (\"mkdir -p \" parameterize(BuildPath)) | getline\n\n    if (target == \"bash\" || target == \"zsh\") {\n\n        print \"#!/usr/bin/env \" target > Trans\n\n        if (fileExists(\"DISCLAIMER\")) {\n            print \"#\" > Trans\n            while (getline line < \"DISCLAIMER\")\n                print \"# \" line > Trans\n            print \"#\" > Trans\n        }\n\n        print \"export TRANS_ENTRY=\\\"$0\\\"\" > Trans\n        print \"if [[ ! $LANG =~ (UTF|utf)-?8$ ]]; then export LANG=en_US.UTF-8; fi\" > Trans\n\n        print \"read -r -d '' TRANS_PROGRAM << 'EOF'\" > Trans\n        print readSqueezed(EntryPoint, TRUE) > Trans\n        print \"EOF\" > Trans\n\n        print \"read -r -d '' TRANS_MANPAGE << 'EOF'\" > Trans\n        if (fileExists(Man))\n            while (getline line < Man)\n                print line > Trans\n        print \"EOF\" > Trans\n        print \"export TRANS_MANPAGE\" > Trans\n\n        if (type == \"release\")\n            print \"export TRANS_BUILD=release\" temp > Trans\n        else {\n            temp = getGitHead()\n            if (temp)\n                print \"export TRANS_BUILD=git:\" temp > Trans\n        }\n\n        print \"gawk -f <(echo -E \\\"$TRANS_PROGRAM\\\") - \\\"$@\\\"\" > Trans\n\n        (\"chmod +x \" parameterize(Trans)) | getline\n\n        # Rebuild EntryScript\n        print \"#!/bin/sh\" > EntryScript\n        print \"export TRANS_DIR=`dirname $0`\" > EntryScript\n        print \"gawk \\\\\" > EntryScript\n        for (i = 0; i < length(Includes) - 1; i++)\n            print \"-i \\\"${TRANS_DIR}/\" Includes[i] \"\\\" \\\\\" > EntryScript\n        print \"-f \\\"${TRANS_DIR}/\" Includes[i] \"\\\" -- \\\"$@\\\"\" > EntryScript\n        (\"chmod +x \" parameterize(EntryScript)) | getline\n        return 0\n\n    } else if (target == \"awk\" || target == \"gawk\") {\n\n        \"uname -s\" | getline temp\n        print (temp == \"Darwin\" ?\n               \"#!/usr/bin/env gawk -f\" : # macOS\n               \"#!/usr/bin/gawk -f\") > TransAwk\n\n        print readSqueezed(EntryPoint, TRUE) > TransAwk\n\n        (\"chmod +x \" parameterize(TransAwk)) | getline\n        return 0\n\n    } else {\n\n        w(\"[FAILED] Unknown target: \" ansi(\"underline\", target))\n        w(\"         Supported targets: \"                                \\\n          ansi(\"underline\", \"bash\") \", \"                                \\\n          ansi(\"underline\", \"zsh\") \", \"                                 \\\n          ansi(\"underline\", \"gawk\"))\n        return 1\n\n    }\n}\n\nfunction clean() {\n    (\"rm -f \" BuildPath Command \"*\") | getline\n    return 0\n}\n\nfunction release(    content, group, sha1, size, temp, text) {\n    d(\"Updating registry ...\")\n    # Update registry\n    text = readFrom(MainRegistryTemplate)\n    gsub(/\\$Version\\$/, Version, text)\n    writeTo(text, MainRegistry)\n\n    d(\"Updating gh-pages/images ...\")\n    # Update gh-pages/images/badge-release\n    text = readFrom(BadgeRelease \".temp\")\n    gsub(/\\$Version\\$/, Version, text)\n    writeTo(text, BadgeRelease)\n    system(\"save-to-png \" BadgeRelease)\n    # Update gh-pages/images/badge-download\n    (\"wc -c \" Trans) | getline temp\n    split(temp, group)\n    size = int(group[1] / 1000)\n    text = readFrom(BadgeDownload \".temp\")\n    gsub(/\\$Size\\$/, size, text)\n    writeTo(text, BadgeDownload)\n    system(\"save-to-png \" BadgeDownload)\n\n    d(\"Updating gh-pages/index.md ...\")\n    # Update gh-pages/index.md\n    (\"sha1sum \" Trans) | getline temp\n    split(temp, group)\n    sha1 = group[1]\n    content = readFrom(Readme)\n    text = readFrom(Index \".temp\")\n    gsub(/\\$sha1\\$/, sha1, text)\n    gsub(/\\$Version\\$/, Version, text)\n    gsub(/\\$readme\\$/, content, text)\n    writeTo(text, Index)\n\n    return 0\n}\n\nfunction test() {\n    return 0\n}\n\nBEGIN {\n    init()\n\n    pos = 0\n    while (ARGV[++pos]) {\n        # -target TARGET\n        match(ARGV[pos], /^--?target(=(.*)?)?$/, group)\n        if (RSTART) {\n            target = tolower(group[2] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -type TYPE\n        match(ARGV[pos], /^--?type(=(.*)?)?$/, group)\n        if (RSTART) {\n            type = tolower(group[2] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # TASK\n        match(ARGV[pos], /^[^\\-]/, group)\n        if (RSTART) {\n            append(tasks, ARGV[pos])\n            continue\n        }\n    }\n\n    # Default task: build\n    if (!anything(tasks)) tasks[0] = \"build\"\n\n    for (i = 0; i < length(tasks); i++) {\n        task = tasks[i]\n        status = 0\n        switch (task) {\n\n        case \"man\":\n            status = man()\n            break\n\n        case \"readme\":\n            status = readme()\n            break\n\n        case \"wiki\":\n            status = wiki()\n            break\n\n        case \"doc\":\n            status = doc()\n            break\n\n        case \"build\":\n            status = build(target, type)\n            break\n\n        case \"clean\":\n            status = clean()\n            break\n\n        case \"release\":\n            status = release()\n            break\n\n        case \"test\":\n            status = test()\n            break\n\n        default: # unknown task\n            status = -1\n        }\n\n        if (status == 0) {\n            d(\"[OK] Task \" ansi(\"bold\", task) \" completed.\")\n        } else if (status < 0) {\n            w(\"[FAILED] Unknown task: \" ansi(\"bold\", task))\n            exit 1\n        } else {\n            w(\"[FAILED] Task \" ansi(\"bold\", task) \" failed.\")\n            exit 1\n        }\n    }\n}\n"
  },
  {
    "path": "google-translate-mode.el",
    "content": ";;; google-translate-mode.el --- Google Translate minor mode\n\n;; This file is distributed as part of translate-shell\n;; URL: https://github.com/soimort/translate-shell\n;; Last-Updated: 2015-04-08 Wed\n\n;; This is free and unencumbered software released into the public domain.\n\n;;; Code:\n\n(defcustom trans-command \"trans\"\n  \"trans command name.\"\n  :type 'string\n  :group 'google-translate-mode)\n\n(defcustom trans-verbose-p nil\n  \"Is in verbose mode. (default: nil)\"\n  :type 'boolean\n  :group 'google-translate-mode)\n\n(defcustom trans-source \"auto\"\n  \"Source language. (default: auto)\"\n  :type 'string\n  :group 'google-translate-mode)\n\n(defcustom trans-target \"en\"\n  \"Target language. (default: en)\"\n  :type 'string\n  :group 'google-translate-mode)\n\n(defun trans (verbose source target text)\n  (shell-command-to-string\n   (concat trans-command\n           (if verbose \"\" \" -b\")\n           (if source (concat \" -s \" source) \"\")\n           (if target (concat \" -t \" target) \"\")\n           \" \" text)))\n\n(defun show-translation ()\n  \"Show translation of the current word in message buffer.\"\n  (interactive)\n  (message\n   (trans trans-verbose-p trans-source trans-target (current-word))))\n\n(defun view-translation ()\n  \"View verbose translation of the current word in popup dialog.\"\n  (interactive)\n  (let ((translation\n         (trans t trans-source trans-target (current-word))))\n    (x-popup-menu t (list \"Translation\"\n                          (list \"PANE\"\n                                (list translation nil))))))\n\n(defun insert-translation ()\n  \"Insert translation of the current word right after.\"\n  (interactive)\n  (insert \" \")\n  (insert\n   (trans trans-verbose-p trans-source trans-target (current-word))))\n\n(defvar google-translate-mode-keymap\n  (let\n      ((map (make-sparse-keymap)))\n    (define-key map (kbd \"C-c -\") 'show-translation)\n    (define-key map (kbd \"C-c =\") 'view-translation)\n    (define-key map (kbd \"C-c +\") 'insert-translation)\n    map)\n  \"Keymap for Google Translate minor mode.\")\n\n(define-minor-mode google-translate-mode\n  \"Google Translate\"\n  :keymap google-translate-mode-keymap)\n\n(provide 'google-translate-mode)\n"
  },
  {
    "path": "include/Commons.awk",
    "content": "####################################################################\n# Commons.awk                                                      #\n####################################################################\n\n# Initialize constants.\nfunction initConst() {\n    NULLSTR = \"\"\n    NONE = \"\\0\"\n    TRUE = 1\n\n    STDIN  = \"/dev/stdin\"\n    STDOUT = \"/dev/stdout\"\n    STDERR = \"/dev/stderr\"\n\n    SUPOUT = \" > /dev/null \"  # suppress output\n    SUPERR = \" 2> /dev/null \" # suppress error\n    PIPE = \" | \"\n}\n\n\n\n## Arrays:\n\n# Return 1 if the array contains anything; otherwise return 0.\nfunction anything(array,\n                  ####\n                  i) {\n    for (i in array)\n        if (array[i]) return 1\n    return 0\n}\n\n# Return 1 if the value is non-empty or an array that contains anything;\n# Otherwise, return 0.\nfunction exists(value) {\n    if (isarray(value))\n        return anything(value)\n    else\n        return value ? 1 : 0\n}\n\n# Return an element if it belongs to the array;\n# Otherwise, return a null string.\nfunction belongsTo(element, array,\n                   ####\n                   i) {\n    for (i in array)\n        if (element == array[i]) return element\n    return NULLSTR\n}\n\n# Return non-zero if two values are identical;\n# Otherwise, return 0.\nfunction identical(x, y,\n                   ####\n                   i) {\n    if (!isarray(x) && !isarray(y))\n        return x == y\n    else if (isarray(x) && isarray(y)) {\n        if (length(x) != length(y)) return 0\n        for (i in x)\n            if (!identical(x[i], y[i])) return 0\n        return 1\n    } else\n        return 0\n}\n\n# Append an element into an array (zero-based).\nfunction append(array, element) {\n    array[anything(array) ? length(array) : 0] = element\n}\n\n# Comparator function used for controlling array scanning order.\n# Like @ind_num_asc, but compare on index fields separated by SUBSEP.\nfunction compareByIndexFields(i1, v1, i2, v2,\n                              ####\n                              t1, t2, tl, j) {\n    split(i1, t1, SUBSEP)\n    split(i2, t2, SUBSEP)\n    tl = length(t1) < length(t2) ? length(t1) : length(t2)\n    for (j = 1; j <= tl; j++) {\n        if (t1[j] < t2[j])\n            return -1\n        else if (t1[j] > t2[j])\n            return 1\n    }\n    return 0\n}\n\n\n\n## Strings:\n\n# Return non-zero if the string represents a numeral;\n# Otherwise, return 0.\nfunction isnum(string) {\n    return string == string + 0\n}\n\n# Return one of the substrings if the string starts with it;\n# Otherwise, return a null string.\nfunction startsWithAny(string, substrings,\n                       ####\n                       i) {\n    for (i in substrings)\n        if (index(string, substrings[i]) == 1) return substrings[i]\n    return NULLSTR\n}\n\n# Return one of the patterns if the string matches this pattern at the beginning;\n# Otherwise, return a null string.\nfunction matchesAny(string, patterns,\n                    ####\n                    i) {\n    for (i in patterns)\n        if (string ~ \"^\" patterns[i]) return patterns[i]\n    return NULLSTR\n}\n\n# Make the first character of string upper-case.\nfunction ucfirst(string) {\n    if (length(string) >= 2)\n        return toupper(substr(string, 1, 1)) substr(string, 2)\n    else if (length(string) == 1)\n        return toupper(string)\n\n    return NULLSTR\n}\n\n# Replicate a string.\nfunction replicate(string, len,\n                   ####\n                   i, temp) {\n    temp = NULLSTR\n    for (i = 0; i < len; i++)\n        temp = temp string\n    return temp\n}\n\n# Reverse a string.\nfunction reverse(string,\n                 ####\n                 i, temp) {\n    temp = NULLSTR\n    for (i = length(string); i > 0; i--)\n        temp = temp substr(string, i, 1);\n    return temp\n}\n\n# Join an array into one string;\n# Return the string.\nfunction join(array, separator, sortedIn, preserveNull,\n              ####\n              i, j, saveSortedIn, temp) {\n    # Default parameter\n    if (!sortedIn)\n        sortedIn = \"compareByIndexFields\"\n\n    temp = NULLSTR\n    j = 0\n    if (isarray(array)) {\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = sortedIn\n        for (i in array)\n            if (preserveNull || array[i] != NULLSTR)\n                temp = j++ ? temp separator array[i] : array[i]\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n    } else\n        temp = array\n\n    return temp\n}\n\n# Split a string into characters.\nfunction explode(string, array) {\n    split(string, array, NULLSTR)\n}\n\n# Return the real character represented by an escape sequence.\n# Example: escapeChar(\"n\") returns \"\\n\".\n# See: <https://en.wikipedia.org/wiki/Escape_character>\n#      <https://en.wikipedia.org/wiki/Escape_sequences_in_C>\nfunction escapeChar(char) {\n    switch (char) {\n    case \"b\":\n        return \"\\b\" # Backspace\n    case \"f\":\n        return \"\\f\" # Formfeed\n    case \"n\":\n        return \"\\n\" # Newline (Line Feed)\n    case \"r\":\n        return \"\\r\" # Carriage Return\n    case \"t\":\n        return \"\\t\" # Horizontal Tab\n    case \"v\":\n        return \"\\v\" # Vertical Tab\n    case \"u0026\":\n        return \"&\" # Unicode Character 'AMPERSAND'\n    case \"u003c\":\n        return \"<\" # Unicode Character 'LESS-THAN SIGN'\n    case \"u003d\":\n        return \"=\" # Unicode Character 'EQUALS SIGN'\n    case \"u003e\":\n        return \">\" # Unicode Character 'GREATER-THAN SIGN'\n    case \"u200b\":\n        return \"\" # Unicode Character 'ZERO WIDTH SPACE'\n    case \"u200c\":\n        return \"\" # Unicode Character 'ZERO WIDTH NON-JOINER'\n    default:\n        return char\n    }\n}\n\n# Convert a literal-formatted string into its original string.\nfunction literal(string,\n                 ####\n                 c, cc, escaping, i, s) {\n    if (string !~ /^\".*\"$/)\n        return string\n\n    explode(string, s)\n    string = NULLSTR\n    escaping = 0\n    for (i = 2; i < length(s); i++) {\n        c = s[i]\n        if (escaping) {\n            if (cc) {\n                cc = cc c\n                if (length(cc) == 5) {\n                    string = string escapeChar(cc)\n                    escaping = 0 # escape ends\n                    cc = NULLSTR\n                }\n            } else if (c == \"u\") {\n                cc = c\n            } else {\n                string = string escapeChar(c)\n                escaping = 0 # escape ends\n            }\n        } else {\n            if (c == \"\\\\\")\n                escaping = 1 # escape begins\n            else\n                string = string c\n        }\n    }\n    return string\n}\n\n# Return the escaped string.\nfunction escape(string) {\n    gsub(/\\\\/, \"\\\\\\\\\", string) # substitute backslashes first\n    gsub(/\"/, \"\\\\\\\"\", string)\n\n    return string\n}\n\n# Reverse of escape(string).\nfunction unescape(string) {\n    gsub(/\\\\\"/, \"\\\"\", string)\n    gsub(/\\\\\\\\/, \"\\\\\", string) # substitute backslashes last\n\n    return string\n}\n\n# Return the escaped, quoted string.\nfunction parameterize(string, quotationMark) {\n    if (!quotationMark)\n        quotationMark = \"'\"\n\n    if (quotationMark == \"'\") {\n        gsub(/'/, \"'\\\\''\", string)\n        return \"'\" string \"'\"\n    } else {\n        return \"\\\"\" escape(string) \"\\\"\"\n    }\n}\n\n# Reverse of parameterize(string, quotationMark).\nfunction unparameterize(string,    temp) {\n    match(string, /^'(.*)'$/, temp)\n    if (temp[0]) { # use temp[0] (there IS a match for quoted empty string)\n        string = temp[1]\n        gsub(/'\\\\''/, \"'\", string)\n        return string\n    }\n    match(string, /^\"(.*)\"$/, temp)\n    if (temp[0]) {\n        string = temp[1]\n        return unescape(string)\n    }\n    return string\n}\n\n# Convert any value to human-readable string.\nfunction toString(value, inline, heredoc, valOnly, numSub, level, sortedIn,\n                  ####\n                  i, items, j, k, p, saveSortedIn, temp, v) {\n    if (!level) level = 0\n    if (!sortedIn)\n        sortedIn = \"compareByIndexFields\"\n\n    if (isarray(value)) {\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = sortedIn\n        p = 0\n        for (i in value) {\n            split(i, j, SUBSEP); k = join(j, \",\")\n            if (!numSub || !isnum(k)) k = parameterize(k, \"\\\"\")\n            v = toString(value[i], inline, heredoc, valOnly, numSub, level + 1, sortedIn)\n            if (!isarray(value[i])) v = parameterize(v, \"\\\"\")\n            if (valOnly)\n                items[p++] = inline ? v : (replicate(\"\\t\", level) v)\n            else\n                items[p++] = inline ? (k \": \" v) :\n                    (replicate(\"\\t\", level) k \"\\t\" v)\n        }\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n        temp = inline ? join(items, \", \") :\n            (\"\\n\" join(items, \"\\n\") \"\\n\" replicate(\"\\t\", level))\n        temp = valOnly ? (\"[\" temp \"]\") : (\"{\" temp \"}\")\n        return temp\n    } else {\n        if (heredoc)\n            return \"'''\\n\" value \"\\n'''\"\n        else\n            return value\n    }\n}\n\n# Squeeze a source line of AWK code.\nfunction squeeze(line, preserveIndent) {\n    # Remove preceding spaces if indentation not preserved\n    if (!preserveIndent)\n        gsub(/^[[:space:]]+/, NULLSTR, line)\n    # Remove comment\n    gsub(/^[[:space:]]*#.*$/, NULLSTR, line)\n    # Remove in-line comment\n    gsub(/#[^\"/]*$/, NULLSTR, line)\n    # Remove trailing spaces\n    gsub(/[[:space:]]+$/, NULLSTR, line)\n    gsub(/[[:space:]]+\\\\$/, \"\\\\\", line)\n\n    return line\n}\n\n# Return 0 if the string starts with '0', 'f', 'n' or 'off';\n# Otherwise, return 1.\nfunction yn(string) {\n    return (tolower(string) ~ /^([0fn]|off)/) ? 0 : 1\n}\n\n\n\n## Display & Debugging:\n\n# Initialize ANSI escape codes for SGR (Select Graphic Rendition).\n# (ANSI X3.64 Standard Control Sequences)\n# See: <https://en.wikipedia.org/wiki/ANSI_escape_code>\nfunction initAnsiCode() {\n    # Dumb terminal: no ANSI escape code whatsoever\n    if (ENVIRON[\"TERM\"] == \"dumb\") return\n\n    AnsiCode[\"reset\"]         = AnsiCode[0] = \"\\33[0m\"\n\n    AnsiCode[\"bold\"]          = \"\\33[1m\"\n    AnsiCode[\"underline\"]     = \"\\33[4m\"\n    AnsiCode[\"negative\"]      = \"\\33[7m\"\n    AnsiCode[\"no bold\"]       = \"\\33[22m\" # SGR code 21 (bold off) not widely supported\n    AnsiCode[\"no underline\"]  = \"\\33[24m\"\n    AnsiCode[\"positive\"]      = \"\\33[27m\"\n\n    AnsiCode[\"black\"]         = \"\\33[30m\"\n    AnsiCode[\"red\"]           = \"\\33[31m\"\n    AnsiCode[\"green\"]         = \"\\33[32m\"\n    AnsiCode[\"yellow\"]        = \"\\33[33m\"\n    AnsiCode[\"blue\"]          = \"\\33[34m\"\n    AnsiCode[\"magenta\"]       = \"\\33[35m\"\n    AnsiCode[\"cyan\"]          = \"\\33[36m\"\n    AnsiCode[\"gray\"]          = \"\\33[37m\"\n\n    AnsiCode[\"default\"]       = \"\\33[39m\"\n\n    AnsiCode[\"dark gray\"]     = \"\\33[90m\"\n    AnsiCode[\"light red\"]     = \"\\33[91m\"\n    AnsiCode[\"light green\"]   = \"\\33[92m\"\n    AnsiCode[\"light yellow\"]  = \"\\33[93m\"\n    AnsiCode[\"light blue\"]    = \"\\33[94m\"\n    AnsiCode[\"light magenta\"] = \"\\33[95m\"\n    AnsiCode[\"light cyan\"]    = \"\\33[96m\"\n    AnsiCode[\"white\"]         = \"\\33[97m\"\n}\n\n# Return ANSI escaped string.\nfunction ansi(code, text) {\n    switch (code) {\n    case \"bold\":\n        return AnsiCode[code] text AnsiCode[\"no bold\"]\n    case \"underline\":\n        return AnsiCode[code] text AnsiCode[\"no underline\"]\n    case \"negative\":\n        return AnsiCode[code] text AnsiCode[\"positive\"]\n    default:\n        return AnsiCode[code] text AnsiCode[0]\n    }\n}\n\n# Print warning message.\nfunction w(text) {\n    print ansi(\"yellow\", text) > STDERR\n}\n\n# Print error message.\nfunction e(text) {\n    print ansi(\"bold\", ansi(\"yellow\", text)) > STDERR\n}\n\n# What a terrible failure.\nfunction wtf(text) {\n    print ansi(\"bold\", ansi(\"red\", text)) > STDERR\n}\n\n# Print debugging message.\nfunction d(text) {\n    print ansi(\"gray\", text) > STDERR\n}\n\n# Debug any value.\nfunction da(value, name, inline, heredoc, valOnly, numSub, sortedIn,\n            ####\n            i, j, saveSortedIn) {\n    # Default parameters\n    if (!name)\n        name = \"_\"\n    if (!sortedIn)\n        sortedIn = \"compareByIndexFields\"\n\n    d(name \" = \" toString(value, inline, heredoc, valOnly, numSub, 0, sortedIn))\n    #if (isarray(value)) {\n    #    saveSortedIn = PROCINFO[\"sorted_in\"]\n    #    PROCINFO[\"sorted_in\"] = sortedIn\n    #    for (i in value) {\n    #        split(i, j, SUBSEP)\n    #        da(value[i], sprintf(name \"[%s]\", join(j, \",\")), sortedIn)\n    #    }\n    #    PROCINFO[\"sorted_in\"] = saveSortedIn\n    #} else\n    #    d(name \" = \" value)\n}\n\n# Naive assertion.\nfunction assert(x, message) {\n    if (!message)\n        message = \"[ERROR] Assertion failed.\"\n\n    if (x)\n        return x\n    else\n        e(message)\n}\n\n\n\n## URLs:\n\n# Initialize `UrlEncoding`.\n# See: <https://en.wikipedia.org/wiki/Percent-encoding>\nfunction initUrlEncoding() {\n    UrlEncoding[\"\\t\"] = \"%09\"\n    UrlEncoding[\"\\n\"] = \"%0A\"\n    UrlEncoding[\" \"]  = \"%20\"\n    UrlEncoding[\"!\"]  = \"%21\"\n    UrlEncoding[\"\\\"\"] = \"%22\"\n    UrlEncoding[\"#\"]  = \"%23\"\n    UrlEncoding[\"$\"]  = \"%24\"\n    UrlEncoding[\"%\"]  = \"%25\"\n    UrlEncoding[\"&\"]  = \"%26\"\n    UrlEncoding[\"'\"]  = \"%27\"\n    UrlEncoding[\"(\"]  = \"%28\"\n    UrlEncoding[\")\"]  = \"%29\"\n    UrlEncoding[\"*\"]  = \"%2A\"\n    UrlEncoding[\"+\"]  = \"%2B\"\n    UrlEncoding[\",\"]  = \"%2C\"\n    UrlEncoding[\"-\"]  = \"%2D\"\n    UrlEncoding[\".\"]  = \"%2E\"\n    UrlEncoding[\"/\"]  = \"%2F\"\n    UrlEncoding[\":\"]  = \"%3A\"\n    UrlEncoding[\";\"]  = \"%3B\"\n    UrlEncoding[\"<\"]  = \"%3C\"\n    UrlEncoding[\"=\"]  = \"%3D\"\n    UrlEncoding[\">\"]  = \"%3E\"\n    UrlEncoding[\"?\"]  = \"%3F\"\n    UrlEncoding[\"@\"]  = \"%40\"\n    UrlEncoding[\"[\"]  = \"%5B\"\n    UrlEncoding[\"\\\\\"] = \"%5C\"\n    UrlEncoding[\"]\"]  = \"%5D\"\n    UrlEncoding[\"^\"]  = \"%5E\"\n    UrlEncoding[\"_\"]  = \"%5F\"\n    UrlEncoding[\"`\"]  = \"%60\"\n    UrlEncoding[\"{\"]  = \"%7B\"\n    UrlEncoding[\"|\"]  = \"%7C\"\n    UrlEncoding[\"}\"]  = \"%7D\"\n    UrlEncoding[\"~\"]  = \"%7E\"\n}\n\n# Return the URL-encoded string.\nfunction quote(string,    i, r, s) {\n    r = NULLSTR\n    explode(string, s)\n    for (i = 1; i <= length(s); i++)\n        r = r (s[i] in UrlEncoding ? UrlEncoding[s[i]] : s[i])\n    return r\n}\n\n# Return the URL-decoded string.\nfunction unquote(string,    i, k, r, s, temp) {\n    r = NULLSTR\n    explode(string, s)\n    temp = NULLSTR\n    for (i = 1; i <= length(s); i++)\n        if (temp) {\n            temp = temp s[i]\n            if (length(temp) > 2) {\n                for (k in UrlEncoding)\n                    if (temp == UrlEncoding[k]) {\n                        r = r k\n                        temp = NULLSTR\n                        break\n                    }\n                if (temp) {\n                    r = r temp\n                    temp = NULLSTR\n                }\n            }\n        } else {\n            if (s[i] != \"%\")\n                r = r s[i]\n            else\n                temp = s[i]\n        }\n    if (temp)\n        r = r temp\n    return r\n}\n\n# Initialize `UriSchemes`.\nfunction initUriSchemes() {\n    UriSchemes[0] = \"file://\"\n    UriSchemes[1] = \"http://\"\n    UriSchemes[2] = \"https://\"\n}\n\n\n\n## System:\n\n# Read from a file and return its content.\nfunction readFrom(file,    line, text) {\n    if (!file) file = \"/dev/stdin\"\n    text = NULLSTR\n    while (getline line < file)\n        text = (text ? text \"\\n\" : NULLSTR) line\n    return text\n}\n\n# Write text to file.\nfunction writeTo(text, file) {\n    if (!file) file = \"/dev/stdout\"\n    print text > file\n}\n\n# Return the output of a command.\nfunction getOutput(command,    content, line) {\n    content = NULLSTR\n    while ((command |& getline line) > 0)\n        content = (content ? content \"\\n\" : NULLSTR) line\n    close(command)\n    return content\n}\n\n# Return non-zero if file exists; otherwise return 0.\nfunction fileExists(file) {\n    return !system(\"test -f \" parameterize(file))\n}\n\n# Return non-zero if file exists and is a directory; otherwise return 0.\nfunction dirExists(file) {\n    return !system(\"test -d \" parameterize(file))\n}\n\n# Detect whether a program exists in path.\n# Return the name (or output) if the program call writes anything to stdout;\n# Otherwise, return a null string.\nfunction detectProgram(prog, arg, returnOutput,    command, temp) {\n    command = prog \" \" arg SUPERR\n    command | getline temp\n    close(command)\n    if (returnOutput)\n        return temp\n    if (temp)\n        return prog\n    return NULLSTR\n}\n\n# Return the HEAD revision if the current directory is a git repo;\n# Otherwise return a null string.\nfunction getGitHead(    line, group) {\n    if (fileExists(\".git/HEAD\")) {\n        getline line < \".git/HEAD\"\n        match(line, /^ref: (.*)$/, group)\n        if (fileExists(\".git/\" group[1])) {\n            getline line < (\".git/\" group[1])\n            return substr(line, 1, 7)\n        } else\n            return NULLSTR\n    } else\n        return NULLSTR\n}\n\n\n\nBEGIN {\n    initConst()\n    initAnsiCode()\n    initUrlEncoding()\n    initUriSchemes()\n}\n"
  },
  {
    "path": "include/Help.awk",
    "content": "####################################################################\n# Help.awk                                                         #\n####################################################################\n\n# Return version as a string.\nfunction getVersion(    build, gitHead) {\n    initAudioPlayer()\n    initPager()\n    Platform = Platform ? Platform : detectProgram(\"uname\", \"-s\", 1)\n    if (ENVIRON[\"TRANS_BUILD\"])\n        build = \"-\" ENVIRON[\"TRANS_BUILD\"]\n    else {\n        gitHead = getGitHead()\n        build = gitHead ? \"-git:\" gitHead : \"\"\n    }\n\n    return ansi(\"bold\", sprintf(\"%-22s%s%s\\n\\n\", Name, Version, build)) \\\n        sprintf(\"%-22s%s\\n\", \"platform\", Platform)                      \\\n        sprintf(\"%-22s%s\\n\", \"terminal type\", ENVIRON[\"TERM\"])          \\\n        sprintf(\"%-22s%s\\n\", \"bi-di emulator\", BiDiTerm ? BiDiTerm :\n                \"[N/A]\")                                                \\\n        sprintf(\"%-22s%s\\n\", \"gawk (GNU Awk)\", PROCINFO[\"version\"])     \\\n        sprintf(\"%s\\n\", FriBidi ? FriBidi :\n                \"fribidi (GNU FriBidi) [NOT INSTALLED]\")                \\\n        sprintf(\"%-22s%s\\n\", \"audio player\", AudioPlayer ? AudioPlayer :\n                \"[NOT INSTALLED]\")                                      \\\n        sprintf(\"%-22s%s\\n\", \"terminal pager\", Pager ? Pager :\n                \"[NOT INSTALLED]\")                                      \\\n        sprintf(\"%-22s%s\\n\", \"web browser\", Option[\"browser\"] != NONE ?\n                Option[\"browser\"] :\"[NONE]\")                            \\\n        sprintf(\"%-22s%s (%s)\\n\", \"user locale\", UserLocale, getName(UserLang)) \\\n        sprintf(\"%-22s%s\\n\", \"host language\", Option[\"hl\"])             \\\n        sprintf(\"%-22s%s\\n\", \"source language\", join(Option[\"sls\"], \"+\")) \\\n        sprintf(\"%-22s%s\\n\", \"target language\", join(Option[\"tl\"], \"+\")) \\\n        sprintf(\"%-22s%s\\n\", \"translation engine\", Option[\"engine\"])    \\\n        sprintf(\"%-22s%s\\n\", \"proxy\", Option[\"proxy\"] ? Option[\"proxy\"] :\n                \"[NONE]\")                                               \\\n        sprintf(\"%-22s%s\\n\", \"user-agent\", Option[\"user-agent\"] ? Option[\"user-agent\"] :\n                \"[NONE]\")                                               \\\n        sprintf(\"%-22s%s\\n\", \"ip version\", Option[\"ip-version\"] ? Option[\"ip-version\"] :\n                \"[DEFAULT]\")                                            \\\n        sprintf(\"%-22s%s\\n\", \"theme\", Option[\"theme\"])                  \\\n        sprintf(\"%-22s%s\\n\", \"init file\", InitScript ? InitScript : \"[NONE]\") \\\n        sprintf(\"\\n%-22s%s\", \"Report bugs to:\", \"https://github.com/soimort/translate-shell/issues\")\n}\n\n# Return help message as a string.\nfunction getHelp() {\n    return \"Usage:  \" ansi(\"bold\", Command)                             \\\n        \" [\" ansi(\"underline\", \"OPTIONS\") \"]\"                           \\\n        \" [\" ansi(\"underline\", \"SOURCES\") \"]\"                           \\\n        \":[\" ansi(\"underline\", \"TARGETS\") \"]\"                           \\\n        \" [\" ansi(\"underline\", \"TEXT\") \"]...\" RS                        \\\n        RS \"Information options:\" RS                                    \\\n        ins(1, ansi(\"bold\", \"-V\") \", \" ansi(\"bold\", \"-version\")) RS     \\\n        ins(2, \"Print version and exit.\") RS                            \\\n        ins(1, ansi(\"bold\", \"-H\") \", \" ansi(\"bold\", \"-help\")) RS        \\\n        ins(2, \"Print help message and exit.\") RS                       \\\n        ins(1, ansi(\"bold\", \"-M\") \", \" ansi(\"bold\", \"-man\")) RS         \\\n        ins(2, \"Show man page and exit.\") RS                            \\\n        ins(1, ansi(\"bold\", \"-T\") \", \" ansi(\"bold\", \"-reference\")) RS   \\\n        ins(2, \"Print reference table of languages (in endonyms) and codes, and exit.\") RS \\\n        ins(1, ansi(\"bold\", \"-R\") \", \" ansi(\"bold\", \"-reference-english\")) RS \\\n        ins(2, \"Print reference table of languages (in English names) and codes, and exit.\") RS \\\n        ins(1, ansi(\"bold\", \"-S\") \", \" ansi(\"bold\", \"-list-engines\")) RS \\\n        ins(2, \"List available translation engines and exit.\") RS       \\\n        ins(1, ansi(\"bold\", \"-list-languages\")) RS                      \\\n        ins(2, \"List all languages (in endonyms) and exit.\") RS         \\\n        ins(1, ansi(\"bold\", \"-list-languages-english\")) RS              \\\n        ins(2, \"List all languages (in English names) and exit.\") RS    \\\n        ins(1, ansi(\"bold\", \"-list-codes\")) RS                          \\\n        ins(2, \"List all codes and exit.\") RS                           \\\n        ins(1, ansi(\"bold\", \"-list-all\")) RS                            \\\n        ins(2, \"List all languages (endonyms and English names) and codes, and exit.\") RS \\\n        ins(1, ansi(\"bold\", \"-L \") ansi(\"underline\", \"CODES\")           \\\n            \", \" ansi(\"bold\", \"-linguist \") ansi(\"underline\", \"CODES\")) RS \\\n        ins(2, \"Print details of languages and exit.\") RS               \\\n        ins(1, ansi(\"bold\", \"-U\") \", \" ansi(\"bold\", \"-upgrade\")) RS     \\\n        ins(2, \"Check for upgrade of this program.\") RS                 \\\n        RS \"Translator options:\" RS                                     \\\n        ins(1, ansi(\"bold\", \"-e \") ansi(\"underline\", \"ENGINE\")          \\\n            \", \" ansi(\"bold\", \"-engine \") ansi(\"underline\", \"ENGINE\")) RS \\\n        ins(2, \"Specify the translation engine to use.\") RS             \\\n        RS \"Display options:\" RS                                        \\\n        ins(1, ansi(\"bold\", \"-verbose\")) RS                             \\\n        ins(2, \"Verbose mode. (default)\") RS                            \\\n        ins(1, ansi(\"bold\", \"-b\") \", \" ansi(\"bold\", \"-brief\")) RS       \\\n        ins(2, \"Brief mode.\") RS                                        \\\n        ins(1, ansi(\"bold\", \"-d\") \", \" ansi(\"bold\", \"-dictionary\")) RS  \\\n        ins(2, \"Dictionary mode.\") RS                                   \\\n        ins(1, ansi(\"bold\", \"-identify\")) RS                            \\\n        ins(2, \"Language identification.\") RS                           \\\n        ins(1, ansi(\"bold\", \"-show-original \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show original text or not.\") RS                         \\\n        ins(1, ansi(\"bold\", \"-show-original-phonetics \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show phonetic notation of original text or not.\") RS    \\\n        ins(1, ansi(\"bold\", \"-show-translation \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show translation or not.\") RS                           \\\n        ins(1, ansi(\"bold\", \"-show-translation-phonetics \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show phonetic notation of translation or not.\") RS      \\\n        ins(1, ansi(\"bold\", \"-show-prompt-message \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show prompt message or not.\") RS                        \\\n        ins(1, ansi(\"bold\", \"-show-languages \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show source and target languages or not.\") RS           \\\n        ins(1, ansi(\"bold\", \"-show-original-dictionary \") ansi(\"underline\", \"y/N\")) RS \\\n        ins(2, \"Show dictionary entry of original text or not.\") RS     \\\n        ins(1, ansi(\"bold\", \"-show-dictionary \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show dictionary entry of translation or not.\") RS       \\\n        ins(1, ansi(\"bold\", \"-show-alternatives \") ansi(\"underline\", \"Y/n\")) RS \\\n        ins(2, \"Show alternative translations or not.\") RS              \\\n        ins(1, ansi(\"bold\", \"-w \") ansi(\"underline\", \"NUM\")             \\\n            \", \" ansi(\"bold\", \"-width \") ansi(\"underline\", \"NUM\")) RS   \\\n        ins(2, \"Specify the screen width for padding.\") RS              \\\n        ins(1, ansi(\"bold\", \"-indent \") ansi(\"underline\", \"NUM\")) RS    \\\n        ins(2, \"Specify the size of indent (number of spaces).\") RS     \\\n        ins(1, ansi(\"bold\", \"-theme \") ansi(\"underline\", \"FILENAME\")) RS \\\n        ins(2, \"Specify the theme to use.\") RS                          \\\n        ins(1, ansi(\"bold\", \"-no-theme\")) RS                            \\\n        ins(2, \"Do not use any other theme than default.\") RS           \\\n        ins(1, ansi(\"bold\", \"-no-ansi\")) RS                             \\\n        ins(2, \"Do not use ANSI escape codes.\") RS                      \\\n        ins(1, ansi(\"bold\", \"-no-autocorrect\")) RS                      \\\n        ins(2, \"Do not autocorrect. (if defaulted by the translation engine)\") RS \\\n        ins(1, ansi(\"bold\", \"-no-bidi\")) RS                             \\\n        ins(2, \"Do not convert bidirectional texts.\") RS                \\\n        ins(1, ansi(\"bold\", \"-bidi\")) RS                                \\\n        ins(2, \"Always convert bidirectional texts.\") RS                \\\n        ins(1, ansi(\"bold\", \"-no-warn\")) RS                             \\\n        ins(2, \"Do not write warning messages to stderr.\") RS           \\\n        ins(1, ansi(\"bold\", \"-dump\")) RS                                \\\n        ins(2, \"Print raw API response instead.\") RS                    \\\n        RS \"Audio options:\" RS                                          \\\n        ins(1, ansi(\"bold\", \"-p, -play\")) RS                            \\\n        ins(2, \"Listen to the translation.\") RS                         \\\n        ins(1, ansi(\"bold\", \"-speak\")) RS                               \\\n        ins(2, \"Listen to the original text.\") RS                       \\\n        ins(1, ansi(\"bold\", \"-n \") ansi(\"underline\", \"VOICE\")           \\\n            \", \" ansi(\"bold\", \"-narrator \") ansi(\"underline\", \"VOICE\")) RS \\\n        ins(2, \"Specify the narrator, and listen to the translation.\") RS \\\n        ins(1, ansi(\"bold\", \"-player \") ansi(\"underline\", \"PROGRAM\")) RS \\\n        ins(2, \"Specify the audio player to use, and listen to the translation.\") RS \\\n        ins(1, ansi(\"bold\", \"-no-play\")) RS                             \\\n        ins(2, \"Do not listen to the translation.\") RS                  \\\n        ins(1, ansi(\"bold\", \"-no-translate\")) RS                        \\\n        ins(2, \"Do not translate anything when using -speak.\") RS       \\\n        ins(1, ansi(\"bold\", \"-download-audio\")) RS                      \\\n        ins(2, \"Download the audio to the current directory.\") RS       \\\n        ins(1, ansi(\"bold\", \"-download-audio-as \") ansi(\"underline\", \"FILENAME\")) RS \\\n        ins(2, \"Download the audio to the specified file.\") RS          \\\n        RS \"Terminal paging and browsing options:\" RS                   \\\n        ins(1, ansi(\"bold\", \"-v\") \", \" ansi(\"bold\", \"-view\")) RS        \\\n        ins(2, \"View the translation in a terminal pager.\") RS          \\\n        ins(1, ansi(\"bold\", \"-pager \") ansi(\"underline\", \"PROGRAM\")) RS \\\n        ins(2, \"Specify the terminal pager to use, and view the translation.\") RS \\\n        ins(1, ansi(\"bold\", \"-no-view\") \", \" ansi(\"bold\", \"-no-pager\")) RS \\\n        ins(2, \"Do not view the translation in a terminal pager.\") RS   \\\n        ins(1, ansi(\"bold\", \"-browser \") ansi(\"underline\", \"PROGRAM\")) RS \\\n        ins(2, \"Specify the web browser to use.\") RS                    \\\n        ins(1, ansi(\"bold\", \"-no-browser\")) RS                          \\\n        ins(2, \"Do not open the web browser.\") RS                       \\\n        RS \"Networking options:\" RS                                     \\\n        ins(1, ansi(\"bold\", \"-x \") ansi(\"underline\", \"HOST:PORT\")       \\\n            \", \" ansi(\"bold\", \"-proxy \") ansi(\"underline\", \"HOST:PORT\")) RS \\\n        ins(2, \"Use HTTP proxy on given port.\") RS                      \\\n        ins(1, ansi(\"bold\", \"-u \") ansi(\"underline\", \"STRING\")          \\\n            \", \" ansi(\"bold\", \"-user-agent \") ansi(\"underline\", \"STRING\")) RS \\\n        ins(2, \"Specify the User-Agent to identify as.\") RS             \\\n        ins(1, ansi(\"bold\", \"-4\") \", \" ansi(\"bold\", \"-ipv4\")            \\\n            \", \" ansi(\"bold\", \"-inet4-only\")) RS                        \\\n        ins(2, \"Connect only to IPv4 addresses.\") RS                    \\\n        ins(1, ansi(\"bold\", \"-6\") \", \" ansi(\"bold\", \"-ipv6\")            \\\n            \", \" ansi(\"bold\", \"-inet6-only\")) RS                        \\\n        ins(2, \"Connect only to IPv6 addresses.\") RS                    \\\n        RS \"Interactive shell options:\" RS                              \\\n        ins(1, ansi(\"bold\", \"-I\") \", \" ansi(\"bold\", \"-interactive\") \", \" ansi(\"bold\", \"-shell\")) RS \\\n        ins(2, \"Start an interactive shell.\") RS                        \\\n        ins(1, ansi(\"bold\", \"-E\") \", \" ansi(\"bold\", \"-emacs\")) RS       \\\n        ins(2, \"Start the GNU Emacs front-end for an interactive shell.\") RS \\\n        ins(1, ansi(\"bold\", \"-no-rlwrap\")) RS                           \\\n        ins(2, \"Do not invoke rlwrap when starting an interactive shell.\") RS \\\n        RS \"I/O options:\" RS                                            \\\n        ins(1, ansi(\"bold\", \"-i \") ansi(\"underline\", \"FILENAME\")        \\\n            \", \" ansi(\"bold\", \"-input \") ansi(\"underline\", \"FILENAME\")) RS \\\n        ins(2, \"Specify the input file.\") RS                            \\\n        ins(1, ansi(\"bold\", \"-o \") ansi(\"underline\", \"FILENAME\")        \\\n            \", \" ansi(\"bold\", \"-output \") ansi(\"underline\", \"FILENAME\")) RS \\\n        ins(2, \"Specify the output file.\") RS                           \\\n        RS \"Language preference options:\" RS                            \\\n        ins(1, ansi(\"bold\", \"-hl \") ansi(\"underline\", \"CODE\")           \\\n            \", \" ansi(\"bold\", \"-host \") ansi(\"underline\", \"CODE\")) RS   \\\n        ins(2, \"Specify the host (interface) language.\") RS             \\\n        ins(1, ansi(\"bold\", \"-s \") ansi(\"underline\", \"CODES\")           \\\n            \", \" ansi(\"bold\", \"-sl \") ansi(\"underline\", \"CODES\")        \\\n            \", \" ansi(\"bold\", \"-source \") ansi(\"underline\", \"CODES\")    \\\n            \", \" ansi(\"bold\", \"-from \") ansi(\"underline\", \"CODES\")) RS  \\\n        ins(2, \"Specify the source language(s), joined by '+'.\") RS     \\\n        ins(1, ansi(\"bold\", \"-t \") ansi(\"underline\", \"CODES\")           \\\n            \", \" ansi(\"bold\", \"-tl \") ansi(\"underline\", \"CODES\")        \\\n            \", \" ansi(\"bold\", \"-target \") ansi(\"underline\", \"CODES\")    \\\n            \", \" ansi(\"bold\", \"-to \") ansi(\"underline\", \"CODES\")) RS    \\\n        ins(2, \"Specify the target language(s), joined by '+'.\") RS     \\\n        RS \"Text preprocessing options:\" RS                             \\\n        ins(1, ansi(\"bold\", \"-j\") \", \" ansi(\"bold\", \"-join-sentence\")) RS \\\n        ins(2, \"Treat all arguments as one single sentence.\") RS        \\\n        RS \"Other options:\" RS                                          \\\n        ins(1, ansi(\"bold\", \"-no-init\")) RS                             \\\n        ins(2, \"Do not load any initialization script.\") RS             \\\n        RS \"See the man page \" Command \"(1) for more information.\"\n}\n\n# Show man page.\nfunction showMan(    temp) {\n    if (ENVIRON[\"TRANS_MANPAGE\"]) {\n        initPager()\n        Groff = detectProgram(\"groff\", \"--version\")\n        if (Pager && Groff) {\n            temp = \"echo -E \\\"${TRANS_MANPAGE}\\\"\"\n            temp = temp PIPE                                            \\\n                Groff \" -Wall -mtty-char -mandoc -Tutf8 \"               \\\n                \"-rLL=\" Option[\"width\"] \"n -rLT=\" Option[\"width\"] \"n\"\n            switch (Pager) {\n            case \"less\":\n                temp = temp PIPE                                        \\\n                    Pager \" -s -P\\\"\\\\ \\\\Manual page \" Command \"(1) line %lt (press h for help or q to quit)\\\"\"\n                break\n            case \"most\":\n                temp = temp PIPE Pager \" -Cs\"\n                break\n            default: # more\n                temp = temp PIPE Pager\n            }\n            system(temp)\n            return\n        }\n    }\n    if (fileExists(ENVIRON[\"TRANS_DIR\"] \"/man/\" Command \".1\"))\n        system(\"man \" parameterize(ENVIRON[\"TRANS_DIR\"] \"/man/\" Command \".1\") SUPERR)\n    else if (system(\"man \" Command SUPERR))\n        print getHelp()\n}\n\n# Return a reference table of languages as a string.\n# Parameters:\n#     displayName = \"endonym\" or \"name\"\nfunction getReference(displayName,\n                      ####\n                      code, col, cols, colNum, i, j, name, num, offset, r, rows, saveSortedIn,\n                      t1, t2) {\n    # number of language codes with stable support\n    num = 0\n    for (code in Locale) {\n        # only show languages that are supported\n        if (Locale[code][\"supported-by\"])\n           num++\n    }\n    colNum = (Option[\"width\"] >= 104) ? 4 : 3\n    if (colNum == 4) {\n        rows = int(num / 4) + (num % 4 ? 1 : 0)\n        cols[0][0] = cols[1][0] = cols[2][0] = cols[3][0] = NULLSTR\n    } else {\n        rows = int(num / 3) + (num % 3 ? 1 : 0)\n        cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR\n    }\n    i = 0\n    saveSortedIn = PROCINFO[\"sorted_in\"]\n    PROCINFO[\"sorted_in\"] = displayName == \"endonym\" ? \"@ind_num_asc\" :\n        \"compName\"\n    for (code in Locale) {\n        # only show languages that are supported\n        if (Locale[code][\"supported-by\"]) {\n            col = int(i / rows)\n            append(cols[col], code)\n            i++\n        }\n    }\n    PROCINFO[\"sorted_in\"] = saveSortedIn\n\n    if (displayName == \"endonym\") {\n        if (colNum == 4) {  # 4-column\n            offset = int((Option[\"width\"] - 104) / 4)\n            r = \"┌\" replicate(\"─\", 25 + offset) \"┬\" replicate(\"─\", 25 + offset) \\\n                \"┬\" replicate(\"─\", 25 + offset) \"┬\" replicate(\"─\", 25 + offset) \"┐\" RS\n            for (i = 0; i < rows; i++) {\n                r = r \"│\"\n                for (j = 0; j < 4; j++) {\n                    if (cols[j][i]) {\n                        t1 = getDisplay(cols[j][i])\n                        if (length(t1) > 17 + offset)\n                            t1 = substr(t1, 1, 14 + offset) \"...\"\n                        switch (cols[j][i]) { # fix rendered text width\n                            case \"sa\":\n                                t1 = sprintf(\" %-\"21+offset\"s\", t1)\n                                break\n                            case \"he\": case \"dv\":\n                                t1 = sprintf(\" %-\"20+offset\"s\", t1)\n                                break\n                            case \"bo\": case \"or\": case \"ur\":\n                                t1 = sprintf(\" %-\"19+offset\"s\", t1)\n                                break\n                            case \"as\": case \"gom\": case \"mai\":\n                            case \"gu\": case \"hi\": case \"bho\":\n                            case \"ta\": case \"te\": case \"my\":\n                            case \"ne\": case \"pa\": case \"km\":\n                            case \"kn\": case \"yi\": case \"si\":\n                                t1 = sprintf(\" %-\"18+offset\"s\", t1)\n                                break\n                            case \"lzh\": case \"yue\":\n                                t1 = sprintf(\" %-\"15+offset\"s\", t1)\n                                break\n                            case \"ja\": case \"ko\":\n                                t1 = sprintf(\" %-\"14+offset\"s\", t1)\n                                break\n                            case \"zh-CN\": case \"zh-TW\":\n                                t1 = sprintf(\" %-\"13+offset\"s\", t1)\n                                break\n                            default:\n                                if (length(t1) <= 17+offset)\n                                    t1 = sprintf(\" %-\"17+offset\"s\", t1)\n                        }\n                        switch (length(cols[j][i])) {\n                            case 1: case 2: case 3: case 4:\n                                t2 = sprintf(\"- %s │\", ansi(\"bold\", sprintf(\"%4s\", cols[j][i])))\n                                break\n                            case 5:\n                                t2 = sprintf(\"- %s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 6:\n                                t2 = sprintf(\"-%s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 7:\n                                t2 = sprintf(\"-%s\", ansi(\"bold\", cols[j][i]))\n                                break\n                            default:\n                                t2 = ansi(\"bold\", cols[j][i])\n                        }\n                        r = r t1 t2\n                    } else\n                        r = r sprintf(\"%\"25+offset\"s│\", NULLSTR)\n                }\n                r = r RS\n            }\n            r = r \"└\" replicate(\"─\", 25 + offset) \"┴\" replicate(\"─\", 25 + offset) \\\n                \"┴\" replicate(\"─\", 25 + offset) \"┴\" replicate(\"─\", 25 + offset) \"┘\"\n        } else {  # fixed-width 3-column\n            r = \"┌\" replicate(\"─\", 25) \"┬\" replicate(\"─\", 25) \"┬\" replicate(\"─\", 25) \"┐\" RS\n            for (i = 0; i < rows; i++) {\n                r = r \"│\"\n                for (j = 0; j < 3; j++) {\n                    if (cols[j][i]) {\n                        t1 = getDisplay(cols[j][i])\n                        if (length(t1) > 17)\n                            t1 = substr(t1, 1, 14) \"...\"\n                        switch (cols[j][i]) { # fix rendered text width\n                            case \"sa\":\n                                t1 = sprintf(\" %-21s\", t1)\n                                break\n                            case \"he\": case \"dv\":\n                                t1 = sprintf(\" %-20s\", t1)\n                                break\n                            case \"bo\": case \"or\": case \"ur\":\n                                t1 = sprintf(\" %-19s\", t1)\n                                break\n                            case \"as\": case \"gom\": case \"mai\":\n                            case \"gu\": case \"hi\": case \"bho\":\n                            case \"ta\": case \"te\": case \"my\":\n                            case \"ne\": case \"pa\": case \"km\":\n                            case \"kn\": case \"yi\": case \"si\":\n                                t1 = sprintf(\" %-18s\", t1)\n                                break\n                            case \"lzh\": case \"yue\":\n                                t1 = sprintf(\" %-15s\", t1)\n                                break\n                            case \"ja\": case \"ko\":\n                                t1 = sprintf(\" %-14s\", t1)\n                                break\n                            case \"zh-CN\": case \"zh-TW\":\n                                t1 = sprintf(\" %-13s\", t1)\n                                break\n                            default:\n                                if (length(t1) <= 17)\n                                    t1 = sprintf(\" %-17s\", t1)\n                        }\n                        switch (length(cols[j][i])) {\n                            case 1: case 2: case 3: case 4:\n                                t2 = sprintf(\"- %s │\", ansi(\"bold\", sprintf(\"%4s\", cols[j][i])))\n                                break\n                            case 5:\n                                t2 = sprintf(\"- %s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 6:\n                                t2 = sprintf(\"-%s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 7:\n                                t2 = sprintf(\"-%s\", ansi(\"bold\", cols[j][i]))\n                                break\n                            default:\n                                t2 = ansi(\"bold\", cols[j][i])\n                        }\n                        r = r t1 t2\n                    } else\n                        r = r sprintf(\"%25s│\", NULLSTR)\n                }\n                r = r RS\n            }\n            r = r \"└\" replicate(\"─\", 25) \"┴\" replicate(\"─\", 25) \"┴\" replicate(\"─\", 25) \"┘\"\n        }\n    } else {\n        if (colNum == 4) {  # 4-column\n            offset = int((Option[\"width\"] - 104) / 4)\n            r = \"┌\" replicate(\"─\", 25 + offset) \"┬\" replicate(\"─\", 25 + offset) \\\n                \"┬\" replicate(\"─\", 25 + offset) \"┬\" replicate(\"─\", 25 + offset) \"┐\" RS\n            for (i = 0; i < rows; i++) {\n                r = r \"│\"\n                for (j = 0; j < 4; j++) {\n                    if (cols[j][i]) {\n                        t1 = getName(cols[j][i])\n                        if (length(t1) > 17 + offset)\n                            t1 = substr(t1, 1, 14 + offset) \"...\"\n                        t1 = sprintf(\" %-\"17+offset\"s\", t1)\n                        switch (length(cols[j][i])) {\n                            case 1: case 2: case 3: case 4:\n                                t2 = sprintf(\"- %s │\", ansi(\"bold\", sprintf(\"%4s\", cols[j][i])))\n                                break\n                            case 5:\n                                t2 = sprintf(\"- %s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 6:\n                                t2 = sprintf(\"-%s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 7:\n                                t2 = sprintf(\"-%s\", ansi(\"bold\", cols[j][i]))\n                                break\n                            default:\n                                t2 = ansi(\"bold\", cols[j][i])\n                        }\n                        r = r t1 t2\n                    } else\n                        r = r sprintf(\"%\"25+offset\"s│\", NULLSTR)\n                }\n                r = r RS\n            }\n            r = r \"└\" replicate(\"─\", 25 + offset) \"┴\" replicate(\"─\", 25 + offset) \\\n                \"┴\" replicate(\"─\", 25 + offset) \"┴\" replicate(\"─\", 25 + offset) \"┘\"\n        } else {  # fixed-width 3-column\n            r = \"┌\" replicate(\"─\", 25) \"┬\" replicate(\"─\", 25) \"┬\" replicate(\"─\", 25) \"┐\" RS\n            for (i = 0; i < rows; i++) {\n                r = r \"│\"\n                for (j = 0; j < 3; j++) {\n                    if (cols[j][i]) {\n                        t1 = getName(cols[j][i])\n                        if (length(t1) > 17)\n                            t1 = substr(t1, 1, 14) \"...\"\n                        t1 = sprintf(\" %-17s\", t1)\n                        switch (length(cols[j][i])) {\n                            case 1: case 2: case 3: case 4:\n                                t2 = sprintf(\"- %s │\", ansi(\"bold\", sprintf(\"%4s\", cols[j][i])))\n                                break\n                            case 5:\n                                t2 = sprintf(\"- %s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 6:\n                                t2 = sprintf(\"-%s│\", ansi(\"bold\", cols[j][i]))\n                                break\n                            case 7:\n                                t2 = sprintf(\"-%s\", ansi(\"bold\", cols[j][i]))\n                                break\n                            default:\n                                t2 = ansi(\"bold\", cols[j][i])\n                        }\n                        r = r t1 t2\n                    } else\n                        r = r sprintf(\"%25s│\", NULLSTR)\n                }\n                r = r RS\n            }\n            r = r \"└\" replicate(\"─\", 25) \"┴\" replicate(\"─\", 25) \"┴\" replicate(\"─\", 25) \"┘\"\n        }\n    }\n    return r\n}\n\n# Return detailed information of languages as a string.\nfunction getLanguage(codes,    code, i, r, saveSortedIn) {\n    r = NULLSTR\n    if (!isarray(codes))\n        r = getDetails(codes)\n    else if (anything(codes)) {\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n        for (i in codes)\n            r = (r ? r RS prettify(\"target-seperator\", replicate(Option[\"chr-target-seperator\"], Option[\"width\"])) RS \\\n                 : r) getDetails(codes[i])\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n    } else\n        r = getDetails(Option[\"hl\"])\n    return r\n}\n"
  },
  {
    "path": "include/LanguageData.awk",
    "content": "####################################################################\n# LanguageData.awk                                                 #\n####################################################################\n\n# Initialize all locales supported.\n# Mostly ISO 639-1 codes, with a few ISO 639-3 codes.\n# \"family\" : Language family (from Glottolog)\n# \"iso\"    : ISO 639-3 code\n# \"glotto\" : Glottocode\n# \"script\" : Writing system (ISO 15924 script code)\n# See: <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>\n#      <https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes>\n#      <https://en.wikipedia.org/wiki/ISO_15924#List_of_codes>\n#      <http://glottolog.org/>\nfunction initLocale() {\n\n    # Afrikaans\n    Locale[\"af\"][\"name\"]               = \"Afrikaans\"\n    Locale[\"af\"][\"endonym\"]            = \"Afrikaans\"\n    Locale[\"af\"][\"translations-of\"]    = \"Vertalings van %s\"\n    Locale[\"af\"][\"definitions-of\"]     = \"Definisies van %s\"\n    Locale[\"af\"][\"synonyms\"]           = \"Sinonieme\"\n    Locale[\"af\"][\"examples\"]           = \"Voorbeelde\"\n    Locale[\"af\"][\"see-also\"]           = \"Sien ook\"\n    Locale[\"af\"][\"family\"]             = \"Indo-European\"\n    Locale[\"af\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"af\"][\"iso\"]                = \"afr\"\n    Locale[\"af\"][\"glotto\"]             = \"afri1274\"\n    Locale[\"af\"][\"script\"]             = \"Latn\"\n    Locale[\"af\"][\"spoken-in\"]          = \"South Africa; Namibia\"\n    Locale[\"af\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Albanian\n    Locale[\"sq\"][\"name\"]               = \"Albanian\"\n    Locale[\"sq\"][\"endonym\"]            = \"Shqip\"\n    Locale[\"sq\"][\"endonym2\"]           = \"Gjuha shqipe\"\n    Locale[\"sq\"][\"translations-of\"]    = \"Përkthimet e %s\"\n    Locale[\"sq\"][\"definitions-of\"]     = \"Përkufizime të %s\"\n    Locale[\"sq\"][\"synonyms\"]           = \"Sinonime\"\n    Locale[\"sq\"][\"examples\"]           = \"Shembuj\"\n    Locale[\"sq\"][\"see-also\"]           = \"Shihni gjithashtu\"\n    Locale[\"sq\"][\"family\"]             = \"Indo-European\"\n    Locale[\"sq\"][\"branch\"]             = \"Paleo-Balkan\"\n    Locale[\"sq\"][\"iso\"]                = \"sqi\"\n    Locale[\"sq\"][\"glotto\"]             = \"alba1267\"\n    Locale[\"sq\"][\"script\"]             = \"Latn\"\n    Locale[\"sq\"][\"spoken-in\"]          = \"Albania; Kosovo; Montenegro; North Macedonia\"\n    Locale[\"sq\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Amharic\n    Locale[\"am\"][\"name\"]               = \"Amharic\"\n    Locale[\"am\"][\"endonym\"]            = \"አማርኛ\"\n    Locale[\"am\"][\"translations-of\"]    = \"የ %s ትርጉሞች\"\n    Locale[\"am\"][\"definitions-of\"]     = \"የ %s ቃላት ፍችዎች\"\n    Locale[\"am\"][\"synonyms\"]           = \"ተመሳሳይ ቃላት\"\n    Locale[\"am\"][\"examples\"]           = \"ምሳሌዎች\"\n    Locale[\"am\"][\"see-also\"]           = \"የሚከተለውንም ይመልከቱ\"\n    Locale[\"am\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"am\"][\"branch\"]             = \"Semitic\"\n    Locale[\"am\"][\"iso\"]                = \"amh\"\n    Locale[\"am\"][\"glotto\"]             = \"amha1245\"\n    Locale[\"am\"][\"script\"]             = \"Ethi\"\n    Locale[\"am\"][\"spoken-in\"]          = \"Ethiopia\"\n    Locale[\"am\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Arabic (Modern Standard Arabic)\n    Locale[\"ar\"][\"name\"]               = \"Arabic\"\n    Locale[\"ar\"][\"endonym\"]            = \"العربية\"\n    Locale[\"ar\"][\"translations-of\"]    = \"ترجمات %s\"\n    Locale[\"ar\"][\"definitions-of\"]     = \"تعريفات %s\"\n    Locale[\"ar\"][\"synonyms\"]           = \"مرادفات\"\n    Locale[\"ar\"][\"examples\"]           = \"أمثلة\"\n    Locale[\"ar\"][\"see-also\"]           = \"انظر أيضًا\"\n    Locale[\"ar\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"ar\"][\"branch\"]             = \"Semitic\"\n    Locale[\"ar\"][\"iso\"]                = \"ara\"\n    Locale[\"ar\"][\"glotto\"]             = \"stan1318\"\n    Locale[\"ar\"][\"script\"]             = \"Arab\"\n    Locale[\"ar\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"ar\"][\"spoken-in\"]          = \"the Arab world\"\n    Locale[\"ar\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Armenian (Eastern Armenian)\n    Locale[\"hy\"][\"name\"]               = \"Armenian\"\n    Locale[\"hy\"][\"endonym\"]            = \"Հայերեն\"\n    Locale[\"hy\"][\"translations-of\"]    = \"%s-ի թարգմանությունները\"\n    Locale[\"hy\"][\"definitions-of\"]     = \"%s-ի սահմանումները\"\n    Locale[\"hy\"][\"synonyms\"]           = \"Հոմանիշներ\"\n    Locale[\"hy\"][\"examples\"]           = \"Օրինակներ\"\n    Locale[\"hy\"][\"see-also\"]           = \"Տես նաև\"\n    Locale[\"hy\"][\"family\"]             = \"Indo-European\"\n    #Locale[\"hy\"][\"branch\"]            = \"Armenian\"\n    Locale[\"hy\"][\"iso\"]                = \"hye\"\n    Locale[\"hy\"][\"glotto\"]             = \"nucl1235\"\n    Locale[\"hy\"][\"script\"]             = \"Armn\"\n    Locale[\"hy\"][\"spoken-in\"]          = \"Armenia\"\n    Locale[\"hy\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Assamese\n    Locale[\"as\"][\"name\"]               = \"Assamese\"\n    Locale[\"as\"][\"endonym\"]            = \"অসমীয়া\"\n    #Locale[\"as\"][\"translations-of\"]\n    #Locale[\"as\"][\"definitions-of\"]\n    #Locale[\"as\"][\"synonyms\"]\n    #Locale[\"as\"][\"examples\"]\n    #Locale[\"as\"][\"see-also\"]\n    Locale[\"as\"][\"family\"]             = \"Indo-European\"\n    Locale[\"as\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"as\"][\"iso\"]                = \"asm\"\n    Locale[\"as\"][\"glotto\"]             = \"assa1263\"\n    Locale[\"as\"][\"script\"]             = \"Beng\"\n    Locale[\"as\"][\"spoken-in\"]          = \"the northeastern Indian state of Assam\"\n    Locale[\"as\"][\"supported-by\"]       = \"google; bing\"\n\n    # Aymara\n    Locale[\"ay\"][\"name\"]               = \"Aymara\"\n    Locale[\"ay\"][\"endonym\"]            = \"Aymar aru\"\n    #Locale[\"ay\"][\"translations-of\"]\n    #Locale[\"ay\"][\"definitions-of\"]\n    #Locale[\"ay\"][\"synonyms\"]\n    #Locale[\"ay\"][\"examples\"]\n    #Locale[\"ay\"][\"see-also\"]\n    Locale[\"ay\"][\"family\"]             = \"Aymaran\"\n    #Locale[\"ay\"][\"branch\"]            = \"Aymaran\"\n    Locale[\"ay\"][\"iso\"]                = \"aym\"\n    Locale[\"ay\"][\"glotto\"]             = \"nucl1667\"\n    Locale[\"ay\"][\"script\"]             = \"Latn\"\n    Locale[\"ay\"][\"spoken-in\"]          = \"Bolivia; Peru\"\n    Locale[\"ay\"][\"supported-by\"]       = \"google\"\n\n    # Azerbaijani (North Azerbaijani)\n    Locale[\"az\"][\"name\"]               = \"Azerbaijani\"\n    Locale[\"az\"][\"name2\"]              = \"Azeri\"\n    Locale[\"az\"][\"endonym\"]            = \"Azərbaycanca\"\n    Locale[\"az\"][\"translations-of\"]    = \"%s sözünün tərcüməsi\"\n    Locale[\"az\"][\"definitions-of\"]     = \"%s sözünün tərifləri\"\n    Locale[\"az\"][\"synonyms\"]           = \"Sinonimlər\"\n    Locale[\"az\"][\"examples\"]           = \"Nümunələr\"\n    Locale[\"az\"][\"see-also\"]           = \"Həmçinin, baxın:\"\n    Locale[\"az\"][\"family\"]             = \"Turkic\"\n    Locale[\"az\"][\"branch\"]             = \"Oghuz\"\n    Locale[\"az\"][\"iso\"]                = \"aze\"\n    Locale[\"az\"][\"glotto\"]             = \"nort2697\"\n    Locale[\"az\"][\"script\"]             = \"Latn\"\n    Locale[\"az\"][\"spoken-in\"]          = \"Azerbaijan\"\n    Locale[\"az\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Bambara\n    Locale[\"bm\"][\"name\"]               = \"Bambara\"\n    Locale[\"bm\"][\"endonym\"]            = \"Bamanankan\"\n    Locale[\"bm\"][\"endonym2\"]           = \"Bamana\"\n    #Locale[\"bm\"][\"translations-of\"]\n    #Locale[\"bm\"][\"definitions-of\"]\n    #Locale[\"bm\"][\"synonyms\"]\n    #Locale[\"bm\"][\"examples\"]\n    #Locale[\"bm\"][\"see-also\"]\n    Locale[\"bm\"][\"family\"]             = \"Mande\"\n    Locale[\"bm\"][\"branch\"]             = \"Manding\"\n    Locale[\"bm\"][\"iso\"]                = \"bam\"\n    Locale[\"bm\"][\"glotto\"]             = \"bamb1269\"\n    Locale[\"bm\"][\"script\"]             = \"Latn\"\n    Locale[\"bm\"][\"spoken-in\"]          = \"Mali\"\n    Locale[\"bm\"][\"supported-by\"]       = \"google\"\n\n    # Bashkir\n    Locale[\"ba\"][\"name\"]               = \"Bashkir\"\n    Locale[\"ba\"][\"endonym\"]            = \"Башҡортса\"\n    Locale[\"ba\"][\"endonym2\"]           = \"башҡорт теле\"\n    #Locale[\"ba\"][\"translations-of\"]\n    #Locale[\"ba\"][\"definitions-of\"]\n    #Locale[\"ba\"][\"synonyms\"]\n    #Locale[\"ba\"][\"examples\"]\n    #Locale[\"ba\"][\"see-also\"]\n    Locale[\"ba\"][\"family\"]             = \"Turkic\"\n    Locale[\"ba\"][\"branch\"]             = \"Kipchak\"\n    Locale[\"ba\"][\"iso\"]                = \"bak\"\n    Locale[\"ba\"][\"glotto\"]             = \"bash1264\"\n    Locale[\"ba\"][\"script\"]             = \"Cyrl\"\n    Locale[\"ba\"][\"spoken-in\"]          = \"the Republic of Bashkortostan in Russia\"\n    Locale[\"ba\"][\"supported-by\"]       = \"bing; yandex\"\n\n    # Basque\n    Locale[\"eu\"][\"name\"]               = \"Basque\"\n    Locale[\"eu\"][\"endonym\"]            = \"Euskara\"\n    Locale[\"eu\"][\"translations-of\"]    = \"%s esapidearen itzulpena\"\n    Locale[\"eu\"][\"definitions-of\"]     = \"Honen definizioak: %s\"\n    Locale[\"eu\"][\"synonyms\"]           = \"Sinonimoak\"\n    Locale[\"eu\"][\"examples\"]           = \"Adibideak\"\n    Locale[\"eu\"][\"see-also\"]           = \"Ikusi hauek ere\"\n    Locale[\"eu\"][\"family\"]             = \"Language isolate\"\n    #Locale[\"eu\"][\"branch\"]            = \"Language isolate\"\n    Locale[\"eu\"][\"iso\"]                = \"eus\"\n    Locale[\"eu\"][\"glotto\"]             = \"basq1248\"\n    Locale[\"eu\"][\"script\"]             = \"Latn\"\n    Locale[\"eu\"][\"spoken-in\"]          = \"Euskal Herria in Spain and France\"\n    Locale[\"eu\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Belarusian, Cyrillic alphabet\n    Locale[\"be\"][\"name\"]               = \"Belarusian\"\n    Locale[\"be\"][\"endonym\"]            = \"беларуская\"\n    Locale[\"be\"][\"translations-of\"]    = \"Пераклады %s\"\n    Locale[\"be\"][\"definitions-of\"]     = \"Вызначэннi %s\"\n    Locale[\"be\"][\"synonyms\"]           = \"Сінонімы\"\n    Locale[\"be\"][\"examples\"]           = \"Прыклады\"\n    Locale[\"be\"][\"see-also\"]           = \"Гл. таксама\"\n    Locale[\"be\"][\"family\"]             = \"Indo-European\"\n    Locale[\"be\"][\"branch\"]             = \"East Slavic\"\n    Locale[\"be\"][\"iso\"]                = \"bel\"\n    Locale[\"be\"][\"glotto\"]             = \"bela1254\"\n    Locale[\"be\"][\"script\"]             = \"Cyrl\"\n    Locale[\"be\"][\"spoken-in\"]          = \"Belarus\"\n    Locale[\"be\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Bengali / Bangla\n    Locale[\"bn\"][\"name\"]               = \"Bengali\"\n    Locale[\"bn\"][\"name2\"]              = \"Bangla\"\n    Locale[\"bn\"][\"endonym\"]            = \"বাংলা\"\n    Locale[\"bn\"][\"translations-of\"]    = \"%s এর অনুবাদ\"\n    Locale[\"bn\"][\"definitions-of\"]     = \"%s এর সংজ্ঞা\"\n    Locale[\"bn\"][\"synonyms\"]           = \"প্রতিশব্দ\"\n    Locale[\"bn\"][\"examples\"]           = \"উদাহরণ\"\n    Locale[\"bn\"][\"see-also\"]           = \"আরো দেখুন\"\n    Locale[\"bn\"][\"family\"]             = \"Indo-European\"\n    Locale[\"bn\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"bn\"][\"iso\"]                = \"ben\"\n    Locale[\"bn\"][\"glotto\"]             = \"beng1280\"\n    Locale[\"bn\"][\"script\"]             = \"Beng\"\n    Locale[\"bn\"][\"spoken-in\"]          = \"Bangladesh; India\"\n    Locale[\"bn\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Bhojpuri\n    Locale[\"bho\"][\"name\"]              = \"Bhojpuri\"\n    Locale[\"bho\"][\"endonym\"]           = \"भोजपुरी\"\n    #Locale[\"bho\"][\"translations-of\"]\n    #Locale[\"bho\"][\"definitions-of\"]\n    #Locale[\"bho\"][\"synonyms\"]\n    #Locale[\"bho\"][\"examples\"]\n    #Locale[\"bho\"][\"see-also\"]\n    Locale[\"bho\"][\"family\"]            = \"Indo-European\"\n    Locale[\"bho\"][\"branch\"]            = \"Indo-Aryan\"\n    Locale[\"bho\"][\"iso\"]               = \"bho\"\n    Locale[\"bho\"][\"glotto\"]            = \"bhoj1246\"\n    Locale[\"bho\"][\"script\"]            = \"Deva\"\n    Locale[\"bho\"][\"spoken-in\"]         = \"India; Nepal; Fiji\"\n    Locale[\"bho\"][\"supported-by\"]      = \"google\"\n\n    # Bosnian, Latin alphabet\n    Locale[\"bs\"][\"name\"]               = \"Bosnian\"\n    Locale[\"bs\"][\"endonym\"]            = \"Bosanski\"\n    Locale[\"bs\"][\"translations-of\"]    = \"Prijevod za: %s\"\n    Locale[\"bs\"][\"definitions-of\"]     = \"Definicije za %s\"\n    Locale[\"bs\"][\"synonyms\"]           = \"Sinonimi\"\n    Locale[\"bs\"][\"examples\"]           = \"Primjeri\"\n    Locale[\"bs\"][\"see-also\"]           = \"Pogledajte i\"\n    Locale[\"bs\"][\"family\"]             = \"Indo-European\"\n    Locale[\"bs\"][\"branch\"]             = \"South Slavic\"\n    Locale[\"bs\"][\"iso\"]                = \"bos\"\n    Locale[\"bs\"][\"glotto\"]             = \"bosn1245\"\n    Locale[\"bs\"][\"script\"]             = \"Latn\"\n    Locale[\"bs\"][\"spoken-in\"]          = \"Bosnia and Herzegovina\"\n    Locale[\"bs\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Breton\n    Locale[\"br\"][\"name\"]               = \"Breton\"\n    Locale[\"br\"][\"endonym\"]            = \"Brezhoneg\"\n    #Locale[\"br\"][\"translations-of\"]\n    #Locale[\"br\"][\"definitions-of\"]\n    #Locale[\"br\"][\"synonyms\"]\n    #Locale[\"br\"][\"examples\"]\n    #Locale[\"br\"][\"see-also\"]\n    Locale[\"br\"][\"family\"]             = \"Indo-European\"\n    Locale[\"br\"][\"branch\"]             = \"Celtic\"\n    Locale[\"br\"][\"iso\"]                = \"bre\"\n    Locale[\"br\"][\"glotto\"]             = \"bret1244\"\n    Locale[\"br\"][\"script\"]             = \"Latn\"\n    Locale[\"br\"][\"spoken-in\"]          = \"Brittany in France\"\n    Locale[\"br\"][\"supported-by\"]       = \"\"\n\n    # Bulgarian\n    Locale[\"bg\"][\"name\"]               = \"Bulgarian\"\n    Locale[\"bg\"][\"endonym\"]            = \"български\"\n    Locale[\"bg\"][\"translations-of\"]    = \"Преводи на %s\"\n    Locale[\"bg\"][\"definitions-of\"]     = \"Дефиниции за %s\"\n    Locale[\"bg\"][\"synonyms\"]           = \"Синоними\"\n    Locale[\"bg\"][\"examples\"]           = \"Примери\"\n    Locale[\"bg\"][\"see-also\"]           = \"Вижте също\"\n    Locale[\"bg\"][\"family\"]             = \"Indo-European\"\n    Locale[\"bg\"][\"branch\"]             = \"South Slavic\"\n    Locale[\"bg\"][\"iso\"]                = \"bul\"\n    Locale[\"bg\"][\"glotto\"]             = \"bulg1262\"\n    Locale[\"bg\"][\"script\"]             = \"Cyrl\"\n    Locale[\"bg\"][\"spoken-in\"]          = \"Bulgaria\"\n    Locale[\"bg\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Cantonese\n    Locale[\"yue\"][\"name\"]              = \"Cantonese\"\n    Locale[\"yue\"][\"endonym\"]           = \"粵語\"\n    Locale[\"yue\"][\"endonym2\"]          = \"廣東話\"\n    #Locale[\"yue\"][\"translations-of\"]\n    #Locale[\"yue\"][\"definitions-of\"]\n    #Locale[\"yue\"][\"synonyms\"]\n    #Locale[\"yue\"][\"examples\"] \n    #Locale[\"yue\"][\"see-also\"]\n    Locale[\"yue\"][\"family\"]            = \"Sino-Tibetan\"\n    Locale[\"yue\"][\"branch\"]            = \"Sinitic\"\n    Locale[\"yue\"][\"iso\"]               = \"yue\"\n    Locale[\"yue\"][\"glotto\"]            = \"cant1236\"\n    Locale[\"yue\"][\"script\"]            = \"Hant\"\n    Locale[\"yue\"][\"spoken-in\"]         = \"southeastern China; Hong Kong; Macau\"\n    Locale[\"yue\"][\"supported-by\"]      = \"bing\"\n\n    # Catalan (Standard Catalan)\n    Locale[\"ca\"][\"name\"]               = \"Catalan\"\n    Locale[\"ca\"][\"endonym\"]            = \"Català\"\n    Locale[\"ca\"][\"translations-of\"]    = \"Traduccions per a %s\"\n    Locale[\"ca\"][\"definitions-of\"]     = \"Definicions de: %s\"\n    Locale[\"ca\"][\"synonyms\"]           = \"Sinònims\"\n    Locale[\"ca\"][\"examples\"]           = \"Exemples\"\n    Locale[\"ca\"][\"see-also\"]           = \"Vegeu també\"\n    Locale[\"ca\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ca\"][\"branch\"]             = \"Western Romance\"\n    Locale[\"ca\"][\"iso\"]                = \"cat\"\n    Locale[\"ca\"][\"glotto\"]             = \"stan1289\"\n    Locale[\"ca\"][\"script\"]             = \"Latn\"\n    Locale[\"ca\"][\"spoken-in\"]          = \"Països Catalans in Andorra, Spain, France and Italy\"\n    Locale[\"ca\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Cebuano\n    Locale[\"ceb\"][\"name\"]              = \"Cebuano\"\n    Locale[\"ceb\"][\"endonym\"]           = \"Cebuano\"\n    Locale[\"ceb\"][\"translations-of\"]   = \"%s Mga Paghubad sa PULONG_O_HUGPONG SA PAMULONG\"\n    Locale[\"ceb\"][\"definitions-of\"]    = \"Mga kahulugan sa %s\"\n    Locale[\"ceb\"][\"synonyms\"]          = \"Mga Kapulong\"\n    Locale[\"ceb\"][\"examples\"]          = \"Mga pananglitan:\"\n    Locale[\"ceb\"][\"see-also\"]          = \"Kitaa pag-usab\"\n    Locale[\"ceb\"][\"family\"]            = \"Austronesian\"\n    Locale[\"ceb\"][\"branch\"]            = \"Malayo-Polynesian\"\n    Locale[\"ceb\"][\"iso\"]               = \"ceb\"\n    Locale[\"ceb\"][\"glotto\"]            = \"cebu1242\"\n    Locale[\"ceb\"][\"script\"]            = \"Latn\"\n    Locale[\"ceb\"][\"spoken-in\"]         = \"the southern Philippines\"\n    Locale[\"ceb\"][\"supported-by\"]      = \"google; yandex\"\n\n    # Cherokee\n    Locale[\"chr\"][\"name\"]              = \"Cherokee\"\n    Locale[\"chr\"][\"endonym\"]           = \"ᏣᎳᎩ\"\n    #Locale[\"chr\"][\"translations-of\"]\n    #Locale[\"chr\"][\"definitions-of\"]\n    #Locale[\"chr\"][\"synonyms\"]\n    #Locale[\"chr\"][\"examples\"]\n    #Locale[\"chr\"][\"see-also\"]\n    Locale[\"chr\"][\"family\"]            = \"Iroquoian\"\n    #Locale[\"chr\"][\"branch\"]\n    Locale[\"chr\"][\"iso\"]               = \"chr\"\n    Locale[\"chr\"][\"glotto\"]            = \"cher1273\"\n    Locale[\"chr\"][\"script\"]            = \"Cher\"\n    Locale[\"chr\"][\"spoken-in\"]         = \"North America\"\n    Locale[\"chr\"][\"supported-by\"]      = \"\"\n\n    # Chichewa\n    Locale[\"ny\"][\"name\"]               = \"Chichewa\"\n    Locale[\"ny\"][\"name2\"]              = \"Chinyanja\"\n    Locale[\"ny\"][\"endonym\"]            = \"Nyanja\"\n    Locale[\"ny\"][\"translations-of\"]    = \"Matanthauzidwe a %s\"\n    Locale[\"ny\"][\"definitions-of\"]     = \"Mamasulidwe a %s\"\n    Locale[\"ny\"][\"synonyms\"]           = \"Mau ofanana\"\n    Locale[\"ny\"][\"examples\"]           = \"Zitsanzo\"\n    Locale[\"ny\"][\"see-also\"]           = \"Onaninso\"\n    Locale[\"ny\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"ny\"][\"branch\"]             = \"Bantu\"\n    Locale[\"ny\"][\"iso\"]                = \"nya\"\n    Locale[\"ny\"][\"glotto\"]             = \"nyan1308\"\n    Locale[\"ny\"][\"script\"]             = \"Latn\"\n    Locale[\"ny\"][\"spoken-in\"]          = \"Malawi; Zambia\"\n    Locale[\"ny\"][\"supported-by\"]       = \"google\"\n\n    # Chinese (Literary)\n    Locale[\"lzh\"][\"name\"]              = \"Chinese (Literary)\"\n    #Locale[\"lzh\"][\"name2\"]            = \"Literary Chinese\"\n    #Locale[\"lzh\"][\"name3\"]            = \"Classical Chinese\"\n    Locale[\"lzh\"][\"endonym\"]           = \"文言\"\n    Locale[\"lzh\"][\"endonym2\"]          = \"古漢語\"\n    #Locale[\"lzh\"][\"translations-of\"]\n    #Locale[\"lzh\"][\"definitions-of\"]\n    #Locale[\"lzh\"][\"synonyms\"]\n    #Locale[\"lzh\"][\"examples\"]\n    #Locale[\"lzh\"][\"see-also\"]\n    Locale[\"lzh\"][\"family\"]            = \"Sino-Tibetan\"\n    Locale[\"lzh\"][\"branch\"]            = \"Sinitic\"\n    Locale[\"lzh\"][\"iso\"]               = \"lzh\"\n    Locale[\"lzh\"][\"glotto\"]            = \"lite1248\"\n    Locale[\"lzh\"][\"script\"]            = \"Hans\" # should actually be Hant\n    Locale[\"lzh\"][\"spoken-in\"]         = \"ancient China\"\n    Locale[\"lzh\"][\"supported-by\"]      = \"bing\"\n\n    # Chinese (Standard Mandarin), Simplified\n    Locale[\"zh-CN\"][\"name\"]            = \"Chinese (Simplified)\"\n    Locale[\"zh-CN\"][\"endonym\"]         = \"简体中文\"\n    Locale[\"zh-CN\"][\"translations-of\"] = \"%s 的翻译\"\n    Locale[\"zh-CN\"][\"definitions-of\"]  = \"%s的定义\"\n    Locale[\"zh-CN\"][\"synonyms\"]        = \"同义词\"\n    Locale[\"zh-CN\"][\"examples\"]        = \"示例\"\n    Locale[\"zh-CN\"][\"see-also\"]        = \"另请参阅\"\n    Locale[\"zh-CN\"][\"family\"]          = \"Sino-Tibetan\"\n    Locale[\"zh-CN\"][\"branch\"]          = \"Sinitic\"\n    Locale[\"zh-CN\"][\"iso\"]             = \"zho-CN\"\n    Locale[\"zh-CN\"][\"glotto\"]          = \"mand1415\"\n    Locale[\"zh-CN\"][\"script\"]          = \"Hans\"\n    Locale[\"zh-CN\"][\"dictionary\"]      = \"true\" # has dictionary\n    Locale[\"zh-CN\"][\"spoken-in\"]       = \"the Greater China regions\"\n    Locale[\"zh-CN\"][\"written-in\"]      = \"mainland China; Singapore\"\n    Locale[\"zh-CN\"][\"supported-by\"]    = \"google; bing; yandex\"\n\n    # Chinese (Standard Mandarin), Traditional\n    Locale[\"zh-TW\"][\"name\"]            = \"Chinese (Traditional)\"\n    Locale[\"zh-TW\"][\"endonym\"]         = \"繁體中文\"\n    Locale[\"zh-TW\"][\"endonym2\"]        = \"正體中文\"\n    Locale[\"zh-TW\"][\"translations-of\"] = \"「%s」的翻譯\"\n    Locale[\"zh-TW\"][\"definitions-of\"]  = \"「%s」的定義\"\n    Locale[\"zh-TW\"][\"synonyms\"]        = \"同義詞\"\n    Locale[\"zh-TW\"][\"examples\"]        = \"例句\"\n    Locale[\"zh-TW\"][\"see-also\"]        = \"另請參閱\"\n    Locale[\"zh-TW\"][\"family\"]          = \"Sino-Tibetan\"\n    Locale[\"zh-TW\"][\"branch\"]          = \"Sinitic\"\n    Locale[\"zh-TW\"][\"iso\"]             = \"zho-TW\"\n    Locale[\"zh-TW\"][\"glotto\"]          = \"mand1415\"\n    Locale[\"zh-TW\"][\"script\"]          = \"Hant\"\n    Locale[\"zh-TW\"][\"dictionary\"]      = \"true\" # has dictionary\n    Locale[\"zh-TW\"][\"spoken-in\"]       = \"the Greater China regions\"\n    Locale[\"zh-TW\"][\"written-in\"]      = \"Taiwan (Republic of China); Hong Kong; Macau\"\n    Locale[\"zh-TW\"][\"supported-by\"]    = \"google; bing\"\n\n    # Chuvash\n    Locale[\"cv\"][\"name\"]               = \"Chuvash\"\n    Locale[\"cv\"][\"endonym\"]            = \"Чӑвашла\"\n    #Locale[\"cv\"][\"translations-of\"]\n    #Locale[\"cv\"][\"definitions-of\"]\n    #Locale[\"cv\"][\"synonyms\"]\n    #Locale[\"cv\"][\"examples\"] \n    #Locale[\"cv\"][\"see-also\"]\n    Locale[\"cv\"][\"family\"]             = \"Turkic\"\n    Locale[\"cv\"][\"branch\"]             = \"Oghur\"\n    Locale[\"cv\"][\"iso\"]                = \"chv\"\n    Locale[\"cv\"][\"glotto\"]             = \"chuv1255\"\n    Locale[\"cv\"][\"script\"]             = \"Cyrl\"\n    Locale[\"cv\"][\"spoken-in\"]          = \"the Chuvash Republic in Russia\"\n    Locale[\"cv\"][\"supported-by\"]       = \"yandex\"\n\n    # Corsican\n    Locale[\"co\"][\"name\"]               = \"Corsican\"\n    Locale[\"co\"][\"endonym\"]            = \"Corsu\"\n    Locale[\"co\"][\"translations-of\"]    = \"Traductions de %s\"\n    Locale[\"co\"][\"definitions-of\"]     = \"Définitions de %s\"\n    Locale[\"co\"][\"synonyms\"]           = \"Synonymes\"\n    Locale[\"co\"][\"examples\"]           = \"Exemples\"\n    Locale[\"co\"][\"see-also\"]           = \"Voir aussi\"\n    Locale[\"co\"][\"family\"]             = \"Indo-European\"\n    Locale[\"co\"][\"branch\"]             = \"Italo-Dalmatian\"\n    Locale[\"co\"][\"iso\"]                = \"cos\"\n    Locale[\"co\"][\"glotto\"]             = \"cors1241\"\n    Locale[\"co\"][\"script\"]             = \"Latn\"\n    Locale[\"co\"][\"spoken-in\"]          = \"Corsica in France; the northern end of the island of Sardinia in Italy\"\n    Locale[\"co\"][\"supported-by\"]       = \"google\"\n\n    # Croatian\n    Locale[\"hr\"][\"name\"]               = \"Croatian\"\n    Locale[\"hr\"][\"endonym\"]            = \"Hrvatski\"\n    Locale[\"hr\"][\"translations-of\"]    = \"Prijevodi riječi ili izraza %s\"\n    Locale[\"hr\"][\"definitions-of\"]     = \"Definicije riječi ili izraza %s\"\n    Locale[\"hr\"][\"synonyms\"]           = \"Sinonimi\"\n    Locale[\"hr\"][\"examples\"]           = \"Primjeri\"\n    Locale[\"hr\"][\"see-also\"]           = \"Također pogledajte\"\n    Locale[\"hr\"][\"family\"]             = \"Indo-European\"\n    Locale[\"hr\"][\"branch\"]             = \"South Slavic\"\n    Locale[\"hr\"][\"iso\"]                = \"hrv\"\n    Locale[\"hr\"][\"glotto\"]             = \"croa1245\"\n    Locale[\"hr\"][\"script\"]             = \"Latn\"\n    Locale[\"hr\"][\"spoken-in\"]          = \"Croatia; Bosnia and Herzegovina\"\n    Locale[\"hr\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Czech\n    Locale[\"cs\"][\"name\"]               = \"Czech\"\n    Locale[\"cs\"][\"endonym\"]            = \"Čeština\"\n    Locale[\"cs\"][\"translations-of\"]    = \"Překlad výrazu %s\"\n    Locale[\"cs\"][\"definitions-of\"]     = \"Definice výrazu %s\"\n    Locale[\"cs\"][\"synonyms\"]           = \"Synonyma\"\n    Locale[\"cs\"][\"examples\"]           = \"Příklady\"\n    Locale[\"cs\"][\"see-also\"]           = \"Viz také\"\n    Locale[\"cs\"][\"family\"]             = \"Indo-European\"\n    Locale[\"cs\"][\"branch\"]             = \"West Slavic\"\n    Locale[\"cs\"][\"iso\"]                = \"ces\"\n    Locale[\"cs\"][\"glotto\"]             = \"czec1258\"\n    Locale[\"cs\"][\"script\"]             = \"Latn\"\n    Locale[\"cs\"][\"spoken-in\"]          = \"Czechia\"\n    Locale[\"cs\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Danish\n    Locale[\"da\"][\"name\"]               = \"Danish\"\n    Locale[\"da\"][\"endonym\"]            = \"Dansk\"\n    Locale[\"da\"][\"translations-of\"]    = \"Oversættelser af %s\"\n    Locale[\"da\"][\"definitions-of\"]     = \"Definitioner af %s\"\n    Locale[\"da\"][\"synonyms\"]           = \"Synonymer\"\n    Locale[\"da\"][\"examples\"]           = \"Eksempler\"\n    Locale[\"da\"][\"see-also\"]           = \"Se også\"\n    Locale[\"da\"][\"family\"]             = \"Indo-European\"\n    Locale[\"da\"][\"branch\"]             = \"North Germanic\"\n    Locale[\"da\"][\"iso\"]                = \"dan\"\n    Locale[\"da\"][\"glotto\"]             = \"dani1285\"\n    Locale[\"da\"][\"script\"]             = \"Latn\"\n    Locale[\"da\"][\"spoken-in\"]          = \"Denmark; Greenland; the Faroe Islands; the northern German region of Southern Schleswig\"\n    Locale[\"da\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Dari (Dari Persian)\n    Locale[\"prs\"][\"name\"]              = \"Dari\"\n    Locale[\"prs\"][\"endonym\"]           = \"دری\"\n    #Locale[\"prs\"][\"translations-of\"]\n    #Locale[\"prs\"][\"definitions-of\"]\n    #Locale[\"prs\"][\"synonyms\"]\n    #Locale[\"prs\"][\"examples\"]\n    #Locale[\"prs\"][\"see-also\"]\n    Locale[\"prs\"][\"family\"]            = \"Indo-European\"\n    Locale[\"prs\"][\"branch\"]            = \"Iranian\"\n    Locale[\"prs\"][\"iso\"]               = \"prs\"\n    Locale[\"prs\"][\"glotto\"]            = \"dari1249\"\n    Locale[\"prs\"][\"script\"]            = \"Arab\"\n    Locale[\"prs\"][\"rtl\"]               = \"true\" # RTL language\n    Locale[\"prs\"][\"spoken-in\"]         = \"Afghanistan; Iran\"\n    Locale[\"prs\"][\"supported-by\"]      = \"bing\"\n\n    # Dhivehi\n    Locale[\"dv\"][\"name\"]               = \"Dhivehi\"\n    Locale[\"dv\"][\"name2\"]              = \"Divehi\"\n    Locale[\"dv\"][\"name3\"]              = \"Maldivian\"\n    Locale[\"dv\"][\"endonym\"]            = \"ދިވެހި\"\n    #Locale[\"dv\"][\"translations-of\"]\n    #Locale[\"dv\"][\"definitions-of\"]\n    #Locale[\"dv\"][\"synonyms\"]\n    #Locale[\"dv\"][\"examples\"]\n    #Locale[\"dv\"][\"see-also\"]\n    Locale[\"dv\"][\"family\"]             = \"Indo-European\"\n    Locale[\"dv\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"dv\"][\"iso\"]                = \"div\"\n    Locale[\"dv\"][\"glotto\"]             = \"dhiv1236\"\n    Locale[\"dv\"][\"script\"]             = \"Thaa\"\n    Locale[\"dv\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"dv\"][\"spoken-in\"]          = \"the Maldives\"\n    Locale[\"dv\"][\"supported-by\"]       = \"google; bing\"\n\n    # Dogri\n    Locale[\"doi\"][\"name\"]              = \"Dogri\"\n    Locale[\"doi\"][\"endonym\"]           = \"डोगरी\"\n    #Locale[\"doi\"][\"translations-of\"]\n    #Locale[\"doi\"][\"definitions-of\"]\n    #Locale[\"doi\"][\"synonyms\"]\n    #Locale[\"doi\"][\"examples\"]\n    #Locale[\"doi\"][\"see-also\"]\n    Locale[\"doi\"][\"family\"]            = \"Indo-European\"\n    Locale[\"doi\"][\"branch\"]            = \"Indo-Aryan\"\n    Locale[\"doi\"][\"iso\"]               = \"doi\"\n    Locale[\"doi\"][\"glotto\"]            = \"indo1311\"\n    Locale[\"doi\"][\"script\"]            = \"Deva\"\n    Locale[\"doi\"][\"spoken-in\"]         = \"the Jammu region in northern India\"\n    Locale[\"doi\"][\"supported-by\"]      = \"google\"\n\n    # Dutch\n    Locale[\"nl\"][\"name\"]               = \"Dutch\"\n    Locale[\"nl\"][\"endonym\"]            = \"Nederlands\"\n    Locale[\"nl\"][\"translations-of\"]    = \"Vertalingen van %s\"\n    Locale[\"nl\"][\"definitions-of\"]     = \"Definities van %s\"\n    Locale[\"nl\"][\"synonyms\"]           = \"Synoniemen\"\n    Locale[\"nl\"][\"examples\"]           = \"Voorbeelden\"\n    Locale[\"nl\"][\"see-also\"]           = \"Zie ook\"\n    Locale[\"nl\"][\"family\"]             = \"Indo-European\"\n    Locale[\"nl\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"nl\"][\"iso\"]                = \"nld\"\n    Locale[\"nl\"][\"glotto\"]             = \"dutc1256\"\n    Locale[\"nl\"][\"script\"]             = \"Latn\"\n    Locale[\"nl\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"nl\"][\"spoken-in\"]          = \"the Netherlands; Belgium; Suriname; Aruba; Curaçao; Sint Maarten; the Caribbean Netherlands\"\n    Locale[\"nl\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Dzongkha\n    Locale[\"dz\"][\"name\"]               = \"Dzongkha\"\n    Locale[\"dz\"][\"endonym\"]            = \"རྫོང་ཁ\"\n    #Locale[\"dz\"][\"translations-of\"]\n    #Locale[\"dz\"][\"definitions-of\"]\n    #Locale[\"dz\"][\"synonyms\"]\n    #Locale[\"dz\"][\"examples\"]\n    #Locale[\"dz\"][\"see-also\"]\n    Locale[\"dz\"][\"family\"]             = \"Sino-Tibetan\"\n    Locale[\"dz\"][\"branch\"]             = \"Tibetic\"\n    Locale[\"dz\"][\"iso\"]                = \"dzo\"\n    Locale[\"dz\"][\"glotto\"]             = \"nucl1307\"\n    Locale[\"dz\"][\"script\"]             = \"Tibt\"\n    Locale[\"dz\"][\"spoken-in\"]          = \"Bhutan\"\n    Locale[\"dz\"][\"supported-by\"]       = \"\"\n\n    # English\n    Locale[\"en\"][\"name\"]               = \"English\"\n    Locale[\"en\"][\"endonym\"]            = \"English\"\n    Locale[\"en\"][\"translations-of\"]    = \"Translations of %s\"\n    Locale[\"en\"][\"definitions-of\"]     = \"Definitions of %s\"\n    Locale[\"en\"][\"synonyms\"]           = \"Synonyms\"\n    Locale[\"en\"][\"examples\"]           = \"Examples\"\n    Locale[\"en\"][\"see-also\"]           = \"See also\"\n    Locale[\"en\"][\"family\"]             = \"Indo-European\"\n    Locale[\"en\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"en\"][\"iso\"]                = \"eng\"\n    Locale[\"en\"][\"glotto\"]             = \"stan1293\"\n    Locale[\"en\"][\"script\"]             = \"Latn\"\n    Locale[\"en\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"en\"][\"spoken-in\"]          = \"worldwide\"\n    Locale[\"en\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Esperanto\n    Locale[\"eo\"][\"name\"]               = \"Esperanto\"\n    Locale[\"eo\"][\"endonym\"]            = \"Esperanto\"\n    Locale[\"eo\"][\"translations-of\"]    = \"Tradukoj de %s\"\n    Locale[\"eo\"][\"definitions-of\"]     = \"Difinoj de %s\"\n    Locale[\"eo\"][\"synonyms\"]           = \"Sinonimoj\"\n    Locale[\"eo\"][\"examples\"]           = \"Ekzemploj\"\n    Locale[\"eo\"][\"see-also\"]           = \"Vidu ankaŭ\"\n    Locale[\"eo\"][\"family\"]             = \"Constructed language\"\n    #Locale[\"eo\"][\"branch\"]\n    Locale[\"eo\"][\"iso\"]                = \"epo\"\n    Locale[\"eo\"][\"glotto\"]             = \"espe1235\"\n    Locale[\"eo\"][\"script\"]             = \"Latn\"\n    Locale[\"eo\"][\"spoken-in\"]          = \"worldwide\"\n    Locale[\"eo\"][\"description\"]        = \"the world's most widely spoken constructed international auxiliary language, designed to be a universal second language for international communication\"\n    Locale[\"eo\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Estonian\n    Locale[\"et\"][\"name\"]               = \"Estonian\"\n    Locale[\"et\"][\"endonym\"]            = \"Eesti\"\n    Locale[\"et\"][\"translations-of\"]    = \"Sõna(de) %s tõlked\"\n    Locale[\"et\"][\"definitions-of\"]     = \"Sõna(de) %s definitsioonid\"\n    Locale[\"et\"][\"synonyms\"]           = \"Sünonüümid\"\n    Locale[\"et\"][\"examples\"]           = \"Näited\"\n    Locale[\"et\"][\"see-also\"]           = \"Vt ka\"\n    Locale[\"et\"][\"family\"]             = \"Uralic\"\n    Locale[\"et\"][\"branch\"]             = \"Finnic\"\n    Locale[\"et\"][\"iso\"]                = \"est\"\n    Locale[\"et\"][\"glotto\"]             = \"esto1258\"\n    Locale[\"et\"][\"script\"]             = \"Latn\"\n    Locale[\"et\"][\"spoken-in\"]          = \"Estonia\"\n    Locale[\"et\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Ewe\n    Locale[\"ee\"][\"name\"]               = \"Ewe\"\n    Locale[\"ee\"][\"endonym\"]            = \"Eʋegbe\"\n    #Locale[\"ee\"][\"translations-of\"]\n    #Locale[\"ee\"][\"definitions-of\"]\n    #Locale[\"ee\"][\"synonyms\"]\n    #Locale[\"ee\"][\"examples\"]\n    #Locale[\"ee\"][\"see-also\"]\n    Locale[\"ee\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"ee\"][\"branch\"]             = \"Gbe\"\n    Locale[\"ee\"][\"iso\"]                = \"ewe\"\n    Locale[\"ee\"][\"glotto\"]             = \"ewee1241\"\n    Locale[\"ee\"][\"script\"]             = \"Latn\"\n    Locale[\"ee\"][\"spoken-in\"]          = \"Ghana; Togo; Benin\"\n    Locale[\"ee\"][\"supported-by\"]       = \"google\"\n\n    # Faroese\n    Locale[\"fo\"][\"name\"]               = \"Faroese\"\n    Locale[\"fo\"][\"endonym\"]            = \"Føroyskt\"\n    #Locale[\"fo\"][\"translations-of\"]\n    #Locale[\"fo\"][\"definitions-of\"]\n    #Locale[\"fo\"][\"synonyms\"]\n    #Locale[\"fo\"][\"examples\"]\n    #Locale[\"fo\"][\"see-also\"]\n    Locale[\"fo\"][\"family\"]             = \"Indo-European\"\n    Locale[\"fo\"][\"branch\"]             = \"North Germanic\"\n    Locale[\"fo\"][\"iso\"]                = \"fao\"\n    Locale[\"fo\"][\"glotto\"]             = \"faro1244\"\n    Locale[\"fo\"][\"script\"]             = \"Latn\"\n    Locale[\"fo\"][\"spoken-in\"]          = \"the Faroe Islands\"\n    Locale[\"fo\"][\"supported-by\"]       = \"bing\"\n\n    # Fijian\n    Locale[\"fj\"][\"name\"]               = \"Fijian\"\n    Locale[\"fj\"][\"endonym\"]            = \"Vosa Vakaviti\"\n    #Locale[\"fj\"][\"translations-of\"]\n    #Locale[\"fj\"][\"definitions-of\"]\n    #Locale[\"fj\"][\"synonyms\"]\n    #Locale[\"fj\"][\"examples\"]\n    #Locale[\"fj\"][\"see-also\"]\n    Locale[\"fj\"][\"family\"]             = \"Austronesian\"\n    Locale[\"fj\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"fj\"][\"iso\"]                = \"fij\"\n    Locale[\"fj\"][\"glotto\"]             = \"fiji1243\"\n    Locale[\"fj\"][\"script\"]             = \"Latn\"\n    Locale[\"fj\"][\"spoken-in\"]          = \"Fiji\"\n    Locale[\"fj\"][\"supported-by\"]       = \"bing\"\n\n    # Filipino / Tagalog\n    Locale[\"tl\"][\"name\"]               = \"Filipino\"\n    Locale[\"tl\"][\"name2\"]              = \"Tagalog\"\n    Locale[\"tl\"][\"endonym\"]            = \"Filipino\"\n    Locale[\"tl\"][\"endonym2\"]           = \"Tagalog\"\n    Locale[\"tl\"][\"translations-of\"]    = \"Mga pagsasalin ng %s\"\n    Locale[\"tl\"][\"definitions-of\"]     = \"Mga kahulugan ng %s\"\n    Locale[\"tl\"][\"synonyms\"]           = \"Mga Kasingkahulugan\"\n    Locale[\"tl\"][\"examples\"]           = \"Mga Halimbawa\"\n    Locale[\"tl\"][\"see-also\"]           = \"Tingnan rin ang\"\n    Locale[\"tl\"][\"family\"]             = \"Austronesian\"\n    Locale[\"tl\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"tl\"][\"iso\"]                = \"fil\"\n    Locale[\"tl\"][\"glotto\"]             = \"fili1244\"\n    Locale[\"tl\"][\"script\"]             = \"Latn\"\n    Locale[\"tl\"][\"spoken-in\"]          = \"the Philippines\"\n    Locale[\"tl\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Finnish\n    Locale[\"fi\"][\"name\"]               = \"Finnish\"\n    Locale[\"fi\"][\"endonym\"]            = \"Suomi\"\n    Locale[\"fi\"][\"translations-of\"]    = \"Käännökset tekstille %s\"\n    Locale[\"fi\"][\"definitions-of\"]     = \"Määritelmät kohteelle %s\"\n    Locale[\"fi\"][\"synonyms\"]           = \"Synonyymit\"\n    Locale[\"fi\"][\"examples\"]           = \"Esimerkkejä\"\n    Locale[\"fi\"][\"see-also\"]           = \"Katso myös\"\n    Locale[\"fi\"][\"family\"]             = \"Uralic\"\n    Locale[\"fi\"][\"branch\"]             = \"Finnic\"\n    Locale[\"fi\"][\"iso\"]                = \"fin\"\n    Locale[\"fi\"][\"glotto\"]             = \"finn1318\"\n    Locale[\"fi\"][\"script\"]             = \"Latn\"\n    Locale[\"fi\"][\"spoken-in\"]          = \"Finland\"\n    Locale[\"fi\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # French (Standard French)\n    Locale[\"fr\"][\"name\"]               = \"French\"\n    Locale[\"fr\"][\"endonym\"]            = \"Français\"\n    Locale[\"fr\"][\"translations-of\"]    = \"Traductions de %s\"\n    Locale[\"fr\"][\"definitions-of\"]     = \"Définitions de %s\"\n    Locale[\"fr\"][\"synonyms\"]           = \"Synonymes\"\n    Locale[\"fr\"][\"examples\"]           = \"Exemples\"\n    Locale[\"fr\"][\"see-also\"]           = \"Voir aussi\"\n    Locale[\"fr\"][\"family\"]             = \"Indo-European\"\n    Locale[\"fr\"][\"branch\"]             = \"Western Romance\"\n    Locale[\"fr\"][\"iso\"]                = \"fra\"\n    Locale[\"fr\"][\"glotto\"]             = \"stan1290\"\n    Locale[\"fr\"][\"script\"]             = \"Latn\"\n    Locale[\"fr\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"fr\"][\"spoken-in\"]          = \"France; Switzerland; Belgium; Luxembourg\"\n    Locale[\"fr\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # French (Canadian French)\n    Locale[\"fr-CA\"][\"name\"]            = \"French (Canadian)\"\n    Locale[\"fr-CA\"][\"endonym\"]         = \"Français canadien\"\n    Locale[\"fr-CA\"][\"translations-of\"] = \"Traductions de %s\"\n    Locale[\"fr-CA\"][\"definitions-of\"]  = \"Définitions de %s\"\n    Locale[\"fr-CA\"][\"synonyms\"]        = \"Synonymes\"\n    Locale[\"fr-CA\"][\"examples\"]        = \"Exemples\"\n    Locale[\"fr-CA\"][\"see-also\"]        = \"Voir aussi\"\n    Locale[\"fr-CA\"][\"family\"]          = \"Indo-European\"\n    Locale[\"fr-CA\"][\"branch\"]          = \"Western Romance\"\n    Locale[\"fr-CA\"][\"iso\"]             = \"fra-CA\"\n    Locale[\"fr-CA\"][\"glotto\"]          = \"queb1247\"\n    Locale[\"fr-CA\"][\"script\"]          = \"Latn\"\n    Locale[\"fr-CA\"][\"spoken-in\"]       = \"Canada\"\n    Locale[\"fr-CA\"][\"supported-by\"]    = \"bing\"\n\n    # Galician\n    Locale[\"gl\"][\"name\"]               = \"Galician\"\n    Locale[\"gl\"][\"endonym\"]            = \"Galego\"\n    Locale[\"gl\"][\"translations-of\"]    = \"Traducións de %s\"\n    Locale[\"gl\"][\"definitions-of\"]     = \"Definicións de %s\"\n    Locale[\"gl\"][\"synonyms\"]           = \"Sinónimos\"\n    Locale[\"gl\"][\"examples\"]           = \"Exemplos\"\n    Locale[\"gl\"][\"see-also\"]           = \"Ver tamén\"\n    Locale[\"gl\"][\"family\"]             = \"Indo-European\"\n    Locale[\"gl\"][\"branch\"]             = \"Western Romance\"\n    Locale[\"gl\"][\"iso\"]                = \"glg\"\n    Locale[\"gl\"][\"glotto\"]             = \"gali1258\"\n    Locale[\"gl\"][\"script\"]             = \"Latn\"\n    Locale[\"gl\"][\"spoken-in\"]          = \"Galicia in northwestern Spain\"\n    Locale[\"gl\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Georgian (Modern Georgian)\n    Locale[\"ka\"][\"name\"]               = \"Georgian\"\n    Locale[\"ka\"][\"endonym\"]            = \"ქართული\"\n    Locale[\"ka\"][\"translations-of\"]    = \"%s-ის თარგმანები\"\n    Locale[\"ka\"][\"definitions-of\"]     = \"%s-ის განსაზღვრებები\"\n    Locale[\"ka\"][\"synonyms\"]           = \"სინონიმები\"\n    Locale[\"ka\"][\"examples\"]           = \"მაგალითები\"\n    Locale[\"ka\"][\"see-also\"]           = \"ასევე იხილეთ\"\n    Locale[\"ka\"][\"family\"]             = \"Kartvelian\"\n    Locale[\"ka\"][\"branch\"]             = \"Karto-Zan\"\n    Locale[\"ka\"][\"iso\"]                = \"kat\"\n    Locale[\"ka\"][\"glotto\"]             = \"nucl1302\"\n    Locale[\"ka\"][\"script\"]             = \"Geor\"\n    Locale[\"ka\"][\"spoken-in\"]          = \"Georgia\"\n    Locale[\"ka\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # German (Standard German)\n    Locale[\"de\"][\"name\"]               = \"German\"\n    Locale[\"de\"][\"endonym\"]            = \"Deutsch\"\n    Locale[\"de\"][\"translations-of\"]    = \"Übersetzungen für %s\"\n    Locale[\"de\"][\"definitions-of\"]     = \"Definitionen von %s\"\n    Locale[\"de\"][\"synonyms\"]           = \"Synonyme\"\n    Locale[\"de\"][\"examples\"]           = \"Beispiele\"\n    Locale[\"de\"][\"see-also\"]           = \"Siehe auch\"\n    Locale[\"de\"][\"family\"]             = \"Indo-European\"\n    Locale[\"de\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"de\"][\"iso\"]                = \"deu\"\n    Locale[\"de\"][\"glotto\"]             = \"stan1295\"\n    Locale[\"de\"][\"script\"]             = \"Latn\"\n    Locale[\"de\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"de\"][\"spoken-in\"]          = \"Central Europe\"\n    Locale[\"de\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Greek (Modern Greek)\n    Locale[\"el\"][\"name\"]               = \"Greek\"\n    Locale[\"el\"][\"endonym\"]            = \"Ελληνικά\"\n    Locale[\"el\"][\"translations-of\"]    = \"Μεταφράσεις του %s\"\n    Locale[\"el\"][\"definitions-of\"]     = \"Όρισμοί %s\"\n    Locale[\"el\"][\"synonyms\"]           = \"Συνώνυμα\"\n    Locale[\"el\"][\"examples\"]           = \"Παραδείγματα\"\n    Locale[\"el\"][\"see-also\"]           = \"Δείτε επίσης\"\n    Locale[\"el\"][\"family\"]             = \"Indo-European\"\n    Locale[\"el\"][\"branch\"]             = \"Paleo-Balkan\"\n    Locale[\"el\"][\"iso\"]                = \"ell\"\n    Locale[\"el\"][\"glotto\"]             = \"mode1248\"\n    Locale[\"el\"][\"script\"]             = \"Grek\"\n    Locale[\"el\"][\"spoken-in\"]          = \"Greece; Cyprus; southern Albania\"\n    Locale[\"el\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Greenlandic (West Greenlandic)\n    Locale[\"kl\"][\"name\"]               = \"Greenlandic\"\n    Locale[\"kl\"][\"endonym\"]            = \"Kalaallisut\"\n    #Locale[\"kl\"][\"translations-of\"]\n    #Locale[\"kl\"][\"definitions-of\"]\n    #Locale[\"kl\"][\"synonyms\"]\n    #Locale[\"kl\"][\"examples\"]\n    #Locale[\"kl\"][\"see-also\"]\n    Locale[\"kl\"][\"family\"]             = \"Eskimo-Aleut\"\n    Locale[\"kl\"][\"branch\"]             = \"Inuit\"\n    Locale[\"kl\"][\"iso\"]                = \"kal\"\n    Locale[\"kl\"][\"glotto\"]             = \"kala1399\"\n    Locale[\"kl\"][\"script\"]             = \"Latn\"\n    Locale[\"kl\"][\"spoken-in\"]          = \"Greenland\"\n    Locale[\"kl\"][\"supported-by\"]       = \"\"\n\n    # Guarani\n    Locale[\"gn\"][\"name\"]               = \"Guarani\"\n    Locale[\"gn\"][\"endonym\"]            = \"Avañe'ẽ\"\n    #Locale[\"gn\"][\"translations-of\"]\n    #Locale[\"gn\"][\"definitions-of\"]\n    #Locale[\"gn\"][\"synonyms\"]\n    #Locale[\"gn\"][\"examples\"]\n    #Locale[\"gn\"][\"see-also\"]\n    Locale[\"gn\"][\"family\"]             = \"Tupian\"\n    #Locale[\"gn\"][\"branch\"]            = \"Guaraní\"\n    Locale[\"gn\"][\"iso\"]                = \"gug\"\n    Locale[\"gn\"][\"glotto\"]             = \"para1311\"\n    Locale[\"gn\"][\"script\"]             = \"Latn\"\n    Locale[\"gn\"][\"spoken-in\"]          = \"Paraguay; Bolivia; Argentina; Brazil\"\n    Locale[\"gn\"][\"supported-by\"]       = \"google\"\n\n    # Gujarati\n    Locale[\"gu\"][\"name\"]               = \"Gujarati\"\n    Locale[\"gu\"][\"endonym\"]            = \"ગુજરાતી\"\n    Locale[\"gu\"][\"translations-of\"]    = \"%s ના અનુવાદ\"\n    Locale[\"gu\"][\"definitions-of\"]     = \"%s ની વ્યાખ્યાઓ\"\n    Locale[\"gu\"][\"synonyms\"]           = \"સમાનાર્થી\"\n    Locale[\"gu\"][\"examples\"]           = \"ઉદાહરણો\"\n    Locale[\"gu\"][\"see-also\"]           = \"આ પણ જુઓ\"\n    Locale[\"gu\"][\"family\"]             = \"Indo-European\"\n    Locale[\"gu\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"gu\"][\"iso\"]                = \"guj\"\n    Locale[\"gu\"][\"glotto\"]             = \"guja1252\"\n    Locale[\"gu\"][\"script\"]             = \"Gujr\"\n    Locale[\"gu\"][\"spoken-in\"]          = \"the Indian state of Gujarat\"\n    Locale[\"gu\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Haitian Creole\n    Locale[\"ht\"][\"name\"]               = \"Haitian Creole\"\n    Locale[\"ht\"][\"endonym\"]            = \"Kreyòl Ayisyen\"\n    Locale[\"ht\"][\"translations-of\"]    = \"Tradiksyon %s\"\n    Locale[\"ht\"][\"definitions-of\"]     = \"Definisyon nan %s\"\n    Locale[\"ht\"][\"synonyms\"]           = \"Sinonim\"\n    Locale[\"ht\"][\"examples\"]           = \"Egzanp:\"\n    Locale[\"ht\"][\"see-also\"]           = \"Wè tou\"\n    Locale[\"ht\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ht\"][\"branch\"]             = \"French Creole\"\n    Locale[\"ht\"][\"iso\"]                = \"hat\"\n    Locale[\"ht\"][\"glotto\"]             = \"hait1244\"\n    Locale[\"ht\"][\"script\"]             = \"Latn\"\n    Locale[\"ht\"][\"spoken-in\"]          = \"Haiti\"\n    Locale[\"ht\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Hawaiian\n    Locale[\"haw\"][\"name\"]              = \"Hawaiian\"\n    Locale[\"haw\"][\"endonym\"]           = \"ʻŌlelo Hawaiʻi\"\n    #Locale[\"haw\"][\"translations-of\"]\n    #Locale[\"haw\"][\"definitions-of\"]\n    #Locale[\"haw\"][\"synonyms\"]\n    #Locale[\"haw\"][\"examples\"]\n    #Locale[\"haw\"][\"see-also\"]\n    Locale[\"haw\"][\"family\"]            = \"Austronesian\"\n    Locale[\"haw\"][\"branch\"]            = \"Malayo-Polynesian\"\n    Locale[\"haw\"][\"iso\"]               = \"haw\"\n    Locale[\"haw\"][\"glotto\"]            = \"hawa1245\"\n    Locale[\"haw\"][\"script\"]            = \"Latn\"\n    Locale[\"haw\"][\"spoken-in\"]         = \"the US state of Hawaii\"\n    Locale[\"haw\"][\"supported-by\"]      = \"google\"\n\n    # Hausa, Latin alphabet\n    Locale[\"ha\"][\"name\"]               = \"Hausa\"\n    Locale[\"ha\"][\"endonym\"]            = \"Hausa\"\n    Locale[\"ha\"][\"translations-of\"]    = \"Fassarar %s\"\n    Locale[\"ha\"][\"definitions-of\"]     = \"Ma'anoni na %s\"\n    Locale[\"ha\"][\"synonyms\"]           = \"Masu kamancin ma'ana\"\n    Locale[\"ha\"][\"examples\"]           = \"Misalai\"\n    Locale[\"ha\"][\"see-also\"]           = \"Duba kuma\"\n    Locale[\"ha\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"ha\"][\"branch\"]             = \"Chadic\"\n    Locale[\"ha\"][\"iso\"]                = \"hau\"\n    Locale[\"ha\"][\"glotto\"]             = \"haus1257\"\n    Locale[\"ha\"][\"script\"]             = \"Latn\"\n    Locale[\"ha\"][\"spoken-in\"]          = \"Chad; Nigeria; Niger; Ghana; Cameroon; Benin\"\n    Locale[\"ha\"][\"supported-by\"]       = \"google\"\n\n    # Hebrew\n    Locale[\"he\"][\"name\"]               = \"Hebrew\"\n    Locale[\"he\"][\"endonym\"]            = \"עִבְרִית\"\n    Locale[\"he\"][\"translations-of\"]    = \"תרגומים של %s\"\n    Locale[\"he\"][\"definitions-of\"]     = \"הגדרות של %s\"\n    Locale[\"he\"][\"synonyms\"]           = \"מילים נרדפות\"\n    Locale[\"he\"][\"examples\"]           = \"דוגמאות\"\n    Locale[\"he\"][\"see-also\"]           = \"ראה גם\"\n    Locale[\"he\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"he\"][\"branch\"]             = \"Semitic\"\n    Locale[\"he\"][\"iso\"]                = \"heb\"\n    Locale[\"he\"][\"glotto\"]             = \"hebr1245\"\n    Locale[\"he\"][\"script\"]             = \"Hebr\"\n    Locale[\"he\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"he\"][\"spoken-in\"]          = \"Israel\"\n    Locale[\"he\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Hill Mari / Western Mari\n    Locale[\"mrj\"][\"name\"]              = \"Hill Mari\"\n    Locale[\"mrj\"][\"endonym\"]           = \"Кырык мары\"\n    #Locale[\"mrj\"][\"translations-of\"]\n    #Locale[\"mrj\"][\"definitions-of\"]\n    #Locale[\"mrj\"][\"synonyms\"]\n    #Locale[\"mrj\"][\"examples\"]\n    #Locale[\"mrj\"][\"see-also\"]\n    Locale[\"mrj\"][\"family\"]            = \"Uralic\"\n    Locale[\"mrj\"][\"branch\"]            = \"Mari\"\n    Locale[\"mrj\"][\"iso\"]               = \"mrj\"\n    Locale[\"mrj\"][\"glotto\"]            = \"west2392\"\n    Locale[\"mrj\"][\"script\"]            = \"Cyrl\"\n    Locale[\"mrj\"][\"spoken-in\"]         = \"the Gornomariysky, Yurinsky and Kilemarsky districts of Mari El, Russia\"\n    Locale[\"mrj\"][\"supported-by\"]      = \"yandex\"\n\n    # Hindi\n    Locale[\"hi\"][\"name\"]               = \"Hindi\"\n    Locale[\"hi\"][\"endonym\"]            = \"हिन्दी\"\n    Locale[\"hi\"][\"translations-of\"]    = \"%s के अनुवाद\"\n    Locale[\"hi\"][\"definitions-of\"]     = \"%s की परिभाषाएं\"\n    Locale[\"hi\"][\"synonyms\"]           = \"समानार्थी\"\n    Locale[\"hi\"][\"examples\"]           = \"उदाहरण\"\n    Locale[\"hi\"][\"see-also\"]           = \"यह भी देखें\"\n    Locale[\"hi\"][\"family\"]             = \"Indo-European\"\n    Locale[\"hi\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"hi\"][\"iso\"]                = \"hin\"\n    Locale[\"hi\"][\"glotto\"]             = \"hind1269\"\n    Locale[\"hi\"][\"script\"]             = \"Deva\"\n    Locale[\"hi\"][\"spoken-in\"]          = \"India\"\n    Locale[\"hi\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Hmong (First Vernacular Hmong)\n    Locale[\"hmn\"][\"name\"]              = \"Hmong\"\n    Locale[\"hmn\"][\"endonym\"]           = \"Hmoob\"\n    Locale[\"hmn\"][\"translations-of\"]   = \"Lus txhais: %s\"\n    #Locale[\"hmn\"][\"definitions-of\"]\n    #Locale[\"hmn\"][\"synonyms\"]\n    #Locale[\"hmn\"][\"examples\"]\n    #Locale[\"hmn\"][\"see-also\"]\n    Locale[\"hmn\"][\"family\"]            = \"Hmong-Mien\"\n    Locale[\"hmn\"][\"branch\"]            = \"Hmongic\"\n    Locale[\"hmn\"][\"iso\"]               = \"hmn\"\n    Locale[\"hmn\"][\"glotto\"]            = \"firs1234\"\n    Locale[\"hmn\"][\"script\"]            = \"Latn\"\n    Locale[\"hmn\"][\"spoken-in\"]         = \"China; Vietnam; Laos; Myanmar; Thailand\"\n    Locale[\"hmn\"][\"supported-by\"]      = \"google; bing\"\n\n    # Hmong Daw (White Hmong)\n    #Locale[\"mww\"][\"name\"]              = \"Hmong Daw\"\n    #Locale[\"mww\"][\"endonym\"]           = \"Hmoob Daw\"\n    #Locale[\"mww\"][\"family\"]            = \"Hmong-Mien\"\n    #Locale[\"mww\"][\"branch\"]            = \"Hmongic\"\n    #Locale[\"mww\"][\"iso\"]               = \"mww\"\n    #Locale[\"mww\"][\"glotto\"]            = \"hmon1333\"\n    #Locale[\"mww\"][\"script\"]            = \"Latn\"\n    #Locale[\"mww\"][\"spoken-in\"]         = \"China; Vietnam; Laos; Myanmar; Thailand\"\n    #Locale[\"mww\"][\"supported-by\"]      = \"bing\"\n\n    # Hungarian\n    Locale[\"hu\"][\"name\"]               = \"Hungarian\"\n    Locale[\"hu\"][\"endonym\"]            = \"Magyar\"\n    Locale[\"hu\"][\"translations-of\"]    = \"%s fordításai\"\n    Locale[\"hu\"][\"definitions-of\"]     = \"%s jelentései\"\n    Locale[\"hu\"][\"synonyms\"]           = \"Szinonimák\"\n    Locale[\"hu\"][\"examples\"]           = \"Példák\"\n    Locale[\"hu\"][\"see-also\"]           = \"Lásd még\"\n    Locale[\"hu\"][\"family\"]             = \"Uralic\"\n    Locale[\"hu\"][\"branch\"]             = \"Ugric\"\n    Locale[\"hu\"][\"iso\"]                = \"hun\"\n    Locale[\"hu\"][\"glotto\"]             = \"hung1274\"\n    Locale[\"hu\"][\"script\"]             = \"Latn\"\n    Locale[\"hu\"][\"spoken-in\"]          = \"Hungary\"\n    Locale[\"hu\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Icelandic\n    Locale[\"is\"][\"name\"]               = \"Icelandic\"\n    Locale[\"is\"][\"endonym\"]            = \"Íslenska\"\n    Locale[\"is\"][\"translations-of\"]    = \"Þýðingar á %s\"\n    Locale[\"is\"][\"definitions-of\"]     = \"Skilgreiningar á\"\n    Locale[\"is\"][\"synonyms\"]           = \"Samheiti\"\n    Locale[\"is\"][\"examples\"]           = \"Dæmi\"\n    Locale[\"is\"][\"see-also\"]           = \"Sjá einnig\"\n    Locale[\"is\"][\"family\"]             = \"Indo-European\"\n    Locale[\"is\"][\"branch\"]             = \"North Germanic\"\n    Locale[\"is\"][\"iso\"]                = \"isl\"\n    Locale[\"is\"][\"glotto\"]             = \"icel1247\"\n    Locale[\"is\"][\"script\"]             = \"Latn\"\n    Locale[\"is\"][\"spoken-in\"]          = \"Iceland\"\n    Locale[\"is\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Igbo\n    Locale[\"ig\"][\"name\"]               = \"Igbo\"\n    Locale[\"ig\"][\"endonym\"]            = \"Igbo\"\n    Locale[\"ig\"][\"translations-of\"]    = \"Ntụgharị asụsụ nke %s\"\n    Locale[\"ig\"][\"definitions-of\"]     = \"Nkọwapụta nke %s\"\n    Locale[\"ig\"][\"synonyms\"]           = \"Okwu oyiri\"\n    Locale[\"ig\"][\"examples\"]           = \"Ọmụmaatụ\"\n    Locale[\"ig\"][\"see-also\"]           = \"Hụkwuo\"\n    Locale[\"ig\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"ig\"][\"branch\"]             = \"Igboid\"\n    Locale[\"ig\"][\"iso\"]                = \"ibo\"\n    Locale[\"ig\"][\"glotto\"]             = \"nucl1417\"\n    Locale[\"ig\"][\"script\"]             = \"Latn\"\n    Locale[\"ig\"][\"spoken-in\"]          = \"southeastern Nigeria\"\n    Locale[\"ig\"][\"supported-by\"]       = \"google\"\n\n    # Ilocano\n    Locale[\"ilo\"][\"name\"]              = \"Ilocano\"\n    Locale[\"ilo\"][\"endonym\"]           = \"Ilokano\"\n    #Locale[\"ilo\"][\"translations-of\"]\n    #Locale[\"ilo\"][\"definitions-of\"]\n    #Locale[\"ilo\"][\"synonyms\"]\n    #Locale[\"ilo\"][\"examples\"]\n    #Locale[\"ilo\"][\"see-also\"]\n    Locale[\"ilo\"][\"family\"]            = \"Austronesian\"\n    Locale[\"ilo\"][\"branch\"]            = \"Malayo-Polynesian\"\n    Locale[\"ilo\"][\"iso\"]               = \"ilo\"\n    Locale[\"ilo\"][\"glotto\"]            = \"ilok1237\"\n    Locale[\"ilo\"][\"script\"]            = \"Latn\"\n    Locale[\"ilo\"][\"spoken-in\"]         = \"the northern Philippines\"\n    Locale[\"ilo\"][\"supported-by\"]      = \"google\"\n\n    # Indonesian\n    Locale[\"id\"][\"name\"]               = \"Indonesian\"\n    Locale[\"id\"][\"endonym\"]            = \"Bahasa Indonesia\"\n    Locale[\"id\"][\"translations-of\"]    = \"Terjemahan dari %s\"\n    Locale[\"id\"][\"definitions-of\"]     = \"Definisi %s\"\n    Locale[\"id\"][\"synonyms\"]           = \"Sinonim\"\n    Locale[\"id\"][\"examples\"]           = \"Contoh\"\n    Locale[\"id\"][\"see-also\"]           = \"Lihat juga\"\n    Locale[\"id\"][\"family\"]             = \"Austronesian\"\n    Locale[\"id\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"id\"][\"iso\"]                = \"ind\"\n    Locale[\"id\"][\"glotto\"]             = \"indo1316\"\n    Locale[\"id\"][\"script\"]             = \"Latn\"\n    Locale[\"id\"][\"spoken-in\"]          = \"Indonesia\"\n    Locale[\"id\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Interlingue\n    Locale[\"ie\"][\"name\"]               = \"Interlingue\"\n    Locale[\"ie\"][\"name2\"]              = \"Occidental\"\n    Locale[\"ie\"][\"endonym\"]            = \"Interlingue\"\n    #Locale[\"ie\"][\"translations-of\"]\n    #Locale[\"ie\"][\"definitions-of\"]\n    #Locale[\"ie\"][\"synonyms\"]\n    #Locale[\"ie\"][\"examples\"]\n    #Locale[\"ie\"][\"see-also\"]\n    Locale[\"ie\"][\"family\"]             = \"Constructed language\"\n    #Locale[\"ie\"][\"branch\"]\n    Locale[\"ie\"][\"iso\"]                = \"ile\"\n    Locale[\"ie\"][\"glotto\"]             = \"occi1241\"\n    Locale[\"ie\"][\"script\"]             = \"Latn\"\n    Locale[\"ie\"][\"spoken-in\"]          = \"worldwide\"\n    Locale[\"ie\"][\"description\"]        = \"an international auxiliary language\"\n    Locale[\"ie\"][\"supported-by\"]       = \"\"\n\n    # Inuinnaqtun\n    Locale[\"ikt\"][\"name\"]              = \"Inuinnaqtun\"\n    Locale[\"ikt\"][\"endonym\"]           = \"Inuinnaqtun\"\n    #Locale[\"ikt\"][\"translations-of\"]\n    #Locale[\"ikt\"][\"definitions-of\"]\n    #Locale[\"ikt\"][\"synonyms\"]\n    #Locale[\"ikt\"][\"examples\"]\n    #Locale[\"ikt\"][\"see-also\"]\n    Locale[\"ikt\"][\"family\"]            = \"Eskimo-Aleut\"\n    Locale[\"ikt\"][\"branch\"]            = \"Inuit\"\n    Locale[\"ikt\"][\"iso\"]               = \"ikt\"\n    Locale[\"ikt\"][\"glotto\"]            = \"copp1244\"\n    Locale[\"ikt\"][\"script\"]            = \"Latn\"\n    Locale[\"ikt\"][\"spoken-in\"]         = \"the Canadian Arctic\"\n    Locale[\"ikt\"][\"supported-by\"]      = \"bing\"\n\n    # Inuktitut (Eastern Canadian Inuktitut)\n    Locale[\"iu\"][\"name\"]               = \"Inuktitut\"\n    Locale[\"iu\"][\"endonym\"]            = \"ᐃᓄᒃᑎᑐᑦ\"\n    #Locale[\"iu\"][\"translations-of\"]\n    #Locale[\"iu\"][\"definitions-of\"]\n    #Locale[\"iu\"][\"synonyms\"]\n    #Locale[\"iu\"][\"examples\"]\n    #Locale[\"iu\"][\"see-also\"]\n    Locale[\"iu\"][\"family\"]             = \"Eskimo-Aleut\"\n    Locale[\"iu\"][\"branch\"]             = \"Inuit\"\n    Locale[\"iu\"][\"iso\"]                = \"iku\"\n    Locale[\"iu\"][\"glotto\"]             = \"east2534\"\n    Locale[\"iu\"][\"script\"]             = \"Cans\"\n    Locale[\"iu\"][\"spoken-in\"]          = \"the Canadian Arctic\"\n    Locale[\"iu\"][\"supported-by\"]       = \"bing\"\n\n    # Inuktitut (Eastern Canadian Inuktitut), Latin alphabet\n    Locale[\"iu-Latn\"][\"name\"]          = \"Inuktitut (Latin)\"\n    Locale[\"iu-Latn\"][\"endonym\"]       = \"Inuktitut\"\n    #Locale[\"iu-Latn\"][\"translations-of\"]\n    #Locale[\"iu-Latn\"][\"definitions-of\"]\n    #Locale[\"iu-Latn\"][\"synonyms\"]\n    #Locale[\"iu-Latn\"][\"examples\"]\n    #Locale[\"iu-Latn\"][\"see-also\"]\n    Locale[\"iu-Latn\"][\"family\"]        = \"Eskimo-Aleut\"\n    Locale[\"iu-Latn\"][\"branch\"]        = \"Inuit\"\n    Locale[\"iu-Latn\"][\"iso\"]           = \"iku\"\n    Locale[\"iu-Latn\"][\"glotto\"]        = \"east2534\"\n    Locale[\"iu-Latn\"][\"script\"]        = \"Latn\"\n    Locale[\"iu-Latn\"][\"spoken-in\"]     = \"the Canadian Arctic\"\n    Locale[\"iu-Latn\"][\"supported-by\"]  = \"bing\"\n\n    # Irish\n    Locale[\"ga\"][\"name\"]               = \"Irish\"\n    Locale[\"ga\"][\"name2\"]              = \"Gaelic\"\n    Locale[\"ga\"][\"endonym\"]            = \"Gaeilge\"\n    Locale[\"ga\"][\"translations-of\"]    = \"Aistriúcháin ar %s\"\n    Locale[\"ga\"][\"definitions-of\"]     = \"Sainmhínithe ar %s\"\n    Locale[\"ga\"][\"synonyms\"]           = \"Comhchiallaigh\"\n    Locale[\"ga\"][\"examples\"]           = \"Samplaí\"\n    Locale[\"ga\"][\"see-also\"]           = \"féach freisin\"\n    Locale[\"ga\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ga\"][\"branch\"]             = \"Celtic\"\n    Locale[\"ga\"][\"iso\"]                = \"gle\"\n    Locale[\"ga\"][\"glotto\"]             = \"iris1253\"\n    Locale[\"ga\"][\"script\"]             = \"Latn\"\n    Locale[\"ga\"][\"spoken-in\"]          = \"Ireland\"\n    Locale[\"ga\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Italian\n    Locale[\"it\"][\"name\"]               = \"Italian\"\n    Locale[\"it\"][\"endonym\"]            = \"Italiano\"\n    Locale[\"it\"][\"translations-of\"]    = \"Traduzioni di %s\"\n    Locale[\"it\"][\"definitions-of\"]     = \"Definizioni di %s\"\n    Locale[\"it\"][\"synonyms\"]           = \"Sinonimi\"\n    Locale[\"it\"][\"examples\"]           = \"Esempi\"\n    Locale[\"it\"][\"see-also\"]           = \"Vedi anche\"\n    Locale[\"it\"][\"family\"]             = \"Indo-European\"\n    Locale[\"it\"][\"branch\"]             = \"Italo-Dalmatian\"\n    Locale[\"it\"][\"iso\"]                = \"ita\"\n    Locale[\"it\"][\"glotto\"]             = \"ital1282\"\n    Locale[\"it\"][\"script\"]             = \"Latn\"\n    Locale[\"it\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"it\"][\"spoken-in\"]          = \"Italy; Switzerland; San Marino; Vatican City\"\n    Locale[\"it\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Japanese\n    Locale[\"ja\"][\"name\"]               = \"Japanese\"\n    Locale[\"ja\"][\"endonym\"]            = \"日本語\"\n    Locale[\"ja\"][\"translations-of\"]    = \"「%s」の翻訳\"\n    Locale[\"ja\"][\"definitions-of\"]     = \"%s の定義\"\n    Locale[\"ja\"][\"synonyms\"]           = \"同義語\"\n    Locale[\"ja\"][\"examples\"]           = \"例\"\n    Locale[\"ja\"][\"see-also\"]           = \"関連項目\"\n    Locale[\"ja\"][\"family\"]             = \"Japonic\"\n    #Locale[\"ja\"][\"branch\"]\n    Locale[\"ja\"][\"iso\"]                = \"jpn\"\n    Locale[\"ja\"][\"glotto\"]             = \"nucl1643\"\n    Locale[\"ja\"][\"script\"]             = \"Jpan\"\n    Locale[\"ja\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"ja\"][\"spoken-in\"]          = \"Japan\"\n    Locale[\"ja\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Javanese, Latin alphabet\n    Locale[\"jv\"][\"name\"]               = \"Javanese\"\n    Locale[\"jv\"][\"endonym\"]            = \"Basa Jawa\"\n    Locale[\"jv\"][\"translations-of\"]    = \"Terjemahan %s\"\n    Locale[\"jv\"][\"definitions-of\"]     = \"Arti %s\"\n    Locale[\"jv\"][\"synonyms\"]           = \"Sinonim\"\n    Locale[\"jv\"][\"examples\"]           = \"Conto\"\n    Locale[\"jv\"][\"see-also\"]           = \"Deleng uga\"\n    Locale[\"jv\"][\"family\"]             = \"Austronesian\"\n    Locale[\"jv\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"jv\"][\"iso\"]                = \"jav\"\n    Locale[\"jv\"][\"glotto\"]             = \"java1254\"\n    Locale[\"jv\"][\"script\"]             = \"Latn\"\n    Locale[\"jv\"][\"spoken-in\"]          = \"Java, Indonesia\"\n    Locale[\"jv\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Kannada (Modern Kannada)\n    Locale[\"kn\"][\"name\"]               = \"Kannada\"\n    Locale[\"kn\"][\"endonym\"]            = \"ಕನ್ನಡ\"\n    Locale[\"kn\"][\"translations-of\"]    = \"%s ನ ಅನುವಾದಗಳು\"\n    Locale[\"kn\"][\"definitions-of\"]     = \"%s ನ ವ್ಯಾಖ್ಯಾನಗಳು\"\n    Locale[\"kn\"][\"synonyms\"]           = \"ಸಮಾನಾರ್ಥಕಗಳು\"\n    Locale[\"kn\"][\"examples\"]           = \"ಉದಾಹರಣೆಗಳು\"\n    Locale[\"kn\"][\"see-also\"]           = \"ಇದನ್ನೂ ಗಮನಿಸಿ\"\n    Locale[\"kn\"][\"family\"]             = \"Dravidian\"\n    Locale[\"kn\"][\"branch\"]             = \"South Dravidian\"\n    Locale[\"kn\"][\"iso\"]                = \"kan\"\n    Locale[\"kn\"][\"glotto\"]             = \"nucl1305\"\n    Locale[\"kn\"][\"script\"]             = \"Knda\"\n    Locale[\"kn\"][\"spoken-in\"]          = \"the southwestern India\"\n    Locale[\"kn\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Kazakh, Cyrillic alphabet\n    Locale[\"kk\"][\"name\"]               = \"Kazakh\"\n    Locale[\"kk\"][\"endonym\"]            = \"Қазақ тілі\"\n    Locale[\"kk\"][\"translations-of\"]    = \"%s аудармалары\"\n    Locale[\"kk\"][\"definitions-of\"]     = \"%s анықтамалары\"\n    Locale[\"kk\"][\"synonyms\"]           = \"Синонимдер\"\n    Locale[\"kk\"][\"examples\"]           = \"Мысалдар\"\n    Locale[\"kk\"][\"see-also\"]           = \"Келесі тізімді де көріңіз:\"\n    Locale[\"kk\"][\"family\"]             = \"Turkic\"\n    Locale[\"kk\"][\"branch\"]             = \"Kipchak\"\n    Locale[\"kk\"][\"iso\"]                = \"kaz\"\n    Locale[\"kk\"][\"glotto\"]             = \"kaza1248\"\n    Locale[\"kk\"][\"script\"]             = \"Cyrl\"\n    Locale[\"kk\"][\"spoken-in\"]          = \"Kazakhstan; China; Mongolia; Russia; Kyrgyzstan; Uzbekistan\"\n    Locale[\"kk\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Khmer (Central Khmer)\n    Locale[\"km\"][\"name\"]               = \"Khmer\"\n    Locale[\"km\"][\"endonym\"]            = \"ភាសាខ្មែរ\"\n    Locale[\"km\"][\"translations-of\"]    = \"ការ​បក​ប្រែ​នៃ %s\"\n    Locale[\"km\"][\"definitions-of\"]     = \"និយមន័យ​នៃ​ %s\"\n    Locale[\"km\"][\"synonyms\"]           = \"សទិសន័យ\"\n    Locale[\"km\"][\"examples\"]           = \"ឧទាហរណ៍\"\n    Locale[\"km\"][\"see-also\"]           = \"មើល​ផង​ដែរ\"\n    Locale[\"km\"][\"family\"]             = \"Austroasiatic\"\n    Locale[\"km\"][\"branch\"]             = \"Khmeric\"\n    Locale[\"km\"][\"iso\"]                = \"khm\"\n    Locale[\"km\"][\"glotto\"]             = \"cent1989\"\n    Locale[\"km\"][\"script\"]             = \"Khmr\"\n    Locale[\"km\"][\"spoken-in\"]          = \"Cambodia; Thailand; Vietnam\"\n    Locale[\"km\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Kinyarwanda\n    Locale[\"rw\"][\"name\"]               = \"Kinyarwanda\"\n    Locale[\"rw\"][\"endonym\"]            = \"Ikinyarwanda\"\n    #Locale[\"rw\"][\"translations-of\"]\n    #Locale[\"rw\"][\"definitions-of\"]\n    #Locale[\"rw\"][\"synonyms\"]\n    #Locale[\"rw\"][\"examples\"]\n    #Locale[\"rw\"][\"see-also\"]\n    Locale[\"rw\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"rw\"][\"branch\"]             = \"Bantu\"\n    Locale[\"rw\"][\"iso\"]                = \"kin\"\n    Locale[\"rw\"][\"glotto\"]             = \"kiny1244\"\n    Locale[\"rw\"][\"script\"]             = \"Latn\"\n    Locale[\"rw\"][\"spoken-in\"]          = \"Rwanda; Uganda; DR Congo; Tanzania\"\n    Locale[\"rw\"][\"supported-by\"]       = \"google\"\n\n    # Klingon, Latin alphabet\n    Locale[\"tlh-Latn\"][\"name\"]         = \"Klingon\"\n    Locale[\"tlh-Latn\"][\"endonym\"]      = \"tlhIngan Hol\"\n    Locale[\"tlh-Latn\"][\"family\"]       = \"Constructed language\"\n    #Locale[\"tlh-Latn\"][\"branch\"]\n    Locale[\"tlh-Latn\"][\"iso\"]          = \"tlh-Latn\"\n    Locale[\"tlh-Latn\"][\"glotto\"]       = \"klin1234\"\n    Locale[\"tlh-Latn\"][\"script\"]       = \"Latn\"\n    Locale[\"tlh-Latn\"][\"spoken-in\"]    = \"the Star Trek universe\"\n    Locale[\"tlh-Latn\"][\"description\"]  = \"a fictional language spoken by the Klingons in the Star Trek universe\"\n    Locale[\"tlh-Latn\"][\"supported-by\"] = \"bing\"\n\n    ## Klingon, pIqaD\n    #Locale[\"tlh-Piqd\"][\"name\"]         = \"Klingon (pIqaD)\"\n    #Locale[\"tlh-Piqd\"][\"endonym\"]      = \" \"\n    #Locale[\"tlh-Piqd\"][\"family\"]       = \"Constructed language\"\n    ##Locale[\"tlh-Piqd\"][\"branch\"]\n    #Locale[\"tlh-Piqd\"][\"iso\"]          = \"tlh-Piqd\"\n    #Locale[\"tlh-Piqd\"][\"glotto\"]       = \"klin1234\"\n    #Locale[\"tlh-Piqd\"][\"script\"]       = \"Piqd\"\n    #Locale[\"tlh-Piqd\"][\"spoken-in\"]    = \"the Star Trek universe\"\n    #Locale[\"tlh-Piqd\"][\"description\"]  = \"a fictional language spoken by the Klingons in the Star Trek universe\"\n    #Locale[\"tlh-Piqd\"][\"supported-by\"] = \"bing\"\n\n    # Konkani (Goan Konkani)\n    Locale[\"gom\"][\"name\"]              = \"Konkani\"\n    Locale[\"gom\"][\"endonym\"]           = \"कोंकणी\"\n    #Locale[\"gom\"][\"translations-of\"]\n    #Locale[\"gom\"][\"definitions-of\"]\n    #Locale[\"gom\"][\"synonyms\"]\n    #Locale[\"gom\"][\"examples\"]\n    #Locale[\"gom\"][\"see-also\"]\n    Locale[\"gom\"][\"family\"]            = \"Indo-European\"\n    Locale[\"gom\"][\"branch\"]            = \"Indo-Aryan\"\n    Locale[\"gom\"][\"iso\"]               = \"gom\"\n    Locale[\"gom\"][\"glotto\"]            = \"goan1235\"\n    Locale[\"gom\"][\"script\"]            = \"Deva\"\n    Locale[\"gom\"][\"spoken-in\"]         = \"the western coastal region of India\"\n    Locale[\"gom\"][\"supported-by\"]      = \"google\"\n\n    # Korean\n    Locale[\"ko\"][\"name\"]               = \"Korean\"\n    Locale[\"ko\"][\"endonym\"]            = \"한국어\"\n    Locale[\"ko\"][\"translations-of\"]    = \"%s의 번역\"\n    Locale[\"ko\"][\"definitions-of\"]     = \"%s의 정의\"\n    Locale[\"ko\"][\"synonyms\"]           = \"동의어\"\n    Locale[\"ko\"][\"examples\"]           = \"예문\"\n    Locale[\"ko\"][\"see-also\"]           = \"참조\"\n    Locale[\"ko\"][\"family\"]             = \"Koreanic\"\n    #Locale[\"ko\"][\"branch\"]\n    Locale[\"ko\"][\"iso\"]                = \"kor\"\n    Locale[\"ko\"][\"glotto\"]             = \"kore1280\"\n    Locale[\"ko\"][\"script\"]             = \"Kore\"\n    Locale[\"ko\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"ko\"][\"spoken-in\"]          = \"South Korea; North Korea; China\"\n    Locale[\"ko\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Krio\n    Locale[\"kri\"][\"name\"]              = \"Krio\"\n    Locale[\"kri\"][\"endonym\"]           = \"Krio\"\n    #Locale[\"kri\"][\"translations-of\"]\n    #Locale[\"kri\"][\"definitions-of\"]\n    #Locale[\"kri\"][\"synonyms\"]\n    #Locale[\"kri\"][\"examples\"]\n    #Locale[\"kri\"][\"see-also\"]\n    Locale[\"kri\"][\"family\"]            = \"Indo-European\"\n    Locale[\"kri\"][\"branch\"]            = \"English Creole\"\n    Locale[\"kri\"][\"iso\"]               = \"kri\"\n    Locale[\"kri\"][\"glotto\"]            = \"krio1253\"\n    Locale[\"kri\"][\"script\"]            = \"Latn\"\n    Locale[\"kri\"][\"spoken-in\"]         = \"Sierra Leone\"\n    Locale[\"kri\"][\"supported-by\"]      = \"google\"\n\n    # Kurdish (Northern Kurdish) / Kurmanji\n    Locale[\"ku\"][\"name\"]               = \"Kurdish (Northern)\"\n    Locale[\"ku\"][\"name2\"]              = \"Kurmanji\"\n    Locale[\"ku\"][\"endonym\"]            = \"Kurmancî\"\n    Locale[\"ku\"][\"endonym2\"]           = \"Kurdî\"\n    #Locale[\"ku\"][\"translations-of\"]\n    #Locale[\"ku\"][\"definitions-of\"]\n    #Locale[\"ku\"][\"synonyms\"]\n    #Locale[\"ku\"][\"examples\"]\n    #Locale[\"ku\"][\"see-also\"]\n    Locale[\"ku\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ku\"][\"branch\"]             = \"Iranian\"\n    Locale[\"ku\"][\"iso\"]                = \"kmr\"\n    Locale[\"ku\"][\"glotto\"]             = \"nort2641\"\n    Locale[\"ku\"][\"script\"]             = \"Latn\"\n    Locale[\"ku\"][\"spoken-in\"]          = \"southeast Turkey; northwest and northeast Iran; northern Iraq; northern Syria; the Caucasus and Khorasan regions\"\n    Locale[\"ku\"][\"supported-by\"]       = \"google\"\n\n    # Kurdish (Central Kurdish) / Sorani\n    Locale[\"ckb\"][\"name\"]              = \"Kurdish (Central)\"\n    Locale[\"ckb\"][\"name2\"]             = \"Sorani\"\n    Locale[\"ckb\"][\"endonym\"]           = \"سۆرانی\"\n    Locale[\"ckb\"][\"endonym2\"]          = \"کوردیی ناوەندی\"\n    #Locale[\"ckb\"][\"translations-of\"]\n    #Locale[\"ckb\"][\"definitions-of\"]\n    #Locale[\"ckb\"][\"synonyms\"]\n    #Locale[\"ckb\"][\"examples\"]\n    #Locale[\"ckb\"][\"see-also\"]\n    Locale[\"ckb\"][\"family\"]            = \"Indo-European\"\n    Locale[\"ckb\"][\"branch\"]            = \"Iranian\"\n    Locale[\"ckb\"][\"iso\"]               = \"ckb\"\n    Locale[\"ckb\"][\"glotto\"]            = \"cent1972\"\n    Locale[\"ckb\"][\"script\"]            = \"Arab\"\n    Locale[\"ckb\"][\"rtl\"]               = \"true\" # RTL language\n    Locale[\"ckb\"][\"spoken-in\"]         = \"Iraqi Kurdistan; western Iran\"\n    Locale[\"ckb\"][\"supported-by\"]      = \"google\"\n\n    # Kyrgyz, Cyrillic alphabet\n    Locale[\"ky\"][\"name\"]               = \"Kyrgyz\"\n    Locale[\"ky\"][\"endonym\"]            = \"Кыргызча\"\n    Locale[\"ky\"][\"translations-of\"]    = \"%s котормосу\"\n    Locale[\"ky\"][\"definitions-of\"]     = \"%s аныктамасы\"\n    Locale[\"ky\"][\"synonyms\"]           = \"Синонимдер\"\n    Locale[\"ky\"][\"examples\"]           = \"Мисалдар\"\n    Locale[\"ky\"][\"see-also\"]           = \"Дагы караңыз\"\n    Locale[\"ky\"][\"family\"]             = \"Turkic\"\n    Locale[\"ky\"][\"branch\"]             = \"Kipchak\"\n    Locale[\"ky\"][\"iso\"]                = \"kir\"\n    Locale[\"ky\"][\"glotto\"]             = \"kirg1245\"\n    Locale[\"ky\"][\"script\"]             = \"Cyrl\"\n    Locale[\"ky\"][\"spoken-in\"]          = \"Kyrgyzstan; China; Tajikistan; Afghanistan; Pakistan\"\n    Locale[\"ky\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Lao\n    Locale[\"lo\"][\"name\"]               = \"Lao\"\n    Locale[\"lo\"][\"endonym\"]            = \"ລາວ\"\n    Locale[\"lo\"][\"translations-of\"]    = \"ຄຳ​ແປ​ສຳລັບ %s\"\n    Locale[\"lo\"][\"definitions-of\"]     = \"ຄວາມໝາຍຂອງ %s\"\n    Locale[\"lo\"][\"synonyms\"]           = \"ຄຳທີ່ຄ້າຍກັນ %s\"\n    Locale[\"lo\"][\"examples\"]           = \"ຕົວຢ່າງ\"\n    Locale[\"lo\"][\"see-also\"]           = \"ເບິ່ງ​ເພີ່ມ​ເຕີມ\"\n    Locale[\"lo\"][\"family\"]             = \"Kra-Dai\"\n    Locale[\"lo\"][\"branch\"]             = \"Tai\"\n    Locale[\"lo\"][\"iso\"]                = \"lao\"\n    Locale[\"lo\"][\"glotto\"]             = \"laoo1244\"\n    Locale[\"lo\"][\"script\"]             = \"Laoo\"\n    Locale[\"lo\"][\"spoken-in\"]          = \"Laos; Thailand; Cambodia\"\n    Locale[\"lo\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Latin\n    Locale[\"la\"][\"name\"]               = \"Latin\"\n    Locale[\"la\"][\"endonym\"]            = \"Latina\"\n    Locale[\"la\"][\"translations-of\"]    = \"Versio de %s\"\n    #Locale[\"la\"][\"definitions-of\"]\n    #Locale[\"la\"][\"synonyms\"]\n    #Locale[\"la\"][\"examples\"]\n    #Locale[\"la\"][\"see-also\"]\n    Locale[\"la\"][\"family\"]             = \"Indo-European\"\n    Locale[\"la\"][\"branch\"]             = \"Latino-Faliscan\"\n    Locale[\"la\"][\"iso\"]                = \"lat\"\n    Locale[\"la\"][\"glotto\"]             = \"lati1261\"\n    Locale[\"la\"][\"script\"]             = \"Latn\"\n    Locale[\"la\"][\"spoken-in\"]          = \"ancient Rome\"\n    Locale[\"la\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Latvian\n    Locale[\"lv\"][\"name\"]               = \"Latvian\"\n    Locale[\"lv\"][\"endonym\"]            = \"Latviešu\"\n    Locale[\"lv\"][\"translations-of\"]    = \"%s tulkojumi\"\n    Locale[\"lv\"][\"definitions-of\"]     = \"%s definīcijas\"\n    Locale[\"lv\"][\"synonyms\"]           = \"Sinonīmi\"\n    Locale[\"lv\"][\"examples\"]           = \"Piemēri\"\n    Locale[\"lv\"][\"see-also\"]           = \"Skatiet arī\"\n    Locale[\"lv\"][\"family\"]             = \"Indo-European\"\n    Locale[\"lv\"][\"branch\"]             = \"Eastern Baltic\"\n    Locale[\"lv\"][\"iso\"]                = \"lav\"\n    Locale[\"lv\"][\"glotto\"]             = \"latv1249\"\n    Locale[\"lv\"][\"script\"]             = \"Latn\"\n    Locale[\"lv\"][\"spoken-in\"]          = \"Latvia\"\n    Locale[\"lv\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Lingala\n    Locale[\"ln\"][\"name\"]               = \"Lingala\"\n    Locale[\"ln\"][\"endonym\"]            = \"Lingála\"\n    #Locale[\"ln\"][\"translations-of\"]\n    #Locale[\"ln\"][\"definitions-of\"]\n    #Locale[\"ln\"][\"synonyms\"]\n    #Locale[\"ln\"][\"examples\"]\n    #Locale[\"ln\"][\"see-also\"]\n    Locale[\"ln\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"ln\"][\"branch\"]             = \"Bantu\"\n    Locale[\"ln\"][\"iso\"]                = \"lin\"\n    Locale[\"ln\"][\"glotto\"]             = \"ling1269\"\n    Locale[\"ln\"][\"script\"]             = \"Latn\"\n    Locale[\"ln\"][\"spoken-in\"]          = \"DR Congo; Republic of the Congo; Angola; Central African Republic; southern South Sudan\"\n    Locale[\"ln\"][\"supported-by\"]       = \"google\"\n\n    # Lithuanian\n    Locale[\"lt\"][\"name\"]               = \"Lithuanian\"\n    Locale[\"lt\"][\"endonym\"]            = \"Lietuvių\"\n    Locale[\"lt\"][\"translations-of\"]    = \"„%s“ vertimai\"\n    Locale[\"lt\"][\"definitions-of\"]     = \"„%s“ apibrėžimai\"\n    Locale[\"lt\"][\"synonyms\"]           = \"Sinonimai\"\n    Locale[\"lt\"][\"examples\"]           = \"Pavyzdžiai\"\n    Locale[\"lt\"][\"see-also\"]           = \"Taip pat žiūrėkite\"\n    Locale[\"lt\"][\"family\"]             = \"Indo-European\"\n    Locale[\"lt\"][\"branch\"]             = \"Eastern Baltic\"\n    Locale[\"lt\"][\"iso\"]                = \"lit\"\n    Locale[\"lt\"][\"glotto\"]             = \"lith1251\"\n    Locale[\"lt\"][\"script\"]             = \"Latn\"\n    Locale[\"lt\"][\"spoken-in\"]          = \"Lithuania\"\n    Locale[\"lt\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Luganda\n    Locale[\"lg\"][\"name\"]               = \"Luganda\"\n    Locale[\"lg\"][\"endonym\"]            = \"Luganda\"\n    Locale[\"lg\"][\"endonym2\"]           = \"Oluganda\"\n    #Locale[\"lg\"][\"translations-of\"]\n    #Locale[\"lg\"][\"definitions-of\"]\n    #Locale[\"lg\"][\"synonyms\"]\n    #Locale[\"lg\"][\"examples\"]\n    #Locale[\"lg\"][\"see-also\"]\n    Locale[\"lg\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"lg\"][\"branch\"]             = \"Bantu\"\n    Locale[\"lg\"][\"iso\"]                = \"lug\"\n    Locale[\"lg\"][\"glotto\"]             = \"gand1255\"\n    Locale[\"lg\"][\"script\"]             = \"Latn\"\n    Locale[\"lg\"][\"spoken-in\"]          = \"Uganda; Rwanda\"\n    Locale[\"lg\"][\"supported-by\"]       = \"google\"\n\n    # Luxembourgish\n    Locale[\"lb\"][\"name\"]               = \"Luxembourgish\"\n    Locale[\"lb\"][\"endonym\"]            = \"Lëtzebuergesch\"\n    #Locale[\"lb\"][\"translations-of\"]\n    #Locale[\"lb\"][\"definitions-of\"]\n    #Locale[\"lb\"][\"synonyms\"]\n    #Locale[\"lb\"][\"examples\"]\n    #Locale[\"lb\"][\"see-also\"]\n    Locale[\"lb\"][\"family\"]             = \"Indo-European\"\n    Locale[\"lb\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"lb\"][\"iso\"]                = \"ltz\"\n    Locale[\"lb\"][\"glotto\"]             = \"luxe1241\"\n    Locale[\"lb\"][\"script\"]             = \"Latn\"\n    Locale[\"lb\"][\"spoken-in\"]          = \"Luxembourg\"\n    Locale[\"lb\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Macedonian\n    Locale[\"mk\"][\"name\"]               = \"Macedonian\"\n    Locale[\"mk\"][\"endonym\"]            = \"Македонски\"\n    Locale[\"mk\"][\"translations-of\"]    = \"Преводи на %s\"\n    Locale[\"mk\"][\"definitions-of\"]     = \"Дефиниции на %s\"\n    Locale[\"mk\"][\"synonyms\"]           = \"Синоними\"\n    Locale[\"mk\"][\"examples\"]           = \"Примери\"\n    Locale[\"mk\"][\"see-also\"]           = \"Види и\"\n    Locale[\"mk\"][\"family\"]             = \"Indo-European\"\n    Locale[\"mk\"][\"branch\"]             = \"South Slavic\"\n    Locale[\"mk\"][\"iso\"]                = \"mkd\"\n    Locale[\"mk\"][\"glotto\"]             = \"mace1250\"\n    Locale[\"mk\"][\"script\"]             = \"Cyrl\"\n    Locale[\"mk\"][\"spoken-in\"]          = \"North Macedonia; Albania; Bosnia and Herzegovina; Romania; Serbia\"\n    Locale[\"mk\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Maithili\n    Locale[\"mai\"][\"name\"]              = \"Maithili\"\n    Locale[\"mai\"][\"endonym\"]           = \"मैथिली\"\n    #Locale[\"mai\"][\"translations-of\"]\n    #Locale[\"mai\"][\"definitions-of\"]\n    #Locale[\"mai\"][\"synonyms\"]\n    #Locale[\"mai\"][\"examples\"]\n    #Locale[\"mai\"][\"see-also\"]\n    Locale[\"mai\"][\"family\"]            = \"Indo-European\"\n    Locale[\"mai\"][\"branch\"]            = \"Indo-Aryan\"\n    Locale[\"mai\"][\"iso\"]               = \"mai\"\n    Locale[\"mai\"][\"glotto\"]            = \"mait1250\"\n    Locale[\"mai\"][\"script\"]            = \"Deva\"\n    Locale[\"mai\"][\"spoken-in\"]         = \"the Mithila region in India and Nepal\"\n    Locale[\"mai\"][\"supported-by\"]      = \"google\"\n\n    # Malagasy (Plateau Malagasy)\n    Locale[\"mg\"][\"name\"]               = \"Malagasy\"\n    Locale[\"mg\"][\"endonym\"]            = \"Malagasy\"\n    Locale[\"mg\"][\"translations-of\"]    = \"Dikan'ny %s\"\n    Locale[\"mg\"][\"definitions-of\"]     = \"Famaritana ny %s\"\n    Locale[\"mg\"][\"synonyms\"]           = \"Mitovy hevitra\"\n    Locale[\"mg\"][\"examples\"]           = \"Ohatra\"\n    Locale[\"mg\"][\"see-also\"]           = \"Jereo ihany koa\"\n    Locale[\"mg\"][\"family\"]             = \"Austronesian\"\n    Locale[\"mg\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"mg\"][\"iso\"]                = \"mlg\"\n    Locale[\"mg\"][\"glotto\"]             = \"plat1254\"\n    Locale[\"mg\"][\"script\"]             = \"Latn\"\n    Locale[\"mg\"][\"spoken-in\"]          = \"Madagascar; the Comoros; Mayotte\"\n    Locale[\"mg\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Malay (Standard Malay), Latin alphabet\n    Locale[\"ms\"][\"name\"]               = \"Malay\"\n    Locale[\"ms\"][\"endonym\"]            = \"Bahasa Melayu\"\n    Locale[\"ms\"][\"translations-of\"]    = \"Terjemahan %s\"\n    Locale[\"ms\"][\"definitions-of\"]     = \"Takrif %s\"\n    Locale[\"ms\"][\"synonyms\"]           = \"Sinonim\"\n    Locale[\"ms\"][\"examples\"]           = \"Contoh\"\n    Locale[\"ms\"][\"see-also\"]           = \"Lihat juga\"\n    Locale[\"ms\"][\"family\"]             = \"Austronesian\"\n    Locale[\"ms\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"ms\"][\"iso\"]                = \"msa\"\n    Locale[\"ms\"][\"glotto\"]             = \"stan1306\"\n    Locale[\"ms\"][\"script\"]             = \"Latn\"\n    Locale[\"ms\"][\"spoken-in\"]          = \"Malaysia; Singapore; Indonesia; Brunei; East Timor\"\n    Locale[\"ms\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Malayalam\n    Locale[\"ml\"][\"name\"]               = \"Malayalam\"\n    Locale[\"ml\"][\"endonym\"]            = \"മലയാളം\"\n    Locale[\"ml\"][\"translations-of\"]    = \"%s എന്നതിന്റെ വിവർത്തനങ്ങൾ\"\n    Locale[\"ml\"][\"definitions-of\"]     = \"%s എന്നതിന്റെ നിർവ്വചനങ്ങൾ\"\n    Locale[\"ml\"][\"synonyms\"]           = \"പര്യായങ്ങള്‍\"\n    Locale[\"ml\"][\"examples\"]           = \"ഉദാഹരണങ്ങള്‍\"\n    Locale[\"ml\"][\"see-also\"]           = \"ഇതും കാണുക\"\n    Locale[\"ml\"][\"family\"]             = \"Dravidian\"\n    Locale[\"ml\"][\"branch\"]             = \"South Dravidian\"\n    Locale[\"ml\"][\"iso\"]                = \"mal\"\n    Locale[\"ml\"][\"glotto\"]             = \"mala1464\"\n    Locale[\"ml\"][\"script\"]             = \"Mlym\"\n    Locale[\"ml\"][\"spoken-in\"]          = \"Kerala, Lakshadweep and Puducherry in India\"\n    Locale[\"ml\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Maltese\n    Locale[\"mt\"][\"name\"]               = \"Maltese\"\n    Locale[\"mt\"][\"endonym\"]            = \"Malti\"\n    Locale[\"mt\"][\"translations-of\"]    = \"Traduzzjonijiet ta' %s\"\n    Locale[\"mt\"][\"definitions-of\"]     = \"Definizzjonijiet ta' %s\"\n    Locale[\"mt\"][\"synonyms\"]           = \"Sinonimi\"\n    Locale[\"mt\"][\"examples\"]           = \"Eżempji\"\n    Locale[\"mt\"][\"see-also\"]           = \"Ara wkoll\"\n    Locale[\"mt\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"mt\"][\"branch\"]             = \"Semitic\"\n    Locale[\"mt\"][\"iso\"]                = \"mlt\"\n    Locale[\"mt\"][\"glotto\"]             = \"malt1254\"\n    Locale[\"mt\"][\"script\"]             = \"Latn\"\n    Locale[\"mt\"][\"spoken-in\"]          = \"Malta\"\n    Locale[\"mt\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Maori\n    Locale[\"mi\"][\"name\"]               = \"Maori\"\n    Locale[\"mi\"][\"endonym\"]            = \"Māori\"\n    Locale[\"mi\"][\"translations-of\"]    = \"Ngā whakamāoritanga o %s\"\n    Locale[\"mi\"][\"definitions-of\"]     = \"Ngā whakamārama o %s\"\n    Locale[\"mi\"][\"synonyms\"]           = \"Ngā Kupu Taurite\"\n    Locale[\"mi\"][\"examples\"]           = \"Ngā Tauira:\"\n    Locale[\"mi\"][\"see-also\"]           = \"Tiro hoki:\"\n    Locale[\"mi\"][\"family\"]             = \"Austronesian\"\n    Locale[\"mi\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"mi\"][\"iso\"]                = \"mri\"\n    Locale[\"mi\"][\"glotto\"]             = \"maor1246\"\n    Locale[\"mi\"][\"script\"]             = \"Latn\"\n    Locale[\"mi\"][\"spoken-in\"]          = \"New Zealand\"\n    Locale[\"mi\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Marathi\n    Locale[\"mr\"][\"name\"]               = \"Marathi\"\n    Locale[\"mr\"][\"endonym\"]            = \"मराठी\"\n    Locale[\"mr\"][\"translations-of\"]    = \"%s ची भाषांतरे\"\n    Locale[\"mr\"][\"definitions-of\"]     = \"%s च्या व्याख्या\"\n    Locale[\"mr\"][\"synonyms\"]           = \"समानार्थी शब्द\"\n    Locale[\"mr\"][\"examples\"]           = \"उदाहरणे\"\n    Locale[\"mr\"][\"see-also\"]           = \"हे देखील पहा\"\n    Locale[\"mr\"][\"family\"]             = \"Indo-European\"\n    Locale[\"mr\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"mr\"][\"iso\"]                = \"mar\"\n    Locale[\"mr\"][\"glotto\"]             = \"mara1378\"\n    Locale[\"mr\"][\"script\"]             = \"Deva\"\n    Locale[\"mr\"][\"spoken-in\"]          = \"the Indian state of Maharashtra\"\n    Locale[\"mr\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Mari (Eastern Mari / Meadow Mari)\n    Locale[\"mhr\"][\"name\"]              = \"Eastern Mari\"\n    Locale[\"mhr\"][\"name2\"]             = \"Meadow Mari\"\n    Locale[\"mhr\"][\"endonym\"]           = \"Олык марий\"\n    #Locale[\"mhr\"][\"translations-of\"]\n    #Locale[\"mhr\"][\"definitions-of\"]\n    #Locale[\"mhr\"][\"synonyms\"]\n    #Locale[\"mhr\"][\"examples\"]\n    #Locale[\"mhr\"][\"see-also\"]\n    Locale[\"mhr\"][\"family\"]            = \"Uralic\"\n    Locale[\"mhr\"][\"branch\"]            = \"Mari\"\n    Locale[\"mhr\"][\"iso\"]               = \"mhr\"\n    Locale[\"mhr\"][\"glotto\"]            = \"east2328\"\n    Locale[\"mhr\"][\"script\"]            = \"Cyrl\"\n    Locale[\"mhr\"][\"spoken-in\"]         = \"Mari El, Russia\"\n    Locale[\"mhr\"][\"supported-by\"]      = \"yandex\"\n\n    # Meiteilon / Manipuri\n    Locale[\"mni-Mtei\"][\"name\"]         = \"Meiteilon\"\n    Locale[\"mni-Mtei\"][\"name2\"]        = \"Manipuri\"\n    Locale[\"mni-Mtei\"][\"name3\"]        = \"Meitei\"\n    Locale[\"mni-Mtei\"][\"name4\"]        = \"Meetei\"\n    Locale[\"mni-Mtei\"][\"endonym\"]      = \"ꯃꯤꯇꯩꯂꯣꯟ\"\n    #Locale[\"mni-Mtei\"][\"translations-of\"]\n    #Locale[\"mni-Mtei\"][\"definitions-of\"]\n    #Locale[\"mni-Mtei\"][\"synonyms\"]\n    #Locale[\"mni-Mtei\"][\"examples\"]\n    #Locale[\"mni-Mtei\"][\"see-also\"]\n    Locale[\"mni-Mtei\"][\"family\"]       = \"Sino-Tibetan\"\n    Locale[\"mni-Mtei\"][\"branch\"]       = \"Tibeto-Burman\"\n    Locale[\"mni-Mtei\"][\"iso\"]          = \"mni\"\n    Locale[\"mni-Mtei\"][\"glotto\"]       = \"mani1292\"\n    Locale[\"mni-Mtei\"][\"script\"]       = \"Mtei\"\n    Locale[\"mni-Mtei\"][\"spoken-in\"]    = \"the northeastern India; Bangladesh; Myanmar\"\n    Locale[\"mni-Mtei\"][\"supported-by\"] = \"google\"\n\n    # Mizo\n    Locale[\"lus\"][\"name\"]              = \"Mizo\"\n    Locale[\"lus\"][\"endonym\"]           = \"Mizo ṭawng\"\n    #Locale[\"lus\"][\"translations-of\"]\n    #Locale[\"lus\"][\"definitions-of\"]\n    #Locale[\"lus\"][\"synonyms\"]\n    #Locale[\"lus\"][\"examples\"]\n    #Locale[\"lus\"][\"see-also\"]\n    Locale[\"lus\"][\"family\"]            = \"Sino-Tibetan\"\n    Locale[\"lus\"][\"branch\"]            = \"Tibeto-Burman\"\n    Locale[\"lus\"][\"iso\"]               = \"lus\"\n    Locale[\"lus\"][\"glotto\"]            = \"lush1249\"\n    Locale[\"lus\"][\"script\"]            = \"Latn\"\n    Locale[\"lus\"][\"spoken-in\"]         = \"the Indian state of Mizoram\"\n    Locale[\"lus\"][\"supported-by\"]      = \"google\"\n\n    # Mongolian, Cyrillic alphabet\n    Locale[\"mn\"][\"name\"]               = \"Mongolian\"\n    Locale[\"mn\"][\"endonym\"]            = \"Монгол\"\n    Locale[\"mn\"][\"translations-of\"]    = \"%s-н орчуулга\"\n    Locale[\"mn\"][\"definitions-of\"]     = \"%s үгийн тодорхойлолт\"\n    Locale[\"mn\"][\"synonyms\"]           = \"Ойролцоо утгатай\"\n    Locale[\"mn\"][\"examples\"]           = \"Жишээнүүд\"\n    Locale[\"mn\"][\"see-also\"]           = \"Мөн харах\"\n    Locale[\"mn\"][\"family\"]             = \"Mongolic\"\n    #Locale[\"mn\"][\"branch\"]\n    Locale[\"mn\"][\"iso\"]                = \"mon\"\n    Locale[\"mn\"][\"glotto\"]             = \"mong1331\"\n    Locale[\"mn\"][\"script\"]             = \"Cyrl\"\n    Locale[\"mn\"][\"spoken-in\"]          = \"Mongolia; Inner Mongolia in China\"\n    Locale[\"mn\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Mongolian, traditional Mongolian alphabet\n    Locale[\"mn-Mong\"][\"name\"]          = \"Mongolian (Traditional)\"\n    Locale[\"mn-Mong\"][\"endonym\"]       = \"ᠮᠣᠩᠭᠣᠯ\"\n    #Locale[\"mn-Mong\"][\"translations-of\"]\n    #Locale[\"mn-Mong\"][\"definitions-of\"]\n    #Locale[\"mn-Mong\"][\"synonyms\"]\n    #Locale[\"mn-Mong\"][\"examples\"]\n    #Locale[\"mn-Mong\"][\"see-also\"]\n    Locale[\"mn-Mong\"][\"family\"]        = \"Mongolic\"\n    #Locale[\"mn-Mong\"][\"branch\"]\n    Locale[\"mn-Mong\"][\"iso\"]           = \"mon-Mong\"\n    Locale[\"mn-Mong\"][\"glotto\"]        = \"mong1331\"\n    Locale[\"mn-Mong\"][\"script\"]        = \"Mong\"\n    Locale[\"mn-Mong\"][\"spoken-in\"]     = \"Mongolia; Inner Mongolia in China\"\n    Locale[\"mn-Mong\"][\"supported-by\"]  = \"bing\"\n\n    # Myanmar / Burmese\n    Locale[\"my\"][\"name\"]               = \"Myanmar\"\n    Locale[\"my\"][\"name2\"]              = \"Burmese\"\n    Locale[\"my\"][\"endonym\"]            = \"မြန်မာစာ\"\n    Locale[\"my\"][\"translations-of\"]    = \"%s၏ ဘာသာပြန်ဆိုချက်များ\"\n    Locale[\"my\"][\"definitions-of\"]     = \"%s၏ အနက်ဖွင့်ဆိုချက်များ\"\n    Locale[\"my\"][\"synonyms\"]           = \"ကြောင်းတူသံကွဲများ\"\n    Locale[\"my\"][\"examples\"]           = \"ဥပမာ\"\n    Locale[\"my\"][\"see-also\"]           = \"ဖော်ပြပါများကိုလဲ ကြည့်ပါ\"\n    Locale[\"my\"][\"family\"]             = \"Sino-Tibetan\"\n    Locale[\"my\"][\"branch\"]             = \"Tibeto-Burman\"\n    Locale[\"my\"][\"iso\"]                = \"mya\"\n    Locale[\"my\"][\"glotto\"]             = \"nucl1310\"\n    Locale[\"my\"][\"script\"]             = \"Mymr\"\n    Locale[\"my\"][\"spoken-in\"]          = \"Myanmar\"\n    Locale[\"my\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Nepali\n    Locale[\"ne\"][\"name\"]               = \"Nepali\"\n    Locale[\"ne\"][\"endonym\"]            = \"नेपाली\"\n    Locale[\"ne\"][\"translations-of\"]    = \"%sका अनुवाद\"\n    Locale[\"ne\"][\"definitions-of\"]     = \"%sको परिभाषा\"\n    Locale[\"ne\"][\"synonyms\"]           = \"समानार्थीहरू\"\n    Locale[\"ne\"][\"examples\"]           = \"उदाहरणहरु\"\n    Locale[\"ne\"][\"see-also\"]           = \"यो पनि हेर्नुहोस्\"\n    Locale[\"ne\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ne\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"ne\"][\"iso\"]                = \"nep\"\n    Locale[\"ne\"][\"glotto\"]             = \"nepa1254\"\n    Locale[\"ne\"][\"script\"]             = \"Deva\"\n    Locale[\"ne\"][\"spoken-in\"]          = \"Nepal; India\"\n    Locale[\"ne\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Norwegian\n    Locale[\"no\"][\"name\"]               = \"Norwegian\"\n    Locale[\"no\"][\"endonym\"]            = \"Norsk\"\n    Locale[\"no\"][\"translations-of\"]    = \"Oversettelser av %s\"\n    Locale[\"no\"][\"definitions-of\"]     = \"Definisjoner av %s\"\n    Locale[\"no\"][\"synonyms\"]           = \"Synonymer\"\n    Locale[\"no\"][\"examples\"]           = \"Eksempler\"\n    Locale[\"no\"][\"see-also\"]           = \"Se også\"\n    Locale[\"no\"][\"family\"]             = \"Indo-European\"\n    Locale[\"no\"][\"branch\"]             = \"North Germanic\"\n    Locale[\"no\"][\"iso\"]                = \"nor\"\n    Locale[\"no\"][\"glotto\"]             = \"norw1258\"\n    Locale[\"no\"][\"script\"]             = \"Latn\"\n    Locale[\"no\"][\"spoken-in\"]          = \"Norway\"\n    Locale[\"no\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Occitan\n    Locale[\"oc\"][\"name\"]               = \"Occitan\"\n    Locale[\"oc\"][\"endonym\"]            = \"Occitan\"\n    #Locale[\"oc\"][\"translations-of\"]\n    #Locale[\"oc\"][\"definitions-of\"]\n    #Locale[\"oc\"][\"synonyms\"]\n    #Locale[\"oc\"][\"examples\"]\n    #Locale[\"oc\"][\"see-also\"]\n    Locale[\"oc\"][\"family\"]             = \"Indo-European\"\n    Locale[\"oc\"][\"branch\"]             = \"Western Romance\"\n    Locale[\"oc\"][\"iso\"]                = \"oci\"\n    Locale[\"oc\"][\"glotto\"]             = \"occi1239\"\n    Locale[\"oc\"][\"script\"]             = \"Latn\"\n    Locale[\"oc\"][\"spoken-in\"]          = \"Occitania in France, Monaco, Italy and Spain\"\n    Locale[\"oc\"][\"supported-by\"]       = \"\"\n\n    # Odia / Oriya\n    Locale[\"or\"][\"name\"]               = \"Odia\"\n    Locale[\"or\"][\"name2\"]              = \"Oriya\"\n    Locale[\"or\"][\"endonym\"]            = \"ଓଡ଼ିଆ\"\n    #Locale[\"or\"][\"translations-of\"]\n    #Locale[\"or\"][\"definitions-of\"]\n    #Locale[\"or\"][\"synonyms\"]\n    #Locale[\"or\"][\"examples\"]\n    #Locale[\"or\"][\"see-also\"]\n    Locale[\"or\"][\"family\"]             = \"Indo-European\"\n    Locale[\"or\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"or\"][\"iso\"]                = \"ori\"\n    Locale[\"or\"][\"glotto\"]             = \"macr1269\"\n    Locale[\"or\"][\"script\"]             = \"Orya\"\n    Locale[\"or\"][\"spoken-in\"]          = \"the Indian state of Odisha\"\n    Locale[\"or\"][\"supported-by\"]       = \"google; bing\"\n\n    # Oromo\n    Locale[\"om\"][\"name\"]               = \"Oromo\"\n    Locale[\"om\"][\"endonym\"]            = \"Afaan Oromoo\"\n    #Locale[\"om\"][\"translations-of\"]\n    #Locale[\"om\"][\"definitions-of\"]\n    #Locale[\"om\"][\"synonyms\"]\n    #Locale[\"om\"][\"examples\"]\n    #Locale[\"om\"][\"see-also\"]\n    Locale[\"om\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"om\"][\"branch\"]             = \"Cushitic\"\n    Locale[\"om\"][\"iso\"]                = \"orm\"\n    Locale[\"om\"][\"glotto\"]             = \"nucl1736\"\n    Locale[\"om\"][\"script\"]             = \"Latn\"\n    Locale[\"om\"][\"spoken-in\"]          = \"the Ethiopian state of Oromia; northeastern Kenya\"\n    Locale[\"om\"][\"supported-by\"]       = \"google\"\n\n    # Papiamento\n    Locale[\"pap\"][\"name\"]              = \"Papiamento\"\n    Locale[\"pap\"][\"endonym\"]           = \"Papiamentu\"\n    #Locale[\"pap\"][\"translations-of\"]\n    #Locale[\"pap\"][\"definitions-of\"]\n    #Locale[\"pap\"][\"synonyms\"]\n    #Locale[\"pap\"][\"examples\"]\n    #Locale[\"pap\"][\"see-also\"]\n    Locale[\"pap\"][\"family\"]            = \"Indo-European\"\n    Locale[\"pap\"][\"branch\"]            = \"Portuguese Creole\"\n    Locale[\"pap\"][\"iso\"]               = \"pap\"\n    Locale[\"pap\"][\"glotto\"]            = \"papi1253\"\n    Locale[\"pap\"][\"script\"]            = \"Latn\"\n    Locale[\"pap\"][\"spoken-in\"]         = \"the Dutch Caribbean\"\n    Locale[\"pap\"][\"supported-by\"]      = \"yandex\"\n\n    # Pashto / Pushto\n    Locale[\"ps\"][\"name\"]               = \"Pashto\"\n    Locale[\"ps\"][\"name2\"]              = \"Pushto\"\n    Locale[\"ps\"][\"endonym\"]            = \"پښتو\"\n    Locale[\"ps\"][\"translations-of\"]    = \"د %sژباړې\"\n    Locale[\"ps\"][\"definitions-of\"]     = \"د%s تعریفونه\"\n    Locale[\"ps\"][\"synonyms\"]           = \"مترادف لغتونه\"\n    Locale[\"ps\"][\"examples\"]           = \"بېلګې\"\n    Locale[\"ps\"][\"see-also\"]           = \"دا هم ووینئ\"\n    Locale[\"ps\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ps\"][\"branch\"]             = \"Iranian\"\n    Locale[\"ps\"][\"iso\"]                = \"pus\"\n    Locale[\"ps\"][\"glotto\"]             = \"pash1269\"\n    Locale[\"ps\"][\"script\"]             = \"Arab\"\n    Locale[\"ps\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"ps\"][\"spoken-in\"]          = \"Afghanistan; Pakistan\"\n    Locale[\"ps\"][\"supported-by\"]       = \"google; bing\"\n\n    # Persian / Farsi (Western Farsi / Iranian Persian)\n    Locale[\"fa\"][\"name\"]               = \"Persian\"\n    Locale[\"fa\"][\"name2\"]              = \"Farsi\"\n    Locale[\"fa\"][\"endonym\"]            = \"فارسی\"\n    Locale[\"fa\"][\"translations-of\"]    = \"ترجمه‌های %s\"\n    Locale[\"fa\"][\"definitions-of\"]     = \"تعریف‌های %s\"\n    Locale[\"fa\"][\"synonyms\"]           = \"مترادف‌ها\"\n    Locale[\"fa\"][\"examples\"]           = \"مثال‌ها\"\n    Locale[\"fa\"][\"see-also\"]           = \"همچنین مراجعه کنید به\"\n    Locale[\"fa\"][\"family\"]             = \"Indo-European\"\n    Locale[\"fa\"][\"branch\"]             = \"Iranian\"\n    Locale[\"fa\"][\"iso\"]                = \"fas\"\n    Locale[\"fa\"][\"glotto\"]             = \"west2369\"\n    Locale[\"fa\"][\"script\"]             = \"Arab\"\n    Locale[\"fa\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"fa\"][\"spoken-in\"]          = \"Iran\"\n    Locale[\"fa\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Polish\n    Locale[\"pl\"][\"name\"]               = \"Polish\"\n    Locale[\"pl\"][\"endonym\"]            = \"Polski\"\n    Locale[\"pl\"][\"translations-of\"]    = \"Tłumaczenia %s\"\n    Locale[\"pl\"][\"definitions-of\"]     = \"%s – definicje\"\n    Locale[\"pl\"][\"synonyms\"]           = \"Synonimy\"\n    Locale[\"pl\"][\"examples\"]           = \"Przykłady\"\n    Locale[\"pl\"][\"see-also\"]           = \"Zobacz też\"\n    Locale[\"pl\"][\"family\"]             = \"Indo-European\"\n    Locale[\"pl\"][\"branch\"]             = \"West Slavic\"\n    Locale[\"pl\"][\"iso\"]                = \"pol\"\n    Locale[\"pl\"][\"glotto\"]             = \"poli1260\"\n    Locale[\"pl\"][\"script\"]             = \"Latn\"\n    Locale[\"pl\"][\"spoken-in\"]          = \"Poland\"\n    Locale[\"pl\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Portuguese (Brazilian)\n    Locale[\"pt-BR\"][\"name\"]            = \"Portuguese (Brazilian)\"\n    Locale[\"pt-BR\"][\"endonym\"]         = \"Português Brasileiro\"\n    Locale[\"pt-BR\"][\"translations-of\"] = \"Traduções de %s\"\n    Locale[\"pt-BR\"][\"definitions-of\"]  = \"Definições de %s\"\n    Locale[\"pt-BR\"][\"synonyms\"]        = \"Sinônimos\"\n    Locale[\"pt-BR\"][\"examples\"]        = \"Exemplos\"\n    Locale[\"pt-BR\"][\"see-also\"]        = \"Veja também\"\n    Locale[\"pt-BR\"][\"family\"]          = \"Indo-European\"\n    Locale[\"pt-BR\"][\"branch\"]          = \"Western Romance\"\n    Locale[\"pt-BR\"][\"iso\"]             = \"por\"\n    Locale[\"pt-BR\"][\"glotto\"]          = \"braz1246\"\n    Locale[\"pt-BR\"][\"script\"]          = \"Latn\"\n    Locale[\"pt-BR\"][\"dictionary\"]      = \"true\" # has dictionary\n    Locale[\"pt-BR\"][\"spoken-in\"]       = \"Portugal; Brazil; Cape Verde; Angola; Mozambique; Guinea-Bissau; Equatorial Guinea; São Tomé and Príncipe; East Timor; Macau\"\n    Locale[\"pt-BR\"][\"supported-by\"]    = \"google; bing; yandex\"\n\n    # Portuguese (European)\n    Locale[\"pt-PT\"][\"name\"]            = \"Portuguese (European)\"\n    Locale[\"pt-PT\"][\"endonym\"]         = \"Português Europeu\"\n    Locale[\"pt-PT\"][\"translations-of\"] = \"Traduções de %s\"\n    Locale[\"pt-PT\"][\"definitions-of\"]  = \"Definições de %s\"\n    Locale[\"pt-PT\"][\"synonyms\"]        = \"Sinônimos\"\n    Locale[\"pt-PT\"][\"examples\"]        = \"Exemplos\"\n    Locale[\"pt-PT\"][\"see-also\"]        = \"Veja também\"\n    Locale[\"pt-PT\"][\"family\"]          = \"Indo-European\"\n    Locale[\"pt-PT\"][\"branch\"]          = \"Western Romance\"\n    Locale[\"pt-PT\"][\"iso\"]             = \"por\"\n    Locale[\"pt-PT\"][\"glotto\"]          = \"port1283\"\n    Locale[\"pt-PT\"][\"script\"]          = \"Latn\"\n    Locale[\"pt-PT\"][\"spoken-in\"]       = \"Portugal; Brazil; Cape Verde; Angola; Mozambique; Guinea-Bissau; Equatorial Guinea; São Tomé and Príncipe; East Timor; Macau\"\n    Locale[\"pt-PT\"][\"supported-by\"]    = \"bing\"\n\n    # Punjabi, Gurmukhī alphabet\n    Locale[\"pa\"][\"name\"]               = \"Punjabi\"\n    Locale[\"pa\"][\"endonym\"]            = \"ਪੰਜਾਬੀ\"\n    Locale[\"pa\"][\"translations-of\"]    = \"ਦੇ ਅਨੁਵਾਦ%s\"\n    Locale[\"pa\"][\"definitions-of\"]     = \"ਦੀਆਂ ਪਰਿਭਾਸ਼ਾ %s\"\n    Locale[\"pa\"][\"synonyms\"]           = \"ਸਮਾਨਾਰਥਕ ਸ਼ਬਦ\"\n    Locale[\"pa\"][\"examples\"]           = \"ਉਦਾਹਰਣਾਂ\"\n    Locale[\"pa\"][\"see-also\"]           = \"ਇਹ ਵੀ ਵੇਖੋ\"\n    Locale[\"pa\"][\"family\"]             = \"Indo-European\"\n    Locale[\"pa\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"pa\"][\"iso\"]                = \"pan\"\n    Locale[\"pa\"][\"glotto\"]             = \"panj1256\"\n    Locale[\"pa\"][\"script\"]             = \"Guru\"\n    Locale[\"pa\"][\"spoken-in\"]          = \"the Punjab region of India and Pakistan\"\n    Locale[\"pa\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Quechua\n    Locale[\"qu\"][\"name\"]               = \"Quechua\"\n    Locale[\"qu\"][\"endonym\"]            = \"Runasimi\"\n    #Locale[\"qu\"][\"translations-of\"]\n    #Locale[\"qu\"][\"definitions-of\"]\n    #Locale[\"qu\"][\"synonyms\"]\n    #Locale[\"qu\"][\"examples\"]\n    #Locale[\"qu\"][\"see-also\"]\n    Locale[\"qu\"][\"family\"]             = \"Quechuan\"\n    #Locale[\"qu\"][\"branch\"]\n    Locale[\"qu\"][\"iso\"]                = \"que\"\n    Locale[\"qu\"][\"glotto\"]             = \"quec1387\"\n    Locale[\"qu\"][\"script\"]             = \"Latn\"\n    Locale[\"qu\"][\"spoken-in\"]          = \"Peru; Bolivia; Ecuador; surrounding countries\"\n    Locale[\"qu\"][\"supported-by\"]       = \"google\"\n\n    # Querétaro Otomi\n    Locale[\"otq\"][\"name\"]              = \"Querétaro Otomi\"\n    Locale[\"otq\"][\"endonym\"]           = \"Hñąñho\"\n    Locale[\"otq\"][\"family\"]            = \"Oto-Manguean\"\n    #Locale[\"otq\"][\"branch\"]\n    Locale[\"otq\"][\"iso\"]               = \"otq\"\n    Locale[\"otq\"][\"glotto\"]            = \"quer1236\"\n    Locale[\"otq\"][\"script\"]            = \"Latn\"\n    Locale[\"otq\"][\"spoken-in\"]         = \"Querétaro in Mexico\"\n    Locale[\"otq\"][\"supported-by\"]      = \"bing\"\n\n    # Romanian / Moldovan, Latin alphabet\n    Locale[\"ro\"][\"name\"]               = \"Romanian\"\n    Locale[\"ro\"][\"endonym\"]            = \"Română\"\n    Locale[\"ro\"][\"translations-of\"]    = \"Traduceri pentru %s\"\n    Locale[\"ro\"][\"definitions-of\"]     = \"Definiții pentru %s\"\n    Locale[\"ro\"][\"synonyms\"]           = \"Sinonime\"\n    Locale[\"ro\"][\"examples\"]           = \"Exemple\"\n    Locale[\"ro\"][\"see-also\"]           = \"Vedeți și\"\n    Locale[\"ro\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ro\"][\"branch\"]             = \"Eastern Romance\"\n    Locale[\"ro\"][\"iso\"]                = \"ron\"\n    Locale[\"ro\"][\"glotto\"]             = \"roma1327\"\n    Locale[\"ro\"][\"script\"]             = \"Latn\"\n    Locale[\"ro\"][\"spoken-in\"]          = \"Romania; Moldova\"\n    Locale[\"ro\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Romansh\n    Locale[\"rm\"][\"name\"]               = \"Romansh\"\n    Locale[\"rm\"][\"endonym\"]            = \"Rumantsch\"\n    #Locale[\"rm\"][\"translations-of\"]\n    #Locale[\"rm\"][\"definitions-of\"]\n    #Locale[\"rm\"][\"synonyms\"]\n    #Locale[\"rm\"][\"examples\"]\n    #Locale[\"rm\"][\"see-also\"]\n    Locale[\"rm\"][\"family\"]             = \"Indo-European\"\n    Locale[\"rm\"][\"branch\"]             = \"Western Romance\"\n    Locale[\"rm\"][\"iso\"]                = \"roh\"\n    Locale[\"rm\"][\"glotto\"]             = \"roma1326\"\n    Locale[\"rm\"][\"script\"]             = \"Latn\"\n    Locale[\"rm\"][\"spoken-in\"]          = \"the Swiss canton of the Grisons\"\n    Locale[\"rm\"][\"supported-by\"]       = \"\"\n\n    # Russian\n    Locale[\"ru\"][\"name\"]               = \"Russian\"\n    Locale[\"ru\"][\"endonym\"]            = \"Русский\"\n    Locale[\"ru\"][\"translations-of\"]    = \"%s: варианты перевода\"\n    Locale[\"ru\"][\"definitions-of\"]     = \"%s – определения\"\n    Locale[\"ru\"][\"synonyms\"]           = \"Синонимы\"\n    Locale[\"ru\"][\"examples\"]           = \"Примеры\"\n    Locale[\"ru\"][\"see-also\"]           = \"Похожие слова\"\n    Locale[\"ru\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ru\"][\"branch\"]             = \"East Slavic\"\n    Locale[\"ru\"][\"iso\"]                = \"rus\"\n    Locale[\"ru\"][\"glotto\"]             = \"russ1263\"\n    Locale[\"ru\"][\"script\"]             = \"Cyrl\"\n    Locale[\"ru\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"ru\"][\"spoken-in\"]          = \"the Russian-speaking world\"\n    Locale[\"ru\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Samoan\n    Locale[\"sm\"][\"name\"]               = \"Samoan\"\n    Locale[\"sm\"][\"endonym\"]            = \"Gagana Sāmoa\"\n    #Locale[\"sm\"][\"translations-of\"]\n    #Locale[\"sm\"][\"definitions-of\"]\n    #Locale[\"sm\"][\"synonyms\"]\n    #Locale[\"sm\"][\"examples\"]\n    #Locale[\"sm\"][\"see-also\"]\n    Locale[\"sm\"][\"family\"]             = \"Austronesian\"\n    Locale[\"sm\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"sm\"][\"iso\"]                = \"smo\"\n    Locale[\"sm\"][\"glotto\"]             = \"samo1305\"\n    Locale[\"sm\"][\"script\"]             = \"Latn\"\n    Locale[\"sm\"][\"spoken-in\"]          = \"the Samoan Islands\"\n    Locale[\"sm\"][\"supported-by\"]       = \"google; bing\"\n\n    # Sanskrit\n    Locale[\"sa\"][\"name\"]               = \"Sanskrit\"\n    Locale[\"sa\"][\"endonym\"]            = \"संस्कृतम्\"\n    #Locale[\"sa\"][\"translations-of\"]\n    #Locale[\"sa\"][\"definitions-of\"]\n    #Locale[\"sa\"][\"synonyms\"]\n    #Locale[\"sa\"][\"examples\"]\n    #Locale[\"sa\"][\"see-also\"]\n    Locale[\"sa\"][\"family\"]             = \"Indo-European\"\n    Locale[\"sa\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"sa\"][\"iso\"]                = \"san\"\n    Locale[\"sa\"][\"glotto\"]             = \"sans1269\"\n    Locale[\"sa\"][\"script\"]             = \"Deva\"\n    Locale[\"sa\"][\"spoken-in\"]          = \"ancient India\"\n    Locale[\"sa\"][\"supported-by\"]       = \"google\"\n\n    # Scots Gaelic / Scottish Gaelic\n    Locale[\"gd\"][\"name\"]               = \"Scots Gaelic\"\n    Locale[\"gd\"][\"endonym\"]            = \"Gàidhlig\"\n    Locale[\"gd\"][\"translations-of\"]    = \"Eadar-theangachadh airson %s\"\n    Locale[\"gd\"][\"definitions-of\"]     = \"Deifiniseanan airson %s\"\n    Locale[\"gd\"][\"synonyms\"]           = \"Co-fhaclan\"\n    Locale[\"gd\"][\"examples\"]           = \"Buill-eisimpleir\"\n    Locale[\"gd\"][\"see-also\"]           = \"Faic na leanas cuideachd\"\n    Locale[\"gd\"][\"family\"]             = \"Indo-European\"\n    Locale[\"gd\"][\"branch\"]             = \"Celtic\"\n    Locale[\"gd\"][\"iso\"]                = \"gla\"\n    Locale[\"gd\"][\"glotto\"]             = \"scot1245\"\n    Locale[\"gd\"][\"script\"]             = \"Latn\"\n    Locale[\"gd\"][\"spoken-in\"]          = \"Scotland\"\n    Locale[\"gd\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Sepedi (Northern Sotho)\n    Locale[\"nso\"][\"name\"]              = \"Sepedi\"\n    Locale[\"nso\"][\"name2\"]             = \"Pedi\"\n    Locale[\"nso\"][\"name3\"]             = \"Northern Sotho\"\n    Locale[\"nso\"][\"endonym\"]           = \"Sepedi\"\n    #Locale[\"nso\"][\"translations-of\"]\n    #Locale[\"nso\"][\"definitions-of\"]\n    #Locale[\"nso\"][\"synonyms\"]\n    #Locale[\"nso\"][\"examples\"]\n    #Locale[\"nso\"][\"see-also\"]\n    Locale[\"nso\"][\"family\"]            = \"Atlantic-Congo\"\n    Locale[\"nso\"][\"branch\"]            = \"Bantu\"\n    Locale[\"nso\"][\"iso\"]               = \"nso\"\n    Locale[\"nso\"][\"glotto\"]            = \"nort3233\"\n    Locale[\"nso\"][\"script\"]            = \"Latn\"\n    Locale[\"nso\"][\"spoken-in\"]         = \"the northeastern provinces of South Africa\"\n    Locale[\"nso\"][\"supported-by\"]      = \"google\"\n\n    # Serbian, Cyrillic alphabet\n    Locale[\"sr-Cyrl\"][\"name\"]          = \"Serbian (Cyrillic)\"\n    Locale[\"sr-Cyrl\"][\"endonym\"]       = \"Српски\"\n    Locale[\"sr-Cyrl\"][\"translations-of\"] = \"Преводи за „%s“\"\n    Locale[\"sr-Cyrl\"][\"definitions-of\"]  = \"Дефиниције за %s\"\n    Locale[\"sr-Cyrl\"][\"synonyms\"]      = \"Синоними\"\n    Locale[\"sr-Cyrl\"][\"examples\"]      = \"Примери\"\n    Locale[\"sr-Cyrl\"][\"see-also\"]      = \"Погледајте такође\"\n    Locale[\"sr-Cyrl\"][\"family\"]        = \"Indo-European\"\n    Locale[\"sr-Cyrl\"][\"branch\"]        = \"South Slavic\"\n    Locale[\"sr-Cyrl\"][\"iso\"]           = \"srp-Cyrl\"\n    Locale[\"sr-Cyrl\"][\"glotto\"]        = \"serb1264\"\n    Locale[\"sr-Cyrl\"][\"script\"]        = \"Cyrl\"\n    Locale[\"sr-Cyrl\"][\"spoken-in\"]     = \"Serbia; Bosnia and Herzegovina; Montenegro; Kosovo\"\n    Locale[\"sr-Cyrl\"][\"supported-by\"]  = \"google; bing; yandex\"\n\n    # Serbian, Latin alphabet\n    Locale[\"sr-Latn\"][\"name\"]          = \"Serbian (Latin)\"\n    Locale[\"sr-Latn\"][\"endonym\"]       = \"Srpski\"\n    Locale[\"sr-Latn\"][\"translations-of\"] = \"Prevodi za „%s“\"\n    Locale[\"sr-Latn\"][\"definitions-of\"]  = \"Definicije za %s\"\n    Locale[\"sr-Latn\"][\"synonyms\"]      = \"Sinonimi\"\n    Locale[\"sr-Latn\"][\"examples\"]      = \"Primeri\"\n    Locale[\"sr-Latn\"][\"see-also\"]      = \"Pogledajte takođe\"\n    Locale[\"sr-Latn\"][\"family\"]        = \"Indo-European\"\n    Locale[\"sr-Latn\"][\"branch\"]        = \"South Slavic\"\n    Locale[\"sr-Latn\"][\"iso\"]           = \"srp-Latn\"\n    Locale[\"sr-Latn\"][\"glotto\"]        = \"serb1264\"\n    Locale[\"sr-Latn\"][\"script\"]        = \"Latn\"\n    Locale[\"sr-Latn\"][\"spoken-in\"]     = \"Serbia; Bosnia and Herzegovina; Montenegro; Kosovo\"\n    Locale[\"sr-Latn\"][\"supported-by\"]  = \"bing\"\n\n    # Sesotho (Southern Sotho)\n    Locale[\"st\"][\"name\"]               = \"Sesotho\"\n    Locale[\"st\"][\"name2\"]              = \"Sotho\"\n    Locale[\"st\"][\"name3\"]              = \"Southern Sotho\"\n    Locale[\"st\"][\"endonym\"]            = \"Sesotho\"\n    Locale[\"st\"][\"translations-of\"]    = \"Liphetolelo tsa %s\"\n    Locale[\"st\"][\"definitions-of\"]     = \"Meelelo ea %s\"\n    Locale[\"st\"][\"synonyms\"]           = \"Mantsoe a tšoanang ka moelelo\"\n    Locale[\"st\"][\"examples\"]           = \"Mehlala\"\n    Locale[\"st\"][\"see-also\"]           = \"Bona hape\"\n    Locale[\"st\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"st\"][\"branch\"]             = \"Bantu\"\n    Locale[\"st\"][\"iso\"]                = \"sot\"\n    Locale[\"st\"][\"glotto\"]             = \"sout2807\"\n    Locale[\"st\"][\"script\"]             = \"Latn\"\n    Locale[\"st\"][\"spoken-in\"]          = \"Lesotho; South Africa; Zimbabwe\"\n    Locale[\"st\"][\"supported-by\"]       = \"google\"\n\n    # Setswana\n    Locale[\"tn\"][\"name\"]               = \"Setswana\"\n    Locale[\"tn\"][\"name2\"]              = \"Tswana\"\n    Locale[\"tn\"][\"endonym\"]            = \"Setswana\"\n    Locale[\"tn\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"tn\"][\"branch\"]             = \"Bantu\"\n    Locale[\"tn\"][\"iso\"]                = \"tsn\"\n    Locale[\"tn\"][\"glotto\"]             = \"tswa1253\"\n    Locale[\"tn\"][\"script\"]             = \"Latn\"\n    Locale[\"tn\"][\"spoken-in\"]          = \"Botswana; South Africa\"\n    Locale[\"tn\"][\"supported-by\"]       = \"\"\n\n    # Shona\n    Locale[\"sn\"][\"name\"]               = \"Shona\"\n    Locale[\"sn\"][\"endonym\"]            = \"chiShona\"\n    Locale[\"sn\"][\"translations-of\"]    = \"Shanduro dze %s\"\n    Locale[\"sn\"][\"definitions-of\"]     = \"Zvinoreva %s\"\n    Locale[\"sn\"][\"synonyms\"]           = \"Mashoko anoreva zvakafana nemamwe\"\n    Locale[\"sn\"][\"examples\"]           = \"Mienzaniso\"\n    Locale[\"sn\"][\"see-also\"]           = \"Onawo\"\n    Locale[\"sn\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"sn\"][\"branch\"]             = \"Bantu\"\n    Locale[\"sn\"][\"iso\"]                = \"sna\"\n    Locale[\"sn\"][\"glotto\"]             = \"core1255\"\n    Locale[\"sn\"][\"script\"]             = \"Latn\"\n    Locale[\"sn\"][\"spoken-in\"]          = \"Zimbabwe\"\n    Locale[\"sn\"][\"supported-by\"]       = \"google\"\n\n    # Sindhi\n    Locale[\"sd\"][\"name\"]               = \"Sindhi\"\n    Locale[\"sd\"][\"endonym\"]            = \"سنڌي\"\n    Locale[\"sd\"][\"translations-of\"]    = \"%s جو ترجمو\"\n    Locale[\"sd\"][\"definitions-of\"]     = \"%s جون وصفون\"\n    Locale[\"sd\"][\"synonyms\"]           = \"هم معني\"\n    Locale[\"sd\"][\"examples\"]           = \"مثالون\"\n    Locale[\"sd\"][\"see-also\"]           = \"به ڏسو\"\n    Locale[\"sd\"][\"family\"]             = \"Indo-European\"\n    Locale[\"sd\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"sd\"][\"iso\"]                = \"snd\"\n    Locale[\"sd\"][\"glotto\"]             = \"sind1272\"\n    Locale[\"sd\"][\"script\"]             = \"Arab\"\n    Locale[\"sd\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"sd\"][\"spoken-in\"]          = \"the region of Sindh in Pakistan; India\"\n    Locale[\"sd\"][\"supported-by\"]       = \"google\"\n\n    # Sinhala / Sinhalese\n    Locale[\"si\"][\"name\"]               = \"Sinhala\"\n    Locale[\"si\"][\"name2\"]              = \"Sinhalese\"\n    Locale[\"si\"][\"endonym\"]            = \"සිංහල\"\n    Locale[\"si\"][\"translations-of\"]    = \"%s හි පරිවර්තන\"\n    Locale[\"si\"][\"definitions-of\"]     = \"%s හි නිර්වචන\"\n    Locale[\"si\"][\"synonyms\"]           = \"සමානාර්ථ පද\"\n    Locale[\"si\"][\"examples\"]           = \"උදාහරණ\"\n    Locale[\"si\"][\"see-also\"]           = \"මෙයත් බලන්න\"\n    Locale[\"si\"][\"family\"]             = \"Indo-European\"\n    Locale[\"si\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"si\"][\"iso\"]                = \"sin\"\n    Locale[\"si\"][\"glotto\"]             = \"sinh1246\"\n    Locale[\"si\"][\"script\"]             = \"Sinh\"\n    Locale[\"si\"][\"spoken-in\"]          = \"Sri Lanka\"\n    Locale[\"si\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Slovak\n    Locale[\"sk\"][\"name\"]               = \"Slovak\"\n    Locale[\"sk\"][\"endonym\"]            = \"Slovenčina\"\n    Locale[\"sk\"][\"translations-of\"]    = \"Preklady výrazu: %s\"\n    Locale[\"sk\"][\"definitions-of\"]     = \"Definície výrazu %s\"\n    Locale[\"sk\"][\"synonyms\"]           = \"Synonymá\"\n    Locale[\"sk\"][\"examples\"]           = \"Príklady\"\n    Locale[\"sk\"][\"see-also\"]           = \"Pozrite tiež\"\n    Locale[\"sk\"][\"family\"]             = \"Indo-European\"\n    Locale[\"sk\"][\"branch\"]             = \"West Slavic\"\n    Locale[\"sk\"][\"iso\"]                = \"slk\"\n    Locale[\"sk\"][\"glotto\"]             = \"slov1269\"\n    Locale[\"sk\"][\"script\"]             = \"Latn\"\n    Locale[\"sk\"][\"spoken-in\"]          = \"Slovakia\"\n    Locale[\"sk\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Slovenian / Slovene\n    Locale[\"sl\"][\"name\"]               = \"Slovenian\"\n    Locale[\"sl\"][\"name2\"]              = \"Slovene\"\n    Locale[\"sl\"][\"endonym\"]            = \"Slovenščina\"\n    Locale[\"sl\"][\"translations-of\"]    = \"Prevodi za %s\"\n    Locale[\"sl\"][\"definitions-of\"]     = \"Razlage za %s\"\n    Locale[\"sl\"][\"synonyms\"]           = \"Sopomenke\"\n    Locale[\"sl\"][\"examples\"]           = \"Primeri\"\n    Locale[\"sl\"][\"see-also\"]           = \"Glejte tudi\"\n    Locale[\"sl\"][\"family\"]             = \"Indo-European\"\n    Locale[\"sl\"][\"branch\"]             = \"South Slavic\"\n    Locale[\"sl\"][\"iso\"]                = \"slv\"\n    Locale[\"sl\"][\"glotto\"]             = \"slov1268\"\n    Locale[\"sl\"][\"script\"]             = \"Latn\"\n    Locale[\"sl\"][\"spoken-in\"]          = \"Slovenia\"\n    Locale[\"sl\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Somali\n    Locale[\"so\"][\"name\"]               = \"Somali\"\n    Locale[\"so\"][\"endonym\"]            = \"Soomaali\"\n    Locale[\"so\"][\"translations-of\"]    = \"Turjumaada %s\"\n    Locale[\"so\"][\"definitions-of\"]     = \"Qeexitaannada %s\"\n    Locale[\"so\"][\"synonyms\"]           = \"La micne ah\"\n    Locale[\"so\"][\"examples\"]           = \"Tusaalooyin\"\n    Locale[\"so\"][\"see-also\"]           = \"Sidoo kale eeg\"\n    Locale[\"so\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"so\"][\"branch\"]             = \"Cushitic\"\n    Locale[\"so\"][\"iso\"]                = \"som\"\n    Locale[\"so\"][\"glotto\"]             = \"soma1255\"\n    Locale[\"so\"][\"script\"]             = \"Latn\"\n    Locale[\"so\"][\"spoken-in\"]          = \"Somalia; Somaliland; Ethiopia; Djibouti\"\n    Locale[\"so\"][\"supported-by\"]       = \"google; bing\"\n\n    # Spanish\n    Locale[\"es\"][\"name\"]               = \"Spanish\"\n    Locale[\"es\"][\"endonym\"]            = \"Español\"\n    Locale[\"es\"][\"translations-of\"]    = \"Traducciones de %s\"\n    Locale[\"es\"][\"definitions-of\"]     = \"Definiciones de %s\"\n    Locale[\"es\"][\"synonyms\"]           = \"Sinónimos\"\n    Locale[\"es\"][\"examples\"]           = \"Ejemplos\"\n    Locale[\"es\"][\"see-also\"]           = \"Ver también\"\n    Locale[\"es\"][\"family\"]             = \"Indo-European\"\n    Locale[\"es\"][\"branch\"]             = \"Western Romance\"\n    Locale[\"es\"][\"iso\"]                = \"spa\"\n    Locale[\"es\"][\"glotto\"]             = \"stan1288\"\n    Locale[\"es\"][\"script\"]             = \"Latn\"\n    Locale[\"es\"][\"dictionary\"]         = \"true\" # has dictionary\n    Locale[\"es\"][\"spoken-in\"]          = \"Spain; the Americas\"\n    Locale[\"es\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Sundanese, Latin alphabet\n    Locale[\"su\"][\"name\"]               = \"Sundanese\"\n    Locale[\"su\"][\"endonym\"]            = \"Basa Sunda\"\n    Locale[\"su\"][\"translations-of\"]    = \"Tarjamahan tina %s\"\n    Locale[\"su\"][\"definitions-of\"]     = \"Panjelasan tina %s\"\n    Locale[\"su\"][\"synonyms\"]           = \"Sinonim\"\n    Locale[\"su\"][\"examples\"]           = \"Conto\"\n    Locale[\"su\"][\"see-also\"]           = \"Tingali ogé\"\n    Locale[\"su\"][\"family\"]             = \"Austronesian\"\n    Locale[\"su\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"su\"][\"iso\"]                = \"sun\"\n    Locale[\"su\"][\"glotto\"]             = \"sund1252\"\n    Locale[\"su\"][\"script\"]             = \"Latn\"\n    Locale[\"su\"][\"spoken-in\"]          = \"Java, Indonesia\"\n    Locale[\"su\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Swahili / Kiswahili, Latin script\n    Locale[\"sw\"][\"name\"]               = \"Swahili\"\n    Locale[\"sw\"][\"name2\"]              = \"Kiswahili\"\n    Locale[\"sw\"][\"endonym\"]            = \"Kiswahili\"\n    Locale[\"sw\"][\"translations-of\"]    = \"Tafsiri ya %s\"\n    Locale[\"sw\"][\"definitions-of\"]     = \"Ufafanuzi wa %s\"\n    Locale[\"sw\"][\"synonyms\"]           = \"Visawe\"\n    Locale[\"sw\"][\"examples\"]           = \"Mifano\"\n    Locale[\"sw\"][\"see-also\"]           = \"Angalia pia\"\n    Locale[\"sw\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"sw\"][\"branch\"]             = \"Bantu\"\n    Locale[\"sw\"][\"iso\"]                = \"swa\"\n    Locale[\"sw\"][\"glotto\"]             = \"swah1253\"\n    Locale[\"sw\"][\"script\"]             = \"Latn\"\n    Locale[\"sw\"][\"spoken-in\"]          = \"the East African coast and litoral islands\"\n    Locale[\"sw\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Swedish\n    Locale[\"sv\"][\"name\"]               = \"Swedish\"\n    Locale[\"sv\"][\"endonym\"]            = \"Svenska\"\n    Locale[\"sv\"][\"translations-of\"]    = \"Översättningar av %s\"\n    Locale[\"sv\"][\"definitions-of\"]     = \"Definitioner av %s\"\n    Locale[\"sv\"][\"synonyms\"]           = \"Synonymer\"\n    Locale[\"sv\"][\"examples\"]           = \"Exempel\"\n    Locale[\"sv\"][\"see-also\"]           = \"Se även\"\n    Locale[\"sv\"][\"family\"]             = \"Indo-European\"\n    Locale[\"sv\"][\"branch\"]             = \"North Germanic\"\n    Locale[\"sv\"][\"iso\"]                = \"swe\"\n    Locale[\"sv\"][\"glotto\"]             = \"swed1254\"\n    Locale[\"sv\"][\"script\"]             = \"Latn\"\n    Locale[\"sv\"][\"spoken-in\"]          = \"Sweden; Finland; Estonia\"\n    Locale[\"sv\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Tahitian\n    Locale[\"ty\"][\"name\"]               = \"Tahitian\"\n    Locale[\"ty\"][\"endonym\"]            = \"Reo Tahiti\"\n    Locale[\"ty\"][\"family\"]             = \"Austronesian\"\n    Locale[\"ty\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"ty\"][\"iso\"]                = \"tah\"\n    Locale[\"ty\"][\"glotto\"]             = \"tahi1242\"\n    Locale[\"ty\"][\"script\"]             = \"Latn\"\n    Locale[\"ty\"][\"spoken-in\"]          = \"French Polynesia\"\n    Locale[\"ty\"][\"supported-by\"]       = \"bing\"\n\n    # Tajik / Tajiki (Tajiki Persian), Cyrillic alphabet\n    Locale[\"tg\"][\"name\"]               = \"Tajik\"\n    Locale[\"tg\"][\"name2\"]              = \"Tajiki\"\n    Locale[\"tg\"][\"endonym\"]            = \"Тоҷикӣ\"\n    Locale[\"tg\"][\"translations-of\"]    = \"Тарҷумаҳои %s\"\n    Locale[\"tg\"][\"definitions-of\"]     = \"Таърифҳои %s\"\n    Locale[\"tg\"][\"synonyms\"]           = \"Муродифҳо\"\n    Locale[\"tg\"][\"examples\"]           = \"Намунаҳо:\"\n    Locale[\"tg\"][\"see-also\"]           = \"Ҳамчунин Бинед\"\n    Locale[\"tg\"][\"family\"]             = \"Indo-European\"\n    Locale[\"tg\"][\"branch\"]             = \"Iranian\"\n    Locale[\"tg\"][\"iso\"]                = \"tgk\"\n    Locale[\"tg\"][\"glotto\"]             = \"taji1245\"\n    Locale[\"tg\"][\"script\"]             = \"Cyrl\"\n    Locale[\"tg\"][\"spoken-in\"]          = \"Tajikistan; Uzbekistan\"\n    Locale[\"tg\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Tamil\n    Locale[\"ta\"][\"name\"]               = \"Tamil\"\n    Locale[\"ta\"][\"endonym\"]            = \"தமிழ்\"\n    Locale[\"ta\"][\"translations-of\"]    = \"%s இன் மொழிபெயர்ப்புகள்\"\n    Locale[\"ta\"][\"definitions-of\"]     = \"%s இன் வரையறைகள்\"\n    Locale[\"ta\"][\"synonyms\"]           = \"இணைச்சொற்கள்\"\n    Locale[\"ta\"][\"examples\"]           = \"எடுத்துக்காட்டுகள்\"\n    Locale[\"ta\"][\"see-also\"]           = \"இதையும் காண்க\"\n    Locale[\"ta\"][\"family\"]             = \"Dravidian\"\n    Locale[\"ta\"][\"branch\"]             = \"South Dravidian\"\n    Locale[\"ta\"][\"iso\"]                = \"tam\"\n    Locale[\"ta\"][\"glotto\"]             = \"tami1289\"\n    Locale[\"ta\"][\"script\"]             = \"Taml\"\n    Locale[\"ta\"][\"spoken-in\"]          = \"the Indian state of Tamil Nadu; Sri Lanka; Singapore\"\n    Locale[\"ta\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Tatar, Cyrillic alphabet\n    Locale[\"tt\"][\"name\"]               = \"Tatar\"\n    Locale[\"tt\"][\"endonym\"]            = \"татарча\"\n    #Locale[\"tt\"][\"translations-of\"]\n    #Locale[\"tt\"][\"definitions-of\"]\n    #Locale[\"tt\"][\"synonyms\"]\n    #Locale[\"tt\"][\"examples\"]\n    #Locale[\"tt\"][\"see-also\"]\n    Locale[\"tt\"][\"family\"]             = \"Turkic\"\n    Locale[\"tt\"][\"branch\"]             = \"Kipchak\"\n    Locale[\"tt\"][\"iso\"]                = \"tat\"\n    Locale[\"tt\"][\"glotto\"]             = \"tata1255\"\n    Locale[\"tt\"][\"script\"]             = \"Cyrl\"\n    Locale[\"tt\"][\"spoken-in\"]          = \"the Republic of Tatarstan in Russia\"\n    Locale[\"tt\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Telugu\n    Locale[\"te\"][\"name\"]               = \"Telugu\"\n    Locale[\"te\"][\"endonym\"]            = \"తెలుగు\"\n    Locale[\"te\"][\"translations-of\"]    = \"%s యొక్క అనువాదాలు\"\n    Locale[\"te\"][\"definitions-of\"]     = \"%s యొక్క నిర్వచనాలు\"\n    Locale[\"te\"][\"synonyms\"]           = \"పర్యాయపదాలు\"\n    Locale[\"te\"][\"examples\"]           = \"ఉదాహరణలు\"\n    Locale[\"te\"][\"see-also\"]           = \"వీటిని కూడా చూడండి\"\n    Locale[\"te\"][\"family\"]             = \"Dravidian\"\n    Locale[\"te\"][\"branch\"]             = \"South-Central Dravidian\"\n    Locale[\"te\"][\"iso\"]                = \"tel\"\n    Locale[\"te\"][\"glotto\"]             = \"telu1262\"\n    Locale[\"te\"][\"script\"]             = \"Telu\"\n    Locale[\"te\"][\"spoken-in\"]          = \"the Indian states of Andhra Pradesh and Telangana\"\n    Locale[\"te\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Thai\n    Locale[\"th\"][\"name\"]               = \"Thai\"\n    Locale[\"th\"][\"endonym\"]            = \"ไทย\"\n    Locale[\"th\"][\"translations-of\"]    = \"คำแปลของ %s\"\n    Locale[\"th\"][\"definitions-of\"]     = \"คำจำกัดความของ %s\"\n    Locale[\"th\"][\"synonyms\"]           = \"คำพ้องความหมาย\"\n    Locale[\"th\"][\"examples\"]           = \"ตัวอย่าง\"\n    Locale[\"th\"][\"see-also\"]           = \"ดูเพิ่มเติม\"\n    Locale[\"th\"][\"family\"]             = \"Kra-Dai\"\n    Locale[\"th\"][\"branch\"]             = \"Tai\"\n    Locale[\"th\"][\"iso\"]                = \"tha\"\n    Locale[\"th\"][\"glotto\"]             = \"thai1261\"\n    Locale[\"th\"][\"script\"]             = \"Thai\"\n    Locale[\"th\"][\"spoken-in\"]          = \"Thailand\"\n    Locale[\"th\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Tibetan (Standard Tibetan)\n    Locale[\"bo\"][\"name\"]               = \"Tibetan\"\n    Locale[\"bo\"][\"endonym\"]            = \"བོད་ཡིག\"\n    #Locale[\"bo\"][\"translations-of\"]\n    #Locale[\"bo\"][\"definitions-of\"]\n    #Locale[\"bo\"][\"synonyms\"]\n    #Locale[\"bo\"][\"examples\"]\n    #Locale[\"bo\"][\"see-also\"]\n    Locale[\"bo\"][\"family\"]             = \"Sino-Tibetan\"\n    Locale[\"bo\"][\"branch\"]             = \"Tibetic\"\n    Locale[\"bo\"][\"iso\"]                = \"bod\"\n    Locale[\"bo\"][\"glotto\"]             = \"tibe1272\"\n    Locale[\"bo\"][\"script\"]             = \"Tibt\"\n    Locale[\"bo\"][\"spoken-in\"]          = \"the Tibet Autonomous Region of China\"\n    Locale[\"bo\"][\"supported-by\"]       = \"bing\"\n\n    # Tigrinya\n    Locale[\"ti\"][\"name\"]               = \"Tigrinya\"\n    Locale[\"ti\"][\"endonym\"]            = \"ትግርኛ\"\n    #Locale[\"ti\"][\"translations-of\"]\n    #Locale[\"ti\"][\"definitions-of\"]\n    #Locale[\"ti\"][\"synonyms\"]\n    #Locale[\"ti\"][\"examples\"]\n    #Locale[\"ti\"][\"see-also\"]\n    Locale[\"ti\"][\"family\"]             = \"Afro-Asiatic\"\n    Locale[\"ti\"][\"branch\"]             = \"Semitic\"\n    Locale[\"ti\"][\"iso\"]                = \"tir\"\n    Locale[\"ti\"][\"glotto\"]             = \"tigr1271\"\n    Locale[\"ti\"][\"script\"]             = \"Ethi\"\n    Locale[\"ti\"][\"spoken-in\"]          = \"Eritrea; the Tigray region of northern Ethiopia\"\n    Locale[\"ti\"][\"supported-by\"]       = \"google; bing\"\n\n    # Tongan\n    Locale[\"to\"][\"name\"]               = \"Tongan\"\n    Locale[\"to\"][\"endonym\"]            = \"Lea faka-Tonga\"\n    Locale[\"to\"][\"family\"]             = \"Austronesian\"\n    Locale[\"to\"][\"branch\"]             = \"Malayo-Polynesian\"\n    Locale[\"to\"][\"iso\"]                = \"ton\"\n    Locale[\"to\"][\"glotto\"]             = \"tong1325\"\n    Locale[\"to\"][\"script\"]             = \"Latn\"\n    Locale[\"to\"][\"spoken-in\"]          = \"Tonga\"\n    Locale[\"to\"][\"supported-by\"]       = \"bing\"\n\n    # Tsonga\n    Locale[\"ts\"][\"name\"]               = \"Tsonga\"\n    Locale[\"ts\"][\"endonym\"]            = \"Xitsonga\"\n    #Locale[\"ts\"][\"translations-of\"]\n    #Locale[\"ts\"][\"definitions-of\"]\n    #Locale[\"ts\"][\"synonyms\"]\n    #Locale[\"ts\"][\"examples\"]\n    #Locale[\"ts\"][\"see-also\"]\n    Locale[\"ts\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"ts\"][\"branch\"]             = \"Bantu\"\n    Locale[\"ts\"][\"iso\"]                = \"tso\"\n    Locale[\"ts\"][\"glotto\"]             = \"tson1249\"\n    Locale[\"ts\"][\"script\"]             = \"Latn\"\n    Locale[\"ts\"][\"spoken-in\"]          = \"Eswatini; Mozambique; South Africa; Zimbabwe\"\n    Locale[\"ts\"][\"supported-by\"]       = \"google\"\n\n    # Turkish\n    Locale[\"tr\"][\"name\"]               = \"Turkish\"\n    Locale[\"tr\"][\"endonym\"]            = \"Türkçe\"\n    Locale[\"tr\"][\"translations-of\"]    = \"%s çevirileri\"\n    Locale[\"tr\"][\"definitions-of\"]     = \"%s için tanımlar\"\n    Locale[\"tr\"][\"synonyms\"]           = \"Eş anlamlılar\"\n    Locale[\"tr\"][\"examples\"]           = \"Örnekler\"\n    Locale[\"tr\"][\"see-also\"]           = \"Ayrıca bkz.\"\n    Locale[\"tr\"][\"family\"]             = \"Turkic\"\n    Locale[\"tr\"][\"branch\"]             = \"Oghuz\"\n    Locale[\"tr\"][\"iso\"]                = \"tur\"\n    Locale[\"tr\"][\"glotto\"]             = \"nucl1301\"\n    Locale[\"tr\"][\"script\"]             = \"Latn\"\n    Locale[\"tr\"][\"spoken-in\"]          = \"Türkiye; Cyprus\"\n    Locale[\"tr\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Turkmen, Latin script\n    Locale[\"tk\"][\"name\"]               = \"Turkmen\"\n    Locale[\"tk\"][\"endonym\"]            = \"Türkmen\"\n    #Locale[\"tk\"][\"translations-of\"]\n    #Locale[\"tk\"][\"definitions-of\"]\n    #Locale[\"tk\"][\"synonyms\"]\n    #Locale[\"tk\"][\"examples\"]\n    #Locale[\"tk\"][\"see-also\"]\n    Locale[\"tk\"][\"family\"]             = \"Turkic\"\n    Locale[\"tk\"][\"branch\"]             = \"Oghuz\"\n    Locale[\"tk\"][\"iso\"]                = \"tuk\"\n    Locale[\"tk\"][\"glotto\"]             = \"turk1304\"\n    Locale[\"tk\"][\"script\"]             = \"Latn\"\n    Locale[\"tk\"][\"spoken-in\"]          = \"Turkmenistan; Iran; Afghanistan; Pakistan\"\n    Locale[\"tk\"][\"supported-by\"]       = \"google; bing\"\n\n    # Twi\n    Locale[\"tw\"][\"name\"]               = \"Twi\"\n    Locale[\"tw\"][\"name2\"]              = \"Akan Kasa\"\n    Locale[\"tw\"][\"endonym\"]            = \"Twi\"\n    #Locale[\"tw\"][\"translations-of\"]\n    #Locale[\"tw\"][\"definitions-of\"]\n    #Locale[\"tw\"][\"synonyms\"]\n    #Locale[\"tw\"][\"examples\"]\n    #Locale[\"tw\"][\"see-also\"]\n    Locale[\"tw\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"tw\"][\"branch\"]             = \"Kwa\"\n    Locale[\"tw\"][\"iso\"]                = \"twi\"\n    Locale[\"tw\"][\"glotto\"]             = \"akua1239\"\n    Locale[\"tw\"][\"script\"]             = \"Latn\"\n    Locale[\"tw\"][\"spoken-in\"]          = \"Ghana\"\n    Locale[\"tw\"][\"supported-by\"]       = \"google\"\n\n    # Udmurt\n    Locale[\"udm\"][\"name\"]              = \"Udmurt\"\n    Locale[\"udm\"][\"endonym\"]           = \"Удмурт\"\n    Locale[\"udm\"][\"family\"]            = \"Uralic\"\n    Locale[\"udm\"][\"branch\"]            = \"Permic\"\n    Locale[\"udm\"][\"iso\"]               = \"udm\"\n    Locale[\"udm\"][\"glotto\"]            = \"udmu1245\"\n    Locale[\"udm\"][\"script\"]            = \"Cyrl\"\n    Locale[\"udm\"][\"spoken-in\"]         = \"the Republic of Udmurt in Russia\"\n    Locale[\"udm\"][\"supported-by\"]      = \"yandex\"\n\n    # Ukrainian\n    Locale[\"uk\"][\"name\"]               = \"Ukrainian\"\n    Locale[\"uk\"][\"endonym\"]            = \"Українська\"\n    Locale[\"uk\"][\"translations-of\"]    = \"Переклади слова або виразу \\\"%s\\\"\"\n    Locale[\"uk\"][\"definitions-of\"]     = \"\\\"%s\\\" – визначення\"\n    Locale[\"uk\"][\"synonyms\"]           = \"Синоніми\"\n    Locale[\"uk\"][\"examples\"]           = \"Приклади\"\n    Locale[\"uk\"][\"see-also\"]           = \"Дивіться також\"\n    Locale[\"uk\"][\"family\"]             = \"Indo-European\"\n    Locale[\"uk\"][\"branch\"]             = \"East Slavic\"\n    Locale[\"uk\"][\"iso\"]                = \"ukr\"\n    Locale[\"uk\"][\"glotto\"]             = \"ukra1253\"\n    Locale[\"uk\"][\"script\"]             = \"Cyrl\"\n    Locale[\"uk\"][\"spoken-in\"]          = \"Ukraine\"\n    Locale[\"uk\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Upper Sorbian\n    Locale[\"hsb\"][\"name\"]              = \"Upper Sorbian\"\n    Locale[\"hsb\"][\"endonym\"]           = \"Hornjoserbšćina\"\n    Locale[\"hsb\"][\"family\"]            = \"Indo-European\"\n    Locale[\"hsb\"][\"branch\"]            = \"West Slavic\"\n    Locale[\"hsb\"][\"iso\"]               = \"hsb\"\n    Locale[\"hsb\"][\"glotto\"]            = \"uppe1395\"\n    Locale[\"hsb\"][\"script\"]            = \"Latn\"\n    Locale[\"hsb\"][\"spoken-in\"]         = \"Saxony, Germany\"\n    Locale[\"hsb\"][\"supported-by\"]      = \"bing\"\n\n    # Urdu\n    Locale[\"ur\"][\"name\"]               = \"Urdu\"\n    Locale[\"ur\"][\"endonym\"]            = \"اُردُو\"\n    Locale[\"ur\"][\"translations-of\"]    = \"کے ترجمے %s\"\n    Locale[\"ur\"][\"definitions-of\"]     = \"کی تعریفات %s\"\n    Locale[\"ur\"][\"synonyms\"]           = \"مترادفات\"\n    Locale[\"ur\"][\"examples\"]           = \"مثالیں\"\n    Locale[\"ur\"][\"see-also\"]           = \"نیز دیکھیں\"\n    Locale[\"ur\"][\"family\"]             = \"Indo-European\"\n    Locale[\"ur\"][\"branch\"]             = \"Indo-Aryan\"\n    Locale[\"ur\"][\"iso\"]                = \"urd\"\n    Locale[\"ur\"][\"glotto\"]             = \"urdu1245\"\n    Locale[\"ur\"][\"script\"]             = \"Arab\"\n    Locale[\"ur\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"ur\"][\"spoken-in\"]          = \"Pakistan; India\"\n    Locale[\"ur\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Uyghur\n    Locale[\"ug\"][\"name\"]               = \"Uyghur\"\n    Locale[\"ug\"][\"endonym\"]            = \"ئۇيغۇر تىلى\"\n    #Locale[\"ug\"][\"translations-of\"]\n    #Locale[\"ug\"][\"definitions-of\"]\n    #Locale[\"ug\"][\"synonyms\"]\n    #Locale[\"ug\"][\"examples\"]\n    #Locale[\"ug\"][\"see-also\"]\n    Locale[\"ug\"][\"family\"]             = \"Turkic\"\n    Locale[\"ug\"][\"branch\"]             = \"Karluk\"\n    Locale[\"ug\"][\"iso\"]                = \"uig\"\n    Locale[\"ug\"][\"glotto\"]             = \"uigh1240\"\n    Locale[\"ug\"][\"script\"]             = \"Arab\"\n    Locale[\"ug\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"ug\"][\"spoken-in\"]          = \"the Xinjiang Uyghur Autonomous Region of China\"\n    Locale[\"ug\"][\"supported-by\"]       = \"google; bing\"\n\n    # Uzbek, Latin alphabet\n    Locale[\"uz\"][\"name\"]               = \"Uzbek\"\n    Locale[\"uz\"][\"endonym\"]            = \"Oʻzbek tili\"\n    Locale[\"uz\"][\"translations-of\"]    = \"%s: tarjima variantlari\"\n    Locale[\"uz\"][\"definitions-of\"]     = \"%s – ta’riflar\"\n    Locale[\"uz\"][\"synonyms\"]           = \"Sinonimlar\"\n    Locale[\"uz\"][\"examples\"]           = \"Namunalar\"\n    Locale[\"uz\"][\"see-also\"]           = \"O‘xshash so‘zlar\"\n    Locale[\"uz\"][\"family\"]             = \"Turkic\"\n    Locale[\"uz\"][\"branch\"]             = \"Karluk\"\n    Locale[\"uz\"][\"iso\"]                = \"uzb\"\n    Locale[\"uz\"][\"glotto\"]             = \"uzbe1247\"\n    Locale[\"uz\"][\"script\"]             = \"Latn\"\n    Locale[\"uz\"][\"spoken-in\"]          = \"Uzbekistan; Afghanistan; Pakistan\"\n    Locale[\"uz\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Vietnamese\n    Locale[\"vi\"][\"name\"]               = \"Vietnamese\"\n    Locale[\"vi\"][\"endonym\"]            = \"Tiếng Việt\"\n    Locale[\"vi\"][\"translations-of\"]    = \"Bản dịch của %s\"\n    Locale[\"vi\"][\"definitions-of\"]     = \"Nghĩa của %s\"\n    Locale[\"vi\"][\"synonyms\"]           = \"Từ đồng nghĩa\"\n    Locale[\"vi\"][\"examples\"]           = \"Ví dụ\"\n    Locale[\"vi\"][\"see-also\"]           = \"Xem thêm\"\n    Locale[\"vi\"][\"family\"]             = \"Austroasiatic\"\n    Locale[\"vi\"][\"branch\"]             = \"Vietic\"\n    Locale[\"vi\"][\"iso\"]                = \"vie\"\n    Locale[\"vi\"][\"glotto\"]             = \"viet1252\"\n    Locale[\"vi\"][\"script\"]             = \"Latn\"\n    Locale[\"vi\"][\"spoken-in\"]          = \"Vietnam\"\n    Locale[\"vi\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # Volapük\n    Locale[\"vo\"][\"name\"]               = \"Volapük\"\n    Locale[\"vo\"][\"endonym\"]            = \"Volapük\"\n    #Locale[\"vo\"][\"translations-of\"]\n    #Locale[\"vo\"][\"definitions-of\"]\n    #Locale[\"vo\"][\"synonyms\"]\n    #Locale[\"vo\"][\"examples\"]\n    #Locale[\"vo\"][\"see-also\"]\n    Locale[\"vo\"][\"family\"]             = \"Constructed language\"\n    #Locale[\"vo\"][\"branch\"]\n    Locale[\"vo\"][\"iso\"]                = \"vol\"\n    Locale[\"vo\"][\"glotto\"]             = \"vola1234\"\n    Locale[\"vo\"][\"script\"]             = \"Latn\"\n    Locale[\"vo\"][\"spoken-in\"]          = \"worldwide\"\n    Locale[\"vo\"][\"description\"]        = \"an international auxiliary language\"\n    Locale[\"vo\"][\"supported-by\"]       = \"\"\n\n    # Welsh\n    Locale[\"cy\"][\"name\"]               = \"Welsh\"\n    Locale[\"cy\"][\"endonym\"]            = \"Cymraeg\"\n    Locale[\"cy\"][\"translations-of\"]    = \"Cyfieithiadau %s\"\n    Locale[\"cy\"][\"definitions-of\"]     = \"Diffiniadau %s\"\n    Locale[\"cy\"][\"synonyms\"]           = \"Cyfystyron\"\n    Locale[\"cy\"][\"examples\"]           = \"Enghreifftiau\"\n    Locale[\"cy\"][\"see-also\"]           = \"Gweler hefyd\"\n    Locale[\"cy\"][\"family\"]             = \"Indo-European\"\n    Locale[\"cy\"][\"branch\"]             = \"Celtic\"\n    Locale[\"cy\"][\"iso\"]                = \"cym\"\n    Locale[\"cy\"][\"glotto\"]             = \"wels1247\"\n    Locale[\"cy\"][\"script\"]             = \"Latn\"\n    Locale[\"cy\"][\"spoken-in\"]          = \"Wales in the UK\"\n    Locale[\"cy\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n    # West Frisian\n    Locale[\"fy\"][\"name\"]               = \"Frisian\"\n    Locale[\"fy\"][\"endonym\"]            = \"Frysk\"\n    Locale[\"fy\"][\"translations-of\"]    = \"Oersettings fan %s\"\n    Locale[\"fy\"][\"definitions-of\"]     = \"Definysjes fan %s\"\n    Locale[\"fy\"][\"synonyms\"]           = \"Synonimen\"\n    Locale[\"fy\"][\"examples\"]           = \"Foarbylden\"\n    Locale[\"fy\"][\"see-also\"]           = \"Sjoch ek\"\n    Locale[\"fy\"][\"family\"]             = \"Indo-European\"\n    Locale[\"fy\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"fy\"][\"iso\"]                = \"fry\"\n    Locale[\"fy\"][\"glotto\"]             = \"west2354\"\n    Locale[\"fy\"][\"script\"]             = \"Latn\"\n    Locale[\"fy\"][\"spoken-in\"]          = \"Friesland in the Netherlands\"\n    Locale[\"fy\"][\"supported-by\"]       = \"google\"\n\n    # Wolof\n    Locale[\"wo\"][\"name\"]               = \"Wolof\"\n    Locale[\"wo\"][\"endonym\"]            = \"Wollof\"\n    #Locale[\"wo\"][\"translations-of\"]\n    #Locale[\"wo\"][\"definitions-of\"]\n    #Locale[\"wo\"][\"synonyms\"]\n    #Locale[\"wo\"][\"examples\"]\n    #Locale[\"wo\"][\"see-also\"]\n    Locale[\"wo\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"wo\"][\"branch\"]             = \"Atlantic\"\n    Locale[\"wo\"][\"iso\"]                = \"wol\"\n    Locale[\"wo\"][\"glotto\"]             = \"wolo1247\"\n    Locale[\"wo\"][\"script\"]             = \"Latn\"\n    Locale[\"wo\"][\"spoken-in\"]          = \"Senegal; Mauritania; the Gambia\"\n    Locale[\"wo\"][\"supported-by\"]       = \"\"\n\n    # Xhosa\n    Locale[\"xh\"][\"name\"]               = \"Xhosa\"\n    Locale[\"xh\"][\"endonym\"]            = \"isiXhosa\"\n    Locale[\"xh\"][\"translations-of\"]    = \"Iinguqulelo zika-%s\"\n    Locale[\"xh\"][\"definitions-of\"]     = \"Iingcaciso zika-%s\"\n    Locale[\"xh\"][\"synonyms\"]           = \"Izithethantonye\"\n    Locale[\"xh\"][\"examples\"]           = \"Imizekelo\"\n    Locale[\"xh\"][\"see-also\"]           = \"Kwakhona bona\"\n    Locale[\"xh\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"xh\"][\"branch\"]             = \"Bantu\"\n    Locale[\"xh\"][\"iso\"]                = \"xho\"\n    Locale[\"xh\"][\"glotto\"]             = \"xhos1239\"\n    Locale[\"xh\"][\"script\"]             = \"Latn\"\n    Locale[\"xh\"][\"spoken-in\"]          = \"South Africa; Zimbabwe\"\n    Locale[\"xh\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Yakut / Sakha\n    Locale[\"sah\"][\"name\"]              = \"Yakut\"\n    Locale[\"sah\"][\"name2\"]             = \"Sakha\"\n    Locale[\"sah\"][\"endonym\"]           = \"Sakha\"\n    Locale[\"sah\"][\"family\"]            = \"Turkic\"\n    Locale[\"sah\"][\"branch\"]            = \"Siberian Turkic\"\n    Locale[\"sah\"][\"iso\"]               = \"sah\"\n    Locale[\"sah\"][\"glotto\"]            = \"yaku1245\"\n    Locale[\"sah\"][\"script\"]            = \"Latn\"\n    Locale[\"sah\"][\"spoken-in\"]         = \"the Republic of Sakha (Yakutia) in Russia\"\n    Locale[\"sah\"][\"supported-by\"]      = \"yandex\"\n\n    # Yiddish\n    Locale[\"yi\"][\"name\"]               = \"Yiddish\"\n    Locale[\"yi\"][\"endonym\"]            = \"ייִדיש\"\n    Locale[\"yi\"][\"translations-of\"]    = \"איבערזעצונגען פון %s\"\n    Locale[\"yi\"][\"definitions-of\"]     = \"דפיניציונען %s\"\n    Locale[\"yi\"][\"synonyms\"]           = \"סינאָנימען\"\n    Locale[\"yi\"][\"examples\"]           = \"ביישפילע\"\n    Locale[\"yi\"][\"see-also\"]           = \"זייען אויך\"\n    Locale[\"yi\"][\"family\"]             = \"Indo-European\"\n    Locale[\"yi\"][\"branch\"]             = \"West Germanic\"\n    Locale[\"yi\"][\"iso\"]                = \"yid\"\n    Locale[\"yi\"][\"glotto\"]             = \"yidd1255\"\n    Locale[\"yi\"][\"script\"]             = \"Hebr\"\n    Locale[\"yi\"][\"rtl\"]                = \"true\" # RTL language\n    Locale[\"yi\"][\"spoken-in\"]          = \"worldwide\"\n    Locale[\"yi\"][\"description\"]        = \"a West Germanic language historically spoken by Ashkenazi Jews\"\n    Locale[\"yi\"][\"supported-by\"]       = \"google; yandex\"\n\n    # Yoruba\n    Locale[\"yo\"][\"name\"]               = \"Yoruba\"\n    Locale[\"yo\"][\"endonym\"]            = \"Yorùbá\"\n    Locale[\"yo\"][\"translations-of\"]    = \"Awọn itumọ ti %s\"\n    Locale[\"yo\"][\"definitions-of\"]     = \"Awọn itumọ ti %s\"\n    Locale[\"yo\"][\"synonyms\"]           = \"Awọn ọrọ onitumọ\"\n    Locale[\"yo\"][\"examples\"]           = \"Awọn apẹrẹ\"\n    Locale[\"yo\"][\"see-also\"]           = \"Tun wo\"\n    Locale[\"yo\"][\"family\"]             = \"Atlantic-Congo\"\n    #Locale[\"yo\"][\"branch\"]\n    Locale[\"yo\"][\"iso\"]                = \"yor\"\n    Locale[\"yo\"][\"glotto\"]             = \"yoru1245\"\n    Locale[\"yo\"][\"script\"]             = \"Latn\"\n    Locale[\"yo\"][\"spoken-in\"]          = \"Nigeria; Benin\"\n    Locale[\"yo\"][\"supported-by\"]       = \"google\"\n\n    # Yucatec Maya\n    Locale[\"yua\"][\"name\"]              = \"Yucatec Maya\"\n    Locale[\"yua\"][\"endonym\"]           = \"Màaya T'àan\"\n    Locale[\"yua\"][\"family\"]            = \"Mayan\"\n    #Locale[\"yua\"][\"branch\"]\n    Locale[\"yua\"][\"iso\"]               = \"yua\"\n    Locale[\"yua\"][\"glotto\"]            = \"yuca1254\"\n    Locale[\"yua\"][\"script\"]            = \"Latn\"\n    Locale[\"yua\"][\"spoken-in\"]         = \"Mexico; Belize\"\n    Locale[\"yua\"][\"supported-by\"]      = \"bing\"\n\n    # Zulu\n    Locale[\"zu\"][\"name\"]               = \"Zulu\"\n    Locale[\"zu\"][\"endonym\"]            = \"isiZulu\"\n    Locale[\"zu\"][\"translations-of\"]    = \"Ukuhumusha i-%s\"\n    Locale[\"zu\"][\"definitions-of\"]     = \"Izincazelo ze-%s\"\n    Locale[\"zu\"][\"synonyms\"]           = \"Amagama afanayo\"\n    Locale[\"zu\"][\"examples\"]           = \"Izibonelo\"\n    Locale[\"zu\"][\"see-also\"]           = \"Bheka futhi\"\n    Locale[\"zu\"][\"family\"]             = \"Atlantic-Congo\"\n    Locale[\"zu\"][\"branch\"]             = \"Bantu\"\n    Locale[\"zu\"][\"iso\"]                = \"zul\"\n    Locale[\"zu\"][\"glotto\"]             = \"zulu1248\"\n    Locale[\"zu\"][\"script\"]             = \"Latn\"\n    Locale[\"zu\"][\"spoken-in\"]          = \"South Africa; Lesotho; Eswatini\"\n    Locale[\"zu\"][\"supported-by\"]       = \"google; bing; yandex\"\n\n}\n\n# Initialize aliases of all locales supported.\nfunction initLocaleAlias(    i) {\n    for (i in Locale) {\n        # ISO 639-3 codes as aliases\n        if (\"iso\" in Locale[i])\n            LocaleAlias[Locale[i][\"iso\"]] = i\n        # Names and endonyms as aliases\n        if (\"name\" in Locale[i])\n            LocaleAlias[tolower(Locale[i][\"name\"])] = i\n        if (\"name2\" in Locale[i])\n            LocaleAlias[tolower(Locale[i][\"name2\"])] = i\n        if (\"endonym\" in Locale[i])\n            LocaleAlias[tolower(Locale[i][\"endonym\"])] = i\n        if (\"endonym2\" in Locale[i])\n            LocaleAlias[tolower(Locale[i][\"endonym2\"])] = i\n    }\n\n    # Other aliases\n    # See: <http://www.loc.gov/standards/iso639-2/php/code_changes.php>\n    LocaleAlias[\"in\"] = \"id\" # withdrawn language code for Indonesian\n    LocaleAlias[\"iw\"] = \"he\" # withdrawn language code for Hebrew\n    LocaleAlias[\"ji\"] = \"yi\" # withdrawn language code for Yiddish\n    LocaleAlias[\"jw\"] = \"jv\" # withdrawn language code for Javanese\n    LocaleAlias[\"kurdish\"] = \"ku\" # Kurdish: default to \"ku\" (N.B. Google uses this code for Kurmanji)\n    LocaleAlias[\"mari\"] = \"mhr\" # Mari: default to \"mhr\" (Eastern Mari)\n    LocaleAlias[\"mo\"] = \"ro\" # Moldavian or Moldovan considered a variant of the Romanian language\n    LocaleAlias[\"moldavian\"] = \"ro\"\n    LocaleAlias[\"moldovan\"] = \"ro\"\n    LocaleAlias[\"mww\"] = \"hmn\" # mww (Hmong Daw) treated the same as hmn (the inclusive code for Hmong)\n    LocaleAlias[\"nb\"] = \"no\" # Google Translate does not distinguish between Bokmål and Nynorsk (but Bing does!)\n    LocaleAlias[\"nn\"] = \"no\"\n    LocaleAlias[\"pt\"] = \"pt-BR\" # Portuguese: default to Brazilian Portuguese (as in Google Translate)\n    LocaleAlias[\"portuguese\"] = \"pt-BR\"\n    LocaleAlias[\"sh\"]      = \"sr-Cyrl\" # Serbo-Croatian: default to Serbian\n    LocaleAlias[\"sr\"]      = \"sr-Cyrl\" # Serbian: default to Serbian Cyrillic\n    LocaleAlias[\"srp\"]     = \"sr-Cyrl\"\n    LocaleAlias[\"serbian\"] = \"sr-Cyrl\"\n    LocaleAlias[\"zh\"]      = \"zh-CN\" # Chinese: default to Chinese Simplified\n    LocaleAlias[\"zh-CHS\"]  = \"zh-CN\"\n    LocaleAlias[\"zh-CHT\"]  = \"zh-TW\"\n    LocaleAlias[\"zh-Hans\"] = \"zh-CN\"\n    LocaleAlias[\"zh-Hant\"] = \"zh-TW\"\n    LocaleAlias[\"zho\"]     = \"zh-CN\"\n    LocaleAlias[\"chinese\"] = \"zh-CN\"\n    LocaleAlias[\"tlh\"] = \"tlh-Latn\"\n    LocaleAlias[\"mni\"] = \"mni-Mtei\" # Meitei: default to Meitei Mayek\n    # TODO: more aliases\n}\n\n# Initialize strings for displaying endonyms of all locales supported.\nfunction initLocaleDisplay(    i) {\n    for (i in Locale) {\n        Locale[i][\"display\"] = show(Locale[i][\"endonym\"], i)\n    }\n}\n"
  },
  {
    "path": "include/LanguageHelper.awk",
    "content": "####################################################################\n# LanguageHelper.awk                                               #\n####################################################################\n\n# Get locale key by language code or alias.\nfunction getCode(code,    group) {\n    if (code == \"auto\" || code in Locale)\n        return code\n    else if (code in LocaleAlias)\n        return LocaleAlias[code]\n    else if (tolower(code) in LocaleAlias)\n        return LocaleAlias[tolower(code)]\n\n    # Remove unidentified region or script code\n    match(code, /^([[:alpha:]][[:alpha:]][[:alpha:]]?)-(.*)$/, group)\n    if (group[1])\n        return group[1]\n\n    return # return nothing if not found\n}\n\n# Return the name of a language.\nfunction getName(code) {\n    return Locale[getCode(code)][\"name\"]\n}\n\n# Return all the names of a language, separated by \"/\"\nfunction getNames(code) {\n    if (\"name2\" in Locale[getCode(code)])\n        return Locale[getCode(code)][\"name\"] \" / \" Locale[getCode(code)][\"name2\"]\n    else\n        return Locale[getCode(code)][\"name\"]\n}\n\n# Return the endonym of a language.\nfunction getEndonym(code) {\n    return Locale[getCode(code)][\"endonym\"]\n}\n\n# Return the string for displaying the endonym of a language.\nfunction getDisplay(code) {\n    return Locale[getCode(code)][\"display\"]\n}\n\n# Return formatted text for \"translations of\".\nfunction showTranslationsOf(code, text,    fmt) {\n    fmt = Locale[getCode(code)][\"translations-of\"]\n    if (!fmt) fmt = Locale[\"en\"][\"translations-of\"]\n    return sprintf(fmt, text)\n}\n\n# Return formatted text for \"definitions of\".\nfunction showDefinitionsOf(code, text,    fmt) {\n    fmt = Locale[getCode(code)][\"definitions-of\"]\n    if (!fmt) fmt = Locale[\"en\"][\"definitions-of\"]\n    return sprintf(fmt, text)\n}\n\n# Return a string of \"synonyms\".\nfunction showSynonyms(code,    tmp) {\n    tmp = Locale[getCode(code)][\"synonyms\"]\n    if (!tmp) tmp = Locale[\"en\"][\"synonyms\"]\n    return tmp\n}\n\n# Return a string of \"examples\".\nfunction showExamples(code,    tmp) {\n    tmp = Locale[getCode(code)][\"examples\"]\n    if (!tmp) tmp = Locale[\"en\"][\"examples\"]\n    return tmp\n}\n\n# Return a string of \"see also\".\nfunction showSeeAlso(code,    tmp) {\n    tmp = Locale[getCode(code)][\"see-also\"]\n    if (!tmp) tmp = Locale[\"en\"][\"see-also\"]\n    return tmp\n}\n\n# Return the family of a language.\nfunction getFamily(code) {\n    return Locale[getCode(code)][\"family\"]\n}\n\n# Return the branch of a language.\nfunction getBranch(code) {\n    return Locale[getCode(code)][\"branch\"]\n}\n\n# Return the ISO 639-3 code of a language.\nfunction getISO(code) {\n    return Locale[getCode(code)][\"iso\"]\n}\n\n# Return the Glottocode of a language.\nfunction getGlotto(code) {\n    return Locale[getCode(code)][\"glotto\"]\n}\n\n# Return the ISO 15924 script code of a language.\nfunction getScript(code) {\n    return Locale[getCode(code)][\"script\"]\n}\n\n# Return 1 if a language is R-to-L; otherwise return 0.\nfunction isRTL(code) {\n    return Locale[getCode(code)][\"rtl\"] ? 1 : 0\n}\n\n# Return 1 if Google provides dictionary data for a language; otherwise return 0.\nfunction hasDictionary(code) {\n    return Locale[getCode(code)][\"dictionary\"] ? 1 : 0\n}\n\n# Comparator using getName().\nfunction compName(i1, v1, i2, v2) {\n    if (getName(i1) < getName(i2))\n        return -1\n    else\n        return (getName(i1) != getName(i2))\n}\n\n# Return the name of script (writing system).\n# See: <https://en.wikipedia.org/wiki/ISO_15924#List_of_codes>\n#      <http://unicode.org/iso15924/iso15924-codes.html>\nfunction scriptName(code) {\n    switch (code) {\n    case \"Arab\": return \"Arabic\"\n    case \"Armn\": return \"Armenian\"\n    case \"Beng\": return \"Bengali\"\n    case \"Cans\": return \"Canadian Aboriginal Syllabics\"\n    case \"Cher\": return \"Cherokee\"\n    case \"Cyrl\": return \"Cyrillic\"\n    case \"Deva\": return \"Devanagari\"\n    case \"Ethi\": return \"Ethiopic (Geʻez)\"\n    case \"Geor\": return \"Georgian (Mkhedruli)\"\n    case \"Grek\": return \"Greek\"\n    case \"Gujr\": return \"Gujarati\"\n    case \"Guru\": return \"Gurmukhi\"\n    case \"Hani\": return \"Han\"\n    case \"Hans\": return \"Han (Simplified)\"\n    case \"Hant\": return \"Han (Traditional)\"\n    case \"Hebr\": return \"Hebrew\"\n    case \"Jpan\": return \"Japanese (Han + Hiragana + Katakana)\"\n    case \"Khmr\": return \"Khmer\"\n    case \"Knda\": return \"Kannada\"\n    case \"Kore\": return \"Korean (Hangul + Han)\"\n    case \"Laoo\": return \"Lao\"\n    case \"Latn\": return \"Latin\"\n    case \"Mlym\": return \"Malayalam\"\n    case \"Mong\": return \"Mongolian\"\n    case \"Mtei\": return \"Meitei Mayek\"\n    case \"Mymr\": return \"Myanmar\"\n    case \"Orya\": return \"Oriya\"\n    case \"Sinh\": return \"Sinhala\"\n    case \"Taml\": return \"Tamil\"\n    case \"Telu\": return \"Telugu\"\n    case \"Thaa\": return \"Thaana\"\n    case \"Thai\": return \"Thai\"\n    case \"Tibt\": return \"Tibetan\"\n    default: return \"Unknown\"\n    }\n}\n\n# Return the regions that a language is spoken in, as an English string.\nfunction getSpokenIn(code,    i, j, r, regions, str) {\n    r = NULLSTR\n    str = Locale[getCode(code)][\"spoken-in\"]\n    if (str) {\n        split(str, regions, /\\s?;\\s?/)\n        j = 0\n        for (i in regions) {\n            r = r regions[i]\n            j++\n            if (j < length(regions) - 1)\n                r = r \", \"\n            else if (j == length(regions) - 1)\n                r = r \" and \"\n        }\n    }\n    return r\n}\n\n# Return the regions that a script is written in, as an English string.\nfunction getWrittenIn(code,    i, j, r, regions, str) {\n    r = NULLSTR\n    str = Locale[getCode(code)][\"written-in\"]\n    if (str) {\n        split(str, regions, /\\s?;\\s?/)\n        j = 0\n        for (i in regions) {\n            r = r regions[i]\n            j++\n            if (j < length(regions) - 1)\n                r = r \", \"\n            else if (j == length(regions) - 1)\n                r = r \" and \"\n        }\n    }\n    return r\n}\n\n# Return the extra description of a language.\nfunction getDescription(code) {\n    return Locale[getCode(code)][\"description\"]\n}\n\n# Return 1 if a language is supported by Google; otherwise return 0.\nfunction isSupportedByGoogle(code,    engines, i, str) {\n    str = Locale[getCode(code)][\"supported-by\"]\n    if (str) {\n        split(str, engines, /\\s?;\\s?/)\n        for (i in engines)\n            if (engines[i] == \"google\") return 1\n    }\n    return 0\n}\n\n# Return 1 if a language is supported by Bing; otherwise return 0.\nfunction isSupportedByBing(code,    engines, i, str) {\n    str = Locale[getCode(code)][\"supported-by\"]\n    if (str) {\n        split(str, engines, /\\s?;\\s?/)\n        for (i in engines)\n            if (engines[i] == \"bing\") return 1\n    }\n    return 0\n}\n\n# Return detailed information of a language as a string.\nfunction getDetails(code,    article, desc, group, iso, name, names, script, writing) {\n    if (code == \"auto\" || !getCode(code)) {\n        e(\"[ERROR] Language not found: \" code \"\\n\"                      \\\n          \"        Run '-reference / -R' to see a list of available languages.\")\n        exit 1\n    }\n\n    script = scriptName(getScript(code))\n    if (isRTL(code)) script = script \" (R-to-L)\"\n\n    split(getISO(code), group, \"-\")\n    iso = group[1]\n\n    name = getName(code)\n    names = getNames(code)\n    if (match(name, /\\(.*\\)/)) {\n        writing = substr(name, match(name, /\\(.*\\)/) + 1)\n        writing = substr(writing, 1, length(writing) - 1)\n        name = substr(name, 1, match(name, /\\(.*\\)/) - 2)\n    }\n\n    if (getDescription(code))\n        desc = sprintf(\"%s is %s.\", names, getDescription(code))\n    else if (getBranch(code)) {\n        article = match(tolower(getBranch(code)), /^[aeiou]/) ? \"an\" : \"a\"\n        if (iso == \"eng\")\n            desc = sprintf(\"%s is %s %s language spoken %s.\",\n                           names, article, getBranch(code), getSpokenIn(code))\n        else\n            desc = sprintf(\"%s is %s %s language spoken mainly in %s.\",\n                           names, article, getBranch(code), getSpokenIn(code))\n    }\n    else if (getFamily(code) == NULLSTR || tolower(getFamily(code)) == \"language isolate\")\n        desc = sprintf(\"%s is a language spoken mainly in %s.\", names, getSpokenIn(code))\n    else\n        desc = sprintf(\"%s is a language of the %s family, spoken mainly in %s.\",\n                       names, getFamily(code), getSpokenIn(code))\n    if (writing && getWrittenIn(code))\n        desc = desc sprintf(\" The %s writing system is officially used in %s.\",\n                            tolower(writing), getWrittenIn(code))\n\n    return ansi(\"bold\", sprintf(\"%s\\n\", getDisplay(code)))              \\\n        sprintf(\"%-22s%s\\n\", \"Name\", ansi(\"bold\", names))               \\\n        sprintf(\"%-22s%s\\n\", \"Family\", ansi(\"bold\", getFamily(code)))   \\\n        sprintf(\"%-22s%s\\n\", \"Writing system\", ansi(\"bold\", script))    \\\n        sprintf(\"%-22s%s\\n\", \"Code\", ansi(\"bold\", getCode(code)))       \\\n        sprintf(\"%-22s%s\\n\", \"ISO 639-3\", ansi(\"bold\", iso))            \\\n        sprintf(\"%-22s%s\\n\", \"SIL\", ansi(\"bold\", \"https://iso639-3.sil.org/code/\" iso)) \\\n        sprintf(\"%-22s%s\\n\", \"Glottolog\", getGlotto(code) ?\n                ansi(\"bold\", \"https://glottolog.org/resource/languoid/id/\" getGlotto(code)) : \"\") \\\n        sprintf(\"%-22s%s\\n\", \"Wikipedia\", ansi(\"bold\", \"https://en.wikipedia.org/wiki/ISO_639:\" iso)) \\\n        (Locale[getCode(code)][\"supported-by\"] ? # FIXME\n        sprintf(\"%-22s%s\\n\", \"Translator support\", sprintf(\"Google [%s]    Bing [%s]\",\n                isSupportedByGoogle(code) ? \"✔\" : \"✘\", isSupportedByBing(code) ? \"✔\" : \"✘\")) : \"\") \\\n        (Locale[getCode(code)][\"spoken-in\"] ? # FIXME\n        ansi(\"bold\", sprintf(\"\\n%s\", desc)) : \"\")\n}\n\n# Add /slashes/ for IPA phonemic notations and (parentheses) for others.\n# Parameters:\n#     code\nfunction showPhonetics(phonetics, code) {\n    if (code && getCode(code) == \"en\")\n        return \"/\" phonetics \"/\"\n    else\n        return \"(\" phonetics \")\"\n}\n\n# Convert a logical string to visual; don't right justify RTL lines.\n# Parameters:\n#     code: ignore to apply bidirectional algorithm on every string\nfunction show(text, code,    command, temp) {\n    if (!code || isRTL(code)) {\n        if (Cache[text][0])\n            return Cache[text][0]\n        else {\n            if ((FriBidi || (code && isRTL(code))) && BiDiNoPad) {\n                command = \"echo \" parameterize(text) PIPE BiDiNoPad\n                command | getline temp\n                close(command)\n            } else # non-RTL language, or FriBidi not installed\n                temp = text\n            return Cache[text][0] = temp\n        }\n    } else\n        return text\n}\n\n# Convert a logical string to visual and right justify RTL lines.\n# Parameters:\n#     code: ignore to apply bidirectional algorithm on every string\n#     width: ignore to use default width for padding\nfunction s(text, code, width,    command, temp) {\n    if (!code || isRTL(code)) {\n        if (!width) width = Option[\"width\"]\n        if (Cache[text][width])\n            return Cache[text][width]\n        else {\n            if ((FriBidi || (code && isRTL(code))) && BiDi) {\n                command = \"echo \" parameterize(text) PIPE sprintf(BiDi, width)\n                command | getline temp\n                close(command)\n            } else # non-RTL language, or FriBidi not installed\n                temp = text\n            return Cache[text][width] = temp\n        }\n    } else\n        return text\n}\n\n# Convert a logical string to visual with a certain level of indentation.\n# Parameters:\n#     level: level of indentation\n#     code: ignore to apply left indentation\n#     width: ignore to use default width for padding\nfunction ins(level, text, code, width,    i, temp) {\n    if (code && isRTL(code)) {\n        if (!width) width = Option[\"width\"]\n        return s(text, code, width - Option[\"indent\"] * level)\n    } else\n        return replicate(\" \", Option[\"indent\"] * level) text\n}\n\n# Parse a POSIX locale identifier and return the language code;\n# Identified by both language identifier and region identifier.\n# Parameters:\n#     lang = [language[_territory][.codeset][@modifier]]\n# See: <https://en.wikipedia.org/wiki/Locale>\nfunction parseLang(lang,    code, group) {\n    match(lang, /^([a-z][a-z][a-z]?)(_|$)/, group)\n    code = getCode(group[1])\n\n    # Detect region identifier\n    ## Regions using Chinese Simplified: China, Singapore\n    if (lang ~ /^zh_(CN|SG)/) code = \"zh-CN\"\n    ## Regions using Chinese Traditional: Taiwan, Hong Kong\n    else if (lang ~ /^zh_(TW|HK)/) code = \"zh-TW\"\n\n    # FIXME: handle unrecognized language code\n    if (!code) code = \"en\"\n\n    return code\n}\n\n# Initialize `UserLang`.\nfunction initUserLang(    lang, utf) {\n    if (lang = ENVIRON[\"LC_ALL\"]) {\n        if (!UserLocale) UserLocale = lang\n        utf = utf || tolower(lang) ~ /utf-?8$/\n    }\n    if (lang = ENVIRON[\"LANG\"]) {\n        if (!UserLocale) UserLocale = lang\n        utf = utf || tolower(lang) ~ /utf-?8$/\n    }\n    if (!UserLocale) {\n        UserLocale = \"en_US.UTF-8\"\n        utf = 1\n    }\n    if (!utf)\n        w(\"[WARNING] Your locale codeset (\" UserLocale \") is not UTF-8.\")\n\n    UserLang = parseLang(UserLocale)\n}\n"
  },
  {
    "path": "include/Main.awk",
    "content": "####################################################################\n# Main.awk                                                         #\n####################################################################\n\n# Initialization.\nfunction init() {\n    initGawk()\n    initBiDiTerm()\n    initBiDi()\n\n    # (LanguageData.awk & LanguageHelper.awk)\n    initLocale()\n    initLocaleAlias()\n    initUserLang()\n\n    RS = \"\\n\"\n\n    ExitCode = 0\n\n    Option[\"debug\"] = 0\n\n    # Translation engine\n    Option[\"engine\"] = \"auto\"\n\n    # Display\n    Option[\"verbose\"] = 1\n    Option[\"show-original\"] = 1\n    Option[\"show-original-phonetics\"] = 1\n    Option[\"show-translation\"] = 1\n    Option[\"show-translation-phonetics\"] = 1\n    Option[\"show-prompt-message\"] = 1\n    Option[\"show-languages\"] = 1\n    Option[\"show-original-dictionary\"] = 0\n    Option[\"show-dictionary\"] = 1\n    Option[\"show-alternatives\"] = 1\n    Option[\"width\"] = ENVIRON[\"COLUMNS\"] ? ENVIRON[\"COLUMNS\"] - 2 : 0\n    Option[\"indent\"] = 4\n    Option[\"no-ansi\"] = 0\n    Option[\"no-autocorrect\"] = 0\n    Option[\"no-bidi\"] = 0\n    Option[\"force-bidi\"] = 0\n    Option[\"no-warn\"] = 0\n    Option[\"theme\"] = \"default\"\n    Option[\"dump\"] = 0\n\n    # Audio\n    Option[\"play\"] = 0\n    Option[\"narrator\"] = \"female\"\n    Option[\"player\"] = ENVIRON[\"PLAYER\"]\n    Option[\"no-translate\"] = 0\n    Option[\"download-audio\"] = 0\n    Option[\"download-audio-as\"] = NULLSTR\n\n    # Terminal paging and browsing\n    Option[\"view\"] = 0\n    Option[\"pager\"] = ENVIRON[\"PAGER\"]\n    Option[\"browser\"] = ENVIRON[\"BROWSER\"]\n\n    # Networking\n    Option[\"proxy\"] = ENVIRON[\"HTTP_PROXY\"] ? ENVIRON[\"HTTP_PROXY\"] : ENVIRON[\"http_proxy\"]\n    Option[\"user-agent\"] = ENVIRON[\"USER_AGENT\"] ? ENVIRON[\"USER_AGENT\"] :\n        \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) \"         \\\n        \"AppleWebKit/537.36 (KHTML, like Gecko) \"            \\\n        \"Chrome/104.0.0.0 \"                                  \\\n        \"Safari/537.36 \"                                     \\\n        \"Edg/104.0.1293.54\"\n    Option[\"ip-version\"] = 0\n\n    # Interactive shell\n    Option[\"no-rlwrap\"] = 0\n    Option[\"interactive\"] = 0\n    Option[\"emacs\"] = 0\n\n    # I/O\n    Option[\"input\"] = NULLSTR\n    Option[\"output\"] = STDOUT\n\n    # Language preference\n    Option[\"hl\"] = ENVIRON[\"HOST_LANG\"] ? ENVIRON[\"HOST_LANG\"] :\n        ENVIRON[\"HOME_LANG\"] ? ENVIRON[\"HOME_LANG\"] : UserLang # FIXME[1.0]: HOME_LANG to be removed\n    Option[\"sl\"] = ENVIRON[\"SOURCE_LANG\"] ? ENVIRON[\"SOURCE_LANG\"] : \"auto\"\n    Option[\"sls\"][1] = Option[\"sl\"]\n    Option[\"tl\"][1] = ENVIRON[\"TARGET_LANG\"] ? ENVIRON[\"TARGET_LANG\"] : UserLang\n\n    # Text preprocessing\n    Option[\"join-sentence\"] = 0\n}\n\n# Initialization script.\nfunction initScript(    file, line, script, temp) {\n    # Find the initialization file\n    file = \".trans\"\n    if (!fileExists(file)) {\n        file = ENVIRON[\"HOME\"] \"/.translate-shell/init.trans\"\n        if (!fileExists(file)) {\n            file = ENVIRON[\"XDG_CONFIG_HOME\"] \"/translate-shell/init.trans\"\n            if (!fileExists(file)) {\n                file = ENVIRON[\"HOME\"] \"/.config/translate-shell/init.trans\"\n                if (!fileExists(file)) {\n                    file = \"/etc/translate-shell\"\n                    if (!fileExists(file)) return\n                }\n            }\n        }\n    }\n\n    InitScript = file\n    script = NULLSTR\n    while (getline line < InitScript)\n        script = script \"\\n\" line\n    loadOptions(script)\n\n    # HACK: Option[\"tl\"] must be an array\n    if (!isarray(Option[\"tl\"])) {\n        temp = Option[\"tl\"]\n        delete Option[\"tl\"]\n        Option[\"tl\"][1] = temp\n    }\n}\n\n# Miscellany initialization.\nfunction initMisc(    command, group, temp) {\n    # (Translate.awk)\n    initHttpService()\n\n    # Initialize screen width if not set\n    if (!Option[\"width\"] && detectProgram(\"tput\", \"-V\")) {\n        command = \"tput cols\" SUPERR\n        command | getline temp\n        close(command)\n        Option[\"width\"] = temp > 5 ? temp - 2 : 64  # minimum screen width: 4\n    }\n\n    # Disable ANSI escape codes if required\n    if (Option[\"no-ansi\"])\n        delete AnsiCode\n\n    # Disable conversion of bidirectional texts if required or supported by emulator\n    if (Option[\"no-bidi\"] || BiDiTerm == \"mlterm\")\n        # mlterm implements its own padding\n        BiDi = BiDiNoPad = NULLSTR\n    else if (!Option[\"force-bidi\"] && (BiDiTerm == \"vte\" || BiDiTerm == \"konsole\")) {\n        # vte & konsole implement no padding; we should handle this\n        BiDiNoPad = NULLSTR\n        BiDi = \"sed \\\"s/'/\\\\\\\\\\\\'/\\\" | xargs -0 printf '%%%ss'\"\n    }\n\n    # (LanguageData.awk)\n    initLocaleDisplay()\n\n    # Disable everything stderr\n    if (Option[\"no-warn\"])\n        STDERR = \"/dev/null\"\n\n    # Initialize audio player or speech synthesizer\n    if (Option[\"play\"]) {\n        if (!Option[\"player\"]) {\n            initAudioPlayer()\n            Option[\"player\"] = AudioPlayer ? AudioPlayer : Option[\"player\"]\n            if (!Option[\"player\"])\n                initSpeechSynthesizer()\n        }\n\n        if (!Option[\"player\"] && !SpeechSynthesizer) {\n            w(\"[WARNING] No available audio player or speech synthesizer.\")\n            Option[\"play\"] = 0\n        }\n    }\n\n    # Initialize pager\n    if (Option[\"view\"]) {\n        if (!Option[\"pager\"]) {\n            initPager()\n            Option[\"pager\"] = Pager\n        }\n\n        if (!Option[\"pager\"]) {\n            w(\"[WARNING] No available terminal pager.\")\n            Option[\"view\"] = 0\n        }\n    }\n\n    # Initialize browser\n    if (!Option[\"browser\"]) {\n        Platform = detectProgram(\"uname\", \"-s\", 1)\n        Option[\"browser\"] = Platform == \"Darwin\" ? \"open\" : \"xdg-open\"\n    }\n}\n\n# Main entry point.\nBEGIN {\n    init()\n\n    if (!(belongsTo(\"-no-init\", ARGV) || belongsTo(\"--no-init\", ARGV)))\n        initScript() # initialization script overrides default setting\n\n    # Command-line options override initialization script\n    pos = 0\n    noargc = 0\n    while (ARGV[++pos]) {\n        ## Information options\n\n        # -V, -version\n        match(ARGV[pos], /^--?(V|vers(i(on?)?)?)$/)\n        if (RSTART) {\n            InfoOnly = \"version\"\n            continue\n        }\n\n        # -H, -help\n        match(ARGV[pos], /^--?(H|h(e(lp?)?)?)$/)\n        if (RSTART) {\n            InfoOnly = \"help\"\n            continue\n        }\n\n        # -M, -man\n        match(ARGV[pos], /^--?(M|m(a(n(u(al?)?)?)?)?)$/)\n        if (RSTART) {\n            InfoOnly = \"manual\"\n            continue\n        }\n\n        # -T, -reference\n        match(ARGV[pos], /^--?(T|ref(e(r(e(n(ce?)?)?)?)?)?)$/)\n        if (RSTART) {\n            InfoOnly = \"reference\"\n            continue\n        }\n\n        # FIXME[1.0]: to be removed\n        match(ARGV[pos], /^--?r$/)\n        if (RSTART) {\n            w(\"[ERROR] Option '-r' has been deprecated since version 0.9.\\n\" \\\n              \"        Use option '-T' or '-reference' instead.\")\n            exit 1\n        }\n\n        # -R, -reference-english\n        match(ARGV[pos], /^--?(R|reference-e(n(g(l(i(sh?)?)?)?)?)?)$/)\n        if (RSTART) {\n            InfoOnly = \"reference-english\"\n            continue\n        }\n\n        # -S, -list-engines\n        match(ARGV[pos], /^--?(S|list-e(n(g(i(n(es?)?)?)?)?)?)$/)\n        if (RSTART) {\n            InfoOnly = \"list-engines\"\n            continue\n        }\n\n        # -list-languages\n        match(ARGV[pos], /^--?(list-languages)$/)\n        if (RSTART) {\n            InfoOnly = \"list-languages\"\n            continue\n        }\n\n        # -list-languages-english\n        match(ARGV[pos], /^--?(list-languages-english)$/)\n        if (RSTART) {\n            InfoOnly = \"list-languages-english\"\n            continue\n        }\n\n        # -list-codes\n        match(ARGV[pos], /^--?(list-codes)$/)\n        if (RSTART) {\n            InfoOnly = \"list-codes\"\n            continue\n        }\n\n        # -list-all\n        match(ARGV[pos], /^--?(list-all)$/)\n        if (RSTART) {\n            InfoOnly = \"list-all\"\n            continue\n        }\n\n        # -L CODES, -linguist CODES\n        match(ARGV[pos], /^--?(L|linguist)(=(.*)?)?$/, group)\n        if (RSTART) {\n            InfoOnly = \"language\"\n            if (group[2]) {\n                if (group[3]) split(group[3], Option[\"tl\"], \"+\")\n            } else\n                split(ARGV[++pos], Option[\"tl\"], \"+\")\n            continue\n        }\n        # FIXME[1.0]: to be removed\n        # -list CODE\n        match(ARGV[pos], /^--?(list)(=(.*)?)?$/, group)\n        if (RSTART) {\n            w(\"[WARNING] Option '-list' will be deprecated in the next version.\\n\" \\\n              \"          Use '-L' / '-linguist' instead.\")\n            InfoOnly = \"language\"\n            if (group[2]) {\n                if (group[3]) split(group[3], Option[\"tl\"], \"+\")\n            } else\n                split(ARGV[++pos], Option[\"tl\"], \"+\")\n            continue\n        }\n\n        # -U, -upgrade\n        match(ARGV[pos], /^--?(U|upgrade)$/)\n        if (RSTART) {\n            InfoOnly = \"upgrade\"\n            continue\n        }\n\n        # -N, -nothing\n        match(ARGV[pos], /^--?(N|nothing)$/)\n        if (RSTART) {\n            InfoOnly = \"nothing\"\n            continue\n        }\n\n        ## Translator options\n\n        # -e ENGINE, -engine ENGINE\n        match(ARGV[pos], /^--?(e|engine)(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"engine\"] = group[2] ?\n                (group[3] ? group[3] : Option[\"engine\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # Shortcut format\n        # '/ENGINE'\n        match(ARGV[pos], /^\\/(.*)$/, group)\n        if (RSTART) {\n            Option[\"engine\"] = group[1]\n            continue\n        }\n\n        ## Display options\n\n        # -verbose\n        match(ARGV[pos], /^--?verbose$/)\n        if (RSTART) {\n            Option[\"verbose\"] = 1 # default value\n            continue\n        }\n\n        # -b, -brief\n        match(ARGV[pos], /^--?b(r(i(ef?)?)?)?$/)\n        if (RSTART) {\n            Option[\"verbose\"] = 0\n            continue\n        }\n\n        # -d, -dictionary\n        match(ARGV[pos], /^--?d(i(c(t(i(o(n(a(ry?)?)?)?)?)?)?)?)?$/)\n        if (RSTART) {\n            Option[\"show-original-dictionary\"] = 1\n            Option[\"show-dictionary\"] = 0\n            Option[\"show-alternatives\"] = 0\n            continue\n        }\n\n        # -identify\n        match(ARGV[pos], /^--?id(e(n(t(i(fy?)?)?)?)?)?$/)\n        if (RSTART) {\n            Option[\"verbose\"] = Option[\"verbose\"] - 2\n            continue\n        }\n\n        # -show-original Y/n\n        match(ARGV[pos], /^--?show-original(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-original\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-original-phonetics Y/n\n        match(ARGV[pos], /^--?show-original-phonetics(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-original-phonetics\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-translation Y/n\n        match(ARGV[pos], /^--?show-translation(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-translation\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-translation-phonetics Y/n\n        match(ARGV[pos], /^--?show-translation-phonetics(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-translation-phonetics\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-prompt-message Y/n\n        match(ARGV[pos], /^--?show-prompt-message(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-prompt-message\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-languages Y/n\n        match(ARGV[pos], /^--?show-languages(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-languages\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-original-dictionary y/N\n        match(ARGV[pos], /^--?show-original-dictionary(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-original-dictionary\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-dictionary Y/n\n        match(ARGV[pos], /^--?show-dictionary(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-dictionary\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -show-alternatives Y/n\n        match(ARGV[pos], /^--?show-alternatives(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"show-alternatives\"] = yn(group[1] ? group[2] : ARGV[++pos])\n            continue\n        }\n\n        # -w NUM, -width NUM\n        match(ARGV[pos], /^--?w(i(d(th?)?)?)?(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"width\"] = group[4] ?\n                (group[5] ? group[5] : Option[\"width\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -indent NUM\n        match(ARGV[pos], /^--?indent(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"indent\"] = group[1] ?\n                (group[2] ? group[2] : Option[\"indent\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -theme FILENAME\n        match(ARGV[pos], /^--?theme(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"theme\"] = group[1] ?\n                (group[2] ? group[2] : Option[\"theme\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -no-theme\n        match(ARGV[pos], /^--?no-theme$/)\n        if (RSTART) {\n            Option[\"theme\"] = NULLSTR\n            continue\n        }\n\n        # -no-ansi\n        match(ARGV[pos], /^--?no-ansi$/)\n        if (RSTART) {\n            Option[\"no-ansi\"] = 1\n            continue\n        }\n\n        # -no-autocorrect\n        match(ARGV[pos], /^--?no-auto(correct)?$/)\n        if (RSTART) {\n            Option[\"no-autocorrect\"] = 1\n            continue\n        }\n\n        # -no-bidi\n        match(ARGV[pos], /^--?no-bidi/)\n        if (RSTART) {\n            Option[\"no-bidi\"] = 1\n            continue\n        }\n\n        # -bidi\n        match(ARGV[pos], /^--?bidi/)\n        if (RSTART) {\n            Option[\"force-bidi\"] = 1\n            continue\n        }\n\n        # -no-warn\n        match(ARGV[pos], /^--?no-warn/)\n        if (RSTART) {\n            Option[\"no-warn\"] = 1\n            continue\n        }\n\n        # -dump\n        match(ARGV[pos], /^--?dump/)\n        if (RSTART) {\n            Option[\"dump\"] = 1\n            continue\n        }\n\n        ## Audio options\n\n        # -p, -play\n        match(ARGV[pos], /^--?p(l(ay?)?)?$/)\n        if (RSTART) {\n            Option[\"play\"] = 1\n            continue\n        }\n\n        # -speak\n        match(ARGV[pos], /^--?sp(e(ak?)?)?$/)\n        if (RSTART) {\n            Option[\"play\"] = 2\n            continue\n        }\n\n        # -n VOICE, -narrator VOICE\n        match(ARGV[pos], /^--?(n|narrator)(=(.*)?)?$/, group)\n        if (RSTART) {\n            if (!Option[\"play\"]) Option[\"play\"] = 1 # -play by default\n            Option[\"narrator\"] = group[2] ?\n                (group[3] ? group[3] : Option[\"narrator\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -player PROGRAM\n        match(ARGV[pos], /^--?player(=(.*)?)?$/, group)\n        if (RSTART) {\n            if (!Option[\"play\"]) Option[\"play\"] = 1 # -play by default\n            Option[\"player\"] = group[1] ?\n                (group[2] ? group[2] : Option[\"player\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -no-play\n        match(ARGV[pos], /^--?no-play$/)\n        if (RSTART) {\n            Option[\"play\"] = 0\n            continue\n        }\n\n        # -no-translate\n        match(ARGV[pos], /^--?no-tran(s(l(a(te?)?)?)?)?$/)\n        if (RSTART) {\n            Option[\"no-translate\"] = 1\n            continue\n        }\n\n        # -download-audio\n        match(ARGV[pos], /^--?download-a(u(d(io?)?)?)?$/)\n        if (RSTART) {\n            Option[\"download-audio\"] = 1\n            continue\n        }\n\n        # -download-audio-as\n        match(ARGV[pos], /^--?download-audio-as(=(.*)?)?$/, group)\n        if (RSTART) {\n            if (!Option[\"download-audio\"]) Option[\"download-audio\"] = 1\n            Option[\"download-audio-as\"] = group[1] ?\n                (group[2] ? group[2] : Option[\"download-audio-as\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        ## Terminal paging and browsing options\n\n        # -v, -view\n        match(ARGV[pos], /^--?v(i(ew?)?)?$/)\n        if (RSTART) {\n            Option[\"view\"] = 1\n            continue\n        }\n\n        # -pager PROGRAM\n        match(ARGV[pos], /^--?pager(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"view\"] = 1\n            Option[\"pager\"] = group[1] ?\n                (group[2] ? group[2] : Option[\"pager\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -no-view, -no-pager\n        match(ARGV[pos], /^--?no-(view|pager)$/)\n        if (RSTART) {\n            Option[\"view\"] = 0\n            continue\n        }\n\n        # -browser PROGRAM\n        match(ARGV[pos], /^--?browser(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"browser\"] = group[1] ?\n                (group[2] ? group[2] : Option[\"browser\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -no-browser\n        match(ARGV[pos], /^--?no-browser$/)\n        if (RSTART) {\n            Option[\"browser\"] = NONE\n            continue\n        }\n\n        ## Networking options\n\n        # -x HOST:PORT, -proxy HOST:PORT\n        match(ARGV[pos], /^--?(x|proxy)(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"proxy\"] = group[2] ?\n                (group[3] ? group[3] : Option[\"proxy\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -u STRING, -user-agent STRING\n        match(ARGV[pos], /^--?(u|user-agent)(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"user-agent\"] = group[2] ?\n                (group[3] ? group[3] : Option[\"user-agent\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -4, -ipv4, -inet4-only\n        match(ARGV[pos], /^--?(4|ipv4|inet4-only)$/)\n        if (RSTART) {\n            Option[\"ip-version\"] = 4\n            continue\n        }\n\n        # -6, -ipv6, -inet6-only\n        match(ARGV[pos], /^--?(6|ipv6|inet6-only)$/)\n        if (RSTART) {\n            Option[\"ip-version\"] = 6\n            continue\n        }\n\n        ## Interactive shell options\n\n        # -I, -interactive, -shell\n        match(ARGV[pos], /^--?(I|int(e(r(a(c(t(i(ve?)?)?)?)?)?)?)?|shell)$/)\n        if (RSTART) {\n            Option[\"interactive\"] = 1\n            continue\n        }\n\n        # -E, -emacs\n        match(ARGV[pos], /^--?(E|emacs)$/)\n        if (RSTART) {\n            Option[\"emacs\"] = 1\n            continue\n        }\n\n        # -no-rlwrap\n        match(ARGV[pos], /^--?no-rlwrap$/)\n        if (RSTART) {\n            Option[\"no-rlwrap\"] = 1\n            continue\n        }\n\n        # FIXME[1.0]: to be removed\n        # -prompt PROMPT_STRING\n        match(ARGV[pos], /^--?prompt(=(.*)?)?$/, group)\n        if (RSTART) {\n            w(\"[ERROR] Option '-prompt' has been deprecated since version 0.9.\\n\" \\\n              \"        Use configuration variable 'fmt-prompt' instead.\")\n            exit 1\n        }\n\n        # FIXME[1.0]: to be removed\n        # -prompt-color COLOR_CODE\n        match(ARGV[pos], /^--?prompt-color(=(.*)?)?$/, group)\n        if (RSTART) {\n            w(\"[ERROR] Option '-prompt-color' has been deprecated since version 0.9.\\n\" \\\n              \"        Use configuration variable 'sgr-prompt' instead.\")\n            exit 1\n        }\n\n        ## I/O options\n\n        # -i FILENAME, -input FILENAME\n        match(ARGV[pos], /^--?i(n(p(ut?)?)?)?(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"input\"] = group[4] ?\n                (group[5] ? group[5] : Option[\"input\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -o FILENAME, -output FILENAME\n        match(ARGV[pos], /^--?o(u(t(p(ut?)?)?)?)?(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"output\"] = group[5] ?\n                (group[6] ? group[6] : Option[\"output\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        ## Language preference options\n\n        # -hl CODE, -host CODE\n        match(ARGV[pos], /^--?(host|hl)(=(.*)?)?$/, group)\n        if (RSTART) {\n            Option[\"hl\"] = group[2] ?\n                (group[3] ? group[3] : Option[\"hl\"]) :\n                ARGV[++pos]\n            continue\n        }\n        # FIXME[1.0]: to be removed\n        # -l CODE, -lang CODE\n        match(ARGV[pos], /^--?(l(a(ng?)?)?)(=(.*)?)?$/, group)\n        if (RSTART) {\n            w(\"[WARNING] Option '-l' / '-lang' will be deprecated in the next version.\\n\" \\\n              \"          Use '-hl' / '-host' instead.\")\n            Option[\"hl\"] = group[4] ?\n                (group[5] ? group[5] : Option[\"hl\"]) :\n                ARGV[++pos]\n            continue\n        }\n\n        # -s CODES, -sl CODES, -source CODES, -f CODES, -from CODES\n        match(ARGV[pos], /^--?(s(o(u(r(ce?)?)?)?|l)?|f|from)(=(.*)?)?$/, group)\n        if (RSTART) {\n            if (group[6]) {\n                if (group[7]) split(group[7], Option[\"sls\"], \"+\")\n            } else\n                split(ARGV[++pos], Option[\"sls\"], \"+\")\n            Option[\"sl\"] = Option[\"sls\"][1]\n            continue\n        }\n\n        # -t CODES, -tl CODES, -target CODES, -to CODES\n        match(ARGV[pos], /^--?t(a(r(g(et?)?)?)?|l|o)?(=(.*)?)?$/, group)\n        if (RSTART) {\n            if (group[5]) {\n                if (group[6]) split(group[6], Option[\"tl\"], \"+\")\n            } else\n                split(ARGV[++pos], Option[\"tl\"], \"+\")\n            continue\n        }\n\n        # Shortcut format\n        # 'CODE:CODE+...' or 'CODE=CODE+...'\n        match(ARGV[pos], /^[{(\\[]?((@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?\\+)*(@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?)?)?(:|=)((@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?\\+)*(@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?)?)[})\\]]?$/, group)\n        if (RSTART) {\n            if (group[1]) {\n                split(group[1], Option[\"sls\"], \"+\")\n                Option[\"sl\"] = Option[\"sls\"][1]\n            }\n            if (group[7]) split(group[7], Option[\"tl\"], \"+\")\n            continue\n        }\n\n        ## Text preprocessing options\n\n        # -j, -join-sentence\n        match(ARGV[pos], /^--?j(o(i(n(-(s(e(n(t(e(n(ce?)?)?)?)?)?)?)?)?)?)?)?$/)\n        if (RSTART) {\n            Option[\"join-sentence\"] = 1\n            continue\n        }\n\n        ## Other options\n\n        # -D, -debug\n        match(ARGV[pos], /^--?(D|debug)$/)\n        if (RSTART) {\n            Option[\"debug\"] = 1\n            continue\n        }\n\n        # -no-init\n        match(ARGV[pos], /^--?no-init/)\n        if (RSTART) continue # skip\n\n        # -, -no-op\n        match(ARGV[pos], /^-(-?no-op)?$/)\n        if (RSTART) continue # no operation, skip\n\n        # --\n        match(ARGV[pos], /^--$/)\n        if (RSTART) {\n            ++pos # skip the end-of-options option\n            break # no more option from here\n        }\n\n        # non-option argument\n        noargv[noargc++] = ARGV[pos]\n    }\n\n    # Handle interactive shell\n    if (Option[\"interactive\"] && !Option[\"no-rlwrap\"])\n        rlwrapMe() # interactive mode\n    else if (Option[\"emacs\"] && !Option[\"interactive\"] && !Option[\"no-rlwrap\"])\n        if (emacsMe()) # emacs front-end\n            Option[\"interactive\"] = 1 # fallback to interactive mode\n\n    # Get started\n\n    initMisc()\n\n    # Information-only session\n    switch (InfoOnly) {\n    case \"version\":\n        print getVersion()\n        exit ExitCode\n    case \"help\":\n        print getHelp()\n        exit ExitCode\n    case \"manual\":\n        showMan()\n        exit ExitCode\n    case \"reference\":\n        print getReference(\"endonym\")\n        exit ExitCode\n    case \"reference-english\":\n        print getReference(\"name\")\n        exit ExitCode\n    case \"list-engines\":\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n        for (translator in Translator)\n            print (Option[\"engine\"] == translator ? \"* \" : \"  \") translator\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n        exit ExitCode\n    case \"list-languages\":\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n        for (code in Locale)\n            # only show languages that are supported\n            if (Locale[code][\"supported-by\"])\n                print getDisplay(Locale[code][\"endonym\"])\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n        exit ExitCode\n    case \"list-languages-english\":\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = \"compName\"\n        for (code in Locale)\n            # only show languages that are supported\n            if (Locale[code][\"supported-by\"])\n                print Locale[code][\"name\"] #(Locale[code][\"name2\"] ? \" / \" Locale[code][\"name2\"] : \"\")\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n        exit ExitCode\n    case \"list-codes\":\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n        for (code in Locale)\n            # only show languages that are supported\n            if (Locale[code][\"supported-by\"])\n                print code\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n        exit ExitCode\n    case \"list-all\":\n        saveSortedIn = PROCINFO[\"sorted_in\"]\n        PROCINFO[\"sorted_in\"] = \"compName\"\n        for (code in Locale)\n            # only show languages that are supported\n            if (Locale[code][\"supported-by\"])\n                printf(\"%-10s %-30s %s\\n\", code, Locale[code][\"name\"], getDisplay(Locale[code][\"endonym\"]))\n        PROCINFO[\"sorted_in\"] = saveSortedIn\n        exit ExitCode\n    case \"language\":\n        print getLanguage(Option[\"tl\"])\n        exit ExitCode\n    case \"upgrade\":\n        upgrade()\n        exit ExitCode\n    case \"nothing\":\n        exit ExitCode\n    }\n\n    # Load theme (overrides command-line options) - slow\n    setTheme()\n\n    if (Option[\"interactive\"])\n        welcome()\n\n    # More remaining non-option arguments\n    if (pos < ARGC)\n        for (i = pos; i < ARGC; i++)\n            noargv[noargc++] = ARGV[i]\n\n    # Text preprocessing: join all arguments if required\n    if (noargc > 1 && Option[\"join-sentence\"]) {\n        noargv[0] = join(noargv, \" \")\n        noargc = 1\n    }\n\n    if (noargc) {\n        # Translate all non-option arguments\n        for (i = 0; i < noargc; i++) {\n            # Verbose mode: separator between sources\n            if (Option[\"verbose\"] && i > pos)\n                p(prettify(\"source-seperator\", replicate(Option[\"chr-source-seperator\"], Option[\"width\"])))\n\n            translates(noargv[i], 1) # inline mode\n        }\n\n        # If input not specified, we're done\n    } else {\n        # If input not specified, use stdin\n        if (!Option[\"input\"]) Option[\"input\"] = STDIN\n    }\n\n    # If input specified, start translating\n    if (Option[\"input\"])\n        translateMain()\n\n    exit ExitCode\n}\n"
  },
  {
    "path": "include/Parser.awk",
    "content": "####################################################################\n# Parser.awk                                                       #\n####################################################################\n\n# Tokenize a string and return a token list.\nfunction tokenize(returnTokens, string,\n                  delimiters,\n                  newlines,\n                  quotes,\n                  escapeChars,\n                  leftBlockComments,\n                  rightBlockComments,\n                  lineComments,\n                  reservedOperators,\n                  reservedPatterns,\n                  ####\n                  blockCommenting,\n                  c,\n                  currentToken,\n                  escaping,\n                  i,\n                  lineCommenting,\n                  p,\n                  quoting,\n                  r,\n                  s,\n                  tempGroup,\n                  tempPattern,\n                  tempString) {\n    # Default parameters\n    if (!delimiters[0]) {\n        delimiters[0] = \" \"  # whitespace\n        delimiters[1] = \"\\t\" # horizontal tab\n        delimiters[2] = \"\\v\" # vertical tab\n    }\n    if (!newlines[0]) {\n        newlines[0] = \"\\n\" # line feed\n        newlines[1] = \"\\r\" # carriage return\n    }\n    if (!quotes[0]) {\n        quotes[0] = \"\\\"\" # double quote\n    }\n    if (!escapeChars[0]) {\n        escapeChars[0] = \"\\\\\" # backslash\n    }\n    if (!leftBlockComments[0]) {\n        leftBlockComments[0] = \"#|\" # Lisp-style extended comment (open)\n        leftBlockComments[1] = \"/*\" # C-style comment (open)\n        leftBlockComments[2] = \"(*\" # ML-style comment (open)\n    }\n    if (!rightBlockComments[0]) {\n        rightBlockComments[0] = \"|#\" # Lisp-style extended comment (close)\n        rightBlockComments[1] = \"*/\" # C-style comment (close)\n        rightBlockComments[2] = \"*)\" # ML-style comment (close)\n    }\n    if (!lineComments[0]) {\n        lineComments[0] = \";\"  # Lisp-style line comment\n        lineComments[1] = \"//\" # C++-style line comment\n        lineComments[2] = \"#\"  # hash comment\n    }\n    if (!reservedOperators[0]) {\n        reservedOperators[0] = \"(\" #  left parenthesis\n        reservedOperators[1] = \")\" # right parenthesis\n        reservedOperators[2] = \"[\" #  left bracket\n        reservedOperators[3] = \"]\" # right bracket\n        reservedOperators[4] = \"{\" #  left brace\n        reservedOperators[5] = \"}\" # right brace\n        reservedOperators[6] = \",\" # comma\n    }\n    if (!reservedPatterns[0]) {\n        reservedPatterns[0] = \"[+-]?((0|[1-9][0-9]*)|[.][0-9]*|(0|[1-9][0-9]*)[.][0-9]*)([Ee][+-]?[0-9]+)?\" # numeric literal (scientific notation possible)\n        reservedPatterns[1] = \"[+-]?0[0-7]+([.][0-7]*)?\" # numeric literal (octal)\n        reservedPatterns[2] = \"[+-]?0[Xx][0-9A-Fa-f]+([.][0-9A-Fa-f]*)?\" # numeric literal (hexadecimal)\n    }\n\n    split(string, s, \"\")\n    currentToken = \"\"\n    quoting = escaping = blockCommenting = lineCommenting = 0\n    p = 0\n    i = 1\n    while (i <= length(s)) {\n        c = s[i]\n        r = substr(string, i)\n\n        if (blockCommenting) {\n            if (tempString = startsWithAny(r, rightBlockComments))\n                blockCommenting = 0 # block comment ends\n\n            i++\n\n        } else if (lineCommenting) {\n            if (belongsTo(c, newlines))\n                lineCommenting = 0 # line comment ends\n\n            i++\n\n        } else if (quoting) {\n            currentToken = currentToken c\n\n            if (escaping) {\n                escaping = 0 # escape ends\n\n            } else {\n                if (belongsTo(c, quotes)) {\n                    # Finish the current token\n                    if (currentToken) {\n                        returnTokens[p++] = currentToken\n                        currentToken = \"\"\n                    }\n\n                    quoting = 0 # quotation ends\n\n                } else if (belongsTo(c, escapeChars)) {\n                    escaping = 1 # escape begins\n\n                } else {\n                    # Continue\n                }\n            }\n\n            i++\n\n        } else {\n            if (belongsTo(c, delimiters) || belongsTo(c, newlines)) {\n                # Finish the current token\n                if (currentToken) {\n                    returnTokens[p++] = currentToken\n                    currentToken = \"\"\n                }\n\n                i++\n\n            } else if (belongsTo(c, quotes)) {\n                # Finish the current token\n                if (currentToken) {\n                    returnTokens[p++] = currentToken\n                }\n\n                currentToken = c\n\n                quoting = 1 # quotation begins\n\n                i++\n\n            } else if (tempString = startsWithAny(r, leftBlockComments)) {\n                # Finish the current token\n                if (currentToken) {\n                    returnTokens[p++] = currentToken\n                    currentToken = \"\"\n                }\n\n                blockCommenting = 1 # block comment begins\n\n                i += length(tempString)\n\n            } else if (tempString = startsWithAny(r, lineComments)) {\n                # Finish the current token\n                if (currentToken) {\n                    returnTokens[p++] = currentToken\n                    currentToken = \"\"\n                }\n\n                lineCommenting = 1 # line comment begins\n\n                i += length(tempString)\n\n            } else if (tempString = startsWithAny(r, reservedOperators)) {\n                # Finish the current token\n                if (currentToken) {\n                    returnTokens[p++] = currentToken\n                    currentToken = \"\"\n                }\n\n                # Reserve token\n                returnTokens[p++] = tempString\n\n                i += length(tempString)\n\n            } else if (tempPattern = matchesAny(r, reservedPatterns)) {\n                # Finish the current token\n                if (currentToken) {\n                    returnTokens[p++] = currentToken\n                    currentToken = \"\"\n                }\n\n                # Reserve token\n                match(r, \"^\" tempPattern, tempGroup)\n                returnTokens[p++] = tempGroup[0]\n\n                i += length(tempGroup[0])\n\n            } else {\n                # Continue with the current token\n                currentToken = currentToken c\n\n                i++\n            }\n        }\n    }\n\n    # Finish the last token\n    if (currentToken)\n        returnTokens[p++] = currentToken\n\n}\n\n# Parse a token list of JSON array and return an AST.\nfunction parseJsonArray(returnAST, tokens,\n                        leftBrackets,\n                        rightBrackets,\n                        separators,\n                        ####\n                        i, j, key, p, stack, token) {\n    # Default parameters\n    if (!leftBrackets[0]) {\n        leftBrackets[0] = \"(\" # left parenthesis\n        leftBrackets[1] = \"[\" # left bracket\n        leftBrackets[2] = \"{\" # left brace\n    }\n    if (!rightBrackets[0]) {\n        rightBrackets[0] = \")\" # right parenthesis\n        rightBrackets[1] = \"]\" # right bracket\n        rightBrackets[2] = \"}\" # right brace\n    }\n    if (!separators[0]) {\n        separators[0] = \",\" # comma\n    }\n\n    stack[p = 0] = 0\n    for (i = 0; i < length(tokens); i++) {\n        token = tokens[i]\n\n        if (belongsTo(token, leftBrackets))\n            stack[++p] = 0\n        else if (belongsTo(token, rightBrackets))\n            --p\n        else if (belongsTo(token, separators))\n            stack[p]++\n        else {\n            key = stack[0]\n            for (j = 1; j <= p; j++)\n                key = key SUBSEP stack[j]\n            returnAST[key] = token\n        }\n    }\n}\n\n# JSON parser.\nfunction parseJson(returnAST, tokens,\n                   arrayStartTokens, arrayEndTokens,\n                   objectStartTokens, objectEndTokens,\n                   commas, colons,\n                   ####\n                   flag, i, j, key, name, p, stack, token) {\n    # Default parameters\n    if (!arrayStartTokens[0])  arrayStartTokens[0]  = \"[\"\n    if (!arrayEndTokens[0])    arrayEndTokens[0]    = \"]\"\n    if (!objectStartTokens[0]) objectStartTokens[0] = \"{\"\n    if (!objectEndTokens[0])   objectEndTokens[0]   = \"}\"\n    if (!commas[0])            commas[0]            = \",\"\n    if (!colons[0])            colons[0]            = \":\"\n\n    stack[p = 0] = 0\n    flag = 0 # ready to read key\n    for (i = 0; i < length(tokens); i++) {\n        token = tokens[i]\n\n        if (belongsTo(token, arrayStartTokens)) {\n            stack[++p] = 0\n        } else if (belongsTo(token, objectStartTokens)) {\n            stack[++p] = NULLSTR\n            flag = 0 # ready to read key\n        } else if (belongsTo(token, objectEndTokens) ||\n                   belongsTo(token, arrayEndTokens)) {\n            --p\n        } else if (belongsTo(token, commas)) {\n            if (isnum(stack[p])) # array\n                stack[p]++ # increase index\n            else # object\n                flag = 0 # ready to read key\n        } else if (belongsTo(token, colons)) {\n            flag = 1 # ready to read value\n        } else if (isnum(stack[p]) || flag) {\n            # Read a value\n            key = stack[0]\n            for (j = 1; j <= p; j++)\n                key = key SUBSEP stack[j]\n            returnAST[key] = token\n            flag = 0 # ready to read key\n        } else {\n            # Read a key\n            stack[p] = unparameterize(token)\n        }\n    }\n}\n\n# S-expr parser.\nfunction parseList(returnAST, tokens,\n                   leftBrackets,\n                   rightBrackets,\n                   separators,\n                   ####\n                   i, j, key, p, stack, token) {\n    # Default parameters\n    if (!leftBrackets[0]) {\n        leftBrackets[0] = \"(\" # left parenthesis\n        leftBrackets[1] = \"[\" # left bracket\n        leftBrackets[2] = \"{\" # left brace\n    }\n    if (!rightBrackets[0]) {\n        rightBrackets[0] = \")\" # right parenthesis\n        rightBrackets[1] = \"]\" # right bracket\n        rightBrackets[2] = \"}\" # right brace\n    }\n    if (!separators[0]) {\n        separators[0] = \",\" # comma\n    }\n\n    stack[p = 0] = 0\n    for (i = 0; i < length(tokens); i++) {\n        token = tokens[i]\n\n        if (belongsTo(token, leftBrackets)) {\n            stack[++p] = 0\n        } else if (belongsTo(token, rightBrackets)) {\n            stack[--p]++\n        } else if (belongsTo(token, separators)) {\n            # skip\n        } else {\n            key = NULLSTR\n            if (p > 0) {\n                for (j = 0; j < p - 1; j++)\n                    key = key SUBSEP stack[j]\n                returnAST[key][stack[p - 1]] = NULLSTR\n                key = key SUBSEP stack[p - 1]\n            }\n            returnAST[key][stack[p]] = token\n            stack[p]++\n        }\n    }\n}\n"
  },
  {
    "path": "include/REPL.awk",
    "content": "####################################################################\n# REPL.awk                                                         #\n####################################################################\n\n# Welcome message.\nfunction welcome() {\n    if (Option[\"fmt-welcome-message\"])\n        print prettify(\"welcome-message\", Option[\"fmt-welcome-message\"]) > STDERR\n    if (Option[\"fmt-welcome-submessage\"])\n        print prettify(\"welcome-submessage\", Option[\"fmt-welcome-submessage\"]) > STDERR\n}\n\n# Prompt for interactive session.\nfunction prompt(    i, p, temp) {\n    p = Option[\"fmt-prompt\"]\n\n    # Format specifiers supported by strftime().\n    # Roughly following ISO 8601:1988, with the notable exception of \"%S\", \"%t\" and \"%T\".\n    # GNU libc extensions like \"%l\", \"%s\" and \"%_*\" are not supported.\n    # See: <https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html>\n    #      <http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html>\n    if (p ~ /%a/) gsub(/%a/, strftime(\"%a\"), p)\n    if (p ~ /%A/) gsub(/%A/, strftime(\"%A\"), p)\n    if (p ~ /%b/) gsub(/%b/, strftime(\"%b\"), p)\n    if (p ~ /%B/) gsub(/%B/, strftime(\"%B\"), p)\n    if (p ~ /%c/) gsub(/%c/, strftime(\"%c\"), p)\n    if (p ~ /%C/) gsub(/%C/, strftime(\"%C\"), p)\n    if (p ~ /%d/) gsub(/%d/, strftime(\"%d\"), p)\n    if (p ~ /%D/) gsub(/%D/, strftime(\"%D\"), p)\n    if (p ~ /%e/) gsub(/%e/, strftime(\"%e\"), p)\n    if (p ~ /%F/) gsub(/%F/, strftime(\"%F\"), p)\n    if (p ~ /%g/) gsub(/%g/, strftime(\"%g\"), p)\n    if (p ~ /%G/) gsub(/%G/, strftime(\"%G\"), p)\n    if (p ~ /%h/) gsub(/%h/, strftime(\"%h\"), p)\n    if (p ~ /%H/) gsub(/%H/, strftime(\"%H\"), p)\n    if (p ~ /%I/) gsub(/%I/, strftime(\"%I\"), p)\n    if (p ~ /%j/) gsub(/%j/, strftime(\"%j\"), p)\n    if (p ~ /%m/) gsub(/%m/, strftime(\"%m\"), p)\n    if (p ~ /%M/) gsub(/%M/, strftime(\"%M\"), p)\n    if (p ~ /%n/) gsub(/%n/, strftime(\"%n\"), p)\n    if (p ~ /%p/) gsub(/%p/, strftime(\"%p\"), p)\n    if (p ~ /%r/) gsub(/%r/, strftime(\"%r\"), p)\n    if (p ~ /%R/) gsub(/%R/, strftime(\"%R\"), p)\n    if (p ~ /%u/) gsub(/%u/, strftime(\"%u\"), p)\n    if (p ~ /%U/) gsub(/%U/, strftime(\"%U\"), p)\n    if (p ~ /%V/) gsub(/%V/, strftime(\"%V\"), p)\n    if (p ~ /%w/) gsub(/%w/, strftime(\"%w\"), p)\n    if (p ~ /%W/) gsub(/%W/, strftime(\"%W\"), p)\n    if (p ~ /%x/) gsub(/%x/, strftime(\"%x\"), p)\n    if (p ~ /%X/) gsub(/%X/, strftime(\"%X\"), p)\n    if (p ~ /%y/) gsub(/%y/, strftime(\"%y\"), p)\n    if (p ~ /%Y/) gsub(/%Y/, strftime(\"%Y\"), p)\n    if (p ~ /%z/) gsub(/%z/, strftime(\"%z\"), p)\n    if (p ~ /%Z/) gsub(/%Z/, strftime(\"%Z\"), p)\n\n    # %_ : prompt message\n    if (p ~ /%_/)\n        gsub(/%_/, showTranslationsOf(Option[\"hl\"]), p)\n\n    # %l : host language\n    if (p ~ /%l/)\n        gsub(/%l/, getDisplay(Option[\"hl\"]), p)\n\n    # %L : host language (English name)\n    if (p ~ /%L/)\n        gsub(/%L/, getName(Option[\"hl\"]), p)\n\n    # %s : source languages, separated by \"+\"\n    # 's' is the format-control character for string\n\n    # %S : source languages (English names), separated by \"+\"\n    if (p ~ /%S/) {\n        temp = getName(Option[\"sls\"][1])\n        for (i = 2; i <= length(Option[\"sls\"]); i++)\n            temp = temp \"+\" getName(Option[\"sls\"][i])\n        gsub(/%S/, temp, p)\n    }\n\n    # TODO: source languages separated by \",\" and \"/\"\n\n    # %t : target languages, separated by \"+\"\n    if (p ~ /%t/) {\n        temp = getDisplay(Option[\"tl\"][1])\n        for (i = 2; i <= length(Option[\"tl\"]); i++)\n            temp = temp \"+\" getDisplay(Option[\"tl\"][i])\n        gsub(/%t/, temp, p)\n    }\n\n    # %T : target languages (English names), separated by \"+\"\n    if (p ~ /%T/) {\n        temp = getName(Option[\"tl\"][1])\n        for (i = 2; i <= length(Option[\"tl\"]); i++)\n            temp = temp \"+\" getName(Option[\"tl\"][i])\n        gsub(/%T/, temp, p)\n    }\n\n    # %, : target languages, separated by \",\"\n    if (p ~ /%,/) {\n        temp = getDisplay(Option[\"tl\"][1])\n        for (i = 2; i <= length(Option[\"tl\"]); i++)\n            temp = temp \",\" getDisplay(Option[\"tl\"][i])\n        gsub(/%,/, temp, p)\n    }\n\n    # %< : target languages (English names), separated by \",\"\n    if (p ~ /%</) {\n        temp = getName(Option[\"tl\"][1])\n        for (i = 2; i <= length(Option[\"tl\"]); i++)\n            temp = temp \",\" getName(Option[\"tl\"][i])\n        gsub(/%</, temp, p)\n    }\n\n    # %/ : target languages, separated by \"/\"\n    if (p ~ /%\\//) {\n        temp = getDisplay(Option[\"tl\"][1])\n        for (i = 2; i <= length(Option[\"tl\"]); i++)\n            temp = temp \"/\" getDisplay(Option[\"tl\"][i])\n        gsub(/%\\//, temp, p)\n    }\n\n    # %? : target languages (English names), separated by \"/\"\n    if (p ~ /%\\?/) {\n        temp = getName(Option[\"tl\"][1])\n        for (i = 2; i <= length(Option[\"tl\"]); i++)\n            temp = temp \"/\" getName(Option[\"tl\"][i])\n        gsub(/%\\?/, temp, p)\n    }\n\n    # %s : source languages, separated by \"+\"\n    temp = getDisplay(Option[\"sls\"][1])\n    for (i = 2; i <= length(Option[\"sls\"]); i++)\n        temp = temp \"+\" getDisplay(Option[\"sls\"][i])\n    printf(prettify(\"prompt\", p), temp) > STDERR\n}\n\n# REPL.\nfunction repl(line,    command, group, name, i, value, words) {\n    split(line, words, \" \")\n    command = words[1]\n\n    if (command ~ /^:(q|quit)$/) {\n        exit\n    } else if (command ~ /^:set$/) {\n        name = words[2]\n        value = words[3]\n        # :set sl and :set tl should work as intended\n        # TODO: support multiple language codes\n        if (name == \"sl\") {\n            delete Option[\"sls\"]\n            Option[\"sls\"][1] = value\n        } else if (name == \"tl\") {\n            delete Option[\"tl\"]\n            Option[\"tl\"][1] = value\n        } else {\n            Option[name] = value\n        }\n    } else if (command ~ /^:show$/) {\n        name = words[2]\n        print prettify(\"welcome-submessage\", toString(Option[name], 1, 0, 1))\n    } else if (command ~ /^:swap$/) {\n        tl = Option[\"tl\"][1]\n        Option[\"tl\"][1] = Option[\"sls\"][1]\n        Option[\"sls\"][1] = tl\n    } else if (command ~ /^:engine$/) {\n        value = words[2]\n        Option[\"engine\"] = value\n        initHttpService()\n    } else if (command ~ /^:reset$/) {\n        # TODO: reset source and target languages, etc.\n    } else {\n        match(command, /^[{(\\[]?((@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?\\+)*(@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?)?)?(:|=)((@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?\\+)*(@?[a-z][a-z][a-z]?(-[[:alpha:]][[:alpha:]][[:alpha:]]?[[:alpha:]]?)?)?)[})\\]]?$/, group)\n        if (RSTART) {\n            if (group[1]) {\n                split(group[1], Option[\"sls\"], \"+\")\n                Option[\"sl\"] = Option[\"sls\"][1]\n            }\n            if (group[7]) split(group[7], Option[\"tl\"], \"+\")\n            line = words[2]\n            for (i = 3; i <= length(words); i++)\n                line = line \" \" words[i]\n        }\n        if (line) {\n            translates(line)\n\n            # Interactive verbose mode: newline after each translation\n            if (Option[\"verbose\"]) printf RS\n        }\n    }\n\n    prompt()\n}\n"
  },
  {
    "path": "include/Script.awk",
    "content": "####################################################################\n# Script.awk                                                       #\n####################################################################\n\n# Load options from the initialization script.\nfunction loadOptions(script,    i, j, tokens, name, value) {\n    tokenize(tokens, script)\n\n    for (i in tokens) {\n        if (tokens[i] ~ /^:/) {\n            name = substr(tokens[i], 2)\n            value = tokens[i + 1]\n\n            if (value ~ /^[+-]?((0|[1-9][0-9]*)|[.][0-9]*|(0|[1-9][0-9]*)[.][0-9]*)([Ee][+-]?[0-9]+)?$/) {\n                # Decimal number\n                delete Option[name]\n                Option[name] = value\n            } else if (value == \"false\" || value == \"true\") {\n                # Boolean\n                delete Option[name]\n                Option[name] = yn(value)\n            } else if (value ~ /^\".*\"$/) {\n                # String\n                delete Option[name]\n                Option[name] = literal(value)\n            } else if (value == \"[\") {\n                # List of strings\n                delete Option[name]\n                for (j = 1; tokens[i + j + 1] && tokens[i + j + 1] != \"]\"; j++) {\n                    if (tokens[i + j + 1] ~ /^\".*\"$/)\n                        Option[name][j] = literal(tokens[i + j + 1])\n                    else {\n                        e(\"[ERROR] Malformed configuration.\")\n                        return\n                    }\n                }\n            } else {\n                e(\"[ERROR] Malformed configuration.\")\n                return\n            }\n        }\n    }\n}\n\n# Check for upgrade.\nfunction upgrade(    i, newVersion, registry, tokens) {\n    RegistryIndex = \"https://raw.githubusercontent.com/soimort/translate-shell/registry/index.trans\"\n\n    registry = curl(RegistryIndex)\n    if (!registry) {\n        e(\"[ERROR] Failed to check for upgrade.\")\n        ExitCode = 1\n        return\n    }\n\n    tokenize(tokens, registry)\n    for (i in tokens)\n        if (tokens[i] == \":translate-shell\")\n            newVersion = literal(tokens[i + 1])\n    if (newerVersion(newVersion, Version)) {\n        w(\"Current version: \\t\" Version)\n        w(\"New version available: \\t\" newVersion)\n        w(\"Download from: \\t\" \"https://www.soimort.org/translate-shell/trans\")\n    } else {\n        w(\"Current version: \\t\" Version)\n        w(\"Already up-to-date.\")\n    }\n}\n"
  },
  {
    "path": "include/Theme.awk",
    "content": "####################################################################\n# Theme.awk                                                        #\n####################################################################\n\n# Prettify a string using corresponding SGR option.\nfunction prettify(name, string,    i, temp) {\n    temp = string\n    if (\"sgr-\" name in Option)\n        if (isarray(Option[\"sgr-\" name]))\n            for (i in Option[\"sgr-\" name])\n                temp = ansi(Option[\"sgr-\" name][i], temp)\n        else\n            temp = ansi(Option[\"sgr-\" name], temp)\n    return temp\n}\n\n# Return a string representing a random color.\nfunction randomColor(    i) {\n    i = int(5 * rand())\n    switch (i) {\n    case 0: return \"green\"\n    case 1: return \"yellow\"\n    case 2: return \"blue\"\n    case 3: return \"magenta\"\n    case 4: return \"cyan\"\n    default: return \"default\"\n    }\n}\n\n# Set theme to: random.\nfunction setRandomTheme(    i, n, temp) {\n    srand(systime())\n    for (i = 0; i < 3; i++) {\n        do temp = randomColor(); while (belongsTo(temp, n))\n        n[i] = temp\n    }\n\n    Option[\"sgr-prompt-message\"] = Option[\"sgr-languages\"] = n[0]\n    Option[\"sgr-original-dictionary-detailed-word-class\"][1] = n[0]\n    Option[\"sgr-original-dictionary-detailed-word-class\"][2] = \"bold\"\n    Option[\"sgr-original-dictionary-synonyms\"] = n[0]\n    Option[\"sgr-original-dictionary-synonyms-word-class\"][1] = n[0]\n    Option[\"sgr-original-dictionary-synonyms-word-class\"][2] = \"bold\"\n    Option[\"sgr-original-dictionary-examples\"] = n[0]\n    Option[\"sgr-original-dictionary-see-also\"] = n[0]\n    Option[\"sgr-dictionary-word-class\"][1] = n[0]\n    Option[\"sgr-dictionary-word-class\"][2] = \"bold\"\n\n    Option[\"sgr-original\"][1] = Option[\"sgr-original-phonetics\"][1] = n[1]\n    Option[\"sgr-original\"][2] = Option[\"sgr-original-phonetics\"][2] = \"bold\"\n    Option[\"sgr-prompt-message-original\"][1] = n[1]\n    Option[\"sgr-prompt-message-original\"][2] = \"bold\"\n    Option[\"sgr-languages-sl\"] = n[1]\n    Option[\"sgr-original-dictionary-detailed-explanation\"][1] = n[1]\n    Option[\"sgr-original-dictionary-detailed-explanation\"][2] = \"bold\"\n    Option[\"sgr-original-dictionary-detailed-example\"] = n[1]\n    Option[\"sgr-original-dictionary-detailed-synonyms\"] = n[1]\n    Option[\"sgr-original-dictionary-detailed-synonyms-item\"][1] = n[1]\n    Option[\"sgr-original-dictionary-detailed-synonyms-item\"][2] = \"bold\"\n    Option[\"sgr-original-dictionary-synonyms-synonyms\"] = n[1]\n    Option[\"sgr-original-dictionary-synonyms-synonyms-item\"][1] = n[1]\n    Option[\"sgr-original-dictionary-synonyms-synonyms-item\"][2] = \"bold\"\n    Option[\"sgr-original-dictionary-examples-example\"] = n[1]\n    Option[\"sgr-original-dictionary-examples-original\"][1] = n[1]\n    Option[\"sgr-original-dictionary-examples-original\"][2] = \"bold\"\n    Option[\"sgr-original-dictionary-examples-original\"][3] = \"underline\"\n    Option[\"sgr-original-dictionary-see-also-phrases\"] = n[1]\n    Option[\"sgr-original-dictionary-see-also-phrases-item\"][1] = n[1]\n    Option[\"sgr-original-dictionary-see-also-phrases-item\"][2] = \"bold\"\n    Option[\"sgr-dictionary-explanation\"] = n[1]\n    Option[\"sgr-dictionary-explanation-item\"][1] = n[1]\n    Option[\"sgr-dictionary-explanation-item\"][2] = \"bold\"\n    Option[\"sgr-alternatives-original\"][1] = n[1]\n    Option[\"sgr-alternatives-original\"][2] = \"bold\"\n\n    Option[\"sgr-translation\"][1] = Option[\"sgr-translation-phonetics\"][1] = n[2]\n    Option[\"sgr-translation\"][2] = Option[\"sgr-translation-phonetics\"][2] = \"bold\"\n    Option[\"sgr-languages-tl\"] = n[2]\n    Option[\"sgr-dictionary-word\"][1] = n[2]\n    Option[\"sgr-dictionary-word\"][2] = \"bold\"\n    Option[\"sgr-alternatives-translations\"] = n[2]\n    Option[\"sgr-alternatives-translations-item\"][1] = n[2]\n    Option[\"sgr-alternatives-translations-item\"][2] = \"bold\"\n    Option[\"sgr-brief-translation\"][1] = Option[\"sgr-brief-translation-phonetics\"][1] = n[2]\n    Option[\"sgr-brief-translation\"][2] = Option[\"sgr-brief-translation-phonetics\"][2] = \"bold\"\n\n    Option[\"fmt-welcome-message\"] = Name\n    Option[\"sgr-welcome-message\"][1] = n[0]\n    Option[\"sgr-welcome-message\"][2] = \"bold\"\n    Option[\"fmt-welcome-submessage\"] = \"(:q to quit)\"\n    Option[\"sgr-welcome-submessage\"] = n[0]\n    Option[\"fmt-prompt\"] = \"%s> \"\n    Option[\"sgr-prompt\"][1] = n[1]\n    Option[\"sgr-prompt\"][2] = \"bold\"\n}\n\n# Set theme to: default.\nfunction setDefaultTheme() {\n    Option[\"sgr-translation\"] = Option[\"sgr-translation-phonetics\"] = \"bold\"\n    Option[\"sgr-prompt-message-original\"] = \"underline\"\n    Option[\"sgr-languages-sl\"] = \"underline\"\n    Option[\"sgr-languages-tl\"] = \"bold\"\n    Option[\"sgr-original-dictionary-detailed-explanation\"] = \"bold\"\n    Option[\"sgr-original-dictionary-detailed-synonyms-item\"] = \"bold\"\n    Option[\"sgr-original-dictionary-synonyms-synonyms-item\"] = \"bold\"\n    Option[\"sgr-original-dictionary-examples-original\"][1] = \"bold\"\n    Option[\"sgr-original-dictionary-examples-original\"][2] = \"underline\"\n    Option[\"sgr-original-dictionary-see-also-phrases-item\"] = \"bold\"\n    Option[\"sgr-dictionary-word\"] = \"bold\"\n    Option[\"sgr-alternatives-original\"] = \"underline\"\n    Option[\"sgr-alternatives-translations-item\"] = \"bold\"\n    Option[\"fmt-welcome-message\"] = Name\n    Option[\"sgr-welcome-message\"] = \"bold\"\n    Option[\"fmt-welcome-submessage\"] = \"(:q to quit)\"\n    Option[\"fmt-prompt\"] = \"%s> \"\n    Option[\"sgr-prompt\"] = \"bold\"\n}\n\n# Set theme using corresponding option.\nfunction setTheme(    file, line, script) {\n    if (Option[\"theme\"] && Option[\"theme\"] != \"default\"                 \\\n        && Option[\"theme\"] != \"none\" && Option[\"theme\"] != \"random\") {\n        file = Option[\"theme\"]\n        if (!fileExists(file)) {\n            file = ENVIRON[\"HOME\"] \"/.translate-shell/\" Option[\"theme\"]\n            if (!fileExists(file)) {\n                file = ENVIRON[\"HOME\"] \"/.config/translate-shell/\" Option[\"theme\"]\n                if (!fileExists(file)) return\n            }\n        }\n    }\n\n    if (file && fileExists(file)) {\n        # Read from theme file\n        script = NULLSTR\n        while (getline line < file)\n            script = script \"\\n\" line\n        loadOptions(script)\n    } else if (Option[\"theme\"] == \"none\")\n        ;# skip\n    else if (Option[\"theme\"] == \"random\")\n        setRandomTheme()\n    else\n        setDefaultTheme()\n}\n"
  },
  {
    "path": "include/Translate.awk",
    "content": "####################################################################\n# Translate.awk                                                    #\n####################################################################\n\nfunction provides(engineName) {\n    Translator[tolower(engineName)] = TRUE\n}\n\nfunction engineMethod(methodName,    engine, translator) {\n    if (!Translator[Option[\"engine\"]]) {\n        # case-insensitive match engine name\n        engine = tolower(Option[\"engine\"])\n        if (!Translator[engine]) # fuzzy match engine name\n            for (translator in Translator)\n                if (Translator[translator] && # there IS such a translator\n                    translator ~ \"^\"engine) {\n                    engine = translator\n                    break\n                }\n        if (!Translator[engine]) {\n            e(\"[ERROR] Translator not found: \" Option[\"engine\"] \"\\n\"    \\\n              \"        Run '-list-engines / -S' to see a list of available engines.\")\n            exit 1\n        }\n        Option[\"engine\"] = engine\n    }\n    return Option[\"engine\"] methodName\n}\n\n# Detect external audio player (mplayer, mpv, mpg123).\nfunction initAudioPlayer() {\n    AudioPlayer = !system(\"mpv\" SUPOUT SUPERR) ?\n        \"mpv --no-config\" :\n        (!system(\"mplayer\" SUPOUT SUPERR) ?\n         \"mplayer\" :\n         (!system(\"mpg123 --version\" SUPOUT SUPERR) ?\n          \"mpg123\" :\n          \"\"))\n}\n\n# Detect external speech synthesizer (say, espeak).\nfunction initSpeechSynthesizer() {\n    SpeechSynthesizer = !system(\"say ''\" SUPOUT SUPERR) ?\n        \"say\" :\n        (!system(\"espeak ''\" SUPOUT SUPERR) ?\n         \"espeak\" :\n         \"\")\n}\n\n# Detect external terminal pager (less, more, most).\nfunction initPager() {\n    Pager = !system(\"less -V\" SUPOUT SUPERR) ?\n        \"less\" :\n        (!system(\"more -V\" SUPOUT SUPERR) ?\n         \"more\" :\n         (!system(\"most\" SUPOUT SUPERR) ?\n          \"most\" :\n          \"\"))\n}\n\n# Initialize `HttpService`.\nfunction initHttpService(    inet) {\n    _Init()\n\n    inet = \"inet\"\n    if (Option[\"ip-version\"])\n        inet = inet Option[\"ip-version\"]\n    if (Option[\"proxy\"]) {\n        match(Option[\"proxy\"], /^(http:\\/*)?(([^:]+):([^@]+)@)?([^\\/]*):([^\\/:]*)/, HttpProxySpec)\n        HttpAuthUser = HttpProxySpec[3]\n        HttpAuthPass = HttpProxySpec[4]\n        HttpAuthCredentials = base64(unquote(HttpAuthUser) \":\" HttpAuthPass)\n        HttpService = \"/\" inet \"/tcp/0/\" HttpProxySpec[5] \"/\" HttpProxySpec[6]\n        HttpPathPrefix = HttpProtocol HttpHost\n    } else {\n        HttpService = \"/\" inet \"/tcp/0/\" HttpHost \"/\" HttpPort\n        HttpPathPrefix = \"\"\n    }\n\n    # How long to wait in milliseconds for IPv6 before trying IPv4\n    PROCINFO[HttpService, \"READ_TIMEOUT\"] = 2000\n}\n\n# Pre-process string (URL-encode before send).\nfunction preprocess(text) {\n    return quote(text)\n}\n\n# Pre-process string (using hexdump to URL-encode everything).\nfunction preprocessByDump(text,    arr, i, len, temp) {\n    len = dumpX(text, arr)\n    temp = \"\"\n    for (i = 1; i <= len; i++)\n        temp = temp \"%\" arr[i]\n    return temp\n}\n\n# [OBSOLETE] Is this function still relevant?\n# Post-process string (remove any redundant whitespace).\nfunction postprocess(text) {\n    text = gensub(/ ([.,;:?!\"])/, \"\\\\1\", \"g\", text)\n    text = gensub(/([\"]) /, \"\\\\1\", \"g\", text)\n    return text\n}\n\n# Send an HTTP GET request and get response from an online translator.\nfunction getResponse(text, sl, tl, hl,\n                     ####\n                     content, header, isBody, url, group, status, location) {\n    url = _RequestUrl(text, sl, tl, hl)\n\n    header = \"GET \" url \" HTTP/1.1\\r\\n\"           \\\n        \"Host: \" HttpHost \"\\r\\n\"                  \\\n        \"Connection: close\\r\\n\"\n    if (Option[\"user-agent\"])\n        header = header \"User-Agent: \" Option[\"user-agent\"] \"\\r\\n\"\n    if (Cookie)\n        header = header \"Cookie: \" Cookie \"\\r\\n\"\n    if (HttpAuthUser && HttpAuthPass)\n        # TODO: digest auth\n        header = header \"Proxy-Authorization: Basic \" HttpAuthCredentials \"\\r\\n\"\n    l(header) # log request header\n\n    content = NULLSTR; isBody = 0\n    while (1) {\n        # separate header and body correctly with CRLF, per RFC 2616\n        print (header \"\\r\\n\") |& HttpService\n        while ((HttpService |& getline) > 0) {\n            if (isBody)\n                content = content ? content \"\\n\" $0 : $0\n            else if (length($0) <= 1)\n                isBody = 1\n            else { # interesting fields in header\n                match($0, /^HTTP[^ ]* ([^ ]*)/, group)\n                if (RSTART) status = group[1]\n                match($0, /^Location: (.*)/, group)\n                if (RSTART) location = squeeze(group[1]) # squeeze the URL!\n            }\n            l(sprintf(\"%4s bytes > %s\", length($0), $0))\n        }\n        close(HttpService)\n\n        if (ERRNO == \"Connection timed out\") {\n            w(\"[WARNING] \" ERRNO \". Retrying IPv4 connection.\")\n            Option[\"ip-version\"] = 4\n            initHttpService()\n            PROCINFO[HttpService, \"READ_TIMEOUT\"] = 0\n            ERRNO = \"\"\n        } else\n            break\n    }\n\n    if ((status == \"301\" || status == \"302\") && location) {\n        content = curl(location)\n    } else if (status == \"429\") {\n        e(\"[ERROR] \" ucfirst(Option[\"engine\"]) \" did not return results because rate limiting is in effect\")\n        assert(false, \"[ERROR] Rate limiting\")\n    } else if (status >= \"400\") {\n        e(\"[ERROR] \" ucfirst(Option[\"engine\"]) \" returned an error response. HTTP status code: \" status)\n        assert(false, \"[ERROR] Other HTTP error\")\n    }\n\n    return assert(content, \"[ERROR] Null response.\")\n}\n\n# Send an HTTP POST request and return response from an online translator.\nfunction postResponse(text, sl, tl, hl, type,\n                      ####\n                      content, contentLength, contentType, group,\n                      header, isBody, reqBody, url, status, location, userAgent) {\n    url = _PostRequestUrl(text, sl, tl, hl, type)\n    contentType = _PostRequestContentType(text, sl, tl, hl, type)\n    userAgent = _PostRequestUserAgent(text, sl, tl, hl, type)\n    reqBody = _PostRequestBody(text, sl, tl, hl, type)\n    if (DumpContentengths[reqBody])\n        contentLength = DumpContentengths[reqBody]\n    else\n        contentLength = DumpContentengths[reqBody] = dump(reqBody, group)\n\n    header = \"POST \" url \" HTTP/1.1\\r\\n\"                  \\\n        \"Host: \" HttpHost \"\\r\\n\"                          \\\n        \"Connection: close\\r\\n\"                           \\\n        \"Content-Length: \" contentLength \"\\r\\n\"           \\\n        \"Content-Type: \" contentType \"\\r\\n\"     # must!\n    if (Option[\"user-agent\"] && !userAgent)\n        header = header \"User-Agent: \" Option[\"user-agent\"] \"\\r\\n\"\n    if (userAgent)\n        header = header \"User-Agent: \" userAgent \"\\r\\n\"\n    if (Cookie)\n        header = header \"Cookie: \" Cookie \"\\r\\n\"\n    if (HttpAuthUser && HttpAuthPass)\n        # TODO: digest auth\n        header = header \"Proxy-Authorization: Basic \" HttpAuthCredentials \"\\r\\n\"\n    l(header) # log request header\n\n    content = NULLSTR; isBody = 0\n    while (1) {\n        print (header \"\\r\\n\" reqBody) |& HttpService\n        while ((HttpService |& getline) > 0) {\n            if (isBody)\n                content = content ? content \"\\n\" $0 : $0\n            else if (length($0) <= 1)\n                isBody = 1\n            else { # interesting fields in header\n                match($0, /^HTTP[^ ]* ([^ ]*)/, group)\n                if (RSTART) status = group[1]\n                match($0, /^Location: (.*)/, group)\n                if (RSTART) location = squeeze(group[1]) # squeeze the URL!\n            }\n            l(sprintf(\"%4s bytes > %s\", length($0), $0))\n        }\n        close(HttpService)\n\n        if (ERRNO == \"Connection timed out\") {\n            w(\"[WARNING] \" ERRNO \". Retrying IPv4 connection.\")\n            Option[\"ip-version\"] = 4\n            initHttpService()\n            PROCINFO[HttpService, \"READ_TIMEOUT\"] = 0\n            ERRNO = \"\"\n        } else\n            break\n    }\n\n    if (status == \"404\") {\n        e(\"[ERROR] 404 Not Found\")\n        exit 1\n    }\n    if ((status == \"301\" || status == \"302\") && location) {\n        url = \"https\" substr(url, 5) # switch to HTTPS; don't use location!\n        content = curlPost(url, reqBody)\n    } else if (status == \"429\") {\n        e(\"[ERROR] \" ucfirst(Option[\"engine\"]) \" did not return results because rate limiting is in effect\")\n        assert(false, \"[ERROR] Rate limiting\")\n    } else if (status >= \"400\") {\n        e(\"[ERROR] \" ucfirst(Option[\"engine\"]) \" returned an error response. HTTP status code: \" status)\n        assert(false, \"[ERROR] Other HTTP error\")\n    }\n\n    return content\n}\n\n# Print a string (to output file or terminal pager).\nfunction p(string) {\n    if (Option[\"view\"]) {\n        # For environments that don't have LESS=\"-R\"\n        print string | Option[\"pager\"] (Option[\"pager\"] == \"less\" ? \" -R\" : \"\")\n        close(Option[\"pager\"] (Option[\"pager\"] == \"less\" ? \" -R\" : \"\"))\n    } else\n        print string > Option[\"output\"]\n}\n\n# Play using a Text-to-Speech engine.\nfunction play(text, tl,    url, status) {\n    url = _TTSUrl(text, tl)\n\n    # Don't use getline from pipe here - the same pipe will be run only once for each AWK script!\n    status = system(Option[\"player\"] \" \" parameterize(url) SUPOUT SUPERR)\n\n    if (status)\n        w(\"Voice output isn't available for \" getName(tl))\n\n    return status\n}\n\n# Download audio from a Text-to-Speech engine.\nfunction download_audio(text, tl,    url, output) {\n    url = _TTSUrl(text, tl)\n\n    if (Option[\"download-audio-as\"])\n        output = Option[\"download-audio-as\"]\n    else\n        output = text \" [\" Option[\"engine\"] \"] (\" Option[\"narrator\"] \").ts\"\n\n    if (url ~ /^\\//)\n        system(\"mv -- \" parameterize(url) \" \" parameterize(output))\n    else\n        curl(url, output)\n}\n\n# Get the translation of a string.\nfunction getTranslation(text, sl, tl, hl,\n                        isVerbose, toSpeech, returnPlaylist, returnIl) {\n    return _Translate(text, sl, tl, hl,\n                      isVerbose, toSpeech, returnPlaylist, returnIl)\n}\n\n# Translate a file.\nfunction fileTranslation(uri,    group, temp1, temp2) {\n    temp1 = Option[\"input\"]\n    temp2 = Option[\"verbose\"]\n\n    match(uri, /^file:\\/\\/(.*)/, group)\n    Option[\"input\"] = group[1]\n    Option[\"verbose\"] = 0\n\n    translateMain()\n\n    Option[\"input\"] = temp1\n    Option[\"verbose\"] = temp2\n}\n\n# Start a browser session and translate a web page.\nfunction webTranslation(uri, sl, tl, hl,    temp) {\n    temp = _WebTranslateUrl(uri, sl, tl, hl)\n    if (temp) {\n        p(temp)\n        if (Option[\"browser\"] != NONE)\n            system(Option[\"browser\"] \" \" parameterize(temp) SUPOUT SUPERR)\n    }\n}\n\n# Translate the source text (into all target languages).\nfunction translate(text, inline,\n                   ####\n                   i, j, playlist, il, saveSortedIn) {\n\n    if (!getCode(Option[\"hl\"])) {\n        # Check if host language is supported\n        w(\"[WARNING] Unknown language code: \" Option[\"hl\"] \", fallback to English: en\")\n        Option[\"hl\"] = \"en\" # fallback to English\n    } else if (isRTL(Option[\"hl\"])) {\n        # Check if host language is R-to-L\n        if (!FriBidi)\n            w(\"[WARNING] \" getName(Option[\"hl\"]) \" is a right-to-left language, but FriBidi is not found.\")\n    }\n\n    if (!getCode(Option[\"sl\"])) {\n        # Check if source language is supported\n        w(\"[WARNING] Unknown source language code: \" Option[\"sl\"])\n    } else if (isRTL(Option[\"sl\"])) {\n        # Check if source language is R-to-L\n        if (!FriBidi)\n            w(\"[WARNING] \" getName(Option[\"sl\"]) \" is a right-to-left language, but FriBidi is not found.\")\n    }\n\n    saveSortedIn = PROCINFO[\"sorted_in\"]\n    PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n    for (i in Option[\"tl\"]) {\n        # Non-interactive verbose mode: separator between targets\n        if (!Option[\"interactive\"])\n            if (Option[\"verbose\"] && i > 1)\n                p(prettify(\"target-seperator\", replicate(Option[\"chr-target-seperator\"], Option[\"width\"])))\n\n        if (inline &&\n            startsWithAny(text, UriSchemes) == \"file://\") {\n            # translate URL only from command-line parameters (inline)\n            fileTranslation(text)\n        } else if (inline &&\n                   startsWithAny(text, UriSchemes) == \"http://\" ||\n                   startsWithAny(text, UriSchemes) == \"https://\") {\n            # translate URL only from command-line parameters (inline)\n            webTranslation(text, Option[\"sl\"], Option[\"tl\"][i], Option[\"hl\"])\n        } else {\n            if (!Option[\"no-translate\"])\n                p(getTranslation(text, Option[\"sl\"], Option[\"tl\"][i], Option[\"hl\"], Option[\"verbose\"], Option[\"play\"] || Option[\"download-audio\"], playlist, il))\n            else\n                il[0] = Option[\"sl\"] == \"auto\" ? \"en\" : Option[\"sl\"]\n\n            if (Option[\"play\"] == 1) {\n                if (Option[\"player\"])\n                    for (j in playlist)\n                        play(playlist[j][\"text\"], playlist[j][\"tl\"])\n                else if (SpeechSynthesizer)\n                    for (j in playlist)\n                        print playlist[j][\"text\"] | SpeechSynthesizer\n            } else if (Option[\"play\"] == 2) {\n                if (Option[\"player\"])\n                    play(text, il[0])\n                else if (SpeechSynthesizer)\n                    print text | SpeechSynthesizer\n            }\n\n            if (Option[\"download-audio\"] == 1) {\n                # Download the translation unless used with -sp or -no-trans\n                if (Option[\"play\"] != 2 && !Option[\"no-translate\"])\n                    download_audio(playlist[length(playlist) - 1][\"text\"], \\\n                                   playlist[length(playlist) - 1][\"tl\"])\n                else\n                    download_audio(text, il[0])\n            }\n        }\n    }\n    PROCINFO[\"sorted_in\"] = saveSortedIn\n}\n\n# Translate the source text (from all source languages).\nfunction translates(text, inline,\n                    ####\n                    i) {\n    saveSortedIn = PROCINFO[\"sorted_in\"]\n    PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n    for (i in Option[\"sls\"]) {\n        # Non-interactive verbose mode: separator between sources\n        if (!Option[\"interactive\"])\n            if (Option[\"verbose\"] && i > 1)\n                p(prettify(\"target-seperator\", replicate(Option[\"chr-target-seperator\"], Option[\"width\"])))\n\n        Option[\"sl\"] = Option[\"sls\"][i]\n        translate(text, inline)\n    }\n    PROCINFO[\"sorted_in\"] = saveSortedIn\n}\n\n# Read from input and translate each line.\nfunction translateMain(    i, line) {\n    if (Option[\"interactive\"])\n        prompt()\n\n    if (Option[\"input\"] == STDIN || fileExists(Option[\"input\"])) {\n        i = 0\n        while (getline line < Option[\"input\"])\n            if (line) {\n                # Non-interactive verbose mode: separator between sources\n                if (!Option[\"interactive\"])\n                    if (Option[\"verbose\"] && i++ > 0)\n                        p(prettify(\"source-seperator\",\n                                   replicate(Option[\"chr-source-seperator\"],\n                                             Option[\"width\"])))\n\n                if (Option[\"interactive\"])\n                    repl(line)\n                else\n                    translates(line)\n            } else {\n                # Non-interactive brief mode: preserve line breaks\n                if (!Option[\"interactive\"])\n                    if (!Option[\"verbose\"])\n                        p(line)\n            }\n    } else\n        e(\"[ERROR] File not found: \" Option[\"input\"])\n}\n"
  },
  {
    "path": "include/TranslatorInterface.awk",
    "content": "####################################################################\n# TranslatorInterface.awk                                          #\n####################################################################\n\n# Abstract method foobarInit(): ()\nfunction _Init(    vm) {\n    vm = engineMethod(\"Init\")\n    return @vm()\n}\n\n# Abstract method foobarRequestUrl(text, sl, tl, hl: string): string\nfunction _RequestUrl(text, sl, tl, hl,    vm) {\n    vm = engineMethod(\"RequestUrl\")\n    return @vm(text, sl, tl, hl)\n}\n\n# Abstract method foobarPostRequestUrl(text, sl, tl, hl, type: string): string\nfunction _PostRequestUrl(text, sl, tl, hl, type,    vm) {\n    vm = engineMethod(\"PostRequestUrl\")\n    return @vm(text, sl, tl, hl, type)\n}\n\n# Abstract method foobarPostRequestContentType(text, sl, tl, hl, type: string): string\nfunction _PostRequestContentType(text, sl, tl, hl, type,    vm) {\n    vm = engineMethod(\"PostRequestContentType\")\n    return @vm(text, sl, tl, hl, type)\n}\n\n# Abstract method foobarPostRequestUserAgent(text, sl, tl, hl, type: string): string\nfunction _PostRequestUserAgent(text, sl, tl, hl, type,    vm) {\n    vm = engineMethod(\"PostRequestUserAgent\")\n    return @vm(text, sl, tl, hl, type)\n}\n\n# Abstract method foobarPostRequestBody(text, sl, tl, hl, type: string): string\nfunction _PostRequestBody(text, sl, tl, hl, type,    vm) {\n    vm = engineMethod(\"PostRequestBody\")\n    return @vm(text, sl, tl, hl, type)\n}\n\n# Abstract method foobarTTSUrl(text, tl: string): string\nfunction _TTSUrl(text, tl,    vm) {\n    vm = engineMethod(\"TTSUrl\")\n    return @vm(text, tl)\n}\n\n# Abstract method foobarWebTranslateUrl(uri, sl, tl, hl: string): string\nfunction _WebTranslateUrl(uri, sl, tl, hl,    vm) {\n    vm = engineMethod(\"WebTranslateUrl\")\n    return @vm(uri, sl, tl, hl)\n}\n\n# Abstract method foobarTranslate(text, sl, tl, hl: string,\n#                                 isVerbose, toSpeech: boolean,\n#                                 returnPlaylist, returnIl: array): string\nfunction _Translate(text, sl, tl, hl,\n                    isVerbose, toSpeech, returnPlaylist, returnIl,\n                    ####\n                    vm) {\n    vm = engineMethod(\"Translate\")\n    return @vm(text, sl, tl, hl,\n               isVerbose, toSpeech, returnPlaylist, returnIl)\n}\n"
  },
  {
    "path": "include/Translators/Apertium.awk",
    "content": "####################################################################\n# Apertium.awk                                                     #\n####################################################################\n#\n# Last Updated: 14 Mar 2016\nBEGIN { provides(\"apertium\") }\n\nfunction apertiumInit() {\n    HttpProtocol = \"http://\"\n    HttpHost = \"www.apertium.org\"\n    HttpPort = 80\n}\n\nfunction apertiumRequestUrl(text, sl, tl, hl) {\n    return HttpPathPrefix \"/apy/translate?\"                             \\\n        \"langpair=\" preprocess(sl) \"|\" preprocess(tl)                   \\\n        \"&q=\" preprocess(text)\n}\n\nfunction apertiumTTSUrl(text, tl,    narrator) {\n    # Not implemented\n}\n\nfunction apertiumWebTranslateUrl(uri, sl, tl, hl) {\n    # Not implemented\n}\n\n# Get the translation of a string.\nfunction apertiumTranslate(text, sl, tl, hl,\n                           isVerbose, toSpeech, returnPlaylist, returnIl,\n                           ####\n                           r,\n                           content, tokens, ast,\n                           _sl, _tl, _hl, il,\n                           translation,\n                           wShowOriginal, wShowTranslation, wShowLanguages,\n                           group, temp) {\n    if (!getCode(tl)) {\n        # Check if target language is supported\n        w(\"[WARNING] Unknown target language code: \" tl)\n    } else if (isRTL(tl)) {\n        # Check if target language is R-to-L\n        if (!FriBidi)\n            w(\"[WARNING] \" getName(tl) \" is a right-to-left language, but FriBidi is not found.\")\n    }\n    _sl = getCode(sl); if (!_sl) _sl = sl\n    _tl = getCode(tl); if (!_tl) _tl = tl\n    _hl = getCode(hl); if (!_hl) _hl = hl\n\n    # Quick hack: Apertium doesn't have an \"auto\" language code\n    _sl = \"auto\" == _sl ? \"en\" : _sl\n\n    content = getResponse(text, _sl, _tl, _hl)\n    if (Option[\"dump\"])\n        return content\n    tokenize(tokens, content)\n    parseJson(ast, tokens)\n\n    l(content, \"content\", 1, 1)\n    l(tokens, \"tokens\", 1, 0, 1)\n    l(ast, \"ast\")\n    if (!isarray(ast) || !anything(ast)) {\n        e(\"[ERROR] Oops! Something went wrong and I can't translate it for you :(\")\n        ExitCode = 1\n        return\n    }\n\n    translation = uprintf(unquote(unparameterize(ast[0 SUBSEP \"responseData\" SUBSEP \"translatedText\"])))\n\n    returnIl[0] = il = _sl\n    if (Option[\"verbose\"] < -1)\n        return il\n    else if (Option[\"verbose\"] < 0)\n        return getLanguage(il)\n\n    # Generate output\n    if (!isVerbose) {\n        # Brief mode\n        r = translation\n\n    } else {\n        # Verbose mode\n        wShowOriginal = Option[\"show-original\"]\n        wShowTranslation = Option[\"show-translation\"]\n        wShowLanguages = Option[\"show-languages\"]\n\n        if (wShowOriginal) {\n            # Display: original text\n            if (r) r = r RS RS\n            r = r m(\"-- display original text\")\n            r = r prettify(\"original\", s(text, il))\n        }\n\n        if (wShowTranslation) {\n            # Display: major translation\n            if (r) r = r RS RS\n            r = r m(\"-- display major translation\")\n            r = r prettify(\"translation\", s(translation, tl))\n        }\n\n        if (wShowLanguages) {\n            # Display: source language -> target language\n            if (r) r = r RS RS\n            r = r m(\"-- display source language -> target language\")\n            temp = Option[\"fmt-languages\"]\n            if (!temp) temp = \"[ %s -> %t ]\"\n            split(temp, group, /(%s|%S|%t|%T)/)\n            r = r prettify(\"languages\", group[1])\n            if (temp ~ /%s/)\n                r = r prettify(\"languages-sl\", getDisplay(il))\n            if (temp ~ /%S/)\n                r = r prettify(\"languages-sl\", getName(il))\n            r = r prettify(\"languages\", group[2])\n            if (temp ~ /%t/)\n                r = r prettify(\"languages-tl\", getDisplay(tl))\n            if (temp ~ /%T/)\n                r = r prettify(\"languages-tl\", getName(tl))\n            r = r prettify(\"languages\", group[3])\n        }\n    }\n\n    if (toSpeech) {\n        returnPlaylist[0][\"text\"] = translation\n        returnPlaylist[0][\"tl\"] = _tl\n    }\n\n    return r\n}\n"
  },
  {
    "path": "include/Translators/Auto.awk",
    "content": "####################################################################\n# Auto.awk                                                         #\n####################################################################\nBEGIN { provides(\"auto\") }\n\nfunction autoInit() {\n}\n\nfunction autoTTSUrl(text, tl) {\n    # TODO: support Bing\n    Option[\"engine\"] = \"google\"\n    initHttpService()\n    return googleTTSUrl(text, tl)\n    # TODO: reset engine to auto\n}\n\nfunction autoWebTranslateUrl(uri, sl, tl, hl) {\n    # TODO: support Bing\n    Option[\"engine\"] = \"google\"\n    initHttpService()\n    return googleWebTranslateUrl(uri, sl, tl, hl)\n    # TODO: reset engine to auto\n}\n\nfunction autoTranslate(text, sl, tl, hl,\n                       isVerbose, toSpeech, returnPlaylist, returnIl,\n                       ####\n                       engine, temp) {\n    if ((sl == \"auto\" || isSupportedByGoogle(sl)) && (tl == \"auto\" || isSupportedByGoogle(tl))) {\n        # both source and target languages are supported by Google\n        engine = Option[\"engine\"] # auto\n        Option[\"engine\"] = \"google\"\n        initHttpService()\n        temp = googleTranslate(text, sl, tl, hl, isVerbose, toSpeech, returnPlaylist, returnIl)\n        Option[\"engine\"] = engine\n    } else if ((sl == \"auto\" || isSupportedByBing(sl)) && (tl == \"auto\" || isSupportedByBing(tl))) {\n        # both source and target languages are supported by Bing\n        engine = Option[\"engine\"] # auto\n        Option[\"engine\"] = \"bing\"\n        initHttpService()\n        temp = bingTranslate(text, sl, tl, hl, isVerbose, toSpeech, returnPlaylist, returnIl)\n        Option[\"engine\"] = engine\n    } else {\n        # TODO: translate between Google-only and Bing-only languages\n\n        # fallback to Google\n        engine = Option[\"engine\"] # auto\n        Option[\"engine\"] = \"google\"\n        initHttpService()\n        temp = googleTranslate(text, sl, tl, hl, isVerbose, toSpeech, returnPlaylist, returnIl)\n        Option[\"engine\"] = engine\n    }\n    return temp\n}\n"
  },
  {
    "path": "include/Translators/BingTranslator.awk",
    "content": "####################################################################\n# BingTranslator.awk                                               #\n####################################################################\n#\n# Last Updated: 8 Jun 2022\nBEGIN { provides(\"bing\") }\n\nfunction bingInit() {\n    HttpProtocol = \"http://\"\n    HttpHost = \"www.bing.com\"\n    HttpPort = 80\n}\n\n# Set IG, IID, and BingTokenKey (a URL-encoded string containing token and key).\nfunction bingSetup(    ast, content, cookie, group, header, isBody, key,\n                       location, status, token, tokens, url) {\n    url = HttpPathPrefix \"/translator\"\n\n    header = \"GET \" url \" HTTP/1.1\\r\\n\"                                 \\\n        \"Host: \" HttpHost \"\\r\\n\"                                        \\\n        \"Connection: close\\r\\n\"\n    if (Option[\"user-agent\"])\n        header = header \"User-Agent: \" Option[\"user-agent\"] \"\\r\\n\"\n\n    cookie = NULLSTR\n    print header |& HttpService\n    while ((HttpService |& getline) > 0) {\n        match($0, /Set-Cookie: ([^;]*);/, group)\n        if (group[1]) {\n            cookie = cookie (cookie ?  \"; \" : NULLSTR) group[1]\n        }\n        if (isBody)\n            content = content ? content \"\\n\" $0 : $0\n        else if (length($0) <= 1)\n            isBody = 1\n        else { # interesting fields in header\n            match($0, /^HTTP[^ ]* ([^ ]*)/, group)\n            if (RSTART) status = group[1]\n            match($0, /^Location: (.*)/, group)\n            if (RSTART) location = squeeze(group[1]) # squeeze the URL!\n        }\n        l(sprintf(\"%4s bytes > %s\", length($0), length($0) < 1024 ? $0 : \"...\"))\n    }\n    close(HttpService)\n\n    if ((status == \"301\" || status == \"302\") && location)\n        content = curl(location)\n    # FIXME: cookie\n    Cookie = cookie\n\n    match(content, /IG:\"([^\"]+)\"/, group)\n    if (group[1]) {\n        IG = group[1]\n        l(IG, \"IG\")\n    } else {\n        e(\"[ERROR] Failed to extract IG.\")\n        exit 1\n    }\n\n    match(content, /data-iid=\"([^\"]+)\"/, group)\n    if (group[1]) {\n        IID = group[1]\n        l(IID, \"IID\")\n    } else {\n        e(\"[ERROR] Failed to extract IID.\")\n        exit 1\n    }\n\n    match(content, /params_AbusePreventionHelper = ([^;]+);/, group)\n    if (group[1]) {\n        tokenize(tokens, group[1])\n        parseJson(ast, tokens)\n        key = ast[0 SUBSEP 0]\n        token = unparameterize(ast[0 SUBSEP 1])\n        BingTokenKey = sprintf(\"&token=%s&key=%s\", quote(token), quote(key))\n        l(BingTokenKey, \"BingTokenKey\")\n    } else {\n        e(\"[ERROR] Failed to extract token & key.\")\n        exit 1\n    }\n}\n\n# FIXME!\nfunction bingTTSUrl(text, tl,\n                    ####\n                    country, gender, i, group,\n                    header, content, isBody) {\n    gender = \"female\"\n    country = NULLSTR\n    split(Option[\"narrator\"], group, \",\")\n    for (i in group) {\n        if (group[i] ~ /^(f(emale)?|w(oman)?)$/)\n            gender = \"female\"\n        else if (group[i] ~ /^m(ale|an)?$/)\n            gender = \"male\"\n        else\n            country = group[i]\n    }\n\n    # Automatic ISO country code\n    if (country) tl = tl \"-\" country\n    else if (tl == \"ar\") tl = tl \"-EG\" # sometimes doesn't work. Why?\n    else if (tl == \"da\") tl = tl \"-DK\"\n    else if (tl == \"de\") tl = tl \"-DE\"\n    else if (tl == \"en\") tl = tl \"-US\"\n    else if (tl == \"es\") tl = tl \"-ES\"\n    else if (tl == \"fi\") tl = tl \"-FI\"\n    else if (tl == \"fr\") tl = tl \"-FR\"\n    else if (tl == \"it\") tl = tl \"-IT\"\n    else if (tl == \"ja\") tl = tl \"-JP\"\n    else if (tl == \"ko\") tl = tl \"-KR\"\n    else if (tl == \"nl\") tl = tl \"-NL\"\n    else if (tl == \"nb\") tl = tl \"-NO\" # Norwegian Bokmål\n    else if (tl == \"pl\") tl = tl \"-PL\"\n    else if (tl == \"pt\") tl = tl \"-PT\"\n    else if (tl == \"ru\") tl = tl \"-RU\"\n    else if (tl == \"sv\") tl = tl \"-SE\"\n    else if (tl == \"yue\") ;\n    else if (tl == \"zh\") tl = tl \"-CN\"\n\n    header = \"GET \" \"/tspeak?\"                                          \\\n        \"&language=\" tl \"&text=\" preprocess(text)                       \\\n        \"&options=\" gender \"&format=audio%2Fmp3\" \" HTTP/1.1\\r\\n\"        \\\n        \"Host: \" HttpHost \"\\r\\n\"                                        \\\n        \"Connection: close\\r\\n\"\n    if (Option[\"user-agent\"])\n        header = header \"User-Agent: \" Option[\"user-agent\"] \"\\r\\n\"\n    if (Cookie)\n        header = header \"Cookie: \" Cookie \"\\r\\n\"\n\n    content = NULLSTR; isBody = 0\n    print header |& HttpService\n    while ((HttpService |& getline) > 0) {\n        if (isBody)\n            content = content ? content \"\\n\" $0 : $0\n        else if (length($0) <= 1)\n            isBody = 1\n        #l(sprintf(\"%4s bytes > %s\", length($0), $0))\n    }\n    close(HttpService)\n\n    if (!TempFile)\n        TempFile = getOutput(\"mktemp\")\n    printf(\"%s\", content) > TempFile\n    close(TempFile)\n    return TempFile\n}\n\nfunction bingWebTranslateUrl(uri, sl, tl, hl,    _sl, _tl) {\n    # Hot-patches for language codes\n    _sl = sl; _tl = tl\n    if (_sl == \"zh\")    _sl = \"zh-CHS\" # still old format\n    if (_sl == \"zh-CN\") _sl = \"zh-CHS\"\n    if (_sl == \"zh-TW\") _sl = \"zh-CHT\"\n    if (_tl == \"zh\")    _tl = \"zh-CHS\"\n    if (_tl == \"zh-CN\") _tl = \"zh-CHS\"\n    if (_tl == \"zh-TW\") _tl = \"zh-CHT\"\n\n    return \"https://www.translatetheweb.com/?\" \"from=\" _sl \"&to=\" _tl \"&a=\" uri\n}\n\n# [OBSOLETE?] Old dictionary API (via HTTP GET).\nfunction bingRequestUrl(text, sl, tl, hl) {\n    return HttpPathPrefix \"/translator/api/Dictionary/Lookup?\"  \\\n        \"from=\" sl \"&to=\" tl \"&text=\" preprocess(text)\n}\n\n# Main Bing Translator API (via HTTP POST).\nfunction bingPostRequestUrl(text, sl, tl, hl, type) {\n    if (type == \"lookup\")\n        return HttpPathPrefix \"/tlookupv3\"\n    #else if (type == \"transliterate\")\n    #    return HttpPathPrefix \"/ttransliteratev3\"\n    else # type == \"translate\"\n        return HttpPathPrefix \"/ttranslatev3\" sprintf(\"?IG=%s&IID=%s\", IG, IID)\n}\n\nfunction bingPostRequestContentType(text, sl, tl, hl, type) {\n    return \"application/x-www-form-urlencoded\"\n}\n\nfunction bingPostRequestUserAgent(text, sl, tl, hl, type) {\n    return \"\"\n}\n\nfunction bingPostRequestBody(text, sl, tl, hl, type) {\n    if (type == \"lookup\")\n        return \"&text=\" quote(text) \"&from=\" sl \"&to=\" tl\n    #else if (type == \"transliterate\")\n    #    return \"&text=\" quote(text) \"&language=\" sl \"&toScript=\" \"latn\"\n    else # type == \"translate\"\n        return \"&text=\" quote(text) \"&fromLang=\" sl \"&to=\" tl BingTokenKey\n}\n\n# Get the translation of a string.\nfunction bingTranslate(text, sl, tl, hl,\n                       isVerbose, toSpeech, returnPlaylist, returnIl,\n                       ####\n                       r,\n                       content, tokens, ast, dicContent, dicTokens, dicAst,\n                       _sl, _tl, _hl, il, isPhonetic,\n                       translation, phonetics, oPhonetics,\n                       wordClasses, words, wordBackTranslations,\n                       wShowOriginal, wShowOriginalPhonetics,\n                       wShowTranslation, wShowTranslationPhonetics,\n                       wShowLanguages, wShowDictionary,\n                       i, j, k, group, temp, saveSortedIn) {\n    isPhonetic = match(tl, /^@/)\n    tl = substr(tl, 1 + isPhonetic)\n\n    if (!getCode(tl)) {\n        # Check if target language is supported\n        w(\"[WARNING] Unknown target language code: \" tl)\n    } else if (isRTL(tl)) {\n        # Check if target language is R-to-L\n        if (!FriBidi)\n            w(\"[WARNING] \" getName(tl) \" is a right-to-left language, but FriBidi is not found.\")\n    }\n    _sl = getCode(sl); if (!_sl) _sl = sl\n    _tl = getCode(tl); if (!_tl) _tl = tl\n    _hl = getCode(hl); if (!_hl) _hl = hl\n\n    bingSetup()\n\n    # Hot-patches for Bing's own translator language codes\n    # See: <https://docs.microsoft.com/en-us/azure/cognitive-services/Translator/language-support>\n    if (_sl == \"auto\")  _sl = \"auto-detect\"\n    if (_sl == \"tl\")    _sl = \"fil\" # Bing uses 'fil' for Filipino\n    if (_sl == \"hmn\")   _sl = \"mww\" # Bing uses 'mww' for Hmong Daw\n    if (_sl == \"ku\")    _sl = \"kmr\" # Bing uses 'kmr' for Northern Kurdish\n    else if (_sl == \"ckb\") _sl = \"ku\" # and 'ku' for Central Kurdish\n    if (_sl == \"mn\")    _sl = \"mn-Cyrl\" # Bing uses 'mn-Cyrl' for Mongolian (Cyrillic)\n    if (_sl == \"no\")    _sl = \"nb\"  # Bing uses Norwegian Bokmål\n    # Bing uses 'pt' or 'pt-br' for Brazilian Portuguese, 'pt-pt' for European Portuguese\n    if (_sl == \"pt-BR\") _sl = \"pt\" # just pt-br\n    else if (_sl == \"pt-PT\") _sl = \"pt\" # FIXME: support pt-pt\n    if (_sl == \"zh-CN\") _sl = \"zh-Hans\"\n    if (_sl == \"zh-TW\") _sl = \"zh-Hant\"\n    if (_tl == \"tl\")    _tl = \"fil\"\n    if (_tl == \"hmn\")   _tl = \"mww\"\n    if (_tl == \"ku\")    _tl = \"kmr\"\n    else if (_tl == \"ckb\") _tl = \"ku\"\n    if (_tl == \"mn\")    _tl = \"mn-Cyrl\"\n    if (_tl == \"no\")    _tl = \"nb\"\n    if (_tl == \"pt-BR\") _tl = \"pt\"\n    else if (_tl == \"pt-PT\") _tl = \"pt-pt\"\n    if (_tl == \"zh-CN\") _tl = \"zh-Hans\"\n    if (_tl == \"zh-TW\") _tl = \"zh-Hant\"\n\n    # Translation\n    content = postResponse(text, _sl, _tl, _hl, \"translate\")\n    if (content == \"\") {\n        # Empty content. Assume \"301 Moved Permanently\" and use cn.bing.com\n        HttpHost = \"cn.bing.com\"\n        # Just dirty hack\n        if (Option[\"proxy\"]) {\n            HttpPathPrefix = HttpProtocol HttpHost\n        } else {\n            HttpService = \"/\" \"inet\" \"/tcp/0/\" HttpHost \"/\" HttpPort  # FIXME: inet version\n        }\n\n        # Try again\n        content = postResponse(text, _sl, _tl, _hl, \"translate\")\n    }\n    if (Option[\"dump\"])\n        return content\n    tokenize(tokens, content)\n    parseJson(ast, tokens)\n\n    l(content, \"content\", 1, 1)\n    l(tokens, \"tokens\", 1, 0, 1)\n    l(ast, \"ast\")\n    if (!isarray(ast) || !anything(ast)) {\n        e(\"[ERROR] Oops! Something went wrong and I can't translate it for you :(\")\n        ExitCode = 1\n        return\n    }\n\n    if (ast[0 SUBSEP \"statusCode\"] == \"400\") {\n        e(\"[ERROR] \" ucfirst(Option[\"engine\"]) \" does not support the specified language(s)\")\n        ExitCode = 1\n        return\n    }\n\n    translation = unparameterize(ast[0 SUBSEP 0 SUBSEP \"translations\" SUBSEP 0 SUBSEP \"text\"])\n\n    returnIl[0] = il = _sl == \"auto-detect\" ?\n        unparameterize(ast[0 SUBSEP 0 SUBSEP \"detectedLanguage\" SUBSEP \"language\"]) : _sl\n    if (Option[\"verbose\"] < -1)\n        return il\n    if (Option[\"verbose\"] < 0)\n        return getLanguage(il)\n\n    # Transliteration\n    wShowTranslationPhonetics = Option[\"show-translation-phonetics\"]\n    if (wShowTranslationPhonetics) {\n        split(_tl, group, \"-\")\n        #content = postResponse(translation, group[1], group[1], _hl, \"transliterate\")\n        #phonetics = unparameterize(content)\n        phonetics = unparameterize(ast[0 SUBSEP 0 SUBSEP \"translations\" SUBSEP 0 SUBSEP \"transliteration\" \\\n                                       SUBSEP \"text\"])\n        if (phonetics == translation) phonetics = \"\"\n    }\n\n    # Generate output\n    if (!isVerbose) {\n        # Brief mode\n\n        r = isPhonetic && phonetics ?\n            prettify(\"brief-translation-phonetics\", join(phonetics, \" \")) :\n            prettify(\"brief-translation\", s(translation, tl))\n\n    } else {\n        # Verbose mode\n\n        wShowOriginal = Option[\"show-original\"]\n        wShowTranslation = Option[\"show-translation\"]\n        wShowLanguages = Option[\"show-languages\"]\n        wShowDictionary = Option[\"show-dictionary\"]\n\n        # Transliteration (original)\n        wShowOriginalPhonetics = Option[\"show-original-phonetics\"]\n        if (wShowOriginalPhonetics) {\n            split(_sl, group, \"-\")\n            #content = postResponse(text, group[1], group[1], _hl, \"transliterate\")\n            #oPhonetics = unparameterize(content)\n            delete ast  # purge old AST\n            content = postResponse(text, il, il, _hl, \"translate\")\n            tokenize(tokens, content)\n            parseJson(ast, tokens)\n            oPhonetics = unparameterize(ast[0 SUBSEP 0 SUBSEP \"translations\" SUBSEP 0 \\\n                                            SUBSEP \"transliteration\" SUBSEP \"text\"])\n            if (oPhonetics == text) oPhonetics = \"\"\n        }\n\n        if (!oPhonetics) wShowOriginalPhonetics = 0\n        if (!phonetics) wShowTranslationPhonetics = 0\n\n        if (wShowOriginal) {\n            # Display: original text & phonetics\n            if (r) r = r RS RS\n            r = r m(\"-- display original text\")\n            r = r prettify(\"original\", s(text, _sl))\n            if (wShowOriginalPhonetics)\n                r = r RS prettify(\"original-phonetics\", showPhonetics(join(oPhonetics, \" \"), _sl))\n        }\n\n        if (wShowTranslation) {\n            # Display: major translation & phonetics\n            if (r) r = r RS RS\n            r = r m(\"-- display major translation\")\n            r = r prettify(\"translation\", s(translation, tl))\n            if (wShowTranslationPhonetics)\n                r = r RS prettify(\"translation-phonetics\", showPhonetics(join(phonetics, \" \"), tl))\n        }\n\n        if (wShowLanguages) {\n            # Display: source language -> target language\n            if (r) r = r RS RS\n            r = r m(\"-- display source language -> target language\")\n            temp = Option[\"fmt-languages\"]\n            if (!temp) temp = \"[ %s -> %t ]\"\n            split(temp, group, /(%s|%S|%t|%T)/)\n            r = r prettify(\"languages\", group[1])\n            if (temp ~ /%s/)\n                r = r prettify(\"languages-sl\", getDisplay(il))\n            if (temp ~ /%S/)\n                r = r prettify(\"languages-sl\", getName(il))\n            r = r prettify(\"languages\", group[2])\n            if (temp ~ /%t/)\n                r = r prettify(\"languages-tl\", getDisplay(tl))\n            if (temp ~ /%T/)\n                r = r prettify(\"languages-tl\", getName(tl))\n            r = r prettify(\"languages\", group[3])\n        }\n\n        if (wShowDictionary) {\n            # Dictionary API\n            dicContent = postResponse(text, il, _tl, _hl, \"lookup\")\n            if (dicContent != \"\") {\n                tokenize(dicTokens, dicContent)\n                parseJson(dicAst, dicTokens)\n\n                l(dicContent, \"dicContent\", 1, 1)\n                l(dicTokens, \"dicTokens\", 1, 0, 1)\n                l(dicAst, \"dicAst\")\n\n                saveSortedIn = PROCINFO[\"sorted_in\"]\n                PROCINFO[\"sorted_in\"] = \"compareByIndexFields\"\n                for (i in dicAst) {\n                    if (match(i, \"^0\" SUBSEP \"0\" SUBSEP \"translations\" SUBSEP \"([[:digit:]]+)\" SUBSEP \\\n                              \"posTag$\", group))\n                        wordClasses[group[1]] = tolower(literal(dicAst[i]))\n                }\n                for (i in dicAst) {\n                    if (match(i, \"^0\" SUBSEP \"0\" SUBSEP \"translations\" SUBSEP \"([[:digit:]]+)\" SUBSEP \\\n                              \"displayTarget$\", group))\n                        words[wordClasses[group[1]]][group[1]] = literal(dicAst[i])\n                    if (match(i, \"^0\" SUBSEP \"0\" SUBSEP \"translations\" SUBSEP \"([[:digit:]]+)\" SUBSEP \\\n                              \"backTranslations\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"displayText$\", group))\n                        wordBackTranslations[wordClasses[group[1]]][group[1]][group[2]] = literal(dicAst[i])\n                }\n                PROCINFO[\"sorted_in\"] = saveSortedIn\n\n                # Display: dictionary entries\n                if (r) r = r RS\n                r = r m(\"-- display dictionary entries\")\n                for (i = 0; i < length(words); i++) {\n                    r = (i > 0 ? r RS : r) RS prettify(\"dictionary-word-class\", s(wordClasses[i], hl))\n\n                    for (j in words[wordClasses[i]]) {\n                        r = r RS prettify(\"dictionary-word\", ins(1, words[wordClasses[i]][j], tl))\n\n                        if (isRTL(il))\n                            explanation = join(wordBackTranslations[wordClasses[i]][j], \", \")\n                        else {\n                            explanation = prettify(\"dictionary-explanation-item\",\n                                                   wordBackTranslations[wordClasses[i]][j][0])\n                            for (k = 1; k < length(wordBackTranslations[wordClasses[i]][j]); k++)\n                                explanation = explanation prettify(\"dictionary-explanation\", \", \") \\\n                                    prettify(\"dictionary-explanation-item\",\n                                             wordBackTranslations[wordClasses[i]][j][k])\n                        }\n\n                        if (isRTL(il))\n                            r = r RS prettify(\"dictionary-explanation-item\", ins(2, explanation, il))\n                        else\n                            r = r RS ins(2, explanation)\n                    }\n                }\n            }\n        }\n    }\n\n    if (toSpeech) {\n        returnPlaylist[0][\"text\"] = translation\n        returnPlaylist[0][\"tl\"] = _tl\n    }\n\n    return r\n}\n"
  },
  {
    "path": "include/Translators/GoogleTranslate.awk",
    "content": "####################################################################\n# GoogleTranslate.awk                                              #\n####################################################################\n#\n# Last Updated: 25 Jul 2019\nBEGIN { provides(\"google\") }\n\n# FIXME!\n# See: <https://translate.google.com/translate/releases/twsfe_w_20151214_RC03/r/js/desktop_module_main.js>\nfunction genRL(a, x,\n               ####\n               b, c, d, i, y) {\n    tokenize(y, x)\n    parseList(b, y)\n    i = SUBSEP 0\n    for (c = 0; c < length(b[i]) - 2; c += 3) {\n        d = b[i][c + 2]\n        d = d >= 97 ? d - 87 :\n            d - 48 # convert to number\n        d = b[i][c + 1] == 43 ? rshift(a, d) : lshift(a, d)\n        a = b[i][c] == 43 ? and(a + d, 4294967295) : xor(a, d)\n    }\n    return a\n}\nfunction genTK(text,\n               ####\n               a, d, dLen, e, tkk, ub, vb) {\n    if (TK[text]) return TK[text]\n\n    tkk = systime() / 3600\n    ub = \"[43,45,51,94,43,98,43,45,102]\"\n    vb = \"[43,45,97,94,43,54]\"\n\n    # FIXME: build a dump cache!\n    dLen = dump(text, d) # convert to byte array\n    a = tkk\n    for (e = 1; e <= dLen; e++)\n        a = genRL(a + d[e], vb)\n    a = genRL(a, ub)\n    0 > a && (a = and(a, 2147483647) + 2147483648)\n    a %= 1e6\n    TK[text] = a \".\" xor(a, tkk)\n\n    l(text, \"text\")\n    l(tkk, \"tkk\")\n    l(TK[text], \"tk\")\n    return TK[text]\n}\n\nfunction googleInit() {\n    HttpProtocol = \"http://\"\n    HttpHost = \"translate.googleapis.com\"\n    HttpPort = 80\n}\n\nfunction googleRequestUrl(text, sl, tl, hl,    qc) {\n    qc = Option[\"no-autocorrect\"] ? \"qc\" : \"qca\";\n    return HttpPathPrefix \"/translate_a/single?client=gtx\"              \\\n        \"&ie=UTF-8&oe=UTF-8\"                                            \\\n        \"&dt=bd&dt=ex&dt=ld&dt=md&dt=rw&dt=rm&dt=ss&dt=t&dt=at&dt=gt\"   \\\n        \"&dt=\" qc \"&sl=\" sl \"&tl=\" tl \"&hl=\" hl                         \\\n        \"&q=\" preprocessByDump(text)\n}\n\nfunction googleTTSUrl(text, tl) {\n    return HttpProtocol HttpHost \"/translate_tts?ie=UTF-8&client=gtx\"\t\\\n        \"&tl=\" tl \"&q=\" preprocessByDump(text)\n}\n\nfunction googleWebTranslateUrl(uri, sl, tl, hl) {\n    return \"https://translate.google.com/translate?\"    \\\n        \"hl=\" hl \"&sl=\" sl \"&tl=\" tl \"&u=\" uri\n}\n\n# Get the translation of a string.\nfunction googleTranslate(text, sl, tl, hl,\n                         isVerbose, toSpeech, returnPlaylist, returnIl,\n                         ####\n                         r,\n                         content, tokens, ast,\n                         _sl, _tl, _hl, il, ils, isPhonetic,\n                         article, example, explanation, ref, word,\n                         translation, translations, phonetics,\n                         wordClasses, words, segments, altTranslations,\n                         original, oPhonetics, oWordClasses, oWords,\n                         oRefs, oSynonymClasses, oSynonyms,\n                         oExamples, oSeeAlso,\n                         wShowOriginal, wShowOriginalPhonetics,\n                         wShowTranslation, wShowTranslationPhonetics,\n                         wShowPromptMessage, wShowLanguages,\n                         wShowOriginalDictionary, wShowDictionary,\n                         wShowAlternatives,\n                         genderedTrans, hasWordClasses, hasAltTranslations,\n                         i, j, k, group, temp, saveSortedIn) {\n    isPhonetic = match(tl, /^@/)\n    tl = substr(tl, 1 + isPhonetic)\n\n    if (!getCode(tl)) {\n        # Check if target language is supported\n        w(\"[WARNING] Unknown target language code: \" tl)\n    } else if (isRTL(tl)) {\n        # Check if target language is R-to-L\n        if (!FriBidi)\n            w(\"[WARNING] \" getName(tl) \" is a right-to-left language, but FriBidi is not found.\")\n    }\n\n    # Convert codes or aliases to standard codes used by Google Translate\n    # If the code or alias cannot be found, use as it is\n    _sl = getCode(sl); if (!_sl) _sl = sl\n    _tl = getCode(tl); if (!_tl) _tl = tl\n    _hl = getCode(hl); if (!_hl) _hl = hl\n    content = getResponse(text, _sl, _tl, _hl)\n    if (Option[\"dump\"])\n        return content\n    tokenize(tokens, content)\n    parseJsonArray(ast, tokens)\n\n    l(content, \"content\", 1, 1)\n    l(tokens, \"tokens\", 1, 0, 1)\n    l(ast, \"ast\")\n    if (!isarray(ast) || !anything(ast)) {\n        e(\"[ERROR] Oops! Something went wrong and I can't translate it for you :(\")\n        ExitCode = 1\n        return\n    }\n\n    saveSortedIn = PROCINFO[\"sorted_in\"]\n    PROCINFO[\"sorted_in\"] = \"compareByIndexFields\"\n    for (i in ast) {\n        if (ast[i] == \"null\") continue\n\n        if (i ~ \"^0\" SUBSEP \"0\" SUBSEP \"[[:digit:]]+\" SUBSEP \"0$\")\n            append(translations, literal(ast[i]))\n        if (i ~ \"^0\" SUBSEP \"0\" SUBSEP \"[[:digit:]]+\" SUBSEP \"1$\")\n            append(original, literal(ast[i]))\n        if (i ~ \"^0\" SUBSEP \"0\" SUBSEP \"[[:digit:]]+\" SUBSEP \"2$\")\n            append(phonetics, literal(ast[i]))\n        if (i ~ \"^0\" SUBSEP \"0\" SUBSEP \"[[:digit:]]+\" SUBSEP \"3$\")\n            append(oPhonetics, literal(ast[i]))\n\n        # 1 - word classes and explanations\n        if (match(i, \"^0\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group))\n            wordClasses[group[1]] = literal(ast[i])\n        if (match(i, \"^0\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"2\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"([[:digit:]]+)$\", group))\n            words[group[1]][group[2]][group[3]] = literal(ast[i])\n        if (match(i, \"^0\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"2\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)$\", group))\n            words[group[1]][group[2]][\"1\"][group[3]] = literal(ast[i])\n\n        # 5 - alternative translations\n        if (match(i, \"^0\" SUBSEP \"5\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group)) {\n            segments[group[1]] = literal(ast[i])\n            altTranslations[group[1]][0] = \"\"\n        }\n        if (match(i, \"^0\" SUBSEP \"5\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"2\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group))\n            altTranslations[group[1]][group[2]] = literal(ast[i])\n\n        # 7 - autocorrection\n        if (i ~ \"^0\" SUBSEP \"7\" SUBSEP \"5$\") {\n            if (!Option[\"no-autocorrect\"] && ast[i] == \"true\")\n                w(\"Showing translation for:  (use -no-auto to disable autocorrect)\")\n            else\n                w(\"Did you mean: \"                                      \\\n                  ansi(\"bold\", unparameterize(ast[\"0\" SUBSEP \"7\" SUBSEP \"1\"])))\n        }\n\n        # 8 - identified source languages\n        if (i ~ \"^0\" SUBSEP \"8\" SUBSEP \"0\" SUBSEP \"[[:digit:]]+$\" ||\n            i ~ \"^0\" SUBSEP \"2$\")\n            append(ils, literal(ast[i]))\n\n        # 11 - (original) word classes and synonyms\n        if (match(i, \"^0\" SUBSEP \"11\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group))\n            oSynonymClasses[group[1]] = literal(ast[i])\n        if (match(i, \"^0\" SUBSEP \"11\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1$\", group))\n            if (ast[i]) {\n                oRefs[literal(ast[i])][1] = group[1]\n                oRefs[literal(ast[i])][2] = group[2]\n            }\n        if (match(i, \"^0\" SUBSEP \"11\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0\" SUBSEP \"([[:digit:]]+)$\", group))\n            oSynonyms[group[1]][group[2]][group[3]] = literal(ast[i])\n\n        # 12 - (original) word classes and explanations\n        if (match(i, \"^0\" SUBSEP \"12\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group))\n            oWordClasses[group[1]] = literal(ast[i])\n        if (match(i, \"^0\" SUBSEP \"12\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group))\n            oWords[group[1]][group[2]][0] = literal(ast[i])\n        if (match(i, \"^0\" SUBSEP \"12\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1$\", group))\n            oWords[group[1]][group[2]][1] = literal(ast[i])\n        if (match(i, \"^0\" SUBSEP \"12\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"2$\", group))\n            oWords[group[1]][group[2]][2] = literal(ast[i])\n\n        # 13 - (original) examples\n        if (match(i, \"^0\" SUBSEP \"13\" SUBSEP \"0\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"0$\", group))\n            oExamples[group[1]] = literal(ast[i])\n\n        # 14 - (original) see also\n        if (match(i, \"^0\" SUBSEP \"14\" SUBSEP \"0\" SUBSEP \"([[:digit:]]+)$\", group))\n            oSeeAlso[group[1]] = literal(ast[i])\n\n        # 18 - gender-specific translations\n        if (match(i, \"^0\" SUBSEP \"18\" SUBSEP \"0\" SUBSEP \"([[:digit:]]+)\" SUBSEP \"1$\", group))\n            genderedTrans[group[1]] = literal(ast[i])\n    }\n    PROCINFO[\"sorted_in\"] = saveSortedIn\n\n    translation = join(translations)\n\n    returnIl[0] = il = !anything(ils) || belongsTo(sl, ils) ? sl : ils[0]\n    if (Option[\"verbose\"] < -1)\n        return il\n    else if (Option[\"verbose\"] < 0)\n        return getLanguage(il)\n\n    # Generate output\n    if (!isVerbose) {\n        # Brief mode\n\n        r = isPhonetic && anything(phonetics) ?\n            prettify(\"brief-translation-phonetics\", join(phonetics, \" \")) :\n            prettify(\"brief-translation\", s(translation, tl))\n\n        if (toSpeech) {\n            returnPlaylist[0][\"text\"] = translation\n            returnPlaylist[0][\"tl\"] = _tl\n        }\n\n    } else {\n        # Verbose mode\n\n        wShowOriginal = Option[\"show-original\"]\n        wShowOriginalPhonetics = Option[\"show-original-phonetics\"]\n        wShowTranslation = Option[\"show-translation\"]\n        wShowTranslationPhonetics = Option[\"show-translation-phonetics\"]\n        wShowPromptMessage = Option[\"show-prompt-message\"]\n        wShowLanguages = Option[\"show-languages\"]\n        wShowOriginalDictionary = Option[\"show-original-dictionary\"]\n        wShowDictionary = Option[\"show-dictionary\"]\n        wShowAlternatives = Option[\"show-alternatives\"]\n\n        if (!anything(oPhonetics)) wShowOriginalPhonetics = 0\n        if (!anything(phonetics)) wShowTranslationPhonetics = 0\n        if (getCode(il) == getCode(tl) &&                               \\\n            (isarray(oWordClasses) || isarray(oSynonymClasses) ||       \\\n             isarray(oExamples) || isarray(oSeeAlso))) {\n            wShowOriginalDictionary = 1\n            wShowTranslation = 0\n        }\n        hasWordClasses = exists(wordClasses)\n        hasAltTranslations = exists(altTranslations[0])\n        if (!hasWordClasses && !hasAltTranslations)\n            wShowPromptMessage = wShowLanguages = 0\n        if (!hasWordClasses) wShowDictionary = 0\n        if (!hasAltTranslations) wShowAlternatives = 0\n\n        if (wShowOriginal) {\n            # Display: original text & phonetics\n            if (r) r = r RS RS\n            r = r m(\"-- display original text & phonetics\")\n            r = r prettify(\"original\", s(join(original, \" \"), il))\n            if (wShowOriginalPhonetics)\n                r = r RS prettify(\"original-phonetics\", showPhonetics(join(oPhonetics, \" \"), il))\n        }\n\n        if (wShowTranslation) {\n            # Display: major translation & phonetics\n            if (r) r = r RS RS\n            r = r m(\"-- display major translation & phonetics\")\n            if (!exists(genderedTrans))\n                r = r prettify(\"translation\", s(translation, tl))\n            else {\n                r = r prettify(\"prompt-message\", s(\"(♂) \", hl))\n                r = r prettify(\"translation\", s(genderedTrans[0], tl)) RS\n                r = r prettify(\"prompt-message\", s(\"(♀) \", hl))\n                r = r prettify(\"translation\", s(genderedTrans[1], tl))\n            }\n            if (wShowTranslationPhonetics)\n                r = r RS prettify(\"translation-phonetics\", showPhonetics(join(phonetics, \" \"), tl))\n        }\n\n        if (wShowPromptMessage || wShowLanguages)\n            if (r) r = r RS\n        if (wShowPromptMessage) {\n            if (hasWordClasses) {\n                # Display: prompt message (Definitions of ...)\n                if (r) r = r RS\n                r = r m(\"-- display prompt message (Definitions of ...)\")\n                if (isRTL(hl)) # host language is R-to-L\n                    r = r prettify(\"prompt-message\", s(showDefinitionsOf(hl, join(original, \" \"))))\n                else { # host language is L-to-R\n                    split(showDefinitionsOf(hl, \"\\0%s\\0\"), group, \"\\0\")\n                    for (i = 1; i <= length(group); i++) {\n                        if (group[i] == \"%s\")\n                            r = r prettify(\"prompt-message-original\", show(join(original, \" \"), il))\n                        else\n                            r = r prettify(\"prompt-message\", group[i])\n                    }\n                }\n            } else if (hasAltTranslations) {\n                # Display: prompt message (Translations of ...)\n                if (r) r = r RS\n                r = r m(\"-- display prompt message (Translations of ...)\")\n                if (isRTL(hl)) # host language is R-to-L\n                    r = r prettify(\"prompt-message\", s(showTranslationsOf(hl, join(original, \" \"))))\n                else { # host language is L-to-R\n                    split(showTranslationsOf(hl, \"\\0%s\\0\"), group, \"\\0\")\n                    for (i = 1; i <= length(group); i++) {\n                        if (group[i] == \"%s\")\n                            r = r prettify(\"prompt-message-original\", show(join(original, \" \"), il))\n                        else\n                            r = r prettify(\"prompt-message\", group[i])\n                    }\n                }\n            }\n        }\n        if (wShowLanguages) {\n            # Display: source language -> target language\n            if (r) r = r RS\n            r = r m(\"-- display source language -> target language\")\n            temp = Option[\"fmt-languages\"]\n            if (!temp) temp = \"[ %s -> %t ]\"\n            split(temp, group, /(%s|%S|%t|%T)/)\n            r = r prettify(\"languages\", group[1])\n            if (temp ~ /%s/)\n                r = r prettify(\"languages-sl\", getDisplay(il))\n            if (temp ~ /%S/)\n                r = r prettify(\"languages-sl\", getName(il))\n            r = r prettify(\"languages\", group[2])\n            if (temp ~ /%t/)\n                r = r prettify(\"languages-tl\", getDisplay(tl))\n            if (temp ~ /%T/)\n                r = r prettify(\"languages-tl\", getName(tl))\n            r = r prettify(\"languages\", group[3])\n        }\n\n        if (wShowOriginalDictionary) {\n            # Display: original dictionary\n            if (exists(oWordClasses)) {\n                # Detailed explanations\n                if (r) r = r RS\n                r = r m(\"-- display original dictionary (detailed explanations)\")\n                for (i = 0; i < length(oWordClasses); i++) {\n                    r = (i > 0 ? r RS : r) RS prettify(\"original-dictionary-detailed-word-class\", s(oWordClasses[i], hl))\n                    for (j = 0; j < length(oWords[i]); j++) {\n                        explanation = oWords[i][j][0]\n                        ref = oWords[i][j][1]\n                        example = oWords[i][j][2]\n\n                        r = (j > 0 ? r RS : r) RS prettify(\"original-dictionary-detailed-explanation\", ins(1, explanation, il))\n                        if (example)\n                            r = r RS prettify(\"original-dictionary-detailed-example\", ins(2, \"- \\\"\" example \"\\\"\", il))\n                        if (ref && isarray(oRefs[ref])) {\n                            temp = prettify(\"original-dictionary-detailed-synonyms\", ins(1, show(showSynonyms(hl), hl) \": \"))\n                            temp = temp prettify(\"original-dictionary-detailed-synonyms-item\", show(oSynonyms[oRefs[ref][1]][oRefs[ref][2]][0], il))\n                            for (k = 1; k < length(oSynonyms[oRefs[ref][1]][oRefs[ref][2]]); k++)\n                                temp = temp prettify(\"original-dictionary-detailed-synonyms\", \", \") \\\n                                    prettify(\"original-dictionary-detailed-synonyms-item\", show(oSynonyms[oRefs[ref][1]][oRefs[ref][2]][k], il))\n                            r = r RS temp\n                        }\n                    }\n                }\n            }\n            if (exists(oSynonymClasses)) {\n                # Synonyms\n                r = r RS RS\n                r = r m(\"-- display original dictionary (synonyms)\")\n                r = r prettify(\"original-dictionary-synonyms\", s(showSynonyms(hl), hl))\n                for (i = 0; i < length(oSynonymClasses); i++) {\n                    r = (i > 0 ? r RS : r) RS prettify(\"original-dictionary-synonyms-word-class\", ins(1, oSynonymClasses[i], hl))\n                    for (j = 0; j < length(oSynonyms[i]); j++) {\n                        temp = prettify(\"original-dictionary-synonyms-synonyms\", ins(2, \"- \"))\n                        temp = temp prettify(\"original-dictionary-synonyms-synonyms-item\", show(oSynonyms[i][j][0], il))\n                        for (k = 1; k < length(oSynonyms[i][j]); k++)\n                            temp = temp prettify(\"original-dictionary-synonyms-synonyms\", \", \") \\\n                                prettify(\"original-dictionary-synonyms-synonyms-item\", show(oSynonyms[i][j][k], il))\n                        r = r RS temp\n                    }\n                }\n            }\n            if (exists(oExamples)) {\n                # Examples\n                r = r RS RS\n                r = r m(\"-- display original dictionary (examples)\")\n                r = r prettify(\"original-dictionary-examples\", s(showExamples(hl), hl))\n                for (i = 0; i < length(oExamples); i++) {\n                    example = oExamples[i]\n\n                    temp = prettify(\"original-dictionary-examples-example\", ins(1, \"- \"))\n                    split(example, group, /(<b>|<\\/b>)/)\n                    if (group[3] ~ / [[:punct:].]/)\n                        group[3] = substr(group[3], 2)\n                    if (isRTL(il)) # target language is R-to-L\n                        temp = temp show(group[1] group[2] group[3], il)\n                    else # target language is L-to-R\n                        temp = temp prettify(\"original-dictionary-examples-example\", group[1]) \\\n                            prettify(\"original-dictionary-examples-original\", group[2]) \\\n                            prettify(\"original-dictionary-examples-example\", group[3])\n                    r = (i > 0 ? r RS : r) RS temp\n                }\n            }\n            if (exists(oSeeAlso)) {\n                # See also\n                r = r RS RS\n                r = r m(\"-- display original dictionary (see also)\")\n                r = r prettify(\"original-dictionary-see-also\", s(showSeeAlso(hl), hl))\n                temp = ins(1, prettify(\"original-dictionary-see-also-phrases-item\", show(oSeeAlso[0], il)))\n                for (k = 1; k < length(oSeeAlso); k++)\n                    temp = temp prettify(\"original-dictionary-see-also-phrases\", \", \") \\\n                        prettify(\"original-dictionary-see-also-phrases-item\", show(oSeeAlso[k], il))\n                r = r RS temp\n            }\n        }\n\n        if (wShowDictionary) {\n            # Display: dictionary entries\n            if (r) r = r RS\n            r = r m(\"-- display dictionary entries\")\n            for (i = 0; i < length(wordClasses); i++) {\n                r = (i > 0 ? r RS : r) RS prettify(\"dictionary-word-class\", s(wordClasses[i], hl))\n                for (j = 0; j < length(words[i]); j++) {\n                    word = words[i][j][0]\n                    article = words[i][j][4]\n                    if (isRTL(il))\n                        explanation = join(words[i][j][1], \", \")\n                    else {\n                        explanation = prettify(\"dictionary-explanation-item\", words[i][j][1][0])\n                        for (k = 1; k < length(words[i][j][1]); k++)\n                            explanation = explanation prettify(\"dictionary-explanation\", \", \") \\\n                                prettify(\"dictionary-explanation-item\", words[i][j][1][k])\n                    }\n\n                    r = r RS prettify(\"dictionary-word\", ins(1, (article ? \"(\" article \") \" : \"\") word, tl))\n                    if (isRTL(il))\n                        r = r RS prettify(\"dictionary-explanation-item\", ins(2, explanation, il))\n                    else\n                        r = r RS ins(2, explanation)\n                }\n            }\n        }\n\n        if (wShowAlternatives) {\n            # Display: alternative translations\n            if (r) r = r RS RS\n            r = r m(\"-- display alternative translations\")\n            for (i = 0; i < length(altTranslations); i++) {\n                r = (i > 0 ? r RS : r) prettify(\"alternatives-original\", show(segments[i], il))\n                if (isRTL(tl)) {\n                    temp = join(altTranslations[i], \", \")\n                    r = r RS prettify(\"alternatives-translations-item\", ins(1, temp, tl))\n                } else {\n                    temp = prettify(\"alternatives-translations-item\", altTranslations[i][0])\n                    for (j = 1; j < length(altTranslations[i]); j++)\n                        temp = temp prettify(\"alternatives-translations\", \", \") \\\n                            prettify(\"alternatives-translations-item\", altTranslations[i][j])\n                    r = r RS ins(1, temp)\n                }\n            }\n        }\n\n        if (toSpeech) {\n            if (index(showTranslationsOf(hl, \"%s\"), \"%s\") > 2) {\n                returnPlaylist[0][\"text\"] = showTranslationsOf(hl)\n                returnPlaylist[0][\"tl\"] = _hl\n                returnPlaylist[1][\"text\"] = join(original)\n                returnPlaylist[1][\"tl\"] = il\n            } else {\n                returnPlaylist[0][\"text\"] = join(original)\n                returnPlaylist[0][\"tl\"] = il\n                returnPlaylist[1][\"text\"] = showTranslationsOf(hl)\n                returnPlaylist[1][\"tl\"] = _hl\n            }\n            returnPlaylist[2][\"text\"] = translation\n            returnPlaylist[2][\"tl\"] = _tl\n        }\n    }\n\n    return r\n}\n"
  },
  {
    "path": "include/Translators/SpellChecker.awk",
    "content": "####################################################################\n# SpellChecker.awk                                                 #\n####################################################################\nBEGIN {\n    provides(\"spell\")\n    provides(\"aspell\")\n    provides(\"hunspell\")\n}\n\n# Detect external (ispell -a compatible) spell checker.\nfunction spellInit() {\n    Ispell = detectProgram(\"aspell\", \"--version\") ? \"aspell\" :\n        (detectProgram(\"hunspell\", \"--version\") ? \"hunspell\" : \"\")\n\n    if (!Ispell) {\n        e(\"[ERROR] Spell checker (aspell or hunspell) not found.\")\n        exit 1\n    }\n}\n\nfunction aspellInit() {\n    if (!(Ispell = detectProgram(\"aspell\", \"--version\") ? \"aspell\" : \"\")) {\n        e(\"[ERROR] Spell checker (aspell) not found.\")\n        exit 1\n    }\n}\n\nfunction hunspellInit() {\n    if (!(Ispell = detectProgram(\"hunspell\", \"--version\") ? \"hunspell\" : \"\")) {\n        e(\"[ERROR] Spell checker (hunspell) not found.\")\n        exit 1\n    }\n}\n\n# Check a string.\nfunction spellTranslate(text, sl, tl, hl,\n                        isVerbose, toSpeech, returnPlaylist, returnIl,\n                        ####\n                        args, i, j, r, line, group, word, sug) {\n    args = \" -a\" (sl != \"auto\" ? \" -d \" sl : \"\")\n    if (system(\"echo\" PIPE Ispell args SUPOUT SUPERR)) {\n        e(\"[ERROR] No dictionary for language: \" sl)\n        exit 1\n    }\n\n    i = 1\n    r = \"\"\n    while (((\"echo \" parameterize(text) PIPE Ispell args SUPERR) |& getline line) > 0) {\n        match(line,\n              /^& (.*) [[:digit:]]+ [[:digit:]]+: ([^,]+)(, ([^,]+))?(, ([^,]+))?/,\n              group)\n        if (RSTART) {\n            ExitCode = 1 # found a spelling error\n\n            word = group[1]\n            sug = \"[\" group[2]\n            if (group[4]) sug = sug \"|\" group[4]\n            if (group[6]) sug = sug \"|\" group[6]\n            sug = sug \"]\"\n\n            j = i + index(substr(text, i), word) - 1\n            r = r substr(text, i, j - i)\n            r = r ansi(\"bold\", ansi(\"red\", word)) ansi(\"yellow\", sug)\n            i = j + length(word)\n        }\n    }\n    r = r substr(text, i)\n    return r\n}\n\nfunction aspellTranslate(text, sl, tl, hl,\n                         isVerbose, toSpeech, returnPlaylist, returnIl) {\n    return spellTranslate(text, sl, tl, hl)\n}\n\nfunction hunspellTranslate(text, sl, tl, hl,\n                           isVerbose, toSpeech, returnPlaylist, returnIl) {\n    return spellTranslate(text, sl, tl, hl)\n}\n\nfunction spellTTSUrl(text, tl,    narrator) {\n    e(\"[ERROR] Spell checker does not support TTS.\")\n    ExitCode = 1\n    return\n}\n\nfunction aspellTTSUrl(text, tl,    narrator) {\n    return spellTTSUrl(text, tl)\n}\n\nfunction hunspellTTSUrl(text, tl,    narrator) {\n    return spellTTSUrl(text, tl)\n}\n\nfunction spellWebTranslateUrl(uri, sl, tl, hl) {\n    e(\"[ERROR] Spell checker does not support web translation.\")\n    ExitCode = 1\n    return\n}\n\nfunction aspellWebTranslateUrl(uri, sl, tl, hl) {\n    return spellWebTranslateUrl(uri, sl, tl, hl)\n}\n\nfunction hunspellWebTranslateUrl(uri, sl, tl, hl) {\n    return spellWebTranslateUrl(uri, sl, tl, hl)\n}\n"
  },
  {
    "path": "include/Translators/YandexTranslate.awk",
    "content": "####################################################################\n# YandexTranslate.awk                                              #\n####################################################################\n#\n# Last Updated: 11 Aug 2018\nBEGIN { provides(\"yandex\") }\n\nfunction genUcid() {\n    \"uuidgen\" |  getline uuid;\n    close(\"uuidgen\");\n    gsub(\"-\", \"\", uuid);\n    ucid = tolower(uuid)\n}\n\nfunction yandexInit() {\n    genUcid() # generate a one-time key\n    YandexWebTranslate = \"z5h64q92x9.net\" # host for web translation\n\n    HttpProtocol = \"http://\"\n    HttpHost = \"translate.yandex.net\"\n    HttpPort = 80\n}\n\nfunction yandexPostRequestUrl(text, sl, tl, hl,    group) {\n    # Quick hack: Yandex doesn't support digraphia code (yet)\n    split(sl, group, \"-\"); sl = group[1]\n    split(tl, group, \"-\"); tl = group[1]\n\n    return HttpPathPrefix \"/api/v1/tr.json/translate\" \\\n        \"?ucid=\" ucid                                 \\\n        \"&srv=android\"                                \\\n        \"&text=\" preprocess(text)                     \\\n        \"&lang=\" (sl == \"auto\" ? tl : sl \"-\" tl)\n}\n\nfunction yandexPostRequestBody(text, sl, tl, hl, type) {\n    return \"\"\n}\n\nfunction yandexPostRequestContentType(text, sl, tl, hl, type) {\n    return \"application/x-www-form-urlencoded\"\n}\n\nfunction yandexPostRequestUserAgent(text, sl, tl, hl, type) {\n    return \"\"\n}\n\nfunction yandexGetDictionaryResponse(text, sl, tl, hl,    content, header, isBody, url) {\n    # Quick hack: Yandex doesn't support digraphia code (yet)\n    split(sl, group, \"-\"); sl = group[1]\n    split(tl, group, \"-\"); tl = group[1]\n\n    url = \"http://dictionary.yandex.net/dicservice.json/lookupMultiple?\" \\\n        \"&text=\" preprocess(text) \"&dict=\" sl \"-\" tl\n    content = curl(url) # but why?!\n\n    return assert(content, \"[ERROR] Null response.\")\n}\n\nfunction yandexTTSUrl(text, tl,\n                      ####\n                      speaker, emotion, i, group) {\n    speaker = NULLSTR\n    emotion = NULLSTR\n    split(Option[\"narrator\"], group, \",\")\n    for (i in group) {\n        if (group[i] ~ /^(g(ood)?|n(eutral)?|e(vil)?)$/)\n            emotion = group[i]\n        else if (group[i] ~ /^(f(emale)?|w(oman)?)$/)\n            speaker = \"alyss\"\n        else if (group[i] ~ /^m(ale|an)?$/)\n            speaker = \"zahar\"\n        else\n            speaker = group[i]\n    }\n\n    switch (tl) { # List of available TTS language codes\n    case \"ar\": tl = \"ar_AE\"; break\n    case \"cs\": tl = \"cs_CZ\"; break\n    case \"da\": tl = \"da_DK\"; break\n    case \"de\": tl = \"de_DE\"; break\n    case \"el\": tl = \"el_GR\"; break\n    case \"en\": tl = \"en_GB\"; break\n    case \"es\": tl = \"es_ES\"; break\n    case \"fi\": tl = \"fi_FI\"; break\n    case \"fr\": tl = \"fr_FR\"; break\n    case \"it\": tl = \"it_IT\"; break\n    case \"nl\": tl = \"nl_NL\"; break\n    case \"no\": tl = \"no_NO\"; break\n    case \"pl\": tl = \"pl_PL\"; break\n    case \"pt\": tl = \"pt_PT\"; break\n    case \"ru\": tl = \"ru_RU\"; break\n    case \"sv\": tl = \"sv_SE\"; break\n    case \"tr\": tl = \"tr_TR\"; break\n    default: tl = NULLSTR\n    }\n    return HttpProtocol \"tts.voicetech.yandex.net\" \"/tts?\"              \\\n        \"text=\" preprocess(text) (tl ? \"&lang=\" tl : tl)                \\\n        (speaker ? \"&speaker=\" speaker : speaker)                       \\\n        (emotion ? \"&emotion=\" emotion : emotion)                       \\\n        \"&format=mp3\" \"&quality=hi\"\n}\n\nfunction yandexWebTranslateUrl(uri, sl, tl, hl) {\n    gsub(/:\\/\\//, \"/\", uri)\n    return HttpProtocol YandexWebTranslate \"/proxy_u/\"  \\\n        (sl == \"auto\" ? tl : sl \"-\" tl)\"/\" uri\n}\n\n# Get the translation of a string.\nfunction yandexTranslate(text, sl, tl, hl,\n                         isVerbose, toSpeech, returnPlaylist, returnIl,\n                         ####\n                         r,\n                         content, tokens, ast,\n                         _sl, _tl, _hl, il, isPhonetic,\n                         translation,\n                         wShowOriginal, wShowTranslation, wShowLanguages,\n                         wShowDictionary, dicContent, dicTokens, dicAst,\n                         i, syn, mean,\n                         group, temp) {\n    isPhonetic = match(tl, /^@/)\n    tl = substr(tl, 1 + isPhonetic)\n\n    if (!getCode(tl)) {\n        # Check if target language is supported\n        w(\"[WARNING] Unknown target language code: \" tl)\n    } else if (isRTL(tl)) {\n        # Check if target language is R-to-L\n        if (!FriBidi)\n            w(\"[WARNING] \" getName(tl) \" is a right-to-left language, but FriBidi is not found.\")\n    }\n    _sl = getCode(sl); if (!_sl) _sl = sl\n    _tl = getCode(tl); if (!_tl) _tl = tl\n    _hl = getCode(hl); if (!_hl) _hl = hl\n\n    content = postResponse(text, _sl, _tl, _hl)\n    if (Option[\"dump\"])\n        return content\n    tokenize(tokens, content)\n    parseJson(ast, tokens)\n\n    l(content, \"content\", 1, 1)\n    l(tokens, \"tokens\", 1, 0, 1)\n    l(ast, \"ast\")\n    if (!isarray(ast) || !anything(ast)) {\n        e(\"[ERROR] Oops! Something went wrong and I can't translate it for you :(\")\n        ExitCode = 1\n        return\n    }\n    if (ast[0 SUBSEP \"code\"] != \"200\") {\n        e(\"[ERROR] \" unparameterize(ast[0 SUBSEP \"message\"]))\n        ExitCode = 1\n        return\n    }\n\n    translation = unparameterize(ast[0 SUBSEP \"text\" SUBSEP 0])\n\n    # Transliteration\n    wShowTranslationPhonetics = Option[\"show-translation-phonetics\"]\n    if (wShowTranslationPhonetics && _tl != \"emj\") {\n        data = \"text=\" text \"&lang=\" tl\n        content = curlPost(\"https://translate.yandex.net/translit/translit\", data)\n        phonetics = (content ~ /not supported$/) ? \"\" : unparameterize(content)\n    }\n\n    split(unparameterize(ast[0 SUBSEP \"lang\"]), group, \"-\")\n    returnIl[0] = il = group[1]\n    if (Option[\"verbose\"] < -1)\n        return il\n    else if (Option[\"verbose\"] < 0)\n        return getLanguage(il)\n\n    # Generate output\n    if (!isVerbose) {\n        # Brief mode\n\n        r = isPhonetic && phonetics ?\n            prettify(\"brief-translation-phonetics\", join(phonetics, \" \")) :\n            prettify(\"brief-translation\", s(translation, tl))\n\n    } else {\n        # Verbose mode\n\n        wShowOriginal = Option[\"show-original\"]\n        wShowTranslation = Option[\"show-translation\"]\n        wShowLanguages = Option[\"show-languages\"]\n        wShowDictionary = Option[\"show-dictionary\"]\n\n        # Transliteration (original)\n        wShowOriginalPhonetics = Option[\"show-original-phonetics\"]\n        if (wShowTranslationPhonetics && il != \"emj\") {\n            data = \"text=\" text \"&lang=\" sl\n            content = curlPost(\"https://translate.yandex.net/translit/translit\", data)\n            oPhonetics = (content ~ /not supported$/) ? \"\" : unparameterize(content)\n        }\n\n        if (!oPhonetics) wShowOriginalPhonetics = 0\n        if (!phonetics) wShowTranslationPhonetics = 0\n\n        if (wShowOriginal) {\n            # Display: original text & phonetics\n            if (r) r = r RS RS\n            r = r m(\"-- display original text & phonetics\")\n            r = r prettify(\"original\", s(text, il))\n            if (wShowOriginalPhonetics)\n                r = r RS prettify(\"original-phonetics\", showPhonetics(join(oPhonetics, \" \"), il))\n        }\n\n        if (wShowTranslation) {\n            # Display: major translation & phonetics\n            if (r) r = r RS RS\n            r = r m(\"-- display major translation\")\n            r = r prettify(\"translation\", s(translation, tl))\n            if (wShowTranslationPhonetics)\n                r = r RS prettify(\"translation-phonetics\", showPhonetics(join(phonetics, \" \"), tl))\n        }\n\n        if (wShowLanguages) {\n            # Display: source language -> target language\n            if (r) r = r RS RS\n            r = r m(\"-- display source language -> target language\")\n            temp = Option[\"fmt-languages\"]\n            if (!temp) temp = \"[ %s -> %t ]\"\n            split(temp, group, /(%s|%S|%t|%T)/)\n            r = r prettify(\"languages\", group[1])\n            if (temp ~ /%s/)\n                r = r prettify(\"languages-sl\", getDisplay(il))\n            if (temp ~ /%S/)\n                r = r prettify(\"languages-sl\", getName(il))\n            r = r prettify(\"languages\", group[2])\n            if (temp ~ /%t/)\n                r = r prettify(\"languages-tl\", getDisplay(tl))\n            if (temp ~ /%T/)\n                r = r prettify(\"languages-tl\", getName(tl))\n            r = r prettify(\"languages\", group[3])\n        }\n\n        if (wShowDictionary && false) { # FIXME!\n            # Dictionary API\n            dicContent = yandexGetDictionaryResponse(text, il, _tl, _hl)\n            tokenize(dicTokens, dicContent)\n            parseJson(dicAst, dicTokens)\n\n            if (anything(dicAst)) {\n                # Display: dictionary entries\n                if (r) r = r RS\n                r = r m(\"-- display dictionary entries\")\n\n                saveSortedIn = PROCINFO[\"sorted_in\"]\n                PROCINFO[\"sorted_in\"] = \"@ind_num_asc\"\n                for (i in dicAst) {\n                    if (i ~ \"^0\" SUBSEP \"def\" SUBSEP \"[[:digit:]]+\" SUBSEP \\\n                        \"pos$\") {\n                        r = r RS prettify(\"dictionary-word-class\", s((literal(dicAst[i])), hl))\n                        syn = mean = \"\"\n                    }\n\n                    # TODO: ex, gen, ...\n\n                    if (i ~ \"^0\" SUBSEP \"def\" SUBSEP \"[[:digit:]]+\" SUBSEP \\\n                        \"tr\" SUBSEP \"[[:digit:]]+\" SUBSEP               \\\n                        \"mean\" SUBSEP \"[[:digit:]]+\" SUBSEP \"text\") {\n                        if (mean) {\n                            mean = mean prettify(\"dictionary-explanation\", \", \") \\\n                                prettify(\"dictionary-explanation-item\", s((literal(dicAst[i])), sl))\n                        } else {\n                            mean = prettify(\"dictionary-explanation-item\", s((literal(dicAst[i])), sl))\n                        }\n                    }\n\n                    if (i ~ \"^0\" SUBSEP \"def\" SUBSEP \"[[:digit:]]+\" SUBSEP \\\n                        \"tr\" SUBSEP \"[[:digit:]]+\" SUBSEP               \\\n                        \"syn\" SUBSEP \"[[:digit:]]+\" SUBSEP \"text\") {\n                        if (syn) {\n                            syn = syn prettify(\"dictionary-explanation\", \", \") \\\n                                prettify(\"dictionary-word\", s((literal(dicAst[i])), il))\n                        } else {\n                            syn = prettify(\"dictionary-word\", s((literal(dicAst[i])), il))\n                        }\n                    }\n\n                    if (i ~ \"^0\" SUBSEP \"def\" SUBSEP \"[[:digit:]]+\" SUBSEP \\\n                        \"tr\" SUBSEP \"[[:digit:]]+\" SUBSEP \"text$\") {\n                        text = prettify(\"dictionary-word\", s((literal(dicAst[i])), il))\n                        if (syn) {\n                            r = r RS ins(1, text prettify(\"dictionary-explanation\", \", \") syn)\n                        } else {\n                            r = r RS ins(1, text)\n                        }\n                        r = r RS ins(2, mean)\n                        syn = mean = \"\"\n                    }\n                }\n                PROCINFO[\"sorted_in\"] = saveSortedIn\n            }\n        }\n    }\n\n    if (toSpeech) {\n        returnPlaylist[0][\"text\"] = translation\n        returnPlaylist[0][\"tl\"] = _tl\n    }\n\n    return r\n}\n"
  },
  {
    "path": "include/Translators/_.awk",
    "content": "@include \"include/Translators/GoogleTranslate.awk\"\n@include \"include/Translators/BingTranslator.awk\"\n@include \"include/Translators/YandexTranslate.awk\"\n@include \"include/Translators/Apertium.awk\"\n@include \"include/Translators/SpellChecker.awk\"\n@include \"include/Translators/Auto.awk\"\n"
  },
  {
    "path": "include/Utils.awk",
    "content": "####################################################################\n# Utils.awk                                                        #\n####################################################################\n\n# Detect gawk version.\nfunction initGawk(    group) {\n    Gawk = \"gawk\"\n    GawkVersion = PROCINFO[\"version\"]\n\n    split(PROCINFO[\"version\"], group, \".\")\n    if (group[1] < 4) {\n        e(\"[ERROR] Oops! Your gawk (version \" GawkVersion \") \"          \\\n          \"appears to be too old.\\n\"                                    \\\n          \"        You need at least gawk 4.0.0 to run this program.\")\n        exit 1\n    }\n}\n\n# Detect whether the terminal emulator implements its own BiDi support.\n# NOTE: not working inside an SSH session!\nfunction initBiDiTerm() {\n    if (ENVIRON[\"MLTERM\"])\n        BiDiTerm = \"mlterm\"\n    else if (ENVIRON[\"KONSOLE_VERSION\"])\n        BiDiTerm = \"konsole\"\n    else if (ENVIRON[\"VTE_VERSION\"])\n        if (int(ENVIRON[\"VTE_VERSION\"]) >= 5703)\n            BiDiTerm = \"vte\"\n}\n\n# Detect external bidirectional algorithm utility (fribidi);\n# Fallback to Unix `rev` if not found.\nfunction initBiDi() {\n    FriBidi = detectProgram(\"fribidi\", \"--version\", 1)\n    BiDiNoPad = FriBidi ? \"fribidi --nopad\" : \"rev\" SUPERR\n    BiDi = FriBidi ? \"fribidi --width %s\" :\n        \"rev\" SUPERR \"| sed \\\"s/'/\\\\\\\\\\\\'/\\\" | xargs -0 printf '%%%ss'\"\n}\n\n# Detect external readline wrapper (rlwrap).\nfunction initRlwrap() {\n    Rlwrap = detectProgram(\"rlwrap\", \"--version\")\n}\n\n# Detect emacs.\nfunction initEmacs() {\n    Emacs = detectProgram(\"emacs\", \"--version\")\n}\n\n# Detect curl.\nfunction initCurl() {\n    Curl = detectProgram(\"curl\", \"--version\")\n}\n\n# Log any value if debugging is enabled.\nfunction l(value, name, inline, heredoc, valOnly, numSub, sortedIn) {\n    if (Option[\"debug\"]) {\n        if (name)\n            da(value, name, inline, heredoc, valOnly, numSub, sortedIn)\n        else\n            d(value)\n    }\n}\n\n# Return a log message if debugging is enabled.\nfunction m(string) {\n    if (Option[\"debug\"])\n        return ansi(\"cyan\", string) RS\n}\n\n# Return 1 if the first version is newer than the second; otherwise return 0.\nfunction newerVersion(ver1, ver2,    i, group1, group2) {\n    split(ver1, group1, \".\")\n    split(ver2, group2, \".\")\n    for (i = 1; i <= 4; i++) {\n        if (group1[i] + 0 > group2[i] + 0)\n            return 1\n        else if (group1[i] + 0 < group2[i] + 0)\n            return 0\n    }\n    return 0\n}\n\n# Fork an rlwrap process as the wrapper. Return non-zero if failed,\nfunction rlwrapMe(    i, command) {\n    initRlwrap()\n\n    if (!Rlwrap) {\n        l(\">> not found: rlwrap\")\n        return 1\n    }\n\n    if (ENVIRON[\"TRANS_ENTRY\"]) {\n        command = Rlwrap \" -C trans \" ENVIRON[\"TRANS_ENTRY\"] \" \"        \\\n            parameterize(\"-no-rlwrap\") # never fork rlwrap again!\n    } else if (fileExists(ENVIRON[\"TRANS_DIR\"] \"/\" EntryScript)) {\n        command = Rlwrap \" -C trans \" \" sh \"                            \\\n            parameterize(ENVIRON[\"TRANS_DIR\"] \"/\" EntryScript)          \\\n            \" - \" parameterize(\"-no-rlwrap\") # never fork rlwrap again!\n    } else {\n        l(\">> not found: $TRANS_ENTRY or EntryPoint\")\n        return 1\n    }\n    for (i = 1; i < length(ARGV); i++)\n        if (ARGV[i])\n            command = command \" \" parameterize(ARGV[i])\n\n    l(\">> forking: \" command)\n    if (!system(command)) {\n        l(\">> process exited with code 0\")\n        exit ExitCode\n    } else {\n        l(\">> process exited with non-zero return code\")\n        return 1\n    }\n}\n\n# Fork an emacs process as the front-end. Return non-zero if failed,\nfunction emacsMe(    i, params, el, command) {\n    initEmacs()\n\n    if (!Emacs) {\n        l(\">> not found: emacs\")\n        return 1\n    }\n\n    params = \"\"\n    for (i = 1; i < length(ARGV); i++)\n        if (ARGV[i])\n            params = params \" \" parameterize(ARGV[i], \"\\\"\")\n    if (ENVIRON[\"TRANS_ENTRY\"]) {\n        el = \"(progn (setq explicit-shell-file-name \\\"\" ENVIRON[\"TRANS_ENTRY\"] \"\\\") \" \\\n            \"(setq explicit-\" Command \"-args '(\\\"-I\\\" \\\"-no-rlwrap\\\"\" params \")) \" \\\n            \"(command-execute 'shell) (rename-buffer \\\"\" Name \"\\\"))\"\n    } else if (fileExists(ENVIRON[\"TRANS_DIR\"] \"/\" EntryScript)) {\n        el = \"(progn (setq explicit-shell-file-name \\\"\" \"sh\" \"\\\") \"     \\\n            \"(setq explicit-\" \"sh\" \"-args '(\\\"\" ENVIRON[\"TRANS_DIR\"] \"/\" EntryScript \"\\\" \\\"-I\\\" \\\"-no-rlwrap\\\"\" params \")) \" \\\n            \"(command-execute 'shell) (rename-buffer \\\"\" Name \"\\\"))\"\n    } else {\n        l(\">> not found: $TRANS_ENTRY or EntryPoint\")\n        return 1\n    }\n    command = Emacs \" --eval \" parameterize(el)\n\n    l(\">> forking: \" command)\n    if (!system(command)) {\n        l(\">> process exited with code 0\")\n        exit ExitCode\n    } else {\n        l(\">> process exited with non-zero return code\")\n        return 1\n    }\n}\n\n# Fetch the content of a URL. Return a null string if failed.\nfunction curl(url, output,    command, content, line) {\n    initCurl()\n\n    if (!Curl) {\n        l(\">> not found: curl\")\n        w(\"[WARNING] curl is not found.\")\n        return NULLSTR\n    }\n\n    command = Curl \" --location --silent\"\n    if (Option[\"proxy\"])\n        command = command \" --proxy \" parameterize(Option[\"proxy\"])\n    if (Option[\"user-agent\"])\n        command = command \" --user-agent \" parameterize(Option[\"user-agent\"])\n    command = command \" \" parameterize(url)\n    if (output) {\n        command = command \" --output \" parameterize(output)\n        system(command)\n        return NULLSTR\n    }\n    content = NULLSTR\n    while ((command |& getline line) > 0)\n        content = (content ? content \"\\n\" : NULLSTR) line\n    close(command)\n    return content\n}\n\n# Fetch the content of a URL. Return a null string if failed.\nfunction curlPost(url, data, output,    command, content, line) {\n    initCurl()\n\n    if (!Curl) {\n        l(\">> not found: curl\")\n        w(\"[WARNING] curl is not found.\")\n        return NULLSTR\n    }\n\n    command = Curl \" --location --silent\"\n    if (Option[\"proxy\"])\n        command = command \" --proxy \" parameterize(Option[\"proxy\"])\n    if (Option[\"user-agent\"])\n        command = command \" --user-agent \" parameterize(Option[\"user-agent\"])\n    command = command \" --request POST --data \" parameterize(data)\n    command = command \" \" parameterize(url)\n    if (output) {\n        command = command \" --output \" parameterize(output)\n        system(command)\n        return NULLSTR\n    }\n    content = NULLSTR\n    while ((command |& getline line) > 0)\n        content = (content ? content \"\\n\" : NULLSTR) line\n    close(command)\n    return content\n}\n\n# Dump a Unicode string into a byte array. Return the length of the array.\nfunction dump(text, group,    command, temp) {\n    # hexdump tricks:\n    # (1) use -v (--no-squeezing)\n    # (2) use \"%u\" (unsigned integers)\n    command = \"hexdump\" \" -v -e'1/1 \\\"%03u\\\" \\\" \\\"'\"\n    command = \"echo \" parameterize(text) PIPE command\n    command | getline temp\n    split(temp, group, \" \")\n    close(command)\n    return length(group) - 1\n}\n\n# Dump a Unicode string into a byte array (hexadecimal). Return the length of the array.\nfunction dumpX(text, group,    command, temp) {\n    command = \"hexdump\" \" -v -e'1/1 \\\"%02X\\\" \\\" \\\"'\"\n    command = \"echo \" parameterize(text) PIPE command\n    command | getline temp\n    split(temp, group, \" \")\n    close(command)\n    return length(group) - 1\n}\n\n# Base64 encode a string.\nfunction base64(text,    command, temp) {\n    if (detectProgram(\"uname\", \"-s\", 1) == \"Linux\") # GNU base64 wraps lines by default\n        command = \"echo -n \" parameterize(text) PIPE \"base64 -w0\"\n    else\n        command = \"echo -n \" parameterize(text) PIPE \"base64\"\n    command = \"bash -c \" parameterize(command, \"\\\"\")\n    command | getline temp\n    close(command)\n    return temp\n}\n\n# Print a Unicode-escaped string. (requires GNU Bash)\nfunction uprintf(text,    command, temp) {\n    command = \"echo -en \" parameterize(text)\n    command = \"bash -c \" parameterize(command, \"\\\"\")\n    command | getline temp\n    close(command)\n    return temp\n}\n"
  },
  {
    "path": "man/trans.1",
    "content": ".\\\" Automatically generated by Pandoc 2.5\n.\\\"\n.TH \"TRANS\" \"1\" \"2023\\-02\\-08\" \"0.9.7.1\" \"\"\n.hy\n.SH NAME\n.PP\ntrans \\- Command\\-line translator using Google Translate, Bing\nTranslator, Yandex.Translate, etc.\n.SH SYNOPSIS\n.PP\n\\f[B]trans\\f[R] [\\f[I]OPTIONS\\f[R]]\n[\\f[I]SOURCE\\f[R]]:[\\f[I]TARGETS\\f[R]] [\\f[I]TEXT\\f[R]]...\n.SH DESCRIPTION\n.PP\nThis tool translates text into any language from the command\\-line,\nusing a translation engine such as Google Translate, Bing Translator and\nYandex.Translate.\n.PP\nEach argument which is not a valid option is treated as \\f[I]TEXT\\f[R]\nto be translated.\n.PP\nIf neither \\f[I]TEXT\\f[R] nor the input file is specified by\ncommand\\-line arguments, the program will read and translate from\nstandard input.\n.SH OPTIONS\n.SS Information options\n.TP\n.B \\f[B]\\-V\\f[R], \\f[B]\\-version\\f[R]\nPrint version and exit.\n.TP\n.B \\f[B]\\-H\\f[R], \\f[B]\\-help\\f[R]\nPrint help message and exit.\n.TP\n.B \\f[B]\\-M\\f[R], \\f[B]\\-man\\f[R]\nShow man page and exit.\n.TP\n.B \\f[B]\\-T\\f[R], \\f[B]\\-reference\\f[R]\nPrint reference table of all supported languages and codes, and exit.\nNames of languages are displayed in their endonyms (language name in the\nlanguage itself).\n.TP\n.B \\f[B]\\-R\\f[R], \\f[B]\\-reference\\-english\\f[R]\nPrint reference table of all supported languages and codes, and exit.\nNames of languages are displayed in English.\n.TP\n.B \\f[B]\\-S\\f[R], \\f[B]\\-list\\-engines\\f[R]\nList available translation engines and exit.\n.TP\n.B \\f[B]\\-list\\-languages\\f[R]\nList all supported languages (in endonyms) and exit.\n.TP\n.B \\f[B]\\-list\\-languages\\-english\\f[R]\nList all supported languages (in English names) and exit.\n.TP\n.B \\f[B]\\-list\\-codes\\f[R]\nList all supported codes and exit.\n.TP\n.B \\f[B]\\-list\\-all\\f[R]\nList all supported languages (endonyms and English names) and codes, and\nexit.\n.TP\n.B \\f[B]\\-L\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-linguist\\f[R] \\f[I]CODES\\f[R]\nPrint details of languages and exit.\nWhen specifying two or more language codes, concatenate them by plus\nsign \\[dq]+\\[dq].\n.TP\n.B \\f[B]\\-U\\f[R], \\f[B]\\-upgrade\\f[R]\nCheck for upgrade of this program.\n.SS Translator options\n.TP\n.B \\f[B]\\-e\\f[R] \\f[I]ENGINE\\f[R], \\f[B]\\-engine\\f[R] \\f[I]ENGINE\\f[R]\nSpecify the translation engine to use.\n(default: auto)\n.SS Display options\n.TP\n.B \\f[B]\\-verbose\\f[R]\nVerbose mode.\n.RS\n.PP\nShow the original text and its most relevant translation, then its\nphonetic notation (if any), then its alternative translations (if any)\nor its definition in the dictionary (if it is a word).\n.PP\nThis option is unnecessary in most cases since verbose mode is enabled\nby default.\n.RE\n.TP\n.B \\f[B]\\-b\\f[R], \\f[B]\\-brief\\f[R]\nBrief mode.\n.RS\n.PP\nShow the most relevant translation or its phonetic notation only.\n.RE\n.TP\n.B \\f[B]\\-d\\f[R], \\f[B]\\-dictionary\\f[R]\nDictionary mode.\n.RS\n.PP\nShow the definition of the original word in the dictionary.\n.RE\n.TP\n.B \\f[B]\\-identify\\f[R]\nLanguage identification.\n.RS\n.PP\nShow the identified language of the original text.\n.RE\n.TP\n.B \\f[B]\\-show\\-original\\f[R] \\f[I]Y/n\\f[R]\nShow original text or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-original\\-phonetics\\f[R] \\f[I]Y/n\\f[R]\nShow phonetic notation of original text or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-translation\\f[R] \\f[I]Y/n\\f[R]\nShow translation or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-translation\\-phonetics\\f[R] \\f[I]Y/n\\f[R]\nShow phonetic notation of translation or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-prompt\\-message\\f[R] \\f[I]Y/n\\f[R]\nShow prompt message or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-languages\\f[R] \\f[I]Y/n\\f[R]\nShow source and target languages or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-original\\-dictionary\\f[R] \\f[I]y/N\\f[R]\nShow dictionary entry of original text or not.\n(default: no)\n.RS\n.PP\nThis option is enabled in dictionary mode.\n.RE\n.TP\n.B \\f[B]\\-show\\-dictionary\\f[R] \\f[I]Y/n\\f[R]\nShow dictionary entry of translation or not.\n(default: yes)\n.TP\n.B \\f[B]\\-show\\-alternatives\\f[R] \\f[I]Y/n\\f[R]\nShow alternative translations or not.\n(default: yes)\n.TP\n.B \\f[B]\\-w\\f[R] \\f[I]NUM\\f[R], \\f[B]\\-width\\f[R] \\f[I]NUM\\f[R]\nSpecify the screen width for padding.\n.RS\n.PP\nThis option overrides the setting of environment variable\n$\\f[B]COLUMNS\\f[R].\n.RE\n.TP\n.B \\f[B]\\-indent\\f[R] \\f[I]NUM\\f[R]\nSpecify the size of indent (number of spaces).\n(default: 4)\n.TP\n.B \\f[B]\\-theme\\f[R] \\f[I]FILENAME\\f[R]\nSpecify the theme to use.\n(default: default)\n.TP\n.B \\f[B]\\-no\\-theme\\f[R]\nDo not use any other theme than default.\n.TP\n.B \\f[B]\\-no\\-ansi\\f[R]\nDo not use ANSI escape codes.\n.TP\n.B \\f[B]\\-no\\-autocorrect\\f[R]\nDo not autocorrect.\n(if defaulted by the translation engine)\n.TP\n.B \\f[B]\\-no\\-bidi\\f[R]\nDo not convert bidirectional texts.\n.TP\n.B \\f[B]\\-bidi\\f[R]\nAlways convert bidirectional texts.\n.TP\n.B \\f[B]\\-no\\-warn\\f[R]\nDo not write warning messages to stderr.\n.TP\n.B \\f[B]\\-dump\\f[R]\nPrint raw API response instead.\n.SS Audio options\n.TP\n.B \\f[B]\\-p\\f[R], \\f[B]\\-play\\f[R]\nListen to the translation.\n.RS\n.PP\nYou must have at least one of the supported audio players\n(\\f[B]mplayer\\f[R], \\f[B]mpv\\f[R] or \\f[B]mpg123\\f[R]) installed to\nstream from Google Text\\-to\\-Speech engine.\nOtherwise, a local speech synthesizer may be used instead (\\f[B]say\\f[R]\non macOS, \\f[B]espeak\\f[R] on Linux or other platforms).\n.RE\n.TP\n.B \\f[B]\\-speak\\f[R]\nListen to the original text.\n.TP\n.B \\f[B]\\-n\\f[R] \\f[I]VOICE\\f[R], \\f[B]\\-narrator\\f[R] \\f[I]VOICE\\f[R]\nSpecify the narrator, and listen to the translation.\n.RS\n.PP\nCommon values for this option are \\f[B]male\\f[R] and \\f[B]female\\f[R].\n.RE\n.TP\n.B \\f[B]\\-player\\f[R] \\f[I]PROGRAM\\f[R]\nSpecify the audio player to use, and listen to the translation.\n.RS\n.PP\nOption \\f[B]\\-play\\f[R] will try to use \\f[B]mplayer\\f[R], \\f[B]mpv\\f[R]\nor \\f[B]mpg123\\f[R] by default, since these players are known to work\nfor streaming URLs.\nNot all command\\-line audio players can work this way.\nUse this option only when you have your own preference.\n.PP\nThis option overrides the setting of environment variable\n$\\f[B]PLAYER\\f[R].\n.RE\n.TP\n.B \\f[B]\\-no\\-play\\f[R]\nDo not listen to the translation.\n.TP\n.B \\f[B]\\-no\\-translate\\f[R]\nDo not translate anything when using \\-speak.\n.TP\n.B \\f[B]\\-download\\-audio\\f[R]\nDownload the audio to the current directory.\n.TP\n.B \\f[B]\\-download\\-audio\\-as\\f[R] \\f[I]FILENAME\\f[R]\nDownload the audio to the specified file.\n.SS Terminal paging and browsing options\n.TP\n.B \\f[B]\\-v\\f[R], \\f[B]\\-view\\f[R]\nView the translation in a terminal pager (\\f[B]less\\f[R], \\f[B]more\\f[R]\nor \\f[B]most\\f[R]).\n.TP\n.B \\f[B]\\-pager\\f[R] \\f[I]PROGRAM\\f[R]\nSpecify the terminal pager to use, and view the translation.\n.RS\n.PP\nThis option overrides the setting of environment variable\n$\\f[B]PAGER\\f[R].\n.RE\n.TP\n.B \\f[B]\\-no\\-view\\f[R], \\f[B]\\-no\\-pager\\f[R]\nDo not view the translation in a terminal pager.\n.TP\n.B \\f[B]\\-browser\\f[R] \\f[I]PROGRAM\\f[R]\nSpecify the web browser to use.\n.RS\n.PP\nThis option overrides the setting of environment variable\n$\\f[B]BROWSER\\f[R].\n.RE\n.TP\n.B \\f[B]\\-no\\-browser\\f[R]\nDo not open the web browser.\n.SS Networking options\n.TP\n.B \\f[B]\\-x\\f[R] \\f[I]HOST:PORT\\f[R], \\f[B]\\-proxy\\f[R] \\f[I]HOST:PORT\\f[R]\nUse HTTP proxy on given port.\n.RS\n.PP\nThis option overrides the setting of environment variables\n$\\f[B]HTTP_PROXY\\f[R] and $\\f[B]http_proxy\\f[R].\n.RE\n.TP\n.B \\f[B]\\-u\\f[R] \\f[I]STRING\\f[R], \\f[B]\\-user\\-agent\\f[R] \\f[I]STRING\\f[R]\nSpecify the User\\-Agent to identify as.\n.RS\n.PP\nThis option overrides the setting of environment variables\n$\\f[B]USER_AGENT\\f[R].\n.RE\n.TP\n.B \\f[B]\\-4\\f[R], \\f[B]\\-ipv4\\f[R], \\f[B]\\-inet4\\-only\\f[R]\nConnect only to IPv4 addresses.\n.TP\n.B \\f[B]\\-6\\f[R], \\f[B]\\-ipv6\\f[R], \\f[B]\\-inet6\\-only\\f[R]\nConnect only to IPv6 addresses.\n.SS Interactive shell options\n.TP\n.B \\f[B]\\-I\\f[R], \\f[B]\\-interactive\\f[R], \\f[B]\\-shell\\f[R]\nStart an interactive shell, invoking \\f[B]rlwrap\\f[R] whenever possible\n(unless \\f[B]\\-no\\-rlwrap\\f[R] is specified).\n.TP\n.B \\f[B]\\-E\\f[R], \\f[B]\\-emacs\\f[R]\nStart the GNU Emacs front\\-end for an interactive shell.\n.RS\n.PP\nThis option does not need to, and cannot be used along with\n\\f[B]\\-I\\f[R] or \\f[B]\\-no\\-rlwrap\\f[R].\n.RE\n.TP\n.B \\f[B]\\-no\\-rlwrap\\f[R]\nDo not invoke \\f[B]rlwrap\\f[R] when starting an interactive shell.\n.RS\n.PP\nThis option is useful when your terminal type is not supported by\n\\f[B]rlwrap\\f[R] (e.g.\n\\f[B]emacs\\f[R]).\n.RE\n.SS I/O options\n.TP\n.B \\f[B]\\-i\\f[R] \\f[I]FILENAME\\f[R], \\f[B]\\-input\\f[R] \\f[I]FILENAME\\f[R]\nSpecify the input file.\n.RS\n.PP\nSource text to be translated will be read from the input file, instead\nof standard input.\n.RE\n.TP\n.B \\f[B]\\-o\\f[R] \\f[I]FILENAME\\f[R], \\f[B]\\-output\\f[R] \\f[I]FILENAME\\f[R]\nSpecify the output file.\n.RS\n.PP\nTranslations will be written to the output file, instead of standard\noutput.\n.RE\n.SS Language preference options\n.TP\n.B \\f[B]\\-hl\\f[R] \\f[I]CODE\\f[R], \\f[B]\\-host\\f[R] \\f[I]CODE\\f[R]\nSpecify your home language (the language you would like to see for\ndisplaying prompt messages in the translation).\n.RS\n.PP\nThis option affects only the display in verbose mode (anything other\nthan source language and target language will be displayed in your home\nlanguage).\nThis option has no effect in brief mode.\n.PP\nThis option is optional.\nWhen its setting is omitted, English will be used.\n.PP\nThis option overrides the setting of environment variables\n$\\f[B]LC_ALL\\f[R], $\\f[B]LANG\\f[R], and $\\f[B]HOST_LANG\\f[R].\n.RE\n.TP\n.B \\f[B]\\-s\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-sl\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-source\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-from\\f[R] \\f[I]CODES\\f[R]\nSpecify the source language(s) (the language(s) of original text).\nWhen specifying two or more language codes, concatenate them by plus\nsign \\[dq]+\\[dq].\n.RS\n.PP\nThis option is optional.\nWhen its setting is omitted, the language of original text will be\nidentified automatically (with a possibility of misidentification).\n.PP\nThis option overrides the setting of environment variable\n$\\f[B]SOURCE_LANG\\f[R].\n.RE\n.TP\n.B \\f[B]\\-t\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-tl\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-target\\f[R] \\f[I]CODES\\f[R], \\f[B]\\-to\\f[R] \\f[I]CODES\\f[R]\nSpecify the target language(s) (the language(s) of translated text).\nWhen specifying two or more language codes, concatenate them by plus\nsign \\[dq]+\\[dq].\n.RS\n.PP\nThis option is optional.\nWhen its setting is omitted, everything will be translated into English.\n.PP\nThis option overrides the setting of environment variables\n$\\f[B]LC_ALL\\f[R], $\\f[B]LANG\\f[R], and $\\f[B]TARGET_LANG\\f[R].\n.RE\n.TP\n.B [\\f[I]SOURCE\\f[R]]:[\\f[I]TARGETS\\f[R]]\nA simpler, alternative way to specify the source language and target\nlanguage(s) is to use a shortcut formatted string:\n.RS\n.IP \\[bu] 2\n\\f[I]SOURCE\\-CODE\\f[R]:\\f[I]TARGET\\-CODE\\f[R]\n.IP \\[bu] 2\n\\f[I]SOURCE\\-CODE\\f[R]:\\f[I]TARGET\\-CODE1\\f[R]+\\f[I]TARGET\\-CODE2\\f[R]+...\n.IP \\[bu] 2\n\\f[I]SOURCE\\-CODE\\f[R]=\\f[I]TARGET\\-CODE\\f[R]\n.IP \\[bu] 2\n\\f[I]SOURCE\\-CODE\\f[R]=\\f[I]TARGET\\-CODE1\\f[R]+\\f[I]TARGET\\-CODE2\\f[R]+...\n.PP\nDelimiter \\[dq]:\\[dq] and \\[dq]=\\[dq] can be used interchangeably.\n.PP\nEither \\f[I]SOURCE\\f[R] or \\f[I]TARGETS\\f[R] may be omitted, but the\ndelimiter character must be kept.\n.RE\n.SS Text preprocessing options\n.TP\n.B \\f[B]\\-j\\f[R], \\f[B]\\-join\\-sentence\\f[R]\nTreat all arguments as one single sentence.\n.SS Other options\n.TP\n.B \\f[B]\\-no\\-init\\f[R]\nDo not load any initialization script.\n.TP\n.B \\f[B]\\-\\-\\f[R]\nEnd\\-of\\-options.\n.RS\n.PP\nAll arguments after this option are treated as \\f[I]TEXT\\f[R] to be\ntranslated.\n.RE\n.SH EXIT STATUS\n.TP\n.B \\f[B]0\\f[R]\nSuccessful translation.\n.TP\n.B \\f[B]1\\f[R]\nError.\n.SH ENVIRONMENT\n.TP\n.B \\f[B]PAGER\\f[R]\nEquivalent to option setting \\f[B]\\-pager\\f[R].\n.TP\n.B \\f[B]BROWSER\\f[R]\nEquivalent to option setting \\f[B]\\-browser\\f[R].\n.TP\n.B \\f[B]PLAYER\\f[R]\nEquivalent to option setting \\f[B]\\-player\\f[R].\n.TP\n.B \\f[B]HTTP_PROXY\\f[R]\nEquivalent to option setting \\f[B]\\-proxy\\f[R].\n.TP\n.B \\f[B]USER_AGENT\\f[R]\nEquivalent to option setting \\f[B]\\-user\\-agent\\f[R].\n.TP\n.B \\f[B]HOST_LANG\\f[R]\nEquivalent to option setting \\f[B]\\-host\\f[R].\n.TP\n.B \\f[B]SOURCE_LANG\\f[R]\nEquivalent to option setting \\f[B]\\-source\\f[R].\n.TP\n.B \\f[B]TARGET_LANG\\f[R]\nEquivalent to option setting \\f[B]\\-target\\f[R].\n.SH FILES\n.TP\n.B \\f[I]/etc/translate\\-shell\\f[R]\nInitialization script.\n(system\\-wide)\n.TP\n.B \\f[I]$HOME/.translate\\-shell/init.trans\\f[R]\nInitialization script.\n(user\\-specific)\n.TP\n.B \\f[I]$XDG_CONFIG_HOME/translate\\-shell/init.trans\\f[R]\nInitialization script.\n(user\\-specific)\n.TP\n.B \\f[I]./.trans\\f[R]\nInitialization script.\n(current directory)\n.SH FURTHER DOCUMENTATION\n.PP\n<https://github.com/soimort/translate-shell/wiki>\n.SH REPORTING BUGS\n.PP\n<https://github.com/soimort/translate-shell/issues>\n.SH AUTHORS\nMort Yao <soi@mort.ninja>.\n"
  },
  {
    "path": "man/trans.1.md",
    "content": "% TRANS(1) 0.9.7.1\n% Mort Yao <soi@mort.ninja>\n% 2023-02-08\n\n# NAME\n\ntrans - Command-line translator using Google Translate, Bing Translator, Yandex.Translate, etc.\n\n# SYNOPSIS\n\n**trans** [*OPTIONS*] [*SOURCE*]:[*TARGETS*] [*TEXT*]...\n\n# DESCRIPTION\n\nThis tool translates text into any language from the command-line, using a translation engine such as Google Translate, Bing Translator and Yandex.Translate.\n\nEach argument which is not a valid option is treated as *TEXT* to be translated.\n\nIf neither *TEXT* nor the input file is specified by command-line arguments, the program will read and translate from standard input.\n\n# OPTIONS\n\n## Information options\n\n**-V**, **-version**\n:   Print version and exit.\n\n**-H**, **-help**\n:   Print help message and exit.\n\n**-M**, **-man**\n:   Show man page and exit.\n\n**-T**, **-reference**\n:   Print reference table of all supported languages and codes, and exit. Names of languages are displayed in their endonyms (language name in the language itself).\n\n**-R**, **-reference-english**\n:   Print reference table of all supported languages and codes, and exit. Names of languages are displayed in English.\n\n**-S**, **-list-engines**\n:   List available translation engines and exit.\n\n**-list-languages**\n:   List all supported languages (in endonyms) and exit.\n\n**-list-languages-english**\n:   List all supported languages (in English names) and exit.\n\n**-list-codes**\n:   List all supported codes and exit.\n\n**-list-all**\n:   List all supported languages (endonyms and English names) and codes, and exit.\n\n**-L** *CODES*, **-linguist** *CODES*\n:   Print details of languages and exit. When specifying two or more language codes, concatenate them by plus sign \"+\".\n\n**-U**, **-upgrade**\n:   Check for upgrade of this program.\n\n## Translator options\n\n**-e** *ENGINE*, **-engine** *ENGINE*\n:   Specify the translation engine to use. (default: auto)\n\n## Display options\n\n**-verbose**\n:   Verbose mode.\n\n    Show the original text and its most relevant translation, then its phonetic notation (if any), then its alternative translations (if any) or its definition in the dictionary (if it is a word).\n\n    This option is unnecessary in most cases since verbose mode is enabled by default.\n\n**-b**, **-brief**\n:   Brief mode.\n\n    Show the most relevant translation or its phonetic notation only.\n\n**-d**, **-dictionary**\n:   Dictionary mode.\n\n    Show the definition of the original word in the dictionary.\n\n**-identify**\n:   Language identification.\n\n    Show the identified language of the original text.\n\n**-show-original** *Y/n*\n:   Show original text or not. (default: yes)\n\n**-show-original-phonetics** *Y/n*\n:   Show phonetic notation of original text or not. (default: yes)\n\n**-show-translation** *Y/n*\n:   Show translation or not. (default: yes)\n\n**-show-translation-phonetics** *Y/n*\n:   Show phonetic notation of translation or not. (default: yes)\n\n**-show-prompt-message** *Y/n*\n:   Show prompt message or not. (default: yes)\n\n**-show-languages** *Y/n*\n:   Show source and target languages or not. (default: yes)\n\n**-show-original-dictionary** *y/N*\n:   Show dictionary entry of original text or not. (default: no)\n\n    This option is enabled in dictionary mode.\n\n**-show-dictionary** *Y/n*\n:   Show dictionary entry of translation or not. (default: yes)\n\n**-show-alternatives** *Y/n*\n:   Show alternative translations or not. (default: yes)\n\n**-w** *NUM*, **-width** *NUM*\n:   Specify the screen width for padding.\n\n    This option overrides the setting of environment variable $**COLUMNS**.\n\n**-indent** *NUM*\n:   Specify the size of indent (number of spaces). (default: 4)\n\n**-theme** *FILENAME*\n:   Specify the theme to use. (default: default)\n\n**-no-theme**\n:   Do not use any other theme than default.\n\n**-no-ansi**\n:   Do not use ANSI escape codes.\n\n**-no-autocorrect**\n:   Do not autocorrect. (if defaulted by the translation engine)\n\n**-no-bidi**\n:   Do not convert bidirectional texts.\n\n**-bidi**\n:   Always convert bidirectional texts.\n\n**-no-warn**\n:   Do not write warning messages to stderr.\n\n**-dump**\n:   Print raw API response instead.\n\n## Audio options\n\n**-p**, **-play**\n:   Listen to the translation.\n\n    You must have at least one of the supported audio players (**mplayer**, **mpv** or **mpg123**) installed to stream from Google Text-to-Speech engine. Otherwise, a local speech synthesizer may be used instead (**say** on macOS, **espeak** on Linux or other platforms).\n\n**-speak**\n:   Listen to the original text.\n\n**-n** *VOICE*, **-narrator** *VOICE*\n:   Specify the narrator, and listen to the translation.\n\n    Common values for this option are **male** and **female**.\n\n**-player** *PROGRAM*\n:   Specify the audio player to use, and listen to the translation.\n\n    Option **-play** will try to use **mplayer**, **mpv** or **mpg123** by default, since these players are known to work for streaming URLs. Not all command-line audio players can work this way. Use this option only when you have your own preference.\n\n    This option overrides the setting of environment variable $**PLAYER**.\n\n**-no-play**\n:   Do not listen to the translation.\n\n**-no-translate**\n:   Do not translate anything when using -speak.\n\n**-download-audio**\n:   Download the audio to the current directory.\n\n**-download-audio-as** *FILENAME*\n:   Download the audio to the specified file.\n\n## Terminal paging and browsing options\n\n**-v**, **-view**\n:   View the translation in a terminal pager (**less**, **more** or **most**).\n\n**-pager** *PROGRAM*\n:   Specify the terminal pager to use, and view the translation.\n\n    This option overrides the setting of environment variable $**PAGER**.\n\n**-no-view**, **-no-pager**\n:   Do not view the translation in a terminal pager.\n\n**-browser** *PROGRAM*\n:   Specify the web browser to use.\n\n    This option overrides the setting of environment variable $**BROWSER**.\n\n**-no-browser**\n:   Do not open the web browser.\n\n## Networking options\n\n**-x** *HOST:PORT*, **-proxy** *HOST:PORT*\n:   Use HTTP proxy on given port.\n\n    This option overrides the setting of environment variables $**HTTP_PROXY** and $**http_proxy**.\n\n**-u** *STRING*, **-user-agent** *STRING*\n:   Specify the User-Agent to identify as.\n\n    This option overrides the setting of environment variables $**USER_AGENT**.\n\n**-4**, **-ipv4**, **-inet4-only**\n:   Connect only to IPv4 addresses.\n\n**-6**, **-ipv6**, **-inet6-only**\n:   Connect only to IPv6 addresses.\n\n## Interactive shell options\n\n**-I**, **-interactive**, **-shell**\n:   Start an interactive shell, invoking **rlwrap** whenever possible (unless **-no-rlwrap** is specified).\n\n**-E**, **-emacs**\n:   Start the GNU Emacs front-end for an interactive shell.\n\n    This option does not need to, and cannot be used along with **-I** or **-no-rlwrap**.\n\n**-no-rlwrap**\n:   Do not invoke **rlwrap** when starting an interactive shell.\n\n    This option is useful when your terminal type is not supported by **rlwrap** (e.g. **emacs**).\n\n## I/O options\n\n**-i** *FILENAME*, **-input** *FILENAME*\n:   Specify the input file.\n\n    Source text to be translated will be read from the input file, instead of standard input.\n\n**-o** *FILENAME*, **-output** *FILENAME*\n:   Specify the output file.\n\n    Translations will be written to the output file, instead of standard output.\n\n## Language preference options\n\n**-hl** *CODE*, **-host** *CODE*\n:   Specify your home language (the language you would like to see for displaying prompt messages in the translation).\n\n    This option affects only the display in verbose mode (anything other than source language and target language will be displayed in your home language). This option has no effect in brief mode.\n\n    This option is optional. When its setting is omitted, English will be used.\n\n    This option overrides the setting of environment variables $**LC_ALL**, $**LANG**, and $**HOST_LANG**.\n\n**-s** *CODES*, **-sl** *CODES*, **-source** *CODES*, **-from** *CODES*\n:   Specify the source language(s) (the language(s) of original text). When specifying two or more language codes, concatenate them by plus sign \"+\".\n\n    This option is optional. When its setting is omitted, the language of original text will be identified automatically (with a possibility of misidentification).\n\n    This option overrides the setting of environment variable $**SOURCE_LANG**.\n\n**-t** *CODES*, **-tl** *CODES*, **-target** *CODES*, **-to** *CODES*\n:   Specify the target language(s) (the language(s) of translated text). When specifying two or more language codes, concatenate them by plus sign \"+\".\n\n    This option is optional. When its setting is omitted, everything will be translated into English.\n\n    This option overrides the setting of environment variables $**LC_ALL**, $**LANG**, and $**TARGET_LANG**.\n\n[*SOURCE*]:[*TARGETS*]\n:   A simpler, alternative way to specify the source language and target language(s) is to use a shortcut formatted string:\n\n    * *SOURCE-CODE*:*TARGET-CODE*\n    * *SOURCE-CODE*:*TARGET-CODE1*+*TARGET-CODE2*+...\n    * *SOURCE-CODE*=*TARGET-CODE*\n    * *SOURCE-CODE*=*TARGET-CODE1*+*TARGET-CODE2*+...\n\n    Delimiter \":\" and \"=\" can be used interchangeably.\n\n    Either *SOURCE* or *TARGETS* may be omitted, but the delimiter character must be kept.\n\n## Text preprocessing options\n\n**-j**, **-join-sentence**\n:   Treat all arguments as one single sentence.\n\n## Other options\n\n**-no-init**\n:   Do not load any initialization script.\n\n**--**\n:   End-of-options.\n\n    All arguments after this option are treated as *TEXT* to be translated.\n\n# EXIT STATUS\n\n**0**\n:   Successful translation.\n\n**1**\n:   Error.\n\n# ENVIRONMENT\n\n**PAGER**\n:   Equivalent to option setting **-pager**.\n\n**BROWSER**\n:   Equivalent to option setting **-browser**.\n\n**PLAYER**\n:   Equivalent to option setting **-player**.\n\n**HTTP_PROXY**\n:   Equivalent to option setting **-proxy**.\n\n**USER_AGENT**\n:   Equivalent to option setting **-user-agent**.\n\n**HOST_LANG**\n:   Equivalent to option setting **-host**.\n\n**SOURCE_LANG**\n:   Equivalent to option setting **-source**.\n\n**TARGET_LANG**\n:   Equivalent to option setting **-target**.\n\n# FILES\n\n*/etc/translate-shell*\n:   Initialization script. (system-wide)\n\n*$HOME/.translate-shell/init.trans*\n:   Initialization script. (user-specific)\n\n*$XDG_CONFIG_HOME/translate-shell/init.trans*\n:   Initialization script. (user-specific)\n\n*./.trans*\n:   Initialization script. (current directory)\n\n# FURTHER DOCUMENTATION\n\n<https://github.com/soimort/translate-shell/wiki>\n\n# REPORTING BUGS\n\n<https://github.com/soimort/translate-shell/issues>\n"
  },
  {
    "path": "man/trans.1.template.md",
    "content": "% TRANS(1) $Version$\n% Mort Yao <soi@mort.ninja>\n% $ReleaseDate$\n\n# NAME\n\ntrans - Command-line translator using Google Translate, Bing Translator, Yandex.Translate, etc.\n\n# SYNOPSIS\n\n**trans** [*OPTIONS*] [*SOURCE*]:[*TARGETS*] [*TEXT*]...\n\n# DESCRIPTION\n\nThis tool translates text into any language from the command-line, using a translation engine such as Google Translate, Bing Translator and Yandex.Translate.\n\nEach argument which is not a valid option is treated as *TEXT* to be translated.\n\nIf neither *TEXT* nor the input file is specified by command-line arguments, the program will read and translate from standard input.\n\n# OPTIONS\n\n## Information options\n\n**-V**, **-version**\n:   Print version and exit.\n\n**-H**, **-help**\n:   Print help message and exit.\n\n**-M**, **-man**\n:   Show man page and exit.\n\n**-T**, **-reference**\n:   Print reference table of all supported languages and codes, and exit. Names of languages are displayed in their endonyms (language name in the language itself).\n\n**-R**, **-reference-english**\n:   Print reference table of all supported languages and codes, and exit. Names of languages are displayed in English.\n\n**-S**, **-list-engines**\n:   List available translation engines and exit.\n\n**-list-languages**\n:   List all supported languages (in endonyms) and exit.\n\n**-list-languages-english**\n:   List all supported languages (in English names) and exit.\n\n**-list-codes**\n:   List all supported codes and exit.\n\n**-list-all**\n:   List all supported languages (endonyms and English names) and codes, and exit.\n\n**-L** *CODES*, **-linguist** *CODES*\n:   Print details of languages and exit. When specifying two or more language codes, concatenate them by plus sign \"+\".\n\n**-U**, **-upgrade**\n:   Check for upgrade of this program.\n\n## Translator options\n\n**-e** *ENGINE*, **-engine** *ENGINE*\n:   Specify the translation engine to use. (default: auto)\n\n## Display options\n\n**-verbose**\n:   Verbose mode.\n\n    Show the original text and its most relevant translation, then its phonetic notation (if any), then its alternative translations (if any) or its definition in the dictionary (if it is a word).\n\n    This option is unnecessary in most cases since verbose mode is enabled by default.\n\n**-b**, **-brief**\n:   Brief mode.\n\n    Show the most relevant translation or its phonetic notation only.\n\n**-d**, **-dictionary**\n:   Dictionary mode.\n\n    Show the definition of the original word in the dictionary.\n\n**-identify**\n:   Language identification.\n\n    Show the identified language of the original text.\n\n**-show-original** *Y/n*\n:   Show original text or not. (default: yes)\n\n**-show-original-phonetics** *Y/n*\n:   Show phonetic notation of original text or not. (default: yes)\n\n**-show-translation** *Y/n*\n:   Show translation or not. (default: yes)\n\n**-show-translation-phonetics** *Y/n*\n:   Show phonetic notation of translation or not. (default: yes)\n\n**-show-prompt-message** *Y/n*\n:   Show prompt message or not. (default: yes)\n\n**-show-languages** *Y/n*\n:   Show source and target languages or not. (default: yes)\n\n**-show-original-dictionary** *y/N*\n:   Show dictionary entry of original text or not. (default: no)\n\n    This option is enabled in dictionary mode.\n\n**-show-dictionary** *Y/n*\n:   Show dictionary entry of translation or not. (default: yes)\n\n**-show-alternatives** *Y/n*\n:   Show alternative translations or not. (default: yes)\n\n**-w** *NUM*, **-width** *NUM*\n:   Specify the screen width for padding.\n\n    This option overrides the setting of environment variable $**COLUMNS**.\n\n**-indent** *NUM*\n:   Specify the size of indent (number of spaces). (default: 4)\n\n**-theme** *FILENAME*\n:   Specify the theme to use. (default: default)\n\n**-no-theme**\n:   Do not use any other theme than default.\n\n**-no-ansi**\n:   Do not use ANSI escape codes.\n\n**-no-autocorrect**\n:   Do not autocorrect. (if defaulted by the translation engine)\n\n**-no-bidi**\n:   Do not convert bidirectional texts.\n\n**-bidi**\n:   Always convert bidirectional texts.\n\n**-no-warn**\n:   Do not write warning messages to stderr.\n\n**-dump**\n:   Print raw API response instead.\n\n## Audio options\n\n**-p**, **-play**\n:   Listen to the translation.\n\n    You must have at least one of the supported audio players (**mplayer**, **mpv** or **mpg123**) installed to stream from Google Text-to-Speech engine. Otherwise, a local speech synthesizer may be used instead (**say** on macOS, **espeak** on Linux or other platforms).\n\n**-speak**\n:   Listen to the original text.\n\n**-n** *VOICE*, **-narrator** *VOICE*\n:   Specify the narrator, and listen to the translation.\n\n    Common values for this option are **male** and **female**.\n\n**-player** *PROGRAM*\n:   Specify the audio player to use, and listen to the translation.\n\n    Option **-play** will try to use **mplayer**, **mpv** or **mpg123** by default, since these players are known to work for streaming URLs. Not all command-line audio players can work this way. Use this option only when you have your own preference.\n\n    This option overrides the setting of environment variable $**PLAYER**.\n\n**-no-play**\n:   Do not listen to the translation.\n\n**-no-translate**\n:   Do not translate anything when using -speak.\n\n**-download-audio**\n:   Download the audio to the current directory.\n\n**-download-audio-as** *FILENAME*\n:   Download the audio to the specified file.\n\n## Terminal paging and browsing options\n\n**-v**, **-view**\n:   View the translation in a terminal pager (**less**, **more** or **most**).\n\n**-pager** *PROGRAM*\n:   Specify the terminal pager to use, and view the translation.\n\n    This option overrides the setting of environment variable $**PAGER**.\n\n**-no-view**, **-no-pager**\n:   Do not view the translation in a terminal pager.\n\n**-browser** *PROGRAM*\n:   Specify the web browser to use.\n\n    This option overrides the setting of environment variable $**BROWSER**.\n\n**-no-browser**\n:   Do not open the web browser.\n\n## Networking options\n\n**-x** *HOST:PORT*, **-proxy** *HOST:PORT*\n:   Use HTTP proxy on given port.\n\n    This option overrides the setting of environment variables $**HTTP_PROXY** and $**http_proxy**.\n\n**-u** *STRING*, **-user-agent** *STRING*\n:   Specify the User-Agent to identify as.\n\n    This option overrides the setting of environment variables $**USER_AGENT**.\n\n**-4**, **-ipv4**, **-inet4-only**\n:   Connect only to IPv4 addresses.\n\n**-6**, **-ipv6**, **-inet6-only**\n:   Connect only to IPv6 addresses.\n\n## Interactive shell options\n\n**-I**, **-interactive**, **-shell**\n:   Start an interactive shell, invoking **rlwrap** whenever possible (unless **-no-rlwrap** is specified).\n\n**-E**, **-emacs**\n:   Start the GNU Emacs front-end for an interactive shell.\n\n    This option does not need to, and cannot be used along with **-I** or **-no-rlwrap**.\n\n**-no-rlwrap**\n:   Do not invoke **rlwrap** when starting an interactive shell.\n\n    This option is useful when your terminal type is not supported by **rlwrap** (e.g. **emacs**).\n\n## I/O options\n\n**-i** *FILENAME*, **-input** *FILENAME*\n:   Specify the input file.\n\n    Source text to be translated will be read from the input file, instead of standard input.\n\n**-o** *FILENAME*, **-output** *FILENAME*\n:   Specify the output file.\n\n    Translations will be written to the output file, instead of standard output.\n\n## Language preference options\n\n**-hl** *CODE*, **-host** *CODE*\n:   Specify your home language (the language you would like to see for displaying prompt messages in the translation).\n\n    This option affects only the display in verbose mode (anything other than source language and target language will be displayed in your home language). This option has no effect in brief mode.\n\n    This option is optional. When its setting is omitted, English will be used.\n\n    This option overrides the setting of environment variables $**LC_ALL**, $**LANG**, and $**HOST_LANG**.\n\n**-s** *CODES*, **-sl** *CODES*, **-source** *CODES*, **-from** *CODES*\n:   Specify the source language(s) (the language(s) of original text). When specifying two or more language codes, concatenate them by plus sign \"+\".\n\n    This option is optional. When its setting is omitted, the language of original text will be identified automatically (with a possibility of misidentification).\n\n    This option overrides the setting of environment variable $**SOURCE_LANG**.\n\n**-t** *CODES*, **-tl** *CODES*, **-target** *CODES*, **-to** *CODES*\n:   Specify the target language(s) (the language(s) of translated text). When specifying two or more language codes, concatenate them by plus sign \"+\".\n\n    This option is optional. When its setting is omitted, everything will be translated into English.\n\n    This option overrides the setting of environment variables $**LC_ALL**, $**LANG**, and $**TARGET_LANG**.\n\n[*SOURCE*]:[*TARGETS*]\n:   A simpler, alternative way to specify the source language and target language(s) is to use a shortcut formatted string:\n\n    * *SOURCE-CODE*:*TARGET-CODE*\n    * *SOURCE-CODE*:*TARGET-CODE1*+*TARGET-CODE2*+...\n    * *SOURCE-CODE*=*TARGET-CODE*\n    * *SOURCE-CODE*=*TARGET-CODE1*+*TARGET-CODE2*+...\n\n    Delimiter \":\" and \"=\" can be used interchangeably.\n\n    Either *SOURCE* or *TARGETS* may be omitted, but the delimiter character must be kept.\n\n## Text preprocessing options\n\n**-j**, **-join-sentence**\n:   Treat all arguments as one single sentence.\n\n## Other options\n\n**-no-init**\n:   Do not load any initialization script.\n\n**--**\n:   End-of-options.\n\n    All arguments after this option are treated as *TEXT* to be translated.\n\n# EXIT STATUS\n\n**0**\n:   Successful translation.\n\n**1**\n:   Error.\n\n# ENVIRONMENT\n\n**PAGER**\n:   Equivalent to option setting **-pager**.\n\n**BROWSER**\n:   Equivalent to option setting **-browser**.\n\n**PLAYER**\n:   Equivalent to option setting **-player**.\n\n**HTTP_PROXY**\n:   Equivalent to option setting **-proxy**.\n\n**USER_AGENT**\n:   Equivalent to option setting **-user-agent**.\n\n**HOST_LANG**\n:   Equivalent to option setting **-host**.\n\n**SOURCE_LANG**\n:   Equivalent to option setting **-source**.\n\n**TARGET_LANG**\n:   Equivalent to option setting **-target**.\n\n# FILES\n\n*/etc/translate-shell*\n:   Initialization script. (system-wide)\n\n*$HOME/.translate-shell/init.trans*\n:   Initialization script. (user-specific)\n\n*$XDG_CONFIG_HOME/translate-shell/init.trans*\n:   Initialization script. (user-specific)\n\n*./.trans*\n:   Initialization script. (current directory)\n\n# FURTHER DOCUMENTATION\n\n<https://github.com/soimort/translate-shell/wiki>\n\n# REPORTING BUGS\n\n<https://github.com/soimort/translate-shell/issues>\n"
  },
  {
    "path": "metainfo.awk",
    "content": "BEGIN {\n    Name        = \"Translate Shell\"\n    Description = \"Command-line translator using Google Translate, Bing Translator, Yandex.Translate, etc.\"\n    Version     = \"0.9.7.1\"\n    ReleaseDate = \"2023-02-08\"\n    Command     = \"trans\"\n    EntryPoint  = \"translate.awk\"\n    EntryScript = \"translate\"\n}\n"
  },
  {
    "path": "test/Test.awk",
    "content": "@include \"test/TestCommons\"\n@include \"test/TestUtils\"\n@include \"test/TestParser\"\n@include \"test/TestLanguageHelper\"\n"
  },
  {
    "path": "test/TestCommons.awk",
    "content": "BEGIN {\n    START_TEST(\"Commons.awk\")\n\n    # Arrays\n    T(\"anything()\", 3)\n    {\n        delete something\n        assertFalse(anything(nothing))\n        something[0] = 0; assertFalse(anything(something)) # edge case\n        something[0] = 1; assertTrue(anything(something))\n    }\n    T(\"exists()\", 4)\n    {\n        delete something\n        assertFalse(exists(something))\n        something[0] = 0; assertFalse(exists(something)) # edge case\n        something[0] = 1; assertTrue(exists(something))\n        assertTrue(exists(something[0]))\n    }\n    T(\"belongsTo()\", 3)\n    {\n        delete array; array[0] = \"foo\"; array[1] = \"bar\"\n        assertTrue(belongsTo(\"foo\", array))\n        assertTrue(belongsTo(\"bar\", array))\n        assertFalse(belongsTo(\"world\", array))\n    }\n    T(\"identical()\", 4)\n    {\n        delete x; x[0] = 42\n        delete y; y[0][0] = 42\n        assertFalse(identical(x, y))\n        assertTrue(identical(x, y[0]))\n        assertFalse(identical(x[0], y[0]))\n        assertTrue(identical(x[0], y[0][0]))\n    }\n    T(\"append()\", 1)\n    {\n        delete array; array[0] = \"foo\"\n        delete expected; expected[0] = \"foo\"; expected[1] = \"bar\"\n        append(array, \"bar\")\n        assertEqual(array, expected)\n    }\n\n    # Strings\n    T(\"isnum()\", 4)\n    {\n        assertTrue(isnum(0))\n        assertTrue(isnum(42.0))\n        assertFalse(isnum(\"\"))\n        assertFalse(isnum(\"hello world\"))\n    }\n    T(\"startsWithAny()\", 3)\n    {\n        delete substrings; substrings[0] = \"A\"; substrings[1] = \"a\"\n        assertTrue(startsWithAny(\"absolute\", substrings))\n        assertTrue(startsWithAny(\"ABSOLUTE\", substrings))\n        assertFalse(startsWithAny(\"ZOO\", substrings))\n    }\n    T(\"matchesAny()\", 4)\n    {\n        delete patterns; patterns[0] = \"[[:space:]]\"; patterns[1] = \"[0Oo]\"\n        assertTrue(matchesAny(\"  \", patterns))\n        assertTrue(matchesAny(\"obsolete\", patterns))\n        assertTrue(matchesAny(\"0.0\", patterns))\n        assertFalse(matchesAny(\"1.0\", patterns))\n    }\n    T(\"replicate()\", 4)\n    {\n        assertEqual(replicate(\"\", 0), \"\")\n        assertEqual(replicate(\"\", 2), \"\")\n        assertEqual(replicate(\"foo bar\", 1), \"foo bar\")\n        assertEqual(replicate(\"foo bar\", 3), \"foo barfoo barfoo bar\")\n    }\n    T(\"reverse()\", 4)\n    {\n        assertEqual(reverse(\"\"), \"\")\n        assertEqual(reverse(\"god\"), \"dog\")\n        assertEqual(reverse(\"0123456789\"), \"9876543210\")\n        assertEqual(reverse(\"さしすせそ\"), \"そせすしさ\")\n    }\n    T(\"join()\", 4)\n    {\n        assertEqual(join(\"\", \"-\"), \"\")\n        delete array; array[0]\n        assertEqual(join(array, \"-\"), \"\")\n        delete array; array[0] = \"foo\"; array[1] = \"bar\"\n        assertEqual(join(array, \" \"), \"foo bar\")\n        assertEqual(join(array, \",\"), \"foo,bar\")\n    }\n    T(\"explode()\", 1)\n    {\n        delete array\n        delete expected; expected[1] = \"f\"; expected[2] = \"o\"; expected[3] = \"o\"\n        explode(\"foo\", array)\n        assertEqual(array, expected)\n    }\n    T(\"escapeChar()\", 8)\n    {\n        assertEqual(escapeChar(\"b\"), \"\\b\")\n        assertEqual(escapeChar(\"f\"), \"\\f\")\n        assertEqual(escapeChar(\"n\"), \"\\n\")\n        assertEqual(escapeChar(\"r\"), \"\\r\")\n        assertEqual(escapeChar(\"t\"), \"\\t\")\n        assertEqual(escapeChar(\"v\"), \"\\v\")\n        assertEqual(escapeChar(\"_\"), \"_\")\n        assertNotEqual(escapeChar(\"_\"), \"\\\\_\")\n    }\n    T(\"literal()\", 6)\n    {\n        assertEqual(literal(\"\"), \"\")\n        assertEqual(literal(\"foo\"), \"foo\")\n        assertEqual(literal(\"\\\"foo\\\"\"), \"foo\")\n        assertEqual(literal(\"\\\"\\\\\\\"foo\\\\\\\"\\\"\"), \"\\\"foo\\\"\")\n        assertEqual(literal(\"\\\"foo\\\\nbar\\\"\"), \"foo\\nbar\")\n        assertEqual(literal(\"\\\"foo\\\\u0026bar\\\"\"), \"foo&bar\")\n    }\n    T(\"escape()\", 4)\n    {\n        assertEqual(escape(\"\"), \"\")\n        assertEqual(escape(\"foo\"), \"foo\")\n        assertEqual(escape(\"\\\"\"), \"\\\\\\\"\")\n        assertEqual(escape(\"\\\"foo\\\"\"), \"\\\\\\\"foo\\\\\\\"\")\n    }\n    T(\"unescape()\", 4)\n    {\n        assertEqual(unescape(\"\"), \"\")\n        assertEqual(unescape(\"foo\"), \"foo\")\n        assertEqual(unescape(\"\\\\\\\"\"), \"\\\"\")\n        assertEqual(unescape(\"\\\\\\\"foo\\\\\\\"\"), \"\\\"foo\\\"\")\n    }\n    T(\"parameterize()\", 10)\n    {\n        assertEqual(parameterize(\"\"), \"''\")\n        assertEqual(parameterize(\"foo\"), \"'foo'\")\n        assertEqual(parameterize(\"foo bar\"), \"'foo bar'\")\n        assertEqual(parameterize(\"foo 'bar\"), \"'foo '\\\\''bar'\")\n        assertEqual(parameterize(\"foo \\\"bar\\\"\"), \"'foo \\\"bar\\\"'\")\n        assertEqual(parameterize(\"\", \"\\\"\"), \"\\\"\\\"\")\n        assertEqual(parameterize(\"foo\", \"\\\"\"), \"\\\"foo\\\"\")\n        assertEqual(parameterize(\"foo bar\", \"\\\"\"), \"\\\"foo bar\\\"\")\n        assertEqual(parameterize(\"foo 'bar\", \"\\\"\"), \"\\\"foo 'bar\\\"\")\n        assertEqual(parameterize(\"foo \\\"bar\\\"\", \"\\\"\"), \"\\\"foo \\\\\\\"bar\\\\\\\"\\\"\")\n    }\n    T(\"unparameterize()\", 10)\n    {\n        assertEqual(unparameterize(\"''\"), \"\")\n        assertEqual(unparameterize(\"'foo'\"), \"foo\")\n        assertEqual(unparameterize(\"'foo bar'\"), \"foo bar\")\n        assertEqual(unparameterize(\"'foo '\\\\''bar'\"), \"foo 'bar\")\n        assertEqual(unparameterize(\"'foo \\\"bar\\\"'\"), \"foo \\\"bar\\\"\")\n        assertEqual(unparameterize(\"\\\"\\\"\"), \"\")\n        assertEqual(unparameterize(\"\\\"foo\\\"\"), \"foo\")\n        assertEqual(unparameterize(\"\\\"foo bar\\\"\"), \"foo bar\")\n        assertEqual(unparameterize(\"\\\"foo 'bar\\\"\"), \"foo 'bar\")\n        assertEqual(unparameterize(\"\\\"foo \\\\\\\"bar\\\\\\\"\\\"\"), \"foo \\\"bar\\\"\")\n    }\n    T(\"toString()\", 4)\n    {\n        assertEqual(toString(\"\"), \"\")\n        assertEqual(toString(42), \"42\")\n        assertEqual(toString(\"foo\"), \"foo\")\n        assertEqual(toString(\"\\\"foo bar\\\"\"), \"\\\"foo bar\\\"\")\n    }\n    T(\"squeeze()\", 4)\n    {\n        assertEqual(squeeze(\"\"), \"\")\n        assertEqual(squeeze(\" \"), \"\")\n        assertEqual(squeeze(\"\t\"), \"\")\n        assertEqual(squeeze(\"  foo = bar #comments\"), \"foo = bar\")\n    }\n    T(\"yn()\", 12)\n    {\n        assertFalse(yn(0))\n        assertFalse(yn(\"0\"))\n        assertFalse(yn(\"false\"))\n        assertFalse(yn(\"no\"))\n        assertFalse(yn(\"off\"))\n        assertFalse(yn(\"OFF\"))\n        assertTrue(yn(1))\n        assertTrue(yn(\"1\"))\n        assertTrue(yn(\"true\"))\n        assertTrue(yn(\"yes\"))\n        assertTrue(yn(\"on\"))\n        assertTrue(yn(\"ON\"))\n    }\n\n    # URLs\n    T(\"quote()\", 4)\n    {\n        assertEqual(quote(\"\"), \"\")\n        assertEqual(quote(\"foo\"), \"foo\")\n        assertEqual(quote(\"foo bar\"), \"foo%20bar\")\n        assertEqual(quote(\"\\\"hello, world!\\\"\"), \"%22hello%2C%20world%21%22\")\n    }\n\n    # un-URLs\n    T(\"unquote()\", 6)\n    {\n        assertEqual(unquote(\"\"), \"\")\n        assertEqual(unquote(\"foo\"), \"foo\")\n        assertEqual(unquote(\"foo%20bar\"), \"foo bar\")\n        assertEqual(unquote(\"%22hello%2C%20world%21%22\"), \"\\\"hello, world!\\\"\")\n        assertEqual(unquote(\"foo%%%%bar\"), \"foo%%%%bar\")\n        assertEqual(unquote(\"foo%%%%b\"), \"foo%%%%b\")\n    }\n\n    # System\n    T(\"fileExists()\", 4)\n    {\n        assertFalse(fileExists(\"README\"))\n        assertFalse(fileExists(\"README .md\"))\n        assertTrue(fileExists(\"README.md\"))\n        assertFalse(fileExists(\".\"))\n    }\n    T(\"dirExists()\", 4)\n    {\n        assertFalse(dirExists(\"README\"))\n        assertFalse(dirExists(\"README.md\"))\n        assertTrue(dirExists(\".\"))\n        assertFalse(dirExists(\" .\"))\n    }\n    T(\"detectProgram()\", 2)\n    {\n        assertTrue(detectProgram(\"ls\"))\n        assertTrue(detectProgram(\"gawk\", \"--version\"))\n    }\n\n    END_TEST()\n}\n"
  },
  {
    "path": "test/TestLanguageHelper.awk",
    "content": "@include \"include/LanguageData\"\n@include \"include/LanguageHelper\"\n\nBEGIN {\n    START_TEST(\"LanguageHelper.awk\")\n\n    T(\"getCode()\", 5)\n    {\n        initLocale()\n        initLocaleAlias()\n        initLocaleDisplay()\n\n        assertEqual(getCode(\"chinese\"), \"zh-CN\")\n        assertEqual(getCode(\"简体中文\"), \"zh-CN\")\n        assertEqual(getCode(\"正體中文\"), \"zh-TW\")\n        assertEqual(getCode(\"Japanese\"), \"ja\")\n        assertEqual(getCode(\"日本語\"), \"ja\")\n    }\n\n    END_TEST()\n}\n"
  },
  {
    "path": "test/TestParser.awk",
    "content": "@include \"include/Parser\"\n\nBEGIN {\n    START_TEST(\"Parser.awk\")\n\n    T(\"tokenize()\", 8)\n    {\n        delete tokens\n        tokenize(tokens, \"0\")\n        delete expected\n        expected[0] = \"0\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"3.14\")\n        delete expected\n        expected[0] = \"3.14\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"Atom\")\n        delete expected\n        expected[0] = \"Atom\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"\\\"foo bar\\\"\")\n        delete expected\n        expected[0] = \"\\\"foo bar\\\"\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"\\\"\\\\\\\"\\\"\")\n        delete expected\n        expected[0] = \"\\\"\\\\\\\"\\\"\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"(QUOTE A)\")\n        delete expected\n        expected[0] = \"(\"\n        expected[1] = \"QUOTE\"\n        expected[2] = \"A\"\n        expected[3] = \")\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"1 + 2 * 3\")\n        delete expected\n        expected[0] = \"1\"\n        expected[1] = \"+\"\n        expected[2] = \"2\"\n        expected[3] = \"*\"\n        expected[4] = \"3\"\n        assertEqual(tokens, expected)\n\n        delete tokens\n        tokenize(tokens, \"[42, \\\"hello, world\\\", [Foo, bar]]\")\n        delete expected\n        expected[0] = \"[\"\n        expected[1] = \"42\"\n        expected[2] = \",\"\n        expected[3] = \"\\\"hello, world\\\"\"\n        expected[4] = \",\"\n        expected[5] = \"[\"\n        expected[6] = \"Foo\"\n        expected[7] = \",\"\n        expected[8] = \"bar\"\n        expected[9] = \"]\"\n        expected[10] = \"]\"\n        assertEqual(tokens, expected)\n    }\n\n    T(\"parseJson()\", 10)\n    {\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"0\")\n        parseJson(ast, tokens)\n        expected[0] = \"0\"\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"null\")\n        parseJson(ast, tokens)\n        expected[0] = \"null\"\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"[42]\")\n        parseJson(ast, tokens)\n        expected[0 SUBSEP 0] = \"42\"\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"[42, \\\"answer\\\", null]\")\n        parseJson(ast, tokens)\n        expected[0 SUBSEP 0] = \"42\"\n        expected[0 SUBSEP 1] = \"\\\"answer\\\"\"\n        expected[0 SUBSEP 2] = \"null\"\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"{\\\"answer\\\": [42], \\\"Answer\\\": null}\")\n        parseJson(ast, tokens)\n        expected[0 SUBSEP \"answer\" SUBSEP 0] = 42\n        expected[0 SUBSEP \"Answer\"] = \"null\"\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"{\\\"answer\\\": {\\\"everything\\\": 42}}\")\n        parseJson(ast, tokens)\n        expected[0 SUBSEP \"answer\" SUBSEP \"everything\"] = \"42\"\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"{\\\"answer\\\": {\\\"everything\\\": [42]}}\")\n        parseJson(ast, tokens)\n        expected[0 SUBSEP \"answer\" SUBSEP \"everything\" SUBSEP 0] = \"42\"\n        assertEqual(ast, expected)\n\n        # empty object - what is the \"correct\" parsing result?\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"{}\")\n        parseJson(ast, tokens)\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"{\\\"answer\\\": {}}\")\n        parseJson(ast, tokens)\n        assertEqual(ast, expected)\n\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"{\\\"answer\\\": {}, \\\"Answer\\\": null}\")\n        parseJson(ast, tokens)\n        expected[0 SUBSEP \"Answer\"] = \"null\"\n        assertEqual(ast, expected)\n    }\n\n    T(\"parseList()\", 1)\n    {\n        delete tokens; delete ast; delete expected\n        tokenize(tokens, \"0\")\n        parseList(ast, tokens)\n        expected[NULLSTR][0] = \"0\"\n        assertEqual(ast, expected)\n    }\n\n    END_TEST()\n}\n"
  },
  {
    "path": "test/TestUtils.awk",
    "content": "@include \"include/Utils\"\n\nBEGIN {\n    START_TEST(\"Utils.awk\")\n\n    T(\"GawkVersion\", 1)\n    {\n        initGawk()\n        assertTrue(GawkVersion ~ \"^(4|5).\")\n    }\n\n    T(\"Rlwrap\", 1)\n    {\n        initRlwrap()\n        assertEqual(Rlwrap, \"rlwrap\")\n    }\n\n    T(\"Emacs\", 1)\n    {\n        initEmacs()\n        assertEqual(Emacs, \"emacs\")\n    }\n\n    T(\"newerVersion()\", 5)\n    {\n        assertTrue(newerVersion(\"0.9\", \"0.8\"))\n        assertTrue(newerVersion(\"0.9.0.1\", \"0.9.0\"))\n        assertTrue(newerVersion(\"1.0\", \"0.9.9999\"))\n        assertTrue(newerVersion(\"1.9.9999\", \"1.9.10\"))\n        assertTrue(newerVersion(\"2\", \"1.9.9999\"))\n    }\n\n    if (yn(ENVIRON[\"NETWORK_ACCESS\"])) { # if network access enabled\n        T(\"curl()\", 1)\n        {\n            delete tokens; delete ast\n            tokenize(tokens, curl(\"https://httpbin.org/get\"))\n            parseJson(ast, tokens)\n            assertEqual(unparameterize(ast[0 SUBSEP \"url\"]),\n                        \"https://httpbin.org/get\")\n        }\n\n        T(\"curlPost()\", 1)\n        {\n            delete tokens; delete ast\n            tokenize(tokens, curlPost(\"https://httpbin.org/post\", \"fizz=buzz\"))\n            parseJson(ast, tokens)\n            assertEqual(unparameterize(ast[0 SUBSEP \"url\"]),\n                        \"https://httpbin.org/post\")\n        }\n    }\n\n    T(\"dump()\", 3)\n    {\n        delete group\n        assertEqual(dump(\"a\", group), 1)\n\n        delete group\n        assertEqual(dump(\"Århus\", group), 6)\n\n        delete group\n        assertEqual(dump(\"안녕하세요 세계\", group), 22)\n    }\n\n    T(\"dumpX()\", 2)\n    {\n        delete group\n        assertEqual(dumpX(\"a\", group), 1)\n\n        delete group\n        assertEqual(dumpX(\"你好\", group), 6)\n    }\n\n    T(\"base64()\", 1)\n    {\n        assertEqual(base64(\"ninja\"), \"bmluamE=\")\n        assertEqual(base64(\"ninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninjaninja\"), \"bmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmphbmluamFuaW5qYW5pbmph\")\n    }\n\n    T(\"uprintf\", 1)\n    {\n        assertEqual(uprintf(\"Ma\\\\u00f1ana\"), \"Mañana\")\n    }\n\n    END_TEST()\n}\n"
  },
  {
    "path": "test.awk",
    "content": "#!/usr/bin/gawk -f\n@include \"include/Commons\"\n\nfunction pass(name, message, ansiCode,    string) {\n    if (!name) name = TEST\n    if (!ansiCode) ansiCode = \"green\"\n\n    G_COUNTER++; COUNTER++; G_SUCCESS++\n    string = sprintf(\"(%2s/%-2s) TESTING %s\", COUNTER, TOTAL, name)\n    if (message) string = string \"\\n       \" message\n    print(ansi(ansiCode, ansi(\"bold\", \"[PASS] \" string)))\n}\n\nfunction fail(name, message, ansiCode,    string) {\n    if (!name) name = TEST\n    if (!ansiCode) ansiCode = \"red\"\n\n    G_COUNTER++; COUNTER++\n    string = sprintf(\"(%2s/%-2s) TESTING %s\", COUNTER, TOTAL, name)\n    if (message) string = string \"\\n       \" message\n    print(ansi(ansiCode, ansi(\"bold\", \"[FAIL] \" string)))\n}\n\nfunction assertTrue(x, name, message, ansiCode) {\n    if (x)\n        pass(name, \"\", ansiCode)\n    else {\n        if (!message) message = \"assertTrue: FALSE\"\n        fail(name, message, ansiCode)\n    }\n}\n\nfunction assertFalse(x, name, message, ansiCode) {\n    if (!message) message = \"assertFalse: TRUE\"\n    assertTrue(!x, name, message, ansiCode)\n}\n\nfunction assertEqual(x, y, name, message, ansiCode,    i) {\n    if (!message)\n        message = \"assertEqual: \" ansi(\"underline\", toString(x, 1))     \\\n            \" IS NOT EQUAL TO \" ansi(\"underline\", toString(y, 1))\n    assertTrue(identical(x, y), name, message, ansiCode)\n}\n\nfunction assertNotEqual(x, y, name, message, ansiCode,    i) {\n    if (!message)\n        message = \"assertNotEqual: \" ansi(\"underline\", toString(x, 1))  \\\n            \" IS EQUAL TO \" ansi(\"underline\", toString(y, 1))\n    assertFalse(identical(x, y), name, message, ansiCode)\n}\n\nfunction T(test, total) {\n    TEST = test\n    TOTAL = total\n    COUNTER = 0\n}\n\nfunction START_TEST(name) {\n    print(ansi(\"negative\", ansi(\"bold\", \"====== TESTING FOR \"           \\\n                                ansi(\"underline\", name) \" STARTED\")))\n    G_COUNTER = G_SUCCESS = 0\n}\n\nfunction END_TEST() {\n    TOTAL = G_COUNTER; COUNTER = G_SUCCESS - 1\n    G_FAILURE = G_COUNTER - G_SUCCESS\n    if (G_FAILURE) {\n        assertEqual(G_COUNTER, G_SUCCESS, \"COMPLETED\",                  \\\n                    G_SUCCESS \" PASSED, \" G_FAILURE \" FAILED\", \"yellow\")\n        exit 1\n    } else\n        assertEqual(G_COUNTER, G_SUCCESS, \"COMPLETED. PERFECT!\")\n}\n\n@include \"test/Test\"\n"
  },
  {
    "path": "translate",
    "content": "#!/bin/sh\nexport TRANS_DIR=`dirname $0`\ngawk \\\n-i \"${TRANS_DIR}/metainfo.awk\" \\\n-i \"${TRANS_DIR}/include/Commons.awk\" \\\n-i \"${TRANS_DIR}/include/Utils.awk\" \\\n-i \"${TRANS_DIR}/include/LanguageData.awk\" \\\n-i \"${TRANS_DIR}/include/LanguageHelper.awk\" \\\n-i \"${TRANS_DIR}/include/Help.awk\" \\\n-i \"${TRANS_DIR}/include/Parser.awk\" \\\n-i \"${TRANS_DIR}/include/Theme.awk\" \\\n-i \"${TRANS_DIR}/include/Translate.awk\" \\\n-i \"${TRANS_DIR}/include/TranslatorInterface.awk\" \\\n-i \"${TRANS_DIR}/include/Translators/GoogleTranslate.awk\" \\\n-i \"${TRANS_DIR}/include/Translators/BingTranslator.awk\" \\\n-i \"${TRANS_DIR}/include/Translators/YandexTranslate.awk\" \\\n-i \"${TRANS_DIR}/include/Translators/Apertium.awk\" \\\n-i \"${TRANS_DIR}/include/Translators/SpellChecker.awk\" \\\n-i \"${TRANS_DIR}/include/Translators/Auto.awk\" \\\n-i \"${TRANS_DIR}/include/Script.awk\" \\\n-i \"${TRANS_DIR}/include/REPL.awk\" \\\n-f \"${TRANS_DIR}/include/Main.awk\" -- \"$@\"\n"
  },
  {
    "path": "translate-shell.plugin.zsh",
    "content": "#!/usr/bin/env zsh\nalias trans=\"$(dirname $0)/translate\"\n"
  },
  {
    "path": "translate.awk",
    "content": "#!/usr/bin/gawk -f\n\n@include \"metainfo.awk\"\n\n@include \"include/Commons.awk\"\n@include \"include/Utils.awk\"\n\n@include \"include/LanguageData.awk\"\n@include \"include/LanguageHelper.awk\"\n@include \"include/Help.awk\"\n@include \"include/Parser.awk\"\n@include \"include/Theme.awk\"\n\n@include \"include/Translate.awk\"\n@include \"include/TranslatorInterface.awk\"\n@include \"include/Translators/_\"\n\n@include \"include/Script.awk\"\n@include \"include/REPL.awk\"\n\n@include \"include/Main.awk\"\n"
  }
]