[
  {
    "path": ".gitignore",
    "content": ".DS_Store\ninfo.plist\n\n"
  },
  {
    "path": ".mdlrc",
    "content": "rules \"~MD013\"\n"
  },
  {
    "path": "Makefile",
    "content": "SHELL=bash\n\nhelp:\n\t@echo \"Some available commands:\"\n\t@echo \" * workflow : create workflow\"\n\t@echo \" * bats     : run dynamic tests\"\n\t@echo \" * test     : test shell scripts\"\n\t@echo \" * style    : style shell scripts\"\n\t@echo \" * harden   : harden shell scripts\"\n\t@echo \" * feedback : create a GitHub issue\"\n\nworkflow: dyntest workflow4 workflow5\n\nworkflow4:\n\t@rm -f Deepl-Translate.alfredworkflow\n\t@cp info4.plist info.plist\n\t@zip Deepl-Translate.alfredworkflow icon.png info.plist deepl.sh\n\t@rm info.plist\n\nworkflow5:\n\t@rm -f Deepl-Translate.alfred5workflow\n\t@cp info5.plist info.plist\n\t@zip Deepl-Translate.alfred5workflow icon.png info.plist deepl.sh\n\t@rm info.plist\n\nfeedback:\n\t@open https://github.com/alexanderwillner/deepl-alfred-workflow2/issues\n\nbats:\n\t@echo \"Running dynamic tests...\"\n\t@type bats >/dev/null 2>&1 || (echo \"Run 'brew install bats-core' first.\" >&2 ; exit 1)\n\t@bats deepl.bats\n\ndyntest:\n\t@DEEPL_KEY= ./deepl.sh -l EN \"Guten Morgen.\" 2>&1|grep \"Good morning\"\n\t@./deepl.sh -l EN \"Guten Morgen.\" 2>&1|grep \"Good morning\"\n\ntest:\n\t@echo \"Running first round of shell checks...\"\n\t@type shellcheck >/dev/null 2>&1 || (echo \"Run 'brew install shellcheck' first.\" >&2 ; exit 1)\n\t@shellcheck -x *.sh\n\t@echo \"Running second round of shell checks...\"\n\t@type shellharden >/dev/null 2>&1 || (echo \"Run 'brew install shellharden' first.\" >&2 ; exit 1)\n\t@shellharden --check deepl.sh\n\nharden:\n\t@shellharden --replace deepl.sh\n\nstyle:\n\t@type shfmt >/dev/null 2>&1 || (echo \"Run 'brew install shfmt' first.\" >&2 ; exit 1)\n\t@shfmt -i 2 -w -s *.sh\n\n.PHONY: workflow feedback bats test harden style\n"
  },
  {
    "path": "README.md",
    "content": "# Alfred DeepL Translation Workflow\n\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/1772be5a3aa4423a8dd122877896ce36)](https://www.codacy.com/gh/AlexanderWillner/deepl-alfred-workflow2/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=AlexanderWillner/deepl-alfred-workflow2&amp;utm_campaign=Badge_Grade) [![download](https://img.shields.io/github/downloads/AlexanderWillner/deepl-alfred-workflow2/total)](https://github.com/AlexanderWillner/deepl-alfred-workflow2/releases)\n\n## Usage\n\nTo activate this workflow use the default keyword ```dl```, enter the passage you wanna get translated and end the input with ```.``` (not needed if you've an API key). The source language will be inferred automatically and the target language can be configured.\n\n![Search](Screenshot-Search.png)\n\nAfter 1-2 seconds you get the translation. This is just an example.\n\n![Result](Screenshot-Result.png)\n\nPress ```↩``` to copy the result or ```⌘ + ↩``` to show result as big screen overlay.\nYou can also translate any selected text within macOS by pressing ```⌃ + ⌥ + ⌘ + d```.\n\nOther languages are supported as well:\n\n![Chinese](Screenshot-Chinese.png)\n\nTo quickly change the target language, you can use the ```dll``` keyword:\n\n![Result](Screenshot-DLL.png)\n\n## Caveats\n\nPlease note that the DeepL API is designed to translate up to 600 characters per minute and per customer only. This fact and generally some longer sentences might result in the message ```Error: Too many requests.``` (see #5).\nHowever, you can also get a (free or paid) [```API key```](https://www.deepl.com/pro-api) and configure it in the settings (see screenshot below).\n\n## Installing the Workflow\n\n1. Simply download the [last release](https://github.com/AlexanderWillner/deepl-alfred-workflow2/releases)\n2. Unzip the file on your computer\n3. Install `Deepl-Translate.alfredworkflow` by double-clicking the workflow file and clicking on \"Import\".\n\nYou'll now see the workflow listed in the left sidebar of your Workflows preferences pane.\n\nOnce imported, you may want to take a quick look at the workflow settings and setup what keyword you want to use. Further, you can change the target language in the settings as shown in this screenshot:\n\n![Config](Screenshot-Config.png)\n\n## Command Line\n\n```shell\n$ # DEEPL_TARGET=\"FR\"\n$ ./deepl.sh -l DE \"This is just an example.\"\n{\n  \"items\": [\n    {\n      \"uid\": null,\n      \"arg\": \"Dies ist nur ein Beispiel.\",\n      \"valid\": \"yes\",\n      \"autocomplete\": \"autocomplete\",\n      \"title\": \"Dies ist nur ein Beispiel.\"\n    },\n    {\n      \"uid\": null,\n      \"arg\": \"Das ist nur ein Beispiel.\",\n      \"valid\": \"yes\",\n      \"autocomplete\": \"autocomplete\",\n      \"title\": \"Das ist nur ein Beispiel.\"\n    },\n    {\n      \"uid\": null,\n      \"arg\": \"Dies ist nur ein Beispiel dafür.\",\n      \"valid\": \"yes\",\n      \"autocomplete\": \"autocomplete\",\n      \"title\": \"Dies ist nur ein Beispiel dafür.\"\n    },\n    {\n      \"uid\": null,\n      \"arg\": \"Dies ist nur ein exemplarisches Beispiel.\",\n      \"valid\": \"yes\",\n      \"autocomplete\": \"autocomplete\",\n      \"title\": \"Dies ist nur ein exemplarisches Beispiel.\"\n    }\n  ]\n}\n```\n\n## Important configuration variables\n\n* `DEEPL_KEY`: the DeepL API key\n* `DEEPL_PRO`: in case you have a professional DeepL account\n* `DEEPL_POSTFIX`: the character to the input should end with to mitigate #5\n* `DEEPL_TARGET`: the target language of the default `dl` keyword\n\n## Builing the workflow\n\nTo create a modified version of the workflow, edit the files and run ```make workflow``` to create an updated workflow.\n\n## Disclaimer\n\nDeepL is a product from DeepL GmbH. More info: [deepl.com/publisher.html](https://www.deepl.com/publisher.html)\n\nThis package has been heavily inspired by [m9dfukc's DeepL Alfred Workflow](https://github.com/m9dfukc/deepl-alfred-workflow).\n"
  },
  {
    "path": "deepl-write.sh",
    "content": "#!/bin/bash\n\n# setup #######################################################################\n#set -o errexit -o pipefail -o noclobber -o nounset\nLANGUAGE=\"${DEEPL_TARGET:-EN}\"\nLANGUAGE_SOURCE=\"${DEEPL_SOURCE:-auto}\"\nLANGUAGE_PREFERRED=\"${DEEPL_PREFERRED:-[\\\"DE\\\",\\\"EN\\\"]}\"\nKEY=\"${DEEPL_KEY:-}\"\nPRO=\"${DEEPL_PRO:-}\"\n# see https://developers.deepl.com/docs/api-reference/translate/openapi-spec-for-text-translation\nFORMALITY=\"${DEEPL_FORMALITY:-prefer_less}\"\nPOSTFIX=\"${DEEPL_POSTFIX:-.}\"\nVERSION=\"2.1.0\"\nPATH=\"$PATH:/usr/local/bin/\"\nDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null 2>&1 && pwd )\"\n###############################################################################\n\n# helper functions ############################################################\nfunction printJson() {\n  echo '{\"items\": [{\"uid\": null,\"arg\": \"'\"$1\"'\",\"valid\": \"yes\",\"autocomplete\": \"autocomplete\",\"title\": \"'\"$1\"'\"}]}'\n}\n###############################################################################\n\n# parameters ##################################################################\nPOSITIONAL=()\nwhile [[ $# -gt 0 ]]; do\n  key=\"$1\"\n  case \"$key\" in\n  -l | --lang)\n    LANGUAGE=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n  *) # unknown option\n    POSITIONAL+=(\"$1\") # save it in an array for later\n    shift              # past argument\n    ;;\n  esac\ndone\nset -- \"${POSITIONAL[@]:-}\" # restore positional parameters\n###############################################################################\n\n# help ########################################################################\nif [ -z \"$1\" ]; then\n  echo \"Home made DeepL CLI (${VERSION}; https://github.com/AlexanderWillner/deepl-alfred-workflow2)\"\n  echo \"\"\n  echo \"SYNTAX : $0 [-l language] <query>\" >&2\n  echo \"Example: $0 -l EN \\\"This is just an example.\\\"\"\n  echo \"\"\n  exit 1\nfi\n###############################################################################\n\n# process query ###############################################################\nquery=\"$1\"\n# shellcheck disable=SC2001\nquery=\"$(echo \"$query\" | sed 's/\\\"/\\\\\\\"/g')\"\n# shellcheck disable=SC2001\nquery=\"$(echo \"$query\" | sed \"s/'/\\\\\\'/g\")\"\nquery=\"$(echo \"$query\" | iconv -f utf-8-mac -t utf-8 | xargs)\"\n\nif [[ $KEY = \"\" ]] && [[ $query != *\"$POSTFIX\"   ]]; then\n  printJson \"End query with $POSTFIX\"\n  exit 2\nfi\n###############################################################################\n\n# prepare query ###############################################################\n# shellcheck disable=SC2001\nquery=\"$(echo \"$query\" | sed \"s/\\\\$POSTFIX$//\")\"\nif [ \"$KEY\" = \"\" ]; then\n  FORM_PARAM=''\nelse\n  FORM_PARAM='\"formality\": \"'\"$FORMALITY\"'\", '\nfi\n\ndata='{\"jsonrpc\":\"2.0\",\"method\": \"LMT_handle_jobs\",\"params\":{\"jobs\":[{\"kind\":\"default\",\"sentences\":[{\"text\":\"'\"$query\"'\",\"id\":1,\"prefix\":\"\"}],\"raw_en_context_before\":[],\"raw_en_context_after\":[],\"preferred_num_beams\":1,\"write_variant_requests\":[\"main\",\"variants\"],\"style_variant\":\"business\"}],\"lang\":{\"target_lang\":\"'\"${LANGUAGE:-EN}\"'\",\"preference\":{\"weight\":{},\"default\":\"default\"},\"source_lang_computed\":\"'\"${LANGUAGE:-EN}\"'\"},\"priority\":1,\"commonJobParams\":{\"quality\":\"normal\",\"regionalVariant\":\"en-US\",\"mode\":\"write\",\"browserType\":1,\"textType\":\"plaintext\",\"style_variant\":\"business\"},\"timestamp\":1739745925254},\"id\":20270141}'\nHEADER=(\n  --compressed\n  -H 'authority: write-free.www.deepl.com'\n  -H 'Origin: https://write-free.www.deepl.com'\n  -H 'Referer: https://www.deepl.com/'\n  -H 'Accept: */*'\n  -H 'Content-Type: application/json'\n  -H 'Accept-Language: en-us'\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Safari/605.1.15'\n)\n###############################################################################\n\n# query #######################################################################\nif [ -n \"$KEY\" ]; then\n  if [ \"$PRO\" = \"1\" ]; then\n    url=\"https://api.deepl.com/v2/translate\"\n  else\n    url=\"https://api-free.deepl.com/v2/translate\"\n  fi\n  if [ ! -z \"$DEEPL_HOST\" ]; then\n    url=\"$DEEPL_HOST/v2/translate\"\n  fi\n\n  echo >&2 \"curl -s -X POST '$url' -H 'Authorization: DeepL-Auth-Key $KEY' --data-urlencode 'text=$query' -d 'formality=$FORMALITY' -d 'target_lang=${LANGUAGE:-EN}'\"\n  result=$(curl -s -X POST \"$url\" -H \"Authorization: DeepL-Auth-Key $KEY\" --data-urlencode \"text=$query\" -d \"formality=$FORMALITY\" -d \"target_lang=${LANGUAGE:-EN}\")\n  ret=$?\n  if [[ \"x$ret\" != \"x0\" ]] || [[ \"$result\" == \"\" ]]; then\n    echo >&2 \"$ret: $result\"\n    http_code=$(curl -s -X POST \"$url\" -H \"Authorization: DeepL-Auth-Key $KEY\" --data-urlencode \"text=$query\" -d \"target_lang=${LANGUAGE:-EN}\" -d \"formality=$FORMALITY\" -w %{http_code} -o /dev/null)\n    if [[ $http_code -eq 403 ]]; then\n      printJson \"Error: Invalid API key\"\n      exit 3\n    fi\n    if [[ $ret -eq 6 ]]; then\n      printJson \"Error: DNS resolution failed - no Internet connection?\"\n      exit 4\n    fi\n    printJson \"Error Code $ret - HTTP Code $http_code\"\n    exit 5\n  fi\n  osascript -l JavaScript -e 'function run(argv) {\n    const translations = JSON.parse(argv[0])[\"translations\"].map(item => ({\n      title: item[\"text\"],\n      arg: item[\"text\"]\n    }))\n\n    return JSON.stringify({ items: translations }, null, 2)\n  }' \"$result\" || echo >&2 \"ERROR w/ key: result '$result', query '$query'\"\nelse\n  echo >&2 \"curl -s 'https://write-free.www.deepl.com/jsonrpc' '${HEADER[@]}' --data-binary $'$data'\"\n  result=$(curl -s 'https://write-free.www.deepl.com/jsonrpc' \"${HEADER[@]}\" --data-binary $\"$data\")\n  ret=$?\n  if [[ \"x$ret\" != \"x0\" ]] || [[ \"$result\" == \"\" ]]; then\n    echo >&2 \"$ret: $result\"\n    http_code=$(curl -s 'https://write-free.www.deepl.com/jsonrpc' \"${HEADER[@]}\" --data-binary $\"$data\" -w %{http_code} -o /dev/null)\n    if [[ $ret -eq 6 ]]; then\n      printJson \"Error: DNS resolution failed - no Internet connection?\"\n      exit 6\n    fi\n    printJson \"Error Code $ret - HTTP Code $http_code\"\n    exit 7\n  fi\n  if [[ $result == *'\"error\":{\"code\":'* ]]; then\n    message=\"$(osascript -l JavaScript -e 'function run(argv) { return JSON.parse(argv[0])[\"error\"][\"message\"] }')\"\n    printJson \"Error: $message\"\n    exit 8\n  else\n    osascript -l JavaScript -e 'function run(argv) {\n      const translations = JSON.parse(argv[0])[\"result\"][\"translations\"][0][\"beams\"].map(item => ({\n        title: item[\"sentences\"],\n        arg: item[\"sentences\"]\n      }))\n\n      return JSON.stringify({ items: translations }, null, 2)\n    }' \"$result\" || echo >&2 \"ERROR w/o key: result '$result', query '$query'\"\n  fi\nfi\n###############################################################################\n"
  },
  {
    "path": "deepl.bats",
    "content": "#!/usr/bin/env bats\n\nteardown() {\n\tsleep 1\n}\n\n@test \"No parameters\" {\n  run ./deepl.sh\n  [[ \"$status\" -eq 1 ]]\n}\n\n@test \"Missing dot\" {\n  run ./deepl.sh \"Vogel\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"End query with a dot\"* ]]\n}\n\n@test \"Single Word\" {\n  run ./deepl.sh -l EN \"Vogel.\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"bird\"* ]]\n}\n\n@test \"Trailing spaces\" {\n  run ./deepl.sh \" Vogel. \"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"bird\"* ]]\n}\n\n@test \"Sentence\" {\n  run ./deepl.sh -l DE \"Translate from any language.\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"aus jeder Sprache\"* ]]\n}\n\n@test \"Umlaut source\" {\n  run ./deepl.sh -l EN \"Erdöl.\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"oil\"* ]]\n}\n\n@test \"Umlaut destination\" {\n  run ./deepl.sh -l DE \"Oil.\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"öl\"* ]]\n}\n\n@test \"Quote source\" {\n  run ./deepl.sh -l DE \"I'll.\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"Ich werde\"* ]]\n}\n\n@test \"Quote destination\" {\n  run ./deepl.sh -l EN \"Ich werde.\"\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *\"I'll be\"* ]]\n}\n\n@test \"Double quote source\" {\n  run ./deepl.sh -l EN '\"Apfel\".'\n  [[ \"$status\" -eq 0 ]]\n  [[ \"$output\" == *'\\\"Apple\\\"'* ]]\n}\n\n#todo: fixme #6\n#@test \"Spanisch\" {\n#  run ./deepl.sh -l EN \"El tiempo es una ilusión.\"\n#  [[ \"$status\" -eq 0 ]]\n#  [[ \"$output\" == *'\\\"time\\\"'* ]]\n#}\n\n#todo: fixme #1\n#@test \"Long sentences\" {\n#  run ./deepl.sh -l DE \"He felt that his whole life was some kind of dream and he sometimes wondered whose it was and whether they were enjoying it.\"\n#  [[ \"$status\" -eq 0 ]]\n#  [[ \"$output\" == *'\\\"Leben\\\"'* ]]\n#}\n\n#todo: fixme #1\n#@test \"Multi sentences\" {\n#  run ./deepl.sh -l DE \"This planet has - or rather had - a problem, which was this: most of the people living on it were unhappy for pretty much of the time. Many solutions were suggested for this problem, but most of these were largely concerned with the movement of small green pieces of paper, which was odd because on the whole it wasn't the small green pieces of paper that were unhappy.\"\n#  [[ \"$status\" -eq 0 ]]\n#  [[ \"$output\" == *'\\\"unglücklich\\\"'* ]]\n#}\n\n"
  },
  {
    "path": "deepl.sh",
    "content": "#!/bin/bash\n\n# setup #######################################################################\n#set -o errexit -o pipefail -o noclobber -o nounset\nLANGUAGE=\"${DEEPL_TARGET:-EN}\"\nLANGUAGE_SOURCE=\"${DEEPL_SOURCE:-auto}\"\nLANGUAGE_PREFERRED=\"${DEEPL_PREFERRED:-[\\\"DE\\\",\\\"EN\\\"]}\"\nKEY=\"${DEEPL_KEY:-}\"\nPRO=\"${DEEPL_PRO:-}\"\n# see https://developers.deepl.com/docs/api-reference/translate/openapi-spec-for-text-translation\nFORMALITY=\"${DEEPL_FORMALITY:-prefer_less}\"\nPOSTFIX=\"${DEEPL_POSTFIX:-.}\"\nVERSION=\"2.1.0\"\nPATH=\"$PATH:/usr/local/bin/\"\nDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null 2>&1 && pwd )\"\n###############################################################################\n\n# helper functions ############################################################\nfunction printJson() {\n  echo '{\"items\": [{\"uid\": null,\"arg\": \"'\"$1\"'\",\"valid\": \"yes\",\"autocomplete\": \"autocomplete\",\"title\": \"'\"$1\"'\"}]}'\n}\n###############################################################################\n\n# parameters ##################################################################\nPOSITIONAL=()\nwhile [[ $# -gt 0 ]]; do\n  key=\"$1\"\n  case \"$key\" in\n  -l | --lang)\n    LANGUAGE=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n  *) # unknown option\n    POSITIONAL+=(\"$1\") # save it in an array for later\n    shift              # past argument\n    ;;\n  esac\ndone\nset -- \"${POSITIONAL[@]:-}\" # restore positional parameters\n###############################################################################\n\n# help ########################################################################\nif [ -z \"$1\" ]; then\n  echo \"Home made DeepL CLI (${VERSION}; https://github.com/AlexanderWillner/deepl-alfred-workflow2)\"\n  echo \"\"\n  echo \"SYNTAX : $0 [-l language] <query>\" >&2\n  echo \"Example: $0 -l DE \\\"This is just an example.\\\"\"\n  echo \"\"\n  exit 1\nfi\n###############################################################################\n\n# process query ###############################################################\nquery=\"$1\"\n# shellcheck disable=SC2001\nquery=\"$(echo \"$query\" | sed 's/\\\"/\\\\\\\"/g')\"\n# shellcheck disable=SC2001\nquery=\"$(echo \"$query\" | sed \"s/'/\\\\\\'/g\")\"\nquery=\"$(echo \"$query\" | iconv -f utf-8-mac -t utf-8 | xargs)\"\n\nif [[ $KEY = \"\" ]] && [[ $query != *\"$POSTFIX\"   ]]; then\n  printJson \"End query with $POSTFIX\"\n  exit 2\nfi\n###############################################################################\n\n# prepare query ###############################################################\n# shellcheck disable=SC2001\nquery=\"$(echo \"$query\" | sed \"s/\\\\$POSTFIX$//\")\"\nif [ \"$KEY\" = \"\" ]; then\n  FORM_PARAM=''\nelse\n  FORM_PARAM='\"formality\": \"'\"$FORMALITY\"'\", '\nfi\ndata='{\"jsonrpc\":\"2.0\",\"method\": \"LMT_handle_jobs\",\"params\":{\"commonJobParams\": {'$FORM_PARAM'\"browserType\": 1, \"mode\": \"translate\", \"textType\": \"plaintext\"}, \"jobs\":[{\"kind\":\"default\",\"raw_en_sentence\":\"'\"$query\"'\",\"preferred_num_beams\":4,\"raw_en_context_before\":[],\"raw_en_context_after\":[],\"quality\":\"fast\"}],\"lang\":{\"user_preferred_langs\":'\"${LANGUAGE_PREFERRED}\"',\"source_lang_user_selected\":\"'\"${LANGUAGE_SOURCE}\"'\",\"target_lang\":\"'\"${LANGUAGE:-EN}\"'\"},\"priority\":1,\"timestamp\":1557063997314},\"id\":79120002}'\nHEADER=(\n  --compressed\n  -H 'authority: www2.deepl.com'\n  -H 'Origin: https://www.deepl.com'\n  -H 'Referer: https://www.deepl.com/translator'\n  -H 'Accept: */*'\n  -H 'Content-Type: application/json'\n  -H 'Accept-Language: en-us'\n  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Safari/605.1.15'\n)\n###############################################################################\n\n# query #######################################################################\nif [ -n \"$KEY\" ]; then\n  if [ \"$PRO\" = \"1\" ]; then\n    url=\"https://api.deepl.com/v2/translate\"\n  else\n    url=\"https://api-free.deepl.com/v2/translate\"\n  fi\n  if [ ! -z \"$DEEPL_HOST\" ]; then\n    url=\"$DEEPL_HOST/v2/translate\"\n  fi\n\n  echo >&2 \"curl -s -X POST '$url' -H 'Authorization: DeepL-Auth-Key $KEY' --data-urlencode 'text=$query' -d 'formality=$FORMALITY' -d 'target_lang=${LANGUAGE:-EN}'\"\n  result=$(curl -s -X POST \"$url\" -H \"Authorization: DeepL-Auth-Key $KEY\" --data-urlencode \"text=$query\" -d \"formality=$FORMALITY\" -d \"target_lang=${LANGUAGE:-EN}\")\n  ret=$?\n  if [[ \"x$ret\" != \"x0\" ]] || [[ \"$result\" == \"\" ]]; then\n    echo >&2 \"$ret: $result\"\n    http_code=$(curl -s -X POST \"$url\" -H \"Authorization: DeepL-Auth-Key $KEY\" --data-urlencode \"text=$query\" -d \"target_lang=${LANGUAGE:-EN}\" -d \"formality=$FORMALITY\" -w %{http_code} -o /dev/null)\n    if [[ $http_code -eq 403 ]]; then\n      printJson \"Error: Invalid API key\"\n      exit 3\n    fi\n    if [[ $ret -eq 6 ]]; then\n      printJson \"Error: DNS resolution failed - no Internet connection?\"\n      exit 4\n    fi\n    printJson \"Error Code $ret - HTTP Code $http_code\"\n    exit 5\n  fi\n  osascript -l JavaScript -e 'function run(argv) {\n    try {\n      const parsed = JSON.parse(argv[0]);\n      if (!parsed || !parsed.translations) {\n        throw new Error(\"Invalid response structure\");\n      }\n      const translations = parsed.translations.map(item => ({\n        title: item[\"text\"],\n        arg: item[\"text\"]\n      }));\n      return JSON.stringify({ items: translations }, null, 2);\n    } catch(e) {\n      return JSON.stringify({ \n        items: [{ \n          title: \"Error parsing response: \" + e.message, \n          arg: \"error\",\n          valid: false \n        }] \n      }, null, 2);\n    }\n  }' \"$result\" || {\n    echo >&2 \"ERROR w/ key: result '$result', query '$query'\"\n    printJson \"Error: Failed to parse translation response\"\n    exit 10\n  }\nelse\n  echo >&2 \"curl -s 'https://www2.deepl.com/jsonrpc' '${HEADER[@]}' --data-binary $'$data'\"\n  result=$(curl -s 'https://www2.deepl.com/jsonrpc' \"${HEADER[@]}\" --data-binary $\"$data\")\n  ret=$?\n  echo >&2 \"DEBUG: curl exit code: $ret\"\n  echo >&2 \"DEBUG: result length: ${#result}\"\n  echo >&2 \"DEBUG: result first 200 chars: ${result:0:200}\"\n  \n  if [[ \"x$ret\" != \"x0\" ]] || [[ \"$result\" == \"\" ]]; then\n    echo >&2 \"$ret: $result\"\n    http_code=$(curl -s 'https://www2.deepl.com/jsonrpc' \"${HEADER[@]}\" --data-binary $\"$data\" -w %{http_code} -o /dev/null)\n    if [[ $ret -eq 6 ]]; then\n      printJson \"Error: DNS resolution failed - no Internet connection?\"\n      exit 6\n    fi\n    printJson \"Error Code $ret - HTTP Code $http_code\"\n    exit 7\n  fi\n  # Validate JSON before parsing\n  if ! echo \"$result\" | python3 -m json.tool > /dev/null 2>&1; then\n    echo >&2 \"ERROR: Invalid JSON response: $result\"\n    printJson \"Error: Invalid JSON response from DeepL\"\n    exit 8\n  fi\n  \n  if [[ $result == *'\"error\":{\"code\":'* ]]; then\n    message=\"$(osascript -l JavaScript -e 'function run(argv) { \n      try {\n        return JSON.parse(argv[0])[\"error\"][\"message\"] \n      } catch(e) {\n        return \"JSON parse error: \" + e.message\n      }\n    }' \"$result\")\"\n    printJson \"Error: $message\"\n    exit 8\n  else\n    osascript -l JavaScript -e 'function run(argv) {\n      try {\n        const parsed = JSON.parse(argv[0]);\n        if (!parsed || !parsed.result || !parsed.result.translations || !parsed.result.translations[0] || !parsed.result.translations[0].beams) {\n          throw new Error(\"Invalid response structure\");\n        }\n        const translations = parsed.result.translations[0].beams.map(item => ({\n          title: item[\"postprocessed_sentence\"],\n          arg: item[\"postprocessed_sentence\"]\n        }));\n        return JSON.stringify({ items: translations }, null, 2);\n      } catch(e) {\n        return JSON.stringify({ \n          items: [{ \n            title: \"Error parsing response: \" + e.message, \n            arg: \"error\",\n            valid: false \n          }] \n        }, null, 2);\n      }\n    }' \"$result\" || {\n      echo >&2 \"ERROR w/o key: result '$result', query '$query'\"\n      printJson \"Error: Failed to parse translation response\"\n      exit 9\n    }\n  fi\nfi\n###############################################################################\n"
  },
  {
    "path": "info4.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>bundleid</key>\n\t<string>ws.willner.alex.alfred.deepl</string>\n\t<key>category</key>\n\t<string>Productivity</string>\n\t<key>connections</key>\n\t<dict>\n\t\t<key>5233F7C8-9221-45A4-BDE0-DE53175096E1</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>1048576</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>D7D47F17-02DB-4A30-8F14-C03CBD051929</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>84FE56AF-330C-4BB8-85E6-34859AAB73A7</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>91D16594-908E-4665-A005-0B715D96E5C2</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>91D16594-908E-4665-A005-0B715D96E5C2</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>1048576</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>AD7C89C1-0978-4469-B62F-245E595DE9BD</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>91D16594-908E-4665-A005-0B715D96E5C2</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>CAA19D9E-04B6-4AD4-A8DC-0B683215DD14</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>5233F7C8-9221-45A4-BDE0-DE53175096E1</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t</dict>\n\t<key>createdby</key>\n\t<string>Alexander Willner</string>\n\t<key>description</key>\n\t<string>Translation using deepl.com</string>\n\t<key>disabled</key>\n\t<false/>\n\t<key>name</key>\n\t<string>Deepl-Translate</string>\n\t<key>objects</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alignment</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>backgroundcolor</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>fadespeed</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>fillmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>font</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>ignoredynamicplaceholders</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>largetypetext</key>\n\t\t\t\t<string>{query}</string>\n\t\t\t\t<key>textcolor</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>wrapat</key>\n\t\t\t\t<integer>50</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.output.largetype</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dl-to-en</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string>Translating to language \"EN\" using DeepL ...</string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>./deepl.sh -l \"EN\" \"{query}\"\n</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string>deepl.sh</string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string>Translate to language \"EN\" using DeepL</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>DeepL Dictionary</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>5233F7C8-9221-45A4-BDE0-DE53175096E1</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>action</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argument</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>focusedappvariable</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>focusedappvariablename</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>hotkey</key>\n\t\t\t\t<integer>14</integer>\n\t\t\t\t<key>hotmod</key>\n\t\t\t\t<integer>1835008</integer>\n\t\t\t\t<key>hotstring</key>\n\t\t\t\t<string>E</string>\n\t\t\t\t<key>leftcursor</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>modsmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>relatedAppsMode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.trigger.hotkey</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>CAA19D9E-04B6-4AD4-A8DC-0B683215DD14</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>2</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>autopaste</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>clipboardtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>ignoredynamicplaceholders</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>transient</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.output.clipboard</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>lastpathcomponent</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>onlyshowifquerypopulated</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>removeextension</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>text</key>\n\t\t\t\t<string>{query}</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>Copied to clipboard:</string>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.output.notification</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>D7D47F17-02DB-4A30-8F14-C03CBD051929</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>1</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>action</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argument</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>focusedappvariable</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>focusedappvariablename</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>hotkey</key>\n\t\t\t\t<integer>2</integer>\n\t\t\t\t<key>hotmod</key>\n\t\t\t\t<integer>1835008</integer>\n\t\t\t\t<key>hotstring</key>\n\t\t\t\t<string>D</string>\n\t\t\t\t<key>leftcursor</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>modsmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>relatedAppsMode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.trigger.hotkey</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>84FE56AF-330C-4BB8-85E6-34859AAB73A7</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>2</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dl-to-de</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string>Translating to language \"de\" using DeepL ...</string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>DEEPL_KEY=\"$DEEPL_KEY\" ./deepl.sh -l \"de\" \"{query}\"</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string>deepl.sh</string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string>Translate to language \"de\" using DeepL</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>DeepL Dictionary</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>91D16594-908E-4665-A005-0B715D96E5C2</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>concurrently</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string># THESE VARIABLES MUST BE SET. SEE THE ONEUPDATER README FOR AN EXPLANATION OF EACH.\nreadonly remote_info_plist='https://raw.githubusercontent.com/AlexanderWillner/deepl-alfred-workflow2/master/info.plist'\nreadonly workflow_url='https://github.com/AlexanderWillner/deepl-alfred-workflow2/releases/latest/download/Deepl-Translate.alfredworkflow'\nreadonly download_type='direct'\nreadonly frequency_check='4'\n\n# FROM HERE ON, CODE SHOULD BE LEFT UNTOUCHED!\nfunction abort {\n  echo \"${1}\" &gt;&amp;2\n  exit 1\n}\n\nfunction url_exists {\n  curl --silent --location --output /dev/null --fail --range 0-0 \"${1}\"\n}\n\nfunction notification {\n  local -r notificator=\"$(find . -type d -name 'Notificator.app')\"\n  if [[ -n \"${notificator}\" ]]; then\n    \"${notificator}/Contents/Resources/Scripts/notificator\" --message \"${1}\" --title \"${alfred_workflow_name}\" --subtitle 'A new version is available'\n    return\n  fi\n\n  local -r terminal_notifier=\"$(find . -type f -name 'terminal-notifier')\"\n  if [[ -n \"${terminal_notifier}\" ]]; then\n    \"${terminal_notifier}\" -title \"${alfred_workflow_name}\" -subtitle 'A new version is available' -message \"${1}\"\n    return\n  fi\n\n  osascript -e \"display notification \\\"${1}\\\" with title \\\"${alfred_workflow_name}\\\" subtitle \\\"A new version is available\\\"\"\n}\n\n# Local sanity checks\nreadonly local_info_plist='info.plist'\nreadonly local_version=\"$(/usr/libexec/PlistBuddy -c 'print version' \"${local_info_plist}\")\"\n\n[[ -n \"${local_version}\" ]] || abort 'You need to set a workflow version in the configuration sheet.'\n[[ \"${download_type}\" =~ ^(direct|page|github_release)$ ]] || abort \"'download_type' (${download_type}) needs to be one of 'direct', 'page', or 'github_release'.\"\n[[ \"${frequency_check}\" =~ ^[0-9]+$ ]] || abort \"'frequency_check' (${frequency_check}) needs to be a number.\"\n\n# Check for updates\nif [[ $(find \"${local_info_plist}\" -mtime +\"${frequency_check}\"d) ]]; then\n  if ! url_exists \"${remote_info_plist}\"; then abort \"'remote_info_plist' (${remote_info_plist}) appears to not be reachable.\"; fi # Remote sanity check\n\n  readonly tmp_file=\"$(mktemp)\"\n  curl --silent --location --output \"${tmp_file}\" \"${remote_info_plist}\"\n  readonly remote_version=\"$(/usr/libexec/PlistBuddy -c 'print version' \"${tmp_file}\")\"\n\n  if [[ \"${local_version}\" == \"${remote_version}\" ]]; then\n    touch \"${local_info_plist}\" # Reset timer by touching local file\n    exit 0\n  fi\n\n  if [[ \"${download_type}\" == 'page' ]]; then\n    notification 'Opening download page…'\n    open \"${workflow_url}\"\n    exit 0\n  fi\n\n  download_url=\"$([[ \"${download_type}\" == 'github_release' ]] &amp;&amp; curl --silent \"https://api.github.com/repos/${workflow_url}/releases/latest\" | grep 'browser_download_url' | head -1 | sed -E 's/.*browser_download_url\": \"(.*)\"/\\1/' || echo \"${workflow_url}\")\"\n\n  if url_exists \"${download_url}\"; then\n    notification 'Downloading and installing…'\n    curl --silent --location --output \"${HOME}/Downloads/${alfred_workflow_name}.alfredworkflow\" \"${download_url}\"\n    open \"${HOME}/Downloads/${alfred_workflow_name}.alfredworkflow\"\n  else\n    abort \"'workflow_url' (${download_url}) appears to not be reachable.\"\n  fi\nfi</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.action.script</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>51AFB0E3-C777-4C5E-A677-3AF381488BCC</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>2</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dl</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string>Translating to language \"{var:DEEPL_TARGET}\" using DeepL ...</string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>DEEPL_KEY=\"$DEEPL_KEY\" ./deepl.sh -l \"$DEEPL_TARGET\" \"{query}\"</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string>deepl.sh</string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string>Translate to language \"{var:DEEPL_TARGET}\" using DeepL</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>DeepL Dictionary</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>AD7C89C1-0978-4469-B62F-245E595DE9BD</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t</array>\n\t<key>readme</key>\n\t<string>Using the keyword 'dl' will translate a sentence using deepl.com. You can configure the target language in the workflow configuration.\nTo avoid the error message 'too many requests', please configure your free (or paid) DeepL API key.</string>\n\t<key>uidata</key>\n\t<dict>\n\t\t<key>51AFB0E3-C777-4C5E-A677-3AF381488BCC</key>\n\t\t<dict>\n\t\t\t<key>colorindex</key>\n\t\t\t<integer>12</integer>\n\t\t\t<key>note</key>\n\t\t\t<string>Automatically update workflow to latest version.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>400</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>460</integer>\n\t\t</dict>\n\t\t<key>5233F7C8-9221-45A4-BDE0-DE53175096E1</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Use this keyword to start the translation to an alternative hard coded language.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>210</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>30</integer>\n\t\t</dict>\n\t\t<key>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Copy translated text to the clipboard.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>490</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>270</integer>\n\t\t</dict>\n\t\t<key>84FE56AF-330C-4BB8-85E6-34859AAB73A7</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Send any selected text to the translator using this hotkey.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>40</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>300</integer>\n\t\t</dict>\n\t\t<key>91D16594-908E-4665-A005-0B715D96E5C2</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Use this keyword to start the translation to the configured language.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>220</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>300</integer>\n\t\t</dict>\n\t\t<key>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Show translation as large text.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>480</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>30</integer>\n\t\t</dict>\n\t\t<key>AD7C89C1-0978-4469-B62F-245E595DE9BD</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Use this keyword to start the translation to the configured language.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>40</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>490</integer>\n\t\t</dict>\n\t\t<key>CAA19D9E-04B6-4AD4-A8DC-0B683215DD14</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Send any selected text to the translator using this hotkey.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>30</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>40</integer>\n\t\t</dict>\n\t\t<key>D7D47F17-02DB-4A30-8F14-C03CBD051929</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Show a notifciation when text was copied to the clipboard.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<integer>680</integer>\n\t\t\t<key>ypos</key>\n\t\t\t<integer>270</integer>\n\t\t</dict>\n\t</dict>\n\t<key>variables</key>\n\t<dict>\n\t\t<key>DEEPL_KEY</key>\n\t\t<string></string>\n\t\t<key>DEEPL_POSTFIX</key>\n\t\t<string>.</string>\n\t\t<key>DEEPL_PREFERRED</key>\n\t\t<string>[\"DE\", \"EN\"]</string>\n\t\t<key>DEEPL_PRO</key>\n\t\t<string>0</string>\n\t\t<key>DEEPL_SOURCE</key>\n\t\t<string>auto</string>\n\t\t<key>DEEPL_TARGET</key>\n\t\t<string>en</string>\n\t</dict>\n\t<key>version</key>\n\t<string>1.11</string>\n\t<key>webaddress</key>\n\t<string>https://github.com/AlexanderWillner/deepl-alfred-workflow2</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "info5.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>bundleid</key>\n\t<string>ws.willner.alex.alfred.deepl</string>\n\t<key>category</key>\n\t<string>Productivity</string>\n\t<key>connections</key>\n\t<dict>\n\t\t<key>5233F7C8-9221-45A4-BDE0-DE53175096E1</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>1048576</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>D7D47F17-02DB-4A30-8F14-C03CBD051929</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>84FE56AF-330C-4BB8-85E6-34859AAB73A7</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>91D16594-908E-4665-A005-0B715D96E5C2</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>91D16594-908E-4665-A005-0B715D96E5C2</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>1048576</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>AD7C89C1-0978-4469-B62F-245E595DE9BD</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>1048576</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>B8B726E5-529C-4F1A-902E-A66B1589922D</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>DA3683E7-31BA-4DE1-9796-2EAB971CA593</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>CAA19D9E-04B6-4AD4-A8DC-0B683215DD14</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>5233F7C8-9221-45A4-BDE0-DE53175096E1</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t\t<key>DA3683E7-31BA-4DE1-9796-2EAB971CA593</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>destinationuid</key>\n\t\t\t\t<string>AD7C89C1-0978-4469-B62F-245E595DE9BD</string>\n\t\t\t\t<key>modifiers</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>modifiersubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>vitoclose</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t</array>\n\t</dict>\n\t<key>createdby</key>\n\t<string>Alexander Willner</string>\n\t<key>description</key>\n\t<string>Translation using deepl.com</string>\n\t<key>disabled</key>\n\t<false/>\n\t<key>name</key>\n\t<string>Deepl-Translate</string>\n\t<key>objects</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alignment</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>backgroundcolor</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>fadespeed</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>fillmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>font</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>ignoredynamicplaceholders</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>largetypetext</key>\n\t\t\t\t<string>{query}</string>\n\t\t\t\t<key>textcolor</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>wrapat</key>\n\t\t\t\t<integer>50</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.output.largetype</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dl-to-en</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string>Translating to language \"EN\" using DeepL ...</string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>./deepl.sh -l \"EN\" \"{query}\"\n</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string>deepl.sh</string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string>Translate to language \"EN\" using DeepL</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>DeepL Dictionary</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>5233F7C8-9221-45A4-BDE0-DE53175096E1</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>action</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argument</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>focusedappvariable</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>focusedappvariablename</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>hotkey</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>hotmod</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>leftcursor</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>modsmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>relatedAppsMode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.trigger.hotkey</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>CAA19D9E-04B6-4AD4-A8DC-0B683215DD14</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>2</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>autopaste</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>clipboardtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>ignoredynamicplaceholders</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>transient</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.output.clipboard</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>lastpathcomponent</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>onlyshowifquerypopulated</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>removeextension</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>text</key>\n\t\t\t\t<string>{query}</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>Copied to clipboard:</string>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.output.notification</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>D7D47F17-02DB-4A30-8F14-C03CBD051929</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>1</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>action</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argument</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>focusedappvariable</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>focusedappvariablename</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>hotkey</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>hotmod</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>leftcursor</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>modsmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>relatedAppsMode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.trigger.hotkey</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>84FE56AF-330C-4BB8-85E6-34859AAB73A7</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>2</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dl-to-de</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string>Translating to language \"de\" using DeepL ...</string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>DEEPL_KEY=\"$DEEPL_KEY\" ./deepl.sh -l \"de\" \"{query}\"</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string>deepl.sh</string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string>Translate to language \"de\" using DeepL</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>DeepL Dictionary</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>91D16594-908E-4665-A005-0B715D96E5C2</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>2</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dll</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<true/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>langs=(${(s/,/)${DEEPL_PREFERRED//[\\[\\]\\\" ]/}})\n\nout=''\nfor file in $langs; do\n\tout=\"${out:+$out,}{\\\"title\\\":\\\"$file\\\",\\\"arg\\\":\\\"$file\\\"}\"\ndone\n\necho \"{\\\"items\\\":[$out]}\"</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>Select Language</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>11</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<false/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>B8B726E5-529C-4F1A-902E-A66B1589922D</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>alfredfiltersresults</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>alfredfiltersresultsmatchmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttreatemptyqueryasnil</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>argumenttrimmode</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>argumenttype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>escaping</key>\n\t\t\t\t<integer>102</integer>\n\t\t\t\t<key>keyword</key>\n\t\t\t\t<string>dl</string>\n\t\t\t\t<key>queuedelaycustom</key>\n\t\t\t\t<integer>3</integer>\n\t\t\t\t<key>queuedelayimmediatelyinitially</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>queuedelaymode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>queuemode</key>\n\t\t\t\t<integer>1</integer>\n\t\t\t\t<key>runningsubtext</key>\n\t\t\t\t<string>Translating to language \"{var:DEEPL_TARGET}\" using DeepL ...</string>\n\t\t\t\t<key>script</key>\n\t\t\t\t<string>DEEPL_KEY=\"$DEEPL_KEY\" ./deepl.sh -l \"$DEEPL_TARGET\" \"{query}\"</string>\n\t\t\t\t<key>scriptargtype</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>scriptfile</key>\n\t\t\t\t<string>deepl.sh</string>\n\t\t\t\t<key>subtext</key>\n\t\t\t\t<string>Translate to language \"{var:DEEPL_TARGET}\" using DeepL</string>\n\t\t\t\t<key>title</key>\n\t\t\t\t<string>DeepL Dictionary</string>\n\t\t\t\t<key>type</key>\n\t\t\t\t<integer>0</integer>\n\t\t\t\t<key>withspace</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.input.scriptfilter</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>AD7C89C1-0978-4469-B62F-245E595DE9BD</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>3</integer>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>argument</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>passthroughargument</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>variables</key>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>DEEPL_TARGET</key>\n\t\t\t\t\t<string>{query}</string>\n\t\t\t\t</dict>\n\t\t\t</dict>\n\t\t\t<key>type</key>\n\t\t\t<string>alfred.workflow.utility.argument</string>\n\t\t\t<key>uid</key>\n\t\t\t<string>DA3683E7-31BA-4DE1-9796-2EAB971CA593</string>\n\t\t\t<key>version</key>\n\t\t\t<integer>1</integer>\n\t\t</dict>\n\t</array>\n\t<key>readme</key>\n\t<string>Using the keyword 'dl' will translate a sentence using deepl.com. You can configure the target language in the workflow configuration.\nTo avoid the error message 'too many requests', please configure your free (or paid) DeepL API key.</string>\n\t<key>uidata</key>\n\t<dict>\n\t\t<key>5233F7C8-9221-45A4-BDE0-DE53175096E1</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Use this keyword to start the translation to an alternative hard coded language.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>300</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>30</real>\n\t\t</dict>\n\t\t<key>61BF4F8C-DC18-4BB4-8DDD-A87C45C0F79E</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Copy translated text to the clipboard.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>580</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>270</real>\n\t\t</dict>\n\t\t<key>84FE56AF-330C-4BB8-85E6-34859AAB73A7</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Send any selected text to the translator using this hotkey.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>130</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>300</real>\n\t\t</dict>\n\t\t<key>91D16594-908E-4665-A005-0B715D96E5C2</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Use this keyword to start the translation to the configured language.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>310</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>300</real>\n\t\t</dict>\n\t\t<key>A222FB0A-D703-4C45-9CB0-4EDEA3399BEF</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Show translation as large text.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>570</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>30</real>\n\t\t</dict>\n\t\t<key>AD7C89C1-0978-4469-B62F-245E595DE9BD</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Use this keyword to start the translation to the configured language.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>310</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>500</real>\n\t\t</dict>\n\t\t<key>B8B726E5-529C-4F1A-902E-A66B1589922D</key>\n\t\t<dict>\n\t\t\t<key>xpos</key>\n\t\t\t<real>30</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>500</real>\n\t\t</dict>\n\t\t<key>CAA19D9E-04B6-4AD4-A8DC-0B683215DD14</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Send any selected text to the translator using this hotkey.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>120</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>40</real>\n\t\t</dict>\n\t\t<key>D7D47F17-02DB-4A30-8F14-C03CBD051929</key>\n\t\t<dict>\n\t\t\t<key>note</key>\n\t\t\t<string>Show a notifciation when text was copied to the clipboard.</string>\n\t\t\t<key>xpos</key>\n\t\t\t<real>770</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>270</real>\n\t\t</dict>\n\t\t<key>DA3683E7-31BA-4DE1-9796-2EAB971CA593</key>\n\t\t<dict>\n\t\t\t<key>xpos</key>\n\t\t\t<real>205</real>\n\t\t\t<key>ypos</key>\n\t\t\t<real>530</real>\n\t\t</dict>\n\t</dict>\n\t<key>userconfigurationconfig</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>placeholder</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>trim</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string>Get one at https://www.deepl.com/pro-api for higher limits.</string>\n\t\t\t<key>label</key>\n\t\t\t<string>API Key</string>\n\t\t\t<key>type</key>\n\t\t\t<string>textfield</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_KEY</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>text</key>\n\t\t\t\t<string>You have a professional DeepL account</string>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string></string>\n\t\t\t<key>label</key>\n\t\t\t<string>DeepL Pro</string>\n\t\t\t<key>type</key>\n\t\t\t<string>checkbox</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_PRO</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>placeholder</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>trim</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string>E.g., http://localhost:1188.</string>\n\t\t\t<key>label</key>\n\t\t\t<string>DeepLX Host</string>\n\t\t\t<key>type</key>\n\t\t\t<string>textfield</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_HOST</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string>default</string>\n\t\t\t\t<key>pairs</key>\n\t\t\t\t<array>\n\t\t\t\t\t<array>\n\t\t\t\t\t\t<string>More Formal</string>\n\t\t\t\t\t\t<string>prefer_more</string>\n\t\t\t\t\t</array>\n\t\t\t\t\t<array>\n\t\t\t\t\t\t<string>Less Formal</string>\n\t\t\t\t\t\t<string>prefer_less</string>\n\t\t\t\t\t</array>\n\t\t\t\t\t<array>\n\t\t\t\t\t\t<string>Default</string>\n\t\t\t\t\t\t<string>default</string>\n\t\t\t\t\t</array>\n\t\t\t\t</array>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string>Sets whether the translated text should lean towards formal or informal language.</string>\n\t\t\t<key>label</key>\n\t\t\t<string>Formality</string>\n\t\t\t<key>type</key>\n\t\t\t<string>popupbutton</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_FORMALITY</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string>[\"DE\", \"EN\"]</string>\n\t\t\t\t<key>placeholder</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>trim</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string></string>\n\t\t\t<key>label</key>\n\t\t\t<string>Preferred Languages</string>\n\t\t\t<key>type</key>\n\t\t\t<string>textfield</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_PREFERRED</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string>auto</string>\n\t\t\t\t<key>placeholder</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>trim</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string></string>\n\t\t\t<key>label</key>\n\t\t\t<string>Source Language</string>\n\t\t\t<key>type</key>\n\t\t\t<string>textfield</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_SOURCE</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string>en</string>\n\t\t\t\t<key>placeholder</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>trim</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string></string>\n\t\t\t<key>label</key>\n\t\t\t<string>Target Language</string>\n\t\t\t<key>type</key>\n\t\t\t<string>textfield</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_TARGET</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>config</key>\n\t\t\t<dict>\n\t\t\t\t<key>default</key>\n\t\t\t\t<string>.</string>\n\t\t\t\t<key>placeholder</key>\n\t\t\t\t<string></string>\n\t\t\t\t<key>required</key>\n\t\t\t\t<false/>\n\t\t\t\t<key>trim</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t\t<key>description</key>\n\t\t\t<string>Add this to the end of your query if you have not set an API key.</string>\n\t\t\t<key>label</key>\n\t\t\t<string>Query Postfix</string>\n\t\t\t<key>type</key>\n\t\t\t<string>textfield</string>\n\t\t\t<key>variable</key>\n\t\t\t<string>DEEPL_POSTFIX</string>\n\t\t</dict>\n\t</array>\n\t<key>variablesdontexport</key>\n\t<array/>\n\t<key>version</key>\n\t<string>2.2.2</string>\n\t<key>webaddress</key>\n\t<string>https://github.com/AlexanderWillner/deepl-alfred-workflow2</string>\n</dict>\n</plist>\n"
  }
]