Compare commits

..

4 Commits

Author SHA1 Message Date
Jules Aguillon
0ae2b73700 Set the 'action' role on number row, numpad and number pane
Some checks failed
Make Apk CI / Build-Apk (push) Has been cancelled
Check translations / check-translations (push) Has been cancelled
Check layouts / check_layout.output (push) Has been cancelled
Check layouts / Generated files (push) Has been cancelled
2025-02-09 14:17:29 +01:00
Jules Aguillon
4eb4abd66b check_layout.py: Check that some keys have a role 2025-02-09 14:10:39 +01:00
Jules Aguillon
de2076beaa Set 'role' for keys in builtin layouts 2025-02-09 14:10:39 +01:00
Jules Aguillon
f0c3a45352 Different color for action keys and space bar
Keys can be made darker or dimmer individually in layouts.
This is done by setting the new 'role' attributes. Roles are "normal",
"action" and "space_bar".

The "action" role is intended to be used for keys like shift, backspace
and other keys from the bottom row.

Themes and special layouts are updated.
2025-02-09 14:10:39 +01:00
165 changed files with 3641 additions and 5485 deletions

View File

@@ -11,7 +11,7 @@
<meta-data android:name="android.view.im" android:resource="@xml/method"/> <meta-data android:name="android.view.im" android:resource="@xml/method"/>
</service> </service>
<activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/settingsTheme" android:exported="true" android:directBootAware="true"> <activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@mipmap/ic_launcher" android:label="@string/settings_activity_label" android:theme="@style/settingsTheme" android:exported="true" android:directBootAware="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
</intent-filter> </intent-filter>

View File

@@ -190,46 +190,18 @@ As translations need to be updated regularly, you can subscribe to this issue
to receive a notification when an update is needed: to receive a notification when an update is needed:
https://github.com/Julow/Unexpected-Keyboard/issues/373 https://github.com/Julow/Unexpected-Keyboard/issues/373
### Adding symbols to Shift, Fn, Compose and other modifiers ### Adding Compose key sequences
New key combinations can be added to builtin modifiers in the following files: New Compose sequences can be added into `srcs/compose/compose/extra.json`.
If a entirely new family of sequences were to be added, a new `.json` file can
be created in the same directory to host them.
- Shift in `srcs/compose/shift.json`. ### Adding key combinations
- Fn in `srcs/compose/fn.json`.
- Compose in `srcs/compose/compose/extra.json`.
- Other modifiers are defined in the `accent_*.json` files in `srcs/compose`.
Generated code must then be updated by running: Key combinations are defined in `srcs/juloo.keyboard2/KeyModifier.java`.
For example, keys modified by the `Fn` key are defined in method
`apply_fn_char`.
``` Keys with special meaning are defined in `KeyValue.java` in method
./gradlew compileComposeSequences `getKeyByName`. Their special action are defined in `KeyEventHandler.java` in
``` method `key_up`
These files describe each symbols that get transformed when a given modifier is
activated, in JSON format. For example:
Example from `fn.json`, when `Fn` is activated, `<` becomes `«`:
```json
{
"<": "«",
}
```
The result of a sequence can be a key name. See the list of key names in
[doc/Possible-key-values.md](doc/Possible-key-values.md). For example from
`fn.json`, when `Fn` is activated, space becomes `nbsp`:
```json
{
" ": "nbsp",
}
```
Compose sequences are made of several steps. For example, the sequence
`Compose V s = Š` is defined as:
```json
{
"V": {
"s": "Š"
}
}
```

View File

@@ -1,4 +1,4 @@
# Unexpected Keyboard [<img src="https://hosted.weblate.org/widget/unexpected-keyboard/svg-badge.svg" alt="État de la traduction" />](https://hosted.weblate.org/engage/unexpected-keyboard/) # Unexpected Keyboard
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" [<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid" alt="Get it on F-Droid"
@@ -24,14 +24,7 @@ Usage: to apply the symbols located in the corners of each key, slide your finge
| --- | --- | --- | | --- | --- | --- |
| <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot-4" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png" alt="Screenshot-5" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png" alt="Screenshot-6" /> | | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot-4" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png" alt="Screenshot-5" /> | <img src="/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png" alt="Screenshot-6" /> |
## Help translate the application
Improve the application translations [using Weblate](https://hosted.weblate.org/engage/unexpected-keyboard/).
[<img src="https://hosted.weblate.org/widget/unexpected-keyboard/multi-auto.svg" alt="État de la traduction" />](https://hosted.weblate.org/engage/unexpected-keyboard/)
## Similar apps ## Similar apps
* [Calculator++](https://git.bubu1.eu/Bubu/android-calculatorpp) - Calculator with a similar UX, swipe to corners for advanced math symbols and operators. * [Calculator++](https://git.bubu1.eu/Bubu/android-calculatorpp) - Calculator with a similar UX, swipe to corners for advanced math symbols and operators.
## Contributing ## Contributing

Binary file not shown.

View File

@@ -1,23 +1,21 @@
plugins { plugins {
id 'com.android.application' version '8.6.0' id 'com.android.application' version '8.1.1'
} }
dependencies { dependencies {
implementation "androidx.window:window-java:1.3.0"
implementation "androidx.core:core:1.16.0"
testImplementation "junit:junit:4.13.2" testImplementation "junit:junit:4.13.2"
} }
android { android {
namespace 'juloo.keyboard2' namespace 'juloo.keyboard2'
compileSdk 35 compileSdk 34
defaultConfig { defaultConfig {
applicationId "juloo.keyboard2" applicationId "juloo.keyboard2"
minSdk 21 minSdk 21
targetSdkVersion 35 targetSdkVersion 35
versionCode 48 versionCode 46
versionName "1.31.1" versionName "1.30.3"
} }
sourceSets { sourceSets {
@@ -84,8 +82,8 @@ android {
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_7
} }
lintOptions { lintOptions {

View File

@@ -8,15 +8,30 @@ arab_pc_ir: Layout includes some ASCII punctuation but not all, missing: ", %, '
beng_national: Layout includes some ASCII punctuation but not all, missing: $ beng_national: Layout includes some ASCII punctuation but not all, missing: $
beng_provat: Layout includes some ASCII punctuation but not all, missing: $, &, *, ., /, <, >, [, \, ], `, {, |, } beng_provat: Layout includes some ASCII punctuation but not all, missing: $, &, *, ., /, <, >, [, \, ], `, {, |, }
cyrl_yaverti: Layout includes some ASCII punctuation but not all, missing: ~ cyrl_yaverti: Layout includes some ASCII punctuation but not all, missing: ~
cyrl_yqukeng_tj: These keys are now added automatically, unexpected: f11_placeholder, f12_placeholder
cyrl_yxukeng_os: Layout includes some ASCII punctuation but not all, missing: ", #, $, &, ', @, [, ], ~ cyrl_yxukeng_os: Layout includes some ASCII punctuation but not all, missing: ", #, $, &, ', @, [, ], ~
deva_alt: Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', (, ), *, +, ., /, :, <, =, >, [, \, ], ^, _, `, {, |, }, ~ cyrl_yxukeng_os: These keys are now added automatically, unexpected: f11_placeholder, f12_placeholder
deva_alt: Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', (, ), +, ., /, :, <, =, >, [, \, ], ^, _, `, {, |, }, ~
deva_inscript: Duplicate keys: ।
deva_inscript: Layout includes some ASCII punctuation but not all, missing: ", $, ', ^, _, `, | deva_inscript: Layout includes some ASCII punctuation but not all, missing: ", $, ', ^, _, `, |
deva_phonetic_in: Duplicate keys: ट
grek_qwerty: Duplicate keys: ;
guj_phonetic_in: Duplicate keys: ટ, ડ
hebr_1_il: Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, } hebr_1_il: Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
hebr_2_il: Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, } hebr_2_il: Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
kann_kannada: Layout includes some ASCII punctuation but not all, missing: #, $, %, (, ), *, +, /, <, =, >, [, \, ], ^, `, {, |, }, ~ kann_kannada: Layout includes some ASCII punctuation but not all, missing: #, $, %, (, ), *, +, /, <, =, >, [, \, ], ^, `, {, |, }, ~
latn_bepo_fr: Missing important key, missing: loc capslock
latn_bone: Missing important key, missing: loc capslock
latn_bone: Missing programming keys, missing: loc esc, loc tab
latn_bone: Layout redefines the bottom row but some important keys are missing, missing: cursor_left, cursor_right, loc compose, loc end, loc home, loc page_down, loc page_up, loc switch_clipboard, loc switch_greekmath, loc voice_typing, switch_backward
latn_colemak: Some keys contain whitespaces, unexpected: ́ latn_colemak: Some keys contain whitespaces, unexpected: ́
latn_dvorak: Missing important key, missing: loc capslock latn_dvorak: Missing important key, missing: loc capslock
latn_neo2: Layout redefines the bottom row but some important keys are missing, missing: loc switch_clipboard latn_neo2: Layout redefines the bottom row but some important keys are missing, missing: loc switch_clipboard
latn_qwerty_se: Duplicate keys: !, ', ,, -, ., ?
latn_qwerty_tly: Duplicate keys: a, c, j, q
latn_qwerty_tly: Missing programming keys, missing: loc esc, loc tab
latn_qwertz_cz_multifunctional: Layout includes some ASCII punctuation but not all, missing: ` latn_qwertz_cz_multifunctional: Layout includes some ASCII punctuation but not all, missing: `
latn_qwertz_sk: Layout includes some ASCII punctuation but not all, missing: ` latn_qwertz_sk: Layout includes some ASCII punctuation but not all, missing: `
urdu_phonetic_ur: Duplicate keys:
urdu_phonetic_ur: Layout includes some ASCII punctuation but not all, missing: <, >, ?, `, |, ~ urdu_phonetic_ur: Layout includes some ASCII punctuation but not all, missing: <, >, ?, `, |, ~
urdu_phonetic_ur: Some keys contain whitespaces, unexpected:

View File

@@ -1,5 +1,5 @@
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import sys, os, glob, re import sys, os, glob
layout_file_name = 0 layout_file_name = 0
warnings = [] warnings = []
@@ -15,9 +15,6 @@ KEY_ATTRIBUTES = set([
"c", "nw", "ne", "sw", "se", "w", "e", "n", "s" "c", "nw", "ne", "sw", "se", "w", "e", "n", "s"
]) ])
# Keys defined in KeyValue.java
known_keys = set()
def warn(msg): def warn(msg):
global warnings global warnings
warnings.append("%s: %s" % (layout_file_name, msg)) warnings.append("%s: %s" % (layout_file_name, msg))
@@ -43,37 +40,50 @@ def unexpected_keys(keys, symbols, msg):
if len(unexpected) > 0: if len(unexpected) > 0:
warn("%s, unexpected: %s" % (msg, key_list_str(unexpected))) warn("%s, unexpected: %s" % (msg, key_list_str(unexpected)))
# Write to [keys] and [dup]. def duplicates(keys):
def parse_row_from_et(row, keys, dup): dup = [ k for k, key_elts in keys.items() if len(key_elts) >= 2 ]
for key in row: if len(dup) > 0:
for attr in key.keys(): warn("Duplicate keys: " + key_list_str(dup))
def should_have_role(keys_map, role, keys):
def is_center_key(key):
def center(key_elt): return key_elt.get("key0", key_elt.get("c"))
return any(( center(key_elt) == key for key_elt in keys_map.get(key, []) ))
def key_roles(key):
return ( key_elt.get("role", "normal") for key_elt in keys_map[key] )
for key in keys:
if is_center_key(key) and role not in key_roles(key):
warn("Key '%s' is not on a key with role=\"%s\"" % (key, role))
# Write to [keys], dict of keyvalue to the key elements they appear in
def parse_row_from_et(row, keys):
for key_elt in row:
for attr in key_elt.keys():
if attr in KEY_ATTRIBUTES: if attr in KEY_ATTRIBUTES:
k = key.get(attr).removeprefix("\\") k = key_elt.get(attr).removeprefix("\\")
if k in keys: dup.add(k) keys.setdefault(k, []).append(key_elt)
keys.add(k)
def parse_layout(fname): def parse_layout(fname):
keys = set() keys = {}
dup = set()
root = ET.parse(fname).getroot() root = ET.parse(fname).getroot()
if root.tag != "keyboard": if root.tag != "keyboard":
return None return None
for row in root: for row in root:
parse_row_from_et(row, keys, dup) parse_row_from_et(row, keys)
return root, keys, dup return root, keys
def parse_row(fname): def parse_row(fname):
keys = set() keys = {}
dup = set()
root = ET.parse(fname).getroot() root = ET.parse(fname).getroot()
if root.tag != "row": if root.tag != "row":
return None return None
parse_row_from_et(root, keys, dup) parse_row_from_et(root, keys)
return root, keys, dup return root, keys
def check_layout(layout): def check_layout(layout):
root, keys, dup = layout root, keys_map = layout
if len(dup) > 0: warn("Duplicate keys: " + key_list_str(dup)) keys = set(keys_map.keys())
duplicates(keys_map)
missing_some_of(keys, "~!@#$%^&*(){}`[]=\\-_;:/.,?<>'\"+|", "ASCII punctuation") missing_some_of(keys, "~!@#$%^&*(){}`[]=\\-_;:/.,?<>'\"+|", "ASCII punctuation")
missing_some_of(keys, "0123456789", "digits") missing_some_of(keys, "0123456789", "digits")
missing_required(keys, ["backspace", "delete"], "Layout doesn't define some important keys") missing_required(keys, ["backspace", "delete"], "Layout doesn't define some important keys")
@@ -94,8 +104,8 @@ def check_layout(layout):
missing_required(keys, ["shift", "loc capslock"], "Missing important key") missing_required(keys, ["shift", "loc capslock"], "Missing important key")
missing_required(keys, ["loc esc", "loc tab"], "Missing programming keys") missing_required(keys, ["loc esc", "loc tab"], "Missing programming keys")
_, bottom_row_keys, _ = parse_row("res/xml/bottom_row.xml") _, bottom_row_keys_map = parse_row("res/xml/bottom_row.xml")
bottom_row_keys = set(bottom_row_keys_map.keys())
if root.get("bottom_row") == "false": if root.get("bottom_row") == "false":
missing_required(keys, bottom_row_keys, missing_required(keys, bottom_row_keys,
"Layout redefines the bottom row but some important keys are missing") "Layout redefines the bottom row but some important keys are missing")
@@ -106,22 +116,9 @@ def check_layout(layout):
if root.get("script") == None: if root.get("script") == None:
warn("Layout doesn't specify a script.") warn("Layout doesn't specify a script.")
keys_without_loc = set(( k.removeprefix("loc ") for k in keys )) should_have_role(keys_map, "action",
# Keys with a len under 3 are often composed characters [ "shift", "ctrl", "fn", "backspace", "enter" ])
special_keys = set(( k for k in keys_without_loc if len(k) > 3 and ":" not in k )) should_have_role(keys_map, "space_bar", [ "space" ])
unknown = special_keys.difference(known_keys)
if len(unknown) > 0:
warn("Layout contains unknown keys: %s" % key_list_str(unknown))
# Fill 'known_keys', which is used for some checks
def parse_known_keys():
global known_keys
with open("srcs/juloo.keyboard2/KeyValue.java", "r") as f:
known_keys = set(
( m.group(1) for m in re.finditer('case "([^"]+)":', f.read()) )
)
parse_known_keys()
for fname in sorted(glob.glob("srcs/layouts/*.xml")): for fname in sorted(glob.glob("srcs/layouts/*.xml")):
layout_id, _ = os.path.splitext(os.path.basename(fname)) layout_id, _ = os.path.splitext(os.path.basename(fname))

View File

@@ -52,11 +52,9 @@ The `<keyboard>`...`</keyboard>` pair follows the declaration tag and encloses t
* `locale_extra_keys`: Whether Unexpected should add language-dependent extra keys from [method.xml](../res/xml/method.xml) to this layout. It accepts `true` or `false`, and defaults to `true`. To disable these automatic additions, specify `locale_extra_keys="false"`. * `locale_extra_keys`: Whether Unexpected should add language-dependent extra keys from [method.xml](../res/xml/method.xml) to this layout. It accepts `true` or `false`, and defaults to `true`. To disable these automatic additions, specify `locale_extra_keys="false"`.
## Row ## Row
The `<row>`...`</row>` pair encloses one row on the keyboard. It has the following optional property: The `<row>`...`</row>` pair encloses one row on the keyboard. It has only one optional property:
* `height`: The height of the row: a positive floating-point value. * `height`: The height of the row: a positive floating-point value.
* `scale`: A positive floating-point value. If present, scale the width of each key so that the total is equal to the specified value, in key width unit.
A row's default height is 1.0 (one quarter of the keyboard height specified on the Settings menu). The `height` property makes the row taller or shorter than this. For example, if you define a 5-row keyboard but one row has `height="0.7"`, then the keyboard's total height is 4.7 units. If the total is different from 4.0, the keyboard will be taller or shorter than that specified in Settings. A row's default height is 1.0 (one quarter of the keyboard height specified on the Settings menu). The `height` property makes the row taller or shorter than this. For example, if you define a 5-row keyboard but one row has `height="0.7"`, then the keyboard's total height is 4.7 units. If the total is different from 4.0, the keyboard will be taller or shorter than that specified in Settings.
## Key ## Key

View File

@@ -1,73 +1,43 @@
# Key values # Key values
A key value defines what a key on the keyboard does when pressed or swiped. This is an exhaustive list of special values accepted for the `key0` through `key8` or `nw` through `se` attributes on a key.
Key values appear in the following places: Any string that does not exactly match these will be printed verbatim.
A key can output multiple characters, but cannot combine multiple built-in key values.
- In custom layouts, they are the value of: the `c` attribute, the compass-point attributes `nw` ... `se`, and the old-style `key0` ... `key8` attributes. ## Escape codes
- Internally, they are used in the definition of the "Add keys to the keyboard" setting. Value | Escape code for
Key values can be any of the following:
- The name of a special key. A complete list of valid special keys follows.
- An arbitrary sequence of characters not containing `:`.
This results in a key that writes the specified characters.
- The syntax `legend:key_def`.
`legend` is the visible legend on the keyboard. It cannot contain `:`.
`key_def` can be:
+ The name of a special key, as listed below.
+ `'string'` An arbitrary string that can contain `:`. `'` can be added to the string as `` \' ``.
+ `keyevent:keycode` An Android keycode. They are listed as `KEYCODE_...` in [KeyEvent](https://developer.android.com/reference/android/view/KeyEvent#summary).
Examples:
+ `⏯:keyevent:85` A play/pause key (which has no effect in most apps).
+ `my@:'my.email@domain.com'` A key that sends an arbitrary string
- A macro, `legend:key_def1,key_def2,...`.
This results in a key with legend `legend` that behaves as if the sequence of `key_def` had been pressed in order.
Examples:
+ `CA:ctrl,a,ctrl,c` A key with legend CA that sends the sequence `ctrl+a`, `ctrl+c`.
+ `Cd:ctrl,backspace` A key with legend Cd that sends the shortcut `ctrl+backspace`.
### Escape codes
When defining a key value, several characters have special effects. If you want a character not to have its usual effect but to be taken literally, you should "escape" it in the usual way for XML:
To get this character... | ...you can type
:---- | :------ :---- | :------
A literal newline character, which is different from `enter` and `action` in certain apps. | `\n` `\?` | `?`
A literal tab character, which is different from `tab` in certain apps. | `\t` `\#` | `#`
`&` | `&amp;` `\@` | `@`
`<` | `&lt;` `\n` | Literal newline character. This is different from `enter` and `action` in certain apps.
`>` | `&gt;` `\t` | Literal tab character. This is different from `tab` in certain apps.
`"` | `&quot;` `\\` | `\`
The characters `\` (unless followed by n or t), `?`, `#`, and `@` do not need to be escaped when writing custom layouts. When writing a layout to be included in the app (in [srcs/layouts](https://github.com/Julow/Unexpected-Keyboard/tree/master/srcs/layouts)), they are represented by typing `\\`, `\?`, `\#`, and `\@`. XML escape codes also work, including:
The characters `,` and `:` can be escaped in a key value, using single quotes. For example, this macro defines a key with legend `http` that sends a string containing `:`: `<key c="http:home,'https://'" />` For simplicity, `,` and `:` cannot be escaped in the key legend. Value | Escape code for
:------- | :------
`&amp;` | `&`
`&lt;` | `<`
`&gt;` | `>`
`&quot;` | `"`
## Modifiers ## Modifiers
System modifiers are sent to the app, which can take app-specific action. System modifiers are sent to the app, which is free to do whatever they want in response.
The other modifiers only exist within the keyboard.
Value | Meaning Value | Meaning
:---------- | :------ :---------- | :------
`shift` | System modifier. `shift` | System modifier.
`ctrl` | System modifier. `ctrl` | System modifier.
`alt` | System modifier. `alt` | System modifier.
`meta` | System modifier. Equivalent to the Windows key. `meta` | System modifier. Equivalent to the Windows key.
`fn` | Activates Fn mode, which assigns letters and symbols to special characters. e.g. `fn` `!` = `¡`
`compose` | Compose key. Enables composing characters using Linux-like shortcuts; e.g. `Compose` `A` `single quote` types `Á` (A with acute accent).
`capslock` | Actives and locks Shift
The other modifiers take effect only within the keyboard. ## Special keys
Value | Meaning
:---------- | :------
`fn` | Activates Fn mode, which assigns letters and symbols to special characters. Example: `fn` `!` = `¡`
`compose` | Compose key. Enables composing characters using Linux-like shortcuts. Example: `Compose` `A` `'` types `Á` (A with acute accent).
`capslock` | Activates and locks Shift.
## App function keys
These keys are sent to apps, which are free to ignore them. The keyboard does not perform editing in response to these keys. These keys are sent to apps, which are free to ignore them. The keyboard does not perform editing in response to these keys.
`esc`, `enter`, `esc`, `enter`,
@@ -83,19 +53,6 @@ These keys are sent to apps, which are free to ignore them. The keyboard does no
`selectAll`, `pasteAsPlainText`, `selectAll`, `pasteAsPlainText`,
`undo`, `redo` `undo`, `redo`
## Keyboard editing actions
In contrast, these keys perform editing on the text without sending anything to the app.
Value | Meaning
:-------------------- | :------
`cursor_left` | Moves the cursor to the left with the slider gesture.
`cursor_right` | Moves the cursor to the right with the slider gesture.
`cursor_up` | Moves the cursor up with the slider gesture. Warning: this might make the cursor leave the text box.
`cursor_down` | Moves the cursor down with the slider gesture. Warning: this might make the cursor leave the text box.
`delete_word` | Delete the word to the left of the cursor.
`forward_delete_word` | Delete the word to the right of the cursor.
The values with `cursor_` are new in v1.31.0. Previous custom layouts specified the slider with `slider="true"`, which should be removed.
## Whitespace ## Whitespace
Value | Meaning Value | Meaning
:------ | :------ :------ | :------
@@ -105,6 +62,15 @@ Value | Meaning
`zwj` | Zero-width joiner. `zwj` | Zero-width joiner.
`zwnj` | Zero-width non-joiner. `zwnj` | Zero-width non-joiner.
## Keyboard editing actions
These keys perform editing on the text without sending keys that the app can interpret differently or ignore.
Value | Meaning
:----------------- | :------
`cursor_left` | Moves the cursor to the left with the slider gesture.
`cursor_right` | Moves the cursor to the right with the slider gesture.
`cursor_up` | Moves the cursor up with the slider gesture. Warning: this might make the cursor leave the text box.
`cursor_down` | Moves the cursor down with the slider gesture. Warning: this might make the cursor leave the text box.
## Other modifiers and diacritics ## Other modifiers and diacritics
Value | Meaning Value | Meaning
:------------------- | :------ :------------------- | :------
@@ -186,3 +152,50 @@ These keys are known to do nothing.
These keys are normally hidden unless the Fn modifier is activated. These keys are normally hidden unless the Fn modifier is activated.
`f11_placeholder` | `f12_placeholder` `f11_placeholder` | `f12_placeholder`
## Complex keys
More complex keys are of this form:
```
:<kind> <attributes>:<payload>
```
Where `<kind>` is one of the kinds documented below and `<attributes>` is a
space separated list of attributes. `<payload>` depends on the `<kind>`.
Attributes are:
- `symbol='Sym'` specifies the symbol to be shown on the keyboard.
- `flags='<flags>'` changes the behavior of the key.
`<flags>` is a coma separated list of:
+ `dim`: Make the symbol dimmer.
+ `small`: Make the symbol smaller.
### Kind `str`
Defines a key that outputs an arbitrary string. `<payload>` is a string wrapped
in single-quotes (`'`), escaping of other single quotes is allowed with `\'`.
For example:
- `:str:'Arbitrary string with a \' inside'`
- `:str symbol='Symbol':'Output string'`
### Kind `char`
Defines a key that outputs a single character. `<payload>` is the character to
output, unquoted.
This kind of key can be used to define a character key with a different symbol
on it. `char` keys can be modified by `ctrl` and other modifiers, unlike `str`
keys.
For example:
- `:char symbol='љ':q`, which is used to implement `ctrl` shortcuts in cyrillic
layouts.
### Kind `keyevent`
Defines a key that sends an Android [key event](https://developer.android.com/reference/android/view/KeyEvent).
`<payload>` is the key event number.
For example:
- `:keyevent symbol='⏯' flags='small':85`

View File

@@ -1,8 +0,0 @@
Delete a word with a circle gesture on the delete key.
Compose key can be unselected.
Improved space bar slider and added selection mode.
Lock shift with a circle gesture.
Improvements to layouts.
Various bug fixes and improvements to themes.
Huge thanks to the contributors: @0skar2 @chuckwagoncomputing @dzaima @eandersons Lokesh Kumar @lrvideckis @ms-jagadeeshan @quantenzitrone @Sestowner @solokot @Spike-from-NH @srikanban @tenextractor

View File

@@ -1,9 +0,0 @@
Bug fixes
Delete a word with a circle gesture on the delete key.
Compose key can be unselected.
Improved space bar slider and added selection mode.
Lock shift with a circle gesture.
Various bug fixes and improvements to themes and layouts.
Many thanks to the contributors: @HaleyHalcyon @Jaoheah @Spike-from-NH

View File

@@ -1,91 +0,0 @@
{
"version": "v1.0.0",
"entity": {
"type": "individual",
"role": "owner",
"name": "Julow",
"email": "jules@j3s.fr",
"description": "Open source developer and maintainer of Unexpected Keyboard.",
"webpageUrl": {
"url": "https://github.com/Julow"
}
},
"projects": [
{
"guid": "unexpected-keyboard",
"name": "Unexpected Keyboard",
"description": "Lightweight and privacy-conscious virtual keyboard for Android.",
"webpageUrl": {
"url": "https://github.com/Julow/Unexpected-Keyboard/"
},
"repositoryUrl": {
"url": "https://github.com/Julow/Unexpected-Keyboard/"
},
"licenses": [
"spdx:GPL-3.0",
"spdx:CC0-1.0"
],
"tags": [
"android",
"mobile",
"privacy",
"productivity",
"programming",
"user-experience"
]
}
],
"funding": {
"channels": [
{
"guid": "liberapay",
"type": "other",
"address": "https://liberapay.com/Julow/",
"description": "Recurring donations for funding Unexpected Keyboard."
},
{
"guid": "github-sponsors",
"type": "other",
"address": "https://github.com/sponsors/Julow",
"description": "Recurring donations for funding Unexpected Keyboard."
},
{
"guid": "paypal",
"type": "other",
"address": "https://paypal.me/JulesAguillon",
"description": "One-time donations for funding Unexpected-keyboard."
}
],
"plans": [
{
"guid": "fund-maintenance",
"status": "active",
"name": "Fund developer time",
"description": "Help the maintainers spend time on Unexpected Keyboard",
"amount": 0,
"currency": "EUR",
"frequency": "monthly",
"channels": [
"liberapay",
"github-sponsors",
"paypal"
]
},
{
"guid": "one-time-contribution",
"status": "active",
"name": "Fund developer time",
"description": "Help the maintainers spend time on Unexpected Keyboard",
"amount": 0,
"currency": "EUR",
"frequency": "one-time",
"channels": [
"liberapay",
"github-sponsors",
"paypal"
]
}
],
"history": []
}
}

View File

@@ -1,524 +0,0 @@
#! /bin/env python3
"""
Script to generate a layout based on an existing.
Tuned to create Sinhala phonetic layout based on qwerty (US), but may be adoped
for other scripts. Look at dicts before the LayoutBuilder code.
Usage:
python3 gen_sinhala_phonetic_layout [-h|--help] [-v|--verbose] [-o|--output]
By default with no args will write to corresponding file in `srcs/layouts/`.
Script uses central symbol (in direction "c") to identify a key, which may not
be appropriate for base (reference) layouts other, than qwerty (US).
Warning will be printed to stderr if new symbol overrides some symbol of the
reference layout in directions other, than "c".
Exception will be rised on other
conflicts e. g. when trying to move a symbol into occupied position.
- Made with latn_qwerty_us.xml from commit `6b1551d`
- Made with Python 3.13
- Requires Python >= 3.11
"""
import argparse
import logging
from enum import StrEnum
from pathlib import Path
from xml.etree import ElementTree
class Placement(StrEnum):
C = 'c'
NW = 'nw'
N = 'n'
NE = 'ne'
E = 'e'
SE = 'se'
S = 's'
SW = 'sw'
W = 'w'
# Based on XKB Sinhala (phonetic)
KEYS_MAP: dict[str, tuple[str, str, str, str]] = {
# Row 1 ###########################################
'q': ('', '', '\u0DD8', '\u0DF2'),
'w': ('', '', '\u0DD0', '\u0DD1'),
'e': ('', '', '\u0DD9', '\u0DDA'),
'r': ('', '', '', ''), # In XKB virama is on layer 2
't': ('', '', '', ''),
'y': ('', '', '', ''), # In XKB virama is on layer 2
'u': ('', '', '\u0DD4', '\u0DD6'),
'i': ('', '', '\u0DD2', '\u0DD3'),
'o': ('', '', '\u0DDC', '\u0DDD'),
'p': ('', '', '', ''),
# Row 2 ###########################################
'a': ('', '', '\u0DCA', '\u0DCF'),
's': ('', '', '', ''),
'd': ('', '', '', ''),
'f': ('', '\u0D93', '', '\u0DDB'), # In XKB aiyanna placed otherwise
'g': ('', '', '', ''),
'h': ('', '\u0D83', '\u0DDE', ''),
'j': ('', '', '', ''),
'k': ('', '', '', ''),
'l': ('', '', '\u0DDF', '\u0DF3'),
# Row 3 ###########################################
'z': ('', '', '', ''), # In XKB contains bar, broken bar
'x': ('', '', '', ''),
'c': ('', '', '', ''),
'v': ('', '', '', ''),
'b': ('', '', '', ''),
'n': ('', '', '\u0D82', ''),
'm': ('', '', '', ''),
}
# How to place four levels of Key.
# Syntax: LEVEL: PLACEMENT | 'FROM_LEVEL+MODIFIER'
# The last means symbol on level FROM_LEVEL with modifier key MODIFIER gives
# key on level LEVEL
#
LEVELS_MAP = {
0: Placement.C,
1: Placement.NE,
2: '0+shift',
3: '1+shift',
}
# Additional modify keys combinations.
# Syntax:
# MODKEY: { A: B }
#
MODMAP_EXTRA: dict[str, dict[str, str]] = {
'shift': {
# Astrological numbers
'1': '',
'2': '',
'3': '',
'4': '',
'5': '',
'6': '',
'7': '',
'8': '',
'9': '',
'0': '',
# Kunddaliya
'.': '',
# Extra broken bar intead z key in XKB
'\u007C': '\u00A6',
# Special whitespaces
'zwj': 'zwnj',
},
'fn': {
# Sinhala archaic digits
'': '𑇡', # 1
'': '𑇢', # 2
'': '𑇣', # 3
'': '𑇤', # 4
'': '𑇥', # 5
'': '𑇦', # 6
'': '𑇧', # 7
'': '𑇨', # 8
'': '𑇩', # 9
'': '𑇪', # 10
'': '𑇫', # 20
'': '𑇬', # 30
'': '𑇭', # 40
'': '𑇮', # 50
'': '𑇯', # 60
'': '𑇰', # 70
'': '𑇱', # 80
'': '𑇲', # 90
'': '𑇳', # 100
'': '𑇴', # 1000
# Sinhala candrabindu for Sanskrit
'': '\u0D81',
},
}
# Table to move additional characters in reference layout.
# Format is (CENTRAL_CHAR, PLACEMENT): (CENTRAL_CHAR, PLACEMENT). E. g. to move
# char from key with central character "q", direction "se" to key with central
# character "w", direction "sw", add line:
# ('q', Placement.SE): ('w', Placement.SW),
#
# To delete a char, use None as destination placement. E.g.:
# ('q', Placment.SE): ('q', None)
#
# Moving of main char in central placement is not supported.
#
TRANSITIONS_MAP: dict[tuple[str, Placement], tuple[str, Placement | None]] = {
('q', Placement.SE): ('q', Placement.SW), # loc esc
('q', Placement.NE): ('q', Placement.SE), # 1
('w', Placement.NE): ('w', Placement.SE), # 2
('e', Placement.SE): ('r', Placement.NW), # loc €
('e', Placement.NE): ('e', Placement.SE), # 3
('r', Placement.NE): ('r', Placement.SE), # 4
('t', Placement.NE): ('t', Placement.SE), # 5
('y', Placement.NE): ('y', Placement.SE), # 6
('u', Placement.NE): ('u', Placement.SE), # 7
('i', Placement.NE): ('i', Placement.SE), # 8
('o', Placement.SE): ('p', Placement.SW), # )
('o', Placement.NE): ('o', Placement.SE), # 9
('p', Placement.NE): ('p', Placement.SE), # 0
('a', Placement.NE): ('a', Placement.NW), # `
('a', Placement.NW): ('a', Placement.SW), # loc tab
('s', Placement.NE): ('s', Placement.NW), # loc §
('g', Placement.SW): ('g', Placement.NW), # _
('g', Placement.NE): ('g', Placement.SW), # -
('h', Placement.SW): ('h', Placement.NW), # +
('h', Placement.NE): ('h', Placement.SW), # =
('l', Placement.NE): ('l', Placement.NW), # |
('x', Placement.NE): ('x', Placement.NW), # loc †
('c', Placement.NE): ('c', Placement.NW), # <
('b', Placement.NE): ('b', Placement.NW), # ?
('n', Placement.NE): ('n', Placement.NW), # :
('m', Placement.NE): ('m', Placement.NW), # "
}
# Add additional characters to arbitrary places.
# Syntax is CHAR: POSITION, where POSITION is a pari as in TRANSITIONS_MAP.
#
CHARS_EXTRA = {
# In XKB ZWJ is on `/` key, and ZWNJ is on spacebar
'zwj': ('m', Placement.SE),
}
# List of char unicode numbers and inclusive ranges of numbers to encode as XML
# numeric character references.
# Good for combining signs to not mess with quotes.
# Characters in line of the keyboard tag will not be escaped.
#
ESCAPE_LIST: list[int | tuple[int, int]] = [
# Sinhalese diacritics
(0xD81, 0xD83),
(0xDCA, 0xDDF),
]
# Default filename. Output path can be overrided with `-o` flag also.
LAYOUT_FILENAME = 'sinhala_phonetic.xml'
# Will be placed after XML declaration. Need to have proper <!-- --> tags.
COMMENT = '''
<!-- This file defines Sinhala layout.
Based on XKB Sinhala (phonetic) layout.
-->
'''
BASE_DIR = Path(__file__).parent
REFERENCE_LAYOUT_FILE = BASE_DIR / 'srcs/layouts/latn_qwerty_us.xml'
LOGGER = logging.getLogger(__name__)
KeysMapType = list[list[ElementTree.Element]]
class LayoutGenError(RuntimeError):
...
def xml_elem_to_str(element: ElementTree.Element) -> str:
return ElementTree.tostring(
element,
xml_declaration=False,
encoding='unicode').strip()
def keys_map_to_str(keys_map: KeysMapType) -> str:
""" Make laout rows map printable for debug purposes """
result = '[\n'
for row in keys_map:
result += ' ' * 4
for key in row:
result += str(key.attrib) + ', '
result += '\n'
result += ']'
return result
def is_in_escape_list(char: str | int) -> bool:
if isinstance(char, str):
char = ord(char)
for item in ESCAPE_LIST:
if isinstance(item, tuple) and char >= item[0] and char <= item[1]:
return True
elif isinstance(item, int):
if char == item:
return True
else:
TypeError(f'Unexpected item {item} of ESCAPE_LIST')
return False
def xml_encode_char(ch: str | int) -> str:
if isinstance(ch, str):
ch = ord(ch)
hex_val = hex(ch).split('x')[-1]
return f'&#x{hex_val.upper().zfill(4)};'
class LayoutBuilder:
XML_DECLARATION = "<?xml version='1.0' encoding='utf-8'?>"
def __init__(
self,
name: str = '',
script: str = '',
numpad_script: str = '',
comment: str = '',
) -> None:
"""
:param comment: MUST be a valid XML comment wrapped in <!-- tags -->
"""
attrs = {}
if name:
attrs['name'] = name
if script:
attrs['script'] = script
if numpad_script:
attrs['numpad_script'] = numpad_script
self._comment = None
if comment:
self._comment = comment.strip() or None
self._xml_keyboard = ElementTree.Element('keyboard', attrib=attrs)
self._modmap = ElementTree.Element('modmap')
@staticmethod
def _parse_reference_layout() -> list[ElementTree.Element]:
return ElementTree.parse(REFERENCE_LAYOUT_FILE).findall('row')
@staticmethod
def _move_untransited_to_new_map(
ref_map: KeysMapType,
new_map: KeysMapType
) -> None:
coordinates = [
(row_num, key_num)
for row_num in range(len(ref_map))
for key_num in range(len(ref_map[row_num]))
]
for row_num, key_num in coordinates:
old_key = ref_map[row_num][key_num]
new_key = new_map[row_num][key_num]
for k, val in old_key.attrib.items():
if (transited := new_key.attrib.get(k)) is not None:
msg = (
f'Transition of {transited} to'
f' {new_key.get(Placement.C)}:{k} conflictls with'
f' existing value "{val}"')
raise LayoutGenError(msg)
new_key.set(k, val)
@staticmethod
def _add_extra_chars_to_ref_map(
coord_map: dict[str, tuple[int, int]],
new_map: KeysMapType
) -> None:
for char, (to_key_name, to_plc) in CHARS_EXTRA.items():
if not (to_coord := coord_map.get(to_key_name)):
msg = f'Trying to add "{char}" to missing key "{to_key_name}"'
raise LayoutGenError(msg)
row_num, key_num = to_coord
key = new_map[row_num][key_num]
if (existing := key.get(to_plc)) is not None:
msg = f'Trying to add char to <{to_key_name}:{to_plc}>, but already contains "{existing}"'
raise LayoutGenError(msg)
key.set(to_plc, char)
LOGGER.info(
'Added "%s" to <%s:%s>',
char, to_key_name, to_plc)
@classmethod
def _apply_transitions(cls, ref_map: list) -> list:
coord_map: dict[str, tuple[int, int]] = {}
coordinates = [
(row_num, key_num)
for row_num in range(len(ref_map))
for key_num in range(len(ref_map[row_num]))
]
for row_num, key_num in coordinates:
row = ref_map[row_num]
key = row[key_num]
key_name = key.get(Placement.C)
if key_name in coord_map:
msg = f'Duplicated value "{key_name}" in central position'
raise LayoutGenError(msg)
coord_map[key_name] = (row_num, key_num)
# Make new map with empty keys
result_map = [[ElementTree.Element('key') for key in row] for row in ref_map]
# Place by transitions map on new places
for (from_key_name, from_plc), (to_key_name, to_plc) in TRANSITIONS_MAP.items():
if Placement.C in (from_plc, to_plc):
raise NotImplementedError('Transition from or to placment "c"')
if not (from_coord := coord_map.get(from_key_name)):
raise LayoutGenError(f'Transition from missing key {from_key_name}')
if not (to_coord := coord_map.get(to_key_name)):
raise LayoutGenError(f'Transition to missing key {to_key_name}')
from_key = ref_map[from_coord[0]][from_coord[1]]
to_key = result_map[to_coord[0]][to_coord[1]]
try:
val = from_key.attrib.pop(from_plc)
except KeyError:
msg = f'No value in key {from_key_name}, placement {from_plc} to move'
raise LayoutGenError(msg)
if to_plc is not None:
if to_key.get(to_plc):
msg = f'Second transition to key {to_key_name}, placement {to_plc}'
raise LayoutGenError(msg)
to_key.set(to_plc, val)
LOGGER.info(
'Moved "%s" from <%s:%s> to <%s:%s>',
val, from_key_name, from_plc, to_key_name, to_plc)
else:
LOGGER.info(
'Deleted "%s" from <%s:%s>',
val, from_key_name, from_plc)
# Fill new map with other values
cls._move_untransited_to_new_map(ref_map, new_map=result_map)
# Add additional characters
cls._add_extra_chars_to_ref_map(coord_map, new_map=result_map)
return result_map
@staticmethod
def _resolve_placement(
key: ElementTree.Element,
placement: Placement,
new_char: str
) -> None:
if placement != Placement.C:
central_char = key.get(Placement.C)
existing = key.get(placement)
if existing:
LOGGER.warning(
'Placement %s of key %s already occupied with %s',
placement, central_char, existing)
key.set(placement, new_char)
def _process_key(self, key: ElementTree.Element) -> ElementTree.Element:
central_char = key.get(Placement.C)
if not central_char:
return key
new_key_entry = KEYS_MAP.get(central_char)
if new_key_entry is None:
return key
for level, placement_spec in LEVELS_MAP.items():
if not (new_char := new_key_entry[level]):
continue
if '+' in placement_spec:
pair = placement_spec.split('+')
from_level, modkey = int(pair[0]), pair[1]
key_a = new_key_entry[from_level]
key_b = new_char
if key_a is None:
raise LayoutGenError(f'Tried to modife {key_a} to {key_b}')
ElementTree.SubElement(self._modmap, modkey, a=key_a, b=key_b)
else:
placement = Placement(placement_spec)
self._resolve_placement(key, placement=placement, new_char=new_char)
return key
@staticmethod
def _make_extra_modmap(modmap: ElementTree.Element) -> ElementTree.Element:
for modkey, ab_map in MODMAP_EXTRA.items():
for a, b in ab_map.items():
LOGGER.info('Adding modmap %s "%s" -> "%s"', modkey, a, b)
ElementTree.SubElement(modmap, modkey, a=a, b=b)
return modmap
@staticmethod
def _post_escape(data: str) -> str:
buf = ''
lines = data.splitlines(keepends=True)
for line in lines:
# Skip keyboard tag line to keep attributes
if '<keyboard ' in line:
buf += line
continue
for ch in line:
if is_in_escape_list(ch):
ch = xml_encode_char(ch)
buf += ch
return buf
def build(self) -> None:
raw_ref_rows = self._parse_reference_layout()
ref_rows = self._apply_transitions(raw_ref_rows)
for row in ref_rows:
new_row = ElementTree.SubElement(self._xml_keyboard, 'row')
for key in row:
LOGGER.debug(
'Processing reference entry %s',
xml_elem_to_str(key))
new_row.append(self._process_key(key))
self._modmap = self._make_extra_modmap(self._modmap)
self._xml_keyboard.append(self._modmap)
def get_xml(self) -> str:
ElementTree.indent(self._xml_keyboard)
body_raw = xml_elem_to_str(self._xml_keyboard)
body = self._post_escape(body_raw)
result = self.XML_DECLARATION + '\n'
if self._comment:
result += self._comment + '\n'
result += body + '\n'
return result
def get_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
prog='gen_sinhala_phonetic_layout',
description='Generate XKB-based Sinhala layout',)
parser.add_argument(
'-o',
'--output',
default=BASE_DIR / f'srcs/layouts/{LAYOUT_FILENAME}',
help='File to write result, `-` for stdout')
parser.add_argument(
'-v',
'--verbose',
help='More verbose logging',
action='store_true')
return parser.parse_args()
if __name__ == '__main__':
args = get_args()
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.WARNING,
format='%(levelname)s: %(message)s')
builder = LayoutBuilder(name='සිංහල', script='sinhala', comment=COMMENT)
builder.build()
content = builder.get_xml()
if args.output == '-':
print(content)
else:
with open(args.output, 'w') as file:
file.write(content)

View File

@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Dfile.encoding=UTF-8 org.gradle.jvmargs=-Dfile.encoding=UTF-8
android.useAndroidX=true android.useAndroidX=false
android.nonTransitiveRClass=true android.nonTransitiveRClass=true

View File

@@ -1,6 +1,6 @@
#Mon Aug 21 18:13:41 CEST 2023 #Mon Aug 21 18:13:41 CEST 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -3,15 +3,28 @@
<aapt:attr name="android:drawable"> <aapt:attr name="android:drawable">
<vector android:name="vector" android:width="35dp" android:height="40dp" android:viewportWidth="35" android:viewportHeight="40"> <vector android:name="vector" android:width="35dp" android:height="40dp" android:viewportWidth="35" android:viewportHeight="40">
<path android:name="trace" android:pathData="M 17.5 20 C 20 3 26 7 27.5 10" android:strokeColor="#09b3f1" android:strokeWidth="2" android:strokeLineCap="round"/> <path android:name="trace" android:pathData="M 17.5 20 C 20 3 26 7 27.5 10" android:strokeColor="#09b3f1" android:strokeWidth="2" android:strokeLineCap="round"/>
<group android:name="pointer_g" android:translateX="27" android:translateY="10"> <group android:name="pointer_g">
<path android:name="pointer" android:pathData="m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0" android:fillColor="#09b3f1" android:strokeColor="#09b3f1" android:strokeWidth="2"/> <path android:name="pointer" android:pathData="m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0" android:fillColor="#09b3f1" android:strokeColor="#09b3f1" android:strokeWidth="2" android:fillAlpha="0" android:strokeAlpha="0"/>
</group> </group>
</vector> </vector>
</aapt:attr> </aapt:attr>
<target android:name="trace"> <target android:name="trace">
<aapt:attr name="android:animation"> <aapt:attr name="android:animation">
<set> <set>
<objectAnimator android:propertyName="strokeAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator android:propertyName="trimPathEnd" android:duration="700" android:valueFrom="0" android:valueTo="1" android:interpolator="@android:interpolator/linear_out_slow_in"/> <objectAnimator android:propertyName="trimPathEnd" android:duration="700" android:valueFrom="0" android:valueTo="1" android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
</set>
</aapt:attr>
</target>
<target android:name="pointer">
<aapt:attr name="android:animation">
<set>
<objectAnimator android:propertyName="fillAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator android:propertyName="fillAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
</set> </set>
</aapt:attr> </aapt:attr>
</target> </target>

View File

@@ -2,14 +2,31 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable"> <aapt:attr name="android:drawable">
<vector android:name="vector" android:width="35dp" android:height="40dp" android:viewportWidth="35" android:viewportHeight="40"> <vector android:name="vector" android:width="35dp" android:height="40dp" android:viewportWidth="35" android:viewportHeight="40">
<path android:name="trace" android:pathData="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4" android:fillColor="#09b3f1" android:strokeColor="#09b3f1" android:strokeWidth="2" android:strokeLineCap="round"/> <path android:name="trace" android:pathData="M 0 0" android:fillColor="#09b3f1" android:strokeColor="#09b3f1" android:strokeWidth="2" android:strokeLineCap="round"/>
</vector> </vector>
</aapt:attr> </aapt:attr>
<target android:name="trace"> <target android:name="trace">
<aapt:attr name="android:animation"> <aapt:attr name="android:animation">
<set> <set>
<objectAnimator android:propertyName="pathData" android:duration="350" android:valueFrom="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 17.5,20.0" android:valueTo="M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4" android:valueType="pathType" android:interpolator="@android:interpolator/linear_out_slow_in"/> <objectAnimator android:propertyName="fillAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator android:propertyName="pathData" android:startOffset="400" android:duration="800" android:valueFrom="M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4" android:valueTo="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4" android:valueType="pathType" android:interpolator="@android:interpolator/linear_out_slow_in"/> <objectAnimator android:propertyName="strokeAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator
android:propertyName="pathData"
android:duration="350"
android:valueFrom="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 17.5,20.0"
android:valueTo="M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4"
android:valueType="pathType"
android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator
android:propertyName="pathData"
android:startOffset="400"
android:duration="800"
android:valueFrom="M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4"
android:valueTo="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31,4"
android:valueType="pathType"
android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator android:propertyName="fillAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
</set> </set>
</aapt:attr> </aapt:attr>
</target> </target>

View File

@@ -2,13 +2,23 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable"> <aapt:attr name="android:drawable">
<vector android:name="vector" android:width="35dp" android:height="40dp" android:viewportWidth="35" android:viewportHeight="40"> <vector android:name="vector" android:width="35dp" android:height="40dp" android:viewportWidth="35" android:viewportHeight="40">
<path android:name="trace" android:pathData=" M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31 ,4" android:fillColor="#09b3f1" android:strokeColor="#09b3f1" android:strokeWidth="2" android:strokeLineCap="round"/> <path android:name="trace" android:pathData="M 0 0" android:fillColor="#09b3f1" android:strokeColor="#09b3f1" android:strokeWidth="2" android:strokeLineCap="round"/>
</vector> </vector>
</aapt:attr> </aapt:attr>
<target android:name="trace"> <target android:name="trace">
<aapt:attr name="android:animation"> <aapt:attr name="android:animation">
<set> <set>
<objectAnimator android:propertyName="pathData" android:duration="700" android:valueFrom="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 17.5,20.0" android:valueTo=" M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31 ,4" android:valueType="pathType" android:interpolator="@android:interpolator/linear_out_slow_in"/> <objectAnimator android:propertyName="fillAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:duration="100" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/>
<objectAnimator
android:propertyName="pathData"
android:duration="700"
android:valueFrom="M 17.5 20.0 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 17.5,20.0"
android:valueTo=" M 31 4 m 2,0 a 2,2 0 1,1 -4,0 a 2,2 0 1,1 4,0 M 17.5 20.0 L 31 ,4"
android:valueType="pathType"
android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator android:propertyName="fillAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
<objectAnimator android:propertyName="strokeAlpha" android:startOffset="900" android:duration="400" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:interpolator="@android:interpolator/linear_out_slow_in"/>
</set> </set>
</aapt:attr> </aapt:attr>
</target> </target>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Klávesnice Unexpected</string> <string name="app_name_release">Klávesnice Unexpected</string>
<string name="app_name_debug">Klávesnice Unexpected (pro ladění)</string> <string name="app_name_debug">Klávesnice Unexpected (pro ladění)</string>
<string name="short_description">Nenáročná virtuální klávesnice pro vývojáře.</string> <string name="short_description">Nenáročná virtuální klávesnice pro vývojáře.</string>
<string name="store_description">Hlavní funkcí je možnost psát více znaků posunutím kláves směrem k rohům.\n\nTato aplikace byla původně navržena pro programátory používající Termux.\nNyní je ideální pro každodenní použití.\n\nTato aplikace neobsahuje žádné reklamy, nevyužívá připojení k síti a je Open Source.</string> <string name="store_description">"Hlavní funkcí je možnost psát více znaků posunutím kláves směrem k rohům.
Tato aplikace byla původně navržena pro programátory používající Termux.
Nyní je ideální pro každodenní použití.
Tato aplikace neobsahuje žádné reklamy, nevyužívá připojení k síti a je Open Source."</string>
<string name="settings_activity_label">Nastavení Klávesnice Unexpected</string>
<string name="pref_portrait">V režimu na výšku</string> <string name="pref_portrait">V režimu na výšku</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">V režimu na šířku</string> <string name="pref_landscape">V režimu na šířku</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Rozvržení</string> <string name="pref_category_layout">Rozvržení</string>
<string name="pref_label_brightness">Upravit jas nápisu</string> <string name="pref_label_brightness">Upravit jas nápisu</string>
<string name="pref_keyboard_opacity">Upravit průhlednost pozadí klávesnice</string> <string name="pref_keyboard_opacity">Upravit průhlednost pozadí klávesnice</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Rozložení %1$d: %2$s</string> <string name="pref_layouts_item">Rozložení %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Odebrat rozložení</string> <string name="pref_layouts_remove_custom">Odebrat rozložení</string>
<string name="pref_custom_layout_title">Vlastní rozložení</string> <string name="pref_custom_layout_title">Vlastní rozložení</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Zobrazit NumPad</string> <string name="pref_show_numpad_title">Zobrazit NumPad</string>
<string name="pref_show_numpad_never">Nikdy</string> <string name="pref_show_numpad_never">Nikdy</string>
<string name="pref_show_numpad_landscape">Pouze v režimu na šířku</string> <string name="pref_show_numpad_landscape">Pouze v režimu na šířku</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Vložit</string> <string name="key_descr_paste">Vložit</string>
<string name="key_descr_cut">Vyjmout</string> <string name="key_descr_cut">Vyjmout</string>
<string name="key_descr_selectAll">Označit vše</string> <string name="key_descr_selectAll">Označit vše</string>
<string name="key_descr_shareText">Sdílet text</string>
<string name="key_descr_pasteAsPlainText">Vložit jako prostý text</string> <string name="key_descr_pasteAsPlainText">Vložit jako prostý text</string>
<string name="key_descr_undo">Zpět</string> <string name="key_descr_undo">Zpět</string>
<string name="key_descr_redo">Znovu</string> <string name="key_descr_redo">Znovu</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">Správce schránky</string> <string name="key_descr_clipboard">Správce schránky</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Nedávno kopírovaný text</string> <string name="clipboard_history_heading">Nedávno kopírovaný text</string>
<string name="clipboard_pin_heading">Připnout</string> <string name="clipboard_pin_heading">Připnout</string>
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <string name="clipboard_remove_confirm">Odebrat ze schránky?</string>
<string name="clipboard_remove_confirmed">Ano</string> <string name="clipboard_remove_confirmed">Ano</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (Debug)</string> <string name="app_name_debug">Unexpected Keyboard (Debug)</string>
<string name="short_description">Eine schlanke, datenschutzfreundliche Bildschirmtastatur für Android.</string> <string name="short_description">Eine schlanke, datenschutzfreundliche Bildschirmtastatur für Android.</string>
<string name="store_description">Diese Tastatur zeichnet sich dadurch aus, dass man zusätzliche Zeichen durch Wischgesten in Richtung der Tastenecken eingeben kann.\n\nDie Anwendung wurde ursprünglich für das Programmieren in Termux entwickelt.\nMittlerweile ist sie auch für den täglichen Gebrauch perfekt geeignet.\n\nDiese App enthält keine Werbung, benötigt keinen Netzwerkzugriff und ist quelloffen.</string> <string name="store_description">"Diese Tastatur zeichnet sich dadurch aus, dass man zusätzliche Zeichen durch Wischgesten in Richtung der Tastenecken eingeben kann.
Die Anwendung wurde ursprünglich für das Programmieren in Termux entwickelt.
Mittlerweile ist sie auch für den täglichen Gebrauch perfekt geeignet.
Diese App enthält keine Werbung, benötigt keinen Netzwerkzugriff und ist quelloffen."</string>
<string name="settings_activity_label">Unexpected Keyboard - Einstellungen</string>
<string name="pref_portrait">Im Hochformatmodus</string> <string name="pref_portrait">Im Hochformatmodus</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">Im Querformatmodus</string> <string name="pref_landscape">Im Querformatmodus</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Layout</string> <string name="pref_category_layout">Layout</string>
<string name="pref_label_brightness">Helligkeit der Beschriftung anpassen</string> <string name="pref_label_brightness">Helligkeit der Beschriftung anpassen</string>
<string name="pref_keyboard_opacity">Deckkraft des Tastaturhintergrunds anpassen</string> <string name="pref_keyboard_opacity">Deckkraft des Tastaturhintergrunds anpassen</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Layout %1$d: %2$s</string> <string name="pref_layouts_item">Layout %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Layout entfernen</string> <string name="pref_layouts_remove_custom">Layout entfernen</string>
<string name="pref_custom_layout_title">Eigenes Layout</string> <string name="pref_custom_layout_title">Eigenes Layout</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Ziffernblock anzeigen</string> <string name="pref_show_numpad_title">Ziffernblock anzeigen</string>
<string name="pref_show_numpad_never">Nie</string> <string name="pref_show_numpad_never">Nie</string>
<string name="pref_show_numpad_landscape">Nur im Querformat</string> <string name="pref_show_numpad_landscape">Nur im Querformat</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Einfügen</string> <string name="key_descr_paste">Einfügen</string>
<string name="key_descr_cut">Ausschneiden</string> <string name="key_descr_cut">Ausschneiden</string>
<string name="key_descr_selectAll">Alles auswählen</string> <string name="key_descr_selectAll">Alles auswählen</string>
<string name="key_descr_shareText">Text teilen</string>
<string name="key_descr_pasteAsPlainText">Unformatiert einfügen</string> <string name="key_descr_pasteAsPlainText">Unformatiert einfügen</string>
<string name="key_descr_undo">Rückgängig</string> <string name="key_descr_undo">Rückgängig</string>
<string name="key_descr_redo">Wiederholen</string> <string name="key_descr_redo">Wiederholen</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">Ende</string> <string name="key_descr_end">Ende</string>
<string name="key_descr_clipboard">Clipboard-Manager</string> <string name="key_descr_clipboard">Clipboard-Manager</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Zuletzt kopierter Text</string> <string name="clipboard_history_heading">Zuletzt kopierter Text</string>
<string name="clipboard_pin_heading">Angeheftet</string> <string name="clipboard_pin_heading">Angeheftet</string>
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <string name="clipboard_remove_confirm">Aus der Zwischenablage entfernen?</string>
<string name="clipboard_remove_confirmed">Ja</string> <string name="clipboard_remove_confirmed">Ja</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (debug)</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="short_description">Un teclado virtual ligero para Android consciente de su privacidad.</string> <string name="short_description">Un teclado virtual ligero para Android consciente de su privacidad.</string>
<string name="store_description">La característica principal es que hay acceso a más caractéres deslizando hacia las esquinas de las teclas.\n\nEsta aplicación fue originalmente diseñada para programadores que usaran Termux.\nAhora es perfecta para uso cotidiano.\n\nLa misma no contiene ningún anuncio/publicidad, no realiza peticiones de red y es de Fuente Abierta.</string> <string name="store_description">"La característica principal es que hay acceso a más caractéres deslizando hacia las esquinas de las teclas.
Esta aplicación fue originalmente diseñada para programadores que usaran Termux.
Ahora es perfecta para uso cotidiano.
La misma no contiene ningún anuncio/publicidad, no realiza peticiones de red y es de Fuente Abierta."</string>
<string name="settings_activity_label">Ajustes de Unexpected Keyboard</string>
<string name="pref_portrait">En modo vertical</string> <string name="pref_portrait">En modo vertical</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">En modo horizontal</string> <string name="pref_landscape">En modo horizontal</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Distribución</string> <string name="pref_category_layout">Distribución</string>
<string name="pref_label_brightness">Ajustar brillo de etiqueta</string> <string name="pref_label_brightness">Ajustar brillo de etiqueta</string>
<string name="pref_keyboard_opacity">Ajustar opacidad del fondo del teclado</string> <string name="pref_keyboard_opacity">Ajustar opacidad del fondo del teclado</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Diseño %1$d: %2$s</string> <string name="pref_layouts_item">Diseño %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Quitar diseño</string> <string name="pref_layouts_remove_custom">Quitar diseño</string>
<string name="pref_custom_layout_title">Diseño personalizado</string> <string name="pref_custom_layout_title">Diseño personalizado</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Mostrar teclado numérico</string> <string name="pref_show_numpad_title">Mostrar teclado numérico</string>
<string name="pref_show_numpad_never">Nunca</string> <string name="pref_show_numpad_never">Nunca</string>
<string name="pref_show_numpad_landscape">Solo en modo horizontal</string> <string name="pref_show_numpad_landscape">Solo en modo horizontal</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Pegar</string> <string name="key_descr_paste">Pegar</string>
<string name="key_descr_cut">Cortar</string> <string name="key_descr_cut">Cortar</string>
<string name="key_descr_selectAll">Seleccionar todo</string> <string name="key_descr_selectAll">Seleccionar todo</string>
<string name="key_descr_shareText">Compartir texto</string>
<string name="key_descr_pasteAsPlainText">Pegar como texto sin formato</string> <string name="key_descr_pasteAsPlainText">Pegar como texto sin formato</string>
<string name="key_descr_undo">Deshacer</string> <string name="key_descr_undo">Deshacer</string>
<string name="key_descr_redo">Rehacer</string> <string name="key_descr_redo">Rehacer</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">Fin</string> <string name="key_descr_end">Fin</string>
<string name="key_descr_clipboard">Arreglar portapapeles</string> <string name="key_descr_clipboard">Arreglar portapapeles</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Textos recién copiados</string> <string name="clipboard_history_heading">Textos recién copiados</string>
<string name="clipboard_pin_heading">Pegado</string> <string name="clipboard_pin_heading">Pegado</string>
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <string name="clipboard_remove_confirm">¿Sacar este portapapeles?</string>
<string name="clipboard_remove_confirmed"></string> <string name="clipboard_remove_confirmed"></string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">صفحه کلید غیرمنتظره</string> <string name="app_name_release">صفحه کلید غیرمنتظره</string>
<string name="app_name_debug">صفحه کلید غیرمنتظره</string> <string name="app_name_debug">صفحه کلید غیرمنتظره</string>
<!-- <string name="short_description">Lightweight and privacy-conscious virtual keyboard for Android.</string> --> <!-- <string name="short_description">Lightweight and privacy-conscious virtual keyboard for Android.</string> -->
<!-- <string name="store_description">The main feature is that you can type more characters by swiping the keys towards the corners.\n\nThis application was originally designed for programmers using Termux.\nNow perfect for everyday use.\n\nThis application contains no ads, doesn\'t make any network requests and is Open Source.</string> --> <!-- <string name="store_description">"The main feature is that you can type more characters by swiping the keys towards the corners.
This application was originally designed for programmers using Termux.
Now perfect for everyday use.
This application contains no ads, doesn't make any network requests and is Open Source."</string> -->
<string name="settings_activity_label">تنظیمات صفحه کلید غیرمنتظره</string>
<string name="pref_portrait">در حالت عمودی</string> <string name="pref_portrait">در حالت عمودی</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">در حالت افقی</string> <string name="pref_landscape">در حالت افقی</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">طرح</string> <string name="pref_category_layout">طرح</string>
<string name="pref_label_brightness">تنظیم برچسب روشنایی</string> <string name="pref_label_brightness">تنظیم برچسب روشنایی</string>
<string name="pref_keyboard_opacity">تنظیم کدر بودن پس‌زمینه صفحه کلید</string> <string name="pref_keyboard_opacity">تنظیم کدر بودن پس‌زمینه صفحه کلید</string>
@@ -19,9 +23,6 @@
<!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> --> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<!-- <string name="pref_layouts_remove_custom">Remove layout</string> --> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_custom_layout_title">طرح شخصی</string> <string name="pref_custom_layout_title">طرح شخصی</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">نمایش پد شماره‌ها</string> <string name="pref_show_numpad_title">نمایش پد شماره‌ها</string>
<string name="pref_show_numpad_never">هرگز</string> <string name="pref_show_numpad_never">هرگز</string>
<string name="pref_show_numpad_landscape">فقط در حالت افقی</string> <string name="pref_show_numpad_landscape">فقط در حالت افقی</string>
@@ -107,6 +108,7 @@
<!-- <string name="key_descr_paste">Paste</string> --> <!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> --> <!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> --> <!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> --> <!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> --> <!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> --> <!-- <string name="key_descr_redo">Redo</string> -->
@@ -120,17 +122,12 @@
<!-- <string name="key_descr_end">End</string> --> <!-- <string name="key_descr_end">End</string> -->
<!-- <string name="key_descr_clipboard">Clipboard manager</string> --> <!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<!-- <string name="clipboard_history_heading">Recently copied text</string> --> <!-- <string name="clipboard_history_heading">Recently copied text</string> -->
<!-- <string name="clipboard_pin_heading">Pinned</string> --> <!-- <string name="clipboard_pin_heading">Pinned</string> -->
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
<!-- <string name="clipboard_remove_confirmed">Yes</string> --> <!-- <string name="clipboard_remove_confirmed">Yes</string> -->
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (debug)</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="short_description">Clavier virtuel léger et respectueux de la vie privée pour Android.</string> <string name="short_description">Clavier virtuel léger et respectueux de la vie privée pour Android.</string>
<string name="store_description">La fonctionnalité principale est l\'accès rapide à plus de caractères en balayant les touches vers les coins.\n\nCette application a été conçue à l\'origine pour les programmeurs utilisant Termux.\nElle est maintenant parfaite pour une utilisation quotidienne.\n\nCette application ne contient pas de publicité, n\'accède pas au réseau et est Open Source.</string> <string name="store_description">"La fonctionnalité principale est l'accès rapide à plus de caractères en balayant les touches vers les coins.
Cette application a été conçue à l'origine pour les programmeurs utilisant Termux.
Elle est maintenant parfaite pour une utilisation quotidienne.
Cette application ne contient pas de publicité, n'accède pas au réseau et est Open Source."</string>
<string name="settings_activity_label">Unexpected Keyboard Paramètres</string>
<string name="pref_portrait">En mode portrait</string> <string name="pref_portrait">En mode portrait</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">En mode landscape</string> <string name="pref_landscape">En mode landscape</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Disposition</string> <string name="pref_category_layout">Disposition</string>
<string name="pref_label_brightness">Luminosité des symboles</string> <string name="pref_label_brightness">Luminosité des symboles</string>
<string name="pref_keyboard_opacity">Transparence du clavier</string> <string name="pref_keyboard_opacity">Transparence du clavier</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Disposition %1$d: %2$s</string> <string name="pref_layouts_item">Disposition %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Supprimer</string> <string name="pref_layouts_remove_custom">Supprimer</string>
<string name="pref_custom_layout_title">Disposition personnalisée</string> <string name="pref_custom_layout_title">Disposition personnalisée</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Afficher le pavé numérique</string> <string name="pref_show_numpad_title">Afficher le pavé numérique</string>
<string name="pref_show_numpad_never">Jamais</string> <string name="pref_show_numpad_never">Jamais</string>
<string name="pref_show_numpad_landscape">Seulement en mode paysage</string> <string name="pref_show_numpad_landscape">Seulement en mode paysage</string>
@@ -65,12 +66,12 @@
<string name="pref_theme_e_altblack">Noir 2</string> <string name="pref_theme_e_altblack">Noir 2</string>
<string name="pref_theme_e_white">Blanc</string> <string name="pref_theme_e_white">Blanc</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<string name="pref_theme_e_desert">Désert</string> <string name="pref_theme_e_desert">Desert</string>
<string name="pref_theme_e_jungle">Jungle</string> <string name="pref_theme_e_jungle">Jungle</string>
<string name="pref_theme_e_monet">Monet (Système)</string> <string name="pref_theme_e_monet">Monet (Système)</string>
<string name="pref_theme_e_monetlight">Monet (Clair)</string> <string name="pref_theme_e_monetlight">Monet (Clair)</string>
<string name="pref_theme_e_monetdark">Monet (Sombre)</string> <string name="pref_theme_e_monetdark">Monet (Sombre)</string>
<string name="pref_theme_e_rosepine">Rosé Pine</string> <!-- <string name="pref_theme_e_rosepine">Rosé Pine</string> -->
<string name="pref_swipe_dist_e_very_short">Très courte</string> <string name="pref_swipe_dist_e_very_short">Très courte</string>
<string name="pref_swipe_dist_e_short">Courte</string> <string name="pref_swipe_dist_e_short">Courte</string>
<string name="pref_swipe_dist_e_default">Normale</string> <string name="pref_swipe_dist_e_default">Normale</string>
@@ -87,7 +88,7 @@
<string name="pref_circle_sensitivity_e_low">Basse</string> <string name="pref_circle_sensitivity_e_low">Basse</string>
<string name="pref_circle_sensitivity_e_disabled">Désactivée</string> <string name="pref_circle_sensitivity_e_disabled">Désactivée</string>
<string name="key_action_next">Suiv.</string> <string name="key_action_next">Suiv.</string>
<string name="key_action_done">Fini</string> <string name="key_action_done">Fin</string>
<string name="key_action_go">Aller</string> <string name="key_action_go">Aller</string>
<string name="key_action_prev">Prec.</string> <string name="key_action_prev">Prec.</string>
<string name="key_action_search">Chercher</string> <string name="key_action_search">Chercher</string>
@@ -96,10 +97,10 @@
<string name="launcher_button_imepicker">Selectionner le keyboard</string> <string name="launcher_button_imepicker">Selectionner le keyboard</string>
<string name="launcher_description">Cette application est un clavier virtuel. Activez-le dans les paramètres système en cliquant sur le bouton ci-dessous.</string> <string name="launcher_description">Cette application est un clavier virtuel. Activez-le dans les paramètres système en cliquant sur le bouton ci-dessous.</string>
<string name="launcher_sourcecode">Cette application est libre et open-source. Lisez le source code et reportez des problèmes sur Github.</string> <string name="launcher_sourcecode">Cette application est libre et open-source. Lisez le source code et reportez des problèmes sur Github.</string>
<string name="launcher_tryhere">Après l\'avoir activé, vous pouvez l\'essayer ici :</string> <string name="launcher_tryhere">Après l\'avoir activé, vous pouvez l\'essayer ici:</string>
<string name="launcher_tryhere_hint">Essayer ici</string> <string name="launcher_tryhere_hint">Essayer ici</string>
<string name="key_descr_capslock">Verrouillage majuscules</string> <string name="key_descr_capslock">Verrouillage majuscules</string>
<string name="key_descr_compose">Composition</string> <string name="key_descr_compose">Compose</string>
<string name="key_descr_switch_greekmath">Symboles mathématiques</string> <string name="key_descr_switch_greekmath">Symboles mathématiques</string>
<string name="key_descr_change_method">Changer de clavier</string> <string name="key_descr_change_method">Changer de clavier</string>
<string name="key_descr_voice_typing">Saisie vocale</string> <string name="key_descr_voice_typing">Saisie vocale</string>
@@ -107,9 +108,10 @@
<string name="key_descr_paste">Coller</string> <string name="key_descr_paste">Coller</string>
<string name="key_descr_cut">Couper</string> <string name="key_descr_cut">Couper</string>
<string name="key_descr_selectAll">Sel. tout</string> <string name="key_descr_selectAll">Sel. tout</string>
<string name="key_descr_shareText">Partager</string>
<string name="key_descr_pasteAsPlainText">Copier en texte brut</string> <string name="key_descr_pasteAsPlainText">Copier en texte brut</string>
<string name="key_descr_undo">Annuler</string> <string name="key_descr_undo">Undo</string>
<string name="key_descr_redo">Refaire</string> <string name="key_descr_redo">Redo</string>
<string name="key_descr_ª">Ordinal</string> <string name="key_descr_ª">Ordinal</string>
<string name="key_descr_º">Ordinal</string> <string name="key_descr_º">Ordinal</string>
<string name="key_descr_superscript">Exposant</string> <string name="key_descr_superscript">Exposant</string>
@@ -119,18 +121,13 @@
<string name="key_descr_home">Début</string> <string name="key_descr_home">Début</string>
<string name="key_descr_end">Fin</string> <string name="key_descr_end">Fin</string>
<string name="key_descr_clipboard">Presse-papiers</string> <string name="key_descr_clipboard">Presse-papiers</string>
<string name="key_descr_combining">Diacritique combinant</string> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<string name="key_descr_dead_key">Touche morte</string> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<string name="key_descr_zwj">Liant sans chasse</string> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<string name="key_descr_zwnj">Antiliant sans chasse</string> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<string name="key_descr_nbsp">Espace insécable</string> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<string name="key_descr_nnbsp">Espace fine insécable</string>
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Texte récemment copié</string> <string name="clipboard_history_heading">Texte récemment copié</string>
<string name="clipboard_pin_heading">Épinglé</string> <string name="clipboard_pin_heading">Épinglé</string>
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <string name="clipboard_remove_confirm">Supprimer ce presse-papiers ?</string>
<string name="clipboard_remove_confirmed">Oui</string> <string name="clipboard_remove_confirmed">Oui</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (debug)</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="short_description">Una Tastiera Virtuale Leggera Per La Programmazione</string> <string name="short_description">Una Tastiera Virtuale Leggera Per La Programmazione</string>
<!-- <string name="store_description">The main feature is that you can type more characters by swiping the keys towards the corners.\n\nThis application was originally designed for programmers using Termux.\nNow perfect for everyday use.\n\nThis application contains no ads, doesn\'t make any network requests and is Open Source.</string> --> <!-- <string name="store_description">"The main feature is that you can type more characters by swiping the keys towards the corners.
This application was originally designed for programmers using Termux.
Now perfect for everyday use.
This application contains no ads, doesn't make any network requests and is Open Source."</string> -->
<string name="settings_activity_label">Impostazioni di Unexpected Keyboard</string>
<!-- <string name="pref_portrait">In portrait mode</string> --> <!-- <string name="pref_portrait">In portrait mode</string> -->
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<!-- <string name="pref_landscape">In landscape mode</string> --> <!-- <string name="pref_landscape">In landscape mode</string> -->
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Layout</string> <string name="pref_category_layout">Layout</string>
<!-- <string name="pref_label_brightness">Adjust label brightness</string> --> <!-- <string name="pref_label_brightness">Adjust label brightness</string> -->
<!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> --> <!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> -->
@@ -19,9 +23,6 @@
<!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> --> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<!-- <string name="pref_layouts_remove_custom">Remove layout</string> --> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<!-- <string name="pref_custom_layout_title">Custom layout</string> --> <!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<!-- <string name="pref_show_numpad_title">Show NumPad</string> --> <!-- <string name="pref_show_numpad_title">Show NumPad</string> -->
<!-- <string name="pref_show_numpad_never">Never</string> --> <!-- <string name="pref_show_numpad_never">Never</string> -->
<!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> --> <!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> -->
@@ -107,6 +108,7 @@
<!-- <string name="key_descr_paste">Paste</string> --> <!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> --> <!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> --> <!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> --> <!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> --> <!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> --> <!-- <string name="key_descr_redo">Redo</string> -->
@@ -120,17 +122,12 @@
<!-- <string name="key_descr_end">End</string> --> <!-- <string name="key_descr_end">End</string> -->
<!-- <string name="key_descr_clipboard">Clipboard manager</string> --> <!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<!-- <string name="clipboard_history_heading">Recently copied text</string> --> <!-- <string name="clipboard_history_heading">Recently copied text</string> -->
<!-- <string name="clipboard_pin_heading">Pinned</string> --> <!-- <string name="clipboard_pin_heading">Pinned</string> -->
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
<!-- <string name="clipboard_remove_confirmed">Yes</string> --> <!-- <string name="clipboard_remove_confirmed">Yes</string> -->
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,16 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (Debug)</string> <string name="app_name_debug">Unexpected Keyboard (Debug)</string>
<string name="short_description">軽量でプライバシーに配慮したAndroid用仮想キーボード</string> <string name="short_description">軽量でプライバシーに配慮したAndroid用仮想キーボード</string>
<string name="store_description">このキーボードは、キーの角をスワイプすることで様々なキーを入力できます。\n\nこのアプリは元々はTermuxでのプログラミング用に設計されました。\nしかし、今では普段の入力にも適しています。\nPCキーボードでの半角入力を再現しています。日本語入力、変換は出来ません。\n\nこのアプリは広告を含まず、インターネットに接続せず、そしてオープンソースです。</string> <string name="store_description">"このキーボードは、キーの角をスワイプすることで様々なキーを入力できます。
このアプリは元々はTermuxでのプログラミング用に設計されました。
しかし、今では普段の入力にも適しています。
PCキーボードでの半角入力を再現しています。日本語入力、変換は出来ません。
このアプリは広告を含まず、インターネットに接続せず、そしてオープンソースです。"</string>
<string name="settings_activity_label">Unexpected Keyboardの設定</string>
<string name="pref_portrait">縦向き</string> <string name="pref_portrait">縦向き</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">横向き</string> <string name="pref_landscape">横向き</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">レイアウト</string> <string name="pref_category_layout">レイアウト</string>
<string name="pref_label_brightness">文字の明るさ</string> <string name="pref_label_brightness">文字の明るさ</string>
<string name="pref_keyboard_opacity">背景の不透明度</string> <string name="pref_keyboard_opacity">背景の不透明度</string>
@@ -19,9 +24,6 @@
<string name="pref_layouts_item">レイアウト %1$d: %2$s</string> <string name="pref_layouts_item">レイアウト %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">レイアウトを削除</string> <string name="pref_layouts_remove_custom">レイアウトを削除</string>
<string name="pref_custom_layout_title">カスタムレイアウト</string> <string name="pref_custom_layout_title">カスタムレイアウト</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">テンキーを表示</string> <string name="pref_show_numpad_title">テンキーを表示</string>
<string name="pref_show_numpad_never">表示しない</string> <string name="pref_show_numpad_never">表示しない</string>
<string name="pref_show_numpad_landscape">横向きの時は表示</string> <string name="pref_show_numpad_landscape">横向きの時は表示</string>
@@ -107,6 +109,7 @@
<string name="key_descr_paste">貼り付け</string> <string name="key_descr_paste">貼り付け</string>
<string name="key_descr_cut">切り取り</string> <string name="key_descr_cut">切り取り</string>
<string name="key_descr_selectAll">すべて選択</string> <string name="key_descr_selectAll">すべて選択</string>
<string name="key_descr_shareText">テキストを共有</string>
<string name="key_descr_pasteAsPlainText">書式なしで貼り付け</string> <string name="key_descr_pasteAsPlainText">書式なしで貼り付け</string>
<string name="key_descr_undo">元に戻す</string> <string name="key_descr_undo">元に戻す</string>
<string name="key_descr_redo">やり直し</string> <string name="key_descr_redo">やり直し</string>
@@ -120,17 +123,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">クリップボード</string> <string name="key_descr_clipboard">クリップボード</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">最近コピーしたテキスト</string> <string name="clipboard_history_heading">最近コピーしたテキスト</string>
<string name="clipboard_pin_heading">お気に入り</string> <string name="clipboard_pin_heading">お気に入り</string>
<string name="clipboard_remove_confirm">クリップボードから削除しますか?</string> <string name="clipboard_remove_confirm">クリップボードから削除しますか?</string>
<string name="clipboard_remove_confirmed">はい</string> <string name="clipboard_remove_confirmed">はい</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<!-- <string name="app_name_debug">Unexpected Keyboard (Debug)</string> --> <!-- <string name="app_name_debug">Unexpected Keyboard (Debug)</string> -->
<string name="short_description">개발자들을 위한 가벼운 가상 키보드.</string> <string name="short_description">개발자들을 위한 가벼운 가상 키보드.</string>
<string name="store_description">주요 기능은 모서리 방향으로 키를 스와이프하여 더 많은 문자를 입력할 수 있다는 것입니다.\n\n이 앱은 처음에는 Termux를 사용하는 프로그래머들을 위한 것으로 개발되었습니다.\n지금은 일상적인 용도로도 완벽합니다.\n\n이 응용 프로그램에는 광고가 없으며 네트워크 요청을 하지 않고 오픈 소스입니다.</string> <string name="store_description">"주요 기능은 모서리 방향으로 키를 스와이프하여 더 많은 문자를 입력할 수 있다는 것입니다.
이 앱은 처음에는 Termux를 사용하는 프로그래머들을 위한 것으로 개발되었습니다.
지금은 일상적인 용도로도 완벽합니다.
이 응용 프로그램에는 광고가 없으며 네트워크 요청을 하지 않고 오픈 소스입니다."</string>
<string name="settings_activity_label">Unexpected Keyboard 설정</string>
<string name="pref_portrait">세로 화면</string> <string name="pref_portrait">세로 화면</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">가로 화면</string> <string name="pref_landscape">가로 화면</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">레이아웃</string> <string name="pref_category_layout">레이아웃</string>
<string name="pref_label_brightness">라벨 밝기 조절</string> <string name="pref_label_brightness">라벨 밝기 조절</string>
<string name="pref_keyboard_opacity">키보드 배경 불투명도 조절</string> <string name="pref_keyboard_opacity">키보드 배경 불투명도 조절</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">레이아웃 %1$d: %2$s</string> <string name="pref_layouts_item">레이아웃 %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">레이아웃 제거</string> <string name="pref_layouts_remove_custom">레이아웃 제거</string>
<string name="pref_custom_layout_title">사용자 정의 레이아웃</string> <string name="pref_custom_layout_title">사용자 정의 레이아웃</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">NumPad 표시</string> <string name="pref_show_numpad_title">NumPad 표시</string>
<string name="pref_show_numpad_never">안 함</string> <string name="pref_show_numpad_never">안 함</string>
<string name="pref_show_numpad_landscape">가로 모드에서만</string> <string name="pref_show_numpad_landscape">가로 모드에서만</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">붙여넣기</string> <string name="key_descr_paste">붙여넣기</string>
<string name="key_descr_cut">자르기</string> <string name="key_descr_cut">자르기</string>
<string name="key_descr_selectAll">전부 선택</string> <string name="key_descr_selectAll">전부 선택</string>
<string name="key_descr_shareText">텍스트 공유</string>
<string name="key_descr_pasteAsPlainText">일반 텍스트로 붙여넣기</string> <string name="key_descr_pasteAsPlainText">일반 텍스트로 붙여넣기</string>
<string name="key_descr_undo">실행 취소</string> <string name="key_descr_undo">실행 취소</string>
<string name="key_descr_redo">다시 실행</string> <string name="key_descr_redo">다시 실행</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">종료</string> <string name="key_descr_end">종료</string>
<string name="key_descr_clipboard">클립보드 관리자</string> <string name="key_descr_clipboard">클립보드 관리자</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">최근에 복사한 텍스트</string> <string name="clipboard_history_heading">최근에 복사한 텍스트</string>
<string name="clipboard_pin_heading">고정</string> <string name="clipboard_pin_heading">고정</string>
<string name="clipboard_remove_confirm">이 클립보드를 제거하시겠습니까?</string> <string name="clipboard_remove_confirm">이 클립보드를 제거하시겠습니까?</string>
<string name="clipboard_remove_confirmed"></string> <string name="clipboard_remove_confirmed"></string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (atkļūdošana)</string> <string name="app_name_debug">Unexpected Keyboard (atkļūdošana)</string>
<string name="short_description">Mazizmēra un privātumu ievērojoša virtuālā Android tastatūra.</string> <string name="short_description">Mazizmēra un privātumu ievērojoša virtuālā Android tastatūra.</string>
<string name="store_description">Galvenā iezīme ir iespēja ievadīt vairāk rakstzīmju ar pavilkšanu uz taustiņu stūriem.\n\nŠī lietotne sākotnēji tika izstrādāta programmētājiem, kas izmanto Termux.\nTagad lieliski piemērota izmantošanai ikdienā.\n\nŠī lietotne nesatur reklāmas, neveic nekādus tīkla pieprasījumus, un tās pirmkods ir pieejams visiem.</string> <string name="store_description">"Galvenā iezīme ir iespēja ievadīt vairāk rakstzīmju ar pavilkšanu uz taustiņu stūriem.
Šī lietotne sākotnēji tika izstrādāta programmētājiem, kas izmanto Termux.
Tagad lieliski piemērota izmantošanai ikdienā.
Šī lietotne nesatur reklāmas, neveic nekādus tīkla pieprasījumus, un tās pirmkods ir pieejams visiem."</string>
<string name="settings_activity_label">Unexpected Keyboard iestatījumi</string>
<string name="pref_portrait">Stateniski</string> <string name="pref_portrait">Stateniski</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">Guleniski</string> <string name="pref_landscape">Guleniski</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Izkārtojums</string> <string name="pref_category_layout">Izkārtojums</string>
<string name="pref_label_brightness">Pielāgot iezīmju spilgtumu</string> <string name="pref_label_brightness">Pielāgot iezīmju spilgtumu</string>
<string name="pref_keyboard_opacity">Pielāgot tastatūras fona necaurredzamību</string> <string name="pref_keyboard_opacity">Pielāgot tastatūras fona necaurredzamību</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Izkārtojums %1$d: %2$s</string> <string name="pref_layouts_item">Izkārtojums %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Noņemt izkārtojumu</string> <string name="pref_layouts_remove_custom">Noņemt izkārtojumu</string>
<string name="pref_custom_layout_title">Pielāgots izkārtojums</string> <string name="pref_custom_layout_title">Pielāgots izkārtojums</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Rādīt ciparnīcu</string> <string name="pref_show_numpad_title">Rādīt ciparnīcu</string>
<string name="pref_show_numpad_never">Nekad</string> <string name="pref_show_numpad_never">Nekad</string>
<string name="pref_show_numpad_landscape">Tikai guleniskajā skatā</string> <string name="pref_show_numpad_landscape">Tikai guleniskajā skatā</string>
@@ -37,7 +38,7 @@
<string name="pref_category_typing">Rakstīšana</string> <string name="pref_category_typing">Rakstīšana</string>
<string name="pref_swipe_dist_title">Pavilkšanas attālums</string> <string name="pref_swipe_dist_title">Pavilkšanas attālums</string>
<string name="pref_swipe_dist_summary">Taustiņu stūros esošo rakstzīmju attālums (%s)</string> <string name="pref_swipe_dist_summary">Taustiņu stūros esošo rakstzīmju attālums (%s)</string>
<string name="pref_long_timeout_title">Ilgas piespiešanas noildze</string> <string name="pref_long_timeout_title">Ilgas piepiešanas noildze</string>
<string name="pref_long_interval_title">Taustiņa atkārtošanās aizture</string> <string name="pref_long_interval_title">Taustiņa atkārtošanās aizture</string>
<string name="pref_keyrepeat_enabled">Taustiņa atkārtošanās ar ilgu piespiešanu</string> <string name="pref_keyrepeat_enabled">Taustiņa atkārtošanās ar ilgu piespiešanu</string>
<string name="pref_lock_double_tap_title">Divkāršs piesitiens burtslēgam</string> <string name="pref_lock_double_tap_title">Divkāršs piesitiens burtslēgam</string>
@@ -94,8 +95,10 @@
<string name="key_action_send">Sūtīt</string> <string name="key_action_send">Sūtīt</string>
<string name="launcher_button_imesettings">Iespējot tastatūru</string> <string name="launcher_button_imesettings">Iespējot tastatūru</string>
<string name="launcher_button_imepicker">Izvēlēties tastatūru</string> <string name="launcher_button_imepicker">Izvēlēties tastatūru</string>
<string name="launcher_description">Šī lietotne ir virtuālā tastatūra. Ar zemāk esošo pogu var atvērt sistēmas iestatījumus un iespējot Unexpected Keyboard.</string> <string name="launcher_description">Šī lietotne ir virtuālā tastatūra.
<string name="launcher_sourcecode">Šī ir bezmaksas un atvērtā pirmkoda lietotne. GitHub var atrast pirmkodu un ziņot par nepilnībām.</string> Ar zemāk esošo pogu var atvērt sistēmas iestatījumus un iespējot Unexpected Keyboard.</string>
<string name="launcher_sourcecode">Šī ir bezmaksas un atvērtā pirmkoda lietotne.
GitHub var atrast pirmkodu un ziņot par nepilnībām.</string>
<string name="launcher_tryhere">Pēc iespējošanas šeit var izmēģināt tastatūru:</string> <string name="launcher_tryhere">Pēc iespējošanas šeit var izmēģināt tastatūru:</string>
<string name="launcher_tryhere_hint">Izmēģināt šeit</string> <string name="launcher_tryhere_hint">Izmēģināt šeit</string>
<string name="key_descr_capslock">Burtslēgs</string> <string name="key_descr_capslock">Burtslēgs</string>
@@ -107,6 +110,7 @@
<string name="key_descr_paste">Ielīmēt</string> <string name="key_descr_paste">Ielīmēt</string>
<string name="key_descr_cut">Izgriezt</string> <string name="key_descr_cut">Izgriezt</string>
<string name="key_descr_selectAll">Iezīmēt visu</string> <string name="key_descr_selectAll">Iezīmēt visu</string>
<string name="key_descr_shareText">Kopīgot tekstu</string>
<string name="key_descr_pasteAsPlainText">Ielīmēt kā vienkāršu tekstu</string> <string name="key_descr_pasteAsPlainText">Ielīmēt kā vienkāršu tekstu</string>
<string name="key_descr_undo">Atsaukt</string> <string name="key_descr_undo">Atsaukt</string>
<string name="key_descr_redo">Atatsaukt</string> <string name="key_descr_redo">Atatsaukt</string>
@@ -120,17 +124,12 @@
<string name="key_descr_end">Beigas</string> <string name="key_descr_end">Beigas</string>
<string name="key_descr_clipboard">Starpliktuves pārvaldnieks</string> <string name="key_descr_clipboard">Starpliktuves pārvaldnieks</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Nesen starpliktuvē ievietots teksts</string> <string name="clipboard_history_heading">Nesen starpliktuvē ievietots teksts</string>
<string name="clipboard_pin_heading">Piesprausts</string> <string name="clipboard_pin_heading">Piesprausts</string>
<string name="clipboard_remove_confirm">Noņemt šo starpliktuves vienumu?</string> <string name="clipboard_remove_confirm">Noņemt šo starpliktuves vienumu?</string>
<string name="clipboard_remove_confirmed"></string> <string name="clipboard_remove_confirmed"></string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (debug)</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="short_description">Lekka i dbająca o prywatność klawiatura wirtualna dla Androida.</string> <string name="short_description">Lekka i dbająca o prywatność klawiatura wirtualna dla Androida.</string>
<string name="store_description">Główną cechą tej klawiatury jest możliwość wprowadzania więcej znaków poprzez przesuwanie po klawiszach do ich rogów.\n\nTa aplikacja została pierwotnie zaprojektowana z myślą o programistach używających Termuxa.\nObecnie nadaje się doskonale do codziennego użytku.\n\nAplikacja nie zawiera reklam, nie żąda dostępu do internetu, a jej kod źródłowy jest dostępny publicznie.</string> <string name="store_description">"Główną cechą tej klawiatury jest możliwość wprowadzania więcej znaków poprzez przesuwanie po klawiszach do ich rogów.
Ta aplikacja została pierwotnie zaprojektowana z myślą o programistach używających Termuxa.
Obecnie nadaje się doskonale do codziennego użytku.
Aplikacja nie zawiera reklam, nie żąda dostępu do internetu, a jej kod źródłowy jest dostępny publicznie."</string>
<string name="settings_activity_label">Ustawienia Unexpected Keyboard</string>
<string name="pref_portrait">W widoku pionowym</string> <string name="pref_portrait">W widoku pionowym</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">W widoku poziomym</string> <string name="pref_landscape">W widoku poziomym</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Układ</string> <string name="pref_category_layout">Układ</string>
<string name="pref_label_brightness">Dostosuj jasność znaków</string> <string name="pref_label_brightness">Dostosuj jasność znaków</string>
<string name="pref_keyboard_opacity">Nieprzezroczystość tła klawiatury</string> <string name="pref_keyboard_opacity">Nieprzezroczystość tła klawiatury</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Układ %1$d: %2$s</string> <string name="pref_layouts_item">Układ %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Usuń układ</string> <string name="pref_layouts_remove_custom">Usuń układ</string>
<string name="pref_custom_layout_title">Własny układ</string> <string name="pref_custom_layout_title">Własny układ</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Pokaż klawiaturę numeryczną</string> <string name="pref_show_numpad_title">Pokaż klawiaturę numeryczną</string>
<string name="pref_show_numpad_never">Nigdy</string> <string name="pref_show_numpad_never">Nigdy</string>
<string name="pref_show_numpad_landscape">Tylko w orientacji poziomej</string> <string name="pref_show_numpad_landscape">Tylko w orientacji poziomej</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Wklej</string> <string name="key_descr_paste">Wklej</string>
<string name="key_descr_cut">Wytnij</string> <string name="key_descr_cut">Wytnij</string>
<string name="key_descr_selectAll">Zaznacz wszystko</string> <string name="key_descr_selectAll">Zaznacz wszystko</string>
<string name="key_descr_shareText">Udostępnij tekst</string>
<string name="key_descr_pasteAsPlainText">Wklej sam tekst</string> <string name="key_descr_pasteAsPlainText">Wklej sam tekst</string>
<string name="key_descr_undo">Cofnij</string> <string name="key_descr_undo">Cofnij</string>
<string name="key_descr_redo">Ponów</string> <string name="key_descr_redo">Ponów</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">Zarządzanie schowkiem</string> <string name="key_descr_clipboard">Zarządzanie schowkiem</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Ostatnio skopiowane elementy</string> <string name="clipboard_history_heading">Ostatnio skopiowane elementy</string>
<string name="clipboard_pin_heading">Przypięte</string> <string name="clipboard_pin_heading">Przypięte</string>
<string name="clipboard_remove_confirm">Usunąć ten element ze schowka?</string> <string name="clipboard_remove_confirm">Usunąć ten element ze schowka?</string>
<string name="clipboard_remove_confirmed">Tak</string> <string name="clipboard_remove_confirmed">Tak</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Teclado Unexpected</string> <string name="app_name_release">Teclado Unexpected</string>
<string name="app_name_debug">Teclado Unexpected</string> <string name="app_name_debug">Teclado Unexpected</string>
<string name="short_description">Um teclado virtual leve para desenvolvedores.</string> <string name="short_description">Um teclado virtual leve para desenvolvedores.</string>
<string name="store_description">A principal característica é que você pode digitar mais caracteres deslizando as teclas para os cantos.\n\nO app foi criado originalmente para desenvolvedores que usam Termux.\nAgora aperfeiçoado para o uso diário.\n\nEste aplicativo não contém anúncios, não faz nenhuma solicitação de rede e é Open Source.</string> <string name="store_description">"A principal característica é que você pode digitar mais caracteres deslizando as teclas para os cantos.
O app foi criado originalmente para desenvolvedores que usam Termux.
Agora aperfeiçoado para o uso diário.
Este aplicativo não contém anúncios, não faz nenhuma solicitação de rede e é Open Source."</string>
<string name="settings_activity_label">Configurações</string>
<string name="pref_portrait">No modo retrato</string> <string name="pref_portrait">No modo retrato</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">No modo paisagem</string> <string name="pref_landscape">No modo paisagem</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Layout</string> <string name="pref_category_layout">Layout</string>
<string name="pref_label_brightness">Ajustar brilho dos rótulos</string> <string name="pref_label_brightness">Ajustar brilho dos rótulos</string>
<string name="pref_keyboard_opacity">Ajustar opacidade do fundo do teclado</string> <string name="pref_keyboard_opacity">Ajustar opacidade do fundo do teclado</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Layout %1$d: %2$s</string> <string name="pref_layouts_item">Layout %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Remover layout</string> <string name="pref_layouts_remove_custom">Remover layout</string>
<string name="pref_custom_layout_title">Layout personalizado</string> <string name="pref_custom_layout_title">Layout personalizado</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Mostrar Teclado Numérico</string> <string name="pref_show_numpad_title">Mostrar Teclado Numérico</string>
<string name="pref_show_numpad_never">Nunca</string> <string name="pref_show_numpad_never">Nunca</string>
<string name="pref_show_numpad_landscape">Somente no modo paisagem</string> <string name="pref_show_numpad_landscape">Somente no modo paisagem</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Colar</string> <string name="key_descr_paste">Colar</string>
<string name="key_descr_cut">Recortar</string> <string name="key_descr_cut">Recortar</string>
<string name="key_descr_selectAll">Selecionar tudo</string> <string name="key_descr_selectAll">Selecionar tudo</string>
<string name="key_descr_shareText">Compartilhar texto</string>
<string name="key_descr_pasteAsPlainText">Colar texto não formatado</string> <string name="key_descr_pasteAsPlainText">Colar texto não formatado</string>
<string name="key_descr_undo">Desfazer</string> <string name="key_descr_undo">Desfazer</string>
<string name="key_descr_redo">Refazer</string> <string name="key_descr_redo">Refazer</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">Área de transferência</string> <string name="key_descr_clipboard">Área de transferência</string>
<string name="key_descr_combining">Combinação de diacríticos</string> <string name="key_descr_combining">Combinação de diacríticos</string>
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Textos recém copiados</string> <string name="clipboard_history_heading">Textos recém copiados</string>
<string name="clipboard_pin_heading">Fixados</string> <string name="clipboard_pin_heading">Fixados</string>
<string name="clipboard_remove_confirm">Remover esta cópia?</string> <string name="clipboard_remove_confirm">Remover esta cópia?</string>
<string name="clipboard_remove_confirmed">Sim</string> <string name="clipboard_remove_confirmed">Sim</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Tastatură Unexpected (depanare)</string> <string name="app_name_debug">Tastatură Unexpected (depanare)</string>
<string name="short_description">Tastatură virtuală pentru Android, ușoară și respectuoasă cu viața privată.</string> <string name="short_description">Tastatură virtuală pentru Android, ușoară și respectuoasă cu viața privată.</string>
<string name="store_description">Funcționalitatea principală este accesul rapid la o mulțime de caractere ASCII prin glisarea către colțurile tastelor.\n\nAceastă aplicație a fost concepută inițial pentru programatori care folosec Termux.\nEste perfectă pentru uzul cotidian.\n\nAceastă aplicație nu conține publicitate, nu folosește rețeaua deloc și e Open Source.</string> <string name="store_description">"Funcționalitatea principală este accesul rapid la o mulțime de caractere ASCII prin glisarea către colțurile tastelor.
Această aplicație a fost concepută inițial pentru programatori care folosec Termux.
Este perfectă pentru uzul cotidian.
Această aplicație nu conține publicitate, nu folosește rețeaua deloc și e Open Source."</string>
<string name="settings_activity_label">Setări Tastatură Unexpected</string>
<string name="pref_portrait">În mod portret</string> <string name="pref_portrait">În mod portret</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">În mod panoramă</string> <string name="pref_landscape">În mod panoramă</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Aspect</string> <string name="pref_category_layout">Aspect</string>
<string name="pref_label_brightness">Modifică luminozitatea denumirii</string> <string name="pref_label_brightness">Modifică luminozitatea denumirii</string>
<string name="pref_keyboard_opacity">Modifică opacitatea fundalului tastaturii</string> <string name="pref_keyboard_opacity">Modifică opacitatea fundalului tastaturii</string>
@@ -19,9 +23,6 @@
<!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> --> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<!-- <string name="pref_layouts_remove_custom">Remove layout</string> --> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_custom_layout_title">Aranjament personalizat</string> <string name="pref_custom_layout_title">Aranjament personalizat</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Arată NumPad</string> <string name="pref_show_numpad_title">Arată NumPad</string>
<string name="pref_show_numpad_never">Niciodată</string> <string name="pref_show_numpad_never">Niciodată</string>
<string name="pref_show_numpad_landscape">Doar în mod panoramă</string> <string name="pref_show_numpad_landscape">Doar în mod panoramă</string>
@@ -107,6 +108,7 @@
<!-- <string name="key_descr_paste">Paste</string> --> <!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> --> <!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> --> <!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> --> <!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> --> <!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> --> <!-- <string name="key_descr_redo">Redo</string> -->
@@ -120,17 +122,12 @@
<!-- <string name="key_descr_end">End</string> --> <!-- <string name="key_descr_end">End</string> -->
<!-- <string name="key_descr_clipboard">Clipboard manager</string> --> <!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<!-- <string name="clipboard_history_heading">Recently copied text</string> --> <!-- <string name="clipboard_history_heading">Recently copied text</string> -->
<!-- <string name="clipboard_pin_heading">Pinned</string> --> <!-- <string name="clipboard_pin_heading">Pinned</string> -->
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
<!-- <string name="clipboard_remove_confirmed">Yes</string> --> <!-- <string name="clipboard_remove_confirmed">Yes</string> -->
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (отладка)</string> <string name="app_name_debug">Unexpected Keyboard (отладка)</string>
<string name="short_description">Легкая клавиатура для пользователей, заботящихся о конфиденциальности.</string> <string name="short_description">Легкая клавиатура для пользователей, заботящихся о конфиденциальности.</string>
<string name="store_description">Главная особенность клавиатуры — это возможность легко напечатать любой ASCII-символ жестами в углы клавиш.\n\nПриложение изначально было разработано для использования с Termux.\nНа данный момент оно также удобно в повседневном использовании.\n\nПриложение не содержит рекламы, не осуществляет никаких запросов в сеть и имеет открытый исходный код.</string> <string name="store_description">"Главная особенность клавиатуры — это возможность легко напечатать любой ASCII-символ жестами в углы клавиш.
Приложение изначально было разработано для использования с Termux.
На данный момент оно также удобно в повседневном использовании.
Приложение не содержит рекламы, не осуществляет никаких запросов в сеть и имеет открытый исходный код."</string>
<string name="settings_activity_label">Настройки Unexpected Keyboard</string>
<string name="pref_portrait">В портретном режиме</string> <string name="pref_portrait">В портретном режиме</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">В ландшафтном режиме</string> <string name="pref_landscape">В ландшафтном режиме</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Расположение</string> <string name="pref_category_layout">Расположение</string>
<string name="pref_label_brightness">Изменить яркость клавиатуры</string> <string name="pref_label_brightness">Изменить яркость клавиатуры</string>
<string name="pref_keyboard_opacity">Изменить прозрачность фона</string> <string name="pref_keyboard_opacity">Изменить прозрачность фона</string>
@@ -19,15 +23,12 @@
<string name="pref_layouts_item">Раскладка %1$d: %2$s</string> <string name="pref_layouts_item">Раскладка %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Удалить раскладку</string> <string name="pref_layouts_remove_custom">Удалить раскладку</string>
<string name="pref_custom_layout_title">Пользовательская раскладка</string> <string name="pref_custom_layout_title">Пользовательская раскладка</string>
<string name="pref_show_number_row_no_number_row">Нет строки цифр</string>
<string name="pref_show_number_row_no_symbols">Строка цифр без символов</string>
<string name="pref_show_number_row_symbols">Строка цифр с символами</string>
<string name="pref_show_numpad_title">Показывать цифровой блок</string> <string name="pref_show_numpad_title">Показывать цифровой блок</string>
<string name="pref_show_numpad_never">Никогда</string> <string name="pref_show_numpad_never">Никогда</string>
<string name="pref_show_numpad_landscape">Только в ландшафтном режиме</string> <string name="pref_show_numpad_landscape">Только в ландшафтном режиме</string>
<string name="pref_show_numpad_always">Всегда</string> <string name="pref_show_numpad_always">Всегда</string>
<string name="pref_number_row_title">Показывать цифры</string> <string name="pref_number_row_title">Показывать цифры</string>
<string name="pref_number_row_summary">Добавить строку цифр над клавиатурой, когда цифровой блок не активен</string> <string name="pref_number_row_summary">Добавить ряд цифр над клавиатурой, когда цифровой блок не активен</string>
<string name="pref_numpad_layout">Раскладка цифрового блока</string> <string name="pref_numpad_layout">Раскладка цифрового блока</string>
<string name="pref_numpad_layout_e_high_first">Старшие цифры сверху</string> <string name="pref_numpad_layout_e_high_first">Старшие цифры сверху</string>
<string name="pref_numpad_layout_e_low_first">Младшие цифры сверху</string> <string name="pref_numpad_layout_e_low_first">Младшие цифры сверху</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Вставить</string> <string name="key_descr_paste">Вставить</string>
<string name="key_descr_cut">Вырезать</string> <string name="key_descr_cut">Вырезать</string>
<string name="key_descr_selectAll">Выбрать все</string> <string name="key_descr_selectAll">Выбрать все</string>
<string name="key_descr_shareText">Поделиться текстом</string>
<string name="key_descr_pasteAsPlainText">Вставить как простой текст</string> <string name="key_descr_pasteAsPlainText">Вставить как простой текст</string>
<string name="key_descr_undo">Отменить</string> <string name="key_descr_undo">Отменить</string>
<string name="key_descr_redo">Повторить</string> <string name="key_descr_redo">Повторить</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">Менеджер буфера обмена</string> <string name="key_descr_clipboard">Менеджер буфера обмена</string>
<string name="key_descr_combining">Сочетание диакритических знаков</string> <string name="key_descr_combining">Сочетание диакритических знаков</string>
<string name="key_descr_dead_key">Немая клавиша</string>
<string name="key_descr_zwj">Соединитель нулевой ширины</string> <string name="key_descr_zwj">Соединитель нулевой ширины</string>
<string name="key_descr_zwnj">Разделитель нулевой ширины</string> <string name="key_descr_zwnj">Разделитель нулевой ширины</string>
<string name="key_descr_nbsp">Неразрывный пробел</string> <string name="key_descr_nbsp">Неразрывный пробел</string>
<string name="key_descr_nnbsp">Узкий неразрывный пробел</string> <string name="key_descr_nnbsp">Узкий неразрывный пробел</string>
<string name="key_descr_delete_word">Удалить слово</string>
<string name="key_descr_forward_delete_word">Удалить слово справа</string>
<string name="key_descr_gesture">Жест</string>
<string name="clipboard_history_heading">Недавно скопированный текст</string> <string name="clipboard_history_heading">Недавно скопированный текст</string>
<string name="clipboard_pin_heading">Закреплено</string> <string name="clipboard_pin_heading">Закреплено</string>
<string name="clipboard_remove_confirm">Удалить этот элемент буфера обмена?</string> <string name="clipboard_remove_confirm">Удалить этот буфер обмена?</string>
<string name="clipboard_remove_confirmed">Да</string> <string name="clipboard_remove_confirmed">Да</string>
<string name="toast_no_voice_input">Приложение для голосового ввода не установлено</string>
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (debug)</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="short_description">Android için hafif ve güvenlik odaklı bir sanal klavye uygulaması.</string> <string name="short_description">Android için hafif ve güvenlik odaklı bir sanal klavye uygulaması.</string>
<string name="store_description">Bu uygulama özünde tuşların kenarlarından kaydırarak daha fazla karakter yazabilmek amacıyla geliştirildi.\n\nBu uygulama aslında Termux kullanıcıları için geliştirildi.\nArtık gündelik kullanım için de uygun.\n\nBu uygulama açık kaynaklıdır. Reklam içermez ve internete bağlanmaz.</string> <string name="store_description">"Bu uygulama özünde tuşların kenarlarından kaydırarak daha fazla karakter yazabilmek amacıyla geliştirildi.
Bu uygulama aslında Termux kullanıcıları için geliştirildi.
Artık gündelik kullanım için de uygun.
Bu uygulama açık kaynaklıdır. Reklam içermez ve internete bağlanmaz."</string>
<string name="settings_activity_label">Unexpected Keyboard Ayarları</string>
<string name="pref_portrait">Portre modunda</string> <string name="pref_portrait">Portre modunda</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">Manzara modunda</string> <string name="pref_landscape">Manzara modunda</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Tuş düzeni</string> <string name="pref_category_layout">Tuş düzeni</string>
<string name="pref_label_brightness">Adjust label brightness</string> <string name="pref_label_brightness">Adjust label brightness</string>
<string name="pref_keyboard_opacity">Klavye arkaplanı opaklığını ayarla</string> <string name="pref_keyboard_opacity">Klavye arkaplanı opaklığını ayarla</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Tuş düzeni %1$d: %2$s</string> <string name="pref_layouts_item">Tuş düzeni %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Tuş düzenini kaldır</string> <string name="pref_layouts_remove_custom">Tuş düzenini kaldır</string>
<string name="pref_custom_layout_title">Özel tuş düzeni</string> <string name="pref_custom_layout_title">Özel tuş düzeni</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">NumPadi göster</string> <string name="pref_show_numpad_title">NumPadi göster</string>
<string name="pref_show_numpad_never">Asla</string> <string name="pref_show_numpad_never">Asla</string>
<string name="pref_show_numpad_landscape">Sadece manzara modunda</string> <string name="pref_show_numpad_landscape">Sadece manzara modunda</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Yapıştır</string> <string name="key_descr_paste">Yapıştır</string>
<string name="key_descr_cut">Kes</string> <string name="key_descr_cut">Kes</string>
<string name="key_descr_selectAll">Tümünü seç</string> <string name="key_descr_selectAll">Tümünü seç</string>
<string name="key_descr_shareText">Metni paylaş</string>
<string name="key_descr_pasteAsPlainText">Düz metin olarak yapıştır</string> <string name="key_descr_pasteAsPlainText">Düz metin olarak yapıştır</string>
<string name="key_descr_undo">Geri al</string> <string name="key_descr_undo">Geri al</string>
<string name="key_descr_redo">İleri al</string> <string name="key_descr_redo">İleri al</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">SON(Sağ yön tuşu)</string> <string name="key_descr_end">SON(Sağ yön tuşu)</string>
<string name="key_descr_clipboard">Pano</string> <string name="key_descr_clipboard">Pano</string>
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Son kopyalanan metin</string> <string name="clipboard_history_heading">Son kopyalanan metin</string>
<string name="clipboard_pin_heading">Sabitlendi</string> <string name="clipboard_pin_heading">Sabitlendi</string>
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <string name="clipboard_remove_confirm">Bu sabitlemeyi sil</string>
<string name="clipboard_remove_confirmed">Evet</string> <string name="clipboard_remove_confirmed">Evet</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (Налагодження)</string> <string name="app_name_debug">Unexpected Keyboard (Налагодження)</string>
<string name="short_description">Легка та конфіденційна віртуальна клавіатура для Android.</string> <string name="short_description">Легка та конфіденційна віртуальна клавіатура для Android.</string>
<string name="store_description">Головна особливість полягає в тому, що ви можете вводити більше символів, проводячи клавіші до кутів.\n\nЦя програма спочатку була розроблена для програмістів, які використовують Termux.\nТепер ідеально підходить для щоденного використання.\n\nЦя програма не містить реклами, не надсилає жодних мережевих запитів і має відкритий код.</string> <string name="store_description">"Головна особливість полягає в тому, що ви можете вводити більше символів, проводячи клавіші до кутів.
Ця програма спочатку була розроблена для програмістів, які використовують Termux.
Тепер ідеально підходить для щоденного використання.
Ця програма не містить реклами, не надсилає жодних мережевих запитів і має відкритий код."</string>
<string name="settings_activity_label">Unexpected Keyboard Налаштування</string>
<string name="pref_portrait">У портретному режимі</string> <string name="pref_portrait">У портретному режимі</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">У альбомному режимі</string> <string name="pref_landscape">У альбомному режимі</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Макет</string> <string name="pref_category_layout">Макет</string>
<string name="pref_label_brightness">Налаштувати яскравість символів</string> <string name="pref_label_brightness">Налаштувати яскравість символів</string>
<string name="pref_keyboard_opacity">Налаштувати прозорість фону клавіатури</string> <string name="pref_keyboard_opacity">Налаштувати прозорість фону клавіатури</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Макет %1$d: %2$s</string> <string name="pref_layouts_item">Макет %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Видалити макет</string> <string name="pref_layouts_remove_custom">Видалити макет</string>
<string name="pref_custom_layout_title">Власний макет</string> <string name="pref_custom_layout_title">Власний макет</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Показувати числову клавіатуру </string> <string name="pref_show_numpad_title">Показувати числову клавіатуру </string>
<string name="pref_show_numpad_never">Ніколи</string> <string name="pref_show_numpad_never">Ніколи</string>
<string name="pref_show_numpad_landscape">Тільки в альбомному режимі</string> <string name="pref_show_numpad_landscape">Тільки в альбомному режимі</string>
@@ -70,7 +71,7 @@
<string name="pref_theme_e_monet">Моне (Системна)</string> <string name="pref_theme_e_monet">Моне (Системна)</string>
<string name="pref_theme_e_monetlight">Моне (Світла)</string> <string name="pref_theme_e_monetlight">Моне (Світла)</string>
<string name="pref_theme_e_monetdark">Моне (Темна)</string> <string name="pref_theme_e_monetdark">Моне (Темна)</string>
<string name="pref_theme_e_rosepine">Рожева сосна</string> <!-- <string name="pref_theme_e_rosepine">Rosé Pine</string> -->
<string name="pref_swipe_dist_e_very_short">Дуже коротка</string> <string name="pref_swipe_dist_e_very_short">Дуже коротка</string>
<string name="pref_swipe_dist_e_short">Коротка</string> <string name="pref_swipe_dist_e_short">Коротка</string>
<string name="pref_swipe_dist_e_default">Звичайна</string> <string name="pref_swipe_dist_e_default">Звичайна</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Вставити</string> <string name="key_descr_paste">Вставити</string>
<string name="key_descr_cut">Вирізати</string> <string name="key_descr_cut">Вирізати</string>
<string name="key_descr_selectAll">Вибрати все</string> <string name="key_descr_selectAll">Вибрати все</string>
<string name="key_descr_shareText">Поділитися текстом</string>
<string name="key_descr_pasteAsPlainText">Вставити як звичайний текст</string> <string name="key_descr_pasteAsPlainText">Вставити як звичайний текст</string>
<string name="key_descr_undo">Відмінити</string> <string name="key_descr_undo">Відмінити</string>
<string name="key_descr_redo">Повторити</string> <string name="key_descr_redo">Повторити</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">Менеджер буфера обміну</string> <string name="key_descr_clipboard">Менеджер буфера обміну</string>
<string name="key_descr_combining">Комбінування діакритики</string> <string name="key_descr_combining">Комбінування діакритики</string>
<string name="key_descr_dead_key">Мертва клавіша</string> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<string name="key_descr_zwj">З\'єднувач нульової ширини</string> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<string name="key_descr_zwnj">Разділювач нульової ширини</string> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<string name="key_descr_nbsp">Нерозривний пробіл</string> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<string name="key_descr_nnbsp">Вузький нерозривний пробіл</string>
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<string name="clipboard_history_heading">Нещодавно скопійований текст</string> <string name="clipboard_history_heading">Нещодавно скопійований текст</string>
<string name="clipboard_pin_heading">Закріплено</string> <string name="clipboard_pin_heading">Закріплено</string>
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <string name="clipboard_remove_confirm">Видалити цей буфер обміну?</string>
<string name="clipboard_remove_confirmed">Так</string> <string name="clipboard_remove_confirmed">Так</string>
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (gỡ lỗi)</string> <string name="app_name_debug">Unexpected Keyboard (gỡ lỗi)</string>
<string name="short_description">Bàn phím ảo gọn nhẹ và tôn trọng quyền riêng tư cho Android.</string> <string name="short_description">Bàn phím ảo gọn nhẹ và tôn trọng quyền riêng tư cho Android.</string>
<string name="store_description">Chức năng chính là dễ dàng gõ nhiều ký tự bằng cách kéo phím về góc của nó.\n\nỨng dụng này ban đầu được thiết kế cho các lập trình viên dùng Termux.\nBây giờ đã hoàn hảo cho việc sử dụng hàng ngày.\n\nỨng dụng này không chứa quảng cáo, không cần đến mạng, và có mã nguồn mở.</string> <string name="store_description">"Chức năng chính là dễ dàng gõ nhiều ký tự bằng cách kéo phím về góc của nó.
Ứng dụng này ban đầu được thiết kế cho các lập trình viên dùng Termux.
Bây giờ đã hoàn hảo cho việc sử dụng hàng ngày.
Ứng dụng này không chứa quảng cáo, không cần đến mạng, và có mã nguồn mở."</string>
<string name="settings_activity_label">Cài đặt Unexpected Keyboard</string>
<string name="pref_portrait">Trong chế độ chân dung</string> <string name="pref_portrait">Trong chế độ chân dung</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">Trong chế độ phong cảnh</string> <string name="pref_landscape">Trong chế độ phong cảnh</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">Bố cục</string> <string name="pref_category_layout">Bố cục</string>
<string name="pref_label_brightness">Tùy chỉnh độ sáng của phím</string> <string name="pref_label_brightness">Tùy chỉnh độ sáng của phím</string>
<string name="pref_keyboard_opacity">Tùy chỉnh độ trong suốt của bàn phím</string> <string name="pref_keyboard_opacity">Tùy chỉnh độ trong suốt của bàn phím</string>
@@ -19,9 +23,6 @@
<!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> --> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<!-- <string name="pref_layouts_remove_custom">Remove layout</string> --> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_custom_layout_title">Tùy chỉnh bố cục</string> <string name="pref_custom_layout_title">Tùy chỉnh bố cục</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">Hiện NumPad</string> <string name="pref_show_numpad_title">Hiện NumPad</string>
<string name="pref_show_numpad_never">Không bao giờ</string> <string name="pref_show_numpad_never">Không bao giờ</string>
<string name="pref_show_numpad_landscape">Chỉ trong chế độ phong cảnh</string> <string name="pref_show_numpad_landscape">Chỉ trong chế độ phong cảnh</string>
@@ -107,6 +108,7 @@
<!-- <string name="key_descr_paste">Paste</string> --> <!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> --> <!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> --> <!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> --> <!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> --> <!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> --> <!-- <string name="key_descr_redo">Redo</string> -->
@@ -120,17 +122,12 @@
<!-- <string name="key_descr_end">End</string> --> <!-- <string name="key_descr_end">End</string> -->
<!-- <string name="key_descr_clipboard">Clipboard manager</string> --> <!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<!-- <string name="clipboard_history_heading">Recently copied text</string> --> <!-- <string name="clipboard_history_heading">Recently copied text</string> -->
<!-- <string name="clipboard_pin_heading">Pinned</string> --> <!-- <string name="clipboard_pin_heading">Pinned</string> -->
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
<!-- <string name="clipboard_remove_confirmed">Yes</string> --> <!-- <string name="clipboard_remove_confirmed">Yes</string> -->
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (debug)</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="short_description">适用于 Android 的轻量级、注重隐私的虚拟键盘。</string> <string name="short_description">适用于 Android 的轻量级、注重隐私的虚拟键盘。</string>
<string name="store_description">此应用的主要功能是,通过将按键沿四角滑动,您可以输入更多字符。\n\n此应用最初是为使用 Termux 的程序员而设计的。\n现在对于日常使用来说也很完美。\n\n此应用没有广告不会发送任何网络请求而且是开源的。</string> <string name="store_description">"此应用的主要功能是,通过将按键沿四角滑动,您可以输入更多字符。
此应用最初是为使用 Termux 的程序员而设计的。
现在对于日常使用来说也很完美。
此应用没有广告,不会发送任何网络请求,而且是开源的。"</string>
<string name="settings_activity_label">Unexpected Keyboard 设置</string>
<string name="pref_portrait">在竖屏模式下</string> <string name="pref_portrait">在竖屏模式下</string>
<!-- <string name="pref_portrait_unfolded">In portrait mode unfolded</string> -->
<string name="pref_landscape">在横屏模式下</string> <string name="pref_landscape">在横屏模式下</string>
<!-- <string name="pref_landscape_unfolded">In landscape mode unfolded</string> -->
<string name="pref_category_layout">布局</string> <string name="pref_category_layout">布局</string>
<string name="pref_label_brightness">调整字母亮度</string> <string name="pref_label_brightness">调整字母亮度</string>
<string name="pref_keyboard_opacity">调整键盘背景透明度</string> <string name="pref_keyboard_opacity">调整键盘背景透明度</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">布局 %1$d%2$s</string> <string name="pref_layouts_item">布局 %1$d%2$s</string>
<string name="pref_layouts_remove_custom">移除布局</string> <string name="pref_layouts_remove_custom">移除布局</string>
<string name="pref_custom_layout_title">自定义布局</string> <string name="pref_custom_layout_title">自定义布局</string>
<!-- <string name="pref_show_number_row_no_number_row">No number row</string> -->
<!-- <string name="pref_show_number_row_no_symbols">Number row without symbols</string> -->
<!-- <string name="pref_show_number_row_symbols">Number row with symbols</string> -->
<string name="pref_show_numpad_title">显示数字小键盘</string> <string name="pref_show_numpad_title">显示数字小键盘</string>
<string name="pref_show_numpad_never">从不</string> <string name="pref_show_numpad_never">从不</string>
<string name="pref_show_numpad_landscape">只在横屏显示</string> <string name="pref_show_numpad_landscape">只在横屏显示</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">粘贴</string> <string name="key_descr_paste">粘贴</string>
<string name="key_descr_cut">剪切</string> <string name="key_descr_cut">剪切</string>
<string name="key_descr_selectAll">全选</string> <string name="key_descr_selectAll">全选</string>
<string name="key_descr_shareText">分享文本</string>
<string name="key_descr_pasteAsPlainText">粘贴为纯文本</string> <string name="key_descr_pasteAsPlainText">粘贴为纯文本</string>
<string name="key_descr_undo">撤销</string> <string name="key_descr_undo">撤销</string>
<string name="key_descr_redo">重做</string> <string name="key_descr_redo">重做</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<!-- <string name="key_descr_clipboard">Clipboard manager</string> --> <!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
<!-- <string name="key_descr_combining">Combining diacritic</string> --> <!-- <string name="key_descr_combining">Combining diacritic</string> -->
<!-- <string name="key_descr_dead_key">Dead key</string> -->
<!-- <string name="key_descr_zwj">Zero width joiner</string> --> <!-- <string name="key_descr_zwj">Zero width joiner</string> -->
<!-- <string name="key_descr_zwnj">Zero width non-joiner</string> --> <!-- <string name="key_descr_zwnj">Zero width non-joiner</string> -->
<!-- <string name="key_descr_nbsp">Non-breaking space</string> --> <!-- <string name="key_descr_nbsp">Non-breaking space</string> -->
<!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> --> <!-- <string name="key_descr_nnbsp">Narrow non-breaking space</string> -->
<!-- <string name="key_descr_delete_word">Delete a word</string> -->
<!-- <string name="key_descr_forward_delete_word">Delete a word on the right</string> -->
<!-- <string name="key_descr_gesture">Gesture</string> -->
<!-- <string name="clipboard_history_heading">Recently copied text</string> --> <!-- <string name="clipboard_history_heading">Recently copied text</string> -->
<!-- <string name="clipboard_pin_heading">Pinned</string> --> <!-- <string name="clipboard_pin_heading">Pinned</string> -->
<!-- <string name="clipboard_remove_confirm">Remove this clipboard item?</string> --> <!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
<!-- <string name="clipboard_remove_confirmed">Yes</string> --> <!-- <string name="clipboard_remove_confirmed">Yes</string> -->
<!-- <string name="toast_no_voice_input">No voice typing app installed</string> -->
</resources> </resources>

View File

@@ -1,15 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string-array name="pref_show_number_row_values">
<item>no_number_row</item>
<item>no_symbols</item>
<item>symbols</item>
</string-array>
<string-array name="pref_show_number_row_entries">
<item>@string/pref_show_number_row_no_number_row</item>
<item>@string/pref_show_number_row_no_symbols</item>
<item>@string/pref_show_number_row_symbols</item>
</string-array>
<string-array name="pref_show_numpad_values"> <string-array name="pref_show_numpad_values">
<item>never</item> <item>never</item>
<item>landscape</item> <item>landscape</item>

View File

@@ -41,9 +41,7 @@
<item>latn_bepo_fr</item> <item>latn_bepo_fr</item>
<item>latn_bone</item> <item>latn_bone</item>
<item>latn_neo2</item> <item>latn_neo2</item>
<item>latn_qwerty_apl</item>
<item>latn_qwerty_az</item> <item>latn_qwerty_az</item>
<item>latn_qwerty_bqn</item>
<item>latn_qwerty_br</item> <item>latn_qwerty_br</item>
<item>latn_qwerty_cy</item> <item>latn_qwerty_cy</item>
<item>latn_qwerty_cz</item> <item>latn_qwerty_cz</item>
@@ -54,7 +52,6 @@
<item>latn_qwerty_gb</item> <item>latn_qwerty_gb</item>
<item>latn_qwerty_haw</item> <item>latn_qwerty_haw</item>
<item>latn_qwerty_hu</item> <item>latn_qwerty_hu</item>
<item>latn_qwerty_is</item>
<item>latn_qwerty_jp</item> <item>latn_qwerty_jp</item>
<item>latn_qwerty_kk</item> <item>latn_qwerty_kk</item>
<item>latn_qwerty_lt</item> <item>latn_qwerty_lt</item>
@@ -81,7 +78,6 @@
<item>latn_qwertz_sq</item> <item>latn_qwertz_sq</item>
<item>latn_workman_us</item> <item>latn_workman_us</item>
<item>shaw_imperial_en</item> <item>shaw_imperial_en</item>
<item>sinhala_phonetic</item>
<item>tamil_default</item> <item>tamil_default</item>
<item>urdu_phonetic_ur</item> <item>urdu_phonetic_ur</item>
<item>custom</item> <item>custom</item>
@@ -126,9 +122,7 @@
<item>BEPO (Français)</item> <item>BEPO (Français)</item>
<item>Bone</item> <item>Bone</item>
<item>Neo 2</item> <item>Neo 2</item>
<item>QWERTY (APL)</item>
<item>QWERTY (Azərbaycanca)</item> <item>QWERTY (Azərbaycanca)</item>
<item>QWERTY (BQN)</item>
<item>QWERTY (Brasileiro)</item> <item>QWERTY (Brasileiro)</item>
<item>QWERTY (Welsh)</item> <item>QWERTY (Welsh)</item>
<item>QWERTY (Czech)</item> <item>QWERTY (Czech)</item>
@@ -139,7 +133,6 @@
<item>QWERTY (UK)</item> <item>QWERTY (UK)</item>
<item>QWERTY (Hawaiian)</item> <item>QWERTY (Hawaiian)</item>
<item>QWERTY (Magyar)</item> <item>QWERTY (Magyar)</item>
<item>QWERTY (Íslenska)</item>
<item>QWERTY (Japan)</item> <item>QWERTY (Japan)</item>
<item>QWERTY (Qazaqşa)</item> <item>QWERTY (Qazaqşa)</item>
<item>QWERTY (Lietuviškai)</item> <item>QWERTY (Lietuviškai)</item>
@@ -166,7 +159,6 @@
<item>QWERTZ (Albanian)</item> <item>QWERTZ (Albanian)</item>
<item>WORKMAN (US)</item> <item>WORKMAN (US)</item>
<item>Shaw Imperial</item> <item>Shaw Imperial</item>
<item>සිංහල</item>
<item>தமிழ்</item> <item>தமிழ்</item>
<item>Urdu Phonetic</item> <item>Urdu Phonetic</item>
<item>@string/pref_layout_e_custom</item> <item>@string/pref_layout_e_custom</item>
@@ -211,9 +203,7 @@
<item>@xml/latn_bepo_fr</item> <item>@xml/latn_bepo_fr</item>
<item>@xml/latn_bone</item> <item>@xml/latn_bone</item>
<item>@xml/latn_neo2</item> <item>@xml/latn_neo2</item>
<item>@xml/latn_qwerty_apl</item>
<item>@xml/latn_qwerty_az</item> <item>@xml/latn_qwerty_az</item>
<item>@xml/latn_qwerty_bqn</item>
<item>@xml/latn_qwerty_br</item> <item>@xml/latn_qwerty_br</item>
<item>@xml/latn_qwerty_cy</item> <item>@xml/latn_qwerty_cy</item>
<item>@xml/latn_qwerty_cz</item> <item>@xml/latn_qwerty_cz</item>
@@ -224,7 +214,6 @@
<item>@xml/latn_qwerty_gb</item> <item>@xml/latn_qwerty_gb</item>
<item>@xml/latn_qwerty_haw</item> <item>@xml/latn_qwerty_haw</item>
<item>@xml/latn_qwerty_hu</item> <item>@xml/latn_qwerty_hu</item>
<item>@xml/latn_qwerty_is</item>
<item>@xml/latn_qwerty_jp</item> <item>@xml/latn_qwerty_jp</item>
<item>@xml/latn_qwerty_kk</item> <item>@xml/latn_qwerty_kk</item>
<item>@xml/latn_qwerty_lt</item> <item>@xml/latn_qwerty_lt</item>
@@ -251,7 +240,6 @@
<item>@xml/latn_qwertz_sq</item> <item>@xml/latn_qwertz_sq</item>
<item>@xml/latn_workman_us</item> <item>@xml/latn_workman_us</item>
<item>@xml/shaw_imperial_en</item> <item>@xml/shaw_imperial_en</item>
<item>@xml/sinhala_phonetic</item>
<item>@xml/tamil_default</item> <item>@xml/tamil_default</item>
<item>@xml/urdu_phonetic_ur</item> <item>@xml/urdu_phonetic_ur</item>
<item>-1</item> <item>-1</item>

View File

@@ -3,11 +3,15 @@
<string name="app_name_release">Unexpected Keyboard</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (Debug)</string> <string name="app_name_debug">Unexpected Keyboard (Debug)</string>
<string name="short_description">Lightweight and privacy-conscious virtual keyboard for Android.</string> <string name="short_description">Lightweight and privacy-conscious virtual keyboard for Android.</string>
<string name="store_description">The main feature is that you can type more characters by swiping the keys towards the corners.\n\nThis application was originally designed for programmers using Termux.\nNow perfect for everyday use.\n\nThis application contains no ads, doesn\'t make any network requests and is Open Source.</string> <string name="store_description">"The main feature is that you can type more characters by swiping the keys towards the corners.
This application was originally designed for programmers using Termux.
Now perfect for everyday use.
This application contains no ads, doesn't make any network requests and is Open Source."</string>
<string name="settings_activity_label">Unexpected Keyboard Settings</string>
<string name="pref_portrait">In portrait mode</string> <string name="pref_portrait">In portrait mode</string>
<string name="pref_portrait_unfolded">In portrait mode unfolded</string>
<string name="pref_landscape">In landscape mode</string> <string name="pref_landscape">In landscape mode</string>
<string name="pref_landscape_unfolded">In landscape mode unfolded</string>
<string name="pref_category_layout">Layout</string> <string name="pref_category_layout">Layout</string>
<string name="pref_label_brightness">Adjust label brightness</string> <string name="pref_label_brightness">Adjust label brightness</string>
<string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string>
@@ -19,9 +23,6 @@
<string name="pref_layouts_item">Layout %1$d: %2$s</string> <string name="pref_layouts_item">Layout %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Remove layout</string> <string name="pref_layouts_remove_custom">Remove layout</string>
<string name="pref_custom_layout_title">Custom layout</string> <string name="pref_custom_layout_title">Custom layout</string>
<string name="pref_show_number_row_no_number_row">No number row</string>
<string name="pref_show_number_row_no_symbols">Number row without symbols</string>
<string name="pref_show_number_row_symbols">Number row with symbols</string>
<string name="pref_show_numpad_title">Show NumPad</string> <string name="pref_show_numpad_title">Show NumPad</string>
<string name="pref_show_numpad_never">Never</string> <string name="pref_show_numpad_never">Never</string>
<string name="pref_show_numpad_landscape">Only in landscape mode</string> <string name="pref_show_numpad_landscape">Only in landscape mode</string>
@@ -107,6 +108,7 @@
<string name="key_descr_paste">Paste</string> <string name="key_descr_paste">Paste</string>
<string name="key_descr_cut">Cut</string> <string name="key_descr_cut">Cut</string>
<string name="key_descr_selectAll">Select all</string> <string name="key_descr_selectAll">Select all</string>
<string name="key_descr_shareText">Share text</string>
<string name="key_descr_pasteAsPlainText">Paste as plain text</string> <string name="key_descr_pasteAsPlainText">Paste as plain text</string>
<string name="key_descr_undo">Undo</string> <string name="key_descr_undo">Undo</string>
<string name="key_descr_redo">Redo</string> <string name="key_descr_redo">Redo</string>
@@ -120,17 +122,12 @@
<string name="key_descr_end">End</string> <string name="key_descr_end">End</string>
<string name="key_descr_clipboard">Clipboard manager</string> <string name="key_descr_clipboard">Clipboard manager</string>
<string name="key_descr_combining">Combining diacritic</string> <string name="key_descr_combining">Combining diacritic</string>
<string name="key_descr_dead_key">Dead key</string>
<string name="key_descr_zwj">Zero width joiner</string> <string name="key_descr_zwj">Zero width joiner</string>
<string name="key_descr_zwnj">Zero width non-joiner</string> <string name="key_descr_zwnj">Zero width non-joiner</string>
<string name="key_descr_nbsp">Non-breaking space</string> <string name="key_descr_nbsp">Non-breaking space</string>
<string name="key_descr_nnbsp">Narrow non-breaking space</string> <string name="key_descr_nnbsp">Narrow non-breaking space</string>
<string name="key_descr_delete_word">Delete a word</string>
<string name="key_descr_forward_delete_word">Delete a word on the right</string>
<string name="key_descr_gesture">Gesture</string>
<string name="clipboard_history_heading">Recently copied text</string> <string name="clipboard_history_heading">Recently copied text</string>
<string name="clipboard_pin_heading">Pinned</string> <string name="clipboard_pin_heading">Pinned</string>
<string name="clipboard_remove_confirm">Remove this clipboard item?</string> <string name="clipboard_remove_confirm">Remove this clipboard?</string>
<string name="clipboard_remove_confirmed">Yes</string> <string name="clipboard_remove_confirmed">Yes</string>
<string name="toast_no_voice_input">No voice typing app installed</string>
</resources> </resources>

View File

@@ -7,6 +7,9 @@
<attr name="colorKey" format="color"/> <attr name="colorKey" format="color"/>
<!-- Background of the keys when pressed --> <!-- Background of the keys when pressed -->
<attr name="colorKeyActivated" format="color"/> <attr name="colorKeyActivated" format="color"/>
<!-- Adjust the lightness of keys depending on their role. -->
<attr name="colorKeyAction" format="color"/>
<attr name="colorKeySpaceBar" format="color"/>
<!-- Label colors --> <!-- Label colors -->
<attr name="colorLabel" format="color"/> <attr name="colorLabel" format="color"/>
<attr name="colorLabelActivated" format="color"/> <attr name="colorLabelActivated" format="color"/>
@@ -19,6 +22,8 @@
<attr name="keyBorderRadius" format="dimension"/> <attr name="keyBorderRadius" format="dimension"/>
<attr name="keyBorderWidth" format="dimension"/> <attr name="keyBorderWidth" format="dimension"/>
<attr name="keyBorderWidthActivated" format="dimension"/> <attr name="keyBorderWidthActivated" format="dimension"/>
<attr name="keyBorderWidthAction" format="dimension"/>
<attr name="keyBorderWidthSpaceBar" format="dimension"/>
<attr name="keyBorderColorLeft" format="color"/> <attr name="keyBorderColorLeft" format="color"/>
<attr name="keyBorderColorTop" format="color"/> <attr name="keyBorderColorTop" format="color"/>
<attr name="keyBorderColorRight" format="color"/> <attr name="keyBorderColorRight" format="color"/>
@@ -42,6 +47,8 @@
<item name="keyBorderRadius">5dp</item> <item name="keyBorderRadius">5dp</item>
<item name="keyBorderWidth">0dp</item> <item name="keyBorderWidth">0dp</item>
<item name="keyBorderWidthActivated">0dp</item> <item name="keyBorderWidthActivated">0dp</item>
<item name="keyBorderWidthAction">?attr/keyBorderWidth</item>
<item name="keyBorderWidthSpaceBar">?attr/keyBorderWidth</item>
<item name="secondaryDimming">0.25</item> <item name="secondaryDimming">0.25</item>
<item name="greyedDimming">0.5</item> <item name="greyedDimming">0.5</item>
<item name="emoji_key_bg" type="color">?attr/emoji_button_bg</item> <item name="emoji_key_bg" type="color">?attr/emoji_button_bg</item>
@@ -54,8 +61,12 @@
<item name="colorKeyboard">#1b1b1b</item> <item name="colorKeyboard">#1b1b1b</item>
<item name="colorKey">#333333</item> <item name="colorKey">#333333</item>
<item name="colorKeyActivated">#1b1b1b</item> <item name="colorKeyActivated">#1b1b1b</item>
<item name="colorKeyAction">#262626</item>
<item name="colorKeySpaceBar">#2b2b2b</item>
<item name="keyBorderWidth">1.2dp</item> <item name="keyBorderWidth">1.2dp</item>
<item name="keyBorderWidthActivated">0dp</item> <item name="keyBorderWidthActivated">0dp</item>
<item name="keyBorderWidthAction">0dp</item>
<item name="keyBorderWidthSpaceBar">0dp</item>
<item name="keyBorderColorBottom">#404040</item> <item name="keyBorderColorBottom">#404040</item>
<item name="colorLabel">#ffffff</item> <item name="colorLabel">#ffffff</item>
<item name="colorLabelActivated">#3399ff</item> <item name="colorLabelActivated">#3399ff</item>
@@ -69,8 +80,12 @@
<item name="colorKeyboard">#e3e3e3</item> <item name="colorKeyboard">#e3e3e3</item>
<item name="colorKey">#cccccc</item> <item name="colorKey">#cccccc</item>
<item name="colorKeyActivated">#e3e3e3</item> <item name="colorKeyActivated">#e3e3e3</item>
<item name="colorKeyAction">#d9d9d9</item>
<item name="colorKeySpaceBar">#dedede</item>
<item name="keyBorderWidth">0.6dp</item> <item name="keyBorderWidth">0.6dp</item>
<item name="keyBorderWidthActivated">0dp</item> <item name="keyBorderWidthActivated">0dp</item>
<item name="keyBorderWidthAction">0dp</item>
<item name="keyBorderWidthSpaceBar">0dp</item>
<item name="keyBorderColorLeft">#cccccc</item> <item name="keyBorderColorLeft">#cccccc</item>
<item name="keyBorderColorTop">#eeeeee</item> <item name="keyBorderColorTop">#eeeeee</item>
<item name="keyBorderColorRight">#cccccc</item> <item name="keyBorderColorRight">#cccccc</item>
@@ -87,6 +102,8 @@
<item name="colorKeyboard">#000000</item> <item name="colorKeyboard">#000000</item>
<item name="colorKey">#000000</item> <item name="colorKey">#000000</item>
<item name="colorKeyActivated">#333333</item> <item name="colorKeyActivated">#333333</item>
<item name="colorKeyAction">#000000</item>
<item name="colorKeySpaceBar">#000000</item>
<item name="keyBorderWidth">0dp</item> <item name="keyBorderWidth">0dp</item>
<item name="keyBorderWidthActivated">1dp</item> <item name="keyBorderWidthActivated">1dp</item>
<item name="keyBorderColorLeft">#2a2a2a</item> <item name="keyBorderColorLeft">#2a2a2a</item>
@@ -108,6 +125,8 @@
<item name="android:isLightTheme">true</item> <item name="android:isLightTheme">true</item>
<item name="colorKeyboard">#ffffff</item> <item name="colorKeyboard">#ffffff</item>
<item name="colorKey">#ffffff</item> <item name="colorKey">#ffffff</item>
<item name="colorKeyAction">#ffffff</item>
<item name="colorKeySpaceBar">#ffffff</item>
<item name="keyBorderWidth">1dp</item> <item name="keyBorderWidth">1dp</item>
<item name="keyBorderWidthActivated">1dp</item> <item name="keyBorderWidthActivated">1dp</item>
<item name="keyBorderColorLeft">#f0f0f0</item> <item name="keyBorderColorLeft">#f0f0f0</item>
@@ -127,6 +146,8 @@
<item name="android:isLightTheme">true</item> <item name="android:isLightTheme">true</item>
<item name="colorKeyboard">#ffffff</item> <item name="colorKeyboard">#ffffff</item>
<item name="colorKey">#ffffff</item> <item name="colorKey">#ffffff</item>
<item name="colorKeyAction">#ffffff</item>
<item name="colorKeySpaceBar">#ffffff</item>
<item name="keyBorderWidth">2dp</item> <item name="keyBorderWidth">2dp</item>
<item name="keyBorderWidthActivated">5dp</item> <item name="keyBorderWidthActivated">5dp</item>
<item name="keyBorderColorLeft">#000000</item> <item name="keyBorderColorLeft">#000000</item>
@@ -148,6 +169,8 @@
<item name="colorKeyboard">#ffe0b2</item> <item name="colorKeyboard">#ffe0b2</item>
<item name="colorKey">#fff3e0</item> <item name="colorKey">#fff3e0</item>
<item name="colorKeyActivated">#ffcc80</item> <item name="colorKeyActivated">#ffcc80</item>
<item name="colorKeyAction">#ffe9c6</item>
<item name="colorKeySpaceBar">#ffedd0</item>
<item name="colorLabel">#000000</item> <item name="colorLabel">#000000</item>
<item name="colorLabelActivated">#ffffff</item> <item name="colorLabelActivated">#ffffff</item>
<item name="colorLabelLocked">#e65100</item> <item name="colorLabelLocked">#e65100</item>
@@ -166,6 +189,8 @@
<item name="colorKeyboard">#4db6ac</item> <item name="colorKeyboard">#4db6ac</item>
<item name="colorKey">#e0f2f1</item> <item name="colorKey">#e0f2f1</item>
<item name="colorKeyActivated">#00695c</item> <item name="colorKeyActivated">#00695c</item>
<item name="colorKeyAction">#b8e3de</item>
<item name="colorKeySpaceBar">#c3e7e3</item>
<item name="colorLabel">#000000</item> <item name="colorLabel">#000000</item>
<item name="colorLabelActivated">#ffffff</item> <item name="colorLabelActivated">#ffffff</item>
<item name="colorLabelLocked">#64ffda</item> <item name="colorLabelLocked">#64ffda</item>
@@ -181,33 +206,39 @@
</style> </style>
<style name="MonetLight" parent="@style/BaseTheme"> <style name="MonetLight" parent="@style/BaseTheme">
<item name="android:isLightTheme">true</item> <item name="android:isLightTheme">true</item>
<item name="colorKeyboard">@android:color/system_neutral1_100</item> <item name="colorKeyboard">@android:color/system_accent1_100</item>
<item name="colorKey">@android:color/system_neutral1_50</item> <item name="colorKey">@android:color/system_accent1_0</item>
<item name="colorKeyActivated">?colorKeyboard</item> <item name="colorKeyActivated">@android:color/system_accent1_300</item>
<item name="colorLabel">@android:color/system_neutral1_800</item> <item name="colorKeyAction">@android:color/system_accent1_100</item>
<item name="colorLabelActivated">@android:color/system_accent1_400</item> <item name="colorKeySpaceBar">@android:color/system_accent1_200</item>
<item name="colorLabelLocked">@android:color/system_accent1_600</item> <item name="colorLabel">@android:color/system_accent1_1000</item>
<item name="colorSubLabel">@android:color/system_neutral1_500</item> <item name="colorLabelActivated">@android:color/system_accent1_1000</item>
<item name="colorLabelLocked">@android:color/system_accent1_500</item>
<item name="colorSubLabel">@android:color/system_accent1_900</item>
<item name="emoji_button_bg">?colorKeyActivated</item> <item name="emoji_button_bg">?colorKeyActivated</item>
<item name="emoji_color">?colorKeyboard</item> <item name="emoji_color">@android:color/system_accent1_1000</item>
</style> </style>
<style name="MonetDark" parent="@style/BaseTheme"> <style name="MonetDark" parent="@style/BaseTheme">
<item name="android:isLightTheme">false</item> <item name="android:isLightTheme">false</item>
<item name="colorKeyboard">@android:color/system_neutral1_900</item> <item name="colorKeyboard">@android:color/system_neutral1_900</item>
<item name="colorKey">@android:color/system_neutral1_800</item> <item name="colorKey">@android:color/system_accent2_800</item>
<item name="colorKeyActivated">?colorKeyboard</item> <item name="colorKeyActivated">@android:color/system_accent1_700</item>
<item name="colorKeyAction">@android:color/system_accent2_900</item>
<item name="colorKeySpaceBar">@android:color/system_accent2_900</item>
<item name="colorLabel">@android:color/system_neutral1_0</item> <item name="colorLabel">@android:color/system_neutral1_0</item>
<item name="colorLabelActivated">@android:color/system_accent1_400</item> <item name="colorLabelActivated">@android:color/system_accent1_400</item>
<item name="colorLabelLocked">@android:color/system_accent1_600</item> <item name="colorLabelLocked">@android:color/system_accent1_100</item>
<item name="colorSubLabel">@android:color/system_neutral1_400</item> <item name="colorSubLabel">@android:color/system_neutral1_300</item>
<item name="emoji_button_bg">?colorKeyActivated</item> <item name="emoji_button_bg">?colorKeyActivated</item>
<item name="emoji_color">?colorKeyboard</item> <item name="emoji_color">@android:color/system_neutral1_900</item>
</style> </style>
<style name="RosePine" parent="BaseTheme"> <style name="RosePine" parent="BaseTheme">
<item name="android:isLightTheme">false</item> <item name="android:isLightTheme">false</item>
<item name="colorKeyboard">#191724</item> <item name="colorKeyboard">#191724</item>
<item name="colorKey">#26233a</item> <item name="colorKey">#26233a</item>
<item name="colorKeyActivated">#403d52</item> <item name="colorKeyActivated">#403d52</item>
<item name="colorKeyAction">#2a2740</item>
<item name="colorKeySpaceBar">#2e2b47</item>
<item name="keyBorderWidth">0dp</item> <item name="keyBorderWidth">0dp</item>
<item name="keyBorderWidthActivated">1dp</item> <item name="keyBorderWidthActivated">1dp</item>
<item name="keyBorderColorLeft">#6e6a86</item> <item name="keyBorderColorLeft">#6e6a86</item>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<row height="0.95"> <row height="0.95">
<key width="1.7" key0="ctrl" key1="loc switch_greekmath" key2="loc meta" key3="loc switch_clipboard" key4="switch_numeric"/> <key width="1.7" role="action" key0="ctrl" key1="loc switch_greekmath" key2="loc meta" key3="loc switch_clipboard" key4="switch_numeric"/>
<key width="1.1" key0="fn" key1="loc alt" key2="loc change_method" key3="switch_emoji" key4="config"/> <key width="1.1" role="action" key0="fn" key1="loc alt" key2="loc change_method" key3="switch_emoji" key4="config"/>
<key width="4.4" key0="space" key7="switch_forward" key8="switch_backward" key5="cursor_left" key6="cursor_right"/> <key width="4.4" role="space_bar" key0="space" key7="switch_forward" key8="switch_backward" key5="cursor_left" key6="cursor_right"/>
<key width="1.1" key0="loc compose" key7="up" key6="right" key5="left" key8="down" key1="loc home" key2="loc page_up" key3="loc end" key4="loc page_down"/> <key width="1.1" role="action" key0="loc compose" key7="up" key6="right" key5="left" key8="down" key1="loc home" key2="loc page_up" key3="loc end" key4="loc page_down"/>
<key width="1.7" key0="enter" key1="loc voice_typing" key2="action"/> <key width="1.7" role="action" key0="enter" key1="loc voice_typing" key2="action"/>
</row> </row>

View File

@@ -2,9 +2,9 @@
<!-- The bottom row used in the clipboard history pane. --> <!-- The bottom row used in the clipboard history pane. -->
<keyboard bottom_row="false"> <keyboard bottom_row="false">
<row height="0.95"> <row height="0.95">
<key key0="switch_back_clipboard"/> <key role="action" key0="switch_back_clipboard"/>
<key width="3" key0="space" key5="cursor_left" key6="cursor_right"/> <key width="3" role="space_bar" key0="space" key5="cursor_left" key6="cursor_right"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
<key key0="enter" key2="action"/> <key role="action" key0="enter" key2="action"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -2,9 +2,9 @@
<!-- The bottom row used in the emoji pane. --> <!-- The bottom row used in the emoji pane. -->
<keyboard bottom_row="false"> <keyboard bottom_row="false">
<row height="0.95"> <row height="0.95">
<key key0="switch_back_emoji"/> <key role="action" key0="switch_back_emoji"/>
<key width="3" key0="space" key5="cursor_left" key6="cursor_right"/> <key role="space_bar" width="3" key0="space" key5="cursor_left" key6="cursor_right"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
<key key0="enter" key2="action"/> <key role="action" key0="enter" key2="action"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -25,7 +25,7 @@
<key key0="ϡ" key1="⌀"/> <key key0="ϡ" key1="⌀"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" key2="loc capslock"/> <key width="1.5" role="action" key0="shift" key2="loc capslock"/>
<key key0="ζ" key3="⇌" key4="√"/> <key key0="ζ" key3="⇌" key4="√"/>
<key key0="χ" key3="accent_arrow_right" key4=""/> <key key0="χ" key3="accent_arrow_right" key4=""/>
<key key0="ϛ" key4="∩"/> <key key0="ϛ" key4="∩"/>
@@ -33,15 +33,15 @@
<key key0="β" key1="≤" key3="" key4="1"/> <key key0="β" key1="≤" key3="" key4="1"/>
<key key0="ν" key1="≠" key3="" key4="2"/> <key key0="ν" key1="≠" key3="" key4="2"/>
<key key0="μ" key1="≥" key3="×" key4="3"/> <key key0="μ" key1="≥" key3="×" key4="3"/>
<key width="1.5" key0="backspace" key3="delete"/> <key width="1.5" role="action" key0="backspace" key3="delete"/>
</row> </row>
<row height="0.95"> <row height="0.95">
<key width="1.2" key0="switch_text" key2="loc esc"/> <key width="1.2" role="action" key0="switch_text" key2="loc esc"/>
<key width="1.2" key0="switch_numeric" key2="loc tab"/> <key width="1.2" role="action" key0="switch_numeric" key2="loc tab"/>
<key width="1.2" key0="fn"/> <key width="1.2" role="action" key0="fn"/>
<key width="2.8" key0="space" key1="superscript" key3="subscript"/> <key width="2.8" role="space_bar" key0="space" key1="superscript" key3="subscript"/>
<key width="1.2" key0="0" key2="."/> <key width="1.2" role="action" key0="0" key2="."/>
<key width="1.2" key0="loc compose" key7="up" key6="right" key5="left" key8="down"/> <key width="1.2" role="action" key0="loc compose" key7="up" key6="right" key5="left" key8="down"/>
<key width="1.2" key0="enter" key1="=" key2="action"/> <key width="1.2" role="action" key0="enter" key1="=" key2="action"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -24,17 +24,18 @@
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_es,extra_keys=accent_aigu:á:é:í:ó:ú@d|accent_tilde:ñ@n|accent_grave@f|accent_trema@u|€"/> <subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_es,extra_keys=accent_aigu:á:é:í:ó:ú@d|accent_tilde:ñ@n|accent_grave@f|accent_trema@u|€"/>
<subtype android:label="%s" android:languageTag="et" android:imeSubtypeLocale="et_EE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_et,extra_keys=accent_trema:ä:ö:ü@u|accent_tilde:õ@o|accent_caron:š:ž@s|€"/> <subtype android:label="%s" android:languageTag="et" android:imeSubtypeLocale="et_EE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_et,extra_keys=accent_trema:ä:ö:ü@u|accent_tilde:õ@o|accent_caron:š:ž@s|€"/>
<subtype android:label="%s" android:languageTag="fa" android:imeSubtypeLocale="fa_IR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=arab_pc_ir"/> <subtype android:label="%s" android:languageTag="fa" android:imeSubtypeLocale="fa_IR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=arab_pc_ir"/>
<subtype android:label="%s" android:languageTag="fr-BE" android:imeSubtypeLocale="fr_BE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_be,extra_keys=accent_grave:à:è:ù@f|accent_aigu:é@d|accent_circonflexe:ê@f|accent_cedille:ç@c|accent_trema@u|€"/> <subtype android:label="%s" android:languageTag="fr-BE" android:imeSubtypeLocale="fr_BE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_be,extra_keys=accent_grave:è@f|accent_aigu:á:é:í:ó:ú:ý:j́@d|accent_circonflexe:ê@f|accent_cedille:ç@c|accent_trema@u|€"/>
<subtype android:label="%s" android:languageTag="fr-CA" android:imeSubtypeLocale="fr_CA" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è:ù@f|accent_aigu:é@d|accent_circonflexe:â:ê:ô@f|accent_cedille:ç@c|accent_trema:ë:ï:ü:ÿ@u"/> <subtype android:label="%s" android:languageTag="fr-CA" android:imeSubtypeLocale="fr_CA" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è:ù@f|accent_aigu:é@d|accent_circonflexe:â:ê:ô@f|accent_cedille:ç@c|accent_trema:ë:ï:ü:ÿ@u"/>
<subtype android:label="%s" android:languageTag="fr-CH" android:imeSubtypeLocale="fr_CH" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_fr_ch,extra_keys=accent_grave:à:è:ù@f|accent_aigu:é@d|accent_circonflexe:â:ê:ô@o|accent_cedille:ç@c|accent_trema:ë:ï:ü:ÿ@u|€"/> <subtype android:label="%s" android:languageTag="fr-CH" android:imeSubtypeLocale="fr_CH" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_fr_ch,extra_keys=accent_grave:à:è:ù@f|accent_aigu:é@d|accent_circonflexe:â:ê:ô@o|accent_cedille:ç@c|accent_trema:ë:ï:ü:ÿ@u|€"/>
<subtype android:label="%s" android:languageTag="fr-FR" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è@d|accent_aigu:é@d|accent_circonflexe:â:ê:ô@o|accent_cedille:ç@c|accent_trema:ë:ï:ü@l|€"/> <subtype android:label="%s" android:languageTag="fr-FR" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è@d|accent_aigu:é@d|accent_circonflexe:â:ê:ô@o|accent_cedille:ç@c|accent_trema:ë:ï:ü@l|€"/>
<subtype android:label="%s" android:languageTag="ga" android:imeSubtypeLocale="ga_IE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_ga,extra_keys=accent_aigu:á:é:í:ó:ú@k|accent_dot_above@l"/> <subtype android:label="%s" android:languageTag="ga" android:imeSubtypeLocale="ga_IE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_ga,extra_keys=accent_aigu:á:é:í:ó:ú@k|accent_dot_above@l"/>
<subtype android:label="%s" android:languageTag="haw" android:imeSubtypeLocale="haw_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_haw,extra_keys=ʻ@l|accent_macron:ā:ē:ī:ō:ū@m"/> <subtype android:label="%s" android:languageTag="haw" android:imeSubtypeLocale="haw_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_haw,extra_keys=ʻ@l|accent_macron:ā:ē:ī:ō:ū@m"/>
<subtype android:label="%s" android:languageTag="he" android:imeSubtypeLocale="he_IL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hebrew,default_layout=hebr_1_il,extra_keys=₪@r|€"/> <subtype android:label="%s" android:languageTag="he" android:imeSubtypeLocale="he_IL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hebrew,default_layout=hebr_1_il,extra_keys=₪@r|€"/>
<subtype android:label="%s" android:languageTag="hi" android:imeSubtypeLocale="hi_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/> <subtype android:label="%s" android:languageTag="hi" android:imeSubtypeLocale="hi_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/>
<subtype android:label="%s" android:languageTag="hu" android:imeSubtypeLocale="hu_HU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_hu,extra_keys=accent_aigu:á:é:í:ó:ú@d|accent_trema:ö:ü@u|accent_ogonek@s|accent_double_aigu:ő:ű@k|€"/> <subtype android:label="%s" android:languageTag="hu" android:imeSubtypeLocale="hu_HU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_hu,extra_keys=accent_aigu:á:é:í:ó:ú@d|accent_trema:ö:ü@u|accent_ogonek@s|accent_double_aigu:ő:ű@k|€"/>
<subtype android:label="%s" android:languageTag="is" android:imeSubtypeLocale="is_IS" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_is,extra_keys=ð|þ|æ|accent_trema:ö@o|accent_aigu:á:é:í:ó:ú:ý@d|accent_circonflexe|accent_ring|accent_grave"/> <subtype android:label="%s" android:languageTag="is" android:imeSubtypeLocale="is_IS" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=ð|þ|æ|accent_trema:ö@o|accent_aigu:á:é:í:ó:ú:ý@d"/>
<subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=accent_grave:à:è:ì:ò:ù@f|accent_aigu:é:ó@d|accent_circonflexe:î@f|€|ə"/> <subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=accent_grave:à:è:ì:ò:ù@f|accent_aigu:é:ó@d|accent_circonflexe:î@f|€|ə"/>
<subtype android:label="%s" android:languageTag="ja" android:imeSubtypeLocale="ja_JP" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_jp"/>
<subtype android:label="%s" android:languageTag="ka-GE" android:imeSubtypeLocale="ka_GE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=georgian_mes"/> <subtype android:label="%s" android:languageTag="ka-GE" android:imeSubtypeLocale="ka_GE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=georgian_mes"/>
<subtype android:label="%s" android:languageTag="kk" android:imeSubtypeLocale="kk_KZ" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_jcuken_kk"/> <subtype android:label="%s" android:languageTag="kk" android:imeSubtypeLocale="kk_KZ" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_jcuken_kk"/>
<subtype android:label="%s" android:languageTag="kn" android:imeSubtypeLocale="kn_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=kannada,default_layout=kann_kannada"/> <subtype android:label="%s" android:languageTag="kn" android:imeSubtypeLocale="kn_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=kannada,default_layout=kann_kannada"/>
@@ -51,7 +52,6 @@
<subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_pt,extra_keys=accent_aigu:á:é:í:ó:ú@d|accent_cedille:ç@c|accent_circonflexe:â:ê:ô@f|accent_grave:à:ò@f|accent_tilde:ã:õ@n|€|ª|º"/> <subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_pt,extra_keys=accent_aigu:á:é:í:ó:ú@d|accent_cedille:ç@c|accent_circonflexe:â:ê:ô@f|accent_grave:à:ò@f|accent_tilde:ã:õ@n|€|ª|º"/>
<subtype android:label="%s" android:languageTag="ro" android:imeSubtypeLocale="ro_RO" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_ro,extra_keys=ă|â|î|ș|ț|€|$"/> <subtype android:label="%s" android:languageTag="ro" android:imeSubtypeLocale="ro_RO" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_ro,extra_keys=ă|â|î|ș|ț|€|$"/>
<subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_jcuken_ru"/> <subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_jcuken_ru"/>
<subtype android:label="%s" android:languageTag="si" android:imeSubtypeLocale="si_LK" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=sinhala,default_layout=sinhala_phonetic,extra_keys=₨"/>
<subtype android:label="%s" android:languageTag="sk" android:imeSubtypeLocale="sk_SK" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_sk,extra_keys=accent_caron:ě:ř:ž:š:č:ň:ď:ľ:ť@f|accent_ring:ů@s|accent_circonflexe:ô@f|accent_trema:ä:ü:ö@u|accent_aigu:á:é:í:ó:ú:ŕ:ś:ĺ:ý@d"/> <subtype android:label="%s" android:languageTag="sk" android:imeSubtypeLocale="sk_SK" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_sk,extra_keys=accent_caron:ě:ř:ž:š:č:ň:ď:ľ:ť@f|accent_ring:ů@s|accent_circonflexe:ô@f|accent_trema:ä:ü:ö@u|accent_aigu:á:é:í:ó:ú:ŕ:ś:ĺ:ý@d"/>
<subtype android:label="%s" android:languageTag="sq" android:imeSubtypeLocale="sq_AL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_sq"/> <subtype android:label="%s" android:languageTag="sq" android:imeSubtypeLocale="sq_AL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_sq"/>
<subtype android:label="%s" android:languageTag="sr" android:imeSubtypeLocale="sr_" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_lynyertz_sr"/> <subtype android:label="%s" android:languageTag="sr" android:imeSubtypeLocale="sr_" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_lynyertz_sr"/>

View File

@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- See [number_row_no_symbols.xml] for the number row with no symbols. -->
<row height="0.75"> <row height="0.75">
<key key0="1" se="!"/> <key role="action" key0="1" se="!"/>
<key key0="2" se="@"/> <key role="action" key0="2" se="@"/>
<key key0="3" se="#"/> <key role="action" key0="3" se="#"/>
<key key0="4" se="$"/> <key role="action" key0="4" se="$"/>
<key key0="5" se="%"/> <key role="action" key0="5" se="%"/>
<key key0="6" sw="^"/> <key role="action" key0="6" sw="^"/>
<key key0="7" sw="&amp;"/> <key role="action" key0="7" sw="&amp;"/>
<key key0="8" sw="*"/> <key role="action" key0="8" sw="*"/>
<key key0="9" sw="("/> <key role="action" key0="9" sw="("/>
<key key0="0" sw=")"/> <key role="action" key0="0" sw=")"/>
</row> </row>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<row height="0.75">
<key key0="1"/>
<key key0="2"/>
<key key0="3"/>
<key key0="4"/>
<key key0="5"/>
<key key0="6"/>
<key key0="7"/>
<key key0="8"/>
<key key0="9"/>
<key key0="0"/>
</row>

View File

@@ -1,36 +1,36 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<keyboard bottom_row="false"> <keyboard bottom_row="false">
<row> <row>
<key width="0.75" key0="loc esc" key2="~" key4="!"/> <key width="0.75" role="action" key0="loc esc" key2="~" key4="!"/>
<key width="0.75" key0="(" key2="[" key4="{"/> <key width="0.75" role="action" key0="(" key2="[" key4="{"/>
<key key0="7" key1="&lt;" key2="&gt;"/> <key key0="7" key1="&lt;" key2="&gt;"/>
<key key0="8" key2="∞"/> <key key0="8" key2="∞"/>
<key key0="9" key2="π"/> <key key0="9" key2="π"/>
<key width="0.75" key0="*" key1="√" key2="×" key3="\#"/> <key width="0.75" role="action" key0="*" key1="√" key2="×" key3="\#"/>
<key width="0.75" key0="/" key1="%" key3="÷"/> <key width="0.75" role="action" key0="/" key1="%" key3="÷"/>
</row> </row>
<row> <row>
<key width="0.75" key0="loc tab" key2="|" key4="\\"/> <key width="0.75" role="action" key0="loc tab" key2="|" key4="\\"/>
<key width="0.75" key0=")" key2="]" key4="}"/> <key width="0.75" role="action" key0=")" key2="]" key4="}"/>
<key key0="4" key1="box" key3="arrows"/> <key key0="4" key1="box" key3="arrows"/>
<key key0="5" key7="up" key6="right" key5="left" key8="down"/> <key key0="5" key7="up" key6="right" key5="left" key8="down"/>
<key key0="6"/> <key key0="6"/>
<key width="0.75" key0="+" key1="Σ" key2="$"/> <key width="0.75" role="action" key0="+" key1="Σ" key2="$"/>
<key width="0.75" key0="-" key1="^"/> <key width="0.75" role="action" key0="-" key1="^"/>
</row> </row>
<row> <row>
<key width="0.75" key0="switch_greekmath"/> <key width="0.75" role="action" key0="switch_greekmath"/>
<key width="0.75" key0="shift" key2="fn" key4="loc alt"/> <key width="0.75" role="action" key0="shift" key2="fn" key4="loc alt"/>
<key key0="1" key1="superscript" key2="ordinal" key3="subscript"/> <key key0="1" key1="superscript" key2="ordinal" key3="subscript"/>
<key key0="2"/> <key key0="2"/>
<key key0="3"/> <key key0="3"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
<row height="0.95"> <row height="0.95">
<key width="1.5" key0="switch_text" key2="ctrl"/> <key width="1.5" role="action" key0="switch_text" key2="ctrl"/>
<key width="1.5" key0="0"/> <key width="1.5" key0="0"/>
<key width="0.75" key0="." key1=":" key2="," key3=";"/> <key width="0.75" role="action" key0="." key1=":" key2="," key3=";"/>
<key width="0.75" key0="space" key1="&quot;" key2="'" key3="loc compose" key4="_"/> <key width="0.75" role="action" key0="action" key1="&quot;" key2="'" key3="loc compose" key4="_"/>
<key width="1.5" key0="enter" key1="±" key2="action" key3="="/> <key width="1.5" role="action" key0="enter" key1="±" key2="action" key3="="/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -1,27 +1,27 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<keyboard bottom_row="false"> <keyboard bottom_row="false">
<row> <row>
<key key0="7"/> <key role="action" key0="7"/>
<key key0="8"/> <key role="action" key0="8"/>
<key key0="9"/> <key role="action" key0="9"/>
<key key0="/"/> <key role="action" key0="/"/>
</row> </row>
<row> <row>
<key key0="4"/> <key role="action" key0="4"/>
<key key0="5"/> <key role="action" key0="5"/>
<key key0="6"/> <key role="action" key0="6"/>
<key key0="*"/> <key role="action" key0="*"/>
</row> </row>
<row> <row>
<key key0="1"/> <key role="action" key0="1"/>
<key key0="2"/> <key role="action" key0="2"/>
<key key0="3"/> <key role="action" key0="3"/>
<key key0="-"/> <key role="action" key0="-"/>
</row> </row>
<row height="0.95"> <row height="0.95">
<key key0="0"/> <key role="action" key0="0"/>
<key key0="."/> <key role="action" key0="."/>
<key key0="="/> <key role="action" key0="="/>
<key key0="+"/> <key role="action" key0="+"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -4,24 +4,24 @@
<key shift="1.0" key0="1"/> <key shift="1.0" key0="1"/>
<key key0="2" indication="ABC"/> <key key0="2" indication="ABC"/>
<key key0="3" indication="DEF"/> <key key0="3" indication="DEF"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
</row> </row>
<row> <row>
<key shift="1.0" key0="4" indication="GHI"/> <key shift="1.0" key0="4" indication="GHI"/>
<key key0="5" indication="JKL"/> <key key0="5" indication="JKL"/>
<key key0="6" indication="MNO"/> <key key0="6" indication="MNO"/>
<key key0="(" key1="paste" key2="=" key3=":" key4="-"/> <key role="action" key0="(" key1="paste" key2="=" key3=":" key4="-"/>
</row> </row>
<row> <row>
<key shift="1.0" key0="7" indication="PQRS"/> <key shift="1.0" key0="7" indication="PQRS"/>
<key key0="8" indication="TUV"/> <key key0="8" indication="TUV"/>
<key key0="9" indication="WXYZ"/> <key key0="9" indication="WXYZ"/>
<key key0=")" key2="," key3="/" key4="."/> <key role="action" key0=")" key2="," key3="/" key4="."/>
</row> </row>
<row> <row>
<key shift="1.0" key0="*" key1="switch_text" key3="switch_numeric"/> <key role="action" shift="1.0" key0="*" key1="switch_text" key3="switch_numeric"/>
<key key0="0" key3="+" key4="space"/> <key key0="0" key3="+" key4="space"/>
<key key0="\#" key7="up" key6="right" key5="left" key8="down"/> <key role="action" key0="\#" key7="up" key6="right" key5="left" key8="down"/>
<key key0="action" key2="enter"/> <key role="action" key0="action" key2="enter"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -8,7 +8,7 @@
</PreferenceCategory> </PreferenceCategory>
<juloo.keyboard2.prefs.ExtraKeysPreference android:title="@string/pref_extra_keys_internal"/> <juloo.keyboard2.prefs.ExtraKeysPreference android:title="@string/pref_extra_keys_internal"/>
</PreferenceScreen> </PreferenceScreen>
<ListPreference android:key="number_row" android:title="@string/pref_number_row_title" android:summary="%s" android:defaultValue="no_number_row" android:entries="@array/pref_show_number_row_entries" android:entryValues="@array/pref_show_number_row_values"/> <CheckBoxPreference android:key="number_row" android:title="@string/pref_number_row_title" android:summary="@string/pref_number_row_summary" android:defaultValue="false"/>
<ListPreference android:key="show_numpad" android:title="@string/pref_show_numpad_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_show_numpad_entries" android:entryValues="@array/pref_show_numpad_values"/> <ListPreference android:key="show_numpad" android:title="@string/pref_show_numpad_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_show_numpad_entries" android:entryValues="@array/pref_show_numpad_values"/>
<ListPreference android:key="numpad_layout" android:title="@string/pref_numpad_layout" android:summary="%s" android:defaultValue="high_first" android:entries="@array/pref_numpad_layout_entries" android:entryValues="@array/pref_numpad_layout_values"/> <ListPreference android:key="numpad_layout" android:title="@string/pref_numpad_layout" android:summary="%s" android:defaultValue="high_first" android:entries="@array/pref_numpad_layout_entries" android:entryValues="@array/pref_numpad_layout_values"/>
</PreferenceCategory> </PreferenceCategory>
@@ -36,20 +36,14 @@
<PreferenceScreen android:title="@string/pref_margin_bottom_title"> <PreferenceScreen android:title="@string/pref_margin_bottom_title">
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="7" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="7" min="0" max="100"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="3" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="3" min="0" max="100"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_portrait_unfolded" android:title="@string/pref_portrait_unfolded" android:summary="%sdp" android:defaultValue="7" min="0" max="100"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_landscape_unfolded" android:title="@string/pref_landscape_unfolded" android:summary="%sdp" android:defaultValue="3" min="0" max="100"/>
</PreferenceScreen> </PreferenceScreen>
<PreferenceScreen android:title="@string/pref_keyboard_height_title"> <PreferenceScreen android:title="@string/pref_keyboard_height_title">
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height" android:title="@string/pref_portrait" android:summary="%s%%" android:defaultValue="35" min="10" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height" android:title="@string/pref_portrait" android:summary="%s%%" android:defaultValue="35" min="10" max="50"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height_landscape" android:title="@string/pref_landscape" android:summary="%s%%" android:defaultValue="50" min="20" max="65"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height_landscape" android:title="@string/pref_landscape" android:summary="%s%%" android:defaultValue="50" min="20" max="65"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height_unfolded" android:title="@string/pref_portrait_unfolded" android:summary="%s%%" android:defaultValue="35" min="10" max="50"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height_landscape_unfolded" android:title="@string/pref_landscape_unfolded" android:summary="%s%%" android:defaultValue="50" min="20" max="65"/>
</PreferenceScreen> </PreferenceScreen>
<PreferenceScreen android:title="@string/pref_horizontal_margin_title"> <PreferenceScreen android:title="@string/pref_horizontal_margin_title">
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="3" min="0" max="30"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="3" min="0" max="30"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="28" min="0" max="200"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="28" min="0" max="200"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_portrait_unfolded" android:title="@string/pref_portrait_unfolded" android:summary="%sdp" android:defaultValue="3" min="0" max="30"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_landscape_unfolded" android:title="@string/pref_landscape_unfolded" android:summary="%sdp" android:defaultValue="28" min="0" max="200"/>
</PreferenceScreen> </PreferenceScreen>
<juloo.keyboard2.prefs.SlideBarPreference android:key="character_size" android:title="@string/pref_character_size_title" android:summary="@string/pref_character_size_summary" android:defaultValue="1.15" min="0.75" max="1.5"/> <juloo.keyboard2.prefs.SlideBarPreference android:key="character_size" android:title="@string/pref_character_size_title" android:summary="@string/pref_character_size_summary" android:defaultValue="1.15" min="0.75" max="1.5"/>
<juloo.keyboard2.prefs.SlideBarPreference android:key="key_vertical_margin" android:title="@string/pref_key_vertical_space" android:summary="%s%%" android:defaultValue="1.5" min="0" max="5"/> <juloo.keyboard2.prefs.SlideBarPreference android:key="key_vertical_margin" android:title="@string/pref_key_vertical_space" android:summary="%s%%" android:defaultValue="1.5" min="0" max="5"/>

View File

@@ -5,11 +5,11 @@
let let
jdk = pkgs.openjdk17; jdk = pkgs.openjdk17;
build_tools_version = "34.0.0"; build_tools_version = "33.0.1";
android = pkgs.androidenv.composeAndroidPackages { android = pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [ build_tools_version ]; buildToolsVersions = [ build_tools_version ];
platformVersions = [ "35" ]; platformVersions = [ "34" ];
abiVersions = [ "armeabi-v7a" ]; abiVersions = [ "armeabi-v7a" ];
inherit repoJson; inherit repoJson;
}; };

View File

@@ -1,4 +1,4 @@
import textwrap, sys, re, string, json, os, string import textwrap, sys, re, string, json, os
from array import array from array import array
# Compile compose sequences from Xorg's format or from JSON files into an # Compile compose sequences from Xorg's format or from JSON files into an
@@ -21,20 +21,6 @@ def parse_keysymdef_h(fname):
yield (m.group(1), chr(int(m.group(2), 16))) yield (m.group(1), chr(int(m.group(2), 16)))
dropped_sequences = 0 dropped_sequences = 0
warning_count = 0
# [s] is a list of strings
def seq_to_str(s, result=None):
msg = "+".join(s)
return msg if result is None else msg + " = " + result
# Print a warning. If [seq] is passed, it is prepended to the message.
def warn(msg, seq=None, result=None):
global warning_count
if seq is not None:
msg = f"Sequence {seq_to_str(seq, result=result)} {msg}"
print(f"Warning: {msg}", file=sys.stderr)
warning_count += 1
# Parse XKB's Compose.pre files # Parse XKB's Compose.pre files
def parse_sequences_file_xkb(fname, xkb_char_extra_names): def parse_sequences_file_xkb(fname, xkb_char_extra_names):
@@ -124,7 +110,7 @@ def parse_sequences_file_json(fname):
tree = json.loads(strip_cstyle_comments(inp)) tree = json.loads(strip_cstyle_comments(inp))
return list(tree_to_seqs(tree, [])) return list(tree_to_seqs(tree, []))
except Exception as e: except Exception as e:
warn("Failed parsing '%s': %s" % (fname, str(e))) print("Failed parsing '%s': %s" % (fname, str(e)), file=sys.stderr)
# Format of the sequences file is determined by its extension # Format of the sequences file is determined by its extension
def parse_sequences_file(fname, xkb_char_extra_names={}): def parse_sequences_file(fname, xkb_char_extra_names={}):
@@ -177,9 +163,9 @@ def add_sequences_to_trie(seqs, trie):
for seq, result in seqs: for seq, result in seqs:
if not add_seq_to_trie(seq, result): if not add_seq_to_trie(seq, result):
dropped_sequences += 1 dropped_sequences += 1
warn("Sequence collide: '%s' and '%s = %s'" % ( print("Sequence collide: '%s' and '%s = %s'" % (
existing_sequence_to_str(seq), existing_sequence_to_str(seq),
"".join(seq), result)) "".join(seq), result), file=sys.stderr)
# Compile the trie into a state machine. # Compile the trie into a state machine.
def make_automata(tries): def make_automata(tries):
@@ -236,32 +222,6 @@ def print_automata(automata):
print("%3d %8s %d" % (i, s, e), file=sys.stderr) print("%3d %8s %d" % (i, s, e), file=sys.stderr)
i += 1 i += 1
# Report warnings about the compose sequences
def check_for_warnings(tries):
def get(seq):
t = tries
for c in seq:
if c not in t:
return None
t = t[c]
return t if type(t) == str else None
# Check that compose+Upper+Upper have an equivalent compose+Upper+Lower or compose+Lower+Lower
for c1 in string.ascii_uppercase:
for c2 in string.ascii_uppercase:
seq = [c1, c2]
seq_l = [c1, c2.lower()]
seq_ll = [c1.lower(), c2.lower()]
r = get(seq)
r_l = get(seq_l)
r_ll = get(seq_ll)
if r is not None:
ll_warning = f" (but {seq_to_str(seq_ll)} = {r_ll} exists)" if r_ll is not None else ""
if r_l is None:
if r != r_ll:
warn(f"has no lower case equivalent {seq_to_str(seq_l)}{ll_warning}", seq=seq, result=r)
elif r != r_l:
warn(f"is not the same as {seq_to_str(seq_l)} = {r_l}{ll_warning}", seq=seq, result=r)
def batched(ar, n): def batched(ar, n):
i = 0 i = 0
while i + n < len(ar): while i + n < len(ar):
@@ -330,10 +290,7 @@ for fname in sorted(sys.argv[1:]):
sequences = parse_sequences_file(fname) sequences = parse_sequences_file(fname)
add_sequences_to_trie(sequences, tries.setdefault(tname, {})) add_sequences_to_trie(sequences, tries.setdefault(tname, {}))
total_sequences += len(sequences) total_sequences += len(sequences)
check_for_warnings(tries["compose"])
entry_states, automata = make_automata(tries) entry_states, automata = make_automata(tries)
gen_java(entry_states, automata) gen_java(entry_states, automata)
print("Compiled %d sequences into %d states. Dropped %d sequences." % (total_sequences, len(automata), dropped_sequences), file=sys.stderr)
print("Compiled %d sequences into %d states. Dropped %d sequences. Generated %d warnings." % (total_sequences, len(automata), dropped_sequences, warning_count), file=sys.stderr)
# print_automata(automata) # print_automata(automata)

View File

@@ -7,56 +7,5 @@
"\\": { "\\": {
"n": "\\n", "n": "\\n",
"t": "\\t" "t": "\\t"
},
"n": {
"g": {
"~": "n͠g"
}
},
"N": {
"g": {
"~": "N͠g"
},
"g": "Ŋ",
"n": ""
},
"g": {
"~": "g̃",
"u": "Ğ"
},
"A": {
"a": "Å",
"e": "Æ",
"t": "@"
},
"a": {
"E": "Æ"
},
"O": {
"e": "Œ"
},
"S": {
"s": "ẞ"
},
"I": {
"j": "IJ"
},
"D": {
"h": "Ð"
},
"E": {
"e": "Ə"
},
"Q": {
"q": ""
},
"R": {
"r": ""
},
"T": {
"h": "Þ"
},
"Z": {
"z": ""
} }
} }

View File

@@ -88,16 +88,6 @@
"⊃": "⊇", "⊃": "⊇",
"±": "∓", "±": "∓",
// APL
"": "⍶",
"⍵": "⍹",
"⋄": "⌺",
"⍝": "⍧",
"∆": "⍙",
"∇": "⍢",
"": "⍡",
"⎕": "⍞",
// hebrew niqqud // hebrew niqqud
"ק": "qamats", // kamatz "ק": "qamats", // kamatz
"ר": "hataf_qamats", // reduced kamatz "ר": "hataf_qamats", // reduced kamatz

View File

@@ -125,14 +125,5 @@
"ॢ": "ॣ", "ॢ": "ॣ",
"॒": "॑", "॒": "॑",
"ॅ": "ॲ", "ॅ": "ॲ",
"ॉ": "ऑ", "ॉ": "ऑ"
// Mathematical symbols
"\uD835": {
"\uDD68": "𝕎", // 𝕨𝕎
"\uDD69": "𝕏", // 𝕩𝕏
"\uDD57": "𝔽", // 𝕗𝔽
"\uDD58": "𝔾", // 𝕘𝔾
"\uDD64": "𝕊" // 𝕤𝕊
}
} }

View File

@@ -1,6 +1,7 @@
package juloo.keyboard2; package juloo.keyboard2;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import android.text.InputType; import android.text.InputType;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
@@ -26,9 +27,9 @@ public final class Autocapitalisation
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
InputType.TYPE_TEXT_FLAG_CAP_WORDS; InputType.TYPE_TEXT_FLAG_CAP_WORDS;
public Autocapitalisation(Handler h, Callback cb) public Autocapitalisation(Looper looper, Callback cb)
{ {
_handler = h; _handler = new Handler(looper);
_callback = cb; _callback = cb;
} }
@@ -87,24 +88,6 @@ public final class Autocapitalisation
callback_now(true); callback_now(true);
} }
/** Pause auto capitalisation until [unpause()] is called. */
public boolean pause()
{
boolean was_enabled = _enabled;
stop();
_enabled = false;
return was_enabled;
}
/** Continue auto capitalisation after [pause()] was called. Argument is the
output of [pause()]. */
public void unpause(boolean was_enabled)
{
_enabled = was_enabled;
_should_update_caps_mode = true;
callback_now(true);
}
public static interface Callback public static interface Callback
{ {
public void update_shift_state(boolean should_enable, boolean should_disable); public void update_shift_state(boolean should_enable, boolean should_disable);

View File

@@ -49,7 +49,7 @@ public final class ClipboardHistoryService
/** The maximum size limits the amount of user data stored in memory but also /** The maximum size limits the amount of user data stored in memory but also
gives a sense to the user that the history is not persisted and can be gives a sense to the user that the history is not persisted and can be
forgotten as soon as the app stops. */ forgotten as soon as the app stops. */
public static final int MAX_HISTORY_SIZE = 6; public static final int MAX_HISTORY_SIZE = 3;
/** Time in ms until history entries expire. */ /** Time in ms until history entries expire. */
public static final long HISTORY_TTL_MS = 5 * 60 * 1000; public static final long HISTORY_TTL_MS = 5 * 60 * 1000;

View File

@@ -4,22 +4,31 @@ import java.util.Arrays;
public final class ComposeKey public final class ComposeKey
{ {
/** Apply the pending compose sequence to [kv]. Returns [null] if no sequence /** Apply the pending compose sequence to [kv]. */
matched. */
public static KeyValue apply(int state, KeyValue kv) public static KeyValue apply(int state, KeyValue kv)
{ {
switch (kv.getKind()) switch (kv.getKind())
{ {
case Char: case Char:
return apply(state, kv.getChar()); KeyValue res = apply(state, kv.getChar());
case String: // Grey-out characters not part of any sequence.
return apply(state, kv.getString()); if (res == null)
return kv.withFlags(kv.getFlags() | KeyValue.FLAG_GREYED);
return res;
/* Tapping compose again exits the pending sequence. */
case Compose_pending:
return KeyValue.getKeyByName("compose_cancel");
/* These keys are not greyed. */
case Event:
case Modifier:
return kv;
/* Other keys cannot be part of sequences. */
default:
return kv.withFlags(kv.getFlags() | KeyValue.FLAG_GREYED);
} }
return null;
} }
/** Apply the pending compose sequence to char [c]. Returns [null] if no /** Apply the pending compose sequence to char [c]. */
sequence matched. */
public static KeyValue apply(int prev, char c) public static KeyValue apply(int prev, char c)
{ {
char[] states = ComposeKeyData.states; char[] states = ComposeKeyData.states;
@@ -42,25 +51,6 @@ public final class ComposeKey
return KeyValue.makeCharKey((char)next_header); return KeyValue.makeCharKey((char)next_header);
} }
/** Apply each char of a string to a sequence. Returns [null] if no sequence
matched. */
public static KeyValue apply(int prev, String s)
{
final int len = s.length();
int i = 0;
if (len == 0) return null;
while (true)
{
KeyValue k = apply(prev, s.charAt(i));
i++;
if (k == null) return null;
if (i >= len) return k;
if (k.getKind() != KeyValue.Kind.Compose_pending)
return null; // Found a final state before the end of [s].
prev = k.getPendingCompose();
}
}
/** The state machine is comprised of two arrays. /** The state machine is comprised of two arrays.
The [states] array represents the different states and the associated The [states] array represents the different states and the associated

View File

@@ -56,72 +56,71 @@ public final class ComposeKeyData
"\u215b\u2151\u000035^\u2154\u2156\u0000458^\u00be\u2157\u215c\u00005\u2158\u000068\u215a\u215d\u00008\u215e\u00008\u221e\u0000()-.\u2395\u2639\u263a\u2234\u2360\u0000 AEIOSTU_aeiostu\u02db\u0218\u021a\u236e\u0219\u021b\u0000 \"'-/3<=" + "\u215b\u2151\u000035^\u2154\u2156\u0000458^\u00be\u2157\u215c\u00005\u2158\u000068\u215a\u215d\u00008\u215e\u00008\u221e\u0000()-.\u2395\u2639\u263a\u2234\u2360\u0000 AEIOSTU_aeiostu\u02db\u0218\u021a\u236e\u0219\u021b\u0000 \"'-/3<=" +
">CDELNRSTZ_cdelnrstz\u2395\u226e\u2665\u00ab\u2264\u22c4\u010c\u010e\u011a\u013d\u0147\u0158\u0160\u0164\u017d\u2343\u0000/<>CELNOPRTUWY^_cdeopruvy\u0415\u0417\u0421\u0423\u0437\u0443\u2395\u21d0\u21d2\u20ac" + ">CDELNRSTZ_cdelnrstz\u2395\u226e\u2665\u00ab\u2264\u22c4\u010c\u010e\u011a\u013d\u0147\u0158\u0160\u0164\u017d\u2343\u0000/<>CELNOPRTUWY^_cdeopruvy\u0415\u0417\u0421\u0423\u0437\u0443\u2395\u21d0\u21d2\u20ac" +
"\u20a4\u20a6\u0150\u20bd\u20b9\u20ae\u0170\u20a9\u00a5\u21d1\u2261\u20ab\u21d3\u04f2\u2338\u0000 \"'/<=>AEIOU_aeiou\u00a8\u2395\u226f\u2265\u00bb\u00c2\u00ca\u00ce\u00d4\u00db\u2369\u2344\u0000!+?AEIOUY\\^abeiouy\u00c2\u00ca\u00d4\u00e2\u00ea\u00f4\u0102" + "\u20a4\u20a6\u0150\u20bd\u20b9\u20ae\u0170\u20a9\u00a5\u21d1\u2261\u20ab\u21d3\u04f2\u2338\u0000 \"'/<=>AEIOU_aeiou\u00a8\u2395\u226f\u2265\u00bb\u00c2\u00ca\u00ce\u00d4\u00db\u2369\u2344\u0000!+?AEIOUY\\^abeiouy\u00c2\u00ca\u00d4\u00e2\u00ea\u00f4\u0102" +
"\u0103\u01a0\u01a1\u01af\u01b0\u2395\u2e18\u0000OUou\u1ede\u1eec\u00bf\u1ea2\u1eba\u1ec8\u1ece\u1ee6\u1ef6\u262d\u0000AEOaeo\u1ea8\u1ec2\u1ed4\u0000Aa\u1eb2\u2370\u0000\"'(*,-;>AET^_`aet~\u00a8\u00b4\u0102\u00c6@\u00c0\u00c3\u0000.|\u0e3f\u0000',./" + "\u0103\u01a0\u01a1\u01af\u01b0\u2395\u2e18\u0000OUou\u1ede\u1eec\u00bf\u1ea2\u1eba\u1ec8\u1ece\u1ee6\u1ef6\u262d\u0000AEOaeo\u1ea8\u1ec2\u1ed4\u0000Aa\u1eb2\u2370\u0000\"'(*,-;>AET^_`~\u00a8\u00b4\u0102\u00c6@\u00c0\u00c3\u0000.|\u0e3f\u0000',./<=C" +
"<=CEOr|\u2102\u20a0\u00a9\u20a2\u20b5\u0000,-.<Hh\u00d0\u0000\"',-.;<=>E^_`e\u00a8\u00b4\u018f\u00c8\u0000.Uilr\uFFFF\ud83d\udd95\uFFFF\ufb03\uFFFF\ufb04\u20a3\u0000(,.TU|\u02d8\u011e>\u20b2\u0000,\u0000\"',-." + "EOr|\u2102\u20a0\u00a9\u20a2\u20b5\u0000,-.<H\u00d0\u0000\"',-.;<=>E^_`\u00a8\u00b4\u018f\u00c8\u0000.Uilr\uFFFF\ud83d\udd95\uFFFF\ufb03\uFFFF\ufb04\u20a3\u0000(,.TU|\u02d8\u011e>\u20b2\u0000,\u0000\"',-.;>J^_" +
";>J^_`j~\u00a8\u00b4\u0132\u00cc\u0128\u0000'\u00b4\u0000,-\u0000',-/<=LTV\u0000A\u0000P\uFFFF\ud83d\udd96<\u0000.\u0000',<=GNOgno~\u014a\u2115\u2116\u00d1\u0000\"',-/;>ACERSXY^_" + "`j~\u00a8\u00b4\u0132\u00cc\u0128\u0000'\u00b4\u0000,-\u0000',-/<=LTV\u0000A\u0000P\uFFFF\ud83d\udd96<\u0000.\u0000',<=GNOo~\u014a\u2115\u2116\u00d1\u0000\"',-/;>ACERSXY^_`~\u00a8\u00b4\u0152\u00ae\u00a7" +
"`e~\u00a8\u00b4\u0152\u00ae\u00a7\u00a4\u262e\u00d2\u00d5\u0000!.=Pt\u00b6\u20a7\u0000Qq\u211a\u0000',<=ORrs\u211d\u20a8\u0000!',.;<MOSs|\u2120\u1e9e$\u0000,-./;<=HMh\u00de\u2122\u0000 !\"'*,-;" + "\u00a4\u262e\u00d2\u00d5\u0000!.=Pt\u00b6\u20a7\u0000Q\u211a\u0000',<=ORs\u211d\u20a8\u0000!',.;<MOS|\u2120\u1e9e$\u0000,-./;<=HM\u00de\u2122\u0000 !\"'*,-;>AEGIOU^_`ae" +
">AEGIOU^_`aegiou~\u00a8\u00b4\u00b8\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0416\u0418\u0423\u0430\u0435\u0436\u0438\u0443\u0000,\u0000Ee\u1e1c\u0000Aa\u1eb6\u0114\u012c\u014e\u016c\u00d9\u0103\u0115\u011f\u012d\u014f\u016d\u0168\u0000Ee\u1fb8\u1fd8\u1fe8\u1fb0\u1fd0\u1fe0\u04d0\u04d6\u04c1\u0419\u040e" + "giou~\u00a8\u00b4\u00b8\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0416\u0418\u0423\u0430\u0435\u0436\u0438\u0443\u0000,\u0000Ee\u1e1c\u0000Aa\u1eb6\u0114\u012c\u014e\u016c\u00d9\u0103\u0115\u011f\u012d\u014f\u016d\u0168\u0000Ee\u1fb8\u1fd8\u1fe8\u1fb0\u1fd0\u1fe0\u04d0\u04d6\u04c1\u0419\u040e\u04d1\u04d7\u04c2\u0439\u045e\u0000Lcsz\u0000=" +
"\u04d1\u04d7\u04c2\u0439\u045e\u0000Lcsz\u0000=^\u0174\u0000O\u0000\"'=^\u00a8\u00b4\u0176\u0000'.<Zz\u2124\u0000]\u2337\u0000-?not\u2395\u25cb\uFFFF\\\u006e\u0000/\uFFFF\ud83d\ude4c\uFFFF\\\u0074\u2342\u2349\u0000[\u0000!()+-./0123456" + "^\u0174\u0000O\u0000\"'=^\u00a8\u00b4\u0176\u0000'.<Z\u2124\u0000]\u2337\u0000-?not\u2395\u25cb\uFFFF\\\u006e\u0000/\uFFFF\ud83d\ude4c\uFFFF\\\u0074\u2342\u2349\u0000[\u0000!()+-./0123456789=ACEGHIJOS" +
"789=ACEGHIJOSUWYZ_aceghijosuwyz|\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u1eb8\u1eb9\u1ecc\u1ecd\u2212\u4e00\u4e01\u4e09\u4e0a\u4e0b\u4e19\u4e2d\u4e59\u4e8c\u4eba\u56db\u5730\u5929\u7532\u0000AEOaeo\u1eac\u1ec6" + "UWYZ_aceghijosuwyz|\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u1eb8\u1eb9\u1ecc\u1ecd\u2212\u4e00\u4e01\u4e09\u4e0a\u4e0b\u4e19\u4e2d\u4e59\u4e8c\u4eba\u56db\u5730\u5929\u7532\u0000AEOaeo\u1eac\u1ec6\u1ed8\u0108\u011c\u0124\u0134\u015c\u1e90\u0000ahijl" +
"\u1ed8\u0108\u011c\u0124\u0134\u015c\u1e90\u0000ahijlnorswxy\u0263\u0266\u0279\u027b\u0281\u0295\u02e4\uFFFF\u0410\u0302\uFFFF\u0415\u0302\uFFFF\u0418\u0302\uFFFF\u041e\u0302\uFFFF\u0420\u0302\uFFFF\u0423\u0302\uFFFF\u0440\u0302\u3192\u319c\u3194\u3196\u3198\u319b\u3197\u319a\u3193\u319f\u3195\u319e\u319d\u3199\u0000 !\"'()+-." + "norswxy\u0263\u0266\u0279\u027b\u0281\u0295\u02e4\uFFFF\u0410\u0302\uFFFF\u0415\u0302\uFFFF\u0418\u0302\uFFFF\u041e\u0302\uFFFF\u0420\u0302\uFFFF\u0423\u0302\uFFFF\u0440\u0302\u3192\u319c\u3194\u3196\u3198\u319b\u3197\u319a\u3193\u319f\u3195\u319e\u319d\u3199\u0000 !\"'()+-.0123456789;<=" +
"0123456789;<=>AEGIOUY^_aegiouy~\u00c4\u00c6\u00d5\u00d6\u00dc\u00e4\u00e6\u00f5\u00f6\u00fc\u0226\u0227\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u1e36\u1e37\u1e5a\u1e5b\u2206\u220a\u2212\u2218\u2260\u2282\u2283" + ">AEGIOUY^_aegiouy~\u00c4\u00c6\u00d5\u00d6\u00dc\u00e4\u00e6\u00f5\u00f6\u00fc\u0226\u0227\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u1e36\u1e37\u1e5a\u1e5b\u2206\u220a\u2212\u2218\u2260\u2282\u2283\u22a5\u22c4\u2373\u2375\u237a\u25cb\u0000LRlr\u1e38\u1e5c" +
"\u22a5\u22c4\u2373\u2375\u237a\u25cb\u0000LRlr\u1e38\u1e5c\u0000AOUaou\u01de\u022a\u01d5\u2358\u0000AEOaeo\u01e0\u0230\u0000Oo\u01ec\u1e20\u0232\u0000Oo\u022c\u01e2\u1fb9\u1fd9\u1fe9\uFFFF\u0410\u0304\uFFFF\u0415\u0304\u04e2\uFFFF\u041e\u0304\uFFFF\u0420\u0304\u04ee\uFFFF\u0430\u0304\uFFFF\u0435\u0304\uFFFF\u043e\u0304\uFFFF\u0440" + "\u0000AOUaou\u01de\u022a\u01d5\u2358\u0000AEOaeo\u01e0\u0230\u0000Oo\u01ec\u1e20\u0232\u0000Oo\u022c\u01e2\u1fb9\u1fd9\u1fe9\uFFFF\u0410\u0304\uFFFF\u0415\u0304\u04e2\uFFFF\u041e\u0304\uFFFF\u0420\u0304\u04ee\uFFFF\u0430\u0304\uFFFF\u0435\u0304\uFFFF\u043e\u0304\uFFFF\u0440\u0304\u2359\u2377\u235b\u2262\u2286\u2287\u234a\u235a\u2378\u2379\u2376\u235c" +
"\u0304\u2359\u2377\u235b\u2262\u2286\u2287\u234a\u235a\u2378\u2379\u2376\u235c\u0000\"()+AEINOUWY^_`abeinouwy\u00af\u00c2\u00ca\u00d4\u00dc\u00e2\u00ea\u00f4\u00fc\u0102\u0103\u0112\u0113\u014c\u014d\u01a0\u01a1\u01af\u01b0\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0410" + "\u0000\"()+AEINOUWY^_`abeinouwy\u00af\u00c2\u00ca\u00d4\u00dc\u00e2\u00ea\u00f4\u00fc\u0102\u0103\u0112\u0113\u014c\u014d\u01a0\u01a1\u01af\u01b0\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u0000U" +
"\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u0000Uu\u03b9\u03c5\u01db\u1fd2\u0000\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u1f0b\u1f1b\u1f2b\u1f3b\u1f4b\u1f5b\u1f6b\u1f03\u1f13\u1f23\u1f33\u1f43\u1f53\u1f63\u0000\u0391\u0395\u0397\u0399\u039f\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u1f0a\u1f1a\u1f2a\u1f3a\u1f4a\u1f6a\u1f02\u1f12\u1f22\u1f32\u1f42" + "u\u03b9\u03c5\u01db\u1fd2\u0000\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u1f0b\u1f1b\u1f2b\u1f3b\u1f4b\u1f5b\u1f6b\u1f03\u1f13\u1f23\u1f33\u1f43\u1f53\u1f63\u0000\u0391\u0395\u0397\u0399\u039f\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u1f0a\u1f1a\u1f2a\u1f3a\u1f4a\u1f6a\u1f02\u1f12\u1f22\u1f32\u1f42\u1f52\u1f62\u0000OUou\u1edc\u1eea\u01f8\u1e80\u1ef2\u0000" +
"\u1f52\u1f62\u0000OUou\u1edc\u1eea\u01f8\u1e80\u1ef2\u0000AEOaeo\u1ea6\u1ec0\u1ed2\u0000EOeo\u1e14\u1e50\u0000\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\uFFFF\u0410\u030f\uFFFF\u0415\u030f\uFFFF\u0418\u030f\uFFFF\u041e\u030f\uFFFF\u0420\u030f\uFFFF\u0423\u030f\u0000Aa\u1eb0\u0000EOeo\u1fba\u1fc8\u1fca" + "AEOaeo\u1ea6\u1ec0\u1ed2\u0000EOeo\u1e14\u1e50\u0000\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\uFFFF\u0410\u030f\uFFFF\u0415\u030f\uFFFF\u0418\u030f\uFFFF\u041e\u030f\uFFFF\u0420\u030f\uFFFF\u0423\u030f\u0000Aa\u1eb0\u0000EOeo\u1fba\u1fc8\u1fca\u1fda\u1ff8\u1fea\u1ffa\uFFFF\u0410\u0300\u0400\u040d\uFFFF\u041e\u0300\uFFFF" +
"\u1fda\u1ff8\u1fea\u1ffa\uFFFF\u0410\u0300\u0400\u040d\uFFFF\u041e\u0300\uFFFF\u0420\u0300\uFFFF\u0423\u0300\uFFFF\u0430\u0300\uFFFF\u043e\u0300\uFFFF\u0440\u0300\uFFFF\u0443\u0300\u0000\"'(*,-;>E^_`ae~\u00a8\u00b4\u00e6\u0000!,.AEGIOUaegiou\u00b8\u0391\u0399\u03a5\u03b1\u03b9\u03c5" + "\u0420\u0300\uFFFF\u0423\u0300\uFFFF\u0430\u0300\uFFFF\u043e\u0300\uFFFF\u0440\u0300\uFFFF\u0443\u0300\u0000\"'(*,-;>^_`ae~\u00a8\u00b4\u00e6\u0000!,.AEGIOUaegiou\u00b8\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0416\u0418\u0423\u0430\u0435\u0436\u0438\u0443\u0000Aa\u0000" +
"\u0410\u0415\u0416\u0418\u0423\u0430\u0435\u0436\u0438\u0443\u0000Aa\u0000Ee\u0000Ee\u0000\"',./<=ACDEGHIKLNORSTUZacdeghijklnorstuz|\u00dc\u00fc\u0000Uu\u01d9\u01cd\u01e6\u021e\u01cf\u01e8" + "Ee\u0000Ee\u0000\"',./<=ACDEGHIKLNORSTUZacdeghijklnorstuz|\u00dc\u00fc\u0000Uu\u01d9\u01cd\u01e6\u021e\u01cf\u01e8\u01d1\u01d3\u0000,-.<=hi\u00f0\u2300\u0000\"" +
"\u01d1\u01d3\u0000,-.<=hi\u00f0\u2300\u0000\"',-.;<=>^_`e\u00a8\u00b4\u0259\u0000.Sfils\u017f\uFFFF\ufb00\uFFFF\ufb01\uFFFF\ufb02\u0000(,.Utu~\u02d8\uFFFF\u0067\u0303\u0000,\u0000\"',-.;>^_`j~\u00a8\u00b4" + "',-.;<=>^_`e\u00a8\u00b4\u0259\u0000.Sfils\u017f\uFFFF\ufb00\uFFFF\ufb01\uFFFF\ufb02\u0000(,.Ut\u02d8\u0000,\u0000\"',-.;>^_`j~\u00a8\u00b4\u0133\u0000'\u00b4\u0000,k\u0138\u0000',-/<tv\u0000./" +
"\u0133\u0000'\u00b4\u0000,k\u0138\u0000',-/<tv\u0000./u\u0000',<g~\u014b\u0000\"',-/;>AU^_`aceorsuwxy~\u00a8\u00b4\u0153\u0000!.=o\u0000o\uFFFF\ud83d\udca9\u0000',<=\u0000!'" + "u\u0000',<g~\u014b\u0000\"',-/;>AU^_`aceorsuwxy~\u00a8\u00b4\u0153\u0000!.=o\u0000o\uFFFF\ud83d\udca9\u0000',<=\u0000!',.;<mos\u00b8\u00df\u0000,-./;<hm\u00fe" +
",.;<mos\u00b8\u00df\u0000,-./;<hm\u00fe\u0000\"'*,-/;>AEGIOU^_`aegiou~\u00a8\u00b4\u0000/ACDEGHIKNORSTUZacdeghijk" + "\u0000\"'*,-/;>AEGIOU^_`aegiou~\u00a8\u00b4\u0000/ACDEGHIKNORSTUZacdeghijklnorstuz|\u0000^\u0000ox\u00d7\u0000\"'=" +
"lnorstuz|\u0000^\u0000ox\u00d7\u0000\"'=^\u00a8\u00b4\u0000'.<\u0000}\u2205\u0000-=BCGS^cv~\u2190\u2192\u2206\u2207\u222a\u2282\u25cb\u2020\u2021\u236d\u2345\u2346\u234b\u2352\u2366\u2367\u233d\u0000\"()+0AEINOUVY^" + "^\u00a8\u00b4\u0000'.<\u0000}\u2205\u0000-=BCGS^cv~\u2190\u2192\u2206\u2207\u222a\u2282\u25cb\u2020\u2021\u236d\u2345\u2346\u234b\u2352\u2366\u2367\u233d\u0000\"()+0AEINOUVY^abeinouvy|~\u00a8\u00c2\u00ca\u00d4\u00e2\u00ea\u00f4\u0102" +
"abeinouvy|~\u00a8\u00c2\u00ca\u00d4\u00e2\u00ea\u00f4\u0102\u0103\u01a0\u01a1\u01af\u01b0\u03b1\u03b7\u03b9\u03c5\u03c9\u2207\u2227\u2228\u0000\u03b9\u03c5\u1fd7\u0000\u0391\u0397\u0399\u03a5\u03a9\u03b1\u03b7\u03b9\u03c5\u03c9\u1f0f\u1f2f\u1f3f\u1f5f\u1f6f\u1f07\u1f27\u1f37\u1f57\u1f67\u0000\u0391\u0397\u0399\u03a9\u03b1\u03b7\u03b9\u03c5\u03c9\u1f0e\u1f2e\u1f3e\u1f6e\u1f06" + "\u0103\u01a0\u01a1\u01af\u01b0\u03b1\u03b7\u03b9\u03c5\u03c9\u2207\u2227\u2228\u0000\u03b9\u03c5\u1fd7\u0000\u0391\u0397\u0399\u03a5\u03a9\u03b1\u03b7\u03b9\u03c5\u03c9\u1f0f\u1f2f\u1f3f\u1f5f\u1f6f\u1f07\u1f27\u1f37\u1f57\u1f67\u0000\u0391\u0397\u0399\u03a9\u03b1\u03b7\u03b9\u03c5\u03c9\u1f0e\u1f2e\u1f3e\u1f6e\u1f06\u1f26\u1f36\u1f56\u1f66\u0000OUou\u1ee0\u1eee\u1ebc\u1e7c\u1ef8\u0000AEOa" +
"\u1f26\u1f36\u1f56\u1f66\u0000OUou\u1ee0\u1eee\u1ebc\u1e7c\u1ef8\u0000AEOaeo\u1eaa\u1ec4\u1ed6\u0000Aa\u1eb4\u2248\u1fb6\u1fc6\u1fd6\u1fe6\u1ff6\u236b\u2372\u2371\u0000'*>AEIOUY`aeiouy~\u00b4\u2207\u2218\u22a4\u25cb\u1fed\u1fc1\u2361\u2365\u0000!\".;AEG" + "eo\u1eaa\u1ec4\u1ed6\u0000Aa\u1eb4\u2248\u1fb6\u1fc6\u1fd6\u1fe6\u1ff6\u236b\u2372\u2371\u0000'*>AEIOUY`aeiouy~\u00b4\u2207\u2218\u22a4\u25cb\u1fed\u1fc1\u2361\u2365\u0000!\".;AEGIOUYaegiouy~\u00c4\u00c6\u00d5\u00d6\u00dc\u00e4\u00e6" +
"IOUYaegiouy~\u00c4\u00c6\u00d5\u00d6\u00dc\u00e4\u00e6\u00f5\u00f6\u00fc\u0226\u0227\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u1e36\u1e37\u1e5a\u1e5b\u22a4\u0000LRlr\u0000AOUaou\u0000AOao\u0000Oo\u0000Oo\u2351\u0000" + "\u00f5\u00f6\u00fc\u0226\u0227\u0391\u0399\u03a5\u03b1\u03b9\u03c5\u0410\u0415\u0418\u041e\u0420\u0423\u0430\u0435\u0438\u043e\u0440\u0443\u1e36\u1e37\u1e5a\u1e5b\u22a4\u0000LRlr\u0000AOUaou\u0000AOao\u0000Oo\u0000Oo\u2351\u0000\"()+,/ACEGIJKLMNOPR" +
"\"()+,/ACEGIJKLMNOPRSUWYZ^_abcegijklmnoprsuwyz~\u00af\u00b8\u00c2\u00c5\u00c6\u00c7\u00ca\u00cf\u00d4\u00d5\u00d8\u00dc\u00e2\u00e5\u00e6\u00e7\u00ea\u00ef\u00f4\u00f5\u00f8\u00fc\u0102\u0103\u0112\u0113" + "SUWYZ^_abcegijklmnoprsuwyz~\u00af\u00b8\u00c2\u00c5\u00c6\u00c7\u00ca\u00cf\u00d4\u00d5\u00d8\u00dc\u00e2\u00e5\u00e6\u00e7\u00ea\u00ef\u00f4\u00f5\u00f8\u00fc\u0102\u0103\u0112\u0113\u014c\u014d\u0168\u0169\u01a0\u01a1\u01af\u01b0\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9" +
"\u014c\u014d\u0168\u0169\u01a0\u01a1\u01af\u01b0\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0410\u0413\u0415\u0418\u041a\u041e\u0420\u0423\u042b\u042d\u042e\u042f\u0430\u0433\u0435\u0438\u043a\u043e\u0440\u0443\u044b\u044d\u044e\u044f\u0000IUiu\u03b9\u03c5\u0000\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0000\u0391\u0395\u0397" + "\u03bf\u03c5\u03c9\u0410\u0413\u0415\u0418\u041a\u041e\u0420\u0423\u042b\u042d\u042e\u042f\u0430\u0433\u0435\u0438\u043a\u043e\u0440\u0443\u044b\u044d\u044e\u044f\u0000IUiu\u03b9\u03c5\u0000\u0391\u0395\u0397\u0399\u039f\u03a5\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0000\u0391\u0395\u0397\u0399\u039f\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0000OUou\u0000Cc\u0000" +
"\u0399\u039f\u03a9\u03b1\u03b5\u03b7\u03b9\u03bf\u03c5\u03c9\u0000OUou\u0000Cc\u0000Oo\u0000AEOaeo\u0000EOeo\u0000Aa\u0000OUou\u0000EOeo\u0000Cc\u0000CDEGHKLNRSTcdeghklnrst" + "Oo\u0000AEOaeo\u0000EOeo\u0000Aa\u0000OUou\u0000EOeo\u0000Cc\u0000CDEGHKLNRSTcdeghklnrst\u0228\u0000\u2395\u2339\u0000Gg\u0000'\u0000'\u0000'\u0000\"'\u0000'\u0000" +
"\u0228\u0000\u2395\u2339\u0000Gg\u0000'\u0000'\u0000'\u0000\"'\u0000'\u0000\"'\u0000'\u0000'\u0000'\u0000'\u0000\"'()`~\u00b4\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8d\u1f9d\u1fad\u1f85\u1f95\u1fa5\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8c\u1f9c\u1fac" + "\"'\u0000'\u0000'\u0000'\u0000'\u0000\"'()`~\u00b4\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8d\u1f9d\u1fad\u1f85\u1f95\u1fa5\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8c\u1f9c\u1fac\u1f84\u1f94\u1fa4\u1fb4\u1fc4\u1ff4\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f89\u1f99\u1fa9\u1f81\u1f91\u1fa1" +
"\u1f84\u1f94\u1fa4\u1fb4\u1fc4\u1ff4\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f89\u1f99\u1fa9\u1f81\u1f91\u1fa1\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f88\u1f98\u1fa8\u1f80\u1f90\u1fa0\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8b\u1f9b\u1fab\u1f83\u1f93\u1fa3\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8a\u1f9a\u1faa\u1f82\u1f92\u1fa2\u1fb2\u1fc2\u1ff2\u0000()\u03b1\u03b7" + "\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f88\u1f98\u1fa8\u1f80\u1f90\u1fa0\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8b\u1f9b\u1fab\u1f83\u1f93\u1fa3\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8a\u1f9a\u1faa\u1f82\u1f92\u1fa2\u1fb2\u1fc2\u1ff2\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8f\u1f9f\u1faf\u1f87\u1f97\u1fa7\u0000\u0391\u0397\u03a9\u03b1" +
"\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8f\u1f9f\u1faf\u1f87\u1f97\u1fa7\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1f8e\u1f9e\u1fae\u1f86\u1f96\u1fa6\u1fb7\u1fc7\u1ff7\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1fbc\u1fcc\u1ffc\u1fb3\u1fc3\u1ff3\u0000'\u0000\"'\u0000'\u0000=\u0000=\u0000\u041e\u043e\u0000=" + "\u03b7\u03c9\u1f8e\u1f9e\u1fae\u1f86\u1f96\u1fa6\u1fb7\u1fc7\u1ff7\u0000()\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u0000\u0391\u0397\u03a9\u03b1\u03b7\u03c9\u1fbc\u1fcc\u1ffc\u1fb3\u1fc3\u1ff3\u0000'\u0000\"'\u0000'\u0000=\u0000=\u0000\u041e\u043e\u0000=\u0000\u0435\u0443\u0447\u044b\u044c\ua64b\ua651\u0463\u0461\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e" +
"\u0000\u0435\u0443\u0447\u044b\u044c\ua64b\ua651\u0463\u0461\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u0069\u0067\u0075\uFFFF\ua659\uFFFF\ua64d\u0000\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u006c\u0061\u0076\u006f\u006e\u0069\u0063\u005f\u0070\u0073\u0069\u006c\u0069\u0000,.\u0439\u043a\u0445\u0458\u0491\u0481\u0000\u0435\u0436\u0437\u0439\u0458\u0465" + "\u0067\u005f\u0061\u0069\u0067\u0075\uFFFF\ua659\uFFFF\ua64d\u0000\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u006c\u0061\u0076\u006f\u006e\u0069\u0063\u005f\u0070\u0073\u0069\u006c\u0069\u0000,.\u0439\u043a\u0445\u0458\u0491\u0481\u0000\u0435\u0436\u0437\u0439\u0458\u0465\uFFFF\ua649\u045f\uFFFF\ua643\u0452\u0000\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f" +
"\uFFFF\ua649\u045f\uFFFF\ua643\u0452\u0000\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0074\u0072\u0065\u006d\u0061\u0000.\u0000=\u0444\u0499\u0000\u0438\u0443\u0475\u0000.\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0062\u0072\u0065\u0076\u0065\u0000,.\u0433\u0441\u0445\u0448\u046f\u0000,.\u044c\u0459\u0000.\u0000,\u00b7\u0447" + "\u0074\u0072\u0065\u006d\u0061\u0000.\u0000=\u0444\u0499\u0000\u0438\u0443\u0475\u0000.\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0062\u0072\u0065\u0076\u0065\u0000,.\u0433\u0441\u0445\u0448\u046f\u0000,.\u044c\u0459\u0000.\u0000,\u00b7\u0447\u044c\u0529\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0074\u0069\u0074\u006c\u006f\u045a" +
"\u044c\u0529\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0074\u0069\u0074\u006c\u006f\u045a\u0000\u0442\u0443\u0447\u047f\u0479\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0069\u006e\u0076\u0065\u0072\u0074\u0065\u0064\u005f\u0062\u0072\u0065\u0076\u0065\u0000\u0430\u0441\u0471\u0000\u0439\u0444\u0458\u045b\u0473\u0000\u0438\u0439\u0443\u0447\u0456\u0458\uFFFF\u0063\u006f\u006d\u0062" + "\u0000\u0442\u0443\u0447\u047f\u0479\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0069\u006e\u0076\u0065\u0072\u0074\u0065\u0064\u005f\u0062\u0072\u0065\u0076\u0065\u0000\u0430\u0441\u0471\u0000\u0439\u0444\u0458\u045b\u0473\u0000\u0438\u0439\u0443\u0447\u0456\u0458\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0070\u006f\u006b\u0072\u0079\u0074\u0069\u0065\u0000,.\u0447\uFFFF" +
"\u0069\u006e\u0069\u006e\u0067\u005f\u0070\u006f\u006b\u0072\u0079\u0074\u0069\u0065\u0000,.\u0447\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u006c\u0061\u0076\u006f\u006e\u0069\u0063\u005f\u0064\u0061\u0073\u0069\u0061\u0000.\u0430\u0431\u0435\u0439\u043d\u043e\u0443\u0445\u0447\u044a\u044e\u0458\u0467\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0070\u0061\u0079" + "\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u006c\u0061\u0076\u006f\u006e\u0069\u0063\u005f\u0064\u0061\u0073\u0069\u0061\u0000.\u0430\u0431\u0435\u0439\u043d\u043e\u0443\u0445\u0447\u044a\u044e\u0458\u0467\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0070\u0061\u0079\u0065\u0072\u006f\u006b\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0076\u0065\u0072\u0074" +
"\u0065\u0072\u006f\u006b\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0076\u0065\u0072\u0074\u0069\u0063\u0061\u006c\u005f\u0074\u0069\u006c\u0064\u0065\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0067\u0072\u0061\u0076\u0065\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0076\u007a\u006d\u0065\u0074\u0000\u0442\u0449\u0000\u0447\u0000\u0430\u0435\u043c\u043d\u0447" + "\u0069\u0063\u0061\u006c\u005f\u0074\u0069\u006c\u0064\u0065\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0067\u0072\u0061\u0076\u0065\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0076\u007a\u006d\u0065\u0074\u0000\u0442\u0449\u0000\u0447\u0000\u0430\u0435\u043c\u043d\u0447\uFFFF\ua653\u046d\u0469\u0000\u044c\uFFFF\ua65d\u0000\".\u0443\u0456\u0000\u0430\u0447\u0463\uFFFF\ua657" +
"\uFFFF\ua653\u046d\u0469\u0000\u044c\uFFFF\ua65d\u0000\".\u0443\u0456\u0000\u0430\u0447\u0463\uFFFF\ua657\u0000\u0442\u0000\u0447\u0000\u05d9\uFFFF\ufb1d\u0000\u05d0\u05f2\uFFFF\ufb2e\uFFFF\ufb1f\u0000\u05d0\uFFFF\ufb2f\u0000\u05d5\uFFFF\ufb4b\u0000\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d8\u05d9\u05da\u05db\u05dc\u05de\u05e0\u05e1\u05e3\u05e4\u05e6\u05e7\u05e8\u05e9\u05ea\uFFFF\ufb30\uFFFF\ufb31\uFFFF\ufb32\uFFFF" + "\u0000\u0442\u0000\u0447\u0000\u05d9\uFFFF\ufb1d\u0000\u05d0\u05f2\uFFFF\ufb2e\uFFFF\ufb1f\u0000\u05d0\uFFFF\ufb2f\u0000\u05d5\uFFFF\ufb4b\u0000\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d8\u05d9\u05da\u05db\u05dc\u05de\u05e0\u05e1\u05e3\u05e4\u05e6\u05e7\u05e8\u05e9\u05ea\uFFFF\ufb30\uFFFF\ufb31\uFFFF\ufb32\uFFFF\ufb33\uFFFF\ufb34\uFFFF\ufb35\uFFFF\ufb36\uFFFF\ufb38\uFFFF\ufb39\uFFFF\ufb3a\uFFFF\ufb3b\uFFFF\ufb3c\uFFFF\ufb3e" +
"\ufb33\uFFFF\ufb34\uFFFF\ufb35\uFFFF\ufb36\uFFFF\ufb38\uFFFF\ufb39\uFFFF\ufb3a\uFFFF\ufb3b\uFFFF\ufb3c\uFFFF\ufb3e\uFFFF\ufb40\uFFFF\ufb41\uFFFF\ufb43\uFFFF\ufb44\uFFFF\ufb46\uFFFF\ufb47\uFFFF\ufb48\uFFFF\ufb49\uFFFF\ufb4a\u0000\u05d1\u05db\u05e4\uFFFF\ufb4c\uFFFF\ufb4d\uFFFF\ufb4e\u0000\u05bc\u05e9\ufb49\u0000\u05e9\uFFFF\ufb2c\uFFFF\ufb2a\u0000\u05bc\u05e9\ufb49\u0000\u05e9\uFFFF\ufb2d\uFFFF\ufb2b\u0000\u0627\u0639\u0648\u064a" + "\uFFFF\ufb40\uFFFF\ufb41\uFFFF\ufb43\uFFFF\ufb44\uFFFF\ufb46\uFFFF\ufb47\uFFFF\ufb48\uFFFF\ufb49\uFFFF\ufb4a\u0000\u05d1\u05db\u05e4\uFFFF\ufb4c\uFFFF\ufb4d\uFFFF\ufb4e\u0000\u05bc\u05e9\ufb49\u0000\u05e9\uFFFF\ufb2c\uFFFF\ufb2a\u0000\u05bc\u05e9\ufb49\u0000\u05e9\uFFFF\ufb2d\uFFFF\ufb2b\u0000\u0627\u0639\u0648\u064a\u0667\u06cc\u06f7\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u006c\u0065\u0066\u005f" +
"\u0667\u06cc\u06f7\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u006c\u0065\u0066\u005f\u0061\u0062\u006f\u0076\u0065\u0623\u06c9\u063d\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u006c\u0065\u0066\u005f\u0062\u0065\u006c\u006f\u0077\u0000\u062f\u0631\u0634\u0646\u0637\u0691\u062b\u0679\u0000\u0634\u0686\u0000\u062d\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067" + "\u0061\u0062\u006f\u0076\u0065\u0623\u06c9\u063d\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u006c\u0065\u0066\u005f\u0062\u0065\u006c\u006f\u0077\u0000\u062f\u0631\u0634\u0646\u0637\u0691\u062b\u0679\u0000\u0634\u0686\u0000\u062d\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u0075\u006b\u0075\u006e\u0000\u062a\u0632\u06f7\u0630\u0695\u0000\u0634\u0635\u0000\u062a\u0000\u0627" +
"\u005f\u0073\u0075\u006b\u0075\u006e\u0000\u062a\u0632\u06f7\u0630\u0695\u0000\u0634\u0635\u0000\u062a\u0000\u0627\u0647\u0648\u064a\u0667\u0668\u06cc\u06f7\u06f8\u0625\u06c0\u0624\u0626\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0068\u0061\u006d\u007a\u0061\u005f\u0062\u0065\u006c\u006f\u0077\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0068\u0061\u006d\u007a\u0061\u005f\u0061\u0062" + "\u0647\u0648\u064a\u0667\u0668\u06cc\u06f7\u06f8\u0625\u06c0\u0624\u0626\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0068\u0061\u006d\u007a\u0061\u005f\u0062\u0065\u006c\u006f\u0077\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0068\u0061\u006d\u007a\u0061\u005f\u0061\u0062\u006f\u0076\u0065\u0000\u0643\u06a9\u06af\u0000\u0648\u06a1\u0000\u0648\u06ca\u0000\u0644\u0667\u06f7\uFFFF\u0063" +
"\u006f\u0076\u0065\u0000\u0643\u06a9\u06af\u0000\u0648\u06a1\u0000\u0648\u06ca\u0000\u0644\u0667\u06f7\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u0068\u0061\u0064\u0064\u0061\u0068\u06b5\u0000\u062a\u0647\u0648\u064a\u06cc\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0066\u0061\u0074\u0068\u0061\u0074\u0061\u006e\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f" + "\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0073\u0068\u0061\u0064\u0064\u0061\u0068\u06b5\u0000\u062a\u0647\u0648\u064a\u06cc\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0066\u0061\u0074\u0068\u0061\u0074\u0061\u006e\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0064\u0061\u006d\u006d\u0061\u0074\u0061\u006e\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f" +
"\u0064\u0061\u006d\u006d\u0061\u0074\u0061\u006e\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u006b\u0061\u0073\u0072\u0061\u0074\u0061\u006e\u0000 \u062a\u0639\u0646\u0647\u0648\u064a\u06cc\u06d5\u0629\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0066\u0061\u0074\u0068\u0061\u06c6\u06ce\u0000\u062b\u0639\u0641\u0646\u0648\u0667\u0668\u06f7\u06f8\u06cb\uFFFF\u0063\u006f\u006d\u0062" + "\u006b\u0061\u0073\u0072\u0061\u0074\u0061\u006e\u0000 \u062a\u0639\u0646\u0647\u0648\u064a\u06cc\u06d5\u0629\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0066\u0061\u0074\u0068\u0061\u06c6\u06ce\u0000\u062b\u0639\u0641\u0646\u0648\u0667\u0668\u06f7\u06f8\u06cb\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0064\u0061\u006d\u006d\u0061\u0068\u0000 \u0627\u0639\u0646\u064a\u0667" +
"\u0069\u006e\u0069\u006e\u0067\u005f\u0064\u0061\u006d\u006d\u0061\u0068\u0000 \u0627\u0639\u0646\u064a\u0667\u0668\u06f7\u06f8\u06d2\u0649\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u006b\u0061\u0073\u0072\u0061\u0000\u0627\u0622\u0000\u0627\u0648\u064a\u06c1\u06d2\u06d5\u06c2\u06d3\u0000\u0627\u0000\u0627\u0631\u0639\u0644\u0648\u064a\u0667\u06cc\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e" + "\u0668\u06f7\u06f8\u06d2\u0649\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u006b\u0061\u0073\u0072\u0061\u0000\u0627\u0622\u0000\u0627\u0648\u064a\u06c1\u06d2\u06d5\u06c2\u06d3\u0000\u0627\u0000\u0627\u0631\u0639\u0644\u0648\u064a\u0667\u06cc\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u0072\u0061\u0062\u0069\u0063\u005f\u0076\u0000\u0639\u0648\u064a\u0668\u06cc\uFFFF\u0063\u006f" +
"\u0067\u005f\u0061\u0072\u0061\u0062\u0069\u0063\u005f\u0076\u0000\u0639\u0648\u064a\u0668\u06cc\uFFFF\u0063\u006f\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u0072\u0061\u0062\u0069\u0063\u005f\u0069\u006e\u0076\u0065\u0072\u0074\u0065\u0064\u005f\u0076\u0000 \u0627\u0639\u0646\u0667\u0668\u06cc\u06f7\u06f8\u0000\u0627\u0631\u0639\u0644\u0648\u064a\u06cc\u06f7\u0000\u0639\u0648\u064a\u06cc\u06f8\u0000\u0915\u0916" + "\u006d\u0062\u0069\u006e\u0069\u006e\u0067\u005f\u0061\u0072\u0061\u0062\u0069\u0063\u005f\u0069\u006e\u0076\u0065\u0072\u0074\u0065\u0064\u005f\u0076\u0000 \u0627\u0639\u0646\u0667\u0668\u06cc\u06f7\u06f8\u0000\u0627\u0631\u0639\u0644\u0648\u064a\u06cc\u06f7\u0000\u0639\u0648\u064a\u06cc\u06f8\u0000\u0915\u0916\u0917\u091c\u0921\u0922\u0928\u092b\u092f\u0930\u0933\u0958\u0959\u095a\u095b\u095c\u095d\u0929\u095e\u095f\u0931" +
"\u0917\u091c\u0921\u0922\u0928\u092b\u092f\u0930\u0933\u0958\u0959\u095a\u095b\u095c\u095d\u0929\u095e\u095f\u0931\u0934\u0000\u09a1\u09a2\u09af\u09dc\u09dd\u09df\u0000\u09be\u09d7\u09cb\u09cc\u0000\u0a16\u0a17\u0a1c\u0a2b\u0a32\u0a38\u0a59\u0a5a\u0a5b\u0a5e\u0a33\u0a36\u0000\u0b21\u0b22\u0b5c\u0b5d\u0000\u0b3e\u0b56\u0b57\u0b4b\u0b48\u0b4c\u0000\u0bbe\u0bd7\u0bca\u0bcc\u0000\u0bbe\u0bcb\u0000\u0b92\u0b94\u0000\u0c56\u0c48\u0000" + "\u0934\u0000\u09a1\u09a2\u09af\u09dc\u09dd\u09df\u0000\u09be\u09d7\u09cb\u09cc\u0000\u0a16\u0a17\u0a1c\u0a2b\u0a32\u0a38\u0a59\u0a5a\u0a5b\u0a5e\u0a33\u0a36\u0000\u0b21\u0b22\u0b5c\u0b5d\u0000\u0b3e\u0b56\u0b57\u0b4b\u0b48\u0b4c\u0000\u0bbe\u0bd7\u0bca\u0bcc\u0000\u0bbe\u0bcb\u0000\u0b92\u0b94\u0000\u0c56\u0c48\u0000\u0cd5\u0cc0\u0000\u0cc2\u0cd5\u0cd6\u0cca\u0cc7\u0cc8\u0000\u0cd5\u0ccb\u0000\u0d3e\u0d57\u0d4a\u0d4c\u0000\u0d3e" +
"\u0cd5\u0cc0\u0000\u0cc2\u0cd5\u0cd6\u0cca\u0cc7\u0cc8\u0000\u0cd5\u0ccb\u0000\u0d3e\u0d57\u0d4a\u0d4c\u0000\u0d3e\u0d4b\u0000\u0dca\u0dcf\u0ddf\u0dda\u0ddc\u0dde\u0000\u0dca\u0ddd\u0000\u0f72\u0f74\u0f80\u0f73\u0f75\u0f81\u0000\u0fb5\u0fb9\u0000\u0fb7\u0f93\u0000\u0fb7\u0f9d\u0000\u0fb7\u0fa2\u0000\u0fb7\u0fa7\u0000\u0fb7\u0fac\u0000\u0f80\u0f76\u0000\u0f80\u0f78\u0000\u0f40\u0f69\u0000\u0f42\u0f4c\u0f51\u0f56\u0f5b\u0f43\u0f4d" + "\u0d4b\u0000\u0dca\u0dcf\u0ddf\u0dda\u0ddc\u0dde\u0000\u0dca\u0ddd\u0000\u0f72\u0f74\u0f80\u0f73\u0f75\u0f81\u0000\u0fb5\u0fb9\u0000\u0fb7\u0f93\u0000\u0fb7\u0f9d\u0000\u0fb7\u0fa2\u0000\u0fb7\u0fa7\u0000\u0fb7\u0fac\u0000\u0f80\u0f76\u0000\u0f80\u0f78\u0000\u0f40\u0f69\u0000\u0f42\u0f4c\u0f51\u0f56\u0f5b\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0000\u1025\u1026\u0000\u1100\u1101\u0000\u1100\u1102\u1103\u1107\u1113\u1114\u1115\u1116\u0000" +
"\u0f52\u0f57\u0f5c\u0000\u1025\u1026\u0000\u1100\u1101\u0000\u1100\u1102\u1103\u1107\u1113\u1114\u1115\u1116\u0000\u1100\u1103\u1117\u1104\u0000\u1102\u1105\u110b\u1112\u1118\u1119\u111b\u111a\u0000\u1107\u110b\u111c\u111d\u0000\u1100\u1102\u1103\u1107\u1109\u110a\u110b\u110c\u110e\u1110\u1111\u112b\u112d\u112f\u1132\u1136\u111e\u111f\u1120\u1108\u1121\u1125\u112b\u1127\u1128\u1129\u112a\u112c\u1122\u1123\u1124\u1126\u0000\u110b" + "\u1100\u1103\u1117\u1104\u0000\u1102\u1105\u110b\u1112\u1118\u1119\u111b\u111a\u0000\u1107\u110b\u111c\u111d\u0000\u1100\u1102\u1103\u1107\u1109\u110a\u110b\u110c\u110e\u1110\u1111\u112b\u112d\u112f\u1132\u1136\u111e\u111f\u1120\u1108\u1121\u1125\u112b\u1127\u1128\u1129\u112a\u112c\u1122\u1123\u1124\u1126\u0000\u110b\u0000\u1100\u1102\u1103\u1105\u1106\u1107\u1109\u110a\u110b\u110c\u110e\u110f\u1110\u1111\u1112\u111e\u112d\u112e" +
"\u0000\u1100\u1102\u1103\u1105\u1106\u1107\u1109\u110a\u110b\u110c\u110e\u110f\u1110\u1111\u1112\u111e\u112d\u112e\u112f\u1130\u1131\u1132\u110a\u1134\u1135\u1136\u1137\u1138\u1139\u113a\u113b\u1133\u0000\u1109\u0000\u1100\u1103\u1106\u1107\u1109\u110b\u110c\u110e\u1110\u1111\u1140\u1141\u1142\u1143\u1144\u1145\u1147\u1148\u1149\u114a\u114b\u1146\u0000\u110b\u110c\u114d\u110d\u0000\u110f\u1112\u1152\u1153\u0000\u1107\u110b\u1156" + "\u112f\u1130\u1131\u1132\u110a\u1134\u1135\u1136\u1137\u1138\u1139\u113a\u113b\u1133\u0000\u1109\u0000\u1100\u1103\u1106\u1107\u1109\u110b\u110c\u110e\u1110\u1111\u1140\u1141\u1142\u1143\u1144\u1145\u1147\u1148\u1149\u114a\u114b\u1146\u0000\u110b\u110c\u114d\u110d\u0000\u110f\u1112\u1152\u1153\u0000\u1107\u110b\u1156\u1157\u0000\u1112\u1158\u0000\u1100\u1103\u1107\u1109\u110c\u0000\u1100\u0000\u113c\u113d\u0000\u113e\u113f\u0000" +
"\u1157\u0000\u1112\u1158\u0000\u1100\u1103\u1107\u1109\u110c\u0000\u1100\u0000\u113c\u113d\u0000\u113e\u113f\u0000\u114e\u114f\u0000\u1150\u1151\u0000\u1169\u116e\u1175\u1176\u1177\u1162\u0000\u1169\u116d\u1175\u1178\u1179\u1164\u0000\u1169\u116e\u1173\u1175\u117a\u117b\u117c\u1166\u0000\u1169\u116e\u1175\u117d\u117e\u1168\u0000\u1161\u1162\u1165\u1166\u1168\u1169\u116e\u1175\u116a\u116b\u117f\u1180\u1181\u1182\u1183\u116c\u0000" + "\u114e\u114f\u0000\u1150\u1151\u0000\u1169\u116e\u1175\u1176\u1177\u1162\u0000\u1169\u116d\u1175\u1178\u1179\u1164\u0000\u1169\u116e\u1173\u1175\u117a\u117b\u117c\u1166\u0000\u1169\u116e\u1175\u117d\u117e\u1168\u0000\u1161\u1162\u1165\u1166\u1168\u1169\u116e\u1175\u116a\u116b\u117f\u1180\u1181\u1182\u1183\u116c\u0000\u1175\u0000\u1163\u1164\u1167\u1169\u1175\u1184\u1185\u1186\u1187\u1188\u0000\u1161\u1162\u1165\u1166\u1168\u116e" +
"\u1175\u0000\u1163\u1164\u1167\u1169\u1175\u1184\u1185\u1186\u1187\u1188\u0000\u1161\u1162\u1165\u1166\u1168\u116e\u1175\u117c\u1189\u118a\u116f\u1170\u118c\u118d\u1171\u118b\u0000\u1173\u1175\u0000\u1161\u1165\u1166\u1167\u1168\u116e\u1175\u118e\u118f\u1190\u1191\u1192\u1193\u1194\u0000\u116e\u1173\u1175\u1195\u1196\u1174\u0000\u116e\u1197\u0000\u1161\u1163\u1169\u116e\u1173\u119e\u1198\u1199\u119a\u119b\u119c\u119d\u0000\u1165" + "\u1175\u117c\u1189\u118a\u116f\u1170\u118c\u118d\u1171\u118b\u0000\u1173\u1175\u0000\u1161\u1165\u1166\u1167\u1168\u116e\u1175\u118e\u118f\u1190\u1191\u1192\u1193\u1194\u0000\u116e\u1173\u1175\u1195\u1196\u1174\u0000\u116e\u1197\u0000\u1161\u1163\u1169\u116e\u1173\u119e\u1198\u1199\u119a\u119b\u119c\u119d\u0000\u1165\u116e\u1175\u119e\u119f\u11a0\u11a1\u11a2\u0000\u11a8\u11af\u11ba\u11e7\u11a9\u11c3\u11aa\u11c4\u0000\u11a8\u0000" +
"\u116e\u1175\u119e\u119f\u11a0\u11a1\u11a2\u0000\u11a8\u11af\u11ba\u11e7\u11a9\u11c3\u11aa\u11c4\u0000\u11a8\u0000\u11a8\u11ae\u11ba\u11bd\u11c0\u11c2\u11eb\u11c5\u11c6\u11c7\u11ac\u11c9\u11ad\u11c8\u0000\u11a8\u11af\u11ca\u11cb\u0000\u11a8\u11aa\u11ab\u11ae\u11af\u11b7\u11b8\u11b9\u11ba\u11bb\u11bf\u11c0\u11c1\u11c2\u11da\u11dd\u11e5\u11e6\u11eb\u11f9\u11b0\u11cc\u11cd\u11ce\u11d0\u11b1\u11b2\u11d3\u11b3\u11d6\u11d8\u11b4\u11b5" + "\u11a8\u11ae\u11ba\u11bd\u11c0\u11c2\u11eb\u11c5\u11c6\u11c7\u11ac\u11c9\u11ad\u11c8\u0000\u11a8\u11af\u11ca\u11cb\u0000\u11a8\u11aa\u11ab\u11ae\u11af\u11b7\u11b8\u11b9\u11ba\u11bb\u11bf\u11c0\u11c1\u11c2\u11da\u11dd\u11e5\u11e6\u11eb\u11f9\u11b0\u11cc\u11cd\u11ce\u11d0\u11b1\u11b2\u11d3\u11b3\u11d6\u11d8\u11b4\u11b5\u11b6\u11d1\u11d2\u11d4\u11d5\u11d7\u11d9\u0000\u11ba\u0000\u11a8\u11ba\u0000\u11ba\u11bc\u11c2\u0000\u11ba\u0000" +
"\u11b6\u11d1\u11d2\u11d4\u11d5\u11d7\u11d9\u0000\u11ba\u0000\u11a8\u11ba\u0000\u11ba\u11bc\u11c2\u0000\u11ba\u0000\u11a8\u11af\u11b8\u11ba\u11bb\u11bc\u11be\u11c2\u11eb\u11da\u11db\u11dc\u11dd\u11de\u11e2\u11e0\u11e1\u11df\u0000\u11af\u11ba\u11bc\u11c1\u11c2\u11e3\u11b9\u11e6\u11e4\u11e5\u0000\u11a8\u11ae\u11af\u11b8\u11ba\u11e7\u11e8\u11e9\u11ea\u11bb\u0000\u11a8\u11a9\u11bc\u11bf\u11ec\u11ed\u11ee\u11ef\u0000\u11b8\u11bc\u11f3" + "\u11a8\u11af\u11b8\u11ba\u11bb\u11bc\u11be\u11c2\u11eb\u11da\u11db\u11dc\u11dd\u11de\u11e2\u11e0\u11e1\u11df\u0000\u11af\u11ba\u11bc\u11c1\u11c2\u11e3\u11b9\u11e6\u11e4\u11e5\u0000\u11a8\u11ae\u11af\u11b8\u11ba\u11e7\u11e8\u11e9\u11ea\u11bb\u0000\u11a8\u11a9\u11bc\u11bf\u11ec\u11ed\u11ee\u11ef\u0000\u11b8\u11bc\u11f3\u11f4\u0000\u11ab\u11af\u11b7\u11b8\u11f5\u11f6\u11f7\u11f8\u0000\u11c2\u11cf\u0000\u11ba\u0000\u11a8\u0000\u11ba" +
"\u11f4\u0000\u11ab\u11af\u11b7\u11b8\u11f5\u11f6\u11f7\u11f8\u0000\u11c2\u11cf\u0000\u11ba\u0000\u11a8\u0000\u11ba\u11eb\u11f1\u11f2\u0000|\u2395\u2347\u0000-\u2395\u2350\u0000|\u2395\u2348\u0000-\u2395\u2357\u0000/\u2204\u0000_|\u2395\u234d\u0000|~\u00a8\u2395\u2354\u0000/\u2209\u0000_\u0000/\u220c\u0000_\u00a8\u2229\u22a4\u22a5\u2395\u25cb\u235d\u2355\u234e\u233b" + "\u11eb\u11f1\u11f2\u0000|\u2395\u2347\u0000-\u2395\u2350\u0000|\u2395\u2348\u0000-\u2395\u2357\u0000/\u2204\u0000_|\u2395\u234d\u0000|~\u00a8\u2395\u2354\u0000/\u2209\u0000_\u0000/\u220c\u0000_\u00a8\u2229\u22a4\u22a5\u2395\u25cb\u235d\u2355\u234e\u233b\u233e\u0000/\u2224\u0000/\u2226\u0000~\u2228\u2395\u2353\u0000~\u2227\u2395\u234c\u0000\u2218" +
"\u233e\u0000/\u2224\u0000/\u2226\u0000~\u2228\u2395\u2353\u0000~\u2227\u2395\u234c\u0000\u2218\u0000|\u0000/\u2241\u0000/\u2244\u0000/\u2249\u0000/\u226d\u0000_\u2395\u236f\u0000/\u0000/\u2270\u0000/\u2271\u0000/\u2274\u0000/\u2275\u0000/\u2278\u0000/\u2279\u0000/\u2280\u0000/\u2281\u0000/\u22e0\u0000/\u22e1\u0000/_" + "\u0000|\u0000/\u2241\u0000/\u2244\u0000/\u2249\u0000/\u226d\u0000_\u2395\u236f\u0000/\u0000/\u2270\u0000/\u2271\u0000/\u2274\u0000/\u2275\u0000/\u2278\u0000/\u2279\u0000/\u2280\u0000/\u2281\u0000/\u22e0\u0000/\u22e1\u0000/_|\u2284\u0000/_\u2285\u0000/\u2288\u0000/\u2289\u0000/\u22e2\u0000/\u22e3\u0000" +
"|\u2284\u0000/_\u2285\u0000/\u2288\u0000/\u2289\u0000/\u22e2\u0000/\u22e3\u0000/\u22ac\u0000\u00a8\u00af\u2218\u22a5\u2336\u0000_\u2218\u22a4\u0000/\u22ad\u0000/\u22ae\u0000/\u22af\u0000/\u22ea\u0000/\u22eb\u0000/\u22ec\u0000/\u22ed\u0000_\u2395\u233a\u0000_\u0000_\u0000_\u0000'/:<=>?\\\u00f7" + "/\u22ac\u0000\u00a8\u00af\u2218\u22a5\u2336\u0000_\u2218\u22a4\u0000/\u22ad\u0000/\u22ae\u0000/\u22af\u0000/\u22ea\u0000/\u22eb\u0000/\u22ec\u0000/\u22ed\u0000_\u2395\u233a\u0000_\u0000_\u0000_\u0000'/:<=>?\\\u00f7\u2190\u2191\u2192\u2193\u2206\u2207\u2218\u2227\u2228\u2260\u22c4\u25cb\u233c\u0000*-.\\_" +
"\u2190\u2191\u2192\u2193\u2206\u2207\u2218\u2227\u2228\u2260\u22c4\u25cb\u233c\u0000*-.\\_|\u00a8\u2218\u2395\u0000/\u2adc\u0000 !\"%'()*,-.0123456789:<=>?[]^_abcehlopruyz{|}" + "|\u00a8\u2218\u2395\u0000/\u2adc\u0000 !\"%'()*,-.0123456789:<=>?[]^_abcehlopruyz{|}\u00a3\u00a7\u00b1\u00d7\u0398\u03a0\u03a3\u03b2\u03b3\u03b5\u03b8\u03ba\u03c0\u03c1\u03c3\u03c5\u03c6\u0430\u0435" +
"\u00a3\u00a7\u00b1\u00d7\u0398\u03a0\u03a3\u03b2\u03b3\u03b5\u03b8\u03ba\u03c0\u03c1\u03c3\u03c5\u03c6\u0430\u0435\u0437\u0438\u0439\u043b\u043c\u043d\u043e\u0441\u0443\u0447\u0448\u044a\u044b\u044c\u044d\u044f\u0456\u0458\u045f\u0461\u0481\u0487\u049b\u04b7\u04c8\u0513\u05d1\u05d3\u05d5\u05d6\u05d7\u05dd\u05e1\u05e3\u05e4\u05e6\u05e7\u05e8\u05e9\u0625\u0626\u0627\u0628\u0629\u062b\u062d\u0631\u0632\u0633\u0635\u0637\u0639\u063a" + "\u0437\u0438\u0439\u043b\u043c\u043d\u043e\u0441\u0443\u0447\u0448\u044a\u044b\u044c\u044d\u044f\u0456\u0458\u045f\u0461\u0481\u0487\u049b\u04b7\u04c8\u0513\u05d1\u05d3\u05d5\u05d6\u05d7\u05dd\u05e1\u05e3\u05e4\u05e6\u05e7\u05e8\u05e9\u0625\u0626\u0627\u0628\u0629\u062b\u062d\u0631\u0632\u0633\u0635\u0637\u0639\u063a\u063d\u0641\u0642\u0643\u0644\u0646\u0647\u064a\u064f\u0650\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668" +
"\u063d\u0641\u0642\u0643\u0644\u0646\u0647\u064a\u064f\u0650\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06a1\u06a9\u06c6\u06c9\u06cc\u06ce\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0901\u0902\u0905\u0906\u0907\u0908\u0909\u090a\u090b\u090c\u090f\u0910\u0913\u0914\u0915\u0916\u0917\u0918\u091a\u091b\u091c\u091d\u091f\u0921\u0922\u0923\u0925\u0926\u0928\u092a\u092b\u092c\u092f\u0930\u0933\u0935" + "\u0669\u06a1\u06a9\u06c6\u06c9\u06cc\u06ce\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0901\u0902\u0905\u0906\u0907\u0908\u0909\u090a\u090b\u090c\u090f\u0910\u0913\u0914\u0915\u0916\u0917\u0918\u091a\u091b\u091c\u091d\u091f\u0921\u0922\u0923\u0925\u0926\u0928\u092a\u092b\u092c\u092f\u0930\u0933\u0935\u0936\u0937\u093c\u093d\u093e\u093f\u0940\u0941\u0943\u0947\u0948\u094b\u094c\u0953\u0956\u0962\u0964\u0970\u0b92" +
"\u0936\u0937\u093c\u093d\u093e\u093f\u0940\u0941\u0943\u0947\u0948\u094b\u094c\u0953\u0956\u0962\u0964\u0970\u0b92\u0b9a\u0baf\u0bb3\u0bb5\u2020\u20ac\u20b9\u2190\u2191\u2192\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u2203\u2206\u2207\u2227\u2228\u2229\u222a\u222b\u2282\u2283\u22a4\u22b7\u22c4\u235d\u2375\u237a\u2395\ua649\ua651\ua67d\uFFFF\u006e\u0062\u0073\u0070\uFFFF\u0066\u0031\u0030\uFFFF\u0066\u0031\uFFFF\u0066\u0032\uFFFF" + "\u0b9a\u0baf\u0bb3\u0bb5\u2020\u20ac\u20b9\u2190\u2191\u2192\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u2203\u2227\u2228\u2229\u222a\u222b\u2282\u2283\u22b7\ua649\ua651\ua67d\uFFFF\u006e\u0062\u0073\u0070\uFFFF\u0066\u0031\u0030\uFFFF\u0066\u0031\uFFFF\u0066\u0032\uFFFF\u0066\u0033\uFFFF\u0066\u0034\uFFFF\u0066\u0035\uFFFF\u0066\u0036\uFFFF\u0066\u0037\uFFFF\u0066\u0038\uFFFF\u0066\u0039\uFFFF\u007a\u0077\u006e\u006a\u20b1\u20b4" +
"\u0066\u0033\uFFFF\u0066\u0034\uFFFF\u0066\u0035\uFFFF\u0066\u0036\uFFFF\u0066\u0037\uFFFF\u0066\u0038\uFFFF\u0066\u0039\uFFFF\u007a\u0077\u006e\u006a\u20b1\u20b4\u20bf\uFFFF\u0072\u0065\u006d\u006f\u0076\u0065\u0064\u2213\u2219\u03f4\u220f\u2211\u03d0\u0263\u03f5\u03d1\u03f0\u03d6\u03f1\u03c2\u03d2\u03d5\u0465\uFFFF\ua641\u0456\u0458\u046b\u0467\u047b\u0455\uFFFF\ua64b\u044c\uFFFF\ua651\u044a\u0454\u0438\uFFFF\ua66f\uFFFF\u0068" + "\u20bf\uFFFF\u0072\u0065\u006d\u006f\u0076\u0065\u0064\u2213\u2219\u03f4\u220f\u2211\u03d0\u0263\u03f5\u03d1\u03f0\u03d6\u03f1\u03c2\u03d2\u03d5\u0465\uFFFF\ua641\u0456\u0458\u046b\u0467\u047b\u0455\uFFFF\ua64b\u044c\uFFFF\ua651\u044a\u0454\u0438\uFFFF\ua66f\uFFFF\u0068\u0061\u0074\u0061\u0066\u005f\u0073\u0065\u0067\u006f\u006c\uFFFF\u0064\u0061\u0067\u0065\u0073\u0068\uFFFF\u0068\u006f\u006c\u0061\u006d\uFFFF\u0071\u0075\u0062" +
"\u0061\u0074\u0061\u0066\u005f\u0073\u0065\u0067\u006f\u006c\uFFFF\u0064\u0061\u0067\u0065\u0073\u0068\uFFFF\u0068\u006f\u006c\u0061\u006d\uFFFF\u0071\u0075\u0062\u0075\u0074\u0073\uFFFF\u0068\u0069\u0072\u0069\u0071\uFFFF\u0072\u0061\u0066\u0065\uFFFF\u0073\u0065\u0067\u006f\u006c\uFFFF\u0068\u0061\u0074\u0061\u0066\u005f\u0070\u0061\u0074\u0061\u0068\uFFFF\u0070\u0061\u0074\u0061\u0068\uFFFF\u0074\u0073\u0065\u0072\u0065\uFFFF" + "\u0075\u0074\u0073\uFFFF\u0068\u0069\u0072\u0069\u0071\uFFFF\u0072\u0061\u0066\u0065\uFFFF\u0073\u0065\u0067\u006f\u006c\uFFFF\u0068\u0061\u0074\u0061\u0066\u005f\u0070\u0061\u0074\u0061\u0068\uFFFF\u0070\u0061\u0074\u0061\u0068\uFFFF\u0074\u0073\u0065\u0072\u0065\uFFFF\u0071\u0061\u006d\u0061\u0074\u0073\uFFFF\u0068\u0061\u0074\u0061\u0066\u005f\u0071\u0061\u006d\u0061\u0074\u0073\uFFFF\u0073\u0068\u0065\u0076\u0061\u066e\u067e" +
"\u0071\u0061\u006d\u0061\u0074\u0073\uFFFF\u0068\u0061\u0074\u0061\u0066\u005f\u0071\u0061\u006d\u0061\u0074\u0073\uFFFF\u0073\u0068\u0065\u0076\u0061\u066e\u067e\u06c1\u0698\u0640\u0636\u0638\u0621\u06a4\u063a\u06a9\u06ba\u06be\u06cc\u0643\u064a\u0900\u0955\u0972\u0911\u0973\u0974\u0976\u0977\u0960\u0961\u090d\u090e\u0912\u0975\u097b\u097c\uFFFF\u0936\u094d\u091a\u0979\u0978\u097e\uFFFF\u0924\u094d\u0930\uFFFF\u0926\u094d\u0930" + "\u06c1\u0698\u0640\u0636\u0638\u0621\u06a4\u063a\u06a9\u06ba\u06be\u06cc\u0643\u064a\u0900\u0955\u0972\u0911\u0973\u0974\u0976\u0977\u0960\u0961\u090d\u090e\u0912\u0975\u097b\u097c\uFFFF\u0936\u094d\u091a\u0979\u0978\u097e\uFFFF\u0924\u094d\u0930\uFFFF\u0926\u094d\u0930\uFFFF\u092a\u094d\u0930\u097f\u097a\uFFFF\u0936\u094d\u0930\uFFFF\u0915\u094d\u0937\u094e\u097d\u0949\u093a\u093b\u0904\u0944\u0945\u0946\u094a\u094f\u0954\u0957" +
"\uFFFF\u092a\u094d\u0930\u097f\u097a\uFFFF\u0936\u094d\u0930\uFFFF\u0915\u094d\u0937\u094e\u097d\u0949\u093a\u093b\u0904\u0944\u0945\u0946\u094a\u094f\u0954\u0957\u0963\u0965\u0971\uFFFF\u0bd0\uFFFF\u0bf2\uFFFF\u0bf0\uFFFF\u0bf1\uFFFF\u0bf3\u21d4\u21d5\u21d6\u21d7\u21d8\u21d9\u22c0\u22c1\u22c2\u22c3\u222e\u22b6\u044b\u0483\u00000123456789\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec" + "\u0963\u0965\u0971\uFFFF\u0bd0\uFFFF\u0bf2\uFFFF\u0bf0\uFFFF\u0bf1\uFFFF\u0bf3\u21d4\u21d5\u21d6\u21d7\u21d8\u21d9\u22c0\u22c1\u22c2\u22c3\u222e\u22b6\u044b\u0483\u00000123456789\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u00000123456789\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u000001" +
"\u09ed\u09ee\u09ef\u00000123456789\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u00000123456789\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u00000123456789\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u000001234" + "23456789\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u00000123456789\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u00000123456789\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u00000123456789\u06f0" +
"56789\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u00000123456789\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u00000123456789\u0be6\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0000\u00df\u0131\u01f0\u0237\u02b0\u02b2\u02b3\u02b7\u02e1\u0905\u0907\u0909\u090b\u090c" + "\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u00000123456789\u0be6\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0000\u00df\u0131\u01f0\u0237\u02b0\u02b2\u02b3\u02b7\u02e1\u0905\u0907\u0909\u090b\u090c\u090f\u0913\u0915\u0917\u091a\u091c\u091f\u0921\u0924\u0926\u0928\u092c\u092e\u0932\u0938\u0939\u093f\u0941\u0943\u0945\u0947\u0949\u094b\u0952\u0962\u0a85\u0a87" +
"\u090f\u0913\u0915\u0917\u091a\u091c\u091f\u0921\u0924\u0926\u0928\u092c\u092e\u0932\u0938\u0939\u093f\u0941\u0943\u0945\u0947\u0949\u094b\u0952\u0962\u0a85\u0a87\u0a89\u0a8f\u0a93\u0a95\u0a97\u0a9a\u0a9c\u0a9f\u0aa1\u0aa4\u0aa6\u0aa8\u0aaa\u0aac\u0aae\u0ab2\u0ab8\u0ab9\u0abf\u0ac1\u0ac7\u0acb\u0bf9\u1d43\u1d47\u1d48\u1d49\u1d4d\u1d4f\u1d50\u1d52\u1d56\u1d57\u1d58\u1d5b\u1d60\u1d9c\u1da0\u1dbe\u1e97\u1e98\u1e99\u2071\u207f\u20b9" + "\u0a89\u0a8f\u0a93\u0a95\u0a97\u0a9a\u0a9c\u0a9f\u0aa1\u0aa4\u0aa6\u0aa8\u0aaa\u0aac\u0aae\u0ab2\u0ab8\u0ab9\u0abf\u0ac1\u0ac7\u0acb\u0bf9\u1d43\u1d47\u1d48\u1d49\u1d4d\u1d4f\u1d50\u1d52\u1d56\u1d57\u1d58\u1d5b\u1d60\u1d9c\u1da0\u1dbe\u1e97\u1e98\u1e99\u2071\u207f\u20b9\u2190\u2191\u2192\u2193\u2196\u2197\u2198\u2199\u2208\u220b\u2282\u2283\u2286\u2287\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\uFFFF\u004a" +
"\u2190\u2191\u2192\u2193\u2196\u2197\u2198\u2199\u2208\u220b\u2282\u2283\u2286\u2287\u2500\u2502\u250c\u2510\u2514\u2518\u251c\u2524\u252c\u2534\u253c\ud835\uFFFF\u004a\u030c\uFFFF\u004a\u0307\u1d34\u1d36\u1d3f\u1d42\u1d38\u0906\u0908\u090a\u0910\u0914\u0916\u0918\u091b\u091d\u0920\u0922\u0925\u0927\u0923\u092d\u0902\u0933\u0936\u0903\u0940\u0942\u0948\u094c\u0951\u0a86\u0a88\u0a8a\u0a90\u0a94\u0a96\u0a98\u0a9b\u0a9d\u0aa0\u0aa2" + "\u030c\uFFFF\u004a\u0307\u1d34\u1d36\u1d3f\u1d42\u1d38\u0906\u0908\u090a\u0910\u0914\u0916\u0918\u091b\u091d\u0920\u0922\u0925\u0927\u0923\u092d\u0902\u0933\u0936\u0903\u0940\u0942\u0948\u094c\u0951\u0a86\u0a88\u0a8a\u0a90\u0a94\u0a96\u0a98\u0a9b\u0a9d\u0aa0\u0aa2\u0aa5\u0aa7\u0aa3\u0aab\u0aad\u0a82\u0ab3\u0ab6\u0a83\u0ac0\u0ac2\u0ac8\u0acc\u1d2c\u1d2e\u1d30\u1d31\u1d33\u1d37\u1d39\u1d3c\u1d3e\u1d40\u1d41\u2c7d\u1db2\uFFFF\ua7f2" +
"\u0aa5\u0aa7\u0aa3\u0aab\u0aad\u0a82\u0ab3\u0ab6\u0a83\u0ac0\u0ac2\u0ac8\u0acc\u1d2c\u1d2e\u1d30\u1d31\u1d33\u1d37\u1d39\u1d3c\u1d3e\u1d40\u1d41\u2c7d\u1db2\uFFFF\ua7f2\uFFFF\ua7f3\u1d23\uFFFF\u0054\u0308\uFFFF\u0057\u030a\uFFFF\u0059\u030a\u1d35\u1d3a\u2550\u2551\u2554\u2557\u255a\u255d\u2560\u2563\u2566\u2569\u256c\u0000\udd57\udd58\udd64\udd68\udd69\uFFFF\ud835\udd3d\uFFFF\ud835\udd3e\uFFFF\ud835\udd4a\uFFFF\ud835\udd4e\uFFFF" + "\uFFFF\ua7f3\u1d23\uFFFF\u0054\u0308\uFFFF\u0057\u030a\uFFFF\u0059\u030a\u1d35\u1d3a\u2550\u2551\u2554\u2557\u255a\u255d\u2560\u2563\u2566\u2569\u256c").toCharArray();
"\ud835\udd4f").toCharArray();
public static final char[] edges = public static final char[] edges =
("\u0001\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0059\u005a\u005b\\\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0067\u0068\u006b\u006e\u006f\u0072\u0075\u0078\u007b\u007e\u0081\u0001\u0001\u0001\u0001\u0001\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + ("\u0001\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0059\u005a\u005b\\\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0067\u0068\u006b\u006e\u006f\u0072\u0075\u0078\u007b\u007e\u0081\u0001\u0001\u0001\u0001\u0001\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" +
@@ -142,10 +141,10 @@ public final class ComposeKeyData
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0012\u048a\u048b\u048c\u048d\u048e\u048f\u0490" + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0012\u048a\u048b\u048c\u048d\u048e\u048f\u0490" +
"\u0491\u0180\u0199\u0052\u0492\u005b\u0493\u032d\u02ff\u0300\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u002f\u04c3\u04c4\u04c5\u04c8\u04c9\u04ca\u04cb\u04ce\u04d1\u04d4\u04d7\u04da\u04db\u04de\u04df\u04e0\u04e1\u04e2\u04e3\u04e4\u0050\u0492\u02c5\u0054\u032b\u032e\u032f\u0115\u04e5\u04e6\u04e7\u04e8\u04e9\u04ea\u04eb\u04ec\u04ed\u04ee\u04ef\u04f0\u04f1\u04f2\u00cf\u04f3\u04f4\u04f5\u0001\u0001\u0003\u0000\u0000" + "\u0491\u0180\u0199\u0052\u0492\u005b\u0493\u032d\u02ff\u0300\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u002f\u04c3\u04c4\u04c5\u04c8\u04c9\u04ca\u04cb\u04ce\u04d1\u04d4\u04d7\u04da\u04db\u04de\u04df\u04e0\u04e1\u04e2\u04e3\u04e4\u0050\u0492\u02c5\u0054\u032b\u032e\u032f\u0115\u04e5\u04e6\u04e7\u04e8\u04e9\u04ea\u04eb\u04ec\u04ed\u04ee\u04ef\u04f0\u04f1\u04f2\u00cf\u04f3\u04f4\u04f5\u0001\u0001\u0003\u0000\u0000" +
"\u0001\u0001\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0136\u062c\u063d\u0689\u06f5\u0704\u0707\u083c\u0bf4\u0c15\u0c24\u0c2f\u0c6f\u0cae\u0d24\u0d66\u0d6c\u0d82\u0d88\u0d90\u0d93\u0d98\u0d9b\u0d9e\u0da8\u0dbf" + "\u0001\u0001\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0136\u062c\u063d\u0689\u06f5\u0704\u0707\u083c\u0bf4\u0c15\u0c24\u0c2f\u0c6f\u0cae\u0d24\u0d66\u0d6c\u0d82\u0d88\u0d90\u0d93\u0d98\u0d9b\u0d9e\u0da8\u0dbf" +
"\u0dec\u0e1f\u0e3e\u0e7d\u0e97\u0e9b\u0eac\u0eb4\u0ec7\u0ed5\u0ee0\u0ee2\u0ef5\u0ef8\u0efb\u0f0d\u0f0f\u0f1f\u0f3c\u0f44\u0f48\u0f53\u0f62\u0f6f\u0fc5\u0fca\u0fce\u0fd0\u0fd8\u0fdf\u0fe2\u0ff7\u0ff9\u108e\u1135\u121e\u1231\u125b\u1292\u129c\u12ad\u12bb\u12c7\u12c9\u12d9\u12dc\u12e0\u12e8\u12ec\u12f3\u130e\u1318\u131d\u1329\u1333\u134e\u1371\u1373\u1377\u137e\u1382\u1385\u13a1\u141d\u1438\u1487\u1549\u1561\u1564\u1567\u1569\u156b" + "\u0dec\u0e1f\u0e3e\u0e7d\u0e94\u0e98\u0ea9\u0eb0\u0ec2\u0ed0\u0edb\u0edd\u0ef0\u0ef3\u0ef6\u0f08\u0f0a\u0f18\u0f34\u0f3c\u0f3f\u0f49\u0f57\u0f63\u0fb9\u0fbe\u0fc2\u0fc4\u0fcc\u0fd2\u0fd5\u0fea\u0fec\u1081\u1128\u1211\u1223\u124d\u1284\u128e\u129f\u12ad\u12b4\u12b6\u12c6\u12c9\u12cd\u12d5\u12d9\u12e0\u12fb\u1305\u130a\u1316\u1320\u133b\u135e\u1360\u1364\u136b\u136f\u1372\u138e\u140a\u1425\u1474\u1536\u154e\u1551\u1554\u1556\u1558" +
"\u156d\u1570\u1572\u1575\u1577\u1579\u157b\u157d\u1628\u162a\u162d\u162f\u1631\u1633\u1636\u1638\u1655\u1670\u1679\u1686\u1698\u169a\u169e\u16a2\u16b5\u16bd\u16c2\u16c4\u16db\u16fa\u16fe\u1704\u171e\u173b\u1795\u1798\u179a\u17a4\u17a8\u17ad\u17b3\u17b5\u17b7\u17bb\u17c2\u17c6\u17ca\u180d\u1817\u1821\u182b\u1860\u1869\u186c\u187e\u1884\u1887\u1889\u18c3\u18c7\u18ca\u18cd\u18e4\u1923\u1940\u195c\u1978\u197b\u1984\u1986\u19a2\u19c4" + "\u155a\u155d\u155f\u1562\u1564\u1566\u1568\u156a\u1615\u1617\u161a\u161c\u161e\u1620\u1623\u1625\u1642\u165d\u1666\u1673\u1685\u1687\u168b\u168f\u16a2\u16aa\u16af\u16b1\u16c8\u16e7\u16eb\u16f1\u170b\u1728\u1782\u1785\u1787\u1791\u1795\u179a\u17a0\u17a2\u17a4\u17a8\u17af\u17b3\u17b7\u17fa\u1804\u180e\u1818\u184d\u1856\u1859\u186b\u1871\u1874\u1876\u18b0\u18b4\u18b7\u18ba\u18d1\u1910\u192d\u1949\u1965\u1968\u1971\u1973\u198f\u19b1" +
"\u19ce\u19d7\u19dd\u19f4\u19fb\u1a00\u1a0d\u1a12\u1a19\u1a1e\u1a21\u1a24\u1a27\u1a2a\u1a31\u1a34\u1a39\u1a3c\u1a43\u1a46\u1a4d\u1a50\u1a53\u1a56\u1a59\u1a5c\u1a5f\u1a62\u1a65\u1a68\u1a73\u1a76\u1a79\u1a82\u1a87\u1a90\u1a95\u1ab6\u1ab8\u1ad9\u1adb\u1af2\u1af7\u1afc\u1b01\u1b04\u1b0a\u1b0c\u1b0f\u1b12\u1b15\u1b18\u1b1f\u1b26\u1b2f\u1b36\u1b47\u1b49\u1b54\u1b65\u1b68\u1b77\u1b7e\u1b81\u1b8e\u1b97\u1ba0\u1ba2\u1bb1\u1bb6\u1bdf\u1be1" + "\u19bb\u19c4\u19ca\u19e1\u19e8\u19ed\u19fa\u19ff\u1a06\u1a0b\u1a0e\u1a11\u1a14\u1a17\u1a1e\u1a21\u1a26\u1a29\u1a30\u1a33\u1a3a\u1a3d\u1a40\u1a43\u1a46\u1a49\u1a4c\u1a4f\u1a52\u1a55\u1a60\u1a63\u1a66\u1a6f\u1a74\u1a7d\u1a82\u1aa3\u1aa5\u1ac6\u1ac8\u1adf\u1ae4\u1ae9\u1aee\u1af1\u1af7\u1af9\u1afc\u1aff\u1b02\u1b05\u1b0c\u1b13\u1b1c\u1b23\u1b34\u1b36\u1b41\u1b52\u1b55\u1b64\u1b6b\u1b6e\u1b7b\u1b84\u1b8d\u1b8f\u1b9e\u1ba3\u1bcc\u1bce" +
"\u1be4\u1be8\u1bea\u1bfd\u1c08\u1c13\u1c1c\u1c21\u1c2a\u1c2d\u1c2f\u1c31\u1c36\u1c3a\u1c3e\u1c42\u1c46\u1c49\u1c4e\u1c54\u1c57\u1c59\u1c5c\u1c69\u1c6c\u1c6f\u1c74\u1c79\u1c7b\u1c7d\u1c80\u1c83\u1c86\u1c89\u1c8d\u1c8f\u1c92\u1c95\u1c98\u1c9b\u1c9e\u1ca1\u1ca4\u1ca7\u1caa\u1cad\u1cb2\u1cb6\u1cb9\u1cbc\u1cbf\u1cc2\u1cc5\u1ccb\u1ccf\u1cd2\u1cd5\u1cd8\u1cdb\u1cde\u1ce1\u1ce4\u1ce8\u1cea\u1cec\u1cee\u1d05\u1d0f\u0009\u0635\u0636\u0637" + "\u1bd1\u1bd5\u1bd7\u1bea\u1bf5\u1c00\u1c09\u1c0e\u1c17\u1c1a\u1c1c\u1c1e\u1c23\u1c27\u1c2b\u1c2f\u1c33\u1c36\u1c3b\u1c41\u1c44\u1c46\u1c49\u1c56\u1c59\u1c5c\u1c61\u1c66\u1c68\u1c6a\u1c6d\u1c70\u1c73\u1c76\u1c7a\u1c7c\u1c7f\u1c82\u1c85\u1c88\u1c8b\u1c8e\u1c91\u1c94\u1c97\u1c9a\u1c9f\u1ca3\u1ca6\u1ca9\u1cac\u1caf\u1cb2\u1cb8\u1cbc\u1cbf\u1cc2\u1cc5\u1cc8\u1ccb\u1cce\u1cd1\u1cd5\u1cd7\u1cd9\u1cdb\u1cf2\u1cfc\u0009\u0635\u0636\u0637" +
"\u0638\u0639\u063a\u063b\u063c\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u002f\u066c\u066d\u0674\u0675\u0676\u0677\u0678\u0679\u067a\u067b\u067c\u067d\u067e\u067f\u0680\u0681\u0682\u0683\u0684\u0685\u0686\u0687\u0688\u023e\u023f\u0240\u0241\u0242\u0243\u0244\u0245\u0246\u0247\u0248\u0249\u024a\u024b\u024c\u024d\u024e\u024f\u0250\u0672\u0252\u0673\u0253\u0001\u0005\u0672\u0673\u0252\u0253\u0001\u0001\u0001\u0001\u0001\u0001" + "\u0638\u0639\u063a\u063b\u063c\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u002f\u066c\u066d\u0674\u0675\u0676\u0677\u0678\u0679\u067a\u067b\u067c\u067d\u067e\u067f\u0680\u0681\u0682\u0683\u0684\u0685\u0686\u0687\u0688\u023e\u023f\u0240\u0241\u0242\u0243\u0244\u0245\u0246\u0247\u0248\u0249\u024a\u024b\u024c\u024d\u024e\u024f\u0250\u0672\u0252\u0673\u0253\u0001\u0005\u0672\u0673\u0252\u0253\u0001\u0001\u0001\u0001\u0001\u0001" +
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0041\u06ca\u06ca\u06cb\u06cc\u06cd\u06ce\u06cf\u06d0\u06d1\u06d2\u06d3\u06d4\u06d5\u06d6\u06d7\u06d8\u04c4\u04c8\u04c9\u04ca\u04da\u04de\u04df\u04e0\u04e1\u04e2\u06dd\u06e1\u06cb\u06e0\u0492\u06db\u06dc\u06e4\u06e5\u04e5\u04e6\u04e8\u06e6\u06e7\u06e8\u06e9\u06ea\u06eb\u06ec\u06ed\u06ee\u06ef\u06f0\u04e9\u06f1\u04ea\u04eb\u04ec" + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0041\u06ca\u06ca\u06cb\u06cc\u06cd\u06ce\u06cf\u06d0\u06d1\u06d2\u06d3\u06d4\u06d5\u06d6\u06d7\u06d8\u04c4\u04c8\u04c9\u04ca\u04da\u04de\u04df\u04e0\u04e1\u04e2\u06dd\u06e1\u06cb\u06e0\u0492\u06db\u06dc\u06e4\u06e5\u04e5\u04e6\u04e8\u06e6\u06e7\u06e8\u06e9\u06ea\u06eb\u06ec\u06ed\u06ee\u06ef\u06f0\u04e9\u06f1\u04ea\u04eb\u04ec" +
"\u04ed\u04ee\u04ef\u04f0\u04f1\u06f2\u06f3\u04f2\u06f4\u00cf\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u06db\u06dc\u0001\u0001\u0003\u06e0\u0492\u0001\u0003\u06db\u06dc\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0008\u06fd\u06fe\u06ff\u0700\u0701\u0702\u0703\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0706\u0001\u007b" + "\u04ed\u04ee\u04ef\u04f0\u04f1\u06f2\u06f3\u04f2\u06f4\u00cf\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u06db\u06dc\u0001\u0001\u0003\u06e0\u0492\u0001\u0003\u06db\u06dc\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0008\u06fd\u06fe\u06ff\u0700\u0701\u0702\u0703\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0706\u0001\u007b" +
@@ -175,72 +174,71 @@ public final class ComposeKeyData
"\u0001\u0001\u0004\u0d86\u0d87\u0433\u0001\u0001\u0005\u0d8d\u0d8e\u0d8f\u0434\u0001\u0001\u0001\u0002\u0d92\u0001\u0003\u0d96\u0d97\u0001\u0001\u0002\u0d9a\u0001\u0002\u0d9d\u0001\u0006\u0da4\u0da5\u0ca0\u0da6\u0da7\u0001\u0001\u0001\u0001\u0011\u0db9\u0c5a\u0c5d\u0c60\u0c64\u0dba\u0dbb\u0c68\u0dbc\u033f\u0340\u0341\u0342\u0dbd\u0dbe\u0343\u0001\u0001\u0001\u0001\u0001\u0001\u001e\u063a\u06cd\u07d3\u0093\u0ddd\u0dde\u0ddf\u0de0" + "\u0001\u0001\u0004\u0d86\u0d87\u0433\u0001\u0001\u0005\u0d8d\u0d8e\u0d8f\u0434\u0001\u0001\u0001\u0002\u0d92\u0001\u0003\u0d96\u0d97\u0001\u0001\u0002\u0d9a\u0001\u0002\u0d9d\u0001\u0006\u0da4\u0da5\u0ca0\u0da6\u0da7\u0001\u0001\u0001\u0001\u0011\u0db9\u0c5a\u0c5d\u0c60\u0c64\u0dba\u0dbb\u0c68\u0dbc\u033f\u0340\u0341\u0342\u0dbd\u0dbe\u0343\u0001\u0001\u0001\u0001\u0001\u0001\u001e\u063a\u06cd\u07d3\u0093\u0ddd\u0dde\u0ddf\u0de0" +
"\u0de1\u0de2\u0de3\u0de4\u0de5\u0de6\u0de7\u0de8\u0de9\u0dea\u0de0\u0105\u0106\u0107\u010d\u010e\u0110\u0111\u0112\u0114\u0deb\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0021\u0d4d\u0e0d\u0e0e\u0e0f\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e0f\u0e1b\u0e0f\u026b\u0e13\u0e14\u026c\u0e1c\u0e18\u0e0f\u0e13\u0e0f\u0e1d\u0e13\u0270\u0e1e\u0001\u0001\u0001" + "\u0de1\u0de2\u0de3\u0de4\u0de5\u0de6\u0de7\u0de8\u0de9\u0dea\u0de0\u0105\u0106\u0107\u010d\u010e\u0110\u0111\u0112\u0114\u0deb\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0021\u0d4d\u0e0d\u0e0e\u0e0f\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e0f\u0e1b\u0e0f\u026b\u0e13\u0e14\u026c\u0e1c\u0e18\u0e0f\u0e13\u0e0f\u0e1d\u0e13\u0270\u0e1e\u0001\u0001\u0001" +
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0015\u063b\u06ce\u07d4\u0e34\u0de1\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e3b\u0e35\u0170\u0172\u0175\u0177\u0178\u0e3c\u0e3d\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0020\u0e5e\u0e5f\u0e66\u0e67\u0e68\u0e69\u0e6a\u0e6b\u0e6c\u0e6d\u0e6e\u02e7\u0e78\u02e8\u02e9\u02ea\u02eb\u02ec\u0e75\u0e76\u0e77\u0196\u0198\u0185\u0e7b" + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0015\u063b\u06ce\u07d4\u0e34\u0de1\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e3b\u0e35\u0170\u0172\u0175\u0177\u0178\u0e3c\u0e3d\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0020\u0e5e\u0e5f\u0e66\u0e67\u0e68\u0e69\u0e6a\u0e6b\u0e6c\u0e6d\u0e6e\u02e7\u0e78\u02e8\u02e9\u02ea\u02eb\u02ec\u0e75\u0e76\u0e77\u0196\u0198\u0185\u0e7b" +
"\u02ed\u0e64\u02ee\u0e65\u02ef\u0e7c\u0001\u0005\u0e64\u0e65\u02ee\u02ef\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u0e75\u0e76\u0e77\u0196\u0198\u0185\u0001\u0001\u0001\u0003\u0e7b\u02ed\u0001\u0001\u0015\u06cf\u07d5\u0e92\u0c21\u0c5a\u0ca1\u0c5a\u0e37\u0c21\u0e93\u0e94\u0e37\u0ca1\u0e95\u0c21\u0e93\u0e94\u0e96\u06cf\u07d5\u0001\u0001\u0001\u0001\u0001\u0003\u0d04\u0e9a\u0001\u000c\u07d6\u0c5b\u0d05\u0d4f" + "\u02ed\u0e64\u02ee\u0e65\u02ef\u0e7c\u0001\u0005\u0e64\u0e65\u02ee\u02ef\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u0e75\u0e76\u0e77\u0196\u0198\u0185\u0001\u0001\u0001\u0003\u0e7b\u02ed\u0001\u0001\u0012\u06cf\u07d5\u0e8f\u0c21\u0c5a\u0ca1\u0c5a\u0e37\u0c21\u0e90\u0e91\u0e37\u0ca1\u0e92\u0e93\u06cf\u07d5\u0001\u0001\u0001\u0001\u0001\u0003\u0d04\u0e97\u0001\u000c\u07d6\u0c5b\u0d05\u0d4f\u0de2\u0e0f\u0ea4" +
"\u0de2\u0e0f\u0ea7\u0ea8\u0ea9\u0eaa\u0eab\u0001\u0001\u0001\u0001\u0001\u0007\u0c5c\u0ca2\u0d06\u0de3\u0eb3\u0eb3\u0001\u0011\u06d0\u07d7\u0c5d\u0ca3\u0d07\u0c5d\u0de4\u0e0f\u0e38\u0ec5\u0e38\u0ca3\u0ec6\u0ec5\u06d0\u07d7\u0001\u0001\u0006\u0d08\u0ecd\u0ed0\u0ed2\u0ed4\u0003\u0000\u0000\u0002\u0000\u0002\u0000\u0001\u0008\u0edd\u0c5e\u0d09\u0ede\u0edd\u0edf\u0edd\u0001\u0001\u0001\u0002\u0c5f\u0010\u06d2\u07d9\u0c60\u0ca4\u0d0b" + "\u0ea5\u0ea6\u0ea7\u0ea8\u0001\u0001\u0001\u0001\u0001\u0006\u0c5c\u0ca2\u0d06\u0de3\u0eaf\u0001\u0010\u06d0\u07d7\u0c5d\u0ca3\u0d07\u0c5d\u0de4\u0e0f\u0e38\u0ec0\u0e38\u0ca3\u0ec1\u06d0\u07d7\u0001\u0001\u0006\u0d08\u0ec8\u0ecb\u0ecd\u0ecf\u0003\u0000\u0000\u0002\u0000\u0002\u0000\u0001\u0008\u0ed8\u0c5e\u0d09\u0ed9\u0ed8\u0eda\u0ed8\u0001\u0001\u0001\u0002\u0c5f\u0010\u06d2\u07d9\u0c60\u0ca4\u0d0b\u0c60\u0e39\u0eed\u0e39\u0ca4" +
"\u0c60\u0e39\u0ef2\u0e39\u0ca4\u0ef3\u0ef2\u0ef4\u06d2\u07d9\u0001\u0001\u0001\u0003\u07da\u07da\u0003\u0c61\u0ca5\n\u07de\u0c62\u0ca6\u0d53\u0de5\u0e10\u0f05\u0f0c\u0d57\u0002\u0f07\u0002\u0f09\u0003\u0000\u0000\u0001\u0002\u0d0c\u000c\u07e0\u0c63\u0de6\u0e11\u0f1b\u0f1c\u0f1d\u0f1b\u0f1c\u0f1d\u0f1e\u0001\u0001\u0001\u0001\u0016\u06d3\u07e1\u0c64\u0ca7\u0d54\u0c64\u0e3a\u09c8\u0ea9\u0f35\u0f36\u0f37\u0f38\u0f39\u0e3a\u0ca7" + "\u0eee\u0eed\u0eef\u06d2\u07d9\u0001\u0001\u0001\u0003\u07da\u07da\u0003\u0c61\u0ca5\n\u07de\u0c62\u0ca6\u0d53\u0de5\u0e10\u0f00\u0f07\u0d57\u0002\u0f02\u0002\u0f04\u0003\u0000\u0000\u0001\u0002\u0d0c\n\u07e0\u0c63\u0de6\u0e11\u0f14\u0f15\u0f16\u0f16\u0f17\u0001\u0001\u0001\u0001\u0015\u06d3\u07e1\u0c64\u0ca7\u0d54\u0c64\u0e3a\u09c8\u0ea6\u0f2d\u0f2e\u0f2f\u0f30\u0f31\u0e3a\u0ca7\u0f32\u0f33\u06d3\u07e1\u0001\u0001\u0001" +
"\u0f3a\u0f35\u0f3b\u06d3\u07e1\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u0f42\u0d0f\u0e13\u0f42\u0f43\u0001\u0001\u0003\u0f47\u0f47\u0001\u0009\u07e3\u0c65\u0de7\u0e14\u0f36\u0f51\u0f51\u0f52\u0001\u0001\u000c\u0f37\u07e4\u0c66\u0d11\u0dba\u0de8\u0f5f\u0f37\u0f60\u0f60\u0f61\u0001\u0001\u0001\u000b\u0c67\u0d55\u0d12\u0d55\u0dbb\u0de9\u0e15\u0f6d\u0f6e\u0f6d\u0001\u0001\u002d\u0f9c\u0fa2\u06d4\u07e5\u0c22\u0c68\u0ca8\u0c68" + "\u0001\u0001\u0001\u0001\u0006\u0f3a\u0d0f\u0e13\u0f3a\u0f3b\u0001\u0001\u0002\u0f3e\u0001\u0008\u07e3\u0c65\u0de7\u0e14\u0f2e\u0f47\u0f48\u0001\u0001\u000b\u0f2f\u07e4\u0c66\u0d11\u0dba\u0de8\u0f54\u0f2f\u0f55\u0f56\u0001\u0001\u0001\n\u0c67\u0d55\u0d12\u0d55\u0dbb\u0de9\u0e15\u0f61\u0f62\u0001\u0001\u002d\u0f90\u0f96\u06d4\u07e5\u0c22\u0c68\u0ca8\u0c68\u0e3b\u0e8f\u0f9a\u0ed8\u0f9b\u0f9c\u0f9d\u0e3b\u0ca8\u0f9e\u0f9f\u0fa0" +
"\u0e3b\u0e92\u0fa6\u0edd\u0fa7\u0fa8\u0fa9\u0e3b\u0ca8\u0faa\u0fab\u0fac\u0fad\u0fae\u0faf\u0fb0\u0fb1\u06d4\u07e5\u0fb2\u0fb5\u0fb6\u0fb7\u0fb8\u0fb9\u0fba\u0fbb\u0fbc\u0fbd\u0fbe\u0fbf\u0fc0\u0fc1\u0fc2\u0fc3\u0fc4\u0002\u0f9e\u0003\u0fa1\u0149\u0001\u0003\u0fa5\u0251\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0fa1\u0149\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + "\u0fa1\u0fa2\u0fa3\u0fa4\u0fa5\u06d4\u07e5\u0fa6\u0fa9\u0faa\u0fab\u0fac\u0fad\u0fae\u0faf\u0fb0\u0fb1\u0fb2\u0fb3\u0fb4\u0fb5\u0fb6\u0fb7\u0fb8\u0002\u0f92\u0003\u0f95\u0149\u0001\u0003\u0f99\u0251\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0f95\u0149\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u0d57\u0de2\u0de8\u0dea\u0003\u0e17" +
"\u0001\u0001\u0001\u0001\u0001\u0005\u0d57\u0de2\u0de8\u0dea\u0003\u0e17\u0fcd\u0001\u0002\u0f38\u0007\u06d7\u07e7\u0e18\u0fd7\u06d7\u07e7\u0001\u0006\u07e8\u0d16\u0dea\u0fde\u0fde\u0001\u0002\u0fe1\u0001\u0008\u0ca9\u0e6d\u0fea\u0fed\u0ff2\u0ff5\u0ff6\u0003\u0000\u0000\u0002\u0fef\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0002\u0fe1\u004e\u1047\u042d\u042e\u042f\u0430\u0cfd\u0d57\u0431\u0432\u0433\u0434\u0435\u0436\u0437" + "\u0fc1\u0001\u0002\u0f30\u0007\u06d7\u07e7\u0e18\u0fcb\u06d7\u07e7\u0001\u0005\u07e8\u0d16\u0dea\u0fd1\u0001\u0002\u0fd4\u0001\u0008\u0ca9\u0e6d\u0fdd\u0fe0\u0fe5\u0fe8\u0fe9\u0003\u0000\u0000\u0002\u0fe2\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0002\u0fd4\u004e\u103a\u042d\u042e\u042f\u0430\u0cfd\u0d57\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u0e37\u1044\u0e38\u1045\u1046\u0e39\u1047\u0e3a\u1048" +
"\u0438\u0439\u043a\u043b\u0e37\u1051\u0e38\u1052\u1053\u0e39\u1054\u0e3a\u1055\u0e3b\u0fcd\u0fd7\u1056\u1057\u0170\u0171\u0172\u0173\u0174\u0175\u0176\u0177\u0184\u0178\u0179\u017d\u017e\u0097\u106b\u106e\u1071\u1074\u1077\u107a\u0186\u0189\u018c\u018f\u107d\u0192\u104f\u0197\u1050\u019a\u0430\u1080\u1081\u1082\u1083\u1084\u1085\u1086\u1087\u1088\u1089\u108a\u108b\u108c\u108d\u0007\u104e\u104f\u1050\u0195\u0197\u019a\u0001\u0001" + "\u0e3b\u0fc1\u0fcb\u1049\u104a\u0170\u0171\u0172\u0173\u0174\u0175\u0176\u0177\u0184\u0178\u0179\u017d\u017e\u0097\u105e\u1061\u1064\u1067\u106a\u106d\u0186\u0189\u018c\u018f\u1070\u0192\u1042\u0197\u1043\u019a\u0430\u1073\u1074\u1075\u1076\u1077\u1078\u1079\u107a\u107b\u107c\u107d\u107e\u107f\u1080\u0007\u1041\u1042\u1043\u0195\u0197\u019a\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0013\u0352\u035a\u0441\u0442\u0444" +
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0013\u0352\u035a\u0441\u0442\u0444\u0354\u0353\u0357\u0358\u044c\u044d\u044e\u045b\u045d\u0463\u0464\u0465\u106a\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0058\u063c\u10e6\u10ed\u10f7\u03b6\u03b7\u03b8\u03b9\u10f8" + "\u0354\u0353\u0357\u0358\u044c\u044d\u044e\u045b\u045d\u0463\u0464\u0465\u105d\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0058\u063c\u10d9\u10e0\u10ea\u03b6\u03b7\u03b8\u03b9\u10eb\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u10f4\u0de0\u03c4" +
"\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u1101\u0de0\u03c4\u0e35\u0ca1\u0ca3\u1105\u0ca4\u0ca7\u0ca8\u1106\u063c\u063c\u031e\u031f\u0320\u0321\u0325\u0329\u032a\u1107\u10f4\u110b\u110a\u10f5\u10f6\u032b\u032c\u032d\u032e\u032f\u10ff\u0212\u110c\u110d\u110e\u0331\u0332\u0333\u110f\u1112\u1115\u1116\u1119\u111c\u111d\u1120\u0334\u1123\u1126\u0335\u10eb\u0336\u10ec\u0337\u1129\u112a\u03b9\u112b\u112c\u112d\u112e" + "\u0e35\u0ca1\u0ca3\u10f8\u0ca4\u0ca7\u0ca8\u10f9\u063c\u063c\u031e\u031f\u0320\u0321\u0325\u0329\u032a\u10fa\u10e7\u10fe\u10fd\u10e8\u10e9\u032b\u032c\u032d\u032e\u032f\u10f2\u0212\u10ff\u1100\u1101\u0331\u0332\u0333\u1102\u1105\u1108\u1109\u110c\u110f\u1110\u1113\u0334\u1116\u1119\u0335\u10de\u0336\u10df\u0337\u111c\u111d\u03b9\u111e\u111f\u1120\u1121\u1122\u1123\u1124\u1125\u1126\u1127\u0005\u10de\u10df\u0336\u0337\u0001\u0001" +
"\u112f\u1130\u1131\u1132\u1133\u1134\u0005\u10eb\u10ec\u0336\u0337\u0001\u0001\u0007\u10f4\u10f5\u10f6\u032b\u032e\u032f\u0001\u0001\u0001\u0001\u0007\u10ff\u0c99\u1100\u0212\u0c9c\u0213\u0001\u0001\u0003\u1104\u0330\u0001\u0001\u0001\u0003\u110a\u032d\u0001\u0001\u0001\u0001\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000" + "\u0007\u10e7\u10e8\u10e9\u032b\u032e\u032f\u0001\u0001\u0001\u0001\u0007\u10f2\u0c99\u10f3\u0212\u0c9c\u0213\u0001\u0001\u0003\u10f7\u0330\u0001\u0001\u0001\u0003\u10fd\u032d\u0001\u0001\u0001\u0001\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" +
"\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0046\u117b\u1182\u119f\u11ba\u0e95\u0ec6\u0ef3\u11c1\u0f3a\u0faa\u11c2\u11c3\u11c4\u11ce\u11d5\u02b7\u11f4\u02b8\u02b9\u02ba\u02bb\u02bf\u02c0\u02c1\u11f8\u11cb\u11cc\u11cd\u1180\u017f\u0181\u0182\u02c5\u11f7\u02c6\u11d3\u02c7\u11d4\u02c8\u11bf\u02c9\u11c0\u02ca\u11fd\u11fe\u11ff\u1200\u1201\u1202\u1203\u02d1\u02d2\u02d3\u02d4\u02d5\u02d6\u02d7\u1204" + "\u0046\u116e\u1175\u1192\u11ad\u0e92\u0ec1\u0eee\u11b4\u0f32\u0f9e\u11b5\u11b6\u11b7\u11c1\u11c8\u02b7\u11e7\u02b8\u02b9\u02ba\u02bb\u02bf\u02c0\u02c1\u11eb\u11be\u11bf\u11c0\u1173\u017f\u0181\u0182\u02c5\u11ea\u02c6\u11c6\u02c7\u11c7\u02c8\u11b2\u02c9\u11b3\u02ca\u11f0\u11f1\u11f2\u11f3\u11f4\u11f5\u11f6\u02d1\u02d2\u02d3\u02d4\u02d5\u02d6\u02d7\u11f7\u11fa\u11fb\u11fc\u11ff\u1202\u1205\u02d8\u02d9\u1208\u120b\u120e\u0005\u1173" +
"\u1207\u1208\u1209\u120c\u120f\u1212\u02d8\u02d9\u1215\u1218\u121b\u0005\u1180\u02c5\u1181\u04f3\u0001\u0001\u000f\u1191\u1192\u1193\u1194\u1195\u1196\u1197\u1198\u1199\u119a\u119b\u119c\u119d\u119e\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000e\u11ad\u11ae\u11af\u11b0\u11b1\u11b2\u11b3\u11b4\u11b5\u11b6\u11b7\u11b8\u11b9\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + "\u02c5\u1174\u04f3\u0001\u0001\u000f\u1184\u1185\u1186\u1187\u1188\u1189\u118a\u118b\u118c\u118d\u118e\u118f\u1190\u1191\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000e\u11a0\u11a1\u11a2\u11a3\u11a4\u11a5\u11a6\u11a7\u11a8\u11a9\u11aa\u11ab\u11ac\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u11b2\u11b3\u02c9\u02ca\u0001\u0001\u0001\u0001\u0001\u0007" +
"\u0001\u0001\u0005\u11bf\u11c0\u02c9\u02ca\u0001\u0001\u0001\u0001\u0001\u0007\u11cb\u11cc\u11cd\u017f\u0181\u0182\u0001\u0001\u0001\u0005\u11d3\u11d4\u02c7\u02c8\u0001\u0001\r\u11e2\u11e5\u11e8\u11eb\u11ee\u11f1\u0285\u0288\u028b\u028e\u0291\u0294\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u11f7\u02c6\u0001\u0005\u11d3\u11d4\u02c7\u02c8\u0001\u0001\u0001" + "\u11be\u11bf\u11c0\u017f\u0181\u0182\u0001\u0001\u0001\u0005\u11c6\u11c7\u02c7\u02c8\u0001\u0001\r\u11d5\u11d8\u11db\u11de\u11e1\u11e4\u0285\u0288\u028b\u028e\u0291\u0294\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u11ea\u02c6\u0001\u0005\u11c6\u11c7\u02c7\u02c8\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u0000\u0000\u0001\u0001\u0003\u0000\u0000\u0003" +
"\u0001\u0001\u0001\u0001\u0003\u0000\u0000\u0001\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0012\u04c4\u0037\u0fab\u0362\u033f\u031e\u033f\u0170\u0e93\u0170\u031e\u02b7\u0362\u1230\u048a\u04c4\u0037\u0001\u0021\u1252\u1255\u01ee\u0e92\u0fa6\u0edd\u0fa7\u0fa8\u0fa9\u0fab\u0fac\u0fad\u0fae\u0faf\u0fb0\u1258\u0fb5\u0fb6\u0fb7\u0fb8\u0fb9\u0fba" + "\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0011\u04c4\u0037\u0f9f\u0362\u033f\u031e\u033f\u0170\u0170\u031e\u02b7\u0362\u1222\u048a\u04c4\u0037\u0001\u0021\u1244\u1247\u01ee\u0e8f\u0f9a\u0ed8\u0f9b\u0f9c\u0f9d\u0f9f\u0fa0\u0fa1\u0fa2\u0fa3\u0fa4\u124a\u0fa9\u0faa\u0fab\u0fac\u0fad\u0fae\u0faf\u0fb0\u0fb1\u0fb2\u0fb3\u0fb4\u0fb5\u0fb6\u0fb7\u0fb8\u0003\u0f99\u0251\u0003" +
"\u0fbb\u0fbc\u0fbd\u0fbe\u0fbf\u0fc0\u0fc1\u0fc2\u0fc3\u0fc4\u0003\u0fa5\u0251\u0003\u0fa1\u0149\u0003\u0fa1\u0149\u002c\u1287\u0038\u013e\u01ef\u0d58\u0105\u0e0f\u128b\u0de2\u0de3\u0de4\u128c\u128d\u128e\u128f\u0de5\u0de6\u1290\u0de7\u0de8\u0de9\u1291\u0dea\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0d58\u128a\u0115\u0003\u128a\u0115\u0001\u0001\u0001\u0001\u0001\u0001" + "\u0f95\u0149\u0003\u0f95\u0149\u002c\u1279\u0038\u013e\u01ef\u0d58\u0105\u0e0f\u127d\u0de2\u0de3\u0de4\u127e\u127f\u1280\u1281\u0de5\u0de6\u1282\u0de7\u0de8\u0de9\u1283\u0dea\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0d58\u127c\u0115\u0003\u127c\u0115\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0008\u013f\u00b7\u01f0\u0106\u0e1b\u128c\u128d\u0001\u0001\u0010\u04c8" +
"\u0001\u0001\u0008\u013f\u00b7\u01f0\u0106\u0e1b\u129a\u129b\u0001\u0001\u0010\u04c8\u0039\u0340\u031f\u01f1\u0340\u0107\u0e0f\u0172\u0172\u031f\u02b8\u12ac\u04c8\u0039\u0001\u0007\u01f2\u12b4\u12b5\u12b7\u12b9\u12b4\u0001\u0002\u0000\u0002\u0000\u0002\u0000\u0009\u0fad\u0141\u01f3\u0fad\u0ede\u0edd\u12c4\u0fad\u0003\u0000\u0000\u0002\u0142\u000f\u04ca\u003b\u0341\u0321\u01f5\u0341\u0175\u0175\u0321\u02b9\u12d8\u048c\u04ca\u003b" + "\u0039\u0340\u031f\u01f1\u0340\u0107\u0e0f\u0172\u0172\u031f\u02b8\u129e\u04c8\u0039\u0001\u0007\u01f2\u12a6\u12a7\u12a9\u12ab\u12a6\u0001\u0002\u0000\u0002\u0000\u0002\u0000\u0007\u0fa1\u0141\u01f3\u0fa1\u0ed9\u0fa1\u0002\u0142\u000f\u04ca\u003b\u0341\u0321\u01f5\u0341\u0175\u0175\u0321\u02b9\u12c5\u048c\u04ca\u003b\u0001\u0003\u003c\u003c\u0003\u0143\u12cc\u0001\u0008\u0040\u0144\u0ca6\u0380\u010d\u0f07\u0d57\u0004\u01fd\u0d59" +
"\u0001\u0003\u003c\u003c\u0003\u0143\u12df\u0001\u0008\u0040\u0144\u0ca6\u0380\u010d\u0f0c\u0d57\u0004\u01fd\u0d59\u0d5a\u0006\u0042\u0145\u010e\u12f2\u048d\u0001\u001a\u04da\u0043\u0342\u0325\u0383\u0342\u0177\u0c21\u0c22\u0177\u0325\u02bb\u0362\u0ea9\u130d\u0351\u0f36\u0f37\u0363\u0364\u0f38\u0365\u048e\u04da\u0043\u0001\u0005\u0f42\u0200\u0e13\u1313\u0002\u1315\u0003\u0000\u0000\u0005\u0045\u0146\u0110\u0e14\u000b\u0f37\u0046" + "\u0d5a\u0006\u0042\u0145\u010e\u12df\u048d\u0001\u001a\u04da\u0043\u0342\u0325\u0383\u0342\u0177\u0c21\u0c22\u0177\u0325\u02bb\u0362\u0ea6\u12fa\u0351\u0f2e\u0f2f\u0363\u0364\u0f30\u0365\u048e\u04da\u0043\u0001\u0005\u0f3a\u0200\u0e13\u1300\u0002\u1302\u0003\u0000\u0000\u0005\u0045\u0146\u0110\u0e14\u000b\u0f2f\u0046\u0147\u0205\u0dbd\u0111\u0f54\u0f2f\u1315\u0147\u0001\u0009\u0148\u00c6\u0206\u00c6\u0dbe\u0112\u131f\u0f62\u0001" +
"\u0147\u0205\u0dbd\u0111\u0f5f\u0f37\u1328\u0147\u0001\u0009\u0148\u00c6\u0206\u00c6\u0dbe\u0112\u1332\u0f6e\u0001\u001b\u04df\u0047\u0363\u0343\u0329\u0d5a\u0343\u0178\u0e92\u0fa6\u0edd\u0fa7\u0fa8\u0fa9\u0178\u0329\u02bf\u0fab\u0fac\u0fad\u0fae\u0faf\u0fb0\u048f\u04df\u0047\u0023\u0d5b\u128b\u0de2\u0de3\u0de4\u128c\u128d\u128e\u128f\u0de6\u1290\u0de7\u0de8\u0de9\u1291\u0dea\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c" + "\u001b\u04df\u0047\u0363\u0343\u0329\u0d5a\u0343\u0178\u0e8f\u0f9a\u0ed8\u0f9b\u0f9c\u0f9d\u0178\u0329\u02bf\u0f9f\u0fa0\u0fa1\u0fa2\u0fa3\u0fa4\u048f\u04df\u0047\u0023\u0d5b\u127d\u0de2\u0de3\u0de4\u127e\u127f\u1280\u1281\u0de6\u1282\u0de7\u0de8\u0de9\u1283\u0dea\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b\u010c\u0d57\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0091\u0002\u0179\u0003\u0f30\u1363\u0001\u0007\u04e2\u0049\u0e18" +
"\u0d57\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0091\u0002\u0179\u0003\u0f38\u1376\u0001\u0007\u04e2\u0049\u0e18\u017d\u04e2\u0049\u0004\u004a\u0210\u0114\u0002\u1384\u0001\u0012\u1397\u1398\u0e9a\u0eab\u0edf\u0f61\u0097\u0d58\u0091\u1399\u139a\u139b\u139c\u139d\u139e\u139f\u13a0\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u002f\u13d0\u13d4\u13e9\u13fc\u0d6b\u0e96\u1403\u0ef4\u0f1e\u0f3b\u0fb1\u1404\u1405\u1406" + "\u017d\u04e2\u0049\u0004\u004a\u0210\u0114\u0002\u1371\u0001\u0012\u1384\u1385\u0e97\u0ea8\u0eda\u0f56\u0097\u0d58\u0091\u1386\u1387\u1388\u1389\u138a\u138b\u138c\u138d\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u002f\u13bd\u13c1\u13d6\u13e9\u0d6b\u0e93\u13f0\u0eef\u0f17\u0f33\u0fa5\u13f1\u13f2\u13f3\u048a\u13fd\u048b\u048c\u048d\u048e\u048f\u0490\u0491\u1386\u1401\u04e3\u13fa\u13fb\u13fc\u0180\u0199\u0183\u1400" +
"\u048a\u1410\u048b\u048c\u048d\u048e\u048f\u0490\u0491\u1399\u1414\u04e3\u140d\u140e\u140f\u0180\u0199\u0183\u1413\u0493\u1401\u02ff\u1402\u0300\u1415\u1416\u1417\u1418\u1419\u141a\u141b\u141c\u0003\u13d3\u04f4\u0001\u000b\u13df\u13e0\u13e1\u13e2\u13e3\u13e4\u13e5\u13e6\u13e7\u13e8\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\n\u13f3\u13f4\u13f5\u13f6\u13f7\u13f8\u13f9\u13fa\u13fb\u0001\u0001\u0001\u0001\u0001" + "\u0493\u13ee\u02ff\u13ef\u0300\u1402\u1403\u1404\u1405\u1406\u1407\u1408\u1409\u0003\u13c0\u04f4\u0001\u000b\u13cc\u13cd\u13ce\u13cf\u13d0\u13d1\u13d2\u13d3\u13d4\u13d5\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\n\u13e0\u13e1\u13e2\u13e3\u13e4\u13e5\u13e6\u13e7\u13e8\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u13ee\u13ef\u02ff\u0300\u0001\u0001\u0001\u0001\u0001\u0007\u13fa\u13fb\u13fc\u0180" +
"\u0001\u0001\u0001\u0001\u0005\u1401\u1402\u02ff\u0300\u0001\u0001\u0001\u0001\u0001\u0007\u140d\u140e\u140f\u0180\u0199\u0183\u0001\u0001\u0001\u0003\u1413\u0493\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0017\u078a\u04c3\u0e3c\u06cf\u06d0\u06d2\u06d3\u06d4\u06d7\u1434\u04c4\u04c8\u04ca\u04da\u04df\u04e2\u1435\u078a\u04f5\u04e4\u1436\u1437\u0001\u0001\u0001\u0001\u0037\u146f\u1474\u147b\u1480\u0ca1\u0ca3\u1105" + "\u0199\u0183\u0001\u0001\u0001\u0003\u1400\u0493\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0017\u078a\u04c3\u0e3c\u06cf\u06d0\u06d2\u06d3\u06d4\u06d7\u1421\u04c4\u04c8\u04ca\u04da\u04df\u04e2\u1422\u078a\u04f5\u04e4\u1423\u1424\u0001\u0001\u0001\u0001\u0037\u145c\u1461\u1468\u146d\u0ca1\u0ca3\u10f8\u0ca4\u0ca7\u0ca8\u10f9\u031e\u031f\u0320\u0321\u0325\u0329\u032a\u1470\u10e7\u10fe\u10fd\u10e8\u10e9\u032b\u032c" +
"\u0ca4\u0ca7\u0ca8\u1106\u031e\u031f\u0320\u0321\u0325\u0329\u032a\u1483\u10f4\u110b\u110a\u10f5\u10f6\u032b\u032c\u032d\u032e\u032f\u10ff\u0212\u110c\u110d\u110e\u0331\u0332\u0333\u110f\u1112\u1115\u1116\u1119\u111c\u111d\u1120\u0334\u1123\u1126\u0335\u10eb\u0336\u10ec\u0337\u1486\u0005\u10eb\u10ec\u0336\u0337\u0007\u10f4\u10f5\u10f6\u032b\u032e\u032f\u0005\u10ff\u1100\u0212\u0213\u0003\u1104\u0330\u0003\u110a\u032d\u0001\u0077" + "\u032d\u032e\u032f\u10f2\u0212\u10ff\u1100\u1101\u0331\u0332\u0333\u1102\u1105\u1108\u1109\u110c\u110f\u1110\u1113\u0334\u1116\u1119\u0335\u10de\u0336\u10df\u0337\u1473\u0005\u10de\u10df\u0336\u0337\u0007\u10e7\u10e8\u10e9\u032b\u032e\u032f\u0005\u10f2\u10f3\u0212\u0213\u0003\u10f7\u0330\u0003\u10fd\u032d\u0001\u0077\u14eb\u14f2\u1501\u150f\u1514\u1517\u07d5\u07d6\u07d7\u07d8\u07d9\u07da\u07dd\u07de\u07df\u07e0\u07e1\u07e2\u07e3" +
"\u14fe\u1505\u1514\u1522\u1527\u152a\u07d5\u07d6\u07d7\u07d8\u07d9\u07da\u07dd\u07de\u07df\u07e0\u07e1\u07e2\u07e3\u07e4\u07e5\u07e6\u07e7\u07e8\u152d\u1534\u0037\u1539\u0038\u0039\u003a\u003b\u003c\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u153c\u1541\u1546\u07f0\u080e\u080f\u080d\u07f1\u078b\u07f2\u0803\u07d2\u078c\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u07fd\u0055\u07f8\u0059" + "\u07e4\u07e5\u07e6\u07e7\u07e8\u151a\u1521\u0037\u1526\u0038\u0039\u003a\u003b\u003c\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u1529\u152e\u1533\u07f0\u080e\u080f\u080d\u07f1\u078b\u07f2\u0803\u07d2\u078c\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u07fd\u0055\u07f8\u0059\u07f9\u005a\u0804\u005b\u07cc\\\u07cd\u005d\u0810\u0811\u0812\u0813\u0814\u0815\u0816\u005e\u005f\u0060\u0061" +
"\u07f9\u005a\u0804\u005b\u07cc\\\u07cd\u005d\u0810\u0811\u0812\u0813\u0814\u0815\u0816\u005e\u005f\u0060\u0061\u0062\u0063\u0817\u0818\u081b\u081c\u081f\u0822\u0823\u0826\u0829\u082c\u082f\u0832\u0835\u0064\u0067\u0068\u006b\u006e\u006f\u0838\u0072\u0075\u0078\u007b\u007e\u0007\u078b\u078c\u0050\u0054\u078d\u04e7\u000f\u079e\u079f\u07a0\u07a1\u07a2\u07a3\u07a4\u07a5\u07a6\u07a7\u07a8\u07a9\u07aa\u07ab\u000e\u07ba\u07bb\u07bc" + "\u0062\u0063\u0817\u0818\u081b\u081c\u081f\u0822\u0823\u0826\u0829\u082c\u082f\u0832\u0835\u0064\u0067\u0068\u006b\u006e\u006f\u0838\u0072\u0075\u0078\u007b\u007e\u0007\u078b\u078c\u0050\u0054\u078d\u04e7\u000f\u079e\u079f\u07a0\u07a1\u07a2\u07a3\u07a4\u07a5\u07a6\u07a7\u07a8\u07a9\u07aa\u07ab\u000e\u07ba\u07bb\u07bc\u07bd\u07be\u07bf\u07c0\u07c1\u07c2\u07c3\u07c4\u07c5\u07c6\u0005\u07cc\u07cd\\\u005d\u0003\u080d\u004e\u0003" +
"\u07bd\u07be\u07bf\u07c0\u07c1\u07c2\u07c3\u07c4\u07c5\u07c6\u0005\u07cc\u07cd\\\u005d\u0003\u080d\u004e\u0003\u07d2\u0053\u0007\u07f0\u07f1\u07f2\u004b\u004f\u0051\u0005\u07f8\u07f9\u0059\u005a\u0003\u07fd\u0055\u0005\u0803\u0804\u0052\u005b\u0005\u07f8\u07f9\u0059\u005a\u0003\u080d\u004e\u0017\u0c5b\u0c5c\u1560\u0c5e\u0c5f\u0c61\u0c62\u0c63\u0c65\u0c66\u0c67\u013e\u013f\u0140\u0141\u0142\u0143\u0144\u0145\u0146\u0147\u0148" + "\u07d2\u0053\u0007\u07f0\u07f1\u07f2\u004b\u004f\u0051\u0005\u07f8\u07f9\u0059\u005a\u0003\u07fd\u0055\u0005\u0803\u0804\u0052\u005b\u0005\u07f8\u07f9\u0059\u005a\u0003\u080d\u004e\u0017\u0c5b\u0c5c\u154d\u0c5e\u0c5f\u0c61\u0c62\u0c63\u0c65\u0c66\u0c67\u013e\u013f\u0140\u0141\u0142\u0143\u0144\u0145\u0146\u0147\u0148\u0001\u0002\u1550\u0001\u0003\u0ed8\u0fa1\u0002\u0810\u0002\u0811\u0002\u0812\u0003\u06e4\u0813\u0002\u0814\u0003" +
"\u0001\u0002\u1563\u0001\u0003\u0edd\u0fad\u0002\u0810\u0002\u0811\u0002\u0812\u0003\u06e4\u0813\u0002\u0814\u0003\u06e5\u0815\u0002\u0816\u0002\u005e\u0002\u005f\u0002\u0060\u000e\u04e5\u158b\u15ae\u15bb\u15c8\u15eb\u160e\u1622\u1623\u1624\u1625\u1626\u1627\u0006\u1591\u159e\u15ab\u15ac\u15ad\u0007\u1598\u1599\u159a\u159b\u159c\u159d\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15a5\u15a6\u15a7\u15a8\u15a9\u15aa\u0001\u0001\u0001" + "\u06e5\u0815\u0002\u0816\u0002\u005e\u0002\u005f\u0002\u0060\u000e\u04e5\u1578\u159b\u15a8\u15b5\u15d8\u15fb\u160f\u1610\u1611\u1612\u1613\u1614\u0006\u157e\u158b\u1598\u1599\u159a\u0007\u1585\u1586\u1587\u1588\u1589\u158a\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u1592\u1593\u1594\u1595\u1596\u1597\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15a2\u15a3\u15a4\u15a5\u15a6\u15a7\u0001\u0001\u0001\u0001\u0001\u0001" +
"\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15b5\u15b6\u15b7\u15b8\u15b9\u15ba\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15c2\u15c3\u15c4\u15c5\u15c6\u15c7\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u15ce\u15db\u15e8\u15e9\u15ea\u0007\u15d5\u15d6\u15d7\u15d8\u15d9\u15da\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15e2\u15e3\u15e4\u15e5\u15e6\u15e7\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u15f1\u15fe\u160b\u160c" + "\u0007\u15af\u15b0\u15b1\u15b2\u15b3\u15b4\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u15bb\u15c8\u15d5\u15d6\u15d7\u0007\u15c2\u15c3\u15c4\u15c5\u15c6\u15c7\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15cf\u15d0\u15d1\u15d2\u15d3\u15d4\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u15de\u15eb\u15f8\u15f9\u15fa\u0007\u15e5\u15e6\u15e7\u15e8\u15e9\u15ea\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u15f2\u15f3\u15f4\u15f5" +
"\u160d\u0007\u15f8\u15f9\u15fa\u15fb\u15fc\u15fd\u0001\u0001\u0001\u0001\u0001\u0001\u0007\u1605\u1606\u1607\u1608\u1609\u160a\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u1614\u161b\u15ab\u15ac\u15ad\u0007\u1598\u1599\u159a\u159b\u159c\u159d\u0007\u15a5\u15a6\u15a7\u15a8\u15a9\u15aa\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0062\u0003\u04e6\u0063\u0002\u0817\u0002\u0e0f\u0002\u0e13\u0003\u0f1d\u0f1d\u0002\u0e0f" + "\u15f6\u15f7\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u1601\u1608\u1598\u1599\u159a\u0007\u1585\u1586\u1587\u1588\u1589\u158a\u0007\u1592\u1593\u1594\u1595\u1596\u1597\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0062\u0003\u04e6\u0063\u0002\u0817\u0002\u0e0f\u0002\u0e13\u0003\u0f16\u0f16\u0002\u0e0f\u0008\u162d\u162e\u162f\u162d\u163e\u1640\u162d\u0001\u0001\u000f\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" +
"\u0008\u1640\u1641\u1642\u1640\u1651\u1653\u1640\u0001\u0001\u000f\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0000\u0002\u0000\u0002\u1657\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0007\u0c69\u0d1b\u0d5f\u1677\u1678\u0d5f\u0001\u0001\u0007\u1680\u1682\u1683\u1680\u1680\u1685" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0000\u0002\u0000\u0002\u1644\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0007\u0c69\u0d1b\u0d5f\u1664\u1665\u0d5f\u0001\u0001\u0007\u166d\u166f\u1670\u166d\u166d\u1672\u0002\u0000\u0001\u0002\u0000\u0001\u0002\u1675\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" +
"\u0002\u0000\u0001\u0002\u0000\u0001\u0002\u1688\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0d1c\u0003\u0e13\u169d\u0001\u0003\u0334\u16a1\u0001\u0003\u0d1d\u16a5\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0007\u0c6a\u0d1e\u1677\u16bc\u1678\u16bc\u0001\u0004\u0c6b\u0d1f\u16c1\u0001\u0002\u0d20\u0005\u0c6c\u16c9\u16ca" + "\u0000\u0000\u0000\u0000\u0000\u0002\u0d1c\u0003\u0e13\u168a\u0001\u0003\u0334\u168e\u0001\u0003\u0d1d\u1692\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0007\u0c6a\u0d1e\u1664\u16a9\u1665\u16a9\u0001\u0004\u0c6b\u0d1f\u16ae\u0001\u0002\u0d20\u0005\u0c6c\u16b6\u16b7\u16c7\u0001\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001" +
"\u16da\u0001\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0004\u16df\u16e0\u16e1\u0001\u0001\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003\u0f37\u16fd\u0001\u0004\u1702\u1703\u1702\u0001\u0001\u0007\u16a1\u0fc4\u0335\u170b\u16a1\u0fc4\u0013\u0000\u0000\u0000\u0000" + "\u0004\u16cc\u16cd\u16ce\u0001\u0001\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003\u0f2f\u16ea\u0001\u0004\u16ef\u16f0\u16ef\u0001\u0001\u0007\u168e\u0fb8\u0335\u16f8\u168e\u0fb8\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0004\u0c6d\u0d21\u170f\u0019" +
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0004\u0c6d\u0d21\u1722\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0d22\u1642\u1657\u1688\u16a5\u16ca\u16e1\u170b\u1722\u174a\u175c\u1775\u16a5\u1785\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0d22\u162f\u1644\u1675\u1692\u16b7\u16ce\u16f8\u170f\u1737\u1749\u1762\u1692\u1772\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" +
"\u0000\u0000\u0000\u0000\u0019\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u1797\u0001\u0002\u175c\u0006\u17a0\u06f1\u17a2\u17a3\u1775" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u1784\u0001\u0002\u1749\u0006\u178d\u06f1\u178f\u1790\u1762\u0002\u0000\u0001\u0001\u0002\u1793\u0002\u0000\u0005\u06f2\u06f2\u168e\u0334\u0004\u179e\u1692\u1793\u0002\u0000" +
"\u0002\u0000\u0001\u0001\u0002\u17a6\u0002\u0000\u0005\u06f2\u06f2\u16a1\u0334\u0004\u17b1\u16a5\u17a6\u0002\u0000\u0002\u16df\u0002\u1785\u0002\u17b9\u0002\u0000\u0003\u17be\u17c0\u0002\u0000\u0002\u0000\u0002\u17c4\u0002\u0000\u0002\u17c8\u0002\u0000\u0017\u17e1\u17e3\u17e5\u17e7\u17e9\u17eb\u17ed\u17ef\u17f1\u17f3\u17f5\u17f7\u17f9\u17fb\u17fd\u17ff\u1801\u1803\u1805\u1807\u1809\u180b\u0002\u0000\u0002\u0000\u0002\u0000\u0002" + "\u0002\u16cc\u0002\u1772\u0002\u17a6\u0002\u0000\u0003\u17ab\u17ad\u0002\u0000\u0002\u0000\u0002\u17b1\u0002\u0000\u0002\u17b5\u0002\u0000\u0017\u17ce\u17d0\u17d2\u17d4\u17d6\u17d8\u17da\u17dc\u17de\u17e0\u17e2\u17e4\u17e6\u17e8\u17ea\u17ec\u17ee\u17f0\u17f2\u17f4\u17f6\u17f8\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000" +
"\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0004\u1811\u1813\u1815\u0002\u0000\u0002\u0000\u0002\u0000\u0004\u181b\u181f\u181d\u0002\u181d\u0002\u0000\u0002\u0000\u0004\u1825\u1829\u1827\u0002\u1827\u0002\u0000\u0002\u0000\u0008\u1833\u1848\u1849\u184a" + "\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0004\u17fe\u1800\u1802\u0002\u0000\u0002\u0000\u0002\u0000\u0004\u1808\u180c\u180a\u0002\u180a\u0002\u0000\u0002\u0000\u0004\u1812\u1816\u1814\u0002\u1814\u0002\u0000\u0002\u0000\u0008\u1820\u1835\u1836\u1837\u1838\u1837\u1838\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" +
"\u184b\u184a\u184b\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0005\u1865\u1866\u1867\u1868\u0001\u0001\u0001\u0001\u0002\u186b\u0001\u0002\u186e\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0005\u1852\u1853\u1854\u1855\u0001\u0001\u0001\u0001\u0002\u1858\u0001\u0002\u185b\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0004\u1853\u186f\u1870\u0001\u0001\u0002\u1873\u0001\u0002\u1854\n\u1880" +
"\u0000\u0000\u0000\u0000\u0000\u0000\u0004\u1866\u1882\u1883\u0001\u0001\u0002\u1886\u0001\u0002\u1867\n\u1893\u1894\u1895\u1896\u1897\u18ad\u1896\u1897\u18ad\u0001\u0001\u0001\u0001\u0016\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0016\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u1881\u1882\u1883\u1884\u189a\u1883\u1884\u189a\u0001\u0001\u0001\u0001\u0016\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0016\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003\u18b3\u18b3\u0001\u0002\u18b6\u0001\u0002\u18b9\u0001\u0004\u18be\u18d0\u18d0\u0012\u0000" +
"\u0000\u0000\u0000\u0003\u18c6\u18c6\u0001\u0002\u18c9\u0001\u0002\u18cc\u0001\u0004\u18d1\u18e3\u18e3\u0012\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0006\u1868\u18ea\u18fd\u1910\u1910\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0006\u1855\u18d7\u18ea\u18fd\u18fd\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" +
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0009\u192c\u192d\u1894\u18ea\u192e\u193e\u193f\u193f\u0001\u0001\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\n\u194a\u1895\u18c9\u18fd\u194b\u193e\u1849\u193e\u1849\u0001\u0011\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0009\u1919\u191a\u1881\u18d7\u191b\u192b\u192c\u192c\u0001\u0001\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\n\u1937\u1882\u18b6\u18ea\u1938\u192b\u1836\u192b\u1836\u0001\u0011\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\n\u1953\u1954\u1883\u18fd\u1955\u192c" +
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\n\u1966\u1967\u1896\u1910\u1968\u193f\u184a\u193f\u184a\u0001\u0001\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u197a\u0001\u0007\u1848\u1895\u1896\u1982\u1983\u1894\u0001\u0001\u0002\u1893\u0009\u184b\u1883\u1897\u18e3\u193e\u193f\u198f\u193f\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u1837\u192c\u1837\u0001\u0001\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u1967\u0001\u0007\u1835\u1882\u1883\u196f\u1970\u1881\u0001\u0001\u0002\u1880\u0009\u1838\u1870\u1884\u18d0\u192b\u192c\u197c\u192c\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u189a\u1836\u1837\u1995\u1837\u001c\u0000\u0000" +
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u18ad\u1849\u184a\u19a8\u184a\u001c\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\n\u1966\u1967\u1896\u1910\u193f\u184a\u1968\u193f\u184a\u0009\u184b\u1883\u1897\u18e3\u193e\u193f\u193f\u198f\u0006\u18ad\u1849\u184a\u184a\u19a8\u000c\u19e9\u19ea" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\n\u1953\u1954\u1883\u18fd\u192c\u1837\u1955\u192c\u1837\u0009\u1838\u1870\u1884\u18d0\u192b\u192c\u192c\u197c\u0006\u189a\u1836\u1837\u1837\u1995\u000c\u19d6\u19d7\u19d8\u19d9\u19da\u19db\u19dc\u19dd\u19de\u19df\u19e0\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" +
"\u19eb\u19ec\u19ed\u19ee\u19ef\u19f0\u19f1\u19f2\u19f3\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0004\u19f8\u19f9\u19fa\u0001\u0001\u0001\u0003\u19fe\u19ff\u0001\u0001\u0007\u1a07\u1a08\u1a09\u1a0a\u1a0b\u1a0c\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1a10\u1a11\u0001\u0001\u0004\u1a16\u1a17\u1a18\u0001\u0001\u0001\u0003\u1a1c\u1a1d\u0001\u0001\u0002\u1a20\u0001\u0002\u1a23\u0001\u0002\u1a26\u0001\u0002" + "\u0001\u0004\u19e5\u19e6\u19e7\u0001\u0001\u0001\u0003\u19eb\u19ec\u0001\u0001\u0007\u19f4\u19f5\u19f6\u19f7\u19f8\u19f9\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u19fd\u19fe\u0001\u0001\u0004\u1a03\u1a04\u1a05\u0001\u0001\u0001\u0003\u1a09\u1a0a\u0001\u0001\u0002\u1a0d\u0001\u0002\u1a10\u0001\u0002\u1a13\u0001\u0002\u1a16\u0001\u0004\u1a1b\u1a1c\u1a1d\u0001\u0001\u0001\u0002\u1a20\u0001\u0003\u1a24\u1a25\u0001\u0001\u0002\u1a28" +
"\u1a29\u0001\u0004\u1a2e\u1a2f\u1a30\u0001\u0001\u0001\u0002\u1a33\u0001\u0003\u1a37\u1a38\u0001\u0001\u0002\u1a3b\u0001\u0004\u1a40\u1a41\u1a42\u0001\u0001\u0001\u0002\u1a45\u0001\u0004\u1a4a\u1a4b\u1a4c\u0001\u0001\u0001\u0002\u1a4f\u0001\u0002\u1a52\u0001\u0002\u1a55\u0001\u0002\u1a58\u0001\u0002\u1a5b\u0001\u0002\u1a5e\u0001\u0002\u1a61\u0001\u0002\u1a64\u0001\u0002\u1a67\u0001\u0006\u1a6e\u1a6f\u1a70\u1a71\u1a72\u0001\u0001" + "\u0001\u0004\u1a2d\u1a2e\u1a2f\u0001\u0001\u0001\u0002\u1a32\u0001\u0004\u1a37\u1a38\u1a39\u0001\u0001\u0001\u0002\u1a3c\u0001\u0002\u1a3f\u0001\u0002\u1a42\u0001\u0002\u1a45\u0001\u0002\u1a48\u0001\u0002\u1a4b\u0001\u0002\u1a4e\u0001\u0002\u1a51\u0001\u0002\u1a54\u0001\u0006\u1a5b\u1a5c\u1a5d\u1a5e\u1a5f\u0001\u0001\u0001\u0001\u0001\u0002\u1a62\u0001\u0002\u1a65\u0001\u0005\u1a6b\u1a6c\u1a6d\u1a6e\u0001\u0001\u0001\u0001\u0003" +
"\u0001\u0001\u0001\u0002\u1a75\u0001\u0002\u1a78\u0001\u0005\u1a7e\u1a7f\u1a80\u1a81\u0001\u0001\u0001\u0001\u0003\u1a85\u1a86\u0001\u0001\u0005\u1a8c\u1a8d\u1a8e\u1a8f\u0001\u0001\u0001\u0001\u0003\u1a93\u1a94\u0001\u0001\u0011\u1aa6\u1aa7\u1aa8\u1aa9\u1aaa\u1aab\u1aac\u1aad\u1aae\u1aaf\u1ab0\u1ab1\u1ab2\u1ab3\u1ab4\u1ab5\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1ab1" + "\u1a72\u1a73\u0001\u0001\u0005\u1a79\u1a7a\u1a7b\u1a7c\u0001\u0001\u0001\u0001\u0003\u1a80\u1a81\u0001\u0001\u0011\u1a93\u1a94\u1a95\u1a96\u1a97\u1a98\u1a99\u1a9a\u1a9b\u1a9c\u1a9d\u1a9e\u1a9f\u1aa0\u1aa1\u1aa2\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1a9e\u0011\u1ab6\u1ab7\u1ab8\u1ab9\u1aba\u1abb\u1abc\u1abd\u1abe\u1abf\u1ac0\u1ac1\u1ac2\u1ac3\u1ac4\u1ac5\u0001\u0001" +
"\u0011\u1ac9\u1aca\u1acb\u1acc\u1acd\u1ace\u1acf\u1ad0\u1ad1\u1ad2\u1ad3\u1ad4\u1ad5\u1ad6\u1ad7\u1ad8\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1ad0\u000c\u1ae7\u1ae8\u1ae9\u1aea\u1aeb\u1aec\u1aed\u1aee\u1aef\u1af0\u1af1\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1af5\u1af6\u0001\u0001\u0003\u1afa\u1afb\u0001\u0001\u0003\u1aff\u1b00\u0001" + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1abd\u000c\u1ad4\u1ad5\u1ad6\u1ad7\u1ad8\u1ad9\u1ada\u1adb\u1adc\u1add\u1ade\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1ae2\u1ae3\u0001\u0001\u0003\u1ae7\u1ae8\u0001\u0001\u0003\u1aec\u1aed\u0001\u0001\u0002\u1af0\u0001\u0006\u1a9f\u1aa0\u1aa1\u1a98\u1aa2\u0002\u1ac5\u0002\u1afb\u0001\u0002\u1afe\u0001\u0002" +
"\u0001\u0002\u1b03\u0001\u0006\u1ab2\u1ab3\u1ab4\u1aab\u1ab5\u0002\u1ad8\u0002\u1b0e\u0001\u0002\u1b11\u0001\u0002\u1b14\u0001\u0002\u1b17\u0001\u0004\u1b1c\u1b1d\u1b1e\u0001\u0001\u0001\u0004\u1b23\u1b24\u1b25\u0001\u0001\u0001\u0005\u1b2b\u1b2c\u1b2d\u1b2e\u0001\u0001\u0001\u0001\u0004\u1b33\u1b34\u1b35\u0001\u0001\u0001\u0009\u1b3f\u1b40\u1b41\u1b42\u1b43\u1b44\u1b45\u1b46\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002" + "\u1b01\u0001\u0002\u1b04\u0001\u0004\u1b09\u1b0a\u1b0b\u0001\u0001\u0001\u0004\u1b10\u1b11\u1b12\u0001\u0001\u0001\u0005\u1b18\u1b19\u1b1a\u1b1b\u0001\u0001\u0001\u0001\u0004\u1b20\u1b21\u1b22\u0001\u0001\u0001\u0009\u1b2c\u1b2d\u1b2e\u1b2f\u1b30\u1b31\u1b32\u1b33\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1b2d\u0006\u1b3c\u1b3d\u1b3e\u1b3f\u1b40\u0001\u0001\u0001\u0001\u0001\u0009\u1b4a\u1b4b\u1b4c\u1b4d\u1b4e\u1b4f" +
"\u1b40\u0006\u1b4f\u1b50\u1b51\u1b52\u1b53\u0001\u0001\u0001\u0001\u0001\u0009\u1b5d\u1b5e\u1b5f\u1b60\u1b61\u1b62\u1b63\u1b64\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1b64\u1b60\u0008\u1b70\u1b71\u1b72\u1b73\u1b74\u1b75\u1b76\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0004\u1b7b\u1b7c\u1b7d\u0001\u0001\u0001\u0002\u1b80\u0001\u0007\u1b88\u1b89\u1b8a\u1b8b\u1b8c\u1b8d\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u1b93" + "\u1b50\u1b51\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1b51\u1b4d\u0008\u1b5d\u1b5e\u1b5f\u1b60\u1b61\u1b62\u1b63\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0004\u1b68\u1b69\u1b6a\u0001\u0001\u0001\u0002\u1b6d\u0001\u0007\u1b75\u1b76\u1b77\u1b78\u1b79\u1b7a\u0001\u0001\u0001\u0001\u0001\u0001\u0005\u1b80\u1b81\u1b82\u1b83\u0001\u0001\u0001\u0001\u0005\u1b89\u1b8a\u1b8b\u1b8c\u0001\u0001\u0001\u0001\u0002\u1b8c\u0008" +
"\u1b94\u1b95\u1b96\u0001\u0001\u0001\u0001\u0005\u1b9c\u1b9d\u1b9e\u1b9f\u0001\u0001\u0001\u0001\u0002\u1b9f\u0008\u1baa\u1bab\u1bac\u1bad\u1bae\u1baf\u1bb0\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1bb4\u1bb5\u0001\u0001\u0015\u1bcb\u1bcc\u1bcd\u1bce\u1bcf\u1bd0\u1bd1\u1bd2\u1bd3\u1bd4\u1bd5\u1bd6\u1bd7\u1bd8\u1bd9\u1bda\u1bdb\u1bdc\u1bdd\u1bde\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + "\u1b97\u1b98\u1b99\u1b9a\u1b9b\u1b9c\u1b9d\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0003\u1ba1\u1ba2\u0001\u0001\u0015\u1bb8\u1bb9\u1bba\u1bbb\u1bbc\u1bbd\u1bbe\u1bbf\u1bc0\u1bc1\u1bc2\u1bc3\u1bc4\u1bc5\u1bc6\u1bc7\u1bc8\u1bc9\u1bca\u1bcb\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1bb9\u0003\u1bc6\u1bc7\u0004\u1bbf\u1bc9\u1bc8\u0002\u1bc1\n" +
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u1bcc\u0003\u1bd9\u1bda\u0004\u1bd2\u1bdc\u1bdb\u0002\u1bd4\n\u1bf4\u1bf5\u1bf6\u1bf7\u1bf8\u1bf9\u1bfa\u1bfb\u1bfc\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u1c03\u1c04\u1c05\u1c06\u1c07\u0001\u0001\u0001\u0001\u0001\u0006\u1c0e\u1c0f\u1c10\u1c11\u1c12\u0001\u0001\u0001\u0001\u0001\u0005\u1c18\u1c19\u1c1a\u1c1b\u0001\u0001\u0001\u0001\u0003\u1c1f\u1c20\u0001" + "\u1be1\u1be2\u1be3\u1be4\u1be5\u1be6\u1be7\u1be8\u1be9\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u1bf0\u1bf1\u1bf2\u1bf3\u1bf4\u0001\u0001\u0001\u0001\u0001\u0006\u1bfb\u1bfc\u1bfd\u1bfe\u1bff\u0001\u0001\u0001\u0001\u0001\u0005\u1c05\u1c06\u1c07\u1c08\u0001\u0001\u0001\u0001\u0003\u1c0c\u1c0d\u0001\u0001\u0005\u1c13\u1c14\u1c15\u1c16\u0001\u0001\u0001\u0001\u0002\u1c19\u0001\u0002\u1be5\u0002\u1c06\u0003\u1c21" +
"\u0001\u0005\u1c26\u1c27\u1c28\u1c29\u0001\u0001\u0001\u0001\u0002\u1c2c\u0001\u0002\u1bf8\u0002\u1c19\u0003\u1c34\u1c35\u0001\u0001\u0003\u139a\u1c39\u0001\u0003\u0cab\u1c3d\u0001\u0003\u139b\u1c41\u0001\u0003\u0cac\u1c45\u0001\u0002\u1c48\u0001\u0004\u1129\u139c\u1c4d\u0001\u0005\u139d\u141a\u04f5\u1c53\u0001\u0002\u1c56\u0001\u0002\u112a\u0002\u1c5b\u0001\u0008\u112b\u04e4\u1c64\u1c65\u1c66\u1c67\u1c68\u0001\u0001\u0001\u0001" + "\u1c22\u0001\u0001\u0003\u1387\u1c26\u0001\u0003\u0cab\u1c2a\u0001\u0003\u1388\u1c2e\u0001\u0003\u0cac\u1c32\u0001\u0002\u1c35\u0001\u0004\u111c\u1389\u1c3a\u0001\u0005\u138a\u1407\u04f5\u1c40\u0001\u0002\u1c43\u0001\u0002\u111d\u0002\u1c48\u0001\u0008\u111e\u04e4\u1c51\u1c52\u1c53\u1c54\u1c55\u0001\u0001\u0001\u0001\u0001\u0002\u1c58\u0001\u0002\u1c5b\u0001\u0004\u1408\u0de1\u1c60\u0001\u0004\u1409\u0de1\u1c65\u0001\u0002\u1c51" +
"\u0001\u0002\u1c6b\u0001\u0002\u1c6e\u0001\u0004\u141b\u0de1\u1c73\u0001\u0004\u141c\u0de1\u1c78\u0001\u0002\u1c64\u0002\u139e\u0002\u1c7f\u0001\u0002\u1c82\u0001\u0002\u1c85\u0001\u0002\u1c88\u0001\u0003\u112c\u1c8c\u0001\u0002\u112c\u0002\u1c91\u0001\u0002\u1c94\u0001\u0002\u1c97\u0001\u0002\u1c9a\u0001\u0002\u1c9d\u0001\u0002\u1ca0\u0001\u0002\u1ca3\u0001\u0002\u1ca6\u0001\u0002\u1ca9\u0001\u0002\u1cac\u0001\u0004\u1cb1\u112d" + "\u0002\u138b\u0002\u1c6c\u0001\u0002\u1c6f\u0001\u0002\u1c72\u0001\u0002\u1c75\u0001\u0003\u111f\u1c79\u0001\u0002\u111f\u0002\u1c7e\u0001\u0002\u1c81\u0001\u0002\u1c84\u0001\u0002\u1c87\u0001\u0002\u1c8a\u0001\u0002\u1c8d\u0001\u0002\u1c90\u0001\u0002\u1c93\u0001\u0002\u1c96\u0001\u0002\u1c99\u0001\u0004\u1c9e\u1120\u138c\u0001\u0003\u1ca2\u1121\u0001\u0002\u1ca5\u0001\u0002\u1ca8\u0001\u0002\u1cab\u0001\u0002\u1cae\u0001\u0002" +
"\u139f\u0001\u0003\u1cb5\u112e\u0001\u0002\u1cb8\u0001\u0002\u1cbb\u0001\u0002\u1cbe\u0001\u0002\u1cc1\u0001\u0002\u1cc4\u0001\u0005\u1436\u1486\u1c65\u1cca\u0001\u0004\u112f\u1c66\u1cca\u0002\u1cd1\u0001\u0002\u1cd4\u0001\u0002\u1cd7\u0001\u0002\u1cda\u0001\u0002\u1cdd\u0001\u0002\u1ce0\u0001\u0002\u1ce3\u0001\u0003\u1130\u1ce7\u0001\u0002\u1131\u0002\u1132\u0002\u1133\u0016\u083b\u0d65\u0da7\u0deb\u0e1e\u0e3d\u0e7c\u0ff5\u1563" + "\u1cb1\u0001\u0005\u1423\u1473\u1c52\u1cb7\u0001\u0004\u1122\u1c53\u1cb7\u0002\u1cbe\u0001\u0002\u1cc1\u0001\u0002\u1cc4\u0001\u0002\u1cc7\u0001\u0002\u1cca\u0001\u0002\u1ccd\u0001\u0002\u1cd0\u0001\u0003\u1123\u1cd4\u0001\u0002\u1124\u0002\u1125\u0002\u1126\u0016\u083b\u0d65\u0da7\u0deb\u0e1e\u0e3d\u0e7c\u0fe8\u1550\u1c26\u1c2a\u1c2e\u1c32\u1c3a\u1c40\u1c54\u1c60\u1c65\u1c79\u1cd4\u1cf1\u0001\n\u0c23\u0cad\u0d23\u0fe9\u1127" +
"\u1c39\u1c3d\u1c41\u1c45\u1c4d\u1c53\u1c67\u1c73\u1c78\u1c8c\u1ce7\u1d04\u0001\n\u0c23\u0cad\u0d23\u0ff6\u1134\u13a0\u1437\u1c68\u1d04\u0002\u1d11\u0001\u00f6\u1e08\u066c\u06cc\u0706\u07ce\u06cd\u06ce\u0351\u0cfd\u0c95\u0cfe\u1e0d\u1e11\u1e14\u1e17\u1e1a\u1e1d\u1e20\u1e23\u1e26\u1e29\u1e2c\u0ddf\u1414\u0e36\u0e66\u07d3\u07d4\u0c59\u0c94\u1230\u1e31\u0d58\u0e0f\u1e32\u0ca6\u130d\u0e13\u0e14\u0d5a\u0e18\u1e33\u0d00\u0688\u0d02" + "\u138d\u1424\u1c55\u1cf1\u0002\u1cfe\u0001\u00ee\u1ded\u066c\u06cc\u0706\u07ce\u06cd\u06ce\u0351\u0cfd\u0c95\u0cfe\u1df2\u1df6\u1df9\u1dfc\u1dff\u1e02\u1e05\u1e08\u1e0b\u1e0e\u1e11\u0ddf\u1401\u0e36\u0e66\u07d3\u07d4\u0c59\u0c94\u1222\u1e16\u0d58\u0e0f\u1e17\u0ca6\u12fa\u0e13\u0e14\u0d5a\u0e18\u1e18\u0d00\u0688\u0d02\u1e19\u0f3a\u1e21\u1e22\u1e23\u1e24\u1e25\u1e26\u1e27\u1e28\u1e29\u1e2a\u1e2b\u1e2c\u1e2d\u1e2e\u1e2f\u162d\u1e30" +
"\u1e34\u0f42\u1e3c\u1e3d\u1e3e\u1e3f\u1e40\u1e41\u1e42\u1e43\u1e44\u1e45\u1e46\u1e47\u1e48\u1e49\u1e4a\u1640\u1e4b\u1e4c\u1e4e\u1e4f\u0d1f\u1e50\u1e51\u1e52\u1e53\u1e54\u1702\u16fd\u1e56\u1e57\u1e59\u1e5a\u17b1\u1e5b\u0fc3\u0d22\u1653\u0d1e\u1e5c\u1678\u1682\u16c9\u0d1f\u1e5e\u1e6a\u1e71\u1e77\u1e7e\u1e84\u1e89\u1e8f\u1e9b\u1ea1\u1ea7\u1eae\u1ebb\u1897\u18ad\u197a\u1ec1\u192e\u1ec2\u1ec3\u1883\u1ec4\u1ec5\u1ec6\u1ec7\u1ec8\u18c6" + "\u1e31\u1e33\u1e34\u0d1f\u1e35\u1e36\u1e37\u1e38\u1e39\u16ef\u16ea\u1e3b\u1e3c\u1e3e\u1e3f\u179e\u1e40\u0fb7\u0d22\u1640\u0d1e\u1e41\u1665\u166f\u16b6\u0d1f\u1e43\u1e4f\u1e56\u1e5c\u1e63\u1e69\u1e6e\u1e74\u1e80\u1e86\u1e8c\u1e93\u1ea0\u1884\u189a\u1967\u1ea6\u191b\u1ea7\u1ea8\u1870\u1ea9\u1eaa\u1eab\u1eac\u1ead\u18b3\u1995\u1eae\u1eaf\u1eb0\u18d0\u1eb1\u1eb2\u1eb3\u192b\u192c\u1df2\u1df6\u1df9\u1dfc\u1dff\u1e02\u1e05\u1e08\u1e0b" +
"\u19a8\u1ec9\u1eca\u1ecb\u18e3\u1ecc\u1ecd\u1ece\u193e\u193f\u1e0d\u1e11\u1e14\u1e17\u1e1a\u1e1d\u1e20\u1e23\u1e26\u1e29\u194b\u1ecf\u198f\u19a8\u1ed0\u1968\u1e0d\u1e11\u1e14\u1e17\u1e1a\u1e1d\u1e20\u1e23\u1e26\u1e29\u1ed1\u1ed2\u1ed3\u1ed4\u1ed5\u1ed6\u1ed7\u1ed8\u1ed9\u1eda\u1edb\u1edc\u1edd\u1ede\u19e9\u19ea\u19eb\u1edf\u1ee0\u1ee1\u19ec\u1ee5\u1ee6\u19ed\u19ee\u1ee7\u1ee8\u1eec\u19ef\u1ef0\u19f0\u1ef4\u19f1\u19f2\u19f3\u1ef5" + "\u1e0e\u1938\u1eb4\u197c\u1995\u1eb5\u1955\u1df2\u1df6\u1df9\u1dfc\u1dff\u1e02\u1e05\u1e08\u1e0b\u1e0e\u1eb6\u1eb7\u1eb8\u1eb9\u1eba\u1ebb\u1ebc\u1ebd\u1ebe\u1ebf\u1ec0\u1ec1\u1ec2\u1ec3\u19d6\u19d7\u19d8\u1ec4\u1ec5\u1ec6\u19d9\u1eca\u1ecb\u19da\u19db\u1ecc\u1ecd\u1ed1\u19dc\u1ed5\u19dd\u1ed9\u19de\u19df\u19e0\u1eda\u1edb\u1edf\u1ee3\u1ee4\u1ee5\u1ee6\u1ee7\u1ee8\u1ee9\u1eea\u1eeb\u1eec\u1eed\u1eee\u1eef\u1ef0\u1ef1\u1ef2\u1ef3" +
"\u1ef6\u1efa\u1efe\u1eff\u1f00\u1f01\u1f02\u1f03\u1f04\u1f05\u1f06\u1f07\u1f08\u1f09\u1f0a\u1f0b\u1f0c\u1f0d\u1f0e\u1f10\u1f12\u1f14\u1f16\u1398\u1e34\u0f52\u0e0d\u0e19\u0e0e\u0e1c\u1f18\u1f19\u1f1a\u1f1b\u1f1c\u1f1d\u1c48\u1129\u04f5\u1f1e\u1f1f\u1f20\u1f21\u1f22\u112d\u112e\u1436\u1f23\u1ce7\u139f\u1132\u1133\u083b\u1685\u1f24\u1f25\u0005\u0000\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003" + "\u1ef5\u1ef7\u1ef9\u1efb\u1385\u1e19\u0f48\u0e0d\u0e19\u0e0e\u0e1c\u1efd\u1efe\u1eff\u1f00\u1f01\u1f02\u1c35\u1f03\u1f04\u1f05\u1f06\u1f07\u1120\u1121\u1f08\u1672\u1f09\u1f0a\u0005\u0000\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0005\u0000\u0000\u0000\u0000\u0001\u0001" +
"\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0005\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0002\u0000\u0001\u0001\u0001\u0002\u0000\u000c\u0000" + "\u0001\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0001\u0002\u0000\u0001\u0001\u0001\u0002\u0000\u000c\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0007\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0007\u0000\u0000\u0000" +
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0007\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0007\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0005\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u000c\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0007" + "\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0005\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u000c\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0007\u0000\u0000\u0000\u0000\u0000\u0000\r\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0001\u0001" +
"\u0000\u0000\u0000\u0000\u0000\u0000\r\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0006\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0004\u0000\u0000\u0000\u0001\u0001\u0001\u0004\u0000\u0000\u0000\u0004\u0000\u0000\u0000" + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0004\u0000\u0000\u0000\u0001\u0001\u0001\u0004\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0001\u0001\u0004\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" +
"\u0004\u0000\u0000\u0000\u0001\u0001\u0004\u0000\u0000\u0000\u0004\u0000\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f31\u1f32\u1f33\u1f34\u1f35\u1f36\u1f37\u1f38\u1f39\u1f3a\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + "\u0001\u0001\u0001\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0002\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f16\u1f17\u1f18\u1f19\u1f1a\u1f1b\u1f1c\u1f1d\u1f1e\u1f1f\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f2b\u1f2c\u1f2d\u1f2e\u1f2f\u1f30\u1f31\u1f32\u1f33\u1f34\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f40\u1f41" +
"\u0001\u0001\u0001\u000b\u1f46\u1f47\u1f48\u1f49\u1f4a\u1f4b\u1f4c\u1f4d\u1f4e\u1f4f\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f5b\u1f5c\u1f5d\u1f5e\u1f5f\u1f60\u1f61\u1f62\u1f63\u1f64\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f70\u1f71\u1f72\u1f73\u1f74\u1f75\u1f76\u1f77\u1f78\u1f79\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f85\u1f86\u1f87\u1f88\u1f89" + "\u1f42\u1f43\u1f44\u1f45\u1f46\u1f47\u1f48\u1f49\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f55\u1f56\u1f57\u1f58\u1f59\u1f5a\u1f5b\u1f5c\u1f5d\u1f5e\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f6a\u1f6b\u1f6c\u1f6d\u1f6e\u1f6f\u1f70\u1f71\u1f72\u1f73\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f7f\u1f80\u1f81\u1f82\u1f83\u1f84\u1f85\u1f86\u1f87\u1f88\u0001" +
"\u1f8a\u1f8b\u1f8c\u1f8d\u1f8e\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f9a\u1f9b\u1f9c\u1f9d\u1f9e\u1f9f\u1fa0\u1fa1\u1fa2\u1fa3\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1faf\u1fb0\u1fb1\u1fb2\u1fb3\u1fb4\u1fb5\u1fb6\u1fb7\u1fb8\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0071\u0f60\u0d0b\u202a\u202d\u2030\u2031\u2032\u2033\u2034\u2035\u2036\u2037\u1ed9\u1eda" + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u000b\u1f94\u1f95\u1f96\u1f97\u1f98\u1f99\u1f9a\u1f9b\u1f9c\u1f9d\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0070\u0f55\u0d0b\u200e\u2011\u2014\u2015\u2016\u2017\u2018\u2019\u201a\u201b\u1ebe\u1ebf\u201c\u201d\u201e\u201f\u2020\u2021\u2022\u2023\u2024\u2025\u2026\u2027\u2028\u2029\u202a\u202b\u202c\u202d\u1ee9\u1eb8\u202e\u1eb9\u202f\u2030\u1ef0\u2031\u2032" +
"\u2038\u2039\u203a\u203b\u203c\u203d\u203e\u203f\u2040\u2041\u2042\u2043\u2044\u2045\u2046\u2047\u2048\u2049\u1f04\u1ed3\u204a\u1ed4\u204b\u204c\u1f0b\u204d\u204e\u204f\u2050\u2051\u2052\u2053\u2054\u2055\u2056\u2057\u2058\u2059\u205a\u205b\u205c\u205d\u205e\u205f\u2060\u2061\u2062\u2063\u2064\u0f52\u2065\u2066\u2067\u2068\u2069\u206a\u206b\u206c\u206d\u206e\u206f\u2070\u2071\u2072\u2074\u2076\u2077\u207a\u207d\u2080\u2081\u0f52" + "\u2033\u2034\u2035\u2036\u2037\u2038\u2039\u203a\u203b\u203c\u203d\u203e\u203f\u2040\u2041\u2042\u2043\u2044\u2045\u2046\u2047\u2048\u0f48\u2049\u204a\u204b\u204c\u204d\u204e\u204f\u2050\u2051\u2052\u2053\u2054\u2055\u2056\u2058\u205a\u205b\u205e\u2061\u2064\u2065\u0f48\u0e0d\u0e19\u0e0e\u0e1c\u1eff\u1f00\u1f01\u1f02\u1c43\u1c48\u1c9e\u1ca2\u1ca5\u1ca8\u2066\u2067\u2068\u2069\u206a\u206b\u206c\u206d\u206e\u206f\u2070\u0003\u0000" +
"\u0e0d\u0e19\u0e0e\u0e1c\u1f1a\u1f1b\u1f1c\u1f1d\u1c56\u1c5b\u1cb1\u1cb5\u1cb8\u1cbb\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u208a\u208b\u208c\u208d\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001" + "\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000" +
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0000\u0002\u0000\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u2093\u2096\u2099\u209c\u209f\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0003" + "\u0002\u0000\u0001\u0003\u0000\u0000\u0003\u0000\u0000\u0003\u0000\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001").toCharArray();
"\u0000\u0000").toCharArray();
public static final int accent_aigu = 1; public static final int accent_aigu = 1;
public static final int accent_arrows = 130; public static final int accent_arrows = 130;
@@ -266,13 +264,13 @@ public final class ComposeKeyData
public static final int accent_tilde = 1144; public static final int accent_tilde = 1144;
public static final int accent_trema = 1172; public static final int accent_trema = 1172;
public static final int compose = 1270; public static final int compose = 1270;
public static final int fn = 7442; public static final int fn = 7423;
public static final int numpad_bengali = 7974; public static final int numpad_bengali = 7947;
public static final int numpad_devanagari = 7995; public static final int numpad_devanagari = 7968;
public static final int numpad_gujarati = 8016; public static final int numpad_gujarati = 7989;
public static final int numpad_hindu = 8037; public static final int numpad_hindu = 8010;
public static final int numpad_kannada = 8058; public static final int numpad_kannada = 8031;
public static final int numpad_persian = 8079; public static final int numpad_persian = 8052;
public static final int numpad_tamil = 8100; public static final int numpad_tamil = 8073;
public static final int shift = 8121; public static final int shift = 8094;
} }

View File

@@ -5,7 +5,6 @@ import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import androidx.window.layout.WindowInfoTracker;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -31,7 +30,6 @@ public final class Config
// From the 'numpad_layout' option, also apply to the numeric pane. // From the 'numpad_layout' option, also apply to the numeric pane.
public boolean inverse_numpad = false; public boolean inverse_numpad = false;
public boolean add_number_row; public boolean add_number_row;
public boolean number_row_symbols;
public float swipe_dist_px; public float swipe_dist_px;
public float slide_step_px; public float slide_step_px;
// Let the system handle vibration when false. // Let the system handle vibration when false.
@@ -42,8 +40,7 @@ public final class Config
public long longPressInterval; public long longPressInterval;
public boolean keyrepeat_enabled; public boolean keyrepeat_enabled;
public float margin_bottom; public float margin_bottom;
public int keyboardHeightPercent; public float keyHeight;
public int screenHeightPixels;
public float horizontal_margin; public float horizontal_margin;
public float key_vertical_margin; public float key_vertical_margin;
public float key_horizontal_margin; public float key_horizontal_margin;
@@ -74,16 +71,13 @@ public final class Config
public final IKeyEventHandler handler; public final IKeyEventHandler handler;
public boolean orientation_landscape = false; public boolean orientation_landscape = false;
public boolean foldable_unfolded = false;
/** Index in 'layouts' of the currently used layout. See /** Index in 'layouts' of the currently used layout. See
[get_current_layout()] and [set_current_layout()]. */ [get_current_layout()] and [set_current_layout()]. */
int current_layout_portrait; int current_layout_portrait;
int current_layout_landscape; int current_layout_landscape;
int current_layout_unfolded_portrait;
int current_layout_unfolded_landscape;
public int bottomInsetMin; public int bottomInsetMin;
private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h, Boolean foldableUnfolded) private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h)
{ {
_prefs = prefs; _prefs = prefs;
// static values // static values
@@ -92,7 +86,7 @@ public final class Config
labelTextSize = 0.33f; labelTextSize = 0.33f;
sublabelTextSize = 0.22f; sublabelTextSize = 0.22f;
// from prefs // from prefs
refresh(res, foldableUnfolded); refresh(res);
// initialized later // initialized later
shouldOfferVoiceTyping = false; shouldOfferVoiceTyping = false;
actionLabel = null; actionLabel = null;
@@ -105,12 +99,13 @@ public final class Config
/* /*
** Reload prefs ** Reload prefs
*/ */
public void refresh(Resources res, Boolean foldableUnfolded) public void refresh(Resources res)
{ {
DisplayMetrics dm = res.getDisplayMetrics(); DisplayMetrics dm = res.getDisplayMetrics();
orientation_landscape = res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; orientation_landscape = res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
foldable_unfolded = foldableUnfolded; // The height of the keyboard is relative to the height of the screen.
// This is the height of the keyboard if it have 4 rows.
int keyboardHeightPercent;
float characterSizeScale = 1.f; float characterSizeScale = 1.f;
String show_numpad_s = _prefs.getString("show_numpad", "never"); String show_numpad_s = _prefs.getString("show_numpad", "never");
show_numpad = "always".equals(show_numpad_s); show_numpad = "always".equals(show_numpad_s);
@@ -118,18 +113,16 @@ public final class Config
{ {
if ("landscape".equals(show_numpad_s)) if ("landscape".equals(show_numpad_s))
show_numpad = true; show_numpad = true;
keyboardHeightPercent = _prefs.getInt(foldable_unfolded ? "keyboard_height_landscape_unfolded" : "keyboard_height_landscape", 50); keyboardHeightPercent = _prefs.getInt("keyboard_height_landscape", 50);
characterSizeScale = 1.25f; characterSizeScale = 1.25f;
} }
else else
{ {
keyboardHeightPercent = _prefs.getInt(foldable_unfolded ? "keyboard_height_unfolded" : "keyboard_height", 35); keyboardHeightPercent = _prefs.getInt("keyboard_height", 35);
} }
layouts = LayoutsPreference.load_from_preferences(res, _prefs); layouts = LayoutsPreference.load_from_preferences(res, _prefs);
inverse_numpad = _prefs.getString("numpad_layout", "default").equals("low_first"); inverse_numpad = _prefs.getString("numpad_layout", "default").equals("low_first");
String number_row = _prefs.getString("number_row", "no_number_row"); add_number_row = _prefs.getBoolean("number_row", false);
add_number_row = !number_row.equals("no_number_row");
number_row_symbols = number_row.equals("symbols");
// The baseline for the swipe distance correspond to approximately the // The baseline for the swipe distance correspond to approximately the
// width of a key in portrait mode, as most layouts have 10 columns. // width of a key in portrait mode, as most layouts have 10 columns.
// Multipled by the DPI ratio because most swipes are made in the diagonals. // Multipled by the DPI ratio because most swipes are made in the diagonals.
@@ -157,7 +150,9 @@ public final class Config
borderConfig = _prefs.getBoolean("border_config", false); borderConfig = _prefs.getBoolean("border_config", false);
customBorderRadius = _prefs.getInt("custom_border_radius", 0) / 100.f; customBorderRadius = _prefs.getInt("custom_border_radius", 0) / 100.f;
customBorderLineWidth = get_dip_pref(dm, "custom_border_line_width", 0); customBorderLineWidth = get_dip_pref(dm, "custom_border_line_width", 0);
screenHeightPixels = dm.heightPixels; // Do not substract key_vertical_margin from keyHeight because this is done
// during rendering.
keyHeight = dm.heightPixels * keyboardHeightPercent / 100 / 4;
horizontal_margin = horizontal_margin =
get_dip_pref_oriented(dm, "horizontal_margin", 3, 28); get_dip_pref_oriented(dm, "horizontal_margin", 3, 28);
double_tap_lock_shift = _prefs.getBoolean("lock_double_tap", false); double_tap_lock_shift = _prefs.getBoolean("lock_double_tap", false);
@@ -172,8 +167,6 @@ public final class Config
pin_entry_enabled = _prefs.getBoolean("pin_entry_enabled", true); pin_entry_enabled = _prefs.getBoolean("pin_entry_enabled", true);
current_layout_portrait = _prefs.getInt("current_layout_portrait", 0); current_layout_portrait = _prefs.getInt("current_layout_portrait", 0);
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0); current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
current_layout_unfolded_portrait = _prefs.getInt("current_layout_unfolded_portrait", 0);
current_layout_unfolded_landscape = _prefs.getInt("current_layout_unfolded_landscape", 0);
circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2")); circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2"));
clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false); clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false);
bottomInsetMin = Utils.is_navigation_bar_gestural(res) ? bottomInsetMin = Utils.is_navigation_bar_gestural(res) ?
@@ -182,34 +175,19 @@ public final class Config
public int get_current_layout() public int get_current_layout()
{ {
if (foldable_unfolded) {
return (orientation_landscape)
? current_layout_unfolded_landscape : current_layout_unfolded_portrait;
} else {
return (orientation_landscape) return (orientation_landscape)
? current_layout_landscape : current_layout_portrait; ? current_layout_landscape : current_layout_portrait;
} }
}
public void set_current_layout(int l) public void set_current_layout(int l)
{ {
if (foldable_unfolded) {
if (orientation_landscape)
current_layout_unfolded_landscape = l;
else
current_layout_unfolded_portrait = l;
} else {
if (orientation_landscape) if (orientation_landscape)
current_layout_landscape = l; current_layout_landscape = l;
else else
current_layout_portrait = l; current_layout_portrait = l;
}
SharedPreferences.Editor e = _prefs.edit(); SharedPreferences.Editor e = _prefs.edit();
e.putInt("current_layout_portrait", current_layout_portrait); e.putInt("current_layout_portrait", current_layout_portrait);
e.putInt("current_layout_landscape", current_layout_landscape); e.putInt("current_layout_landscape", current_layout_landscape);
e.putInt("current_layout_unfolded_portrait", current_layout_unfolded_portrait);
e.putInt("current_layout_unfolded_landscape", current_layout_unfolded_landscape);
e.apply(); e.apply();
} }
@@ -232,13 +210,7 @@ public final class Config
/** [get_dip_pref] depending on orientation. */ /** [get_dip_pref] depending on orientation. */
float get_dip_pref_oriented(DisplayMetrics dm, String pref_base_name, float def_port, float def_land) float get_dip_pref_oriented(DisplayMetrics dm, String pref_base_name, float def_port, float def_land)
{ {
final String suffix; String suffix = orientation_landscape ? "_landscape" : "_portrait";
if (foldable_unfolded) {
suffix = orientation_landscape ? "_landscape_unfolded" : "_portrait_unfolded";
} else {
suffix = orientation_landscape ? "_landscape" : "_portrait";
}
float def = orientation_landscape ? def_land : def_port; float def = orientation_landscape ? def_land : def_port;
return get_dip_pref(dm, pref_base_name + suffix, def); return get_dip_pref(dm, pref_base_name + suffix, def);
} }
@@ -274,10 +246,10 @@ public final class Config
private static Config _globalConfig = null; private static Config _globalConfig = null;
public static void initGlobalConfig(SharedPreferences prefs, Resources res, public static void initGlobalConfig(SharedPreferences prefs, Resources res,
IKeyEventHandler handler, Boolean foldableUnfolded) IKeyEventHandler handler)
{ {
migrate(prefs); migrate(prefs);
_globalConfig = new Config(prefs, res, handler, foldableUnfolded); _globalConfig = new Config(prefs, res, handler);
LayoutModifier.init(_globalConfig, res); LayoutModifier.init(_globalConfig, res);
} }
@@ -300,7 +272,7 @@ public final class Config
/** Config migrations. */ /** Config migrations. */
private static int CONFIG_VERSION = 2; private static int CONFIG_VERSION = 1;
public static void migrate(SharedPreferences prefs) public static void migrate(SharedPreferences prefs)
{ {
@@ -312,7 +284,7 @@ public final class Config
e.putInt("version", CONFIG_VERSION); e.putInt("version", CONFIG_VERSION);
// Migrations might run on an empty [prefs] for new installs, in this case // Migrations might run on an empty [prefs] for new installs, in this case
// they set the default values of complex options. // they set the default values of complex options.
switch (saved_version) switch (saved_version) // Fallback switch
{ {
case 0: case 0:
// Primary, secondary and custom layout options are merged into the new // Primary, secondary and custom layout options are merged into the new
@@ -326,12 +298,7 @@ public final class Config
if (custom_layout != null && !custom_layout.equals("")) if (custom_layout != null && !custom_layout.equals(""))
l.add(LayoutsPreference.CustomLayout.parse(custom_layout)); l.add(LayoutsPreference.CustomLayout.parse(custom_layout));
LayoutsPreference.save_to_preferences(e, l); LayoutsPreference.save_to_preferences(e, l);
// Fallthrough
case 1: case 1:
boolean add_number_row = prefs.getBoolean("number_row", false);
e.putString("number_row", add_number_row ? "no_symbols" : "no_number_row");
// Fallthrough
case 2:
default: break; default: break;
} }
e.apply(); e.apply();

View File

@@ -51,14 +51,8 @@ public class Emoji
if ((line = reader.readLine()) != null) if ((line = reader.readLine()) != null)
{ {
String[] tokens = line.split(" "); String[] tokens = line.split(" ");
int last = 0; for (int i = 0; i < tokens.length-1; i++)
for (int i = 1; i < tokens.length; i++) _groups.add(_all.subList(Integer.parseInt(tokens[i]), Integer.parseInt(tokens[i+1])));
{
int next = Integer.parseInt(tokens[i]);
_groups.add(_all.subList(last, next));
last = next;
}
_groups.add(_all.subList(last, _all.size()));
} }
} }
catch (IOException e) { Logs.exn("Emoji.init() failed", e); } catch (IOException e) { Logs.exn("Emoji.init() failed", e); }

View File

@@ -1,62 +0,0 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.pm.PackageManager;
import androidx.window.java.layout.WindowInfoTrackerCallbackAdapter;
import androidx.window.layout.DisplayFeature;
import androidx.window.layout.FoldingFeature;
import androidx.window.layout.WindowInfoTracker;
import androidx.window.layout.WindowLayoutInfo;
import androidx.core.util.Consumer;
public class FoldStateTracker {
private final Consumer<WindowLayoutInfo> _innerListener;
private final WindowInfoTrackerCallbackAdapter _windowInfoTracker;
private FoldingFeature _foldingFeature = null;
private Runnable _changedCallback = null;
public FoldStateTracker(Context context) {
_windowInfoTracker =
new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(context));
_innerListener = new LayoutStateChangeCallback();
_windowInfoTracker.addWindowLayoutInfoListener(context, Runnable::run, _innerListener);
}
public static boolean isFoldableDevice(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE);
}
public boolean isUnfolded() {
// FoldableFeature is only present when the device is unfolded. Otherwise, it's removed.
// A weird decision from Google, but that's how it works:
// https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:window/window/src/main/java/androidx/window/layout/adapter/sidecar/SidecarAdapter.kt;l=187?q=SidecarAdapter
return _foldingFeature != null;
}
public void close() {
_windowInfoTracker.removeWindowLayoutInfoListener(_innerListener);
}
public void setChangedCallback(Runnable _changedCallback) {
this._changedCallback = _changedCallback;
}
class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
@Override
public void accept(WindowLayoutInfo newLayoutInfo) {
FoldingFeature old = _foldingFeature;
_foldingFeature = null;
for (DisplayFeature feature: newLayoutInfo.getDisplayFeatures()) {
if (feature instanceof FoldingFeature) {
_foldingFeature = (FoldingFeature) feature;
}
}
if (old != _foldingFeature && _changedCallback != null) {
_changedCallback.run();
}
}
}
}

View File

@@ -2,7 +2,6 @@ package juloo.keyboard2;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.os.Looper; import android.os.Looper;
import android.os.Handler;
import android.text.InputType; import android.text.InputType;
import android.view.KeyCharacterMap; import android.view.KeyCharacterMap;
import android.view.KeyEvent; import android.view.KeyEvent;
@@ -29,10 +28,10 @@ public final class KeyEventHandler
[setSelection] could be used instead. */ [setSelection] could be used instead. */
boolean _move_cursor_force_fallback = false; boolean _move_cursor_force_fallback = false;
public KeyEventHandler(IReceiver recv) public KeyEventHandler(Looper looper, IReceiver recv)
{ {
_recv = recv; _recv = recv;
_autocap = new Autocapitalisation(recv.getHandler(), _autocap = new Autocapitalisation(looper,
this.new Autocapitalisation_callback()); this.new Autocapitalisation_callback());
_mods = Pointers.Modifiers.EMPTY; _mods = Pointers.Modifiers.EMPTY;
} }
@@ -98,9 +97,11 @@ public final class KeyEventHandler
case Keyevent: send_key_down_up(key.getKeyevent()); break; case Keyevent: send_key_down_up(key.getKeyevent()); break;
case Modifier: break; case Modifier: break;
case Editing: handle_editing_key(key.getEditing()); break; case Editing: handle_editing_key(key.getEditing()); break;
case Compose_pending: _recv.set_compose_pending(true); break; case Compose_pending:
_recv.set_compose_pending(true);
break;
case Slider: handle_slider(key.getSlider(), key.getSliderRepeat()); break; case Slider: handle_slider(key.getSlider(), key.getSliderRepeat()); break;
case Macro: evaluate_macro(key.getMacro()); break; case StringWithSymbol: send_text(key.getStringWithSymbol()); break;
} }
update_meta_state(old_mods); update_meta_state(old_mods);
} }
@@ -147,11 +148,11 @@ public final class KeyEventHandler
if (down) if (down)
{ {
_meta_state = _meta_state | meta_flags; _meta_state = _meta_state | meta_flags;
send_keyevent(KeyEvent.ACTION_DOWN, eventCode, _meta_state); send_keyevent(KeyEvent.ACTION_DOWN, eventCode);
} }
else else
{ {
send_keyevent(KeyEvent.ACTION_UP, eventCode, _meta_state); send_keyevent(KeyEvent.ACTION_UP, eventCode);
_meta_state = _meta_state & ~meta_flags; _meta_state = _meta_state & ~meta_flags;
} }
} }
@@ -182,28 +183,25 @@ public final class KeyEventHandler
} }
} }
/*
* Don't set KeyEvent.FLAG_SOFT_KEYBOARD.
*/
void send_key_down_up(int keyCode) void send_key_down_up(int keyCode)
{ {
send_key_down_up(keyCode, _meta_state); send_keyevent(KeyEvent.ACTION_DOWN, keyCode);
send_keyevent(KeyEvent.ACTION_UP, keyCode);
} }
/** Ignores currently pressed system modifiers. */ void send_keyevent(int eventAction, int eventCode)
void send_key_down_up(int keyCode, int metaState)
{
send_keyevent(KeyEvent.ACTION_DOWN, keyCode, metaState);
send_keyevent(KeyEvent.ACTION_UP, keyCode, metaState);
}
void send_keyevent(int eventAction, int eventCode, int metaState)
{ {
InputConnection conn = _recv.getCurrentInputConnection(); InputConnection conn = _recv.getCurrentInputConnection();
if (conn == null) if (conn == null)
return; return;
conn.sendKeyEvent(new KeyEvent(1, 1, eventAction, eventCode, 0, conn.sendKeyEvent(new KeyEvent(1, 1, eventAction, eventCode, 0,
metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, _meta_state, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE)); KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
if (eventAction == KeyEvent.ACTION_UP) if (eventAction == KeyEvent.ACTION_UP)
_autocap.event_sent(eventCode, metaState); _autocap.event_sent(eventCode, _meta_state);
} }
void send_text(CharSequence text) void send_text(CharSequence text)
@@ -240,9 +238,6 @@ public final class KeyEventHandler
case REPLACE: send_context_menu_action(android.R.id.replaceText); break; case REPLACE: send_context_menu_action(android.R.id.replaceText); break;
case ASSIST: send_context_menu_action(android.R.id.textAssist); break; case ASSIST: send_context_menu_action(android.R.id.textAssist); break;
case AUTOFILL: send_context_menu_action(android.R.id.autofill); break; case AUTOFILL: send_context_menu_action(android.R.id.autofill); break;
case DELETE_WORD: send_key_down_up(KeyEvent.KEYCODE_DEL, KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON); break;
case FORWARD_DELETE_WORD: send_key_down_up(KeyEvent.KEYCODE_FORWARD_DEL, KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON); break;
case SELECTION_CANCEL: cancel_selection(); break;
} }
} }
@@ -260,17 +255,15 @@ public final class KeyEventHandler
return conn.getExtractedText(_move_cursor_req, 0); return conn.getExtractedText(_move_cursor_req, 0);
} }
/** [r] might be negative, in which case the direction is reversed. */ /** [repeatition] might be negative, in which case the direction is reversed. */
void handle_slider(KeyValue.Slider s, int r) void handle_slider(KeyValue.Slider s, int repeatition)
{ {
switch (s) switch (s)
{ {
case Cursor_left: move_cursor(-r); break; case Cursor_left: move_cursor(-repeatition); break;
case Cursor_right: move_cursor(r); break; case Cursor_right: move_cursor(repeatition); break;
case Cursor_up: move_cursor_vertical(-r); break; case Cursor_up: move_cursor_vertical(-repeatition); break;
case Cursor_down: move_cursor_vertical(r); break; case Cursor_down: move_cursor_vertical(repeatition); break;
case Selection_cursor_left: move_cursor_sel(r, true); break;
case Selection_cursor_right: move_cursor_sel(r, false); break;
} }
} }
@@ -284,7 +277,12 @@ public final class KeyEventHandler
if (conn == null) if (conn == null)
return; return;
ExtractedText et = get_cursor_pos(conn); ExtractedText et = get_cursor_pos(conn);
if (et != null && can_set_selection(conn)) int system_mods =
KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON | KeyEvent.META_META_ON;
// Fallback to sending key events if system modifiers are activated or
// ExtractedText is not supported, for example on Termux.
if (!_move_cursor_force_fallback && et != null
&& (_meta_state & system_mods) == 0)
{ {
int sel_start = et.selectionStart; int sel_start = et.selectionStart;
int sel_end = et.selectionEnd; int sel_end = et.selectionEnd;
@@ -303,45 +301,8 @@ public final class KeyEventHandler
sel_start = sel_end; sel_start = sel_end;
} }
if (conn.setSelection(sel_start, sel_end)) if (conn.setSelection(sel_start, sel_end))
return; // Fallback to sending key events if [setSelection] failed return; // [setSelection] succeeded, don't fallback to key events
} }
move_cursor_fallback(d);
}
/** Move one of the two side of a selection. If [sel_left] is true, the left
position is moved, otherwise the right position is moved. */
void move_cursor_sel(int d, boolean sel_left)
{
InputConnection conn = _recv.getCurrentInputConnection();
if (conn == null)
return;
ExtractedText et = get_cursor_pos(conn);
if (et != null && can_set_selection(conn))
{
int sel_start = et.selectionStart;
int sel_end = et.selectionEnd;
if (sel_left == (sel_start <= sel_end))
sel_start += d;
else
sel_end += d;
if (conn.setSelection(sel_start, sel_end))
return; // Fallback to sending key events if [setSelection] failed
}
move_cursor_fallback(d);
}
/** Returns whether the selection can be set using [conn.setSelection()].
This can happen on Termux or when system modifiers are activated for
example. */
boolean can_set_selection(InputConnection conn)
{
final int system_mods =
KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON | KeyEvent.META_META_ON;
return !_move_cursor_force_fallback && (_meta_state & system_mods) == 0;
}
void move_cursor_fallback(int d)
{
if (d < 0) if (d < 0)
send_key_down_up_repeat(KeyEvent.KEYCODE_DPAD_LEFT, -d); send_key_down_up_repeat(KeyEvent.KEYCODE_DPAD_LEFT, -d);
else else
@@ -358,76 +319,6 @@ public final class KeyEventHandler
send_key_down_up_repeat(KeyEvent.KEYCODE_DPAD_DOWN, d); send_key_down_up_repeat(KeyEvent.KEYCODE_DPAD_DOWN, d);
} }
void evaluate_macro(KeyValue[] keys)
{
if (keys.length == 0)
return;
// Ignore modifiers that are activated at the time the macro is evaluated
mods_changed(Pointers.Modifiers.EMPTY);
evaluate_macro_loop(keys, 0, Pointers.Modifiers.EMPTY, _autocap.pause());
}
/** Evaluate the macro asynchronously to make sure event are processed in the
right order. */
void evaluate_macro_loop(final KeyValue[] keys, int i, Pointers.Modifiers mods, final boolean autocap_paused)
{
boolean should_delay = false;
KeyValue kv = KeyModifier.modify(keys[i], mods);
if (kv != null)
{
if (kv.hasFlagsAny(KeyValue.FLAG_LATCH))
{
// Non-special latchable keys clear latched modifiers
if (!kv.hasFlagsAny(KeyValue.FLAG_SPECIAL))
mods = Pointers.Modifiers.EMPTY;
mods = mods.with_extra_mod(kv);
}
else
{
key_down(kv, false);
key_up(kv, mods);
mods = Pointers.Modifiers.EMPTY;
}
should_delay = wait_after_macro_key(kv);
}
i++;
if (i >= keys.length) // Stop looping
{
_autocap.unpause(autocap_paused);
}
else if (should_delay)
{
// Add a delay before sending the next key to avoid race conditions
// causing keys to be handled in the wrong order. Notably, KeyEvent keys
// handling is scheduled differently than the other edit functions.
final int i_ = i;
final Pointers.Modifiers mods_ = mods;
_recv.getHandler().postDelayed(new Runnable() {
public void run()
{
evaluate_macro_loop(keys, i_, mods_, autocap_paused);
}
}, 1000/30);
}
else
evaluate_macro_loop(keys, i, mods, autocap_paused);
}
boolean wait_after_macro_key(KeyValue kv)
{
switch (kv.getKind())
{
case Keyevent:
case Editing:
case Event:
return true;
case Slider:
return _move_cursor_force_fallback;
default:
return false;
}
}
/** Repeat calls to [send_key_down_up]. */ /** Repeat calls to [send_key_down_up]. */
void send_key_down_up_repeat(int event_code, int repeat) void send_key_down_up_repeat(int event_code, int repeat)
{ {
@@ -435,27 +326,12 @@ public final class KeyEventHandler
send_key_down_up(event_code); send_key_down_up(event_code);
} }
void cancel_selection()
{
InputConnection conn = _recv.getCurrentInputConnection();
if (conn == null)
return;
ExtractedText et = get_cursor_pos(conn);
if (et == null) return;
final int curs = et.selectionStart;
// Notify the receiver as Android's [onUpdateSelection] is not triggered.
if (conn.setSelection(curs, curs));
_recv.selection_state_changed(false);
}
public static interface IReceiver public static interface IReceiver
{ {
public void handle_event_key(KeyValue.Event ev); public void handle_event_key(KeyValue.Event ev);
public void set_shift_state(boolean state, boolean lock); public void set_shift_state(boolean state, boolean lock);
public void set_compose_pending(boolean pending); public void set_compose_pending(boolean pending);
public void selection_state_changed(boolean selection_is_ongoing);
public InputConnection getCurrentInputConnection(); public InputConnection getCurrentInputConnection();
public Handler getHandler();
} }
class Autocapitalisation_callback implements Autocapitalisation.Callback class Autocapitalisation_callback implements Autocapitalisation.Callback

View File

@@ -8,8 +8,8 @@ public final class KeyModifier
{ {
/** The optional modmap takes priority over modifiers usual behaviors. Set to /** The optional modmap takes priority over modifiers usual behaviors. Set to
[null] to disable. */ [null] to disable. */
private static Modmap _modmap = null; private static KeyboardData.Modmap _modmap = null;
public static void set_modmap(Modmap mm) public static void set_modmap(KeyboardData.Modmap mm)
{ {
_modmap = mm; _modmap = mm;
} }
@@ -36,7 +36,7 @@ public final class KeyModifier
case Modifier: case Modifier:
return modify(k, mod.getModifier()); return modify(k, mod.getModifier());
case Compose_pending: case Compose_pending:
return apply_compose_pending(mod.getPendingCompose(), k); return ComposeKey.apply(mod.getPendingCompose(), k);
case Hangul_initial: case Hangul_initial:
if (k.equals(mod)) // Allow typing the initial in letter form if (k.equals(mod)) // Allow typing the initial in letter form
return KeyValue.makeStringKey(k.getString(), KeyValue.FLAG_GREYED); return KeyValue.makeStringKey(k.getString(), KeyValue.FLAG_GREYED);
@@ -82,7 +82,6 @@ public final class KeyModifier
case HOOK_ABOVE: return apply_compose(k, ComposeKeyData.accent_hook_above); case HOOK_ABOVE: return apply_compose(k, ComposeKeyData.accent_hook_above);
case DOUBLE_GRAVE: return apply_compose(k, ComposeKeyData.accent_double_grave); case DOUBLE_GRAVE: return apply_compose(k, ComposeKeyData.accent_double_grave);
case ARROW_RIGHT: return apply_combining_char(k, "\u20D7"); case ARROW_RIGHT: return apply_combining_char(k, "\u20D7");
case SELECTION_MODE: return apply_selection_mode(k);
default: return k; default: return k;
} }
} }
@@ -123,44 +122,30 @@ public final class KeyModifier
} }
} }
/** Keys that do not match any sequence are greyed. */
private static KeyValue apply_compose_pending(int state, KeyValue kv)
{
switch (kv.getKind())
{
case Char:
case String:
KeyValue res = ComposeKey.apply(state, kv);
// Grey-out characters not part of any sequence.
if (res == null)
return kv.withFlags(kv.getFlags() | KeyValue.FLAG_GREYED);
return res;
/* Tapping compose again exits the pending sequence. */
case Compose_pending:
return KeyValue.getKeyByName("compose_cancel");
/* These keys are not greyed. */
case Event:
case Modifier:
return kv;
/* Other keys cannot be part of sequences. */
default:
return kv.withFlags(kv.getFlags() | KeyValue.FLAG_GREYED);
}
}
/** Apply the given compose state or fallback to the dead_char. */ /** Apply the given compose state or fallback to the dead_char. */
private static KeyValue apply_compose_or_dead_char(KeyValue k, int state, char dead_char) private static KeyValue apply_compose_or_dead_char(KeyValue k, int state, char dead_char)
{ {
KeyValue r = ComposeKey.apply(state, k); switch (k.getKind())
{
case Char:
char c = k.getChar();
KeyValue r = ComposeKey.apply(state, c);
if (r != null) if (r != null)
return r; return r;
}
return apply_dead_char(k, dead_char); return apply_dead_char(k, dead_char);
} }
private static KeyValue apply_compose(KeyValue k, int state) private static KeyValue apply_compose(KeyValue k, int state)
{ {
KeyValue r = ComposeKey.apply(state, k); switch (k.getKind())
return (r != null) ? r : k; {
case Char:
KeyValue r = ComposeKey.apply(state, k.getChar());
if (r != null)
return r;
}
return k;
} }
private static KeyValue apply_dead_char(KeyValue k, char dead_char) private static KeyValue apply_dead_char(KeyValue k, char dead_char)
@@ -190,23 +175,22 @@ public final class KeyModifier
{ {
if (_modmap != null) if (_modmap != null)
{ {
KeyValue mapped = _modmap.get(Modmap.M.Shift, k); KeyValue mapped = _modmap.shift.get(k);
if (mapped != null) if (mapped != null)
return mapped; return mapped;
} }
KeyValue r = ComposeKey.apply(ComposeKeyData.shift, k);
if (r != null)
return r;
switch (k.getKind()) switch (k.getKind())
{ {
case Char: case Char:
char kc = k.getChar(); char kc = k.getChar();
KeyValue r = ComposeKey.apply(ComposeKeyData.shift, kc);
if (r != null)
return r;
char c = Character.toUpperCase(kc); char c = Character.toUpperCase(kc);
return (kc == c) ? k : k.withChar(c); return (kc == c) ? k : k.withChar(c);
case String: case String:
String ks = k.getString(); String s = Utils.capitalize_string(k.getString());
String s = Utils.capitalize_string(ks); return KeyValue.makeStringKey(s, k.getFlags());
return s.equals(ks) ? k : KeyValue.makeStringKey(s, k.getFlags());
default: return k; default: return k;
} }
} }
@@ -215,7 +199,7 @@ public final class KeyModifier
{ {
if (_modmap != null) if (_modmap != null)
{ {
KeyValue mapped = _modmap.get(Modmap.M.Fn, k); KeyValue mapped = _modmap.fn.get(k);
if (mapped != null) if (mapped != null)
return mapped; return mapped;
} }
@@ -223,8 +207,7 @@ public final class KeyModifier
switch (k.getKind()) switch (k.getKind())
{ {
case Char: case Char:
case String: KeyValue r = ComposeKey.apply(ComposeKeyData.fn, k.getChar());
KeyValue r = ComposeKey.apply(ComposeKeyData.fn, k);
return (r != null) ? r : k; return (r != null) ? r : k;
case Keyevent: name = apply_fn_keyevent(k.getKeyevent()); break; case Keyevent: name = apply_fn_keyevent(k.getKeyevent()); break;
case Event: name = apply_fn_event(k.getEvent()); break; case Event: name = apply_fn_event(k.getEvent()); break;
@@ -289,7 +272,7 @@ public final class KeyModifier
{ {
if (_modmap != null) if (_modmap != null)
{ {
KeyValue mapped = _modmap.get(Modmap.M.Ctrl, k); KeyValue mapped = _modmap.ctrl.get(k);
// Do not return the modified character right away, first turn it into a // Do not return the modified character right away, first turn it into a
// key event. // key event.
if (mapped != null) if (mapped != null)
@@ -382,41 +365,6 @@ public final class KeyModifier
case SHIFT: name = "capslock"; break; case SHIFT: name = "capslock"; break;
} }
break; break;
case Keyevent:
switch (k.getKeyevent())
{
case KeyEvent.KEYCODE_DEL: name = "delete_word"; break;
case KeyEvent.KEYCODE_FORWARD_DEL: name = "forward_delete_word"; break;
}
break;
}
return (name == null) ? k : KeyValue.getKeyByName(name);
}
private static KeyValue apply_selection_mode(KeyValue k)
{
String name = null;
switch (k.getKind())
{
case Char:
switch (k.getChar())
{
case ' ': name = "selection_cancel"; break;
}
break;
case Slider:
switch (k.getSlider())
{
case Cursor_left: name = "selection_cursor_left"; break;
case Cursor_right: name = "selection_cursor_right"; break;
}
break;
case Keyevent:
switch (k.getKeyevent())
{
case KeyEvent.KEYCODE_ESCAPE: name = "selection_cancel"; break;
}
break;
} }
return (name == null) ? k : KeyValue.getKeyByName(name); return (name == null) ? k : KeyValue.getKeyByName(name);
} }

View File

@@ -59,7 +59,6 @@ public final class KeyValue implements Comparable<KeyValue>
BREVE, BREVE,
BAR, BAR,
FN, FN,
SELECTION_MODE,
} // Last is be applied first } // Last is be applied first
public static enum Editing public static enum Editing
@@ -76,9 +75,6 @@ public final class KeyValue implements Comparable<KeyValue>
SHARE, SHARE,
ASSIST, ASSIST,
AUTOFILL, AUTOFILL,
DELETE_WORD,
FORWARD_DELETE_WORD,
SELECTION_CANCEL,
} }
public static enum Placeholder public static enum Placeholder
@@ -99,7 +95,7 @@ public final class KeyValue implements Comparable<KeyValue>
Modifier, Editing, Placeholder, Modifier, Editing, Placeholder,
String, // [_payload] is also the string to output, value is unused. String, // [_payload] is also the string to output, value is unused.
Slider, // [_payload] is a [KeyValue.Slider], value is slider repeatition. Slider, // [_payload] is a [KeyValue.Slider], value is slider repeatition.
Macro, // [_payload] is a [KeyValue.Macro], value is unused. StringWithSymbol, // [_payload] is a [KeyValue.StringWithSymbol], value is unused.
} }
private static final int FLAGS_OFFSET = 20; private static final int FLAGS_OFFSET = 20;
@@ -109,8 +105,7 @@ public final class KeyValue implements Comparable<KeyValue>
public static final int FLAG_LATCH = (1 << FLAGS_OFFSET << 0); public static final int FLAG_LATCH = (1 << FLAGS_OFFSET << 0);
// Key can be locked by typing twice when enabled in settings // Key can be locked by typing twice when enabled in settings
public static final int FLAG_DOUBLE_TAP_LOCK = (1 << FLAGS_OFFSET << 1); public static final int FLAG_DOUBLE_TAP_LOCK = (1 << FLAGS_OFFSET << 1);
// Special keys are not repeated. // Special keys are not repeated and don't clear latched modifiers.
// Special latchable keys don't clear latched modifiers.
public static final int FLAG_SPECIAL = (1 << FLAGS_OFFSET << 2); public static final int FLAG_SPECIAL = (1 << FLAGS_OFFSET << 2);
// Whether the symbol should be greyed out. For example, keys that are not // Whether the symbol should be greyed out. For example, keys that are not
// part of the pending compose sequence. // part of the pending compose sequence.
@@ -228,17 +223,16 @@ public final class KeyValue implements Comparable<KeyValue>
return ((int)(short)(_code & VALUE_BITS)); return ((int)(short)(_code & VALUE_BITS));
} }
/** Defined only when [getKind() == Kind.Macro]. */ /** Defined only when [getKind() == Kind.StringWithSymbol]. */
public KeyValue[] getMacro() public String getStringWithSymbol()
{ {
return ((Macro)_payload).keys; return ((StringWithSymbol)_payload).str;
} }
/* Update the char and the symbol. */ /* Update the char and the symbol. */
public KeyValue withChar(char c) public KeyValue withChar(char c)
{ {
return new KeyValue(String.valueOf(c), Kind.Char, c, return new KeyValue(String.valueOf(c), Kind.Char, c, getFlags());
getFlags() & ~(FLAG_KEY_FONT | FLAG_SMALLER_FONT));
} }
public KeyValue withKeyevent(int code) public KeyValue withKeyevent(int code)
@@ -248,31 +242,7 @@ public final class KeyValue implements Comparable<KeyValue>
public KeyValue withFlags(int f) public KeyValue withFlags(int f)
{ {
return new KeyValue(_payload, _code, _code, f); return new KeyValue(_payload, (_code & KIND_BITS), (_code & VALUE_BITS), f);
}
public KeyValue withSymbol(String symbol)
{
int flags = getFlags() & ~(FLAG_KEY_FONT | FLAG_SMALLER_FONT);
switch (getKind())
{
case Char:
case Keyevent:
case Event:
case Compose_pending:
case Hangul_initial:
case Hangul_medial:
case Modifier:
case Editing:
case Placeholder:
if (symbol.length() > 1)
flags |= FLAG_SMALLER_FONT;
return new KeyValue(symbol, _code, _code, flags);
case Macro:
return makeMacro(symbol, getMacro(), flags);
default:
return makeMacro(symbol, new KeyValue[]{ this }, flags);
}
} }
@Override @Override
@@ -316,6 +286,7 @@ public final class KeyValue implements Comparable<KeyValue>
return "[KeyValue " + getKind().toString() + "+" + getFlags() + "+" + value + " \"" + getString() + "\"]"; return "[KeyValue " + getKind().toString() + "+" + getFlags() + "+" + value + " \"" + getString() + "\"]";
} }
/** [value] is an unsigned integer. */
private KeyValue(Comparable p, int kind, int value, int flags) private KeyValue(Comparable p, int kind, int value, int flags)
{ {
if (p == null) if (p == null)
@@ -483,11 +454,10 @@ public final class KeyValue implements Comparable<KeyValue>
return new KeyValue(str, Kind.String, 0, flags | FLAG_SMALLER_FONT); return new KeyValue(str, Kind.String, 0, flags | FLAG_SMALLER_FONT);
} }
public static KeyValue makeMacro(String symbol, KeyValue[] keys, int flags) public static KeyValue makeStringKeyWithSymbol(String str, String symbol, int flags)
{ {
if (symbol.length() > 1) return new KeyValue(new StringWithSymbol(str, symbol),
flags |= FLAG_SMALLER_FONT; Kind.StringWithSymbol, 0, flags);
return new KeyValue(new Macro(keys, symbol), Kind.Macro, 0, flags);
} }
/** Make a modifier key for passing to [KeyModifier]. */ /** Make a modifier key for passing to [KeyModifier]. */
@@ -496,24 +466,25 @@ public final class KeyValue implements Comparable<KeyValue>
return new KeyValue("", Kind.Modifier, mod.ordinal(), 0); return new KeyValue("", Kind.Modifier, mod.ordinal(), 0);
} }
/** Return a key by its name. If the given name doesn't correspond to any public static KeyValue parseKeyDefinition(String str)
special key, it is parsed with [KeyValueParser]. */
public static KeyValue getKeyByName(String name)
{ {
KeyValue k = getSpecialKeyByName(name); if (str.length() < 2 || str.charAt(0) != ':')
if (k != null) return makeStringKey(str);
return k;
try try
{ {
return KeyValueParser.parse(name); return KeyValueParser.parse(str);
} }
catch (KeyValueParser.ParseError _e) catch (KeyValueParser.ParseError _e)
{ {
return makeStringKey(name); return makeStringKey(str);
} }
} }
public static KeyValue getSpecialKeyByName(String name) /**
* Return a key by its name. If the given name doesn't correspond to a key
* defined in this function, it is passed to [parseStringKey] as a fallback.
*/
public static KeyValue getKeyByName(String name)
{ {
switch (name) switch (name)
{ {
@@ -711,15 +682,10 @@ public final class KeyValue implements Comparable<KeyValue>
case "pasteAsPlainText": return editingKey(0xE035, Editing.PASTE_PLAIN); case "pasteAsPlainText": return editingKey(0xE035, Editing.PASTE_PLAIN);
case "undo": return editingKey(0xE036, Editing.UNDO); case "undo": return editingKey(0xE036, Editing.UNDO);
case "redo": return editingKey(0xE037, Editing.REDO); case "redo": return editingKey(0xE037, Editing.REDO);
case "delete_word": return editingKey(0xE01B, Editing.DELETE_WORD);
case "forward_delete_word": return editingKey(0xE01C, Editing.FORWARD_DELETE_WORD);
case "cursor_left": return sliderKey(Slider.Cursor_left, 1); case "cursor_left": return sliderKey(Slider.Cursor_left, 1);
case "cursor_right": return sliderKey(Slider.Cursor_right, 1); case "cursor_right": return sliderKey(Slider.Cursor_right, 1);
case "cursor_up": return sliderKey(Slider.Cursor_up, 1); case "cursor_up": return sliderKey(Slider.Cursor_up, 1);
case "cursor_down": return sliderKey(Slider.Cursor_down, 1); case "cursor_down": return sliderKey(Slider.Cursor_down, 1);
case "selection_cancel": return editingKey("Esc", Editing.SELECTION_CANCEL, FLAG_SMALLER_FONT);
case "selection_cursor_left": return sliderKey(Slider.Selection_cursor_left, -1); // Move the left side of the selection
case "selection_cursor_right": return sliderKey(Slider.Selection_cursor_right, 1);
// These keys are not used // These keys are not used
case "replaceText": return editingKey("repl", Editing.REPLACE); case "replaceText": return editingKey("repl", Editing.REPLACE);
case "textAssist": return editingKey(0xE038, Editing.ASSIST); case "textAssist": return editingKey(0xE038, Editing.ASSIST);
@@ -769,42 +735,8 @@ public final class KeyValue implements Comparable<KeyValue>
case "": case "": case "": case "":
return makeStringKey(name, FLAG_SMALLER_FONT); return makeStringKey(name, FLAG_SMALLER_FONT);
/* Sinhala letters to reduced size */ /* The key is not one of the special ones. */
case "": case "": case "": case "": case "": default: return parseKeyDefinition(name);
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "": case "": case "":
/* Astrological numbers */
case "": case "": case "": case "": case "":
case "": case "": case "": case "": case "":
case "": case "":
/* Diacritics */
case "\u0d81": case "\u0d82": case "\u0d83": case "\u0dca":
case "\u0dcf": case "\u0dd0": case "\u0dd1": case "\u0dd2":
case "\u0dd3": case "\u0dd4": case "\u0dd6": case "\u0dd8":
case "\u0dd9": case "\u0dda": case "\u0ddb": case "\u0ddc":
case "\u0ddd": case "\u0dde": case "\u0ddf":
/* Archaic digits */
case "𑇡": case "𑇢": case "𑇣": case "𑇤": case "𑇥":
case "𑇦": case "𑇧": case "𑇨": case "𑇩": case "𑇪":
case "𑇫": case "𑇬": case "𑇭": case "𑇮": case "𑇯":
case "𑇰": case "𑇱": case "𑇲": case "𑇳": case "𑇴":
/* Exta */
case "": case "": // Rupee is not exclusively Sinhala sign
return makeStringKey(name, FLAG_SMALLER_FONT);
/* Internal keys */
case "selection_mode": return makeInternalModifier(Modifier.SELECTION_MODE);
default: return null;
} }
} }
@@ -815,14 +747,35 @@ public final class KeyValue implements Comparable<KeyValue>
throw new RuntimeException("Assertion failure"); throw new RuntimeException("Assertion failure");
} }
public static final class StringWithSymbol implements Comparable<StringWithSymbol>
{
public final String str;
final String _symbol;
public StringWithSymbol(String _str, String _sym)
{
str = _str;
_symbol = _sym;
}
@Override
public String toString() { return _symbol; }
@Override
public int compareTo(StringWithSymbol snd)
{
int d = str.compareTo(snd.str);
if (d != 0) return d;
return _symbol.compareTo(snd._symbol);
}
};
public static enum Slider public static enum Slider
{ {
Cursor_left(0xE008), Cursor_left(0xE008),
Cursor_right(0xE006), Cursor_right(0xE006),
Cursor_up(0xE005), Cursor_up(0xE005),
Cursor_down(0xE007), Cursor_down(0xE007);
Selection_cursor_left(0xE008),
Selection_cursor_right(0xE006);
final String symbol; final String symbol;
@@ -834,31 +787,4 @@ public final class KeyValue implements Comparable<KeyValue>
@Override @Override
public String toString() { return symbol; } public String toString() { return symbol; }
}; };
public static final class Macro implements Comparable<Macro>
{
public final KeyValue[] keys;
private final String _symbol;
public Macro(KeyValue[] keys_, String sym_)
{
keys = keys_;
_symbol = sym_;
}
public String toString() { return _symbol; }
@Override
public int compareTo(Macro snd)
{
int d = keys.length - snd.keys.length;
if (d != 0) return d;
for (int i = 0; i < keys.length; i++)
{
d = keys[i].compareTo(snd.keys[i]);
if (d != 0) return d;
}
return _symbol.compareTo(snd._symbol);
}
};
} }

View File

@@ -1,22 +1,14 @@
package juloo.keyboard2; package juloo.keyboard2;
import java.util.ArrayList;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
Parse a key definition. The syntax for a key definition is: Parse a key definition. The syntax for a key definition is:
- [(symbol):(key_action)]
- [:(kind) (attributes):(payload)]. - [:(kind) (attributes):(payload)].
- If [str] doesn't start with a [:] character, it is interpreted as an - If [str] doesn't start with a [:] character, it is interpreted as an
arbitrary string key. arbitrary string key.
[key_action] is:
- ['Arbitrary string']
- [(key_action),(key_action),...]
- [keyevent:(code)]
- [(key_name)]
For the different kinds and attributes, see doc/Possible-key-values.md. For the different kinds and attributes, see doc/Possible-key-values.md.
Examples: Examples:
@@ -25,118 +17,6 @@ Examples:
*/ */
public final class KeyValueParser public final class KeyValueParser
{
static Pattern KEYDEF_TOKEN;
static Pattern QUOTED_PAT;
static Pattern WORD_PAT;
static public KeyValue parse(String input) throws ParseError
{
int symbol_ends = 0;
final int input_len = input.length();
while (symbol_ends < input_len && input.charAt(symbol_ends) != ':')
symbol_ends++;
if (symbol_ends == 0) // Old syntax
return Starting_with_colon.parse(input);
if (symbol_ends == input_len) // String key
return KeyValue.makeStringKey(input);
String symbol = input.substring(0, symbol_ends);
init();
Matcher m = KEYDEF_TOKEN.matcher(input);
m.region(symbol_ends + 1, input_len);
KeyValue first_key = parse_key_def(m);
if (!parse_comma(m)) // Input is a single key def with a specified symbol
return first_key.withSymbol(symbol);
// Input is a macro
ArrayList<KeyValue> keydefs = new ArrayList<KeyValue>();
keydefs.add(first_key);
do { keydefs.add(parse_key_def(m)); }
while (parse_comma(m));
return KeyValue.makeMacro(symbol, keydefs.toArray(new KeyValue[]{}), 0);
}
static void init()
{
if (KEYDEF_TOKEN != null)
return;
KEYDEF_TOKEN = Pattern.compile("'|,|keyevent:|(?:[^\\\\',]+|\\\\.)+");
QUOTED_PAT = Pattern.compile("((?:[^'\\\\]+|\\\\')*)'");
WORD_PAT = Pattern.compile("[a-zA-Z0-9_]+|.");
}
static KeyValue key_by_name_or_str(String str)
{
KeyValue k = KeyValue.getSpecialKeyByName(str);
if (k != null)
return k;
return KeyValue.makeStringKey(str);
}
static KeyValue parse_key_def(Matcher m) throws ParseError
{
if (!match(m, KEYDEF_TOKEN))
parseError("Expected key definition", m);
String token = m.group(0);
switch (token)
{
case "'": return parse_string_keydef(m);
case ",": parseError("Unexpected comma", m); return null;
case "keyevent:": return parse_keyevent_keydef(m);
default: return key_by_name_or_str(remove_escaping(token));
}
}
static KeyValue parse_string_keydef(Matcher m) throws ParseError
{
if (!match(m, QUOTED_PAT))
parseError("Unterminated quoted string", m);
return KeyValue.makeStringKey(remove_escaping(m.group(1)));
}
static KeyValue parse_keyevent_keydef(Matcher m) throws ParseError
{
if (!match(m, WORD_PAT))
parseError("Expected keyevent code", m);
int eventcode = 0;
try { eventcode = Integer.parseInt(m.group(0)); }
catch (Exception _e)
{ parseError("Expected an integer payload", m); }
return KeyValue.keyeventKey("", eventcode, 0);
}
/** Returns [true] if the next token is a comma, [false] if it is the end of the input. Throws an error otherwise. */
static boolean parse_comma(Matcher m) throws ParseError
{
if (!match(m, KEYDEF_TOKEN))
return false;
String token = m.group(0);
if (!token.equals(","))
parseError("Expected comma instead of '"+ token + "'", m);
return true;
}
static String remove_escaping(String s)
{
if (!s.contains("\\"))
return s;
StringBuilder out = new StringBuilder(s.length());
final int len = s.length();
int prev = 0, i = 0;
for (; i < len; i++)
if (s.charAt(i) == '\\')
{
out.append(s, prev, i);
prev = i + 1;
}
out.append(s, prev, i);
return out.toString();
}
/**
Parse a key definition starting with a [:]. This is the old syntax and is
kept for compatibility.
*/
final static class Starting_with_colon
{ {
static Pattern START_PAT; static Pattern START_PAT;
static Pattern ATTR_PAT; static Pattern ATTR_PAT;
@@ -184,7 +64,7 @@ public final class KeyValueParser
payload = parseSingleQuotedString(m); payload = parseSingleQuotedString(m);
if (symbol == null) if (symbol == null)
return KeyValue.makeStringKey(payload, flags); return KeyValue.makeStringKey(payload, flags);
return KeyValue.makeStringKey(payload, flags).withSymbol(symbol); return KeyValue.makeStringKeyWithSymbol(payload, symbol, flags);
case "char": case "char":
payload = parsePayloadWord(m); payload = parsePayloadWord(m);
@@ -254,14 +134,6 @@ public final class KeyValueParser
PAYLOAD_START_PAT = Pattern.compile("\\s*:"); PAYLOAD_START_PAT = Pattern.compile("\\s*:");
WORD_PAT = Pattern.compile("[a-zA-Z0-9_]*"); WORD_PAT = Pattern.compile("[a-zA-Z0-9_]*");
} }
}
static boolean match(Matcher m, Pattern pat)
{
try { m.region(m.end(), m.regionEnd()); } catch (Exception _e) {}
m.usePattern(pat);
return m.lookingAt();
}
static void parseError(String msg, Matcher m) throws ParseError static void parseError(String msg, Matcher m) throws ParseError
{ {
@@ -273,7 +145,8 @@ public final class KeyValueParser
StringBuilder msg_ = new StringBuilder("Syntax error"); StringBuilder msg_ = new StringBuilder("Syntax error");
try try
{ {
msg_.append(" at token '").append(m.group(0)).append("'"); char c = m.group(0).charAt(0);
msg_.append(" at character '").append(c).append("'");
} catch (IllegalStateException _e) {} } catch (IllegalStateException _e) {}
msg_.append(" at position "); msg_.append(" at position ");
msg_.append(i); msg_.append(i);

View File

@@ -6,7 +6,6 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.os.Build.VERSION; import android.os.Build.VERSION;
import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.text.InputType; import android.text.InputType;
import android.util.Log; import android.util.Log;
@@ -39,12 +38,9 @@ public class Keyboard2 extends InputMethodService
private ViewGroup _emojiPane = null; private ViewGroup _emojiPane = null;
private ViewGroup _clipboard_pane = null; private ViewGroup _clipboard_pane = null;
public int actionId; // Action performed by the Action key. public int actionId; // Action performed by the Action key.
private Handler _handler;
private Config _config; private Config _config;
private FoldStateTracker _foldStateTracker;
/** Layout currently visible before it has been modified. */ /** Layout currently visible before it has been modified. */
KeyboardData current_layout_unmodified() KeyboardData current_layout_unmodified()
{ {
@@ -111,24 +107,14 @@ public class Keyboard2 extends InputMethodService
{ {
super.onCreate(); super.onCreate();
SharedPreferences prefs = DirectBootAwarePreferences.get_shared_preferences(this); SharedPreferences prefs = DirectBootAwarePreferences.get_shared_preferences(this);
_handler = new Handler(getMainLooper()); _keyeventhandler = new KeyEventHandler(getMainLooper(), this.new Receiver());
_keyeventhandler = new KeyEventHandler(this.new Receiver()); Config.initGlobalConfig(prefs, getResources(), _keyeventhandler);
_foldStateTracker = new FoldStateTracker(this);
Config.initGlobalConfig(prefs, getResources(), _keyeventhandler, _foldStateTracker.isUnfolded());
prefs.registerOnSharedPreferenceChangeListener(this); prefs.registerOnSharedPreferenceChangeListener(this);
_config = Config.globalConfig(); _config = Config.globalConfig();
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard); _keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_keyboardView.reset(); _keyboardView.reset();
Logs.set_debug_logs(getResources().getBoolean(R.bool.debug_logs)); Logs.set_debug_logs(getResources().getBoolean(R.bool.debug_logs));
ClipboardHistoryService.on_startup(this, _keyeventhandler); ClipboardHistoryService.on_startup(this, _keyeventhandler);
_foldStateTracker.setChangedCallback(() -> { refresh_config(); });
}
@Override
public void onDestroy() {
super.onDestroy();
_foldStateTracker.close();
} }
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm) private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
@@ -245,7 +231,7 @@ public class Keyboard2 extends InputMethodService
private void refresh_config() private void refresh_config()
{ {
int prev_theme = _config.theme; int prev_theme = _config.theme;
_config.refresh(getResources(), _foldStateTracker.isUnfolded()); _config.refresh(getResources());
refreshSubtypeImm(); refreshSubtypeImm();
// Refreshing the theme config requires re-creating the views // Refreshing the theme config requires re-creating the views
if (prev_theme != _config.theme) if (prev_theme != _config.theme)
@@ -373,8 +359,6 @@ public class Keyboard2 extends InputMethodService
{ {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd); super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd);
_keyeventhandler.selection_updated(oldSelStart, newSelStart); _keyeventhandler.selection_updated(oldSelStart, newSelStart);
if ((oldSelStart == oldSelEnd) != (newSelStart == newSelEnd))
_keyboardView.set_selection_state(newSelStart != newSelEnd);
} }
@Override @Override
@@ -493,20 +477,10 @@ public class Keyboard2 extends InputMethodService
_keyboardView.set_compose_pending(pending); _keyboardView.set_compose_pending(pending);
} }
public void selection_state_changed(boolean selection_is_ongoing)
{
_keyboardView.set_selection_state(selection_is_ongoing);
}
public InputConnection getCurrentInputConnection() public InputConnection getCurrentInputConnection()
{ {
return Keyboard2.this.getCurrentInputConnection(); return Keyboard2.this.getCurrentInputConnection();
} }
public Handler getHandler()
{
return _handler;
}
} }
private IBinder getConnectionToken() private IBinder getConnectionToken()

View File

@@ -42,8 +42,6 @@ public class Keyboard2View extends View
private Config _config; private Config _config;
private float _keyWidth; private float _keyWidth;
private float _mainLabelSize;
private float _subLabelSize;
private float _marginRight; private float _marginRight;
private float _marginLeft; private float _marginLeft;
private float _marginBottom; private float _marginBottom;
@@ -141,13 +139,6 @@ public class Keyboard2View extends View
set_fake_ptr_latched(_compose_key, _compose_kv, pending, false); set_fake_ptr_latched(_compose_key, _compose_kv, pending, false);
} }
/** Called from [Keybard2.onUpdateSelection]. */
public void set_selection_state(boolean selection_state)
{
set_fake_ptr_latched(KeyboardData.Key.EMPTY,
KeyValue.getKeyByName("selection_mode"), selection_state, true);
}
public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods) public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods)
{ {
return KeyModifier.modify(k, mods); return KeyModifier.modify(k, mods);
@@ -229,7 +220,7 @@ public class Keyboard2View extends View
return null; return null;
for (KeyboardData.Row row : _keyboard.rows) for (KeyboardData.Row row : _keyboard.rows)
{ {
y += (row.shift + row.height) * _tc.row_height; y += (row.shift + row.height) * _config.keyHeight;
if (ty < y) if (ty < y)
return row; return row;
} }
@@ -305,25 +296,15 @@ public class Keyboard2View extends View
DisplayMetrics dm = getContext().getResources().getDisplayMetrics(); DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
width = dm.widthPixels; width = dm.widthPixels;
} }
int height =
(int)(_config.keyHeight * _keyboard.keysHeight
+ _config.marginTop + _marginBottom);
setMeasuredDimension(width, height);
_marginLeft = Math.max(_config.horizontal_margin, insets_left); _marginLeft = Math.max(_config.horizontal_margin, insets_left);
_marginRight = Math.max(_config.horizontal_margin, insets_right); _marginRight = Math.max(_config.horizontal_margin, insets_right);
_marginBottom = _config.margin_bottom + insets_bottom; _marginBottom = _config.margin_bottom + insets_bottom;
_keyWidth = (width - _marginLeft - _marginRight) / _keyboard.keysWidth; _keyWidth = (width - _marginLeft - _marginRight) / _keyboard.keysWidth;
_tc = new Theme.Computed(_theme, _config, _keyWidth, _keyboard); _tc = new Theme.Computed(_theme, _config, _keyWidth);
// Compute the size of labels based on the width or the height of keys. The
// margin around keys is taken into account. Keys normal aspect ratio is
// assumed to be 3/2. It's generally more, the width computation is useful
// when the keyboard is unusually high.
float labelBaseSize = Math.min(
_tc.row_height - _tc.vertical_margin,
_keyWidth * 3/2 - _tc.horizontal_margin
) * _config.characterSize;
_mainLabelSize = labelBaseSize * _config.labelTextSize;
_subLabelSize = labelBaseSize * _config.sublabelTextSize;
int height =
(int)(_tc.row_height * _keyboard.keysHeight
+ _config.marginTop + _marginBottom);
setMeasuredDimension(width, height);
} }
@Override @Override
@@ -364,15 +345,25 @@ public class Keyboard2View extends View
float y = _tc.margin_top; float y = _tc.margin_top;
for (KeyboardData.Row row : _keyboard.rows) for (KeyboardData.Row row : _keyboard.rows)
{ {
y += row.shift * _tc.row_height; y += row.shift * _config.keyHeight;
float x = _marginLeft + _tc.margin_left; float x = _marginLeft + _tc.margin_left;
float keyH = row.height * _tc.row_height - _tc.vertical_margin; float keyH = row.height * _config.keyHeight - _tc.vertical_margin;
for (KeyboardData.Key k : row.keys) for (KeyboardData.Key k : row.keys)
{ {
x += k.shift * _keyWidth; x += k.shift * _keyWidth;
float keyW = _keyWidth * k.width - _tc.horizontal_margin; float keyW = _keyWidth * k.width - _tc.horizontal_margin;
boolean isKeyDown = _pointers.isKeyDown(k); boolean isKeyDown = _pointers.isKeyDown(k);
Theme.Computed.Key tc_key = isKeyDown ? _tc.key_activated : _tc.key; Theme.Computed.Key tc_key;
if (isKeyDown)
tc_key = _tc.key_activated;
else
switch (k.role)
{
case Action: tc_key = _tc.key_action; break;
case Space_bar: tc_key = _tc.key_space_bar; break;
default:
case Normal: tc_key = _tc.key; break;
}
drawKeyFrame(canvas, x, y, keyW, keyH, tc_key); drawKeyFrame(canvas, x, y, keyW, keyH, tc_key);
if (k.keys[0] != null) if (k.keys[0] != null)
drawLabel(canvas, k.keys[0], keyW / 2f + x, y, keyH, isKeyDown, tc_key); drawLabel(canvas, k.keys[0], keyW / 2f + x, y, keyH, isKeyDown, tc_key);
@@ -384,7 +375,7 @@ public class Keyboard2View extends View
drawIndication(canvas, k, x, y, keyW, keyH, _tc); drawIndication(canvas, k, x, y, keyW, keyH, _tc);
x += _keyWidth * k.width; x += _keyWidth * k.width;
} }
y += row.height * _tc.row_height; y += row.height * _config.keyHeight;
} }
} }
@@ -452,8 +443,9 @@ public class Keyboard2View extends View
kv = modifyKey(kv, _mods); kv = modifyKey(kv, _mods);
if (kv == null) if (kv == null)
return; return;
float textSize = scaleTextSize(kv, true); float textSize = scaleTextSize(kv, _config.labelTextSize, keyH);
Paint p = tc.label_paint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), labelColor(kv, isKeyDown, false), textSize); Paint p = tc.label_paint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), textSize);
p.setColor(labelColor(kv, isKeyDown, false));
canvas.drawText(kv.getString(), x, (keyH - p.ascent() - p.descent()) / 2f + y, p); canvas.drawText(kv.getString(), x, (keyH - p.ascent() - p.descent()) / 2f + y, p);
} }
@@ -466,8 +458,9 @@ public class Keyboard2View extends View
kv = modifyKey(kv, _mods); kv = modifyKey(kv, _mods);
if (kv == null) if (kv == null)
return; return;
float textSize = scaleTextSize(kv, false); float textSize = scaleTextSize(kv, _config.sublabelTextSize, keyH);
Paint p = tc.sublabel_paint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), labelColor(kv, isKeyDown, true), textSize, a); Paint p = tc.sublabel_paint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), textSize, a);
p.setColor(labelColor(kv, isKeyDown, true));
float subPadding = _config.keyPadding; float subPadding = _config.keyPadding;
if (v == Vertical.CENTER) if (v == Vertical.CENTER)
y += (keyH - p.ascent() - p.descent()) / 2f; y += (keyH - p.ascent() - p.descent()) / 2f;
@@ -491,15 +484,14 @@ public class Keyboard2View extends View
if (k.indication == null || k.indication.equals("")) if (k.indication == null || k.indication.equals(""))
return; return;
Paint p = tc.indication_paint; Paint p = tc.indication_paint;
p.setTextSize(_subLabelSize); p.setTextSize(keyH * _config.sublabelTextSize * _config.characterSize);
canvas.drawText(k.indication, 0, k.indication.length(), canvas.drawText(k.indication, 0, k.indication.length(),
x + keyW / 2f, (keyH - p.ascent() - p.descent()) * 4/5 + y, p); x + keyW / 2f, (keyH - p.ascent() - p.descent()) * 4/5 + y, p);
} }
private float scaleTextSize(KeyValue k, boolean main_label) private float scaleTextSize(KeyValue k, float rel_size, float keyH)
{ {
float smaller_font = k.hasFlagsAny(KeyValue.FLAG_SMALLER_FONT) ? 0.75f : 1.f; float smaller_font = k.hasFlagsAny(KeyValue.FLAG_SMALLER_FONT) ? 0.75f : 1.f;
float label_size = main_label ? _mainLabelSize : _subLabelSize; return keyH * rel_size * smaller_font * _config.characterSize;
return label_size * smaller_font;
} }
} }

View File

@@ -177,9 +177,14 @@ public final class KeyboardData
private static Map<Integer, KeyboardData> _layoutCache = new HashMap<Integer, KeyboardData>(); private static Map<Integer, KeyboardData> _layoutCache = new HashMap<Integer, KeyboardData>();
public static Row load_row(Resources res, int res_id) throws Exception public static Row load_bottom_row(Resources res) throws Exception
{ {
return parse_row(res.getXml(res_id)); return parse_row(res.getXml(R.xml.bottom_row));
}
public static Row load_number_row(Resources res) throws Exception
{
return parse_row(res.getXml(R.xml.number_row));
} }
public static KeyboardData load_num_pad(Resources res) throws Exception public static KeyboardData load_num_pad(Resources res) throws Exception
@@ -260,7 +265,7 @@ public final class KeyboardData
case "modmap": case "modmap":
if (modmap != null) if (modmap != null)
throw error(parser, "Multiple '<modmap>' are not allowed"); throw error(parser, "Multiple '<modmap>' are not allowed");
modmap = parse_modmap(parser); modmap = Modmap.parse(parser);
break; break;
default: default:
throw error(parser, "Expecting tag <row>, got <" + parser.getName() + ">"); throw error(parser, "Expecting tag <row>, got <" + parser.getName() + ">");
@@ -336,13 +341,9 @@ public final class KeyboardData
int status; int status;
float h = attribute_float(parser, "height", 1f); float h = attribute_float(parser, "height", 1f);
float shift = attribute_float(parser, "shift", 0f); float shift = attribute_float(parser, "shift", 0f);
float scale = attribute_float(parser, "scale", 0f);
while (expect_tag(parser, "key")) while (expect_tag(parser, "key"))
keys.add(Key.parse(parser)); keys.add(Key.parse(parser));
Row row = new Row(keys, h, shift); return new Row(keys, h, shift);
if (scale > 0f)
row = row.updateWidth(scale);
return row;
} }
public Row copy() public Row copy()
@@ -406,12 +407,14 @@ public final class KeyboardData
public final float shift; public final float shift;
/** String printed on the keys. It has no other effect. */ /** String printed on the keys. It has no other effect. */
public final String indication; public final String indication;
/** Keys are rendered differently according to their role. */
public final Role role;
/** Whether a key was declared with the 'loc' prefix. */ /** Whether a key was declared with the 'loc' prefix. */
public static final int F_LOC = 1; public static final int F_LOC = 1;
public static final int ALL_FLAGS = F_LOC; public static final int ALL_FLAGS = F_LOC;
protected Key(KeyValue[] ks, KeyValue antic, int f, float w, float s, String i) protected Key(KeyValue[] ks, KeyValue antic, int f, float w, float s, String i, Role role_)
{ {
keys = ks; keys = ks;
anticircle = antic; anticircle = antic;
@@ -419,10 +422,9 @@ public final class KeyboardData
width = Math.max(w, 0f); width = Math.max(w, 0f);
shift = Math.max(s, 0f); shift = Math.max(s, 0f);
indication = i; indication = i;
role = role_;
} }
static final Key EMPTY = new Key(new KeyValue[9], null, 0, 1.f, 1.f, null);
/** Read a key value attribute that have a synonym. Having both synonyms /** Read a key value attribute that have a synonym. Having both synonyms
present at the same time is an error. present at the same time is an error.
Returns [null] if the attributes are not present. */ Returns [null] if the attributes are not present. */
@@ -489,9 +491,11 @@ public final class KeyboardData
float width = attribute_float(parser, "width", 1f); float width = attribute_float(parser, "width", 1f);
float shift = attribute_float(parser, "shift", 0.f); float shift = attribute_float(parser, "shift", 0.f);
String indication = parser.getAttributeValue(null, "indication"); String indication = parser.getAttributeValue(null, "indication");
String role_str = parser.getAttributeValue(null, "role");
Role role = (role_str == null) ? Role.Normal : Role.parse(role_str);
while (parser.next() != XmlPullParser.END_TAG) while (parser.next() != XmlPullParser.END_TAG)
continue; continue;
return new Key(ks, anticircle, keysflags, width, shift, indication); return new Key(ks, anticircle, keysflags, width, shift, indication, role);
} }
/** Whether key at [index] as [flag]. */ /** Whether key at [index] as [flag]. */
@@ -503,7 +507,7 @@ public final class KeyboardData
/** New key with the width multiplied by 's'. */ /** New key with the width multiplied by 's'. */
public Key scaleWidth(float s) public Key scaleWidth(float s)
{ {
return new Key(keys, anticircle, keysflags, width * s, shift, indication); return new Key(keys, anticircle, keysflags, width * s, shift, indication, role);
} }
public void getKeys(Map<KeyValue, KeyPos> dst, int row, int col) public void getKeys(Map<KeyValue, KeyPos> dst, int row, int col)
@@ -524,12 +528,12 @@ public final class KeyboardData
for (int j = 0; j < keys.length; j++) ks[j] = keys[j]; for (int j = 0; j < keys.length; j++) ks[j] = keys[j];
ks[i] = kv; ks[i] = kv;
int flags = (keysflags & ~(ALL_FLAGS << i)); int flags = (keysflags & ~(ALL_FLAGS << i));
return new Key(ks, anticircle, flags, width, shift, indication); return new Key(ks, anticircle, flags, width, shift, indication, role);
} }
public Key withShift(float s) public Key withShift(float s)
{ {
return new Key(keys, anticircle, keysflags, width, s, indication); return new Key(keys, anticircle, keysflags, width, s, indication, role);
} }
public boolean hasValue(KeyValue kv) public boolean hasValue(KeyValue kv)
@@ -539,6 +543,23 @@ public final class KeyboardData
return true; return true;
return false; return false;
} }
public static enum Role
{
Normal,
Action, // Generally Shift, Delete and keys on the bottom row
Space_bar;
public static Role parse(String str)
{
switch (str)
{
case "action": return Action;
case "space_bar": return Space_bar;
default: case "normal": return Normal;
}
}
}
} }
// Not using Function<KeyValue, KeyValue> to keep compatibility with Android 6. // Not using Function<KeyValue, KeyValue> to keep compatibility with Android 6.
@@ -555,38 +576,57 @@ public final class KeyboardData
for (int i = 0; i < ks.length; i++) for (int i = 0; i < ks.length; i++)
if (k.keys[i] != null) if (k.keys[i] != null)
ks[i] = apply(k.keys[i], k.keyHasFlag(i, Key.F_LOC)); ks[i] = apply(k.keys[i], k.keyHasFlag(i, Key.F_LOC));
return new Key(ks, k.anticircle, k.keysflags, k.width, k.shift, k.indication); return new Key(ks, k.anticircle, k.keysflags, k.width, k.shift, k.indication, k.role);
} }
} }
public static Modmap parse_modmap(XmlPullParser parser) throws Exception public static class Modmap
{ {
Modmap mm = new Modmap(); public final Map<KeyValue, KeyValue> shift;
public final Map<KeyValue, KeyValue> fn;
public final Map<KeyValue, KeyValue> ctrl;
public Modmap(Map<KeyValue, KeyValue> s, Map<KeyValue, KeyValue> f, Map<KeyValue, KeyValue> c)
{
shift = s;
fn = f;
ctrl = c;
}
public static Modmap parse(XmlPullParser parser) throws Exception
{
HashMap<KeyValue, KeyValue> shift = new HashMap<KeyValue, KeyValue>();
HashMap<KeyValue, KeyValue> fn = new HashMap<KeyValue, KeyValue>();
HashMap<KeyValue, KeyValue> ctrl = new HashMap<KeyValue, KeyValue>();
while (next_tag(parser)) while (next_tag(parser))
{ {
Modmap.M m;
switch (parser.getName()) switch (parser.getName())
{ {
case "shift": m = Modmap.M.Shift; break; case "shift":
case "fn": m = Modmap.M.Fn; break; parse_mapping(parser, shift);
case "ctrl": m = Modmap.M.Ctrl; break; break;
case "fn":
parse_mapping(parser, fn);
break;
case "ctrl":
parse_mapping(parser, ctrl);
break;
default: default:
throw error(parser, "Expecting tag <shift> or <fn>, got <" + throw error(parser, "Expecting tag <shift> or <fn>, got <" + parser.getName() + ">");
parser.getName() + ">");
} }
parse_modmap_mapping(parser, mm, m);
}
return mm;
} }
private static void parse_modmap_mapping(XmlPullParser parser, Modmap mm, return new Modmap(shift, fn, ctrl);
Modmap.M m) throws Exception }
private static void parse_mapping(XmlPullParser parser, Map<KeyValue, KeyValue> dst) throws Exception
{ {
KeyValue a = KeyValue.getKeyByName(parser.getAttributeValue(null, "a")); KeyValue a = KeyValue.getKeyByName(parser.getAttributeValue(null, "a"));
KeyValue b = KeyValue.getKeyByName(parser.getAttributeValue(null, "b")); KeyValue b = KeyValue.getKeyByName(parser.getAttributeValue(null, "b"));
while (parser.next() != XmlPullParser.END_TAG) while (parser.next() != XmlPullParser.END_TAG)
continue; continue;
mm.add(m, a, b); dst.put(a, b);
}
} }
/** Position of a key on the layout. */ /** Position of a key on the layout. */

View File

@@ -42,7 +42,6 @@ public class LauncherActivity extends Activity implements Handler.Callback
if (VERSION.SDK_INT >= 28) if (VERSION.SDK_INT >= 28)
_tryhere_area.addOnUnhandledKeyEventListener( _tryhere_area.addOnUnhandledKeyEventListener(
this.new Tryhere_OnUnhandledKeyEventListener()); this.new Tryhere_OnUnhandledKeyEventListener());
_handler = new Handler(getMainLooper(), this);
} }
@Override @Override
@@ -53,7 +52,7 @@ public class LauncherActivity extends Activity implements Handler.Callback
_animations.add(find_anim(R.id.launcher_anim_swipe)); _animations.add(find_anim(R.id.launcher_anim_swipe));
_animations.add(find_anim(R.id.launcher_anim_round_trip)); _animations.add(find_anim(R.id.launcher_anim_round_trip));
_animations.add(find_anim(R.id.launcher_anim_circle)); _animations.add(find_anim(R.id.launcher_anim_circle));
_handler.removeMessages(0); _handler = new Handler(getMainLooper(), this);
_handler.sendEmptyMessageDelayed(0, 500); _handler.sendEmptyMessageDelayed(0, 500);
} }

View File

@@ -11,8 +11,7 @@ public final class LayoutModifier
{ {
static Config globalConfig; static Config globalConfig;
static KeyboardData.Row bottom_row; static KeyboardData.Row bottom_row;
static KeyboardData.Row number_row_no_symbols; static KeyboardData.Row number_row;
static KeyboardData.Row number_row_symbols;
static KeyboardData num_pad; static KeyboardData num_pad;
/** Update the layout according to the configuration. /** Update the layout according to the configuration.
@@ -45,7 +44,7 @@ public final class LayoutModifier
} }
else if (globalConfig.add_number_row && !kw.embedded_number_row) // The numpad removes the number row else if (globalConfig.add_number_row && !kw.embedded_number_row) // The numpad removes the number row
{ {
added_number_row = modify_number_row(globalConfig.number_row_symbols ? number_row_symbols : number_row_no_symbols, kw); added_number_row = modify_number_row(number_row, kw);
remove_keys.addAll(added_number_row.getKeys(0).keySet()); remove_keys.addAll(added_number_row.getKeys(0).keySet());
} }
// Add the bottom row before computing the extra keys // Add the bottom row before computing the extra keys
@@ -139,8 +138,15 @@ public final class LayoutModifier
return new KeyboardData.MapKeyValues() { return new KeyboardData.MapKeyValues() {
public KeyValue apply(KeyValue key, boolean localized) public KeyValue apply(KeyValue key, boolean localized)
{ {
KeyValue modified = ComposeKey.apply(map_digit, key); switch (key.getKind())
return (modified != null) ? modified : key; {
case Char:
KeyValue modified = ComposeKey.apply(map_digit, key.getChar());
if (modified != null)
return modified;
break;
}
return key;
} }
}; };
} }
@@ -205,9 +211,8 @@ public final class LayoutModifier
globalConfig = globalConfig_; globalConfig = globalConfig_;
try try
{ {
number_row_no_symbols = KeyboardData.load_row(res, R.xml.number_row_no_symbols); number_row = KeyboardData.load_number_row(res);
number_row_symbols = KeyboardData.load_row(res, R.xml.number_row); bottom_row = KeyboardData.load_bottom_row(res);
bottom_row = KeyboardData.load_row(res, R.xml.bottom_row);
num_pad = KeyboardData.load_num_pad(res); num_pad = KeyboardData.load_num_pad(res);
} }
catch (Exception e) catch (Exception e)

View File

@@ -1,33 +0,0 @@
package juloo.keyboard2;
import java.lang.reflect.Array;
import java.util.Map;
import java.util.TreeMap;
/** Stores key combinations that are applied by [KeyModifier]. */
public final class Modmap
{
public enum M { Shift, Fn, Ctrl }
Map<KeyValue, KeyValue>[] _map;
public Modmap()
{
_map = (Map<KeyValue, KeyValue>[])Array.newInstance(TreeMap.class,
M.values().length);
}
public void add(M m, KeyValue a, KeyValue b)
{
int i = m.ordinal();
if (_map[i] == null)
_map[i] = new TreeMap<KeyValue, KeyValue>();
_map[i].put(a, b);
}
public KeyValue get(M m, KeyValue a)
{
Map<KeyValue, KeyValue> mm = _map[m.ordinal()];
return (mm == null) ? null : mm.get(a);
}
}

View File

@@ -219,7 +219,7 @@ public final class Pointers implements Handler.Callback
* [direction] is an int between [0] and [15] that represent 16 sections of a * [direction] is an int between [0] and [15] that represent 16 sections of a
* circle, clockwise, starting at the top. * circle, clockwise, starting at the top.
*/ */
static KeyValue getKeyAtDirection(KeyboardData.Key k, int direction) KeyValue getKeyAtDirection(KeyboardData.Key k, int direction)
{ {
return k.keys[DIRECTION_TO_INDEX[direction]]; return k.keys[DIRECTION_TO_INDEX[direction]];
} }
@@ -234,25 +234,17 @@ public final class Pointers implements Handler.Callback
private KeyValue getNearestKeyAtDirection(Pointer ptr, int direction) private KeyValue getNearestKeyAtDirection(Pointer ptr, int direction)
{ {
KeyValue k; KeyValue k;
// [i] is [0, -1, +1, ..., -3, +3], scanning 43% of the circle's area, // [i] is [0, -1, 1, -2, 2], scanning a 1/4 of the circle's area, centered
// centered on the initial swipe direction. // on the initial direction.
for (int i = 0; i > -4; i = (~i>>31) - i) for (int i = 0; i > -2; i = (~i>>31) - i)
{ {
int d = (direction + i + 16) % 16; int d = (direction + i + 16) % 16;
// Don't make the difference between a key that doesn't exist and a key // Don't make the difference between a key that doesn't exist and a key
// that is removed by [_handler]. Triggers side effects. // that is removed by [_handler]. Triggers side effects.
k = _handler.modifyKey(getKeyAtDirection(ptr.key, d), ptr.modifiers); k = _handler.modifyKey(getKeyAtDirection(ptr.key, d), ptr.modifiers);
if (k != null) if (k != null)
{
// When the nearest key is a slider, it is only selected if it's placed
// within 18% of the original swipe direction.
// This reduces accidental swipes on the slider and allow typing circle
// gestures without being interrupted by the slider.
if (k.getKind() == KeyValue.Kind.Slider && Math.abs(i) >= 2)
continue;
return k; return k;
} }
}
return null; return null;
} }

View File

@@ -23,14 +23,6 @@ public class SettingsActivity extends PreferenceActivity
} }
catch (Exception _e) { fallbackEncrypted(); return; } catch (Exception _e) { fallbackEncrypted(); return; }
addPreferencesFromResource(R.xml.settings); addPreferencesFromResource(R.xml.settings);
boolean foldableDevice = FoldStateTracker.isFoldableDevice(this);
findPreference("margin_bottom_portrait_unfolded").setEnabled(foldableDevice);
findPreference("margin_bottom_landscape_unfolded").setEnabled(foldableDevice);
findPreference("horizontal_margin_portrait_unfolded").setEnabled(foldableDevice);
findPreference("horizontal_margin_landscape_unfolded").setEnabled(foldableDevice);
findPreference("keyboard_height_unfolded").setEnabled(foldableDevice);
findPreference("keyboard_height_landscape_unfolded").setEnabled(foldableDevice);
} }
void fallbackEncrypted() void fallbackEncrypted()

View File

@@ -12,6 +12,8 @@ public class Theme
// Key colors // Key colors
public final int colorKey; public final int colorKey;
public final int colorKeyActivated; public final int colorKeyActivated;
public final int colorKeyAction;
public final int colorKeySpaceBar;
// Label colors // Label colors
public final int lockedColor; public final int lockedColor;
@@ -25,6 +27,8 @@ public class Theme
public final float keyBorderRadius; public final float keyBorderRadius;
public final float keyBorderWidth; public final float keyBorderWidth;
public final float keyBorderWidthActivated; public final float keyBorderWidthActivated;
public final float keyBorderWidthAction;
public final float keyBorderWidthSpaceBar;
public final int keyBorderColorLeft; public final int keyBorderColorLeft;
public final int keyBorderColorTop; public final int keyBorderColorTop;
public final int keyBorderColorRight; public final int keyBorderColorRight;
@@ -39,6 +43,8 @@ public class Theme
TypedArray s = context.getTheme().obtainStyledAttributes(attrs, R.styleable.keyboard, 0, 0); TypedArray s = context.getTheme().obtainStyledAttributes(attrs, R.styleable.keyboard, 0, 0);
colorKey = s.getColor(R.styleable.keyboard_colorKey, 0); colorKey = s.getColor(R.styleable.keyboard_colorKey, 0);
colorKeyActivated = s.getColor(R.styleable.keyboard_colorKeyActivated, 0); colorKeyActivated = s.getColor(R.styleable.keyboard_colorKeyActivated, 0);
colorKeyAction = s.getColor(R.styleable.keyboard_colorKeyAction, colorKey);
colorKeySpaceBar = s.getColor(R.styleable.keyboard_colorKeySpaceBar, colorKey);
// colorKeyboard = s.getColor(R.styleable.keyboard_colorKeyboard, 0); // colorKeyboard = s.getColor(R.styleable.keyboard_colorKeyboard, 0);
colorNavBar = s.getColor(R.styleable.keyboard_navigationBarColor, 0); colorNavBar = s.getColor(R.styleable.keyboard_navigationBarColor, 0);
isLightNavBar = s.getBoolean(R.styleable.keyboard_windowLightNavigationBar, false); isLightNavBar = s.getBoolean(R.styleable.keyboard_windowLightNavigationBar, false);
@@ -53,6 +59,8 @@ public class Theme
keyBorderRadius = s.getDimension(R.styleable.keyboard_keyBorderRadius, 0); keyBorderRadius = s.getDimension(R.styleable.keyboard_keyBorderRadius, 0);
keyBorderWidth = s.getDimension(R.styleable.keyboard_keyBorderWidth, 0); keyBorderWidth = s.getDimension(R.styleable.keyboard_keyBorderWidth, 0);
keyBorderWidthActivated = s.getDimension(R.styleable.keyboard_keyBorderWidthActivated, 0); keyBorderWidthActivated = s.getDimension(R.styleable.keyboard_keyBorderWidthActivated, 0);
keyBorderWidthAction = s.getDimension(R.styleable.keyboard_keyBorderWidthAction, 0);
keyBorderWidthSpaceBar = s.getDimension(R.styleable.keyboard_keyBorderWidthSpaceBar, 0);
keyBorderColorLeft = s.getColor(R.styleable.keyboard_keyBorderColorLeft, colorKey); keyBorderColorLeft = s.getColor(R.styleable.keyboard_keyBorderColorLeft, colorKey);
keyBorderColorTop = s.getColor(R.styleable.keyboard_keyBorderColorTop, colorKey); keyBorderColorTop = s.getColor(R.styleable.keyboard_keyBorderColorTop, colorKey);
keyBorderColorRight = s.getColor(R.styleable.keyboard_keyBorderColorRight, colorKey); keyBorderColorRight = s.getColor(R.styleable.keyboard_keyBorderColorRight, colorKey);
@@ -61,7 +69,7 @@ public class Theme
} }
/** Interpolate the 'value' component toward its opposite by 'alpha'. */ /** Interpolate the 'value' component toward its opposite by 'alpha'. */
int adjustLight(int color, float alpha) static int adjustLight(int color, float alpha)
{ {
float[] hsv = new float[3]; float[] hsv = new float[3];
Color.colorToHSV(color, hsv); Color.colorToHSV(color, hsv);
@@ -94,30 +102,25 @@ public class Theme
public final float horizontal_margin; public final float horizontal_margin;
public final float margin_top; public final float margin_top;
public final float margin_left; public final float margin_left;
public final float row_height;
public final Paint indication_paint; public final Paint indication_paint;
public final Key key; public final Key key;
public final Key key_activated; public final Key key_activated;
public final Key key_action;
public final Key key_space_bar;
public Computed(Theme theme, Config config, float keyWidth, KeyboardData layout) public Computed(Theme theme, Config config, float keyWidth)
{ {
// Rows height is proportional to the keyboard height, meaning it doesn't vertical_margin = config.key_vertical_margin * config.keyHeight;
// change for layouts with more or less rows. 3.95 is the usual height of
// a layout in KeyboardData unit. The keyboard will be higher if the
// layout has more rows and smaller if it has less because rows stay the
// same height.
row_height = Math.min(
config.screenHeightPixels * config.keyboardHeightPercent / 100 / 3.95f,
config.screenHeightPixels / layout.keysHeight);
vertical_margin = config.key_vertical_margin * row_height;
horizontal_margin = config.key_horizontal_margin * keyWidth; horizontal_margin = config.key_horizontal_margin * keyWidth;
// Add half of the key margin on the left and on the top as it's also // Add half of the key margin on the left and on the top as it's also
// added on the right and on the bottom of every keys. // added on the right and on the bottom of every keys.
margin_top = config.marginTop + vertical_margin / 2; margin_top = config.marginTop + vertical_margin / 2;
margin_left = horizontal_margin / 2; margin_left = horizontal_margin / 2;
key = new Key(theme, config, keyWidth, false); key = new Key(theme, config, keyWidth, false, KeyboardData.Key.Role.Normal);
key_activated = new Key(theme, config, keyWidth, true); key_action = new Key(theme, config, keyWidth, false, KeyboardData.Key.Role.Action);
key_space_bar = new Key(theme, config, keyWidth, false, KeyboardData.Key.Role.Space_bar);
key_activated = new Key(theme, config, keyWidth, true, KeyboardData.Key.Role.Normal);
indication_paint = init_label_paint(config, null); indication_paint = init_label_paint(config, null);
indication_paint.setColor(theme.subLabelColor); indication_paint.setColor(theme.subLabelColor);
} }
@@ -135,22 +138,38 @@ public class Theme
final Paint _special_label_paint; final Paint _special_label_paint;
final Paint _sublabel_paint; final Paint _sublabel_paint;
final Paint _special_sublabel_paint; final Paint _special_sublabel_paint;
final int _label_alpha_bits;
public Key(Theme theme, Config config, float keyWidth, boolean activated) public Key(Theme theme, Config config, float keyWidth, boolean activated,
KeyboardData.Key.Role role)
{ {
bg_paint.setColor(activated ? theme.colorKeyActivated : theme.colorKey); border_radius = config.borderConfig ? config.customBorderRadius * keyWidth : theme.keyBorderRadius;
if (config.borderConfig) int bg_color;
if (activated)
{ {
border_radius = config.customBorderRadius * keyWidth; bg_color = theme.colorKeyActivated;
border_width = config.customBorderLineWidth; border_width = theme.keyBorderWidthActivated;
bg_paint.setAlpha(config.keyActivatedOpacity);
} }
else else
{ {
border_radius = theme.keyBorderRadius; switch (role)
border_width = activated ? theme.keyBorderWidthActivated : theme.keyBorderWidth; {
case Action:
bg_color = theme.colorKeyAction;
border_width = theme.keyBorderWidthAction;
break;
case Space_bar:
bg_color = theme.colorKeySpaceBar;
border_width = theme.keyBorderWidthSpaceBar;
break;
default:
bg_color = theme.colorKey;
border_width = config.borderConfig ? config.customBorderLineWidth : theme.keyBorderWidth;
break;
} }
bg_paint.setAlpha(activated ? config.keyActivatedOpacity : config.keyOpacity); bg_paint.setAlpha(config.keyOpacity);
}
bg_paint.setColor(bg_color);
border_left_paint = init_border_paint(config, border_width, theme.keyBorderColorLeft); border_left_paint = init_border_paint(config, border_width, theme.keyBorderColorLeft);
border_top_paint = init_border_paint(config, border_width, theme.keyBorderColorTop); border_top_paint = init_border_paint(config, border_width, theme.keyBorderColorTop);
border_right_paint = init_border_paint(config, border_width, theme.keyBorderColorRight); border_right_paint = init_border_paint(config, border_width, theme.keyBorderColorRight);
@@ -159,21 +178,18 @@ public class Theme
_special_label_paint = init_label_paint(config, _key_font); _special_label_paint = init_label_paint(config, _key_font);
_sublabel_paint = init_label_paint(config, null); _sublabel_paint = init_label_paint(config, null);
_special_sublabel_paint = init_label_paint(config, _key_font); _special_sublabel_paint = init_label_paint(config, _key_font);
_label_alpha_bits = (config.labelBrightness & 0xFF) << 24;
} }
public Paint label_paint(boolean special_font, int color, float text_size) public Paint label_paint(boolean special_font, float text_size)
{ {
Paint p = special_font ? _special_label_paint : _label_paint; Paint p = special_font ? _special_label_paint : _label_paint;
p.setColor((color & 0x00FFFFFF) | _label_alpha_bits);
p.setTextSize(text_size); p.setTextSize(text_size);
return p; return p;
} }
public Paint sublabel_paint(boolean special_font, int color, float text_size, Paint.Align align) public Paint sublabel_paint(boolean special_font, float text_size, Paint.Align align)
{ {
Paint p = special_font ? _special_sublabel_paint : _sublabel_paint; Paint p = special_font ? _special_sublabel_paint : _sublabel_paint;
p.setColor((color & 0x00FFFFFF) | _label_alpha_bits);
p.setTextSize(text_size); p.setTextSize(text_size);
p.setTextAlign(align); p.setTextAlign(align);
return p; return p;
@@ -194,6 +210,7 @@ public class Theme
{ {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setTextAlign(Paint.Align.CENTER); p.setTextAlign(Paint.Align.CENTER);
p.setAlpha(config.labelBrightness);
if (font != null) if (font != null)
p.setTypeface(font); p.setTypeface(font);
return p; return p;

View File

@@ -11,7 +11,6 @@ import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.AbstractMap.SimpleEntry; import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -71,8 +70,6 @@ class VoiceImeSwitcher
} }
}) })
.create(); .create();
if (ime_display_names.size() == 0)
dialog.setMessage(ims.getResources().getString(R.string.toast_no_voice_input));
Utils.show_dialog_on_ime(dialog, ims.getWindow().getWindow().getDecorView().getWindowToken()); Utils.show_dialog_on_ime(dialog, ims.getWindow().getWindow().getDecorView().getWindowToken());
} }

View File

@@ -41,7 +41,7 @@ public class CustomExtraKeysPreference extends ListGroupPreference<String>
if (key_names != null) if (key_names != null)
{ {
for (String key_name : key_names) for (String key_name : key_names)
kvs.put(KeyValue.getKeyByName(key_name), KeyboardData.PreferredPos.DEFAULT); kvs.put(KeyValue.parseKeyDefinition(key_name), KeyboardData.PreferredPos.DEFAULT);
} }
return kvs; return kvs;
} }

View File

@@ -3,7 +3,6 @@ package juloo.keyboard2.prefs;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build.VERSION;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.util.AttributeSet; import android.util.AttributeSet;
@@ -73,8 +72,6 @@ public class ExtraKeysPreference extends PreferenceCategory
"pasteAsPlainText", "pasteAsPlainText",
"undo", "undo",
"redo", "redo",
"delete_word",
"forward_delete_word",
"superscript", "superscript",
"subscript", "subscript",
"f11_placeholder", "f11_placeholder",
@@ -180,15 +177,8 @@ public class ExtraKeysPreference extends PreferenceCategory
id = R.string.key_descr_redo; id = R.string.key_descr_redo;
additional_info = format_key_combination(new String[]{"fn", "undo"}); additional_info = format_key_combination(new String[]{"fn", "undo"});
break; break;
case "delete_word":
id = R.string.key_descr_delete_word;
additional_info = format_key_combination_gesture(res, "backspace");
break;
case "forward_delete_word":
id = R.string.key_descr_forward_delete_word;
additional_info = format_key_combination_gesture(res, "forward_delete");
break;
case "selectAll": id = R.string.key_descr_selectAll; break; case "selectAll": id = R.string.key_descr_selectAll; break;
case "shareText": id = R.string.key_descr_shareText; break;
case "subscript": id = R.string.key_descr_subscript; break; case "subscript": id = R.string.key_descr_subscript; break;
case "superscript": id = R.string.key_descr_superscript; break; case "superscript": id = R.string.key_descr_superscript; break;
case "switch_greekmath": id = R.string.key_descr_switch_greekmath; break; case "switch_greekmath": id = R.string.key_descr_switch_greekmath; break;
@@ -202,28 +192,6 @@ public class ExtraKeysPreference extends PreferenceCategory
case "nbsp": id = R.string.key_descr_nbsp; break; case "nbsp": id = R.string.key_descr_nbsp; break;
case "nnbsp": id = R.string.key_descr_nnbsp; break; case "nnbsp": id = R.string.key_descr_nnbsp; break;
case "accent_aigu":
case "accent_grave":
case "accent_double_aigu":
case "accent_dot_above":
case "accent_circonflexe":
case "accent_tilde":
case "accent_cedille":
case "accent_trema":
case "accent_ring":
case "accent_caron":
case "accent_macron":
case "accent_ogonek":
case "accent_breve":
case "accent_slash":
case "accent_bar":
case "accent_dot_below":
case "accent_hook_above":
case "accent_horn":
case "accent_double_grave":
id = R.string.key_descr_dead_key;
break;
case "combining_dot_above": case "combining_dot_above":
case "combining_double_aigu": case "combining_double_aigu":
case "combining_slash": case "combining_slash":
@@ -286,7 +254,6 @@ public class ExtraKeysPreference extends PreferenceCategory
return kv.getString(); return kv.getString();
} }
/** Format a key combination */
static String format_key_combination(String[] keys) static String format_key_combination(String[] keys)
{ {
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
@@ -298,45 +265,60 @@ public class ExtraKeysPreference extends PreferenceCategory
return out.toString(); return out.toString();
} }
/** Explain a gesture on a key */
static String format_key_combination_gesture(Resources res, String key_name)
{
return res.getString(R.string.key_descr_gesture) + " + "
+ KeyValue.getKeyByName(key_name).getString();
}
/** Place an extra key next to the key specified by the first argument, on
bottom-right preferably or on the bottom-left. If the specified key is not
on the layout, place on the specified row and column. */
static KeyboardData.PreferredPos mk_preferred_pos(String next_to_key, int row, int col, boolean prefer_bottom_right)
{
KeyValue next_to = (next_to_key == null) ? null : KeyValue.getKeyByName(next_to_key);
int d1, d2; // Preferred direction and fallback direction
if (prefer_bottom_right) { d1 = 4; d2 = 3; } else { d1 = 3; d2 = 4; }
return new KeyboardData.PreferredPos(next_to,
new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(row, col, d1),
new KeyboardData.KeyPos(row, col, d2),
new KeyboardData.KeyPos(row, -1, d1),
new KeyboardData.KeyPos(row, -1, d2),
new KeyboardData.KeyPos(-1, -1, -1),
});
}
static KeyboardData.PreferredPos key_preferred_pos(String key_name) static KeyboardData.PreferredPos key_preferred_pos(String key_name)
{ {
switch (key_name) switch (key_name)
{ {
case "cut": return mk_preferred_pos("x", 2, 2, true); case "cut":
case "copy": return mk_preferred_pos("c", 2, 3, true); return new KeyboardData.PreferredPos(KeyValue.getKeyByName("x"),
case "paste": return mk_preferred_pos("v", 2, 4, true); new KeyboardData.KeyPos[]{
case "undo": return mk_preferred_pos("z", 2, 1, true); new KeyboardData.KeyPos(2, 2, 8),
case "selectAll": return mk_preferred_pos("a", 1, 0, true); new KeyboardData.KeyPos(2, -1, 8),
case "redo": return mk_preferred_pos("y", 0, 5, true); new KeyboardData.KeyPos(-1, -1, 8),
case "f11_placeholder": return mk_preferred_pos("9", 0, 8, false); });
case "f12_placeholder": return mk_preferred_pos("0", 0, 9, false); case "copy":
case "delete_word": return mk_preferred_pos("backspace", -1, -1, false); return new KeyboardData.PreferredPos(KeyValue.getKeyByName("c"),
case "forward_delete_word": return mk_preferred_pos("backspace", -1, -1, true); new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(2, 3, 8),
new KeyboardData.KeyPos(2, -1, 8),
new KeyboardData.KeyPos(-1, -1, 8),
});
case "paste":
return new KeyboardData.PreferredPos(KeyValue.getKeyByName("v"),
new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(2, 4, 8),
new KeyboardData.KeyPos(2, -1, 8),
new KeyboardData.KeyPos(-1, -1, 8),
});
case "undo":
return new KeyboardData.PreferredPos(KeyValue.getKeyByName("z"),
new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(2, 1, 8),
new KeyboardData.KeyPos(2, -1, 8),
new KeyboardData.KeyPos(-1, -1, 8),
});
case "redo":
return new KeyboardData.PreferredPos(KeyValue.getKeyByName("y"),
new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(0, -1, 8),
new KeyboardData.KeyPos(-1, -1, 8),
});
case "f11_placeholder":
return new KeyboardData.PreferredPos(KeyValue.getKeyByName("9"),
new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(0, 8, 3),
new KeyboardData.KeyPos(0, 8, 4),
new KeyboardData.KeyPos(0, -1, 3),
new KeyboardData.KeyPos(0, -1, 4),
});
case "f12_placeholder":
return new KeyboardData.PreferredPos(KeyValue.getKeyByName("0"),
new KeyboardData.KeyPos[]{
new KeyboardData.KeyPos(0, 9, 3),
new KeyboardData.KeyPos(0, 9, 4),
new KeyboardData.KeyPos(0, -1, 3),
new KeyboardData.KeyPos(0, -1, 4),
});
} }
return KeyboardData.PreferredPos.DEFAULT; return KeyboardData.PreferredPos.DEFAULT;
} }
@@ -393,8 +375,6 @@ public class ExtraKeysPreference extends PreferenceCategory
setKey(pref_key_of_key_name(key_name)); setKey(pref_key_of_key_name(key_name));
setDefaultValue(default_checked); setDefaultValue(default_checked);
setTitle(title); setTitle(title);
if (VERSION.SDK_INT >= 26)
setSingleLineTitle(false);
} }
@Override @Override

View File

@@ -37,6 +37,6 @@
<key key0="ز" key3="."/> <key key0="ز" key3="."/>
<key key0="ظ" key3="&#1567;"/> <key key0="ظ" key3="&#1567;"/>
<key key0="د"/> <key key0="د"/>
<key width="1.0" key0="backspace" key2="delete"/> <key width="1.0" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -37,6 +37,6 @@
<key key0="و" key1="ۋ" key4="ۊ"/> <key key0="و" key1="ۋ" key4="ۊ"/>
<key key0="چ"/> <key key0="چ"/>
<key key0="ٚ" key1="ٛ"/> <key key0="ٚ" key1="ٛ"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -39,6 +39,6 @@
<key key0="و" key1=","/> <key key0="و" key1=","/>
<key key0="ز" key1="."/> <key key0="ز" key1="."/>
<key key0="ظ" key1="&#1567;"/> <key key0="ظ" key1="&#1567;"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -34,6 +34,6 @@
<key key0="ب" key1="ٮ" /> <key key0="ب" key1="ٮ" />
<key key0="ن" key2="&#1548;" key3="&#1563;"/> <key key0="ن" key2="&#1548;" key3="&#1563;"/>
<key key0="م" key2="." key3=":" /> <key key0="م" key2="." key3=":" />
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -39,6 +39,6 @@
<key key0="و" key1=","/> <key key0="و" key1=","/>
<key key0="ز" key1="."/> <key key0="ز" key1="."/>
<key key0="ظ" key1="&#1567;"/> <key key0="ظ" key1="&#1567;"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -36,6 +36,6 @@
<key key0="پ" key2="&#1567;"/> <key key0="پ" key2="&#1567;"/>
<key key0="و"/> <key key0="و"/>
<key key0="چ"/> <key key0="چ"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -37,7 +37,7 @@
<key key0="խ" key3="\\" key2="|"/> <key key0="խ" key3="\\" key2="|"/>
</row> </row>
<row> <row>
<key key0="shift" key2="loc capslock"/> <key role="action" key0="shift" key2="loc capslock"/>
<key key0="զ"/> <key key0="զ"/>
<key key0="ղ"/> <key key0="ղ"/>
<key key0="ց"/> <key key0="ց"/>
@@ -46,6 +46,6 @@
<key key0="ն" key4="/" key2="\?"/> <key key0="ն" key4="/" key2="\?"/>
<key key0="մ" key4=";" key2=":"/> <key key0="մ" key4=";" key2=":"/>
<key key0="շ" key4="&apos;" key2="&quot;"/> <key key0="շ" key4="&apos;" key2="&quot;"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -24,7 +24,7 @@
<key key0="দ" key1="_" key2="ধ" key3="(" key4=")"/> <key key0="দ" key1="_" key2="ধ" key3="(" key4=")"/>
</row> </row>
<row> <row>
<key width="1.4" key0="shift" key2="loc capslock"/> <key width="1.4" role="action" key0="shift" key2="loc capslock"/>
<key shift="0.1" key0="্র" key2="্য" key3="\#" key4="*"/> <key shift="0.1" key0="্র" key2="্য" key3="\#" key4="*"/>
<key key0="ো" key1="ৌ" key2="ও" key3="ঔ" key4="\@"/> <key key0="ো" key1="ৌ" key2="ও" key3="ঔ" key4="\@"/>
<key key0="ে" key1="ৈ" key2="এ" key3="ঐ" key4="%"/> <key key0="ে" key1="ৈ" key2="এ" key3="ঐ" key4="%"/>
@@ -32,6 +32,6 @@
<key key0="ন" key1="৳" key2="ণ" key3=";" key4="."/> <key key0="ন" key1="৳" key2="ণ" key3=";" key4="."/>
<key key0="স" key1="&quot;" key2="ষ" key3="!" key4=","/> <key key0="স" key1="&quot;" key2="ষ" key3="!" key4=","/>
<key key0="ম" key1="'" key2="শ" key3="\?" key4="।"/> <key key0="ম" key1="'" key2="শ" key3="\?" key4="।"/>
<key shift="0.1" width="1.4" key0="backspace" key2="delete"/> <key shift="0.1" width="1.4" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -24,7 +24,7 @@
<key key0="ল" key1="ং" key2="॥" key3="halfspace" /> <key key0="ল" key1="ং" key2="॥" key3="halfspace" />
</row> </row>
<row> <row>
<key width="1.5" key0="shift" /> <key width="1.5" role="action" key0="shift" />
<key key0="য়" key1="য" /> <key key0="য়" key1="য" />
<key key0="শ" key1="ঢ়" /> <key key0="শ" key1="ঢ়" />
<key key0="চ" key1="ছ" key2="ৃ" key3="," /> <key key0="চ" key1="ছ" key2="ৃ" key3="," />
@@ -32,6 +32,6 @@
<key key0="ব" key1="ভ" key2="\?" key3="্" /> <key key0="ব" key1="ভ" key2="\?" key3="্" />
<key key0="ন" key1="ণ" key2=":" key3=";" /> <key key0="ন" key1="ণ" key2=":" key3=";" />
<key key0="ম" key1="ঙ" key2="&quot;" key3="'" /> <key key0="ম" key1="ঙ" key2="&quot;" key3="'" />
<key width="1.5" key0="backspace" key2="delete" /> <key width="1.5" role="action" key0="backspace" key2="delete" />
</row> </row>
</keyboard> </keyboard>

View File

@@ -27,7 +27,7 @@
<key key0="п" key2="|" key3="\\"/> <key key0="п" key2="|" key3="\\"/>
</row> </row>
<row> <row>
<key key0="shift" key2="loc capslock"/> <key role="action" key0="shift" key2="loc capslock"/>
<key key0="я"/> <key key0="я"/>
<key key0="ч"/> <key key0="ч"/>
<key key0="ё" key1="е"/> <key key0="ё" key1="е"/>
@@ -37,6 +37,6 @@
<key key0="т" key1="₮" key2="\?" key3="/"/> <key key0="т" key1="₮" key2="\?" key3="/"/>
<key key0="ь" key1="ъ" key2=":" key3=";"/> <key key0="ь" key1="ъ" key2=":" key3=";"/>
<key key0="в" key1="ю" key2="&quot;" key3="'"/> <key key0="в" key1="ю" key2="&quot;" key3="'"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -40,7 +40,7 @@
<key key0="э" key2="|" key3="\\"/> <key key0="э" key2="|" key3="\\"/>
</row> </row>
<row> <row>
<key key0="shift" key2="loc capslock"/> <key role="action" key0="shift" key2="loc capslock"/>
<key key0="я"/> <key key0="я"/>
<key key0="ч"/> <key key0="ч"/>
<key key0="с"/> <key key0="с"/>
@@ -50,6 +50,6 @@
<key key0="ь" key2="\?" key3="/"/> <key key0="ь" key2="\?" key3="/"/>
<key key0="б" key2=":" key3=";"/> <key key0="б" key2=":" key3=";"/>
<key key0="ю" key2="&quot;" key3="'"/> <key key0="ю" key2="&quot;" key3="'"/>
<key key0="backspace" key2="delete"/> <key role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -26,17 +26,17 @@
<key key0="ж" key2="=" key3="+"/> <key key0="ж" key2="=" key3="+"/>
<key key0="э" key2="|" key3="\\"/> <key key0="э" key2="|" key3="\\"/>
</row> </row>
<row scale="11"> <row>
<key width="1.22" key0="shift" key2="loc capslock"/> <key width="1.18" role="action" key0="shift" key2="loc capslock"/>
<key key0="я"/> <key width="0.96" key0="я"/>
<key key0="ч"/> <key width="0.96" key0="ч"/>
<key key0="с"/> <key width="0.96" key0="с"/>
<key key0="м"/> <key width="0.96" key0="м"/>
<key key0="и" key1="loc і" key2="&lt;" key3="."/> <key width="0.96" key0="и" key1="loc і" key2="&lt;" key3="."/>
<key key0="т" key2="&gt;" key3=","/> <key width="0.96" key0="т" key2="&gt;" key3=","/>
<key key0="ь" key1="ъ" key2="\?" key3="/"/> <key width="0.96" key0="ь" key1="ъ" key2="\?" key3="/"/>
<key key0="б" key2=":" key3=";"/> <key width="0.96" key0="б" key2=":" key3=";"/>
<key key0="ю" key2="&quot;" key3="'"/> <key width="0.96" key0="ю" key2="&quot;" key3="'"/>
<key width="1.22" key0="backspace" key2="delete"/> <key width="1.18" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -27,7 +27,7 @@
<key key0="є" key2="|" key3="\\"/> <key key0="є" key2="|" key3="\\"/>
</row> </row>
<row> <row>
<key width="1.1" key0="shift" key2="loc capslock"/> <key width="1.1" role="action" key0="shift" key2="loc capslock"/>
<key key0="я"/> <key key0="я"/>
<key key0="ч" /> <key key0="ч" />
<key key0="с" /> <key key0="с" />
@@ -37,6 +37,6 @@
<key key0="ь" key2=":" key3=";"/> <key key0="ь" key2=":" key3=";"/>
<key key0="б" key2="&quot;" key3="'"/> <key key0="б" key2="&quot;" key3="'"/>
<key key0="ю" key1="«" key2="»"/> <key key0="ю" key1="«" key2="»"/>
<key width="1.1" key0="backspace" key2="delete"/> <key width="1.1" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -8,32 +8,32 @@
<fn a="у" b="у̂" /> <fn a="у" b="у̂" />
<fn a="cursor_left" b="home" /> <fn a="cursor_left" b="home" />
<fn a="cursor_right" b="end" /> <fn a="cursor_right" b="end" />
<ctrl a="љ" b="љ:q" /> <ctrl a="љ" b=":char symbol='љ':q" />
<ctrl a="њ" b="њ:w" /> <ctrl a="њ" b=":char symbol='њ':w" />
<ctrl a="е" b="е:e" /> <ctrl a="е" b=":char symbol='е':e" />
<ctrl a="р" b="р:r" /> <ctrl a="р" b=":char symbol='р':r" />
<ctrl a="т" b="т:t" /> <ctrl a="т" b=":char symbol='т':t" />
<ctrl a="ж" b="ж:y" /> <ctrl a="ж" b=":char symbol='ж':y" />
<ctrl a="у" b="у:u" /> <ctrl a="у" b=":char symbol='у':u" />
<ctrl a="и" b="и:i" /> <ctrl a="и" b=":char symbol='и':i" />
<ctrl a="о" b="о:o" /> <ctrl a="о" b=":char symbol='о':o" />
<ctrl a="п" b="п:p" /> <ctrl a="п" b=":char symbol='п':p" />
<ctrl a="а" b="а:a" /> <ctrl a="а" b=":char symbol='а':a" />
<ctrl a="с" b="с:s" /> <ctrl a="с" b=":char symbol='с':s" />
<ctrl a="д" b="д:d" /> <ctrl a="д" b=":char symbol='д':d" />
<ctrl a="ф" b="ф:f" /> <ctrl a="ф" b=":char symbol='ф':f" />
<ctrl a="г" b="г:g" /> <ctrl a="г" b=":char symbol='г':g" />
<ctrl a="х" b="х:h" /> <ctrl a="х" b=":char symbol='х':h" />
<ctrl a="ј" b="ј:j" /> <ctrl a="ј" b=":char symbol='ј':j" />
<ctrl a="к" b="к:k" /> <ctrl a="к" b=":char symbol='к':k" />
<ctrl a="л" b="л:l" /> <ctrl a="л" b=":char symbol='л':l" />
<ctrl a="з" b="з:z" /> <ctrl a="з" b=":char symbol='з':z" />
<ctrl a="џ" b="џ:x" /> <ctrl a="џ" b=":char symbol='џ':x" />
<ctrl a="ц" b="ц:c" /> <ctrl a="ц" b=":char symbol='ц':c" />
<ctrl a="в" b="в:v" /> <ctrl a="в" b=":char symbol='в':v" />
<ctrl a="б" b="б:b" /> <ctrl a="б" b=":char symbol='б':b" />
<ctrl a="н" b="н:n" /> <ctrl a="н" b=":char symbol='н':n" />
<ctrl a="м" b="м:m" /> <ctrl a="м" b=":char symbol='м':m" />
</modmap> </modmap>
<row> <row>
<key key0="љ" ne="1" se="loc esc"/> <key key0="љ" ne="1" se="loc esc"/>
@@ -62,7 +62,7 @@
<key key0="ћ" ne="`" sw="|"/> <key key0="ћ" ne="`" sw="|"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" nw="loc superscript" ne="loc capslock" sw="loc subscript"/> <key width="1.5" role="action" key0="shift" nw="loc superscript" ne="loc capslock" sw="loc subscript"/>
<key key0="ж" nw="loc undo" ne="loc redo" sw="&lt;" se="&gt;"/> <key key0="ж" nw="loc undo" ne="loc redo" sw="&lt;" se="&gt;"/>
<key key0="џ" ne="loc cut"/> <key key0="џ" ne="loc cut"/>
<key key0="ц" ne="loc copy"/> <key key0="ц" ne="loc copy"/>
@@ -71,6 +71,6 @@
<key key0="н" nw="!" ne="\?" sw="/"/> <key key0="н" nw="!" ne="\?" sw="/"/>
<key key0="м" ne=";" sw=","/> <key key0="м" ne=";" sw=","/>
<key key0="ђ" ne=":" sw="."/> <key key0="ђ" ne=":" sw="."/>
<key width="1.5" key0="backspace" ne="delete"/> <key width="1.5" role="action" key0="backspace" ne="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -27,7 +27,7 @@
<key key0="ч" key1="„" key2="“"/> <key key0="ч" key1="„" key2="“"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" key2="loc capslock"/> <key width="1.5" role="action" key0="shift" key2="loc capslock"/>
<key key0="ю"/> <key key0="ю"/>
<key key0="й"/> <key key0="й"/>
<key key0="ъ" key1="loc accent_cedille" key2="&lt;" key4=">"/> <key key0="ъ" key1="loc accent_cedille" key2="&lt;" key4=">"/>
@@ -36,6 +36,6 @@
<key key0="п" key2="&quot;" key3="'"/> <key key0="п" key2="&quot;" key3="'"/>
<key key0="р" key3=","/> <key key0="р" key3=","/>
<key key0="л" key3="."/> <key key0="л" key3="."/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -24,7 +24,7 @@
<key key0="л" key1="щ" key2="|" key3="\\" key4="ю"/> <key key0="л" key1="щ" key2="|" key3="\\" key4="ю"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" key2="loc capslock"/> <key width="1.5" role="action" key0="shift" key2="loc capslock"/>
<key key0="з"/> <key key0="з"/>
<key key0="ь" key3="ѝ"/> <key key0="ь" key3="ѝ"/>
<key key0="ц" key2="&lt;" key3="."/> <key key0="ц" key2="&lt;" key3="."/>
@@ -32,6 +32,6 @@
<key key0="б" key2="\?" key3="/"/> <key key0="б" key2="\?" key3="/"/>
<key key0="н" key2=":" key3=";"/> <key key0="н" key2=":" key3=";"/>
<key key0="м" key2="&quot;" key3="'"/> <key key0="м" key2="&quot;" key3="'"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -22,21 +22,21 @@
<key key0="р" key7="6" /> <key key0="р" key7="6" />
<key key0="о" key7="7" /> <key key0="о" key7="7" />
<key key0="л" key7="8" /> <key key0="л" key7="8" />
<key key0="д" key7="9" /> <key key0="д" key7="9" key8="f11_placeholder" />
<key key0="ж" key7="0" /> <key key0="ж" key7="0" key8="f12_placeholder" />
<key key0="э" key7="\?" key3="/" /> <key key0="э" key7="\?" key3="/" />
</row> </row>
<row scale="11"> <row>
<key width="1.22" key0="shift" key2="loc capslock" /> <key width="1.18" role="action" key0="shift" key2="loc capslock" />
<key key0="я" key7="`" key8=";" /> <key width="0.96" key0="я" key7="`" key8=";" />
<key key0="ч" key7="*" key8=":" /> <key width="0.96" key0="ч" key7="*" key8=":" />
<key key0="с" key7="&amp;" key8="\#" /> <key width="0.96" key0="с" key7="&amp;" key8="\#" />
<key key0="м" key7="|" key8="\\" /> <key width="0.96" key0="м" key7="|" key8="\\" />
<key key0="и" key7="~" /> <key width="0.96" key0="и" key7="~" />
<key key0="т" key7="ц" /> <key width="0.96" key0="т" key7="ц" />
<key key0="ӣ" key3="&lt;" key2="&gt;" /> <key width="0.96" key0="ӣ" key3="&lt;" key2="&gt;" />
<key key0="б" key7="ъ" key8="ы" /> <key width="0.96" key0="б" key7="ъ" key8="ы" />
<key key0="ю" key7="&quot;" key8="'"/> <key width="0.96" key0="ю" key7="&quot;" key8="'"/>
<key width="1.22" key0="." key7="," /> <key width="1.18" key0="." key7="," />
</row> </row>
</keyboard> </keyboard>

View File

@@ -22,21 +22,21 @@
<key key0="р" key7="6" /> <key key0="р" key7="6" />
<key key0="о" key7="7" key8="ѡ" /> <key key0="о" key7="7" key8="ѡ" />
<key key0="л" key7="8" /> <key key0="л" key7="8" />
<key key0="д" key7="9" /> <key key0="д" key7="9" key8="f11_placeholder" />
<key key0="ж" key7="0" /> <key key0="ж" key7="0" key8="f12_placeholder" />
<key key0="э" key7="/" key8="|" /> <key key0="э" key7="/" key8="|" />
</row> </row>
<row scale="11"> <row>
<key width="1.22" key0="shift" /> <key width="1.18" role="action" key0="shift" />
<key key0="ꙗ" key7="combining_breve" key8=";" /> <key width="0.96" key0="ꙗ" key7="combining_breve" key8=";" />
<key key0="ч" key7="combining_pokrytie" key8=":" /> <key width="0.96" key0="ч" key7="combining_pokrytie" key8=":" />
<key key0="с" key7="combining_inverted_breve" key8="`" /> <key width="0.96" key0="с" key7="combining_inverted_breve" key8="`" />
<key key0="м" key7="ѭ" /> <key width="0.96" key0="м" key7="ѭ" />
<key key0="и" key7="combining_vertical_tilde" key8="-" /> <key width="0.96" key0="и" key7="combining_vertical_tilde" key8="-" />
<key key0="т" key7="\?" key8="\\" /> <key width="0.96" key0="т" key7="\?" key8="\\" />
<key key0="ц" key3="&lt;" key2="&gt;" /> <key width="0.96" key0="ц" key3="&lt;" key2="&gt;" />
<key key0="б" key3="(" key2=")" /> <key width="0.96" key0="б" key3="(" key2=")" />
<key key0="ю" key3="{" key2="}" /> <key width="0.96" key0="ю" key3="{" key2="}" />
<key width="1.22" key0="." key7="," key8="_" /> <key width="1.18" key0="." key7="," key8="_" />
</row> </row>
</keyboard> </keyboard>

View File

@@ -1,29 +1,30 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<keyboard name="देवनागरी (हिंदी)-2" script="devanagari"> <keyboard name="देवनागरी (हिंदी)-2" script="devanagari">
<row scale="6.6"> <row>
<key shift="0.35" c="क" nw="ख" ne="घ" sw="ङ" se="ग"/> <key shift="0.35" width="0.9" key0="क" key1="ख" key2="घ" key3="ङ" key4="ग"/>
<key c="च" nw="छ" ne="झ" sw="ञ" se="ज"/> <key width="0.9" key0="च" key1="छ" key2="झ" key3="ञ" key4="ज"/>
<key c="ट" nw="" ne="" sw="" se="" anticircle="" indication=""/> <key width="0.9" key0="" key1="" key2="" key3="" key4=""/>
<key c="त" nw="" ne="" sw="" se="" anticircle="" indication=""/> <key width="0.9" key0="" key1="" key2="" key3="" key4=""/>
<key c="प" nw="" ne="" sw="" se="" anticircle="" indication=""/> <key width="0.9" key0="" key1="" key2="" key3="" key4=""/>
<key c="र" nw="ज्ञ" ne="ल" sw="य" se="व"/> <key width="0.9" key0="र" key1="ज्ञ" key2="ल" key3="य" key4="व"/>
<key c="ह" nw="श" ne="ळ" sw="स" se="ष"/> <key width="0.9" key0="ह" key1="श" key2="ळ" key3="स" key4="ष"/>
</row>
<row scale="6.6">
<key shift="0.35" c="ा" nw="अ" ne="आ"/>
<key c="ि" nw="इ"/>
<key c="ी" nw="ई" anticircle="४" indication="४"/>
<key c="ु" nw="उ" ne="ऊ" se="ू" anticircle="५" indication="५"/>
<key c="े" nw="ए" ne="ऋ" se="ृ" anticircle="६" indication="६"/>
<key c="ै" nw="ऐ" ne="ऌ" se="ॢ"/>
<key c="ो" nw="ओ" ne="औ" se="ौ"/>
</row> </row>
<row> <row>
<key c="ऽ" se="\@"/> <key shift="0.35" width="0.9" key0="ा" key1="अ" key2="आ"/>
<key c="ँ" nw="₹" ne="॑" sw="" se="" anticircle="" indication=""/> <key width="0.9" key0="ि" key1="इ"/>
<key c="ं" nw="ॐ" ne="।" sw="" se="&quot;" anticircle="१" indication="१"/> <key width="0.9" key0="ी" key1="ई"/>
<key c="्" nw="," ne=";" sw="!" se="\?" anticircle="" indication=""/> <key width="0.9" key0="" key1="" key2="" key4=""/>
<key c="़" nw="" sw="-" se="" anticircle="" indication=""/> <key width="0.9" key0="" key1="" key2="" key4=""/>
<key width="2" c="backspace" ne="delete"/> <key width="0.9" key0="ै" key1="ऐ" key2="ऌ" key4="ॢ"/>
<key width="0.9" key0="ो" key1="ओ" key2="औ" key4="ौ"/>
</row>
<row>
<key key0="्" key2="*" key4="\@"/>
<key key0="ँ" key1="₹" key2="॑" key3="ॖ" key4="॓"/>
<key key0="ं" key1="ॐ" key2="ऽ" key3="" key4="&quot;"/>
<key key0="।" key1="," key2=";" key3="!" key4="\?"/>
<key key0="़" key1="॰" key2="" key3="-" key4="॒"/>
<key key0="५" key1="१" key2="३" key3="७" key4="९" key5="४" key6="६" key7="२" key8="८"/>
<key role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -24,14 +24,14 @@
<key key0="त" key1="थ" key2="ख़" key3="(" key4=")"/> <key key0="त" key1="थ" key2="ख़" key3="(" key4=")"/>
</row> </row>
<row> <row>
<key width="1.4" key0="shift" key2="loc capslock"/> <key width="1.4" role="action" key0="shift" key2="loc capslock"/>
<key shift="0.1" key0="ट" key1="ठ" key2="ड़" key3="\#" key4="*"/> <key shift="0.1" key0="ट" key1="ठ" key2="ड़" key3="\#" key4="*"/>
<key key0="ं" key1="ँ" key3="ॐ" key4="\@"/> <key key0="ं" key1="ँ" key2="।" key3="ॐ" key4="\@"/>
<key key0="म" key1="ण" key2="य" key3="य़" key4="%"/> <key key0="म" key1="ण" key2="य" key3="य़" key4="%"/>
<key key0="न" key2="।" key3=":" key4="&amp;"/> <key key0="न" key2="।" key3=":" key4="&amp;"/>
<key key0="व" key2="ढ़" key3=";" key4="."/> <key key0="व" key2="ढ़" key3=";" key4="."/>
<key key0="ल" key1="ळ" key2="फ़" key3="!" key4=","/> <key key0="ल" key1="ळ" key2="फ़" key3="!" key4=","/>
<key key0="स" key1="श" key2="ष" key3="\?"/> <key key0="स" key1="श" key2="ष" key3="\?" key4="।"/>
<key shift="0.1" width="1.4" key0="backspace" key2="delete"/> <key shift="0.1" width="1.4" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -10,7 +10,7 @@
<key key0="ड" key1="~" key2="2" key3="\@" /> <key key0="ड" key1="~" key2="2" key3="\@" />
<key key0="े" key1="ए" key2="3" key3="\#" key4="$" /> <key key0="े" key1="ए" key2="3" key3="\#" key4="$" />
<key key0="र" key1="ऋ" key2="4" key3="ृ" key4="₹"/> <key key0="र" key1="ऋ" key2="4" key3="ृ" key4="₹"/>
<key key0="त" key2="5" key3="%" key4="त्र"/> <key key0="त" key1="ट" key2="5" key3="%" key4="त्र"/>
<key key0="य" key2="6" key3="^"/> <key key0="य" key2="6" key3="^"/>
<key key0="ु" key1="उ" key2="7" key3="&amp;"/> <key key0="ु" key1="उ" key2="7" key3="&amp;"/>
<key key0="ि" key1="इ" key2="8" key3="*" /> <key key0="ि" key1="इ" key2="8" key3="*" />
@@ -29,7 +29,7 @@
<key key0="ल" key1="ऌ" key2="।" key3 ="ॢ" key4="॥"/> <key key0="ल" key1="ऌ" key2="।" key3 ="ॢ" key4="॥"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" key2="loc capslock"/> <key width="1.5" role="action" key0="shift" key2="loc capslock"/>
<key key0="ज्ञ" key2="|" key3="\\" key4="ऍ"/> <key key0="ज्ञ" key2="|" key3="\\" key4="ऍ"/>
<key key0="ष" key1="क्ष" key3 ="ॅ" key4="ॉ"/> <key key0="ष" key1="क्ष" key3 ="ॅ" key4="ॉ"/>
<key key0="च" key2="&lt;" key3=","/> <key key0="च" key2="&lt;" key3=","/>
@@ -37,6 +37,6 @@
<key key0="ब" key2="\?" key3="/"/> <key key0="ब" key2="\?" key3="/"/>
<key key0="न" key1="ङ" key2=":" key3=";" key4="ऽ"/> <key key0="न" key1="ङ" key2=":" key3=";" key4="ऽ"/>
<key key0="म" key1="ॐ" key2="&quot;" key3="'" key4="ँ"/> <key key0="म" key1="ॐ" key2="&quot;" key3="'" key4="ँ"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

View File

@@ -28,7 +28,7 @@
<key key0="ჩ" key1="ჭ"/> <key key0="ჩ" key1="ჭ"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" key2="loc capslock"/> <key width="1.5" role="action" key0="shift" key2="loc capslock"/>
<key key0="ზ" key1="ჵ"/> <key key0="ზ" key1="ჵ"/>
<key key0="ხ" key1="ჴ" key2="loc †"/> <key key0="ხ" key1="ჴ" key2="loc †"/>
<key key0="ც" key2="&lt;" key3="."/> <key key0="ც" key2="&lt;" key3="."/>
@@ -38,6 +38,6 @@
<key key0="მ" key2="&quot;" key3="'"/> <key key0="მ" key2="&quot;" key3="'"/>
<key key0="ძ"/> <key key0="ძ"/>
<key key0="ჟ"/> <key key0="ჟ"/>
<key width="1.5" key0="backspace" key2="delete"/> <key width="1.5" role="action" key0="backspace" key2="delete"/>
</row> </row>
</keyboard> </keyboard>

Some files were not shown because too many files have changed in this diff Show More